Compare commits
	
		
			2 Commits
		
	
	
		
			bcd1500f9c
			...
			b9a837e3c7
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| b9a837e3c7 | |||
| cad6ed9604 | 
							
								
								
									
										83
									
								
								Session.vim
									
									
									
									
									
								
							
							
						
						
									
										83
									
								
								Session.vim
									
									
									
									
									
								
							@ -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
									
									
									
									
									
								
							
							
						
						
									
										103
									
								
								vm/asm.c
									
									
									
									
									
								
							@ -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);
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										27
									
								
								vm/asm.h
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								vm/asm.h
									
									
									
									
									
								
							@ -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
									
									
									
									
									
								
							
							
						
						
									
										109
									
								
								vm/main.c
									
									
									
									
									
								
							@ -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);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										80
									
								
								vm/vm.c
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								vm/vm.c
									
									
									
									
									
								
							@ -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);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@ -154,8 +154,8 @@ void vm_start(Drive* boot_drive, IODevice* io_device)
 | 
			
		||||
                uint16_t addr;
 | 
			
		||||
                if (addr_is_reg) {
 | 
			
		||||
                    Reg reg = is_store ? ins_dst_reg(ins) : ins_op2_reg(ins);
 | 
			
		||||
                    uint16_t offset = eat_uint16(vm);
 | 
			
		||||
                    addr = vm->regs[reg] + offset;
 | 
			
		||||
                    int16_t offset = (int16_t)eat_uint16(vm);
 | 
			
		||||
                    addr = (uint16_t)((int16_t)vm->regs[reg] + offset);
 | 
			
		||||
                } else {
 | 
			
		||||
                    addr = eat_uint16(vm);
 | 
			
		||||
                }
 | 
			
		||||
@ -186,8 +186,8 @@ void vm_start(Drive* boot_drive, IODevice* io_device)
 | 
			
		||||
                uint16_t addr;
 | 
			
		||||
                if (addr_is_reg) {
 | 
			
		||||
                    Reg reg = is_store ? ins_dst_reg(ins) : ins_op2_reg(ins);
 | 
			
		||||
                    uint16_t offset = eat_uint16(vm);
 | 
			
		||||
                    addr = vm->regs[reg] + offset;
 | 
			
		||||
                    int16_t offset = (int16_t)eat_uint16(vm);
 | 
			
		||||
                    addr = (uint16_t)((int16_t)vm->regs[reg] + offset);
 | 
			
		||||
                } else {
 | 
			
		||||
                    addr = eat_uint16(vm);
 | 
			
		||||
                }
 | 
			
		||||
@ -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:
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user