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;
|
||||
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;
|
||||
|
||||
|
13
asm/asm.h
13
asm/asm.h
@ -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);
|
||||
|
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 },
|
||||
};
|
||||
}
|
||||
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
1383
asm/main.c
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
|
@ -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),
|
||||
|
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 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";
|
||||
|
4
vm/vm.c
4
vm/vm.c
@ -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: {
|
||||
|
Loading…
x
Reference in New Issue
Block a user