- replaces Apple IIc, IIc+ VBL ProDOS interrupt handler with direct $C019 polling
- removes a few pieces of unused code
- added comments and changed formatting (sorry) for consistency
This commit is contained in:
Dagen Brock 2020-03-19 04:34:14 -05:00 committed by Dagen Brock
commit 2a002b1c07
13 changed files with 3059 additions and 3228 deletions

1
.gitignore vendored
View File

@ -8,4 +8,3 @@ src/*_Output.txt
src/*.system
flapple800.po
flapple140.po

View File

@ -14,6 +14,8 @@ fi
#revert file to original state (MONO=0)
sed -i.bak "s/^MONO\(.*\)equ.*/MONO\1equ 0/g" src/flapple.s
rm src/flapple.s.bak
./make_po.sh
gsplus

View File

@ -1,23 +1,24 @@
**************************************************
* Apple Standard Memory Locations
**************************************************
CLRLORES equ $F832
LORES equ $C050
TXTSET equ $C051
MIXCLR equ $C052
MIXSET equ $C053
TXTPAGE1 equ $C054
TXTPAGE2 equ $C055
KEY equ $C000
C80STOREOFF equ $C000
C80STOREON equ $C001
STROBE equ $C010
SPEAKER equ $C030
VBL equ $C02E
RDVBLBAR equ $C019 ;not VBL (VBL signal low
CLRLORES equ $F832
LORES equ $C050
TXTSET equ $C051
MIXCLR equ $C052
MIXSET equ $C053
TXTPAGE1 equ $C054
TXTPAGE2 equ $C055
KEY equ $C000
C80STOREOFF equ $C000
C80STOREON equ $C001
STROBE equ $C010
SPEAKER equ $C030
VBL equ $C02E
RDVBLBAR equ $C019 ;not VBL (VBL signal low
RAMWRTAUX equ $C005
RAMWRTMAIN equ $C004
SETAN3 equ $C05E ;Set annunciator-3 output to 0
SET80VID equ $C00D ;enable 80-column display mode (WR-only)
RAMWRTAUX equ $C005
RAMWRTMAIN equ $C004
SETAN3 equ $C05E ;Set annunciator-3 output to 0
SET80VID equ $C00D ;enable 80-column display mode (WR-only)

View File

@ -1,488 +1,466 @@
SPRITE_X db 0
SPRITE_Y db 0 ; BYTE,not pixel. gotta be, sorry
SPRITE_W db 0
SPRITE_W_D2 db 0
SPRITE_H db 0 ; <- in bytes
SPRITE_X db 0
SPRITE_Y db 0 ; BYTE,not pixel. gotta be, sorry
SPRITE_W db 0
SPRITE_W_D2 db 0
SPRITE_H db 0 ; <- in bytes
SPRITE_MAIN da 0
SPRITE_AUX da 0
SPRITE_MASK da 0
SPRITE_IMASK da 0
SPRITE_COLLISION db 0
SPRITE_Y_IDX dw 0
SPRITE_X_IDX dw 0
SPRITE_MAIN da 0
SPRITE_AUX da 0
SPRITE_MASK da 0
SPRITE_IMASK da 0
SPRITE_COLLISION db 0
SPRITE_Y_IDX dw 0
SPRITE_X_IDX dw 0
SPRITE_SCREEN_P equ $00
SPRITE_DATA_P equ $02
SPRITE_SCREEN_P2 equ $02
SPRITE_AUX_P equ $04
SPRITE_SCREEN_P3 equ $04
SPRITE_MASK_P equ $FA
SPRITE_SCREEN_P4 equ $FA
SPRITE_IMASK_P equ $FC
SPRITE_SCREEN_P equ $00
SPRITE_DATA_P equ $02
SPRITE_SCREEN_P2 equ $02
SPRITE_AUX_P equ $04
SPRITE_SCREEN_P3 equ $04
SPRITE_MASK_P equ $FA
SPRITE_SCREEN_P4 equ $FA
SPRITE_IMASK_P equ $FC
SPRITE_SCREEN_IDX db #$0
SPRITE_SCREEN_IDX db #$0
BIRD_X equ #17
BIRD_Y_INIT equ #17
BIRD_Y db #BIRD_Y_INIT ; (0-47)
BIRD_Y_OLD db #BIRD_Y_INIT ; used for undraw - to decouple input routine from sequence
BIRD_FLAP db #0 ; 0=down 1=up
BIRD_FLAP_RATE equ #5
BIRD_FLAP_CNT db 0
BIRD_VELOCITY db 0 ; in two's compliment {-3,3}
BIRD_VELOCITY_MAX equ #20
BIRD_VELOCITY_MIN equ #%111111111 ; -1
BIRD_WIDTH equ #5
BIRD_X equ #17
BIRD_Y_INIT equ #17
BIRD_Y db #BIRD_Y_INIT ; (0-47)
BIRD_Y_OLD db #BIRD_Y_INIT ; used for undraw - to decouple input routine from sequence
BIRD_FLAP db #0 ; 0=down 1=up
BIRD_FLAP_RATE equ #5
BIRD_FLAP_CNT db 0
**
FlapBird
inc BIRD_FLAP_CNT
lda BIRD_FLAP_CNT
cmp #BIRD_FLAP_RATE
bcs :flapIt
rts
inc BIRD_FLAP_CNT
lda BIRD_FLAP_CNT
cmp #BIRD_FLAP_RATE
bcs :flapIt
rts
:flapIt
lda #0
sta BIRD_FLAP_CNT
inc BIRD_FLAP
lda BIRD_FLAP
cmp #2
bne :noFlip
lda #0
sta BIRD_FLAP
:noFlip rts
lda #0
sta BIRD_FLAP_CNT
inc BIRD_FLAP
lda BIRD_FLAP
cmp #2
bne :noFlip
lda #0
sta BIRD_FLAP
:noFlip rts
***** EVEN then ODD, i.e. AUX then MAIN
BIRD_WUP_E_PIXEL
DO MONO
hex 00,EA,EA,FF,F0,50,D5,A5,0F,00
hex AA,EA,EE,CF,CF,D5,55,8A,90,90
hex 05,AD,A4,08,08,05,5D,51,01,00
ELSE
hex BB,EA,EA,FF,FB,57,D5,A5,0F,77
hex AA,EA,EE,CF,CF,D5,55,8A,90,97
hex B5,AD,A4,B8,B8,75,5D,51,71,77
FIN
DO MONO
hex 00,EA,EA,FF,F0,50,D5,A5,0F,00
hex AA,EA,EE,CF,CF,D5,55,8A,90,90
hex 05,AD,A4,08,08,05,5D,51,01,00
ELSE
hex BB,EA,EA,FF,FB,57,D5,A5,0F,77
hex AA,EA,EE,CF,CF,D5,55,8A,90,97
hex B5,AD,A4,B8,B8,75,5D,51,71,77
FIN
BIRD_WUP_E_MASK
hex FF,00,00,00,0F,0F,00,00,00,FF
hex 00,00,00,00,00,00,00,00,00,0F
hex F0,00,00,F0,F0,F0,00,00,F0,FF
hex FF,00,00,00,0F,0F,00,00,00,FF
hex 00,00,00,00,00,00,00,00,00,0F
hex F0,00,00,F0,F0,F0,00,00,F0,FF
BIRD_WUP_E_IMASK
hex 00,FF,FF,FF,F0,F0,FF,FF,FF,00
hex FF,FF,FF,FF,FF,FF,FF,FF,FF,F0
hex 0F,FF,FF,0F,0F,0F,FF,FF,0F,00
hex 00,FF,FF,FF,F0,F0,FF,FF,FF,00
hex FF,FF,FF,FF,FF,FF,FF,FF,FF,F0
hex 0F,FF,FF,0F,0F,0F,FF,FF,0F,00
***** EVEN then ODD, i.e. AUX then MAIN
BIRD_WDN_E_PIXEL
DO MONO
hex 00,EA,EA,FF,F0,50,D5,A5,0F,00
hex AA,EE,EE,CF,CF,DD,5D,8A,90,90
hex 54,AE,A4,08,08,5D,55,51,01,00
ELSE
hex BB,EA,EA,FF,FB,57,D5,A5,0F,77
hex AA,EE,EE,CF,CF,DD,5D,8A,90,97
hex 54,AE,A4,B8,B8,5D,55,51,71,77
FIN
DO MONO
hex 00,EA,EA,FF,F0,50,D5,A5,0F,00
hex AA,EE,EE,CF,CF,DD,5D,8A,90,90
hex 54,AE,A4,08,08,5D,55,51,01,00
ELSE
hex BB,EA,EA,FF,FB,57,D5,A5,0F,77
hex AA,EE,EE,CF,CF,DD,5D,8A,90,97
hex 54,AE,A4,B8,B8,5D,55,51,71,77
FIN
BIRD_WDN_E_MASK
hex FF,00,00,00,0F,0F,00,00,00,FF
hex 00,00,00,00,00,00,00,00,00,0F
hex 00,00,00,F0,F0,00,00,00,F0,FF
hex FF,00,00,00,0F,0F,00,00,00,FF
hex 00,00,00,00,00,00,00,00,00,0F
hex 00,00,00,F0,F0,00,00,00,F0,FF
BIRD_WDN_E_IMASK
hex 00,FF,FF,FF,F0,F0,FF,FF,FF,00
hex FF,FF,FF,FF,FF,FF,FF,FF,FF,F0
hex FF,FF,FF,0F,0F,FF,FF,FF,0F,00
hex 00,FF,FF,FF,F0,F0,FF,FF,FF,00
hex FF,FF,FF,FF,FF,FF,FF,FF,FF,F0
hex FF,FF,FF,0F,0F,FF,FF,FF,0F,00
***** EVEN then ODD, i.e. AUX then MAIN
BIRD_WUP_O_PIXEL
DO MONO
hex 00,A0,A0,F0,00,00,50,50,F0,00
hex A0,AE,EE,FF,FF,55,5D,AA,00,00
hex 5A,DE,4E,8C,8C,5D,D5,18,19,09
hex 00,0A,0A,00,00,00,05,05,00,00
ELSE
hex BB,AB,AB,FB,BB,77,57,57,F7,77
hex AB,AE,EE,FF,FF,55,5D,AA,00,77
hex 5A,DE,4E,8C,8C,5D,D5,18,19,79
hex BB,BA,BA,BB,BB,77,75,75,77,77
FIN
DO MONO
hex 00,A0,A0,F0,00,00,50,50,F0,00
hex A0,AE,EE,FF,FF,55,5D,AA,00,00
hex 5A,DE,4E,8C,8C,5D,D5,18,19,09
hex 00,0A,0A,00,00,00,05,05,00,00
ELSE
hex BB,AB,AB,FB,BB,77,57,57,F7,77
hex AB,AE,EE,FF,FF,55,5D,AA,00,77
hex 5A,DE,4E,8C,8C,5D,D5,18,19,79
hex BB,BA,BA,BB,BB,77,75,75,77,77
FIN
BIRD_WUP_O_MASK
hex FF,0F,0F,0F,FF,FF,0F,0F,0F,FF
hex 0F,00,00,00,00,00,00,00,00,FF
hex 00,00,00,00,00,00,00,00,00,F0
hex FF,F0,F0,FF,FF,FF,F0,F0,FF,FF
hex FF,0F,0F,0F,FF,FF,0F,0F,0F,FF
hex 0F,00,00,00,00,00,00,00,00,FF
hex 00,00,00,00,00,00,00,00,00,F0
hex FF,F0,F0,FF,FF,FF,F0,F0,FF,FF
BIRD_WUP_O_IMASK
hex 00,F0,F0,F0,00,00,F0,F0,F0,00
hex F0,FF,FF,FF,FF,FF,FF,FF,FF,00
hex FF,FF,FF,FF,FF,FF,FF,FF,FF,0F
hex 00,0F,0F,00,00,00,0F,0F,00,00
hex 00,F0,F0,F0,00,00,F0,F0,F0,00
hex F0,FF,FF,FF,FF,FF,FF,FF,FF,00
hex FF,FF,FF,FF,FF,FF,FF,FF,FF,0F
hex 00,0F,0F,00,00,00,0F,0F,00,00
***** EVEN then ODD, i.e. AUX then MAIN
BIRD_WDN_O_PIXEL
DO MONO
hex 00,A0,A0,F0,00,00,50,50,F0,00
hex A0,EE,EE,FF,FF,D5,DD,AA,00,00
hex 4A,EE,4E,8C,8C,DD,55,18,19,09
hex 05,0A,0A,00,00,05,05,05,00,00
ELSE
hex BB,AB,AB,FB,BB,77,57,57,F7,77
hex AB,EE,EE,FF,FF,D5,DD,AA,00,77
hex 4A,EE,4E,8C,8C,DD,55,18,19,79
hex B5,BA,BA,BB,BB,75,75,75,77,77
FIN
DO MONO
hex 00,A0,A0,F0,00,00,50,50,F0,00
hex A0,EE,EE,FF,FF,D5,DD,AA,00,00
hex 4A,EE,4E,8C,8C,DD,55,18,19,09
hex 05,0A,0A,00,00,05,05,05,00,00
ELSE
hex BB,AB,AB,FB,BB,77,57,57,F7,77
hex AB,EE,EE,FF,FF,D5,DD,AA,00,77
hex 4A,EE,4E,8C,8C,DD,55,18,19,79
hex B5,BA,BA,BB,BB,75,75,75,77,77
FIN
BIRD_WDN_O_MASK
hex FF,0F,0F,0F,FF,FF,0F,0F,0F,FF
hex 0F,00,00,00,00,00,00,00,00,FF
hex 00,00,00,00,00,00,00,00,00,F0
hex F0,F0,F0,FF,FF,F0,F0,F0,FF,FF
hex FF,0F,0F,0F,FF,FF,0F,0F,0F,FF
hex 0F,00,00,00,00,00,00,00,00,FF
hex 00,00,00,00,00,00,00,00,00,F0
hex F0,F0,F0,FF,FF,F0,F0,F0,FF,FF
BIRD_WDN_O_IMASK
hex 00,F0,F0,F0,00,00,F0,F0,F0,00
hex F0,FF,FF,FF,FF,FF,FF,FF,FF,00
hex FF,FF,FF,FF,FF,FF,FF,FF,FF,0F
hex 0F,0F,0F,00,00,0F,0F,0F,00,00
hex 00,F0,F0,F0,00,00,F0,F0,F0,00
hex F0,FF,FF,FF,FF,FF,FF,FF,FF,00
hex FF,FF,FF,FF,FF,FF,FF,FF,FF,0F
hex 0F,0F,0F,00,00,0F,0F,0F,00,00
** y=line a=height x=col
UndrawBird lda BIRD_Y_OLD
lsr
tay
bne :oddBird
:evenBird lda #3
bne :continue
:oddBird lda #4
:continue ldx #BIRD_X
cmp #4
beq :undraw4
:undraw3 lda LoLineTableL,y
sta SPRITE_SCREEN_P
lda LoLineTableH,y
sta SPRITE_SCREEN_P+1
lda LoLineTableL+1,y
sta SPRITE_SCREEN_P2
lda LoLineTableH+1,y
sta SPRITE_SCREEN_P2+1
lda LoLineTableL+2,y
sta SPRITE_SCREEN_P3
lda LoLineTableH+2,y
sta SPRITE_SCREEN_P3+1
UndrawBird lda BIRD_Y_OLD
lsr
tay
bne :oddBird
:evenBird lda #3
bne :continue
:oddBird lda #4
:continue ldx #BIRD_X
cmp #4
beq :undraw4
:undraw3 lda LoLineTableL,y
sta SPRITE_SCREEN_P
lda LoLineTableH,y
sta SPRITE_SCREEN_P+1
lda LoLineTableL+1,y
sta SPRITE_SCREEN_P2
lda LoLineTableH+1,y
sta SPRITE_SCREEN_P2+1
lda LoLineTableL+2,y
sta SPRITE_SCREEN_P3
lda LoLineTableH+2,y
sta SPRITE_SCREEN_P3+1
txa
pha ; stash
tay ; COL offset
sta TXTPAGE2
lda #BGCOLORAUX
:wipe1 sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
iny
:wipe1b sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
iny
:wipe1c sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
iny
:wipe1d sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
iny
:wipe1e sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
txa
pha ; stash
tay ; COL offset
sta TXTPAGE2
lda #BGCOLORAUX
:wipe1 sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
iny
:wipe1b sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
iny
:wipe1c sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
iny
:wipe1d sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
iny
:wipe1e sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
pla ; unstash
tay
sta TXTPAGE1
lda #BGCOLOR
:wipe2 sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
iny
pla ; unstash
tay
sta TXTPAGE1
lda #BGCOLOR
:wipe2 sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
iny
:wipe2b sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
iny
:wipe2c sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
iny
:wipe2d sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
iny
:wipe2e sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
rts
:wipe2b sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
iny
:wipe2c sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
iny
:wipe2d sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
iny
:wipe2e sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
rts
:undraw4 lda LoLineTableL,y
sta SPRITE_SCREEN_P
lda LoLineTableH,y
sta SPRITE_SCREEN_P+1
lda LoLineTableL+1,y
sta SPRITE_SCREEN_P2
lda LoLineTableH+1,y
sta SPRITE_SCREEN_P2+1
lda LoLineTableL+2,y
sta SPRITE_SCREEN_P3
lda LoLineTableH+2,y
sta SPRITE_SCREEN_P3+1
lda LoLineTableL+3,y
sta SPRITE_SCREEN_P4
lda LoLineTableH+3,y
sta SPRITE_SCREEN_P4+1
:undraw4 lda LoLineTableL,y
sta SPRITE_SCREEN_P
lda LoLineTableH,y
sta SPRITE_SCREEN_P+1
lda LoLineTableL+1,y
sta SPRITE_SCREEN_P2
lda LoLineTableH+1,y
sta SPRITE_SCREEN_P2+1
lda LoLineTableL+2,y
sta SPRITE_SCREEN_P3
lda LoLineTableH+2,y
sta SPRITE_SCREEN_P3+1
lda LoLineTableL+3,y
sta SPRITE_SCREEN_P4
lda LoLineTableH+3,y
sta SPRITE_SCREEN_P4+1
txa
pha ; stash
tay ; COL offset
sta TXTPAGE2
lda #BGCOLORAUX
:wipe3 sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P4),y
iny
:wipe3b sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P4),y
iny
:wipe3c sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P4),y
iny
:wipe3d sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P4),y
iny
:wipe3e sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P4),y
txa
pha ; stash
tay ; COL offset
sta TXTPAGE2
lda #BGCOLORAUX
:wipe3 sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P4),y
iny
:wipe3b sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P4),y
iny
:wipe3c sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P4),y
iny
:wipe3d sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P4),y
iny
:wipe3e sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P4),y
pla ; unstash
tay
sta TXTPAGE1
lda #BGCOLOR
:wipe4 sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P4),y
iny
:wipe4b sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P4),y
iny
:wipe4c sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P4),y
iny
:wipe4d sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P4),y
iny
:wipe4e sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P4),y
rts
pla ; unstash
tay
sta TXTPAGE1
lda #BGCOLOR
:wipe4 sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P4),y
iny
:wipe4b sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P4),y
iny
:wipe4c sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P4),y
iny
:wipe4d sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P4),y
iny
:wipe4e sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P4),y
rts
DrawBird
lda BIRD_Y
lsr
bcs :oddHeight
lda BIRD_Y
lsr
bcs :oddHeight
:evenHeight
sta SPRITE_Y
lda #3
sta SPRITE_H
lda BIRD_FLAP
beq :flapDownEven
:flapUpEven CopyPtr BIRD_WUP_E_PIXEL;SPRITE_DATA_P
CopyPtr BIRD_WUP_E_MASK;SPRITE_MASK_P
CopyPtr BIRD_WUP_E_IMASK;SPRITE_IMASK_P
jmp :drawSprite
:flapDownEven CopyPtr BIRD_WDN_E_PIXEL;SPRITE_DATA_P
CopyPtr BIRD_WDN_E_MASK;SPRITE_MASK_P
CopyPtr BIRD_WDN_E_IMASK;SPRITE_IMASK_P
jmp :drawSprite
sta SPRITE_Y
lda #3
sta SPRITE_H
lda BIRD_FLAP
beq :flapDownEven
:flapUpEven CopyPtr BIRD_WUP_E_PIXEL;SPRITE_DATA_P
CopyPtr BIRD_WUP_E_MASK;SPRITE_MASK_P
CopyPtr BIRD_WUP_E_IMASK;SPRITE_IMASK_P
jmp :drawSprite
:flapDownEven CopyPtr BIRD_WDN_E_PIXEL;SPRITE_DATA_P
CopyPtr BIRD_WDN_E_MASK;SPRITE_MASK_P
CopyPtr BIRD_WDN_E_IMASK;SPRITE_IMASK_P
jmp :drawSprite
:oddHeight
sta SPRITE_Y
lda #4
sta SPRITE_H
lda BIRD_FLAP
beq :flapDownOdd
:flapUpOdd CopyPtr BIRD_WUP_O_PIXEL;SPRITE_DATA_P
CopyPtr BIRD_WUP_O_MASK;SPRITE_MASK_P
CopyPtr BIRD_WUP_O_IMASK;SPRITE_IMASK_P
jmp :drawSprite
:flapDownOdd CopyPtr BIRD_WDN_O_PIXEL;SPRITE_DATA_P
CopyPtr BIRD_WDN_O_MASK;SPRITE_MASK_P
CopyPtr BIRD_WDN_O_IMASK;SPRITE_IMASK_P
jmp :drawSprite
sta SPRITE_Y
lda #4
sta SPRITE_H
lda BIRD_FLAP
beq :flapDownOdd
:flapUpOdd CopyPtr BIRD_WUP_O_PIXEL;SPRITE_DATA_P
CopyPtr BIRD_WUP_O_MASK;SPRITE_MASK_P
CopyPtr BIRD_WUP_O_IMASK;SPRITE_IMASK_P
jmp :drawSprite
:flapDownOdd CopyPtr BIRD_WDN_O_PIXEL;SPRITE_DATA_P
CopyPtr BIRD_WDN_O_MASK;SPRITE_MASK_P
CopyPtr BIRD_WDN_O_IMASK;SPRITE_IMASK_P
jmp :drawSprite
:drawSprite
jsr DrawSpriteBetter
rts
*** MAKE IT WORK
BirdTest
lda BIRD_X ;#30 (0-79)
sta SPRITE_X
lda BIRD_Y ;#10 (0-23)
sta SPRITE_Y
lda #5 ;/2 value (we do two passes of 1/2... Aux/Main)
sta SPRITE_W
lda #3 ;/2 value (must be byte aligned vertically
sta SPRITE_H
; CopyPtr BIRD_WDN_MAIN;SPRITE_MAIN_P
; CopyPtr BIRD_WDN_AUX;SPRITE_AUX_P
; CopyPtr BIRD_WDN_MASK;SPRITE_MASK_P
; CopyPtr BIRD_WDN_IMASK;SPRITE_IMASK_P
jsr DrawSpriteBetter
rts
jsr DrawSpriteBetter
rts
* still does collision
DrawSpriteBetter
lda #0
sta SPRITE_X_IDX
:drawLine lda SPRITE_Y ;
tay
lda LoLineTableL,y ; SET SCREEN LINE
sta SPRITE_SCREEN_P
lda LoLineTableH,y
sta SPRITE_SCREEN_P+1
lda #0
sta SPRITE_X_IDX
:drawLine lda SPRITE_Y ;
tay
lda LoLineTableL,y ; SET SCREEN LINE
sta SPRITE_SCREEN_P
lda LoLineTableH,y
sta SPRITE_SCREEN_P+1
lda #BIRD_X ;SPRITE_X ; ADD IN X OFFSET TO SCREEN POSITION
clc ; I think the highest position is $f8
adc SPRITE_SCREEN_P ; eg- Line 18, col 40= $4f8
sta SPRITE_SCREEN_P ; SHOULD NEVER CARRY?
lda #BIRD_X ;SPRITE_X ; ADD IN X OFFSET TO SCREEN POSITION
clc ; I think the highest position is $f8
adc SPRITE_SCREEN_P ; eg- Line 18, col 40= $4f8
sta SPRITE_SCREEN_P ; SHOULD NEVER CARRY?
jmp DrawSpriteLineC
jmp DrawSpriteLineC
]DSLCD_done
inc SPRITE_Y
dec SPRITE_H
lda SPRITE_H
bne :drawLine
rts
inc SPRITE_Y
dec SPRITE_H
lda SPRITE_H
bne :drawLine
rts
DrawSpriteLineC
; EVEN COLS
DD_EVEN lda #0
sta SPRITE_SCREEN_IDX
sta TXTPAGE2
; EVEN COLS
DD_EVEN lda #0
sta SPRITE_SCREEN_IDX
sta TXTPAGE2
:lineLoop
:collisionCheckDrawer
ldy SPRITE_SCREEN_IDX ; GET SCREEN PIXELS
lda (SPRITE_SCREEN_P),y
ldy SPRITE_SCREEN_IDX ; GET SCREEN PIXELS
lda (SPRITE_SCREEN_P),y
ldy SPRITE_X_IDX ; PREP Y INDEX
cmp #BGCOLORAUX ; AUX BGCOLOR @TODO
beq :noCollisionSIMPLE
pha ; SAVE -> STACK
and (SPRITE_IMASK_P),y
cmp #BGCOLORAUX_0LO
beq :noCollision
cmp #BGCOLORAUX_0HI
beq :noCollision
lda #1
sta SPRITE_COLLISION
ldy SPRITE_X_IDX ; PREP Y INDEX
cmp #BGCOLORAUX ; AUX BGCOLOR @TODO
beq :noCollisionSIMPLE
pha ; SAVE -> STACK
and (SPRITE_IMASK_P),y
cmp #BGCOLORAUX_0LO
beq :noCollision
cmp #BGCOLORAUX_0HI
beq :noCollision
lda #1
sta SPRITE_COLLISION
:noCollision
:doPixels pla ; Y=SPRITE X A=BG DATA
and (SPRITE_MASK_P),y ; CUT OUT SPRITE IN BG DATA
ora (SPRITE_DATA_P),y ; OVERLAY OUR SPRITE DATA
ldy SPRITE_SCREEN_IDX
sta (SPRITE_SCREEN_P),y
sec
bcs :donePixel
:doPixels pla ; Y=SPRITE X A=BG DATA
and (SPRITE_MASK_P),y ; CUT OUT SPRITE IN BG DATA
ora (SPRITE_DATA_P),y ; OVERLAY OUR SPRITE DATA
ldy SPRITE_SCREEN_IDX
sta (SPRITE_SCREEN_P),y
sec
bcs :donePixel
:noCollisionSIMPLE
lda (SPRITE_DATA_P),y
ldy SPRITE_SCREEN_IDX
sta (SPRITE_SCREEN_P),y
lda (SPRITE_DATA_P),y
ldy SPRITE_SCREEN_IDX
sta (SPRITE_SCREEN_P),y
:donePixel inc SPRITE_X_IDX
inc SPRITE_SCREEN_IDX
ldy SPRITE_SCREEN_IDX
cpy SPRITE_W
bcc :lineLoop
:donePixel inc SPRITE_X_IDX
inc SPRITE_SCREEN_IDX
ldy SPRITE_SCREEN_IDX
cpy SPRITE_W
bcc :lineLoop
DD_ODD
; ODD COLS
lda #0
sta SPRITE_SCREEN_IDX
sta TXTPAGE1
:lineLoop ;ldy SPRITE_X_IDX ;
;lda (SPRITE_IMASK_P),y
;beq :noPixel
; ODD COLS
lda #0
sta SPRITE_SCREEN_IDX
sta TXTPAGE1
:lineLoop
:collisionCheckDrawer
ldy SPRITE_SCREEN_IDX ; GET SCREEN PIXELS
lda (SPRITE_SCREEN_P),y
ldy SPRITE_X_IDX ; PREP Y INDEX
cmp #BGCOLOR ; MAIN BGCOLOR @TODO
beq :noCollisionSIMPLE
pha ; SAVE -> STACK
and (SPRITE_IMASK_P),y
cmp #BGCOLOR_0LO
beq :noCollision
cmp #BGCOLOR_0HI
beq :noCollision
lda #1
sta SPRITE_COLLISION
ldy SPRITE_SCREEN_IDX ; GET SCREEN PIXELS
lda (SPRITE_SCREEN_P),y
ldy SPRITE_X_IDX ; PREP Y INDEX
cmp #BGCOLOR ; MAIN BGCOLOR @TODO
beq :noCollisionSIMPLE
pha ; SAVE -> STACK
and (SPRITE_IMASK_P),y
cmp #BGCOLOR_0LO
beq :noCollision
cmp #BGCOLOR_0HI
beq :noCollision
lda #1
sta SPRITE_COLLISION
:noCollision
:doPixels pla ; Y=SPRITE X A=BG DATA
and (SPRITE_MASK_P),y ; CUT OUT SPRITE IN BG DATA
ora (SPRITE_DATA_P),y ; OVERLAY OUR SPRITE DATA
ldy SPRITE_SCREEN_IDX
sta (SPRITE_SCREEN_P),y
sec
bcs :donePixel
:doPixels pla ; Y=SPRITE X A=BG DATA
and (SPRITE_MASK_P),y ; CUT OUT SPRITE IN BG DATA
ora (SPRITE_DATA_P),y ; OVERLAY OUR SPRITE DATA
ldy SPRITE_SCREEN_IDX
sta (SPRITE_SCREEN_P),y
sec
bcs :donePixel
:noCollisionSIMPLE
lda (SPRITE_DATA_P),y
ldy SPRITE_SCREEN_IDX
sta (SPRITE_SCREEN_P),y
lda (SPRITE_DATA_P),y
ldy SPRITE_SCREEN_IDX
sta (SPRITE_SCREEN_P),y
:donePixel inc SPRITE_X_IDX
inc SPRITE_SCREEN_IDX
ldy SPRITE_SCREEN_IDX
cpy SPRITE_W
bcc :lineLoop
jmp ]DSLCD_done
:donePixel inc SPRITE_X_IDX
inc SPRITE_SCREEN_IDX
ldy SPRITE_SCREEN_IDX
cpy SPRITE_W
bcc :lineLoop
jmp ]DSLCD_done

File diff suppressed because it is too large Load Diff

View File

@ -9,21 +9,15 @@
typ $ff ; set P8 type ($ff = "SYS") for output file
xc off ; @todo force 6502?
xc off
MLI equ $bf00
; Sorry, I gotta have some macros.. this is merlin format after all
; You might as well take advantage of your tools :P
CopyPtr MAC
lda #<]1 ; load low byte
sta ]2 ; store low byte
lda #>]1 ; load high byte
sta ]2+1 ; store high byte
<<<
; HANDLE GREENSCREEN DOODS... MONO flag set 0 = color mode, 1 = mono mode
MONO equ 0
* Change this flag to build either color/mono version
* 0 = color mode, 1 = mono mode
* The main difference is that it uses a black background so playfield is more visible on B/W screens
MONO equ 0
DO MONO
* MONO VERSION BUILD
dsk fmono.system ; tell compiler output filename
BGCOLOR equ #$00
BGCOLORAUX equ #$00
@ -32,8 +26,8 @@ BGCOLOR_0HI equ #$00
BGCOLORAUX_0LO equ #$00
BGCOLORAUX_0HI equ #$00
; HANDLE COLOR DOODS
ELSE
* COLOR VERSION BUILD
dsk flap.system ; tell compiler output filename
BGCOLOR equ #$77
BGCOLORAUX equ #$BB
@ -41,20 +35,31 @@ BGCOLOR_0LO equ #$70
BGCOLOR_0HI equ #$07
BGCOLORAUX_0LO equ #$B0
BGCOLORAUX_0HI equ #$0B
FIN
* Usage: CopyPtr sourceAddress;destinationZPPtrLoc
* macro used to set up ZeroPage pointers
* Example setting up sprite data pointer to the location of a bird sprite
* CopyPtr BIRD_WUP_E_PIXEL;SPRITE_DATA_P
CopyPtr MAC
lda #<]1 ; load low byte
sta ]2 ; store low byte
lda #>]1 ; load high byte
sta ]2+1 ; store high byte
<<<
Main
jsr DetectMachine ; also inits vbl
jsr SetupVBL
jsr LoadHiScore
jsr IntroWipe
jsr DL_SetDLRMode
Title
jsr VBlank
AttractLoop
jsr WaitVBL
DO MONO
lda #$FF
ELSE
@ -68,97 +73,87 @@ Title
ldy #BGCOLOR
jsr DL_WipeIn
jsr DrawFlogo
lda FlogoCount
and #%00000011 ; every 4 times?
lda SongSkipCounter
and #%00000011 ; throttle to play song every 4 times?
bne :noSongForYou
jsr PlayFlappySong ;@todo throttle
jsr SND_PlayFlappySong
:noSongForYou
inc FlogoCount
inc SongSkipCounter
ldx #60
ldy #2
jsr WaitKeyXY
PreGameLoop
** INIT ALL GAME STATE ITEMS
PlayfieldAttract
* INITIALIZE ALL GAME STATE VALUES
lda #BIRD_X
sta SPRITE_X
lda #BIRD_Y_INIT
sta BIRD_Y
sta BIRD_Y_OLD
lda #BIRD_WIDTH
sta SPRITE_W
lda #0
sta SPRITE_COLLISION
sta PreGameTick
sta PreGameTick+1
sta PreGameText
sta AttractTick
sta AttractTick+1
sta AttractText
sta ScoreLo
sta ScoreHi
lda #0
ldx #3
:clearPipes sta TopPipes,x
sta BotPipes
:zeroPipes sta TopPipes,x
sta BotPipes,x
dex
bpl :clearPipes
bpl :zeroPipes
** CLEAR SCREEN - SETUP BIRD
jsr VBlank
* CLEAR SCREEN TO PLAYFIELD COLOR
jsr WaitVBL
lda #BGCOLOR
jsr DL_Clear
lda #BIRD_X
sta SPRITE_X
lda #5
sta SPRITE_W ; all birds are same width
** WAIT FOR PLAYER TO HIT SOMETHING
:noKey jsr VBlank
* ANIMATE PLAYFIELD/BIRD WHILE WAITING FOR A KEYPRESS
:attractAnimLoop jsr WaitVBL
jsr UndrawBird
jsr DrawBird
jsr UpdateGrass
jsr FlapBird
inc PreGameTick
inc AttractTick
bne :noOverflow
inc PreGameTick+1
:noOverflow lda PreGameTick
cmp #60
bcc :skipText
lda PreGameText
inc AttractTick+1
:noOverflow lda AttractTick
cmp #60 ; on the 60th tick (aka after 1 second)
bne :skipText
inc PreGameText
jsr DrawTap
jsr DrawTap ; draw the "tap to flap" message
:skipText
lda PreGameTick+1
cmp #2
lda AttractTick+1
cmp #2 ; on the 0x200 aka 512th tick, switch to hiscore screen
bne :checkKey
jmp HiScreen
:checkKey jsr ButtonsCheck
bcs :key
bcs :keyPressed
lda KEY
bpl :noKey
:key sta STROBE
bpl :attractAnimLoop
:keyPressed sta STROBE
lda #BGCOLOR
jsr DL_Clear
jmp GameLoop
PreGameTick dw 0
PreGameText db 0
GSBORDER da _GSBORDER
_GSBORDER db 0
AttractTick dw 0
AttractText db 0
* MAIN GAME LOOP
GameLoop
jsr VBlank
jsr UndrawBird
jsr DrawPipes
jsr DrawScore
jsr DrawBird
jmp UpdatePipes
jsr WaitVBL ; wait until we are in vertical blanking period
jsr UndrawBird ; overwrite sprite area with background color
jsr DrawPipes ; draw pipes in new position (this wipes with bgcolor as it draws)
jsr DrawScore ; draw the score indicator at the top (overlapping any pipes)
jsr DrawBird ; draw the bird
jmp UpdatePipes ; update the
UpdatePipesDone
DONTUPDATEPIPES
jsr FlapBird
jsr UpdateGrass
@ -175,7 +170,7 @@ GAME_OVER
jsr DrawPipes
jsr DrawScore
jsr DrawSplosion
jsr SND_Static
jsr SND_Crash
jsr UpdateHiScore
lda #3
sta SPR_Y
@ -205,13 +200,13 @@ GAME_OVER
lda QuitFlag
beq :noQuit
jmp Quit
:noQuit jmp PreGameLoop
:noQuit jmp PlayfieldAttract
:noKey
lda #$FA
ldx #$50
ldy #$00
jsr DL_WipeIn
jmp Title
jmp AttractLoop
HiScreen
jsr GetRand
jsr DL_Clear
@ -230,74 +225,11 @@ HiScreen
lda QuitFlag
beq :noQuit
jmp Quit
:noQuit jmp PreGameLoop
:noKey jmp Title
:noQuit jmp PlayfieldAttract
:noKey jmp AttractLoop
FlogoCount db 0 ; used to throttle how often song is played
SongSkipCounter db 0 ; used to throttle how often song is played
SND_Flap jmp SND_Flap2
SND_Flap1
ldx #$1c ;LENGTH OF NOISE BURST
:spkLoop lda SPEAKER ;TOGGLE SPEAKER
txa
asl
asl
tay
:waitLoop dey ;DELAY LOOP FOR PULSE WIDTH
bne :waitLoop
dex ;GET NEXT PULSE OF THIS NOISE BURST
bne :spkLoop
rts
SND_Flap2
ldx #$16 ;LENGTH OF NOISE BURST
:spkLoop sta SPEAKER ;TOGGLE SPEAKER
txa
clc
adc #$30
tay
:waitLoop dey ;DELAY LOOP FOR PULSE WIDTH
bne :waitLoop
dex ;GET NEXT PULSE OF THIS NOISE BURST
bne :spkLoop
rts
SND_Static
ldx #$80 ;LENGTH OF NOISE BURST
:spkLoop lda SPEAKER ;TOGGLE SPEAKER
jsr GetRand
tay
* ldy $BA00,X ;GET PULSE WIDTH PSEUDO-RANDOMLY
:waitLoop dey ;DELAY LOOP FOR PULSE WIDTH
bne :waitLoop
dex ;GET NEXT PULSE OF THIS NOISE BURST
bne :spkLoop
ldx #$60 ;LENGTH OF NOISE BURST
:spkLoop2 lda SPEAKER ;TOGGLE SPEAKER
jsr GetRand
and #%1000000
tay
* ldy $BA00,X ;GET PULSE WIDTH PSEUDO-RANDOMLY
:waitLoop2 dey ;DELAY LOOP FOR PULSE WIDTH
bne :waitLoop2
dex ;GET NEXT PULSE OF THIS NOISE BURST
bne :spkLoop2
ldx #$80 ;LENGTH OF NOISE BURST
:spkLoop3 lda SPEAKER ;TOGGLE SPEAKER
jsr GetRand
lsr
tay
:waitLoop3 dey ;DELAY LOOP FOR PULSE WIDTH
bne :waitLoop3
dex ;GET NEXT PULSE OF THIS NOISE BURST
bne :spkLoop3
rts
HandleInput
lda BIRD_Y
@ -400,9 +332,6 @@ PauseKeyCheck cmp #"p"
lda #0
rts
BIRD_VELOCITY db 0 ; in two's compliment {-3,3}
BIRD_VELOCITY_MAX equ #20
BIRD_VELOCITY_MIN equ #%111111111 ; -1
LoadHiScore jsr CreateHiScoreFile
bcs :error
jsr OpenHiScoreFile
@ -428,7 +357,7 @@ CreateHiScoreFile
:error cmp #$47 ; dup filename - already created?
bne :bail
clc ; this is ok, clear error state
:bail rts ; oh well... just carry on in session
:bail rts ; oh well... just carry on in session
OpenHiScoreFile
jsr MLI
@ -445,7 +374,7 @@ OpenHiScoreFile
ReadHiScoreFile
lda #0
sta IOBuffer
sta IOBuffer+1 ;zero load area, just in case
sta IOBuffer+1 ; zero load area, just in case
lda OpenRefNum
sta ReadRefNum
jsr MLI
@ -493,7 +422,7 @@ WriteHiScoreFile
OpenHiScoreParam
dfb #$03 ; number of parameters
dfb #$03 ; number of parameters
dw HiScoreFile
dw $900
OpenRefNum db 0 ; assigned by open call
@ -501,7 +430,7 @@ HiScoreFile str 'flaphi'
CloseHiScoreParam
dfb #$01 ; number of parameters
dfb #$01 ; number of parameters
CloseRefNum db 0
@ -533,6 +462,7 @@ WriteResult dw 0 ; result count (amount transferred)
Quit jsr QRPause
jsr ShutDownVBL ; disable IIc VBL polling if needed
sta TXTPAGE1 ; Don't forget to give them back the right page!
jsr MLI ; first actual command, call ProDOS vector
dfb $65 ; QUIT P8 request ($65)
@ -584,15 +514,16 @@ QRPause jsr DL_SetDLRMixMode
ldy #60
jsr WaitKeyXY
rts
QuitStr str "http://dagenbrock.com/flappy"
QuitStr str "https://github.com/digarok/flapple"
******************************
**************************************************
* Score Routines
*********************
**************************************************
ScoreLo db 0 ; 0-99
ScoreHi db 0 ; hundreds, not shown on screen
ScoreHi db 0 ; hundreds, not shown during gameplay but in highscore it is shown
HiScoreLo db 0
HiScoreHi db 0
** Draw the Score - @todo - handle > 99
DrawScore lda ScoreLo
and #$0F
@ -612,7 +543,7 @@ DrawScore lda ScoreLo
sta Lo02+18
rts
** HANDLE HIGH SCORE
** HANDLE HIGH SCORE
UpdateHiScore
lda HiScoreHi
cmp ScoreHi
@ -623,7 +554,6 @@ UpdateHiScore
bcc :newHighScore
bcs :noHighScore
:newHighScore lda ScoreHi
sta HiScoreHi
lda ScoreLo
@ -635,7 +565,7 @@ UpdateHiScore
**************************************************
* Grass
* Grass
**************************************************
UpdateGrass inc GrassState
lda GrassState
@ -842,7 +772,7 @@ WaitKey
WaitKeyXY
stx _waitX
:kloop jsr VBlank
:kloop jsr WaitVBL
lda KEY
bmi :kpress
dex
@ -859,27 +789,8 @@ WaitKeyXY
rts
_waitX db 0
**************************************************
* See if we're running on a IIgs
* From Apple II Technote:
* Miscellaneous #7
* Apple II Family Identification
**************************************************
DetectMachine
sec ;Set carry bit (flag)
jsr $FE1F ;Call to the monitor
bcs :oldmachine ;If carry is still set, then old machine
* bcc :newmachine ;If carry is clear, then new machine
:newmachine asl _compType ;multiply vblank detection val $7E * 2
lda #1
bne :setmachine
:oldmachine lda #0
:setmachine sta GMachineIIgs
jsr InitVBlank
rts
GMachineIIgs db 0
IntroWipe
sta C80STOREON
@ -905,12 +816,12 @@ IntroText str "Dagen Brock presents..."
**************************************************
* Wait for vertical blanking interval - IIe/IIgs
* Wait for multiple VBLs
**************************************************
VBlankX
:xloop txa
pha
jsr VBlank
jsr WaitVBL
pla
tax
dex
@ -918,94 +829,14 @@ VBlankX
rts
InitVBlank
lda $FBC0 ; check for IIc
bne :rts ; not a IIc--use VBlankIIeIIgs
jsr MLI ; instantiate our interrupt
dfb $40
da VBLIntParm
lda #%00001000 ; enable vblint only
ldx #SETMOUSE
jsr mouse
lda #VBlankIIc ; override vblank
sta VBlankRoutine
lda #>VBlankIIc
sta VBlankRoutine+1
cli
:rts rts
VBLIntParm dfb 2
brk ;?
da VBLIntHandler
VBLIntHandler cld ; Expected by ProDOS
ldx #SERVEMOUSE
jsr mouse
bcs :notOurs ; pass if not
sec
ror _vblflag ;set hibit
clc
:notOurs rts
mouse ldy $C400,x
sty :jump+1
ldx #$C4
ldy #$40
sei
:jump jmp $C400
MOUSE = $c400 ; mouse = slot 4
*SETMOUSE = $c412 ; Apple IIc Ref p.168
*SERVEMOUSE = $c413 ; Apple IIc Ref p.168
SETMOUSE = $12
SERVEMOUSE = $13
READMOUSE = $14
INITMOUSE = $19
VBlank jmp VBlankIIeIIgs
VBlankRoutine equ *-2
VBlankIIc
cli ;enable interrupts
:loop1 bit _vblflag
bpl :loop1 ;wait for vblflag = 1
lsr _vblflag ;...& set vblflag = 0
*:loop2 bit _vblflag
* bpl :loop2
* lsr _vblflag
sei
rts
_vblflag db 0
VBlankIIeIIgs
lda _compType
:vblActive cmp RDVBLBAR ; make sure we wait for the current one to stop
bpl :vblActive ; in case it got launched in rapid succession
:screenActive cmp RDVBLBAR
bmi :screenActive
rts
_compType db #$7e ; $7e - IIe ; $FE - IIgs
MLI equ $bf00 ; ProDOS entry point
put vbl
put util
put applerom
put dlrlib

View File

@ -2,192 +2,192 @@
* Well... optimized number drawing because, why not
****
BB equ #$00
BW equ #$F0
WB equ #$0F
WW equ #$FF
BB equ #$00
BW equ #$F0
WB equ #$0F
WW equ #$FF
DrawNum_Table da DrawNum_0
da DrawNum_1
da DrawNum_2
da DrawNum_3
da DrawNum_4
da DrawNum_5
da DrawNum_6
da DrawNum_7
da DrawNum_8
da DrawNum_9
DrawNum_Table da DrawNum_0
da DrawNum_1
da DrawNum_2
da DrawNum_3
da DrawNum_4
da DrawNum_5
da DrawNum_6
da DrawNum_7
da DrawNum_8
da DrawNum_9
* y = x, a=val (0-9)
DrawNum
asl
tax
lda DrawNum_Table,x
sta :jsrPtr+1
lda DrawNum_Table+1,x
sta :jsrPtr+2
tya
tax
:jsrPtr jsr DrawNum_0
rts
asl
tax
lda DrawNum_Table,x
sta :jsrPtr+1
lda DrawNum_Table+1,x
sta :jsrPtr+2
tya
tax
:jsrPtr jsr DrawNum_0
rts
* x = x offset (even cols) 0-40
DrawNum_0 sta TXTPAGE2
lda #BB
sta Lo01,x
sta Lo02,x
sta Lo01+1,x
sta Lo02+1,X
sta TXTPAGE1
lda #BW
sta Lo01,x
lda #WB
sta Lo02,x
lda #WW
sta Lo01+1,x
sta Lo02+1,x
rts
DrawNum_0 sta TXTPAGE2
lda #BB
sta Lo01,x
sta Lo02,x
sta Lo01+1,x
sta Lo02+1,X
sta TXTPAGE1
lda #BW
sta Lo01,x
lda #WB
sta Lo02,x
lda #WW
sta Lo01+1,x
sta Lo02+1,x
rts
DrawNum_1 sta TXTPAGE2
lda #BW
sta Lo01,x
lda #WB
sta Lo02,x
sta Lo02+1,x
lda #WW
sta Lo01+1,x
sta TXTPAGE1
sta Lo01+1,x
sta Lo02+1,x
lda #BB
sta Lo01,x
sta Lo02,x
rts
DrawNum_1 sta TXTPAGE2
lda #BW
sta Lo01,x
lda #WB
sta Lo02,x
sta Lo02+1,x
lda #WW
sta Lo01+1,x
sta TXTPAGE1
sta Lo01+1,x
sta Lo02+1,x
lda #BB
sta Lo01,x
sta Lo02,x
rts
DrawNum_2 sta TXTPAGE2
lda #BW
sta Lo01,x
lda #WB
sta Lo02+1,x
lda #BB
sta Lo02,x
sta Lo01+1,x
sta TXTPAGE1
sta Lo01,x
sta Lo02,x
lda #WW
sta Lo01+1,x
sta Lo02+1,x
rts
DrawNum_2 sta TXTPAGE2
lda #BW
sta Lo01,x
lda #WB
sta Lo02+1,x
lda #BB
sta Lo02,x
sta Lo01+1,x
sta TXTPAGE1
sta Lo01,x
sta Lo02,x
lda #WW
sta Lo01+1,x
sta Lo02+1,x
rts
DrawNum_3 sta TXTPAGE2
lda #BW
sta Lo01,x
lda #WB
sta Lo02,x
lda #BB
sta Lo01+1,x
sta Lo02+1,x
sta TXTPAGE1
sta Lo01,x
lda #WB
sta Lo02,x
lda #WW
sta Lo01+1,x
sta Lo02+1,x
rts
DrawNum_3 sta TXTPAGE2
lda #BW
sta Lo01,x
lda #WB
sta Lo02,x
lda #BB
sta Lo01+1,x
sta Lo02+1,x
sta TXTPAGE1
sta Lo01,x
lda #WB
sta Lo02,x
lda #WW
sta Lo01+1,x
sta Lo02+1,x
rts
DrawNum_4 sta TXTPAGE2
lda #BB
sta Lo01,x
sta Lo01+1,x
sta Lo02+1,x
lda #BW
sta Lo02,x
sta TXTPAGE1
sta Lo02,x
lda #WW
sta Lo01,x
sta Lo01+1,x
sta Lo02+1,x
rts
DrawNum_4 sta TXTPAGE2
lda #BB
sta Lo01,x
sta Lo01+1,x
sta Lo02+1,x
lda #BW
sta Lo02,x
sta TXTPAGE1
sta Lo02,x
lda #WW
sta Lo01,x
sta Lo01+1,x
sta Lo02+1,x
rts
DrawNum_5 sta TXTPAGE2
lda #BW
sta Lo01+1,x
lda #WB
sta Lo02,x
lda #BB
sta Lo01,x
sta Lo02+1,x
sta TXTPAGE1
sta Lo01,x
sta Lo02,x
lda #WW
sta Lo01+1,x
sta Lo02+1,x
rts
DrawNum_5 sta TXTPAGE2
lda #BW
sta Lo01+1,x
lda #WB
sta Lo02,x
lda #BB
sta Lo01,x
sta Lo02+1,x
sta TXTPAGE1
sta Lo01,x
sta Lo02,x
lda #WW
sta Lo01+1,x
sta Lo02+1,x
rts
DrawNum_6 sta TXTPAGE2
lda #BB
sta Lo01,x
sta Lo02,x
sta Lo02+1,x
lda #WB
sta Lo01+1,x
sta TXTPAGE1
sta Lo01,x
sta Lo02,x
lda #WW
sta Lo01+1,x
sta Lo02+1,x
rts
DrawNum_6 sta TXTPAGE2
lda #BB
sta Lo01,x
sta Lo02,x
sta Lo02+1,x
lda #WB
sta Lo01+1,x
sta TXTPAGE1
sta Lo01,x
sta Lo02,x
lda #WW
sta Lo01+1,x
sta Lo02+1,x
rts
DrawNum_7 sta TXTPAGE2
lda #BW
sta Lo01,x
lda #WW
sta Lo02,x
sta Lo02+1,x
lda #BB
sta Lo01+1,x
sta TXTPAGE1
sta Lo02,x
lda #BW
sta Lo01,x
lda #WW
sta Lo01+1,x
sta Lo02+1,x
rts
DrawNum_7 sta TXTPAGE2
lda #BW
sta Lo01,x
lda #WW
sta Lo02,x
sta Lo02+1,x
lda #BB
sta Lo01+1,x
sta TXTPAGE1
sta Lo02,x
lda #BW
sta Lo01,x
lda #WW
sta Lo01+1,x
sta Lo02+1,x
rts
DrawNum_8 sta TXTPAGE2
lda #WB
sta Lo01,x
lda #BB
sta Lo02,X
sta Lo01+1,x
sta Lo02+1,x
sta TXTPAGE1
sta Lo02,x
lda #BW
sta Lo01,x
lda #WW
sta Lo01+1,x
sta Lo02+1,x
rts
DrawNum_8 sta TXTPAGE2
lda #WB
sta Lo01,x
lda #BB
sta Lo02,X
sta Lo01+1,x
sta Lo02+1,x
sta TXTPAGE1
sta Lo02,x
lda #BW
sta Lo01,x
lda #WW
sta Lo01+1,x
sta Lo02+1,x
rts
DrawNum_9 sta TXTPAGE2
lda #BB
sta Lo01,x
sta Lo01+1,x
sta Lo02+1,x
lda #BW
sta Lo02,x
sta TXTPAGE1
sta Lo01,x
sta Lo02,x
lda #WW
sta Lo01+1,x
sta Lo02+1,x
rts
DrawNum_9 sta TXTPAGE2
lda #BB
sta Lo01,x
sta Lo01+1,x
sta Lo02+1,x
lda #BW
sta Lo02,x
sta TXTPAGE1
sta Lo01,x
sta Lo02,x
lda #WW
sta Lo01+1,x
sta Lo02+1,x
rts

File diff suppressed because it is too large Load Diff

View File

@ -3,25 +3,27 @@
*
* Flapple Bird - A de-make of Flappy Bird for the Apple II computer
*
* More information about this project is available at
* http://dagenbrock.com/flappy
* # Download releases here:
* https://github.com/digarok/flapple/releases
*
* How to run
* ==========
* You can download either disk image and run it with an emulator
* or transfer it to the respective media and run it on a real
* machine (recommended).
* The 3.5" ProDOS disk version is "flapple800.po", and the
* 5.25" ProDOS disk version is "flapple140.po".
* # How to run
* You can download either disk image and run it with an emulator like GSplus
* or transfer to the respective media and run on a real machine (recommended).
* - `flapple800.po` is the 3.5" ProDOS disk version (800KB)
* - `flapple140.po` is the 5.25" ProDOS disk version (140KB)
*
* How to build
* ============
* This is written to compile on Merlin 8/16, but I believe should
* work with all later Merlin variants. Load Merlin, then 'L'oad
* the file "flapple.s", finally hit OpenApple-A to assemble and
* it should build the "flap.system" file.
* It should automatically boot ProDOS and load the color version of the game.
* There is a Monochrome version of the game included on the disk.
* To run it, quit game with the `q` key, and from the ProDOS selector menu
* run `fmono.system`.
*
* # How to build
* This was originally written to compile on Merlin 8/16, but it's now
* maintained using Merlin32 (https://github.com/digarok/merlin32/).
*
*
* Again, more information about this project is available at
* http://dagenbrock.com/flappy
* - Classic Merlin16+ on an Apple IIgs
* - Load Merlin, then `L`oad the file "flapple.s", finally hit OpenApple-A to assemble and it should build the "flap.system" file.
* - Modern PC builds:
* - Assemble with `merlin32 src/flapple.s`
* - Make disks with `./make_po.sh`
* * Requires having `merlin32` and `cadius` commands available on your system.

View File

@ -1,162 +1,149 @@
* Flappy's Flapping Chirp Sound
SND_Flap ldx #$16 ;LENGTH OF NOISE BURST
:spkLoop sta SPEAKER ;TOGGLE SPEAKER
txa
clc
adc #$30
tay
:waitLoop dey ;DELAY LOOP FOR PULSE WIDTH
bne :waitLoop
dex ;GET NEXT PULSE OF THIS NOISE BURST
bne :spkLoop
rts
PlayFlappySong
ldy #0
:loop lda FlappySong,y
cmp #NoteEnd
beq :done
cmp #NoteRest
bne :notRest
ldx FlappySong+1,y
jsr VBlankX
clc
bcc :nextNote
:notRest ldx FlappySong+1,y
jsr SENoteAX
ldx #2
jsr VBlankX
:nextNote iny
iny
lda KEY ; allow user to skip my totally awesome song
bpl :noKey
sta STROBE
rts
:noKey clc
bcc :loop
:done rts
* Flappy's Devastating Crash Sound
SND_Crash
ldx #$80 ;LENGTH OF NOISE BURST
jsr SEStaticBurst
FlappySong hex 72,22,72,22,56,22,01,0E
hex 72,22,72,22,56,22,01,0E
hex 72,22,72,22,56,22,01,0E
hex 72,22,72,22,80,22,01,0E
hex 72,22,72,22,56,22,01,0E
hex 72,22,72,22,56,22,01,0E
hex 72,22,72,22,4C,22,56,22
hex 5B,22,72,22,5B,22,56,40
hex 02 ; end byte
ldx #$60 ;LENGTH OF NOISE BURST
:spkLoop2 lda SPEAKER ;TOGGLE SPEAKER
jsr GetRand
and #%1000000
tay
:waitLoop2 dey ;DELAY LOOP FOR PULSE WIDTH
bne :waitLoop2
dex ;GET NEXT PULSE OF THIS NOISE BURST
bne :spkLoop2
ldx #$80 ;LENGTH OF NOISE BURST
jsr SEStaticBurst
rts
SEStaticBurst
:spkLoop lda SPEAKER ;TOGGLE SPEAKER
jsr GetRand
tay
:waitLoop dey ;DELAY LOOP FOR PULSE WIDTH
bne :waitLoop
dex ;GET NEXT PULSE OF THIS NOISE BURST
bne :spkLoop
rts
* BELOW HERE IS THE "MUSIC ENGINE"
SND_PlayFlappySong
ldy #0
:loop lda FlappySong,y
cmp #NoteEnd
beq :done
cmp #NoteRest
bne :notRest
ldx FlappySong+1,y
jsr VBlankX
clc
bcc :nextNote
:notRest ldx FlappySong+1,y
jsr SENoteAX
ldx #2
jsr VBlankX
:nextNote iny
iny
lda KEY ; allow user to skip my totally awesome song
bpl :noKey
sta STROBE
rts
:noKey clc
bcc :loop
:done rts
FlappySong hex 72,22,72,22,56,22,01,0E
hex 72,22,72,22,56,22,01,0E
hex 72,22,72,22,56,22,01,0E
hex 72,22,72,22,80,22,01,0E
hex 72,22,72,22,56,22,01,0E
hex 72,22,72,22,56,22,01,0E
hex 72,22,72,22,4C,22,56,22
hex 5B,22,72,22,5B,22,56,40
hex 02 ; end byte
**************************************************
* wrapper for SEplayNote
* wrapper for SEplayNote
* a = freq ... x = dur
**************************************************
SENoteAX jsr _storeReg
sta _SECURRNOTE
stx _SECURRNOTE+1
jsr SEplayNote
jsr _loadReg
rts
SENoteAX jsr _storeReg
sta _SECURRNOTE
stx _SECURRNOTE+1
jsr SEplayNote
jsr _loadReg
rts
**************************************************
*
**************************************************
ds \
_SECURRNOTE db 0,0 ; current note being played (frequency/duration)
ds \ ; align
SEplayNote
ldy _SECURRNOTE+1
:loop lda SPEAKER
:whyWut dey
bne :thar
dec _SECURRNOTE+1
beq :doneThat
:thar dex
bne :whyWut
ldx _SECURRNOTE
jmp :loop
:doneThat rts
ldy _SECURRNOTE+1
:loop lda SPEAKER
:whyWut dey
bne :thar
dec _SECURRNOTE+1
beq :doneThat
:thar dex
bne :whyWut
ldx _SECURRNOTE
jmp :loop
:doneThat rts
SEplayNote_OLD
:loop lda SPEAKER
:whyWut dey
bne :thar
dec _SECURRNOTE+1
beq :doneThat
:thar dex
bne :whyWut
ldx _SECURRNOTE
jmp :loop
:doneThat rts
_SECURRNOTE db 0,0 ; current note being played (frequency/duration)
**************************************************
* This is essentially the scale
**************************************************
_SE_tones db NoteG0,NoteGsharp0,NoteA0,NoteBflat0,NoteB0
db NoteC1,NoteCsharp1,NoteD1,NoteDsharp1,NoteE1
db NoteF1,NoteFsharp1,NoteG1,NoteGsharp1,NoteA1
db NoteBflat1,NoteB1,NoteC2,NoteCsharp2,NoteD2
db NoteDsharp2,NoteE2,NoteF2
NoteRest equ $01 ;\_ these are inaudible anyway
NoteEnd equ $02 ;/
NoteG0 equ $00 ; because it loops (underflow)
NoteGsharp0 equ $f0
NoteA0 equ $e6
NoteBflat0 equ $d5
NoteB0 equ $cb ; speculating here on up
NoteC1 equ $c0
NoteCsharp1 equ $b5
NoteD1 equ $ac
NoteDsharp1 equ $a3
NoteE1 equ $99
NoteF1 equ $90
NoteFsharp1 equ $89
NoteG1 equ $80
NoteGsharp1 equ $79
NoteA1 equ $72
NoteBflat1 equ $6c
NoteB1 equ $66
NoteC2 equ $60
NoteCsharp2 equ $5b
NoteD2 equ $56
NoteDsharp2 equ $51
NoteE2 equ $4c
NoteF2 equ $48
; starts to suck here anyway
SErandStatic
ldy #$ff
:loop lda SPEAKER
jsr GetRand
tax
beq :next
:wait dex
bne :wait
:next dey
bne :loop
rts
* y = length
SErandStaticBit
:loop lda SPEAKER
jsr GetRand
lsr
tax
beq :next
:wait dex
bne :wait
:next dey
bne :loop
rts
* y = length - no shift so wider range
SErandStaticBit2
:loop lda SPEAKER
jsr GetRand
tax
beq :next
:wait dex
bne :wait
:next dey
bne :loop
rts
_SE_tones db NoteG0,NoteGsharp0,NoteA0,NoteBflat0,NoteB0
db NoteC1,NoteCsharp1,NoteD1,NoteDsharp1,NoteE1
db NoteF1,NoteFsharp1,NoteG1,NoteGsharp1,NoteA1
db NoteBflat1,NoteB1,NoteC2,NoteCsharp2,NoteD2
db NoteDsharp2,NoteE2,NoteF2
NoteRest equ $01 ;\_ these are inaudible anyway
NoteEnd equ $02 ;/
NoteG0 equ $00 ; because it loops (underflow)
NoteGsharp0 equ $f0
NoteA0 equ $e6
NoteBflat0 equ $d5
NoteB0 equ $cb ; speculating here on up
NoteC1 equ $c0
NoteCsharp1 equ $b5
NoteD1 equ $ac
NoteDsharp1 equ $a3
NoteE1 equ $99
NoteF1 equ $90
NoteFsharp1 equ $89
NoteG1 equ $80
NoteGsharp1 equ $79
NoteA1 equ $72
NoteBflat1 equ $6c
NoteB1 equ $66
NoteC2 equ $60
NoteCsharp2 equ $5b
NoteD2 equ $56
NoteDsharp2 equ $51
NoteE2 equ $4c
NoteF2 equ $48
; starts to suck here anyway

View File

@ -1,162 +1,144 @@
SPRITE_X db 0
SPRITE_Y db 0 ; BYTE,not pixel. gotta be, sorry
SPRITE_W db 0
SPRITE_W_D2 db 0
SPRITE_H db 0 ; <- in bytes
SPRITE_X db 0
SPRITE_Y db 0 ; BYTE,not pixel. gotta be, sorry
SPRITE_W db 0
SPRITE_W_D2 db 0
SPRITE_H db 0 ; <- in bytes
SPRITE_MAIN da 0
SPRITE_AUX da 0
SPRITE_MASK da 0
SPRITE_IMASK da 0
SPRITE_COLLISION db 0
SPRITE_Y_IDX dw 0
SPRITE_X_IDX dw 0
SPRITE_MAIN da 0
SPRITE_AUX da 0
SPRITE_MASK da 0
SPRITE_IMASK da 0
SPRITE_COLLISION db 0
SPRITE_Y_IDX dw 0
SPRITE_X_IDX dw 0
SPRITE_SCREEN_P equz $00
SPRITE_MAIN_P equz $02
SPRITE_SCREEN_P2 equz $02
SPRITE_AUX_P equz $04
SPRITE_SCREEN_P3 equz $04
SPRITE_MASK_P equz $FA
SPRITE_SCREEN_P4 equz $FA
SPRITE_IMASK_P equz $FC
SPRITE_SCREEN_P equz $00
SPRITE_MAIN_P equz $02
SPRITE_SCREEN_P2 equz $02
SPRITE_AUX_P equz $04
SPRITE_SCREEN_P3 equz $04
SPRITE_MASK_P equz $FA
SPRITE_SCREEN_P4 equz $FA
SPRITE_IMASK_P equz $FC
SPRITE_SCREEN_IDX db #$0
AUX_BG_COLOR db #$BB
MAIN_BG_COLOR db #$77
*** MAKE IT WORK
BirdTest
lda BIRD_X ;#30 (0-79)
sta SPRITE_X
lda BIRD_Y ;#10 (0-23)
sta SPRITE_Y
lda #5 ;/2 value (we do two passes of 1/2... Aux/Main)
sta SPRITE_W
lda #3 ;/2 value (must be byte aligned vertically
sta SPRITE_H
CopyPtr BIRD_WDN_MAIN;SPRITE_MAIN_P
CopyPtr BIRD_WDN_AUX;SPRITE_AUX_P
CopyPtr BIRD_WDN_MASK;SPRITE_MASK_P
CopyPtr BIRD_WDN_IMASK;SPRITE_IMASK_P
jsr DrawSpriteBetter
rts
SPRITE_SCREEN_IDX db #$0
AUX_BG_COLOR db #$BB
MAIN_BG_COLOR db #$77
* still does collision
DrawSpriteBetter
lda #0
sta SPRITE_X_IDX
:drawLine lda SPRITE_Y ;
tay
lda LoLineTableL,y ; SET SCREEN LINE
sta SPRITE_SCREEN_P
lda LoLineTableH,y
sta SPRITE_SCREEN_P+1
lda #0
sta SPRITE_X_IDX
:drawLine lda SPRITE_Y ;
tay
lda LoLineTableL,y ; SET SCREEN LINE
sta SPRITE_SCREEN_P
lda LoLineTableH,y
sta SPRITE_SCREEN_P+1
lda SPRITE_X ; ADD IN X OFFSET TO SCREEN POSITION
clc ; I think the highest position is $f8
adc SPRITE_SCREEN_P ; eg- Line 18, col 40= $4f8
sta SPRITE_SCREEN_P ; SHOULD NEVER CARRY?
lda SPRITE_X ; ADD IN X OFFSET TO SCREEN POSITION
clc ; I think the highest position is $f8
adc SPRITE_SCREEN_P ; eg- Line 18, col 40= $4f8
sta SPRITE_SCREEN_P ; SHOULD NEVER CARRY?
jmp DrawSpriteLineC
jmp DrawSpriteLineC
]DSLCD_done
inc SPRITE_Y
dec SPRITE_H
lda SPRITE_H
bne :drawLine
rts
inc SPRITE_Y
dec SPRITE_H
lda SPRITE_H
bne :drawLine
rts
DrawSpriteLineC
; EVEN COLS
DD_EVEN lda #0
sta SPRITE_SCREEN_IDX
sta TXTPAGE2
; EVEN COLS
DD_EVEN lda #0
sta SPRITE_SCREEN_IDX
sta TXTPAGE2
:lineLoop
;ldy SPRITE_X_IDX ;
;lda (SPRITE_IMASK_P),y
;beq :noPixel
;ldy SPRITE_X_IDX ;
;lda (SPRITE_IMASK_P),y
;beq :noPixel
:collisionCheckDrawer
ldy SPRITE_SCREEN_IDX ; GET SCREEN PIXELS
lda (SPRITE_SCREEN_P),y
pha ; SAVE -> STACK
ldy SPRITE_X_IDX ; PREP Y INDEX
cmp #$BB ; AUX BGCOLOR @TODO
beq :noCollision
and (SPRITE_IMASK_P),y
cmp #$B0
beq :noCollision
cmp #$0B
beq :noCollision
lda #1
sta SPRITE_COLLISION
sta $c034
ldy SPRITE_SCREEN_IDX ; GET SCREEN PIXELS
lda (SPRITE_SCREEN_P),y
pha ; SAVE -> STACK
ldy SPRITE_X_IDX ; PREP Y INDEX
cmp #$BB ; AUX BGCOLOR @TODO
beq :noCollision
and (SPRITE_IMASK_P),y
cmp #$B0
beq :noCollision
cmp #$0B
beq :noCollision
lda #1
sta SPRITE_COLLISION
sta $c034
:noCollision
:doPixels pla ; Y=SPRITE X A=BG DATA
and (SPRITE_MASK_P),y ; CUT OUT SPRITE IN BG DATA
ora (SPRITE_AUX_P),y ; OVERLAY OUR SPRITE DATA
ldy SPRITE_SCREEN_IDX
sta (SPRITE_SCREEN_P),y
:doPixels pla ; Y=SPRITE X A=BG DATA
and (SPRITE_MASK_P),y ; CUT OUT SPRITE IN BG DATA
ora (SPRITE_AUX_P),y ; OVERLAY OUR SPRITE DATA
ldy SPRITE_SCREEN_IDX
sta (SPRITE_SCREEN_P),y
:noPixel inc SPRITE_X_IDX
inc SPRITE_X_IDX
inc SPRITE_SCREEN_IDX
ldy SPRITE_SCREEN_IDX
cpy SPRITE_W
bcc :lineLoop
:noPixel inc SPRITE_X_IDX
inc SPRITE_X_IDX
inc SPRITE_SCREEN_IDX
ldy SPRITE_SCREEN_IDX
cpy SPRITE_W
bcc :lineLoop
DD_ODD
; ODD COLS
inc SPRITE_X_IDX ; + 1 column offset
lda SPRITE_X_IDX
sec
sbc SPRITE_W ; RESET DATA PTR
sbc SPRITE_W ; *2 due to pixel skip
sta SPRITE_X_IDX
lda #0
sta SPRITE_SCREEN_IDX
sta TXTPAGE1
; ODD COLS
inc SPRITE_X_IDX ; + 1 column offset
lda SPRITE_X_IDX
sec
sbc SPRITE_W ; RESET DATA PTR
sbc SPRITE_W ; *2 due to pixel skip
sta SPRITE_X_IDX
lda #0
sta SPRITE_SCREEN_IDX
sta TXTPAGE1
:lineLoop ;ldy SPRITE_X_IDX ;
;lda (SPRITE_IMASK_P),y
;beq :noPixel
:lineLoop ;ldy SPRITE_X_IDX ;
;lda (SPRITE_IMASK_P),y
;beq :noPixel
:collisionCheckDrawer
ldy SPRITE_SCREEN_IDX ; GET SCREEN PIXELS
lda (SPRITE_SCREEN_P),y
pha ; SAVE -> STACK
ldy SPRITE_X_IDX ; PREP Y INDEX
cmp #$77 ; MAIN BGCOLOR @TODO
beq :noCollision
and (SPRITE_IMASK_P),y
cmp #$70
beq :noCollision
cmp #$07
beq :noCollision
lda #1
sta SPRITE_COLLISION
sta $c034
ldy SPRITE_SCREEN_IDX ; GET SCREEN PIXELS
lda (SPRITE_SCREEN_P),y
pha ; SAVE -> STACK
ldy SPRITE_X_IDX ; PREP Y INDEX
cmp #$77 ; MAIN BGCOLOR @TODO
beq :noCollision
and (SPRITE_IMASK_P),y
cmp #$70
beq :noCollision
cmp #$07
beq :noCollision
lda #1
sta SPRITE_COLLISION
sta $c034
:noCollision
:doPixels pla ; Y=SPRITE X A=BG DATA
and (SPRITE_MASK_P),y ; CUT OUT SPRITE IN BG DATA
ora (SPRITE_MAIN_P),y ; OVERLAY OUR SPRITE DATA
ldy SPRITE_SCREEN_IDX
sta (SPRITE_SCREEN_P),y
:doPixels pla ; Y=SPRITE X A=BG DATA
and (SPRITE_MASK_P),y ; CUT OUT SPRITE IN BG DATA
ora (SPRITE_MAIN_P),y ; OVERLAY OUR SPRITE DATA
ldy SPRITE_SCREEN_IDX
sta (SPRITE_SCREEN_P),y
:noPixel inc SPRITE_X_IDX
inc SPRITE_X_IDX
inc SPRITE_SCREEN_IDX
ldy SPRITE_SCREEN_IDX
cpy SPRITE_W
bcc :lineLoop
dec SPRITE_X_IDX ; -1 column offset (for next row)
:noPixel inc SPRITE_X_IDX
inc SPRITE_X_IDX
inc SPRITE_SCREEN_IDX
ldy SPRITE_SCREEN_IDX
cpy SPRITE_W
bcc :lineLoop
dec SPRITE_X_IDX ; -1 column offset (for next row)
jmp ]DSLCD_done
jmp ]DSLCD_done

View File

@ -1,44 +1,44 @@
** Register preservation
_sX dw 0
_sY dw 0
_sA dw 0
_storeReg sta _sA
stx _sX
sty _sY
rts
_loadReg lda _sA
ldx _sX
ldy _sY
rts
_sX dw 0
_sY dw 0
_sA dw 0
_storeReg sta _sA
stx _sX
sty _sY
rts
_loadReg lda _sA
ldx _sX
ldy _sY
rts
**************************************************
* Awesome PRNG thx to White Flame (aka David Holz)
**************************************************
GetRand
lda _randomByte
beq :doEor
asl
bcc :noEor
:doEor eor #$1d
:noEor sta _randomByte
rts
_randomByte db 0
lda _randomByte
beq :doEor
asl
bcc :noEor
:doEor eor #$1d
:noEor sta _randomByte
rts
_randomByte db 0
GetRandLow
lda _randomByte2
beq :doEor
asl
bcc :noEor
:doEor eor #$1d
:noEor sta _randomByte2
cmp #$80
bcs :hot
lda #$0
rts
:hot lda #$04
rts
lda _randomByte2
beq :doEor
asl
bcc :noEor
:doEor eor #$1d
:noEor sta _randomByte2
cmp #$80
bcs :hot
lda #$0
rts
:hot lda #$04
rts
_randomByte2 db 0
_randomByte2 db 0

63
src/vbl.s Normal file
View File

@ -0,0 +1,63 @@
OP_BPL = #$10
OP_BMI = #$30
SetupVBL
lda $FBB3 ; machine id byte (A2Misc TN #7)
cmp #$06 ; IIe, IIc, IIgs
bne :foundII ; II, II+
lda $FBC0 ; machine id byte (A2Misc TN #7)
beq :foundIIc ; IIc = FBB3:06 FBC0:00
sec
jsr $FE1F ; Check for IIgs compatibility routine
bcs :foundIIe
bcc :foundIIgs
:foundII lda #$60 ; RTS opcode
sta WaitVBL
rts
:foundIIc lda #$EA ; NOP opcode
sta ShutDownVBL
lda #OP_BPL ; BPL opcode
sta __waitRasterOp
lda #$70
sta __patchVBLIIc+1
lda #$60
sta __patchVBLIIc+3
sei
sta $C07F ; enable access to VBL register
sta $C05B ; enable VBL polling
sta $C07E ; disable access to VBL register
rts
:foundIIe lda #OP_BPL ; BPL opcode
sta __waitRasterOp
lda #OP_BMI ; BMI opcode
sta __waitVBLOp
:foundIIgs rts
ShutDownVBL rts ; SMC
:lastVBL bit $C019
bpl :lastVBL
lda $C070 ; $c019 bit 7 is sticky, reset it
sta $C07F ; enable access to VBL register
sta $C05A ; disable VBL polling
sta $C07E ; disable access to VBL register
cli
rts
* This function gets modified based on System: II(+), IIe, IIc, IIgs
WaitVBL
:waitRaster lda $c019
bmi :waitRaster ; make sure we are screen area first, (VBL=0) on IIgs, !SMC IIe/c
__waitRasterOp = *-2
__patchVBLIIc = *
:waitVBL lda $c019
bpl :waitVBL ; as soon as blanking starts return, (VBL=1) on IIgs, !SMC IIe/c
__waitVBLOp = *-2
rts