Routines
 Prev: 247D Up: Map Next: 24FB
24B7: THE 'LINE-DRAWING' SUBROUTINE
 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 H-L 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 Y-step from B' to A. 24E3 ADD A,H Add in H'. 24E4 LD B,A Result to B'. 24E5 LD A,C Now the X-step; 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 X-position -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 X-position 255, in range. This entry point is used by the routines at PIXEL_ADD and STK_TO_A. Report B - Integer out of range. REPORT_B_3 24F9 RST \$08 Call the error handling routine. 24FA DEFB \$0A
 Prev: 247D Up: Map Next: 24FB