1
0
Fork 0
mirror of https://github.com/imjasonh/nescript synced 2026-07-09 01:16:12 +00:00
nescript/examples/sha256/assets.ne

437 lines
15 KiB
Text
Raw Normal View History

examples/sha256: interactive SHA-256 hasher with on-screen keyboard An end-to-end FIPS 180-4 SHA-256 hasher running entirely on the NES. The player types up to 16 ASCII characters on a 5x8 on-screen keyboard, presses Enter, and the program computes and displays the 64-character hex digest. Layout (`examples/sha256/*.ne`): constants.ne layout + K[64] / H_INIT[8] tables (declared as `var` with init_array because the v0.1 compiler treats `const u8[N] = [...]` as a no-op — noted in the file) assets.ne 44-tile Tileset (A..Z, 0..9, punctuation, special keys, cursor) shared between BG and sprite layers background.ne static nametable (title, labels, keyboard grid) painted at reset state.ne globals sha_core.ne 32-bit byte primitives (copy, xor, and, add, not, rotr, shr) in inline asm + sigma/Sigma mixers + schedule/round steps + fold render.ne OAM helpers for cursor, input buffer, and 64-nibble digest keyboard.ne key dispatch table entering_state.ne cursor navigation + typing + auto-demo computing_state.ne phased driver (48 schedule steps + 64 rounds + fold across ~30 frames at 4 iterations each) showing_state.ne renders the 256-bit digest as 8 rows of 8 sprite glyphs Implementation notes: - All 32-bit words live as 4 little-endian bytes in `wk[64]`, `w[256]`, `h_state[32]` so every primitive walks four bytes with `LDA {arr},X`/`STA {arr},X` chains and, for adds, a carry chain. - Every primitive reads its parameters straight out of the transport slots `$04`/`$05` rather than `{dst}`/`{src}` substitutions: the inline-asm resolver looks parameters up in the analyzer's allocation table but the codegen spills them to a different per-function RAM slot, so `{dst}` would resolve to a ZP slot nothing ever writes to. Bypassing the substitution entirely sidesteps the issue without a compiler change. - Rotate-right by any amount is a byte-rotate loop plus a bit- rotate loop so the 10 SHA amounts (2, 6, 7, 11, 13, 17, 18, 19, 22, 25) all compile to a handful of chained `ROR`s. - The headless jsnes golden auto-types "NES" after 1 s of idle and captures its SHA-256 digest AE9145DB5CABC41FE34B54E34AF8881F462362EA20FD8F861B26532FFBB84E0D — byte-identical to `shasum` / `hashlib.sha256(b"NES")`. Build: `cargo run --release -- build examples/sha256.ne` https://claude.ai/code/session_01FRmSBruVWCufm3LsUVMs8v
2026-04-16 14:02:58 +00:00
// sha256/assets.ne — one big Tileset sprite block.
//
// The ROM uses a single 8 KB CHR page that both the background
// layer and the sprite layer read from, so every tile declared
// here is available either way. User tiles start at index 1
// (index 0 is reserved for the compiler's built-in smiley).
//
// The alphabet is a 2-pixel-stroke sans-serif that reads well on
// NES resolution. Every tile keeps its glyph inside a 6×6 window
// (columns 1..6, rows 1..6) so adjacent characters never touch.
//
// Colour vocabulary:
// . palette index 0 — transparent (sprites) / bg universal
// 2 palette index 2 — main glyph colour (white in bg0/sp0)
// 3 palette index 3 — accent (cursor bar, key arrows)
sprite Tileset {
pixels: [
// ── 1: A ─────────────────────────────────────────
"........",
"..2222..",
".22..22.",
".22..22.",
".222222.",
".22..22.",
".22..22.",
"........",
// ── 2: B ─────────────────────────────────────────
"........",
".22222..",
".22..22.",
".22222..",
".22..22.",
".22..22.",
".22222..",
"........",
// ── 3: C ─────────────────────────────────────────
"........",
"..22222.",
".22..22.",
".22.....",
".22.....",
".22..22.",
"..22222.",
"........",
// ── 4: D ─────────────────────────────────────────
"........",
".2222...",
".22.22..",
".22..22.",
".22..22.",
".22.22..",
".2222...",
"........",
// ── 5: E ─────────────────────────────────────────
"........",
".222222.",
".22.....",
".22222..",
".22.....",
".22.....",
".222222.",
"........",
// ── 6: F ─────────────────────────────────────────
"........",
".222222.",
".22.....",
".22222..",
".22.....",
".22.....",
".22.....",
"........",
// ── 7: G ─────────────────────────────────────────
"........",
"..22222.",
".22.....",
".22.222.",
".22..22.",
".22..22.",
"..2222..",
"........",
// ── 8: H ─────────────────────────────────────────
"........",
".22..22.",
".22..22.",
".222222.",
".22..22.",
".22..22.",
".22..22.",
"........",
// ── 9: I ─────────────────────────────────────────
"........",
"..2222..",
"...22...",
"...22...",
"...22...",
"...22...",
"..2222..",
"........",
// ── 10: J ────────────────────────────────────────
"........",
"....222.",
".....22.",
".....22.",
".....22.",
".22..22.",
"..2222..",
"........",
// ── 11: K ────────────────────────────────────────
"........",
".22..22.",
".22.22..",
".2222...",
".22.22..",
".22..22.",
".22..22.",
"........",
// ── 12: L ────────────────────────────────────────
"........",
".22.....",
".22.....",
".22.....",
".22.....",
".22.....",
".222222.",
"........",
// ── 13: M ────────────────────────────────────────
"........",
".22..22.",
".222222.",
".222222.",
".22..22.",
".22..22.",
".22..22.",
"........",
// ── 14: N ────────────────────────────────────────
"........",
".22..22.",
".222.22.",
".222222.",
".22.222.",
".22..22.",
".22..22.",
"........",
// ── 15: O ────────────────────────────────────────
"........",
"..2222..",
".22..22.",
".22..22.",
".22..22.",
".22..22.",
"..2222..",
"........",
// ── 16: P ────────────────────────────────────────
"........",
".22222..",
".22..22.",
".22..22.",
".22222..",
".22.....",
".22.....",
"........",
// ── 17: Q ────────────────────────────────────────
"........",
"..2222..",
".22..22.",
".22..22.",
".22.222.",
".22.22..",
"..222.2.",
"........",
// ── 18: R ────────────────────────────────────────
"........",
".22222..",
".22..22.",
".22..22.",
".22222..",
".22.22..",
".22..22.",
"........",
// ── 19: S ────────────────────────────────────────
"........",
"..22222.",
".22.....",
"..2222..",
".....22.",
".....22.",
".22222..",
"........",
// ── 20: T ────────────────────────────────────────
"........",
".222222.",
"...22...",
"...22...",
"...22...",
"...22...",
"...22...",
"........",
// ── 21: U ────────────────────────────────────────
"........",
".22..22.",
".22..22.",
".22..22.",
".22..22.",
".22..22.",
"..2222..",
"........",
// ── 22: V ────────────────────────────────────────
"........",
".22..22.",
".22..22.",
".22..22.",
".22..22.",
"..2222..",
"...22...",
"........",
// ── 23: W ────────────────────────────────────────
"........",
".22..22.",
".22..22.",
".22..22.",
".222222.",
".222222.",
".22..22.",
"........",
// ── 24: X ────────────────────────────────────────
"........",
".22..22.",
"..2222..",
"...22...",
"...22...",
"..2222..",
".22..22.",
"........",
// ── 25: Y ────────────────────────────────────────
"........",
".22..22.",
".22..22.",
"..2222..",
"...22...",
"...22...",
"...22...",
"........",
// ── 26: Z ────────────────────────────────────────
"........",
".222222.",
".....22.",
"....22..",
"...22...",
"..22....",
".222222.",
"........",
// ── 27: 0 ────────────────────────────────────────
"........",
"..2222..",
".22..22.",
".22..22.",
".22..22.",
".22..22.",
"..2222..",
"........",
// ── 28: 1 ────────────────────────────────────────
"........",
"...22...",
"..222...",
".2.22...",
"...22...",
"...22...",
"..2222..",
"........",
// ── 29: 2 ────────────────────────────────────────
"........",
"..2222..",
".22..22.",
".....22.",
"....22..",
"..22....",
".222222.",
"........",
// ── 30: 3 ────────────────────────────────────────
"........",
"..2222..",
".22..22.",
"....22..",
".....22.",
".22..22.",
"..2222..",
"........",
// ── 31: 4 ────────────────────────────────────────
"........",
"....22..",
"...222..",
"..2.22..",
".22.22..",
".222222.",
"....22..",
"........",
// ── 32: 5 ────────────────────────────────────────
"........",
".222222.",
".22.....",
".22222..",
".....22.",
".22..22.",
"..2222..",
"........",
// ── 33: 6 ────────────────────────────────────────
"........",
"..2222..",
".22.....",
".22222..",
".22..22.",
".22..22.",
"..2222..",
"........",
// ── 34: 7 ────────────────────────────────────────
"........",
".222222.",
".....22.",
"....22..",
"...22...",
"..22....",
"..22....",
"........",
// ── 35: 8 ────────────────────────────────────────
"........",
"..2222..",
".22..22.",
"..2222..",
".22..22.",
".22..22.",
"..2222..",
"........",
// ── 36: 9 ────────────────────────────────────────
"........",
"..2222..",
".22..22.",
".22..22.",
"..22222.",
".....22.",
"..2222..",
"........",
// ── 37: underscore / space ('_') ─────────────────
// A shallow underline so the "space" key is visible
// in the keyboard grid and the rendered input buffer
// shows blanks where the user typed spaces.
"........",
"........",
"........",
"........",
"........",
"........",
".222222.",
"........",
// ── 38: period ('.') ─────────────────────────────
"........",
"........",
"........",
"........",
"........",
"..22....",
"..22....",
"........",
// ── 39: colon (':') — used in labels only ────────
"........",
"........",
"...22...",
"...22...",
"........",
"...22...",
"...22...",
"........",
// ── 40: dash ('-') — used in labels only ─────────
"........",
"........",
"........",
"........",
".222222.",
"........",
"........",
"........",
// ── 41: backspace arrow ('<') ────────────────────
// A left-pointing arrow with a vertical bar on the
// right, read as "rub out" by anyone who's used a
// Unix terminal.
"........",
"...2..2.",
"..22..2.",
".222222.",
"..22..2.",
"...2..2.",
"........",
"........",
// ── 42: enter / return arrow ('>') ───────────────
// An arrow pointing down and left — the classic
// ↵ glyph flattened to monochrome. Drawn offset to
// the right so it reads as "confirm".
"........",
"......2.",
"......2.",
"..2...2.",
".22...2.",
"222222..",
".22.....",
"..2.....",
// ── 43: cursor glyph ─────────────────────────────
// A right-pointing triangle in the accent colour
// (palette index 3). When placed as a sprite at the
// cell immediately left of the selected key, it sits
// on a row that carries only this sprite, so it never
// contributes to the keyboard row's 8-per-scanline
// budget.
"........",
"..3.....",
"..33....",
"..333...",
"..333...",
"..33....",
"..3.....",
"........",
// ── 44: blank tile ───────────────────────────────
// Every pixel is palette index 0 — renders as the
// universal colour (dk_blue) in the background and
// as fully transparent when used as a sprite. Used
// to pad the nametable so short rows don't fall back
// to tile 0 (the built-in smiley glyph).
"........",
"........",
"........",
"........",
"........",
"........",
"........",
"........"
]
}