code wiki / _hdl_build / nx_gcode_job_gate.nx
nx_gcode_job_gate.nx source
↩ module page · 59 lines · 3792 B
1// nx_gcode_job_gate.nx -- second STATE_MACHINE composition gate (NXMOTION M1 seed): the
2// PRINT-JOB LIFECYCLE machine authored by _gjob_author via emit13. States 0=IDLE 1=HOMING
3// 2=READY 3=PRINTING 4=PAUSED 5=COMPLETE; events 0=home_cmd 1=home_done 2=start 3=pause
4// 4=resume 5=finish. THE SAFETY LAW IS THE TABLE: an unhomed start REFUSES (the Klipper-class
5// "must home before print" property, as a gate not a comment). Durable: GJOB-ROW/GJOB-GATE ->
6// knowledge/status/gcode_job_gate.log. Exit 0 iff all rows pass. Owner: Engineer (verify).
7// license_tier: ORIGINAL
8import "_pe_gjob.nx"
9import "nx_syscalls.nx"
10
11func gj_w(fd: i64, s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(fd, s, n); return 0 }
12func gj_wn(fd: i64, v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m; sys_write(fd,"-" as *u8,1)}; let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48;k=1}; while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1}; var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1}; sys_write(fd,bb,k); return 0 }
13
14func gj_row(lfd: i64, name: *u8, got: i64, want: i64) -> i64 {
15 gj_w(1, " " as *u8); gj_w(1, name); gj_w(1, ": got=" as *u8); gj_wn(1, got)
16 gj_w(lfd, "GJOB-ROW name=" as *u8); gj_w(lfd, name)
17 gj_w(lfd, " got=" as *u8); gj_wn(lfd, got); gj_w(lfd, " want=" as *u8); gj_wn(lfd, want)
18 if got == want { gj_w(1, " PASS\n" as *u8); gj_w(lfd, " verdict=PASS\n" as *u8); return 1 }
19 gj_w(1, " FAIL\n" as *u8); gj_w(lfd, " verdict=FAIL\n" as *u8)
20 return 0
21}
22
23// run the first n of a 6-slot event sequence from IDLE
24func gj_run(e0: i64, e1: i64, e2: i64, e3: i64, e4: i64, n: i64) -> i64 {
25 let ev: *i64 = sys_mmap(64) as *i64
26 ev[0]=e0; ev[1]=e1; ev[2]=e2; ev[3]=e3; ev[4]=e4
27 return _pe_gjob_run(ev, n, 0)
28}
29
30func main() -> i64 {
31 gj_w(1, "=== GCODE JOB GATE: print-job lifecycle law on the team-authored machine ===\n" as *u8)
32 let lfd: i64 = sys_openat_append("knowledge/status/gcode_job_gate.log" as *u8, 0x1a4)
33 if lfd < 0 { gj_w(1, " gate log open FAILED -- loud fail\n" as *u8); sys_exit(1); return 1 }
34 var pass: i64 = 0
35 // [1] happy path: home, done, start, pause, resume -> PRINTING(3)
36 pass = pass + gj_row(lfd, "home-start-pause-resume" as *u8, gj_run(0, 1, 2, 3, 4, 5), 3)
37 // [2] full job: home, done, start, finish -> COMPLETE(5)
38 pass = pass + gj_row(lfd, "full-job-completes" as *u8, gj_run(0, 1, 2, 5, 0, 4), 5)
39 // [3] THE SAFETY LAW: start while IDLE (unhomed) refused
40 pass = pass + gj_row(lfd, "unhomed-start-refused" as *u8, gj_run(2, 0, 0, 0, 0, 1), 0 - 1)
41 // [4] start while HOMING (home not done) refused
42 pass = pass + gj_row(lfd, "mid-homing-start-refused" as *u8, gj_run(0, 2, 0, 0, 0, 2), 0 - 1)
43 // [5] pause before printing refused
44 pass = pass + gj_row(lfd, "pause-before-print-refused" as *u8, gj_run(0, 1, 3, 0, 0, 3), 0 - 1)
45 // [6] resume without pause refused
46 pass = pass + gj_row(lfd, "resume-without-pause-refused" as *u8, gj_run(0, 1, 2, 4, 0, 4), 0 - 1)
47 // [7] nothing after COMPLETE
48 let ev6: *i64 = sys_mmap(64) as *i64
49 ev6[0]=0; ev6[1]=1; ev6[2]=2; ev6[3]=5; ev6[4]=2; ev6[5]=0
50 pass = pass + gj_row(lfd, "restart-after-complete-refused" as *u8, _pe_gjob_run(ev6, 5, 0), 0 - 1)
51 gj_w(lfd, "GJOB-GATE rows=7 pass=" as *u8); gj_wn(lfd, pass)
52 if pass == 7 { gj_w(lfd, " verdict=GREEN\n" as *u8) } else { gj_w(lfd, " verdict=RED\n" as *u8) }
53 sys_close(lfd)
54 gj_w(1, " --- GCODE JOB GATE: " as *u8); gj_wn(1, pass); gj_w(1, "/7 rows ---\n" as *u8)
55 if pass == 7 { gj_w(1, " GCODE JOB GATE: GREEN (home-before-print law held by authored machine)\n" as *u8); sys_exit(0); return 0 }
56 gj_w(1, " GCODE JOB GATE: RED (fix the table or the emitter, never the gate)\n" as *u8)
57 sys_exit(1)
58 return 1
59}