;-------------------------------------------------------------------------
RasterRow = $2d ; May not be a line with sprites or a badline
_rx = $03
_ry = $04
_pageflip = $05
;-------------------------------------------------------------------------
* = $0801
;-------------------------------------------------------------------------
;- SYS $0810
;-------------------------------------------------------------------------
.byte $0c, $08, $00, $00, $9e, $20, $32, $30
.byte $36, $34, $00, $00, $00, $00, $00
;-------------------------------------------------------------------------
* = $0810
;-------------------------------------------------------------------------
sei
;-------------------------------------------------------------------------
; Turn all sprites off
;-------------------------------------------------------------------------
lda #$00
sta $d021
sta $d020
sta $d015
;-------------------------------------------------------------------------
; Wait for VBLANC
;-------------------------------------------------------------------------
bit $d011
bpl * - 3
bit $d011
bmi * - 3
;-------------------------------------------------------------------------
; Perform halfvariance polling
;-------------------------------------------------------------------------
.page
ldx $d012
inx
cpx $d012
bne * - 3
ldy #$0a
dey
bne * - 1
inx
cpx $d012
nop
beq Time_1
nop
bit $24
Time_1 ldy #$09
dey
bne * - 1
nop
nop
inx
cpx $d012
nop
beq Time_2
bit $24
Time_2 ldy #$0a
dey
bne * - 1
inx
cpx $d012
bne Time_3
Time_3 nop
nop
nop
nop
nop
;-------------------------------------------------------------------------
; Raster is stable here.
; Launch a continous timer which a count of 63.
;-------------------------------------------------------------------------
lda #$3e
sta $dc04
sty $dc05
lda #$11
sta $dc0e
.endp
;-------------------------------------------------------------------------
; Initialize everything needed to be inited here
;-------------------------------------------------------------------------
; Set multicolor-mode and turn on the bitmap, in the process set
; the high end of the raster to 0, point the screenmemory to
; $0000 - $3fff, allocated positions are:
; Bitmap @ $4000
; Screen 1 = $6000
; Screen 2 = $6400
; Screen 3 = $6800 (For doublebuffering)
; Screen 4 = $6c00 (For doublebuffering)
lda #$3b
sta $d011
lda $d016
ora #%00010000
sta $d016
lda $dd00
and #%11111100
ora #%00000010
sta $dd00
ldx #0
stx _pageflip
lda #%10100101
FillScreen
sta $4000, x
sta $4100, x
sta $4200, x
sta $4300, x
sta $4400, x
sta $4500, x
sta $4600, x
sta $4700, x
sta $4800, x
sta $4900, x
sta $4a00, x
sta $4b00, x
sta $4c00, x
sta $4d00, x
sta $4e00, x
sta $4f00, x
sta $5000, x
sta $5100, x
sta $5200, x
sta $5300, x
sta $5400, x
sta $5500, x
sta $5600, x
sta $5700, x
sta $5800, x
sta $5900, x
sta $5a00, x
sta $5b00, x
sta $5c00, x
sta $5d00, x
sta $5e00, x
sta $5f00, x
inx
bne FillScreen
SetColorloop
lda #$9e
sta $6000, x
lda #$2f
sta $6400, x
lda #$57
sta $6100, x
lda #$8a
sta $6500, x
lda #$c1
sta $6200, x
lda #$bd
sta $6600, x
lda #$10
sta $6300, x
lda #$f6
sta $6700, x
lda #$69
sta $6000 + $800, x
lda #$2b
sta $6400 + $800, x
lda #$58
sta $6100 + $800, x
lda #$83
sta $6500 + $800, x
lda #$f1
sta $6200 + $800, x
lda #$be
sta $6600 + $800, x
lda #$10
sta $6300 + $800, x
lda #$a6
sta $6700 + $800, x
inx
bne SetColorloop
;-------------------------------------------------------------------------
; Setup irq-code
;-------------------------------------------------------------------------
lda #$7f
sta $dc0d
sta $dd0d
lda #1
sta $d01a
sta $d019
;-------------------------------------------------------------------------
; Setup interrupt position
;-------------------------------------------------------------------------
lda #RasterRow
sta $d012
;-------------------------------------------------------------------------
lda #$35
sta $01
lda #irq
sta $ffff
lda $dc0d
lda $dd0d
asl $d019
;-------------------------------------------------------------------------
; Setup the nmi-irq
;-------------------------------------------------------------------------
lda #nmiirq
sta $fffb
;-------------------------------------------------------------------------
; Setup the timer adjusted to work every eight row, (63 * 8) - 1 cycles
;-------------------------------------------------------------------------
lda #$f7
sta $dd04
lda #$01
sta $dd05
cli
;-------------------------------------------------------------------------
; Here is the maincode executed
;-------------------------------------------------------------------------
MainCode
lda _pageflip
eor #$ff
sta _pageflip
jmp MainCode
;-------------------------------------------------------------------------
irq
;-------------------------------------------------------------------------
; Save the registers
;-------------------------------------------------------------------------
pha
php
stx _rx
sty _ry
;-------------------------------------------------------------------------
; Stabilize the raster
;-------------------------------------------------------------------------
lda $dc04
and #7
sta Time_4 + 1
lda #7
sec
Time_4 sbc #4
sta Time_5 + 1
.page
Time_5 bpl * + 2
cmp #$c9
cmp #$c9
cmp #$c9
cmp #$24
nop
.endp
;-------------------------------------------------------------------------
; Stable raster here, start the nmi-irq if the raster is on the beginning of the screen
;-------------------------------------------------------------------------
.page
lda $d012
cmp #RasterRow + 8
bcs StopNMI
lda _pageflip ;3 3
bmi _page_2 ;2 3 5 6
lda #$81 ;2 7
sta _p_2 + 1 ;4 11
lda #$91 ;2 13
sta _p_1 + 1 ;4 17
nop ;2 19
jmp start_nmi ;3 22
_page_2 lda #$a1 ; 2 8
sta _p_2 + 1 ; 4 12
lda #$b1 ; 2 14
sta _p_1 + 1 ; 4 18
nop ; 2 20
nop ; 2 22
start_nmi
bit $ea ;3 3 25 25
.endp
lda #$11
sta $dd0e
lda #$81
sta $dd0d
lda $dd0d
;-------------------------------------------------------------------------
; Set raster-row for ending the NMI here
;-------------------------------------------------------------------------
lda #$f8
sta $d012
;-------------------------------------------------------------------------
; Restore all registers
;-------------------------------------------------------------------------
plp
pla
ldx _rx
ldy _ry
;-------------------------------------------------------------------------
; Return from irq here
;-------------------------------------------------------------------------
asl $d019
rti
;-------------------------------------------------------------------------
; Stop the NMI-irq, play music and stuff
;-------------------------------------------------------------------------
StopNMI
lda _p_2 + 1 ; Restore $d018 for the first row
sta $d018
lda #RasterRow
sta $d012
lda #$00
sta $dd0e
;-------------------------------------------------------------------------
; Restore all registers
;-------------------------------------------------------------------------
plp
pla
ldx _rx
ldy _ry
;-------------------------------------------------------------------------
; Return from irq here
;-------------------------------------------------------------------------
asl $d019
rti
nmiirq
;-------------------------------------------------------------------------
; Stabilize the raster
;-------------------------------------------------------------------------
sta reg_a + 1
lda $dd04
eor #$e7
sta time_6 + 1
.page
time_6 bpl *
cmp #$c9
cmp #$c9
cmp #$24
nop
.endp
;-------------------------------------------------------------------------
; Stable raster here, create badline for fli and restore to next badline
;-------------------------------------------------------------------------
_p_1 lda #$91
sta $d018
lda #$3f
sta $d011
_p_2 lda #$81
sta $d018
lda #$3b
sta $d011
;-------------------------------------------------------------------------
; Trigger new NMI, restore A and return from IRQ here
;-------------------------------------------------------------------------
lda $dd0d
reg_a lda #0
rti
; .byte $c9, $c9, $c9, $c9, $c9, $c9, $c9, $c9, $c9, $c9
; .byte $c9, $c9, $c9, $c9, $c9, $c9, $c9, $c9, $c9, $c9
; .byte $c9, $c9, $c9, $c9, $c9, $c9, $c9, $c9, $c9, $c9
; .byte $c9, $c9, $c9, $c9, $c9, $c9, $c9, $c9, $c9, $c9
; .byte $c9, $c9, $c9, $c9, $c9, $c9, $c9, $c9, $c9, $c9
; .byte $c9, $c9, $c9, $c9, $c9, $c9, $c9, $c9, $c9, $c9
; bit $ea
=== Pitfalls ===
by Bitbreaker/Oxyron* (the code example is not mine, it was here before, i just added some rant)
FIXME
isn't it a bad idea to do the following, as the asl clobbers the carry:
plp
pla
asl $d019
rti
So better pull P and A after asl $d019. However the processor status is anyway pushed to the stack on an interrupt and restored by the rti.
Also the NMIIRQ does not work with both CIA types, one might use two different NMI-handlers:
In case of using a new CIA you better waste an additional cycle by:
sta $06
nop
lda $dd04
eor #$e7
...
lda $06
rti