Skip to navigation

Revs on the BBC Micro

Keyboard: ProcessDrivingKeys (Part 2 of 6)

Name: ProcessDrivingKeys (Part 2 of 6) [Show more] Type: Subroutine Category: Keyboard Summary: Process keyboard steering Deep dive: Computer assisted steering (CAS)
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * AssistSteering calls via keys7 * AssistSteering calls via keys10 * AssistSteering calls via keys11 * ProcessDrivingKeys (Part 1 of 6) calls via keys11

Other entry points: keys7 Re-entry point for the AssistSteering routine when no joystick steering is being applied keys10 Re-entry point for the AssistSteering routine when CAS is being applied to the steering keys11 Re-entry point for the AssistSteering routine if CAS is not enabled or the car is facing backwards
.keys2 LDX #&A9 \ Scan the keyboard to see if "L" is being pressed JSR ScanKeyboard BNE keys3 \ If "L" is not being pressed, jump to keys3 LDA #2 \ Set V = 2 STA V .keys3 LDX #&A8 \ Scan the keyboard to see if ";" is being pressed JSR ScanKeyboard BNE keys4 \ If ";" is not being pressed, jump to keys4 INC V \ Set V = 1 .keys4 \ By this point, we have: \ \ * V = 1 if ";" is being pressed (steer right) \ \ * V = 2 if "L" is being pressed (steer left) \ \ * V = 0 if neither is being pressed \ \ We now calculate the amount of steering change into \ (A T), so we can apply it to (steeringHi steeringLo), \ which is a sign-magnitude number with the sign bit in \ bit 0 \ \ In the following, we swap the steering change between \ (A T) and (U T) quite a bit, and in the Superior \ Software variant of the game, we also apply computer \ assisted steering (CAS) LDA #3 \ Set U = 3 STA U \ \ So (U T) = (3 0) = 768, which is the value we use for \ steering when the SPACE key is held down IF _ACORNSOFT OR _4TRACKS LDX #&9D \ Scan the keyboard to see if SPACE is being pressed JSR ScanKeyboard ELIF _SUPERIOR OR _REVSPLUS PLP \ Retrieve the result of the keyboard scan above, when \ we scanned for SPACE ENDIF BEQ keys6 \ If SPACE is being pressed, jump to keys6 with \ (U T) = 768 \ SPACE is not being pressed, so we need to calculate \ the correct value of (U T) depending on the steering \ wheel position LDA #0 \ Set A = 0 LDX #2 \ If steeringHi > 2, jump to keys5 to skip the following CPX steeringHi \ instruction BCC keys5 LDA #1 \ Set A = 1 .keys5 STA U \ Set U = A, which will be 1 if steeringHi > 2, or \ 0 otherwise LDA #128 \ Set T = 128 STA T .keys6 \ By this point, (U T) is: \ \ * (3 0) = 768 if the SPACE key is being held down \ \ * (1 128) = 384 if steeringHi > 2 \ \ * (0 128) = 128 if steeringHi <= 2 LDA V \ If V = 0 then no steering is being applied, so jump to BEQ keys7 \ keys7 CMP #3 \ If V = 3, jump to keys13 to move on to the throttle BEQ keys13 \ and brake keys without applying any steering \ If we get here then V = 1 or 2, so steering is being \ applied, so we set the sign of (U T) to match the \ position of the wheel, before jumping down to keys8 \ or keys9 EOR steeringLo \ If bit 0 of steeringLo is clear, jump to keys9 AND #1 BEQ keys9 JSR Negate16Bit+2 \ Otherwise (steeringHi steeringLo) is negative, so \ set (A T) = -(U T) JMP keys8 \ Jump to keys8 to store the negated value in (U T) .keys7 \ If we get here then no steering is being applied LDA xTyreForceNoseLo \ Set T = xTyreForceNoseLo AND %11110000 AND #%11110000 STA T LDA xTyreForceNoseHi \ Set (A T) = (xTyreForceNoseHi xTyreForceNoseLo) \ AND %11110000 \ = xTyreForceNose AND %11110000 JSR Absolute16Bit \ Set (A T) = |A T| LSR A \ Set (A T) = (A T) >> 2 ROR T \ = |A T| / 4 LSR A \ = (|xTyreForceNose| AND %11110000) / 4 ROR T IF _ACORNSOFT OR _4TRACKS CMP #12 \ If A < 12, skip the following instruction BCC keys8 LDA #12 \ Set A = 12, so A has a maximum value of 12, and |A T| \ is set to a maximum value of 12 * 256 ELIF _SUPERIOR OR _REVSPLUS CMP steeringHi \ If A < steeringHi, clear the C flag, so the following \ call to SetSteeringLimit does nothing JSR SetSteeringLimit \ If A >= steeringHi, set: \ \ (A T) = |steeringHi steeringLo| \ \ so this is the maximum value of |A T| ENDIF .keys8 STA U \ Set (U T) = (A T) .keys9 IF _ACORNSOFT OR _4TRACKS LDA steeringLo \ Set A = steeringLo ELIF _SUPERIOR OR _REVSPLUS JMP AssistSteeringKeys \ Jump to AssistSteeringKeys, which in turn jumps back \ to keys10, so this is effectively a JSR call \ \ The routine returns with A = steeringLo ENDIF .keys10 SEC \ Set (A T) = (steeringHi steeringLo) - (U T) SBC T \ STA T \ starting with the low bytes LDA steeringHi \ And then the high bytes SBC U CMP #200 \ If the high byte in A < 200, skip the following BCC keys11 \ instructions \ Otherwise the high byte in A >= 200, so we negate \ (A T) JSR Negate16Bit \ Set (A T) = -(A T) STA U \ Set (U T) = (A T) LDA T \ Flip the sign bit in bit 0 of T EOR #1 STA T LDA U \ Set (A T) = (U T) .keys11 CMP #145 \ If the high byte in A < 145, skip the following BCC keys12 \ instruction LDA #145 \ Set A = 145, so A has a maximum value of 145 .keys12 STA steeringHi \ Set (steeringHi steeringLo) = (A T) LDA T STA steeringLo