code wiki / _hdl_build / nx_emu_x86_k.nx
nx_emu_x86_k.nx source
↩ module page · 55 lines · 3914 B
1// nx_emu_x86_k.nx -- x86 full-system ladder R4: the CONSOLIDATED kernel-subset x86-64 interpreter
2// (a reusable LIB; stops the per-rung duplication of R1-R3). Instruction set so far:
3// R1: mov imm/reg, shl, add, sub, syscall(write/exit)
4// R2: ZF/SF flags, cmp(48 39), jmp(EB), je(74), jne(75)
5// R3: 64-bit memory load/store via ModRM mod=00 base-indirect (48 89 store / 48 8B load)
6// R4: a STACK + push(50+r)/pop(58+r) + call(E8 rel32)/ret(C3) == real FUNCTION CALLS
7// Caller passes a `mem` region (RAM + stack live here; rsp = reg[4]). FLAT decode (nx_cc-friendly).
8// HONEST SCOPE: still flat 64-bit long-mode-ish execution; privilege modes (R5), IDT/paging (R6),
9// devices (R7), boot (R8+) are later rungs. No hardware writes (Rule 26). license_tier: ORIGINAL
10import "nx_syscalls_x86_64.nx"
11
12func k_i32(code: *u8, off: i64) -> i64 {
13 var v: i64 = (code[off] as i64) | ((code[off+1] as i64) << 8) | ((code[off+2] as i64) << 16) | ((code[off+3] as i64) << 24)
14 if (v & 0x80000000) != 0 { v = v - (1 << 32) }
15 return v
16}
17func k_st64(mem: *u8, addr: i64, v: i64) -> i64 { var i: i64=0; while i<8 { mem[addr+i]=((v>>(i*8)) & 0xff) as u8; i=i+1 } return 0 }
18func k_ld64(mem: *u8, addr: i64) -> i64 { var v: i64=0; var i: i64=0; while i<8 { v = v | ((mem[addr+i] as i64) << (i*8)); i=i+1 } return v }
19
20func emu_x86_run_k(code: *u8, len: i64, mem: *u8) -> i64 {
21 let reg: *i64 = sys_mmap(8 * 16) as *i64
22 var pc: i64 = 0
23 var zf: i64 = 0
24 var sf: i64 = 0
25 while pc < len {
26 let b: i64 = code[pc] as i64
27 var h: i64 = 0
28 if b == 0x0F {
29 if (code[pc+1] as i64) == 0x05 {
30 if reg[0] == 60 { return reg[7] & 0xff }
31 if reg[0] == 1 { sys_write(reg[7], ((code as i64) + reg[6]) as *u8, reg[2]) }
32 pc = pc + 2; h = 1
33 } else { return 0 - 1 }
34 }
35 if h == 0 { if b == 0xEB { var r: i64=code[pc+1] as i64; if r>127 { r=r-256 } pc = pc + 2 + r; h = 1 } }
36 if h == 0 { if b == 0x74 { var r: i64=code[pc+1] as i64; if r>127 { r=r-256 } if zf==1 { pc=pc+2+r } else { pc=pc+2 } h = 1 } }
37 if h == 0 { if b == 0x75 { var r: i64=code[pc+1] as i64; if r>127 { r=r-256 } if zf==0 { pc=pc+2+r } else { pc=pc+2 } h = 1 } }
38 if h == 0 { if b == 0xE8 { let rel: i64=k_i32(code, pc+1); reg[4]=reg[4]-8; k_st64(mem, reg[4], pc+5); pc=pc+5+rel; h = 1 } }
39 if h == 0 { if b == 0xC3 { pc = k_ld64(mem, reg[4]); reg[4]=reg[4]+8; h = 1 } }
40 if h == 0 { if b >= 0x50 { if b <= 0x57 { reg[4]=reg[4]-8; k_st64(mem, reg[4], reg[b-0x50]); pc=pc+1; h = 1 } } }
41 if h == 0 { if b >= 0x58 { if b <= 0x5F { reg[b-0x58]=k_ld64(mem, reg[4]); reg[4]=reg[4]+8; pc=pc+1; h = 1 } } }
42 if h == 0 { if b == 0x48 {
43 let op: i64 = code[pc+1] as i64
44 if op == 0xC7 { reg[(code[pc+2] as i64) & 7] = k_i32(code, pc+3); pc = pc + 7; h = 1 }
45 if op == 0x89 { let m: i64=code[pc+2] as i64; let md: i64=(m>>6)&3; if md==3 { reg[m & 7] = reg[(m>>3) & 7] } else { k_st64(mem, reg[m & 7], reg[(m>>3) & 7]) } pc = pc + 3; h = 1 }
46 if op == 0x8B { let m: i64=code[pc+2] as i64; let md: i64=(m>>6)&3; if md==3 { reg[(m>>3) & 7] = reg[m & 7] } else { reg[(m>>3) & 7] = k_ld64(mem, reg[m & 7]) } pc = pc + 3; h = 1 }
47 if op == 0xC1 { let m: i64=code[pc+2] as i64; reg[m & 7] = reg[m & 7] << (code[pc+3] as i64); pc = pc + 4; h = 1 }
48 if op == 0x01 { let m: i64=code[pc+2] as i64; reg[m & 7] = reg[m & 7] + reg[(m>>3) & 7]; pc = pc + 3; h = 1 }
49 if op == 0x29 { let m: i64=code[pc+2] as i64; reg[m & 7] = reg[m & 7] - reg[(m>>3) & 7]; pc = pc + 3; h = 1 }
50 if op == 0x39 { let m: i64=code[pc+2] as i64; let t: i64 = reg[m & 7] - reg[(m>>3) & 7]; if t==0 { zf=1 } else { zf=0 } if t<0 { sf=1 } else { sf=0 } pc = pc + 3; h = 1 }
51 } }
52 if h == 0 { return 0 - 3 }
53 }
54 return 0 - 4
55}