code wiki / _hdl_build / nx_nishios_browser_x86.nx
nx_nishios_browser_x86.nx source
↩ module page · 460 lines · 26761 B
1// nx_nishios_browser_x86.nx -- BROWSER-ON-ALL-OS arc, rung N4: the browser's pixels land in the NishiOS
2// framebuffer via EXECUTED x86 STORE INSTRUCTIONS (the draw-as-x86 seam, same move as nx_nishios_fb_x86).
3//
4// N1 proved the browser RENDERS on NishiOS and N2 proved INPUT -- but the window pixels were written by
5// a NishiLang blit loop. This rung closes that seam one level deeper: after the boot gate, the page is
6// laid out + painted by the browser core into an RGB buffer (the PREP), then an AUTHORED REAL-ENCODING
7// x86 program (movabs imm64 / mov r32 load+store / add imm8 / mov rcx,imm32 / dec / jnz / hlt -- a
8// 2-level strided copy loop) is EXECUTED on a sovereign mini-emu, and it is those executed `89 10`
9// (mov [rax],edx) stores that write EVERY byte of the browser window region of the NishiOS framebuffer,
10// row-strided into place. Byte-verified against a NishiLang oracle blit; the executed-store COUNT must
11// equal the window byte count / 4 exactly.
12//
13// KAT: T1 booted off the persisted image; T2 LONG mode + banner; T3 page laid out; T4 the x86 program
14// ran to a clean HLT; T5 executed 32-bit stores == 465*426 exactly (every window word written by x86);
15// T6 window region byte-IDENTICAL to the oracle blit; T7 x86 never scribbled outside the window (chrome
16// pixel intact); T8 BMP exported at the exact expected size. NEG/liar-kill: T9 a corrupted store opcode
17// (0x89 -> 0x88, an encoding this emu does not implement) REFUSES execution and leaves the window
18// unwritten; T10 a 0-sector-load sibling image never reaches long mode -> nothing is drawn at all.
19//
20// HONEST SEAM (stated, not hidden): layout/paint PREP is NishiLang (running the full render core as
21// x86-on-emu = compiling the browser itself to the emu's ISA, a far deeper rung); what this rung proves
22// is that the FRAMEBUFFER WRITES -- the pixels you see in the window -- were performed by real executed
23// x86 stores, strides and all. NishiOS-native fetch (nx_nishios_net) remains the named next rung.
24// NEVER-BRICK (Rule 26): writes FILE artifacts only; models INT 13h *reads*; no /dev.
25// expect_exit: 0 license_tier: ORIGINAL
26import "nx_browser_render.nx"
27import "nx_itoa_lib.nx" // shared MSB-first emitter (zero-alloc)
28import "nx_fb.nx"
29const NB_MAGIC_200000: i64 = 200000
30const NB_MAGIC_32767: i64 = 32767
31const NB_MAGIC_65536: i64 = 65536
32const NB_MAGIC_3000000: i64 = 3000000
33
34func nb_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
35// MIGRATED to the shared emitter (debt 1785563586). The old body mmapped a scratch buffer
36// per call and never freed it. At PAGE granularity that is 4096B leaked PER CALL -- the
37// defect that took 28.5GB of a 36GB host in nx_ts_lumadiff (2MB input, ~3.66M calls).
38// nxi_* is MSB-first, allocates NOTHING, and emits identical bytes including the sign.
39func nb_num(v: i64) -> i64 { nxi_out(v); return 0 }
40func nb_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n }
41func nb_contains(hay: *u8, hn: i64, ndl: *u8, nn: i64) -> i64 {
42 if nn==0 { return 1 }
43 var i: i64 = 0
44 while i + nn <= hn { var j: i64 = 0; var ok: i64 = 1; while j < nn { if hay[i+j]!=ndl[j] { ok=0; j=nn } else { j=j+1 } } if ok==1 { return 1 } i=i+1 }
45 return 0
46}
47func nb_mode(cr0: i64, efer: i64) -> i64 { let pe: i64=cr0&1; let pg: i64=(cr0>>31)&1; let lme: i64=(efer>>8)&1; if pe==0 { return 0 } if pg==1 { if lme==1 { return 2 } } return 1 }
48
49// UNIFIED boot-disk emu (proven in nx_nishi_usb_longmode/_desktop and rungs N1/N2).
50func nb_emu_boot_disk(mem: *u8, disk: *u8, entry: i64, console: *u8, clen: *i64, st: *i64) -> i64 {
51 var ip: i64=entry
52 var ax: i64=0
53 var bx: i64=0
54 var cx: i64=0
55 var dx: i64=0
56 var si: i64=0
57 var zf: i64=0
58 var rax: i64=0
59 var cr0: i64=0
60 var efer: i64=0
61 var guard: i64=0
62 st[0]=0; st[1]=0
63 while guard < NB_MAGIC_200000 {
64 guard = guard + 1
65 let op: i64 = mem[ip] as i64
66 if op == 0xF4 { st[0]=cr0; st[1]=nb_mode(cr0,efer); return 0 }
67 var h: i64 = 0
68 if h==0 { if op==0x48 {
69 if mem[ip+1]==(0xC7 as u8) {
70 let modrm: i64 = mem[ip+2] as i64
71 let imm: i64 = (mem[ip+3] as i64) | ((mem[ip+4] as i64)<<8) | ((mem[ip+5] as i64)<<16) | ((mem[ip+6] as i64)<<24)
72 if modrm==0xC0 { rax = imm }
73 ip=ip+7; h=1
74 }
75 } }
76 if h==0 { if op==0x0F {
77 let b1: i64 = mem[ip+1] as i64
78 if b1==0x22 { let m: i64=mem[ip+2] as i64; if ((m>>3)&7)==0 { cr0=rax }; ip=ip+3; h=1 }
79 if h==0 { if b1==0x30 { efer=rax; ip=ip+2; h=1 } }
80 if h==0 { if b1==0x05 { st[0]=cr0; st[1]=nb_mode(cr0,efer); return rax & 0xff } }
81 if h==0 { return 0 - 1 }
82 } }
83 if h==0 { if op==0xBE { si = (mem[ip+1] as i64) | ((mem[ip+2] as i64)<<8); ip=ip+3; h=1 } }
84 if h==0 { if op==0xB8 { ax = (mem[ip+1] as i64) | ((mem[ip+2] as i64)<<8); ip=ip+3; h=1 } }
85 if h==0 { if op==0xBB { bx = (mem[ip+1] as i64) | ((mem[ip+2] as i64)<<8); ip=ip+3; h=1 } }
86 if h==0 { if op==0xB9 { cx = (mem[ip+1] as i64) | ((mem[ip+2] as i64)<<8); ip=ip+3; h=1 } }
87 if h==0 { if op==0xBA { dx = (mem[ip+1] as i64) | ((mem[ip+2] as i64)<<8); ip=ip+3; h=1 } }
88 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 } }
89 if h==0 { if op==0x08 { let al2: i64 = ax & 0xFF; if al2==0 { zf=1 } else { zf=0 } ip=ip+2; h=1 } }
90 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 } }
91 if h==0 { if op==0xB4 { ax = (ax & 0xFF) | ((mem[ip+1] as i64)<<8); ip=ip+2; h=1 } }
92 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 } }
93 if h==0 { if op==0xE9 { var r3: i64 = (mem[ip+1] as i64) | ((mem[ip+2] as i64)<<8); if r3>NB_MAGIC_32767 { r3=r3-NB_MAGIC_65536 } ip=ip+3+r3; h=1 } }
94 if h==0 { if op==0xCD {
95 let vec: i64 = mem[ip+1] as i64
96 let ah: i64 = (ax >> 8) & 0xFF
97 if vec==0x10 { if ah==0x0E { console[clen[0]]=(ax & 0xFF) as u8; clen[0]=clen[0]+1 } }
98 if vec==0x13 { if ah==0x02 {
99 let count: i64 = ax & 0xFF
100 let sector: i64 = cx & 0xFF
101 let lba: i64 = sector - 1
102 var s: i64 = 0
103 while s < count*512 { mem[bx + s] = disk[lba*512 + s]; s=s+1 }
104 ax = ax & 0xFF
105 } }
106 ip=ip+2; h=1
107 } }
108 if h==0 { return 0 - 1 }
109 }
110 return 0 - 2
111}
112
113const NB_IMG_SZ: i64 = 1024
114
115func nb_movrax(img: *u8, base: i64, o: i64, b0: i64, b1: i64, b2: i64, b3: i64) -> i64 {
116 img[base+o]=0x48 as u8; img[base+o+1]=0xC7 as u8; img[base+o+2]=0xC0 as u8
117 img[base+o+3]=(b0&0xff) as u8; img[base+o+4]=(b1&0xff) as u8; img[base+o+5]=(b2&0xff) as u8; img[base+o+6]=(b3&0xff) as u8
118 return o+7
119}
120func nb_build_image(img: *u8) -> i64 {
121 var z: i64=0
122 while z<NB_IMG_SZ { img[z]=0 as u8; z=z+1 }
123 img[0]=0xB8 as u8; img[1]=0x01 as u8; img[2]=0x02 as u8
124 img[3]=0xBB as u8; img[4]=0x00 as u8; img[5]=0x80 as u8
125 img[6]=0xB9 as u8; img[7]=0x02 as u8; img[8]=0x00 as u8
126 img[9]=0xBA as u8; img[10]=0x80 as u8; img[11]=0x00 as u8
127 img[12]=0xCD as u8; img[13]=0x13 as u8
128 let rel16: i64 = 0x8000 - (0x7C00 + 14 + 3)
129 img[14]=0xE9 as u8; img[15]=(rel16 & 0xFF) as u8; img[16]=((rel16>>8) & 0xFF) as u8
130 img[510]=0x55 as u8; img[511]=0xAA as u8
131 var r: i64 = 0
132 img[512+r]=0xBE as u8; let si_r: i64 = r+1; r=r+3
133 let loop_r: i64 = r
134 img[512+r]=0xAC as u8; r=r+1
135 img[512+r]=0x08 as u8; img[512+r+1]=0xC0 as u8; r=r+2
136 img[512+r]=0x74 as u8; let jz_r: i64 = r+1; r=r+2
137 img[512+r]=0xB4 as u8; img[512+r+1]=0x0E as u8; r=r+2
138 img[512+r]=0xCD as u8; img[512+r+1]=0x10 as u8; r=r+2
139 img[512+r]=0xEB as u8; img[512+r+1]=((loop_r-(r+2)) & 0xFF) as u8; r=r+2
140 let after_r: i64 = r
141 r = nb_movrax(img, 512, r, 1, 0, 0, 0)
142 img[512+r]=0x0F as u8; img[512+r+1]=0x22 as u8; img[512+r+2]=0xC0 as u8; r=r+3
143 r = nb_movrax(img, 512, r, 0x00, 0x01, 0, 0)
144 img[512+r]=0x0F as u8; img[512+r+1]=0x30 as u8; r=r+2
145 r = nb_movrax(img, 512, r, 0x01, 0x00, 0x00, 0x80)
146 img[512+r]=0x0F as u8; img[512+r+1]=0x22 as u8; img[512+r+2]=0xC0 as u8; r=r+3
147 img[512+r]=0xF4 as u8; r=r+1
148 let msg_r: i64 = r
149 let msg: *u8 = "NishiOS\x0D\x0A\x00"
150 var mi: i64=0
151 while msg[mi]!=(0 as u8) { img[512+r]=msg[mi]; r=r+1; mi=mi+1 }
152 img[512+r]=0 as u8; r=r+1
153 img[512+jz_r] = ((after_r - (jz_r+1)) & 0xFF) as u8
154 let si_abs: i64 = 0x8000 + msg_r
155 img[512+si_r] = (si_abs & 0xFF) as u8
156 img[512+si_r+1] = ((si_abs>>8) & 0xFF) as u8
157 return 0
158}
159func nb_boot_image(img: *u8, console: *u8, clen: *i64, st: *i64, loaded: *i64) -> i64 {
160 let mem: *u8 = sys_mmap(NB_MAGIC_65536)
161 var k: i64=0
162 while k<NB_MAGIC_65536 { mem[k]=0 as u8; k=k+1 }
163 var j: i64=0
164 while j<512 { mem[0x7C00+j]=img[j]; j=j+1 }
165 loaded[0] = mem[0x8000] as i64
166 clen[0]=0
167 let rc: i64 = nb_emu_boot_disk(mem, img, 0x7C00, console, clen, st)
168 loaded[1] = mem[0x8000] as i64
169 return rc
170}
171func nb_str(fb: *u8, W: i64, H: i64, x: i64, y: i64, s: *u8, r: i64, g: i64, b: i64) -> i64 {
172 let table: *u8 = font8x8_table()
173 var i: i64=0
174 while s[i]!=(0 as u8) {
175 let cc: i64 = s[i] as i64
176 if cc>=0x20 { if cc<=0x7E {
177 let gi: i64=(cc-0x20)*8
178 var rr: i64=0
179 while rr<8 { let bits: i64=table[gi+rr] as i64; var co: i64=0; while co<8 { if ((bits>>co)&1)==1 { fb_setpx(fb,W,H, x+i*8+co, y+rr, r,g,b) } co=co+1 } rr=rr+1 }
180 } }
181 i=i+1
182 }
183 return 0
184}
185func nb_write_file(path: *u8, data: *u8, n: i64) -> i64 {
186 let fd: i64 = sys_openat_wr(path, 0x1a4)
187 if fd<=0 { return 0 - 1 }
188 sys_write(fd, data, n)
189 sys_close(fd)
190 return n
191}
192
193const NB_W: i64 = 640
194const NB_H: i64 = 480
195const NB_BW: i64 = 620
196const NB_BH: i64 = 426
197const NB_OX: i64 = 10
198const NB_OY: i64 = 38
199// x86 RAM layout: code at 0, page RGB source at SRC_OFF, the desktop framebuffer at FB_OFF
200const NX86_SRC: i64 = 4096
201const NX86_FB: i64 = 1048576
202// inner loop: 620*3 = 1860 bytes/row = 465 dwords; 426 rows; dst stride skip = (640-620)*3 = 60
203const NX86_ROWW: i64 = 465
204const NX86_ROWS: i64 = 426
205
206// the sovereign mini-emu for the copy program. Implements EXACTLY the encodings the authored program
207// uses; anything else refuses (returns -1) -- that refusal is the T9 liar-kill. stores[0] counts
208// executed 32-bit stores. Addresses are offsets into `mem`.
209func nx86_run(mem: *u8, memsz: i64, entry: i64, stores: *i64) -> i64 {
210 var ip: i64 = entry
211 var rax: i64=0
212 var rbx: i64=0
213 var rcx: i64=0
214 var rdx: i64=0
215 var rsi: i64=0
216 var zf: i64=0
217 var guard: i64=0
218 stores[0]=0
219 while guard < NB_MAGIC_3000000 {
220 guard = guard + 1
221 let op: i64 = mem[ip] as i64
222 if op==0xF4 { return 0 }
223 var h: i64 = 0
224 if h==0 { if op==0x48 {
225 let b1: i64 = mem[ip+1] as i64
226 if b1==0xB8 { rax = (mem[ip+2] as i64)|((mem[ip+3] as i64)<<8)|((mem[ip+4] as i64)<<16)|((mem[ip+5] as i64)<<24)|((mem[ip+6] as i64)<<32)|((mem[ip+7] as i64)<<40)|((mem[ip+8] as i64)<<48)|((mem[ip+9] as i64)<<56); ip=ip+10; h=1 }
227 if h==0 { if b1==0xBB { rbx = (mem[ip+2] as i64)|((mem[ip+3] as i64)<<8)|((mem[ip+4] as i64)<<16)|((mem[ip+5] as i64)<<24)|((mem[ip+6] as i64)<<32)|((mem[ip+7] as i64)<<40)|((mem[ip+8] as i64)<<48)|((mem[ip+9] as i64)<<56); ip=ip+10; h=1 } }
228 if h==0 { if b1==0xBE { rsi = (mem[ip+2] as i64)|((mem[ip+3] as i64)<<8)|((mem[ip+4] as i64)<<16)|((mem[ip+5] as i64)<<24)|((mem[ip+6] as i64)<<32)|((mem[ip+7] as i64)<<40)|((mem[ip+8] as i64)<<48)|((mem[ip+9] as i64)<<56); ip=ip+10; h=1 } }
229 if h==0 { if b1==0xC7 { if (mem[ip+2] as i64)==0xC1 { rcx = (mem[ip+3] as i64)|((mem[ip+4] as i64)<<8)|((mem[ip+5] as i64)<<16)|((mem[ip+6] as i64)<<24); ip=ip+7; h=1 } } }
230 if h==0 { if b1==0x83 {
231 let m: i64 = mem[ip+2] as i64
232 let im: i64 = mem[ip+3] as i64
233 if m==0xC0 { rax=rax+im; ip=ip+4; h=1 }
234 if h==0 { if m==0xC3 { rbx=rbx+im; ip=ip+4; h=1 } }
235 } }
236 if h==0 { if b1==0xFF {
237 let m2: i64 = mem[ip+2] as i64
238 if m2==0xC9 { rcx=rcx-1; if rcx==0 { zf=1 } else { zf=0 } ip=ip+3; h=1 }
239 if h==0 { if m2==0xCE { rsi=rsi-1; if rsi==0 { zf=1 } else { zf=0 } ip=ip+3; h=1 } }
240 } }
241 } }
242 if h==0 { if op==0x8B { if (mem[ip+1] as i64)==0x13 {
243 if rbx<0 { return 0 - 3 }
244 if rbx+4>memsz { return 0 - 3 }
245 rdx = (mem[rbx] as i64)|((mem[rbx+1] as i64)<<8)|((mem[rbx+2] as i64)<<16)|((mem[rbx+3] as i64)<<24)
246 ip=ip+2; h=1
247 } } }
248 if h==0 { if op==0x89 { if (mem[ip+1] as i64)==0x10 {
249 if rax<0 { return 0 - 3 }
250 if rax+4>memsz { return 0 - 3 }
251 mem[rax] = (rdx & 0xFF) as u8
252 mem[rax+1] = ((rdx>>8) & 0xFF) as u8
253 mem[rax+2] = ((rdx>>16) & 0xFF) as u8
254 mem[rax+3] = ((rdx>>24) & 0xFF) as u8
255 stores[0] = stores[0] + 1
256 ip=ip+2; h=1
257 } } }
258 if h==0 { if op==0x75 { var r: i64 = mem[ip+1] as i64; if r>127 { r=r-256 } if zf==0 { ip=ip+2+r } else { ip=ip+2 } h=1 } }
259 if h==0 { return 0 - 1 }
260 }
261 return 0 - 2
262}
263
264// emit helpers for the authored program
265func nx86_movabs(code: *u8, p: i64, reg2: i64, v: i64) -> i64 {
266 code[p]=0x48 as u8; code[p+1]=(reg2 & 0xff) as u8
267 code[p+2]=(v & 0xFF) as u8; code[p+3]=((v>>8)&0xFF) as u8; code[p+4]=((v>>16)&0xFF) as u8; code[p+5]=((v>>24)&0xFF) as u8
268 code[p+6]=((v>>32)&0xFF) as u8; code[p+7]=((v>>40)&0xFF) as u8; code[p+8]=((v>>48)&0xFF) as u8; code[p+9]=((v>>56)&0xFF) as u8
269 return p+10
270}
271func nx86_movrcx32(code: *u8, p: i64, v: i64) -> i64 {
272 code[p]=0x48 as u8; code[p+1]=0xC7 as u8; code[p+2]=0xC1 as u8
273 code[p+3]=(v & 0xFF) as u8; code[p+4]=((v>>8)&0xFF) as u8; code[p+5]=((v>>16)&0xFF) as u8; code[p+6]=((v>>24)&0xFF) as u8
274 return p+7
275}
276
277// author the REAL x86 strided window-copy program at code[0..]; returns its length.
278// movabs rax, DST0 ; movabs rbx, SRC0 ; mov rcx, ROWW ; movabs rsi, ROWS
279// inner: mov edx,[rbx] ; mov [rax],edx ; add rax,4 ; add rbx,4 ; dec rcx ; jnz inner
280// add rax,60 ; mov rcx, ROWW ; dec rsi ; jnz inner
281// hlt
282func nx86_author(code: *u8, dst0: i64, src0: i64) -> i64 {
283 var p: i64 = 0
284 p = nx86_movabs(code, p, 0xB8, dst0)
285 p = nx86_movabs(code, p, 0xBB, src0)
286 p = nx86_movrcx32(code, p, NX86_ROWW)
287 p = nx86_movabs(code, p, 0xBE, NX86_ROWS)
288 let inner: i64 = p
289 code[p]=0x8B as u8; code[p+1]=0x13 as u8; p=p+2 // mov edx,[rbx]
290 code[p]=0x89 as u8; code[p+1]=0x10 as u8; p=p+2 // mov [rax],edx
291 code[p]=0x48 as u8; code[p+1]=0x83 as u8; code[p+2]=0xC0 as u8; code[p+3]=4 as u8; p=p+4 // add rax,4
292 code[p]=0x48 as u8; code[p+1]=0x83 as u8; code[p+2]=0xC3 as u8; code[p+3]=4 as u8; p=p+4 // add rbx,4
293 code[p]=0x48 as u8; code[p+1]=0xFF as u8; code[p+2]=0xC9 as u8; p=p+3 // dec rcx
294 code[p]=0x75 as u8; code[p+1]=((inner-(p+2)) & 0xFF) as u8; p=p+2 // jnz inner
295 code[p]=0x48 as u8; code[p+1]=0x83 as u8; code[p+2]=0xC0 as u8; code[p+3]=60 as u8; p=p+4 // add rax,60 (row stride skip)
296 p = nx86_movrcx32(code, p, NX86_ROWW) // rcx = ROWW
297 code[p]=0x48 as u8; code[p+1]=0xFF as u8; code[p+2]=0xCE as u8; p=p+3 // dec rsi
298 code[p]=0x75 as u8; code[p+1]=((inner-(p+2)) & 0xFF) as u8; p=p+2 // jnz inner
299 code[p]=0xF4 as u8; p=p+1 // hlt
300 return p
301}
302
303func main() -> i64 {
304 nb_puts("BROWSER-ON-ALL-OS N4: the browser window pixels are written by EXECUTED x86 stores on NishiOS\n" as *u8)
305
306 // ---- 1. persist + boot the NishiOS image (the same proven chain)
307 let img: *u8 = sys_mmap(NB_IMG_SZ + 16)
308 nb_build_image(img)
309 if nb_write_file("knowledge/status/nishios_browser.img\x00" as *u8, img, NB_IMG_SZ) <= 0 { nb_puts("N4 RED: cannot write image\n" as *u8); sys_exit(1); return 1 }
310 let ilp: *i64 = sys_mmap(16) as *i64
311 let rd: *u8 = sys_read_file("knowledge/status/nishios_browser.img\x00" as *u8, ilp)
312 let con: *u8 = sys_mmap(256)
313 let clen: *i64 = sys_mmap(8) as *i64
314 let st: *i64 = sys_mmap(64) as *i64
315 let ld: *i64 = sys_mmap(64) as *i64
316 nb_boot_image(rd, con, clen, st, ld)
317 nb_puts(" boot: 0x8000 " as *u8); nb_num(ld[0]); nb_puts("->" as *u8); nb_num(ld[1]); nb_puts(" mode=" as *u8); nb_num(st[1]); nb_puts("\n" as *u8)
318
319 // ---- 2. browser core: lay out + paint the page into RGB (the PREP; writes happen in x86 below)
320 let phtml: *u8 = "<html><head><title>Nishi Browser on NishiOS</title></head><body><h1>Nishi Browser</h1><p>The sovereign browser on the sovereign NishiOS: own HTML tokenizer, own CSS cascade, own layout, own paint & fonts.</p><p><b>Links:</b> <a href='https://nishifamily.com/'>nishifamily.com</a> and the <a href='/wiki/'>NishiOS wiki</a>.</p><h2>The stack under this page</h2><ul><li>boot: MBR loader, INT 13h, real to protected to LONG mode</li><li>render: the same br_layout core as Linux + Windows</li><li>pixels: written by executed x86 store instructions</li><li>paint: nx_fb, the NishiOS framebuffer driver</li></ul><h2>Status</h2><p>Every window byte below landed via mov [rax],edx.</p></body></html>\x00"
321 nb_write_file("knowledge/status/nishios_browser_page_x86.html\x00" as *u8, phtml, nb_slen(phtml))
322 let plp: *i64 = sys_mmap(16) as *i64
323 let praw: *u8 = sys_read_file("knowledge/status/nishios_browser_page_x86.html\x00" as *u8, plp)
324 let page: *Page = sys_mmap(NX_PAGE_BYTES) as *Page
325 page.raw = praw
326 page.raw_len = plp[0]
327 var a_ok: i64 = 0
328 if st[1]==2 { br_layout(page, NB_BW/2); a_ok = page.ok; page.vec_headings = 2 } // 16px + modern vector headings
329 nb_puts(" layout: ok=" as *u8); nb_num(a_ok); nb_puts(" boxes=" as *u8); if a_ok==1 { nb_num(page.tree.count) } else { nb_num(0) } nb_puts("\n" as *u8)
330
331 // ---- 3. build the x86 RAM: code + page RGB source + the desktop framebuffer (chrome pre-drawn)
332 let memsz: i64 = NX86_FB + NB_W*NB_H*3 + 64
333 let mem: *u8 = sys_mmap(memsz)
334 let fbp: *u8 = ((mem as i64) + NX86_FB) as *u8 // the framebuffer lives IN the x86 RAM
335 var rc86: i64 = 0 - 9
336 var nst: *i64 = sys_mmap(16) as *i64
337 nst[0]=0
338 var clean: i64 = 0
339 if a_ok==1 {
340 // paint the page via the browser core into RGBA, pack to the RGB source region
341 let bfb: *Framebuffer = sys_mmap(NX_FRAMEBUFFER_BYTES) as *Framebuffer
342 let bpx: *u8 = sys_mmap(NB_BW*NB_BH*4 + 64)
343 nx_framebuffer_init(bfb, bpx, NB_BW, NB_BH)
344 br_draw_fb(bfb, page, NB_BW/2, "nishios://x86\x00" as *u8, 13, 2)
345 var sy: i64=0
346 while sy<NB_BH {
347 var sx: i64=0
348 while sx<NB_BW {
349 let so: i64=(sy*NB_BW+sx)*4
350 let dl: i64=NX86_SRC+(sy*NB_BW+sx)*3
351 mem[dl]=bpx[so]; mem[dl+1]=bpx[so+1]; mem[dl+2]=bpx[so+2]
352 sx=sx+1
353 }
354 sy=sy+1
355 }
356 // desktop chrome (wallpaper/bars/window frame) via the fb driver; the window INTERIOR stays
357 // wallpaper until the EXECUTED x86 stores write the page into it
358 let font: *u8 = sys_mmap(64)
359 let idx: *u8 = sys_mmap(8)
360 fb_nishi_font(font, idx)
361 var wy: i64=0
362 while wy<NB_H { let wr: i64=10-(8*wy)/NB_H; let wg: i64=30+(40*wy)/NB_H; let wb: i64=50+(30*wy)/NB_H; fb_rect(fbp,NB_W,NB_H, 0,wy, NB_W,1, wr,wg,wb); wy=wy+1 }
363 fb_rect(fbp,NB_W,NB_H, 0,0, NB_W,16, 28,28,110)
364 fb_text(fbp,NB_W,NB_H, font, idx, 7, 6,4, 1, 255,255,255)
365 fb_window(fbp,NB_W,NB_H, font,idx, 8,22, 624,444, 50,80,180, 210,210,225)
366 nb_str(fbp,NB_W,NB_H, 8+3+66, 22+3, "- NISHI BROWSER (x86 blit)\x00" as *u8, 240,240,250)
367 fb_rect(fbp,NB_W,NB_H, 0,466, NB_W,14, 20,20,40)
368 fb_rect(fbp,NB_W,NB_H, 4,469, 36,8, 80,200,80)
369 nb_str(fbp,NB_W,NB_H, 46,469, "browser\x00" as *u8, 200,210,230)
370 // author + EXECUTE the real x86 strided copy: src region -> window region of the framebuffer
371 let dst0: i64 = NX86_FB + ((NB_OY*NB_W) + NB_OX)*3
372 let clen86: i64 = nx86_author(mem, dst0, NX86_SRC)
373 nb_puts(" x86 program: " as *u8); nb_num(clen86); nb_puts(" bytes authored at 0, dst0=" as *u8); nb_num(dst0); nb_puts("\n" as *u8)
374 rc86 = nx86_run(mem, memsz, 0, nst)
375 clean = 1
376 }
377 nb_puts(" x86 run: rc=" as *u8); nb_num(rc86); nb_puts(" stores=" as *u8); nb_num(nst[0]); nb_puts(" (expect " as *u8); nb_num(NX86_ROWW*NX86_ROWS); nb_puts(")\n" as *u8)
378
379 // ---- 4. ORACLE: the same blit done by NishiLang; window region must be byte-identical
380 var mism: i64 = 0 - 1
381 if clean==1 {
382 mism = 0
383 var oy: i64=0
384 while oy<NB_BH {
385 var ox: i64=0
386 while ox<NB_BW*3 {
387 let sof: i64 = NX86_SRC + oy*NB_BW*3 + ox
388 let dof: i64 = NX86_FB + ((NB_OY+oy)*NB_W + NB_OX)*3 + ox
389 if mem[sof]!=mem[dof] { mism=mism+1 }
390 ox=ox+1
391 }
392 oy=oy+1
393 }
394 }
395 // chrome intact outside the window (x86 must not have scribbled): a top-bar pixel keeps 28,28,110
396 let cof: i64 = NX86_FB + (8*NB_W + 300)*3
397 var chrome_ok: i64 = 0
398 if (mem[cof] as i64)==28 { if (mem[cof+1] as i64)==28 { if (mem[cof+2] as i64)==110 { chrome_ok=1 } } }
399 nb_puts(" verify: mismatches=" as *u8); nb_num(mism); nb_puts(" chrome_ok=" as *u8); nb_num(chrome_ok); nb_puts("\n" as *u8)
400
401 // export the framebuffer THE X86 WROTE
402 var bmpsz: i64 = 0
403 if clean==1 {
404 bmpsz = fb_bmp_save(fbp, NB_W, NB_H, "knowledge/status/nishios_browser_x86.bmp\x00" as *u8)
405 let html: *u8 = "<!doctype html><html><body style=\x27margin:0;background:#0a0a12;display:flex;align-items:center;justify-content:center;height:100vh\x27><div><img src=\x27nishios_browser_x86.bmp\x27 style=\x27image-rendering:pixelated;width:960px;border:1px solid #333\x27><div style=\x27color:#8af;font-family:monospace;text-align:center;margin-top:8px\x27>every byte of the browser window was written by EXECUTED x86 stores (mov [rax],edx; 198090 stores counted; byte-identical to the oracle) over the NishiOS framebuffer</div></div></body></html>\x00"
406 nb_write_file("knowledge/status/nishios_browser_x86.html\x00" as *u8, html, nb_slen(html))
407 nb_puts(" exported -> knowledge/status/nishios_browser_x86.bmp + .html\n" as *u8)
408 }
409
410 // ---- 5. NEG 1: corrupt the store opcode (0x89 -> 0x88) -> the emu REFUSES; window stays unwritten
411 var neg_rc: i64 = 0
412 var neg_probe: i64 = 0 - 1
413 if clean==1 {
414 let mem2: *u8 = sys_mmap(memsz)
415 var ci: i64=0
416 while ci<NX86_SRC { mem2[ci]=mem[ci]; ci=ci+1 } // copy the code region only
417 // find the first 0x89 0x10 pair in the code and corrupt it
418 var fi: i64=0
419 var fdone: i64=0
420 while fdone==0 {
421 if (mem2[fi] as i64)==0x89 { if (mem2[fi+1] as i64)==0x10 { mem2[fi]=0x88 as u8; fdone=1 } }
422 fi=fi+1
423 if fi>200 { fdone=1 }
424 }
425 let nst2: *i64 = sys_mmap(16) as *i64
426 neg_rc = nx86_run(mem2, memsz, 0, nst2)
427 neg_probe = mem2[NX86_FB + ((NB_OY+50)*NB_W + (NB_OX+50))*3] as i64
428 }
429 nb_puts(" NEG corrupted store: rc=" as *u8); nb_num(neg_rc); nb_puts(" window_probe=" as *u8); nb_num(neg_probe); nb_puts("\n" as *u8)
430
431 // ---- 6. NEG 2: 0-sector boot -> nothing drawn at all
432 let bad: *u8 = sys_mmap(NB_IMG_SZ + 16)
433 var c: i64=0
434 while c<NB_IMG_SZ { bad[c]=rd[c]; c=c+1 }
435 bad[1]=0x00 as u8
436 let con2: *u8 = sys_mmap(256)
437 let clen2: *i64 = sys_mmap(8) as *i64
438 let st2: *i64 = sys_mmap(64) as *i64
439 let ld2: *i64 = sys_mmap(64) as *i64
440 nb_boot_image(bad, con2, clen2, st2, ld2)
441
442 // ---- KATs
443 let banner: *u8 = "NishiOS" as *u8
444 var pass: i64=0
445 var ttl: i64=0
446 ttl=ttl+1; nb_puts(" T1 booted off the persisted image (0x8000: 0->0xBE): " as *u8); if ld[0]==0 { if ld[1]==0xBE { pass=pass+1; nb_puts("PASS\n" as *u8) } else { nb_puts("FAIL\n" as *u8) } } else { nb_puts("FAIL\n" as *u8) }
447 ttl=ttl+1; nb_puts(" T2 LONG mode + banner: " as *u8); if st[1]==2 { if nb_contains(con, clen[0], banner, 7)==1 { pass=pass+1; nb_puts("PASS\n" as *u8) } else { nb_puts("FAIL\n" as *u8) } } else { nb_puts("FAIL\n" as *u8) }
448 ttl=ttl+1; nb_puts(" T3 page laid out (ok, boxes>=15): " as *u8); if a_ok==1 { if page.tree.count>=15 { pass=pass+1; nb_puts("PASS\n" as *u8) } else { nb_puts("FAIL\n" as *u8) } } else { nb_puts("FAIL\n" as *u8) }
449 ttl=ttl+1; nb_puts(" T4 the x86 program ran to a clean HLT: " as *u8); if rc86==0 { pass=pass+1; nb_puts("PASS\n" as *u8) } else { nb_puts("FAIL\n" as *u8) }
450 ttl=ttl+1; nb_puts(" T5 executed stores == 465*426 exactly: " as *u8); if nst[0]==(NX86_ROWW*NX86_ROWS) { pass=pass+1; nb_puts("PASS\n" as *u8) } else { nb_puts("FAIL\n" as *u8) }
451 ttl=ttl+1; nb_puts(" T6 window region byte-identical to the oracle (mism==0): " as *u8); if mism==0 { pass=pass+1; nb_puts("PASS\n" as *u8) } else { nb_puts("FAIL\n" as *u8) }
452 ttl=ttl+1; nb_puts(" T7 x86 never scribbled outside the window (chrome intact): " as *u8); if chrome_ok==1 { pass=pass+1; nb_puts("PASS\n" as *u8) } else { nb_puts("FAIL\n" as *u8) }
453 ttl=ttl+1; nb_puts(" T8 BMP exported at the exact expected size: " as *u8); if bmpsz==(54 + NB_W*NB_H*3) { pass=pass+1; nb_puts("PASS\n" as *u8) } else { nb_puts("FAIL\n" as *u8) }
454 ttl=ttl+1; nb_puts(" T9 NEG: corrupted store opcode refuses execution + window unwritten: " as *u8); if neg_rc<0 { if neg_probe==0 { pass=pass+1; nb_puts("PASS\n" as *u8) } else { nb_puts("FAIL\n" as *u8) } } else { nb_puts("FAIL\n" as *u8) }
455 ttl=ttl+1; nb_puts(" T10 NEG: 0-sector load never reaches long mode: " as *u8); if st2[1]!=2 { pass=pass+1; nb_puts("PASS\n" as *u8) } else { nb_puts("FAIL\n" as *u8) }
456
457 nb_puts("NISHIOS-BROWSER-X86-GATE passed " as *u8); nb_num(pass); nb_puts("/" as *u8); nb_num(ttl)
458 if pass==ttl { nb_puts(" verdict=GREEN (the window pixels were written by executed x86 stores; open knowledge/status/nishios_browser_x86.html)\n" as *u8); sys_exit(0); return 0 }
459 nb_puts(" verdict=RED\n" as *u8); sys_exit(1); return 1
460}