1
0
Fork 0
mirror of https://github.com/imjasonh/nescript synced 2026-07-08 17:06:04 +00:00
nescript/examples/sha256/assets.ne
Claude ba23f8578a
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

436 lines
15 KiB
Text
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// 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).
"........",
"........",
"........",
"........",
"........",
"........",
"........",
"........"
]
}