Skip to navigation

Revs on the BBC Micro

Dashboard: ShowStartingLights

Name: ShowStartingLights [Show more] Type: Subroutine Category: Dashboard Summary: Show the lights at the start of the race Deep dive: Starting lights
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * MainDrivingLoop (Part 2 of 5) calls ShowStartingLights

The lights at the start of the race follow this pattern: * The lights are initially off, so they show as three lights with a white border and black interior. * Once we have started our engine, the timer starts and after a pause the lights turn blue. During this time we can't move, but we can rev the engine. * After another pause, the lights turn green and we can start the race. * After another pause, the lights disappear. This is implemented by the counter in raceStarting, which works like this. 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)
.ShowStartingLights LDA raceStarted \ If bit 7 of raceStarted is clear then this is either BPL star9 \ a practice or qualifying lap, so jump to star9 to \ return from the subroutine, as there is no need for \ starting lights LDX raceStarting \ If raceStarting = 0, then the race is not in the BEQ star9 \ process of starting (i.e. it's already started), so \ jump to star9 to return from the subroutine, as there \ is no need for starting lights BPL star2 \ If raceStarting <= 127, jump to star2 to decrement \ the raceStarting counter (this instruction isn't \ necessary as the following comparison covers the same \ test, so this branch could be removed) CPX #128 \ If raceStarting <> 128, jump to star2 to decrement BNE star2 \ the raceStarting counter \ If we get here then raceStarting = 128, which means \ the lights are showing as black, and we are waiting \ for the engine to start to continue the countdown BIT engineStatus \ If bit 7 of engineStatus is clear, then the engine is BPL star1 \ not yet on, so jump to star1 to keep the value of X \ (and therefore the value of raceStarting) at 128, as \ we only move on to the second stage once we have \ started our engine LDX #240 \ If we get here then the engine has started, so set \ X = 240 to store as the updated value of raceStarting, \ which can now start ticking down .star1 \ If we get here then the lights are off LDY #0 \ Set Y to the EOR pattern that doesn't flip any pixels, \ \ See star8 below for an explanation of the EOR pattern LDA #%10000000 \ Set A to a pixel byte containing four pixels with \ colours 2, 0, 0, 0 (white, black, black, black) BNE star6 \ Jump to star6 to store the updated value of X in \ raceStarting and draw the lights (this BNE is \ effectively a JMP as A is never zero) .star2 \ If we get here, then X is non-zero and X <> 128, so \ the engine has started and the light sequence has \ started CPX #160 \ If X = 160, jump to star4 to consider switching from BEQ star4 \ the blue lights to the green lights DEX \ Decrement X BPL star5 \ If X is positive, jump to star5 to display the green \ lights CPX #192 \ If X >= 192, jump to star1 BCS star1 .star3 \ If we get here then the lights are blue (the second \ stage) LDA #%10100101 \ Set A to a pixel byte containing four pixels with \ colours 2, 1, 2, 1 (white, blue, white, blue) LDY #%01110111 \ Set Y to the EOR pattern that flips the above to \ %11010010, i.e. colours 2, 2, 1, 2 (white, white, \ blue, white) \ \ See star8 below for an explanation of the EOR pattern BNE star6 \ Jump to star6 to store the updated value of X in \ raceStarting and draw the lights (this BNE is \ effectively a JMP as A is never zero) .star4 LDA mainLoopCounterLo \ If mainLoopCounterLo mod 64 <> 0, which will be true AND #63 \ for 63 out of 64 iterations round the main loop, jump BNE star3 \ to star3 to display the blue lights \ Otherwise it is time to switch on the green lights LDX #40 \ Set X = 40 .star5 \ If we get here then the lights are green (the third \ and final stage) LDA #%11110010 \ Set A to a pixel byte containing four pixels with \ colours 2, 2, 3, 2 (white, white, green, white) LDY #%00000101 \ Set Y to the EOR pattern that flips the above to \ %11110111, i.e. colours 2, 3, 3, 3 (white, green, \ green, green) \ \ See star8 below for an explanation of the EOR pattern .star6 STX raceStarting \ Store the updated value of X in raceStarting \ We now draw the lights, starting with the white border \ lines, and then the lights themselves using the pixel \ byte in A and the EOR pattern in Y \ \ We only need to draw the left set of lights, as the \ screen buffer will replicate the other two sets to the \ right \ \ The whole light takes up ten pixel rows: two rows for \ the top edge, six rows for the light bulb, and another \ two rows for the bottom edge PHA \ Store the pixel byte in A on the stack, so we can \ retrieve it below when drawing the lights STY T \ Store the EOR pattern in T, so we can retrieve it when \ drawing the lights LDA #%11110000 \ Set A to a pixel byte containing four pixels with \ colours 2, 2, 2, 2 (white, white, white, white), for \ drawing the edges, which we actually draw as a full \ block of white, and then fill in the centre later LDX #9 \ The light contains ten pixel rows, so set a row \ counter in X .star7 STA dashData37+36,X \ Store the X-th row of the light in the screen buffer, \ in dash data block 37 (the screen drawing routine will \ replicate the light in blocks 38 and 39) DEX \ Decrement the pixel row counter BPL star7 \ Loop back until we have drawn all ten rows of the \ light PLA \ Set A to the pixel byte for the lights that we stored \ on the stack above LDX #5 \ The central bulb of the light is six pixel rows, so \ set a row counter in X .star8 STA dashData37+38,X \ Store the X-th row of the light in the screen buffer, \ again in dash data block 37, starting two pixel rows \ after the edge that we drew above EOR T \ Flip the pixels by EOR'ing with T, so the pattern of \ the bulb pixels flips with each row required \ \ This means the green light looks like this: \ \ white, white, green, white ..x. \ white, green, green, green .xxx \ white, white, green, white ..x. \ white, green, green, green .xxx \ white, white, green, white ..x. \ white, green, green, green .xxx \ \ and the blue light looks like this: \ \ white, blue, white, blue .x.x \ white, white, blue, white ..x. \ white, blue, white, blue .x.x \ white, white, blue, white ..x. \ white, blue, white, blue .x.x \ white, white, blue, white ..x. \ \ The EOR pattern for the black lights is 0, so there is \ no flipping and every row is the same: \ \ white, black, black, black .xxx \ white, black, black, black .xxx \ white, black, black, black .xxx \ white, black, black, black .xxx \ white, black, black, black .xxx \ white, black, black, black .xxx DEX \ Decrement the pixel row counter BPL star8 \ Loop back until we have drawn all six rows of the \ bulb .star9 RTS \ Return from the subroutine