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}