10
20
30
40
50
60 :
70 OSWRCH=&FFEE:OSNEWL=&FFE7:OSBYTE=&FFF4
80 OSARGS=&FFDA:lptr=&A8
90 vduv=&0226
100 scrMap=&0356
110 originXY=&030C:
120 latestXY=&0310:
130 beforeXY=&0314:
140 plotCM=&031F
150 vduQXY=&0320:vduQX=vduQXY+0:vduQY=vduQXY+2
160 plotXY=&0324:plotX=plotXY+0:plotY=plotXY+2:
170 lastXY=&0328:lastX=lastXY+0:lastY=lastXY+2:
180 prevXY=&032C:prevX=prevXY+0:prevY=prevXY+2:
190 pixelY=&00D1
200 cordXY=&00D2:x1=cordXY+0:y1=cordXY+1:x2=cordXY+2:y2=cordXY+3
210 charXY=&00D6:charX=charXY+0:charY=charXY+1
220 oldXY =&00DA:oldX =oldXY +0:oldY =oldXY +1
230 dx=&DC:dy=&DD:xi=&DE:yi=&DF:ai=dx:bi=dy:d=&330:d=charX
240 :
250
260
270
280
290
300
310
320
330
340
350
360 :
370 DIM mcode% 600:load%=&FFFF08CA
380 FOR P=0 TO 1
390 O%=mcode%:P%=load%
400 [OPT P*3+4
410 .init%
420 LDA #1:LDX #lptr:LDY #0:JSR OSARGS :\ ptr=>command line
430 LDA (lptr),Y:CMP #13:BEQ switchOn :\ M7PLOT<cr> -> turn on
440 LDX #&FF
450 .switchLp
460 INX:LDA &FF00,X:CMP #&60:BNE switchLp :\ Look for RTS
470 INY:LDA (lptr),Y:AND #&DF :\ M7PLOT ON -> turn on
480 LDY #&FF:CMP #ASC"N":BNE switchOff :\ M7PLOT OFF -> turn off
490 .switchOn
500 LDX #newplot AND 255:LDY #newplot DIV 256
510 .switchOff
520 STX vduv+0:STY vduv+1
530 :
540 .plotquit
550 RTS
560 .newplot
570 BCS plotquit :\ VDU 23,nn
580 \ &031F = PLOT number, also in A
590 \ &0320 = PLOT X
600 \ &0322 = PLOT Y after cycling:
610 \ &0324 = last X (int) plotX
620 \ &0326 = last Y (int) plotY
630 \ &0328 = prev X (int) lastX
640 \ &0328 = prev Y (int) lastY
650 \ &032C = temp X (int) prevX
660 \ &032E = temp Y (int) prevY
670 \
680 \ Start by converting coordinates
690 LDY scrMap:CPY #4:BNE plotquit:PHA :\ Not map 4, teletext mode
700 AND #4:EOR #4:TAY:JSR plotadd :\ Add origin or previous point
710 :
720 \ Cycle the coordinates
730 LDX #3
740 .loop
750 \LDA latestXY,X:\STA beforeXY,X :\ Only needed for fills
760 \LDA lastXY,X:\STA prevXY,X :\ These are the
770 LDA plotXY,X:STA lastXY,X :\ three plotting
780 LDA vduQXY,X:STA plotXY,X :\ coordinates
790 STA latestXY,X
800 DEX:BPL loop
810 :
820 \ Scale the coordinates
830 .plotscale
840 LDX #plotX-&300 :\ 1280
850 LDY #4:JSR plotdiv:PHP :\ DIV 16 => 80, save sign
860 LDA plotX
870 CMP #60:BCC P%+4:SBC #1
880 CMP #20:BCC P%+4:SBC #1 :\ Adjust => 78
890 PLP:BPL P%+4:ADC #2 :\ Adjust if negative
900 STA plotX:PHA
910 :
920 LDX #plotY-&300 :\ 1024
930 LDY #3:JSR plotdiv:PHP :\ DIV 8 => 125, save sign
940 LDA plotY:STA pixelY
950 LSR A:ADC #13:ADC pixelY
960 ROR A:LSR A:LSR A
970 ADC pixelY:ROR A:ADC pixelY
980 ROR A:LSR A:LSR A :\ DIV 5 => 25
990 CLC:ADC plotY :\ 25+125 => 150
1000 ROR A :\ DIV 2 => 75
1010 PLP:BPL P%+4:ADC #&66 :\ Adjust if negative
1020 STA plotY
1030 :
1040 STA y1:STA y2
1050 PLA:STA x1:STA x2 :\ Point to start plotting
1060 PLA:TAY :\ Get PLOT action
1070 AND #&F8:CMP #&80:BEQ clg :\ PLOT &8x -> set up screen
1080 TYA:CMP #&48:BCS plotexit :\ Not DRAW or PLOT
1090 AND #3:BEQ plotexit :\ %xxxxxxxx00 - MOVE
1100 LDA #134:JSR OSBYTE
1110 STX oldX:STY oldY :\ Save current text X,Y
1120 LDA &D0:PHA:ORA #2:STA &D0:\ Don't scroll screen
1130 LDA plotCM:JSR plotaction
1140 PLA:STA &D0:BCS plotexit :\ Skip past if no output
1150 LDA #31:JSR OSWRCH :\ Restore text X,Y
1160 LDA oldX:JSR OSWRCH
1170 LDA oldY:JMP OSWRCH
1180 .plotexit
1190 RTS
1200 :
1210 .clg
1220 LDA #22:JSR OSWRCH
1230 LDA #&87:JSR OSWRCH :\ MODE &87
1240 LDX #25:BNE initgo :\ Initialise 25 lines
1250 .initlp
1260 JSR OSNEWL
1270 .initgo
1280 TYA:EOR #&10:JSR OSWRCH :\ Set colour code
1290 DEX:BNE initlp
1300 LDA #30:JMP OSWRCH
1310 :
1320 .plotaction
1330 CMP #&40:BCC plotdraw :\ %00xxxxxx - DRAW
1340 : :\ %0100xxxx - PLOT
1350 : :\ %xxxxxx01 - set pixel
1360 : :\ %xxxxxx10 - invert pixel
1370 : :\ %xxxxxx11 - unset pixel
1380 \ Core plot code, x1=hardware 0-77
1390 \ y1=hardware 0-74
1400 .plotpoint
1410 LDA y1:CMP #75:BCS plotnull :\ Off screen
1420 LSR A:ADC #21:LSR A:LDY #3 :\ DIV 3
1430 .plotdiv3
1440 ADC y1:ROR A:LSR A
1450 DEY:BNE plotdiv3:STA charY :\ DIV 3 => 25
1460 ASL A:ADC charY :\ 3*(Y DIV 3)
1470 SBC y1:STA pixelY :\ 3*(Y DIV 3) - Y
1480 LDA x1:CMP #78:BCS plotnull :\ Off screen
1490 PHA
1500 :
1510 LDA #31:JSR OSWRCH :\ Position cursor
1520 PLA:LSR A:PHP:CLC:ADC #1:JSR OSWRCH
1530 LDA #24:SEC:SBC charY:JSR OSWRCH
1540 LDA #135:JSR OSBYTE :\ Get character
1550 PLP:LDA pixelY:ROL A:TAY
1560 LDA plotCM:LSR A:BCS plotpix:\ %xxxxxxx1 - set/unset pixel
1570 TXA:BCC plotinv :\ %xxxxxx10 - invert pixel
1580 .plotpix
1590 LSR A:TXA :\ %xxxxxx01 - set pixel
1600 .plotset :\ %xxxxxx11 - unset pixel
1610 ORA plotchars-&FA,Y:BCC plotwrite
1620 .plotinv
1630 EOR plotchars-&FA,Y
1640 .plotwrite
1650 ORA #&80:JSR OSWRCH:CLC :\ Output character
1660 .plotnull
1670 RTS
1680 :
1690 \ Draw from lastX,lastY to plotX,plotY hardware coords
1700 .plotdraw
1710 PHA :\ Save plot command
1720 LDA lastX:STA x1 :\ lastXY is start
1730 LDA lastY:STA y1
1740 :
1750 \ Draw a line using Bresenham algorithm
1760 \ Draw from x1,y1 to x2,y2
1770 \
1780 \ Decide direction to draw and step
1790 LDX #1
1800 .drawSignLp
1810 LDA x1,X:CMP #&A8:LDA x2,X:BCC drawPlus
1820 CMP #&A8:BCS drawSame:BCC drawDiff
1830 .drawPlus
1840 CMP #&A8:BCC drawSame
1850 .drawDiff
1860 LDA x2,X:CMP x1,X:JMP drawSign
1870 .drawSame
1880 LDA x1,X:CMP x2,X
1890 .drawSign
1900 BCS drawSub :\ x1<x2 y1<y2
1910 SEC:LDA x2,X:SBC x1,X:STA dx,X :\ dx=x2-x1 dy=y2-y1
1920 LDA #1:STA xi,X:BNE drawSignNxt :\ xi=+1 yi=+1
1930 .drawSub :\ x1>x2 y1<y2
1940 LDA x1,X:SBC x2,X:STA dx,X :\ dx=x1-x2 dy=y1-y2
1950 lda #255:STA xi,X :\ xi=-1 yi=-1
1960 .drawSignNxt
1970 DEX:BPL drawSignLp
1980 :
1990 \ Test for primary axis (longer distance)
2000 LDX #0:LDY #1 :\ X is longer, X=Xaxis, Y=Yaxis
2010 LDA dx:CMP dy:BCS P%+4:INX:DEY :\ Y is longer, X=Yaxis, X=Xaxis
2020 :
2030 \ Draw the line
2040 .drawXY
2050 LDA dx,Y:PHA:SEC:SBC dx,X:STA ai :\ ai=dy-dx or ai=dx-dy
2060 ADC #12:STA d :\ d=dy-dx+offset or d=dx-dy+offset
2070 PLA:STA bi:JMP drawXYgo :\ bi=dy or bi=dx
2080 .drawXYlp :\ while x1 <> x2
2090 TXA:PHA:JSR plotpoint :\ plot(x1,y1)
2100 PLA:TAX:EOR #1:TAY
2110 LDA d:CLC:BMI drawXYb :\ diff<0, inc b
2120 .drawXYa :\ diff>0, inc a
2130 LDA xi,Y:ADC x1,Y:sta x1,Y :\ y1 += yi
2140 LDA ai:CLC:BCC drawXYplot
2150 .drawXYb
2160 LDA bi :\ diff += bi
2170 .drawXYplot
2180 ADC d:sta d :\ update diff
2190 LDA xi,X:CLC:ADC x1,X:sta x1,X :\ x1 += xi
2200 .drawXYgo
2210 LDA x1,X:EOR x2,X:BNE drawXYlp :\ Loop until last point
2220 PLA:AND #8:BNE drawdone :\ Omit final point
2230 JMP plotpoint
2240 :
2250 .plotdiv
2260 LDA &301,X:ASL A
2270 ROR &301,X:ROR &300,X
2280 DEY:BNE plotdiv
2290 LDA &301,X:\ Return with flags=sign
2300 .drawdone
2310 CLC:RTS
2320 :
2330 .plotadd
2340 LDX #vduQXY-&300:JSR plotadd2
2350 INX:INX:INY:INY
2360 .plotadd2
2370 CLC
2380 LDA &300,X:ADC originXY+0,Y:STA &300,X
2390 LDA &301,X:ADC originXY+1,Y:STA &301,X
2400 RTS
2410 :
2420 .plotchars
2430 EQUB &01:EQUB &02:EQUB &04
2440 EQUB &08:EQUB &10:EQUB &40
2450 :
2460 ]:IF P%>&FFFF0B00:PRINT"Code overflow":END
2470 NEXT
2480 PRINT"*SAVE M7PLOT ";~mcode%;" ";~O%;" ";~init%OR&FFFF0000;" ";~load%
2490 END
2500 DEFPROCtest1
2510 PLOT &87,0,0
2520 FOR Y%=0 TO 999 STEP 8
2530 PLOT 69,16+0000,Y%
2540 PLOT 69,16+1229,Y%
2550 PLOT 69,16+Y%*1230DIV1000,000+Y%+0
2560 PLOT 69,16+Y%*1230DIV1000,999-Y%+1
2570 PLOT 69,16+Y%*1230DIV1000,000
2580 PLOT 69,16+Y%*1230DIV1000,999
2590 NEXT:IFGET
2600 PRINT'''
2610 ENDPROC
2620 DEFPROCtest2
2630 PLOT &87,0,0
2640 X%=0:Y%=890:V%=0:W%=0
2650 REPEAT
2660 MOVE V%,W%:DRAW X%,Y%
2670 PRINTTAB(5,23);CHR$135;X%;",";Y%;
2680 PRINT" ";?dx;" ";?dy;" ";?xi;" ";?yi;
2690 PRINT" ";?ai;" ";?bi;" ";?d;" ";
2700 PRINTTAB(5,24);CHR$135;?&8F;" ";
2710 A%=GET:VDU13
2720 MOVE V%,W%:PLOT 7,X%,Y%
2730 IF A%=ASC"."ORA%=ASC">":X%=X%+1-9*INKEY-1
2740 IF A%=ASC","ORA%=ASC"<":X%=X%-1+9*INKEY-1
2750 IF A%=ASC"A"ORA%=ASC"a":Y%=Y%+1-9*INKEY-1
2760 IF A%=ASC"Z"ORA%=ASC"z":Y%=Y%-1+9*INKEY-1
2770 IF A%=ASC"H"ORA%=ASC"h":V%=V%+1-4*INKEY-1
2780 IF A%=ASC"G"ORA%=ASC"g":V%=V%-1+4*INKEY-1
2790 IF A%=ASC"Y"ORA%=ASC"y":W%=W%+1-4*INKEY-1
2800 IF A%=ASC"B"ORA%=ASC"b":W%=W%-1+4*INKEY-1
2810 UNTIL FALSE
2820 ENDPROC
2830 DEFPROCtest3
2840 PLOT &87,0,0
2850 MOVE 0,0:DRAW 1279,0:DRAW 1279,999:DRAW 0,999
2860 DRAW 0,0:DRAW 640,500:DRAW 1279,999
2870 MOVE 0,999:DRAW 640,500:DRAW 1279,0
2880 MOVE 440,400:PLOT 1,420,0:PLOT 1,0,199
2890 PLOT 1,-420,0:PLOT 1,0,-199
2900 MOVE 440,100:PLOT 10,420,0:PLOT 10,0,199
2910 PLOT 10,-420,0:PLOT 10,0,-199
2920 IFGET
2930 PRINT'''
2940 ENDPROC
2950 DEFPROCtest4
2960 PLOT &87,0,0
2970 MOVE 0,0:DRAW 1279,0:DRAW 1279,999:DRAW 0,999
2980 DRAW 0,0:DRAW 1279,999
2990 MOVE 0,999:DRAW 1279,0
3000 IFGET
3010 PRINT'''
3020 ENDPROC
3030 DEFPROCtest5
3040 PLOT &87,0,0
3050 MOVE 16+0,0:DRAW 16+1229,0:DRAW 16+1229,999:DRAW 16+0,999
3060 DRAW 16+0,0:DRAW 16+1229,999
3070 MOVE 16+0,999:DRAW 16+1229,0
3080 IFGET
3090 PRINT'''
3100 ENDPROC