- 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 src/*.system
flapple800.po flapple800.po
flapple140.po flapple140.po

View File

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

View File

@ -1,23 +1,24 @@
************************************************** **************************************************
* Apple Standard Memory Locations * Apple Standard Memory Locations
************************************************** **************************************************
CLRLORES equ $F832 CLRLORES equ $F832
LORES equ $C050 LORES equ $C050
TXTSET equ $C051 TXTSET equ $C051
MIXCLR equ $C052 MIXCLR equ $C052
MIXSET equ $C053 MIXSET equ $C053
TXTPAGE1 equ $C054 TXTPAGE1 equ $C054
TXTPAGE2 equ $C055 TXTPAGE2 equ $C055
KEY equ $C000 KEY equ $C000
C80STOREOFF equ $C000 C80STOREOFF equ $C000
C80STOREON equ $C001 C80STOREON equ $C001
STROBE equ $C010 STROBE equ $C010
SPEAKER equ $C030 SPEAKER equ $C030
VBL equ $C02E VBL equ $C02E
RDVBLBAR equ $C019 ;not VBL (VBL signal low 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_X db 0
SPRITE_Y db 0 ; BYTE,not pixel. gotta be, sorry SPRITE_Y db 0 ; BYTE,not pixel. gotta be, sorry
SPRITE_W db 0 SPRITE_W db 0
SPRITE_W_D2 db 0 SPRITE_W_D2 db 0
SPRITE_H db 0 ; <- in bytes SPRITE_H db 0 ; <- in bytes
SPRITE_MAIN da 0 SPRITE_MAIN da 0
SPRITE_AUX da 0 SPRITE_AUX da 0
SPRITE_MASK da 0 SPRITE_MASK da 0
SPRITE_IMASK da 0 SPRITE_IMASK da 0
SPRITE_COLLISION db 0 SPRITE_COLLISION db 0
SPRITE_Y_IDX dw 0 SPRITE_Y_IDX dw 0
SPRITE_X_IDX dw 0 SPRITE_X_IDX dw 0
SPRITE_SCREEN_P equ $00 SPRITE_SCREEN_P equ $00
SPRITE_DATA_P equ $02 SPRITE_DATA_P equ $02
SPRITE_SCREEN_P2 equ $02 SPRITE_SCREEN_P2 equ $02
SPRITE_AUX_P equ $04 SPRITE_AUX_P equ $04
SPRITE_SCREEN_P3 equ $04 SPRITE_SCREEN_P3 equ $04
SPRITE_MASK_P equ $FA SPRITE_MASK_P equ $FA
SPRITE_SCREEN_P4 equ $FA SPRITE_SCREEN_P4 equ $FA
SPRITE_IMASK_P equ $FC SPRITE_IMASK_P equ $FC
SPRITE_SCREEN_IDX db #$0 SPRITE_SCREEN_IDX db #$0
BIRD_X equ #17 BIRD_VELOCITY db 0 ; in two's compliment {-3,3}
BIRD_Y_INIT equ #17 BIRD_VELOCITY_MAX equ #20
BIRD_Y db #BIRD_Y_INIT ; (0-47) BIRD_VELOCITY_MIN equ #%111111111 ; -1
BIRD_Y_OLD db #BIRD_Y_INIT ; used for undraw - to decouple input routine from sequence BIRD_WIDTH equ #5
BIRD_FLAP db #0 ; 0=down 1=up BIRD_X equ #17
BIRD_FLAP_RATE equ #5 BIRD_Y_INIT equ #17
BIRD_FLAP_CNT db 0 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 FlapBird
inc BIRD_FLAP_CNT inc BIRD_FLAP_CNT
lda BIRD_FLAP_CNT lda BIRD_FLAP_CNT
cmp #BIRD_FLAP_RATE cmp #BIRD_FLAP_RATE
bcs :flapIt bcs :flapIt
rts rts
:flapIt :flapIt
lda #0 lda #0
sta BIRD_FLAP_CNT sta BIRD_FLAP_CNT
inc BIRD_FLAP inc BIRD_FLAP
lda BIRD_FLAP lda BIRD_FLAP
cmp #2 cmp #2
bne :noFlip bne :noFlip
lda #0 lda #0
sta BIRD_FLAP sta BIRD_FLAP
:noFlip rts :noFlip rts
***** EVEN then ODD, i.e. AUX then MAIN ***** EVEN then ODD, i.e. AUX then MAIN
BIRD_WUP_E_PIXEL BIRD_WUP_E_PIXEL
DO MONO DO MONO
hex 00,EA,EA,FF,F0,50,D5,A5,0F,00 hex 00,EA,EA,FF,F0,50,D5,A5,0F,00
hex AA,EA,EE,CF,CF,D5,55,8A,90,90 hex AA,EA,EE,CF,CF,D5,55,8A,90,90
hex 05,AD,A4,08,08,05,5D,51,01,00 hex 05,AD,A4,08,08,05,5D,51,01,00
ELSE ELSE
hex BB,EA,EA,FF,FB,57,D5,A5,0F,77 hex BB,EA,EA,FF,FB,57,D5,A5,0F,77
hex AA,EA,EE,CF,CF,D5,55,8A,90,97 hex AA,EA,EE,CF,CF,D5,55,8A,90,97
hex B5,AD,A4,B8,B8,75,5D,51,71,77 hex B5,AD,A4,B8,B8,75,5D,51,71,77
FIN FIN
BIRD_WUP_E_MASK BIRD_WUP_E_MASK
hex FF,00,00,00,0F,0F,00,00,00,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,00,00,00,00,00,00,0F
hex F0,00,00,F0,F0,F0,00,00,F0,FF hex F0,00,00,F0,F0,F0,00,00,F0,FF
BIRD_WUP_E_IMASK BIRD_WUP_E_IMASK
hex 00,FF,FF,FF,F0,F0,FF,FF,FF,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,FF,FF,FF,FF,FF,FF,F0
hex 0F,FF,FF,0F,0F,0F,FF,FF,0F,00 hex 0F,FF,FF,0F,0F,0F,FF,FF,0F,00
***** EVEN then ODD, i.e. AUX then MAIN ***** EVEN then ODD, i.e. AUX then MAIN
BIRD_WDN_E_PIXEL BIRD_WDN_E_PIXEL
DO MONO DO MONO
hex 00,EA,EA,FF,F0,50,D5,A5,0F,00 hex 00,EA,EA,FF,F0,50,D5,A5,0F,00
hex AA,EE,EE,CF,CF,DD,5D,8A,90,90 hex AA,EE,EE,CF,CF,DD,5D,8A,90,90
hex 54,AE,A4,08,08,5D,55,51,01,00 hex 54,AE,A4,08,08,5D,55,51,01,00
ELSE ELSE
hex BB,EA,EA,FF,FB,57,D5,A5,0F,77 hex BB,EA,EA,FF,FB,57,D5,A5,0F,77
hex AA,EE,EE,CF,CF,DD,5D,8A,90,97 hex AA,EE,EE,CF,CF,DD,5D,8A,90,97
hex 54,AE,A4,B8,B8,5D,55,51,71,77 hex 54,AE,A4,B8,B8,5D,55,51,71,77
FIN FIN
BIRD_WDN_E_MASK BIRD_WDN_E_MASK
hex FF,00,00,00,0F,0F,00,00,00,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,00,00,00,00,00,00,0F
hex 00,00,00,F0,F0,00,00,00,F0,FF hex 00,00,00,F0,F0,00,00,00,F0,FF
BIRD_WDN_E_IMASK BIRD_WDN_E_IMASK
hex 00,FF,FF,FF,F0,F0,FF,FF,FF,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,FF,FF,FF,FF,FF,FF,F0
hex FF,FF,FF,0F,0F,FF,FF,FF,0F,00 hex FF,FF,FF,0F,0F,FF,FF,FF,0F,00
***** EVEN then ODD, i.e. AUX then MAIN ***** EVEN then ODD, i.e. AUX then MAIN
BIRD_WUP_O_PIXEL BIRD_WUP_O_PIXEL
DO MONO DO MONO
hex 00,A0,A0,F0,00,00,50,50,F0,00 hex 00,A0,A0,F0,00,00,50,50,F0,00
hex A0,AE,EE,FF,FF,55,5D,AA,00,00 hex A0,AE,EE,FF,FF,55,5D,AA,00,00
hex 5A,DE,4E,8C,8C,5D,D5,18,19,09 hex 5A,DE,4E,8C,8C,5D,D5,18,19,09
hex 00,0A,0A,00,00,00,05,05,00,00 hex 00,0A,0A,00,00,00,05,05,00,00
ELSE ELSE
hex BB,AB,AB,FB,BB,77,57,57,F7,77 hex BB,AB,AB,FB,BB,77,57,57,F7,77
hex AB,AE,EE,FF,FF,55,5D,AA,00,77 hex AB,AE,EE,FF,FF,55,5D,AA,00,77
hex 5A,DE,4E,8C,8C,5D,D5,18,19,79 hex 5A,DE,4E,8C,8C,5D,D5,18,19,79
hex BB,BA,BA,BB,BB,77,75,75,77,77 hex BB,BA,BA,BB,BB,77,75,75,77,77
FIN
FIN
BIRD_WUP_O_MASK BIRD_WUP_O_MASK
hex FF,0F,0F,0F,FF,FF,0F,0F,0F,FF hex FF,0F,0F,0F,FF,FF,0F,0F,0F,FF
hex 0F,00,00,00,00,00,00,00,00,FF hex 0F,00,00,00,00,00,00,00,00,FF
hex 00,00,00,00,00,00,00,00,00,F0 hex 00,00,00,00,00,00,00,00,00,F0
hex FF,F0,F0,FF,FF,FF,F0,F0,FF,FF hex FF,F0,F0,FF,FF,FF,F0,F0,FF,FF
BIRD_WUP_O_IMASK BIRD_WUP_O_IMASK
hex 00,F0,F0,F0,00,00,F0,F0,F0,00 hex 00,F0,F0,F0,00,00,F0,F0,F0,00
hex F0,FF,FF,FF,FF,FF,FF,FF,FF,00 hex F0,FF,FF,FF,FF,FF,FF,FF,FF,00
hex FF,FF,FF,FF,FF,FF,FF,FF,FF,0F hex FF,FF,FF,FF,FF,FF,FF,FF,FF,0F
hex 00,0F,0F,00,00,00,0F,0F,00,00 hex 00,0F,0F,00,00,00,0F,0F,00,00
***** EVEN then ODD, i.e. AUX then MAIN ***** EVEN then ODD, i.e. AUX then MAIN
BIRD_WDN_O_PIXEL BIRD_WDN_O_PIXEL
DO MONO DO MONO
hex 00,A0,A0,F0,00,00,50,50,F0,00 hex 00,A0,A0,F0,00,00,50,50,F0,00
hex A0,EE,EE,FF,FF,D5,DD,AA,00,00 hex A0,EE,EE,FF,FF,D5,DD,AA,00,00
hex 4A,EE,4E,8C,8C,DD,55,18,19,09 hex 4A,EE,4E,8C,8C,DD,55,18,19,09
hex 05,0A,0A,00,00,05,05,05,00,00 hex 05,0A,0A,00,00,05,05,05,00,00
ELSE ELSE
hex BB,AB,AB,FB,BB,77,57,57,F7,77 hex BB,AB,AB,FB,BB,77,57,57,F7,77
hex AB,EE,EE,FF,FF,D5,DD,AA,00,77 hex AB,EE,EE,FF,FF,D5,DD,AA,00,77
hex 4A,EE,4E,8C,8C,DD,55,18,19,79 hex 4A,EE,4E,8C,8C,DD,55,18,19,79
hex B5,BA,BA,BB,BB,75,75,75,77,77 hex B5,BA,BA,BB,BB,75,75,75,77,77
FIN FIN
BIRD_WDN_O_MASK BIRD_WDN_O_MASK
hex FF,0F,0F,0F,FF,FF,0F,0F,0F,FF hex FF,0F,0F,0F,FF,FF,0F,0F,0F,FF
hex 0F,00,00,00,00,00,00,00,00,FF hex 0F,00,00,00,00,00,00,00,00,FF
hex 00,00,00,00,00,00,00,00,00,F0 hex 00,00,00,00,00,00,00,00,00,F0
hex F0,F0,F0,FF,FF,F0,F0,F0,FF,FF hex F0,F0,F0,FF,FF,F0,F0,F0,FF,FF
BIRD_WDN_O_IMASK BIRD_WDN_O_IMASK
hex 00,F0,F0,F0,00,00,F0,F0,F0,00 hex 00,F0,F0,F0,00,00,F0,F0,F0,00
hex F0,FF,FF,FF,FF,FF,FF,FF,FF,00 hex F0,FF,FF,FF,FF,FF,FF,FF,FF,00
hex FF,FF,FF,FF,FF,FF,FF,FF,FF,0F hex FF,FF,FF,FF,FF,FF,FF,FF,FF,0F
hex 0F,0F,0F,00,00,0F,0F,0F,00,00 hex 0F,0F,0F,00,00,0F,0F,0F,00,00
** y=line a=height x=col ** y=line a=height x=col
UndrawBird lda BIRD_Y_OLD UndrawBird lda BIRD_Y_OLD
lsr lsr
tay tay
bne :oddBird bne :oddBird
:evenBird lda #3 :evenBird lda #3
bne :continue bne :continue
:oddBird lda #4 :oddBird lda #4
:continue ldx #BIRD_X :continue ldx #BIRD_X
cmp #4 cmp #4
beq :undraw4 beq :undraw4
:undraw3 lda LoLineTableL,y :undraw3 lda LoLineTableL,y
sta SPRITE_SCREEN_P sta SPRITE_SCREEN_P
lda LoLineTableH,y lda LoLineTableH,y
sta SPRITE_SCREEN_P+1 sta SPRITE_SCREEN_P+1
lda LoLineTableL+1,y lda LoLineTableL+1,y
sta SPRITE_SCREEN_P2 sta SPRITE_SCREEN_P2
lda LoLineTableH+1,y lda LoLineTableH+1,y
sta SPRITE_SCREEN_P2+1 sta SPRITE_SCREEN_P2+1
lda LoLineTableL+2,y lda LoLineTableL+2,y
sta SPRITE_SCREEN_P3 sta SPRITE_SCREEN_P3
lda LoLineTableH+2,y lda LoLineTableH+2,y
sta SPRITE_SCREEN_P3+1 sta SPRITE_SCREEN_P3+1
txa txa
pha ; stash pha ; stash
tay ; COL offset tay ; COL offset
sta TXTPAGE2 sta TXTPAGE2
lda #BGCOLORAUX lda #BGCOLORAUX
:wipe1 sta (SPRITE_SCREEN_P),y :wipe1 sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y sta (SPRITE_SCREEN_P3),y
iny iny
:wipe1b sta (SPRITE_SCREEN_P),y :wipe1b sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y sta (SPRITE_SCREEN_P3),y
iny iny
:wipe1c sta (SPRITE_SCREEN_P),y :wipe1c sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y sta (SPRITE_SCREEN_P3),y
iny iny
:wipe1d sta (SPRITE_SCREEN_P),y :wipe1d sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y sta (SPRITE_SCREEN_P3),y
iny iny
:wipe1e sta (SPRITE_SCREEN_P),y :wipe1e sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y sta (SPRITE_SCREEN_P3),y
pla ; unstash pla ; unstash
tay tay
sta TXTPAGE1 sta TXTPAGE1
lda #BGCOLOR lda #BGCOLOR
:wipe2 sta (SPRITE_SCREEN_P),y :wipe2 sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y sta (SPRITE_SCREEN_P3),y
iny iny
:wipe2b sta (SPRITE_SCREEN_P),y :wipe2b sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y sta (SPRITE_SCREEN_P3),y
iny iny
:wipe2c sta (SPRITE_SCREEN_P),y :wipe2c sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y sta (SPRITE_SCREEN_P3),y
iny iny
:wipe2d sta (SPRITE_SCREEN_P),y :wipe2d sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y sta (SPRITE_SCREEN_P3),y
iny iny
:wipe2e sta (SPRITE_SCREEN_P),y :wipe2e sta (SPRITE_SCREEN_P),y
sta (SPRITE_SCREEN_P2),y sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P3),y sta (SPRITE_SCREEN_P3),y
rts 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 txa
sta SPRITE_SCREEN_P pha ; stash
lda LoLineTableH,y tay ; COL offset
sta SPRITE_SCREEN_P+1 sta TXTPAGE2
lda LoLineTableL+1,y lda #BGCOLORAUX
sta SPRITE_SCREEN_P2 :wipe3 sta (SPRITE_SCREEN_P),y
lda LoLineTableH+1,y sta (SPRITE_SCREEN_P2),y
sta SPRITE_SCREEN_P2+1 sta (SPRITE_SCREEN_P3),y
lda LoLineTableL+2,y sta (SPRITE_SCREEN_P4),y
sta SPRITE_SCREEN_P3 iny
lda LoLineTableH+2,y :wipe3b sta (SPRITE_SCREEN_P),y
sta SPRITE_SCREEN_P3+1 sta (SPRITE_SCREEN_P2),y
lda LoLineTableL+3,y sta (SPRITE_SCREEN_P3),y
sta SPRITE_SCREEN_P4 sta (SPRITE_SCREEN_P4),y
lda LoLineTableH+3,y iny
sta SPRITE_SCREEN_P4+1 :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 pla ; unstash
pha ; stash tay
tay ; COL offset sta TXTPAGE1
sta TXTPAGE2 lda #BGCOLOR
lda #BGCOLORAUX :wipe4 sta (SPRITE_SCREEN_P),y
:wipe3 sta (SPRITE_SCREEN_P),y sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P2),y sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P3),y sta (SPRITE_SCREEN_P4),y
sta (SPRITE_SCREEN_P4),y iny
iny :wipe4b sta (SPRITE_SCREEN_P),y
:wipe3b sta (SPRITE_SCREEN_P),y sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P2),y sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P3),y sta (SPRITE_SCREEN_P4),y
sta (SPRITE_SCREEN_P4),y iny
iny :wipe4c sta (SPRITE_SCREEN_P),y
:wipe3c sta (SPRITE_SCREEN_P),y sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P2),y sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P3),y sta (SPRITE_SCREEN_P4),y
sta (SPRITE_SCREEN_P4),y iny
iny :wipe4d sta (SPRITE_SCREEN_P),y
:wipe3d sta (SPRITE_SCREEN_P),y sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P2),y sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P3),y sta (SPRITE_SCREEN_P4),y
sta (SPRITE_SCREEN_P4),y iny
iny :wipe4e sta (SPRITE_SCREEN_P),y
:wipe3e sta (SPRITE_SCREEN_P),y sta (SPRITE_SCREEN_P2),y
sta (SPRITE_SCREEN_P2),y sta (SPRITE_SCREEN_P3),y
sta (SPRITE_SCREEN_P3),y sta (SPRITE_SCREEN_P4),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 DrawBird
lda BIRD_Y lda BIRD_Y
lsr lsr
bcs :oddHeight bcs :oddHeight
:evenHeight :evenHeight
sta SPRITE_Y sta SPRITE_Y
lda #3 lda #3
sta SPRITE_H sta SPRITE_H
lda BIRD_FLAP lda BIRD_FLAP
beq :flapDownEven beq :flapDownEven
:flapUpEven CopyPtr BIRD_WUP_E_PIXEL;SPRITE_DATA_P :flapUpEven CopyPtr BIRD_WUP_E_PIXEL;SPRITE_DATA_P
CopyPtr BIRD_WUP_E_MASK;SPRITE_MASK_P CopyPtr BIRD_WUP_E_MASK;SPRITE_MASK_P
CopyPtr BIRD_WUP_E_IMASK;SPRITE_IMASK_P CopyPtr BIRD_WUP_E_IMASK;SPRITE_IMASK_P
jmp :drawSprite jmp :drawSprite
:flapDownEven CopyPtr BIRD_WDN_E_PIXEL;SPRITE_DATA_P :flapDownEven CopyPtr BIRD_WDN_E_PIXEL;SPRITE_DATA_P
CopyPtr BIRD_WDN_E_MASK;SPRITE_MASK_P CopyPtr BIRD_WDN_E_MASK;SPRITE_MASK_P
CopyPtr BIRD_WDN_E_IMASK;SPRITE_IMASK_P CopyPtr BIRD_WDN_E_IMASK;SPRITE_IMASK_P
jmp :drawSprite jmp :drawSprite
:oddHeight :oddHeight
sta SPRITE_Y sta SPRITE_Y
lda #4 lda #4
sta SPRITE_H sta SPRITE_H
lda BIRD_FLAP lda BIRD_FLAP
beq :flapDownOdd beq :flapDownOdd
:flapUpOdd CopyPtr BIRD_WUP_O_PIXEL;SPRITE_DATA_P :flapUpOdd CopyPtr BIRD_WUP_O_PIXEL;SPRITE_DATA_P
CopyPtr BIRD_WUP_O_MASK;SPRITE_MASK_P CopyPtr BIRD_WUP_O_MASK;SPRITE_MASK_P
CopyPtr BIRD_WUP_O_IMASK;SPRITE_IMASK_P CopyPtr BIRD_WUP_O_IMASK;SPRITE_IMASK_P
jmp :drawSprite jmp :drawSprite
:flapDownOdd CopyPtr BIRD_WDN_O_PIXEL;SPRITE_DATA_P :flapDownOdd CopyPtr BIRD_WDN_O_PIXEL;SPRITE_DATA_P
CopyPtr BIRD_WDN_O_MASK;SPRITE_MASK_P CopyPtr BIRD_WDN_O_MASK;SPRITE_MASK_P
CopyPtr BIRD_WDN_O_IMASK;SPRITE_IMASK_P CopyPtr BIRD_WDN_O_IMASK;SPRITE_IMASK_P
jmp :drawSprite jmp :drawSprite
:drawSprite :drawSprite
jsr DrawSpriteBetter jsr DrawSpriteBetter
rts 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
* still does collision * still does collision
DrawSpriteBetter DrawSpriteBetter
lda #0 lda #0
sta SPRITE_X_IDX sta SPRITE_X_IDX
:drawLine lda SPRITE_Y ; :drawLine lda SPRITE_Y ;
tay tay
lda LoLineTableL,y ; SET SCREEN LINE lda LoLineTableL,y ; SET SCREEN LINE
sta SPRITE_SCREEN_P sta SPRITE_SCREEN_P
lda LoLineTableH,y lda LoLineTableH,y
sta SPRITE_SCREEN_P+1 sta SPRITE_SCREEN_P+1
lda #BIRD_X ;SPRITE_X ; ADD IN X OFFSET TO SCREEN POSITION lda #BIRD_X ;SPRITE_X ; ADD IN X OFFSET TO SCREEN POSITION
clc ; I think the highest position is $f8 clc ; I think the highest position is $f8
adc SPRITE_SCREEN_P ; eg- Line 18, col 40= $4f8 adc SPRITE_SCREEN_P ; eg- Line 18, col 40= $4f8
sta SPRITE_SCREEN_P ; SHOULD NEVER CARRY? sta SPRITE_SCREEN_P ; SHOULD NEVER CARRY?
jmp DrawSpriteLineC jmp DrawSpriteLineC
]DSLCD_done ]DSLCD_done
inc SPRITE_Y inc SPRITE_Y
dec SPRITE_H dec SPRITE_H
lda SPRITE_H lda SPRITE_H
bne :drawLine bne :drawLine
rts rts
DrawSpriteLineC DrawSpriteLineC
; EVEN COLS ; EVEN COLS
DD_EVEN lda #0 DD_EVEN lda #0
sta SPRITE_SCREEN_IDX sta SPRITE_SCREEN_IDX
sta TXTPAGE2 sta TXTPAGE2
:lineLoop :lineLoop
:collisionCheckDrawer :collisionCheckDrawer
ldy SPRITE_SCREEN_IDX ; GET SCREEN PIXELS ldy SPRITE_SCREEN_IDX ; GET SCREEN PIXELS
lda (SPRITE_SCREEN_P),y lda (SPRITE_SCREEN_P),y
ldy SPRITE_X_IDX ; PREP Y INDEX ldy SPRITE_X_IDX ; PREP Y INDEX
cmp #BGCOLORAUX ; AUX BGCOLOR @TODO cmp #BGCOLORAUX ; AUX BGCOLOR @TODO
beq :noCollisionSIMPLE beq :noCollisionSIMPLE
pha ; SAVE -> STACK pha ; SAVE -> STACK
and (SPRITE_IMASK_P),y and (SPRITE_IMASK_P),y
cmp #BGCOLORAUX_0LO cmp #BGCOLORAUX_0LO
beq :noCollision beq :noCollision
cmp #BGCOLORAUX_0HI cmp #BGCOLORAUX_0HI
beq :noCollision beq :noCollision
lda #1 lda #1
sta SPRITE_COLLISION sta SPRITE_COLLISION
:noCollision :noCollision
:doPixels pla ; Y=SPRITE X A=BG DATA :doPixels pla ; Y=SPRITE X A=BG DATA
and (SPRITE_MASK_P),y ; CUT OUT SPRITE IN BG DATA and (SPRITE_MASK_P),y ; CUT OUT SPRITE IN BG DATA
ora (SPRITE_DATA_P),y ; OVERLAY OUR SPRITE DATA ora (SPRITE_DATA_P),y ; OVERLAY OUR SPRITE DATA
ldy SPRITE_SCREEN_IDX ldy SPRITE_SCREEN_IDX
sta (SPRITE_SCREEN_P),y sta (SPRITE_SCREEN_P),y
sec sec
bcs :donePixel bcs :donePixel
:noCollisionSIMPLE :noCollisionSIMPLE
lda (SPRITE_DATA_P),y lda (SPRITE_DATA_P),y
ldy SPRITE_SCREEN_IDX ldy SPRITE_SCREEN_IDX
sta (SPRITE_SCREEN_P),y sta (SPRITE_SCREEN_P),y
:donePixel inc SPRITE_X_IDX :donePixel inc SPRITE_X_IDX
inc SPRITE_SCREEN_IDX inc SPRITE_SCREEN_IDX
ldy SPRITE_SCREEN_IDX ldy SPRITE_SCREEN_IDX
cpy SPRITE_W cpy SPRITE_W
bcc :lineLoop bcc :lineLoop
DD_ODD DD_ODD
; ODD COLS ; ODD COLS
lda #0 lda #0
sta SPRITE_SCREEN_IDX sta SPRITE_SCREEN_IDX
sta TXTPAGE1 sta TXTPAGE1
:lineLoop ;ldy SPRITE_X_IDX ;
;lda (SPRITE_IMASK_P),y
;beq :noPixel
:lineLoop
:collisionCheckDrawer :collisionCheckDrawer
ldy SPRITE_SCREEN_IDX ; GET SCREEN PIXELS ldy SPRITE_SCREEN_IDX ; GET SCREEN PIXELS
lda (SPRITE_SCREEN_P),y lda (SPRITE_SCREEN_P),y
ldy SPRITE_X_IDX ; PREP Y INDEX ldy SPRITE_X_IDX ; PREP Y INDEX
cmp #BGCOLOR ; MAIN BGCOLOR @TODO cmp #BGCOLOR ; MAIN BGCOLOR @TODO
beq :noCollisionSIMPLE beq :noCollisionSIMPLE
pha ; SAVE -> STACK pha ; SAVE -> STACK
and (SPRITE_IMASK_P),y and (SPRITE_IMASK_P),y
cmp #BGCOLOR_0LO cmp #BGCOLOR_0LO
beq :noCollision beq :noCollision
cmp #BGCOLOR_0HI cmp #BGCOLOR_0HI
beq :noCollision beq :noCollision
lda #1 lda #1
sta SPRITE_COLLISION sta SPRITE_COLLISION
:noCollision :noCollision
:doPixels pla ; Y=SPRITE X A=BG DATA :doPixels pla ; Y=SPRITE X A=BG DATA
and (SPRITE_MASK_P),y ; CUT OUT SPRITE IN BG DATA and (SPRITE_MASK_P),y ; CUT OUT SPRITE IN BG DATA
ora (SPRITE_DATA_P),y ; OVERLAY OUR SPRITE DATA ora (SPRITE_DATA_P),y ; OVERLAY OUR SPRITE DATA
ldy SPRITE_SCREEN_IDX ldy SPRITE_SCREEN_IDX
sta (SPRITE_SCREEN_P),y sta (SPRITE_SCREEN_P),y
sec sec
bcs :donePixel bcs :donePixel
:noCollisionSIMPLE :noCollisionSIMPLE
lda (SPRITE_DATA_P),y lda (SPRITE_DATA_P),y
ldy SPRITE_SCREEN_IDX ldy SPRITE_SCREEN_IDX
sta (SPRITE_SCREEN_P),y sta (SPRITE_SCREEN_P),y
:donePixel inc SPRITE_X_IDX :donePixel inc SPRITE_X_IDX
inc SPRITE_SCREEN_IDX inc SPRITE_SCREEN_IDX
ldy SPRITE_SCREEN_IDX ldy SPRITE_SCREEN_IDX
cpy SPRITE_W cpy SPRITE_W
bcc :lineLoop bcc :lineLoop
jmp ]DSLCD_done
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 typ $ff ; set P8 type ($ff = "SYS") for output file
xc off ; @todo force 6502? xc off ; @todo force 6502?
xc off 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 * Change this flag to build either color/mono version
MONO equ 0 * 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 DO MONO
* MONO VERSION BUILD
dsk fmono.system ; tell compiler output filename dsk fmono.system ; tell compiler output filename
BGCOLOR equ #$00 BGCOLOR equ #$00
BGCOLORAUX equ #$00 BGCOLORAUX equ #$00
@ -32,8 +26,8 @@ BGCOLOR_0HI equ #$00
BGCOLORAUX_0LO equ #$00 BGCOLORAUX_0LO equ #$00
BGCOLORAUX_0HI equ #$00 BGCOLORAUX_0HI equ #$00
; HANDLE COLOR DOODS
ELSE ELSE
* COLOR VERSION BUILD
dsk flap.system ; tell compiler output filename dsk flap.system ; tell compiler output filename
BGCOLOR equ #$77 BGCOLOR equ #$77
BGCOLORAUX equ #$BB BGCOLORAUX equ #$BB
@ -41,20 +35,31 @@ BGCOLOR_0LO equ #$70
BGCOLOR_0HI equ #$07 BGCOLOR_0HI equ #$07
BGCOLORAUX_0LO equ #$B0 BGCOLORAUX_0LO equ #$B0
BGCOLORAUX_0HI equ #$0B BGCOLORAUX_0HI equ #$0B
FIN 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 Main
jsr DetectMachine ; also inits vbl jsr SetupVBL
jsr LoadHiScore jsr LoadHiScore
jsr IntroWipe jsr IntroWipe
jsr DL_SetDLRMode jsr DL_SetDLRMode
Title
jsr VBlank AttractLoop
jsr WaitVBL
DO MONO DO MONO
lda #$FF lda #$FF
ELSE ELSE
@ -68,97 +73,87 @@ Title
ldy #BGCOLOR ldy #BGCOLOR
jsr DL_WipeIn jsr DL_WipeIn
jsr DrawFlogo jsr DrawFlogo
lda FlogoCount lda SongSkipCounter
and #%00000011 ; every 4 times? and #%00000011 ; throttle to play song every 4 times?
bne :noSongForYou bne :noSongForYou
jsr PlayFlappySong ;@todo throttle jsr SND_PlayFlappySong
:noSongForYou :noSongForYou
inc FlogoCount inc SongSkipCounter
ldx #60 ldx #60
ldy #2 ldy #2
jsr WaitKeyXY jsr WaitKeyXY
PreGameLoop PlayfieldAttract
** INIT ALL GAME STATE ITEMS * INITIALIZE ALL GAME STATE VALUES
lda #BIRD_X
sta SPRITE_X
lda #BIRD_Y_INIT lda #BIRD_Y_INIT
sta BIRD_Y sta BIRD_Y
sta BIRD_Y_OLD sta BIRD_Y_OLD
lda #BIRD_WIDTH
sta SPRITE_W
lda #0 lda #0
sta SPRITE_COLLISION sta SPRITE_COLLISION
sta PreGameTick sta AttractTick
sta PreGameTick+1 sta AttractTick+1
sta PreGameText sta AttractText
sta ScoreLo sta ScoreLo
sta ScoreHi sta ScoreHi
lda #0
ldx #3 ldx #3
:clearPipes sta TopPipes,x :zeroPipes sta TopPipes,x
sta BotPipes sta BotPipes,x
dex dex
bpl :clearPipes bpl :zeroPipes
** CLEAR SCREEN - SETUP BIRD * CLEAR SCREEN TO PLAYFIELD COLOR
jsr VBlank jsr WaitVBL
lda #BGCOLOR lda #BGCOLOR
jsr DL_Clear 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 * ANIMATE PLAYFIELD/BIRD WHILE WAITING FOR A KEYPRESS
:noKey jsr VBlank :attractAnimLoop jsr WaitVBL
jsr UndrawBird jsr UndrawBird
jsr DrawBird jsr DrawBird
jsr UpdateGrass jsr UpdateGrass
jsr FlapBird jsr FlapBird
inc PreGameTick inc AttractTick
bne :noOverflow bne :noOverflow
inc PreGameTick+1 inc AttractTick+1
:noOverflow lda PreGameTick :noOverflow lda AttractTick
cmp #60 cmp #60 ; on the 60th tick (aka after 1 second)
bcc :skipText
lda PreGameText
bne :skipText bne :skipText
inc PreGameText jsr DrawTap ; draw the "tap to flap" message
jsr DrawTap
:skipText :skipText
lda PreGameTick+1 lda AttractTick+1
cmp #2 cmp #2 ; on the 0x200 aka 512th tick, switch to hiscore screen
bne :checkKey bne :checkKey
jmp HiScreen jmp HiScreen
:checkKey jsr ButtonsCheck :checkKey jsr ButtonsCheck
bcs :key bcs :keyPressed
lda KEY lda KEY
bpl :noKey bpl :attractAnimLoop
:key sta STROBE :keyPressed sta STROBE
lda #BGCOLOR lda #BGCOLOR
jsr DL_Clear jsr DL_Clear
jmp GameLoop jmp GameLoop
PreGameTick dw 0 AttractTick dw 0
AttractText db 0
PreGameText db 0
GSBORDER da _GSBORDER
_GSBORDER db 0
* MAIN GAME LOOP
GameLoop GameLoop
jsr VBlank jsr WaitVBL ; wait until we are in vertical blanking period
jsr UndrawBird ; overwrite sprite area with background color
jsr UndrawBird jsr DrawPipes ; draw pipes in new position (this wipes with bgcolor as it draws)
jsr DrawPipes jsr DrawScore ; draw the score indicator at the top (overlapping any pipes)
jsr DrawScore jsr DrawBird ; draw the bird
jsr DrawBird jmp UpdatePipes ; update the
jmp UpdatePipes
UpdatePipesDone UpdatePipesDone
DONTUPDATEPIPES
jsr FlapBird jsr FlapBird
jsr UpdateGrass jsr UpdateGrass
@ -175,7 +170,7 @@ GAME_OVER
jsr DrawPipes jsr DrawPipes
jsr DrawScore jsr DrawScore
jsr DrawSplosion jsr DrawSplosion
jsr SND_Static jsr SND_Crash
jsr UpdateHiScore jsr UpdateHiScore
lda #3 lda #3
sta SPR_Y sta SPR_Y
@ -205,13 +200,13 @@ GAME_OVER
lda QuitFlag lda QuitFlag
beq :noQuit beq :noQuit
jmp Quit jmp Quit
:noQuit jmp PreGameLoop :noQuit jmp PlayfieldAttract
:noKey :noKey
lda #$FA lda #$FA
ldx #$50 ldx #$50
ldy #$00 ldy #$00
jsr DL_WipeIn jsr DL_WipeIn
jmp Title jmp AttractLoop
HiScreen HiScreen
jsr GetRand jsr GetRand
jsr DL_Clear jsr DL_Clear
@ -230,74 +225,11 @@ HiScreen
lda QuitFlag lda QuitFlag
beq :noQuit beq :noQuit
jmp Quit jmp Quit
:noQuit jmp PreGameLoop :noQuit jmp PlayfieldAttract
:noKey jmp Title :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 HandleInput
lda BIRD_Y lda BIRD_Y
@ -400,9 +332,6 @@ PauseKeyCheck cmp #"p"
lda #0 lda #0
rts 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 LoadHiScore jsr CreateHiScoreFile
bcs :error bcs :error
jsr OpenHiScoreFile jsr OpenHiScoreFile
@ -428,7 +357,7 @@ CreateHiScoreFile
:error cmp #$47 ; dup filename - already created? :error cmp #$47 ; dup filename - already created?
bne :bail bne :bail
clc ; this is ok, clear error state 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 OpenHiScoreFile
jsr MLI jsr MLI
@ -445,7 +374,7 @@ OpenHiScoreFile
ReadHiScoreFile ReadHiScoreFile
lda #0 lda #0
sta IOBuffer sta IOBuffer
sta IOBuffer+1 ;zero load area, just in case sta IOBuffer+1 ; zero load area, just in case
lda OpenRefNum lda OpenRefNum
sta ReadRefNum sta ReadRefNum
jsr MLI jsr MLI
@ -493,7 +422,7 @@ WriteHiScoreFile
OpenHiScoreParam OpenHiScoreParam
dfb #$03 ; number of parameters dfb #$03 ; number of parameters
dw HiScoreFile dw HiScoreFile
dw $900 dw $900
OpenRefNum db 0 ; assigned by open call OpenRefNum db 0 ; assigned by open call
@ -501,7 +430,7 @@ HiScoreFile str 'flaphi'
CloseHiScoreParam CloseHiScoreParam
dfb #$01 ; number of parameters dfb #$01 ; number of parameters
CloseRefNum db 0 CloseRefNum db 0
@ -533,6 +462,7 @@ WriteResult dw 0 ; result count (amount transferred)
Quit jsr QRPause Quit jsr QRPause
jsr ShutDownVBL ; disable IIc VBL polling if needed
sta TXTPAGE1 ; Don't forget to give them back the right page! sta TXTPAGE1 ; Don't forget to give them back the right page!
jsr MLI ; first actual command, call ProDOS vector jsr MLI ; first actual command, call ProDOS vector
dfb $65 ; QUIT P8 request ($65) dfb $65 ; QUIT P8 request ($65)
@ -584,15 +514,16 @@ QRPause jsr DL_SetDLRMixMode
ldy #60 ldy #60
jsr WaitKeyXY jsr WaitKeyXY
rts rts
QuitStr str "http://dagenbrock.com/flappy" QuitStr str "https://github.com/digarok/flapple"
****************************** **************************************************
* Score Routines * Score Routines
********************* **************************************************
ScoreLo db 0 ; 0-99 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 HiScoreLo db 0
HiScoreHi db 0 HiScoreHi db 0
** Draw the Score - @todo - handle > 99 ** Draw the Score - @todo - handle > 99
DrawScore lda ScoreLo DrawScore lda ScoreLo
and #$0F and #$0F
@ -612,7 +543,7 @@ DrawScore lda ScoreLo
sta Lo02+18 sta Lo02+18
rts rts
** HANDLE HIGH SCORE ** HANDLE HIGH SCORE
UpdateHiScore UpdateHiScore
lda HiScoreHi lda HiScoreHi
cmp ScoreHi cmp ScoreHi
@ -623,7 +554,6 @@ UpdateHiScore
bcc :newHighScore bcc :newHighScore
bcs :noHighScore bcs :noHighScore
:newHighScore lda ScoreHi :newHighScore lda ScoreHi
sta HiScoreHi sta HiScoreHi
lda ScoreLo lda ScoreLo
@ -635,7 +565,7 @@ UpdateHiScore
************************************************** **************************************************
* Grass * Grass
************************************************** **************************************************
UpdateGrass inc GrassState UpdateGrass inc GrassState
lda GrassState lda GrassState
@ -842,7 +772,7 @@ WaitKey
WaitKeyXY WaitKeyXY
stx _waitX stx _waitX
:kloop jsr VBlank :kloop jsr WaitVBL
lda KEY lda KEY
bmi :kpress bmi :kpress
dex dex
@ -859,27 +789,8 @@ WaitKeyXY
rts rts
_waitX db 0 _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 IntroWipe
sta C80STOREON sta C80STOREON
@ -905,12 +816,12 @@ IntroText str "Dagen Brock presents..."
************************************************** **************************************************
* Wait for vertical blanking interval - IIe/IIgs * Wait for multiple VBLs
************************************************** **************************************************
VBlankX VBlankX
:xloop txa :xloop txa
pha pha
jsr VBlank jsr WaitVBL
pla pla
tax tax
dex dex
@ -918,94 +829,14 @@ VBlankX
rts 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
MLI equ $bf00 ; ProDOS entry point
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
put vbl
put util put util
put applerom put applerom
put dlrlib put dlrlib

View File

@ -2,192 +2,192 @@
* Well... optimized number drawing because, why not * Well... optimized number drawing because, why not
**** ****
BB equ #$00 BB equ #$00
BW equ #$F0 BW equ #$F0
WB equ #$0F WB equ #$0F
WW equ #$FF WW equ #$FF
DrawNum_Table da DrawNum_0 DrawNum_Table da DrawNum_0
da DrawNum_1 da DrawNum_1
da DrawNum_2 da DrawNum_2
da DrawNum_3 da DrawNum_3
da DrawNum_4 da DrawNum_4
da DrawNum_5 da DrawNum_5
da DrawNum_6 da DrawNum_6
da DrawNum_7 da DrawNum_7
da DrawNum_8 da DrawNum_8
da DrawNum_9 da DrawNum_9
* y = x, a=val (0-9) * y = x, a=val (0-9)
DrawNum DrawNum
asl asl
tax tax
lda DrawNum_Table,x lda DrawNum_Table,x
sta :jsrPtr+1 sta :jsrPtr+1
lda DrawNum_Table+1,x lda DrawNum_Table+1,x
sta :jsrPtr+2 sta :jsrPtr+2
tya tya
tax tax
:jsrPtr jsr DrawNum_0 :jsrPtr jsr DrawNum_0
rts rts
* x = x offset (even cols) 0-40 * x = x offset (even cols) 0-40
DrawNum_0 sta TXTPAGE2 DrawNum_0 sta TXTPAGE2
lda #BB lda #BB
sta Lo01,x sta Lo01,x
sta Lo02,x sta Lo02,x
sta Lo01+1,x sta Lo01+1,x
sta Lo02+1,X sta Lo02+1,X
sta TXTPAGE1 sta TXTPAGE1
lda #BW lda #BW
sta Lo01,x sta Lo01,x
lda #WB lda #WB
sta Lo02,x sta Lo02,x
lda #WW lda #WW
sta Lo01+1,x sta Lo01+1,x
sta Lo02+1,x sta Lo02+1,x
rts rts
DrawNum_1 sta TXTPAGE2 DrawNum_1 sta TXTPAGE2
lda #BW lda #BW
sta Lo01,x sta Lo01,x
lda #WB lda #WB
sta Lo02,x sta Lo02,x
sta Lo02+1,x sta Lo02+1,x
lda #WW lda #WW
sta Lo01+1,x sta Lo01+1,x
sta TXTPAGE1 sta TXTPAGE1
sta Lo01+1,x sta Lo01+1,x
sta Lo02+1,x sta Lo02+1,x
lda #BB lda #BB
sta Lo01,x sta Lo01,x
sta Lo02,x sta Lo02,x
rts rts
DrawNum_2 sta TXTPAGE2 DrawNum_2 sta TXTPAGE2
lda #BW lda #BW
sta Lo01,x sta Lo01,x
lda #WB lda #WB
sta Lo02+1,x sta Lo02+1,x
lda #BB lda #BB
sta Lo02,x sta Lo02,x
sta Lo01+1,x sta Lo01+1,x
sta TXTPAGE1 sta TXTPAGE1
sta Lo01,x sta Lo01,x
sta Lo02,x sta Lo02,x
lda #WW lda #WW
sta Lo01+1,x sta Lo01+1,x
sta Lo02+1,x sta Lo02+1,x
rts rts
DrawNum_3 sta TXTPAGE2 DrawNum_3 sta TXTPAGE2
lda #BW lda #BW
sta Lo01,x sta Lo01,x
lda #WB lda #WB
sta Lo02,x sta Lo02,x
lda #BB lda #BB
sta Lo01+1,x sta Lo01+1,x
sta Lo02+1,x sta Lo02+1,x
sta TXTPAGE1 sta TXTPAGE1
sta Lo01,x sta Lo01,x
lda #WB lda #WB
sta Lo02,x sta Lo02,x
lda #WW lda #WW
sta Lo01+1,x sta Lo01+1,x
sta Lo02+1,x sta Lo02+1,x
rts rts
DrawNum_4 sta TXTPAGE2 DrawNum_4 sta TXTPAGE2
lda #BB lda #BB
sta Lo01,x sta Lo01,x
sta Lo01+1,x sta Lo01+1,x
sta Lo02+1,x sta Lo02+1,x
lda #BW lda #BW
sta Lo02,x sta Lo02,x
sta TXTPAGE1 sta TXTPAGE1
sta Lo02,x sta Lo02,x
lda #WW lda #WW
sta Lo01,x sta Lo01,x
sta Lo01+1,x sta Lo01+1,x
sta Lo02+1,x sta Lo02+1,x
rts rts
DrawNum_5 sta TXTPAGE2 DrawNum_5 sta TXTPAGE2
lda #BW lda #BW
sta Lo01+1,x sta Lo01+1,x
lda #WB lda #WB
sta Lo02,x sta Lo02,x
lda #BB lda #BB
sta Lo01,x sta Lo01,x
sta Lo02+1,x sta Lo02+1,x
sta TXTPAGE1 sta TXTPAGE1
sta Lo01,x sta Lo01,x
sta Lo02,x sta Lo02,x
lda #WW lda #WW
sta Lo01+1,x sta Lo01+1,x
sta Lo02+1,x sta Lo02+1,x
rts rts
DrawNum_6 sta TXTPAGE2 DrawNum_6 sta TXTPAGE2
lda #BB lda #BB
sta Lo01,x sta Lo01,x
sta Lo02,x sta Lo02,x
sta Lo02+1,x sta Lo02+1,x
lda #WB lda #WB
sta Lo01+1,x sta Lo01+1,x
sta TXTPAGE1 sta TXTPAGE1
sta Lo01,x sta Lo01,x
sta Lo02,x sta Lo02,x
lda #WW lda #WW
sta Lo01+1,x sta Lo01+1,x
sta Lo02+1,x sta Lo02+1,x
rts rts
DrawNum_7 sta TXTPAGE2 DrawNum_7 sta TXTPAGE2
lda #BW lda #BW
sta Lo01,x sta Lo01,x
lda #WW lda #WW
sta Lo02,x sta Lo02,x
sta Lo02+1,x sta Lo02+1,x
lda #BB lda #BB
sta Lo01+1,x sta Lo01+1,x
sta TXTPAGE1 sta TXTPAGE1
sta Lo02,x sta Lo02,x
lda #BW lda #BW
sta Lo01,x sta Lo01,x
lda #WW lda #WW
sta Lo01+1,x sta Lo01+1,x
sta Lo02+1,x sta Lo02+1,x
rts rts
DrawNum_8 sta TXTPAGE2 DrawNum_8 sta TXTPAGE2
lda #WB lda #WB
sta Lo01,x sta Lo01,x
lda #BB lda #BB
sta Lo02,X sta Lo02,X
sta Lo01+1,x sta Lo01+1,x
sta Lo02+1,x sta Lo02+1,x
sta TXTPAGE1 sta TXTPAGE1
sta Lo02,x sta Lo02,x
lda #BW lda #BW
sta Lo01,x sta Lo01,x
lda #WW lda #WW
sta Lo01+1,x sta Lo01+1,x
sta Lo02+1,x sta Lo02+1,x
rts rts
DrawNum_9 sta TXTPAGE2 DrawNum_9 sta TXTPAGE2
lda #BB lda #BB
sta Lo01,x sta Lo01,x
sta Lo01+1,x sta Lo01+1,x
sta Lo02+1,x sta Lo02+1,x
lda #BW lda #BW
sta Lo02,x sta Lo02,x
sta TXTPAGE1 sta TXTPAGE1
sta Lo01,x sta Lo01,x
sta Lo02,x sta Lo02,x
lda #WW lda #WW
sta Lo01+1,x sta Lo01+1,x
sta Lo02+1,x sta Lo02+1,x
rts 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 * Flapple Bird - A de-make of Flappy Bird for the Apple II computer
* *
* More information about this project is available at * # Download releases here:
* http://dagenbrock.com/flappy * https://github.com/digarok/flapple/releases
* *
* How to run * # How to run
* ========== * You can download either disk image and run it with an emulator like GSplus
* You can download either disk image and run it with an emulator * or transfer to the respective media and run on a real machine (recommended).
* or transfer it to the respective media and run it on a real * - `flapple800.po` is the 3.5" ProDOS disk version (800KB)
* machine (recommended). * - `flapple140.po` is the 5.25" ProDOS disk version (140KB)
* The 3.5" ProDOS disk version is "flapple800.po", and the
* 5.25" ProDOS disk version is "flapple140.po".
* *
* How to build * 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.
* This is written to compile on Merlin 8/16, but I believe should * To run it, quit game with the `q` key, and from the ProDOS selector menu
* work with all later Merlin variants. Load Merlin, then 'L'oad * run `fmono.system`.
* the file "flapple.s", finally hit OpenApple-A to assemble and
* it should build the "flap.system" file.
* *
* # 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/).
* *
* * - Classic Merlin16+ on an Apple IIgs
* Again, more information about this project is available at * - Load Merlin, then `L`oad the file "flapple.s", finally hit OpenApple-A to assemble and it should build the "flap.system" file.
* http://dagenbrock.com/flappy * - 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 * Flappy's Devastating Crash Sound
ldy #0 SND_Crash
:loop lda FlappySong,y ldx #$80 ;LENGTH OF NOISE BURST
cmp #NoteEnd jsr SEStaticBurst
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 ldx #$60 ;LENGTH OF NOISE BURST
hex 72,22,72,22,56,22,01,0E :spkLoop2 lda SPEAKER ;TOGGLE SPEAKER
hex 72,22,72,22,56,22,01,0E jsr GetRand
hex 72,22,72,22,80,22,01,0E and #%1000000
hex 72,22,72,22,56,22,01,0E tay
hex 72,22,72,22,56,22,01,0E :waitLoop2 dey ;DELAY LOOP FOR PULSE WIDTH
hex 72,22,72,22,4C,22,56,22 bne :waitLoop2
hex 5B,22,72,22,5B,22,56,40 dex ;GET NEXT PULSE OF THIS NOISE BURST
hex 02 ; end byte 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 * a = freq ... x = dur
************************************************** **************************************************
SENoteAX jsr _storeReg SENoteAX jsr _storeReg
sta _SECURRNOTE sta _SECURRNOTE
stx _SECURRNOTE+1 stx _SECURRNOTE+1
jsr SEplayNote jsr SEplayNote
jsr _loadReg jsr _loadReg
rts rts
************************************************** **************************************************
* _SECURRNOTE db 0,0 ; current note being played (frequency/duration)
**************************************************
ds \
ds \ ; align
SEplayNote SEplayNote
ldy _SECURRNOTE+1 ldy _SECURRNOTE+1
:loop lda SPEAKER :loop lda SPEAKER
:whyWut dey :whyWut dey
bne :thar bne :thar
dec _SECURRNOTE+1 dec _SECURRNOTE+1
beq :doneThat beq :doneThat
:thar dex :thar dex
bne :whyWut bne :whyWut
ldx _SECURRNOTE ldx _SECURRNOTE
jmp :loop jmp :loop
:doneThat rts :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 * This is essentially the scale
************************************************** **************************************************
_SE_tones db NoteG0,NoteGsharp0,NoteA0,NoteBflat0,NoteB0 _SE_tones db NoteG0,NoteGsharp0,NoteA0,NoteBflat0,NoteB0
db NoteC1,NoteCsharp1,NoteD1,NoteDsharp1,NoteE1 db NoteC1,NoteCsharp1,NoteD1,NoteDsharp1,NoteE1
db NoteF1,NoteFsharp1,NoteG1,NoteGsharp1,NoteA1 db NoteF1,NoteFsharp1,NoteG1,NoteGsharp1,NoteA1
db NoteBflat1,NoteB1,NoteC2,NoteCsharp2,NoteD2 db NoteBflat1,NoteB1,NoteC2,NoteCsharp2,NoteD2
db NoteDsharp2,NoteE2,NoteF2 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
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_X db 0
SPRITE_Y db 0 ; BYTE,not pixel. gotta be, sorry SPRITE_Y db 0 ; BYTE,not pixel. gotta be, sorry
SPRITE_W db 0 SPRITE_W db 0
SPRITE_W_D2 db 0 SPRITE_W_D2 db 0
SPRITE_H db 0 ; <- in bytes SPRITE_H db 0 ; <- in bytes
SPRITE_MAIN da 0 SPRITE_MAIN da 0
SPRITE_AUX da 0 SPRITE_AUX da 0
SPRITE_MASK da 0 SPRITE_MASK da 0
SPRITE_IMASK da 0 SPRITE_IMASK da 0
SPRITE_COLLISION db 0 SPRITE_COLLISION db 0
SPRITE_Y_IDX dw 0 SPRITE_Y_IDX dw 0
SPRITE_X_IDX dw 0 SPRITE_X_IDX dw 0
SPRITE_SCREEN_P equz $00 SPRITE_SCREEN_P equz $00
SPRITE_MAIN_P equz $02 SPRITE_MAIN_P equz $02
SPRITE_SCREEN_P2 equz $02 SPRITE_SCREEN_P2 equz $02
SPRITE_AUX_P equz $04 SPRITE_AUX_P equz $04
SPRITE_SCREEN_P3 equz $04 SPRITE_SCREEN_P3 equz $04
SPRITE_MASK_P equz $FA SPRITE_MASK_P equz $FA
SPRITE_SCREEN_P4 equz $FA SPRITE_SCREEN_P4 equz $FA
SPRITE_IMASK_P equz $FC SPRITE_IMASK_P equz $FC
SPRITE_SCREEN_IDX db #$0 SPRITE_SCREEN_IDX db #$0
AUX_BG_COLOR db #$BB AUX_BG_COLOR db #$BB
MAIN_BG_COLOR db #$77 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
* still does collision * still does collision
DrawSpriteBetter DrawSpriteBetter
lda #0 lda #0
sta SPRITE_X_IDX sta SPRITE_X_IDX
:drawLine lda SPRITE_Y ; :drawLine lda SPRITE_Y ;
tay tay
lda LoLineTableL,y ; SET SCREEN LINE lda LoLineTableL,y ; SET SCREEN LINE
sta SPRITE_SCREEN_P sta SPRITE_SCREEN_P
lda LoLineTableH,y lda LoLineTableH,y
sta SPRITE_SCREEN_P+1 sta SPRITE_SCREEN_P+1
lda SPRITE_X ; ADD IN X OFFSET TO SCREEN POSITION lda SPRITE_X ; ADD IN X OFFSET TO SCREEN POSITION
clc ; I think the highest position is $f8 clc ; I think the highest position is $f8
adc SPRITE_SCREEN_P ; eg- Line 18, col 40= $4f8 adc SPRITE_SCREEN_P ; eg- Line 18, col 40= $4f8
sta SPRITE_SCREEN_P ; SHOULD NEVER CARRY? sta SPRITE_SCREEN_P ; SHOULD NEVER CARRY?
jmp DrawSpriteLineC jmp DrawSpriteLineC
]DSLCD_done ]DSLCD_done
inc SPRITE_Y inc SPRITE_Y
dec SPRITE_H dec SPRITE_H
lda SPRITE_H lda SPRITE_H
bne :drawLine bne :drawLine
rts rts
DrawSpriteLineC DrawSpriteLineC
; EVEN COLS ; EVEN COLS
DD_EVEN lda #0 DD_EVEN lda #0
sta SPRITE_SCREEN_IDX sta SPRITE_SCREEN_IDX
sta TXTPAGE2 sta TXTPAGE2
:lineLoop :lineLoop
;ldy SPRITE_X_IDX ; ;ldy SPRITE_X_IDX ;
;lda (SPRITE_IMASK_P),y ;lda (SPRITE_IMASK_P),y
;beq :noPixel ;beq :noPixel
:collisionCheckDrawer :collisionCheckDrawer
ldy SPRITE_SCREEN_IDX ; GET SCREEN PIXELS ldy SPRITE_SCREEN_IDX ; GET SCREEN PIXELS
lda (SPRITE_SCREEN_P),y lda (SPRITE_SCREEN_P),y
pha ; SAVE -> STACK pha ; SAVE -> STACK
ldy SPRITE_X_IDX ; PREP Y INDEX ldy SPRITE_X_IDX ; PREP Y INDEX
cmp #$BB ; AUX BGCOLOR @TODO cmp #$BB ; AUX BGCOLOR @TODO
beq :noCollision beq :noCollision
and (SPRITE_IMASK_P),y and (SPRITE_IMASK_P),y
cmp #$B0 cmp #$B0
beq :noCollision beq :noCollision
cmp #$0B cmp #$0B
beq :noCollision beq :noCollision
lda #1 lda #1
sta SPRITE_COLLISION sta SPRITE_COLLISION
sta $c034 sta $c034
:noCollision :noCollision
:doPixels pla ; Y=SPRITE X A=BG DATA :doPixels pla ; Y=SPRITE X A=BG DATA
and (SPRITE_MASK_P),y ; CUT OUT SPRITE IN BG DATA and (SPRITE_MASK_P),y ; CUT OUT SPRITE IN BG DATA
ora (SPRITE_AUX_P),y ; OVERLAY OUR SPRITE DATA ora (SPRITE_AUX_P),y ; OVERLAY OUR SPRITE DATA
ldy SPRITE_SCREEN_IDX ldy SPRITE_SCREEN_IDX
sta (SPRITE_SCREEN_P),y sta (SPRITE_SCREEN_P),y
:noPixel inc SPRITE_X_IDX :noPixel inc SPRITE_X_IDX
inc SPRITE_X_IDX inc SPRITE_X_IDX
inc SPRITE_SCREEN_IDX inc SPRITE_SCREEN_IDX
ldy SPRITE_SCREEN_IDX ldy SPRITE_SCREEN_IDX
cpy SPRITE_W cpy SPRITE_W
bcc :lineLoop bcc :lineLoop
DD_ODD DD_ODD
; ODD COLS ; ODD COLS
inc SPRITE_X_IDX ; + 1 column offset inc SPRITE_X_IDX ; + 1 column offset
lda SPRITE_X_IDX lda SPRITE_X_IDX
sec sec
sbc SPRITE_W ; RESET DATA PTR sbc SPRITE_W ; RESET DATA PTR
sbc SPRITE_W ; *2 due to pixel skip sbc SPRITE_W ; *2 due to pixel skip
sta SPRITE_X_IDX sta SPRITE_X_IDX
lda #0 lda #0
sta SPRITE_SCREEN_IDX sta SPRITE_SCREEN_IDX
sta TXTPAGE1 sta TXTPAGE1
:lineLoop ;ldy SPRITE_X_IDX ; :lineLoop ;ldy SPRITE_X_IDX ;
;lda (SPRITE_IMASK_P),y ;lda (SPRITE_IMASK_P),y
;beq :noPixel ;beq :noPixel
:collisionCheckDrawer :collisionCheckDrawer
ldy SPRITE_SCREEN_IDX ; GET SCREEN PIXELS ldy SPRITE_SCREEN_IDX ; GET SCREEN PIXELS
lda (SPRITE_SCREEN_P),y lda (SPRITE_SCREEN_P),y
pha ; SAVE -> STACK pha ; SAVE -> STACK
ldy SPRITE_X_IDX ; PREP Y INDEX ldy SPRITE_X_IDX ; PREP Y INDEX
cmp #$77 ; MAIN BGCOLOR @TODO cmp #$77 ; MAIN BGCOLOR @TODO
beq :noCollision beq :noCollision
and (SPRITE_IMASK_P),y and (SPRITE_IMASK_P),y
cmp #$70 cmp #$70
beq :noCollision beq :noCollision
cmp #$07 cmp #$07
beq :noCollision beq :noCollision
lda #1 lda #1
sta SPRITE_COLLISION sta SPRITE_COLLISION
sta $c034 sta $c034
:noCollision :noCollision
:doPixels pla ; Y=SPRITE X A=BG DATA :doPixels pla ; Y=SPRITE X A=BG DATA
and (SPRITE_MASK_P),y ; CUT OUT SPRITE IN BG DATA and (SPRITE_MASK_P),y ; CUT OUT SPRITE IN BG DATA
ora (SPRITE_MAIN_P),y ; OVERLAY OUR SPRITE DATA ora (SPRITE_MAIN_P),y ; OVERLAY OUR SPRITE DATA
ldy SPRITE_SCREEN_IDX ldy SPRITE_SCREEN_IDX
sta (SPRITE_SCREEN_P),y sta (SPRITE_SCREEN_P),y
:noPixel inc SPRITE_X_IDX :noPixel inc SPRITE_X_IDX
inc SPRITE_X_IDX inc SPRITE_X_IDX
inc SPRITE_SCREEN_IDX inc SPRITE_SCREEN_IDX
ldy SPRITE_SCREEN_IDX ldy SPRITE_SCREEN_IDX
cpy SPRITE_W cpy SPRITE_W
bcc :lineLoop bcc :lineLoop
dec SPRITE_X_IDX ; -1 column offset (for next row) dec SPRITE_X_IDX ; -1 column offset (for next row)
jmp ]DSLCD_done jmp ]DSLCD_done

View File

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