The original organization is "free" because it retains the PPU's existing subdivision. The nicer organization requires something to shove bits around ... which is why UNL_DripGame presents its interface to 8x8 attributes as a 2048x2-bit array in CPU memory. (Does the convenience of "no bitpacking" outweigh the "takes four times as long"?)

I do not understand this picture. Attribute table RAM is normally $40 bytes long.

Personally if I'd have to do a circuit that does *only* 8x8 (or any finer than 16x16) attribute size, I believe it should be possible to do with discrete logic (and maybe PAL), by sacrifying one name table in CIRAM, and use the other half of CIRAM for colour data. Unfortunately it's *not* possible to highack the adress lines of CIRAM, making such a trick hard to realize. The answer is to steal a part of CHR-RAM, whose address lines *can* be highacked, by the second 1k of CIRAM.

So it'd work like that :* Name-table : 1k of CIRAM (minus $3c0-$3ff, unused)* Finer-grained attribute-table : 1k of CHR-RAM (reads like a name, table)* Pattern tables : 7k stands in physical CHR-RAM, and 1k in the second half of CIRAM, but nobody notices, and this fakes 8k of CHR-RAM

A register traps NT fetched, and uses it's adress to replace adress lines of CHR-RAM on AT fetches... that's it. Not very simple, but not very complicated either. Oh, and all the content of the new attribute table should be repeated 4 times in a byte.

Nice idea, Bregalad! It just sounds like a waste of space to dedicate the an entire 1KB to attributes, while all you really need is 240 bytes. Couldn't we use the rest of this memory as a name table for status bars or something?

You take advantage of the fact that the currently-needed attribute fetching address is derived from the nametable fetch that occurs immediately beforehand, so that's the first fetch with ppuA13 high. You just remember the address from that fetch (using a latch or something), and then you rearrange the bits to form a new attribute address to fetch. My design arranged the expanded attribute table to be like the regular attribute table, but with 8x8 regions instead of 16x16 (so each byte described a 16x16 region of four 8x8 regions).

And then after that, my design was to extract the two bits of interest from the extended attribute byte, repeating them 4 times to form a full byte, since the NES is still expecting its own attribute format and will select two bits out of the byte on its own, mirroring the bits just removes the need to figure out which two bits the NES is going to extract from the byte you give it.

I do not understand this picture. Attribute table RAM is normally $40 bytes long.

I seem to have neglected to precisely mention the actual "add a RAM chip to the cart to handle attributes" anywhere, aside from the //then cart-internals: first, the (probably 6264) But since the [added] RAM was only being used for Attribute Tables, not CHR, I called it ATRAM.

A register traps NT fetched, and uses it's adress to replace adress lines of CHR-RAM on AT fetches... that's it. Not very simple, but not very complicated either. Oh, and all the content of the new attribute table should be repeated 4 times in a byte.

That, however, is pretty close to exactly what the Verilog I wrote on the linked page in my userspace does. (It also remaps more of PPU-address-space as a write port.) It stores each attribute byte as packed, though, and just mirrors the relevant two-bits across the byte when read based on the preceding NT-fetch...like what Drag said.

[hr]

Mind, I didn't actually design/code the actual PRG- and CHR-mapping portions that need taking care of. I'm told that 1,2,4kiB SRAMs are no longer cheaply available, just 8kiB and 32kiB. The 4-screen AT is ~1kiB. 4-screen NT (that is, adding 2 screens' worth) is ~2kiB. CHR-RAM unbanked is 8kiB, so that's not nice to add without adding banking...

e: So what sort of CHR-banking (and PRG, I suppose) would be sensible, as it seems like "just" adding 8x8 attributes seems like a waste of CPLD?

For the programmer, it'd be four 8 KiB pages of CHR-RAM, where tile #s $3C-$3F, $7C-$7F, $BC-$BF, and $FC-$FF in the left pattern table is replaced with the replacement attribute tables. Each of the four pages would correspond to the four corners of each 16x16 zone.

But this is the layout that Sik was complaining about, so maybe it's a bit too annoying.

Oops, I saw the image and skipped right over the link. Sorry. It looks like we had the same idea, so I don't have anything else to add, other than I tried a couple of layouts for the bitpacking and settled on the "like the PPU except 8x8" because it was already pretty versatile for both horizontal and vertical nametable updates.

I think Tepples might've mentioned the CPLD so there'd be an implementation of 8x8 attribute tables for others to use in their CPLD mappers, since 8x8 attributes doesn't really provide any advantages or disadvantages for any particular chr/prg banking style.

Nice idea, Bregalad! It just sounds like a waste of space to dedicate the an entire 1KB to attributes, while all you really need is 240 bytes. Couldn't we use the rest of this memory as a name table for status bars or something?

(moved from split topic)"...per nametable upgraded. (And technically, 180 bytes, if you let CIRAM take some, but then you have less arrangement control.)"

Quote:

since 8x8 attributes doesn't really provide any advantages or disadvantages for any particular chr/prg banking style.

Quote:

like a waste of CPLD

okay, more like a waste of a 6264 (8kiB)...There's already address lines attached to nice-arranged (present revision) to allow PPU-space mapped registers, at 14'b__11_xx01_RRRx_xxRR, instead of in CPU-space, but that would prevent raster effects from being as easy or as nice.

It occurs to me that one could implement 8x16 attributes with a little discrete logic: a flip-flop to toggle even/odd for each AT fetch, hooked up (with an AND to mask it to only AT area) to CIRAM /A10, so that the second nametable's attribute zone gets co-opted for the other half of the first. [Like my other "simple" suggestions, this is hellish to write to; restricting the oscillating behavior to reads with another input on the AND, and allowing PPUA10 to control CIRAMA10 for writes, would make it somewhat easier at the cost of somewhat more logic...but maybe you could fit it all in one NAND chip.]

16x8 attributes would be harder, since you need to implement a scanline counter and then switch every 8.

Of course, were the cartridge to have access to four more address lines, one would have just enough to maximize the first nametable's attribute density at 8x1, putting it in the other table. But that's just wishful thinking.

I was pondering how to make hexagon-arranged square attributes (think how Koei's strategy games often do it)--but then I realized that just doing a 16x8 and having some mild redundancy in attribute tables would be far, far, easier than actually implementing 16x16 offset attributes (check row, check column, selecting the proper attribute out of the byte, adding to the row...) along with being more flexible for the rest of the screen.

Who is online

Users browsing this forum: No registered users and 2 guests

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