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

102 lines
3.7 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/background.ne — the static nametable.
//
// Painted once at reset-time (the first `background` declaration
// in the program is loaded before rendering is enabled). Contains
// the title banner, section labels, and the 5 × 8 keyboard grid.
// The Entering and Showing state handlers draw the dynamic input
// buffer, the cursor, and the 64-digit hash on top of this
// background via sprites.
//
// Legend characters are chosen to read cleanly when glanced over
// as ASCII art:
// upper-case A-Z and 0-9 → their matching glyph tile
// space ' ' → blank tile (tile 44)
// ':' ',' '-' '.' → punctuation glyph tiles
// '_' → space-key glyph on the keyboard
// 'p' → period-key glyph on the keyboard
// '<' '>' → backspace / enter key glyphs
//
// `palette_map:` leaves every metatile on bg sub-palette 0; the
// keyboard keys render as lt_gray (palette index 2), which reads
// cleanly against the dk_blue universal background.
background Screen {
legend {
" ": 44 // blank (universal colour)
"A": 1
"B": 2
"C": 3
"D": 4
"E": 5
"F": 6
"G": 7
"H": 8
"I": 9
"J": 10
"K": 11
"L": 12
"M": 13
"N": 14
"O": 15
"P": 16
"Q": 17
"R": 18
"S": 19
"T": 20
"U": 21
"V": 22
"W": 23
"X": 24
"Y": 25
"Z": 26
"0": 27
"1": 28
"2": 29
"3": 30
"4": 31
"5": 32
"6": 33
"7": 34
"8": 35
"9": 36
"_": 37 // space-key glyph (underscore bar)
"p": 38 // period-key glyph
":": 39
"-": 40
"<": 41 // backspace
">": 42 // enter
}
map: [
" ", // row 0
" SHA-256 HASHER ", // row 1 — title
" ", // row 2
" INPUT: ", // row 3 — input label
" ", // row 4 — input row A
" ", // row 5 — input row B
" ", // row 6
" TYPE A MESSAGE PRESS > ", // row 7 — prompt
" ", // row 8
" ", // row 9
" ", // row 10
" ", // row 11
" A B C D E F G H ", // row 12 — kb row 0
" I J K L M N O P ", // row 13 — kb row 1
" Q R S T U V W X ", // row 14 — kb row 2
" Y Z 0 1 2 3 4 5 ", // row 15 — kb row 3
" 6 7 8 9 _ p < > ", // row 16 — kb row 4
" ", // row 17
" ", // row 18
" ", // row 19
" SHA-256: ", // row 20 — hash label
" ", // row 21 — hash rows
" ", // row 22
" ", // row 23
" ", // row 24
" ", // row 25
" ", // row 26
" ", // row 27
" ", // row 28
" " // row 29
]
}