El SNES usa un CPU Ricoh 5A22 basado en el núcleo WDC 65816, una extensión de 16-bit del 6502.
Modo | Ejemplo | Descripción |
---|---|---|
Inmediato | LDA #$42 |
Carga el valor $42 en A |
Absoluto | LDA $7E0010 |
Carga el valor en $7E0010 |
Indexado | LDA $10,X |
Carga el valor en $10 + X |
Indirecto | LDA ($10) |
Carga el valor en la dirección almacenada en $10 |
A: Acumulador (8/16 bits) X, Y: Índices (8/16 bits) P: Registro de estado (Flags) PC: Contador de programa S: Puntero de pila D: Registro de base direct page DB: Banco de datos PB: Banco de programa
nvmxdizc (cada letra representa un bit) n: Negative (Negativo) v: Overflow (Desbordamiento) m: Memory/Accumulator (8/16 bit) x: Index Register Size (8/16 bit) d: Decimal Mode (Modo decimal) i: Interrupt Disable (Deshabilitar interrupciones) z: Zero (Resultado cero) c: Carry (Acarreo)
; Aumentar salud máxima a 255 LDA #$FF ; Carga FF (255) en A STA $7E0010 ; Almacena en dirección de salud máxima STA $7E0012 ; Actualiza salud actual RTS ; Retorno de subrutina
; Saltar rutina de daño original JMP $C0B000 ; Salta a nuestra nueva rutina ; Código original continuaría aquí... NuevaRutina: PHB ; Guarda banco de datos LDA #$00 ; Carga 0 en A (sin daño) PLB ; Restaura banco de datos RTL ; Retorno largo
CheckPowerUp: LDA $7E001A ; Carga tipo de power-up CMP #$05 ; Compara con nuestro nuevo tipo (5) BNE Original ; Si no es igual, salta a rutina original JSR NuevoEfecto ; Ejecuta nuestro nuevo efecto RTS NuevoEfecto: LDA #$02 ; Velocidad doble STA $7E0020 LDA #$FF ; Invencibilidad STA $7E0022 RTS
; Reemplazar JSR original con nuestro hook ORG $80A100 ; Dirección original JSR NuestroHook NuestroHook: PHA ; Guarda A en pila LDA $7E0010 ; Lee valor de RAM CMP #$50 ; Compara con 80 BCC Original ; Si menor, salta a original PLA ; Restaura A JMP $80A200 ; Salta a rutina alternativa Original: PLA ; Restaura A JMP $80A150 ; Salta a rutina original
.ORG $C0F000 ; Nuevo banco libre NuevasRutinas: ; --- Rutina de teleport --- PHX LDX #$0000 LDA #$01 STA $7F0000,X ; Almacena posición X INX CPX #$0010 BNE $-07 ; Bucle hasta X=16 PLX RTL ; En el código original: JSL $C0F000 ; Llama a nuestra nueva rutina
.ORG $008000 ; SRAM o espacio libre PatchRAM: LDA #$EA ; Opcode NOP STA $808000 ; Parchea dirección STA $808001 STA $808002 RTS ; Ejecutar desde algún trigger del juego
Herramienta | Descripción |
---|---|
WLA-DX | Ensamblador multiplataforma para 65816 |
bsnes-plus | Emulador con debugger avanzado |
Geiger's Debugger | Debugger especializado para SNES |
Lunar Monitor | Monitor de RAM/ROM para SMW |
# Makefile para parche ASM
TARGET = parche.ips
SOURCE = codigo.asm
all: $(TARGET)
$(TARGET): $(SOURCE)
wla-65816 -o $(SOURCE) objeto.obj
wlalink -v -r linkfile objeto.obj parche.bin
ipscreate original.rom parche.bin $(TARGET)
clean:
rm -f *.obj *.bin *.ips
Técnicas para depurar modificaciones:
; Ejemplo: Punto de interrupción en bsnes-plus // Comando en debugger: break $80A100 // Detiene ejecución aquí step // Ejecuta una instrucción trace // Muestra ejecución paso a paso
; Rutina para registrar ejecución LogExecution: PHA ; Guarda A PHX ; Guarda X LDX LogIndex ; Índice de log LDA $7E0010 ; Valor a registrar STA $7F0000,X ; Almacena en SRAM INX STX LogIndex PLX ; Restaura X PLA ; Restaura A RTS
Técnicas para código más eficiente:
; $7E0000-$7E1FFF es más rápido que otros bancos LDA $7E0010 ; Acceso rápido STA $7E0012 ; Almacenamiento rápido
; En lugar de: LDX #$0000 Loop: LDA Datos,X STA $7E1000,X INX CPX #$0004 BNE Loop ; Mejor: LDA Datos STA $7E1000 LDA Datos+1 STA $7E1001 LDA Datos+2 STA $7E1002 LDA Datos+3 STA $7E1003