La Super Nintendo Entertainment System (SNES) fue lanzada en 1990 y representa uno de los sistemas de 16 bits más populares. Programar para SNES requiere entender su arquitectura única y trabajar con limitaciones específicas.
| Componente | Especificación |
|---|---|
| CPU | Ricoh 5A22 (basado en 65c816) a 3.58MHz (1.79MHz en modo slow) |
| RAM | 128KB WRAM + 64KB VRAM |
| Resolución | 256x224 a 512x448 (interlaced) |
| Colores | Hasta 32,768 (15-bit) en pantalla, 256 simultáneos por línea |
| Sprites | Hasta 128 en pantalla (32 por línea), tamaños de 8x8 a 64x64 |
$0000-$1FFF: WRAM (8KB mirrored)
$2100-$21FF: Registros PPU
$4200-$44FF: Registros del sistema y DMA
$7E0000-$7FFFFF: WRAM (128KB)
$8000-$FFFF: ROM del juego (bank switching)
; Cabecera SNES
.MEMORYMAP
SLOTSIZE $8000
DEFAULTSLOT 0
SLOT 0 $8000
.ENDME
.ROMBANKSIZE $8000
.ROMBANKS 1
.BANK 0 SLOT 0
.ORG $0000
.SECTION "Inicio" SEMIFREE
Start:
; Inicializar el sistema
sei ; Deshabilitar interrupciones
clc ; Limpiar carry
xce ; Cambiar a modo nativo
rep #$30 ; A=16 bits, X/Y=16 bits
ldx #$1FFF ; Configurar stack pointer
txs
; Configurar modo gráfico
lda #$80 ; Forzar blank
sta $2100
; Más inicialización...
; Habilitar display
lda #$0F
sta $2100
; Bucle principal
MainLoop:
wai ; Esperar VBlank
jmp MainLoop
.ENDS
El 65c816 tiene tres registros principales de 16 bits:
; Ejemplos de direccionamiento
lda #$1234 ; Inmediato
lda $00 ; Direct page
lda $1234 ; Absoluto
lda ($00),y ; Indirecto indexado
lda $1234,x ; Absoluto indexado
La SNES tiene varios modos gráficos (0-7) que determinan cómo se renderizan los fondos y sprites:
| Modo | Fondos | Colores | Notas |
|---|---|---|---|
| 0 | 4 fondos de 2bpp | 16 colores (4 paletas) | Más simple |
| 1 | BG1: 4bpp, BG2: 4bpp, BG3: 2bpp | BG1/BG2: 16 colores, BG3: 4 colores | Común en juegos |
| 7 | 1 fondo de 8bpp | 256 colores | Para gráficos detallados |
; Configurar modo 1 con prioridad para BG3
lda #$09
sta $2105 ; Registro BGMODE
; Configurar tamaños de tile
lda #$04 ; BG3 16x16 tiles
sta $2107 ; Registro BG3SC
; Configurar direcciones VRAM
lda #$00 ; BG1 tiles en $0000
sta $210B ; Registro BG12NBA
lda #$01 ; BG2 tiles en $1000
sta $210B
Los sprites (OBJ) en SNES son elementos gráficos que se mueven independientemente de los fondos. Cada sprite puede ser de 8x8 a 64x64 píxeles.
; OAM (Object Attribute Memory) estructura:
; Byte 0: Coordenada X (9 bits)
; Byte 1: Coordenada Y
; Byte 2: Número de tile
; Byte 3: Atributos (prioridad, paleta, flip, etc.)
; Cargar sprite en OAM
LoadSprite:
lda #$80 ; X = 128
sta $0200 ; OAM low table
lda #$00
sta $0201 ; Byte alto X (bit 9)
lda #$50 ; Y = 80
sta $0202
lda #$01 ; Tile 1
sta $0203
lda #$30 ; Paleta 3, prioridad 1, no flip
sta $0204
; Actualizar OAM
lda #$02 ; Iniciar DMA en canal 2
sta $420B
El sonido en SNES es manejado por el chip SPC700 con su propio DSP. Se programa cargando código y datos en su memoria.
; Inicializar sonido
InitSound:
lda #$AA ; Comando de inicialización
sta $2140
lda #$BB
sta $2141
; Esperar respuesta
- lda $2140
cmp #$CC
bne -
; Cargar datos SPC
; (usando DMA para transferir el programa SPC)
; Reproducir muestra de sonido
PlaySound:
lda #$01 ; Canal 1
sta $2140
lda #$00 ; Volumen completo
sta $2141
lda #sample_id ; ID de la muestra
sta $2142
lda #$00
sta $2143
La SNES puede leer hasta 8 botones por control (A, B, X, Y, Start, Select, L, R) más direccionales.
; Leer estado del control 1
ReadInput:
lda $4218 ; Byte bajo (B, Y, Select, Start, Up, Down, Left, Right)
sta controller1
lda $4219 ; Byte alto (A, X, L, R)
sta controller1+1
; Verificar botón A
lda controller1+1
and #$80 ; Máscara para A
beq NoAPressed
; Código cuando A está presionado
NoAPressed:
Este es un esqueleto básico para un juego simple:
; Inicialización del juego
InitGame:
; Configurar modo gráfico
lda #$09 ; Modo 1, prioridad BG3
sta $2105
; Cargar tiles en VRAM
jsr LoadTiles
; Cargar paletas
jsr LoadPalettes
; Inicializar sprites
jsr InitSprites
; Habilitar display
lda #$0F
sta $2100
; Bucle principal del juego
GameLoop:
wai ; Esperar VBlank
; Leer controles
jsr ReadInput
; Actualizar lógica del juego
jsr UpdateGame
; Renderizar
jsr Render
jmp GameLoop
; Rutinas del juego
LoadTiles:
; Implementar carga de tiles
rts
LoadPalettes:
; Implementar carga de paletas
rts
InitSprites:
; Inicializar OAM
rts
UpdateGame:
; Actualizar posición de sprites, etc.
rts
Render:
; Actualizar OAM, scroll, etc.
rts
Nota: Programar para SNES es un proceso complejo que requiere paciencia. Comienza con ejemplos simples y ve aumentando la complejidad gradualmente.
Advertencia: Distribuir ROMs de juegos comerciales es ilegal. Este manual es solo para desarrollo de juegos originales.