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
/
BitBlt.a
796 lines (691 loc) · 35.5 KB
/
BitBlt.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
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
.INCLUDE GRAFTYPES.TEXT
;---------------------------------------------------------------
;
; --> BITBLT.TEXT
;
; Low-level bit boundary block transfer.
;
.PROC BITBLT,7
.REF LEFTMASK,RIGHTMASK,PATEXPAND
;--------------------------------------------------------------
;
; PROCEDURE BitBlt(srcBits,dstBits: BitMap;
; srcRect,dstRect: Rect;
; mode: INTEGER; pat: Pattern);
;
; TRANSFERS A RECTANGULAR BLOCK OF BITS WITH NO CLIPPING AT ALL.
; MODE SPECIFIES THE COMBINATION MODE AND WHETHER THE SOURCE SHOULD COME
; FROM THE SOURCE BITMAP OR FROM A REPEATING PATTERN.
;
; COPYRIGHT APPLE COMPUTER INC.
; WRITTEN BY BILL ATKINSON
;
; POSITION INDEPENDENT AND RE-ENTRANT, CLOBBERS ONLY A0.
;
; MODES: 0 SRC --> DST
; 1 SRC OR DST --> DST
; 2 SRC XOR DST --> DST
; 3 SRC BIC DST --> DST
;
; 4 (NOT SRC) --> DST
; 5 (NOT SRC) OR DST --> DST
; 6 (NOT SRC) XOR DST --> DST
; 7 (NOT SRC) BIC DST --> DST
;
; 8 PATTERN --> DST
; 9 PATTERN OR DST --> DST
; 10 PATTERN XOR DST --> DST
; 11 PATTERN BIC DST --> DST
;
; 12 (NOT PATTERN) --> DST
; 13 (NOT PATTERN) OR DST --> DST
; 14 (NOT PATTERN) XOR DST --> DST
; 15 (NOT PATTERN) BIC DST --> DST
;
;
;----------------------------------------------------
;
; A6 OFFSETS OF PARAMETERS AFTER LINK:
;
PARAMSIZE .EQU 22 ;SIZE OF PARAMETERS
SRCBITS .EQU PARAMSIZE+8-4 ;LONG, ADDR OF BITMAP
DSTBITS .EQU SRCBITS-4 ;LONG, ADDR OF BITMAP
SRCRECT .EQU DSTBITS-4 ;LONG, ADDR OF RECT
DSTRECT .EQU SRCRECT-4 ;LONG, ADDR OF RECT
MODE .EQU DSTRECT-2 ;WORD
PAT .EQU MODE-4 ;LONG, ADDR OF PATTERN
;----------------------------------------------------
;
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
;
EXPAT .EQU -64 ;16 LONGS
SRCV .EQU EXPAT-2 ;WORD
DSTV .EQU SRCV-2 ;WORD
SRCROW .EQU DSTV-2 ;WORD
DSTROW .EQU SRCROW-2 ;WORD
srcBump .EQU DSTROW-2 ;WORD
HEIGHT .EQU srcBump-2 ;WORD
WORDCNT .EQU HEIGHT-2 ;WORD
SAVEA5 .EQU WORDCNT-4 ;LONG
VARSIZE .EQU SAVEA5 ;SIZE OF LOCAL VARIABLES
;-------------------------------------------------------------------
;
; ENTER HERE. CALLER TAKES CARE OF CURSOR.
;
LINK A6,#VARSIZE ;ALLOCATE LOCAL VARIABLES
MOVEM.L D3-D7/A2-A5,-(SP) ;SAVE REGS
MOVE.L A5,SAVEA5(A6) ;SAVE GLOBAL POINTER
;----------------------------------------------------------------------
;
; GET PARAMETER POINTERS IN REGISTERS
;
MOVE.L SRCRECT(A6),A2 ;A2 POINTS TO SRCRECT
MOVE.L DSTRECT(A6),A3 ;A3 POINTS TO DSTRECT
MOVE.L SRCBITS(A6),A4 ;A4 POINTS TO SRCBITS
MOVE.L DSTBITS(A6),A5 ;A5 POINTS TO DSTBITS
;-------------------------------------------------------------
;
; CALC HEIGHT OF DSTRECT. QUIT IF HEIGHT <= 0
;
MOVE BOTTOM(A3),D0 ;GET BOTTOM
SUB TOP(A3),D0 ;CALC HEIGHT
BLE GOHOME ;QUIT IF HEIGHT <= 0
MOVE D0,HEIGHT(A6) ;SAVE FOR LATER
;--------------------------------------------------------------
;
; SET UP FOR TOP TO BOTTOM, LEFT TO RIGHT
; GET SRC AND DST TOP AND ROWBYTES
;
MOVEQ #2,D3 ;BUMP:=2 (TRANSFER LEFT TO RIGHT)
MOVE TOP(A2),D0 ;GET SRC TOP
SUB BOUNDS+TOP(A4),D0 ;CONVERT SRC TOP TO GLOBAL
MOVE D0,SRCV(A6) ;SAVE FOR LATER
MOVE TOP(A3),D0 ;GET DST TOP
SUB BOUNDS+TOP(A5),D0 ;CONVERT DST TOP TO GLOBAL
MOVE D0,DSTV(A6) ;SAVE FOR LATER
MOVE ROWBYTES(A4),SRCROW(A6) ;SRCROW:=SRCBITS.ROWBYTES
MOVE ROWBYTES(A5),DSTROW(A6) ;DSTROW:=DSTBITS.ROWBYTES
;--------------------------------------------------------------------
;
; SET UP INVERT FLAG, IN CASE SRC OR PATTERN WILL BE INVERTED
;
CLR D7 ;SAY NOT INVERTED
MOVE MODE(A6),D0 ;GET TRANSFER MODE
BTST #2,D0 ;IS MODE AN INV. ONE ?
BEQ.S MODEOK ;NOT INVERTED, CONTINUE
NOT D7 ;INVERTED, PUT -1 IN INVERT REG
MODEOK BTST #3,D0 ;WILL WE USE PATTERN ?
BEQ.S DIREC ;NO, DON'T BOTHER TO SET UP
;------------------------------------------------------------
;
; PATTERN WILL BE USED. EXPAND 8 BYTE PATTERN TO 16 LONGS.
;
MOVE 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 POINTER
JSR PATEXPAND ;EXPAND 8 BYTES TO 16 LONGS
MOVE.L DSTBITS(A6),A5 ;RESTORE A5 TO DSTBITS
;------------------------------------------------------------
;
; SET UP (VERT * 4) MOD 64 AS PATTERN SELECTOR
;
MOVEQ #$F,D7 ;TREAT COORD MOD 16
AND TOP(A3),D7 ;GET DST TOP LOCAL COORD
LSL #2,D7 ;QUAD FOR LONG PATTERNS
MOVE.L EXPAT(A6,D7),D6 ;GET FIRST PATTERN DATA
BRA.S NOTSRC ;NOT USING SRC, SKIP OVER
;-----------------------------------------------------------
;
; SOURCE WILL BE USED, SO SET UP VERT AND HORIZ DIRECTIONS
; SUCH THAT SRC WON'T GET CLOBBERED TILL AFTER IT HAS BEEN USED
;
DIREC MOVE.L BASEADDR(A4),D0 ;GET SRC BASEADDR
CMP.L BASEADDR(A5),D0 ;ARE SRC AND DST ARRAYS THE SAME ?
BNE.S GETSRC ;NO, DONT WORRY ABOUT OVERLAP
MOVE SRCV(A6),D0 ;GET SRCV
CMP DSTV(A6),D0 ;IS SRCV > DSTV ?
BGT.S GETSRC ;YES, CONTINUE WITH TOP TO BOTTOM
BLT.S UPSIDE ;NO, DO UPSIDE DOWN
MOVE LEFT(A2),D0 ;SAME VERT, CHOOSE HORIZ DIRECTION
SUB BOUNDS+LEFT(A4),D0 ;CONVERT SRC LEFT TO GLOBAL
MOVE LEFT(A3),D1 ;GET DST LEFT
SUB BOUNDS+LEFT(A5),D1 ;CONVERT TO GLOBAL
CMP D1,D0 ;IS SRCLEFT < DSTLEFT ?
BGE.S GETSRC ;NO, DO LEFT TO RIGHT
NEG D3 ;YES, BUMP:=-2 (RIGHT TO LEFT)
BRA.S GETSRC ;CONTINUE
;----------------------------------------------------------
;
; DO UPSIDE DOWN TO AVOID CLOBBERING SRC
;
UPSIDE MOVE HEIGHT(A6),D0 ;GET HEIGHT
SUB #1,D0 ;CALC HEIGHT-1
ADD D0,SRCV(A6) ;SRCVERT:=SRCV+HEIGHT-1
ADD D0,DSTV(A6) ;DSTVERT:=DSTV+HEIGHT-1
NEG SRCROW(A6) ;SRCROW:=-SRCROW
NEG DSTROW(A6) ;DSTROW:=-DSTROW
;-----------------------------------------------------
;
; SET UP SHIFTCNT IN D6 (RELATIVE SHIFT BETWEEN SRC & DST)
;
GETSRC MOVE LEFT(A3),D6 ;GET DST LEFT
SUB BOUNDS+LEFT(A5),D6 ;CONVERT TO GLOBAL
MOVE LEFT(A2),D1 ;GET SRC LEFT
SUB BOUNDS+LEFT(A4),D1 ;CONVERT TO GLOBAL
SUB D1,D6 ;CALC DELTA HORIZ
AND #$F,D6 ;SHIFTCNT:=DELTA HORIZ MOD 16
;------------------------------------------------------------
;
; SET UP SRCLEFT IN A4, ADDR OF LEFTMOST SRC WORD
; (GOODBYE SRCBITS PTR)
;
MOVE SRCV(A6),D0 ;GET FIRST SRC VERT
MULU ROWBYTES(A4),D0 ;CALC SRC ROWBYTES * FIRST SRC VERT
MOVE.L BASEADDR(A4),A4 ;GET START OF SRC BITMAP
ADD.L D0,A4 ;ADD TO BITMAP START
ADD D6,D1 ;CALC SRCH+SHIFTCNT
ASR #3,D1 ;CONVERT BITS TO BYTE OFFSET
AND #$FFFE,D1 ;TRUNC TO WORD BOUNDARY
ADD D1,A4 ;LEAVE SRCLEFT IN A4
;------------------------------------------------------------
;
; SET UP DSTLEFT IN A5, ADDR OF LEFTMOST DST WORD
; (GOODBYE DSTBITS PTR)
;
NOTSRC MOVE LEFT(A3),D1 ;GET DST LEFT
SUB BOUNDS+LEFT(A5),D1 ;CONVERT TO GLOBAL
MOVE DSTV(A6),D0 ;GET FIRST DST VERT
MULU ROWBYTES(A5),D0 ;CALC DSTROW * FIRST DST VERT
MOVE.L BASEADDR(A5),A5 ;GET START OF DST BITMAP
ADD.L D0,A5 ;ADD DSTV*DSTROW
MOVE D1,D0 ;COPY DSTLEFT GLOBAL
ASR #4,D1 ;CONVERT FROM DOTS TO WORDS
ADD D1,D1 ;DOUBLE FOR BYTES
ADD D1,A5 ;LEAVE DSTLEFT IN A5
;-------------------------------------
;
; SET UP LEFTMASK IN D4
; (GOODBYE SRCRECT PTR)
;
MOVE D0,D1 ;SAVE DSTH
JSR LEFTMASK ;GET LEFTMASK
MOVE D0,D4 ;PUT IN D4
;-------------------------------------
;
; SET UP RIGHTMASK IN D5
; (GOODBYE DSTRECT PTR)
;
AND #$F,D1 ;TREAT DSTH MOD 16
MOVE RIGHT(A3),D0 ;GET DST RIGHT
SUB LEFT(A3),D0 ;CALC WIDTH
BLE GOHOME ;QUIT IF WIDTH <= 0
ADD D1,D0 ;CALC (DSTH MOD 16) + WIDTH
MOVE D0,D1 ;MAKE AN EXTRA COPY
JSR RIGHTMASK ;GET RIGHT MASK
MOVE D0,D5 ;SAVE RIGHTMASK IN D5
;------------------------------------------------
;
; CALC TOTAL NUMBER OF DST WORDS-1
;
ASR #4,D1 ;CALC ((DSTH MOD 16)+WIDTH) DIV 16
MOVE D1,WORDCNT(A6) ;SAVE AS WORDCNT
MOVE D1,D2 ;set up for below
;
; Set up srcBump and dstBump, assuming bumping to the right
;
ADD D1,D1 ;calc 2*wordCount
MOVE D1,D0 ;make a copy
ADD #2,D0 ;adjust for total bytesNeeded
;--------------------------------------------------------------------------
;
; IF DRAWING BACKWARDS FROM RIGHT, then adjust dstBump,
; ADJUST SRCADDR,DSTADDR TO FIRST WORD,
; AND SWAP LEFT AND RIGHT MASKS FOR FIRSTMASK AND LASTMASK.
;
MOVE D3,A0 ;put hBump (+-2) into A0
TST D3 ;ARE WE STARTING ON THE LEFT ?
BPL.S DIROK ;YES, CONTINUE
NEG D0 ;calc -1 * bytesNeeded
ADD D1,A5 ;ADJUST DSTADDR TO RIGHTMOST
ADD D1,A4 ;ADJUST SRCADDR TO RIGHTMOST
EXG D4,D5 ;FIRSTMASK=RIGHT,LASTMASK=LEFT
DIROK MOVE srcRow(A6),srcBump(A6)
SUB D0,srcBump(A6) ;srcBump := srcRow +- bytesBumped
MOVE dstRow(A6),A3
SUB D0,A3 ;dstBump := dstRow +- bytesBumped
;----------------------------------------------
;
; SET UP MODE CASE JUMP IN A1
;
GETMODE MOVE MODE(A6),D0 ;GET TRANSFER MODE
BNE.S NOTFAST ;BR IF NOT MODE 0
TST D6 ;IS SHIFTCNT 0 ?
BNE.S NOTFAST ;NO, CONTINUE
TST WORDCNT(A6) ;IS WORDCNT > 0 ?
BLE.S NOTFAST ;NO, CONTINUE
LEA SETUP0,A1 ;USE FAST COPY.
TST D3 ;ARE WE BUMPING LEFT TO RIGHT ?
BPL.S NEXTROW ;YES, ALL SET
LEA LEFT0,A1 ;NO, USE BACKWARDS LOOP
BRA.S NEXTROW
NOTFAST AND #$B,D0 ;TREAT MODE MOD 16 AND KILL INVERT BIT
MOVE D0,D1 ;MAKE A COPY
AND #3,D0 ;MASK FOR LOW BITS ONLY
ADD D0,D1 ;MAKE MODIFIED MODE * 2 FOR INDEX
TST D2 ;IS DST ALL IN ONE WORD ?
BNE.S DOMAIN ;NO, USE FIRST JUMP TABLE
ADD #16,D1 ;YES, USE SECOND JUMP TABLE
DOMAIN LEA MODETAB,A1 ;GET ADDRESS OF MODE TABLE
ADD 0(A1,D1),A1 ;POINT TO THIS MODE'S ROW LOOP
;---------------------------------------------------------
;
; OUTER LOOP: DO EACH SCAN LINE AND COME BACK TO NXTSRC OR NXTPAT.
; SOME MODES OPTIMIZE AND DO WHOLE OUTER LOOP AND COME BACK TO GOHOME.
;
NEXTROW MOVE HEIGHT(A6),D3 ;get height
SUB #1,D3 ;init DBRA rowcount
ROWLOOP MOVE D4,D1 ;MASK:=FIRSTMASK
MOVE WORDCNT(A6),D2 ;GET WORDCOUNT
JMP (A1) ;DO THIS ROW AND COME BACK
NXTSRC ADD srcBump(A6),A4 ;bump srcPtr to next row
ADD A3,A5 ;BUMP DSTADDR TO NEXT ROW
DBRA D3,ROWLOOP ;loop for all srcRows
BRA.S GOHOME ;then quit
NXTPAT ADD #4,D7 ;BUMP PATTERN SELECTOR
AND #$3F,D7 ;MOD 64 FOR 16 LONG REPEAT
MOVE.L EXPAT(A6,D7),D6 ;GET PATTERN DATA FOR NEXT ROW
ADD A3,A5 ;BUMP DSTADDR TO NEXT ROW
DBRA D3,ROWLOOP ;loop for all srcRows
;then quit
GOHOME MOVEM.L (SP)+,D3-D7/A2-A5 ;RESTORE REGS
UNLINK PARAMSIZE,'BITBLT '
;---------------------------------------------------------------;
; ;
; INTERFACE TO EACH BITBLT SCANLINE LOOP: ;
; ;
; REGISTERS: A0: hBump (+-2) D0: scratch ;
; A1: MODE CASE JUMP D1: FIRSTMASK ;
; A2: used for loop jmp D2: WORDCNT ;
; A3: dstBump D3: height-1 ;
; A4: SRCPTR D4: FIRSTMASK ;
; A5: DSTPTR D5: LASTMASK ;
; A6: LOCALS D6: SHIFTCNT OR PATTERN ;
; A7: STACK PTR D7: INVERT OR PAT-SEL ;
; ;
;---------------------------------------------------------------;
MODETAB .WORD MAIN0-MODETAB ;JUMP TABLE USED IF DST WIDER THAN ONE WORD
.WORD MAIN1-MODETAB
.WORD MAIN2-MODETAB
.WORD MAIN3-MODETAB
.WORD SETUP8-MODETAB
.WORD MAIN9-MODETAB
.WORD SETUP10-MODETAB
.WORD MAIN11-MODETAB
.WORD END0-MODETAB ;JUMP TABLE USED IF DST FITS IN ONE WORD WIDE
.WORD END1-MODETAB
.WORD END2-MODETAB
.WORD END3-MODETAB
.WORD WORD8-MODETAB
.WORD END9-MODETAB
.WORD END10-MODETAB
.WORD END11-MODETAB
;------------------------------------------------------------
;
; OPTIMIZE RIGHT HORIZONTAL SCROLL IF NO SHIFT.
; ONLY IF MODE 0, BUMPING RIGHT TO LEFT, WORDCNT > 0, AND NO SHIFT.
;
LEFT0 MOVE (A4),D0 ;GET SRC FROM BITMAP
ADD A0,A4 ;BUMP LEFT
AND D1,D0 ;MASK FIRST WORD
NOT D1 ;MAKE NOTMASK
AND (A5),D1 ;GET DATA FROM DST
OR D1,D0 ;MERGE WITH SRC DATA
MOVE D0,(A5) ;PUT RESULT TO DST
ADD A0,A5 ;BUMP LEFT
MOVEQ #-1,D1 ;FLUSH MASK FOR END0
SUB #1,D2 ;DEC WORD COUNT
BEQ.S END0 ;BR IF NO UNMASKED WORDS
SUB A0,A4 ;GET READY FOR PRE-DECREMENT
SUB A0,A5 ;GET READY FOR PRE-DECREMENT
LSR #1,D2 ;HALVE WORDCOUNT FOR LONGCOUNT
BCC.S LONE0 ;BR IF EVEN # WORDS LEFT
MOVE -(A4),-(A5) ;ELSE MAKE EVEN BY DOING A WORD
SUB #1,D2 ;ADJUST LONGCOUNT
BRA.S LMORE0 ;SEE IF ANY LONGS LEFT TO DO
LTWO0 MOVE.L -(A4),-(A5) ;MOVE A LONG WORD
LONE0 MOVE.L -(A4),-(A5) ;MOVE ANOTHER LONG
SUB #2,D2 ;ANY UNMASKED LONGS LEFT IN ROW ?
LMORE0 BGT LTWO0 ;YES, AT LEAST 2 LONGS LEFT
BEQ LONE0 ;YES, FINISH UP LAST LONG
ADD A0,A4 ;RETURN TO NORMAL AFTER PRE-DECREMENT
ADD A0,A5 ;RETURN TO NORMAL AFTER PRE-DECREMENT
BRA.S END0 ;DO LAST WORD WITH MASK
;------------------------------------------------------------
;
; OPTIMIZE VERTICAL AND LEFT HORIZONTAL SCROLL IF SHIFT = 0.
; ONLY IF MODE 0, BUMPING LEFT TO RIGHT, WORDCNT > 0, AND NO SHIFT.
;
SETUP0 LEA FAST0,A1 ;only do setup once
LEA COPYBIG,A2 ;point to big copy
BRA CALCLP ;share loop calc
FAST0 MOVE (A4)+,D0 ;GET SRC FROM BITMAP
AND D1,D0 ;MASK FIRST WORD
NOT D1 ;MAKE NOTMASK
AND (A5),D1 ;GET DST DATA
OR D1,D0 ;MERGE WITH SRC DATA
MOVE D0,(A5)+ ;PUT RESULT TO DST
MOVEQ #-1,D1 ;FLUSH MASK FOR END0
SUB #1,D2 ;DEC WORD COUNT
BEQ.S END0 ;BR IF NO UNMASKED WORDS
JSR (A2) ;call unwound copy loop
MOVEQ #-1,D2 ;force finish up below
;-------------------------------------------------------
;
; MODE 0 OR 4: SRC --> DST
;
END0 AND D5,D1 ;MASK:=MASK AND LASTMASK
MAIN0 MOVE.L -2(A4),D0 ;GET SRC FROM BITMAP
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
LSR.L D6,D0 ;ALIGN TO DST
EOR D7,D0 ;INVERT SRC IF MODE BIT 2 SET
AND D1,D0 ;MASK SRC
NOT D1 ;FORM NOTMASK
AND (A5),D1 ;GET DST DATA
OR D1,D0 ;MERGE WITH SRC DATA
MOVE D0,(A5) ;PUT RESULT TO DST
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
MOVEQ #-1,D1 ;FLUSH MASK
SUB #1,D2 ;DEC WORD COUNT
BGT MAIN0 ;BR IF UNMASKED WORDS LEFT
BEQ END0 ;DO LAST WORD WITH LASTMASK
BRA NXTSRC ;LOOP BACK FOR MORE
;----------------------------------------------------------
;
; Call copybig with wordcount in D2 (clobbered)
;
COPYBIG BCLR #0,D2 ;is wordcount even ?
BEQ.S @1 ;yes, continue
MOVE.W (A4)+,(A5)+ ;no, make it even
@1 SUB #32,D2 ;calc wordcount-32
BLE.S @2 ;continue if wordcount <= 32
BSR.S COPY32 ;else copy 32 words
BRA.S @1 ;and loop for more
@2 NEG D2 ;calc 32-wordcount
JMP COPY32(D2) ;jump into loop
COPY32 MOVE.L (A4)+,(A5)+ ;TABLE TO COPY 0..32 WORDS
MOVE.L (A4)+,(A5)+ ;wordCount = 30
MOVE.L (A4)+,(A5)+ ;wordCount = 28
MOVE.L (A4)+,(A5)+ ;wordCount = 26
MOVE.L (A4)+,(A5)+ ;wordCount = 24
MOVE.L (A4)+,(A5)+ ;wordCount = 22
MOVE.L (A4)+,(A5)+ ;wordCount = 20
MOVE.L (A4)+,(A5)+ ;wordCount = 18
MOVE.L (A4)+,(A5)+ ;wordCount = 16
MOVE.L (A4)+,(A5)+ ;wordCount = 14
MOVE.L (A4)+,(A5)+ ;wordCount = 12
MOVE.L (A4)+,(A5)+ ;wordCount = 10
MOVE.L (A4)+,(A5)+ ;wordCount = 8
MOVE.L (A4)+,(A5)+ ;wordCount = 6
MOVE.L (A4)+,(A5)+ ;wordCount = 4
MOVE.L (A4)+,(A5)+ ;wordCount = 2
COPY0 RTS ;wordCount = 0
COPY31 MOVE.L (A4)+,(A5)+ ;TABLE TO COPY 1..31 WORDS
MOVE.L (A4)+,(A5)+ ;wordCount = 29
MOVE.L (A4)+,(A5)+ ;wordCount = 27
MOVE.L (A4)+,(A5)+ ;wordCount = 25
MOVE.L (A4)+,(A5)+ ;wordCount = 23
MOVE.L (A4)+,(A5)+ ;wordCount = 21
MOVE.L (A4)+,(A5)+ ;wordCount = 19
MOVE.L (A4)+,(A5)+ ;wordCount = 17
MOVE.L (A4)+,(A5)+ ;wordCount = 15
MOVE.L (A4)+,(A5)+ ;wordCount = 13
MOVE.L (A4)+,(A5)+ ;wordCount = 11
MOVE.L (A4)+,(A5)+ ;wordCount = 9
MOVE.L (A4)+,(A5)+ ;wordCount = 7
MOVE.L (A4)+,(A5)+ ;wordCount = 5
MOVE.L (A4)+,(A5)+ ;wordCount = 3
COPY1 MOVE.W (A4)+,(A5)+ ;wordCount = 1
RTS
;-------------------------------------------------------
;
; MODE 1 OR 5: SRC OR DST --> DST
;
END1 AND D5,D1 ;MASK:=MASK AND LASTMASK
MAIN1 MOVE.L -2(A4),D0 ;GET SRC FROM BITMAP
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
LSR.L D6,D0 ;ALIGN TO DST
EOR D7,D0 ;INVERT SRC IF MODE BIT 2 SET
AND D1,D0 ;MASK SRC
OR D0,(A5) ;OR SRC INTO DST
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
MOVEQ #-1,D1 ;FLUSH MASK
SUB #1,D2 ;DEC WORD COUNT
BGT MAIN1 ;LOOP TILL LAST WORD
BEQ END1 ;DO LAST WORD WITH LASTMASK
BRA NXTSRC ;LOOP BACK FOR NEXT ROW
;-------------------------------------------------------
;
; MODE 2 OR 6: SRC XOR DST --> DST
;
END2 AND D5,D1 ;MASK:=MASK AND LASTMASK
MAIN2 MOVE.L -2(A4),D0 ;GET SRC FROM BITMAP
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
LSR.L D6,D0 ;ALIGN TO DST
EOR D7,D0 ;INVERT SRC IF MODE BIT 2 SET
AND D1,D0 ;MASK SRC
EOR D0,(A5) ;XOR SRC INTO DST
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
MOVEQ #-1,D1 ;FLUSH MASK
SUB #1,D2 ;DEC WORD COUNT
BGT MAIN2 ;LOOP TILL LAST WORD
BEQ END2 ;DO LAST WORD WITH LASTMASK
BRA NXTSRC ;LOOP BACK FOR NEXT ROW
;-------------------------------------------------------
;
; MODE 3 OR 7: SRC BIC DST --> DST
;
END3 AND D5,D1 ;MASK:=MASK AND LASTMASK
MAIN3 MOVE.L -2(A4),D0 ;GET SRC FROM BITMAP
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
LSR.L D6,D0 ;ALIGN TO DST
EOR D7,D0 ;INVERT SRC IF MODE BIT 2 SET
AND D1,D0 ;MASK SRC
NOT D0 ;INVERT SRC
AND D0,(A5) ;BIT CLEAR SRC INTO DST
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
MOVEQ #-1,D1 ;FLUSH MASK
SUB #1,D2 ;DEC WORD COUNT
BGT MAIN3 ;LOOP TILL LAST WORD
BEQ END3 ;DO LAST WORD WITH LASTMASK
BRA NXTSRC ;LOOP BACK FOR NEXT ROW
;-----------------------------------------------------------
;
; OPTIMIZE MODE 8 OR 12 IF DST FITS IN ONE WORD (VERT LINES ETC)
;
WORD8 AND D5,D1 ;COMBINE LEFT AND RIGHT MASKS
MOVE D1,D5 ;COPY COMBINED MASK
NOT D5 ;FORM NOTMASK
WORD8A AND D1,D6 ;MASK EXTRA PATTERN TO ZEROS
MOVE (A5),D0 ;GET DST DATA
AND D5,D0 ;AND WITH NOTMASK
OR D6,D0 ;MERGE WITH SRC DATA
MOVE D0,(A5)+ ;PUT RESULT TO DST
ADD A3,A5 ;BUMP DSTPTR TO NEXT ROW
ADD #4,D7 ;BUMP PATTERN SELECTOR
AND #$3F,D7 ;MOD 64 FOR 16 LONG REPEAT
MOVE EXPAT(A6,D7),D6 ;GET PATTERN FOR NEXT ROW
DBRA D3,WORD8A ;LOOP ALL ROWS
BRA GOHOME
;-------------------------------------------------------
;
; MODE 8 OR 12: PATTERN --> DST (FILLING AREAS, DRAWING LINES)
;
SETUP8 LEA FAST8,A1 ;only do setup once
LEA FILLBIG,A2 ;point to big fill
CALCLP CMP #32,D2 ;is wordcnt > 32 ?
BGT.S @2 ;yes use fillbig
ADD #COPY0+1-COPYBIG,A2 ;no, point to even table
BTST #0,D2 ;will wordcount-1 be even ?
BNE.S @1 ;yes, use even table
ADD #COPY1+1-COPY0,A2 ;no, point to odd table
@1 SUB D2,A2 ;adjust loop jump
@2 JMP (A1) ;re-connect with shared code
FAST8 MOVE D6,D0 ;GET PATTERN DATA
AND D1,D0 ;MASK FIRST WORD
NOT D1 ;MAKE NOTMASK
AND (A5),D1 ;GET DST DATA
OR D1,D0 ;MERGE WITH PAT DATA
MOVE D0,(A5)+ ;PUT RESULT TO DST
SUB #1,D2 ;DEC WORD COUNT
BEQ.S END8 ;BR IF NO UNMASKED WORDS
JSR (A2) ;call unwound loop
END8 MOVE D5,D1 ;MASK:= RIGHTMASK
AND D1,D6 ;MASK PATTERN
NOT D1 ;MAKE NOTMASK
AND (A5),D1 ;GET DST DATA
OR D1,D6 ;MERGE WITH PAT DATA
MOVE D6,(A5)+ ;PUT RESULT TO DST
BRA NXTPAT ;LOOP BACK FOR NEXT ROW
;----------------------------------------------------------
;
; Call fillbig with wordcount in D2 (clobbered)
;
FILLBIG BCLR #0,D2 ;is wordcount even ?
BEQ.S @1 ;yes, continue
MOVE.W D6,(A5)+ ;no, make it even
@1 SUB #32,D2 ;calc wordcount-32
BLE.S @2 ;continue if wordcount <= 32
BSR.S FILL32 ;elsae fill 32 words
BRA.S @1 ;and loop for more
@2 NEG D2 ;calc 32-wordcount
JMP FILL32(D2) ;jump into loop
FILL32 MOVE.L D6,(A5)+ ;TABLE TO FILL 0..32 WORDS
MOVE.L D6,(A5)+ ;wordCount = 30
MOVE.L D6,(A5)+ ;wordCount = 28
MOVE.L D6,(A5)+ ;wordCount = 26
MOVE.L D6,(A5)+ ;wordCount = 24
MOVE.L D6,(A5)+ ;wordCount = 22
MOVE.L D6,(A5)+ ;wordCount = 20
MOVE.L D6,(A5)+ ;wordCount = 18
MOVE.L D6,(A5)+ ;wordCount = 16
MOVE.L D6,(A5)+ ;wordCount = 14
MOVE.L D6,(A5)+ ;wordCount = 12
MOVE.L D6,(A5)+ ;wordCount = 10
MOVE.L D6,(A5)+ ;wordCount = 8
MOVE.L D6,(A5)+ ;wordCount = 6
MOVE.L D6,(A5)+ ;wordCount = 4
MOVE.L D6,(A5)+ ;wordCount = 2
RTS ;wordCount = 0
FILL31 MOVE.L D6,(A5)+ ;TABLE TO FILL 1..31 WORDS
MOVE.L D6,(A5)+ ;wordCount = 29
MOVE.L D6,(A5)+ ;wordCount = 27
MOVE.L D6,(A5)+ ;wordCount = 25
MOVE.L D6,(A5)+ ;wordCount = 23
MOVE.L D6,(A5)+ ;wordCount = 21
MOVE.L D6,(A5)+ ;wordCount = 19
MOVE.L D6,(A5)+ ;wordCount = 17
MOVE.L D6,(A5)+ ;wordCount = 15
MOVE.L D6,(A5)+ ;wordCount = 13
MOVE.L D6,(A5)+ ;wordCount = 11
MOVE.L D6,(A5)+ ;wordCount = 9
MOVE.L D6,(A5)+ ;wordCount = 7
MOVE.L D6,(A5)+ ;wordCount = 5
MOVE.L D6,(A5)+ ;wordCount = 3
MOVE.W D6,(A5)+ ;wordCount = 1
RTS
;-------------------------------------------------------
;
; MODE 9 OR 13: PATTERN OR DST --> DST
;
END9 AND D5,D1 ;MASK:=MASK AND LASTMASK
MAIN9 MOVE D6,D0 ;GET PATTERN DATA
AND D1,D0 ;MASK PATTERN
OR D0,(A5)+ ;OR PATTERN INTO DST
MOVEQ #-1,D1 ;FLUSH MASK
SUB #1,D2 ;DEC WORD COUNT
BGT MAIN9 ;LOOP TILL LAST WORD
BEQ END9 ;DO LAST WORD WITH LASTMASK
BRA NXTPAT ;LOOP BACK FOR NEXT ROW
;-------------------------------------------------------
;
; MODE 10 OR 14: PATTERN XOR DST --> DST (INVERTING AREAS, XOR LINES)
;
SETUP10 LEA FAST10,A1 ;only do setup once
LEA XORBIG,A2 ;point to big fill
BRA CALCLP ;share loop calc
FAST10 MOVE D6,D0 ;GET PATTERN DATA
AND D1,D0 ;MASK FIRST WORD
EOR D0,(A5)+ ;XOR PATTERN INTO DST
MOVEQ #-1,D1 ;FLUSH MASK FOR END10
SUB #1,D2 ;DEC WORD COUNT
BEQ.S END10 ;BR IF NO UNMASKED WORDS
JSR (A2) ;call unwound loop
MOVEQ #-1,D2 ;force finish up below
END10 AND D5,D1 ;MASK:=MASK AND LASTMASK
AND D1,D6 ;MASK PATTERN
EOR D6,(A5)+ ;XOR PATTERN DATA INTO DST
BRA NXTPAT ;LOOP BACK FOR NEXT ROW
;----------------------------------------------------------
;
; Call XORbig with wordcount in D2 (clobbered)
;
XORBIG BCLR #0,D2 ;is wordcount even ?
BEQ.S @1 ;yes, continue
EOR.W D6,(A5)+ ;no, make it even
@1 SUB #32,D2 ;calc wordcount-32
BLE.S @2 ;continue if wordcount <= 32
BSR.S XOR32 ;else XOR 32 words
BRA @1 ;and loop for more
@2 NEG D2 ;calc 32-wordcount
JMP XOR32(D2) ;jump into loop
XOR32 EOR.L D6,(A5)+ ;TABLE TO XOR 0..32 WORDS
EOR.L D6,(A5)+ ;wordCount = 30
EOR.L D6,(A5)+ ;wordCount = 28
EOR.L D6,(A5)+ ;wordCount = 26
EOR.L D6,(A5)+ ;wordCount = 24
EOR.L D6,(A5)+ ;wordCount = 22
EOR.L D6,(A5)+ ;wordCount = 20
EOR.L D6,(A5)+ ;wordCount = 18
EOR.L D6,(A5)+ ;wordCount = 16
EOR.L D6,(A5)+ ;wordCount = 14
EOR.L D6,(A5)+ ;wordCount = 12
EOR.L D6,(A5)+ ;wordCount = 10
EOR.L D6,(A5)+ ;wordCount = 8
EOR.L D6,(A5)+ ;wordCount = 6
EOR.L D6,(A5)+ ;wordCount = 4
EOR.L D6,(A5)+ ;wordCount = 2
RTS ;wordCount = 0
XOR31 EOR.L D6,(A5)+ ;TABLE TO XOR 1..31 WORDS
EOR.L D6,(A5)+ ;wordCount = 29
EOR.L D6,(A5)+ ;wordCount = 27
EOR.L D6,(A5)+ ;wordCount = 25
EOR.L D6,(A5)+ ;wordCount = 23
EOR.L D6,(A5)+ ;wordCount = 21
EOR.L D6,(A5)+ ;wordCount = 19
EOR.L D6,(A5)+ ;wordCount = 17
EOR.L D6,(A5)+ ;wordCount = 15
EOR.L D6,(A5)+ ;wordCount = 13
EOR.L D6,(A5)+ ;wordCount = 11
EOR.L D6,(A5)+ ;wordCount = 9
EOR.L D6,(A5)+ ;wordCount = 7
EOR.L D6,(A5)+ ;wordCount = 5
EOR.L D6,(A5)+ ;wordCount = 3
EOR.W D6,(A5)+ ;wordCount = 1
RTS
;-------------------------------------------------------
;
; MODE 11 OR 15: PATTERN BIC DST --> DST
;
END11 AND D5,D1 ;MASK:=MASK AND LASTMASK
MAIN11 MOVE D6,D0 ;GET PATTERN DATA
AND D1,D0 ;MASK PATTERN
NOT D0 ;INVERT PATTERN
AND D0,(A5)+ ;BIC PATTERN INTO DST
MOVEQ #-1,D1 ;FLUSH MASK
SUB #1,D2 ;DEC WORD COUNT
BGT MAIN11 ;LOOP TILL LAST WORD
BEQ END11 ;DO LAST WITH LASTMASK
BRA NXTPAT ;LOOP BACK FOR NEXT ROW
.ASCII 'CopyRight 1983 Apple Computer Inc.'
.END