refactor for level support

This commit is contained in:
alpine9000
2016-05-13 20:54:45 +10:00
parent 598094f6e1
commit 50b54f3d80
11 changed files with 683 additions and 728 deletions
+1 -1
View File
@@ -11,7 +11,7 @@ BASE_ADDRESS=4000
# note: this must be high enough not to conflict with MFMbufE
BOOTBLOCK_ASM=alpine_bootblock.s
OBJS=out/init.o out/utils.o out/image.o out/blit.o out/joystick.o out/player.o out/items.o out/blitmtext.o out/blittext.o out/music.o out/P6112-Play.o out/splash.o out/background.o out/sound.o out/trackloader.o out/disk.o
OBJS=out/init.o out/utils.o out/image.o out/blit.o out/joystick.o out/player.o out/items.o out/blitmtext.o out/blittext.o out/music.o out/P6112-Play.o out/splash.o out/background.o out/sound.o out/trackloader.o out/disk.o out/counter.o out/map.o out/message.o
IMAGES=foreground.png \
background.png \
+2
View File
@@ -6,6 +6,8 @@ PLAYER_MOVE_DOWN equ 2
PLAYER_MOVE_LEFT equ 3
PLAYER_MOVE_RIGHT equ 4
PLAYER_LIVES_COUNTER equ '0003'
PLAYER_INITIAL_X equ $c0
PLAYER_LEFT_X equ $c0
PLAYER_INITIAL_Y equ $e4-32
+256
View File
@@ -0,0 +1,256 @@
copperList:
panelCopperListBpl1Ptr:
dc.w BPL1PTL,0
dc.w BPL1PTH,0
dc.w BPL2PTL,0
dc.w BPL2PTH,0
dc.w BPL3PTL,0
dc.w BPL3PTH,0
dc.w BPL4PTL,0
dc.w BPL4PTH,0
dc.w BPLCON1,0
dc.w DDFSTRT,(RASTER_X_START/2-SCREEN_RES)
dc.w DDFSTOP,(RASTER_X_START/2-SCREEN_RES)+(8*((SCREEN_WIDTH/16)-1))
dc.w BPLCON0,(4<<12)|COLOR_ON ; 4 bit planes
dc.w BPL1MOD,SCREEN_WIDTH_BYTES*4-SCREEN_WIDTH_BYTES
dc.w BPL2MOD,SCREEN_WIDTH_BYTES*4-SCREEN_WIDTH_BYTES
panelCopperPalettePtr:
include "out/panel-copper-list.s"
dc.w $5bd1,$fffe
dc.w BPL1MOD,BITPLANE_WIDTH_BYTES*SCREEN_BIT_DEPTH-SCREEN_WIDTH_BYTES-2
dc.w BPL2MOD,BITPLANE_WIDTH_BYTES*SCREEN_BIT_DEPTH-SCREEN_WIDTH_BYTES-2
dc.w BPLCON1
copperListScrollPtr:
dc.w 0
copperListBpl1Ptr:
;; this is where bitplanes are assigned to playfields
;; http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node0079.html
;; 3 bitplanes per playfield, playfield1 gets bitplanes 1,3,5
dc.w BPL1PTL,0
dc.w BPL1PTH,0
dc.w BPL3PTL,0
dc.w BPL3PTH,0
dc.w BPL5PTL,0
dc.w BPL5PTH,0
copperListBpl2Ptr:
;; 3 bitplanes per playfield, playfield2 gets bitplanes 2,4,6
dc.w BPL2PTL,0
dc.w BPL2PTH,0
dc.w BPL4PTL,0
dc.w BPL4PTH,0
dc.w BPL6PTL,0
dc.w BPL6PTH,0
dc.w DDFSTRT,(RASTER_X_START/2-SCREEN_RES)-8 ; -8 for extra scrolling word
dc.w DDFSTOP,(RASTER_X_START/2-SCREEN_RES)+(8*((SCREEN_WIDTH/16)-1))
dc.w BPLCON0,(SCREEN_BIT_DEPTH*2<<12)|COLOR_ON|DBLPF
if TIMING_TEST=1
dc.l $fffffffe
endif
playAreaCopperPalettePtr1:
;; the foreground color values are just place holders and will be poked with the correcr value
include "out/foreground-copper-list.s"
include "out/background-copper-list.s"
;; top flag row has it's own palette
dc.w $84d1
dc.w $fffe
flagsCopperPalettePtr1:
;; the foreground color values are just place holders and will be poked with the correcr value
include "out/foreground-copper-list.s"
include "out/background-copper-list.s"
dc.w $94d1
dc.w $fffe
;;
playAreaCopperPalettePtr2:
;; the foreground color values are just place holders and will be poked with the correcr value
include "out/foreground-copper-list.s"
include "out/background-copper-list.s"
;; bottom flag row has it's own palette
dc.w $f4d1
dc.w $fffe
flagsCopperPalettePtr2:
;; the foreground color values are just place holders and will be poked with the correcr value
include "out/foreground-copper-list.s"
include "out/background-copper-list.s"
dc.w $ffdf
dc.w $fffe
dc.w $04d1
dc.w $fffe
playAreaCopperPalettePtr3:
;; the foreground color values are just place holders and will be poked with the correcr value
include "out/foreground-copper-list.s"
include "out/background-copper-list.s"
dc.l $fffffffe
mpanelCopperList:
panelCopperListBpl1Ptr_MP:
dc.w BPL1PTL,0
dc.w BPL1PTH,0
dc.w BPL2PTL,0
dc.w BPL2PTH,0
dc.w BPL3PTL,0
dc.w BPL3PTH,0
dc.w BPL4PTL,0
dc.w BPL4PTH,0
dc.w BPLCON1,0
dc.w DDFSTRT,(RASTER_X_START/2-SCREEN_RES)
dc.w DDFSTOP,(RASTER_X_START/2-SCREEN_RES)+(8*((SCREEN_WIDTH/16)-1))
dc.w BPLCON0,(4<<12)|COLOR_ON ; 4 bit planes
dc.w BPL1MOD,SCREEN_WIDTH_BYTES*4-SCREEN_WIDTH_BYTES
dc.w BPL2MOD,SCREEN_WIDTH_BYTES*4-SCREEN_WIDTH_BYTES
include "out/panel-grey-copper.s"
dc.w $5bd1,$fffe
dc.w BPL1MOD,BITPLANE_WIDTH_BYTES*SCREEN_BIT_DEPTH-SCREEN_WIDTH_BYTES-2
dc.w BPL2MOD,BITPLANE_WIDTH_BYTES*SCREEN_BIT_DEPTH-SCREEN_WIDTH_BYTES-2
dc.w BPLCON1
copperListScrollPtr_MP:
dc.w 0
copperListBpl1Ptr_MP:
;; this is where bitplanes are assigned to playfields
;; http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node0079.html
;; 3 bitplanes per playfield, playfield1 gets bitplanes 1,3,5
dc.w BPL1PTL,0
dc.w BPL1PTH,0
dc.w BPL3PTL,0
dc.w BPL3PTH,0
dc.w BPL5PTL,0
dc.w BPL5PTH,0
copperListBpl2Ptr_MP:
;; 3 bitplanes per playfield, playfield2 gets bitplanes 2,4,6
dc.w BPL2PTL,0
dc.w BPL2PTH,0
dc.w BPL4PTL,0
dc.w BPL4PTH,0
dc.w BPL6PTL,0
dc.w BPL6PTH,0
dc.w DDFSTRT,(RASTER_X_START/2-SCREEN_RES)-8 ; -8 for extra scrolling word
dc.w DDFSTOP,(RASTER_X_START/2-SCREEN_RES)+(8*((SCREEN_WIDTH/16)-1))
dc.w BPLCON0,(SCREEN_BIT_DEPTH*2<<12)|COLOR_ON|DBLPF
playAreaCopperPalettePtr1_MP:
include "out/foreground-grey-copper.s"
include "out/background-grey-copper.s"
dc.w $84d1
dc.w $fffe
flagsCopperPalettePtr1_MP:
include "out/foreground-grey-copper.s"
include "out/background-grey-copper.s"
dc.w $94d1
dc.w $fffe
playAreaCopperPalettePtr2_MP:
include "out/foreground-grey-copper.s"
include "out/background-grey-copper.s"
mpanelWaitLinePtr:
dc.w MPANEL_COPPER_WAIT
dc.w $fffe
mpanelCopperListBpl1Ptr:
dc.w BPL1PTL,0
dc.w BPL1PTH,0
dc.w BPL2PTL,0
dc.w BPL2PTH,0
dc.w BPL3PTL,0
dc.w BPL3PTH,0
dc.w BPL4PTL,0
dc.w BPL4PTH,0
dc.w BPLCON1,0
dc.w DDFSTRT,(RASTER_X_START/2-SCREEN_RES)
dc.w DDFSTOP,(RASTER_X_START/2-SCREEN_RES)+(8*((SCREEN_WIDTH/16)-1))
dc.w BPLCON0,(4<<12)|COLOR_ON ; 4 bit planes
dc.w BPL1MOD,SCREEN_WIDTH_BYTES*4-SCREEN_WIDTH_BYTES
dc.w BPL2MOD,SCREEN_WIDTH_BYTES*4-SCREEN_WIDTH_BYTES
mpanelCopperPalettePtr_MP:
include "out/mpanel-copper-list.s"
dc.w $BAd1,$fffe
dc.w BPL1MOD,BITPLANE_WIDTH_BYTES*SCREEN_BIT_DEPTH-SCREEN_WIDTH_BYTES-2
dc.w BPL2MOD,BITPLANE_WIDTH_BYTES*SCREEN_BIT_DEPTH-SCREEN_WIDTH_BYTES-2
dc.w BPLCON1
copperListScrollPtr2_MP:
dc.w 0
copperListBpl1Ptr2_MP:
;; this is where bitplanes are assigned to playfields
;; http://amigadev.elowar.com/read/ADCD_2.1/Hardware_Manual_guide/node0079.html
;; 3 bitplanes per playfield, playfield1 gets bitplanes 1,3,5
dc.w BPL1PTL,0
dc.w BPL1PTH,0
dc.w BPL3PTL,0
dc.w BPL3PTH,0
dc.w BPL5PTL,0
dc.w BPL5PTH,0
copperListBpl2Ptr2_MP:
;; 3 bitplanes per playfield, playfield2 gets bitplanes 2,4,6
dc.w BPL2PTL,0
dc.w BPL2PTH,0
dc.w BPL4PTL,0
dc.w BPL4PTH,0
dc.w BPL6PTL,0
dc.w BPL6PTH,0
dc.w DDFSTRT,(RASTER_X_START/2-SCREEN_RES)-8 ; -8 for extra scrolling word
dc.w DDFSTOP,(RASTER_X_START/2-SCREEN_RES)+(8*((SCREEN_WIDTH/16)-1))
dc.w BPLCON0,(SCREEN_BIT_DEPTH*2<<12)|COLOR_ON|DBLPF
playAreaCopperPalettePtr3_MP:
include "out/foreground-grey-copper.s"
include "out/background-grey-copper.s"
dc.w $f4d1
dc.w $fffe
flagsCopperPalettePtr2_MP:
include "out/foreground-grey-copper.s"
include "out/background-grey-copper.s"
dc.w $ffdf
dc.w $fffe
dc.w $04d1
dc.w $fffe
playAreaCopperPalettePtr4_MP:
include "out/foreground-grey-copper.s"
include "out/background-grey-copper.s"
dc.l $fffffffe
xdef copperList
xdef mpanelCopperList
xdef mpanelCopperListBpl1Ptr
xdef copperListBpl1Ptr
xdef copperListBpl2Ptr
xdef copperListBpl1Ptr_MP
xdef copperListBpl1Ptr2_MP
xdef copperListBpl2Ptr_MP
xdef copperListBpl2Ptr2_MP
+59
View File
@@ -0,0 +1,59 @@
xdef RenderCounter
xdef ResetCounter
xdef IncrementCounter
xdef DecrementCounter
RenderCounter:
lea panel,a0
move.w #20,d1
jsr DrawText8
rts
ResetCounter:
move.l #"0000",(a0)
rts
IncrementCounter:
move.l a0,a1
add.l #3,a0
.loop:
sub.l d0,d0
move.b (a0),d0
addq.b #1,d0
cmp.b #'9',d0
ble .done
move.b #'0',d0
move.b d0,(a0)
sub.l #1,a0
cmp.l a1,a0
blt .startOfText
bra .loop
.done:
move.b d0,(a0)
.startOfText:
rts
DecrementCounter:
move.l a0,a1
add.l #3,a0
.loop:
sub.l d0,d0
move.b (a0),d0
cmp.b #'0',d0
beq .dontWrap
subq.b #1,d0
bra .done
.dontWrap:
move.b #'9',d0
move.b d0,(a0)
sub.l #1,a0
cmp.l a1,a0
blt .startOfText
bra .loop
.done:
move.b d0,(a0)
.startOfText:
rts
+115 -711
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="orthogonal" renderorder="right-down" width="100" height="8" tilewidth="16" tileheight="16" nextobjectid="1">
<tileset firstgid="1" name="foreground" tilewidth="16" tileheight="16" tilecount="320" columns="20">
<image source="assets/assets.png" width="320" height="256"/>
<image source="../assets/assets.png" width="320" height="256"/>
</tileset>
<tileset firstgid="321" name="items" tilewidth="16" tileheight="16" tilecount="320" columns="20">
<image source="assets/items.png" trans="000000" width="320" height="256"/>
<image source="../assets/items.png" trans="000000" width="320" height="256"/>
</tileset>
<layer name="foreground" width="100" height="8">
<data encoding="base64" compression="zlib">
@@ -18,7 +18,7 @@
</layer>
<layer name="items" width="100" height="8">
<data encoding="base64" compression="zlib">
eJztVVsOgjAQpNfxFooooqIBq/e/CZDQpJbusw3hg/mEmdnZ2Y8WxY4t4WTkmiNT0xnZDMdrFJkoz7WQY97UL9Zxaf65Gn/foyc87ok7lRk60XpwdNT+ruNY1x+z5DreGfB9AN8hfogbwgvzSBDLleLH0Wq7sOP/au669rhv5B4WuSOEisG1HofDfzJ2S4FEfxB6T/uF+ak+a+Qm4b04uBAajedXoIHmt5nfGsiP2j8G6Tsh7fCK8DX3WBMvIt9v4/l38DEAYj8UWQ==
eJztlVsOgyAQRWVp1arYh5Ko+9+KmpSEUuYpNX54PvHOneFOgkVxcSZKI6+5MWuckfXwuodiJsrzKHL02/LFMq7Mt1bjH3p0hMdz552qDJloPTh1I6HxGaeynsyv1uvugO8LOIf0Mdi+4nkkQHNp4dxHm4Vdv9efrG2gdcg+HLJHiJqhDXty9G9CMx/8ZknY7hfPT+VpGTuR0BA1Gs8c/fvEOTUrRspP6yn9T0gzbBH9v/exl+Hk813kYwFAERLp
</data>
</layer>
</map>
+3 -3
View File
@@ -1,10 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.0" orientation="orthogonal" renderorder="right-down" width="100" height="8" tilewidth="16" tileheight="16" nextobjectid="1">
<tileset firstgid="1" name="foreground" tilewidth="16" tileheight="16" tilecount="320" columns="20">
<image source="assets/assets.png" width="320" height="256"/>
<image source="../assets/assets.png" width="320" height="256"/>
</tileset>
<tileset firstgid="321" name="items" tilewidth="16" tileheight="16" tilecount="320" columns="20">
<image source="assets/items.png" trans="000000" width="320" height="256"/>
<image source="../assets/items.png" trans="000000" width="320" height="256"/>
</tileset>
<layer name="foreground" width="100" height="8">
<data encoding="base64" compression="zlib">
@@ -18,7 +18,7 @@
</layer>
<layer name="items" width="100" height="8">
<data encoding="base64" compression="zlib">
eJztVVsOgjAQpNfxFooooqIBq/e/CZDQpJbusw3hg/mEmdnZ2Y8WxY4t4WTkmiNT0xnZDMdrFJkoz7WQY97UL9Zxaf65Gn/foyc87ok7lRk60XpwdNT+ruNY1x+z5DreGfB9AN8hfogbwgvzSBDLleLH0Wq7sOP/au669rhv5B4WuSOEisG1HofDfzJ2S4FEfxB6T/uF+ak+a+Qm4b04uBAajedXoIHmt5nfGsiP2j8G6Tsh7fCK8DX3WBMvIt9v4/l38DEAYj8UWQ==
eJztlVsOgyAQRWVp1arYh5Ko+9+KmpSEUuYpNX54PvHOneFOgkVxcSZKI6+5MWuckfXwuodiJsrzKHL02/LFMq7Mt1bjH3p0hMdz552qDJloPTh1I6HxGaeynsyv1uvugO8LOIf0Mdi+4nkkQHNp4dxHm4Vdv9efrG2gdcg+HLJHiJqhDXty9G9CMx/8ZknY7hfPT+VpGTuR0BA1Gs8c/fvEOTUrRspP6yn9T0gzbBH9v/exl+Hk813kYwFAERLp
</data>
</layer>
</map>
+180
View File
@@ -0,0 +1,180 @@
include "includes.i"
xdef RenderPathway
xdef ClearPathway
RenderPathway:
move.l pathwayPlayerTileAddress,d5
andi.w #$fff0,d5 ; point the address to the last tile of the previous column
addq #2,d5 ;
move.l d5,a4
move.w #1,d5
.loopX:
move.w #6,d6 ; y index
move.w #0,d7 ; number of rows without a pathway
.loopY:
move.l pathwayMapPtr,a2
jsr GetMapTile
cmp.l a4,a2 ; search for the start column
ble .next
cmp.l pathwayPlayerTileAddress,a2
beq .next
move.l d0,a2
move.w (a2),d0
cmp.w #0,d0
beq .dontBlit
lea foregroundTilemap,a1
add.w d0,a1 ; source tile
move.l foregroundScrollX,d0
lsr.w #FOREGROUND_SCROLL_SHIFT_CONVERT,d0 ; convert to pixels
lsr.w #3,d0 ; bytes to scroll
move.l foregroundOffscreen,a0
add.l d0,a0
move.l #-BITPLANE_WIDTH_BYTES*SCREEN_BIT_DEPTH*8,d0
move.w d5,d4
mulu.w #2,d4
add.l d4,d0
add.l #10,d0
add.l d0,a0
move.l #10,d2
sub.l d6,d2
jsr BlitTile
bra .next
.dontBlit:
add.w #1,d7
cmp.w #7,d7
beq .skip
.next:
dbra d6,.loopY
add.w #1,d5
cmp.w #(FOREGROUND_PLAYAREA_WIDTH_WORDS/2)-0,d5 ; don't render pathways off the play area
beq .pathwayNotComplete
bra .loopX
.skip:
sub.w #1,pathwayRenderPending
rts
.pathwayNotComplete:
rts
ClearPathway:
sub.w #1,pathwayClearPending
move.l foregroundPlayerTileAddress,d7
andi.w #$fff0,d7 ; address of the last tile in the previous column
move.w #0,d5 ; x index
.loopX:
move.w #6,d6 ; y index
.loopY:
move.l foregroundMapPtr,a2 ;; todo: this will be too slow, it will render too many tiles
bsr GetMapTile
cmp.l d7,a2 ; finished clearing...
bgt .done
move.l d0,a2
move.w (a2),d0
if 0
move.l foregroundMapPtr,a3
move.w (a3),d0
endif
cmp.w #0,d0
beq .dontBlit
lea foregroundTilemap,a1
add.w d0,a1 ; source tile
move.l foregroundScrollX,d0
lsr.w #FOREGROUND_SCROLL_SHIFT_CONVERT,d0 ; convert to pixels
lsr.w #3,d0 ; bytes to scroll
move.l foregroundOffscreen,a0
add.l d0,a0
move.l #-BITPLANE_WIDTH_BYTES*SCREEN_BIT_DEPTH*8,d0
move.w d5,d4
mulu.w #2,d4
add.l d4,d0
add.l #10,d0
add.l d0,a0
move.l #10,d2
sub.l d6,d2
jsr BlitTile
bra .next
.dontBlit:
.next:
dbra d6,.loopY
add.w #1,d5
bra .loopX
;; dbra d5,.loopX
.done
rts
RenderMapTile:
;; d5 - x map index
;; d6 - y map index
move.l foregroundMapPtr,a2
bsr GetMapTile
move.l d0,a2
move.w (a2),d0
cmp.w #0,d0
beq .dontBlit
lea foregroundTilemap,a1
add.w d0,a1 ; source tile
move.l foregroundScrollX,d0
lsr.w #FOREGROUND_SCROLL_SHIFT_CONVERT,d0 ; convert to pixels
lsr.w #3,d0 ; bytes to scroll
move.l foregroundOffscreen,a0
add.l d0,a0
move.l #-BITPLANE_WIDTH_BYTES*SCREEN_BIT_DEPTH*8,d0
move.w d5,d4
mulu.w #2,d4
add.l d4,d0
add.l #10,d0
add.l d0,a0
move.l #10,d2
sub.l d6,d2
jsr BlitTile
.dontBlit:
rts
GetMapTile:
;; d5 - x board index
;; d6 - y board index
;; a2 - map
;;
;; d0 - pathwayOffset
;; calculate the a2 offset of the top right tile based on foreground scroll
move.l foregroundScrollX,d0
lsr.l #FOREGROUND_SCROLL_TILE_INDEX_CONVERT,d0
lsr.l #1,d0
and.b #$f0,d0
add.l d0,a2
move.l #(FOREGROUND_PLAYAREA_WIDTH_WORDS/2)-1,d1
sub.w d5,d1 ; x column
mulu.w #FOREGROUND_PLAYAREA_HEIGHT_WORDS*2,d1
sub.l d1,a2 ; player x if y == bottom ?
sub.l d1,d1
move.w #FOREGROUND_PLAYAREA_HEIGHT_WORDS-1,d1
sub.w d6,d1 ; y row
lsl.w #1,d1
add.l d1,a2
;; a2 now points at the tile at the coordinate
move.l a2,d0
rts
+57
View File
@@ -0,0 +1,57 @@
include "includes.i"
xdef Message
xdef InitialiseMessagePanel
xdef ShowMessagePanel
xdef HideMessagePanel
Message:
;; a0 - bitplane
;; a1 - text
;; d1 - ypos
move.w #SCREEN_WIDTH/2,d0
move.l a1,a2
.loop:
cmp.b #0,(a2)+
beq .lengthComplete
sub.w #4,d0
bra .loop
.lengthComplete:
move.w d0,d1
move.w #(32*4)<<6|(8),d0
lea mpanelOrig,a0
lea mpanel,a2
add.l #(40*4*8),a2
jsr SimpleBlit
lea mpanel,a0
move.w d1,d0
move.w #11,d1
jsr DrawMaskedText8
bsr ShowMessagePanel
rts
ShowMessagePanel:
jsr WaitVerticalBlank
lea mpanelCopperList,a0
move.l a0,COP1LC(a6)
rts
HideMessagePanel:
jsr WaitVerticalBlank
lea copperList,a0
move.l a0,COP1LC(a6)
rts
InitialiseMessagePanel:
lea mpanelCopperListBpl1Ptr,a0
lea mpanel,a1
jsr PokePanelBitplanePointers
rts
mpanel:
incbin "out/mpanel.bin"
mpanelOrig:
incbin "out/mpanelOrig.bin"
+6 -7
View File
@@ -23,7 +23,7 @@ PLAYER_INSTALL_COLOR_PALETTE equ 0
PLAYER_SPRITE_DATA equ 4
PLAYER_SPRITE_FALLING_DATA equ 8
InitialisePlayer:
ResetPlayer:
move.l playerSpriteConfig,a0
move.l PLAYER_SPRITE_DATA(a0),d0
add.l #6*PLAYER_SPRITE_VERTICAL_BYTES,d0
@@ -36,17 +36,16 @@ InitialisePlayer:
move.w #PLAYER_INITIAL_Y+16,spriteYEnd
rts
ResetPlayer:
HidePlayer:
move.w #0,spriteX
move.w #0,spriteY
move.w #0,spriteYEnd
rts
HidePlayer:
move.w #$7000,spriteX
rts
InitialisePlayer:
move.l #PLAYER_LIVES_COUNTER,livesCounterText
rts
ScrollSprites:
cmp.l #0,foregroundScrollPixels
beq .skip
+1 -3
View File
@@ -50,9 +50,7 @@ ShowSplash:
.wait:
jsr WaitVerticalBlank
jsr ReadJoystick
btst.b #0,joystick
beq .wait
jsr WaitForJoystick
rts