mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-28 16:31:01 +00:00
4325cdcc78
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
814 lines
25 KiB
Plaintext
814 lines
25 KiB
Plaintext
;EASE$$$ READ ONLY COPY of file ÒBITBLT.m.aÓ
|
|
; 1.1 CCH 11/11/1988 Fixed Header.
|
|
; 1.0 CCH 11/ 9/1988 Adding to EASE.
|
|
; OLD REVISIONS BELOW
|
|
; 1.2 CCH 10/12/1988 Changed Òm.GrafType.aÓ to ÒGrafType.m.aÓ.
|
|
; 1.1 MSH 5/18/88 Changed inclides to use m.GRAPHTYPES to work under EASE.
|
|
; 1.0 BBM 2/11/88 Adding file for the first time into EASEÉ
|
|
; END EASE MODIFICATION HISTORY
|
|
|
|
BLANKS ON
|
|
STRING ASIS
|
|
|
|
INCLUDE 'GRAFTYPES.m.a'
|
|
;---------------------------------------------------------------
|
|
;
|
|
; --> BITBLT.TEXT
|
|
;
|
|
; Low-level bit boundary block transfer.
|
|
;
|
|
|
|
|
|
BITBLT PROC EXPORT
|
|
IMPORT 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 DC.W MAIN0-MODETAB ;JUMP TABLE USED IF DST WIDER THAN ONE WORD
|
|
DC.W MAIN1-MODETAB
|
|
DC.W MAIN2-MODETAB
|
|
DC.W MAIN3-MODETAB
|
|
DC.W SETUP8-MODETAB
|
|
DC.W MAIN9-MODETAB
|
|
DC.W SETUP10-MODETAB
|
|
DC.W MAIN11-MODETAB
|
|
|
|
DC.W END0-MODETAB ;JUMP TABLE USED IF DST FITS IN ONE WORD WIDE
|
|
DC.W END1-MODETAB
|
|
DC.W END2-MODETAB
|
|
DC.W END3-MODETAB
|
|
DC.W WORD8-MODETAB
|
|
DC.W END9-MODETAB
|
|
DC.W END10-MODETAB
|
|
DC.W 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
|
|
|
|
|
|
|
|
DC.B '(c) Apple Computer Inc., 1983-1985'
|
|
|
|
|
|
END
|
|
|
|
|
|
|
|
|
|
|