backspace and return

This commit is contained in:
sfja 2025-03-31 18:47:41 +02:00
parent cad6ed9604
commit b9a837e3c7
6 changed files with 314 additions and 83 deletions

View File

@ -13,13 +13,14 @@ if &shortmess =~ 'A'
else
set shortmess=aoO
endif
badd +437 vm/main.c
badd +48 Makefile
badd +10 vm/vm.h
badd +181 vm/vm.c
badd +14 vm/asm.h
badd +263 vm/asm.c
badd +440 vm/main.c
badd +11 Makefile
badd +12 vm/vm.h
badd +262 vm/vm.c
badd +91 vm/asm.h
badd +378 vm/asm.c
badd +747 ~/.config/nvim/init.lua
badd +10 compile_flags.txt
argglobal
%argdel
$argadd vm/main.c
@ -28,7 +29,7 @@ tabnew +setlocal\ bufhidden=wipe
tabnew +setlocal\ bufhidden=wipe
tabnew +setlocal\ bufhidden=wipe
tabrewind
edit vm/main.c
edit Makefile
let s:save_splitbelow = &splitbelow
let s:save_splitright = &splitright
set splitbelow splitright
@ -45,9 +46,10 @@ set winminheight=0
set winheight=1
set winminwidth=0
set winwidth=1
exe 'vert 1resize ' . ((&columns * 123 + 128) / 256)
exe 'vert 2resize ' . ((&columns * 132 + 128) / 256)
exe 'vert 1resize ' . ((&columns * 71 + 128) / 256)
exe 'vert 2resize ' . ((&columns * 184 + 128) / 256)
argglobal
balt compile_flags.txt
setlocal fdm=manual
setlocal fde=0
setlocal fmr={{{,}}}
@ -58,19 +60,19 @@ setlocal fdn=20
setlocal fen
silent! normal! zE
let &fdl = &fdl
let s:l = 437 - ((37 * winheight(0) + 32) / 65)
let s:l = 11 - ((10 * winheight(0) + 32) / 65)
if s:l < 1 | let s:l = 1 | endif
keepjumps exe s:l
normal! zt
keepjumps 437
normal! 012|
keepjumps 11
normal! 027|
wincmd w
argglobal
if bufexists(fnamemodify("Makefile", ":p")) | buffer Makefile | else | edit Makefile | endif
if bufexists(fnamemodify("vm/main.c", ":p")) | buffer vm/main.c | else | edit vm/main.c | endif
if &buftype ==# 'terminal'
silent file Makefile
silent file vm/main.c
endif
balt vm/main.c
balt vm/asm.c
setlocal fdm=manual
setlocal fde=0
setlocal fmr={{{,}}}
@ -81,15 +83,16 @@ setlocal fdn=20
setlocal fen
silent! normal! zE
let &fdl = &fdl
let s:l = 15 - ((14 * winheight(0) + 32) / 65)
let s:l = 440 - ((29 * winheight(0) + 32) / 65)
if s:l < 1 | let s:l = 1 | endif
keepjumps exe s:l
normal! zt
keepjumps 15
normal! 0
keepjumps 440
normal! 010|
wincmd w
exe 'vert 1resize ' . ((&columns * 123 + 128) / 256)
exe 'vert 2resize ' . ((&columns * 132 + 128) / 256)
2wincmd w
exe 'vert 1resize ' . ((&columns * 71 + 128) / 256)
exe 'vert 2resize ' . ((&columns * 184 + 128) / 256)
tabnext
edit vm/vm.h
let s:save_splitbelow = &splitbelow
@ -122,12 +125,12 @@ setlocal fdn=20
setlocal fen
silent! normal! zE
let &fdl = &fdl
let s:l = 10 - ((9 * winheight(0) + 32) / 65)
let s:l = 12 - ((11 * winheight(0) + 32) / 65)
if s:l < 1 | let s:l = 1 | endif
keepjumps exe s:l
normal! zt
keepjumps 10
normal! 011|
keepjumps 12
normal! 06|
wincmd w
argglobal
if bufexists(fnamemodify("vm/vm.c", ":p")) | buffer vm/vm.c | else | edit vm/vm.c | endif
@ -145,12 +148,12 @@ setlocal fdn=20
setlocal fen
silent! normal! zE
let &fdl = &fdl
let s:l = 83 - ((7 * winheight(0) + 32) / 65)
let s:l = 262 - ((49 * winheight(0) + 32) / 65)
if s:l < 1 | let s:l = 1 | endif
keepjumps exe s:l
normal! zt
keepjumps 83
normal! 021|
keepjumps 262
normal! 0
wincmd w
exe 'vert 1resize ' . ((&columns * 93 + 128) / 256)
exe 'vert 2resize ' . ((&columns * 162 + 128) / 256)
@ -186,12 +189,12 @@ setlocal fdn=20
setlocal fen
silent! normal! zE
let &fdl = &fdl
let s:l = 53 - ((34 * winheight(0) + 32) / 65)
let s:l = 91 - ((48 * winheight(0) + 32) / 65)
if s:l < 1 | let s:l = 1 | endif
keepjumps exe s:l
normal! zt
keepjumps 53
normal! 0
keepjumps 91
normal! 045|
wincmd w
argglobal
if bufexists(fnamemodify("vm/asm.c", ":p")) | buffer vm/asm.c | else | edit vm/asm.c | endif
@ -209,12 +212,12 @@ setlocal fdn=20
setlocal fen
silent! normal! zE
let &fdl = &fdl
let s:l = 265 - ((36 * winheight(0) + 32) / 65)
let s:l = 146 - ((10 * winheight(0) + 32) / 65)
if s:l < 1 | let s:l = 1 | endif
keepjumps exe s:l
normal! zt
keepjumps 265
normal! 032|
keepjumps 146
normal! 019|
wincmd w
exe 'vert 1resize ' . ((&columns * 87 + 128) / 256)
exe 'vert 2resize ' . ((&columns * 168 + 128) / 256)
@ -239,7 +242,7 @@ set winwidth=1
exe 'vert 1resize ' . ((&columns * 127 + 128) / 256)
exe 'vert 2resize ' . ((&columns * 128 + 128) / 256)
argglobal
balt vm/asm.h
balt vm/vm.c
setlocal fdm=manual
setlocal fde=0
setlocal fmr={{{,}}}
@ -250,12 +253,12 @@ setlocal fdn=20
setlocal fen
silent! normal! zE
let &fdl = &fdl
let s:l = 265 - ((35 * winheight(0) + 32) / 65)
let s:l = 369 - ((29 * winheight(0) + 32) / 65)
if s:l < 1 | let s:l = 1 | endif
keepjumps exe s:l
normal! zt
keepjumps 265
normal! 031|
keepjumps 369
normal! 042|
wincmd w
argglobal
if bufexists(fnamemodify("vm/vm.c", ":p")) | buffer vm/vm.c | else | edit vm/vm.c | endif
@ -273,16 +276,16 @@ setlocal fdn=20
setlocal fen
silent! normal! zE
let &fdl = &fdl
let s:l = 123 - ((48 * winheight(0) + 32) / 65)
let s:l = 228 - ((61 * winheight(0) + 32) / 65)
if s:l < 1 | let s:l = 1 | endif
keepjumps exe s:l
normal! zt
keepjumps 123
normal! 0
keepjumps 228
normal! 01|
wincmd w
exe 'vert 1resize ' . ((&columns * 127 + 128) / 256)
exe 'vert 2resize ' . ((&columns * 128 + 128) / 256)
tabnext 3
tabnext 1
set stal=1
if exists('s:wipebuf') && len(win_findbuf(s:wipebuf)) == 0 && getbufvar(s:wipebuf, '&buftype') isnot# 'terminal'
silent exe 'bwipe ' . s:wipebuf

103
vm/asm.c
View File

@ -149,6 +149,24 @@ Line s_in_i(Reg dst_reg, uint16_t op1_imm)
.op1 = (Ex) { .imm = op1_imm },
};
}
Line s_call_i(uint16_t op1_imm)
{
return (Line) {
.ty = LineTy_Call_Imm,
.op1 = (Ex) { .imm = op1_imm },
};
}
Line s_call_l(int op1_label)
{
return (Line) {
.ty = LineTy_Call_Label,
.op1 = (Ex) { .label = op1_label },
};
}
Line s_ret(void)
{
return (Line) { .ty = LineTy_Ret };
}
Line s_lit_i(uint16_t op1_imm)
{
return (Line) {
@ -187,9 +205,29 @@ Line s_iret(void)
}
DEFINE_BINARY_I(or, Or)
DEFINE_BINARY_I(xor, Xor)
DEFINE_BINARY_I(and, And)
DEFINE_BINARY_I(add, Add)
DEFINE_BINARY_I(sub, Sub)
DEFINE_BINARY_I(mul, Mul)
#define DEFINE_BINARY_R(FN, LINETY) \
Line s_##FN##_r(Reg dst_reg, Reg op1_reg, Reg op2_reg) \
{ \
return (Line) { \
.ty = LineTy_##LINETY##_Reg, \
.dst = (Ex) { .reg = (uint16_t)dst_reg }, \
.op1 = (Ex) { .reg = (uint16_t)op1_reg }, \
.op2 = (Ex) { .reg = (uint16_t)op2_reg }, \
}; \
}
DEFINE_BINARY_R(or, Or)
DEFINE_BINARY_R(xor, Xor)
DEFINE_BINARY_R(and, And)
DEFINE_BINARY_R(add, Add)
DEFINE_BINARY_R(sub, Sub)
DEFINE_BINARY_R(mul, Mul)
static inline void add_dst_reg(uint32_t* ins, uint16_t reg);
static inline void add_op1_reg(uint32_t* ins, uint16_t reg);
@ -200,7 +238,7 @@ static inline void set_mov_addr_is_reg(uint32_t* ins);
static inline void set_mov_is_store(uint32_t* ins);
static inline uint16_t linety_arithm_ins(LineTy ty);
void assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size)
uint16_t assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size)
{
bool debug = false;
@ -443,6 +481,31 @@ void assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size)
out[ip++] = op1;
break;
}
case LineTy_Call_Imm: {
uint16_t op1 = line->op1.imm;
uint32_t ins = Op_Call;
set_is_imm(&ins);
out[ip++] = (uint16_t)ins;
out[ip++] = op1;
break;
}
case LineTy_Call_Label: {
int op1 = line->op1.label;
uint32_t ins = Op_Call;
set_is_imm(&ins);
out[ip++] = (uint16_t)ins;
ADD_LABEL(op1);
break;
}
case LineTy_Ret: {
uint32_t ins = Op_Ret;
out[ip++] = (uint16_t)ins;
break;
}
case LineTy_Lit_Imm: {
uint16_t op1 = line->op1.imm;
@ -472,13 +535,17 @@ void assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size)
break;
}
case LineTy_IRet: {
out[ip++] = Op_IRet;
uint32_t ins = Op_Ret;
ins |= 1 << 6;
out[ip++] = (uint16_t)ins;
break;
}
case LineTy_Or_Imm:
case LineTy_Xor_Imm:
case LineTy_And_Imm:
case LineTy_Add_Imm:
case LineTy_Sub_Imm: {
case LineTy_Sub_Imm:
case LineTy_Mul_Imm: {
uint16_t dst = line->dst.reg;
uint16_t op1 = line->op1.reg;
uint16_t op2 = line->op2.imm;
@ -492,6 +559,24 @@ void assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size)
out[ip++] = op2;
break;
}
case LineTy_Or_Reg:
case LineTy_Xor_Reg:
case LineTy_And_Reg:
case LineTy_Add_Reg:
case LineTy_Sub_Reg:
case LineTy_Mul_Reg: {
uint16_t dst = line->dst.reg;
uint16_t op1 = line->op1.reg;
uint16_t op2 = line->op2.reg;
uint32_t ins = linety_arithm_ins(line->ty);
add_op2_reg(&ins, op2);
add_op1_reg(&ins, op1);
add_dst_reg(&ins, dst);
out[ip++] = (uint16_t)ins;
break;
}
}
if (debug) {
@ -547,6 +632,8 @@ void assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size)
if (debug) {
printf("done!\n");
}
return ip * 2;
}
static inline void add_dst_reg(uint32_t* ins, uint16_t reg)
@ -582,13 +669,23 @@ static inline uint16_t linety_arithm_ins(LineTy ty)
{
switch (ty) {
case LineTy_Or_Imm:
case LineTy_Or_Reg:
return Op_Or;
case LineTy_Xor_Imm:
case LineTy_Xor_Reg:
return Op_Xor;
case LineTy_And_Imm:
case LineTy_And_Reg:
return Op_And;
case LineTy_Add_Imm:
case LineTy_Add_Reg:
return Op_Add;
case LineTy_Sub_Imm:
case LineTy_Sub_Reg:
return Op_Sub;
case LineTy_Mul_Imm:
case LineTy_Mul_Reg:
return Op_Mul;
default:
fprintf(stderr, "error: line type '%d' not handled\n", ty);
exit(1);

View File

@ -24,14 +24,25 @@ typedef enum {
LineTy_Mov16_MemReg_Reg,
LineTy_Mov16_MemLabel_Reg,
LineTy_In_Imm,
LineTy_Call_Imm,
LineTy_Call_Label,
LineTy_Ret,
LineTy_Lit_Imm,
LineTy_Lit_Label,
LineTy_Int,
LineTy_IRet,
LineTy_Or_Imm,
LineTy_Xor_Imm,
LineTy_And_Imm,
LineTy_Add_Imm,
LineTy_Sub_Imm,
LineTy_Mul_Imm,
LineTy_Or_Reg,
LineTy_Xor_Reg,
LineTy_And_Reg,
LineTy_Add_Reg,
LineTy_Sub_Reg,
LineTy_Mul_Reg,
} LineTy;
typedef struct {
@ -71,20 +82,32 @@ 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_ml_r(int dst_label, Reg op2_reg);
Line s_in_i(Reg dst_reg, uint16_t op1_imm);
Line s_call_i(uint16_t op1_imm);
Line s_call_l(int op1_label);
Line s_ret(void);
Line s_lit_i(uint16_t op1_imm);
Line s_lit_l(int op1_label);
Line s_int(uint8_t int_id);
Line s_iret(void);
Line s_or_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm);
Line s_xor_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm);
Line s_and_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm);
Line s_add_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm);
Line s_sub_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm);
Line s_mul_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm);
Line s_or_r(Reg dst_reg, Reg op1_reg, Reg op2_reg);
Line s_xor_r(Reg dst_reg, Reg op1_reg, Reg op2_reg);
Line s_and_r(Reg dst_reg, Reg op1_reg, Reg op2_reg);
Line s_add_r(Reg dst_reg, Reg op1_reg, Reg op2_reg);
Line s_sub_r(Reg dst_reg, Reg op1_reg, Reg op2_reg);
Line s_mul_r(Reg dst_reg, Reg op1_reg, Reg op2_reg);
#define s_push_r(REG) s_add_i(Rsp, Rsp, 2), s_mov16_mr_r(Rsp, 0, REG)
#define s_pop_r(REG) s_mov16_r_mr(REG, Rsp, 2), s_sub_i(Rsp, Rsp, 2)
#define s_pop_r(REG) s_mov16_r_mr(REG, Rsp, 0), s_sub_i(Rsp, Rsp, 2)
void assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size);
uint16_t assemble_to_binary(
uint16_t* out, const Line* lines, size_t lines_size);
#define fmt_binary(VAL) \
(VAL) >> 7 & 1 ? '1' : '0', (VAL) >> 6 & 1 ? '1' : '0', \

109
vm/main.c
View File

@ -269,7 +269,8 @@ static inline bool is_exit_event(SDL_Event* event)
return event->type == SDL_QUIT
|| (event->type == SDL_KEYDOWN
&& event->key.keysym.scancode == SDL_SCANCODE_ESCAPE
&& event->key.keysym.mod & KMOD_CTRL);
// && event->key.keysym.mod & KMOD_CTRL
);
}
void sdldevice_poll_events(SdlDevice* device)
@ -392,6 +393,10 @@ int main(void)
int keyboard_interrupt_1 = label_ids++;
int keyboard_interrupt_2 = label_ids++;
int keyboard_interrupt_3 = label_ids++;
int keyboard_interrupt_4 = label_ids++;
int put_char = label_ids++;
int put_char_0 = label_ids++;
int put_char_1 = label_ids++;
int screen_x = label_ids++;
int screen_y = label_ids++;
@ -399,7 +404,6 @@ int main(void)
Line program_asm[] = {
// clang-format off
s_nop(),
// rsp points *at* the top element
s_mov16_r_i(Rbp, 2048),
@ -417,12 +421,13 @@ int main(void)
L(main_loop),
s_hlt(),
s_jmp_l(main_loop),
s_nop(),
L(interrupt_table),
// size
s_data_i(1),
s_data_l(keyboard_interrupt),
s_nop(),
L(keyboard_interrupt),
s_and_i(Rfl, Rfl, (uint16_t)~(1 << Fl_Int)),
s_push_r(Rbp),
@ -430,28 +435,63 @@ int main(void)
s_push_r(R0),
s_push_r(R1),
s_push_r(R2),
s_push_r(R3),
// read keyboard port
s_in_i(R0, Device_Keyboard),
s_add_i(R0, R0, 'A' - 4),
s_cmp_i(R0, 105),
s_cmp_i(R0, 44),
s_mov16_r_r(R1, Rfl),
s_and_i(R1, R1, 1 << Fl_Eq),
s_jnz_l(R1, keyboard_interrupt_0),
s_jmp_l(keyboard_interrupt_1),
s_cmp_i(R0, 42),
s_mov16_r_r(R1, Rfl),
s_and_i(R1, R1, 1 << Fl_Eq),
s_jnz_l(R1, keyboard_interrupt_1),
s_cmp_i(R0, 40),
s_mov16_r_r(R1, Rfl),
s_and_i(R1, R1, 1 << Fl_Eq),
s_jnz_l(R1, keyboard_interrupt_2),
s_jmp_l(keyboard_interrupt_3),
L(keyboard_interrupt_0),
s_mov16_r_i(R0, ' '),
s_jmp_l(keyboard_interrupt_1),
s_call_l(put_char),
s_jmp_l(keyboard_interrupt_4),
L(keyboard_interrupt_1),
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_cmp_i(R1, 0),
s_mov16_r_r(R2, Rfl),
s_and_i(R2, R2, 1 << Fl_Eq),
s_jnz_l(R2, keyboard_interrupt_4),
s_sub_i(R1, R1, 1),
s_mov16_ml_r(screen_x, R1),
s_mov16_r_i(R0, ' '),
s_call_l(put_char),
s_mov16_r_ml(R1, screen_x),
s_sub_i(R1, R1, 1),
s_mov16_ml_r(screen_x, R1),
s_jmp_l(keyboard_interrupt_4),
L(keyboard_interrupt_2),
s_mov16_r_ml(R1, screen_y),
s_add_i(R1, R1, 1),
s_mov16_ml_r(screen_y, R1),
s_mov16_r_i(R1, 0),
s_mov16_ml_r(screen_x, R1),
s_jmp_l(keyboard_interrupt_4),
L(keyboard_interrupt_3),
s_add_i(R0, R0, 'A' - 4),
s_call_l(put_char),
s_jmp_l(keyboard_interrupt_4),
L(keyboard_interrupt_4),
s_pop_r(R3),
s_pop_r(R2),
s_pop_r(R1),
s_pop_r(R0),
@ -459,6 +499,45 @@ int main(void)
s_pop_r(Rbp),
s_or_i(Rfl, Rfl, 1 << Fl_Int),
s_iret(),
L(put_char),
s_push_r(Rbp),
s_mov16_r_r(Rbp, Rsp),
s_push_r(R1),
s_push_r(R2),
s_mov16_r_ml(R2, screen_y),
s_mul_i(R2, R2, width_in_ch),
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_mov16_r_ml(R1, screen_x),
s_add_i(R1, R1, 1),
s_mov16_ml_r(screen_x, R1),
s_cmp_i(R1, width_in_ch),
s_mov16_r_r(R2, Rfl),
s_and_i(R2, R2, 1 << Fl_Eq),
s_jnz_l(R2, put_char_0),
s_jmp_l(put_char_1),
L(put_char_0),
s_mov16_r_ml(R1, screen_y),
s_add_i(R1, R1, 1),
s_mov16_ml_r(screen_y, R1),
s_mov16_r_i(R1, 0),
s_mov16_ml_r(screen_x, R1),
L(put_char_1),
s_pop_r(R1),
s_pop_r(R2),
s_mov16_r_r(Rsp, Rbp),
s_pop_r(Rbp),
s_ret(),
L(screen_x),
s_data_i(0),
L(screen_y),
@ -470,7 +549,9 @@ int main(void)
size_t program_asm_size = sizeof(program_asm) / sizeof(program_asm[0]);
uint16_t* program = calloc(512 * 2, sizeof(uint16_t));
assemble_to_binary(program, program_asm, program_asm_size);
uint16_t program_size
= assemble_to_binary(program, program_asm, program_asm_size);
printf("program size = %d\n", program_size);
// dump_program(program);

72
vm/vm.c
View File

@ -22,7 +22,6 @@ static inline void handle_device_write(
VM* vm, uint16_t op1, uint16_t device_id);
static inline int handle_interrupt(VM* vm, uint8_t int_id);
static inline int jump_to_interrupt_handler(VM* vm, uint8_t int_id);
static inline void interrupt_return(VM* vm);
static inline void maybe_update_vcd(VM* vm, uint16_t addr);
static inline uint16_t eat_uint16(VM* vm);
static inline uint16_t read_seg_uint16(VM* vm, uint16_t ptr);
@ -57,9 +56,10 @@ void vm_start(Drive* boot_drive, IODevice* io_device)
VM* vm = &vm_inst;
uint16_t* rip = &vm->regs[Rip];
uint16_t* rbp = &vm->regs[Rbp];
uint16_t* rsp = &vm->regs[Rsp];
uint16_t* rfl = &vm->regs[Rfl];
uint16_t* rip = &vm->regs[Rip];
uint16_t* rcs = &vm->regs[Rcs];
const uint16_t bootloader_size = 512;
@ -72,10 +72,10 @@ void vm_start(Drive* boot_drive, IODevice* io_device)
uint16_t ins = eat_uint16(vm);
Op op = ins_op(ins);
/*printf("[%3d] = %3d %s\n", *rip - 2, op, op_str(op));*/
// printf("[%3d] = %3d %s\n", *rip - 2, op, op_str(op));
if (*rip >= 300) {
printf("killed: rip >= 200\n");
if (*rip >= 1024) {
printf("killed: rip >= 1024\n");
exit(0);
}
@ -224,6 +224,46 @@ void vm_start(Drive* boot_drive, IODevice* io_device)
handle_device_write(vm, op1, device_id);
break;
}
case Op_Call: {
bool is_far_call = ins >> 13 & 1;
uint16_t op1 = ins_op1_or_imm(vm, ins);
if (is_far_call) {
uint16_t op2 = ins_reg_val_or_imm(vm, ins, 14, 7, 0x7);
*rsp += 2;
*(uint16_t*)&vm->mem[*rsp] = *rcs;
*rsp += 2;
*(uint16_t*)&vm->mem[*rsp] = *rip;
*rip = op1;
*rcs = op2;
} else {
*rsp += 2;
*(uint16_t*)&vm->mem[*rsp] = *rip;
*rip = op1;
}
break;
}
case Op_Ret: {
bool is_far_return = ins >> 6 & 1;
if (is_far_return) {
*rip = *(uint16_t*)&vm->mem[*rsp];
*rsp -= 2;
*rcs = *(uint16_t*)&vm->mem[*rsp];
*rsp -= 2;
} else {
*rip = *(uint16_t*)&vm->mem[*rsp];
*rsp -= 2;
}
break;
}
case Op_Lit: {
uint16_t op2 = ins_op1_or_imm(vm, ins);
vm->int_table = op2;
@ -238,10 +278,6 @@ void vm_start(Drive* boot_drive, IODevice* io_device)
}
break;
}
case Op_IRet: {
interrupt_return(vm);
break;
}
case Op_Or:
case Op_Xor:
@ -440,18 +476,6 @@ static inline int jump_to_interrupt_handler(VM* vm, uint8_t int_id)
return 0;
}
static inline void interrupt_return(VM* vm)
{
uint16_t* rsp = &vm->regs[Rsp];
uint16_t* rip = &vm->regs[Rip];
uint16_t* rcs = &vm->regs[Rcs];
*rip = *(uint16_t*)&vm->mem[*rsp];
*rsp -= 2;
*rcs = *(uint16_t*)&vm->mem[*rsp];
*rsp -= 2;
}
static inline void maybe_update_vcd(VM* vm, uint16_t addr)
{
if (!vm->io_device)
@ -552,12 +576,14 @@ const char* op_str(Op op)
return "in";
case Op_Out:
return "out";
case Op_Call:
return "call";
case Op_Ret:
return "ret";
case Op_Lit:
return "lit";
case Op_Int:
return "int";
case Op_IRet:
return "iret";
case Op_Or:
return "or";
case Op_Xor:

View File

@ -36,9 +36,10 @@ typedef enum {
Op_Mov16,
Op_In,
Op_Out,
Op_Call,
Op_Ret,
Op_Lit,
Op_Int,
Op_IRet,
Op_Or,
Op_Xor,
Op_And,