# Car geometry: MoveCars (Part 2 of 2)

```       Name: MoveCars (Part 2 of 2)                                  [Show more]
Type: Subroutine
Category: Car geometry
Summary: Move the cars forward around the track, and apply steering
Deep dive: Placing cars on the track
Tactics of the non-player drivers
Context: See this subroutine in context in the source code
References: No direct references to this subroutine in this source file

This part moves the car round the track by the speed we just calculated, and
applies steering if required.

The steering algorithm works as follows:

* Only apply steering if the car is visible.

* If any of the following are true, apply the amount of steering given in
carSteering:

* Bit 6 of the car's objectStatus is set

* Bit 6 of the car's carSteering is clear

* Bit 7 of the car's racing line = bit 7 of carSteering, so:

* Car is in the right half and is steering left (when bit 7 is clear)

* Car is in the left half and is steering right (when bit 7 is set)

* The car is not within 30 of either verge, 30 <= carRacingLine < 226

* Otherwise, if the car's racing line is within 20 of either verge, steer
away from the verge by one.

LDA objectStatus,X     \ If bit 7 of the driver's car object status byte is
ASL A                  \ set, then the car is not visible, so jump to mar20 to
BCS mcar20             \ move on to the next car

BMI mcar17             \ If bit 6 of the driver's car object status byte is
\ mcar17 to steer the car

LDA carSteering,X      \ If bit 6 of the car's carSteering is clear, jump to
AND #%01000000         \ mcar17 to steer the car
BEQ mcar17

LDA carRacingLine,X    \ If bit 7 of the car's racing line and carSteering are
EOR carSteering,X      \ the same (so the car is steering into the opposite
BPL mcar17             \ half of the track), jump to mcar17 to steer the car

LDA carRacingLine,X    \ If the car's racing line < 128, then the car is in the
BPL mcar15             \ right half of the track, so jump to mcar15 to check
\ how close it is to the right verge

CMP #236               \ If the car's racing line < 236, jump to mcar14
BCC mcar14

\ If we get here then the car's racing line >= 236,
\ which is very close to the left verge, so we steer a
\ little to the right

DEC carRacingLine,X    \ Steer the car a little to the right

BCS mcar20             \ Jump to mcar20 (this BCS is effectively a JMP as we
\ just passed through a BCC)

.mcar14

CMP #226               \ If the car's racing line < 226, jump to mcar17 to
BCC mcar17             \ steer the car

\ If we get here, then the car's racing line >= 226,
\ which is quite close to the left verge

BCS mcar20             \ Jump to mcar20 (this BCS is effectively a JMP as we
\ just passed through a BCC)

.mcar15

CMP #20                \ If the car's racing line >= 20, jump to mcar16
BCS mcar16

\ If we get here then the car's racing line < 20, which
\ is very close to the right verge, so we steer a little
\ to the left

INC carRacingLine,X    \ Steer the car a little to the left

BCC mcar20             \ Jump to mcar20 (this BCC is effectively a JMP as we
\ just passed through a BCS)

.mcar16

CMP #30                \ If the car's racing line < 30, jump to mcar20 to move
BCC mcar20             \ on to the next driver

.mcar17

\ If we get here, then we need to apply the steering
\ given in carSteering
\
\ carSteering is a sign-magnitude number, where bit 7 is
\ the sign and bits 0-5 contain the magnitude, so before
\ we can apply the steering, we need to convert it into
\ a signed number

LDA carSteering,X      \ Set A to the car's carSteering

AND #%10111111         \ Clear bit 6

CLC                    \ Clear the C flag in preparation for the addition below

BPL mcar18             \ If bit 7 of A is clear, then the amount of steering is
\ mcar18 to add it to the racing line

\ If we get here then the sign-magnitude number in A is
\ negative, so we need to convert this into a signed
\ number
\
\ We do this by first setting bit 6 (which we just
\ cleared above) so bits 6 and 7 are both set, and we
\ then need to flip bits 0-5, to convert the positive
\ magnitude into its negative equivalent
\
\ We can do this in one EOR instruction, as follows

EOR #%01111111         \ Set bit 6 of A and flip bits 0-5, so A is now a
\ negative number that we can add to the racing line in
\ order to subtract the correct amount of steering

ADC carRacingLine,X    \ Steer the car right by the amount in A

BCS mcar19             \ If the subtraction didn't underflow then we are still
\ on the track, so jump to mcar19 to update the racing
\ line with the new figure

BCC mcar20             \ Otherwise the subtraction just underflowed, which
\ means we just steered the car off the track, so jump
\ to mcar20 so we don't update the car's racing line
\ (this BCC is effectively a JMP as we just passed
\ through a BCS)

.mcar18

ADC carRacingLine,X    \ Steer the car left by the amount in A

BCS mcar20             \ If the addition just overflowed then this would steer
\ the car off the track, so jump to mcar20 so we don't
\ update the car's racing line (so we don't actually do
\ the steer)

.mcar19

STA carRacingLine,X    \ Update the car's racing line with the updated figure,
\ to steer the car across the track

.mcar20

DEX                    \ Decrement the loop counter to point to the next driver

BMI mcar21             \ If we have worked our way through all 20 drivers, jump
\ to mcar21 to return from the subroutine

CPX currentPlayer      \ If driver X is the current player, jump up to mcar20
BEQ mcar20             \ to move on to the next driver

JMP mcar1              \ Jump up to mcar1 to process the next driver

.mcar21

RTS                    \ Return from the subroutine
```