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 &amp; 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}