;---------------------------------------------------------------------------

;   * Subject: [stella] Source (fwd)
;   * From: Glenn Saunders <krishna@primenet.com>
;   * Date: Thu, 17 Apr 1997 21:09:46 -0700 (PDT)

;---------------------------------------------------------------------------

; Here is the source file to Activision's Freeway, which was reconstructed
; by hand and extensively commented by "Burger" Bill Heineman.  He assures
; me this is legal, and although I'm not going to go out of my way to
; distribute this, I feel that the subscribers of the mailing list should
; study it.

        LST     OFF
        TR      ON

*
* Equates for all the WRITE only registers for the
* Atari 2600
*

VSYNC   =       $00     ;Vertical sync set-clear
VBLANK  =       $01     ;Vertical blank set-clear
WSYNC   =       $02     ;Wait for leading edge of horizontal blank
RSYNC   =       $03     ;Reset horizontal sync counter
NUSIZ0  =       $04     ;Number size Player Missile 0
NUSIZ1  =       $05     ;Number size Player Missile 1
COLUP0  =       $06     ;Color-lum Player 0
COLUP1  =       $07     ;Color-lum Player 1
COLUPF  =       $08     ;Color-lum playfield
COLUBK  =       $09     ;Color-lum background
CTRLPF  =       $0A     ;Ctrol playfield ball size & collisions
REFP0   =       $0B     ;Reflect player #0
REFP1   =       $0C     ;Reflect player #1
PF0     =       $0D     ;First 4 bits of playfield
PF1     =       $0E     ;Middle 8 bits of playfield
PF2     =       $0F     ;Last 8 bits of playfield
RESP0   =       $10     ;Reset player #0 X coord
RESP1   =       $11     ;Reset player #1 X coord
RESM0   =       $12     ;Reset missile #0 X coord
RESM1   =       $13     ;Reset missile #1 X coord
RESBL   =       $14     ;Reset ball
AUDC0   =       $15     ;Audio control 0
AUDC1   =       $16     ;Audio control 1
AUDF0   =       $17     ;Audio frequency 0
AUDF1   =       $18     ;Audio frequency 1
AUDV0   =       $19     ;Audio volume 0
AUDV1   =       $1A     ;Audio volume 1
GRP0    =       $1B     ;Pixel data player #0
GRP1    =       $1C     ;Pixel data player #1
ENABL   =       $1F     ;Ball enable register
HMP0    =       $20     ;Horizontal motion Player #0
HMP1    =       $21     ;Horizontal motion Player #1
HMBL    =       $24     ;Horizontal motion Ball
HMOVE   =       $2A     ;Add horizontal motion to registers
HMCLR   =       $2B     ;Clear horizontal motion registers
CXCLR   =       $2C     ;Clear collision registers

*
* Collision registers
*

CXM0P   =       $00     ;Read collision M0-P1/M0-P0
CXM1P   =       $01     ;Read collision M1-P0/M1-P1
CXP0FB  =       $02     ;Read collision P0-PF/P0-BL
CXP1FB  =       $03     ;Read collision P1-PF/P1-BL
CXM0FB  =       $04     ;Read collision M0-PF/M0-BL
CXM1FB  =       $05     ;Read collision M1-PF/M1-BL
CXBLPF  =       $06     ;Read collision BL-PF/-----
CXPPMM  =       $07     ;Read collision P0-P1/M0-M1
INPT0   =       $08     ;Paddle #0
INPT1   =       $09     ;Paddle #1
INPT2   =       $0A     ;Paddle #2
INPT3   =       $0B     ;Paddle #3
INPT4   =       $0C     ;Misc input #0
INPT5   =       $0D     ;Misc input #1

*
* Memory equates
*

        DUM     $80
GameNumber      DS      1       ;Current game variation being played (0-7)
FrameCounter    DS      1       ;Inc'd every video frame
Polynomial      DS      1       ;Random number polynomial
SelectDelay     DS      1       ;Timer for select autorepeat
Player1Joy      DS      1       ;Player 1's joystick value
Player2Joy      DS      1       ;Player 2's joystick value
SaverColor      DS      1       ;$00 for normal, Random for screen saver
LumMask         DS      1       ;$FF for color, $0F for B&W and $07 for saver
ZColorScore     DS      1       ;Score color and Activision color
ZColorChicken   DS      1       ;Chicken color
ZColorLine      DS      1       ;Street line color
ZColorPavement  DS      1       ;Pavement color
ZColorBlack     DS      1       ;Tire/black
ZColorSidewalk  DS      1       ;Sidewalk color
ChickenYs       DS      2       ;Y coords for Player 1 and 2's chickens
Chick0LaneCollide       DS      1       ;Lane where chicken #1 hit a car
Chick1LaneCollide       DS      1       ;Lane where chicken #2 hit a car
ChickP0Collide  DS      1       ;Collision flag from VCS
ChickP1Collide  DS      1       ;Collision flag from VCS
CurrentCarColor DS      1       ;Current color of the car shape
LaneNumber      DS      1       ;Lane currently being drawn
CarXDirection   DS      1       ;1 or -1 for car X motion
ZCarPatterns    DS      10      ;Current size and multiples of cars
CarMotionTimers DS      10      ;Timer before car is moved
CarMotions      DS      10      ;Motion values for each car
LChickPtrs16    DS      12      ;Pointers for each chick per 16 scan lines
RChickPtrs16    DS      12      ;Pointers for each chick per 16 scan lines
ZCarColors      DS      10      ;Colors for all the cars

* I assume there are 7 pointers in a row here

CarShapePtr             DS      2       ;Pointer to current car shape
ChickLeftShapePtr       DS      2       ;Pointer to chicken shape #0
ChickRightShapePtr      DS      2       ;Pointer to chicken shape #1

* The order of the 4 pointers below is important!

ScoreShape01Ptr DS      2       ;Pointer to left score first digit
ScoreShape11Ptr DS      2       ;Pointer to right score first digit
ScoreShape02Ptr DS      2       ;Pointer to left score second digit
ScoreShape12Ptr DS      2       ;Pointer to right score second digit

*
* All variables from here to $FF are zero'd out every new game
*

SaverTimer      DS      1       ;If > 127 then in screen saver mode
GameTimer       DS      1       ;If 0 then game is in progress
Scores          DS      2       ;Player scores (BCD)
FrameCounterHi  DS      1       ;Inc'd every 256 frames
ChickenSounds   DS      2       ;True if a chicken was hit (Timer for clucking)
CarXCoords      DS      10      ;Array of automobile X coords
TempX1          DS      1       ;Temp X coord

*
* These temp variables cannot be used in a subroutine, they are in the stack
*

TempHonkDistance        DS      1       ;Distance from a car to a chicken
TempCarSpeed            DS      1       ;Speed of the car
TempCarX                DS      1       ;X coord of the car
TempCarPattern          DS      1       ;Car speed pattern
TempCarFacing           DS      1       ;Facing of the car
TempCarXWrap            DS      1       ;Wrapped X coord of a car
TempClosestDist         DS      1       ;Closest car's distance
TempClosestFacing       DS      1       ;Closest car's facing
        DEND

*
* 6532 equates
*

RIOTDATAA       =       $0280
RIOTDATAB       =       $0282
RIOTTIMER       =       $0284
RIOTSETTIMER1   =       $0294
RIOTSETTIMER8   =       $0295
RIOTSETTIMER64  =       $0296
RIOTSETTIMER1024        =       $0297

        ORG     $F000

*
* Freeway for the Atari 2600 VCS
*
* Copyright 1981 Activision Inc.
* By David Crane
*

ResetEntry
        SEI     ;Disable IRQ's
        CLD     ;Binary mode

        LDX     #0      ;Kill all of zero page
WarmStart       LDA     #0      ;Zap memory
]A      STA     $00,X
        TXS     ;Place here to set stack to #$FF
        INX     ;at end of loop
        BNE     ]A

        JSR     ResetGameVars   ;Clear out the game variables

*
* Main game loop

MainLoop        LDX     #6-1
]A      LDA     BaseColors,X    ;Get the colors
        EOR     SaverColor      ;Screen saver
        AND     LumMask ;B&W mask
        STA     ZColorScore,X   ;Save the adjusted colors
        CPX     #4
        BGE     :NoHardW
        STA     COLUP0,X        ;Set the hardware default
:NoHardW        DEX
        BPL     ]A

        STX     Chick0LaneCollide       ;X = FF
        STX     Chick1LaneCollide       ;Chicken's didn't hit a car
        STA     WSYNC   ;Wait a line
        STA     RESBL   ;Reset the ball
        LDA     #$22    ;Set the horizontal ball motion (+2)
        STA     HMBL
        STA     ENABL   ;Enable the ball (02)
        LDA     #40     ;X position for score digit #1
        INX     ;X = 00
        STX     COLUPF  ;Black playfield (Ball)
        JSR     SetMotionRegsX  ;Position digit #1
        LDA     #48     ;X position for score digit #2
        STA     CTRLPF  ;($30) No Reflect,No Score,Low Priority,8 pixel
wide ball
        INX     ;X = 01
        JSR     SetMotionRegsX  ;Position digit #2

        LDA     #$04    ;Two copies wide
        STA     NUSIZ0  ;Two pairs of score digits
        STA     NUSIZ1

        LDA     ZColorScore     ;Color of the score
        LDY     GameTimer       ;Game in progress
        BNE     :NormalScore
        LDY     FrameCounterHi  ;Frames/256
        CPY     #32
        BLT     :NoTimeInc      ;Not time yet?
        INC     GameTimer       ;Inc the game over timer
:NoTimeInc      CPY     #30
        BLT     :NormalScore
        LDA     FrameCounter    ;Use the frame counter for a color
        AND     LumMask ;Fixed lum
:NormalScore    STA     COLUP0  ;Save the score color
        STA     COLUP1

*
* Now display the player's scores at the top of the screen
*

]A      LDA     RIOTTIMER       ;Wait for the proper scan line
        BNE     ]A

*
* 1 line of playfield
*

        STA     WSYNC   ;Wait for sync
        STA     HMOVE   ;Add horizontal motion to position sprites
        STA     VBLANK  ;Enable video
        STA     CXCLR   ;Clear collision registers

*
* Display the scores (8 scan lines)
* 61 cycle loop
*

        LDY     #7      ;7 lines to display
]A      STA     WSYNC   ;3 Wait for sync
        STA     HMCLR   ;3 Clear horizontal motion
        LDA     (ScoreShape01Ptr),Y     ;5 Get the shape for player #0's score
        STA     GRP0    ;3
        LDA     (ScoreShape02Ptr),Y     ;5
        STA     GRP1    ;3
        JSR     Waste18 ;18 Wait for it to be displayed
        LDA     (ScoreShape11Ptr),Y     ;5 Get the shape for player #1's score
        STA     GRP0    ;3
        LDA     (ScoreShape12Ptr),Y     ;5
        STA     GRP1    ;3
        DEY     ;2
        BPL     ]A      ;3

*
* Waste 1 scan line to prepare to draw the sidewalk
*

        LDA     #$40    ;Move the chickens 4 pixels to the left
        STA     HMP1
        STA     WSYNC   ;Wait a line
        STA     HMOVE   ;Add horizontal motion
        INY     ;Y = 0
        STY     GRP0    ;Clear the player shapes (Don't draw score)
        STY     GRP1
        LDA     #$08
        STA     REFP0   ;Reverse player #0
        LDA     LChickPtrs16+11 ;Get the topmost chicken shape
        STA     ChickLeftShapePtr
        LDA     RChickPtrs16+11
        STA     ChickRightShapePtr
        LDY     #8+1    ;8 scan lines of sidewalk and 1 of border
        STA     HMCLR   ;Clear horizontal motion registers

*
* Draw the first black line between the score and the sidewalk
*

        STA     WSYNC
        STA     HMOVE   ;Add horizontal motion
        LDA     ZColorBlack     ;Draw the black line
        STA     COLUBK
        LDA     ZColorChicken   ;Set the chicken's color
        STA     COLUP1

*
* Just draw lines with the chicken on the sidewalk and 1 black line
*

]A      STA     WSYNC
        LDA     ZColorSidewalk  ;Assume sidewalk color
        CPY     #1      ;Bottom line?
        BNE     :NotLine
        LDA     ZColorBlack     ;Draw a black line
:NotLine        STA     COLUBK  ;Set the background color
        LDA     (ChickLeftShapePtr),Y   ;First chicken shape
        STA     GRP1
        JSR     Waste14
        LDA     (ChickRightShapePtr),Y
        STA     GRP1
        DEY
        BNE     ]A

*
* Now I need 3 scan lines to position the car
*

        STA     WSYNC   ;Sync video
        STA     HMOVE   ;Add horizontal motion (Draw black line)
        LDA     ZColorPavement  ;Force pavement
        STA     COLUBK
        LDA     #10-1   ;Init the lane count (10 lanes)
        STA     LaneNumber
        LDA     (ChickLeftShapePtr),Y   ;First chicken (Y=0)
        STA     GRP1
        NOP     ;10 cycles
        NOP
        NOP
        NOP
        NOP
        LDA     (ChickRightShapePtr),Y  ;Second chicken
        STA     GRP1
        LDX     LaneNumber      ;X = (10-1)
        LDA     LChickPtrs16+1,X        ;Get the chick shape for the first lane
        STA     ChickLeftShapePtr
        LDA     RChickPtrs16+1,X
        STA     ChickRightShapePtr

*
* I will draw a lane of the highway
*

DrawALane       LDY     #15     ;15 lines to draw
        LDA     #0      ;A = 0
        STA     WSYNC

*
* Line 1 is just pavement and setup for car position
*

        STA     HMOVE   ;(0) 3 Add horizontal motion
        STA     PF1     ;(3) 3 Clear out the highway pattern (A=0)
        STA     PF2     ;(6) 3
        STA     COLUPF  ;(9) 3 Playfield is black
        LDA     (ChickLeftShapePtr),Y   ;(12) 5 First shape byte
        STA     GRP1    ;(17) 3
        LDA     ZCarColors,X    ;(20) 4 Get the color of the car
        STA     CurrentCarColor ;(24) 3
        LDA     CarMotions,X    ;(27) 4 Get the DEX count for car course
position
        AND     #$0F    ;(31) 2 Only use lower 4 bits
        STA     TempX1  ;(33) 3
        LDA     (ChickRightShapePtr),Y  ;(36) 5 Get player #2's shape
        DEY     ;(41) 2 Y = 14
        STA     GRP1    ;(43) 3 Draw it
        LDA     ZCarPatterns,X  ;(46) 4 Get the width of the shape
        AND     #7      ;(50) 2
        STA     NUSIZ0  ;(52) 3
        CMP     #5      ;(55) 2 Double wide?
        BNE     :ItsACar        ;(57) 2/3
        LDA     #TruckFrame-4   ;(59) 2 Draw a truck
        BNE     :GotCarShp      ;(61) 3

:ItsACar        LDA     #CarFrame-4     ;(60) 2 Draw a car
        NOP     ;(62) 2

:GotCarShp      STA     CarShapePtr     ;(64) 3 Save the car's shape
        LDA     (ChickLeftShapePtr),Y   ;(67) 5
        STA     GRP1    ;(72) 3

*
* Line 2 is pavement and actually setting the car position
*

        LDA     ZCarPatterns,X  ;(75) 4
        BMI     :CarOnRight     ;(79) 2/3 (Car is on the right side)

*
* Set the car position for the left side
*

        LDX     TempX1  ;(81) 3
        CPX     #3      ;(84) 2
        LDA     (ChickRightShapePtr),Y  ;(86) 5 Get the right chicken shape

*
* IMPORTANT!!!! This routine MUST start at cycle 91!!!
*

]A      DEX     ;(91) 2
        BPL     ]A      ;2/3
        STA     RESP0   ;3 Position the car on the left side
        BGE     :DelayOk        ;2/3 Too close to the left
        JSR     Waste12 ;Waste 12 cycles
:DelayOk        DEY     ;2 Y = 13
        STA     GRP1    ;3 Right chicken
        LDX     LaneNumber      ;3
        LDA     CarMotions,X    ;4 Fine horizonal position for car
        STA     HMP0    ;3
        LDA     ZColorBlack     ;3 Black color for tires
        JMP     :BeginLaneLoop  ;3

*
* Draw the right chicken first, then position the car on the right
* IMPORTANT!!!! This routine MUST start at cycle 82!!!
*

:CarOnRight     NOP     ;(82) 2 4 cycles
        NOP     ;(84) 2
        STA     CXCLR   ;(86) 3 Clear collisions
        LDX     LaneNumber      ;(89) 3
        LDA     CarMotions,X    ;(92) 4 Get the fine motion
        STA     HMP0    ;(96) 3 Set now
        LDA     TempX1  ;(99) 3 Get the course cycle count
        SEC     ;(102) 2
        SBC     #30/5   ;(104) 2 Remove 30 cycles (121-91)
        TAX     ;(106) 2
        LDA     (ChickRightShapePtr),Y  ;(108) 5 Get the right shape
        DEY     ;(113) 2 Y = 13
        STA     GRP1    ;(115) 3 Draw it
        LDA     ZColorBlack     ;(118) 3 Start with black tires

*
* IMPORTANT!!!! This routine MUST start at cycle 121!!!
*

]A      DEX     ;(121) Course adjustment
        BPL     ]A
        STA     RESP0   ;Set the car on the right side

*
* Draw the car in the lane, I enter with Black in A
* and then change to the proper color so I can draw the tires in black
* and the rest of the car in the proper color
*

:BeginLaneLoop  STA     WSYNC   ;Sync
]A      STA     HMOVE   ;Add horizontal motion
        STA     COLUP0  ;Save the car color (Or black for the tires)
        LDA     (CarShapePtr),Y ;Get the car shape
        STA     GRP0    ;Draw it
        LDA     ChickP1Collide  ;Did player #2 get hit by a car? (Previous
line)
        ORA     CXPPMM
        STA     ChickP1Collide
        STA     CXCLR   ;Clear collisions
        LDA     (ChickLeftShapePtr),Y   ;Get the chicken shape
        STA     GRP1
        CPY     #6      ;At the bottom of the car?
        LDA     ChickP0Collide  ;Check for car collision
        ORA     CXPPMM
        STA     ChickP0Collide
        STA     CXCLR   ;Clear collisions again! (For player #2)
        LDA     (ChickRightShapePtr),Y  ;Set player #2's chicken
        STA     GRP1
        BLT     :FinishLane     ;No more? (Fall through is only 2 cycles)
        DEY     ;Count down
        STA     |HMCLR  ;4 Clear horizontal motion registers (4 cycles)
        LDA     CurrentCarColor ;Get the car color
        EOR     SaverColor      ;Screen saver
        AND     LumMask
        JMP     ]A      ;Loop

*
* Now, I finished drawing the car in the NORMAL color,
* let's draw the bottom tires
*

:FinishLane     LDA     ZColorBlack     ;Get black
        DEY     ;Y = 4
        STA     WSYNC   ;Sync
        STA     HMOVE   ;Add horizontal motion
        STA     COLUP0
        LDA     (CarShapePtr),Y ;Draw the bottommost tires
        STA     GRP0
        LDA     ChickP1Collide  ;Check for Player #2's chicken death
        ORA     CXPPMM
        STA     ChickP1Collide
        STA     CXCLR   ;Clear collisions
        LDA     (ChickLeftShapePtr),Y   ;Right player
        STA     GRP1
        NOP     ;2
        LDA     ChickP0Collide  ;Save player 1's collision value (Final for
lane)
        ORA     CXPPMM
        STA     ChickP0Collide
        STA     CXCLR   ;Clear collisions
        LDA     (ChickRightShapePtr),Y  ;Draw the right chicken
        STA     GRP1
        DEY     ;Y = 3

*
* Now, clear the car sprite and wrap up player 2's collision register
* Draw only pavement
*

        STA     WSYNC   ;Sync
        STA     HMOVE   ;Add horizontal motion
        LDA     #0      ;Kill the car shape
        STA     GRP0
        LDA     (ChickLeftShapePtr),Y   ;Draw the left chicken
        STA     GRP1
        LDX     LaneNumber      ;Which lane am I in?
        BIT     ChickP0Collide  ;Did I hit?
        BPL     :NoHitP0
        STX     Chick0LaneCollide       ;Save the lane number of the collision
:NoHitP0        LDA     ChickP1Collide  ;Get player #2
        ORA     CXPPMM  ;Add the current hardware
        BPL     :NoHitP1        ;Did I hit?
        STX     Chick1LaneCollide       ;Save the collision
:NoHitP1        LDA     (ChickRightShapePtr),Y  ;Get the chicken shape
        STA     GRP1    ;Draw it
        STA     CXCLR   ;Clear collisions
        DEY     ;Y = 2
        LDA     LaneNumber      ;Are we in the final lane?
        BEQ     WrapUp  ;Finish and draw sidewalk if so...

*
* I need to draw the center divider or the single white line
* I will draw 3 lines, Either the lines will be drawn...
* Pavement,White,Pavement or
* Chicken,Pavement,Chicken
*

        LDX     ZColorPavement  ;Get the pavement color
        CMP     #5      ;Should I draw the center divider?
        BNE     :DrawWhiteLane  ;Draw the regular white lines
        LDX     ZColorChicken   ;Use the chicken's color for the lines
:DrawWhiteLane  STA     WSYNC
        STA     HMOVE   ;Add horizontal motion
        LDA     #$AA    ;Draw the line patter
        STA     PF0     ;Write the highway line pattern
        STA     PF2
        LSR     ;Reverse bits A = $55
        STA     PF1     ;Middle bits
        STX     COLUPF  ;Save the color (Pavement or chicken)
        LDA     (ChickLeftShapePtr),Y   ;First chicken
        STA     GRP1
        DEC     LaneNumber      ;Next lane
        LDA     (ChickRightShapePtr),Y
        STA     GRP1
        DEY     ;Y = 1

*
* Center line (Pavement or white)
*

        STA     WSYNC
        STA     HMOVE   ;Add horizontal motion
        CPX     ZColorChicken   ;Am I drawing the center divider?
        BNE     :NotCenter3
        LDA     #0      ;I will also force the cars to face right
        STA     REFP0   ;Don't reverse player #0
        LDA     ZColorPavement  ;No center line
        JMP     :Pavement

:NotCenter3     LDA     ZColorLine      ;White line color
:Pavement       STA     COLUPF  ;Change the line color
        LDA     (ChickLeftShapePtr),Y   ;First chicken
        STA     GRP1
        JSR     Waste12 ;Waste 12 cycles
        LDA     (ChickRightShapePtr),Y  ;Second chicken
        STA     GRP1
        DEY     ;Y = 0

*
* Final line (Chicken or pavement)
*

        STA     WSYNC
        STA     HMOVE   ;Add horizontal motion
        STX     COLUPF
        LDA     (ChickLeftShapePtr),Y
        STA     GRP1
        LDX     LaneNumber      ;Get the lane number
        LDA     LChickPtrs16+1,X        ;Set the chick shape pointers for
the next lane
        STA     ChickLeftShapePtr
        LDA     RChickPtrs16+1,X
        STA     TempX1  ;Can't use yet...
        NOP
        LDA     (ChickRightShapePtr),Y  ;Final right chicken shape
        STA     GRP1
        LDA     TempX1  ;Grab from temp
        STA     ChickRightShapePtr      ;Now I can use it
        LDA     #0      ;Clear the collision masks
        STA     ChickP0Collide
        STA     ChickP1Collide
        STA     PF0     ;Clear out the left most highway pattern
        JMP     DrawALane       ;The other two are cleared at the beginning

*
* Now, draw the last lines of the chicken (Y == 2 on entry)
*

WrapUp  STA     WSYNC   ;Sync
        STA     HMOVE   ;Add horizontal motion
        LDA     (ChickLeftShapePtr),Y   ;Get the left chicken
        STA     GRP1
        JSR     Waste14 ;Waste 26 cycles
        JSR     Waste12
        LDA     (ChickRightShapePtr),Y  ;Get the right chicken
        STA     GRP1
        DEY     ;Looped 3 times?
        BPL     WrapUp  ;All done?

*
* Now draw the sidewalk on the bottom of the screen
* I must loop with Y == 15 to compensate for the Chicken pointers
*

        LDY     #9+6    ;9 scan lines to draw
]A      LDA     ZColorSidewalk  ;Assume sidewalk color
        STA     WSYNC   ;Sync
        STA     HMOVE   ;Border
        CPY     #9+6    ;Topmost black line?
        BNE     :NotBlk2
        LDA     ZColorBlack     ;Draw black
:NotBlk2        STA     COLUBK  ;Save the color
        LDA     LChickPtrs16    ;Bottommost chicken pointers
        STA     ChickLeftShapePtr
        LDA     RChickPtrs16
        STA     ChickRightShapePtr
        LDA     (ChickLeftShapePtr),Y   ;Draw the left chicken
        STA     GRP1
        LDA     (ChickRightShapePtr),Y  ;Draw the right chicken
        DEY
        STA     GRP1
        CPY     #6      ;All done?
        BGE     ]A

*
* Draw the activision logo
* 1 line of black to prepare, then draw it
*

        STA     WSYNC   ;Wait for video sync
        STA     HMOVE
        LDA     ZColorBlack     ;Black line
        STA     COLUBK
        LDX     #0      ;Clear the shape register
        STX     GRP1
        STX     HMCLR   ;Clear horizontal motion registers
        INX     ;X = 1
        STX     NUSIZ0  ;3 shapes, close together
        STX     NUSIZ1
        STA     RESP0   ;Set the x coord (16)
        STA     RESP1   ;X coord (25) (16+9)
        LDA     #$10    ;Move player #1 one pixel to the left
        STA     HMP1
        LDA     ZColorScore     ;Score color
        STA     COLUP0
        STA     COLUP1

*
* Now draw the 8 lines
* Note : All the activision shapes end with a shape of zero,
* this way, I can assume the video display is pure black after the loop
* is finished.
*

        LDX     #8-1    ;8 scan lines
]A      STA     WSYNC
        STA     HMOVE   ;3 Move the players (Only first time)
        LDA     Activision1,X   ;4 Draw the shape
        STA     GRP0    ;3
        LDA     Activision2,X   ;4 Draw in player #1
        STA     GRP1    ;3
        NOP     ;2 Waste 2 cycles
        LDA     Activision4,X   ;4 Preload the final 2 bytes
        TAY     ;2
        LDA     Activision3,X   ;4
        STA     GRP0    ;3 Store in shape (Cycle 32)
        STY     GRP1    ;3
        STA     HMCLR   ;3 Clear horizontal motion registers for future loops
        DEX     ;2 All done?
        BPL     ]A      ;3 Loop

*
* The video display is now finished, let's time to the vertical blank
* (It's black anyways)
*

        LDA     #26     ;Init the vertical blank timer
        STA     RIOTSETTIMER64

*
* Update a score value and process each player EVERY OTHER FRAME!
* I do this since I want the chickens to move 30 pixels a second instead
* of 60. Turbo chickens aren't much fun.
*

        LDA     FrameCounter    ;Player 1 or 2 (Update 30 FPS)
        AND     #1
        TAX     ;0/1
        ASL
        TAY     ;0/2
        LDA     Scores,X        ;Get the score (BCD)
        AND     #$F0    ;Mask it
        LSR     ;$00,$08,$10,$18,$20
        BNE     :NotZero
        LDA     #ChickFrameX    ;Space character
:NotZero        STA     ScoreShape01Ptr,Y       ;Insert a space (Or digit)
        LDA     Scores,X        ;Get the BCD number again
        AND     #$0F    ;0-9
        ASL     ;Mul by 8
        ASL
        ASL     ;$00,$08,$10,$18,$20
        STA     ScoreShape02Ptr,Y       ;Save the second digit

        LDY     #0      ;Preload Y so the sound may be muted
        JSR     ReadConsoleSwitches     ;Get the console switches (Affect's A)
        BPL     :SetVol2        ;Reset pressed?

*
* Process sound effects from the players
* $8F = Got a point
* $5C = Cluck!
*

        LDA     ChickenSounds,X ;Was the chicken moving down by impact?
        BEQ     CheckSelect     ;No sound effect
        AND     #$40    ;$40-$5C?
        BEQ     :GotPoint
        LDA     #4      ;Div 2 / Pure tone
        STA     AUDC0,X
        DEC     ChickenSounds,X ;Count down the sound timer
        LDA     ChickenSounds,X ;Get the value
        AND     #$1F    ;0-27
        CMP     #16
        BLT     :SetVol2        ;Volume is zero (Y=0)
        PHA
        AND     #3      ;0-3
        ADC     #3-1    ;3-6
        STA     AUDF0,X ;Set the frequency
        PLA
        LDY     #4      ;Medium volume
:SetVol2        STY     AUDV0,X ;Save the volume

        CMP     #0      ;No more?
        BNE     :DontKillSnd1
        LDA     #0      ;Shut off the sound
        STA     ChickenSounds,X ;No more clucking...

:DontKillSnd1   LDA     RIOTDATAB       ;Get the difficulty switches
        AND     DiffSwitchTbl,X ;Hard?
        BEQ     :EndSound       ;Nope
        LDA     #6      ;Reset the chicken to the bottom on impact
        STA     ChickenYs,X
:EndSound       JMP     SkipAmbientSnd

*
* I got a point!
*

:GotPoint       LDA     ChickenSounds,X ;Get the clucking timer
        STA     AUDV0,X ;Set the volume using it
        LDA     #12     ;Div 31 pure tone
        STA     AUDC0,X
        TXA     ;0/1
        ADC     #6      ;6/7
        STA     AUDF0,X
        DEC     ChickenSounds,X ;Count down the sound timer
        LDA     ChickenSounds,X ;Done?
        AND     #$0F
        BNE     JmpEndSnd
        LDA     #0      ;Kill the sound
        STA     ChickenSounds,X
JmpEndSnd       JMP     SkipAmbientSnd  ;End

*
* Check for game select and play a honking horn if so.
* Play amibent sounds (Motors, honking)
*

CheckSelect     LDA     SelectDelay     ;Is the select switch held down?
        CMP     #8      ;Check the time
        LDA     #2      ;Choose a horn
        BGE     :HonkHorn       ;Honk!
        LDA     GameTimer       ;Game in progress?
        BEQ     :DoAmbient
        LDA     #0      ;Don't play any sound if the game is over
        STA     AUDV0,X ;Clear the volume (Kill voice)
        BEQ     JmpEndSnd       ;JMP

:DoAmbient      LDA     ChickenSounds   ;Any sound effect present?
        ORA     ChickenSounds+1
        BNE     :TryMotor

        LDA     Polynomial      ;Get the random number value
        EOR     #$40
        CMP     #$E0
        BLT     :TryMotor       ;No sound now
        LDA     Polynomial
        EOR     FrameCounter    ;Real random
        AND     #$3F
        BEQ     :TryMotor
        LDA     Polynomial      ;Get the value

*
* Honk a horn
*

:HonkHorn       AND     #3      ;1 of 4 horns to play
        ORA     #4      ;Pitch 4-7
        STA     AUDF0
        SEC
        SBC     #1      ;Pitch 3-6
        STA     AUDF1
        LDA     #1      ;4 bit polynomial
        STA     AUDC0
        STA     AUDC1
        STA     AUDV0   ;Set volume to minimum
        STA     AUDV1   ;for both voices
        BNE     JmpEndSnd       ;JMP

*
* Play a car's motor if it's speed changes
*

:TryMotor       LDA     ChickenYs,X     ;Get the Y coord
        LSR     ;Div by 16 for the lane
        LSR
        LSR
        LSR
        TAY
        CPY     #10
        BLT     :LaneNumOk
        LDY     #9      ;Force bottom lane
:LaneNumOk      LDA     #0      ;Going right?
        CPY     #5
        BLT     :FacingRight
        LDA     #1      ;Going left..
:FacingRight    STA     TempCarFacing   ;0-1

        LDA     ZCarPatterns,Y  ;Get the car pattern for the lane
        STA     TempCarPattern  ;Save the pattern
        LSR
        LSR
        LSR
        LSR
        AND     #7      ;Isolate the speed
        STA     TempCarSpeed    ;Save speed
        CMP     #2
        LDA     #32     ;Can honk if 32 pixels away
        BLT     :FastCar
        LDA     #$FF    ;Set the facing for a slow car
        STA     TempCarFacing
        LDA     #16     ;Honk if 16 pixels away
:FastCar        STA     TempHonkDistance

        LDA     #3      ;5 bit poly -> 4 bit poly
        STA     AUDC0,X
        LDA     CarXCoords,Y    ;Get the X coord
        STA     TempCarX
        LDA     #127    ;Maximum distance
        STA     TempClosestDist
        LDA     TempCarFacing   ;0,1,-1
        STA     TempClosestFacing       ;Assume this is the closest facing

        LDA     TempCarPattern  ;Get width in pixels of car
        AND     #7
        ASL
        ASL
        ORA     #3      ;Round up to end of table
        TAY     ;Index

]A      LDA     TempCarFacing   ;Get the facing (0,1,-1)
        STA     TempX1
        CLC
        LDA     CarGroupXs,Y    ;Get the base X
        ADC     TempCarX        ;Add to true X
        CMP     #160
        BLT     :NoXWrap
        SBC     #160    ;Wrap around
:NoXWrap        STA     TempCarXWrap    ;Save the X

        LDA     TrueChickenXs,X ;Get the chicken
        SEC
        SBC     TempCarXWrap    ;Get the difference
        BGE     :DiffPositive
        EOR     #$FF    ;Negate it
        INC     TempX1  ;0,1,2
:DiffPositive   CMP     TempClosestDist ;Closer?
        BGE     :NotCloser
        STA     TempClosestDist ;Save the new distance
        LDA     TempX1  ;Save the facing
        STA     TempClosestFacing
:NotCloser      DEY
        TYA
        AND     #3      ;All done?
        BNE     ]A

        LDA     TempClosestDist ;Will a car honk?
        CMP     TempHonkDistance
        BLT     :IllHonk
        LDA     #15     ;5 bit poly div 6
        STA     AUDC0,X
        LDA     #31     ;Very low pitch (1 Khz)
        STA     AUDF0,X
        LDA     #1      ;Minimum volume
        STA     AUDV0,X
        JMP     SkipAmbientSnd  ;Done

*
* Honk the horn
*

:IllHonk        DEC     TempHonkDistance        ;Dec the distance to the
car 15,31
        EOR     TempHonkDistance        ;Reverse volume based on distance
        LSR     ;Lower for the VCS
        LSR
        STA     AUDV0,X ;Set the volume
        LDY     TempClosestFacing       ;-1,0,1,2
        INY     ;0-3
        LDA     MotorPitchs,Y   ;Get the pitch
        CLC
        ADC     TempCarSpeed    ;Add the car's speed
        STA     AUDF0,X ;Set the frequency

*
* Blend the random number generator
*

SkipAmbientSnd  LDA     FrameCounter    ;Only mix every 32 frames
        AND     #$1F
        BNE     :NoRandom
        LDA     Polynomial      ;Adjust the random number generator
        ASL
        ASL
        ASL
        EOR     Polynomial
        ASL
        ROL     Polynomial

*
* Move the cars in the upper 5 lanes
*

:NoRandom       LDA     GameTimer       ;Game in progress (if == 0)
        BNE     :WaitHere
        LDX     #9
        LDA     #-1     ;Make cars move to the left
        STA     CarXDirection
]A      JSR     MoveACar
        DEX
        CPX     #5
        BGE     ]A

*
* Process VBlank here
*

:WaitHere       LDA     RIOTTIMER       ;Wait until the timer says ok!
        BNE     :WaitHere

        LDY     #$82    ;Enable video blank flags
        STY     WSYNC   ;Sync to HBlank
        STY     VBLANK  ;Enable vertical blank and dump I0-I3 to ground
        STY     VSYNC   ;Enable vertical sync signal
        STY     WSYNC   ;Wait 3 scan lines
        STY     WSYNC
        STY     WSYNC
        STA     VSYNC   ;Disable vertical sync signal (A=0)

*
* Inc the frame counters and timers
*

        INC     FrameCounter    ;Inc the frame counter
        BNE     :NoRollSv       ;255 frames?
        INC     FrameCounterHi  ;High byte of the frame counter
        INC     SaverTimer      ;Inc the screen saver timer
        BNE     :NoRollSv       ;Zero?
        SEC     ;Keep the high byte set
        ROR     SaverTimer      ;= $80

:NoRollSv       LDY     #$FF    ;Assume normal color
        LDA     RIOTDATAB       ;B&W set?
        AND     #$08
        BNE     :Color
        LDY     #$0F    ;Force b&w
:Color  TYA     ;Place in A
        LDY     #0      ;Assume screen saver not active
        BIT     SaverTimer      ;Screen saver active?
        BPL     :NoSaver8
        AND     #$F7    ;Halve the brightness
        LDY     SaverTimer      ;Get the timer value for the random colors
:NoSaver8       STY     SaverColor      ;Save the random saver scrambler
        ASL     SaverColor      ;0,2,4 etc...
        STA     LumMask ;$FF,$0F,$07

        LDA     #44
        STA     WSYNC   ;Wait for scan line
        STA     RIOTSETTIMER64  ;Set the timer for start of screen

*
* Move the cars in the lower 5 lanes
*

        LDA     GameTimer       ;Game in progress (if == 0)
        BNE     ReadJoysticks
        LDX     #4
        LDA     #1      ;Make cars move to the right
        STA     CarXDirection
]A      JSR     MoveACar
        DEX
        BPL     ]A

*
* Read the joysticks
*

ReadJoysticks   LDA     RIOTDATAA       ;Read the joystick
        TAY
        AND     #$0F
        STA     Player2Joy      ;Save player 2's joystick
        TYA
        LSR
        LSR
        LSR
        LSR
        STA     Player1Joy      ;Save player 1's joystick
        INY
        BEQ     :NoJoy  ;No joystick pressed
        LDA     #0      ;Joystick is pressed
        STA     SaverTimer

:NoJoy  LDA     Polynomial      ;Make sure the polynomial is non-zero!
        BNE     :DoConsole
        INC     Polynomial
        BNE     :NewSel

:DoConsole      JSR     ReadConsoleSwitches     ;Read the console
        BMI     :ChkSelect      ;Reset pressed?
        LDX     #SaverTimer     ;Yep, reset the game
        JMP     WarmStart

:ChkSelect      LDY     #0      ;Was select pressed? (Init Y)
        BCS     :SaveSelDelay   ;Nope (Clear select delay)

        LDA     SelectDelay     ;Select the next game
        BEQ     :NotHeld
        DEC     SelectDelay
        BPL     :NotSelTime
:NotHeld        INC     GameNumber      ;Inc the game selected
:NewSel JSR     ResetGameVars

        LDA     GameNumber      ;Make sure the game number is 0-7
        AND     #7
        STA     GameNumber
        STA     SaverTimer
        ORA     #$A0    ;Space / Digit
        TAY
        INY
        STY     Scores  ;$A1-$A8 Space/1-8
        LDA     #$AA    ;Space/space
        STA     Scores+1
        LDY     #30     ;Game over!
        STY     GameTimer
:SaveSelDelay   STY     SelectDelay     ;30/60 delay (1/2 second or 0)

:NotSelTime     LDA     GameTimer       ;Game in progress? (if == 0)
        BEQ     MoveTheChickens
        JMP     MainLoop        ;Loop

*
* Move both player's either up or down.
* Add score if you reached the top
*

MoveTheChickens LDX     #2-1
]A      LDA     ChickenSounds,X ;Override?
        BEQ     :Normal
        AND     #$10    ;Force down...
        BNE     :ForceDown
        BEQ     :NotDown        ;JMP

:Normal LDA     Player1Joy,X    ;Pressing up?
        LSR
        BCS     :NotUp  ;Nope
        INC     ChickenYs,X     ;Move 1 pixel up
        LDY     ChickenYs,X     ;At the top?
        CPY     #178
        BLT     :NotUp  ;Nope
        SED     ;BCD
        LDA     Scores,X        ;Add 1 to the score
        ADC     #1-1
        STA     Scores,X
        CLD     ;HEX
        LDA     #$8F    ;Start the sound effect for a point
        STA     ChickenSounds,X
        BNE     :ForceBottom    ;JMP

:NotUp  LSR     ;See if going down
        BCS     :NotDown
:ForceDown      DEC     ChickenYs,X     ;Move down 1
        LDA     ChickenYs,X
        CMP     #6      ;At the bottom
        BGE     :NotDown
:ForceBottom    LDA     #6      ;Set to the bottom
        STA     ChickenYs,X

:NotDown        LDA     ChickenSounds,X ;Am I playing a clucking sound?
        AND     #$1F
        CMP     #$17
        BGE     :Next
        LDA     Chick0LaneCollide,X     ;Am I hitting a car?
        BMI     :Next
        LDA     #92     ;Reset the sound
        STA     ChickenSounds,X
:Next   DEX     ;Next chicken...
        BPL     ]A

*
* Get the pointers to the chickens' shapes
*

        LDX     #0      ;Player #1
        JSR     CalcChickShapePtr       ;Get the pointer
        STA     LChickPtrs16,Y  ;Save the pointer
        CPY     #11     ;Topmost?
        BEQ     :NoChick4
        CLC
        ADC     #16
        STA     LChickPtrs16+1,Y
:NoChick4       INX
        JSR     CalcChickShapePtr
        STA     RChickPtrs16,Y
        CPY     #11
        BEQ     AlterCarSpeeds
        CLC
        ADC     #16
        STA     RChickPtrs16+1,Y

*
* Check if I need to speed up or slow down the cars
*

AlterCarSpeeds  LDA     FrameCounter    ;Time?
        AND     #$70
        BNE     :JmpMain
        LDA     GameNumber      ;Easy game?
        AND     #4
        BEQ     :JmpMain

        LDA     FrameCounter    ;Get the frame count
        AND     #$0F    ;Update 1 lane per frame
        TAX
        CPX     #10     ;Only 10 lanes
        BGE     :JmpMain
        LDA     ZCarPatterns,X  ;Get the speed of this lane
        LSR
        LSR
        LSR
        LSR
        AND     #7      ;Isolate the speed
        TAY     ;Save in Y
        LDA     FrameCounter    ;Get the random number
        EOR     Polynomial
        LSR     ;Check low bit (1 = speed up)
        BCC     :NotFaster
        DEY     ;Speed up the car
        BPL     :NotFaster
        LDY     #0      ;No faster than zero
:NotFaster      LSR     ;Check bit #1 (1 = slow down)
        BCC     :GotSpeed
        INY     ;Slow down a bit
        CPY     #6
        BLT     :GotSpeed
        LDY     #5      ;Slowest speed
:GotSpeed       TYA
        ASL     ;Put back the speed value
        ASL
        ASL
        ASL
        STA     TempX1  ;Save in temp
        LDA     ZCarPatterns,X  ;Get the pattern
        AND     #$8F    ;Mask speed
        ORA     TempX1  ;Blend new speed
        STA     ZCarPatterns,X  ;Save the pattern
:JmpMain        JMP     MainLoop

*
* Reset the game variables
*

ResetGameVars   LDA     FrameCounter    ;Reset the frame counter
        AND     #1      ;But allow updating of the chickens
        STA     FrameCounter

        LDX     #2-1    ;2 players
]A      LDA     #6      ;Move to the bottom
        STA     ChickenYs,X
        LDA     #0      ;Reset the volume of the audio chip
        STA     AUDV0,X
        DEX
        BPL     ]A

        LDX     #14-1
        LDA     #>FontPage
]A      STA     CarShapePtr,X   ;Init the high byte for video pointers
        DEX
        DEX
        BPL     ]A

        LDX     #10-1   ;10 lanes
]A      LDA     #1      ;Allow motion in 2 frames
        STA     CarMotionTimers,X
        LDA     CarColors,X     ;Copy the car colors
        STA     ZCarColors,X
        CLC
        LDA     GameNumber      ;Get the traffic pattern
        AND     #3
        TAY
        TXA
        ADC     Mul10Tbl1,Y     ;Mul 0-3 by 10
        TAY
        LDA     CarPatterns,Y   ;Save the pattern
        STA     ZCarPatterns,X
        LDA     #$60    ;Horizontal motion (+6 pixels)
        STA     CarMotions,X
        LDA     #ChickFrameX    ;No chickens are drawn
        STA     LChickPtrs16,X  ;Zap all the tables
        STA     LChickPtrs16+4,X
        STA     RChickPtrs16+2,X
        DEX
        BPL     ]A
        RTS

*
* Given a requested X coord in A,
* return in A and Y and Horizonal offset and the cycle delay
*

CalcXRegs       CLC
        ADC     #46
        TAY
        AND     #$F     ;Mask the 4 bit offset
        STA     TempX1  ;Save temp
        TYA     ;Get value again
        LSR     ;Isolate the upper 4 bits
        LSR
        LSR
        LSR
        TAY     ;Save as a WSYNC Delay
        CLC
        ADC     TempX1  ;Mod 15
        CMP     #15
        BLT     :NoExcess
        SBC     #15     ;Remove one step
        INY     ;5 more cycles
:NoExcess       EOR     #7      ;Negate horizontal offset
        ASL     ;Move to upper 4 bits (Hardware)
Waste18 ASL             ;2 Call to waste 18 cycles
        ASL     ;2
Waste14 ASL     ;2 Call to waste 14 cycles
Waste12 RTS     ;6 Call to waste 12 cycles

*
* Set the horizontal motion registers
*

SetMotionRegsX  JSR     CalcXRegs       ;Calculate the values
        STA     HMP0,X  ;Save the horizontal motion register
        STA     WSYNC   ;Sync to video
]A      DEY     ;Wait for cycle delay (5 cycles per)
        BPL     ]A
        STA     RESP0,X ;Hit the register for course adjustment
        RTS     ;Exit

*
* Move a car either left or right
* Note : I also will clear the chick shape values
*

MoveACar        DEC     CarMotionTimers,X       ;Time to move it yet?
        BPL     :NoMoveNow      ;Nope
        LDA     ZCarPatterns,X  ;Get the car's speed
        LSR
        LSR
        LSR
        LSR
        AND     #7      ;0-7
        SEC
        SBC     #1      ;-1-6
        BPL     :NotFast        ;2 pixels a frame?
        LDA     CarXCoords,X
        CLC
        ADC     CarXDirection   ;Add the car direction now
        STA     CarXCoords,X
        LDA     #0      ;Reset the timer
:NotFast        STA     CarMotionTimers,X

        LDA     CarXCoords,X
        CLC
        ADC     CarXDirection   ;Add the car direction
        CMP     #200    ;Off the left side?
        BLT     :NotHigh
        LDA     #159    ;Wrap around
:NotHigh        CMP     #160    ;Off the right side?
        BLT     :InRange
        LDA     #0      ;Wrap around
:InRange        STA     CarXCoords,X

:NoMoveNow      LDA     CarXCoords,X    ;Get the X coord of a car
        JSR     CalcXRegs
        STA     TempX1  ;Save the horiz registers
        DEY     ;-15 from the cycle count
        DEY
        DEY
        ASL     ZCarPatterns,X  ;Save the carry
        CPY     #6      ;Set carry if on the right side (Clear on left)
        ROR     ZCarPatterns,X  ;Put the flag back
        TYA
        ORA     TempX1  ;Get the horiz reg value
        STA     CarMotions,X    ;Save the motion registers
        LDA     #ChickFrameX    ;Assume all chickens are blank
        STA     LChickPtrs16,X
        STA     RChickPtrs16+2,X
        STA     LChickPtrs16+4,X
        RTS

*
* Figure out which lane I shall draw the chicken
*

CalcChickShapePtr       LDA     ChickenYs,X     ;Get the Y
        LSR     ;/ by 16 to get the lane
        LSR
        LSR
        LSR
        TAY
        LDA     ChickenYs,X     ;Get the Y again
        AND     #$F     ;Mask
        STA     TempX1  ;Save in a temp
        LDA     ChickenSounds,X ;Chicken in normal mode?
        BEQ     :Normal
        AND     #$40    ;Not in pain...
        BEQ     :Normal
        LDA     ChickenYs,X     ;Test bit #2
        LSR
        LSR
        LSR
        LDA     #ChickFrame3    ;If !(&4), use a sqwak frame
        BCC     :GotFrame
:Normal LDA     TempX1  ;Get the scan line
        LSR
        LSR
        LSR
        LDA     #ChickFrame1    ;Use for lines !(&4)
        BCC     :GotFrame
        LDA     #ChickFrame2    ;Use for lines &4
:GotFrame       SEC
        SBC     TempX1  ;Subtract from the scan line
        RTS

*
* Read the console switches from the 6532 RIOT chip
* Bits are...
* $01 Reset
* $02 Select
* $08 Color
* $40 Difficulty Left
* $80 Difficulty Right
* Carry = Select, Negative = Reset
*

ReadConsoleSwitches
        LDA     RIOTDATAB       ;Read the switches
        LSR     ;Shift the reset switch
        ROR     ;Rotate reset to negative flag
        RTS     ;and Carry has select

        HEX     250C250D        ;Not used... (Filler)

*
* Activision logo bit map
*

Activision1     DB      %00000000
        DB      %10101101
        DB      %10101001
        DB      %11101001
        DB      %10101001
        DB      %11101101
        DB      %01000001
        DB      %00001111

Activision2     DB      %00000000
        DB      %01010000
        DB      %01011000
        DB      %01011100
        DB      %01010110
        DB      %01010011
        DB      %00010001
        DB      %11110000

Activision3     DB      %00000000
        DB      %10111010
        DB      %10001010
        DB      %10111010
        DB      %10100010
        DB      %00111010
        DB      %10000000
        DB      %11111110

Activision4     DB      %00000000
        DB      %11101001
        DB      %10101011
        DB      %10101111
        DB      %10101101
        DB      %11101001
        DB      %00000000
        DB      %00000000

*
* Size and shapes for each traffic pattern for the 8 games
*

CarPatterns     HEX     50403020101020304050    ;Game #1,#5
        HEX     40312213041514233241    ;Game #2,#6
        HEX     46362016050016203646    ;Game #3,#7
        HEX     05152515050515251505    ;Game #4,#8

*
* Base colors
*

BaseColors      HEX     4A      ;Score and Activision color
        HEX     1E      ;Chicken / Median color
        HEX     0C      ;Line color
        HEX     06      ;Pavement color
        HEX     00      ;Tire color
        HEX     08      ;Sidewalk color

CarColors       HEX     1AD8448824824A12DC42    ;Colors for each lane of cars

*
* Must not cross page boundaries!!
* All shapes are upside down to allow decrementing by Y as both
* a counter and a shape index
*
        ERR     *&$FF   ;Must be page aligned (256)
*
* Numeric font
*

FontPage        DB      %00111100
        DB      %01100110
        DB      %01100110
        DB      %01100110
        DB      %01100110
        DB      %01100110
        DB      %01100110
        DB      %00111100

        DB      %00111100
        DB      %00011000
        DB      %00011000
        DB      %00011000
        DB      %00011000
        DB      %00011000
        DB      %00111000
        DB      %00011000

        DB      %01111110
        DB      %01100000
        DB      %01100000
        DB      %00111100
        DB      %00000110
        DB      %00000110
        DB      %01000110
        DB      %00111100

        DB      %00111100
        DB      %01000110
        DB      %00000110
        DB      %00001100
        DB      %00001100
        DB      %00000110
        DB      %01000110
        DB      %00111100

        DB      %00001100
        DB      %00001100
        DB      %00001100
        DB      %01111110
        DB      %01001100
        DB      %00101100
        DB      %00011100
        DB      %00001100

        DB      %01111100
        DB      %01000110
        DB      %00000110
        DB      %00000110
        DB      %01111100
        DB      %01100000
        DB      %01100000
        DB      %01111110

        DB      %00111100
        DB      %01100110
        DB      %01100110
        DB      %01100110
        DB      %01111100
        DB      %01100000
        DB      %01100010
        DB      %00111100

        DB      %00011000
        DB      %00011000
        DB      %00011000
        DB      %00011000
        DB      %00001100
        DB      %00000110
        DB      %01000010
        DB      %01111110

        DB      %00111100
        DB      %01100110
        DB      %01100110
        DB      %00111100
        DB      %00111100
        DB      %01100110
        DB      %01100110
        DB      %00111100

        DB      %00111100
        DB      %01000110
        DB      %00000110
        DB      %00111110
        DB      %01100110
        DB      %01100110
        DB      %01100110
        DB      %00111100

*
* Chicken frame with no shape
*

ChickFrameX     DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000

ChickFrame1     DB      %00110000
        DB      %01100000
        DB      %01111000
        DB      %11111000
        DB      %10111000
        DB      %00001100
        DB      %00000110
        DB      %00000100
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000

ChickFrame2     DB      %00011000
        DB      %00110000
        DB      %01111000
        DB      %11111000
        DB      %10111000
        DB      %00011000
        DB      %00001100
        DB      %00001000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000

ChickFrame3     DB      %01100000
        DB      %00110000
        DB      %01111000
        DB      %11111000
        DB      %10111000
        DB      %00111100
        DB      %00101000
        DB      %01000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000
        DB      %00000000

CarFrame        DB      %01100110
        DB      %11111110
        DB      %11001111
        DB      %10110011
        DB      %10110011
        DB      %10110011
        DB      %10110011
        DB      %11001111
        DB      %11111110
        DB      %01100110
        DB      %00000000

TruckFrame      DB      %10000101
        DB      %11111111
        DB      %10000101
        DB      %11111101
        DB      %11111101
        DB      %11111101
        DB      %11111101
        DB      %10000101
        DB      %11111111
        DB      %10000101

Mul10Tbl1       DB      0,10,20,30
CarGroupXs      DB      0,0,0,0 ;X coord for each car group
        DB      0,0,16,16
        DB      0,0,0,32
        DB      0,0,16,32
        DB      0,0,0,64
        DB      0,0,0,0
        DB      0,0,32,64
TrueChickenXs   DB      48,104  ;Chicken Xs
MotorPitchs     DB      16,16,17,16     ;Base pitches for motors

        DA      ResetEntry      ;Reset vector (MUST be at $F7FC)
DiffSwitchTbl   HEX     4080    ;Left,Right difficulty flags

        SAV     Freeway

;  ------------------------------------------------------------------------



