From db6e20b4b14c2875612043d75f176a1a8e747fa5 Mon Sep 17 00:00:00 2001 From: sfja Date: Mon, 31 Mar 2025 15:11:59 +0200 Subject: [PATCH] typing and spaces works --- Session.vim | 117 ++++++++++++++++++++-------------------------------- vm/asm.c | 45 +++++++++++++++++++- vm/asm.h | 4 ++ vm/main.c | 36 ++++++++++++++-- vm/vm.c | 27 ++++++++++-- vm/vm.h | 7 ++-- 6 files changed, 153 insertions(+), 83 deletions(-) diff --git a/Session.vim b/Session.vim index 3a87670..3c8eae5 100644 --- a/Session.vim +++ b/Session.vim @@ -13,12 +13,13 @@ if &shortmess =~ 'A' else set shortmess=aoO endif -badd +397 vm/main.c -badd +1 Makefile -badd +30 vm/vm.h -badd +225 vm/vm.c -badd +53 vm/asm.h -badd +178 vm/asm.c +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 +747 ~/.config/nvim/init.lua argglobal %argdel $argadd vm/main.c @@ -44,8 +45,8 @@ set winminheight=0 set winheight=1 set winminwidth=0 set winwidth=1 -exe 'vert 1resize ' . ((&columns * 127 + 128) / 256) -exe 'vert 2resize ' . ((&columns * 128 + 128) / 256) +exe 'vert 1resize ' . ((&columns * 123 + 128) / 256) +exe 'vert 2resize ' . ((&columns * 132 + 128) / 256) argglobal setlocal fdm=manual setlocal fde=0 @@ -57,11 +58,11 @@ setlocal fdn=20 setlocal fen silent! normal! zE let &fdl = &fdl -let s:l = 397 - ((1 * winheight(0) + 32) / 65) +let s:l = 437 - ((37 * winheight(0) + 32) / 65) if s:l < 1 | let s:l = 1 | endif keepjumps exe s:l normal! zt -keepjumps 397 +keepjumps 437 normal! 012| wincmd w argglobal @@ -80,15 +81,15 @@ setlocal fdn=20 setlocal fen silent! normal! zE let &fdl = &fdl -let s:l = 1 - ((0 * winheight(0) + 32) / 65) +let s:l = 15 - ((14 * winheight(0) + 32) / 65) if s:l < 1 | let s:l = 1 | endif keepjumps exe s:l normal! zt -keepjumps 1 +keepjumps 15 normal! 0 wincmd w -exe 'vert 1resize ' . ((&columns * 127 + 128) / 256) -exe 'vert 2resize ' . ((&columns * 128 + 128) / 256) +exe 'vert 1resize ' . ((&columns * 123 + 128) / 256) +exe 'vert 2resize ' . ((&columns * 132 + 128) / 256) tabnext edit vm/vm.h let s:save_splitbelow = &splitbelow @@ -107,8 +108,8 @@ set winminheight=0 set winheight=1 set winminwidth=0 set winwidth=1 -exe 'vert 1resize ' . ((&columns * 127 + 128) / 256) -exe 'vert 2resize ' . ((&columns * 128 + 128) / 256) +exe 'vert 1resize ' . ((&columns * 93 + 128) / 256) +exe 'vert 2resize ' . ((&columns * 162 + 128) / 256) argglobal balt Makefile setlocal fdm=manual @@ -121,12 +122,12 @@ setlocal fdn=20 setlocal fen silent! normal! zE let &fdl = &fdl -let s:l = 26 - ((25 * winheight(0) + 32) / 65) +let s:l = 10 - ((9 * winheight(0) + 32) / 65) if s:l < 1 | let s:l = 1 | endif keepjumps exe s:l normal! zt -keepjumps 26 -normal! 0 +keepjumps 10 +normal! 011| wincmd w argglobal if bufexists(fnamemodify("vm/vm.c", ":p")) | buffer vm/vm.c | else | edit vm/vm.c | endif @@ -144,15 +145,15 @@ setlocal fdn=20 setlocal fen silent! normal! zE let &fdl = &fdl -let s:l = 70 - ((18 * winheight(0) + 32) / 65) +let s:l = 83 - ((7 * winheight(0) + 32) / 65) if s:l < 1 | let s:l = 1 | endif keepjumps exe s:l normal! zt -keepjumps 70 -normal! 026| +keepjumps 83 +normal! 021| wincmd w -exe 'vert 1resize ' . ((&columns * 127 + 128) / 256) -exe 'vert 2resize ' . ((&columns * 128 + 128) / 256) +exe 'vert 1resize ' . ((&columns * 93 + 128) / 256) +exe 'vert 2resize ' . ((&columns * 162 + 128) / 256) tabnext edit vm/asm.h let s:save_splitbelow = &splitbelow @@ -160,10 +161,7 @@ let s:save_splitright = &splitright set splitbelow splitright wincmd _ | wincmd | vsplit -wincmd _ | wincmd | -vsplit -2wincmd h -wincmd w +1wincmd h wincmd w let &splitbelow = s:save_splitbelow let &splitright = s:save_splitright @@ -174,9 +172,8 @@ set winminheight=0 set winheight=1 set winminwidth=0 set winwidth=1 -exe 'vert 1resize ' . ((&columns * 73 + 128) / 256) -exe 'vert 2resize ' . ((&columns * 86 + 128) / 256) -exe 'vert 3resize ' . ((&columns * 95 + 128) / 256) +exe 'vert 1resize ' . ((&columns * 87 + 128) / 256) +exe 'vert 2resize ' . ((&columns * 168 + 128) / 256) argglobal balt vm/vm.c setlocal fdm=manual @@ -189,12 +186,12 @@ setlocal fdn=20 setlocal fen silent! normal! zE let &fdl = &fdl -let s:l = 53 - ((52 * winheight(0) + 32) / 65) +let s:l = 53 - ((34 * winheight(0) + 32) / 65) if s:l < 1 | let s:l = 1 | endif keepjumps exe s:l normal! zt keepjumps 53 -normal! 026| +normal! 0 wincmd w argglobal if bufexists(fnamemodify("vm/asm.c", ":p")) | buffer vm/asm.c | else | edit vm/asm.c | endif @@ -212,40 +209,15 @@ setlocal fdn=20 setlocal fen silent! normal! zE let &fdl = &fdl -let s:l = 178 - ((18 * winheight(0) + 32) / 65) +let s:l = 265 - ((36 * winheight(0) + 32) / 65) if s:l < 1 | let s:l = 1 | endif keepjumps exe s:l normal! zt -keepjumps 178 -normal! 013| +keepjumps 265 +normal! 032| wincmd w -argglobal -if bufexists(fnamemodify("vm/vm.c", ":p")) | buffer vm/vm.c | else | edit vm/vm.c | endif -if &buftype ==# 'terminal' - silent file vm/vm.c -endif -balt vm/asm.c -setlocal fdm=manual -setlocal fde=0 -setlocal fmr={{{,}}} -setlocal fdi=# -setlocal fdl=0 -setlocal fml=1 -setlocal fdn=20 -setlocal fen -silent! normal! zE -let &fdl = &fdl -let s:l = 104 - ((1 * winheight(0) + 32) / 65) -if s:l < 1 | let s:l = 1 | endif -keepjumps exe s:l -normal! zt -keepjumps 104 -normal! 043| -wincmd w -2wincmd w -exe 'vert 1resize ' . ((&columns * 73 + 128) / 256) -exe 'vert 2resize ' . ((&columns * 86 + 128) / 256) -exe 'vert 3resize ' . ((&columns * 95 + 128) / 256) +exe 'vert 1resize ' . ((&columns * 87 + 128) / 256) +exe 'vert 2resize ' . ((&columns * 168 + 128) / 256) tabnext edit vm/asm.c let s:save_splitbelow = &splitbelow @@ -264,9 +236,10 @@ set winminheight=0 set winheight=1 set winminwidth=0 set winwidth=1 -exe 'vert 1resize ' . ((&columns * 119 + 128) / 256) -exe 'vert 2resize ' . ((&columns * 136 + 128) / 256) +exe 'vert 1resize ' . ((&columns * 127 + 128) / 256) +exe 'vert 2resize ' . ((&columns * 128 + 128) / 256) argglobal +balt vm/asm.h setlocal fdm=manual setlocal fde=0 setlocal fmr={{{,}}} @@ -277,11 +250,11 @@ setlocal fdn=20 setlocal fen silent! normal! zE let &fdl = &fdl -let s:l = 354 - ((61 * winheight(0) + 32) / 65) +let s:l = 265 - ((35 * winheight(0) + 32) / 65) if s:l < 1 | let s:l = 1 | endif keepjumps exe s:l normal! zt -keepjumps 354 +keepjumps 265 normal! 031| wincmd w argglobal @@ -300,15 +273,15 @@ setlocal fdn=20 setlocal fen silent! normal! zE let &fdl = &fdl -let s:l = 423 - ((31 * winheight(0) + 32) / 65) +let s:l = 123 - ((48 * winheight(0) + 32) / 65) if s:l < 1 | let s:l = 1 | endif keepjumps exe s:l normal! zt -keepjumps 423 -normal! 019| +keepjumps 123 +normal! 0 wincmd w -exe 'vert 1resize ' . ((&columns * 119 + 128) / 256) -exe 'vert 2resize ' . ((&columns * 136 + 128) / 256) +exe 'vert 1resize ' . ((&columns * 127 + 128) / 256) +exe 'vert 2resize ' . ((&columns * 128 + 128) / 256) tabnext 3 set stal=1 if exists('s:wipebuf') && len(win_findbuf(s:wipebuf)) == 0 && getbufvar(s:wipebuf, '&buftype') isnot# 'terminal' diff --git a/vm/asm.c b/vm/asm.c index fd5aee0..79e5ae5 100644 --- a/vm/asm.c +++ b/vm/asm.c @@ -43,6 +43,22 @@ Line s_jmp_l(int op1_label) .op1 = (Ex) { .label = op1_label }, }; } +Line s_jnz_l(Reg op1_reg, int op2_label) +{ + return (Line) { + .ty = LineTy_Jnz_Label, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .label = op2_label }, + }; +} +Line s_cmp_i(Reg op1_reg, uint16_t op2_imm) +{ + return (Line) { + .ty = LineTy_Cmp_Imm, + .op1 = (Ex) { .reg = (uint16_t)op1_reg }, + .op2 = (Ex) { .imm = op2_imm }, + }; +} Line s_mov8_mr_r(Reg dst_reg, Reg op2_reg) { return (Line) { @@ -239,10 +255,37 @@ void assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size) break; } case LineTy_Jmp_Label: { + int op1 = line->op1.label; + uint32_t ins = Op_Jmp; set_is_imm(&ins); out[ip++] = (uint16_t)ins; - ADD_LABEL(line->op1.label); + ADD_LABEL(op1); + break; + } + case LineTy_Jnz_Label: { + uint16_t op1 = line->op1.reg; + int op2 = line->op2.label; + + uint32_t ins = Op_Jnz; + set_is_imm(&ins); + add_op1_reg(&ins, op1); + + out[ip++] = (uint16_t)ins; + ADD_LABEL(op2); + break; + } + case LineTy_Cmp_Imm: { + uint16_t op1 = line->op1.reg; + uint16_t op2 = line->op2.imm; + + uint32_t ins = Op_Cmp; + set_is_imm(&ins); + add_op1_reg(&ins, op1); + + out[ip++] = (uint16_t)ins; + out[ip++] = op2; + break; break; } case LineTy_Mov8_MemReg_Reg: { diff --git a/vm/asm.h b/vm/asm.h index 2094d94..93c6a8f 100644 --- a/vm/asm.h +++ b/vm/asm.h @@ -11,6 +11,8 @@ typedef enum { LineTy_Nop, LineTy_Hlt, LineTy_Jmp_Label, + LineTy_Jnz_Label, + LineTy_Cmp_Imm, LineTy_Mov8_MemReg_Reg, LineTy_Mov8_MemImm_Imm, LineTy_Mov8_MemImm_Reg, @@ -55,6 +57,8 @@ Line s_data_l(int label); Line s_nop(void); Line s_hlt(void); Line s_jmp_l(int op1_label); +Line s_jnz_l(Reg op1_reg, int op2_label); +Line s_cmp_i(Reg op1_reg, uint16_t op2_imm); 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_r(uint16_t dst_imm, Reg op2_reg); diff --git a/vm/main.c b/vm/main.c index 8a54965..762e8e4 100644 --- a/vm/main.c +++ b/vm/main.c @@ -187,9 +187,10 @@ extern const bool charset[][ch_height][ch_width]; void sdldevice_set_char(IODevice* io_device, uint16_t offset, uint8_t value) { - // printf("value = %d '%c', offset = %d\n", value, value, offset); - if (!((value >= 'A' && value <= 'Z') || value == ' ')) + if (!((value >= 'A' && value <= 'Z') || value == ' ')) { + printf("sdldevice: invalid char value = %d\n", value); return; + } SdlDevice* device = io_device->self; pthread_mutex_lock(&device->mutex); @@ -385,6 +386,10 @@ int main(void) int main_loop = label_ids++; int interrupt_table = label_ids++; int keyboard_interrupt = label_ids++; + int keyboard_interrupt_0 = label_ids++; + int keyboard_interrupt_1 = label_ids++; + int keyboard_interrupt_2 = label_ids++; + int keyboard_interrupt_3 = label_ids++; int screen_x = label_ids++; int screen_y = label_ids++; @@ -426,6 +431,15 @@ int main(void) s_in_i(R0, 0), s_add_i(R0, R0, 'A' - 4), + s_cmp_i(R0, 105), + 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), + L(keyboard_interrupt_0), + s_mov16_r_i(R0, ' '), + s_jmp_l(keyboard_interrupt_1), + L(keyboard_interrupt_1), s_mov16_r_ml(R1, screen_x), s_add_i(R1, R1, 0x0c00), s_mov8_mr_r(R1, R0), @@ -456,7 +470,19 @@ int main(void) // dump_program(program); - // return 0; + for (int i = 'A'; i <= 'Z'; ++i) { + uint64_t ch = 0; + for (int y = 0; y < ch_height; ++y) { + for (int x = 0; x < ch_width; ++x) { + if (charset[i][y][x]) { + ch |= 1 << (y * ch_width + (ch_height - x - 1)); + } + } + } + printf("['%c'] = 0x%lX,\n", i, ch); + } + + return 0; MemDrive drive; memdrive_construct(&drive, (uint64_t*)program, 512); @@ -477,6 +503,10 @@ const char* __asan_default_options(void) return "detect_leaks=0"; } +const uint64_t charset_2[] = { + [' '] = 0x0000000000000000, +}; + #define _ false, #define t true, diff --git a/vm/vm.c b/vm/vm.c index 8827105..cb90887 100644 --- a/vm/vm.c +++ b/vm/vm.c @@ -96,6 +96,7 @@ void vm_start(Drive* boot_drive, IODevice* io_device) case Op_Jnz: { uint16_t op1 = ins_op1(vm, ins); uint16_t op2 = ins_op2_or_imm(vm, ins); + if (op1 != 0) { *rip = op2; } @@ -103,15 +104,33 @@ void vm_start(Drive* boot_drive, IODevice* io_device) } case Op_Test: { uint16_t op1 = ins_op1(vm, ins); - *rfl &= (uint16_t)~((op1 == 0 ? 1 : 0) << Fl_Zero); + + if (op1 == 0) { + *rfl |= 1u << Fl_Zero; + } else { + *rfl &= (uint16_t)~(1u << Fl_Zero); + } break; } case Op_Cmp: { uint16_t op1 = ins_op1(vm, ins); uint16_t op2 = ins_op2_or_imm(vm, ins); - *rfl &= (uint16_t)~((op1 == op2 ? 1 : 0) << Fl_Eq - & (op1 < op2 ? 1 : 0) << Fl_Be - & ((int16_t)op1 < (int16_t)op2 ? 1 : 0) << Fl_Lt); + + if (op1 == op2) { + *rfl |= 1u << Fl_Eq; + } else { + *rfl &= (uint16_t)~(1u << Fl_Eq); + } + if (op1 < op2) { + *rfl |= 1u << Fl_Be; + } else { + *rfl &= (uint16_t)~(1u << Fl_Be); + } + if ((int16_t)op1 < (int16_t)op2) { + *rfl |= 1u << Fl_Lt; + } else { + *rfl &= (uint16_t)~(1u << Fl_Lt); + } break; } case Op_Mov8: { diff --git a/vm/vm.h b/vm/vm.h index b3c2ff3..0ee7603 100644 --- a/vm/vm.h +++ b/vm/vm.h @@ -7,11 +7,12 @@ typedef enum { R1 = 1, R2 = 2, R3 = 3, - Rbp = 4, - Rsp = 5, - Rip = 6, + R4 = 4, + Rbp = 5, + Rsp = 6, Rfl = 7, Rcs = 8, + Rip = 9, } Reg; typedef enum {