Routines 
Prev: 09341  Up: Map  Next: 09467 
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  09399  CALL STK_TO_BC  ABS Y to B; ABS X to C; SGN Y to D; SGN X to E.  
09402  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.  
09403  CP B  
09404  JR NC,DL_X_GE_Y  
09406  LD L,C  
09407  PUSH DE  Save diagonal step (+/1,+/1) in DE.  
09408  XOR A  Insert a vertical step (+/1,0) into DE (D holds SGN Y).  
09409  LD E,A  
09410  JR DL_LARGER  Now jump to set H.  
DL_X_GE_Y  09412  OR C  Return if ABS X and ABS Y are both zero.  
09413  RET Z  
09414  LD L,B  The smaller (ABS Y here) goes to L.  
09415  LD B,C  ABS X to B here, for H.  
09416  PUSH DE  Save the diagonal step here too.  
09417  LD D,0  Horizontal step (0,+/1) to DE here.  
DL_LARGER  09419  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.


09420  LD A,B  B to A as well as to H.  
09421  RRA  A starts at INT (H/2).  
D_L_LOOP  09422  ADD A,L  L is added to A.  
09423  JR C,D_L_DIAG  If 256 or more, jump  diagonal step.  
09425  CP H  If A is less than H, jump for horizontal or vertical step.  
09426  JR C,D_L_HR_VT  
D_L_DIAG  09428  SUB H  Reduce A by H.  
09429  LD C,A  Restore it to C.  
09430  EXX  Now use the exchange resisters.  
09431  POP BC  Diagonal step to BC'.  
09432  PUSH BC  Save it too.  
09433  JR D_L_STEP  Jump to take the step.  
D_L_HR_VT  09435  LD C,A  Save A (unreduced) in C.  
09436  PUSH DE  Step to stack briefly.  
09437  EXX  Get exchange registers.  
09438  POP BC  Step to BC' now.  
D_L_STEP  09439  LD HL,(23677)  Now take the step: first, COORDS to HL' as the start point.  
09442  LD A,B  Ystep from B' to A.  
09443  ADD A,H  Add in H'.  
09444  LD B,A  Result to B'.  
09445  LD A,C  Now the Xstep; it will be tested for range (Y will be tested in PLOT).  
09446  INC A  
09447  ADD A,L  Add L' to C' in A, jump on carry for further test.  
09448  JR C,D_L_RANGE  
09450  JR Z,REPORT_B_3  Zero after no carry denotes Xposition 1, out of range.  
D_L_PLOT  09452  DEC A  Restore true value to A.  
09453  LD C,A  Value to C' for plotting.  
09454  CALL PLOT_SUB  Plot the step.  
09457  EXX  Restore main registers.  
09458  LD A,C  C back to A to continue algorithm.  
09459  DJNZ D_L_LOOP  Loop back for B steps (i.e. H steps).  
09461  POP DE  Clear machine stack.  
09462  RET  Finished.  
D_L_RANGE  09463  JR Z,D_L_PLOT  Zero after carry denotes Xposition 255, in range.  
REPORT_B_3  09465  RST 8  Call the error handling routine.  
09466  DEFB 10 
Prev: 09341  Up: Map  Next: 09467 