News:

11 March 2016 - Forum Rules

Main Menu

Soul Blazer input lag

Started by Gideon Zhi, June 20, 2014, 04:35:13 PM

Previous topic - Next topic

Gideon Zhi

Hi guys, I had a few minutes during lunch today and I figured I'd look into why Soul Blazer has some very noticeable input lag. It's especially noticeable if you try to use the sword strafe while also walking (L/R) and infects just about all aspects of the game's control. Brief examination of the game's code yielded this as being unique to the sword strafe on L:


$00/9D7C: 20 9D 9F     JSR $9F9D [$00:9F9D]      A:0002 X:0800 Y:0800 D:0000 DB:01 S:1FF1 P:envmxdIzc HC:138 VC:253
$00/9D7F: 02 80        COP #$80                  A:0000 X:0800 Y:0A00 D:0000 DB:01 S:1FF1 P:envmxdIZc HC:876 VC:253
$00/9D82: 02 82        COP #$82                  A:9D82 X:0800 Y:0800 D:0000 DB:01 S:1FF1 P:envmxdIZc HC:696 VC:254


A quick glance at 65816info.txt yields COP as "Coprocessor Empowerement." Loads a hardware vector from the cart header. Wait, what? Soul Blazer doesn't have any extra hardware - no DSP or SA-1 or anything like that. What the hell is going on here?

Revenant

#1
The COP opcode just triggers a software interrupt exactly like BRK does, and they're both treated as two-byte instructions. The second byte can be (and sometimes is, though not commonly on the NES/SNES) used as an actual operand; in this case, the interrupt handler uses it as an index into a jump table:

COP #$80 in Soul Blazer does this (I omitted a few instructions at the beginning):

$00/D627 A3 02       LDA $02,s  [$00:1FEF]   A:0000 X:0800 Y:0800 D:0000 DB:01 S:1FED P:envmxdIZc HC:0674 VC:000 FC:38 I:00
$00/D629 3A          DEC A                   A:9D71 X:0800 Y:0800 D:0000 DB:01 S:1FED P:eNvmxdIzc HC:0728 VC:000 FC:38 I:00
$00/D62A 85 38       STA $38    [$00:0038]   A:9D70 X:0800 Y:0800 D:0000 DB:01 S:1FED P:eNvmxdIzc HC:0758 VC:000 FC:38 I:00
$00/D62C A7 38       LDA [$38]  [$00:9D70]   A:9D70 X:0800 Y:0800 D:0000 DB:01 S:1FED P:eNvmxdIzc HC:0830 VC:000 FC:38 I:00
$00/D62E E6 38       INC $38    [$00:0038]   A:2980 X:0800 Y:0800 D:0000 DB:01 S:1FED P:envmxdIzc HC:0926 VC:000 FC:38 I:00
$00/D630 29 FF 00    AND #$00FF              A:2980 X:0800 Y:0800 D:0000 DB:01 S:1FED P:eNvmxdIzc HC:0996 VC:000 FC:38 I:00
$00/D633 0A          ASL A                   A:0080 X:0800 Y:0800 D:0000 DB:01 S:1FED P:envmxdIzc HC:1036 VC:000 FC:38 I:00
$00/D634 AA          TAX                     A:0100 X:0800 Y:0800 D:0000 DB:01 S:1FED P:envmxdIzc HC:1066 VC:000 FC:38 I:00
$00/D635 7C 38 D6    JMP ($D638,x)[$00:DE7A] A:0100 X:0100 Y:0800 D:0000 DB:01 S:1FED P:envmxdIzc HC:1096 VC:000 FC:38 I:00


So it's basically just a "syscall" sort of deal (like the x86 "int" instruction), but for the SNES :P

Gideon Zhi

Alright, that makes sense. Slightly boggled by the whole "coprocessor empowerement" thing; I'd never seen COP before today and only had a few minutes in which to digest the code. I'll dig a bit further into this, but the input lag is something I'd really like to see fixed (if the possibility of an easy fix exists, anyway.)

Vehek

Terranigma does that too, where events are assembly mixed with event commands called by COP. If Soul Blazer's doing the same thing, then you're looking at event code.