Skip to navigation

Revs on the BBC Micro

Driving model: ApplySkidForces

Name: ApplySkidForces [Show more] Type: Subroutine Category: Driving model Summary: Calculate the tyre forces when the car is skidding Deep dive: Skidding
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * ApplyTyresAndSkids calls ApplySkidForces

Calculate the following: * Set xTyreForceNose or xTyreForceRear = max(wingForce95 << 8, scaled |xVelocity|) * abs(-xVelocity) * Call GetTyreForces to set (A T), H and (NN MM) * If the throttle is being applied and we are processing the front tyres, return from the subroutine * If A < wingForce95, then: * If the throttle is being applied, then zTyreForceNose or zTyreForceRear = (A T) * abs(H) otherwise set: zTyreForceNose or zTyreForceRear = max((A T), (NN MM)) * abs(H) * If A >= wingForce95, then: * Set (A T) = wingForce95 << 8 * If the throttle is being applied, then zTyreForceNose or zTyreForceRear = (A T) * abs(H) otherwise set: zTyreForceNose or zTyreForceRear = max((A T), (NN MM)) * abs(H) * If the throttle is being applied and we are processing the rear tyres, set: xTyreForceNose or xTyreForceRear = 0
Arguments: X The set of tyres to process: * 0 = front tyres * 1 = rear tyres
.ApplySkidForces LDA #0 \ Set zTyreForceNose for tyre X to 0 STA zTyreForceNoseHi,X STA zTyreForceNoseLo,X LDY #8 \ Set Y = 8 so the call to Scale16Bit scales xVelocity JSR Scale16Bit \ Scale up |xVelocity| by 2^5, capping the result at the \ maximum possible positive value of &7Fxx, and \ returning the result in (NN MM) LDA xVelocityHi \ Set H = xVelocityHi with the sign flipped, so that EOR #%10000000 \ abs(H) = abs(-xVelocity) STA H LDA #0 \ Set T = 0 STA T LDA wingForce95,X \ Set A to wingForce95 for tyre X STX G \ Set G to the tyre number in X so the ApplyLimitAndSign \ routine sets xTyreForceNose or xTyreForceRear \ accordingly JSR ApplyLimitAndSign \ Set xTyreForceNose or xTyreForceRear \ = max((A T), (NN MM)) * abs(H) \ \ = max(wingForce95 << 8, scaled |xVelocity|) \ * abs(-xVelocity) JSR GetTyreForces \ Calculate the tyre forces due to the throttle or \ brakes: \ \ * (A T) = the force \ \ * H = the sign of the force \ \ * G = X + 2, so the call to ApplyLimitThrottle sets \ zTyreForceNose or zTyreForceRear accordingly \ \ * If the throttle is not being applied, (NN MM) is \ a maximum value for the force \ \ If the throttle is being applied and we are processing \ the front tyres, only G is calculated and the C flag \ is set BCS skid2 \ If the C flag is set then GetTyreForces did not return \ any calculated values, so jump to skid2 to return from \ the subroutine CMP wingForce95,X \ If A < wingForce95 for tyre X, jump to skid1 BCC skid1 LDA #0 \ Set T = 0 STA T LDA wingForce95,X \ Set A to wingForce95 for tyre X, so \ A = min(A, wingForce95) JSR ApplyLimitThrottle \ If the throttle is being applied, then set \ zTyreForceNose or zTyreForceRear to: \ \ (A T) * abs(H) \ \ otherwise set it to: \ \ max((A T), (NN MM)) * abs(H) LDY throttleBrakeState \ If throttleBrakeState <> 1 then the throttle is not DEY \ being applied, so jump to skid2 BNE skid2 CPX #0 \ If X = 0, then we are processing the front tyres, so BEQ skid2 \ jump to skid2 \ If we get here then the throttle is being applied and \ we are processing the rear tyres LDA #0 \ Set xTyreForceNose for tyre X to 0 STA xTyreForceNoseHi,X STA xTyreForceNoseLo,X BEQ skid2 \ Jump to skid2 to return from the subroutine (this BEQ \ is effectively a JMP as A is always zero) .skid1 JSR ApplyLimitThrottle \ If the throttle is being applied, then set \ zTyreForceNose or zTyreForceRear to: \ \ (A T) * abs(H) \ \ otherwise set it to: \ \ max((A T), (NN MM)) * abs(H) .skid2 RTS \ Return from the subroutine