Skip to content

Step 1 of 5 · Reading · ~3 min

Read

Production

ROM Loader & Memory Map

A .ch8 file is the simplest executable format there is: the program's bytes and nothing else. No header, no magic number, no checksum. After this lesson your emulator can take such a file, put it where the machine expects it, refuse the files that cannot work, and answer questions about what is now in RAM.

What is in the file

Look at a real ROM with a hex dumper such as xxd -p: the first line of the IBM logo program reads

00e0a22a600c6108d01f7009a239d01fa2487008d01f7004a257d01f7008

Those are the instructions you decoded two lessons ago, byte after byte, with the first byte of each instruction first. The test harness sends ROMs in exactly this form: hex digits, two per byte, with whitespace ignored.

Loading is three steps

1. check the size           reject what can not run
2. reset the machine        zero RAM, put the font back
3. copy the bytes           ROM[0] goes to address 0x200, ROM[1] to 0x201, ...

The ROM region is 0xFFF - 0x200 + 1 = 3584 bytes. A file with more bytes than that cannot fit and is refused. A file with no bytes is refused too, because there is no instruction at 0x200 to run. An odd number of bytes is accepted, since a trailing data byte is legal, but worth flagging.

The order matters in one place: refusing must not damage anything. If a bad file is offered while another ROM is loaded, the loaded ROM keeps running. Check the size before touching memory.

Why reset

Suppose the machine runs the 132-byte logo and then loads a 4-byte ROM without clearing RAM. Bytes 4 to 131 of the old program are still sitting at 0x204 and beyond, and a program that runs off its end, or reads a table it expects to be zero, behaves differently from how it did on a fresh machine. A load starts from power-on state: all RAM zero, the font in place, only the new bytes copied over.

The map you built

0x000 - 0x04F   unused
0x050 - 0x09F   font: digit d at 0x050 + 5*d
0x0A0 - 0x1FF   unused
0x200 - 0xFFF   ROM, then free RAM (3584 bytes in all)

The font is part of the machine, not of the ROM. Every game assumes the digits exist, and one that draws a score calls the font instruction rather than carrying its own copy. If a loader let ROM bytes reach below 0x200 it could overwrite the font, so the 0x200 start also protects it.

Reading RAM back

The harness asks for single bytes and for 16-bit words. A word is two bytes with the lower address first: bytes A2 2A at 0x200 form the word 0xA22A, the instruction word. Reading a word at 0xFFF would need a byte that does not exist, so it is out of range, and so is any address above 0xFFF.

Common mistakes

  • Copying the ROM to address 0 instead of 0x200.
  • Skipping the reset, so a short ROM keeps the tail of the previous one.
  • Clearing RAM before the size check, so a rejected file still wipes the running program.
  • Accepting a ROM of 3585 bytes: the last byte lands at 0x1000, outside RAM.
  • Building a word with the low byte first.

Your exercise

The starter supplies the font and the output for FREE and FONT. You write load, byte and word, and the replies for each error.

Up nextQuirks: COSMAC vs ModernProduction

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…