It is currently Mon Dec 10, 2018 7:54 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 31 posts ]  Go to page 1, 2, 3  Next
Author Message
PostPosted: Mon Mar 11, 2013 8:41 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7802
Location: Seattle
About half a year ago, nocash released his CHR-less Magic Floor, and verified it against his PAL NES. I recently tried to make a reproduction of it on my NTSC NES, and it haaaaates it. All the sprites are wrong, and the dot usually disappears immediately. (Which is because the PPU OAM readback is somewhat broken in the 2C02, but there's more).

Magic Floor originally moved the dot by doing something like
Code:
LDA #0
STA $2003
LDA $2004
CLC
ADC YdirectionAndVelocity
STA $2004
LDA #3
STA $2003
LDA $2004
CLC
ADC XdirectionAndVelocity
STA $2004

I shadowed away the reads from $2004; tried resetting $2003 to 0 at the end, and even tried replacing the $2003←3 with $2004←#Tile; $2004←0, but none of them really ever made it happy.

And despite the entire OAM being set on powerup (all #$EF or #$FF, I tried both), there's still garbage sprites appearing in the upper left corner (if I had to guess, somewhere around X=Y=16). And behavior still gets worse as the PPU gets warmer.

I finally switched the entire code to just use OAM DMA like everyone else, and it worked fine. So what's going on? Just how tricky is the OAM? Is it possible to do partial OAM updates on an NTSC NES? It seems silly to spend 513 or 514 cycles doing OAM DMA instead of ≈24.


Top
 Profile  
 
PostPosted: Tue Mar 12, 2013 12:37 pm 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 3141
Location: Tampere, Finland
I'll be pretty surprised if after all these years it turns out that even the $2004 writes (using STA) do not work correctly on 2C02. I mean, is it really possible that nobody has tested this properly before? Although I *do* distinctly remember several people wondering why their $2004 writing code didn't work.

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi


Top
 Profile  
 
PostPosted: Tue Mar 12, 2013 12:44 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7599
Location: Chexbres, VD, Switzerland
Sprite DMA technically IS writes to $2004, they are just done by DMA.

Reading from $2004 is however very ambigious. I think different revisions of the PPU are different, some allow reading OAM, some don't.
Anyway I see no valid reason to ever read OAM, to be honest.


Top
 Profile  
 
PostPosted: Tue Mar 12, 2013 12:53 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11010
Location: Rio de Janeiro - Brazil
I remember someone saying a long time ago that using $2004 for sprites wasn't reliable. For a while I thought his was true, but more recently someone else said this was nonsense. I have no idea what the deal really is with $2003/$2004.


Top
 Profile  
 
PostPosted: Tue Mar 12, 2013 1:52 pm 
Offline
User avatar

Joined: Mon Sep 27, 2004 8:33 am
Posts: 3715
Location: Central Texas, USA
I remember spending tens of hours trying to make sense of it when writing some tests. Suffice to say, $2003/$2004 aren't a simple address-data read/write pair or at least OAM has lots of quirks that cause extra things to happen.


Top
 Profile  
 
PostPosted: Thu Mar 14, 2013 1:20 pm 
Online

Joined: Fri Feb 24, 2012 12:09 pm
Posts: 727
Bregalad wrote:
Sprite DMA technically IS writes to $2004, they are just done by DMA.

Yes, technically (concerning what is passed through addresss/data bus), DMA and non-DMA should be same.
The differences that may cause the problems on NTSC consoles might be transfer timing, or transfer length (DMA writes all 100h bytes, whilst my Magic Floor game updates only 2 bytes; the sprites X and Y coordinates).

lidnariq wrote:
I shadowed away the reads from $2004; tried resetting $2003 to 0 at the end

Setting [2003h]=00h after manual transfers should leave the OAM address in same state as DMA transfer (assuming that DMA started at 00h, and wrapped to 00h after writing its 100h bytes).
However, as that didn't work: Did you try setting [2003h]=FFh, and then writing a dummy byte [2004h]=EFh? That would produce the same wrapping from FFh to 00h as happening at the end of DMA. Don't know if that will fix the problem... maybe the PPU is internally containing two OAM address registers, [2003h], and a second internal address register that gets updated only on writes to [2004h].


Top
 Profile  
 
PostPosted: Thu Mar 14, 2013 3:00 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7802
Location: Seattle
nocash wrote:
Did you try setting [2003h]=FFh, and then writing a dummy byte [2004h]=EFh? That would produce the same wrapping from FFh to 00h as happening at the end of DMA.
You appear to be on to something.

I made test ROMs that tried any one of these sequences:
$2003←$00, $2004←ty, $2004←0, $2004←0, $2004←tx, $2003←$00
$2003←$00, $2004←ty, $2004←0, $2004←0, $2004←tx, $2003←$FF, $2004←tx
$2003←$FC, $2004←ty, $2004←$FC, $2004←$FC, $2004←tx
$2003←$FC, $2004←ty, $2004←$FC, $2004←$FC, $2004←tx, $2003←$00
$2003←$FC, $2004←ty, $2004←$FC, $2004←$FC, $2004←tx, $2003←$FF, $2004←tx

The ones in bold worked, i.e. the sprite not only appeared at all but also in the right place.


Top
 Profile  
 
PostPosted: Thu Mar 14, 2013 4:54 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7006
Location: Canada
I recently wrote an NES ROM using STA $2004 to fill up the OAM. It runs fine on a PowerPak, but strangely on the PowerPak Lite about half the sprites will be missing/elsewhere. (I should try it from an EPROM later...)

I find this really weird, especially since the sprites are still messed up on the PowerPak Lite even if I reset the cart. (And on the PowerPak they're still fine if I reset.) Exactly which sprites are messed up is mostly consistent, but sometimes changes a little from reset to reset.

I thought this might be a problem with my PowerPak Lite, but maybe there's some really weird conditions for when it's safe to write $2004, or maybe the wiring of the cartridge is important. I dunno!


Edit: After doing some testing, I have found that the $2004 writes work fine as long as I do them immediately before turning on rendering. See my later post for more info.

Edit: Hrm, it's not -quite- reliable even when doing that! Wow. See my later posts.


Last edited by rainwarrior on Fri Mar 15, 2013 9:20 pm, edited 3 times in total.

Top
 Profile  
 
PostPosted: Thu Mar 14, 2013 5:56 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7802
Location: Seattle
I idly wonder if this is at all related to the MMC1+OAM problems infiniteneslives was having.

Something I find additionally confusing: when I first made the test ROM, all the irrelevant sprites were (as I said) somewhere around X=Y=16. Now all the offscreen ones are staying offscreen.

For the record: I'm using NES-CNROM-256-05, where I removed the mask ROMs, desoldered H, V, and CPU A14 jumpers, shorted VRAM /OE to ground, connected VRAM A10 to PPU A13, jumpered PRG /WR to Vcc, and just for good measure I removed the 161. PRG has been socketed with pin 1 folded out (so /BUSY won't try to sink power from Vcc), and I'm using an AT28C64-15PC (so 150ns)

Maybe the reason the CPU has OAM DMA and asserts M2 for 15/24 of the cycle is for the PPU, not for external ROMs? Maybe the reason that the 2C07 isn't cranky is because the 2A07 is clocked just a little slower? … Probably not, given that people regularly report success at overclocking the 2A03 by 200%.


Top
 Profile  
 
PostPosted: Fri Mar 15, 2013 3:22 pm 
Offline
Site Admin
User avatar

Joined: Mon Sep 20, 2004 6:04 am
Posts: 3595
Location: Indianapolis
rainwarrior wrote:
I recently wrote an NES ROM using STA $2004 to fill up the OAM. It runs fine on a PowerPak, but strangely on the PowerPak Lite about half the sprites will be missing/elsewhere. (I should try it from an EPROM later...)


I would guess that the PowerPak menu has used the DMA, and that would account for the difference.

Makes me wonder if using DMA for several frames, then switching over to manual writes would be any different. I think it's been established that the PPU displaying sprites isn't enough to refresh the DRAM (by Andrew Davie's story about testing The Three Stooges). I don't know much about the physics behind DRAM, but can we know if writing to $2004 is enough to refresh it? If not, I guess $2004 would never be safely usable (maybe interspersed with DMA copies?). But if it does, can a partially uninitialized/unrefreshed DRAM be unstable?


Top
 Profile  
 
PostPosted: Fri Mar 15, 2013 3:35 pm 
Offline
User avatar

Joined: Fri Nov 12, 2004 2:49 pm
Posts: 7599
Location: Chexbres, VD, Switzerland
If I'm not mistaken, with DRAM, bits will randomly change from '1' to '0' after some time. When the same cell is written again, it will of course take the new value, and normally other cells shouldn't be affected.

I think it is common in DRAM that there is a mecanism that automatically writes back a read value during the same cycle. This way, just by reading the data, it can be refreshed, and this is simpler than doing a read cycle followed by a write cycle (especially if done in software !).
Nowadays most DRAM refresh in hardware (there is something that reads the cells permanently internally), but this is probably not the case with NES' DRAM.

I've heard some old computer even had their main RAM as non-refreshable DRAM, and the NMI-style interrupt was meant to tell the CPU that it should read all the RAM to refresh it. This should hurt the performance terribly though.


Top
 Profile  
 
PostPosted: Fri Mar 15, 2013 3:46 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 7802
Location: Seattle
Memblers wrote:
I don't know much about the physics behind DRAM, but can we know if writing to $2004 is enough to refresh it?


Generically, writing to DRAM is good enough to refresh it. With the OAM... dunno. One thought, given the experiment I had above: maybe when the address overflows from $FF to 0 it triggers a refresh?


Top
 Profile  
 
PostPosted: Fri Mar 15, 2013 4:48 pm 
Offline
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 3141
Location: Tampere, Finland
lidnariq wrote:
Memblers wrote:
I don't know much about the physics behind DRAM, but can we know if writing to $2004 is enough to refresh it?


Generically, writing to DRAM is good enough to refresh it. With the OAM... dunno. One thought, given the experiment I had above: maybe when the address overflows from $FF to 0 it triggers a refresh?

Why wouldn't these work then?
Quote:
$2003←$FC, $2004←ty, $2004←$FC, $2004←$FC, $2004←tx, $2003←$00
$2003←$FC, $2004←ty, $2004←$FC, $2004←$FC, $2004←tx, $2003←$FF, $2004←tx

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi


Top
 Profile  
 
PostPosted: Fri Mar 15, 2013 5:31 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7006
Location: Canada
Memblers wrote:
I think it's been established that the PPU displaying sprites isn't enough to refresh the DRAM (by Andrew Davie's story about testing The Three Stooges).


The two times I've built ROMs that loads once at startup through $2004, both of them were completely stable for at least 30 minutes with no writes at all to OAM but rendering on (don't think I've tested them for longer).

Reading should be enough to refresh DRAM, though I don't know if the system is guaranteed to read all OAM bytes every frame. Does it quit early in the case of an 8-sprite overflow? It could just be that my use case didn't include this possibility.


Top
 Profile  
 
PostPosted: Fri Mar 15, 2013 7:16 pm 
Offline
User avatar

Joined: Sun Sep 19, 2004 10:59 pm
Posts: 1440
It doesn't need to read every byte - all it needs to do is read all 32 rows, and that's guaranteed to happen every scanline if you have rendering enabled.

_________________
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 3 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