+  RHDN Forum Archive
|-+  Romhacking
| |-+  ROM Hacking Discussion
| | |-+  Added DTE Routine to SNES ROM: Hangs with screen corruption after IRQ
Pages: [1]
Author Topic: Added DTE Routine to SNES ROM: Hangs with screen corruption after IRQ  (Read 1 times)
JeanMarieStaub
Guest
« on: July 08, 2011, 06:13:35 pm »

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:
Code:
arch snes.cpu; lorom\t// Load settings for SNES/WDC65816 in LoROM mode
incsrc dte_table.asm

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

org $01ecb0
check_codes_cont:\t// Continuation of the old code
\tcmp #$c3
\tbne +
\t\tjml $00b501
+;\tjsr dte_routine::init\t// Go go go!
\trtl
\t
namespace dte_routine
init:
\tcmp #$40\t\t// DTE charcodes start here
\tbcc end
\tclc
\tcmp #$80\t\t// DTE charcodes end here
\tbcs end

runcheck:
\tstx $1ffd\t\t// Backup X
\tsep #$30\t\t// Make ACL + registers 8bit
\tsec
\tsbc #$40\t\t// Start charcodes from 0, not 40
\tclc
\tldx $1fff\t\t// Load DTE flagbyte from RAM
\tcpx #$9d\t\t// If this is set, we're at the 2nd char
\tbeq secondchar

firstchar:
\tldx #$9d\t\t// set flag to true
\tdec $0772\t// decrement load_idx
\tasl \t\t\t// dte_num = charcode*2
\tjmp base

secondchar:
\tasl \t\t\t// dte_num = charcode*2
\tclc
\tadc #$01\t\t// select 2nd char of pair
\tldx #$00\t\t// set flag to false

base:
\tstx $1fff\t\t// store flag in RAM
\ttax
\tlda global::dte_table,x\t// load character from DTE table
\trep #$10\t\t// Make registers 16bit
\tldx $1ffd\t\t// Restore X

end:
\trts

Here is what an example of a crash looks like in the trace:
Code:
$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
Guest
« Reply #1 on: July 08, 2011, 07:25:52 pm »

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.
Pages: [1]  


Powered by SMF 1.1.4 | SMF © 2006-2007, Simple Machines LLC