nx_emu_x86_real16_test.nx source
↩ module page · 79 lines · 6075 B
1// nx_emu_x86_real16_test.nx -- x86 ladder R9 rung-3: REALLY BOOT THE REAL IMAGE on the sovereign emu.
2// Up to now the emu ran 64-bit code and the real nishi_boot.img was only structurally checked -- never
3// EXECUTED. A real PC boots by loading sector 0 at linear 0x7C00 and running its 16-bit real-mode code
4// through BIOS INT 10h. This adds a 16-bit real-mode interpreter + a BIOS INT 10h (AH=0x0E teletype)
5// model, LOADS the real on-disk nishi_boot.img into emu memory at 0x7C00, sets IP=0x7C00, and EXECUTES
6// the actual boot opcodes (BE mov si / AC lodsb / 08C0 or al,al / 74 jz / B4 mov ah / CD10 int10 / EB jmp
7// / F4 hlt) until HALT, collecting the teletype output. This closes the "emu does not model BIOS" gap:
8// our real artifact now genuinely boots + prints its banner on our own machine model.
9// KAT: the console output == "NISHIOS x86 boots\r\n" AND the cpu halted cleanly.
10// HONEST SCOPE: this is the FIRST boot rung -- it executes the real MBR. INT 13h disk-read (load more
11// sectors) -> stage2 -> a long-mode kernel -> GDT/IDT/MM/scheduler/syscalls/userspace are the rungs
12// above (the real-OS ladder). No persistent-hardware writes (Rule 26).
13// expect_exit: 0 license_tier: ORIGINAL
14import "nx_syscalls.nx"
15
16func r16_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
17func r16_num(v: i64) -> i64 { let b: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)} let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i: i64=0; while i<k{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 }
18func r16_beq(a: *u8, b: *u8, n: i64) -> i64 { var i: i64=0; while i<n { if a[i]!=b[i] { return 0 } i=i+1 } return 1 }
19
20// 16-bit real-mode interpreter. mem = the machine's low memory (image already loaded at 0x7C00).
21// AX modeled as a 16-bit reg (AL=low byte, AH=high byte). SI is a linear address into mem (the boot
22// code uses absolute 0x7C00+offset). INT 10h AH=0x0E appends AL to the console buffer.
23// returns 0 = clean HLT, -1 = unknown opcode, -2 = ran away (no HLT).
24func emu_x86_real16(mem: *u8, entry: i64, console: *u8, clen: *i64) -> i64 {
25 var ip: i64 = entry
26 var ax: i64 = 0
27 var si: i64 = 0
28 var zf: i64 = 0
29 var guard: i64 = 0
30 while guard < 200000 {
31 guard = guard + 1
32 let op: i64 = mem[ip] as i64
33 if op == 0xF4 { return 0 } // hlt -> boot code finished
34 var h: i64 = 0
35 if h==0 { if op==0xBE { si = (mem[ip+1] as i64) | ((mem[ip+2] as i64) << 8); ip = ip + 3; h=1 } } // mov si, imm16
36 if h==0 { if op==0xAC { let al: i64 = mem[si] as i64; ax = (ax & 0xFF00) | al; si = si + 1; ip = ip + 1; h=1 } } // lodsb
37 if h==0 { if op==0x08 { let al2: i64 = ax & 0xFF; if al2==0 { zf=1 } else { zf=0 } ip = ip + 2; h=1 } } // or al,al
38 if h==0 { if op==0x74 { var r: i64 = mem[ip+1] as i64; if r>127 { r=r-256 } if zf==1 { ip = ip + 2 + r } else { ip = ip + 2 } h=1 } } // jz rel8
39 if h==0 { if op==0xB4 { ax = (ax & 0xFF) | ((mem[ip+1] as i64) << 8); ip = ip + 2; h=1 } } // mov ah, imm8
40 if h==0 { if op==0xCD { let vec: i64 = mem[ip+1] as i64; let ah: i64 = (ax >> 8) & 0xFF; if vec==0x10 { if ah==0x0E { console[clen[0]] = (ax & 0xFF) as u8; clen[0] = clen[0] + 1 } } ip = ip + 2; h=1 } } // int imm8 (BIOS)
41 if h==0 { if op==0xEB { var r2: i64 = mem[ip+1] as i64; if r2>127 { r2=r2-256 } ip = ip + 2 + r2; h=1 } } // jmp rel8
42 if h==0 { return 0 - 1 }
43 }
44 return 0 - 2
45}
46
47func main() -> i64 {
48 r16_puts("x86 ladder R9 rung-3: REALLY BOOT the real nishi_boot.img on the sovereign emu (16-bit real mode + BIOS INT 10h)\n" as *u8)
49 // load the REAL on-disk image
50 let lenp: *i64 = sys_mmap(8) as *i64
51 let img: *u8 = sys_read_file("knowledge/status/nishi_boot.img\x00" as *u8, lenp)
52 if (img as i64)==0 { r16_puts("R9-3 RED: cannot read knowledge/status/nishi_boot.img (build nx_nishi_bootimg first)\n" as *u8); sys_exit(1); return 1 }
53 let imglen: i64 = lenp[0]
54
55 // build the machine: 64KB low memory, load sector 0 at linear 0x7C00 (where BIOS puts the boot sector)
56 let mem: *u8 = sys_mmap(65536)
57 var i: i64=0
58 while i<65536 { mem[i]=0 as u8; i=i+1 }
59 var j: i64=0
60 while j<512 { mem[0x7C00 + j] = img[j]; j=j+1 }
61
62 let console: *u8 = sys_mmap(256)
63 let clen: *i64 = sys_mmap(8) as *i64
64 clen[0]=0
65 let rc: i64 = emu_x86_real16(mem, 0x7C00, console, clen)
66
67 r16_puts(" loaded real image (" as *u8); r16_num(imglen); r16_puts(" bytes) at 0x7C00, executed boot code -> halt rc=" as *u8); r16_num(rc); r16_puts("\n" as *u8)
68 r16_puts(" SOVEREIGN-EMU console (what a screen would show): " as *u8); sys_write(1, console, clen[0]); r16_puts(" [" as *u8); r16_num(clen[0]); r16_puts(" chars]\n" as *u8)
69
70 var pass: i64=0
71 var ttl: i64=0
72 ttl=ttl+1; r16_puts(" T1 real MBR image loaded (512 bytes, 0x55AA): " as *u8); if imglen>=512 { if mem[0x7C00+510]==(0x55 as u8) { if mem[0x7C00+511]==(0xAA as u8) { pass=pass+1; r16_puts("PASS\n" as *u8) } else { r16_puts("FAIL\n" as *u8) } } else { r16_puts("FAIL\n" as *u8) } } else { r16_puts("FAIL\n" as *u8) }
73 ttl=ttl+1; r16_puts(" T2 boot code printed 'NISHIOS x86 boots\\r\\n' via BIOS: " as *u8); if clen[0]==19 { if r16_beq(console, "NISHIOS x86 boots\x0D\x0A\x00" as *u8, 19)==1 { pass=pass+1; r16_puts("PASS\n" as *u8) } else { r16_puts("FAIL\n" as *u8) } } else { r16_puts("FAIL\n" as *u8) }
74 ttl=ttl+1; r16_puts(" T3 cpu halted cleanly (rc=0): " as *u8); if rc==0 { pass=pass+1; r16_puts("PASS\n" as *u8) } else { r16_puts("FAIL\n" as *u8) }
75
76 r16_puts("X86-REAL16-BOOT-GATE passed " as *u8); r16_num(pass); r16_puts("/" as *u8); r16_num(ttl)
77 if pass==ttl { r16_puts(" verdict=GREEN (the REAL bootable image executes + prints on the sovereign machine; INT 13h load -> stage2 -> kernel = next rungs)\n" as *u8); sys_exit(0); return 0 }
78 r16_puts(" verdict=RED\n" as *u8); sys_exit(1); return 1
79}