code wiki / (root) / nx_jam_response_test.nx

nx_jam_response_test.nx source

↩ module page · 63 lines · 3023 B

1// nx_jam_response_test.nx -- KAT: the FULL jam->action loop on a simulated 2// telemetry sequence: detect (jam_step) + respond (jr_step) -> CONTINUE/ALERT/PAUSE. 3// Proves a developing jam auto-pauses, and a transient does NOT. expect_exit: 0. 4 5import "nx_syscalls.nx" 6import "nx_jam_detect.nx" 7import "nx_jam_response.nx" 8 9func w(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } sys_write(1, s, n); return 0 } 10func wn(v: i64) -> i64 { 11 let b: *u8 = sys_mmap(28); var m: i64 = v 12 if m < 0 { m = 0 - m; sys_write(1, "-" as *u8, 1) } 13 let t: *u8 = sys_mmap(28); var k: i64 = 0 14 if m == 0 { t[0] = 48 as u8; k = 1 } 15 while m > 0 { t[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 } 16 var i: i64 = 0; while i < k { b[i] = t[k - 1 - i]; i = i + 1 } 17 sys_write(1, b, k); return 0 18} 19func chk(cond: i64, pass: *i64, fail: *i64, label: *u8) -> i64 { 20 if cond == 1 { pass[0] = pass[0] + 1; w(" ok " as *u8); w(label); w("\n" as *u8) } 21 else { fail[0] = fail[0] + 1; w(" XX " as *u8); w(label); w("\n" as *u8) } 22 return 0 23} 24 25// one full window: commanded e + measured feed -> detect -> respond 26func window(eq: i64, fq: i64, consec: *i64, pass: *i64, fail: *i64) -> i64 { 27 let TH: i64 = NX_JAM_Q14 28 let v: i64 = jam_step(eq, fq, TH, 70) 29 return jr_step(v, consec, 2, 4) // alert at 2 consecutive, pause at 4 30} 31 32func main() -> i64 { 33 let pass: *i64 = (sys_mmap(8)) as *i64 34 let fail: *i64 = (sys_mmap(8)) as *i64 35 pass[0] = 0 36 fail[0] = 0 37 let Q: i64 = NX_JAM_Q14 38 let consec: *i64 = (sys_mmap(8)) as *i64 39 consec[0] = 0 40 w("=== nx_jam_response KAT (detect + auto-pause loop) ===\n" as *u8) 41 42 // healthy printing -> CONTINUE 43 chk(window(10 * Q, 10 * Q, consec, pass, fail) == JR_CONTINUE, pass, fail, "healthy -> CONTINUE" as *u8) 44 // jam develops: window1 grind -> CONTINUE (debounce) 45 chk(window(10 * Q, 2 * Q, consec, pass, fail) == JR_CONTINUE, pass, fail, "1 jam window -> CONTINUE (debounced)" as *u8) 46 // window2 -> ALERT 47 chk(window(10 * Q, 1 * Q, consec, pass, fail) == JR_ALERT, pass, fail, "2 consecutive -> ALERT" as *u8) 48 // window3 -> still CONTINUE (below pause) 49 chk(window(10 * Q, 0, consec, pass, fail) == JR_ALERT, pass, fail, "3 consecutive -> still ALERT (escalating)" as *u8) 50 // window4 -> PAUSE (auto-pause the print) 51 chk(window(10 * Q, 0, consec, pass, fail) == JR_PAUSE, pass, fail, "4 consecutive -> AUTO-PAUSE" as *u8) 52 53 // transient must NOT pause: reset, one jam, then healthy 54 consec[0] = 0 55 window(10 * Q, 1 * Q, consec, pass, fail) // 1 jam 56 let a: i64 = window(10 * Q, 10 * Q, consec, pass, fail) // healthy clears it 57 chk(a == JR_CONTINUE, pass, fail, "transient cleared by a healthy window" as *u8) 58 chk(consec[0] == 0, pass, fail, "streak reset (no false pause)" as *u8) 59 60 w("=== VERDICT pass=" as *u8); wn(pass[0]); w(" fail=" as *u8); wn(fail[0]); w(" ===\n" as *u8) 61 if fail[0] == 0 { return 0 } 62 return 1 63}