code wiki / (root) / nx_chip8_font_gate.nx

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}