Added DTE Routine to SNES ROM: Hangs with screen corruption after IRQ

Started by JeanMarieStaub, July 08, 2011, 07:13:35 PM

Previous topic - Next topic


I have added a DTE Routine and table to a game that originally uses uncompressed text for its dialogues.
In principle it works, the routine and table do everything they're supposed to. However, at some point (it differs, I have not yet found on what it depends) during the routine, the SNES gets an IRQ and some instructions later goes into a BRK-loop and the screen only shows corruption.

Here is what my added routine looks like:

arch snes.cpu; lorom // Load settings for SNES/WDC65816 in LoROM mode
incsrc dte_table.asm

org $00b4a2 // Jump from old routine to dte subroutine
jsl check_codes_cont
nop // the JSL instruction is 3 bytes shorter than the old code, so we're padding here

org $01ecb0
check_codes_cont: // Continuation of the old code
cmp #$c3
bne +
jml $00b501
+; jsr dte_routine::init // Go go go!

namespace dte_routine
cmp #$40 // DTE charcodes start here
bcc end
cmp #$80 // DTE charcodes end here
bcs end

stx $1ffd // Backup X
sep #$30 // Make ACL + registers 8bit
sbc #$40 // Start charcodes from 0, not 40
ldx $1fff // Load DTE flagbyte from RAM
cpx #$9d // If this is set, we're at the 2nd char
beq secondchar

ldx #$9d // set flag to true
dec $0772 // decrement load_idx
asl // dte_num = charcode*2
jmp base

asl // dte_num = charcode*2
adc #$01 // select 2nd char of pair
ldx #$00 // set flag to false

stx $1fff // store flag in RAM
lda global::dte_table,x // load character from DTE table
rep #$10 // Make registers 16bit
ldx $1ffd // Restore X


Here is what an example of a crash looks like in the trace:

$00/B4A2 22 B0 EC 01 JSL $01ECB0[$01:ECB0]   A:0043 X:0BAE Y:0032 P:envMxdizC

$01/ECB0 C9 C3       CMP #$C3                A:0043 X:0BAE Y:0032 P:envMxdizC
$01/ECB2 D0 04       BNE $04    [$ECB8]      A:0043 X:0BAE Y:0032 P:eNvMxdizc
$01/ECB8 20 BC EC    JSR $ECBC  [$01:ECBC]   A:0043 X:0BAE Y:0032 P:eNvMxdizc

$01/ECBC C9 40       CMP #$40                A:0043 X:0BAE Y:0032 P:eNvMxdizc
$01/ECBE 90 31       BCC $31    [$ECF1]      A:0043 X:0BAE Y:0032 P:envMxdizC
$01/ECC0 18          CLC                     A:0043 X:0BAE Y:0032 P:envMxdizC
$01/ECC1 C9 80       CMP #$80                A:0043 X:0BAE Y:0032 P:envMxdizc
$01/ECC3 B0 2C       BCS $2C    [$ECF1]      A:0043 X:0BAE Y:0032 P:eNvMxdizc
$01/ECC5 8E FD 1F    STX $1FFD  [$00:1FFD]   A:0043 X:0BAE Y:0032 P:eNvMxdizc
$01/ECC8 E2 30       SEP #$30                A:0043 X:0BAE Y:0032 P:eNvMxdizc
$01/ECCA 38          SEC                     A:0043 X:00AE Y:0032 P:eNvMXdizc
$01/ECCB E9 40       SBC #$40                A:0043 X:00AE Y:0032 P:eNvMXdizC
$01/ECCD 18          CLC                     A:0003 X:00AE Y:0032 P:envMXdizC
$01/ECCE AE FF 1F    LDX $1FFF  [$00:1FFF]   A:0003 X:00AE Y:0032 P:envMXdizc
*** IRQ
$00/0204 5C 80 94 00 JMP $009480[$00:9480]   A:0003 X:0000 Y:0032 P:envMXdIZc
$00/9480 08          PHP                     A:0003 X:0000 Y:0032 P:envMXdIZc
$00/9481 C2 20       REP #$20                A:0003 X:0000 Y:0032 P:envMXdIZc
$00/9483 48          PHA                     A:0003 X:0000 Y:0032 P:envmXdIZc
$00/9484 DA          PHX                     A:0003 X:0000 Y:0032 P:envmXdIZc
$00/9485 5A          PHY                     A:0003 X:0000 Y:0032 P:envmXdIZc
$00/9486 8B          PHB                     A:0003 X:0000 Y:0032 P:envmXdIZc
$00/9487 0B          PHD                     A:0003 X:0000 Y:0032 P:envmXdIZc
$00/9488 A9 00 00    LDA #$0000              A:0003 X:0000 Y:0032 P:envmXdIZc
$00/948B E2 20       SEP #$20                A:0000 X:0000 Y:0032 P:envmXdIZc
$00/948D A2 00       LDX #$00                A:0000 X:0000 Y:0032 P:envMXdIZc
$00/948F 06 DA       ASL $DA    [$00:06DA]   A:0000 X:0000 Y:0032 P:envMXdIZc
$00/9491 2B          PLD                     A:0000 X:0000 Y:0032 P:envMXdIZc
$00/9492 A9 00       LDA #$00                A:0000 X:0000 Y:0032 P:envMXdIzc
$00/9494 48          PHA                     A:0000 X:0000 Y:0032 P:envMXdIZc
$00/9495 AB          PLB                     A:0000 X:0000 Y:0032 P:envMXdIZc
$00/9496 AD 11 42    LDA $4211  [$00:4211]   A:0000 X:0000 Y:0032 P:envMXdIZc
$00/9499 A5 D9       LDA $D9    [$00:06D9]   A:00C2 X:0000 Y:0032 P:eNvMXdIzc
$00/949B F0 06       BEQ $06    [$94A3]      A:0000 X:0000 Y:0032 P:envMXdIZc
$00/94A3 A5 DF       LDA $DF    [$00:06DF]   A:0000 X:0000 Y:0032 P:envMXdIZc
$00/94A5 F0 06       BEQ $06    [$94AD]      A:0008 X:0000 Y:0032 P:envMXdIzc
$00/94A7 20 16 B7    JSR $B716  [$00:B716]   A:0008 X:0000 Y:0032 P:envMXdIzc

$00/B716 A5 7F       LDA $7F    [$00:067F]   A:0008 X:0000 Y:0032 P:envMXdIzc
$00/B718 D0 25       BNE $25    [$B73F]      A:0001 X:0000 Y:0032 P:envMXdIzc
$00/B73F A2 08       LDX #$08                A:0001 X:0000 Y:0032 P:envMXdIzc
$00/B741 00 CA       BRK #$CA                A:0001 X:0008 Y:0032 P:envMXdIzc
*** BRK
$00/FFFF FF 00 C1 05 SBC $05C100,x[$05:C108] A:0001 X:0008 Y:0032 P:envMXdIzc
$00/0003 00 09       BRK #$09                A:00FF X:0008 Y:0032 P:eNvMXdIzc
*** BRK
$00/FFFF FF 00 C1 05 SBC $05C100,x[$05:C108] A:00FF X:0008 Y:0032 P:eNvMXdIzc
$00/0003 00 09       BRK #$09                A:00FD X:0008 Y:0032 P:eNvMXdIzC
*** BRK

The SBC/BRK then goes on forever.

My guess is that this has something to do with bad timing caused by my new routine.
I'm only taking my first steps in SNES ASM hacking, so I have virtually no knowledge about such issues, but I'm hoping I'll find some guidance here!
Thanks in advance!

P.S. Would it be better to attach the trace or is it okay to put it into the post itself?

Gideon Zhi

You've got X/Y set to 8-bit. The interrupt is expecting it to be 16-bit. That's why it's dying - it's interpreting LDX #$0800 as LDX #$08, then attempting to execute the #$00 after.
$01/ECC8 E2 30       SEP #$30                A:0043 X:0BAE Y:0032 P:eNvMxdizc <-- this is where you change the width of X/Y.