code wiki / _hdl_build / nx_fpsmeter_gate.nx
nx_fpsmeter_gate.nx source
↩ module page · 54 lines · 2713 B
1// nx_fpsmeter_gate.nx -- proves the sovereign rolling FPS meter (nx_fpsmeter). Native, fast.
2import "nx_syscalls.nx"
3import "nx_fpsmeter.nx"
4import "nx_gate_verdict.nx"
5
6func g_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 }
7func g_pn(v: i64) -> i64 {
8 let b: *u8 = sys_mmap(28); var x: i64 = v
9 if x == 0 { b[0]=48; sys_write(1,b,1); return 0 }
10 var d: i64=0; var y: i64=x
11 while y>0 { d=d+1; y=y/10 }
12 var i: i64=d-1; y=x
13 while i>=0 { b[i]=(48+(y%10)) as u8; y=y/10; i=i-1 }
14 sys_write(1,b,d); return 0
15}
16func g_check(name: *u8, cond: i64) -> i64 {
17 if cond==1 { g_puts(" PASS " as *u8) } else { g_puts(" FAIL " as *u8) }
18 g_puts(name); g_puts("\n" as *u8); return cond
19}
20func g_abs(v: i64) -> i64 { if v<0 { return 0-v } return v }
21// tick `nframes` frames `interval` ms apart starting at t0; return the fps reading at the last frame
22func run_fps(m: *i64, t0: i64, interval: i64, nframes: i64) -> i64 {
23 fm_init(m)
24 var t: i64 = t0
25 var i: i64 = 0
26 while i < nframes { fm_tick(m, t); t = t + interval; i = i + 1 }
27 return fm_fps(m, t - interval)
28}
29
30func main() -> i64 {
31 g_puts("nx_fpsmeter gate (rolling fps meter, MEASURED)\n" as *u8)
32 var pass: i64 = 0; var total: i64 = 0
33 let m: *i64 = sys_mmap((2 + FM_CAP) * 8) as *i64
34
35 let f30: i64 = run_fps(m, 100000, 33, 60) // ~30 fps (33ms apart)
36 let f8: i64 = run_fps(m, 100000, 125, 30) // ~8 fps (125ms apart)
37 let f60: i64 = run_fps(m, 100000, 16, 120) // ~60 fps (16ms apart)
38 g_puts(" [measure] 33ms->" as *u8); g_pn(f30); g_puts(" fps 125ms->" as *u8); g_pn(f8); g_puts(" fps 16ms->" as *u8); g_pn(f60); g_puts(" fps\n" as *u8)
39
40 pass = pass + g_check("33ms cadence reads ~30 fps" as *u8, g_abs(f30 - 30) <= 2); total=total+1
41 pass = pass + g_check("125ms cadence reads ~8 fps (the current vroom)" as *u8, g_abs(f8 - 8) <= 1); total=total+1
42 pass = pass + g_check("16ms cadence reads ~60 fps" as *u8, g_abs(f60 - 60) <= 3); total=total+1
43
44 g_puts("---- fpsmeter gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8)
45 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
46 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
47 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
48 let ctr__dry: *i64 = gv_ctr()
49 ctr__dry[0] = pass
50 ctr__dry[1] = total
51 let rc__dry: i64 = gv_verdict("FPSMETER-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
52 sys_exit(rc__dry)
53 return rc__dry
54}