[stella] Source (fwd)

Subject: [stella] Source (fwd)
From: Glenn Saunders <krishna@xxxxxxxxxxxx>
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
Current Thread