Skip to navigation

Revs on the BBC Micro

Dashboard: DrawCarInMirror

Name: DrawCarInMirror [Show more] Type: Subroutine Category: Dashboard Summary: Draw a car in a specified segment of one of the wing mirrors, or clear a specified segment Deep dive: Wing mirrors
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * UpdateMirrors calls DrawCarInMirror

Arguments: Y Mirror segment (0 to 5) * 0 = left mirror, outer segment * 1 = left mirror, middle segment * 2 = left mirror, inner segment * 3 = right mirror, inner segment * 4 = right mirror, middle segment * 5 = right mirror, outer segment N Start offset within the segment for the car lines A End offset within the segment for the car lines (or 0 to clear the mirror segment)
Returns: Y Y is unchanged
.DrawCarInMirror STA RR \ Store A in RR STY G \ Store Y in G so we can retrieve it before returning \ from the subroutine LDA mirrorAddressHi,Y \ Set (Q P) to the base screen address of this mirror STA Q \ segment (to which we add the following offsets to get LDA mirrorAddressLo,Y \ the screen address for this particular segment) STA P LDA startMirror,Y \ Set W to the offset of the first pixel byte in this STA W \ mirror segment LDA endMirror,Y \ Set Y to the offset of the first pixel byte in this TAY \ mirror segment .mirr1 \ We now work our way through the mirror segment pixel \ bytes, going backwards from the end byte to the start \ byte, either removing the car or drawing the car with \ added random blurriness LDA #%11110000 \ Set A to the pixel byte containing four pixels of \ colour 2 (white) CPY RR \ If Y >= RR, jump to mirr2 to draw a white pixel byte BCS mirr2 CPY N \ If Y < N, jump to mirr2 to draw a white pixel byte BCC mirr2 \ If we get here then N <= Y < RR, so we draw a pixel \ byte of black pixels to represent the car, with the \ pixels randomised but tending to black when the \ engine is on (if the engine is off, then all the \ pixels are black, so this part simulates the mirror \ shuddering when the engine is on) LDX 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 AND &2000,X \ There is game code at location &2000, so this randomly \ switches some of the white pixels (colour 2) to black \ (colour 0) in the pixel byte in A AND engineStatus \ If our engine is off, then engineStatus is zero and \ all the pixels are set to black, but if the engine is \ on, engineStatus is &FF so this instruction has no \ effect, leaving the image randomised .mirr2 STA (P),Y \ Draw the pixel byte in A at screen address (Q P) + Y DEY \ Decrement Y to point to the pixel byte above BPL mirr3 \ If bit 7 of Y is clear, jump to mirr3 to move on to \ the next pixel byte TYA \ If Y mod 8 < 7 then jump to mirr3 to move on to the AND #7 \ next pixel byte CMP #7 BCC mirr3 \ If we get here then Y has bit 7 set and Y mod 8 = 7, \ so we have gone past the top of the current character \ row and need to move up to the last pixel row in the \ character block above row instead \ \ There are &140 bytes per row, and we want to move from \ the top of the character block on this row to the \ bottom of the character block on the row above, so we \ subtract &140 to go up to the top of the character \ block on the row above, and then add 8 to jump down to \ the bottom row, i.e. we subtract &140 - 8 = &138 LDA P \ Set (Q P) = (Q P) - &138 SEC \ SBC #&38 \ starting with the low bytes STA P LDA Q \ And then the high bytes, so (Q P) points to the end of SBC #&01 \ the character block on the previous character row STA Q \ (i.e. the next pixel row up) .mirr3 CPY W \ Loop back to draw the next pixel byte, until Y < W BCS mirr1 LDY G \ Retrieve the value of Y that we stored in G, so that \ Y is preserved through the call to the routine RTS \ Return from the subroutine EQUB &FF \ This byte appears to be unused