mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-08-18 10:29:04 +00:00
4300 lines
74 KiB
ArmAsm
4300 lines
74 KiB
ArmAsm
|
||
; From: http://www.deater.net/weave/vmwprod/tb1/tb_6502.html
|
||
|
||
.segment "INIT"
|
||
.segment "ONCE"
|
||
.segment "STARTUP"
|
||
.segment "CODE"
|
||
|
||
.define EQU =
|
||
|
||
; blt = bcc
|
||
; bge = bcs
|
||
|
||
;; ZERO PAGE
|
||
CH EQU $24
|
||
CV EQU $25
|
||
BASL EQU $28
|
||
BASH EQU $29
|
||
H2 EQU $2C
|
||
COLOR EQU $30
|
||
YSAV EQU $34
|
||
YSAV1 EQU $35
|
||
RANDOM_SEED EQU $43
|
||
|
||
;; Our Zero Page Allocations
|
||
|
||
PADDLE_STATUS EQU $CA
|
||
HISCORE_1 EQU $CB
|
||
HISCORE_2 EQU $CC
|
||
HISCORE_3 EQU $CD
|
||
HISCORE_H EQU $CE
|
||
HISCORE_L EQU $CF
|
||
|
||
BOSS_X EQU $D0
|
||
BOSS_XADD EQU $D1
|
||
BOSS_COUNT EQU $D2
|
||
BOSS_SMOKE EQU $D3
|
||
BOSS_EXPLODING EQU $D4
|
||
BOSS_WAITING EQU $D5
|
||
BOSS_HITS EQU $D6
|
||
BOSS_SHOOTING EQU $D7
|
||
|
||
ENEMIES_SPAWNED EQU $D8
|
||
ENEMY_TYPE EQU $D9
|
||
ENEMY_WAVE EQU $DA
|
||
CURRENT_INIT_X EQU $DB
|
||
CURRENT_ENEMY_KIND EQU $DC
|
||
TOTAL_ENEMIES_OUT EQU $DD
|
||
SCROLL EQU $DE
|
||
SOUND_ON EQU $DF
|
||
|
||
SHIPX EQU $E0
|
||
SHIPXADD EQU $E1
|
||
ENEMY_PL EQU $E2
|
||
ENEMY_PH EQU $E3
|
||
MISSILE_PL EQU $E4
|
||
MISSILE_PH EQU $E5
|
||
GR_PAGE EQU $E6
|
||
LEVEL EQU $E7
|
||
SHIELDS EQU $E8
|
||
SCOREL EQU $E9
|
||
SCOREH EQU $EA
|
||
BONUS_FLAGS EQU $EB
|
||
|
||
BCD_BYTEH EQU $EC
|
||
BCD_BYTE EQU $ED
|
||
|
||
COL_X1 EQU $EC
|
||
COL_X2 EQU $ED
|
||
COL_X3 EQU $EE
|
||
COL_X4 EQU $EF
|
||
|
||
ENEMY_EXPLODING EQU $F0
|
||
ENEMY_KIND EQU $F1
|
||
ENEMY_X EQU $F2
|
||
ENEMY_Y EQU $F3
|
||
ENEMY_XADD EQU $F4
|
||
ENEMY_YADD EQU $F5
|
||
ENEMY_XMIN EQU $F6
|
||
ENEMY_XMAX EQU $F7
|
||
|
||
BETWEEN_DELAY EQU $F8
|
||
ENEMY_WAIT EQU $F9
|
||
|
||
STRINGL EQU $FA
|
||
STRINGH EQU $FB
|
||
PARAM2 EQU $FC
|
||
RESULT EQU $FD
|
||
LASTKEY EQU $FE
|
||
TEMP EQU $FF
|
||
|
||
;; VECTORS
|
||
BASIC EQU $3D0 ;; VECTOR for return to Applesoft
|
||
|
||
KEYPRESS EQU $C000
|
||
KEYRESET EQU $C010
|
||
|
||
SPEAKER EQU $C030
|
||
|
||
;; SOFT SWITCHES
|
||
GR EQU $C050
|
||
TEXT EQU $C051
|
||
FULLGR EQU $C052
|
||
TEXTGR EQU $C053
|
||
PAGE0 EQU $C054
|
||
PAGE1 EQU $C055
|
||
LORES EQU $C056
|
||
HIRES EQU $C057
|
||
|
||
PADDLE_BUTTON0 EQU $C061
|
||
PADDL0 EQU $C064
|
||
PTRIG EQU $C070
|
||
|
||
;; MONITOR ROUTINES
|
||
HLINE EQU $F819 ;; HLINE Y,$2C at A
|
||
VLINE EQU $F828 ;; VLINE A,$2D at Y
|
||
CLRSCR EQU $F832 ;; Clear low-res screen
|
||
CLRTOP EQU $F836 ;; clear only top of low-res screen
|
||
SETCOL EQU $F864 ;; COLOR=A
|
||
BASCALC EQU $FBC1 ;;
|
||
HOME EQU $FC58 ;; Clear the text screen
|
||
WAIT EQU $FCA8 ;; delay 1/2(26+27A+5A^2) us
|
||
SETINV EQU $FE80 ;; INVERSE
|
||
SETNORM EQU $FE84 ;; NORMAL
|
||
COUT1 EQU $FDF0 ;; output A to screen
|
||
|
||
|
||
;; GAME PARAMETERS
|
||
NUM_MISSILES EQU 2
|
||
NUM_ENEMIES EQU 6
|
||
UP_SHIELDS EQU 32
|
||
WAVE_SIZE EQU 16
|
||
WAVES_TILL_BOSS EQU 5
|
||
|
||
;; BONUS_FLAGS
|
||
PERFECT_SHIELDS EQU $80
|
||
PERFECT_KILLS EQU $40
|
||
PERFECT_AIM EQU $1
|
||
|
||
|
||
;==========================================================
|
||
; MAIN()
|
||
;==========================================================
|
||
|
||
|
||
;==============================
|
||
; back up part of the zero page
|
||
;==============================
|
||
|
||
lda #>zero_page_save
|
||
sta BASH
|
||
lda #<zero_page_save
|
||
sta BASL
|
||
|
||
ldy #0
|
||
save_zp_loop:
|
||
lda $C8,Y ; copy $C8-$FF
|
||
sta (BASL),Y ; to (zero_page_save)
|
||
iny
|
||
cpy #$38 ; we copy 56 bytes
|
||
bne save_zp_loop
|
||
|
||
lda #$ff
|
||
sta SOUND_ON
|
||
|
||
|
||
;==========================
|
||
; set graphics mode, page 0
|
||
;==========================
|
||
jsr HOME
|
||
jsr set_page0_gr
|
||
|
||
;=================
|
||
; clear the screen
|
||
;=================
|
||
jsr CLRTOP
|
||
|
||
;====================
|
||
; setup the high score
|
||
;=====================
|
||
|
||
lda #$01
|
||
sta HISCORE_H
|
||
lda #$00
|
||
sta HISCORE_L
|
||
sta PADDLE_STATUS
|
||
|
||
; modestly make me the high scorer
|
||
lda #$D6
|
||
sta HISCORE_1
|
||
lda #$CD
|
||
sta HISCORE_2
|
||
lda #$D7
|
||
sta HISCORE_3
|
||
|
||
lda #>(score_string+31)
|
||
sta STRINGH
|
||
lda #<(score_string+31)
|
||
sta STRINGL
|
||
jsr print_high_score
|
||
|
||
;=============
|
||
; put vmw logo
|
||
;=============
|
||
|
||
lda #$7 ; y=7
|
||
sta CV
|
||
lda #$8 ; x=8
|
||
sta CH
|
||
lda #>vmw_sprite
|
||
sta STRINGH
|
||
lda #<vmw_sprite
|
||
sta STRINGL
|
||
jsr blit ; blit the vmw sprite
|
||
|
||
;==================================
|
||
; Write "A VMW SOFTWARE PRODUCTION"
|
||
;==================================
|
||
|
||
lda #>vmw_string ; string = vmw_string
|
||
sta STRINGH
|
||
lda #<vmw_string
|
||
sta STRINGL
|
||
jsr print_text_xy ; print the string
|
||
|
||
;======================
|
||
; wait until keypressed
|
||
;======================
|
||
jsr wait_until_keypressed
|
||
|
||
|
||
|
||
;======================
|
||
; Opening Graphic
|
||
;======================
|
||
opener:
|
||
|
||
;=================
|
||
; clear the screen
|
||
;=================
|
||
jsr set_page0_gr
|
||
|
||
jsr HOME ; clear the screen
|
||
jsr CLRTOP
|
||
|
||
;=======================
|
||
; put opening graphic up
|
||
;=======================
|
||
lda #$0 ; y=0
|
||
sta CV
|
||
sta CH
|
||
lda #>opener_sprite
|
||
sta STRINGH
|
||
lda #<opener_sprite
|
||
sta STRINGL
|
||
jsr blit ; blit the opener sprite
|
||
|
||
lda #$A ; y=10 (we had to split in two)
|
||
sta CV
|
||
lda #>opener_sprite_2
|
||
sta STRINGH
|
||
lda #<opener_sprite_2
|
||
sta STRINGL
|
||
jsr blit ; blit the second half of sprite
|
||
|
||
|
||
;================================================
|
||
; Write "MERCILESS MALICIOUS MARAUDING MARKETERS"
|
||
;================================================
|
||
|
||
lda #>mercy_string ; string = MMMM
|
||
sta STRINGH
|
||
lda #<mercy_string
|
||
sta STRINGL
|
||
jsr print_text_xy ; print the string
|
||
|
||
jsr wait_until_keypressed ; wait until key pressed
|
||
|
||
|
||
;==========================================================
|
||
; The MAIN MENU
|
||
;==========================================================
|
||
|
||
main_menu:
|
||
jsr set_page0_text ; enter text mode
|
||
jsr HOME ; clear screen
|
||
|
||
lda #>help_string ; string = "H FOR HELP"
|
||
sta STRINGH
|
||
lda #<help_string
|
||
sta STRINGL
|
||
jsr print_text_xy ; print the string
|
||
|
||
lda #$5
|
||
sta PARAM2
|
||
|
||
|
||
jsr do_menu ; do the menu
|
||
|
||
lda RESULT ; load menu item from page0
|
||
|
||
cmp #$0 ; is it zero?
|
||
bne check_1 ; if not move ahead
|
||
jmp do_new_game ; yes, start new game
|
||
|
||
check_1:
|
||
cmp #$1 ; is it one?
|
||
bne check_2 ; if not, move ahead
|
||
jmp do_about ; else, show about into
|
||
|
||
check_2:
|
||
cmp #$2 ; is it two?
|
||
bne check_3 ; if not, move ahead
|
||
jmp do_story ; else, do the story info
|
||
|
||
check_3:
|
||
cmp #$3 ; is it three?
|
||
bne check_4 ; if not, move ahead
|
||
jmp do_hi_score ; else, show hi-score
|
||
|
||
check_4:
|
||
cmp #$4 ; is it four?
|
||
bne check_5 ; if not move ahead
|
||
jmp exit ; if so exit
|
||
|
||
check_5:
|
||
jsr do_help
|
||
|
||
jmp main_menu ; return to main_menu loop
|
||
|
||
|
||
;==========================================================
|
||
; EXIT back to BASIC
|
||
;==========================================================
|
||
|
||
exit:
|
||
jsr SETNORM ; NORMAL text
|
||
jsr set_page0_text
|
||
|
||
;======================
|
||
; restore the zero page
|
||
;======================
|
||
|
||
lda #>zero_page_save
|
||
sta BASH
|
||
lda #<zero_page_save
|
||
sta BASL
|
||
|
||
ldy #0
|
||
restore_zp_loop:
|
||
lda (BASL),Y ; copy (zero_page_save)
|
||
sta $C8,Y ; back to $C8-$FF
|
||
iny
|
||
cpy #$38 ; we copy 56 bytes
|
||
bne restore_zp_loop
|
||
|
||
jsr HOME ; clear screen
|
||
jmp (BASIC) ; return to BASIC
|
||
|
||
|
||
|
||
;==========================================================
|
||
; do_menu
|
||
;==========================================================
|
||
; draw a text-mode menu
|
||
|
||
do_menu:
|
||
lda #$0 ; start with menu=0
|
||
sta RESULT
|
||
|
||
menu:
|
||
lda #$8 ; y=8
|
||
sta CV
|
||
|
||
|
||
lda #>new_game_string ; string starts at "NEW GAME"
|
||
sta STRINGH
|
||
lda #<new_game_string
|
||
sta STRINGL
|
||
|
||
|
||
ldy #$0 ; clear string offset pointer
|
||
|
||
ldx #$0 ; clear line count
|
||
|
||
next_line:
|
||
lda #$8D ; carriage return
|
||
jsr COUT1
|
||
|
||
lda #$10 ; x=16
|
||
sta CH
|
||
|
||
sty TEMP ; save Y as NORM/INV changes it
|
||
|
||
jsr SETNORM ; set text style to normal
|
||
|
||
cpx RESULT ; are we at the selected entry?
|
||
bne menu_restore_y ; if not, move on
|
||
|
||
jsr SETINV ; if so, reverse text
|
||
|
||
menu_restore_y:
|
||
ldy TEMP ; restore Y we saved earlier
|
||
|
||
menu_char:
|
||
|
||
|
||
lda (STRINGL),Y ; get char from strings
|
||
beq done_line ; if 0, done this line
|
||
jsr COUT1 ; monitor char output line
|
||
iny ; indexY ++
|
||
jmp menu_char ; loop till done line
|
||
|
||
done_line:
|
||
inx ; move to next line
|
||
iny ; pointer after null
|
||
cpx PARAM2 ; are we past end of menu?
|
||
bne next_line ; if not, print next line
|
||
|
||
menu_wait:
|
||
jsr wait_until_keypressed
|
||
|
||
lda LASTKEY
|
||
|
||
cmp #('Q')
|
||
bne check_h
|
||
lda #$4
|
||
sta RESULT
|
||
rts
|
||
|
||
check_h:
|
||
cmp #('H')
|
||
bne check_i
|
||
lda #$5 ; if help, set RESULT=5
|
||
sta RESULT
|
||
rts
|
||
|
||
check_i:
|
||
cmp #('I')
|
||
bne check_m
|
||
dec RESULT
|
||
jmp check_menu_values
|
||
|
||
check_m:
|
||
cmp #('M')
|
||
|
||
bne check_cr
|
||
|
||
inc RESULT
|
||
jmp check_menu_values
|
||
check_cr:
|
||
cmp #(13)
|
||
bne menu_wait
|
||
rts
|
||
|
||
|
||
|
||
check_menu_values:
|
||
|
||
lda RESULT
|
||
bpl check_menu_over
|
||
lda PARAM2
|
||
sbc #$1
|
||
sta RESULT
|
||
|
||
check_menu_over:
|
||
cmp PARAM2
|
||
bne menu
|
||
lda #$0
|
||
sta RESULT
|
||
|
||
jmp menu
|
||
|
||
|
||
|
||
|
||
|
||
;==========================================================
|
||
; do_about
|
||
;==========================================================
|
||
; print the "about" info
|
||
|
||
do_about:
|
||
bit GR
|
||
jsr CLRTOP
|
||
|
||
lda #$0 ; x,y= 12,0
|
||
sta CV
|
||
lda #$C
|
||
sta CH
|
||
|
||
lda #>vince_sprite
|
||
sta STRINGH
|
||
lda #<vince_sprite
|
||
sta STRINGL
|
||
jsr blit ; blit the pic of vince
|
||
|
||
lda #>about_lines
|
||
sta STRINGH
|
||
lda #<about_lines
|
||
sta STRINGL
|
||
jsr print_text_xy ; print text
|
||
jsr print_text_xy ; print text
|
||
|
||
jsr wait_until_keypressed
|
||
|
||
lda #$6 ; only want to clear bottom 3 lines
|
||
sta BASH ; so set pointer to $6D0
|
||
lda #$D0
|
||
sta BASL
|
||
ldx #$01 ; set X already to 1
|
||
jsr bottom_y ; and jump midway into clear_bottom
|
||
|
||
jsr print_text_xy ; print text
|
||
jsr print_text_xy ; print text
|
||
|
||
|
||
jsr wait_until_keypressed
|
||
|
||
jmp opener
|
||
|
||
;==========================================================
|
||
; do_help
|
||
;==========================================================
|
||
; print the "help" info
|
||
|
||
do_help:
|
||
jsr set_page0_text
|
||
jsr HOME
|
||
|
||
lda #>help_lines
|
||
sta STRINGH
|
||
lda #<help_lines
|
||
sta STRINGL
|
||
|
||
ldx #$14
|
||
jsr print_x_strings ; print text
|
||
|
||
|
||
jsr wait_until_keypressed
|
||
|
||
rts
|
||
|
||
|
||
|
||
;==========================================================
|
||
; do_story
|
||
;==========================================================
|
||
; the story routine
|
||
|
||
do_story:
|
||
bit GR
|
||
jsr CLRTOP
|
||
|
||
;
|
||
; draw the mars map
|
||
;
|
||
|
||
|
||
lda #$0 ; y=0
|
||
sta CV
|
||
sta CH
|
||
lda #>phobos_sprite
|
||
sta STRINGH
|
||
lda #<phobos_sprite
|
||
sta STRINGL
|
||
jsr blit ; blit the phobos sprite
|
||
|
||
|
||
lda #>story_lines
|
||
sta STRINGH
|
||
lda #<story_lines
|
||
sta STRINGL
|
||
|
||
jsr print_text_xy ; print text
|
||
jsr print_text_xy ; print text
|
||
jsr print_text_xy ; print text
|
||
jsr print_text_xy ; print text
|
||
|
||
jsr wait_until_keypressed
|
||
|
||
|
||
;
|
||
; animate the droid launch
|
||
;
|
||
|
||
jsr clear_bottom
|
||
|
||
jsr print_text_xy ; print text
|
||
jsr print_text_xy ; print text
|
||
jsr print_text_xy ; print text
|
||
|
||
lda #$12 ; x=18
|
||
sta CH
|
||
lda #$7
|
||
sta CV ; y=7
|
||
|
||
phobos_loop:
|
||
|
||
lda #>evil_ship_sprite
|
||
sta STRINGH
|
||
lda #<evil_ship_sprite
|
||
sta STRINGL
|
||
jsr blit ; blit the droid sprite
|
||
|
||
; delay
|
||
; wait 1/2 (26+27A+5A^2) us
|
||
|
||
lda #$8B ; 107 = 30080us = 30ms
|
||
jsr WAIT
|
||
|
||
lda #$0 ; set color to zero
|
||
jsr SETCOL
|
||
|
||
; HLINE H1,H2 at V1
|
||
lda CH ; get x value
|
||
tay ; move it to H1
|
||
adc #$3 ; add 3
|
||
sta H2 ; move it to H2
|
||
lda #$e ; set V1
|
||
jsr HLINE
|
||
|
||
ldy CH ; reset H1
|
||
lda #$f ; set V1 to bottom value
|
||
jsr HLINE
|
||
|
||
; move ship
|
||
|
||
inc CH ; incrememnt X
|
||
lda CH
|
||
cmp #$25 ; have we reached 37? (edge)
|
||
bne phobos_loop
|
||
|
||
|
||
|
||
jsr wait_until_keypressed
|
||
|
||
;
|
||
; "you are tom..."
|
||
;
|
||
|
||
jsr clear_bottom
|
||
jsr CLRTOP
|
||
|
||
lda #$1 ; y=0
|
||
sta CV
|
||
lda #$C ; x=12
|
||
sta CH
|
||
lda #>tom_sprite
|
||
sta STRINGH
|
||
lda #<tom_sprite
|
||
sta STRINGL
|
||
jsr blit ; blit the tom sprite
|
||
|
||
lda #>you_are_tom
|
||
sta STRINGH
|
||
lda #<you_are_tom
|
||
sta STRINGL
|
||
|
||
jsr print_text_xy ; print text
|
||
jsr print_text_xy ; print text
|
||
jsr print_text_xy ; print text
|
||
jsr print_text_xy ; print text
|
||
|
||
jsr wait_until_keypressed
|
||
|
||
jmp opener
|
||
|
||
|
||
;==========================================================
|
||
; do_ending
|
||
;==========================================================
|
||
; the ending you get after level 1
|
||
|
||
do_ending:
|
||
jsr set_page0_gr ; set graphics mode
|
||
jsr CLRTOP
|
||
jsr clear_bottom
|
||
|
||
;
|
||
; draw the earth
|
||
;
|
||
|
||
lda #$7 ; y=7
|
||
sta CV
|
||
lda #$F ; x=15
|
||
sta CH
|
||
lda #>earth_sprite
|
||
sta STRINGH
|
||
lda #<earth_sprite
|
||
sta STRINGL
|
||
jsr blit ; blit the earth sprite
|
||
|
||
|
||
lda #>ending_lines
|
||
sta STRINGH
|
||
lda #<ending_lines
|
||
sta STRINGL
|
||
|
||
jsr print_text_xy ; print text
|
||
jsr print_text_xy ; print text
|
||
jsr print_text_xy ; print text
|
||
|
||
ldx #30
|
||
jsr wait_X_100msec ; pause for 3 seconds
|
||
bit KEYRESET ; clear keyboard
|
||
|
||
jsr wait_until_keypressed
|
||
|
||
|
||
;
|
||
; second page
|
||
;
|
||
|
||
|
||
|
||
|
||
jsr clear_bottom
|
||
|
||
jsr print_text_xy ; print text
|
||
jsr print_text_xy ; print text
|
||
jsr print_text_xy ; print text
|
||
jsr print_text_xy ; print text
|
||
|
||
jsr wait_until_keypressed
|
||
|
||
;
|
||
; third page
|
||
;
|
||
|
||
jsr CLRTOP
|
||
jsr clear_bottom
|
||
|
||
;
|
||
; draw Susie
|
||
;
|
||
|
||
lda #$7 ; y=7
|
||
sta CV
|
||
lda #$A ; x=10
|
||
sta CH
|
||
lda #>susie_sprite
|
||
sta STRINGH
|
||
lda #<susie_sprite
|
||
sta STRINGL
|
||
jsr blit ; blit the susie sprite
|
||
|
||
|
||
lda #>susie_lines
|
||
sta STRINGH
|
||
lda #<susie_lines
|
||
sta STRINGL
|
||
|
||
jsr print_text_xy ; print text
|
||
jsr wait_until_keypressed
|
||
|
||
;
|
||
; fourth page
|
||
;
|
||
|
||
jsr CLRTOP
|
||
jsr clear_bottom
|
||
|
||
;
|
||
; draw Tom's head
|
||
;
|
||
|
||
lda #$7 ; y=7
|
||
sta CV
|
||
lda #$F ; x=15
|
||
sta CH
|
||
lda #>tom_head_sprite
|
||
sta STRINGH
|
||
lda #<tom_head_sprite
|
||
sta STRINGL
|
||
jsr blit ; blit Tom's head
|
||
|
||
|
||
lda #>tom_sigh
|
||
sta STRINGH
|
||
lda #<tom_sigh
|
||
sta STRINGL
|
||
|
||
jsr print_text_xy ; print text
|
||
jsr wait_until_keypressed
|
||
|
||
jmp no_ending
|
||
|
||
|
||
;==========================================================
|
||
; START NEW GAME
|
||
;==========================================================
|
||
|
||
|
||
do_new_game:
|
||
|
||
|
||
;; set up struct pointers
|
||
|
||
lda #>missile_0 ; clear the missile struct
|
||
sta MISSILE_PH ; should make this clear all BSS
|
||
lda #<missile_0 ; at some point
|
||
sta MISSILE_PL
|
||
|
||
lda #>enemy_0
|
||
sta ENEMY_PH
|
||
lda #<enemy_0
|
||
sta ENEMY_PL
|
||
|
||
;; Clear BSS
|
||
|
||
ldy #$0
|
||
lda #$0
|
||
clear_bss:
|
||
sta start_bss,Y
|
||
iny
|
||
cpy #end_bss-start_bss
|
||
bne clear_bss
|
||
|
||
;; Init one-time vars
|
||
|
||
lda #$8
|
||
sta SHIELDS ; shields start at 8
|
||
jsr update_shields
|
||
|
||
lda #$12
|
||
sta SHIPX ; shipx at start is 18
|
||
|
||
lda #$1
|
||
sta LEVEL ; start at level 1
|
||
|
||
lda #$0
|
||
sta SCOREL
|
||
sta SCOREH
|
||
jsr print_score
|
||
|
||
new_level:
|
||
|
||
;========================
|
||
; Setup various variables
|
||
;========================
|
||
|
||
|
||
|
||
lda #(PERFECT_AIM|PERFECT_SHIELDS|PERFECT_KILLS)
|
||
sta BONUS_FLAGS ; set perfect shot/shield/enemies
|
||
|
||
lda #$14
|
||
sta ENEMY_WAIT
|
||
|
||
lda #$0
|
||
sta BETWEEN_DELAY
|
||
sta SHIPXADD ; clear shipxadd
|
||
sta ENEMY_WAVE
|
||
sta TOTAL_ENEMIES_OUT
|
||
sta ENEMIES_SPAWNED
|
||
sta ENEMY_TYPE
|
||
|
||
;=======================
|
||
; Print "LEVEL X"
|
||
;=======================
|
||
|
||
jsr set_page0_text
|
||
jsr HOME
|
||
|
||
;===================
|
||
; set level to level
|
||
;===================
|
||
|
||
lda #>(level_string+9)
|
||
sta STRINGH
|
||
lda #<(level_string+9)
|
||
sta STRINGL
|
||
|
||
lda #0
|
||
sta BCD_BYTEH
|
||
lda LEVEL
|
||
sta BCD_BYTE
|
||
jsr print_bcd_byte
|
||
|
||
|
||
;======================
|
||
; Print level on screen
|
||
;======================
|
||
|
||
lda #>(level_string_xy)
|
||
sta STRINGH
|
||
lda #<(level_string_xy)
|
||
sta STRINGL
|
||
|
||
jsr print_text_xy
|
||
|
||
ldx #20
|
||
jsr wait_X_100msec ; pause for 3 seconds
|
||
bit KEYRESET ; clear keyboard
|
||
|
||
;==================================
|
||
; Enter graphics mode, clear screen
|
||
;==================================
|
||
|
||
jsr set_page0_gr ; set graphics mode
|
||
jsr clear_screen ; clear screen
|
||
|
||
|
||
draw_stars:
|
||
|
||
;=====================
|
||
; Setup star field
|
||
;=====================
|
||
|
||
lda #>(star_field)
|
||
sta STRINGH
|
||
lda #<(star_field)
|
||
sta STRINGL
|
||
|
||
ldy #$0
|
||
star_init:
|
||
jsr random_number
|
||
and #$9f
|
||
clc
|
||
adc #$4
|
||
sta (STRINGL),Y
|
||
iny
|
||
lda #$0
|
||
sta (STRINGL),Y
|
||
iny
|
||
bne star_init
|
||
|
||
lda #$0
|
||
sta SCROLL
|
||
|
||
|
||
;/========================\
|
||
;+ +
|
||
;+ MAIN GAME LOOP +
|
||
;+ +
|
||
;\========================/
|
||
|
||
main_game_loop:
|
||
jsr clear_screen ; clear screen
|
||
jsr show_stars
|
||
|
||
|
||
|
||
|
||
|
||
done_scrolling:
|
||
|
||
; ================================
|
||
; put out new enemies (if needed)
|
||
; ================================
|
||
|
||
inc BETWEEN_DELAY ; inc how long we've delayed
|
||
lda BETWEEN_DELAY ; load it in
|
||
cmp ENEMY_WAIT ; have we waited long enough?
|
||
beq reset_delay
|
||
|
||
jmp move_enemies ; if not, go on to movement
|
||
reset_delay:
|
||
|
||
; delay==wait, so attempt to put out new enemy
|
||
|
||
lda BETWEEN_DELAY
|
||
and #$1
|
||
sta BETWEEN_DELAY ; reset delay
|
||
|
||
; special case for boss
|
||
|
||
lda #$9 ; if boss, don't keep track of
|
||
cmp ENEMY_TYPE ; how many enemies were spawned
|
||
bne not_boss_dont_clear
|
||
|
||
lda #$1 ; store 1 so we don't increment wave
|
||
sta ENEMIES_SPAWNED
|
||
|
||
not_boss_dont_clear:
|
||
|
||
; see if we are at a new wave
|
||
; basically, if 16 have been spawned, change
|
||
|
||
lda ENEMIES_SPAWNED
|
||
and #$0f
|
||
bne same_enemy_type ; if not 16 gone by, move on
|
||
|
||
;=======================
|
||
; change the enemy type
|
||
|
||
inc ENEMIES_SPAWNED
|
||
|
||
jsr random_number
|
||
and #$7 ; get a random number 0-7
|
||
sta ENEMY_TYPE
|
||
|
||
inc ENEMY_WAVE
|
||
|
||
lda ENEMY_WAVE ; have we gone enough waves to reach boss?
|
||
cmp #WAVES_TILL_BOSS
|
||
bne not_boss_yet
|
||
|
||
lda #$8
|
||
sta ENEMY_TYPE
|
||
|
||
|
||
|
||
not_boss_yet:
|
||
|
||
; set various constants
|
||
; these may be overriden later
|
||
|
||
|
||
lda #20
|
||
sec
|
||
sbc LEVEL
|
||
sta ENEMY_WAIT ; enemy_wait=20-level
|
||
|
||
; set kind and init x to be random by default
|
||
|
||
lda #$ff
|
||
sta CURRENT_ENEMY_KIND
|
||
sta CURRENT_INIT_X
|
||
|
||
|
||
|
||
same_enemy_type:
|
||
|
||
; find empty enemy slot
|
||
|
||
ldy #$0 ; point to enemies[0]
|
||
tya
|
||
|
||
find_empty_enemy:
|
||
pha
|
||
lda (ENEMY_PL),Y ; get enemy[y].out
|
||
beq add_enemy
|
||
|
||
pla
|
||
clc
|
||
adc #$9
|
||
tay
|
||
cpy #(NUM_ENEMIES*9)
|
||
bne find_empty_enemy
|
||
|
||
|
||
jmp move_enemies ; no empty, slots, move on
|
||
|
||
|
||
add_enemy:
|
||
pla
|
||
|
||
;==============================================
|
||
; First see if we must wait for enemy to clear
|
||
; types 2 and 8
|
||
|
||
lda ENEMY_TYPE
|
||
cmp #$2
|
||
|
||
bne check_type_8
|
||
|
||
lda TOTAL_ENEMIES_OUT
|
||
beq change_to_type_3
|
||
jmp move_enemies
|
||
change_to_type_3:
|
||
lda #$3
|
||
sta ENEMY_TYPE
|
||
|
||
jsr random_number
|
||
and #$8
|
||
sta CURRENT_ENEMY_KIND
|
||
|
||
jsr random_number
|
||
and #$1F ; mask off so 0-31
|
||
clc
|
||
adc #$2
|
||
asl A
|
||
sta CURRENT_INIT_X
|
||
jmp setup_enemy_defaults
|
||
|
||
check_type_8:
|
||
|
||
cmp #$8
|
||
beq before_boss_stuff
|
||
jmp check_type_9
|
||
|
||
before_boss_stuff:
|
||
|
||
;======================
|
||
; before boss stuff
|
||
|
||
lda TOTAL_ENEMIES_OUT
|
||
beq prepare_for_boss
|
||
jmp move_enemies
|
||
|
||
prepare_for_boss:
|
||
|
||
;===============
|
||
; HANDLE BONUSES
|
||
;===============
|
||
|
||
; Set text mode
|
||
|
||
jsr set_page0_text
|
||
jsr HOME
|
||
|
||
; Print "BONUS POINTS"
|
||
|
||
lda #>bonus_string
|
||
sta STRINGH
|
||
lda #<bonus_string
|
||
sta STRINGL
|
||
|
||
jsr print_text_xy ; print text
|
||
|
||
; Check to see if we had any bonuses
|
||
|
||
lda #$C1
|
||
bit BONUS_FLAGS
|
||
beq no_bonus
|
||
|
||
|
||
; Check if we had no hits on shields
|
||
|
||
perfect_shields:
|
||
bpl perfect_kills
|
||
|
||
jsr score_plus_50
|
||
|
||
lda #>bonus_shields
|
||
sta STRINGH
|
||
lda #<bonus_shields
|
||
sta STRINGL
|
||
|
||
jsr print_text_xy ; print text
|
||
|
||
|
||
; See if we killed all the enemies
|
||
|
||
perfect_kills:
|
||
bit BONUS_FLAGS
|
||
bvc perfect_aim
|
||
|
||
jsr score_plus_50
|
||
|
||
lda #>bonus_kills
|
||
sta STRINGH
|
||
lda #<bonus_kills
|
||
sta STRINGL
|
||
|
||
jsr print_text_xy ; print text
|
||
|
||
; See if no missiles missed
|
||
|
||
perfect_aim:
|
||
lda #$01
|
||
bit BONUS_FLAGS
|
||
beq done_bonus
|
||
|
||
jsr score_plus_50
|
||
|
||
lda #>bonus_aim
|
||
sta STRINGH
|
||
lda #<bonus_aim
|
||
sta STRINGL
|
||
|
||
jsr print_text_xy ; print text
|
||
|
||
jmp done_bonus
|
||
|
||
; we had no bonuses
|
||
|
||
no_bonus:
|
||
lda #>no_bonus_string
|
||
sta STRINGH
|
||
lda #<no_bonus_string
|
||
sta STRINGL
|
||
|
||
jsr print_text_xy ; print text
|
||
|
||
; Wait until a keypress, and return to graphics mode
|
||
|
||
done_bonus:
|
||
|
||
ldx #30
|
||
jsr wait_X_100msec ; pause for 3 seconds
|
||
bit KEYRESET ; clear keyboard
|
||
|
||
jsr wait_until_keypressed
|
||
jsr set_page0_gr
|
||
|
||
|
||
;======================
|
||
; setup boss
|
||
|
||
lda #$0C
|
||
sta BOSS_X ; boss_x = 13
|
||
|
||
lda #$1
|
||
sta BOSS_XADD ; boss_xadd=1
|
||
sta BOSS_WAITING ; boss_waiting=1
|
||
|
||
jsr random_number
|
||
and #$1f
|
||
sta BOSS_COUNT ; boss_count = rand%32
|
||
|
||
lda #$0
|
||
sta BOSS_SMOKE ; boss_smoke=0
|
||
sta BOSS_EXPLODING ; boss_exploding=0
|
||
sta BOSS_SHOOTING ; boss_shooting=0
|
||
|
||
lda LEVEL
|
||
asl A
|
||
clc
|
||
adc #$10
|
||
sta BOSS_HITS ; boss_hits=(level*2)+20
|
||
|
||
lda #$9
|
||
sta ENEMY_TYPE ; enemy_type=9
|
||
|
||
jmp move_enemies
|
||
|
||
|
||
check_type_9:
|
||
|
||
; if boss, and he's waiting,
|
||
; don't produce enemies
|
||
|
||
cmp #$9
|
||
bne setup_enemy_defaults
|
||
lda BOSS_WAITING
|
||
beq setup_enemy_defaults
|
||
jmp move_enemies
|
||
|
||
|
||
;========================
|
||
; setup enemy defaults
|
||
setup_enemy_defaults:
|
||
inc ENEMIES_SPAWNED
|
||
inc TOTAL_ENEMIES_OUT
|
||
|
||
lda #$1
|
||
sta (ENEMY_PL),Y ; enemy[i].out=1
|
||
|
||
lda #$0
|
||
iny ; exploding
|
||
sta (ENEMY_PL),Y ; enemy[i].exploding=0
|
||
|
||
iny ; kind
|
||
|
||
lda CURRENT_ENEMY_KIND ; if kind <0 then random
|
||
bpl store_enemy_kind
|
||
|
||
jsr random_number
|
||
and #$38
|
||
|
||
jmp store_enemy_kind
|
||
|
||
store_enemy_kind:
|
||
sta (ENEMY_PL),Y
|
||
|
||
; determine enemy _x
|
||
; if < 0, make random between 2->34
|
||
|
||
lda CURRENT_INIT_X
|
||
bpl store_init_x
|
||
|
||
jsr random_number
|
||
and #$1f
|
||
clc
|
||
adc #$2
|
||
asl
|
||
|
||
store_init_x:
|
||
iny ; X
|
||
sta (ENEMY_PL),Y
|
||
|
||
; enemy_y is always 0 by default
|
||
|
||
iny ; Y
|
||
lda #$0
|
||
sta (ENEMY_PL),Y
|
||
|
||
lda #$0
|
||
iny
|
||
sta (ENEMY_PL),Y ; xadd
|
||
iny
|
||
sta (ENEMY_PL),Y ; yadd
|
||
lda #$2
|
||
iny
|
||
sta (ENEMY_PL),Y ; xmin
|
||
iny
|
||
lda #$24
|
||
sta (ENEMY_PL),Y ; ymin
|
||
|
||
dey ; xmin
|
||
dey ; yadd
|
||
dey ; xadd
|
||
|
||
|
||
;===========================================
|
||
; Enemy specific inits
|
||
|
||
lda ENEMY_TYPE
|
||
beq enemy_type_0
|
||
cmp #$1
|
||
beq enemy_type_1
|
||
jmp enemy_type_2
|
||
|
||
enemy_type_0:
|
||
enemy_type_1:
|
||
|
||
;================================
|
||
; ENEMY TYPE 0 and 1
|
||
; diagonal, no wait
|
||
; movement proportional to level
|
||
|
||
lda LEVEL ; xadd = level
|
||
sta (ENEMY_PL),Y
|
||
|
||
iny
|
||
|
||
lsr A
|
||
ora #$1
|
||
sta (ENEMY_PL),Y ; yadd = level/2
|
||
jmp move_enemies
|
||
|
||
enemy_type_2:
|
||
;=====================
|
||
; Enemy Type 2
|
||
; just a place-holder
|
||
; waits for enemies to die then moves on to 3
|
||
|
||
cmp #$2
|
||
bne enemy_type_3
|
||
jmp move_enemies
|
||
|
||
|
||
enemy_type_3:
|
||
|
||
cmp #$3
|
||
bne enemy_type_4
|
||
|
||
;======================
|
||
; Enemy type 3
|
||
|
||
lda #$1
|
||
sta (ENEMY_PL),Y ; xadd=1
|
||
|
||
iny
|
||
|
||
lda LEVEL
|
||
sta (ENEMY_PL),Y ; yadd=level
|
||
|
||
jmp move_enemies
|
||
|
||
enemy_type_4:
|
||
|
||
cmp #$4
|
||
bne enemy_type_5
|
||
|
||
|
||
;=========================
|
||
; Enemy Type 4
|
||
; Horizontal, then fall
|
||
|
||
lda #$2
|
||
sta (ENEMY_PL),Y ; xadd = 2
|
||
|
||
iny
|
||
|
||
jsr random_number
|
||
ora #$80 ; set negative
|
||
sta (ENEMY_PL),y ; yadd = -(random%128)
|
||
; this means bop back and forth a random
|
||
; time, then drop
|
||
|
||
jmp move_enemies
|
||
|
||
|
||
enemy_type_5:
|
||
cmp #$5
|
||
bne enemy_type_6
|
||
|
||
;========================
|
||
; Enemy Type 5
|
||
; "wiggle"
|
||
|
||
lda #$1
|
||
sta (ENEMY_PL),y ; xadd=1
|
||
|
||
iny
|
||
lda LEVEL
|
||
sta (ENEMY_PL),y ; yadd=2
|
||
|
||
iny
|
||
jsr random_number
|
||
and #$0f
|
||
clc
|
||
adc #$2
|
||
sta (ENEMY_PL),y ; xmin=(rand%16)+2
|
||
|
||
|
||
dey ; yadd
|
||
dey ; xadd
|
||
dey ; y
|
||
dey ;x
|
||
asl A
|
||
sta (ENEMY_PL),y
|
||
iny ;y
|
||
iny ; xadd
|
||
iny ; yadd
|
||
iny ; xmin
|
||
|
||
jsr random_number
|
||
and #$0f
|
||
clc
|
||
adc (ENEMY_PL),Y
|
||
adc #$02
|
||
iny
|
||
sta (ENEMY_PL),Y ; xmax = xmin+(rand%16)+2
|
||
|
||
jmp move_enemies
|
||
|
||
|
||
enemy_type_6:
|
||
cmp #$6
|
||
beq enemy_type_7
|
||
cmp #$7
|
||
beq enemy_type_7
|
||
jmp enemy_type_8
|
||
enemy_type_7:
|
||
;=====================
|
||
; Enemy Types 6+7
|
||
; "Rain"
|
||
|
||
|
||
|
||
jsr random_number
|
||
and #6
|
||
bne no_use_own_x
|
||
|
||
dey ; y
|
||
dey ; x
|
||
|
||
lda SHIPX
|
||
cmp #$2
|
||
bpl shipx_ok
|
||
lda #$2 ; stupid bug where gets stuck is < xmin
|
||
|
||
shipx_ok:
|
||
|
||
asl A
|
||
sta (ENEMY_PL),Y ; one-in-four chance we use shipx as X
|
||
|
||
iny ; y
|
||
iny ; xadd
|
||
|
||
no_use_own_x:
|
||
|
||
lda #$0
|
||
sta (ENEMY_PL),Y ; xadd=0
|
||
iny
|
||
lda #$1
|
||
sta (ENEMY_PL),Y ; yadd = 1
|
||
|
||
jmp move_enemies
|
||
|
||
enemy_type_8:
|
||
enemy_type_9:
|
||
|
||
;======================
|
||
; Things flung by boss
|
||
|
||
|
||
dey ; y
|
||
dey ; x
|
||
|
||
lda BOSS_X
|
||
clc
|
||
adc #$5
|
||
asl A
|
||
sta (ENEMY_PL),Y ; enemy_x=boss_x+5
|
||
|
||
iny
|
||
lda #$3
|
||
asl A
|
||
asl A
|
||
sta (ENEMY_PL),Y ; enemy_y=3
|
||
|
||
|
||
iny
|
||
lda #$0
|
||
sta (ENEMY_PL),Y ; xadd=0
|
||
|
||
iny
|
||
lda #$2
|
||
sta (ENEMY_PL),Y ; yadd=2
|
||
|
||
|
||
|
||
|
||
|
||
move_enemies:
|
||
|
||
;==============================================
|
||
; Move Enemies! (first thing, if no new added)
|
||
;==============================================
|
||
|
||
ldy #$0 ; point to enemies[0]
|
||
handle_enemies:
|
||
|
||
tya
|
||
pha ; store y on stack
|
||
|
||
lda (ENEMY_PL),Y ; get enemy[y].out
|
||
bne load_enemy_zero_page ; if enemy.out then we are good
|
||
|
||
jmp skip_to_next_enemy ; enemy is not out, so skip to next
|
||
|
||
|
||
|
||
;==========================================
|
||
; load this enemy stuff into zero page for
|
||
; easier access
|
||
;==========================================
|
||
|
||
load_enemy_zero_page:
|
||
ldx #ENEMY_EXPLODING
|
||
load_to_zero_page:
|
||
iny ; point to exploding
|
||
lda (ENEMY_PL),Y
|
||
sta 0,X ; store to zero page
|
||
inx
|
||
cpx #(ENEMY_XMAX+1) ; see if reached end
|
||
bne load_to_zero_page ; if not keep copying
|
||
|
||
;================================
|
||
; skip all movement and collision
|
||
; if exploding
|
||
;================================
|
||
|
||
lda ENEMY_EXPLODING
|
||
beq move_enemy_x
|
||
jmp draw_enemy
|
||
|
||
;================================
|
||
; Start the enemy movement engine
|
||
;================================
|
||
|
||
|
||
;========
|
||
; Move X
|
||
;========
|
||
|
||
move_enemy_x:
|
||
clc
|
||
lda ENEMY_X ; X
|
||
adc ENEMY_XADD ; x+=xadd
|
||
sta ENEMY_X
|
||
|
||
lsr A
|
||
|
||
cmp ENEMY_XMIN ; are we less than xmin?
|
||
bmi switch_dir_enemy_x ; if so, switch direction
|
||
|
||
cmp ENEMY_XMAX ; are we greater than xmax?
|
||
bpl switch_dir_enemy_x ; if so, switch direction
|
||
|
||
jmp move_enemy_y
|
||
|
||
|
||
switch_dir_enemy_x:
|
||
|
||
; switch X direction
|
||
|
||
lda #$0 ; load zero
|
||
sec
|
||
sbc ENEMY_XADD ; 0 - ENEMY_XADD
|
||
sta ENEMY_XADD ; store it back out, negated
|
||
jmp move_enemy_x ; re-add it in
|
||
|
||
;========
|
||
; Move Y
|
||
;========
|
||
|
||
move_enemy_y:
|
||
|
||
lda #$0 ; load in zero
|
||
cmp ENEMY_YADD ; compare to YADD
|
||
|
||
bmi no_y_special_case ; if minus, we have special case
|
||
|
||
inc ENEMY_YADD
|
||
bne done_enemy_y
|
||
|
||
lda #$0
|
||
sta ENEMY_XADD
|
||
lda #$2
|
||
sta ENEMY_YADD
|
||
|
||
; increment y
|
||
; is it > 0?
|
||
; if not keep going
|
||
; if so, yadd=level*2
|
||
|
||
jmp done_enemy_y
|
||
|
||
no_y_special_case:
|
||
clc
|
||
lda ENEMY_Y ; get Y
|
||
adc ENEMY_YADD ; y+=yadd
|
||
sta ENEMY_Y ; store back out
|
||
|
||
lsr A
|
||
lsr A
|
||
|
||
cmp #$12 ; is y<=12?
|
||
bmi done_enemy_y ; if so no need to do anything
|
||
beq done_enemy_y
|
||
|
||
; off screen
|
||
|
||
pla ; pop saved Y off stack
|
||
tay
|
||
pha ; push y back on stack
|
||
|
||
lda #$0
|
||
sta (ENEMY_PL),Y ; set enemy[i].out=0
|
||
|
||
dec TOTAL_ENEMIES_OUT
|
||
|
||
lda BONUS_FLAGS
|
||
and #<(~PERFECT_KILLS)
|
||
sta BONUS_FLAGS
|
||
|
||
jmp skip_to_next_enemy ; skip to next enemy
|
||
|
||
|
||
done_enemy_y:
|
||
|
||
;===============
|
||
; Done Movement
|
||
;===============
|
||
|
||
|
||
;======================
|
||
; Check for Collisions
|
||
;======================
|
||
|
||
|
||
;==================================
|
||
; Check ENEMY <> MISSILE collision
|
||
;==================================
|
||
|
||
check_enemy_missile_collision:
|
||
|
||
ldy #$0
|
||
sty YSAV
|
||
check_missile_loop:
|
||
lda (MISSILE_PL),Y
|
||
beq missile_not_out
|
||
|
||
iny ; point to missile.x
|
||
lda (MISSILE_PL),Y ; load missile.x
|
||
|
||
sta COL_X1
|
||
sta COL_X2
|
||
|
||
lda ENEMY_X
|
||
lsr A
|
||
sta COL_X3
|
||
clc
|
||
adc #3
|
||
sta COL_X4
|
||
|
||
jsr check_inside
|
||
|
||
bcc missile_done
|
||
|
||
x_in_range:
|
||
|
||
iny
|
||
lda (MISSILE_PL),Y ; load missile.y
|
||
|
||
sta COL_X3
|
||
clc
|
||
adc #2
|
||
sta COL_X4
|
||
|
||
lda ENEMY_Y
|
||
lsr A
|
||
lsr A
|
||
sta COL_X1
|
||
clc
|
||
adc #1
|
||
sta COL_X2
|
||
|
||
jsr check_inside
|
||
|
||
bcc missile_done
|
||
|
||
|
||
horrible_explosion:
|
||
|
||
; clear missile
|
||
|
||
ldy YSAV
|
||
lda #$0
|
||
sta (MISSILE_PL),Y
|
||
|
||
; clear enemy
|
||
|
||
lda #$1
|
||
sta ENEMY_EXPLODING
|
||
lda #$40
|
||
sta ENEMY_KIND
|
||
|
||
jsr inc_score
|
||
|
||
jmp draw_enemy
|
||
|
||
|
||
missile_done:
|
||
missile_not_out:
|
||
ldy YSAV
|
||
iny
|
||
iny
|
||
iny
|
||
sty YSAV
|
||
cpy #(NUM_MISSILES*3)
|
||
bne check_missile_loop
|
||
|
||
;=================================
|
||
; Done missile <> enemy collision
|
||
;=================================
|
||
|
||
|
||
;====================================
|
||
; check for ship <-> enemy collision
|
||
;====================================
|
||
|
||
lda SHIPX
|
||
sta COL_X3
|
||
clc
|
||
adc #8
|
||
sta COL_X4 ; big check is shipx - shipx+8
|
||
|
||
lda ENEMY_X
|
||
lsr A
|
||
sta COL_X1
|
||
clc
|
||
adc #2
|
||
sta COL_X2 ; small check enemy_x - enemy_x+2
|
||
|
||
jsr check_inside ; check if overlap
|
||
|
||
bcc draw_enemy ; if not, move ahead
|
||
|
||
lda #16
|
||
sta COL_X3
|
||
lda #18
|
||
sta COL_X4 ; big check is 16 - 18
|
||
|
||
lda ENEMY_Y
|
||
lsr A
|
||
lsr A
|
||
sta COL_X1
|
||
clc
|
||
adc #$1
|
||
sta COL_X2 ; little check is enemy_y - enemy_y+1
|
||
|
||
jsr check_inside ; check if overlap
|
||
|
||
bcc draw_enemy ; if not, move ahead
|
||
|
||
; make the enemy explode
|
||
|
||
lda #$1
|
||
sta ENEMY_EXPLODING
|
||
lda #$40
|
||
sta ENEMY_KIND
|
||
|
||
dec SHIELDS
|
||
jsr update_shields ; move shields down
|
||
|
||
lda #<(~PERFECT_SHIELDS) ; (~PERFECT_SHIELDS)
|
||
and BONUS_FLAGS ; remove perfect shield bonus
|
||
sta BONUS_FLAGS
|
||
|
||
|
||
;=====================================
|
||
; Done ship <> enemy collision detect
|
||
;=====================================
|
||
|
||
|
||
draw_enemy:
|
||
|
||
; See if the enemy is currently exploding
|
||
; if so, do explosion stuff
|
||
|
||
check_enemy_explode:
|
||
lda ENEMY_EXPLODING ; load enemy[i].exploding
|
||
beq not_exploding ; if 0 then not exploding
|
||
|
||
handle_exploding:
|
||
|
||
jsr click ; make some noise
|
||
|
||
clc
|
||
lda ENEMY_KIND ; move to next step in explosion
|
||
adc #$4
|
||
sta ENEMY_KIND
|
||
|
||
cmp #$58 ; have we cycles through explosion?
|
||
bne draw_enemy_sprite ; if not, we are still exploding
|
||
|
||
dec TOTAL_ENEMIES_OUT ; total_enemies_out--
|
||
|
||
pla
|
||
tay ; load y
|
||
pha
|
||
|
||
lda #$0 ; enemy[i].out=0
|
||
sta (ENEMY_PL),Y
|
||
|
||
jmp skip_to_next_enemy
|
||
|
||
|
||
; point to enemies_x
|
||
; goto enemies_xy
|
||
|
||
|
||
not_exploding:
|
||
|
||
|
||
|
||
draw_enemy_sprite:
|
||
|
||
; point to proper sprite
|
||
|
||
lda #>enemy_sprite0 ; point to the missile sprite
|
||
sta STRINGH
|
||
lda #<enemy_sprite0
|
||
sta STRINGL
|
||
|
||
lda ENEMY_KIND ; get kind
|
||
and #$F8
|
||
|
||
clc
|
||
adc STRINGL
|
||
|
||
sta STRINGL
|
||
lda #0
|
||
adc STRINGH
|
||
sta STRINGH
|
||
|
||
|
||
enemies_xy:
|
||
lda ENEMY_X ; get X
|
||
lsr A
|
||
sta CH
|
||
lda ENEMY_Y ; load it
|
||
lsr A
|
||
lsr A
|
||
sta CV
|
||
|
||
jsr blit ; blit the missile sprite
|
||
|
||
|
||
|
||
|
||
save_zp_enemy_back:
|
||
; save zero page copy back to RAM
|
||
|
||
ldx #ENEMY_EXPLODING
|
||
|
||
pla
|
||
tay ; restore y pointer
|
||
pha
|
||
|
||
save_from_zero_page:
|
||
|
||
|
||
iny ; point to exploding
|
||
lda 0,X
|
||
sta (ENEMY_PL),Y
|
||
|
||
inx
|
||
cpx #(ENEMY_XMAX+1) ; see if reached end
|
||
bne save_from_zero_page ; if not keep copying
|
||
|
||
|
||
skip_to_next_enemy:
|
||
|
||
pla ; get saved value of Y
|
||
clc
|
||
adc #$9 ; add 9 to point to next
|
||
tay
|
||
|
||
cpy #NUM_ENEMIES*9 ; have we looped through them all?
|
||
beq draw_the_boss ; if not, loop
|
||
jmp handle_enemies
|
||
|
||
|
||
;===================================================
|
||
;===================================================
|
||
; BOSS STUFF
|
||
|
||
|
||
draw_the_boss:
|
||
|
||
;=======================
|
||
; if enemy_type==9
|
||
; we have a boss out
|
||
|
||
lda ENEMY_TYPE
|
||
cmp #$9
|
||
|
||
beq check_boss_exploding
|
||
jmp done_with_boss
|
||
check_boss_exploding:
|
||
;================================
|
||
; if not exploding, draw the boss
|
||
|
||
lda BOSS_EXPLODING
|
||
bne skip_draw_boss
|
||
|
||
lda #$0 ; boss_y=0
|
||
sta CV
|
||
lda BOSS_X
|
||
sta CH ; boss_x
|
||
|
||
lda #>boss_sprite
|
||
sta STRINGH
|
||
lda #<boss_sprite
|
||
sta STRINGL
|
||
jsr blit ; blit the ship sprite
|
||
|
||
skip_draw_boss:
|
||
;================================
|
||
; Draw Smoke
|
||
|
||
lda BOSS_SMOKE
|
||
beq skip_draw_smoke
|
||
|
||
|
||
; point to proper sprite
|
||
|
||
lda #>smoke_sprite0 ; point to the missile sprite
|
||
sta STRINGH
|
||
lda #<smoke_sprite0
|
||
sta STRINGL
|
||
|
||
lda BOSS_SMOKE ; get kind
|
||
|
||
and #$fc ; mask off bottom 2 bits
|
||
|
||
clc
|
||
adc STRINGL
|
||
|
||
sta STRINGL
|
||
lda #0
|
||
adc STRINGH
|
||
sta STRINGH
|
||
|
||
lda BOSS_X ; get X
|
||
clc
|
||
adc #$5
|
||
sta CH
|
||
lda #$3 ; load it
|
||
sta CV
|
||
|
||
jsr blit ; blit the missile sprite
|
||
|
||
lda BOSS_X
|
||
clc
|
||
adc #$5
|
||
sec
|
||
sbc BOSS_XADD
|
||
sta CH
|
||
|
||
lda #$4
|
||
sta CV
|
||
|
||
jsr blit
|
||
|
||
dec BOSS_SMOKE
|
||
|
||
skip_draw_smoke:
|
||
|
||
;======================
|
||
; BOSS Laser Shoot
|
||
|
||
lda BOSS_SHOOTING
|
||
beq skip_boss_shooting
|
||
|
||
dec BOSS_SHOOTING
|
||
|
||
jsr click
|
||
|
||
|
||
ldx #$0
|
||
boss_shoot_loop:
|
||
txa
|
||
pha
|
||
|
||
; point to proper sprite
|
||
|
||
lda #>laser_sprite0 ; point to the missile sprite
|
||
sta STRINGH
|
||
lda #<laser_sprite0
|
||
sta STRINGL
|
||
|
||
lda BOSS_SHOOTING ; get shooting
|
||
and #$1
|
||
|
||
beq got_right_laser
|
||
|
||
clc
|
||
lda #$5
|
||
adc STRINGL
|
||
|
||
sta STRINGL
|
||
lda #0
|
||
adc STRINGH
|
||
sta STRINGH
|
||
|
||
got_right_laser:
|
||
|
||
lda BOSS_X
|
||
sta CH
|
||
|
||
txa
|
||
asl
|
||
|
||
clc
|
||
adc #$3
|
||
sta CV
|
||
|
||
jsr blit ; blit the laser sprite
|
||
|
||
lda BOSS_X
|
||
clc
|
||
adc #$C
|
||
sta CH
|
||
|
||
pla
|
||
pha
|
||
asl
|
||
clc
|
||
adc #$3
|
||
sta CV
|
||
|
||
|
||
jsr blit
|
||
|
||
|
||
pla
|
||
tax
|
||
inx
|
||
cpx #$8
|
||
bne boss_shoot_loop
|
||
jsr click
|
||
|
||
|
||
skip_boss_shooting:
|
||
|
||
;=============================
|
||
; boss is dead
|
||
|
||
lda BOSS_EXPLODING
|
||
beq boss_is_not_exploding
|
||
|
||
lda #$1
|
||
sta BOSS_WAITING
|
||
|
||
ldx #$20
|
||
big_explosion:
|
||
txa
|
||
pha
|
||
|
||
; point to proper sprite
|
||
|
||
lda #>smoke_sprite0 ; point to the missile sprite
|
||
sta STRINGH
|
||
lda #<smoke_sprite0
|
||
sta STRINGL
|
||
|
||
lda BOSS_EXPLODING ; get kind
|
||
lsr A
|
||
lsr A
|
||
and #$0c ; mask off bottom 2 bits
|
||
|
||
clc
|
||
adc STRINGL
|
||
|
||
sta STRINGL
|
||
lda #0
|
||
adc STRINGH
|
||
sta STRINGH
|
||
|
||
jsr random_number
|
||
and #$03
|
||
sta CV
|
||
|
||
jsr random_number
|
||
and #$07
|
||
clc
|
||
adc BOSS_X
|
||
sta CH
|
||
|
||
jsr blit ; blit the missile sprite
|
||
|
||
pla
|
||
tax
|
||
dex
|
||
bne big_explosion
|
||
|
||
jsr click
|
||
dec BOSS_EXPLODING
|
||
|
||
bne not_dead_yet
|
||
|
||
lda LEVEL ; only show ending after level 1
|
||
cmp #$1
|
||
bne no_ending
|
||
|
||
jmp do_ending
|
||
|
||
no_ending:
|
||
|
||
inc SCOREH ; add 100 to score
|
||
jsr print_score
|
||
|
||
lda LEVEL
|
||
cmp #$7 ; level can't be higher than 7
|
||
beq start_new_level
|
||
inc LEVEL
|
||
|
||
inc SHIELDS
|
||
inc SHIELDS
|
||
|
||
lda #$A
|
||
cmp SHIELDS
|
||
bpl start_new_level
|
||
sta SHIELDS
|
||
|
||
start_new_level:
|
||
jsr update_shields
|
||
jmp new_level
|
||
|
||
not_dead_yet:
|
||
jmp move_boss
|
||
|
||
boss_is_not_exploding:
|
||
|
||
dec BOSS_COUNT
|
||
bne move_boss
|
||
|
||
;=========================================
|
||
; Toggle boss waiting state if count is up
|
||
|
||
lda BOSS_WAITING
|
||
beq make_boss_wait
|
||
stop_boss_waiting:
|
||
lda #$0
|
||
sta BOSS_WAITING ; boss_waiting=0
|
||
jsr random_number
|
||
sta BOSS_COUNT ; boss_count=rand%256
|
||
jmp move_boss
|
||
|
||
make_boss_wait:
|
||
lda #$1
|
||
sta BOSS_WAITING
|
||
|
||
jsr random_number
|
||
and #$01f
|
||
clc
|
||
adc #$30
|
||
sta BOSS_COUNT
|
||
|
||
lda #$20
|
||
sta BOSS_SHOOTING
|
||
|
||
move_boss:
|
||
lda BOSS_WAITING
|
||
bne laser_collision
|
||
|
||
lda BOSS_X
|
||
clc
|
||
adc BOSS_XADD
|
||
sta BOSS_X
|
||
|
||
cmp #26
|
||
bpl boss_reverse
|
||
|
||
boss_under:
|
||
cmp #$0
|
||
bpl laser_collision
|
||
|
||
boss_reverse:
|
||
|
||
lda #$0 ; load zero
|
||
sec
|
||
sbc BOSS_XADD ; 0 - ENEMY_XADD
|
||
sta BOSS_XADD ; store it back out, negated
|
||
jmp move_boss ; re-add it in
|
||
|
||
|
||
laser_collision:
|
||
|
||
;================================
|
||
; Collision detection for lasers
|
||
;
|
||
|
||
lda BOSS_SHOOTING
|
||
beq done_with_boss
|
||
|
||
left_laser:
|
||
lda BOSS_X
|
||
sta COL_X1
|
||
sta COL_X2
|
||
lda SHIPX
|
||
sta COL_X3
|
||
lda #$6
|
||
clc
|
||
adc SHIPX
|
||
sta COL_X4
|
||
jsr check_inside
|
||
bcs laser_hit
|
||
|
||
right_laser:
|
||
lda BOSS_X
|
||
clc
|
||
adc #$C
|
||
sta COL_X1
|
||
sta COL_X2
|
||
jsr check_inside
|
||
bcc done_with_boss
|
||
|
||
laser_hit:
|
||
lda BOSS_SHOOTING
|
||
and #$3 ; only take damage 1/8 the time
|
||
bne done_with_boss
|
||
|
||
dec SHIELDS
|
||
jsr update_shields
|
||
|
||
|
||
|
||
|
||
done_with_boss:
|
||
|
||
ldy #$0 ; point to missile[0]
|
||
move_missiles:
|
||
lda (MISSILE_PL),Y ; get missile[y]
|
||
beq loop_move_missiles ; if missile.out==0 skip
|
||
|
||
iny ; move to missile.y
|
||
iny
|
||
clc ; clear carry
|
||
lda (MISSILE_PL),Y ; get missile.y
|
||
adc #$FF ; move up (subtract 1)
|
||
sta (MISSILE_PL),Y ; store missile.y
|
||
bpl missile_collision_detection ; if not off screen, contine
|
||
|
||
dey ; back up to missile.out
|
||
dey
|
||
lda #$0
|
||
sta (MISSILE_PL),Y ; set missile.out=0
|
||
|
||
lda #<(~PERFECT_AIM) ; shot missed!
|
||
and BONUS_FLAGS ; clear perfect shot flag
|
||
sta BONUS_FLAGS
|
||
|
||
jmp loop_move_missiles ; continue
|
||
|
||
missile_collision_detection:
|
||
|
||
check_missile_boss:
|
||
lda ENEMY_TYPE
|
||
cmp #$9
|
||
bne done_missile_collision
|
||
dey ; missile x
|
||
lda (MISSILE_PL),Y
|
||
iny ; fix y
|
||
sta COL_X1
|
||
sta COL_X2
|
||
lda BOSS_X
|
||
sta COL_X3
|
||
clc
|
||
adc #$0d
|
||
sta COL_X4
|
||
jsr check_inside
|
||
|
||
bcc done_missile_collision
|
||
|
||
check_boss_y:
|
||
lda (MISSILE_PL),Y
|
||
sta COL_X1
|
||
clc
|
||
adc #$2
|
||
sta COL_X2
|
||
lda #$0
|
||
sta COL_X3
|
||
lda #$3
|
||
sta COL_X4
|
||
jsr check_inside
|
||
|
||
bcc done_missile_collision
|
||
|
||
hit_the_boss:
|
||
dey
|
||
dey
|
||
lda #$0
|
||
sta (MISSILE_PL),Y ; missile_out=0
|
||
lda #$B
|
||
sta BOSS_SMOKE
|
||
|
||
dec BOSS_HITS
|
||
bne loop_move_missiles
|
||
|
||
lda #$2F
|
||
sta BOSS_EXPLODING
|
||
lda #$0
|
||
sta BOSS_SHOOTING
|
||
|
||
jmp loop_move_missiles
|
||
|
||
done_missile_collision:
|
||
|
||
jmp loop_move_at_y
|
||
|
||
loop_move_missiles:
|
||
iny
|
||
iny
|
||
loop_move_at_y:
|
||
iny
|
||
cpy #NUM_MISSILES*3 ; have we checked all missiles?
|
||
bne move_missiles ; if not, loop
|
||
|
||
done_move_missiles:
|
||
|
||
ldy #$0 ; point to missiles[0]
|
||
draw_missiles:
|
||
lda (MISSILE_PL),Y ; get missile[y]
|
||
beq loop_draw_missiles ; if missile.out==0 skip
|
||
|
||
iny ; point to missile.x
|
||
lda (MISSILE_PL),Y ; load it
|
||
sta CH
|
||
iny ; point to missile.y
|
||
lda (MISSILE_PL),Y ; load it
|
||
sta CV
|
||
|
||
sty YSAV1 ; save Y
|
||
|
||
lda #>missile_sprite ; point to the missile sprite
|
||
sta STRINGH
|
||
lda #<missile_sprite
|
||
sta STRINGL
|
||
jsr blit ; blit the missile sprite
|
||
|
||
ldy YSAV1 ; restore Y
|
||
|
||
jmp loop_draw_missiles_noadd
|
||
|
||
loop_draw_missiles:
|
||
iny
|
||
iny
|
||
|
||
loop_draw_missiles_noadd:
|
||
iny
|
||
|
||
cpy #NUM_MISSILES*3 ; have we looped through them all?
|
||
bne draw_missiles ; if not, loop
|
||
|
||
|
||
|
||
game_read_keyboard:
|
||
jsr get_key
|
||
lda LASTKEY
|
||
bne game_q
|
||
jmp move_ship ; if no keypressed, move the ship
|
||
|
||
game_q:
|
||
cmp #'Q'
|
||
bne game_j
|
||
;; call verify_quit
|
||
jmp done_game
|
||
;; jmp set_pause_flag
|
||
|
||
game_j:
|
||
cmp #'J'
|
||
bne game_k
|
||
|
||
lda SHIPXADD ; load xadd
|
||
beq game_j_sub
|
||
bpl game_j_0 ; is switch dir, then 0 it
|
||
game_j_sub:
|
||
dec SHIPXADD ; else, dec XADD
|
||
jmp move_ship
|
||
game_j_0:
|
||
lda #$0
|
||
sta SHIPXADD
|
||
jmp move_ship
|
||
|
||
game_k:
|
||
cmp #'K'
|
||
bne game_c
|
||
|
||
lda SHIPXADD ; load xadd
|
||
bmi game_j_0 ; if we are switching dirs, set to zero
|
||
inc SHIPXADD ; else xadd++
|
||
jmp move_ship
|
||
|
||
game_c:
|
||
cmp #'C'
|
||
bne game_p
|
||
|
||
lda PADDLE_STATUS
|
||
eor #$80
|
||
sta PADDLE_STATUS
|
||
|
||
jmp move_ship
|
||
|
||
game_p:
|
||
cmp #'P'
|
||
bne game_s
|
||
bit KEYRESET
|
||
jsr wait_until_keypressed
|
||
jmp move_ship
|
||
|
||
game_s:
|
||
cmp #'S'
|
||
bne game_h
|
||
lda SOUND_ON
|
||
eor #$ff
|
||
sta SOUND_ON
|
||
jmp move_ship
|
||
|
||
game_h:
|
||
cmp #'H'
|
||
bne game_space
|
||
jsr do_help
|
||
jsr set_page0_gr
|
||
|
||
game_space:
|
||
cmp #' '+128 ; +128 because of get_key 'feature'
|
||
bne game_unknown
|
||
|
||
ldy #$0 ; point to missile[y]
|
||
fire_missiles:
|
||
lda (MISSILE_PL),Y ; get missile[y].out
|
||
bne end_fire_loop ; if not out, skip ahead
|
||
|
||
lda #$1 ; set missile[y].out=1
|
||
sta (MISSILE_PL),Y
|
||
iny ; point to missile[y].x
|
||
lda #$3
|
||
clc
|
||
adc SHIPX ; missile[y].x=shipx+3
|
||
sta (MISSILE_PL),Y
|
||
iny ; point to missile[y].y
|
||
lda #$10 ; set to 16
|
||
sta (MISSILE_PL),Y
|
||
jmp done_fire_missiles
|
||
|
||
end_fire_loop:
|
||
iny
|
||
iny
|
||
iny
|
||
|
||
cpy #NUM_MISSILES*3 ; see if we have more missiles
|
||
bne fire_missiles ; if so, loop
|
||
done_fire_missiles:
|
||
|
||
jmp move_ship
|
||
|
||
game_unknown:
|
||
|
||
|
||
|
||
|
||
move_ship:
|
||
clc ; Clear carry
|
||
lda SHIPX ; load ship_x
|
||
adc SHIPXADD ; ship_x+=xadd
|
||
sta SHIPX ; store it back
|
||
|
||
check_x_under:
|
||
bpl check_x_over ; if positive, keep going
|
||
lda #$0 ; we were below zero
|
||
sta SHIPX ; so shipx=0
|
||
sta SHIPXADD ; xadd=0
|
||
jmp blit_ship ; go to blit
|
||
|
||
check_x_over:
|
||
cmp #$21 ; are we over 33?
|
||
bmi blit_ship ; if not, blit ship
|
||
lda #$0 ; shipxadd=0
|
||
sta SHIPXADD
|
||
lda #$21 ; shipx=33
|
||
sta SHIPX
|
||
|
||
blit_ship:
|
||
lda #$10 ; shipy=16
|
||
sta CV
|
||
lda SHIPX
|
||
sta CH ; load shipx
|
||
|
||
|
||
lda #>ship_sprite
|
||
sta STRINGH
|
||
lda #<ship_sprite
|
||
sta STRINGL
|
||
jsr blit ; blit the ship sprite
|
||
|
||
jsr clear_bottom
|
||
|
||
lda #>shields_string
|
||
sta STRINGH
|
||
lda #<shields_string
|
||
sta STRINGL
|
||
|
||
clc
|
||
lda #$2
|
||
adc GR_PAGE
|
||
sta BASH
|
||
lda #$50
|
||
sta BASL
|
||
|
||
ldy #$0
|
||
|
||
shield_print_loop:
|
||
|
||
;=============================
|
||
; CHECK TO SEE IF GAME IS OVER
|
||
;=============================
|
||
|
||
lda SHIELDS
|
||
bmi done_game
|
||
|
||
|
||
lda (STRINGL),Y
|
||
sta (BASL),Y
|
||
iny
|
||
cpy #$1E ; string is 30 long
|
||
bne shield_print_loop
|
||
|
||
inc BASH ; move to line 23
|
||
|
||
lda #>score_string
|
||
sta STRINGH
|
||
lda #<score_string
|
||
sta STRINGL
|
||
|
||
ldy #$0
|
||
|
||
score_print_loop:
|
||
lda (STRINGL),Y
|
||
sta (BASL),Y
|
||
iny
|
||
cpy #$26 ; string is 38 long
|
||
bne score_print_loop
|
||
|
||
clc
|
||
lda #$80
|
||
adc BASL
|
||
sta BASL ; move to line 24
|
||
|
||
;OPTIMIZE
|
||
|
||
lda #>level_string
|
||
sta STRINGH
|
||
lda #<level_string
|
||
sta STRINGL
|
||
|
||
ldy #$0
|
||
level_print_loop:
|
||
lda (STRINGL),Y
|
||
sta (BASL),Y
|
||
iny
|
||
cpy #$C ; string is 12 long
|
||
bne level_print_loop
|
||
|
||
|
||
|
||
|
||
|
||
;==========
|
||
; Flip Pages
|
||
|
||
lda #$4
|
||
bit GR_PAGE
|
||
bne gr_page_1
|
||
|
||
gr_page_0:
|
||
bit PAGE1 ; switch to page 0
|
||
lda #$4
|
||
jmp write_out_gr_page
|
||
gr_page_1:
|
||
bit PAGE0 ; switch to page 1
|
||
lda #$8
|
||
write_out_gr_page:
|
||
sta GR_PAGE
|
||
|
||
; lda #$8B ; 107 = 30080us = 30ms
|
||
lda #$65
|
||
jsr WAIT
|
||
|
||
|
||
jmp main_game_loop
|
||
|
||
done_game:
|
||
|
||
|
||
ldx #30
|
||
jsr wait_X_100msec ; pause for 3 seconds
|
||
bit KEYRESET ; clear keyboard
|
||
|
||
jsr set_page0_text
|
||
jsr HOME
|
||
|
||
lda #>game_over_string
|
||
sta STRINGH
|
||
lda #<game_over_string
|
||
sta STRINGL
|
||
|
||
jsr print_text_xy
|
||
|
||
jsr wait_until_keypressed
|
||
|
||
jsr set_page0_text
|
||
|
||
see_if_new_hi_score:
|
||
|
||
sed
|
||
lda SCOREH
|
||
cmp HISCORE_H
|
||
cld
|
||
|
||
beq too_close
|
||
bpl new_high
|
||
jmp do_hi_score
|
||
|
||
|
||
too_close:
|
||
sed
|
||
lda SCOREL
|
||
cmp HISCORE_L
|
||
cld
|
||
|
||
bpl new_high
|
||
jmp do_hi_score
|
||
|
||
new_high:
|
||
|
||
; Actually set the high score
|
||
|
||
lda SCOREL
|
||
sta HISCORE_L
|
||
lda SCOREH
|
||
sta HISCORE_H
|
||
|
||
lda #>(score_string+31)
|
||
sta STRINGH
|
||
lda #<(score_string+31)
|
||
sta STRINGL
|
||
jsr print_high_score
|
||
|
||
jsr HOME
|
||
|
||
; print new high score message
|
||
|
||
lda #>new_high_score_string
|
||
sta STRINGH
|
||
lda #<new_high_score_string
|
||
sta STRINGL
|
||
|
||
jsr print_text_xy
|
||
jsr print_text_xy
|
||
|
||
; set high score to AAA
|
||
|
||
lda #$C1
|
||
sta HISCORE_1
|
||
sta HISCORE_2
|
||
sta HISCORE_3
|
||
|
||
|
||
; load initials address
|
||
|
||
lda #$06
|
||
sta STRINGH
|
||
lda #$12
|
||
sta STRINGL
|
||
|
||
|
||
; load pointer address
|
||
|
||
lda #$06
|
||
sta BASH
|
||
lda #$92
|
||
sta BASL
|
||
|
||
ldy #$0
|
||
ldx #$0
|
||
|
||
initials_loop:
|
||
|
||
; erase old pointer
|
||
|
||
ldy #$0
|
||
lda #$A0
|
||
sta (BASL),Y
|
||
iny
|
||
sta (BASL),Y
|
||
iny
|
||
sta (BASL),Y
|
||
|
||
txa
|
||
tay
|
||
|
||
; draw pointer
|
||
|
||
lda #$DE ; '^'
|
||
sta (BASL),Y
|
||
|
||
|
||
ldy #$0
|
||
|
||
; draw initials
|
||
|
||
lda HISCORE_1
|
||
sta (STRINGL),Y
|
||
|
||
iny
|
||
lda HISCORE_2
|
||
sta (STRINGL),Y
|
||
|
||
iny
|
||
lda HISCORE_3
|
||
sta (STRINGL),Y
|
||
|
||
in_key:
|
||
jsr wait_until_keypressed
|
||
lda LASTKEY
|
||
beq in_key
|
||
|
||
cmp #$D
|
||
beq do_hi_score
|
||
|
||
cmp #'I'
|
||
bne in_down
|
||
inc HISCORE_1,X
|
||
|
||
in_down:
|
||
|
||
cmp #'M'
|
||
bne in_left
|
||
dec HISCORE_1,X
|
||
|
||
in_left:
|
||
cmp #'K'
|
||
bne in_right
|
||
inx
|
||
|
||
in_right:
|
||
cmp #'J'
|
||
bne fix_limits
|
||
dex
|
||
fix_limits:
|
||
|
||
; Make sure X is between 0 and 2
|
||
|
||
cpx #$0
|
||
bpl x_high
|
||
ldx #$2
|
||
x_high:
|
||
cpx #$3
|
||
bmi x_lo
|
||
ldx #$0
|
||
x_lo:
|
||
|
||
jmp initials_loop
|
||
|
||
|
||
do_hi_score:
|
||
|
||
jsr HOME
|
||
|
||
lda #>high_score_string
|
||
sta STRINGH
|
||
lda #<high_score_string
|
||
sta STRINGL
|
||
|
||
jsr print_text_xy
|
||
|
||
|
||
; go to screen co-ords 15x12
|
||
|
||
lda #$06
|
||
sta STRINGH
|
||
lda #$37
|
||
sta STRINGL
|
||
|
||
; put the initials up
|
||
|
||
lda HISCORE_1
|
||
ldy #$0
|
||
sta (STRINGL),Y
|
||
|
||
lda HISCORE_2
|
||
iny
|
||
sta (STRINGL),Y
|
||
|
||
lda HISCORE_3
|
||
iny
|
||
sta (STRINGL),Y
|
||
|
||
; Print score to screen
|
||
;
|
||
|
||
lda #$06
|
||
sta STRINGH
|
||
lda #$3D
|
||
sta STRINGL
|
||
|
||
jsr print_high_score
|
||
|
||
jsr wait_until_keypressed
|
||
|
||
jmp opener
|
||
|
||
|
||
|
||
;=========================================================
|
||
; CLICK
|
||
;=========================================================
|
||
|
||
click:
|
||
lda SOUND_ON
|
||
beq no_click
|
||
bit SPEAKER
|
||
no_click:
|
||
rts
|
||
|
||
|
||
|
||
;==========================================================
|
||
; Wait X 100 msec
|
||
;==========================================================
|
||
;
|
||
wait_X_100msec:
|
||
lda #$86 ; constant ~ 100msec
|
||
jsr WAIT
|
||
dex
|
||
bne wait_X_100msec
|
||
rts
|
||
|
||
|
||
|
||
|
||
;==========================================================
|
||
; Update Shields
|
||
;==========================================================
|
||
;
|
||
|
||
update_shields:
|
||
|
||
lda #>shields_string
|
||
sta STRINGH
|
||
lda #<shields_string
|
||
sta STRINGL
|
||
|
||
|
||
ldy #0
|
||
|
||
lda SHIELDS
|
||
bne normal_shields
|
||
|
||
|
||
flash_shields:
|
||
lda #$7f
|
||
and (STRINGL),Y
|
||
sta (STRINGL),Y
|
||
iny
|
||
cpy #$7
|
||
bne flash_shields
|
||
jmp shields_line
|
||
|
||
normal_shields:
|
||
lda #$80
|
||
ora (STRINGL),Y
|
||
sta (STRINGL),Y
|
||
iny
|
||
cpy #$7
|
||
bne normal_shields
|
||
|
||
shields_line:
|
||
|
||
ldy #$A
|
||
ldx #$0
|
||
shield_line_loop:
|
||
|
||
cpx SHIELDS
|
||
bmi shield_box
|
||
lda #'_'+128
|
||
jmp shield_char
|
||
shield_box:
|
||
lda #' '
|
||
shield_char:
|
||
sta (STRINGL),Y
|
||
iny
|
||
iny
|
||
inx
|
||
cpx #$A
|
||
bne shield_line_loop
|
||
|
||
rts
|
||
|
||
|
||
;==========================================================
|
||
; Random Number Generator
|
||
;==========================================================
|
||
; from dlyons@Apple.COM (David A Lyons)
|
||
; posting to comps.sys.apple2 24 November 1992
|
||
; algorithm from Pop Science ~1980s
|
||
; when seeded with non-zero, will generate all 255 values
|
||
; before repeating
|
||
|
||
random_number:
|
||
lda RANDOM_SEED
|
||
bne random_not_zero
|
||
lda #$D
|
||
random_not_zero:
|
||
asl A
|
||
bcc random_num_done
|
||
eor #$87
|
||
random_num_done:
|
||
sta RANDOM_SEED
|
||
rts
|
||
|
||
|
||
|
||
|
||
;==========================================================
|
||
; Wait until keypressed
|
||
;==========================================================
|
||
;
|
||
|
||
wait_until_keypressed:
|
||
inc RANDOM_SEED ; seed random num counter
|
||
lda KEYPRESS ; check if keypressed
|
||
bpl wait_until_keypressed ; if not, loop
|
||
jmp figure_out_key
|
||
|
||
|
||
;==========================================================
|
||
; Get Key
|
||
;==========================================================
|
||
;
|
||
|
||
get_key:
|
||
|
||
|
||
|
||
check_paddle_button:
|
||
|
||
; check for paddle button
|
||
|
||
bit PADDLE_BUTTON0
|
||
bpl no_button
|
||
lda #' '+128
|
||
jmp save_key
|
||
|
||
no_button:
|
||
lda KEYPRESS
|
||
bpl no_key
|
||
|
||
figure_out_key:
|
||
cmp #' '+128 ; the mask destroys space
|
||
beq save_key ; so handle it specially
|
||
|
||
and #$5f ; mask, to make upper-case
|
||
check_right_arrow:
|
||
cmp #$15
|
||
bne check_left_arrow
|
||
lda #'K'
|
||
check_left_arrow:
|
||
cmp #$08
|
||
bne check_up_arrow
|
||
lda #'J'
|
||
check_up_arrow:
|
||
cmp #$0B
|
||
bne check_down_arrow
|
||
lda #'I'
|
||
check_down_arrow:
|
||
cmp #$0A
|
||
bne check_escape
|
||
lda #'M'
|
||
check_escape:
|
||
cmp #$1B
|
||
bne save_key
|
||
lda #'Q'
|
||
jmp save_key
|
||
|
||
no_key:
|
||
|
||
bit PADDLE_STATUS
|
||
bpl no_key_store
|
||
|
||
; check for paddle action
|
||
; code from http://web.pdx.edu/~heiss/technotes/aiie/tn.aiie.06.html
|
||
|
||
inc PADDLE_STATUS
|
||
lda PADDLE_STATUS
|
||
and #$03
|
||
beq check_paddles
|
||
jmp no_key_store
|
||
|
||
check_paddles:
|
||
|
||
lda PADDLE_STATUS
|
||
and #$80
|
||
sta PADDLE_STATUS
|
||
|
||
ldx #$0
|
||
LDA PTRIG ;TRIGGER PADDLES
|
||
LDY #0 ;INIT COUNTER
|
||
NOP ;COMPENSATE FOR 1ST COUNT
|
||
NOP
|
||
PREAD2: LDA PADDL0,X ;COUNT EVERY 11 <20>SEC.
|
||
BPL RTS2D ;BRANCH WHEN TIMED OUT
|
||
INY ;INCREMENT COUNTER
|
||
BNE PREAD2 ;CONTINUE COUNTING
|
||
DEY ;COUNTER OVERFLOWED
|
||
RTS2D: ;RETURN W/VALUE 0-255
|
||
|
||
cpy #96
|
||
bmi paddle_left
|
||
cpy #160
|
||
bmi no_key_store
|
||
lda #'K'
|
||
jmp save_key
|
||
|
||
paddle_left:
|
||
|
||
lda #'J'
|
||
jmp save_key
|
||
|
||
no_key_store:
|
||
lda #0 ; no key, so save a zero
|
||
|
||
save_key:
|
||
sta LASTKEY ; save the key to our buffer
|
||
bit KEYRESET ; clear the keyboard buffer
|
||
rts
|
||
|
||
|
||
|
||
;==========================================================
|
||
; score_plus_50
|
||
;==========================================================
|
||
;
|
||
score_plus_50:
|
||
|
||
|
||
sed ; enter decimal mode
|
||
clc
|
||
lda SCOREL
|
||
adc #$50
|
||
sta SCOREL ; score+=50
|
||
|
||
lda SCOREH
|
||
adc #$0
|
||
sta SCOREH ; carry into high byte if needed
|
||
|
||
cld ; leave decimal mode
|
||
|
||
jmp print_score
|
||
|
||
;==========================================================
|
||
; inc_score
|
||
;==========================================================
|
||
;
|
||
inc_score:
|
||
|
||
|
||
sed ; enter decimal mode
|
||
clc
|
||
lda SCOREL
|
||
adc #$5
|
||
sta SCOREL ; score+=5
|
||
|
||
lda SCOREH
|
||
adc #$0
|
||
sta SCOREH ; carry into high byte if needed
|
||
|
||
cld ; leave decimal mode
|
||
|
||
|
||
lda SCOREL ; if score /100 =0 then inc shields
|
||
bne print_score
|
||
|
||
lda SHIELDS
|
||
|
||
cmp #$0A ; don't raise shields higher than 10
|
||
bpl print_score
|
||
|
||
inc SHIELDS
|
||
jsr update_shields
|
||
|
||
print_score:
|
||
lda #>(score_string+7)
|
||
sta STRINGH
|
||
lda #<(score_string+7)
|
||
sta STRINGL
|
||
|
||
tya
|
||
pha ; save Y on stack
|
||
|
||
|
||
ldy #$0
|
||
|
||
lda SCOREH
|
||
sta BCD_BYTEH
|
||
|
||
lda SCOREL
|
||
sta BCD_BYTE
|
||
jsr print_bcd_word
|
||
|
||
pla ; restore Y
|
||
tay
|
||
|
||
rts
|
||
|
||
;======================
|
||
; print high_score
|
||
;======================
|
||
; location to output to in STRINGH/STRINGL
|
||
|
||
print_high_score:
|
||
tya
|
||
pha ; save Y on stack
|
||
|
||
ldy #$0
|
||
|
||
lda HISCORE_H
|
||
sta BCD_BYTEH
|
||
|
||
lda HISCORE_L
|
||
sta BCD_BYTE
|
||
jsr print_bcd_word
|
||
|
||
pla ; restore Y
|
||
tay
|
||
|
||
rts
|
||
|
||
;==========================================================
|
||
; print_bcd_word
|
||
;==========================================================
|
||
; string to output in STRINGH/STRINGL
|
||
; byte to output in BCD_BYTE
|
||
|
||
print_bcd_word:
|
||
|
||
|
||
lda BCD_BYTEH
|
||
lsr A
|
||
lsr A
|
||
lsr A
|
||
lsr A
|
||
and #$f ; mask low nybble
|
||
bne to_ascii_thou
|
||
|
||
lda #$A0 ; load a space
|
||
|
||
jmp write_thousands
|
||
to_ascii_thou:
|
||
adc #$B0 ; covert to ascii
|
||
|
||
write_thousands:
|
||
sta (STRINGL),Y ; store output
|
||
|
||
iny
|
||
|
||
lda BCD_BYTEH
|
||
|
||
and #$f
|
||
bne to_ascii_hun
|
||
|
||
cmp BCD_BYTEH
|
||
|
||
bne to_ascii_hun
|
||
|
||
lda #$A0
|
||
jmp write_hundreds
|
||
|
||
to_ascii_hun:
|
||
adc #$B0
|
||
write_hundreds:
|
||
sta (STRINGL),Y
|
||
|
||
iny
|
||
|
||
|
||
print_bcd_byte:
|
||
|
||
lda BCD_BYTE
|
||
lsr A
|
||
lsr A
|
||
lsr A
|
||
lsr A
|
||
and #$f ; mask low nybble
|
||
bne to_ascii_tens ; if not zero, convert to ascii
|
||
|
||
cmp BCD_BYTEH
|
||
|
||
bne to_ascii_tens
|
||
|
||
lda #$A0
|
||
|
||
jmp write_tens
|
||
to_ascii_tens:
|
||
adc #$B0 ; covert to ascii
|
||
|
||
write_tens:
|
||
sta (STRINGL),Y ; store output
|
||
|
||
iny ; point one lower
|
||
|
||
|
||
lda BCD_BYTE
|
||
clc
|
||
and #$f
|
||
adc #$B0
|
||
|
||
sta (STRINGL),Y
|
||
|
||
|
||
rts
|
||
|
||
;==========================================================
|
||
; check inside
|
||
;==========================================================
|
||
; Simple collision detection. Have small line x1<->x2
|
||
; Want to see if it overlaps long line x3<---------->x4
|
||
; so:
|
||
; if ((x1>x3)&&(x1<x4)) || ((x2>x3) && (x2<x4)) inside
|
||
; else outside
|
||
|
||
check_inside:
|
||
|
||
lda COL_X1
|
||
cmp COL_X3
|
||
bmi check_higher
|
||
cmp COL_X4
|
||
bmi inside
|
||
check_higher:
|
||
lda COL_X2
|
||
cmp COL_X3
|
||
bmi outside
|
||
cmp COL_X4
|
||
bpl outside
|
||
|
||
inside:
|
||
sec
|
||
rts
|
||
outside:
|
||
clc
|
||
rts
|
||
|
||
|
||
;==========================================================
|
||
; set_page0_text
|
||
;==========================================================
|
||
;
|
||
set_page0_text:
|
||
bit PAGE0 ; set page0
|
||
bit TEXT ; set text mode
|
||
rts
|
||
|
||
|
||
;==========================================================
|
||
; set_page0_gr
|
||
;==========================================================
|
||
;
|
||
|
||
set_page0_gr:
|
||
lda #4
|
||
sta GR_PAGE
|
||
bit PAGE0 ; set page 0
|
||
bit LORES ; Lo-res graphics
|
||
bit TEXTGR ; mixed gr/text mode
|
||
bit GR ; set graphics
|
||
rts
|
||
|
||
;==========================================================
|
||
; clear bottom
|
||
;==========================================================
|
||
;
|
||
clear_bottom:
|
||
lda #$2
|
||
clc
|
||
adc GR_PAGE
|
||
sta BASH ; point to line 21
|
||
|
||
lda #$50
|
||
sta BASL
|
||
|
||
ldx #$00 ; line counter
|
||
bottom_y:
|
||
lda #' '+128 ; want to put a space
|
||
ldy #$0 ; column count
|
||
bottom_loop:
|
||
sta (BASL),Y ; store a space
|
||
iny ; incrememnt
|
||
cpy #$28 ; are we > 40?
|
||
bmi bottom_loop ; if not, loop
|
||
|
||
lda #$80 ; go to next line [they are $80 apart]
|
||
clc
|
||
adc BASL ; increment base
|
||
sta BASL ; store it out
|
||
lda #$0 ; load 0 into A
|
||
adc BASH ; carry into top byte if need be
|
||
sta BASH ; and store out
|
||
|
||
inx ; increment line count
|
||
cpx #$4 ; have we done 4
|
||
bcc bottom_y ; if not, loop
|
||
|
||
rts
|
||
|
||
|
||
;==========================================================
|
||
; print X strings
|
||
;==========================================================
|
||
;
|
||
;
|
||
print_x_strings:
|
||
stx TEMP
|
||
jsr print_text_xy
|
||
ldx TEMP
|
||
dex
|
||
bne print_x_strings
|
||
rts
|
||
|
||
|
||
;==========================================================
|
||
; Print text x,y
|
||
;==========================================================
|
||
; x=ch y=cv
|
||
; string=string_addr
|
||
|
||
print_text_xy:
|
||
ldy #$0 ; clear IY
|
||
lda (STRINGL),Y ; load x from memory
|
||
sta CH ; store to CH
|
||
iny ; point to next value
|
||
|
||
lda (STRINGL),Y ; load y from memory
|
||
sta CV ; store to CV
|
||
; point to beginning of string
|
||
|
||
clc
|
||
lda #$2
|
||
adc STRINGL
|
||
sta STRINGL
|
||
lda #$0
|
||
adc STRINGH
|
||
sta STRINGH
|
||
|
||
print_text:
|
||
ldy #$0
|
||
lda CV
|
||
jsr BASCALC ; get the address of y in BASH:BASL
|
||
clc ; clear the carry
|
||
lda BASL ; load BASL
|
||
adc CH ; add x
|
||
sta BASL ; store BASL back out
|
||
|
||
output_loop:
|
||
lda (STRINGL),Y ; load char from string_addr+y
|
||
beq print_done ; if null terminated, done
|
||
sta (BASL),Y ; store to BASH:BASL
|
||
iny ; IY++
|
||
jmp output_loop ; loop
|
||
|
||
print_done:
|
||
iny
|
||
tya ; transfer y to accumulator
|
||
|
||
|
||
adc STRINGL ; add y and stringl
|
||
sta STRINGL ; and store it out
|
||
lda #$0 ; clear accumulator
|
||
adc STRINGH ; add with carry from prev stringh
|
||
sta STRINGH ; and save it
|
||
|
||
|
||
rts
|
||
|
||
|
||
|
||
|
||
;==========================================================
|
||
; clear_screen
|
||
;==========================================================
|
||
;
|
||
|
||
clear_screen:
|
||
|
||
ldx #$0
|
||
clear_0:
|
||
cpx #$0
|
||
bne clear_1
|
||
lda GR_PAGE
|
||
sta BASH
|
||
lda #$0
|
||
sta BASL
|
||
ldy #$78
|
||
jmp clear_it
|
||
clear_1:
|
||
cpx #$1
|
||
bne clear_2
|
||
lda #$80
|
||
sta BASL
|
||
ldy #$78
|
||
jmp clear_it
|
||
clear_2:
|
||
cpx #$2
|
||
bne clear_3
|
||
clc
|
||
lda #$1
|
||
adc GR_PAGE
|
||
|
||
sta BASH
|
||
ldy #$78
|
||
jmp clear_it
|
||
clear_3:
|
||
cpx #$3
|
||
bne clear_4
|
||
lda #$0
|
||
sta BASL
|
||
ldy #$78
|
||
jmp clear_it
|
||
clear_4:
|
||
cpx #$4
|
||
bne clear_5
|
||
clc
|
||
lda #$2
|
||
adc GR_PAGE
|
||
sta BASH
|
||
ldy #$50
|
||
jmp clear_it
|
||
clear_5:
|
||
cpx #$5
|
||
bne clear_6
|
||
lda #$80
|
||
sta BASL
|
||
ldy #$50
|
||
jmp clear_it
|
||
clear_6:
|
||
cpx #$6
|
||
bne clear_7
|
||
clc
|
||
lda #$3
|
||
adc GR_PAGE
|
||
sta BASH
|
||
ldy #$50
|
||
jmp clear_it
|
||
clear_7:
|
||
cpx #$7
|
||
bne clear_8
|
||
lda #$0
|
||
sta BASL
|
||
ldy #$50
|
||
jmp clear_it
|
||
clear_8:
|
||
|
||
rts
|
||
|
||
clear_it:
|
||
lda #$00
|
||
clear_loop:
|
||
dey
|
||
|
||
sta (BASL),Y
|
||
|
||
bne clear_loop
|
||
|
||
inx
|
||
jmp clear_0
|
||
|
||
;==========================================================
|
||
; show_stars
|
||
;==========================================================
|
||
;
|
||
|
||
show_stars:
|
||
|
||
|
||
lda #>star_field ; Load the star offsets
|
||
sta STRINGH ; array into
|
||
lda #<star_field ; STRINGH/STRINGL
|
||
sta STRINGL
|
||
|
||
lda BETWEEN_DELAY
|
||
and #$1
|
||
beq star_7
|
||
dec SCROLL ; decrement the scroll count
|
||
|
||
star_7:
|
||
ldy SCROLL ; load the scroll offset into Y
|
||
|
||
|
||
ldx #$8 ; We initially repeat 8 times
|
||
lda #$0 ; And have L of 0
|
||
sta TEMP ; This is stupid interlace stuff
|
||
sta COL_X1
|
||
|
||
star_4:
|
||
lda GR_PAGE ; we loop here, it resets
|
||
sta BASH ; to the proper page
|
||
|
||
star_0:
|
||
|
||
lda (STRINGL),Y ; get star offset
|
||
beq star_5
|
||
pha ; save for later
|
||
|
||
bmi light_star ; check color
|
||
lda #$5
|
||
jmp done_star
|
||
light_star:
|
||
lda #$A
|
||
done_star:
|
||
sta COL_X2 ; save color for later
|
||
|
||
pla ; restore offset
|
||
clc
|
||
and #$7f ; clear color flag
|
||
adc TEMP ; add in offset
|
||
sta BASL ; store as offset
|
||
|
||
tya ; save y on stack
|
||
pha ;
|
||
|
||
lda COL_X2
|
||
ldy #$0
|
||
sta (BASL),Y ; plot star
|
||
|
||
pla ; restore y from stack
|
||
tay
|
||
|
||
star_5:
|
||
iny ; increase y (offset pointer)
|
||
|
||
|
||
|
||
lda (STRINGL),Y ; get star offset
|
||
beq star_6
|
||
pha ; save for later
|
||
|
||
bmi light_star2 ; check color
|
||
lda #$50
|
||
jmp done_star2
|
||
light_star2:
|
||
lda #$A0
|
||
done_star2:
|
||
sta COL_X2 ; save color for later
|
||
|
||
pla ; restore offset
|
||
clc
|
||
and #$7f ; clear color flag
|
||
adc TEMP ; add in offset
|
||
sta BASL ; store as offset
|
||
|
||
tya ; save y on stack
|
||
pha ;
|
||
|
||
lda COL_X2
|
||
ldy #$0
|
||
sta (BASL),Y ; plot star
|
||
|
||
pla ; restore y from stack
|
||
tay
|
||
star_6:
|
||
|
||
iny ; increase y (offset pointer)
|
||
|
||
|
||
|
||
lda TEMP ; get offset
|
||
clc
|
||
adc #$80 ; increment to next line
|
||
sta TEMP ; and save back
|
||
|
||
bcc overflow_line ; if overflow, increase BASH
|
||
inc BASH
|
||
overflow_line:
|
||
|
||
dex ; repeat X times
|
||
bne star_0
|
||
|
||
inc COL_X1 ; check if first time through
|
||
lda #$1
|
||
cmp COL_X1
|
||
star_1:
|
||
bne star_2 ; reload for second 8 lines
|
||
ldx #$8
|
||
lda #$28
|
||
sta TEMP
|
||
jmp star_4
|
||
star_2: ; check if second time through
|
||
lda #$2
|
||
cmp COL_X1
|
||
bne star_3
|
||
ldx #$4 ; reload for another 4 lines
|
||
lda #$50
|
||
sta TEMP
|
||
jmp star_4
|
||
|
||
star_3:
|
||
rts
|
||
|
||
|
||
;==========================================================
|
||
; blit
|
||
;==========================================================
|
||
; x=ch y=cv
|
||
; string=addr of sprite
|
||
; only works on sprites < 256 bytes!!!
|
||
|
||
|
||
blit:
|
||
|
||
ldy #$00 ; clear IY
|
||
|
||
big_blit_loop:
|
||
|
||
lda CV ; Load y
|
||
jsr BASCALC ; we only do 40x20 so just use text mode
|
||
|
||
lda #$4
|
||
bit GR_PAGE
|
||
bne keep_blitting
|
||
clc
|
||
adc BASH
|
||
sta BASH
|
||
|
||
keep_blitting:
|
||
|
||
clc ; clear the carry
|
||
lda BASL ; load BASL
|
||
adc CH ; add x
|
||
sta BASL ; store BASL back out
|
||
bcc blit_loop ; if carry we overflowed
|
||
inc BASH ; add overflow into BASH
|
||
|
||
|
||
|
||
blit_loop:
|
||
lda (STRINGL),Y ; load char from string_addr+y
|
||
beq blit_x_done ; if null terminated, done this row
|
||
sty YSAV ; save IY
|
||
|
||
pha ; save run/color on stack
|
||
jsr SETCOL ; make low/high both col
|
||
; and save in in COLOR
|
||
|
||
pla ; restore run/color
|
||
lsr
|
||
lsr
|
||
lsr
|
||
lsr ; shift A right by 4 to get run-length
|
||
tax ; store in IX
|
||
|
||
ldy #$0 ; clear IY
|
||
lda COLOR ; load back COLOR
|
||
|
||
bne rle_loop ; if not zero, plot it
|
||
skip_color:
|
||
inc BASL ; increment pointer
|
||
dex ; count down IX
|
||
bne skip_color ; and skip ahead
|
||
jmp rle_loop_done ; done
|
||
|
||
|
||
rle_loop:
|
||
sta (BASL),Y ; store our color to the line
|
||
inc BASL ; increment output pointer
|
||
dex ; decrement count
|
||
bne rle_loop ; until done
|
||
|
||
rle_loop_done:
|
||
ldy YSAV ; restore SPRITE pointer
|
||
iny ; IY++
|
||
jmp blit_loop ; loop until row done
|
||
|
||
blit_x_done:
|
||
iny ; point past 0
|
||
lda (STRINGL),Y ; get next
|
||
beq blit_done ; if 0 as well, done with sprite
|
||
inc CV ; otherwise y++
|
||
jmp big_blit_loop ; and loop
|
||
|
||
blit_done:
|
||
rts
|
||
|
||
|
||
;; *********************
|
||
;; BSS
|
||
;; *********************
|
||
.bss
|
||
|
||
start_bss:
|
||
missile_0: .res NUM_MISSILES*3
|
||
enemy_0: .res NUM_ENEMIES*9
|
||
|
||
|
||
|
||
end_bss:
|
||
|
||
star_field: .res 255
|
||
zero_page_save: .res 56
|
||
|
||
|
||
;; *********************
|
||
;; DATA
|
||
;; *********************
|
||
.data
|
||
|
||
|
||
; SHIELDS: plus 22 spaces (30 total)
|
||
shields_string:
|
||
.byte $D3,$C8,$C9,$C5,$CC,$C4,$D3,$BA
|
||
.byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0
|
||
.byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0
|
||
.byte $A0,$A0
|
||
|
||
; SCORE and HISCORE: (38 Total)
|
||
score_string:
|
||
.byte $D3,$C3,$CF,$D2,$C5,$BA,$A0,$A0,$A0,$A0
|
||
.byte $A0
|
||
.byte $A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$A0
|
||
.byte $C8,$C9,$D3,$C3,$CF,$D2,$C5,$BA,$A0,$A0,$A0,$A0
|
||
.byte $B5,$B0,$B0,$A0,$A0,$A0
|
||
|
||
|
||
; LEVEL:
|
||
level_string_xy:
|
||
.byte $0E,$0A
|
||
level_string:
|
||
.byte $CC,$C5,$D6,$C5,$CC,$BA,$A0,$A0,$A0,$A0,$B1,$A0,$00
|
||
|
||
|
||
|
||
|
||
; A VMW SOFTWARE PRODUCTION
|
||
vmw_string: .byte $07,$14
|
||
.byte $C1,$A0,$D6,$CD,$D7,$A0,$D3,$CF,$C6,$D4,$D7,$C1,$D2
|
||
.byte $C5,$A0,$D0,$D2,$CF,$C4,$D5,$C3,$D4,$C9,$CF,$CE,$00
|
||
|
||
; MERCILESS MARAUDING MALICIOUS MARKETERS
|
||
mercy_string: .byte $00,$14
|
||
.byte $CD,$C5,$D2,$C3,$C9,$CC,$C5,$D3,$D3,$A0,$CD,$C1,$D2
|
||
.byte $C1,$D5,$C4,$C9,$CE,$C7,$A0,$CD,$C1,$CC,$C9,$C3,$C9
|
||
.byte $CF,$D5,$D3,$A0,$CD,$C1,$D2,$CB,$C5,$D4,$C5,$D2,$D3
|
||
.byte $00
|
||
|
||
; GAME OVER
|
||
game_over_string:
|
||
.byte $0F,$0A
|
||
.byte $C7,$C1,$CD,$C5,$A0,$CF,$D6,$C5,$D2,$00
|
||
|
||
; NEW GAME
|
||
new_game_string: .byte $CE,$C5,$D7,$A0,$C7,$C1,$CD,$C5,$00
|
||
; ABOUT
|
||
about_string: .byte $C1,$C2,$CF,$D5,$D4,$00
|
||
; STORY
|
||
story_string: .byte $D3,$D4,$CF,$D2,$D9,$00
|
||
; HISCORE
|
||
hiscore_string: .byte $C8,$C9,$A0,$D3,$C3,$CF,$D2,$C5,$00
|
||
; QUIT
|
||
quit_string: .byte $D1,$D5,$C9,$D4,$00
|
||
; H FOR HELP
|
||
help_string: .byte $0,$14
|
||
.byte $C8,$A0,$C6,$CF,$D2,$A0,$C8,$C5,$CC,$D0,$00
|
||
; QUIT? ARE YOU SURE?
|
||
quit_conf_string: .byte $D1,$D5,$C9,$D4,$BF,$A0,$C1,$D2,$C5,$A0,$D9,$CF,$D5
|
||
.byte $A0,$D3,$D5,$D2,$C5,$BF,$00
|
||
; YES
|
||
yes_string: .byte $D9,$C5,$D3,$00
|
||
; NO
|
||
no_string: .byte $CE,$CF,$00
|
||
|
||
|
||
about_lines:
|
||
; TOM BOMBEM BY VINCE WEAVER (PIC ABOVE)
|
||
.byte $0,$14
|
||
.byte $D4,$CF,$CD,$A0,$C2,$CF,$CD,$C2,$C5,$CD
|
||
.byte $A0,$A0,$C2,$D9,$A0,$D6,$C9,$CE,$C3,$C5
|
||
.byte $A0,$D7,$C5,$C1,$D6,$C5,$D2,$A0,$A8,$D0
|
||
.byte $C9,$C3,$A0,$C1,$C2,$CF,$D6,$C5,$A9,$00
|
||
|
||
; BASED ON LINUX TB_ASM - APPLE II FOREVER
|
||
.byte $0,$16
|
||
.byte $C2,$C1,$D3,$C5,$C4,$A0,$CF,$CE,$A0,$CC
|
||
.byte $C9,$CE,$D5,$D8,$A0,$D4,$C2,$DF,$C1,$D3
|
||
.byte $CD,$A0,$AD,$A0,$C1,$D0,$D0,$CC,$C5,$A0
|
||
.byte $C9,$C9,$A0,$C6,$CF,$D2,$C5,$D6,$C5,$D2,$00
|
||
|
||
; VINCE@DEATER.NET
|
||
.byte $0,$16
|
||
.byte $D6,$C9,$CE,$C3,$C5,$C0,$C4,$C5,$C1,$D4
|
||
.byte $C5,$D2,$AE,$CE,$C5,$D4,$00
|
||
|
||
; HTTP://WWW.DEATER.NET/WEAVE/VMWPROD/TB1/
|
||
.byte $0,$17
|
||
.byte $C8,$D4,$D4,$D0,$BA,$AF,$AF,$D7,$D7,$D7
|
||
.byte $AE,$C4,$C5,$C1,$D4,$C5,$D2,$AE,$CE,$C5
|
||
.byte $D4,$AF,$D7,$C5,$C1,$D6,$C5,$AF,$D6,$CD
|
||
.byte $D7,$D0,$D2,$CF,$C4,$AF,$D4,$C2,$B1,$AF,$00
|
||
|
||
ending_lines:
|
||
; *** MESSAGE FROM EARTH ***
|
||
.byte $7,$14
|
||
.byte $AA,$AA,$AA,$A0,$CD,$C5,$D3,$D3,$C1,$C7
|
||
.byte $C5,$A0,$C6,$D2,$CF,$CD,$A0,$C5,$C1,$D2
|
||
.byte $D4,$C8,$A0,$AA,$AA,$AA,$00
|
||
|
||
; CONGRATULATIONS TOM, YOU'VE DESTROYED
|
||
.byte $0,$16
|
||
.byte $C3,$CF,$CE,$C7,$D2,$C1,$D4,$D5,$CC,$C1
|
||
.byte $D4,$C9,$CF,$CE,$D3,$A0,$D4,$CF,$CD,$AC
|
||
.byte $A0,$D9,$CF,$D5,$A7,$D6,$C5,$A0,$C4,$C5
|
||
.byte $D3,$D4,$D2,$CF,$D9,$C5,$C4,$00
|
||
|
||
; THE MENACE!
|
||
.byte $2,$17
|
||
.byte $D4,$C8,$C5,$A0,$CD,$C5,$CE,$C1,$C3,$C5
|
||
.byte $A1,$00
|
||
|
||
; BUT WAIT! SENSORS ARE DETECTING NEW
|
||
.byte $0,$14
|
||
.byte $C2,$D5,$D4,$A0,$D7,$C1,$C9,$D4,$A1,$A0
|
||
.byte $A0,$D3,$C5,$CE,$D3,$CF,$D2,$D3,$A0,$C1
|
||
.byte $D2,$C5,$A0,$C4,$C5,$D4,$C5,$C3,$D4,$C9
|
||
.byte $CE,$C7,$A0,$CE,$C5,$D7,$00
|
||
|
||
; INCOMING TARGETS.
|
||
.byte $2,$15
|
||
.byte $C9,$CE,$C3,$CF,$CD,$C9,$CE,$C7,$A0,$D4
|
||
.byte $C1,$D2,$C7,$C5,$D4,$D3,$AE,$00
|
||
|
||
; REMEMBER, YOU DON'T GET PAID UNTIL ALL
|
||
.byte $0,$16
|
||
.byte $D2,$C5,$CD,$C5,$CD,$C2,$C5,$D2,$AC,$A0
|
||
.byte $D9,$CF,$D5,$A0,$C4,$CF,$CE,$A7,$D4,$A0
|
||
.byte $C7,$C5,$D4,$A0,$D0,$C1,$C9,$C4,$A0,$D5
|
||
.byte $CE,$D4,$C9,$CC,$A0,$C1,$CC,$CC,$00
|
||
|
||
; ARE DESTROYED
|
||
.byte $2,$17
|
||
.byte $C1,$D2,$C5,$A0,$C4,$C5,$D3,$D4,$D2,$CF
|
||
.byte $D9,$C5,$C4,$00
|
||
|
||
susie_lines:
|
||
; PS. YOUR PET GUINEA PIG IS DOING FINE
|
||
.byte $0,$14
|
||
.byte $D0,$D3,$AE,$A0,$A0,$D9,$CF,$D5,$D2,$A0
|
||
.byte $D0,$C5,$D4,$A0,$C7,$D5,$C9,$CE,$C5,$C1
|
||
.byte $A0,$D0,$C9,$C7,$A0,$C9,$D3,$A0,$C4,$CF
|
||
.byte $C9,$CE,$C7,$A0,$C6,$C9,$CE,$C5,$00
|
||
|
||
tom_sigh:
|
||
; TOM: *SIGH*
|
||
.byte $0,$14
|
||
.byte $D4,$CF,$CD,$BA,$A0,$AA,$D3,$C9,$C7,$C8,$AA,$00
|
||
|
||
story_lines:
|
||
|
||
; IT IS THE YEAR 2025.
|
||
.byte $0,$14
|
||
.byte $C9,$D4,$A0,$C9,$D3,$A0,$D4,$C8,$C5,$A0
|
||
.byte $D9,$C5,$C1,$D2,$A0,$B2,$B0,$B2,$B5,$AE,$00
|
||
|
||
; ALL TELEMARKETERS AND UNSOLICITED
|
||
|
||
.byte $2,$15
|
||
.byte $C1,$CC,$CC,$A0,$D4,$C5,$CC,$C5,$CD,$C1
|
||
.byte $D2,$CB,$C5,$D4,$C5,$D2,$D3,$A0,$C1,$CE
|
||
.byte $C4,$A0,$D5,$CE,$D3,$CF,$CC,$C9,$C3,$C9
|
||
.byte $D4,$C5,$C4,$00
|
||
|
||
; BULK E-MAILERS HAVE BEEN EXILED
|
||
.byte $4,$16
|
||
.byte $C2,$D5,$CC,$CB,$A0,$C5,$AD,$CD,$C1,$C9
|
||
.byte $CC,$C5,$D2,$D3,$A0,$C8,$C1,$D6,$C5,$A0
|
||
.byte $C2,$C5,$C5,$CE,$A0,$C5,$D8,$C9,$CC,$C5
|
||
.byte $C4,$00
|
||
|
||
; TO PHOBOS.
|
||
.byte $6,$17
|
||
.byte $D4,$CF,$A0,$D0,$C8,$CF,$C2,$CF,$D3,$AE,$00
|
||
|
||
; RIGHT BEFORE BEING TRAPPED FOREVER
|
||
.byte $0,$14
|
||
.byte $D2,$C9,$C7,$C8,$D4,$A0,$C2,$C5,$C6,$CF
|
||
.byte $D2,$C5,$A0,$C2,$C5,$C9,$CE,$C7,$A0,$D4
|
||
.byte $D2,$C1,$D0,$D0,$C5,$C4,$A0,$C6,$CF,$D2
|
||
.byte $C5,$D6,$C5,$D2,$00
|
||
|
||
; THEY MANAGE TO LAUNCH ONE LAST
|
||
.byte $2,$15
|
||
.byte $D4,$C8,$C5,$D9,$A0,$CD,$C1,$CE,$C1,$C7
|
||
.byte $C5,$A0,$D4,$CF,$A0,$CC,$C1,$D5,$CE,$C3
|
||
.byte $C8,$A0,$CF,$CE,$C5,$A0,$CC,$C1,$D3,$D4,$00
|
||
|
||
; MARKETING DROID.
|
||
.byte $4,$16
|
||
.byte $CD,$C1,$D2,$CB,$C5,$D4,$C9,$CE,$C7,$A0
|
||
.byte $C4,$D2,$CF,$C9,$C4,$AE,$00
|
||
|
||
help_lines:
|
||
; TOM BOMBEM
|
||
.byte $A,$0
|
||
.byte $D4,$CF,$CD,$A0,$C2,$CF,$CD,$C2,$C5,$CD,$00
|
||
; BY
|
||
.byte $E,$1
|
||
.byte $C2,$D9,$00
|
||
; VINCE WEAVER
|
||
.byte $9,$2
|
||
.byte $D6,$C9,$CE,$C3,$C5,$A0,$D7,$C5,$C1,$D6
|
||
.byte $C5,$D2,$00
|
||
; KEY BINDINGS:
|
||
.byte $0,$4
|
||
.byte $CB,$C5,$D9,$A0,$C2,$C9,$CE,$C4,$C9,$CE
|
||
.byte $C7,$D3,$BA,$00
|
||
; UP OR 'I' : MOVE MENU UP
|
||
.byte $2,$6
|
||
.byte $D5,$D0,$A0,$CF,$D2,$A0,$A7,$C9,$A7,$A0
|
||
.byte $A0,$A0,$A0,$BA,$A0,$CD,$CF,$D6,$C5,$A0
|
||
.byte $CD,$C5,$CE,$D5,$A0,$D5,$D0,$00
|
||
; DOWN OR 'M' : MOVE MENU DOWN
|
||
.byte $2,$7
|
||
.byte $C4,$CF,$D7,$CE,$A0,$CF,$D2,$A0,$A7,$CD
|
||
.byte $A7,$A0,$A0,$BA,$A0,$CD,$CF,$D6,$C5,$A0
|
||
.byte $CD,$C5,$CE,$D5,$A0,$C4,$CF,$D7,$CE,$00
|
||
; ENTER : SELECTS CURRENT OPTION
|
||
.byte $2,$8
|
||
.byte $C5,$CE,$D4,$C5,$D2,$00
|
||
.byte $F,$8
|
||
.byte $BA,$A0,$D3,$C5,$CC,$C5,$C3,$D4,$D3,$A0
|
||
.byte $C3,$D5,$D2,$D2,$C5,$CE,$D4,$A0,$CF,$D0
|
||
.byte $D4,$C9,$CF,$CE,$00
|
||
; RIGHT OR 'K' : MOVES SHIP RIGHT
|
||
.byte $2,$A
|
||
.byte $D2,$C9,$C7,$C8,$D4,$A0,$CF,$D2,$A0,$A7
|
||
.byte $CB,$A7,$A0,$BA,$A0,$CD,$CF,$D6,$C5,$D3
|
||
.byte $A0,$D3,$C8,$C9,$D0,$A0,$D2,$C9,$C7,$C8
|
||
.byte $D4,$00
|
||
; LEFT OR 'J' : MOVES SHIP LEFT
|
||
.byte $2,$B
|
||
.byte $CC,$C5,$C6,$D4,$A0,$CF,$D2,$A0,$A7,$CA
|
||
.byte $A7,$A0,$A0,$BA,$A0,$CD,$CF,$D6,$C5,$D3
|
||
.byte $A0,$D3,$C8,$C9,$D0,$A0,$CC,$C5,$C6,$D4,$00
|
||
; SPACEBAR : SHOOTS
|
||
.byte $2,$C
|
||
.byte $D3,$D0,$C1,$C3,$C5,$C2,$C1,$D2,$A0,$A0
|
||
.byte $A0,$A0,$A0,$BA,$A0,$D3,$C8,$CF,$CF,$D4
|
||
.byte $D3,$00
|
||
; 'H' : DISPLAYS HELP
|
||
.byte $2,$E
|
||
.byte $A7,$C8,$A7,$00
|
||
.byte $F,$E
|
||
.byte $BA,$A0,$C4,$C9,$D3,$D0,$CC,$C1,$D9,$D3
|
||
.byte $A0,$C8,$C5,$CC,$D0,$00
|
||
; ESC OR 'Q' : QUITS
|
||
.byte $2,$F
|
||
.byte $C5,$D3,$C3,$A0,$CF,$D2,$A0,$A7,$D1,$A7
|
||
.byte $A0,$A0,$A0,$BA,$A0,$D1,$D5,$C9,$D4,$D3,$00
|
||
; 'P' : PAUSES
|
||
.byte $2,$10
|
||
.byte $A7,$D0,$A7,$00
|
||
.byte $F,$10
|
||
.byte $BA,$A0,$D0,$C1,$D5,$D3,$C5,$D3,$00
|
||
; 'S' : TOGGLES SOUND
|
||
.byte $2,$11
|
||
.byte $A7,$D3,$A7,$00
|
||
.byte $F,$11
|
||
.byte $BA,$A0,$D4,$CF,$C7,$C7,$CC,$C5,$D3,$A0
|
||
.byte $D3,$CF,$D5,$CE,$C4,$00
|
||
; 'C' : ENABLES PADDLES
|
||
.byte $2,$12
|
||
.byte $A7,$C3,$A7,$00
|
||
.byte $F,$12
|
||
.byte $BA,$A0,$C5,$CE,$C1,$C2,$CC,$C5,$D3,$A0
|
||
.byte $D0,$C1,$C4,$C4,$CC,$C5,$D3,$00
|
||
|
||
|
||
you_are_tom:
|
||
; YOU ARE TOM BOMBEM.
|
||
.byte $0,$14
|
||
.byte $D9,$CF,$D5,$A0,$C1,$D2,$C5,$A0,$D4,$CF
|
||
.byte $CD,$A0,$C2,$CF,$CD,$C2,$C5,$CD,$AE,$00
|
||
|
||
; YOU DREW THE SHORT STRAW
|
||
.byte $1,$15
|
||
.byte $D9,$CF,$D5,$A0,$C4,$D2,$C5,$D7,$A0,$D4
|
||
.byte $C8,$C5,$A0,$D3,$C8,$CF,$D2,$D4,$A0,$D3
|
||
.byte $D4,$D2,$C1,$D7,$00
|
||
|
||
; IT IS UP TO YOU TO DESTROY THE EVIL
|
||
.byte $2,$16
|
||
.byte $C9,$D4,$A0,$C9,$D3,$A0,$D5,$D0,$A0,$D4
|
||
.byte $CF,$A0,$D9,$CF,$D5,$A0,$D4,$CF,$A0,$C4
|
||
.byte $C5,$D3,$D4,$D2,$CF,$D9,$A0,$D4,$C8,$C5
|
||
.byte $A0,$C5,$D6,$C9,$CC,$00
|
||
|
||
; AND RESTORE PEACE TO THE SOL SYSTEM.
|
||
.byte $3,$17
|
||
.byte $C1,$CE,$C4,$A0,$D2,$C5,$D3,$D4,$CF,$D2
|
||
.byte $C5,$A0,$D0,$C5,$C1,$C3,$C5,$A0,$D4,$CF
|
||
.byte $A0,$D4,$C8,$C5,$A0,$D3,$CF,$CC,$A0,$D3
|
||
.byte $D9,$D3,$D4,$C5,$CD,$AE,$00
|
||
|
||
|
||
bonus_string:
|
||
; BONUS POINTS
|
||
.byte $E,$0
|
||
.byte $C2,$CF,$CE,$D5,$D3,$A0,$D0,$CF,$C9,$CE
|
||
.byte $D4,$D3,$00
|
||
|
||
no_bonus_string:
|
||
; NONE
|
||
.byte $12,$2
|
||
.byte $CE,$CF,$CE,$C5,$00
|
||
|
||
bonus_shields:
|
||
; PERFECT SHIELDS +50
|
||
.byte $9,$2
|
||
.byte $D0,$C5,$D2,$C6,$C5,$C3,$D4,$A0,$D3,$C8
|
||
.byte $C9,$C5,$CC,$C4,$D3,$A0,$A0,$A0,$AB,$B5
|
||
.byte $B0,$00
|
||
|
||
bonus_aim:
|
||
; PERFECT AIM +50
|
||
.byte $9,$3
|
||
.byte $D0,$C5,$D2,$C6,$C5,$C3,$D4,$A0,$C1,$C9
|
||
.byte $CD,$A0,$A0,$A0,$A0,$A0,$A0,$A0,$AB,$B5
|
||
.byte $B0,$00
|
||
|
||
bonus_kills:
|
||
; PERFECT KILLS +50
|
||
.byte $9,$4
|
||
.byte $D0,$C5,$D2,$C6,$C5,$C3,$D4,$A0,$CB,$C9
|
||
.byte $CC,$CC,$D3,$A0,$A0,$A0,$A0,$A0,$AB,$B5
|
||
.byte $B0,$00
|
||
|
||
|
||
high_score_string:
|
||
; HIGH SCORE
|
||
.byte $F,$A
|
||
.byte $C8,$C9,$C7,$C8,$A0,$D3,$C3,$CF,$D2,$C5,$00
|
||
|
||
new_high_score_string:
|
||
; NEW HIGH SCORE
|
||
.byte $D,$0
|
||
.byte $CE,$C5,$D7,$A0,$C8,$C9,$C7,$C8,$A0,$D3
|
||
.byte $C3,$CF,$D2,$C5,$00
|
||
|
||
; USE ARROWS TO ENTER INITIALS
|
||
.byte $6,$2
|
||
.byte $D5,$D3,$C5,$A0,$C1,$D2,$D2,$CF,$D7,$D3
|
||
.byte $A0,$D4,$CF,$A0,$C5,$CE,$D4,$C5,$D2,$A0
|
||
.byte $C9,$CE,$C9,$D4,$C9,$C1,$CC,$D3,$00
|
||
|
||
|
||
vmw_sprite:
|
||
.byte $71,$14,$72,$14,$72,$00
|
||
.byte $71,$14,$72,$14,$72,$00
|
||
.byte $10,$51,$34,$52,$34,$52,$00
|
||
.byte $10,$51,$34,$52,$34,$52,$00
|
||
.byte $20,$31,$54,$32,$54,$32,$00
|
||
.byte $20,$31,$54,$32,$54,$32,$00
|
||
.byte $30,$11,$74,$12,$74,$12,$00
|
||
.byte $30,$11,$74,$12,$74,$12,$00
|
||
.byte $00
|
||
opener_sprite:
|
||
.byte $36,$10,$36,$10,$16,$30,$16,$10,$29,$20,$39,$10,$19,$30,$19,$10,$29,$20,$29,$10,$19,$30,$19,$00
|
||
.byte $10,$16,$20,$16,$10,$16,$10,$26,$10,$26,$10,$19,$10,$19,$10,$19,$10,$19,$10,$29,$10,$29,$10,$19,$10,$19,$10,$19,$20,$29,$10,$29,$00
|
||
.byte $10,$16,$20,$16,$10,$16,$10,$16,$10,$16,$10,$16,$10,$29,$20,$19,$10,$19,$10,$19,$10,$19,$10,$19,$10,$29,$20,$29,$10,$19,$10,$19,$10,$19,$00
|
||
.byte $10,$16,$20,$16,$10,$16,$10,$16,$30,$16,$10,$19,$10,$19,$10,$19,$10,$19,$10,$19,$30,$19,$10,$19,$10,$19,$10,$19,$20,$19,$30,$19,$00
|
||
.byte $10,$16,$20,$36,$10,$16,$30,$16,$10,$29,$20,$39,$10,$19,$30,$19,$10,$29,$20,$29,$10,$19,$30,$19,$00
|
||
.byte $F0,$F0,$00
|
||
.byte $F0,$A0,$1A,$A0,$1A,$00
|
||
.byte $30,$1A,$70,$1F,$F0,$40,$15,$00
|
||
.byte $F0,$F0,$00
|
||
.byte $50,$1A,$A0,$15,$C0,$1F,$00
|
||
.byte $00
|
||
opener_sprite_2:
|
||
.byte $50,$2A,$F0,$1A,$D0,$1E,$00
|
||
.byte $10,$1D,$30,$3A,$F0,$E0,$1E,$21,$00
|
||
.byte $10,$3D,$16,$8F,$36,$F0,$60,$1E,$29,$00
|
||
.byte $2D,$11,$19,$16,$1F,$11,$14,$16,$14,$16,$2F,$46,$F0,$40,$1E,$10,$29,$00
|
||
.byte $10,$2D,$19,$16,$1F,$11,$14,$16,$14,$16,$2F,$56,$60,$11,$D0,$29,$00
|
||
.byte $30,$1D,$16,$8A,$6F,$40,$1D,$4A,$A0,$29,$00
|
||
.byte $F0,$90,$11,$80,$1F,$40,$21,$00
|
||
.byte $40,$15,$50,$1A,$F0,$00
|
||
.byte $10,$1F,$F0,$1F,$90,$15,$00
|
||
.byte $F0,$F0,$80,$1A,$00
|
||
.byte $00
|
||
|
||
vince_sprite:
|
||
.byte $20,$15,$8F,$15,$00
|
||
.byte $10,$15,$1A,$4F,$1A,$4F,$2A,$00
|
||
.byte $15,$5A,$15,$1A,$1F,$2A,$3F,$1A,$00
|
||
.byte $1A,$15,$10,$15,$3A,$8F,$15,$00
|
||
.byte $1A,$10,$15,$CF,$1A,$00
|
||
.byte $15,$10,$1A,$7F,$1A,$1F,$2A,$25,$00
|
||
.byte $25,$9F,$25,$10,$15,$1A,$00
|
||
.byte $15,$1A,$4F,$1A,$3F,$1A,$10,$15,$10,$15,$1A,$00
|
||
.byte $1A,$25,$1A,$1F,$15,$10,$15,$1A,$1F,$1A,$40,$15,$00
|
||
.byte $10,$1A,$10,$15,$1F,$20,$15,$10,$15,$1F,$15,$30,$15,$00
|
||
.byte $10,$1A,$15,$1A,$1F,$15,$20,$1A,$2F,$1A,$30,$1A,$00
|
||
.byte $10,$1F,$15,$3F,$2A,$4F,$30,$1A,$00
|
||
.byte $10,$1F,$1A,$25,$1A,$5F,$35,$2A,$00
|
||
.byte $10,$2F,$15,$10,$1A,$4F,$1A,$10,$3A,$00
|
||
.byte $10,$2F,$1A,$15,$2A,$3F,$1A,$10,$2A,$15,$00
|
||
.byte $10,$2A,$10,$15,$20,$2A,$20,$1F,$15,$1A,$00
|
||
.byte $10,$15,$2F,$15,$2F,$1A,$20,$15,$2A,$15,$00
|
||
.byte $20,$1F,$3A,$1F,$2A,$25,$1F,$1A,$00
|
||
.byte $20,$1A,$4F,$25,$10,$15,$1F,$15,$00
|
||
.byte $30,$25,$50,$1A,$1F,$15,$00
|
||
.byte $00
|
||
|
||
phobos_sprite:
|
||
.byte $F0,$30,$1A,$F0,$00
|
||
.byte $F0,$F0,$60,$1F,$00
|
||
.byte $F0,$F0,$00
|
||
.byte $50,$1A,$4F,$F0,$00
|
||
.byte $40,$11,$69,$E0,$1F,$00
|
||
.byte $30,$11,$59,$11,$29,$F0,$00
|
||
.byte $30,$11,$89,$F0,$00
|
||
.byte $30,$11,$39,$11,$49,$50,$15,$18,$F0,$00
|
||
.byte $30,$11,$89,$50,$18,$F0,$00
|
||
.byte $30,$11,$59,$11,$29,$F0,$40,$1F,$00
|
||
.byte $40,$11,$69,$F0,$1A,$00
|
||
.byte $50,$1A,$4F,$F0,$00
|
||
.byte $F0,$F0,$00
|
||
.byte $F0,$F0,$00
|
||
.byte $30,$1F,$D0,$1A,$C0,$1A,$00
|
||
.byte $00
|
||
evil_ship_sprite:
|
||
.byte $17,$1E,$17,$00
|
||
.byte $00
|
||
|
||
|
||
tom_sprite:
|
||
.byte $20,$62,$46,$00
|
||
.byte $20,$22,$40,$25,$26,$00
|
||
.byte $20,$22,$40,$25,$26,$00
|
||
.byte $20,$22,$40,$25,$26,$00
|
||
.byte $20,$22,$40,$25,$26,$00
|
||
.byte $40,$42,$26,$00
|
||
.byte $82,$86,$00
|
||
.byte $22,$26,$42,$26,$29,$22,$26,$00
|
||
.byte $22,$26,$42,$46,$22,$26,$00
|
||
.byte $22,$26,$42,$46,$22,$26,$00
|
||
.byte $22,$26,$42,$46,$22,$26,$00
|
||
.byte $22,$26,$42,$46,$22,$26,$00
|
||
.byte $27,$2E,$22,$26,$22,$26,$27,$2E,$00
|
||
.byte $40,$22,$26,$22,$26,$00
|
||
.byte $40,$22,$26,$22,$26,$00
|
||
.byte $40,$22,$26,$22,$26,$00
|
||
.byte $40,$27,$2E,$27,$2E,$00
|
||
.byte $40,$25,$2A,$25,$2A,$00
|
||
.byte $00
|
||
|
||
ship_sprite:
|
||
.byte $20,$36,$00
|
||
.byte $10,$1A,$3F,$1A,$00
|
||
.byte $2A,$1F,$1A,$1F,$2A,$00
|
||
.byte $30,$1D,$00
|
||
.byte $00
|
||
|
||
missile_sprite:
|
||
.byte $1A,$00
|
||
.byte $1A,$00
|
||
.byte $1D,$00
|
||
.byte $00
|
||
|
||
enemy_sprites:
|
||
enemy_sprite0:
|
||
.byte $2F,$11,$00
|
||
.byte $3F,$00
|
||
.byte $00,$00,$00
|
||
enemy_sprite1:
|
||
.byte $16,$10,$16,$00
|
||
.byte $10,$16,$00
|
||
.byte $00
|
||
enemy_sprite2:
|
||
.byte $17,$28,$00
|
||
.byte $17,$28,$00
|
||
.byte $00,$00
|
||
enemy_sprite3:
|
||
.byte $10,$1D,$00
|
||
.byte $1D,$10,$1D,$00
|
||
.byte $00
|
||
enemy_sprite4:
|
||
.byte $19,$2F,$00
|
||
.byte $19,$2A,$00
|
||
.byte $00,$00
|
||
enemy_sprite5:
|
||
.byte $14,$1C,$14,$00
|
||
.byte $34,$00
|
||
; .byte $14,$1C,$14,$00
|
||
.byte $00,$00
|
||
enemy_sprite6:
|
||
.byte $1F,$20,$00
|
||
.byte $3C,$00
|
||
.byte $00,$00,$00
|
||
enemy_sprite7:
|
||
.byte $33,$00
|
||
.byte $13,$10,$13,$00
|
||
.byte $00,$00
|
||
|
||
explosion_sprites:
|
||
explosion_sprite0:
|
||
.byte $2D,$19,$00
|
||
.byte $19,$1D,$15,$00
|
||
.byte $00
|
||
explosion_sprite1:
|
||
.byte $2A,$11,$00
|
||
.byte $11,$1A,$00
|
||
.byte $00,$00
|
||
explosion_sprite2:
|
||
.byte $25,$00
|
||
.byte $10,$25,$00
|
||
.byte $00
|
||
|
||
smoke_sprites:
|
||
smoke_sprite0:
|
||
.byte $10,$15,$00
|
||
.byte $00
|
||
smoke_sprite1:
|
||
.byte $25,$1A,$00
|
||
.byte $00
|
||
smoke_sprite2:
|
||
.byte $2A,$11,$00
|
||
.byte $00
|
||
|
||
boss_sprite:
|
||
.byte $1F,$1A,$11,$79,$11,$1A,$1F,$00
|
||
.byte $1F,$15,$1A,$21,$17,$1E,$17,$21,$1A,$15,$1F,$00
|
||
.byte $1F,$10,$15,$1A,$17,$1E,$1D,$1E,$17,$1A,$15,$10,$1F,$00
|
||
.byte $00
|
||
|
||
laser_sprites:
|
||
laser_sprite0:
|
||
.byte $1B,$00
|
||
.byte $13,$00
|
||
.byte $00
|
||
laser_sprite1:
|
||
.byte $13,$00
|
||
.byte $1B,$00
|
||
.byte $00
|
||
|
||
tom_head_sprite:
|
||
.byte $10,$32,$26,$00
|
||
.byte $10,$12,$20,$15,$16,$00
|
||
.byte $10,$12,$20,$15,$16,$00
|
||
.byte $10,$12,$20,$15,$16,$00
|
||
.byte $10,$12,$20,$15,$16,$00
|
||
.byte $20,$22,$16,$00
|
||
.byte $42,$36,$00
|
||
.byte $00
|
||
|
||
earth_sprite:
|
||
.byte $10,$1A,$2F,$00
|
||
.byte $14,$2C,$26,$00
|
||
.byte $12,$1C,$36,$00
|
||
.byte $12,$16,$2C,$16,$00
|
||
.byte $12,$16,$1C,$26,$00
|
||
.byte $10,$1A,$2F,$00
|
||
.byte $00
|
||
|
||
susie_sprite:
|
||
.byte $BA,$15,$10,$2F,$10,$3A,$00
|
||
.byte $2A,$90,$15,$20,$15,$20,$2A,$00
|
||
.byte $1A,$F0,$20,$1A,$00
|
||
.byte $1A,$F0,$20,$1A,$00
|
||
.byte $1A,$F0,$3A,$00
|
||
.byte $2A,$C0,$5A,$00
|
||
.byte $4A,$35,$5A,$35,$4A,$00
|