Prev: 09341 Up: Map Next: 09467
09399: 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 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 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. 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 Y-step from B' to A. 09443 ADD A,H Add in H'. 09444 LD B,A Result to B'. 09445 LD A,C Now the X-step; 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 X-position -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 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 09465 RST 8 Call the error handling routine. 09466 DEFB 10
 Prev: 09341 Up: Map Next: 09467