mirror of
https://github.com/elliotnunn/sys7.1-doc-wip.git
synced 2024-12-28 03:29:17 +00:00
842 lines
25 KiB
Plaintext
842 lines
25 KiB
Plaintext
;EASE$$$ READ ONLY COPY of file “RGNBLT.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'
|
|
;------------------------------------------------------------------
|
|
;
|
|
; --> RGNBLT.TEXT
|
|
;
|
|
; Low level block transfer clipped to an arbitrary region.
|
|
;
|
|
|
|
|
|
RgnBlt PROC EXPORT
|
|
IMPORT BitBlt,RSect,ShieldCursor,ShowCursor
|
|
IMPORT 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 D0-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)+,D0-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 DC.W SEEKOK-RECTJMP
|
|
DC.W A-RECTJMP
|
|
DC.W B-RECTJMP
|
|
DC.W AB-RECTJMP
|
|
DC.W C-RECTJMP
|
|
DC.W AC-RECTJMP
|
|
DC.W BC-RECTJMP
|
|
DC.W 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 DC.W MASK0-MODETAB
|
|
DC.W MASK1-MODETAB
|
|
DC.W MASK2-MODETAB
|
|
DC.W MASK3-MODETAB
|
|
DC.W MASK8-MODETAB
|
|
DC.W MASK9-MODETAB
|
|
DC.W MASK10-MODETAB
|
|
DC.W 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
|
|
|
|
|
|
|