assember works

This commit is contained in:
sfja 2025-04-02 03:08:13 +02:00
parent ba643a68a3
commit 7bf7eae401
8 changed files with 1489 additions and 109 deletions

View File

@ -401,6 +401,54 @@ uint16_t assemble_line(uint16_t* out, const Line* line)
out[ip++] = op1;
break;
}
case LineTy_Out_Reg_Reg: {
uint16_t op1 = line->op1.reg;
uint16_t op2 = line->op2.reg;
uint32_t ins = Op_In;
add_op1_reg(&ins, op1);
ins |= (op2 & 0x7u) << 13;
out[ip++] = (uint16_t)ins;
break;
}
case LineTy_Out_Reg_Imm: {
uint16_t op1 = line->op1.reg;
uint16_t op2 = line->op2.imm;
uint32_t ins = Op_In;
add_op1_reg(&ins, op1);
ins |= 1 << 7;
out[ip++] = (uint16_t)ins;
out[ip++] = op2;
break;
}
case LineTy_Out_Imm_Reg: {
uint16_t op1 = line->op1.imm;
uint16_t op2 = line->op2.reg;
uint32_t ins = Op_In;
set_is_imm(&ins);
ins |= (op2 & 0x7u) << 13;
out[ip++] = (uint16_t)ins;
out[ip++] = op1;
break;
}
case LineTy_Out_Imm_Imm: {
uint16_t op1 = line->op1.imm;
uint16_t op2 = line->op2.imm;
uint32_t ins = Op_In;
set_is_imm(&ins);
ins |= 1 << 7;
out[ip++] = (uint16_t)ins;
out[ip++] = op1;
out[ip++] = op2;
break;
}
case LineTy_Call_Reg: {
uint16_t op1 = line->op1.reg;

View File

@ -44,6 +44,10 @@ typedef enum {
LineTy_Mov16_MemLabel_Reg,
LineTy_In_Reg,
LineTy_In_Imm,
LineTy_Out_Reg_Reg,
LineTy_Out_Reg_Imm,
LineTy_Out_Imm_Reg,
LineTy_Out_Imm_Imm,
LineTy_Call_Reg,
LineTy_Call_Imm,
LineTy_Call_Label,
@ -114,6 +118,7 @@ typedef struct {
uint16_t offset;
} Line;
uint16_t assemble_line(uint16_t* out, const Line* line);
uint16_t assemble_lines_with_labels(
uint16_t* out, const Line* lines, size_t lines_size);
@ -139,8 +144,8 @@ Line s_mov8_r_r(Reg dst_reg, Reg op2_reg);
Line s_mov8_r_i(Reg dst_reg, uint16_t op2_imm);
Line s_mov8_r_mr(Reg dst_reg, Reg op2_reg, uint16_t op2_offset);
Line s_mov8_r_mi(Reg dst_reg, uint16_t op2_imm);
Line s_mov8_mr_r(Reg dst_reg, Reg op2_reg);
Line s_mov8_mr_i(Reg dst_reg, uint16_t op2_imm);
Line s_mov8_mr_r(Reg dst_reg, uint16_t dst_offset, Reg op2_reg);
Line s_mov8_mr_i(Reg dst_reg, uint16_t dst_offset, uint16_t op2_imm);
Line s_mov8_mi_r(uint16_t dst_imm, Reg op2_reg);
Line s_mov8_mi_i(uint16_t dst_imm, uint16_t op2_imm);
Line s_mov16_r_r(Reg dst_reg, Reg op2_reg);
@ -156,6 +161,10 @@ Line s_mov16_mi_i(uint16_t dst_imm, uint16_t op2_imm);
Line s_mov16_ml_r(int dst_label, Reg op2_reg);
Line s_in_r(Reg dst_reg, Reg op1_reg);
Line s_in_i(Reg dst_reg, uint16_t op1_imm);
Line s_out_r_r(Reg op1_reg, Reg op2_reg);
Line s_out_r_i(Reg op1_reg, uint16_t op2_imm);
Line s_out_i_r(uint16_t op1_imm, Reg op2_reg);
Line s_out_i_i(uint16_t op1_imm, uint16_t op2_imm);
Line s_call_r(Reg op1_reg);
Line s_call_i(uint16_t op1_imm);
Line s_call_l(int op1_label);

View File

@ -166,20 +166,22 @@ Line s_mov8_r_mi(Reg dst_reg, uint16_t op2_imm)
.op2 = (Ex) { .imm = op2_imm },
};
}
Line s_mov8_mr_r(Reg dst_reg, Reg op2_reg)
Line s_mov8_mr_r(Reg dst_reg, uint16_t dst_offset, Reg op2_reg)
{
return (Line) {
.ty = LineTy_Mov8_MemReg_Reg,
.dst = (Ex) { .reg = (uint16_t)dst_reg },
.op2 = (Ex) { .reg = (uint16_t)op2_reg },
.offset = dst_offset,
};
}
Line s_mov8_mr_i(Reg dst_reg, uint16_t op2_imm)
Line s_mov8_mr_i(Reg dst_reg, uint16_t dst_offset, uint16_t op2_imm)
{
return (Line) {
.ty = LineTy_Mov8_MemReg_Imm,
.dst = (Ex) { .reg = (uint16_t)dst_reg },
.op2 = (Ex) { .imm = op2_imm },
.offset = dst_offset,
};
}
Line s_mov8_mi_r(uint16_t dst_imm, Reg op2_reg)
@ -305,6 +307,38 @@ Line s_in_i(Reg dst_reg, uint16_t op1_imm)
.op1 = (Ex) { .imm = op1_imm },
};
}
Line s_out_r_r(Reg op1_reg, Reg op2_reg)
{
return (Line) {
.ty = LineTy_Out_Reg_Reg,
.op1 = (Ex) { .reg = (uint16_t)op1_reg },
.op2 = (Ex) { .reg = (uint16_t)op2_reg },
};
}
Line s_out_r_i(Reg op1_reg, uint16_t op2_imm)
{
return (Line) {
.ty = LineTy_Out_Reg_Imm,
.op1 = (Ex) { .reg = (uint16_t)op1_reg },
.op2 = (Ex) { .imm = op2_imm },
};
}
Line s_out_i_r(uint16_t op1_imm, Reg op2_reg)
{
return (Line) {
.ty = LineTy_Out_Imm_Reg,
.op1 = (Ex) { .imm = op1_imm },
.op2 = (Ex) { .reg = (uint16_t)op2_reg },
};
}
Line s_out_i_i(uint16_t op1_imm, uint16_t op2_imm)
{
return (Line) {
.ty = LineTy_Out_Imm_Imm,
.op1 = (Ex) { .imm = op1_imm },
.op2 = (Ex) { .imm = op2_imm },
};
}
Line s_call_r(Reg op1_reg)
{
return (Line) {

1383
asm/main.c

File diff suppressed because it is too large Load Diff

View File

@ -5,13 +5,13 @@ start:
mov rsp, 2048 - 2
lit interrupt_table
or rfl, rfl, 1 << Fl_Int
or rfl, rfl, 1 << 5 ; Fl_Int
or rfl, Rfl, 1 << Fl_Vcd
or rfl, rfl, 1 << 6 ; Fl_Vcd
mov16 r0, 512
mov16 r1, 1
int Int_DiskRead
mov r0, 512
mov r1, 1
int 0 ; Int_DiskRead
main_loop:
hlt
@ -20,15 +20,15 @@ main_loop:
interrupt_table:
; size
d16 1
data keyboard_interrupt
d16 keyboard_interrupt
nop
keyboard_interrupt:
and rfl, rfl, !(1 << Fl_Int)
and rfl, rfl, !(1 << 5) ; Fl_Int
; push rbp
add rsp, rsp, 2
mov u16 [rsp], rbp
mov rbp, Rsp
mov rbp, rsp
; push r0
add rsp, rsp, 2
mov u16 [rsp], r0
@ -42,51 +42,51 @@ keyboard_interrupt:
add rsp, rsp, 2
mov u16 [rsp], r3
in r0, Device_Keyboard
in r0, 0 ; Device_Keyboard
cmp r0, 44
mov r1, rfl
and r1, r1, 1 << Fl_Eq
and r1, r1, 1 << 1 ; Fl_Eq
jnz r1, .L0
cmp r0, 42
mov16 r1, rfl
and r1, r1, 1 << Fl_Eq
mov r1, rfl
and r1, r1, 1 << 1 ; Fl_Eq
jnz r1, .L1
cmp r0, 40
mov r1, rfl
and r1, r1, 1 << Fl_Eq
and r1, r1, 1 << 1 ; Fl_Eq
jnz r1, .L2
jmp .L3
.L0:
mov R0, ' '
mov r0, ' '
call put_char
jmp .L4
.L1:
mov r1, screen_x
mov r1, u16 [screen_x]
cmp r1, 0
mov r2, rfl
and r2, r2, 1 << Fl_Eq
and r2, r2, 1 << 1 ; Fl_Eq
jnz r2, .L4
sub r1, r1, 1
mov screen_x, R1
; mov r0, ' '
mov u16 [screen_x], r1
mov r0, ' '
call put_char
mov16 r1, screen_x
mov r1, u16 [screen_x]
sub r1, r1, 1
mov screen_x, R1
mov u16 [screen_x], r1
jmp .L4
.L2:
mov r1, screen_y
mov r1, u16 [screen_y]
add r1, r1, 1
mov screen_y, R1
mov u16 [screen_y], r1
mov r1, 0
mov screen_x, R1
mov u16 [screen_x], r1
jmp .L4
.L3:
@ -112,7 +112,7 @@ keyboard_interrupt:
; pop rbp
mov rbp, u16 [rsp]
sub rsp, rsp, 2
or rfl, rfl, 1 << Fl_Int
or rfl, rfl, 1 << 5 ; Fl_Int
iret
put_char:
@ -127,29 +127,29 @@ put_char:
add rsp, rsp, 2
mov u16 [rsp], r2
mov r2, screen_y
mul r2, r2, vcd_width_in_ch
mov r1, screen_x
mov r2, u16 [screen_y]
mul r2, r2, 40 ; vcd_width_in_ch
mov r1, u16 [screen_x]
add r1, r1, 0x0c00
add r1, r1, r2
mov r1, r0
mov u8 [r1], r0
mov r1, screen_x
mov r1, u16 [screen_x]
add r1, r1, 1
mov screen_x, r1
mov u16 [screen_x], r1
cmp r1, vcd_width_in_ch
cmp r1, 40 ; vcd_width_in_ch
mov r2, rfl
and r2, r2, 1 << Fl_Eq
and r2, r2, 1 << 1 ; Fl_Eq
jnz r2, .L0
jmp .L1
.L0:
mov r1, screen_y
mov r1, u16 [screen_y]
add r1, r1, 1
mov screen_y, r1
mov u16 [screen_y], r1
mov r1, 0
mov screen_x, r1
mov u16 [screen_x], r1
.L1:
; pop r1

View File

@ -162,7 +162,7 @@ void write_program(FILE* fp)
s_mov16_r_ml(R1, screen_x),
s_add_i(R1, R1, 0x0c00),
s_add_r(R1, R1, R2),
s_mov8_mr_r(R1, R0),
s_mov8_mr_r(R1, 0, R0),
s_mov16_r_ml(R1, screen_x),
s_add_i(R1, R1, 1),

View File

@ -413,8 +413,16 @@ __attribute__((unused)) static inline void dump_program(uint16_t* program)
}
}
int main(void)
typedef struct {
const char* disk_file;
} Args;
static inline Args parse_args(int argc, char** argv);
int main(int argc, char** argv)
{
Args args = parse_args(argc, argv);
int res;
int label_ids = 0;
@ -425,10 +433,12 @@ int main(void)
exit(1);
}
FILE* fp = fopen("build/image", "rb");
FILE* fp = fopen(args.disk_file, "rb");
if (!fp) {
fprintf(
stderr, "error: could not open build/image: %s\n", strerror(errno));
fprintf(stderr,
"error: could not open %s: %s\n",
args.disk_file,
strerror(errno));
exit(1);
}
@ -441,6 +451,28 @@ int main(void)
sdldevice_destroy(&io_device);
}
static inline Args parse_args(int argc, char** argv)
{
const char* disk_file = "build/image";
for (int i = 1; i < argc; ++i) {
if (strcmp(argv[i], "-i") == 0 || strcmp(argv[i], "--disk-file") == 0) {
if (i + 1 >= argc) {
fprintf(
stderr, "error: expected filename after '%s'\n", argv[i]);
exit(1);
}
disk_file = argv[i + 1];
i += 1;
} else {
fprintf(stderr, "error: unrecognized argument '%s'\n", argv[i]);
exit(1);
}
}
return (Args) {
disk_file,
};
}
const char* __asan_default_options(void)
{
return "detect_leaks=0";

View File

@ -222,9 +222,9 @@ void vm_start(Drive* boot_drive, IODevice* io_device)
break;
}
case Op_Out: {
uint16_t op1 = ins_op2(vm, ins);
uint16_t device_id = ins_op1_or_imm(vm, ins);
handle_device_write(vm, op1, device_id);
uint16_t op2 = ins_reg_val_or_imm(vm, ins, 7, 13, 0x7);
handle_device_write(vm, op2, device_id);
break;
}
case Op_Call: {