backspace and return
This commit is contained in:
parent
cad6ed9604
commit
b9a837e3c7
83
Session.vim
83
Session.vim
@ -13,13 +13,14 @@ if &shortmess =~ 'A'
|
|||||||
else
|
else
|
||||||
set shortmess=aoO
|
set shortmess=aoO
|
||||||
endif
|
endif
|
||||||
badd +437 vm/main.c
|
badd +440 vm/main.c
|
||||||
badd +48 Makefile
|
badd +11 Makefile
|
||||||
badd +10 vm/vm.h
|
badd +12 vm/vm.h
|
||||||
badd +181 vm/vm.c
|
badd +262 vm/vm.c
|
||||||
badd +14 vm/asm.h
|
badd +91 vm/asm.h
|
||||||
badd +263 vm/asm.c
|
badd +378 vm/asm.c
|
||||||
badd +747 ~/.config/nvim/init.lua
|
badd +747 ~/.config/nvim/init.lua
|
||||||
|
badd +10 compile_flags.txt
|
||||||
argglobal
|
argglobal
|
||||||
%argdel
|
%argdel
|
||||||
$argadd vm/main.c
|
$argadd vm/main.c
|
||||||
@ -28,7 +29,7 @@ tabnew +setlocal\ bufhidden=wipe
|
|||||||
tabnew +setlocal\ bufhidden=wipe
|
tabnew +setlocal\ bufhidden=wipe
|
||||||
tabnew +setlocal\ bufhidden=wipe
|
tabnew +setlocal\ bufhidden=wipe
|
||||||
tabrewind
|
tabrewind
|
||||||
edit vm/main.c
|
edit Makefile
|
||||||
let s:save_splitbelow = &splitbelow
|
let s:save_splitbelow = &splitbelow
|
||||||
let s:save_splitright = &splitright
|
let s:save_splitright = &splitright
|
||||||
set splitbelow splitright
|
set splitbelow splitright
|
||||||
@ -45,9 +46,10 @@ set winminheight=0
|
|||||||
set winheight=1
|
set winheight=1
|
||||||
set winminwidth=0
|
set winminwidth=0
|
||||||
set winwidth=1
|
set winwidth=1
|
||||||
exe 'vert 1resize ' . ((&columns * 123 + 128) / 256)
|
exe 'vert 1resize ' . ((&columns * 71 + 128) / 256)
|
||||||
exe 'vert 2resize ' . ((&columns * 132 + 128) / 256)
|
exe 'vert 2resize ' . ((&columns * 184 + 128) / 256)
|
||||||
argglobal
|
argglobal
|
||||||
|
balt compile_flags.txt
|
||||||
setlocal fdm=manual
|
setlocal fdm=manual
|
||||||
setlocal fde=0
|
setlocal fde=0
|
||||||
setlocal fmr={{{,}}}
|
setlocal fmr={{{,}}}
|
||||||
@ -58,19 +60,19 @@ setlocal fdn=20
|
|||||||
setlocal fen
|
setlocal fen
|
||||||
silent! normal! zE
|
silent! normal! zE
|
||||||
let &fdl = &fdl
|
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
|
if s:l < 1 | let s:l = 1 | endif
|
||||||
keepjumps exe s:l
|
keepjumps exe s:l
|
||||||
normal! zt
|
normal! zt
|
||||||
keepjumps 437
|
keepjumps 11
|
||||||
normal! 012|
|
normal! 027|
|
||||||
wincmd w
|
wincmd w
|
||||||
argglobal
|
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'
|
if &buftype ==# 'terminal'
|
||||||
silent file Makefile
|
silent file vm/main.c
|
||||||
endif
|
endif
|
||||||
balt vm/main.c
|
balt vm/asm.c
|
||||||
setlocal fdm=manual
|
setlocal fdm=manual
|
||||||
setlocal fde=0
|
setlocal fde=0
|
||||||
setlocal fmr={{{,}}}
|
setlocal fmr={{{,}}}
|
||||||
@ -81,15 +83,16 @@ setlocal fdn=20
|
|||||||
setlocal fen
|
setlocal fen
|
||||||
silent! normal! zE
|
silent! normal! zE
|
||||||
let &fdl = &fdl
|
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
|
if s:l < 1 | let s:l = 1 | endif
|
||||||
keepjumps exe s:l
|
keepjumps exe s:l
|
||||||
normal! zt
|
normal! zt
|
||||||
keepjumps 15
|
keepjumps 440
|
||||||
normal! 0
|
normal! 010|
|
||||||
wincmd w
|
wincmd w
|
||||||
exe 'vert 1resize ' . ((&columns * 123 + 128) / 256)
|
2wincmd w
|
||||||
exe 'vert 2resize ' . ((&columns * 132 + 128) / 256)
|
exe 'vert 1resize ' . ((&columns * 71 + 128) / 256)
|
||||||
|
exe 'vert 2resize ' . ((&columns * 184 + 128) / 256)
|
||||||
tabnext
|
tabnext
|
||||||
edit vm/vm.h
|
edit vm/vm.h
|
||||||
let s:save_splitbelow = &splitbelow
|
let s:save_splitbelow = &splitbelow
|
||||||
@ -122,12 +125,12 @@ setlocal fdn=20
|
|||||||
setlocal fen
|
setlocal fen
|
||||||
silent! normal! zE
|
silent! normal! zE
|
||||||
let &fdl = &fdl
|
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
|
if s:l < 1 | let s:l = 1 | endif
|
||||||
keepjumps exe s:l
|
keepjumps exe s:l
|
||||||
normal! zt
|
normal! zt
|
||||||
keepjumps 10
|
keepjumps 12
|
||||||
normal! 011|
|
normal! 06|
|
||||||
wincmd w
|
wincmd w
|
||||||
argglobal
|
argglobal
|
||||||
if bufexists(fnamemodify("vm/vm.c", ":p")) | buffer vm/vm.c | else | edit vm/vm.c | endif
|
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
|
setlocal fen
|
||||||
silent! normal! zE
|
silent! normal! zE
|
||||||
let &fdl = &fdl
|
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
|
if s:l < 1 | let s:l = 1 | endif
|
||||||
keepjumps exe s:l
|
keepjumps exe s:l
|
||||||
normal! zt
|
normal! zt
|
||||||
keepjumps 83
|
keepjumps 262
|
||||||
normal! 021|
|
normal! 0
|
||||||
wincmd w
|
wincmd w
|
||||||
exe 'vert 1resize ' . ((&columns * 93 + 128) / 256)
|
exe 'vert 1resize ' . ((&columns * 93 + 128) / 256)
|
||||||
exe 'vert 2resize ' . ((&columns * 162 + 128) / 256)
|
exe 'vert 2resize ' . ((&columns * 162 + 128) / 256)
|
||||||
@ -186,12 +189,12 @@ setlocal fdn=20
|
|||||||
setlocal fen
|
setlocal fen
|
||||||
silent! normal! zE
|
silent! normal! zE
|
||||||
let &fdl = &fdl
|
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
|
if s:l < 1 | let s:l = 1 | endif
|
||||||
keepjumps exe s:l
|
keepjumps exe s:l
|
||||||
normal! zt
|
normal! zt
|
||||||
keepjumps 53
|
keepjumps 91
|
||||||
normal! 0
|
normal! 045|
|
||||||
wincmd w
|
wincmd w
|
||||||
argglobal
|
argglobal
|
||||||
if bufexists(fnamemodify("vm/asm.c", ":p")) | buffer vm/asm.c | else | edit vm/asm.c | endif
|
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
|
setlocal fen
|
||||||
silent! normal! zE
|
silent! normal! zE
|
||||||
let &fdl = &fdl
|
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
|
if s:l < 1 | let s:l = 1 | endif
|
||||||
keepjumps exe s:l
|
keepjumps exe s:l
|
||||||
normal! zt
|
normal! zt
|
||||||
keepjumps 265
|
keepjumps 146
|
||||||
normal! 032|
|
normal! 019|
|
||||||
wincmd w
|
wincmd w
|
||||||
exe 'vert 1resize ' . ((&columns * 87 + 128) / 256)
|
exe 'vert 1resize ' . ((&columns * 87 + 128) / 256)
|
||||||
exe 'vert 2resize ' . ((&columns * 168 + 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 1resize ' . ((&columns * 127 + 128) / 256)
|
||||||
exe 'vert 2resize ' . ((&columns * 128 + 128) / 256)
|
exe 'vert 2resize ' . ((&columns * 128 + 128) / 256)
|
||||||
argglobal
|
argglobal
|
||||||
balt vm/asm.h
|
balt vm/vm.c
|
||||||
setlocal fdm=manual
|
setlocal fdm=manual
|
||||||
setlocal fde=0
|
setlocal fde=0
|
||||||
setlocal fmr={{{,}}}
|
setlocal fmr={{{,}}}
|
||||||
@ -250,12 +253,12 @@ setlocal fdn=20
|
|||||||
setlocal fen
|
setlocal fen
|
||||||
silent! normal! zE
|
silent! normal! zE
|
||||||
let &fdl = &fdl
|
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
|
if s:l < 1 | let s:l = 1 | endif
|
||||||
keepjumps exe s:l
|
keepjumps exe s:l
|
||||||
normal! zt
|
normal! zt
|
||||||
keepjumps 265
|
keepjumps 369
|
||||||
normal! 031|
|
normal! 042|
|
||||||
wincmd w
|
wincmd w
|
||||||
argglobal
|
argglobal
|
||||||
if bufexists(fnamemodify("vm/vm.c", ":p")) | buffer vm/vm.c | else | edit vm/vm.c | endif
|
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
|
setlocal fen
|
||||||
silent! normal! zE
|
silent! normal! zE
|
||||||
let &fdl = &fdl
|
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
|
if s:l < 1 | let s:l = 1 | endif
|
||||||
keepjumps exe s:l
|
keepjumps exe s:l
|
||||||
normal! zt
|
normal! zt
|
||||||
keepjumps 123
|
keepjumps 228
|
||||||
normal! 0
|
normal! 01|
|
||||||
wincmd w
|
wincmd w
|
||||||
exe 'vert 1resize ' . ((&columns * 127 + 128) / 256)
|
exe 'vert 1resize ' . ((&columns * 127 + 128) / 256)
|
||||||
exe 'vert 2resize ' . ((&columns * 128 + 128) / 256)
|
exe 'vert 2resize ' . ((&columns * 128 + 128) / 256)
|
||||||
tabnext 3
|
tabnext 1
|
||||||
set stal=1
|
set stal=1
|
||||||
if exists('s:wipebuf') && len(win_findbuf(s:wipebuf)) == 0 && getbufvar(s:wipebuf, '&buftype') isnot# 'terminal'
|
if exists('s:wipebuf') && len(win_findbuf(s:wipebuf)) == 0 && getbufvar(s:wipebuf, '&buftype') isnot# 'terminal'
|
||||||
silent exe 'bwipe ' . s:wipebuf
|
silent exe 'bwipe ' . s:wipebuf
|
||||||
|
103
vm/asm.c
103
vm/asm.c
@ -149,6 +149,24 @@ Line s_in_i(Reg dst_reg, uint16_t op1_imm)
|
|||||||
.op1 = (Ex) { .imm = 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)
|
Line s_lit_i(uint16_t op1_imm)
|
||||||
{
|
{
|
||||||
return (Line) {
|
return (Line) {
|
||||||
@ -187,9 +205,29 @@ Line s_iret(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_BINARY_I(or, Or)
|
DEFINE_BINARY_I(or, Or)
|
||||||
|
DEFINE_BINARY_I(xor, Xor)
|
||||||
DEFINE_BINARY_I(and, And)
|
DEFINE_BINARY_I(and, And)
|
||||||
DEFINE_BINARY_I(add, Add)
|
DEFINE_BINARY_I(add, Add)
|
||||||
DEFINE_BINARY_I(sub, Sub)
|
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_dst_reg(uint32_t* ins, uint16_t reg);
|
||||||
static inline void add_op1_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 void set_mov_is_store(uint32_t* ins);
|
||||||
static inline uint16_t linety_arithm_ins(LineTy ty);
|
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;
|
bool debug = false;
|
||||||
|
|
||||||
@ -443,6 +481,31 @@ void assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size)
|
|||||||
out[ip++] = op1;
|
out[ip++] = op1;
|
||||||
break;
|
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: {
|
case LineTy_Lit_Imm: {
|
||||||
uint16_t op1 = line->op1.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;
|
break;
|
||||||
}
|
}
|
||||||
case LineTy_IRet: {
|
case LineTy_IRet: {
|
||||||
out[ip++] = Op_IRet;
|
uint32_t ins = Op_Ret;
|
||||||
|
ins |= 1 << 6;
|
||||||
|
out[ip++] = (uint16_t)ins;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LineTy_Or_Imm:
|
case LineTy_Or_Imm:
|
||||||
|
case LineTy_Xor_Imm:
|
||||||
case LineTy_And_Imm:
|
case LineTy_And_Imm:
|
||||||
case LineTy_Add_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 dst = line->dst.reg;
|
||||||
uint16_t op1 = line->op1.reg;
|
uint16_t op1 = line->op1.reg;
|
||||||
uint16_t op2 = line->op2.imm;
|
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;
|
out[ip++] = op2;
|
||||||
break;
|
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) {
|
if (debug) {
|
||||||
@ -547,6 +632,8 @@ void assemble_to_binary(uint16_t* out, const Line* lines, size_t lines_size)
|
|||||||
if (debug) {
|
if (debug) {
|
||||||
printf("done!\n");
|
printf("done!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return ip * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void add_dst_reg(uint32_t* ins, uint16_t reg)
|
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) {
|
switch (ty) {
|
||||||
case LineTy_Or_Imm:
|
case LineTy_Or_Imm:
|
||||||
|
case LineTy_Or_Reg:
|
||||||
return Op_Or;
|
return Op_Or;
|
||||||
|
case LineTy_Xor_Imm:
|
||||||
|
case LineTy_Xor_Reg:
|
||||||
|
return Op_Xor;
|
||||||
case LineTy_And_Imm:
|
case LineTy_And_Imm:
|
||||||
|
case LineTy_And_Reg:
|
||||||
return Op_And;
|
return Op_And;
|
||||||
case LineTy_Add_Imm:
|
case LineTy_Add_Imm:
|
||||||
|
case LineTy_Add_Reg:
|
||||||
return Op_Add;
|
return Op_Add;
|
||||||
case LineTy_Sub_Imm:
|
case LineTy_Sub_Imm:
|
||||||
|
case LineTy_Sub_Reg:
|
||||||
return Op_Sub;
|
return Op_Sub;
|
||||||
|
case LineTy_Mul_Imm:
|
||||||
|
case LineTy_Mul_Reg:
|
||||||
|
return Op_Mul;
|
||||||
default:
|
default:
|
||||||
fprintf(stderr, "error: line type '%d' not handled\n", ty);
|
fprintf(stderr, "error: line type '%d' not handled\n", ty);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
27
vm/asm.h
27
vm/asm.h
@ -24,14 +24,25 @@ typedef enum {
|
|||||||
LineTy_Mov16_MemReg_Reg,
|
LineTy_Mov16_MemReg_Reg,
|
||||||
LineTy_Mov16_MemLabel_Reg,
|
LineTy_Mov16_MemLabel_Reg,
|
||||||
LineTy_In_Imm,
|
LineTy_In_Imm,
|
||||||
|
LineTy_Call_Imm,
|
||||||
|
LineTy_Call_Label,
|
||||||
|
LineTy_Ret,
|
||||||
LineTy_Lit_Imm,
|
LineTy_Lit_Imm,
|
||||||
LineTy_Lit_Label,
|
LineTy_Lit_Label,
|
||||||
LineTy_Int,
|
LineTy_Int,
|
||||||
LineTy_IRet,
|
LineTy_IRet,
|
||||||
LineTy_Or_Imm,
|
LineTy_Or_Imm,
|
||||||
|
LineTy_Xor_Imm,
|
||||||
LineTy_And_Imm,
|
LineTy_And_Imm,
|
||||||
LineTy_Add_Imm,
|
LineTy_Add_Imm,
|
||||||
LineTy_Sub_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;
|
} LineTy;
|
||||||
|
|
||||||
typedef struct {
|
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_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_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_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_i(uint16_t op1_imm);
|
||||||
Line s_lit_l(int op1_label);
|
Line s_lit_l(int op1_label);
|
||||||
Line s_int(uint8_t int_id);
|
Line s_int(uint8_t int_id);
|
||||||
Line s_iret(void);
|
Line s_iret(void);
|
||||||
Line s_or_i(Reg dst_reg, Reg op1_reg, uint16_t op2_imm);
|
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_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_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_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_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) \
|
#define fmt_binary(VAL) \
|
||||||
(VAL) >> 7 & 1 ? '1' : '0', (VAL) >> 6 & 1 ? '1' : '0', \
|
(VAL) >> 7 & 1 ? '1' : '0', (VAL) >> 6 & 1 ? '1' : '0', \
|
||||||
|
109
vm/main.c
109
vm/main.c
@ -269,7 +269,8 @@ static inline bool is_exit_event(SDL_Event* event)
|
|||||||
return event->type == SDL_QUIT
|
return event->type == SDL_QUIT
|
||||||
|| (event->type == SDL_KEYDOWN
|
|| (event->type == SDL_KEYDOWN
|
||||||
&& event->key.keysym.scancode == SDL_SCANCODE_ESCAPE
|
&& 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)
|
void sdldevice_poll_events(SdlDevice* device)
|
||||||
@ -392,6 +393,10 @@ int main(void)
|
|||||||
int keyboard_interrupt_1 = label_ids++;
|
int keyboard_interrupt_1 = label_ids++;
|
||||||
int keyboard_interrupt_2 = label_ids++;
|
int keyboard_interrupt_2 = label_ids++;
|
||||||
int keyboard_interrupt_3 = 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_x = label_ids++;
|
||||||
int screen_y = label_ids++;
|
int screen_y = label_ids++;
|
||||||
|
|
||||||
@ -399,7 +404,6 @@ int main(void)
|
|||||||
|
|
||||||
Line program_asm[] = {
|
Line program_asm[] = {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
s_nop(),
|
|
||||||
|
|
||||||
// rsp points *at* the top element
|
// rsp points *at* the top element
|
||||||
s_mov16_r_i(Rbp, 2048),
|
s_mov16_r_i(Rbp, 2048),
|
||||||
@ -417,12 +421,13 @@ int main(void)
|
|||||||
L(main_loop),
|
L(main_loop),
|
||||||
s_hlt(),
|
s_hlt(),
|
||||||
s_jmp_l(main_loop),
|
s_jmp_l(main_loop),
|
||||||
s_nop(),
|
|
||||||
L(interrupt_table),
|
L(interrupt_table),
|
||||||
// size
|
// size
|
||||||
s_data_i(1),
|
s_data_i(1),
|
||||||
s_data_l(keyboard_interrupt),
|
s_data_l(keyboard_interrupt),
|
||||||
s_nop(),
|
s_nop(),
|
||||||
|
|
||||||
L(keyboard_interrupt),
|
L(keyboard_interrupt),
|
||||||
s_and_i(Rfl, Rfl, (uint16_t)~(1 << Fl_Int)),
|
s_and_i(Rfl, Rfl, (uint16_t)~(1 << Fl_Int)),
|
||||||
s_push_r(Rbp),
|
s_push_r(Rbp),
|
||||||
@ -430,28 +435,63 @@ int main(void)
|
|||||||
s_push_r(R0),
|
s_push_r(R0),
|
||||||
s_push_r(R1),
|
s_push_r(R1),
|
||||||
s_push_r(R2),
|
s_push_r(R2),
|
||||||
|
s_push_r(R3),
|
||||||
|
|
||||||
// read keyboard port
|
|
||||||
s_in_i(R0, Device_Keyboard),
|
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_mov16_r_r(R1, Rfl),
|
||||||
s_and_i(R1, R1, 1 << Fl_Eq),
|
s_and_i(R1, R1, 1 << Fl_Eq),
|
||||||
s_jnz_l(R1, keyboard_interrupt_0),
|
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),
|
L(keyboard_interrupt_0),
|
||||||
s_mov16_r_i(R0, ' '),
|
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),
|
L(keyboard_interrupt_1),
|
||||||
s_mov16_r_ml(R1, screen_x),
|
s_mov16_r_ml(R1, screen_x),
|
||||||
s_add_i(R1, R1, 0x0c00),
|
s_cmp_i(R1, 0),
|
||||||
s_mov8_mr_r(R1, R0),
|
s_mov16_r_r(R2, Rfl),
|
||||||
|
s_and_i(R2, R2, 1 << Fl_Eq),
|
||||||
s_mov16_r_ml(R1, screen_x),
|
s_jnz_l(R2, keyboard_interrupt_4),
|
||||||
s_add_i(R1, R1, 1),
|
s_sub_i(R1, R1, 1),
|
||||||
s_mov16_ml_r(screen_x, R1),
|
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(R2),
|
||||||
s_pop_r(R1),
|
s_pop_r(R1),
|
||||||
s_pop_r(R0),
|
s_pop_r(R0),
|
||||||
@ -459,6 +499,45 @@ int main(void)
|
|||||||
s_pop_r(Rbp),
|
s_pop_r(Rbp),
|
||||||
s_or_i(Rfl, Rfl, 1 << Fl_Int),
|
s_or_i(Rfl, Rfl, 1 << Fl_Int),
|
||||||
s_iret(),
|
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),
|
L(screen_x),
|
||||||
s_data_i(0),
|
s_data_i(0),
|
||||||
L(screen_y),
|
L(screen_y),
|
||||||
@ -470,7 +549,9 @@ int main(void)
|
|||||||
size_t program_asm_size = sizeof(program_asm) / sizeof(program_asm[0]);
|
size_t program_asm_size = sizeof(program_asm) / sizeof(program_asm[0]);
|
||||||
|
|
||||||
uint16_t* program = calloc(512 * 2, sizeof(uint16_t));
|
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);
|
// dump_program(program);
|
||||||
|
|
||||||
|
72
vm/vm.c
72
vm/vm.c
@ -22,7 +22,6 @@ static inline void handle_device_write(
|
|||||||
VM* vm, uint16_t op1, uint16_t device_id);
|
VM* vm, uint16_t op1, uint16_t device_id);
|
||||||
static inline int handle_interrupt(VM* vm, uint8_t int_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 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 void maybe_update_vcd(VM* vm, uint16_t addr);
|
||||||
static inline uint16_t eat_uint16(VM* vm);
|
static inline uint16_t eat_uint16(VM* vm);
|
||||||
static inline uint16_t read_seg_uint16(VM* vm, uint16_t ptr);
|
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;
|
VM* vm = &vm_inst;
|
||||||
|
|
||||||
uint16_t* rip = &vm->regs[Rip];
|
uint16_t* rbp = &vm->regs[Rbp];
|
||||||
uint16_t* rsp = &vm->regs[Rsp];
|
uint16_t* rsp = &vm->regs[Rsp];
|
||||||
uint16_t* rfl = &vm->regs[Rfl];
|
uint16_t* rfl = &vm->regs[Rfl];
|
||||||
|
uint16_t* rip = &vm->regs[Rip];
|
||||||
uint16_t* rcs = &vm->regs[Rcs];
|
uint16_t* rcs = &vm->regs[Rcs];
|
||||||
|
|
||||||
const uint16_t bootloader_size = 512;
|
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);
|
uint16_t ins = eat_uint16(vm);
|
||||||
Op op = ins_op(ins);
|
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) {
|
if (*rip >= 1024) {
|
||||||
printf("killed: rip >= 200\n");
|
printf("killed: rip >= 1024\n");
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,6 +224,46 @@ void vm_start(Drive* boot_drive, IODevice* io_device)
|
|||||||
handle_device_write(vm, op1, device_id);
|
handle_device_write(vm, op1, device_id);
|
||||||
break;
|
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: {
|
case Op_Lit: {
|
||||||
uint16_t op2 = ins_op1_or_imm(vm, ins);
|
uint16_t op2 = ins_op1_or_imm(vm, ins);
|
||||||
vm->int_table = op2;
|
vm->int_table = op2;
|
||||||
@ -238,10 +278,6 @@ void vm_start(Drive* boot_drive, IODevice* io_device)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Op_IRet: {
|
|
||||||
interrupt_return(vm);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case Op_Or:
|
case Op_Or:
|
||||||
case Op_Xor:
|
case Op_Xor:
|
||||||
@ -440,18 +476,6 @@ static inline int jump_to_interrupt_handler(VM* vm, uint8_t int_id)
|
|||||||
return 0;
|
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)
|
static inline void maybe_update_vcd(VM* vm, uint16_t addr)
|
||||||
{
|
{
|
||||||
if (!vm->io_device)
|
if (!vm->io_device)
|
||||||
@ -552,12 +576,14 @@ const char* op_str(Op op)
|
|||||||
return "in";
|
return "in";
|
||||||
case Op_Out:
|
case Op_Out:
|
||||||
return "out";
|
return "out";
|
||||||
|
case Op_Call:
|
||||||
|
return "call";
|
||||||
|
case Op_Ret:
|
||||||
|
return "ret";
|
||||||
case Op_Lit:
|
case Op_Lit:
|
||||||
return "lit";
|
return "lit";
|
||||||
case Op_Int:
|
case Op_Int:
|
||||||
return "int";
|
return "int";
|
||||||
case Op_IRet:
|
|
||||||
return "iret";
|
|
||||||
case Op_Or:
|
case Op_Or:
|
||||||
return "or";
|
return "or";
|
||||||
case Op_Xor:
|
case Op_Xor:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user