It is currently Tue Jul 23, 2019 1:54 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 54 posts ]  Go to page Previous  1, 2, 3, 4
Author Message
PostPosted: Tue Apr 23, 2019 10:37 am 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8488
Location: Seattle
supercat wrote:
That would seem likely to work, but if there's a race condition between the DRAM machinery and the CPU cycles,
The DRAM circuitry is completely idle during forced and vertical blanking. ... with the caveat that the (PAL) 2C07 enables DRAM refresh for 50 scanlines before video rendering starts, and the PAL famiclone (UA6538) enables DRAM refresh for 50 scanlines after video rendering.

Quote:
In most DRAM chips, however, the "area" of the array is orders of magnitude larger than that of any individual reservoir.
The DRAM inside the 2C02 is weird; I haven't seen anything like it. It's NMOS, it holds both the bit and the inversion of the bit, it still takes four transistors. The only way it's smaller than the SRAM that's also used on the die is that the NMOS pull-up is shared along an entire column, instead of next to each bit.

Both "bit" and "notbit" go in/out to the DRAM interface logic... look in the vicinity of node 426 in Visual2C02.


Top
 Profile  
 
PostPosted: Tue Apr 23, 2019 11:36 am 
Offline

Joined: Thu Apr 18, 2019 9:13 am
Posts: 151
lidnariq wrote:
supercat wrote:
That would seem likely to work, but if there's a race condition between the DRAM machinery and the CPU cycles,
The DRAM circuitry is completely idle during forced and vertical blanking. ... with the caveat that the (PAL) 2C07 enables DRAM refresh for 50 scanlines before video rendering starts, and the PAL famiclone (UA6538) enables DRAM refresh for 50 scanlines after video rendering.


All operations involving DRAM reads--and that includes partial-row writes--need to be carefully sequenced. The mechanisms that force a regular sequence of actions may be idle, but if one wants to e.g. write to addresses 9 and 10 without affecting other bytes on the row, one of two sequences of events must occur:

1. Bytes 8-15 are read into a buffer, bytes 1 and 2 of that buffer are written with new data, and the buffer is written back to the row.

2. Bytes 8-15 are read into a buffer, bytes 1 of that buffer is written with new data, and the buffer is written back to the row. Then bytes 8-15 are read into a buffer again, byte 2 of that buffer is written, and the buffer is written back to the row.

In the second sequence, one could insert an arbitrary number of "read row X" and "write back row X" operations [with X being the same row as the other operations or a differen trow] between the first write-back, but the first half and second half of that sequence must, individually, be processed without other intervening operations.

Note that the number of discrete steps involving the DRAM array exceeds the number of CPU writes involved in performing them, so some kind of sequenced machinery is required even for accesses involving OAMADDR and OAMDATA.

Quote:
Quote:
In most DRAM chips, however, the "area" of the array is orders of magnitude larger than that of any individual reservoir.
The DRAM inside the 2C02 is weird; I haven't seen anything like it. It's NMOS, it holds both the bit and the inversion of the bit, it still takes four transistors. The only way it's smaller than the SRAM that's also used on the die is that the NMOS pull-up is shared along an entire column, instead of next to each bit.

Both "bit" and "notbit" go in/out to the DRAM interface logic... look in the vicinity of node 426 in Visual2C02.


I'd noticed the weird cell shape and wondered what was going on. Bulk DRAM uses a one-transistor cell, and until I saw the chip layout I would have guessed they'd use a three-transistor design with a storage transistor (source grounded), write transistor (connects storage gate to write bus), and read transistor (connects storage drain to read bus). That would avoid the destructive read issue, but I don't think that's what they're doing.

BTW, the area savings from eliminating the pull-up is significant, since the pull-ups would need to have routing to VDD.


Top
 Profile  
 
PostPosted: Tue Apr 23, 2019 1:16 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8488
Location: Seattle
supercat wrote:
All operations involving DRAM reads--and that includes partial-row writes--need to be carefully sequenced. The mechanisms that force a regular sequence of actions may be idle,
I understand what you're saying (I know how DRAM works), but I don't see how your explanation is relevant to the specific bug we've observed. There is at least one published contemporary game that relies on this copying behavior in combination with OAMDMA - it relies on the first 4 bytes in the page that is DMA'd being sprite 0 and generating a sprite 0 hit, while using OAMADDR to cycle sprite priority on the remaining 60 entries.


Top
 Profile  
 
PostPosted: Tue Apr 23, 2019 1:54 pm 
Offline

Joined: Thu Apr 18, 2019 9:13 am
Posts: 151
lidnariq wrote:
supercat wrote:
All operations involving DRAM reads--and that includes partial-row writes--need to be carefully sequenced. The mechanisms that force a regular sequence of actions may be idle,
I understand what you're saying (I know how DRAM works), but I don't see how your explanation is relevant to the specific bug we've observed. There is at least one published contemporary game that relies on this copying behavior in combination with OAMDMA - it relies on the first 4 bytes in the page that is DMA'd being sprite 0 and generating a sprite 0 hit, while using OAMADDR to cycle sprite priority on the remaining 60 entries.


The copying behavior would occur because the change to OAMADDR occurs between the time that a row specified by OAMADDR gets read into the buffer and the time that the contents of the buffer get written back to the row specified by OAMADDR. Ideally, a write to OAMADDR would cause the contents of the buffer to get stored to the row identified by the *old* value of OAMADDR, and then cause the row identified by the new value to be read into the buffer, but if the chip did that there wouldn't be a bug. What's important is the sequence of events that does occur, and what race conditions if any may be entailed.


Top
 Profile  
 
PostPosted: Tue Apr 23, 2019 2:16 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8488
Location: Seattle
supercat wrote:
What's important is the sequence of events that does occur, and what race conditions if any may be entailed.
Of the CPU-vs-PPU phases, we know of at least the three following behaviors on a write to OAMADDR

1- Works as desired
2- Copies the page at openbus (usually $20) to the page containing the new pointer
3- Other things that sound more analog like.
cite: Quietust (1), (2)

The CPU-vs-PPU phase is randomly chosen when the CPU and/or PPU are released from reset. The bug is known to be present in silicon revision G, not be in (rarer) older revisions (A-E), and revision H's properties are unknown. Most famiclones are copies of the revision G PPU and have this bug. (Note that revision A-E have other quirks pertaining to sprites, and we collectively haven't sat down to figure out what's happening).


Top
 Profile  
 
PostPosted: Tue Apr 23, 2019 2:56 pm 
Offline

Joined: Thu Apr 18, 2019 9:13 am
Posts: 151
lidnariq wrote:
The CPU-vs-PPU phase is randomly chosen when the CPU and/or PPU are released from reset. The bug is known to be present in silicon revision G, not be in (rarer) older revisions (A-E), and revision H's properties are unknown. Most famiclones are copies of the revision G PPU and have this bug. (Note that revision A-E have other quirks pertaining to sprites, and we collectively haven't sat down to figure out what's happening).


Could a cart power on, determine CPU phase, and force a reset (e.g. via the lockout chip) if the phase is unfavorable?


Top
 Profile  
 
PostPosted: Tue Apr 23, 2019 3:00 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8488
Location: Seattle
Nope. CIC lock doesn't renegotiate after negotiation fails, just endlessly asserts and de-asserts RESET to the CPU and PPU.


Top
 Profile  
 
PostPosted: Sun Apr 28, 2019 9:40 am 
Offline

Joined: Thu Apr 18, 2019 9:13 am
Posts: 151
lidnariq wrote:
Nope. CIC lock doesn't renegotiate after negotiation fails, just endlessly asserts and de-asserts RESET to the CPU and PPU.


So CIC-Reset on the cartridge slot is output-only? Bummer.

Otherwise, I was wondering about whether there would be any problem setting OAMADDR to a multiple of eight near the end and then writing from there through $FF and wrapping to 0? The act of setting OAMADDR would trash the row whose value is being set, but if that row will be rewritten anyway that wouldn't matter. If OAM can avoid corrupting the first or last row when the last action before display start is a write to address $FF, then I would think that approach would allow games that just need to update the last two sprites in a frame to save a lot of time compared with having to use OAM-DMA.


Top
 Profile  
 
PostPosted: Sun Apr 28, 2019 11:14 am 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8488
Location: Seattle
supercat wrote:
Otherwise, I was wondering about whether there would be any problem setting OAMADDR to a multiple of eight near the end and then writing from there through $FF and wrapping to 0? The act of setting OAMADDR would trash the row whose value is being set, but if that row will be rewritten anyway that wouldn't matter. If OAM can avoid corrupting the first or last row when the last action before display start is a write to address $FF, then I would think that approach would allow games that just need to update the last two sprites in a frame to save a lot of time compared with having to use OAM-DMA.
Might work? I think the problem is that the other 60 sprites might get corrupted and moved on-screen.

You can DMA from ROM, if the problem were just RAM.

This is definitely "you have to extensively test on hardware" territory. We haven't quantified what happens well enough for any emulator to implement sufficiently accurate and programmer-hostile bugs.


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

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