It is currently Sat Sep 21, 2019 7:17 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 27 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Fri Jan 25, 2019 8:44 am 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 2312
Location: Fukuoka, Japan
After asking questions to Vectrex28 on twitter about how he was changing palette mid-screen, I learned that it was done during hblank (which I already had a doubt about it) and that he was disabling the ppu while doing so.

My question is, my assumption was that the PPU was disabled to some degree since it's in hblank, so what does happens when doing so? What is affected when disabling the PPU in hblank? I was able to change some color when keeping the PPU active but it seems more stable when deactivating it.

I don't remember reading anything about it so it must be something I missed on the subject.


Top
 Profile  
 
PostPosted: Fri Jan 25, 2019 10:56 am 
Online

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8568
Location: Seattle
Banshaku wrote:
My question is, my assumption was that the PPU was disabled to some degree since it's in hblank, so what does happens when doing so?
Not really disabled. The only real thing is that the PPU is not sending pixels to the screen, but it's still 100% busy internally.

Every two pixels it reads some value from the PPU's address bus. Every pixel it does something to OAM.

Quote:
What is affected when disabling the PPU in hblank? I was able to change some color when keeping the PPU active but it seems more stable when deactivating it.
... I thought you couldn't successfully write to the PPU's memories without being in vertical or forced blanking.

Certainly for normal writes to OAM or not-palette space will cause a condition where both /WR and /RD are true at the same time. Visual2C02 implies writes to the palette don't happen at all during hblanking if rendering is still enabled.


Last edited by lidnariq on Fri Jan 25, 2019 12:46 pm, edited 2 times in total.

Top
 Profile  
 
PostPosted: Fri Jan 25, 2019 11:49 am 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 2564
Location: DIGDUG
Quote:
I thought you couldn't successfully write to the PPU's memories without being in vertical or forced blanking.


When I tested this, there was a huge difference between trying it in an emulator and on a real NES. It only seems to work fine in emulators, if perfectly timed, but fails on hardware.

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
PostPosted: Fri Jan 25, 2019 12:04 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7582
Location: Canada
lidnariq wrote:
Not really disabled. The only real thing is that the PPU is not sending pixels to the screen, but it's still 100% busy internally.

I think there's an important distinction that it's not going to increment the address while it's disabled, though.

lidnariq wrote:
Certainly for normal writes to OAM or not-palette space will cause a condition where both /WR and /RD are true at the same time. Visual2C02 implies writes to the palette don't happen at all during hblanking.

I don't understand this statement. How is this ROM I wrote able to change palette during the horizontal blank?
http://forums.nesdev.com/viewtopic.php?f=3&t=13264


Top
 Profile  
 
PostPosted: Fri Jan 25, 2019 12:12 pm 
Online

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8568
Location: Seattle
Well, the first half of it was me making an edit-o. The latter half is just me reporting what I saw in testing in Visual2C02.


Top
 Profile  
 
PostPosted: Fri Jan 25, 2019 12:27 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7582
Location: Canada
Or wait, I guess I'm confusing two cases. You mean that if rendering isn't disabled, i.e. forced blank within hblank, then you can't actually write the palette in hblank?

(The ROM I linked does write 0 to $2001 before writing the palette during hblank.)


Top
 Profile  
 
PostPosted: Fri Jan 25, 2019 12:30 pm 
Online

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8568
Location: Seattle
I mean that I asked Visual2C02 to time two writes to $2006 and a write to $2007 to cause a write to the PPU palette memory during hblanking without turning off rendering first, and the data didn't go through.


Top
 Profile  
 
PostPosted: Fri Jan 25, 2019 12:42 pm 
Offline

Joined: Mon May 25, 2009 2:20 pm
Posts: 75
i do this for the textbox at the bottom of the screen in my game, the IRQ first waits strictly until the H blank period by with one of those "wait a specific amount of cpu cycles" loops ..until it's at like PPU pixel 270 or whatever ...turn off the PPU, and update 1 color as fast as possible where you preload the 2006/2007 LDX/LDY/LDA right about ppu pixel 230-ish ..just when it's about to begin.

wait another full scanline until next H blank, update 2nd color, and again for the 3rd color.

Disch helped me with this when i first implemented it many years ago. About getting the timing just precise.

Some emulators do flicker those "dot crawl" on the very right edge of the screen in certain places. :( ...fceux is totally 100% fine.


Top
 Profile  
 
PostPosted: Fri Jan 25, 2019 1:21 pm 
Offline
User avatar

Joined: Wed Sep 07, 2005 9:55 am
Posts: 368
Location: Phoenix, AZ
For my status bar, I've timed it to where the second write to $2006 happens just after hblank starts. Then you can write 3 colors in one go (I don't have to reset the scroll since there is a gap between the status bar and the playing field and rendering is disabled).

Code:
         ldx pal_RAM + 10                      ; change $3F09, $3F0A, $3F0B
         ldy pal_RAM + 11
         lda #$3F
         sta PPU_ADDR
         lda #$09
            jsr func_Nop60
         sta PPU_ADDR                          ; hblank has started
         lda pal_RAM + 9
         sta PPU_DATA
         stx PPU_DATA
         sty PPU_DATA


The vram address then points to entry #0 (or a mirror) and I don't get a garbage line across the screen while waiting for the next hblank to update more of the palette.

That only works if your gap matches the color of entry #0.

edit: for clarity

_________________
. That's just like, your opinion, man .


Last edited by never-obsolete on Fri Jan 25, 2019 2:14 pm, edited 2 times in total.

Top
 Profile  
 
PostPosted: Fri Jan 25, 2019 1:51 pm 
Online

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8568
Location: Seattle
If I'm working through Visual2C02 correctly, palette reads and writes depend on the contents of the PPU's physical address bus, not the "v" or "t" scrolling registers.
During active PPU operation A12 and A13 are never both high simultaneously, not even in response to register writes.
So if I'm reading things correctly, it should be impossible to write to the palette while rendering is happening, period.


Top
 Profile  
 
PostPosted: Fri Jan 25, 2019 2:07 pm 
Offline
User avatar

Joined: Wed Sep 07, 2005 9:55 am
Posts: 368
Location: Phoenix, AZ
I should have added that I have rendering disabled during the gap, and by vaddr I meant whatever is used to show the behavior described in the wiki.

_________________
. That's just like, your opinion, man .


Top
 Profile  
 
PostPosted: Fri Jan 25, 2019 2:16 pm 
Offline

Joined: Mon May 25, 2009 2:20 pm
Posts: 75
woa is your routine really that short ? dang mine is moderately long. and it's been years since i looked at it, i actually updated 2 colors on first H blank, and the 3rd color on 2nd H-blank, so i only did it twice. But there was still 1 more scanline of waiting. :|

Maybe i should show what mine looks like, and you might be able to make it shorter.

Also i apparently reset the 2006 thing after the first 2 colors to PPU 0000 (not 3F00 like you said)...and then 02E0 after the 3rd color, cause if i didn't then it wont point to the right area of the NES nametable thing where the textbox is at


Top
 Profile  
 
PostPosted: Fri Jan 25, 2019 2:28 pm 
Offline
User avatar

Joined: Wed Sep 07, 2005 9:55 am
Posts: 368
Location: Phoenix, AZ
That snippet only does 3 colors, but I do it 4 times to change half the palette. Basically it goes:

NMI fires
-write status bar palette
-swap in status bar chr
-change to name table B

<status bar gets drawn>

IRQ fires
-disable rendering
-change bkg palette #2
-swap in gameplay chr
-wait for hblank, change bkg palette #3
-change to name table A
-wait for hblank, change bkg palette #4
-wait for hblank, change spr palette #1
-wait for hblank, set the scroll, enable rendering

<playing field gets drawn>


Note: I use single screen mirroring with the playing field in A and the status bar in B.

_________________
. That's just like, your opinion, man .


Top
 Profile  
 
PostPosted: Fri Jan 25, 2019 5:28 pm 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 2312
Location: Fukuoka, Japan
It was a good thing I asked that question! If I didn't, I would have had some interesting surprise later.

The reason I didn't turn ppu off is because of my wrong assumption that hblank should be similar to vlbank in some way (first error). The second one is, when testing with mesen and fceux, it allows me to change the color when ppu is on as long that I time my code to be inside hblank, everything is fine. This means you have to be careful to test timed code in hblank with those 2.

What made me research more on the subject was that nintendulator was not reacting the same: it was either not changing the color and creating a lot of flickers or the artifact were occurring at a different place. For now, nintendulor may be the closest to what happens on hardware then.

As for why I didn't test on hardware, it's because I started to code that part this week and my current setup speed is like "doing it like it's 1985" (i.e. it takes 5 minutes by epprom so I don't feel to use that writer much. Maybe it was even faster in 1985, actually :lol:) so I didn't test yet.

As for the dot crawl when color of background is different (first NT is blue, change one color then switch in NT that is black), nintendulator does show some artifact, all the time. Does PPU/CPU sync that I asked it another thread would make it more stable then?


Top
 Profile  
 
PostPosted: Sat Jan 26, 2019 8:53 am 
Offline

Joined: Sun Feb 07, 2016 6:16 pm
Posts: 725
Banshaku wrote:
What made me research more on the subject was that nintendulator was not reacting the same: it was either not changing the color and creating a lot of flickers or the artifact were occurring at a different place. For now, nintendulor may be the closest to what happens on hardware then.
As far as I can tell from the source, Nintentulator doesn't appear to prevent palette writes during HBlank, whether or not rendering is disabled.

In the code, the 2nd write to $2006 immediately changes VRAMAddr, and then writes to $2007 change the palette if VRAMAddr is still >= $3F00. There isn't any extra logic beyond this, so my best guess is that the value of VRAMAddr was changed between your $2006 & $2007 writes. But it also looks like VRAMAddr doesn't get changed beyond the usual stuff (H/V scroll increments, etc.), so not quite sure what could be causing the difference in this particular case.

It does, however, look like read/writes to $2007 will do nothing if rendering is not disabled. The VRAM increment (by 1 or 32) is still triggered. This only applies to non-palette read/writes, so it doesn't explain the behavior you're seeing.

As a quick test, preventing all reads/writes to $2007 (including palette) when rendering is enabled & before scanline 240 changes absolutely nothing to the 230 recorded tests I have (these are all test roms), so that's a good start. I don't have any recorded tests for actual games to try, though, unfortunately.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 27 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 6 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group