CDC DMA failing on Kega Fusion?
Posted: Tue Oct 04, 2016 10:21 pm
Hello. We learn a lot thanks to Luke's ProjectCD, and now have been trying to go fancy on the optimizations, such as running the engine from SubCPU and similar. We're currently on the tedious task of adapting the previously edited ReadCD to use DMA and its expanded bandwidth. So far it appear to work just fine on edited Genesis Plus GX, Gens, and many other emulators, all BUT Kega Fusion. Being unable to, or having no strategy to properly debug whatever happen to be going on this emulator, what can we do to find the cause and/or fix this issue?
The freeze appear to on this location as if CDC status were never "ready":
Here is the full code for reference; previously it was pretty much the same to SoullessSentinel/Luke's ProjectCD, with a few adds (++) to properly "load" some files' uneven file size:
The freeze appear to on this location as if CDC status were never "ready":
Code: Select all
.waitSTAT:
BIOS_CDCSTAT ; Check CDC status
bcs.s .waitSTAT ; If not ready, branch
Code: Select all
; Set DMA to PRG-RAM
move.b #5,(CDC_Mode).w
; Load Volume VolumeDescriptor
moveq #$10,d0 ; Start Sector
move.l #2*$800,d1 ; Read 2 sectors
move.w #FileSysBuffer/8,(CDC_DMA_Adr).w ; Destination
bsr.w ReadCD ; Read Data
; (...)
ReadSector: macro
.waitSTAT:
BIOS_CDCSTAT ; Check CDC status
bcs.s .waitSTAT ; If not ready, branch
.waitREAD:
BIOS_CDCREAD ; Read data
bcs.s .waitREAD ; If not done, branch
BIOS_CDCACK ; Acknowledge transfer
endm
ReadCD:
pushr d0-d7/a0-a6 ; Store all registers
move.l d1,d6 ; ++
lsr.l #8,d1 ; ++ '' Bitshift filesize (to get sector count)
lsr.l #3,d1 ; ++ ''
andi.l #$7FF,d6 ; ++ D6 will contain the size of "incomplete" sector
lea BiosPacket(pc),a5 ; Load bios packet
move.l d0,(a5) ; Write start sector to packet
move.l d1,4(a5) ; Write size to packet
movea.l a5,a0 ; Put packet to a0 (for BIOS)
tst.l d1 ; ++ Is there any "complete" sector needing to be read?
beq.s RCD_ByteSpecificTransfer ; ++ If not, branch
BIOS_CDCSTOP ; Stop CDC
BIOS_ROMREADN ; Begin data read
RCD_SectorReadLoop:
ReadSector
addq.l #1, (a5) ; Increment starting sector
addi.l #$0800,8(a5) ; Increment destination address
subq.l #1,4(a5) ; Decrement sectors left
bne.s RCD_SectorReadLoop ; If not finished, branch
tst.l d6 ; ++ Is there any "incomplete" sector needing to be read?
beq.w RCD_Return ; ++ If not, branch
RCD_ByteSpecificTransfer: ; ++
move.l #1,4(a5)
move.l 8(a5),d7
move.l #SectorBuffer,8(a5)
; For some reason (maybe timing?) we need to
; re-setup the reader
movea.l a5,a0 ; Put packet to a0 (for BIOS)
BIOS_CDCSTOP ; Stop CDC
BIOS_ROMREADN ; Begin data read
ReadSector
clr.l 4(a5)
RCD_Return:
popr d0-d7/a0-a6 ; Restore all registers
rts ; Return