Skip to content

The SM8521 CPU

codingncaffeine edited this page Jun 28, 2026 · 2 revisions

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.

Core model

  • 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.

Registers

The register file lives in low memory and is banked: the working registers r0r15 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)
R0R15 general registers (also addressable as 8 pairs RR0RR14)
IE0/IE1, IR0/IR1 interrupt enable / request
P0P3 I/O ports (buttons, touch scan, cartridge slot select)
MMU0MMU4 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.

Instruction set

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.

Notes & gotchas

  • CLR and SWAP affect no flags — easy to get wrong if you reuse a flag-setting helper for them.
  • MULT uses the odd byte of the destination register pair as the multiplicand.
  • DIV stores 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 0x400x47 and the 16-bit ALU at 0x600x67 use the same two-byte register-pair-address operand form — a subtle place to introduce a wrong-length bug.

Cycle timing

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.

Clone this wiki locally