text works

This commit is contained in:
sfja 2025-03-31 03:24:59 +02:00
parent ad79f82f1f
commit 415f9b72f7
3 changed files with 362 additions and 25 deletions

View File

@ -43,6 +43,14 @@ Line s_jmp_l(int op1_label)
.op1 = (Ex) { .label = op1_label }, .op1 = (Ex) { .label = op1_label },
}; };
} }
Line s_mov8_mr_r(Reg dst_reg, Reg op2_reg)
{
return (Line) {
.ty = LineTy_Mov8_MemReg_Reg,
.dst = (Ex) { .reg = (uint16_t)dst_reg },
.op2 = (Ex) { .reg = (uint16_t)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)
{ {
return (Line) { return (Line) {
@ -84,6 +92,22 @@ Line s_mov16_r_mr(Reg dst_reg, Reg op2_reg, uint16_t op2_offset)
.offset = op2_offset, .offset = op2_offset,
}; };
} }
Line s_mov16_r_mi(Reg dst_reg, uint16_t op2_imm)
{
return (Line) {
.ty = LineTy_Mov16_Reg_MemImm,
.dst = (Ex) { .reg = (uint16_t)dst_reg },
.op2 = (Ex) { .imm = op2_imm },
};
}
Line s_mov16_r_ml(Reg dst_reg, int op2_label)
{
return (Line) {
.ty = LineTy_Mov16_Reg_MemLabel,
.dst = (Ex) { .reg = (uint16_t)dst_reg },
.op2 = (Ex) { .label = op2_label },
};
}
Line s_mov16_mr_r(Reg dst_reg, uint16_t dst_offset, Reg op2_reg) Line s_mov16_mr_r(Reg dst_reg, uint16_t dst_offset, Reg op2_reg)
{ {
return (Line) { return (Line) {
@ -93,6 +117,14 @@ Line s_mov16_mr_r(Reg dst_reg, uint16_t dst_offset, Reg op2_reg)
.offset = dst_offset, .offset = dst_offset,
}; };
} }
Line s_mov16_ml_r(int dst_label, Reg op2_reg)
{
return (Line) {
.ty = LineTy_Mov16_MemLabel_Reg,
.dst = (Ex) { .label = dst_label },
.op2 = (Ex) { .reg = (uint16_t)op2_reg },
};
}
Line s_in_i(Reg dst_reg, uint16_t op1_imm) Line s_in_i(Reg dst_reg, uint16_t op1_imm)
{ {
return (Line) { return (Line) {
@ -121,7 +153,7 @@ Line s_iret(void)
} }
#define DEFINE_BINARY_I(FN, LINETY) \ #define DEFINE_BINARY_I(FN, LINETY) \
Line s_##FN##_r_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) \ Line s_##FN##_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm) \
{ \ { \
return (Line) { \ return (Line) { \
.ty = LineTy_##LINETY##_Imm, \ .ty = LineTy_##LINETY##_Imm, \
@ -213,6 +245,21 @@ void assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size)
ADD_LABEL(line->op1.label); ADD_LABEL(line->op1.label);
break; break;
} }
case LineTy_Mov8_MemReg_Reg: {
uint16_t dst = line->dst.reg;
uint16_t op2 = line->op2.reg;
uint32_t ins = Op_Mov8;
add_op2_reg(&ins, op2);
set_mov_is_memory(&ins);
set_mov_addr_is_reg(&ins);
set_mov_is_store(&ins);
add_dst_reg(&ins, dst);
out[ip++] = (uint16_t)ins;
out[ip++] = line->offset;
break;
}
case LineTy_Mov8_MemImm_Imm: { case LineTy_Mov8_MemImm_Imm: {
uint16_t dst = line->dst.imm; uint16_t dst = line->dst.imm;
uint16_t op2 = line->op2.imm; uint16_t op2 = line->op2.imm;
@ -277,6 +324,31 @@ void assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size)
out[ip++] = line->offset; out[ip++] = line->offset;
break; break;
} }
case LineTy_Mov16_Reg_MemImm: {
uint16_t dst = line->dst.reg;
uint16_t op2 = line->op2.imm;
uint32_t ins = Op_Mov16;
set_is_imm(&ins);
set_mov_is_memory(&ins);
add_dst_reg(&ins, dst);
out[ip++] = (uint16_t)ins;
out[ip++] = op2;
break;
}
case LineTy_Mov16_Reg_MemLabel: {
uint16_t dst = line->dst.reg;
uint32_t ins = Op_Mov16;
set_is_imm(&ins);
set_mov_is_memory(&ins);
add_dst_reg(&ins, dst);
out[ip++] = (uint16_t)ins;
ADD_LABEL(line->op2.label);
break;
}
case LineTy_Mov16_MemReg_Reg: { case LineTy_Mov16_MemReg_Reg: {
uint16_t dst = line->dst.reg; uint16_t dst = line->dst.reg;
uint16_t op2 = line->op2.reg; uint16_t op2 = line->op2.reg;
@ -292,6 +364,18 @@ void assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size)
out[ip++] = line->offset; out[ip++] = line->offset;
break; break;
} }
case LineTy_Mov16_MemLabel_Reg: {
uint16_t op2 = line->op2.reg;
uint32_t ins = Op_Mov16;
add_op2_reg(&ins, op2);
set_mov_is_memory(&ins);
set_mov_is_store(&ins);
out[ip++] = (uint16_t)ins;
ADD_LABEL(line->dst.label);
break;
}
case LineTy_In_Imm: { case LineTy_In_Imm: {
uint16_t dst = line->dst.reg; uint16_t dst = line->dst.reg;
uint16_t op1 = line->op1.imm; uint16_t op1 = line->op1.imm;
@ -429,9 +513,9 @@ static inline uint16_t linety_arithm_ins(LineTy ty)
return Op_Or; return Op_Or;
case LineTy_And_Imm: case LineTy_And_Imm:
return Op_And; return Op_And;
case LineTy_Add_Reg_Imm: case LineTy_Add_Imm:
return Op_Add; return Op_Add;
case LineTy_Sub_Reg_Imm: case LineTy_Sub_Imm:
return Op_Sub; return Op_Sub;
default: default:
fprintf(stderr, "error: line type '%d' not handled\n", ty); fprintf(stderr, "error: line type '%d' not handled\n", ty);

View File

@ -11,12 +11,16 @@ typedef enum {
LineTy_Nop, LineTy_Nop,
LineTy_Hlt, LineTy_Hlt,
LineTy_Jmp_Label, LineTy_Jmp_Label,
LineTy_Mov8_MemReg_Reg,
LineTy_Mov8_MemImm_Imm, LineTy_Mov8_MemImm_Imm,
LineTy_Mov8_MemImm_Reg, LineTy_Mov8_MemImm_Reg,
LineTy_Mov16_Reg_Reg, LineTy_Mov16_Reg_Reg,
LineTy_Mov16_Reg_Imm, LineTy_Mov16_Reg_Imm,
LineTy_Mov16_Reg_MemReg, LineTy_Mov16_Reg_MemReg,
LineTy_Mov16_Reg_MemImm,
LineTy_Mov16_Reg_MemLabel,
LineTy_Mov16_MemReg_Reg, LineTy_Mov16_MemReg_Reg,
LineTy_Mov16_MemLabel_Reg,
LineTy_In_Imm, LineTy_In_Imm,
LineTy_Lit_Imm, LineTy_Lit_Imm,
LineTy_Lit_Label, LineTy_Lit_Label,
@ -51,12 +55,16 @@ Line s_data_l(int label);
Line s_nop(void); Line s_nop(void);
Line s_hlt(void); Line s_hlt(void);
Line s_jmp_l(int op1_label); Line s_jmp_l(int op1_label);
Line s_mov8_mr_r(Reg dst_reg, 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_mov8_mi_r(uint16_t dst_imm, Reg op2_reg); Line s_mov8_mi_r(uint16_t dst_imm, Reg op2_reg);
Line s_mov16_r_r(Reg dst_reg, Reg op2_reg); Line s_mov16_r_r(Reg dst_reg, Reg op2_reg);
Line s_mov16_r_i(Reg dst_reg, uint16_t op2_imm); Line s_mov16_r_i(Reg dst_reg, uint16_t op2_imm);
Line s_mov16_r_mr(Reg dst_reg, Reg op2_reg, uint16_t op2_offset); Line s_mov16_r_mr(Reg dst_reg, Reg op2_reg, uint16_t op2_offset);
Line s_mov16_r_mi(Reg dst_reg, uint16_t op2_imm);
Line s_mov16_r_ml(Reg dst_reg, int op2_label);
Line s_mov16_mr_r(Reg dst_reg, uint16_t dst_offset, Reg op2_reg); Line s_mov16_mr_r(Reg dst_reg, uint16_t dst_offset, Reg op2_reg);
Line s_mov16_ml_r(int dst_label, Reg op2_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_lit_i(uint16_t op1_imm); Line s_lit_i(uint16_t op1_imm);
Line s_lit_l(int op1_label); Line s_lit_l(int op1_label);

289
vm/main.c
View File

@ -187,8 +187,8 @@ extern const bool charset[][ch_height][ch_width];
void sdldevice_set_char(IODevice* io_device, uint16_t offset, uint8_t value) void sdldevice_set_char(IODevice* io_device, uint16_t offset, uint8_t value)
{ {
printf("value = %d '%c', offset = %d\n", value, value, offset); // printf("value = %d '%c', offset = %d\n", value, value, offset);
if (value < 'A' || value > 'C') if (!((value >= 'A' && value <= 'Z') || value == ' '))
return; return;
SdlDevice* device = io_device->self; SdlDevice* device = io_device->self;
@ -380,24 +380,22 @@ int main(void)
{ {
int res; int res;
int main_loop = 1; int label_ids = 0;
int interrupt_table = 2;
int keyboard_interrupt = 3; int main_loop = label_ids++;
int interrupt_table = label_ids++;
int keyboard_interrupt = label_ids++;
int screen_x = label_ids++;
int screen_y = label_ids++;
#define L(LABEL) s_label(LABEL) #define L(LABEL) s_label(LABEL)
Line program_asm[] = { Line program_asm[] = {
// clang-format off // clang-format off
s_nop(), s_nop(),
// set video character display flag // set video character display flag
s_or_i(Rfl, Rfl, 1 << Fl_Vcd), s_or_i(Rfl, Rfl, 1 << Fl_Vcd),
// print ABC
s_mov8_mi_i(0x0c00 + 0, 'A'),
s_mov8_mi_i(0x0c00 + 1, 'B'),
s_mov8_mi_i(0x0c00 + 2, 'C'),
// setup stack // setup stack
s_mov16_r_i(Rbp, 2048), s_mov16_r_i(Rbp, 2048),
// rsp points *at* the top element // rsp points *at* the top element
@ -417,29 +415,36 @@ int main(void)
s_data_l(keyboard_interrupt), s_data_l(keyboard_interrupt),
s_nop(), s_nop(),
L(keyboard_interrupt), L(keyboard_interrupt),
s_nop(),
s_nop(),
// clear interrupt flag
s_and_i(Rfl, Rfl, (uint16_t)~(1 << Fl_Int)), s_and_i(Rfl, Rfl, (uint16_t)~(1 << Fl_Int)),
// setup stack frame
s_push_r(Rbp), s_push_r(Rbp),
s_mov16_r_r(Rbp, Rsp), s_mov16_r_r(Rbp, Rsp),
// conserve registers
s_push_r(R0), s_push_r(R0),
s_push_r(R1),
s_push_r(R2),
// read keyboard port // read keyboard port
s_in_i(R0, 0), s_in_i(R0, 0),
s_add_i(R0, R0, 'A' - 4), s_add_i(R0, R0, 'A' - 4),
s_mov8_mi_r(0x0c00 + 4, R0),
// tear down frame s_mov16_r_ml(R1, screen_x),
s_add_i(R1, R1, 0x0c00),
s_mov8_mr_r(R1, R0),
s_mov16_r_ml(R1, screen_x),
s_add_i(R1, R1, 1),
s_mov16_ml_r(screen_x, R1),
s_pop_r(R2),
s_pop_r(R1),
s_pop_r(R0), s_pop_r(R0),
s_mov16_r_r(Rsp, Rbp), s_mov16_r_r(Rsp, Rbp),
s_pop_r(Rbp), s_pop_r(Rbp),
// set interrupt flag
s_or_i(Rfl, Rfl, 1 << Fl_Int), s_or_i(Rfl, Rfl, 1 << Fl_Int),
// return from interrupt
s_iret(), s_iret(),
L(screen_x),
s_data_i(0),
L(screen_y),
s_data_i(0),
// clang-format on // clang-format on
}; };
@ -449,9 +454,9 @@ int main(void)
uint16_t* program = calloc(512, sizeof(uint16_t)); uint16_t* program = calloc(512, sizeof(uint16_t));
assemble_to_binary(program, program_asm, program_asm_size); assemble_to_binary(program, program_asm, program_asm_size);
dump_program(program); // dump_program(program);
/*return 0;*/ // return 0;
MemDrive drive; MemDrive drive;
memdrive_construct(&drive, (uint64_t*)program, 512); memdrive_construct(&drive, (uint64_t*)program, 512);
@ -476,6 +481,16 @@ const char* __asan_default_options(void)
#define t true, #define t true,
const bool charset[][ch_height][ch_width] = { const bool charset[][ch_height][ch_width] = {
[' '] = {
{ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ },
{ _ _ _ _ _ _ _ _ },
},
['A'] = { ['A'] = {
{ _ _ _ _ _ _ _ _ }, { _ _ _ _ _ _ _ _ },
{ _ _ _ t t _ _ _ }, { _ _ _ t t _ _ _ },
@ -506,4 +521,234 @@ const bool charset[][ch_height][ch_width] = {
{ _ t t t t t t _ }, { _ t t t t t t _ },
{ _ _ t t t t _ _ }, { _ _ t t t t _ _ },
}, },
['D'] = {
{ _ _ _ _ _ _ _ _ },
{ _ t t t t t _ _ },
{ _ t t t t t t _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ t t t t t t _ },
{ _ t t t t t _ _ },
},
['E'] = {
{ _ _ _ _ _ _ _ _ },
{ _ t t t t t t _ },
{ _ t t t t t t _ },
{ _ t t _ _ _ _ _ },
{ _ t t t t t t _ },
{ _ t t _ _ _ _ _ },
{ _ t t t t t t _ },
{ _ t t t t t t _ },
},
['F'] = {
{ _ _ _ _ _ _ _ _ },
{ _ t t t t t t _ },
{ _ t t t t t t _ },
{ _ t t _ _ _ _ _ },
{ _ t t t t _ _ _ },
{ _ t t t t _ _ _ },
{ _ t t _ _ _ _ _ },
{ _ t t _ _ _ _ _ },
},
['G'] = {
{ _ _ _ _ _ _ _ _ },
{ _ t t t t t t _ },
{ _ t t t t t t _ },
{ _ t t _ _ _ _ _ },
{ _ t t _ t t t _ },
{ _ t t _ _ t t _ },
{ _ t t t t t t _ },
{ _ t t t t t t _ },
},
['H'] = {
{ _ _ _ _ _ _ _ _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ t t t t t t _ },
{ _ t t t t t t _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
},
['I'] = {
{ _ _ _ _ _ _ _ _ },
{ _ t t t t t t _ },
{ _ t t t t t t _ },
{ _ _ _ t t _ _ _ },
{ _ _ _ t t _ _ _ },
{ _ _ _ t t _ _ _ },
{ _ t t t t t t _ },
{ _ t t t t t t _ },
},
['J'] = {
{ _ _ _ _ _ _ _ _ },
{ _ t t t t t t _ },
{ _ t t t t t t _ },
{ _ _ _ _ _ t t _ },
{ _ _ _ _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ t t t t t t _ },
{ _ _ t t t t _ _ },
},
['K'] = {
{ _ _ _ _ _ _ _ _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ t t _ t t t _ },
{ _ t t t t t _ _ },
{ _ t t t t t _ _ },
{ _ t t _ t t t _ },
{ _ t t _ _ t t _ },
},
['L'] = {
{ _ _ _ _ _ _ _ _ },
{ _ t t _ _ _ _ _ },
{ _ t t _ _ _ _ _ },
{ _ t t _ _ _ _ _ },
{ _ t t _ _ _ _ _ },
{ _ t t _ _ _ _ _ },
{ _ t t t t t t _ },
{ _ t t t t t t _ },
},
['M'] = {
{ _ _ _ _ _ _ _ _ },
{ t t t _ _ t t t },
{ t t t t t t t t },
{ t t _ t t _ t t },
{ t t _ _ _ _ t t },
{ t t _ _ _ _ t t },
{ t t _ _ _ _ t t },
{ t t _ _ _ _ t t },
},
['N'] = {
{ _ _ _ _ _ _ _ _ },
{ _ t t _ _ t t _ },
{ _ t t t _ t t _ },
{ _ t t t t t t _ },
{ _ t t _ t t t _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
},
['O'] = {
{ _ _ _ _ _ _ _ _ },
{ _ _ t t t t _ _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ _ t t t t _ _ },
},
['P'] = {
{ _ _ _ _ _ _ _ _ },
{ _ t t t t t _ _ },
{ _ t t t t t _ _ },
{ _ t t _ _ t t _ },
{ _ t t t t t t _ },
{ _ t t t t t _ _ },
{ _ t t _ _ _ _ _ },
{ _ t t _ _ _ _ _ },
},
['Q'] = {
{ _ _ _ _ _ _ _ _ },
{ _ _ t t t t _ _ },
{ _ t t t t t t _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ t t _ t t t _ },
{ _ t t t t t t _ },
{ _ _ t t t t t t },
},
['R'] = {
{ _ _ _ _ _ _ _ _ },
{ _ t t t t t _ _ },
{ _ t t t t t t _ },
{ _ t t _ _ t t _ },
{ _ t t t t t t _ },
{ _ t t t t t _ _ },
{ _ t t _ t t _ _ },
{ _ t t _ _ t t _ },
},
['S'] = {
{ _ _ _ _ _ _ _ _ },
{ _ _ t t t t _ _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ _ _ _ },
{ _ _ t t t t _ _ },
{ _ _ _ _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ _ t t t t _ _ },
},
['T'] = {
{ _ _ _ _ _ _ _ _ },
{ _ t t t t t t _ },
{ _ t t t t t t _ },
{ _ _ _ t t _ _ _ },
{ _ _ _ t t _ _ _ },
{ _ _ _ t t _ _ _ },
{ _ _ _ t t _ _ _ },
{ _ _ _ t t _ _ _ },
},
['U'] = {
{ _ _ _ _ _ _ _ _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ t t t t t t _ },
{ _ _ t t t t _ _ },
},
['V'] = {
{ _ _ _ _ _ _ _ _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ t t t t t t _ },
{ _ _ t t t t _ _ },
{ _ _ _ t t _ _ _ },
},
['W'] = {
{ _ _ _ _ _ _ _ _ },
{ t t _ _ _ _ t t },
{ t t _ _ _ _ t t },
{ t t _ _ _ _ t t },
{ t t _ t t _ t t },
{ t t _ t t _ t t },
{ t t t t t t t t },
{ t t t _ _ t t t },
},
['X'] = {
{ _ _ _ _ _ _ _ _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ _ t t t t _ _ },
{ _ _ t t t t _ _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
},
['Y'] = {
{ _ _ _ _ _ _ _ _ },
{ _ t t _ _ t t _ },
{ _ t t _ _ t t _ },
{ _ _ t t t t _ _ },
{ _ _ _ t t _ _ _ },
{ _ _ _ t t _ _ _ },
{ _ _ _ t t _ _ _ },
{ _ _ _ t t _ _ _ },
},
['Z'] = {
{ _ _ _ _ _ _ _ _ },
{ _ t t t t t t _ },
{ _ t t t t t t _ },
{ _ _ _ _ t t _ _ },
{ _ _ _ t t _ _ _ },
{ _ _ t t _ _ _ _ },
{ _ t t t t t t _ },
{ _ t t t t t t _ },
},
}; };