Sega 32X is system #44 in sigilOS RetroPie. The 32X was an add-on for the Sega Genesis that added a pair of Hitachi SH-2 processors and a 320×224 ARGB framebuffer — more CPU and a cleaner colour space than the base console. The sigilOS core reuses the SH-2 engine from the Saturn (#43) via first-def-wins override, adds the 32X memory map, and renders packed RGB555 big-endian pixels to the ARGB framebuffer. uart=51 PASS.
First-def-wins SH-2 reuse
The Saturn and the 32X both use the Hitachi SH-2. Rather than duplicating the core, s32x.sg is linked before sh2.sg. The Sigil linker's first-def-wins rule means any function defined in s32x.sg takes precedence over the same symbol in sh2.sg. For the 32X, only the memory bus seam needs to differ — sh2_bus_read and sh2_bus_write in s32x.sg route to the 32X memory map (ROM, WRAM, frame VRAM). Everything else — the SH-2 instruction decoder, delay-slot handling, register file — comes from the shared sh2.sg unmodified.
This is the same pattern used for MSX Turbo-R (#42), which overrode the Z80 bus seam with an R800 core, and for CPS-1 (#37), which reused the 68000 core entirely. One CPU, multiple systems.
Memory map
| Address range | Region | Size |
|---|---|---|
$00000000–$0000FFFF | Boot ROM | 64 KB |
$04000000–$0403FFFF | Frame VRAM (RGB555 big-endian) | 143,360 B |
$06000000–$0603FFFF | WRAM (work RAM) | 256 KB |
The frame VRAM layout stores one 16-bit RGB555 pixel per 2 bytes, big-endian, for a 320×224 framebuffer. Each pixel: bits [14:10] = R, [9:5] = G, [4:0] = B. Bit 15 is unused (high bit of the big-endian word).
RGB555 → ARGB conversion
s32x_rgb555(px) extracts the three 5-bit channels and scales each to 8 bits by shifting left 3 and ORing with the top bits — the standard 5-to-8 expansion:
fn s32x_rgb555(px: Int) -> Int {
let r5 = (px >> 10) & 31
let g5 = (px >> 5) & 31
let b5 = px & 31
let r8 = (r5 << 3) | (r5 >> 2)
let g8 = (g5 << 3) | (g5 >> 2)
let b8 = (b5 << 3) | (b5 >> 2)
return (255 << 24) | (r8 << 16) | (g8 << 8) | b8
}
The 5-to-8 expansion via (ch << 3) | (ch >> 2) maps 0→0 and 31→255 exactly, with a smooth ramp across the middle — identical to the Saturn's VDP2 backdrop expansion.
s32x_render
s32x_render(fvram, fb) walks the 71,680-pixel frame VRAM (320 × 224) and converts each packed RGB555 big-endian word to ARGB, writing into the output framebuffer. The big-endian read swaps bytes before extracting channels.
Test coverage
| Test | Checks | Result |
|---|---|---|
| WRAM bus r/w | Write and read back from $06000000 | PASS |
| Frame VRAM r/w | Write and read back from $04000000 | PASS |
| RGB555 decode | s32x_rgb555 oracle for R=31/G=0/B=0 → ARGB | PASS |
| s32x_render pixel | Single pixel round-trip through render pipeline | PASS |
| sh2_reset from ROM | Reset vector loads PC and SP from boot ROM | PASS |
| MOV #99,R2 step | Single SH-2 instruction executes correctly | PASS |