assember works
This commit is contained in:
parent
ba643a68a3
commit
7bf7eae401
48
asm/asm.c
48
asm/asm.c
@ -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;
|
||||||
|
|
||||||
|
13
asm/asm.h
13
asm/asm.h
@ -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);
|
||||||
|
38
asm/ctors.c
38
asm/ctors.c
@ -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) {
|
||||||
|
1383
asm/main.c
1383
asm/main.c
File diff suppressed because it is too large
Load Diff
@ -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
|
||||||
|
@ -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),
|
||||||
|
40
vm/main.c
40
vm/main.c
@ -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";
|
||||||
|
4
vm/vm.c
4
vm/vm.c
@ -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: {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user