OpenSNES
Modern Open-Source SNES Development SDK
Loading...
Searching...
No Matches
main.c File Reference

HiColor — 1792 colors on screen from a 4bpp background. More...

#include <snes.h>

Macros

#define VRAM_GFX   0x0000
 BG2 tiles at VRAM word $0000 (28672 bytes).
#define VRAM_MAP_BASE   0x3C00
 BG2 32x32 map base (word address).
#define VRAM_MAP_LOAD   0x3C80
 Map loads at row 4: BG2VOFS=31 makes screen line 0 show map row 4.

Functions

static void buildTilemap (void)
 Build krom's tilemap pattern: sequential tiles; even rows use palettes 0-3, odd rows 4-7 (the CGRAM ping-pong); one sub-palette per 64-pixel screen quarter (matches the converter's 64x8 segments).
void hicolorIrqStream (void)
 Per-scanline CGRAM streaming IRQ handler (irq_stream.asm).
static void hicolorVblank (void)
 VBlank: rewind the palette stream for the new frame.
int main (void)

Variables

static u16 pal_offset
 16-bit offset of sunset_pal within its bank (IRQ stream source)
u8 sunset_pal []
 28 rows x 4 segments x 16 colors BGR555 — streamed by the IRQ
u8 sunset_pal_end []
u8 sunset_pic []
 4bpp planar tiles, 896 sequential tiles (28 rows x 32), no dedup
u8 sunset_pic_end []
static u16 tilemap [896]
 Generated 32x28 tilemap (krom's fixed pattern — see buildTilemap).

Detailed Description

HiColor — 1792 colors on screen from a 4bpp background.

Port of krom (Peter Lemon)'s HiColor64PerTileRow demo (SNES/PPU/HDMA/HiColor64PerTileRow), the canonical "beat the palette ceiling" technique. An H-timer IRQ fires on EVERY scanline and DMAs 16 bytes (8 colors) into CGRAM while the PPU is drawing; over one 8-line tile row that streams a full fresh 64-color set. Even tile rows render from CGRAM colors 0-63 while the stream refills 64-127 for the odd row, and vice versa — 28 rows x 64 = 1792 colors from a background mode that nominally allows 128.

SNES Concepts
  • H-timer IRQ ($4207/$4200 bit 4) — per-scanline CPU interrupts
  • Raw IRQ handlers via irqSet() (see irq_stream.asm — ASM only)
  • General DMA to CGRAM ($2122) during active display
  • CGRAM double-banking via tilemap palette bits (rows alternate 0-3 / 4-7)
  • The NMITIMEN shadow: nmiSet/irqEnable compose instead of clobbering
What to Observe
A sunset over water with perfectly smooth gradients — 357 distinct colors on screen (measure any static 4bpp screen: max 128). The top of each 8-pixel band is where the palette race lives; krom's HTIME of 190 places the writes in H-blank.
Modules Used
console, dma, background
See also
https://github.com/PeterLemon/SNES — original demo & converter
docs/tutorials/graphics.md

Macro Definition Documentation

◆ VRAM_GFX

#define VRAM_GFX   0x0000

BG2 tiles at VRAM word $0000 (28672 bytes).

◆ VRAM_MAP_BASE

#define VRAM_MAP_BASE   0x3C00

BG2 32x32 map base (word address).

◆ VRAM_MAP_LOAD

#define VRAM_MAP_LOAD   0x3C80

Map loads at row 4: BG2VOFS=31 makes screen line 0 show map row 4.

Function Documentation

◆ buildTilemap()

void buildTilemap ( void )
static

Build krom's tilemap pattern: sequential tiles; even rows use palettes 0-3, odd rows 4-7 (the CGRAM ping-pong); one sub-palette per 64-pixel screen quarter (matches the converter's 64x8 segments).

◆ hicolorIrqStream()

void hicolorIrqStream ( void )
extern

Per-scanline CGRAM streaming IRQ handler (irq_stream.asm).

◆ hicolorVblank()

void hicolorVblank ( void )
static

VBlank: rewind the palette stream for the new frame.

Reloads CGRAM 0-63 with row 0's colors (128 bytes) and resets the DMA source to the table start. The per-scanline IRQ then streams the remaining 27 rows during active display, the source address auto-advancing across transfers. Mirrors krom's VBLANKIRQ verbatim.

◆ main()

int main ( void )

Variable Documentation

◆ pal_offset

u16 pal_offset
static

16-bit offset of sunset_pal within its bank (IRQ stream source)

◆ sunset_pal

u8 sunset_pal[]
extern

28 rows x 4 segments x 16 colors BGR555 — streamed by the IRQ

◆ sunset_pal_end

u8 sunset_pal_end[]

◆ sunset_pic

u8 sunset_pic[]
extern

4bpp planar tiles, 896 sequential tiles (28 rows x 32), no dedup

◆ sunset_pic_end

u8 sunset_pic_end[]

◆ tilemap

u16 tilemap[896]
static

Generated 32x28 tilemap (krom's fixed pattern — see buildTilemap).