Hi,
I want to make a titlescreen which uses many tiles, without removing some less important still at least 2 pages. Can I show background gfx from more than one page at the same time?
You can use an interrupt or timed code to switch CHR banks (through a mapper) or switch pattern tables (through $2000). Also, I think the MMC5 mapper can let you use both tables with its EXRAM ... does anyone know more about it?
The 'sprite 0 hit' waiting trick is always available. It's especially useful with the simpler carts (CNROM, UNROM, etc.), for switching tiles once or beginning the timed code to switch more tiles in.
Don't wanna use MMC5 for just a simple Pong-Clone. I've heard about that sprite 0 trick, but how does it work?
To use it, you choose which scanline you want it to happen on, then you put sprite zero one that line, but it has to be on top of non-transparent background pixels.
Then you have a routine like this, that waits for the PPU to get to that part of the screen where sprite zero is.
Code:
sprite_sync:
lda $2002
and #$40
bne sprite_sync
sync_up2:
lda $2002
and #$40
beq sync_up2
rts
Even better, take advantage of the fact that the BIT instruction transfers bit 6 (which happens to be where the sprite 0 hit flag is in $2002) into the 'overflow' flag:
Code:
wait_spr0:
- BIT $2002
BVS -
- BIT $2002
BVC -
RTS
Yep, that's much better. The shorter loop will allow a more precise response.
I assume I have to insert the code between this:
Code:
waitblank:
lda $2002
bpl waitblank
Does this code already switch between banks or does is just wait 'till the scanline with sprite 0 in it is drawn? (never used more than one bank yet)
The code I posted does 2 things:
1. It waits for the sprite 0 hit flag to be CLEARED, so you know you've started rendering the next frame.
2. It waits for the sprite 0 hit flag to be SET, so you know when to swap in the new graphics bank.
I've finally drawn the background, now I want to insert it. When I reached sprite 0's position, how can I switch the banks?
Depends on where your graphics are loaded. Once sprite #0 is hit, write to the CHR bankswitch register, or swap to the other half of the 4kB pattern table with the $2000 reg.
And be sure to select your first graphics bank at the beginning of the frame.
How can I swap between the banks?
Why do I have to switch to bank 0 at beginning? I would need bank 1 for the first lines.
Yeah, I don't mean bank 0, but just whichever is the first one graphics-wise.
I'll need to know which mapper you're using to say how to swap banks, but if your CHR is only 8kB you'll need to toggle D4 of the $2000 register.
Good. I didn't program anything 'bout the titlescreen yet, I need to know where to include the background-tiles file.
Code:
.bank 2 ; switch to bank 2
.org $0000 ; start at $0000
.incbin "pong.bkg" ; background
.incbin "pong.spr" ; sprite data
I know those files must be included in a specific order, can I just add the second bkg-file or must it be before the sprite file?
BKG and SPR are just 4kB of tile data, correct? If it is, then it doesn't matter which order they're in. The NES can swap those 2 banks already, using the $2000 register.
But if there's more than 2 of these 4kB pages, you'll need to use bankswitching. CNROM (iNES mapper #3) is a good and simple one, that uses 32kB of CHR-ROM.
Ok, then I'll use mapper 3. I've used mapper 0 until now. Can you give me the code for switching now?
Sure, it's real easy. Have something like this:
Code:
lda #0 ;(select bank number here)
tax
sta bankpages,x
bankpages: .byte 0,1,2,3
Because of bus conflicts, you have to write a value to ROM only where that same value is already so it'll work on a real cart. The bankpages label and indexed write to it takes care of that.
Ok I now use mapper 3 (.inesmap 3, is this correct?).
I changed your .byte to .db because nesasm didn't like that.
The rest of your code was put into a subroutine which was executed on start, just for testing if I see different tiles now. But still the first bank is used.
I incbin'ed the second background layer after the sprite layer.
You should have 4 CHR pages, 32kB. So the ROM will be 64kB in total. Also be sure the iNES header is set for 4 CHR pages.
It still doesn't work.
I've included four char files (32kb). But why should the rom then be 64kb big? At the moment its size is 32kb.
Maybe the problem is the bankpages variable. Is it correct that it's .org'd at $0000? Or could it be that it's because I wrote .db instead of .byte?
The rom should be 64kB because mapper 3 is always 32kB PRG + 32kB CHR.
The bankpages label needs to be in ROM, $0000 would be RAM. Put it anywhere between $8000 to $FFFF and see if that helps.
It worked! Thanks a lot!
Now with Mapper 3 do I still have to use the sprite 0 trick? If yes, please explain Quietust's code once more: I know that the code to switch between banks in one frame has to be somewhere in the wait-for-vBlank loop. Why is he using a subroutine? And how do I put sprite 0 in a line? Is sprite 0 always the first sprite defined at $0200? Then I have to rewrite much code...