-
Notifications
You must be signed in to change notification settings - Fork 0
Boot Sequence
Bringing the Game.com up is a multi-stage handshake. Reconstructing it was a large part of getting the emulator working, and it's a good tour of how the machine fits together. (The machine requires its original system ROM images to boot; those are copyrighted and are not distributed with the core — see Building & Setup.)
On reset the CPU begins executing from a small on-chip boot ROM. Its first jobs are the usual low-level bring-up: disable interrupts, select the register bank, initialize the stack pointer, and program the MMU bank registers so the larger external system ROM is paged into the address space.
The boot ROM then runs a short loop that compares a signature string against the same string in the external system ROM, byte by byte. If they don't match it branches to a dead-end (an effective "no valid system ROM" halt); if they match, it falls through and jumps into the external kernel through one of the MMU-paged windows.
This handshake is a useful early correctness check when writing an emulator: if your MMU paging is even slightly wrong, the signature compare fails and the machine "hangs" right at the start — a clear, early signal.
Soon after entering the kernel, the code writes the clock-control register and then executes a STOP instruction. STOP halts the CPU until an interrupt occurs — here it's waiting for the oscillator to stabilize. In an emulator the clock is always "stable," so you simply need to deliver a wake (a clock-ready interrupt) to resume. Miss this and the machine looks frozen one instruction into the kernel.
From there the kernel runs an event-driven main loop. It enables interrupts, and the timer and display interrupts post events into a small queue in RAM; the main loop scans that queue and dispatches work — drawing the menu, animating, handling input. This is why the timers and interrupts (below) aren't optional: without them, the kernel reaches its event loop and waits forever for events that never arrive.
A subtle consequence: the kernel runs mostly with interrupts enabled, dropping into brief critical sections (disable → restore) to touch the shared event queue safely. If your interrupt model delivers a spurious interrupt at the wrong moment — for example, by "latching" a request that hardware would have dropped while masked — the kernel takes a wrong branch and the boot derails. Matching the hardware's drop-if-masked behavior is what makes it run.
Inserting a cartridge changes the boot path: the kernel probes the cartridge slot (via a port-select bit) and presents the cartridge on the menu. It does not auto-launch — the machine boots to the shell and the player selects the cartridge to start it, exactly as on hardware — the kernel's bank registers never map a cartridge page on their own, so launching a title is a menu action, not an automatic jump.
Tigerbyte
Hardware
Development