HBlank, IRQ and Sprite 0 hit

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

Wave
Posts: 110
Joined: Mon Nov 16, 2009 5:59 am

HBlank, IRQ and Sprite 0 hit

Post by Wave »

I'm trying to fit in a "library" all special efects that can be done (at least 90%) in hblank.
There's all the info i've gathered about this:
HBlank is 28 cycles long.
How to get to that 28 cycles:
MMC3 with IRQ or other mapper.
Sprite 0 hit and wait with timed code (only once per frame)

What can be done:
-Modify nametable via $2000
-Modify color intensify / grayscale via $2001
-Modify palette (only a few bytes though, could be used to change background colour)
-Change scrollX via $2005
-Change scrollXY via $2005/$2006
-Bankswitch chr via mapper
-Change mirroring via mapper

After that 28 cycles other operations can be done on irq that doesn't affect drawing.

Is that correct? Are there some pre/postrequisites to do this effects?
what else could be done?
Last edited by Wave on Thu Dec 09, 2010 6:02 am, edited 1 time in total.
User avatar
thefox
Posts: 3139
Joined: Mon Jan 03, 2005 10:36 am
Location: Tampere, Finland
Contact:

Re: HBlank, IRQ and Sprite 0 hit

Post by thefox »

Wave wrote:HBlank is 28 cycles long.
Right, (341-256)/3 = 28.333... CPU cycles on NTSC, (341-256)/3.2 = 26.5625 CPU cycles on PAL.
How to get to that 28 cycles:
MMC3 with IRQ or other mapper.
Sprite 0 hit and wait with timed code (only once per frame)
Or timed code all the way from vblank.
What can be done:
-Modify nametable via $2000
-Modify color intensify / grayscale via $2001
These can also be done outside of vblank. Also $2000 can be used to change the bg/spr pattern tables.
Wave
Posts: 110
Joined: Mon Nov 16, 2009 5:59 am

Re: HBlank, IRQ and Sprite 0 hit

Post by Wave »

thefox wrote:
Wave wrote:HBlank is 28 cycles long.
Right, (341-256)/3 = 28.333... CPU cycles on NTSC, (341-256)/3.2 = 26.5625 CPU cycles on PAL.
How to get to that 28 cycles:
MMC3 with IRQ or other mapper.
Sprite 0 hit and wait with timed code (only once per frame)
Or timed code all the way from vblank.
What can be done:
-Modify nametable via $2000
-Modify color intensify / grayscale via $2001
These can also be done outside of vblank. Also $2000 can be used to change the bg/spr pattern tables.
What happens if you do it outside hblank?
So changing bg/spr pattern could be used to make a 512 tiles background for example?
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

The title screen of Smash TV bankswitches the background pattern table multiple times. So I'll add to the list:

-Modify pattern table via mapper ports or $2000

But when changing the palette in mid-scanline, you'll probably have to switch scrollXY back before the next scanline.
Last edited by tepples on Thu Dec 09, 2010 6:11 am, edited 1 time in total.
Wave
Posts: 110
Joined: Mon Nov 16, 2009 5:59 am

Post by Wave »

tepples wrote:The title screen of Smash TV bankswitches the background pattern table multiple times. So I'll add to the list:

-Modify pattern table via mapper ports

But when changing the palette in mid-scanline, you'll probably have to switch scrollXY back before the next scanline.
I forgot about bankswitching CHR with mappers, yes, or changing mirroring
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

tepples wrote:But when changing the palette in mid-scanline, you'll probably have to switch scrollXY back before the next scanline.
Yeah, the bitch about HBlank effects that mess with $2006 is that you have to fix the scroll later, and unless you want to set it to the top half of the tile (i.e. fine Y scroll of 3 or less), that can't be done quickly.

If the fine Y scroll is supposed to be 3 or less, than just 2 writes to $2006 are enough to fix the scroll, otherwise you have to also write to $2005 and there will hardly be enough time for an actual effect other than a scroll change.

EDIT: changed 7 to 3.
Last edited by tokumaru on Fri Dec 10, 2010 8:46 am, edited 1 time in total.
Wave
Posts: 110
Joined: Mon Nov 16, 2009 5:59 am

Post by Wave »

tokumaru wrote:
tepples wrote:But when changing the palette in mid-scanline, you'll probably have to switch scrollXY back before the next scanline.
Yeah, the bitch about HBlank effects that mess with $2006 is that you have to fix the scroll later, and unless you want to set it to the top half of the tile (i.e. fine Y scroll of 7 or less), that can't be done quickly.

If the fine Y scroll is supposed to be 7 or less, than just 2 writes to $2006 are enough to fix the scroll, otherwise you have to also write to $2005 and there will hardly be enough time for an actual effect other than a scroll change.
Isn't a tile 8 pixels long? I don't undersand this very well :S
tepples
Posts: 22345
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Post by tepples »

The $2006-$2005-$2005-$2006 write sequence during rendering can set the VRAM address to any line. Using two writes to $2006 alone during rendering can set the VRAM address to lines 0 through 3, 8 through 11, 16 through 19, ..., 232 through 235, but not the lines in between.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

Wave wrote:Isn't a tile 8 pixels long? I don't undersand this very well :S
Yes, a tile is 8 pixels long... but what is it you don't understand?

If you look at loopy's scrolling document, you'll see that the VRAM register, which is used for accessing PPU data and for the scroll, has the following format:

Code: Select all

0yyyNNYYYYYXXXXX

XXXXX: X coordinate of the tile in the name table;
YYYYY: Y coordinate of the tile in the name table;
NN: name table;
yyy: fine Y scroll (pixel within the tile);
The fine X scroll is stored elsewhere.

Anyway, at first glance, it seems like you can easily restore the scroll by writing the value using the format above to $2006, but the catch is that the first write to $2006 clears the top 2 bits. This is a problem because bit 14 is part of the fine Y scroll. Since this bit is forced to 0, the only possible fine scroll values are 000 (0), 001 (1), 010 (2) and 011 (3), so you can only reset the scroll to the top half of the tile.

By combining $2006 writes with $2005 writes (i.e. $2006, $2005, $2005, $2006) it's possible to set all the fields, but that would take too long to do during HBlank after another PPU memory operation.
Wave
Posts: 110
Joined: Mon Nov 16, 2009 5:59 am

Post by Wave »

tokumaru wrote:
Wave wrote:Isn't a tile 8 pixels long? I don't undersand this very well :S
Yes, a tile is 8 pixels long... but what is it you don't understand?

If you look at loopy's scrolling document, you'll see that the VRAM register, which is used for accessing PPU data and for the scroll, has the following format:

Code: Select all

0yyyNNYYYYYXXXXX

XXXXX: X coordinate of the tile in the name table;
YYYYY: Y coordinate of the tile in the name table;
NN: name table;
yyy: fine Y scroll (pixel within the tile);
The fine X scroll is stored elsewhere.

Anyway, at first glance, it seems like you can easily restore the scroll by writing the value using the format above to $2006, but the catch is that the first write to $2006 clears the top 2 bits. This is a problem because bit 14 is part of the fine Y scroll. Since this bit is forced to 0, the only possible fine scroll values are 000 (0), 001 (1), 010 (2) and 011 (3), so you can only reset the scroll to the top half of the tile.

By combining $2006 writes with $2005 writes (i.e. $2006, $2005, $2005, $2006) it's possible to set all the fields, but that would take too long to do during HBlank after another PPU memory operation.
I thought you said you only have to change the fine scroll if it was 7 or less and that would've been always.
I understand how it works now :)
Last edited by Wave on Fri Dec 10, 2010 4:40 pm, edited 1 time in total.
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

Wave wrote:I thought you said you only have to change the fine scroll if it was 7 or less and that would've been allways.
Hehe, sory about that, my mistake! =) I meant 3 or less.
Wave
Posts: 110
Joined: Mon Nov 16, 2009 5:59 am

Post by Wave »

I think I'm gonna drop:
-Modify palette (only a few bytes though, could be used to change background colour)

And go for:
-Modify nametable via $2000
-Modify color intensify / grayscale via $2001
-Change scrollX via $2005
-Change scrollXY via $2005/$2006
-Bankswitch chr via mapper
-Change mirroring via mapper

To change scrollX, can I write to $2005 the same value twice?

While waiting for the scanline, to unify code, I can call BRK when I reach the hblank can't I?
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

Wave wrote:To change scrollX, can I write to $2005 the same value twice?
Yeah, you can write anything the second time and it won't cause any changes to the current frame. Whatever you write will still affect the Y bits of the temporary VRAM register though, so if you do something that causes the temporary register to be copied to the real register (i.e. a second write to $2006), you should have valid data for the Y scroll.
While waiting for the scanline, to unify code, I can call BRK when I reach the hblank can't I?
You mean so that the IRQ code performs the effects the same way no matter if it was triggered by a mapper or not? I guess that's OK.
User avatar
Dwedit
Posts: 4470
Joined: Fri Nov 19, 2004 7:35 pm
Contact:

Post by Dwedit »

You could also read PPUSTAT instead of a second PPUSCROLL write.
Here come the fortune cookies! Here come the fortune cookies! They're wearing paper hats!
User avatar
tokumaru
Posts: 12106
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Post by tokumaru »

Dwedit wrote:You could also read PPUSTAT instead of a second PPUSCROLL write.
True. If you have a free register (the one you just used to write the X scroll being a good candidate) that would be the best choice.
Post Reply