base:20-pixel_sprite_interleave
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionLast revisionBoth sides next revision | ||
base:20-pixel_sprite_interleave [2020-10-15 14:40] – raistlin | base:20-pixel_sprite_interleave [2020-10-15 15:02] – raistlin | ||
---|---|---|---|
Line 4: | Line 4: | ||
Original idea and help from Christopher Jam for 20-pixel interleave technique | Original idea and help from Christopher Jam for 20-pixel interleave technique | ||
- | ===== Intro ===== | + | === Intro === |
When using large arrays of sprites, eg. an 8x10 array, it can be tricky to do this without having gaps or glitches. Annoyingly, C64 sprites are 21 pixels tall - so it's not possible to have this array without at least one row of sprites being around a bad line - where there simply aren't enough cycles to update all the sprite values. | When using large arrays of sprites, eg. an 8x10 array, it can be tricky to do this without having gaps or glitches. Annoyingly, C64 sprites are 21 pixels tall - so it's not possible to have this array without at least one row of sprites being around a bad line - where there simply aren't enough cycles to update all the sprite values. | ||
Line 44: | Line 44: | ||
=== Updating Sprite Values === | === Updating Sprite Values === | ||
- | Given all of that, you still need to update all 8 sprite values in as few cycles as possible. And you need to start the update from as close as possible to the right position. | + | Often, especially when dealing with a vertically scrolling screen, or the addition |
For this, it's worth knowing about a neat little trick. | For this, it's worth knowing about a neat little trick. | ||
- | The most basic way to update the sprite values would of course be: | + | The most basic and obvious |
< | < | ||
Line 55: | Line 55: | ||
inx | inx | ||
stx ScreenAddr + $3f8 + 1 | stx ScreenAddr + $3f8 + 1 | ||
- | | + | |
+ | stx ScreenAddr + $3f8 + 2 | ||
+ | inx | ||
+ | stx ScreenAddr + $3f8 + 3 | ||
+ | inx | ||
+ | stx ScreenAddr + $3f8 + 4 | ||
+ | inx | ||
+ | stx ScreenAddr + $3f8 + 5 | ||
+ | inx | ||
+ | stx ScreenAddr + $3f8 + 6 | ||
inx | inx | ||
stx ScreenAddr + $3f8 + 7 | stx ScreenAddr + $3f8 + 7 | ||
</ | </ | ||
- | What matters to us here is the cycle count between our first write to the sprite values and our last. So that's 7x2 + 7x4 = 42. To reduce this, we can use the illegal opcode, SAX:- | + | What matters to us here is the cycle count between our first write to the sprite values and our last. So that's 7x2 + 7x4 = 42 cycles. To reduce this, we can use the illegal opcode, SAX:- |
< | < | ||
LDA #64 + 4 | LDA #64 + 4 | ||
- | LDX #fb | + | LDX #$fb |
- | SAX ScreenAddr + $3f8 + 0; <-- SAX will write A&X .. ie. 64 in this case (we mask out bit 2) | + | SAX ScreenAddr + $3f8 + 0; <-- SAX will write "A & X" |
STA ScreenAddr + $3f8 + 4 | STA ScreenAddr + $3f8 + 4 | ||
INX | INX | ||
SAX ScreenAddr + $3f8 + 1 | SAX ScreenAddr + $3f8 + 1 | ||
- | | + | |
+ | INX | ||
+ | SAX ScreenAddr + $3f8 + 2 | ||
+ | STA ScreenAddr + $3f8 + 6 | ||
INX | INX | ||
SAX ScreenAddr + $3f8 + 3 | SAX ScreenAddr + $3f8 + 3 |