Routines 
Prev: 247D  Up: Map 
This subroutine is called by DRAW to draw an approximation to a straight line from the point X0, Y0 held in COORDS to the point X0+X, Y0+Y, where the increments X and Y are on the top of the calculator stack. The subroutine was originally intended for the ZX80 and ZX81 8K ROM, and it is described in a BASIC program on page 121 of the ZX81 manual.
The method is to intersperse as many horizontal or vertical steps as are needed among a basic set of diagonal steps, using an algorithm that spaces the horizontal or vertical steps as evenly as possible.


DRAW_LINE  24B7  CALL STK_TO_BC  ABS Y to B; ABS X to C; SGN Y to D; SGN X to E.  
24BA  LD A,C  Jump if ABS X is greater than or equal to ABS Y, so that the smaller goes to L, and the larger (later) goes to H.  
24BB  CP B  
24BC  JR NC,DL_X_GE_Y  
24BE  LD L,C  
24BF  PUSH DE  Save diagonal step (+/1,+/1) in DE.  
24C0  XOR A  Insert a vertical step (+/1,0) into DE (D holds SGN Y).  
24C1  LD E,A  
24C2  JR DL_LARGER  Now jump to set H.  
DL_X_GE_Y  24C4  OR C  Return if ABS X and ABS Y are both zero.  
24C5  RET Z  
24C6  LD L,B  The smaller (ABS Y here) goes to L.  
24C7  LD B,C  ABS X to B here, for H.  
24C8  PUSH DE  Save the diagonal step here too.  
24C9  LD D,$00  Horizontal step (0,+/1) to DE here.  
DL_LARGER  24CB  LD H,B  Larger of ABS X, ABS Y to H now.  
The algorithm starts here. The larger of ABS X and ABS Y, say H, is put into A and reduced to INT (H/2). The HL horizontal or vertical steps and L diagonal steps are taken (where L is the smaller of ABS X and ABS Y) in this way: L is added to A; if A now equals or exceeds H, it is reduced by H and a diagonal step is taken; otherwise a horizontal or vertical step is taken. This is repeated H times (B also holds H). Note that meanwhile the exchange registers H' and L' are used to hold COORDS.


24CC  LD A,B  B to A as well as to H.  
24CD  RRA  A starts at INT (H/2).  
D_L_LOOP  24CE  ADD A,L  L is added to A.  
24CF  JR C,D_L_DIAG  If 256 or more, jump  diagonal step.  
24D1  CP H  If A is less than H, jump for horizontal or vertical step.  
24D2  JR C,D_L_HR_VT  
D_L_DIAG  24D4  SUB H  Reduce A by H.  
24D5  LD C,A  Restore it to C.  
24D6  EXX  Now use the exchange resisters.  
24D7  POP BC  Diagonal step to BC'.  
24D8  PUSH BC  Save it too.  
24D9  JR D_L_STEP  Jump to take the step.  
D_L_HR_VT  24DB  LD C,A  Save A (unreduced) in C.  
24DC  PUSH DE  Step to stack briefly.  
24DD  EXX  Get exchange registers.  
24DE  POP BC  Step to BC' now.  
D_L_STEP  24DF  LD HL,($5C7D)  Now take the step: first, COORDS to HL' as the start point.  
24E2  LD A,B  Ystep from B' to A.  
24E3  ADD A,H  Add in H'.  
24E4  LD B,A  Result to B'.  
24E5  LD A,C  Now the Xstep; it will be tested for range (Y will be tested in PLOT).  
24E6  INC A  
24E7  ADD A,L  Add L' to C' in A, jump on carry for further test.  
24E8  JR C,D_L_RANGE  
24EA  JR Z,REPORT_B_3  Zero after no carry denotes Xposition 1, out of range.  
D_L_PLOT  24EC  DEC A  Restore true value to A.  
24ED  LD C,A  Value to C' for plotting.  
24EE  CALL PLOT_SUB  Plot the step.  
24F1  EXX  Restore main registers.  
24F2  LD A,C  C back to A to continue algorithm.  
24F3  DJNZ D_L_LOOP  Loop back for B steps (i.e. H steps).  
24F5  POP DE  Clear machine stack.  
24F6  RET  Finished.  
D_L_RANGE  24F7  JR Z,D_L_PLOT  Zero after carry denotes Xposition 255, in range.  
REPORT_B_3  24F9  RST $08  Call the error handling routine.  
24FA  DEFB $0A 
Prev: 247D  Up: Map 