Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; *** R I V E R R A I D ***
- ; Copyright 1982 Activision
- ; Designer: Carol Shaw
- ; Analyzed, labeled and commented
- ; by Thomas Jentzsch (JTZ)
- ; Last Update: 13.08.2001 (v0.9)
- ; Section generation:
- ; The river is divided into sections which are generated by random. The random
- ; number generator can generate 57337 different sections. Each section is
- ; divided into 16 blocks. The last block is the bridge. For each other block a
- ; random Id is generated, which defines the shape of the river. The river is
- ; randomly generated with or without islands.
- ; Each block is 32 lines high and is divided into two parts. Those parts are
- ; neccessary for the bridge only, because it is smaller than a whole block.
- ;
- ; All objects are also randomly generated. There is one object in each block.
- ; First the game randomly selects if a fuel tank, an enemy object (ship, plane
- ; or helicopter) or a house should be generated. Then a starting x-position is
- ; defined and finally the direction (left/right) of the object is set.
- ; The ships and helicopters start patroling also randomly.
- ;
- ; Kernel:
- ; The main display is 160 lines tall. Below is the state display (score, fuel,
- ; lives and copyright).
- ; The kernel displays five or six of the section blocks. When a block leaves
- ; the display, it is replaced on the fly by a new generated one.
- ; It's basically a two line kernel, which is repeated twelve times. After that,
- ; there is code for eight more lines, where the block is iterated and all new
- ; parameter are set. (12 * 2 + 8 = 32!)
- ; The parameters for each block are:
- ; - a pointer to the current playfield pattern
- ; - a flag for a bright or dark green playfield
- ; - two pointers for the current object, the data is displayed interlaced,
- ; this gives in a single line resolution here
- ; - a color pointer for the object
- ; - x-positioning values for the object
- ; - some flags for the object (size, reflection...)
- ; All collisons are checked for each displayed block and only the hardware
- ; collision registers are used for that (no software calculations).
- ; Misc:
- ; - There are no score variables, the score is stored and changed directly in
- ; the display pointers!
- ; - The are no variables to store the x-positions of the objects, all
- ; calculations are done directly with the position values.
- ; (There aren't any BCD calculations in this code!)
- ; - All variables for the players are swapped, when the players change.
- ; - The game speeds aren't adjusted for PAL, the PAL game run's about 16% slower.
- ; (This seems to be true for most PAL conversions.)
- ; - ...
- processor 6502
- include vcs.h
- ;===============================================================================
- ; A S S E M B L E R - S W I T C H E S
- ;===============================================================================
- FILL_OPT = 1 ; fill optimized bytes with NOPs
- SCREENSAVER = 1 ; compile with screensaver code
- TRAINER = 0 ; enable training mode
- NTSC = 1 ; compile for NTSC
- ;===============================================================================
- ; C O N S T A N T S
- ;===============================================================================
- ; initial values for the random number generator:
- SEED_LO = $14 ; change "to go, where no one has gone before" :)
- SEED_HI = $A8
- ; color constants:
- BLACK = $00
- GREY = $06
- ORANGE = $2A
- IF NTSC
- YELLOW = $1C
- RED = $48
- BLUE = $84
- CYAN = $B0
- GREEN = $D2
- ELSE
- YELLOW = $2C
- RED = $68
- BLUE = $B4
- CYAN = $70
- GREEN = $52
- ENDIF
- DARK_RED = RED - $6
- LIGHT_GREEN = GREEN + $8
- BROWN = YELLOW - $C
- LIGHT_GREY = GREY + $6
- DARK_BLUE = BLUE - $4
- ; main game constants:
- NUM_BLOCKS = 6 ; max. number of block on screen
- SECTION_BLOCKS = 16 ; number of blocks/stage
- BLOCK_PARTS = 2 ; each block has two parts
- BLOCK_SIZE = 32 ; number of lines/block
- NUM_LINES = 160 ; number of lines in main kernel
- MAX_LEVEL = 48 ; number of difficulty levels
- DIGIT_H = 8 ; height of the score digits
- JET_Y = 19 ; fixed y-position for jet
- MIN_MISSILE = JET_Y-6 ; starting position of player missile
- MAX_MISSILE = NUM_LINES+1
- MISSILE_SPEED = 6 ; y-speed of the jet missile
- ROAD_HEIGHT = 13 ; number of lines for road
- INTRO_SCROLL = 48 ; counter for scrolling into new game
- SWITCH_PAGE_ID = 9 ; first pattern id with data on different page
- ; constants for shape-ids:
- ID_EXPLOSION0 = 0 ; used for explosion end
- ID_EXPLOSION1 = 1
- ID_EXPLOSION2 = 2
- ID_EXPLOSION3 = 3
- ID_PLANE = 4
- ID_HELI0 = 5
- ID_HELI1 = 6
- ID_SHIP = 7
- ID_BRIDGE = 8
- ID_HOUSE = 9
- ID_FUEL = 10
- ; flags for blockLst:
- PF1_PAGE_FLAG = %00000001 ; pattern for PF1 in page $FC or $FD
- PF2_PAGE_FLAG = %00000010 ; pattern for PF1 in page $FC or $FD
- PF_COLOR_FLAG = %00000100 ; bright or dark green PF
- PATROL_FLAG = %00010000 ; enemy is patroling (change directions)
- PF_COLLIDE_FLAG = %00100000 ; enemy collided with playfield
- ENEMY_MOVE_FLAG = %01000000 ; enemy is moving
- PF_ROAD_FLAG = %10000000 ; display road and bridge
- ; flags for State1Lst:
- DIRECTION_FLAG = %00001000 ; move direction of object
- FINE_MASK = %11110000 ; mask bits for HMxy
- NUSIZ_MASK = %00000111 ; mask bits for NUSIx
- ; flags for PF_State:
- ISLAND_FLAG = %10000000 ; island displayed in block
- CHANGE_FLAG = %01000000 ; begin or end of island (JTZ: this interpretation might be wrong)
- ; joystick bits:
- MOVE_RIGHT = %00001000
- MOVE_LEFT = %00000100
- MOVE_DOWN = %00000010
- MOVE_UP = %00000001
- ; values for ENAxy:
- DISABLE = %00
- ENABLE = %10 ; value for enabling a missile
- ; values for NUSIZx:
- TWO_COPIES = %001
- THREE_COPIES = %011
- DOUBLE_SIZE = %101
- QUAD_SIZE = %111
- ; mask for SWCHB:
- BW_MASK = %1000 ; black and white bit
- ;===============================================================================
- ; Z P - V A R I A B L E S
- ;===============================================================================
- gameVariation = $80 ; one or two player game
- gameDelay = $81 ; delay before gameVariation changes
- frameCnt = $82 ; simple frame counter
- random = $83 ; 8 bit random number (used for: start of ship and helicopter, sound)
- joystick = $84 ; saved joystick value (?000rldu)
- IF SCREENSAVER
- SS_XOR = $85 ; change colors in screensaver mode (0/$01..$ff)
- SS_Mask = $86 ; darker colors in screensaver mode ($ff/$f7)
- ENDIF
- dXSpeed = $87 ; x-acceleration
- prevPF1PatId = $88 ; playfield pattern Id of the previous block
- PF_State = $89 ; io000000
- sectionEnd = $8A ; 0 = end of section
- blockOffset = $8B ; offset into first displayed block
- posYLo = $8C ; low value of blockOffset
- bridgeExplode = $8D ; counter for bridge explosion
- ; the next 36 bytes are used to save all variables for six blocks:
- ;---------------------------------------
- blockLst = $8E ; ..$93 flags for block definition
- blockLstEnd = blockLst+NUM_BLOCKS-1
- ;---------------------------------------
- XPos1Lst = $94 ; ..$99 coarse value for x-positioning of object
- XPos1LstEnd = XPos1Lst+NUM_BLOCKS-1
- ;---------------------------------------
- State1Lst = $9A ; ..$9F bit 0..2 = NUSIZ1, bit 3 = REFP1, 4..7 = fine move
- State1LstEnd = State1Lst+NUM_BLOCKS-1
- ;---------------------------------------
- Shape1IdLst = $A0 ;.. $A5 ids for object
- Shape1IdLstEnd = Shape1IdLst+NUM_BLOCKS-1
- ;---------------------------------------
- PF1Lst = $A6 ; ..$AB low pointer for PF1 data
- PF1LstEnd = PF1Lst+NUM_BLOCKS-1
- ;---------------------------------------
- PF2Lst = $AC ; ..$B1 low pointer for PF2 data
- PF2LstEnd = PF2Lst+NUM_BLOCKS-1
- ;---------------------------------------
- ; end of block variables
- missileY = $B2 ; y-position of player missile
- playerX = $B3 ; x-position of player jet
- speedX = $B4 ; x-speed of player jet
- speedY = $B5 ; y-speed of play jet
- blockPart = $B6 ; 1/2 (used for bridge)
- fuelHi = $B7 ; high value of fuel (displayed)
- fuelLo = $B8 ; low value of fuel
- sectionBlock = $B9 ; number of block in current section (16..1)
- shapePtr0 = $BA ; ..$BB pointer to the shape for the player jet
- PF1PatId = $BC ; playfield pattern Id for the new generated block
- ;---------------------------------------
- player1State = $BD ; ..$C1
- level = player1State ; difficulty level for current player (1..48)
- randomLoSave = player1State+1; saved random generator values for begin of level
- randomHiSave = player1State+2;
- livesPtr = player1State+3; ..$C1
- ;---------------------------------------
- player2State = $C2 ; ..$C5
- livesPtr2 = player2State+3; the high pointer is not saved here, because it's const
- ;---------------------------------------
- gameMode = $C6 ; 0 = running; -1 = game over; 1..48 = scroll into game
- shapePtr1a = $C7 ; ..$C8
- shapePtr1b = $C9 ; ..$CA
- colorPtr = $CB ; ..$CC
- scorePtr1 = $CD ; ..$D8 12 bytes for the score display of current player
- PF1Ptr = $D9 ; ..$DA
- PF2Ptr = $DB ; ..$DC
- ;---------------------------------------
- scorePtr2 = $DD ; ..$E7 12 bytes for the score display of other player
- ; the constant hi-pointers are temporary used:
- blockNum = scorePtr2+1 ; current block in kernel
- reflect0 = scorePtr2+3 ; flag for GRP0 (player jet) reflection
- hitEnemyIdx = scorePtr2+5 ; index of enemy that was hit by missile
- PFCrashFlag = scorePtr2+7 ; jet crashed into playfield
- missileFlag = scorePtr2+9 ; $ff means: missile enabled
- ;---------------------------------------
- collidedEnemy = $E8 ; jet collided with enemy (id)
- randomLo = $E9 ; current number generator values
- randomHi = $EA
- randomLoSave2 = $EB ; saved number generator values for current player
- randomHiSave2 = $EC
- temp2 = $ED ;
- roadBlock = temp2 ; bit 7 = 1: road in block
- PFcolor = $EE ; color of river banks
- valleyWidth = PFcolor ; define minimum width of valley in first levels (6/0)
- playerColor = $EF ; YELLOW/BLACK
- stateBKColor = $F0 ; GREY (const!)
- statePFColor = $F1 ; YELLOW+2 (const!)
- temp = $F2 ; main temporary variable
- diffPF = temp ; difference between to PF pattern ids
- zero1 = $f3 ; always zero!
- player = $F4 ; 0/1
- missileX = $F5 ; x-position of player missile
- zero2 = $F6 ; always zero!
- IF SCREENSAVER
- SS_Delay = $F7 ; screensaver delay
- ENDIF
- sound0Id = $F8 ;
- sound0Cnt = $F9
- bridgeSound = $FA ; bridge is exploding
- missileSound = $FB ; missile fired
- temp3 = $FC
- blockLine = temp3 ; current displayed line of block in kernel
- maxId = temp3
- lineNum = $FD ; counter for kernel lines
- ;===============================================================================
- ; M A C R O S
- ;===============================================================================
- MAC FILL_NOP
- IF FILL_OPT
- REPEAT {1}
- NOP
- REPEND
- ENDIF
- ENDM
- ;===============================================================================
- ; R O M - C O D E (Part 1)
- ;===============================================================================
- ORG $F000
- START:
- SEI ; 2
- CLD ; 2
- LDX #0 ; 2
- Reset:
- LDA #0 ; 2
- .loopClear:
- STA $00,X ; 4
- TXS ; 2
- INX ; 2
- BNE .loopClear ; 2
- JSR SetScorePtrs ; 6
- LDA #>Zero ; 2
- LDX #12-1 ; 2
- JSR SetScorePtr1 ; 6 set high-pointers to $FB
- LDX #colorPtr+1-PF1Lst; 2 #38
- JSR GameInit ; 6
- LDA random ; 3
- BNE MainLoop ; 2
- INC random ; 5
- STA livesPtr ; 3 = 0!
- LDA #<One ; 2
- STA scorePtr1+10 ; 3
- MainLoop:
- LDX #4 ; 2 offset ball
- LDA fuelHi ; 3
- LSR ; 2
- LSR ; 2
- LSR ; 2
- CLC ; 2
- ADC #69 ; 2
- JSR SetPosX ; 6 position ball for fuel display
- ; *** prepare everything for the main kernel: ***
- ; set all color registers (and NUSIZ1 = 0)
- INX ; 2 x = 5!
- .loopSetColors:
- LDA ColorTab,X ; 4
- IF SCREENSAVER
- EOR SS_XOR ; 3
- AND SS_Mask ; 3
- ELSE
- FILL_NOP 4
- ENDIF
- STA PFcolor,X ; 4
- STA NUSIZ1,X ; 4
- DEX ; 2
- BPL .loopSetColors ; 2
- TAY ; 2 y = 0!
- LDA scorePtr1+10 ; 3
- CMP #<Two ; 2
- BEQ .skipTwo ; 2
- LDA SWCHB ; 4
- LSR ; 2 reset pressed?
- BCC .skipTwo ; 2 yes, skip player 2
- LDA player ; 3 current player = 2?
- BEQ .skipTwo ; 2 no, skip
- STY playerColor ; 3 yes, set..
- STY COLUP0 ; 3 ..and player 2 color = 0
- .skipTwo:
- ; flicker background when bridge explodes:
- LDA bridgeExplode ; 3
- BEQ .skipExplosion ; 2
- DEC bridgeExplode ; 5
- LSR ; 2
- BCC .skipExplosion ; 2
- LDA #DARK_RED ; 2 flicker background red
- IF SCREENSAVER
- AND SS_Mask ; 3
- ELSE
- FILL_NOP 2
- ENDIF
- STA COLUBK ; 3
- .skipExplosion:
- INX ; 2 x = 0!
- STX temp ; 3
- STX NUSIZ0 ; 3
- LDY playerX ; 3
- LDA reflect0 ; 3
- STA REFP0 ; 3
- BEQ .noReflect ; 2
- INY ; 2 adjust x-pos
- .noReflect:
- TYA ; 2
- JSR SetPosX ; 6 x-position player jet
- INX ; 2
- STX CTRLPF ; 3 reflect playfield
- STX VDELP1 ; 3 enable vertical delay for player 1
- ; set size, reflect and postion for top enemy object;
- LDY XPos1Lst +NUM_BLOCKS-1; 3
- LDA State1Lst+NUM_BLOCKS-1; 3
- STA NUSIZ1 ; 3
- STA REFP1 ; 3
- JSR SetPosX2 ; 6 position top enemy object
- ; x-position missile:
- INX ; 2
- LDA missileX ; 3
- JSR SetPosX ; 6 position missile
- JSR DoHMove ; 6
- STY PF0 ; 3 enable complete PF0 (y=$ff)
- ; clear collsion variables:
- STY hitEnemyIdx ; 3
- STY PFCrashFlag ; 3
- STY missileFlag ; 3
- STY collidedEnemy ; 3
- ; set variables for top block:
- LDX #NUM_BLOCKS-1 ; 2
- JSR SetPFxPtr ; 6
- LDA blockOffset ; 3
- CMP #3 ; 2 top block just started?
- BCS .skipDex ; 2 no, skip
- DEX ; 2 yes, start at block 4
- .skipDex:
- STX blockNum ; 3
- LDY Shape1IdLst,X ; 4
- LDX shapePtr1aTab,Y ; 4
- STX shapePtr1a ; 3
- LDX shapePtr1bTab,Y ; 4
- STX shapePtr1b ; 3
- LDX ColorPtrTab,Y ; 4
- STX colorPtr ; 3
- STA CXCLR ; 3 clear all collison registers
- STA HMCLR ; 3
- ; calculate offset into first block:
- TAX ; 2
- SEC ; 2
- SBC #1 ; 2
- AND #$1F ; 2
- STA blockLine ; 3
- LSR blockLine ; 5 0..15
- CMP #26 ; 2
- BCC lowOffset ; 2
- SBC #22 ; 2
- BNE endOffset ; 2
- lowOffset:
- CMP #4 ; 2
- BCC endOffset ; 2
- AND #%01 ; 2
- ORA #%10 ; 2
- endOffset:
- ; set entrypoint into kernel:
- TAY ; 2
- LDA JmpHiTab,Y ; 4
- PHA ; 3
- LDA JmpLoTab,Y ; 4
- PHA ; 3
- ; prepare graphics for first line of kernel:
- TXA ; 2
- LSR ; 2
- TAY ; 2
- LDA (shapePtr1a),Y ; 5
- BCC .evenLine ; 2 even blockOffset!
- LDA (shapePtr1b),Y ; 5
- .evenLine:
- CPX #26 ; 2 blockoffset >= 26?
- BCS .noShape ; 2 yes, skip enemy shape
- CPX #3 ; 2 blockoffset < 3?
- BCC .noShape ; 2 yes, skip enemy shape
- STA GRP1 ; 3 no, display enemy shape in first row
- LDA #0 ; 2
- STA GRP0 ; 3 VDELP1!
- .noShape:
- LDA (PF1Ptr),Y ; 5
- STA PF1 ; 3
- LDA (PF2Ptr),Y ; 5
- STA PF2 ; 3
- LDA (colorPtr),Y ; 5
- IF SCREENSAVER
- EOR SS_XOR ; 3
- AND SS_Mask ; 3
- ELSE
- FILL_NOP 4
- ENDIF
- STA COLUP1 ; 3
- LDX blockNum ; 3
- LDA blockLst,X ; 4
- STA roadBlock ; 3 save road-state
- AND #PF_COLOR_FLAG ; 2
- ORA #GREEN ; 2
- IF SCREENSAVER
- EOR SS_XOR ; 3
- AND SS_Mask ; 3
- ELSE
- FILL_NOP 4
- ENDIF
- STA PFcolor ; 3
- BIT blockLstEnd ; 3 road in first block?
- BPL .noRoad ; 2 no, use green color
- CPY #ROAD_HEIGHT ; 2 offset inside road?
- BCS .noRoad ; 2 no, use green color
- LDA RoadColorTab,Y ; 4 yes, use road colors
- IF SCREENSAVER
- EOR SS_XOR ; 3
- AND SS_Mask ; 3
- ELSE
- FILL_NOP 4
- ENDIF
- .noRoad:
- STA COLUPF ; 3
- LDY #NUM_LINES ; 2
- STY lineNum ; 3
- .waitTim:
- LDA INTIM ; 4
- BNE .waitTim ; 2
- STA WSYNC ; 3
- STA HMOVE ; 3
- STA VBLANK ; 3
- RTS ; 6 jump into kernel!
- ; *** main display kernel: ***
- DisplayKernel SUBROUTINE
- ; first some external code to save cycles in the kernel:
- JmpPoint2: ;12
- INC lineNum ; 5
- LDY blockLine ; 3
- BPL enterKernel2 ; 3
- .skipJet0:
- LDX zero2 ; 3 load 0 with exactly 3 cylces
- BEQ .contJet0 ; 3
- .noRoad:
- LDA PFcolor ; 3
- JMP .contPFColor ; 3
- .doJet0a:
- LDA (shapePtr0),Y ; 5
- TAX ; 2
- LDA #$00 ; 2
- .loopKernel1: ; @19
- BEQ .contJet0a ; 2 this jump is taken when comming from .doJet0a
- BNE .contKernel1 ; 3 this jump is taken when comming from .loopkernel1
- IF SCREENSAVER = 0
- FILL_NOP 1
- ENDIF
- JmpPoint3: ;12
- JSR Wait12 ;12
- .contKernel1:
- NOP ; 2 @26
- ;--------------------------------------
- ; even line:
- ; - ...
- ; - draw player jet
- ; - load new P1 shape
- ; *** here starts the main kernel loop: ***
- .loopKernel: ;
- CPY #JET_Y ; 2 draw player jet?
- BCS .skipJet0 ; 2 no, skip
- LDA (shapePtr0),Y ; 5 yes, load data..
- TAX ; 2 ..into x
- .contJet0:
- LDY blockLine ; 3
- BIT roadBlock ; 3 road displayed?
- BPL .noRoad ; 2 no, normal PF color
- LDA RoadColorTab,Y ; 4 yes, load road colors
- IF SCREENSAVER
- EOR SS_XOR ; 3
- .contPFColor:
- AND SS_Mask ; 3
- ELSE
- FILL_NOP 2
- .contPFColor:
- FILL_NOP 1
- ENDIF
- STA.w temp ; 4
- LDA (shapePtr1b),Y ; 5
- STA GRP1 ; 3 time doesn't matter (VDELP1!)
- LDA (PF1Ptr),Y ; 5
- STA PF1 ; 3 @75
- ;--------------------------------------
- ; new line starts here!
- ; odd line:
- ; - set PF color
- ; - set P1 color
- ; - change PF
- STA HMOVE ; 3
- STX GRP0 ; 3 @2 this also updates GRP1
- LDA temp ; 3
- STA COLUPF ; 3 @8
- LDA (colorPtr),Y ; 5
- IF SCREENSAVER
- EOR SS_XOR ; 3
- AND SS_Mask ; 3
- ELSE
- FILL_NOP 4
- ENDIF
- STA COLUP1 ; 3 @22
- LDA (PF2Ptr),Y ; 5
- STA PF2 ; 3 @30
- enterKernel2:
- LDA (shapePtr1a),Y ; 5
- STA GRP1 ; 3 time doesn't matter (VDELP1!)
- LDY lineNum ; 3
- DEY ; 2
- BEQ .exitKernel2 ; 2
- CPY #JET_Y ; 2
- BCC .doJet0a ; 2
- TYA ; 2
- SBC missileY ; 3
- AND #$F8 ; 2
- BNE .skipEnable0 ; 2
- LDA #ENABLE ; 2
- .skipEnable0:
- LDX #$00 ; 2
- .contJet0a:
- DEY ; 2
- STY lineNum ; 3
- STA WSYNC ; 3
- ;--------------------------------------
- ; even line:
- ; - en-/disable missile
- ; - update P0 and P1 graphics
- ; - decrease block-line
- ; - ...
- STA HMOVE ; 3
- STA ENAM0 ; 3
- STX GRP0 ; 3 @6 this also updates GRP1
- BEQ .exitKernel2 ; 2
- DEC blockLine ; 5
- BNE .loopKernel1 ; 2
- ;*** start of next block (requires eight extra kernel lines): ***
- ; new block, line 1
- ; - dec block-number
- ; - set new road-state
- ; - get new PF color
- ; - set new shape-pointer 1a
- DEC blockNum ; 5
- JmpPoint1:
- LDX blockNum ; 3
- BMI LF202 ; 2
- LDA blockLst,X ; 4 save road-state
- STA roadBlock ; 3
- AND #PF_COLOR_FLAG ; 2 bright or dark..
- ORA #GREEN ; 2 ..green
- IF SCREENSAVER
- EOR SS_XOR ; 3
- AND SS_Mask ; 3
- ELSE
- FILL_NOP 4
- ENDIF
- STA PFcolor ; 3
- LDA Shape1IdLst,X ; 4 set
- TAX ; 2 shape-pointer
- LDA shapePtr1aTab,X ; 4 for the
- STA shapePtr1a ; 3 next enemy
- LF1CE:
- LDA #$00 ; 2
- STA GRP1 ; 3
- CPY #JET_Y ; 2
- STA WSYNC ; 3
- ;--------------------------------------
- ; new block, line 2
- ; x = shape-id
- ; - set jet
- ; - set PF
- ; - set new shape-pointer 1b
- ; - set new color-pointer
- STA HMOVE ; 3
- BCS .skipJet1 ; 2
- LDA (shapePtr0),Y ; 5
- .skipJet1:
- STA GRP0 ; 3
- LDY #0 ; 2 display last line of playfield pattern
- LDA (PF1Ptr),Y ; 5
- STA PF1 ; 3
- LDA (PF2Ptr),Y ; 5
- STA PF2 ; 3
- LDY lineNum ; 3
- DEY ; 2
- .exitKernel2:
- BEQ .exitKernel1 ; 2
- LDA shapePtr1bTab,X ; 4
- STA shapePtr1b ; 3
- LDA ColorPtrTab,X ; 4
- STA colorPtr ; 3
- JmpPoint0:
- CPY #JET_Y ; 2
- BCS .skipJet2 ; 2
- LDA (shapePtr0),Y ; 5
- TAX ; 2
- LDA #DISABLE ; 2
- BEQ .contJet2 ; 3
- LF202: INX ; 2
- BEQ LF1CE ; 2
- JmpPoint9:
- NOP ; 2
- SEC ; 2
- BCS .enterKernel9 ; 3
- .skipJet2:
- TYA ; 2
- SBC missileY ; 3
- AND #$F8 ; 2
- BNE .skipEnable1 ; 2
- LDA #ENABLE ; 2
- .skipEnable1:
- LDX #$00 ; 2
- .contJet2:
- STA WSYNC ; 3
- ;--------------------------------------
- ; new block, line 3
- ; - en-/disabvle missile
- ; - set jet
- ; - set new PF pointers
- STA HMOVE ; 3
- STA ENAM0 ; 3
- STX GRP0 ; 3
- DEY ; 2
- STY lineNum ; 3
- .exitKernel1:
- BEQ .exitKernel ; 2
- LDX blockNum ; 3
- .enterKernel9:
- JSR SetPFxPtr ;50
- LDA PFcolor ; 3
- CPY #JET_Y ; 2
- NOP ; 2 @76
- ;--------------------------------------
- ; new block, line 4
- ; - set new PF color
- ; - set PF
- ; - load fine movement
- STA HMOVE ; 3
- STA COLUPF ; 3
- BCS .skipJet3 ; 2
- LDA (shapePtr0),Y ; 5
- STA GRP0 ; 3
- .skipJet3:
- LDY #SECTION_BLOCKS-1 ; 2
- LDA (PF1Ptr),Y ; 5
- STA PF1 ; 3
- LDA (PF2Ptr),Y ; 5
- STA PF2 ; 3
- DEC lineNum ; 5
- BEQ .exitKernel ; 2
- JmpPoint8:
- LDA State1Lst,X ; 4 put fine move-value
- STA temp ; 3 into temp
- LDY lineNum ; 3
- CPY #JET_Y ; 2
- BCC .skipJet4 ; 2
- TYA ; 2
- SBC missileY ; 3
- AND #$F8 ; 2
- BNE .skipEnable2 ; 2
- LDA #ENABLE ; 2
- .skipEnable2:
- LDY #0 ; 2
- .contJet4:
- STA WSYNC ; 3
- ;--------------------------------------
- ; new block, line 5
- ; - en-/disable missile
- ; - set jet
- ; - position new shape
- STA HMOVE ; 3
- STA ENAM0 ; 3
- STY GRP0 ; 3
- ; position player 1:
- LDA XPos1Lst,X ; 4 load coarse move-value
- BEQ .posVeryLeft ; 2
- TAX ; 2
- CPX #7 ; 2
- BCS .posRight ; 2
- .waitLeft:
- DEX ; 2
- BNE .waitLeft ; 2
- STA RESP1 ; 3
- .contLeft:
- DEC lineNum ; 5
- LDY lineNum ; 3
- BNE .contPos ; 2
- .exitKernel:
- JMP DisplayState ; 3 exit the kernel
- .posVeryLeft:
- NOP ; 2
- NOP ; 2
- LDA #$60 ; 2
- STA RESP1 ; 3
- STA HMP1 ; 3
- BNE .contLeft ; 2
- .skipJet4:
- LDA (shapePtr0),Y ; 5
- TAY ; 2
- LDA #$00 ; 2
- BEQ .contJet4 ; 2
- .posRight:
- SBC #4 ; 2
- TAX ; 2
- DEC lineNum ; 5
- LDY lineNum ; 3
- BEQ .exitKernel ; 2
- .waitRight:
- DEX ; 2
- BPL .waitRight ; 2
- STA RESP1 ; 3
- JmpPoint7:
- .contPos:
- STA WSYNC ; 3
- ;--------------------------------------
- ; new block, line 6
- STA HMOVE ; 3
- CPY #JET_Y ; 2
- BCS .skipJet5 ; 2
- LDA (shapePtr0),Y ; 5
- STA GRP0 ; 3
- .skipJet5:
- LDY #SECTION_BLOCKS-2 ; 2
- LDA (PF1Ptr),Y ; 5
- STA PF1 ; 3
- LDA (PF2Ptr),Y ; 5
- STA PF2 ; 3
- LDY lineNum ; 3
- DEY ; 2
- BEQ .exitKernel ; 2
- LDX blockNum ; 3
- LDA temp ; 3
- STA HMP1 ; 3
- JmpPoint6:
- LDA #[BLOCK_SIZE-8]/2 ; 2
- STA blockLine ; 3
- TYA ; 2
- SEC ; 2
- SBC missileY ; 3
- AND #$F8 ; 2
- BNE .skipEnable3 ; 2
- LDA #ENABLE ; 2
- .skipEnable3:
- CPY #JET_Y ; 2
- STA WSYNC ; 3
- ;--------------------------------------
- ; new block, line 7
- STA HMOVE ; 3
- STA ENAM0 ; 3
- BCS .skipJet6 ; 2
- LDA (shapePtr0),Y ; 5
- STA GRP0 ; 3
- .skipJet6:
- LDA State1Lst,X ; 4
- STA NUSIZ1 ; 3
- STA REFP1 ; 3
- DEY ; 2
- STY lineNum ; 3
- BEQ DisplayState ; 2
- STA HMCLR ; 3
- ; check collisions:
- ; (the collsion check between jet or missile and playfield aren't
- ; really neccessary for each block, but the collison registers
- ; are cleared after each block)
- INX ; 2
- BIT CXM0P-$30 ; 3 player missile hit enemy?
- BPL .notHit ; 2
- STX hitEnemyIdx ; 3 save block number
- .notHit:
- IF TRAINER
- BIT zero1
- ELSE
- BIT CXP0FB-$30 ; 3 jet hit PF?
- ENDIF
- BPL .noPFCrash ; 2
- STX PFCrashFlag ; 3
- .noPFCrash:
- IF TRAINER
- BIT zero1
- ELSE
- BIT CXM0FB-$30 ; 3 player missile hit PF?
- ENDIF
- BPL .notHitPF ; 2
- STX missileFlag ; 3
- .notHitPF:
- IF TRAINER
- BIT zero1
- ELSE
- BIT CXPPMM-$30 ; 3 jet crashed into enemy?
- ENDIF
- BPL .noCrash ; 2
- STX collidedEnemy ; 3 save block number
- .noCrash:
- .enterKernel5:
- ;--------------------------------------
- ; new block, line 8
- STA WSYNC ; 3
- STA HMOVE ; 3
- CPY #JET_Y ; 2
- BCS .skipJet7 ; 2
- LDA (shapePtr0),Y ; 5
- STA GRP0 ; 3
- .skipJet7:
- LDY #SECTION_BLOCKS-3 ; 2
- LDA (PF1Ptr),Y ; 5
- STA PF1 ; 3
- LDA (PF2Ptr),Y ; 5
- STA PF2 ; 3
- LDY lineNum ; 3
- DEY ; 2
- BEQ DisplayState ; 2
- BIT CXP1FB-$30 ; 3 enemy hit PF?
- BPL .notEnemyPF ; 2 no, skip
- LDA blockLst,X ; 4
- ORA #PF_COLLIDE_FLAG ; 2 yes, set collision flag
- STA blockLst,X ; 4
- .notEnemyPF:
- STA CXCLR ; 3 clear all collison registers
- .enterKernel4:
- TYA ; 2
- SEC ; 2
- SBC missileY ; 3
- AND #$F8 ; 2
- BNE .skipEnable4 ; 2
- LDA #ENABLE ; 2
- .skipEnable4:
- CPY #JET_Y ; 2
- STA WSYNC ; 3
- ;--------------------------------------
- ; new block, line 9 (= begin of even line)
- STA HMOVE ; 3
- STA ENAM0 ; 3
- BCS .skipJet8 ; 2
- LDA (shapePtr0),Y ; 5
- STA GRP0 ; 3
- .contJet8:
- DEY ; 2
- STY lineNum ; 3
- BEQ DisplayState ; 2 exit the kernel
- JMP .loopKernel ; 3 @26
- JmpPoint5:
- LDA #[BLOCK_SIZE-8]/2 ; 2
- STA blockLine ; 3
- BNE .enterKernel5 ; 3
- JmpPoint4:
- LDA #[BLOCK_SIZE-8]/2 ; 2 12
- STA blockLine ; 3
- BNE .enterKernel4 ; 3
- .skipJet8: ; waste some time
- NOP ; 2
- NOP ; 2
- BCS .contJet8 ; 3
- DisplayState SUBROUTINE
- ; finish display kernel:
- STA WSYNC ; 3
- STA HMOVE ; 3
- LDY #$00 ; 2
- STY GRP1 ; 3
- STY GRP0 ; 3
- LDA zero1 ; 3 waste one extra cylce (but also wastes a variable!)
- STA COLUBK ; 3
- STY PF0 ; 3
- STY PF1 ; 3
- STY PF2 ; 3
- STY REFP0 ; 3
- STY REFP1 ; 3
- STY reflect0 ; 3
- ; prepare state display:
- LDA #$11 ; 2 reflect PF, 2 pixel ball width, also for HMP0!
- STA RESP0 ; 3
- STA RESP1 ; 3
- STA CTRLPF ; 3
- STA HMP0 ; 3
- LDA #$20 ; 2
- STA HMP1 ; 3
- LDA playerColor ; 3
- JSR SetColPx ; 6
- LDA stateBKColor ; 3
- STA COLUBK ; 3
- LDA #THREE_COPIES ; 2
- STA NUSIZ0 ; 3
- STA NUSIZ1 ; 3
- LDA statePFColor ; 3
- STA COLUPF ; 3
- LDY #$07 ; 2
- STY VDELP0 ; 3
- STY lineNum ; 3
- STA HMCLR ; 3
- ; display score:
- .loopScore:
- LDA (scorePtr1+8),Y ; 5
- TAX ; 2
- LDA (scorePtr1+10),Y ; 5
- STA WSYNC ; 3
- STA HMOVE ; 3
- STY temp2 ; 3
- STA temp ; 3
- LDA (scorePtr1),Y ; 5
- STA GRP0 ; 3
- LDA (scorePtr1+2),Y ; 5
- STA GRP1 ; 3
- LDA (scorePtr1+4),Y ; 5
- STA GRP0 ; 3
- LDA (scorePtr1+6),Y ; 5
- LDY temp ; 3
- STA GRP1 ; 3
- STX GRP0 ; 3
- STY GRP1 ; 3
- STA GRP0 ; 3
- LDY temp2 ; 3
- DEY ; 2
- BPL .loopScore ; 2
- LDA zero1 ; 3 a = 0 (BLACK)
- JSR FinishDigits ; 6 y = 14
- ; display fuel:
- .loopFuel:
- STY temp2 ; 3 line counter
- LDA FuelTab4,Y ; 4
- LDX FuelTab3,Y ; 4
- STA WSYNC ; 3
- STA HMOVE ; 3
- STA temp ; 3
- NOP ; 2
- LDA #$00 ; 2
- STA GRP0 ; 3
- LDA ENABLTab,Y ; 4
- STA ENABL ; 3
- LDA FuelTab0,Y ; 4
- STA GRP1 ; 3
- LDA FuelTab1,Y ; 4
- STA GRP0 ; 3
- LDA FuelTab2,Y ; 4
- LDY temp ; 3
- STA GRP1 ; 3
- STX GRP0 ; 3
- STY GRP1 ; 3
- STA GRP0 ; 3
- LDY temp2 ; 3
- DEY ; 2
- BPL .loopFuel ; 2
- LDA playerColor ; 3
- JSR FinishDigits ; 6
- INY ; 2 y=15
- CLC ; 2
- LDX gameMode ; 3
- INX ; 2
- BNE .noGame ; 2
- LDA #<Space ; 2
- STA livesPtr ; 3
- ; animate copyright message:
- LDA frameCnt ; 3
- LSR ; 2
- LSR ; 2
- LSR ; 2
- CMP #20 ; 2
- BCS .ok ; 2
- CMP #12 ; 2
- .noGame:
- LDY #7 ; 2
- BCC .ok ; 2
- SBC #4 ; 2
- TAY ; 2
- .ok:
- STY temp3 ; 3 copyright scroll offset
- ; display lives and copyright:
- .loopCopyright:
- LDY temp3 ; 3
- LDA Copyright5,Y ; 4
- STA temp ; 3
- STA WSYNC ; 3
- STA HMOVE ; 3
- LDX Copyright4,Y ; 4
- LDA (livesPtr),Y ; 5
- STA GRP0 ; 3
- DEC temp3 ; 5
- LDA Copyright1,Y ; 4
- STA GRP1 ; 3
- LDA Copyright2,Y ; 4
- STA GRP0 ; 3
- LDA Copyright3,Y ; 4
- LDY temp ; 3
- STA GRP1 ; 3
- STX GRP0 ; 3
- STY GRP1 ; 3
- STA GRP0 ; 3
- DEC lineNum ; 5
- BPL .loopCopyright ; 2
- STA WSYNC ; 3
- STA HMOVE ; 3
- LDX #$00 ; 2
- STX VDELP0 ; 3
- STX GRP1 ; 3
- STX GRP0 ; 3
- LDA blockOffset ; 3
- CMP #BLOCK_SIZE-6 ; 2
- BCC .skipInx ; 2
- INX ; 2
- .skipInx:
- ; check collisions for the last displayed block:
- BIT CXM0P-$30 ; 3 player missile hit enemy?
- BPL .notHit2 ; 2
- STX hitEnemyIdx ; 3 save block number
- .notHit2:
- IF TRAINER
- BIT zero1
- ELSE
- BIT CXP0FB-$30 ; 3 jet hit PF?
- ENDIF
- BPL .noPFCrash2 ; 2
- STX PFCrashFlag ; 3
- .noPFCrash2:
- BIT CXM0FB-$30 ; 3 player missile hit PF?
- BPL .notHitPF2 ; 2
- STX missileFlag ; 3
- .notHitPF2:
- IF NTSC
- LDA #29 ; 2
- ELSE
- LDA #58 ; 2
- ENDIF
- LDY #%10000010 ; 2
- STA WSYNC ; 3
- STA TIM64T ; 4
- STY VBLANK ; 3
- BIT CXP1FB-$30 ; 3 enemy hit PF?
- BPL .notEnemyPF2 ; 2
- LDA blockLst,X ; 4
- ORA #PF_COLLIDE_FLAG ; 2
- STA blockLst,X ; 4
- .notEnemyPF2:
- IF TRAINER
- LDA zero1
- ELSE
- BIT CXPPMM-$30 ; 3 jet crashed into enemy?
- ENDIF
- BPL .noCrash2 ; 2
- STX collidedEnemy ; 3 save block number
- .noCrash2:
- ; *** update framecounter, check for screensaver: ***
- DEC frameCnt ; 5
- BNE .skipSS_Delay ; 2
- LDX gameMode ; 3
- INX ; 2
- BNE .skipInit ; 2
- JSR SwapPlayers ; 6
- .skipInit:
- IF SCREENSAVER
- INC SS_Delay ; 5
- BNE .skipSS_Delay ; 2
- SEC ; 2
- ROR SS_Delay ; 5
- ELSE
- FILL_NOP 4
- ENDIF
- .skipSS_Delay:
- IF SCREENSAVER
- LDY #$FF ; 2
- LDA SWCHB ; 4
- AND #BW_MASK ; 2 black and white?
- BNE .colorMode ; 2 no, color mode
- LDY #$0F ; 2 yes, mask out high nibble
- .colorMode:
- TYA ; 2
- LDY #$00 ; 2
- BIT SS_Delay ; 3
- BPL .noScreenSaver ; 2
- AND #$F7 ; 2
- LDY SS_Delay ; 3
- .noScreenSaver:
- STY SS_XOR ; 3
- ASL SS_XOR ; 5
- STA SS_Mask ; 3
- ELSE
- FILL_NOP 28
- ENDIF
- ; *** randomly start movement of enemies: ***
- LDA random ; 3
- ASL ; 2
- ASL ; 2
- ASL ; 2
- EOR random ; 3
- ASL ; 2
- ROL random ; 5
- LDA frameCnt ; 3
- AND #$0F ; 2 every 16th frame
- BNE .skipStartMove ; 2
- LDA random ; 3
- AND #$07 ; 2
- CMP #5 ; 2 start one of the first five enemies
- BCC .inBound ; 2
- SBC #5 ; 2 doubled chances for the first three enemies
- .inBound:
- TAX ; 2
- LDA blockLst,X ; 4 start
- ORA #ENEMY_MOVE_FLAG ; 2 movement
- STA blockLst,X ; 4 of enemy
- .skipStartMove:
- ;*** animate and move the enemy objects: ***
- LDX #NUM_BLOCKS-1 ; 2
- .loopEnemies:
- ; animate some enemies:
- LDY Shape1IdLst,X ; 4
- CPY #ID_SHIP ; 2 don't animate ship, bridge, house and fuel
- BCS .skipAnimate ; 2
- LDA #$01 ; 2 every 2nd frame
- CPY #ID_PLANE ; 2 fast animate plane (not done) and helicopter
- BCS .fastAnimation ; 2
- LDA #$0F ; 2 slow animate explosions (every 16th frame)
- .fastAnimation:
- AND frameCnt ; 3
- BNE .skipAnimate ; 2
- LDA AnimateIdTab,Y ; 4
- STA Shape1IdLst,X ; 4
- TAY ; 2
- .skipAnimate:
- ; check for move and direction change:
- LDA gameMode ; 3
- BNE .skipMoveEnemy ; 2
- LDA level ; 3
- LSR ; 2 first level?
- BEQ .skipMoveEnemy ; 2 yes, don't move
- CPY #ID_PLANE ; 2 move plane in same direction every frame
- BEQ .xMoveEnemy ; 2
- BCC .skipMoveEnemy ; 2
- CPY #ID_BRIDGE ; 2 don't move bridge, house and fuel
- BCS .skipMoveEnemy ; 2
- LDA frameCnt ; 3
- ROR ; 2
- BCS .skipMoveEnemy ; 2 move helicopter and ship every 2nd frame
- LDA blockLst,X ; 4
- ASL ; 2 enemy moving?
- BPL .skipMoveEnemy ; 2 no, skip move
- ASL ; 2 enemy collided with PF?
- BPL .noPFCollision ; 2 no, skip
- ASL ; 2 patroling enemy?
- BMI .xMoveEnemy ; 2 no, skip swap direction
- LDA State1Lst,X ; 4 switch
- EOR #DIRECTION_FLAG ; 2 enemy move
- STA State1Lst,X ; 4 direction
- LDA blockLst,X ; 4
- ORA #PATROL_FLAG ; 2 (re)enable patrol mode
- BNE .endChangeDir ; 2
- .noPFCollision:
- LDA blockLst,X ; 4
- AND #~PATROL_FLAG ; 2 disable patrol mode (only temporary)
- .endChangeDir:
- STA blockLst,X ; 4
- ; move enemy one pixel left or right:
- ; (no real position variables, the code is working
- ; directly with the positioning values)
- .xMoveEnemy:
- LDY XPos1Lst,X ; 4
- LDA State1Lst,X ; 4
- LSR ; 2
- LSR ; 2
- LSR ; 2
- LSR ; 2
- EOR #$07 ; 2
- BCS .xMoveLeft ; 2 moving left!
- ADC #1 ; 2
- CMP #15 ; 2
- BCC .skipRightIny ; 2
- SBC #15 ; 2
- INY ; 2
- .skipRightIny:
- CPY #10 ; 2
- BCC .contMoveX ; 2
- CMP #10 ; 2 >= 160?
- BCC .contMoveX ; 2 no, continue
- LDY #0 ; 2 yes,..
- TYA ; 2 ..move shape (plane)..
- BEQ .contMoveX ; 2 ..to the very left (0)
- .xMoveLeft:
- SBC #1 ; 2
- BCS .contMoveX2 ; 2
- ADC #15 ; 2
- DEY ; 2 < 0?
- BPL .contMoveX ; 2 no, continue
- LDY #10 ; 2 yes, move shape (plane)..
- LDA #9 ; 2 ..to the very right (159)
- .contMoveX:
- STY XPos1Lst,X ; 4 store coarse value here
- .contMoveX2:
- EOR #$07 ; 2
- JSR Mult16 ; 6
- EOR State1Lst,X ; 4
- AND #FINE_MASK ; 2 #$F0
- EOR State1Lst,X ; 4
- STA State1Lst,X ; 4 OR fine value into here
- .skipMoveEnemy:
- ; clear PF-collision:
- LDA blockLst,X ; 4
- AND #~PF_COLLIDE_FLAG ; 2
- STA blockLst,X ; 4
- DEX ; 2
- BMI .exitLoopEnemies ; 2
- JMP .loopEnemies ; 3
- .exitLoopEnemies:
- ; *** read joystick: ***
- LDA SWCHA ; 4
- LDX player ; 3
- BEQ .player1 ; 2
- JSR Mult16 ; 6
- .player1:
- AND #$F0 ; 2 mask out other player joystick
- TAX ; 2
- LDY #4 ; 2
- .loopBits:
- ROL ; 2 roll new 4 bits into joystick
- ROL joystick ; 5 (old 4 bits got into upper nibble!)
- DEY ; 2
- BNE .loopBits ; 2
- CPX #$F0 ; 2
- BNE .joystickMoved ; 2
- LDX player ; 3
- LDA INPT4-$30,X ; 4
- BMI .noFire ; 2
- .joystickMoved:
- LDA gameMode ; 3
- CMP #INTRO_SCROLL ; 2
- BNE .skipRestart ; 2
- LDA #64 ; 2 restart new game
- STA speedY ; 3
- STY gameMode ; 3 y=0!
- .skipRestart:
- IF SCREENSAVER
- STY SS_Delay ; 3 y=0!
- ELSE
- FILL_NOP 2
- ENDIF
- .noFire:
- LDX gameMode ; 3
- BEQ .checkCollisions ; 2 game running
- BMI .gameOver ; 2 game is over
- CPX #INTRO_SCROLL+1 ; 2 scrolling into new game/life?
- BCC .doSoundJmp ; 2 yes, skip decrease
- BNE .startGame ; 2 no, finished scrolling, start new game
- ; decrease lives:
- LDA livesPtr ; 3
- BEQ .finishGame ; 2 zero!
- SBC #DIGIT_H ; 2
- BNE LF5B5 ; 2
- LDA #<Space+1 ; 2
- LF5B5: CMP #<MaxOut ; 2 score overflow?
- BNE LF5BB ; 2
- LDA #<Three ; 2 reset lives to 3
- LF5BB: STA livesPtr ; 3
- .startGame:
- DEC gameMode ; 5 start game
- BNE .doSoundJmp ; 2
- .gameOver:
- INX ; 2
- BEQ .doSoundJmp ; 2
- DEC gameMode ; 5
- BMI .doSoundJmp ; 2
- STY shapePtr0 ; 3
- LDA livesPtr2 ; 3
- CMP #<Copyright0 ; 2 other player still alive?
- BEQ .skipSwap ; 2 no, skip swap
- JSR SwapPlayers ; 6
- .skipSwap:
- LDA livesPtr ; 3
- CMP #<Copyright0 ; 2 current player still alive?
- BNE .initPlayer ; 2 yes, continue
- .finishGame:
- JSR FinishGame ; 6
- BNE .doSoundJmp ; 2
- .initPlayer:
- LDX #shapePtr0+2-PF1Lst;2 #22
- JSR GameInit ; 6
- TYA ; 2
- ORA #PF_ROAD_FLAG ; 2
- STA blockLstEnd ; 3
- LDA randomLoSave ; 3 load..
- STA randomLo ; 3 ..random variables..
- LDA randomHiSave ; 3 ..with saved..
- STA randomHi ; 3 ..player variables
- .doSoundJmp:
- JMP DoSound ; 3
- .checkCollisions:
- LDX collidedEnemy ; 3 collided with enemy?
- BMI .endCollisions ; 2 no, skip
- LDA Shape1IdLst,X ; 4
- CMP #ID_PLANE ; 2 collided with explosion?
- BCC .endCollisions ; 2 no, skip
- CMP #ID_BRIDGE ; 2 collided with ship, plane or helicopter?
- BCC .noBridge ; 2 yes, do collision
- BNE .refuel ; 2 no, collided with fuel!
- INC sectionEnd ; 5 no, collided with bridge!
- .noBridge:
- LDY #$1F ; 2 load some sound values
- LDA #1 ; 2 sound id = 1
- JSR LooseJet ; 6
- LDX collidedEnemy ; 3
- LDA #ID_EXPLOSION2 ; 2 start explosion
- JMP .contJetExplosion ; 3
- .refuel:
- LDA fuelHi ; 3
- ADC #$01 ; 2
- LDX #4 ; 2 sound id = 4
- BCC .notFull ; 2
- LDA #$FF ; 2
- STA fuelLo ; 3
- LDX #3 ; 2 sound id = 3
- .notFull:
- STA fuelHi ; 3
- CPX sound0Id ; 3
- BEQ .endCollisions ; 2
- STX sound0Id ; 3
- LDA #$08 ; 2
- STA sound0Cnt ; 3
- .endCollisions:
- LDX PFCrashFlag ; 3 jet crashed?
- BMI .skipCrash ; 2 no, skip
- .maxedOut:
- LDY #$1F ; 2
- LDA #1 ; 2 sound id = 1
- .looseJet:
- JSR LooseJet ; 6
- BNE .doSoundJmp ; 2
- .skipCrash:
- ; decrease fuel:
- LDA fuelLo ; 3
- SEC ; 2
- IF TRAINER
- SBC #0
- ELSE
- SBC #$20 ; 2
- ENDIF
- BCS .skipDecHi ; 2
- LDY fuelHi ; 3
- BNE .fuelOk ; 2
- LDA #2 ; 2 sound id = 2
- LDY #$23 ; 2
- JMP .looseJet ; 3 out of fuel!
- .fuelOk:
- DEC fuelHi ; 5
- .skipDecHi:
- STA fuelLo ; 3
- ; *** move jet left or right: ***
- LDA joystick ; 3
- TAY ; 2
- AND #MOVE_LEFT|MOVE_RIGHT; 2
- EOR #MOVE_LEFT|MOVE_RIGHT; 2
- BNE .leftRight ; 2
- STA dXSpeed ; 3 jet is flying straight
- STA speedX ; 3
- LDX #<JetStraight-1 ; 2
- BNE .setPtr0 ; 2
- .leftRight:
- LDA dXSpeed ; 3 increase the x speed change
- CLC ; 2
- ADC #8 ; 2
- BCS .maxChange ; 2
- STA dXSpeed ; 3
- .maxChange:
- LDX #<JetMove-1 ; 2
- TYA ; 2
- AND #MOVE_RIGHT ; 2
- STA reflect0 ; 3
- BEQ .moveRight ; 2
- BCS .maxChange2 ; 2
- LDA speedX ; 3
- SEC ; 2
- SBC dXSpeed ; 3
- BCS .setXSpeed ; 2
- .maxChange2:
- DEC playerX ; 5
- BNE .setXSpeed ; 2
- .moveRight:
- BCS .maxChange3 ; 2
- LDA speedX ; 3
- BIT joystick ; 3 moved right before?
- BPL .wasRight ; 2 yes, skip
- LDA #-1 ; 2 bo, move the jet very slowly to the left (JTZ: what's that good for?)
- .wasRight:
- ADC dXSpeed ; 3
- BCC .setXSpeed ; 2
- .maxChange3:
- INC playerX ; 5
- .setXSpeed:
- STA speedX ; 3
- .setPtr0:
- STX shapePtr0 ; 3
- ; change jet speed:
- LDX speedY ; 3
- TYA ; 2
- LSR ; 2
- BCS .noMoveUp ; 2
- .incSpeed:
- TXA ; 2
- ADC #2 ; 2
- BCC .changeSpeed ; 2
- BCS .skipChange ; 2
- .noMoveUp:
- LSR ; 2
- BCC .noMoveDown ; 2
- TXA ; 2
- ASL ; 2
- BCC .incSpeed ; 2
- BEQ .skipChange ; 2
- .noMoveDown:
- TXA ; 2
- CMP #$41 ; 2 minimal speed?
- BCC .skipChange ; 2 yes, skip slow down
- SBC #2 ; 2
- .changeSpeed:
- STA speedY ; 3
- .skipChange:
- LDX hitEnemyIdx ; 3 object hit?
- BMI .skipCollisions ; 2 no, skip
- LDY Shape1IdLst,X ; 4
- CPY #ID_PLANE ; 2 enemy objects?
- BCC .skipCollisions ; 2 no, explosions
- LDA #ID_EXPLOSION1 ; 2 start explosion animation
- .contJetExplosion:
- LDY Shape1IdLst,X ; 4
- STA Shape1IdLst,X ; 4
- LDA #23 ; 2
- STA bridgeSound ; 3
- CPY #ID_BRIDGE ; 2
- BNE .skipBridge ; 2
- STA bridgeExplode ; 3 start bridge explosion
- LDA #$E0|TWO_COPIES ; 2 set fixed position and size (two copies close)
- STA State1Lst,X ; 4
- LDA #4 ; 2 coarse positiong value
- STA XPos1Lst,X ; 4
- INC sectionEnd ; 5 new section has been started
- .skipBridge:
- ; increase score:
- LDX #8 ; 2 add 10s
- LDA ScoreTab,Y ; 4
- BPL .loopSetPtr1 ; 2
- AND #$7F ; 2 add n*100 points
- LDX scorePtr1+8 ; 3
- CPX #<Space ; 2
- BNE .noSpace ; 2
- LDX #<Zero ; 2 replace Space..
- STX scorePtr1+8 ; 3 ..with Zero
- .noSpace:
- LDX #6 ; 2 add 100s
- .loopSetPtr1:
- PHA ; 3
- CPX #2 ; 2 life pointer
- BNE .notLivePtr ; 2
- ; check for bonus life:
- LDA livesPtr ; 3
- CMP #<Nine ; 2
- BEQ .maxLives ; 2
- BCC .notMax ; 2
- LDA #$FF ; 2 CF=1!
- .notMax:
- ADC #DIGIT_H ; 2
- STA livesPtr ; 3
- .maxLives:
- .notLivePtr:
- LDA scorePtr1,X ; 4
- SEC ; 2
- SBC #<Space ; 2
- BNE .noSpace2 ; 2
- STA scorePtr1,X ; 4 point to '0'
- .noSpace2:
- PLA ; 4
- CLC ; 2
- ADC scorePtr1,X ; 4
- CMP #<MaxOut ; 2
- BCC .noMaxOut ; 2 exit loop
- SBC #<MaxOut ; 2
- STA scorePtr1,X ; 4
- LDA #DIGIT_H ; 2
- DEX ; 2
- DEX ; 2
- BPL .loopSetPtr1 ; 2
- ; more than 999990 points, set score to !!!!!!, game over:
- LDA #<MaxOut ; 2
- LDX #12-2 ; 2
- JSR SetScorePtr1 ; 6
- LDA #<Copyright0 ; 2
- STA livesPtr ; 3
- JMP .maxedOut ; 3
- .noMaxOut:
- STA scorePtr1,X ; 4
- .noMissile:
- LDX #$B4 ; 2 disable missile
- BNE .directMissile ; 2
- .skipCollisions:
- ; *** move or fire missiles: ***
- LDA missileFlag ; 3
- BPL .noMissile ; 2
- LDA missileY ; 3
- CMP #MAX_MISSILE+1 ; 2
- BCS .checkFire ; 2
- ADC #MISSILE_SPEED ; 2 y-move missile
- TAX ; 2
- LDA SWCHB ; 4 read difficulty
- LDY player ; 3
- BNE .player1a ; 2
- ASL ; 2
- .player1a:
- TAY ; 2
- BPL .guidedMissile ; 2
- BMI .directMissile ; 2
- .checkFire:
- LDX player ; 3
- LDA INPT4-$30,X ; 4
- BMI .noMissile ; 2
- LDX #$0F ; 2
- STX missileSound ; 3
- LDX #MIN_MISSILE ; 2
- .guidedMissile:
- LDA playerX ; 3
- CLC ; 2
- ADC #$05 ; 2
- STA missileX ; 3
- .directMissile:
- STX missileY ; 3
- ; *** sound routines: ***
- ; TODO: analyze, labels, comments
- DoSound:
- ; start with channel 0:
- LDY #$1C ; 2
- LDA sound0Cnt ; 3
- LDX sound0Id ; 3
- BEQ LF789 ; 2
- DEX ; 2
- BEQ LF770 ; 2
- LDY #$0F ; 2
- CPX #$02 ; 2
- BCS LF776 ; 2
- LDY #$08 ; 2
- LF770: LSR ; 2
- TAX ; 2
- LDA #$08 ; 2 white noise
- BNE LF77D ; 2
- LF776: BEQ LF77A ; 2
- LDY #$1F ; 2
- LF77A: TAX ; 2
- LDA #$04 ; 2 high pure tone
- LF77D: DEC sound0Cnt ; 5
- BNE .setAud0 ; 2
- PHA ; 3
- LDA #0 ; 2
- STA sound0Id ; 3 stop sound0
- PLA ; 4
- BPL .setAud0 ; 2
- ; low fuel sound:
- LF789: LDA gameMode ; 3 game running?
- BNE .mute0 ; 2 no, quiet (x=0)
- LDA fuelHi ; 3
- CMP #$40 ; 2
- BCS .jetSound ; 2
- LDY sound0Cnt ; 3
- BNE .contSound0 ; 2
- LDY #$3F ; 2
- .contSound0:
- DEY ; 2
- STY sound0Cnt ; 3
- LDX fuelLo ; 3
- STX temp ; 3
- CMP #$04 ; 2
- BCS LF7B0 ; 2
- ROL temp ; 5
- ROL ; 2
- ROL temp ; 5
- ROL ; 2
- EOR #$FF ; 2
- ADC #$20 ; 2
- BNE .loadAud0 ; 2
- LF7B0: CPY #$1C ; 2
- BCC .jetSound ; 2
- TYA ; 2
- LSR ; 2
- .loadAud0:
- TAY ; 2
- LDA #$0C ; 2
- LDX #$0F ; 2
- BNE .setAud0 ; 2
- ; make some noise, depending on jet speed:
- .jetSound:
- LDA speedY ; 3 frequency depends on y-speed
- LSR ; 2
- LSR ; 2
- LSR ; 2
- LSR ; 2
- EOR #$FF ; 2
- SEC ; 2
- ADC #$1F ; 2
- TAY ; 2
- LDA joystick ; 3 volume depends on joystick position
- AND #MOVE_UP|MOVE_DOWN; 2
- TAX ; 2
- LDA VolumeTab,X ; 4
- TAX ; 2
- LDA #$08 ; 2 white noise
- .setAud0:
- STA AUDC0 ; 3
- STY AUDF0 ; 3
- .mute0:
- STX AUDV0 ; 3
- ; continue with channel 1:
- ; (missile fire or bridge explosion)
- LDA missileSound ; 3
- BEQ .noMissileSound ; 2
- DEC missileSound ; 5
- LDX bridgeSound ; 3 bridge exposion has higher priority
- BNE .doBridge ; 2
- EOR #$FF ; 2
- SEC ; 2
- ADC #$1C ; 2
- LDY #$0C ; 2 medium pure tone
- LDX #$08 ; 2
- BNE .setAud1 ; 2
- .noMissileSound:
- LDX bridgeSound ; 3
- BEQ .skipSound1 ; 2
- ; let the bridge explode:
- .doBridge:
- DEC bridgeSound ; 5 countdown volume
- TXA ; 2
- LSR ; 2
- CLC ; 2
- ADC #$04 ; 2
- TAX ; 2
- LDA random ; 3 random frequency
- ORA #$18 ; 2
- LDY #$08 ; 2
- .setAud1:
- STA AUDF1 ; 3
- STY AUDC1 ; 3
- .skipSound1:
- STX AUDV1 ; 3
- ; start next frame:
- .waitTim:
- LDA INTIM ; 4
- BNE .waitTim ; 2
- LDY #$82 ; 2
- STY WSYNC ; 3
- STY VSYNC ; 3
- STY WSYNC ; 3
- STY WSYNC ; 3
- STY WSYNC ; 3
- STA VSYNC ; 3
- IF NTSC
- LDA #43 ; 2
- ELSE
- LDA #73 ; 2
- ENDIF
- STA TIM64T ; 4
- ; *** check switches: ***
- LDA SWCHB ; 4
- LSR ; 2
- BCS .noReset ; 2
- LDA gameVariation ; 3 RESET was pressed
- STA player ; 3
- LDX #$F7 ; 2
- JMP Reset ; 3
- .noReset:
- LSR ; 2
- BCS .noSelect ; 2
- DEC gameDelay ; 5 SELECT was pressed
- BPL .skipSelect ; 2
- LDA gameVariation ; 3 toggle game (one or two player)
- EOR #$01 ; 2
- STA gameVariation ; 3
- IF SCREENSAVER
- STA SS_Delay ; 3
- ELSE
- FILL_NOP 2
- ENDIF
- STA player ; 3
- ASL ; 2
- ASL ; 2
- ASL ; 2
- ADC #DIGIT_H ; 2
- JSR SetScorePtrs ; 6
- JSR FinishGame ; 6
- LDY #$1E ; 2
- .noSelect:
- STY gameDelay ; 3
- .skipSelect:
- LDA gameMode ; 3
- BMI .mainLoopJmp ; 2
- CMP #INTRO_SCROLL ; 2 scrolling into game
- BNE .setBlockVars ; 2 no, generate new blocks
- LDA #<JetStraight-1 ; 2 yes, set..
- STA shapePtr0 ; 3 ..jet data pointer..
- .mainLoopJmp:
- JMP MainLoop ; 3 .. and continue with main loop
- ; check, if a new block is neccessary:
- .setBlockVars:
- LDA #3-1 ; 2 add speedY*3 to blockOffset -> max. speed = 3 lines/frame
- STA blockNum ; 3
- .loopNext:
- DEC blockNum ; 5
- BMI .mainLoopJmp ; 2
- LDA speedY ; 3
- CMP #$FE ; 2 maximum speed?
- BCS .incOffset ; 2 yes, increase offset
- ADC posYLo ; 3
- STA posYLo ; 3
- BCC .loopNext ; 2
- .incOffset:
- INC blockOffset ; 5
- LDA blockOffset ; 3
- CMP #BLOCK_SIZE ; 2
- BCC .loopNext ; 2
- ; *** it#s time to create a new block: ***
- LDX #0 ; 2
- STX blockOffset ; 3
- LDY #NUM_BLOCKS ; 2
- STY temp ; 3 move 6 blocks
- LDA level ; 3
- CMP #5 ; 2 first four levels?
- BCC .firstLevels ; 2 yes, prevent small valley
- LDY #0 ; 2 no, allow all widths of valley
- .firstLevels:
- STY valleyWidth ; 3 0 = all widths allowed, 6 = limited widths
- ; first move the other blocks, to make space for the new one:
- .loopBlocks: ;
- LDY #5 ; 2 move 5 bytes
- .loopMoveBlock:
- LDA blockLst+1,X ; 4
- STA blockLst,X ; 4
- INX ; 2
- DEY ; 2
- BNE .loopMoveBlock ; 2
- INX ; 2 skip one entry
- DEC temp ; 5
- BNE .loopBlocks ; 2
- STY State1LstEnd ; 3 y=0!
- LDA blockLstEnd ; 3 clear variable (except PF_COLOR_FLAG)
- AND #PF_COLOR_FLAG ; 2
- STA blockLstEnd ; 3
- LDX PF1PatId ; 3 copy previous PF pattern id
- STX prevPF1PatId ; 3
- DEC blockPart ; 5 second part of block?
- BEQ .nextBlock ; 2 yes, next block
- LDX sectionBlock ; 3
- DEX ; 2 first part of last block of section?
- BNE .notLast ; 2 no, continue part
- ; the last block of a section has to be a road with bridge:
- STX sectionEnd ; 3 yes, end of current section
- LDA level ; 3
- LSR ; 2 straight current level?
- LDA #PF_ROAD_FLAG ; 2
- BCS .isStraight ; 2 yes, dark green in NEXT level
- LDA #PF_ROAD_FLAG|PF_COLOR_FLAG; 2 no, lighter green in NEXT level
- .isStraight:
- STA blockLstEnd ; 3
- .notLast:
- JSR NextRandom16 ; 6 new random number for next part of block
- JMP .nextBlockPart ; 3
- ; continue with a 'normal' block:
- .nextBlock:
- DEC sectionBlock ; 5 last block of section?
- BNE .contSection ; 2 no, continue
- JSR SaveSection ; 6 yes, save variables..
- LDX #SECTION_BLOCKS ; 2 ..and got next level
- STX sectionBlock ; 3
- .contSection:
- JSR NextRandom16 ; 6 new random number for next block
- LDX sectionBlock ; 3
- DEX ; 2 last block of section?
- BNE .notLastBlock ; 2 no, skip
- STX PF_State ; 3 yes, PF-State = static
- LDA #12 ; 2 pattern-id for last block (with bridge)
- BNE .setPF1Id ; 3
- .notLastBlock:
- LDA level ; 3
- LSR ; 2 straight level?
- LDA #7 ; 2 pattern-id for straight block
- BCS .setPF1Id ; 2 yes, set
- LDA PF_State ; 3
- DEX ; 2 last but one block of section?
- BNE .notLastButOne ; 2 no, skip
- ; finish island before end of section:
- CMP #ISLAND_FLAG|CHANGE_FLAG; 2 both flags set?
- BEQ .isSetBoth ; 2 yes, 11 -> 10 (1. step to finish island)
- BNE .clearBoth ; 3 no, static PF and no island (2. step to finish island)
- ; change PF_State bits 7 & 6:
- ; 00 -> 01/00 static -> changing or static
- ; 01 -> 11 changing -> island & changing
- ; 10 -> 00 island & static -> static (JTZ: ???)
- ; 11 -> 10/11 island & changing -> island & changing or static
- .notLastButOne:
- ASL ; 2
- EOR PF_State ; 3 CHANGE_FLAG != ISLAND_FLAG?
- BMI .updateFlags ; 2 yes, change flags
- LDA randomLo ; 3 randomly change state?
- AND #%00110000 ; 2
- BNE .skipFlags ; 2 no, don't change state (75%)
- .isSetBoth:
- LDA PF_State ; 3
- AND #ISLAND_FLAG ; 2 ISLAND_FLAG set?
- BNE .isIsland ; 2 yes, clear CHANGE_FLAG
- ORA #CHANGE_FLAG ; 2 no, set CHANGE_FLAG
- .isIsland:
- STA PF_State ; 3
- LDA #0 ; 2
- BEQ .setPF1Id ; 3
- .updateFlags:
- ; change flags: 01 -> 11, 10 -> 00
- LDA #ISLAND_FLAG|CHANGE_FLAG; 2
- BIT PF_State ; 3 CHANGE_FLAG set?
- BVS .setBoth ; 2 yes, set ISLAND_FLAG
- .clearBoth:
- LDA #0 ; 2 no, clear both flags
- .setBoth:
- STA PF_State ; 3
- .skipFlags:
- ; create new random PF id:
- ; (JTZ: I'm not 100% sure, that I understand everything completely)
- LDY #14 ; 2 y = 14
- LDA randomLo ; 3
- AND #$0F ; 2
- CMP #2 ; 2
- BCS .minOk ; 2
- ADC #2 ; 2 minimum = 2
- .minOk: ; a = 2..15
- BIT PF_State ; 3 ISLAND_FLAG set?
- BPL .skipDey ; 2 no, skip
- DEY ; 2 y = 13
- .skipDey:
- LDX valleyWidth ; 3 all widths allowed?
- BEQ .allWidths ; 2 yes, skip limit
- LDY #8 ; 2 y = 8
- .allWidths:
- STY temp ; 3 save max. allowed id
- CMP temp ; 3 random id < max. id?
- BCC .setPF1Id ; 2 yes, skip
- LDA temp ; 3 no, use max. id
- .setPF1Id:
- STA PF1PatId ; 3 a = 2..8 or 2..13/14
- LDY #BLOCK_PARTS ; 2 reset blockPart
- STY blockPart ; 3
- .nextBlockPart:
- LDA prevPF1PatId ; 3
- TAX ; 2
- SEC ; 2
- SBC PF1PatId ; 3
- STA diffPF ; 3 store the difference between the two blocks
- BCS .biggerPrev ; 2
- ; new id is bigger:
- INC diffPF ; 5
- CPX #SWITCH_PAGE_ID-1 ; 2
- LDX PF1PatId ; 3
- BCS .prevBigId ; 2
- CPX #SWITCH_PAGE_ID ; 2
- BCC .page1Id ; 2
- LDA #-1 ; 2
- ADC prevPF1PatId ; 3 CF=1! (JTZ: what's that good for?)
- BPL .prevId ; 3
- ; old id is bigger or equal:
- .biggerPrev:
- BEQ .equalId ; 2
- DEC diffPF ; 5 -1
- .equalId:
- CPX #SWITCH_PAGE_ID ; 2
- BCS .page0Id ; 2
- ; not enough space for an island:
- .page1Id:
- JSR GetPageFlag ; 6
- JSR LoadPFPattern ; 6 a = 0/1
- STA PF1LstEnd ; 3
- LDA #0 ; 2
- STA PF2LstEnd ; 3
- BEQ .contPage1 ; 3
- ; enough space for an island in previous block:
- .page0Id:
- LDA PF1PatId ; 3
- CMP #SWITCH_PAGE_ID-1 ; 2
- BCS .prevBigId ; 2
- ; enough space for an island in both blocks:
- LDA #14+1 ; 2
- SBC PF1PatId ; 3 CF=0!
- BCS .prevId ; 3 negate id (inverts pattern)
- .prevBigId:
- LDA #PF1_PAGE_FLAG|PF2_PAGE_FLAG|PF_COLOR_FLAG; 2
- .prevId:
- STA PF1LstEnd ; 3
- JSR GetPageFlag ; 6
- SEC ; 2
- ROL ; 2
- JSR LoadPFPattern ; 6 a = 1/3
- .contPage1:
- BIT PF_State ; 3 ISLAND_FLAG set?
- BPL .skipSwapPF ; 2 no, don't swap
- LDA PF1LstEnd ; 3
- LDX PF2LstEnd ; 3
- STA PF2LstEnd ; 3
- STX PF1LstEnd ; 3
- .skipSwapPF:
- BIT blockLstEnd ; 3 PF_ROAD_FLAG set?
- BPL .skipRoad ; 2 no, skip
- LDA #QUAD_SIZE ; 2 yes, create road block
- STA State1LstEnd ; 3 quad size bridge
- LDY #ID_BRIDGE ; 2
- LDA #63 ; 2 x-position
- JMP .endNewShape ; 3
- .skipRoad:
- ; *** create new objects: ***
- LDY #ID_FUEL ; 2
- LDA sectionBlock ; 3
- CLC ; 2
- ADC blockPart ; 3
- CMP #SECTION_BLOCKS+BLOCK_PARTS; 2 no enemies at first part of first block of section
- BCS .newHouse ; 2
- ; create more enemies and less fuel in higher difficulty levels:
- LDA #64 ; 2
- SBC level ; 3 1..48 (CF=0!)
- ASL ; 2 a = 124..30
- CMP randomHi ; 3
- BCC .newEnemy ; 2 ~48%..88% -> more enemies, less fuel and houses
- BIT randomLo ; 3
- BVC .newFuel ; 2 ~24%.. 6% -> less fuel
- ; no enemy or fuel, create new house instead:
- .newHouse:
- DEY ; 2 y=ID_HOUSE
- LDX PF1PatId ; 3
- CPX prevPF1PatId ; 3
- BCC .currentSmaller ; 2
- LDX prevPF1PatId ; 3
- .currentSmaller: ; x = smaller id
- LDA #DOUBLE_SIZE ; 2 house is double sized
- STA State1LstEnd ; 3
- LDA level ; 3
- LSR ; 2
- BCC .notStraight ; 2
- ; create random x-position for house in straight section:
- LDA randomLo ; 3
- AND #$1F ; 2
- ADC #8 ; 2
- CMP #25 ; 2 random position fits in left bank?
- BCC .setShapeDir ; 2 yes, ok
- ADC #92 ; 2 no, position house on right bank
- BNE .setShapeDir ; 3
- ; position house in non-straight section:
- .notStraight:
- LDA ShapePosTab,X ; 4 x-pos based on PF1 id
- BIT PF_State ; 3 ISLAND_FLAG set?
- BPL .setShapeDir ; 2 no, skip
- CPX #0 ; 2 PF id = 0?
- BEQ .setShapeDir ; 2 no, skip
- LDA #71 ; 2 fixed position for a house on island
- BNE .setShapeDir ; 3
- ; create new ship, helicopter or plane:
- .newEnemy:
- LDA #%111 ; 2
- LDX level ; 3
- CPX #3 ; 2 enemy planes start at level three
- BCS .withPlanes ; 2
- LDA #%001 ; 2 limit first levels to ship and helicopter
- .withPlanes:
- AND randomHi ; 3 create random enemy object
- TAX ; 2
- LDY EnemyIdTab,X ; 4
- .newFuel:
- CPY #ID_SHIP ; 2
- BNE .noShip ; 2
- LDA #DOUBLE_SIZE ; 2 doublesize
- STA State1LstEnd ; 3
- .noShip:
- LDA PF1PatId ; 3
- CMP prevPF1PatId ; 3 new pat-id = previous pat-id?
- BNE .newId ; 2 no,
- ; position object in straight blocks:
- STA maxId ; 3
- LDA level ; 3
- LSR ; 2
- BCC .notStraight2 ; 2
- ; position object in straight section:
- LDA #106 ; 2
- LDX State1LstEnd ; 3 ship? (doublesize)
- BEQ .isShip ; 2 yes, position more right
- LDA #97 ; 2 no, position more left
- .isShip:
- SBC valleyWidth ; 3 decrease maximum position (-6) in first four levels,
- ; this avoids positioning near the river bank
- STA temp ; 3 store maximum position
- LDA randomLo ; 3
- AND #$3F ; 2
- ADC #45 ; 2
- ADC valleyWidth ; 3 increase random position in first four levels (s.a.)
- CMP temp ; 3 random position < maximum?
- BCC .setShapeDir ; 2 yes, ok
- LDA temp ; 3 no, position = maximum
- .setShapeDir:
- ; make random direction for new shape:
- BIT randomLo ; 3
- BMI .invertDirection ; 2
- BPL .endNewShape ; 3
- .newId:
- BCS .currentBigger ; 2
- LDA prevPF1PatId ; 3
- .currentBigger:
- STA maxId ; 3 maxId cointains max(prevId, newId)
- ; position object in non-straight section:
- .notStraight2:
- ; check, if there is enough space for new object:
- LDX #13 ; 2 PF id
- BIT PF_State ; 3 ISLAND_FLAG set?
- BPL .contPage12 ; 2 no, skip
- LDX #10 ; 2 yes, lower PF id
- .contPage12:
- CPX maxId ; 3
- BCS .spaceOk ; 2
- TYA ; 2
- SBC #ID_SHIP-1 ; 2 new enemy is a ship?
- BNE .spaceOk ; 2 no, skip
- STA State1LstEnd ; 3 yes, change..
- DEY ; 2 ..ship into helicopter
- .spaceOk:
- LDA maxId ; 3
- ASL ; 2
- ASL ; 2
- BEQ .posSomewhere ; 2
- BIT PF_State ; 3 ISLAND_FLAG set?
- BPL .posSomewhere ; 2 no, position somewhere
- ; position object outside:
- EOR #$FF ; 2
- ADC #81 ; 2
- BIT randomLo ; 3
- BPL .skipNeg ; 2
- EOR #$FF ; 2
- ADC #160 ; 2
- BNE .contPos ; 3
- ; position object somewhere:
- .posSomewhere:
- ADC #16 ; 2
- BIT randomLo ; 3
- BMI .doNeg ; 2
- .contPos:
- CLC ; 2
- ADC #2 ; 2
- ADC valleyWidth ; 3 keep space to river bank in first levels
- BNE .endNewShape ; 3
- .doNeg:
- EOR #$FF ; 2
- ADC #160+1 ; 2
- .skipNeg:
- CPY #ID_FUEL ; 2 position fuel 1 pixel more right
- SBC #9 ; 2
- SBC valleyWidth ; 3 keep space to river bank in first levels
- LDX State1LstEnd ; 3 double sized object? (ship, house)
- BEQ .invertDirection ; 2 no, skip
- SBC #10 ; 2 yes, move 10 pixels left
- .invertDirection:
- CPY #ID_FUEL ; 2 fuel?
- BEQ .endNewShape ; 2 yes, has constant direction
- PHA ; 3
- LDA State1LstEnd ; 3
- ORA #DIRECTION_FLAG ; 2 set direction flag
- STA State1LstEnd ; 3
- PLA ; 4
- .endNewShape:
- STY Shape1IdLstEnd ; 3 save id of new object
- JSR CalcPosX ; 6
- STY XPos1LstEnd ; 3 save coarse x-positioning value
- ORA State1LstEnd ; 3
- STA State1LstEnd ; 3 save fine x-positioning value
- JMP .loopNext ; 3
- ; ****************************** end of main loop ******************************
- GameInit SUBROUTINE
- ; Input: x (= 22/38, number of initialized variables)
- ; initializes some variables for new game:
- .initLoop:
- LDA InitTab,X ; 4
- STA PF1Lst,X ; 4
- DEX ; 2
- BPL .initLoop ; 2
- ; clear some variables for new game:
- LDA #0 ; 2
- LDX #30 ; 2
- .loopClear:
- STA dXSpeed,X ; 4
- DEX ; 2
- BPL .loopClear ; 2
- LDX #NUM_BLOCKS-1 ; 2
- LDY #PF1_PAGE_FLAG ; 2
- LDA level ; 3
- LSR ; 2 straight level?
- BCC .loopSet ; 2 no, skip
- LDY #PF1_PAGE_FLAG|PF_COLOR_FLAG; 2 yes, set brighter green in current level
- .loopSet:
- STY blockLst,X ; 4
- DEX ; 2
- BPL .loopSet ; 2
- RTS ; 6
- IF NTSC
- LoadPFPattern SUBROUTINE
- BIT PF_State ; 3 ISLAND_FLAG set?
- BPL .contPage1 ; 2 no, set current page-flag
- TAY ; 2 yes, read new page-flag from table
- LDA PageFlagTab,Y ; 4
- .contPage1:
- ORA blockLstEnd ; 3
- STA blockLstEnd ; 3
- LDA BankPtrTab,X ; 4 load a pattern for the river bank
- CLC ; 2
- ADC diffPF ; 3 adjust with difference between new and prev PF id
- STA PF2LstEnd ; 3
- RTS ; 6
- ELSE
- FinishDigits SUBROUTINE
- INY ; 2
- STA WSYNC ; 3
- STA HMOVE ; 3
- STY GRP1 ; 3
- STY GRP0 ; 3
- STY GRP1 ; 3
- LDY #14 ; 2 load line counter
- SetColPx:
- STA COLUP0 ; 3
- STA COLUP1 ; 3
- DoHMove:
- STA WSYNC ; 3
- STA HMOVE ; 3
- RTS ; 6
- ENDIF
- NextRandom16 SUBROUTINE
- ; implements a 16 bit LFSR which generates a new random number:
- LDA randomHi ; 3
- ASL ; 2
- ASL ; 2
- ASL ; 2
- EOR randomHi ; 3
- ASL ; 2
- ROL randomLo ; 5
- ROL randomHi ; 5
- ; (JTZ: randomHi is very random, randomLo is NOT when more than one bit is used,
- ; because: randomLo[x+1] = randomLo[x]*2 + 0/1, but randomLo is used more often,
- ; randomHi only for new enemy and which. This could make the game a bit predictable.)
- RTS ; 6
- SaveSection SUBROUTINE
- ; called at the start of a new section, increases difficulty level
- ; and saves random variables to be able to restart this section
- LDX level ; 3 limit level to 48
- CPX #MAX_LEVEL ; 2
- BCC .notMax ; 2
- LDX #MAX_LEVEL-2 ; 2 go back to 47
- .notMax:
- LDA randomLoSave ; 3
- STA randomLoSave2 ; 3
- LDA randomHiSave ; 3
- STA randomHiSave2 ; 3
- LDA randomLo ; 3
- STA randomLoSave ; 3
- LDA randomHi ; 3
- STA randomHiSave ; 3
- INX ; 2
- STX level ; 3 1..48
- RTS ; 6
- SetPosX SUBROUTINE
- ; calculates the values and positions objects:
- JSR CalcPosX ; 6
- SetPosX2:
- STA HMP0,X ; 4
- INY ; 2
- INY ; 2
- INY ; 2
- STA WSYNC ; 3
- .waitPos:
- DEY ; 2
- BPL .waitPos ; 2
- STA RESP0,X ; 4
- RTS ; 6
- ;===============================================================================
- ; R O M - T A B L E S (Part 1)
- ;===============================================================================
- align 256
- Zero:
- .byte $3C ; | XXXX | $FB00
- .byte $66 ; | XX XX |
- .byte $66 ; | XX XX |
- .byte $66 ; | XX XX |
- .byte $66 ; | XX XX |
- .byte $66 ; | XX XX |
- .byte $66 ; | XX XX |
- .byte $3C ; | XXXX |
- One:
- .byte $3C ; | XXXX |
- .byte $18 ; | XX |
- .byte $18 ; | XX |
- .byte $18 ; | XX |
- .byte $18 ; | XX |
- .byte $18 ; | XX |
- .byte $38 ; | XXX |
- .byte $18 ; | XX |
- Two:
- .byte $7E ; | XXXXXX |
- .byte $60 ; | XX |
- .byte $60 ; | XX |
- .byte $3C ; | XXXX |
- .byte $06 ; | XX |
- .byte $06 ; | XX |
- .byte $46 ; | X XX |
- .byte $3C ; | XXXX |
- Three:
- .byte $3C ; | XXXX |
- .byte $46 ; | X XX |
- .byte $06 ; | XX |
- .byte $0C ; | XX |
- .byte $0C ; | XX |
- .byte $06 ; | XX |
- .byte $46 ; | X XX |
- .byte $3C ; | XXXX |
- Four:
- .byte $0C ; | XX |
- .byte $0C ; | XX |
- .byte $0C ; | XX |
- .byte $7E ; | XXXXXX |
- .byte $4C ; | X XX |
- .byte $2C ; | X XX |
- .byte $1C ; | XXX |
- .byte $0C ; | XX |
- Five:
- .byte $7C ; | XXXXX |
- .byte $46 ; | X XX |
- .byte $06 ; | XX |
- .byte $06 ; | XX |
- .byte $7C ; | XXXXX |
- .byte $60 ; | XX |
- .byte $60 ; | XX |
- .byte $7E ; | XXXXXX |
- Six:
- .byte $3C ; | XXXX |
- .byte $66 ; | XX XX |
- .byte $66 ; | XX XX |
- .byte $66 ; | XX XX |
- .byte $7C ; | XXXXX |
- .byte $60 ; | XX |
- .byte $62 ; | XX X |
- .byte $3C ; | XXXX |
- Seven:
- .byte $18 ; | XX |
- .byte $18 ; | XX |
- .byte $18 ; | XX |
- .byte $18 ; | XX |
- .byte $0C ; | XX |
- .byte $06 ; | XX |
- .byte $42 ; | X X |
- .byte $7E ; | XXXXXX |
- Eight:
- .byte $3C ; | XXXX |
- .byte $66 ; | XX XX |
- .byte $66 ; | XX XX |
- .byte $3C ; | XXXX |
- .byte $3C ; | XXXX |
- .byte $66 ; | XX XX |
- .byte $66 ; | XX XX |
- .byte $3C ; | XXXX |
- Nine:
- .byte $3C ; | XXXX |
- .byte $46 ; | X XX |
- .byte $06 ; | XX |
- .byte $3E ; | XXXXX |
- .byte $66 ; | XX XX |
- .byte $66 ; | XX XX |
- .byte $66 ; | XX XX |
- .byte $3C ; | XXXX |
- MaxOut:
- .byte $18 ; | XX |
- .byte $18 ; | XX |
- .byte $00 ; | |
- .byte $18 ; | XX |
- .byte $18 ; | XX |
- .byte $18 ; | XX |
- .byte $18 ; | XX |
- .byte $18 ; | XX |
- Space:
- .byte $00 ; | |
- Copyright0:
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $F7 ; |XXXX XXX|
- .byte $95 ; |X X X X|
- .byte $87 ; |X XXX|
- .byte $80 ; |X |
- .byte $90 ; |X X |
- .byte $F0 ; |XXXX |
- Copyright1:
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $47 ; | X XXX|
- .byte $41 ; | X X|
- .byte $77 ; | XXX XXX|
- .byte $55 ; | X X X X|
- .byte $75 ; | XXX X X|
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- Copyright2:
- .byte $AD ; |X X XX X|
- .byte $A9 ; |X X X X|
- .byte $E9 ; |XXX X X|
- .byte $A9 ; |X X X X|
- .byte $ED ; |XXX XX X|
- .byte $41 ; | X X|
- .byte $0F ; | XXXX|
- .byte $00 ; | |
- .byte $03 ; | XX|
- .byte $00 ; | |
- .byte $4B ; | X X XX|
- .byte $4A ; | X X X |
- .byte $6B ; | XX X XX|
- .byte $00 ; | |
- .byte $08 ; | X |
- .byte $00 ; | |
- Copyright3:
- .byte $50 ; | X X |
- .byte $58 ; | X XX |
- .byte $5C ; | X XXX |
- .byte $56 ; | X X XX |
- .byte $53 ; | X X XX|
- .byte $11 ; | X X|
- .byte $F0 ; |XXXX |
- .byte $00 ; | |
- .byte $80 ; |X |
- .byte $80 ; |X |
- .byte $AA ; |X X X X |
- .byte $AA ; |X X X X |
- .byte $BA ; |X XXX X |
- .byte $22 ; | X X |
- .byte $27 ; | X XXX|
- .byte $02 ; | X |
- Copyright4:
- .byte $BA ; |X XXX X |
- .byte $8A ; |X X X |
- .byte $BA ; |X XXX X |
- .byte $A2 ; |X X X |
- .byte $3A ; | XXX X |
- .byte $80 ; |X |
- .byte $FE ; |XXXXXXX |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $11 ; | X X|
- .byte $11 ; | X X|
- .byte $17 ; | X XXX|
- .byte $15 ; | X X X|
- .byte $17 ; | X XXX|
- .byte $00 ; | |
- Copyright5:
- .byte $E9 ; |XXX X X|
- .byte $AB ; |X X X XX|
- .byte $AF ; |X X XXXX|
- .byte $AD ; |X X XX X|
- .byte $E9 ; |XXX X X|
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $77 ; | XXX XXX|
- .byte $54 ; | X X X |
- .byte $77 ; | XXX XXX|
- .byte $51 ; | X X X|
- .byte $77 ; | XXX XXX|
- PageFlagTab:
- .byte 0, PF2_PAGE_FLAG, PF1_PAGE_FLAG, PF1_PAGE_FLAG|PF2_PAGE_FLAG ; PF1_PAGE_FLAG unused!
- shapePtr1bTab:
- .byte <Explosion0-1, <Explosion1B-1, <Explosion2B-1, <Explosion1B-1
- .byte <PlaneB-1, <Heli0B-1, <Heli1B-1, <ShipB-1, <BridgeB-1, <HouseB-1, <FuelB-1
- ; x-positions of new object:
- ShapePosTab:
- .byte 143, 141, 7, 10, 132, 13, 128, 18, 124, 22, 120, 26, 116, 30, 112
- ;===============================================================================
- ; R O M - C O D E (Part 2)
- ;===============================================================================
- SetPFxPtr SUBROUTINE
- ; called from kernel, sets pointers for new playfield data:
- LDA PF1Lst,X ; 4
- STA PF1Ptr ; 3
- LDA blockLst,X ; 4
- AND #PF1_PAGE_FLAG ; 2
- ORA #>PFPat0 ; 2
- STA PF1Ptr+1 ; 3
- LDA PF2Lst,X ; 4
- STA PF2Ptr ; 3
- LDA blockLst,X ; 4
- LSR ; 2
- AND #PF2_PAGE_FLAG>>1 ; 2
- ORA #>PFPat0 ; 2
- STA PF2Ptr+1 ; 3
- RTS ; 6 = 44
- ;===============================================================================
- ; R O M - T A B L E S (Part 2)
- ;===============================================================================
- ; high addresses of entry points into kernel:
- JmpHiTab:
- .byte >[JmpPoint0-1], >[JmpPoint1-1], >[JmpPoint2-1], >[JmpPoint3-1], >[JmpPoint4-1]
- .byte >[JmpPoint5-1], >[JmpPoint6-1], >[JmpPoint7-1], >[JmpPoint8-1], >[JmpPoint9-1]
- ; used to animate explosions and helicopter:
- AnimateIdTab:
- .byte 0 ;
- .byte ID_EXPLOSION2 ; start of explosion sequence
- .byte ID_EXPLOSION3 ;
- .byte ID_EXPLOSION0 ; end explosion with 0
- .byte ID_PLANE ; no animation for plane
- .byte ID_HELI1 ; switch between..
- .byte ID_HELI0 ; ..ID_HELI0 and ID_HELI1
- ; these are the patterns, that are used to define the playfield:
- PFPat0:
- .byte $00 ; | | $FC00
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $01 ; | X|
- .byte $03 ; | XX|
- .byte $07 ; | XXX|
- .byte $0F ; | XXXX|
- .byte $1F ; | XXXXX|
- PFPat14:
- .byte $3F ; | XXXXXX|
- .byte $3F ; | XXXXXX|
- .byte $3F ; | XXXXXX|
- .byte $3F ; | XXXXXX|
- .byte $3F ; | XXXXXX|
- .byte $3F ; | XXXXXX|
- .byte $3F ; | XXXXXX|
- .byte $3F ; | XXXXXX|
- .byte $3F ; | XXXXXX|
- .byte $3F ; | XXXXXX|
- .byte $3F ; | XXXXXX|
- .byte $3F ; | XXXXXX|
- .byte $3F ; | XXXXXX|
- .byte $3F ; | XXXXXX|
- .byte $3F ; | XXXXXX|
- .byte $3F ; | XXXXXX|
- .byte $1F ; | XXXXX|
- .byte $0F ; | XXXX|
- .byte $07 ; | XXX|
- .byte $03 ; | XX|
- .byte $01 ; | X|
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $01 ; | X|
- .byte $03 ; | XX|
- .byte $07 ; | XXX|
- .byte $0F ; | XXXX|
- PFPat13:
- .byte $1F ; | XXXXX|
- .byte $1F ; | XXXXX|
- .byte $1F ; | XXXXX|
- .byte $1F ; | XXXXX|
- .byte $1F ; | XXXXX|
- .byte $1F ; | XXXXX|
- .byte $1F ; | XXXXX|
- .byte $1F ; | XXXXX|
- .byte $1f ; | XXXXX|
- .byte $1F ; | XXXXX|
- .byte $1F ; | XXXXX|
- .byte $1F ; | XXXXX|
- .byte $1F ; | XXXXX|
- .byte $1F ; | XXXXX|
- .byte $1F ; | XXXXX|
- .byte $1F ; | XXXXX|
- .byte $0F ; | XXXX|
- .byte $07 ; | XXX|
- .byte $03 ; | XX|
- .byte $01 ; | X|
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $01 ; | X|
- .byte $03 ; | XX|
- .byte $07 ; | XXX|
- PFPat12:
- .byte $0F ; | XXXX|
- .byte $0F ; | XXXX|
- .byte $0F ; | XXXX|
- .byte $0F ; | XXXX|
- .byte $0F ; | XXXX|
- .byte $0F ; | XXXX|
- .byte $0F ; | XXXX|
- .byte $0F ; | XXXX|
- .byte $0F ; | XXXX|
- .byte $0F ; | XXXX|
- .byte $0F ; | XXXX|
- .byte $0F ; | XXXX|
- .byte $0F ; | XXXX|
- .byte $0F ; | XXXX|
- .byte $0F ; | XXXX|
- .byte $0F ; | XXXX|
- .byte $07 ; | XXX|
- .byte $03 ; | XX|
- .byte $01 ; | X|
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $01 ; | X|
- .byte $03 ; | XX|
- PFPat11:
- .byte $07 ; | XXX|
- .byte $07 ; | XXX|
- .byte $07 ; | XXX|
- .byte $07 ; | XXX|
- .byte $07 ; | XXX|
- .byte $07 ; | XXX|
- .byte $07 ; | XXX|
- .byte $07 ; | XXX|
- .byte $07 ; | XXX|
- .byte $07 ; | XXX|
- .byte $07 ; | XXX|
- .byte $07 ; | XXX|
- .byte $07 ; | XXX|
- .byte $07 ; | XXX|
- .byte $07 ; | XXX|
- .byte $07 ; | XXX|
- .byte $03 ; | XX|
- .byte $01 ; | X|
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $01 ; | X|
- PFPat10:
- .byte $03 ; | XX|
- .byte $03 ; | XX|
- .byte $03 ; | XX|
- .byte $03 ; | XX|
- .byte $03 ; | XX|
- .byte $03 ; | XX|
- .byte $03 ; | XX|
- .byte $03 ; | XX|
- .byte $03 ; | XX|
- .byte $03 ; | XX|
- .byte $03 ; | XX|
- .byte $03 ; | XX|
- .byte $03 ; | XX|
- .byte $03 ; | XX|
- .byte $03 ; | XX|
- .byte $03 ; | XX|
- .byte $01 ; | X|
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- PFPat9:
- .byte $01 ; | X|
- .byte $01 ; | X|
- .byte $01 ; | X|
- .byte $01 ; | X|
- .byte $01 ; | X|
- .byte $01 ; | X|
- .byte $01 ; | X|
- .byte $01 ; | X|
- .byte $01 ; | X|
- .byte $01 ; | X|
- .byte $01 ; | X|
- .byte $01 ; | X|
- .byte $01 ; | X|
- .byte $01 ; | X|
- .byte $01 ; | X|
- .byte $01 ; | X|
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- JetStraight:
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $2A ; | X X X |
- .byte $3E ; | XXXXX |
- .byte $1C ; | XXX |
- .byte $08 ; | X |
- .byte $49 ; | X X X|
- .byte $6B ; | XX X XX|
- .byte $7F ; | XXXXXXX|
- .byte $7F ; | XXXXXXX|
- .byte $3E ; | XXXXX |
- .byte $1C ; | XXX |
- .byte $08 ; | X |
- .byte $08 ; | X |
- .byte $08 ; | X |
- JetMove:
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $02 ; | X |
- .byte $2E ; | X XXX |
- .byte $3C ; | XXXX |
- .byte $18 ; | XX |
- .byte $08 ; | X |
- .byte $0A ; | X X |
- .byte $2E ; | X XXX |
- .byte $3E ; | XXXXX |
- .byte $3E ; | XXXXX |
- .byte $3C ; | XXXX |
- .byte $18 ; | XX |
- .byte $08 ; | X |
- .byte $08 ; | X |
- .byte $08 ; | X |
- JetExplode:
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $02 ; | X |
- .byte $08 ; | X |
- .byte $10 ; | X |
- .byte $00 ; | |
- .byte $40 ; | X |
- .byte $08 ; | X |
- .byte $21 ; | X X|
- .byte $44 ; | X X |
- .byte $10 ; | X |
- .byte $04 ; | X |
- .byte $08 ; | X |
- .byte $00 ; | |
- ; low pointers to the patterns for the river bank:
- BankPtrTab: ; $FCF1
- .byte <PFPat0, <PFPat1, <PFPat2, <PFPat3, <PFPat4, <PFPat5, <PFPat6, <PFPat7, <PFPat8
- ; last patterns are only used for islands:
- .byte <PFPat9, <PFPat10, <PFPat11, <PFPat12, <PFPat13, <PFPat14
- align 256
- .byte $80 ; |X | $FD00
- .byte $C0 ; |XX |
- .byte $E0 ; |XXX |
- .byte $F0 ; |XXXX |
- .byte $F8 ; |XXXXX |
- .byte $FC ; |XXXXXX |
- .byte $FE ; |XXXXXXX |
- PFPat8:
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FE ; |XXXXXXX |
- .byte $FC ; |XXXXXX |
- .byte $F8 ; |XXXXX |
- .byte $F0 ; |XXXX |
- .byte $E0 ; |XXX |
- .byte $C0 ; |XX |
- .byte $80 ; |X |
- .byte $C0 ; |XX |
- .byte $E0 ; |XXX |
- .byte $F0 ; |XXXX |
- .byte $F8 ; |XXXXX |
- .byte $FC ; |XXXXXX |
- PFPat7:
- .byte $FE ; |XXXXXXX |
- .byte $FE ; |XXXXXXX |
- .byte $FE ; |XXXXXXX |
- .byte $FE ; |XXXXXXX |
- .byte $FE ; |XXXXXXX |
- .byte $FE ; |XXXXXXX |
- .byte $FE ; |XXXXXXX |
- .byte $FE ; |XXXXXXX |
- .byte $FE ; |XXXXXXX |
- .byte $FE ; |XXXXXXX |
- .byte $FE ; |XXXXXXX |
- .byte $FE ; |XXXXXXX |
- .byte $FE ; |XXXXXXX |
- .byte $FE ; |XXXXXXX |
- .byte $FE ; |XXXXXXX |
- .byte $FE ; |XXXXXXX |
- .byte $FC ; |XXXXXX |
- .byte $F8 ; |XXXXX |
- .byte $F0 ; |XXXX |
- .byte $E0 ; |XXX |
- .byte $C0 ; |XX |
- .byte $80 ; |X |
- .byte $C0 ; |XX |
- .byte $E0 ; |XXX |
- .byte $F0 ; |XXXX |
- .byte $F8 ; |XXXXX |
- PFPat6:
- .byte $FC ; |XXXXXX |
- .byte $FC ; |XXXXXX |
- .byte $FC ; |XXXXXX |
- .byte $FC ; |XXXXXX |
- .byte $FC ; |XXXXXX |
- .byte $FC ; |XXXXXX |
- .byte $FC ; |XXXXXX |
- .byte $FC ; |XXXXXX |
- .byte $FC ; |XXXXXX |
- .byte $FC ; |XXXXXX |
- .byte $FC ; |XXXXXX |
- .byte $FC ; |XXXXXX |
- .byte $FC ; |XXXXXX |
- .byte $FC ; |XXXXXX |
- .byte $FC ; |XXXXXX |
- .byte $FC ; |XXXXXX |
- .byte $F8 ; |XXXXX |
- .byte $F0 ; |XXXX |
- .byte $E0 ; |XXX |
- .byte $C0 ; |XX |
- .byte $80 ; |X |
- .byte $C0 ; |XX |
- .byte $E0 ; |XXX |
- .byte $F0 ; |XXXX |
- PFPat5:
- .byte $F8 ; |XXXXX |
- .byte $F8 ; |XXXXX |
- .byte $F8 ; |XXXXX |
- .byte $F8 ; |XXXXX |
- .byte $F8 ; |XXXXX |
- .byte $F8 ; |XXXXX |
- .byte $F8 ; |XXXXX |
- .byte $F8 ; |XXXXX |
- .byte $F8 ; |XXXXX |
- .byte $F8 ; |XXXXX |
- .byte $F8 ; |XXXXX |
- .byte $F8 ; |XXXXX |
- .byte $F8 ; |XXXXX |
- .byte $F8 ; |XXXXX |
- .byte $F8 ; |XXXXX |
- .byte $F8 ; |XXXXX |
- .byte $F0 ; |XXXX |
- .byte $E0 ; |XXX |
- .byte $C0 ; |XX |
- .byte $80 ; |X |
- .byte $C0 ; |XX |
- .byte $E0 ; |XXX |
- PFPat4:
- .byte $F0 ; |XXXX |
- .byte $F0 ; |XXXX |
- .byte $F0 ; |XXXX |
- .byte $F0 ; |XXXX |
- .byte $F0 ; |XXXX |
- .byte $F0 ; |XXXX |
- .byte $F0 ; |XXXX |
- .byte $F0 ; |XXXX |
- .byte $F0 ; |XXXX |
- .byte $F0 ; |XXXX |
- .byte $F0 ; |XXXX |
- .byte $F0 ; |XXXX |
- .byte $F0 ; |XXXX |
- .byte $F0 ; |XXXX |
- .byte $F0 ; |XXXX |
- .byte $F0 ; |XXXX |
- .byte $E0 ; |XXX |
- .byte $C0 ; |XX |
- .byte $80 ; |X |
- .byte $C0 ; |XX |
- PFPat3:
- .byte $E0 ; |XXX |
- .byte $E0 ; |XXX |
- .byte $E0 ; |XXX |
- .byte $E0 ; |XXX |
- .byte $E0 ; |XXX |
- .byte $E0 ; |XXX |
- .byte $E0 ; |XXX |
- .byte $E0 ; |XXX |
- .byte $E0 ; |XXX |
- .byte $E0 ; |XXX |
- .byte $E0 ; |XXX |
- .byte $E0 ; |XXX |
- .byte $E0 ; |XXX |
- .byte $E0 ; |XXX |
- .byte $E0 ; |XXX |
- .byte $E0 ; |XXX |
- .byte $C0 ; |XX |
- .byte $80 ; |X |
- PFPat2:
- .byte $C0 ; |XX |
- .byte $C0 ; |XX |
- .byte $C0 ; |XX |
- .byte $C0 ; |XX |
- .byte $C0 ; |XX |
- .byte $C0 ; |XX |
- .byte $C0 ; |XX |
- .byte $C0 ; |XX |
- .byte $C0 ; |XX |
- .byte $C0 ; |XX |
- .byte $C0 ; |XX |
- .byte $C0 ; |XX |
- .byte $C0 ; |XX |
- .byte $C0 ; |XX |
- .byte $C0 ; |XX |
- .byte $C0 ; |XX |
- PFPat1:
- .byte $80 ; |X |
- .byte $80 ; |X |
- .byte $80 ; |X |
- .byte $80 ; |X |
- .byte $80 ; |X |
- .byte $80 ; |X |
- .byte $80 ; |X |
- .byte $80 ; |X |
- .byte $80 ; |X |
- .byte $80 ; |X |
- .byte $80 ; |X |
- .byte $80 ; |X |
- .byte $80 ; |X |
- .byte $80 ; |X |
- .byte $80 ; |X |
- .byte $80 ; |X |
- InitTab: ; $FDB1
- .ds 6, <PFPat8 ; PF1Lst
- .ds 6, <PFPat12 ; PF2Lst
- .byte NUM_LINES+20 ; missileY
- .byte 76 ; playerX
- .byte 0 ; speedX
- .byte 254 ; speedY
- .byte 1 ;
- .byte $FF, $FF ; fuelHi, fuelLo
- .byte 17 ; sectionBlock
- .byte <PFPat0, >PFPat0 ; shapePtr0 ;22
- .byte 12 ; PF1PatId
- .byte 1 ; level
- .byte SEED_LO, SEED_HI ; randomLoSave, randomHiSave
- .byte <Space, >Space ; livesPtr
- .byte 1, SEED_LO, SEED_HI, <Space ; player2State (level, randomLoSave, randomHiSave, livesPtr)
- .byte $80 ; gameMode
- .byte <FuelA, >FuelA ; shapePtr1a
- .byte <FuelB, >FuelB ; shapePtr1b
- .byte <ShipCol-3, >ShipCol ; colorPtr
- ;===============================================================================
- ; R O M - C O D E (Part 3)
- ;===============================================================================
- CalcPosX SUBROUTINE
- ; calculates values for x-positioning:
- ; Input:
- ; - a = x-position
- ; Return:
- ; - y = coarse value for delay loop
- ; - a = fine value for HMxy
- TAY ; 2
- INY ; 2
- TYA ; 2
- AND #$0F ; 2
- STA temp2 ; 3
- TYA ; 2
- LSR ; 2
- LSR ; 2
- LSR ; 2
- LSR ; 2
- TAY ; 2
- CLC ; 2
- ADC temp2 ; 3
- CMP #$0F ; 2
- BCC .skipIny ; 2
- SBC #$0F ; 2
- INY ; 2
- .skipIny:
- EOR #$07 ; 2
- Mult16:
- ASL ; 2
- ASL ; 2
- ASL ; 2
- ASL ; 2
- Wait12:
- RTS ; 6
- ;===============================================================================
- ; R O M - T A B L E S (Part 3)
- ;===============================================================================
- ; low addresses of entry points into kernel:
- JmpLoTab:
- .byte <[JmpPoint0-1]
- .byte <[JmpPoint1-1]
- .byte <[JmpPoint2-1]
- .byte <[JmpPoint3-1]
- .byte <[JmpPoint4-1]
- .byte <[JmpPoint5-1]
- .byte <[JmpPoint6-1]
- .byte <[JmpPoint7-1]
- .byte <[JmpPoint8-1]
- .byte <[JmpPoint9-1]
- align 256
- FuelTab0:
- .byte $7F ; | XXXXXXX| $FE00
- .byte $40 ; | X |
- .byte $4F ; | X XXXX|
- .byte $48 ; | X X |
- .byte $48 ; | X X |
- .byte $4E ; | X XXX |
- .byte $48 ; | X X |
- .byte $48 ; | X X |
- .byte $4F ; | X XXXX|
- .byte $40 ; | X |
- .byte $40 ; | X |
- .byte $4C ; | X XX |
- .byte $4C ; | X XX |
- .byte $4C ; | X XX |
- .byte $7F ; | XXXXXXX|
- FuelTab1:
- .byte $FF ; |XXXXXXXX|
- Explosion0:
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- FuelTab2:
- .byte $FF ; |XXXXXXXX|
- .byte $00 ; | |
- .byte $03 ; | XX|
- .byte $C2 ; |XX X |
- .byte $63 ; | XX XX|
- .byte $30 ; | XX |
- .byte $1B ; | XX XX|
- .byte $EC ; |XXX XX |
- .byte $46 ; | X XX |
- .byte $43 ; | X XX|
- .byte $C1 ; |XX X|
- .byte $48 ; | X X |
- .byte $08 ; | X |
- .byte $08 ; | X |
- FuelTab3:
- .byte $FF ; |XXXXXXXX|
- .byte $00 ; | |
- .byte $80 ; |X |
- .byte $00 ; | |
- .byte $80 ; |X |
- .byte $80 ; |X |
- .byte $80 ; |X |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $80 ; |X |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- FuelTab4:
- .byte $FF ; |XXXXXXXX|
- .byte $01 ; | X|
- .byte $81 ; |X X|
- .byte $81 ; |X X|
- .byte $81 ; |X X|
- .byte $E1 ; |XXX X|
- .byte $81 ; |X X|
- .byte $81 ; |X X|
- .byte $F1 ; |XXXX X|
- .byte $01 ; | X|
- .byte $01 ; | X|
- .byte $19 ; | XX X|
- .byte $19 ; | XX X|
- .byte $19 ; | XX X|
- .byte $FF ; |XXXXXXXX|
- ; used to en- or disable ball in fuel display:
- ENABLTab:
- .byte DISABLE
- .byte ENABLE, ENABLE, ENABLE, ENABLE, ENABLE, ENABLE, ENABLE, ENABLE, ENABLE, ENABLE
- ; the scores to the enemy objects (bit 7 = 0: *10, = 1: *100):
- ScoreTab:
- .byte 0, 0, 0, 0 ; EXPLOSIONS
- .byte DIGIT_H * 1 | $80 ; PLANE 100
- .byte DIGIT_H * 6 ; HELI 60
- .byte DIGIT_H * 6 ; HELI 60
- .byte DIGIT_H * 3 ; SHIP 30
- .byte DIGIT_H * 5 |$80 ; BRIDGE 500
- .byte 0 ; HOUSE
- .byte DIGIT_H * 8 ; FUEL 80
- ; the data is stored for interlaced display:
- FuelA:
- .byte $FE ; |XXXXXXX |
- .byte $DE ; |XX XXXX |
- .byte $DE ; |XX XXXX |
- .byte $FE ; |XXXXXXX |
- .byte $DE ; |XX XXXX |
- .byte $DE ; |XX XXXX |
- .byte $FE ; |XXXXXXX |
- .byte $D6 ; |XX X XX |
- .byte $D6 ; |XX X XX |
- .byte $DE ; |XX XXXX |
- .byte $CE ; |XX XXX |
- FuelB:
- .byte $C6 ; |XX XX |
- .byte $DE ; |XX XXXX |
- .byte $DE ; |XX XXXX |
- .byte $C6 ; |XX XX |
- .byte $CE ; |XX XXX |
- .byte $C6 ; |XX XX |
- .byte $C6 ; |XX XX |
- .byte $D6 ; |XX X XX |
- .byte $FE ; |XXXXXXX |
- .byte $DE ; |XX XXXX |
- .byte $DE ; |XX XXXX |
- .byte $7C ; | XXXXX |
- BridgeA:
- .byte $42 ; | X X |
- BridgeB:
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $FF ; |XXXXXXXX|
- .byte $42 ; | X X |
- ShipB:
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $FC ; |XXXXXX |
- .byte $FF ; |XXXXXXXX|
- .byte $30 ; | XX |
- .byte $10 ; | X |
- PlaneA:
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $30 ; | XX |
- .byte $4F ; | X XXXX|
- .byte $C6 ; |XX XX |
- .byte $00 ; | |
- Heli1B:
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $0E ; | XXX |
- .byte $8E ; |X XXX |
- .byte $FF ; |XXXXXXXX|
- .byte $0E ; | XXX |
- .byte $07 ; | XXX|
- Heli0A:
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $04 ; | X |
- .byte $FF ; |XXXXXXXX|
- .byte $9F ; |X XXXXX|
- .byte $04 ; | X |
- .byte $07 ; | XXX|
- ShipA:
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $7C ; | XXXXX |
- .byte $FE ; |XXXXXXX |
- .byte $78 ; | XXXX |
- .byte $10 ; | X |
- PlaneB:
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $38 ; | XXX |
- .byte $FF ; |XXXXXXXX|
- .byte $80 ; |X |
- Heli1A:
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $04 ; | X |
- .byte $FF ; |XXXXXXXX|
- .byte $9F ; |X XXXXX|
- .byte $04 ; | X |
- .byte $1C ; | XXX |
- Heli0B:
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $0E ; | XXX |
- .byte $8E ; |X XXX |
- .byte $FF ; |XXXXXXXX|
- .byte $0E ; | XXX |
- .byte $1C ; | XXX |
- Explosion1B:
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $10 ; | X |
- .byte $20 ; | X |
- .byte $40 ; | X |
- .byte $10 ; | X |
- Explosion1A:
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $04 ; | X |
- .byte $02 ; | X |
- .byte $08 ; | X |
- .byte $04 ; | X |
- .byte $00 ; | |
- Explosion2B:
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $20 ; | X |
- .byte $02 ; | X |
- .byte $41 ; | X X|
- .byte $20 ; | X |
- .byte $02 ; | X |
- .byte $04 ; | X |
- Explosion2A:
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $04 ; | X |
- .byte $88 ; |X X |
- .byte $10 ; | X |
- .byte $04 ; | X |
- .byte $80 ; |X |
- .byte $10 ; | X |
- .byte $00 ; | |
- .byte $00 ; | |
- HouseB:
- .byte $00 ; | |
- .byte $04 ; | X |
- .byte $1F ; | XXXXX|
- .byte $0E ; | XXX |
- .byte $04 ; | X |
- .byte $04 ; | X |
- .byte $00 ; | |
- .byte $AA ; |X X X X |
- .byte $FE ; |XXXXXXX |
- .byte $7C ; | XXXXX |
- .byte $00 ; | |
- HouseA:
- .byte $00 ; | |
- .byte $04 ; | X |
- .byte $0E ; | XXX |
- .byte $1F ; | XXXXX|
- .byte $0E ; | XXX |
- .byte $04 ; | X |
- .byte $00 ; | |
- .byte $FE ; |XXXXXXX |
- .byte $AA ; |X X X X |
- .byte $FE ; |XXXXXXX |
- .byte $38 ; | XXX |
- .byte $00 ; | |
- .byte $00 ; | |
- .byte $00 ; | |
- ;===============================================================================
- ; R O M - C O D E (Part 4)
- ;===============================================================================
- GetPageFlag SUBROUTINE
- ; get bit 0 of the page for the playfield data:
- TXA ;2
- BEQ .exit ;2
- LDA #%0 ;2
- CPX #SWITCH_PAGE_ID ;2 PF id < 9
- BCS .exit ;2 no, read data from page $FC
- LDA #%1 ;2 yes, read data from page $FD
- .exit:
- RTS ;6
- SetScorePtrs SUBROUTINE
- STA scorePtr1+10 ;3
- STA scorePtr2+10 ;3
- ; let score-pointers point to 'Space' to avoid leading zeros:
- LDA #<Space ;2
- LDX #8 ;2
- .loopScorePtr2:
- STA scorePtr2,X ;4
- DEX ;2
- DEX ;2
- BPL .loopScorePtr2 ;2
- LDX #8 ;2
- SetScorePtr1:
- STA scorePtr1,X ;4
- DEX ;2
- DEX ;2
- BPL SetScorePtr1 ;2
- RTS ;6
- ;===============================================================================
- ; R O M - T A B L E S (Part 4)
- ;===============================================================================
- ColorPtrTab:
- .byte $49 ; explosion 0 (no extra data for explosion colors)
- .byte $2A ; explosion 1
- .byte $66 ; explosion 2
- .byte $2A ; explosion 3
- .byte <PlaneCol-6 ; plane
- .byte <HelicopterCol-4 ; helicopter
- .byte <HelicopterCol-4 ; helicopter
- .byte <ShipCol-4 ; ship
- .byte <BridgeCol-1 ; bridge
- .byte <HouseCol-2 ; house (one byte shared!)
- .byte <FuelCol-1 ; fuel (=$37)
- HouseCol:
- .byte BROWN, LIGHT_GREEN, LIGHT_GREEN, LIGHT_GREEN, LIGHT_GREEN
- .byte BLACK, LIGHT_GREY, LIGHT_GREY, BLACK, BLACK
- FuelCol:
- .byte LIGHT_GREY, LIGHT_GREY, LIGHT_GREY, RED, RED, RED
- .byte LIGHT_GREY, LIGHT_GREY, LIGHT_GREY, RED, RED, RED
- HelicopterCol:
- .byte CYAN, CYAN, DARK_BLUE, CYAN, ORANGE, ORANGE
- IF NTSC
- PlaneCol:
- .byte $AC, $9C, $8C
- ShipCol:
- .byte $A8, $32, BLACK, BLACK
- BridgeCol:
- .byte $20, $14, $12, $14, $12, $18, $12, $14, $12, $14, $20
- ELSE
- PlaneCol:
- .byte $BC, $BC, $9C
- ShipCol:
- .byte $98, $42, BLACK, BLACK
- BridgeCol:
- .byte $20, $24, $22, $24, $22, $28, $22, $24, $22, $24, $20
- .byte $B4 ; unused
- ENDIF
- ;===============================================================================
- ; R O M - C O D E (Part 5)
- ;===============================================================================
- LooseJet SUBROUTINE
- ; called when player looses a life:
- STY sound0Cnt ; 3
- STA sound0Id ; 3
- LDA blockLst ; 3
- EOR blockLstEnd ; 3
- AND #PF_COLOR_FLAG ; 2 dark section?
- BEQ .skipRestartLevel ; 2 yes, skip
- LDA sectionEnd ; 3 end of section?
- BEQ .isEnd ; 2 yes, check restart of level
- BIT blockLstEnd ; 3 road in new block?
- BPL .skipRestartLevel ; 2 no, skip
- JSR SaveSection ; 6 yes, goto next section
- BNE .skipRestartLevel ; 3
- .isEnd:
- BIT blockLstEnd ; 3 PF_ROAD_FLAG set?
- BMI .skipRestartLevel ; 2 yes, skip restart level
- ; restart level:
- LDX level ; 3 limit level to 48
- DEX ; 2
- CPX #MAX_LEVEL-2 ; 2
- BNE .skipLimit ; 2
- LDX #MAX_LEVEL ; 2
- .skipLimit:
- STX level ; 3
- LDA randomLoSave2 ; 3 retrieve saved random values
- STA randomLoSave ; 3
- LDA randomHiSave2 ; 3
- STA randomHiSave ; 3
- .skipRestartLevel:
- LDA #<JetExplode-1 ; 2
- STA shapePtr0 ; 3
- .contFinish:
- STA gameMode ; 3
- LDA #NUM_LINES+20 ; 2 disable missile
- STA missileY ; 3
- RTS ; 6
- FinishGame:
- ; called when the the game is not running:
- LDA #$FF ; 2 disable al animations
- STA frameCnt ; 3
- BNE .contFinish ; 3
- IF NTSC
- FinishDigits SUBROUTINE
- INY ; 2
- STA WSYNC ; 3
- STA HMOVE ; 3
- STY GRP1 ; 3
- STY GRP0 ; 3
- STY GRP1 ; 3
- LDY #14 ; 2 load line counter
- SetColPx:
- STA COLUP0 ; 3
- STA COLUP1 ; 3
- DoHMove:
- STA WSYNC ; 3
- STA HMOVE ; 3
- RTS ; 6
- ELSE
- LoadPFPattern SUBROUTINE
- BIT PF_State ; 3 ISLAND_FLAG set?
- BPL .contPage1 ; 2 no, set current page-flag
- TAY ; 2 yes, read new page-flag from table
- LDA PageFlagTab,Y ; 4
- .contPage1:
- ORA blockLstEnd ; 3
- STA blockLstEnd ; 3
- LDA BankPtrTab,X ; 4
- CLC ; 2
- ADC diffPF ; 3 adjust with difference between new and prev PF id
- STA PF2LstEnd ; 3
- RTS ; 6
- ENDIF
- ;===============================================================================
- ; R O M - T A B L E S (Part 5)
- ;===============================================================================
- RoadColorTab:
- .byte $04, $04, $08, $08, $08, $08, YELLOW, $08, $08, $08, $08 ; next two bytes are shared
- VolumeTab:
- .byte $04, $04 ; next byte ($07) is shared
- EnemyIdTab:
- .byte ID_SHIP, ID_HELI0, ID_SHIP, ID_HELI0, ID_PLANE, ID_SHIP, ID_HELI0, ID_HELI0
- shapePtr1aTab:
- .byte <Explosion0-1, <Explosion1A-1, <Explosion2A-1, <Explosion1A-1
- .byte <PlaneA-1, <Heli0A-1, <Heli1A-1, <ShipA-1, <BridgeA-1, <HouseA-1, <FuelA-1
- ;===============================================================================
- ; R O M - C O D E (Part 6)
- ;===============================================================================
- SwapPlayers SUBROUTINE
- ; swaps player variable blocks in two player game:
- LDA gameVariation ;3 don't swap in one player game
- BEQ .skipSwap ;2
- EOR player ;3 change player
- STA player ;3
- LDX #3 ;2
- .loopSwap0:
- LDA player1State,X ;4
- LDY player2State,X ;4
- STA player2State,X ;4
- STY player1State,X ;4
- DEX ;2
- BPL .loopSwap0 ;2
- LDX #12-2 ;2
- .loopSwap1:
- LDA scorePtr1,X ;4
- LDY scorePtr2,X ;4
- STA scorePtr2,X ;4
- STY scorePtr1,X ;4
- DEX ;2
- DEX ;2
- BPL .loopSwap1 ;2
- .skipSwap:
- RTS ;6
- ;===============================================================================
- ; R O M - T A B L E S (Part 6)
- ;===============================================================================
- ColorTab:
- .byte 0, YELLOW, GREY, YELLOW+2, BLUE
- .word START
- .word 0
Add Comment
Please, Sign In to add comment