Meh, I figured it out. For I have the dark powers necessary to read pages and pages of virtually commentless assembler code written for multiple processors ;)grinvader wrote:zvoodoo in all its awesome.
Resistance is futile.
Here are my findings:
Code: Select all
DeJap Star Ocean disassembly:
cc2428 lda #$5008
cc242b pea $00e9
cc242e ldx #$0400
cc2431 ldy #$04e0
cc2434 jsr $244c
cc244c sta $2116
cc244f sep #$20
cc2451 stz $4800
cc2454 lda #$01
cc2456 bra $247c
cc247c sta $4300 ;*1
cc247f lda #$18
cc2481 sta $4301
cc2484 stx $4302
cc2487 lda $03,s
cc2489 sta $4304
cc248c sty $4305
cc248f lda #$01
cc2491 sta $4801 ;*2
cc2494 pha
cc2495 pla
cc2496 sta $420b ;*3
cc2499 stz $4800
*1:
https://zsnes.bountysource.com/svn/!source/5112/trunk/src/cpu/regsw.inc
calls reg43X0w
does not do anything but save value to temporary memory variable, to be used
later.
*2:
https://zsnes.bountysource.com/svn/!source/5112/trunk/src/chips/sa1regs.asm
calls sdd14801w
value written is not zero, so AddrNoIncr is cleared by this function.
sets up banks $c0-$ff to read bytes from memaccessbankr8sdd1, which allows
S-DD1 decompression when certain conditions are met.
note:
AddrNoIncr appears to be set to 0 when fixed address transfers are *disabled*.
Thusly, AddrNoIncr is set to 1 when fixed address transfers are *enabled*.
fairly self-explanatory, but just in case ...
*3:
https://zsnes.bountysource.com/svn/!source/5112/trunk/src/cpu/dma.asm
calls reg420Bw, which calls transdma
transdma reads $43x0, which in our case here, clears AddrNoIncr
now, DMA begins and uses
https://zsnes.bountysource.com/svn/!source/5112/trunk/src/cpu/memory.asm
memaccessbankr8sdd1
this function tests AddrNoIncr, and sees that the value is zero and then
jumps to .failed, which calls memaccessbankr8, or the standard read function.
this basically bypasses decompression entirely.
notes:
ZSNES' setup is to basically map banks $c0-$ff to an S-DD1 custom memory reader
function. it then expects to only transfer data when the fixed DMA transfer flag
is set, so it intentionally keeps this flag clear except when transmitting DMA
data. however, the same memory read function is called both for normal memory
accesses, as well as for DMA. it appears to be a clever trick to bypass the
overhead of having to test during DMA if a transfer should use the S-DD1
decompression routine, even when games do not have S-DD1 chips.
findings:
1:
it appears that ZSNES does not update the AddrNoIncr flag when writing to $43x0.
instead, ZSNES loads this value upon writing to $420b.
this is unlikely to be the case for real hardware, but is technically possible.
this action would be completely transparent outside of S-DD1 support. it looks to
be more a workaround for ZSNES' unique setup, as setting the value inside $43x0
would enable S-DD1 decompression during standard code reads ... something that is
definitely not possible and would likely immediately crash a game.
2:
writes that set any bits at all in $4801 will clear the AddrNoIncr flag.
this is definitely not the case on real hardware, the S-DD1 cannot interfere with
SNES hardware to control how transfers occur.
it does this so that memaccesssbankr8sdd1 will not start decompressing data
immediately. S-DD1 only decompresses on DMA, so you definitely don't want it
decompressing on standard reads (which could be just the S-CPU executing code from
banks $c0-$ff).
only DMA transfer routine (after $420b write) sets AddrNoIncr to 1.
3:
it is unlikely that the S-DD1 monitors all writes to $43x0 registers (and possibly
to $420b as well) to know whether or not the transfer is set for fixed addressing or
not.
the S-DD1 has no reason to care about whether or not fixed address transferring is
enabled, as it has no interface with S-CPU's DMA unit and its' registers.
the S-DD1 simply intercepts reads from the cartridge ROM and returns decompressed
bytes. therefore, the S-DD1 has its' own internal address transfer position.
further, if one were to attempt to transfer without S-DD1 decompression, it would
make the most sense to simply not set the S-DD1 enable flag bit in $4801 for said
channel.
conclusions:
it appears that clearing the fixed transfer flag in a DMA transfer with $4801 set
not decompressing is merely a side effect of ZSNES' very unique speed-sensitive
considerations, and does not appear to be consistent with what actual hardware
would do.
it is my educated, researched opinion that the issue is in both DeJap's translation,
and in ZSNES' S-DD1 implementation, that the title screen graphic appears corrupt,
and that it is not a bug in other emulators -- I believe other emulators are working
as the Star Ocean translation would on real hardware.
however, I have to reiterate once again, we don't have access to the real hardware
to definitively rule this out. therefore, we can only make educated guesses, which
is what this is.
If anyone wants to bring this issue up to me or the SNES9x team, please present actual hardware evidence of your claims. Do not claim it's a bug simply because it does not display correctly, unless you can test the game on actual hardware, using a real S-DD1 chip to do so.