How the system knows where to load background an sprites?

Discuss technical or other issues relating to programming the Nintendo Entertainment System, Famicom, or compatible systems. See the NESdev wiki for more information.

Moderator: Moderators

Post Reply
yaofan1212
Posts: 12
Joined: Sat Dec 04, 2021 9:48 am

How the system knows where to load background an sprites?

Post by yaofan1212 »

Hello!

I am studying a code and I couldn't have to figure out the following.

The code:

.segment "TILES"
.incbin "background.chr"
.incbin "sprite.chr"

Relevant part of config linker file:
CHR: start = $0000, size = $2000, type = ro, file = %O, fill = yes, fillval = $00;
TILES: load = CHR, type = ro;

How the system knows to put the data in "background.chr" in Pattern table 0 (for background) and to put data "sprite.chr" in Pattern table 1 (for sprites)?

As far as I know, when the system boots up, immediately copy the info from CHR-ROM to the pattern tables, but how does it knows where to put each part.

Thanks!
User avatar
Quietust
Posts: 1920
Joined: Sun Sep 19, 2004 10:59 pm
Contact:

Re: How the system knows where to load background an sprites?

Post by Quietust »

yaofan1212 wrote: Mon Dec 06, 2021 10:35 am Hello!

I am studying a code and I couldn't have to figure out the following.

The code:

Code: Select all

.segment "TILES"
.incbin "background.chr"
.incbin "sprite.chr"

 Relevant part of config linker file:
    CHR:    start = $0000,  size = $2000, type = ro, file = %O, fill = yes, fillval = $00;
    TILES:    load = CHR, type = ro;
How the system knows to put the data in "background.chr" in Pattern table 0 (for background) and to put data "sprite.chr" in Pattern table 1 (for sprites)?

As far as I know, when the system boots up, immediately copy the info from CHR-ROM to the pattern tables, but how does it knows where to put each part.

Thanks!
The NES does not perform any such copy operations on boot-up - if the cartridge has CHR ROM, then that ROM is directly mapped into the bottom half of the PPU's address space where the pattern tables exist (and RAM will typically be mapped into the upper half of the address space in order to hold the nametabledata).

Since the code in question performs .incbin "background.chr" first, that one ends up at PPU address $0000, and assuming that said file is only 4096 bytes long (which it should be), then "sprite.chr" will end up at PPU address $1000.

As for how the PPU decides which pattern table is used for background and which one is used for sprites, that's controlled by the last value written to CPU address $2000 - bits 3 (0x08) and 4 (0x10) specify where the PPU attempts to load Sprite and Background tiles, respectively. In the above case, you would want to write with bit 3 set and bit 4 clear, while if the two .incbin commands were reversed then you'd write with bit 3 clear and bit 4 set.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
yaofan1212
Posts: 12
Joined: Sat Dec 04, 2021 9:48 am

Re: How the system knows where to load background an sprites?

Post by yaofan1212 »

Quietust wrote: Mon Dec 06, 2021 10:44 am
yaofan1212 wrote: Mon Dec 06, 2021 10:35 am Hello!

I am studying a code and I couldn't have to figure out the following.

The code:

Code: Select all

.segment "TILES"
.incbin "background.chr"
.incbin "sprite.chr"

 Relevant part of config linker file:
    CHR:    start = $0000,  size = $2000, type = ro, file = %O, fill = yes, fillval = $00;
    TILES:    load = CHR, type = ro;
How the system knows to put the data in "background.chr" in Pattern table 0 (for background) and to put data "sprite.chr" in Pattern table 1 (for sprites)?

As far as I know, when the system boots up, immediately copy the info from CHR-ROM to the pattern tables, but how does it knows where to put each part.

Thanks!
The NES does not perform any such copy operations on boot-up - if the cartridge has CHR ROM, then that ROM is directly mapped into the bottom half of the PPU's address space where the pattern tables exist (and RAM will typically be mapped into the upper half of the address space in order to hold the nametabledata).

Since the code in question performs .incbin "background.chr" first, that one ends up at PPU address $0000, and assuming that said file is only 4096 bytes long (which it should be), then "sprite.chr" will end up at PPU address $1000.

As for how the PPU decides which pattern table is used for background and which one is used for sprites, that's controlled by the last value written to CPU address $2000 - bits 3 (0x08) and 4 (0x10) specify where the PPU attempts to load Sprite and Background tiles, respectively. In the above case, you would want to write with bit 3 set and bit 4 clear, while if the two .incbin commands were reversed then you'd write with bit 3 clear and bit 4 set.
But when the system starts I see that the background.chr file is copied to Table Pattern 0:
Image

And the sprite.chr file is copied to Table Pattern 1:
Image

I don´t see any part in the code copying to the address of TP1, so I figure out that is doing the copy automatically. This is what I don't understand.



Thanks for your help.
Last edited by yaofan1212 on Mon Dec 06, 2021 11:08 am, edited 1 time in total.
yaofan1212
Posts: 12
Joined: Sat Dec 04, 2021 9:48 am

Re: How the system knows where to load background an sprites?

Post by yaofan1212 »

I think I figured out. The "background.chr" file is padded with zeroes up to address $FF0! And then follows the sprite.chr file exactly at address $1000!

Thanks for your help!
User avatar
nia_prene
Posts: 17
Joined: Sat Dec 04, 2021 2:50 pm

Re: How the system knows where to load background an sprites?

Post by nia_prene »

yaofan1212 wrote: Mon Dec 06, 2021 10:35 am .segment "TILES"
.incbin "background.chr"
.incbin "sprite.chr"

Relevant part of config linker file:
CHR: start = $0000, size = $2000, type = ro, file = %O, fill = yes, fillval = $00;
TILES: load = CHR, type = ro;
It looks like you figured it out, but your linker is doing exactly what you told it to do. It is loading your "TILES" segment right into your chr memory area. Since you have .incbin your background tiles first, they are loaded into that memory area first. Your files are probably exactly 256 tiles (4k) in size, so there are probably empty padding out the space between your background and your sprites. To make this more explicit (and show appropriate errors if your files change sizes) consider the following

Code: Select all

.segment "BACKGROUND"
.incbin "background.chr"

.segment "SPRITES"
.incbin "sprite.chr


BACKGROUNDCHR:    start = $0000,  size=$1000, type = ro, file = %O, fill = yes, fillval = $00;
SPRITECHR:    start = $1000,  size=$1000, type = ro, file = %O, fill = yes, fillval = $00;

BACKGROUND:    load =BACKGROUNDCHR, type = ro
SPRITES:    load =SPRITECHR, type = ro
Now you control where the sprite and background data go independent of each other
Last edited by nia_prene on Wed Dec 08, 2021 12:47 pm, edited 3 times in total.
yaofan1212
Posts: 12
Joined: Sat Dec 04, 2021 9:48 am

Re: How the system knows where to load background an sprites?

Post by yaofan1212 »

nia_prene wrote: Wed Dec 08, 2021 12:38 pm
yaofan1212 wrote: Mon Dec 06, 2021 10:35 am .segment "TILES"
.incbin "background.chr"
.incbin "sprite.chr"

Relevant part of config linker file:
CHR: start = $0000, size = $2000, type = ro, file = %O, fill = yes, fillval = $00;
TILES: load = CHR, type = ro;
It looks like you figured it out, but your linker is doing exactly what you told it to do. It is loading your "TILES" segment right into your chr memory area. Since you have .incbin your background tiles first, they are loaded into that memory area first. Your files are probably exactly 256 tiles (4k) in size, so there are probably empty padding out the space between your background and your sprites. To make this more explicit (and show appropriate errors if your files change sizes) consider the following

Code: Select all

.segment "BACKGROUND"
.incbin "background.chr"

.segment "SPRITES"
.incbin "sprite.chr


BACKGROUNDCHR:    start = $0000,  size=$1000, type = ro, file = %O, fill = yes, fillval = $00;
SPRITECHR:    start = $1000,  size=$1000, type = ro, file = %O, fill = yes, fillval = $00;

BACKGROUND:    load =BACKGROUNDCHR, type = ro
SPRITES:    load =SPRITECHR, type = ro
Now you control where the sprite and background data go independent of each other
Thank you very much for your contribution.
Post Reply