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; out[ip++] = op1;
break; 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: { case LineTy_Call_Reg: {
uint16_t op1 = line->op1.reg; uint16_t op1 = line->op1.reg;

View File

@ -44,6 +44,10 @@ typedef enum {
LineTy_Mov16_MemLabel_Reg, LineTy_Mov16_MemLabel_Reg,
LineTy_In_Reg, LineTy_In_Reg,
LineTy_In_Imm, LineTy_In_Imm,
LineTy_Out_Reg_Reg,
LineTy_Out_Reg_Imm,
LineTy_Out_Imm_Reg,
LineTy_Out_Imm_Imm,
LineTy_Call_Reg, LineTy_Call_Reg,
LineTy_Call_Imm, LineTy_Call_Imm,
LineTy_Call_Label, LineTy_Call_Label,
@ -114,6 +118,7 @@ typedef struct {
uint16_t offset; uint16_t offset;
} Line; } Line;
uint16_t assemble_line(uint16_t* out, const Line* line);
uint16_t assemble_lines_with_labels( uint16_t assemble_lines_with_labels(
uint16_t* out, const Line* lines, size_t lines_size); 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_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_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_r_mi(Reg dst_reg, uint16_t 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);
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);
Line s_mov8_mi_r(uint16_t dst_imm, Reg op2_reg); 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_mov8_mi_i(uint16_t dst_imm, uint16_t op2_imm);
Line s_mov16_r_r(Reg dst_reg, Reg op2_reg); 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_mov16_ml_r(int dst_label, Reg op2_reg);
Line s_in_r(Reg dst_reg, Reg op1_reg); Line s_in_r(Reg dst_reg, Reg op1_reg);
Line s_in_i(Reg dst_reg, uint16_t op1_imm); 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_r(Reg op1_reg);
Line s_call_i(uint16_t op1_imm); Line s_call_i(uint16_t op1_imm);
Line s_call_l(int op1_label); 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 }, .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) { return (Line) {
.ty = LineTy_Mov8_MemReg_Reg, .ty = LineTy_Mov8_MemReg_Reg,
.dst = (Ex) { .reg = (uint16_t)dst_reg }, .dst = (Ex) { .reg = (uint16_t)dst_reg },
.op2 = (Ex) { .reg = (uint16_t)op2_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) { return (Line) {
.ty = LineTy_Mov8_MemReg_Imm, .ty = LineTy_Mov8_MemReg_Imm,
.dst = (Ex) { .reg = (uint16_t)dst_reg }, .dst = (Ex) { .reg = (uint16_t)dst_reg },
.op2 = (Ex) { .imm = op2_imm }, .op2 = (Ex) { .imm = op2_imm },
.offset = dst_offset,
}; };
} }
Line s_mov8_mi_r(uint16_t dst_imm, Reg op2_reg) 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 }, .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) Line s_call_r(Reg op1_reg)
{ {
return (Line) { return (Line) {

1381
asm/main.c

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -162,7 +162,7 @@ void write_program(FILE* fp)
s_mov16_r_ml(R1, screen_x), s_mov16_r_ml(R1, screen_x),
s_add_i(R1, R1, 0x0c00), s_add_i(R1, R1, 0x0c00),
s_add_r(R1, R1, R2), 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_mov16_r_ml(R1, screen_x),
s_add_i(R1, R1, 1), 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 res;
int label_ids = 0; int label_ids = 0;
@ -425,10 +433,12 @@ int main(void)
exit(1); exit(1);
} }
FILE* fp = fopen("build/image", "rb"); FILE* fp = fopen(args.disk_file, "rb");
if (!fp) { if (!fp) {
fprintf( fprintf(stderr,
stderr, "error: could not open build/image: %s\n", strerror(errno)); "error: could not open %s: %s\n",
args.disk_file,
strerror(errno));
exit(1); exit(1);
} }
@ -441,6 +451,28 @@ int main(void)
sdldevice_destroy(&io_device); 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) const char* __asan_default_options(void)
{ {
return "detect_leaks=0"; return "detect_leaks=0";

View File

@ -222,9 +222,9 @@ void vm_start(Drive* boot_drive, IODevice* io_device)
break; break;
} }
case Op_Out: { case Op_Out: {
uint16_t op1 = ins_op2(vm, ins);
uint16_t device_id = ins_op1_or_imm(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; break;
} }
case Op_Call: { case Op_Call: {