; 04jul08: final version of this documentation for posting ; ;=============================================================================== ; The following is taken from a binary bump of the contexts of a "Towering ; Inferno" cartridge. I then wrote a program to give me a hex to assembly ; listing (not designed to be compiled but designed for documentation ; purposes). I then layered three sets of programmer comments in my ; possession to create this "after the fact" documented piece of code. Since ; it has been 26 years since I wrote that game, I am taking alot of comments ; on face value and have not verified against actual game play ; ; The actual code is copyrighted by U.S. Games (c) 1982 ; This document is copyright by Paul Allen Newell (c) 2008 ; ;=============================================================================== ; NOTES: ; "floyds" refer to the actual fire characters in the game ; "jmp" and branches go to labels starting with "L_" ; "jsr" go to labels starting with "S_" ; labels used for both jsr, jmp, and branches start with "X_" ; data blocks start with labels with "D_" ; "???" means that parser thinks its never used or doesn't know what it is ; ;=============================================================================== ; typographic ruler to make sure my comments stay within an 80 character limit ; 1 2 3 4 5 6 7 8 ;2345678901234567890123456789012345678901234567890123456789012345678901234567890 ; ;=============================================================================== 0x0006: LCOLOR EQU $06 ; these are the only "Atari" 0x0007: RCOLOR EQU $07 ; registers labelled 0x0008: ACOLOR EQU $08 0x0009: BCOLOR EQU $09 0x000a: LOWSET EQU $0A ; 0x0080: SWITCH EQU $80 ; what game is being played ; 0x0081: RIGVER EQU $81 ; vertical position for fireman and ; ; helicopter 0x0082: RIGHOR EQU $82 ; horizontal position for fireman and ; ; helicopter 0x0083: INCREG EQU $83 ; storage for horizontal shifts of ; ; fireman (and/or return for water ; ; position) ; 0x0084: ONELOW EQU $84 ; BCD storage of scores for both 0x0085: TWOLOW EQU $85 ; players 0x0086: ONEHIG EQU $86 ; 0x0087: TWOHIG EQU $87 ; ; 0x0088: POINT EQU $88 ; 16 bit (LSB first, MSB last) index ; ; of whether dealing with $C0 or ; ; $D0 set of floyds 0x0089: POINTA EQU $89 ; ; 0x008a: LCON EQU $8A ; line counters during drawing 0x008b: RCON EQU $8B ; routines ; 0x008c: SCODS1 EQU $8C ; BCD storage of each digit to be 0x008d: SCODS2 EQU $8D ; displayed in low resolution mask 0x008e: SCODS3 EQU $8E ; (index material) -- one digit 0x008f: SCODS4 EQU $8F ; stashed in the upper nibble ; ; *** NOTE: Many times a register will be used for one thing in the ; interior display and another in the exterior display so, ; to make life easier, it is given a different label ; depending on what it's doing ; 0x0090: FLODUM EQU $90 ; dummy containing floor pattern (for ; ; mask $0F) to be rolled in the ; ; drawing routine 0x0090: HETIM1 EQU $90 ; timer to determine how long the ; ; helicopter should sit on the top ; ; of the screen ; 0x0091: FUPDUM EQU $91 ; dummy containing floor pattern (for ; ; mask $0F) to be rolled in the ; ; drawing routine 0x0091: HETIM2 EQU $91 ; timer to determine the helicopter's ; ; arc up and over from the building ; 0x0092: EPATRN EQU $92 ; contains index for which floor ; ; pattern (for mask $0E) should be ; ; used 0x0092: HETIM3 EQU $92 ; timer to determine the helicopter's ; ; drop to the ground ; 0x0093: MANDIR EQU $93 ; is fireman facing up or down (which ; ; way will the water shoot) 0x0093: HETIM4 EQU $93 ; timer to determine how long the ; ; helicopter should sit after ; ; victim before entering again ; 0x0094: CURPDL EQU $94 ; contains paddle info to check for ; ; bad moves and corrections 0x0094: HETIM5 EQU $94 ; timer for the release of each ; ; victim from the helicopter ; 0x0095: DIR EQU $95 ; direction of count for helicopter ; ; blade 0x0095: ODDEVE EQU $95 ; multiplexer for the floyds ($C0 or ; ; $D0) and double score display at ; ; top or score/victims and ; ; something else that I can't ; ; figure out why its there, but ; ; it is ; 0x0096: MEMORY EQU $96 ; current count for helicopter blade ; ; rotation 0x0096: MENLEF EQU $96 ; number of fireman left, expressed ; ; in value suitable for the ; ; multiplier/magnifier register for ; ; direct use ; 0x0097: DUMMY EQU $97 ; an all purpose dummy ; 0x0098: RESET EQU $98 ; has game reset been released or not ; ; after being depressed ; 0x0099: LOGO EQU $99 ; should logo be displayed or not ; 0x009a: RESETA EQU $9A ; has game select been released or ; ; not after being depressed ; 0x009b: CHROMA EQU $9B ; logical mask for 'AND-ing' all ; ; color against to allow for color ; ; or B&W ; 0x009c: FLOWER EQU $9C ; permanent storage for the floor 0x009d: FUPPER EQU $9D ; pattern (for mask $0F) to be used ; 0x009e: ONEFIV EQU $9E ; used to determine whether a player 0x009f: TWOFIV EQU $9F ; has had his turn or note (orig ; ; names reflect when we needed to ; ; know when each player had to pass ; ; five floors to get his ; ; helicopter) ; ; ARROW PATTERN STORED IN $A0-$A8 ; HELICOPTER PATTERN STORED IN $A0-$A7 ; 0x00a8: MIRDUM EQU $A8 ; used to determine which direction ; ; the fireman should be facing in ; ; relation to the paddle's desires ; ; and the nature of the ; ; moving/firing ; 0x00a9: VICONE EQU $A9 ; number of victims saved by each 0x00aa: VICTWO EQU $AA ; player on a given floor ; 0x00ab: TYPE EQU $AB ; used as dummy for "white flash" ; ; when a fireman is killed (unknown ; ; why this is same comment as $BF) ; 0x00ac: TIMER EQU $AC ; rate of death per victim ; 0x00ad: WINNER EQU $AD ; value of background color when in ; ; the "ninth floor" win graphic ; ; (else $00) ; 0x00ae: DANGER EQU $AE ; upper nibble is what building, 0x00af: DANGEE EQU $AF ; lower nibble is what floor -- one ; ; register for each player ; 0x00b0: DOUBLE EQU $B0 ; unused in final version ; ; FLAME PATTERNS STORED IN $B1-$BB ; ;??? EQU $BC ; unknown ;??? EQU $BD ; unknown ;??? EQU $BE ; unknown ; 0x00bf: EXCESS EQU $BF ; used as dummy for "white flash" ; ; when a fireman is killed (unknown ; ; why this is same comment as $AB) ; ; RIGHT FLOYDS STORED IN $C0-$CE ; LEFT FLOYDS STORED IN $D0-$DE ; EXTERIOR FLAMES STORED IN $C0-$DE ; ;??? EQU $DF ; unknown ; ; 4th DIGIT IN EXTERIOR DRAW STORED IN $E1-$EA ; (?concerning exact range?) ; 0x00e0: SOUDUM EQU $E0 ; dummy for sound rolls 0x00e1: SOUDIR EQU $E1 ; dummy for sound rolls ; 0x00e2: GATE EQU $E2 ; is the gate to upper floors open or ; ; not ; 0x00e3: BONUS EQU $E3 ; flag for giving bonus points for ; ; clearing a floor of all floyds, ; ; clearing the maze, stopping the ; ; victim timer, assorted goodies ; 0x00e4: VALCOL EQU $E4 ; what color is the valve at the top ; ; (has it been hit or not) ; 0x00e5: FIRDUM EQU $E5 ; dummy to hold bit #3 of floyds ; ; ($C0-$D0) that tells the drawing ; ; routine whether to draw or not ; 0x00e6: EVICM EQU $E6 ; masks for holding info and ; ; displaying how many victims are ; ; left (used with 'AND-ing') 0x00e7: FVICM EQU $E7 ; ; 0x00e8: ALTDUM EQU $E8 ; color of a floor (EOR for victim ; ; color) ; 0x00e9: SECTIM EQU $E9 ; number of seconds and number of ; ; frames timers for victim death 0x00ea: FRMTIM EQU $EA ; ; 0x00eb: WHICH EQU $EB ; player one or two (bit #0) and ; ; color (all the bits) --- also ; ; used as a multiplexer in exterior ; 0x00ec: RAND0 EQU $EC ; storage for random number generator 0x00ed: RAND1 EQU $ED ; ($E0 is the random number used) 0x00ee: RAND2 EQU $EE ; 0x00ef: RAND3 EQU $EF ; ; 0x00f0: OVEUND EQU $F0 ; mask for "AND-ing" whether floyds ; ; under or over the walls (with ; ; LOWSET--$0A register) ; 0x00f1: TRIG1D EQU $F1 ; trigger to run off $1D during ; ; drawing routine (this is one of ; ; the cloudier parts of the code) 0x00f1: RETURN EQU $F1 ; trigger for return from exterior to ; ; interior of the building ; 0x00f2: WATSAV EQU $F2 ; memory of displacement of ; ; horizontal shift between the ; ; fireman and his water 0x00f2: WHIMEM EQU $F2 ; dummy to save "WHICH" during victim ; ; scoring routine --- in this case ; ; which multiplex ; 0x00f3: WATCOU EQU $F3 ; counter for how far the water can ; ; shoot 0x00f3: XMEN EQU $F3 ; dummy to save "WHICH" during victim ; ; scoring routine --- in this case ; ; for which player ; 0x00f4: WATPOS EQU $F4 ; vertical position for water when on ; ; and "keep off screen" when off 0x00f4: VICTIE EQU $F4 ; vertical position for victims ; ; running when on and "keep off ; ; screen" when off ; 0x00f5: SAVES EQU $F5 ; number of victims left per player ; ; during the floor play (added to ; ; respective VICONE/VICTWO at end ; ; of floor for exterior needs 0x00f5: RAPID EQU $F5 ; trigger to determine whether game ; ; select is in fast mode ; 0x00f6: EMPTY EQU $F6 ; special visual or not ; 0x00f7: LOCKUP EQU $F7 ; mask used to lock out player one or ; ; two if they have died in the game ; ; #4 sequence ; ; STACK RESERVE $F8-$FF ; ; ; ; 0xb000: ORG $b000 ; origin of the program in memory 0xb000: CLD d8 ; clear decimal mode 0xb001: LDX #$ff a2 ff ; set stack at $FF 0xb003: TXS 9a ; 0xb004: LDA #$00 a9 00 ; clear out all zero page 0xb006: L_b006 STA $00,X 95 00 ; 0xb008: DEX ca ; 0xb009: BNE L_b006 d0 fb ; 0xb00b: INX e8 ; 0xb00c: STX SWITCH 86 80 ; set game select for game #1 ; ; THIS IS THE BAD TIMING BUG THAT WAS ; ; INCORRECTLY SET TO #$24 0xb00e: LDA #$29 a9 29 ; set timer off and rolling (really 0xb010: STA $0296 8d 96 02 ; an unknown since its cold start) ; 0xb013: LDA #$aa a9 aa ; seed random number generator 0xb015: STA RAND0 85 ec ; 0xb017: STA RAND1 85 ed ; ; ; ***** HARD START FOR ANY GAME ***** 0xb019: L_b019 LDX #$30 a2 30 ; 0xb01b: LDA #$00 a9 00 ; ; ; ; I would have expected this line to ; ; be "STA DANGEE,X" as $af is an ; ; EQU to DANGEE, but my master ; ; indicates STA $af,X 0xb01d: L_b01d STA $af,X 95 af ; clear out floyd memory 0xb01f: DEX ca ; 0xb020: BNE L_b01d d0 fb ; ; 0xb022: STX LOGO 86 99 ; set defaults of $00 0xb024: STX BCOLOR 86 09 ; 0xb026: STX WINNER 86 ad ; 0xb028: STX $2b 86 2b ; 0xb02a: STX LOCKUP 86 f7 ; 0xb02c: STX VICONE 86 a9 ; 0xb02e: STX VICTWO 86 aa ; 0xb030: STX EMPTY 86 f6 ; ; 0xb032: INX e8 ; set defaults of $01 0xb033: STX RESET 86 98 ; ; 0xb035: LDA #$10 a9 10 ; set level to beginning 0xb037: STA DANGEE 85 af ; 0xb039: LDX SWITCH a6 80 ; if game #2, make sure we don't lose 0xb03b: CPX #$02 e0 02 ; the level user was on; nor 0xb03d: BNE L_b049 d0 0a ; accidentally create a bad value 0xb03f: LDA DANGER a5 ae ; 0xb041: AND #$0f 29 0f ; 0xb043: BEQ L_b04b f0 06 ; 0xb045: DEC DANGER c6 ae ; 0xb047: BPL L_b04b 10 02 ; ; 0xb049: L_b049 STA DANGER 85 ae ; ; 0xb04b: L_b04b LDA #$a6 a9 a6 ; set color/first player flag 0xb04d: STA WHICH 85 eb ; ; ; 0xb04f: JMP L_b9dd 4c dd b9 ; go to the exterior sequence ; 0xb052: S_b052 LDA WHICH a5 eb ; subroutine to grab which player it 0xb054: AND #$01 29 01 ; is and stuff in it the 'X' index 0xb056: TAX aa ; 0xb057: RTS 60 ; ; ; ; ***** SEMI-HARD START ***** ; ; (new floor, hold score and level ; ; currently advanced to) 0xb058: L_b058 LDA #$00 a9 00 ; set defaults to $00 0xb05a: STA ONEFIV 85 9e ; 0xb05c: STA TWOFIV 85 9f ; 0xb05e: LDA SWITCH a5 80 ; if single player game, null out 0xb060: BMI L_b068 30 06 ; player two defaults 0xb062: INC TWOFIV e6 9f ; 0xb064: LDA #$11 a9 11 ; 0xb066: STA DANGEE 85 af ; 0xb068: L_b068 LDA #$00 a9 00 ; more defaults 0xb06a: STA VICONE 85 a9 ; 0xb06c: STA VICTWO 85 aa ; 0xb06e: STA SOUDIR 85 e1 ; 0xb070: STA SOUDUM 85 e0 ; ; 0xb072: LDA LOCKUP a5 f7 ; see if player one has been locked 0xb074: AND #$0f 29 0f ; out of the game (game #4); if so, 0xb076: ORA ONEFIV 05 9e ; go back and do player two only 0xb078: STA ONEFIV 85 9e ; 0xb07a: BEQ L_b07f f0 03 ; 0xb07c: JSR S_b435 20 35 b4 ; ; ; ; ***** SOFT START (used for player ; ; two) 0xb07f: L_b07f LDA #$50 a9 50 ; 0xb081: STA $05 85 05 ; force left/right mask after ; ; exterior ; 0xb083: JSR S_bd08 20 08 bd ; more setup, done with a long JSR to ; ; keep timing cycles right for ; ; other aspects of the game (game ; ; bombs if code of S_bd08 moved ; ; here) ; 0xb086: LDX #$ff a2 ff ; set 'AND' masks defaults for 0xb088: STX EVICM 86 e6 ; victims 0xb08a: STX FVICM 86 e7 ; ; 0xb08c: INX e8 ; set 'white-flash' to off 0xb08d: STX EXCESS 86 bf ; 0xb08f: STX TYPE 86 ab ; ; 0xb091: LDA #$04 a9 04 ; set for full victims left and put 0xb093: STA SAVES 85 f5 ; non-zero positive into "BONUS" 0xb095: STA BONUS 85 e3 ; flag ; 0xb097: LDA #$3c a9 3c ; set victim timers 0xb099: STA FRMTIM 85 ea ; 0xb09b: LDA TIMER a5 ac ; 0xb09d: STA SECTIM 85 e9 ; ; 0xb09f: JSR S_b052 20 52 b0 ; read difficulty switches and set ; ; floyds over/under walls 0xb0a2: LSR A 4a ; accordingly 0xb0a3: LDA $0282 ad 82 02 ; ; ; ; THIS IS THE BUG WHERE CODE WENT TO ; ; PROM MANUFACTURER WITH "bcs" AND ; ; IT HAD TO BE CHANGED TO "bcc" TO ; ; GET CORRECTED PLAYER SCORES ON ; ; CORRECT SIDE OF DISPLAY ; ; (additional correction at 0xbf06 ; ; owing to this change 0xb0a6: BCC L_b0a9 90 01 ; 0xb0a8: ASL A 0a ; 0xb0a9: L_b0a9 BMI L_b0af 30 04 ; 0xb0ab: LDA #$fb a9 fb ; 0xb0ad: BNE L_b0b1 d0 02 ; (acts like "jmp") 0xb0af: L_b0af LDA #$ff a9 ff ; 0xb0b1: L_b0b1 STA OVEUND 85 f0 ; 0xb0b3: LDA #$3b a9 3b ; set for 3 extra firemen 0xb0b5: STA MENLEF 85 96 ; ; 0xb0b7: INC ONEFIV,X f6 9e ; let world know this player is ; ; getting his try on this floor 0xb0b9: LDA DANGER,X b5 ae ; determine color of the flames 0xb0bb: AND #$0f 29 0f ; 0xb0bd: TAY a8 ; 0xb0be: LDA D_b110,Y b9 10 b1 ; 0xb0c1: STA ALTDUM 85 e8 ; ; 0xb0c3: LDX #$00 a2 00 ; torch out a floor, masking out what 0xb0c5: L_b0c5 LDA D_b11a,X bd 1a b1 ; needs to be masked at top and 0xb0c8: BPL L_b0d4 10 0a ; bottom of screen 0xb0ca: JSR S_b1ad 20 ad b1 ; 0xb0cd: STA $c0,X 95 c0 ; 0xb0cf: LDA RAND1 a5 ed ; 0xb0d1: JMP L_b0d6 4c d6 b0 ; 0xb0d4: L_b0d4 STA $c0,X 95 c0 ; 0xb0d6: L_b0d6 STA $d0,X 95 d0 ; 0xb0d8: INX e8 ; 0xb0d9: CPX #$0f e0 0f ; 0xb0db: BNE L_b0c5 d0 e8 ; ; 0xb0dd: LDA RAND0 a5 ec ; determine a floor maze pattern 0xb0df: CPY #$09 c0 09 ; if 9th floor, do special set-up 0xb0e1: BEQ L_b0fe f0 1b ; 0xb0e3: STA FUPPER 85 9d ; upper part of $0F mask 0xb0e5: LDA RAND1 a5 ed ; 0xb0e7: STA FLOWER 85 9c ; lower part of $0F mask 0xb0e9: LSR A 4a ; 0xb0ea: BCC L_b0f2 90 06 ; avoid the one combination saved for 0xb0ec: LDA FUPPER a5 9d ; the ninth floor 0xb0ee: AND #$fb 29 fb ; 0xb0f0: STA FUPPER 85 9d ; 0xb0f2: L_b0f2 LDA FLOWER a5 9c ; 0xb0f4: AND #$03 29 03 ; 0xb0f6: ASL A 0a ; 0xb0f7: ASL A 0a ; 0xb0f8: ASL A 0a ; 0xb0f9: ASL A 0a ; 0xb0fa: STA EPATRN 85 92 ; index of $0E mask 0xb0fc: BPL L_b10a 10 0c ; (acts like "jmp") ; 0xb0fe: L_b0fe ORA #$84 09 84 ; force the one big obstacle in 9th 0xb100: STA FUPPER 85 9d ; floor 0xb102: LDA RAND1 a5 ed ; 0xb104: STA FLOWER 85 9c ; 0xb106: LDA #$30 a9 30 ; for max difficulty in $0E index 0xb108: STA EPATRN 85 92 ; ; 0xb10a: L_b10a JSR S_b129 20 29 b1 ; go to positioning subroutine ; 0xb10d: JMP L_b5d0 4c d0 b5 ; go to beginning of drawing routine ; ; (need to avoid everything else ; ; since too many cycles will happen ; ; elsewhere) ; 0xb110: D_b110 DB $74,$16,$26,$36 ; data table for the floor (and 0xb114: DB $64,$86,$c4,$d6 ; building) color selection 0xb118: DB $e6,$f6 ; ; 0xb11a: D_b11a DB $77,$77,$77,$ff ; data table for the flame 0xb11e: DB $ff,$ff,$ff,$ff ; generation masks (no flames 0xb122: DB $ff,$ff,$ff,$ff ; at top/bottom, just shift 0xb126: DB $ff,$77,$77 ; factors (controlled by bit ; ; $3), though masker also ; ; doubles into BPL/BMI test ; 0xb129: S_b129 LDX #$ff a2 ff ; positioning routine to be called 0xb12b: STX CURPDL 86 94 ; once at start of each floor and ; ; when a fireman is killed 0xb12d: INX e8 ; kill all previous paddle info 0xb12e: STX ODDEVE 86 95 ; set defaults to $00 0xb130: STX MIRDUM 86 a8 ; 0xb132: STX $0c 86 0c ; 0xb134: STX $2c 86 2c ; 0xb136: STX WATSAV 86 f2 ; 0xb138: STX WATCOU 86 f3 ; 0xb13a: INX e8 ; 0xb13b: STX MANDIR 86 93 ; set the man facing up 0xb13d: INX e8 ; 0xb13e: STX GATE 86 e2 ; close the gate 0xb140: LDA #$10 a9 10 ; 0xb142: STA WATPOS 85 f4 ; get the water off the screen 0xb144: LDA #$0f a9 0f ; 0xb146: STA VALCOL 85 e4 ; set valve to "white" 0xb148: STA $02 85 02 ; wait until next horizontal line 0xb14a: LDX #$08 a2 08 ; 0xb14c: L_b14c DEX ca ; 0xb14d: BNE L_b14c d0 fd ; 0xb14f: STA $11 85 11 ; position the fireman and his water 0xb151: STA $13 85 13 ; plus his vertical and horizontal 0xb153: LDA #$e0 a9 e0 ; position 0xb155: STA $21 85 21 ; 0xb157: LDA #$62 a9 62 ; 0xb159: STA RIGVER 85 81 ; 0xb15b: LDA #$80 a9 80 ; 0xb15d: STA RIGHOR 85 82 ; 0xb15f: S_b15f STA $02 85 02 ; wait until beginning of next 0xb161: LDX #$08 a2 08 ; horizontal line 0xb163: L_b163 DEX ca ; 0xb164: BNE L_b163 d0 fd ; 0xb166: BIT $80 24 80 ; 0xb168: STA $12 85 12 ; position the valve and gate 0xb16a: LDA #$10 a9 10 ; 0xb16c: STA $14 85 14 ; 0xb16e: STA $22 85 22 ; 0xb170: RTS 60 ; ; 0xb171: S_b171 LDY #$66 a0 66 ; each frame generates a new flicker 0xb173: STY $b2 84 b2 ; pattern for individual flames 0xb175: STY $b3 84 b3 ; (the top parts are variable) 0xb177: LDY #$ff a0 ff ; 0xb179: STY $b4 84 b4 ; 0xb17b: STY $b5 84 b5 ; 0xb17d: JSR S_b1ad 20 ad b1 ; 0xb180: AND #$0f 29 0f ; 0xb182: TAX aa ; 0xb183: LDY D_b19d,X bc 9d b1 ; 0xb186: STY $b9 84 b9 ; 0xb188: STY $ba 84 ba ; 0xb18a: STY $bb 84 bb ; 0xb18c: AND #$0c 29 0c ; 0xb18e: TAX aa ; 0xb18f: LDY D_b19d,X bc 9d b1 ; 0xb192: STY $b6 84 b6 ; 0xb194: STY $b7 84 b7 ; 0xb196: STY $b8 84 b8 ; 0xb198: LDY #$00 a0 00 ; 0xb19a: STY $b1 84 b1 ; 0xb19c: RTS 60 ; ; 0xb19d: D_b19d DB $aa,$00,$88,$22 ; part of the flame data 0xb1a1: DB $55,$00,$11,$44 ; 0xb1a5: DB $99,$00,$11,$88 ; 0xb1a9: DB $66,$00,$22,$44 ; ; 0xb1ad: S_b1ad LDA RAND0 a5 ec ; Phil's random number generator 0xb1af: STA RAND2 85 ee ; designed to take a sixteen bit 0xb1b1: LDA RAND1 a5 ed ; number, multiply it by five, add 0xb1b3: STA RAND3 85 ef ; one, and then use the upper byte 0xb1b5: ASL A 0a ; as a random eight bit number (to 0xb1b6: ROL RAND0 26 ec ; save time, I use the lower byte 0xb1b8: ASL A 0a ; as semi-random (it will alternate 0xb1b9: ROL RAND0 26 ec ; between odd and even which is 0xb1bb: CLC 18 ; what is needed) --- [have no 0xb1bc: ADC RAND3 65 ef ; memory who "Phil" is] 0xb1be: STA RAND1 85 ed ; 0xb1c0: LDA #$00 a9 00 ; 0xb1c2: ADC RAND0 65 ec ; 0xb1c4: CLC 18 ; 0xb1c5: ADC RAND2 65 ee ; 0xb1c7: STA RAND0 85 ec ; 0xb1c9: LDA #$00 a9 00 ; 0xb1cb: INC RAND1 e6 ed ; 0xb1cd: ADC RAND0 65 ec ; 0xb1cf: STA RAND0 85 ec ; 0xb1d1: RTS 60 ; ; 0xb1d2: S_b1d2 LDA $35 a5 35 ; subroutine to deal with water 0xb1d4: BMI L_b21d 30 47 ; hitting a floyd; ignore if water 0xb1d6: LDA $31 a5 31 ; has made contact with a wall or 0xb1d8: BPL L_b21d 10 43 ; there is no contact with water ; ; and floyd 0xb1da: LDA ODDEVE a5 95 ; by use of multiplexer, determine 0xb1dc: LSR A 4a ; whether the hit was with a $C0 or 0xb1dd: BCC L_b1e3 90 04 ; $DO series 0xb1df: LDA #$d0 a9 d0 ; 0xb1e1: BNE L_b1e5 d0 02 ; (acts like "jmp") 0xb1e3: L_b1e3 LDA #$c0 a9 c0 ; 0xb1e5: L_b1e5 STA POINT 85 88 ; 0xb1e7: LDA WATPOS a5 f4 ; determine which row by subtracting 0xb1e9: SEC 38 ; current water position from 0xb1ea: SBC D_b996 ed 96 b9 ; bottom margin and then one row at 0xb1ed: LDY #$00 a0 00 ; a time until result < 0, then 0xb1ef: SEC 38 ; save this row number in "Y" 0xb1f0: L_b1f0 INY c8 ; 0xb1f1: SBC #$0c e9 0c ; 0xb1f3: BCS L_b1f0 b0 fb ; 0xb1f5: LDA (POINT),Y b1 88 ; load that row of floyds 0xb1f7: TAX aa ; 0xb1f8: AND #$08 29 08 ; if by accident they're already off 0xb1fa: BEQ L_b203 f0 07 ; (top row error), do nothing 0xb1fc: TXA 8a ; 0xb1fd: AND #$07 29 07 ; else index by multiplexer/magnifier ; ; controls (lower three bits) and 0xb1ff: TAX aa ; determine what the new row should ; ; be 0xb200: LDA D_b21e,X bd 1e b2 ; 0xb203: L_b203 STA DUMMY 85 97 ; save this in dummy (including bit ; ; #3 -- on/off) 0xb205: JSR S_b1ad 20 ad b1 ; get a new shift factor and truncate ; ; the two together 0xb208: AND #$f0 29 f0 ; 0xb20a: ORA DUMMY 05 97 ; 0xb20c: STA (POINT),Y 91 88 ; store it in the row memory 0xb20e: LDA #$01 a9 01 ; add one to the score 0xb210: STA DUMMY 85 97 ; 0xb212: JSR S_b299 20 99 b2 ; 0xb215: LDA #$f4 a9 f4 ; fire off the sounds appropriate for ; ; this section 0xb217: STA SOUDUM 85 e0 ; 0xb219: LDA #$20 a9 20 ; 0xb21b: STA SOUDIR 85 e1 ; 0xb21d: L_b21d RTS 60 ; ; 0xb21e: D_b21e DB $00,$08,$08,$0d ; data for line 0xb200 0xb222: DB $08,$08,$0c,$0e ; ; 0xb226: S_b226 LDA RAND0 a5 ec ; take one row of floyds, except for 0xb228: TAY a8 ; $CF or $DF and give it a new 0xb229: AND #$0f 29 0f ; shift factor 0xb22b: CMP #$0f c9 0f ; 0xb22d: BNE L_b230 d0 01 ; 0xb22f: DEY 88 ; 0xb230: L_b230 TYA 98 ; 0xb231: AND #$1f 29 1f ; 0xb233: TAX aa ; 0xb234: TYA 98 ; 0xb235: AND #$f0 29 f0 ; 0xb237: STA DUMMY 85 97 ; 0xb239: LDA $c0,X b5 c0 ; 0xb23b: AND #$0f 29 0f ; 0xb23d: ORA DUMMY 05 97 ; 0xb23f: STA $c0,X 95 c0 ; 0xb241: RTS 60 ; ; 0xb242: S_b242 LDA BONUS a5 e3 ; if the bonus flag says there ain't 0xb244: BMI L_b298 30 52 ; no more floyds and bonus scored, ; ; bypass this routine 0xb246: BNE L_b25f d0 17 ; if floyds left, go to routine 0xb248: LDA SAVES a5 f5 ; all floyds out but no bonus given 0xb24a: ASL A 0a ; yet (this happens once a floor 0xb24b: ASL A 0a ; BONUS=$00) give 10 points for 0xb24c: ASL A 0a ; each victim left (BCD) 0xb24d: ASL A 0a ; 0xb24e: STA DUMMY 85 97 ; 0xb250: JSR S_b299 20 99 b2 ; 0xb253: LDA #$20 a9 20 ; appropriate score sound 0xb255: STA SOUDIR 85 e1 ; 0xb257: LDA #$ff a9 ff ; 0xb259: STA SOUDUM 85 e0 ; 0xb25b: STA BONUS 85 e3 ; set bonus flag so it only does this ; ; once 0xb25d: BNE L_b298 d0 39 ; (acts like "jmp") 0xb25f: L_b25f LDA EVICM a5 e6 ; if no victims left, don't bother 0xb261: BEQ L_b298 f0 35 ; 0xb263: DEC FRMTIM c6 ea ; decrement from timer 0xb265: LDA FRMTIM a5 ea ; 0xb267: AND #$03 29 03 ; every 4th frame, change one row's 0xb269: BNE L_b272 d0 07 ; shift factor, unless in middle of 0xb26b: LDA EXCESS a5 bf ; fireman death, in which case 0xb26d: BNE L_b272 d0 03 ; don't do 0xb26f: JSR S_b226 20 26 b2 ; 0xb272: L_b272 LDA FRMTIM a5 ea ; every time FRMTIM hits zero, reset 0xb274: BNE L_b298 d0 22 ; timer and proceed to decrement 0xb276: LDA #$3c a9 3c ; second counter, else that's all 0xb278: STA FRMTIM 85 ea ; 0xb27a: DEC SECTIM c6 e9 ; 0xb27c: BNE L_b298 d0 1a ; if SECTIM is zero, its one less ; ; victim time 0xb27e: LDA TIMER a5 ac ; reset SECTIM 0xb280: STA SECTIM 85 e9 ; 0xb282: LDX #$04 a2 04 ; roll '0000' through FVICM into 0xb284: L_b284 LDA FVICM a5 e7 ; EVICM (which kills 'AND' mask for 0xb286: LSR A 4a ; displaying victims for another 0xb287: STA FVICM 85 e7 ; victim) 0xb289: ROL EVICM 26 e6 ; 0xb28b: DEX ca ; 0xb28c: BNE L_b284 d0 f6 ; 0xb28e: DEC SAVES c6 f5 ; one less victim in the save memory 0xb290: LDA #$11 a9 11 ; appropriate death sounds 0xb292: STA SOUDUM 85 e0 ; 0xb294: LDA #$ff a9 ff ; 0xb296: STA SOUDIR 85 e1 ; 0xb298: L_b298 RTS 60 ; ; 0xb299: S_b299 LDA WHICH a5 eb ; universal score routine 0xb29b: AND #$01 29 01 ; see where the score should go 0xb29d: TAX aa ; 0xb29e: CLC 18 ; 0xb29f: SED f8 ; set for BCD addition 0xb2a0: LDA ONELOW,X b5 84 ; 0xb2a2: ADC DUMMY 65 97 ; and perform 16 bit addition 0xb2a4: STA ONELOW,X 95 84 ; (assuming that the number to 0xb2a6: LDA ONEHIG,X b5 86 ; added is less than or equal to 0xb2a8: ADC #$00 69 00 ; decimal 99) 0xb2aa: STA ONEHIG,X 95 86 ; 0xb2ac: CLD d8 ; 0xb2ad: S_b2ad LDA ONELOW,X b5 84 ; second entry point, takes the new 0xb2af: ASL A 0a ; score (or different person's 0xb2b0: ASL A 0a ; score and loads it into 4 display 0xb2b1: ASL A 0a ; index registers 0xb2b2: ASL A 0a ; 0xb2b3: STA SCODS4 85 8f ; 0xb2b5: LDA ONELOW,X b5 84 ; 0xb2b7: AND #$f0 29 f0 ; 0xb2b9: STA SCODS3 85 8e ; 0xb2bb: LDA ONEHIG,X b5 86 ; 0xb2bd: ASL A 0a ; 0xb2be: ASL A 0a ; 0xb2bf: ASL A 0a ; 0xb2c0: ASL A 0a ; 0xb2c1: STA SCODS2 85 8d ; 0xb2c3: LDA ONEHIG,X b5 86 ; 0xb2c5: AND #$f0 29 f0 ; 0xb2c7: STA SCODS1 85 8c ; 0xb2c9: RTS 60 ; ; ; ; subroutine to move firemen and ; ; shoot water 0xb2ca: S_b2ca JSR S_b052 20 52 b0 ; which player 0xb2cd: EOR #$01 49 01 ; reverse the input since dummied at 0xb2cf: TAX aa ; last minute to switch which player ; ; shows on which side of scoring ; ; sequence 0xb2d0: LDA INCREG a5 83 ; input fireman movement from paddle 0xb2d2: STA $21 85 21 ; routine 0xb2d4: LDY $3c,X b4 3c ; see if water was shot ... 0xb2d6: BPL L_b30e 10 36 ; ... and split if shot 0xb2d8: LDX WATCOU a6 f3 ; see if there is water currently on 0xb2da: BNE L_b30e d0 32 ; top be displayed (leave if there 0xb2dc: TAX aa ; is) 0xb2dd: LDA MIRDUM a5 a8 ; determine which way the critter is 0xb2df: AND #$0c 29 0c ; facing (or wants to be facing) 0xb2e1: BEQ L_b309 f0 26 ; and since water button is off and 0xb2e3: AND #$08 29 08 ; no water is on, go ahead and let 0xb2e5: EOR #$08 49 08 ; the fireman change direction 0xb2e7: STA $0c 85 0c ; 0xb2e9: STA DUMMY 85 97 ; 0xb2eb: LDA ODDEVE a5 95 ; adjust starting point of water to 0xb2ed: AND #$08 29 08 ; reflect the current direction of 0xb2ef: CMP DUMMY c5 97 ; the fireman (including accounting 0xb2f1: BEQ L_b309 f0 16 ; for any move of fireman); this 0xb2f3: LDA ODDEVE a5 95 ; is for horizontal position only 0xb2f5: EOR #$08 49 08 ; 0xb2f7: STA ODDEVE 85 95 ; 0xb2f9: LDA INCREG a5 83 ; 0xb2fb: LDX DUMMY a6 97 ; 0xb2fd: BEQ L_b305 f0 06 ; 0xb2ff: CLC 18 ; 0xb300: ADC #$60 69 60 ; 0xb302: JMP L_b308 4c 08 b3 ; 0xb305: L_b305 SEC 38 ; 0xb306: SBC #$60 e9 60 ; 0xb308: L_b308 TAX aa ; 0xb309: L_b309 STX $23 86 23 ; 0xb30b: JMP L_b369 4c 69 b3 ; 0xb30e: L_b30e AND #$f0 29 f0 ; see if there was horizontal fireman 0xb310: BEQ L_b31d f0 0b ; movement and adjust the "return 0xb312: CMP #$10 c9 10 ; shift factor" for the water to 0xb314: BNE L_b31b d0 05 ; allow for such 0xb316: INC WATSAV e6 f2 ; 0xb318: JMP L_b31d 4c 1d b3 ; 0xb31b: L_b31b DEC WATSAV c6 f2 ; 0xb31d: L_b31d INC WATCOU e6 f3 ; whether already going or shooting 0xb31f: LDA WATCOU a5 f3 ; new water, send water further in ; ; its direction 0xb321: CMP #$07 c9 07 ; if past limit, go to reset section 0xb323: BEQ L_b357 f0 32 ; 0xb325: STA DUMMY 85 97 ; figure out the new vertical change 0xb327: ASL A 0a ; 0xb328: CLC 18 ; 0xb329: ADC DUMMY 65 97 ; 0xb32b: STA DUMMY 85 97 ; 0xb32d: LDA #$00 a9 00 ; clear any horizontal movement, 0xb32f: STA $23 85 23 ; water does shoot straight 0xb331: LDA RIGVER a5 81 ; 0xb333: LDX MANDIR a6 93 ; depending on which direction the 0xb335: CPX #$01 e0 01 ; fireman is facing, increase or 0xb337: BEQ L_b342 f0 09 ; decrease the water's position 0xb339: SEC 38 ; 0xb33a: SBC #$06 e9 06 ; 0xb33c: SEC 38 ; 0xb33d: SBC DUMMY e5 97 ; 0xb33f: JMP L_b348 4c 48 b3 ; 0xb342: L_b342 CLC 18 ; 0xb343: ADC DUMMY 65 97 ; 0xb345: SEC 38 ; 0xb346: SBC #$02 e9 02 ; 0xb348: L_b348 STA WATPOS 85 f4 ; save new water current position 0xb34a: CMP D_b36a cd 6a b3 ; make sure its not shooting into the 0xb34d: BCS L_b369 b0 1a ; bottom (can't hit extra fireman) 0xb34f: LDA MANDIR a5 93 ; 0xb351: CMP #$01 c9 01 ; 0xb353: BEQ L_b369 f0 14 ; 0xb355: BNE L_b365 d0 0e ; (acts like "jmp") if okay, then 0xb357: L_b357 LDA WATSAV a5 f2 ; exit; if not, pretend no water 0xb359: ASL A 0a ; using the "return shift factor", 0xb35a: ASL A 0a ; reset the horizontal position of 0xb35b: ASL A 0a ; water to where the fireman is 0xb35c: ASL A 0a ; 0xb35d: STA $23 85 23 ; 0xb35f: LDA #$00 a9 00 ; null out all the tabs 0xb361: STA WATCOU 85 f3 ; 0xb363: STA WATSAV 85 f2 ; 0xb365: L_b365 LDA #$10 a9 10 ; "no display" of water 0xb367: STA WATPOS 85 f4 ; 0xb369: L_b369 RTS 60 ; ; 0xb36a: D_b36a DB $5e ; data for line ; ; 0xb34a "CMP D_b36a" ; 0xb36b: S_b36b LDA MANDIR a5 93 ; a very awkward way of changing the 0xb36d: CMP #$02 c9 02 ; fireman's display mask to facing 0xb36f: BEQ L_b37d f0 0c ; up or down 0xb371: LDA #$f9 a9 f9 ; 0xb373: STA $a1 85 a1 ; 0xb375: LDA #$31 a9 31 ; 0xb377: STA $a2 85 a2 ; 0xb379: LDA #$38 a9 38 ; 0xb37b: BNE L_b387 d0 0a ; (acts like "jmp") 0xb37d: L_b37d LDA #$f8 a9 f8 ; 0xb37f: STA $a1 85 a1 ; 0xb381: LDA #$30 a9 30 ; 0xb383: STA $a2 85 a2 ; 0xb385: LDA #$39 a9 39 ; 0xb387: L_b387 STA $a4 85 a4 ; 0xb389: STA $a5 85 a5 ; 0xb38b: LDA #$28 a9 28 ; 0xb38d: STA $a6 85 a6 ; 0xb38f: LDA #$3e a9 3e ; 0xb391: STA $a3 85 a3 ; 0xb393: LDA #$2c a9 2c ; 0xb395: STA $a7 85 a7 ; 0xb397: LDA #$30 a9 30 ; 0xb399: STA $a0 85 a0 ; 0xb39b: LDA #$00 a9 00 ; 0xb39d: STA $a8 85 a8 ; I would have expected this line to ; ; be "STA MIRDUM" as $a8 is an ; ; EQU to MIRDUM, but my master ; ; indicates STA $a8 0xb39f: RTS 60 ; ; ; ; subroutine for sound(s) 0xb3a0: S_b3a0 LDA BONUS a5 e3 ; if bonus rewarded, kill all fire 0xb3a2: BMI L_b3eb 30 47 ; audio 0xb3a4: LDA EVICM a5 e6 ; if only one victim left, set off 0xb3a6: CMP #$f0 c9 f0 ; alarm instead of fire sound when 0xb3a8: BNE L_b3cd d0 23 ; the victim flashes white 0xb3aa: LDX SECTIM a6 e9 ; combine SECTIM and FRMTIM to get 0xb3ac: DEX ca ; half second timer: if flashing 0xb3ad: STX DUMMY 86 97 ; white alarm sound; else, do floyd 0xb3af: LDA FRMTIM a5 ea ; sound 0xb3b1: ASL A 0a ; 0xb3b2: ASL A 0a ; 0xb3b3: ASL A 0a ; 0xb3b4: ROL DUMMY 26 97 ; 0xb3b6: LDA DUMMY a5 97 ; 0xb3b8: CMP #$05 c9 05 ; 0xb3ba: BPL L_b3cd 10 11 ; 0xb3bc: LSR A 4a ; 0xb3bd: BCS L_b3cd b0 0e ; 0xb3bf: LDA #$05 a9 05 ; 0xb3c1: STA $16 85 16 ; 0xb3c3: LDA #$1f a9 1f ; 0xb3c5: STA $18 85 18 ; 0xb3c7: LDA #$0f a9 0f ; 0xb3c9: STA $1a 85 1a ; 0xb3cb: BNE L_b3fd d0 30 ; (acts like "jmp") 0xb3cd: L_b3cd LDA #$02 a9 02 ; floyd sound 0xb3cf: STA $16 85 16 ; 0xb3d1: LDX #$00 a2 00 ; 0xb3d3: LDY #$0c a0 0c ; 0xb3d5: L_b3d5 LDA $c3,X b5 c3 ; number of floyds left determines 0xb3d7: AND #$08 29 08 ; the volume of the sound 0xb3d9: BNE L_b3dc d0 01 ; 0xb3db: INY c8 ; 0xb3dc: L_b3dc INX e8 ; 0xb3dd: CPX #$0a e0 0a ; 0xb3df: BNE L_b3e3 d0 02 ; 0xb3e1: LDX #$10 a2 10 ; 0xb3e3: L_b3e3 CPX #$1a e0 1a ; 0xb3e5: BNE L_b3d5 d0 ee ; 0xb3e7: CPY #$20 c0 20 ; if no flames left, special branch 0xb3e9: BNE L_b3f7 d0 0c ; (MHZ) 0xb3eb: L_b3eb LDA #$00 a9 00 ; no volume since no flames 0xb3ed: STA $1a 85 1a ; 0xb3ef: LDX BONUS a6 e3 ; if bonus flag is negative, then its 0xb3f1: BMI L_b3fd 30 0a ; already done this; else set for 0xb3f3: STA BONUS 85 e3 ; $00 to allow the one time entry ; ; into bonus scoring routine 0xb3f5: BPL L_b3fd 10 06 ; (acts like "jmp") 0xb3f7: L_b3f7 STY $18 84 18 ; load number of floyds left into 0xb3f9: LDA #$0f a9 0f ; volume 0xb3fb: STA $1a 85 1a ; ; ; ; a relic from the dark ages of my ; ; programming past (in other words, ; ; I don't understand it) 0xb3fd: L_b3fd LDA SOUDUM a5 e0 ; basis of this routine is that it 0xb3ff: BEQ L_b427 f0 26 ; ramps through a given type of 0xb401: BMI L_b412 30 0f ; sound 0xb403: CMP #$14 c9 14 ; 0xb405: BNE L_b40d d0 06 ; 0xb407: LDA ODDEVE a5 95 ; lower nibble of SOUDUM determines 0xb409: LSR A 4a ; the sound type 0xb40a: BCS L_b40d b0 01 ; bit #7 determines whether its a 0xb40c: RTS 60 ; high to low or vice versa for ; ; pitch, and that value is kept in ; ; SOUDIR (up or down count) 0xb40d: L_b40d INC SOUDIR e6 e1 ; if SOUDUM is $00, then no sound 0xb40f: JMP L_b414 4c 14 b4 ; any new sound takes precedence over 0xb412: L_b412 DEC SOUDIR c6 e1 ; any current sound 0xb414: L_b414 LDA SOUDIR a5 e1 ; 0xb416: BMI L_b427 30 0f ; 0xb418: CMP #$20 c9 20 ; 0xb41a: BEQ L_b427 f0 0b ; 0xb41c: STA $17 85 17 ; 0xb41e: LDA SOUDUM a5 e0 ; 0xb420: STA $15 85 15 ; 0xb422: LDA #$0f a9 0f ; 0xb424: STA $19 85 19 ; 0xb426: RTS 60 ; 0xb427: L_b427 LDA #$00 a9 00 ; 0xb429: STA $19 85 19 ; 0xb42b: STA SOUDUM 85 e0 ; 0xb42d: RTS 60 ; ; ; ; ***** This routine is a true relic of the times when it took five ; floors to get to the exterior of the building. The code never ; really got done right to reflect that the five-floor system, ; but it appears to work and serve its purpose. ***** ; 0xb42e: S_b42e JSR S_b052 20 52 b0 ; done at the end of each floor, give 0xb431: LDA SAVES a5 f5 ; the number of saved victims to 0xb433: STA VICONE,X 95 a9 ; correct player 0xb435: S_b435 LDY ONEFIV a4 9e ; see if player one has had his turn 0xb437: BEQ L_b445 f0 0c ; 0xb439: LDA LOCKUP a5 f7 ; see if player two is locked out 0xb43b: LSR A 4a ; (game #4); if so, indicate in 0xb43c: LSR A 4a ; appropriate place 0xb43d: LSR A 4a ; 0xb43e: LSR A 4a ; 0xb43f: ORA TWOFIV 05 9f ; 0xb441: STA TWOFIV 85 9f ; see if player two has had his turn 0xb443: BNE L_b45a d0 15 ; 0xb445: L_b445 LDA WHICH a5 eb ; if either player gets to go again, 0xb447: EOR #$ff 49 ff ; reverse player indicator and 0xb449: STA WHICH 85 eb ; double check the other player 0xb44b: AND #$01 29 01 ; 0xb44d: TAX aa ; 0xb44e: LDA ONEFIV,X b5 9e ; if double check shows they've both 0xb450: BNE L_b445 d0 f3 ; gone, so be it 0xb452: JSR S_b2ad 20 ad b2 ; if not, load this player's score ; ; into display 0xb455: PLA 68 ; adjust stack to JMP not RTS 0xb456: PLA 68 ; 0xb457: JMP L_b07f 4c 7f b0 ; go give them their floor to do 0xb45a: L_b45a PLA 68 ; adjust stack to JMP not RTS 0xb45b: PLA 68 ; 0xb45c: JMP L_b9dd 4c dd b9 ; both players finished, go to ; ; outside ; ; ***** THE DRIVER OF THE INTERIOR ***** ; 0xb45f: L_b45f JSR S_bc4e 20 4e bc ; check to see if the player has ; ; aborted game 0xb462: LDA RIGHOR a5 82 ; if fireman out of floor then 0xb464: CMP D_b997 cd 97 b9 ; advance, else continue displaying 0xb467: BNE L_b46c d0 03 ; this floor 0xb469: JSR S_b42e 20 2e b4 ; 0xb46c: L_b46c LDA EXCESS a5 bf ; if "white-flash" death on, freeze 0xb46e: BNE L_b476 d0 06 ; everything 0xb470: JSR S_b1d2 20 d2 b1 ; check for a hit 0xb473: JSR S_b2ca 20 ca b2 ; move the fireman 0xb476: L_b476 JSR S_b171 20 71 b1 ; flicker the floyds 0xb479: L_b479 JSR S_b242 20 42 b2 ; countdown the victims 0xb47c: JSR S_b15f 20 5f b1 ; position the value et al 0xb47f: JSR S_b36b 20 6b b3 ; which mask for fireman 0xb482: JSR S_b3a0 20 a0 b3 ; call all the sounds 0xb485: JMP L_b5d0 4c d0 b5 ; okay to go to the drawing routine ; 0xb488: D_b488 DB $00,$00 ; data for the $0E masks for 0xb48a: DB $55,$55,$55,$22 ; victim display 0xb48e: DB $22,$77,$22,$22 ; ; 0xb492: D_b492 DB $00,$00 ; data for the $0F masks for 0xb494: DB $aa,$aa,$aa,$44 ; victim display 0xb498: DB $44,$ee,$44,$44 ; ; 0xb49c: D_b49c DB $00,$00 ; data for the $0E mask display ; ; of digits 0xb49e: DB $ee,$ee,$aa,$aa ; 0xb4a2: DB $aa,$aa,$aa,$ee ; 0xb4a6: DB $00,$00,$00,$00 ; 0xb4aa: DB $00,$00,$00,$00 ; ; 0xb4ae: DB $ee,$ee,$44,$44 ; 0xb4b2: DB $44,$44,$44,$cc ; 0xb4b6: DB $00,$00,$00,$00 ; 0xb4ba: DB $00,$00,$00,$00 ; ; 0xb4be: DB $ee,$ee,$88,$88 ; 0xb4c2: DB $cc,$66,$22,$ee ; 0xb4c6: DB $00,$00,$00,$00 ; 0xb4ca: DB $00,$00,$00,$00 ; ; 0xb4ce: DB $ee,$ee,$22,$22 ; 0xb4d2: DB $ee,$22,$22,$ee ; 0xb4d6: DB $00,$00,$00,$00 ; 0xb4da: DB $00,$00,$00,$00 ; ; 0xb4de: DB $22,$22,$22,$22 ; 0xb4e2: DB $ee,$aa,$aa,$88 ; 0xb4e6: DB $00,$00,$00,$00 ; 0xb4ea: DB $00,$00,$00,$00 ; ; 0xb4ee: DB $ee,$22,$22,$66 ; 0xb4f2: DB $cc,$88,$88,$ee ; 0xb4f6: DB $00,$00,$00,$00 ; 0xb4fa: DB $00,$00,$00,$00 ; ; 0xb4fe: DB $ee,$ee,$aa,$aa ; 0xb502: DB $ee,$88,$88,$ee ; 0xb506: DB $00,$00,$00,$00 ; 0xb50a: DB $00,$00,$00,$00 ; ; 0xb50e: DB $88,$88,$44,$44 ; 0xb512: DB $22,$22,$22,$ee ; 0xb516: DB $00,$00,$00,$00 ; 0xb51a: DB $00,$00,$00,$00 ; ; 0xb51e: DB $ee,$ee,$aa,$aa ; 0xb522: DB $ee,$aa,$aa,$ee ; 0xb526: DB $00,$00,$00,$00 ; 0xb52a: DB $00,$00,$00,$00 ; ; 0xb52e: DB $22,$22,$22,$22 ; 0xb532: DB $ee,$aa,$aa,$ee ; ; 0xb536: D_b536 DB $00,$00 ; data for the $0F mask display ; ; of digits 0xb538: DB $77,$77,$55,$55 ; 0xb53c: DB $55,$55,$77,$77 ; 0xb540: DB $00,$00,$00,$00 ; 0xb544: DB $00,$00,$00,$00 ; ; 0xb548: DB $77,$77,$22,$22 ; 0xb54c: DB $22,$22,$22,$33 ; 0xb550: DB $00,$00,$00,$00 ; 0xb554: DB $00,$00,$00,$00 ; ; 0xb558: DB $77,$77,$11,$11 ; 0xb55c: DB $33,$66,$44,$77 ; 0xb560: DB $00,$00,$00,$00 ; 0xb564: DB $00,$00,$00,$00 ; ; 0xb568: DB $77,$77,$44,$44 ; 0xb56c: DB $77,$44,$44,$77 ; 0xb570: DB $00,$00,$00,$00 ; 0xb574: DB $00,$00,$00,$00 ; ; 0xb578: DB $44,$44,$44,$44 ; 0xb57c: DB $77,$55,$55,$11 ; 0xb580: DB $00,$00,$00,$00 ; 0xb584: DB $00,$00,$00,$00 ; ; 0xb588: DB $77,$44,$44,$66 ; 0xb58c: DB $33,$11,$11,$77 ; 0xb590: DB $00,$00,$00,$00 ; 0xb594: DB $00,$00,$00,$00 ; ; 0xb598: DB $77,$77,$55,$55 ; 0xb59c: DB $77,$11,$11,$77 ; 0xb5a0: DB $00,$00,$00,$00 ; 0xb5a4: DB $00,$00,$00,$00 ; ; 0xb5a8: DB $11,$11,$22,$22 ; 0xb5ac: DB $44,$44,$44,$77 ; 0xb5b0: DB $00,$00,$00,$00 ; 0xb5b4: DB $00,$00,$00,$00 ; ; 0xb5b8: DB $77,$77,$55,$55 ; 0xb5bc: DB $77,$55,$55,$77 ; 0xb5c0: DB $00,$00,$00,$00 ; 0xb5c4: DB $00,$00,$00,$00 ; ; 0xb5c8: DB $44,$44,$44,$44 ; 0xb5cc: DB $77,$55,$55,$77 ; ; 0xb5d0: L_b5d0 LDA #$00 a9 00 ; clear the low resolution masks 0xb5d2: STA $0d 85 0d ; 0xb5d4: STA $0e 85 0e ; 0xb5d6: STA $0f 85 0f ; 0xb5d8: LDA FUPPER a5 9d ; load permanent $0F floor pattern 0xb5da: STA FUPDUM 85 91 ; info into dummies that can be 0xb5dc: LDA FLOWER a5 9c ; displayed 0xb5de: STA FLODUM 85 90 ; 0xb5e0: JSR S_b052 20 52 b0 ; which player is up 0xb5e3: LDA DANGER,X b5 ae ; save the floor number (in the upper 0xb5e5: ASL A 0a ; nibble) and save game on stack 0xb5e6: ASL A 0a ; 0xb5e7: ASL A 0a ; 0xb5e8: ASL A 0a ; 0xb5e9: PHA 48 ; 0xb5ea: LDA BONUS a5 e3 ; if no floyds left, use normal color 0xb5ec: BMI L_b60b 30 1d ; for the victims 0xb5ee: LDY SECTIM a4 e9 ; else, determine if a victim is 0xb5f0: DEY 88 ; about to die in half second 0xb5f1: STY DUMMY 84 97 ; intervals and flash it 0xb5f3: LDA FRMTIM a5 ea ; accordingly (white or black) 0xb5f5: ASL A 0a ; 0xb5f6: ASL A 0a ; 0xb5f7: ASL A 0a ; 0xb5f8: ROL DUMMY 26 97 ; 0xb5fa: LDA DUMMY a5 97 ; 0xb5fc: CMP #$05 c9 05 ; 0xb5fe: BPL L_b60b 10 0b ; 0xb600: LSR A 4a ; 0xb601: BCC L_b607 90 04 ; 0xb603: LDA #$00 a9 00 ; 0xb605: BEQ L_b60f f0 08 ; (acts like "jmp") 0xb607: L_b607 LDA #$0c a9 0c ; 0xb609: BNE L_b60f d0 04 ; (acts like "jmp") 0xb60b: L_b60b LDA ALTDUM a5 e8 ; 0xb60d: EOR #$ff 49 ff ; 0xb60f: L_b60f AND CHROMA 25 9b ; 0xb611: STA LCOLOR 85 06 ; put the right victim color in color ; ; register 0xb613: LDY #$09 a0 09 ; pre-load the number of lines to be ; ; devoted to the score and victim ; ; display 0xb615: PLA 68 ; retrieve the floor index and stuff 0xb616: STA DUMMY 85 97 ; in dummy 0xb618: L_b618 LDA $0284 ad 84 02 ; check the timer and go when it 0xb61b: BNE L_b618 d0 fb ; equals zero 0xb61d: STA $02 85 02 ; wait until next horizontal line 0xb61f: STA $2a 85 2a ; inc all horizontal shift factors 0xb621: STA $01 85 01 ; turn on the electron gun 0xb623: STA $2c 85 2c ; clear all the collision registers 0xb625: LDA ODDEVE a5 95 ; check multiplexer to which column 0xb627: LSR A 4a ; of floyds should be drawn and 0xb628: BCS L_b62f b0 05 ; stuff this info in an indirect ; ; address register 0xb62a: LDA #$d0 a9 d0 ; 0xb62c: JMP L_b633 4c 33 b6 ; 0xb62f: L_b62f STA $10 85 10 ; 0xb631: LDA #$c0 a9 c0 ; 0xb633: L_b633 STA POINT 85 88 ; 0xb635: LDA RIGVER a5 81 ; put the fireman's vertical position 0xb637: STA RCON 85 8b ; in dummy counter 0xb639: LDA WATPOS a5 f4 ; put the water's vertical position 0xb63b: STA LCON 85 8a ; in dummy counter 0xb63d: LDA #$80 a9 80 ; initialize floyd shift (value no 0xb63f: STA $20 85 20 ; longer right, but it works ; ; anyway) 0xb641: LDX #$00 a2 00 ; clear the other shift registers 0xb643: STX $21 86 21 ; 0xb645: STX $22 86 22 ; 0xb647: STX $23 86 23 ; 0xb649: LDA #$02 a9 02 ; set for two low resolution colors 0xb64b: STA LOWSET 85 0a ; 0xb64d: LDA WHICH a5 eb ; load player's color into register 0xb64f: AND CHROMA 25 9b ; (check B&W) 0xb651: STA RCOLOR 85 07 ; 0xb653: TXA 8a ; using multiplexer, do I draw the 0xb654: BCC L_b687 90 31 ; score or the victims ; ; display the victims and floor level 0xb656: L_b656 STA $02 85 02 ; wait until next horizontal line 0xb658: NOP ea ; 0xb659: LDA D_b488,Y b9 88 b4 ; load the masks indexed by what line 0xb65c: AND EVICM 25 e6 ; and "AND" with the number of ; ; remaining masks and display 0xb65e: STA $0e 85 0e ; stuff in the first $0E 0xb660: LDA D_b492,Y b9 92 b4 ; 0xb663: AND FVICM 25 e7 ; 0xb665: STA $0f 85 0f ; stuff it 0xb667: TYA 98 ; display the fourth digit of score 0xb668: ORA SCODS1 05 8c ; using method described at L_b687 0xb66a: TAX aa ; 0xb66b: LDA D_b49c,X bd 9c b4 ; 0xb66e: AND #$f0 29 f0 ; 0xb670: STA $0e 85 0e ; store this digit in the second $0E 0xb672: LDA #$00 a9 00 ; make sure second $0D is clear 0xb674: STA $0d 85 0d ; 0xb676: NOP ea ; 0xb677: STA $0f 85 0f ; clear out second $0F 0xb679: TYA 98 ; 0xb67a: ORA DUMMY 05 97 ; grab level number held in dummy, 0xb67c: TAX aa ; index the right mask, and dump in 0xb67d: LDA D_b536,X bd 36 b5 ; $0D after being past second $0D ; ; so it will only show in first 0xb680: STA $0d 85 0d ; stuff it in first $0D 0xb682: DEY 88 ; 0xb683: BNE L_b656 d0 d1 ; do until all lines are done then 0xb685: BEQ L_b6b7 f0 30 ; clear out ; ; draw the last three digits of score 0xb687: L_b687 STA $02 85 02 ; wait until next horizontal line 0xb689: STA $2a 85 2a ; update shift for the floyds 0xb68b: STA $0e 85 0e ; clear out first $0E and $0F 0xb68d: STA $0f 85 0f ; 0xb68f: TYA 98 ; grab line number, 'ORA' with the 0xb690: ORA SCODS4 05 8f ; digit value and use that value to 0xb692: TAX aa ; find the right mask to display ; ; (need to combine two for $0F) 0xb693: LDA D_b536,X bd 36 b5 ; do half of $0F and hold in dummy 0xb696: AND #$f0 29 f0 ; 0xb698: STA DUMMY 85 97 ; 0xb69a: TYA 98 ; do the $0E value 0xb69b: ORA SCODS2 05 8d ; 0xb69d: TAX aa ; 0xb69e: LDA D_b49c,X bd 9c b4 ; 0xb6a1: AND #$0f 29 0f ; 0xb6a3: STA $0e 85 0e ; display in the second $0E 0xb6a5: TYA 98 ; do the rest of $0F 0xb6a6: ORA SCODS3 05 8e ; 0xb6a8: TAX aa ; 0xb6a9: LDA D_b536,X bd 36 b5 ; 0xb6ac: AND #$0f 29 0f ; 0xb6ae: ORA DUMMY 05 97 ; merge with previously calculated ; ; $0F 0xb6b0: STA $0f 85 0f ; store in second $0F 0xb6b2: LDA #$00 a9 00 ; clear accumulator to clear $0E and 0xb6b4: DEY 88 ; $0F at head 0xb6b5: BNE L_b687 d0 d0 ; 0xb6b7: L_b6b7 LDA #$25 a9 25 ; because of L_b656, don't want to 0xb6b9: AND OVEUND 25 f0 ; wait, just sail through and set 0xb6bb: STA LOWSET 85 0a ; $0A to over/under and one low ; ; color, two high color 0xb6bd: LDA ALTDUM a5 e8 ; load floor color 0xb6bf: AND CHROMA 25 9b ; 0xb6c1: STA ACOLOR 85 08 ; 0xb6c3: LDA VALCOL a5 e4 ; load valve color 0xb6c5: AND CHROMA 25 9b ; 0xb6c7: STA LCOLOR 85 06 ; 0xb6c9: STA $02 85 02 ; wait until next horizontal line 0xb6cb: LDY #$ff a0 ff ; make $0E solid and, except for 0xb6cd: STY $0e 84 0e ; valve opening, $0F 0xb6cf: LDY #$7f a0 7f ; 0xb6d1: STY $0f 84 0f ; 0xb6d3: STY $1d 84 1d ; turn on object $1D (the valve) 0xb6d5: STY TRIG1D 84 f1 ; 0xb6d7: LDA #$30 a9 30 ; x8 for valve magnification 0xb6d9: STA $04 85 04 ; 0xb6db: LDY #$0e a0 0e ; pre-load the number of rows counter ; ; for main 0xb6dd: LDA (POINT),Y b1 88 ; get the first floyd info from right ; ; column 0xb6df: STA $20 85 20 ; store the shift factor (upper ; ; nibble) 0xb6e1: AND #$08 29 08 ; isolate bit #3 (on/off) and store 0xb6e3: STA FIRDUM 85 e5 ; in dummy 0xb6e5: LDA #$80 a9 80 ; set thin wall around floor ($0D) 0xb6e7: STA $0d 85 0d ; 0xb6e9: L_b6e9 STA $02 85 02 ; return for start each row, wait ; ; next horizontal 0xb6eb: STA $2a 85 2a ; update the shift 0xb6ed: LDX #$0b a2 0b ; load number of lines per row 0xb6ef: STX DUMMY 86 97 ; counter 0xb6f1: JMP L_b703 4c 03 b7 ; bypass 0xb6f4: L_b6f4 STA $02 85 02 ; wait until next horizontal line 0xb6f6: LDA TRIG1D a5 f1 ; determine if $1D should be drawn, 0xb6f8: STA $1d 85 1d ; by virtue of value in TRIGID ; ; (valve and extra fireman) 0xb6fa: JMP L_b703 4c 03 b7 ; bypass 0xb6fd: L_b6fd STA $02 85 02 ; wait until next horizontal line ; ; ; I would have expected this line to ; ; be "LDA DOUBLE,X" as $b0 is an ; ; EQU to DOUBLE, but my master ; ; indicates LDA $b0,X 0xb6ff: LDA $b0,X b5 b0 ; grab right floyd mask 0xb701: STA $1b 85 1b ; load 0xb703: L_b703 LDX RCON a6 8b ; see if fireman should be drawn 0xb705: CPX #$09 e0 09 ; 0xb707: BCS L_b70d b0 04 ; no fireman 0xb709: LDA $a0,X b5 a0 ; grab the right mask 0xb70b: STA $1c 85 1c ; load 0xb70d: L_b70d LDA #$00 a9 00 ; default if no water 0xb70f: LDX LCON a6 8a ; see if water should be drawn 0xb711: CPX #$02 e0 02 ; 0xb713: BCS L_b717 b0 02 ; no water 0xb715: LDA #$02 a9 02 ; water mask 0xb717: L_b717 STA $1e 85 1e ; load 0xb719: INC RCON e6 8b ; increment the fireman counter 0xb71b: INC LCON e6 8a ; increment the water counter 0xb71d: LDX DUMMY a6 97 ; see if more lines left to draw of ; ; that row 0xb71f: BEQ L_b6e9 f0 c8 ; if line count = 0 (note that this ; ; is the second of two tests and ; ; that the next row info has ; ; already been prepared), go to ; ; next row 0xb721: DEX ca ; decrement the line counter 0xb722: STX DUMMY 86 97 ; store this info safely 0xb724: BEQ L_b72d f0 07 ; if line count = 0 (note this is ; ; the first of two tests), then the ; ; next line will be the last and ; ; should prepare the next row ; ; material 0xb726: LDA FIRDUM a5 e5 ; see if there are floyds to draw or ; ; not 0xb728: BNE L_b6fd d0 d3 ; draw floyds 0xb72a: JMP L_b6f4 4c f4 b6 ; worry about $1D ; ; ; set up for next row 0xb72d: L_b72d DEY 88 ; decrement row counter 0xb72e: BMI L_b7a2 30 72 ; if negative, then all done 0xb730: LDA (POINT),Y b1 88 ; grab next set of floyds 0xb732: STA $20 85 20 ; put the shift value in 0xb734: STA $04 85 04 ; put in magnification/multiplication ; ; register 0xb736: AND #$08 29 08 ; grab bit #3 (on/off) and stuff in 0xb738: STA FIRDUM 85 e5 ; dummy 0xb73a: TYA 98 ; see if its the last row, and bounce 0xb73b: BEQ L_b758 f0 1b ; to L_b758 if it is 0xb73d: ASL FLODUM 06 90 ; roll floor pattern through FLODUM 0xb73f: ROL FUPDUM 26 91 ; and FUPDUM and, using the row 0xb741: ROL A 2a ; counter plus this bit, grab the 0xb742: TAX aa ; right maze pattern for $0F and 0xb743: LDA D_b818,X bd 18 b8 ; store on the stack 0xb746: PHA 48 ; 0xb747: LDA #$2c a9 2c ; set the fire color 0xb749: AND CHROMA 25 9b ; 0xb74b: STA LCOLOR 85 06 ; this fire color also kills $1D 0xb74d: STA $1d 85 1d ; valve since valve only drawn 0xb74f: STA TRIG1D 85 f1 ; first row 0xb751: LDA BONUS a5 e3 ; see if there should be a maze or ; ; not 0xb753: BMI L_b7ce 30 79 ; no maze 0xb755: JMP L_b7bc 4c bc b7 ; yes maze ; ; get ready to do the bottom row 0xb758: L_b758 LDA GATE a5 e2 ; see if the gate should be on or off 0xb75a: STA $1f 85 1f ; and load into register 0xb75c: LDA MENLEF a5 96 ; if no men left, draw barricade, 0xb75e: BEQ L_b782 f0 22 ; else do men 0xb760: STA $02 85 02 ; wait until next horizontal line 0xb762: STA $2a 85 2a ; increment the shift factors 0xb764: STY $0d 84 0d ; clear all low resolution masks 0xb766: STY $0e 84 0e ; 0xb768: STY $0f 84 0f ; 0xb76a: AND #$03 29 03 ; dump mag and multi info into the 0xb76c: ORA #$30 09 30 ; right register -- floyds don't ; ; matter now 0xb76e: STA $04 85 04 ; (want the bullets x8) 0xb770: LDA #$03 a9 03 ; 0xb772: STA TRIG1D 85 f1 ; turn on $1D flag (extra firemen) 0xb774: NOP ea ; 0xb775: STA $12 85 12 ; absolute position the fireman 0xb777: LDA WHICH a5 eb ; determine what color they should be 0xb779: AND CHROMA 25 9b ; 0xb77b: STA LCOLOR 85 06 ; 0xb77d: NOP ea ; 0xb77e: NOP ea ; 0xb77f: JMP L_b703 4c 03 b7 ; go back and draw that last row ; ; ; no men left 0xb782: L_b782 NOP ea ; 0xb783: ORA #$20 09 20 ; draw a single bar the same color as ; ; maze 0xb785: STA $04 85 04 ; bar is x4 magnification 0xb787: LDA #$02 a9 02 ; 0xb789: STA TRIG1D 85 f1 ; turn on $1D (the "bar") 0xb78b: LDA ALTDUM a5 e8 ; make "bar" same color as floor 0xb78d: AND CHROMA 25 9b ; 0xb78f: STA LCOLOR 85 06 ; 0xb791: LDA #$60 a9 60 ; shift factor for the bar (from 0xb793: STA $22 85 22 ; valve position) 0xb795: STA $02 85 02 ; wait until next horizontal line 0xb797: STA $2a 85 2a ; update the shifts 0xb799: STY $0d 84 0d ; clear all the low resolution masks 0xb79b: STY $0e 84 0e ; 0xb79d: STY $0f 84 0f ; 0xb79f: JMP L_b703 4c 03 b7 ; go back and draw that last row ; ; all done with all that 0xb7a2: L_b7a2 LDA #$00 a9 00 ; 0xb7a4: STA $02 85 02 ; wait until next horizontal line 0xb7a6: STY $0d 84 0d ; fill all the low res masks (Y=$FF) 0xb7a8: STY $0e 84 0e ; 0xb7aa: STA $1c 85 1c ; clear all high resolution masks 0xb7ac: STA $1d 85 1d ; 0xb7ae: STA $1e 85 1e ; 0xb7b0: STA $1f 85 1f ; 0xb7b2: STY $0f 84 0f ; 0xb7b4: TAY a8 ; 0xb7b5: LDA (POINT),Y b1 88 ; save last shift factor to be used 0xb7b7: STA $20 85 20 ; on the next pass (multiplex) 0xb7b9: JMP L_b83c 4c 3c b8 ; get the hell out of this mess ; 0xb7bc: L_b7bc TYA 98 ; want the maze 0xb7bd: ORA EPATRN 05 92 ; grab the right $0E mask by index of 0xb7bf: TAX aa ; row and ERATRN 0xb7c0: LDA D_b7d8,X bd d8 b7 ; 0xb7c3: TAX aa ; store $0E in "X" 0xb7c4: PLA 68 ; store $0F in "A" from stack save 0xb7c5: L_b7c5 STA $02 85 02 ; wait until next horizontal line 0xb7c7: STX $0e 86 0e ; load the two low resolution masks 0xb7c9: STA $0f 85 0f ; 0xb7cb: JMP L_b703 4c 03 b7 ; go draw the next row ; ; no maze 0xb7ce: L_b7ce CPY #$01 c0 01 ; if second to last row, use maze 0xb7d0: BEQ L_b7bc f0 ea ; info to build the entrance way 0xb7d2: PLA 68 ; restore the stack from that save 0xb7d3: LDA #$00 a9 00 ; load everything with $00 0xb7d5: TAX aa ; 0xb7d6: BEQ L_b7c5 f0 ed ; (acts like "jmp") go to merge with ; ; the rest (dumping $00 into both ; ; of the masks) ; 0xb7d8: D_b7d8 DB $00,$ff,$01 ; the four possible 0xb7db: DB $01,$00,$c0,$00 ; combinations for the $0E 0xb7df: DB $00,$00 ; masks 0xb7e1: DB $00,$00,$c0,$00 ; 0xb7e5: DB $00,$ff,$00 ; ; 0xb7e8: DB $00,$ff,$01 ; 0xb7eb: DB $01,$00,$00,$00 ; 0xb7ef: DB $00,$3f ; 0xb7f1: DB $00,$00,$00,$00 ; 0xb7f5: DB $00,$ff,$00 ; ; 0xb7f8: DB $00,$ff,$01 ; 0xb7fb: DB $01,$00,$c1,$01 ; 0xb7ff: DB $00,$00 ; 0xb801: DB $00,$01,$c1,$00 ; 0xb805: DB $00,$ff,$00 ; ; 0xb808: DB $00,$ff,$01 ; this is the pattern for 9th 0xb80b: DB $01,$00,$01,$01 ; floor (no label apparently 0xb80f: DB $00,$3f ; necessary as this is just 0xb811: DB $00,$01,$01,$00 ; documentation note) 0xb815: DB $00,$ff,$00 ; ; 0xb818: D_b818 DB $00,$00 ; possible combinations for the 0xb81a: DB $1f,$1f ; $0F maze masks (row ASL-ed 0xb81c: DB $00,$01 ; with the key bit from 0xb81e: DB $00,$c0 ; FLODUM and FUPDUM brought 0xb820: DB $00,$f0 ; in to the $0 spot provides 0xb822: DB $c0,$ff ; the index) 0xb824: DB $00,$co ; 0xb826: DB $00,$c0 ; 0xb828: DB $f0,$ff ; 0xb82a: DB $00,$c0 ; 0xb82c: DB $00,$c0 ; 0xb82e: DB $c0,$ff ; 0xb830: DB $00,$co ; 0xb832: DB $00,$01 ; 0xb834: DB $7f,$7f ; ; 0xb836: X_b836 STA $02 85 02 ; last minute emergency routine to 0xb838: DEX ca ; pad every frame with "x" number 0xb839: BNE X_b836 d0 fb ; of extra lines to achieve sync 0xb83b: RTS 60 ; ; 0xb83c: L_b83c JSR S_b1ad 20 ad b1 ; keep the random number generator 0xb83f: LDA EXCESS a5 bf ; going in "white-flash" mode, no 0xb841: BEQ L_b84b f0 08 ; paddle read, so do extra lines on 0xb843: LDX #$12 a2 12 ; top of the extra being padded to 0xb845: JSR X_b836 20 36 b8 ; begin with 0xb848: JMP L_b90d 4c 0d b9 ; 0xb84b: L_b84b LDX #$0d a2 0d ; regular pad only (will be reading 0xb84d: JSR X_b836 20 36 b8 ; the paddles) ; 0xb850: STX INCREG 86 83 ; clear INCREG 0xb852: LDA WHICH a5 eb ; determine which player is up and 0xb854: LSR A 4a ; duplicate his paddle info into 0xb855: LDA $0280 ad 80 02 ; both upper and lower nibble of 0xb858: BCS L_b865 b0 0b ; what the program thinks is the 0xb85a: AND #$0f 29 0f ; paddle read 0xb85c: STA DUMMY 85 97 ; 0xb85e: ASL A 0a ; 0xb85f: ASL A 0a ; 0xb860: ASL A 0a ; 0xb861: ASL A 0a ; 0xb862: JMP L_b86d 4c 6d b8 ; 0xb865: L_b865 AND #$f0 29 f0 ; 0xb867: STA DUMMY 85 97 ; 0xb869: LSR A 4a ; 0xb86a: LSR A 4a ; 0xb86b: LSR A 4a ; 0xb86c: LSR A 4a ; 0xb86d: L_b86d ORA DUMMY 05 97 ; 0xb86f: STA DUMMY 85 97 ; store the double info in DUMMY 0xb871: ORA #$cc 09 cc ; put the vertical info in "X" 0xb873: TAX aa ; 0xb874: LDA DUMMY a5 97 ; put the horizontal info in "Y" 0xb876: ORA #$33 09 33 ; 0xb878: TAY a8 ; ; 0xb879: STA $02 85 02 ; wait until next horizontal line 0xb87b: LDA RIGVER a5 81 ; check to see if at bottom of 0xb87d: CMP D_b996 cd 96 b9 ; screen; if so, do not allow any 0xb880: BCS L_b888 b0 06 ; more down movement (make "X" $FF) 0xb882: CPX #$dd e0 dd ; 0xb884: BNE L_b888 d0 02 ; 0xb886: LDX #$ff a2 ff ; ; 0xb888: L_b888 STA $02 85 02 ; wait until next horizontal line 0xb88a: LDA $33 a5 33 ; see if there was contact with 0xb88c: AND #$c0 29 c0 ; non-passable object (wall, extra 0xb88e: BNE L_b894 d0 04 ; men, gate, etc.) and, if not, 0xb890: LDA $30 a5 30 ; bounce away 0xb892: BPL L_b8c0 10 2c ; 0xb894: L_b894 LDA CURPDL a5 94 ; if there was, look at the previous 0xb896: ORA #$cc 09 cc ; move and mark the next move an 0xb898: CMP #$ee c9 ee ; invert of both the "X" and "Y" of 0xb89a: BEQ L_b8a4 f0 08 ; past move, thus getting off the 0xb89c: CMP #$dd c9 dd ; obstacle (if no move last time in 0xb89e: BEQ L_b8a8 f0 08 ; a given direction, make current a 0xb8a0: LDX #$ff a2 ff ; no-move ($FF) 0xb8a2: BNE L_b8aa d0 06 ; (acts like "jmp") 0xb8a4: L_b8a4 LDX #$dd a2 dd ; 0xb8a6: BNE L_b8aa d0 02 ; 0xb8a8: L_b8a8 LDX #$ee a2 ee ; 0xb8aa: L_b8aa LDA CURPDL a5 94 ; 0xb8ac: ORA #$33 09 33 ; 0xb8ae: CMP #$bb c9 bb ; 0xb8b0: BEQ L_b8ba f0 08 ; 0xb8b2: CMP #$77 c9 77 ; 0xb8b4: BEQ L_b8be f0 08 ; 0xb8b6: LDY #$ff a0 ff ; 0xb8b8: BNE L_b8c0 d0 06 ; (acts like "jmp") 0xb8ba: L_b8ba LDY #$77 a0 77 ; 0xb8bc: BNE L_b8c0 d0 02 ; (acts like "jmp") 0xb8be: L_b8be LDY #$bb a0 bb ; 0xb8c0: L_b8c0 STY DUMMY 84 97 ; no longer needing to keep dummy, 0xb8c2: TXA 8a ; merge corrected "X" and "Y" (or 0xb8c3: AND DUMMY 25 97 ; movements in no need of 0xb8c5: STA CURPDL 85 94 ; correction as the "old" move for ; ; future paddle readings ; 0xb8c7: STA $02 85 02 ; wait until next horizontal line 0xb8c9: LDA #$ff a9 ff ; (I think this is useless code) 0xb8cb: CPX #$ee e0 ee ; see if there is up or down movement 0xb8cd: BEQ L_b8d5 f0 06 ; 0xb8cf: CPX #$dd e0 dd ; 0xb8d1: BEQ L_b8da f0 07 ; 0xb8d3: BNE L_b8dc d0 07 ; (acts like "jmp") 0xb8d5: L_b8d5 INC RIGVER e6 81 ; UP = increase the vertical position 0xb8d7: JMP L_b8dc 4c dc b8 ; 0xb8da: L_b8da DEC RIGVER c6 81 ; DOWN = decrease vertical position 0xb8dc: L_b8dc CPY #$bb c0 bb ; see if there if left or right 0xb8de: BEQ L_b8e6 f0 06 ; movement 0xb8e0: CPY #$77 c0 77 ; 0xb8e2: BEQ L_b8ef f0 0b ; 0xb8e4: BNE L_b8f5 d0 0f ; (acts like "jmp") 0xb8e6: L_b8e6 LDA #$10 a9 10 ; LEFT = alter horizontal shift 0xb8e8: STA INCREG 85 83 ; 0xb8ea: INC RIGHOR e6 82 ; LEFT = increase horizontal position 0xb8ec: JMP L_b8f5 4c f5 b8 ; counter 0xb8ef: L_b8ef LDA #$f0 a9 f0 ; RIGHT = alter horizontal shift 0xb8f1: STA INCREG 85 83 ; 0xb8f3: DEC RIGHOR c6 82 ; RIGHT = decrease horizontal ; ; position counter ; 0xb8f5: L_b8f5 STA $02 85 02 ; wait until next horizontal line 0xb8f7: LDA WHICH a5 eb ; examining paddles again, determine 0xb8f9: LSR A 4a ; whether man is facing up or down 0xb8fa: LDA $0280 ad 80 02 ; and want to be facing left or 0xb8fd: EOR #$ff 49 ff ; right 0xb8ff: BCC L_b905 90 04 ; 0xb901: LSR A 4a ; 0xb902: LSR A 4a ; 0xb903: LSR A 4a ; 0xb904: LSR A 4a ; 0xb905: L_b905 STA MIRDUM 85 a8 ; 0xb907: AND #$03 29 03 ; 0xb909: BEQ L_b90d f0 02 ; 0xb90b: STA MANDIR 85 93 ; ; 0xb90d: L_b90d LDA #$02 a9 02 ; start blanking and sync interval 0xb90f: STA $02 85 02 ; wait until next horizontal line 0xb911: STA $01 85 01 ; begin vert blank (turn gun off) 0xb913: STA $00 85 00 ; begin vert sync (scan bottom to 0xb915: LDA #$2a a9 2a ; top) fire off the timer 0xb917: STA $0295 8d 95 02 ; 0xb91a: LDA ODDEVE a5 95 ; reverse the multiplexer 0xb91c: EOR #$01 49 01 ; 0xb91e: STA ODDEVE 85 95 ; ; 0xb920: L_b920 LDA $0284 ad 84 02 ; test timer for zero, then continue 0xb923: BNE L_b920 d0 fb ; 0xb925: STA $02 85 02 ; wait until next horizontal line 0xb927: STA $00 85 00 ; end vert sync (scan top to bottom) ; ; ***** THERE IS NOTE IN CODE THAT THIS WAS ANOTHER PART OF THE BAD ; TIMING BUG AS IT WAS ORIGINALLY #$24 AND CHANGED TO #$26 ***** 0xb929: LDA #$26 a9 26 ; ; 0xb92b: STA $0296 8d 96 02 ; fire off the timer 0xb92e: LSR EXCESS 46 bf ; roll TYPE and EXCESS to produce the 0xb930: LSR TYPE 46 ab ; "white-flash" on death (will only 0xb932: LDA EXCESS a5 bf ; amount to something if something ; ; besides $00 is stored in them) 0xb934: BCC L_b93a 90 04 ; TYPE into EXCESS to the right 0xb936: ORA #$80 09 80 ; 0xb938: BNE L_b93c d0 02 ; 0xb93a: L_b93a AND #$7f 29 7f ; 0xb93c: L_b93c STA EXCESS 85 bf ; 0xb93e: AND #$0f 29 0f ; 0xb940: STA BCOLOR 85 09 ; store in background color ; 0xb942: LDX EVICM a6 e6 ; if no victims left, kill all 0xb944: BNE L_b94e d0 08 ; remaining firemen 0xb946: LDA #$00 a9 00 ; 0xb948: STA MENLEF 85 96 ; 0xb94a: LDA EXCESS a5 bf ; don't do a total kill until after ; ; the "white-flash" is over 0xb94c: BEQ L_b977 f0 29 ; (acts like "jmp") 0xb94e: L_b94e LDA EXCESS a5 bf ; if no "white-flash", then I can go 0xb950: BEQ L_b958 f0 06 ; looking for one; else finish the ; ; current flash 0xb952: CMP #$01 c9 01 ; if there is "white-flash", when one 0xb954: BEQ L_b987 f0 31 ; last frame of flash, go to real ; ; death sequence 0xb956: BNE L_b974 d0 1c ; (acts like "jmp") 0xb958: L_b958 LDA $37 a5 37 ; if there has been contact between a 0xb95a: BMI L_b977 30 1b ; fireman and a floyd, go and set ; ; off the "white-flash" 0xb95c: AND #$40 29 40 ; while I'm at it, did the valve get 0xb95e: BEQ L_b974 f0 14 ; put out? 0xb960: LDA GATE a5 e2 ; if gate already open, no sound 0xb962: BEQ L_b96c f0 08 ; wanted 0xb964: LDA #$f8 a9 f8 ; sound for putting out the valve 0xb966: STA SOUDUM 85 e0 ; 0xb968: LDA #$20 a9 20 ; 0xb96a: STA SOUDIR 85 e1 ; 0xb96c: L_b96c LDA #$00 a9 00 ; open the gate at the bottom 0xb96e: STA GATE 85 e2 ; 0xb970: LDA ALTDUM a5 e8 ; make valve color the same as the 0xb972: STA VALCOL 85 e4 ; floor so it looks like it has ; ; disappeared 0xb974: L_b974 JMP L_b45f 4c 5f b4 ; go back to the driver ; 0xb977: L_b977 LDA #$cc a9 cc ; there has been a floyd that touched 0xb979: STA EXCESS 85 bf ; the fireman, so set off "white 0xb97b: STA TYPE 85 ab ; flash" and death sound, but do 0xb97d: LDA #$ff a9 ff ; not take action on the kill yet 0xb97f: STA SOUDIR 85 e1 ; 0xb981: LDA #$14 a9 14 ; 0xb983: STA SOUDUM 85 e0 ; 0xb985: BNE L_b974 d0 ed ; (acts like "jmp") 0xb987: L_b987 LDA MENLEF a5 96 ; last frame of "white-flash", take ; ; the action 0xb989: BEQ L_b99a f0 0f ; are there no more firemen left 0xb98b: LSR A 4a ; still some left so logical MENLEF 0xb98c: AND #$fb 29 fb ; to show the new amount and store 0xb98e: STA MENLEF 85 96 ; 0xb990: JSR S_b129 20 29 b1 ; reposition the fireman 0xb993: JMP L_b479 4c 79 b4 ; go back into the middle of driver ; ; (can't do it all because of cycle ; ; overload) ; 0xb996: D_b996 DB $59 ; to make sure fireman doesn't ; ; go off bottom (data for ; ; lines 0xb1ea "SBC D_b996" ; ; and 0xb87d "CMP D_b996") ; 0xb997: D_b997 DB $39 ; number to check to see if off ; ; the floor (data for line ; ; 0xb464 "CMP D_b997") ; 0xb998: D_b998 DB $01,$10 ; data for lockup players in ; ; game #4 ; ; ; this is where the program ends if a ; ; fireman has died and no extra ; ; firemen are left 0xb99a: L_b99a JSR S_b052 20 52 b0 ; see which player died 0xb99d: LDA SWITCH a5 80 ; what game is it? 0xb99f: CMP #$84 c9 84 ; get lost unless game #4 0xb9a1: BNE L_b9b5 d0 12 ; 0xb9a3: TAY a8 ; 0xb9a4: LDA D_b998,X bd 98 b9 ; lockout either player one or two 0xb9a7: STA DUMMY 85 97 ; 0xb9a9: LDA LOCKUP a5 f7 ; 0xb9ab: ORA DUMMY 05 97 ; 0xb9ad: STA LOCKUP 85 f7 ; 0xb9af: CMP #$11 c9 11 ; if both players died, end of game 0xb9b1: BEQ L_b9d8 f0 25 ; 0xb9b3: BNE L_b9c3 d0 0e ; (acts like "jmp") 0xb9b5: L_b9b5 LDA SWITCH a5 80 ; reload the game number 0xb9b7: BMI L_b9bf 30 06 ; stay here if a one player game 0xb9b9: CMP #$03 c9 03 ; unless game #3 (endless), end of 0xb9bb: BEQ L_b9c3 f0 06 ; game 0xb9bd: BNE L_b9d8 d0 19 ; (acts like "jmp") ; 0xb9bf: L_b9bf CMP #$85 c9 85 ; if game #5, go to special place 0xb9c1: BEQ L_b9ca f0 07 ; 0xb9c3: L_b9c3 DEC DANGER,X d6 ae ; drop the player back a floor 0xb9c5: L_b9c5 INC ONEFIV,X f6 9e ; indicate that's he's had his turn 0xb9c7: JSR S_b435 20 35 b4 ; go to place that can evaluate such 0xb9ca: L_b9ca LDA #$00 a9 00 ; game #5, drop player to bottom of 0xb9cc: STA ONELOW,X 95 84 ; first building and remove entire 0xb9ce: STA ONEHIG,X 95 86 ; score 0xb9d0: STA VICONE,X 95 a9 ; 0xb9d2: LDA #$10 a9 10 ; 0xb9d4: STA DANGER,X 95 ae ; 0xb9d6: BNE L_b9c5 d0 ed ; (acts like "jmp") ; 0xb9d8: L_b9d8 PHA 48 ; end of game, alter the stack and 0xb9d9: PHA 48 ; enter into a subroutine to be 0xb9da: JMP L_bc69 4c 69 bc ; found at L_bc69 (could be done as ; ; JSR, but that didn't work for ; ; debugging) ; ; ; ; ***** THE EXTERIOR OF THE BUILDING ***** ; 0xb9dd: L_b9dd LDA #$74 a9 74 ; if start of everything, assign the 0xb9df: STA TYPE 85 ab ; building color 0xb9e1: L_b9e1 LDA #$10 a9 10 ; set victims running to "not seen" 0xb9e3: STA VICTIE 85 f4 ; 0xb9e5: LDA #$04 a9 04 ; lock helicopter blades at a good 0xb9e7: STA MEMORY 85 96 ; place 0xb9e9: LDA #$ea a9 ea ; set helicopter on top of building 0xb9eb: STA RIGVER 85 81 ; 0xb9ed: LDA #$40 a9 40 ; initialize rapid game select 0xb9ef: STA RAPID 85 f5 ; 0xb9f1: LDA #$00 a9 00 ; initialize all the helicopter 0xb9f3: STA HETIM1 85 90 ; movement timers 0xb9f5: STA HETIM2 85 91 ; 0xb9f7: STA HETIM3 85 92 ; 0xb9f9: STA HETIM4 85 93 ; 0xb9fb: STA RETURN 85 f1 ; set flag for "do not return to ; ; interior" 0xb9fd: STA $0c 85 0c ; initialize the sound 0xb9ff: STA SOUDUM 85 e0 ; (I think this may be useless in 0xba01: STA SOUDIR 85 e1 ; current version -- older versions ; ; used SOUND1 and SOUND2 here) 0xba03: STA $19 85 19 ; 0xba05: LDA #$1f a9 1f ; initialize the victim running timer 0xba07: STA HETIM5 85 94 ; ; 0xba09: LDA #$a6 a9 a6 ; initialize for single player 0xba0b: STA WHICH 85 eb ; ; 0xba0d: JSR S_ba1a 20 1a ba ; position everything 0xba10: LDA LOGO a5 99 ; check to see if logo or not 0xba12: BEQ L_ba17 f0 03 ; yes logo: do nothing 0xba14: JSR S_ba41 20 41 ba ; no logo: torch building ; 0xba17: L_ba17 JMP L_bdc5 4c c5 bd ; go to beginning of draw cycle ; ; (avoid excessive cycles in doing ; ; exterior driver) ; 0xba1a: S_ba1a STA $02 85 02 ; positioning routine for flames in 0xba1c: LDX #$08 a2 08 ; the building and the helicopter, 0xba1e: L_ba1e DEX ca ; must be called continuously while 0xba1f: BNE L_ba1e d0 fd ; the logo is being displayed and 0xba21: STA $10 85 10 ; once after it disappears (or once 0xba23: STA $11 85 11 ; if logo never there) 0xba25: LDA #$70 a9 70 ; 0xba27: STA $20 85 20 ; 0xba29: LDA #$30 a9 30 ; 0xba2b: STA $21 85 21 ; 0xba2d: RTS 60 ; ; 0xba2e: D_ba2e DB $00,$04,$07,$0b ; data for for level of flames 0xba32: DB $0e,$12,$15,$19 ; on the exterior of the 0xba36: DB $1c,$20 ; building ; 0xba38: S_ba38 LDA DANGER a5 ae ; grab the level of player who has 0xba3a: CMP DANGEE c5 af ; made most progress 0xba3c: BPL L_ba40 10 02 ; 0xba3e: LDA DANGEE a5 af ; 0xba40: L_ba40 RTS 60 ; ; 0xba41: S_ba41 JSR S_ba38 20 38 ba ; 0xba44: STA DUMMY 85 97 ; get the building number 0xba46: LSR A 4a ; 0xba47: LSR A 4a ; 0xba48: LSR A 4a ; 0xba49: LSR A 4a ; 0xba4a: TAY a8 ; 0xba4b: DEY 88 ; subtract one since building one is ; ; "1" and not "0" 0xba4c: LDA D_b110,Y b9 10 b1 ; grab and load the right color for 0xba4f: STA TYPE 85 ab ; the building 0xba51: LDA DUMMY a5 97 ; grab floor level of highest player 0xba53: AND #$0f 29 0f ; 0xba55: TAY a8 ; 0xba56: LDA D_ba2e,Y b9 2e ba ; grab the cutoff value 0xba59: STA DUMMY 85 97 ; 0xba5b: LDX #$00 a2 00 ; 0xba5d: L_ba5d CPX DUMMY e4 97 ; if less than cutoff, no flames 0xba5f: BMI L_ba77 30 16 ; 0xba61: TXA 8a ; 0xba62: LSR A 4a ; 0xba63: BCS L_ba69 b0 04 ; 0xba65: LDA #$08 a9 08 ; if equal or more than cutoff, force ; ; flames 0xba67: BNE L_ba79 d0 10 ; (acts like "jmp") 0xba69: L_ba69 LSR A 4a ; if odd, then if next bit clear use 0xba6a: BCS L_ba71 b0 05 ; RAND1 else pump the random 0xba6c: LDA RAND1 a5 ed ; generator (done to minimize calls 0xba6e: JMP L_ba79 4c 79 ba ; to random generator) 0xba71: L_ba71 JSR S_b1ad 20 ad b1 ; 0xba74: JMP L_ba79 4c 79 ba ; 0xba77: L_ba77 AND #$f7 29 f7 ; 0xba79: L_ba79 STA $bb,X 95 bb ; store in floyd memory 0xba7b: INX e8 ; 0xba7c: CPX #$20 e0 20 ; 0xba7e: BNE L_ba5d d0 dd ; 0xba80: LDA #$00 a9 00 ; load "over the building" with no 0xba82: TAX aa ; flames 0xba83: L_ba83 STA $db,X 95 db ; 0xba85: INX e8 ; 0xba86: CPX #$05 e0 05 ; 0xba88: STA $bc 85 bc ; make sure the bottom floor is clear 0xba8a: BNE L_ba83 d0 f7 ; because have to display victims 0xba8c: RTS 60 ; there (note: the STA should be ; ; after the BNE, it seems to have ; ; been okay to keep) ; 0xba8d: S_ba8d LDY MEMORY a4 96 ; rotate the blades of the helicopter 0xba8f: LDA D_bace,Y b9 ce ba ; 0xba92: STA $a0 85 a0 ; 0xba94: LDA D_bad6,Y b9 d6 ba ; 0xba97: STA $a1 85 a1 ; 0xba99: LDA D_bade,Y b9 de ba ; 0xba9c: STA $a2 85 a2 ; 0xba9e: CPY #$07 c0 07 ; 0xbaa0: BEQ L_baaa f0 08 ; 0xbaa2: CPY #$01 c0 01 ; 0xbaa4: BEQ L_bab3 f0 0d ; 0xbaa6: LDA DIR a5 95 ; 0xbaa8: BEQ L_bab3 f0 09 ; 0xbaaa: L_baaa LDA #$01 a9 01 ; 0xbaac: STA DIR 85 95 ; 0xbaae: DEC MEMORY c6 96 ; 0xbab0: JMP L_bab9 4c b9 ba ; 0xbab3: L_bab3 LDA #$00 a9 00 ; 0xbab5: STA DIR 85 95 ; 0xbab7: INC MEMORY e6 96 ; 0xbab9: L_bab9 LDA #$08 a9 08 ; 0xbabb: STA $a3 85 a3 ; 0xbabd: LDA #$f3 a9 f3 ; 0xbabf: STA $a4 85 a4 ; 0xbac1: LDA #$3f a9 3f ; 0xbac3: STA $a5 85 a5 ; 0xbac5: LDA #$0e a9 0e ; 0xbac7: STA $a6 85 a6 ; 0xbac9: LDA #$00 a9 00 ; 0xbacb: STA $a7 85 a7 ; 0xbacd: RTS 60 ; ; 0xbace: D_bace DB $00,$07,$03,$01 ; data set #1 for blades 0xbad2: DB $00,$40,$60,$70 ; 0xbad6: D_bad6 DB $00,$08,$1c,$3f ; data set #2 for blades 0xbada: DB $7f,$3e,$1c,$08 ; 0xbade: D_bade DB $00,$78,$68,$48 ; data set #3 for blades 0xbae2: DB $08,$09,$0b,$0f ; ; 0xbae6: S_bae6 LDY #$00 a0 00 ; flicker the flames on the building 0xbae8: STY $b1 84 b1 ; (same as on the inside, but much 0xbaea: LDY #$60 a0 60 ; smaller flames) 0xbaec: STY $b2 84 b2 ; 0xbaee: LDY #$f0 a0 f0 ; 0xbaf0: STY $b3 84 b3 ; 0xbaf2: JSR S_b1ad 20 ad b1 ; 0xbaf5: AND #$0f 29 0f ; 0xbaf7: TAX aa ; 0xbaf8: LDY D_b19d,X bc 9d b1 ; 0xbafb: AND #$0c 29 0c ; 0xbafd: TAX aa ; 0xbafe: LDA D_b19d,X bd 9d b1 ; 0xbb01: AND #$f0 29 f0 ; 0xbb03: STA $b4 85 b4 ; 0xbb05: TYA 98 ; 0xbb06: AND #$f0 29 f0 ; 0xbb08: STA $b5 85 b5 ; 0xbb0a: RTS 60 ; ; ; ; launch the helicopter 0xbb0b: S_bb0b LDA HETIM1 a5 90 ; timer for how long helicopter sits 0xbb0d: CMP #$20 c9 20 ; on the top of the building before 0xbb0f: BEQ L_bb1e f0 0d ; going with appropriate sounds and 0xbb11: LDA #$1f a9 1f ; volume 0xbb13: STA $16 85 16 ; 0xbb15: STA $18 85 18 ; 0xbb17: LDA #$0a a9 0a ; 0xbb19: STA $1a 85 1a ; 0xbb1b: INC HETIM1 e6 90 ; 0xbb1d: RTS 60 ; ; 0xbb1e: L_bb1e LDA #$1a a9 1a ; section for helicopter to arc up 0xbb20: STA $18 85 18 ; and away from the building, first 0xbb22: LDA #$0f a9 0f ; increase the volume and pitch 0xbb24: STA $1a 85 1a ; 0xbb26: LDA HETIM2 a5 91 ; timer for this operation 0xbb28: CMP #$32 c9 32 ; 0xbb2a: BEQ L_bb40 f0 14 ; 0xbb2c: TAX aa ; 0xbb2d: INC HETIM2 e6 91 ; 0xbb2f: LDA D_bb98,X bd 98 bb ; grab the move out of the data table 0xbb32: STA $21 85 21 ; upper nibble is for horizontal 0xbb34: LSR A 4a ; shift 0xbb35: BCC L_bb97 90 60 ; if bit #0 clear, then no vertical ; ; motion 0xbb37: LSR A 4a ; bit #0 not clear 0xbb38: BCC L_bb3d 90 03 ; if bit #1 clear, move helicopter up 0xbb3a: DEC RIGVER c6 81 ; if bit #1 set, move helicopter down 0xbb3c: RTS 60 ; 0xbb3d: L_bb3d INC RIGVER e6 81 ; 0xbb3f: RTS 60 ; 0xbb40: L_bb40 LDA HETIM3 a5 92 ; timer for the helicopter to drop to 0xbb42: CMP #$81 c9 81 ; the ground after the arc 0xbb44: BEQ L_bb4b f0 05 ; 0xbb46: INC HETIM3 e6 92 ; 0xbb48: DEC RIGVER c6 81 ; 0xbb4a: RTS 60 ; 0xbb4b: L_bb4b LDA #$1f a9 1f ; lower the pitch and volume once 0xbb4d: STA $18 85 18 ; landed and see if there are any 0xbb4f: LDA #$08 a9 08 ; victims (any victims left) to 0xbb51: STA $1a 85 1a ; unload (if so, go to L_bb5b) 0xbb53: LDA VICONE a5 a9 ; 0xbb55: BNE L_bb5b d0 04 ; 0xbb57: LDA VICTWO a5 aa ; 0xbb59: BEQ L_bb5f f0 04 ; 0xbb5b: L_bb5b JSR S_bbe3 20 e3 bb ; 0xbb5e: RTS 60 ; 0xbb5f: L_bb5f LDA HETIM5 a5 94 ; if last victim running out, go 0xbb61: CMP #$1f c9 1f ; through motions one last time 0xbb63: BEQ L_bb69 f0 04 ; 0xbb65: JSR S_bbe9 20 e9 bb ; 0xbb68: RTS 60 ; 0xbb69: L_bb69 JSR X_bc37 20 37 bc ; make the victim "no show display" 0xbb6c: LDA HETIM4 a5 93 ; timer to see how long it should sit 0xbb6e: CMP #$60 c9 60 ; on ground before going back to 0xbb70: BNE L_bb95 d0 23 ; building 0xbb72: LDA DANGER a5 ae ; if either player has made it 0xbb74: AND #$0f 29 0f ; through the ninth floor, give the 0xbb76: CMP #$09 c9 09 ; "winner" graphic 0xbb78: BEQ L_bb82 f0 08 ; 0xbb7a: LDA DANGEE a5 af ; 0xbb7c: AND #$0f 29 0f ; 0xbb7e: CMP #$09 c9 09 ; 0xbb80: BNE L_bb85 d0 03 ; 0xbb82: L_bb82 INC WINNER e6 ad ; "winner graphic" 0xbb84: RTS 60 ; 0xbb85: L_bb85 LDX #$a6 a2 a6 ; ready to enter building when get 0xbb87: STX WHICH 86 eb ; into exterior driver, set to 1st ; ; player 0xbb89: LDA #$00 a9 00 ; load his score into display dummies 0xbb8b: STA DUMMY 85 97 ; 0xbb8d: JSR S_b2ad 20 ad b2 ; 0xbb90: LDA #$01 a9 01 ; let program know to return to 0xbb92: STA RETURN 85 f1 ; interior 0xbb94: RTS 60 ; 0xbb95: L_bb95 INC HETIM4 e6 93 ; 0xbb97: L_bb97 RTS 60 ; ; 0xbb98: D_bb98 DB $01,$01,$01,$01,$01 ; data for helicopter arc 0xbb9d: DB $f0,$f0,$f0,$f0,$f0 ; 0xbba2: DB $f0,$f0,$f0,$f0,$f0 ; 0xbba7: DB $f0,$f0,$f0,$f0,$f0 ; 0xbbac: DB $f0,$f0,$f0,$f0,$f0 ; 0xbbb1: DB $f3,$f3,$f3,$f3,$f3 ; 0xbbb6: DB $f3,$f3,$f3,$f3,$f3 ; 0xbbbb: DB $f3,$f3,$f3,$f3,$f3 ; 0xbbc0: DB $f3,$f3,$f3,$f3,$f3 ; 0xbbc5: DB $f3,$f3,$f3,$f3,$f3 ; ; 0xbbca: S_bbca LDY #$01 a0 01 ; subroutine to load $E1 to $E9 with 0xbbcc: L_bbcc LDA SCODS1 a5 8c ; necessary low resolution masks 0xbbce: STA DUMMY 85 97 ; to force an extra digit into the 0xbbd0: TYA 98 ; scoring display 0xbbd1: CLC 18 ; 0xbbd2: ADC DUMMY 65 97 ; 0xbbd4: TAX aa ; 0xbbd5: LDA D_b49c,X bd 9c b4 ; 0xbbd8: AND #$f0 29 f0 ; 0xbbda: STA $e0,Y 99 e0 00 ; I would have expected this line to ; ; be "STA SOUDUM,Y" as $e0 is an ; ; EQU to SOUDUM, but my master ; ; indicates STA $e0,Y 0xbbdd: INY c8 ; 0xbbde: CPY #$0a c0 0a ; 0xbbe0: BNE L_bbcc d0 ea ; 0xbbe2: RTS 60 ; ; 0xbbe3: S_bbe3 LDA HETIM5 a5 94 ; this subroutine unloads a victim 0xbbe5: CMP #$1f c9 1f ; from helicopter based on timer 0xbbe7: BEQ L_bc06 f0 1d ; (unfortunately, have no memory of ; ; how most of this algorithm works) 0xbbe9: S_bbe9 STA $17 85 17 ; set the sound depending on which 0xbbeb: TAY a8 ; player is scoring 0xbbec: LDA SWITCH a5 80 ; 0xbbee: BPL L_bbf8 10 08 ; 0xbbf0: LDA XMEN a5 f3 ; 0xbbf2: BEQ L_bbf8 f0 04 ; 0xbbf4: TYA 98 ; 0xbbf5: EOR #$ff 49 ff ; 0xbbf7: TAY a8 ; 0xbbf8: L_bbf8 TYA 98 ; 0xbbf9: STA $15 85 15 ; 0xbbfb: INC HETIM5 e6 94 ; 0xbbfd: LDA #$f0 a9 f0 ; increment horizontal position of 0xbbff: STA $24 85 24 ; the victim 0xbc01: LDA #$0f a9 0f ; 0xbc03: STA $19 85 19 ; 0xbc05: RTS 60 ; 0xbc06: L_bc06 LDA #$00 a9 00 ; 0xbc08: STA HETIM5 85 94 ; 0xbc0a: JSR S_bc40 20 40 bc ; position victim in starting place 0xbc0d: LDX #$00 a2 00 ; 0xbc0f: L_bc0f STX XMEN 86 f3 ; 0xbc11: LDA VICONE,X b5 a9 ; are there any more victims left to 0xbc13: BEQ L_bc2f f0 1a ; unload 0xbc15: LDA #$25 a9 25 ; 0xbc17: STA DUMMY 85 97 ; 0xbc19: LDA WHICH a5 eb ; switch everything around and save 0xbc1b: STA WHIMEN 85 f2 ; (orig documentation has "???" 0xbc1d: STX WHICH 86 eb ; on this statement) 0xbc1f: JSR S_b299 20 99 b2 ; score 25 points 0xbc22: LDA WHIMEN a5 f2 ; 0xbc24: STA WHICH 85 eb ; 0xbc26: LDA #$51 a9 51 ; activate the visual of the victim 0xbc28: STA VICTIE 85 f4 ; 0xbc2a: LDX XMEN a6 f3 ; 0xbc2c: DEC VICONE,X d6 a9 ; since that victim has been scored, 0xbc2e: RTS 60 ; decrement number left to score 0xbc2f: L_bc2f CPX #$01 e0 01 ; ??? (I think this sees if all but 0xbc31: BEQ X_bc37 f0 04 ; last victim is out as S_bb0b 0xbc33: INX e8 ; handles the last) ??? 0xbc34: JMP L_bc0f 4c 0f bc ; ; 0xbc37: X_bc37 LDA #$10 a9 10 ; don't show a victim 0xbc39: STA VICTIE 85 f4 ; 0xbc3b: LDA #$00 a9 00 ; 0xbc3d: STA $19 85 19 ; 0xbc3f: RTS 60 ; ; 0xbc40: S_bc40 STA $02 85 02 ; position the victim at a known 0xbc42: LDX #$0c a2 0c ; starting point 0xbc44: L_bc44 DEX ca ; 0xbc45: BNE L_bc44 d0 fd ; 0xbc47: STA $14 85 14 ; 0xbc49: LDA #$40 a9 40 ; 0xbc4b: STA $24 85 24 ; 0xbc4d: RTS 60 ; ; 0xbc4e: S_bc4e LDY #$ff a0 ff ; read the game reset switch 0xbc50: LDA $0282 ad 82 02 ; but first, check color/B&W switch 0xbc53: AND #$08 29 08 ; 0xbc55: BNE L_bc59 d0 02 ; 0xbc57: LDY #$0f a0 0f ; 0xbc59: L_bc59 STY CHROMA 84 9b ; 0xbc5b: LDA $0282 ad 82 02 ; now look at the switch 0xbc5e: LSR A 4a ; 0xbc5f: BCS L_bcb4 b0 53 ; not depressed, exit 0xbc61: LDA #$00 a9 00 ; clear special effect 0xbc63: STA EMPTY 85 f6 ; 0xbc65: LDA RESET a5 98 ; if there hasn't been release since 0xbc67: BNE L_bcb8 d0 4f ; last depression of switch, don't ; ; read 0xbc69: L_bc69 LDA #$01 a9 01 ; set flag to indicate that a 0xbc6b: STA RESET 85 98 ; depression of switch has occurred 0xbc6d: LDA LOGO a5 99 ; look to see where it should be 0xbc6f: EOR #$01 49 01 ; 0xbc71: BNE L_bc78 d0 05 ; 0xbc73: PLA 68 ; 0xbc74: PLA 68 ; 0xbc75: JMP L_b019 4c 19 b0 ; new game, clear all and go to ; ; static exterior (through front of ; ; interior like its a cold boot) 0xbc78: L_bc78 STA LOGO 85 99 ; if logo is on, then time to start a 0xbc7a: JSR S_ba41 20 41 ba ; game, so ignite the building 0xbc7d: LDA SWITCH a5 80 ; look at how many players and set 0xbc7f: AND #$7f 29 7f ; bit #7 if two player 0xbc81: CMP #$04 c9 04 ; 0xbc83: BPL L_bc87 10 02 ; 0xbc85: BNE L_bc89 d0 02 ; 0xbc87: L_bc87 ORA #$80 09 80 ; 0xbc89: L_bc89 STA SWITCH 85 80 ; 0xbc8b: JSR S_ba1a 20 1a ba ; position the helicopter and flames 0xbc8e: LDA #$a6 a9 a6 ; one last time and then set player 0xbc90: STA WHICH 85 eb ; for first 0xbc92: LDA SWITCH a5 80 ; if game #2 or #4, don't clear score 0xbc94: CMP #$02 c9 02 ; (game #2 because its to continue 0xbc96: BEQ L_bcaf f0 17 ; and game #4 to make sure lockup 0xbc98: CMP #$04 c9 04 ; doesn't kill locked score (this 0xbc9a: BEQ L_bcaf f0 13 ; bit may not be necessary, but 0xbc9c: LDA #$00 a9 00 ; until told otherwise, let's 0xbc9e: STA ONELOW 85 84 ; assume its okay?) assuming other 0xbca0: STA TWOLOW 85 85 ; game, clear score, score display 0xbca2: STA ONEHIG 85 86 ; for both players, etc. 0xbca4: STA TWOHIG 85 87 ; 0xbca6: LDX #$00 a2 00 ; 0xbca8: JSR S_b2ad 20 ad b2 ; 0xbcab: INX e8 ; 0xbcac: JSR S_b2ad 20 ad b2 ; 0xbcaf: L_bcaf PLA 68 ; 0xbcb0: PLA 68 ; 0xbcb1: JMP L_bdc5 4c c5 bd ; go to draw sequence to land ; ; helicopter 0xbcb4: L_bcb4 LDA #$00 a9 00 ; indicate that the switch has been 0xbcb6: STA RESET 85 98 ; released after being depressed 0xbcb8: L_bcb8 RTS 60 ; ; 0xbcb9: S_bcb9 LDA $0282 ad 82 02 ; read the game select switch 0xbcbc: AND #$02 29 02 ; 0xbcbe: BNE L_bcef d0 2f ; 0xbcc0: LDA RESETA a5 9a ; make sure that the switch has been 0xbcc2: BNE L_bcf8 d0 34 ; released since last depression 0xbcc4: LDA #$01 a9 01 ; (unless into rapid fire) 0xbcc6: STA RESETA 85 9a ; indicate switch has been depressed ; 0xbcc8: L_bcc8 LDA SWITCH a5 80 ; if currently on game #7, loop back 0xbcca: AND #$7f 29 7f ; to #1 0xbccc: CMP #$07 c9 07 ; 0xbcce: BNE L_bcd5 d0 05 ; 0xbcd0: LDA #$01 a9 01 ; 0xbcd2: STA SWITCH 85 80 ; 0xbcd4: RTS 60 ; 0xbcd5: L_bcd5 INC SWITCH e6 80 ; increment game number 0xbcd7: LDX #$00 a2 00 ; since game select has been pushed, 0xbcd9: STX ONELOW 86 84 ; kill all previous info from the 0xbcdb: STX ONEHIG 86 86 ; score, levels, etc. 0xbcdd: STX TWOLOW 86 85 ; 0xbcdf: STX TWOHIG 86 87 ; 0xbce1: LDY #$10 a0 10 ; 0xbce3: STY DANGER 84 ae ; 0xbce5: STY DANGEE 84 af ; 0xbce7: JSR S_b2ad 20 ad b2 ; 0xbcea: INX e8 ; 0xbceb: JSR S_b2ad 20 ad b2 ; 0xbcee: RTS 60 ; 0xbcef: L_bcef LDA #$00 a9 00 ; indicate that the switch has been 0xbcf1: STA RESETA 85 9a ; released 0xbcf3: LDA #$40 a9 40 ; reset rapid counter 0xbcf5: STA RAPID 85 f5 ; 0xbcf7: L_bcf7 RTS 60 ; 0xbcf8: L_bcf8 INC RAPID e6 f5 ; if rapid has reached a certain 0xbcfa: LDA RAPID a5 f5 ; point then begin moving through 0xbcfc: BPL L_bcf7 10 f9 ; numbers very quickly 0xbcfe: AND #$08 29 08 ; 0xbd00: BEQ L_bcf7 f0 f5 ; 0xbd02: LDA #$80 a9 80 ; 0xbd04: STA RAPID 85 f5 ; 0xbd06: BNE L_bcc8 d0 c0 ; (acts like "jmp") ; 0xbd08: S_bd08 JSR S_b052 20 52 b0 ; which player is about ready to go 0xbd0b: LDA DANGER,X b5 ae ; figure out what the speed of 0xbd0d: TAY a8 ; victim's death should be for the 0xbd0e: LSR A 4a ; floor by adding building number 0xbd0f: LSR A 4a ; (minus one since building's count 0xbd10: LSR A 4a ; starts at "1", not "0") to floor 0xbd11: LSR A 4a ; currently on and accessing the 0xbd12: STA DUMMY 85 97 ; data table 0xbd14: TYA 98 ; 0xbd15: AND #$0f 29 0f ; 0xbd17: CLC 18 ; 0xbd18: ADC DUMMY 65 97 ; 0xbd1a: TAY a8 ; 0xbd1b: DEY 88 ; 0xbd1c: LDA D_bd22,Y b9 22 bd ; 0xbd1f: STA TIMER 85 ac ; 0xbd21: RTS 60 ; ; 0xbd22: D_bd22 DB $14,$12,$10,$0e ; data table for the first 0xbd26: DB $0c,$0b,$0a,$09 ; building 0xbd2a: DB $07,$06 ; ; 0xbd2c: DB $05,$04,$04,$03 ; data table to be used in 0xbd30: DB $03,$03,$03,$03 ; successive buildings (no 0xbd34: DB $03 ; D_label necessary) -- do ; ; not know why this looks ; ; one byte short, I think it ; ; "borrow" 0xbd35's "a5" ; ; ; ***** THE EXTERIOR DRIVER **** ; 0xbd35: L_bd35 LDA EMPTY a5 f6 ; if special graphic is up, don't 0xbd37: BMI L_bd6e 30 35 ; stop anything 0xbd39: LDA WINNER a5 ad ; look when to turn off "winner" and 0xbd3b: AND #$7f 29 7f ; put the player in the next 0xbd3d: CMP #$5f c9 5f ; building 0xbd3f: BNE L_bd6e d0 2d ; 0xbd41: LDX #$01 a2 01 ; fire helicopter off the top again 0xbd43: STX LOGO 86 99 ; 0xbd45: DEX ca ; 0xbd46: STX WINNER 86 ad ; clear "winner" graphic 0xbd48: L_bd48 LDA DANGER,X b5 ae ; 0xbd4a: STA DUMMY 85 97 ; redundant code to make sure that it 0xbd4c: AND #$0f 29 0f ; does nothing if not on ninth 0xbd4e: CMP #$09 c9 09 ; floor (this is for player who 0xbd50: BNE L_bd66 d0 14 ; didn't get "winner" since it ; ; checks both) 0xbd52: LDA DUMMY a5 97 ; go to next building, if on ninth 0xbd54: AND #$f0 29 f0 ; building, then go to first 0xbd56: CMP #$90 c9 90 ; building again 0xbd58: BEQ L_bd62 f0 08 ; 0xbd5a: CLC 18 ; 0xbd5b: ADC #$10 69 10 ; up a building 0xbd5d: L_bd5d STA DANGER,X 95 ae ; 0xbd5f: JMP L_bd66 4c 66 bd ; 0xbd62: L_bd62 LDA #$10 a9 10 ; restart first building 0xbd64: BNE L_bd5d d0 f7 ; (acts like "jmp") 0xbd66: L_bd66 INX e8 ; 0xbd67: CPX #$02 e0 02 ; do the other player 0xbd69: BNE L_bd48 d0 dd ; 0xbd6b: JMP L_b9e1 4c e1 b9 ; 0xbd6e: L_bd6e LDA RETURN a5 f1 ; bounce away unless time to return 0xbd70: BEQ L_bd86 f0 14 ; to interior 0xbd72: INC DANGER e6 ae ; increase both player's floor 0xbd74: INC DANGEE e6 af ; (remember that a failed player 0xbd76: LDA SWITCH a5 80 ; was previously decreased or ; ; zeroed) 0xbd78: CMP #$87 c9 87 ; if game #7, put both players on the 0xbd7a: BNE L_bd83 d0 07 ; same floor based on which is 0xbd7c: JSR S_ba38 20 38 ba ; higher up the building (remember 0xbd7f: STA DANGER 85 ae ; this is cooperation game, if 0xbd81: STA DANGEE 85 af ; either makes it then both ; ; advance) 0xbd83: L_bd83 JMP L_b058 4c 58 b0 ; back inside 0xbd86: L_bd86 JSR S_bc4e 20 4e bc ; check the game reset switch 0xbd89: LDA LOGO a5 99 ; bounce away unless trying to freeze 0xbd8b: BNE L_bdb3 d0 26 ; with logo 0xbd8d: JSR S_ba8d 20 8d ba ; helicopter draw 0xbd90: LDA #$04 a9 04 ; freeze the blade 0xbd92: STA MEMORY 85 96 ; 0xbd94: LDA #$00 a9 00 ; kill all sound 0xbd96: STA $1a 85 1a ; 0xbd98: LDA SWITCH a5 80 ; if two players, then multiplex for 0xbd9a: AND #$7f 29 7f ; two scores else just first player 0xbd9c: CMP #$04 c9 04 ; 0xbd9e: BPL L_bda4 10 04 ; 0xbda0: LDA #$a6 a9 a6 ; 0xbda2: BNE L_bda8 d0 04 ; (acts like "jmp") 0xbda4: L_bda4 LDA WHICH a5 eb ; 0xbda6: EOR #$ff 49 ff ; 0xbda8: L_bda8 STA WHICH 85 eb ; 0xbdaa: JSR S_ba1a 20 1a ba ; position helicopter and future ; ; flames 0xbdad: JSR S_bcb9 20 b9 bc ; read the game select 0xbdb0: JMP L_bdbc 4c bc bd ; avoid/bypass 0xbdb3: L_bdb3 JSR S_bb0b 20 0b bb ; fly the helicopter 0xbdb6: JSR S_ba8d 20 8d ba ; draw and rotate the helicopter and ; ; blades 0xbdb9: JSR S_bae6 20 e6 ba ; keep the flames flickering 0xbdbc: L_bdbc JSR S_b052 20 52 b0 ; put appropriate score in display 0xbdbf: JSR S_b2ad 20 ad b2 ; (based on multiplex needs) 0xbdc2: JSR S_bbca 20 ca bb ; get that magic fourth digit ; ; 0xbdc5: L_bdc5 LDA EMPTY a5 f6 ; if special already up and going, no 0xbdc7: BMI L_bddc 30 13 ; need to check for putting it up 0xbdc9: LDA WINNER a5 ad ; if not already up, see if all 0xbdcb: BEQ L_bde0 f0 13 ; conditions are met, set flag 0xbdcd: LDA $0282 ad 82 02 ; else leave default 0xbdd0: AND #$0a 29 0a ; 0xbdd2: BNE L_bde0 d0 0c ; 0xbdd4: LDA $3c a5 3c ; 0xbdd6: BMI L_bde0 30 08 ; 0xbdd8: LDA $3d a5 3d ; 0xbdda: BMI L_bde0 30 04 ; 0xbddc: L_bddc LDA #$ff a9 ff ; special 0xbdde: BNE L_bde2 d0 02 ; (acts like "jmp") 0xbde0: L_bde0 LDA #$00 a9 00 ; default 0xbde2: L_bde2 STA EMPTY 85 f6 ; 0xbde4: L_bde4 LDA $0284 ad 84 02 ; check time timer and wait for zero 0xbde7: BNE L_bde4 d0 fb ; 0xbde9: STA $02 85 02 ; wait until next horizontal line 0xbdeb: STA $2a 85 2a ; update all shifts 0xbded: STA $01 85 01 ; turn on electron gun 0xbdef: STA BCOLOR 85 09 ; set background to black 0xbdf1: STA $0d 85 0d ; clear all low resolution masks 0xbdf3: STA $0e 85 0e ; 0xbdf5: STA $0f 85 0f ; 0xbdf7: STA $05 85 05 ; set mag and multi for helicopter 0xbdf9: LDA #$02 a9 02 ; using $0A, put player's color on 0xbdfb: STA LOWSET 85 0a ; proper side (depending on the 0xbdfd: LDA WHICH a5 eb ; multiplex) and stuff back on the 0xbdff: LSR A 4a ; other side of low resolution 0xbe00: BCC L_be0e 90 0c ; color selection. This makes it 0xbe02: LDA #$00 a9 00 ; possible to use the same routine 0xbe04: STA RCOLOR 85 07 ; for both halves of the multiplex 0xbe06: LDA WHICH a5 eb ; 0xbe08: AND CHROMA 25 9b ; 0xbe0a: STA LCOLOR 85 06 ; 0xbe0c: BNE L_be18 d0 0a ; (acts like "jmp") 0xbe0e: L_be0e LDA #$00 a9 00 ; 0xbe10: STA LCOLOR 85 06 ; 0xbe12: LDA WHICH a5 eb ; 0xbe14: AND CHROMA 25 9b ; 0xbe16: STA RCOLOR 85 07 ; 0xbe18: L_be18 LDA #$00 a9 00 ; start out with null values 0xbe1a: STA DUMMY 85 97 ; 0xbe1c: LDY #$09 a0 09 ; number of lines to be draw 0xbe1e: L_be1e STA $02 85 02 ; wait until next horizontal line 0xbe20: STA $0e 85 0e ; load $0E 0xbe22: LDA DUMMY a5 97 ; 0xbe24: STA $0f 85 0f ; load $0F 0xbe26: TYA 98 ; method of doing this is identical 0xbe27: ORA SCODS4 05 8f ; as in score routine back in the 0xbe29: TAX aa ; interior of building except that 0xbe2a: LDA D_b536,X bd 36 b5 ; except that both sides are loaded 0xbe2d: AND #$f0 29 f0 ; with black for one of the display 0xbe2f: STA DUMMY 85 97 ; colors to mask and that DIGIT has 0xbe31: TYA 98 ; prepared $E0 and up to hold a set 0xbe32: ORA SCODS3 05 8e ; of masks necessary to allow a 0xbe34: TAX aa ; fourth digit to be gotten in 0xbe35: LDA D_b536,X bd 36 b5 ; 0xbe38: AND #$0f 29 0f ; 0xbe3a: ORA DUMMY 05 97 ; 0xbe3c: STA DUMMY 85 97 ; 0xbe3e: TYA 98 ; 0xbe3f: ORA SCODS2 05 8d ; 0xbe41: TAX aa ; 0xbe42: LDA D_b49c,X bd 9c b4 ; 0xbe45: AND #$0f 29 0f ; 0xbe47: ORA $e0,Y 19 e0 00 ; I would have expected this line to ; ; be "ORA SOUDUM,Y" as $e0 is an ; ; EQU to SOUDUM, but my master ; ; indicates ORA $e0,Y 0xbe4a: DEY 88 ; see if there are more lines to do 0xbe4b: BNE L_be1e d0 d1 ; and do again if there are 0xbe4d: STA $02 85 02 ; wait until next horizontal line 0xbe4f: STA $0e 85 0e ; clear low resolution masks (from 0xbe51: STA $0f 85 0f ; last data read) 0xbe53: LDA #$01 a9 01 ; reset $0A for one low res color 0xbe55: STA LOWSET 85 0a ; 0xbe57: LDA WINNER a5 ad ; put correct background in 0xbe59: AND CHROMA 25 9b ; 0xbe5b: STA BCOLOR 85 09 ; 0xbe5d: LDA TYPE a5 ab ; put proper building color in 0xbe5f: AND CHROMA 25 9b ; 0xbe61: STA ACOLOR 85 08 ; 0xbe63: LDA #$2d a9 2d ; all flames are this color 0xbe65: AND CHROMA 25 9b ; 0xbe67: STA LCOLOR 85 06 ; 0xbe69: AND #$f7 29 f7 ; the helicopter is this color 0xbe6b: STA RCOLOR 85 07 ; 0xbe6d: LDA RIGVER a5 81 ; helicopter vertical position in 0xbe6f: STA RCON 85 8b ; dummy counter 0xbe71: LDA VICTIE a5 f4 ; victim vertical position in dummy 0xbe73: STA LCON 85 8a ; counter 0xbe75: LDA #$03 a9 03 ; set flame multiplier 0xbe77: STA $04 85 04 ; 0xbe79: LDX #$25 a2 25 ; number of rows to building (plus ; ; one to allow instant jump to tail ; ; to get $0F mask) 0xbe7b: BNE L_bebb d0 3e ; (acts like "jmp") ; 0xbe7d: LDY #$04 a0 04 ; NOTE: this line is actaully a NOP ; ; as it never is executed (old ; ; code whose branch to got ; ; removed without the line ; ; being removed) ; 0xbe7f: L_be7f STA $02 85 02 ; wait until next horizontal line 0xbe81: L_be81 STY DUMMY 84 97 ; stash line counter 0xbe83: LDY RCON a4 8b ; should the helicopter be drawn? 0xbe85: CPY #$08 c0 08 ; 0xbe87: BCS L_be8e b0 05 ; 0xbe89: LDA $a0,Y b9 a0 00 ; this LDA $xx,Y is correct as ; ; location does not have an EQU 0xbe8c: STA $1c 85 1c ; stuff it 0xbe8e: L_be8e LDA $bb,X b5 bb ; are there flames in this row 0xbe90: AND #$08 29 08 ; 0xbe92: BEQ L_be9e f0 0a ; 0xbe94: LDY DUMMY a4 97 ; there are flames, using line ; ; counter 0xbe47: ; ; this LDA $xx,Y is correct as ; ; location does not have an EQU 0xbe96: LDA $b1,Y b9 b1 00 ; the right mask can be indexed 0xbe99: STA $1b 85 1b ; stuff it 0xbe9b: JMP L_beac 4c ac be ; 0xbe9e: L_be9e LDA #$00 a9 00 ; no flames, can check for victims 0xbea0: LDY LCON a4 8a ; (assume none) 0xbea2: CPY #$03 c0 03 ; 0xbea4: BCS L_bea8 b0 02 ; 0xbea6: LDA #$02 a9 02 ; yes flames 0xbea8: L_bea8 STA $1f 85 1f ; stuff it 0xbeaa: LDY DUMMY a4 97 ; restore line counter 0xbeac: L_beac INC LCON e6 8a ; increment victim counter 0xbeae: INC RCON e6 8b ; increment helicopter counter 0xbeb0: DEY 88 ; decrement line counter 0xbeb1: BMI L_bebb 30 08 ; go for next row 0xbeb3: BNE L_be7f d0 ca ; do another 0xbeb5: STA $02 85 02 ; last line, wait until next hor line 0xbeb7: STY $0f 84 0f ; clear $0F 0xbeb9: BEQ L_be81 f0 c6 ; (acts like "jmp") force back into ; ; draw 0xbebb: L_bebb LDA EMPTY a5 f6 ; ready for next row, determine what 0xbebd: BEQ L_bec5 f0 06 ; $0F mask is to be displayed 0xbebf: LDA D_bfb1,X bd b1 bf ; special 0xbec2: JMP L_bec8 4c c8 be ; 0xbec5: L_bec5 LDA D_bfd6,X bd d6 bf ; building 0xbec8: L_bec8 STA $0f 85 0f ; stuff it 0xbeca: LDY #$04 a0 04 ; new set of lines per row 0xbecc: DEX ca ; decrement row counter 0xbecd: BNE L_be81 d0 b2 ; do again unless out of rows ; 0xbecf: STA $2b 85 2b ; clear all shift registers 0xbed1: STA $02 85 02 ; wait until next horizontal line 0xbed3: LDA #$08 a9 08 ; load "sidewalk" color 0xbed5: STA ACOLOR 85 08 ; 0xbed7: LDA #$ff a9 ff ; load "sidewalk" into low resolution 0xbed9: STA $0d 85 0d ; masks 0xbedb: STA $0e 85 0e ; 0xbedd: STA $0f 85 0f ; 0xbedf: BIT $80 24 80 ; timing (not needed) 0xbee1: STX $1c 86 1c ; clear high resolution masks 0xbee3: STX $1b 86 1b ; 0xbee5: LDA #$1a a9 1a ; get up logo color 0xbee7: AND CHROMA 25 9b ; 0xbee9: STA LCOLOR 85 06 ; 0xbeeb: STA RCOLOR 85 07 ; 0xbeed: LDA #$01 a9 01 ; set high resolution magnification 0xbeef: STA $04 85 04 ; and multiplication masks 0xbef1: LDA #$00 a9 00 ; 0xbef3: STA $05 85 05 ; 0xbef5: STA $02 85 02 ; wait until next horizontal line 0xbef7: STX $0d 86 0d ; clear all the low resolution masks 0xbef9: STX $0e 86 0e ; 0xbefb: STX $0f 86 0f ; 0xbefd: LDX #$0f a2 0f ; set for 16 lines of logo 0xbeff: LDA LOGO a5 99 ; look to see whether there is a logo 0xbf01: BEQ L_bf0b f0 08 ; to draw or not ; 0xbf03: L_bf03 STA $02 85 02 ; do not draw logo, therefore just 0xbf05: DEX ca ; skip through 16 lines to ; ; compensate and clear out ; ; THIS HAD TO BE CHANGED AS A RESULT OF "0xb0a6: BCC L_b0a9" CHANGE, ; WAS ORIGINALLY "bne" AND WAS CHANGED (?BY WHO?) TO MATCH THE LOGO ; SECTION ; 0xbf06: BPL L_bf03 10 fb ; ; 0xbf08: JMP L_bf7c 4c 7c bf ; ; 0xbf0b: L_bf0b LDA #$10 a9 10 ; draw logo, so set shift increments 0xbf0d: STA $21 85 21 ; 0xbf0f: NOP ea ; timing 0xbf10: STA $10 85 10 ; absolute position the two high res 0xbf12: STA $11 85 11 ; objects 0xbf14: LDA SWITCH a5 80 ; grab game number in upper nibble 0xbf16: ASL A 0a ; to be able to index mask inside 0xbf17: ASL A 0a ; routine 0xbf18: ASL A 0a ; 0xbf19: ASL A 0a ; 0xbf1a: STA DUMMY 85 97 ; 0xbf1c: LDA #$00 a9 00 ; make sure $0F is cleared right off 0xbf1e: L_bf1e STA $0f 85 0f ; the bat -- left side of screen 0xbf20: STA $02 85 02 ; wait until next horizontal line 0xbf22: STA $2a 85 2a ; update the shifts (works first time ; ; only 0xbf24: LDA D_bf4e,X bd 4e bf ; load and stuff the first two parts 0xbf27: STA $1b 85 1b ; of the logo 0xbf29: LDA D_bf5d,X bd 5d bf ; 0xbf2c: STA $1c 85 1c ; 0xbf2e: TXA 8a ; while there is time to kill, begin 0xbf2f: SBC #$05 e9 05 ; preparing the game number index 0xbf31: AND #$0f 29 0f ; for display (same way as scoring 0xbf33: ORA DUMMY 05 97 ; routine) 0xbf35: LDY D_bf6c,X bc 6c bf ; quickly dump out old info and put 0xbf38: STY $1b 84 1b ; third part of logo in 0xbf3a: STA $2b 85 2b ; clear out shifts (makes sure it 0xbf3c: TAY a8 ; only does it once) and continue 0xbf3d: LDA D_b49c,Y b9 9c b4 ; with game number 0xbf40: AND #$0f 29 0f ; 0xbf42: STA $0f 85 0f ; stuff game number (right side) 0xbf44: LDA #$00 a9 00 ; get ready to kill $0F when begin 0xbf46: DEX ca ; new line 0xbf47: BPL L_bf1e 10 d5 ; see if there is another line to do 0xbf49: STA $0f 85 0f ; if not, first kill $0F 0xbf4b: JMP L_bf7c 4c 7c bf ; bypass data tables ; 0xbf4e: D_bf4e DB $00,$00,$05,$0a ; data tables for logo 0xbf52: DB $ea,$28,$4e,$80 ; 0xbf56: DB $e7,$08,$eb,$aa ; 0xbf5a: DB $ab,$a8,$a7 ; (uses 0xbf5d for 16th byte) ; 0xbf5d: D_bf5d DB $00,$00,$a8,$a8 ; data tables for logo 0xbf61: DB $ea,$aa,$ef,$00 ; 0xbf65: DB $91,$51,$51,$57 ; 0xbf69: DB $55,$55,$97 ; (uses 0xbf6c for 16th byte) ; 0xbf6c: D_bf6c DB $00,$00,$b7,$a1 ; data tables for logo 0xbf70: DB $b2,$a4,$b7,$00 ; 0xbf74: DB $77,$54,$54,$72 ; 0xbf78: DB $51,$55,$72,$00 ; ; 0xbf7c: L_bf7c LDX #$0d a2 0d ; pad with extra lines to maintain 0xbf7e: JSR X_b836 20 36 b8 ; game sync/timing ; 0xbf81: LDA #$02 a9 02 ; 0xbf83: STA $02 85 02 ; wait until next horizontal line 0xbf85: STA $01 85 01 ; turn off electron beam 0xbf87: STA $00 85 00 ; scan from bottom to top 0xbf89: LDA #$2a a9 2a ; set off the damn timer 0xbf8b: STA $0295 8d 95 02 ; ; 0xbf8e: LDA LOGO a5 99 ; if in logo mode, bypass 0xbf90: BEQ L_bfa0 f0 0e ; 0xbf92: LDA SWITCH a5 80 ; if not in logo mode, but one 0xbf94: BPL L_bfa0 10 0a ; player, bypass 0xbf96: LDA RETURN a5 f1 ; if not in return mode, bypass 0xbf98: BNE L_bfa0 d0 06 ; 0xbf9a: LDA WHICH a5 eb ; flip player flag (used as 0xbf9c: EOR #$ff 49 ff ; multiplexer) 0xbf9e: STA WHICH 85 eb ; ; 0xbfa0: L_bfa0 LDA $0284 ad 84 02 ; check timer for zero 0xbfa3: BNE L_bfa0 d0 fb ; 0xbfa5: STA $02 85 02 ; wait until next horizontal line 0xbfa7: STA $00 85 00 ; scan from top to bottom ; ; ***** THERE IS NOTE IN CODE THAT THIS WAS ANOTHER PART OF THE BAD ; TIMING BUG AS IT WAS ORIGINALLY #$24 AND CHANGED TO #$29 ***** 0xbfa9: LDA #$29 a9 29 ; 0xbfab: STA $0296 8d 96 02 ; set off the next timer 0xbfae: JMP L_bd35 4c 35 bd ; go back to the driver ; 0xbfb1: D_bfb1 DB $00 ; data for the special display 0xbfb2: DB $00,$f8,$00,$48 ; 0xbfb6: DB $48,$58,$58,$68 ; 0xbfba: DB $68,$48,$48,$00 ; 0xbfbe: DB $48,$48,$48,$48 ; 0xbfc2: DB $78,$48,$48,$30 ; 0xbfc6: DB $00,$40,$40,$40 ; 0xbfca: DB $40,$78,$48,$48 ; 0xbfce: DB $78,$00,$f8,$00 ; 0xbfd2: DB $00,$00,$00,$00 ; (I think it might be using ; ; 0xbfd6's $00) ; 0xbfd6: D_bfd6 DB $00 ; data for the building 0xbfd7: DB $00,$a8,$f8,$a8 ; 0xbfdb: DB $f8,$a8,$f8,$a8 ; 0xbfdf: DB $f8,$a8,$f8,$a8 ; 0xbfe3: DB $f8,$a8,$f8,$a8 ; 0xbfe7: DB $f8,$a8,$f8,$a8 ; 0xbfeb: DB $f8,$a8,$f8,$a8 ; 0xbfef: DB $f8,$a8,$f8,$a8 ; 0xbff3: DB $f8,$a8,$f8,$00 ; 0xbff7: DB $00,$00,$00,$00 ; 0xbffb: DB $00 ; ; 0xbffc: ORG $bffc ; the reset vectors 0xbffc: DB $00,$b0,$00,$b0 0x0000: END ; the end