User:Myask/MyaGrafx: Difference between revisions
(→Basic: increase verilogness) |
m (re-section for ease of editing) |
||
Line 7: | Line 7: | ||
So, for the basicmost case... PPU: --10 NT11 11yy yxxx is where attributes normally reside. To our advantage, the nametable byte precedes the attribute table byte. This allows at least the 8x8 tile to be detected: NT-fetch is PPU: --10 NTYY YyyX XXxx. (A0, A5 are what we want to know, as they're not in the AT fetch; A1,6 are the 16-px accounted for by which two bits within an attribute byte.). For this simple one, instead of storing the attribute data per-tile, it's arranged as usual: four tiles in a 32x32 are specified each byte, just that the game pak will return different byte depending on the X and Y tile evenness. | So, for the basicmost case... PPU: --10 NT11 11yy yxxx is where attributes normally reside. To our advantage, the nametable byte precedes the attribute table byte. This allows at least the 8x8 tile to be detected: NT-fetch is PPU: --10 NTYY YyyX XXxx. (A0, A5 are what we want to know, as they're not in the AT fetch; A1,6 are the 16-px accounted for by which two bits within an attribute byte.). For this simple one, instead of storing the attribute data per-tile, it's arranged as usual: four tiles in a 32x32 are specified each byte, just that the game pak will return different byte depending on the X and Y tile evenness. | ||
==Basic Implementation== | |||
//pseudo-verilog | //pseudo-verilog | ||
Line 31: | Line 31: | ||
& ((~&PPUA[9:6]) ? UL : 1); //and enable for the UL AT fetches and all NT fetches. | & ((~&PPUA[9:6]) ? UL : 1); //and enable for the UL AT fetches and all NT fetches. | ||
assign Mya_ATRAM_D[7:0] = PPU_D[7:0] | assign Mya_ATRAM_D[7:0] = PPU_D[7:0] | ||
==Less basic== | ==Less basic== | ||
This mode of writing does not work if we want to extend to 8x1 attributes; there are three bits of attribute space to add and we only have three choices (00, 01, 10) of PPUADDR 8-9 for NT3. Even in two-screen mirroring, there is a small problem: but as we are relying on CIRAM for the first sliver of each section, one does not need to have duplicate write-access to those. One could remap $38** to what would have been in $3F**. Four-screen proves more problematic. Also problematic is determining the fine-Y. Brute-force method is to snoop for writes to PPU_SCROLL, as well as reads from PPU_STATUS and writes to PPU_ADDR to know the high-byte latch status. If we don't want to allow raster effects, which seems like a short-sighted decision, perhaps one could somehow divine where to begin from the dummy-fetch prerender scanline. In any case, it would basically require a scanline counter, at which point one would just add a few more bits of state to get a useful scanline-type interrupt, though if it shares the low three bits with the rendering portion it would be more of a NT-relative Y-coordinate interrupt... | This mode of writing does not work if we want to extend to 8x1 attributes; there are three bits of attribute space to add and we only have three choices (00, 01, 10) of PPUADDR 8-9 for NT3. Even in two-screen mirroring, there is a small problem: but as we are relying on CIRAM for the first sliver of each section, one does not need to have duplicate write-access to those. One could remap $38** to what would have been in $3F**. Four-screen proves more problematic. Also problematic is determining the fine-Y. Brute-force method is to snoop for writes to PPU_SCROLL, as well as reads from PPU_STATUS and writes to PPU_ADDR to know the high-byte latch status. If we don't want to allow raster effects, which seems like a short-sighted decision, perhaps one could somehow divine where to begin from the dummy-fetch prerender scanline. In any case, it would basically require a scanline counter, at which point one would just add a few more bits of state to get a useful scanline-type interrupt, though if it shares the low three bits with the rendering portion it would be more of a NT-relative Y-coordinate interrupt... |
Revision as of 22:55, 22 April 2015
"Perhaps someone should mock up a specification for a CPLD that only provides 8x8 attributes and nothing else."--Tepples
Sources
PPU rendering, Cartridge connector
Basic
As the cart only has CIRAM A10 piped through, one can't just remap part of CIRAM to supply the 256 bytes of attribute one needs for page 0.
So, for the basicmost case... PPU: --10 NT11 11yy yxxx is where attributes normally reside. To our advantage, the nametable byte precedes the attribute table byte. This allows at least the 8x8 tile to be detected: NT-fetch is PPU: --10 NTYY YyyX XXxx. (A0, A5 are what we want to know, as they're not in the AT fetch; A1,6 are the 16-px accounted for by which two bits within an attribute byte.). For this simple one, instead of storing the attribute data per-tile, it's arranged as usual: four tiles in a 32x32 are specified each byte, just that the game pak will return different byte depending on the X and Y tile evenness.
Basic Implementation
//pseudo-verilog always @(negedge PPU_/RD) if (PPU_A[13] & (~& PPUA[9:8])) begin //NT-fetch AT_8X <= PPUA[0]; AT_8Y <= PPUA[5]; end always @(posedge M2) if (~CPU_W & CPU_A[15] == 1) //only have one visible register bit, so little decoding necessary: CPU$8xxx. Mya_ATRAM_Enable <= CPU_D[0]; assign Mya_ATRAM_A[5:0] = PPU_A[5:0]; //don't really need to go through CPLD? assign Mya_ATRAM_A[6] = (PPU_A[12] ? PPU_A[6]: AT_8X); //write to PPU 0011 NT*0 YXyy yxxx, A8=0 is to dodge palettes. assign Mya_ATRAM_A[7] = (PPU_A[12] ? PPU_A[7]: AT_8Y); assign Mya_ATRAM_A[9:8] = PPU_A[11:10]; //NT-select. Also don't need to be routed through. assign Mya_ATRAM_WR = PPU_WR & (&PPU_A[13:12]) & ~PPU_A[8]; assign UL = ~(AT_8X | AT_8Y); //UpperLeft: replace with 0 to not bother using CIRAM for any attributes at all assign Mya_ATRAM_CE = PPU_A[13] & (PPU_A[12] ? (~PPU_A[8]) : PPU_A[8]) & PPU_A[9] & ~UL & Mya_ATRAM_Enable; assign CIRAM_CE = PPUA[13] //NT/AT only & (~PPUA[12] | (& PPUA[11:8])) //disable for 30xx-3Exx to allow the writes to cart & ((~&PPUA[9:6]) ? UL : 1); //and enable for the UL AT fetches and all NT fetches. assign Mya_ATRAM_D[7:0] = PPU_D[7:0]
Less basic
This mode of writing does not work if we want to extend to 8x1 attributes; there are three bits of attribute space to add and we only have three choices (00, 01, 10) of PPUADDR 8-9 for NT3. Even in two-screen mirroring, there is a small problem: but as we are relying on CIRAM for the first sliver of each section, one does not need to have duplicate write-access to those. One could remap $38** to what would have been in $3F**. Four-screen proves more problematic. Also problematic is determining the fine-Y. Brute-force method is to snoop for writes to PPU_SCROLL, as well as reads from PPU_STATUS and writes to PPU_ADDR to know the high-byte latch status. If we don't want to allow raster effects, which seems like a short-sighted decision, perhaps one could somehow divine where to begin from the dummy-fetch prerender scanline. In any case, it would basically require a scanline counter, at which point one would just add a few more bits of state to get a useful scanline-type interrupt, though if it shares the low three bits with the rendering portion it would be more of a NT-relative Y-coordinate interrupt...