home *** CD-ROM | disk | FTP | other *** search
/ Really Useful CD 1 / ReallyUsefulCD1.iso / extras / progutils / _graphics / line < prev   
Encoding:
Text File  |  1991-05-24  |  39.4 KB  |  780 lines

  1. REM > <Graphics$Dir>.Line draw routine for 8 bpp modes
  2. REM
  3. REM Version 1.04 ⌐ Jan-Herman Buining (24-May-1991)
  4. REM
  5. REM For one byte per pixel screen modes only
  6. REM
  7. :
  8. REM Screen mode, boundaries, size and resolution
  9. MODE   13       : REM Screen mode
  10. XShift=2        : REM X pixel shift factor
  11. YShift=2        : REM Y pixel shift factor
  12. HSize =1280     : REM Screen width in pixels (bytes)
  13. VSize =1024     : REM Screen height in pixels (bytes)
  14. LBound=0   +320 : REM Minimum X   >= 0
  15. RBound=1280-320 : REM Maximum X+1 <= HSize
  16. BBound=0   +256 : REM Minimum Y   >= 0
  17. TBound=1024-256 : REM Maximum Y+1 <= VSize
  18. :
  19. REM Random generator coords resolution in bits
  20. Random=11       : REM -1024 <= Random <= 1023
  21. :
  22. REM Bounding box, lines should clip inside this
  23. RECTANGLE LBound-1,BBound-1,RBound-LBound+1,TBound-BBound+1
  24. VDU 24,LBound;BBound;RBound-1;TBound-1;
  25. :
  26. PROCAssemble(Start%,End%)
  27. :
  28. REM Repeated drawing of random lines until <Escape>
  29. CALL CallLine
  30. :
  31. END
  32. :
  33. DEF PROCLine(A%,B%,C%,D%,E%)
  34.   CALL Line
  35. ENDPROC
  36. :
  37. REM +++++ ASSEMBLY +++++
  38.   :
  39.   DEF PROCAssemble(RETURN Code%,RETURN O%)
  40.     LOCAL Opt%,L%,P%,CodeSize%
  41.     :
  42.     REM Size of code
  43.     CodeSize=4<<10
  44.     :
  45.     DIM Code% CodeSize,L% -1
  46.     :
  47.     FOR Opt%=%1100 TO %1110 STEP %0010
  48.       P%=Code%
  49.       O%=Code%
  50.       [OPT Opt%
  51. ;**********************************************
  52. ;**********************************************
  53. ;**              Data                        **
  54. ;**********************************************
  55. ;**********************************************
  56. .ScreenAddress   EQUD    FNScreenAddress      ; Screen base address
  57. ; Optionally you could choose to store window
  58. ; clipping (bound) variables in this block
  59. ;----------------------------------------------
  60. .RandomSeed1     EQUD    RND(TIME)            ; Random seed
  61. .RandomSeed2     EQUD    RND(2)               ; 33rd bit
  62. ;**********************************************
  63. ;**********************************************
  64. ;**              Random coordinates          **
  65. ;**********************************************
  66. ;**********************************************
  67. .RandomCoordinates
  68.                  STMFD   R13!,{R8-R10,R14}
  69.                  LDR     R8,RandomSeed1
  70.                  LDR     R9,RandomSeed2
  71. ;----------------------------------------------
  72.                  TST     R9,R9,LSR #1         ; Fast random number
  73.                  MOVS    R10,R8,RRX
  74.                  ADC     R9,R9,R9
  75.                  EOR     R10,R10,R8,LSL #12
  76.                  EOR     R8,R10,R10,LSR #20   ; Random mumber in R8
  77.                  MOV     R0,R8
  78. ;----------------------------------------------
  79.                  TST     R9,R9,LSR #1         ; Fast random number
  80.                  MOVS    R10,R8,RRX
  81.                  ADC     R9,R9,R9
  82.                  EOR     R10,R10,R8,LSL #12
  83.                  EOR     R8,R10,R10,LSR #20   ; Random mumber in R8
  84.                  MOV     R1,R8
  85. ;----------------------------------------------
  86.                  TST     R9,R9,LSR #1         ; Fast random number
  87.                  MOVS    R10,R8,RRX
  88.                  ADC     R9,R9,R9
  89.                  EOR     R10,R10,R8,LSL #12
  90.                  EOR     R8,R10,R10,LSR #20   ; Random mumber in R8
  91.                  MOV     R2,R8
  92. ;----------------------------------------------
  93.                  TST     R9,R9,LSR #1         ; Fast random number
  94.                  MOVS    R10,R8,RRX
  95.                  ADC     R9,R9,R9
  96.                  EOR     R10,R10,R8,LSL #12
  97.                  EOR     R8,R10,R10,LSR #20   ; Random mumber in R8
  98.                  MOV     R3,R8
  99. ;----------------------------------------------
  100.                  TST     R9,R9,LSR #1         ; Fast random number
  101.                  MOVS    R10,R8,RRX
  102.                  ADC     R9,R9,R9
  103.                  EOR     R10,R10,R8,LSL #12
  104.                  EOR     R8,R10,R10,LSR #20   ; Random mumber in R8
  105.                  MOV     R4,R8,LSR #24        ; Colour
  106. ;----------------------------------------------
  107.                  STR     R8,RandomSeed1
  108.                  STR     R9,RandomSeed2
  109. ;----------------------------------------------
  110.                  MOV     R8,#LBound           ; Centre random coordinates
  111.                  ADD     R8,R8,#RBound        ; for neater display
  112.                  MOV     R8,R8,ASR #1         ; Window X centre
  113.                  MOV     R9,#BBound
  114.                  ADD     R9,R9,#TBound
  115.                  MOV     R9,R9,ASR #1         ; Window Y centre
  116.                  MOV     R0,R0,LSR #32-Random ; X1
  117.                  SUB     R0,R0,#1<<(Random-1)
  118.                  ADD     R0,R0,R8
  119.                  MOV     R1,R1,LSR #32-Random ; Y1
  120.                  SUB     R1,R1,#1<<(Random-1)
  121.                  ADD     R1,R1,R9
  122.                  MOV     R2,R2,LSR #32-Random ; X2
  123.                  SUB     R2,R2,#1<<(Random-1)
  124.                  ADD     R2,R2,R8
  125.                  MOV     R3,R3,LSR #32-Random ; Y2
  126.                  SUB     R3,R3,#1<<(Random-1)
  127.                  ADD     R3,R3,R9
  128.                  LDMFD   R13!,{R8-R10,PC}^    ; {R0=X start point}
  129.                                               ; {R1=Y start point}
  130.                                               ; {R2=X end point}
  131.                                               ; {R3=Y end point}
  132.                                               ; {R4=Colour byte}
  133. ;**********************************************
  134. .CallLine        STMFD   R13!,{R0-R5,R14}
  135.                  SWI     "XOS_RemoveCursors"
  136. .CallLineCont    MOV     R5,#256              ; 256 lines at a time
  137. .CallLineNext    BL      RandomCoordinates    ; Get random point and colour
  138.                  BL      Line                 ; Plot the line
  139.                  SUBS    R5,R5,#1             ; Next line
  140.                  BGT     CallLineNext
  141.                  SWI     "XOS_ReadEscapeState"
  142.                  BCC     CallLineCont         ; Next 256 lines
  143.                  SWI     "XOS_RestoreCursors"
  144.                  LDMFD   R13!,{R0-R5,PC}^     ; Preserve mode and state
  145. ;**********************************************
  146. ;**********************************************
  147. ;**              Line preprocessing          **
  148. ;**********************************************
  149. ;**********************************************
  150.                                               ; {R0=X start point}
  151.                                               ; {R1=Y start point}
  152.                                               ; {R2=X end point}
  153.                                               ; {R3=Y end point}
  154.                                               ; {R4=Colour byte}
  155.                                               ; {Preserve mode and state}
  156. .Line            STMFD   R13!,{R0-R6,R11,R14}
  157.                  MOV     R0,R0,LSL #16        ; Ensure 16 bit coords
  158.                  MOV     R1,R1,LSL #16        ; Don't combine these two
  159.                  MOV     R2,R2,LSL #16        ; shifts as line rejection
  160.                  MOV     R3,R3,LSL #16        ; compatibility will be lost
  161.                  MOV     R0,R0,ASR #XShift    ; Shift to screen resolution
  162.                  MOV     R1,R1,ASR #XShift
  163.                  MOV     R2,R2,ASR #XShift
  164.                  MOV     R3,R3,ASR #XShift
  165. ;----------------------------------------------
  166.                  CMP     R3,R1                ; Delta Y
  167.                  BEQ     LineHorizontal       ; Line is horizontal or point
  168.                  CMP     R2,R0                ; Delta X
  169.                  BEQ     LineVertical         ; Line is vertical
  170.                  BGT     LinePreprocess       ; Coordinates in right order
  171. ;----------------------------------------------
  172.                  EOR     R0,R0,R2             ; Swap X coordinates
  173.                  EOR     R2,R0,R2
  174.                  EOR     R0,R0,R2
  175.                  EOR     R1,R1,R3             ; Swap Y coordinates also
  176.                  EOR     R3,R1,R3
  177.                  EOR     R1,R1,R3
  178. ;----------------------------------------------
  179. .LinePreprocess  MOV     R5,#0                ; Point state
  180.                  CMP     R0,#LBound<<16-XShift
  181.                  ORRLT   R5,R5,#%0001         ; Left of border
  182.                  CMP     R0,#RBound<<16-XShift
  183.                  ORRGE   R5,R5,#%0010         ; Right of border
  184.                  CMP     R1,#BBound<<16-YShift
  185.                  ORRLT   R5,R5,#%0100         ; Below border
  186.                  CMP     R1,#TBound<<16-YShift
  187.                  ORRGE   R5,R5,#%1000         ; Above border
  188. ;----------------------------------------------
  189.                  MOV     R6,#0                ; Point state
  190.                  CMP     R2,#LBound<<16-XShift
  191.                  ORRLT   R6,R6,#%0001         ; Left of border
  192.                  CMP     R2,#RBound<<16-XShift
  193.                  ORRGE   R6,R6,#%0010         ; Right of border
  194.                  CMP     R3,#BBound<<16-YShift
  195.                  ORRLT   R6,R6,#%0100         ; Below border
  196.                  CMP     R3,#TBound<<16-YShift
  197.                  ORRGE   R6,R6,#%1000         ; Above border
  198. ;----------------------------------------------
  199.                  ORRS    R11,R5,R6            ; Combination
  200.                  BEQ     LineOnScreen         ; Line already on screen
  201.                  EOR     R14,R5,R6            ; Difference
  202.                  BICS    R14,R11,R14          ; Logical intersection
  203.                  LDMNEFD R13!,{R0-R6,R11,PC}^ ; Line outside boundaries
  204.                  TST     R11,#%0011           ; Actually, this can only be
  205.                  BNE     LineClipToX          ; called first (or never)
  206. ;----------------------------------------------
  207. .LineClipToY     STMFD   R13!,{R7-R10}        ; {R5,R6,R11,R14 Corruptable}
  208.                  MOV     R7,R2,ASR #1         ; Dx was positive
  209.                  SUB     R7,R7,R0,ASR #1      ; Subdivide X
  210.                  MOV     R8,R3,ASR #1         ; Dy can be anything
  211.                  SUBS    R8,R8,R1,ASR #1      ; Subdivide Y
  212.                  BEQ     LineClipToYExit      ; No more clipping possible
  213.                  RSBLT   R8,R8,#0             ; Dy must be positive
  214.                  RSBLT   R7,R7,#0             ; Negate Dx
  215. ;----------------------------------------------
  216.                  MOV     R9,#BBound>>YShift   ; Screen Y boundary (bottom)
  217.                  MOV     R10,#TBound>>YShift  ; Screen Y boundary (top)
  218.                  SUB     R10,R10,#1           ; Visible boundary
  219. ;----------------------------------------------
  220. .LineClipToYNext TST     R5,#%0100            ; Clip to line Y=R9 ?
  221.                  BEQ     LineClipToYNBY1      ; No
  222.                  CMP     R1,R9,LSL #16        ; Position from clipping line
  223.                  ADDLT   R0,R0,R7             ; Under
  224.                  ADDLT   R1,R1,R8
  225.                  SUBGE   R0,R0,R7             ; Over
  226.                  SUBGE   R1,R1,R8
  227.                  CMP     R9,R1,ASR #16        ; Am I on the clipping line ?
  228.                  BICEQ   R5,R5,#%0100         ; Yes
  229.                  B       LineClipToYNTY1      ; Mutual exclusive
  230. ;----------------------------------------------
  231. .LineClipToYNBY1 TST     R5,#%1000            ; Clip to line Y=R10 ?
  232.                  BEQ     LineClipToYNTY1      ; No
  233.                  CMP     R1,R10,LSL #16       ; Position from clipping line
  234.                  ADDLT   R0,R0,R7             ; Under
  235.                  ADDLT   R1,R1,R8
  236.                  SUBGE   R0,R0,R7             ; Over
  237.                  SUBGE   R1,R1,R8
  238.                  CMP     R10,R1,ASR #16       ; Am I on the clipping line ?
  239.                  BICEQ   R5,R5,#%1000         ; Yes
  240. ;----------------------------------------------
  241. .LineClipToYNTY1 TST     R6,#%0100            ; Clip to line Y=R9 ?
  242.                  BEQ     LineClipToYNBY2      ; No
  243.                  CMP     R3,R9,LSL #16        ; Position from clipping line
  244.                  ADDLT   R2,R2,R7             ; Under
  245.                  ADDLT   R3,R3,R8
  246.                  SUBGE   R2,R2,R7             ; Over
  247.                  SUBGE   R3,R3,R8
  248.                  CMP     R9,R3,ASR #16        ; Am I on the clipping line ?
  249.                  BICEQ   R6,R6,#%0100         ; Yes
  250.                  B       LineClipToYNTY2      ; Mutual exclusive
  251. ;----------------------------------------------
  252. .LineClipToYNBY2 TST     R6,#%1000            ; Clip to line Y=R10 ?
  253.                  BEQ     LineClipToYNTY2      ; No
  254.                  CMP     R3,R10,LSL #16       ; Position from clipping line
  255.                  ADDLT   R2,R2,R7             ; Under
  256.                  ADDLT   R3,R3,R8
  257.                  SUBGE   R2,R2,R7             ; Over
  258.                  SUBGE   R3,R3,R8
  259.                  CMP     R10,R3,ASR #16       ; On the clipping line ?
  260.                  BICEQ   R6,R6,#%1000         ; Yes
  261. ;----------------------------------------------
  262. .LineClipToYNTY2 MOVS    R8,R8,ASR #1         ; Subdivide Y
  263.                  BEQ     LineClipToYExit      ; No more clipping possible
  264.                  MOV     R7,R7,ASR #1         ; Subdivide X
  265. ;----------------------------------------------
  266.                  ORR     R11,R5,R6            ; Combination
  267.                  ANDS    R11,R11,#%1100       ; Y clipping done ?
  268.                  BNE     LineClipToYNext      ; No
  269. ;----------------------------------------------
  270. .LineClipToYExit CMP     R0,#LBound<<16-XShift; Round off error ?
  271.                  MOVLT   R0,#LBound<<16-XShift; Yes
  272.                  CMP     R1,#BBound<<16-YShift
  273.                  MOVLT   R1,#BBound<<16-YShift
  274.                  CMP     R2,#LBound<<16-XShift
  275.                  MOVLT   R2,#LBound<<16-XShift
  276.                  CMP     R3,#BBound<<16-YShift
  277.                  MOVLT   R3,#BBound<<16-YShift
  278.                  LDMFD   R13!,{R7-R10}
  279. ;----------------------------------------------
  280.                  MOV     R5,R3,ASR #16
  281.                  CMP     R5,R1,ASR #16        ; Delta Y
  282.                  BEQ     LineHorizontal       ; Line is horizontal or point
  283.                  MOV     R5,R2,ASR #16
  284.                  CMP     R5,R0,ASR #16        ; Delta X
  285.                  BEQ     LineVertical         ; Line is vertical
  286. ;----------------------------------------------
  287. .LineOnScreen    MOV     R0,R0,ASR #16        ; Hardware coords
  288.                  MOV     R1,R1,ASR #16
  289.                  MOV     R2,R2,ASR #16
  290.                  MOV     R3,R3,ASR #16
  291. ;----------------------------------------------
  292.                  SUB     R2,R2,R0             ; Delta X
  293.                  MOV     R5,#(HSize>>XShift)  ; Pixels per line
  294.                  SUBS    R3,R3,R1             ; Delta Y
  295.                  RSBLT   R3,R3,#0             ; Absolute value of Delta Y
  296.                  RSBGT   R5,R5,#0             ; Ascending, is down in memory
  297.                  FNPixelAddress               ; Returns pixel address in R11
  298. ;----------------------------------------------
  299.                  CMP     R2,R3
  300.                  BGT     LineAroundHorizontal
  301.                  BLT     LineAroundVertical
  302.                  BEQ     LineDiagonal
  303. ;**********************************************
  304. ;**********************************************
  305. ;**              Horizontal clipping         **
  306. ;**********************************************
  307. ;**********************************************
  308. .LineClipToX     STMFD   R13!,{R7-R10}        ; {R5,R6,R11,R14 Corruptable}
  309.                  MOV     R8,R3,ASR #1         ; Dy can be anything
  310.                  SUB     R8,R8,R1,ASR #1      ; Subdivide Y
  311.                  MOV     R7,R2,ASR #1         ; Dx was positive
  312.                  SUBS    R7,R7,R0,ASR #1      ; Subdivide X
  313.                  BEQ     LineClipToXExit      ; No more clipping possible
  314. ;----------------------------------------------
  315.                  MOV     R9,#LBound>>XShift   ; Screen X boundary (left)
  316.                  MOV     R10,#RBound>>XShift  ; Screen X boundary (right)
  317.                  SUB     R10,R10,#1           ; Visible boundary
  318. ;----------------------------------------------
  319. .LineClipToXNext TST     R5,#%0001            ; Clip to line X=R9 ?
  320.                  BEQ     LineClipToXNLX1      ; No
  321.                  CMP     R0,R9,LSL #16        ; Position from clipping line
  322.                  ADDLT   R0,R0,R7             ; Left
  323.                  ADDLT   R1,R1,R8
  324.                  SUBGE   R0,R0,R7             ; Right
  325.                  SUBGE   R1,R1,R8
  326.                  CMP     R9,R0,ASR #16        ; Am I on the clipping line ?
  327.                  BICEQ   R5,R5,#%0001         ; Yes
  328.                  B       LineClipToXNRX1      ; Mutual exclusive
  329. ;----------------------------------------------
  330. .LineClipToXNLX1 TST     R5,#%0010            ; Clip to line X=R10 ?
  331.                  BEQ     LineClipToXNRX1      ; No
  332.                  CMP     R0,R10,LSL #16       ; Position from clipping line
  333.                  ADDLT   R0,R0,R7             ; Left
  334.                  ADDLT   R1,R1,R8
  335.                  SUBGE   R0,R0,R7             ; Right
  336.                  SUBGE   R1,R1,R8
  337.                  CMP     R10,R0,ASR #16       ; Am I on the clipping line ?
  338.                  BICEQ   R5,R5,#%0010         ; Yes
  339. ;----------------------------------------------
  340. .LineClipToXNRX1 TST     R6,#%0001            ; Clip to line X=R9 ?
  341.                  BEQ     LineClipToXNLX2      ; No
  342.                  CMP     R2,R9,LSL #16        ; Position from clipping line
  343.                  ADDLT   R2,R2,R7             ; Left
  344.                  ADDLT   R3,R3,R8
  345.                  SUBGE   R2,R2,R7             ; Right
  346.                  SUBGE   R3,R3,R8
  347.                  CMP     R9,R2,ASR #16        ; Am I on the clipping line ?
  348.                  BICEQ   R6,R6,#%0001         ; Yes
  349.                  B       LineClipToXNRX2      ; Mutual exclusive
  350. ;----------------------------------------------
  351. .LineClipToXNLX2 TST     R6,#%0010            ; Clip to line X=R10 ?
  352.                  BEQ     LineClipToXNRX2      ; No
  353.                  CMP     R2,R10,LSL #16       ; Position from clipping line
  354.                  ADDLT   R2,R2,R7             ; Left
  355.                  ADDLT   R3,R3,R8
  356.                  SUBGE   R2,R2,R7             ; Right
  357.                  SUBGE   R3,R3,R8
  358.                  CMP     R10,R2,ASR #16       ; On the clipping line ?
  359.                  BICEQ   R6,R6,#%0010         ; Yes
  360. ;----------------------------------------------
  361. .LineClipToXNRX2 MOVS    R7,R7,ASR #1         ; Subdivide X
  362.                  BEQ     LineClipToXExit      ; No more clipping possible
  363.                  MOV     R8,R8,ASR #1         ; Subdivide Y
  364. ;----------------------------------------------
  365.                  ORR     R11,R5,R6            ; Combination
  366.                  ANDS    R11,R11,#%0011       ; X clipping done ?
  367.                  BNE     LineClipToXNext      ; No
  368. ;----------------------------------------------
  369. .LineClipToXExit CMP     R0,#LBound<<16-XShift; Round off error ?
  370.                  MOVLT   R0,#LBound<<16-XShift; Yes
  371.                  LDMFD   R13!,{R7-R10}
  372. ;----------------------------------------------
  373.                  MOV     R5,R3,ASR #16
  374.                  CMP     R5,R1,ASR #16        ; Delta Y
  375.                  BEQ     LineHorizontal       ; Line is horizontal or point
  376.                  MOV     R5,R2,ASR #16
  377.                  CMP     R5,R0,ASR #16        ; Delta X
  378.                  BEQ     LineVertical         ; Line is vertical
  379.                  B       LinePreprocess       ; Now clip, reject or draw
  380. ;**********************************************
  381. ;**********************************************
  382. ;**              Horizontal line drawing     **
  383. ;**********************************************
  384. ;**********************************************
  385.                                               ; {R0=X start point <<16}
  386.                                               ; {R1=Y start point <<16}
  387.                                               ; {R2=X end point <<16}
  388.                                               ; {R3=Y end point <<16}
  389.                                               ; {R4=Colour byte}
  390. .LineHorizontal  CMP     R1,#BBound<<16-YShift; Line below border ?
  391.                  LDMLTFD R13!,{R0-R6,R11,PC}^
  392.                  CMP     R1,#TBound<<16-YShift; Line above border ?
  393.                  LDMGEFD R13!,{R0-R6,R11,PC}^
  394. ;----------------------------------------------
  395.                  CMP     R2,R0                ; X coordinates order
  396.                  EORLT   R0,R0,R2             ; Swap X coordinates
  397.                  EORLT   R2,R0,R2
  398.                  EORLT   R0,R0,R2
  399. ;----------------------------------------------
  400.                  CMP     R2,#LBound<<16-XShift; Line left of border ?
  401.                  LDMLTFD R13!,{R0-R6,R11,PC}^
  402.                  CMP     R0,#RBound<<16-XShift; Line right of border ?
  403.                  LDMGEFD R13!,{R0-R6,R11,PC}^
  404. ;----------------------------------------------
  405.                  MOV     R0,R0,ASR #16        ; Hardware coords
  406.                  MOV     R1,R1,ASR #16
  407.                  MOV     R2,R2,ASR #16
  408.                  MOV     R3,R3,ASR #16
  409. ;----------------------------------------------
  410.                  CMP     R0,#LBound>>XShift   ; Clip X start ?
  411.                  MOVLT   R0,#LBound>>XShift
  412.                  CMP     R2,#RBound>>XShift   ; Clip X end ?
  413.                  MOVGE   R2,#RBound>>XShift   ; One too high therefore ADDLT
  414.                  SUB     R2,R2,R0             ; Delta X, one too low
  415.                  ADDLT   R2,R2,#1             ; Number of pixels to plot
  416.                  FNPixelAddress               ; Returns pixel address in R11
  417. ;----------------------------------------------
  418.                  RSBS    R5,R2,#11            ; Short lines breakeven point
  419.                  ADDGE   PC,PC,R5,LSL #2      ; 1*4 bytes of code
  420.                  B       LineHorizontalLong   ; 12 or more pixels
  421.                  STRB    R4,[R11],#1          ; 11 pixels
  422.                  STRB    R4,[R11],#1
  423.                  STRB    R4,[R11],#1
  424.                  STRB    R4,[R11],#1          ; 8 pixels
  425.                  STRB    R4,[R11],#1
  426.                  STRB    R4,[R11],#1
  427.                  STRB    R4,[R11],#1
  428.                  STRB    R4,[R11],#1          ; 4 pixels
  429.                  STRB    R4,[R11],#1
  430.                  STRB    R4,[R11],#1
  431.                  STRB    R4,[R11],#1          ; 1 pixel
  432.                  LDMFD   R13!,{R0-R6,R11,PC}^
  433. ;----------------------------------------------
  434. .LineHorizontalLong
  435.                  ANDS    R5,R11,#%11          ; Bytes before aligned part
  436.                  BEQ     LineHorizontalAligned
  437.                  RSB     R5,R5,#4             ; Bytes to plot to align
  438.                  CMP     R5,#2
  439.                  STRGTB  R4,[R11],#1          ; 3 pixels
  440.                  STRGEB  R4,[R11],#1          ; 2 pixels
  441.                  STRALB  R4,[R11],#1          ; 1 pixel
  442.                  SUBS    R2,R2,R5             ; Pixels left to be plotted
  443.                  LDMLEFD R13!,{R0-R6,R11,PC}^ ; All pixels done
  444. ;----------------------------------------------
  445. .LineHorizontalAligned
  446.                  AND     R4,R4,#&FF           ; Colour byte
  447.                  ORR     R4,R4,R4,LSL #8      ; Set up colour byte to
  448.                  ORR     R4,R4,R4,LSL #16     ; become colour word
  449.                  MOV     R0,R4                ; For multiple stores
  450.                  MOV     R1,R4                ; R0,R1,R3,R4
  451.                  MOV     R3,R4
  452. ;----------------------------------------------
  453.                  MOV     R5,R2,LSR #4         ; 16 or more pixels to plot ?
  454.                  MOV     R14,R5,LSR #5        ; 512 pixels a time
  455.                  AND     R5,R5,#%11111        ; Multiple of 512 pixels
  456.                  RSB     R5,R5,#32            ; Number of entries to skip
  457.                  ADD     PC,PC,R5,LSL #2      ; 1*4 bytes of code
  458.                  MOVNV   R0,R0                ; Dummy instruction
  459. .LineHorizontalAlignedNext512
  460.                  STMIA   R11!,{R0,R1,R3,R4}   ; 16 MPixels/sec store
  461.                  STMIA   R11!,{R0,R1,R3,R4}
  462.                  STMIA   R11!,{R0,R1,R3,R4}
  463.                  STMIA   R11!,{R0,R1,R3,R4}
  464.                  STMIA   R11!,{R0,R1,R3,R4}
  465.                  STMIA   R11!,{R0,R1,R3,R4}
  466.                  STMIA   R11!,{R0,R1,R3,R4}
  467.                  STMIA   R11!,{R0,R1,R3,R4}
  468.                  STMIA   R11!,{R0,R1,R3,R4}
  469.                  STMIA   R11!,{R0,R1,R3,R4}
  470.                  STMIA   R11!,{R0,R1,R3,R4}
  471.                  STMIA   R11!,{R0,R1,R3,R4}
  472.                  STMIA   R11!,{R0,R1,R3,R4}
  473.                  STMIA   R11!,{R0,R1,R3,R4}
  474.                  STMIA   R11!,{R0,R1,R3,R4}
  475.                  STMIA   R11!,{R0,R1,R3,R4}
  476.                  STMIA   R11!,{R0,R1,R3,R4}
  477.                  STMIA   R11!,{R0,R1,R3,R4}
  478.                  STMIA   R11!,{R0,R1,R3,R4}
  479.                  STMIA   R11!,{R0,R1,R3,R4}
  480.                  STMIA   R11!,{R0,R1,R3,R4}
  481.                  STMIA   R11!,{R0,R1,R3,R4}
  482.                  STMIA   R11!,{R0,R1,R3,R4}
  483.                  STMIA   R11!,{R0,R1,R3,R4}
  484.                  STMIA   R11!,{R0,R1,R3,R4}
  485.                  STMIA   R11!,{R0,R1,R3,R4}
  486.                  STMIA   R11!,{R0,R1,R3,R4}
  487.                  STMIA   R11!,{R0,R1,R3,R4}
  488.                  STMIA   R11!,{R0,R1,R3,R4}
  489.                  STMIA   R11!,{R0,R1,R3,R4}
  490.                  STMIA   R11!,{R0,R1,R3,R4}
  491.                  STMIA   R11!,{R0,R1,R3,R4}
  492.                  SUBS    R14,R14,#1
  493.                  BGE     LineHorizontalAlignedNext512
  494. ;----------------------------------------------
  495.                  AND     R2,R2,#%1111         ; Modulo of 16 pixels
  496.                  MOVS    R5,R2,LSR #2         ; Multiple of 4 pixels left ?
  497.                  BEQ     LineHorizontalLessThan4
  498.                  CMP     R5,#2
  499.                  STMGTIA R11!,{R0,R1,R3}      ; 12-15 pixels
  500.                  STMEQIA R11!,{R0,R1}         ;  8-11 pixels
  501.                  STMLTIA R11!,{R0}            ;  4- 7 pixels
  502. ;----------------------------------------------
  503. .LineHorizontalLessThan4                      ;  0- 3 pixels
  504.                  ANDS    R5,R2,#%11           ; Some pixels left ?
  505.                  LDMEQFD R13!,{R0-R6,R11,PC}^ ; No
  506.                  CMP     R5,#2
  507.                  STRGTB  R4,[R11],#1          ; 3 pixels
  508.                  STRGEB  R4,[R11],#1          ; 2 pixels
  509.                  STRALB  R4,[R11],#1          ; 1 pixel
  510.                  LDMFD   R13!,{R0-R6,R11,PC}^
  511. ;**********************************************
  512. ;**********************************************
  513. ;**              Vertical line drawing       **
  514. ;**********************************************
  515. ;**********************************************
  516.                                               ; {R0=X start point <<16}
  517.                                               ; {R1=Y start point <<16}
  518.                                               ; {R2=X end point <<16}
  519.                                               ; {R3=Y end point <<16}
  520.                                               ; {R4=Colour byte}
  521. .LineVertical    CMP     R0,#LBound<<16-XShift; Line left of border ?
  522.                  LDMLTFD R13!,{R0-R6,R11,PC}^
  523.                  CMP     R0,#RBound<<16-XShift; Line right of border ?
  524.                  LDMGEFD R13!,{R0-R6,R11,PC}^
  525. ;----------------------------------------------
  526.                  CMP     R1,R3                ; Y coordinates order
  527.                  EORLT   R1,R1,R3             ; Swap Y coordinates
  528.                  EORLT   R3,R1,R3
  529.                  EORLT   R1,R1,R3
  530. ;----------------------------------------------
  531.                  CMP     R1,#BBound<<16-YShift; Line below border ?
  532.                  LDMLTFD R13!,{R0-R6,R11,PC}^
  533.                  CMP     R3,#TBound<<16-YShift; Line above border ?
  534.                  LDMGEFD R13!,{R0-R6,R11,PC}^
  535. ;----------------------------------------------
  536.                  MOV     R0,R0,ASR #16        ; Hardware coords
  537.                  MOV     R1,R1,ASR #16
  538.                  MOV     R2,R2,ASR #16
  539.                  MOV     R3,R3,ASR #16
  540. ;----------------------------------------------
  541.                  CMP     R1,#TBound>>YShift   ; Clip Y start ?
  542.                  MOVGE   R1,#TBound>>YShift
  543.                  SUBGE   R1,R1,#1
  544.                  CMP     R3,#BBound>>YShift   ; Clip Y end ?
  545.                  MOVLT   R3,#BBound>>YShift
  546.                  SUB     R3,R1,R3             ; Delta Y
  547.                  ADD     R3,R3,#1             ; Number of pixels to plot
  548.                  FNPixelAddress               ; Returns pixel address in R11
  549. ;----------------------------------------------
  550.                  MOV     R14,R3,LSR #3        ; Initialise pixel counter
  551.                  AND     R1,R3,#%111          ; Low bits for unfold
  552.                  RSB     R1,R1,#8             ; Skip MOD 8 entries in table
  553.                  ADD     PC,PC,R1,LSL #2      ; 1*4 bytes of code
  554.                  MOVNV   R0,R0                ; Dummy instruction
  555. .LineVerticalNextPixel                        ; 1.75 MPixels/sec store
  556. ;----------------------------------------------
  557.                  STRB    R4,[R11],#(HSize>>XShift)
  558.                  STRB    R4,[R11],#(HSize>>XShift)
  559.                  STRB    R4,[R11],#(HSize>>XShift)
  560.                  STRB    R4,[R11],#(HSize>>XShift)
  561.                  STRB    R4,[R11],#(HSize>>XShift)
  562.                  STRB    R4,[R11],#(HSize>>XShift)
  563.                  STRB    R4,[R11],#(HSize>>XShift)
  564.                  STRB    R4,[R11],#(HSize>>XShift)
  565.                  SUBS    R14,R14,#1           ; 8 more pixels to plot?
  566.                  BGE     LineVerticalNextPixel
  567.                  LDMFD   R13!,{R0-R6,R11,PC}^
  568. ;**********************************************
  569. ;**********************************************
  570. ;**              Random line drawing         **
  571. ;**********************************************
  572. ;**********************************************
  573.                                               ; {R2=Delta X > 0 (DX>DY)}
  574.                                               ; {R3=Delta Y > 0}
  575.                                               ; {R4=Colour byte}
  576.                                               ; {R5=Y screen line increment}
  577.                                               ; {R11=Pixel base address}
  578. .LineAroundHorizontal
  579.                  RSB     R0,R2,#0             ; Initialise error term
  580.                  MOV     R14,R2,LSR #3        ; Initialise pixel counter
  581.                  AND     R1,R2,#%111          ; Low bits for unfold
  582.                  RSB     R1,R1,#8             ; Skip MOD 8 entries in table
  583.                  ADD     PC,PC,R1,LSL #4      ; 4*4 bytes of code
  584.                  MOVNV   R0,R0                ; Dummy instruction
  585. .LineAroundHorizontalNextPixel                ; 1 MPixels/sec store
  586. ;----------------------------------------------
  587.                  STRB    R4,[R11],#1          ; Plot pixel and update X coord
  588.                  ADDS    R0,R0,R3,LSL #1      ; Increase error term
  589.                  ADDGT   R11,R11,R5           ; Update Y coord
  590.                  SUBGT   R0,R0,R2,LSL #1      ; And decrease error term
  591. ;----------------------------------------------
  592.                  STRB    R4,[R11],#1          ; Plot pixel and update X coord
  593.                  ADDS    R0,R0,R3,LSL #1      ; Increase error term
  594.                  ADDGT   R11,R11,R5           ; Update Y coord
  595.                  SUBGT   R0,R0,R2,LSL #1      ; And decrease error term
  596. ;----------------------------------------------
  597.                  STRB    R4,[R11],#1          ; Plot pixel and update X coord
  598.                  ADDS    R0,R0,R3,LSL #1      ; Increase error term
  599.                  ADDGT   R11,R11,R5           ; Update Y coord
  600.                  SUBGT   R0,R0,R2,LSL #1      ; And decrease error term
  601. ;----------------------------------------------
  602.                  STRB    R4,[R11],#1          ; Plot pixel and update X coord
  603.                  ADDS    R0,R0,R3,LSL #1      ; Increase error term
  604.                  ADDGT   R11,R11,R5           ; Update Y coord
  605.                  SUBGT   R0,R0,R2,LSL #1      ; And decrease error term
  606. ;----------------------------------------------
  607.                  STRB    R4,[R11],#1          ; Plot pixel and update X coord
  608.                  ADDS    R0,R0,R3,LSL #1      ; Increase error term
  609.                  ADDGT   R11,R11,R5           ; Update Y coord
  610.                  SUBGT   R0,R0,R2,LSL #1      ; And decrease error term
  611. ;----------------------------------------------
  612.                  STRB    R4,[R11],#1          ; Plot pixel and update X coord
  613.                  ADDS    R0,R0,R3,LSL #1      ; Increase error term
  614.                  ADDGT   R11,R11,R5           ; Update Y coord
  615.                  SUBGT   R0,R0,R2,LSL #1      ; And decrease error term
  616. ;----------------------------------------------
  617.                  STRB    R4,[R11],#1          ; Plot pixel and update X coord
  618.                  ADDS    R0,R0,R3,LSL #1      ; Increase error term
  619.                  ADDGT   R11,R11,R5           ; Update Y coord
  620.                  SUBGT   R0,R0,R2,LSL #1      ; And decrease error term
  621. ;----------------------------------------------
  622.                  STRB    R4,[R11],#1          ; Plot pixel and update X coord
  623.                  ADDS    R0,R0,R3,LSL #1      ; Increase error term
  624.                  ADDGT   R11,R11,R5           ; Update Y coord
  625.                  SUBGT   R0,R0,R2,LSL #1      ; And decrease error term
  626. ;----------------------------------------------
  627.                  SUBS    R14,R14,#1           ; 8 more pixels to plot?
  628.                  BGE     LineAroundHorizontalNextPixel
  629. ;----------------------------------------------
  630.                  STRB    R4,[R11],#1          ; End pixel
  631.                  LDMFD   R13!,{R0-R6,R11,PC}^
  632. ;**********************************************
  633.                                               ; {R2=Delta X > 0 (DX<DY)}
  634.                                               ; {R3=Delta Y > 0}
  635.                                               ; {R4=Colour byte}
  636.                                               ; {R5=Y screen line increment}
  637.                                               ; {R11=Pixel base address}
  638. .LineAroundVertical
  639.                  RSB     R0,R3,#0             ; Initialise error term
  640.                  MOV     R14,R3,LSR #3        ; Initialise pixel counter
  641.                  AND     R1,R3,#%111          ; Low bits for unfold
  642.                  RSB     R1,R1,#8             ; Skip MOD 8 entries in table
  643.                  ADD     PC,PC,R1,LSL #4      ; 4*4 bytes of code
  644.                  MOVNV   R0,R0                ; Dummy instruction
  645. .LineAroundVerticalNextPixel                  ; 1.75 MPixels/sec store
  646. ;----------------------------------------------
  647.                  STRB    R4,[R11],R5          ; Plot pixel and update Y coord
  648.                  ADDS    R0,R0,R2,LSL #1      ; Increase error term
  649.                  ADDGT   R11,R11,#1           ; Update X coord
  650.                  SUBGT   R0,R0,R3,LSL #1      ; And decrease error term
  651. ;----------------------------------------------
  652.                  STRB    R4,[R11],R5          ; Plot pixel and update Y coord
  653.                  ADDS    R0,R0,R2,LSL #1      ; Increase error term
  654.                  ADDGT   R11,R11,#1           ; Update X coord
  655.                  SUBGT   R0,R0,R3,LSL #1      ; And decrease error term
  656. ;----------------------------------------------
  657.                  STRB    R4,[R11],R5          ; Plot pixel and update Y coord
  658.                  ADDS    R0,R0,R2,LSL #1      ; Increase error term
  659.                  ADDGT   R11,R11,#1           ; Update X coord
  660.                  SUBGT   R0,R0,R3,LSL #1      ; And decrease error term
  661. ;----------------------------------------------
  662.                  STRB    R4,[R11],R5          ; Plot pixel and update Y coord
  663.                  ADDS    R0,R0,R2,LSL #1      ; Increase error term
  664.                  ADDGT   R11,R11,#1           ; Update X coord
  665.                  SUBGT   R0,R0,R3,LSL #1      ; And decrease error term
  666. ;----------------------------------------------
  667.                  STRB    R4,[R11],R5          ; Plot pixel and update Y coord
  668.                  ADDS    R0,R0,R2,LSL #1      ; Increase error term
  669.                  ADDGT   R11,R11,#1           ; Update X coord
  670.                  SUBGT   R0,R0,R3,LSL #1      ; And decrease error term
  671. ;----------------------------------------------
  672.                  STRB    R4,[R11],R5          ; Plot pixel and update Y coord
  673.                  ADDS    R0,R0,R2,LSL #1      ; Increase error term
  674.                  ADDGT   R11,R11,#1           ; Update X coord
  675.                  SUBGT   R0,R0,R3,LSL #1      ; And decrease error term
  676. ;----------------------------------------------
  677.                  STRB    R4,[R11],R5          ; Plot pixel and update Y coord
  678.                  ADDS    R0,R0,R2,LSL #1      ; Increase error term
  679.                  ADDGT   R11,R11,#1           ; Update X coord
  680.                  SUBGT   R0,R0,R3,LSL #1      ; And decrease error term
  681. ;----------------------------------------------
  682.                  STRB    R4,[R11],R5          ; Plot pixel and update Y coord
  683.                  ADDS    R0,R0,R2,LSL #1      ; Increase error term
  684.                  ADDGT   R11,R11,#1           ; Update X coord
  685.                  SUBGT   R0,R0,R3,LSL #1      ; And decrease error term
  686. ;----------------------------------------------
  687.                  SUBS    R14,R14,#1           ; 8 more pixels to plot?
  688.                  BGE     LineAroundVerticalNextPixel
  689. ;----------------------------------------------
  690.                  STRB    R4,[R11],R5          ; End pixel
  691.                  LDMFD   R13!,{R0-R6,R11,PC}^
  692. ;**********************************************
  693.                                               ; {R2=Delta X > 0 (DX=DY)}
  694.                                               ; {R3=Delta Y > 0}
  695.                                               ; {R4=Colour byte}
  696.                                               ; {R5=Y screen line increment}
  697.                                               ; {R11=Pixel base address}
  698. .LineDiagonal    ADD     R5,R5,#1             ; Automatic X increment
  699.                  ADD     R3,R3,#1             ; Increment for last pixel
  700.                  MOV     R14,R3,LSR #3        ; Initialise pixel counter
  701.                  AND     R1,R3,#%111          ; Low bits for unfold
  702.                  RSB     R1,R1,#8             ; Skip MOD 8 entries in table
  703.                  ADD     PC,PC,R1,LSL #2      ; 1*4 bytes of code
  704.                  MOVNV   R0,R0                ; Dummy instruction
  705. .LineDiagonalNextPixel                        ; 1.75 MPixels/sec store
  706. ;----------------------------------------------
  707.                  STRB    R4,[R11],R5          ; Plot pixel asn update coords
  708.                  STRB    R4,[R11],R5
  709.                  STRB    R4,[R11],R5
  710.                  STRB    R4,[R11],R5
  711.                  STRB    R4,[R11],R5
  712.                  STRB    R4,[R11],R5
  713.                  STRB    R4,[R11],R5
  714.                  STRB    R4,[R11],R5
  715. ;----------------------------------------------
  716.                  SUBS    R14,R14,#1           ; 8 more pixels to plot?
  717.                  BGE     LineDiagonalNextPixel
  718.                  LDMFD   R13!,{R0-R6,R11,PC}^
  719. ;**********************************************
  720. ;**********************************************
  721. ;**              End                         **
  722. ;**********************************************
  723. ;**********************************************
  724.       ]
  725.     NEXT
  726.   ENDPROC
  727.   :
  728. REM ----- ASSEMBLY -----
  729. :
  730. REM +++++ MACRO'S +++++
  731.   :
  732.   DEF FNPixelAddress
  733.     REM Returns the screen address for a
  734.     REM pixel with (R0,R1) coordinates in R11
  735.     [OPT Opt%
  736.                  LDR     R11,ScreenAddress    ; Screen base address
  737.                  ADD     R11,R11,R0           ; X coordinate
  738.                  RSB     R1,R1,#(VSize>>YShift) ; Reverse Y coordinate
  739.                  SUB     R1,R1,#1             ; to visible area maximum
  740.                  MOV     R0,#(HSize>>XShift)  ; Just this way for overscan
  741.                  MLA     R11,R0,R1,R11        ; Address of Y coordinate line
  742.     ]
  743.   =Opt%
  744.   :
  745.   DEF FNScreenAddress
  746.     DIM Block% 16
  747.     Block%!00=149
  748.     Block%!04=-1
  749.     SYS "OS_ReadVduVariables",Block%,Block%+8
  750.   =Block%!08
  751.   :
  752.   DEF FNADR(R%,Label%)
  753.     REM Prevents bad immediate constant problems
  754.     REM Limited to addresses in the range
  755.     REM -&7FFF to &7FFF relative to the PC
  756.     LOCAL Move%
  757.     IF (Opt% AND %10)=0 THEN
  758.       [OPT Opt%
  759.                  EQUD    0
  760.                  EQUD    0
  761.       ]
  762.     ELSE
  763.       Move%=Label%-(P%+8)
  764.       IF Move%<0 THEN
  765.         [OPT Opt%
  766.                  SUB     R%,PC,#(-Move% AND &00FF)
  767.                  SUB     R%,R%,#(-Move% AND &FF00)
  768.         ]
  769.       ELSE
  770.         [OPT Opt%
  771.                  ADD     R%,PC,#(Move% AND &00FF)
  772.                  ADD     R%,R%,#(Move% AND &FF00)
  773.         ]
  774.       ENDIF
  775.     ENDIF
  776.   =Opt%
  777.   :
  778. REM ----- MACRO'S -----
  779. :
  780.