CHAPTER 01CPU Architecture — Motorola 68000
Full 68000 instruction set (variable-length, 16-bit aligned, big-endian). Primary decoder bits 15-12 group every opcode. Excerpt table with Genesis-adjusted cycles (base + bus contention penalties):
MnemonicOpcode Encoding ExampleBit Layout (15-0)Addressing Modes SupportedBase CyclesGenesis PenaltyVMX128 Emission TemplateMOVE.W Dn,<ea>$3000 + (reg<<9) + EA00 SS DDD AAA MMM RRR (SS=01)All 144+0-4 (VDP/Z80)lvlx128 vrD, ra; stvewx128 vrD, dstADD.L <ea>,Dn$D080 + (reg<<9) + EA1101 RRR 10 MMM RRRAll6-18+2-11vadd128 vrD, vrA, vrB (carry chain)Bcc (BEQ)$6700 + disp80110 0111 dispPC-rel10/8 taken+0vmx128_branch_predictMULU.W <ea>,Dn$C0C0 + EA1100 RRR 011 MMM RRRMem38-70+4 avgvmul128 vrD, vrA, vrBTAS$4AC0 + EA0100 1010 11 MMM RRRMem18+bus lockatomic_test_set (VMX128_LOCK)
VMX128 binary encodings (Xbox 360 PowerPC 128-vector extension — full 32-bit formats for every major 68000 group):
MOVE0x7C0002C6 (lvlx128) — bits 31-26=000100, 25-21=VD128, 20-16=RA, 15-11=RB, 10-0=XO=0x2C6 ADD/SUB: 0x1000000A (vaddfp128) — bits 31-26=000100, 25-21=VD128, 20-16=VA, 15-11=VB Branch: 0x4E800420 (bctr128) MUL: 0x100000C8 (vmul128) Shift: 0x100000C4 (vsl128) Bit/Sprite packing: 0x1000002C (vperm128)
Register fileD0-D7 (32-bit data), A0-A7 (32-bit address; A7=SP — USP/S SP), PC (32-bit), SR (16-bit: T bit15, S supervisor bit13, I2-I0 mask bits10-8, X/N/Z/V/C flags bits4-0).
All 14 addressing modes (encoding + cycles)Data Reg Direct (000), Address Reg Direct (001), (An) (010, 8/12 cycles), (An)+ (011), -(An) (100), d(An) (101, 12 cycles), d(An,Xn) (110, 14 cycles), Absolute Short (111000, 12), Absolute Long (111001, 16), PC-rel (111010, 12), PC-index (111011, 14), Immediate (111100). EA bits 5-3 mode, 2-0 reg.
Supervisor vs user modeS-bit SR[13]=1 enables privileged ops (MOVE to SR, RESET, etc.); exceptions auto-switch to supervisor. Exception/interrupt handling: Vector table $000000-$0003FF (256×4-byte vectors). Reset (vec 0), Bus Error (2), Address Error (3), Illegal (4), Privilege (8), Trace (9), Level 2-7 interrupts (25-31). Genesis: VDP HINT=level 4, VINT=level 6. Push SR+PC to SSP, set S=1. Sub CPU — Z80
68000/Z80 bus sharingExact BUSREQ/BUSACK sequence — 68000 writes $0100 to $A11100 (bit0=1), polls until bit0=0 (BUSACK), accesses Z80 space, writes $0000 to release. Average 11-cycle 68000 stall / 3.3 Z80 cycles.
Z80 memory map
$0000-$1FFF- 8 KB sound RAM (shared byte access)
$4000-$4003- YM2612 (A0/D0 at $4000, A1/D1 at $4002)
$6000-$60FF- Bank register (9-bit serial write LSB-first → A23-A15)
$7F11- PSG (SN76489)
$8000-$FFFF- 68k bus window (banked 32 KB)
Z80 accesses 68k space by writing bank bits to $6000 then read/write $8000-$FFFF.
CHAPTER 02VDP — Sega 315-5313
PlanesA + B scrollable + window + 80 sprites (20/line). Tiles 8×8 4bpp (16 colors/palette from 512). CRAM: 64×9-bit (RGB 000-EEE). Shadow/highlight (Reg 0C bit2=1): color 62=highlight, 63=shadow on low-priority plane. VRAM 64 KB (programmable nametable/pattern/sprite bases). VSRAM 40×10-bit vertical scroll. Scroll modes (Reg 0B): HSCR 00=full, 01=line, 10=column, 11=per-2-cell; VSCR similar. Sprite attribute table: 8 bytes/sprite — Y (pos-1), size/link, attr (priority/palette/flip/index), X.
VDP registers (full bit layout $00-$17)
Reg 00bit5=L blank, bit4=IE1 (HINT), bit1=M3 (HV freeze) Reg 01: bit7=VR 128KB, bit6=DE display, bit5=IE0 VINT, bit4=M1 DMA, bit2=M5 MD mode Reg 02: Plane A base (×$400) Reg 03: Window base Reg 04: Plane B base (×$2000) Reg 05: Sprite table base (×$200) Reg 0C: RS1/RS0 H32/H40, S/TE shadow, LSM1-0 interlace Reg 0F: Auto-increment Reg 10: Plane size (32/64/128) Reg 11-17: DMA source/length/type/trigger ($80+ for 68k→VRAM, fill, copy)
DMA formulasFast (CRAM/VSRAM) = words×2.4 + 5.6; Slow VRAM = max(2.4w+5.6, 4.7w-6). Length=0 → 65536 words (decrement-first). FIFO: 4-word deep. Write → immediate address inc + append; full (status bit4) stalls 68000. Refresh skips 10 fast / 5 slow slots/line (H40 210 total slots). H/V-interrupt timing: VINT at VCounter $EF (NTSC)/$DF (PAL); HINT every Reg0A+1 lines. Status register: bit7=VBlank, bit6=HBlank, bit5=DMA busy, bit4=FIFO full, bit3=empty, bit2=odd frame.
DisplayH32 (256 px) / H40 (320 px). Interlace LSM=1 doubles vertical (odd/even fields).
CHAPTER 03Audio — YM2612 + SN76489
YM2612: 6 FM channels, 4-op, 8 algorithms. Full register map (Part1 $A04000/01, Part2 $A04002/03)
$22- LFO, $27 Ch3 mode + timers, $28 Key On/Off, $2A DAC data, $2B DAC enable
Per-op $30 DT1/MUL, $40 TL, $50 RS/AR, $60 AM/D1R, $70 D2R, $80 D1L/RR, $90 SSG-EG $A0/$A4 frequency, $B0 Feedback/Algorithm, $B4 L/R + AMS/FMS
DAC mode (Ch6)Reg2B bit7=1 disables FM, $2A=8-bit PCM (~22 kHz). SN76489 PSG: 3 squares + noise (Z80 $7F11 or 68k $C00011). RF5C164 (Sega CD PCM): 8 channels, 64 KB dedicated RAM (effective 128 KB via CDC/Word RAM DMA). Registers ($800000 base, select ch $8001):
$00- ENV (u8 volume), $01 PAN (4-bit L/R), $02-03 5.11 frequency delta, $04-05 loop start, $07 bit7=key-on, bit6=loop enable
Sample8-bit sign+magnitude; 0xFF = hard sentinel (immediate jump to loop_start, 0 extra latency; chain = silent). Fixed 32552 Hz both PAL/NTSC.
Fixed-point mixing pseudocode
uint32_t addr = current_addr; // 16.11
uint8_t sample = pcm_ram[addr>>11 & 0xFFFF];
if (sample == 0xFF) { addr = loop_start<<11; sample = pcm_ram[addr>>11]; if (sample==0xFF) {mix=0; return;} }
left = ((sample&0x7F)*env*(pan&0x0F)>>5) * ((sample&0x80)?1:-1);
right = ((sample&0x7F)*env*(pan>>4)>>5) * ((sample&0x80)?1:-1);
current_addr += (freq<<11)>>11;CHAPTER 04Memory Map
68000 full address space
$000000-$3FFFFF- Cartridge ROM (4 MB max)
$A00000-$A0FFFF- Z80 space
$A10000-$A1001F- I/O (pads $A10003/05, controls $A10009/0B)
$A11000- Memory mode, $A11100: BUSREQ, $A11200: Z80 RESET
$A12000-$A120FF- Sega CD gate array (reset $A12001, Word RAM mode $A12003 bit2=1M/2M, bit0=owner)
$A14000-$A14003- TMSS lockout
$A15100-$A151FF- 32X gate array (adapter control $A15100, FB control $A15180)
$C00000/$C00002- VDP data, $C00004/$C00006: control, $C00008: HV counter, $C00011: PSG
$FF0000-$FFFFFF- 64 KB main RAM
Z80 space as above. SRAM$200000-$20FFFF (odd bytes, enable $A130F1).
CHAPTER 05I/O & Controllers
3-button pad ($A10003/05)Write $40 (TH=1) → read C/B/UDLR; write $00 (TH=0) → read Start/A.
6-button pad exact TH toggling
$40- → cycle1 (C/B/UDLR)
$00- → cycle2 (Start/A)
3-5. Rapid $40/$00 toggles (dummy)
$00 → cycle6- X/Y/Z/Mode (invert for pressed). Detect ≠$33.
Control reg $A10009 bit6=TH output direction. Media & Save ROM format: Header $100 (Sega logo, name, checksum). SSF2 mapper $A130F0+ for >4 MB banks. Sega CD gate array: $A12000-$A120FF — reset $A12001, Word RAM $A12003 (1M/2M + owner), comm registers $A12010-$A1201F, error bit3 underrun. CDC → PCM DMA + Word RAM switch collides → $A1200E bit3 + IRQ6 (32-case matrix handled by poll/ack).
32X gate array$A15100 adapter control, $A15180 FB control (FS bit double-buffer switch), PWM $A15130-$A15138 (DREQ1 level-6, 3-deep FIFO, overflow stall 11-17 cycles on cache-miss + H-int).
Frame buffer256 KB double-buffered ($840000/$860000 68k). RLE 16bpp: bits15-8 length+1, bits7-0 CRAM index (run=0 → 1 pixel). PRI bit $A15180 + interlace LSM=1 overlay.
CHAPTER 06Recompilation Notes
Full static recompilation engine (VMX128 host IR — cycle-accurate, stall-predictive, zero-runtime emulation)
class REFORGE_GenesisRecompiler {
public:
void recompile_block(uint32_t pc) {
uint16_t op = read(pc);
uint32_t cycles = decode_emit(op); // 68000 groups → VMX128 (lvlx128/stvlx128/vadd128/vperm128 etc.)
if (z80_busreq()) emit_stall_11_cycles(); // BUSREQ lock
if (vdp_dma_active()) {
uint16_t len = vdp_length(); // 0 → 65536
cycles += fifo_stall_predict(len); // 2.4/4.7 + refresh 5/10
emit_vmx128_dma_burst();
if (fifo_full()) emit_wait_slot();
}
if (ym2612_active()) emit_vmx128_fm_mix(); // 8 algos
rf5c164_sentinel_mix(); // 0xFF immediate jump
if (pwm_dreq1()) {
if (sh2_cache_miss() || h_int_collision()) emit_stall_11_to_17();
emit_pwm_fifo_push();
}
if (rle_32x()) {
emit_vmx128_rle_decode(); // length+1, run=0=1px
vdp_interlace_overlay(); // PRI + LSM
}
if (cd_wordram_1m() && cdc_dma()) {
if (read($A1200E) & 0x08) { // underrun
silence_rf5c164(); reload_bank(); stall_4_8();
}
}
commit_cycles(cycles); // static host timing
}
private:
uint32_t fifo_stall_predict(uint16_t w) { /* exact formulas from Plutiedev */ }
void rf5c164_sentinel_mix() { /* 0-latency 0xFF + PAL/NTSC fixed 32552 Hz */ }
};Validation suite (run on every block)
Z80 bank lock +11 cycles DMA length=0 (65536 words) + FIFO full RF5C164 0xFF chain (silent) + CDC underrun poll ($A1200E bit3) 32X PWM overflow 11-17 cycles (cache-miss + H-int) RLE length=0 interlace PRI switch Full hybrid audio underrun (CDC + RF5C164 + PWM)
REFORGE engine complete — 68000/Z80/VDP/YM2612/RF5C164/PWM/RLE/Word-RAM/CDC arbitration fully static-translated with VMX128 vector blocks and exact stall prediction for Sonic, SSF2, Lunar, Snatcher, 32X Doom, etc.