nx_chip8_font_gate.nx source
↩ module page · 69 lines · 3423 B
1// nx_chip8_font_gate.nx -- proves the CHIP-8 fontset + FX29 (set I = digit*5) + drawing a font glyph.
2// Program: V0=0xA, FX29 -> I=50, draw 5 rows at (0,0) -> the 'A' glyph (F0 90 F0 90 90). Checks I and pixels.
3import "nx_syscalls.nx"
4import "nx_chip8.nx"
5import "nx_gate_verdict.nx"
6
7func 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 }
8func g_pn(v: i64) -> i64 {
9 let b: *u8 = sys_mmap(28)
10 var x: i64 = v
11 if x < 0 { b[0] = 45 as u8; sys_write(1, b, 1); x = 0 - x }
12 if x == 0 { b[0] = 48 as u8; sys_write(1, b, 1); return 0 }
13 var d: i64 = 0
14 var y: i64 = x
15 while y > 0 { d = d + 1; y = y / 10 }
16 var i: i64 = d - 1
17 y = x
18 while i >= 0 { b[i] = (48 + (y % 10)) as u8; y = y / 10; i = i - 1 }
19 sys_write(1, b, d)
20 return 0
21}
22func g_check(name: *u8, cond: i64) -> i64 {
23 if cond == 1 { g_puts(" PASS " as *u8) } else { g_puts(" FAIL " as *u8) }
24 g_puts(name); g_puts("\n" as *u8)
25 return cond
26}
27
28func main() -> i64 {
29 g_puts("nx_chip8 font gate (FX29 + fontset glyph draw)\n" as *u8)
30 var pass: i64 = 0
31 var total: i64 = 0
32
33 let base: i64 = sys_mmap(65536) as i64
34 ch8_reset(base)
35 // 60 0A F0 29 61 00 62 00 D1 25 12 0A
36 ch8_load(base, 512, 96); ch8_load(base, 513, 10)
37 ch8_load(base, 514, 240); ch8_load(base, 515, 41)
38 ch8_load(base, 516, 97); ch8_load(base, 517, 0)
39 ch8_load(base, 518, 98); ch8_load(base, 519, 0)
40 ch8_load(base, 520, 209); ch8_load(base, 521, 37)
41 ch8_load(base, 522, 18); ch8_load(base, 523, 10)
42
43 var s: i64 = 0
44 while s < 5 { ch8_step(base); s = s + 1 }
45
46 pass = pass + g_check("FX29: I == 50 (digit 0xA * 5)" as *u8, ch8_geti(base) == 50); total = total + 1
47 // 'A' glyph row0 F0 = 11110000
48 pass = pass + g_check("row0: pixel(0,0)==1 pixel(3,0)==1" as *u8, ch8_pixel(base, 0, 0) == 1); total = total + 1
49 pass = pass + g_check("row0: pixel(3,0)==1" as *u8, ch8_pixel(base, 3, 0) == 1); total = total + 1
50 pass = pass + g_check("row0: pixel(4,0)==0 (F0 ends at col3)" as *u8, ch8_pixel(base, 4, 0) == 0); total = total + 1
51 // row1 90 = 10010000 -> col0 + col3
52 pass = pass + g_check("row1: pixel(0,1)==1" as *u8, ch8_pixel(base, 0, 1) == 1); total = total + 1
53 pass = pass + g_check("row1: pixel(1,1)==0 (90 gap)" as *u8, ch8_pixel(base, 1, 1) == 0); total = total + 1
54 pass = pass + g_check("row1: pixel(3,1)==1" as *u8, ch8_pixel(base, 3, 1) == 1); total = total + 1
55 // row4 90 -> col0 + col3
56 pass = pass + g_check("row4: pixel(0,4)==1 pixel(3,4)==1" as *u8, ch8_pixel(base, 0, 4) == 1); total = total + 1
57 pass = pass + g_check("row4: pixel(3,4)==1" as *u8, ch8_pixel(base, 3, 4) == 1); total = total + 1
58
59 g_puts("---- chip8 font gate: passed " as *u8); g_pn(pass); g_puts(" / " as *u8); g_pn(total); g_puts(" ----\n" as *u8)
60 // MIGRATED onto nx_gate_verdict by nx_gate_dry_apply (D001, minimal form): every check
61 // row above is untouched, so the PASS/FAIL vector cannot change; only the hand-rolled
62 // verdict emission is replaced by the ONE shared base class. Proven by nx_gate_migrate verify.
63 let ctr__dry: *i64 = gv_ctr()
64 ctr__dry[0] = pass
65 ctr__dry[1] = total
66 let rc__dry: i64 = gv_verdict("CHIP8-FONT-GATE" as *u8, ctr__dry, "teeth unchanged; verdict emission migrated onto the shared base class" as *u8)
67 sys_exit(rc__dry)
68 return rc__dry
69}