This repository has been archived by the owner on Nov 29, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDrawLine.a
745 lines (653 loc) · 34.2 KB
/
DrawLine.a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
.INCLUDE GRAFTYPES.TEXT
;-----------------------------------------------------------------
;
; --> DRAWLINE.TEXT
;
.PROC DrawLine
.REF RgnBlt,RSect,ShieldCursor,ShowCursor,TrimRect
.REF InitRgn,SeekRgn,PatExpand,ColorMap
.REF XorSlab,DrawSlab,SlabMode,FastSlabMode,MaskTab
;----------------------------------------------------------------
;
; PROCEDURE DRAWLINE(P1,P2: POINT);
;
; DRAWS A LINE CLIPPED TO CURRENT PORT'S CLIPRGN AND VISRGN
;
; P1 AND P2 ARE GIVEN IN LOCAL COORDINATES OF THEPORT.
;
;------------------------------------------------
;
; A6 OFFSETS OF PARAMETERS AFTER LINK:
;
PARAMSIZE .EQU 8 ;SIZE OF PARAMETERS
P1 .EQU PARAMSIZE+8-4 ;POINT
P2 .EQU P1-4 ;POINT
;-------------------------------------------------
;
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
;
EXPAT .EQU -64 ;16 LONGS
LINERECT .EQU EXPAT-8 ;RECT
MINRECT .EQU LINERECT-8 ;RECT
STATEA .EQU MINRECT-RGNREC ;RGN STATE RECORD
STATEB .EQU STATEA-RGNREC ;RGN STATE RECORD
STATEC .EQU STATEB-RGNREC ;RGN STATE RECORD
SAVESTK .EQU STATEC-4 ;LONG
RECTFLAG .EQU SAVESTK-2 ;WORD
MASKBUF .EQU RECTFLAG-4 ;LONG
BUFLEFT .EQU MASKBUF-2 ;WORD
BUFSIZE .EQU BUFLEFT-2 ;WORD
VERT .EQU BUFSIZE-2 ;WORD
MODECASE .EQU VERT-4 ;LONG
PAT .EQU MODECASE-4 ;LONG, ADDR OF PAT
LEFTEDGE .EQU PAT-4 ;LONG, FIXED POINT
RIGHTEDGE .EQU LEFTEDGE-4 ;LONG, FIXED POINT
SLOPE .EQU RIGHTEDGE-4 ;LONG, FIXED POINT
DSTLEFT .EQU SLOPE-4 ;LONG
SAVEA5 .EQU DSTLEFT-4 ;LONG
PORT .EQU SAVEA5-4 ;LONG
MODE .EQU PORT-2 ;WORD
FASTFLAG .EQU MODE-2 ;BYTE
BIGRGN .EQU FASTFLAG-4 ;LONG, RgnHandle
VARSIZE .EQU BIGRGN ;SIZE OF LOCAL VARIABLES
LINK A6,#VARSIZE ;ALLOCATE LOCAL VARS
MOVEM.L D0-D7/A1-A5,-(SP) ;SAVE REGS
MOVE.L SP,SAVESTK(A6) ;REMEMBER STACK FOR LATER
MOVE.L A5,SAVEA5(A6) ;REMEMBER GLOBAL PTR
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
MOVE.L WIDEOPEN(A0),BIGRGN(A6) ;STASH WIDEOPEN IN BIGRGN
MOVE.L THEPORT(A0),A3 ;POINT TO CURRENT GRAFPORT
TST PNVIS(A3) ;IS PNVIS NEGATIVE ?
BLT GOHOME ;YES, QUIT
MOVE.L A3,PORT(A6) ;SAVE PORT FOR LATER
;-------------------------------------------------------
;
; QUIT IF PEN MODE NOT IN 8..15
;
MOVEQ #-8,D0
AND PNMODE(A3),D0 ;GET ALL BUT 3 BITS OF PEN MODE
CMP #8,D0 ;IS PEN MODE 8..15 ?
BNE GOHOME ;NO, QUIT
;-------------------------------------------------------
;
; Check for color filtering. Alter mode and pattern accordingly.
;
MOVE PNMODE(A3),-(SP) ;PUSH PEN MODE
PEA PNPAT(A3) ;PUSH ADDR OF PEN PATTERN
TST COLRBIT(A3) ;IS COLORBIT = 0 ?
BEQ.S NOCOLOR ;YES, DON'T MAP
JSR COLORMAP ;CHECK AGAINST THECOLOR, THEFILTER
NOCOLOR MOVE.L (SP)+,PAT(A6) ;GET (ALTERED) PATTERN
MOVE (SP)+,MODE(A6) ;AND (ALTERED) MODE
;---------------------------------------------------------
;
; GET CLIPRGN AND VISRGN HANDLES AND DE-REFERENCE THEM
;
MOVE.L A3,A5 ;PUT GRAFPTR IN A5
MOVE.L CLIPRGN(A5),A2 ;GET CLIPRGN HANDLE
MOVE.L (A2),A2 ;GET CLIPRGN POINTER
MOVE.L VISRGN(A5),A3 ;GET VISRGN HANDLE
MOVE.L (A3),A3 ;GET VISRGN POINTER
;-------------------------------------------------------------
;
; SET UP LINERECT, THE RECTANGLE BOUNDING THE LINE AND PEN
;
MOVEM.W P2(A6),D1/D2/D3/D4 ;GET D1=V1, D2=H1, D3=V2, D4=H2
CMP D3,D1 ;IS V1 > V2 ?
BLE.S VOK2 ;NO, CONTINUE
EXG D1,D3 ;YES, SWAP VERT
VOK2 CMP D4,D2 ;IS H1 > H2 ?
BLE.S HOK2 ;NO, CONTINUE
EXG D2,D4 ;NO SWAP HORIZ
HOK2 ADD PNSIZE+H(A5),D4 ;ADD PEN WIDTH TO RIGHT
ADD PNSIZE+V(A5),D3 ;ADD PEN HEIGHT TO BOTTOM
MOVEM.W D1/D2/D3/D4,LINERECT(A6) ;STORE TOP, LEFT, BOTTOM, RIGHT
;-----------------------------------------------------------------------
;
; CALC MINRECT, THE INTERSECTION OF LINERECT, BITMAP BOUNDS,
; CLIPRGN BBOX, AND VISRGN BBOX. QUIT IF NO INTERSECTION.
;
PEA LINERECT(A6) ;PUSH LINE RECT
PEA PORTBITS+BOUNDS(A5) ;PUSH BITMAP BOUNDS
PEA RGNBBOX(A2) ;PUSH CLIPRGN BBOX
PEA RGNBBOX(A3) ;PUSH VISRGN BBOX
MOVE #4,-(SP) ;PUSH NRECTS=4
PEA MINRECT(A6) ;PUSH DST ADDR
JSR RSECT ;CALC INTERSECTION
BEQ GOHOME ;QUIT IF NO INTERSECT
;
; HIDE CURSOR IF CURSOR INTERSECTS MINRECT.
;
PEA MINRECT(A6) ;PUSH SHIELDRECT PARAMETER
MOVE.L PORTBITS+BOUNDS+TOPLEFT(A5),-(SP) ;PUSH DELTA TO CONVERT TO GLOBAL
MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
JSR SHIELDCURSOR ;HIDE CURSOR IF IT INTERSECTS
MOVE.L PORT(A6),A5 ;GET BACK THEPORT
;
; CHECK FOR BOTH VISRGN AND CLIPRGN RECTANGULAR
;
CLR.B FASTFLAG(A6) ;FASTFLAG := FALSE
CMP #10,RGNSIZE(A2) ;IS CLIPRGN RECTANGULAR ?
BNE.S FLAGOK ;NO, CONTINUE
CMP #10,RGNSIZE(A3) ;IS VISRGN RECTANGULAR ?
BEQ.S CKPAT ;YES, CONTINUE
;
; If only visRgn is non-rectangular, then check if
; its intersection with minrect would be rectangular.
; IF TrimRect(visRgn,minRect) then treat as rectangular.
;
MOVE.L visRgn(A5),-(SP) ;push rgnHandle
PEA minRect(A6) ;push addr of minRect
JSR TrimRect ;call trimRect
BLT DONE ;quit if intersection empty
BGT.S FLAGOK ;continue if non-rectangular
;
; CHECK FOR BLACK OR WHITE PATTERN
;
CKPAT MOVE.L PAT(A6),A0 ;POINT TO PATTERN
MOVE.L (A0)+,D0 ;GET 1ST HALF OF PATTERN
CMP.L (A0)+,D0 ;IS IT SAME AS 2ND HALF ?
BNE.S FLAGOK ;NO, CONTINUE
NOT.L D0 ;IS PATTERN BLACK ?
BEQ.S YESFLAG ;YES, WE MADE IT
NOT.L D0 ;IS PATTERN WHITE ?
BNE.S FLAGOK ;NO, CONTINUE
EOR #4,MODE(A6) ;YES, ALTER MODE AS IF BLACK
YESFLAG ST FASTFLAG(A6) ;RECT CLIPPED AND BLACK
;
; fast case: map mode into black,xor,white, or do-nothing
;
MOVEQ #7,D0 ;GET 3 BIT MASK
AND MODE(A6),D0 ;GET 3 BITS OF MODE
MOVE.B MODEMAP(D0),D0 ;MAP TO BLACK,XOR,WHITE,NOP
BMI DONE ;QUIT IF DO-NOTHING MODE
MOVE D0,MODE(A6) ;UPDATE MODE
BRA.S FLAGOK ;AND CONTINUE
MODEMAP .BYTE 0,0,1,2,2,255,255,255
FLAGOK
;
; GET THE TWO LINE ENDPOINTS INTO REGISTERS
; AND CHECK FOR HORIZONTAL OR VERTICAL LINE
;
MOVEM.W P2(A6),D1/D2/D3/D4 ;GET D1=V2, D2=H2, D3=V1, D4=H1
CMP D2,D4 ;H1=H2 ?
BEQ.S HVLINE ;YES, DO VERTICAL LINE
CMP D1,D3 ;NO, IS V2 > V1 ?
BGT.S SLANTED ;YES, DRAW SLANTED LINE
BLT.S VSWAP ;SWAP POINTS AND DRAW SLANTED
;ELSE V1=V2, DO HORIZONTAL
;-----------------------------------------------------------
;
; LINE IS EITHER HORIZONTAL OR VERTICAL.
; CHECK FOR ONE DOT LINE, BLACK OR WHITE PATTERN, AND
; CLIPRGN AND VISRGN BOTH RECTANGULAR. IF SO, OPTIMIZE FAST LINES.
;
HVLINE TST.B FASTFLAG(A6) ;RECT CLIPPED AND BLACK ?
BEQ.S NOTFAST ;NO, CONTINUE
CMP.L #$00010001,PNSIZE(A5) ;IS PEN 1 BY 1 ?
BEQ FASTLINE ;YES, DO IT FAST !
;--------------------------------------------------------------------
;
; NOT FASTLINE. PUSH PARAMS AND CALL RGNBLT FOR HORIZ OR VERT LINE.
;
NOTFAST PEA PORTBITS(A5) ;PUSH SRCBITS = DSTBITS
MOVE.L (SP),-(SP) ;PUSH DSTBITS
PEA MINRECT(A6) ;PUSH SRCRECT = DSTRECT
MOVE.L (SP),-(SP) ;PUSH DSTRECT
MOVE PNMODE(A5),-(SP) ;PUSH MODE
PEA PNPAT(A5) ;PUSH PATTERN
MOVE.L CLIPRGN(A5),-(SP) ;PUSH CLIPRGN HANDLE
MOVE.L VISRGN(A5),-(SP) ;PUSH VISRGN HANDLE
MOVE.L BIGRGN(A6),-(SP) ;PUSH SAVED WIDEOPEN
MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
JSR RGNBLT ;DRAW THE HORIZ OR VERT LINE
BRA DONE ;RESTORE CURSOR AND QUIT
;-------------------------------------------------------------
;
; THE LINE IS SLANTED. SORT VERTICALLY
; AND DRAW TOP TO BOTTOM AS HORIZONTAL SLABS.
;
VSWAP EXG D1,D3 ;SORT POINTS BY VERTICAL
EXG D2,D4 ;SWAP HORIZ TO MATCH
SLANTED MOVE D3,D0 ;COPY LINE BOTTOM
ADD PNSIZE+V(A5),D0 ;ADD PEN HEIGHT
CMP RGNBBOX+TOP(A2),D0 ;IS RESULT <= CLIP TOP ?
BLE DONE ;YES, RESTORE CURSOR AND QUIT
CMP RGNBBOX+BOTTOM(A2),D1 ;IS TOP >= CLIP BOTTOM ?
BGE DONE ;YES, RESTORE CURSOR AND QUIT
;-------------------------------------------------------------
;
; SET UP INITIAL FIXED POINT LEFTEDGE AND RIGHTEDGE
; AND CHECK FOR ZERO PENSIZE.
;
MOVE.W D2,LEFTEDGE(A6) ;LEFTEDGE.INT := TOP HORIZ
MOVE.W #$8000,LEFTEDGE+2(A6) ;LEFTEDGE.FRACT := 1/2
MOVE.L LEFTEDGE(A6),RIGHTEDGE(A6) ;RIGHTEDGE:=LEFTEDGE
MOVE PNSIZE+H(A5),D0 ;GET PEN WIDTH
BLE DONE ;QUIT IF PENWIDTH <= 0
ADD.W D0,RIGHTEDGE(A6) ;ADD TO RIGHTEDGE.INT
MOVE PNSIZE+V(A5),D6 ;GET PEN HEIGHT
BLE DONE ;QUIT IF PEN HEIGHT <= 0
;----------------------------------------------------
;
; CALC FIXED POINT SLOPE = FixRatio(dh,dv);
;
CLR.L -(SP) ;MAKE ROOM FOR FCN RESULT
MOVE D4,-(SP) ;PUSH BOTTOM HORIZ
SUB D2,(SP) ;CALC DH
MOVE D3,-(SP) ;PUSH BOTTOM VERT
SUB D1,(SP) ;CALC DV
_FixRatio ;CALC FIXED POINT SLOPE DH/DV
MOVE.L (SP)+,D7 ;POP RESULT
MOVE.L D7,SLOPE(A6) ;SAVE FOR LATER
;
; CALC adjust := pen height * slope
;
CLR.L -(SP) ;PUSH ROOM FOR FCN RESULT
CLR.W -(SP) ;PUSH LOWORD = 0
MOVE.W D6,-(SP) ;PUSH HIWORD = PEN HEIGHT
MOVE.L D7,-(SP) ;PUSH SLOPE
_FixMul ;CALC FixMul(pnSize.v,slope)
MOVE.L (SP)+,D6 ;POP ANSWER INTO D6
;
; ADJUST LEFTEDGE AND RIGHTEDGE DEPENDING ON SIGN AND MAGNITUDE OF SLOPE
;
MOVE.L D7,D0 ;COPY SLOPE
ASR.L #1,D0 ;CALC SLOPE/2
ADD.L D0,LEFTEDGE(A6) ;ADD SLOPE/2 TO LEFT EDGE
ADD.L D0,RIGHTEDGE(A6) ;ADD SLOPE/2 TO RIGHT EDGE
TST.L D7 ;IS SLOPE NEGATIVE ?
BMI.S NEGSLOPE ;YES, CONTINUE
SUB.L D6,LEFTEDGE(A6) ;SUBTRACT ADJUST FROM LEFTEDGE
CMP.L #$00010000,D7 ;IS SLOPE < ONE ?
BGE.S LESSV1 ;NO, BRANCH
MOREV1 ADD.L D7,LEFTEDGE(A6) ;ADD SLOPE TO LEFTEDGE
BRA.S SLOPEOK ;CONTINUE
LESSV1 SUB.W #1,RIGHTEDGE(A6) ;RIGHTEDGE := RIGHTEDGE - 1
BRA.S SLOPEOK ;CONTINUE
;----------------------------------------------------
;
; SLOPE IS NEGATIVE
;
NEGSLOPE SUB.L D6,RIGHTEDGE(A6) ;SUBTRACT ADJUST FROM RIGHTEDGE
CMP.L #$FFFF0000,D7 ;IS SLOPE > -ONE ?
BLT.S LESSV2 ;NO, CONTINUE
MOREV2 ADD.L D7,RIGHTEDGE(A6) ;ADD SLOPE TO RIGHTEDGE
BRA.S SLOPEOK
LESSV2 ADD.W #1,LEFTEDGE(A6) ;LEFTEDGE := LEFTEDGE + 1
SLOPEOK MOVEM.W MINRECT(A6),D1/D2/D3/D4 ;GET MINRECT TOP,LEFT,BOTTOM,RIGHT
;
; ADJUST LEFTEDGE AND RIGHTEDGE IF LINE WAS CLIPPED VERTICALLY
;
CMP LINERECT+TOP(A6),D1 ;DID TOP GET CLIPPED ?
BEQ.S TOPOK ;NO, CONTINUE
MOVE D1,D0
SUB LINERECT+TOP(A6),D0 ;CALC DISCARD AMMOUNT
MOVE.L D7,D5 ;GET 32 BIT SLOPE
SWAP D5 ;GET HI WORD OF SLOPE
MULS D0,D5 ;MULT TIMES DISCARD
SWAP D5 ;PUT RESULT IN HI WORD
CLR.W D5 ;CLEAR LO WORD
MOVE.L D7,D6 ;GET NEW COPY OF SLOPE
MULU D0,D6 ;MULT LO WORD TIMES DISCARD
ADD.L D6,D5 ;CALC 32BIT SLOPE*DISCARD
ADD.L D5,LEFTEDGE(A6) ;BUMP LEFTEDGE TO NEW TOP
ADD.L D5,RIGHTEDGE(A6) ;BUMP RIGHTEDGE TO NEW TOP
TOPOK
;
; CALC BUFLEFT
;
MOVE MINRECT+LEFT(A6),D2 ;GET MINRECT LEFT
SUB PORTBITS+BOUNDS+LEFT(A5),D2 ;CONVERT TO GLOBAL COORDS
AND #$FFF0,D2 ;TRUNC TO MULT OF 16
ADD PORTBITS+BOUNDS+LEFT(A5),D2 ;CONVERT BACK TO GLOBAL
MOVE D2,BUFLEFT(A6) ;SAVE AS BUFLEFT
;
; IF FASTFLAG, THEN SKIP REGION SETUP
;
TST.B FASTFLAG(A6) ;RECT CLIPPED AND BLACK ?
BNE SKIPSETUP ;YES, DON'T WASTE TIME WITH SETUP
;
; CALC BUFSIZE
;
MOVE MINRECT+RIGHT(A6),D0 ;GET MINRECT RIGHT
SUB D2,D0 ;CALC MAXH-BUFLEFT
LSR #5,D0 ;DIV BY 32 FOR LONGS
MOVE D0,BUFSIZE(A6) ;BUFSIZE = # LONGS - 1
;
; ALLOCATE AND CLEAR A SCANLINE BUFFER FOR THE COMPOSITE MASK
;
CLRMASK CLR.L -(SP) ;ALLOCATE AND CLEAR ONE LONG
DBRA D0,CLRMASK ;LOOP TILL DONE
MOVE.L SP,MASKBUF(A6) ;REMEMBER WHERE MASKBUF IS
;-------------------------------------------------------------------------
;
; INIT STATE RECORDS AND ALLOCATE BUFFERS FOR EACH NON-RECTANGULAR REGION
;
CLR D5 ;INIT BOTH ARE RECT
MOVE #-32767,STATEA+THISV(A6) ;INIT HARMLESS STATE
MOVE #32767,STATEA+NEXTV(A6) ;IN CASE RECTANGULAR
CMP #10,RGNSIZE(A2) ;IS CLIPRGN RECTANGULAR ?
BEQ.S ARECT ;YES, CONTINUE
ADD #2,D5 ;NO, SET ITS FLAG
MOVE.L A2,A0 ;POINT TO CLIPRGN
LEA STATEA(A6),A1 ;POINT TO STATE RECORD A
BSR.S INITONE ;INIT STATE, ALLOC BUFFER
ARECT
MOVE #-32767,STATEB+THISV(A6) ;INIT HARMLESS STATE
MOVE #32767,STATEB+NEXTV(A6) ;IN CASE RECTANGULAR
CMP #10,RGNSIZE(A3) ;IS VISRGN RECTANGULAR ?
BEQ.S BRECT ;YES, CONTINUE
ADD #4,D5 ;NO, SET ITS FLAG
MOVE.L A3,A0 ;POINT TO VISRGN
LEA STATEB(A6),A1 ;POINT TO STATE RECORD B
PEA BRECT ;PUSH FAKE RETURN ADDR
INITONE MOVE MINRECT+LEFT(A6),D0 ;GET MINH
MOVE MINRECT+RIGHT(A6),D1 ;GET MAXH
MOVE BUFLEFT(A6),D2 ;GET BUFLEFT
JMP INITRGN ;INIT STATE, ALLOC BUFFER
BRECT
;--------------------------------------------------------------------
;
; IF BOTH REGIONS ARE RECTANGULAR, THEN DRAW MINRECT INTO MASK BUFFER
;
MOVE.W D5,RECTFLAG(A6) ;ARE BOTH RGNS RECT ?
BNE.S NOTRECT ;NO, CONTNUE
MOVE.L MASKBUF(A6),A0 ;YES, POINT TO MASK BUFFER
MOVE MINRECT+LEFT(A6),D3 ;SET UP LEFT
SUB BUFLEFT(A6),D3 ;MAKE IT BUFFER RELATIVE
MOVE MINRECT+RIGHT(A6),D4 ;SET UP RIGHT
SUB BUFLEFT(A6),D4 ;MAKE IT BUFFER RELATIVE
JSR XorSlab ;AND XOR BETWEEN THEM
NOTRECT
SKIPSETUP
;------------------------------------
;
; CALC STARTING DSTLEFT
;
MOVE MINRECT+TOP(A6),D1
SUB PORTBITS+BOUNDS+TOP(A5),D1 ;CONVERT MINV TO GLOBAL COORDS
MULU PORTBITS+ROWBYTES(A5),D1 ;MULT BY DST ROWBYTES
ADD.L PORTBITS+BASEADDR(A5),D1 ;ADD START OF BITMAP
SUB PORTBITS+BOUNDS+LEFT(A5),D2 ;CONVERT BUFLEFT TO GLOBAL
LSR #3,D2 ;CALC BUFLEFT DIV 8
EXT.L D2 ;CLR HI WORD
ADD.L D2,D1 ;ADD HORIZ BYTE OFFSET
MOVE.L D1,DSTLEFT(A6) ;SAVE AS DSTLEFT
;----------------------------------------------------
;
; MAKE LEFTEDGE,RIGHTEDGE,MINRECT RELATIVE TO BUFFER LEFT
;
MOVE BUFLEFT(A6),D1
SUB.W D1,LEFTEDGE(A6) ;ADJUST LEFTEDGE.INT
SUB.W D1,RIGHTEDGE(A6) ;ADJUST RIGHTEDGE.INT
SUB D1,MINRECT+LEFT(A6)
SUB D1,MINRECT+RIGHT(A6)
;------------------------------------------------------------
;
; TAKE FAST OR SLOW OUTER CONTROL LOOP FOR SLANTED LINES:
;
TST.B fastFlag(A6) ;ARE WE RECT CLIPPED BLACK ?
BEQ.S GOSLOW ;NO, CONTINUE
MOVE MODE(A6),D2 ;GET (ALTERED) PEN MODE
JSR FastSlabMode ;Get fast case jump in A4
LEA MaskTab,A0 ;point to mask table
LEA MINRECT(A6),A3 ;POINT TO MINRECT
MOVE.L SLOPE(A6),D7 ;GET FIXED POINT SLOPE
MOVE PORTBITS+ROWBYTES(A5),D6 ;GET DST ROWBYTES
MOVE.L DSTLEFT(A6),A5 ;GET DSTLEFT
MOVE MINRECT+BOTTOM(A6),D5 ;GET MINRECT BOTTOM
SUB MINRECT+TOP(A6),D5 ;CALC HEIGHT
SUB #1,D5 ;MINUS 1 FOR DBRA COUNT
NXTFAST MOVE.W LEFTEDGE(A6),D1 ;GET LEFTEDGE.INT
MOVE.W RIGHTEDGE(A6),D2 ;GET RIGHTEDGE.INT
MOVE.L A5,A1 ;INIT DSTPTR TO LEFT
JSR DrawSlab ;DRAW ONE SLAB IN PENMODE
ADD D6,A5 ;BUMP DST TO NEXT ROW
ADD.L D7,LEFTEDGE(A6) ;ADD SLOPE TO LEFT EDGE
ADD.L D7,RIGHTEDGE(A6) ;ADD SLOPE TO RIGHT EDGE
DBRA D5,NXTFAST ;LOOP FOR ALL SCANLINES
BRA DONE ;AND QUIT
GOSLOW MOVE MODE(A6),D2 ;GET (ALTERED) PEN MODE
JSR SlabMode ;GET DrawSlab CASE JUMP IN A4
;------------------------------------------------------------------
;
; EXPAND 8 BYTE PATTERN TO 16 LONGS AND INIT PATTERN SELECTOR
;
CLR.L D7 ;SAY NOT INVERTED
MOVE MODE(A6),D2 ;GET (ALTERED) PEN MODE
BCLR #2,D2 ;TEST AND CLR INVERT BIT
BEQ.S NOTINV ;SKIP IF NOT INVERTED
NOT.L D7 ;INVERTED; D7 GETS ALL 1'S
NOTINV MOVE PORTBITS+BOUNDS+LEFT(A5),D2 ;GET GLOBAL-LOCAL OFFSET
MOVE.L PAT(A6),A0 ;POINT TO BYTE WIDE PATTERN
LEA EXPAT(A6),A1 ;POINT TO EXPANDED PATTERN
MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
JSR PATEXPAND ;EXPAND 8 BYTES TO 16 LONGS
MOVE.L PORT(A6),A5 ;RESTORE GRAFPTR IN A5
MOVEQ #$F,D7 ;TREAT COORD MOD 16
AND MINRECT+TOP(A6),D7 ;GET TOP VERT LOCAL COORD
LSL #2,D7 ;QUAD FOR LONG INDEX
;
; FOR EACH SLAB, MAKE MASK BUFFER CURRENT AND DRAW SLAB
;
LEA MINRECT(A6),A3 ;POINT TO MINRECT
MOVE PORTBITS+ROWBYTES(A5),D5 ;GET DST ROWBYTES
MOVE.L DSTLEFT(A6),A5 ;GET DSTLEFT
MOVE.L SLOPE(A6),D4 ;GET FIXED POINT SLOPE
MOVE MINRECT+TOP(A6),VERT(A6) ;INIT CURRENT VERT:=MINV
NXTMASK BSR.S SEEKMASK ;MAKE MASK BUFFER CURRENT
MOVE.L EXPAT(A6,D7),D6 ;GET PATTERN DATA
MOVE.W LEFTEDGE(A6),D1 ;GET LEFTEDGE.INT
MOVE.W RIGHTEDGE(A6),D2 ;GET RIGHTEDGE.INT
LEA MaskTab,A0 ;point to mask table
MOVE.L A5,A1 ;INIT DSTPTR TO LEFT
MOVE.L MASKBUF(A6),A2 ;INIT MASKPTR TO LEFT
JSR DrawSlab ;DRAW ONE SLAB IN PENMODE
ADD #4,D7 ;BUMP PATTERN SELECTOR
AND #$3F,D7 ;MOD 64 FOR 16 LONG REPEAT
ADD D5,A5 ;BUMP DST TO NEXT ROW
ADD.L D4,LEFTEDGE(A6) ;ADD SLOPE TO LEFT EDGE
ADD.L D4,RIGHTEDGE(A6) ;ADD SLOPE TO RIGHT EDGE
ADD #1,VERT(A6) ;BUMP CURRENT VERT
MOVE VERT(A6),D0 ;GET CURRENT VERT
CMP MINRECT+BOTTOM(A6),D0 ;ARE WE AT BOTTOM YET ?
BLT NXTMASK ;NO, LOOP ALL SCAN LINES
DONE MOVE.L SAVEA5(A6),A5 ;GET GLOBAL PTR
JSR SHOWCURSOR ;RESTORE CURSOR
GOHOME MOVE.L SAVESTK(A6),SP ;STRIP BUFFER
MOVEM.L (SP)+,D0-D7/A1-A5 ;RESTORE REGISTERS
UNLINK PARAMSIZE,'DRAWLINE'
;-----------------------------------------------------------------------------
;
; LOCAL ROUTINE TO UPDATE THE MASK BUFFER
; BASED ON WHICH REGIONS ARE RECTANGULAR
;
SEEKMASK MOVE VERT(A6),D0 ;GET CURRENT VERT COORD
MOVE RECTFLAG(A6),D1 ;GET RECTFLAG = 0,2,4
MOVE RECTJMP(D1),D1 ;GET OFFSET FROM TABLE
JMP RECTJMP(D1) ;TAKE CASE JUMP
RECTJMP .WORD IGNORE-RECTJMP ;DO NOTHING IF BOTH RECT
.WORD A-RECTJMP
.WORD B-RECTJMP
.WORD AB-RECTJMP
;--------------------------------------------------------------------
;
; ONLY REGION A IS NON RECTANGULAR. UPDATE IT AND USE IT AS THE MASK
;
A LEA STATEA(A6),A1
JSRSEEK JSR SEEKRGN
MOVE.L SCANBUF(A1),MASKBUF(A6)
IGNORE RTS
;--------------------------------------------------------------------
;
; ONLY REGION B IS NON RECTANGULAR. UPDATE IT AND USE IT AS THE MASK
;
B LEA STATEB(A6),A1
BRA.S JSRSEEK
;-------------------------------------------------------------------
;
; REGIONS A AND B ARE NON-RECTANGULAR. UPDATE EACH,
; THEN FORM INTERSECTION IN THE MASK BUFFER.
;
AB LEA STATEA(A6),A1
JSR SEEKRGN
LEA STATEB(A6),A1
JSR SEEKRGN
MOVE.L STATEA+SCANBUF(A6),A0
MOVE.L STATEB+SCANBUF(A6),A1
MOVE.L MASKBUF(A6),A2
MOVE BUFSIZE(A6),D1
ABLOOP MOVE.L (A0)+,D0
AND.L (A1)+,D0
MOVE.L D0,(A2)+
DBRA D1,ABLOOP
RTS
;-------------------------------------------------------
;
; SET UP AND DRAW A FAST HORIZONTAL OR VERTICAL LINE.
;
FASTLINE CMP D1,D3 ;IS LINE HORIZONTAL ?
BNE VLINE ;NO, MUST BE VERTICAL
BSR HVSETUP ;GET DSTPTR,ROWBYTES,HGLOBAL
MOVE 32(A0,D0),D6 ;GET LEFTMASK IN D6
MOVE MINRECT+RIGHT(A6),D2 ;GET MINRECT RIGHT
SUB PORTBITS+BOUNDS+LEFT(A5),D2 ;CONVERT TO GLOBAL
MOVE D2,D0 ;MAKE A COPY OF RIGHT
AND #$F,D0 ;TREAT RIGHT MOD 16
ADD D0,D0 ;DOUBLE FOR TABLE
MOVE 0(A0,D0),D3 ;GET RIGHTMASK IN D3
LSR #4,D2 ;CONVERT DOTS TO WORDS
CMP #1,MODE(A6) ;WHICH MODIFIED MODE ?
BLT.S HSET ;BR IF BLACK
BEQ.S HTOGL ;BR IF XOR
;ELSE WHITE
;------------------------------------------------------
;
; DRAW A WHITE HORIZONTAL LINE
;
NOT D6 ;MAKE NOT LEFTMASK
NOT D3 ;MAKE NOT RIGHTMASK
SUB D1,D2 ;CALC WORDCOUNT
BEQ.S ENDCLR ;BR IF ALL IN ONE WORD
AND D6,(A4)+ ;DO LEFT WORD WITH MASK
CLR.L D6 ;FLUSH LEFTMASK FOR END
SUB #1,D2 ;DEC WORD COUNT
BEQ.S ENDCLR ;BR IF NO UNMASKED WORDS
LSR #1,D2 ;HALVE WORDCOUNT FOR LONGCOUNT
BCC.S CLRONE ;BR IF EVEN # WORDS LEFT
MOVE D6,(A4)+ ;ELSE MAKE EVEN BY DOING A WORD
SUB #1,D2 ;ADJUST LONGCOUNT
BRA.S CLRMORE ;SEE IF ANY LONGS LEFT TO DO
CLRTWO MOVE.L D6,(A4)+ ;FILL A LONG WITH BLACK
CLRONE MOVE.L D6,(A4)+ ;FILL ANOTHER LONG
SUB #2,D2 ;ANY UNMASKED LONGS LEFT ?
CLRMORE BGT CLRTWO ;YES, AT LEAST TWO LONGS
BEQ CLRONE ;YES, FINISH UP LAST LONG
ENDCLR OR D3,D6 ;COMBINE LEFT AND RIGHT MASK
AND D6,(A4) ;DRAW LINE
BRA.S DONE ;RESTORE CURSOR AND QUIT
;--------------------------------------------------
;
; DRAW AN XOR HORIZONTAL LINE
;
HTOGL SUB D1,D2 ;CALC WORDCOUNT
BEQ.S ENDTOGL ;BR IF ALL IN ONE WORD
EOR D6,(A4)+ ;DO LEFT WORD WITH MASK
MOVEQ #-1,D6 ;FLUSH LEFTMASK FOR END
SUB #1,D2 ;DEC WORD COUNT
BEQ.S ENDTOGL ;BR IF NO UNMASKED WORDS
LSR #1,D2 ;HALVE WORDCOUNT FOR LONGCOUNT
BCC.S TOGLONE ;BR IF EVEN # WORDS LEFT
EOR D6,(A4)+ ;ELSE MAKE EVEN BY DOING A WORD
SUB #1,D2 ;ADJUST LONGCOUNT
BRA.S TOGLMORE ;SEE IF ANY LONGS LEFT TO DO
TOGLTWO NOT.L (A4)+ ;INVERT A LONG
TOGLONE NOT.L (A4)+ ;INVERT ANOTHER LONG
SUB #2,D2 ;ANY UNMASKED LONGS LEFT ?
TOGLMORE BGT TOGLTWO ;YES, AT LEAST TWO LONGS
BEQ TOGLONE ;YES, FINISH UP LAST LONG
ENDTOGL AND D3,D6 ;COMBINE LEFT AND RIGHT MASK
EOR D6,(A4) ;DRAW LINE
BRA.S DONE ;RESTORE CURSOR AND QUIT
;--------------------------------------------
;
; DRAW A BLACK HORIZONTAL LINE
;
HSET SUB D1,D2 ;CALC WORDCOUNT
BEQ.S ENDSET ;BR IF ALL IN ONE WORD
OR D6,(A4)+ ;DO LEFT WORD WITH MASK
MOVEQ #-1,D6 ;FLUSH LEFTMASK FOR END
SUB #1,D2 ;DEC WORD COUNT
BEQ.S ENDSET ;BR IF NO UNMASKED WORDS
LSR #1,D2 ;HALVE WORDCOUNT FOR LONGCOUNT
BCC.S SETONE ;BR IF EVEN # WORDS LEFT
MOVE D6,(A4)+ ;ELSE MAKE EVEN BY DOING A WORD
SUB #1,D2 ;ADJUST LONGCOUNT
BRA.S SETMORE ;SEE IF ANY LONGS LEFT TO DO
SETTWO MOVE.L D6,(A4)+ ;FILL A LONG WITH BLACK
SETONE MOVE.L D6,(A4)+ ;FILL ANOTHER LONG
SUB #2,D2 ;ANY UNMASKED LONGS LEFT ?
SETMORE BGT SETTWO ;YES, AT LEAST TWO LONGS
BEQ SETONE ;YES, FINISH UP LAST LONG
ENDSET AND D3,D6 ;COMBINE LEFT AND RIGHT MASK
OR D6,(A4) ;DRAW LINE
BRA.S DONE ;RESTORE CURSOR AND QUIT
;-------------------------------------------------------
;
; DRAW A VERTICAL LINE.
;
VLINE BSR.S HVSETUP ;GET DSTPTR,ROWBYTES,HGLOBAL
MOVE 64(A0,D0),D0 ;GET BITMASK IN D0
MOVE MINRECT+BOTTOM(A6),D1 ;GET BOTTOM
SUB MINRECT+TOP(A6),D1 ;CALC HEIGHT
SUB #1,D1 ;INIT HEIGHT COUNT
CMP #1,MODE(A6) ;WHICH MODIFIED MODE ?
BLT.S VSET ;BR IF BLACK
BEQ.S VTOGL ;BR IF XOR
;ELSE WHITE
NOT D0 ;MAKE NOTMASK
VCLR AND D0,(A4) ;CLEAR ONE DOT
ADD D7,A4 ;BUMP TO NEXT ROW
DBRA D1,VCLR ;LOOP ALL DOTS
BRA.S DONE ;RESTORE CURSOR AND QUIT
VTOGL EOR D0,(A4) ;TOGGLE ONE DOT
ADD D7,A4 ;BUMP TO NEXT ROW
DBRA D1,VTOGL ;LOOP ALL DOTS
BRA.S DONE ;RESTORE CURSOR AND QUIT
VSET OR D0,(A4) ;SET ONE DOT
ADD D7,A4 ;BUMP TO NEXT ROW
DBRA D1,VSET ;LOOP ALL DOTS
BRA.S DONE ;RESTORE CURSOR AND QUIT
;------------------------------------------------------------------------
;
; LOCAL ROUTINE TO SET UP POINTER TO FIRST WORD, BIT INDEX, AND ROWBYTES
;
; INPUTS: MINRECT
; A5: thePort
;
; OUTPUTS: D0: STARTING HORIZ GLOBAL COORDS
; D1: STARTING HORIZ GLOBAL DIV 16
; D7: ROWBYTES
; A0: MaskTab
; A4: POINTER TO FIRST WORD
;
; CLOBBERS: D0,D1,D7,A0,A4
;
HVSETUP MOVE.L PORTBITS+BASEADDR(A5),A4 ;GET BITMAP START
MOVE MINRECT+TOP(A6),D0 ;GET STARTING VERT
SUB PORTBITS+BOUNDS+TOP(A5),D0 ;CONVERT TO GLOBAL
MOVE PORTBITS+ROWBYTES(A5),D7 ;GET ROWBYTES
MULU D7,D0 ;MULT TOP BY ROWBYTES
ADD.L D0,A4 ;ADD TO BASEADDR
MOVE MINRECT+LEFT(A6),D0 ;GET STARTING HORIZ
SUB PORTBITS+BOUNDS+LEFT(A5),D0 ;CONVERT TO GLOBAL
MOVE D0,D1 ;MAKE A COPY
LSR #4,D1 ;CONVERT BITS TO WORDS
ADD D1,A4 ;ADD TO RUNNING TOTAL
ADD D1,A4 ;TWICE FOR BYTES
LEA MaskTab,A0 ;return with masktab in A0
AND #$F,D0 ;TREAT LEFT MOD 16
ADD D0,D0 ;DOUBLE FOR TABLE
RTS
.END