Skip to navigation

Elite on the BBC Micro and NES

Dashboard: DILX

[NES version, Bank 6]

Name: DILX [Show more] Type: Subroutine Category: Dashboard Summary: Update a bar-based indicator on the dashboard
Context: See this subroutine in context in the source code References: This subroutine is called as follows: * DIALS calls DILX * DIALS calls via DILX+2

The range of values shown on the indicator depends on which entry point is called. For the default entry point of DILX, the range is 0-255 (as the value passed in A is one byte). The other entry points are shown below. This routine does a similar job to the routine of the same name in the BBC Master version of Elite, but the code is significantly different.
Arguments: A The value to be shown on the indicator (so the larger the value, the longer the bar) SC(1 0) The address of the tile at the left end of the indicator in nametable buffer 0 K The lower end of the safe range, so safe values are in the range K <= A < K+1 (and other values are dangerous) K+1 The upper end of the safe range, so safe values are in the range K <= A < K+1 (and other values are dangerous)
Returns: SC(1 0) The address of the tile at the left end of the next indicator down
Other entry points: DILX+2 The range of the indicator is 0-64 (for the fuel and speed indicators)
.DILX LSR A ; If we call DILX, we set A = A / 16, so A is 0-31 LSR A LSR A ; If we call DILX+2, we set A = A / 4, so A is 0-31 CMP #31 ; If A < 31 then jump to dilx1 to skip the following BCC dilx1 ; instruction LDA #30 ; Set A = 30, so the maximum value of the value to show ; on the indicator in A is 30 .dilx1 LDY #0 ; We are going to draw the indicator as a row of tiles, ; so set an index in Y to count the tiles as we work ; from left to right CMP K ; If A < K then this value is lower than the lower end BCC dilx8 ; of the safe range, so jump to dilx8 to flash the ; indicator bar between colour 4 and colour 2, to ; indicate a dangerous value CMP K+1 ; If A >= K+1 then this value is higher than the upper BCS dilx8 ; end of the safe range, so jump to dilx8 to draw the ; indicator bar between colour 4 and colour 2, to ; indicate a dangerous value STA Q ; Store the value we want to draw on the indicator in Q .dilx2 LSR A ; Set A = A / 8 LSR A ; LSR A ; Each indicator consists of four tiles that we use to ; show a value from 0 to 30, so this gives us the number ; of sections we need to fill with a full bar (in the ; range 0 to 3, as A is in the range 0 to 30) BEQ dilx4 ; If the result is 0 then the value is too low to need ; any full bars, so jump to dilx4 to draw the end cap of ; the indicator bar and any blank space to the right TAX ; Set X to the number of sections that we need to fill ; with a full bar, so we can use it as a loop counter to ; draw the correct number of full bars LDA #236 ; Set A = 236, which is the pattern number of the fully ; filled bar in colour 4 (for a safe value) .dilx3 STA (SC),Y ; Set the Y-th tile of the indicator to A to show a full ; bar INY ; Increment the tile number in Y to move to the next ; tile in the indicator DEX ; Decrement the loop counter in X BNE dilx3 ; Loop back until we have drawn the correct number of ; full bars .dilx4 ; We now draw the correct end cap on the right end of ; the indicator bar LDA Q ; Set A to the value we want to draw on the indicator, ; which we stored in Q above AND #7 ; Set A = A mod 8, which gives us the remaining value ; once we've taken off any fully filled tiles (as each ; of the four tiles that make up the indicator ; represents a value of 8) CLC ; Set A = A + 237 ADC #237 ; ; The eight patterns from 237 to 244 contain the end cap ; patterns in colour 4 (for a safe value), ranging ; from the smallest cap to the largest, so this sets A ; to the correct pattern number to use as the end cap ; for displaying the remainder in A STA (SC),Y ; Set the Y-th tile of the indicator to A to show the ; end cap INY ; Increment the tile number in Y to move to the next ; tile in the indicator ; We now fill the rest of the four tiles with a blank ; indicator tile, if required LDA #85 ; Set A = 85, which is the pattern number of an empty ; tile in an indicator .dilx5 CPY #4 ; If Y = 4 then we have just drawn the last tile in BEQ dilx6 ; the indicator, so jump to dilx6 to finish off, as we ; have now drawn the entire indicator STA (SC),Y ; Otherwise set the Y-th tile of the indicator to A to ; fill the space to the right of the indicator bar with ; the blank indicator pattern INY ; Increment the tile number in Y to move to the next ; tile in the indicator BNE dilx5 ; Loop back to dilx5 to draw the next tile (this BNE is ; effectively a JMP as Y won't ever wrap around to 0) .dilx6 LDA SC ; Set SC(1 0) = SC(1 0) + 32 CLC ; ADC #32 ; Starting with the low bytes STA SC BCC dilx7 ; And then the high bytes INC SC+1 ; ; This points SC(1 0) to the nametable entry for the ; next indicator on the row below, as there are 32 tiles ; in each row .dilx7 SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 RTS ; Return from the subroutine .dilx8 STA Q ; Store the value we want to draw on the indicator in Q LDA MCNT ; Fetch the main loop counter and jump to dilx10 if bit AND #%00001000 ; 3 is set, which will be true half of the time, with BNE dilx10 ; the bit being 0 for eight iterations around the main ; loop, and 1 for the next eight iterations ; ; If we jump to dilx10 then the indicator is shown in ; red, and if we don't jump it is shown in the normal ; colour, so this flashes the indicator bar between red ; and the normal colour, changing the colour every eight ; iterations of the main loop LDA Q ; Set A to the value we want to draw on the indicator, ; which we stored in Q above JMP dilx2 ; Jump back to dilx2 to draw the indicator in the normal ; colour scheme LDY #0 ; These instructions are never run and have no effect BEQ dilx13 .dilx10 ; If we get here then we show the indicator in red LDA Q ; Set A to the value we want to draw on the indicator, ; which we stored in Q above LSR A ; Set A = A / 8 LSR A ; LSR A ; Each indicator consists of four tiles that we use to ; show a value from 0 to 30, so this gives us the number ; of sections we need to fill with a full bar (in the ; range 0 to 3, as A is in the range 0 to 30) BEQ dilx12 ; If the result is 0 then the value is too low to need ; any full bars, so jump to dilx12 to draw the end cap ; of the indicator bar and any blank space to the right TAX ; Set X to the number of sections that we need to fill ; with a full bar, so we can use it as a loop counter to ; draw the correct number of full bars LDA #227 ; Set A = 237, which is the pattern number of the fully ; filled bar in colour 2 (for a dangerous value) .dilx11 STA (SC),Y ; Set the Y-th tile of the indicator to A to show a full ; bar INY ; Increment the tile number in Y to move to the next ; tile in the indicator DEX ; Decrement the loop counter in X BNE dilx11 ; Loop back until we have drawn the correct number of ; full bars .dilx12 ; We now draw the correct end cap on the right end of ; the indicator bar LDA Q ; Set A to the value we want to draw on the indicator, ; which we stored in Q above AND #7 ; Set A = A mod 8, which gives us the remaining value ; once we've taken off any fully filled tiles (as each ; of the four tiles that make up the indicator ; represents a value of 8) CLC ; Set A = A + 228 ADC #228 ; ; The eight patterns from 228 to 235 contain the end cap ; patterns in colour 2 (for a dangerous value), ranging ; from the smallest cap to the largest, so this sets A ; to the correct pattern number to use as the end cap ; for displaying the remainder in A STA (SC),Y ; Set the Y-th tile of the indicator to A to show the ; end cap INY ; Increment the tile number in Y to move to the next ; tile in the indicator .dilx13 ; We now fill the rest of the four tiles with a blank ; indicator tile, if required LDA #85 ; Set A = 85, which is the pattern number of an empty ; tile in an indicator .dilx14 CPY #4 ; If Y = 4 then we have just drawn the last tile in BEQ dilx15 ; the indicator, so jump to dilx6 to finish off, as we ; have now drawn the entire indicator STA (SC),Y ; Otherwise set the Y-th tile of the indicator to A to ; fill the space to the right of the indicator bar with ; the blank indicator pattern INY ; Increment the tile number in Y to move to the next ; tile in the indicator BNE dilx14 ; Loop back to dilx14 to draw the next tile (this BNE is ; effectively a JMP as Y won't ever wrap around to 0) .dilx15 LDA SC ; Set SC(1 0) = SC(1 0) + 32 CLC ; ADC #32 ; Starting with the low bytes STA SC BCC dilx16 ; And then the high bytes INC SC+1 ; ; This points SC(1 0) to the nametable entry for the ; next indicator on the row below, as there are 32 tiles ; in each row .dilx16 SETUP_PPU_FOR_ICON_BAR ; If the PPU has started drawing the icon bar, configure ; the PPU to use nametable 0 and pattern table 0 RTS ; Return from the subroutine