.MakeDrivingSounds LDA tyreSqueal \ If bit 7 of tyreSqueal is clear for both tyres, jump ORA tyreSqueal+1 \ to soun1 to skip the following as no tyres are BPL soun1 \ squealing \ Otherwise we add some random pitch variation to the \ crash/contact sound and make the sound of the tyres \ squealing LDA VIA+&68 \ Read 6522 User VIA T1C-L timer 2 low-order counter \ (SHEILA &68), which decrements one million times a \ second and will therefore be pretty random CMP #63 \ If A < 63 (25% chance), jump to soun1 to skip the BCS soun1 \ following AND #3 \ Reduce A to a random number in the range 0 to 3 CLC \ Add 130 to A, so A is a random number in the range ADC #130 \ 130 to 133 STA soundData+28 \ Update byte #5 of sound #4 (low byte of pitch) so the \ pitch of the crash/contact sound wavers randomly LDA #3 \ Make sound #3 (tyre squeal) using envelope 1 LDY #1 JSR MakeSound .soun1 \ We now increment or decrement soundRevCount so it \ steps towards the value of soundRevTarget, which moves \ the pitch of the engine towards the current rev count LDX soundRevCount \ Set X = soundRevCount CPX soundRevTarget \ If X = soundRevTarget, jump to soun8 to return from BEQ soun8 \ the subroutine BCC soun2 \ If X < soundRevTarget, jump to soun2 to increment X DEX \ Decrement X and skip the next instruction (this BCS BCS soun3 \ is effectively a JMP as we passed through the BCC) .soun2 INX \ Increment X .soun3 STX soundRevCount \ Store X in soundRevCount, so soundRevCount moves one \ step closer to soundRevTarget \ We now do the following, depending on the updated \ value of soundRevCount in X: \ \ * If soundRevCount < 28, flush all the sound buffers \ (i.e. stop making any sounds) \ \ * If 28 <= soundRevCount < 92, make the engine \ exhaust sound, set the pitch of engine tone 1 to \ soundRevCount + 95 and the volume of engine tone 1 \ to 0, and make the sound of engine tone 1 \ \ * If soundRevCount >= 92, silence the exhaust, set \ the pitch of engine tone 1 to soundRevCount - 92, \ and make the sound of engine tone 1 CPX #28 \ If X < 28, then jump to soun9 to flush all the sound BCC soun9 \ buffers, as the rev count is too low for the engine to \ make a sound TXA \ Set A = X - 92 SEC SBC #92 BCS soun4 \ If the subtraction didn't underflow, i.e. X >= 92, \ then jump to soun4 to silence the engine exhaust and \ set the pitch of engine tone 1 to X - 92 PHA \ Store A on the stack to we can retrieve it after the \ following call LDA #0 \ Make sound #0 (engine exhaust) at the current volume JSR MakeSound-3 \ level PLA \ Retrieve the value of A that we stored on the stack, \ so A = X - 92 CLC \ Set A = A + 187 ADC #187 \ = X - 92 + 187 \ = X + 95 \ \ so we set the pitch of engine tone 1 to X + 95 LDY #0 \ Set Y = 0, so we set the volume of engine tone 1 to \ zero (silent) BEQ soun5 \ Jump to soun5 (this BEQ is effectively a JMP as Y is \ always zero) .soun4 LDX #0 \ Flush the buffer for sound channel 0, which will stop JSR FlushSoundBuffer \ the sound of the engine exhaust LDY volumeLevel \ Set Y to the current volume level .soun5 STA soundData+12 \ Update byte #5 of sound #1 (low byte of pitch), to set \ the pitch of engine tone 1 to A LDA #1 \ Make sound #1 (engine tone 1) with volume Y JSR MakeSound \ We now do the following, depending on the updated \ value of soundRevCount: \ \ * If the volume level is currently zero, make the \ sound of engine tone 2 sound with volume 0 \ \ * If soundRevCount >= 64, set the pitch of engine \ tone 2 to soundRevCount - 64, and make the sound \ of engine tone 2 \ \ * If soundRevCount < 64, make the sound of engine \ tone 2 with volume 0 LDY volumeLevel \ If the volume level is currently zero (no sound), jump BEQ soun7 \ to soun7 to make the engine tone 2 sound with volume 0 LDA soundRevCount \ Set A = soundRevCount - 64 SEC SBC #64 BCS soun6 \ If the subtraction didn't underflow, i.e. A >= 64, \ then jump to soun6 to set the pitch of engine tone 2 \ to soundRevCount - 64 LDY #0 \ Set Y = 0, so we set the volume of engine tone 2 to \ zero (silent) BEQ soun7 \ Jump to soun7 (this BEQ is effectively a JMP as Y is \ always zero) .soun6 STA soundData+20 \ Update byte #5 of sound #2 (low byte of pitch), to set \ the pitch of engine tone 2 to A .soun7 LDA #2 \ Make sound #2 (engine tone 2) with volume Y JSR MakeSound .soun8 RTS \ Return from the subroutine .soun9 JSR FlushSoundBuffers \ Flush all four sound channel buffers RTS \ Return from the subroutineName: MakeDrivingSounds [Show more] Type: Subroutine Category: Sound Summary: Make the relevant sounds for the engine and tyres Deep dive: The engine soundsContext: See this subroutine in context in the source code References: This subroutine is called as follows: * MainDrivingLoop (Part 2 of 5) calls MakeDrivingSounds * MainDrivingLoop (Part 5 of 5) calls MakeDrivingSounds
[X]
Subroutine FlushSoundBuffer (category: Sound)
Flush the specified sound buffer
[X]
Subroutine FlushSoundBuffers (category: Sound)
Flush all four specified sound buffers
[X]
Subroutine MakeSound (category: Sound)
Make a sound
[X]
Entry point MakeSound-3 in subroutine MakeSound (category: Sound)
Make the sound at the current volume level
[X]
Configuration variable VIA = &FE00
Memory-mapped space for accessing internal hardware, such as the video ULA, 6845 CRTC and 6522 VIAs (also known as SHEILA)
[X]
Label soun1 is local to this routine
[X]
Label soun2 is local to this routine
[X]
Label soun3 is local to this routine
[X]
Label soun4 is local to this routine
[X]
Label soun5 is local to this routine
[X]
Label soun6 is local to this routine
[X]
Label soun7 is local to this routine
[X]
Label soun8 is local to this routine
[X]
Label soun9 is local to this routine
[X]
Variable soundData (category: Sound)
OSWORD blocks for making the various game sounds
[X]
Variable soundRevCount in workspace Zero page
The current pitch for the revs sound
[X]
Variable soundRevTarget in workspace Zero page
The target pitch for the revs sound
[X]
Variable tyreSqueal (category: Driving model)
A flag to determine whether the front or rear tyres are squealing
[X]
Variable volumeLevel in workspace Main variable workspace
The game's volume level