********************************************************************************
* Epoch, by Larry Miller *
* Copyright 1981 Sirius Software *
* *
* Code is from the common 35840-byte single-file cracked version. *
* *
* ** THIS IS A WORK IN PROGRESS ** *
* (some of the math is not yet explained) *
* *
********************************************************************************
* Disassembly by Andy McFadden, using 6502bench SourceGen v1.7.2. *
* Last updated 2020/09/24 *
********************************************************************************
* Some notes on terminology and conventions: *
* *
* The game creates a collection of objects, representing enemy ships, *
* projectiles, stars, and so on. Each object is a collection of elements, *
* which may be points, horizontal lines, vertical lines, or filled rectangles. *
* Elements are always parallel to the screen. *
* *
* When an enemy ship or base is destroyed, a "flare" object and several *
* "chunk" objects are created. The flare expires after a few frames, the *
* chunks expand outward from the explosion. *
* *
* Most games define objects in "world" space, and then use a model-view *
* transform to get "eye" (or "camera") coordinates. Epoch maintains *
* everything in eye space. The camera has a 45-degree FOV, and treats the *
* view area as square (which makes things stretch when projected). Objects *
* that move entirely outside the view frustum are deleted. *
********************************************************************************
INSTR_JSR_ABS .eq $20 {const} ;opcode for JSR abs
INSTR_RTS .eq $60 {const} ;opcode for RTS
INSTR_TXA .eq $8a {const} ;opcode for TXA
INSTR_STA_DPIIY .eq $91 {const} ;opcode for STA (dp),Y
INSTR_STA_ABS .eq $99 {const} ;opcode for STA abs
INSTR_LDA_ABS .eq $ad {const} ;opcode for LDA abs
ptr_10 .eq $10 {addr/2} ;low byte always 0; multiple uses
math_tab_ptr12 .eq $12 {addr/2} ;low byte always 0
math_tab_ptr14 .eq $14 {addr/2} ;low byte always 0
boot_slot .eq $2b ;boot slot * 16, usually $60
cur_obj_index .eq $62 ;index of object we're working on
cur_elem_index .eq $64 ;index of element we're working on
avail_obj_index .eq $66 ;index of next-available object slot
avail_elem_index .eq $68 ;index of next-available element slot
head_obj_index .eq $6a ;index of first object in list
head_enemy_obj_index .eq $6c ;index of first enemy object in list
free_obj_count .eq $6d ;count of free entries in object list
free_elem_count .eq $6e ;count of free entries in element list
mod_elem_type .eq $70 ;$00=pt, $01=hl, $80=vl, $81=rct
no_draw_obj_flag .eq $72 ;bool 00/nz: don't draw cur object
prev_obj_index .eq $74 ;index from previous loop iteration
clamped_lr_count .eq $76 ;inc if left/right edge clamped
clamped_tb_count .eq $78 ;inc if top/bottom edge clamped
elem_bad_z_flag? .eq $7a
no_draw_elem_flag? .eq $7c
tmp_8a .eq $8a ;various uses
move_tmp .eq $8e {addr/2}
orig_elem_type .eq $91 ;$00=pt, $01=hlin, $80=rct, $ff=vlin
portal_delta_xc .eq $94 {addr/2} ;94/95 paired with 96/97
adj_fwd_speed .eq $98 {addr/2} ;adjusted speed: $6da4 with fractional adj
joy_yaw_angle .eq $9a {addr/2} ;magnitude of movement in X axis (0-$7ff)
joy_yaw_sign .eq $9c ;sign of movement in X axis (L=0 R=ff)
joy_pitch_angle .eq $9d {addr/2} ;magnitude of movement in Y axis (0-$7ff)
joy_pitch_sign .eq $9f ;sign of movement in Y axis (U=0 D=ff)
impact_flash_ctr .eq $a0 ;counts number of times to flash after impact
drawn_elem_count .eq $a1 ;counts the number of elements drawn in current obj
linked_obj_index .eq $a2 ;used when creating linked objects (ship explosions)
shape_cl_index .eq $a3 ;shape class index (0-10)
wronly_a4? .eq $a4 ;written, never read
wronly_a5? .eq $a5 ;written/incremented, never read
test_obj_index .eq $a8 ;index of object being tested for collision
wronly_a9? .eq $a9 ;written, never read
orig_opcode .eq $af ;opcode to restore after render op
mid_col_count .eq $b0 ;for rect, (right - left - 3) (write-only)
engine_sound_ctr? .eq $b1 {addr/3} ;appears involved in engine sounds
wronly_b4? .eq $b4 ;written, never read
end_game_cause .eq $b5 ;0=time, 4=fuel, 8=amun (string index)
score_rating_index .eq $b6 ;rating (0-4) x16
update_mvmt_flag .eq $bb ;affects ship movement updates
zcoord_factor .eq $bc
zcoord_clz .eq $bd ;count of leading zeroes in Z coord
prev_scale_tab_ptr11 .eq $be ;previous value of high byte of ptr
initial_xpos .eq $bf {addr/2} ;initial object XC (signed, neg=left)
initial_ypos .eq $c1 {addr/2} ;initial object YC (signed, neg=up)
prev_zpos .eq $c5 {addr/2} ;holds previous Z value; minor optimization
sound_counters .eq $c8 {addr/5} ;counters used for managing sfx
engine_sound_enable .eq $cc ;appears to enable unused engine sound
portal_next_xc .eq $ce {addr/2} ;X coord of next portal boundary obj
portal_next_yc .eq $d0 {addr/2} ;Y coord of next portal boundary obj
bit_mask_left9 .eq $d5 {addr/9} ;00/80/c0..ff, used with clz
bit_mask_right9 .eq $de {addr/9} ;ff/7f/3f..00
bit_mask_right8 .eq $e7 {addr/8} ;01/03/07..ff
bit_mask_left8 .eq $ef {addr/8} ;fe/fc/f8..00
elem_collision_flag .eq $f8 ;bool 00/nz: did we cross enemy element Z plane?
impact_sound_flag .eq $fa ;bool 00/01: play impact sound
HIRES_P1 .eq $2000 {addr/8192} ;hi-res graphics page 1
DATA_AREA .eq $4000 ;start of shape and music data
obj_spdlim_z_lo .eq $9d20 {addr/40} ;Z speed limit, low (hdr +$11)
obj_spdlim_z_hi .eq $9d48 {addr/40} ;Z speed limit, high (hdr +$12)
obj_spdlim_x_lo .eq $9d70 {addr/40} ;X speed limit, low (hdr +$13)
obj_spdlim_x_hi .eq $9d98 {addr/40} ;X speed limit, high (hdr +$14)
obj_spdlim_y_lo .eq $9dc0 {addr/40} ;Y speed limit, low (hdr +$15)
obj_spdlim_y_hi .eq $9de8 {addr/40} ;Y speed limit, high (hdr +$16)
obj_move_zc_lo .eq $9e10 {addr/40} ;object movement vector, Z low
obj_move_zc_hi .eq $9e38 {addr/40} ;object movement vector, Z high
obj_move_xc_lo .eq $9e60 {addr/40} ;object movement vector, X low
obj_move_xc_hi .eq $9e88 {addr/40} ;object movement vector, X high
obj_move_yc_lo .eq $9eb0 {addr/40} ;object movement vector, Y low
obj_move_yc_hi .eq $9ed8 {addr/40} ;object movement vector, Y high
KBD .eq $c000 ;R last key pressed + 128
KBDSTRB .eq $c010 ;RW keyboard strobe
SPKR .eq $c030 ;RW toggle speaker
TXTCLR .eq $c050 ;RW display graphics
MIXCLR .eq $c052 ;RW display full screen
TXTPAGE1 .eq $c054 ;RW display page 1
TXTPAGE2 .eq $c055 ;RW display page 2 (or read/write aux mem)
LORES .eq $c056 ;RW display lo-res graphics
HIRES .eq $c057 ;RW display hi-res graphics
BUTN0 .eq $c061 ;R switch input 0 / open-apple
BUTN1 .eq $c062 ;R switch input 1 / closed-apple
PADDL0 .eq $c064 ;R analog input 0
PADDL1 .eq $c065 ;R analog input 1
PTRIG .eq $c070 ;RW analog input reset
LCBANK2_RW .eq $c080 ;RW read RAM bank 2, write off
ROMIN .eq $c081 ;RWx2 read ROM, write RAM bank 2
MON_HOME .eq $fc58 ;clear screen and reset text output to top-left
MON_WAIT .eq $fca8 ;delay for (26 + 27*Acc + 5*(Acc*Acc))/2 cycles
MON_6502_RESET .eq $fffc {addr/2} ;6502 reset vector
.org $0800
********************************************************************************
* Program entry point. *
********************************************************************************
0800: 20 58 fc Entry jsr MON_HOME ;clear the screen
0803: a0 00 ldy #$00
0805: b9 13 08 :Loop lda :spaces,y
0808: 99 84 06 sta $0684,y ;clear this part even harder
080b: c8 iny
080c: c0 20 cpy #$20 ;copies opcode byte ($a0) from $832
080e: d0 f5 bne :Loop
0810: 4c c0 08 jmp Init1
0813: a0 a0 a0 a0+ :spaces .str “ ”
;
; Program initialization continued: memory relocation.
;
0832: a0 00 Init2 ldy #$00 ;relocate $0900-0cff to $0000-03ff
0834: b9 00 09 :_Load1 lda $0900,y
0837: 99 00 00 :_Store1 sta $0000,y
083a: c8 iny
083b: d0 f7 bne :_Load1
083d: ee 36 08 inc :_Load1+2
0840: ee 39 08 inc :_Store1+2
0843: ae 39 08 ldx :_Store1+2
0846: e0 04 cpx #$04
0848: d0 ea bne :_Load1
084a: b9 00 93 :_Load2 lda $9300,y ;relocate $7300-93ff to $9f00-bfff
084d: 99 00 bf :_Store2 sta $bf00,y
0850: 88 dey
0851: d0 f7 bne :_Load2
0853: ce 4c 08 dec :_Load2+2
0856: ce 4f 08 dec :_Store2+2
0859: ae 4f 08 ldx :_Store2+2
085c: e0 9e cpx #$9e
085e: d0 ea bne :_Load2
0860: b9 00 70 :_Load3 lda $7000,y ;relocate $7000-72ff to $9a00-9cff
0863: 99 00 9a :_Store3 sta $9a00,y
0866: c8 iny
0867: d0 f7 bne :_Load3
0869: ee 62 08 inc :_Load3+2
086c: ee 65 08 inc :_Store3+2
086f: ae 65 08 ldx :_Store3+2
0872: e0 9d cpx #$9d
0874: d0 ea bne :_Load3
0876: b9 00 6f :_Load4 lda $6f00,y ;relocate $3700-6fff to $5e00-96ff
0879: 99 00 96 :_Store4 sta $9600,y
087c: 88 dey
087d: d0 f7 bne :_Load4
087f: ce 78 08 dec :_Load4+2
0882: ce 7b 08 dec :_Store4+2
0885: ae 7b 08 ldx :_Store4+2
0888: e0 5d cpx #$5d
088a: d0 ea bne :_Load4
088c: b9 00 1c :_Load5 lda $1c00,y ;relocate $1c00-36ff to $4000-5aff
088f: 99 00 40 :_Store5 sta $4000,y
0892: c8 iny
0893: d0 f7 bne :_Load5
0895: ee 8e 08 inc :_Load5+2
0898: ee 91 08 inc :_Store5+2
089b: ae 91 08 ldx :_Store5+2
089e: e0 5b cpx #$5b
08a0: d0 ea bne :_Load5
08a2: b9 00 1b :_Load6 lda $1b00,y ;relocate $0d00-1bff to $0f00-1dff
08a5: 99 00 1d :_Store6 sta $1d00,y
08a8: 88 dey
08a9: d0 f7 bne :_Load6
08ab: ce a4 08 dec :_Load6+2
08ae: ce a7 08 dec :_Store6+2
08b1: ae a7 08 ldx :_Store6+2
08b4: e0 0e cpx #$0e
08b6: d0 ea bne :_Load6
08b8: 4c 33 81 jmp Start ;start game
08bb: 00 00 00 00+ .junk 5
;
; Program initialization continued: pause briefly then jump to next bit of code.
;
08c0: a9 ff Init1 lda #$ff ;pause briefly (why?)
08c2: 20 a8 fc jsr MON_WAIT
08c5: 20 a8 fc jsr MON_WAIT
08c8: 20 a8 fc jsr MON_WAIT
08cb: 20 a8 fc jsr MON_WAIT
08ce: 20 a8 fc jsr MON_WAIT
08d1: 4c 32 08 jmp Init2
08d4: 00 00 00 00+ .align $0100 (44 bytes)
.org $d000
;
; Zero-page memory. For disassembly purposes it was getting in the way when set
; to address zero -- global EQUs and local variables are easier to work with
; than data explicitly assembled to $0000. I gave it an address of $d000 just
; to get it out of the way.
;
; Some values here are not set anywhere else, and MUST have the correct values
; (e.g. the bit masks and the check at $7655).
;
; $60-d1 are zeroed at the start of every game.
;
d000: 05 3b c0 84+ zero_page .bulk $05,$3b,$c0,$84,$00,$95,$14,$ff ;$00
d008: ff ff ff 20+ .bulk $ff,$ff,$ff,$20,$21,$00,$0f,$55
d010: 00 3b 00 ae+ .bulk $00,$3b,$00,$ae,$00,$14,$95,$47 ;$10
d018: 28 22 ff ff+ .bulk $28,$22,$ff,$ff,$ff,$ff,$ff,$ff
d020: 00 28 00 18+ .bulk $00,$28,$00,$18,$00,$01,$00,$09 ;$20
d028: 80 04 d0 60+ .bulk $80,$04,$d0,$60,$ff,$ff,$ff,$ff
d030: f7 00 ff aa+ .bulk $f7,$00,$ff,$aa,$02,$28,$a2,$25 ;$30
d038: a2 05 ff ff+ .bulk $a2,$05,$ff,$ff,$ff,$01,$00,$00
d040: 00 00 00 c0+ .bulk $00,$00,$00,$c0,$01,$08,$ff,$ff ;$40
d048: 00 ff ff ff+ .bulk $00,$ff,$ff,$ff,$ff,$ff,$75,$53
d050: f7 ff f7 ff+ .bulk $f7,$ff,$f7,$ff,$ff,$ff,$ff,$ff ;$50
d058: ff ff ff ff+ .bulk $ff,$ff,$ff,$ff,$ff,$ff,$ff,$ff
d060: 00 00 06 00+ .bulk $00,$00,$06,$00,$18,$00,$05,$00 ;$60
d068: 17 00 01 00+ .bulk $17,$00,$01,$00,$ef,$20,$26,$00
d070: 00 00 00 00+ .bulk $00,$00,$00,$00,$07,$00,$00,$00 ;$70
d078: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$00,$76,$00
d080: 65 00 63 00+ .bulk $65,$00,$63,$00,$27,$00,$05,$3b ;$80
d088: 1a 19 df 01+ .bulk $1a,$19,$df,$01,$06,$0e,$7a,$0c
d090: 00 00 d4 00+ .bulk $00,$00,$d4,$00,$00,$00,$00,$00 ;$90
d098: 86 00 00 d0+ .bulk $86,$00,$00,$d0,$00,$00,$d0,$00
d0a0: 00 00 f7 00+ .bulk $00,$00,$f7,$00,$00,$00,$00,$00 ;$a0
d0a8: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$00,$00,$8a
d0b0: fd 00 b7 06+ .bulk $fd,$00,$b7,$06,$00,$00,$00,$00 ;$b0
d0b8: 00 00 00 00+ .bulk $00,$00,$00,$00,$ed,$02,$ae,$00
d0c0: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$90,$90,$00 ;$c0
d0c8: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$00,$00,$00
d0d0: 00 00 0b 9c+ .bulk $00,$00,$0b,$9c,$00,$00,$80,$c0 ;$d0
d0d8: e0 f0 f8 fc+ .bulk $e0,$f0,$f8,$fc,$fe,$ff,$ff,$7f
d0e0: 3f 1f 0f 07+ .bulk $3f,$1f,$0f,$07,$03,$01,$00,$01 ;$e0
d0e8: 03 07 0f 1f+ .bulk $03,$07,$0f,$1f,$3f,$7f,$ff,$fe
d0f0: fc f8 f0 e0+ .bulk $fc,$f8,$f0,$e0,$c0,$80,$00,$00 ;$f0
d0f8: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$00,$00,$01
.org $0100
;
; 6502 stack.
;
0100: dd ff df ff+ STACK .junk 256
;
; System input buffer.
;
0200: 93 INPUT_BUFFER .dd1 $93 ;used by copy protection check?
0201: 90 8d bc b8+ .align $0100 (255 bytes)
;
; Called when the reset key is hit. Erases memory.
;
]memptr .var $00 {addr/2}
0300: a0 00 Reset ldy #$00 ;start at $0c00
0302: 84 00 sty ]memptr
0304: a9 0c lda #$0c
0306: 85 01 sta ]memptr+1
0308: a2 b4 ldx #$b4 ;continue until $bfff
030a: 98 tya ;A-reg=0
030b: 91 00 :Loop sta (]memptr),y
030d: c8 iny
030e: d0 fb bne :Loop
0310: e6 01 inc ]memptr+1 ;advance pointer to next page
0312: ca dex ;count down the pages
0313: d0 f6 bne :Loop
; Make a sound.
]counter .var $00 {addr/1}
0315: a9 c0 lda #$c0
0317: 85 00 sta ]counter
0319: a0 c0 L0319 ldy #$c0
031b: ad 30 c0 L031B lda SPKR ;click
031e: a6 00 ldx ]counter
0320: ca L0320 dex
0321: d0 fd bne L0320
0323: 88 dey
0324: d0 f5 bne L031B
0326: 46 00 lsr ]counter
0328: d0 ef bne L0319
; Reboot.
032a: a6 2b ldx boot_slot ;get boot slot (e.g. $60)
032c: ca dex ;decrement to get previous (e.g. $5F)
032d: 8a txa
032e: 4a lsr A ;divide by 16 to get slot num - 1
032f: 4a lsr A
0330: 4a lsr A
0331: 4a lsr A
0332: 09 c0 ora #$c0 ;push slot address - 1 (e.g. $c5ff)
0334: 48 pha
0335: a9 ff lda #$ff
0337: 48 pha
0338: 60 rts ;jump to it
0339: 00 00 00 00+ .junk 185
03f2: 00 03 L03F2 .dd2 Reset ;reset vector
03f4: a6 L03F4 .dd1 $a6 ;power-up byte
03f5: ff ff ff ff+ .junk 11
.org $0f00
0f00: 00 00 00 00+ .junk 83
0f53: a2 40 unref_0f53 ldx #$40
0f55: bd 40 05 :Loop lda $0540,x
0f58: 9d 00 03 sta Reset,x
0f5b: ca dex
0f5c: 10 f7 bpl :Loop
0f5e: ad 81 c0 lda ROMIN ;read ROM, write RAM
0f61: ad 81 c0 lda ROMIN
0f64: a9 00 lda #$00 ;point RAM reset vector at $0300
0f66: 8d f2 03 sta L03F2
0f69: 8d fc ff sta MON_6502_RESET
0f6c: a9 03 lda #$03
0f6e: 8d f3 03 sta L03F2+1
0f71: 8d fd ff sta MON_6502_RESET+1
0f74: 49 a5 eor #$a5
0f76: 8d f4 03 sta L03F4
0f79: ad 80 c0 lda LCBANK2_RW ;read RAM (write disabled)
0f7c: 4c 33 81 jmp Start
0f7f: 00 .junk 1
0f80: 00 00 00 00+ copyright_msg .junk 40 ;holds "decrypted" copyright message
0fa8: 00 .junk 1
;
; Init a series of pages to a value.
;
; On entry:
; A-reg: value to store
; X-reg: start page
; Y-reg: end page
; $10: page offset (expected to be zero)
;
• Clear variables
]memptr .var $10 {addr/2}
]end_page .var $86 {addr/1}
0fa9: 84 86 Memset sty ]end_page
0fab: 86 11 stx ]memptr+1
0fad: a0 00 :PageLoop ldy #$00
0faf: 91 10 :_Loop sta (]memptr),y
0fb1: c8 iny
0fb2: d0 fb bne :_Loop
0fb4: e6 11 inc ]memptr+1
0fb6: a4 11 ldy ]memptr+1
0fb8: c4 86 cpy ]end_page
0fba: d0 f1 bne :PageLoop
0fbc: a9 91 lda #INSTR_STA_DPIIY ;set store instruction
0fbe: 8d af 0f sta :_Loop ;(this doesn't seem useful)
0fc1: 60 rts
0fc2: 00 00 00 00+ .junk 46
0ff0: 60 Return0ff0 rts
0ff1: 00 00 00 .junk 3
0ff4: 60 Return0ff4 rts
0ff5: 00 00 00 00+ .align $0100 (11 bytes)
;
; Math table #1, maps ? to ?.
;
; 8 256-byte pages.
;
; The index into this is generally extracted from math table #2 ($ac00).
1000: 01 01 01 01+ math_tab1_base? .bulk $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01
+ $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01
+ $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01
+ $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01
+ $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01
+ $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01
+ $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01
+ $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01
+ $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01
+ $01,$01,$01,$01,$01,$01,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
+ $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
+ $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
+ $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
+ $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
+ $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
+ $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
+ $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
+ $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
+ $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
+ $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
+ $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
+ $02,$02,$02,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
+ $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
+ $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
+ $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
+ $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
+ $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
+ $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
+ $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$04
+ $04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04
+ $04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04
+ $04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04
+ $04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04
+ $04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04
+ $04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$05,$05,$05,$05
+ $05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05
+ $05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05
+ $05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05
+ $05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05
+ $05,$05,$05,$05,$05,$05,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06
+ $06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06
+ $06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06
+ $06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06
+ $06,$06,$06,$06,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07
+ $07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07
+ $07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07
+ $07,$07,$07,$07,$07,$07,$07,$07,$07,$08,$08,$08,$08,$08,$08,$08
+ $08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08
+ $08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08,$08
+ $08,$08,$08,$08,$08,$08,$08,$09,$09,$09,$09,$09,$09,$09,$09,$09
+ $09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09
+ $09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09,$09
+ $0a,$0a,$0a,$0a,$0a,$0a,$0a,$0a,$0a,$0a,$0a,$0a,$0a,$0a,$0a,$0a
+ $0a,$0a,$0a,$0a,$0a,$0a,$0a,$0a,$0a,$0a,$0a,$0a,$0a,$0a,$0a,$0a
+ $0a,$0a,$0a,$0a,$0a,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b
+ $0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b,$0b
+ $0b,$0b,$0b,$0b,$0b,$0b,$0b,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$0c
+ $0c,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$0c
+ $0c,$0c,$0c,$0c,$0c,$0d,$0d,$0d,$0d,$0d,$0d,$0d,$0d,$0d,$0d,$0d
+ $0d,$0d,$0d,$0d,$0d,$0d,$0d,$0d,$0d,$0d,$0d,$0d,$0d,$0d,$0d,$0d
+ $0d,$0d,$0e,$0e,$0e,$0e,$0e,$0e,$0e,$0e,$0e,$0e,$0e,$0e,$0e,$0e
+ $0e,$0e,$0e,$0e,$0e,$0e,$0e,$0e,$0e,$0e,$0e,$0e,$0f,$0f,$0f,$0f
+ $0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f,$0f
+ $0f,$0f,$0f,$0f,$0f,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10
+ $10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$10,$11,$11,$11,$11
+ $11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11,$11
+ $11,$11,$12,$12,$12,$12,$12,$12,$12,$12,$12,$12,$12,$12,$12,$12
+ $12,$12,$12,$12,$12,$12,$13,$13,$13,$13,$13,$13,$13,$13,$13,$13
+ $13,$13,$13,$13,$13,$13,$13,$13,$13,$13,$14,$14,$14,$14,$14,$14
+ $14,$14,$14,$14,$14,$14,$14,$14,$14,$14,$14,$14,$15,$15,$15,$15
+ $15,$15,$15,$15,$15,$15,$15,$15,$15,$15,$15,$15,$15,$15,$16,$16
+ $16,$16,$16,$16,$16,$16,$16,$16,$16,$16,$16,$16,$16,$16,$17,$17
+ $17,$17,$17,$17,$17,$17,$17,$17,$17,$17,$17,$17,$17,$17,$18,$18
+ $18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$19,$19
+ $19,$19,$19,$19,$19,$19,$19,$19,$19,$19,$19,$19,$19,$1a,$1a,$1a
+ $1a,$1a,$1a,$1a,$1a,$1a,$1a,$1a,$1a,$1a,$1a,$1b,$1b,$1b,$1b,$1b
+ $1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1c,$1c,$1c,$1c,$1c,$1c,$1c
+ $1c,$1c,$1c,$1c,$1c,$1c,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d
+ $1d,$1d,$1e,$1e,$1e,$1e,$1e,$1e,$1e,$1e,$1e,$1e,$1e,$1e,$1e,$1f
+ $1f,$1f,$1f,$1f,$1f,$1f,$1f,$1f,$1f,$1f,$1f,$20,$20,$20,$20,$20
+ $20,$20,$20,$20,$20,$20,$21,$21,$21,$21,$21,$21,$21,$21,$21,$21
+ $21,$21,$22,$22,$22,$22,$22,$22,$22,$22,$22,$22,$23,$23,$23,$23
+ $23,$23,$23,$23,$23,$23,$23,$24,$24,$24,$24,$24,$24,$24,$24,$24
+ $24,$25,$25,$25,$25,$25,$25,$25,$25,$25,$25,$26,$26,$26,$26,$26
+ $26,$26,$26,$26,$26,$27,$27,$27,$27,$27,$27,$27,$27,$27,$28,$28
+ $28,$28,$28,$28,$28,$28,$28,$29,$29,$29,$29,$29,$29,$29,$29,$29
+ $2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2a,$2b,$2b,$2b,$2b,$2b,$2b,$2b
+ $2b,$2b,$2c,$2c,$2c,$2c,$2c,$2c,$2c,$2c,$2d,$2d,$2d,$2d,$2d,$2d
+ $2d,$2d,$2d,$2e,$2e,$2e,$2e,$2e,$2e,$2e,$2f,$2f,$2f,$2f,$2f,$2f
+ $2f,$2f,$30,$30,$30,$30,$30,$30,$30,$30,$31,$31,$31,$31,$31,$31
+ $31,$31,$32,$32,$32,$32,$32,$32,$32,$33,$33,$33,$33,$33,$33,$33
+ $34,$34,$34,$34,$34,$34,$34,$35,$35,$35,$35,$35,$35,$35,$36,$36
+ $36,$36,$36,$36,$36,$37,$37,$37,$37,$37,$37,$37,$38,$38,$38,$38
+ $38,$38,$39,$39,$39,$39,$39,$39,$39,$3a,$3a,$3a,$3a,$3a,$3a,$3b
+ $3b,$3b,$3b,$3b,$3b,$3b,$3c,$3c,$3c,$3c,$3c,$3c,$3d,$3d,$3d,$3d
+ $3d,$3d,$3e,$3e,$3e,$3e,$3e,$3e,$3f,$3f,$3f,$3f,$3f,$3f,$40,$40
+ $40,$40,$40,$41,$41,$41,$41,$41,$41,$42,$42,$42,$42,$42,$42,$43
+ $43,$43,$43,$43,$44,$44,$44,$44,$44,$44,$45,$45,$45,$45,$45,$46
+ $46,$46,$46,$46,$47,$47,$47,$47,$47,$48,$48,$48,$48,$48,$48,$49
+ $49,$49,$49,$49,$4a,$4a,$4a,$4a,$4a,$4b,$4b,$4b,$4b,$4c,$4c,$4c
+ $4c,$4c,$4d,$4d,$4d,$4d,$4d,$4e,$4e,$4e,$4e,$4e,$4f,$4f,$4f,$4f
+ $4f,$50,$50,$50,$50,$51,$51,$51,$51,$51,$52,$52,$52,$52,$53,$53
+ $53,$53,$53,$54,$54,$54,$54,$55,$55,$55,$55,$56,$56,$56,$56,$56
+ $57,$57,$57,$57,$58,$58,$58,$58,$59,$59,$59,$59,$5a,$5a,$5a,$5a
+ $5a,$5b,$5b,$5b,$5b,$5c,$5c,$5c,$5c,$5d,$5d,$5d,$5e,$5e,$5e,$5e
+ $5f,$5f,$5f,$5f,$60,$60,$60,$60,$61,$61,$61,$61,$62,$62,$62,$62
+ $63,$63,$63,$63,$64,$64,$64,$65,$65,$65,$65,$66,$66,$66,$66,$67
+ $67,$67,$68,$68,$68,$68,$69,$69,$69,$6a,$6a,$6a,$6a,$6b,$6b,$6b
+ $6c,$6c,$6c,$6d,$6d,$6d,$6d,$6e,$6e,$6e,$6f,$6f,$6f,$6f,$70,$70
+ $70,$71,$71,$71,$72,$72,$72,$73,$73,$73,$73,$74,$74,$74,$75,$75
+ $75,$76,$76,$76,$77,$77,$77,$78,$78,$78,$79,$79,$79,$7a,$7a,$7a
+ $7b,$7b,$7b,$7c,$7c,$7c,$7d,$7d,$7d,$7e,$7e,$7e,$7f,$7f,$7f,$80
math_tab1_lastpg?
1700: 80 80 81 81+ .bulk $80,$80,$81,$81,$81,$82,$82,$82,$83,$83,$84,$84,$84,$85,$85,$85
+ $86,$86,$86,$87,$87,$87,$88,$88,$89,$89,$89,$8a,$8a,$8a,$8b,$8b
+ $8c,$8c,$8c,$8d,$8d,$8d,$8e,$8e,$8f,$8f,$8f,$90,$90,$91,$91,$91
+ $92,$92,$93,$93,$93,$94,$94,$95,$95,$95,$96,$96,$97,$97,$97,$98
+ $98,$99,$99,$99,$9a,$9a,$9b,$9b,$9c,$9c,$9c,$9d,$9d,$9e,$9e,$9e
+ $9f,$9f,$a0,$a0,$a1,$a1,$a2,$a2,$a2,$a3,$a3,$a4,$a4,$a5,$a5,$a6
+ $a6,$a6,$a7,$a7,$a8,$a8,$a9,$a9,$aa,$aa,$ab,$ab,$ab,$ac,$ac,$ad
+ $ad,$ae,$ae,$af,$af,$b0,$b0,$b1,$b1,$b2,$b2,$b3,$b3,$b3,$b4,$b5
+ $b5,$b6,$b6,$b6,$b7,$b7,$b8,$b8,$b9,$b9,$ba,$ba,$bb,$bb,$bc,$bc
+ $bd,$bd,$be,$bf,$bf,$c0,$c0,$c1,$c1,$c2,$c2,$c3,$c3,$c4,$c4,$c5
+ $c5,$c6,$c6,$c7,$c8,$c8,$c9,$c9,$ca,$ca,$cb,$cb,$cc,$cc,$cd,$ce
+ $ce,$cf,$cf,$d0,$d0,$d1,$d2,$d2,$d3,$d3,$d4,$d4,$d5,$d5,$d6,$d7
+ $d7,$d8,$d8,$d9,$da,$da,$db,$db,$dc,$dd,$dd,$de,$de,$df,$e0,$e0
+ $e1,$e1,$e2,$e3,$e3,$e4,$e4,$e5,$e6,$e6,$e7,$e8,$e8,$e9,$e9,$ea
+ $eb,$eb,$ec,$ed,$ed,$ee,$ef,$ef,$f0,$f0,$f1,$f2,$f2,$f3,$f4,$f4
+ $f5,$f6,$f6,$f7,$f8,$f8,$f9,$fa,$fb,$fb,$fc,$fc,$fd,$fe,$ff,$ff
;
; Draws a vertical stripe.
;
; This is generally not called directly, the primary exception being when
; drawing the crosshairs. A lookup table ($b700/b800) converts line numbers to
; addresses, which are then used as an indirect jump (for the top) or as a
; location to store an RTS (for the bottom).
;
; On entry:
; X-reg: pixel byte value (adjusted for odd/even)
; Y-reg: horizontal offset (0-39)
;
1800: 8a UnrolledORA txa
1801: 19 00 20 ora HIRES_P1,y
1804: 99 00 20 sta HIRES_P1,y
1807: 8a txa
1808: 19 00 24 ora HIRES_P1+$400,y
180b: 99 00 24 sta HIRES_P1+$400,y
180e: 8a txa
180f: 19 00 28 ora HIRES_P1+$800,y
1812: 99 00 28 sta HIRES_P1+$800,y
1815: 8a txa
1816: 19 00 2c ora HIRES_P1+$c00,y
1819: 99 00 2c sta HIRES_P1+$c00,y
181c: 8a txa
181d: 19 00 30 ora HIRES_P1+$1000,y
1820: 99 00 30 sta HIRES_P1+$1000,y
1823: 8a txa
1824: 19 00 34 ora HIRES_P1+$1400,y
1827: 99 00 34 sta HIRES_P1+$1400,y
182a: 8a txa
182b: 19 00 38 ora HIRES_P1+$1800,y
182e: 99 00 38 sta HIRES_P1+$1800,y
1831: 8a txa
1832: 19 00 3c ora HIRES_P1+$1c00,y
1835: 99 00 3c sta HIRES_P1+$1c00,y
1838: 8a txa
1839: 19 80 20 ora HIRES_P1+128,y
183c: 99 80 20 sta HIRES_P1+128,y
183f: 8a txa
1840: 19 80 24 ora HIRES_P1+$480,y
1843: 99 80 24 sta HIRES_P1+$480,y
1846: 8a txa
1847: 19 80 28 ora HIRES_P1+$880,y
184a: 99 80 28 sta HIRES_P1+$880,y
184d: 8a txa
184e: 19 80 2c ora HIRES_P1+$c80,y
1851: 99 80 2c sta HIRES_P1+$c80,y
1854: 8a txa
1855: 19 80 30 ora HIRES_P1+$1080,y
1858: 99 80 30 sta HIRES_P1+$1080,y
185b: 8a txa
185c: 19 80 34 ora HIRES_P1+$1480,y
185f: 99 80 34 sta HIRES_P1+$1480,y
1862: 8a txa
1863: 19 80 38 ora HIRES_P1+$1880,y
1866: 99 80 38 sta HIRES_P1+$1880,y
1869: 8a txa
186a: 19 80 3c ora HIRES_P1+$1c80,y
186d: 99 80 3c sta HIRES_P1+$1c80,y
1870: 8a txa
1871: 19 00 21 ora HIRES_P1+$100,y
1874: 99 00 21 sta HIRES_P1+$100,y
1877: 8a txa
1878: 19 00 25 ora HIRES_P1+$500,y
187b: 99 00 25 sta HIRES_P1+$500,y
187e: 8a txa
187f: 19 00 29 ora HIRES_P1+$900,y
1882: 99 00 29 sta HIRES_P1+$900,y
1885: 8a txa
1886: 19 00 2d ora HIRES_P1+$d00,y
1889: 99 00 2d sta HIRES_P1+$d00,y
188c: 8a txa
188d: 19 00 31 ora HIRES_P1+$1100,y
1890: 99 00 31 sta HIRES_P1+$1100,y
1893: 8a txa
1894: 19 00 35 ora HIRES_P1+$1500,y
1897: 99 00 35 sta HIRES_P1+$1500,y
189a: 8a txa
189b: 19 00 39 ora HIRES_P1+$1900,y
189e: 99 00 39 sta HIRES_P1+$1900,y
18a1: 8a txa
18a2: 19 00 3d ora HIRES_P1+$1d00,y
18a5: 99 00 3d sta HIRES_P1+$1d00,y
18a8: 8a txa
18a9: 19 80 21 ora HIRES_P1+$180,y
18ac: 99 80 21 sta HIRES_P1+$180,y
18af: 8a txa
18b0: 19 80 25 ora HIRES_P1+$580,y
18b3: 99 80 25 sta HIRES_P1+$580,y
18b6: 8a txa
18b7: 19 80 29 ora HIRES_P1+$980,y
18ba: 99 80 29 sta HIRES_P1+$980,y
18bd: 8a txa
18be: 19 80 2d ora HIRES_P1+$d80,y
18c1: 99 80 2d sta HIRES_P1+$d80,y
18c4: 8a txa
18c5: 19 80 31 ora HIRES_P1+$1180,y
18c8: 99 80 31 sta HIRES_P1+$1180,y
18cb: 8a txa
18cc: 19 80 35 ora HIRES_P1+$1580,y
18cf: 99 80 35 sta HIRES_P1+$1580,y
18d2: 8a txa
18d3: 19 80 39 ora HIRES_P1+$1980,y
18d6: 99 80 39 sta HIRES_P1+$1980,y
18d9: 8a txa
18da: 19 80 3d ora HIRES_P1+$1d80,y
18dd: 99 80 3d sta HIRES_P1+$1d80,y
18e0: 8a txa
18e1: 19 00 22 ora HIRES_P1+$200,y
18e4: 99 00 22 sta HIRES_P1+$200,y
18e7: 8a txa
18e8: 19 00 26 ora HIRES_P1+$600,y
18eb: 99 00 26 sta HIRES_P1+$600,y
18ee: 8a txa
18ef: 19 00 2a ora HIRES_P1+$a00,y
18f2: 99 00 2a sta HIRES_P1+$a00,y
18f5: 8a txa
18f6: 19 00 2e ora HIRES_P1+$e00,y
18f9: 99 00 2e sta HIRES_P1+$e00,y
18fc: 8a txa
18fd: 19 00 32 ora HIRES_P1+$1200,y
1900: 99 00 32 sta HIRES_P1+$1200,y
1903: 8a txa
1904: 19 00 36 ora HIRES_P1+$1600,y
1907: 99 00 36 sta HIRES_P1+$1600,y
190a: 8a txa
190b: 19 00 3a ora HIRES_P1+$1a00,y
190e: 99 00 3a sta HIRES_P1+$1a00,y
1911: 8a txa
1912: 19 00 3e ora HIRES_P1+$1e00,y
1915: 99 00 3e sta HIRES_P1+$1e00,y
1918: 8a txa
1919: 19 80 22 ora HIRES_P1+$280,y
191c: 99 80 22 sta HIRES_P1+$280,y
191f: 8a txa
1920: 19 80 26 ora HIRES_P1+$680,y
1923: 99 80 26 sta HIRES_P1+$680,y
1926: 8a txa
1927: 19 80 2a ora HIRES_P1+$a80,y
192a: 99 80 2a sta HIRES_P1+$a80,y
192d: 8a txa
192e: 19 80 2e ora HIRES_P1+$e80,y
1931: 99 80 2e sta HIRES_P1+$e80,y
1934: 8a txa
1935: 19 80 32 ora HIRES_P1+$1280,y
1938: 99 80 32 sta HIRES_P1+$1280,y
193b: 8a txa
193c: 19 80 36 ora HIRES_P1+$1680,y
193f: 99 80 36 sta HIRES_P1+$1680,y
1942: 8a txa
1943: 19 80 3a ora HIRES_P1+$1a80,y
1946: 99 80 3a sta HIRES_P1+$1a80,y
1949: 8a txa
194a: 19 80 3e ora HIRES_P1+$1e80,y
194d: 99 80 3e sta HIRES_P1+$1e80,y
1950: 8a txa
1951: 19 00 23 ora HIRES_P1+$300,y
1954: 99 00 23 sta HIRES_P1+$300,y
1957: 8a txa
1958: 19 00 27 ora HIRES_P1+$700,y
195b: 99 00 27 sta HIRES_P1+$700,y
195e: 8a txa
195f: 19 00 2b ora HIRES_P1+$b00,y
1962: 99 00 2b sta HIRES_P1+$b00,y
1965: 8a txa
1966: 19 00 2f ora HIRES_P1+$f00,y
1969: 99 00 2f sta HIRES_P1+$f00,y
196c: 8a txa
196d: 19 00 33 ora HIRES_P1+$1300,y
1970: 99 00 33 sta HIRES_P1+$1300,y
1973: 8a txa
1974: 19 00 37 ora HIRES_P1+$1700,y
1977: 99 00 37 sta HIRES_P1+$1700,y
197a: 8a txa
197b: 19 00 3b ora HIRES_P1+$1b00,y
197e: 99 00 3b sta HIRES_P1+$1b00,y
1981: 8a txa
1982: 19 00 3f ora HIRES_P1+$1f00,y
1985: 99 00 3f sta HIRES_P1+$1f00,y
1988: 8a txa
1989: 19 80 23 ora HIRES_P1+$380,y
198c: 99 80 23 sta HIRES_P1+$380,y
198f: 8a txa
1990: 19 80 27 ora HIRES_P1+$780,y
1993: 99 80 27 sta HIRES_P1+$780,y
1996: 8a txa
1997: 19 80 2b ora HIRES_P1+$b80,y
199a: 99 80 2b sta HIRES_P1+$b80,y
199d: 8a txa
199e: 19 80 2f ora HIRES_P1+$f80,y
19a1: 99 80 2f sta HIRES_P1+$f80,y
19a4: 8a txa
19a5: 19 80 33 ora HIRES_P1+$1380,y
19a8: 99 80 33 sta HIRES_P1+$1380,y
19ab: 8a txa
19ac: 19 80 37 ora HIRES_P1+$1780,y
19af: 99 80 37 sta HIRES_P1+$1780,y
19b2: 8a txa
19b3: 19 80 3b ora HIRES_P1+$1b80,y
19b6: 99 80 3b sta HIRES_P1+$1b80,y
19b9: 8a txa
19ba: 19 80 3f ora HIRES_P1+$1f80,y
19bd: 99 80 3f sta HIRES_P1+$1f80,y
19c0: 8a txa
19c1: 19 28 20 ora HIRES_P1+40,y
19c4: 99 28 20 sta HIRES_P1+40,y
19c7: 8a txa
19c8: 19 28 24 ora HIRES_P1+$428,y
19cb: 99 28 24 sta HIRES_P1+$428,y
19ce: 8a txa
19cf: 19 28 28 ora HIRES_P1+$828,y
19d2: 99 28 28 sta HIRES_P1+$828,y
19d5: 8a txa
19d6: 19 28 2c ora HIRES_P1+$c28,y
19d9: 99 28 2c sta HIRES_P1+$c28,y
19dc: 8a txa
19dd: 19 28 30 ora HIRES_P1+$1028,y
19e0: 99 28 30 sta HIRES_P1+$1028,y
19e3: 8a txa
19e4: 19 28 34 ora HIRES_P1+$1428,y
19e7: 99 28 34 sta HIRES_P1+$1428,y
19ea: 8a txa
19eb: 19 28 38 ora HIRES_P1+$1828,y
19ee: 99 28 38 sta HIRES_P1+$1828,y
19f1: 8a txa
19f2: 19 28 3c ora HIRES_P1+$1c28,y
19f5: 99 28 3c sta HIRES_P1+$1c28,y
19f8: 8a txa
19f9: 19 a8 20 ora HIRES_P1+168,y
19fc: 99 a8 20 sta HIRES_P1+168,y
19ff: 8a txa
1a00: 19 a8 24 ora HIRES_P1+$4a8,y
1a03: 99 a8 24 sta HIRES_P1+$4a8,y
1a06: 8a txa
1a07: 19 a8 28 ora HIRES_P1+$8a8,y
1a0a: 99 a8 28 sta HIRES_P1+$8a8,y
1a0d: 8a txa
1a0e: 19 a8 2c ora HIRES_P1+$ca8,y
1a11: 99 a8 2c sta HIRES_P1+$ca8,y
1a14: 8a txa
1a15: 19 a8 30 ora HIRES_P1+$10a8,y
1a18: 99 a8 30 sta HIRES_P1+$10a8,y
1a1b: 8a txa
1a1c: 19 a8 34 ora HIRES_P1+$14a8,y
1a1f: 99 a8 34 sta HIRES_P1+$14a8,y
1a22: 8a txa
1a23: 19 a8 38 ora HIRES_P1+$18a8,y
1a26: 99 a8 38 sta HIRES_P1+$18a8,y
1a29: 8a txa
1a2a: 19 a8 3c ora HIRES_P1+$1ca8,y
1a2d: 99 a8 3c sta HIRES_P1+$1ca8,y
1a30: 8a txa
1a31: 19 28 21 ora HIRES_P1+$128,y
1a34: 99 28 21 sta HIRES_P1+$128,y
1a37: 8a txa
1a38: 19 28 25 ora HIRES_P1+$528,y
1a3b: 99 28 25 sta HIRES_P1+$528,y
1a3e: 8a txa
1a3f: 19 28 29 ora HIRES_P1+$928,y
1a42: 99 28 29 sta HIRES_P1+$928,y
1a45: 8a txa
1a46: 19 28 2d ora HIRES_P1+$d28,y
1a49: 99 28 2d sta HIRES_P1+$d28,y
1a4c: 8a txa
1a4d: 19 28 31 ora HIRES_P1+$1128,y
1a50: 99 28 31 sta HIRES_P1+$1128,y
1a53: 8a OraSeq_85 txa
1a54: 19 28 35 ora HIRES_P1+$1528,y ;line 85
1a57: 99 28 35 sta HIRES_P1+$1528,y
1a5a: 8a OraSeq_86 txa
1a5b: 19 28 39 ora HIRES_P1+$1928,y ;line 86
1a5e: 99 28 39 sta HIRES_P1+$1928,y
1a61: 8a txa
1a62: 19 28 3d ora HIRES_P1+$1d28,y
1a65: 99 28 3d sta HIRES_P1+$1d28,y
1a68: 8a txa
1a69: 19 a8 21 ora HIRES_P1+$1a8,y
1a6c: 99 a8 21 sta HIRES_P1+$1a8,y
1a6f: 8a OraSeq_89 txa
1a70: 19 a8 25 ora HIRES_P1+$5a8,y ;line 89
1a73: 99 a8 25 sta HIRES_P1+$5a8,y
1a76: 8a txa
1a77: 19 a8 29 ora HIRES_P1+$9a8,y
1a7a: 99 a8 29 sta HIRES_P1+$9a8,y
1a7d: 8a txa
1a7e: 19 a8 2d ora HIRES_P1+$da8,y
1a81: 99 a8 2d sta HIRES_P1+$da8,y
1a84: 8a txa
1a85: 19 a8 31 ora HIRES_P1+$11a8,y
1a88: 99 a8 31 sta HIRES_P1+$11a8,y
1a8b: 8a OraSeq_93 txa
1a8c: 19 a8 35 ora HIRES_P1+$15a8,y
1a8f: 99 a8 35 sta HIRES_P1+$15a8,y
1a92: 8a txa
1a93: 19 a8 39 ora HIRES_P1+$19a8,y
1a96: 99 a8 39 sta HIRES_P1+$19a8,y
1a99: 8a txa
1a9a: 19 a8 3d ora HIRES_P1+$1da8,y
1a9d: 99 a8 3d sta HIRES_P1+$1da8,y
1aa0: 8a txa
1aa1: 19 28 22 ora HIRES_P1+$228,y
1aa4: 99 28 22 sta HIRES_P1+$228,y
1aa7: 8a txa
1aa8: 19 28 26 ora HIRES_P1+$628,y
1aab: 99 28 26 sta HIRES_P1+$628,y
1aae: 8a txa
1aaf: 19 28 2a ora HIRES_P1+$a28,y
1ab2: 99 28 2a sta HIRES_P1+$a28,y
1ab5: 8a txa
1ab6: 19 28 2e ora HIRES_P1+$e28,y
1ab9: 99 28 2e sta HIRES_P1+$e28,y
1abc: 8a OraSeq_100 txa
1abd: 19 28 32 ora HIRES_P1+$1228,y ;line 100
1ac0: 99 28 32 sta HIRES_P1+$1228,y
1ac3: 8a txa
1ac4: 19 28 36 ora HIRES_P1+$1628,y
1ac7: 99 28 36 sta HIRES_P1+$1628,y
1aca: 8a txa
1acb: 19 28 3a ora HIRES_P1+$1a28,y
1ace: 99 28 3a sta HIRES_P1+$1a28,y
1ad1: 8a txa
1ad2: 19 28 3e ora HIRES_P1+$1e28,y
1ad5: 99 28 3e sta HIRES_P1+$1e28,y
1ad8: 8a txa
1ad9: 19 a8 22 ora HIRES_P1+$2a8,y
1adc: 99 a8 22 sta HIRES_P1+$2a8,y
1adf: 8a txa
1ae0: 19 a8 26 ora HIRES_P1+$6a8,y
1ae3: 99 a8 26 sta HIRES_P1+$6a8,y
1ae6: 8a txa
1ae7: 19 a8 2a ora HIRES_P1+$aa8,y
1aea: 99 a8 2a sta HIRES_P1+$aa8,y
1aed: 8a txa
1aee: 19 a8 2e ora HIRES_P1+$ea8,y
1af1: 99 a8 2e sta HIRES_P1+$ea8,y
1af4: 8a OraSeq_108 txa
1af5: 19 a8 32 ora HIRES_P1+$12a8,y
1af8: 99 a8 32 sta HIRES_P1+$12a8,y
1afb: 8a txa
1afc: 19 a8 36 ora HIRES_P1+$16a8,y
1aff: 99 a8 36 sta HIRES_P1+$16a8,y
1b02: 8a txa
1b03: 19 a8 3a ora HIRES_P1+$1aa8,y
1b06: 99 a8 3a sta HIRES_P1+$1aa8,y
1b09: 8a txa
1b0a: 19 a8 3e ora HIRES_P1+$1ea8,y
1b0d: 99 a8 3e sta HIRES_P1+$1ea8,y
1b10: 8a txa
1b11: 19 28 23 ora HIRES_P1+$328,y
1b14: 99 28 23 sta HIRES_P1+$328,y
1b17: 8a txa
1b18: 19 28 27 ora HIRES_P1+$728,y
1b1b: 99 28 27 sta HIRES_P1+$728,y
1b1e: 8a txa
1b1f: 19 28 2b ora HIRES_P1+$b28,y
1b22: 99 28 2b sta HIRES_P1+$b28,y
1b25: 8a txa
1b26: 19 28 2f ora HIRES_P1+$f28,y
1b29: 99 28 2f sta HIRES_P1+$f28,y
1b2c: 8a txa
1b2d: 19 28 33 ora HIRES_P1+$1328,y
1b30: 99 28 33 sta HIRES_P1+$1328,y
1b33: 8a txa
1b34: 19 28 37 ora HIRES_P1+$1728,y
1b37: 99 28 37 sta HIRES_P1+$1728,y
1b3a: 8a txa
1b3b: 19 28 3b ora HIRES_P1+$1b28,y
1b3e: 99 28 3b sta HIRES_P1+$1b28,y
1b41: 8a txa
1b42: 19 28 3f ora HIRES_P1+$1f28,y
1b45: 99 28 3f sta HIRES_P1+$1f28,y
1b48: 8a txa
1b49: 19 a8 23 ora HIRES_P1+$3a8,y
1b4c: 99 a8 23 sta HIRES_P1+$3a8,y
1b4f: 8a txa
1b50: 19 a8 27 ora HIRES_P1+$7a8,y
1b53: 99 a8 27 sta HIRES_P1+$7a8,y
1b56: 8a txa
1b57: 19 a8 2b ora HIRES_P1+$ba8,y
1b5a: 99 a8 2b sta HIRES_P1+$ba8,y
1b5d: 8a txa
1b5e: 19 a8 2f ora HIRES_P1+$fa8,y
1b61: 99 a8 2f sta HIRES_P1+$fa8,y
1b64: 8a txa
1b65: 19 a8 33 ora HIRES_P1+$13a8,y
1b68: 99 a8 33 sta HIRES_P1+$13a8,y
1b6b: 8a txa
1b6c: 19 a8 37 ora HIRES_P1+$17a8,y
1b6f: 99 a8 37 sta HIRES_P1+$17a8,y
1b72: 8a txa
1b73: 19 a8 3b ora HIRES_P1+$1ba8,y
1b76: 99 a8 3b sta HIRES_P1+$1ba8,y
1b79: 8a txa
1b7a: 19 a8 3f ora HIRES_P1+$1fa8,y
1b7d: 99 a8 3f sta HIRES_P1+$1fa8,y
1b80: 8a txa
1b81: 19 50 20 ora HIRES_P1+80,y
1b84: 99 50 20 sta HIRES_P1+80,y
1b87: 8a txa
1b88: 19 50 24 ora HIRES_P1+$450,y
1b8b: 99 50 24 sta HIRES_P1+$450,y
1b8e: 8a txa
1b8f: 19 50 28 ora HIRES_P1+$850,y
1b92: 99 50 28 sta HIRES_P1+$850,y
1b95: 8a txa
1b96: 19 50 2c ora HIRES_P1+$c50,y
1b99: 99 50 2c sta HIRES_P1+$c50,y
1b9c: 8a txa
1b9d: 19 50 30 ora HIRES_P1+$1050,y
1ba0: 99 50 30 sta HIRES_P1+$1050,y
1ba3: 8a txa
1ba4: 19 50 34 ora HIRES_P1+$1450,y
1ba7: 99 50 34 sta HIRES_P1+$1450,y
1baa: 8a txa
1bab: 19 50 38 ora HIRES_P1+$1850,y
1bae: 99 50 38 sta HIRES_P1+$1850,y
1bb1: 8a txa
1bb2: 19 50 3c ora HIRES_P1+$1c50,y
1bb5: 99 50 3c sta HIRES_P1+$1c50,y
1bb8: 8a txa
1bb9: 19 d0 20 ora HIRES_P1+208,y
1bbc: 99 d0 20 sta HIRES_P1+208,y
1bbf: 8a txa
1bc0: 19 d0 24 ora HIRES_P1+$4d0,y
1bc3: 99 d0 24 sta HIRES_P1+$4d0,y
1bc6: 8a txa
1bc7: 19 d0 28 ora HIRES_P1+$8d0,y
1bca: 99 d0 28 sta HIRES_P1+$8d0,y
1bcd: 8a txa
1bce: 19 d0 2c ora HIRES_P1+$cd0,y
1bd1: 99 d0 2c sta HIRES_P1+$cd0,y
1bd4: 8a txa
1bd5: 19 d0 30 ora HIRES_P1+$10d0,y
1bd8: 99 d0 30 sta HIRES_P1+$10d0,y
1bdb: 8a txa
1bdc: 19 d0 34 ora HIRES_P1+$14d0,y
1bdf: 99 d0 34 sta HIRES_P1+$14d0,y
1be2: 8a txa
1be3: 19 d0 38 ora HIRES_P1+$18d0,y
1be6: 99 d0 38 sta HIRES_P1+$18d0,y
1be9: 8a txa
1bea: 19 d0 3c ora HIRES_P1+$1cd0,y
1bed: 99 d0 3c sta HIRES_P1+$1cd0,y
1bf0: 8a txa
1bf1: 19 50 21 ora HIRES_P1+$150,y
1bf4: 99 50 21 sta HIRES_P1+$150,y
1bf7: 8a txa
1bf8: 19 50 25 ora HIRES_P1+$550,y
1bfb: 99 50 25 sta HIRES_P1+$550,y
1bfe: 8a txa
1bff: 19 50 29 ora HIRES_P1+$950,y
1c02: 99 50 29 sta HIRES_P1+$950,y
1c05: 8a txa
1c06: 19 50 2d ora HIRES_P1+$d50,y
1c09: 99 50 2d sta HIRES_P1+$d50,y
1c0c: 8a txa
1c0d: 19 50 31 ora HIRES_P1+$1150,y
1c10: 99 50 31 sta HIRES_P1+$1150,y
1c13: 8a txa
1c14: 19 50 35 ora HIRES_P1+$1550,y
1c17: 99 50 35 sta HIRES_P1+$1550,y
1c1a: 8a txa
1c1b: 19 50 39 ora HIRES_P1+$1950,y
1c1e: 99 50 39 sta HIRES_P1+$1950,y
1c21: 8a txa
1c22: 19 50 3d ora HIRES_P1+$1d50,y
1c25: 99 50 3d sta HIRES_P1+$1d50,y
1c28: 8a txa
1c29: 19 d0 21 ora HIRES_P1+$1d0,y
1c2c: 99 d0 21 sta HIRES_P1+$1d0,y
1c2f: 8a txa
1c30: 19 d0 25 ora HIRES_P1+$5d0,y
1c33: 99 d0 25 sta HIRES_P1+$5d0,y
1c36: 8a txa
1c37: 19 d0 29 ora HIRES_P1+$9d0,y
1c3a: 99 d0 29 sta HIRES_P1+$9d0,y
1c3d: 8a txa
1c3e: 19 d0 2d ora HIRES_P1+$dd0,y
1c41: 99 d0 2d sta HIRES_P1+$dd0,y
1c44: 8a txa
1c45: 19 d0 31 ora HIRES_P1+$11d0,y
1c48: 99 d0 31 sta HIRES_P1+$11d0,y
1c4b: 8a txa
1c4c: 19 d0 35 ora HIRES_P1+$15d0,y
1c4f: 99 d0 35 sta HIRES_P1+$15d0,y
1c52: 8a txa
1c53: 19 d0 39 ora HIRES_P1+$19d0,y
1c56: 99 d0 39 sta HIRES_P1+$19d0,y
1c59: 8a txa
1c5a: 19 d0 3d ora HIRES_P1+$1dd0,y
1c5d: 99 d0 3d sta HIRES_P1+$1dd0,y
1c60: 8a txa
1c61: 19 50 22 ora HIRES_P1+$250,y
1c64: 99 50 22 sta HIRES_P1+$250,y
1c67: 8a txa
1c68: 19 50 26 ora HIRES_P1+$650,y
1c6b: 99 50 26 sta HIRES_P1+$650,y
1c6e: 8a txa
1c6f: 19 50 2a ora HIRES_P1+$a50,y
1c72: 99 50 2a sta HIRES_P1+$a50,y
1c75: 8a txa
1c76: 19 50 2e ora HIRES_P1+$e50,y
1c79: 99 50 2e sta HIRES_P1+$e50,y
1c7c: 8a txa
1c7d: 19 50 32 ora HIRES_P1+$1250,y
1c80: 99 50 32 sta HIRES_P1+$1250,y
1c83: 8a txa
1c84: 19 50 36 ora HIRES_P1+$1650,y
1c87: 99 50 36 sta HIRES_P1+$1650,y
1c8a: 8a txa
1c8b: 19 50 3a ora HIRES_P1+$1a50,y
1c8e: 99 50 3a sta HIRES_P1+$1a50,y
1c91: 8a txa
1c92: 19 50 3e ora HIRES_P1+$1e50,y
1c95: 99 50 3e sta HIRES_P1+$1e50,y
1c98: 8a txa
1c99: 19 d0 22 ora HIRES_P1+$2d0,y
1c9c: 99 d0 22 sta HIRES_P1+$2d0,y
1c9f: 8a txa
1ca0: 19 d0 26 ora HIRES_P1+$6d0,y
1ca3: 99 d0 26 sta HIRES_P1+$6d0,y
1ca6: 8a txa
1ca7: 19 d0 2a ora HIRES_P1+$ad0,y
1caa: 99 d0 2a sta HIRES_P1+$ad0,y
1cad: 8a txa
1cae: 19 d0 2e ora HIRES_P1+$ed0,y
1cb1: 99 d0 2e sta HIRES_P1+$ed0,y
1cb4: 8a txa
1cb5: 19 d0 32 ora HIRES_P1+$12d0,y
1cb8: 99 d0 32 sta HIRES_P1+$12d0,y
1cbb: 8a txa
1cbc: 19 d0 36 ora HIRES_P1+$16d0,y
1cbf: 99 d0 36 sta HIRES_P1+$16d0,y
1cc2: 8a txa
1cc3: 19 d0 3a ora HIRES_P1+$1ad0,y
1cc6: 99 d0 3a sta HIRES_P1+$1ad0,y
1cc9: 8a txa
1cca: 19 d0 3e ora HIRES_P1+$1ed0,y
1ccd: 99 d0 3e sta HIRES_P1+$1ed0,y
1cd0: 8a txa
1cd1: 19 50 23 ora HIRES_P1+$350,y
1cd4: 99 50 23 sta HIRES_P1+$350,y
1cd7: 8a txa
1cd8: 19 50 27 ora HIRES_P1+$750,y
1cdb: 99 50 27 sta HIRES_P1+$750,y
1cde: 8a txa
1cdf: 19 50 2b ora HIRES_P1+$b50,y
1ce2: 99 50 2b sta HIRES_P1+$b50,y
1ce5: 8a txa
1ce6: 19 50 2f ora HIRES_P1+$f50,y
1ce9: 99 50 2f sta HIRES_P1+$f50,y
1cec: 8a txa
1ced: 19 50 33 ora HIRES_P1+$1350,y
1cf0: 99 50 33 sta HIRES_P1+$1350,y
1cf3: 8a txa
1cf4: 19 50 37 ora HIRES_P1+$1750,y
1cf7: 99 50 37 sta HIRES_P1+$1750,y
1cfa: 8a txa
1cfb: 19 50 3b ora HIRES_P1+$1b50,y
1cfe: 99 50 3b sta HIRES_P1+$1b50,y
1d01: 8a txa
1d02: 19 50 3f ora HIRES_P1+$1f50,y
1d05: 99 50 3f sta HIRES_P1+$1f50,y
1d08: 8a txa
1d09: 19 d0 23 ora HIRES_P1+$3d0,y
1d0c: 99 d0 23 sta HIRES_P1+$3d0,y
1d0f: 8a txa
1d10: 19 d0 27 ora HIRES_P1+$7d0,y
1d13: 99 d0 27 sta HIRES_P1+$7d0,y
1d16: 8a txa
1d17: 19 d0 2b ora HIRES_P1+$bd0,y
1d1a: 99 d0 2b sta HIRES_P1+$bd0,y
1d1d: 8a txa
1d1e: 19 d0 2f ora HIRES_P1+$fd0,y
1d21: 99 d0 2f sta HIRES_P1+$fd0,y
1d24: 8a txa
1d25: 19 d0 33 ora HIRES_P1+$13d0,y
1d28: 99 d0 33 sta HIRES_P1+$13d0,y
1d2b: 8a txa
1d2c: 19 d0 37 ora HIRES_P1+$17d0,y
1d2f: 99 d0 37 sta HIRES_P1+$17d0,y
1d32: 8a txa
1d33: 19 d0 3b ora HIRES_P1+$1bd0,y
1d36: 99 d0 3b sta HIRES_P1+$1bd0,y
1d39: 8a txa
1d3a: 19 d0 3f ora HIRES_P1+$1fd0,y
1d3d: 99 d0 3f sta HIRES_P1+$1fd0,y
1d40: 60 rts
1d41: 60 a0 20 99+ .align $0100 (191 bytes)
.org $4000
;
; Offset to shape data. Add $4000.
shape_data_offset
4000: f1 13 .dd2 shape_cls_offs-$4000
********************************************************************************
* Musical sequences. *
* *
* Each sequence starts with a four byte header: *
* +$00-01: global duration; affects speed of entire sequence *
* +$02-03: unused *
* *
* After that is a series of 4-byte entries: *
* +$00: pitch of voice #0 *
* +$01: pitch of voice #1 *
* +$02: pitch of voice #2 *
* +$03: note duration *
* *
* Setting all three voices to the same value provides a steady tone. The *
* pitch values are indices into the table at $4012, which are used to *
* increment three counters. Higher values equate to higher pitches. *
* *
* The duration is an iteration count; the total iterations performed is equal *
* to (note_duration * global_duration). *
* *
* The table below holds offsets to the seven defined music sequences. Add *
* $4000. *
********************************************************************************
4002: 77 07 music_offset .dd2 music_00-$4000 ;$00
4004: 13 04 .dd2 music_01-$4000 ;$01
4006: 0f 07 .dd2 music_02-$4000 ;$02
4008: 33 07 .dd2 music_03-$4000 ;$03
400a: 67 07 .dd2 music_04-$4000 ;$04
400c: cb 00 .dd2 music_05-$4000 ;$05
400e: b3 03 .dd2 music_06-$4000 ;$06
4010: 33 07 .dd2 music_03-$4000 ;$07 (same as $03)
;
; Musical note value table. The first three entries in the 4-bytes-per-entry
; music tables are indexes into this.
;
; There are 73 valid-looking entries ($00-48). The highest actually used is
; $3d.
4012: 00 00 note_values .dd2 $0000
4014: 00 02 .dd2 $0200
4016: 1e 02 .dd2 $021e
4018: 40 02 .dd2 $0240
401a: 61 02 .dd2 $0261
401c: 88 02 .dd2 $0288
401e: ab 02 .dd2 $02ab
4020: d4 02 .dd2 $02d4
4022: 00 03 .dd2 $0300
4024: 2c 03 .dd2 $032c
4026: 5d 03 .dd2 $035d
4028: 90 03 .dd2 $0390
402a: 9f 03 .dd2 $039f
402c: 00 04 .dd2 $0400
402e: 3c 04 .dd2 $043c
4030: 80 04 .dd2 $0480
4032: c2 04 .dd2 $04c2
4034: 10 05 .dd2 $0510
4036: 56 05 .dd2 $0556
4038: a8 05 .dd2 $05a8
403a: 00 06 .dd2 $0600
403c: 58 06 .dd2 $0658
403e: ba 06 .dd2 $06ba
4040: 20 07 .dd2 $0720
4042: 8e 07 .dd2 $078e
4044: 00 08 .dd2 $0800
4046: 78 08 .dd2 $0878
4048: 00 09 .dd2 $0900
404a: 84 09 .dd2 $0984
404c: 20 0a .dd2 $0a20
404e: ac 0a .dd2 $0aac
4050: 50 0b .dd2 $0b50
4052: 00 0c .dd2 $0c00
4054: b0 0c .dd2 $0cb0
4056: 74 0d .dd2 $0d74
4058: 40 0e .dd2 $0e40
405a: 1c 0f .dd2 $0f1c
405c: 00 10 .dd2 $1000
405e: f0 10 .dd2 $10f0
4060: 00 12 .dd2 $1200
4062: 08 13 .dd2 $1308
4064: 40 14 .dd2 $1440
4066: 58 15 .dd2 $1558
4068: a0 16 .dd2 $16a0
406a: 00 18 .dd2 $1800
406c: 60 19 .dd2 $1960
406e: e8 1a .dd2 $1ae8
4070: 80 1c .dd2 $1c80
4072: 38 1e .dd2 $1e38
4074: 00 20 .dd2 $2000
4076: e0 21 .dd2 $21e0
4078: 00 24 .dd2 $2400
407a: 10 26 .dd2 $2610
407c: 80 28 .dd2 $2880
407e: b0 2a .dd2 $2ab0
4080: 40 2d .dd2 $2d40
4082: 00 30 .dd2 $3000
4084: c0 32 .dd2 $32c0
4086: d0 35 .dd2 $35d0
4088: 00 39 .dd2 $3900
408a: 70 3c .dd2 $3c70
408c: 00 40 .dd2 $4000
408e: c0 43 .dd2 $43c0
4090: 00 48 .dd2 $4800
4092: 20 4c .dd2 $4c20
4094: 00 51 .dd2 $5100
4096: 60 55 .dd2 $5560
4098: 80 5a .dd2 $5a80
409a: 00 60 .dd2 $6000
409c: 80 65 .dd2 $6580
409e: a0 6b .dd2 $6ba0
40a0: 00 72 .dd2 $7200
40a2: e0 78 .dd2 $78e0
40a4: 00 80 .dd2 $8000
40a6: 00 00 .dd2 $0000
40a8: 00 3d 3d 3d+ .junk 35
;
; Music sequence $05: game over (high score).
40cb: 2c 01 music_05 .dd2 $012c
40cd: 00 00 .dd2 $0000
40cf: 01 0d 19 02 .bulk $01,$0d,$19,$02
40d3: 02 0e 1a 02 .bulk $02,$0e,$1a,$02
40d7: 01 0d 19 02 .bulk $01,$0d,$19,$02
40db: 02 0e 1a 02 .bulk $02,$0e,$1a,$02
40df: 01 0d 19 02 .bulk $01,$0d,$19,$02
40e3: 02 0e 1a 02 .bulk $02,$0e,$1a,$02
40e7: 01 0d 19 02 .bulk $01,$0d,$19,$02
40eb: 02 0e 1a 02 .bulk $02,$0e,$1a,$02
40ef: 01 0d 19 02 .bulk $01,$0d,$19,$02
40f3: 02 0e 1a 02 .bulk $02,$0e,$1a,$02
40f7: 01 0d 19 02 .bulk $01,$0d,$19,$02
40fb: 02 0e 1a 02 .bulk $02,$0e,$1a,$02
40ff: 01 14 20 02 .bulk $01,$14,$20,$02
4103: 02 15 21 02 .bulk $02,$15,$21,$02
4107: 01 14 20 02 .bulk $01,$14,$20,$02
410b: 02 15 21 02 .bulk $02,$15,$21,$02
410f: 01 14 20 02 .bulk $01,$14,$20,$02
4113: 02 15 21 02 .bulk $02,$15,$21,$02
4117: 01 14 20 02 .bulk $01,$14,$20,$02
411b: 02 15 21 02 .bulk $02,$15,$21,$02
411f: 01 14 20 02 .bulk $01,$14,$20,$02
4123: 02 15 21 02 .bulk $02,$15,$21,$02
4127: 01 14 20 02 .bulk $01,$14,$20,$02
412b: 02 15 21 02 .bulk $02,$15,$21,$02
412f: 01 0d 25 02 .bulk $01,$0d,$25,$02
4133: 02 0e 26 02 .bulk $02,$0e,$26,$02
4137: 01 0d 25 02 .bulk $01,$0d,$25,$02
413b: 02 0e 26 02 .bulk $02,$0e,$26,$02
413f: 01 0d 25 02 .bulk $01,$0d,$25,$02
4143: 02 0e 26 02 .bulk $02,$0e,$26,$02
4147: 01 0d 25 02 .bulk $01,$0d,$25,$02
414b: 02 0e 26 02 .bulk $02,$0e,$26,$02
414f: 01 0d 25 02 .bulk $01,$0d,$25,$02
4153: 02 0e 26 02 .bulk $02,$0e,$26,$02
4157: 01 0d 25 02 .bulk $01,$0d,$25,$02
415b: 02 0e 26 02 .bulk $02,$0e,$26,$02
415f: 01 0d 25 02 .bulk $01,$0d,$25,$02
4163: 02 0e 26 02 .bulk $02,$0e,$26,$02
4167: 01 0d 25 02 .bulk $01,$0d,$25,$02
416b: 02 0e 26 02 .bulk $02,$0e,$26,$02
416f: 01 0d 25 02 .bulk $01,$0d,$25,$02
4173: 02 0e 26 02 .bulk $02,$0e,$26,$02
4177: 01 0d 25 02 .bulk $01,$0d,$25,$02
417b: 02 0e 26 02 .bulk $02,$0e,$26,$02
417f: 01 0d 25 02 .bulk $01,$0d,$25,$02
4183: 02 0e 26 02 .bulk $02,$0e,$26,$02
4187: 01 0d 25 02 .bulk $01,$0d,$25,$02
418b: 20 25 29 03 .bulk $20,$25,$29,$03
418f: 20 25 28 18 .bulk $20,$25,$28,$18
4193: 20 25 28 1c .bulk $20,$25,$28,$1c
4197: 08 08 08 04 .bulk $08,$08,$08,$04
419b: 01 01 01 04 .bulk $01,$01,$01,$04
419f: 08 08 08 04 .bulk $08,$08,$08,$04
41a3: 01 01 01 04 .bulk $01,$01,$01,$04
41a7: 08 08 08 04 .bulk $08,$08,$08,$04
41ab: 01 01 01 04 .bulk $01,$01,$01,$04
41af: 08 08 08 04 .bulk $08,$08,$08,$04
41b3: 01 01 01 04 .bulk $01,$01,$01,$04
41b7: 08 08 08 04 .bulk $08,$08,$08,$04
41bb: 01 01 01 04 .bulk $01,$01,$01,$04
41bf: 08 08 08 04 .bulk $08,$08,$08,$04
41c3: 01 0d 19 02 .bulk $01,$0d,$19,$02
41c7: 02 0e 1a 02 .bulk $02,$0e,$1a,$02
41cb: 01 0d 19 02 .bulk $01,$0d,$19,$02
41cf: 02 0e 1a 02 .bulk $02,$0e,$1a,$02
41d3: 01 0d 19 02 .bulk $01,$0d,$19,$02
41d7: 02 0e 1a 02 .bulk $02,$0e,$1a,$02
41db: 01 0d 19 02 .bulk $01,$0d,$19,$02
41df: 02 0e 1a 02 .bulk $02,$0e,$1a,$02
41e3: 01 0d 19 02 .bulk $01,$0d,$19,$02
41e7: 02 0e 1a 02 .bulk $02,$0e,$1a,$02
41eb: 01 0d 19 02 .bulk $01,$0d,$19,$02
41ef: 02 0e 1a 02 .bulk $02,$0e,$1a,$02
41f3: 01 14 20 02 .bulk $01,$14,$20,$02
41f7: 02 15 21 02 .bulk $02,$15,$21,$02
41fb: 01 14 20 02 .bulk $01,$14,$20,$02
41ff: 02 15 21 02 .bulk $02,$15,$21,$02
4203: 01 14 20 02 .bulk $01,$14,$20,$02
4207: 02 15 21 02 .bulk $02,$15,$21,$02
420b: 01 14 20 02 .bulk $01,$14,$20,$02
420f: 02 15 21 02 .bulk $02,$15,$21,$02
4213: 01 14 20 02 .bulk $01,$14,$20,$02
4217: 02 15 21 02 .bulk $02,$15,$21,$02
421b: 01 14 20 02 .bulk $01,$14,$20,$02
421f: 02 15 21 02 .bulk $02,$15,$21,$02
4223: 01 0d 25 02 .bulk $01,$0d,$25,$02
4227: 02 0e 26 02 .bulk $02,$0e,$26,$02
422b: 01 0d 25 02 .bulk $01,$0d,$25,$02
422f: 02 0e 26 02 .bulk $02,$0e,$26,$02
4233: 01 0d 25 02 .bulk $01,$0d,$25,$02
4237: 02 0e 26 02 .bulk $02,$0e,$26,$02
423b: 01 0d 25 02 .bulk $01,$0d,$25,$02
423f: 02 0e 26 02 .bulk $02,$0e,$26,$02
4243: 01 0d 25 02 .bulk $01,$0d,$25,$02
4247: 02 0e 26 02 .bulk $02,$0e,$26,$02
424b: 01 0d 25 02 .bulk $01,$0d,$25,$02
424f: 02 0e 26 02 .bulk $02,$0e,$26,$02
4253: 01 0d 25 02 .bulk $01,$0d,$25,$02
4257: 02 0e 26 02 .bulk $02,$0e,$26,$02
425b: 01 0d 25 02 .bulk $01,$0d,$25,$02
425f: 02 0e 26 02 .bulk $02,$0e,$26,$02
4263: 01 0d 25 02 .bulk $01,$0d,$25,$02
4267: 02 0e 26 02 .bulk $02,$0e,$26,$02
426b: 01 0d 25 02 .bulk $01,$0d,$25,$02
426f: 02 0e 26 02 .bulk $02,$0e,$26,$02
4273: 01 0d 25 02 .bulk $01,$0d,$25,$02
4277: 02 0e 26 02 .bulk $02,$0e,$26,$02
427b: 01 0d 25 02 .bulk $01,$0d,$25,$02
427f: 00 28 2c 03 .bulk $00,$28,$2c,$03
4283: 29 2c 31 18 .bulk $29,$2c,$31,$18
4287: 29 2c 31 1c .bulk $29,$2c,$31,$1c
428b: 08 08 08 04 .bulk $08,$08,$08,$04
428f: 01 01 01 04 .bulk $01,$01,$01,$04
4293: 08 08 08 04 .bulk $08,$08,$08,$04
4297: 01 01 01 04 .bulk $01,$01,$01,$04
429b: 08 08 08 04 .bulk $08,$08,$08,$04
429f: 01 01 01 04 .bulk $01,$01,$01,$04
42a3: 08 08 08 04 .bulk $08,$08,$08,$04
42a7: 01 01 01 04 .bulk $01,$01,$01,$04
42ab: 08 08 08 04 .bulk $08,$08,$08,$04
42af: 01 01 01 04 .bulk $01,$01,$01,$04
42b3: 08 08 08 04 .bulk $08,$08,$08,$04
42b7: 01 0d 19 18 .bulk $01,$0d,$19,$18
42bb: 01 14 20 18 .bulk $01,$14,$20,$18
42bf: 01 0d 25 2d .bulk $01,$0d,$25,$2d
42c3: 20 25 29 03 .bulk $20,$25,$29,$03
42c7: 25 2a 2e 30 .bulk $25,$2a,$2e,$30
42cb: 22 2a 2e 03 .bulk $22,$2a,$2e,$03
42cf: 24 2c 30 03 .bulk $24,$2c,$30,$03
42d3: 05 2e 31 1e .bulk $05,$2e,$31,$1e
42d7: 2a 2d 33 0c .bulk $2a,$2d,$33,$0c
42db: 2c 31 35 06 .bulk $2c,$31,$35,$06
42df: 2a 33 36 06 .bulk $2a,$33,$36,$06
42e3: 2c 31 38 06 .bulk $2c,$31,$38,$06
42e7: 29 31 38 06 .bulk $29,$31,$38,$06
42eb: 25 31 38 06 .bulk $25,$31,$38,$06
42ef: 20 31 38 06 .bulk $20,$31,$38,$06
42f3: 1d 31 38 06 .bulk $1d,$31,$38,$06
42f7: 07 31 35 03 .bulk $07,$31,$35,$03
42fb: 07 33 36 03 .bulk $07,$33,$36,$03
42ff: 0d 35 38 18 .bulk $0d,$35,$38,$18
4303: 11 31 3a 0c .bulk $11,$31,$3a,$0c
4307: 08 33 3c 0c .bulk $08,$33,$3c,$0c
430b: 0d 35 3d 30 .bulk $0d,$35,$3d,$30
430f: 00 00 00 00 .bulk $00,$00,$00,$00
;
; Junk; copy of first part of music sequence $01.
4313: fa 00 00 00+ .junk 160
;
; Music sequence $06: exit time portal (max time).
43b3: fa 00 music_06 .dd2 $00fa
43b5: 00 00 .dd2 $0000
43b7: 00 1b 20 01 .bulk $00,$1b,$20,$01
43bb: 00 1b 22 01 .bulk $00,$1b,$22,$01
43bf: 00 1d 24 01 .bulk $00,$1d,$24,$01
43c3: 00 1d 25 01 .bulk $00,$1d,$25,$01
43c7: 27 27 27 02 .bulk $27,$27,$27,$02
43cb: 29 29 29 02 .bulk $29,$29,$29,$02
43cf: 27 27 27 02 .bulk $27,$27,$27,$02
43d3: 29 29 29 02 .bulk $29,$29,$29,$02
43d7: 27 27 27 02 .bulk $27,$27,$27,$02
43db: 29 29 29 02 .bulk $29,$29,$29,$02
43df: 27 27 27 02 .bulk $27,$27,$27,$02
43e3: 29 29 29 02 .bulk $29,$29,$29,$02
43e7: 27 27 27 02 .bulk $27,$27,$27,$02
43eb: 29 29 29 02 .bulk $29,$29,$29,$02
43ef: 27 27 27 02 .bulk $27,$27,$27,$02
43f3: 29 29 29 02 .bulk $29,$29,$29,$02
43f7: 27 27 27 02 .bulk $27,$27,$27,$02
43fb: 29 29 29 02 .bulk $29,$29,$29,$02
43ff: 27 27 27 02 .bulk $27,$27,$27,$02
4403: 29 29 29 02 .bulk $29,$29,$29,$02
4407: 27 27 27 02 .bulk $27,$27,$27,$02
440b: 29 29 29 02 .bulk $29,$29,$29,$02
440f: 00 00 00 00 .bulk $00,$00,$00,$00
;
; Music sequence $01: start of game.
4413: fa 00 music_01 .dd2 $00fa
4415: 00 00 .dd2 $0000
4417: 08 08 08 01 .bulk $08,$08,$08,$01
441b: 0a 0a 0a 01 .bulk $0a,$0a,$0a,$01
441f: 0c 0c 0c 01 .bulk $0c,$0c,$0c,$01
4423: 0d 0d 0d 01 .bulk $0d,$0d,$0d,$01
4427: 0f 0f 0f 02 .bulk $0f,$0f,$0f,$02
442b: 11 11 11 02 .bulk $11,$11,$11,$02
442f: 0f 0f 0f 02 .bulk $0f,$0f,$0f,$02
4433: 11 11 11 02 .bulk $11,$11,$11,$02
4437: 0f 0f 0f 02 .bulk $0f,$0f,$0f,$02
443b: 11 11 11 02 .bulk $11,$11,$11,$02
443f: 0f 0f 0f 02 .bulk $0f,$0f,$0f,$02
4443: 11 11 11 02 .bulk $11,$11,$11,$02
4447: 0f 0f 0f 02 .bulk $0f,$0f,$0f,$02
444b: 11 11 11 02 .bulk $11,$11,$11,$02
444f: 0f 0f 0f 02 .bulk $0f,$0f,$0f,$02
4453: 11 11 11 02 .bulk $11,$11,$11,$02
4457: 0f 0f 0f 02 .bulk $0f,$0f,$0f,$02
445b: 11 11 11 02 .bulk $11,$11,$11,$02
445f: 0f 0f 0f 02 .bulk $0f,$0f,$0f,$02
4463: 11 11 11 02 .bulk $11,$11,$11,$02
4467: 0f 14 00 01 .bulk $0f,$14,$00,$01
446b: 0f 16 00 01 .bulk $0f,$16,$00,$01
446f: 11 18 00 01 .bulk $11,$18,$00,$01
4473: 11 19 00 01 .bulk $11,$19,$00,$01
4477: 1b 1b 00 02 .bulk $1b,$1b,$00,$02
447b: 1d 1d 00 02 .bulk $1d,$1d,$00,$02
447f: 1b 1b 00 02 .bulk $1b,$1b,$00,$02
4483: 1d 1d 00 02 .bulk $1d,$1d,$00,$02
4487: 1b 1b 00 02 .bulk $1b,$1b,$00,$02
448b: 1d 1d 00 02 .bulk $1d,$1d,$00,$02
448f: 1b 1b 00 02 .bulk $1b,$1b,$00,$02
4493: 1d 1d 00 02 .bulk $1d,$1d,$00,$02
4497: 1b 1b 00 02 .bulk $1b,$1b,$00,$02
449b: 1d 1d 00 02 .bulk $1d,$1d,$00,$02
449f: 1b 1b 00 02 .bulk $1b,$1b,$00,$02
44a3: 1d 1d 00 02 .bulk $1d,$1d,$00,$02
44a7: 1b 1b 00 02 .bulk $1b,$1b,$00,$02
44ab: 1d 1d 00 02 .bulk $1d,$1d,$00,$02
44af: 1b 1b 00 02 .bulk $1b,$1b,$00,$02
44b3: 1d 1d 00 02 .bulk $1d,$1d,$00,$02
44b7: 00 1b 20 01 .bulk $00,$1b,$20,$01
44bb: 00 1b 22 01 .bulk $00,$1b,$22,$01
44bf: 00 1d 24 01 .bulk $00,$1d,$24,$01
44c3: 00 1d 25 01 .bulk $00,$1d,$25,$01
44c7: 27 27 27 02 .bulk $27,$27,$27,$02
44cb: 29 29 29 02 .bulk $29,$29,$29,$02
44cf: 27 27 27 02 .bulk $27,$27,$27,$02
44d3: 29 29 29 02 .bulk $29,$29,$29,$02
44d7: 27 27 27 02 .bulk $27,$27,$27,$02
44db: 29 29 29 02 .bulk $29,$29,$29,$02
44df: 27 27 27 02 .bulk $27,$27,$27,$02
44e3: 29 29 29 02 .bulk $29,$29,$29,$02
44e7: 27 27 27 02 .bulk $27,$27,$27,$02
44eb: 29 29 29 02 .bulk $29,$29,$29,$02
44ef: 27 27 27 02 .bulk $27,$27,$27,$02
44f3: 29 29 29 02 .bulk $29,$29,$29,$02
44f7: 27 27 27 02 .bulk $27,$27,$27,$02
44fb: 29 29 29 02 .bulk $29,$29,$29,$02
44ff: 27 27 27 02 .bulk $27,$27,$27,$02
4503: 29 29 29 02 .bulk $29,$29,$29,$02
4507: 27 27 27 02 .bulk $27,$27,$27,$02
450b: 29 29 29 02 .bulk $29,$29,$29,$02
450f: 27 27 27 02 .bulk $27,$27,$27,$02
4513: 29 29 29 02 .bulk $29,$29,$29,$02
4517: 27 27 27 02 .bulk $27,$27,$27,$02
451b: 29 29 29 02 .bulk $29,$29,$29,$02
451f: 27 27 27 02 .bulk $27,$27,$27,$02
4523: 29 29 29 02 .bulk $29,$29,$29,$02
4527: 27 27 27 02 .bulk $27,$27,$27,$02
452b: 29 29 29 02 .bulk $29,$29,$29,$02
452f: 00 00 00 00 .bulk $00,$00,$00,$00
;
; Junk, vaguely musical.
4533: 12 12 00 06+ .bulk $12,$12,$00,$06,$0d,$0d,$00,$02,$12,$14,$00,$01,$12,$16,$00,$01
+ $12,$18,$00,$01,$12,$19,$00,$01,$16,$16,$00,$02,$16,$16,$00,$02
+ $16,$16,$00,$02,$16,$16,$00,$02,$16,$00,$14,$01,$16,$00,$16,$01
+ $16,$00,$18,$01,$16,$00,$19,$01,$12,$00,$1e,$02,$12,$00,$1e,$02
+ $12,$00,$1e,$02,$12,$00,$1e,$02,$12,$00,$1e,$02,$12,$00,$1e,$02
+ $16,$16,$00,$06,$12,$12,$00,$02,$16,$14,$00,$01,$16,$16,$00,$01
+ $16,$18,$00,$01,$16,$19,$00,$01,$19,$19,$00,$02,$19,$19,$00,$02
+ $19,$19,$00,$02,$19,$19,$00,$02,$19,$19,$20,$01,$19,$19,$22,$01
+ $19,$19,$24,$01,$19,$19,$25,$01,$16,$00,$22,$02,$16,$00,$22,$02
+ $16,$00,$22,$02,$16,$00,$22,$02,$16,$00,$22,$02,$16,$00,$22,$02
+ $19,$19,$00,$06,$16,$16,$00,$02,$19,$00,$18,$01,$19,$00,$1a,$01
+ $19,$00,$1b,$01,$19,$00,$1d,$01,$1d,$1d,$00,$08,$1d,$00,$18,$01
+ $1d,$00,$1a,$01,$1d,$00,$1b,$01,$1d,$00,$1d,$01,$11,$11,$00,$08
+ $11,$00,$1f,$01,$11,$00,$1d,$01,$11,$00,$1c,$01,$11,$00,$1a,$01
+ $16,$16,$00,$02,$16,$16,$00,$02,$16,$16,$00,$02,$11,$11,$00,$02
+ $16,$00,$16,$01,$16,$00,$13,$01,$16,$00,$15,$01,$16,$00,$17,$01
+ $1a,$11,$0a,$0c,$1a,$11,$0a,$0c,$00,$00,$00,$00
;
; Junk; copy of first part of "game over, new high score" music.
463f: 40 01 00 00+ .bulk $40,$01,$00,$00,$01,$0d,$19,$02,$02,$0e,$1a,$02,$01,$0d,$19,$02
+ $02,$0e,$1a,$02,$01,$0d,$19,$02,$02,$0e,$1a,$02,$01,$0d,$19,$02
+ $02,$0e,$1a,$02,$01,$0d,$19,$02,$02,$0e,$1a,$02,$01,$0d,$19,$02
+ $02,$0e,$1a,$02,$01,$14,$20,$02,$02,$15,$21,$02,$01,$14,$20,$02
+ $02,$15,$21,$02,$01,$14,$20,$02,$02,$15,$21,$02,$01,$14,$20,$02
+ $02,$15,$21,$02,$01,$14,$20,$02,$02,$15,$21,$02,$01,$14,$20,$02
+ $02,$15,$21,$02,$01,$0d,$25,$02,$02,$0e,$26,$02,$01,$0d,$25,$02
+ $02,$0e,$26,$02,$01,$0d,$25,$02,$02,$0e,$26,$02,$01,$0d,$25,$02
+ $02,$0e,$26,$02,$01,$0d,$25,$02,$02,$0e,$26,$02,$01,$0d,$25,$02
+ $02,$0e,$26,$02,$01,$0d,$25,$02,$02,$0e,$26,$02,$01,$0d,$25,$02
+ $02,$0e,$26,$02,$01,$0d,$25,$02,$02,$0e,$26,$02,$01,$0d,$25,$02
+ $02,$0e,$26,$02,$01,$0d,$25,$02,$02,$0e,$26,$02,$01,$0d,$25,$02
+ $02,$0e,$26,$03,$20,$25,$29,$03,$20,$25,$28,$1e,$00,$00,$00,$00
;
; Music sequence $02: enter time portal.
470f: 40 01 music_02 .dd2 $0140
4711: 00 00 .dd2 $0000
4713: 22 2a 2e 03 .bulk $22,$2a,$2e,$03
4717: 24 2c 30 03 .bulk $24,$2c,$30,$03
471b: 05 2e 31 1e .bulk $05,$2e,$31,$1e
471f: 2a 2d 33 0c .bulk $2a,$2d,$33,$0c
4723: 2c 31 35 06 .bulk $2c,$31,$35,$06
4727: 2a 33 36 06 .bulk $2a,$33,$36,$06
472b: 2c 31 38 18 .bulk $2c,$31,$38,$18
472f: 00 00 00 00 .bulk $00,$00,$00,$00
;
; Music sequence $03: enemy base destroyed.
4733: 38 00 music_03 .dd2 $0038
4735: 00 00 .dd2 $0000
4737: 2a 2a 2a 01 .bulk $2a,$2a,$2a,$01
473b: 29 29 29 01 .bulk $29,$29,$29,$01
473f: 27 27 27 01 .bulk $27,$27,$27,$01
4743: 25 25 25 01 .bulk $25,$25,$25,$01
4747: 24 24 24 01 .bulk $24,$24,$24,$01
474b: 22 22 22 01 .bulk $22,$22,$22,$01
474f: 20 20 20 01 .bulk $20,$20,$20,$01
4753: 1e 1e 1e 01 .bulk $1e,$1e,$1e,$01
4757: 1d 1d 1d 01 .bulk $1d,$1d,$1d,$01
475b: 1b 1b 1b 01 .bulk $1b,$1b,$1b,$01
475f: 19 19 19 01 .bulk $19,$19,$19,$01
4763: 00 00 00 00 .bulk $00,$00,$00,$00
;
; Music sequence $04: fly through friendly base.
4767: f4 01 music_04 .dd2 $01f4
4769: 00 00 .dd2 $0000
476b: 20 25 29 03 .bulk $20,$25,$29,$03
476f: 25 2a 2e 09 .bulk $25,$2a,$2e,$09
4773: 00 00 00 00 .bulk $00,$00,$00,$00
;
; Music sequence $00: game over (not high score).
4777: 40 01 00 00 music_00 .bulk $40,$01,$00,$00
477b: 01 0d 19 18 .bulk $01,$0d,$19,$18
477f: 01 14 20 18 .bulk $01,$14,$20,$18
4783: 01 0d 25 2d .bulk $01,$0d,$25,$2d
4787: 20 25 29 03 .bulk $20,$25,$29,$03
478b: 25 2a 2e 30 .bulk $25,$2a,$2e,$30
478f: 00 00 00 00 .bulk $00,$00,$00,$00
********************************************************************************
* Shape definitions. Shapes are organized into classes, e.g. all enemy ships *
* are in one class, all enemy bases are in another. For each region of space *
* there is a limit to the number of objects from a given class. Only shapes *
* from classes 0-7 can be spawned; classes 8-10 are used for player *
* projectiles and explosions. *
* *
* The data here is only referenced when an object is created. At creation *
* time it's "unpacked" into various tables. *
* *
* The first byte of the class definition is an AND mask that is applied to the *
* shape index. It determines the maximum number of variants that there can be *
* in the table, and can be used to get an odd/even effect. The second byte is *
* unused. This is followed by a series of 16-bit offsets (from $4000) that *
* specify the start of the shapes. *
* *
* Each shape begins with a 24-byte header: *
* +$00: number of elements in shape *
* +$01: lifespan, used for explosion flares and one of the chunks *
* +$02: score class (1-7, or 0 if not enemy ship or base) *
* +$03: unique identifier (e.g. time warp is $6f) *
* +$04: activity class: 0 for most things, 1 for player projectiles and *
* explosion flares, 2 for explosion chunks, 3 for enemy ships (not bases) *
* +$05: 4 for player projectiles, 0 for everything else *
* +$06: nonzero for enemy ships; affects how frequently they can change *
* direction *
* +$07: determines method of selecting initial position; value is $00 for *
* ships/bases/stars, $01/02 for enemy projectiles, $7e for explosion chunks, *
* $7f for portal boundaries, $ff for Epoch logo and player projectile *
* +$08-09: minimum initial Z position *
* +$0a-0b: maximum initial Z position *
* +$0c-0e: unused, almost always zero *
* +$0f-10: hitbox size; also used as initial position modifier, when creating *
* object not at edge *
* +$11-12: maximum Z speed *
* +$13-14: maximum X speed, only nonzero for explosions/flare *
* +$15-16: maximum Y speed, only nonzero for explosions/flare *
* +$17: unused, always zero *
* *
* The shape header is followed by the elements, 16 bytes each: *
* +$00: element type *
* $00=point *
* $01=horizontal line *
* $80=rect *
* $ff=vertical line *
* +$01: color A *
* +$02: color B *
* $00=black *
* $10=white (single-pixel) *
* $20=green *
* $30=purple *
* $40=orange *
* $50=blue *
* $60=white (double-pixel) *
* >=$80 ($ff) = do not draw *
* +$03: color change frequency; 0=only color A used *
* +$04-05: Z offset, +value away from viewer (16-bit signed) *
* +$06-07: left (16-bit signed) *
* +$08-09: top (16-bit signed) *
* +$0a-0b: right (16-bit signed) *
* +$0c-0d: bottom (16-bit signed) *
* +$0e-0f: unused, always zero *
* *
* All coordinates are inclusive. Negative values are up and to the left. *
* *
* Color values are used as the high nibble of an index into a color table with *
* $70 entries. *
********************************************************************************
4793: 00 00 .junk 2
;
; Shape class $00: EPOCH logo.
;
; All of the elements have a +$1000 Z offset, which moves everything farther
; from the viewer.
;
4795: 00 shape_00 .dd1 %00000000 ;1 entry
4796: 00 .dd1 $00
4797: 99 07 .dd2 shape_00_0-$4000
4799: 13 00 00 01+ shape_00_0 .bulk $13,$00,$00,$01,$00,$00,$00,$ff,$00,$0f,$00,$10,$00,$00,$00,$c0
+ $01,$00,$00,$00,$00,$00,$00,$00
47b1: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$10,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
47c1: 80 40 00 00+ .bulk $80,$40,$00,$00,$00,$10,$80,$fc,$00,$ff,$c0,$fc,$00,$01,$00,$00
47d1: 80 40 00 00+ .bulk $80,$40,$00,$00,$00,$10,$c0,$fc,$00,$ff,$80,$fd,$40,$ff,$00,$00
47e1: 80 40 00 00+ .bulk $80,$40,$00,$00,$00,$10,$c0,$fc,$e0,$ff,$40,$fd,$20,$00,$00,$00
47f1: 80 40 00 00+ .bulk $80,$40,$00,$00,$00,$10,$c0,$fc,$c0,$00,$80,$fd,$00,$01,$00,$00
4801: 80 40 00 00+ .bulk $80,$40,$00,$00,$00,$10,$00,$fe,$00,$ff,$40,$fe,$00,$01,$00,$00
4811: 80 40 00 00+ .bulk $80,$40,$00,$00,$00,$10,$c0,$fe,$00,$ff,$00,$ff,$00,$00,$00,$00 ;'P' right vertical ($481d should be $20?)
4821: 80 40 00 00+ .bulk $80,$40,$00,$00,$00,$10,$40,$fe,$e0,$ff,$c0,$fe,$20,$00,$00,$00 ;'P' lower horizontal
4831: 80 40 00 00+ .bulk $80,$40,$00,$00,$00,$10,$40,$fe,$00,$ff,$c0,$fe,$40,$ff,$00,$00
4841: 80 40 00 00+ .bulk $80,$40,$00,$00,$00,$10,$80,$ff,$00,$ff,$c0,$ff,$00,$01,$00,$00
4851: 80 40 00 00+ .bulk $80,$40,$00,$00,$00,$10,$40,$00,$00,$ff,$80,$00,$00,$01,$00,$00
4861: 80 40 00 00+ .bulk $80,$40,$00,$00,$00,$10,$c0,$ff,$00,$ff,$40,$00,$40,$ff,$00,$00
4871: 80 40 00 00+ .bulk $80,$40,$00,$00,$00,$10,$c0,$ff,$c0,$00,$40,$00,$00,$01,$00,$00
4881: 80 40 00 00+ .bulk $80,$40,$00,$00,$00,$10,$00,$01,$00,$ff,$40,$01,$00,$01,$00,$00 ;'C' vertical
4891: 80 40 00 00+ .bulk $80,$40,$00,$00,$00,$10,$40,$01,$00,$ff,$00,$02,$40,$ff,$00,$00
48a1: 80 40 00 00+ .bulk $80,$40,$00,$00,$00,$10,$40,$01,$c0,$00,$00,$02,$00,$01,$00,$00
48b1: 80 40 00 00+ .bulk $80,$40,$00,$00,$00,$10,$80,$02,$00,$ff,$c0,$02,$00,$01,$00,$00
48c1: 80 40 00 00+ .bulk $80,$40,$00,$00,$00,$10,$40,$03,$00,$ff,$80,$03,$00,$01,$00,$00
48d1: 80 40 00 00+ .bulk $80,$40,$00,$00,$00,$10,$c0,$02,$e0,$ff,$40,$03,$20,$00,$00,$00 ;'H' horizontal ($48d7 should be $80?)
;
; Shape class $01: enemy bases.
;
; There are more entries for the 300-point base, which makes it more likely to
; appear.
;
48e1: 03 shape_01 .dd1 %00000011 ;4 entries
48e2: 00 .dd1 $00
48e3: b9 09 .dd2 shape_01_1-$4000
48e5: f1 08 .dd2 shape_01_0-$4000
48e7: b9 09 .dd2 shape_01_1-$4000
48e9: b9 09 .dd2 shape_01_1-$4000
48eb: 00 00 00 00+ .junk 6
48f1: 0b 00 07 11+ shape_01_0 .bulk $0b,$00,$07,$11,$00,$00,$00,$00,$00,$10,$00,$70,$00,$00,$00,$0f
+ $00,$00,$00,$00,$00,$00,$00,$00
4909: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
4919: 01 20 00 00+ .bulk $01,$20,$00,$00,$00,$00,$80,$fe,$d0,$ff,$80,$01,$d0,$ff,$00,$00
4929: 01 20 00 00+ .bulk $01,$20,$00,$00,$00,$00,$80,$fe,$e8,$ff,$80,$01,$e8,$ff,$00,$00
4939: 01 20 00 00+ .bulk $01,$20,$00,$00,$00,$00,$80,$fe,$00,$00,$80,$01,$00,$00,$00,$00
4949: 01 20 00 00+ .bulk $01,$20,$00,$00,$00,$00,$80,$fe,$18,$00,$80,$01,$18,$00,$00,$00
4959: 01 20 00 00+ .bulk $01,$20,$00,$00,$00,$00,$80,$fe,$30,$00,$80,$01,$30,$00,$00,$00
4969: ff 60 00 00+ .bulk $ff,$60,$00,$00,$00,$00,$00,$ff,$a0,$ff,$00,$ff,$60,$00,$00,$00
4979: ff 60 00 00+ .bulk $ff,$60,$00,$00,$00,$00,$00,$01,$a0,$ff,$00,$01,$60,$00,$00,$00
4989: 01 60 00 00+ .bulk $01,$60,$00,$00,$00,$00,$00,$ff,$a0,$ff,$00,$01,$a0,$ff,$00,$00
4999: 01 60 00 00+ .bulk $01,$60,$00,$00,$00,$00,$00,$ff,$60,$00,$00,$01,$60,$00,$00,$00
49a9: 80 60 00 01+ .bulk $80,$60,$00,$01,$00,$00,$e0,$ff,$e0,$ff,$20,$00,$20,$00,$00,$00
49b9: 0a 00 06 12+ shape_01_1 .bulk $0a,$00,$06,$12,$00,$00,$00,$00,$00,$10,$00,$50,$00,$00,$00,$10
+ $00,$00,$00,$00,$00,$00,$00,$00
49d1: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
49e1: 80 60 00 01+ .bulk $80,$60,$00,$01,$00,$00,$e0,$ff,$e0,$ff,$20,$00,$20,$00,$00,$00
49f1: 80 20 00 00+ .bulk $80,$20,$00,$00,$00,$00,$b0,$fe,$b0,$ff,$80,$ff,$50,$00,$00,$00
4a01: 80 20 00 00+ .bulk $80,$20,$00,$00,$00,$00,$80,$00,$b0,$ff,$50,$01,$50,$00,$00,$00
4a11: ff 50 00 00+ .bulk $ff,$50,$00,$00,$00,$00,$00,$00,$a0,$ff,$00,$00,$60,$00,$00,$00
4a21: 80 50 00 00+ .bulk $80,$50,$00,$00,$00,$00,$60,$fe,$00,$ff,$a0,$01,$b0,$ff,$00,$00
4a31: 80 50 00 00+ .bulk $80,$50,$00,$00,$00,$00,$60,$fe,$50,$00,$a0,$01,$00,$01,$00,$00
4a41: ff 40 00 00+ .bulk $ff,$40,$00,$00,$00,$00,$00,$00,$00,$01,$00,$00,$80,$01,$00,$00
4a51: 01 40 00 02+ .bulk $01,$40,$00,$02,$00,$00,$20,$ff,$60,$01,$e0,$00,$60,$01,$00,$00
4a61: 01 40 00 01+ .bulk $01,$40,$00,$01,$00,$00,$40,$ff,$30,$01,$c0,$00,$30,$01,$00,$00
;
; Shape class $02: enemy ships + time portal.
;
4a71: 07 shape_02 .dd1 %00000111 ;8 entries
4a72: 00 .dd1 $00
4a73: 91 0a .dd2 shape_02_0-$4000
4a75: 29 0b .dd2 shape_02_1-$4000
4a77: d9 0b .dd2 shape_02_3-$4000
4a79: 29 0b .dd2 shape_02_1-$4000
4a7b: 31 0c .dd2 shape_02_4-$4000
4a7d: d9 0b .dd2 shape_02_3-$4000
4a7f: 81 0b .dd2 shape_02_2-$4000
4a81: 81 0b .dd2 shape_02_2-$4000
4a83: 00 00 00 00+ .junk 14
; The second rect/line set has a small Z offset, which moves it farther from the
; viewer. This seems backward, since those parts are drawn last.
4a91: 08 00 05 e1+ shape_02_0 .bulk $08,$00,$05,$e1,$03,$00,$0f,$00,$00,$01,$00,$20,$00,$00,$00,$00
+ $01,$00,$04,$00,$00,$00,$00,$00
4aa9: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
4ab9: 80 30 00 00+ .bulk $80,$30,$00,$00,$00,$00,$a0,$ff,$a0,$ff,$60,$00,$60,$00,$00,$00
4ac9: 80 30 00 00+ .bulk $80,$30,$00,$00,$60,$00,$a0,$ff,$a0,$ff,$60,$00,$60,$00,$00,$00
4ad9: 01 20 00 00+ .bulk $01,$20,$00,$00,$00,$00,$00,$ff,$a0,$ff,$00,$01,$a0,$ff,$00,$00
4ae9: 01 20 00 00+ .bulk $01,$20,$00,$00,$00,$00,$00,$ff,$60,$00,$00,$01,$60,$00,$00,$00
4af9: 01 20 00 00+ .bulk $01,$20,$00,$00,$60,$00,$00,$ff,$a0,$ff,$00,$01,$60,$00,$00,$00
4b09: 01 20 00 00+ .bulk $01,$20,$00,$00,$60,$00,$00,$ff,$60,$00,$00,$01,$60,$00,$00,$00
4b19: 00 60 00 01+ .bulk $00,$60,$00,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
4b29: 04 00 02 21+ shape_02_1 .bulk $04,$00,$02,$21,$03,$00,$19,$00 ;$00-07
4b31: 00 04 .dd2 $0400 ;$08-09
4b33: 00 20 .dd2 $2000 ;$0a-0b
4b35: 00 00 00 .bulk $00,$00,$00 ;$0c-0e
4b38: c0 01 .dd2 $01c0 ;$0f-10
4b3a: 00 03 .dd2 $0300 ;$11-12
4b3c: 00 00 .dd2 $0000 ;$13-14
4b3e: 00 00 .dd2 $0000 ;$15-16
4b40: 00 .dd1 $00 ;$17
4b41: 80 50 00 00+ .bulk $80,$50,$00,$00,$00,$00,$a0,$ff,$90,$ff,$60,$00,$70,$00,$00,$00
4b51: ff 20 00 00+ .bulk $ff,$20,$00,$00,$00,$00,$00,$ff,$60,$ff,$00,$ff,$a0,$00,$00,$00
4b61: ff 20 00 00+ .bulk $ff,$20,$00,$00,$00,$00,$00,$01,$60,$ff,$00,$01,$a0,$00,$00,$00
4b71: 01 20 00 00+ .bulk $01,$20,$00,$00,$00,$00,$00,$ff,$00,$00,$00,$01,$00,$00,$00,$00
4b81: 04 00 03 22+ shape_02_2 .bulk $04,$00,$03,$22,$03,$00,$14,$00,$00,$04,$00,$20,$00,$00,$00,$40
+ $01,$00,$03,$00,$00,$00,$00,$00
4b99: 80 30 00 00+ .bulk $80,$30,$00,$00,$00,$00,$a0,$ff,$90,$ff,$60,$00,$70,$00,$00,$00
4ba9: ff 40 00 00+ .bulk $ff,$40,$00,$00,$00,$00,$00,$00,$60,$ff,$00,$00,$a0,$00,$00,$00
4bb9: 01 40 00 00+ .bulk $01,$40,$00,$00,$00,$00,$c0,$fe,$60,$ff,$40,$01,$60,$ff,$00,$00
4bc9: 01 40 00 00+ .bulk $01,$40,$00,$00,$00,$00,$c0,$fe,$a0,$00,$40,$01,$a0,$00,$00,$00
4bd9: 04 00 04 23+ shape_02_3 .bulk $04,$00,$04,$23,$03,$00,$28,$00,$00,$04,$00,$30,$00,$00,$00,$20
+ $01,$00,$02,$00,$00,$00,$00,$00
4bf1: 80 50 00 00+ .bulk $80,$50,$00,$00,$00,$00,$a0,$ff,$c0,$ff,$60,$00,$40,$00,$00,$00
4c01: 80 40 00 01+ .bulk $80,$40,$00,$01,$00,$00,$e0,$fe,$d0,$ff,$40,$ff,$30,$00,$00,$00
4c11: 80 40 00 01+ .bulk $80,$40,$00,$01,$00,$00,$c0,$00,$d0,$ff,$20,$01,$30,$00,$00,$00
4c21: 01 50 00 00+ .bulk $01,$50,$00,$00,$00,$00,$00,$ff,$00,$00,$00,$01,$00,$00,$00,$00
4c31: 05 00 00 6f+ shape_02_4 .bulk $05,$00,$00,$6f,$00,$00,$00,$00,$00,$10,$00,$60,$00,$00,$00,$20
+ $00,$00,$00,$00,$00,$00,$00,$00
4c49: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
4c59: 80 30 50 01+ .bulk $80,$30,$50,$01,$00,$00,$80,$ff,$c0,$fe,$e0,$ff,$40,$01,$00,$00
4c69: 80 40 20 02+ .bulk $80,$40,$20,$02,$00,$00,$20,$00,$c0,$fe,$80,$00,$40,$01,$00,$00
4c79: 80 20 10 01+ .bulk $80,$20,$10,$01,$00,$00,$c0,$fe,$80,$ff,$40,$01,$e0,$ff,$00,$00
4c89: 80 50 10 03+ .bulk $80,$50,$10,$03,$00,$00,$c0,$fe,$20,$00,$40,$01,$80,$00,$00,$00
;
; Shape class $03: enemy projectiles.
;
; The value at +$07 is matched with the ship class when matching projectiles
; with enemies, so the flashing orange/white object is fired by bases, and the
; solid orange object is fired by ships.
;
4c99: 02 shape_03 .dd1 %00000010 ;4 entries, even only
4c9a: 00 .dd1 $00
4c9b: a9 0c .dd2 shape_03_0-$4000
4c9d: d1 0c .dd2 shape_03_1-$4000 ;(unused)
4c9f: d1 0c .dd2 shape_03_1-$4000
4ca1: d1 0c .dd2 shape_03_1-$4000 ;(unused)
4ca3: 00 00 00 00+ .junk 6
4ca9: 01 00 00 31+ shape_03_0 .bulk $01,$00,$00,$31,$03,$00,$00,$01,$00,$02,$00,$40,$00,$00,$00,$20
+ $00,$00,$08,$00,$00,$00,$00,$00
4cc1: 80 40 10 01+ .bulk $80,$40,$10,$01,$00,$00,$e0,$ff,$e0,$ff,$20,$00,$20,$00,$00,$00
4cd1: 01 00 00 32+ shape_03_1 .bulk $01,$00,$00,$32,$03,$00,$00,$02,$00,$02,$00,$40,$00,$00,$00,$20
+ $00,$60,$07,$00,$00,$00,$00,$00
4ce9: 80 40 00 00+ .bulk $80,$40,$00,$00,$00,$00,$e0,$ff,$e0,$ff,$20,$00,$20,$00,$00,$00
;
; Shape class $04: reference back to shape $01_1 (300pt enemy base).
;
; This doesn't appear to be used -- the per-region limit tables at $708c all
; have zero for the 4th entry.
;
4cf9: 00 shape_04 .dd1 %00000000 ;1 entry
4cfa: 00 .dd1 $00
4cfb: b9 09 .dd2 shape_01_1-$4000
4cfd: 00 00 00 00+ .junk 12
;
; Shape class $05: time portal travel bounds.
;
4d09: 07 shape_05 .dd1 %00000111 ;8 entries
4d0a: 00 .dd1 $00
4d0b: 29 0d .dd2 shape_05_0-$4000
4d0d: 71 0d .dd2 shape_05_1-$4000
4d0f: b9 0d .dd2 shape_05_2-$4000
4d11: 01 0e .dd2 shape_05_3-$4000
4d13: a9 0e .dd2 shape_05_4-$4000
4d15: f1 0e .dd2 shape_05_5-$4000
4d17: 39 0f .dd2 shape_05_6-$4000
4d19: 71 0d .dd2 shape_05_1-$4000
4d1b: 00 00 00 00+ .junk 14
4d29: 03 00 00 51+ shape_05_0 .bulk $03,$00,$00,$51,$00,$00,$00,$7f,$00,$20,$00,$24,$00,$00,$00,$a0
+ $02,$00,$00,$00,$00,$00,$00,$00
4d41: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
4d51: 01 20 50 01+ .bulk $01,$20,$50,$01,$00,$00,$b0,$fd,$90,$fd,$90,$02,$90,$fd,$00,$00
4d61: 01 40 00 00+ .bulk $01,$40,$00,$00,$a0,$00,$70,$fd,$a0,$02,$80,$02,$a0,$02,$00,$00
4d71: 03 00 00 52+ shape_05_1 .bulk $03,$00,$00,$52,$00,$00,$00,$7f,$00,$20,$00,$24,$00,$00,$00,$e0
+ $02,$00,$00,$00,$00,$00,$00,$00
4d89: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
4d99: 01 50 10 01+ .bulk $01,$50,$10,$01,$00,$00,$e0,$fd,$40,$fd,$e0,$02,$40,$fd,$00,$00
4da9: 01 30 00 00+ .bulk $01,$30,$00,$00,$c0,$00,$20,$fd,$30,$02,$f0,$02,$30,$02,$00,$00
4db9: 03 00 00 53+ shape_05_2 .bulk $03,$00,$00,$53,$00,$00,$00,$7f,$00,$20,$00,$24,$00,$00,$00,$e0
+ $02,$00,$00,$00,$00,$00,$00,$00
4dd1: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
4de1: 01 50 20 01+ .bulk $01,$50,$20,$01,$00,$00,$00,$fe,$d0,$fd,$e0,$02,$d0,$fd,$00,$00
4df1: 80 30 00 01+ .bulk $80,$30,$00,$01,$a0,$00,$b0,$fd,$40,$02,$90,$02,$c7,$02,$00,$00
4e01: 09 00 00 54+ shape_05_3 .bulk $09,$00,$00,$54,$00,$00,$00,$7f,$00,$20,$00,$24,$00,$00,$00,$a0
+ $02,$00,$00,$00,$00,$00,$00,$00
4e19: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
4e29: 00 20 00 00+ .bulk $00,$20,$00,$00,$00,$00,$d0,$fd,$a0,$fd,$00,$00,$00,$00,$00,$00
4e39: 00 20 30 01+ .bulk $00,$20,$30,$01,$00,$02,$c0,$ff,$c0,$fd,$00,$00,$00,$00,$00,$00
4e49: 00 20 00 00+ .bulk $00,$20,$00,$00,$50,$01,$35,$02,$70,$fd,$00,$00,$00,$00,$00,$00
4e59: 00 20 40 05+ .bulk $00,$20,$40,$05,$00,$01,$bb,$fd,$60,$02,$00,$00,$00,$00,$00,$00
4e69: 00 20 00 00+ .bulk $00,$20,$00,$00,$50,$00,$e0,$ff,$83,$02,$00,$00,$00,$00,$00,$00
4e79: 00 60 00 01+ .bulk $00,$60,$00,$01,$00,$00,$48,$02,$a0,$fd,$00,$00,$00,$00,$00,$00
4e89: 00 20 00 00+ .bulk $00,$20,$00,$00,$70,$00,$66,$02,$20,$00,$00,$00,$00,$00,$00,$00
4e99: 00 20 00 00+ .bulk $00,$20,$00,$00,$30,$01,$8e,$fd,$dd,$ff,$00,$00,$00,$00,$00,$00
4ea9: 03 00 00 55+ shape_05_4 .bulk $03,$00,$00,$55,$00,$00,$00,$7f,$00,$20,$00,$24,$00,$00,$00,$00
+ $03,$00,$00,$00,$00,$00,$00,$00
4ec1: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
4ed1: ff 30 40 01+ .bulk $ff,$30,$40,$01,$20,$00,$20,$fd,$00,$fe,$20,$fd,$b0,$02,$00,$00
4ee1: ff 20 00 00+ .bulk $ff,$20,$00,$00,$90,$01,$f0,$02,$30,$fd,$f0,$02,$60,$02,$00,$00
; Weird colors.
4ef1: 03 00 00 56+ shape_05_5 .bulk $03,$00,$00,$56,$00,$00,$00,$7f,$00,$20,$00,$24,$00,$00,$00,$b0
+ $02,$00,$00,$00,$00,$00,$00,$00
4f09: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
4f19: ff 06 00 00+ .bulk $ff,$06,$00,$00,$00,$00,$c0,$fd,$50,$fd,$c0,$fd,$20,$02,$00,$00
4f29: ff 03 00 00+ .bulk $ff,$03,$00,$00,$20,$02,$b0,$02,$e0,$fe,$b0,$02,$70,$03,$00,$00
4f39: 03 00 00 57+ shape_05_6 .bulk $03,$00,$00,$57,$00,$00,$00,$7f,$00,$20,$00,$24,$00,$00,$00,$00
+ $03,$00,$00,$00,$00,$00,$00,$00
4f51: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
4f61: 80 20 50 02+ .bulk $80,$20,$50,$02,$00,$00,$89,$fd,$a0,$fd,$e0,$fd,$50,$02,$00,$00
4f71: 80 40 20 01+ .bulk $80,$40,$20,$01,$90,$00,$44,$02,$b0,$fd,$00,$03,$e0,$01,$00,$00
;
; Shape class $06: friendly base.
;
4f81: 00 shape_06 .dd1 %00000000 ;1 entry
4f82: 00 .dd1 $00
4f83: 91 0f .dd2 shape_06_0-$4000
4f85: 00 00 00 00+ .junk 12
; Left window: 4x orange, 4x black
; Middle window: purple, white, white, green, black, black ("it's complicated")
; Right window: 2x white, 2x black
4f91: 08 00 00 61+ shape_06_0 .bulk $08,$00,$00,$61,$00,$00,$00,$00,$00,$10,$00,$40,$00,$00,$00,$20
+ $00,$00,$00,$00,$00,$00,$00,$00
4fa9: 00 50 00 00+ .bulk $00,$50,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00 ;fly-through point
4fb9: 80 20 00 00+ .bulk $80,$20,$00,$00,$00,$00,$f0,$fe,$e0,$fe,$a0,$01,$e0,$ff,$00,$00
4fc9: 80 20 00 00+ .bulk $80,$20,$00,$00,$00,$00,$70,$ff,$20,$00,$90,$00,$60,$00,$00,$00
4fd9: 80 20 00 00+ .bulk $80,$20,$00,$00,$00,$00,$90,$ff,$e0,$ff,$e0,$ff,$20,$00,$00,$00
4fe9: 80 20 00 00+ .bulk $80,$20,$00,$00,$00,$00,$20,$00,$e0,$ff,$70,$00,$20,$00,$00,$00
4ff9: 80 40 00 03+ .bulk $80,$40,$00,$03,$00,$00,$60,$ff,$40,$ff,$a0,$ff,$90,$ff,$00,$00 ;left
5009: 80 30 00 02+ .bulk $80,$30,$00,$02,$00,$00,$20,$00,$40,$ff,$50,$00,$90,$ff,$00,$00 ;middle
5019: 80 10 00 01+ .bulk $80,$10,$00,$01,$00,$00,$e0,$00,$40,$ff,$10,$01,$90,$ff,$00,$00 ;right
;
; Shape class $07: stars.
;
5029: 07 shape_07 .dd1 %00000111 ;1 entry
502a: 00 .dd1 $00
502b: 49 10 .dd2 shape_07_0-$4000
502d: 71 10 .dd2 shape_07_1-$4000
502f: 99 10 .dd2 shape_07_2-$4000
5031: c1 10 .dd2 shape_07_3-$4000
5033: e9 10 .dd2 shape_07_4-$4000
5035: 11 11 .dd2 shape_07_5-$4000
5037: e9 10 .dd2 shape_07_4-$4000
5039: 71 10 .dd2 shape_07_1-$4000
503b: 00 00 00 00+ .junk 14
5049: 01 00 00 71+ shape_07_0 .bulk $01,$00,$00,$71,$00,$00,$00,$00,$40,$00,$00,$0a,$00,$00,$00,$01
+ $00,$00,$00,$00,$00,$00,$00,$00
5061: 00 60 00 00+ .bulk $00,$60,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
5071: 01 00 00 72+ shape_07_1 .bulk $01,$00,$00,$72,$00,$00,$00,$00,$40,$00,$00,$40,$00,$00,$00,$01
+ $00,$00,$00,$00,$00,$00,$00,$00
5089: 00 50 00 00+ .bulk $00,$50,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
5099: 01 00 00 73+ shape_07_2 .bulk $01,$00,$00,$73,$00,$00,$00,$00,$40,$00,$00,$28,$00,$00,$00,$01
+ $00,$00,$00,$00,$00,$00,$00,$00
50b1: 00 40 00 01+ .bulk $00,$40,$00,$01,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
50c1: 01 00 00 74+ shape_07_3 .bulk $01,$00,$00,$74,$00,$00,$00,$00,$40,$00,$00,$10,$00,$00,$00,$01
+ $00,$00,$00,$00,$00,$00,$00,$00
50d9: 00 30 00 00+ .bulk $00,$30,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
50e9: 01 00 00 75+ shape_07_4 .bulk $01,$00,$00,$75,$00,$00,$00,$00,$40,$00,$00,$70,$00,$00,$00,$01
+ $00,$00,$00,$00,$00,$00,$00,$00
5101: 00 20 00 02+ .bulk $00,$20,$00,$02,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
; This one is a rect, not a point.
5111: 01 00 00 76+ shape_07_5 .bulk $01,$00,$00,$76,$00,$00,$00,$00,$40,$00,$00,$70,$00,$00,$00,$01
+ $00,$00,$00,$00,$00,$00,$00,$00
5129: 80 40 00 00+ .bulk $80,$40,$00,$00,$00,$00,$e2,$ff,$e2,$ff,$1e,$00,$1e,$00,$00,$00
;
; Shape class $08: projectile fired by player. Note the element has a small Z
; offset.
;
5139: 00 shape_08 .dd1 %00000000 ;1 entry
513a: 00 .dd1 $00
513b: 49 11 .dd2 shape_08_0-$4000
513d: 00 00 00 00+ .junk 12
5149: 01 00 00 81+ shape_08_0 .bulk $01,$00,$00,$81,$01,$04,$00,$ff,$10,$00,$b0,$00,$00,$00,$00,$30
+ $00,$00,$08,$00,$00,$00,$00,$00
5161: 80 10 ff 00+ .bulk $80,$10,$ff,$00,$80,$00,$c0,$ff,$c0,$ff,$40,$00,$40,$00,$00,$00
;
; Shape class $09: explosion chunks.
;
5171: 07 shape_09 .dd1 %00000111 ;8 entries
5172: 00 .dd1 $00
5173: 91 11 .dd2 shape_09_0-$4000
5175: b9 11 .dd2 shape_09_1-$4000
5177: e1 11 .dd2 shape_09_2-$4000
5179: 09 12 .dd2 shape_09_3-$4000
517b: 31 12 .dd2 shape_09_4-$4000
517d: 59 12 .dd2 shape_09_5-$4000
517f: 91 11 .dd2 shape_09_0-$4000
5181: b9 11 .dd2 shape_09_1-$4000
5183: 00 00 00 00+ .junk 14
5191: 01 00 00 91+ shape_09_0 .bulk $01,$00,$00,$91,$02,$00,$00,$7e,$10,$00,$00,$01,$00,$00,$00,$20
+ $00,$1a,$00,$1a,$00,$1a,$00,$00
51a9: 80 20 00 00+ .bulk $80,$20,$00,$00,$00,$00,$e9,$ff,$ec,$ff,$0b,$00,$09,$00,$00,$00
; Limited lifespan.
51b9: 01 20 00 92+ shape_09_1 .bulk $01,$20,$00,$92,$02,$00,$00,$7e,$10,$00,$00,$01,$00,$00,$00,$20
+ $00,$0a,$00,$0a,$00,$0a,$00,$00
51d1: 80 30 ff 01+ .bulk $80,$30,$ff,$01,$00,$00,$fa,$ff,$f6,$ff,$15,$00,$16,$00,$00,$00
51e1: 01 00 00 93+ shape_09_2 .bulk $01,$00,$00,$93,$02,$00,$00,$7e,$10,$00,$00,$01,$00,$00,$00,$20
+ $00,$0a,$00,$0a,$00,$0f,$00,$00
51f9: 80 50 ff 01+ .bulk $80,$50,$ff,$01,$00,$00,$f9,$ff,$fb,$ff,$08,$00,$03,$00,$00,$00
5209: 01 00 00 94+ shape_09_3 .bulk $01,$00,$00,$94,$02,$00,$00,$7e,$10,$00,$00,$01,$00,$00,$00,$20
+ $00,$0a,$00,$0a,$00,$0a,$00,$00
5221: 80 10 ff 01+ .bulk $80,$10,$ff,$01,$00,$00,$f2,$ff,$f9,$ff,$0a,$00,$0b,$00,$00,$00
5231: 01 00 00 95+ shape_09_4 .bulk $01,$00,$00,$95,$02,$00,$00,$7e,$10,$00,$00,$01,$00,$00,$00,$18
+ $00,$0a,$00,$0a,$00,$18,$00,$00
5249: 80 40 30 01+ .bulk $80,$40,$30,$01,$00,$00,$fb,$ff,$fb,$ff,$10,$00,$11,$00,$00,$00
5259: 01 00 00 96+ shape_09_5 .bulk $01,$00,$00,$96,$02,$00,$00,$7e,$10,$00,$00,$01,$00,$00,$00,$20
+ $00,$0a,$00,$0a,$00,$0a,$00,$00
5271: 80 50 00 00+ .bulk $80,$50,$00,$00,$00,$00,$da,$ff,$de,$ff,$19,$00,$1b,$00,$00,$00
;
; Shape class $0a: enemy ship explosion flare.
;
; All of these have nonzero values for the counter at +$01, which limits their
; lifespan.
;
5281: 03 shape_0a .dd1 %00000011 ;4 entries
5282: 00 .dd1 $00
5283: 91 12 .dd2 shape_0a_0-$4000
5285: c9 12 .dd2 shape_0a_1-$4000
5287: 51 13 .dd2 shape_0a_2-$4000
5289: 99 13 .dd2 shape_0a_3-$4000
528b: 00 00 00 00+ .junk 6
5291: 02 02 00 01+ shape_0a_0 .bulk $02,$02,$00,$01,$01,$00,$00,$7e,$10,$00,$00,$01,$00,$00,$00,$90
+ $00,$40,$00,$40,$00,$40,$00,$00
52a9: 80 20 50 01+ .bulk $80,$20,$50,$01,$00,$00,$a0,$fe,$d0,$fe,$80,$00,$90,$00,$00,$00
52b9: 80 40 30 01+ .bulk $80,$40,$30,$01,$00,$00,$a0,$fd,$20,$ff,$80,$00,$c0,$01,$00,$00
52c9: 07 06 00 02+ shape_0a_1 .bulk $07,$06,$00,$02,$01,$00,$00,$7e,$10,$00,$00,$01,$00,$00,$00,$80
+ $00,$20,$00,$20,$00,$20,$00,$00
52e1: 00 60 00 01+ .bulk $00,$60,$00,$01,$00,$00,$00,$ff,$70,$ff,$00,$00,$00,$00,$00,$00
52f1: 00 60 00 00+ .bulk $00,$60,$00,$00,$00,$00,$c0,$ff,$b0,$00,$00,$00,$00,$00,$00,$00
5301: 00 60 00 00+ .bulk $00,$60,$00,$00,$00,$00,$90,$01,$20,$01,$00,$00,$00,$00,$00,$00
5311: 00 60 00 01+ .bulk $00,$60,$00,$01,$00,$00,$a0,$00,$10,$02,$00,$00,$00,$00,$00,$00
5321: 00 60 00 00+ .bulk $00,$60,$00,$00,$00,$00,$d0,$00,$b1,$01,$00,$00,$00,$00,$00,$00
5331: 00 60 00 00+ .bulk $00,$60,$00,$00,$00,$00,$f0,$00,$d0,$fe,$00,$00,$00,$00,$00,$00
5341: 00 60 00 00+ .bulk $00,$60,$00,$00,$00,$00,$20,$01,$20,$ff,$00,$00,$00,$00,$00,$00
5351: 03 01 00 03+ shape_0a_2 .bulk $03,$01,$00,$03,$01,$00,$00,$7e,$10,$00,$00,$01,$00,$00,$00,$60
+ $00,$80,$00,$80,$00,$80,$00,$00
5369: 80 10 00 00+ .bulk $80,$10,$00,$00,$00,$00,$90,$fc,$b0,$fe,$90,$00,$15,$02,$00,$00
5379: 80 40 00 00+ .bulk $80,$40,$00,$00,$90,$01,$b0,$ff,$70,$ff,$c0,$01,$30,$02,$00,$00
5389: 80 30 00 00+ .bulk $80,$30,$00,$00,$00,$02,$d0,$fd,$e0,$ff,$60,$00,$20,$02,$00,$00
5399: 04 04 00 03+ shape_0a_3 .bulk $04,$04,$00,$03,$01,$00,$00,$7e,$10,$00,$00,$01,$00,$00,$00,$60
+ $00,$80,$00,$80,$00,$80,$00,$00
53b1: 01 20 ff 00+ .bulk $01,$20,$ff,$00,$00,$00,$a0,$fe,$fb,$ff,$60,$00,$05,$00,$00,$00
53c1: 01 20 30 01+ .bulk $01,$20,$30,$01,$00,$00,$b0,$ff,$00,$00,$40,$01,$00,$00,$00,$00
53d1: 01 50 ff 00+ .bulk $01,$50,$ff,$00,$00,$00,$d0,$fe,$20,$00,$60,$00,$20,$00,$00,$00
53e1: 01 10 00 01+ .bulk $01,$10,$00,$01,$00,$00,$90,$ff,$c0,$ff,$40,$01,$c0,$ff,$00,$00
;
; Offsets to shape class definitions. The 16-bit values are added to $4000.
;
; The location of this table is identified by an offset stored at $4000.
;
; Used by code at $760f.
53f1: 95 07 shape_cls_offs .dd2 shape_00-$4000 ;$00
53f3: e1 08 .dd2 shape_01-$4000 ;$01
53f5: 71 0a .dd2 shape_02-$4000 ;$02
53f7: 99 0c .dd2 shape_03-$4000 ;$03
53f9: f9 0c .dd2 shape_04-$4000 ;$04
53fb: 09 0d .dd2 shape_05-$4000 ;$05
53fd: 81 0f .dd2 shape_06-$4000 ;$06
53ff: 29 10 .dd2 shape_07-$4000 ;$07
5401: 39 11 .dd2 shape_08-$4000 ;$08
5403: 71 11 .dd2 shape_09-$4000 ;$09
5405: 81 12 .dd2 shape_0a-$4000 ;$0a
5407: 95 07 .dd2 shape_00-$4000 ;$0b ($00)
5409: 3d 3d 3d 3d+ .align $0100 (247 bytes)
;
; High byte of address of unrolled AND instructions. Low byte of address comes
; out of table at $b700.
unroll_and_addr_hi
5500: a6 a6 a6 a6+ .bulk $a6,$a6,$a6,$a6,$a6,$a6,$a6,$a6,$a6,$a6,$a6,$a6,$a6,$a6,$a6,$a6
+ $a6,$a6,$a6,$a6,$a6,$a6,$a6,$a6,$a6,$a6,$a6,$a6,$a6,$a6,$a6,$a6
+ $a6,$a6,$a6,$a6,$a6,$a7,$a7,$a7,$a7,$a7,$a7,$a7,$a7,$a7,$a7,$a7
+ $a7,$a7,$a7,$a7,$a7,$a7,$a7,$a7,$a7,$a7,$a7,$a7,$a7,$a7,$a7,$a7
+ $a7,$a7,$a7,$a7,$a7,$a7,$a7,$a7,$a7,$a7,$a8,$a8,$a8,$a8,$a8,$a8
+ $a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8
+ $a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a9,$a9
+ $a9,$a9,$a9,$a9,$a9,$a9,$a9,$a9,$a9,$a9,$a9,$a9,$a9,$a9,$a9,$a9
+ $a9,$a9,$a9,$a9,$a9,$a9,$a9,$a9,$a9,$a9,$a9,$a9,$a9,$a9,$a9,$a9
+ $a9,$a9,$a9,$aa,$aa,$aa,$aa,$aa,$aa,$aa,$aa,$aa,$aa,$aa,$aa,$aa
+ $aa,$aa,$aa,$aa,$aa,$aa,$aa,$aa,$aa,$aa,$aa,$aa,$aa,$aa,$aa,$aa
+ $aa,$aa,$aa,$aa,$aa,$aa,$aa,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab
+ $ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab
+ $ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab
+ $ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab
+ $ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab,$ab
;
; Low/high address of unrolled STA instructions.
5600: 00 03 06 09+ unroll_sta_lo .bulk $00,$03,$06,$09,$0c,$0f,$12,$15,$18,$1b,$1e,$21,$24,$27,$2a,$2d
+ $30,$33,$36,$39,$3c,$3f,$42,$45,$48,$4b,$4e,$51,$54,$57,$5a,$5d
+ $60,$63,$66,$69,$6c,$6f,$72,$75,$78,$7b,$7e,$81,$84,$87,$8a,$8d
+ $90,$93,$96,$99,$9c,$9f,$a2,$a5,$a8,$ab,$ae,$b1,$b4,$b7,$ba,$bd
+ $c0,$c3,$c6,$c9,$cc,$cf,$d2,$d5,$d8,$db,$de,$e1,$e4,$e7,$ea,$ed
+ $f0,$f3,$f6,$f9,$fc,$ff,$02,$05,$08,$0b,$0e,$11,$14,$17,$1a,$1d
+ $20,$23,$26,$29,$2c,$2f,$32,$35,$38,$3b,$3e,$41,$44,$47,$4a,$4d
+ $50,$53,$56,$59,$5c,$5f,$62,$65,$68,$6b,$6e,$71,$74,$77,$7a,$7d
+ $80,$83,$86,$89,$8c,$8f,$92,$95,$98,$9b,$9e,$a1,$a4,$a7,$aa,$ad
+ $b0,$b3,$b6,$b9,$bc,$bf,$c2,$c5,$c8,$cb,$ce,$d1,$d4,$d7,$da,$dd
+ $e0,$e3,$e6,$e9,$ec,$ef,$f2,$f5,$f8,$fb,$fe,$01,$04,$07,$0a,$0d
+ $10,$13,$16,$19,$1c,$1f,$22,$25,$28,$2b,$2e,$31,$34,$37,$3a,$3d
+ $3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d
+ $3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d
+ $3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d
+ $3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d,$3d
5700: 58 58 58 58+ unroll_sta_hi .bulk $58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58
+ $58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58
+ $58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58
+ $58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58
+ $58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58,$58
+ $58,$58,$58,$58,$58,$58,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59
+ $59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59
+ $59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59
+ $59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59
+ $59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59
+ $59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$59,$5a,$5a,$5a,$5a,$5a
+ $5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a
+ $5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a
+ $5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a
+ $5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a
+ $5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a,$5a
;
; Draws a byte-wide vertical stripe.
;
; This is generally not called directly. A lookup table ($5600/5700) converts
; line numbers to addresses, which are then used as an indirect jump (for the
; top) or as a location to store an RTS (for the bottom).
;
; On entry:
; A-reg: pixel byte value (adjusted for odd/even)
; Y-reg: horizontal offset (0-39)
;
5800: 99 00 20 UnrolledSTA sta HIRES_P1,y
5803: 99 00 24 sta HIRES_P1+$400,y
5806: 99 00 28 sta HIRES_P1+$800,y
5809: 99 00 2c sta HIRES_P1+$c00,y
580c: 99 00 30 sta HIRES_P1+$1000,y
580f: 99 00 34 sta HIRES_P1+$1400,y
5812: 99 00 38 sta HIRES_P1+$1800,y
5815: 99 00 3c sta HIRES_P1+$1c00,y
5818: 99 80 20 sta HIRES_P1+128,y
581b: 99 80 24 sta HIRES_P1+$480,y
581e: 99 80 28 sta HIRES_P1+$880,y
5821: 99 80 2c sta HIRES_P1+$c80,y
5824: 99 80 30 sta HIRES_P1+$1080,y
5827: 99 80 34 sta HIRES_P1+$1480,y
582a: 99 80 38 sta HIRES_P1+$1880,y
582d: 99 80 3c sta HIRES_P1+$1c80,y
5830: 99 00 21 sta HIRES_P1+$100,y
5833: 99 00 25 sta HIRES_P1+$500,y
5836: 99 00 29 sta HIRES_P1+$900,y
5839: 99 00 2d sta HIRES_P1+$d00,y
583c: 99 00 31 sta HIRES_P1+$1100,y
583f: 99 00 35 sta HIRES_P1+$1500,y
5842: 99 00 39 sta HIRES_P1+$1900,y
5845: 99 00 3d sta HIRES_P1+$1d00,y
5848: 99 80 21 sta HIRES_P1+$180,y
584b: 99 80 25 sta HIRES_P1+$580,y
584e: 99 80 29 sta HIRES_P1+$980,y
5851: 99 80 2d sta HIRES_P1+$d80,y
5854: 99 80 31 sta HIRES_P1+$1180,y
5857: 99 80 35 sta HIRES_P1+$1580,y
585a: 99 80 39 sta HIRES_P1+$1980,y
585d: 99 80 3d sta HIRES_P1+$1d80,y
5860: 99 00 22 sta HIRES_P1+$200,y
5863: 99 00 26 sta HIRES_P1+$600,y
5866: 99 00 2a sta HIRES_P1+$a00,y
5869: 99 00 2e sta HIRES_P1+$e00,y
586c: 99 00 32 sta HIRES_P1+$1200,y
586f: 99 00 36 sta HIRES_P1+$1600,y
5872: 99 00 3a sta HIRES_P1+$1a00,y
5875: 99 00 3e sta HIRES_P1+$1e00,y
5878: 99 80 22 sta HIRES_P1+$280,y
587b: 99 80 26 sta HIRES_P1+$680,y
587e: 99 80 2a sta HIRES_P1+$a80,y
5881: 99 80 2e sta HIRES_P1+$e80,y
5884: 99 80 32 sta HIRES_P1+$1280,y
5887: 99 80 36 sta HIRES_P1+$1680,y
588a: 99 80 3a sta HIRES_P1+$1a80,y
588d: 99 80 3e sta HIRES_P1+$1e80,y
5890: 99 00 23 sta HIRES_P1+$300,y
5893: 99 00 27 sta HIRES_P1+$700,y
5896: 99 00 2b sta HIRES_P1+$b00,y
5899: 99 00 2f sta HIRES_P1+$f00,y
589c: 99 00 33 sta HIRES_P1+$1300,y
589f: 99 00 37 sta HIRES_P1+$1700,y
58a2: 99 00 3b sta HIRES_P1+$1b00,y
58a5: 99 00 3f sta HIRES_P1+$1f00,y
58a8: 99 80 23 sta HIRES_P1+$380,y
58ab: 99 80 27 sta HIRES_P1+$780,y
58ae: 99 80 2b sta HIRES_P1+$b80,y
58b1: 99 80 2f sta HIRES_P1+$f80,y
58b4: 99 80 33 sta HIRES_P1+$1380,y
58b7: 99 80 37 sta HIRES_P1+$1780,y
58ba: 99 80 3b sta HIRES_P1+$1b80,y
58bd: 99 80 3f sta HIRES_P1+$1f80,y
58c0: 99 28 20 sta HIRES_P1+40,y
58c3: 99 28 24 sta HIRES_P1+$428,y
58c6: 99 28 28 sta HIRES_P1+$828,y
58c9: 99 28 2c sta HIRES_P1+$c28,y
58cc: 99 28 30 sta HIRES_P1+$1028,y
58cf: 99 28 34 sta HIRES_P1+$1428,y
58d2: 99 28 38 sta HIRES_P1+$1828,y
58d5: 99 28 3c sta HIRES_P1+$1c28,y
58d8: 99 a8 20 sta HIRES_P1+168,y
58db: 99 a8 24 sta HIRES_P1+$4a8,y
58de: 99 a8 28 sta HIRES_P1+$8a8,y
58e1: 99 a8 2c sta HIRES_P1+$ca8,y
58e4: 99 a8 30 sta HIRES_P1+$10a8,y
58e7: 99 a8 34 sta HIRES_P1+$14a8,y
58ea: 99 a8 38 sta HIRES_P1+$18a8,y
58ed: 99 a8 3c sta HIRES_P1+$1ca8,y
58f0: 99 28 21 sta HIRES_P1+$128,y
58f3: 99 28 25 sta HIRES_P1+$528,y
58f6: 99 28 29 sta HIRES_P1+$928,y
58f9: 99 28 2d sta HIRES_P1+$d28,y
58fc: 99 28 31 sta HIRES_P1+$1128,y
58ff: 99 28 35 sta HIRES_P1+$1528,y
5902: 99 28 39 sta HIRES_P1+$1928,y
5905: 99 28 3d sta HIRES_P1+$1d28,y
5908: 99 a8 21 sta HIRES_P1+$1a8,y
590b: 99 a8 25 sta HIRES_P1+$5a8,y
590e: 99 a8 29 sta HIRES_P1+$9a8,y
5911: 99 a8 2d sta HIRES_P1+$da8,y
5914: 99 a8 31 sta HIRES_P1+$11a8,y
5917: 99 a8 35 sta HIRES_P1+$15a8,y
591a: 99 a8 39 sta HIRES_P1+$19a8,y
591d: 99 a8 3d sta HIRES_P1+$1da8,y
5920: 99 28 22 sta HIRES_P1+$228,y
5923: 99 28 26 sta HIRES_P1+$628,y
5926: 99 28 2a sta HIRES_P1+$a28,y
5929: 99 28 2e sta HIRES_P1+$e28,y
592c: 99 28 32 sta HIRES_P1+$1228,y
592f: 99 28 36 sta HIRES_P1+$1628,y
5932: 99 28 3a sta HIRES_P1+$1a28,y
5935: 99 28 3e sta HIRES_P1+$1e28,y
5938: 99 a8 22 sta HIRES_P1+$2a8,y
593b: 99 a8 26 sta HIRES_P1+$6a8,y
593e: 99 a8 2a sta HIRES_P1+$aa8,y
5941: 99 a8 2e sta HIRES_P1+$ea8,y
5944: 99 a8 32 sta HIRES_P1+$12a8,y
5947: 99 a8 36 sta HIRES_P1+$16a8,y
594a: 99 a8 3a sta HIRES_P1+$1aa8,y
594d: 99 a8 3e sta HIRES_P1+$1ea8,y
5950: 99 28 23 sta HIRES_P1+$328,y
5953: 99 28 27 sta HIRES_P1+$728,y
5956: 99 28 2b sta HIRES_P1+$b28,y
5959: 99 28 2f sta HIRES_P1+$f28,y
595c: 99 28 33 sta HIRES_P1+$1328,y
595f: 99 28 37 sta HIRES_P1+$1728,y
5962: 99 28 3b sta HIRES_P1+$1b28,y
5965: 99 28 3f sta HIRES_P1+$1f28,y
5968: 99 a8 23 sta HIRES_P1+$3a8,y
596b: 99 a8 27 sta HIRES_P1+$7a8,y
596e: 99 a8 2b sta HIRES_P1+$ba8,y
5971: 99 a8 2f sta HIRES_P1+$fa8,y
5974: 99 a8 33 sta HIRES_P1+$13a8,y
5977: 99 a8 37 sta HIRES_P1+$17a8,y
597a: 99 a8 3b sta HIRES_P1+$1ba8,y
597d: 99 a8 3f sta HIRES_P1+$1fa8,y
5980: 99 50 20 sta HIRES_P1+80,y
5983: 99 50 24 sta HIRES_P1+$450,y
5986: 99 50 28 sta HIRES_P1+$850,y
5989: 99 50 2c sta HIRES_P1+$c50,y
598c: 99 50 30 sta HIRES_P1+$1050,y
598f: 99 50 34 sta HIRES_P1+$1450,y
5992: 99 50 38 sta HIRES_P1+$1850,y
5995: 99 50 3c sta HIRES_P1+$1c50,y
5998: 99 d0 20 sta HIRES_P1+208,y
599b: 99 d0 24 sta HIRES_P1+$4d0,y
599e: 99 d0 28 sta HIRES_P1+$8d0,y
59a1: 99 d0 2c sta HIRES_P1+$cd0,y
59a4: 99 d0 30 sta HIRES_P1+$10d0,y
59a7: 99 d0 34 sta HIRES_P1+$14d0,y
59aa: 99 d0 38 sta HIRES_P1+$18d0,y
59ad: 99 d0 3c sta HIRES_P1+$1cd0,y
59b0: 99 50 21 sta HIRES_P1+$150,y
59b3: 99 50 25 sta HIRES_P1+$550,y
59b6: 99 50 29 sta HIRES_P1+$950,y
59b9: 99 50 2d sta HIRES_P1+$d50,y
59bc: 99 50 31 sta HIRES_P1+$1150,y
59bf: 99 50 35 sta HIRES_P1+$1550,y
59c2: 99 50 39 sta HIRES_P1+$1950,y
59c5: 99 50 3d sta HIRES_P1+$1d50,y
59c8: 99 d0 21 sta HIRES_P1+$1d0,y
59cb: 99 d0 25 sta HIRES_P1+$5d0,y
59ce: 99 d0 29 sta HIRES_P1+$9d0,y
59d1: 99 d0 2d sta HIRES_P1+$dd0,y
59d4: 99 d0 31 sta HIRES_P1+$11d0,y
59d7: 99 d0 35 sta HIRES_P1+$15d0,y
59da: 99 d0 39 sta HIRES_P1+$19d0,y
59dd: 99 d0 3d sta HIRES_P1+$1dd0,y
59e0: 99 50 22 sta HIRES_P1+$250,y
59e3: 99 50 26 sta HIRES_P1+$650,y
59e6: 99 50 2a sta HIRES_P1+$a50,y
59e9: 99 50 2e sta HIRES_P1+$e50,y
59ec: 99 50 32 sta HIRES_P1+$1250,y
59ef: 99 50 36 sta HIRES_P1+$1650,y
59f2: 99 50 3a sta HIRES_P1+$1a50,y
59f5: 99 50 3e sta HIRES_P1+$1e50,y
59f8: 99 d0 22 sta HIRES_P1+$2d0,y
59fb: 99 d0 26 sta HIRES_P1+$6d0,y
59fe: 99 d0 2a sta HIRES_P1+$ad0,y
5a01: 99 d0 2e sta HIRES_P1+$ed0,y
5a04: 99 d0 32 sta HIRES_P1+$12d0,y
5a07: 99 d0 36 sta HIRES_P1+$16d0,y
5a0a: 99 d0 3a sta HIRES_P1+$1ad0,y
5a0d: 99 d0 3e sta HIRES_P1+$1ed0,y
5a10: 99 50 23 sta HIRES_P1+$350,y
5a13: 99 50 27 sta HIRES_P1+$750,y
5a16: 99 50 2b sta HIRES_P1+$b50,y
5a19: 99 50 2f sta HIRES_P1+$f50,y
5a1c: 99 50 33 sta HIRES_P1+$1350,y
5a1f: 99 50 37 sta HIRES_P1+$1750,y
5a22: 99 50 3b sta HIRES_P1+$1b50,y
5a25: 99 50 3f sta HIRES_P1+$1f50,y
5a28: 99 d0 23 sta HIRES_P1+$3d0,y
5a2b: 99 d0 27 sta HIRES_P1+$7d0,y
5a2e: 99 d0 2b sta HIRES_P1+$bd0,y
5a31: 99 d0 2f sta HIRES_P1+$fd0,y
5a34: 99 d0 33 sta HIRES_P1+$13d0,y
5a37: 99 d0 37 sta HIRES_P1+$17d0,y
5a3a: 99 d0 3b sta HIRES_P1+$1bd0,y
5a3d: 99 d0 3f sta HIRES_P1+$1fd0,y
5a40: 60 rts
5a41: d0 3f 60 00+ .junk 47
;
; Redraws the crosshairs after we erase a rect.
;
; Note we do the draw *before* restoring the instruction we overwrote during the
; erase, but since rect erase uses STA or AND, and crosshair draw uses ORA, they
; don't interfere with each other.
;
• Clear variables
]restore_index .var $8a {addr/1}
5a70: 20 80 5a AfterEraseRect jsr DrawCrosshairs
5a73: a6 64 ldx cur_elem_index
5a75: a4 8a ldy ]restore_index
5a77: 4c 4e 8e jmp AfterEraseRect1
5a7a: 00 00 00 00+ .junk 5
5a7f: 7e :saved_xreg .dd1 $7e
;
; Draws the crosshairs at the center of the screen.
;
; On exit:
; X-reg preserved
;
5a80: 8e 7f 5a DrawCrosshairs stx :saved_xreg
5a83: a9 60 lda #INSTR_RTS
5a85: 8d 8b 1a sta OraSeq_93 ;stop at line 93
5a88: a2 03 ldx #$03 ;two pixels of white
5a8a: a0 14 ldy #20 ;column 20 (center of screen)
5a8c: 20 53 1a jsr OraSeq_85 ;draw vertical line, from line 85 to 92
5a8f: a9 8a lda #INSTR_TXA
5a91: 8d 8b 1a sta OraSeq_93 ;restore
5a94: a9 60 lda #INSTR_RTS
5a96: 8d f4 1a sta OraSeq_108 ;stop at line 108
5a99: 20 bc 1a jsr OraSeq_100 ;draw vertical line, from line 100 to 107
5a9c: a9 8a lda #INSTR_TXA
5a9e: 8d f4 1a sta OraSeq_108 ;restore
5aa1: ea nop
5aa2: ad 3a 22 lda HIRES_P1+$23a ;draw the horizontal parts with a few stores
5aa5: 09 7e ora #$7e
5aa7: 8d 3a 22 sta HIRES_P1+$23a
5aaa: ad 0b 22 lda HIRES_P1+$20b
5aad: 09 07 ora #$07
5aaf: 8d 3b 22 sta HIRES_P1+$23b
5ab2: ad 3c 22 lda HIRES_P1+$23c
5ab5: 09 60 ora #$60
5ab7: 8d 3c 22 sta HIRES_P1+$23c
5aba: ad 3d 22 lda HIRES_P1+$23d
5abd: 09 7f ora #$7f
5abf: 8d 3d 22 sta HIRES_P1+$23d
5ac2: ae 7f 5a ldx :saved_xreg
5ac5: 60 rts
5ac6: 00 00 00 00+ .align $0100 (58 bytes)
.org $5e00
5e00: 00 00 00 00+ .junk 69
;
; Adjusts position of next time portal boundary object.
;
; On entry:
; $ce-cf: portal boundary X coord modifier
; $d0-d1: portal boundary Y coord modifier
;
; On exit:
; X-reg unmodified
; $ce-cf / $d0-d1 updated
;
• Clear variables
]portal_zc? .var $86 {addr/2}
]math2_val? .var $8a {addr/1}
]lz_count .var $8b {addr/1}
]joy_effect .var $8c {addr/2}
]portal_delta_yc .var $96 {addr/2}
UpdatePortalPosn
5e45: ea nop
5e46: a9 00 lda #$00 ;set Z coord to $2400
5e48: 85 86 sta ]portal_zc?
5e4a: a9 24 lda #$24
5e4c: 85 87 sta ]portal_zc?+1
5e4e: d0 18 bne :Cont ;(always)
5e50: a4 86 b9 00+ unref_5e50? .junk 24 ;dead code
5e68: 85 87 :Cont sta ]portal_zc?+1
5e6a: a8 tay
5e6b: b9 00 b9 lda clz_table,y ;count leading zeroes ($24 -> 2)
5e6e: a8 tay
5e6f: 85 8b sta ]lz_count
5e71: 18 clc
5e72: 69 ac adc #>math_tab2_base?
5e74: 85 13 sta math_tab_ptr12+1
5e76: a5 86 lda ]portal_zc?
5e78: 39 d5 00 and bit_mask_left9,y
5e7b: 05 87 ora ]portal_zc?+1
5e7d: a8 tay
5e7e: b1 12 lda (math_tab_ptr12),y
5e80: 85 8a sta ]math2_val?
5e82: ea nop
5e83: 18 clc
5e84: a4 8a ldy ]math2_val?
5e86: b9 00 b5 lda turn_map_lo?,y
5e89: 65 9a adc joy_yaw_angle
5e8b: 85 8c sta ]joy_effect
5e8d: a5 9b lda joy_yaw_angle+1
5e8f: e5 8b sbc ]lz_count
5e91: 30 25 bmi L5EB8
5e93: 85 8d sta ]joy_effect+1
5e95: 38 sec
5e96: ea nop
5e97: 69 ac adc #>math_tab2_base?
5e99: 85 15 sta math_tab_ptr14+1
5e9b: a4 8c ldy ]joy_effect
5e9d: b9 00 17 lda math_tab1_lastpg?,y ;$80 - $ff
5ea0: a8 tay
5ea1: b1 14 lda (math_tab_ptr14),y
5ea3: 85 95 sta portal_delta_xc+1
5ea5: a4 8d ldy ]joy_effect+1
5ea7: 39 ef 00 and bit_mask_left8,y
5eaa: 45 9c eor joy_yaw_sign
5eac: 85 94 sta portal_delta_xc
5eae: a5 95 lda portal_delta_xc+1
5eb0: 39 e7 00 and bit_mask_right8,y
5eb3: 45 9c eor joy_yaw_sign
5eb5: 4c d4 5e jmp L5ED4
5eb8: ea L5EB8 nop
5eb9: 18 clc
5eba: 69 08 adc #$08
5ebc: 30 12 bmi L5ED0
5ebe: 18 clc
5ebf: 69 10 adc #>math_tab1_base?
5ec1: 85 15 sta math_tab_ptr14+1
5ec3: a4 8c ldy ]joy_effect
5ec5: a5 9c lda joy_yaw_sign
5ec7: 85 95 sta portal_delta_xc+1
5ec9: 51 14 eor (math_tab_ptr14),y
5ecb: 85 94 sta portal_delta_xc
5ecd: 4c d6 5e jmp L5ED6
5ed0: a9 00 L5ED0 lda #$00
5ed2: 85 94 sta portal_delta_xc
5ed4: 85 95 L5ED4 sta portal_delta_xc+1
;
5ed6: ea L5ED6 nop
5ed7: 18 clc
5ed8: a4 8a ldy ]math2_val?
5eda: b9 00 b5 lda turn_map_lo?,y
5edd: 65 9d adc joy_pitch_angle
5edf: 85 8c sta ]joy_effect
5ee1: a5 9e lda joy_pitch_angle+1
5ee3: e5 8b sbc ]lz_count
5ee5: 30 25 bmi L5F0C
5ee7: 85 8d sta ]joy_effect+1
5ee9: 38 sec
5eea: ea nop
5eeb: 69 ac adc #>math_tab2_base?
5eed: 85 15 sta math_tab_ptr14+1
5eef: a4 8c ldy ]joy_effect
5ef1: b9 00 17 lda math_tab1_lastpg?,y
5ef4: a8 tay
5ef5: b1 14 lda (math_tab_ptr14),y
5ef7: 85 97 sta ]portal_delta_yc+1
5ef9: a4 8d ldy ]joy_effect+1
5efb: 39 ef 00 and bit_mask_left8,y
5efe: 45 9f eor joy_pitch_sign
5f00: 85 96 sta ]portal_delta_yc
5f02: a5 97 lda ]portal_delta_yc+1
5f04: 39 e7 00 and bit_mask_right8,y
5f07: 45 9f eor joy_pitch_sign
5f09: 4c 28 5f jmp L5F28
5f0c: ea L5F0C nop
5f0d: 18 clc
5f0e: 69 08 adc #$08
5f10: 30 12 bmi L5F24
5f12: 18 clc
5f13: 69 10 adc #>math_tab1_base?
5f15: 85 15 sta math_tab_ptr14+1
5f17: a4 8c ldy ]joy_effect
5f19: a5 9f lda joy_pitch_sign
5f1b: 85 97 sta ]portal_delta_yc+1
5f1d: 51 14 eor (math_tab_ptr14),y
5f1f: 85 96 sta ]portal_delta_yc
5f21: 4c 2a 5f jmp L5F2A
5f24: a9 00 L5F24 lda #$00
5f26: 85 96 sta ]portal_delta_yc
5f28: 85 97 L5F28 sta ]portal_delta_yc+1
5f2a: ea L5F2A nop
; Update output values.
5f2b: a0 02 ldy #$02
5f2d: b9 ce 00 :Loop lda portal_next_xc,y
5f30: 18 clc
5f31: 79 94 00 adc portal_delta_xc,y ;coordinate delta
5f34: 99 ce 00 sta portal_next_xc,y
5f37: b9 cf 00 lda portal_next_xc+1,y
5f3a: 79 95 00 adc portal_delta_xc+1,y
5f3d: 99 cf 00 sta portal_next_xc+1,y
5f40: c9 12 cmp #$12 ;high byte >= 18?
5f42: 30 08 bmi :InPosRange ;no, branch
5f44: a9 12 lda #$12 ;yes, clamp to 18
5f46: 99 cf 00 sta portal_next_xc+1,y
5f49: 4c 55 5f jmp :Next
5f4c: c9 ed :InPosRange cmp #$ed ;high byte < -19?
5f4e: 10 05 bpl :Next ;no, branch
5f50: a9 ed lda #$ed ;yes, clamp to -19
5f52: 99 cf 00 sta portal_next_xc+1,y
5f55: 88 :Next dey
5f56: 88 dey
5f57: 10 d4 bpl :Loop
5f59: 60 rts
5f5a: 3d 3d 3d 3d+ .junk 12
;
; Updates object movement vector.
;
; Some objects, like enemy ships, update their movement periodically. Others,
; like explosion chunks, have their vector set to random values.
;
; If the player is turning, we need to update the vector so that things behave
; as if we were rotating rather than sliding.
;
; On entry:
; X-reg: object index
;
; On exit:
; $64 and X-reg: index of first element
;
• Clear variables
5f66: 18 UpdateObject clc ;do sound stuff
5f67: a5 b2 lda engine_sound_ctr?+1
5f69: 69 05 adc #$05
5f6b: 85 b2 sta engine_sound_ctr?+1
5f6d: 90 0f bcc :NoSound
5f6f: e6 b3 inc engine_sound_ctr?+2
5f71: a5 cc lda engine_sound_enable
5f73: f0 09 beq :NoSound
5f75: a5 b3 lda engine_sound_ctr?+2
5f77: 25 b1 and engine_sound_ctr?
5f79: d0 03 bne :NoSound
5f7b: ad 30 c0 lda SPKR
;
5f7e: a9 00 :NoSound lda #$00
5f80: 85 b4 sta wronly_b4? ;init to zero
5f82: bd a0 9a lda obj_shape_uid,x ;get shape unique ID
5f85: 29 f0 and #$f0
5f87: c9 f0 cmp #$f0 ;check for $Fx (never happens?)
5f89: d0 02 bne :NotFn
5f8b: 85 b4 sta wronly_b4? ;set $b4 to #$f0 (never happens?)
5f8d: a9 90 :NotFn lda #$90
5f8f: 85 c6 sta prev_zpos+1 ;init "previous zpos", an optimization used in
5f91: 85 c5 sta prev_zpos ; UpdateElement
5f93: a9 00 lda #$00
5f95: 85 72 sta no_draw_obj_flag ;init flags and counters
5f97: 85 f8 sta elem_collision_flag
5f99: 85 a4 sta wronly_a4?
5f9b: 85 a1 sta drawn_elem_count
5f9d: 85 a5 sta wronly_a5?
5f9f: 20 7f 7f jsr Return7f7f
5fa2: bd 28 9a lda obj_lifetime_ctr,x ;get object lifetime counter
5fa5: f0 10 beq :NotExpired ;zero, object lives forever
5fa7: de 28 9a dec obj_lifetime_ctr,x ;decrement
5faa: d0 0b bne :NotExpired ;not yet zero, continue
5fac: a9 ff lda #$ff
5fae: 9d 18 9b sta obj_activity_state,x ;mark object as expired
5fb1: e6 72 inc no_draw_obj_flag
5fb3: ea nop
5fb4: 4c 42 64 jmp GetFirstElemIndex ;copy first element index into $64 and return
5fb7: bd 18 9b :NotExpired lda obj_activity_state,x ;check object activity state (0-3 or > $80)
5fba: 30 06 bmi :NoDraw ;not valid, don't draw it
5fbc: d0 09 bne :Branch_SetBB ;nonzero, branch
5fbe: ea nop ;zero for things that don't fly toward player
5fbf: 4c 42 64 jmp GetFirstElemIndex ;get first element index, and return
5fc2: e6 72 :NoDraw inc no_draw_obj_flag
5fc4: 4c 42 64 jmp GetFirstElemIndex
5fc7: 10 06 :Branch_SetBB bpl :SetBB ;(always)
5fc9: e6 72 ea 4c+ unref_5fc9 .junk 6
5fcf: 38 :SetBB sec ;A-reg currently 1-3
5fd0: e9 01 sbc #$01 ;subtract 1 so it's 0-2
5fd2: 85 bb sta update_mvmt_flag ;save as movement flag (nonzero for enemy ships)
5fd4: f0 05 beq :NoVelChange ;zero for things with constant velocity; branch
5fd6: de 90 9b dec vel_change_ctr,x ;decrement the velocity-change countdown
5fd9: f0 03 beq :DoVelChange ;reached zero, do the change
5fdb: 4c 8d 60 :NoVelChange jmp :MoveStuff
5fde: a5 bb :DoVelChange lda update_mvmt_flag
5fe0: 29 02 and #$02 ;check for 2 (enemy ships)
5fe2: f0 09 beq :AddRandom ;no, must be 1; branch to apply randomness
5fe4: 20 06 7d jsr UpdateObjectVelocity
5fe7: 20 7f 7f jsr Return7f7f
5fea: 4c 69 60 jmp :ResetVelChgCtr
; Add some randomness. We should only get here for explosion chunks. Note that
; chunks and flares are the only things that have nonzero values for X/Y speed.
]rng_limit .var $86 {addr/2}
]rng_limit_mode .var $88 {addr/1}
]rng_result .var $8a {addr/2}
5fed: a9 01 :AddRandom lda #$01
5fef: 85 88 sta ]rng_limit_mode ;set mode to +/-
5ff1: bd 20 9d lda obj_spdlim_z_lo,x ;get Z speed limit
5ff4: 85 86 sta ]rng_limit
5ff6: bd 48 9d lda obj_spdlim_z_hi,x
5ff9: 85 87 sta ]rng_limit+1
5ffb: 20 b0 7b jsr GenRandom ;generate random value
5ffe: bd 30 9c lda obj_move_zc2_lo,x ;modify value in object table, adding the
6001: 18 clc ; random value to the existing value
6002: 65 8a adc ]rng_result
6004: 9d 10 9e sta obj_move_zc_lo,x
6007: bd 58 9c lda obj_move_zc2_hi,x
600a: 65 8b adc ]rng_result+1
600c: 9d 38 9e sta obj_move_zc_hi,x
600f: ea nop
6010: bd 70 9d lda obj_spdlim_x_lo,x ;repeat for X speed
6013: 85 86 sta ]rng_limit
6015: bd 98 9d lda obj_spdlim_x_hi,x
6018: 85 87 sta ]rng_limit+1
601a: 20 b0 7b jsr GenRandom
601d: bd 80 9c lda obj_move_xc2_lo,x
6020: 18 clc
6021: 65 8a adc ]rng_result
6023: 9d 60 9e sta obj_move_xc_lo,x
6026: bd a8 9c lda obj_move_xc2_hi,x
6029: 65 8b adc ]rng_result+1
602b: 9d 88 9e sta obj_move_xc_hi,x
602e: ea nop
602f: bd c0 9d lda obj_spdlim_y_lo,x ;repeat for Y speed
6032: 85 86 sta ]rng_limit
6034: bd e8 9d lda obj_spdlim_y_hi,x
6037: 85 87 sta ]rng_limit+1
6039: 20 b0 7b jsr GenRandom
603c: bd d0 9c lda obj_move_yc2_lo,x
603f: 18 clc
6040: 65 8a adc ]rng_result
6042: 9d b0 9e sta obj_move_yc_lo,x
6045: bd f8 9c lda obj_move_yc2_hi,x
6048: 65 8b adc ]rng_result+1
604a: 9d d8 9e sta obj_move_yc_hi,x
604d: ea nop
;
604e: 18 clc ;do sound stuff
604f: a5 b2 lda engine_sound_ctr?+1
6051: 69 2c adc #$2c
6053: 85 b2 sta engine_sound_ctr?+1
6055: 90 0f bcc :NoSound
6057: e6 b3 inc engine_sound_ctr?+2
6059: a5 cc lda engine_sound_enable
605b: f0 09 beq :NoSound
605d: a5 b3 lda engine_sound_ctr?+2
605f: 25 b1 and engine_sound_ctr?
6061: d0 03 bne :NoSound
6063: ad 30 c0 lda SPKR
6066: 20 7f 7f :NoSound jsr Return7f7f
; Reset the velocity-change counter, and update the state so that we don't try
; to change the velocity again if this isn't a ship.
6069: bd 68 9b :ResetVelChgCtr lda vel_change_intvl_max,x
606c: d0 09 bne :IsShip ;nonzero for enemy ships
606e: a9 01 lda #$01
6070: 9d 18 9b sta obj_activity_state,x ;not enemy ship, mark as "don't update velocity"
6073: ea nop
6074: 4c 8d 60 jmp :MoveStuff
6077: 85 86 :IsShip sta ]rng_limit ;use value as RNG limit
6079: a9 00 lda #$00
607b: 85 87 sta ]rng_limit+1
607d: 85 88 sta ]rng_limit_mode
607f: 20 b0 7b jsr GenRandom ;get value in $8a-8b
6082: 18 clc
6083: a5 8a lda ]rng_result
6085: 69 02 adc #$02 ;add 2
6087: 9d 90 9b sta vel_change_ctr,x ;set counter
608a: 20 7f 7f jsr Return7f7f
;
; Calculate object movement.
;
]move_abs .var $86 {addr/2}
]table2_val2? .var $88 {addr/2}
]table2_val1? .var $8a {addr/1}
]lz_count .var $8b {addr/1}
]turn_angle? .var $8c {addr/2}
608d: bd 88 9e :MoveStuff lda obj_move_xc_hi,x ;get high byte of X move
6090: 10 10 bpl :IsPosX ;positive, branch
6092: 38 sec
6093: a9 00 lda #$00 ;compute absolute value (0 - value)
6095: fd 60 9e sbc obj_move_xc_lo,x
6098: 85 86 sta ]move_abs
609a: a9 00 lda #$00
609c: fd 88 9e sbc obj_move_xc_hi,x
609f: 4c aa 60 jmp :ContX
60a2: bc 60 9e :IsPosX ldy obj_move_xc_lo,x ;copy low byte
60a5: 84 86 sty ]move_abs
60a7: bd 88 9e lda obj_move_xc_hi,x ;set flags for high byte
60aa: ea :ContX nop
60ab: d0 18 bne :BigX ;high byte nonzero, branch
60ad: a4 86 ldy ]move_abs ;get low byte
60af: b9 00 b9 lda clz_table,y ;count leading zeroes
60b2: 18 clc
60b3: 69 08 adc #$08 ;add 8 for the high byte
60b5: 85 8b sta ]lz_count ;save leading zero count
60b7: 69 a4 adc #>math_tab2_base?-$800 ;compute pointer (without the +8)
60b9: 85 13 sta math_tab_ptr12+1
60bb: a4 86 ldy ]move_abs ;(?)
60bd: b1 12 lda (math_tab_ptr12),y ;get value from table
60bf: 85 8a sta ]table2_val1?
60c1: ea nop
60c2: 4c df 60 jmp :GotThingX
60c5: 85 87 :BigX sta ]move_abs+1 ;save high byte
60c7: a8 tay
60c8: b9 00 b9 lda clz_table,y ;count leading zeroes
60cb: a8 tay
60cc: 85 8b sta ]lz_count ;save leading zero count
60ce: 18 clc
60cf: 69 ac adc #>math_tab2_base? ;compute pointer
60d1: 85 13 sta math_tab_ptr12+1
60d3: a5 86 lda ]move_abs ;get low byte
60d5: 39 d5 00 and bit_mask_left9,y ;mask off overlapping bits
60d8: 05 87 ora ]move_abs+1 ;merge with high byte
60da: a8 tay ;use as index
60db: b1 12 lda (math_tab_ptr12),y ;get value from table
60dd: 85 8a sta ]table2_val1?
60df: ea :GotThingX nop
60e0: 18 clc
60e1: a4 8a ldy ]table2_val1?
60e3: b9 00 b5 lda turn_map_lo?,y
60e6: 65 9a adc joy_yaw_angle ;add joystick yaw magnitude
60e8: 85 8c sta ]turn_angle?
60ea: a5 9b lda joy_yaw_angle+1
60ec: e5 8b sbc ]lz_count
60ee: 30 21 bmi :SlowYaw
60f0: 85 8d sta ]turn_angle?+1
60f2: 38 sec
60f3: ea nop
60f4: 69 ac adc #>math_tab2_base?
60f6: 85 15 sta math_tab_ptr14+1
60f8: a4 8c ldy ]turn_angle?
60fa: b9 00 17 lda math_tab1_lastpg?,y
60fd: a8 tay
60fe: b1 14 lda (math_tab_ptr14),y
6100: 85 89 sta ]table2_val2?+1
6102: a4 8d ldy ]turn_angle?+1
6104: 39 ef 00 and bit_mask_left8,y
6107: 85 88 sta ]table2_val2?
6109: a5 89 lda ]table2_val2?+1
610b: 39 e7 00 and bit_mask_right8,y
610e: 4c 2d 61 jmp L612D
6111: ea :SlowYaw nop
6112: 18 clc
6113: 69 08 adc #$08
6115: 30 12 bmi :NoYaw
6117: 18 clc
6118: 69 10 adc #>math_tab1_base?
611a: 85 15 sta math_tab_ptr14+1
611c: a4 8c ldy ]turn_angle?
611e: a9 00 lda #$00
6120: 85 89 sta ]table2_val2?+1
6122: b1 14 lda (math_tab_ptr14),y
6124: 85 88 sta ]table2_val2?
6126: 4c 2f 61 jmp L612F
6129: a9 00 :NoYaw lda #$00
612b: 85 88 sta ]table2_val2?
612d: 85 89 L612D sta ]table2_val2?+1
; Update Z movement with results.
612f: ea L612F nop
6130: bd 88 9e lda obj_move_xc_hi,x
6133: 45 9c eor joy_yaw_sign
6135: 10 2a bpl L6161
6137: 18 clc
6138: bd 10 9e lda obj_move_zc_lo,x
613b: 65 88 adc ]table2_val2?
613d: 9d 10 9e sta obj_move_zc_lo,x
6140: bd 38 9e lda obj_move_zc_hi,x
6143: 65 89 adc ]table2_val2?+1
6145: 9d 38 9e sta obj_move_zc_hi,x
6148: a5 bb lda update_mvmt_flag
614a: f0 3c beq :CalcY
614c: 18 clc
614d: bd 30 9c lda obj_move_zc2_lo,x
6150: 65 88 adc ]table2_val2?
6152: 9d 30 9c sta obj_move_zc2_lo,x
6155: bd 58 9c lda obj_move_zc2_hi,x
6158: 65 89 adc ]table2_val2?+1
615a: 9d 58 9c sta obj_move_zc2_hi,x
615d: ea nop
615e: 4c 88 61 jmp :CalcY
6161: 38 L6161 sec
6162: bd 10 9e lda obj_move_zc_lo,x
6165: e5 88 sbc ]table2_val2?
6167: 9d 10 9e sta obj_move_zc_lo,x
616a: bd 38 9e lda obj_move_zc_hi,x
616d: e5 89 sbc ]table2_val2?+1
616f: 9d 38 9e sta obj_move_zc_hi,x
6172: a5 bb lda update_mvmt_flag ;object changes direction sometimes?
6174: f0 12 beq :CalcY ;no, skip this next part
6176: 38 sec
6177: bd 30 9c lda obj_move_zc2_lo,x
617a: e5 88 sbc ]table2_val2?
617c: 9d 30 9c sta obj_move_zc2_lo,x
617f: bd 58 9c lda obj_move_zc2_hi,x
6182: e5 89 sbc ]table2_val2?+1
6184: 9d 58 9c sta obj_move_zc2_hi,x
6187: ea nop
;
; Repeat for Y coordinate.
;
6188: bd d8 9e :CalcY lda obj_move_yc_hi,x
618b: 10 10 bpl :PosY
618d: 38 sec
618e: a9 00 lda #$00
6190: fd b0 9e sbc obj_move_yc_lo,x
6193: 85 86 sta ]move_abs
6195: a9 00 lda #$00
6197: fd d8 9e sbc obj_move_yc_hi,x
619a: 4c a5 61 jmp :ContY
619d: bc b0 9e :PosY ldy obj_move_yc_lo,x
61a0: 84 86 sty ]move_abs
61a2: bd d8 9e lda obj_move_yc_hi,x
61a5: ea :ContY nop
61a6: d0 18 bne L61C0
61a8: a4 86 ldy ]move_abs
61aa: b9 00 b9 lda clz_table,y
61ad: 18 clc
61ae: 69 08 adc #$08
61b0: 85 8b sta ]lz_count
61b2: 69 a4 adc #>math_tab2_base?-$800
61b4: 85 13 sta math_tab_ptr12+1
61b6: a4 86 ldy ]move_abs
61b8: b1 12 lda (math_tab_ptr12),y
61ba: 85 8a sta ]table2_val1?
61bc: ea nop
61bd: 4c da 61 jmp L61DA
61c0: 85 87 L61C0 sta ]move_abs+1
61c2: a8 tay
61c3: b9 00 b9 lda clz_table,y
61c6: a8 tay
61c7: 85 8b sta ]lz_count
61c9: 18 clc
61ca: 69 ac adc #>math_tab2_base?
61cc: 85 13 sta math_tab_ptr12+1
61ce: a5 86 lda ]move_abs
61d0: 39 d5 00 and bit_mask_left9,y
61d3: 05 87 ora ]move_abs+1
61d5: a8 tay
61d6: b1 12 lda (math_tab_ptr12),y
61d8: 85 8a sta ]table2_val1?
61da: ea L61DA nop
61db: 18 clc
61dc: a4 8a ldy ]table2_val1?
61de: b9 00 b5 lda turn_map_lo?,y
61e1: 65 9d adc joy_pitch_angle
61e3: 85 8c sta ]turn_angle?
61e5: a5 9e lda joy_pitch_angle+1
61e7: e5 8b sbc ]lz_count
61e9: 30 21 bmi :SlowPitch
61eb: 85 8d sta ]turn_angle?+1
61ed: 38 sec
61ee: ea nop
61ef: 69 ac adc #>math_tab2_base?
61f1: 85 15 sta math_tab_ptr14+1
61f3: a4 8c ldy ]turn_angle?
61f5: b9 00 17 lda math_tab1_lastpg?,y
61f8: a8 tay
61f9: b1 14 lda (math_tab_ptr14),y
61fb: 85 89 sta ]table2_val2?+1
61fd: a4 8d ldy ]turn_angle?+1
61ff: 39 ef 00 and bit_mask_left8,y
6202: 85 88 sta ]table2_val2?
6204: a5 89 lda ]table2_val2?+1
6206: 39 e7 00 and bit_mask_right8,y
6209: 4c 28 62 jmp L6228
620c: ea :SlowPitch nop
620d: 18 clc
620e: 69 08 adc #$08
6210: 30 12 bmi :NoPitch
6212: 18 clc
6213: 69 10 adc #>math_tab1_base?
6215: 85 15 sta math_tab_ptr14+1
6217: a4 8c ldy ]turn_angle?
6219: a9 00 lda #$00
621b: 85 89 sta ]table2_val2?+1
621d: b1 14 lda (math_tab_ptr14),y
621f: 85 88 sta ]table2_val2?
6221: 4c 2a 62 jmp L622A
6224: a9 00 :NoPitch lda #$00
6226: 85 88 sta ]table2_val2?
6228: 85 89 L6228 sta ]table2_val2?+1
; Update Z movement with results.
622a: ea L622A nop
622b: bd d8 9e lda obj_move_yc_hi,x
622e: 45 9f eor joy_pitch_sign
6230: 10 2a bpl L625C
6232: 18 clc
6233: bd 10 9e lda obj_move_zc_lo,x
6236: 65 88 adc ]table2_val2?
6238: 9d 10 9e sta obj_move_zc_lo,x
623b: bd 38 9e lda obj_move_zc_hi,x
623e: 65 89 adc ]table2_val2?+1
6240: 9d 38 9e sta obj_move_zc_hi,x
6243: a5 bb lda update_mvmt_flag
6245: f0 3c beq L6283
6247: 18 clc
6248: bd 30 9c lda obj_move_zc2_lo,x
624b: 65 88 adc ]table2_val2?
624d: 9d 30 9c sta obj_move_zc2_lo,x
6250: bd 58 9c lda obj_move_zc2_hi,x
6253: 65 89 adc ]table2_val2?+1
6255: 9d 58 9c sta obj_move_zc2_hi,x
6258: ea nop
6259: 4c 83 62 jmp L6283
625c: 38 L625C sec
625d: bd 10 9e lda obj_move_zc_lo,x
6260: e5 88 sbc ]table2_val2?
6262: 9d 10 9e sta obj_move_zc_lo,x
6265: bd 38 9e lda obj_move_zc_hi,x
6268: e5 89 sbc ]table2_val2?+1
626a: 9d 38 9e sta obj_move_zc_hi,x
626d: a5 bb lda update_mvmt_flag
626f: f0 12 beq L6283
6271: 38 sec
6272: bd 30 9c lda obj_move_zc2_lo,x
6275: e5 88 sbc ]table2_val2?
6277: 9d 30 9c sta obj_move_zc2_lo,x
627a: bd 58 9c lda obj_move_zc2_hi,x
627d: e5 89 sbc ]table2_val2?+1
627f: 9d 58 9c sta obj_move_zc2_hi,x
6282: ea nop
;
; Repeat for Z coordinate.
;
6283: bd 38 9e L6283 lda obj_move_zc_hi,x
6286: 10 10 bpl L6298
6288: 38 sec
6289: a9 00 lda #$00
628b: fd 10 9e sbc obj_move_zc_lo,x
628e: 85 86 sta ]move_abs
6290: a9 00 lda #$00
6292: fd 38 9e sbc obj_move_zc_hi,x
6295: 4c a0 62 jmp L62A0
6298: bc 10 9e L6298 ldy obj_move_zc_lo,x
629b: 84 86 sty ]move_abs
629d: bd 38 9e lda obj_move_zc_hi,x
62a0: ea L62A0 nop
62a1: d0 18 bne L62BB
62a3: a4 86 ldy ]move_abs
62a5: b9 00 b9 lda clz_table,y
62a8: 18 clc
62a9: 69 08 adc #$08
62ab: 85 8b sta ]lz_count
62ad: 69 a4 adc #>math_tab2_base?-$800
62af: 85 13 sta math_tab_ptr12+1
62b1: a4 86 ldy ]move_abs
62b3: b1 12 lda (math_tab_ptr12),y
62b5: 85 8a sta ]table2_val1?
62b7: ea nop
62b8: 4c d5 62 jmp L62D5
62bb: 85 87 L62BB sta ]move_abs+1
62bd: a8 tay
62be: b9 00 b9 lda clz_table,y
62c1: a8 tay
62c2: 85 8b sta ]lz_count
62c4: 18 clc
62c5: 69 ac adc #>math_tab2_base?
62c7: 85 13 sta math_tab_ptr12+1
62c9: a5 86 lda ]move_abs
62cb: 39 d5 00 and bit_mask_left9,y
62ce: 05 87 ora ]move_abs+1
62d0: a8 tay
62d1: b1 12 lda (math_tab_ptr12),y
62d3: 85 8a sta ]table2_val1?
62d5: ea L62D5 nop
62d6: 18 clc
62d7: a4 8a ldy ]table2_val1?
62d9: b9 00 b5 lda turn_map_lo?,y
62dc: 65 9a adc joy_yaw_angle
62de: 85 8c sta ]turn_angle?
62e0: a5 9b lda joy_yaw_angle+1
62e2: e5 8b sbc ]lz_count
62e4: 30 21 bmi :SlowYaw
62e6: 85 8d sta ]turn_angle?+1
62e8: 38 sec
62e9: ea nop
62ea: 69 ac adc #>math_tab2_base?
62ec: 85 15 sta math_tab_ptr14+1
62ee: a4 8c ldy ]turn_angle?
62f0: b9 00 17 lda math_tab1_lastpg?,y
62f3: a8 tay
62f4: b1 14 lda (math_tab_ptr14),y
62f6: 85 89 sta ]table2_val2?+1
62f8: a4 8d ldy ]turn_angle?+1
62fa: 39 ef 00 and bit_mask_left8,y
62fd: 85 88 sta ]table2_val2?
62ff: a5 89 lda ]table2_val2?+1
6301: 39 e7 00 and bit_mask_right8,y
6304: 4c 23 63 jmp L6323
6307: ea :SlowYaw nop
6308: 18 clc
6309: 69 08 adc #$08
630b: 30 12 bmi :NoYaw
630d: 18 clc
630e: 69 10 adc #>math_tab1_base?
6310: 85 15 sta math_tab_ptr14+1
6312: a4 8c ldy ]turn_angle?
6314: a9 00 lda #$00
6316: 85 89 sta ]table2_val2?+1
6318: b1 14 lda (math_tab_ptr14),y
631a: 85 88 sta ]table2_val2?
631c: 4c 25 63 jmp L6325
631f: a9 00 :NoYaw lda #$00
6321: 85 88 sta ]table2_val2?
6323: 85 89 L6323 sta ]table2_val2?+1
; Update X/Y movement with results.
6325: ea L6325 nop
6326: bd 38 9e lda obj_move_zc_hi,x
6329: 45 9c eor joy_yaw_sign
632b: 30 2a bmi L6357
632d: 18 clc
632e: bd 60 9e lda obj_move_xc_lo,x
6331: 65 88 adc ]table2_val2?
6333: 9d 60 9e sta obj_move_xc_lo,x
6336: bd 88 9e lda obj_move_xc_hi,x
6339: 65 89 adc ]table2_val2?+1
633b: 9d 88 9e sta obj_move_xc_hi,x
633e: a5 bb lda update_mvmt_flag
6340: f0 3c beq L637E
6342: 18 clc
6343: bd 80 9c lda obj_move_xc2_lo,x
6346: 65 88 adc ]table2_val2?
6348: 9d 80 9c sta obj_move_xc2_lo,x
634b: bd a8 9c lda obj_move_xc2_hi,x
634e: 65 89 adc ]table2_val2?+1
6350: 9d a8 9c sta obj_move_xc2_hi,x
6353: ea nop
6354: 4c 7e 63 jmp L637E
6357: 38 L6357 sec
6358: bd 60 9e lda obj_move_xc_lo,x
635b: e5 88 sbc ]table2_val2?
635d: 9d 60 9e sta obj_move_xc_lo,x
6360: bd 88 9e lda obj_move_xc_hi,x
6363: e5 89 sbc ]table2_val2?+1
6365: 9d 88 9e sta obj_move_xc_hi,x
6368: a5 bb lda update_mvmt_flag
636a: f0 12 beq L637E
636c: 38 sec
636d: bd 80 9c lda obj_move_xc2_lo,x
6370: e5 88 sbc ]table2_val2?
6372: 9d 80 9c sta obj_move_xc2_lo,x
6375: bd a8 9c lda obj_move_xc2_hi,x
6378: e5 89 sbc ]table2_val2?+1
637a: 9d a8 9c sta obj_move_xc2_hi,x
637d: ea nop
637e: 18 L637E clc
637f: 18 clc
6380: a4 8a ldy ]table2_val1?
6382: b9 00 b5 lda turn_map_lo?,y
6385: 65 9d adc joy_pitch_angle
6387: 85 8c sta ]turn_angle?
6389: a5 9e lda joy_pitch_angle+1
638b: e5 8b sbc ]lz_count
638d: 30 21 bmi :SlowPitch
638f: 85 8d sta ]turn_angle?+1
6391: 38 sec
6392: ea nop
6393: 69 ac adc #>math_tab2_base?
6395: 85 15 sta math_tab_ptr14+1
6397: a4 8c ldy ]turn_angle?
6399: b9 00 17 lda math_tab1_lastpg?,y
639c: a8 tay
639d: b1 14 lda (math_tab_ptr14),y
639f: 85 89 sta ]table2_val2?+1
63a1: a4 8d ldy ]turn_angle?+1
63a3: 39 ef 00 and bit_mask_left8,y
63a6: 85 88 sta ]table2_val2?
63a8: a5 89 lda ]table2_val2?+1
63aa: 39 e7 00 and bit_mask_right8,y
63ad: 4c cc 63 jmp L63CC
63b0: ea :SlowPitch nop
63b1: 18 clc
63b2: 69 08 adc #$08
63b4: 30 12 bmi :NoPitch
63b6: 18 clc
63b7: 69 10 adc #>math_tab1_base?
63b9: 85 15 sta math_tab_ptr14+1
63bb: a4 8c ldy ]turn_angle?
63bd: a9 00 lda #$00
63bf: 85 89 sta ]table2_val2?+1
63c1: b1 14 lda (math_tab_ptr14),y
63c3: 85 88 sta ]table2_val2?
63c5: 4c ce 63 jmp L63CE
63c8: a9 00 :NoPitch lda #$00
63ca: 85 88 sta ]table2_val2?
63cc: 85 89 L63CC sta ]table2_val2?+1
63ce: ea L63CE nop
63cf: bd 38 9e lda obj_move_zc_hi,x
63d2: 45 9f eor joy_pitch_sign
63d4: 30 2a bmi L6400
63d6: 18 clc
63d7: bd b0 9e lda obj_move_yc_lo,x
63da: 65 88 adc ]table2_val2?
63dc: 9d b0 9e sta obj_move_yc_lo,x
63df: bd d8 9e lda obj_move_yc_hi,x
63e2: 65 89 adc ]table2_val2?+1
63e4: 9d d8 9e sta obj_move_yc_hi,x
63e7: a5 bb lda update_mvmt_flag
63e9: f0 3c beq L6427
63eb: 18 clc
63ec: bd d0 9c lda obj_move_yc2_lo,x
63ef: 65 88 adc ]table2_val2?
63f1: 9d d0 9c sta obj_move_yc2_lo,x
63f4: bd f8 9c lda obj_move_yc2_hi,x
63f7: 65 89 adc ]table2_val2?+1
63f9: 9d f8 9c sta obj_move_yc2_hi,x
63fc: ea nop
63fd: 4c 27 64 jmp L6427
6400: 38 L6400 sec
6401: bd b0 9e lda obj_move_yc_lo,x
6404: e5 88 sbc ]table2_val2?
6406: 9d b0 9e sta obj_move_yc_lo,x
6409: bd d8 9e lda obj_move_yc_hi,x
640c: e5 89 sbc ]table2_val2?+1
640e: 9d d8 9e sta obj_move_yc_hi,x
6411: a5 bb lda update_mvmt_flag
6413: f0 12 beq L6427
6415: 38 sec
6416: bd d0 9c lda obj_move_yc2_lo,x
6419: e5 88 sbc ]table2_val2?
641b: 9d d0 9c sta obj_move_yc2_lo,x
641e: bd f8 9c lda obj_move_yc2_hi,x
6421: e5 89 sbc ]table2_val2?+1
6423: 9d f8 9c sta obj_move_yc2_hi,x
6426: ea nop
6427: 20 7f 7f L6427 jsr Return7f7f
642a: 18 clc ;do sound stuff
642b: a5 b2 lda engine_sound_ctr?+1
642d: 69 30 adc #$30
642f: 85 b2 sta engine_sound_ctr?+1
6431: 90 0f bcc GetFirstElemIndex
6433: e6 b3 inc engine_sound_ctr?+2
6435: a5 cc lda engine_sound_enable
6437: f0 09 beq GetFirstElemIndex
6439: a5 b3 lda engine_sound_ctr?+2
643b: 25 b1 and engine_sound_ctr?
643d: d0 03 bne GetFirstElemIndex
643f: ad 30 c0 lda SPKR
;
; Extracts the index of an object's first element into X-reg and ZP.
;
; On entry:
; X-reg: object index
;
; On exit:
; $64 and X-reg: element index
;
GetFirstElemIndex
6442: bd 00 9a lda obj_first_elem_index,x
6445: aa tax
6446: 85 64 sta cur_elem_index
6448: 60 rts
6449: 3d 3d 3d 3d+ .junk 12
;
; Updates element coordinates with object movement vector, and generates screen
; coordinates for use by the render functions.
;
; Player movement -- pitch/yaw and forward speed -- are applied evenly to all
; element coordinates here.
;
; On entry:
; X-reg: element index
;
; On exit:
; $70: new value for modified element type
; $7e: screen top (0-191)
; $80: screen bottom (0-191)
; $82: abs value of screen left (0-139)
; $84: abs value of screen right (0-139)
; X-reg preserved
;
; (Not all coordinates may be set, e.g. points only need top/left.)
;
• Clear variables
]new_zpos .var $86 {addr/2}
]zpos_sign .var $8c {addr/1}
6455: a9 00 UpdateElement lda #$00
6457: 85 7c sta no_draw_elem_flag? ;clear flag
6459: 85 70 sta mod_elem_type ;set mod type to point
645b: 85 76 sta clamped_lr_count ;init counters
645d: 85 78 sta clamped_tb_count
645f: 85 7a sta elem_bad_z_flag? ;clear flag
6461: a5 c8 lda sound_counters
6463: f0 03 beq :NoSound
6465: ad 30 c0 lda SPKR
6468: a9 ad :NoSound lda #INSTR_LDA_ABS
646a: 20 4c 7b jsr ModDrwEraVrtRct ;suppress drawing (why?)
646d: a5 72 lda no_draw_obj_flag ;check flag
646f: f0 0e beq :DoDraw ;not set, branch
6471: e6 7c inc no_draw_elem_flag?
6473: 4c 93 6b jmp :RestoreRts
; Element crossed "far" plane ($8000), do not draw.
6476: e6 7a :NoDrawZC inc elem_bad_z_flag?
6478: e6 7c inc no_draw_elem_flag?
647a: e6 72 inc no_draw_obj_flag
647c: 4c 93 6b jmp :RestoreRts
; Update Z coordinate with object and player movement. +Z is away from viewer.
; If the Z coordinate is >= $8000, it has disappeared into the distance. If
; it's <= 0, we've flown past it or into it.
;
; Note this does not take joystick angles into account.
647f: 18 :DoDraw clc
6480: a4 62 ldy cur_obj_index ;get object index
6482: bd 40 a1 lda elem_zpos_lo,x ;get current Z position
6485: 79 10 9e adc obj_move_zc_lo,y ;add object movement
6488: 85 86 sta ]new_zpos ;save in ZP
648a: bd 80 a1 lda elem_zpos_hi,x
648d: 85 8c sta ]zpos_sign ;sign of zpos; note does not include player movement
648f: 79 38 9e adc obj_move_zc_hi,y ;repeat for high byte
6492: 70 e2 bvs :NoDrawZC ;branch if we passed $8000 (signed overflow)
6494: 85 87 sta ]new_zpos+1
6496: a5 86 lda ]new_zpos ;subtract player's speed
6498: 38 sec
6499: e5 98 sbc adj_fwd_speed
649b: 9d 40 a1 sta elem_zpos_lo,x ;update value in table
649e: 85 86 sta ]new_zpos ;update value in ZP
64a0: a8 tay
64a1: a5 87 lda ]new_zpos+1
64a3: e5 99 sbc adj_fwd_speed+1 ;repeat for high byte
64a5: 70 cf bvs :NoDrawZC ;branch if we passed $8000 (shouldn't be possible
64a7: 9d 80 a1 sta elem_zpos_hi,x ; unless we can move backward)
64aa: ea nop
64ab: 85 87 sta ]new_zpos+1
64ad: 30 03 bmi :CheckFlewInto ;if high byte negative, it's behind us
64af: 4c df 64 jmp :CheckZZero ;object somewhere in front of us, continue on
64b2: a5 8c :CheckFlewInto lda ]zpos_sign ;check the Z position before the player moved
64b4: 10 06 bpl :FlewInto ;was positive, player flew into element plane; branch
64b6: 20 7f 7f jsr Return7f7f ;was negative, object flew into player... distinction
64b9: 4c aa 69 jmp :ObjectBehind ; w/o a diff, but we know it's not base/portal
64bc: a4 62 :FlewInto ldy cur_obj_index ;get index of object we may have flown into
64be: 20 7f 7f jsr Return7f7f
64c1: a9 00 lda #$00
64c3: 8d 98 6d sta time_portal_fail_ctr ;reset time portal fail counter
64c6: b9 a0 9a lda obj_shape_uid,y ;get shape unique ID
64c9: 29 f0 and #$f0
64cb: c9 f0 cmp #$f0 ;(not used by game?)
64cd: f0 0d beq :NotHostile
64cf: c9 50 cmp #$50 ;time portal boundary?
64d1: f0 09 beq :NotHostile ;yes, branch
64d3: c9 60 cmp #$60 ;friendly base or time portal?
64d5: f0 05 beq :NotHostile ;yes, branch
64d7: e6 f8 inc elem_collision_flag ;possibly bumped an enemy ship, base, or projectile
64d9: 20 7f 7f jsr Return7f7f
64dc: 4c aa 69 :NotHostile jmp :ObjectBehind
64df: d0 12 :CheckZZero bne :CheckSameZ ;high byte nonzero, branch
64e1: a4 86 ldy ]new_zpos ;get low byte
64e3: d0 0e bne :CheckSameZ ;nonzero, branch
64e5: e6 7c inc no_draw_elem_flag? ;we're at Z=0, don't draw this element
64e7: a9 ff lda #$ff
64e9: 85 86 sta ]new_zpos ;set Z position to -1
64eb: 85 87 sta ]new_zpos+1
64ed: 20 7f 7f jsr Return7f7f
64f0: 4c bc 64 jmp :FlewInto ;jump to "we flew into something" code
; Object is in front of us.
;
; Check to see if the previous element we processed had the same Z coordinate.
; If so, we can avoid repeating some of the calculations.
64f3: 20 7f 7f :CheckSameZ jsr Return7f7f
64f6: c5 c6 cmp prev_zpos+1 ;does high byte of new_zpos match previous?
64f8: d0 0b bne :MismatchHi ;no, branch
64fa: c4 c5 cpy prev_zpos ;does low byte match?
64fc: d0 09 bne :MismatchLo ;no, branch
64fe: a5 be lda prev_scale_tab_ptr11 ;match; get previous pointer value
6500: 85 13 sta math_tab_ptr12+1 ; and store in pointer
6502: 4c 13 66 jmp :SkipZCalc ;skip the following calculation
; Previous Z coord didn't match, perform calculations.
;
; Remember that all movement is calculated as deltas, not absolutes, and that
; everything is in eye space. If an enemy ship moved 10 units to the left, we
; shift it 10 units, regardless of position. If we rotated 5 degrees, however,
; the distance from the viewer determines how many units it moves.
;
; The amount of movement is the same for all points with the same Z coordinate.
; In a "true" 3D system that wouldn't be the case, but Epoch keeps all elements
; parallel to the view plane. So when we rotate left, the elements move right,
; and effectively rotate away from the viewer to maintain their parallel
; orientation.
6505: 85 c6 :MismatchHi sta prev_zpos+1 ;save new_zpos+1
6507: 84 c5 :MismatchLo sty prev_zpos ;save new_zpos
6509: a5 87 lda ]new_zpos+1
650b: d0 20 bne :BigZ
650d: a4 86 ldy ]new_zpos
650f: b9 00 b9 lda clz_table,y
6512: a8 tay
6513: 18 clc
6514: 69 08 adc #$08
6516: 85 bd sta zcoord_clz
6518: 69 a4 adc #>math_tab2_base?-$800
651a: 85 13 sta math_tab_ptr12+1
651c: ad a7 6d lda speed_fraction
651f: 39 d5 00 and bit_mask_left9,y
6522: 05 86 ora ]new_zpos
6524: a8 tay
6525: b1 12 lda (math_tab_ptr12),y
6527: 85 bc sta zcoord_factor
6529: ea nop
652a: 4c 47 65 jmp :CalcYaw
652d: 85 87 :BigZ sta ]new_zpos+1
652f: a8 tay
6530: b9 00 b9 lda clz_table,y
6533: a8 tay
6534: 85 bd sta zcoord_clz
6536: 18 clc
6537: 69 ac adc #>math_tab2_base?
6539: 85 13 sta math_tab_ptr12+1
653b: a5 86 lda ]new_zpos
653d: 39 d5 00 and bit_mask_left9,y
6540: 05 87 ora ]new_zpos+1
6542: a8 tay
6543: b1 12 lda (math_tab_ptr12),y
6545: 85 bc sta zcoord_factor
; Compute movement delta (in eye coordinates) caused by player yaw (joystick
; horizontal axis).
]yaw_thing? .var $8c {addr/2}
]yaw_move .var $94 {addr/2}
6547: ea :CalcYaw nop
6548: 20 7f 7f jsr Return7f7f
654b: a5 13 lda math_tab_ptr12+1
654d: 85 be sta prev_scale_tab_ptr11
654f: 18 clc
6550: a4 bc ldy zcoord_factor
6552: b9 00 b5 lda turn_map_lo?,y
6555: 65 9a adc joy_yaw_angle
6557: 85 8c sta ]yaw_thing?
6559: a5 9b lda joy_yaw_angle+1
655b: e5 bd sbc zcoord_clz
655d: 30 25 bmi :SlowYaw
655f: 85 8d sta ]yaw_thing?+1
6561: 38 sec
6562: ea nop
6563: 69 ac adc #>math_tab2_base?
6565: 85 15 sta math_tab_ptr14+1
6567: a4 8c ldy ]yaw_thing?
6569: b9 00 17 lda math_tab1_lastpg?,y
656c: a8 tay
656d: b1 14 lda (math_tab_ptr14),y
656f: 85 95 sta ]yaw_move+1
6571: a4 8d ldy ]yaw_thing?+1
6573: 39 ef 00 and bit_mask_left8,y
6576: 45 9c eor joy_yaw_sign
6578: 85 94 sta ]yaw_move
657a: a5 95 lda ]yaw_move+1
657c: 39 e7 00 and bit_mask_right8,y
657f: 45 9c eor joy_yaw_sign
6581: 4c a0 65 jmp L65A0
6584: ea :SlowYaw nop
6585: 18 clc
6586: 69 08 adc #$08
6588: 30 12 bmi :NoYaw
658a: 18 clc
658b: 69 10 adc #>math_tab1_base?
658d: 85 15 sta math_tab_ptr14+1
658f: a4 8c ldy ]yaw_thing?
6591: a5 9c lda joy_yaw_sign
6593: 85 95 sta ]yaw_move+1
6595: 51 14 eor (math_tab_ptr14),y
6597: 85 94 sta ]yaw_move
6599: 4c a2 65 jmp :CalcPitch
659c: a9 00 :NoYaw lda #$00
659e: 85 94 sta ]yaw_move
65a0: 85 95 L65A0 sta ]yaw_move+1
; Compute movement delta (in eye coordinates) caused by player pitch (joystick
; vertical axis).
]pitch_thing? .var $8c {addr/2}
]pitch_move .var $96 {addr/2}
65a2: ea :CalcPitch nop
65a3: 18 clc
65a4: 18 clc
65a5: a4 bc ldy zcoord_factor
65a7: b9 00 b5 lda turn_map_lo?,y
65aa: 65 9d adc joy_pitch_angle
65ac: 85 8c sta ]pitch_thing?
65ae: a5 9e lda joy_pitch_angle+1
65b0: e5 bd sbc zcoord_clz
65b2: 30 25 bmi :SlowPitch
65b4: 85 8d sta ]pitch_thing?+1
65b6: 38 sec
65b7: ea nop
65b8: 69 ac adc #>math_tab2_base?
65ba: 85 15 sta math_tab_ptr14+1
65bc: a4 8c ldy ]pitch_thing?
65be: b9 00 17 lda math_tab1_lastpg?,y
65c1: a8 tay
65c2: b1 14 lda (math_tab_ptr14),y
65c4: 85 97 sta ]pitch_move+1
65c6: a4 8d ldy ]pitch_thing?+1
65c8: 39 ef 00 and bit_mask_left8,y
65cb: 45 9f eor joy_pitch_sign
65cd: 85 96 sta ]pitch_move
65cf: a5 97 lda ]pitch_move+1
65d1: 39 e7 00 and bit_mask_right8,y
65d4: 45 9f eor joy_pitch_sign
65d6: 4c f5 65 jmp L65F5
65d9: ea :SlowPitch nop
65da: 18 clc
65db: 69 08 adc #$08
65dd: 30 12 bmi :NoPitch
65df: 18 clc
65e0: 69 10 adc #>math_tab1_base?
65e2: 85 15 sta math_tab_ptr14+1
65e4: a4 8c ldy ]pitch_thing?
65e6: a5 9f lda joy_pitch_sign
65e8: 85 97 sta ]pitch_move+1
65ea: 51 14 eor (math_tab_ptr14),y
65ec: 85 96 sta ]pitch_move
65ee: 4c f7 65 jmp L65F7
65f1: a9 00 :NoPitch lda #$00
65f3: 85 96 sta ]pitch_move
65f5: 85 97 L65F5 sta ]pitch_move+1
65f7: ea L65F7 nop
;
65f8: 20 7f 7f jsr Return7f7f
65fb: 18 clc ;do sound stuff
65fc: a5 b2 lda engine_sound_ctr?+1
65fe: 69 0d adc #$0d
6600: 85 b2 sta engine_sound_ctr?+1
6602: 90 0f bcc :SkipZCalc
6604: e6 b3 inc engine_sound_ctr?+2
6606: a5 cc lda engine_sound_enable
6608: f0 09 beq :SkipZCalc
660a: a5 b3 lda engine_sound_ctr?+2
660c: 25 b1 and engine_sound_ctr?
660e: d0 03 bne :SkipZCalc
6610: ad 30 c0 lda SPKR
; Jump here if the previous element had the same Z coord.
6613: 18 :SkipZCalc clc ;do sound stuff
6614: a5 b2 lda engine_sound_ctr?+1
6616: 69 23 adc #$23
6618: 85 b2 sta engine_sound_ctr?+1
661a: 90 0f bcc :NoSound2
661c: e6 b3 inc engine_sound_ctr?+2
661e: a5 cc lda engine_sound_enable
6620: f0 09 beq :NoSound2
6622: a5 b3 lda engine_sound_ctr?+2
6624: 25 b1 and engine_sound_ctr?
6626: d0 03 bne :NoSound2
6628: ad 30 c0 lda SPKR
;
; Update element coordinates, and calculate screen coordinates. Start with the
; left.
;
]scrn_yc_top .var $7e {addr/1}
]scrn_yc_btm .var $80 {addr/1}
]scrn_xc_lft_abs .var $82 {addr/1}
]scrn_xc_rgt_abs .var $84 {addr/1}
]updated_coord? .var $8c {addr/2}
662b: 18 :NoSound2 clc
662c: bd c0 a1 lda elem_left_lo,x ;get left coordinate, low byte
662f: 65 94 adc ]yaw_move ;add movement from joystick
6631: a8 tay ;hold in Y-reg
6632: bd 00 a2 lda elem_left_hi,x ;get high byte
6635: 65 95 adc ]yaw_move+1 ;add joystick movement
6637: 85 8f sta move_tmp+1
6639: 70 32 bvs :OffScreenLeft
663b: 18 clc
663c: 98 tya
663d: a4 62 ldy cur_obj_index
663f: 79 60 9e adc obj_move_xc_lo,y
6642: 9d c0 a1 sta elem_left_lo,x
6645: 85 8c sta ]updated_coord?
6647: a5 8f lda move_tmp+1
6649: 79 88 9e adc obj_move_xc_hi,y
664c: 70 1f bvs :OffScreenLeft
664e: 9d 00 a2 sta elem_left_hi,x
6651: 30 2c bmi :NegLeft
6653: a4 7c ldy no_draw_elem_flag?
6655: d0 1b bne :ZeroLeft1
6657: 85 8d sta ]updated_coord?+1
6659: ea nop
665a: a5 8c lda ]updated_coord?
665c: c5 86 cmp ]new_zpos
665e: a5 8d lda ]updated_coord?+1
6660: e5 87 sbc ]new_zpos+1
6662: ea nop
6663: 30 12 bmi :Jmp_LeftBoundsOk ;good, branch
6665: e6 76 :LeftBoundsBad inc clamped_lr_count
6667: a9 8a lda #138 ;clamp to left edge of screen
6669: a4 7a ldy elem_bad_z_flag? ;are we drawing this at all?
666b: f0 07 beq :ConstLeft ;yes, use constant value
666d: e6 72 :OffScreenLeft inc no_draw_obj_flag ;no, inc some flags and set to zero
666f: e6 7c inc no_draw_elem_flag?
6671: ea nop
6672: a9 00 :ZeroLeft1 lda #$00
6674: 4c e5 66 :ConstLeft jmp :GotLeft
:Jmp_LeftBoundsOk
6677: 4c a8 66 jmp :LeftBoundsOk
667a: a9 00 :ZeroLeft2 lda #$00
667c: 4c e5 66 jmp :GotLeft
667f: a5 7c :NegLeft lda no_draw_elem_flag?
6681: d0 ef bne :ZeroLeft1
6683: 38 sec
6684: a9 00 lda #$00
6686: e5 8c sbc ]updated_coord?
6688: 85 8c sta ]updated_coord?
668a: a9 00 lda #$00
668c: fd 00 a2 sbc elem_left_hi,x
668f: 85 8d sta ]updated_coord?+1
6691: a5 8c lda ]updated_coord?
6693: c5 86 cmp ]new_zpos
6695: a5 8d lda ]updated_coord?+1
6697: e5 87 sbc ]new_zpos+1
6699: ea nop
669a: 30 0c bmi :LeftBoundsOk
669c: 4c 65 66 jmp :LeftBoundsBad
669f: a5 8c :CheckLeftZero lda ]updated_coord? ;high byte is zero, check low byte
66a1: d0 14 bne :LeftSmall ;nonzero, branch
66a3: a9 00 lda #$00 ;left coord is zero, so screen coord is zero
66a5: 4c e5 66 jmp :GotLeft
66a8: a5 87 :LeftBoundsOk lda ]new_zpos+1
66aa: f0 f3 beq :CheckLeftZero
66ac: a4 bd ldy zcoord_clz
66ae: a5 8c lda ]updated_coord?
66b0: 39 d5 00 and bit_mask_left9,y
66b3: 05 8d ora ]updated_coord?+1
66b5: f0 c3 beq :ZeroLeft2
66b7: a8 :LeftSmall tay
66b8: b1 12 lda (math_tab_ptr12),y
66ba: a8 tay
66bb: 18 clc
66bc: b9 00 b5 lda turn_map_lo?,y
66bf: 69 1c adc #$1c
66c1: 85 8e sta move_tmp
66c3: b9 00 b6 lda turn_map_hi?,y
66c6: 69 07 adc #$07
66c8: 85 8f sta move_tmp+1
66ca: 38 sec
66cb: a5 8e lda move_tmp
66cd: a4 bc ldy zcoord_factor
66cf: f9 00 b5 sbc turn_map_lo?,y
66d2: 85 8e sta move_tmp
66d4: a5 8f lda move_tmp+1
66d6: f9 00 b6 sbc turn_map_hi?,y
66d9: ea nop
66da: 30 9e bmi :ZeroLeft2
66dc: 38 sec ;+1
66dd: 69 0f adc #>math_tab1_base?-$100
66df: 85 15 sta math_tab_ptr14+1
66e1: a4 8e ldy move_tmp
66e3: b1 14 lda (math_tab_ptr14),y
66e5: ea :GotLeft nop
66e6: 85 82 sta ]scrn_xc_lft_abs
; Calculate top coordinate.
66e8: 18 clc
66e9: bd 40 a2 lda elem_top_lo,x
66ec: 65 96 adc ]pitch_move
66ee: a8 tay
66ef: bd 80 a2 lda elem_top_hi,x
66f2: 65 97 adc ]pitch_move+1
66f4: 85 8f sta move_tmp+1
66f6: 70 32 bvs :OffScreenTop
66f8: 18 clc
66f9: 98 tya
66fa: a4 62 ldy cur_obj_index
66fc: 79 b0 9e adc obj_move_yc_lo,y
66ff: 9d 40 a2 sta elem_top_lo,x
6702: 85 8c sta ]updated_coord?
6704: a5 8f lda move_tmp+1
6706: 79 d8 9e adc obj_move_yc_hi,y
6709: 70 1f bvs :OffScreenTop
670b: 9d 80 a2 sta elem_top_hi,x
670e: 30 2c bmi :NegTop
6710: a4 7c ldy no_draw_elem_flag?
6712: d0 1b bne :ZeroTop1
6714: 85 8d sta ]updated_coord?+1
6716: ea nop
6717: a5 8c lda ]updated_coord?
6719: c5 86 cmp ]new_zpos
671b: a5 8d lda ]updated_coord?+1
671d: e5 87 sbc ]new_zpos+1
671f: ea nop
6720: 30 12 bmi :Jmp_TopBoundsOk
6722: e6 78 :TopBoundsBad inc clamped_tb_count
6724: a9 5e lda #94
6726: a4 7a ldy elem_bad_z_flag?
6728: f0 07 beq :ConstTop
672a: e6 72 :OffScreenTop inc no_draw_obj_flag
672c: e6 7c inc no_draw_elem_flag?
672e: ea nop
672f: a9 00 :ZeroTop1 lda #$00
6731: 4c a2 67 :ConstTop jmp :GotTop
:Jmp_TopBoundsOk
6734: 4c 65 67 jmp :TopBoundsOk
6737: a9 00 :ZeropTop2 lda #$00
6739: 4c a2 67 jmp :GotTop
673c: a5 7c :NegTop lda no_draw_elem_flag?
673e: d0 ef bne :ZeroTop1
6740: 38 sec
6741: a9 00 lda #$00
6743: e5 8c sbc ]updated_coord?
6745: 85 8c sta ]updated_coord?
6747: a9 00 lda #$00
6749: fd 80 a2 sbc elem_top_hi,x
674c: 85 8d sta ]updated_coord?+1
674e: a5 8c lda ]updated_coord?
6750: c5 86 cmp ]new_zpos
6752: a5 8d lda ]updated_coord?+1
6754: e5 87 sbc ]new_zpos+1
6756: ea nop
6757: 30 0c bmi :TopBoundsOk
6759: 4c 22 67 jmp :TopBoundsBad
675c: a5 8c :CheckTopZero lda ]updated_coord?
675e: d0 14 bne :TopSmall
6760: a9 00 lda #$00
6762: 4c a2 67 jmp :GotTop
6765: a5 87 :TopBoundsOk lda ]new_zpos+1
6767: f0 f3 beq :CheckTopZero
6769: a4 bd ldy zcoord_clz
676b: a5 8c lda ]updated_coord?
676d: 39 d5 00 and bit_mask_left9,y
6770: 05 8d ora ]updated_coord?+1
6772: f0 c3 beq :ZeropTop2
6774: a8 :TopSmall tay
6775: b1 12 lda (math_tab_ptr12),y
6777: a8 tay
6778: 18 clc
6779: b9 00 b5 lda turn_map_lo?,y
677c: 69 8e adc #142 ;center?
677e: 85 8e sta move_tmp
6780: b9 00 b6 lda turn_map_hi?,y
6783: 69 06 adc #$06
6785: 85 8f sta move_tmp+1
6787: 38 sec
6788: a5 8e lda move_tmp
678a: a4 bc ldy zcoord_factor
678c: f9 00 b5 sbc turn_map_lo?,y
678f: 85 8e sta move_tmp
6791: a5 8f lda move_tmp+1
6793: f9 00 b6 sbc turn_map_hi?,y
6796: ea nop
6797: 30 9e bmi :ZeropTop2
6799: 38 sec ;+1
679a: 69 0f adc #>math_tab1_base?-$100
679c: 85 15 sta math_tab_ptr14+1
679e: a4 8e ldy move_tmp
67a0: b1 14 lda (math_tab_ptr14),y
67a2: ea :GotTop nop
67a3: 20 7f 7f jsr Return7f7f
67a6: bc 80 a2 ldy elem_top_hi,x
67a9: 30 08 bmi :NegTop2
67ab: 18 clc
67ac: 69 60 adc #96 ;center?
67ae: 85 7e sta ]scrn_yc_top
67b0: 4c ba 67 jmp :Cont
67b3: 49 ff :NegTop2 eor #$ff ;invert
67b5: 18 clc
67b6: 69 61 adc #97 ;center? (+1 because of negation)
67b8: 85 7e sta ]scrn_yc_top
67ba: a5 c9 :Cont lda sound_counters+1 ;do sound stuff
67bc: f0 03 beq :NoSound
67be: ad 30 c0 lda SPKR ;click for sfx (player cannon, ship explosion)
67c1: bd c0 9f :NoSound lda elem_types,x ;get declared element type
67c4: d0 0b bne :NotPoint
; This is a point, so we only need left/top. Confirm we're visible and bail.
67c6: a5 76 lda clamped_lr_count
67c8: 05 78 ora clamped_tb_count
67ca: f0 02 beq :NoIncFlag
67cc: e6 7c inc no_draw_elem_flag?
67ce: 4c 90 6b :NoIncFlag jmp :RestoreRts1
67d1: 30 03 :NotPoint bmi :RectOrVl
67d3: 4c ca 68 jmp :DoHorizLine ;horizontal line
; This is a rectangle or vertical line. Calculate bottom coordinate.
67d6: 85 91 :RectOrVl sta orig_elem_type ;save element type in ZP
67d8: 18 clc
67d9: bd 40 a3 lda elem_bottom_lo,x
67dc: 65 96 adc ]pitch_move
67de: a8 tay
67df: bd 80 a3 lda elem_bottom_hi,x
67e2: 65 97 adc ]pitch_move+1
67e4: 85 8f sta move_tmp+1
67e6: 70 32 bvs :OffScreenBot
67e8: 18 clc
67e9: 98 tya
67ea: a4 62 ldy cur_obj_index
67ec: 79 b0 9e adc obj_move_yc_lo,y
67ef: 9d 40 a3 sta elem_bottom_lo,x
67f2: 85 8c sta ]updated_coord?
67f4: a5 8f lda move_tmp+1
67f6: 79 d8 9e adc obj_move_yc_hi,y
67f9: 70 1f bvs :OffScreenBot
67fb: 9d 80 a3 sta elem_bottom_hi,x
67fe: 30 2c bmi :NegBot
6800: a4 7c ldy no_draw_elem_flag?
6802: d0 1b bne :ZeroBot1
6804: 85 8d sta ]updated_coord?+1
6806: ea nop
6807: a5 8c lda ]updated_coord?
6809: c5 86 cmp ]new_zpos
680b: a5 8d lda ]updated_coord?+1
680d: e5 87 sbc ]new_zpos+1
680f: ea nop
6810: 30 12 bmi :Jump_BotBoundsOk
6812: e6 78 :BotBoundsBad inc clamped_tb_count
6814: a9 5e lda #94 ;(used later)
6816: a4 7a ldy elem_bad_z_flag?
6818: f0 07 beq :ConstBot
681a: e6 72 :OffScreenBot inc no_draw_obj_flag
681c: e6 7c inc no_draw_elem_flag?
681e: ea nop
681f: a9 00 :ZeroBot1 lda #$00
6821: 4c 92 68 :ConstBot jmp :GotBottom
:Jump_BotBoundsOk
6824: 4c 55 68 jmp :BotBoundsOk
6827: a9 00 :ZeroBot2 lda #$00
6829: 4c 92 68 jmp :GotBottom
682c: a5 7c :NegBot lda no_draw_elem_flag?
682e: d0 ef bne :ZeroBot1
6830: 38 sec
6831: a9 00 lda #$00
6833: e5 8c sbc ]updated_coord?
6835: 85 8c sta ]updated_coord?
6837: a9 00 lda #$00
6839: fd 80 a3 sbc elem_bottom_hi,x
683c: 85 8d sta ]updated_coord?+1
683e: a5 8c lda ]updated_coord?
6840: c5 86 cmp ]new_zpos
6842: a5 8d lda ]updated_coord?+1
6844: e5 87 sbc ]new_zpos+1
6846: ea nop
6847: 30 0c bmi :BotBoundsOk
6849: 4c 12 68 jmp :BotBoundsBad
684c: a5 8c :CheckBotZero lda ]updated_coord?
684e: d0 14 bne :BotSmall
6850: a9 00 lda #$00
6852: 4c 92 68 jmp :GotBottom
6855: a5 87 :BotBoundsOk lda ]new_zpos+1
6857: f0 f3 beq :CheckBotZero
6859: a4 bd ldy zcoord_clz
685b: a5 8c lda ]updated_coord?
685d: 39 d5 00 and bit_mask_left9,y
6860: 05 8d ora ]updated_coord?+1
6862: f0 c3 beq :ZeroBot2
6864: a8 :BotSmall tay
6865: b1 12 lda (math_tab_ptr12),y
6867: a8 tay
6868: 18 clc
6869: b9 00 b5 lda turn_map_lo?,y
686c: 69 8e adc #142
686e: 85 8e sta move_tmp
6870: b9 00 b6 lda turn_map_hi?,y
6873: 69 06 adc #$06
6875: 85 8f sta move_tmp+1
6877: 38 sec
6878: a5 8e lda move_tmp
687a: a4 bc ldy zcoord_factor
687c: f9 00 b5 sbc turn_map_lo?,y
687f: 85 8e sta move_tmp
6881: a5 8f lda move_tmp+1
6883: f9 00 b6 sbc turn_map_hi?,y
6886: ea nop
6887: 30 9e bmi :ZeroBot2
6889: 38 sec ;+1
688a: 69 0f adc #>math_tab1_base?-$100
688c: 85 15 sta math_tab_ptr14+1
688e: a4 8e ldy move_tmp
6890: b1 14 lda (math_tab_ptr14),y
6892: ea :GotBottom nop
6893: 20 7f 7f jsr Return7f7f
6896: bc 80 a3 ldy elem_bottom_hi,x
6899: 30 08 bmi :BotNeg
689b: 18 clc
689c: 69 60 adc #96
689e: 85 80 sta ]scrn_yc_btm ;bottom Y coord for vertical line?
68a0: 4c aa 68 jmp :BotCont
68a3: 49 ff :BotNeg eor #$ff
68a5: 18 clc
68a6: 69 61 adc #97
68a8: 85 80 sta ]scrn_yc_btm
68aa: c5 7e :BotCont cmp ]scrn_yc_top ;compare top to bottom
68ac: f0 08 beq :IsHline
68ae: a9 80 lda #$80
68b0: 85 70 sta mod_elem_type ;set type to vline
68b2: ea nop
68b3: 4c bc 68 jmp :BotTbOk
68b6: a5 78 :IsHline lda clamped_tb_count
68b8: f0 02 beq :BotTbOk
68ba: e6 7c inc no_draw_elem_flag?
68bc: 06 91 :BotTbOk asl orig_elem_type ;shift left to test ($80 for rect, $ff for vline)
68be: ea nop
68bf: 10 0f bpl :CalcRight
68c1: a5 76 lda clamped_lr_count ;vertical line
68c3: f0 02 beq :NoIncFlag
68c5: e6 7c inc no_draw_elem_flag?
68c7: 4c 90 6b :NoIncFlag jmp :RestoreRts1
68ca: a5 78 :DoHorizLine lda clamped_tb_count
68cc: f0 02 beq :CalcRight
68ce: e6 7c inc no_draw_elem_flag?
; Horizontal line or rect. Calculate right coordinate.
68d0: 18 :CalcRight clc
68d1: bd c0 a2 lda elem_right_lo,x
68d4: 65 94 adc ]yaw_move
68d6: a8 tay
68d7: bd 00 a3 lda elem_right_hi,x
68da: 65 95 adc ]yaw_move+1
68dc: 85 8f sta move_tmp+1
68de: 70 32 bvs :OffScreenRgt
68e0: 18 clc
68e1: 98 tya
68e2: a4 62 ldy cur_obj_index
68e4: 79 60 9e adc obj_move_xc_lo,y
68e7: 9d c0 a2 sta elem_right_lo,x
68ea: 85 8c sta ]updated_coord?
68ec: a5 8f lda move_tmp+1
68ee: 79 88 9e adc obj_move_xc_hi,y
68f1: 70 1f bvs :OffScreenRgt
68f3: 9d 00 a3 sta elem_right_hi,x
68f6: 30 2c bmi :NegRgt
68f8: a4 7c ldy no_draw_elem_flag?
68fa: d0 1b bne :ZeroRgt1
68fc: 85 8d sta ]updated_coord?+1
68fe: ea nop
68ff: a5 8c lda ]updated_coord?
6901: c5 86 cmp ]new_zpos
6903: a5 8d lda ]updated_coord?+1
6905: e5 87 sbc ]new_zpos+1
6907: ea nop
6908: 30 12 bmi :Jmp_RgtBoundsOk
690a: e6 76 :RgtBoundsBad inc clamped_lr_count
690c: a9 8a lda #138
690e: a4 7a ldy elem_bad_z_flag?
6910: f0 07 beq :ConstRgt
6912: e6 72 :OffScreenRgt inc no_draw_obj_flag
6914: e6 7c inc no_draw_elem_flag?
6916: ea nop
6917: a9 00 :ZeroRgt1 lda #$00
6919: 4c 8a 69 :ConstRgt jmp :GotRgt
:Jmp_RgtBoundsOk
691c: 4c 4d 69 jmp :RgtBoundsOk
691f: a9 00 :ZeroRgt2 lda #$00
6921: 4c 8a 69 jmp :GotRgt
6924: a5 7c :NegRgt lda no_draw_elem_flag?
6926: d0 ef bne :ZeroRgt1
6928: 38 sec
6929: a9 00 lda #$00
692b: e5 8c sbc ]updated_coord?
692d: 85 8c sta ]updated_coord?
692f: a9 00 lda #$00
6931: fd 00 a3 sbc elem_right_hi,x
6934: 85 8d sta ]updated_coord?+1
6936: a5 8c lda ]updated_coord?
6938: c5 86 cmp ]new_zpos
693a: a5 8d lda ]updated_coord?+1
693c: e5 87 sbc ]new_zpos+1
693e: ea nop
693f: 30 0c bmi :RgtBoundsOk
6941: 4c 0a 69 jmp :RgtBoundsBad
6944: a5 8c :CheckRgtZero lda ]updated_coord?
6946: d0 14 bne :RgtSmall
6948: a9 00 lda #$00
694a: 4c 8a 69 jmp :GotRgt
694d: a5 87 :RgtBoundsOk lda ]new_zpos+1
694f: f0 f3 beq :CheckRgtZero
6951: a4 bd ldy zcoord_clz
6953: a5 8c lda ]updated_coord?
6955: 39 d5 00 and bit_mask_left9,y
6958: 05 8d ora ]updated_coord?+1
695a: f0 c3 beq :ZeroRgt2
695c: a8 :RgtSmall tay
695d: b1 12 lda (math_tab_ptr12),y
695f: a8 tay
6960: 18 clc
6961: b9 00 b5 lda turn_map_lo?,y
6964: 69 1c adc #$1c
6966: 85 8e sta move_tmp
6968: b9 00 b6 lda turn_map_hi?,y
696b: 69 07 adc #$07
696d: 85 8f sta move_tmp+1
696f: 38 sec
6970: a5 8e lda move_tmp
6972: a4 bc ldy zcoord_factor
6974: f9 00 b5 sbc turn_map_lo?,y
6977: 85 8e sta move_tmp
6979: a5 8f lda move_tmp+1
697b: f9 00 b6 sbc turn_map_hi?,y
697e: ea nop
697f: 30 9e bmi :ZeroRgt2
6981: 38 sec ;+1
6982: 69 0f adc #>math_tab1_base?-$100
6984: 85 15 sta math_tab_ptr14+1
6986: a4 8e ldy move_tmp
6988: b1 14 lda (math_tab_ptr14),y
698a: ea :GotRgt nop
698b: 20 7f 7f jsr Return7f7f
698e: 85 84 sta ]scrn_xc_rgt_abs ;set right coordinate
6990: c5 82 cmp ]scrn_xc_lft_abs ;same as left?
6992: d0 11 bne :LftNeRgt ;no, branch
6994: bd 00 a3 lda elem_right_hi,x ;absolute value is equal; compare signs
6997: 5d 00 a2 eor elem_left_hi,x
699a: 30 09 bmi :LftNeRgt ;signs not equal, branch
699c: a5 76 lda clamped_lr_count
699e: f0 02 beq :NoIncFlag
69a0: e6 7c inc no_draw_elem_flag?
69a2: 4c 90 6b :NoIncFlag jmp :RestoreRts1
69a5: e6 70 :LftNeRgt inc mod_elem_type ;vline->rect
69a7: 4c 90 6b jmp :RestoreRts1
;
; Transform object that is behind us (Z is negative).
;
; This marks the element as "do not draw", then calculates the position of the
; element as if the Z coordinate were at (0-Z). Since there's no need to update
; the position for an element we're not drawing, my guess is that the
; calculations are performed for the benefit of collision detection vs. the
; player (but if that's the case, why worry about right/bottom coords?).
;
]scale1_val? .var $8a {addr/1}
]scale2_base? .var $8b {addr/1}
69aa: 18 :ObjectBehind clc ;do sound stuff
69ab: a5 b2 lda engine_sound_ctr?+1
69ad: 69 18 adc #$18
69af: 85 b2 sta engine_sound_ctr?+1
69b1: 90 0f bcc :NoSound
69b3: e6 b3 inc engine_sound_ctr?+2
69b5: a5 cc lda engine_sound_enable
69b7: f0 09 beq :NoSound
69b9: a5 b3 lda engine_sound_ctr?+2
69bb: 25 b1 and engine_sound_ctr?
69bd: d0 03 bne :NoSound
69bf: ad 30 c0 lda SPKR
69c2: a9 0e :NoSound lda #$0e
69c4: 85 72 sta no_draw_obj_flag ;set flag to suppress rendering of object
69c6: e6 7a inc elem_bad_z_flag?
69c8: e6 7c inc no_draw_elem_flag?
69ca: 38 sec
69cb: a9 00 lda #$00
69cd: e5 86 sbc ]new_zpos
69cf: 85 86 sta ]new_zpos
69d1: a9 00 lda #$00
69d3: e5 87 sbc ]new_zpos+1
69d5: 85 87 sta ]new_zpos+1
69d7: a9 fc lda #$fc
69d9: 85 c6 sta prev_zpos+1 ;set to -$0400 (invalid)
69db: a5 87 lda ]new_zpos+1
69dd: d0 18 bne L69F7
69df: a4 86 ldy ]new_zpos
69e1: b9 00 b9 lda clz_table,y
69e4: 18 clc
69e5: 69 08 adc #$08
69e7: 85 8b sta ]scale2_base?
69e9: 69 a4 adc #>math_tab2_base?-$800
69eb: 85 13 sta math_tab_ptr12+1
69ed: a4 86 ldy ]new_zpos
69ef: b1 12 lda (math_tab_ptr12),y
69f1: 85 8a sta ]scale1_val?
69f3: ea nop
69f4: 4c 11 6a jmp L6A11
69f7: 85 87 L69F7 sta ]new_zpos+1
69f9: a8 tay
69fa: b9 00 b9 lda clz_table,y
69fd: a8 tay
69fe: 85 8b sta ]scale2_base?
6a00: 18 clc
6a01: 69 ac adc #>math_tab2_base?
6a03: 85 13 sta math_tab_ptr12+1
6a05: a5 86 lda ]new_zpos
6a07: 39 d5 00 and bit_mask_left9,y
6a0a: 05 87 ora ]new_zpos+1
6a0c: a8 tay
6a0d: b1 12 lda (math_tab_ptr12),y
6a0f: 85 8a sta ]scale1_val?
6a11: ea L6A11 nop
6a12: 18 clc
6a13: a4 8a ldy ]scale1_val?
6a15: b9 00 b5 lda turn_map_lo?,y
6a18: 65 9a adc joy_yaw_angle
6a1a: 85 8c sta ]updated_coord?
6a1c: a5 9b lda joy_yaw_angle+1
6a1e: e5 8b sbc ]scale2_base?
6a20: 30 25 bmi L6A47
6a22: 85 8d sta ]updated_coord?+1
6a24: 38 sec
6a25: ea nop
6a26: 69 ac adc #>math_tab2_base?
6a28: 85 15 sta math_tab_ptr14+1
6a2a: a4 8c ldy ]updated_coord?
6a2c: b9 00 17 lda math_tab1_lastpg?,y
6a2f: a8 tay
6a30: b1 14 lda (math_tab_ptr14),y
6a32: 85 95 sta ]yaw_move+1
6a34: a4 8d ldy ]updated_coord?+1
6a36: 39 ef 00 and bit_mask_left8,y
6a39: 45 9c eor joy_yaw_sign
6a3b: 85 94 sta ]yaw_move
6a3d: a5 95 lda ]yaw_move+1
6a3f: 39 e7 00 and bit_mask_right8,y
6a42: 45 9c eor joy_yaw_sign
6a44: 4c 63 6a jmp L6A63
6a47: ea L6A47 nop
6a48: 18 clc
6a49: 69 08 adc #$08
6a4b: 30 12 bmi L6A5F
6a4d: 18 clc
6a4e: 69 10 adc #>math_tab1_base?
6a50: 85 15 sta math_tab_ptr14+1
6a52: a4 8c ldy ]updated_coord?
6a54: a5 9c lda joy_yaw_sign
6a56: 85 95 sta ]yaw_move+1
6a58: 51 14 eor (math_tab_ptr14),y
6a5a: 85 94 sta ]yaw_move
6a5c: 4c 65 6a jmp L6A65
6a5f: a9 00 L6A5F lda #$00
6a61: 85 94 sta ]yaw_move
6a63: 85 95 L6A63 sta ]yaw_move+1
6a65: ea L6A65 nop
6a66: 18 clc
6a67: a4 8a ldy ]scale1_val?
6a69: b9 00 b5 lda turn_map_lo?,y
6a6c: 65 9d adc joy_pitch_angle
6a6e: 85 8c sta ]updated_coord?
6a70: a5 9e lda joy_pitch_angle+1
6a72: e5 8b sbc ]scale2_base?
6a74: 30 25 bmi L6A9B
6a76: 85 8d sta ]updated_coord?+1
6a78: 38 sec
6a79: ea nop
6a7a: 69 ac adc #>math_tab2_base?
6a7c: 85 15 sta math_tab_ptr14+1
6a7e: a4 8c ldy ]updated_coord?
6a80: b9 00 17 lda math_tab1_lastpg?,y
6a83: a8 tay
6a84: b1 14 lda (math_tab_ptr14),y
6a86: 85 97 sta ]pitch_move+1
6a88: a4 8d ldy ]updated_coord?+1
6a8a: 39 ef 00 and bit_mask_left8,y
6a8d: 45 9f eor joy_pitch_sign
6a8f: 85 96 sta ]pitch_move
6a91: a5 97 lda ]pitch_move+1
6a93: 39 e7 00 and bit_mask_right8,y
6a96: 45 9f eor joy_pitch_sign
6a98: 4c b7 6a jmp L6AB7
6a9b: ea L6A9B nop
6a9c: 18 clc
6a9d: 69 08 adc #$08
6a9f: 30 12 bmi L6AB3
6aa1: 18 clc
6aa2: 69 10 adc #>math_tab1_base?
6aa4: 85 15 sta math_tab_ptr14+1
6aa6: a4 8c ldy ]updated_coord?
6aa8: a5 9f lda joy_pitch_sign
6aaa: 85 97 sta ]pitch_move+1
6aac: 51 14 eor (math_tab_ptr14),y
6aae: 85 96 sta ]pitch_move
6ab0: 4c b9 6a jmp L6AB9
6ab3: a9 00 L6AB3 lda #$00
6ab5: 85 96 sta ]pitch_move
6ab7: 85 97 L6AB7 sta ]pitch_move+1
6ab9: ea L6AB9 nop
6aba: 18 clc ;do sound stuff
6abb: a5 b2 lda engine_sound_ctr?+1
6abd: 69 0d adc #$0d
6abf: 85 b2 sta engine_sound_ctr?+1
6ac1: 90 0f bcc :NoSound
6ac3: e6 b3 inc engine_sound_ctr?+2
6ac5: a5 cc lda engine_sound_enable
6ac7: f0 09 beq :NoSound
6ac9: a5 b3 lda engine_sound_ctr?+2
6acb: 25 b1 and engine_sound_ctr?
6acd: d0 03 bne :NoSound
6acf: ad 30 c0 lda SPKR
6ad2: 38 :NoSound sec
6ad3: bd c0 a1 lda elem_left_lo,x
6ad6: e5 94 sbc ]yaw_move
6ad8: a8 tay
6ad9: bd 00 a2 lda elem_left_hi,x
6adc: e5 95 sbc ]yaw_move+1
6ade: 85 8f sta move_tmp+1
6ae0: 70 17 bvs L6AF9
6ae2: 18 clc
6ae3: 98 tya
6ae4: a4 62 ldy cur_obj_index
6ae6: 79 60 9e adc obj_move_xc_lo,y
6ae9: 9d c0 a1 sta elem_left_lo,x
6aec: a5 8f lda move_tmp+1
6aee: 79 88 9e adc obj_move_xc_hi,y
6af1: 70 06 bvs L6AF9
6af3: 9d 00 a2 sta elem_left_hi,x
6af6: 4c fd 6a jmp L6AFD
6af9: e6 72 L6AF9 inc no_draw_obj_flag
6afb: e6 7c inc no_draw_elem_flag?
6afd: ea L6AFD nop
6afe: 38 sec
6aff: bd 40 a2 lda elem_top_lo,x
6b02: e5 96 sbc ]pitch_move
6b04: a8 tay
6b05: bd 80 a2 lda elem_top_hi,x
6b08: e5 97 sbc ]pitch_move+1
6b0a: 85 8f sta move_tmp+1
6b0c: 70 17 bvs L6B25
6b0e: 18 clc
6b0f: 98 tya
6b10: a4 62 ldy cur_obj_index
6b12: 79 b0 9e adc obj_move_yc_lo,y
6b15: 9d 40 a2 sta elem_top_lo,x
6b18: a5 8f lda move_tmp+1
6b1a: 79 d8 9e adc obj_move_yc_hi,y
6b1d: 70 06 bvs L6B25
6b1f: 9d 80 a2 sta elem_top_hi,x
6b22: 4c 29 6b jmp L6B29
6b25: e6 72 L6B25 inc no_draw_obj_flag
6b27: e6 7c inc no_draw_elem_flag?
6b29: ea L6B29 nop
6b2a: bd c0 9f lda elem_types,x ;get original element type
6b2d: 85 91 sta orig_elem_type ;copy to ZP
6b2f: 10 33 bpl :PtOrHlin
6b31: 38 sec ;rect or vline
6b32: bd 40 a3 lda elem_bottom_lo,x
6b35: e5 96 sbc ]pitch_move
6b37: a8 tay
6b38: bd 80 a3 lda elem_bottom_hi,x
6b3b: e5 97 sbc ]pitch_move+1
6b3d: 85 8f sta move_tmp+1
6b3f: 70 17 bvs L6B58
6b41: 18 clc
6b42: 98 tya
6b43: a4 62 ldy cur_obj_index
6b45: 79 b0 9e adc obj_move_yc_lo,y
6b48: 9d 40 a3 sta elem_bottom_lo,x
6b4b: a5 8f lda move_tmp+1
6b4d: 79 d8 9e adc obj_move_yc_hi,y
6b50: 70 06 bvs L6B58
6b52: 9d 80 a3 sta elem_bottom_hi,x
6b55: 4c 5c 6b jmp L6B5C
6b58: e6 72 L6B58 inc no_draw_obj_flag
6b5a: e6 7c inc no_draw_elem_flag?
6b5c: ea L6B5C nop
6b5d: 06 91 asl orig_elem_type ;test low bits
6b5f: 10 03 bpl :PtOrHlin ;was rect, branch
6b61: 4c 90 6b jmp :RestoreRts1
6b64: 38 :PtOrHlin sec ;point, hline, or rect
6b65: bd c0 a2 lda elem_right_lo,x
6b68: e5 94 sbc ]yaw_move
6b6a: a8 tay
6b6b: bd 00 a3 lda elem_right_hi,x
6b6e: e5 95 sbc ]yaw_move+1
6b70: 85 8f sta move_tmp+1
6b72: 70 17 bvs L6B8B
6b74: 18 clc
6b75: 98 tya
6b76: a4 62 ldy cur_obj_index
6b78: 79 60 9e adc obj_move_xc_lo,y
6b7b: 9d c0 a2 sta elem_right_lo,x
6b7e: a5 8f lda move_tmp+1
6b80: 79 88 9e adc obj_move_xc_hi,y
6b83: 70 06 bvs L6B8B
6b85: 9d 00 a3 sta elem_right_hi,x
6b88: 4c 8f 6b jmp :RestoreRts2
6b8b: e6 72 L6B8B inc no_draw_obj_flag
6b8d: e6 7c inc no_draw_elem_flag?
6b8f: ea :RestoreRts2 nop
6b90: 20 7f 7f :RestoreRts1 jsr Return7f7f
6b93: a9 20 :RestoreRts lda #INSTR_JSR_ABS ;restore draw/erase of vertical lines and rects
6b95: 20 4c 7b jsr ModDrwEraVrtRct
6b98: 60 rts
6b99: 3d 3d 3d 3d+ .junk 293
logo_region_toggle
6cbe: ff .dd1 $ff ;bool 00/ff: select logo region for title screen?
demo_logo_progress
6cbf: 0a .dd1 $0a ;initial value for forward progress when showing logo
6cc0: 86 00 demo_logo_speed .dd2 $0086 ;foward speed when showing logo in demo (1340)
6cc2: 00 00 00 00 .junk 4
;
; Counter used with random number generation (0-54). Incremented every time the
; function is called.
6cc6: 12 rng_counter .junk 1
;
; Register spill.
6cc7: 1f saved_xreg_7bb0 .junk 1
;
; This big pile of bytes appears to hold the state for random number generation
; (function at $7bb0). Some of the bytes are tweaked directly by certain
; functions, possibly to add entropy.
6cc8: 26 e0 eb f4+ rng_state1 .bulk $26,$e0,$eb,$f4,$50,$6e,$8f,$a7,$73,$3c,$48,$57,$d4,$c7,$8d,$df ;55 elements
+ $33,$ea,$25,$27,$eb,$6e,$ac,$a3,$7a,$ec,$79,$61,$b5,$30,$e5,$78
+ $01,$59,$b9,$6b,$6b,$76,$d7,$9b,$e5,$a8,$2d,$14,$a9,$f7,$12,$7c
+ $d8,$ba,$04,$b3,$b2,$11,$1e
6cff: 13 2b 7b 7c+ rng_state2 .bulk $13,$2b,$7b,$7c,$3d,$72,$38,$7e,$5d,$44,$cf,$d1,$df,$13,$0f,$bc ;55 elements
+ $f5,$dc,$27,$2e,$f2,$53,$2f,$44,$7d,$5a,$35,$4d,$84,$93,$41,$65
+ $c5,$b1,$79,$ca,$43,$04,$53,$b4,$d6,$b7,$7e,$f8,$99,$81,$57,$5e
+ $af,$4b,$3c,$80,$cd,$9a,$88
6d36: 00 00 00 00+ .junk 5
game_active_flag
6d3b: 00 .dd1 $00 ;bool 00/ff: is game being played?
6d3c: 00 wronly_6d3c .dd1 $00 ;written, never read
6d3d: 01 rng_update_flag .dd1 $01 ;if zero, invoke the RNG several times
6d3e: 00 .junk 1
end_game_msg_ctr
6d3f: 00 00 .dd2 $0000 ;holds "out of ____" on screen during demo for a bit
title_text_draw_index
6d41: 00 .dd1 $00 ;index into title text string
6d42: 03 rsrc_draw_index .dd1 $03 ;index into $70dc/$70e1 (0-4)
6d43: 00 game_over_music .dd1 $00 ;1=not high score, 5=high score, 0=music done
6d44: 00 horiz_axis_mod .dd1 $00 ;horizontal joystick axis modifier (00/ff)
6d45: 00 00 .junk 2
6d47: 00 vert_axis_mod .dd1 $00 ;vertical joystick axis modifier (00/ff)
sound_disab_flag
6d48: 00 .dd1 $00 ;bool 00/01: is sound disabled?
;
; $6d49-6dbc zeroed out during game init ($8152).
;
6d49: 00 tmp_xmove_lo .dd1 $00
6d4a: 00 tmp_xmove_hi .dd1 $00
6d4b: 00 tmp_ymove_lo .dd1 $00
6d4c: 00 tmp_ymove_hi .dd1 $00
6d4d: 00 tmp_zmove_lo .dd1 $00
6d4e: 00 tmp_zmove_hi .dd1 $00
6d4f: 00 00 .junk 2
6d51: 00 00 max_z_spd_copy .dd2 $0000
6d53: 00 00 00 portal_xmod0 .dd3 $000000 ;portal boundary position modifier
6d56: 00 00 00 portal_ymod0 .dd3 $000000 ;portal boundary position modifier
6d59: 00 00 00 portal_xmod1 .dd3 $000000 ;portal boundary position modifier
6d5c: 00 00 00 portal_ymod1 .dd3 $000000 ;portal boundary position modifier
6d5f: 00 fuel_this_frame .dd1 $00 ;# of units of fuel we burned this frame
6d60: 00 .junk 1
;
; Region progress counter, updated every frame. When this reaches zero, we
; update the region number.
region_progress_ctr
6d61: e5 09 .dd2 $09e5
;
; Region of space (0-7). Determines what sorts of things are created here,
; based on the contents of the table at $708c.
6d63: 06 space_region .dd1 $06
;
; Counter used when deciding whether to create multiple objects in one frame.
; Initially set to 0-28, then reduced by class-specific values at $707f.
6d64: fe create_mult_ctr .dd1 $fe
;
; Counter used to pick the class of a shape to create. This is incremented,
; ANDed with #$07, and checked against the list of shapes valid in this region.
6d65: 27 shape_cl_ctr .dd1 $27
6d66: 00 .junk 1
;
; Points to region limit table for the current region. This is set to the value
; from the region table base ptr ($70cc) plus (region * 8).
6d67: bc 70 region_tab_ptr .dd2 region_class_max+48
;
; Active object count, by class. The Nth entry is incremented when an object of
; class N is created, and decremented when it's destroyed. This is used to
; enforce the per-region limits.
;
; (Like everything else nearby, this is zeroed out by the loop at $8152.)
active_class_ctrs
6d69: 01 00 00 00+ .bulk $01,$00,$00,$00,$00,$00,$00,$04,$00,$00,$00,$00,$00,$00,$00,$00
;
; Copy of shape header, used by object creator. $6d79-6d8a are copied from
; header +$08 to +$11.
6d79: 00 element_count .dd1 $00 ;hdr +$00 element count
6d7a: 00 00 00 .bulk $00,$00,$00 ;hdr +$01-03 (unused)
6d7d: 00 shape_act_type .dd1 $00 ;hdr +$04: activity type
6d7e: 00 00 00 .bulk $00,$00,$00 ;hdr +$05-07 (unused)
6d81: 40 00 shape_zmin .dd2 $0040 ;hdr +$08-09: minimum initial value for Z
6d83: 00 10 shape_zmax .dd2 $1000 ;hdr +$0a-0b: maximum initial value for Z
6d85: 00 00 00 .bulk $00,$00,$00 ;hdr +$0c-0e (unused)
6d88: 01 00 shape_hitbox .dd2 $0001 ;hdr +$0f-10: size of hitbox
6d8a: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$00,$00 ;hdr +$11-17 (unused)
;
6d91: 00 shot_delay_ctr .dd1 $00 ;paces shots when buttons held down
6d92: 00 btns_down_flag .dd1 $00 ;bool 00/80: both buttons down (or spacebar hit)?
btns_0_down_flag
6d93: 00 .dd1 $00 ;bool 00/80: button 0 down?
btns_1_down_flag
6d94: 00 .dd1 $00 ;bool 00/80: button 1 down?
time_in_portal_ctr
6d95: 00 00 .dd2 $0000 ;counts time spent in portal
6d97: 00 wronly_6d97? .dd1 $00 ;incremented, never read
time_portal_fail_ctr
6d98: 00 .dd1 $00 ;increases when flying outside time portal
entered_portal_flag
6d99: 00 .dd1 $00 ;bool 00/nz: did we just enter a time portal?
6d9a: 00 .junk 1
6d9b: 00 00 00 00+ wronly_6d9b? .fill 6,$00 ;written, updated, never read
6da1: 00 00 00 .junk 3
6da4: 00 00 00 forward_speed .dd3 $000000 ;16.8: speed/10 (so "2600"=$00 04 01)
6da7: 00 speed_fraction .dd1 $00 ;fractional speed tracking
6da8: 00 00 .junk 2
6daa: 00 joystick_x_mag .dd1 $00 ;joystick X axis magnitude ($00-65 or 5b)
6dab: 00 joy_mag_sum .dd1 $00 ;sum of joystick magnitudes
joy_mag_plus_spd
6dac: 08 .dd1 $08 ;sum of joystick magnitudes and a speed thing
6dad: 00 joystick_y_mag .dd1 $00 ;joystick Y axis magnitude ($00-65 or 5b)
portal_bound_limit
6dae: 00 00 .dd2 $0000 ;RNG limit when positioning portal boundaries
6db0: 00 wronly_6db0? .dd1 $00 ;written, never read
6db1: 00 00 00 00+ .junk 12
; (end of zeroed-out area)
;
; -----
;
; Player resource state.
;
; Modified via indirect access; see $7c68 and $7ca0.
;
; $6dbd-6dcf (19 bytes) are initialized from $6dd7.
6dbd: 00 resource_state .dd1 $00
6dbe: 00 00 00 cur_score .dd3 $000000 ;24-bit BCD: current score
6dc1: 00 .dd1 $00 ;(last byte ignored)
6dc2: 99 99 time_left .dd2 $9999 ;16-bit BCD: amount of time left
6dc4: 00 .dd1 $00
6dc5: 00 90 fuel_left .dd2 $9000 ;16-bit BCD: amount of fuel left
6dc7: 00 .dd1 $00
6dc8: 00 01 amun_left .dd2 $0100 ;16-bit BCD: amount of ammo left
6dca: 00 00 cur_speed .dd2 $0000 ;16-bit BCD: current speed
6dcc: 00 .dd1 $00
6dcd: 0c frame_counter .dd1 $0c
status_line_index
6dce: 14 .dd1 $14
6dcf: 00 .dd1 $00
;
6dd0: 00 .junk 1
6dd1: 00 00 00 high_score .dd3 $000000 ;24-bit BCD: high score
6dd4: 00 00 00 .junk 3
;
; Initial ship loadout: 0 score, 9999 time, 9000 fuel, 100 ammo, 0 speed.
6dd7: 00 00 00 00+ initial_loadout .bulk $00,$00,$00,$00,$00,$99,$99,$00,$00,$90,$00,$00,$01,$00,$00,$00
+ $00,$00,$00
6dea: 00 00 00 00+ .junk 75
;
; Text shown during title sequence.
text_sirius_pres
6e35: 53 49 52 49+ .str ‘SIRIUS SOFTWARE PRESENTS ’
6e4e: 43 4f 50 59+ text_copyright .str ‘COPYRIGHT 1981’
6e5c: 42 59 20 20+ text_larry_spc .str ‘BY LARRY MILLER HIT SPACEBAR TO START’
;
; The next 3 items form the top 40-char row of the status area.
6e85: 20 20 48 49+ text_score_time .str ‘ HIGH SCORE TIME FUEL AMUN ’
text_axis_status
6ea5: 20 .dd1 ‘ ’ ;value from $7345-7348 (' ','H','V','\')
6ea6: 34 20 53 50+ text_joy_sens .str ‘4 SPEED’ ;first char set to '1' - '5'
;
; Unused.
6ead: 41 42 4f 56+ text_position .str ‘ABOVEBELOWRIGHTLEFT ’
;
; Text shown at end of game.
6ec1: 4f 55 54 20+ text_out_of .str ‘OUT OF ’
text_time_fuel_amun
6ec8: 54 49 4d 45+ .str ‘TIMEFUELAMUN*RES’ ;printed after "OUT OF"
6ed8: 52 41 54 49+ text_rating .str ‘RATING ’
;
; Secret key sequence. Type "NOTICE" while playing to pop up a copyright
; notice.
secret_key_index
6ee0: 00 .dd1 $00 ;current position in sequence
6ee1: 0e secret_key_seq .dd1 $0e ;'N' - $40
6ee2: 0f .dd1 $0f ;'O' - $40
6ee3: 14 .dd1 $14 ;'T' - $40
6ee4: 09 .dd1 $09 ;'I' - $40
6ee5: 03 .dd1 $03 ;'C' - $40
6ee6: 05 .dd1 $05 ;'E' - $40
;
; Score ratings. 5 entries, 16 bytes each. Determined by score thresholds
; defined at $70e6.
text_rating_labels
6ee7: 4e 4f 56 49+ .str ‘NOVICE PILOT CAPTAIN FLEET COMMANDE’
+ ‘R GALACTIC EMPEROR’
6f37: 11 11 11 1f+ font_glyphs .bulk $11,$11,$11,$1f,$11,$0a,$04,$00 ;'A'
6f3f: 0f 11 11 0f+ .bulk $0f,$11,$11,$0f,$11,$11,$0f,$00
6f47: 0e 11 01 01+ .bulk $0e,$11,$01,$01,$01,$11,$0e,$00
6f4f: 0f 11 11 11+ .bulk $0f,$11,$11,$11,$11,$11,$0f,$00
6f57: 1f 01 01 0f+ .bulk $1f,$01,$01,$0f,$01,$01,$1f,$00
6f5f: 01 01 01 0f+ .bulk $01,$01,$01,$0f,$01,$01,$1f,$00
6f67: 1e 11 11 19+ .bulk $1e,$11,$11,$19,$01,$11,$0e,$00
6f6f: 11 11 11 1f+ .bulk $11,$11,$11,$1f,$11,$11,$11,$00
6f77: 0e 04 04 04+ .bulk $0e,$04,$04,$04,$04,$04,$0e,$00
6f7f: 06 09 09 08+ .bulk $06,$09,$09,$08,$08,$08,$1c,$00
6f87: 11 09 05 03+ .bulk $11,$09,$05,$03,$05,$09,$11,$00
6f8f: 1f 01 01 01+ .bulk $1f,$01,$01,$01,$01,$01,$01,$00
6f97: 11 11 11 15+ .bulk $11,$11,$11,$15,$15,$1b,$11,$00
6f9f: 11 19 19 15+ .bulk $11,$19,$19,$15,$13,$13,$11,$00
6fa7: 0e 11 11 11+ .bulk $0e,$11,$11,$11,$11,$11,$0e,$00
6faf: 01 01 01 0f+ .bulk $01,$01,$01,$0f,$11,$11,$0f,$00
6fb7: 10 0e 15 11+ .bulk $10,$0e,$15,$11,$11,$11,$0e,$00
6fbf: 11 09 05 0f+ .bulk $11,$09,$05,$0f,$11,$11,$0f,$00
6fc7: 0e 11 10 0e+ .bulk $0e,$11,$10,$0e,$01,$11,$0e,$00
6fcf: 04 04 04 04+ .bulk $04,$04,$04,$04,$04,$04,$1f,$00
6fd7: 0e 11 11 11+ .bulk $0e,$11,$11,$11,$11,$11,$11,$00
6fdf: 04 0a 11 11+ .bulk $04,$0a,$11,$11,$11,$11,$11,$00
6fe7: 11 1b 15 15+ .bulk $11,$1b,$15,$15,$11,$11,$11,$00
6fef: 11 11 0a 04+ .bulk $11,$11,$0a,$04,$0a,$11,$11,$00
6ff7: 04 04 04 0e+ .bulk $04,$04,$04,$0e,$11,$11,$11,$00
6fff: 1f 01 02 04+ .bulk $1f,$01,$02,$04,$08,$10,$1f,$00 ;'Z'
7007: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$00,$00,$00 ;' '
700f: 09 0f 09 09+ .bulk $09,$0f,$09,$09,$04,$0a,$11,$00 ;'V' + 'H', shown when both joystick axes are flipped
; Digits start here.
font_glyph_digits
7017: 0e 11 11 11+ .bulk $0e,$11,$11,$11,$11,$11,$0e,$00 ;'0'
701f: 0e 04 04 04+ .bulk $0e,$04,$04,$04,$04,$06,$04,$00
7027: 1f 01 06 08+ .bulk $1f,$01,$06,$08,$10,$11,$0e,$00
702f: 0e 11 10 1c+ .bulk $0e,$11,$10,$1c,$08,$10,$0f,$00
7037: 08 08 3f 09+ .bulk $08,$08,$3f,$09,$0a,$0c,$08,$00
703f: 0e 11 10 10+ .bulk $0e,$11,$10,$10,$0f,$01,$1f,$00
7047: 0e 11 11 0f+ .bulk $0e,$11,$11,$0f,$01,$02,$1c,$00
704f: 02 02 02 04+ .bulk $02,$02,$02,$04,$08,$10,$1f,$00
7057: 0e 11 11 0e+ .bulk $0e,$11,$11,$0e,$11,$11,$0e,$00
705f: 07 08 10 1e+ .bulk $07,$08,$10,$1e,$11,$11,$0e,$00 ;'9'
7067: 00 04 04 1f+ .bulk $00,$04,$04,$1f,$04,$04,$00,$00 ;'+'
706f: 00 00 00 1f+ .bulk $00,$00,$00,$1f,$00,$00,$00,$00 ;'-'
7077: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$00,$00,$00 ;' '
;
; Table of values used to update the "create multiple shapes in one frame"
; counter at $6d64.
707f: 30 18 10 0c+ create_mult_tab .bulk $30,$18,$10,$0c,$0c,$30,$18,$02
7087: 08 0c 0c 01+ .junk 5
;
; Determines which classes of objects are spawned in this region of space. Take
; the region index from $6d63, multiply by 8, and use that as an index. Each
; row of 8 specifies the maximum number of objects of that class that can be
; created here.
;
; The shape classes are:
; 0: Epoch logo
; 1: enemy bases
; 2: enemy ships + time portal
; 3: enemy projectiles
; 4: enemy base (300pt version only); unused below
; 5: time portal boundaries
; 6: friendly base
; 7: stars
; (time portals are in the same set as enemy ships)
;
; Classes 8-10 are used for player projectiles and enemy ship explosions.
region_class_max
708c: 00 01 01 01+ .bulk $00,$01,$01,$01,$00,$00,$00,$0c ;$01: 1 base, 1 ship, 1 projectile, 12 stars
7094: 00 01 01 00+ .bulk $00,$01,$01,$00,$00,$00,$00,$0f ;$02: 1 base, 1 ship, 15 stars
709c: 00 00 02 02+ .bulk $00,$00,$02,$02,$00,$00,$00,$0b ;$03: 2 ships, 2 projectiles, 11 stars
70a4: 00 00 00 00+ .bulk $00,$00,$00,$00,$00,$0c,$00,$00 ;$03: traveling through time portal
70ac: 00 01 00 01+ .bulk $00,$01,$00,$01,$00,$00,$01,$0c ;$04: 1 base, 1 projectile, 1 friendly, 12 stars
70b4: 00 00 01 00+ .bulk $00,$00,$01,$00,$00,$00,$00,$20 ;$05: 1 ship, 32 stars (my god, it's full of)
70bc: 01 00 00 00+ .bulk $01,$00,$00,$00,$00,$00,$00,$08 ;$06: title sequence
70c4: 00 01 01 00+ .bulk $00,$01,$01,$00,$00,$00,$01,$09 ;$07: 1 base, 1 ship, 1 friendly, 9 stars
70cc: 8c 70 region_tab_base .dd2 region_class_max ;points to the region table
;
; Lo-res color values. Used to set the color on lo-res page 2, which is flashed
; on certain events (e.g. getting hit).
70ce: 06 0c 0d 0f+ lo_res_color .bulk $06,$0c,$0d,$0f,$09,$01,$0e,$0d ;m.blu, l.grn, yell, wht, orng, red, aqu, yell
70d6: 00 00 00 00+ .junk 6
;
; Screen columns for status line items: score, time, fuel, amun, high.
70dc: 07 0f 15 1b+ rsrc_print_col .bulk $07,$0f,$15,$1b,$00
;
; Index into $6dbd: score, time, fuel, amun, high. This is the index of the
; *last* byte, since that's what we want to print first (little-endian).
status_val_index
70e1: 03 06 09 0c+ .bulk $03,$06,$09,$0c,$16
;
; Score rating thresholds (24-bit little-endian BCD):
; 0 - 800 : novice
; 800 - 2499 : pilot
; 2500 - 7999 : captain
; 8000 - 24999 : fleet commander
; > 25000 : galactic emperor
rating_thresholds
70e6: 00 08 00 .dd3 $000800
70e9: 00 25 00 .dd3 $002500
70ec: 00 80 00 .dd3 $008000
70ef: 00 50 02 .dd3 $025000
70f2: 00 00 00 .junk 3
70f5: 08 00 time_rate .dd2 $0008 ;-8 units per tick
70f7: 20 00 speed_rate .dd2 $0020 ;+20 per tick while button held (cf. $7349)
time_portal_rate
70f9: 00 00 .dd2 $0000 ;+N time restored (based on speed)
70fb: 01 00 amun_rate .dd2 $0001 ;-1 per shot
; Enemy ship point values.
enemy_point_values
70fd: 00 05 00 00 .dd4 $00000500 ;+5 (not used?)
7101: 00 10 00 00 .dd4 $00001000 ;+10 (not used?)
7105: 00 30 00 00 .dd4 $00003000 ;+30 for alien: |-#-|
7109: 00 40 00 00 .dd4 $00004000 ;+40 for alien: (rotated H)
710d: 00 60 00 00 .dd4 $00006000 ;+60 for alien: =-##-=
7111: 00 00 01 00 .dd4 $00010000 ;+100 for alien: two rotated H
7115: 00 00 03 00 .dd4 $00030000 ;+300 for base #1 (block)
7119: 00 00 05 00 .dd4 $00050000 ;+500 for base #2 (wide/thin)
711d: 00 03 fuel_rate_1 .dd2 $0300 ;-300 (collision)
711f: 02 00 fuel_rate_2 .dd2 $0002 ;-2 (maneuvers)
7121: 00 00 00 5a+ .junk 80
;
; Sound effect tables (function at $7cda). Table 0 is for player cannon fire,
; table 1 is for an enemy ship explosion. Five bytes are copied into $c8-cc.
; The last byte (which acts as an "enabled" flag) is always zero.
7171: 01 02 03 03+ sfx_table_0 .bulk $01,$02,$03,$03,$00
7176: 02 03 04 06+ .bulk $02,$03,$04,$06,$00
717b: 03 05 07 09+ .bulk $03,$05,$07,$09,$00
7180: 05 08 0a 0d+ .bulk $05,$08,$0a,$0d,$00
7185: 0a 0a 0c 14+ .bulk $0a,$0a,$0c,$14,$00
718a: 0a 0c 0e 18+ .bulk $0a,$0c,$0e,$18,$00
718f: 0a 10 18 24+ .bulk $0a,$10,$18,$24,$00
7194: 00 01 00 09+ .bulk $00,$01,$00,$09,$00
7199: 00 00 02 03+ sfx_table_1 .bulk $00,$00,$02,$03,$00
719e: 00 00 03 06+ .bulk $00,$00,$03,$06,$00
71a3: 00 00 06 0a+ .bulk $00,$00,$06,$0a,$00
71a8: 00 00 0c 10+ .bulk $00,$00,$0c,$10,$00
71ad: 00 00 0e 10+ .bulk $00,$00,$0e,$10,$00
71b2: 00 00 0a 14+ .bulk $00,$00,$0a,$14,$00
71b7: 00 00 07 10+ .bulk $00,$00,$07,$10,$00
71bc: 00 00 0a 14+ .bulk $00,$00,$0a,$14,$00
joystick_sens_mod
71c1: ff fd .dd2 $fdff ;$faff, $fbff, ... $feff
;
; Color pixel bit masks. The index is formed by taking the element color value
; ($00=black, $10=white, ...$60=white) and ORing it with a value (0-6,7-14) for
; the pixel we want to draw or erase.
;
; Hi-res bytes have 7 pixels (with a little hand-waving), so the last entry in
; each set of 8 is ignored. There are 16 bytes per color, rather than 8,
; because the colors change for odd/even columns.
color_bit_masks_thin
71c3: 01 02 04 08+ .bulk $01,$02,$04,$08,$10,$20,$40,$40 ;$00 black (handled specially)
71cb: 01 02 04 08+ .bulk $01,$02,$04,$08,$10,$20,$40,$40
71d3: 01 02 04 08+ .bulk $01,$02,$04,$08,$10,$20,$40,$40 ;$10 white (single pixel)
71db: 01 02 04 08+ .bulk $01,$02,$04,$08,$10,$20,$40,$40
71e3: 02 02 08 08+ .bulk $02,$02,$08,$08,$20,$20,$20,$20 ;$20 green
71eb: 01 01 04 04+ .bulk $01,$01,$04,$04,$10,$10,$40,$40
71f3: 01 01 04 04+ .bulk $01,$01,$04,$04,$10,$10,$40,$40 ;$30 purple
71fb: 02 02 08 08+ .bulk $02,$02,$08,$08,$20,$20,$20,$20
7203: 82 82 88 88+ .bulk $82,$82,$88,$88,$a0,$a0,$a0,$a0 ;$40 orange
720b: 81 81 84 84+ .bulk $81,$81,$84,$84,$90,$90,$c0,$c0
7213: 81 81 84 84+ .bulk $81,$81,$84,$84,$90,$90,$c0,$c0 ;$50 blue
721b: 82 82 88 88+ .bulk $82,$82,$88,$88,$a0,$a0,$a0,$a0
7223: 03 03 06 0c+ .bulk $03,$03,$06,$0c,$18,$30,$60,$60 ;$60 white (double pixel)
722b: 03 03 06 0c+ .bulk $03,$03,$06,$0c,$18,$30,$60,$60
;
; Secret message: "COPYRIGHT BY LARRY R. MILLER 1981 noo". 40 bytes are
; decoded to a secondary buffer, but only 36 are printed.
secret_copyright
7233: 23 2f 30 39+ .bulk $23,$2f,$30,$39,$32,$29,$27,$28,$34,$00,$22,$39,$00,$2c,$21,$32
+ $32,$39,$00,$32,$0e,$00,$2d,$29,$2c,$2c,$25,$32,$00,$11,$19,$18
+ $11,$00,$00,$00,$00,$4e,$4f,$4f
725b: 0d 18 11 0e+ .junk 8
;
; See comments for $71c3, above.
;
; These pixels are for the left edge of something that extends to the right,
; starting in pixel N. If it starts in pixel 0 the entire byte is filled, if it
; starts in pixel 6 only the last bit is set. We always set a color in this
; byte though, so if the color pattern sets bits 1/3/5, and we're starting in
; pixel 6, we'll actually set pixel 5.
;
; When drawing the middle parts of something, we just use index 0/8 to fill the
; whole byte.
color_bit_masks_left
7263: 7f 7e 7c 78+ .bulk $7f,$7e,$7c,$78,$70,$60,$40,$40 ;$00 black (handled specially)
726b: 7f 7e 7c 78+ .bulk $7f,$7e,$7c,$78,$70,$60,$40,$40
7273: 7f 7e 7c 78+ .bulk $7f,$7e,$7c,$78,$70,$60,$40,$40 ;$10 white (single pixel)
727b: 7f 7e 7c 78+ .bulk $7f,$7e,$7c,$78,$70,$60,$40,$40
7283: 2a 2a 28 28+ .bulk $2a,$2a,$28,$28,$20,$20,$20,$20 ;$20 green
728b: 55 55 54 54+ .bulk $55,$55,$54,$54,$50,$50,$40,$40
7293: 55 55 54 54+ .bulk $55,$55,$54,$54,$50,$50,$40,$40 ;$30 purple
729b: 2a 2a 28 28+ .bulk $2a,$2a,$28,$28,$20,$20,$20,$20
72a3: aa aa a8 a8+ .bulk $aa,$aa,$a8,$a8,$a0,$a0,$a0,$a0 ;$40 orange
72ab: d5 d5 d4 d4+ .bulk $d5,$d5,$d4,$d4,$d0,$d0,$c0,$c0
72b3: d5 d5 d4 d4+ .bulk $d5,$d5,$d4,$d4,$d0,$d0,$c0,$c0 ;$50 blue
72bb: aa aa a8 a8+ .bulk $aa,$aa,$a8,$a8,$a0,$a0,$a0,$a0
72c3: 7f 7f 7e 7c+ .bulk $7f,$7f,$7e,$7c,$78,$70,$60,$60 ;$60 white (double pixel)
72cb: 7f 7f 7e 7c+ .bulk $7f,$7f,$7e,$7c,$78,$70,$60,$60
;
; See comments for $71c3, above.
;
; Same basic idea as the previous table, but for the right side of something
; that extends to the left.
color_bit_masks_right
72d3: 01 03 07 0f+ .bulk $01,$03,$07,$0f,$1f,$3f,$7f,$7f ;$00 black (handled specially)
72db: 01 03 07 0f+ .bulk $01,$03,$07,$0f,$1f,$3f,$7f,$7f
72e3: 01 03 07 0f+ .bulk $01,$03,$07,$0f,$1f,$3f,$7f,$7f ;$10 white (single pixel)
72eb: 01 03 07 0f+ .bulk $01,$03,$07,$0f,$1f,$3f,$7f,$7f
72f3: 02 02 0a 0a+ .bulk $02,$02,$0a,$0a,$2a,$2a,$2a,$2a ;$20 green
72fb: 01 01 05 05+ .bulk $01,$01,$05,$05,$15,$15,$55,$55
7303: 01 01 05 05+ .bulk $01,$01,$05,$05,$15,$15,$55,$55 ;$30 purple
730b: 02 02 0a 0a+ .bulk $02,$02,$0a,$0a,$2a,$2a,$2a,$2a
7313: 82 82 8a 8a+ .bulk $82,$82,$8a,$8a,$aa,$aa,$aa,$aa ;$40 orange
731b: 81 81 85 85+ .bulk $81,$81,$85,$85,$95,$95,$d5,$d5
7323: 81 81 85 85+ .bulk $81,$81,$85,$85,$95,$95,$d5,$d5 ;$50 blue
732b: 82 82 8a 8a+ .bulk $82,$82,$8a,$8a,$aa,$aa,$aa,$aa
7333: 03 03 07 0f+ .bulk $03,$03,$07,$0f,$1f,$3f,$7f,$7f ;$60 white (double pixel)
733b: 03 03 07 0f+ .bulk $03,$03,$07,$0f,$1f,$3f,$7f,$7f
7343: 00 07 .junk 2
;
; Joystick axis flip chars, for UI. ' '=normal, 'H'=horiz flip, 'V'=vert flip,
; '\'=both (displays as a glyph with both 'H' and 'V').
7345: 20 48 56 5c axis_flip_chars .str ‘ HV\’
;
; This is an 8.8 number that specifies how rapidly our speed increases or
; decreases in a frame.
;
; This is independent of (but equal to) the speed change that we display on-
; screen, which is specified by a 16-bit value at $70f7.
7349: 00 02 delta_speed .dd2 $0200 ;8.8: speed change per frame
734b: 3d 3d 3d 3d+ .junk 26
;
; Draws one of the numeric status values (score, time, fuel, amun, speed).
; Leading zeroes are replaced with spaces, unless the value is zero.
;
; Values for X/Y:
; $24/$0e: speed in column 36
; $0f/$06: time in column 6
;
; On entry:
; X-reg: horizontal offset (0-39)
; Y-reg: offset to resource to print
; $86: number of BCD bytes in value
;
• Clear variables
]bcd_byte_cnt .var $86 {addr/1}
]nonzero_flag .var $87 {addr/1}
]byte_counter .var $88 {addr/1}
]rsrc_index .var $89 {addr/1}
7365: a5 86 DrawStatusNum lda ]bcd_byte_cnt
7367: 85 88 sta ]byte_counter ;number of two-digit BCD bytes to print
7369: a9 00 lda #$00
736b: 85 87 sta ]nonzero_flag ;clear flag
736d: 84 89 sty ]rsrc_index
736f: b9 bd 6d :Loop lda resource_state,y ;get value
7372: 29 f0 and #$f0 ;strip low nibble
7374: d0 0e bne :HiNonzero ;nonzero, print it
7376: a5 87 lda ]nonzero_flag ;have we seen a nonzero value before?
7378: d0 05 bne :HiPrint0 ;yes, print '0'
737a: a9 60 lda #$60 ;no, print ' '
737c: 4c 87 73 jmp :HiPrint
737f: a9 00 :HiPrint0 lda #$00 ;'0'
7381: 4c 87 73 jmp :HiPrint
7384: e6 87 :HiNonzero inc ]nonzero_flag ;set flag
7386: 4a lsr A ;divide by 2 to get value * 8
7387: 20 df 75 :HiPrint jsr PrintDigitLine9 ;print the digit
738a: a4 89 ldy ]rsrc_index
738c: b9 bd 6d lda resource_state,y ;get same byte
738f: 29 0f and #$0f ;strip the high nibble
7391: d0 14 bne :LoNonzero ;nonzero, print it
7393: a5 87 lda ]nonzero_flag ;have we seen a nonzero value before?
7395: d0 0b bne :LoPrint0 ;yes, print '0'
7397: a5 88 lda ]byte_counter ;get bytes remaining
7399: c9 02 cmp #$02 ;is it < 2?
739b: 30 05 bmi :LoPrint0 ;yes, this is last digit; branch
739d: a9 60 lda #$60 ;print ' '
739f: 4c ac 73 jmp :LoPrint
73a2: a9 00 :LoPrint0 lda #$00 ;print '0'
73a4: 4c ac 73 jmp :LoPrint
73a7: e6 87 :LoNonzero inc ]nonzero_flag ;set flag
73a9: 0a asl A ;multiply by 8
73aa: 0a asl A
73ab: 0a asl A
73ac: 20 df 75 :LoPrint jsr PrintDigitLine9 ;print the digit
73af: c6 89 dec ]rsrc_index ;decrement to next little-endian digit
73b1: a4 89 ldy ]rsrc_index
73b3: c6 88 dec ]byte_counter ;decrement counter
73b5: d0 b8 bne :Loop ;not done, loop
73b7: ea nop
73b8: 60 rts
;
; Prints a character on line 0.
;
; On entry:
; A-reg: ASCII character value
; X-reg: horizontal offset (0-39)
;
; On exit:
; X-reg: (+1)
;
73b9: 38 PrintCharLine0 sec
73ba: e9 41 sbc #‘A’ ;subtract so 'A' is zero
73bc: 10 39 bpl :PrintLetter ;still >= 0, print it
73be: 18 clc
73bf: 69 11 adc #$11 ;add ('A' - '0') so '0' is zero
73c1: 30 32 bmi :PrintSpace ;still negative, print ' '
73c3: 0a asl A ;multiply by 8 to get index
73c4: 0a asl A
73c5: 0a asl A
73c6: a8 tay
73c7: b9 1d 70 lda font_glyph_digits+6,y ;read pixels from bottom line
73ca: 9d 00 20 sta HIRES_P1,x ;line 0
73cd: b9 1c 70 lda font_glyph_digits+5,y
73d0: 9d 00 24 sta HIRES_P1+$400,x
73d3: b9 1b 70 lda font_glyph_digits+4,y
73d6: 9d 00 28 sta HIRES_P1+$800,x
73d9: b9 1a 70 lda font_glyph_digits+3,y
73dc: 9d 00 2c sta HIRES_P1+$c00,x
73df: b9 19 70 lda font_glyph_digits+2,y
73e2: 9d 00 30 sta HIRES_P1+$1000,x
73e5: b9 18 70 lda font_glyph_digits+1,y
73e8: 9d 00 34 sta HIRES_P1+$1400,x
73eb: b9 17 70 lda font_glyph_digits,y
73ee: 9d 00 38 sta HIRES_P1+$1800,x
73f1: e8 inx
73f2: 4c 26 74 jmp :Return
73f5: a9 1a :PrintSpace lda #$1a ;blank glyph
73f7: 0a :PrintLetter asl A
73f8: 0a asl A
73f9: 0a asl A
73fa: a8 tay
73fb: b9 3d 6f lda font_glyphs+6,y
73fe: 9d 00 20 sta HIRES_P1,x
7401: b9 3c 6f lda font_glyphs+5,y
7404: 9d 00 24 sta HIRES_P1+$400,x
7407: b9 3b 6f lda font_glyphs+4,y
740a: 9d 00 28 sta HIRES_P1+$800,x
740d: b9 3a 6f lda font_glyphs+3,y
7410: 9d 00 2c sta HIRES_P1+$c00,x
7413: b9 39 6f lda font_glyphs+2,y
7416: 9d 00 30 sta HIRES_P1+$1000,x
7419: b9 38 6f lda font_glyphs+1,y
741c: 9d 00 34 sta HIRES_P1+$1400,x
741f: b9 37 6f lda font_glyphs,y
7422: 9d 00 38 sta HIRES_P1+$1800,x
7425: e8 inx
7426: 60 :Return rts
;
; Prints a character on line 9 (not 8).
;
; On entry:
; A-reg: ASCII character value
; X-reg: horizontal offset (0-39)
;
; On exit:
; X-reg: (+1)
;
7427: 38 PrintCharLine9 sec
7428: e9 41 sbc #‘A’
742a: 10 39 bpl :PrintLetter
742c: 18 clc
742d: 69 11 adc #$11
742f: 30 32 bmi :PrintSpace
7431: 0a asl A
7432: 0a asl A
7433: 0a asl A
7434: a8 tay
7435: b9 1d 70 lda font_glyph_digits+6,y
7438: 9d 80 24 sta HIRES_P1+$480,x ;line 9
743b: b9 1c 70 lda font_glyph_digits+5,y
743e: 9d 80 28 sta HIRES_P1+$880,x
7441: b9 1b 70 lda font_glyph_digits+4,y
7444: 9d 80 2c sta HIRES_P1+$c80,x
7447: b9 1a 70 lda font_glyph_digits+3,y
744a: 9d 80 30 sta HIRES_P1+$1080,x
744d: b9 19 70 lda font_glyph_digits+2,y
7450: 9d 80 34 sta HIRES_P1+$1480,x
7453: b9 18 70 lda font_glyph_digits+1,y
7456: 9d 80 38 sta HIRES_P1+$1880,x
7459: b9 17 70 lda font_glyph_digits,y
745c: 9d 80 3c sta HIRES_P1+$1c80,x
745f: e8 inx
7460: 4c 94 74 jmp L7494
7463: a9 1a :PrintSpace lda #$1a ;blank glyph
7465: 0a :PrintLetter asl A
7466: 0a asl A
7467: 0a asl A
7468: a8 tay
7469: b9 3d 6f lda font_glyphs+6,y
746c: 9d 80 24 sta HIRES_P1+$480,x
746f: b9 3c 6f lda font_glyphs+5,y
7472: 9d 80 28 sta HIRES_P1+$880,x
7475: b9 3b 6f lda font_glyphs+4,y
7478: 9d 80 2c sta HIRES_P1+$c80,x
747b: b9 3a 6f lda font_glyphs+3,y
747e: 9d 80 30 sta HIRES_P1+$1080,x
7481: b9 39 6f lda font_glyphs+2,y
7484: 9d 80 34 sta HIRES_P1+$1480,x
7487: b9 38 6f lda font_glyphs+1,y
748a: 9d 80 38 sta HIRES_P1+$1880,x
748d: b9 37 6f lda font_glyphs,y
7490: 9d 80 3c sta HIRES_P1+$1c80,x
7493: e8 inx
7494: 60 L7494 rts
;
; Prints a character on line 32.
;
; On entry:
; A-reg: ASCII character value
; X-reg: horizontal offset (0-39)
;
; On exit:
; X-reg: (+1)
;
7495: 38 PrintCharLine32 sec
7496: e9 41 sbc #‘A’
7498: 10 39 bpl :PrintLetter
749a: 18 clc
749b: 69 11 adc #$11
749d: 30 32 bmi :PrintSpace
749f: 0a asl A
74a0: 0a asl A
74a1: 0a asl A
74a2: a8 tay
74a3: b9 1d 70 lda font_glyph_digits+6,y
74a6: 9d 00 22 sta HIRES_P1+$200,x ;line 32
74a9: b9 1c 70 lda font_glyph_digits+5,y
74ac: 9d 00 26 sta HIRES_P1+$600,x
74af: b9 1b 70 lda font_glyph_digits+4,y
74b2: 9d 00 2a sta HIRES_P1+$a00,x
74b5: b9 1a 70 lda font_glyph_digits+3,y
74b8: 9d 00 2e sta HIRES_P1+$e00,x
74bb: b9 19 70 lda font_glyph_digits+2,y
74be: 9d 00 32 sta HIRES_P1+$1200,x
74c1: b9 18 70 lda font_glyph_digits+1,y
74c4: 9d 00 36 sta HIRES_P1+$1600,x
74c7: b9 17 70 lda font_glyph_digits,y
74ca: 9d 00 3a sta HIRES_P1+$1a00,x
74cd: e8 inx
74ce: 4c 02 75 jmp L7502
74d1: a9 1a :PrintSpace lda #$1a ;blank glyph
74d3: 0a :PrintLetter asl A
74d4: 0a asl A
74d5: 0a asl A
74d6: a8 tay
74d7: b9 3d 6f lda font_glyphs+6,y
74da: 9d 00 22 sta HIRES_P1+$200,x
74dd: b9 3c 6f lda font_glyphs+5,y
74e0: 9d 00 26 sta HIRES_P1+$600,x
74e3: b9 3b 6f lda font_glyphs+4,y
74e6: 9d 00 2a sta HIRES_P1+$a00,x
74e9: b9 3a 6f lda font_glyphs+3,y
74ec: 9d 00 2e sta HIRES_P1+$e00,x
74ef: b9 39 6f lda font_glyphs+2,y
74f2: 9d 00 32 sta HIRES_P1+$1200,x
74f5: b9 38 6f lda font_glyphs+1,y
74f8: 9d 00 36 sta HIRES_P1+$1600,x
74fb: b9 37 6f lda font_glyphs,y
74fe: 9d 00 3a sta HIRES_P1+$1a00,x
7501: e8 inx
7502: 60 L7502 rts
;
; Prints a character on line 160.
;
; On entry:
; A-reg: ASCII character value
; X-reg: horizontal offset (0-39)
;
; On exit:
; X-reg: (+1)
;
PrintCharLine160
7503: 38 sec
7504: e9 41 sbc #‘A’ ;subtract so 'A' is zero
7506: 10 39 bpl :PrintLetter ;still >= 0, print it
7508: 18 clc
7509: 69 11 adc #$11 ;add ('A' - '0') so '0' is zero
750b: 30 32 bmi :PrintSpace ;still negative, must be ' '
750d: 0a asl A ;multiply by 8 to get index
750e: 0a asl A
750f: 0a asl A
7510: a8 tay
7511: b9 1d 70 lda font_glyph_digits+6,y
7514: 9d 50 22 sta HIRES_P1+$250,x ;line 160
7517: b9 1c 70 lda font_glyph_digits+5,y
751a: 9d 50 26 sta HIRES_P1+$650,x
751d: b9 1b 70 lda font_glyph_digits+4,y
7520: 9d 50 2a sta HIRES_P1+$a50,x
7523: b9 1a 70 lda font_glyph_digits+3,y
7526: 9d 50 2e sta HIRES_P1+$e50,x
7529: b9 19 70 lda font_glyph_digits+2,y
752c: 9d 50 32 sta HIRES_P1+$1250,x
752f: b9 18 70 lda font_glyph_digits+1,y
7532: 9d 50 36 sta HIRES_P1+$1650,x
7535: b9 17 70 lda font_glyph_digits,y
7538: 9d 50 3a sta HIRES_P1+$1a50,x
753b: e8 inx
753c: 4c 70 75 jmp :Return
753f: a9 1a :PrintSpace lda #$1a ;blank glyph
7541: 0a :PrintLetter asl A ;multiply by 8 to get index
7542: 0a asl A
7543: 0a asl A
7544: a8 tay
7545: b9 3d 6f lda font_glyphs+6,y
7548: 9d 50 22 sta HIRES_P1+$250,x ;line 160
754b: b9 3c 6f lda font_glyphs+5,y
754e: 9d 50 26 sta HIRES_P1+$650,x
7551: b9 3b 6f lda font_glyphs+4,y
7554: 9d 50 2a sta HIRES_P1+$a50,x
7557: b9 3a 6f lda font_glyphs+3,y
755a: 9d 50 2e sta HIRES_P1+$e50,x
755d: b9 39 6f lda font_glyphs+2,y
7560: 9d 50 32 sta HIRES_P1+$1250,x
7563: b9 38 6f lda font_glyphs+1,y
7566: 9d 50 36 sta HIRES_P1+$1650,x
7569: b9 37 6f lda font_glyphs,y
756c: 9d 50 3a sta HIRES_P1+$1a50,x
756f: e8 inx
7570: 60 :Return rts
;
; Prints a character on line 176.
;
; On entry:
; A-reg: ASCII character value
; X-reg: horizontal offset (0-39)
;
; On exit:
; X-reg: (+1)
;
PrintCharLine176
7571: 38 sec
7572: e9 41 sbc #‘A’
7574: 10 39 bpl :PrintLetter
7576: 18 clc
7577: 69 11 adc #$11
7579: 30 32 bmi :PrintSpace
757b: 0a asl A
757c: 0a asl A
757d: 0a asl A
757e: a8 tay
757f: b9 1d 70 lda font_glyph_digits+6,y
7582: 9d 50 23 sta HIRES_P1+$350,x ;line 176
7585: b9 1c 70 lda font_glyph_digits+5,y
7588: 9d 50 27 sta HIRES_P1+$750,x
758b: b9 1b 70 lda font_glyph_digits+4,y
758e: 9d 50 2b sta HIRES_P1+$b50,x
7591: b9 1a 70 lda font_glyph_digits+3,y
7594: 9d 50 2f sta HIRES_P1+$f50,x
7597: b9 19 70 lda font_glyph_digits+2,y
759a: 9d 50 33 sta HIRES_P1+$1350,x
759d: b9 18 70 lda font_glyph_digits+1,y
75a0: 9d 50 37 sta HIRES_P1+$1750,x
75a3: b9 17 70 lda font_glyph_digits,y
75a6: 9d 50 3b sta HIRES_P1+$1b50,x
75a9: e8 inx
75aa: 4c de 75 jmp :Return
75ad: a9 1a :PrintSpace lda #$1a ;blank glyph
75af: 0a :PrintLetter asl A
75b0: 0a asl A
75b1: 0a asl A
75b2: a8 tay
75b3: b9 3d 6f lda font_glyphs+6,y
75b6: 9d 50 23 sta HIRES_P1+$350,x
75b9: b9 3c 6f lda font_glyphs+5,y
75bc: 9d 50 27 sta HIRES_P1+$750,x
75bf: b9 3b 6f lda font_glyphs+4,y
75c2: 9d 50 2b sta HIRES_P1+$b50,x
75c5: b9 3a 6f lda font_glyphs+3,y
75c8: 9d 50 2f sta HIRES_P1+$f50,x
75cb: b9 39 6f lda font_glyphs+2,y
75ce: 9d 50 33 sta HIRES_P1+$1350,x
75d1: b9 38 6f lda font_glyphs+1,y
75d4: 9d 50 37 sta HIRES_P1+$1750,x
75d7: b9 37 6f lda font_glyphs,y
75da: 9d 50 3b sta HIRES_P1+$1b50,x
75dd: e8 inx
75de: 60 :Return rts
;
; Prints a numeric digit, '+', '-', or ' ' on line 9. Used for scores, time,
; fuel, ammo, and forward speed. Unlike the other functions, the digit argument
; must already be multiplied by 8.
;
; On entry:
; A-reg: digit * 8
; X-reg: horizontal offset (0-39)
;
; On exit:
; X-reg: (+1)
;
75df: a8 PrintDigitLine9 tay
75e0: b9 1d 70 lda font_glyph_digits+6,y
75e3: 9d 80 24 sta HIRES_P1+$480,x
75e6: b9 1c 70 lda font_glyph_digits+5,y
75e9: 9d 80 28 sta HIRES_P1+$880,x
75ec: b9 1b 70 lda font_glyph_digits+4,y
75ef: 9d 80 2c sta HIRES_P1+$c80,x
75f2: b9 1a 70 lda font_glyph_digits+3,y
75f5: 9d 80 30 sta HIRES_P1+$1080,x
75f8: b9 19 70 lda font_glyph_digits+2,y
75fb: 9d 80 34 sta HIRES_P1+$1480,x
75fe: b9 18 70 lda font_glyph_digits+1,y
7601: 9d 80 38 sta HIRES_P1+$1880,x
7604: b9 17 70 lda font_glyph_digits,y
7607: 9d 80 3c sta HIRES_P1+$1c80,x
760a: e8 inx
760b: 60 rts
760c: 09 .junk 1
760d: 26 copy_prot_const .dd1 $26
760e: 07 :saved_yreg .dd1 $07
;
; Creates a new instance of a shape. Chooses a random shape from the requested
; shape class.
;
; If we don't have enough room, this returns without creating anything.
;
; On entry:
; Y-reg: shape class index (0-11)
;
; On exit:
; $62: index of newly-created object
;
• Clear variables
]shape_cls_ptr .var $16 {addr/2}
]offset_tab_ptr .var $18 {addr/2}
]rng_limit_mode .var $88 {addr/1}
]rng_result .var $8a {addr/2}
760f: ea CreateObject nop
7610: 8c 0e 76 sty :saved_yreg
7613: 84 a3 sty shape_cl_index
7615: 98 tya
7616: 0a asl A ;double it
7617: a8 tay ;keep it in Y-reg
7618: ad 00 40 lda shape_data_offset ;create a pointer to $53f1
761b: 85 18 sta ]offset_tab_ptr
761d: 18 clc
761e: ad 01 40 lda shape_data_offset+1
7621: 69 40 adc #>DATA_AREA
7623: 85 19 sta ]offset_tab_ptr+1 ;$18-19 is now a pointer to shape class offset table
7625: b1 18 lda (]offset_tab_ptr),y ;look up value specified by Y-reg
7627: 85 16 sta ]shape_cls_ptr ;store in $16-17
7629: 18 clc
762a: c8 iny
762b: b1 18 lda (]offset_tab_ptr),y
762d: 69 40 adc #>DATA_AREA
762f: 85 17 sta ]shape_cls_ptr+1 ;$16-17 is now pointer to shape_NN
]shape_ptr .var $18 {addr/2}
7631: a9 ff lda #$ff
7633: 85 88 sta ]rng_limit_mode ;don't limit RNG result
7635: ea nop
7636: 20 b0 7b jsr GenRandom ;sets $8a-8b
7639: a5 8b lda ]rng_result+1 ;get semi-random value
763b: a0 00 ldy #$00
763d: 31 16 and (]shape_cls_ptr),y ;AND with shape's item AND mask
763f: 0a asl A ;double it
7640: 69 02 adc #$02 ;add 2 to skip header (mask + unused byte)
7642: a8 tay
7643: b1 16 lda (]shape_cls_ptr),y ;get offset to shape entry
7645: 85 18 sta ]shape_ptr ;set pointer
7647: c8 iny
7648: b1 16 lda (]shape_cls_ptr),y
764a: ac 0d 76 ldy copy_prot_const ;Y-reg=$26
764d: 18 clc
764e: 69 40 adc #>DATA_AREA
7650: 85 19 sta ]shape_ptr+1 ;$18-19 is now pointer to shape_NN_X
7652: 20 7f 7f jsr Return7f7f
; Copy-protection booby-trap. Loads a constant value from $760d and uses it to
; load a constant value from $0037. If the value at $0037 isn't $25, the code
; below executes, stomping on a semi-random memory location. The game will
; seize up after a couple of seconds.
7655: b9 11 00 lda $0011,y ;get value from $0037
7658: c9 25 cmp #$25 ;is it $25?
765a: f0 14 beq :Okay ;yes, all is well
765c: a5 8a lda ]rng_result ;no, perform random sabotage
765e: 29 7f and #$7f
7660: 85 8a sta ]rng_result
7662: b1 8a lda (]rng_result),y
7664: a0 e7 ldy #$e7 ;write to an offset to be sneaky
7666: 91 8a sta (]rng_result),y
7668: a9 00 lda #$00 ;overwrite the pointer
766a: 85 8a sta ]rng_result
766c: a9 20 lda #$20
766e: 85 8b sta ]rng_result+1
;
7670: a0 00 :Okay ldy #$00
7672: b1 18 lda (]shape_ptr),y ;get number of elements in shape
7674: 8d 79 6d sta element_count
7677: c5 6e cmp free_elem_count ;do we have room?
7679: 30 03 bmi :HaveRoom ;yes, branch
767b: f0 01 beq :HaveRoom
767d: 60 rts
767e: a6 66 :HaveRoom ldx avail_obj_index ;get next available slot num
7680: 86 62 stx cur_obj_index ;use as slot num
7682: 10 02 bpl :HaveSlot ;branch if slot number okay
7684: ea nop
7685: 60 rts
7686: bd 00 9a :HaveSlot lda obj_first_elem_index,x ;check the head of the element list
7689: 30 03 bmi :SlotGood ;entry is unused as expected; branch
768b: 4c 5c 81 jmp PartialRestart ;list is bad, reset state
768e: bc 50 9a :SlotGood ldy obj_next_obj,x ;get index of next object
7691: 84 66 sty avail_obj_index ;remember it for next time
7693: a5 6a lda head_obj_index ;get previous obj list head index
7695: 86 6a stx head_obj_index ;set new object as head of list
7697: 9d 50 9a sta obj_next_obj,x ;put previous head in "next" pointer
; Copy data from +$08-11 in shape header (zmin, zmax, hitbox).
769a: a0 11 ldy #$11
769c: b1 18 :Copy8Loop lda (]shape_ptr),y
769e: 99 79 6d sta element_count,y
76a1: 88 dey
76a2: b1 18 lda (]shape_ptr),y
76a4: 99 79 6d sta element_count,y
76a7: 88 dey
76a8: c0 08 cpy #$08
76aa: 10 f0 bpl :Copy8Loop
;
76ac: c6 6d dec free_obj_count ;decrement number of free object slots
76ae: a5 a3 lda shape_cl_index ;get the shape class index
76b0: 9d 08 9c sta obj_shape_cl_index,x ;store
76b3: ac 0e 76 ldy :saved_yreg ;get the shape class index, from a different place
76b6: b9 69 6d lda active_class_ctrs,y ;get the by-class active object count
76b9: 18 clc
76ba: 69 01 adc #$01 ;increment it
; Copy some more values out of the shape header. Set various object entries.
76bc: 99 69 6d sta active_class_ctrs,y
76bf: a0 00 ldy #$00
76c1: c8 iny ;Y=$01
76c2: b1 18 lda (]shape_ptr),y ;get object lifetime
76c4: 9d 28 9a sta obj_lifetime_ctr,x
76c7: c8 iny ;Y=$02
76c8: b1 18 lda (]shape_ptr),y ;get enemy score class
76ca: 9d 78 9a sta obj_score_class,x
76cd: ea nop
76ce: f0 13 beq :NoPoints ;if not an enemy ship or base, branch
76d0: a9 dd lda #$dd
76d2: 9d f0 9a sta obj_next_enemy_index,x ;set next-enemy index to "none"
76d5: a5 6c lda head_enemy_obj_index ;get previous enemy index
76d7: 86 6c stx head_enemy_obj_index ;replace previous enemy index with ourselves
76d9: 9d c8 9a sta obj_prev_enemy_index,x ;set our "previous enemy" link
76dc: a8 tay ;was the previous-enemy index valid?
76dd: 30 04 bmi :NoPoints ;no, branch
76df: 8a txa ;A-reg = our new object index
76e0: 99 f0 9a sta obj_next_enemy_index,y ;yes, set previous object's next-enemy link to us
76e3: a0 02 :NoPoints ldy #$02
76e5: c8 iny ;Y=$03
76e6: b1 18 lda (]shape_ptr),y
76e8: 9d a0 9a sta obj_shape_uid,x
76eb: c8 iny ;Y=$04
76ec: b1 18 lda (]shape_ptr),y
76ee: 9d 18 9b sta obj_activity_state,x
76f1: 8d 7d 6d sta shape_act_type
76f4: c8 iny ;Y=$05
76f5: b1 18 lda (]shape_ptr),y
76f7: 9d 40 9b sta obj_plyr_proj_flag,x
76fa: c8 iny ;Y=$06
76fb: b1 18 lda (]shape_ptr),y
76fd: 9d 68 9b sta vel_change_intvl_max,x
7700: a0 0e ldy #$0e
7702: c8 iny ;Y=$0f
7703: b1 18 lda (]shape_ptr),y
7705: 9d b8 9b sta hitbox_size_lo,x
7708: c8 iny ;Y=$10
7709: b1 18 lda (]shape_ptr),y
770b: 9d e0 9b sta hitbox_size_hi,x
770e: 20 7f 7f jsr Return7f7f
; Set initial position.
7711: a0 07 ldy #$07
7713: b1 18 lda (]shape_ptr),y ;get shape header +$07
7715: f0 21 beq :Jmp_SetPosGeneral ;value is $00 for most shapes
7717: 30 2e bmi :SetPosnCenter ;$ff for player projectiles and Epoch logo
7719: c9 7f cmp #$7f ;$7f for portal boundaries
771b: f0 1e beq :Jmp_SetBoundPosn
771d: c9 7e cmp #$7e ;$7e for explosion flare and chunks
771f: f0 1d beq :SetPosnExpl
; A-reg=$ff (logo, player projectile) or $01/$02 (enemy projectile). We look
; for an object whose ship class matches the projectile type (1=base, 2=ship).
; If we find it, we set the projectile's position to match. (This is why time
; portals can shoot at you.)
7721: a4 6a ldy head_obj_index
7723: ea nop ;A-reg=$ff (logo, plyr proj) or $01/$02 (enemy proj)
7724: d9 08 9c :FindLoop cmp obj_shape_cl_index,y ;compare to shape class (0-11)
7727: f0 32 beq :CopyPrev ;(found ship that fired projectile?)
7729: be 50 9a ldx obj_next_obj,y ;get index of next object
772c: 30 0a bmi :Jmp_SetPosGeneral ;reached end of list, do general positioning
772e: dd 08 9c cmp obj_shape_cl_index,x ;compare to shape class (0-11)
7731: f0 2d beq :CopyObjPosn ;(found ship that fired projectile?)
7733: bc 50 9a ldy obj_next_obj,x ;get index of next object
7736: 10 ec bpl :FindLoop ;if not done, loop
:Jmp_SetPosGeneral
7738: 4c 8d 77 jmp :SetPosnGeneral
:Jmp_SetBoundPosn
773b: 4c 06 79 jmp :SetBoundaryPosn
]rng_limit .var $86 {addr/2}
]initial_zpos .var $8c {addr/2}
]src_obj_index .var $8e {addr/1}
773e: a5 a2 :SetPosnExpl lda linked_obj_index ;get index of object that exploded
7740: 29 3f and #$3f ;(value is $00-27, not sure what this is for)
7742: 85 8e sta ]src_obj_index
7744: 4c 62 77 jmp :CopyObjPosn1
; Sets the initial object position to the center of the screen. Useful for
; player projectiles and the Epoch logo.
7747: a9 00 :SetPosnCenter lda #$00
7749: 85 bf sta initial_xpos
774b: 85 c0 sta initial_xpos+1
774d: 85 c1 sta initial_ypos
774f: 85 c2 sta initial_ypos+1
7751: 85 8c sta ]initial_zpos
7753: 85 8d sta ]initial_zpos+1
7755: 20 7f 7f jsr Return7f7f
7758: 4c 2a 79 jmp :InitPosnRdy
775b: 84 8e :CopyPrev sty ]src_obj_index
775d: 4c 62 77 jmp :CopyObjPosn1
; Copy position from existing object. The top/left coordinate of the first
; element is used.
7760: 86 8e :CopyObjPosn stx ]src_obj_index
7762: a4 8e :CopyObjPosn1 ldy ]src_obj_index
7764: be 00 9a ldx obj_first_elem_index,y ;get index of first element
7767: bd c0 a1 lda elem_left_lo,x ;copy left to X
776a: 85 bf sta initial_xpos
776c: bd 00 a2 lda elem_left_hi,x
776f: 85 c0 sta initial_xpos+1
7771: bd 40 a2 lda elem_top_lo,x ;copy top to Y
7774: 85 c1 sta initial_ypos
7776: bd 80 a2 lda elem_top_hi,x
7779: 85 c2 sta initial_ypos+1
777b: bd 40 a1 lda elem_zpos_lo,x ;copy Z
777e: 85 8c sta ]initial_zpos
7780: bd 80 a1 lda elem_zpos_hi,x
7783: 85 8d sta ]initial_zpos+1
7785: a6 62 ldx cur_obj_index
7787: 20 7f 7f jsr Return7f7f
778a: 4c 2a 79 jmp :InitPosnRdy
; Sets initial position for ships, bases, stars.
778d: a6 62 :SetPosnGeneral ldx cur_obj_index
778f: 18 clc ;do sound stuff
7790: a5 b2 lda engine_sound_ctr?+1
7792: 69 1a adc #$1a
7794: 85 b2 sta engine_sound_ctr?+1
7796: 90 0f bcc :NoSound
7798: e6 b3 inc engine_sound_ctr?+2
779a: a5 cc lda engine_sound_enable
779c: f0 09 beq :NoSound
779e: a5 b3 lda engine_sound_ctr?+2
77a0: 25 b1 and engine_sound_ctr?
77a2: d0 03 bne :NoSound
77a4: ad 30 c0 lda SPKR
; Perform some calculations on linear and angular speed to form the limit we
; pass to the RNG, then generate a random value.
77a7: ad aa 6d :NoSound lda joystick_x_mag ;sum up the joystick axis magnitudes
77aa: 18 clc
77ab: 6d ad 6d adc joystick_y_mag
77ae: 8d ab 6d sta joy_mag_sum
77b1: a5 99 lda adj_fwd_speed+1 ;get high byte of forward speed
77b3: 29 0f and #%00001111 ;(max speed is $0384 (9000), so this does nothing)
77b5: 85 8c sta ]initial_zpos
77b7: a5 98 lda adj_fwd_speed ;get low byte
77b9: 29 f0 and #%11110000 ;strip low nibble
77bb: 05 8c ora ]initial_zpos ;blend with low nibble of high byte
77bd: a8 tay
77be: b9 00 b0 lda speed_table?,y ;get value from table
77c1: a4 99 ldy adj_fwd_speed+1 ;get high byte of forward speed
77c3: 10 03 bpl :IsPos ;branch if positive (always)
77c5: 49 ff eor #$ff ;(perhaps at one time the player could go backwards?)
77c7: ea nop
77c8: 18 :IsPos clc
77c9: 6d ab 6d adc joy_mag_sum ;add the sum of the joystick magnitudes
77cc: 8d ac 6d sta joy_mag_plus_spd
77cf: 09 02 ora #%00000010 ;set bit 1 (why?)
77d1: 85 86 sta ]rng_limit
77d3: a9 00 lda #$00
77d5: 85 88 sta ]rng_limit_mode ;limit range
77d7: 85 87 sta ]rng_limit+1 ;high byte is zero
77d9: 90 03 bcc :NoInc
77db: e6 87 inc ]rng_limit+1 ;or, rarely, 1
77dd: ea nop
77de: 20 b0 7b :NoInc jsr GenRandom
77e1: a5 8b lda ]rng_result+1 ;get the high byte of the result
77e3: ea nop
77e4: f0 03 beq :WasZero ;if zero, branch; this is most common case
77e6: 4c b1 78 :Jmp_PosnInside jmp :SetPosnInside
]random_val .var $8e {addr/1}
77e9: a5 8a :WasZero lda ]rng_result ;get the low byte of the result
77eb: 85 8e sta ]random_val ;save for later
77ed: cd ab 6d cmp joy_mag_sum ;compare to the joystick sum
77f0: ea nop
77f1: b0 f3 bcs :Jmp_PosnInside ;was >=, take less-common path
;
77f3: 18 clc ;do sound stuff
77f4: a5 b2 lda engine_sound_ctr?+1
77f6: 69 26 adc #$26
77f8: 85 b2 sta engine_sound_ctr?+1
77fa: 90 0f bcc :NoSound
77fc: e6 b3 inc engine_sound_ctr?+2
77fe: a5 cc lda engine_sound_enable
7800: f0 09 beq :NoSound
7802: a5 b3 lda engine_sound_ctr?+2
7804: 25 b1 and engine_sound_ctr?
7806: d0 03 bne :NoSound
7808: ad 30 c0 lda SPKR
780b: 38 :NoSound sec
; Generate initial position, placing the object at one edge of the screen.
;
; The distance calculation generates two random numbers and keeps the larger
; one, probably as a way to bias the initial placement toward greater distance.
780c: ad 83 6d lda shape_zmax ;get max initial Z position for this shape
780f: ed 81 6d sbc shape_zmin ;subtract minimum position
7812: 85 86 sta ]rng_limit ;save delta
7814: ad 84 6d lda shape_zmax+1 ;repeat for high byte
7817: ed 82 6d sbc shape_zmin+1
781a: 85 87 sta ]rng_limit+1
781c: 20 b0 7b jsr GenRandom ;generate random number between 0 and limit
781f: a5 8a lda ]rng_result ;copy value out
7821: 85 8c sta ]initial_zpos
7823: a5 8b lda ]rng_result+1
7825: 85 8d sta ]initial_zpos+1
7827: 20 b0 7b jsr GenRandom ;generate a second random number
782a: a5 8a lda ]rng_result
782c: c5 8c cmp ]initial_zpos ;compare new value to previous value
782e: a5 8b lda ]rng_result+1
7830: e5 8d sbc ]initial_zpos+1
7832: 10 08 bpl :KeepNew ;new value bigger, keep it; branch
7834: a5 8c lda ]initial_zpos ;old value bigger, copy to RNG result
7836: 85 8a sta ]rng_result
7838: a5 8d lda ]initial_zpos+1
783a: 85 8b sta ]rng_result+1
783c: 18 :KeepNew clc
783d: a5 8a lda ]rng_result ;get result
783f: 6d 81 6d adc shape_zmin ;add minimum initial Z position
7842: 85 8c sta ]initial_zpos ;save as initial Z
7844: a5 8b lda ]rng_result+1 ;same for high byte
7846: 6d 82 6d adc shape_zmin+1
7849: 85 8d sta ]initial_zpos+1
784b: 20 7f 7f jsr Return7f7f
784e: a5 8c lda ]initial_zpos ;use full value as RNG limit
7850: 85 86 sta ]rng_limit
7852: a5 8d lda ]initial_zpos+1
7854: 85 87 sta ]rng_limit+1
7856: a9 01 lda #$01
7858: 85 88 sta ]rng_limit_mode ;set mode to return +/- value
785a: 20 b0 7b jsr GenRandom ;generate random value
785d: a5 8e lda ]random_val ;get the random number we generated earlier
785f: cd aa 6d cmp joystick_x_mag ;compare to joystick position
7862: ea nop
7863: 90 03 bcc :FasterYaw ;branch if less (more likely if turning faster)
7865: 4c 8c 78 jmp :SlowerYaw
; Set X/Y coordinates. Assuming a 45-degree FOV, we can place an object at the
; edge of the visible area by setting X=Z and/or Y=Z.
7868: a5 8a :FasterYaw lda ]rng_result ;set YC to random value, XC same as ZC
786a: 85 c1 sta initial_ypos ; so it's at left or right edge
786c: a5 8b lda ]rng_result+1
786e: 85 c2 sta initial_ypos+1
7870: a5 8c lda ]initial_zpos
7872: 85 bf sta initial_xpos
7874: a5 8d lda ]initial_zpos+1
7876: 85 c0 sta initial_xpos+1
7878: a5 9c lda joy_yaw_sign ;which way are we turning?
787a: 30 0d bmi :RightTurn ;turning right, create ship on right edge; branch
787c: 38 sec ;set X position to 0-X so it's on left edge
787d: a9 00 lda #$00
787f: e5 bf sbc initial_xpos
7881: 85 bf sta initial_xpos
7883: a9 00 lda #$00
7885: e5 c0 sbc initial_xpos+1
7887: 85 c0 sta initial_xpos+1
7889: 4c 2a 79 :RightTurn jmp :InitPosnRdy
788c: a5 8a :SlowerYaw lda ]rng_result ;set XC to random value, YC same as ZC
788e: 85 bf sta initial_xpos ; so it's at top or bottom edge
7890: a5 8b lda ]rng_result+1
7892: 85 c0 sta initial_xpos+1
7894: a5 8c lda ]initial_zpos
7896: 85 c1 sta initial_ypos
7898: a5 8d lda ]initial_zpos+1
789a: 85 c2 sta initial_ypos+1
789c: ea nop
789d: a5 9f lda joy_pitch_sign ;which we are we turning?
789f: 30 0d bmi :DownTurn ;pitching downward, create at bottom; branch
78a1: 38 sec ;set Y position to 0-Y so it's at top edge
78a2: a9 00 lda #$00
78a4: e5 c1 sbc initial_ypos
78a6: 85 c1 sta initial_ypos
78a8: a9 00 lda #$00
78aa: e5 c2 sbc initial_ypos+1
78ac: 85 c2 sta initial_ypos+1
78ae: 4c 2a 79 :DownTurn jmp :InitPosnRdy
; Set the initial position somewhere in the middle of the view area, rather than
; at the edge. The 45 degree FOV means the Z coordinate defines the edges; we
; reduce it by the size of the hitbox in an attempt to place it at least partly
; on-screen.
78b1: ad 83 6d :SetPosnInside lda shape_zmax ;set Z position to max
78b4: 85 8c sta ]initial_zpos
78b6: ad 84 6d lda shape_zmax+1
78b9: 85 8d sta ]initial_zpos+1
78bb: 38 sec ;set RNG limit to max Z minus header tweak
78bc: a5 8c lda ]initial_zpos
78be: ed 88 6d sbc shape_hitbox
78c1: 85 86 sta ]rng_limit
78c3: a5 8d lda ]initial_zpos+1
78c5: ed 89 6d sbc shape_hitbox+1
78c8: 85 87 sta ]rng_limit+1
78ca: a9 01 lda #$01
78cc: 85 88 sta ]rng_limit_mode ;set RNG to return +/-
78ce: ea nop
78cf: ad 3b 6d lda game_active_flag ;are we in demo mode?
78d2: d0 18 bne :NotDemo ;no, branch
; Tweaks to improve the appearance of ships in the title demo. Does not affect
; stars or projectiles.
78d4: a5 8a lda ]rng_result
78d6: 29 0f and #$0f
78d8: d0 12 bne :NotDemo ;skip this next bit 15 out of 16 times
78da: a5 a3 lda shape_cl_index ;get shape class index
78dc: c9 02 cmp #$02 ;enemy ship?
78de: f0 08 beq :IsDemoShip ;yes, branch
78e0: c9 06 cmp #$06 ;friendly base?
78e2: f0 04 beq :IsDemoShip ;yes, branch
78e4: c9 01 cmp #$01 ;enemy base?
78e6: d0 04 bne :NotDemo ;no, skip this
78e8: a9 01 :IsDemoShip lda #$01
78ea: 85 87 sta ]rng_limit+1 ;set upper limit so things are near the center
78ec: 20 b0 7b :NotDemo jsr GenRandom ;generate random value
78ef: a5 8a lda ]rng_result ;save as X position
78f1: 85 bf sta initial_xpos
78f3: a5 8b lda ]rng_result+1
78f5: 85 c0 sta initial_xpos+1
78f7: 20 b0 7b jsr GenRandom ;generate another random value
78fa: a5 8a lda ]rng_result ;save as Y position
78fc: 85 c1 sta initial_ypos
78fe: a5 8b lda ]rng_result+1
7900: 85 c2 sta initial_ypos+1
7902: ea nop
7903: 4c 2a 79 jmp :InitPosnRdy ;continue
; Sets the position of a time portal boundary object. This was computed
; earlier.
:SetBoundaryPosn
7906: a5 ce lda portal_next_xc ;copy $ce-d1 to $bf-c2
7908: 85 bf sta initial_xpos
790a: a5 cf lda portal_next_xc+1
790c: 85 c0 sta initial_xpos+1
790e: a5 d0 lda portal_next_yc
7910: 85 c1 sta initial_ypos
7912: a5 d1 lda portal_next_yc+1
7914: 85 c2 sta initial_ypos+1
7916: ad 83 6d lda shape_zmax ;set initial Z position to max ($2400 for all)
7919: 85 8c sta ]initial_zpos
791b: ad 84 6d lda shape_zmax+1
791e: 85 8d sta ]initial_zpos+1
7920: a5 8d lda ]initial_zpos+1 ;check high byte
7922: c9 20 cmp #$20 ;>= $20? (time portal bounds are $24)
7924: 10 04 bpl :InitPosnRdy ;yes, branch
7926: a9 20 lda #$20
7928: 85 8d sta ]initial_zpos+1 ;ensure it's at least $20
;
; Initial position is set. Finish creation. (Multiple things branch here.)
;
792a: 20 7f 7f :InitPosnRdy jsr Return7f7f
792d: a5 8c lda ]initial_zpos ;add 2 to initial Z position (why... to
792f: 18 clc ; prevent player projectiles at Z=0?)
7930: 69 02 adc #$02
7932: 85 8c sta ]initial_zpos
7934: 90 02 bcc :NoInc
7936: e6 8d inc ]initial_zpos+1
; Initialize object slot.
7938: a9 00 :NoInc lda #$00
793a: 9d 10 9e sta obj_move_zc_lo,x
793d: 9d 38 9e sta obj_move_zc_hi,x
7940: 9d 60 9e sta obj_move_xc_lo,x
7943: 9d 88 9e sta obj_move_xc_hi,x
7946: 9d b0 9e sta obj_move_yc_lo,x
7949: 9d d8 9e sta obj_move_yc_hi,x
794c: 9d 20 9d sta obj_spdlim_z_lo,x
794f: 9d 48 9d sta obj_spdlim_z_hi,x
7952: 9d 70 9d sta obj_spdlim_x_lo,x
7955: 9d 98 9d sta obj_spdlim_x_hi,x
7958: 9d c0 9d sta obj_spdlim_y_lo,x
795b: 9d e8 9d sta obj_spdlim_y_hi,x
795e: 9d 30 9c sta obj_move_zc2_lo,x
7961: 9d 58 9c sta obj_move_zc2_hi,x
7964: 9d 80 9c sta obj_move_xc2_lo,x
7967: 9d a8 9c sta obj_move_xc2_hi,x
796a: 9d d0 9c sta obj_move_yc2_lo,x
796d: 9d f8 9c sta obj_move_yc2_hi,x
7970: a9 01 lda #$01
7972: 9d 90 9b sta vel_change_ctr,x ;queue a velocity change
; Shape hdr +$04: 0 for most things, 1 for player projectiles and explosion
; flares, 2 for explosion chunks, 3 for enemy ships (not bases)
7975: ad 7d 6d lda shape_act_type
7978: f0 3f beq :Jmp_DoneWithHdr
797a: c9 01 cmp #$01 ;player projectile or explosion flare?
797c: f0 31 beq :PlyrProjOrFlare ;yes, branch
797e: a0 10 ldy #$10
7980: c8 iny ;Y=$11
7981: b1 18 lda (]shape_ptr),y
7983: 9d 20 9d sta obj_spdlim_z_lo,x
7986: c8 iny
7987: b1 18 lda (]shape_ptr),y
7989: 9d 48 9d sta obj_spdlim_z_hi,x
798c: c8 iny
798d: b1 18 lda (]shape_ptr),y
798f: 9d 70 9d sta obj_spdlim_x_lo,x
7992: c8 iny
7993: b1 18 lda (]shape_ptr),y
7995: 9d 98 9d sta obj_spdlim_x_hi,x
7998: c8 iny
7999: b1 18 lda (]shape_ptr),y
799b: 9d c0 9d sta obj_spdlim_y_lo,x
799e: c8 iny ;Y=$16
799f: b1 18 lda (]shape_ptr),y
79a1: 9d e8 9d sta obj_spdlim_y_hi,x
79a4: ea nop
79a5: a4 a2 ldy linked_obj_index ;are we linked to another object?
79a7: 10 13 bpl :CreateLinked ;yes, branch
79a9: a9 00 lda #$00 ;(?)
79ab: ea nop
79ac: 4c 39 7a jmp :DoneWithHdr
:PlyrProjOrFlare
79af: a4 a2 ldy linked_obj_index ;is a linked object specified?
79b1: 10 09 bpl :CreateLinked ;yes, branch
79b3: a9 00 lda #$00
79b5: 9d 18 9b sta obj_activity_state,x ;mark as non-moving
79b8: ea nop
:Jmp_DoneWithHdr
79b9: 4c 39 7a jmp :DoneWithHdr
79bc: c0 7f :CreateLinked cpy #$7f ;player projectile?
79be: f0 3b beq :PrepPlayerProj? ;yes, branch
79c0: ea nop ;no, explosion flare or chunk
79c1: b9 10 9e lda obj_move_zc_lo,y ;copy object movement vectors
79c4: 9d 10 9e sta obj_move_zc_lo,x
79c7: 9d 30 9c sta obj_move_zc2_lo,x
79ca: b9 38 9e lda obj_move_zc_hi,y
79cd: 9d 38 9e sta obj_move_zc_hi,x
79d0: 9d 58 9c sta obj_move_zc2_hi,x
79d3: b9 60 9e lda obj_move_xc_lo,y
79d6: 9d 60 9e sta obj_move_xc_lo,x
79d9: 9d 80 9c sta obj_move_xc2_lo,x
79dc: b9 88 9e lda obj_move_xc_hi,y
79df: 9d 88 9e sta obj_move_xc_hi,x
79e2: 9d a8 9c sta obj_move_xc2_hi,x
79e5: b9 b0 9e lda obj_move_yc_lo,y
79e8: 9d b0 9e sta obj_move_yc_lo,x
79eb: 9d d0 9c sta obj_move_yc2_lo,x
79ee: b9 d8 9e lda obj_move_yc_hi,y
79f1: 9d d8 9e sta obj_move_yc_hi,x
79f4: 9d f8 9c sta obj_move_yc2_hi,x
79f7: ea nop
79f8: 4c 39 7a jmp :DoneWithHdr
; Prepare player projectile.
:PrepPlayerProj?
79fb: a0 11 ldy #$11
79fd: b1 18 lda (]shape_ptr),y ;get projectile max Z velocity
79ff: 18 clc
7a00: 65 98 adc adj_fwd_speed ;add to ship's forward speed
7a02: 9d 30 9c sta obj_move_zc2_lo,x ;store in object movement table
7a05: 9d 10 9e sta obj_move_zc_lo,x
7a08: c8 iny ;Y=$12
7a09: b1 18 lda (]shape_ptr),y
7a0b: 65 99 adc adj_fwd_speed+1 ;repeat for high byte
7a0d: 9d 58 9c sta obj_move_zc2_hi,x
7a10: 9d 38 9e sta obj_move_zc_hi,x
7a13: ea nop
7a14: c8 iny ;Y=$13
7a15: b1 18 lda (]shape_ptr),y ;load zeroes for the rest of the movement
7a17: 9d 60 9e sta obj_move_xc_lo,x
7a1a: 9d 80 9c sta obj_move_xc2_lo,x
7a1d: c8 iny ;Y=$14
7a1e: b1 18 lda (]shape_ptr),y
7a20: 9d 88 9e sta obj_move_xc_hi,x
7a23: 9d a8 9c sta obj_move_xc2_hi,x
7a26: c8 iny ;Y=$15
7a27: b1 18 lda (]shape_ptr),y
7a29: 9d b0 9e sta obj_move_yc_lo,x
7a2c: 9d d0 9c sta obj_move_yc2_lo,x
7a2f: c8 iny ;Y=$16
7a30: b1 18 lda (]shape_ptr),y
7a32: 9d d8 9e sta obj_move_yc_hi,x
7a35: 9d f8 9c sta obj_move_yc2_hi,x
7a38: ea nop
7a39: 18 :DoneWithHdr clc ;do sound stuff
7a3a: a5 b2 lda engine_sound_ctr?+1
7a3c: 69 1d adc #$1d
7a3e: 85 b2 sta engine_sound_ctr?+1
7a40: 90 0f bcc :NoSound
7a42: e6 b3 inc engine_sound_ctr?+2
7a44: a5 cc lda engine_sound_enable
7a46: f0 09 beq :NoSound
7a48: a5 b3 lda engine_sound_ctr?+2
7a4a: 25 b1 and engine_sound_ctr?
7a4c: d0 03 bne :NoSound
7a4e: ad 30 c0 lda SPKR
; Advance to first element.
7a51: a5 18 :NoSound lda ]shape_ptr ;get shape pointer
7a53: 18 clc
7a54: 69 18 adc #24 ;24 bytes in shape header
7a56: 85 18 sta ]shape_ptr
7a58: 90 02 bcc :NoInc
7a5a: e6 19 inc ]shape_ptr+1
]elem_ptr .var $18 {addr/2}
7a5c: a5 68 :NoInc lda avail_elem_index ;get next available index
7a5e: 85 64 sta cur_elem_index ;save as current index
7a60: 9d 00 9a sta obj_first_elem_index,x ;set as first element in object's list
7a63: ea nop
7a64: a6 64 :NextElement ldx cur_elem_index ;get index of next element
7a66: bd 00 9f lda elem_obj_index,x ;see if something is here
7a69: 30 03 bmi :IndexOkay ;unused, we're good; branch
7a6b: 4c 5c 81 jmp PartialRestart ;unexpected, reset state
7a6e: bd 40 9f :IndexOkay lda elem_next_elem,x ;get index of next element in list
7a71: 85 68 sta avail_elem_index ;update next-available element index
7a73: 18 clc ;do sound stuff
7a74: a5 b2 lda engine_sound_ctr?+1
7a76: 69 12 adc #$12
7a78: 85 b2 sta engine_sound_ctr?+1
7a7a: 90 0f bcc :NoSound
7a7c: e6 b3 inc engine_sound_ctr?+2
7a7e: a5 cc lda engine_sound_enable
7a80: f0 09 beq :NoSound
7a82: a5 b3 lda engine_sound_ctr?+2
7a84: 25 b1 and engine_sound_ctr?
7a86: d0 03 bne :NoSound
7a88: ad 30 c0 lda SPKR
7a8b: c6 6e :NoSound dec free_elem_count
7a8d: a5 62 lda cur_obj_index ;get the object index
7a8f: 9d 00 9f sta elem_obj_index,x ;set as back-ref in element table
7a92: a0 00 ldy #$00
7a94: b1 18 lda (]elem_ptr),y ;get element type
7a96: 9d c0 9f sta elem_types,x
7a99: c8 iny
7a9a: b1 18 lda (]elem_ptr),y ;get color A
7a9c: 9d 00 a0 sta elem_colorsA,x
7a9f: 9d 80 a0 sta elem_cur_colors,x
7aa2: c8 iny
7aa3: b1 18 lda (]elem_ptr),y ;get color B
7aa5: 9d 40 a0 sta elem_colorsB,x
7aa8: c8 iny
7aa9: b1 18 lda (]elem_ptr),y ;color change freq
7aab: 9d c0 a0 sta elem_colorchanges,x
7aae: 9d 00 a1 sta elem_colorchange_ctrs,x
7ab1: ea nop
; Copy the element coordinates, adjusting them for the initial position computed
; earlier.
7ab2: c8 iny ;Y=$04
7ab3: b1 18 lda (]elem_ptr),y ;get Z offset
7ab5: 18 clc
7ab6: 65 8c adc ]initial_zpos
7ab8: 9d 40 a1 sta elem_zpos_lo,x
7abb: c8 iny
7abc: b1 18 lda (]elem_ptr),y
7abe: 65 8d adc ]initial_zpos+1
7ac0: 9d 80 a1 sta elem_zpos_hi,x
7ac3: c8 iny
7ac4: b1 18 lda (]elem_ptr),y ;get left coord
7ac6: 18 clc
7ac7: 65 bf adc initial_xpos
7ac9: 9d c0 a1 sta elem_left_lo,x
7acc: c8 iny
7acd: b1 18 lda (]elem_ptr),y
7acf: 65 c0 adc initial_xpos+1
7ad1: 9d 00 a2 sta elem_left_hi,x
7ad4: c8 iny
7ad5: b1 18 lda (]elem_ptr),y ;get top coord
7ad7: 18 clc
7ad8: 65 c1 adc initial_ypos
7ada: 9d 40 a2 sta elem_top_lo,x
7add: c8 iny
7ade: b1 18 lda (]elem_ptr),y
7ae0: 65 c2 adc initial_ypos+1
7ae2: 9d 80 a2 sta elem_top_hi,x
7ae5: c8 iny
7ae6: b1 18 lda (]elem_ptr),y ;get right coord
7ae8: 18 clc
7ae9: 65 bf adc initial_xpos
7aeb: 9d c0 a2 sta elem_right_lo,x
7aee: c8 iny
7aef: b1 18 lda (]elem_ptr),y
7af1: 65 c0 adc initial_xpos+1
7af3: 9d 00 a3 sta elem_right_hi,x
7af6: c8 iny
7af7: b1 18 lda (]elem_ptr),y ;get bottom coord
7af9: 18 clc
7afa: 65 c1 adc initial_ypos
7afc: 9d 40 a3 sta elem_bottom_lo,x
7aff: c8 iny
7b00: b1 18 lda (]elem_ptr),y
7b02: 65 c2 adc initial_ypos+1
7b04: 9d 80 a3 sta elem_bottom_hi,x
7b07: ea nop
7b08: a9 00 lda #$00
7b0a: 9d 40 a5 sta elem_erase_6,x ;init pixel bit mask?
7b0d: a9 83 lda #$83
7b0f: 9d 80 9f sta elem_mod_types,x ;flag as newly-created, not yet drawn
7b12: ce 79 6d dec element_count ;decrement the counter
7b15: f0 17 beq :Done ;done, bail
7b17: a5 68 lda avail_elem_index ;do we have room for another element?
7b19: 30 13 bmi :Done ;no, bail with partial definition
7b1b: 85 64 sta cur_elem_index ;set "next elem" as current
7b1d: 9d 40 9f sta elem_next_elem,x ;store it in element list as well
7b20: a5 18 lda ]elem_ptr ;advance element pointer 16 bytes
7b22: 18 clc
7b23: 69 10 adc #16
7b25: 85 18 sta ]elem_ptr
7b27: 90 02 bcc :NoInc
7b29: e6 19 inc ]elem_ptr+1 ;advance high byte
7b2b: 4c 64 7a :NoInc jmp :NextElement
7b2e: a9 fc :Done lda #$fc
7b30: 9d 40 9f sta elem_next_elem,x ;mark the end of the element list
7b33: ea nop
7b34: ea nop
7b35: 60 rts
;
; Draws the status line. Each call here draws one character and increments the
; index, so this must be called 40x to draw the whole thing.
;
7b36: ee ce 6d DrawStatusLine inc status_line_index ;advance to next char
7b39: ae ce 6d ldx status_line_index ;get current index
7b3c: e0 28 cpx #40 ;reached end of line?
7b3e: 30 05 bmi :NotEnd ;not yet, branch
7b40: a2 00 ldx #$00
7b42: 8e ce 6d stx status_line_index ;reset to start of line
7b45: bd 85 6e :NotEnd lda text_score_time,x ;get one character
7b48: 20 b9 73 jsr PrintCharLine0 ;draw that character
7b4b: 60 rts
;
; Modifies the instructions that draw and erase vertical lines and rects. Can
; be used to prevent these two functions from modifying the hi-res screen.
;
; (It's unclear what purpose this serves. Might be an attempt to confuse
; somebody disassembling a memory snapshot? As far as I can tell, the
; draw/erase functions are never actually called in "LDA mode".)
;
; On entry:
; A-reg: opcode ($20 for JSR, $ad for LDA)
;
7b4c: 8d 98 90 ModDrwEraVrtRct sta _CallOra0 ;draw vert line
7b4f: 8d a4 91 sta _CallOraSta1 ;draw rect
7b52: 8d c3 91 sta _CallOraSta2
7b55: 8d f1 91 sta _CallOraSta3
7b58: 8d 63 8d sta _CallAnd0 ;erase vert line
7b5b: 8d 07 8e sta _CallAnd1 ;erase rect
7b5e: 8d 2a 8e sta _CallAnd2
7b61: 8d 47 8e sta _CallAnd3
7b64: 60 rts
7b65: 83 8c b4 97+ .junk 75
;
; Generates "random" values.
;
; I'm not sure what the mathematical basis for this is. It seems a bit ad hoc.
;
; The return value can optionally be limited to a range. When the mode is $00,
; a limit of 100 produces a result in the range [0,100]. When the mode is $01,
; odd results are negated, so the range becomes [-99,100] stepping by 2.
;
; On entry:
; $86-87: max value (inclusive)
; $88: $00=limit range, $01=limit and pos/neg, $ff=no limit
;
; On exit:
; $89: copy of $8b before attempts to limit value
; $8a-8b: "random" value
; X-reg preserved
;
• Clear variables
]rng_limit .var $86 {addr/2}
]rng_limit_mode .var $88 {addr/1}
]retval_unmod .var $89 {addr/1}
]retval .var $8a {addr/2}
7bb0: 8e c7 6c GenRandom stx saved_xreg_7bb0 ;preserve X-reg
7bb3: 38 :Retry sec
7bb4: ad c6 6c lda rng_counter ;get counter [0,54]
7bb7: e9 18 sbc #24 ;subtract 24 [-24,30]
7bb9: 10 03 bpl :Ge24 ;[0,30], branch
7bbb: 18 clc ;now [-24,-1]
7bbc: 69 37 adc #55 ;add 55 [31,54]
7bbe: aa :Ge24 tax ;X-reg now [0,54] but flipped around
7bbf: ac c6 6c ldy rng_counter ;get original counter in Y-reg
7bc2: 18 clc
7bc3: b9 c8 6c lda rng_state1,y ;get first value
7bc6: 7d c8 6c adc rng_state1,x ;add to alternate value in same table
7bc9: 85 8a sta ]retval ;set as return value
7bcb: ea nop
7bcc: 99 c8 6c sta rng_state1,y ;update state
7bcf: b9 ff 6c lda rng_state2,y ;get second value
7bd2: 7d ff 6c adc rng_state2,x ;add to alternate value in same table
7bd5: 85 8b sta ]retval+1
7bd7: 85 89 sta ]retval_unmod ;return a copy
7bd9: 99 ff 6c sta rng_state2,y ;update state
7bdc: a8 tay
7bdd: ea nop
; Advance to the next set of "random" values.
7bde: ee c6 6c inc rng_counter ;increment index
7be1: ad c6 6c lda rng_counter ;check current value
7be4: c9 37 cmp #55 ;reached limit?
7be6: 30 06 bmi :CounterOk ;no, branch
7be8: a9 00 lda #$00
7bea: 8d c6 6c sta rng_counter ;reset counter
7bed: ea nop
; Check the mode to see if we need to limit the range. If so, we generate a
; mask for the argument and apply it to the result. If the result is out of
; range, retry.
7bee: a5 88 :CounterOk lda ]rng_limit_mode ;is mode $ff?
7bf0: 30 4d bmi :Return ;yes, bail
7bf2: a4 87 ldy ]rng_limit+1 ;get high byte of limit
7bf4: f0 18 beq :ArgHiZero ;it's zero, just check the low byte
7bf6: be 00 b9 ldx clz_table,y ;count leading zeroes in arg
7bf9: b5 de lda bit_mask_right9,x ;get mask that covers bits
7bfb: 25 8b and ]retval+1 ;mask the return value byte with it
7bfd: 85 8b sta ]retval+1 ;save it
7bff: c5 87 cmp ]rng_limit+1 ;compare to high byte of arg
7c01: ea nop ; in case arg is not (2^N)-1
7c02: f0 05 beq :CheckLow ;matched, check low byte
7c04: 10 ad bpl :Retry ;larger than arg, try again
7c06: 4c 27 7c jmp :GoodRange ;smaller, value is fine
7c09: a5 8a :CheckLow lda ]retval ;get low byte of result
7c0b: 4c 20 7c jmp :CheckLow2
7c0e: a9 00 :ArgHiZero lda #$00
7c10: 85 8b sta ]retval+1 ;limit hi is zero, so result hi will be zero
7c12: a4 86 ldy ]rng_limit ;get low byte of limit arg
7c14: f0 2e beq :Return0 ;looks like they really want zero; branch
7c16: be 00 b9 ldx clz_table,y ;count leading zeroes in arg
7c19: b5 de lda bit_mask_right9,x ;get mask that covers bits
7c1b: 25 8a and ]retval ;mask return value byte with it
7c1d: 85 8a sta ]retval ;save low byte
7c1f: ea nop
7c20: c5 86 :CheckLow2 cmp ]rng_limit ;compare low byte of result to low byte of limit
7c22: ea nop
7c23: f0 02 beq :GoodRange ;they match, accept it
7c25: b0 8c bcs :Retry ;return value too large, re-roll
7c27: a5 88 :GoodRange lda ]rng_limit_mode ;check mode
7c29: f0 14 beq :Return ;is zero, we're done
; Generate a negative result half the time.
7c2b: a5 8a lda ]retval
7c2d: 29 01 and #$01 ;is it odd or even?
7c2f: f0 0e beq :Return ;even, bail
7c31: 38 sec ;odd, compute (0 - retval)
7c32: a9 00 lda #$00
7c34: e5 8a sbc ]retval
7c36: 85 8a sta ]retval
7c38: a9 00 lda #$00
7c3a: e5 8b sbc ]retval+1
7c3c: 85 8b sta ]retval+1
7c3e: ea nop
7c3f: ae c7 6c :Return ldx saved_xreg_7bb0 ;restore X-reg
7c42: ea nop
7c43: 60 rts
7c44: a9 00 :Return0 lda #$00 ;set return value to zero
7c46: 85 8a sta ]retval
7c48: 85 8b sta ]retval+1
7c4a: ea nop
7c4b: 4c 3f 7c jmp :Return
;
; Sets the color of lo-res graphics page 2.
;
; This takes 16 + (5*4 + 2 + 3) * 256 - 1 + 6 = 6421 cycles.
;
; On entry:
; A-reg: color (0-15)
;
]lr_color .var $8c {addr/1}
7c4e: 85 8c SetLoRes2 sta ]lr_color ;shift color so it's in both nibbles
7c50: 0a asl A
7c51: 0a asl A
7c52: 0a asl A
7c53: 0a asl A
7c54: 05 8c ora ]lr_color
7c56: a0 00 ldy #$00
7c58: 99 00 08 :Loop sta $0800,y
7c5b: 99 00 09 sta $0900,y
7c5e: 99 00 0a sta $0a00,y
7c61: 99 00 0b sta $0b00,y
7c64: c8 iny
7c65: d0 f1 bne :Loop
7c67: 60 rts
;
; Reduces the amount of a resource available to the player. The resource counts
; are stored as little-endian BCD values.
;
; Possible values for X-reg/Y-reg:
;
; $05/$0f: $6dc2 (time), by 8
; $0b/$15: $6dc8 (amun), by 1
; $0d/$11: $6dca (speed), by 20
; $08/$39: $6dc5 (fuel), by 2
; $08/$37: $6dc5 (fuel), by 300
;
; On entry:
; X-reg: index to resource counter (base $6dbd)
; Y-reg: index to increase amount (base $70e6)
; $8a: number of BCD bytes (2 digits per byte)
;
; On exit:
; Carry set on underflow
;
• Clear variables
]num_bytes .var $8a {addr/1}
]rsrc_index .var $8b {addr/1}
]digit_counter .var $8c {addr/1}
7c68: ad 3b 6d ReduceResource lda game_active_flag ;game active?
7c6b: f0 2f beq RsrcChangeOk ;no, bail without changing
7c6d: a5 8a lda ]num_bytes ;get number of bytes to update
7c6f: 29 07 and #$07 ;limit to 0-7
7c71: 85 8c sta ]digit_counter ;save it
7c73: 86 8b stx ]rsrc_index
7c75: f8 sed ;switch to decimal mode
7c76: 38 sec
7c77: bd bd 6d :Loop lda resource_state,x ;get resource digit
7c7a: f9 e6 70 sbc rating_thresholds,y ;subtract value
7c7d: 9d bd 6d sta resource_state,x ;save result
7c80: c8 iny ;advance to next
7c81: e8 inx
7c82: c6 8c dec ]digit_counter ;done with digits?
7c84: ea nop
7c85: d0 f0 bne :Loop ;no, loop
7c87: b0 13 bcs RsrcChangeOk
; Underflow, clamp to zero. (Code also used for overflow.)
7c89: a9 00 lda #$00
7c8b: a4 8a SetRsrcValue ldy ]num_bytes
7c8d: 88 dey
7c8e: a6 8b ldx ]rsrc_index
7c90: 9d bd 6d :ZeroLoop sta resource_state,x ;set all to zero
7c93: e8 inx
7c94: 88 dey
7c95: ea nop
7c96: 10 f8 bpl :ZeroLoop
7c98: d8 cld
7c99: 38 sec ;signal underflow
7c9a: ea nop
7c9b: 60 rts
7c9c: 18 RsrcChangeOk clc ;success
7c9d: d8 cld
7c9e: ea nop
7c9f: 60 rts
;
; Increases the amount of a resource available to the player. The resource
; counts are stored as little-endian BCD values.
;
; Possible values for X-reg/Y-reg:
;
; $05/$13: $6dc2 (time), by ($70f9)
; $0d/$11: $6dca (speed), by 20
; $00/$??: $6dbd (score), by shape-specific value
;
; On entry:
; X-reg: index to resource counter (base $6dbd)
; Y-reg: index to increase amount (base $70e6)
; $8a: number of BCD bytes (2 digits per byte)
;
; On exit:
; Carry set on underflow
;
IncreaseResource
7ca0: ad 3b 6d lda game_active_flag ;game active?
7ca3: f0 f7 beq RsrcChangeOk ;no, bail without changing
7ca5: 86 8b stx ]rsrc_index
7ca7: a5 8a lda ]num_bytes ;get number of bytes to update
7ca9: 85 8c sta ]digit_counter
7cab: f8 sed
7cac: 18 clc
7cad: bd bd 6d :Loop lda resource_state,x ;get resource value
7cb0: 79 e6 70 adc rating_thresholds,y ;add increment value
7cb3: 9d bd 6d sta resource_state,x ;save it
7cb6: e8 inx ;advance to next
7cb7: c8 iny
7cb8: ea nop
7cb9: c6 8c dec ]digit_counter ;done with digits?
7cbb: d0 f0 bne :Loop ;no, loop
7cbd: 90 dd bcc RsrcChangeOk
; Overflow. Clamp to all 99s.
7cbf: a9 99 lda #$99
7cc1: ea nop
7cc2: 4c 8b 7c jmp SetRsrcValue
;
7cc5: 4c a9 0f Jmp_Memset jmp Memset
7cc8: ea a0 00 91+ .junk 18
;
; Sets up a sound to play over multiple frames.
;
; Y=$00 A=$00: player cannon fired
; Y=$02 A=(score class): enemy ship (non-base) destroyed
;
; On entry:
; A-reg: sub-index (0-7)
; Y-reg: effect number ($00 or $02)
; X-reg preserved
;
• Clear variables
]temp .var $86 {addr/1}
]saved_xreg .var $87 {addr/1}
7cda: 86 87 InitiateSfx stx ]saved_xreg ;preserve X-reg
7cdc: 85 86 sta ]temp
7cde: 0a asl A ;multiply by 4
7cdf: 0a asl A
7ce0: 18 clc
7ce1: 65 86 adc ]temp ;add to itself (multiply by 5)
7ce3: c0 02 cpy #$02 ;is Y-reg 0 or 1?
7ce5: 30 02 bmi :UseTable0 ;yes, branch
7ce7: 69 28 adc #40 ;add 40 so we're indexing table 1
7ce9: a0 00 :UseTable0 ldy #$00
7ceb: aa tax
7cec: ad 48 6d lda sound_disab_flag ;sound disabled?
7cef: d0 11 bne :NoSound ;yes, branch
7cf1: ad 3b 6d lda game_active_flag
7cf4: f0 0c beq :NoSound
7cf6: bd 71 71 :CopyLoop lda sfx_table_0,x ;copy 5 bytes to $c8-cc
7cf9: 99 c8 00 sta sound_counters,y
7cfc: e8 inx
7cfd: c8 iny
7cfe: c0 05 cpy #$05
7d00: 30 f4 bmi :CopyLoop
7d02: a6 87 :NoSound ldx ]saved_xreg ;restore X-reg
7d04: ea nop
7d05: 60 rts
;
; Updates the motion vector for an object. Called on first update for enemy
; ships and projectiles, and then called at random intervals for enemy ships.
;
; Things generally move toward the player (at 0,0,0).
;
; On entry:
; X-reg: object index
;
; On exit:
; Object velocity values updated
; X-reg preserved
;
• Clear variables
]left_coord .var $86 {addr/2}
]top_coord .var $88 {addr/2}
]z_coord .var $8a {addr/2}
]biggest_dim .var $8c {addr/2}
UpdateObjectVelocity
7d06: 18 clc ;do sound stuff
7d07: a5 b2 lda engine_sound_ctr?+1
7d09: 69 41 adc #$41
7d0b: 85 b2 sta engine_sound_ctr?+1
7d0d: 90 0f bcc :NoSound
7d0f: e6 b3 inc engine_sound_ctr?+2
7d11: a5 cc lda engine_sound_enable
7d13: f0 09 beq :NoSound
7d15: a5 b3 lda engine_sound_ctr?+2
7d17: 25 b1 and engine_sound_ctr?
7d19: d0 03 bne :NoSound
7d1b: ad 30 c0 lda SPKR
7d1e: bd 20 9d :NoSound lda obj_spdlim_z_lo,x ;get maximum Z velocity
7d21: 8d 51 6d sta max_z_spd_copy ;save a copy
7d24: bd 48 9d lda obj_spdlim_z_hi,x
7d27: 8d 52 6d sta max_z_spd_copy+1
7d2a: bc 00 9a ldy obj_first_elem_index,x ;get index of first element
7d2d: b9 c0 a1 lda elem_left_lo,y ;copy element left/top/zc into DP storage
7d30: 85 86 sta ]left_coord
7d32: b9 00 a2 lda elem_left_hi,y
7d35: 85 87 sta ]left_coord+1
7d37: b9 40 a2 lda elem_top_lo,y
7d3a: 85 88 sta ]top_coord
7d3c: b9 80 a2 lda elem_top_hi,y
7d3f: 85 89 sta ]top_coord+1
7d41: b9 40 a1 lda elem_zpos_lo,y
7d44: 85 8a sta ]z_coord
7d46: b9 80 a1 lda elem_zpos_hi,y
7d49: 85 8b sta ]z_coord+1
; Find the absolute value of the largest coordinate (left / top / zc) in the
; first element in the object. This is using the current object position, in
; eye coordinates, so the largest coordinate is the point farthest from the
; viewer.
;
; (This code has a lot of redundancies, as if 16-bit signed comparison macros
; got strung together.)
7d4b: a5 87 lda ]left_coord+1 ;get sign of left coordinate
7d4d: 10 0d bpl :LeftPos1 ;positive, branch
7d4f: 49 ff eor #$ff ;negate, store absolute value
7d51: 85 8d sta ]biggest_dim+1 ;(note invert w/o +1)
7d53: a5 86 lda ]left_coord
7d55: 49 ff eor #$ff
7d57: 85 8c sta ]biggest_dim
7d59: 4c 62 7d jmp :LeftCont1
7d5c: 85 8d :LeftPos1 sta ]biggest_dim+1 ;copy left to "biggest"
7d5e: a5 86 lda ]left_coord
7d60: 85 8c sta ]biggest_dim
7d62: a5 89 :LeftCont1 lda ]top_coord+1 ;get high byte of top coordinate
7d64: 10 02 bpl :TopPos1
7d66: 49 ff eor #$ff ;negate
7d68: c5 8d :TopPos1 cmp ]biggest_dim+1 ;compare to low byte of left coordinate
7d6a: f0 06 beq :TopLeftSame ;hi bytes match, check low byte
7d6c: 10 13 bpl :TopBiggerH
7d6e: 18 clc ;force branch at jump destination
7d6f: 4c 8e 7d jmp :FwdBiggerLeft ;left is bigger
7d72: a5 88 :TopLeftSame lda ]top_coord ;get low byte of top coordinate
7d74: a4 89 ldy ]top_coord+1 ;check sign
7d76: 10 02 bpl :TopPos2
7d78: 49 ff eor #$ff ;negate
7d7a: c5 8c :TopPos2 cmp ]biggest_dim ;compare to low byte of left coordinate
7d7c: 90 10 bcc :FwdBiggerLeft ;left is bigger
7d7e: 4c 8b 7d jmp :TopBiggerL ;top is bigger
; Top coord is bigger than left.
7d81: 85 8d :TopBiggerH sta ]biggest_dim+1 ;copy top coord to "biggest"
7d83: a5 88 lda ]top_coord
7d85: a4 89 ldy ]top_coord+1
7d87: 10 02 bpl :TopBiggerL
7d89: 49 ff eor #$ff
7d8b: 85 8c :TopBiggerL sta ]biggest_dim
7d8d: 38 sec ;don't take next branch
7d8e: 90 47 :FwdBiggerLeft bcc :LeftBigger
7d90: a5 89 lda ]top_coord+1 ;copy top coord to "biggest" (again; negative)
7d92: 10 0d bpl :TopPos3
7d94: 49 ff eor #$ff
7d96: 85 8d sta ]biggest_dim+1
7d98: a5 88 lda ]top_coord
7d9a: 49 ff eor #$ff
7d9c: 85 8c sta ]biggest_dim
7d9e: 4c a7 7d jmp :TopCheckZ
7da1: 85 8d :TopPos3 sta ]biggest_dim+1 ;copy top coord to "biggest" (again; positive)
7da3: a5 88 lda ]top_coord
7da5: 85 8c sta ]biggest_dim
; Compare Z coordinate.
7da7: a5 8b :TopCheckZ lda ]z_coord+1 ;get high byte of Z coord
7da9: 10 02 bpl :ZPos1T
7dab: 49 ff eor #$ff ;negate
7dad: c5 8d :ZPos1T cmp ]biggest_dim+1 ;compare to high byte of "biggest"
7daf: f0 06 beq :ZSameT ;equal, check low byte
7db1: 10 13 bpl :ZBiggerT ;zc is bigger, use it
7db3: 18 clc
7db4: 4c d3 7d jmp :ZSmallerT ;zc is smaller, jump to the jump
7db7: a5 8a :ZSameT lda ]z_coord ;get low byte
7db9: a4 8b ldy ]z_coord+1 ;check sign
7dbb: 10 02 bpl :ZPos2T
7dbd: 49 ff eor #$ff ;negate
7dbf: c5 8c :ZPos2T cmp ]biggest_dim ;compare to low byte of "biggest"
7dc1: 90 10 bcc :ZSmallerT ;zc is smaller, branch
7dc3: 4c d0 7d jmp :ZPos3T ;use zc instead
7dc6: 85 8d :ZBiggerT sta ]biggest_dim+1 ;save high byte
7dc8: a5 8a lda ]z_coord ;get low byte
7dca: a4 8b ldy ]z_coord+1 ;check sign
7dcc: 10 02 bpl :ZPos3T
7dce: 49 ff eor #$ff
7dd0: 85 8c :ZPos3T sta ]biggest_dim
7dd2: 38 sec
7dd3: ea :ZSmallerT nop
7dd4: 4c 1a 7e jmp :GotBiggest
; Left coord is bigger than top. (We already have the absolute value in
; "biggest", but we copy it again.)
7dd7: a5 87 :LeftBigger lda ]left_coord+1
7dd9: 10 0d bpl :LeftPos2
7ddb: 49 ff eor #$ff
7ddd: 85 8d sta ]biggest_dim+1
7ddf: a5 86 lda ]left_coord
7de1: 49 ff eor #$ff
7de3: 85 8c sta ]biggest_dim
7de5: 4c ee 7d jmp :LeftCheckZ
7de8: 85 8d :LeftPos2 sta ]biggest_dim+1
7dea: a5 86 lda ]left_coord
7dec: 85 8c sta ]biggest_dim
; Compare Z coordinate. (Duplicate of code above.)
7dee: a5 8b :LeftCheckZ lda ]z_coord+1
7df0: 10 02 bpl :ZPos1L
7df2: 49 ff eor #$ff
7df4: c5 8d :ZPos1L cmp ]biggest_dim+1
7df6: f0 06 beq :ZSameL
7df8: 10 13 bpl :ZBiggerL
7dfa: 18 clc
7dfb: 4c 1a 7e jmp :GotBiggest
7dfe: a5 8a :ZSameL lda ]z_coord
7e00: a4 8b ldy ]z_coord+1
7e02: 10 02 bpl :ZPos2L
7e04: 49 ff eor #$ff
7e06: c5 8c :ZPos2L cmp ]biggest_dim
7e08: 90 10 bcc :GotBiggest
7e0a: 4c 17 7e jmp :ZPos3L
7e0d: 85 8d :ZBiggerL sta ]biggest_dim+1
7e0f: a5 8a lda ]z_coord
7e11: a4 8b ldy ]z_coord+1
7e13: 10 02 bpl :ZPos3L
7e15: 49 ff eor #$ff
7e17: 85 8c :ZPos3L sta ]biggest_dim
7e19: 38 sec
; We now have the biggest dimension value. Use it to configure table lookups.
]table_ptr1 .var $10 {addr/2}
]scale_tab_val .var $7e {addr/1}
]clz_value .var $80 {addr/1}
7e1a: ea :GotBiggest nop
7e1b: a5 8c lda ]biggest_dim ;add 2 to biggest dimension
7e1d: 18 clc
7e1e: 69 02 adc #$02
7e20: 85 8c sta ]biggest_dim
7e22: 90 02 bcc :NoInc
7e24: e6 8d inc ]biggest_dim+1
7e26: a4 8d :NoInc ldy ]biggest_dim+1 ;get high byte
7e28: d0 17 bne :BigHiNZ ;nonzero, branch
; Get scale factor when biggest dimension < 256.
7e2a: a4 8c ldy ]biggest_dim
7e2c: b9 00 b9 lda clz_table,y ;count leading zeroes [0,8]
7e2f: 18 clc
7e30: 69 08 adc #$08 ;add 8 for the zero high byte [8,16]
7e32: 85 80 sta ]clz_value ;save leading zero count
7e34: 69 a4 adc #>math_tab2_base?-$800 ;[$ac,$b4]
7e36: 85 11 sta ]table_ptr1+1 ;set as pointer high byte
7e38: a4 8c ldy ]biggest_dim ;use biggest dimension, low byte, as index
7e3a: b1 10 lda (]table_ptr1),y
7e3c: 85 7e sta ]scale_tab_val
7e3e: 4c 58 7e jmp :UpdateSpeeds
; Get scale factor when biggest dimension >= 256. The high and low bytes are
; merged into a single byte, which is used to index into a table determined by
; the high byte. This is a clever way of implementing "use the leftmost 8 bits
; of the 16-bit value as an index into the table".
7e41: b9 00 b9 :BigHiNZ lda clz_table,y ;count leading zeroes in high byte
7e44: a8 tay ;copy to Y-reg
7e45: 85 80 sta ]clz_value ;save leading zero count
7e47: 18 clc
7e48: 69 ac adc #>math_tab2_base? ;[$ac,$b4]
7e4a: 85 11 sta ]table_ptr1+1 ;set as pointer high byte
7e4c: a5 8c lda ]biggest_dim ;get "biggest" low byte
7e4e: 39 d5 00 and bit_mask_left9,y ;clear overlapping bits (leaves 0-8 hi bits set)
7e51: 05 8d ora ]biggest_dim+1 ;merge with "biggest" high byte
7e53: a8 tay ;use as index
7e54: b1 10 lda (]table_ptr1),y
7e56: 85 7e sta ]scale_tab_val
;
; Table pointer is configured. Loop over X/Y/Z, using X-reg=$00/$02/$04.
;
]table_ptr2 .var $12 {addr/2}
]ltmp_82? .var $82 {addr/1}
]ltmp_84? .var $84 {addr/1}
]speed_abs .var $8e {addr/2}
]z_spd_tmp .var $90 {addr/2}
7e58: ea :UpdateSpeeds nop
7e59: a2 00 ldx #$00
7e5b: b5 87 :CoordLoop lda ]left_coord+1,x ;get absolute value of coordinate
7e5d: 10 11 bpl :IsPos
7e5f: 38 sec ;compute (0 - coordinate)
7e60: a9 00 lda #$00
7e62: f5 86 sbc ]left_coord,x
7e64: 85 8e sta ]speed_abs
7e66: a9 00 lda #$00
7e68: f5 87 sbc ]left_coord+1,x
7e6a: 85 8f sta ]speed_abs+1
7e6c: ea nop
7e6d: 4c 77 7e jmp L7E77
7e70: 85 8f :IsPos sta ]speed_abs+1
7e72: b5 86 lda ]left_coord,x
7e74: ea nop
7e75: 85 8e sta ]speed_abs
;
7e77: a4 8d L7E77 ldy ]biggest_dim+1 ;check high byte
7e79: f0 10 beq :HighZero
7e7b: a4 80 ldy ]clz_value
7e7d: a5 8e lda ]speed_abs
7e7f: 39 d5 00 and bit_mask_left9,y
7e82: 05 8f ora ]speed_abs+1
7e84: a8 tay
7e85: b1 10 lda (]table_ptr1),y
7e87: ea nop
7e88: 4c 90 7e jmp :Cont
7e8b: a4 8e :HighZero ldy ]speed_abs
7e8d: b1 10 lda (]table_ptr1),y
7e8f: ea nop
;
7e90: a8 :Cont tay
7e91: 85 82 sta ]ltmp_82?
7e93: b9 00 b5 lda turn_map_lo?,y
7e96: 38 sec
7e97: a4 7e ldy ]scale_tab_val
7e99: f9 00 b5 sbc turn_map_lo?,y
7e9c: 85 90 sta ]z_spd_tmp
7e9e: a4 82 ldy ]ltmp_82?
7ea0: b9 00 b6 lda turn_map_hi?,y
7ea3: a4 7e ldy ]scale_tab_val
7ea5: f9 00 b6 sbc turn_map_hi?,y
7ea8: 85 91 sta ]z_spd_tmp+1
7eaa: 18 clc
7eab: a5 90 lda ]z_spd_tmp
7ead: 6d 51 6d adc max_z_spd_copy ;add maximum Z velocity allowed for this object
7eb0: 85 90 sta ]z_spd_tmp
7eb2: a5 91 lda ]z_spd_tmp+1
7eb4: 6d 52 6d adc max_z_spd_copy+1
7eb7: 85 91 sta ]z_spd_tmp+1
7eb9: a5 91 lda ]z_spd_tmp+1 ;get high byte
7ebb: 30 19 bmi :SetZero ;went negative, clamp to zero
7ebd: c9 08 cmp #$08 ;is it >= 8?
7ebf: 10 20 bpl :Gt8 ;yes, branch
7ec1: 18 clc
7ec2: 69 10 adc #>math_tab1_base?
7ec4: 85 13 sta ]table_ptr2+1
7ec6: a4 90 ldy ]z_spd_tmp
7ec8: b1 12 lda (]table_ptr2),y
7eca: 9d 49 6d sta tmp_xmove_lo,x
7ecd: a9 00 lda #$00
7ecf: 9d 4a 6d sta tmp_xmove_hi,x
7ed2: ea nop
7ed3: 4c 06 7f jmp L7F06
7ed6: a9 00 :SetZero lda #$00
7ed8: 9d 49 6d sta tmp_xmove_lo,x
7edb: 9d 4a 6d sta tmp_xmove_hi,x
7ede: 4c 06 7f jmp L7F06
7ee1: 38 :Gt8 sec
7ee2: e9 08 sbc #$08 ;reduce by 8
7ee4: 85 91 sta ]z_spd_tmp+1
7ee6: 18 clc
7ee7: 69 ad adc #>math_tab2_base?+$100
7ee9: 85 13 sta ]table_ptr2+1
7eeb: a4 90 ldy ]z_spd_tmp
7eed: b9 00 17 lda math_tab1_lastpg?,y
7ef0: a8 tay
7ef1: b1 12 lda (]table_ptr2),y
7ef3: a4 91 ldy ]z_spd_tmp+1
7ef5: 85 84 sta ]ltmp_84?
7ef7: 39 e7 00 and bit_mask_right8,y
7efa: 9d 4a 6d sta tmp_xmove_hi,x
7efd: a5 84 lda ]ltmp_84?
7eff: 39 ef 00 and bit_mask_left8,y
7f02: 9d 49 6d sta tmp_xmove_lo,x
7f05: ea nop
;
7f06: b4 87 L7F06 ldy ]left_coord+1,x
7f08: 30 12 bmi :IsPos
7f0a: 38 sec
7f0b: a9 00 lda #$00
7f0d: fd 49 6d sbc tmp_xmove_lo,x
7f10: 9d 49 6d sta tmp_xmove_lo,x
7f13: a9 00 lda #$00
7f15: fd 4a 6d sbc tmp_xmove_hi,x
7f18: 9d 4a 6d sta tmp_xmove_hi,x
7f1b: ea nop
7f1c: e0 04 :IsPos cpx #$04 ;are working on Z?
7f1e: d0 2b bne :NextCoord ;no, branch to skip this next part
; Modify Z velocity based on player speed.
7f20: a5 98 lda adj_fwd_speed ;get forward speed
7f22: 85 8e sta ]speed_abs
7f24: a5 99 lda adj_fwd_speed+1
7f26: 85 8f sta ]speed_abs+1
7f28: 06 8e asl ]speed_abs ;double it
7f2a: 26 8f rol ]speed_abs+1
7f2c: 18 clc
7f2d: bd 49 6d lda tmp_xmove_lo,x ;add doubled speed to movement (which is negative)
7f30: 65 8e adc ]speed_abs
7f32: bd 4a 6d lda tmp_xmove_hi,x
7f35: 65 8f adc ]speed_abs+1
7f37: 10 12 bpl :NextCoord ;it became positive, don't do this
7f39: 18 clc ;add (non-doubled) speed to Z movement
7f3a: bd 49 6d lda tmp_xmove_lo,x
7f3d: 65 98 adc adj_fwd_speed
7f3f: 9d 49 6d sta tmp_xmove_lo,x
7f42: bd 4a 6d lda tmp_xmove_hi,x
7f45: 65 99 adc adj_fwd_speed+1
7f47: 9d 4a 6d sta tmp_xmove_hi,x
7f4a: ea nop
7f4b: e8 :NextCoord inx ;advance to next coordinate
7f4c: e8 inx
7f4d: e0 06 cpx #$06 ;done yet?
7f4f: 10 03 bpl :All3Done ;yes, branch
7f51: 4c 5b 7e jmp :CoordLoop ;no, loop
; Copy results out to object data tables.
7f54: a6 62 :All3Done ldx cur_obj_index
7f56: ea nop
7f57: ad 49 6d lda tmp_xmove_lo
7f5a: 9d 60 9e sta obj_move_xc_lo,x
7f5d: ad 4a 6d lda tmp_xmove_hi
7f60: 9d 88 9e sta obj_move_xc_hi,x
7f63: ad 4b 6d lda tmp_ymove_lo
7f66: 9d b0 9e sta obj_move_yc_lo,x
7f69: ad 4c 6d lda tmp_ymove_hi
7f6c: 9d d8 9e sta obj_move_yc_hi,x
7f6f: ad 4d 6d lda tmp_zmove_lo
7f72: 9d 10 9e sta obj_move_zc_lo,x
7f75: ad 4e 6d lda tmp_zmove_hi
7f78: 9d 38 9e sta obj_move_zc_hi,x
7f7b: 20 7f 7f jsr Return7f7f
7f7e: 60 rts
;
; Debugging thing? Deleted sound routine?
;
7f7f: 60 Return7f7f rts
7f80: 60 00 7a 3a+ .junk 61
7fbd: 00 :saved_86 .dd1 $00
7fbe: 00 :saved_87 .dd1 $00
7fbf: 00 :saved_yreg .dd1 $00
7fc0: 00 :saved_xreg .dd1 $00
7fc1: 00 .junk 1
;
; Plays a musical sequence.
;
; $00: game-over music (not high score)
; $01: start game
; $02: enter time portal
; $03: (chirp) enemy base destroyed (either kind)
; $04: fly through friendly base
; $05: game-over music (high score)
; $06: exit time portal (max time)
; $07: (same as $03)
;
; Hitting a key exits the sequence early.
;
; On entry:
; A-reg: sequence number (0-7)
;
; On exit:
; X/Y-reg preserved
; $86-87 preserved
;
• Clear variables
]music_ptr .var $16 {addr/2}
]note0 .var $86 {addr/2}
]note1 .var $88 {addr/2}
]note2 .var $8a {addr/2}
]duration .var $8c {addr/2}
]rep_count .var $8f {addr/1}
]sound_num .var $91 {addr/1}
]count0 .var $aa {addr/2}
]count1 .var $ac {addr/2}
]count2 .var $ae {addr/2}
7fc2: 85 91 PlayMusicSeq sta ]sound_num
7fc4: a5 86 lda ]note0 ;preserve previous contents of $86-87
7fc6: 8d bd 7f sta :saved_86
7fc9: a5 87 lda ]note0+1
7fcb: 8d be 7f sta :saved_87
7fce: 8c bf 7f sty :saved_yreg ;preserve X/Y-reg
7fd1: 8e c0 7f stx :saved_xreg
7fd4: ac 48 6d ldy sound_disab_flag ;check whether sound is enabled
7fd7: f0 03 beq :SoundOn
7fd9: 4c 4f 80 jmp :Bail
7fdc: ac 10 c0 :SoundOn ldy KBDSTRB ;clear keyboard strobe
7fdf: a5 91 lda ]sound_num ;get sound number
7fe1: 29 07 and #$07 ;make sure it's 0-7
7fe3: 0a asl A
7fe4: a8 tay
7fe5: b9 02 40 lda music_offset,y ;get pointer to music
7fe8: 85 16 sta ]music_ptr
7fea: b9 03 40 lda music_offset+1,y
7fed: 18 clc
7fee: 69 40 adc #>DATA_AREA
7ff0: 85 17 sta ]music_ptr+1
7ff2: a0 00 ldy #$00 ;grab first two bytes, which affect how long
7ff4: b1 16 lda (]music_ptr),y ; each note is played
7ff6: 85 8c sta ]duration
7ff8: a0 01 ldy #$01
7ffa: b1 16 lda (]music_ptr),y
7ffc: 85 8d sta ]duration+1
7ffe: a9 00 lda #$00 ;initialize counters
8000: 85 aa sta ]count0
8002: 85 ab sta ]count0+1
8004: 85 ac sta ]count1
8006: 85 ad sta ]count1+1
8008: 85 ae sta ]count2
800a: 85 af sta ]count2+1
; Loop over all notes in sequence.
800c: a5 16 :MusicLoop lda ]music_ptr ;advance pointer 4 bytes
800e: 18 clc
800f: 69 04 adc #$04
8011: 85 16 sta ]music_ptr
8013: 90 02 bcc :NoInc
8015: e6 17 inc ]music_ptr+1
8017: a0 00 :NoInc ldy #$00 ;get first entry
8019: b1 16 lda (]music_ptr),y
801b: 0a asl A
801c: aa tax
801d: bd 12 40 lda note_values,x ;look up value from table
8020: 85 86 sta ]note0
8022: bd 13 40 lda note_values+1,x
8025: 85 87 sta ]note0+1
8027: a0 01 ldy #$01 ;get second entry
8029: b1 16 lda (]music_ptr),y
802b: 0a asl A
802c: aa tax
802d: bd 12 40 lda note_values,x ;look up value from table
8030: 85 88 sta ]note1
8032: bd 13 40 lda note_values+1,x
8035: 85 89 sta ]note1+1
8037: a0 02 ldy #$02 ;get third entry
8039: b1 16 lda (]music_ptr),y
803b: 0a asl A
803c: aa tax
803d: bd 12 40 lda note_values,x ;look up value from table
8040: 85 8a sta ]note2
8042: bd 13 40 lda note_values+1,x
8045: 85 8b sta ]note2+1
8047: a0 03 ldy #$03 ;get 4th entry
8049: b1 16 lda (]music_ptr),y
804b: 85 8f sta ]rep_count
804d: d0 11 bne :PlayNotes ;zero value here indicates end of list
804f: ad bd 7f :Bail lda :saved_86
8052: 85 86 sta ]note0
8054: ad be 7f lda :saved_87
8057: 85 87 sta ]note0+1
8059: ac bf 7f ldy :saved_yreg
805c: ae c0 7f ldx :saved_xreg
805f: 60 rts
]do_click .var $80 {addr/1}
]duration_counter .var $90 {addr/2}
8060: a5 8c :PlayNotes lda ]duration ;initialize global duration counter
8062: 85 90 sta ]duration_counter
8064: a5 8d lda ]duration+1
8066: 85 91 sta ]duration_counter+1
8068: 18 :PlayLoop clc
8069: a5 86 lda ]note0 ;advance counter #0
806b: 65 aa adc ]count0
806d: 85 aa sta ]count0
806f: a5 87 lda ]note0+1
8071: 65 ab adc ]count0+1
8073: 85 ab sta ]count0+1
8075: 10 35 bpl :Pos0 ;positive half, branch
8077: a5 86 lda ]note0 ;(pad timing?)
8079: 18 clc
807a: a5 88 lda ]note1 ;advance counter #1
807c: 65 ac adc ]count1
807e: 85 ac sta ]count1
8080: a5 89 lda ]note1+1
8082: 65 ad adc ]count1+1
8084: 85 ad sta ]count1+1
8086: 10 12 bpl :Pos1 ;positive half, branch
8088: 18 clc
8089: a5 8a lda ]note2 ;advance counter #2
808b: 65 ae adc ]count2
808d: 85 ae sta ]count2
808f: a5 8b lda ]note2+1
8091: 65 af adc ]count2+1
8093: 85 af sta ]count2+1
8095: a5 86 lda ]note0
8097: 4c cf 80 jmp :ClickIfOne_2
809a: 18 :Pos1 clc
809b: a5 8a lda ]note2 ;advance counter #2
809d: 65 ae adc ]count2
809f: 85 ae sta ]count2
80a1: a5 8b lda ]note2+1
80a3: 65 af adc ]count2+1
80a5: 85 af sta ]count2+1
80a7: 30 25 bmi :ClickIfOne_1 ;negative half, click if 1
80a9: 4c e4 80 jmp :ClickIfZero
80ac: ea :Pos0 nop
80ad: 18 clc
80ae: a5 88 lda ]note1 ;advance counter #1
80b0: 65 ac adc ]count1
80b2: 85 ac sta ]count1
80b4: a5 89 lda ]note1+1
80b6: 65 ad adc ]count1+1
80b8: 85 ad sta ]count1+1
80ba: 30 de bmi :Pos1 ;negative half, branch
80bc: 18 clc
80bd: a5 8a lda ]note2
80bf: 65 ae adc ]count2
80c1: 85 ae sta ]count2
80c3: a5 8b lda ]note2+1
80c5: 65 af adc ]count2+1
80c7: 85 af sta ]count2+1
80c9: a5 86 lda ]note0 ;(padding?)
80cb: 4c e4 80 jmp :ClickIfZero
80ce: ea :ClickIfOne_1 nop
80cf: a5 80 :ClickIfOne_2 lda ]do_click
80d1: f0 0a beq :NotOne
80d3: a9 00 lda #$00
80d5: 85 80 sta ]do_click
80d7: ad 30 c0 lda SPKR ;click
80da: 4c f9 80 jmp :LoopBottom
80dd: ea :NotOne nop ;pad for timing
80de: ea nop
80df: ea nop
80e0: ea nop
80e1: 4c f9 80 jmp :LoopBottom
80e4: a5 80 :ClickIfZero lda ]do_click
80e6: d0 0a bne :NotZero
80e8: a9 01 lda #$01
80ea: 85 80 sta ]do_click
80ec: ad 30 c0 lda SPKR ;click
80ef: 4c f9 80 jmp :LoopBottom
80f2: ea :NotZero nop
80f3: ea nop
80f4: ea nop
80f5: ea nop
80f6: 4c f9 80 jmp :LoopBottom
80f9: 38 :LoopBottom sec ;decrement counter
80fa: a5 90 lda ]duration_counter
80fc: e9 01 sbc #$01
80fe: 85 90 sta ]duration_counter
8100: a5 91 lda ]duration_counter+1
8102: e9 00 sbc #$00 ;use SBC so cycle count is consistent
8104: 85 91 sta ]duration_counter+1
8106: 30 12 bmi :DurationExp
8108: ea nop
8109: ea nop
810a: ea nop
810b: ea nop
810c: ea nop
810d: ad 00 c0 lda KBD ;check for player interrupting music
8110: 10 03 bpl :Cont ;not yet, branch
8112: 4c 4f 80 jmp :Bail ;yes, stop now (note: kbd strobe not cleared)
]vestigial_8e? .var $8e {addr/1}
8115: a5 8e :Cont lda ]vestigial_8e? ;(?)
8117: 4c 68 80 jmp :PlayLoop
811a: c6 8f :DurationExp dec ]rep_count ;decrement per-note repetition counter
811c: f0 03 beq :NextNote ;if we hit zero, move on to next note
811e: 4c 60 80 jmp :PlayNotes ;otherwise, keep playing this one
8121: 4c 0c 80 :NextNote jmp :MusicLoop
8124: cc .junk 1
8125: 96 high_code_page .dd1 $96
8126: 00 3d 3d 3d+ .junk 13
;
; Game entry point.
;
; We also jump here when R/Ctrl+R is hit.
;
8133: ad 10 c0 Start lda KBDSTRB ;clear keyboard
8136: a9 00 lda #$00
8138: 8d 3b 6d sta game_active_flag
813b: 8d 3c 6d sta wronly_6d3c
813e: 8d 3d 6d sta rng_update_flag
8141: 8d 3f 6d sta end_game_msg_ctr
8144: 8d 40 6d sta end_game_msg_ctr+1
; Jump here when starting a new game, after playing the start-new-game music.
8147: a2 13 InitGame ldx #$13
8149: bd d7 6d :CopyLoop lda initial_loadout,x ;set initial values for resources
814c: 9d bd 6d sta resource_state,x ; time, fuel, amun (multi-byte BCD)
814f: ca dex
8150: 10 f7 bpl :CopyLoop
; Init $6d49-6dbb to zero.
8152: a9 00 lda #$00
8154: a2 72 ldx #$72
8156: 9d 49 6d :ZLoop1 sta tmp_xmove_lo,x
8159: ca dex
815a: 10 fa bpl :ZLoop1
;
; Reset a few things. Various places jump here when the state of the world
; appears to be screwed up.
;
• Clear variables
]zero .var $00 {addr/1}
815c: a2 c0 PartialRestart ldx #$c0
815e: 9a txs ;init stack pointer
815f: ad 50 c0 lda TXTCLR ;enable graphics
8162: ad 52 c0 lda MIXCLR ;disable mixed-mode
8165: ad 57 c0 lda HIRES ;enable hi-res graphics
8168: ad 54 c0 lda TXTPAGE1 ;enable page 1
816b: 20 7f 7f jsr Return7f7f
; Init $60-d1 to zero.
816e: a9 00 lda #$00
8170: a2 60 ldx #$60
8172: 95 00 :ZLoop2 sta ]zero,x
8174: e8 inx
8175: e0 d2 cpx #$d2
8177: d0 f9 bne :ZLoop2
; Init a few variables.
8179: a9 00 lda #$00
817b: 85 10 sta ptr_10 ;set low bytes of these pointers
817d: 85 12 sta math_tab_ptr12
817f: 85 14 sta math_tab_ptr14
8181: 8d ae 6d sta portal_bound_limit ;init these to zero
8184: 8d af 6d sta portal_bound_limit+1
8187: 8d b0 6d sta wronly_6db0?
818a: 8d 43 6d sta game_over_music
; Init hi-res page 1 ($2000-3fff), text page 1 ($0400-07ff), and storage from
; $9700-a5ff to zero.
818d: a2 20 ldx #$20 ;start page
818f: a0 40 ldy #$40 ;end page
8191: a9 00 lda #$00 ;value
8193: 20 c5 7c jsr Jmp_Memset ;set $2000-3fff to $00
8196: a9 00 lda #$00 ;value
8198: a2 04 ldx #$04 ;start page
819a: a0 08 ldy #$08 ;end page
819c: 20 c5 7c jsr Jmp_Memset ;set $0400-07ff to $00
819f: ae 25 81 ldx high_code_page ;#$96
81a2: e8 inx
81a3: a0 a6 ldy #$a6
81a5: a9 00 lda #$00
81a7: 20 c5 7c jsr Jmp_Memset ;set $9700-a5ff to $00
;
81aa: a2 13 ldx #$13 ;(?)
81ac: a9 ef lda #$ef ;set object index trackers to "no value"
81ae: 85 6a sta head_obj_index
81b0: 85 6c sta head_enemy_obj_index
81b2: 8d 62 6d sta region_progress_ctr+1 ;init value; gets replaced later
81b5: a9 28 lda #40
81b7: 85 6d sta free_obj_count ;room for 40 objects
81b9: a9 40 lda #64
81bb: 85 6e sta free_elem_count ;room for 64 elements
81bd: 20 7f 7f jsr Return7f7f
; Init $9a50-9a76 to ascending values $01-27, then set $9a77 to $ed.
; Init $9a00-9a26 to $f7, then set $9a27 to $ed.
81c0: a2 00 ldx #$00
81c2: a0 01 ldy #$01
81c4: 98 :ObjLoop tya
81c5: 9d 50 9a sta obj_next_obj,x
81c8: a9 f7 lda #$f7
81ca: 9d 00 9a sta obj_first_elem_index,x
81cd: c8 iny
81ce: e8 inx
81cf: e0 27 cpx #39
81d1: d0 f1 bne :ObjLoop
81d3: a9 ed lda #$ed
81d5: 9d 50 9a sta obj_next_obj,x ;last entry gets end-of-list marker
81d8: 9d 00 9a sta obj_first_elem_index,x
81db: 20 7f 7f jsr Return7f7f
; Init $9f40-9f7e to ascending values $01-3f, then set $9f7f to $ec.
; Init $9f00-9f3e to $f6, then set $9f3f to $ec.
81de: a2 00 ldx #$00
81e0: a0 01 ldy #$01
81e2: 98 :ElemLoop tya
81e3: 9d 40 9f sta elem_next_elem,x ;set "next" index to slot number + 1
81e6: a9 f6 lda #$f6
81e8: 9d 00 9f sta elem_obj_index,x
81eb: c8 iny
81ec: e8 inx
81ed: e0 3f cpx #$3f
81ef: d0 f1 bne :ElemLoop
81f1: a9 ec lda #$ec
81f3: 9d 40 9f sta elem_next_elem,x ;mark the end of the list
81f6: 9d 00 9f sta elem_obj_index,x
81f9: 20 7f 7f jsr Return7f7f
;
• Clear variables
]bcd_byte_cnt1 .var $86 {addr/1}
]bcd_byte_cnt2 .var $8a {addr/1}
81fc: 20 80 5a MainLoop jsr DrawCrosshairs
81ff: 4c 23 82 jmp :MainLoop1
8202: ba 85 16 bd+ .junk 33
8223: ee cd 6d :MainLoop1 inc frame_counter ;increment the counter used for pacing
8226: a2 24 ldx #$24
8228: a0 0e ldy #$0e
822a: a9 02 lda #$02
822c: 85 86 sta ]bcd_byte_cnt1 ;2-byte value
822e: 20 65 73 jsr DrawStatusNum ;draw current speed
8231: ad 63 6d lda space_region ;get region
8234: c9 03 cmp #$03 ;are we flying through a time portal?
8236: d0 2e bne :NoTimeIncr ;no, branch
8238: ad 98 6d lda time_portal_fail_ctr ;are we *successfully* flying through a time portal?
823b: d0 29 bne :NoTimeIncr ;no, branch
; Flying through the middle of a time portal. Update time.
823d: ad cd 6d lda frame_counter ;get frame counter
8240: 29 01 and #$01 ;check odd/even frame
8242: d0 22 bne :NoTimeIncr ;odd, skip this next bit
8244: a9 02 lda #$02
8246: 85 8a sta ]bcd_byte_cnt2 ;update two-byte (4-digit) number
8248: ad cb 6d lda cur_speed+1 ;get high BCD byte of speed
824b: 8d f9 70 sta time_portal_rate ;use as low byte of increase
824e: a9 00 lda #$00
8250: 8d fa 70 sta time_portal_rate+1 ;set high byte of increase to zero
8253: a0 13 ldy #$13
8255: a2 05 ldx #$05
8257: 20 a0 7c jsr IncreaseResource ;increase time
825a: a9 02 lda #$02
825c: 85 86 sta ]bcd_byte_cnt1 ;draw two-byte (4-digit) number
825e: a2 0f ldx #$0f
8260: a0 06 ldy #$06
8262: 20 65 73 jsr DrawStatusNum ;draw time
8265: ea nop
; 6-frame cycle: 0-4 draw resource count, 5 reduce time, advance progress in
; region, and fall through to draw resource #0.
8266: ee 42 6d :NoTimeIncr inc rsrc_draw_index
8269: ad 42 6d lda rsrc_draw_index ;get index
826c: c9 05 cmp #$05 ;< 5?
826e: 30 51 bmi :DrawRsrc ;yes, draw a thing
8270: a9 00 lda #$00
8272: 8d 42 6d sta rsrc_draw_index ;reset index
8275: 20 7f 7f jsr Return7f7f
8278: a9 02 lda #$02
827a: 85 8a sta ]bcd_byte_cnt2 ;2-byte value
827c: a2 05 ldx #$05
827e: a0 0f ldy #$0f
8280: 20 68 7c jsr ReduceResource ;update time remaining
• Clear variables
]prog_factor .var $86 {addr/1}
8283: a9 0e lda #$0e ;default to 14
8285: 85 86 sta ]prog_factor
8287: ad 3b 6d lda game_active_flag ;are we showing the demo?
828a: f0 21 beq :GotFactor ;yes, branch
828c: ad 63 6d lda space_region ;get region
828f: c9 03 cmp #$03 ;inside a time portal?
8291: f0 1a beq :GotFactor ;yes, branch (not speed-dependent inside portal)
8293: a9 09 lda #$09 ;reduce to 9
8295: 85 86 sta ]prog_factor
8297: ad cb 6d lda cur_speed+1 ;check speed
829a: c9 05 cmp #$05 ;at least 500?
829c: 90 0f bcc :GotFactor ;no, branch
829e: a9 10 lda #$10 ;increase to 16
82a0: 85 86 sta ]prog_factor
82a2: ad cb 6d lda cur_speed+1 ;check speed again
82a5: c9 10 cmp #$10 ;at least 1000?
82a7: 90 04 bcc :GotFactor ;no, branch
82a9: a9 20 lda #$20 ;increase to 32
82ab: 85 86 sta ]prog_factor
82ad: 38 :GotFactor sec
82ae: ad 61 6d lda region_progress_ctr
82b1: e5 86 sbc ]prog_factor
82b3: 8d 61 6d sta region_progress_ctr
82b6: b0 03 bcs :NoDec
82b8: ce 62 6d dec region_progress_ctr+1
]bcd_byte_cnt .var $86 {addr/1}
82bb: a9 03 :NoDec lda #$03
82bd: 85 86 sta ]bcd_byte_cnt ;score is 3 bytes (6 digits)
82bf: a9 00 lda #$00 ;draw score
82c1: c9 04 :DrawRsrc cmp #$04 ;is index up to 4?
82c3: d0 06 bne :Not4 ;no, leave BCD byte count alone (== 2)
82c5: a9 03 lda #$03 ;yes, high scores are also 3 bytes
82c7: 85 86 sta ]bcd_byte_cnt
82c9: a9 04 lda #$04 ;draw #4 (high score)
82cb: a8 :Not4 tay
82cc: be dc 70 ldx rsrc_print_col,y ;get screen column (0-39)
82cf: b9 e1 70 lda status_val_index,y ;get storage index of item
82d2: a8 tay
82d3: 20 65 73 jsr DrawStatusNum ;draw it
82d6: ea nop
; Handle keyboard input. This part is handled for the demo as well.
82d7: ad 00 c0 lda KBD ;read keyboard
82da: 10 36 bpl :Jmp_83a2 ;no key hit, bail
82dc: c9 d6 cmp #“V”
82de: d0 0e bne :NotV
82e0: ad 10 c0 lda KBDSTRB ;clear keyboard strobe
82e3: ad 47 6d lda vert_axis_mod
82e6: 49 ff eor #$ff ;flip vertical joystick axis
82e8: 8d 47 6d sta vert_axis_mod
82eb: 4c fd 82 jmp :SetAxisChar
82ee: c9 c8 :NotV cmp #“H” ;is it 'H'?
82f0: d0 23 bne :NotH ;no, branch
82f2: ad 10 c0 lda KBDSTRB ;clear keyboard strobe
82f5: ad 44 6d lda horiz_axis_mod
82f8: 49 ff eor #$ff ;flip horizontal joystick axis
82fa: 8d 44 6d sta horiz_axis_mod
]joy_axis_adj .var $86 {addr/1}
82fd: ad 44 6d :SetAxisChar lda horiz_axis_mod ;00/ff
8300: 29 01 and #$01 ;00/01
8302: 85 86 sta ]joy_axis_adj
8304: ad 47 6d lda vert_axis_mod ;00/ff
8307: 29 02 and #$02 ;00/02
8309: 05 86 ora ]joy_axis_adj
830b: a8 tay ;0/1/2/3
830c: b9 45 73 lda axis_flip_chars,y ;get char ('H', 'V', etc)
830f: 8d a5 6e sta text_axis_status ;set in status bar
8312: 4c a2 83 :Jmp_83a2 jmp :GetInput1
8315: c9 93 :NotH cmp #$93 ;Ctrl+S?
8317: f0 04 beq :ToggleSound
8319: c9 d3 cmp #“S” ;plain 'S' (same effect, not documented)?
831b: d0 1a bne :NotS ;no, continue
831d: a9 20 :ToggleSound lda #$20
831f: 8d 85 6e sta text_score_time ;set sound-enabled to "on" for now
8322: ad 48 6d lda sound_disab_flag
8325: 49 01 eor #$01 ;toggle sound flag (00/01)
8327: 8d 48 6d sta sound_disab_flag
832a: f0 05 beq :SoundEnabled
832c: a9 53 lda #‘S’
832e: 8d 85 6e sta text_score_time ;update text at top of screen to show sound disabled
8331: ad 10 c0 :SoundEnabled lda KBDSTRB ;clear keyboard
8334: 4c a2 83 jmp :GetInput1
8337: 29 7f :NotS and #$7f
8339: c9 31 cmp #‘1’ ;check for 1-5
833b: 30 15 bmi :NotDigit
833d: c9 36 cmp #‘6’
833f: b0 11 bcs :NotDigit ;nope, continue
8341: 8d a6 6e sta text_joy_sens ;set value for display
8344: 29 07 and #$07 ;convert ['1','5'] to [1,5]
8346: 18 clc
8347: 69 f9 adc #$f9 ;now [$fa,$fe]
8349: 8d c2 71 sta joystick_sens_mod+1
834c: ad 10 c0 lda KBDSTRB
834f: 4c a2 83 jmp :GetInput1
; Check for "NOTICE" key sequence.
8352: 38 :NotDigit sec
8353: e9 40 sbc #$40
8355: ac e0 6e ldy secret_key_index
8358: d9 e1 6e cmp secret_key_seq,y
835b: f0 08 beq :NoticeMatch
835d: a9 00 lda #$00 ;didn't match, reset sequence
835f: 8d e0 6e sta secret_key_index
8362: 4c a2 83 jmp :GetInput1
; Matched, show secret copyright message.
8365: ee e0 6e :NoticeMatch inc secret_key_index
8368: ad 10 c0 lda KBDSTRB ;clear keyboard strobe
836b: ad e0 6e lda secret_key_index ;get index
836e: c9 06 cmp #$06 ;all 5 chars typed?
8370: 30 30 bmi :GetInput1 ;not yet
8372: a0 27 :PrintCopyright ldy #39 ;copy 40 bytes
8374: b9 33 72 :SecCopyrLoop lda secret_copyright,y
8377: 18 clc
8378: 69 20 adc #$20 ;"decode" character
837a: 99 80 0f sta copyright_msg,y
837d: 88 dey
837e: 10 f4 bpl :SecCopyrLoop
8380: ad 50 c0 lda TXTCLR ;enable graphics
8383: ad 57 c0 lda HIRES ;enable hi-res graphics
8386: ad 54 c0 lda TXTPAGE1 ;enable page 1
]counter .var $8c {addr/1}
8389: a2 00 ldx #$00
838b: a9 00 lda #$00
838d: 85 8c sta ]counter
838f: a4 8c :PrintCopyrLoop ldy ]counter
8391: b9 80 0f lda copyright_msg,y
8394: 20 95 74 jsr PrintCharLine32
8397: e6 8c inc ]counter
8399: e0 24 cpx #36 ;print 35 bytes
839b: ea nop
839c: 30 f1 bmi :PrintCopyrLoop
839e: ea nop
839f: 4c 72 83 jmp :PrintCopyright ;loop forever
83a2: ad 3b 6d :GetInput1 lda game_active_flag ;currently playing game?
83a5: f0 03 beq :NotPlaying ;no, branch
83a7: 4c 05 84 jmp CheckRestart ;yes, go read the joystick and check other keys
; Read inputs while showing the title demo.
83aa: ad 00 c0 :NotPlaying lda KBD ;read keyboard
83ad: 10 23 bpl :NoSpc ;no key hit, branch
83af: 29 7f and #%01111111 ;strip high bit
83b1: c9 20 cmp #‘ ’ ;was it spacebar?
83b3: d0 1d bne :NoSpc ;no, keep going
83b5: ad 10 c0 lda KBDSTRB ;clear keyboard strobe
83b8: a9 04 lda #$04
83ba: 8d 3c 6d sta wronly_6d3c ;set useless thing to $04
83bd: a9 ff lda #$ff
83bf: 8d 3b 6d sta game_active_flag ;now playing game
83c2: 8d 3c 6d sta wronly_6d3c ;set useless thing to $ff
83c5: a9 01 lda #$01
83c7: 20 c2 7f jsr PlayMusicSeq ;play "start game" music
83ca: a9 01 lda #$01 ;(?)
83cc: 20 f4 0f jsr Return0ff4
83cf: 4c 47 81 jmp InitGame ;start the game
83d2: a9 d0 :NoSpc lda #$d0 ;set a bunch of DP values
83d4: 85 9b sta joy_yaw_angle+1
83d6: 85 9e sta joy_pitch_angle+1
83d8: a9 00 lda #$00
83da: 85 9c sta joy_yaw_sign ;zero all this stuff out
83dc: 85 9f sta joy_pitch_sign ;(all of these get zeroed out when we start a new
83de: 85 9a sta joy_yaw_angle ; game, not sure why we do it here)
83e0: 85 9d sta joy_pitch_angle
83e2: 85 ce sta portal_next_xc
83e4: 85 cf sta portal_next_xc+1
83e6: 85 d0 sta portal_next_yc
83e8: 85 d1 sta portal_next_yc+1
83ea: 8d aa 6d sta joystick_x_mag
83ed: 8d ad 6d sta joystick_y_mag
83f0: ad cf 6c lda rng_state1+7 ;perturb RNG state
83f3: 18 clc
83f4: 69 52 adc #$52
83f6: 8d cf 6c sta rng_state1+7
83f9: ee 10 6d inc rng_state2+17
83fc: 20 b0 7b jsr GenRandom
83ff: 20 7f 7f jsr Return7f7f
8402: 4c d0 84 jmp ReadJoystick ;go read the joystick (for RNG state update?)
;
; Check for restart key sequence and game-over conditions.
;
8405: ad 00 c0 CheckRestart lda KBD
8408: c9 d2 cmp #“R” ;'R' hit (seems dangerous)?
840a: f0 04 beq :DoReset
840c: c9 92 cmp #$92 ;Ctrl+R
840e: d0 06 bne :NotR
8410: ad 10 c0 :DoReset lda KBDSTRB ;clear keyboard strobe
8413: 4c 33 81 jmp Start ;restart game
; Check end-game conditions.
8416: ad c2 6d :NotR lda time_left
8419: 0d c3 6d ora time_left+1
841c: d0 05 bne :HaveTime
841e: a9 00 lda #$00 ;cause = no time
8420: 4c 3d 84 jmp GameOver
8423: ad c5 6d :HaveTime lda fuel_left
8426: 0d c6 6d ora fuel_left+1
8429: d0 08 bne :HaveFuel
842b: a9 04 lda #$04 ;cause = no fuel
842d: 4c 3d 84 jmp GameOver
8430: 4c d0 84 :HaveAmun jmp ReadJoystick
]score_rating .var $91 {addr/1}
8433: ad c8 6d :HaveFuel lda amun_left
8436: 0d c9 6d ora amun_left+1
8439: d0 f5 bne :HaveAmun
;
; We ran out of time/fuel/amun, game is over.
;
843b: a9 08 lda #$08 ;cause = no amun
843d: 85 b5 GameOver sta end_game_cause
; Determine rating, based on score.
843f: a9 04 lda #$04 ;init rating to 4 (max)
8441: 85 91 sta ]score_rating
8443: a0 09 ldy #$09
8445: ea :RatingLoop nop
8446: f8 sed
8447: ad be 6d lda cur_score
844a: d9 e6 70 cmp rating_thresholds,y
844d: ad bf 6d lda cur_score+1
8450: f9 e7 70 sbc rating_thresholds+1,y
8453: ad c0 6d lda cur_score+2
8456: f9 e8 70 sbc rating_thresholds+2,y
8459: d8 cld
845a: 10 08 bpl :GotRating
845c: c6 91 dec ]score_rating
845e: 88 dey
845f: 88 dey
8460: 88 dey
8461: 10 e2 bpl :RatingLoop
8463: ea nop
8464: a5 91 :GotRating lda ]score_rating ;get rating
8466: 0a asl A ;16 chars per rating string
8467: 0a asl A
8468: 0a asl A
8469: 0a asl A
846a: 85 b6 sta score_rating_index
;
846c: ad 10 c0 lda KBDSTRB ;clear keyboard strobe
846f: a9 00 lda #$00
8471: 8d 3b 6d sta game_active_flag ;clear "playing game" flag
8474: a9 02 lda #$02
8476: 8d cd 6d sta frame_counter
; Zero out $9a-9f and $c8-cd.
8479: a2 05 ldx #$05
847b: a9 00 lda #$00
847d: 95 9a :ZeroDpLoop sta joy_yaw_angle,x
847f: 95 c8 sta sound_counters,x
8481: ca dex
8482: 10 f9 bpl :ZeroDpLoop
8484: a9 01 lda #$01 ;set to $0104
8486: 8d 40 6d sta end_game_msg_ctr+1
8489: a9 04 lda #$04
848b: 8d 3f 6d sta end_game_msg_ctr
848e: a9 02 lda #$02 ;change it to $0180
8490: 8d 40 6d sta end_game_msg_ctr+1
8493: a9 80 lda #$80
8495: 8d 3f 6d sta end_game_msg_ctr
8498: a9 01 lda #$01
849a: 8d 43 6d sta game_over_music
; Compare high score to current score.
849d: f8 sed
849e: ad d1 6d lda high_score
84a1: cd be 6d cmp cur_score
84a4: ad d2 6d lda high_score+1
84a7: ed bf 6d sbc cur_score+1
84aa: ad d3 6d lda high_score+2
84ad: ed c0 6d sbc cur_score+2
84b0: b0 17 bcs :NotHighScore
84b2: ad be 6d lda cur_score
84b5: 8d d1 6d sta high_score
84b8: ad bf 6d lda cur_score+1
84bb: 8d d2 6d sta high_score+1
84be: ad c0 6d lda cur_score+2
84c1: 8d d3 6d sta high_score+2
84c4: a9 05 lda #$05
84c6: 8d 43 6d sta game_over_music ;play full fanfare
84c9: d8 :NotHighScore cld
84ca: 20 7f 7f jsr Return7f7f
84cd: 4c fc 81 jmp MainLoop
;
; Reads the joystick after checking for the pause key.
;
; We do this whether or not we're playing a game.
;
• Clear variables
]rng_limit_mode .var $88 {addr/1}
]pdl0 .var $8a {addr/1}
]pdl1 .var $8d {addr/1}
]counter .var $8e {addr/1}
84d0: a9 00 ReadJoystick lda #$00
84d2: 8d 5f 6d sta fuel_this_frame ;init fuel consumption
84d5: 85 14 sta math_tab_ptr14 ;set low byte of pointers to zero
84d7: 85 12 sta math_tab_ptr12
84d9: 85 10 sta ptr_10
84db: ad 00 c0 lda KBD ;check keyboard
84de: c9 9b cmp #$9b ;ESC?
84e0: d0 0e bne DoReadJoystick
; Pause mode. Wait for key.
84e2: ad 10 c0 lda KBDSTRB ;clear keyboard strobe
84e5: ad 00 c0 :PauseLoop lda KBD ;check for key hit
84e8: 10 fb bpl :PauseLoop ;nothing hit, loop
84ea: ad 10 c0 lda KBDSTRB ;clear keyboard strobe
84ed: 20 7f 7f jsr Return7f7f
;
; Read both joystick axes.
;
; Paddles are normally read in an 11-cycle loop, so reading 0-255 requires 2816
; cycles. This routine requires 15 cycles per loop, theoretically yielding a
; value from 0-187 in the same time frame for an ideal joystick. (In practice,
; it will be able to read a bit higher because the capacitor may continue to
; charge past the point where the routine times out.)
;
; We need to adjust the center point. In theory this should be (256-188)/2=34,
; but the code here biases the result by +50. Under AppleWin's mouse emulation
; I see 50-243 (0-193 unadjusted). When PDL(n) is reporting 127 this code
; returns 138, suggesting that the correct adjustment is actually +39. However,
; the code that handles movement uses 152 ($98) as the center point, so the
; adjustment here should actually be +64 (confirmed in AppleWin).
;
; This implementation offers better resolution than the 22-cycle variants, but
; stretches the timing when one paddle finishes.
;
; (For reference, PADDL0/PADDL1 become positive (<$80) when their capacitors
; have recharged.)
;
84f0: ad 70 c0 DoReadJoystick lda PTRIG ;trigger paddle discharge
84f3: a0 32 ldy #50 ;offset by +50
84f5: ad 64 c0 :ReadBothLoop lda PADDL0 ;4 (15 cycles/loop)
84f8: 2d 65 c0 and PADDL1 ;4
84fb: 10 0a bpl :OneDone ;2 one or both are done, branch
84fd: c8 iny ;2
84fe: d0 f5 bne :ReadBothLoop ;3 exit if we wrap around to zero
8500: 88 dey ;both paddles done; decr to 255
8501: 84 8a sty ]pdl0 ;save paddle 0 value
8503: ea nop
8504: 4c 2e 85 jmp :BothDone
8507: ad 64 c0 :OneDone lda PADDL0 ;is paddle 0 done?
850a: 10 14 bpl :P0Done ;yes, branch
850c: 84 8d sty ]pdl1 ;no, paddle 1 is done; save it
850e: ad 64 c0 :P0OnlyLoop lda PADDL0 ;read paddle 0
8511: 2d 64 c0 and PADDL0 ;4-cycle nop to balance timing
8514: 10 04 bpl :BothDone
8516: c8 iny
8517: d0 f5 bne :P0OnlyLoop
8519: 88 dey ;decrement to 255
851a: 84 8a :BothDone sty ]pdl0
851c: ea nop
851d: 4c 30 85 jmp :JoystickDone
8520: 84 8a :P0Done sty ]pdl0 ;save paddle 0 value
8522: ad 65 c0 :P1OnlyLoop lda PADDL1 ;read paddle 1
8525: 2d 65 c0 and PADDL1 ;4-cycle nop to balance timing
8528: 10 04 bpl :BothDone
852a: c8 iny
852b: d0 f5 bne :P1OnlyLoop
852d: 88 dey ;decrement to 255
852e: 84 8d :BothDone sty ]pdl1 ;save paddle 1 value
; Got joystick reading.
8530: 98 :JoystickDone tya
8531: 65 b2 adc engine_sound_ctr?+1
8533: 85 b2 sta engine_sound_ctr?+1
8535: 90 0f bcc :NoSound
8537: e6 b3 inc engine_sound_ctr?+2
8539: a5 cc lda engine_sound_enable
853b: f0 09 beq :NoSound
853d: a5 b3 lda engine_sound_ctr?+2
853f: 25 b1 and engine_sound_ctr?
8541: d0 03 bne :NoSound
8543: ad 30 c0 lda SPKR
8546: 20 7f 7f :NoSound jsr Return7f7f
8549: ad 3b 6d lda game_active_flag ;are we showing the demo?
854c: d0 3e bne SetTurnRate ;no, branch
; Add entropy to the RNG by pulling in the joystick and button values. This is
; fairly ineffective, since a self-centering joystick will tend to return the
; same values, and the "floating bus" effect will likely result in both buttons
; returning the same value (unless one is pressed, which gets you one bit).
854e: ad 3d 6d lda rng_update_flag ;is update flag clear?
8551: d0 36 bne :Bail ;no, bail
8553: ee 3d 6d inc rng_update_flag ;yes, inc so we don't do this again
8556: a5 8a lda ]pdl0 ;perturb RNG state with joystick values
8558: 0a asl A
8559: ea nop
855a: 4d d9 6c eor rng_state1+17
855d: 8d d9 6c sta rng_state1+17
8560: a5 8d lda ]pdl1
8562: 0a asl A
8563: 4d da 6c eor rng_state1+18
8566: 8d da 6c sta rng_state1+18
8569: ea nop
856a: a9 ff lda #$ff
856c: 85 88 sta ]rng_limit_mode ;no limit on result
856e: 85 8e sta ]counter
8570: 20 b0 7b :SpinLoop jsr GenRandom
8573: 20 b0 7b jsr GenRandom
8576: ad 62 c0 lda BUTN1 ;perturb RNG state with button values
8579: 4d 61 c0 eor BUTN0 ;(this will most likely evaluate to $00)
857c: 0a asl A
857d: 4d db 6c eor rng_state1+19
8580: 8d db 6c sta rng_state1+19
8583: c6 8e dec ]counter
8585: a5 8e lda ]counter
8587: d0 e7 bne :SpinLoop
8589: 4c 6f 89 :Bail jmp UpdateRegion
858c: a0 03 SetTurnRate ldy #$03 ;start with vertical axis
858e: b9 44 6d :Loop lda horiz_axis_mod,y ;get axis modifier ($00/$ff)
8591: 49 ff eor #$ff ;invert
8593: 99 9c 00 sta joy_yaw_sign,y ;store in $9c/$9f
8596: 99 9c 00 sta joy_yaw_sign,y ;(?)
8599: b9 8a 00 lda tmp_8a,y ;get paddle read value ($8a/$8d)
859c: 38 sec
859d: e9 98 sbc #$98 ;use $98 (152) as center point
859f: 10 0d bpl :IsPos
85a1: aa tax ;preserve value in X-reg
85a2: b9 9c 00 lda joy_yaw_sign,y ;joystick left/up (negative), invert sign
85a5: 49 ff eor #$ff
85a7: 99 9c 00 sta joy_yaw_sign,y
85aa: 8a txa ;restore value
85ab: 49 ff eor #$ff ;invert it
85ad: ea nop
85ae: aa :IsPos tax ;copy magnitude to X-reg
85af: 99 aa 6d sta joystick_x_mag,y ;store for some odd uses
85b2: c9 08 cmp #$08 ;is magnitude < 8?
85b4: 90 03 bcc :SlowTurn ;yes, turning slowly; branch
85b6: ee 5f 6d inc fuel_this_frame ;turning quickly, burn more fuel
85b9: 18 :SlowTurn clc
85ba: bd 00 b5 lda turn_map_lo?,x ;convert magnitude to 16-bit turn angle
85bd: 6d c1 71 adc joystick_sens_mod ;reduce by joystick sensitivity setting ($ff)
85c0: 99 9a 00 sta joy_yaw_angle,y ;set the pitch or yaw rate
85c3: bd 00 b6 lda turn_map_hi?,x
85c6: 6d c2 71 adc joystick_sens_mod+1 ;add value in range [$fa,$fe], or [-6,-2], which
85c9: 99 9b 00 sta joy_yaw_angle+1,y ; reduces movement and widens center zone
85cc: e0 00 cpx #$00 ;is the joystick axis centered?
85ce: d0 09 bne :NoSub ;no, branch
85d0: b9 9b 00 lda joy_yaw_angle+1,y ;yes, modify movement rate
85d3: 38 sec
85d4: e9 0c sbc #$0c ;subtract 12 (ensures that object updater
85d6: 99 9b 00 sta joy_yaw_angle+1,y ; recognizes that we're not moving)
; Do some peculiar things with state that nothing reads. Perturb the RNG state.
85d9: b9 9c 00 :NoSub lda joy_yaw_sign,y
85dc: 99 9c 6d sta wronly_6d9b?+1,y
85df: 59 aa 6d eor joystick_x_mag,y
85e2: 99 9b 6d sta wronly_6d9b?,y
85e5: 0a asl A
85e6: 18 clc
85e7: 79 cb 6c adc rng_state1+3,y
85ea: 99 cb 6c sta rng_state1+3,y
85ed: 98 tya
85ee: aa tax
85ef: 1e 9b 6d asl wronly_6d9b?,x ;shift 16-bit value left, twice
85f2: 3e 9c 6d rol wronly_6d9b?+1,x
85f5: 1e 9b 6d asl wronly_6d9b?,x
85f8: 3e 9c 6d rol wronly_6d9b?+1,x
; Advance to the other axis.
85fb: 88 dey
85fc: 88 dey
85fd: ea nop
85fe: 88 dey ;now Y-reg=0 or -3
85ff: 10 8d bpl :Loop
8601: 20 7f 7f jsr Return7f7f
;
; Check to see if both buttons are down, or the space bar is hit. If so, fire a
; shot.
;
; If the buttons are held down, we pace the shots more slowly than we would if
; the player were pressing the button or spacebar rapidly. If you hit the space
; bar too rapidly, attempting to fire every frame, the game will throttle your
; shots. If you time it so the space bar is hit on alternate frames, you will
; fire as quickly as possible.
;
8604: ad 61 c0 lda BUTN0 ;are both buttons down?
8607: 2d 62 c0 and BUTN1
860a: a8 tay ;preserve in Y-reg
860b: 30 0c bmi :BothDown ;yes, branch
860d: ad 00 c0 lda KBD ;check keyboard
8610: c9 a0 cmp #“ ” ;spacebar hit?
8612: d0 48 bne CheckSpeedButtons ;no, go check for speed change
8614: ad 10 c0 lda KBDSTRB ;yes, clear keyboard strobe
8617: a0 ff ldy #$ff ;set Y-reg to value with high bit set
8619: ea :BothDown nop
861a: ad 92 6d lda btns_down_flag ;were both buttons down before?
861d: 10 08 bpl :DoFire ;no, branch
861f: 8c 92 6d sty btns_down_flag ;yes, save current state (up or down)
8622: ce 91 6d dec shot_delay_ctr ;decrement the inter-shot counter
8625: 10 32 bpl :NoFire ;not ready to fire yet, bail
8627: 8c 92 6d :DoFire sty btns_down_flag ;set flag
862a: ea nop
; Fire a shot if possible.
]num_bytes .var $8a {addr/1}
862b: a5 6e lda free_elem_count ;? testing to see if obj table is full?
862d: f0 2a beq :NoFire
862f: a5 6d lda free_obj_count
8631: f0 26 beq :NoFire
8633: a9 06 lda #$06
8635: 8d 91 6d sta shot_delay_ctr ;init shot delay (reduces shot spamming)
8638: a2 0b ldx #$0b
863a: a9 02 lda #$02
863c: 85 8a sta ]num_bytes
863e: a0 15 ldy #$15
8640: 20 68 7c jsr ReduceResource ;reduce ammunition by 1
8643: a9 7f lda #$7f ;special value, tested later
8645: 85 a2 sta linked_obj_index
8647: ea nop
8648: a0 08 ldy #$08 ;player projectile
864a: 20 0f 76 jsr CreateObject
864d: a0 00 ldy #$00 ;effect #0: player cannon fired
864f: a9 00 lda #$00
8651: 20 da 7c jsr InitiateSfx ;initiate the sound effect
8654: a9 00 lda #$00 ;(?)
8656: 20 f0 0f jsr Return0ff0
8659: 4c f5 86 :NoFire jmp :AdjustSpeed
;
; Speeds up or slows down based on whether a single button is being pushed.
;
; The button read is ignored on the first frame, presumably to reduce the
; instances where you speed up or slow down while trying to fire by hitting both
; buttons.
;
; Note the displayed speed value is updated independently of the actual forward
; speed, using constants from two different locations.
;
• Clear variables
]num_bytes .var $8a {addr/1}
CheckSpeedButtons
865c: a9 00 lda #$00
865e: 8d 91 6d sta shot_delay_ctr ;reset shot delay counter to zero
8661: 8c 92 6d sty btns_down_flag ;save buttons-down flag value
8664: ad 61 c0 lda BUTN0 ;get button 0 (go slower)
8667: 10 4b bpl :NoSlow ;not pushed, bail
8669: ad 93 6d lda btns_0_down_flag ;was button 0 down before?
866c: 10 43 bpl :Jmp_AdjustSpeed ;no, bail
866e: ad 92 6d lda btns_down_flag ;both buttons down?
8671: 30 3e bmi :Jmp_AdjustSpeed ;yes, bail
; Slow down.
8673: ee 5f 6d inc fuel_this_frame ;increase fuel consumption
8676: a2 0d ldx #$0d ;reduce displayed speed by 20
8678: a0 11 ldy #$11
867a: a9 02 lda #$02 ;2-byte value
867c: 85 8a sta ]num_bytes
867e: 20 68 7c jsr ReduceResource ;reduce speed
8681: b0 20 bcs :Underflow ;reached zero
8683: 38 sec
8684: ad a4 6d lda forward_speed ;adjust forward speed, which is a 16.8 value
8687: ed 49 73 sbc delta_speed ;subtract per-frame delta, an 8.8 value
868a: 8d a4 6d sta forward_speed
868d: ad a5 6d lda forward_speed+1
8690: ed 4a 73 sbc delta_speed+1
8693: 8d a5 6d sta forward_speed+1
8696: ad a6 6d lda forward_speed+2
8699: e9 00 sbc #$00
869b: 8d a6 6d sta forward_speed+2
869e: 20 7f 7f jsr Return7f7f
86a1: 10 0e bpl :Jmp_AdjustSpeed ;if speed is still positive, branch
86a3: a9 00 :Underflow lda #$00 ;set desired speed to zero
86a5: 8d a4 6d sta forward_speed
86a8: 8d a5 6d sta forward_speed+1
86ab: 8d a6 6d sta forward_speed+2
86ae: 20 7f 7f jsr Return7f7f
:Jmp_AdjustSpeed
86b1: 4c f5 86 jmp :AdjustSpeed
86b4: ad 62 c0 :NoSlow lda BUTN1 ;get button 1 (go faster)
86b7: 10 f8 bpl :Jmp_AdjustSpeed ;not pushed, bail
86b9: ad 92 6d lda btns_down_flag ;was button 1 down before?
86bc: 30 f3 bmi :Jmp_AdjustSpeed ;no, bail
86be: ad 94 6d lda btns_1_down_flag ;both buttons down?
86c1: 10 ee bpl :Jmp_AdjustSpeed ;yes, bail
; Speed up.
86c3: ee 5f 6d inc fuel_this_frame ;increase fuel consumption
86c6: ad cb 6d lda cur_speed+1 ;get high byte of speed
86c9: c9 90 cmp #$90 ;have we reached 9000?
86cb: b0 27 bcs :NoFaster ;yes, bail
86cd: a2 0d ldx #$0d
86cf: a0 11 ldy #$11
86d1: a9 02 lda #$02
86d3: 85 8a sta ]num_bytes
86d5: 20 a0 7c jsr IncreaseResource ;increase displayed speed by 20
86d8: b0 1a bcs :NoFaster
86da: ad a4 6d lda forward_speed ;adjust forward speed, which is a 16.8 value
86dd: 6d 49 73 adc delta_speed ;add per-frame delta, an 8.8 value
86e0: 8d a4 6d sta forward_speed
86e3: ad a5 6d lda forward_speed+1
86e6: 6d 4a 73 adc delta_speed+1
86e9: 8d a5 6d sta forward_speed+1
86ec: 90 07 bcc :AdjustSpeed
86ee: ee a6 6d inc forward_speed+2
86f1: 20 7f 7f jsr Return7f7f
86f4: ea :NoFaster nop
; Copy forward speed to DP variable, adjusting for fractional speed values
; (which aren't used in this game). A speed of 0.5 would be handled by setting
; the speed to 0 or 1 on alternate frames.
]sound_adj? .var $86 {addr/2}
86f5: ad 61 c0 :AdjustSpeed lda BUTN0 ;set button-down flags
86f8: 8d 93 6d sta btns_0_down_flag
86fb: ad 62 c0 lda BUTN1
86fe: 8d 94 6d sta btns_1_down_flag
8701: 18 clc
8702: ad a7 6d lda speed_fraction ;track fractional value, updating every frame
8705: 6d a4 6d adc forward_speed ;not used in this game (always zero)
8708: 8d a7 6d sta speed_fraction
870b: ad a5 6d lda forward_speed+1
870e: 69 00 adc #$00
8710: 85 98 sta adj_fwd_speed
8712: 85 86 sta ]sound_adj? ;used to adjust sound we don't actually play
8714: ad a6 6d lda forward_speed+2 ; (presumably this is used to tweak the engine noise
8717: 69 00 adc #$00 ; when accelerating or decelerating, but the
8719: 85 99 sta adj_fwd_speed+1 ; engine noise is disabled)
871b: 85 87 sta ]sound_adj?+1
871d: 10 0d bpl :IsPos
871f: 38 sec ;we're moving backward, so use (0 - value) here
8720: a9 00 lda #$00 ;(not possible in this game)
8722: e5 86 sbc ]sound_adj?
8724: 85 86 sta ]sound_adj?
8726: a9 00 lda #$00
8728: e5 87 sbc ]sound_adj?+1
872a: 85 87 sta ]sound_adj?+1
872c: ce 5f 6d :IsPos dec fuel_this_frame ;have we fully deducted fuel for this frame?
872f: 30 0e bmi :FuelDone ;yes, branch
; Update fuel.
8731: a2 08 ldx #$08 ;update current fuel by 2
8733: a0 39 ldy #$39
8735: a9 02 lda #$02 ;update 2-byte value
8737: 85 8a sta ]num_bytes
8739: 20 68 7c jsr ReduceResource ;reduce value
873c: 4c 2c 87 jmp :IsPos
873f: ad 63 6d :FuelDone lda space_region ;get region?
8742: c9 03 cmp #$03 ;inside time portal?
8744: f0 57 beq :InPortal ;yes, branch
8746: ad 95 6d lda time_in_portal_ctr ;is the counter nonzero?
8749: 0d 96 6d ora time_in_portal_ctr+1
874c: d0 03 bne :PostPortalReset? ;yes, we just left portal; reset state
874e: 4c 58 89 jmp :NotInPortal ;no, continue
; Reset portal-related state after leaving a portal.
:PostPortalReset?
8751: a9 00 lda #$00
8753: 85 ce sta portal_next_xc
8755: 85 cf sta portal_next_xc+1
8757: 85 d0 sta portal_next_yc
8759: 85 d1 sta portal_next_yc+1
875b: 8d 95 6d sta time_in_portal_ctr
875e: 8d 96 6d sta time_in_portal_ctr+1
8761: 8d 98 6d sta time_portal_fail_ctr
8764: 8d 53 6d sta portal_xmod0
8767: 8d 54 6d sta portal_xmod0+1
876a: 8d 55 6d sta portal_xmod0+2
876d: 8d 56 6d sta portal_ymod0
8770: 8d 57 6d sta portal_ymod0+1
8773: 8d 58 6d sta portal_ymod0+2
8776: 8d 59 6d sta portal_xmod1
8779: 8d 5a 6d sta portal_xmod1+1
877c: 8d 5b 6d sta portal_xmod1+2
877f: 8d 5c 6d sta portal_ymod1
8782: 8d 5d 6d sta portal_ymod1+1
8785: 8d 5e 6d sta portal_ymod1+2
8788: 8d 9b 6d sta wronly_6d9b?
878b: 8d 9c 6d sta wronly_6d9b?+1
878e: 8d 9d 6d sta wronly_6d9b?+2
8791: 8d 9e 6d sta wronly_6d9b?+3
8794: 8d 9f 6d sta wronly_6d9b?+4
8797: 8d a0 6d sta wronly_6d9b?+5
879a: 4c 58 89 jmp :NotInPortal
;
; Perturb the time portal position.
;
]rng_limit .var $86 {addr/2}
]rng_limit_mode .var $88 {addr/1}
]rng_retval .var $8a {addr/2}
]random_val .var $8e {addr/3}
879d: ad 95 6d :InPortal lda time_in_portal_ctr ;increment the time-in-portal counter
87a0: 18 clc
87a1: 69 01 adc #$01
87a3: 8d 95 6d sta time_in_portal_ctr
87a6: 90 03 bcc :NoInc
87a8: ee 96 6d inc time_in_portal_ctr+1
87ab: ad ae 6d :NoInc lda portal_bound_limit ;increment the limit, so portals get wilder over
87ae: 18 clc ; time; value is only reset when game restarts
87af: 69 01 adc #$01
87b1: 8d ae 6d sta portal_bound_limit
87b4: 90 03 bcc :NoInc
87b6: ee af 6d inc portal_bound_limit+1
; Start with the X coordinate.
87b9: ad ae 6d :NoInc lda portal_bound_limit ;pass limit to RNG
87bc: 85 86 sta ]rng_limit
87be: ad af 6d lda portal_bound_limit+1
87c1: 85 87 sta ]rng_limit+1
87c3: a9 01 lda #$01 ;limited range, positive/negative
87c5: 85 88 sta ]rng_limit_mode
87c7: 20 b0 7b jsr GenRandom ;get random number
87ca: a5 8a lda ]rng_retval ;copy the result out
87cc: 85 8e sta ]random_val
87ce: a5 8b lda ]rng_retval+1
87d0: 85 8f sta ]random_val+1
87d2: 30 07 bmi :IsNeg
87d4: a9 00 lda #$00 ;sign-extend positive
87d6: 85 90 sta ]random_val+2
87d8: 4c df 87 jmp :Cont1
87db: a9 ff :IsNeg lda #$ff ;sign-extend negative
87dd: 85 90 sta ]random_val+2
; Add the random value to the YC modifier.
]shifted_copy .var $86 {addr/3}
87df: 18 :Cont1 clc
87e0: ad 53 6d lda portal_xmod0
87e3: 65 8e adc ]random_val
87e5: 8d 53 6d sta portal_xmod0
87e8: ad 54 6d lda portal_xmod0+1
87eb: 65 8f adc ]random_val+1
87ed: 8d 54 6d sta portal_xmod0+1
87f0: ad 55 6d lda portal_xmod0+2
87f3: 65 90 adc ]random_val+2
87f5: 8d 55 6d sta portal_xmod0+2
87f8: 20 7f 7f jsr Return7f7f
; Copy the value from $6d53 to ZP, essentially right-shifting 8x and sign-
; extending.
87fb: ad 54 6d lda portal_xmod0+1
87fe: 85 86 sta ]shifted_copy
8800: ad 55 6d lda portal_xmod0+2
8803: 85 87 sta ]shifted_copy+1
8805: 10 05 bpl :IsPos
8807: a9 ff lda #$ff
8809: 4c 0e 88 jmp :Cont2
880c: a9 00 :IsPos lda #$00
880e: 85 88 :Cont2 sta ]shifted_copy+2
; Modify the 24-bit value at $6d53, subtracting itself right-shifted 8x, so
; bigger magnitudes beget bigger magnitudes (positive feedback loop).
8810: 38 sec
8811: ad 53 6d lda portal_xmod0
8814: e5 86 sbc ]shifted_copy
8816: 8d 53 6d sta portal_xmod0
8819: ad 54 6d lda portal_xmod0+1
881c: e5 87 sbc ]shifted_copy+1
881e: 8d 54 6d sta portal_xmod0+1
8821: ad 55 6d lda portal_xmod0+2
8824: e5 88 sbc ]shifted_copy+2
8826: 8d 55 6d sta portal_xmod0+2
8829: 20 7f 7f jsr Return7f7f
; Modify the 24-bit value at $6d59, adding $6d53 right-shifted 8x.
882c: 18 clc
882d: ad 59 6d lda portal_xmod1
8830: 65 86 adc ]shifted_copy
8832: 8d 59 6d sta portal_xmod1
8835: ad 5a 6d lda portal_xmod1+1
8838: 65 87 adc ]shifted_copy+1
883a: 8d 5a 6d sta portal_xmod1+1
883d: ad 5b 6d lda portal_xmod1+2
8840: 65 88 adc ]shifted_copy+2
8842: 8d 5b 6d sta portal_xmod1+2
; Copy the value from $6d59 to ZP, essentially right-shifting 8x and sign-
; extending.
8845: ad 5a 6d lda portal_xmod1+1
8848: 85 86 sta ]shifted_copy
884a: ad 5b 6d lda portal_xmod1+2
884d: 85 87 sta ]shifted_copy+1
884f: 10 05 bpl :IsPos
8851: a9 ff lda #$ff
8853: 4c 58 88 jmp :Cont
8856: a9 00 :IsPos lda #$00
8858: 85 88 :Cont sta ]shifted_copy+2
885a: 20 7f 7f jsr Return7f7f
; Modify the 24-bit value at $6d59, subtracting itself right-shifted 8x.
885d: 38 sec
885e: ad 59 6d lda portal_xmod1
8861: e5 86 sbc ]shifted_copy
8863: 8d 59 6d sta portal_xmod1
8866: ad 5a 6d lda portal_xmod1+1
8869: e5 87 sbc ]shifted_copy+1
886b: 8d 5a 6d sta portal_xmod1+1
886e: ad 5b 6d lda portal_xmod1+2
8871: e5 88 sbc ]shifted_copy+2
8873: 8d 5b 6d sta portal_xmod1+2
8876: ea nop
8877: ea nop
8878: ea nop
8879: ea nop
887a: 18 clc ;update portal boundary X coordinate
887b: a5 ce lda portal_next_xc
887d: 65 86 adc ]shifted_copy
887f: 85 ce sta portal_next_xc
8881: a5 cf lda portal_next_xc+1
8883: 65 87 adc ]shifted_copy+1
8885: 85 cf sta portal_next_xc+1
;
; Do it all again for Y coordinate.
;
]rng_limit .var $86 {addr/2}
]rng_limit_mode .var $88 {addr/1}
]random_val .var $8e {addr/3}
8887: ad ae 6d lda portal_bound_limit ;reset limit
888a: 85 86 sta ]rng_limit
888c: ad af 6d lda portal_bound_limit+1
888f: 85 87 sta ]rng_limit+1
8891: a9 01 lda #$01
8893: 85 88 sta ]rng_limit_mode ;generate +/-
8895: 20 b0 7b jsr GenRandom ;generate 16-bit random number
8898: a5 8a lda ]rng_retval
889a: 85 8e sta ]random_val
889c: a5 8b lda ]rng_retval+1
889e: 85 8f sta ]random_val+1
88a0: 30 07 bmi :IsNeg
88a2: a9 00 lda #$00
88a4: 85 90 sta ]random_val+2 ;sign-extend positive
88a6: 4c ad 88 jmp :Cont1
88a9: a9 ff :IsNeg lda #$ff
88ab: 85 90 sta ]random_val+2 ;sign-extend negative
; Add the random value to the XC modifier.
]shifted_copy .var $86 {addr/3}
88ad: 18 :Cont1 clc
88ae: ad 56 6d lda portal_ymod0 ;add random number
88b1: 65 8e adc ]random_val
88b3: 8d 56 6d sta portal_ymod0
88b6: ad 57 6d lda portal_ymod0+1
88b9: 65 8f adc ]random_val+1
88bb: 8d 57 6d sta portal_ymod0+1
88be: ad 58 6d lda portal_ymod0+2
88c1: 65 90 adc ]random_val+2
88c3: 8d 58 6d sta portal_ymod0+2
88c6: 20 7f 7f jsr Return7f7f
; Copy the value from $6d56 to ZP, essentially right-shifting 8x and sign-
; extending.
88c9: ad 57 6d lda portal_ymod0+1
88cc: 85 86 sta ]shifted_copy
88ce: ad 58 6d lda portal_ymod0+2
88d1: 85 87 sta ]shifted_copy+1
88d3: 10 05 bpl :IsPos
88d5: a9 ff lda #$ff
88d7: 4c dc 88 jmp :Cont2
88da: a9 00 :IsPos lda #$00
88dc: 85 88 :Cont2 sta ]shifted_copy+2
; Modify the 24-bit value at $6d56, subtracting itself right-shifted 8x, so
; bigger magnitudes beget bigger magnitudes (positive feedback loop).
88de: 38 sec
88df: ad 56 6d lda portal_ymod0
88e2: e5 86 sbc ]shifted_copy
88e4: 8d 56 6d sta portal_ymod0
88e7: ad 57 6d lda portal_ymod0+1
88ea: e5 87 sbc ]shifted_copy+1
88ec: 8d 57 6d sta portal_ymod0+1
88ef: ad 58 6d lda portal_ymod0+2
88f2: e5 88 sbc ]shifted_copy+2
88f4: 8d 58 6d sta portal_ymod0+2
88f7: 20 7f 7f jsr Return7f7f
; Modify the 24-bit value at $6d5c, adding $6d56 right-shifted 8x.
88fa: 18 clc
88fb: ad 5c 6d lda portal_ymod1
88fe: 65 86 adc ]shifted_copy
8900: 8d 5c 6d sta portal_ymod1
8903: ad 5d 6d lda portal_ymod1+1
8906: 65 87 adc ]shifted_copy+1
8908: 8d 5d 6d sta portal_ymod1+1
890b: ad 5e 6d lda portal_ymod1+2
890e: 65 88 adc ]shifted_copy+2
8910: 8d 5e 6d sta portal_ymod1+2
; Copy the value from $6d5c to ZP, essentially right-shifting 8x and sign-
; extending.
8913: ad 5d 6d lda portal_ymod1+1
8916: 85 86 sta ]shifted_copy
8918: ad 5e 6d lda portal_ymod1+2
891b: 85 87 sta ]shifted_copy+1
891d: 10 05 bpl :IsPos2
891f: a9 ff lda #$ff
8921: 4c 26 89 jmp :Cont3
8924: a9 00 :IsPos2 lda #$00
8926: 85 88 :Cont3 sta ]shifted_copy+2
8928: 20 7f 7f jsr Return7f7f
; Modify the 24-bit value at $6d5c, subtracting itself right-shifted 8x.
892b: 38 sec
892c: ad 5c 6d lda portal_ymod1
892f: e5 86 sbc ]shifted_copy
8931: 8d 5c 6d sta portal_ymod1
8934: ad 5d 6d lda portal_ymod1+1
8937: e5 87 sbc ]shifted_copy+1
8939: 8d 5d 6d sta portal_ymod1+1
893c: ad 5e 6d lda portal_ymod1+2
893f: e5 88 sbc ]shifted_copy+2
8941: 8d 5e 6d sta portal_ymod1+2
8944: ea nop
8945: ea nop
8946: ea nop
8947: ea nop
8948: 18 clc
8949: a5 d0 lda portal_next_yc ;update portal boundary Y coordinate
894b: 65 86 adc ]shifted_copy
894d: 85 d0 sta portal_next_yc
894f: a5 d1 lda portal_next_yc+1
8951: 65 87 adc ]shifted_copy+1
8953: 85 d1 sta portal_next_yc+1
8955: 20 45 5e jsr UpdatePortalPosn ;calculate next position
;
; Decrement sound counters by one, unless already at zero.
;
8958: a5 87 :NotInPortal lda ]shifted_copy+1 ;(?)
895a: a0 04 ldy #$04
895c: b6 c8 :DecrLoop ldx sound_counters,y
895e: f0 05 beq :AlreadyZero
8960: ca dex
8961: 8a txa
8962: 99 c8 00 sta sound_counters,y
8965: 88 :AlreadyZero dey
8966: ea nop
8967: 10 f3 bpl :DecrLoop
8969: a5 fa lda impact_sound_flag ;decrement $fa to zero
896b: f0 02 beq UpdateRegion
896d: c6 fa dec impact_sound_flag
;
; Switches to a new region if appropriate.
;
• Clear variables
896f: ad 3b 6d UpdateRegion lda game_active_flag ;are we in demo mode?
8972: f0 2d beq :Jmp_CheckRegion_1 ;yes, branch
8974: ad 63 6d lda space_region ;get region
8977: c9 03 cmp #$03 ;are we inside a time portal?
8979: d0 29 bne :Jmp_CheckRegion_2 ;no, branch
897b: ad c3 6d lda time_left+1 ;check time left
897e: c9 99 cmp #$99 ;reached max?
8980: 90 08 bcc :StillInside ;not yet, branch
8982: a9 06 lda #$06
8984: 20 c2 7f jsr PlayMusicSeq ;play "exit time portal" music
8987: 4c 9e 89 jmp :ChangeRegion ;switch to a new region
898a: ad 96 6d :StillInside lda time_in_portal_ctr+1 ;have we been inside for at least 500 ticks?
898d: d0 07 bne :Sub0500
898f: ad 95 6d lda time_in_portal_ctr
8992: c9 05 cmp #$05
8994: 90 0b bcc :Jmp_CheckRegion_1 ;haven't been inside long, skip button check
8996: ad 61 c0 :Sub0500 lda BUTN0 ;are both buttons held down?
8999: 2d 62 c0 and BUTN1
899c: 10 03 bpl :Jmp_CheckRegion_1 ;no, branch
899e: 4c fd 89 :ChangeRegion jmp :RandRegion ;exit the time portal to a new, random region
:Jmp_CheckRegion_1
89a1: 4c f0 89 jmp :CheckRegion
:Jmp_CheckRegion_2
89a4: 4c f0 89 jmp :CheckRegion
:EnterTimePortal
89a7: ee 97 6d inc wronly_6d97?
89aa: ad 3b 6d lda game_active_flag ;are we in demo mode?
89ad: f0 28 beq :NoFanfare ;yes, skip the fanfare
89af: a9 02 lda #$02
89b1: 20 c2 7f jsr PlayMusicSeq ;play "enter time portal" music
; Erase status line, from left side to partway through fuel counter.
89b4: a2 00 ldx #$00
89b6: a9 00 :EraseLoop lda #$00
89b8: 9d 80 24 sta HIRES_P1+$480,x ;line 9
89bb: 9d 80 28 sta HIRES_P1+$880,x
89be: 9d 80 2c sta HIRES_P1+$c80,x
89c1: 9d 80 30 sta HIRES_P1+$1080,x
89c4: 9d 80 38 sta HIRES_P1+$1880,x
89c7: 9d 80 34 sta HIRES_P1+$1480,x
89ca: 9d 80 3c sta HIRES_P1+$1c80,x ;line 15
89cd: e8 inx
89ce: e0 18 cpx #24 ;reached column 24 (last digit of fuel)?
89d0: 30 e4 bmi :EraseLoop
89d2: a9 02 lda #$02
89d4: 20 f4 0f jsr Return0ff4
89d7: a9 00 :NoFanfare lda #$00
89d9: 8d 99 6d sta entered_portal_flag ;clear "just entered" flag
89dc: a9 40 lda #$40
89de: 8d 62 6d sta region_progress_ctr+1 ;configure max time in portal
89e1: ad 3b 6d lda game_active_flag ;are we in demo mode?
89e4: d0 05 bne :Playing ;no, branch
89e6: a9 18 lda #$18
89e8: 8d 62 6d sta region_progress_ctr+1 ;reduce max time in portal
89eb: a9 03 :Playing lda #$03 ;set space-region to 3 (inside portal)
89ed: 4c 55 8a jmp :SetRegion
89f0: ad 99 6d :CheckRegion lda entered_portal_flag ;did we just enter a time portal?
89f3: d0 b2 bne :EnterTimePortal ;yes, do the intro bit
89f5: ad 62 6d lda region_progress_ctr+1 ;check our progress in this region
89f8: 30 03 bmi :RandRegion ;time for a new region, branch
89fa: 4c 7e 8a jmp SpawnNewStuff
; Pick a region at random.
• Clear variables
]rng_limit_mode .var $88 {addr/1}
]rng_result .var $8a {addr/2}
89fd: a9 ff :RandRegion lda #$ff
89ff: 85 88 sta ]rng_limit_mode ;no limit
8a01: 20 b0 7b jsr GenRandom ;generate random number
8a04: a5 8b lda ]rng_result+1
8a06: 29 0f and #$0f
8a08: 8d 62 6d sta region_progress_ctr+1 ;init progress counter high byte to 0-15
8a0b: a5 8a lda ]rng_result
8a0d: 8d 61 6d sta region_progress_ctr ;init progress counter low byte
8a10: 29 07 and #$07 ;limit to 0-7
8a12: 8d 63 6d sta space_region ;use as region value
8a15: ac 3b 6d ldy game_active_flag ;are we playing the game?
8a18: d0 33 bne :InGame ;yes, branch
; Change the demo region.
8a1a: a5 8b lda ]rng_result+1 ;not playing; set the forward speed
8a1c: 85 98 sta adj_fwd_speed
8a1e: 29 03 and #$03
8a20: 85 99 sta adj_fwd_speed+1 ;limit to 0-3 ($3ff is speed=10230)
8a22: ad be 6c lda logo_region_toggle ;flip toggle
8a25: 49 ff eor #$ff
8a27: 8d be 6c sta logo_region_toggle
8a2a: 10 15 bpl :NotLogo ;go into Epoch-logo mode every other time
8a2c: ad bf 6c lda demo_logo_progress ;init progress to specific value for logo
8a2f: 8d 62 6d sta region_progress_ctr+1 ; so it doesn't flip modes mid-logo-zoom
8a32: ad c0 6c lda demo_logo_speed ;set forward speed
8a35: 85 98 sta adj_fwd_speed
8a37: ad c1 6c lda demo_logo_speed+1
8a3a: 85 99 sta adj_fwd_speed+1
8a3c: a9 06 lda #$06 ;set region to Epoch logo
8a3e: 4c 55 8a jmp :SetRegion
8a41: ad 63 6d :NotLogo lda space_region ;get region
8a44: c9 06 cmp #$06 ;is it 6?
8a46: d0 0d bne :SetRegion ;no, branch
8a48: a9 03 lda #$03 ;don't show logo again; do time portal instead
8a4a: 4c 55 8a jmp :SetRegion
8a4d: c9 03 :InGame cmp #$03 ;did we randomly pick time portal?
8a4f: f0 ac beq :RandRegion ;yes, re-roll
8a51: c9 06 cmp #$06 ;did we randomly pick Epoch logo?
8a53: f0 a8 beq :RandRegion ;yes, re-roll
8a55: 8d 63 6d :SetRegion sta space_region ;set the new region
8a58: 0a asl A ;multiply by 8
8a59: 0a asl A
8a5a: 0a asl A
8a5b: 18 clc
8a5c: 6d cc 70 adc region_tab_base ;add base pointer
8a5f: 8d 67 6d sta region_tab_ptr ;set pointer
8a62: ea nop
8a63: ad cd 70 lda region_tab_base+1
8a66: 69 00 adc #$00
8a68: 8d 68 6d sta region_tab_ptr+1 ;set high byte
8a6b: ea nop
8a6c: ad 63 6d lda space_region ;get the region
8a6f: c9 03 cmp #$03 ;are we in a time portal?
8a71: d0 0b bne SpawnNewStuff ;no, branch
8a73: ad 62 6d lda region_progress_ctr+1 ;reset region progress
8a76: 69 0e adc #$0e
8a78: 8d 62 6d sta region_progress_ctr+1
8a7b: 20 7f 7f jsr Return7f7f
;
8a7e: a9 07 SpawnNewStuff lda #$07 ;get a "random" value from 0-7
8a80: 38 sec
8a81: e5 b3 sbc engine_sound_ctr?+2
8a83: 30 4f bmi :NoCreate ;not in range, don't spawn this frame
8a85: 0a asl A ;multiply by 4 (0-28)
8a86: 0a asl A
8a87: 8d 64 6d sta create_mult_ctr ;put a limit on how much we create
8a8a: ad 63 6d lda space_region ;get the region
8a8d: c9 03 cmp #$03 ;are we in a time portal?
8a8f: d0 19 bne :TryCreateObj ;no, branch
8a91: a4 6a ldy head_obj_index
8a93: b9 08 9c lda obj_shape_cl_index,y ;get shape class
8a96: c9 05 cmp #$05 ;is it a time portal boundary object?
8a98: d0 10 bne :TryCreateObj
8a9a: b9 00 9a lda obj_first_elem_index,y
8a9d: 30 0b bmi :TryCreateObj
8a9f: a8 tay
8aa0: b9 80 a1 lda elem_zpos_hi,y
8aa3: c9 1f cmp #$1f
8aa5: 90 03 bcc :TryCreateObj
8aa7: 4c ee 8a jmp DrawStatus
; Create a new object if there's room for it in the tables and it fits in the
; objects-per-region limit.
]region_ptr? .var $16 {addr/2}
8aaa: ad 67 6d :TryCreateObj lda region_tab_ptr ;get pointer to region limit table
8aad: 85 16 sta ]region_ptr?
8aaf: ad 68 6d lda region_tab_ptr+1
8ab2: 85 17 sta ]region_ptr?+1
8ab4: ea nop
8ab5: a5 6d lda free_obj_count ;do we have room to create a new object?
8ab7: f0 1b beq :NoCreate ;no, branch
8ab9: a5 6e lda free_elem_count ;got space in element list?
8abb: f0 17 beq :NoCreate ;no, branch
8abd: a2 07 ldx #$07 ;loop over 8 shape classes
8abf: ee 65 6d :ChkClassLoop inc shape_cl_ctr ;increment counter
8ac2: ad 65 6d lda shape_cl_ctr ;get counter
8ac5: 29 07 and #$07 ;reduce to 0-7
8ac7: a8 tay
8ac8: b9 69 6d lda active_class_ctrs,y ;get count of active objects of this class
8acb: d1 16 cmp (]region_ptr?),y ;compare to max
8acd: 30 08 bmi :CreateObject ;cur < max, create another
8acf: ca dex
8ad0: ea nop
8ad1: 10 ec bpl :ChkClassLoop ;try the next class
8ad3: ea nop
8ad4: 4c ee 8a :NoCreate jmp DrawStatus ;no luck, go on to the next thing
; Create a new object. Object class in Y-reg.
8ad7: a9 f7 :CreateObject lda #$f7
8ad9: 85 a2 sta linked_obj_index
8adb: ad 64 6d lda create_mult_ctr ;get counter
8ade: 38 sec
8adf: f9 7f 70 sbc create_mult_tab,y ;subtract a class-specific value, so we can create
8ae2: 8d 64 6d sta create_mult_ctr ; lots of stars all at once, but just one base
8ae5: 20 0f 76 jsr CreateObject ;create an object
8ae8: ea nop
8ae9: ad 64 6d lda create_mult_ctr ;check counter
8aec: 10 bc bpl :TryCreateObj ;we're in the "positive phase", so try for another
;
; Draw status text a bit at a time.
;
8aee: 20 36 7b DrawStatus jsr DrawStatusLine ;draw one character of status line
8af1: 20 36 7b :DrawStatus1 jsr DrawStatusLine ;draw one character of status line
8af4: 18 clc ;do sound stuff
8af5: a5 b2 lda engine_sound_ctr?+1
8af7: 69 0b adc #$0b
8af9: 85 b2 sta engine_sound_ctr?+1
8afb: 90 0f bcc :NoSound
8afd: e6 b3 inc engine_sound_ctr?+2
8aff: a5 cc lda engine_sound_enable
8b01: f0 09 beq :NoSound
8b03: a5 b3 lda engine_sound_ctr?+2
8b05: 25 b1 and engine_sound_ctr?
8b07: d0 03 bne :NoSound
8b09: ad 30 c0 lda SPKR ;click
8b0c: a5 b3 :NoSound lda engine_sound_ctr?+2 ;load $b3
8b0e: a5 b3 lda engine_sound_ctr?+2 ;load $b3 again
8b10: 18 clc
8b11: a5 b3 lda engine_sound_ctr?+2 ;load $b3 a third time
8b13: c9 09 cmp #$09 ;is it < 9?
8b15: 30 da bmi :DrawStatus1 ;yes, draw another character
8b17: 20 7f 7f jsr Return7f7f
8b1a: ad 3b 6d lda game_active_flag ;are we in demo mode?
8b1d: f0 03 beq :ShowOutOf ;yes, branch
8b1f: 4c 2d 8c jmp StartRedraw
; After the game ends, we show "out of ____", and continue to display it for a
; bit after the demo resumes. We do this instead of the author/copyright text.
]str_index .var $8c {addr/1}
8b22: ad 40 6d :ShowOutOf lda end_game_msg_ctr+1 ;has high byte of counter hit zero?
8b25: f0 7f beq :NoShowOut ;yes, branch
8b27: 38 sec
8b28: ad 3f 6d lda end_game_msg_ctr ;decrement counter
8b2b: e9 01 sbc #$01
8b2d: 8d 3f 6d sta end_game_msg_ctr
8b30: ad 40 6d lda end_game_msg_ctr+1
8b33: e9 00 sbc #$00
8b35: 8d 40 6d sta end_game_msg_ctr+1
; Draw "OUT OF ____" message.
8b38: a2 00 ldx #$00 ;column 0
8b3a: a9 00 lda #$00
8b3c: 85 8c sta ]str_index
8b3e: a4 8c :OutOfLoop ldy ]str_index
8b40: b9 c1 6e lda text_out_of,y ;get char from string
8b43: 20 03 75 jsr PrintCharLine160 ;print it
8b46: e6 8c inc ]str_index
8b48: e0 06 cpx #$06 ;done yet? (6 chars in "OUT OF")
8b4a: ea nop
8b4b: 30 f1 bmi :OutOfLoop
8b4d: ea nop
8b4e: a2 08 ldx #$08 ;column 8
8b50: a5 b5 lda end_game_cause ;get reason for ending game (0/4/8)
8b52: 85 8c sta ]str_index ;use as index into string
8b54: a4 8c :RsrcLoop ldy ]str_index
8b56: b9 c8 6e lda text_time_fuel_amun,y ;get char from string
8b59: 20 03 75 jsr PrintCharLine160 ;print it
8b5c: e6 8c inc ]str_index
8b5e: e0 0c cpx #$0c ;reached column 12 (8+4)?
8b60: ea nop
8b61: 30 f1 bmi :RsrcLoop
8b63: ea nop
; Draw "RATING ______" message.
8b64: a2 10 ldx #16 ;column 16
8b66: a9 00 lda #$00
8b68: 85 8c sta ]str_index
8b6a: a4 8c :RatLoop ldy ]str_index
8b6c: b9 d8 6e lda text_rating,y ;get char from string
8b6f: 20 03 75 jsr PrintCharLine160 ;print it
8b72: e6 8c inc ]str_index
8b74: e0 16 cpx #22 ;done yet? (6 chars in "RATING")
8b76: ea nop
8b77: 30 f1 bmi :RatLoop
8b79: ea nop
8b7a: a2 18 ldx #24 ;column 24
8b7c: a5 b6 lda score_rating_index ;index to rating string
8b7e: 85 8c sta ]str_index
8b80: a4 8c :RatLabelLoop ldy ]str_index
8b82: b9 e7 6e lda text_rating_labels,y ;get char from string
8b85: 20 03 75 jsr PrintCharLine160 ;print it
8b88: e6 8c inc ]str_index
8b8a: e0 28 cpx #40 ;reached column 40 (24+16)?
8b8c: ea nop
8b8d: 30 f1 bmi :RatLabelLoop
8b8f: ea nop
; Play the music if we haven't yet.
8b90: ad 43 6d lda game_over_music ;have we played the music?
8b93: f0 0e beq :MusicDone ;yes, bail
8b95: c9 01 cmp #$01 ;is it the "not new high score" music?
8b97: d0 02 bne :PlayGameOver ;no, play it
8b99: a9 00 lda #$00 ;yes, play the short game-over sequence
8b9b: 20 c2 7f :PlayGameOver jsr PlayMusicSeq
8b9e: a9 00 lda #$00
8ba0: 8d 43 6d sta game_over_music ;record that we're done playing
8ba3: 4c 2d 8c :MusicDone jmp StartRedraw ;don't show author/copyright
8ba6: ea :NoShowOut nop
8ba7: ad 3f 6d lda end_game_msg_ctr ;did timer just expire?
8baa: f0 23 beq :DrawTitleText ;no, skip
; We show "out of ____" for a while after the game ends. If the timer has just
; expired, we want to erase the text.
8bac: a2 00 ldx #$00
8bae: a9 00 :ClearLoop lda #$00
8bb0: 9d 50 22 sta HIRES_P1+$250,x ;line 160
8bb3: 9d 50 26 sta HIRES_P1+$650,x
8bb6: 9d 50 2a sta HIRES_P1+$a50,x
8bb9: 9d 50 2e sta HIRES_P1+$e50,x
8bbc: 9d 50 36 sta HIRES_P1+$1650,x
8bbf: 9d 50 32 sta HIRES_P1+$1250,x
8bc2: 9d 50 3a sta HIRES_P1+$1a50,x
8bc5: e8 inx
8bc6: e0 28 cpx #40
8bc8: 30 e4 bmi :ClearLoop
8bca: a9 00 lda #$00
8bcc: 8d 3f 6d sta end_game_msg_ctr ;zero this so we know erase is done
;
; Draw the author/copyright strings. We draw one per frame, rotating.
;
8bcf: ee 41 6d :DrawTitleText inc title_text_draw_index ;inc index
8bd2: ad 41 6d lda title_text_draw_index ;get index
8bd5: c9 03 cmp #$03 ;have we hit 3?
8bd7: 30 1e bmi :Not3 ;not yet, branch
8bd9: a9 00 lda #$00
8bdb: 8d 41 6d sta title_text_draw_index ;yes, reset index to zero
; Index=0, draw "Sirius Software Presents" on line 32.
8bde: a2 08 ldx #$08
8be0: a9 00 lda #$00
8be2: 85 8c sta ]str_index
8be4: a4 8c :Loop0 ldy ]str_index
8be6: b9 35 6e lda text_sirius_pres,y
8be9: 20 95 74 jsr PrintCharLine32
8bec: e6 8c inc ]str_index
8bee: e0 20 cpx #$20
8bf0: ea nop
8bf1: 30 f1 bmi :Loop0
8bf3: ea nop
8bf4: 4c 2d 8c jmp StartRedraw
8bf7: ad 41 6d :Not3 lda title_text_draw_index ;load index again
8bfa: c9 01 cmp #$01 ;is it 1?
8bfc: f0 19 beq :Not1 ;yes, branch
; Index=1, draw "By Larry Miller" on line 160.
8bfe: a2 0c ldx #$0c
8c00: a9 00 lda #$00
8c02: 85 8c sta ]str_index
8c04: a4 8c :Loop1 ldy ]str_index
8c06: b9 5c 6e lda text_larry_spc,y
8c09: 20 03 75 jsr PrintCharLine160
8c0c: e6 8c inc ]str_index
8c0e: e0 1c cpx #$1c
8c10: ea nop
8c11: 30 f1 bmi :Loop1
8c13: ea nop
8c14: 4c 2d 8c jmp StartRedraw
; Index = 2, draw "Copyright 1981".
8c17: a2 0d :Not1 ldx #$0d
8c19: a9 00 lda #$00
8c1b: 85 8c sta ]str_index
8c1d: a4 8c :Loop2 ldy ]str_index
8c1f: b9 4e 6e lda text_copyright,y
8c22: 20 71 75 jsr PrintCharLine176
8c25: e6 8c inc ]str_index
8c27: e0 1b cpx #$1b
8c29: ea nop
8c2a: 30 f1 bmi :Loop2
8c2c: ea nop
;
; Starting point for object update and redraw.
;
; (This could be considered the top of the game loop, since we reset the stack
; pointer.)
;
8c2d: a9 ee StartRedraw lda #$ee
8c2f: 85 c6 sta prev_zpos+1 ;(invalidate? is this actually invalid?)
8c31: a9 00 lda #$00
8c33: 85 b2 sta engine_sound_ctr?+1 ;reset sound counters
8c35: 85 b3 sta engine_sound_ctr?+2
8c37: 85 cc sta engine_sound_enable ;disable "engine noise"?
8c39: a9 df lda #$df
8c3b: 85 74 sta prev_obj_index ;we're at the start, so no previous object
8c3d: a2 c0 ldx #$c0
8c3f: 9a txs ;reset stack pointer
8c40: 20 7f 7f jsr Return7f7f
8c43: a6 6a ldx head_obj_index ;get index of object at head of list
8c45: 86 62 stx cur_obj_index ;set as current
8c47: 10 0f bpl RedrawObject ;if valid, start redrawing
8c49: 4c 5c 81 jmp PartialRestart ;otherwise, something is wrong; reset game engine
8c4c: 3d 3d 3d 3d+ .junk 12
;
; Erases and draws an object.
;
; On entry:
; X-reg: object index (0-39)
;
8c58: bd 00 9a RedrawObject lda obj_first_elem_index,x ;get index of first element
8c5b: 10 03 bpl :ElemOk ;if valid, branch
8c5d: 4c 5c 81 jmp PartialRestart ;otherwise, reset game engine
8c60: a9 00 :ElemOk lda #$00
8c62: 8d 82 8c sta unused_flag_merge
8c65: 20 66 5f jsr UpdateObject ;update object movement; puts 1st elem into cur_elem
8c68: a6 64 ldx cur_elem_index ;get element index
8c6a: 10 03 bpl :Jmp_Redraw ;is valid, branch
8c6c: 4c 2a 92 jmp NextObject ;not valid, move on to next obj
8c6f: 4c 83 8c :Jmp_Redraw jmp RedrawElement
8c72: 00 00 00 3d+ .junk 15
8c81: 00 saved_obj_index .dd1 $00 ;temp storage for current object index
unused_flag_merge
8c82: 00 .dd1 $00 ;merged flag values (unused)
;
; Redraws an element. Computes the screen coordinates of the new position, then
; jumps to the appropriate erase function, which upon completion jumps to the
; apppropriate draw function.
;
; Elements that are clipped completely (fully off screen) will have a mod type
; of $82, and won't be drawn.
;
; (This is not a function that's called. This is part of a stream of execution
; that loops through here until the set of elements for the current object is
; exhausted.)
;
; On entry:
; X-reg: element index
;
8c83: bd 00 9f RedrawElement lda elem_obj_index,x ;get element's object index (this is strictly
8c86: 10 03 bpl :IndexOkay ; a consistency check)
8c88: 4c 5c 81 jmp PartialRestart ;unexpected, reset game
8c8b: 20 55 64 :IndexOkay jsr UpdateElement ;update element position, set mod type and flags
8c8e: a5 c9 lda sound_counters+1 ;do sound stuff
8c90: f0 03 beq :NoSound
8c92: ad 30 c0 lda SPKR ;click for sfx (player cannon, ship explosion)
8c95: bd 80 9f :NoSound lda elem_mod_types,x ;check the modified element type
8c98: f0 12 beq ErasePoint ;was $00, erase a point
8c9a: 10 24 bpl EraseHorizLine ;was $01, erase horizontal line
8c9c: 0a asl A
8c9d: f0 07 beq :EraseVertLine ;was $80, erase vertical line
8c9f: 29 04 and #$04 ;was it $82 ($04 after shift)?
8ca1: d0 06 bne :NoErase ;yes, element was not drawn, nothing to erase
8ca3: 4c 71 8d jmp EraseRect ;no, $81 or $83; erase rect
8ca6: 4c 38 8d :EraseVertLine jmp EraseVertLine
8ca9: 4c 52 8e :NoErase jmp DrawElement
;
; Erases a point. Pixel bits are set to zero.
;
; On entry:
; X-reg: element index
;
• Clear variables
]hptr .var $10 {addr/2}
8cac: bd 00 a4 ErasePoint lda elem_erase_1,x ;get high byte of pointer
8caf: 85 11 sta ]hptr+1
8cb1: bc c0 a3 ldy elem_erase_0,x ;get index into page
8cb4: bd 40 a5 lda elem_erase_6,x ;get bit mask
8cb7: 49 ff eor #$ff ;invert it for AND
8cb9: 31 10 and (]hptr),y
8cbb: 91 10 sta (]hptr),y ;update hi-res screen
8cbd: 4c 52 8e jmp DrawElement
;
; Erases a horizontal line, ANDing the color pixel bits to zero.
;
; On entry:
; X-reg: element index
;
• Clear variables
]hptr .var $18 {addr/2}
]saved_yreg .var $86 {addr/1}
]right_col .var $87 {addr/1}
]color0 .var $89 {addr/1}
]odd_even_mask .var $90 {addr/1}
]color1 .var $91 {addr/1}
8cc0: bd c0 a4 EraseHorizLine lda elem_erase_4,x ;get column of right edge
8cc3: 85 87 sta ]right_col
8cc5: bd 40 a4 lda elem_erase_2,x ;get hi-res line address, low byte
8cc8: 85 18 sta ]hptr
8cca: bd 00 a5 lda elem_erase_5,x ;get hi-res line address, high byte
8ccd: 85 19 sta ]hptr+1
8ccf: bd 80 a0 lda elem_cur_colors,x ;get current element color
8cd2: 1d c0 a3 ora elem_erase_0,x ;OR with left edge pixel color offset
8cd5: a8 tay
8cd6: 29 08 and #%00001000 ;strip all but bit 3 to get odd/even mask
8cd8: 85 90 sta ]odd_even_mask
8cda: b9 63 72 lda color_bit_masks_left,y ;get left-edge color bit pattern
8cdd: 49 ff eor #$ff ;invert bits for AND
8cdf: bc 00 a4 ldy elem_erase_1,x ;get column of left edge
8ce2: 31 18 and (]hptr),y ;mask bits from hi-res screen
8ce4: 91 18 sta (]hptr),y ;update hi-res screen
8ce6: c8 iny ;move to next column
8ce7: c4 87 cpy ]right_col ;compare to right edge
8ce9: f0 38 beq :RightCol ;at right, branch
8ceb: 10 48 bpl :DrawDone ;past right (single-column), we're done
8ced: 84 86 sty ]saved_yreg ;spill Y-reg
8cef: a5 90 lda ]odd_even_mask ;get mask (0 or 8)
8cf1: 1d 80 a0 ora elem_cur_colors,x ;combine with current element color
8cf4: a8 tay
8cf5: b9 63 72 lda color_bit_masks_left,y ;get full-byte color
8cf8: 49 ff eor #$ff ;invert to form AND mask
8cfa: 85 89 sta ]color0 ;save as first color
8cfc: a5 90 lda ]odd_even_mask
8cfe: 49 08 eor #$08 ;flip odd/even
8d00: 1d 80 a0 ora elem_cur_colors,x
8d03: a8 tay
8d04: b9 63 72 lda color_bit_masks_left,y ;get full-byte color
8d07: 49 ff eor #$ff ;invert to form AND mask
8d09: 85 91 sta ]color1 ;save as second color
;
8d0b: a4 86 ldy ]saved_yreg ;restore Y-reg (hi-res column)
8d0d: a5 91 :MiddleLoop lda ]color1
8d0f: 31 18 and (]hptr),y ;remove second color from bits in this byte
8d11: 91 18 sta (]hptr),y ;update hi-res screen
8d13: c8 iny
8d14: c4 87 cpy ]right_col ;at right edge yet?
8d16: 10 0b bpl :RightCol ;yes, branch
8d18: a5 89 lda ]color0
8d1a: 31 18 and (]hptr),y ;remove first color from bits in this byte
8d1c: 91 18 sta (]hptr),y ;update hi-res screen
8d1e: c8 iny
8d1f: c4 87 cpy ]right_col ;at right edge yet?
8d21: 30 ea bmi :MiddleLoop ;no, loop
8d23: bd 80 a4 :RightCol lda elem_erase_3,x ;get pixel color offset for right edge
8d26: 1d 80 a0 ora elem_cur_colors,x ;combine with element color
8d29: a8 tay
8d2a: b9 d3 72 lda color_bit_masks_right,y ;get pixel color mask
8d2d: 49 ff eor #$ff ;invert to form AND mask
8d2f: a4 87 ldy ]right_col
8d31: 31 18 and (]hptr),y
8d33: 91 18 sta (]hptr),y ;update hi-res screen
8d35: 4c 52 8e :DrawDone jmp DrawElement
;
; Erases a vertical line, ANDing the color pixel bits to zero.
;
; On entry:
; X-reg: element index
;
]instr_ptr .var $10 {addr/2}
]mod_offset .var $8a {addr/1}
8d38: bc 00 a5 EraseVertLine ldy elem_erase_5,x ;get bottom coordinate
8d3b: c8 iny ;increment to get start of next entry
8d3c: b9 00 55 lda unroll_and_addr_hi,y ;get address of instruction, high byte
8d3f: 85 11 sta ]instr_ptr+1 ;set high byte of pointer
8d41: b9 00 b7 lda unroll_a_o_addr_lo,y ;get address of instruction, low byte
8d44: a8 tay
8d45: 85 8a sta ]mod_offset ;save offset
8d47: a9 60 lda #INSTR_RTS
8d49: 91 10 sta (]instr_ptr),y ;replace the TXA with an RTS
8d4b: bc 40 a4 ldy elem_erase_2,x ;get top coordinate
8d4e: b9 00 b7 lda unroll_a_o_addr_lo,y ;copy instruction address to JSR instruction
8d51: 8d 64 8d sta _CallAnd0+1
8d54: b9 00 55 lda unroll_and_addr_hi,y
8d57: 8d 65 8d sta _CallAnd0+2
8d5a: bc 00 a4 ldy elem_erase_1,x ;get left edge column
8d5d: bd 40 a5 lda elem_erase_6,x ;get pixel bit mask
8d60: 49 ff eor #$ff ;invert to form AND mask
8d62: aa tax ;copy to X-reg
8d63: 20 76 a8 _CallAnd0 jsr AndSeq_90 ;execute unrolled AND sequence
8d66: a4 8a ldy ]mod_offset
8d68: a9 8a lda #INSTR_TXA
8d6a: 91 10 sta (]instr_ptr),y ;replace TXA instruction
8d6c: a6 64 ldx cur_elem_index
8d6e: 4c 52 8e jmp DrawElement ;go draw the element in its new position
;
; Erases a filled rectangle.
;
; On entry:
; X-reg: element index
;
• Clear variables
]restore_ptr .var $10 {addr/2}
]left_col .var $86 {addr/1}
]right_col .var $87 {addr/1}
]restore_index .var $8a {addr/1}
]left_pixel_mask .var $8c {addr/1}
]odd_even_mask .var $90 {addr/1}
]elem_color .var $91 {addr/1}
8d71: bd c0 a4 EraseRect lda elem_erase_4,x ;get hi-res column of right edge
8d74: 85 87 sta ]right_col
8d76: bd 00 a4 lda elem_erase_1,x ;get hi-res column of left edge
8d79: 85 86 sta ]left_col
8d7b: bd 80 a0 lda elem_cur_colors,x ;get current element color
8d7e: 85 91 sta ]elem_color
8d80: 1d c0 a3 ora elem_erase_0,x ;merge nibbles with left edge color index
8d83: a8 tay
8d84: 29 08 and #%00001000 ;strip all but bit 3 to form odd/even mask
8d86: 85 90 sta ]odd_even_mask
8d88: b9 63 72 lda color_bit_masks_left,y ;get pixel bits for left edge
8d8b: 49 ff eor #$ff ;invert to form AND mask
8d8d: 85 8c sta ]left_pixel_mask
8d8f: 38 sec
8d90: a5 87 lda ]right_col ;compute (right - left - 3)
8d92: e5 86 sbc ]left_col
8d94: e9 03 sbc #$03
8d96: 85 b0 sta mid_col_count
8d98: 10 35 bpl :WideRect ;erasing 4+ columns, use STA
; Erasing 1-3 columns, use sequence of AND instructions.
8d9a: a9 8a lda #INSTR_TXA ;replacing TXA
8d9c: 85 af sta orig_opcode
8d9e: bc 00 a5 ldy elem_erase_5,x ;get bottom coord
8da1: c8 iny ;incr to get start of next group
8da2: b9 00 55 lda unroll_and_addr_hi,y ;get address of TXA instruction
8da5: 85 11 sta ]restore_ptr+1 ;save for later
8da7: b9 00 b7 lda unroll_a_o_addr_lo,y
8daa: a8 tay
8dab: 85 8a sta ]restore_index
8dad: a9 60 lda #INSTR_RTS
8daf: 91 10 sta (]restore_ptr),y ;replace with RTS instruction
8db1: bc 40 a4 ldy elem_erase_2,x ;get top coord
8db4: b9 00 b7 lda unroll_a_o_addr_lo,y ;get address of instruction group
8db7: 8d 08 8e sta _CallAnd1+1 ;modify the JSR instructions
8dba: 8d 2b 8e sta _CallAnd2+1
8dbd: 8d 48 8e sta _CallAnd3+1
8dc0: b9 00 55 lda unroll_and_addr_hi,y
8dc3: 8d 09 8e sta _CallAnd1+2
8dc6: 8d 2c 8e sta _CallAnd2+2
8dc9: 8d 49 8e sta _CallAnd3+2
8dcc: 4c 01 8e jmp :DoErase ;go erase stuff
; Erasing 4+ columns, use sequence of STA instructions.
8dcf: a9 99 :WideRect lda #INSTR_STA_ABS ;replacing STA
8dd1: 85 af sta orig_opcode
8dd3: bc 00 a5 ldy elem_erase_5,x ;get bottom coord
8dd6: c8 iny ;incr to get start of next group
8dd7: b9 00 57 lda unroll_sta_hi,y ;get address of STA instruction
8dda: 85 11 sta ]restore_ptr+1 ;save for later
8ddc: b9 00 56 lda unroll_sta_lo,y
8ddf: a8 tay
8de0: 85 8a sta ]restore_index
8de2: a9 60 lda #INSTR_RTS
8de4: 91 10 sta (]restore_ptr),y ;replace with RTS instruction
8de6: bc 40 a4 ldy elem_erase_2,x ;get top coord
8de9: b9 00 56 lda unroll_sta_lo,y ;get address of instruction group
8dec: 8d 08 8e sta _CallAnd1+1 ;modify the JSR instructions
8def: 8d 2b 8e sta _CallAnd2+1
8df2: 8d 48 8e sta _CallAnd3+1
8df5: b9 00 57 lda unroll_sta_hi,y
8df8: 8d 09 8e sta _CallAnd1+2
8dfb: 8d 2c 8e sta _CallAnd2+2
8dfe: 8d 49 8e sta _CallAnd3+2
; Erase left edge.
8e01: a9 00 :DoErase lda #$00 ;for STA, we write $00
8e03: a6 8c ldx ]left_pixel_mask ;for AND, we mask
8e05: a4 86 ldy ]left_col
8e07: 20 61 a8 _CallAnd1 jsr AndSeq_87 ;perform unrolled AND or STA sequence
8e0a: e6 86 inc ]left_col ;advance to next column
8e0c: a5 86 lda ]left_col
8e0e: c5 87 cmp ]right_col ;have we reached the right column?
8e10: f0 23 beq :EraseRectRt ;yes, erase that
8e12: 30 03 bmi :EraseRectMid ;no, erase middle
8e14: 4c 4a 8e jmp :EraseRectDone ;past it, erase is done
8e17: a5 90 :EraseRectMid lda ]odd_even_mask
8e19: 49 08 eor #$08 ;flip odd/even
8e1b: 85 90 sta ]odd_even_mask
8e1d: 05 91 ora ]elem_color ;merge nibble with current element color
8e1f: a8 tay
8e20: b9 63 72 lda color_bit_masks_left,y ;get full-byte color pixel mask
8e23: 49 ff eor #$ff ;invert to form AND mask
8e25: aa tax ;copy to X-reg for AND sequence
8e26: a4 86 ldy ]left_col ;get column
8e28: a9 00 lda #$00 ;set A-reg to $00 for STA
8e2a: 20 61 a8 _CallAnd2 jsr AndSeq_87 ;perform unrolled AND or STA sequence
8e2d: e6 86 inc ]left_col ;advance to next column
8e2f: a5 86 lda ]left_col
8e31: c5 87 cmp ]right_col ;have we reached the right column?
8e33: 30 e2 bmi :EraseRectMid ;not yet, loop
8e35: a6 64 :EraseRectRt ldx cur_elem_index
8e37: bd 80 a4 lda elem_erase_3,x ;get right edge pixel color offset
8e3a: 05 91 ora ]elem_color ;merge nibble with current element color
8e3c: a8 tay
8e3d: b9 d3 72 lda color_bit_masks_right,y ;get full-byte color pixel mask
8e40: 49 ff eor #$ff ;invert to form AND mask
8e42: aa tax ;copy to X-reg for AND sequence
8e43: a4 87 ldy ]right_col ;get column
8e45: a9 00 lda #$00 ;set A-reg to $00 for STA
8e47: 20 61 a8 _CallAnd3 jsr AndSeq_87 ;perform unrolled AND or STA sequence
8e4a: 4c 70 5a :EraseRectDone jmp AfterEraseRect ;draw crosshairs, then restore instruction
8e4d: 8a .junk 1
;
; Finishes the erase-rect operation by restoring the opcode in the unrolled op
; sequence, then falling into the draw routine.
;
8e4e: a5 af AfterEraseRect1 lda orig_opcode
8e50: 91 10 sta (]restore_ptr),y ;restore opcode
;
; Draws an element.
;
; On entry:
; X-reg: element index
;
8e52: a5 c8 DrawElement lda sound_counters ;do sound stuff
8e54: f0 03 beq :NoSound
8e56: ad 30 c0 lda SPKR
8e59: a5 72 :NoSound lda no_draw_obj_flag
8e5b: 05 7c ora no_draw_elem_flag?
8e5d: f0 13 beq :UpdateColor
8e5f: a9 82 :NoDraw lda #$82
8e61: 9d 80 9f sta elem_mod_types,x ;set mod type to "do not draw"
8e64: 20 7f 7f jsr Return7f7f
8e67: ad 82 8c lda unused_flag_merge ;update this location; results never used
8e6a: 05 7a ora elem_bad_z_flag?
8e6c: 8d 82 8c sta unused_flag_merge
8e6f: 4c 16 92 jmp ElemDrawDone
8e72: e6 a1 :UpdateColor inc drawn_elem_count
8e74: bd c0 a0 lda elem_colorchanges,x ;get the color change counter
8e77: f0 27 beq :NoChanges ;zero, no changes for this one
8e79: de 00 a1 dec elem_colorchange_ctrs,x ;decrement the counter
8e7c: 10 1d bpl :NotYet ;not time to change yet, branch
8e7e: bd c0 a0 lda elem_colorchanges,x
8e81: 9d 00 a1 sta elem_colorchange_ctrs,x ;reset the counter
8e84: bd 00 a0 lda elem_colorsA,x
8e87: dd 80 a0 cmp elem_cur_colors,x ;is it currently colorA?
8e8a: 20 7f 7f jsr Return7f7f
8e8d: f0 06 beq :UseB ;yes, use B
8e8f: 9d 80 a0 sta elem_cur_colors,x ;no, use A
8e92: 4c 9b 8e jmp :NotYet
8e95: bd 40 a0 :UseB lda elem_colorsB,x
8e98: 9d 80 a0 sta elem_cur_colors,x
8e9b: bd 80 a0 :NotYet lda elem_cur_colors,x ;get the color
8e9e: 30 bf bmi :NoDraw ;>= $80, don't draw the element
8ea0: a5 70 :NoChanges lda mod_elem_type ;get mod type set by update-element code
8ea2: 9d 80 9f sta elem_mod_types,x ;set as type in table
8ea5: f0 15 beq DrawPoint ;$00, draw point
8ea7: 10 10 bpl :JmpDrawHoriz ;$01, draw horizontal line
8ea9: 0a asl A
8eaa: f0 0a beq :JmpDrawVert ;$80, draw vertical line
8eac: a9 81 lda #$81 ;rect
8eae: 9d 80 9f sta elem_mod_types,x ;set mod type (should already be $81?)
8eb1: 85 70 sta mod_elem_type ;set in ZP as well (should already be $81?)
8eb3: 4c a6 90 jmp DrawRect
8eb6: 4c 07 90 :JmpDrawVert jmp DrawVertLine
8eb9: 4c 1f 8f :JmpDrawHoriz jmp DrawHorizLine
;
; Draws a point.
;
; On entry:
; X-reg: element index
; $7e: top screen coordinate (0-191)
; $82: abs val of left screen coordinate (0-139)
;
; On exit:
; X-reg: preserved
;
• Clear variables
]hpage_ptr .var $10 {addr/2}
]top_coord .var $7e {addr/1}
]left_coord_abs .var $82 {addr/1}
]hires_col .var $86 {addr/1}
8ebc: 18 DrawPoint clc ;do sound stuff
8ebd: a5 b2 lda engine_sound_ctr?+1
8ebf: 69 09 adc #$09
8ec1: 85 b2 sta engine_sound_ctr?+1
8ec3: 90 0f bcc :NoSound
8ec5: e6 b3 inc engine_sound_ctr?+2
8ec7: a5 cc lda engine_sound_enable
8ec9: f0 09 beq :NoSound
8ecb: a5 b3 lda engine_sound_ctr?+2
8ecd: 25 b1 and engine_sound_ctr?
8ecf: d0 03 bne :NoSound
8ed1: ad 30 c0 lda SPKR
8ed4: a4 82 :NoSound ldy ]left_coord_abs ;get absolute value of left coord
8ed6: bd 00 a2 lda elem_left_hi,x ;get left coord high byte
8ed9: 30 0b bmi :NegLeft ;negative, branch
8edb: b9 00 bc lda pos_xc_to_col,y ;convert coordinate to column (20-39)
8ede: 85 86 sta ]hires_col
8ee0: b9 00 be lda pos_xc_to_color_idx,y ;get pixel color index
8ee3: 4c ee 8e jmp :Cont
8ee6: b9 00 bd :NegLeft lda neg_xc_to_col,y ;convert coordinate to column (0-19)
8ee9: 85 86 sta ]hires_col
8eeb: b9 00 bf lda neg_xc_to_color_idx,y ;get pixel color index
8eee: 1d 80 a0 :Cont ora elem_cur_colors,x ;get high nibble of current color
8ef1: a8 tay
8ef2: b9 c3 71 lda color_bit_masks_thin,y ;get the bit pattern for the color
8ef5: 9d 40 a5 sta elem_erase_6,x
8ef8: a4 7e ldy ]top_coord ;get top coord
8efa: 18 clc
8efb: a5 86 lda ]hires_col ;get the column (byte offset)
8efd: 79 00 ba adc hires_addr_lo,y ;add the low byte of the hi-res line address
8f00: 9d c0 a3 sta elem_erase_0,x ;save that for erase time
8f03: b9 00 bb lda hires_addr_hi,y ;get the high byte of the hi-res line address
8f06: 69 00 adc #$00
8f08: 9d 00 a4 sta elem_erase_1,x ;save that as well
8f0b: 85 11 sta ]hpage_ptr+1
8f0d: bd 80 a0 lda elem_cur_colors,x ;get color
8f10: f0 0a beq :IsBlack ;black, ORA will do nothing
8f12: bc c0 a3 ldy elem_erase_0,x
8f15: b1 10 lda (]hpage_ptr),y
8f17: 1d 40 a5 ora elem_erase_6,x
8f1a: 91 10 sta (]hpage_ptr),y
8f1c: 4c 16 92 :IsBlack jmp ElemDrawDone
;
; Draws a horizontal line.
;
; The pixels are ORed onto the screen, blending the current contents.
;
; On entry:
; X-reg: element index
; $7e: screen Y coordinate (0-191)
; $82: screen left X coordinate magnitude (0-139)
; $84: screen right X coordinate magnitude (0-139)
;
• Clear variables
]hptr .var $18 {addr/2}
]ycoord .var $7e {addr/1}
]left_mag .var $82 {addr/1}
]right_mag .var $84 {addr/1}
]index_tmp .var $86 {addr/1}
]right_col .var $87 {addr/1}
]color0 .var $89 {addr/1}
]odd_even_mask .var $90 {addr/1}
]color1 .var $91 {addr/1}
8f1f: 18 DrawHorizLine clc ;do sound stuff
8f20: a5 b2 lda engine_sound_ctr?+1
8f22: 69 23 adc #$23
8f24: 85 b2 sta engine_sound_ctr?+1
8f26: 90 0f bcc :NoSound
8f28: e6 b3 inc engine_sound_ctr?+2
8f2a: a5 cc lda engine_sound_enable
8f2c: f0 09 beq :NoSound
8f2e: a5 b3 lda engine_sound_ctr?+2
8f30: 25 b1 and engine_sound_ctr?
8f32: d0 03 bne :NoSound
8f34: ad 30 c0 lda SPKR
8f37: a4 82 :NoSound ldy ]left_mag ;get magnitude of X coord for left end
8f39: bd 00 a2 lda elem_left_hi,x ;check sign
8f3c: 30 0c bmi :IsNegL
8f3e: b9 00 bc lda pos_xc_to_col,y ;get column from positive table
8f41: 9d 00 a4 sta elem_erase_1,x
8f44: b9 00 be lda pos_xc_to_color_idx,y ;get coord color index
8f47: 4c 53 8f jmp :ContL
8f4a: b9 00 bd :IsNegL lda neg_xc_to_col,y ;get column from negative table
8f4d: 9d 00 a4 sta elem_erase_1,x
8f50: b9 00 bf lda neg_xc_to_color_idx,y ;get coord color index
8f53: 9d c0 a3 :ContL sta elem_erase_0,x
8f56: a4 84 ldy ]right_mag ;get magnitude of X coord for right end
8f58: bd 00 a3 lda elem_right_hi,x ;check sign
8f5b: 30 0e bmi :IsNegR
8f5d: b9 00 bc lda pos_xc_to_col,y ;get column from positive table
8f60: 9d c0 a4 sta elem_erase_4,x
8f63: 85 87 sta ]right_col
8f65: b9 00 be lda pos_xc_to_color_idx,y ;get coord color index
8f68: 4c 76 8f jmp :ContR
8f6b: b9 00 bd :IsNegR lda neg_xc_to_col,y ;get column from negative table
8f6e: 9d c0 a4 sta elem_erase_4,x
8f71: 85 87 sta ]right_col
8f73: b9 00 bf lda neg_xc_to_color_idx,y ;get coord color index
8f76: 9d 80 a4 :ContR sta elem_erase_3,x
;
8f79: a4 7e ldy ]ycoord ;get Y coordinate for line
8f7b: b9 00 bb lda hires_addr_hi,y ;get hi-res line base address
8f7e: 9d 00 a5 sta elem_erase_5,x
8f81: 85 19 sta ]hptr+1 ;set up the pointer
8f83: b9 00 ba lda hires_addr_lo,y
8f86: 9d 40 a4 sta elem_erase_2,x
8f89: 85 18 sta ]hptr
; Draw partial byte for left end of line.
8f8b: bd 80 a0 lda elem_cur_colors,x ;get current element color (high nibble)
8f8e: f0 74 beq :DrawDone ;black, do nothing
8f90: 1d c0 a3 ora elem_erase_0,x ;get element color (low nibble)
8f93: a8 tay
8f94: 29 08 and #%00001000 ;mask bit 3 so it's 0/8 for odd/even
8f96: 85 90 sta ]odd_even_mask
8f98: b9 63 72 lda color_bit_masks_left,y ;get pixel bit mask for left-side byte
8f9b: bc 00 a4 ldy elem_erase_1,x ;get column of left edge
8f9e: 11 18 ora (]hptr),y
8fa0: 91 18 sta (]hptr),y ;set pixels on hi-res screen
8fa2: c8 iny ;advance to next column
8fa3: c4 87 cpy ]right_col ;is right pixel in next column?
8fa5: f0 4d beq :RightSide ;yes, branch
8fa7: 10 5b bpl :DrawDone ;right/left pixels are in same byte, bail
; Draw middle. We set up odd vs. even and draw alternately.
8fa9: 84 86 sty ]index_tmp ;spill Y-reg
8fab: a5 90 lda ]odd_even_mask ;get color index (0 or 8)
8fad: 1d 80 a0 ora elem_cur_colors,x ;combine with current element color
8fb0: a8 tay
8fb1: b9 63 72 lda color_bit_masks_left,y ;get full-byte color bit mask
8fb4: 85 89 sta ]color0 ;save as first color
8fb6: a5 90 lda ]odd_even_mask
8fb8: 49 08 eor #$08 ;flip odd/even
8fba: 1d 80 a0 ora elem_cur_colors,x ;combine with current element color
8fbd: a8 tay
8fbe: b9 63 72 lda color_bit_masks_left,y ;get full-byte color bit mask
8fc1: 85 91 sta ]color1 ;save as second color
8fc3: a4 86 ldy ]index_tmp ;restore Y-reg (hi-res col)
8fc5: 18 clc
8fc6: a5 91 :MiddleLoop lda ]color1 ;get second color
8fc8: 11 18 ora (]hptr),y ;blend with hi-res screen
8fca: 91 18 sta (]hptr),y ;update screen
8fcc: c8 iny
8fcd: c4 87 cpy ]right_col ;have we reached right edge?
8fcf: 10 23 bpl :RightSide ;yes, go handle that
8fd1: 18 clc ;do sound stuff
8fd2: a5 b2 lda engine_sound_ctr?+1
8fd4: 69 07 adc #$07
8fd6: 85 b2 sta engine_sound_ctr?+1
8fd8: 90 0f bcc :NoSound
8fda: e6 b3 inc engine_sound_ctr?+2
8fdc: a5 cc lda engine_sound_enable
8fde: f0 09 beq :NoSound
8fe0: a5 b3 lda engine_sound_ctr?+2
8fe2: 25 b1 and engine_sound_ctr?
8fe4: d0 03 bne :NoSound
8fe6: ad 30 c0 lda SPKR
8fe9: a5 89 :NoSound lda ]color0 ;get first color
8feb: 11 18 ora (]hptr),y ;blend with hi-res screen
8fed: 91 18 sta (]hptr),y ;update screen
8fef: c8 iny
8ff0: c4 87 cpy ]right_col ;have we reached right edge?
8ff2: 30 d2 bmi :MiddleLoop ;no, keep going
; Draw partial byte for right end of line.
8ff4: bd 80 a4 :RightSide lda elem_erase_3,x ;get pixel color offset
8ff7: 1d 80 a0 ora elem_cur_colors,x ;combine with current element color
8ffa: a8 tay
8ffb: b9 d3 72 lda color_bit_masks_right,y ;get pixel bit mask
8ffe: a4 87 ldy ]right_col ;get index of right column
9000: 11 18 ora (]hptr),y ;blend with hi-res screen
9002: 91 18 sta (]hptr),y ;update screen
9004: 4c 16 92 :DrawDone jmp ElemDrawDone
;
; Draws a vertical line.
;
; The pixels are ORed onto the screen, blending the current contents.
;
; On entry:
; X-reg: element index
; $7e: top (0-191)
; $80: bottom (0-191)
; $82: abs value of left (0-139)
; $84: abs value of right (0-139)
;
• Clear variables
]restore_ptr .var $10 {addr/2}
]yc_top .var $7e {addr/1}
]yc_bottom .var $80 {addr/1}
]xc_left_abs .var $82 {addr/1}
]restore_index .var $8a {addr/1}
]color_mask .var $92 {addr/1}
9007: 18 DrawVertLine clc ;do sound stuff
9008: a5 b2 lda engine_sound_ctr?+1
900a: 69 20 adc #$20
900c: 85 b2 sta engine_sound_ctr?+1
900e: 90 0f bcc :NoSound
9010: e6 b3 inc engine_sound_ctr?+2
9012: a5 cc lda engine_sound_enable
9014: f0 09 beq :NoSound
9016: a5 b3 lda engine_sound_ctr?+2
9018: 25 b1 and engine_sound_ctr?
901a: d0 03 bne :NoSound
901c: ad 30 c0 lda SPKR
901f: a5 80 :NoSound lda ]yc_bottom
9021: 9d 00 a5 sta elem_erase_5,x ;save bottom coord
9024: e5 7e sbc ]yc_top ;do more sound stuff
9026: 0a asl A
9027: 65 b2 adc engine_sound_ctr?+1
9029: 85 b2 sta engine_sound_ctr?+1
902b: 90 0f bcc :NoSound
902d: e6 b3 inc engine_sound_ctr?+2
902f: a5 cc lda engine_sound_enable
9031: f0 09 beq :NoSound
9033: a5 b3 lda engine_sound_ctr?+2
9035: 25 b1 and engine_sound_ctr?
9037: d0 03 bne :NoSound
9039: ad 30 c0 lda SPKR
903c: a5 7e :NoSound lda ]yc_top
903e: 9d 40 a4 sta elem_erase_2,x ;save top coordinate
9041: bc 00 a5 ldy elem_erase_5,x ;get bottom coordinate
9044: c8 iny ;increment to get following instruction group
9045: b9 00 b8 lda unroll_ora_addr_hi,y ;get address of TXA instruction, high byte
9048: 85 11 sta ]restore_ptr+1 ;set pointer
904a: b9 00 b7 lda unroll_a_o_addr_lo,y ;get address of instruction, low byte
904d: a8 tay
904e: 85 8a sta ]restore_index
9050: a9 60 lda #INSTR_RTS
9052: 91 10 sta (]restore_ptr),y ;replace TXA with RTS
9054: bc 40 a4 ldy elem_erase_2,x ;get top coordinate
9057: b9 00 b7 lda unroll_a_o_addr_lo,y ;get address of corresponding ORA sequence
905a: 8d 99 90 sta _CallOra0+1 ;modify JSR call
905d: b9 00 b8 lda unroll_ora_addr_hi,y
9060: 8d 9a 90 sta _CallOra0+2
;
9063: a4 82 ldy ]xc_left_abs ;get absolute value of left X coord
9065: bd 00 a2 lda elem_left_hi,x ;get sign
9068: 30 0c bmi :IsNeg ;negative, branch
906a: b9 00 bc lda pos_xc_to_col,y ;get hi-res column of line
906d: 9d 00 a4 sta elem_erase_1,x ;save it
9070: b9 00 be lda pos_xc_to_color_idx,y ;get color index
9073: 4c 7f 90 jmp :Cont
9076: b9 00 bd :IsNeg lda neg_xc_to_col,y ;get hi-res column of line
9079: 9d 00 a4 sta elem_erase_1,x ;save it
907c: b9 00 bf lda neg_xc_to_color_idx,y ;get color index
907f: 9d c0 a3 :Cont sta elem_erase_0,x
9082: 1d 80 a0 ora elem_cur_colors,x ;OR with current element color nibble
9085: a8 tay
9086: b9 c3 71 lda color_bit_masks_thin,y ;get pixel mask for a single color pixel
9089: 9d 40 a5 sta elem_erase_6,x ;save it
908c: 85 92 sta ]color_mask
908e: bd 80 a0 lda elem_cur_colors,x ;get current color
9091: f0 08 beq :NoDraw ;it's black, skip drawing
9093: bc 00 a4 ldy elem_erase_1,x ;get hi-res column
9096: a6 92 ldx ]color_mask ;get pixel mask
9098: 20 6f 1a _CallOra0 jsr OraSeq_89 ;perform unrolled ORA sequence
909b: a4 8a :NoDraw ldy ]restore_index
909d: a9 8a lda #INSTR_TXA
909f: 91 10 sta (]restore_ptr),y ;change the RTS back to TXA
90a1: a6 64 ldx cur_elem_index
90a3: 4c 16 92 jmp ElemDrawDone ;done
;
; Draws a filled rectangle.
;
; On entry:
; X-reg: element index
; $7e: top (0-191)
; $80: bottom (0-191)
; $82: abs value of left (0-139)
; $84: abs value of right (0-139)
;
• Clear variables
]restore_ptr .var $10 {addr/2}
]yc_top .var $7e {addr/1}
]yc_bottom .var $80 {addr/1}
]xc_left_abs .var $82 {addr/1}
]xc_right_abs .var $84 {addr/1}
]left_col .var $88 {addr/1}
]right_col .var $89 {addr/1}
]restore_index .var $8a {addr/1}
]height_approx .var $8c {addr/1}
]pix_clr_idx_rt .var $8f {addr/1}
]odd_even_mask .var $90 {addr/1}
]cur_color .var $91 {addr/1}
]left_color_mask .var $92 {addr/1}
90a6: 18 DrawRect clc ;do sound stuff
90a7: a5 b2 lda engine_sound_ctr?+1
90a9: 69 2a adc #$2a
90ab: 85 b2 sta engine_sound_ctr?+1
90ad: 90 0f bcc :NoSound
90af: e6 b3 inc engine_sound_ctr?+2
90b1: a5 cc lda engine_sound_enable
90b3: f0 09 beq :NoSound
90b5: a5 b3 lda engine_sound_ctr?+2
90b7: 25 b1 and engine_sound_ctr?
90b9: d0 03 bne :NoSound
90bb: ad 30 c0 lda SPKR
90be: bd 80 a0 :NoSound lda elem_cur_colors,x ;get current color
90c1: 85 91 sta ]cur_color
90c3: a5 80 lda ]yc_bottom
90c5: 9d 00 a5 sta elem_erase_5,x ;save bottom coord
90c8: e5 7e sbc ]yc_top ;compute (bottom - top); carry undefined (bug?)
90ca: 85 8c sta ]height_approx
90cc: a5 7e lda ]yc_top
90ce: 9d 40 a4 sta elem_erase_2,x ;save top coord
; Set up right edge.
90d1: a4 84 ldy ]xc_right_abs ;get absolute value of X coord
90d3: bd 00 a3 lda elem_right_hi,x ;get sign (from eye coords)
90d6: 30 0e bmi :IsNegR
90d8: b9 00 bc lda pos_xc_to_col,y ;get hi-res column for right edge
90db: 9d c0 a4 sta elem_erase_4,x ;save it
90de: 85 89 sta ]right_col
90e0: b9 00 be lda pos_xc_to_color_idx,y ;get pixel color index
90e3: 4c f1 90 jmp :ContR
90e6: b9 00 bd :IsNegR lda neg_xc_to_col,y ;get hi-res colum for right edge
90e9: 9d c0 a4 sta elem_erase_4,x ;save it
90ec: 85 89 sta ]right_col
90ee: b9 00 bf lda neg_xc_to_color_idx,y ;get pixel color index
90f1: 9d 80 a4 :ContR sta elem_erase_3,x ;save it
90f4: 85 8f sta ]pix_clr_idx_rt
; Set up left edge.
90f6: a4 82 ldy ]xc_left_abs ;get absolute value of X coord
90f8: bd 00 a2 lda elem_left_hi,x ;get sign
90fb: 30 0c bmi :IsNegL
90fd: b9 00 bc lda pos_xc_to_col,y ;get hi-res column for left edge
9100: 9d 00 a4 sta elem_erase_1,x ;save it
9103: b9 00 be lda pos_xc_to_color_idx,y ;get pixel color index
9106: 4c 12 91 jmp :ContL
9109: b9 00 bd :IsNegL lda neg_xc_to_col,y ;get hi-res column for right edge
910c: 9d 00 a4 sta elem_erase_1,x ;save it
910f: b9 00 bf lda neg_xc_to_color_idx,y ;get pixel color index
9112: 9d c0 a3 :ContL sta elem_erase_0,x
9115: 05 91 ora ]cur_color ;combine nibbles with element color
9117: a8 tay
9118: 29 08 and #%00001000 ;strip all but bit 3 to get odd/even mask
911a: 85 90 sta ]odd_even_mask
911c: a5 91 lda ]cur_color ;check color
911e: d0 03 bne :NotBlack ;not black, keep going
9120: 4c 16 92 jmp ElemDrawDone
9123: b9 63 72 :NotBlack lda color_bit_masks_left,y
9126: 85 92 sta ]left_color_mask
9128: bc 00 a4 ldy elem_erase_1,x ;get hi-res column of left edge
912b: 84 88 sty ]left_col
912d: 38 sec
912e: a5 89 lda ]right_col ;compute (right - left - 3)
9130: e5 88 sbc ]left_col
9132: e9 03 sbc #$03
9134: 85 b0 sta mid_col_count
9136: 10 35 bpl :WideRect ;touch 4+ columns, use STA
; We touch 1-3 columns, use ORA for all parts.
9138: a9 8a lda #INSTR_TXA ;replacing a TXA instruction
913a: 85 af sta orig_opcode
913c: bc 00 a5 ldy elem_erase_5,x ;get bottom coordinate
913f: c8 iny ;increment so we're at start of next group
9140: b9 00 b8 lda unroll_ora_addr_hi,y ;get address of instruction, high byte
9143: 85 11 sta ]restore_ptr+1
9145: b9 00 b7 lda unroll_a_o_addr_lo,y ;get address of instruction, low byte
9148: a8 tay
9149: 85 8a sta ]restore_index
914b: a9 60 lda #INSTR_RTS
914d: 91 10 sta (]restore_ptr),y ;replace TXA with RTS
914f: bc 40 a4 ldy elem_erase_2,x ;get top coordinate
9152: b9 00 b7 lda unroll_a_o_addr_lo,y ;copy address of instruction group to JSRs
9155: 8d a5 91 sta _CallOraSta1+1
9158: 8d c4 91 sta _CallOraSta2+1
915b: 8d f2 91 sta _CallOraSta3+1
915e: b9 00 b8 lda unroll_ora_addr_hi,y
9161: 8d a6 91 sta _CallOraSta1+2
9164: 8d c5 91 sta _CallOraSta2+2
9167: 8d f3 91 sta _CallOraSta3+2
916a: 4c 9f 91 jmp :DoDraw ;go draw
; We touch 4+ columns, use STA for middle and edges.
916d: a9 99 :WideRect lda #INSTR_STA_ABS ;replacing a STA instruction
916f: 85 af sta orig_opcode
9171: bc 00 a5 ldy elem_erase_5,x ;get bottom coord
9174: c8 iny ;increment so we're at start of next group
9175: b9 00 57 lda unroll_sta_hi,y ;get address of instruction, high byte
9178: 85 11 sta ]restore_ptr+1
917a: b9 00 56 lda unroll_sta_lo,y ;get address of instruction, low byte
917d: a8 tay
917e: 85 8a sta ]restore_index
9180: a9 60 lda #INSTR_RTS
9182: 91 10 sta (]restore_ptr),y ;replace STA with RTS
9184: bc 40 a4 ldy elem_erase_2,x ;get top coord
9187: b9 00 56 lda unroll_sta_lo,y ;copy address of instruction group to JSRs
918a: 8d a5 91 sta _CallOraSta1+1
918d: 8d c4 91 sta _CallOraSta2+1
9190: 8d f2 91 sta _CallOraSta3+1
9193: b9 00 57 lda unroll_sta_hi,y
9196: 8d a6 91 sta _CallOraSta1+2
9199: 8d c5 91 sta _CallOraSta2+2
919c: 8d f3 91 sta _CallOraSta3+2
; Draw left edge.
919f: a6 92 :DoDraw ldx ]left_color_mask ;get color bits for left edge
91a1: 8a txa ;need in A-reg for STA, X-reg for ORA
91a2: a4 88 ldy ]left_col ;get column
91a4: 20 5a 1a _CallOraSta1 jsr OraSeq_86 ;perform unrolled STA or ORA sequence
91a7: e6 88 inc ]left_col ;advance to next column
91a9: a5 88 lda ]left_col
91ab: c5 89 cmp ]right_col ;are we at right column?
91ad: f0 37 beq :DrawRight ;yes, draw that
91af: 30 03 bmi :DrawMiddle ;not yet, draw middle
91b1: 4c f6 91 jmp :RectDone ;past it, must be single column; we're done
91b4: a5 90 :DrawMiddle lda ]odd_even_mask
91b6: 49 08 eor #$08 ;flip odd/even
91b8: 85 90 sta ]odd_even_mask
91ba: 05 91 ora ]cur_color ;merge nibbles with current element color
91bc: a8 tay ; to form index for whole-byte color
91bd: b9 63 72 lda color_bit_masks_left,y ;get pixel bit mask
91c0: aa tax ;need in A-reg for STA, X-reg for ORA
91c1: a4 88 ldy ]left_col ;get column
91c3: 20 5a 1a _CallOraSta2 jsr OraSeq_86 ;perform unrolled STA or ORA sequence
;
91c6: 18 clc ;do sound stuff
91c7: a5 b2 lda engine_sound_ctr?+1
91c9: 65 8c adc ]height_approx
91cb: 85 b2 sta engine_sound_ctr?+1
91cd: 90 0f bcc :NoSound
91cf: e6 b3 inc engine_sound_ctr?+2
91d1: a5 cc lda engine_sound_enable
91d3: f0 09 beq :NoSound
91d5: a5 b3 lda engine_sound_ctr?+2
91d7: 25 b1 and engine_sound_ctr?
91d9: d0 03 bne :NoSound
91db: ad 30 c0 lda SPKR
91de: e6 88 :NoSound inc ]left_col ;advance to next column
91e0: a5 88 lda ]left_col
91e2: c5 89 cmp ]right_col ;are we at right column?
91e4: 30 ce bmi :DrawMiddle ;not yet, loop
91e6: a5 8f :DrawRight lda ]pix_clr_idx_rt ;get pixel color index for right edge
91e8: 05 91 ora ]cur_color ;merge nibbles with current element color
91ea: a8 tay
91eb: b9 d3 72 lda color_bit_masks_right,y ;get pixel bit mask
91ee: a4 89 ldy ]right_col ;get column
91f0: aa tax ;need in A-reg for STA, X-reg for ORA
91f1: 20 5a 1a _CallOraSta3 jsr OraSeq_86 ;perform unrolled STA or ORA sequence
;
91f4: 06 8c asl ]height_approx ;do sound stuff
91f6: 18 :RectDone clc
91f7: a5 b2 lda engine_sound_ctr?+1
91f9: 65 8c adc ]height_approx
91fb: 85 b2 sta engine_sound_ctr?+1
91fd: 90 0f bcc :NoSound
91ff: e6 b3 inc engine_sound_ctr?+2
9201: a5 cc lda engine_sound_enable
9203: f0 09 beq :NoSound
9205: a5 b3 lda engine_sound_ctr?+2
9207: 25 b1 and engine_sound_ctr?
9209: d0 03 bne :NoSound
920b: ad 30 c0 lda SPKR
920e: a6 64 :NoSound ldx cur_elem_index ;get element index in X-reg
9210: a4 8a ldy ]restore_index ;get index of byte we need to restore
9212: a5 af lda orig_opcode ;get original opcode
9214: 91 10 sta (]restore_ptr),y ;restore the opcode we overwrote
;
; Done drawing an element. Move to the next one.
;
9216: a5 c8 ElemDrawDone lda sound_counters ;do sound stuff
9218: f0 03 beq :NoSound
921a: ad 30 c0 lda SPKR
921d: bd 40 9f :NoSound lda elem_next_elem,x ;get index of next element
9220: 30 08 bmi NextObject ;found end of list for this object; branch
9222: aa tax ;copy to X-reg
9223: 86 64 stx cur_elem_index ;save a copy here
9225: e6 a5 inc wronly_a5?
9227: 4c 83 8c jmp RedrawElement ;erase and redraw it
;
; Done drawing object. Move to the next one.
;
• Clear variables
]tmp_obj_index .var $8c {addr/1}
922a: a5 ca NextObject lda sound_counters+2 ;do sound stuff
922c: f0 03 beq :NoSound
922e: ad 30 c0 lda SPKR ;click for sfx (player cannon, ship explosion)
9231: a6 62 :NoSound ldx cur_obj_index
9233: 20 7f 7f jsr Return7f7f
9236: bd 50 9a lda obj_next_obj,x ;get index of next object
9239: 85 8c sta ]tmp_obj_index
923b: a5 a1 lda drawn_elem_count ;check drawn element count
923d: d0 0c bne :Jmp_NextObject1 ;we drew at least one, keep it around
923f: bd a0 9a lda obj_shape_uid,x ;get the shape ID
9242: 29 f0 and #$f0
9244: c9 f0 cmp #$f0 ;is it $Fn?
9246: f0 06 beq UnusedThing? ;yes, do special thing
:Jmp_ObjOffScreen
9248: 4c 24 93 jmp ObjectOffScreen ;no, kill the object, possibly with special behavior
:Jmp_NextObject1
924b: 4c 18 93 jmp NextObject1
;
; Draws a direction in place of the ammunition count. This doesn't appear to be
; used.
;
; (If you change the code above with 9245:50, you can see it trying to show
; which way you need to move while flying through a time portal. However, it
; flashes conflicting messages and fights with the rendering of the ammunition
; count, so it's possible this feature was abandoned before completion.)
;
• Clear variables
]screen_left .var $86 {addr/2}
]screen_top .var $88 {addr/2}
]screen_left_abs .var $8c {addr/2}
924e: bd 18 9b UnusedThing? lda obj_activity_state,x
9251: 30 f5 bmi :Jmp_ObjOffScreen
9253: ad 3b 6d lda game_active_flag ;are we in demo mode?
9256: f0 f0 beq :Jmp_ObjOffScreen ;yes, branch
9258: bc 00 9a ldy obj_first_elem_index,x
925b: a9 02 lda #$02
925d: 85 a9 sta wronly_a9?
925f: b9 40 a2 lda elem_top_lo,y
9262: 85 88 sta ]screen_top
9264: b9 80 a2 lda elem_top_hi,y
9267: 85 89 sta ]screen_top+1
9269: b9 c0 a1 lda elem_left_lo,y
926c: 85 86 sta ]screen_left
926e: b9 00 a2 lda elem_left_hi,y
9271: 85 87 sta ]screen_left+1
9273: a5 87 lda ]screen_left+1 ;(?)
9275: 10 0d bpl :PosLeft1
9277: 49 ff eor #$ff ;negate (without +1)
9279: 85 8d sta ]screen_left_abs+1
927b: a5 86 lda ]screen_left
927d: 49 ff eor #$ff
927f: 85 8c sta ]screen_left_abs
9281: 4c 8a 92 jmp :GotAbs
9284: 85 8d :PosLeft1 sta ]screen_left_abs+1
9286: a5 86 lda ]screen_left
9288: 85 8c sta ]screen_left_abs
928a: a5 89 :GotAbs lda ]screen_top+1
928c: 10 02 bpl :PosLeft2
928e: 49 ff eor #$ff
9290: c5 8d :PosLeft2 cmp ]screen_left_abs+1
9292: f0 06 beq :CheckTop
9294: 10 13 bpl L92A9
9296: 18 clc
9297: 4c b6 92 jmp L92B6
929a: a5 88 :CheckTop lda ]screen_top
929c: a4 89 ldy ]screen_top+1
929e: 10 02 bpl L92A2
92a0: 49 ff eor #$ff
92a2: c5 8c L92A2 cmp ]screen_left_abs
92a4: 90 10 bcc L92B6
92a6: 4c b3 92 jmp L92B3
92a9: 85 8d L92A9 sta ]screen_left_abs+1
92ab: a5 88 lda ]screen_top
92ad: a4 89 ldy ]screen_top+1
92af: 10 02 bpl L92B3
92b1: 49 ff eor #$ff
92b3: 85 8c L92B3 sta ]screen_left_abs
92b5: 38 sec
92b6: 90 52 L92B6 bcc :RightOrLeft
92b8: a5 89 lda ]screen_top+1
92ba: 10 49 bpl :Below
; This appears to flash a direction (ABOVE, BELOW, LEFT, RIGHT) in place of the
; ammunition count.
92bc: a9 00 lda #$00
92be: 85 8c :SetDir sta ]screen_left_abs ;save string index
92c0: ad cd 6d lda frame_counter
92c3: 29 02 and #$02
92c5: f0 1b beq :EraseAmunCount ;erase instead of draw this frame
92c7: a2 1b ldx #27 ;first column under "AMUN"
92c9: a5 8c lda ]screen_left_abs ;(?)
92cb: 85 8c sta ]screen_left_abs ;(?)
92cd: a4 8c :CharLoop ldy ]screen_left_abs ;get char index
92cf: b9 ad 6e lda text_position,y ;get char
92d2: 20 27 74 jsr PrintCharLine9 ;print char
92d5: e6 8c inc ]screen_left_abs ;advance char index
92d7: e0 20 cpx #32 ;printed 5 chars?
92d9: ea nop
92da: 30 f1 bmi :CharLoop ;not yet, branch
92dc: ea nop
92dd: a6 62 ldx cur_obj_index ;put object index in X-reg
92df: 4c 18 93 jmp NextObject1 ;back to work
; Erases 5 characters under "AMUN ". Probably used to make the direction flash.
92e2: a2 1b :EraseAmunCount ldx #27
92e4: a9 00 :Loop lda #$00
92e6: 9d 80 24 sta HIRES_P1+$480,x ;line 9
92e9: 9d 80 28 sta HIRES_P1+$880,x ; ...
92ec: 9d 80 2c sta HIRES_P1+$c80,x
92ef: 9d 80 30 sta HIRES_P1+$1080,x
92f2: 9d 80 38 sta HIRES_P1+$1880,x
92f5: 9d 80 34 sta HIRES_P1+$1480,x
92f8: 9d 80 3c sta HIRES_P1+$1c80,x ;line 15
92fb: e8 inx
92fc: e0 20 cpx #32 ;erased 5 bytes?
92fe: 30 e4 bmi :Loop
9300: a6 62 ldx cur_obj_index ;put object index in X-reg
9302: 4c 18 93 jmp NextObject1 ;back to work
9305: a9 05 :Below lda #5
9307: 4c be 92 jmp :SetDir
930a: a5 87 :RightOrLeft lda ]screen_left+1
930c: 30 05 bmi :Left
930e: a9 0a lda #10
9310: 4c be 92 jmp :SetDir
9313: a9 0f :Left lda #15
9315: 4c be 92 jmp :SetDir
; Check for some special conditions.
9318: a5 72 NextObject1 lda no_draw_obj_flag ;is the "no draw" flag set?
931a: d0 08 bne ObjectOffScreen ;yes, branch
931c: bd 18 9b lda obj_activity_state,x ;is the object going away?
931f: 30 03 bmi ObjectOffScreen ;yes, branch
9321: 4c 9f 94 jmp CheckPlyrHit ;alive and well, go check for collisions
;
; Handles an object that is no longer on-screen. If it's a friendly base or
; time portal, and we "collided" with the center, do the special behavior.
;
; If we're done with the object, we want to free up the object and element
; slots.
;
; On entry:
; X-reg: object index
;
• Clear variables
]abs_coord_diff .var $86 {addr/2}
]shape_class_nib .var $88 {addr/1}
9324: e6 72 ObjectOffScreen inc no_draw_obj_flag
9326: bd a0 9a lda obj_shape_uid,x ;get shape ID
9329: 29 f0 and #$f0
932b: 85 88 sta ]shape_class_nib
932d: c9 60 cmp #$60 ;friendly base ($61) or time portal ($6f)?
932f: f0 07 beq :IsFriendly
9331: c9 50 cmp #$50 ;time portal boundary ($5x)?
9333: f0 03 beq :IsFriendly
9335: 4c f7 93 jmp :FriendlyCollDone
9338: a9 00 :IsFriendly lda #$00
933a: 85 f8 sta elem_collision_flag
933c: bd 18 9b lda obj_activity_state,x
933f: 10 03 bpl :CheckCenterColl
9341: 4c f7 93 jmp :FriendlyCollDone
; Check for collision with first element, which is a point in the middle of the
; gap.
:CheckCenterColl
9344: bc 00 9a ldy obj_first_elem_index,x ;get index of first element
9347: b9 c0 a1 lda elem_left_lo,y ;copy left coordinate to ZP
934a: 85 86 sta ]abs_coord_diff
934c: b9 00 a2 lda elem_left_hi,y
934f: 85 87 sta ]abs_coord_diff+1
9351: 10 0a bpl :LeftPos
9353: 49 ff eor #$ff ;negate to get abs val
9355: 85 87 sta ]abs_coord_diff+1
9357: a5 86 lda ]abs_coord_diff
9359: 49 ff eor #$ff
935b: 85 86 sta ]abs_coord_diff
935d: bd b8 9b :LeftPos lda hitbox_size_lo,x ;get object hitbox size
9360: c5 86 cmp ]abs_coord_diff ;compare to coordinate difference
9362: bd e0 9b lda hitbox_size_hi,x
9365: e5 87 sbc ]abs_coord_diff+1
9367: 30 30 bmi :Missed ;missed, branch
9369: b9 40 a2 lda elem_top_lo,y ;copy top coordinate to ZP
936c: 85 86 sta ]abs_coord_diff
936e: b9 80 a2 lda elem_top_hi,y
9371: 85 87 sta ]abs_coord_diff+1
9373: 10 0a bpl :TopPos
9375: 49 ff eor #$ff ;negate to get abs val
9377: 85 87 sta ]abs_coord_diff+1
9379: a5 86 lda ]abs_coord_diff
937b: 49 ff eor #$ff
937d: 85 86 sta ]abs_coord_diff
937f: bd b8 9b :TopPos lda hitbox_size_lo,x ;get object hitbox size
9382: c5 86 cmp ]abs_coord_diff ;compare to coordinate difference
9384: bd e0 9b lda hitbox_size_hi,x
9387: e5 87 sbc ]abs_coord_diff+1
9389: 30 0e bmi :Missed ;missed, branch
; We flew into something. See what it was.
938b: a5 88 lda ]shape_class_nib
938d: c9 50 cmp #$50 ;was it a time portal boundary?
938f: d0 3c bne :HitNonBound ;no, branch
9391: a9 00 lda #$00 ;yes, we passed through center of portal bound obj
9393: 8d 98 6d sta time_portal_fail_ctr ;reset counter
9396: 4c f7 93 jmp :FriendlyCollDone
9399: a5 88 :Missed lda ]shape_class_nib
939b: c9 50 cmp #$50 ;was it a time portal boundary?
939d: d0 29 bne :MissedNonBound ;no, branch
; Flew outside a portal boundary.
939f: ee 98 6d inc time_portal_fail_ctr ;increment fail counter
93a2: 38 sec
93a3: ad 61 6d lda region_progress_ctr ;advance progress tracker
93a6: e9 00 sbc #$00
93a8: 8d 61 6d sta region_progress_ctr
93ab: ad 62 6d lda region_progress_ctr+1
93ae: e9 04 sbc #$04
93b0: 8d 62 6d sta region_progress_ctr+1
93b3: a9 01 lda #$01
93b5: 85 a0 sta impact_flash_ctr ;flash once
93b7: ad 48 6d lda sound_disab_flag ;do sound stuff
93ba: d0 3b bne :FriendlyCollDone
93bc: a9 01 lda #$01
93be: 85 fa sta impact_sound_flag
93c0: a9 fe lda #$fe ;(?)
93c2: 20 f0 0f jsr Return0ff0
93c5: 4c f7 93 jmp :FriendlyCollDone
; Flew outside center of a non-portal-boundary object.
93c8: ea :MissedNonBound nop
93c9: ea nop
93ca: 4c f7 93 jmp :FriendlyCollDone
; Flew through middle of something other than portal boundary.
93cd: bd a0 9a :HitNonBound lda obj_shape_uid,x ;get shape identifier
93d0: c9 6f cmp #$6f ;is it a time warp?
93d2: d0 06 bne :GiveRsrc ;no, must be base; branch
93d4: 8d 99 6d sta entered_portal_flag ;yes, set "in time warp" flag to non-zero
93d7: 4c f7 93 jmp :FriendlyCollDone
; Flew threw base, give max fuel and ammo.
93da: a9 00 :GiveRsrc lda #$00
93dc: 8d c4 6d sta time_left+2
93df: 8d c5 6d sta fuel_left
93e2: 8d c7 6d sta fuel_left+2
93e5: 8d c8 6d sta amun_left
93e8: a9 90 lda #$90 ;set fuel to 9000
93ea: 8d c6 6d sta fuel_left+1
93ed: a9 01 lda #$01 ;set ammo to 100
93ef: 8d c9 6d sta amun_left+1
93f2: a9 04 lda #$04
93f4: 20 c2 7f jsr PlayMusicSeq ;play "fly through base" music
; Done with tests for player colliding with friendly object.
:FriendlyCollDone
93f7: a6 62 ldx cur_obj_index ;get object index
93f9: bd 18 9b lda obj_activity_state,x ;check object state
93fc: 30 03 bmi DeleteObject ;was negative, go ahead and delete
93fe: 4c 9a 94 jmp :NoDeleteYet ;was positive, still need to erase
;
; Deletes an object, marking its slot as unused. All associated elements are
; also deleted.
;
; -----
;
; The first chunk of code is a copy protection booby-trap. It essentially
; checks the value in the keyboard input buffer at $0200 to see if it's $90.
; The pointer at $12-13 has its low byte initialized to zero infrequently, so
; storing a nonzero value there causes annoying graphical glitches.
;
• Clear variables
]prot_ptr .var $10 {addr/2}
9401: ad c4 71 DeleteObject lda color_bit_masks_thin+1 ;#$02
9404: 85 11 sta ]prot_ptr+1 ;create pointer to $0200
9406: a0 00 ldy #$00
9408: ad c6 71 lda color_bit_masks_thin+3 ;#$08
940b: 18 clc
940c: 69 88 adc #$88 ;now A-reg=$90
940e: 51 10 eor (]prot_ptr),y ;XOR value at $0200 (#$93), A-reg=$03
9410: 84 11 sty ]prot_ptr+1 ;Y-reg=0, so now ($10) points at $0000
9412: a0 11 ldy #$11
9414: 49 03 eor #$03 ;A-reg=$00
9416: c8 iny ;Y=reg=$12
9417: 91 10 sta (]prot_ptr),y ;set $12 to $00
9419: c6 11 dec ]prot_ptr+1
;
]elem_tmp .var $88 {addr/1}
]index_tmp .var $8a {addr/1}
941b: bc 00 9a ldy obj_first_elem_index,x ;get element index
941e: b9 40 9f :DelElemLoop lda elem_next_elem,y ;get index of following element
9421: 85 88 sta ]elem_tmp ;save that
9423: a5 68 lda avail_elem_index ;get "next available element" index
9425: 84 68 sty avail_elem_index ;replace with index of following element
9427: 99 40 9f sta elem_next_elem,y ;replace following-element index with next element
942a: 20 7f 7f jsr Return7f7f
942d: a9 fd lda #$fd
942f: 99 00 9f sta elem_obj_index,y ;invalidate reference back to object
9432: e6 6e inc free_elem_count ;increment number of available elements
9434: a4 88 ldy ]elem_tmp ;get index of following element
9436: 10 e6 bpl :DelElemLoop ;if it's not an end-of-list marker, loop
9438: a9 dd lda #$dd
943a: 9d 00 9a sta obj_first_elem_index,x ;invalidate reference from object to first element
943d: bd 78 9a lda obj_score_class,x ;get the score class
9440: f0 22 beq :NoPoints ;not enemy ship or base, branch
9442: 20 7f 7f jsr Return7f7f
9445: bc f0 9a ldy obj_next_enemy_index,x ;get next-enemy index
9448: 10 0a bpl :HaveNext ;found a valid value, branch
944a: a0 fc ldy #$fc
944c: bd c8 9a lda obj_prev_enemy_index,x ;invalidate prev-enemy index
944f: 85 6c sta head_enemy_obj_index ;update ZP
9451: 4c 5a 94 jmp :SetNext
9454: bd c8 9a :HaveNext lda obj_prev_enemy_index,x ;get prev-enemy index
9457: 99 c8 9a sta obj_prev_enemy_index,y ;set as next enemy's prev-enemy index
945a: 30 08 :SetNext bmi :NoPoints
945c: 84 8a sty ]index_tmp ;swap A-reg/Y-reg
945e: a8 tay
945f: a5 8a lda ]index_tmp
9461: 99 f0 9a sta obj_next_enemy_index,y ;set prev enemy's next-enemy index
9464: bd 50 9a :NoPoints lda obj_next_obj,x ;get next-object index
9467: 85 62 sta cur_obj_index ;make that object current
9469: a4 74 ldy prev_obj_index ;get index of object from previous loop
946b: 20 7f 7f jsr Return7f7f
946e: 10 05 bpl :PrevValid
9470: 85 6a sta head_obj_index ;copy current object index here
9472: 4c 78 94 jmp :Cont
9475: 99 50 9a :PrevValid sta obj_next_obj,y ;set previous object's next-object index
9478: a5 66 :Cont lda avail_obj_index ;get the next-object index
947a: 9d 50 9a sta obj_next_obj,x ;store that in the table
947d: 86 66 stx avail_obj_index ;set deleted object index as ZP next-obj value
947f: e6 6d inc free_obj_count ;increment the number of free objects
9481: bc 08 9c ldy obj_shape_cl_index,x ;get shape class of deleted object
9484: b9 69 6d lda active_class_ctrs,y ;update the appropriate active-class counter
9487: 38 sec
9488: e9 01 sbc #$01 ;reduce by 1
948a: 99 69 6d sta active_class_ctrs,y
948d: 20 7f 7f jsr Return7f7f
9490: a6 62 ldx cur_obj_index ;put the next object in X-reg
9492: 10 03 bpl :DrawNext ;if it's valid, branch to redraw it
9494: 4c 60 96 jmp :DoneWithObjs ;not valid, done with objects
9497: 4c 58 8c :DrawNext jmp RedrawObject
949a: a9 fe :NoDeleteYet lda #$fe
949c: 9d 18 9b sta obj_activity_state,x ;mark as pending deletion
;
; Check if the collision flag is set. The flag is not set for time portals or
; friendly bases, so this only handles collisions with enemy ships, bases, and
; projectiles.
;
949f: 86 74 CheckPlyrHit stx prev_obj_index ;save current object index as prev object
94a1: a9 ad lda #INSTR_LDA_ABS
94a3: 20 4c 7b jsr ModDrwEraVrtRct ;disable rect draw/erase
94a6: a5 f8 lda elem_collision_flag ;did we collide with hostile object?
94a8: d0 03 bne :DidCollide ;yes, branch
94aa: 4c eb 94 jmp CheckPlyrProj ;no, go check our projectiles
94ad: 10 07 :DidCollide bpl :DidCollide1 ;always?
94af: a9 02 lda #$02 ;(not sure what this is; flashes twice and then jumps
94b1: 85 a0 sta impact_flash_ctr ; to player projectile handling. A breakpoint here
94b3: 4c eb 94 jmp CheckPlyrProj ; never fired.)
94b6: ad 3b 6d :DidCollide1 lda game_active_flag ;are we in demo mode?
94b9: d0 03 bne :PlayerHit ;no, take your lumps
94bb: 4c eb 94 jmp CheckPlyrProj ;yes, skip next bit
; Player collided with something other than a friendly base, time portal, or
; time portal boundary. Flash the screen and deduct fuel.
• Clear variables
]num_digit_bytes .var $8a {addr/1}
94be: a9 ef :PlayerHit lda #$ef
94c0: ea nop
94c1: 9d 18 9b sta obj_activity_state,x ;mark thing player hit for deletion
94c4: a9 03 lda #$03
94c6: 85 a0 sta impact_flash_ctr ;flash 3x
94c8: ad 48 6d lda sound_disab_flag ;do sound stuff
94cb: d0 09 bne :NoSound
94cd: a9 01 lda #$01
94cf: 85 fa sta impact_sound_flag ;set this flag
94d1: a9 ff lda #$ff
94d3: 20 f0 0f jsr Return0ff0
94d6: a9 02 :NoSound lda #$02
94d8: 85 8a sta ]num_digit_bytes ;2-byte value
94da: a2 08 ldx #$08 ;select fuel, reduce by impact amount
94dc: a0 37 ldy #$37
94de: 20 68 7c jsr ReduceResource ;reduce fuel by 300
94e1: ea nop
94e2: a6 62 ldx cur_obj_index
94e4: 86 a2 stx linked_obj_index
94e6: a9 03 lda #$03
94e8: 85 a0 sta impact_flash_ctr ;(again?)
94ea: ea nop
;
; If this object is a player projectile, see if it hit something.
;
]proj_move_zc .var $88 {addr/2}
]coord_diff .var $8e {addr/2}
]hitbox_size .var $90 {addr/2}
94eb: bd 40 9b CheckPlyrProj lda obj_plyr_proj_flag,x ;is this a player projectile?
94ee: 20 7f 7f jsr Return7f7f
94f1: f0 2f beq :Jmp_Bottom ;no, branch
94f3: ad 3b 6d lda game_active_flag ;are we in demo mode?
94f6: f0 2a beq :Jmp_Bottom ;yes, branch
94f8: bd 18 9b lda obj_activity_state,x ;is object active?
94fb: 30 25 bmi :Jmp_Bottom ;no, branch
; Set up 3D hit box.
94fd: bd 10 9e lda obj_move_zc_lo,x ;get player projectile Z movement
9500: 85 88 sta ]proj_move_zc ;copy to DP
9502: bd 38 9e lda obj_move_zc_hi,x
9505: 18 clc
9506: 69 02 adc #$02 ;add $0200 so enemy can't move forward and
9508: 85 89 sta ]proj_move_zc+1 ; jump across seam from one frame to next
950a: bd b8 9b lda hitbox_size_lo,x ;get size of projectile hitbox ($0030)
950d: 85 90 sta ]hitbox_size
950f: bd e0 9b lda hitbox_size_hi,x
9512: 85 91 sta ]hitbox_size+1
9514: 06 90 asl ]hitbox_size ;double it
9516: 26 91 rol ]hitbox_size+1
9518: bd 00 9a lda obj_first_elem_index,x ;get index of player projectile rect
951b: aa tax ;put that in X-reg
951c: 85 64 sta cur_elem_index ;save in ZP
951e: a4 6a ldy head_obj_index ;get index of first object in list
9520: 10 03 bpl :IsValidObj ;is valid, branch
9522: 4c 55 96 :Jmp_Bottom jmp ObjLoopBottom ;done with objects
9525: b9 78 9a :IsValidObj lda obj_score_class,y ;get score class
9528: d0 09 bne :IsTarget ;is enemy ship or base, branch
952a: b9 50 9a :NextObj lda obj_next_obj,y ;get next object index
952d: a8 tay
952e: 10 f5 bpl :IsValidObj ;is valid, loop
9530: 4c 55 96 jmp ObjLoopBottom ;done with objects
9533: 84 a8 :IsTarget sty test_obj_index ;save index of object we're testing
9535: b9 00 9a lda obj_first_elem_index,y ;get index of first element in object
9538: 10 05 bpl :IsValidElem ;is valid, branch
953a: a6 62 ldx cur_obj_index ;not valid (does this happen?)
953c: 4c 55 96 jmp ObjLoopBottom ;done with objects
; Check for collision by comparing the left, top, and Z coordinates of the first
; element of the objects. The hitbox extends over and down by an amount
; specified by the projectile shape definition. Note this does NOT take into
; account the hitbox of the enemy ship or base, which is why you should aim for
; the top-left corner of the main body rect for the 30/40/60-pt aliens.
]targ_elem_index .var $86 {addr/1}
953f: a8 :IsValidElem tay ;copy target obj's first element index to Y-reg
9540: 85 86 sta ]targ_elem_index ;save in ZP (not used?)
9542: 38 sec
9543: bd c0 a1 lda elem_left_lo,x ;compute difference of left coordinates
9546: f9 c0 a1 sbc elem_left_lo,y
9549: 85 8e sta ]coord_diff
954b: bd 00 a2 lda elem_left_hi,x
954e: f9 00 a2 sbc elem_left_hi,y
9551: 70 18 bvs :MissX ;signed overflow, that's a big miss; branch
9553: 85 8f sta ]coord_diff+1
9555: 10 0a bpl :PosX
9557: 49 ff eor #$ff ;negate (without +1?) to get absolute value
9559: 85 8f sta ]coord_diff+1
955b: a5 8e lda ]coord_diff
955d: 49 ff eor #$ff
955f: 85 8e sta ]coord_diff
9561: a5 8e :PosX lda ]coord_diff ;compare diff to hitbox size
9563: c5 90 cmp ]hitbox_size
9565: a5 8f lda ]coord_diff+1
9567: e5 91 sbc ]hitbox_size+1
9569: 30 03 bmi :InsideX ;diff < hitbox size, keep going
956b: 4c 38 96 :MissX jmp :LoopBottom ;missed, bail
956e: 38 :InsideX sec
956f: bd 40 a2 lda elem_top_lo,x ;compute difference of top coordinates
9572: f9 40 a2 sbc elem_top_lo,y
9575: 85 8e sta ]coord_diff
9577: bd 80 a2 lda elem_top_hi,x
957a: f9 80 a2 sbc elem_top_hi,y
957d: 70 ec bvs :MissX ;signed overflow, missed; branch
957f: 85 8f sta ]coord_diff+1
9581: 10 0a bpl :PosY
9583: 49 ff eor #$ff ;negate (without +1?) to get absolute value
9585: 85 8f sta ]coord_diff+1
9587: a5 8e lda ]coord_diff
9589: 49 ff eor #$ff
958b: 85 8e sta ]coord_diff
958d: a5 8e :PosY lda ]coord_diff ;compare diff to hitbox size
958f: c5 90 cmp ]hitbox_size
9591: a5 8f lda ]coord_diff+1
9593: e5 91 sbc ]hitbox_size+1
9595: 10 29 bpl :MissZ ;diff >= hitbox size, bail
9597: 38 sec
9598: bd 40 a1 lda elem_zpos_lo,x ;compute difference of Z coordinates
959b: f9 40 a1 sbc elem_zpos_lo,y
959e: 85 8e sta ]coord_diff
95a0: bd 80 a1 lda elem_zpos_hi,x
95a3: f9 80 a1 sbc elem_zpos_hi,y
95a6: 70 18 bvs :MissZ ;signed overflow, missed; branch
95a8: 85 8f sta ]coord_diff+1
95aa: 10 0a bpl :PosZ
95ac: 49 ff eor #$ff ;negate (without +1?) to get absolute value
95ae: 85 8f sta ]coord_diff+1
95b0: a5 8e lda ]coord_diff
95b2: 49 ff eor #$ff
95b4: 85 8e sta ]coord_diff
95b6: a5 8e :PosZ lda ]coord_diff ;compare difference in coordinates to projectile's Z
95b8: c5 88 cmp ]proj_move_zc ; speed, so we collide if we're about to move through
95ba: a5 8f lda ]coord_diff+1 ; the target or already moved through it
95bc: e5 89 sbc ]proj_move_zc+1
95be: 30 03 bmi EnemyDestroyed
95c0: 4c 38 96 :MissZ jmp :LoopBottom
;
; Handles an enemy ship or base that has been struck by a player projectile.
; Flashes the screen and updates the score.
;
95c3: 20 7f 7f EnemyDestroyed jsr Return7f7f
95c6: a4 a8 ldy test_obj_index ;get index of object we're testing
95c8: 84 a2 sty linked_obj_index ;set as "linked object" for chunks/flare
95ca: b9 78 9a lda obj_score_class,y ;get index into score table
95cd: 85 a0 sta impact_flash_ctr ;flash that many times (more for bases)
95cf: a2 00 ldx #$00 ;index of score bytes
95d1: 0a asl A ;multiply score class by 4
95d2: 0a asl A
95d3: 18 clc
95d4: 69 17 adc #$17 ;add offset to enemy point value table
95d6: a8 tay
95d7: a9 04 lda #$04 ;4-byte value
95d9: 85 8a sta ]num_digit_bytes
95db: 20 a0 7c jsr IncreaseResource ;increase score
95de: a5 a0 lda impact_flash_ctr ;get score class
95e0: c9 06 cmp #$06 ;was it a base?
95e2: 30 08 bmi :NotBase
95e4: a9 03 lda #$03
95e6: 20 c2 7f jsr PlayMusicSeq ;enemy base destroyed, play chirp sound
95e9: 4c f6 95 jmp :SoundDone
95ec: a0 02 :NotBase ldy #$02
95ee: 20 da 7c jsr InitiateSfx ;play enemy destroyed sound
95f1: a5 a0 lda impact_flash_ctr ;(?)
95f3: 20 f0 0f jsr Return0ff0
; Create flare and chunks.
95f6: a5 a0 :SoundDone lda impact_flash_ctr ;(?)
95f8: a0 0a ldy #$0a ;class = ship explosion flare
95fa: a6 62 ldx cur_obj_index ;preserve current object index
95fc: 8e 81 8c stx saved_obj_index
95ff: 20 0f 76 jsr CreateObject ;create explosion object
9602: ea nop
9603: ae 81 8c ldx saved_obj_index ;restore object index
9606: 86 62 stx cur_obj_index
9608: 18 clc
9609: a5 a0 lda impact_flash_ctr ;get score class
960b: 69 02 adc #$02 ;add two
960d: 8d 37 96 sta :chunk_ctr ;create this many chunks
9610: ce 37 96 :ChunkLoop dec :chunk_ctr ;done yet?
9613: 30 16 bmi :ChunksDone ;yes, branch
9615: a0 09 ldy #$09 ;class = explosion chunks
9617: a5 a8 lda test_obj_index
9619: 85 a2 sta linked_obj_index
961b: a6 62 ldx cur_obj_index
961d: 8e 81 8c stx saved_obj_index ;save current object index
9620: 20 0f 76 jsr CreateObject ;create chunk
9623: ae 81 8c ldx saved_obj_index
9626: 86 62 stx cur_obj_index ;restore object index
9628: 4c 10 96 jmp :ChunkLoop
962b: a9 fa :ChunksDone lda #$fa
962d: a4 a8 ldy test_obj_index
962f: 99 18 9b sta obj_activity_state,y
9632: a6 62 ldx cur_obj_index
9634: 4c 55 96 jmp ObjLoopBottom
9637: 00 :chunk_ctr .dd1 $00 ;explosion chunk counter
9638: 18 :LoopBottom clc ;do sound stuff
9639: a5 b2 lda engine_sound_ctr?+1
963b: 69 06 adc #$06
963d: 85 b2 sta engine_sound_ctr?+1
963f: 90 0f bcc :NoSound
9641: e6 b3 inc engine_sound_ctr?+2
9643: a5 cc lda engine_sound_enable
9645: f0 09 beq :NoSound
9647: a5 b3 lda engine_sound_ctr?+2
9649: 25 b1 and engine_sound_ctr?
964b: d0 03 bne :NoSound
964d: ad 30 c0 lda SPKR
9650: a4 a8 :NoSound ldy test_obj_index
9652: 4c 2a 95 jmp :NextObj ;check next object
9655: 20 7f 7f ObjLoopBottom jsr Return7f7f
9658: a6 62 ldx cur_obj_index ;get object index
965a: bd 50 9a lda obj_next_obj,x ;see if there's another object
965d: aa tax
965e: 10 54 bpl :MoreObjs ;there is, go handle it
; Done walking objects. If we're showing an impact flash, do it now, otherwise
; just restart the main loop.
9660: a5 a0 :DoneWithObjs lda impact_flash_ctr ;are we flashing the lo-res screen?
9662: d0 07 bne :ShowImpactFlash ;yes, go do that
9664: 4c fc 81 jmp MainLoop
9667: a9 ff 85 88 .junk 4
; Flash the screen when something gets hit. Set the lo-res screen to a random
; color and display it briefly.
]rng_result .var $8a {addr/2}
:ShowImpactFlash
966b: c6 a0 dec impact_flash_ctr
966d: 20 b0 7b jsr GenRandom ;get random value (is limit set?)
9670: a5 8b lda ]rng_result+1 ;get high byte
9672: 29 07 and #$07 ;reduce to 0-7
9674: a8 tay
9675: b9 ce 70 lda lo_res_color,y ;get color value from table
9678: 20 4e 7c jsr SetLoRes2 ;fill lo-res screen with it
967b: ad 56 c0 lda LORES ;switch to lo-res screen
967e: ad 55 c0 lda TXTPAGE2 ;page 2
; Play a brief sound effect (about 144 Hz).
9681: a2 07 ldx #$07
9683: a0 f6 :DelayLoop ldy #$f6 ;2
9685: 88 :Delay1 dey ;2
9686: d0 fd bne :Delay1 ;3 (7 * 246) - 1 = 1721 cycles
9688: a0 f6 ldy #$f6
968a: 88 :Delay2 dey
968b: d0 fd bne :Delay2
968d: a0 f6 ldy #$f6
968f: 88 :Delay3 dey
9690: d0 fd bne :Delay3
9692: a0 f6 ldy #$f6
9694: 88 :Delay4 dey
9695: d0 fd bne :Delay4 ;1721 * 4 = 6884 cycles
9697: a5 fa lda impact_sound_flag ;play sound?
9699: f0 0d beq :NoSound ;no, done with sound (even if not done with flash)
969b: ad 3b 6d lda game_active_flag ;showing the demo?
969e: f0 08 beq :NoSound ;yes, no sound
96a0: ad 48 6d lda sound_disab_flag ;sound disabled?
96a3: d0 03 bne :NoSound ;yes, no sound
96a5: ad 30 c0 lda SPKR ;click
96a8: ca :NoSound dex
96a9: d0 d8 bne :DelayLoop
96ab: ad 54 c0 lda TXTPAGE1 ;switch back to page 1
96ae: ad 57 c0 lda HIRES ;hi-res graphics
96b1: 4c fc 81 jmp MainLoop
96b4: 86 62 :MoreObjs stx cur_obj_index
96b6: 20 7f 7f jsr Return7f7f
96b9: 4c 58 8c jmp RedrawObject ;jump to top of object redraw loop
96bc: 3d 3d 3d 3d+ .align $0100 (68 bytes)
.org $9a00
;
; Active object state, for up to 40 objects.
;
; -----
;
; Index of first element in object. Unused entries are set to $f7. The last
; entry is set to $ed as an end-of-list marker.
;
; Set to $dd when object is being deleted.
obj_first_elem_index
9a00: 00 01 14 15+ .junk 40
;
; Lifespan counter. If initially $00, object can live forever. If nonzero,
; object expires after that many ticks.
;
; From shape header +$01.
obj_lifetime_ctr
9a28: 00 00 00 00+ .junk 40
;
; Index of next active object. Initialized to $01-27 (1-39). The last entry is
; set to $ed as an end-of-list marker.
9a50: ef 00 01 02+ obj_next_obj .junk 40
;
; "Score class" for enemy ships and bases (1-7), or 0 for other entities. See
; table at $70fd for score values.
;
; From shape header +$02.
9a78: 00 00 00 00+ obj_score_class .junk 40
;
; Shape unique identifier. Code checks for $6f (time warp), $5x (time portal
; boundaries), and $fx (which never happens).
;
; From shape header +$03.
9aa0: 72 01 75 75+ obj_shape_uid .junk 40
;
; Link to previous object slot with an enemy ship or base.
obj_prev_enemy_index
9ac8: 00 00 00 00+ .junk 40
;
; Link to next object slot with an enemy ship or base.
obj_next_enemy_index
9af0: 00 00 00 00+ .junk 40
;
; Initially set to value (0-3) from shape header at +$04:
; $00: friendly/enemy bases, time portals, stars
; $01: player projectiles, explosion flares
; $02: explosion chunks
; $03: enemy ships
;
; Value $02 will be replaced with $01 after initial velocity is set, and the
; state may be replaced with other values at the end of the object's life. So
; the meaning becomes:
;
; $00: no movement: friendly/enemy bases, stars
; $01: movement doesn't change: player projectile, enemy projectile, explosion
; chunks, explosion flare
; $02: (unused)
; $03: movement updated periodically: enemy ships
; $ef: player collided with this
; $fe: object is being / has been deleted
; $ff: object lifetime has expired (e.g. explosion flares)
obj_activity_state
9b18: 00 00 00 00+ .junk 40
;
; Set to 4 for player projectiles, 0 for everything else. Used as an "is it a
; friendly projectile" flag.
;
; From shape header +$05.
obj_plyr_proj_flag
9b40: 00 00 00 00+ .junk 40
;
; Max interval between velocity re-evaluation.
;
; From shape header +$06.
vel_change_intvl_max
9b68: 00 00 00 00+ .junk 40
;
; Velocity change counter, only used for enemy ships. When this reaches zero,
; we recompute the ship's velocity, and reset the counter to a random value.
;
; Random value is limited by shape header value +$06. Initialized to $01 for
; new slot.
9b90: 01 01 01 01+ vel_change_ctr .junk 40
;
; Size of hitbox, in eye coordinates. The top-left corner is specified by the
; first element in the shape defintion.
;
; From shape header $0f/$10.
9bb8: 01 c0 01 01+ hitbox_size_lo .junk 40
9be0: 00 01 00 00+ hitbox_size_hi .junk 40
;
; Shape class for this object (0-11).
obj_shape_cl_index
9c08: 07 00 07 07+ .junk 40
;
; Base movement, to which random values may be added.
;
; These are updated in specific situations.
9c30: 00 00 00 00+ obj_move_zc2_lo .junk 40
9c58: 00 00 00 00+ obj_move_zc2_hi .junk 40
9c80: 00 00 00 00+ obj_move_xc2_lo .junk 40
9ca8: 00 00 00 00+ obj_move_xc2_hi .junk 40
9cd0: 00 00 00 00+ obj_move_yc2_lo .junk 40
9cf8: 00 00 00 00+ obj_move_yc2_hi .junk 7
;
; NOTE: some additional per-object tables follow. There's no data in the file
; at this point, so they're defined as equates.
;
; obj_spdlim_z_lo .eq $9d20 {addr/40} ;Z speed limit, low (hdr +$11)
; obj_spdlim_z_hi .eq $9d48 {addr/40} ;Z speed limit, high (hdr +$12)
; obj_spdlim_x_lo .eq $9d70 {addr/40} ;X speed limit, low (hdr +$13)
; obj_spdlim_x_hi .eq $9d98 {addr/40} ;X speed limit, high (hdr +$14)
; obj_spdlim_y_lo .eq $9dc0 {addr/40} ;Y speed limit, low (hdr +$15)
; obj_spdlim_y_hi .eq $9de8 {addr/40} ;Y speed limit, high (hdr +$16)
; obj_move_zc_lo .eq $9e10 {addr/40} ;object movement vector, Z low
; obj_move_zc_hi .eq $9e38 {addr/40} ;object movement vector, Z high
; obj_move_xc_lo .eq $9e60 {addr/40} ;object movement vector, X low
; obj_move_xc_hi .eq $9e88 {addr/40} ;object movement vector, X high
; obj_move_yc_lo .eq $9eb0 {addr/40} ;object movement vector, Y low
; obj_move_yc_hi .eq $9ed8 {addr/40} ;object movement vector, Y high
;
9cff: 00 .junk 1
.org $9f00
;
; Active element state, for up to 64 elements.
;
; -----
;
; Index of object that the element is a part of (0-39). It may also hold $f6
; when first initialized, $ec as an end-of-list marker ($9f3f only), or
; $ec/f6/fd after various events.
9f00: 00 01 01 01+ elem_obj_index .junk 64
;
; Index of next element in this object. This is initialized to N+1, i.e.
; entries 0,1,2 have values 1,2,3. When an object is created, the entry for the
; last element is changed to #$fc to mark the end of the list.
9f40: fc 02 03 04+ elem_next_elem .junk 64
;
; Modified element type. Value is based on the element type and state:
; $00=point
; $01=horizontal line
; $80=vertical line ($ff in element def)
; $81=rect ($80 in elementdef)
; $82=do not draw
; $83=created, not yet draw
;
; These may not match the original type, e.g. a rect may be "demoted" to a
; vertical line if the left and right coordinates are equal.
9f80: 00 00 81 81+ elem_mod_types .junk 64
;
; Unmodified element type: $00=point, $01=hline, $80=rect, $ff=vline.
9fc0: 00 00 80 80+ elem_types .junk 64
;
; Colors and color-change tracking.
a000: 50 00 40 40+ elem_colorsA .junk 64 ;first color
a040: 00 00 00 00+ elem_colorsB .junk 64 ;second color (optional)
a080: 50 00 40 40+ elem_cur_colors .junk 64 ;holds colorA or colorB
elem_colorchanges
a0c0: 00 00 00 00+ .junk 64 ;change frequency, from shape definition
elem_colorchange_ctrs
a100: 00 00 00 00+ .junk 64 ;current value of counter
;
; Current element position (eye coordinates), updated as things move. Negative
; values indicate positions to the left and above the crosshairs.
;
; For points and lines, only the relevant coordinates are used (e.g.
; right/bottom don't matter for points).
a140: 40 ba ba ba+ elem_zpos_lo .junk 64
a180: 3a 09 09 09+ elem_zpos_hi .junk 64
a1c0: 95 00 80 c0+ elem_left_lo .junk 64
a200: f5 00 fc fc+ elem_left_hi .junk 64
a240: 95 00 00 00+ elem_top_lo .junk 64
a280: fc 00 ff ff+ elem_top_hi .junk 64
a2c0: 95 00 c0 80+ elem_right_lo .junk 64
a300: f5 00 fc fd+ elem_right_hi .junk 64
a340: 95 00 00 40+ elem_bottom_lo .junk 64
a380: fc 00 01 ff+ elem_bottom_hi .junk 64
;
; These values are recorded while drawing, so that we can erase the element
; before drawing the next. Some of these have different meanings for different
; element types.
;
; Points:
; a3c0: offset into hi-res page (addr low byte + col)
; a400: high byte of hi-res page
; a540: pixel bit mask
;
; Horizontal lines:
; a3c0: left edge pixel color offset (0-6,8-14)
; a400: hi-res column of left edge (0-39)
; a440: hi-res line address, low byte
; a480: right edge pixel color offset (0-6,8-14)
; a4c0: hi-res column of right edge (0-39)
; a500: hi-res line address, high byte
;
; Vertical lines and rects:
; $a3c0: left edge pixel color offset (0-6,8-14)
; $a400: hi-res column of left edge (0-39)
; $a440: top coord (0-191)
; $a480: right edge pixel color offset (0-6,8-14)
; $a4c0: hi-res column of right edge (0-39)
; $a500: bottom coord (0-191)
; $a540: pixel bit mask (vertical line only)
a3c0: b8 3c 06 0b+ elem_erase_0 .junk 64
a400: 2d 22 0c 0d+ elem_erase_1 .junk 64
a440: 00 00 56 56+ elem_erase_2 .junk 64
a480: 00 00 0b 06+ elem_erase_3 .junk 64
a4c0: 00 00 0d 0e+ elem_erase_4 .junk 64
a500: 00 00 6a 59+ elem_erase_5 .junk 64
a540: 90 01 00 00+ elem_erase_6 .junk 64
a580: 00 00 00 00+ .junk 64
a5c0: 00 00 00 00+ .junk 64
;
; Erases a vertical stripe.
;
; This is generally not called directly. A lookup table ($5500/b800) converts
; line numbers to addresses, which are then used as an indirect jump (for the
; top) or as a location to store an RTS (for the bottom).
;
; On entry:
; X-reg: pixel byte value (adjusted for odd/even)
; Y-reg: horizontal offset (0-39)
;
a600: 8a UnrolledAND txa
a601: 39 00 20 and HIRES_P1,y
a604: 99 00 20 sta HIRES_P1,y
a607: 8a txa
a608: 39 00 24 and HIRES_P1+$400,y
a60b: 99 00 24 sta HIRES_P1+$400,y
a60e: 8a txa
a60f: 39 00 28 and HIRES_P1+$800,y
a612: 99 00 28 sta HIRES_P1+$800,y
a615: 8a txa
a616: 39 00 2c and HIRES_P1+$c00,y
a619: 99 00 2c sta HIRES_P1+$c00,y
a61c: 8a txa
a61d: 39 00 30 and HIRES_P1+$1000,y
a620: 99 00 30 sta HIRES_P1+$1000,y
a623: 8a txa
a624: 39 00 34 and HIRES_P1+$1400,y
a627: 99 00 34 sta HIRES_P1+$1400,y
a62a: 8a txa
a62b: 39 00 38 and HIRES_P1+$1800,y
a62e: 99 00 38 sta HIRES_P1+$1800,y
a631: 8a txa
a632: 39 00 3c and HIRES_P1+$1c00,y
a635: 99 00 3c sta HIRES_P1+$1c00,y
a638: 8a txa
a639: 39 80 20 and HIRES_P1+128,y
a63c: 99 80 20 sta HIRES_P1+128,y
a63f: 8a txa
a640: 39 80 24 and HIRES_P1+$480,y
a643: 99 80 24 sta HIRES_P1+$480,y
a646: 8a txa
a647: 39 80 28 and HIRES_P1+$880,y
a64a: 99 80 28 sta HIRES_P1+$880,y
a64d: 8a txa
a64e: 39 80 2c and HIRES_P1+$c80,y
a651: 99 80 2c sta HIRES_P1+$c80,y
a654: 8a txa
a655: 39 80 30 and HIRES_P1+$1080,y
a658: 99 80 30 sta HIRES_P1+$1080,y
a65b: 8a txa
a65c: 39 80 34 and HIRES_P1+$1480,y
a65f: 99 80 34 sta HIRES_P1+$1480,y
a662: 8a txa
a663: 39 80 38 and HIRES_P1+$1880,y
a666: 99 80 38 sta HIRES_P1+$1880,y
a669: 8a txa
a66a: 39 80 3c and HIRES_P1+$1c80,y
a66d: 99 80 3c sta HIRES_P1+$1c80,y
a670: 8a txa
a671: 39 00 21 and HIRES_P1+$100,y
a674: 99 00 21 sta HIRES_P1+$100,y
a677: 8a txa
a678: 39 00 25 and HIRES_P1+$500,y
a67b: 99 00 25 sta HIRES_P1+$500,y
a67e: 8a txa
a67f: 39 00 29 and HIRES_P1+$900,y
a682: 99 00 29 sta HIRES_P1+$900,y
a685: 8a txa
a686: 39 00 2d and HIRES_P1+$d00,y
a689: 99 00 2d sta HIRES_P1+$d00,y
a68c: 8a txa
a68d: 39 00 31 and HIRES_P1+$1100,y
a690: 99 00 31 sta HIRES_P1+$1100,y
a693: 8a txa
a694: 39 00 35 and HIRES_P1+$1500,y
a697: 99 00 35 sta HIRES_P1+$1500,y
a69a: 8a txa
a69b: 39 00 39 and HIRES_P1+$1900,y
a69e: 99 00 39 sta HIRES_P1+$1900,y
a6a1: 8a txa
a6a2: 39 00 3d and HIRES_P1+$1d00,y
a6a5: 99 00 3d sta HIRES_P1+$1d00,y
a6a8: 8a txa
a6a9: 39 80 21 and HIRES_P1+$180,y
a6ac: 99 80 21 sta HIRES_P1+$180,y
a6af: 8a txa
a6b0: 39 80 25 and HIRES_P1+$580,y
a6b3: 99 80 25 sta HIRES_P1+$580,y
a6b6: 8a txa
a6b7: 39 80 29 and HIRES_P1+$980,y
a6ba: 99 80 29 sta HIRES_P1+$980,y
a6bd: 8a txa
a6be: 39 80 2d and HIRES_P1+$d80,y
a6c1: 99 80 2d sta HIRES_P1+$d80,y
a6c4: 8a txa
a6c5: 39 80 31 and HIRES_P1+$1180,y
a6c8: 99 80 31 sta HIRES_P1+$1180,y
a6cb: 8a txa
a6cc: 39 80 35 and HIRES_P1+$1580,y
a6cf: 99 80 35 sta HIRES_P1+$1580,y
a6d2: 8a txa
a6d3: 39 80 39 and HIRES_P1+$1980,y
a6d6: 99 80 39 sta HIRES_P1+$1980,y
a6d9: 8a txa
a6da: 39 80 3d and HIRES_P1+$1d80,y
a6dd: 99 80 3d sta HIRES_P1+$1d80,y
a6e0: 8a txa
a6e1: 39 00 22 and HIRES_P1+$200,y
a6e4: 99 00 22 sta HIRES_P1+$200,y
a6e7: 8a txa
a6e8: 39 00 26 and HIRES_P1+$600,y
a6eb: 99 00 26 sta HIRES_P1+$600,y
a6ee: 8a txa
a6ef: 39 00 2a and HIRES_P1+$a00,y
a6f2: 99 00 2a sta HIRES_P1+$a00,y
a6f5: 8a txa
a6f6: 39 00 2e and HIRES_P1+$e00,y
a6f9: 99 00 2e sta HIRES_P1+$e00,y
a6fc: 8a txa
a6fd: 39 00 32 and HIRES_P1+$1200,y
a700: 99 00 32 sta HIRES_P1+$1200,y
a703: 8a txa
a704: 39 00 36 and HIRES_P1+$1600,y
a707: 99 00 36 sta HIRES_P1+$1600,y
a70a: 8a txa
a70b: 39 00 3a and HIRES_P1+$1a00,y
a70e: 99 00 3a sta HIRES_P1+$1a00,y
a711: 8a txa
a712: 39 00 3e and HIRES_P1+$1e00,y
a715: 99 00 3e sta HIRES_P1+$1e00,y
a718: 8a txa
a719: 39 80 22 and HIRES_P1+$280,y
a71c: 99 80 22 sta HIRES_P1+$280,y
a71f: 8a txa
a720: 39 80 26 and HIRES_P1+$680,y
a723: 99 80 26 sta HIRES_P1+$680,y
a726: 8a txa
a727: 39 80 2a and HIRES_P1+$a80,y
a72a: 99 80 2a sta HIRES_P1+$a80,y
a72d: 8a txa
a72e: 39 80 2e and HIRES_P1+$e80,y
a731: 99 80 2e sta HIRES_P1+$e80,y
a734: 8a txa
a735: 39 80 32 and HIRES_P1+$1280,y
a738: 99 80 32 sta HIRES_P1+$1280,y
a73b: 8a txa
a73c: 39 80 36 and HIRES_P1+$1680,y
a73f: 99 80 36 sta HIRES_P1+$1680,y
a742: 8a txa
a743: 39 80 3a and HIRES_P1+$1a80,y
a746: 99 80 3a sta HIRES_P1+$1a80,y
a749: 8a txa
a74a: 39 80 3e and HIRES_P1+$1e80,y
a74d: 99 80 3e sta HIRES_P1+$1e80,y
a750: 8a txa
a751: 39 00 23 and HIRES_P1+$300,y
a754: 99 00 23 sta HIRES_P1+$300,y
a757: 8a txa
a758: 39 00 27 and HIRES_P1+$700,y
a75b: 99 00 27 sta HIRES_P1+$700,y
a75e: 8a txa
a75f: 39 00 2b and HIRES_P1+$b00,y
a762: 99 00 2b sta HIRES_P1+$b00,y
a765: 8a txa
a766: 39 00 2f and HIRES_P1+$f00,y
a769: 99 00 2f sta HIRES_P1+$f00,y
a76c: 8a txa
a76d: 39 00 33 and HIRES_P1+$1300,y
a770: 99 00 33 sta HIRES_P1+$1300,y
a773: 8a txa
a774: 39 00 37 and HIRES_P1+$1700,y
a777: 99 00 37 sta HIRES_P1+$1700,y
a77a: 8a txa
a77b: 39 00 3b and HIRES_P1+$1b00,y
a77e: 99 00 3b sta HIRES_P1+$1b00,y
a781: 8a txa
a782: 39 00 3f and HIRES_P1+$1f00,y
a785: 99 00 3f sta HIRES_P1+$1f00,y
a788: 8a txa
a789: 39 80 23 and HIRES_P1+$380,y
a78c: 99 80 23 sta HIRES_P1+$380,y
a78f: 8a txa
a790: 39 80 27 and HIRES_P1+$780,y
a793: 99 80 27 sta HIRES_P1+$780,y
a796: 8a txa
a797: 39 80 2b and HIRES_P1+$b80,y
a79a: 99 80 2b sta HIRES_P1+$b80,y
a79d: 8a txa
a79e: 39 80 2f and HIRES_P1+$f80,y
a7a1: 99 80 2f sta HIRES_P1+$f80,y
a7a4: 8a txa
a7a5: 39 80 33 and HIRES_P1+$1380,y
a7a8: 99 80 33 sta HIRES_P1+$1380,y
a7ab: 8a txa
a7ac: 39 80 37 and HIRES_P1+$1780,y
a7af: 99 80 37 sta HIRES_P1+$1780,y
a7b2: 8a txa
a7b3: 39 80 3b and HIRES_P1+$1b80,y
a7b6: 99 80 3b sta HIRES_P1+$1b80,y
a7b9: 8a txa
a7ba: 39 80 3f and HIRES_P1+$1f80,y
a7bd: 99 80 3f sta HIRES_P1+$1f80,y
a7c0: 8a txa
a7c1: 39 28 20 and HIRES_P1+40,y
a7c4: 99 28 20 sta HIRES_P1+40,y
a7c7: 8a txa
a7c8: 39 28 24 and HIRES_P1+$428,y
a7cb: 99 28 24 sta HIRES_P1+$428,y
a7ce: 8a txa
a7cf: 39 28 28 and HIRES_P1+$828,y
a7d2: 99 28 28 sta HIRES_P1+$828,y
a7d5: 8a txa
a7d6: 39 28 2c and HIRES_P1+$c28,y
a7d9: 99 28 2c sta HIRES_P1+$c28,y
a7dc: 8a txa
a7dd: 39 28 30 and HIRES_P1+$1028,y
a7e0: 99 28 30 sta HIRES_P1+$1028,y
a7e3: 8a txa
a7e4: 39 28 34 and HIRES_P1+$1428,y
a7e7: 99 28 34 sta HIRES_P1+$1428,y
a7ea: 8a txa
a7eb: 39 28 38 and HIRES_P1+$1828,y
a7ee: 99 28 38 sta HIRES_P1+$1828,y
a7f1: 8a txa
a7f2: 39 28 3c and HIRES_P1+$1c28,y
a7f5: 99 28 3c sta HIRES_P1+$1c28,y
a7f8: 8a txa
a7f9: 39 a8 20 and HIRES_P1+168,y
a7fc: 99 a8 20 sta HIRES_P1+168,y
a7ff: 8a txa
a800: 39 a8 24 and HIRES_P1+$4a8,y
a803: 99 a8 24 sta HIRES_P1+$4a8,y
a806: 8a txa
a807: 39 a8 28 and HIRES_P1+$8a8,y
a80a: 99 a8 28 sta HIRES_P1+$8a8,y
a80d: 8a txa
a80e: 39 a8 2c and HIRES_P1+$ca8,y
a811: 99 a8 2c sta HIRES_P1+$ca8,y
a814: 8a txa
a815: 39 a8 30 and HIRES_P1+$10a8,y
a818: 99 a8 30 sta HIRES_P1+$10a8,y
a81b: 8a txa
a81c: 39 a8 34 and HIRES_P1+$14a8,y
a81f: 99 a8 34 sta HIRES_P1+$14a8,y
a822: 8a txa
a823: 39 a8 38 and HIRES_P1+$18a8,y
a826: 99 a8 38 sta HIRES_P1+$18a8,y
a829: 8a txa
a82a: 39 a8 3c and HIRES_P1+$1ca8,y
a82d: 99 a8 3c sta HIRES_P1+$1ca8,y
a830: 8a txa
a831: 39 28 21 and HIRES_P1+$128,y
a834: 99 28 21 sta HIRES_P1+$128,y
a837: 8a txa
a838: 39 28 25 and HIRES_P1+$528,y
a83b: 99 28 25 sta HIRES_P1+$528,y
a83e: 8a txa
a83f: 39 28 29 and HIRES_P1+$928,y
a842: 99 28 29 sta HIRES_P1+$928,y
a845: 8a txa
a846: 39 28 2d and HIRES_P1+$d28,y
a849: 99 28 2d sta HIRES_P1+$d28,y
a84c: 8a txa
a84d: 39 28 31 and HIRES_P1+$1128,y
a850: 99 28 31 sta HIRES_P1+$1128,y
a853: 8a txa
a854: 39 28 35 and HIRES_P1+$1528,y
a857: 99 28 35 sta HIRES_P1+$1528,y
a85a: 8a txa
a85b: 39 28 39 and HIRES_P1+$1928,y
a85e: 99 28 39 sta HIRES_P1+$1928,y
a861: 8a AndSeq_87 txa
a862: 39 28 3d and HIRES_P1+$1d28,y ;line 87
a865: 99 28 3d sta HIRES_P1+$1d28,y
a868: 8a txa
a869: 39 a8 21 and HIRES_P1+$1a8,y
a86c: 99 a8 21 sta HIRES_P1+$1a8,y
a86f: 8a txa
a870: 39 a8 25 and HIRES_P1+$5a8,y
a873: 99 a8 25 sta HIRES_P1+$5a8,y
a876: 8a AndSeq_90 txa
a877: 39 a8 29 and HIRES_P1+$9a8,y ;line 90
a87a: 99 a8 29 sta HIRES_P1+$9a8,y
a87d: 8a txa
a87e: 39 a8 2d and HIRES_P1+$da8,y
a881: 99 a8 2d sta HIRES_P1+$da8,y
a884: 8a txa
a885: 39 a8 31 and HIRES_P1+$11a8,y
a888: 99 a8 31 sta HIRES_P1+$11a8,y
a88b: 8a txa
a88c: 39 a8 35 and HIRES_P1+$15a8,y
a88f: 99 a8 35 sta HIRES_P1+$15a8,y
a892: 8a txa
a893: 39 a8 39 and HIRES_P1+$19a8,y
a896: 99 a8 39 sta HIRES_P1+$19a8,y
a899: 8a txa
a89a: 39 a8 3d and HIRES_P1+$1da8,y
a89d: 99 a8 3d sta HIRES_P1+$1da8,y
a8a0: 8a txa
a8a1: 39 28 22 and HIRES_P1+$228,y
a8a4: 99 28 22 sta HIRES_P1+$228,y
a8a7: 8a txa
a8a8: 39 28 26 and HIRES_P1+$628,y
a8ab: 99 28 26 sta HIRES_P1+$628,y
a8ae: 8a txa
a8af: 39 28 2a and HIRES_P1+$a28,y
a8b2: 99 28 2a sta HIRES_P1+$a28,y
a8b5: 8a txa
a8b6: 39 28 2e and HIRES_P1+$e28,y
a8b9: 99 28 2e sta HIRES_P1+$e28,y
a8bc: 8a txa
a8bd: 39 28 32 and HIRES_P1+$1228,y
a8c0: 99 28 32 sta HIRES_P1+$1228,y
a8c3: 8a txa
a8c4: 39 28 36 and HIRES_P1+$1628,y
a8c7: 99 28 36 sta HIRES_P1+$1628,y
a8ca: 8a txa
a8cb: 39 28 3a and HIRES_P1+$1a28,y
a8ce: 99 28 3a sta HIRES_P1+$1a28,y
a8d1: 8a txa
a8d2: 39 28 3e and HIRES_P1+$1e28,y
a8d5: 99 28 3e sta HIRES_P1+$1e28,y
a8d8: 8a txa
a8d9: 39 a8 22 and HIRES_P1+$2a8,y
a8dc: 99 a8 22 sta HIRES_P1+$2a8,y
a8df: 8a txa
a8e0: 39 a8 26 and HIRES_P1+$6a8,y
a8e3: 99 a8 26 sta HIRES_P1+$6a8,y
a8e6: 8a txa
a8e7: 39 a8 2a and HIRES_P1+$aa8,y
a8ea: 99 a8 2a sta HIRES_P1+$aa8,y
a8ed: 8a txa
a8ee: 39 a8 2e and HIRES_P1+$ea8,y
a8f1: 99 a8 2e sta HIRES_P1+$ea8,y
a8f4: 8a txa
a8f5: 39 a8 32 and HIRES_P1+$12a8,y
a8f8: 99 a8 32 sta HIRES_P1+$12a8,y
a8fb: 8a txa
a8fc: 39 a8 36 and HIRES_P1+$16a8,y
a8ff: 99 a8 36 sta HIRES_P1+$16a8,y
a902: 8a txa
a903: 39 a8 3a and HIRES_P1+$1aa8,y
a906: 99 a8 3a sta HIRES_P1+$1aa8,y
a909: 8a txa
a90a: 39 a8 3e and HIRES_P1+$1ea8,y
a90d: 99 a8 3e sta HIRES_P1+$1ea8,y
a910: 8a txa
a911: 39 28 23 and HIRES_P1+$328,y
a914: 99 28 23 sta HIRES_P1+$328,y
a917: 8a txa
a918: 39 28 27 and HIRES_P1+$728,y
a91b: 99 28 27 sta HIRES_P1+$728,y
a91e: 8a txa
a91f: 39 28 2b and HIRES_P1+$b28,y
a922: 99 28 2b sta HIRES_P1+$b28,y
a925: 8a txa
a926: 39 28 2f and HIRES_P1+$f28,y
a929: 99 28 2f sta HIRES_P1+$f28,y
a92c: 8a txa
a92d: 39 28 33 and HIRES_P1+$1328,y
a930: 99 28 33 sta HIRES_P1+$1328,y
a933: 8a txa
a934: 39 28 37 and HIRES_P1+$1728,y
a937: 99 28 37 sta HIRES_P1+$1728,y
a93a: 8a txa
a93b: 39 28 3b and HIRES_P1+$1b28,y
a93e: 99 28 3b sta HIRES_P1+$1b28,y
a941: 8a txa
a942: 39 28 3f and HIRES_P1+$1f28,y
a945: 99 28 3f sta HIRES_P1+$1f28,y
a948: 8a txa
a949: 39 a8 23 and HIRES_P1+$3a8,y
a94c: 99 a8 23 sta HIRES_P1+$3a8,y
a94f: 8a txa
a950: 39 a8 27 and HIRES_P1+$7a8,y
a953: 99 a8 27 sta HIRES_P1+$7a8,y
a956: 8a txa
a957: 39 a8 2b and HIRES_P1+$ba8,y
a95a: 99 a8 2b sta HIRES_P1+$ba8,y
a95d: 8a txa
a95e: 39 a8 2f and HIRES_P1+$fa8,y
a961: 99 a8 2f sta HIRES_P1+$fa8,y ;line 123
a964: 8a txa
a965: 39 a8 33 and HIRES_P1+$13a8,y
a968: 99 a8 33 sta HIRES_P1+$13a8,y
a96b: 8a txa
a96c: 39 a8 37 and HIRES_P1+$17a8,y
a96f: 99 a8 37 sta HIRES_P1+$17a8,y
a972: 8a txa
a973: 39 a8 3b and HIRES_P1+$1ba8,y
a976: 99 a8 3b sta HIRES_P1+$1ba8,y
a979: 8a txa
a97a: 39 a8 3f and HIRES_P1+$1fa8,y
a97d: 99 a8 3f sta HIRES_P1+$1fa8,y
a980: 8a txa
a981: 39 50 20 and HIRES_P1+80,y
a984: 99 50 20 sta HIRES_P1+80,y
a987: 8a txa
a988: 39 50 24 and HIRES_P1+$450,y
a98b: 99 50 24 sta HIRES_P1+$450,y
a98e: 8a txa
a98f: 39 50 28 and HIRES_P1+$850,y
a992: 99 50 28 sta HIRES_P1+$850,y
a995: 8a txa
a996: 39 50 2c and HIRES_P1+$c50,y
a999: 99 50 2c sta HIRES_P1+$c50,y
a99c: 8a txa
a99d: 39 50 30 and HIRES_P1+$1050,y
a9a0: 99 50 30 sta HIRES_P1+$1050,y
a9a3: 8a txa
a9a4: 39 50 34 and HIRES_P1+$1450,y
a9a7: 99 50 34 sta HIRES_P1+$1450,y
a9aa: 8a txa
a9ab: 39 50 38 and HIRES_P1+$1850,y
a9ae: 99 50 38 sta HIRES_P1+$1850,y
a9b1: 8a txa
a9b2: 39 50 3c and HIRES_P1+$1c50,y
a9b5: 99 50 3c sta HIRES_P1+$1c50,y
a9b8: 8a txa
a9b9: 39 d0 20 and HIRES_P1+208,y
a9bc: 99 d0 20 sta HIRES_P1+208,y
a9bf: 8a txa
a9c0: 39 d0 24 and HIRES_P1+$4d0,y
a9c3: 99 d0 24 sta HIRES_P1+$4d0,y
a9c6: 8a txa
a9c7: 39 d0 28 and HIRES_P1+$8d0,y
a9ca: 99 d0 28 sta HIRES_P1+$8d0,y
a9cd: 8a txa
a9ce: 39 d0 2c and HIRES_P1+$cd0,y
a9d1: 99 d0 2c sta HIRES_P1+$cd0,y
a9d4: 8a txa
a9d5: 39 d0 30 and HIRES_P1+$10d0,y
a9d8: 99 d0 30 sta HIRES_P1+$10d0,y
a9db: 8a txa
a9dc: 39 d0 34 and HIRES_P1+$14d0,y
a9df: 99 d0 34 sta HIRES_P1+$14d0,y
a9e2: 8a txa
a9e3: 39 d0 38 and HIRES_P1+$18d0,y
a9e6: 99 d0 38 sta HIRES_P1+$18d0,y
a9e9: 8a txa
a9ea: 39 d0 3c and HIRES_P1+$1cd0,y
a9ed: 99 d0 3c sta HIRES_P1+$1cd0,y
a9f0: 8a txa
a9f1: 39 50 21 and HIRES_P1+$150,y
a9f4: 99 50 21 sta HIRES_P1+$150,y
a9f7: 8a txa
a9f8: 39 50 25 and HIRES_P1+$550,y
a9fb: 99 50 25 sta HIRES_P1+$550,y
a9fe: 8a txa
a9ff: 39 50 29 and HIRES_P1+$950,y
aa02: 99 50 29 sta HIRES_P1+$950,y
aa05: 8a txa
aa06: 39 50 2d and HIRES_P1+$d50,y
aa09: 99 50 2d sta HIRES_P1+$d50,y
aa0c: 8a txa
aa0d: 39 50 31 and HIRES_P1+$1150,y
aa10: 99 50 31 sta HIRES_P1+$1150,y
aa13: 8a txa
aa14: 39 50 35 and HIRES_P1+$1550,y
aa17: 99 50 35 sta HIRES_P1+$1550,y
aa1a: 8a txa
aa1b: 39 50 39 and HIRES_P1+$1950,y
aa1e: 99 50 39 sta HIRES_P1+$1950,y
aa21: 8a txa
aa22: 39 50 3d and HIRES_P1+$1d50,y
aa25: 99 50 3d sta HIRES_P1+$1d50,y
aa28: 8a txa
aa29: 39 d0 21 and HIRES_P1+$1d0,y
aa2c: 99 d0 21 sta HIRES_P1+$1d0,y
aa2f: 8a txa
aa30: 39 d0 25 and HIRES_P1+$5d0,y
aa33: 99 d0 25 sta HIRES_P1+$5d0,y
aa36: 8a txa
aa37: 39 d0 29 and HIRES_P1+$9d0,y
aa3a: 99 d0 29 sta HIRES_P1+$9d0,y
aa3d: 8a txa
aa3e: 39 d0 2d and HIRES_P1+$dd0,y
aa41: 99 d0 2d sta HIRES_P1+$dd0,y
aa44: 8a txa
aa45: 39 d0 31 and HIRES_P1+$11d0,y
aa48: 99 d0 31 sta HIRES_P1+$11d0,y
aa4b: 8a txa
aa4c: 39 d0 35 and HIRES_P1+$15d0,y
aa4f: 99 d0 35 sta HIRES_P1+$15d0,y
aa52: 8a txa
aa53: 39 d0 39 and HIRES_P1+$19d0,y
aa56: 99 d0 39 sta HIRES_P1+$19d0,y
aa59: 8a txa
aa5a: 39 d0 3d and HIRES_P1+$1dd0,y
aa5d: 99 d0 3d sta HIRES_P1+$1dd0,y
aa60: 8a txa
aa61: 39 50 22 and HIRES_P1+$250,y
aa64: 99 50 22 sta HIRES_P1+$250,y
aa67: 8a txa
aa68: 39 50 26 and HIRES_P1+$650,y
aa6b: 99 50 26 sta HIRES_P1+$650,y
aa6e: 8a txa
aa6f: 39 50 2a and HIRES_P1+$a50,y
aa72: 99 50 2a sta HIRES_P1+$a50,y
aa75: 8a txa
aa76: 39 50 2e and HIRES_P1+$e50,y
aa79: 99 50 2e sta HIRES_P1+$e50,y
aa7c: 8a txa
aa7d: 39 50 32 and HIRES_P1+$1250,y
aa80: 99 50 32 sta HIRES_P1+$1250,y
aa83: 8a txa
aa84: 39 50 36 and HIRES_P1+$1650,y
aa87: 99 50 36 sta HIRES_P1+$1650,y
aa8a: 8a txa
aa8b: 39 50 3a and HIRES_P1+$1a50,y
aa8e: 99 50 3a sta HIRES_P1+$1a50,y
aa91: 8a txa
aa92: 39 50 3e and HIRES_P1+$1e50,y
aa95: 99 50 3e sta HIRES_P1+$1e50,y
aa98: 8a txa
aa99: 39 d0 22 and HIRES_P1+$2d0,y
aa9c: 99 d0 22 sta HIRES_P1+$2d0,y
aa9f: 8a txa
aaa0: 39 d0 26 and HIRES_P1+$6d0,y
aaa3: 99 d0 26 sta HIRES_P1+$6d0,y
aaa6: 8a txa
aaa7: 39 d0 2a and HIRES_P1+$ad0,y
aaaa: 99 d0 2a sta HIRES_P1+$ad0,y
aaad: 8a txa
aaae: 39 d0 2e and HIRES_P1+$ed0,y
aab1: 99 d0 2e sta HIRES_P1+$ed0,y
aab4: 8a txa
aab5: 39 d0 32 and HIRES_P1+$12d0,y
aab8: 99 d0 32 sta HIRES_P1+$12d0,y
aabb: 8a txa
aabc: 39 d0 36 and HIRES_P1+$16d0,y
aabf: 99 d0 36 sta HIRES_P1+$16d0,y
aac2: 8a txa
aac3: 39 d0 3a and HIRES_P1+$1ad0,y
aac6: 99 d0 3a sta HIRES_P1+$1ad0,y
aac9: 8a txa
aaca: 39 d0 3e and HIRES_P1+$1ed0,y
aacd: 99 d0 3e sta HIRES_P1+$1ed0,y
aad0: 8a txa
aad1: 39 50 23 and HIRES_P1+$350,y
aad4: 99 50 23 sta HIRES_P1+$350,y
aad7: 8a txa
aad8: 39 50 27 and HIRES_P1+$750,y
aadb: 99 50 27 sta HIRES_P1+$750,y
aade: 8a txa
aadf: 39 50 2b and HIRES_P1+$b50,y
aae2: 99 50 2b sta HIRES_P1+$b50,y
aae5: 8a txa
aae6: 39 50 2f and HIRES_P1+$f50,y
aae9: 99 50 2f sta HIRES_P1+$f50,y
aaec: 8a txa
aaed: 39 50 33 and HIRES_P1+$1350,y
aaf0: 99 50 33 sta HIRES_P1+$1350,y
aaf3: 8a txa
aaf4: 39 50 37 and HIRES_P1+$1750,y
aaf7: 99 50 37 sta HIRES_P1+$1750,y
aafa: 8a txa
aafb: 39 50 3b and HIRES_P1+$1b50,y
aafe: 99 50 3b sta HIRES_P1+$1b50,y
ab01: 8a txa
ab02: 39 50 3f and HIRES_P1+$1f50,y
ab05: 99 50 3f sta HIRES_P1+$1f50,y
ab08: 8a txa
ab09: 39 d0 23 and HIRES_P1+$3d0,y
ab0c: 99 d0 23 sta HIRES_P1+$3d0,y
ab0f: 8a txa
ab10: 39 d0 27 and HIRES_P1+$7d0,y
ab13: 99 d0 27 sta HIRES_P1+$7d0,y
ab16: 8a txa
ab17: 39 d0 2b and HIRES_P1+$bd0,y
ab1a: 99 d0 2b sta HIRES_P1+$bd0,y
ab1d: 8a txa
ab1e: 39 d0 2f and HIRES_P1+$fd0,y
ab21: 99 d0 2f sta HIRES_P1+$fd0,y
ab24: 8a txa
ab25: 39 d0 33 and HIRES_P1+$13d0,y
ab28: 99 d0 33 sta HIRES_P1+$13d0,y
ab2b: 8a txa
ab2c: 39 d0 37 and HIRES_P1+$17d0,y
ab2f: 99 d0 37 sta HIRES_P1+$17d0,y
ab32: 8a txa
ab33: 39 d0 3b and HIRES_P1+$1bd0,y
ab36: 99 d0 3b sta HIRES_P1+$1bd0,y
ab39: 8a txa
ab3a: 39 d0 3f and HIRES_P1+$1fd0,y
ab3d: 99 d0 3f sta HIRES_P1+$1fd0,y
ab40: 60 rts
ab41: 60 a0 20 99+ .align $0100 (191 bytes)
;
; Math table #2, maps ? to ?. The result is generally used as an index into
; math table #1 (at $1000).
;
; This is indexed with a 16-bit value that is effectively reduced to 11 bits.
; For example, if we want to retrieve a value for %00001ABC DEFGHIJKL, we count
; the leading zeroes (4), use that to create an AND mask (%11110000) that is
; applied to the low byte, and then we OR the bytes together (DEFG1ABC). The
; count of leading zeroes (0-8) is used as an index into the 9 256-byte pages
; that follow.
;
; The situation where the high byte is zero is special-cased in the code.
;
; The general effect is of decreasing precision as the values get larger.
;
; It might seem that parts of the table will go unused, e.g. the page for lz=6
; handles $02xx and $03xx, so only entries whose indices end with %10 or %11
; will be accessed. In practice, the leading-zero count may be established for
; the Z coordinate, and then lookups performed for the X/Y coordinates, so the
; full range of values is possible.
ac00: 00 01 02 03+ math_tab2_base? .bulk $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e,$0f
+ $10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$1a,$1b,$1c,$1d,$1e,$1f
+ $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$2d,$2e,$2f
+ $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f
+ $40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f
+ $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5a,$5b,$5c,$5d,$5e,$5f
+ $60,$61,$62,$63,$64,$65,$66,$67,$68,$69,$6a,$6b,$6c,$6d,$6e,$6f
+ $70,$71,$72,$73,$74,$75,$76,$77,$78,$79,$7a,$7b,$7c,$7d,$7e,$7f
+ $80,$81,$82,$83,$84,$85,$86,$87,$88,$89,$8a,$8b,$8c,$8d,$8e,$8f
+ $90,$91,$92,$93,$94,$95,$96,$97,$98,$99,$9a,$9b,$9c,$9d,$9e,$9f
+ $a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7,$a8,$a9,$aa,$ab,$ac,$ad,$ae,$af
+ $b0,$b1,$b2,$b3,$b4,$b5,$b6,$b7,$b8,$b9,$ba,$bb,$bc,$bd,$be,$bf
+ $c0,$c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8,$c9,$ca,$cb,$cc,$cd,$ce,$cf
+ $d0,$d1,$d2,$d3,$d4,$d5,$d6,$d7,$d8,$d9,$da,$db,$dc,$dd,$de,$df
+ $e0,$e1,$e2,$e3,$e4,$e5,$e6,$e7,$e8,$e9,$ea,$eb,$ec,$ed,$ee,$ef
+ $f0,$f1,$f2,$f3,$f4,$f5,$f6,$f7,$f8,$f9,$fa,$fb,$fc,$fd,$fe,$ff
ad00: 00 02 04 06+ .bulk $00,$02,$04,$06,$08,$0a,$0c,$0e,$10,$12,$14,$16,$18,$1a,$1c,$1e
+ $20,$22,$24,$26,$28,$2a,$2c,$2e,$30,$32,$34,$36,$38,$3a,$3c,$3e
+ $40,$42,$44,$46,$48,$4a,$4c,$4e,$50,$52,$54,$56,$58,$5a,$5c,$5e
+ $60,$62,$64,$66,$68,$6a,$6c,$6e,$70,$72,$74,$76,$78,$7a,$7c,$7e
+ $80,$82,$84,$86,$88,$8a,$8c,$8e,$90,$92,$94,$96,$98,$9a,$9c,$9e
+ $a0,$a2,$a4,$a6,$a8,$aa,$ac,$ae,$b0,$b2,$b4,$b6,$b8,$ba,$bc,$be
+ $c0,$c2,$c4,$c6,$c8,$ca,$cc,$ce,$d0,$d2,$d4,$d6,$d8,$da,$dc,$de
+ $e0,$e2,$e4,$e6,$e8,$ea,$ec,$ee,$f0,$f2,$f4,$f6,$f8,$fa,$fc,$fe
+ $01,$03,$05,$07,$09,$0b,$0d,$0f,$11,$13,$15,$17,$19,$1b,$1d,$1f
+ $21,$23,$25,$27,$29,$2b,$2d,$2f,$31,$33,$35,$37,$39,$3b,$3d,$3f
+ $41,$43,$45,$47,$49,$4b,$4d,$4f,$51,$53,$55,$57,$59,$5b,$5d,$5f
+ $61,$63,$65,$67,$69,$6b,$6d,$6f,$71,$73,$75,$77,$79,$7b,$7d,$7f
+ $81,$83,$85,$87,$89,$8b,$8d,$8f,$91,$93,$95,$97,$99,$9b,$9d,$9f
+ $a1,$a3,$a5,$a7,$a9,$ab,$ad,$af,$b1,$b3,$b5,$b7,$b9,$bb,$bd,$bf
+ $c1,$c3,$c5,$c7,$c9,$cb,$cd,$cf,$d1,$d3,$d5,$d7,$d9,$db,$dd,$df
+ $e1,$e3,$e5,$e7,$e9,$eb,$ed,$ef,$f1,$f3,$f5,$f7,$f9,$fb,$fd,$ff
ae00: 00 04 08 0c+ .bulk $00,$04,$08,$0c,$10,$14,$18,$1c,$20,$24,$28,$2c,$30,$34,$38,$3c
+ $40,$44,$48,$4c,$50,$54,$58,$5c,$60,$64,$68,$6c,$70,$74,$78,$7c
+ $80,$84,$88,$8c,$90,$94,$98,$9c,$a0,$a4,$a8,$ac,$b0,$b4,$b8,$bc
+ $c0,$c4,$c8,$cc,$d0,$d4,$d8,$dc,$e0,$e4,$e8,$ec,$f0,$f4,$f8,$fc
+ $01,$05,$09,$0d,$11,$15,$19,$1d,$21,$25,$29,$2d,$31,$35,$39,$3d
+ $41,$45,$49,$4d,$51,$55,$59,$5d,$61,$65,$69,$6d,$71,$75,$79,$7d
+ $81,$85,$89,$8d,$91,$95,$99,$9d,$a1,$a5,$a9,$ad,$b1,$b5,$b9,$bd
+ $c1,$c5,$c9,$cd,$d1,$d5,$d9,$dd,$e1,$e5,$e9,$ed,$f1,$f5,$f9,$fd
+ $02,$06,$0a,$0e,$12,$16,$1a,$1e,$22,$26,$2a,$2e,$32,$36,$3a,$3e
+ $42,$46,$4a,$4e,$52,$56,$5a,$5e,$62,$66,$6a,$6e,$72,$76,$7a,$7e
+ $82,$86,$8a,$8e,$92,$96,$9a,$9e,$a2,$a6,$aa,$ae,$b2,$b6,$ba,$be
+ $c2,$c6,$ca,$ce,$d2,$d6,$da,$de,$e2,$e6,$ea,$ee,$f2,$f6,$fa,$fe
+ $03,$07,$0b,$0f,$13,$17,$1b,$1f,$23,$27,$2b,$2f,$33,$37,$3b,$3f
+ $43,$47,$4b,$4f,$53,$57,$5b,$5f,$63,$67,$6b,$6f,$73,$77,$7b,$7f
+ $83,$87,$8b,$8f,$93,$97,$9b,$9f,$a3,$a7,$ab,$af,$b3,$b7,$bb,$bf
+ $c3,$c7,$cb,$cf,$d3,$d7,$db,$df,$e3,$e7,$eb,$ef,$f3,$f7,$fb,$ff
af00: 00 08 10 18+ .bulk $00,$08,$10,$18,$20,$28,$30,$38,$40,$48,$50,$58,$60,$68,$70,$78
+ $80,$88,$90,$98,$a0,$a8,$b0,$b8,$c0,$c8,$d0,$d8,$e0,$e8,$f0,$f8
+ $01,$09,$11,$19,$21,$29,$31,$39,$41,$49,$51,$59,$61,$69,$71,$79
+ $81,$89,$91,$99,$a1,$a9,$b1,$b9,$c1,$c9,$d1,$d9,$e1,$e9,$f1,$f9
+ $02,$0a,$12,$1a,$22,$2a,$32,$3a,$42,$4a,$52,$5a,$62,$6a,$72,$7a
+ $82,$8a,$92,$9a,$a2,$aa,$b2,$ba,$c2,$ca,$d2,$da,$e2,$ea,$f2,$fa
+ $03,$0b,$13,$1b,$23,$2b,$33,$3b,$43,$4b,$53,$5b,$63,$6b,$73,$7b
+ $83,$8b,$93,$9b,$a3,$ab,$b3,$bb,$c3,$cb,$d3,$db,$e3,$eb,$f3,$fb
+ $04,$0c,$14,$1c,$24,$2c,$34,$3c,$44,$4c,$54,$5c,$64,$6c,$74,$7c
+ $84,$8c,$94,$9c,$a4,$ac,$b4,$bc,$c4,$cc,$d4,$dc,$e4,$ec,$f4,$fc
+ $05,$0d,$15,$1d,$25,$2d,$35,$3d,$45,$4d,$55,$5d,$65,$6d,$75,$7d
+ $85,$8d,$95,$9d,$a5,$ad,$b5,$bd,$c5,$cd,$d5,$dd,$e5,$ed,$f5,$fd
+ $06,$0e,$16,$1e,$26,$2e,$36,$3e,$46,$4e,$56,$5e,$66,$6e,$76,$7e
+ $86,$8e,$96,$9e,$a6,$ae,$b6,$be,$c6,$ce,$d6,$de,$e6,$ee,$f6,$fe
+ $07,$0f,$17,$1f,$27,$2f,$37,$3f,$47,$4f,$57,$5f,$67,$6f,$77,$7f
+ $87,$8f,$97,$9f,$a7,$af,$b7,$bf,$c7,$cf,$d7,$df,$e7,$ef,$f7,$ff
b000: 00 10 20 30+ speed_table? .bulk $00,$10,$20,$30,$40,$50,$60,$70,$80,$90,$a0,$b0,$c0,$d0,$e0,$f0
+ $01,$11,$21,$31,$41,$51,$61,$71,$81,$91,$a1,$b1,$c1,$d1,$e1,$f1
+ $02,$12,$22,$32,$42,$52,$62,$72,$82,$92,$a2,$b2,$c2,$d2,$e2,$f2
+ $03,$13,$23,$33,$43,$53,$63,$73,$83,$93,$a3,$b3,$c3,$d3,$e3,$f3
+ $04,$14,$24,$34,$44,$54,$64,$74,$84,$94,$a4,$b4,$c4,$d4,$e4,$f4
+ $05,$15,$25,$35,$45,$55,$65,$75,$85,$95,$a5,$b5,$c5,$d5,$e5,$f5
+ $06,$16,$26,$36,$46,$56,$66,$76,$86,$96,$a6,$b6,$c6,$d6,$e6,$f6
+ $07,$17,$27,$37,$47,$57,$67,$77,$87,$97,$a7,$b7,$c7,$d7,$e7,$f7
+ $08,$18,$28,$38,$48,$58,$68,$78,$88,$98,$a8,$b8,$c8,$d8,$e8,$f8
+ $09,$19,$29,$39,$49,$59,$69,$79,$89,$99,$a9,$b9,$c9,$d9,$e9,$f9
+ $0a,$1a,$2a,$3a,$4a,$5a,$6a,$7a,$8a,$9a,$aa,$ba,$ca,$da,$ea,$fa
+ $0b,$1b,$2b,$3b,$4b,$5b,$6b,$7b,$8b,$9b,$ab,$bb,$cb,$db,$eb,$fb
+ $0c,$1c,$2c,$3c,$4c,$5c,$6c,$7c,$8c,$9c,$ac,$bc,$cc,$dc,$ec,$fc
+ $0d,$1d,$2d,$3d,$4d,$5d,$6d,$7d,$8d,$9d,$ad,$bd,$cd,$dd,$ed,$fd
+ $0e,$1e,$2e,$3e,$4e,$5e,$6e,$7e,$8e,$9e,$ae,$be,$ce,$de,$ee,$fe
+ $0f,$1f,$2f,$3f,$4f,$5f,$6f,$7f,$8f,$9f,$af,$bf,$cf,$df,$ef,$ff
b100: 00 20 40 60+ .bulk $00,$20,$40,$60,$80,$a0,$c0,$e0,$01,$21,$41,$61,$81,$a1,$c1,$e1
+ $02,$22,$42,$62,$82,$a2,$c2,$e2,$03,$23,$43,$63,$83,$a3,$c3,$e3
+ $04,$24,$44,$64,$84,$a4,$c4,$e4,$05,$25,$45,$65,$85,$a5,$c5,$e5
+ $06,$26,$46,$66,$86,$a6,$c6,$e6,$07,$27,$47,$67,$87,$a7,$c7,$e7
+ $08,$28,$48,$68,$88,$a8,$c8,$e8,$09,$29,$49,$69,$89,$a9,$c9,$e9
+ $0a,$2a,$4a,$6a,$8a,$aa,$ca,$ea,$0b,$2b,$4b,$6b,$8b,$ab,$cb,$eb
+ $0c,$2c,$4c,$6c,$8c,$ac,$cc,$ec,$0d,$2d,$4d,$6d,$8d,$ad,$cd,$ed
+ $0e,$2e,$4e,$6e,$8e,$ae,$ce,$ee,$0f,$2f,$4f,$6f,$8f,$af,$cf,$ef
+ $10,$30,$50,$70,$90,$b0,$d0,$f0,$11,$31,$51,$71,$91,$b1,$d1,$f1
+ $12,$32,$52,$72,$92,$b2,$d2,$f2,$13,$33,$53,$73,$93,$b3,$d3,$f3
+ $14,$34,$54,$74,$94,$b4,$d4,$f4,$15,$35,$55,$75,$95,$b5,$d5,$f5
+ $16,$36,$56,$76,$96,$b6,$d6,$f6,$17,$37,$57,$77,$97,$b7,$d7,$f7
+ $18,$38,$58,$78,$98,$b8,$d8,$f8,$19,$39,$59,$79,$99,$b9,$d9,$f9
+ $1a,$3a,$5a,$7a,$9a,$ba,$da,$fa,$1b,$3b,$5b,$7b,$9b,$bb,$db,$fb
+ $1c,$3c,$5c,$7c,$9c,$bc,$dc,$fc,$1d,$3d,$5d,$7d,$9d,$bd,$dd,$fd
+ $1e,$3e,$5e,$7e,$9e,$be,$de,$fe,$1f,$3f,$5f,$7f,$9f,$bf,$df,$ff
b200: 00 40 80 c0+ .bulk $00,$40,$80,$c0,$01,$41,$81,$c1,$02,$42,$82,$c2,$03,$43,$83,$c3
+ $04,$44,$84,$c4,$05,$45,$85,$c5,$06,$46,$86,$c6,$07,$47,$87,$c7
+ $08,$48,$88,$c8,$09,$49,$89,$c9,$0a,$4a,$8a,$ca,$0b,$4b,$8b,$cb
+ $0c,$4c,$8c,$cc,$0d,$4d,$8d,$cd,$0e,$4e,$8e,$ce,$0f,$4f,$8f,$cf
+ $10,$50,$90,$d0,$11,$51,$91,$d1,$12,$52,$92,$d2,$13,$53,$93,$d3
+ $14,$54,$94,$d4,$15,$55,$95,$d5,$16,$56,$96,$d6,$17,$57,$97,$d7
+ $18,$58,$98,$d8,$19,$59,$99,$d9,$1a,$5a,$9a,$da,$1b,$5b,$9b,$db
+ $1c,$5c,$9c,$dc,$1d,$5d,$9d,$dd,$1e,$5e,$9e,$de,$1f,$5f,$9f,$df
+ $20,$60,$a0,$e0,$21,$61,$a1,$e1,$22,$62,$a2,$e2,$23,$63,$a3,$e3
+ $24,$64,$a4,$e4,$25,$65,$a5,$e5,$26,$66,$a6,$e6,$27,$67,$a7,$e7
+ $28,$68,$a8,$e8,$29,$69,$a9,$e9,$2a,$6a,$aa,$ea,$2b,$6b,$ab,$eb
+ $2c,$6c,$ac,$ec,$2d,$6d,$ad,$ed,$2e,$6e,$ae,$ee,$2f,$6f,$af,$ef
+ $30,$70,$b0,$f0,$31,$71,$b1,$f1,$32,$72,$b2,$f2,$33,$73,$b3,$f3
+ $34,$74,$b4,$f4,$35,$75,$b5,$f5,$36,$76,$b6,$f6,$37,$77,$b7,$f7
+ $38,$78,$b8,$f8,$39,$79,$b9,$f9,$3a,$7a,$ba,$fa,$3b,$7b,$bb,$fb
+ $3c,$7c,$bc,$fc,$3d,$7d,$bd,$fd,$3e,$7e,$be,$fe,$3f,$7f,$bf,$ff
b300: 00 80 01 81+ .bulk $00,$80,$01,$81,$02,$82,$03,$83,$04,$84,$05,$85,$06,$86,$07,$87 ;lz=7; even bytes unused
+ $08,$88,$09,$89,$0a,$8a,$0b,$8b,$0c,$8c,$0d,$8d,$0e,$8e,$0f,$8f
+ $10,$90,$11,$91,$12,$92,$13,$93,$14,$94,$15,$95,$16,$96,$17,$97
+ $18,$98,$19,$99,$1a,$9a,$1b,$9b,$1c,$9c,$1d,$9d,$1e,$9e,$1f,$9f
+ $20,$a0,$21,$a1,$22,$a2,$23,$a3,$24,$a4,$25,$a5,$26,$a6,$27,$a7
+ $28,$a8,$29,$a9,$2a,$aa,$2b,$ab,$2c,$ac,$2d,$ad,$2e,$ae,$2f,$af
+ $30,$b0,$31,$b1,$32,$b2,$33,$b3,$34,$b4,$35,$b5,$36,$b6,$37,$b7
+ $38,$b8,$39,$b9,$3a,$ba,$3b,$bb,$3c,$bc,$3d,$bd,$3e,$be,$3f,$bf
+ $40,$c0,$41,$c1,$42,$c2,$43,$c3,$44,$c4,$45,$c5,$46,$c6,$47,$c7
+ $48,$c8,$49,$c9,$4a,$ca,$4b,$cb,$4c,$cc,$4d,$cd,$4e,$ce,$4f,$cf
+ $50,$d0,$51,$d1,$52,$d2,$53,$d3,$54,$d4,$55,$d5,$56,$d6,$57,$d7
+ $58,$d8,$59,$d9,$5a,$da,$5b,$db,$5c,$dc,$5d,$dd,$5e,$de,$5f,$df
+ $60,$e0,$61,$e1,$62,$e2,$63,$e3,$64,$e4,$65,$e5,$66,$e6,$67,$e7
+ $68,$e8,$69,$e9,$6a,$ea,$6b,$eb,$6c,$ec,$6d,$ed,$6e,$ee,$6f,$ef
+ $70,$f0,$71,$f1,$72,$f2,$73,$f3,$74,$f4,$75,$f5,$76,$f6,$77,$f7
+ $78,$f8,$79,$f9,$7a,$fa,$7b,$fb,$7c,$fc,$7d,$fd,$7e,$fe,$7f,$ff
b400: 00 01 02 03+ .bulk $00,$01,$02,$03,$04,$05,$06,$07,$08,$09,$0a,$0b,$0c,$0d,$0e,$0f ;for high byte == 0
+ $10,$11,$12,$13,$14,$15,$16,$17,$18,$19,$1a,$1b,$1c,$1d,$1e,$1f
+ $20,$21,$22,$23,$24,$25,$26,$27,$28,$29,$2a,$2b,$2c,$2d,$2e,$2f
+ $30,$31,$32,$33,$34,$35,$36,$37,$38,$39,$3a,$3b,$3c,$3d,$3e,$3f
+ $40,$41,$42,$43,$44,$45,$46,$47,$48,$49,$4a,$4b,$4c,$4d,$4e,$4f
+ $50,$51,$52,$53,$54,$55,$56,$57,$58,$59,$5a,$5b,$5c,$5d,$5e,$5f
+ $60,$61,$62,$63,$64,$65,$66,$67,$68,$69,$6a,$6b,$6c,$6d,$6e,$6f
+ $70,$71,$72,$73,$74,$75,$76,$77,$78,$79,$7a,$7b,$7c,$7d,$7e,$7f
+ $80,$81,$82,$83,$84,$85,$86,$87,$88,$89,$8a,$8b,$8c,$8d,$8e,$8f
+ $90,$91,$92,$93,$94,$95,$96,$97,$98,$99,$9a,$9b,$9c,$9d,$9e,$9f
+ $a0,$a1,$a2,$a3,$a4,$a5,$a6,$a7,$a8,$a9,$aa,$ab,$ac,$ad,$ae,$af
+ $b0,$b1,$b2,$b3,$b4,$b5,$b6,$b7,$b8,$b9,$ba,$bb,$bc,$bd,$be,$bf
+ $c0,$c1,$c2,$c3,$c4,$c5,$c6,$c7,$c8,$c9,$ca,$cb,$cc,$cd,$ce,$cf
+ $d0,$d1,$d2,$d3,$d4,$d5,$d6,$d7,$d8,$d9,$da,$db,$dc,$dd,$de,$df
+ $e0,$e1,$e2,$e3,$e4,$e5,$e6,$e7,$e8,$e9,$ea,$eb,$ec,$ed,$ee,$ef
+ $f0,$f1,$f2,$f3,$f4,$f5,$f6,$f7,$f8,$f9,$fa,$fb,$fc,$fd,$fe,$ff
;
; Math table #3, maps ? to ?.
;
; Appears to be lo/hi 16-bit value in the range [$0000,$07ff].
;
; Used to map joystick deflection to horizontal and vertical turn rate;
; AppleWin's joystick emulation generates indexes 0-101.
b500: 00 00 00 96+ turn_map_lo? .bulk $00,$00,$00,$96,$00,$52,$96,$cf,$00,$2b,$52,$76,$96,$b3,$cf,$e8
+ $00,$16,$2c,$3f,$52,$64,$76,$86,$96,$a5,$b3,$c1,$cf,$dc,$e8,$f4
+ $00,$0b,$16,$21,$2b,$36,$3f,$49,$52,$5c,$64,$6d,$76,$7e,$86,$8e
+ $96,$9d,$a5,$ac,$b3,$ba,$c1,$c8,$cf,$d5,$dc,$e2,$e8,$ee,$f4,$fa
+ $00,$06,$0b,$11,$16,$1c,$21,$26,$2b,$31,$36,$3b,$3f,$44,$49,$4e
+ $52,$57,$5c,$60,$64,$69,$6d,$71,$76,$7a,$7e,$82,$86,$8a,$8e,$92
+ $96,$9a,$9d,$a1,$a5,$a8,$ac,$b0,$b3,$b7,$ba,$be,$c1,$c5,$c8,$cb
+ $cf,$d2,$d5,$d8,$dc,$df,$e2,$e5,$e8,$eb,$ee,$f1,$f4,$f7,$fa,$fd
+ $00,$03,$06,$08,$0b,$0e,$11,$14,$16,$19,$1c,$1e,$21,$24,$26,$29
+ $2b,$2e,$31,$33,$36,$38,$3b,$3d,$3f,$42,$44,$47,$49,$4b,$4e,$50
+ $52,$55,$57,$59,$5b,$5e,$60,$62,$64,$67,$69,$6b,$6d,$6f,$71,$73
+ $76,$78,$7a,$7c,$7e,$80,$82,$84,$86,$88,$8a,$8c,$8e,$90,$92,$94
+ $96,$98,$99,$9b,$9d,$9f,$a1,$a3,$a5,$a7,$a8,$aa,$ac,$ae,$b0,$b1
+ $b3,$b5,$b7,$b9,$ba,$bc,$be,$bf,$c1,$c3,$c5,$c6,$c8,$ca,$cb,$cd
+ $cf,$d0,$d2,$d4,$d5,$d7,$d8,$da,$dc,$dd,$df,$e0,$e2,$e3,$e5,$e7
+ $e8,$ea,$eb,$ed,$ee,$f0,$f1,$f3,$f4,$f6,$f7,$f9,$fa,$fc,$fd,$fe
b600: 00 00 01 01+ turn_map_hi? .bulk $00,$00,$01,$01,$02,$02,$02,$02,$03,$03,$03,$03,$03,$03,$03,$03
+ $04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04,$04
+ $05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05
+ $05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05,$05
+ $06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06
+ $06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06
+ $06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06
+ $06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06,$06
+ $07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07
+ $07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07
+ $07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07
+ $07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07
+ $07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07
+ $07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07
+ $07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07
+ $07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07,$07
;
; Points of interest in the unrolled hi-res AND/OR stores, indexed by hi-res
; line number. Lines from 192-255 go to a no-op RTS.
;
; There's a series of ORA/STA commands from $1800-1dff, and a series of AND/STA
; commands from $a600-abff.
;
; Both sets of tables use the same low byte. The high byte comes from tables at
; $5500 and $b800.
;
unroll_a_o_addr_lo
b700: 00 07 0e 15+ .bulk $00,$07,$0e,$15,$1c,$23,$2a,$31,$38,$3f,$46,$4d,$54,$5b,$62,$69
+ $70,$77,$7e,$85,$8c,$93,$9a,$a1,$a8,$af,$b6,$bd,$c4,$cb,$d2,$d9
+ $e0,$e7,$ee,$f5,$fc,$03,$0a,$11,$18,$1f,$26,$2d,$34,$3b,$42,$49
+ $50,$57,$5e,$65,$6c,$73,$7a,$81,$88,$8f,$96,$9d,$a4,$ab,$b2,$b9
+ $c0,$c7,$ce,$d5,$dc,$e3,$ea,$f1,$f8,$ff,$06,$0d,$14,$1b,$22,$29
+ $30,$37,$3e,$45,$4c,$53,$5a,$61,$68,$6f,$76,$7d,$84,$8b,$92,$99
+ $a0,$a7,$ae,$b5,$bc,$c3,$ca,$d1,$d8,$df,$e6,$ed,$f4,$fb,$02,$09
+ $10,$17,$1e,$25,$2c,$33,$3a,$41,$48,$4f,$56,$5d,$64,$6b,$72,$79
+ $80,$87,$8e,$95,$9c,$a3,$aa,$b1,$b8,$bf,$c6,$cd,$d4,$db,$e2,$e9
+ $f0,$f7,$fe,$05,$0c,$13,$1a,$21,$28,$2f,$36,$3d,$44,$4b,$52,$59
+ $60,$67,$6e,$75,$7c,$83,$8a,$91,$98,$9f,$a6,$ad,$b4,$bb,$c2,$c9
+ $d0,$d7,$de,$e5,$ec,$f3,$fa,$01,$08,$0f,$16,$1d,$24,$2b,$32,$39
+ $40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40
+ $40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40
+ $40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40
+ $40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40,$40
;
; High byte of address of unrolled ORA instructions.
unroll_ora_addr_hi
b800: 18 18 18 18+ .bulk $18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18
+ $18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18,$18
+ $18,$18,$18,$18,$18,$19,$19,$19,$19,$19,$19,$19,$19,$19,$19,$19
+ $19,$19,$19,$19,$19,$19,$19,$19,$19,$19,$19,$19,$19,$19,$19,$19
+ $19,$19,$19,$19,$19,$19,$19,$19,$19,$19,$1a,$1a,$1a,$1a,$1a,$1a
+ $1a,$1a,$1a,$1a,$1a,$1a,$1a,$1a,$1a,$1a,$1a,$1a,$1a,$1a,$1a,$1a
+ $1a,$1a,$1a,$1a,$1a,$1a,$1a,$1a,$1a,$1a,$1a,$1a,$1a,$1a,$1b,$1b
+ $1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b
+ $1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1b
+ $1b,$1b,$1b,$1c,$1c,$1c,$1c,$1c,$1c,$1c,$1c,$1c,$1c,$1c,$1c,$1c
+ $1c,$1c,$1c,$1c,$1c,$1c,$1c,$1c,$1c,$1c,$1c,$1c,$1c,$1c,$1c,$1c
+ $1c,$1c,$1c,$1c,$1c,$1c,$1c,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d
+ $1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d
+ $1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d
+ $1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d
+ $1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d,$1d
;
; This provides the number of leading zero bits in an 8-bit value ("count
; leading zeroes"). On a modern system you'd do this with something like gcc's
; __builtin_clz().
;
; Mathematically, it's 8 minus the binary order of N:
; 8 - ceiling(log2(N))
;
; 0: %00000000 = 8
; 1: %00000001 = 7
; 2: %00000010 = 6
; 3: %00000011 = 6
; 4: %00000100 = 5
; 5: %00000101 = 5
; ...
; 255: %11111111 = 0
b900: 08 07 06 06+ clz_table .bulk $08,$07,$06,$06,$05,$05,$05,$05,$04,$04,$04,$04,$04,$04,$04,$04
+ $03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03,$03
+ $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
+ $02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02,$02
+ $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01
+ $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01
+ $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01
+ $01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01,$01
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
+ $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
;
; Hi-res line start address, low byte.
ba00: 00 00 00 00+ hires_addr_lo .bulk $00,$00,$00,$00,$00,$00,$00,$00,$80,$80,$80,$80,$80,$80,$80,$80
+ $00,$00,$00,$00,$00,$00,$00,$00,$80,$80,$80,$80,$80,$80,$80,$80
+ $00,$00,$00,$00,$00,$00,$00,$00,$80,$80,$80,$80,$80,$80,$80,$80
+ $00,$00,$00,$00,$00,$00,$00,$00,$80,$80,$80,$80,$80,$80,$80,$80
+ $28,$28,$28,$28,$28,$28,$28,$28,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8
+ $28,$28,$28,$28,$28,$28,$28,$28,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8
+ $28,$28,$28,$28,$28,$28,$28,$28,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8
+ $28,$28,$28,$28,$28,$28,$28,$28,$a8,$a8,$a8,$a8,$a8,$a8,$a8,$a8
+ $50,$50,$50,$50,$50,$50,$50,$50,$d0,$d0,$d0,$d0,$d0,$d0,$d0,$d0
+ $50,$50,$50,$50,$50,$50,$50,$50,$d0,$d0,$d0,$d0,$d0,$d0,$d0,$d0
+ $50,$50,$50,$50,$50,$50,$50,$50,$d0,$d0,$d0,$d0,$d0,$d0,$d0,$d0
+ $50,$50,$50,$50,$50,$50,$50,$50,$d0,$d0,$d0,$d0,$d0,$d0,$d0,$d0
bac0: d0 .dd1 $d0
bac1: 00 00 00 00+ .align $0100 (63 bytes)
;
; Hi-res line start address, high byte.
bb00: 20 24 28 2c+ hires_addr_hi .bulk $20,$24,$28,$2c,$30,$34,$38,$3c,$20,$24,$28,$2c,$30,$34,$38,$3c
+ $21,$25,$29,$2d,$31,$35,$39,$3d,$21,$25,$29,$2d,$31,$35,$39,$3d
+ $22,$26,$2a,$2e,$32,$36,$3a,$3e,$22,$26,$2a,$2e,$32,$36,$3a,$3e
+ $23,$27,$2b,$2f,$33,$37,$3b,$3f,$23,$27,$2b,$2f,$33,$37,$3b,$3f
+ $20,$24,$28,$2c,$30,$34,$38,$3c,$20,$24,$28,$2c,$30,$34,$38,$3c
+ $21,$25,$29,$2d,$31,$35,$39,$3d,$21,$25,$29,$2d,$31,$35,$39,$3d
+ $22,$26,$2a,$2e,$32,$36,$3a,$3e,$22,$26,$2a,$2e,$32,$36,$3a,$3e
+ $23,$27,$2b,$2f,$33,$37,$3b,$3f,$23,$27,$2b,$2f,$33,$37,$3b,$3f
+ $20,$24,$28,$2c,$30,$34,$38,$3c,$20,$24,$28,$2c,$30,$34,$38,$3c
+ $21,$25,$29,$2d,$31,$35,$39,$3d,$21,$25,$29,$2d,$31,$35,$39,$3d
+ $22,$26,$2a,$2e,$32,$36,$3a,$3e,$22,$26,$2a,$2e,$32,$36,$3a,$3e
+ $23,$27,$2b,$2f,$33,$37,$3b,$3f,$23,$27,$2b,$2f,$33,$37,$3b,$3f
bbc0: 3f .dd1 $3f
bbc1: 0e 0e 0e 0e+ .align $0100 (63 bytes)
;
; Converts a positive screen X coordinate (0-139) to a horizontal column (20-
; 39).
bc00: 14 14 14 14+ pos_xc_to_col .bulk $14,$14,$14,$14,$14,$14,$14,$15,$15,$15,$15,$15,$15,$15,$16,$16
+ $16,$16,$16,$16,$16,$17,$17,$17,$17,$17,$17,$17,$18,$18,$18,$18
+ $18,$18,$18,$19,$19,$19,$19,$19,$19,$19,$1a,$1a,$1a,$1a,$1a,$1a
+ $1a,$1b,$1b,$1b,$1b,$1b,$1b,$1b,$1c,$1c,$1c,$1c,$1c,$1c,$1c,$1d
+ $1d,$1d,$1d,$1d,$1d,$1d,$1e,$1e,$1e,$1e,$1e,$1e,$1e,$1f,$1f,$1f
+ $1f,$1f,$1f,$1f,$20,$20,$20,$20,$20,$20,$20,$21,$21,$21,$21,$21
+ $21,$21,$22,$22,$22,$22,$22,$22,$22,$23,$23,$23,$23,$23,$23,$23
+ $24,$24,$24,$24,$24,$24,$24,$25,$25,$25,$25,$25,$25,$25,$26,$26
+ $26,$26,$26,$26,$26,$27,$27,$27,$27,$27,$27,$27
bc8c: 00 00 00 00+ .align $0100 (116 bytes)
;
; Converts the absolute value of a negative screen X coordinate (1-139) to a
; horizontal hi-res column (0-19).
bd00: 14 13 13 13+ neg_xc_to_col .bulk $14,$13,$13,$13,$13,$13,$13,$13,$12,$12,$12,$12,$12,$12,$12,$11
+ $11,$11,$11,$11,$11,$11,$10,$10,$10,$10,$10,$10,$10,$0f,$0f,$0f
+ $0f,$0f,$0f,$0f,$0e,$0e,$0e,$0e,$0e,$0e,$0e,$0d,$0d,$0d,$0d,$0d
+ $0d,$0d,$0c,$0c,$0c,$0c,$0c,$0c,$0c,$0b,$0b,$0b,$0b,$0b,$0b,$0b
+ $0a,$0a,$0a,$0a,$0a,$0a,$0a,$09,$09,$09,$09,$09,$09,$09,$08,$08
+ $08,$08,$08,$08,$08,$07,$07,$07,$07,$07,$07,$07,$06,$06,$06,$06
+ $06,$06,$06,$05,$05,$05,$05,$05,$05,$05,$04,$04,$04,$04,$04,$04
+ $04,$03,$03,$03,$03,$03,$03,$03,$02,$02,$02,$02,$02,$02,$02,$01
+ $01,$01,$01,$01,$01,$01,$00,$00,$00,$00,$00,$00
bd8c: 00 00 00 00+ .align $0100 (116 bytes)
;
; Converts a positive screen X coordinate (0-139) to a pixel color offset (0-
; 6,8-14). This can't simply be 0-7 because of the odd/even color scheme.
;
; Note you can identify whether this color is for an odd or even byte by ANDing
; the value with #$08 (bit is set for even columns).
pos_xc_to_color_idx
be00: 00 01 02 03+ .bulk $00,$01,$02,$03,$04,$05,$06,$08,$09,$0a,$0b,$0c,$0d,$0e,$00,$01
+ $02,$03,$04,$05,$06,$08,$09,$0a,$0b,$0c,$0d,$0e,$00,$01,$02,$03
+ $04,$05,$06,$08,$09,$0a,$0b,$0c,$0d,$0e,$00,$01,$02,$03,$04,$05
+ $06,$08,$09,$0a,$0b,$0c,$0d,$0e,$00,$01,$02,$03,$04,$05,$06,$08
+ $09,$0a,$0b,$0c,$0d,$0e,$00,$01,$02,$03,$04,$05,$06,$08,$09,$0a
+ $0b,$0c,$0d,$0e,$00,$01,$02,$03,$04,$05,$06,$08,$09,$0a,$0b,$0c
+ $0d,$0e,$00,$01,$02,$03,$04,$05,$06,$08,$09,$0a,$0b,$0c,$0d,$0e
+ $00,$01,$02,$03,$04,$05,$06,$08,$09,$0a,$0b,$0c,$0d,$0e,$00,$01
+ $02,$03,$04,$05,$06,$08,$09,$0a,$0b,$0c,$0d,$0e
be8c: 00 00 00 00+ .align $0100 (116 bytes)
;
; Converts the absolute value of a negative screen X coordinate (1-139) to a
; pixel color offset (0-6,8-14).
neg_xc_to_color_idx
bf00: 00 0e 0d 0c+ .bulk $00,$0e,$0d,$0c,$0b,$0a,$09,$08,$06,$05,$04,$03,$02,$01,$00,$0e
+ $0d,$0c,$0b,$0a,$09,$08,$06,$05,$04,$03,$02,$01,$00,$0e,$0d,$0c
+ $0b,$0a,$09,$08,$06,$05,$04,$03,$02,$01,$00,$0e,$0d,$0c,$0b,$0a
+ $09,$08,$06,$05,$04,$03,$02,$01,$00,$0e,$0d,$0c,$0b,$0a,$09,$08
+ $06,$05,$04,$03,$02,$01,$00,$0e,$0d,$0c,$0b,$0a,$09,$08,$06,$05
+ $04,$03,$02,$01,$00,$0e,$0d,$0c,$0b,$0a,$09,$08,$06,$05,$04,$03
+ $02,$01,$00,$0e,$0d,$0c,$0b,$0a,$09,$08,$06,$05,$04,$03,$02,$01
+ $00,$0e,$0d,$0c,$0b,$0a,$09,$08,$06,$05,$04,$03,$02,$01,$00,$0e
+ $0d,$0c,$0b,$0a,$09,$08,$06,$05,$04,$03,$02,$01
bf8c: 00 00 00 00+ .align $0100 (116 bytes)