Skip to navigation

Elite on the BBC Micro and NES

Version analysis of BLINE

This code appears in the following versions (click to see it in the source code):

Code variations between these versions are shown below.

Name: BLINE Type: Subroutine Category: Drawing circles Summary: Draw a circle segment and add it to the ball line heap Deep dive: The ball line heap Drawing circles

Code variation 1 of 6A variation in the comments only

Tap on a block to expand it, and tap it again to revert.

Draw a single segment of a circle, adding the point to the ball line heap.
Draw a single segment of a circle by adding the point to the ball line heap, so it can be sent to the I/O processor for drawing once the whole circle has been added to the heap.

Arguments: CNT The number of this segment STP The step size for the circle K6(1 0) The x-coordinate of the new point on the circle, as a screen coordinate (T X) The y-coordinate of the new point on the circle, as an offset from the centre of the circle FLAG Set to &FF for the first call, so it sets up the first point in the heap but waits until the second call before drawing anything (as we need two points, i.e. two calls, before we can draw a line) K The circle's radius K3(1 0) Pixel x-coordinate of the centre of the circle K4(1 0) Pixel y-coordinate of the centre of the circle K5(1 0) Screen x-coordinate of the previous point added to the ball line heap (if this is not the first point) K5(3 2) Screen y-coordinate of the previous point added to the ball line heap (if this is not the first point) SWAP If non-zero, we swap (X1, Y1) and (X2, Y2)
Returns: CNT CNT is updated to CNT + STP A The new value of CNT K5(1 0) Screen x-coordinate of the point that we just added to the ball line heap K5(3 2) Screen y-coordinate of the point that we just added to the ball line heap FLAG Set to 0
.BLINE TXA \ Set K6(3 2) = (T X) + K4(1 0) ADC K4 \ = y-coord of centre + y-coord of new point STA K6+2 \ LDA K4+1 \ so K6(3 2) now contains the y-coordinate of the new ADC T \ point on the circle but as a screen coordinate, to go STA K6+3 \ along with the screen y-coordinate in K6(1 0) LDA FLAG \ If FLAG = 0, jump down to BL1 BEQ BL1 INC FLAG \ Flag is &FF so this is the first call to BLINE, so \ increment FLAG to set it to 0, as then the next time \ we call BLINE it can draw the first line, from this \ point to the next

Code variation 2 of 6Related to Elite's use of the Tube

Tap on a block to expand it, and tap it again to revert.

.BL5 \ The following inserts a &FF marker into the LSY2 line \ heap to indicate that the next call to BLINE should \ store both the (X1, Y1) and (X2, Y2) points. We do \ this on the very first call to BLINE (when FLAG is \ &FF), and on subsequent calls if the segment does not \ fit on-screen, in which case we don't draw or store \ that segment, and we start a new segment with the next \ call to BLINE that does fit on-screen LDY LSP \ If byte LSP-1 of LSY2 = &FF, jump to BL7 to tidy up LDA #&FF \ and return from the subroutine, as the point that has CMP LSY2-1,Y \ been passed to BLINE is the start of a segment, so all BEQ BL7 \ we need to do is save the coordinate in K5, without \ moving the pointer in LSP STA LSY2,Y \ Otherwise we just tried to plot a segment but it \ didn't fit on-screen, so put the &FF marker into the \ heap for this point, so the next call to BLINE starts \ a new segment INC LSP \ Increment LSP to point to the next point in the heap BNE BL7 \ Jump to BL7 to tidy up and return from the subroutine \ (this BNE is effectively a JMP, as LSP will never be \ zero)
BEQ BL5 \ This is the first call to BLINE, so we don't need to \ copy the previous point to XX15 as there isn't one, \ so we jump to BL5 to tidy up and return from the \ subroutine (this BEQ is effectively a JMP, as we just \ incremented FLAG to 0)
.BL1

 LDA K5                 \ Set XX15 = K5 = x_lo of previous point
 STA XX15

 LDA K5+1               \ Set XX15+1 = K5+1 = x_hi of previous point
 STA XX15+1

 LDA K5+2               \ Set XX15+2 = K5+2 = y_lo of previous point
 STA XX15+2

 LDA K5+3               \ Set XX15+3 = K5+3 = y_hi of previous point
 STA XX15+3

 LDA K6                 \ Set XX15+4 = x_lo of new point
 STA XX15+4

 LDA K6+1               \ Set XX15+5 = x_hi of new point
 STA XX15+5

 LDA K6+2               \ Set XX12 = y_lo of new point
 STA XX12

 LDA K6+3               \ Set XX12+1 = y_hi of new point
 STA XX12+1

 JSR LL145              \ Call LL145 to see if the new line segment needs to be
                        \ clipped to fit on-screen, returning the clipped line's
                        \ end-points in (X1, Y1) and (X2, Y2)

 BCS BL5                \ If the C flag is set then the line is not visible on
                        \ screen anyway, so jump to BL5, to avoid drawing and
                        \ storing this line

Code variation 3 of 6Related to Elite's use of the Tube

This variation is blank in the 6502 Second Processor version.

LDA SWAP \ If SWAP = 0, then we didn't have to swap the line BEQ BL9 \ coordinates around during the clipping process, so \ jump to BL9 to skip the following swap LDA X1 \ Otherwise the coordinates were swapped by the call to LDY X2 \ LL145 above, so we swap (X1, Y1) and (X2, Y2) back STA X2 \ again STY X1 LDA Y1 LDY Y2 STA Y2 STY Y1 .BL9
 LDY LSP                \ Set Y = LSP

Code variation 4 of 6Related to Elite's use of the Tube

This variation is blank in the 6502 Second Processor version.

LDA LSY2-1,Y \ If byte LSP-1 of LSY2 is not &FF, jump down to BL8 CMP #&FF \ to skip the following (X1, Y1) code BNE BL8 \ Byte LSP-1 of LSY2 is &FF, which indicates that we \ need to store (X1, Y1) in the heap
 LDA X1                 \ Store X1 in the LSP-th byte of LSX2
 STA LSX2,Y

 LDA Y1                 \ Store Y1 in the LSP-th byte of LSY2
 STA LSY2,Y

 INY                    \ Increment Y to point to the next byte in LSX2/LSY2

Code variation 5 of 6A variation in the labels only

This variation is blank in the 6502 Second Processor version.

.BL8
 LDA X2                 \ Store X2 in the LSP-th byte of LSX2
 STA LSX2,Y

 LDA Y2                 \ Store Y2 in the LSP-th byte of LSX2
 STA LSY2,Y

 INY                    \ Increment Y to point to the next byte in LSX2/LSY2

 STY LSP                \ Update LSP to point to the same as Y

Code variation 6 of 6Related to Elite's use of the Tube

Tap on a block to expand it, and tap it again to revert.

JSR LOIN \ Draw a line from (X1, Y1) to (X2, Y2) LDA XX13 \ If XX13 is non-zero, jump up to BL5 to add a &FF BNE BL5 \ marker to the end of the line heap. XX13 is non-zero \ after the call to the clipping routine LL145 above if \ the end of the line was clipped, meaning the next line \ sent to BLINE can't join onto the end but has to start \ a new segment, and that's what inserting the &FF \ marker does .BL7
.BL5
 LDA K6                 \ Copy the data for this step point from K6(3 2 1 0)
 STA K5                 \ into K5(3 2 1 0), for use in the next call to BLINE:
 LDA K6+1               \
 STA K5+1               \   * K5(1 0) = screen x-coordinate of this point
 LDA K6+2               \
 STA K5+2               \   * K5(3 2) = screen y-coordinate of this point
 LDA K6+3               \
 STA K5+3               \ They now become the "previous point" in the next call

 LDA CNT                \ Set CNT = CNT + STP
 CLC
 ADC STP
 STA CNT

 RTS                    \ Return from the subroutine