issue with ppu drawing vertical tiles (RESOLVED)

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
issue with ppu drawing vertical tiles (RESOLVED)
by on (#215115)
im trying to draw vertical tiles for a score value. my project starts out with $2000ppu having the vram draw with an increment of 1. Now I am able to turn the ppu rendering off, and write anything to any nametable.

now when i want to draw verticaly, the vram engine inside the game recognizes my attempt to change the increment mode of $2000ppu to (8... 84..) #$8C.

It changes and i am able to see the tiles in-game instantnly drawn vertically. However, when it is complete, i will get this millisecond white flash.

My question is, am i writing too much to the vram with the ppu rendering on? Or am i missing additional code to stop that flashing from happening?

Here is the tile data that is loaded, it includes the high/low NT address, the incremet mode with number of tiles, and the tiles.

Code:
206484 00 00 00 00
206584 00 00 00 00
206784 00 00 00 00
206884 00 00 00 00
206A84 00 00 00 00
206B84 00 00 00 00 FF (FF signifies the end of the reading tile data)


This is the code within the vram engine that changes the bits to $2000ppu for 32+ increments

Code:
01:FE61: A5 FF     LDA $FF = #$88
01:FE63: 09 04     ORA #$04
01:FE65: B0 02     BCS $FE69
01:FE67: 29 FB     AND #$FB
01:FE69: 8D 00 20  STA $2000 = #$8C


And this is the code at the beginning of my NMI

Code:
01:C083: AD 02 20  LDA $2002 = #$00
01:C086: A5 FF     LDA $FF = #$8C
01:C088: 29 F8     AND #$F8
01:C08A: 8D 00 20  STA $2000 = #$88
01:C08D: 85 FF     STA $FF = #$88


Now, it seems that if I take away the last vertical string of vram tiles to be drawn in my score, (206B84 00 00 00 00) the screen does not flash or shake after the drawing is completed. I'm worried that I am writing too much to the vram, but I feel that I am not.

Any help would be greatly appreciated! I wanted to do as much troubleshooting on my own as I could before posting here, but ive wasted too much time, and need help. Thanks!
Re: issue with ppu drawing vertical tiles
by on (#215119)
Screen shaking does sound like you run out of vblank time for your updates.
You should be able to upload your amount of data quite comfortably, though.
In your NMI handler, do you do anything before uploading your data? If so, it may push your updates out of Vblank time.
Did you try to upload same amount of data in horizontal line instead of vertical and see if problem is still there?
Also, the data tile you provided seems to not include "the high/low NT address, the incremet mode with number of tiles, and the tiles."
Unless all of these are zeros, which would mean you dont try to upload to NT but to chr instead?
Re: issue with ppu drawing vertical tiles
by on (#215121)
Here is my NMI I put together, (taken from FCEUX debugger) I'm still trying to learn how to have everything setup properly. But so far I've had excellent results with an IRQ, palettes, the vram engine. It's just drawing the amount of vertical lines that is causing an issue. Again I feel i'm not overkilling the drawing routine, so I feel I'm missing something somewhere... And I my previous reply I did include the High/low address values for the Nametable addresses. and increment mode. Example (206484 00 00 00 00 ) 20=HInt, 64=LOnt, 84=bit 8# to signify vertical drawing & #4 bit signifying number of tiles to draw, 00 00 00 00=tiles.

Code:
 01:C000: 48        PHA
 01:C001: 8A        TXA
 01:C002: 48        PHA
 01:C003: 98        TYA
 01:C004: 48        PHA
 01:C005: A9 00     LDA #$00
 01:C007: 8D 03 20  STA $2003 = #$00
 01:C00A: A9 02     LDA #$02
 01:C00C: 8D 14 40  STA $4014 = #$02

 01:C00F: 20 30 FE  JSR $FE30 ;to vram engine
 01:C012: 20 83 C0  JSR $C083 ;AD0220 A5FF 29F8 8D0020 85FF 60

 01:C015: A5 EC     LDA $EC = #$00
 01:C017: 8D 00 C0  STA $C000 = #$48
 01:C01A: 8D 01 C0  STA $C001 = #$8A
 01:C01D: A9 01     LDA #$01
 01:C01F: 8D 01 E0  STA $E001 = #$00
 01:C022: A6 ED     LDX $ED = #$00
 01:C024: BD F0 FE  LDA $FEF0,X @ $FEF0 = #$F6
 01:C027: 85 EE     STA $EE = #$00
 01:C029: BD F1 FE  LDA $FEF1,X @ $FEF1 = #$FE
 01:C02C: 85 EF     STA $EF = #$00
 01:C02E: 58        CLI
 01:C02F: A5 FE     LDA $FE = #$00
 01:C031: 8D 01 20  STA $2001 = #$00
 01:C034: A2 05     LDX #$05
 01:C036: 8E 00 80  STX $8000 = #$4C
 01:C039: B5 F0     LDA $F0,X @ $00F0 = #$00
 01:C03B: 8D 01 80  STA $8001 = #$6C
 01:C03E: CA        DEX
 01:C03F: 10 F5     BPL $C036
 01:C041: A2 00     LDX #$00
 01:C043: AD 02 20  LDA $2002 = #$88
 01:C046: A9 3F     LDA #$3F
 01:C048: 8D 06 20  STA $2006 = #$00
 01:C04B: 8E 06 20  STX $2006 = #$00
 01:C04E: A0 20     LDY #$20
 01:C050: BD C0 06  LDA $06C0,X @ $06C0 = #$00
 01:C053: 8D 07 20  STA $2007 = #$00
 01:C056: E8        INX
 01:C057: 88        DEY
 01:C058: D0 F6     BNE $C050
 01:C05A: A9 3F     LDA #$3F
 01:C05C: 8D 06 20  STA $2006 = #$00
 01:C05F: 8C 06 20  STY $2006 = #$00
 01:C062: 8C 06 20  STY $2006 = #$00
 01:C065: 8C 06 20  STY $2006 = #$00
 01:C068: A5 FD     LDA $FD = #$00
 01:C06A: 8D 05 20  STA $2005 = #$00
 01:C06D: A5 FC     LDA $FC = #$00
 01:C06F: 8D 05 20  STA $2005 = #$00
 01:C072: 20 90 C0  JSR $C090        ;game code
 01:C075: E6 F6     INC $F6 = #$00  ;frame counter
 01:C077: 20 8E FF  JSR $FF8E        ;joypad code
 01:C07A: 20 00 80  JSR $8000       ;sound engine
 01:C07D: 68        PLA
 01:C07E: A8        TAY
 01:C07F: 68        PLA
 01:C080: AA        TAX
 01:C081: 68        PLA
 01:C082: 40        RTI
Re: issue with ppu drawing vertical tiles
by on (#215124)
instead of all of this
Code:
01:C05A: A9 3F     LDA #$3F
 01:C05C: 8D 06 20  STA $2006 = #$00
 01:C05F: 8C 06 20  STY $2006 = #$00
 01:C062: 8C 06 20  STY $2006 = #$00
 01:C065: 8C 06 20  STY $2006 = #$00
 01:C068: A5 FD     LDA $FD = #$00
 01:C06A: 8D 05 20  STA $2005 = #$00
 01:C06D: A5 FC     LDA $FC = #$00
 01:C06F: 8D 05 20  STA $2005 = #$00

try this:
Code:
lda WhateverValueYouWantFor2000;Selects the nametable with the lowest two bits
sta $2000;I'm dumb, I forgot this and had to edit it in.
lda $FD
sta $2005
lda $FC
sta $2005

The short, simple version:
When you write to $2005, $2006, and $2000, internal PPU scroll bits are affected. $2006 can affect the nametable bits that were written previously to $2000. So you should write $2000 after all your $2006 writes are done. After your write to $2000, you write the X value for scroll to $2005, then you write the Y value for scroll to $2005. Nothing else is needed. (In your NMI, at the top of the screen.)

If you want to do freaky midscreen stuff, you write to $2006, $2005, $2005, $2006 in order. The four writes you have to $2006 with the two to $2005 seems like a lot of extra stuff.

Edit: Here's the wiki page that explains all of that, and more: https://wiki.nesdev.com/w/index.php/PPU_scrolling
But don't let it confuse you. For the top of the screen, all you need is a write to $2000, and two writes to $2005.

Edit2: For what it's worth, you actually don't need to guess about whether or not your NMI is running out of time. NintendulatorDX has timers. At the start of your NMI you can do sta $4020, and after the write to $2005 I suggested you can do sta $4030 and it will tell you in the debugger (debug, disassembly, timers) how many cycles your NMI ran for. If it's close to around ~2270, you're out of time. Otherwise, it's something else. We can't really tell from what you posted. Those jsr instructions could go to very slow subroutines.
Re: issue with ppu drawing vertical tiles
by on (#215127)
yeah I'm now pretty confused after reading that. I thought vram was supposed to be done early in the NMI? The vram engine I jsr to, performs the bit change to $2000, to allow the vertical drawing. So i'm guessing I should reshift how my NMI is arranged? Your example confused me too, you talk about write anything to $2000, then my writes to $2005 twice. So am I to do, load value, store to $2000, load x, store to $2005, load y, store to $2005?

I tried reading that wiki yesterday and it's very complex, so i'm doing the best I can, any additional help would be great, thanks!

EDIT: I came really close by removing/editing certain writes to $2006, but then rebooting caused my screen to be grayed out. But the flashing stopped during my vertical tile writes...
Re: issue with ppu drawing vertical tiles
by on (#215129)
Quote:
I thought vram was supposed to be done early in the NMI?

It is! And nothing I said changes that. You have ~2270 cycles to do all your writes to $2006, $2007, $2005, and $2000 if you want everything done before the screen starts rendering.
Quote:
So am I to do, load value, store to $2000, load x, store to $2005, load y, store to $2005?

Exactly. And this needs to be done after all your other $2006/$2007 writes, because $2006 affects the scroll too. (In a way that's harder to understand and control.)
Quote:
So am I to do, load value, store to $2000, load x, store to $2005, load y, store to $2005?

That's exactly right. And I'm totally dumb, and forgot the sta $2000 in my code example and edited it in just now. But it really should be as simple as those three scroll writes ($2000, $2005, $2005) after all your other VRAM updates are done.

Still, use Nintendulator DX and time your code. Even if what I suggest works, it's still good to know how close you are to the limit.
Re: issue with ppu drawing vertical tiles (RESOLVED)
by on (#215131)
Ok thanks for all your help, i'll give this another shot. :-)

EDIT: GOT IT! :-D

So I reshifted and rewrote certain portions as you suggested. I have no more glitches, no more flashes, or faint screen jumps when drawing vertically! Here is my new NMI structure.

Code:
 01:C000: 48        PHA
 01:C001: 8A        TXA
 01:C002: 48        PHA
 01:C003: 98        TYA
 01:C004: 48        PHA
 01:C005: A9 00     LDA #$00
 01:C007: 8D 03 20  STA $2003 = #$00
 01:C00A: A9 02     LDA #$02
 01:C00C: 8D 14 40  STA $4014 = #$02

 ;palette engine
 01:C00F: A2 00     LDX #$00
 01:C011: AD 02 20  LDA $2002 = #$88
 01:C014: A9 3F     LDA #$3F
 01:C016: 8D 06 20  STA $2006 = #$00
 01:C019: 8E 06 20  STX $2006 = #$00
 01:C01C: A0 20     LDY #$20
 01:C01E: BD C0 06  LDA $06C0,X @ $06C0 = #$00
 01:C021: 8D 07 20  STA $2007 = #$00
 01:C024: E8        INX
 01:C025: 88        DEY
 01:C026: D0 F6     BNE $C01E

 ;jsr to vram engine
 01:C028: 20 30 FE  JSR $FE30

 ;final writes to $2000 & $2005
 01:C02B: A5 FF     LDA $FF = #$88
 01:C02D: 29 F8     AND #$F8
 01:C02F: 8D 00 20  STA $2000 = #$88
 01:C032: 85 FF     STA $FF = #$88
 01:C034: A5 FD     LDA $FD = #$00
 01:C036: 8D 05 20  STA $2005 = #$00
 01:C039: A5 FC     LDA $FC = #$00
 01:C03B: 8D 05 20  STA $2005 = #$00

 ;mmc3 irq routine
 01:C03E: A5 EC     LDA $EC = #$00
 01:C040: 8D 00 C0  STA $C000 = #$48
 01:C043: 8D 01 C0  STA $C001 = #$8A
 01:C046: A9 01     LDA #$01
 01:C048: 8D 01 E0  STA $E001 = #$00
 01:C04B: A6 ED     LDX $ED = #$00
 01:C04D: BD F0 FE  LDA $FEF0,X @ $FEF0 = #$F6
 01:C050: 85 EE     STA $EE = #$00
 01:C052: BD F1 FE  LDA $FEF1,X @ $FEF1 = #$FE
 01:C055: 85 EF     STA $EF = #$00
 01:C057: 58        CLI
 
 ;ppu rendering
 01:C058: A5 FE     LDA $FE = #$00
 01:C05A: 8D 01 20  STA $2001 = #$00
 
 ;mmc3 chr setup
 01:C05D: A2 05     LDX #$05
 01:C05F: 8E 00 80  STX $8000 = #$4C
 01:C062: B5 F0     LDA $F0,X @ $00F0 = #$00
 01:C064: 8D 01 80  STA $8001 = #$6C
 01:C067: CA        DEX
 01:C068: 10 F5     BPL $C05F
 
 ;game code
 01:C06A: 20 90 C0  JSR $C090
 
 ;frame counter
 01:C06D: E6 F6     INC $F6 = #$00
 
 ;joypad routine
 01:C06F: 20 8E FF  JSR $FF8E

 ;sound engine
 01:C072: 20 00 80  JSR $8000
 
 01:C075: 68        PLA
 01:C076: A8        TAY
 01:C077: 68        PLA
 01:C078: AA        TAX
 01:C079: 68        PLA
 01:C07A: 40        RTI
Re: issue with ppu drawing vertical tiles
by on (#215133)
Congrats! One thing! You should write to $2000 here too:
Code:
 01:C00F: A2 00     LDX #$00
 01:C011: AD 02 20  LDA $2002 = #$88

;Here.

 01:C014: A9 3F     LDA #$3F
 01:C016: 8D 06 20  STA $2006 = #$00
 01:C019: 8E 06 20  STX $2006 = #$00
 01:C01C: A0 20     LDY #$20
 01:C01E: BD C0 06  LDA $06C0,X @ $06C0 = #$00
 01:C021: 8D 07 20  STA $2007 = #$00
 01:C024: E8        INX
 01:C025: 88        DEY
 01:C026: D0 F6     BNE $C01E

$2000 controls the nametables, yes. But it also controls the increment value, as you know. Your NMI starts, and you write to $2007 without specifying the increment value beforehand in the new version. So it's technically relying on whatever the last value written to it was. (Yes, you still need ANOTHER $2000 write at the end, only for scrolling)
Re: issue with ppu drawing vertical tiles (RESOLVED)
by on (#215135)
Oh ok, I'll add

Code:
LDA $FF
STA $2000


This is good enough, right? :-)
Re: issue with ppu drawing vertical tiles (RESOLVED)
by on (#215136)
How about...
Code:
LDA $FF
and #%11111011
STA $2000

otherwise you're still relying on the last written value. The above guarantees you're at increment 1, which is what is required for those palette writes.
Re: issue with ppu drawing vertical tiles (RESOLVED)
by on (#215137)
Ok, so...

Code:
 01:C00F: A2 00     LDX #$00
 01:C011: AD 02 20  LDA $2002 = #$00
 01:C014: A5 FF     LDA $FF = #$88
 01:C016: 29 FB     AND #$FB
 01:C018: 8D 00 20  STA $2000 = #$88
 01:C01B: A9 3F     LDA #$3F
 01:C01D: 8D 06 20  STA $2006 = #$00
 01:C020: 8E 06 20  STX $2006 = #$00
 01:C023: A0 20     LDY #$20
 01:C025: BD C0 06  LDA $06C0,X @ $06C0 = #$0F
 01:C028: 8D 07 20  STA $2007 = #$00
 01:C02B: E8        INX
 01:C02C: 88        DEY
 01:C02D: D0 F6     BNE $C025
Re: issue with ppu drawing vertical tiles (RESOLVED)
by on (#215138)
Yes, that's safe.
Re: issue with ppu drawing vertical tiles (RESOLVED)
by on (#215140)
Thank you for all of your help! Now i'm back on track. :-)