+  RHDN Forum Archive
|-+  Romhacking
| |-+  ROM Hacking Discussion
| | |-+  SNES Vblank detection not working.
Pages: [1]
Author Topic: SNES Vblank detection not working.  (Read 2 times)
KingMike
Guest
« on: September 24, 2009, 02:35:01 pm »

Now, I recall byuu saying that
Code:
-:
 lda $4212 : bmi -
+:
 lda $4212 : bpl +
was all that was needed to ensure successful writes to VRAM.
Well, that seems to crash the game here (original NMI):
Code:
$E8/2272 AD 12 42    LDA $4212  [$7E:4212]   A:008A X:0055 Y:0000 D:0000 DB:7E S:01D8 P:eNvMxdIzcHC:0004 VC:225 00 FL:63182
$E8/2275 30 FB       BMI $FB    [$2272]      A:008A X:0055 Y:0000 D:0000 DB:7E S:01D8 P:eNvMxdIzcHC:0030 VC:225 00 FL:63182
$E8/2272 AD 12 42    LDA $4212  [$7E:4212]   A:008A X:0055 Y:0000 D:0000 DB:7E S:01D8 P:eNvMxdIzcHC:0048 VC:225 00 FL:63182
$00/81EB 18          CLC                     A:008A X:0055 Y:0000 D:0000 DB:7E S:01D4 P:eNvMxdIzcHC:0134 VC:225 00 FL:63182
$00/81EC FB          XCE                     A:008A X:0055 Y:0000 D:0000 DB:7E S:01D4 P:eNvMxdIzcHC:0148 VC:225 00 FL:63182
$00/81ED C2 30       REP #$30                A:008A X:0055 Y:0000 D:0000 DB:7E S:01D4 P:eNvMxdIzcHC:0162 VC:225 00 FL:63182
$00/81EF 5C F3 81 C0 JMP $C081F3[$C0:81F3]   A:008A X:0055 Y:0000 D:0000 DB:7E S:01D4 P:eNvmxdIzcHC:0184 VC:225 00 FL:63182
$C0/81F3 C2 30       REP #$30                A:008A X:0055 Y:0000 D:0000 DB:7E S:01D4 P:eNvmxdIzcHC:0216 VC:225 00 FL:63182
$C0/81F5 08          PHP                     A:008A X:0055 Y:0000 D:0000 DB:7E S:01D4 P:eNvmxdIzcHC:0234 VC:225 00 FL:63182
$C0/81F6 48          PHA                     A:008A X:0055 Y:0000 D:0000 DB:7E S:01D3 P:eNvmxdIzcHC:0254 VC:225 00 FL:63182
$C0/81F7 DA          PHX                     A:008A X:0055 Y:0000 D:0000 DB:7E S:01D1 P:eNvmxdIzcHC:0282 VC:225 00 FL:63182
$C0/81F8 5A          PHY                     A:008A X:0055 Y:0000 D:0000 DB:7E S:01CF P:eNvmxdIzcHC:0310 VC:225 00 FL:63182
$C0/81F9 0B          PHD                     A:008A X:0055 Y:0000 D:0000 DB:7E S:01CD P:eNvmxdIzcHC:0338 VC:225 00 FL:63182
$C0/81FA 8B          PHB                     A:008A X:0055 Y:0000 D:0000 DB:7E S:01CB P:eNvmxdIzcHC:0366 VC:225 00 FL:63182
$C0/81FB E2 20       SEP #$20                A:008A X:0055 Y:0000 D:0000 DB:7E S:01CA P:eNvmxdIzcHC:0386 VC:225 00 FL:63182
$C0/81FD A9 00       LDA #$00                A:008A X:0055 Y:0000 D:0000 DB:7E S:01CA P:eNvMxdIzcHC:0404 VC:225 00 FL:63182
$C0/81FF 48          PHA                     A:0000 X:0055 Y:0000 D:0000 DB:7E S:01CA P:envMxdIZcHC:0416 VC:225 00 FL:63182
$C0/8200 AB          PLB                     A:0000 X:0055 Y:0000 D:0000 DB:7E S:01C9 P:envMxdIZcHC:0436 VC:225 00 FL:63182
$C0/8201 C2 20       REP #$20                A:0000 X:0055 Y:0000 D:0000 DB:00 S:01CA P:envMxdIZcHC:0462 VC:225 00 FL:63182
$C0/8203 A9 00 00    LDA #$0000              A:0000 X:0055 Y:0000 D:0000 DB:00 S:01CA P:envmxdIZcHC:0480 VC:225 00 FL:63182
$C0/8206 5B          TCD                     A:0000 X:0055 Y:0000 D:0000 DB:00 S:01CA P:envmxdIZcHC:0498 VC:225 00 FL:63182
$C0/8207 E2 30       SEP #$30                A:0000 X:0055 Y:0000 D:0000 DB:00 S:01CA P:envmxdIZcHC:0510 VC:225 00 FL:63182
$C0/8209 AD 10 42    LDA $4210  [$00:4210]   A:0000 X:0055 Y:0000 D:0000 DB:00 S:01CA P:envMXdIZcHC:0528 VC:225 00 FL:63182
$C0/820C A5 C4       LDA $C4    [$00:00C4]   A:00C2 X:0055 Y:0000 D:0000 DB:00 S:01CA P:eNvMXdIzcHC:0552 VC:225 00 FL:63182
$C0/820E F0 03       BEQ $03    [$8213]      A:0001 X:0055 Y:0000 D:0000 DB:00 S:01CA P:envMXdIzcHC:0572 VC:225 00 FL:63182
$C0/8210 4C DA 82    JMP $82DA  [$00:82DA]   A:0001 X:0055 Y:0000 D:0000 DB:00 S:01CA P:envMXdIzcHC:0584 VC:225 00 FL:63182
$C0/82DA C2 30       REP #$30                A:0001 X:0055 Y:0000 D:0000 DB:00 S:01CA P:envMXdIzcHC:0602 VC:225 00 FL:63182
$C0/82DC E2 20       SEP #$20                A:0001 X:0055 Y:0000 D:0000 DB:00 S:01CA P:envmxdIzcHC:0620 VC:225 00 FL:63182
$C0/82DE A5 C4       LDA $C4    [$00:00C4]   A:0001 X:0055 Y:0000 D:0000 DB:00 S:01CA P:envMxdIzcHC:0638 VC:225 00 FL:63182
$C0/82E0 1A          INC A                   A:0001 X:0055 Y:0000 D:0000 DB:00 S:01CA P:envMxdIzcHC:0658 VC:225 00 FL:63182
$C0/82E1 A9 01       LDA #$01                A:0002 X:0055 Y:0000 D:0000 DB:00 S:01CA P:envMxdIzcHC:0670 VC:225 00 FL:63182
$C0/82E3 85 C4       STA $C4    [$00:00C4]   A:0001 X:0055 Y:0000 D:0000 DB:00 S:01CA P:envMxdIzcHC:0682 VC:225 00 FL:63182
$C0/82E5 C2 20       REP #$20                A:0001 X:0055 Y:0000 D:0000 DB:00 S:01CA P:envMxdIzcHC:0702 VC:225 00 FL:63182
$C0/82E7 AB          PLB                     A:0001 X:0055 Y:0000 D:0000 DB:00 S:01CA P:envmxdIzcHC:0720 VC:225 00 FL:63182
$C0/82E8 2B          PLD                     A:0001 X:0055 Y:0000 D:0000 DB:7E S:01CB P:envmxdIzcHC:0746 VC:225 00 FL:63182
$C0/82E9 7A          PLY                     A:0001 X:0055 Y:0000 D:0000 DB:7E S:01CD P:envmxdIZcHC:0780 VC:225 00 FL:63182
$C0/82EA FA          PLX                     A:0001 X:0055 Y:0000 D:0000 DB:7E S:01CF P:envmxdIZcHC:0814 VC:225 00 FL:63182
$C0/82EB 68          PLA                     A:0001 X:0055 Y:0000 D:0000 DB:7E S:01D1 P:envmxdIzcHC:0848 VC:225 00 FL:63182
$C0/82EC 28          PLP                     A:008A X:0055 Y:0000 D:0000 DB:7E S:01D3 P:envmxdIzcHC:0882 VC:225 00 FL:63182
$C0/82ED 40          RTI                     A:008A X:0055 Y:0000 D:0000 DB:7E S:01D4 P:eNvmxdIzcHC:0908 VC:225 00 FL:63182
$E8/2275 30 FB       BMI $FB    [$2272]      A:008A X:0055 Y:0000 D:0000 DB:7E S:01D8 P:eNvMxdIzcHC:0958 VC:225 00 FL:63182
$E8/2272 AD 12 42    LDA $4212  [$7E:4212]   A:008A X:0055 Y:0000 D:0000 DB:7E S:01D8 P:eNvMxdIzcHC:0976 VC:225 00 FL:63182
$E8/2275 30 FB       BMI $FB    [$2272]      A:008A X:0055 Y:0000 D:0000 DB:7E S:01D8 P:eNvMxdIzcHC:1002 VC:225 00 FL:63182
Any ideas?
MathOnNapkins
Guest
« Reply #1 on: September 24, 2009, 03:51:02 pm »

Hrm.... well....

Code: (anomie's register doc)
4212 r b++++ HVBJOY - PPU Status
        vh-----a

        v    = V-Blank Flag. If we're currently in V-Blank, this flag is set,
            otherwise it is clear. The setting seems to occur at H Counter
            about $16-$17 when V Counter is $E1, and the clearing at about $1E
            with V Counter 0.

(rest omitted)

The purpose of the first loop is to wait until current V-blank ends, if your code happens to already be in the middle of one. The second loop waits until the next V-blank occurs. That said, if you really need to write to VRAM, I believe "When in Rome, do as the Romans do" applies here. I would much rather tack any VRAM writes I have to do onto the existing NMI routine than do them independently, b/c there's no telling when NMI will kick in and potentially screw with your code that is doing VRAM writes.

Byuu's code seems to be for use in a game that doesn't have the NMI interrupt enabled, but I could be wrong about that.
tomaitheous
Guest
« Reply #2 on: September 24, 2009, 10:51:42 pm »

 I would assume polling the status reg/port like that can cause the vblank interrupt (NMI) to miss under some conditions. It's best to have a status variable updated by the vblank int call, and poll that from the main code or code outside the interrupt. But like MathOnNapkins stated, maybe your game doesn't use interrupt call and in that case polling the port directly would be fine. Or you could buffer your writes/data/whatever and do a small hook in the vblank interrupt routine to copy said tiles/map/data to vram based on flag/variable system.
KingMike
Guest
« Reply #3 on: September 24, 2009, 11:31:49 pm »

I realize the problem.
I forgot to check DB. Tongue
Corrected by remembering to use long addressing to check registers.
Now I can get to work fixing the rest of the bugs in my code.
MathOnNapkins
Guest
« Reply #4 on: September 25, 2009, 08:48:18 am »

Damn.... always the small things, isn't it?
tomaitheous
Guest
« Reply #5 on: September 25, 2009, 09:10:08 pm »

Quote from: KingMike on September 24, 2009, 11:31:49 pm
I realize the problem.
I forgot to check DB. Tongue
Corrected by remembering to use long addressing to check registers.
Now I can get to work fixing the rest of the bugs in my code.

 You still shouldn't poll the port if an interrupt depends (enabled) on that status bit (assuming reading it clears the flag from being held for the interrupt). Might work fine in emulator, but not 100% on the real system. Might want to check further into this.
Nightcrawler
Guest
« Reply #6 on: September 28, 2009, 08:43:41 am »

The $4212 vblank status bit (as well as the others in that register) is not cleared on read. There should be no issue with polling it.
Pages: [1]  


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