Created
May 5, 2011 07:41
-
-
Save og2t/956683 to your computer and use it in GitHub Desktop.
For Y extended sprite rows with single raster irq (two in fact)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.var spr1X = $d000 | |
.var spr1Y = $d001 | |
.var spr2X = $d002 | |
.var spr2Y = $d003 | |
.var spr3X = $d004 | |
.var spr3Y = $d005 | |
.var spr4X = $d006 | |
.var spr4Y = $d007 | |
.var spr5X = $d008 | |
.var spr5Y = $d009 | |
.var spr6X = $d00a | |
.var spr6Y = $d00b | |
.var spr7X = $d00c | |
.var spr7Y = $d00d | |
.var spr8X = $d00e | |
.var spr8Y = $d00f | |
.var code = $0810 | |
.var startLine = $38 + 38 | |
.var brkFile = createFile("breakpoints.txt") | |
.macro break() | |
{ | |
.eval brkFile.writeln("break " + toHexString(*)) | |
} | |
.pseudocommand nop x { | |
:ensureImmediateArgument(x) | |
.for (var i=0; i<x.getValue(); i++) nop | |
} | |
.pseudocommand pause cycles | |
{ | |
:ensureImmediateArgument(cycles) | |
.var x = floor(cycles.getValue()) | |
.if (x<2) .error "Cant make a pause on " + x + " cycles" | |
// Take care of odd cyclecount | |
.if ([x&1]==1) { | |
bit $00 | |
.eval x=x-3 | |
} | |
// Take care of the rest | |
.if (x>0) | |
:nop #x/2 | |
} | |
.macro ensureImmediateArgument(arg) { | |
.if (arg.getType()!=AT_IMMEDIATE) .error "The argument must be immediate!" | |
} | |
//======================================================================================= | |
:BasicUpstart2(run) | |
.pc = code "code" | |
run: sei | |
lda #$34 | |
sta $01 // copy to the last video bank | |
lda #$35 | |
sta $01 | |
jsr setup | |
lda #$7f | |
sta $dc0d | |
sta $dd0d | |
bit $dc0d | |
lda #$1b | |
sta $d011 | |
lda #$55 | |
sta $3fff | |
jsr vblank | |
lda #62 // set timer interval | |
sta $dc04 | |
lda #$00 | |
sta $dc05 | |
lda #$01 | |
cmp $d012 | |
bne *-3 | |
jsr delay_0 | |
bne *+5 | |
cmp $00 | |
nop | |
jsr delay_1 | |
bne *+4 | |
cmp $00 | |
jsr delay_1-1 | |
beq *+2 | |
lda #$11 // run timer exactly here | |
sta $dc0e | |
lda #<Stable_IRQ | |
sta $fffe | |
lda #>Stable_IRQ | |
sta $ffff | |
lda #1 | |
sta $d01a | |
sta $d019 | |
cli | |
jmp backgroundProcess | |
//--------------------------------------------- | |
delay_0: ldx #$a2 // delay on Timer A CIA | |
ldx #$a2 | |
ldx #$a6 | |
delay_1: nop | |
ldx #$07 | |
dex | |
bne *-1 | |
lda $d012 | |
cmp $d012 | |
rts | |
//--------------------------------------------- | |
Stable_IRQ: pha | |
txa | |
pha | |
tya | |
pha | |
sec | |
lda #$32 | |
sbc $dc04 | |
sta *+4 | |
bpl * | |
lda #LDA_IMM | |
lda #LDA_IMM | |
lda #LDA_IMM | |
lda NOP | |
// stable raster here... cycle 46 | |
display: lda $d012 | |
bne switch | |
// here we are in raster $00 | |
// set the next raster irq to the line before the start line | |
lda #startLine - 1 | |
sta $d012 | |
// first line of the text screen | |
lda #50 | |
sta spr1Y | |
sta spr2Y | |
sta spr3Y | |
sta spr4Y | |
sta spr5Y | |
sta spr6Y | |
sta spr7Y | |
sta spr8Y | |
jmp irqExit | |
switch: | |
// start line | |
// reset the raster | |
lda #0 | |
sta $d012 | |
// perform the sprite crunch trick | |
jmp trick | |
irqExit: inc $d019 | |
pla | |
tay | |
pla | |
tax | |
pla | |
rti | |
.align $100 | |
trick: // set sprites y | |
lda #startLine | |
sta spr1Y | |
sta spr2Y | |
sta spr3Y | |
sta spr4Y | |
sta spr5Y | |
sta spr6Y | |
sta spr7Y | |
sta spr8Y | |
:pause #4 | |
dec $d021 | |
lda #$ff | |
sta $d017 | |
:pause #4 | |
// the trick happens exactly here | |
lda #$00 | |
sta $d017 | |
inc $d021 | |
lda #$ff | |
sta $d017 | |
// wait a line to set the new sprite y | |
:pause #63 | |
// y extended sprites wrapped twice | |
lda #startLine + [2 * 2 * 21] + 1 | |
sta spr1Y | |
sta spr2Y | |
sta spr3Y | |
sta spr4Y | |
sta spr5Y | |
sta spr6Y | |
sta spr7Y | |
sta spr8Y | |
// neither first or last byte of the sprite doesn't have any influence on the effect | |
inc lastByte | |
inc lastByte - 1 | |
inc sprite | |
jmp irqExit | |
// --------------------------------------------------------- | |
setup: lda #$00 | |
sta $d012 | |
lda #$09 | |
sta $d020 | |
lda #$00 | |
sta $d021 | |
// set sprites | |
lda #40 | |
sta spr1X | |
clc | |
adc #24 | |
sta spr2X | |
adc #24 | |
sta spr3X | |
adc #24 | |
sta spr4X | |
adc #24 | |
sta spr5X | |
adc #24 | |
sta spr6X | |
adc #24 | |
sta spr7X | |
adc #24 | |
sta spr8X | |
lda #startLine | |
sta spr1Y | |
sta spr2Y | |
sta spr3Y | |
sta spr4Y | |
sta spr5Y | |
sta spr6Y | |
sta spr7Y | |
sta spr8Y | |
lda #sprite/64 | |
sta $07f8 | |
sta $07f9 | |
sta $07fa | |
sta $07fb | |
sta $07fc | |
sta $07fd | |
sta $07fe | |
sta $07ff | |
lda #%11111111 | |
sta $d015 | |
lda #0 | |
sta $d01b | |
// clear screen | |
ldx #0 | |
lda #32 | |
!: sta $0400,x | |
sta $0500,x | |
sta $0500,x | |
inx | |
bne !- | |
rts | |
vblank: lda $d011 | |
bpl *-3 | |
lda $d011 | |
bmi *-3 | |
rts | |
.align $100 | |
.pc = * "background processes" | |
backgroundProcess: | |
//inc $d020 | |
jmp backgroundProcess | |
// reference to charsets/banks | |
// write data | |
.pc = $2000 "sprite" | |
sprite: .by $55, $55, $55 | |
.by $aa, $aa, $aa | |
.by $55, $55, $55 | |
.by $aa, $aa, $aa | |
.by $55, $55, $55 | |
.by $aa, $aa, $aa | |
.by $55, $55, $55 | |
.by $aa, $aa, $aa | |
.by $55, $55, $55 | |
.by $aa, $aa, $aa | |
.by $55, $55, $55 | |
.by $aa, $aa, $aa | |
.by $55, $55, $55 | |
.by $aa, $aa, $aa | |
.by $55, $55, $55 | |
.by $aa, $aa, $aa | |
.by $55, $55, $55 | |
.by $aa, $aa, $aa | |
.by $55, $55, $55 | |
.by $aa, $aa, $aa | |
.by $55, $55, $ff | |
lastByte: .by $3f | |
/* | |
The normal Struktur of Sprites looks like this: | |
00, 01, 02, | |
03, 04, 05, | |
06, 07, 08, | |
: : : | |
3c, 3d, 3e | |
So there are always 3 Byte-Steps, but if you use Sprite-Crunching, you can change that Struktur. | |
Set the bits of $d017 before the start of the right sideborder and clear them two cycles before the end of the left sideborder and SCR will show its magic! | |
Then the SpritePositionByte (first of the 3 Bytes in a Sprite row) has influence on the effect. | |
Also notice that a Sprite only ends if the SpritePositionByte would be $3f, otherwise the Sprite warps over and starts at $00 or $01 again. | |
1/ SPB of the actual SCR line | |
2/ Diff to the normal step | |
3/ SPB of the next line | |
00: +2 01 01: -1 05 02: impossible | |
03: -1 07 04: +2 05 05: +3 05 | |
06: +4 05 | |
09: -1 | |
0c: ... | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment