.INCLUDE GRAFTYPES.TEXT ;------------------------------------------------------------------ ; ; --> RGNBLT.TEXT ; ; Low level block transfer clipped to an arbitrary region. ; .PROC RgnBlt,9 .REF BitBlt,RSect,ShieldCursor,ShowCursor .REF SeekRgn,PatExpand,ColorMap,InitRgn,TrimRect ;-------------------------------------------------------------- ; ; PROCEDURE RgnBlt(srcBits,dstBits: BitMap; ; srcRect,dstRect: Rect; ; mode: INTEGER; pat: Pattern; ; rgnA,rgnB,rgnC: RgnHandle); ; ; TRANSFERS A RECTANGULAR BLOCK OF BITS CLIPPED TO THE DESTINATION ; BITMAP'S BOUNDS AND TO THE INTERSECTION OF THREE REGIONS. ; MODE SPECIFIES THE TRANSFER MODE AND WHETHER THE SOURCE SHOULD COME ; FROM THE SOURCE BITMAP OR FROM A REPEATING PATTERN. ; ; COPYRIGHT APPLE COMPUTER INC. ; DESIGNED AND WRITTEN BY BILL ATKINSON ; ; THIS CODE IS POSITION INDEPENDENT, RE-ENTRANT, AND READ-ONLY. ; 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 34 ;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 RGNA .EQU PAT-4 ;LONG, RGNHANDLE RGNB .EQU RGNA-4 ;LONG, RGNHANDLE RGNC .EQU RGNB-4 ;LONG, RGNHANDLE ;------------------------------------------------- ; ; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK: ; EXPAT .EQU -64 ;16 LONGS MINRECT .EQU EXPAT-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 SRCADDR .EQU BUFSIZE-4 ;LONG DSTADDR .EQU SRCADDR-4 ;LONG SRCROW .EQU DSTADDR-4 ;LONG DSTROW .EQU SRCROW-4 ;LONG VERT .EQU DSTROW-2 ;WORD MODECASE .EQU VERT-4 ;LONG SAVEA5 .EQU MODECASE-4 ;LONG FIRSTV .EQU SAVEA5-2 ;WORD LASTV .EQU FIRSTV-2 ;WORD VBUMP .EQU LASTV-2 ;WORD, MUST BE ABOVE HBUMP HBUMP .EQU VBUMP-2 ;WORD SRCRECT2 .EQU HBUMP-8 ;RECT MASKADDR .EQU SRCRECT2-4 ;LONG VARSIZE .EQU MASKADDR ;SIZE OF LOCAL VARIABLES LINK A6,#VARSIZE ;ALLOCATE LOCAL VARIABLES MOVEM.L D3-D7/A2-A5,-(SP) ;SAVE REGS MOVE.L SP,SAVESTK(A6) ;REMEMBER STACK FOR LATER MOVE.L A5,SAVEA5(A6) ;REMEMBER GLOBAL PTR ;---------------------------------------------------------------- ; ; ADJUST MODE AND PATTERN IF COLOR FILTERING. ; MOVE MODE(A6),-(SP) ;YES, PUSH INPUT MODE MOVE.L PAT(A6),-(SP) ;PUSH ADDR OF INPUT PATTERN JSR COLORMAP ;ALTER BY THECOLOR, THEFILTER MOVE.L (SP)+,PAT(A6) ;GET (ALTERED) PATTERN MOVE (SP)+,MODE(A6) ;GET (ALTERED) MODE ;------------------------------------------------------ ; ; GET THREE REGION HANDLES AND DE-REFERENCE THEM. ; MOVE.L RGNA(A6),A1 ;GET RGNHANDLE MOVE.L (A1),A1 ;DE-REFERENCE IT MOVE.L RGNB(A6),A2 ;GET RGNHANDLE MOVE.L (A2),A2 ;DE-REFERENCE IT MOVE.L RGNC(A6),A3 ;GET RGNHANDLE MOVE.L (A3),A3 ;DE-REFERENCE IT ;------------------------------------------------------------------- ; ; CALC MINRECT, THE INTERSECTION OF DSTRECT, DSTBITS.BOUNDS, ; AND 3 REGION BOUNDING BOXES. QUIT IF THE INTERSECTION IS EMPTY. ; MOVE.L DSTRECT(A6),-(SP) ;PUSH DSTRECT MOVE.L DSTBITS(A6),A4 ;A4 POINTS TO DSTBITS PEA BOUNDS(A4) ;PUSH DSTBITS.BOUNDS PEA RGNBBOX(A1) ;PUSH RGNA BBOX PEA RGNBBOX(A2) ;PUSH RGNB BBOX PEA RGNBBOX(A3) ;PUSH RGNC BBOX MOVE #5,-(SP) ;PUSH NRECTS=5 PEA MINRECT(A6) ;PUSH WHERE TO PUT RESULT JSR RSECT ;CALC INTERSECTION BEQ GOHOME ;QUIT IF EMPTY ;---------------------------------------------------- ; ; HIDE THE CURSOR IF IT INTERSECTS MINRECT ; PEA MINRECT(A6) ;PUSH SHIELD RECT MOVE.L BOUNDS+TOPLEFT(A4),-(SP) ;PUSH DELTA TO CONVERT TO GLOBAL JSR SHIELDCURSOR ;REMOVE CURSOR IF INTERSECT ;---------------------------------------------------- ; ; ARE ALL THREE REGIONS RECTANGULAR ? ; CMP #10,RGNSIZE(A1) ;IS RGNA RECTANGULAR ? BNE.S NOTRECT ;NO, CONTINUE CMP #10,RGNSIZE(A3) ;IS RGN3 RECTANGULAR ? BNE.S NOTRECT ;NO, CONTINUE CMP #10,RGNSIZE(A2) ;IS RGN2 RECTANGULAR ? BEQ.S OKRECT ;NO, CONTINUE ; ; If only rgnB (visRgn) is non-rectangular, then check if ; its intersection with minrect would be rectangular. ; IF TrimRect(rgnB,minRect) then take the fast way. ; MOVE.L RGNB(A6),-(SP) ;push rgnHandle PEA minRect(A6) ;push addr of minRect JSR TrimRect ;call trimRect BLT DONE ;quit if intersection empty BGT.S NOTRECT ;continue if non-rectangular ;-------------------------------------------------------------- ; ; SINCE ALL THREE REGIONS ARE RECTANGULAR, WE WILL USE BITBLT. ; FIRST CLIP SRCRECT TO MATCH MINRECT. (COPY SRCRECT SINCE IT'S NOT VAR) ; OKRECT MOVE.L SRCRECT(A6),A2 ;POINT TO SRC RECT LEA SRCRECT2(A6),A0 ;POINT TO LOCAL COPY OF SRCRECT MOVE.L DSTRECT(A6),A3 ;POINT TO DSTRECT MOVE MINRECT+TOP(A6),D0 ;GET MINRECT TOP SUB TOP(A3),D0 ;CONVERT FROM DST COORDS ADD TOP(A2),D0 ;TO SRC COORDS MOVE D0,TOP(A0) ;PUT CLIPPED SRC TOP INTO COPY MOVE MINRECT+LEFT(A6),D0 ;GET MINRECT LEFT SUB LEFT(A3),D0 ;CONVERT FROM DST COORDS ADD LEFT(A2),D0 ;TO SRC COORDS MOVE D0,LEFT(A0) ;PUT CLIPPED SRC LEFT INTO COPY ;---------------------------------------------------- ; ; PUSH PARAMETERS AND CALL BITBLT ; MOVE.L SRCBITS(A6),-(SP) ;PUSH SRCBITS MOVE.L A4,-(SP) ;PUSH DSTBITS MOVE.L A0,-(SP) ;PUSH SRCRECT COPY PEA MINRECT(A6) ;PUSH DST = MINRECT MOVE MODE(A6),-(SP) ;PUSH MODE MOVE.L PAT(A6),-(SP) ;PUSH PATTERN JSR BITBLT ;CALL BITBLT BRA DONE ;RESTORE CURSOR AND QUIT ;----------------------------------- ; ; CALC BUFLEFT AND BUFSIZE ; NOTRECT MOVE MINRECT+LEFT(A6),D1 ;GET MINRECT LEFT SUB BOUNDS+LEFT(A4),D1 ;CONVERT TO GLOBAL COORDS AND #$FFF0,D1 ;TRUNC TO MULT OF 16 ADD BOUNDS+LEFT(A4),D1 ;CONVERT BACK TO LOCAL MOVE D1,BUFLEFT(A6) ;SAVE AS BUFLEFT MOVE MINRECT+RIGHT(A6),D0 ;GET MINRECT RIGHT SUB D1,D0 ;CALC WIDTH IN DOTS 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 DBRA D0,CLRMASK ;LOOP TILL DONE MOVE.L SP,MASKBUF(A6); ;REMEMBER WHERE MASKBUF IS ;------------------------------------------------------------------- ; ; INIT STATE RECORDS VERT0 AND VERT1 IN CASE RECTANGULAR ; MOVE #32767,D0 MOVE D0,STATEA+NEXTV(A6) MOVE D0,STATEB+NEXTV(A6) MOVE D0,STATEC+NEXTV(A6) NEG D0 MOVE D0,STATEA+THISV(A6) MOVE D0,STATEB+THISV(A6) MOVE D0,STATEC+THISV(A6) ;---------------------------------------------------------------------- ; ; ALLOCATE BUFFERS AND INIT STATE RECORDS FOR EACH NON-RECT REGION ; CLR D5 ;INIT ALL RGNS RECT MOVE.L RGNA(A6),A0 ;GET RGNHANDLE MOVE.L (A0),A0 ;DE-REFERENCE IT CMP #10,RGNSIZE(A0) ;IS RGNA RECTANGULAR ? BEQ.S ARECT ;YES, SKIP IT ADD #2,D5 ;NO, SET UP FLAG LEA STATEA(A6),A1 ;POINT TO STATE RECORD A BSR.S INITONE ;INIT STATE, ALLOC BUFFER ARECT MOVE.L RGNB(A6),A0 ;GET RGNHANDLE MOVE.L (A0),A0 ;DE-REFERENCE IT CMP #10,RGNSIZE(A0) ;IS RGNB RECTANGULAR ? BEQ.S BRECT ;YES, SKIP IT ADD #4,D5 ;NO, BUMP FLAG LEA STATEB(A6),A1 ;POINT TO STATE RECORD B BSR.S INITONE ;INIT STATE, ALLOC BUFFER BRECT MOVE.L RGNC(A6),A0 ;GET RGNHANDLE MOVE.L (A0),A0 ;DE-REFERENCE IT CMP #10,RGNSIZE(A0) ;IS RGNC RECTANGULAR ? BEQ.S CRECT ;YES, SKIP IT ADD #8,D5 ;NO, BUMP FLAG LEA STATEC(A6),A1 ;POINT TO STATE RECORD C PEA CRECT ;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 CRECT ;--------------------------------------------------------------------- ; ; IF ONLY ONE REGION IS NON-RECTANGULAR, PLAY IT BACK DIRECTLY ; INTO THE MASK BUFFER. ; MOVE.L MASKBUF(A6),D7 MOVE D5,RECTFLAG(A6) CMP #2,D5 ;IS RGNA THE ONLY NON-RECT ? BNE.S AOK ;NO, CONTINUE MOVE.L D7,STATEA+SCANBUF(A6) ;YES, PLAY DIRECTLY INTO MASK BRA.S COK AOK CMP #4,D5 ;IS RGNB THE ONLY NON-RECT ? BNE.S BOK MOVE.L D7,STATEB+SCANBUF(A6) BRA.S COK BOK CMP #8,D5 ;IS RGNC THE ONLY NON-RECT ? BNE.S COK MOVE.L D7,STATEC+SCANBUF(A6) COK ;---------------------------------------------------------- ; ; ASSUME WE WILL BE DRAWING DOWNWARD AND TO RIGHT. ; MOVE MINRECT+TOP(A6),FIRSTV(A6) ;FIRSTV:=MINRECT TOP MOVE MINRECT+BOTTOM(A6),LASTV(A6) ;LASTV:=MINRECT BOTTOM MOVE.L #$00040001,HBUMP(A6) ;HBUMP:=4 BYTES, VBUMP:=1 SCAN MOVE ROWBYTES(A4),D0 EXT.L D0 MOVE.L D0,DSTROW(A6) ;DSTROW:=+ROWBYTES MOVE.L D7,MASKADDR(A6) ;MASKADDR:=MASKBUF ;--------------------------------------- ; ; SET UP INVERT FLAG IN D7 TO REFLECT MODE BIT 2 ; CLR.L D7 ;SAY NOT INVERTED MOVE MODE(A6),D2 ;GET TRANSFER MODE BMI DONE ;QUIT IF MODE NEGATIVE BCLR #2,D2 ;TEST AND CLR INVERT BIT BEQ.S SETMODE ;SKIP IF NOT INVERTED NOT.L D7 ;INVERTED; D7 GETS ALL 1'S ;-------------------------------------------------- ; ; CALCULATE CASE JUMP FOR DIFFERENT TRANSFER MODES ; SETMODE AND #$F,D2 ;TREAT MODE MOD 16 MOVEQ #3,D0 AND D2,D0 ;GET BOTTOM 2 BITS OF MODE ADD D0,D2 ;MODIFY MODE FOR INDEX LEA MODETAB,A0 ;POINT TO MODE TABLE ADD 0(A0,D2),A0 ;GET CASE JUMP ADDRESS MOVE.L A0,MODECASE(A6) ;SAVE FOR LATER BTST #3,D2 ;WILL PATTERN BE USED ? BEQ.S USESRC ;NO, USE SOURCE INSTEAD ;------------------------------------------------------------------ ; ; PATTERN WILL BE USED. EXPAND 8 BYTE PATTERN TO 16 LONGS ; MOVE BOUNDS+LEFT(A4),D2 ;GET GLOBAL-LOCAL OFFSET MOVE.L PAT(A6),A0 ;POINT TO BYTE WIDE PATTERN LEA EXPAT(A6),A1 ;POINT TO EXPANDED PATTERN JSR PATEXPAND ;EXPAND 8 BYTES TO 16 LONGS ;------------------------------------------------- ; ; SET UP (VERT * 4) MOD 64 AS PATTERN SELECTOR ; MOVEQ #$F,D7 ;TREAT COORD MOD 16 AND MINRECT+TOP(A6),D7 ;GET TOP VERT COORD LSL #2,D7 ;QUAD FOR 4 BYTE PATTERNS MOVE.L EXPAT(A6,D7),D6 ;GET FIRST PATTERN DATA BRA GETDST ;SKIP OVER SRC STUFF ;-------------------------------------------------------------- ; ; SRC WILL BE USED. CHECK FOR OVERLAP AND CHOOSE DIRECTION SO ; THAT SRC WONT GET CLOBBERED BEFORE IT IS USED. ; USESRC MOVE.L DSTRECT(A6),A1 ;POINT TO DSTRECT MOVE.L SRCRECT(A6),A2 ;POINT TO SRCRECT MOVE.L SRCBITS(A6),A3 ;POINT TO SRCBITS MOVE ROWBYTES(A3),D0 EXT.L D0 MOVE.L D0,SRCROW(A6) ;SRCROW:=+ROWBYTES MOVE.L BASEADDR(A3),D0 ;GET SRC BASEADDR CMP.L BASEADDR(A4),D0 ;ARE SRC AND DST SAME BITMAP ? BNE.S SRCOK ;NO, DON'T WORRY ABOUT OVERLAP MOVE TOP(A1),D0 ;GET DST TOP SUB BOUNDS+TOP(A4),D0 ;CONVERT TO GLOBAL MOVE TOP(A2),D1 ;GET SRC TOP SUB BOUNDS+TOP(A3),D1 ;CONVERT TO GLOBAL SUB D1,D0 ;CALC DV:=DSTTOP-SRCTOP BLT.S SRCOK ;EVERYTHING FINE IF SCROLLING UP BGT.S UPSIDE ;UPSIDE DOWN IF SCROLLING DOWN ;------------------------------------------------------------ ; ; DV=0. IF DH > 0 THEN WE MUST TRANSFER BACKWARDS FROM RIGHT. ; MOVE LEFT(A1),D0 ;GET DST LEFT SUB BOUNDS+LEFT(A4),D0 ;CONVERT TO GLOBAL MOVE LEFT(A2),D1 ;GET SRC LEFT SUB BOUNDS+LEFT(A3),D1 ;CONVERT TO GLOBAL SUB D1,D0 ;DH := DSTLEFT-SRCLEFT BLE.S SRCOK ;IF DH <= 0, WE'RE FINE NEG HBUMP(A6) ;ELSE BUMP TOWARD LEFT BRA.S SRCOK ;CONTINUE ;------------------------------------------------------------ ; ; DV IS POSITIVE, WE MUST TRANSFER UPSIDE-DOWN FROM BOTTOM. ; UPSIDE NEG VBUMP(A6) ;VBUMP:=-1, BUMP UPWARD NEG.L SRCROW(A6) ;SRCROW:=-SRC ROWBYTES NEG.L DSTROW(A6) ;DSTROW:=-DST ROWBYTES MOVE MINRECT+BOTTOM(A6),FIRSTV(A6) SUB #1,FIRSTV(A6) ;FIRSTV:=BOTTOM-1 MOVE MINRECT+TOP(A6),LASTV(A6) SUB #1,LASTV(A6) ;LASTV:=TOP-1 ;---------------------------------------------- ; ; CALC SHIFTCNT ; SRCOK MOVE LEFT(A1),D6 ;GET DST LEFT LOCAL COORDS SUB BOUNDS+LEFT(A4),D6 ;CONVERT TO GLOBAL MOVE LEFT(A2),D1 ;GET SRC LEFT LOCAL COORDS SUB BOUNDS+LEFT(A3),D1 ;CONVERT TO GLOBAL SUB D1,D6 ;CALC DELTA HORIZ GLOBAL AND #$F,D6 ;MOD 16 FOR SHIFTCNT ;------------------------------------ ; ; CALC STARTING SRCADDR ; MOVE FIRSTV(A6),D0 ;GET FIRST DST VERTICAL SUB TOP(A1),D0 ;SUBTRACT DSTRECT TOP ADD TOP(A2),D0 ;ADD SRCRECT TOP SUB BOUNDS+TOP(A3),D0 ;CONVERT SRCV TO GLOBAL MULU ROWBYTES(A3),D0 ;MULT BY SRC ROWBYTES MOVE.L BASEADDR(A3),A0 ;GET START OF BITMAP ADD.L D0,A0 ;ADD OFFSET TO BASEADDR MOVE MINRECT+LEFT(A6),D0 ;GET DST LEFT SUB LEFT(A1),D0 ;CONVERT FROM DST COORDS ADD LEFT(A2),D0 ;TO SRC COORDS SUB BOUNDS+LEFT(A3),D0 ;CONVERT TO GLOBAL SRC ADD D6,D0 ;ADD SHIFTCNT LSR #4,D0 ;CONVERT DOTS TO WORDS ADD D0,D0 ;DOUBLE FOR BYTES ADD D0,A0 ;ADD HORIZ OFFSET MOVE.L A0,SRCADDR(A6) ;SAVE AS SRCADDR ;------------------------------------ ; ; CALC STARTING DSTADDR ; GETDST MOVE FIRSTV(A6),D0 ;GET FIRST DST VERT SUB BOUNDS+TOP(A4),D0 ;CONVERT TO GLOBAL MULU ROWBYTES(A4),D0 ;MULT BY ROWBYTES MOVE.L BASEADDR(A4),A0 ;GET START OF BITMAP ADD.L D0,A0 ;ADD VERTICAL OFFSET MOVE MINRECT+LEFT(A6),D0 ;GET DST LEFT SUB BOUNDS+LEFT(A4),D0 ;CONVERT TO GLOBAL LSR #4,D0 ;CONVERT DOTS TO WORDS ADD D0,D0 ;DOUBLE FOR BYTES ADD D0,A0 ;ADD HORIZ OFFSET MOVE.L A0,DSTADDR(A6) ;SAVE AS DSTADDR ;------------------------------------------------------------------------ ; ; ADJUST SRCADDR,DSTADDR,MASKADDR IF WE ARE BUMPING BACKWARDS FROM RIGHT ; TST HBUMP(A6) ;BUMPING BACKWARD ? BPL.S HBUMPOK ;NO, CONTINUE MOVE BUFSIZE(A6),D0 ;GET BUFFER SIZE ASL #2,D0 ;QUAD FOR # BYTES EXT.L D0 ;CLEAR HI WORD ADD.L D0,DSTADDR(A6) ;ADJUST DSTADDR ADD.L D0,SRCADDR(A6) ;ADJUST SRCADDR ADD.L D0,MASKADDR(A6) ;ADJUST MASKADDR HBUMPOK MOVE FIRSTV(A6),VERT(A6) ;INIT CURRENT VERTICAL ;------------------------------------------------------- ; ; MAKE MASK BUFFER CURRENT FOR THIS VERTICAL. ; THEN SET UP AND DRAW CURRENT SCANLINE. ; NXTMASK JSR SEEKMASK ;MAKE MASK BUFFER CURRENT MOVE.L SRCADDR(A6),A3 ;INIT SRCPTR MOVE.L DSTADDR(A6),A5 ;INIT DSTPTR FOR ROW MOVE.L MASKADDR(A6),A4 ;INIT MASKPTR FOR ROW MOVE BUFSIZE(A6),D2 ;INIT COUNT OF LONGS MOVE.L MODECASE(A6),A2 ;GET MODE CASE JUMP JMP (A2) ;TAKE MODE JUMP NEXTSRC MOVE.L SRCROW(A6),D0 ;GET SRC ROWBYTES ADD.L D0,SRCADDR(A6) ;BUMP SRC TO NEXT ROW BRA.S BUMPV ;CONTINUE WITH NEXT ROW NEXTPAT ADD #4,D7 ;BUMP PATTERN SELECTOR AND #$3F,D7 ;MOD 64 FOR 16 LONG REPEAT MOVE.L EXPAT(A6,D7),D6 ;GET PATTERN FOR NEXT ROW ;----------------------------------------------------- ; ; BUMP DESTINATION VERTICALLY AND LOOP FOR ALL ROWS ; BUMPV MOVE.L DSTROW(A6),D0 ;GET DST ROWBYTES ADD.L D0,DSTADDR(A6) ;BUMP DST TO NEXT ROW NODRAW MOVE VERT(A6),D0 ;GET CURRENT VERT ADD VBUMP(A6),D0 ;BUMP UP OR DOWN A SCAN LINE MOVE D0,VERT(A6) ;UPDATE CURRENT VERT CMP LASTV(A6),D0 ;ARE WE AT THE LAST SCAN LINE ? BNE NXTMASK ;NO, LOOP FOR ALL SCAN LINES ;----------------------------------------------------------------- ; ; ENTIRE RGNBLT COMPLETE. RESTORE REGS AND STACK AND GO HOME. ; DONE MOVE.L SAVEA5(A6),A5 ;GET GLOBAL POINTER JSR SHOWCURSOR ;RESTORE CURSOR GOHOME MOVE.L SAVESTK(A6),SP ;STRIP VARIABLE SIZED BUFFER MOVEM.L (SP)+,D3-D7/A2-A5 ;RESTORE REGISTERS UNLINK PARAMSIZE,'RGNBLT ' ;----------------------------------------------------------------- ; ; LOCAL ROUTINE TO UPDATE MASK BUFFER TO CURRENT VERTICAL COORD. ; 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 SEEKOK-RECTJMP .WORD A-RECTJMP .WORD B-RECTJMP .WORD AB-RECTJMP .WORD C-RECTJMP .WORD AC-RECTJMP .WORD BC-RECTJMP .WORD ABC-RECTJMP ;-------------------------------------------------------------------- ; ; ONLY REGION A IS NON RECTANGULAR. UPDATE IT AND USE IT AS THE MASK ; A LEA STATEA(A6),A1 BRA.S JMPSEEK ;-------------------------------------------------------------------- ; ; ONLY REGION B IS NON RECTANGULAR. UPDATE IT AND USE IT AS THE MASK ; B LEA STATEB(A6),A1 BRA.S JMPSEEK ;-------------------------------------------------------------------- ; ; ONLY REGION C IS NON RECTANGULAR. UPDATE IT AND USE IT AS THE MASK ; C LEA STATEC(A6),A1 JMPSEEK MOVE.L MASKBUF(A6),SCANBUF(A1) ;PLAY DIRECTLY INTO MASKBUF JMP SEEKRGN ;------------------------------------------------------------------- ; ; REGIONS A AND B ARE NON-RECTANGULAR. UPDATE EACH, ; THEN FORM INTERSECTION IN THE MASK BUFFER. ; AB LEA STATEA(A6),A1 JSR SEEKRGN MOVE D1,-(SP) ;REMEMBER IF RGN CHANGED LEA STATEB(A6),A1 JSR SEEKRGN OR (SP)+,D1 ;HAS EITHER RGN CHANGED ? BEQ.S SEEKOK ;NO, WE'RE DONE MOVE.L STATEA+SCANBUF(A6),A0 MOVE.L STATEB+SCANBUF(A6),A1 BRA.S CPY2BUF ;------------------------------------------------------------------- ; ; REGIONS A AND C ARE NON-RECTANGULAR. UPDATE EACH, ; THEN FORM INTERSECTION IN THE MASK BUFFER. ; AC LEA STATEA(A6),A1 JSR SEEKRGN MOVE D1,-(SP) ;REMEMBER IF RGN CHANGED LEA STATEC(A6),A1 JSR SEEKRGN OR (SP)+,D1 ;HAS EITHER RGN CHANGED ? BEQ.S SEEKOK ;NO, WE'RE DONE MOVE.L STATEA+SCANBUF(A6),A0 MOVE.L STATEC+SCANBUF(A6),A1 BRA.S CPY2BUF ;------------------------------------------------------------------- ; ; REGIONS B AND C ARE NON-RECTANGULAR. UPDATE EACH, ; THEN FORM INTERSECTION IN THE MASK BUFFER. ; BC LEA STATEB(A6),A1 JSR SEEKRGN MOVE D1,-(SP) ;REMEMBER IF RGN CHANGED LEA STATEC(A6),A1 JSR SEEKRGN OR (SP)+,D1 ;HAS EITHER RGN CHANGED ? BEQ.S SEEKOK ;NO, WE'RE DONE MOVE.L STATEB+SCANBUF(A6),A0 MOVE.L STATEC+SCANBUF(A6),A1 CPY2BUF MOVE.L MASKBUF(A6),A2 MOVE BUFSIZE(A6),D1 BCLOOP MOVE.L (A0)+,D0 AND.L (A1)+,D0 MOVE.L D0,(A2)+ DBRA D1,BCLOOP SEEKOK RTS ;ALL 3 ARE RECT, DO NOTHING ;------------------------------------------------------------------- ; ; REGIONS A, B AND C ARE ALL NON-RECTANGULAR. UPDATE EACH, ; THEN FORM INTERSECTION IN THE MASK BUFFER. ; ABC LEA STATEA(A6),A1 JSR SEEKRGN MOVE D1,-(SP) ;REMEMBER IF RGN CHANGED LEA STATEB(A6),A1 JSR SEEKRGN OR D1,(SP) ;REMEMBER IF RGN CHANGED LEA STATEC(A6),A1 JSR SEEKRGN OR (SP)+,D1 ;HAS EITHER RGN CHANGED ? BEQ.S ABCDONE ;NO, WE'RE DONE MOVE.L STATEA+SCANBUF(A6),A0 MOVE.L STATEB+SCANBUF(A6),A1 MOVE.L STATEC+SCANBUF(A6),A2 MOVE.L MASKBUF(A6),A3 MOVE BUFSIZE(A6),D1 ABCLOOP MOVE.L (A0)+,D0 AND.L (A1)+,D0 AND.L (A2)+,D0 MOVE.L D0,(A3)+ DBRA D1,ABCLOOP ABCDONE RTS ;---------------------------------------------------------------; ; ; ; INTERFACE TO EACH OF THE RGNBLT SCANLINE LOOPS: ; ; ; ; REGISTERS: A0: D0: ; ; A1: D1: ; ; A2: D2: LONGCNT ; ; A3: SRCPTR D3: ; ; A4: MASKPTR D4: ; ; A5: DSTPTR D5: ; ; A6: D6: SHIFTCNT OR PATTERN ; ; A7: D7: INVERT OR PAT-SEL ; ; ; ;---------------------------------------------------------------; MODETAB .WORD MASK0-MODETAB .WORD MASK1-MODETAB .WORD MASK2-MODETAB .WORD MASK3-MODETAB .WORD MASK8-MODETAB .WORD MASK9-MODETAB .WORD MASK10-MODETAB .WORD MASK11-MODETAB ;------------------------------------------------------- ; ; MODE 0 OR 4: SRC --> DST ; MASK0 MOVE.L -2(A3),D0 ;GET SRC FROM BITMAP LSR.L D6,D0 ;ALIGN TO DST SWAP D0 ;PUT INTO HI HALF OF D0 MOVE.L (A3),D1 ;GET SRC FROM BITMAP ADD HBUMP(A6),A3 ;BUMP 4 BYTES RIGHT OR LEFT LSR.L D6,D1 ;ALIGN TO DST MOVE D1,D0 ;ASSEMBLE ONE LONG EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET MOVE.L (A4),D1 ;GET MASK ADD HBUMP(A6),A4 ;BUMP 4 BYTES RIGHT OR LEFT AND.L D1,D0 ;MASK SRC NOT.L D1 ;FORM NOTMASK AND.L (A5),D1 ;GET DST DATA OR.L D1,D0 ;MERGE WITH SRC DATA MOVE.L D0,(A5) ;PUT RESULT IN DST ADD HBUMP(A6),A5 ;BUMP 4 BYTES RIGHT OR LEFT DBRA D2,MASK0 ;LOOP ALL LONGS THIS ROW BRA NEXTSRC ;GO FOR NEXT ROW ;------------------------------------------------------- ; ; MODE 1 OR 5: SRC OR DST --> DST ; MASK1 MOVE.L -2(A3),D0 ;GET SRC FROM BITMAP LSR.L D6,D0 ;ALIGN TO DST SWAP D0 ;PUT INTO HI HALF OF D0 MOVE.L (A3),D1 ;GET SRC FROM BITMAP ADD HBUMP(A6),A3 ;BUMP 4 BYTES RIGHT OR LEFT LSR.L D6,D1 ;ALIGN TO DST MOVE D1,D0 ;ASSEMBLE ONE LONG EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET AND.L (A4),D0 ;AND WITH MASK ADD HBUMP(A6),A4 ;BUMP 4 BYTES RIGHT OR LEFT OR.L D0,(A5) ;OR RESULT INTO DST ADD HBUMP(A6),A5 ;BUMP 4 BYTES RIGHT OR LEFT DBRA D2,MASK1 ;LOOP ALL LONGS THIS ROW BRA NEXTSRC ;LOOP FOR NEXT ROW ;------------------------------------------------------- ; ; MODE 2 OR 6: SRC XOR DST --> DST ; MASK2 MOVE.L -2(A3),D0 ;GET SRC FROM BITMAP LSR.L D6,D0 ;ALIGN TO DST SWAP D0 ;PUT INTO HI HALF OF D0 MOVE.L (A3),D1 ;GET SRC FROM BITMAP ADD HBUMP(A6),A3 ;BUMP 4 BYTES RIGHT OR LEFT LSR.L D6,D1 ;ALIGN TO DST MOVE D1,D0 ;ASSEMBLE ONE LONG EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET AND.L (A4),D0 ;AND WITH MASK ADD HBUMP(A6),A4 ;BUMP 4 BYTES RIGHT OR LEFT EOR.L D0,(A5) ;XOR RESULT INTO DST ADD HBUMP(A6),A5 ;BUMP 4 BYTES RIGHT OR LEFT DBRA D2,MASK2 ;LOOP ALL LONGS THIS ROW BRA NEXTSRC ;LOOP FOR NEXT ROW ;------------------------------------------------------- ; ; MODE 3 OR 7: SRC BIC DST --> DST ; MASK3 MOVE.L -2(A3),D0 ;GET SRC FROM BITMAP LSR.L D6,D0 ;ALIGN TO DST SWAP D0 ;PUT INTO HI HALF OF D0 MOVE.L (A3),D1 ;GET SRC FROM BITMAP ADD HBUMP(A6),A3 ;BUMP 4 BYTES RIGHT OR LEFT LSR.L D6,D1 ;ALIGN TO DST MOVE D1,D0 ;ASSEMBLE ONE LONG EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET AND.L (A4),D0 ;AND WITH MASK ADD HBUMP(A6),A4 ;BUMP 4 BYTES RIGHT OR LEFT NOT.L D0 ;INVERT FOR BIC AND.L D0,(A5) ;BIC RESULT INTO DST ADD HBUMP(A6),A5 ;BUMP 4 BYTES RIGHT OR LEFT DBRA D2,MASK3 ;LOOP ALL LONGS THIS ROW BRA NEXTSRC ;LOOP FOR NEXT ROW ;------------------------------------------------------- ; ; MODE 8 OR 12: PATTERN --> DST (FILLING AREAS, DRAWING LINES) ; MASK8 MOVE.L D6,D0 ;GET PATTERN DATA MOVE.L (A4)+,D1 ;GET MASK AND.L D1,D0 ;MASK PATTERN DATA NOT.L D1 ;MAKE NOTMASK AND.L (A5),D1 ;GET DST DATA OR.L D1,D0 ;MERGE WITH PAT DATA MOVE.L D0,(A5)+ ;PUT RESULT TO DST DBRA D2,MASK8 ;LOOP ALL LONGS THIS ROW BRA NEXTPAT ;LOOP BACK FOR NEXT ROW ;------------------------------------------------------- ; ; MODE 9 OR 13: PATTERN OR DST --> DST ; MASK9 MOVE.L D6,D0 ;GET PATTERN DATA AND.L (A4)+,D0 ;MASK PATTERN DATA OR.L D0,(A5)+ ;OR RESULT INTO DST DBRA D2,MASK9 ;LOOP ALL LONGS THIS ROW BRA NEXTPAT ;LOOP BACK FOR NEXT ROW ;------------------------------------------------------- ; ; MODE 10 OR 14: PATTERN XOR DST --> DST (INVERTING AREAS, XOR LINES) ; MASK10 MOVE.L D6,D0 ;GET PATTERN DATA AND.L (A4)+,D0 ;MASK PATTERN DATA EOR.L D0,(A5)+ ;XOR RESULT INTO DST DBRA D2,MASK10 ;LOOP ALL LONGS THIS ROW BRA NEXTPAT ;LOOP BACK FOR NEXT ROW ;------------------------------------------------------- ; ; MODE 11 OR 15: PATTERN BIC DST --> DST ; MASK11 MOVE.L D6,D0 ;GET PATTERN DATA AND.L (A4)+,D0 ;MASK PATTERN DATA NOT.L D0 ;INVERT FOR BIC AND.L D0,(A5)+ ;BIC RESULT INTO DST DBRA D2,MASK11 ;LOOP ALL LONGS THIS ROW BRA NEXTPAT ;LOOP BACK FOR NEXT ROW .END