-
Notifications
You must be signed in to change notification settings - Fork 0
The SM8521 CPU
The Game.com runs on a Sharp SM8521, an 8-bit single-chip microcontroller that integrates the CPU core (Sharp's "SM85CPU"), an LCD controller, a DMA blitter, timers, a sound generator, and I/O ports. There is very little public documentation for the CPU itself; the instruction set below was reconstructed from the datasheet's instruction summary plus reverse-engineering.
- 8-bit data, 16-bit address space (64 KB).
- Clock: 4.9152 MHz (a 9.8304 MHz crystal divided by two). Note that at least one well-known emulator hardcodes 5.5296 MHz, which is about 12.5% too fast; the 4.9152 MHz figure is supported by timing loops in the official development kit.
- 67 instructions across the full 256-byte opcode space, with 23 addressing modes. Instructions are variable length (1–4 bytes), so getting each opcode's length exactly right is essential.
The register file lives in low memory and is banked: the working registers r0–r15
are a window into an internal register RAM, and the window's base is PS0 & 0xF8. This
means changing PS0 swaps the entire register context, and ordinary RAM writes to the
low addresses alias the registers.
| Register | Purpose |
|---|---|
PC |
16-bit program counter |
SP (SPH/SPL) |
stack pointer; 8- or 16-bit per a SYS bit |
PS0 |
selects the register bank / interrupt priority |
PS1 |
flags: C Z S V D H B I (carry, zero, sign, overflow, decimal, half-carry, ?, interrupt-enable) |
R0–R15
|
general registers (also addressable as 8 pairs RR0…RR14) |
IE0/IE1, IR0/IR1
|
interrupt enable / request |
P0–P3
|
I/O ports (buttons, touch scan, cartridge slot select) |
MMU0–MMU4
|
memory bank registers (see [[Memory & the MMU |
Two operand notations matter: lowercase r/rr are bank-relative (resolved through
PS0), while uppercase R/RR are absolute register-file addresses.
Arithmetic (ADD/ADC/SUB/SBC/CMP/MULT/DIV/DA/INC/DEC and 16-bit …W forms), logic
(AND/OR/XOR/COM/NEG), shifts/rotates (RR/RL/RRC/RLC/SRL/SRA/SLL/SWAP), bit operations
(BSET/BCLR/BTST/BBC/BBS/BMOV/BCMP/BAND/BOR/BXOR), moves (MOV/MOVW/MOVM), and control
flow (BR/JMP/CALL/CALS/RET/IRET/DBNZ) with 16 condition codes.
-
CLRandSWAPaffect no flags — easy to get wrong if you reuse a flag-setting helper for them. -
MULTuses the odd byte of the destination register pair as the multiplicand. -
DIVstores the quotient in the dividend pair and the remainder in the high byte of the divisor pair; division by zero sets the overflow flag. - Two opcodes (
0x5A/0x5B) have indexed sub-modes that some references implement incompletely. - The 8-bit ALU at
0x40–0x47and the 16-bit ALU at0x60–0x67use the same two-byte register-pair-address operand form — a subtle place to introduce a wrong-length bug.
The clock itself is settled: 4.9152 MHz, proven by back-solving the official SDK's
calibrated delay loops (the same loops give exact hardware cycle counts for the instructions
they use — DECW=8, BR-taken=8, …). That's the anchor everything else is checked against.
Tigerbyte uses a per-instruction cycle table (not a flat per-instruction guess), with the SDK-confirmed values pinned. Closing the rest to hardware-exact is the main remaining accuracy frontier: the fully authoritative per-opcode/per-addressing-mode table lives only in the Sharp datasheet's instruction-set pages, which is the transcription target. Timing couples directly into the sound (the DAC rate is driven by Timer 1), so this is where audio fidelity is won.
Tigerbyte
Hardware
Development