l_oliveira wrote:I've been testing blargg's "DPCM resistant" controller read code and it doesn't help at all with this problem.
If your solution works for the controller issue, it still creates a problem, which is holding up the processor during NMI processing....
Fortunately that problem is of easy solution:
Because the controller read routine and related processing doesn't rely on anything that *MUST* be done during NMI we can move it away from the NMI processing and insert it on the main loop (which is just a jump instruction which jumps on itself) and then we don't waste processor cycles during the NMI processing. To mod it to work that way we would just need to move the "ControllerTest" code to the "InfLoop" routine and remove the JSR instruction which originally called it.
Funny enough, when I did that, the bug manifested itself on FCEUX. Probably means that FCEUX is coded in a way that the the bug simulation code won't trigger if the processor core is doing interrupt processing...
Oh well...
Test case file added (includes asm listing) with controller stuff moved to main loop. Uses blargg's code for controller read. Music change instruction was removed so the music driver don't crash while "the cursor is dancing" ...
I watched your 1st test rom, thanks. That sprite behavior doesn't seem like the DMA bug to me;
more of a case of the sprit data or pointer getting over written. It doesn't affect the NSF playback so its not changing the 'SongNumber' VAR that is passed to the InitMusic routine. Just saw that you commented out "JSR InitMusic" at the end of EndDrawChk:
Should recheck your ControllerTest:
NewButton3 is the first Read; stack holds the second Read; NewBotton2 is the third Read; 'A' then holds the fourth read but you overwrite it from the stack with the second Read.
A> CMP second Read to first Read, and exit to JoyEnd if Equal.
B> If not Equal, CMP second Read to NewButtons (which seems like it's undefined) and exit to JoyEnd if Equal.
C>If not Equal get the third Read (which may or may not match the first two Reads) and drop into JoyEnd and RTS.
Thinking you wanted a four Read test routine, but it is only testing the first two reads and assuming the third Read will be good if the first two fail. The undefined NewButtons is part(all) of the problem. That may solve your sprite/NewSong problem but you will need to restructure to get the four Read testing working, I think. I would also avoid the stack it may be a problem also if other code is using it in the NMI; or Not.
The configuration I'm using with the MMC1 code, has the bulk of the logic in the main loop. It's based on the VegaPlay fork called FamiSlayer v6.66
http://www.heavyw8bit.com/famislayer.php
The NMI routine I use only does a few tests to either call the NSF Frame Play code or let the Main loop do the Frame Play. The choice is based on a Assembler definition 'Sync'. It will never changed at runtime, so could be rewritten with IFDEFs to eliminate the Sync check.
Code: Select all
NMI: ;Extern NMI = NSFroutine + $021F
; Save regs to stk
PHA
TXA
PHA
TYA
PHA
JSR UpdateSprites
LDA StartMode ; Mode CHK: 1=PLAYING OR 0=STOPPED
BEQ NMIexit ; IF STOPPED, We're done
LDA #Sync ; Test Sync option
CMP #$01
BEQ NMIexit ; If Sync = 0, NSFplay via NMI
JSR RamPlay ; go sub to NSF Play vector
NMIexit: ; Restore regs from stk
PLA
TAY
PLA
TAX
PLA
; Fall into IRQ for RTI
IRQ: ;Extern IRQ = NSFroutine + $023A
RTI
Though I had tried another Controller Read routine that had a fixed structure- 'read twice; CMP both; and do again if no match' , it had issues but could have been the surrounding code. Also tried not using the 'RIGHT' button at all, this solved the DMA issue but complicated the UI layout. But it did demonstrate to me that the the DMA bug seems to only affect Bit7. Anyone know for sure?
With the controller read loop I posted, in most cases it will execute twice, but I don't know the max pass count with DMA interference.
It plays all the NSF that had failed before, without the 'false trigger' bug, but I did notice a slight tempo slow down that occurred after 2-5 mins of play time on a file (testing on Nestopia). I'm not convinced of the reason; could have been caused by a Windows' background tasks or some other code issue. Needs more testing but not sure there is a tempo fix, in my case, for NSFs that heavily use the DPCM channel aside from just not using the 'RIGHT' button.
Yogi