Step 1 of 5 · Reading · ~2 min
Read
Production
ROM Loader & Memory Map
A .ch8 file is the simplest binary format there is: raw bytes, copied
verbatim into RAM at 0x200. No magic, no header, no checksums.
That's the entire loader.
The memory map (Cowgod's reference)
0x000 - 0x04F font sprites (16 hex digits x 5 bytes each = 80 bytes)
0x050 - 0x1FF reserved (was the original interpreter on COSMAC VIP)
0x200 - 0xE9F program / data
0xEA0 - 0xEFF call stack (16 levels x 2 bytes) -- COSMAC convention
0xF00 - 0xFFF display refresh buffer (64x32 / 8 = 256 bytes)
Modern emulators don't have to honor the 0xEA0+ layout — they keep the stack and display as host-side arrays — but the font and the 0x200 start address are not negotiable. Every ROM ever written assumes them.
Who writes the font?
You do. At startup, before any ROM is loaded:
Each digit is 4 pixels wide and 5 rows tall. Encoded as 5 bytes; only the high nibble of each byte carries pixels (low nibble is always 0). Look at digit 0:
1111 0000 F0 ####
1001 0000 90 # #
1001 0000 90 # #
1001 0000 90 # #
1111 0000 F0 ####
The ROM calls FX29 with a digit (0..F) in VX; that op sets I to the address of the corresponding sprite. Then DXYN with N=5 draws it.
How big can a ROM be?
3584 bytes (0xFFF - 0x200 + 1). Most are 200-1500. The biggest stock CHIP-8 game I've seen is just under 3 KiB. SCHIP keeps the same limit; XO-CHIP extends RAM to 64 KiB with bank-switch opcodes.
Validation
There is no magic, no checksum. A robust loader can:
- Reject ROMs
> 3584bytes (won't fit). - Warn on odd byte counts (probably truncated, but legal).
- Bail if the file doesn't exist.
That's it. The rest is trust.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…