code wiki / _hdl_build / nx_mw_f32_probe.nx
nx_mw_f32_probe.nx source
↩ module page · 58 lines · 2821 B
1// nx_mw_f32_probe.nx -- MINIMAL repro probe for the 2026-07-02 native-render regression (vox3d + mineworld
2// gates suddenly render sky-only; projection r[2] sign wrong / scene displaced). Exercises the exact f32+m4
3// path project() uses, printing ACTUAL vs hand-computed EXPECTED. Diagnostic only. license_tier: ORIGINAL
4import "nx_syscalls.nx"
5import "nx_f32_hw.nx"
6
7func hw(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 }
8func pn(v: i64) -> i64 {
9 let b: *u8 = sys_mmap(32) as *u8
10 var x: i64 = v
11 var neg: i64 = 0
12 if x < 0 { neg = 1; x = 0 - x }
13 var i: i64 = 31
14 if x == 0 { b[i] = 48 as u8; i = i - 1 }
15 while x > 0 { b[i] = (48 + x % 10) as u8; x = x / 10; i = i - 1 }
16 if neg == 1 { b[i] = 45 as u8; i = i - 1 }
17 sys_write(1, (b as i64 + i + 1) as *u8, 31 - i)
18 return 0
19}
20func fr(num: i64, den: i64) -> i64 { return f32_div(f32_of(num), f32_of(den)) }
21// print f32 as milli-int
22func pf(x: i64) -> i64 { pn(f32_int(f32_mul(x, f32_of(1000)))); return 0 }
23
24func main() -> i64 {
25 hw("P1 add 3+4=" as *u8); pn(f32_int(f32_add(f32_of(3), f32_of(4)))); hw(" want 7\n" as *u8)
26 hw("P2 mul 3*4=" as *u8); pn(f32_int(f32_mul(f32_of(3), f32_of(4)))); hw(" want 12\n" as *u8)
27 hw("P3 div 300/4=" as *u8); pn(f32_int(fr(300, 4))); hw(" want 75\n" as *u8)
28 hw("P4 sub 3-10=" as *u8); pn(f32_int(f32_sub(f32_of(3), f32_of(10)))); hw(" want -7\n" as *u8)
29 var sb: i64 = 0
30 if (f32_of(0 - 5) & 0x80000000) != 0 { sb = 1 }
31 hw("P5 signbit(-5)=" as *u8); pn(sb); hw(" want 1 " as *u8)
32 var sb2: i64 = 0
33 if (f32_of(5) & 0x80000000) != 0 { sb2 = 1 }
34 hw("signbit(5)=" as *u8); pn(sb2); hw(" want 0\n" as *u8)
35 hw("P6 neg mfrac -375/1000 -> " as *u8); pf(f32_neg(fr(0 - 375, 1000))); hw(" want 375\n" as *u8)
36
37 // the exact build_R path: Ry=roty(1.0, 0.0), Rx=rotx(0.927, +0.375), R=Rx*Ry, r=R*(0,-8,4)
38 let Ry: *i64 = sys_mmap(16 * 8) as *i64
39 let Rx: *i64 = sys_mmap(16 * 8) as *i64
40 let R: *i64 = sys_mmap(16 * 8) as *i64
41 let v: *i64 = sys_mmap(4 * 8) as *i64
42 let r: *i64 = sys_mmap(4 * 8) as *i64
43 m4_roty(fr(1000, 1000), fr(0, 1000), Ry)
44 m4_rotx(fr(927, 1000), f32_neg(fr(0 - 375, 1000)), Rx)
45 m4_mul(Rx, Ry, R)
46 v[0] = f32_of(0)
47 v[1] = f32_of(0 - 8)
48 v[2] = f32_of(4)
49 v[3] = f32_of(0)
50 m4_vec4(R, v, r)
51 hw("P7 r=(" as *u8); pf(r[0]); hw("," as *u8); pf(r[1]); hw("," as *u8); pf(r[2])
52 hw(")x1000 want r2 in {708 (conv s*y+c*z) | 6708 (conv -s*y+c*z)} and r0=0\n" as *u8)
53 // identity check: Ry alone on v must return v
54 let r2v: *i64 = sys_mmap(4 * 8) as *i64
55 m4_vec4(Ry, v, r2v)
56 hw("P8 roty(1,0)*v=(" as *u8); pf(r2v[0]); hw("," as *u8); pf(r2v[1]); hw("," as *u8); pf(r2v[2]); hw(")x1000 want (0,-8000,4000)\n" as *u8)
57 return 0
58}