Skip to content

Instantly share code, notes, and snippets.

@Solvalou
Created September 27, 2010 20:01
Show Gist options
  • Save Solvalou/599711 to your computer and use it in GitHub Desktop.
Save Solvalou/599711 to your computer and use it in GitHub Desktop.
; iNES - Header
.inesprg 1 ; size of PRG-ROM, 16kB
.ineschr 1 ; size of CHR-ROM/RAM, 8kB
.inesmir 1 ; type of mirroring, 0 = horizontal, 1 = vertical
.inesmap 0 ; used mapper, 0 = no mapper
.bank 1
.org $FFFA
.dw 0 ; NMI_Routine($FFFA)
.dw start ; Reset_Routine($FFFC)
.dw 0 ; IRQ_Routine($FFFE)
.bank 0
.org $0000 ; RAM, zero-page
; player 1 score digits
digitI: .db 0
digitII: .db 0
digitIII: .db 0
; player 2 score digits
digitIV: .db 0
digitV: .db 0
digitVI: .db 0
; hi-score digits
hidigitI: .db 0
hidigitII: .db 0
hidigitIII: .db 0
; credit counter digits
credit_digitI: .db 0
credit_digitII: .db 0
credits: .db 0
timer_counter: .db 0
; variables for timed_writing-routine
address_lo: .db 0
address_hi: .db 0
destination_lo: .db 0
destination_hi: .db 0
writing_cycles: .db 0
status: .db 0 ; routine status
select_status: .db 0 ; status of select-button
a_status: .db 0 ; status of a-button
vblank_timer_count: .db 0
tile_one: .db 0
tile_two: .db 0
tile_three: .db 0
tile_four: .db 0
counter: .db 0
counter_: .db 0
; game variables
lifecount: .db 0
loopcounter: .db 0
lineI_lo: .db 0
lineI_hi: .db 0
lineII_lo: .db 0
lineII_hi: .db 0
lineIII_lo: .db 0
lineIII_hi: .db 0
lineIV_lo: .db 0
lineIV_hi: .db 0
lineV_lo: .db 0
lineV_hi: .db 0
alien_one_lo: .db 0
alien_one_hi: .db 0
alien_two_lo: .db 0
alien_two_hi: .db 0
alien_three_lo: .db 0
alien_three_hi: .db 0
empty_status: .db 0
after_status: .db 0
tile_status: .db 0
address_counter_max: .db 0
address_counter: .db 0
movement: .db 0 ; 0 = right, 1 = left
empty_lo: .db 0
empty_hi: .db 0
first_run: .db 0 ; 0 = first run, 1 = after first run
; sprite variables
ship_x: .db 0
missile_x: .db 0
missile_y: .db 0
; collision detection variables
; missile hitbox
missile_left: .db 0
missile_right: .db 0
missile_top: .db 0
; no bottom needed, missile can't be hit at the bottom
alien_left: .db 0
alien_right: .db 0
alien_bottom: .db 0
; no top needed, alien can't be hit at the top
line_lo: .db 0
line_hi: .db 0
tile_hi: .db 0
collision_status: .db 0
; --------------------------------------------------------------------
; first alien line; status variables
tileA: .db 0
tileB: .db 0
tileC: .db 0
tileD: .db 0
tileE: .db 0
tileF: .db 0
tileG: .db 0
tileH: .db 0
tileI: .db 0
tileJ: .db 0
tileK: .db 0
; --------------------------------------------------------------------
; second alien line; status variables
tileAA: .db 0
tileAB: .db 0
tileAC: .db 0
tileAD: .db 0
tileAE: .db 0
tileAF: .db 0
tileAG: .db 0
tileAH: .db 0
tileAI: .db 0
tileAJ: .db 0
tileAK: .db 0
; --------------------------------------------------------------------
; third alien line; status variables
tileBA: .db 0
tileBB: .db 0
tileBC: .db 0
tileBD: .db 0
tileBE: .db 0
tileBF: .db 0
tileBG: .db 0
tileBH: .db 0
tileBI: .db 0
tileBJ: .db 0
tileBK: .db 0
; --------------------------------------------------------------------
; fourth alien line; status variables
tileCA: .db 0
tileCB: .db 0
tileCC: .db 0
tileCD: .db 0
tileCE: .db 0
tileCF: .db 0
tileCG: .db 0
tileCH: .db 0
tileCI: .db 0
tileCJ: .db 0
tileCK: .db 0
; --------------------------------------------------------------------
; fifth alien line; status variables
tileDA: .db 0
tileDB: .db 0
tileDC: .db 0
tileDD: .db 0
tileDE: .db 0
tileDF: .db 0
tileDG: .db 0
tileDH: .db 0
tileDI: .db 0
tileDJ: .db 0
tileDK: .db 0
; --------------------------------------------------------------------
; tile addresses
A_hi: .db 0
B_hi: .db 0
C_hi: .db 0
D_hi: .db 0
E_hi: .db 0
F_hi: .db 0
G_hi: .db 0
H_hi: .db 0
I_hi: .db 0
J_hi: .db 0
K_hi: .db 0
AA_hi: .db 0
AB_hi: .db 0
AC_hi: .db 0
AD_hi: .db 0
AE_hi: .db 0
AF_hi: .db 0
AG_hi: .db 0
AH_hi: .db 0
AI_hi: .db 0
AJ_hi: .db 0
AK_hi: .db 0
BA_hi: .db 0
BB_hi: .db 0
BC_hi: .db 0
BD_hi: .db 0
BE_hi: .db 0
BF_hi: .db 0
BG_hi: .db 0
BH_hi: .db 0
BI_hi: .db 0
BJ_hi: .db 0
BK_hi: .db 0
CA_hi: .db 0
CB_hi: .db 0
CC_hi: .db 0
CD_hi: .db 0
CE_hi: .db 0
CF_hi: .db 0
CG_hi: .db 0
CH_hi: .db 0
CI_hi: .db 0
CJ_hi: .db 0
CK_hi: .db 0
DA_hi: .db 0
DB_hi: .db 0
DC_hi: .db 0
DD_hi: .db 0
DE_hi: .db 0
DF_hi: .db 0
DG_hi: .db 0
DH_hi: .db 0
DI_hi: .db 0
DJ_hi: .db 0
DK_hi: .db 0
; --------------------------------------------------------------------
; defines the status of the alien-columns
columnA_status: .db 0
columnB_status: .db 0
columnC_status: .db 0
columnD_status: .db 0
columnE_status: .db 0
columnF_status: .db 0
columnG_status: .db 0
columnH_status: .db 0
columnI_status: .db 0
columnJ_status: .db 0
columnK_status: .db 0
.org $0300 ; sprite-DMA section
spriteI_y: .db 0 ; sprite 1, y-position
spriteI_t: .db 0 ; sprite 1, tile-nr
spriteI_s: .db 0 ; sprite 1, special byte
spriteI_x: .db 0 ; sprite 1, x-position
spriteII_y: .db 0 ; same as above
spriteII_t: .db 0
spriteII_s: .db 0
spriteII_x: .db 0
; up to 32 sprites can be defined here
; spritenr. set with roman numerics,
; because nesasm doesn't support numericals in names
.org $8000 ; start of the PRG-ROM
start:
CPU_init:
cld ; clear decimal mode, not supported
sei ; disable interrupts
stack_init:
ldx #$FF ; set x to $FF = top of stack
txs ; transfer x to stack
PPU_init:
lda #%00001000
sta $2000 ; background pattern table at $0000
; sprite pattern table at $1000
lda #%00011110
sta $2001 ; #%76543210
; 4 - sprites visible
; 3 - background visible
; 2 - no sprite clipping
; 1 - no background clipping
; 0 - color display
points_init:
ldx #$20
stx digitI
stx digitII
stx digitIII
stx digitIV
stx digitV
stx digitVI
stx hidigitI
stx hidigitII
stx hidigitIII
credit_init:
ldx #$20
stx credit_digitI
stx credit_digitII
status_var_init:
ldx #$00
stx status
stx a_status
stx select_status
game_init:
ldx #$00
stx empty_lo
stx empty_hi
stx movement ; set to right
stx loopcounter
stx empty_status
stx first_run
ldx #$23
stx lifecount
ldx #$21
stx lineI_lo
stx lineII_lo
stx lineIII_lo
stx lineIV_lo
ldx #$C5
stx lineI_hi
ldx #$85
stx lineII_hi
ldx #$45
stx lineIII_hi
ldx #$05
stx lineIV_hi
ldx #$20
stx lineV_lo
ldx #$C5
stx lineV_hi
tile_status_init:
ldx #$00
stx tileA
stx tileB
stx tileC
stx tileD
stx tileE
stx tileF
stx tileG
stx tileH
stx tileI
stx tileJ
stx tileK
stx tileAA
stx tileAB
stx tileAC
stx tileAD
stx tileAE
stx tileAF
stx tileAG
stx tileAH
stx tileAI
stx tileAJ
stx tileAK
stx tileBA
stx tileBB
stx tileBC
stx tileBD
stx tileBE
stx tileBF
stx tileBG
stx tileBH
stx tileBI
stx tileBJ
stx tileBK
stx tileCA
stx tileCB
stx tileCC
stx tileCD
stx tileCE
stx tileCF
stx tileCG
stx tileCH
stx tileCI
stx tileCJ
stx tileCK
stx tileDA
stx tileDB
stx tileDC
stx tileDD
stx tileDE
stx tileDF
stx tileDG
stx tileDH
stx tileDI
stx tileDJ
stx tileDK
column_status_init:
ldx #$00
stx columnA_status
stx columnB_status
stx columnC_status
stx columnD_status
stx columnE_status
stx columnF_status
stx columnG_status
stx columnH_status
stx columnI_status
stx columnJ_status
stx columnK_status
sprite_var_init:
ldx #16 ; set player-ship-sprite start position at 16
stx ship_x
ldx #207
stx missile_y
hitbox_init:
ldx #$00
stx missile_left
stx missile_right
stx missile_top
stx alien_left
stx alien_right
stx alien_bottom
stx line_lo
stx line_hi
stx tile_hi
stx collision_status
palette_init:
lda #$3F ; sets the start-address of the
sta $2006 ; palette-data at $3F00
lda #$00
sta $2006
ldx #$00
palette_load:
lda palette_data, x
sta $2007
inx
cpx #32
bne palette_load
; --------------------------------------------------------------------
infinite:
jsr hud_static
; if status-variable is 0 then draw the titlescreen
; when finished set status to 1
lda status
cmp #$00
beq titlescreen
cmp #$02
beq gamejmp ; jumps to label "game"
cmp #$03
beq gamejmp
titlescreen_return:
;sprite_load:
; lda $03 ; load a with the DMA-position $0300
; sta $4014 ; transfer 256bytes from $0300 to $2004
jmp infinite
gamejmp:
jmp game
; +------------------------------------------------------------------+
; | TITLESCREEN-ANIMATION |
; +------------------------------------------------------------------+
titlescreen:
ldy #$00
lda #$05
sta vblank_timer_count ; vblank_timer waits 5 vblanks
timer_routine: ; waits 2 seconds
jsr vblank_timer
iny
cpy #20
bne timer_routine
; +------------------------------------------------------------------+
; | NAMETABLE LOADING WITH PAUSING |
; | those variables must be defined |
; | when using the "timed_writing" routine |
; +------------------------------------------------------------------+
; | lda #$xx xx = low part of the destinated address |
; | sta destination_lo |
; | lda #$xx xx = high part of the destinated address |
; | sta destination_hi |
; | lda #$xx xx = number of tiles to be written |
; | sta writing_cycles |
; | lda #low(x) x = nametable to be loaded |
; | sta address_lo |
; | lda #high(x) x = nametable to be loaded |
; | sta address_hi |
; | ldy #$00 y needs to be reset before jsr |
; | jsr timed_writing |
; +------------------------------------------------------------------+
play_routine:
lda #$21
sta destination_lo
lda #$0E
sta destination_hi
lda #$04
sta writing_cycles
lda #low(play)
sta address_lo
lda #high(play)
sta address_hi
ldy #$00
jsr timed_writing
; located at $21A9
space_invaders_routine:
lda #$21
sta destination_lo
lda #$69
sta destination_hi
lda #$0F
sta writing_cycles
lda #low(space_invaders)
sta address_lo
lda #high(space_invaders)
sta address_hi
ldy #$00
jsr timed_writing
ldy #$00
timer_routine1: ; waits 1,2 seconds
jsr vblank_timer
iny
cpy #12
bne timer_routine1
; *SCORE ADVANCE TABLE*
score_advance_init:
ldx #$00
lda #$21
sta $2006
lda #$E6
sta $2006
score_advance_load:
lda score_advance, x
sta $2007
inx
cpx #$15
bne score_advance_load
; draw UFO and "="
lda #$22
sta $2006
lda #$2A
sta $2006
lda #$46
sta $2007
lda #$47
sta $2007
lda #$31
sta $2007
; draw alien #1
lda #$22
sta $2006
lda #$6A
sta $2006
lda #$40
sta $2007
lda #$41
sta $2007
; draw alien #2
lda #$22
sta $2006
lda #$AA
sta $2006
lda #$42
sta $2007
lda #$43
sta $2007
; draw alien #3
lda #$22
sta $2006
lda #$EA
sta $2006
lda #$44
sta $2007
lda #$45
sta $2007
jsr scanline_reset
jsr vblank_timer
; writes the parts of the "SCORE ADVANCE TABLE"
mystery_score:
lda #$22
sta destination_lo
lda #$2D
sta destination_hi
lda #$09
sta writing_cycles
lda #low(score)
sta address_lo
lda #high(score)
sta address_hi
ldy #$00
jsr timed_writing
score1_routine:
lda #$22
sta destination_lo
lda #$6C
sta destination_hi
lda #$0A
sta writing_cycles
lda #low(score1)
sta address_lo
lda #high(score1)
sta address_hi
ldy #$00
jsr timed_writing
score2_routine:
lda #$22
sta destination_lo
lda #$AC
sta destination_hi
lda #$0A
sta writing_cycles
lda #low(score2)
sta address_lo
lda #high(score2)
sta address_hi
ldy #$00
jsr timed_writing
score3_routine:
lda #$22
sta destination_lo
lda #$EC
sta destination_hi
lda #$0A
sta writing_cycles
lda #low(score3)
sta address_lo
lda #high(score3)
sta address_hi
ldy #$00
jsr timed_writing
ldy #$00
timer_routine2: ; waits 2,3 seconds
jsr vblank_timer
iny
cpy #23
bne timer_routine2
lda #$01
sta status
jmp titlescreen_return
; +------------------------------------------------------------------+
; | END OF TITLESCREEN-ANIMATION |
; +------------------------------------------------------------------+
; +------------------------------------------------------------------+
; | HUD |
; +------------------------------------------------------------------+
; static part:
hud_static:
jsr vblank
score_line_init:
lda #$20
sta $2006
sta $2006 ; address set to $2020, second line on screen
ldx #$00 ; x reset
ldy #$00 ; y reset
score_line_load:
lda score_line, x
sta $2007
inx
cpx #$20
bne score_line_load
credit_sign:
lda #$23
sta $2006
lda #$93
sta $2006
ldx #$00
credit_sign_loop:
lda credit, x
sta $2007
inx
cpx #$06
bne credit_sign_loop
jsr scanline_reset
lda status ; check if a game was started
cmp #$02 ; the advanced hud gets showed until now
bcs advanced_hud
rts
advanced_hud:
lda #$23
sta $2006
lda #$83
sta $2006
lda lifecount ; draws the number of lifes on the screen
sta $2007
lda #$00 ; draws a empty tile
sta $2007
lda lifecount
cmp #$03
beq three_lifes
cmp #$02
beq two_lifes
cmp #$01
bcc one_life ; ...or less
three_lifes: ; draw two ships
lda #$48 ; but why is it called three_lifes?
sta $2007 ; because the third one is the player-ship!
lda #$49
sta $2007
lda #$48
sta $2007
lda #$49
sta $2007
jsr scanline_reset
rts
two_lifes:
lda #$48
sta $2007
lda #$49
sta $2007
jsr scanline_reset
rts
one_life:
jsr scanline_reset
rts
; --------------------------------------------------------------------
; dynamic part:
hud_dynamic:
score_load_init:
lda #$20
sta $2006
lda #$65
sta $2006
score_load:
; player 1 score digits
lda digitI
sta $2007
lda digitII
sta $2007
lda digitIII
sta $2007
lda #$20
sta $2007
lda #$00
sta $2007 ; writes 4 spaces
sta $2007
sta $2007
sta $2007
; hi-score digits
lda hidigitI
sta $2007
lda hidigitII
sta $2007
lda hidigitIII
sta $2007
lda #$20
sta $2007
lda #$00
sta $2007 ; writes 6 spaces
sta $2007
sta $2007
sta $2007
sta $2007
sta $2007
; player 2 score digits
lda digitIV
sta $2007
lda digitV
sta $2007
lda digitVI
sta $2007
lda #$20
sta $2007
credit_digits:
lda #$23
sta $2006
lda #$9A
sta $2006
lda credit_digitI
sta $2007
lda credit_digitII
sta $2007
jsr scanline_reset
rts
; +------------------------------------------------------------------+
; | HUD END |
; +------------------------------------------------------------------+
; +------------------------------------------------------------------+
; | CLS - CLEAR SCREEN |
; +------------------------------------------------------------------+
cls:
screen_off:
lda #$00
sta $2000 ; reset the two ppu status-registers
sta $2001 ; -"-
lda #$20 ; start address:
sta $2006 ; beginning under the static hud
lda #$C0
sta $2006
ldx #3 ; number of 256byte chunks to load
ldy #0
lda #$00
nametable_load:
sta $2007
iny ; increment y
bne nametable_load ; branch if zero flag set
; y will be incremented until it overflows
; $FF + 1 = $00, this routine loads 256byte
dex ; decrement x, because 1 chunk was loaded
bne nametable_load ; branch until zero flag set, until x = 0
screen_on:
jsr vblank_ ; wait vor vblank before turning the screen
lda #%00001000 ; on again
sta $2000
lda #%00011110
sta $2001
jsr scanline_reset ; reset the scanline to the top of the screen
jsr credit_decrease ; decrease the credit counter because a game was started
lda #$02 ; set the status to 2, titlescreen animation
sta status ; and this routine will be skipped now
jmp infinite
; +------------------------------------------------------------------+
; | CLS END |
; +------------------------------------------------------------------+
; +------------------------------------------------------------------+
; | GAME ROUTINE |
; +------------------------------------------------------------------+
game:
lda #$01 ; set vblank_timer loopcount to "1"
sta vblank_timer_count ; a call of the vblank_timer-routine
ldy #$00 ; waits "1" vblank before doing stuff
jsr vblank ; wait for vblank, check input, draw hud
lda #$23 ; set VRAM-pointer to $2360
sta $2006
lda #$60
sta $2006
ldx #$00 ; reset x, because it is used as loop-index
lda #$4A ; load the "line"-tile
line_load: ; loads the line of the hud into nametable #1
sta $2007
inx
cpx #$20
bne line_load
jsr scanline_reset
; --------------------------------------------------------------------
; move-direction
lda movement
beq direction_right
jmp direction_left
; --------------------------------------------------------------------
; animation seperation-routine
direction_right:
lda #$00
sta address_counter_max
jsr columns
jsr columns_analysis_right
jsr columns_analysis_left
dec address_counter_max
lda first_run
beq continue
jsr address_counter_max_inc
continue:
lda address_counter_max
cmp address_counter
beq tile_dec_jmp
lda loopcounter
cmp #$00
beq anim1 ; first animation-step
cmp #$01
beq anim2_jmp ; second animation-step
cmp #$02
beq anim3_jmp ; third animation-step
cmp #$03
beq anim4_jmp ; last animation-step
direction_left:
lda #$00
sta address_counter_max
jsr columns
jsr columns_analysis_right
jsr columns_analysis_left
dec address_counter_max
jsr address_counter_max_inc
lda address_counter_max
cmp address_counter
beq tile_dec_jmp
lda loopcounter
cmp #$00
beq anim4_jmp ; first animation-step
cmp #$01
beq anim3_jmp ; second animation-step
cmp #$02
beq anim2_jmp ; third animation-step
cmp #$03
beq anim1 ; last animation-step
jmp infinite
; --------------------------------------------------------------------
tile_dec_jmp:
jmp tile_dec
anim2_jmp:
jmp anim2
anim3_jmp:
jmp anim3
anim4_jmp:
jmp anim4
anim4__jmp:
jmp anim4_
anim1:
ldx #$44
stx alien_one_lo
ldx #$45
stx alien_one_hi
ldx #$60
stx alien_two_lo
ldx #$61
stx alien_two_hi
ldx #$40
stx alien_three_lo
ldx #$41
stx alien_three_hi
jsr line1_load
lda movement
bne anim1_
inc address_counter
inc loopcounter
jmp infinite
anim1_:
lda #$01
sta first_run
lda #$00
sta loopcounter
jmp infinite
; --------------------------------------------------------------------
anim2:
ldx #$70
stx alien_one_lo
ldx #$71
stx alien_one_hi
ldx #$62
stx alien_two_lo
ldx #$63
stx alien_two_hi
ldx #$50
stx alien_three_lo
ldx #$51
stx alien_three_hi
jsr line1_load
inc loopcounter
jmp infinite
; --------------------------------------------------------------------
anim3:
lda movement
bne decrease
anim3_:
ldx #$72
stx alien_one_lo
ldx #$73
stx alien_one_hi
ldx #$64
stx alien_two_lo
ldx #$65
stx alien_two_hi
ldx #$00
stx alien_three_lo
ldx #$52
stx alien_three_hi
jsr line1_load
inc loopcounter
jmp infinite
decrease:
dec lineI_hi
dec lineII_hi
dec lineIII_hi
dec lineIV_hi
dec lineV_hi
jmp anim3_
; --------------------------------------------------------------------
anim4:
lda movement
bne anim4_
inc lineI_hi
inc lineII_hi
inc lineIII_hi
inc lineIV_hi
inc lineV_hi
anim4_:
ldx #$75
stx alien_one_lo
ldx #$76
stx alien_one_hi
ldx #$67
stx alien_two_lo
ldx #$68
stx alien_two_hi
ldx #$53
stx alien_three_lo
ldx #$54
stx alien_three_hi
jsr line1_load
lda movement
bne anim4_end
lda #$00
sta loopcounter
jmp infinite
anim4_end:
inc address_counter
inc loopcounter
jmp infinite
tile_dec:
lineI_dec:
lda #$20
adc lineI_hi
sta lineI_hi
and #$F0
cmp #$00
beq lineI_lo_inc
cmp #$10
beq lineI_lo_inc
lineII_dec:
lda #$20
adc lineII_hi
sta lineII_hi
and #$F0
cmp #$00
beq lineII_lo_inc
cmp #$10
beq lineII_lo_inc
lineIII_dec:
lda #$20
adc lineIII_hi
sta lineIII_hi
and #$F0
cmp #$00
beq lineIII_lo_inc
cmp #$10
beq lineIII_lo_inc
lineIV_dec:
lda #$20
adc lineIV_hi
sta lineIV_hi
and #$F0
cmp #$00
beq lineIV_lo_inc
cmp #$10
beq lineIV_lo_inc
lineV_dec:
lda #$20
adc lineV_hi
sta lineV_hi
and #$F0
cmp #$00
beq lineV_lo_inc
cmp #$10
beq lineV_lo_inc
line_dec_end:
dec lineI_hi
dec lineII_hi
dec lineIII_hi
dec lineIV_hi
dec lineV_hi
lda #$00
sta address_counter
sta loopcounter
lda movement
bne movement_swap
lda #$01
sta movement
jmp infinite
movement_swap:
lda #$00
sta movement
jmp infinite
lineI_lo_inc:
inc lineI_lo
jmp lineII_dec
lineII_lo_inc:
inc lineII_lo
jmp lineIII_dec
lineIII_lo_inc:
inc lineIII_lo
jmp lineIV_dec
lineIV_lo_inc:
inc lineIV_lo
jmp lineV_dec
lineV_lo_inc:
inc lineV_lo
jmp line_dec_end
; +------------------------------------------------------------------+
; | ALIEN DISPLAYING WITH PAUSING |
; | those variables must be defined |
; | when using the "alien_load" routine |
; +------------------------------------------------------------------+
; | lda #$xx xx = low part of the destinated address |
; | sta destination_lo |
; | lda #$xx xx = high part of the destinated address |
; | sta destination_hi |
; | lda #$xx xx = tile index-nr for the first tile |
; | sta tile_one |
; | lda #$xx xx = tile index-nr for the second tile |
; | sta tile_two |
; | jsr alien_load |
; +------------------------------------------------------------------+
line1_load:
lda lineI_lo
sta destination_lo
lda lineI_hi
sta destination_hi
lda alien_one_lo
sta tile_one
lda alien_one_hi
sta tile_two
lda #$74
sta tile_three
lda #$77
sta tile_four
lda #$01
sta empty_status
lda tileA
bne jmp_A
jsr tile_load
jsr A_address
return_A:
lda tileB
bne jmp_B
jsr tile_load
jsr B_address
return_B:
lda tileC
bne jmp_C
jsr tile_load
jsr C_address
return_C:
lda tileD
bne jmp_D
jsr tile_load
jsr D_address
return_D:
lda tileE
bne jmp_E
jsr tile_load
jsr E_address
return_E:
lda tileF
bne jmp_F
jsr tile_load
jsr F_address
return_F:
lda tileG
bne jmp_G
jsr tile_load
jsr G_address
return_G:
lda tileH
bne jmp_H
jsr tile_load
jsr H_address
return_H:
lda tileI
bne jmp_I
jsr tile_load
jsr I_address
return_I:
lda tileJ
bne jmp_J
jsr tile_load
jsr J_address
return_J:
lda tileK
bne jmp_K
jsr tile_load
jsr K_address
return_K:
jsr empty_tile
lda #$01
sta after_status
jmp line2_load
jmp_A:
jsr empty_tile
jmp return_A
jmp_B:
jsr empty_tile
jmp return_B
jmp_C:
jsr empty_tile
jmp return_C
jmp_D:
jsr empty_tile
jmp return_D
jmp_E:
jsr empty_tile
jmp return_E
jmp_F:
jsr empty_tile
jmp return_F
jmp_G:
jsr empty_tile
jmp return_G
jmp_H:
jsr empty_tile
jmp return_H
jmp_I:
jsr empty_tile
jmp return_I
jmp_J:
jsr empty_tile
jmp return_J
jmp_K:
jsr empty_tile
jmp return_K
; --------------------------------------------------------------------
line2_load:
lda lineII_lo
sta destination_lo
lda lineII_hi
sta destination_hi
lda alien_one_lo
sta tile_one
lda alien_one_hi
sta tile_two
lda #$74
sta tile_three
lda #$77
sta tile_four
lda #$01
sta empty_status
lda tileAA
bne jmp_AA
jsr tile_load
jsr AA_address
return_AA:
lda tileAB
bne jmp_AB
jsr tile_load
jsr AB_address
return_AB:
lda tileAC
bne jmp_AC
jsr tile_load
jsr AC_address
return_AC:
lda tileAD
bne jmp_AD
jsr tile_load
jsr AD_address
return_AD:
lda tileAE
bne jmp_AE
jsr tile_load
jsr AE_address
return_AE:
lda tileAF
bne jmp_AF
jsr tile_load
jsr AF_address
return_AF:
lda tileAG
bne jmp_AG
jsr tile_load
jsr AG_address
return_AG:
lda tileAH
bne jmp_AH
jsr tile_load
jsr AH_address
return_AH:
lda tileAI
bne jmp_AI
jsr tile_load
jsr AI_address
return_AI:
lda tileAJ
bne jmp_AJ
jsr tile_load
jsr AJ_address
return_AJ:
lda tileAK
bne jmp_AK
jsr tile_load
jsr AK_address
return_AK:
jsr empty_tile
lda #$01
sta after_status
jmp line3_load
jmp_AA:
jsr empty_tile
jmp return_AA
jmp_AB:
jsr empty_tile
jmp return_AB
jmp_AC:
jsr empty_tile
jmp return_AC
jmp_AD:
jsr empty_tile
jmp return_AD
jmp_AE:
jsr empty_tile
jmp return_AE
jmp_AF:
jsr empty_tile
jmp return_AF
jmp_AG:
jsr empty_tile
jmp return_AG
jmp_AH:
jsr empty_tile
jmp return_AH
jmp_AI:
jsr empty_tile
jmp return_AI
jmp_AJ:
jsr empty_tile
jmp return_AJ
jmp_AK:
jsr empty_tile
jmp return_AK
; --------------------------------------------------------------------
line3_load:
lda lineIII_lo
sta destination_lo
lda lineIII_hi
sta destination_hi
lda alien_two_lo
sta tile_one
lda alien_two_hi
sta tile_two
lda #$66
sta tile_three
lda #$69
sta tile_four
lda #$01
sta empty_status
lda tileBA
bne jmp_BA
jsr tile_load
jsr BA_address
return_BA:
lda tileBB
bne jmp_BB
jsr tile_load
jsr BB_address
return_BB:
lda tileBC
bne jmp_BC
jsr tile_load
jsr BC_address
return_BC:
lda tileBD
bne jmp_BD
jsr tile_load
jsr BD_address
return_BD:
lda tileBE
bne jmp_BE
jsr tile_load
jsr BE_address
return_BE:
lda tileBF
bne jmp_BF
jsr tile_load
jsr BF_address
return_BF:
lda tileBG
bne jmp_BG
jsr tile_load
jsr BG_address
return_BG:
lda tileBH
bne jmp_BH
jsr tile_load
jsr BH_address
return_BH:
lda tileBI
bne jmp_BI
jsr tile_load
jsr BI_address
return_BI:
lda tileBJ
bne jmp_BJ
jsr tile_load
jsr BJ_address
return_BJ:
lda tileBK
bne jmp_BK
jsr tile_load
jsr BK_address
return_BK:
jsr empty_tile
lda #$01
sta after_status
jmp line4_load
jmp_BA:
jsr empty_tile
jmp return_BA
jmp_BB:
jsr empty_tile
jmp return_BB
jmp_BC:
jsr empty_tile
jmp return_BC
jmp_BD:
jsr empty_tile
jmp return_BD
jmp_BE:
jsr empty_tile
jmp return_BE
jmp_BF:
jsr empty_tile
jmp return_BF
jmp_BG:
jsr empty_tile
jmp return_BG
jmp_BH:
jsr empty_tile
jmp return_BH
jmp_BI:
jsr empty_tile
jmp return_BI
jmp_BJ:
jsr empty_tile
jmp return_BJ
jmp_BK:
jsr empty_tile
jmp return_BK
; --------------------------------------------------------------------
line4_load:
lda lineIV_lo
sta destination_lo
lda lineIV_hi
sta destination_hi
lda alien_two_lo
sta tile_one
lda alien_two_hi
sta tile_two
lda #$66
sta tile_three
lda #$69
sta tile_four
lda #$01
sta empty_status
lda tileCA
bne jmp_CA
jsr tile_load
jsr CA_address
return_CA:
lda tileCB
bne jmp_CB
jsr tile_load
jsr CB_address
return_CB:
lda tileCC
bne jmp_CC
jsr tile_load
jsr CC_address
return_CC:
lda tileCD
bne jmp_CD
jsr tile_load
jsr CD_address
return_CD:
lda tileCE
bne jmp_CE
jsr tile_load
jsr CE_address
return_CE:
lda tileCF
bne jmp_CF
jsr tile_load
jsr CF_address
return_CF:
lda tileCG
bne jmp_CG
jsr tile_load
jsr CG_address
return_CG:
lda tileCH
bne jmp_CH
jsr tile_load
jsr CH_address
return_CH:
lda tileCI
bne jmp_CI
jsr tile_load
jsr CI_address
return_CI:
lda tileCJ
bne jmp_CJ
jsr tile_load
jsr CJ_address
return_CJ:
lda tileCK
bne jmp_CK
jsr tile_load
jsr CK_address
return_CK:
jsr empty_tile
lda #$01
sta after_status
jmp line5_load
jmp_CA:
jsr empty_tile
jmp return_CA
jmp_CB:
jsr empty_tile
jmp return_CB
jmp_CC:
jsr empty_tile
jmp return_CC
jmp_CD:
jsr empty_tile
jmp return_CD
jmp_CE:
jsr empty_tile
jmp return_CE
jmp_CF:
jsr empty_tile
jmp return_CF
jmp_CG:
jsr empty_tile
jmp return_CG
jmp_CH:
jsr empty_tile
jmp return_CH
jmp_CI:
jsr empty_tile
jmp return_CI
jmp_CJ:
jsr empty_tile
jmp return_CJ
jmp_CK:
jsr empty_tile
jmp return_CK
; --------------------------------------------------------------------
line5_load:
lda lineV_lo
sta destination_lo
lda lineV_hi
sta destination_hi
lda alien_three_lo
sta tile_one
lda alien_three_hi
sta tile_two
lda #$00
sta tile_three
lda #$00
sta tile_four
lda #$01
sta empty_status
lda tileDA
bne jmp_DA
jsr tile_load
jsr DA_address
return_DA:
lda tileDB
bne jmp_DB
jsr tile_load
jsr DB_address
return_DB:
lda tileDC
bne jmp_DC
jsr tile_load
jsr DC_address
return_DC:
lda tileDD
bne jmp_DD
jsr tile_load
jsr DD_address
return_DD:
lda tileDE
bne jmp_DE
jsr tile_load
jsr DE_address
return_DE:
lda tileDF
bne jmp_DF
jsr tile_load
jsr DF_address
return_DF:
lda tileDG
bne jmp_DG
jsr tile_load
jsr DG_address
return_DG:
lda tileDH
bne jmp_DH
jsr tile_load
jsr DH_address
return_DH:
lda tileDI
bne jmp_DI
jsr tile_load
jsr DI_address
return_DI:
lda tileDJ
bne jmp_DJ
jsr tile_load
jsr DJ_address
return_DJ:
lda tileDK
bne jmp_DK
jsr tile_load
jsr DK_address
return_DK:
jsr empty_tile
lda #$01
sta after_status
rts
jmp_DA:
jsr empty_tile
jmp return_DA
jmp_DB:
jsr empty_tile
jmp return_DB
jmp_DC:
jsr empty_tile
jmp return_DC
jmp_DD:
jsr empty_tile
jmp return_DD
jmp_DE:
jsr empty_tile
jmp return_DE
jmp_DF:
jsr empty_tile
jmp return_DF
jmp_DG:
jsr empty_tile
jmp return_DG
jmp_DH:
jsr empty_tile
jmp return_DH
jmp_DI:
jsr empty_tile
jmp return_DI
jmp_DJ:
jsr empty_tile
jmp return_DJ
jmp_DK:
jsr empty_tile
jmp return_DK
; --------------------------------------------------------------------
empty_tile:
jsr vblank_timer
jsr empty_tile_loading
lda destination_lo
sta $2006
lda destination_hi
sta $2006
lda tile_status
beq empty_tile_load
lda movement
bne special_tile_right
lda loopcounter
cmp #$02
beq special_tile
jmp empty_tile_load
special_tile_right:
lda loopcounter
cmp #$01
beq special_tile
empty_tile_load:
lda #$00
sta $2007
sta $2007
return_special_tile:
jsr scanline_reset
inc destination_hi
inc destination_hi
lda #$01
sta empty_status
rts
special_tile:
lda tile_four
sta $2007
lda #$00
sta $2007
sta tile_status
jmp return_special_tile
; --------------------------------------------------------------------
tile_load:
jsr vblank_timer
jsr empty_tile_loading
lda movement
beq loading_right
loading_left:
lda loopcounter
cmp #$01
beq load_choose
cmp #$02
beq first_load
jmp normal_load
loading_right:
lda loopcounter
cmp #$02
beq load_choose
cmp #$03
beq first_load
jmp normal_load
normal_load:
lda destination_lo ; define start-address here
sta $2006
lda destination_hi
sta $2006
lda tile_one
sta $2007
lda tile_two
sta $2007
lda #$01
sta tile_status
jsr scanline_reset
inc destination_hi
inc destination_hi
jsr alien_hitbox
rts
special_load:
dec destination_hi
lda destination_lo ; define start-address here
sta $2006
lda destination_hi
sta $2006
lda #$00
sta $2007
lda tile_three
sta $2007
lda tile_two
sta $2007
jsr scanline_reset
inc destination_hi
inc destination_hi
inc destination_hi
lda #$00
sta empty_status
lda #$01
sta tile_status
sta after_status
rts
load_choose:
lda empty_status
bne special_load
jmp normal_load
first_load:
lda after_status
cmp #$01
bne normal_load
dec destination_hi
lda destination_lo ; define start-address here
sta $2006
lda destination_hi
sta $2006
lda #$00
sta $2007
lda tile_one
sta $2007
lda tile_two
sta $2007
jsr scanline_reset
inc destination_hi
inc destination_hi
inc destination_hi
lda #$00
sta after_status
lda #$01
sta tile_status
rts
empty_tile_loading:
lda destination_lo
sta empty_lo
lda destination_hi
sta empty_hi
jsr address_decrease
lda empty_lo
sta $2006
lda empty_hi
sta $2006
lda #$00
sta $2007
sta $2007
jsr scanline_reset
rts
address_decrease:
lda empty_hi
sbc #$20
sta empty_hi
and #$F0
cmp #$E0
beq address_lo_dec
cmp #$F0
beq address_lo_dec
rts
address_lo_dec:
dec empty_lo
rts
; --------------------------------------------------------------------
columns:
columnA:
lda tileA
beq columnB
lda tileAA
beq columnB
lda tileBA
beq columnB
lda tileCA
beq columnB
lda tileDA
beq columnB
lda #$01
sta columnA_status
columnB:
lda tileB
beq columnC
lda tileAB
beq columnC
lda tileBB
beq columnC
lda tileCB
beq columnC
lda tileDB
beq columnC
lda #$01
sta columnB_status
columnC:
lda tileC
beq columnD
lda tileAC
beq columnD
lda tileBC
beq columnD
lda tileCC
beq columnD
lda tileDC
beq columnD
lda #$01
sta columnC_status
columnD:
lda tileD
beq columnE
lda tileAD
beq columnE
lda tileBD
beq columnE
lda tileCD
beq columnE
lda tileDD
beq columnE
lda #$01
sta columnD_status
columnE:
lda tileE
beq columnF
lda tileAE
beq columnF
lda tileBE
beq columnF
lda tileCE
beq columnF
lda tileDE
beq columnF
lda #$01
sta columnE_status
columnF:
lda tileF
beq columnG
lda tileAF
beq columnG
lda tileBF
beq columnG
lda tileCF
beq columnG
lda tileDF
beq columnG
lda #$01
sta columnF_status
columnG:
lda tileG
beq columnH
lda tileAG
beq columnH
lda tileBG
beq columnH
lda tileCG
beq columnH
lda tileDG
beq columnH
lda #$01
sta columnG_status
columnH:
lda tileH
beq columnI
lda tileAH
beq columnI
lda tileBH
beq columnI
lda tileCH
beq columnI
lda tileDH
beq columnI
lda #$01
sta columnH_status
columnI:
lda tileI
beq columnJ
lda tileAI
beq columnJ
lda tileBI
beq columnJ
lda tileCI
beq columnJ
lda tileDI
beq columnJ
lda #$01
sta columnI_status
columnJ:
lda tileJ
beq columnK
lda tileAJ
beq columnK
lda tileBJ
beq columnK
lda tileCJ
beq columnK
lda tileDJ
beq columnK
lda #$01
sta columnJ_status
columnK:
lda tileK
beq column_return
lda tileAK
beq column_return
lda tileBK
beq column_return
lda tileCK
beq column_return
lda tileDK
beq column_return
lda #$01
sta column_return
column_return:
rts
columns_analysis_right:
lda columnK_status
beq all_columns
jsr address_counter_max_inc
lda columnJ_status
beq columns_end
jsr address_counter_max_inc
lda columnI_status
beq columns_end
jsr address_counter_max_inc
lda columnH_status
beq columns_end
jsr address_counter_max_inc
lda columnG_status
beq columns_end
jsr address_counter_max_inc
lda columnF_status
beq columns_end
jsr address_counter_max_inc
lda columnE_status
beq columns_end
jsr address_counter_max_inc
lda columnD_status
beq columns_end
jsr address_counter_max_inc
lda columnC_status
beq columns_end
jsr address_counter_max_inc
lda columnB_status
beq columns_end
jsr address_counter_max_inc
lda columnA_status
beq columns_end
jsr address_counter_max_inc
columns_end:
rts
all_columns:
jsr address_counter_max_inc
jmp columns_end
address_counter_max_inc:
inc address_counter_max
inc address_counter_max
rts
columns_analysis_left:
lda columnA_status
beq all_columns
jsr address_counter_max_inc
lda columnB_status
beq columns_end
jsr address_counter_max_inc
lda columnC_status
beq columns_end
jsr address_counter_max_inc
lda columnD_status
beq columns_end
jsr address_counter_max_inc
lda columnE_status
beq columns_end
jsr address_counter_max_inc
lda columnF_status
beq columns_end
jsr address_counter_max_inc
lda columnG_status
beq columns_end
jsr address_counter_max_inc
lda columnH_status
beq columns_end
jsr address_counter_max_inc
lda columnI_status
beq columns_end
jsr address_counter_max_inc
lda columnJ_status
beq columns_end
jsr address_counter_max_inc
lda columnK_status
beq columns_end
jsr address_counter_max_inc
jmp columns_end
; +------------------------------------------------------------------+
; | GAME ROUTINE - END |
; +------------------------------------------------------------------+
; +------------------------------------------------------------------+
; | JOYSTICK INPUT |
; +------------------------------------------------------------------+
input:
input_init:
lda #$01 ; strobe the joypad before read
sta $4016
lda #$00
sta $4016
input_read:
lda $4016 ; a-button
and #1
bne a_button
return_a:
lda $4016 ; b-button
and #1
bne b_button
return_b:
lda $4016 ; select-button
and #1
bne select_button
lda #$00
sta select_status
return_select:
lda $4016 ; start-button
and #1
bne start_button
return_start:
lda $4016 ; d-pad up
and #1
bne up_button
return_up:
lda $4016 ; d-pad down
and #1
bne down_button
return_down:
lda $4016 ; d-pad left
and #1
bne left_button
return_left:
lda $4016 ; d-pad right
and #1
bne right_button
return_right:
rts
; --------------------------------------------------------------------
a_button:
lda a_status
bne return_a
lda ship_x
adc #8
sta missile_x
lda #$01
sta a_status
jmp return_a
b_button:
jmp return_b
select_button:
lda select_status
cmp #$00
bne return_select
jsr credit_increase
lda #$01
sta select_status
jmp return_select
start_button:
lda status
cmp #$02
bcs return_start
jsr cls
jmp return_start
up_button:
jmp return_up
down_button:
jmp return_down
left_button:
lda ship_x
cmp #16
beq return_left
dec ship_x ; decrease x-position of the player ship
jmp return_left
right_button:
lda ship_x
cmp #224
beq return_right
inc ship_x ; increase x-position of the player ship
jmp return_right
; +------------------------------------------------------------------+
; | JOYSTICK INPUT END |
; +------------------------------------------------------------------+
; nametable_loop_init:
; lda #low(nametable) ; load low address of nametable-file
; sta addressLO ; store it in variable "addressLO"
; lda #high(nametable) ; load high address of nametable-file
; sta addressHI ; store it in variable "addressHI"
; ldx #4 ; number of 256byte chunks to load
; 4 x 256byte = 1kB
; no need to set y, it was reset above
; nametable_load:
; lda [addressLO], y ; load a with the index of "addressLO" and y
; sta $2007
; iny ; increment y
; bne nametable_load ; branch if zero flag set
; y will be incremented until it overflows
; $FF + 1 = $00, this routine loads 256byte
; inc addressHI ; increment the high address so the next 256byte can be loaded
; dex ; decrement x, because 1 chunk was loaded
; bne nametable_load ; branch until zero flag set, until x = 0
vblank:
lda $2002 ; waits for vertical blank
bpl vblank
jsr input
jsr hud_dynamic
lda status
cmp #$02
bne vblank_end
jsr sprite
vblank_end:
rts
vblank_:
lda $2002 ; waits for vertical blank
bpl vblank_
rts
scanline_reset:
lda #$00 ; set the scanline at the top of the screen
sta $2006 ; position $2000
sta $2006
rts
; --------------------------------------------------------------------
timed_writing:
jsr vblank_timer
lda destination_lo
sta $2006
lda destination_hi
sta $2006
lda [address_lo], y
sta $2007
jsr scanline_reset
lda destination_hi
cmp #$FF
beq overflow
overflow_return:
inc destination_hi
iny
cpy writing_cycles
bne timed_writing
rts
overflow:
inc destination_lo
jmp overflow_return
; +------------------------------------------------------------------+
; | SPRITE LOADING |
; +------------------------------------------------------------------+
sprite:
sprite_init:
lda #$00
sta $2003
sta $2003 ; set load-destination to $0000, begin of sprite-ram
sprite_write:
lda #207
sta $2004 ; y-position
lda #$00
sta $2004 ; tile-nr
lda #$00
sta $2004 ; special byte
lda ship_x
sta $2004 ; x-position
lda #207
sta $2004
lda #$01
sta $2004
lda #$00
sta $2004
lda ship_x
adc #$07
sta $2004
; player missile sprite
jsr missile_hitbox
; jsr draw_missile_hitbox
jsr hud_collision
lda missile_y
sta $2004
lda #$02
sta $2004
lda #$00
sta $2004
lda missile_x
sta $2004
lda a_status ; check if "a" button was pressed
beq sprite_end
dec missile_y
dec missile_y
sprite_end:
rts
; +------------------------------------------------------------------+
; | TIMER ROUTINES |
; +------------------------------------------------------------------+
; the first uses the CPU-clock
; the second uses the vblank
timer: ; 1 call waits for 0.1 second
timer_init:
ldx #$00
ldy #$00
timer_loop: ; jsr , wastes 6 cycles
nop ; no operation, wastes 1 cycle
nop
nop
nop
nop ; 5 cycles
inx ; 2 cycles
bne timer_loop ; 2 cycles (+1 if branch succeeds)
iny ; 2 cycles
cpy #$30 ; 2 cycles
bne timer_loop ; 2 cycles (+1 if branch succeeds)
rts ; 6 cycles
timer_long: ; 1 call waits for 1 second
timer_long_init:
lda #00
sta timer_counter
timer_long_loop:
jsr timer
inc timer_counter
lda timer_counter
cmp #$0A
bne timer_long_loop
rts
vblank_timer:
vblank_timer_init:
ldx #$00
vblank_timer_loop:
jsr vblank ; wait for vblank
inx
cpx vblank_timer_count ; has to be defined!
bne vblank_timer_loop ; NTSC = 60Hz, PAL = 50Hz
; NTSC = 0,1 sec, PAL = 0,12 sec
rts
vblank_timer_:
vblank_timer_init_:
ldx #$00
vblank_timer_loop_: ; 1 call waits for 0.1 second
jsr vblank_ ; wait for vblank
inx
cpx vblank_timer_count ; has to be defined!
bne vblank_timer_loop_ ; NTSC = 60Hz, PAL = 50Hz
; NTSC = 0,1 sec, PAL = 0,12 sec
rts
; +------------------------------------------------------------------+
; | CREDIT COUNTER |
; +------------------------------------------------------------------+
credit_increase:
second_digit_inc:
inc credit_digitII
lda credit_digitII
cmp #$2A
beq first_digit_inc
inc_return:
rts
first_digit_inc:
lda #$20
sta credit_digitII
inc credit_digitI
jmp inc_return
credit_decrease:
second_digit_dec:
dec credit_digitII
lda credit_digitII
cmp #$1F
beq first_digit_dec
dec_return:
rts
first_digit_dec:
lda #$29
sta credit_digitII
dec credit_digitI
jmp dec_return
; +------------------------------------------------------------------+
; | COLLISION DETECTION |
; +------------------------------------------------------------------+
missile_hitbox:
lda missile_x
sta missile_left
ldy missile_x
iny ; width of 1
sty missile_right
lda missile_y
adc #$04 ; 4 empty pixels
sta missile_top
rts
alien_hitbox:
hitboxA:
lda tileA
bne hitboxAA
lda lineI_lo
sta line_lo
lda lineI_hi
sta line_hi
lda A_hi
sta tile_hi
jsr address_calc
; jsr draw_alien_hitbox
jsr collision_detection
lda collision_status
beq hitboxAA
lda #$01
sta tileA
jsr collision_detected
jmp alien_hitbox_end
hitboxAA:
lda tileAA
bne hitboxBA
lda lineI_lo
sta line_lo
lda lineI_hi
sta line_hi
lda AA_hi
sta tile_hi
jsr address_calc
; jsr draw_alien_hitbox
jsr collision_detection
lda collision_status
beq hitboxBA
lda #$01
sta tileAA
jsr collision_detected
jmp alien_hitbox_end
hitboxBA:
lda tileBA
bne hitboxCA
lda lineI_lo
sta line_lo
lda lineI_hi
sta line_hi
lda BA_hi
sta tile_hi
jsr address_calc
; jsr draw_alien_hitbox
jsr collision_detection
lda collision_status
beq hitboxCA
lda #$01
sta tileBA
jsr collision_detected
jmp alien_hitbox_end
hitboxCA:
lda tileCA
bne hitboxDA
lda lineI_lo
sta line_lo
lda lineI_hi
sta line_hi
lda CA_hi
sta tile_hi
jsr address_calc
; jsr draw_alien_hitbox
jsr collision_detection
lda collision_status
beq hitboxDA
lda #$01
sta tileCA
jsr collision_detected
jmp alien_hitbox_end
hitboxDA:
lda tileDA
bne hitboxB
lda lineI_lo
sta line_lo
lda lineI_hi
sta line_hi
lda DA_hi
sta tile_hi
jsr address_calc
; jsr draw_alien_hitbox
jsr collision_detection
lda collision_status
beq hitboxB
lda #$01
sta tileDA
jsr collision_detected
jmp alien_hitbox_end
; --------------------------------------------------------------------
hitboxB:
lda tileB
bne hitboxC
lda B_hi
sta tile_hi
jsr address_calc
; jsr draw_alien_hitbox
jsr collision_detection
lda collision_status
beq hitboxC
lda #$01
sta tileB
jsr collision_detected
jmp alien_hitbox_end
hitboxC:
lda tileC
bne hitboxD
lda C_hi
sta tile_hi
jsr address_calc
; jsr draw_alien_hitbox
jsr collision_detection
lda collision_status
beq hitboxD
lda #$01
sta tileC
jsr collision_detected
jmp alien_hitbox_end
hitboxD:
lda tileD
bne hitboxE
lda D_hi
sta tile_hi
jsr address_calc
; jsr draw_alien_hitbox
jsr collision_detection
lda collision_status
beq hitboxE
lda #$01
sta tileD
jsr collision_detected
jmp alien_hitbox_end
hitboxE:
lda tileE
bne hitboxF
lda E_hi
sta tile_hi
jsr address_calc
; jsr draw_alien_hitbox
jsr collision_detection
lda collision_status
beq hitboxF
lda #$01
sta tileE
jsr collision_detected
jmp alien_hitbox_end
hitboxF:
lda tileF
bne hitboxG
lda F_hi
sta tile_hi
jsr address_calc
; jsr draw_alien_hitbox
jsr collision_detection
lda collision_status
beq hitboxG
lda #$01
sta tileF
jsr collision_detected
jmp alien_hitbox_end
hitboxG:
lda tileG
bne hitboxH
lda G_hi
sta tile_hi
jsr address_calc
; jsr draw_alien_hitbox
jsr collision_detection
lda collision_status
beq hitboxH
lda #$01
sta tileG
jsr collision_detected
jmp alien_hitbox_end
hitboxH:
lda tileH
bne hitboxI
lda H_hi
sta tile_hi
jsr address_calc
; jsr draw_alien_hitbox
jsr collision_detection
lda collision_status
beq hitboxI
lda #$01
sta tileH
jsr collision_detected
jmp alien_hitbox_end
hitboxI:
lda tileI
bne hitboxJ
lda I_hi
sta tile_hi
jsr address_calc
; jsr draw_alien_hitbox
jsr collision_detection
lda collision_status
beq hitboxJ
lda #$01
sta tileI
jsr collision_detected
jmp alien_hitbox_end
hitboxJ:
lda tileJ
bne hitboxK
lda J_hi
sta tile_hi
jsr address_calc
; jsr draw_alien_hitbox
jsr collision_detection
lda collision_status
beq hitboxK
lda #$01
sta tileJ
jsr collision_detected
jmp alien_hitbox_end
hitboxK:
lda tileK
bne alien_hitbox_end
lda K_hi
sta tile_hi
jsr address_calc
; jsr draw_alien_hitbox
jsr collision_detection
lda collision_status
beq alien_hitbox_end
lda #$01
sta tileK
jsr collision_detected
jmp alien_hitbox_end
alien_hitbox_end:
rts
; ----------------------------------------------------
address_calc:
; calculate the left side of the alien-hitbox
lda tile_hi ; load hi part of the tile address
; clc
; sbc line_hi ; substract the hi part of the line-index
tay ; use the result as loop-index
dey
dey
lda #$00
back:
clc
adc #$08
dey
bne back
sta alien_left ; pixel-address of the left side of the alien-hitbox
lda line_lo ; load lo-address of the line-index
and #$0F ; clear the first nibble of the accumulator
tay ; transfer accumulator to x, used as loop-index
beq overjmp
lda #$00
; calculate the bottom side of the alien-hitbox
back_:
clc
adc #64 ; add 64px to alien_bottom/ 8 rows via 8px
dey
bne back_ ; jump to back_ until line-index is "0"
sbc #8
sta alien_bottom
overjmp:
lda line_hi
lsr a ; do 5 right-shifts
lsr a
lsr a
lsr a
lsr a
tay
iny ; get the line-nr. as a decimal digit
lda alien_bottom
back__:
adc #$08
dey
bne back__
sta alien_bottom
; calculate the right side of the alien-hitbox
lda alien_left
adc #$10
sta alien_right
rts
; ----------------------------------------------------
collision_detection:
; sec
lda missile_top
cmp alien_bottom
bcs collision_end
lda missile_right
cmp alien_left
bcc collision_end
lda missile_left
cmp alien_right
bcs collision_end
lda #$01
sta collision_status
rts
collision_end:
lda #$00
sta collision_status
rts
; ----------------------------------------------------
collision_detected:
jsr vblank_
lda line_lo
sta $2006
dec tile_hi
dec tile_hi
lda tile_hi
sta $2006
lda #$00
sta $2007
sta $2007
jsr scanline_reset
lda #$00
sta a_status
lda #216
sta missile_y
rts
; --------------------------------------------------------------------
hud_collision:
lda missile_top
cmp #20
bcs hud_collision_end
lda #$00
sta a_status
lda #216
sta missile_y
hud_collision_end:
rts
; --------------------------------------------------------------------
draw_missile_hitbox:
lda missile_top
sta $2004
lda #$10
sta $2004
lda #0
sta $2004
lda missile_left
sta $2004
rts
draw_alien_hitbox:
lda alien_bottom
; sbc #$08
sta $2004
lda #$10
sta $2004
lda #0
sta $2004
lda alien_left
sta $2004
rts
; --------------------------------------------------------------------
A_address:
lda destination_hi
sta A_hi
rts
B_address:
lda destination_hi
sta B_hi
rts
C_address:
lda destination_hi
sta C_hi
rts
D_address:
lda destination_hi
sta D_hi
rts
E_address:
lda destination_hi
sta E_hi
rts
F_address:
lda destination_hi
sta F_hi
rts
G_address:
lda destination_hi
sta G_hi
rts
H_address:
lda destination_hi
sta H_hi
rts
I_address:
lda destination_hi
sta I_hi
rts
J_address:
lda destination_hi
sta J_hi
rts
K_address:
lda destination_hi
sta K_hi
rts
AA_address:
lda destination_hi
sta AA_hi
rts
AB_address:
lda destination_hi
sta AB_hi
rts
AC_address:
lda destination_hi
sta AC_hi
rts
AD_address:
lda destination_hi
sta AD_hi
rts
AE_address:
lda destination_hi
sta AE_hi
rts
AF_address:
lda destination_hi
sta AF_hi
rts
AG_address:
lda destination_hi
sta AG_hi
rts
AH_address:
lda destination_hi
sta AH_hi
rts
AI_address:
lda destination_hi
sta AI_hi
rts
AJ_address:
lda destination_hi
sta AJ_hi
rts
AK_address:
lda destination_hi
sta AK_hi
rts
BA_address:
lda destination_hi
sta BA_hi
rts
BB_address:
lda destination_hi
sta BB_hi
rts
BC_address:
lda destination_hi
sta BC_hi
rts
BD_address:
lda destination_hi
sta BD_hi
rts
BE_address:
lda destination_hi
sta BE_hi
rts
BF_address:
lda destination_hi
sta BF_hi
rts
BG_address:
lda destination_hi
sta BG_hi
rts
BH_address:
lda destination_hi
sta BH_hi
rts
BI_address:
lda destination_hi
sta BI_hi
rts
BJ_address:
lda destination_hi
sta BJ_hi
rts
BK_address:
lda destination_hi
sta BK_hi
rts
CA_address:
lda destination_hi
sta CA_hi
rts
CB_address:
lda destination_hi
sta CB_hi
rts
CC_address:
lda destination_hi
sta CC_hi
rts
CD_address:
lda destination_hi
sta CD_hi
rts
CE_address:
lda destination_hi
sta CE_hi
rts
CF_address:
lda destination_hi
sta CF_hi
rts
CG_address:
lda destination_hi
sta CG_hi
rts
CH_address:
lda destination_hi
sta CH_hi
rts
CI_address:
lda destination_hi
sta CI_hi
rts
CJ_address:
lda destination_hi
sta CJ_hi
rts
CK_address:
lda destination_hi
sta CK_hi
rts
DA_address:
lda destination_hi
sta DA_hi
rts
DB_address:
lda destination_hi
sta DB_hi
rts
DC_address:
lda destination_hi
sta DC_hi
rts
DD_address:
lda destination_hi
sta DD_hi
rts
DE_address:
lda destination_hi
sta DE_hi
rts
DF_address:
lda destination_hi
sta DF_hi
rts
DG_address:
lda destination_hi
sta DG_hi
rts
DH_address:
lda destination_hi
sta DH_hi
rts
DI_address:
lda destination_hi
sta DI_hi
rts
DJ_address:
lda destination_hi
sta DJ_hi
rts
DK_address:
lda destination_hi
sta DK_hi
rts
; --------------------------------------------------------------------
palette_data: .incbin "data\palette.pal"
nametable: .incbin "data\nametable.map"
; located at $2040
score_line: .db $00, $00, $00, $13, $03, $0F, $12, $05, $34, $21, $35, $00, $08, $09, $33, $13 ; SCORE<1> HI-S
.db $03, $0F, $12, $05, $00, $13, $03, $0F, $12, $05, $34, $22, $35, $00, $00, $00 ; CORE SCORE<2>
; located at $2394
credit: .db $03, $12, $05, $04, $09, $14 ; CREDIT
; located at $214E
play: .db $10, $0C, $01, $19 ; PLAY
; located at $21A9
space_invaders: .db $13, $10, $01, $03, $05, $00, $00, $09, $0E, $16, $01, $04, $05, $12, $13 ; SPACE INVADERS
; located at $2206
score_advance: .db $32, $13, $03, $0F, $12, $05, $00, $01, $04, $16, $01, $0E, $03, $05, $00, $14 ; *SCORE ADVANCE T
.db $01, $02, $0C, $05, $32 ; ABLE*
; located at $224D
score: .db $30, $00, $0D, $19, $13, $14, $05, $12, $19 ; ? MYSTERY
; located at $228C
score1: .db $31, $23, $20, $00, $10, $0F, $09, $0E, $14, $13 ; =30 POINTS
; located at $22CC
score2: .db $31, $22, $20, $00, $10, $0F, $09, $0E, $14, $13 ; =20 POINTS
; located at $230C
score3: .db $31, $21, $20, $00, $10, $0F, $09, $0E, $14, $13 ; =10 POINTS
.bank 2
.org $0000
.incbin "data\background.chr" ; 4kB of background sprites
.incbin "data\sprite.chr" ; 4kB of sprite-data
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment