8x16 and whatever else unreg wants to know

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Post by unregistered »

tokumaru wrote:This means that the program can easily write the attribute bytes straight to the attribute table
How am I susposed to write bytes to the attribute table? The attribute table must be part of the PPU... and it sits under the nametable, I think.
User avatar
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Post by Kasumi »

You write the high, then low byte of the address of the attribute byte you want to update to $2006, then you write the byte you want written to that attribute byte to $2007. This must be done during vblank or while rendering is disabled.


See this for the addresses: http://wiki.nesdev.com/w/index.php/PPU_attribute_tables
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Post by unregistered »

Kasumi, thank you! :D
3gengames wrote:You can split that data away from that data and then use all 8-bits per metatile and then read the data from an attribute table for them too, and like you said use 1 byte for 4 attributes. :)
... I don't understand. :(
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

Yeah, it's exactly the same as writing tiles to the name tables. After the 960 name table bytes there are 64 attribute table bytes.
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Post by unregistered »

Ah, so that's how it works... I remember now that my sister said it (NESst) saved the attributes with the nametable. Great to know, thank you tokumaru! :D
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Post by unregistered »

http://wiki.nesdev.com/w/index.php/PPU_attribute_tables wrote: value = (topleft << 0) | (topright << 2) | (bottomleft << 4) | (bottomright << 6)
I think this means that this value byte would contain the bit order bottomright,bottomleft,topright,topleft... which seems backward to me. Could it be 00000000b instead? :?
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

It is how the wiki says it is... You can't really change how the PPU works, the best you can do if a particular order of bits doesn't please you is to use a translation table, to convert from your format to the hardware format.

There's little advantage in that though, because you'd be wasting 256 bytes of ROM and some CPU time reading from the table instead of directly writing values to VRAM without any benefit other than making the attribute data easier for you to type.
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Post by unregistered »

unregistered wrote:
http://wiki.nesdev.com/w/index.php/PPU_attribute_tables wrote: value = (topleft << 0) | (topright << 2) | (bottomleft << 4) | (bottomright << 6)
Does the wiki say this value byte contains the bit order bottomright,bottomleft,topright,topleft? :shock: :( (Thank you for helping me so much though tokumaru! :D)
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

Heh, I always have to check, but yeah, it seems that the attribute bits are arranged like this:

Code: Select all

Attribute byte:

DDCCBBAA

Attribute block:

+--+--+
|AA|BB|
+--+--+
|CC|DD|
+--+--+
It may look kind backwards since we read numbers from left to right, but when you consider that numbers grow from right to left it's not so weird.
tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

Perhaps what's backwards is that the leftmost part of a pattern table byte is in the high bits, but the leftmost part of an attribute table byte is in the low bits.
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Post by unregistered »

^ I don't remember anything about pattern table bytes. :oops:

tokumaru wrote:Heh, I always have to check, but yeah, it seems that the attribute bits are arranged like this:

Code: Select all

Attribute byte:

DDCCBBAA

Attribute block:

+--+--+
|AA|BB|
+--+--+
|CC|DD|
+--+--+
Thank you, kind sir! :)
tokumaru wrote:It may look kind backwards since we read numbers from left to right, but when you consider that numbers grow from right to left it's not so weird.
It took me a bit to understand because I've never ever thought about numbers growing from right to left... but they do! :D
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Post by unregistered »

tokumaru[color=olive], on [/color][url=http://nesdev.com/bbs/viewtopic.php?t=7451&postdays=0&postorder=asc&start=360][color=olive]page 25[/color][/url][color=olive],[/color] wrote:You could arrange the metatiles in ROM kinda like this:

Code: Select all

MetatileTile0:
	.db $00, $04, $08

MetatileTile1:
	.db $01, $05, $09

MetatileTile2:
	.db $02, $06, $0a

MetatileTile3:
	.db $03, $07, $0b

MetatileCollision:
	.db %00001010, %01001100, $00011010

MetatilePalette:
	.db %10101010, %00000000, %01010101
Here I have 3 metatiles, each using 6 bytes. If I want to get the collision info for any given tile, I can just put its index in X or Y and read it from the MetatileCollision table.
Is there a possible way to make the 6 labels a part of the machine? Like, well, make them local labels that I could use. Would I have to make each label different in every file? I'd like to make an assembly object... something like jmp bg0.@MetatileCollision. Is that possible? :)
tokumaru[color=olive], on [/color][url=http://nesdev.com/bbs/viewtopic.php?t=7451&postdays=0&postorder=asc&start=360][color=olive]page 25[/color][/url][color=olive],[/color] wrote:So, if your screenArray is an array of 16x15 metatile indexes, you can do something like this to read the collision info of any metatile:

Code: Select all

	;use 2 4-bit coordinates to calculate
	;how far in the array the metatile is
	lda metatileY
	asl
	asl
	asl
	asl
	ora metatileX
	tax

	;get the index of the metatile
	lda screenArray, x
	tax

	;get its collision information
	lda MetatileCollision, x
Just as easily you now can use lda MetatileTile0, x to read the index of its top left tile, and the other tables to find out anything you want about the metatile in that position.
Sweet thank you for explaining to me how to use 4bit numbers. :D I hope, after playing with them a bit, I'll get comfortable using them.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

unregistered wrote:Is there a possible way to make the 6 labels a part of the machine? Like, well, make them local labels that I could use. Would I have to make each label different in every file? I'd like to make an assembly object... something like jmp bg0.@MetatileCollision. Is that possible? :)
I didn't really understand the question... Why would you JMP to a data table? That would most likely crash the program!

Do you want to use different data for each level or something like that? If that's the case, then the answer is the indirect indexed addressing mode (i.e. LDA ($XX), Y). With that addressing mode you use pointers to define the tables that will be read, and you can alter the pointers as much as you want.

For example, you could have a different name for each collision table (or whatever table you want), and then make a table with all the addresses:

Code: Select all

MetatileCollisionAdresses:
	.dw MetatileCollisionLevel1, MetatileCollisionLevel2, MetatileCollisionLevel3
Then you can read the address for the current level and put it in a pointer using the level's index:

Code: Select all

	lda LevelIndex ;get the level's index
	asl ;multiply by 2 because each address is 2 bytes
	tax ;use that as an index into the table of addresses
	lda MetatileCollisionAdresses+0, x ;copy the low byte
	sta MetatileCollision+0
	lda MetatileCollisionAdresses+1, x ;copy the high byte
	sta MetatileCollision+1
Then you can use indirect indexed addressing to read the data, instead of what we had before. The only real difference is that now you'll have to use Y as your index register, because this addressing mode doesn't work with X:

Code: Select all

	;get collision information 
	lda (MetatileCollision), y
thank you for explaining to me how to use 4bit numbers.
There are lots of ways to use 4-bit numbers. In this case it was convenient to use 4-bit values because 4 bits are enough to represent the metatile coordinates inside a single screen.
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Post by unregistered »

tokumaru wrote:
unregistered wrote:Is there a possible way to make the 6 labels a part of the machine? Like, well, make them local labels that I could use. Would I have to make each label different in every file? I'd like to make an assembly object... something like jmp bg0.@MetatileCollision. Is that possible? :)
I didn't really understand the question... Why would you JMP to a data table? That would most likely crash the program!
hahaha hahaha hahaha (laughing at myself) hahaha ok hahaha! No I shouldn't have typed JMP... ... ...should have gone with lda bg0.@MetatileCollision, 3. I was trying to say I would make an assembly object named bg0. And then I would try to access the third entry of its MetatileCollision array (labeled @MetatileCollision). I wanted to use @MetatileCollision because it is a local label/variable and then hopefully I could leave each file with a label named @MetatileCollision. Or would I need to have a unique label name in each .NAC (nametable & collision) file? We would replace each .NAM file with a .NAC file.

tokumaru, thank you so very much for your explanation of the indirect indexed addressing mode and for the code examples. :) : ) :D
tokumaru wrote:
thank you for explaining to me how to use 4bit numbers.
There are lots of ways to use 4-bit numbers. In this case it was convenient to use 4-bit values because 4 bits are enough to represent the metatile coordinates inside a single screen.

Ah yes! That's amazing! :D
unregistered
Posts: 1318
Joined: Thu Apr 23, 2009 11:21 pm
Location: cypress, texas

Post by unregistered »

unregistered wrote:
tokumaru[color=olive], on [/color][url=http://nesdev.com/bbs/viewtopic.php?t=7451&postdays=0&postorder=asc&start=360][color=olive]page 25[/color][/url][color=olive],[/color] wrote:You could arrange the metatiles in ROM kinda like this:

Code: Select all

MetatileTile0:
	.db $00, $04, $08

MetatileTile1:
	.db $01, $05, $09

MetatileTile2:
	.db $02, $06, $0a

MetatileTile3:
	.db $03, $07, $0b

MetatileCollision:
	.db %00001010, %01001100, $00011010

MetatilePalette:
	.db %10101010, %00000000, %01010101
Here I have 3 metatiles, each using 6 bytes. If I want to get the collision
info for any given tile, I can just put its index in X or Y and read it from the MetatileCollision table.
Ok here's^ 3 metatiles,each using 6 bytes. Does this mean each new metatile will use 6 bytes? It's confusing :? trying to complete one .NAC (Nametable & Collision) file. For the attribute bytes we have 64 bytes (8 * 8 ). For the Collision part we will have 240 bytes (16 * 15). So 64 != 240.......... My solution is to increase our metatile size to 32x32. Then we would have 64 bytes for both of them, I think. :oops: But, then it's confusing to think about, for me at least. :? I need some help. Dear God, please help me. Thank you God! Amen. :)
Post Reply