Skip to navigation

Revs on the BBC Micro

Workspaces

REVS SOURCE Revs was written by Geoffrey J Crammond and is copyright Acornsoft 1985 The code on this site has been reconstructed from a disassembly of the original game binaries The commentary is copyright Mark Moxon, and any misunderstandings or mistakes in the documentation are entirely my fault The terminology and notations used in this commentary are explained at https://revs.bbcelite.com/about_site/terminology_used_in_this_commentary.html The deep dive articles referred to in this commentary can be found at https://revs.bbcelite.com/deep_dives
This source file produces the following binary file: * Revs2.bin
INCLUDE "1-source-files/main-sources/revs-header.h.asm" _ACORNSOFT = (_VARIANT = 1) _SUPERIOR = (_VARIANT = 2) _4TRACKS = (_VARIANT = 3) _REVSPLUS = (_VARIANT = 4) GUARD &8000 \ Guard against assembling over sideways ROMs
Configuration variables
IRQ1V = &0204 \ The IRQ1V vector that we intercept to implement the \ screen mode VIA = &FE00 \ Memory-mapped space for accessing internal hardware, \ such as the video ULA, 6845 CRTC and 6522 VIAs (also \ known as SHEILA) OSRDCH = &FFE0 \ The address for the OSRDCH routine OSWRCH = &FFEE \ The address for the OSWRCH routine OSBYTE = &FFF4 \ The address for the OSBYTE routine OSWORD = &FFF1 \ The address for the OSWORD routine CODE% = &0B00 \ The address of the main game code LOAD% = &1200 \ The load address of the main code binary LOAD_END% = &7000 \ The address of the end of the main code binary dashData = &3000 \ The address of the first code block that gets swapped \ in and out of screen memory, along with parts of the \ dashboard image trackLoad = &70DB \ The load address of the track data file trackChecksum = &7800 \ The address of the checksums in the track data file \ after it is loaded but before it is moved in memory \ The following configuration variables represent screen \ addresses for the custom screen tyreLeft1 = &6E85 \ The tread on the left tyre in screen memory tyreLeft2 = &6E8A tyreLeft3 = &6FC0 tyreRight1 = &6FB2 \ The tread on the right tyre in screen memory tyreRight2 = &6FBD tyreRight3 = &70F8 leftSurface = &713D \ A point in the track view next to the left edge of the \ dashboard, which we use to determine the surface under \ the left side of the car rightSurface = &7205 \ A point in the track view next to the right edge of \ the dashboard, which we use to determine the surface \ under the left right of the car mirror0 = &7540 \ Mirror 0 base address (left mirror, outer segment) mirror1 = &7548 \ Mirror 1 base address (left mirror, middle segment) mirror2 = &7418 \ Mirror 2 base address (left mirror, inner segment) mirror3 = &7530 \ Mirror 3 base address (right mirror, inner segment) mirror4 = &7670 \ Mirror 4 base address (right mirror, middle segment) mirror5 = &7678 \ Mirror 5 base address (right mirror, outer segment) assistLeft1 = &77DB \ Centre-bottom of dashboard in screen memory for assistLeft2 = &77DC \ showing the computer assisted steering (CAS) assistRight1 = &77E3 \ indicator assistRight2 = &77E4 \ The following configuration variables represent screen \ addresses for mode 7 row2_column1 = &7C79 \ Chequered flag mode 7 screen address row18_column5 = &7E85 \ The first entry's number in a mode 7 menu row24_column5 = &7FC5 \ Location of "PRESS SPACE BAR TO CONTINUE" prompt
Name: Zero page [Show more] Type: Workspace Address: &0070 to &008F Category: Workspaces Summary: Mainly temporary variables that are used a lot
Context: See this workspace on its own page References: No direct references to this workspace in this source file
ORG &0000 .playerMoving SKIP 1 \ Flag to denote whether the player's car is moving \ \ * 0 = player's car is not moving \ \ * Non-zero = player's car is moving .thisSectionFlags SKIP 1 \ The track section flags for the current track section .thisVectorNumber SKIP 1 \ The number of the segment vector for the current track \ segment, ready to store in the track segment buffer \ as segmentVector .currentPosition SKIP 1 \ The position of the current player \ \ This refers to the current player's position in the \ driversInOrder list .thisSectionNumber SKIP 1 \ The number * 8 of the current section number when \ calculating the track verges .sectionListStart SKIP 1 \ The start index of the track section list that's \ used when calculating the positions of the track \ verges \ \ The list runs from index sectionListStart up to 6 .sectionListValid SKIP 1 \ The index of the first valid entry in the track \ section list \ \ The list runs from index sectionListStart up to 6, and \ valid entries run from index sectionListValid up to 6 \ \ Set to 6 in ResetVariables to indicate that the list \ does not yet contain any valid entries .sectionListSize SKIP 1 \ The size of the track section list that's used when \ calculating the positions of the track verges .sectionListPointer SKIP 1 \ The index of the current entry in the track section \ list, as we only update one entry in the list on each \ iteration of the main driving loop \ \ The list runs from index sectionListStart up to 6 \ \ Set to 6 in ResetVariables .oddsOfEngineStart SKIP 1 \ The chances of the engine starting while revving the \ engine (the engine will start with a chance of 1 in \ oddsOfEngineStart) \ \ Set to 7 in ResetVariables .playerYawAngleLo SKIP 1 \ Low byte of the player's yaw angle \ \ This is the left-right rotation of the player's car \ \ Stored as a 16-bit value (playerYawAngleHi \ playerYawAngleLo) .playerYawAngleHi SKIP 1 \ High byte of the player's yaw angle \ \ This is the left-right rotation of the player's car \ \ Stored as a 16-bit value (playerYawAngleHi \ playerYawAngleLo) .vectorNumber SKIP 1 \ The segment vector number when building car objects \ in the BuildCarObjects routine .playerPitchAngle SKIP 1 \ The player's pitch angle \ \ This is the up-down rotation of the player's car .segmentOffset SKIP 1 \ The offset to use for the segment being processed in \ the GetSegmentAngles routine \ \ * 0 when our car is facing in the same direction \ \ * 120 when our car is facing the opposite direction .leaveTrackTimer SKIP 1 \ The leave track timer \ \ When set to a non-zero figure, the timer starts to \ count down by one every iteration of the main loop, \ until it reaches 1, at which point we leave the track \ \ During the countdown we are unable to accelerate or \ brake, but can steer .edgeDistanceLo SKIP 1 \ Low byte of the distance between the player's car and \ the nearest track edge \ \ Stored as a 16-bit value (edgeDistanceHi \ edgeDistanceLo) .edgeDistanceHi SKIP 1 \ High byte of the distance between the player's car and \ the nearest track edge \ \ Stored as a 16-bit value (edgeDistanceHi \ edgeDistanceLo) .segmentListPointer SKIP 1 \ The index of the current entry in the track segment \ list \ \ As the segment list for the left side of the track is \ populated after the right side, this gives us the \ index of the last entry for the left side of the track \ once it has been populated \ \ segmentListRight gives us the equivalent index for the \ the right side of the track \ \ The list runs from index 6 upwards .edgeSegmentNumber SKIP 1 \ The number of the segment within the track segment \ list that is closest to the player's car .prevSegmentOffset SKIP 1 \ The segment coordinate offset for the previous segment \ when adding segments to the track segment list .segmentListRight SKIP 1 \ The index of the last entry in the track segment \ list for the right side of the track \ \ segmentListPointer gives us the equivalent index for \ the left side of the track .previousSteering SKIP 1 \ The previous value of sectionSteering when calculating \ the optimum steering for a track segment .turnCounter SKIP 1 \ A counter for the length of turn when calculating the \ optimum steering for a track segment .prevDriverSpeed06 SKIP 1 \ Bits 0-6 of the previous value of trackDriverSpeed \ when calculating the optimum steering for a track \ segment .gearChange SKIP 1 \ Used to store the direction of the gear change \ \ * 1 = change up \ \ * 0 = no gear change \ \ * -1 = change down .debugSpinning SKIP 1 \ This variable is never read, but is set to 64 and back \ to 0 when the car spins past the point where it \ changes the direction that it is facing along the \ track \ \ Perhaps it was used for debugging the spinning \ routines? .thisPitchIndex SKIP 0 \ The index of the pitch angle in the track segment list \ for the verge we are processing .thisObjectIndex SKIP 0 \ The index of the current object part's data as we work \ our way through an object's constituent parts .rowCounter SKIP 1 \ The table row number when printing the driver tables .pressingShiftArrow SKIP 1 \ Bit 7 is set if we are pressing SHIFT and right arrow \ (which restarts the game) .thisPosition SKIP 1 \ The position of the car that we are analysing in the \ MoveAndDrawCars routine .vergeOnScreenEdge SKIP 1 \ Determines whether the verge edge we are drawing for \ the current segment is partially off-screen \ \ * 0 = Edge is either wholly on-screen or off-screen \ \ * &FF = Edge is partially off-screen .horizonLine SKIP 1 \ The track line number of the horizon \ \ Track lines are one pixel high, and go from 79 (at the \ top of the track view, in the sky), down to 3 (the \ lowest track line, between the mirrors and dashboard) .prevDriverSpeed7 SKIP 1 \ The previous value of trackDriverSpeed when \ calculating the optimum steering for a track segment, \ only used for accessing bit 7 .sectionBehind SKIP 1 \ Used to store the number * 8 of the track section \ behind us when we drive backwards along the track \ \ Track sections are numbered from 0 to 23, so this \ ranges from 0 to 184 .playerSegmentIndex SKIP 1 \ Used to store the index * 3 of the track segment \ containing the player's car in the track segment \ buffer \ \ The player's car is always 32 segments behind the \ front segment in the track segment buffer, so this \ always contains frontSegmentIndex - 96, wrapped around \ as required (as there are three bytes per buffer \ entry) .prevSegmentIndex SKIP 1 \ Used to store the index * 3 of the previous track \ segment .frontSegmentIndex SKIP 1 \ Used to store the index * 3 of the front track \ segment in the track segment buffer \ \ Track segment indexes are numbered from 0 to 39, so \ this ranges from 0 to 117 .directionFacing SKIP 1 \ The direction that our car is facing \ \ * Bit 7 clear = facing forwards \ \ * Bit 7 set = facing backwards .yGravityDelta SKIP 1 \ The distance in the y-axis that the car would fall if \ the track wasn't there, for use when calculating the \ outcome of jumps and being dropped from the crane .vergeType SKIP 1 \ The type of verge that is currently being drawn in \ the DrawTrack routine: \ \ * 0 = leftVergeStart, the left edge of the left \ verge \ \ * 1 = leftTrackStart, the right edge of the left \ verge \ \ * 2 = rightVergeStart, the left edge of the right \ verge \ \ * 3 = rightGrassStart, the right edge of the right \ verge .yJumpHeight SKIP 1 \ The height of the car's jump (or crane lift), in terms \ of track lines, which we use to alter the position of \ the horizon .vergeTopRight SKIP 1 \ The track line just above the segment at \ vergeDepthOfField (i.e. the furthest segment that \ might contain a verge) when drawing the right verge .scaleUp SKIP 1 \ The nominator scale factor for scaling an object \ scaffold (i.e. scale up) \ \ The scaffold is multiplied by scaleUp .scaleDown SKIP 1 \ The denominator scale factor for scaling an object \ scaffold (i.e. scale down) \ \ The scaffold is divided by 2^scaleDown .vergeTopLeft SKIP 1 \ The track line just above the segment at \ vergeDepthOfField (i.e. the furthest segment that \ might contain a verge) when drawing the left verge .heightAboveTrack SKIP 1 \ The car's height above the track, for when it is being \ dropped from the crane, or jumping from hitting the \ verge too fast .playerSpeedLo SKIP 1 \ Low byte of the speed of the player's car along the \ track \ \ This appears to be in mph, with the high byte \ containing the miles per hour, and the low byte \ containing a fraction \ \ Stored as a 16-bit value (playerSpeedHi \ playerSpeedLo) .positionChangeBCD SKIP 1 \ The change in BCD for the player's race position \ \ Gets added to currentPositionBCD when non-zero \ \ Set to the current player's position in BCD in \ ResetVariables .pastHalfway SKIP 1 \ Stores which half of the track the player is in \ \ * 0 = the first half of the track \ \ * 1 = the second half of the track \ \ The halfway point is defined as the middle track \ section, or if there is an odd number of track \ sections, the section before the middle track section \ \ Set to 1 in ResetVariables .currentPositionBCD SKIP 1 \ The current race position in BCD \ \ Displayed at the top of the screen after "Position" .pixelMaskVerge SKIP 1 \ Offset within the vergePixelMask table for segments \ that are close enough to show a verge, i.e. those \ within the verge depth of field .backgroundLeft SKIP 1 \ Details of the verge colour for the left side of the \ verge edge we are drawing, to use as the track line's \ background colour .backgroundRight SKIP 1 \ Details of the verge colour for the right side of the \ verge edge we are drawing, to use as the track line's \ background colour .xPixelCoord SKIP 1 \ The pixel x-coordinate of the centre of the current \ object \ \ In terms of screen coordinates, so 0 is the left edge \ of the screen, 80 is the centre and 159 is the right \ edge .yPixelCoord SKIP 1 \ The pixel y-coordinate of the centre of the current \ object \ \ In terms of track lines, so 80 is the top of the track \ view and 0 is the bottom of the track view .objectType SKIP 1 \ The type of object to draw (0 to 12) \ \ * 0 = Four-object car, front tyres \ * 1 = Four-object car, body and helmet \ * 2 = Four-object car, rear tyres \ * 3 = Four-object car, rear wing \ * 4 = Standard car \ * 5 = Distant car \ * 6 = Corner marker \ * 7 = Straight sign \ * 8 = Start flag \ * 9 = Blank road sign \ * 10 = Chicane road sign \ * 11 = Right turn road sign \ * 12 = Left turn road sign .xPrevVelocityLo SKIP 1 \ Used to store the low byte of the x-coordinate of the \ player's previous velocity vector during the driving \ model calculations (i.e. the velocity from the last \ iteration of the main loop) \ \ Stored as a 16-bit value (xPrevVelocityHi \ xPrevVelocityLo) .xPrevVelocityHi SKIP 1 \ Used to store the high byte of the x-coordinate of the \ player's previous velocity vector during the driving \ model calculations (i.e. the velocity from the last \ iteration of the main loop) \ \ Stored as a 16-bit value (xPrevVelocityHi \ xPrevVelocityLo) .xSpinVelocityLo SKIP 1 \ Used to store the low byte of the scaled spin yaw \ angle during the driving model calculations \ \ Stored as a 16-bit value (xSpinVelocityHi \ xSpinVelocityLo) .xSpinVelocityHi SKIP 1 \ Used to store the high byte of the scaled spin yaw \ angle during the driving model calculations \ \ Stored as a 16-bit value (xSpinVelocityHi \ xSpinVelocityLo) .revCount SKIP 1 \ The current rev count, as shown on the rev counter .engineTorque SKIP 1 \ The power being generated by the engine .throttleBrakeState SKIP 1 \ Denotes whether the throttle or brake are being \ applied \ \ * Bit 7 is set if there is no brake or throttle key \ press \ \ * 0 = brakes are being applied \ \ * 1 = throttle is being applied .throttleBrake SKIP 1 \ The amount of throttle or brake being applied .gearNumber SKIP 1 \ The current gear number \ \ * 0 = reverse \ \ * 1 = neutral \ \ * 2-7 = 1 to 5 .objectDistanceLo SKIP 1 \ The low byte of the distance to the current object \ \ If a car's objectDistanceHi is >= 5, then it is drawn \ as a distant car \ \ Stored as a 16-bit value (objectDistanceHi \ objectDistanceLo) .colourScheme SKIP 0 \ The number of the table colour scheme passed to the \ SetRowColours routine: \ \ Scheme 0: Even rows: 132 on 134 (blue on cyan) \ Odd rows: 134 on 135 (cyan on white) \ \ Scheme 4: Even rows: 129 on 132 (red on blue) \ Odd rows: 131 on 130 (yellow on green) \ \ Scheme 8: Even rows: 131 on 132 (yellow on blue) \ Odd rows: 129 on 135 (red on white) .objectNumber SKIP 0 \ The object number of the four-part car we are drawing .sectionCounter SKIP 0 \ A counter for the track section we are processing .segmentCounter SKIP 0 \ A counter for the track segment we are processing .blockCounter SKIP 0 \ A counter for the dash data block we are processing .secondAxis SKIP 1 \ The number of the second axis to calculate in the \ GetRotationMatrix routine .playerPastSegment SKIP 1 \ Determines whether the player has gone past the \ closest segment to the player (i.e. whether the \ relative yaw angle of the segment is greater than 90 \ degrees) \ \ * Bit 7 clear = not yet \ \ * Bit 7 set = player has gone past the closest \ segment .playerHeading SKIP 1 \ The player's yaw angle, relative to the direction of \ the track, where a heading of 0 means the player is \ pointing straight along the track .driverPrinted SKIP 0 \ The number of the driver we just printed in the \ PrintPositionName routine .thisDriver SKIP 0 \ The number of the car we are currently drawing .xStoreDraw SKIP 0 \ Temporary storage for X so it can be preserved through \ calls to DrawCarInPosition, DrawCarOrSign and \ DrawSegmentEdge .thisYawIndex SKIP 0 \ The index of the yaw angle in the track segment list \ for the verge we are processing .thisSignNumber SKIP 1 \ The sign number that we are currently building .timerAdjust SKIP 1 \ A counter for implementing the clock speed adjustment \ \ Starts out with the value of trackTimerAdjust from the \ track data (see the ProcessTime routine) \ \ Gets decremented on each iteration of the main driving \ loop, looping back to trackTimerAdjust after reaching \ zero \ \ When timerAdjust matches equals trackTimerAdjust, the \ clock timer adds 18/100 of a second rather than the \ usual 9/100 of a second, so the clock timer speeds up \ every time the counter loops round \ \ Decreasing the value of trackTimerAdjust therefore \ speeds up the clock timer, allowing the speed of the \ clock timer to be adjusted on a per-track basis \ \ The Silverstone track has a trackTimerAdjust value of \ 24, so timerAdjust wraps around from 0 to 24 .bottomTrackLine SKIP 1 \ The bottom track line for the current object part .prevEdgeInByte SKIP 1 \ Determines whether we are drawing two edges within the \ same pixel byte in DrawObjectEdge .segmentDirection SKIP 1 \ The relative dirction of our car, to use when \ processing segments in the GetSegmentAngles routine \ \ * 0 when our car is facing in the same direction \ \ * 1 when our car is facing in the opposite direction .setSpeedForDriver SKIP 1 \ The driver whose speed will be set on the next call to \ the SetDriverSpeed routine .vergeBufferEnd SKIP 1 \ The index of the last entry in the track verge buffer \ for the side of the track we are currently drawing in \ DrawTrack .prevPitchIndex SKIP 1 \ The index of the pitch angles in the verge buffer for \ the previous entry in the verge buffer when drawing \ the verge edges .positionAhead SKIP 1 \ The number of the position ahead of the current \ player's position \ \ This refers to the current player's position in the \ driversInOrder list \ \ The position ahead of the leader is last place .spinPitchAngle SKIP 1 \ The amount of pitch angle spin that is being applied \ to the player's car .prevYawIndex SKIP 1 \ The index of the yaw angles in the verge buffer for \ the previous entry in the verge buffer when drawing \ the verge edges .vergeDepthOfField SKIP 1 \ The index into the verge buffer of the furthest verge \ mark, so for segments further from the player than \ this point, we do not draw verge marks .horizonListIndex SKIP 1 \ The track section or segment that's on the horizon, \ given in terms of the index within the track section \ list (or the track segment list) \ \ Specifically, entry number horizonListIndex at \ yVergeRight equals horizonLine, as does the same entry \ in yVergeLeft (as the track is level in a left to \ right direction) .prevHorizonIndex SKIP 1 \ The value of horizonListIndex from the previous call \ to the GetTrackAndMarkers routine .updateBackground SKIP 1 \ Flag to indicate we have changed the background colour \ of a track line \ \ Set to non-zero if we draw a track verge in the first \ part of the track line on the left edge of the screen .pixelMaskIndex SKIP 1 \ The index into the vergePixelMask table for the colour \ of the verge edge we are drawing in DrawSegmentEdge .objectDistanceHi SKIP 1 \ The high byte of the distance to the current object \ \ If a car's objectDistanceHi is >= 5, then it is drawn \ as a distant car \ \ Stored as a 16-bit value (objectDistanceHi \ objectDistanceLo) .markerNumber SKIP 1 \ The marker number that we are drawing in the \ DrawCornerMarkers routine .markersToDraw SKIP 1 \ The number of corner markers to draw .gearChangeKey SKIP 1 \ Determines whether or not a gear change key has been \ pressed \ \ * Bit 7 set = a gear change key has been pressed .clutchEngaged SKIP 1 \ Determines whether the clutch is engaged \ \ * Bit 7 clear = clutch is engaged \ \ * Bit 7 set = clutch is not fully engaged .revsOnGearChange SKIP 1 \ The rev count when the gear was last changed .positionBehind SKIP 1 \ The number of the position behind the current player's \ position \ \ This refers to the current player's position in the \ driversInOrder list \ \ The position behind last place is the leader .edgeSegmentPointer SKIP 1 \ The index of the segment within the track verge buffer \ that is closest to the player's car .bumpyGrassHeight SKIP 1 \ The height of the bumps when driving over grass, which \ fluctuates randomly in the range 1 to 7 .edgeYawAngle SKIP 1 \ The yaw angle of the track segment that is closest to \ the player's car, from the point of view of the car .soundRevTarget SKIP 1 \ The target pitch for the revs sound \ \ The pitch for the revs sound moves towards this pitch \ level one step at a time, to simulate the sound of the \ engine "catching up" to the throttle \ \ The target pitch is set to revCount + 25 .soundRevCount SKIP 1 \ The current pitch for the revs sound .engineStatus SKIP 1 \ Whether or not the engine is on \ \ * 0 = engine is off \ \ * &FF = engine is on .resetSectionList SKIP 1 \ Controls whether to reset the contents of the track \ section list \ \ * 0 = do not reset the track section list \ \ * Non-zero = reset the track section list .playerSpeedHi SKIP 1 \ High byte of the speed of the player's car along the \ track \ \ This appears to be in mph, with the high byte \ containing the miles per hour, and the low byte \ containing a fraction \ \ Stored as a 16-bit value (playerSpeedHi \ playerSpeedLo) .printMode SKIP 1 \ Determines how the next character is printed \ on-screen: \ \ * 0 = poke the character directly into screen memory \ \ * 1 = print the character with OSWRCH (for mode 7) .qualifyTimeEnding SKIP 1 \ Determines whether the time warnings have been shown \ at the end of the qualifying time: \ \ * Bit 6 set = the one-minute warning has been shown \ \ * Bit 7 set = the time-up watning has been shown .updateDrivingInfo SKIP 1 \ Determines which parts of the driving information \ should be updated at the top of the screen \ \ * Bit 7 set = update lap number (during a race) \ update lap time (practice/qualifying) \ \ * Bit 6 set = we are driving the first practice or \ qualifying lap, so do not update the \ best lap time \ \ Set to %10000000 in ResetVariables for race laps only .collisionDriver SKIP 1 \ The number of the driver being hit by the player's car .processContact SKIP 1 \ Another car is close enough to the player's car for us \ to process car-on-car contact \ \ * 0 = no car is close enough \ \ * Non-zero = a car is close enough to check for \ contact .lineBufferSize SKIP 1 \ The size of the line buffer \ \ Zeroed in SetupGame .mainLoopCounterLo SKIP 1 \ Low byte of the main loop counter, which increments on \ each iteration of the main driving loop \ \ Stored as a 16-bit value (mainLoopCounterHi \ mainLoopCounterLo) .startingStack SKIP 1 \ The value of the stack pointer when the game starts, \ so we can restore it when restarting the game .raceStarted SKIP 1 \ Flag determining whether the race has started \ \ * Bit 7 clear = this is practice or a qualifying lap \ \ * Bit 7 set = the race has started .raceStarting SKIP 1 \ The current stage of the starting lights at the start \ of the race \ \ When a race is about to start, raceStarting is set to \ 128, and stays on this value until the engine is \ started, at which point it starts to count down, with \ one tick per iteration of the main loop, working \ through the following sequence: \ \ * 128 = show black lights, engine not yet started \ \ * Start counting down from 240 once engine starts \ \ * 240-192 = show black lights \ \ * 191-161 = show blue lights \ \ * 160 = keep showing blue lights and stop counting \ down until main loop counter is a multiple \ of 64 \ \ * Start counting down from 40 once loop counter is \ a multiple of 64 \ \ * 40-1 = show green lights \ \ * 0 = show no lights (race has started) \ \ When bit 7 is set (i.e. raceStarting >= 128), we are \ on the grid, so we do not increment the clock timer in \ ProcessTime, and the MoveCars routine has no effect .numberOfLaps SKIP 1 \ The number of laps in the race (5, 10 or 20) .currentPlayer SKIP 1 \ The number of the current player \ \ * 0 for practice \ \ * 0 to 19 for competition .P SKIP 1 \ Temporary storage, used in a number of places .Q SKIP 1 \ Temporary storage, used in a number of places .R SKIP 1 \ Temporary storage, used in a number of places .S SKIP 1 \ Temporary storage, used in a number of places .T SKIP 1 \ Temporary storage, used in a number of places .U SKIP 1 \ Temporary storage, used in a number of places .edgePixel SKIP 0 \ The current edge, as a one-pixel byte .V SKIP 1 \ Temporary storage, used in a number of places .W SKIP 1 \ Temporary storage, used in a number of places .leftOfEdge SKIP 0 \ The fill colour to the left of the edge we are drawing .G SKIP 1 \ Temporary storage, used in a number of places .rightOfEdge SKIP 0 \ The fill colour to the right of the edge we are \ drawing .H SKIP 1 \ Temporary storage, used in a number of places .I SKIP 1 \ Temporary storage, used in a number of places .J SKIP 1 \ Temporary storage, used in a number of places .prevBlockNumber SKIP 0 \ The dash data block number for the previous edge .K SKIP 1 \ Temporary storage, used in a number of places .L SKIP 1 \ Temporary storage, used in a number of places .thisEdge SKIP 0 \ The current edge that we are drawing as part of an \ object part .M SKIP 1 \ Temporary storage, used in a number of places .topTrackLine SKIP 0 \ The top track line for the current object part .N SKIP 1 \ Temporary storage, used in a number of places .PP SKIP 1 \ Temporary storage, used in a number of places .QQ SKIP 1 \ Temporary storage, used in a number of places .blockOffset SKIP 0 \ The dash data offset for the current edge .RR SKIP 1 \ Temporary storage, used in a number of places .nextEdge SKIP 0 \ The next edge that we are drawing as part of an \ object part (where applicable) .SS SKIP 1 \ Temporary storage, used in a number of places .colourData SKIP 0 \ Colour data for the current object part .TT SKIP 1 \ Temporary storage, used in a number of places .blockNumber SKIP 0 \ The dash data block number for the current edge .UU SKIP 1 \ Temporary storage, used in a number of places .VV SKIP 1 \ Temporary storage, used in a number of places .WW SKIP 1 \ Temporary storage, used in a number of places .GG SKIP 1 \ Temporary storage, used in a number of places .HH SKIP 1 \ This byte does not appear to be used .II SKIP 1 \ Temporary storage, used in a number of places .JJ SKIP 1 \ Temporary storage, used in a number of places .edgePixelMask SKIP 0 \ The pixel mask for the previous edge .pixelMaskNoVerge SKIP 1 \ Offset within the vergePixelMask table for segments \ that are too far away to show a verge, i.e. those \ outside the verge depth of field .nextBlockNumber SKIP 0 \ The dash data block number for the next edge .LL SKIP 1 \ Temporary storage, used in a number of places .MM SKIP 1 \ Temporary storage, used in a number of places .nextEdgeCoord SKIP 0 \ The x-coordinate for the next edge .NN SKIP 1 \ Temporary storage, used in a number of places
Name: Stack variables [Show more] Type: Workspace Address: &0100 to &0175 Category: Workspaces Summary: Variables that share page 1 with the stack
Context: See this workspace on its own page References: No direct references to this workspace in this source file
ORG &0100 .positionNumber SKIP 0 \ Position numbers to show in the first column of the \ driver table .carStatus SKIP 20 \ Each car's status byte \ \ * Bit 0 = update this carStatus byte when applying \ tactics in the ProcessOvertaking routine \ \ * Clear = do update carStatus \ \ * Set = do not update carStatus \ \ * Bit 4 = affects driving around corners for visible \ cars (see BuildVisibleCar) \ \ * Clear = set carSteering to the segment's \ steering line in segmentSteering when \ going fast enough (carSpeedHi >= 50) \ \ * Set = do not set carSteering in the \ BuildVisibleCar routine (and use the \ value set by ProcessOvertaking instead) \ \ * Bit 6 = acceleration status \ \ * Clear = do not acclerate car \ \ * Set = acclerate car \ \ * Bit 7 = braking status \ \ * Clear = do not apply brakes \ \ * Set = apply brakes .carSteering SKIP 20 \ Contains the steering to apply to each car \ \ * Bits 0-5 = the amount of steering as a positive \ value (0 to 31) \ \ * Bit 6 = controls whether to apply steering in the \ MoveCars routine \ \ * Clear = always apply steering \ \ * Set = only apply steering if there is enough \ room on the track \ \ * Bit 7 = the direction of the steering \ \ * Clear = steer left \ \ * Set = steer right \ \ The steering is stored as a sign-magnitude number, \ where the sign is in bit 7 and the magnitude is in \ bits 0-5 \ \ The amount of steering is stored in terms of the \ change in racing line, where the width of the track is \ 256, so steering by 26 would steer the car sideways by \ 10% of the track width .driverSpeed SKIP 20 \ The average speed of this driver in the race (88 to \ 162) \ \ The speed for each driver depends on a number of \ factors, and is calculated in the SetDriverSpeed \ routine \ \ Indexed by driver number (0 to 19) .driversInOrder SKIP 20 \ A list of driver numbers in order \ \ For example, during a race, this contains the race \ position of each driver in the race (i.e. first place, \ second place etc.) \ \ It is also used to sort drivers by lap time and points \ for the driver table \ \ Indexed by driver number (0 to 19) \ \ Gets set in InitialiseDrivers to the number of each \ driver, so the initial order is driver number .carSpeedHi SKIP 20 \ High byte of each car's forward speed \ \ Stored as an 8-bit value (carSpeedHi carSpeedLo) .carProgress SKIP 20 \ Lowest byte of each car's progress through the segment \ it's in \ \ This is effectively a fractional part of the car's \ progress throught the segment, with 0 being the start \ of the segment and 255 the end of the segment \ \ When this byte rolls over, we increment the car's \ segment number in (objectSegmentHi objectSegmentLo) to \ move on to the next segment .carRacingLine SKIP 20 \ Each car's position on the track in the x-axis \ \ This determines how far each car is to the left or \ right on the track - i.e. it's the car's racing line \ \ * 0 is full right \ \ * 128 is the centre line \ \ * 255 is full left \ \ Bit 7 is therefore set if the car is in the left half \ the track, and clear for the right half .objectStatus SKIP 24 \ Various status flags for each object \ \ * Bits 0-3 = the object type \ \ * Bit 6: 0 = the car is still racing \ 1 = the car has finished the race \ \ * Bit 7: 0 = object is visible \ 1 = object is hidden \ \ Set to &80 in ResetVariables .carSectionSpeed SKIP 20 \ Set to the driver speed for the next track section, \ which is taken from the track data and used to set the \ section's maximum speed for non-player drivers \ \ Only applies to sections with bit 7 of the flag byte \ set, in which case carSectionSpeed is set to the \ trackDriverSpeed value from the preceding track \ section \ \ Set to 255 in ResetVariables, which means no minimum \ speed
Name: Main variable workspace [Show more] Type: Workspace Address: &0380 to &07F8 and &0880 to &0AFF Category: Workspaces Summary: The main block of game variables
Context: See this workspace on its own page References: No direct references to this workspace in this source file
ORG &0380 .objYawAngleLo SKIP 24 \ Low byte of each object's yaw angle \ \ Stored as a 16-bit value (objYawAngleHi objYawAngleLo) .objYawAngleHi SKIP 24 \ High byte of each object's yaw angle \ \ Stored as a 16-bit value (objYawAngleHi objYawAngleLo) .objectPitchAngle SKIP 24 \ Each object's pitch angle .objectSize SKIP 24 \ The size of each of the objects (i.e. the scaled value \ of scaleUp for the object) SKIP 32 \ These bytes appear to be unused .leftSegment SKIP 80 \ For each track line, the index of the segment within \ the track segment list for the left verge .rightSegment SKIP 80 \ For each track line, the index of the segment within \ the track segment list for the right verge .driverGridRow SKIP 20 \ The grid row for each driver (0 to 9) \ \ There are two cars per grid row, with grid row 0 at \ the front including the car in pole position \ \ There are 20 cars, in rows 0 to 9 \ \ Indexed by driver number (0 to 19) \ \ Gets set in InitialiseDrivers .driverLapNumber SKIP 20 \ The current lap number for each driver \ \ Indexed by driver number (0 to 19) .driversInOrder2 SKIP 20 \ Used to store a copy of the driversInOrder list .totalRaceMinutes SKIP 20 \ Minutes of each driver's total race time, stored in \ BCD \ \ Set to &80 in ResetVariables .totalPointsTop SKIP 20 \ Top byte of total accumulated points for each driver \ \ Indexed by driver number (0 to 19) \ \ Gets set to 0 in InitialiseDrivers \ \ Stored as a 24-bit value (totalPointsTop totalPointsHi \ totalPointsLo) .tyreRightEdge SKIP 80 \ Storage for the first track pixel byte along the right \ edge of the left tyre \ \ This table is used to store the track pixel byte that \ would be shown along the edge of the left tyre, but \ which is partially obscured by the edge \ \ This is stored so we can retrieve it when masking the \ pixel byte with the tyre edge when we draw the track \ line that starts at the edge of the left tyre \ \ There is a byte for each track line from 43 (the track \ line at the top of the dashboard) down to line 3 (the \ lowest track line, just above where the wing mirror \ joins the car body) \ \ Lines 0 to 2 are not used .rightGrassStart SKIP 80 \ For each track line, the block number where the grass \ starts to the right of the track .leftVergeStart SKIP 80 \ For each track line, the block number where the left \ track verge starts .configStop SKIP 1 \ A key has been pressed that stops the race \ \ * Bit 5 set = retire from race/lap \ (SHIFT-f7 pressed) \ \ * Bit 7 and bit 6 set = pit stop \ (SHIFT-f0 pressed) \ \ * Bit 7 set and bit 6 clear = restart game \ (SHIFT and right arrow pressed) \ \ Zeroed in SetupGame .configJoystick SKIP 1 \ A key has been pressed to set joystick or keyboard \ \ * No bits set = keyboard \ (SHIFT-f1 pressed) \ \ * Bit 7 set = joystick \ (SHIFT-f2 pressed) \ \ Zeroed in SetupGame .configVolume SKIP 1 \ A key has been pressed to change the volume \ \ * Bit 7 and bit 6 set = volume down \ (SHIFT-f4 pressed) \ \ * Bit 7 clear and bit 6 set = volume up \ (SHIFT-f5 pressed) \ \ Zeroed in SetupGame .configPause SKIP 1 \ A key has been pressed to pause the game \ \ * Bit 7 set = pause game \ (COPY pressed) \ \ * Bit 6 set = unpause game \ (DELETE pressed) \ \ Zeroed in SetupGame .configAssist SKIP 1 \ A key has been pressed to toggle computer assisted \ steering (CAS) \ \ * No bits set = disable computer assisted steering \ (SHIFT-f3 pressed) \ \ * Bit 7 set = enable computer assisted steering \ (SHIFT-f6 pressed) \ \ Zeroed in SetupGame SKIP 5 \ These bytes appear to be unused .volumeLevel SKIP 1 \ The game's volume level \ \ This uses the operating system's volume scale, with \ -15 being full volume and 0 being silent \ \ Set to -10 (246) in SetupGame SKIP 1 \ This byte appears to be unused .rightVergeStart SKIP 80 \ For each track line, the block number where the right \ track verge starts .leftTrackStart SKIP 80 \ For each track line, the block number where the track \ starts (i.e. the left edge of the black track) .bestLapTenths SKIP 20 \ Tenths of seconds of each driver's best lap time, \ stored in BCD \ \ Indexed by driver number (0 to 19) .clockTenths SKIP 1 \ Tenths of seconds for the clock timer \ \ The clock timer counts the time spent on the track, so \ that's the total amount of qualifying time, or the \ time spent throughout an entire race .lapTenths SKIP 1 \ Tenths of seconds for the lap timer \ \ The lap timer counts the time spent on the current lap SKIP 2 \ These bytes appear to be unused .bestLapSeconds SKIP 20 \ Seconds of each driver's best lap time, stored in BCD \ \ Indexed by driver number (0 to 19) .clockSeconds SKIP 1 \ Seconds for the clock timer \ \ The clock timer counts the time spent on the track, so \ that's the total amount of qualifying time, or the \ time spent throughout an entire race .lapSeconds SKIP 1 \ Seconds for the lap timer \ \ The lap timer counts the time spent on the current lap SKIP 2 \ These bytes appear to be unused .bestLapMinutes SKIP 20 \ Minutes of each driver's best lap time, stored in BCD \ \ Indexed by driver number (0 to 19) .clockMinutes SKIP 1 \ Minutes for the clock timer \ \ The clock timer counts the time spent on the track, so \ that's the total amount of qualifying time, or the \ time spent throughout an entire race .lapMinutes SKIP 1 \ Minutes for the lap timer \ \ The lap timer counts the time spent on the current lap SKIP 2 \ These bytes appear to be unused .objTrackSection SKIP 24 \ The number of the track section * 8 for each object \ \ In the Silverstone track there are 24 track sections \ numbered from 0 to 23, so this ranges from 0 to 184 .segmentVector SKIP 1 \ The segment vector number for a track segment in the \ track segment buffer .segmentSteering SKIP 1 \ The carSteering value to steer round the corner for a \ track segment in the track segment buffer \ \ The various bits are as for carSteering: \ \ * Bits 0-5 = the amount of steering as a positive \ value (0 to 31) \ \ * Bit 6 = controls whether to apply steering in the \ MoveCars routine \ \ * Clear = always apply steering \ \ * Set = only apply steering if there is enough \ room on the track \ \ * Bit 7 = the direction of the steering \ \ * Clear = steer left \ \ * Set = steer right .segmentFlags SKIP 1 \ Flags for a track segment in the track segment buffer \ \ Based on the track section flags for the track section \ containing the segment, but updated for each segment SKIP 39 * 3 \ The track segment buffer contains data for 40 track \ segments, with three bytes per segment, so this \ reserves space for the other 39 SKIP 8 \ These bytes appear to be unused .lineBufferPixel SKIP 40 \ The original screen contents of each pixel in the line \ buffer .lineBufferAddrLo SKIP 40 \ The low byte of the screen address of each pixel in \ the line buffer \ \ Stored as a 16-bit value (lineBufferAddrHi \ lineBufferAddrLo) .lineBufferAddrHi SKIP 40 \ The low byte of the screen address of each pixel in \ the line buffer \ \ Stored as a 16-bit value (lineBufferAddrHi \ lineBufferAddrLo) ORG &0880 .objSectionSegmt SKIP 24 \ Each object's segment number within the current track \ section, counting from the start of the section \ \ This value increments along with objectSegment as the \ object moves through each segment along the track, \ until it reaches the section's trackSectionSize (the \ section's length in terms of segments), at which point \ it resets to zero for the next section \ \ So while objectSegment is the object's segment number \ when looking at the entire track, objSectionSegmt is \ the object's segment number within the current track \ section only .totalRaceTenths SKIP 20 \ Tenths of seconds of each driver's total race time, \ stored in BCD \ \ Indexed by driver number (0 to 19) .totalRaceSeconds SKIP 20 \ Seconds of each driver's total race time, stored in \ BCD \ \ Indexed by driver number (0 to 19) SKIP 16 \ These bytes appear to be unused .objectSegmentLo SKIP 24 \ Low byte of each object's segment, i.e. its position \ around on the track \ \ Segment 0 is on the starting line, and segment numbers \ go from 0 to trackLength as we move along the track, \ before wrapping back to zero again at the end of the \ lap \ \ Set to the value of trackStartLine in ResetVariables \ \ The Silverstone track has a total of 1024 segments \ \ Stored as a 16-bit value (objectSegmentHi \ objectSegmentLo) .objectSegmentHi SKIP 24 \ High byte of each object's segment, i.e. its position \ around on the track \ \ Segment 0 is on the starting line, and segment numbers \ go from 0 to trackLength as we move along the track, \ before wrapping back to zero again at the end of the \ lap \ \ Set to the value of trackStartLine in ResetVariables \ \ The Silverstone track has a total of 1024 segments \ \ Stored as a 16-bit value (objectSegmentHi \ objectSegmentLo) .xSegmentCoordILo SKIP 1 \ The low byte of the 3D x-coordinate for an inner track \ segment in the track segment buffer \ \ Stored as a 16-bit value (xSegmentCoordIHi \ xSegmentCoordILo) .ySegmentCoordILo SKIP 1 \ The low byte of the 3D y-coordinate for an inner track \ segment in the track segment buffer \ \ Stored as a 16-bit value (ySegmentCoordIHi \ ySegmentCoordILo) .zSegmentCoordILo SKIP 1 \ The low byte of the 3D z-coordinate for an inner track \ segment in the track segment buffer \ \ Stored as a 16-bit value (zSegmentCoordIHi \ zSegmentCoordILo) SKIP 39 * 3 \ The track segment buffer contains data for 40 track \ segments, with three bytes per segment, so this \ reserves space for the other 39 .xSegmentCoordOLo SKIP 1 \ The low byte of the 3D x-coordinate for an outer track \ segment in the track segment buffer \ \ Stored as a 16-bit value (xSegmentCoordOHi \ xSegmentCoordOLo) .ySegmentCoordOLo SKIP 1 \ The low byte of the 3D y-coordinate for an outer track \ segment in the track segment buffer \ \ Stored as a 16-bit value (ySegmentCoordOHi \ ySegmentCoordOLo) .zSegmentCoordOLo SKIP 1 \ The low byte of the 3D z-coordinate for an outer track \ segment in the track segment buffer \ \ Stored as a 16-bit value (zSegmentCoordOHi \ zSegmentCoordOLo) SKIP 39 * 3 \ The track segment buffer contains data for 40 track \ segments, with three bytes per segment, so this \ reserves space for the other 39 SKIP 4 \ These bytes appear to be unused .xHelmetCoordLo SKIP 1 \ Low byte of the x-coordinate of the body/helmet object \ in the four-object car \ \ Stored as a 16-bit value (xHelmetCoordHi \ xHelmetCoordLo) .yHelmetCoordLo SKIP 1 \ Low byte of the y-coordinate of the body/helmet object \ in the four-object car \ \ Stored as a 16-bit value (yHelmetCoordHi \ yHelmetCoordLo) .zHelmetCoordLo SKIP 1 \ Low byte of the z-coordinate of the body/helmet object \ in the four-object car \ \ Stored as a 16-bit value (zHelmetCoordHi \ zHelmetCoordLo) SKIP 3 \ These bytes appear to be unused .xCoord1Lo SKIP 1 \ The low byte of the x-coordinate of the temporary \ coordinate variable (xCoord1, yCoord1, zCoord1) \ \ Stored as a 16-bit value (xCoord1Hi xCoord1Lo) .yCoord1Lo SKIP 1 \ The low byte of the y-coordinate of the temporary \ coordinate variable (xCoord1, yCoord1, zCoord1) \ \ Stored as a 16-bit value (yCoord1Hi yCoord1Lo) .zCoord1Lo SKIP 1 \ The low byte of the z-coordinate of the temporary \ coordinate variable (xCoord1, yCoord1, zCoord1) \ \ Stored as a 16-bit value (zCoord1Hi zCoord1Lo) .xCoord2Lo SKIP 1 \ The low byte of the x-coordinate of the temporary \ coordinate variable (xCoord2, yCoord2, zCoord2) \ \ Stored as a 16-bit value (xCoord2Hi xCoord2Lo) .yCoord2Lo SKIP 1 \ The low byte of the y-coordinate of the temporary \ coordinate variable (xCoord2, yCoord2, zCoord2) \ \ Stored as a 16-bit value (yCoord2Hi yCoord2Lo) .zCoord2Lo SKIP 1 \ The low byte of the z-coordinate of the temporary \ coordinate variable (xCoord2, yCoord2, zCoord2) \ \ Stored as a 16-bit value (zCoord2Hi zCoord2Lo) .xSegmentCoordIHi SKIP 1 \ The high byte of the 3D x-coordinate for an inner \ track segment in the track segment buffer \ \ Stored as a 16-bit value (xSegmentCoordIHi \ xSegmentCoordILo) .ySegmentCoordIHi SKIP 1 \ The high byte of the 3D y-coordinate for an inner \ track segment in the track segment buffer \ \ Stored as a 16-bit value (ySegmentCoordIHi \ ySegmentCoordILo) .zSegmentCoordIHi SKIP 1 \ The high byte of the 3D z-coordinate for an inner \ track segment in the track segment buffer \ \ Stored as a 16-bit value (zSegmentCoordIHi \ zSegmentCoordILo) SKIP 39 * 3 \ The track segment buffer contains data for 40 track \ segments, with three bytes per segment, so this \ reserves space for the other 39 .xSegmentCoordOHi SKIP 1 \ The high byte of the 3D x-coordinate for an outer \ track segment in the track segment buffer \ \ Stored as a 16-bit value (xSegmentCoordOHi \ xSegmentCoordOLo) .ySegmentCoordOHi SKIP 1 \ The high byte of the 3D y-coordinate for an outer \ track segment in the track segment buffer \ \ Stored as a 16-bit value (ySegmentCoordOHi \ ySegmentCoordOLo) .zSegmentCoordOHi SKIP 1 \ The high byte of the 3D z-coordinate for an outer \ track segment in the track segment buffer \ \ Stored as a 16-bit value (zSegmentCoordOHi \ zSegmentCoordOLo) SKIP 39 * 3 \ The track segment buffer contains data for 40 track \ segments, with three bytes per segment, so this \ reserves space for the other 39 SKIP 4 \ These bytes appear to be unused .xHelmetCoordHi SKIP 1 \ High byte of the x-coordinate of the body/helmet \ object in the four-object car \ \ Stored as a 16-bit value (xHelmetCoordHi \ xHelmetCoordLo) .yHelmetCoordHi SKIP 1 \ High byte of the y-coordinate of the body/helmet \ object in the four-object car \ \ Stored as a 16-bit value (yHelmetCoordHi \ yHelmetCoordLo) .zHelmetCoordHi SKIP 1 \ High byte of the z-coordinate of the body/helmet \ object in the four-object car \ \ Stored as a 16-bit value (yHelmetCoordHi \ yHelmetCoordLo) SKIP 3 \ These bytes appear to be unused .xCoord1Hi SKIP 1 \ The high byte of the x-coordinate of the temporary \ coordinate variable (xCoord1, yCoord1, zCoord1) \ \ Stored as a 16-bit value (xCoord1Hi xCoord1Lo) .yCoord1Hi SKIP 1 \ The high byte of the y-coordinate of the temporary \ coordinate variable (xCoord1, yCoord1, zCoord1) \ \ Stored as a 16-bit value (yCoord1Hi yCoord1Lo) .zCoord1Hi SKIP 1 \ The high byte of the z-coordinate of the temporary \ coordinate variable (xCoord1, yCoord1, zCoord1) \ \ Stored as a 16-bit value (zCoord1Hi zCoord1Lo) .xCoord2Hi SKIP 1 \ The high byte of the x-coordinate of the temporary \ coordinate variable (xCoord2, yCoord2, zCoord2) \ \ Stored as a 16-bit value (xCoord2Hi xCoord2Lo) .yCoord2Hi SKIP 1 \ The high byte of the y-coordinate of the temporary \ coordinate variable (xCoord2, yCoord2, zCoord2) \ \ Stored as a 16-bit value (yCoord2Hi yCoord2Lo) .zCoord2Hi SKIP 1 \ The high byte of the z-coordinate of the temporary \ coordinate variable (xCoord2, yCoord2, zCoord2) \ \ Stored as a 16-bit value (zCoord2Hi zCoord2Lo)