HBlank, IRQ and Sprite 0 hit
Moderator: Moderators
HBlank, IRQ and Sprite 0 hit
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?
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.
Re: HBlank, IRQ and Sprite 0 hit
Right, (341-256)/3 = 28.333... CPU cycles on NTSC, (341-256)/3.2 = 26.5625 CPU cycles on PAL.Wave wrote:HBlank is 28 cycles long.
Or timed code all the way from vblank.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)
These can also be done outside of vblank. Also $2000 can be used to change the bg/spr pattern tables.What can be done:
-Modify nametable via $2000
-Modify color intensify / grayscale via $2001
Re: HBlank, IRQ and Sprite 0 hit
What happens if you do it outside hblank?thefox wrote:Right, (341-256)/3 = 28.333... CPU cycles on NTSC, (341-256)/3.2 = 26.5625 CPU cycles on PAL.Wave wrote:HBlank is 28 cycles long.
Or timed code all the way from vblank.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)
These can also be done outside of vblank. Also $2000 can be used to change the bg/spr pattern tables.What can be done:
-Modify nametable via $2000
-Modify color intensify / grayscale via $2001
So changing bg/spr pattern could be used to make a 512 tiles background for example?
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.
-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.
I forgot about bankswitching CHR with mappers, yes, or changing mirroringtepples 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.
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.tepples wrote:But when changing the palette in mid-scanline, you'll probably have to switch scrollXY back before the next scanline.
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.
Isn't a tile 8 pixels long? I don't undersand this very well :Stokumaru wrote: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.tepples wrote:But when changing the palette in mid-scanline, you'll probably have to switch scrollXY back before the next scanline.
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.
Yes, a tile is 8 pixels long... but what is it you don't understand?Wave wrote:Isn't a tile 8 pixels long? I don't undersand this very well :S
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);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.tokumaru wrote:Yes, a tile is 8 pixels long... but what is it you don't understand?Wave wrote:Isn't a tile 8 pixels long? I don't undersand this very well :S
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:
The fine X scroll is stored elsewhere.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);
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 understand how it works now
Last edited by Wave on Fri Dec 10, 2010 4:40 pm, edited 1 time in total.
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?
-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?
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.Wave wrote:To change scrollX, can I write to $2005 the same value twice?
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.While waiting for the scanline, to unify code, I can call BRK when I reach the hblank can't I?