#define poke(addr,val) .(:lda #val:sta addr:.) #define doke(addr,val) .(:lda #<val:sta addr:lda #>val:sta addr+1:.) #define endIRQ pla:tay:pla:tax:pla:rti #define ackIRQ pha:lda $d019:sta $d019:txa:pha:tya:pha *= $0801-2 .word *+2 ; load address .byt $0b,$08,$0a,$00,$9e,$32,$30,$36,$31,0,0,0 ; 10 sys2061 main: poke($d021,$04) sta 646 lda#147 jsr $ffd2 poke($d021,0) poke($0400,1) ;something to see poke($0428,2) jsr IRQstart loop: inc $7e7 ; a nice untidy main loop to ensure instability! bpl loop jmp loop IRQstart poke($dc0d,$7f) ; kill CIA irq sei poke($01, $35) ; disable ROM poke($d01a,$01) ; enable VIC irq poke($d011,$1b) ; clear high bit of irq rasterline poke($d012,$32) ; last invisible line doke($fffe,irq1 ) ; set irq vector cli rts irq1: ackIRQ poke($d020,$0f) ; this is unstable! poke($d011,$1a) ; force partial badline before screen starts poke($d020,$0b) ; this is stable ^_^ poke($d011,$1b) ; trigger normal re-fetch of first row of chars poke($d012,$ff) ; set end-of-screen irq doke($fffe,irq2 ) endIRQ irq2: ackIRQ ;ensure first row of chars is already being displayed when badline forced by irq1 poke($d011,$18) poke($d012,$32 ) doke($fffe,irq1 ) endIRQ
when you need to stabilize every N raster lines, there's a huge gain from using CIA timers since you can stabilize anywhere on a line. Hermit's init code on codebase64 is nice and compact and can be generalized to give you a 63 or 65 cycle counter, and it's smooth sailing after that. Conceptually I don't think it's much more complicated than the double IRQ, and not as crazy as putting a jmp instruction at $dc02-$dc04.
Therefore, in my code I did not use a raster interrupt but just waited in the main routine for $d01f to become unequal to zero: sei ... ;Place sprites ... lda $d01f ;Clear sprite-to-background collision register lda #$ff ; Turn sprites on sta $d015 lda $d01f ; Wait for nonzero collision bits beq *-3 ; ;Add delay depending on number of zero bits asl bcc *+2 ... ... ;Set timer ;Continue main program cli rts
Quote:when you need to stabilize every N raster lines, there's a huge gain from using CIA timers since you can stabilize anywhere on a line. Hermit's init code on codebase64 is nice and compact and can be generalized to give you a 63 or 65 cycle counter, and it's smooth sailing after that. Conceptually I don't think it's much more complicated than the double IRQ, and not as crazy as putting a jmp instruction at $dc02-$dc04. IMHO in pretty much all cases that justify using this timer method you'd also want to use the mentioned "ninja method" (best term ever :=)) for ACKing the interrupt, because every single cycle counts in these cases :)
I have a question regarding the cia-timer method: When setting $dc04 to #8, will the timer really count only from 7..1?