Attribute table

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

Choz
Posts: 10
Joined: Tue Jul 30, 2013 10:35 am

Attribute table

Post by Choz » Tue Jul 30, 2013 10:58 am

Hi!
I restarted the development of my NES emulator that I started back in 1997. I thought that nothing would work but to my surprise, I did not had much tweaking to do to at least make the intro screens of a few games show. But now my next step is to make the attribute table works. I don't plan release this emulator, I am doing this for fun.

Right now, I can see the intro of Ice Hockey with a few animations with also a few glitches. I succeeded to get the sprites colours right, but the backgrounds colours are still off. I think that my attribute table code is the problem. So, I would like to know if someone can tell me if I am wrong or not and why.

So, this is how I do it (I changed a few things for readability, it is coded in C):

xTile and yTile are the coordinates of the tile, not in pixels, but in tile coordinates.
address is the address of the attribute table, I add 23C0 to it later.

xP = (xTile / 4);
yP = (yYile / 4) * 32;
address = yP + xP;


Then to isolate the group of 2 bits to use in the final palette index (33 - 22 - 11 - 00)
I do :

x = (xTile / 2) mod 2;
y = (yTile / 2) mod 2;
bits = y << 1 or x;

So, bits contains values : 0, 1, 2 or 3.

Then I take the byte from the attribute table with the address that I found in the upper code and I isolate the bits to place them in the right position.
So that I get xx00 where xx the bits variable that I got.

bits = ((attTable[address ] >> (bits * 2)) << 2)


This code is NOT optimized. It is somewhat hard to understand and maybe there is easier way to do this. I am open to suggestions.

Tell me me if it is too complicated or if I forgot something.
Thanks!

lidnariq
Posts: 10238
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Attribute table

Post by lidnariq » Tue Jul 30, 2013 11:21 am

Choz wrote:xP = (xTile / 4);
yP = (yYile / 4) * 32;
address = yP + xP;
For the attribute table, that should be 8, not 32.

Choz
Posts: 10
Joined: Tue Jul 30, 2013 10:35 am

Re: Attribute table

Post by Choz » Tue Jul 30, 2013 12:18 pm

lidnariq wrote:
Choz wrote:xP = (xTile / 4);
yP = (yYile / 4) * 32;
address = yP + xP;
For the attribute table, that should be 8, not 32.
Thanks, it is true. I thought 32 because of the 32 tiles on a horizontal line, but we are talking about 32 / 4 = 8 attribute squares. It removed the strange artifacts that I had in the intro of Ice Hockey. The colours are still not perfect. If nobody find something else in my code then I will take for granted that it is right and I will search elsewhere in my code.

I also have another problem with the paddle reading, but I will probably make another topic for this.
Thanks!!

lidnariq
Posts: 10238
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Attribute table

Post by lidnariq » Tue Jul 30, 2013 12:43 pm

Choz wrote:The colours are still not perfect
If you're willing to provide a screenshot, it'd be easier to guess what's going on.

Choz
Posts: 10
Joined: Tue Jul 30, 2013 10:35 am

Re: Attribute table

Post by Choz » Tue Jul 30, 2013 1:35 pm

lidnariq wrote:
Choz wrote:The colours are still not perfect
If you're willing to provide a screenshot, it'd be easier to guess what's going on.
Ok here is the screenshot. The lower part is cut to 200 pixels (I was running this in 320 x 200 in DOS before), I will change this in the future.
Ice_hockey.png
Ice_hockey.png (5.51 KiB) Viewed 9951 times

lidnariq
Posts: 10238
Joined: Sun Apr 13, 2008 11:12 am
Location: Seattle

Re: Attribute table

Post by lidnariq » Tue Jul 30, 2013 1:59 pm

It looks like you're drawing the background using the wrong rows in the palette table?

The title should be palette set 3, consisting of colors $31, $30, and $22; in your screenshot it looks like you're using palette set 4, consisting of colors $36, $00, and $16. Off by one error, maybe?

Choz
Posts: 10
Joined: Tue Jul 30, 2013 10:35 am

Re: Attribute table

Post by Choz » Tue Jul 30, 2013 4:02 pm

lidnariq wrote:It looks like you're drawing the background using the wrong rows in the palette table?

The title should be palette set 3, consisting of colors $31, $30, and $22; in your screenshot it looks like you're using palette set 4, consisting of colors $36, $00, and $16. Off by one error, maybe?
I found out that my xTile and yTile coordinates were in fact pixels coordinate. So I changed my code to divide them by 8. The colours changed, but they are still not right.
Here is my code:

xTile = x / 8;
yTile = y / 8;
xAttr = (xTile / 4);
yAttr = (yTile / 4);
adrAttr= yAttr * 8 + xAttr;

xB = (xAttr >> 1) % 2;
yB = (yAttr >> 1) % 2;

bits = yB << 1 | xB; // Get the position of the 2 bits in the attribute byte (multiplied by 2 in the next line)
bits = ((attTable0[adrAttr] >> (bits * 2)) << 2) & 0x0C; // Left shift bits to make them in position 2 and 3. Or 0C to eliminate garbage bits

Screenshot :
Ice_Hockey.png
Ice_Hockey.png (5.42 KiB) Viewed 9936 times

User avatar
koitsu
Posts: 4218
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Attribute table

Post by koitsu » Tue Jul 30, 2013 4:10 pm

Things I notice:

1. The screen itself seems to be too small -- your screenshot should be 768x720, yet it's 768x602. This would explain the "weird graphics" at the bottom of the picture (the box which should say (C) 1988 NINTENDO) being cropped.

2. Looks like for the "ICE HOCKEY" part of the screen you're using palette set index #4 (i.e. the 5th palette entry) rather than set index #3 (i.e. the 4th palette entry). Index #4 consists of colours $00/$36/$00/$16 (or possibly $0f/$36/$00/$16 due to how the mirroring of #0 works), and index #3 consists of colours $0f/$31/$30/$22.

For the player selection and (C) 1988 NINTENDO boxes, you should be using index #2 (colours $0f/$25/$15/$20), but on-screen you're again using index #4. I mention this because lidnariq wondered about an off-by-one error, and this evidence would refute that possibility.

Maybe you have horizontal vs. vertical mirroring implemented wrong?

All that that said, this will probably help you the most -- raw attribute table data for the title screen. Offsets are in PPU RAM:

Code: Select all

000023C0  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
000023D0  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
000023E0  AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA  ªªªªªªªªªªªªªªªª
000023F0  55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU

000027C0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000027D0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000027E0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
000027F0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................

00002BC0  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
00002BD0  FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF  ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ
00002BE0  AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA  ªªªªªªªªªªªªªªªª
00002BF0  55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU

00002FC0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00002FD0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00002FE0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
00002FF0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
I would recommend dumping PPU RAM within your emulator and looking through it. If it doesn't match the above, then you're doing something wrong with regards to PPU accesses or otherwise. If it's correct, then the issue lies with how you're using the attribute data to do a palette lookup, or how you're doing palette-colours-to-RGB stuff. It could be either -- but at least you got sprites correct. :-)

Edit: Oh, I forgot another one -- here's the palette portion of PPU RAM as well, along with the mirrored copies ($3f20 onward):

Code: Select all

00003F00  0F 36 06 27 0F 15 05 00 0F 25 15 20 0F 31 30 22  .6.'.....%. .10"
00003F10  00 36 00 16 00 36 12 29 00 20 30 16 00 36 16 30  .6...6.). 0..6.0

00003F20  0F 36 06 27 0F 15 05 00 0F 25 15 20 0F 31 30 22  .6.'.....%. .10"
00003F30  00 36 00 16 00 36 12 29 00 20 30 16 00 36 16 30  .6...6.). 0..6.0
00003F40  0F 36 06 27 0F 15 05 00 0F 25 15 20 0F 31 30 22  .6.'.....%. .10"
00003F50  00 36 00 16 00 36 12 29 00 20 30 16 00 36 16 30  .6...6.). 0..6.0
00003F60  0F 36 06 27 0F 15 05 00 0F 25 15 20 0F 31 30 22  .6.'.....%. .10"
00003F70  00 36 00 16 00 36 12 29 00 20 30 16 00 36 16 30  .6...6.). 0..6.0
00003F80  0F 36 06 27 0F 15 05 00 0F 25 15 20 0F 31 30 22  .6.'.....%. .10"
00003F90  00 36 00 16 00 36 12 29 00 20 30 16 00 36 16 30  .6...6.). 0..6.0
00003FA0  0F 36 06 27 0F 15 05 00 0F 25 15 20 0F 31 30 22  .6.'.....%. .10"
00003FB0  00 36 00 16 00 36 12 29 00 20 30 16 00 36 16 30  .6...6.). 0..6.0
00003FC0  0F 36 06 27 0F 15 05 00 0F 25 15 20 0F 31 30 22  .6.'.....%. .10"
00003FD0  00 36 00 16 00 36 12 29 00 20 30 16 00 36 16 30  .6...6.). 0..6.0
00003FE0  0F 36 06 27 0F 15 05 00 0F 25 15 20 0F 31 30 22  .6.'.....%. .10"
00003FF0  00 36 00 16 00 36 12 29 00 20 30 16 00 36 16 30  .6...6.). 0..6.0

Choz
Posts: 10
Joined: Tue Jul 30, 2013 10:35 am

Re: Attribute table

Post by Choz » Tue Jul 30, 2013 5:13 pm

Hi koitsu (koitsu, dare na no deshou ka ?) Are you japanese by the way?

Thanks for your help.
The screen is 256x200 instead of 256x240. My emulator was in mode 13h at first. Now that it is in Windows, I will correct it later.

I did a dump just like you suggested. 0 values are normal in the attribute table because I redirect read/write to 23c0 for mirroring (same thing for palettes).
But I don't understand why I don't have the same values than you in the 3F00 line and why I got 0 in 3f10 line.
And I just saw that my sprite colours are not right anymore (if you look at my first screenshot, the 1st sprite was right, now it is like the 3rd sprite).

I will continue to look at my code. I just wanted to post what I got. I don't expect the solution now.

Here is what I got:


Attribute tables
23C0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
23D0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
23E0 AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA
23F0 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55
27C0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
27D0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
27E0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
27F0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2BC0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2BD0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2BE0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2BF0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2FC0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2FD0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2FE0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2FF0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

Palette
YOUR LINE:
3F00 0F 36 06 27 0F 15 05 00 0F 25 15 20 0F 31 30 22

MY LINE:
3F00 F 36 0 16 F 36 12 29 F 20 30 16 F 36 16 30

And the rest:
3F10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3F20 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3F30 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3F40 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3F50 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3F60 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3F70 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3F80 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3F90 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3FA0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3FB0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3FC0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3FD0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3FE0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
3FF0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

User avatar
koitsu
Posts: 4218
Joined: Sun Sep 19, 2004 9:28 pm
Location: A world gone mad

Re: Attribute table

Post by koitsu » Tue Jul 30, 2013 9:37 pm

I'm caucasian/white and American. すいません、日本語は話せません. Chinese or Korean I'd probably be better with. :)

So your attribute table is okay (we know what's in $23c0-23ff is correct, and we'll just have to assume that your mirroring code for the other attribute table regions is correct -- if it's wrong, well, that could be part of your problem. :-) )

Your palette entries look like you may have some PPU emulation problems of sorts, or possibly you're doing the mirroring of the palette entries incorrectly.

I'm also going to assume $3f20-3fff is being mirrored properly in your code (hence all zeros), but again, if it's not that could explain a lot of things. To debug mirrored "stuff", you might have to add some printf() statements or equivalent that log when someone is doing a write to certain areas of PPU RAM which are mirrored and then try to work back where the issue may be.

I'm sorry I can't be of much more help, but you can work out all of this yourself using FCEUX (its real-time hex editor and PPU viewing capabilities should help you immensely). I just do not generally help with emulator code; others here can help with that if need be, but there are lots of open-source emulators you could examine to see if you have the "general logic" incorrect.

mkwong98
Posts: 236
Joined: Mon May 30, 2011 9:01 pm

Re: Attribute table

Post by mkwong98 » Wed Jul 31, 2013 5:09 am

In both screenshots the background tiles are using the same palette set as the sprite on the left, so I think you mix up the two.

Choz
Posts: 10
Joined: Tue Jul 30, 2013 10:35 am

Re: Attribute table

Post by Choz » Wed Jul 31, 2013 11:58 am

koitsu wrote:I'm caucasian/white and American. すいません、日本語は話せません. Chinese or Korean I'd probably be better with. :)
Chinese and Korean, the 2 others languages that I would like to learn! Your Japanese is still good, you used the wa particle for contrast which I would not use naturally! I am a manga/anime illustrator (not professionally yet), and I have been learning Japanese for years. But now I am stuck because I should talk in japanese with other people to get better.

I did not know that FCEUX had all of this debugging stuff. I noticed in my emulator that the game write 2 times at ppu adress 3f02 (the first incorrect data in the palette). The first time, it does write 06 as it should but it writes 0 the second time. I tried breakpoints in FCEUX and I saw that it writes only one time at this address. So I guess that I have a conditional branching error somewhere. I think that I should log every instruction before this, but I have to write a disassembler for this and it takes time of course.
mkwong98 wrote:In both screenshots the background tiles are using the same palette set as the sprite on the left, so I think you mix up the two.
Good point, I will check this.

Thanks to both of you. If I find the problem I will post it here.

User avatar
mikejmoffitt
Posts: 1352
Joined: Sun May 27, 2012 8:43 pm

Re: Attribute table

Post by mikejmoffitt » Fri Aug 02, 2013 11:57 am

koitsu wrote:すいません、日本語は話せません.
Today I learned that すいません means something and isn't a typo!

Is your emulator running in MS-DOS? Just curious.

Choz
Posts: 10
Joined: Tue Jul 30, 2013 10:35 am

Re: Attribute table

Post by Choz » Fri Aug 02, 2013 8:26 pm

mikejmoffitt wrote:
koitsu wrote:すいません、日本語は話せません.
Today I learned that すいません means something and isn't a typo!

Is your emulator running in MS-DOS? Just curious.

すみません and すいません are the same thing in fact.

My emulator was in MS-DOS with DJGPP but now it is in Windows with SDL. I wanted to work on it but to keep it in DOS, I would have to use DOSBOX and or something else. Also, I have been using Visual Studio at work for years now so, returning to DJGPP would be hard for me.

tepples
Posts: 22277
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Attribute table

Post by tepples » Fri Aug 02, 2013 10:55 pm

MinGW uses the same compiler as DJGPP but produces Windows PE executables instead of DPMI executables. Would it also be hard to make something compile in MinGW?

Post Reply