Page 2 of 6
Re: Feedback wanted on SVG PPU frame timing diagram
Posted: Mon Mar 11, 2013 2:14 am
by ulfalizer
beannaich wrote:Makes sense. Instead of the last cycle of pre-render, the first cycle of raster 0 can be skipped. I noticed some possible Visual2C02 bugginess, if you look at the AB for the tile fetches at the end of pre-render (happens on all lines, though):
Code: Select all
321: $2000 <- name 1/2
322: $2000 <- name 2/2
..
329: $2001 <- name 1/2
330: $2000 <- name 2/2
the same occurs for the two dummy fetches:
337: $2002
338: $2000 <-+ why does the address go back to $2000 during the second cycle of nametable fetch?
339: $2002 |
340: $2000 <-+
The same thing seems to happen with attributes:
323: $23C0 <- attr 1/2
324: $2300 <- attr 2/2
I'm chalking that up to bugginess for now.
Might be related to the PPU loading the address in two stages too. Can't remember exactly how that works at the moment.
Re: Feedback wanted on SVG PPU frame timing diagram
Posted: Mon Mar 11, 2013 2:21 am
by ulfalizer
Here's an updated diagram with the skip location fixed and the lines renumbered to reflect how the PPU views things.
One thing that still isn't clear to me is how the idle ticks at the beginning of the scanlines affect rendering. Will there be a black column on the far left on the display, or does the timing work out differently somehow?
Re: Feedback wanted on SVG PPU frame timing diagram
Posted: Mon Mar 11, 2013 2:46 am
by beannaich
ulfalizer wrote:One thing that still isn't clear to me is how the idle ticks at the beginning of the scanlines affect rendering. Will there be a black column on the far left on the display, or does the timing work out differently somehow?
There wouldn't be a black column because the rendering pipeline is initialized in the pre-render scanline. The two buffered tiles would cover the gap. The 16-bit shift registers for the bit-planes isn't clocked until dot 1, allowing for a complete display even with the skipped cycle.
Re: Feedback wanted on SVG PPU frame timing diagram
Posted: Mon Mar 11, 2013 3:43 am
by ulfalizer
beannaich wrote:ulfalizer wrote:One thing that still isn't clear to me is how the idle ticks at the beginning of the scanlines affect rendering. Will there be a black column on the far left on the display, or does the timing work out differently somehow?
There wouldn't be a black column because the rendering pipeline is initialized in the pre-render scanline. The two buffered tiles would cover the gap. The 16-bit shift registers for the bit-planes isn't clocked until dot 1, allowing for a complete display even with the skipped cycle.
Ah, yeah, I think I see how that works now. The "fill levels" at the different ticks would be
Code: Select all
0: [xxxx xxxx] <- [xxxx xxxx]
1: [xxxx xxxx] <- [xxxx xxx-]
2: [xxxx xxxx] <- [xxxx xx--]
3: [xxxx xxxx] <- [xxxx x---]
4: [xxxx xxxx] <- [xxxx ----]
5: [xxxx xxxx] <- [xxx- ----]
6: [xxxx xxxx] <- [xx-- ----]
7: [xxxx xxxx] <- [x--- ----]
8: [xxxx xxxx] <- [xxxx xxxx]
9: [xxxx xxxx] <- [xxxx xxx-]
...
Re: Feedback wanted on SVG PPU frame timing diagram
Posted: Mon Mar 11, 2013 4:11 am
by ulfalizer
Here's a new version with some clarifying notes about rendering.
Re: Feedback wanted on SVG PPU frame timing diagram
Posted: Mon Mar 11, 2013 9:07 am
by Quietust
ulfalizer wrote:beannaich wrote:Makes sense. Instead of the last cycle of pre-render, the first cycle of raster 0 can be skipped. I noticed some possible Visual2C02 bugginess, if you look at the AB for the tile fetches at the end of pre-render (happens on all lines, though):
Code: Select all
321: $2000 <- name 1/2
322: $2000 <- name 2/2
..
329: $2001 <- name 1/2
330: $2000 <- name 2/2
the same occurs for the two dummy fetches:
337: $2002
338: $2000 <-+ why does the address go back to $2000 during the second cycle of nametable fetch?
339: $2002 |
340: $2000 <-+
The same thing seems to happen with attributes:
323: $23C0 <- attr 1/2
324: $2300 <- attr 2/2
I'm chalking that up to bugginess for now.
Might be related to the PPU loading the address in two stages too. Can't remember exactly how that works at the moment.
That would almost definitely be it - if you pay attention, you'll notice that the last 2 digits of AB are always exactly the same as DB, because they're actually the same signal, aliased together to make it easier to read the logs.
Re: Feedback wanted on SVG PPU frame timing diagram
Posted: Mon Mar 11, 2013 2:41 pm
by beannaich
Quietust wrote:That would almost definitely be it - if you pay attention, you'll notice that the last 2 digits of AB are always exactly the same as DB, because they're actually the same signal, aliased together to make it easier to read the logs.
So for example:
Code: Select all
H AB DB
$001: $2002 $00
$002: $20FF $FF
Is that why on the pinout there is AD0-7 and A8-13?
Re: Feedback wanted on SVG PPU frame timing diagram
Posted: Mon Mar 11, 2013 2:50 pm
by tepples
Nintendo has used multiplexed address and data buses to reduce pin count in a lot of its designs. Others I can think of are Nintendo 64 and Game Boy Advance.
Re: Feedback wanted on SVG PPU frame timing diagram
Posted: Mon Mar 11, 2013 3:01 pm
by beannaich
tepples wrote:Nintendo has used multiplexed address and data buses to reduce pin count in a lot of its designs. Others I can think of are Nintendo 64 and Game Boy Advance.
GBA with it's cartridge interface, latching the 24-bit address through D0-15 and A16-23, then using 16-bit incrementing counters on sequential reads and only supplying A16-23? It certainly reduces pin count, but makes a mess out of the cartridge interface and imposes timing penalties for non-sequential accesses.
Re: Feedback wanted on SVG PPU frame timing diagram
Posted: Mon Mar 11, 2013 3:05 pm
by tepples
beannaich wrote:[GBA seek/read] certainly reduces pin count, but makes a mess out of the cartridge interface and imposes timing penalties for non-sequential accesses.
As opposed to the NES PPU interface that imposes a timing penalty on all accesses?
Re: Feedback wanted on SVG PPU frame timing diagram
Posted: Mon Mar 11, 2013 3:12 pm
by beannaich
tepples wrote:As opposed to the NES PPU interface that imposes a timing penalty on all accesses?
Touche.
EDIT: Ulfalizer, I believe the shift registers are left-shift, with carry from bit 15 being used for output. Then every 8 clocks, the bottom 8 bits are loaded in with the most recently fetched data.
Re: Feedback wanted on SVG PPU frame timing diagram
Posted: Tue Mar 12, 2013 12:20 am
by ulfalizer
beannaich wrote:tepples wrote:As opposed to the NES PPU interface that imposes a timing penalty on all accesses?
Touche.
EDIT: Ulfalizer, I believe the shift registers are left-shift, with carry from bit 15 being used for output. Then every 8 clocks, the bottom 8 bits are loaded in with the most recently fetched data.
That's what I was trying to describe, but I used "top" instead of "bottom". (On the right side feels like top to me, but if you think about the bits "bottom" might make more sense.

)
The output is determined by fine_x I think, which acts as a pointer into the left/top shift reg. That's why you need 16 bits - to make sure you never "run out" of pixels even if fine_x is set to 7.
Re: Feedback wanted on SVG PPU frame timing diagram
Posted: Tue Mar 12, 2013 1:13 am
by beannaich
ulfalizer wrote:The output is determined by fine_x I think, which acts as a pointer into the left/top shift reg. That's why you need 16 bits - to make sure you never "run out" of pixels even if fine_x is set to 7.
Yeah, it's a tad weird though, since the value of fine_x really determines bit (15 - fine_x) is output.
Code: Select all
FEDCBA98 76543210
00110011 00110011
^
|
fine_x(0)+
FEDCBA98 76543210
00110011 00110011
^
|
fine_x(7)-------+
Conceptually, the background does the following every dot for output (C++):
Code: Select all
// get bits from shifters
u8_t attr = ( attr_shifter ) & 0x3U;
u8_t bit0 = ( bit0_shifter >> ( fine_x ^ 0xFU ) ) & 0x1U;
u8_t bit1 = ( bit1_shifter >> ( fine_x ^ 0xFU ) ) & 0x1U;
// clock shifters to the next pixel
bit0_shifter = u16_t( bit0_shifter << 1 );
bit1_shifter = u16_t( bit1_shifter << 1 );
// 'clock' in new data if necessary
if ( hclock & 0x8U )
{
attr_shifter = u8_t( attr_shifter << 2 ) | attr_fetch; // attr_shifter is only clocked once per tile (every 8 dots)
bit0_shifter |= bit0_fetch;
bit1_shifter |= bit1_fetch;
}
u8_t color = ( attr << 2 ) | ( bit1 << 1 ) | bit0;
if ( color ) // don't ouput 0
{
output_bg( color );
}
Re: Feedback wanted on SVG PPU frame timing diagram
Posted: Tue Mar 12, 2013 1:37 am
by ulfalizer
beannaich wrote:ulfalizer wrote:The output is determined by fine_x I think, which acts as a pointer into the left/top shift reg. That's why you need 16 bits - to make sure you never "run out" of pixels even if fine_x is set to 7.
Yeah, it's a tad weird though, since the value of fine_x really determines bit (15 - fine_x) is output.
Makes things consistent with the non-fine scroll at least, with increasing values pushing things to the left.
Re: Feedback wanted on SVG PPU frame timing diagram
Posted: Tue Mar 12, 2013 5:03 am
by ulfalizer
Here's a new version that includes the OAM clears. Spot any errors?
Removed the shift reg note as well, since it was a bit ambiguous and confusing.
Edit: Fixed a minor error on the 'Visible scanlines' line around h=279-305.