Skip to navigation


Dashboard: DrawRevCounter

Name: DrawRevCounter [Show more] Type: Subroutine Category: Dashboard Summary: Draw the hand on the rev counter
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * UpdateDashboard calls DrawRevCounter
.DrawRevCounter LDA #%000 \ Set H = %000 to pass into DrawDashboardLine below STA H LDA revCount \ Set A = revCount, which is the value we want to draw \ on the rev counter, in the range 0 to 170 CMP #30 \ If A >= 30, skip the following instruction BCS revs1 LDA #30 \ Set A = 30, so A is always at least 30, and is now in \ the range 30 to 170 (we do this because the hand on \ the rev counter doesn't fall all the way back to zero) .revs1 STA T \ Set T = A LSR A \ Set A = A / 2 + T CLC \ = A / 2 + A ADC T \ = 1.5 * A \ = 1.5 * revCount \ \ which is in the range 45 to 255 ROR A \ Set A = A / 2 \ = 0.75 * revCount \ \ which is in the range 22 to 127 \ We now convert the value in A to the corresponding \ position on the dial in terms of which quadrant it's \ in, and which half of that quadrant, so we can pass \ the details to the DrawDashboardLine routine SEC \ Set A = A - 76 SBC #76 BCS revs2 \ If the subtraction went past zero, add 152, to get: ADC #152 \ \ A = A + 76 \ So for A in the range 22 to 127, this converts: \ \ A = 22-75 into A = 98-151 \ A = 76-127 into A = 0-51 \ \ If we consider a clock with 0 at 12 o'clock, then 38 \ at 3 o'clock, 76 at 6 o'clock and 114 at 9 o'clock, \ A is now the position of the hand on that clock, i.e. \ the position of the hand that we want to draw on the \ rev counter .revs2 \ We now calculate the quadrant that contains the hand \ on the rev counter, numbered 0 to 3 counting clockwise \ from top-right \ \ We do this by calculating X = A / 38, by repeatedly \ subtracting 38 from A until we go past zero LDX #&FF \ We start by setting X = -1 SEC \ Set the C flag for the subtraction .revs3 INX \ Increment X as we are doing a subtraction SBC #38 \ Set A = A - 38 BCS revs3 \ If the subtraction didn't take us past zero, loop back \ to subtract another 38 ADC #38 \ Otherwise add the 38 back that pushed us over the \ limit, so X now contains the quadrant number, and A \ contains the remainder (i.e. the fraction that the \ hand is past the start of the quadrant) CMP #19 \ If the remainder is < 19, skip the following, as A BCC revs4 \ contains the distance from the start of quadrant X to \ the position of the hand (and the C flag is clear) SBC #19 \ Set A = ~(A - 19) + 20 EOR #&FF \ = ~(A - 19) + 1 + 19 CLC \ = -(A - 19) + 19 ADC #20 \ = 19 - (A - 19) \ \ so A now contains the distance from the hand to the \ end of quadrant X SEC \ Set the C flag to indicate that A is now the distance \ from the hand to the end of the quadrant .revs4 \ By this point: \ \ X = quadrant number (0 to 3) \ \ A = distance from start of quadrant to hand (C = 0) \ distance from hand to end of quadrant (C = 1) \ \ where each quadrant is 38 in size, so A is <= 19 \ \ The C flag therefore represents which half of the \ quadrant the hand is in, 0 denoting the first half and \ 1 denoting the second half TAY \ Set Y = the distance between the hand and quadrant STY T \ Set T = the distance between the hand and quadrant TXA \ Ensure X is in the range 0 to 3 (it should be, but AND #3 \ this makes absolutely sure) TAX TXA \ This sets bits 1 and 2 of V to the quadrant number, ROL A \ and bit 0 to the C flag, so the possible values are: STA V \ \ * 0 = %000 = Quadrant 0, first half, 12:00 to 1:30 \ * 1 = %001 = Quadrant 0, second half, 1:30 to 3:00 \ * 2 = %010 = Quadrant 1, first half, 3:00 to 4:30 \ * 3 = %011 = Quadrant 1, second half, 4:30 to 6:00 \ * 4 = %100 = Quadrant 2, first half, 6:00 to 7:30 \ * 5 = %101 = Quadrant 2, second half, 7:30 to 9:00 \ * 6 = %110 = Quadrant 3, first half, 9:00 to 10:30 \ * 7 = %111 = Quadrant 3, second half, 10:30 to 12:00 \ \ These are the quadrant values we need to pass to the \ DrawDashboardLine routine below AND #%11111100 \ If bit 2 of A is zero, then the hand is in the right BEQ revs5 \ half of the dial, so jump to revs5 to set W = 0 LDA #7 \ Otherwise the hand is in the left half of the dial, \ so set A so we set W = 7 below .revs5 STA W \ Set W = 0 if the hand is in the right half \ 7 if the hand is in the left half \ \ so we start drawing from the leftmost pixel when \ drawing to the right, or the rightmost pixel when \ drawing to the left (which ensures that the hand joins \ the centre spoke of the rev counter without a gap) LDA handPixels,Y \ Set A to the number of pixels that are along the long \ axis of the hand, given the distance between the hand \ and quadrant that we set in Y above STA SS \ Set SS to the number of pixels along the long axis STA U \ Set U to the number of pixels along the long axis, to \ pass through to the DrawDashboardLine routine below LDA startDialLo,X \ Set the low byte of (Q P) to the low byte of the AND #%11111000 \ screen address for the starting point of the hand for STA P \ quadrant Y, which we get from the startDialLo table, \ and clear bits 0 to 2 so the address points to the \ top line of the relevant character block LDA startDialLo,X \ Set Y to the pixel row within the character block AND #%00000111 \ for the starting point, which we get from bits 0 to 2 TAY \ of the starting point's screen address LDA startDialHi,X \ Set the high byte of (Q P) to the high byte of the STA Q \ screen address for the starting point of the hand for \ quadrant Y, so (Q P) now contains the full address of \ the starting point's character block \ Fall through into DrawDashboardLine to draw a line \ from the starting point given in (Q P) and Y, in the \ direction given in V, with U pixels along the longest \ axis, and in the half of the dial given in W