mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-28 01:29:20 +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.
4943 lines
158 KiB
Plaintext
4943 lines
158 KiB
Plaintext
;
|
||
; File: BitBlt.a
|
||
;
|
||
; Function: Low-level bit boundary block transfer.
|
||
;
|
||
; OLD NOTE: Because BitBlt only called by RgnBlt, we know that the
|
||
; bitMaps that are passed us are not portBits.
|
||
;
|
||
; Copyright: © 1981-1990, 1992 by Apple Computer, Inc., all rights reserved.
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <SM5> 12/2/92 kc Roll in CopyBits changes from QuickDrawPatches.a in Reality
|
||
; <R24> 10/2/92 SAH Fixed a word alignment bug in the fast bSetup0 and bSetup8
|
||
; patches (word alignment would cause the Move16 code to fail).
|
||
; Also added a check in the bSetup8 patch to make sure that the
|
||
; left edge quadlong alignment would remain constant across
|
||
; scanlines.
|
||
; <R23> 10/1/92 SAH Brought in fast bSetup8 patch for 040 machines that uses
|
||
; Move16's.
|
||
; <R20> 4/10/92 SAH Moved in the working fast bSetup0 patch for 68040 machines from
|
||
; QDIIciPatchROM.a.
|
||
; <SM4> 7/30/92 chp Moved a short branch inside the conditional generated by <SM3>
|
||
; to get rid of an assembler Òtrivial short branch = NOPÓ warning.
|
||
; <SM3> 7/1/92 kc Conditionalize the Move16 code in bSetup0 because it doesn't
|
||
; work without flushing the cache.
|
||
; <SM2> 6/12/92 stb <sm 6/9/92>stb Synched-up with QDciPatchROM.a; added comments
|
||
; from QDciPatchROM.a; alpha channel stuff at bLONG8, bSETUP8,
|
||
; bXLONG8, bXMAIN8, bSubOver16; handle vertically aligned hilites
|
||
; and preserve a non-white bkg color through the entire blit at
|
||
; bSloHilite; fixed bTransparent and rTransparent to remove an
|
||
; optimization that was losing pattern data. Related changes in
|
||
; Arith8Blt.a;
|
||
; <17> 6/11/91 gbm Take out conditional for Regatta
|
||
; <16> 3/13/91 SMC forRegattaCPUs, fixed cpuFlag check in bSetup0 to include '040
|
||
; processors and greater.
|
||
; <15> 12/13/90 SMC Pulled out Debugger traps left in <14>. With KON.
|
||
; <14> 11/26/90 SMC Fixed pattern hiliting once and for all. With BAL.
|
||
; <13> 10/31/90 SMC Fixed alpha channel crimes with BAL.
|
||
; <12> 10/18/90 SMC Simplify and shorten colorized OR and BIC blit loops. With KON.
|
||
; <11> 9/26/90 SMC Fixed right edge problem in bSubOver16. A move.l was being used
|
||
; to retrieve a 16-bit pixel instead of a move.w.
|
||
; <10> 9/26/90 SMC Removed bTransparent optimization that was losing pattern data.
|
||
; <9> 9/17/90 BG Removed <5>. 040s are now behaving more reliably.
|
||
; <8> 9/13/90 SMC Fixed problem in bSloHilite when the background color is not
|
||
; white.
|
||
; <7> 8/17/90 KON Fix vertically aligned, horizontally overlapped arithmetic
|
||
; transfer modes. The pixel location was saved as a word instead
|
||
; of a long (in bAvg), and there was an alignment problem. This
|
||
; will not be fixed on the ci to save space.
|
||
; <6> 8/13/90 SMC Made speed improvements to bMAIN0,1,2,3 and bcMain0,3.
|
||
; <5> 6/25/90 BG Added EclipseNOPs for flakey 040s.
|
||
; <4> 6/5/90 KON Add check for inverting; if so, goto NotFast.
|
||
; <3> 6/4/90 KON Check of modeCase colorizing was backwards.
|
||
; <2> 5/24/90 KON Make bitblt look at colorizing flags rather than BGnotWhite.
|
||
; <1.7> 11/18/89 BAL Added QuickerDraw 8-bit arithmetic transfer loops
|
||
; <¥1.6> 7/14/89 BAL For Aurora: Final CQD
|
||
; <1.5> 6/30/89 BAL Unrolled loop to get a 2x improvement in big-pattern filling
|
||
; <¥1.4> 5/29/89 BAL Blasting in 32-Bit QuickDraw version 1.0 Final
|
||
; <¥1.3> 4/12/89 BAL Blasting in 32-Bit QuickDraw 1.0B1
|
||
; 9/18/88 BAL Altered to use common stack frame file 'Drawing Vars.a'
|
||
; 1/3/87 CRC added color blt loops
|
||
; 12/12/86 CRC Added arithmetic modes
|
||
; 7/29/86 EHB Use new stack-based EXPAT buffer
|
||
; 7/26/86 EHB Added support for expanded patterns
|
||
; 7/22/86 EHB Added color to pattern OR and pattern BIC transfer modes Added
|
||
; FIRSTMASK to stack frame to free up a register
|
||
; 6/22/86 EHB Add FCOLOR, BCOLOR params to BitBlt Call new PatExpand with
|
||
; FCOLOR, BCOLOR
|
||
; 6/19/86 EHB Modified to use pixel depth All horizontal calculations done
|
||
; using longs for big pixels
|
||
; 6/9/86 EHB Use new LMask32 and RMask32 routines
|
||
; 6/8/86 EHB Modified bitBlt and scanline routines to use longs and BFEXTU.
|
||
; 6/24/85 EHB Big re-org: all shared fields set up by stretchbits before
|
||
; calling here. All parms in stack frame or registers.
|
||
;
|
||
; To Do:
|
||
;
|
||
|
||
BLANKS ON
|
||
STRING ASIS
|
||
|
||
MACHINE MC68020
|
||
|
||
|
||
BITBLT PROC EXPORT
|
||
EXPORT bMAIN0, bMAIN1, bMAIN2, bMAIN3, bSETUP8, bMAIN9, bSETUP10, bMAIN11
|
||
EXPORT bXMAIN8, bXMAIN9, bXMAIN10, bXMAIN11, bcMain0, bcMain1, bHilite, bcMain3
|
||
EXPORT bEND0, bEND1, bEND2, bEND3, bLONG8, bEND9, bEND10, bEND11, bXLONG8, bXEND9
|
||
EXPORT bXEND10, bXEND11, bcEnd0, bcEnd1, bSloHilite, bcEnd3, bAvg, bAddPin, bAddOver
|
||
EXPORT bSubPin, bTransparent, bMax, bSubOver, bMin, bLeft0, bSetup0
|
||
EXPORT bArith32Setup,bArith16Setup,bArith32Tab,bArith16Tab,bHiliteTab
|
||
|
||
;--------------------------------------------------------------
|
||
;
|
||
; PROCEDURE BitBlt(srcPix,dstPix: BitMap;
|
||
; srcRect,dstRect: Rect;
|
||
; mode: INTEGER; pat: Pattern);
|
||
;
|
||
; ALL PARAMETERS PASSED IN STACK FRAME.
|
||
;
|
||
; 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.
|
||
;
|
||
; mode bit meaning
|
||
; 7 6 5 4 3 2 1 0
|
||
; 0 msk ari 0 pat not coxb-
|
||
; arith.vars
|
||
;
|
||
; 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
|
||
;
|
||
; 16 ÉÊ31 ---
|
||
|
||
; 32 AVG(SRC, DST, WEIGHT) --> DST
|
||
; 33 SRC + DST --> DST (pin TO MAX)
|
||
; 34 SRC + DST --> DST (no pin)
|
||
; 35 DST - SRC --> DST (pin TO MIN)
|
||
; 36 SRC less bg --> DST
|
||
; 37 MAX(SRC, DST) --> DST
|
||
; 38 DST - SRC --> DST (no pin)
|
||
; 39 MIN(SRC, DST) --> DST
|
||
|
||
; 40 AVG(PAT, DST, WEIGHT) --> DST
|
||
; 41 PAT + DST --> DST (pin TO MAX)
|
||
; 42 PAT + DST --> DST (no pin)
|
||
; 43 DST - PAT --> DST (pin TO MIN)
|
||
; 44 PAT less bg --> DST
|
||
; 45 MAX(PAT, DST) --> DST
|
||
; 46 DST - PAT --> DST (no pin)
|
||
; 47 MIN(PAT, DST) --> DST
|
||
|
||
; 48 ---
|
||
; 49 ---
|
||
; 50 src Hilite Dst (bg <--> fg)
|
||
; 51 ---
|
||
; 52 ÉÊ55 unassigned
|
||
|
||
; 56 ---
|
||
; 57 ---
|
||
; 58 pat Hilite Dst
|
||
|
||
; Note that the mask bit is stripped by DrawText
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACK FRAME VARS USED BY SEEKMASK (CALLED BY STRETCHBITS, RGNBLT, DRAWARC, DRAWLINE)
|
||
;
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
||
;
|
||
PARAMSIZE EQU 44 ;SIZE OF PARAMETERS
|
||
SRCBITS EQU PARAMSIZE+8-4 ;LONG, ADDR OF BITMAP
|
||
MASKBITS EQU SRCBITS-4 ;LONG, ADDR OF BITMAP
|
||
DSTBITS EQU MASKBITS-4 ;LONG, ADDR OF BITMAP
|
||
SRCRECT EQU DSTBITS-4 ;LONG, ADDR OF RECT
|
||
MASKRECT EQU SRCRECT-4 ;LONG, ADDR OF RECT
|
||
DSTRECT EQU MASKRECT-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
|
||
multColor EQU RGNC-2 ;byte, set if source contains nonblack/white colors
|
||
|
||
blit32 EQU 0 ;<14>
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'BITBLT'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;-------------------------------------------------------------
|
||
;
|
||
; ENTER HERE. CALLER TAKES CARE OF CURSOR.
|
||
;
|
||
; ON ENTRY, REGISTERS SET UP LIKE THIS:
|
||
;
|
||
; A2: SRCRECT
|
||
; A3: DSTRECT
|
||
; A4: SRCPIX
|
||
; A5: DSTPIX
|
||
;
|
||
; D3: SRCSHIFT (NOT USED)
|
||
; D4: DSTSHIFT
|
||
; D7: INVERT FLAG
|
||
;
|
||
; ONLY A6,A7 MUST BE PRESERVED
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; FIRST CLIP SRCRECT TO MATCH MINRECT. (COPY SRCRECT SINCE IT'S NOT VAR)
|
||
; ONLY TOPLEFT USED.
|
||
;
|
||
LEA SRCRECT2(A6),A0 ;POINT TO LOCAL COPY OF SRCRECT
|
||
|
||
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
|
||
|
||
MOVE.L A0,A2 ;KEEP NEW SRCRECT PTR IN A2
|
||
LEA MINRECT(A6),A3 ;AND USE MINRECT AS DSTRECT
|
||
|
||
|
||
;-------------------------------------------------------------
|
||
;
|
||
; 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
|
||
;
|
||
MOVE #4,D3 ;BUMP:=4 (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
|
||
|
||
|
||
;-------------------------------------------------
|
||
;
|
||
; SET UP DRAWING PARAMETERS FOR PATTERNS
|
||
;
|
||
MOVE LOCMODE(A6),D2 ;GET MODE
|
||
BTST #3,D2 ;PATTERN BIT SET?
|
||
BEQ.S USESRC ;=>NO, USE SOURCE
|
||
MOVE PATROW(A6),D1 ;BIG PATTERN USED?
|
||
BNE.S DONEW ;=>YES, GO USE IT
|
||
|
||
MOVEQ #$F,D7 ;TREAT COORD MOD 16
|
||
AND TOP(A3),D7 ;GET DST TOP LOCAL COORD
|
||
MOVE.L ([EXPAT,A6],D7*4),D6 ;GET FIRST PATTERN DATA
|
||
BRA NOTSRC ;NOT USING SRC, SKIP OVER
|
||
|
||
; NEW PATTERN. SET STARTING VERT POSITION, SET FLAG.
|
||
|
||
DONEW MOVEQ #0,D6 ;CLEAR HIGH WORD
|
||
MOVE PATVMASK(A6),D6 ;GET VERTICAL MASK
|
||
ADDQ #1,D6 ;CONVERT TO COUNT
|
||
DIVU PATROW(A6),D6 ;DIVIDE BY ROWSIZE
|
||
SUBQ #1,D6 ;CONVERT TO ROW MASK
|
||
AND TOP(A3),D6 ;GET TOP VERT COORD
|
||
MULU D1,D6 ;GET PATVPOS INTO D6
|
||
MOVE PATHMASK(A6),D7 ;SET UP HMASK IN D7
|
||
BRA 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
|
||
;
|
||
USESRC 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
|
||
move minRect+right(A6),d2 ;get local srcRight <BAL 2Mar89>
|
||
sub minRect+left(A6),d2 ;get src width <BAL 2Mar89>
|
||
add d0,d2 ;get global srcRight <BAL 2Mar89>
|
||
cmp d1,d2 ;is srcRight < dstLeft ? <BAL 2Mar89>
|
||
ble.s GETSRC ;yes, no overlap <BAL 2Mar89>
|
||
NEG D3 ;no, BUMP:=-4 (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.L SRCROW(A6) ;SRCROW:=-SRCROW
|
||
NEG.L 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
|
||
EXT.L D6 ;MAKE IT A LONG
|
||
LSL.L D4,D6 ;CONVERT DST PIXELS TO BITS
|
||
MOVE LEFT(A2),D1 ;GET SRC LEFT
|
||
SUB BOUNDS+LEFT(A4),D1 ;CONVERT TO GLOBAL
|
||
EXT.L D1 ;MAKE IT A LONG
|
||
MOVE SRCSHIFT(A6),D0 ;GET DEPTH OF SRC PIXELS
|
||
LSL.L D0,D1 ;CONVERT PIXELS TO BITS
|
||
SUB.L D1,D6 ;CALC DELTA HORIZ
|
||
MOVEQ #$1F,D0 ;NEED DELTA HORIZ MOD 32
|
||
AND.L D0,D6 ;SHIFTCNT:=DELTA HORIZ MOD 32
|
||
NEG.L D6 ;NEGATE FOR USE WITH BFEXTU
|
||
|
||
|
||
;------------------------------------------------------------
|
||
;
|
||
; SET UP SRCLEFT IN A4, ADDR OF LEFTMOST SRC LONG
|
||
; (GOODBYE SRCPIX PTR)
|
||
;
|
||
MOVE ROWBYTES(A4),D0 ;GET SRC ROWBYTES
|
||
AND #NURBMASK,D0 ;MASK OFF FLAG BITS
|
||
MULS SRCV(A6),D0 ;CALC SRC ROWBYTES * FIRST SRC VERT; BAL 02Dec88
|
||
MOVE.L BASEADDR(A4),A4 ;GET START OF SRC BITMAP
|
||
ADD.L D0,A4 ;ADD TO BITMAP START
|
||
SUB.L D6,D1 ;CALC SRCH+SHIFTCNT
|
||
ASR.L #5,D1 ;CONVERT BITS TO LONGS
|
||
ADD.L D1,D1 ;CONVERT LONGS TO WORDS
|
||
ADD.L D1,D1 ;CONVERT WORDS TO BYTES
|
||
ADD.L D1,A4 ;LEAVE SRCLEFT IN A4
|
||
|
||
|
||
;------------------------------------------------------------
|
||
;
|
||
; SET UP DSTLEFT IN A5, ADDR OF LEFTMOST DST LONG
|
||
; (GOODBYE DSTPIX PTR)
|
||
;
|
||
NOTSRC MOVE LEFT(A3),D1 ;GET DST LEFT
|
||
SUB BOUNDS+LEFT(A5),D1 ;CONVERT TO GLOBAL
|
||
EXT.L D1 ;MAKE IT LONG
|
||
LSL.L D4,D1 ;CONVERT PIXELS TO BITS
|
||
MOVE ROWBYTES(A5),D0 ;GET DST ROWBYTES
|
||
AND #NURBMASK,D0 ;MASK OFF FLAG BITS
|
||
MULS DSTV(A6),D0 ;CALC DSTROW * FIRST DST VERT; BAL 02Dec88
|
||
MOVE.L BASEADDR(A5),A5 ;GET START OF DST BITMAP
|
||
ADD.L D0,A5 ;ADD DSTV*DSTROW
|
||
MOVE.L D1,D0 ;COPY DSTLEFT GLOBAL
|
||
ASR.L #5,D1 ;CONVERT BITS TO LONGS
|
||
LSL.L #2,D1 ;CONVERT LONGS TO BYTES
|
||
ADD.L D1,A5 ;GET DSTLEFT IN A5
|
||
|
||
|
||
;------------------------------------
|
||
;
|
||
; SET UP D6 FOR BIG PATTERNS (PATVPOS IN HIGH WORD, PATHPOS IN LOW WORD)
|
||
; SET UP A4 TO POINT TO FIRST SCAN IN PAT TO BE USED
|
||
;
|
||
TST PATROW(A6) ;DOING BIG PATTERN?
|
||
BEQ.S NOTBIGPAT ;=>NO
|
||
MOVE.L EXPAT(A6),A4 ;SRCADDR := EXPANDED PATTERN
|
||
ADD D6,A4 ;ADD PATVPOS TO PATTERN
|
||
SWAP D6 ;SAVE PATVPOS IN HIGH WORD
|
||
MOVE D1,D6 ;GET LOW WORD OF DSTLEFT
|
||
AND D7,D6 ;MASK FOR HORIZ OFFSET INTO PATTERN
|
||
MOVE D6,PATHPOS(A6) ;AND SAVE STARTING HORIZ OFFSET
|
||
|
||
NOTBIGPAT
|
||
;-------------------------------------
|
||
;
|
||
; SET UP 32 BIT LEFTMASK IN D4
|
||
;
|
||
MOVE.L D4,D5 ;SAVE DSTSHIFT FOR LEFTMASK
|
||
MOVEQ #$1F,D2 ;NEED LEFT AND RIGHT MOD 32
|
||
AND.L D2,D0 ;GET DSTH MOD 32
|
||
MOVEQ #-1,D4 ;GET ALL ONES INTO LEFTMASK
|
||
LSR.L D0,D4 ;SHIFT IN ZEROS FROM LEFT
|
||
|
||
|
||
;-------------------------------------
|
||
;
|
||
; SET UP 32 BIT RIGHTMASK IN D5
|
||
; (GOODBYE DSTSHIFT)
|
||
;
|
||
MOVE RIGHT(A3),D1 ;GET DST RIGHT
|
||
SUB LEFT(A3),D1 ;CALC WIDTH
|
||
BLE GOHOME ;QUIT IF WIDTH <= 0
|
||
move.w d1,destPixCnt(a6) ;save for 16/32 bit arith loops <BAL 02Mar89>
|
||
EXT.L D1 ;MAKE WIDTH LONG
|
||
LSL.L D5,D1 ;CONVERT PIXELS TO BITS
|
||
ADD.L D0,D1 ;CALC (DSTH MOD 32) + WIDTH
|
||
|
||
MOVEQ #-1,D5 ;GET ALL ONES IN RIGHTMASK
|
||
AND.L D1,D2 ;GET RIGHT MOD 32
|
||
beq.s @maskOK ;mask ok if width is mult of 32 <1.5> BAL
|
||
LSR.L D2,D5 ;SHIFT IN ZEROS FROM LEFT
|
||
NOT.L D5 ;AND NEGATE TO MAKE RIGHTMASK
|
||
|
||
@maskOK
|
||
;------------------------------------------------
|
||
;
|
||
; CALC TOTAL NUMBER OF DST LONGS-1
|
||
;
|
||
subq.l #1,d1 ;force multiples of 32 to round down <1.5> BAL
|
||
ASR.L #5,D1 ;CALC ((DSTH MOD 32)+WIDTH) DIV 32
|
||
MOVE D1,LONGCNT(A6) ;SAVE AS LONGCNT
|
||
MOVE.L D1,D2 ;COPY FOR BELOW
|
||
|
||
|
||
;------------------------------------------------
|
||
;
|
||
; SET UP SRCBUMP AND DSTBUMP, ASSUMING BUMPING TO THE RIGHT
|
||
;
|
||
ADD.L D1,D1 ;CONVERT LONGS TO WORDS
|
||
ADD.L D1,D1 ;CONVERT WORDS TO BYTES
|
||
MOVE.L D1,D0 ;COPY FOR BELOW
|
||
ADDQ.L #4,D0 ;ADJUST FOR TOTAL BYTES NEEDED
|
||
|
||
|
||
;--------------------------------------------------------------------------
|
||
;
|
||
; IF DRAWING BACKWARDS FROM RIGHT, THEN ADJUST DSTBUMP,
|
||
; ADJUST SRCADDR,DSTADDR TO FIRST LONG,
|
||
; AND SWAP LEFT AND RIGHT MASKS FOR FIRSTMASK AND LASTMASK.
|
||
;
|
||
MOVE D3,A0 ;put hBump (+-4) into A0
|
||
TST D3 ;ARE WE STARTING ON THE LEFT ?
|
||
BPL.S DIROK ;YES, CONTINUE
|
||
NEG.L D0 ;calc -1 * bytesNeeded
|
||
ADD.L D1,A5 ;ADJUST DSTADDR TO RIGHTMOST
|
||
ADD.L D1,A4 ;ADJUST SRCADDR TO RIGHTMOST
|
||
EXG D4,D5 ;FIRSTMASK=RIGHT,LASTMASK=LEFT
|
||
|
||
DIROK MOVE srcRow+2(A6),srcBump(A6)
|
||
SUB D0,srcBump(A6) ;srcBump := srcRow +- bytesBumped
|
||
MOVE dstRow+2(A6),A3
|
||
SUB D0,A3 ;dstBump := dstRow +- bytesBumped
|
||
|
||
|
||
;----------------------------------------------
|
||
;
|
||
; SET UP MODE CASE JUMP IN A1
|
||
;
|
||
; D6 has bit shiftCnt
|
||
; D4 has firstMask
|
||
; D2 has longCnt
|
||
;
|
||
GETMODE MOVE LOCMODE(A6),D0 ;GET TRANSFER MODE
|
||
BNE.S NOTFAST ;BR IF NOT MODE 0
|
||
|
||
|
||
ScaleColorBit EQU 3
|
||
SwapFGBGBit EQU 4
|
||
UseStretchBit EQU 5
|
||
InvertItBit EQU 7
|
||
ColorizeInModeCaseBit EQU 8
|
||
ColorizeInSrcBufBit EQU 9
|
||
|
||
|
||
BTST #ColorizeInModeCaseBit, XLateFlag(a6) ;colorize?
|
||
BNE.S NOTFAST ;no, continue
|
||
|
||
tst.l d7 ;inverting? <KON 6JUN90>
|
||
bne.s NOTFAST ;yes, go slow <KON 6JUN90>
|
||
|
||
move d6,d1 ;get shiftCnt <BAL 26Mar89>
|
||
and #7,d1 ;multiple of 8? <BAL 26Mar89>
|
||
BNE.S NOTFAST ;NO, CONTINUE <BAL 26Mar89>
|
||
|
||
TST D2 ;IS LONGCNT > 0 ? <BAL 26Mar89>
|
||
BLE.S NOTFAST ;NO, CONTINUE <BAL 26Mar89>
|
||
move.w d6,d1 ;get shiftCnt <BAL 26Mar89>
|
||
asr.w #3,d1 ;get src adjustment in bytes<BAL 26Mar89>
|
||
add d1,a4 ;misAlign src <BAL 26Mar89>
|
||
|
||
@Fast MOVE.L BitBltSetup0,A1 ;USE FAST COPY. (get address from trap table)
|
||
TST D3 ;ARE WE BUMPING LEFT TO RIGHT ?
|
||
BPL.s @goFast ;YES, ALL SET
|
||
MOVE.L BitBltLeft0,A1 ;NO, USE BACKWARDS LOOP (get address from trap table)
|
||
@goFast jmp (A1)
|
||
|
||
NOTFAST
|
||
CMP #$20,D0 ;a new arithmetic mode?
|
||
BLO @notHilite ;if 0 to 1F, it is an old mode or old mode + big pat
|
||
|
||
; change bColor to transColor (the unmapped background color) since bColor is used in
|
||
; arithmetic transfer modes to compare with, not to apply to the source
|
||
|
||
MOVE.L transColor(A6),bColor(A6)
|
||
|
||
CMP #$40,D0
|
||
BHS goHome ;an undefined mode; do nothing
|
||
CMP #$30,D0
|
||
BLT.S @arithMode
|
||
CMP #$32,D0 ;source hilite?
|
||
BEQ.S @arithMode ;treat like an arithmetic mode
|
||
CMP #$3A,D0 ;pat hilite?
|
||
BNE goHome ;if not, an undefined mode
|
||
|
||
; if the pattern is black & mode is hilite, then go to fast hilite case
|
||
|
||
TST patRow(A6) ;big or small?
|
||
BNE.S @arithMode ;if big, assume it is not all black
|
||
|
||
;check all longs of the small pattern for blackness
|
||
|
||
MOVE.L BCOLOR(A6),D2 ;check for non-background color <14>
|
||
MOVEQ #$0F,D3 ;16 longs in a pattern
|
||
MOVE.L EXPAT(A6),A1 ;pointer to first long
|
||
@nextLong
|
||
CMP.L (A1)+,D2 ;is it black?
|
||
DBEQ D3,@nextLong ;check all of the pattern for black <14>
|
||
BNE @fastHilite ;if all black, do fast way <14>
|
||
@arithMode
|
||
BTST #3,D0 ;is the pattern bit set?
|
||
BEQ.S @newSource ;if a source mode, set up registers appropriately
|
||
MOVE patRow(A6),D2 ;if patRow contains appropriate value, set big pat bit
|
||
BEQ.S @smallPattern
|
||
|
||
; big pattern case
|
||
|
||
@bigPat
|
||
MOVE.B #1,endSwitch(A6) ;note that this is a big pattern (make it positive)
|
||
SWAP D6
|
||
MOVE D6,patPos(A6) ;set up large pattern vertical offset
|
||
CLR D6 ;clear high word for bit operations
|
||
SWAP D6
|
||
ASL.L #3,D6 ;scale from bytes to bits for bit operation offset
|
||
MOVE.L D6,patOffset(A6) ;set up initial horizontal offset
|
||
|
||
; need to scale patHMask from longs to pixels
|
||
|
||
MOVE dstPix+pixelSize(A6),D3 ;get number of bits in a pixel
|
||
SUBQ #1,D3 ;make into a mask
|
||
NOT D3 ;turn on bits equal to & greater than pixelSize
|
||
ASL #3,D2 ;convert from bytes to bits
|
||
SUBQ #1,D2 ;make it a mask
|
||
AND D3,D2 ;force pixel alignment
|
||
MOVE D2,patHMask(A6) ;save mask
|
||
BRA.S @skipSourceSetup
|
||
|
||
; small pattern case
|
||
|
||
@smallPattern
|
||
CLR.B endSwitch(A6) ;note that this is a small pattern mode
|
||
LEA ([EXPAT,A6],D7*4),A4 ;GET FIRST PATTERN DATA
|
||
MOVE D7,patPos(A6) ;save initial offset as well
|
||
MOVEQ #0,D6
|
||
MOVE.L D6,patOffset(A6)
|
||
MOVE #$001F,patHMask(A6) ;set up patHMask for old patterns (must fit into a long)
|
||
BRA.S @skipSourceSetup
|
||
|
||
; source case
|
||
|
||
@newSource
|
||
ST endSwitch(A6) ;note that this is a source mode (make it negative)
|
||
MOVE #-1,patHMask(A6) ;do not restrict source range if mode is source
|
||
@skipSourceSetup
|
||
AND #$37,D0 ;ignore the pattern info
|
||
|
||
; add, add pin, sub, sub pin, max, min, avg registers and locals set up
|
||
|
||
; D0 dest/mask pixel off. D1 jump table offset D2 pixels in long (or 0 if 1 long)
|
||
; D3 (fg long) D4 (bg long) D5 inverse color table entry size
|
||
; D6 source pixel offset D7 bits per pixel A0 inverse color table
|
||
; A1 color table A2 long bump A3 background pixel
|
||
; A4 (source) A5 (destination)
|
||
; (SP) hbump for a pixel doneMid(A6) flags lastMask(A6) (right mask if left to right)
|
||
; midCount(A6) pixel cnt pixInLong(A6) pixels in a long
|
||
; invSize(A6) inverse color table resolution longCnt(A6) same as D2
|
||
|
||
MOVEQ #32,D2 ;bits in a long
|
||
MOVEQ #0,D7
|
||
MOVE dstPix+pixelSize(A6),D7 ;get number of bits in a pixel
|
||
DIVU D7,D2 ;figure number of pixels in a long
|
||
MOVE D2,pixInLong(A6) ;save for later multiply
|
||
MOVE D2,pixInLong1(A6) ;left 1 based for transparent long case
|
||
MOVEQ #0,D3 ;assume destination offset is 0
|
||
MOVE.L D7,-(SP) ;assume bump is positive
|
||
MOVEQ #32,D1 ;positive long bump for transparent
|
||
move.w a0,hBump(a6) ;save in stack frame for direct loops <BAL>
|
||
CMP #0,A0 ;bumping postive or negative?
|
||
BPL.S @bumpOK
|
||
NEG.L (SP) ;make pixel bump negative
|
||
NEG.L D1 ;make long bump negative
|
||
MOVEQ #32,D3
|
||
SUB D2,D3
|
||
ADD.L D3,D6 ;D6 set to first source pixel position
|
||
@bumpOK
|
||
MOVE.L D1,A2 ;set up long bump for transparent
|
||
MOVE.L D5,lastMask(A6) ;free up a register
|
||
MOVE.L invColor(A6),A0 ;set up pointer to inverse color table in register
|
||
MOVE invSize(A6),D5 ;set up resolution of inverse color table in register
|
||
CLR.B doneMid(A6) ;set up loop/mask flags
|
||
MOVE longCnt(A6),D1 ;0 if only 1 long
|
||
SUBQ #1,D1 ;less 1 more for last long
|
||
MOVE D1,longCnt(A6) ;assume all fits in 1 long
|
||
BMI.S @only1Long ;if only one long, set long count to -1
|
||
MULU pixInLong(A6),D1 ;convert long count to pixel count
|
||
SUBQ #1,D1 ;make count 0 based for DBRA
|
||
MOVE D1,midCount(A6) ;save number of pixels in middle part less first, last masks
|
||
SUBQ #1,D2 ;make count 0 based for DBRAs
|
||
MOVE D2,longCnt(A6) ;save # of pixels in a mask in long count
|
||
@only1Long
|
||
SUBQ #1,pixInLong(A6) ;make count 0 based for DBRAs
|
||
MOVE.l D3,destPixOffset(A6) ;save as a long <08Jan89 BAL>
|
||
|
||
CMP #$30,D0 ;hilite?
|
||
BGT.S @slowHilite ;if so, set up things a little different for hilite
|
||
|
||
if Quicker THEN
|
||
|
||
cmp.w #8,d7 ;is pixelsize >= 8? <1.7> BAL
|
||
bge.s @FastDeepArith ;yes, handle direct arith loops separately <1.7> BAL
|
||
|
||
else
|
||
|
||
cmp.w #16,d7 ;is pixelsize >= 16? <1.7> BAL
|
||
bge.s @FastDeepArith ;yes, handle direct arith loops separately <1.7> BAL
|
||
|
||
endif
|
||
|
||
@notFastArith ; <1.7> BAL
|
||
ADD D0,D0 ;make it a word offset (40 É 4E)
|
||
MOVE D0,D1 ;set up in offset register for jump table, below
|
||
BFEXTU transColor(A6){0:D7},D0 ;get 1 pixel of the background color for transparent
|
||
MOVE.L D0,A3 ;register set up for transparent
|
||
MOVE.l D3,D0 ;set up destination offset
|
||
BRA doMain ;
|
||
@slowHilite
|
||
MOVE.l D3,D0 ;set up destination offset
|
||
MOVEQ #$3C,D1 ;hilite jumptable offset for slow case
|
||
BFEXTU hilitColor(A6){0:D7},D5 ;set up a pixel of the hilite color
|
||
BRA doMain
|
||
|
||
; ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
; highlight registers and locals set up
|
||
; D0 background pixel D5 foreground pixel D7 pixel size A0 foreground long
|
||
; A2 32-pixel size lastMask(A6)
|
||
@fastHilite
|
||
MOVE dstPix+pixelSize(A6),D7 ;width of a pixel
|
||
MOVE.L D5,lastMask(A6) ;free up a register
|
||
MOVE.L hilitColor(A6),A0 ;set up a long of the forecolor
|
||
BFEXTU hilitColor(A6){0:D7},D5 ;set up a pixel of the forecolor
|
||
LEA 32,A2
|
||
SUB D7,A2 ;set up constant equal to long width in bits - pixel width
|
||
BFEXTU transColor(A6){0:D7},D0 ;get 1 pixel of the background color for hilite
|
||
move.w dstShift(a6),d1 ;get shift count
|
||
MOVE.L bHiliteTabPtr,A1 ;get address of table (from trap table)
|
||
ADD.L -4(a1,D1*4),a1 ;select routine based on destination depth
|
||
BRA NEXTROW
|
||
|
||
@FastDeepArith ;enter with mode in d0
|
||
and.w #$7,d0 ;strip arithmetic bit
|
||
beq.s @DirectAvg ;it's blend mode, so check for 50% case
|
||
@modeOK
|
||
if blit32 then ;<14>
|
||
cmp.w #16,d7 ;is dst 16 bits/pixel?
|
||
beq.s @Arith16 ;use alternate table
|
||
|
||
if Quicker THEN
|
||
|
||
blt.s @Arith8 ;use alternate table <1.7> BAL
|
||
|
||
endif
|
||
|
||
move.l bArith32TabPtr,A1 ;point to 32 bit/pixel loops
|
||
add.l (a1,d0*4),a1 ;get modecase based on d0
|
||
_bArith32jmp
|
||
|
||
@Arith16
|
||
move.l bArith16TabPtr,A1 ;point to 16 bit/pixel loops
|
||
add.l (a1,d0*4),a1 ;get modecase based on d0
|
||
MOVE.L D4,D1 ;remember FIRSTMASK
|
||
_bArith16jmp
|
||
endif ;<14>
|
||
|
||
@Arith8
|
||
|
||
if Quicker THEN
|
||
|
||
cmp.w #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
|
||
bne.s @notFastArith ;if not, skip
|
||
tst.l (sp) ;right to left?
|
||
bmi.s @notFastArith ;if so, skip
|
||
|
||
lea bArith8Tab,A1 ;point to 8 bit/pixel loops
|
||
add.l (a1,d0*4),a1 ;get modecase based on d0
|
||
move.l D4,D1 ;remember FIRSTMASK
|
||
bra.s NextRow
|
||
|
||
endif
|
||
|
||
@DirectAvg
|
||
lea weight(a6),a1 ;point to weights
|
||
move.w (a1)+,d1
|
||
cmp.w (a1)+,d1 ;is opColor gray?
|
||
bne.s @modeOK
|
||
cmp.w (a1),d1
|
||
bne.s @modeOK
|
||
addq #1,d1 ;yes, check for gray values of $8000 or $7fff
|
||
and.w #$fffe,d1
|
||
cmp.w #$8000,d1
|
||
bne.s @modeOK
|
||
addq #8,d0 ;use alternate modecase
|
||
bra.s @modeOK
|
||
|
||
@notHilite
|
||
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
|
||
CMP #8,D1 ;pattern?
|
||
BGE.S @checkBigPat ;donÕt worry about color src blt loops if so
|
||
CMP #4,D1 ;xor?
|
||
BEQ.S @0 ;skip if so
|
||
|
||
btst #ColorizeInModeCaseBit, XLateFlag(a6) ;colorize?
|
||
beq.s @0 ;use color loops only if colorize
|
||
ADD #$18,D1 ;use color loops
|
||
@checkBigPat
|
||
TST PATROW(A6) ;BIG PATTERN?
|
||
BEQ.S @0 ;=>NO, CHECK FOR ONE LONG
|
||
ADD #8,D1 ;YES, BUMP INDEX
|
||
|
||
@0
|
||
TST D2 ;IS DST ALL IN ONE LONG ?
|
||
BNE.S DOMAIN ;=>NO, USE FIRST JUMP TABLE
|
||
ADD #$20,D1 ;YES, USE SECOND JUMP TABLE
|
||
DOMAIN LEA BitBltModeTab,A1 ;GET ADDRESS OF MODE TABLE
|
||
MOVE.L 0(A1,D1*2),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.L D4,FIRSTMASK(A6) ;SAVE FIRSTMASK
|
||
MOVE.L FCOLOR(A6),D3 ;GET FGCOLOR
|
||
MOVE.L BCOLOR(A6),D4 ;GET BKCOLOR (transColor if arithmetic mode)
|
||
BRA.S ROWLOOP ;SKIP TO FIRST ROW CASE <SMC 19Jul90>
|
||
|
||
NXTSRC ADD SRCBUMP(A6),A4 ;BUMP SRCPTR TO NEXT ROW
|
||
ADD A3,A5 ;BUMP DSTADDR TO NEXT ROW
|
||
SUBQ #1,HEIGHT(A6) ;DECREMENT ROWCOUNT
|
||
BEQ.S GOHOME ;QUIT IF LAST SRC DONE <SMC 19Jul90>
|
||
|
||
ROWLOOP MOVE.L FIRSTMASK(A6),D1 ;MASK:=FIRSTMASK
|
||
MOVE LONGCNT(A6),D2 ;GET LONGCOUNT
|
||
JMP (A1) ;DO THIS ROW AND COME BACK
|
||
|
||
NXTBIGPAT
|
||
clr.w d6 ;make it unsigned <MCF 29Dec88>
|
||
SWAP D6 ;GET VERT POSITION IN PATTERN
|
||
SUB.l D6,A4 ;GET BACK PAT BASE <MCF 29Dec88>
|
||
ADD PATROW(A6),D6 ;BUMP TO NEXT SCAN
|
||
AND PATVMASK(A6),D6 ;AND MASK WITHIN PATTERN
|
||
ADD.l D6,A4 ;BUMP TO PROPER VERT <MCF 29Dec88>
|
||
SWAP D6 ;SAVE VERTICAL POSITION
|
||
MOVE PATHPOS(A6),D6 ;INIT HORIZONTAL OFFSET
|
||
ADD A3,A5 ;BUMP DSTADDR TO NEXT ROW
|
||
SUBQ #1,HEIGHT(A6) ;DECREMENT ROWCOUNT
|
||
BNE.S ROWLOOP ;LOOP FOR ALL SRCROWS
|
||
GOHOME RTS ;THEN QUIT
|
||
|
||
NXTPAT
|
||
ADD #1,D7 ;BUMP PATTERN SELECTOR
|
||
AND #$0F,D7 ;MOD 16 FOR 16 LONG REPEAT
|
||
MOVE.L ([EXPAT,A6],D7*4),D6 ;GET FIRST PATTERN DATA
|
||
ADD A3,A5 ;BUMP DSTADDR TO NEXT ROW
|
||
SUBQ #1,HEIGHT(A6) ;DECREMENT ROWCOUNT
|
||
BNE.S ROWLOOP ;LOOP FOR ALL SRCROWS
|
||
RTS ;THEN QUIT
|
||
|
||
if blit32 then ;<14>
|
||
NxtNewSrc32
|
||
TST.B endSwitch(A6)
|
||
BEQ.S NxtNewPat
|
||
BPL.S NxtNewBigPat
|
||
ADD SRCBUMP(A6),A4 ;BUMP SRCPTR TO NEXT ROW
|
||
; moveq #0,d6 ;clear out position index <BAL 06Jan89>
|
||
MOVE.L patOffset(A6),d6 ;reset to left edge <BAL 11Mar89>
|
||
BRA.S newCommon
|
||
endif ;<14>
|
||
|
||
NxtNewSrc
|
||
TST.B endSwitch(A6)
|
||
BEQ.S NxtNewPat
|
||
BPL.S NxtNewBigPat
|
||
ADD SRCBUMP(A6),A4 ;BUMP SRCPTR TO NEXT ROW
|
||
BRA.S newCommon
|
||
|
||
NxtNewBigPat
|
||
moveq #0,d0 ;clear out high word <MCF 29Dec88>
|
||
MOVE PatPos(A6),D6 ;GET VERT POSITION IN PATTERN
|
||
SUB.l D6,A4 ;GET BACK PAT BASE <MCF 29Dec88>
|
||
ADD PATROW(A6),D6 ;BUMP TO NEXT SCAN
|
||
AND PATVMASK(A6),D6 ;AND MASK WITHIN PATTERN
|
||
ADD.l D6,A4 ;BUMP TO PROPER VERT <MCF 29Dec88>
|
||
MOVE D6,PatPos(A6) ;SAVE VERTICAL POSITION
|
||
BRA.S newPatCommon
|
||
|
||
NxtNewPat
|
||
MOVE PatPos(A6),D1 ;was in D7; set up from locals for new modes
|
||
ADD #1,D1 ;BUMP PATTERN SELECTOR
|
||
AND #$0F,D1 ;MOD 16 FOR 16 LONG REPEAT
|
||
MOVE D1,PatPos(A6) ;save for new modes
|
||
LEA ([EXPAT,A6],D1*4),A4 ;GET FIRST PATTERN DATA
|
||
newPatCommon
|
||
MOVE.L patOffset(A6),D6 ;initialize 1 pixel to the left of pat if left to right
|
||
newCommon
|
||
CLR.B doneMid(A6) ;set up loop/mask flags
|
||
MOVE.l destPixOffset(A6),D0 ;set up destination pixel offset
|
||
ADD dstRow+2(A6),A5
|
||
SUBQ #1,HEIGHT(A6) ;DECREMENT ROWCOUNT
|
||
BNE.S ROWLOOP ;LOOP FOR ALL SRCROWS
|
||
ADDQ #4,SP ;toss hbump on stack
|
||
RTS ;THEN QUIT
|
||
|
||
;---------------------------------------------------------------;
|
||
; ;
|
||
; INTERFACE TO EACH BITBLT SCANLINE LOOP: ;
|
||
; ;
|
||
; REGISTERS: A0: hBump (+-4) D0: scratch ;
|
||
; A1: MODE CASE JUMP D1: FIRSTMASK.L ;
|
||
; A2: used for loop jmp D2: LONGCNT ;
|
||
; A3: dstBump D3: FG COLOR ;
|
||
; A4: SRCPTR D4: BK COLOR ;
|
||
; A5: DSTPTR D5: LASTMASK.L ;
|
||
; A6: LOCALS D6: SHIFTCNT OR PATTERN ;
|
||
; A7: STACK PTR D7: INVERT OR PAT-SEL ;
|
||
; ;
|
||
;---------------------------------------------------------------;
|
||
|
||
IF 0 THEN
|
||
MODETAB DC.W MAIN0-MODETAB ;0 JUMP TABLE USED IF DST WIDER THAN ONE LONG
|
||
DC.W MAIN1-MODETAB ;2
|
||
DC.W MAIN2-MODETAB ;4
|
||
DC.W MAIN3-MODETAB ;6
|
||
DC.W SETUP8-MODETAB ;8
|
||
DC.W MAIN9-MODETAB ;A
|
||
DC.W SETUP10-MODETAB ;C
|
||
DC.W MAIN11-MODETAB ;E
|
||
DC.W XMAIN8-MODETAB ;10 EXPANDED PATTERN MODES
|
||
DC.W XMAIN9-MODETAB ;12
|
||
DC.W XMAIN10-MODETAB ;14
|
||
DC.W XMAIN11-MODETAB ;16
|
||
|
||
DC.W cMain0-ModeTab ;18 src --> dst (fg black or bg white)
|
||
DC.W cMain1-ModeTab ;1A src OR dst (fg black)
|
||
DC.W Hilite-ModeTab ;1C DST fg <--> bg
|
||
DC.W cMain3-ModeTab ;1E src BIC dst (bg white)
|
||
|
||
DC.W END0-MODETAB ;20 JUMP TABLE USED IF DST FITS IN ONE LONG WIDE
|
||
DC.W END1-MODETAB ;22
|
||
DC.W END2-MODETAB ;24
|
||
DC.W END3-MODETAB ;26
|
||
DC.W LONG8-MODETAB ;28
|
||
DC.W END9-MODETAB ;2A
|
||
DC.W END10-MODETAB ;2C
|
||
DC.W END11-MODETAB ;2E
|
||
DC.W XLONG8-MODETAB ;30 EXPANDED PATTERN MODES
|
||
DC.W XEND9-MODETAB ;32
|
||
DC.W XEND10-MODETAB ;34
|
||
DC.W XEND11-MODETAB ;36
|
||
|
||
DC.W cEnd0-ModeTab ;38 src --> dst (fg black or bg white)
|
||
DC.W cEnd1-ModeTab ;3A src OR dst (fg black)
|
||
DC.W SloHilite-ModeTab ;3C (src, pat is mask) DST fg <--> bg
|
||
DC.W cEnd3-ModeTab ;3E src BIC dst (bg white)
|
||
|
||
DC.W Avg-ModeTab ;40 AVG(SRC, DST, WEIGHT) --> DST
|
||
DC.W AddPin-ModeTab ;42 SRC + DST --> DST (pin to max)
|
||
DC.W AddOver-ModeTab ;44 SRC + DST --> DST (no pin)
|
||
DC.W SubPin-ModeTab ;46 DST - SRC --> DST (pin to min)
|
||
DC.W Transparent-ModeTab ;48 SRC less bg --> DST
|
||
DC.W Max-ModeTab ;4A MAX(SRC, DST) --> DST
|
||
DC.W SubOver-ModeTab ;4C DST - SRC --> DST (no pin)
|
||
DC.W Min-ModeTab ;4E MIN(SRC, DST) --> DST
|
||
ENDIF
|
||
|
||
|
||
ALIGN 4
|
||
|
||
if Quicker then
|
||
|
||
IMPORT bAddOver8
|
||
IMPORT bSubOver8
|
||
IMPORT bAddPin8
|
||
IMPORT bSubPin8
|
||
IMPORT bMax8
|
||
IMPORT bMin8
|
||
IMPORT bAvg8,bTransparent8
|
||
|
||
bArith8Tab
|
||
DC.L bAvg8-bArith8Tab ;18 AVG(SRC, DST, WEIGHT) --> DST
|
||
DC.L bAddPin8-bArith8Tab ;1A SRC + DST --> DST (pin to max)
|
||
DC.L bAddOver8-bArith8Tab ;1C SRC + DST --> DST (no pin)
|
||
DC.L bSubPin8-bArith8Tab ;1E DST - SRC --> DST (pin to min)
|
||
DC.L bTransparent8-bArith8Tab ;20 SRC less bg --> DST
|
||
DC.L bMax8-bArith8Tab ;22 MAX(SRC, DST) --> DST
|
||
DC.L bSubOver8-bArith8Tab ;24 DST - SRC --> DST (no pin)
|
||
DC.L bMin8-bArith8Tab ;26 MIN(SRC, DST) --> DST
|
||
DC.L bAvg8-bArith8Tab ;50% case
|
||
|
||
endif
|
||
|
||
if blit32 then ;<14>
|
||
bArith16Tab
|
||
DC.L bAvg16-bArith16Tab ;18 AVG(SRC, DST, WEIGHT) --> DST
|
||
DC.L bAddPin16-bArith16Tab ;1A SRC + DST --> DST (pin to max)
|
||
DC.L bAddOver16-bArith16Tab ;1C SRC + DST --> DST (no pin)
|
||
DC.L bSubPin16-bArith16Tab ;1E DST - SRC --> DST (pin to min)
|
||
DC.L bTransparent16-bArith16Tab ;20 SRC less bg --> DST
|
||
DC.L bMax16-bArith16Tab ;22 MAX(SRC, DST) --> DST
|
||
DC.L bSubOver16-bArith16Tab ;24 DST - SRC --> DST (no pin)
|
||
DC.L bMin16-bArith16Tab ;26 MIN(SRC, DST) --> DST
|
||
DC.L bAvg16Half-bArith16Tab ;50% case
|
||
|
||
bArith32Tab
|
||
DC.L bAvg32-bArith32Tab ;18 AVG(SRC, DST, WEIGHT) --> DST
|
||
DC.L bAddPin32-bArith32Tab ;1A SRC + DST --> DST (pin to max)
|
||
DC.L bAddOver32-bArith32Tab ;1C SRC + DST --> DST (no pin)
|
||
DC.L bSubPin32-bArith32Tab ;1E DST - SRC --> DST (pin to min)
|
||
DC.L bTransparent32-bArith32Tab ;20 SRC less bg --> DST
|
||
DC.L bMax32-bArith32Tab ;22 MAX(SRC, DST) --> DST
|
||
DC.L bSubOver32-bArith32Tab ;24 DST - SRC --> DST (no pin)
|
||
DC.L bMin32-bArith32Tab ;26 MIN(SRC, DST) --> DST
|
||
DC.L bAvg32Half-bArith32Tab ;50% case
|
||
else ;<14>
|
||
bArith16Tab
|
||
bArith32Tab
|
||
endif ;<14>
|
||
|
||
bHiliteTab ; (1-bit hilite converted to Xor)
|
||
DC.L bHilite-bHiliteTab ; 2-bit
|
||
DC.L bHilite-bHiliteTab ; 4-bit
|
||
DC.L bHilite-bHiliteTab ; 8-bit
|
||
if blit32 then ;<14>
|
||
DC.L bHilite-bHiliteTab ;16-bit
|
||
DC.L bHilite32-bHiliteTab ;32-bit
|
||
endif ;<14>
|
||
|
||
ALIGN Alignment
|
||
|
||
;------------------------------------------------------------
|
||
;
|
||
; OPTIMIZE RIGHT HORIZONTAL SCROLL IF NO SHIFT.
|
||
; ONLY IF MODE 0, BUMPING RIGHT TO LEFT, LONGCNT > 0, AND NO SHIFT.
|
||
;
|
||
bLEFT0 MOVE.L D4,D1 ;MASK:=FIRSTMASK
|
||
MOVE LONGCNT(A6),D2 ;GET LONGCOUNT
|
||
MOVE.L (A4),D0 ;GET SRC FROM BITMAP
|
||
ADD A0,A4 ;BUMP LEFT
|
||
AND.L D1,D0 ;MASK FIRST LONG
|
||
NOT.L D1 ;MAKE NOTMASK
|
||
AND.L (A5),D1 ;GET DATA FROM DST
|
||
OR.L D1,D0 ;MERGE WITH SRC DATA
|
||
MOVE.L D0,(A5) ;PUT RESULT TO DST
|
||
ADD A0,A5 ;BUMP LEFT
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BEQ.S LLast0 ;BR IF NO UNMASKED LONGS
|
||
SUB A0,A4 ;GET READY FOR PRE-DECREMENT
|
||
SUB A0,A5 ;GET READY FOR PRE-DECREMENT
|
||
BRA.S LONE0 ;GO MOVE A LONG
|
||
LTWO0 MOVE.L -(A4),-(A5) ;MOVE A LONG LONG
|
||
LONE0 MOVE.L -(A4),-(A5) ;MOVE ANOTHER LONG
|
||
SUB #2,D2 ;ANY UNMASKED LONGS LEFT IN ROW ?
|
||
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
|
||
|
||
LLast0 MOVE.L D5,D1 ;copy last mask
|
||
MOVE.L (A4),D0 ;get last long of src from bitmap
|
||
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
|
||
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 TO DST
|
||
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
|
||
|
||
ADD SRCBUMP(A6),A4 ;BUMP SRCPTR TO NEXT ROW
|
||
ADD A3,A5 ;BUMP DSTADDR TO NEXT ROW
|
||
SUBQ #1,HEIGHT(A6) ;DECREMENT ROWCOUNT
|
||
BNE.S bLEFT0 ;LOOP FOR ALL SRCROWS
|
||
BRA.S GOHOME ;THEN QUIT
|
||
|
||
|
||
;------------------------------------------------------------
|
||
;
|
||
; <14> All new fast scrolling routine that takes advantage of the
|
||
; MOVE16 instruction on the 68040 when possible.
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = JUMPA d0 = SCRATCH
|
||
; a1 = JUMPB d1 = <LONGS>,SCRATCH
|
||
; a2 = JUMPC d2 = LEFTLONGS,SCRATCH
|
||
; a3 = JUMPD d3 = RIGHTLONGS,QUADBLOCKS
|
||
; a4 = <SRCPTR> d4 = <LEFTMASK>
|
||
; a5 = <DSTPTR> d5 = <RIGHTMASK>
|
||
; a6 = locals d6 = SRCWID
|
||
; a7 = sp d7 = DSTWID
|
||
;-------------------------------------------------------
|
||
bSETUP0
|
||
|
||
OFFSET EQU 38
|
||
|
||
MOVE SRCBUMP(A6),D6 ;get srcwid into a register
|
||
MOVE A3,D7 ;put dstwid into a more useful register
|
||
MOVEQ #$F,D1 ;get useful mask
|
||
|
||
ADDQ #1,D2 ;make longs width one based
|
||
|
||
CMP.B #cpu68040,cpuFlag ;is this an '040 or greater machine?
|
||
BLT.S @normal ;no, use normal case
|
||
|
||
CMP #8,D2 ;are at least 8 longs being moved?
|
||
BLT.S @normal ;no, use normal case
|
||
|
||
; <02OCT92 SAH> <24>
|
||
; we need to make sure that everything is long aligned. If srcPtr, dstPtr, srcWid or dstWid
|
||
; are word aligned, we need to go slow...
|
||
|
||
move.w a4,d0 ;get copy of src address <02OCT92 SAH> <24>
|
||
move.w a5,d3 ;get copy of dst address <02OCT92 SAH> <24>
|
||
or.w d3,d0 ;or in with src address <02OCT92 SAH> <24>
|
||
or.w d6,d0 ;or in srcWid <02OCT92 SAH> <24>
|
||
or.w d7,d0 ;or in dstWid <02OCT92 SAH> <24>
|
||
and.w #3,d0 ;and all four with long align mask <02OCT92 SAH> <24>
|
||
bne.s @normal ;if any one is word aligned, go slow <02OCT92 SAH> <24>
|
||
|
||
MOVE D2,D3 ;are srcwid and dstwid both quadlong multiples?
|
||
LSL #2,D3 ; ((srcwid + (longs*4)) | (dstwid + (longs*4))) & 0x000F == 0)
|
||
MOVE D6,D0
|
||
ADD D3,D0
|
||
ADD D7,D3
|
||
OR D0,D3
|
||
AND D1,D3
|
||
BNE.S @normal ;no, use normal case
|
||
|
||
MOVE.L A4,D3 ;do srcptr and dstptr have same quadlong phase?
|
||
SUB.L A5,D3 ; (srcptr - dstptr) & 0x000F == 0)
|
||
AND D1,D3
|
||
BEQ.S @fast ;yes, use fast case
|
||
|
||
@normal MOVE D2,D3 ;count = longs
|
||
MOVEQ #0,D0
|
||
ADDQ.L #1,D4 ;count += (leftmask++ == -1)
|
||
ADDX D0,D3
|
||
ADDQ.L #1,D5 ;count += (rightmask++ == -1)
|
||
ADDX D0,D3
|
||
MOVE.L D5,D0 ;JUMPD = &@right + (rightmask ? (@right - @rmask) : 0)
|
||
BEQ.S @0
|
||
MOVEQ #-OFFSET,D0
|
||
@0: LEA (@right,D0.W),A3
|
||
MOVE.L A3,A1 ;JUMPB = JUMPD
|
||
SUBQ #3,D3 ;if ((count -= 3) < 0)
|
||
BMI.S @5 ; goto @5
|
||
AND D3,D1 ;JUMPB = &@mv4 - (count % 16) * 2
|
||
NEG D1
|
||
LEA (@mv4,D1.W*2),A1
|
||
LSR #4,D3 ;count /= 16;
|
||
BRA.S @5
|
||
|
||
@fast MOVEQ #-1,D0
|
||
MOVE.W A4,D3 ;leftlongs = (-srcptr % 16) / 4
|
||
NEG D3
|
||
AND.W D3,D1
|
||
LSR.W #2,D1
|
||
SUB D1,D2 ;longs -= leftlongs
|
||
ADDQ.L #1,D4 ;leftlongs -= (leftmask++ != -1)
|
||
ADDX D0,D1
|
||
BGE.S @1 ;if (leftlongs < 0)
|
||
MOVEQ #3,D1 ; leftlongs = 3
|
||
SUBQ #4,D2 ; longs -= 4
|
||
@1:
|
||
MOVEQ #3,D3 ;rightlongs = longs & 0x03
|
||
AND D2,D3
|
||
SUB D3,D2 ;longs -= rightlongs
|
||
ADDQ.L #1,D5 ;rightlongs -= (rightmask++ != -1)
|
||
ADDX D0,D3
|
||
BGE.S @2 ;if (rightlongs < 0)
|
||
MOVEQ #3,D3 ; rightlongs = 3
|
||
SUBQ #4,D2 ; longs -= 4
|
||
@2:
|
||
NEG D3 ;JUMPD = &@right + (-rightlongs * 2)
|
||
LEA (@right,D3.W*2),A3
|
||
TST.L D5 ;if (rightmask - 1 != -1)
|
||
BEQ.S @3
|
||
SUB #OFFSET,A3 ; JUMPD -= @right - @rmask;
|
||
@3:
|
||
MOVE.L A3,A2 ;JUMPC = JUMPD
|
||
LSR #2,D2 ;longs /= 4
|
||
BEQ.S @4 ;if (longs)
|
||
SUBQ #1,D2 ; longs--
|
||
MOVE D2,D3 ; quadblocks = longs / 8
|
||
LSR #3,D3
|
||
AND #$07,D2 ; JUMPC = &@mv16 + (-(longs & 0x7) * 4)
|
||
NEG D2
|
||
LEA (@mv16,D2.W*4),A2
|
||
@4:
|
||
MOVE.L A2,A1 ;JUMPB = JUMPC
|
||
MOVE D1,D2 ;if (leftlongs != 0)
|
||
BEQ.S @5
|
||
NEG D2 ; JUMPB = &@left - (leftlongs * 2)
|
||
LEA (@left,D2.W*2),A1
|
||
@5: MOVE.L A1,A0 ;JUMPA = JUMPB
|
||
TST.L D4 ;if (leftmask - 1 != -1)
|
||
BEQ.S @6
|
||
LEA @lmask,A0 ; JUMPA = &@lmask
|
||
@6: SUBQ.L #1,D4 ;++leftmask
|
||
SUBQ.L #1,D5 ;++rightmask
|
||
MOVE.L HEIGHT(A6),D1 ;(put height into high word)
|
||
MOVE D3,D1 ;(set up initial quadblocks count)
|
||
nop ;finish any write in pipeline (may not need this one)
|
||
JMP (A0)
|
||
|
||
MACRO ;*** REMOVE WHEN ASSEMBLER KNOWS ABOUT MOVE16
|
||
myMOVE16 ;*** REMOVE WHEN ASSEMBLER KNOWS ABOUT MOVE16
|
||
DC.L $F624D000 ;*** REMOVE WHEN ASSEMBLER KNOWS ABOUT MOVE16
|
||
ENDM ;*** REMOVE WHEN ASSEMBLER KNOWS ABOUT MOVE16
|
||
|
||
ALIGN Alignment
|
||
|
||
@lmask MOVE.L (A4)+,D0 ;get long of src
|
||
MOVE.L (A5),D2 ;get long of dst
|
||
EOR.L D2,D0 ;
|
||
AND.L D4,D0 ;splice src and dst together through leftmask
|
||
EOR.L D2,D0 ;
|
||
MOVE.L D0,(A5)+ ;save result to dst
|
||
nop ;finish any write in pipeline
|
||
JMP (A1) ;go copy partial or full quadlong blocks
|
||
|
||
MOVE.L (A4)+,(A5)+ ;copy partial left quadlong block
|
||
MOVE.L (A4)+,(A5)+
|
||
MOVE.L (A4)+,(A5)+
|
||
@left nop ;finish any write in pipeline
|
||
JMP (A2) ;go copy quadlong blocks
|
||
|
||
@mv256 myMOVE16 ;MOVE16 (A4)+,(A5)+ ;copy 32 longs
|
||
myMOVE16 ;MOVE16 (A4)+,(A5)+
|
||
myMOVE16 ;MOVE16 (A4)+,(A5)+
|
||
myMOVE16 ;MOVE16 (A4)+,(A5)+
|
||
myMOVE16 ;MOVE16 (A4)+,(A5)+ ;copy 16 longs
|
||
myMOVE16 ;MOVE16 (A4)+,(A5)+
|
||
myMOVE16 ;MOVE16 (A4)+,(A5)+
|
||
@mv16 myMOVE16 ;MOVE16 (A4)+,(A5)+ ;copy 4 longs
|
||
DBRA D1,@mv256 ;dec counter and go do another 32 longs
|
||
JMP (A3) ;go finish right edge of scanline
|
||
|
||
@mv64 MOVE.L (A4)+,(A5)+ ;copy 16 longs
|
||
MOVE.L (A4)+,(A5)+
|
||
MOVE.L (A4)+,(A5)+
|
||
MOVE.L (A4)+,(A5)+
|
||
MOVE.L (A4)+,(A5)+
|
||
MOVE.L (A4)+,(A5)+
|
||
MOVE.L (A4)+,(A5)+
|
||
MOVE.L (A4)+,(A5)+
|
||
MOVE.L (A4)+,(A5)+ ;copy 8 longs
|
||
MOVE.L (A4)+,(A5)+
|
||
MOVE.L (A4)+,(A5)+
|
||
MOVE.L (A4)+,(A5)+
|
||
MOVE.L (A4)+,(A5)+
|
||
MOVE.L (A4)+,(A5)+
|
||
MOVE.L (A4)+,(A5)+
|
||
@mv4 MOVE.L (A4)+,(A5)+ ;copy 1 long
|
||
DBRA D1,@mv64 ;dec count and go do another 16 longs
|
||
JMP (A3) ;go finish right edge of scanline
|
||
|
||
MOVE.L (A4)+,(A5)+ ;copy partial right quadlong block
|
||
MOVE.L (A4)+,(A5)+
|
||
MOVE.L (A4)+,(A5)+
|
||
@rmask MOVE.L (A4)+,D0 ;get long of src
|
||
MOVE.L (A5),D2 ;get long of dst
|
||
EOR.L D2,D0
|
||
AND.L D5,D0 ;splice src and dst together through rightmask
|
||
EOR.L D2,D0
|
||
MOVE.L D0,(A5)+ ;save result to dst
|
||
ADD D6,A4 ;bump srcptr by (srcbump - (longcnt * 4))
|
||
ADD D7,A5 ;bump dstptr by (dstbump - (longcnt * 4))
|
||
MOVE D3,D1 ;restore quadblock count
|
||
SWAP D1 ;swap linecount into low word
|
||
SUBQ #1,D1 ;decrement linecount
|
||
BEQ GoHome ;leave if zero
|
||
SWAP D1 ;swap linecount out of low word
|
||
nop ;finish any write in pipeline
|
||
JMP (A0) ;go do another line
|
||
|
||
MOVE.L (A4)+,(A5)+ ;copy partial right quadlong block
|
||
MOVE.L (A4)+,(A5)+
|
||
MOVE.L (A4)+,(A5)+
|
||
@right ADD D6,A4 ;bump srcptr by (srcbump - (longcnt * 4))
|
||
ADD D7,A5 ;bump dstptr by (dstbump - (longcnt * 4))
|
||
MOVE D3,D1 ;restore quadblock count
|
||
SWAP D1 ;swap linecount into low word
|
||
SUBQ #1,D1 ;decrement linecount
|
||
BEQ.S GoHome ;leave if zero
|
||
SWAP D1 ;swap linecount out of low word
|
||
nop ;finish any write in pipeline
|
||
JMP (A0) ;go do another line
|
||
|
||
IF @right - @rmask - OFFSET THEN
|
||
AERROR '¥¥¥ Offset assumption is bad ¥¥¥'
|
||
ENDIF
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 0 or 4: SRC --> DST
|
||
;
|
||
; <20Jul90 SMC>
|
||
; Split loop into shift and no shift cases, and separated
|
||
; out the blitting of the longs between the left and right
|
||
; masks in both cases.
|
||
;
|
||
bEND0 AND.L D5,D1 ;firstmask = firstmask AND lastmask
|
||
MOVE.L D1,FIRSTMASK(A6) ;make it stick for remaining scan lines
|
||
bMAIN0 LEA bMAIN0A,A1 ;get address of no shift case
|
||
TST.L D6 ;check if shift = 0
|
||
BNE.S @1 ;if not, go blit
|
||
LEA bMAIN0B,A1 ;if shift != 0, use shift case
|
||
@1: JMP (A1) ;jump to blit loop
|
||
;
|
||
; Shifted srcCopy/notSrcCopy case
|
||
;
|
||
bEND0A MOVE.L D5,D1 ;mask = lastmask
|
||
bMAIN0A BFEXTU (A4){D6:0},D0 ;get long of src from bitmap
|
||
ADD A0,A4 ;bump srcptr left or right
|
||
EOR.L D7,D0 ;invert src if mode bit 2 set
|
||
AND.L D1,D0 ;mask src
|
||
NOT.L D1 ;form notmask
|
||
AND.L (A5),D1 ;get dest data
|
||
OR.L D1,D0 ;splice with src data
|
||
MOVE.L D0,(A5) ;put result into dst
|
||
ADD A0,A5 ;bump dstptr left or right
|
||
SUB #1,D2 ;dec long count
|
||
BEQ bEND0A ;do last long with lastmask
|
||
BLT NXTSRC ;loop back for next scan line
|
||
bMID0A BFEXTU (A4){D6:0},D0 ;get long of src from bitmap
|
||
ADD A0,A4 ;bump srcptr left or right
|
||
EOR.L D7,D0 ;invert src if mode bit 2 set
|
||
MOVE.L D0,(A5) ;put result into dest
|
||
ADD A0,A5 ;bump dstptr left or right
|
||
SUB #1,D2 ;dec long count
|
||
BGT bMID0A ;branch if unmasked longs left
|
||
BRA bEND0A ;do last long with lastmask
|
||
;
|
||
; No shift srcCopy/notSrcCopy case
|
||
;
|
||
bEND0B MOVE.L D5,D1 ;mask = lastmask
|
||
bMAIN0B MOVE.L (A4),D0 ;get long of src from bitmap
|
||
ADD A0,A4 ;bump srcptr left or right
|
||
EOR.L D7,D0 ;invert src if mode bit 2 set
|
||
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 to dst
|
||
ADD A0,A5 ;bump dstptr left or right
|
||
SUB #1,D2 ;dec long count
|
||
BEQ bEND0B ;do last long with lastmask
|
||
BLT NXTSRC ;loop back for next scan line
|
||
bMID0B MOVE.L (A4),D0 ;get long of src from bitmap
|
||
ADD A0,A4 ;bump srcptr left or right
|
||
EOR.L D7,D0 ;invert src if mode bit 2 set
|
||
MOVE.L D0,(A5) ;put result into dest
|
||
ADD A0,A5 ;bump dstptr left or right
|
||
SUB #1,D2 ;dec long count
|
||
BGT bMID0B ;branch if unmasked longs left
|
||
BRA bEND0B ;do last long with lastmask
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 1 or 5: SRC OR DST --> DST
|
||
;
|
||
; <20Jul90 SMC>
|
||
; Split loop into shift and no shift cases.
|
||
;
|
||
bEND1 AND.L D5,D1 ;firstmask = firstmask AND lastmask
|
||
MOVE.L D1,FIRSTMASK(A6) ;make it stick for remaining scan lines
|
||
bMAIN1 LEA bMAIN1A,A1 ;get address of no shift case
|
||
TST.L D6 ;check if shift = 0
|
||
BNE.S @1 ;if not, go blit
|
||
LEA bMAIN1B,A1 ;if shift != 0, use shift case
|
||
@1: JMP (A1) ;jump to blit loop
|
||
;
|
||
; Shifted srcOr/notSrcOr case
|
||
;
|
||
bEND1A MOVE.L D5,D1 ;mask = lastmask
|
||
bMAIN1A BFEXTU (A4){D6:0},D0 ;get src from bitmap with shift
|
||
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
|
||
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
||
AND.L D1,D0 ;MASK SRC
|
||
OR.L D0,(A5) ;OR SRC INTO DST
|
||
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
|
||
MOVEQ #-1,D1 ;FLUSH MASK
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BGT bMAIN1A ;LOOP TILL LAST LONG
|
||
BEQ bEND1A ;DO LAST LONG WITH LASTMASK
|
||
BRA NXTSRC ;LOOP BACK FOR NEXT ROW
|
||
;
|
||
; No shift srcOr/notSrcOr case
|
||
;
|
||
bEND1B MOVE.L D5,D1 ;mask = lastmask
|
||
bMAIN1B MOVE.L (A4),D0 ;get src from bitmap without shift
|
||
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
|
||
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
||
AND.L D1,D0 ;MASK SRC
|
||
OR.L D0,(A5) ;OR SRC INTO DST
|
||
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
|
||
MOVEQ #-1,D1 ;FLUSH MASK
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BGT bMAIN1B ;LOOP TILL LAST LONG
|
||
BEQ bEND1B ;DO LAST LONG WITH LASTMASK
|
||
BRA NXTSRC ;LOOP BACK FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 2 or 6: SRC XOR DST --> DST
|
||
;
|
||
; <20Jul90 SMC>
|
||
; Split loop into shift and no shift cases.
|
||
;
|
||
bEND2 AND.L D5,D1 ;firstmask = firstmask AND lastmask
|
||
MOVE.L D1,FIRSTMASK(A6) ;make it stick for remaining scan lines
|
||
bMAIN2 LEA bMAIN2A,A1 ;get address of no shift case
|
||
TST.L D6 ;check if shift = 0
|
||
BNE.S @1 ;if not, go blit
|
||
LEA bMAIN2B,A1 ;if shift != 0, use shift case
|
||
@1: JMP (A1) ;jump to blit loop
|
||
;
|
||
; Shifted srcXor/notSrcXor case
|
||
;
|
||
bEND2A MOVE.L D5,D1 ;mask = lastmask
|
||
bMAIN2A BFEXTU (A4){D6:0},D0 ;get src from bitmap with shift
|
||
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
|
||
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
||
AND.L D1,D0 ;MASK SRC
|
||
EOR.L D0,(A5) ;XOR SRC INTO DST
|
||
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
|
||
MOVEQ #-1,D1 ;FLUSH MASK
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BGT bMAIN2A ;LOOP TILL LAST LONG
|
||
BEQ bEND2A ;DO LAST LONG WITH LASTMASK
|
||
BRA NXTSRC ;LOOP BACK FOR NEXT ROW
|
||
;
|
||
; No shift srcXor/notSrcXor case
|
||
;
|
||
bEND2B MOVE.L D5,D1 ;mask = lastmask
|
||
bMAIN2B MOVE.L (A4),D0 ;get src from bitmap without shift
|
||
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
|
||
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
||
AND.L D1,D0 ;MASK SRC
|
||
EOR.L D0,(A5) ;XOR SRC INTO DST
|
||
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
|
||
MOVEQ #-1,D1 ;FLUSH MASK
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BGT bMAIN2B ;LOOP TILL LAST LONG
|
||
BEQ bEND2B ;DO LAST LONG WITH LASTMASK
|
||
BRA NXTSRC ;LOOP BACK FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 3 or 7: SRC BIC DST --> DST
|
||
;
|
||
; <20Jul90 SMC>
|
||
; Split loop into shift and no shift cases.
|
||
;
|
||
bEND3 AND.L D5,D1 ;firstmask = firstmask AND lastmask
|
||
MOVE.L D1,FIRSTMASK(A6) ;make it stick for remaining scan lines
|
||
bMAIN3 LEA bMAIN3A,A1 ;get address of no shift case
|
||
TST.L D6 ;check if shift = 0
|
||
BNE.S @1 ;if not, go blit
|
||
LEA bMAIN3B,A1 ;if shift != 0, use shift case
|
||
@1: JMP (A1) ;jump to blit loop
|
||
;
|
||
; Shifted srcBic/notSrcBic case
|
||
;
|
||
bEND3A MOVE.L D5,D1 ;mask = lastmask
|
||
bMAIN3A BFEXTU (A4){D6:0},D0 ;get src from bitmap with shift
|
||
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
|
||
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
||
AND.L D1,D0 ;MASK SRC
|
||
NOT.L D0 ;INVERT SRC
|
||
AND.L D0,(A5) ;BIT CLEAR SRC INTO DST
|
||
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
|
||
MOVEQ #-1,D1 ;FLUSH MASK
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BGT bMAIN3A ;LOOP TILL LAST LONG
|
||
BEQ bEND3A ;DO LAST LONG WITH LASTMASK
|
||
BRA NXTSRC ;LOOP BACK FOR NEXT ROW
|
||
;
|
||
; No shift srcBic/notSrcBic case
|
||
;
|
||
bEND3B MOVE.L D5,D1 ;mask = lastmask
|
||
bMAIN3B MOVE.L (A4),D0 ;get src from bitmap without shift
|
||
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
|
||
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
||
AND.L D1,D0 ;MASK SRC
|
||
NOT.L D0 ;INVERT SRC
|
||
AND.L D0,(A5) ;BIT CLEAR SRC INTO DST
|
||
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
|
||
MOVEQ #-1,D1 ;FLUSH MASK
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BGT bMAIN3B ;LOOP TILL LAST LONG
|
||
BEQ bEND3B ;DO LAST LONG WITH LASTMASK
|
||
BRA NXTSRC ;LOOP BACK FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 0 or 4: SRC --> DST (foreground black or background white)
|
||
;
|
||
; <20Jul90 SMC>
|
||
; Split loop into three cases. Shifted and colorized srcCopy,
|
||
; shifted and colorized notSrcCopy, and not shifted but colorized
|
||
; srcCopy/notSrcCopy. In all three cases, the blitting of the longs
|
||
; between the left and right masks done separately for speed.
|
||
;
|
||
; The shifted, colorized srcCopy and notSrcCopy cases were split so
|
||
; that the notmask register was free to speed up colorizing. The
|
||
; old loop used the stack which cost two reads and two writes.
|
||
;
|
||
bcEND0 AND.L D5,D1 ;firstmask = firstmask AND lastmask
|
||
MOVE.L D1,FIRSTMASK(A6) ;make it stick for remaining scan lines
|
||
bcMAIN0 EOR.L D4,D3 ;munge FG and BK colors once for rest of scan lines
|
||
LEA bcMAIN0C,A1 ;get address of no shift case
|
||
TST.L D6 ;check if shift = 0
|
||
BEQ.S @1 ;is so, go blit
|
||
LEA bcMAIN0B,A1 ;get address of shifted notSrcCopy case
|
||
TST.L D7 ;is this the not mask true?
|
||
BNE.S @1 ;yes, go blit
|
||
LEA bcMAIN0A,A1 ;get address of shifted srcCopy case
|
||
@1: JMP (A1) ;go blitting
|
||
;
|
||
; Shifted and colorized srcCopy case
|
||
;
|
||
bcEND0A MOVE.L D5,D1 ;mask = lastmask
|
||
bcMAIN0A
|
||
BFEXTU (A4){D6:0},D0 ;get long of src from bitmap with shift
|
||
ADD A0,A4 ;bump srcptr left or right
|
||
AND.L D3,D0 ;apply FG color to ones of src
|
||
EOR.L D4,D0 ;apply BK color to zeroes of src
|
||
MOVE.L (A5),D7 ;get long from dest
|
||
EOR.L D7,D0 ;splice colorized src into dst
|
||
AND.L D1,D0 ; using first or last mask
|
||
EOR.L D7,D0
|
||
MOVE.L D0,(A5) ;move result to dst
|
||
ADD A0,A5 ;bump dstptr left or right
|
||
SUB #1,D2 ;dec long count
|
||
BEQ bcEND0A ;DO LAST LONG WITH LASTMASK
|
||
BLT NXTSRC ;LOOP BACK FOR MORE
|
||
bcMID0A BFEXTU (A4){D6:0},D0 ;get long of src from bitmap with shift
|
||
ADD A0,A4 ;bump srcptr left or right
|
||
AND.L D3,D0 ;apply FG color to ones of src
|
||
EOR.L D4,D0 ;apply BK color to zeroes of src
|
||
MOVE.L D0,(A5) ;move result to dst
|
||
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BGT bcMID0A ;BR IF UNMASKED LONGS LEFT
|
||
BRA bcEND0A ;DO LAST LONG WITH LASTMASK
|
||
;
|
||
; Shifted and colorized notSrcCopy case
|
||
;
|
||
bcEND0B MOVE.L D5,D1 ;mask = lastmask
|
||
bcMAIN0B
|
||
BFEXTU (A4){D6:0},D0 ;get long of src from bitmap with shift
|
||
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
|
||
NOT.L D0 ;INVERT SRC IF MODE BIT 2 SET
|
||
AND.L D3,D0 ;apply FG color to ones of src
|
||
EOR.L D4,D0 ;apply BK color to zeroes of src
|
||
MOVE.L (A5),D7 ;get long from dest
|
||
EOR.L D7,D0 ;splice colorized src into dst
|
||
AND.L D1,D0 ; using first or last mask
|
||
EOR.L D7,D0
|
||
MOVE.L D0,(A5) ;move result to dst
|
||
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BEQ bcEND0B ;DO LAST LONG WITH LASTMASK
|
||
BLT NXTSRC ;LOOP BACK FOR MORE
|
||
bcMID0B BFEXTU (A4){D6:0},D0 ;get long of src from bitmap with shift
|
||
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
|
||
NOT.L D0 ;INVERT SRC IF MODE BIT 2 SET
|
||
AND.L D3,D0 ;apply FG color to ones of src
|
||
EOR.L D4,D0 ;apply BK color to zeroes of src
|
||
MOVE.L D0,(A5) ;move result to dst
|
||
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BGT bcMID0B ;BR IF UNMASKED LONGS LEFT
|
||
BRA bcEND0B ;DO LAST LONG WITH LASTMASK
|
||
;
|
||
; No shift but colorized srcCopy/notSrcCopy case
|
||
;
|
||
bcEND0C MOVE.L D5,D1 ;mask = lastmask
|
||
bcMAIN0C
|
||
MOVE.L (A4),D0 ;get long of src from bitmap without shift
|
||
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
|
||
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
||
AND.L D3,D0 ;apply FG color to ones of src
|
||
EOR.L D4,D0 ;apply BK color to zeroes of src
|
||
MOVE.L (A5),D6 ;get long from dest
|
||
EOR.L D6,D0 ;splice colorized src into dst
|
||
AND.L D1,D0 ; using first or last mask
|
||
EOR.L D6,D0
|
||
MOVE.L D0,(A5) ;move result to dst
|
||
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BEQ bcEND0C ;DO LAST LONG WITH LASTMASK
|
||
BLT NXTSRC ;LOOP BACK FOR MORE
|
||
bcMID0C MOVE.L (A4),D0 ;get long of src from bitmap without shift
|
||
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
|
||
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
||
AND.L D3,D0 ;apply FG color to ones of src
|
||
EOR.L D4,D0 ;apply BK color to zeroes of src
|
||
MOVE.L D0,(A5) ;move result to dst
|
||
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BGT bcMID0C ;BR IF UNMASKED LONGS LEFT
|
||
BRA bcEND0C ;DO LAST LONG WITH LASTMASK
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 1 or 5: SRC OR DST --> DST (foreground black)
|
||
; MODE 3 or 7: SRC BIC DST --> DST (background white)
|
||
;
|
||
; <20Jul90 SMC>, <18Oct90 SMC> <12>
|
||
; Folded BIC loop into OR loop by making forecolor equal backcolor.
|
||
; Split OR loop into two cases. Shifted and colorized srcOr/notSrcOr, and
|
||
; colorized, not shifted srcOr/notSrcOr. In both cases, the blitting of
|
||
; the longs between the left and right masks are done separately for speed.
|
||
;
|
||
bcEND3 MOVE.L D4,D3
|
||
bcEND1 AND.L D5,D1 ;firstmask = firstmask AND lastmask
|
||
MOVE.L D1,FIRSTMASK(A6) ;make it stick for remaining scan lines
|
||
BRA.S bcMAIN1
|
||
bcMAIN3 MOVE.L D4,D3
|
||
bcMAIN1 LEA bcMAIN1B,A1 ;get address of no shift case
|
||
TST.L D6 ;check if shift = 0
|
||
BEQ.S bcMAIN1B ;is so, go blit
|
||
LEA bcMAIN1A,A1 ;get address of shift case
|
||
JMP (A1) ;go blitting
|
||
;
|
||
; Colorized, shifted srcOr/notSrcOr case
|
||
;
|
||
bcEND1A MOVE.L D5,D1 ;mask = lastmask
|
||
bcMAIN1A
|
||
BFEXTU (A4){D6:0},D0 ;get src from bitmap with shift
|
||
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
|
||
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
||
MOVE.L (A5),D4 ;get long of dst
|
||
AND.L D1,D0 ;combine src and left or right mask
|
||
NOT.L D0 ;reverse the mask
|
||
EOR.L D3,D4 ;splice colorized src into dst
|
||
AND.L D0,D4 ; using mask
|
||
EOR.L D3,D4
|
||
MOVE.L D4,(A5) ;move result to dst
|
||
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
|
||
MOVEQ #-1,D1 ;FLUSH MASK
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BGT bcMAIN1A ;LOOP TILL LAST LONG
|
||
BEQ bcEND1A ;DO LAST LONG WITH LASTMASK
|
||
BRA NXTSRC ;LOOP BACK FOR NEXT ROW
|
||
;
|
||
; Colorized, not shifted srcOr/notSrcOr case
|
||
;
|
||
bcEND1B MOVE.L D5,D1 ;mask = lastmask
|
||
bcMAIN1B
|
||
MOVE.L (A4),D0 ;get src from bitmap without shift
|
||
ADD A0,A4 ;BUMP SRCPTR LEFT OR RIGHT
|
||
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
||
MOVE.L (A5),D4 ;get long of dst
|
||
AND.L D1,D0 ;combine src and left or right mask
|
||
NOT.L D0 ;reverse the mask
|
||
EOR.L D3,D4 ;splice colorized src into dst
|
||
AND.L D0,D4 ; using mask
|
||
EOR.L D3,D4
|
||
MOVE.L D4,(A5) ;move result to dst
|
||
ADD A0,A5 ;BUMP DSTPTR LEFT OR RIGHT
|
||
MOVEQ #-1,D1 ;FLUSH MASK
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BGT bcMAIN1B ;LOOP TILL LAST LONG
|
||
BEQ bcEND1B ;DO LAST LONG WITH LASTMASK
|
||
BRA NXTSRC ;LOOP BACK FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-----------------------------------------------------------
|
||
;
|
||
; OPTIMIZE MODE 8 OR 12 IF DST FITS IN ONE LONG (VERT LINES ETC)
|
||
;
|
||
; <13> fix as seen in QDciPatchROM.a <sm 6/9/92>stb
|
||
|
||
bLONG8 AND.L alphaMask(A6),D1 ;clip left mask with alpha mask <13>
|
||
MOVE HEIGHT(A6),D3 ;GET NUMBER OF ROWS
|
||
move.l exPat(a6),a4 ;get pattern pointer <1.5> BAL
|
||
lea (a4,d7*4),a2 ;point into pattern <1.5> BAL
|
||
addq #4,a3 ;convert dstBump to rowBytes <1.5> BAL
|
||
SUBQ #1,D3 ;MAKE 0 BASED FOR DBRA LOOP
|
||
AND.L D5,D1 ;COMBINE LEFT AND RIGHT MASKS
|
||
MOVE.L D1,D5 ;COPY COMBINED MASK
|
||
|
||
MOVE.L A4,A1 ;pointer to first long <1.5> BAL
|
||
MOVE.L (A1)+,D0 ;get first long of pattern <1.5> BAL
|
||
MOVEQ #$0E,D2 ;15-1 longs remaining <1.5> BAL
|
||
@nextLong
|
||
CMP.L (A1)+,D0 ;is it solid? <1.5> BAL
|
||
DBNE D2,@nextLong ;check all of the pattern for equality
|
||
BEQ.S SolidVert ;if all same, do fast way <1.5> BAL
|
||
|
||
NOT.L D5 ;FORM NOTMASK
|
||
beq.s Long32 ;no need to mask <1.5> BAL
|
||
LONG8 AND.L D1,D6 ;MASK EXTRA PATTERN TO ZEROS
|
||
MOVE.L (A5),D0 ;GET DST DATA
|
||
AND.L D5,D0 ;AND WITH NOTMASK
|
||
OR.L D6,D0 ;MERGE WITH SRC DATA
|
||
MOVE.L D0,(A5) ;PUT RESULT TO DST
|
||
ADD A3,A5 ;BUMP DSTPTR TO NEXT ROW
|
||
ADD #1,D7 ;BUMP PATTERN SELECTOR
|
||
AND #$0F,D7 ;MOD 16 FOR 16 LONG REPEAT
|
||
MOVE.L (a4,D7*4),D6 ;GET PATTERN DATA <1.5> BAL
|
||
DBRA D3,LONG8 ;LOOP ALL ROWS
|
||
BRA GOHOME
|
||
|
||
LONG32 MOVE.L (a2)+,(A5) ;PUT pattern TO DST <1.5> BAL
|
||
ADD A3,A5 ;BUMP DSTPTR TO NEXT ROW <1.5> BAL
|
||
ADD #1,D7 ;BUMP PATTERN SELECTOR <1.5> BAL
|
||
AND #$0F,D7 ;MOD 16 FOR 16 LONG REPEAT <1.5> BAL
|
||
bne.s @patOK ; <1.5> BAL
|
||
MOVE.L a4,a2 ;reload pattern pointer <1.5> BAL
|
||
@patOK DBRA D3,LONG32 ;LOOP ALL ROWS <1.5> BAL
|
||
BRA GOHOME ; <1.5> BAL
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-----------------------------------------------------------
|
||
;
|
||
; OPTIMIZE MODE 8 OR 12 IF DST FITS IN ONE LONG AND SOLID PATTERN
|
||
;
|
||
; Enter with pattern in D0
|
||
;
|
||
SolidVert
|
||
NOT.L D5 ;FORM NOTMASK <1.5> BAL
|
||
beq.s @Long32 ;no need to mask <1.5> BAL
|
||
AND.L D1,D0 ;MASK EXTRA PATTERN TO ZEROS <1.5> BAL
|
||
@LONG8 MOVE.L (A5),D2 ;GET DST DATA <1.5> BAL
|
||
AND.L D5,D2 ;AND WITH NOTMASK <1.5> BAL
|
||
OR.L D0,D2 ;MERGE WITH SRC DATA <1.5> BAL
|
||
MOVE.L D2,(A5) ;PUT RESULT TO DST <1.5> BAL
|
||
ADD A3,A5 ;BUMP DSTPTR TO NEXT ROW <1.5> BAL
|
||
DBRA D3,@LONG8 ;LOOP ALL ROWS <1.5> BAL
|
||
BRA GOHOME ; <1.5> BAL
|
||
|
||
@LONG32 MOVE.L D0,(A5) ;PUT pattern TO DST <1.5> BAL
|
||
ADD A3,A5 ;BUMP DSTPTR TO NEXT ROW <1.5> BAL
|
||
DBRA D3,@LONG32 ;LOOP ALL ROWS <1.5> BAL
|
||
BRA GOHOME ; <1.5> BAL
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;------------------------------------------------------------
|
||
;
|
||
; MODE 8 OR 12: PATTERN --> DST (FILLING AREAS, DRAWING LINES)
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = moveTablePtr d0 = scratch
|
||
; a1 = ~firstMask d1 = scratch
|
||
; a2 = ~lastMask d2 = rowCount
|
||
; a3 = hBump d3 = blockCount
|
||
; a4 = patterPtr d4 = firstMask
|
||
; a5 = dstPtr d5 = lastMask
|
||
; a6 = locals d6 = pattern data
|
||
; a7 = sp d7 = pattern selector
|
||
;-------------------------------------------------------
|
||
|
||
; <13> Start of alpha channel changes as seen in QDciPatchROM.a <sm 6/9/92>stb
|
||
|
||
bSETUP8 TST.B alphaMode(A6) ;drawing in alpha mode?
|
||
BEQ.S @bSETUP8 ;no, use normal loop
|
||
MOVE.L alphaMask(A6),D3 ;get alpha mask
|
||
AND.L D3,D1 ;AND ALPHA WITH LEFT MASK
|
||
MOVE.L D1,FIRSTMASK(A6) ;SAVE THAT RESULT
|
||
AND.L D3,D5 ;AND ALPHA WITH RIGHT MASK
|
||
BRA.S @bMAIN8 ;jump into alpha loop
|
||
|
||
@bEND8 AND.L D5,D1 ;MASK:=MASK AND LASTMASK
|
||
@bMAIN8 MOVE.L D1,D0 ;COPY MASK
|
||
AND.L D6,D1 ;GET MASKED PATTERN
|
||
NOT.L D0 ;REVERSE MASK
|
||
AND.L (A5),D0 ;GET NOT MASKED DST
|
||
OR.L D1,D0 ;COMBINE PATTERN AND DST
|
||
MOVE.L D0,(A5)+ ;PUT RESULT TO DST
|
||
MOVE.L D3,D1 ;FLUSH MASK
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BGT @bMAIN8 ;LOOP TILL LAST LONG
|
||
BEQ @bEND8 ;DO LAST LONG WITH LASTMASK
|
||
@NXTPAT ADD #1,D7 ;BUMP PATTERN SELECTOR
|
||
AND #$0F,D7 ;MOD 16 FOR 16 LONG REPEAT
|
||
MOVE.L ([EXPAT,A6],D7*4),D6 ;GET FIRST PATTERN DATA
|
||
ADD A3,A5 ;BUMP DSTADDR TO NEXT ROW
|
||
SUBQ #1,HEIGHT(A6) ;DECREMENT ROWCOUNT
|
||
BEQ.S GOHOME ;LOOP FOR ALL SRCROWS
|
||
MOVE.L FIRSTMASK(A6),D1 ;MASK:=FIRSTMASK
|
||
MOVE LONGCNT(A6),D2 ;GET LONGCOUNT
|
||
BRA.S @bMAIN8 ;GO NEXT LINE
|
||
|
||
; <13> End of alpha channel changes
|
||
|
||
@bSETUP8
|
||
;
|
||
; <02OCT92 SAH> <24>
|
||
; We first need to check if we can go fast. There are several conditions for this:
|
||
; 1. At least 16 longs are being moved (otherwise slow case is faster)
|
||
; 2. The destination address is long aligned (we cannot handle word aligned addresses).
|
||
; 3. hBump is a long multiple (same reason as 3).
|
||
; 4. The dst maintains the same quadlong phase across all scanlines
|
||
; 5. The pattern is constant.
|
||
;
|
||
|
||
cmp.w #16,d2 ; must have at least 16 to make fast case worthwhile (cond 1)
|
||
blt.s @slowCase ; less, so go slow
|
||
|
||
cmp.b #cpu68040,cpuFlag ;is this an '040 or greater machine?
|
||
blt.s @slowCase ; less, so go slow
|
||
|
||
move.w a5,d0 ; get copy of dst address (cond 2 and 3) <02OCT92 SAH> <24>
|
||
move.w a3,d3 ; get copy of hBump <02OCT92 SAH> <24>
|
||
or.w d3,d0 ; or it in <02OCT92 SAH> <24>
|
||
and.w #3,d0 ; check if hBump and dst address are long aligned <02OCT92 SAH> <24>
|
||
bne.s @slowCase ; either one is word aligned, so go slow <02OCT92 SAH> <24>
|
||
|
||
move.w a3,d3 ; get a copy of the hBump (cond 4) <02OCT92 SAH> <24>
|
||
move.w d2,d0 ; get the number of longs to write <02OCT92 SAH> <24>
|
||
addq.w #1,d0 ; make it a one based count <02OCT92 SAH> <24>
|
||
lsl.w #2,d0 ; make it bytes <02OCT92 SAH> <24>
|
||
add.w d0,d3 ; add the number of bytes to write <02OCT92 SAH> <24>
|
||
and.w #$f,d3 ; is the quadlong phase the same? <02OCT92 SAH> <24>
|
||
bne.s @slowCase ; no, so go slow <02OCT92 SAH> <24>
|
||
|
||
move.l expat(a6),a0 ; get start of expanded pattern (cond 5)
|
||
move.l (a0),d4 ; get first pattern long (d4 not used yet)
|
||
moveq #15,d0 ; get count
|
||
@0 cmp.l (a0)+,d4 ; compare
|
||
dbne d0,@0 ; continue if still equal
|
||
beq fastBSETUP8 ; if == 0, then pattern is solid and we can go fast
|
||
|
||
@slowCase move.w d2,d3 ; get count of longwords to move
|
||
move.l d1,d4 ; get copy of firstMask
|
||
not.l d1 ; invert for dst masking
|
||
movea.l d1,a1 ; setup inverted firstMask
|
||
bne.s @hasFirstMask ; if mask is valid, use it
|
||
addq.w #1,d3 ; if no mask, copy 1 extra long
|
||
@hasFirstMask
|
||
move.l d5,d0 ; get copy of lastMask
|
||
not.l d0 ; invert for dst masking
|
||
movea.l d0,a2 ; setup inverted lastMask
|
||
bne.s @hasLastMask ; if mask is valid, use it
|
||
addq.w #1,d3 ; if no mask, copy 1 extra long
|
||
@hasLastMask
|
||
movea.l expat(a6),a4 ; get pointer to base of patterns
|
||
lea 4(a4,d7.w*4),a4 ; point to next pattern longword
|
||
move.w d7,d0 ; use pattern index as bit number
|
||
moveq.l #1,d7 ; use a rotating bit as the pattern counter
|
||
lsl.w d0,d7 ; position the bit to reflect the pattern index
|
||
move.w Height(a6),d2 ; get row count
|
||
subq.w #1,d2 ; zero based for DBRA
|
||
|
||
lea @blockLoopEnd,a0; point to starting address in block move table
|
||
subq.w #1,d3 ; not counting the last long
|
||
beq.s @rowStart ; if no longs in the middle, start now
|
||
|
||
moveq.l #$0F,d0 ; mask for initial move count
|
||
and.w d3,d0 ; get the number of longs to move first
|
||
neg.w d0 ; index backwards
|
||
lea -4(a0,d0.w*2),a0; setup the starting address (-4 to bypass DBRA)
|
||
lsr.w #4,d3 ; setup number of additional blocks of 16 to move
|
||
bra.s @rowStart ; start now
|
||
|
||
@resetPat moveq.l #1,d7 ; reset the pattern selector
|
||
suba.w #16*4,a4 ; point back to first pattern
|
||
@rowLoop move.l (a4)+,d6 ; get source long from pattern
|
||
@rowStart move.l a1,d1 ; get mask for first long of dest
|
||
beq.s @no1stMask ; if no masking, just store the source
|
||
move.l d6,d0 ; get pattern data
|
||
and.l d4,d0 ; mask first long
|
||
and.l (a5),d1 ; get first long of dest data
|
||
or.l d1,d0 ; merge with src data
|
||
move.l d0,(a5)+ ; put result to dest
|
||
@no1stMask
|
||
move.w d3,d0 ; setup block loop counter
|
||
jmp (a0) ; jump into the move table
|
||
|
||
@blockLoop move.l d6,(a5)+ ; move 16 longs
|
||
move.l d6,(a5)+ ; move 15 longs
|
||
move.l d6,(a5)+ ; move 14 longs
|
||
move.l d6,(a5)+ ; move 13 longs
|
||
move.l d6,(a5)+ ; move 12 longs
|
||
move.l d6,(a5)+ ; move 11 longs
|
||
move.l d6,(a5)+ ; move 10 longs
|
||
move.l d6,(a5)+ ; move 9 longs
|
||
move.l d6,(a5)+ ; move 8 longs
|
||
move.l d6,(a5)+ ; move 7 longs
|
||
move.l d6,(a5)+ ; move 6 longs
|
||
move.l d6,(a5)+ ; move 5 longs
|
||
move.l d6,(a5)+ ; move 4 longs
|
||
move.l d6,(a5)+ ; move 3 longs
|
||
move.l d6,(a5)+ ; move 2 longs
|
||
move.l d6,(a5)+ ; move 1 long
|
||
dbra d0,@blockLoop ; move remaining blocks of 16 longs
|
||
@blockLoopEnd
|
||
|
||
move.l a2,d0 ; get mask for last long of dest
|
||
beq.s @noLstMask ; if no masking, just store the source
|
||
and.l (a5),d0 ; get last long of dest data
|
||
and.l d5,d6 ; mask last long
|
||
or.l d6,d0 ; merge with src data
|
||
move.l d0,(a5)+ ; put result to dest
|
||
@noLstMask
|
||
adda.w a3,a5 ; update dest address
|
||
add.w d7,d7 ; shift the pattern index
|
||
dbeq d2,@rowLoop ; loop through all source rows
|
||
dbne d2,@resetPat ; reset pattern and loop
|
||
bra.s GoHome ; then quit
|
||
|
||
;
|
||
; <25SEP92 SAH> Fast pattern case for constant patterns. Can only be installed on 040
|
||
; machines when VM is off.
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = left block d0 = scratch
|
||
; a1 = middle block d1 = scratch
|
||
; a2 = right block d2 = scratch
|
||
; a3 = middle src d3 = blockCount
|
||
; a4 = hBump d4 = firstMask
|
||
; a5 = dstPtr d5 = lastMask
|
||
; a6 = locals d6 = pattern data
|
||
; a7 = sp d7 = stack offset / rowCount
|
||
;-------------------------------------------------------
|
||
|
||
|
||
; macro for MOVE16 (A3)+,(A5)+
|
||
MACRO ;*** REMOVE WHEN ASSEMBLER KNOWS ABOUT MOVE16
|
||
aMOVE16 ;*** REMOVE WHEN ASSEMBLER KNOWS ABOUT MOVE16
|
||
DC.L $F623D000 ;*** REMOVE WHEN ASSEMBLER KNOWS ABOUT MOVE16
|
||
ENDM ;*** REMOVE WHEN ASSEMBLER KNOWS ABOUT MOVE16
|
||
|
||
fastBSETUP8 move.w a3,a4 ; put hBump in more consistant register
|
||
move.w d2,d3 ; get count of longwords to move
|
||
subq.w #1,d3 ; make one based count of number of middle longs
|
||
move.l d1,d4 ; get copy of firstMask
|
||
movea.l expat(a6),a3 ; get ptr to pattern table
|
||
move.l (a3),d6 ; get source long from pattern
|
||
|
||
; find offset for left edge alignment
|
||
moveq #0,d2 ; init left count to zero
|
||
lea @left,a0 ; get end of left edge table
|
||
moveq #4,d0 ; figure out the number of left longs 4 - ((a5 + 4) & 0xf)
|
||
add.w a5,d0 ; (a5 + 4)
|
||
and.w #$f,d0 ; & 0xf
|
||
lsr.w #2,d0 ; convert to longs
|
||
beq.s @leftAligned ; left is already aligned
|
||
moveq #4,d1 ;
|
||
sub.w d0,d1 ; 4 - ...
|
||
sub.w d1,d3 ; subtract the longs we do on the left edge
|
||
neg.w d1 ; we want to look backwards
|
||
lea (a0,d1*2),a0 ; get offset
|
||
@leftAligned
|
||
|
||
; find offset for right edge alignment
|
||
lea @right,a2 ; get end of right edge table
|
||
moveq #3,d2 ; get a mask for right edge count
|
||
and.w d3,d2 ; get the odd longs
|
||
neg.w d2 ; offset backwards
|
||
lea (a2,d2.w*2),a2 ; get start of blit
|
||
|
||
; now figure out how much to move in the middle
|
||
lea @blockLoopEnd,a1 ; assume we have nothing to do
|
||
lsr.w #2,d3 ; each move16 moves 4 longs
|
||
moveq #$3,d0 ; get mask for first time through (each loop does 4 move16's)
|
||
and.w d3,d0 ; and find the number to do
|
||
neg.w d0 ; negate the count
|
||
lea (a1,d0.w*4),a1 ; offset back into table
|
||
lsr.w #2,d3 ; convert remaining longs to groups of four
|
||
|
||
; now create our stack buffer for move16
|
||
move.w sp,d0 ; get copy of stack
|
||
and.w #$f,d0 ; get quadlong mask
|
||
add.w #64,d0 ; add 64 bytes for base table
|
||
move.w d0,d7 ; save how much we subtracted...
|
||
swap d7 ; in high word of d7
|
||
sub.w d0,sp ; subtract room on stack
|
||
moveq #7,d0 ; we want to write 16 longs (we do two at a time)
|
||
move.l sp,a3 ; get start of table
|
||
@0 move.l d6,(a3)+ ; fill table
|
||
move.l d6,(a3)+ ; fill table
|
||
dbra d0,@0
|
||
|
||
move.w Height(a6),d7 ; get row count
|
||
subq.w #1,d7 ; zero based for DBRA
|
||
|
||
@rowLoop move.w d3,d2 ; setup block loop counter (for move16)
|
||
move.l sp,a3 ; restore block base
|
||
move.l (a5),d1 ; get a long of dst
|
||
move.l d6,d0 ; get a long of src
|
||
eor.l d1,d0 ;
|
||
and.l d4,d0 ; mask first long
|
||
eor.l d1,d0 ;
|
||
move.l d0,(a5)+ ; put result to dest
|
||
jmp (a0) ; jumpt to start of left edge
|
||
|
||
move.l d6,(a5)+ ; long 1
|
||
move.l d6,(a5)+ ; long 2
|
||
move.l d6,(a5)+ ; long 3
|
||
@left nop ; clear pipeline
|
||
jmp (a1) ; jump into middle block
|
||
|
||
@blockLoop aMOVE16 ; move16 (a3)+,(a5)+ ; move 16 longs
|
||
aMOVE16 ; move16 (a3)+,(a5)+ ; move 12 longs
|
||
aMOVE16 ; move16 (a3)+,(a5)+ ; move 8 longs
|
||
aMOVE16 ; move16 (a3)+,(a5)+ ; move 4 longs
|
||
@blockLoopEnd
|
||
move.l sp,a3 ; restore block base
|
||
dbra d2,@blockLoop ; move remaining blocks of 16 longs
|
||
|
||
jmp (a2) ; jump into right edge block
|
||
|
||
move.l d6,(a5)+ ; long 1
|
||
move.l d6,(a5)+ ; long 2
|
||
move.l d6,(a5)+ ; long 3
|
||
@right
|
||
move.l d6,d0 ; get a long of src
|
||
move.l (a5),d1 ; get a long of dst
|
||
eor.l d1,d0 ;
|
||
and.l d5,d0 ; splice with mask
|
||
eor.l d1,d0 ;
|
||
move.l d0,(a5)+ ; put result to dest
|
||
|
||
adda.w a4,a5 ; update dest address
|
||
dbra d7,@rowLoop ; loop through all source rows
|
||
swap d7 ; get stack offset back
|
||
add.w d7,sp ; restore stack
|
||
rts ; then quit
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 9 OR 13: PATTERN OR DST --> DST
|
||
;
|
||
bEND9 AND.L D5,D1 ;MASK:=MASK AND LASTMASK
|
||
bMAIN9 AND.L D6,D1 ;MASK PATTERN
|
||
MOVE.L D1,D0 ;COPY MASKED PATTERN
|
||
AND.L D3,D0 ;APPLY FG COLOR TO MASKED PATTERN
|
||
NOT.L D1 ;GET NOT MASKED PATTERN
|
||
AND.L (A5),D1 ;USE TO PUNCH OUT DST
|
||
OR.L D1,D0 ;COMBINE SRC AND DST
|
||
MOVE.L D0,(A5)+ ;PUT RESULT TO DST
|
||
MOVEQ #-1,D1 ;FLUSH MASK
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BGT bMAIN9 ;LOOP TILL LAST LONG
|
||
BEQ bEND9 ;DO LAST LONG WITH LASTMASK
|
||
BRA NXTPAT ;LOOP BACK FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-----------------------------------------------------------
|
||
;
|
||
; OPTIMIZE MODE 10 OR 14 IF DST FITS IN ONE LONG (XOR VERT LINES)
|
||
;
|
||
bEnd10 MOVE HEIGHT(A6),D3 ;GET NUMBER OF ROWS <1.5> BAL
|
||
move.l exPat(a6),a4 ;get pattern pointer <1.5> BAL
|
||
lea (a4,d7*4),a2 ;point into pattern <1.5> BAL
|
||
addq #4,a3 ;convert dstBump to rowBytes <1.5> BAL
|
||
SUBQ #1,D3 ;MAKE 0 BASED FOR DBRA LOOP <1.5> BAL
|
||
AND.L D5,D1 ;COMBINE LEFT AND RIGHT MASKS <1.5> BAL
|
||
|
||
@LONG MOVE.L (a2)+,d6 ;get next pattern long <1.5> BAL
|
||
AND.L D1,D6 ;MASK EXTRA PATTERN TO ZEROS <1.5> BAL
|
||
EOR.L D6,(A5) ;XOR PATTERN INTO DST <1.5> BAL
|
||
ADD A3,A5 ;BUMP DSTPTR TO NEXT ROW <1.5> BAL
|
||
ADD #1,D7 ;BUMP PATTERN SELECTOR <1.5> BAL
|
||
AND #$0F,D7 ;MOD 16 FOR 16 LONG REPEAT <1.5> BAL
|
||
bne.s @patOK ; <1.5> BAL
|
||
MOVE.L a4,a2 ;reload pattern pointer <1.5> BAL
|
||
@patOK DBRA D3,@LONG ;LOOP ALL ROWS <1.5> BAL
|
||
BRA GOHOME ; <1.5> BAL
|
||
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;------------------------------------------------------------
|
||
;
|
||
; MODE 10 OR 14: PATTERN XOR DST --> DST (INVERTING AREAS, XOR LINES)
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = moveTablePtr d0 = scratch
|
||
; a1 = d1 = scratch
|
||
; a2 = expat d2 = rowCount
|
||
; a3 = hBump d3 = blockCount
|
||
; a4 = patterPtr d4 = firstMask
|
||
; a5 = dstPtr d5 = lastMask
|
||
; a6 = locals d6 = pattern data
|
||
; a7 = sp d7 = pattern selector
|
||
;-------------------------------------------------------
|
||
|
||
|
||
bSETUP10 move.w d2,d3 ; get count of longwords to move
|
||
move.l d1,d4 ; get copy of firstMask
|
||
movea.l expat(a6),a2 ; get pointer to base of patterns
|
||
lea 4(a2,d7.w*4),a4 ; point to next pattern longword
|
||
move.w d7,d0 ; use pattern index as bit number
|
||
moveq.l #1,d7 ; use a rotating bit as the pattern counter
|
||
lsl.w d0,d7 ; position the bit to reflect the pattern index
|
||
move.w Height(a6),d2 ; get row count
|
||
subq.w #1,d2 ; zero based for DBRA
|
||
|
||
lea @blockLoopEnd,a0; point to starting address in block move table
|
||
subq.w #1,d3 ; not counting the last long
|
||
beq.s @rowStart ; if no longs in the middle, start now
|
||
|
||
moveq.l #$0F,d0 ; mask for initial move count
|
||
and.w d3,d0 ; get the number of longs to move first
|
||
neg.w d0 ; index backwards
|
||
lea -4(a0,d0.w*2),a0; setup the starting address (-4 to bypass DBRA)
|
||
lsr.w #4,d3 ; setup number of additional blocks of 16 to move
|
||
bra.s @rowStart ; start now
|
||
|
||
@resetPat moveq.l #1,d7 ; reset the pattern selector
|
||
movea.l a2,a4 ; point back to first pattern
|
||
@rowLoop move.l (a4)+,d6 ; get source long from pattern
|
||
@rowStart move.l d6,d0 ; get pattern data
|
||
and.l d4,d0 ; mask first long
|
||
eor.l d0,(a5)+ ; xor pattern into dest
|
||
|
||
move.w d3,d0 ; setup block loop counter
|
||
jmp (a0) ; jump into the move table
|
||
|
||
@blockLoop eor.l d6,(a5)+ ; move 16 longs
|
||
eor.l d6,(a5)+ ; move 15 longs
|
||
eor.l d6,(a5)+ ; move 14 longs
|
||
eor.l d6,(a5)+ ; move 13 longs
|
||
eor.l d6,(a5)+ ; move 12 longs
|
||
eor.l d6,(a5)+ ; move 11 longs
|
||
eor.l d6,(a5)+ ; move 10 longs
|
||
eor.l d6,(a5)+ ; move 9 longs
|
||
eor.l d6,(a5)+ ; move 8 longs
|
||
eor.l d6,(a5)+ ; move 7 longs
|
||
eor.l d6,(a5)+ ; move 6 longs
|
||
eor.l d6,(a5)+ ; move 5 longs
|
||
eor.l d6,(a5)+ ; move 4 longs
|
||
eor.l d6,(a5)+ ; move 3 longs
|
||
eor.l d6,(a5)+ ; move 2 longs
|
||
eor.l d6,(a5)+ ; move 1 long
|
||
dbra d0,@blockLoop ; move remaining blocks of 16 longs
|
||
@blockLoopEnd
|
||
|
||
and.l d5,d6 ; mask last long
|
||
eor.l d6,(a5)+ ; xor pattern into dest
|
||
|
||
adda.w a3,a5 ; update dest address
|
||
add.w d7,d7 ; shift the pattern index
|
||
dbeq d2,@rowLoop ; loop through all source rows
|
||
dbne d2,@resetPat ; reset pattern and loop
|
||
bra.s GoHome ; then quit
|
||
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 11 OR 15: PATTERN BIC DST --> DST
|
||
;
|
||
bEND11 AND.L D5,D1 ;MASK:=MASK AND LASTMASK
|
||
bMAIN11 AND.L D6,D1 ;MASK PATTERN
|
||
MOVE.L D1,D0 ;COPY MASKED PATTERN
|
||
AND.L D4,D0 ;APPLY BK COLOR TO MASKED PATTERN
|
||
NOT.L D1 ;GET NOT MASKED PATTERN
|
||
AND.L (A5),D1 ;PUNCH OUT DST
|
||
OR.L D1,D0 ;COMBINE SRC AND DST
|
||
MOVE.L D0,(A5)+ ;PUT RESULT TO DST
|
||
MOVEQ #-1,D1 ;FLUSH MASK
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BGT bMAIN11 ;LOOP TILL LAST LONG
|
||
BEQ bEND11 ;DO LAST WITH LASTMASK
|
||
BRA NXTPAT ;LOOP BACK FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; EXPANDED PATTERN MODES
|
||
;
|
||
;-----------------------------------------------------------
|
||
;
|
||
; OPTIMIZE MODE 8 OR 12 IF DST FITS IN ONE LONG (VERT LINES ETC)
|
||
;
|
||
; <13> fix as seen in QDciPatchROM.a <sm 6/9/92>stb
|
||
|
||
bXLONG8 AND.L alphaMask(A6),D1;clip mask with alpha mask <13>
|
||
MOVE PATROW(A6),A0 ;GET PATTERN ROWBYTES
|
||
MOVE PATVMASK(A6),D2 ;GET MASK FOR VERT
|
||
MOVE HEIGHT(A6),D3 ;GET NUMBER OF ROWS
|
||
SUBQ #1,D3 ;MAKE 0 BASED FOR DBRA LOOP
|
||
addq #4,a3 ;convert dstBump to rowBytes <1.5> BAL
|
||
AND.L D5,D1 ;COMBINE LEFT AND RIGHT MASKS
|
||
MOVE.L D1,D5 ;COPY COMBINED MASK
|
||
ADD D6,A4 ;ADD PATHPOS TO BASE
|
||
clr.w D6 ;treat as unsigned <1.5> BAL
|
||
SWAP D6 ;GET PATVPOS <1.5> BAL
|
||
SUB.l D6,A4 ;BACK UP TO BASE OF PATTERN <1.5> BAL
|
||
NOT.L D5 ;FORM NOTMASK <1.5> BAL
|
||
beq.s xLong32 ;no reason to mask <1.5> BAL
|
||
|
||
XLONG MOVE.L 0(A4,D6),D7 ;GET A LONG OF PATTERN
|
||
AND.L D1,D7 ;MASK EXTRA PATTERN TO ZEROS
|
||
MOVE.L (A5),D0 ;GET DST DATA
|
||
AND.L D5,D0 ;AND WITH NOTMASK
|
||
OR.L D7,D0 ;MERGE WITH SRC DATA
|
||
MOVE.L D0,(A5) ;PUT RESULT TO DST
|
||
ADD A3,A5 ;BUMP DSTPTR TO NEXT ROW
|
||
ADD A0,D6 ;BUMP PATTERN TO NEXT ROW
|
||
AND D2,D6 ;WRAP IF PAST END OF PATTERN
|
||
DBRA D3,XLONG ;LOOP ALL ROWS
|
||
BRA GOHOME
|
||
|
||
XLONG32 MOVE.L 0(A4,D6),(A5) ;PUT pattern TO DST <1.5> BAL
|
||
ADD A3,A5 ;BUMP DSTPTR TO NEXT ROW <1.5> BAL
|
||
ADD A0,D6 ;BUMP PATTERN TO NEXT ROW <1.5> BAL
|
||
AND D2,D6 ;WRAP IF PAST END OF PATTERN <1.5> BAL
|
||
DBRA D3,XLONG32 ;LOOP ALL ROWS <1.5> BAL
|
||
BRA GOHOME ; <1.5> BAL
|
||
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 8 OR 12: PATTERN --> DST (FILLING AREAS, DRAWING LINES)
|
||
; PATTERN ALREADY HAS COLOR IN IT, SO NONE IS ADDED
|
||
; Doesn't handle the fits in 1 long case (see above) <1.5> BAL
|
||
; Loops for all scanlines then goes home <1.5> BAL
|
||
;
|
||
|
||
; <13> Start of alpha channel changes from QDciPatchROM.a <sm 6/9/92>stb
|
||
|
||
bXMAIN8 TST.B alphaMode(A6) ;drawing in alpha mode?
|
||
BEQ bXMAIN8G ;no, use normal loop
|
||
MOVE.L alphaMask(A6),D3 ;get alpha mask
|
||
AND.L D3,D1 ;AND ALPHA WITH LEFT MASK
|
||
MOVE.L D1,FIRSTMASK(A6) ;SAVE THAT RESULT
|
||
AND.L D3,D5 ;AND ALPHA WITH RIGHT MASK
|
||
BRA.S @bX8 ;jump into alpha loop
|
||
|
||
ALIGN Alignment
|
||
|
||
@bXEND8 AND.L D5,D1 ;MASK:=MASK AND LASTMASK
|
||
@bX8 MOVE.L 0(A4,D6),D4 ;GET PATTERN
|
||
ADDQ #4,D6 ;BUMP TO NEXT LONG OF PATTERN
|
||
AND D7,D6 ;WRAP WHEN PATTERN REPEATS
|
||
MOVE.L (A5),D0 ;GET DST
|
||
EOR.L D0,D4 ;APPLY DST TO PATTERN
|
||
AND.L D1,D4 ;MASK OFF EDGE
|
||
EOR.L D0,D4 ;REAPPLY DST
|
||
MOVE.L D4,(A5)+ ;PUT RESULT TO DST
|
||
MOVE.L D3,D1 ;FLUSH MASK
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BEQ @bXEND8 ;DO LAST LONG WITH LASTMASK
|
||
BLT.S @nxtBigPat ;BUMP TO NEXT PATTERN ROW
|
||
SUBQ #1,D2 ;DEC LONG COUNT
|
||
|
||
NOT.L D3 ;REVERSE ALPHA MASK
|
||
@alpha MOVE.L 0(A4,D6),D4 ;GET PATTERN
|
||
ADDQ #4,D6 ;BUMP TO NEXT LONG OF PATTERN
|
||
AND D7,D6 ;WRAP WHEN PATTERN REPEATS
|
||
MOVE.L (A5),D0 ;GET DST
|
||
EOR.L D4,D0 ;APPLY PATTERN TO DST
|
||
AND.L D3,D0 ;MASK WITH ALPHA MASK
|
||
EOR.L D4,D0 ;REAPPLY PATTERN
|
||
MOVE.L D0,(A5)+ ;PUT RESULT TO DST
|
||
DBRA D2,@alpha ;DEC LONG COUNT
|
||
NOT.L D3 ;UNREVERSE ALPHA MASK
|
||
BRA.S @bXEND8 ;DO LAST LONG WITH LASTMASK
|
||
|
||
@nxtBigPat
|
||
clr.w d6 ;make it unsigned
|
||
SWAP D6 ;GET VERT POSITION IN PAT
|
||
SUB.l D6,A4 ;GET BACK PAT BASE
|
||
ADD PATROW(A6),D6 ;BUMP TO NEXT SCAN
|
||
AND PATVMASK(A6),D6 ;AND MASK WITHIN PATTERN
|
||
ADD.l D6,A4 ;BUMP TO PROPER VERT
|
||
SWAP D6 ;SAVE VERTICAL POSITION
|
||
MOVE PATHPOS(A6),D6 ;INIT HORIZONTAL OFFSET
|
||
ADD A3,A5 ;BUMP DSTADDR TO NEXT ROW
|
||
SUBQ #1,HEIGHT(A6) ;DECREMENT ROWCOUNT
|
||
beq GOHOME ;LOOP FOR ALL SRCROWS
|
||
MOVE.L FIRSTMASK(A6),D1 ;MASK:=FIRSTMASK
|
||
MOVE LONGCNT(A6),D2 ;GET LONGCOUNT
|
||
bra.s @bX8 ;go do next row
|
||
|
||
; <13> End of alpha channel changes
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 8 OR 12: PATTERN --> DST (FILLING AREAS, DRAWING LINES)
|
||
; PATTERN ALREADY HAS COLOR IN IT, SO NONE IS ADDED
|
||
; Doesn't handle the fits in 1 long case (see above) <1.5> BAL
|
||
; Loops for all scanlines then goes home <1.5> BAL
|
||
;
|
||
|
||
bXMid8 subq #1,d2 ;make zero based for dbra <1.5> BAL
|
||
@next MOVE.L 0(A4,D6),(A5)+ ;PUT PATTERN TO DST <1.5> BAL
|
||
ADDQ #4,D6 ;BUMP TO NEXT LONG OF PATTERN <1.5> BAL
|
||
AND D7,D6 ;WRAP WHEN PATTERN REPEATS <1.5> BAL
|
||
dbra d2,@next ;DEC LONG COUNT <1.5> BAL
|
||
|
||
bXEND8 AND.L D5,D1 ;MASK:=MASK AND LASTMASK
|
||
bXMAIN8G MOVE.L D1,D0 ;COPY MASK FOR DST
|
||
AND.L 0(A4,D6),D0 ;MASK PATTERN
|
||
ADDQ #4,D6 ;BUMP TO NEXT LONG OF PATTERN
|
||
AND D7,D6 ;WRAP WHEN PATTERN REPEATS
|
||
NOT.L D1 ;GET NOTMASK FOR DST
|
||
AND.L (A5),D1 ;PUNCH A LONG OF DST
|
||
OR.L D1,D0 ;COMBINE PAT AND DST
|
||
MOVE.L D0,(A5)+ ;PUT RESULT TO DST
|
||
MOVEQ #-1,D1 ;FLUSH MASK
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
bgt.s bXMid8 ;LOOP TILL LAST LONG <1.5> BAL
|
||
BEQ bXEND8 ;DO LAST LONG WITH LASTMASK
|
||
|
||
@nxtBigPat
|
||
clr.w d6 ;make it unsigned <1.5> BAL
|
||
SWAP D6 ;GET VERT POSITION IN PAT <1.5> BAL
|
||
SUB.l D6,A4 ;GET BACK PAT BASE <1.5> BAL
|
||
ADD PATROW(A6),D6 ;BUMP TO NEXT SCAN <1.5> BAL
|
||
AND PATVMASK(A6),D6 ;AND MASK WITHIN PATTERN <1.5> BAL
|
||
ADD.l D6,A4 ;BUMP TO PROPER VERT <1.5> BAL
|
||
SWAP D6 ;SAVE VERTICAL POSITION <1.5> BAL
|
||
MOVE PATHPOS(A6),D6 ;INIT HORIZONTAL OFFSET <1.5> BAL
|
||
ADD A3,A5 ;BUMP DSTADDR TO NEXT ROW <1.5> BAL
|
||
SUBQ #1,HEIGHT(A6) ;DECREMENT ROWCOUNT <1.5> BAL
|
||
beq GOHOME ;LOOP FOR ALL SRCROWS <1.5> BAL
|
||
MOVE.L FIRSTMASK(A6),D1 ;MASK:=FIRSTMASK <1.5> BAL
|
||
MOVE LONGCNT(A6),D2 ;GET LONGCOUNT <1.5> BAL
|
||
bra.s bXMAIN8G ;go do next row <1.5> BAL
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 9 OR 13: BIG PATTERN OR DST --> DST
|
||
;
|
||
bXEND9 AND.L D5,D1 ;MASK:=MASK AND LASTMASK
|
||
bXMAIN9 AND.L 0(A4,D6),D1 ;MASK PATTERN
|
||
ADDQ #4,D6 ;BUMP TO NEXT LONG OF PATTERN
|
||
AND D7,D6 ;WRAP WHEN PATTERN REPEATS
|
||
MOVE.L D1,D0 ;COPY MASKED PATTERN
|
||
AND.L D3,D0 ;APPLY FG COLOR TO MASKED PATTERN
|
||
NOT.L D1 ;GET NOT MASKED PATTERN
|
||
AND.L (A5),D1 ;USE TO PUNCH OUT DST
|
||
OR.L D1,D0 ;COMBINE SRC AND DST
|
||
MOVE.L D0,(A5)+ ;PUT RESULT TO DST
|
||
MOVEQ #-1,D1 ;FLUSH MASK
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BGT bXMAIN9 ;LOOP TILL LAST LONG
|
||
BEQ bXEND9 ;DO LAST LONG WITH LASTMASK
|
||
BRA NXTBIGPAT ;LOOP BACK FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-----------------------------------------------------------
|
||
;
|
||
; OPTIMIZE MODE 10 OR 14 IF DST FITS IN ONE LONG (XOR VERT LINES)
|
||
;
|
||
bXEND10 MOVE PATROW(A6),A0 ;GET PATTERN ROWBYTES <1.5> BAL
|
||
MOVE PATVMASK(A6),D2 ;GET MASK FOR VERT <1.5> BAL
|
||
MOVE HEIGHT(A6),D3 ;GET NUMBER OF ROWS <1.5> BAL
|
||
SUBQ #1,D3 ;MAKE 0 BASED FOR DBRA LOOP <1.5> BAL
|
||
addq #4,a3 ;convert dstBump to rowBytes <1.5> BAL
|
||
AND.L D5,D1 ;COMBINE LEFT AND RIGHT MASKS <1.5> BAL
|
||
ADD D6,A4 ;ADD PATHPOS TO BASE <1.5> BAL
|
||
clr.w D6 ;treat as unsigned <1.5> BAL
|
||
SWAP D6 ;GET PATVPOS <1.5> BAL
|
||
SUB.l D6,A4 ;BACK UP TO BASE OF PATTERN <1.5> BAL
|
||
|
||
@nxtRow MOVE.L 0(A4,D6),D0 ;Get a long of pattern <1.5> BAL
|
||
AND.L D1,D0 ;Mask the pattern <1.5> BAL
|
||
EOR.L D0,(A5) ;XOR RESULT INTO DST <1.5> BAL
|
||
ADD A3,A5 ;BUMP DSTPTR TO NEXT ROW <1.5> BAL
|
||
ADD A0,D6 ;BUMP PATTERN TO NEXT ROW <1.5> BAL
|
||
AND D2,D6 ;WRAP IF PAST END OF PATTERN <1.5> BAL
|
||
DBRA D3,@nxtRow ;LOOP ALL ROWS <1.5> BAL
|
||
BRA GOHOME ; <1.5> BAL
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 10 OR 14: BIG PATTERN XOR DST --> DST (INVERTING AREAS, XOR LINES)
|
||
;
|
||
bXRGHT10 AND.L D5,D1 ;MASK:=MASK AND LASTMASK
|
||
bXMAIN10 AND.L 0(A4,D6),D1 ;MASK PATTERN
|
||
ADDQ #4,D6 ;BUMP TO NEXT LONG OF PATTERN
|
||
AND D7,D6 ;WRAP WHEN PATTERN REPEATS
|
||
EOR.L D1,(A5)+ ;XOR RESULT INTO DST
|
||
MOVEQ #-1,D1 ;FLUSH MASK
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BGT bXMAIN10 ;LOOP TILL LAST LONG
|
||
BEQ bXRGHT10 ;DO LAST LONG WITH LASTMASK
|
||
BRA NXTBIGPAT ;LOOP BACK FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 11 OR 15: BIG PATTERN BIC DST --> DST
|
||
;
|
||
bXEND11 AND.L D5,D1 ;MASK:=MASK AND LASTMASK
|
||
bXMAIN11 AND.L 0(A4,D6),D1 ;MASK PATTERN
|
||
ADDQ #4,D6 ;BUMP TO NEXT LONG OF PATTERN
|
||
AND D7,D6 ;WRAP WHEN PATTERN REPEATS
|
||
MOVE.L D1,D0 ;COPY MASKED PATTERN
|
||
AND.L D4,D0 ;APPLY BK COLOR TO MASKED PATTERN
|
||
NOT.L D1 ;GET NOT MASKED PATTERN
|
||
AND.L (A5),D1 ;PUNCH OUT DST
|
||
OR.L D1,D0 ;COMBINE SRC AND DST
|
||
MOVE.L D0,(A5)+ ;PUT RESULT TO DST
|
||
MOVEQ #-1,D1 ;FLUSH MASK
|
||
SUB #1,D2 ;DEC LONG COUNT
|
||
BGT bXMAIN11 ;LOOP TILL LAST LONG
|
||
BEQ bXEND11 ;DO LAST WITH LASTMASK
|
||
BRA NXTBIGPAT ;LOOP BACK FOR NEXT ROW
|
||
|
||
|
||
if blit32 then ;<14>
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; arithSetup32
|
||
|
||
; (SP) hbump for a pixel
|
||
; A0 inverse color table
|
||
; A1 modeCase
|
||
; D0 first destination/mask pixel position
|
||
; D2 number of pixels in a long, or 0 if only 1 long
|
||
; D5 inverse color table entry size
|
||
; D6 first source pixel position
|
||
; D7 pixel size
|
||
; doneMid(A6) cleared (byte)
|
||
; lastMask(A6) equal to D5 standard
|
||
; midCount(A6) equal to # of pixels on line less mask longs
|
||
; pixInLong(A6) equal to # of pixels in a long
|
||
|
||
bArith32Setup
|
||
move.w destPixCnt(a6),d2 ;get # pixels to blit <1.5> BAL
|
||
subq.w #1,d2 ;make zero based for dbra <1.5> BAL
|
||
move.w d2,longcnt(a6) ;remember for later <1.5> BAL
|
||
|
||
moveq #0,d4 ;patHMask should be a long
|
||
move.w patHMask(a6),d4 ;get pattern index mask
|
||
lsr.l #3,d4 ;make byte mask
|
||
move.w d4,patHMask(a6) ;save for subover
|
||
|
||
TST.B endSwitch(A6) ;is the src a pattern?
|
||
bpl.s @usePat
|
||
moveq #0,d6 ;no, clear pattern index
|
||
@usePat
|
||
lsr.l #3,d6 ;make byte offset
|
||
MOVE.L d6,patOffset(A6) ;save for subsequent scans
|
||
|
||
move.w srcrow+2(a6),srcbump(a6)
|
||
move.w hBump(a6),a3 ;set up hBump in a3 (±4)
|
||
move.w a3,d7 ;are we bumping right to left?
|
||
bpl.s @goBlit
|
||
addq.w #1,d2 ;bump cnt
|
||
move.w d2,longcnt(a6) ;remember for later
|
||
@goBlit jmp (a1) ;take modecase
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
; a4 = srcPtr/patPtr d1 = leftMask
|
||
; a5 = dstPtr
|
||
|
||
bArith16Setup
|
||
move.w destPixCnt(a6),d2 ;get # pixels to blit
|
||
subq.w #1,d2 ;make zero based for dbra
|
||
move.w d2,longcnt(a6) ;remember for later
|
||
|
||
; TST.B endSwitch(A6) ;is the src a pattern?
|
||
; bpl.s @usePat
|
||
; moveq #0,d6 ;no, clear pattern index
|
||
;usePat
|
||
asr.l #3,d6 ;make byte offset
|
||
MOVE.L d6,patOffset(A6) ;save for subsequent scans
|
||
|
||
move.w srcrow+2(a6),srcbump(a6)
|
||
move.w hBump(a6),d7 ;are we bumping right to left?
|
||
asr.w #1,d7 ;convert to word bump (±2)
|
||
move.w d7,a3 ;setup hbump in a3
|
||
bpl.s @RtoL
|
||
addq.w #1,d2 ;bump cnt
|
||
move.w d2,longcnt(a6) ;remember for later
|
||
@RtoL
|
||
tst.l d1 ;should we blit first pixel?
|
||
bmi.s @leftOK ;yes, ptrs are ok
|
||
addq #2,a5 ;bump dstptr
|
||
addq.l #2,d6 ;bump src index
|
||
MOVE.L d6,patOffset(A6) ;save for subsequent scans
|
||
@leftOK
|
||
moveq #0,d4 ;patHMask should be a long
|
||
move.w patHMask(a6),d4 ;get pattern index mask
|
||
lsr.l #3,d4 ;make long mask
|
||
bset #1,d4 ;make word mask
|
||
move.w d4,patHMask(a6) ;save for subover
|
||
|
||
jmp (a1) ;take modecase
|
||
|
||
else ;<14>
|
||
bArith32Setup
|
||
bArith16Setup
|
||
; _Debugger
|
||
endif ;<14>
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 34, 42, 58: SRC + DST --> DST (no pin)
|
||
|
||
; (SP) hbump for a pixel
|
||
; A0 inverse color table
|
||
; A1 color table
|
||
; D0 first destination/mask pixel position
|
||
; D2 number of pixels in a long, or 0 if only 1 long
|
||
; D5 inverse color table entry size
|
||
; D6 first source pixel position
|
||
; D7 pixel size
|
||
; doneMid(A6) cleared (byte)
|
||
; lastMask(A6) equal to D5 standard
|
||
; midCount(A6) equal to # of pixels on line less mask longs
|
||
; pixInLong(A6) equal to # of pixels in a long
|
||
|
||
; note: D4 is unused
|
||
|
||
bAddOver
|
||
bAddOverIndexed
|
||
;
|
||
; if we are going backwards, align destination and mask <14AUG90 KON>
|
||
;
|
||
tst (sp) ;is bump amount negative? <14AUG90 KON>
|
||
bpl.s @RealbAddOver1 ; <14AUG90 KON>
|
||
sub.l (SP),D6 ;bump src right OR left by 1 pixel first time only <14AUG90 KON>
|
||
|
||
@RealbAddOver
|
||
tst (sp) ;is bump amount negative? <14AUG90 KON>
|
||
bpl.s @RealbAddOver1 ; <14AUG90 KON>
|
||
sub.l (SP),D0 ;align destination and mask each scan line <14AUG90 KON>
|
||
@RealbAddOver1
|
||
MOVE.L colorTable(A6),A1 ;set up color table
|
||
TST D2 ;is there only 1 long?
|
||
BGT.S @firstMask ;if not, use the first mask in D1
|
||
@forceLast
|
||
OR.B #3,doneMid(A6) ;note that the first part and mid part are done
|
||
@lastMask
|
||
MOVE pixInLong(A6),D2 ;loop once for each pixel in the long
|
||
AND.L lastMask(A6),D1 ;MASK:=MASK AND LASTMASK
|
||
@firstMask
|
||
@loopTop
|
||
AND patHMask(A6),D6 ;constrict to the source long if in a pattern mode
|
||
BFEXTU D1{D0:D7},D3 ;a pixel of the mask
|
||
BEQ.S @skip
|
||
|
||
BFEXTU (A4){D6:D7},D3 ;get a pixel of the source (zeros top word)
|
||
LEA red(A1,D3*8),A2 ;figure out where it lives in the color table
|
||
BFEXTU (A5){D0:D7},D3 ;a pixel of the destination
|
||
LEA red(A1,D3*8),A3 ;figure out where destination lives
|
||
MOVE (A2)+,D3 ;red get source color value
|
||
ADD (A3)+,D3 ; combine source and destination
|
||
ASL.L D5,D3 ; save the top bits in the top word
|
||
MOVE (A2)+,D3 ;green get source color value
|
||
ADD (A3)+,D3 ; combine source and destination
|
||
ASL.L D5,D3 ; save the top bits in the top word
|
||
MOVE (A2)+,D3 ;blue get source color value
|
||
ADD (A3)+,D3 ; combine source and destination
|
||
ASL.L D5,D3 ; save the top bits in the top word
|
||
SWAP D3 ;r, g, b in high word
|
||
MOVE.B itTable(A0,D3),D3 ;get the pixel value of the additive sum
|
||
BFINS D3,(A5){D0:D7} ;move to the destination
|
||
@skip
|
||
ADD.L (SP),D6 ;BUMP SRCPTR LEFT OR RIGHT by 1 pixel
|
||
ADD.L (SP),D0 ;bump destination and mask
|
||
DBRA D2,@loopTop ;do it for all of the pixels on the line (or within the mask)
|
||
MOVEQ #-1,D1 ;flush mask
|
||
BSET #0,doneMid(A6) ;has the middle part already been done?
|
||
BNE.S @midDone ;if so, skip it
|
||
MOVE midCount(A6),D2 ;reset to mid count
|
||
BMI.S @forceLast ;if none, just do the last part
|
||
BRA.S @loopTop
|
||
@midDone
|
||
BSET #1,doneMid(A6) ;already done the last mask part too?
|
||
BEQ.S @lastMask ;if not, do it
|
||
lea @RealbAddOver,A1 ;restore address to ourselves <14AUG90 KON>
|
||
BRA NxtNewSrc ;LOOP BACK FOR MORE
|
||
|
||
|
||
|
||
if blit32 then ;<14>
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
; a0 = tmpsrc d0 = high bit clearing mask
|
||
; a1 = modeCase/mask d1 = dst msb's
|
||
; a2 = tmpdst d2 = longCnt
|
||
; a3 = hBump d3 = src msb's
|
||
; a4 = srcPtr/patPtr d4 = patHMask
|
||
; a5 = dstPtr d5 = dest pixel
|
||
; a6 = locals d6 = pat offset
|
||
; a7^= patHBump d7 = src pixel
|
||
;-------------------------------------------------------
|
||
|
||
bAddOver32
|
||
move.l a4,a0 ;get working copy of srcptr
|
||
add.w d6,a0 ;index into pattern
|
||
move.l a5,a2 ;get working copy of dstptr
|
||
|
||
move.l #~$ff808080,d0 ;get high bit clearing mask
|
||
move.l #$00808080,a1 ;get high bit mask
|
||
|
||
@loopTop
|
||
move.l a1,d3 ;copy high bit mask
|
||
move.l (a0),d7 ;get a pixel of the source xrgb
|
||
and.l d7,d3 ;remember src msb's
|
||
add.w a3,a0 ;bump bidirectionally
|
||
and.l d0,d7 ;mask out stragglers
|
||
|
||
move.l (a2),d5 ;get a pixel of the dest xrgb
|
||
move.l a1,d1 ;copy high bit mask
|
||
and.l d5,d1 ;remember dst msb's
|
||
and.l d0,d5 ;mask out stragglers
|
||
|
||
add.l d5,d7 ;merge src with dst
|
||
eor.l d3,d1 ;compute partial sum of msb's
|
||
eor.l d1,d7 ;compute partial sum of msb's
|
||
move.l d7,(a2) ;move to the destination
|
||
add.w a3,a2 ;bump bidirectionally
|
||
addq.l #4,d6 ;bump pattern offset
|
||
and.l d4,d6 ;constrict to the source long if in a pattern mode
|
||
bne.s @patOK ;don't need to reload pat ptr
|
||
move.l a4,a0 ;reload pat ptr
|
||
@patOK DBRA D2,@loopTop ;do it for all pixels on the line
|
||
lea bAddOver32,a1 ;reload modeCase
|
||
BRA NxtNewSrc32 ;LOOP BACK FOR MORE
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
; a0 = tmpsrc d0 = high bit clearing mask
|
||
; a1 = modeCase/mask d1 = dst msb's
|
||
; a2 = tmpdst d2 = longCnt
|
||
; a3 = hBump d3 = src msb's
|
||
; a4 = srcPtr/patPtr d4 = patHMask
|
||
; a5 = dstPtr d5 = dest pixel
|
||
; a6 = locals d6 = pat offset
|
||
; a7^= patHBump d7 = src pixel
|
||
;-------------------------------------------------------
|
||
bAddOver16
|
||
move.l a4,a0 ;get working copy of srcptr
|
||
add.w d6,a0 ;index into pattern
|
||
move.l a5,a2 ;get working copy of dstptr
|
||
|
||
move.w #$3def,d0 ;get high bit clearing mask
|
||
move.w #$4210,a1 ;get high bit mask
|
||
|
||
@loopTop
|
||
move.w a1,d3 ;copy high bit mask
|
||
move.w (a0),d7 ;get a pixel of the source xrgb
|
||
and.w d7,d3 ;remember src msb's
|
||
add.w a3,a0 ;bump bidirectionally
|
||
and.w d0,d7 ;mask out stragglers
|
||
|
||
move.w (a2),d5 ;get a pixel of the dest xrgb
|
||
move.w a1,d1 ;copy high bit mask
|
||
and.w d5,d1 ;remember dst msb's
|
||
and.w d0,d5 ;mask out stragglers
|
||
|
||
add.w d5,d7 ;merge src with dst
|
||
eor.w d3,d1 ;compute partial sum of msb's
|
||
eor.w d1,d7 ;compute partial sum of msb's
|
||
move.w d7,(a2) ;move to the destination
|
||
add.w a3,a2 ;bump bidirectionally
|
||
addq.l #2,d6 ;bump pattern offset
|
||
and.l d4,d6 ;constrict to the source long if in a pattern mode
|
||
bne.s @patOK ;don't need to reload pat ptr
|
||
move.l a4,a0 ;reload pat ptr
|
||
@patOK DBRA D2,@loopTop ;do it for all pixels on the line
|
||
lea bAddOver16,a1 ;reload modeCase
|
||
BRA NxtNewSrc32 ;LOOP BACK FOR MORE
|
||
|
||
endif ;<14>
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 33, 41, 57: SRC + DST --> DST (pin to max)
|
||
|
||
; in addition to the registers set up for Mode 17 (AddOver), this needs
|
||
; the 3 element word array pin(A6) to be set to the maximum b, g, r values (in that order)
|
||
; for comparison and pinning
|
||
|
||
; Note that D4 is unused
|
||
|
||
bAddPin
|
||
bAddPinIndexed
|
||
;
|
||
; if we are going backwards, align destination and mask <14AUG90 KON>
|
||
;
|
||
tst (sp) ;is bump amount negative? <14AUG90 KON>
|
||
bpl.s @RealbAddPin1 ; <14AUG90 KON>
|
||
sub.l (SP),D6 ;bump src right OR left by 1 pixel first time only <14AUG90 KON>
|
||
|
||
@RealbAddPin
|
||
tst (sp) ;is bump amount negative? <14AUG90 KON>
|
||
bpl.s @RealbAddPin1 ; <14AUG90 KON>
|
||
sub.l (SP),D0 ;align destination and mask each scan line <14AUG90 KON>
|
||
@RealbAddPin1
|
||
|
||
MOVE.L colorTable(A6),A1 ;set up color table
|
||
TST D2 ;is there only 1 long?
|
||
BGT.S @firstMask ;if not, use the first mask in D1
|
||
@forceLast
|
||
OR.B #3,doneMid(A6) ;note that the first part and mid part are done
|
||
@lastMask
|
||
MOVE pixInLong(A6),D2 ;loop once for each pixel in the long
|
||
AND.L lastMask(A6),D1 ;MASK:=MASK AND LASTMASK
|
||
@firstMask
|
||
@loopTop
|
||
AND patHMask(A6),D6 ;constrict to the source long if in a pattern mode
|
||
BFEXTU D1{D0:D7},D3 ;a pixel of the mask
|
||
BEQ.S @skip
|
||
|
||
BFEXTU (A4){D6:D7},D3 ;get a pixel of the source (zeros top word)
|
||
LEA red(A1,D3*8),A2 ;figure out where it lives in the color table
|
||
BFEXTU (A5){D0:D7},D3 ;a pixel of the destination
|
||
LEA red(A1,D3*8),A3 ;figure out where destination lives
|
||
MOVE (A2)+,D3 ;get source color value
|
||
ADD (A3)+,D3 ;combine source and destination
|
||
BCS.S @tooBigRed
|
||
CMP pin+4(A6),D3 ;bigger than pin value?
|
||
BLS.S @notTooBigRed ;no, no problem
|
||
@tooBigRed
|
||
MOVE pin+4(A6),D3
|
||
@notTooBigRed
|
||
ASL.L D5,D3 ;save the top bits in the top word
|
||
MOVE (A2)+,D3 ;get source color value
|
||
ADD (A3)+,D3 ;combine source and destination
|
||
BCS.S @tooBigGreen
|
||
CMP pin+2(A6),D3 ;bigger than pin value?
|
||
BLS.S @notTooBigGreen ;no, no problem
|
||
@tooBigGreen
|
||
MOVE pin+2(A6),D3
|
||
@notTooBigGreen
|
||
ASL.L D5,D3 ;save the top bits in the top word
|
||
MOVE (A2)+,D3 ;get source color value
|
||
ADD (A3)+,D3 ;combine source and destination
|
||
BCS.S @tooBigBlue
|
||
CMP pin(A6),D3 ;bigger than pin value?
|
||
BLS.S @notTooBigBlue ;no, no problem
|
||
@tooBigBlue
|
||
MOVE pin(A6),D3
|
||
@notTooBigBlue
|
||
ASL.L D5,D3 ;save the top bits in the top word
|
||
SWAP D3 ;r, g, b in high word
|
||
MOVE.B itTable(A0,D3),D3 ;get the pixel value of the additive sum
|
||
BFINS D3,(A5){D0:D7} ;move to the destination
|
||
@skip
|
||
ADD.L (SP),D6 ;BUMP SRCPTR LEFT OR RIGHT by 1 pixel
|
||
ADD.L (SP),D0 ;bump destination and mask
|
||
DBRA D2,@loopTop ;do it for all of the pixels on the line (or within the mask)
|
||
MOVEQ #-1,D1 ;flush mask
|
||
BSET #0,doneMid(A6) ;has the middle part already been done?
|
||
BNE.S @midDone ;if so, skip it
|
||
MOVE midCount(A6),D2 ;reset to mid count
|
||
BMI.S @forceLast ;if none, just do the last part
|
||
BRA.S @loopTop
|
||
@midDone
|
||
BSET #1,doneMid(A6) ;already done the last mask part too?
|
||
BEQ.S @lastMask ;if not, do it
|
||
lea @RealbAddPin,A1 ;restore address to ourselves <14AUG90 KON>
|
||
BRA NxtNewSrc ;LOOP BACK FOR MORE
|
||
|
||
|
||
if blit32 then ;<14>
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
; a0 = tmpsrc d0 = result/scratch
|
||
; a1 = modeCase d1 = lo3Bytes mask
|
||
; a2 = tmpdst d2 = longCnt
|
||
; a3 = hBump d3 = pin pixel 0rgb
|
||
; a4 = srcPtr/patPtr d4 = patHMask (bytes)
|
||
; a5 = dstPtr d5 = dst long
|
||
; a6 = locals d6 = pat offset (bytes)
|
||
; a7^= d7 = src long
|
||
;-------------------------------------------------------
|
||
bAddPin32
|
||
;set up pin pixel as 0rgb in D3 -> overwrites pattern bump
|
||
|
||
lea bAddPin32Main,A1 ;go there from now on
|
||
moveq #0,d3 ;start fresh, waste iTabRes
|
||
move.b pin+4(a6),d3 ;pick up red
|
||
swap d3 ;put in byte 3
|
||
move.w pin+2(a6),d3 ;get green in byte 2
|
||
move.b pin(a6),d3 ;put blue in lo byte
|
||
|
||
bAddPin32Main
|
||
move.l a4,a0 ;get working copy of srcptr
|
||
add.w d6,a0 ;index into pattern
|
||
move.l a5,a2 ;get working copy of dstptr
|
||
move.l Lo3Bytes,d1 ;pick up mask
|
||
|
||
@loopTop
|
||
move.l (a0),d7 ;get a pixel of the source xrgb
|
||
and.l d1,d7 ;waste high byte
|
||
move.l d7,d0 ;make a copy of the src xrgb
|
||
add a3,a0 ;bump bi-directionally
|
||
move.l (a2),d5 ;get a pixel of the dest xrgb
|
||
and.l d1,d5 ;waste high byte
|
||
|
||
clr.b d0 ;prevent carries from below
|
||
add.w d5,d0 ;add green components
|
||
BCS.S @PinGreen
|
||
cmp.w d3,d0 ;do we need to pin result?
|
||
bls.s @GreenOK
|
||
@PinGreen
|
||
move.w d3,d0 ;use pin value instead
|
||
@GreenOK
|
||
move.b d7,d0 ;get src blue
|
||
add.b d5,d0 ;add dest blue
|
||
BCS.S @PinBlue
|
||
cmp.b d3,d0 ;do we need to pin result?
|
||
bls.s @BlueOK
|
||
@PinBlue
|
||
move.b d3,d0 ;use pin value instead
|
||
@BlueOK
|
||
clr.w d5 ;now d5 has only red in byte 3
|
||
add.l d5,d0 ;add red components
|
||
cmp.l d3,d0 ;compare red components
|
||
bls.s @RedOK
|
||
@PinRed
|
||
swap d3 ;get max red in lo word
|
||
swap d0 ;get too big red in lo word
|
||
move.w d3,d0 ;pin to max red
|
||
swap d0 ;get back 0rgb
|
||
swap d3 ;restore pin pixel
|
||
@RedOK
|
||
move.l d0,(a2) ;move to the destination
|
||
add a3,a2 ;bump bi-directionally
|
||
addq.l #4,d6 ;bump pattern offset
|
||
and.l d4,d6 ;constrict to the source long if in a pattern mode
|
||
bne.s @patOK ;don't need to reload pat ptr
|
||
move.l a4,a0 ;reload pat ptr
|
||
@patOK DBRA D2,@loopTop ;do it for all pixels on the line
|
||
BRA NxtNewSrc32 ;LOOP BACK FOR MORE
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
; a0 = tmpsrc d0 = result/scratch
|
||
; a1 = modeCase d1 = lo3Bytes mask
|
||
; a2 = tmpdst d2 = longCnt
|
||
; a3 = hBump d3 = pin pixel 0rgb
|
||
; a4 = srcPtr/patPtr d4 = patHMask (bytes)
|
||
; a5 = dstPtr d5 = dst long
|
||
; a6 = locals d6 = pat offset (bytes)
|
||
; a7^= d7 = src long
|
||
;-------------------------------------------------------
|
||
bAddPin16
|
||
lea bAddPin16Main,A1 ;go here from now on
|
||
moveq #0,d3 ;start fresh, waste iTabRes
|
||
move.b pin+4(a6),d3 ;pick up red
|
||
lsr.b #3,d3 ;get right aligned 5 bits
|
||
swap d3 ;put in byte 3
|
||
move.w pin+2(a6),d3 ;get green in byte 2
|
||
lsr.w #3,d3 ;get right aligned 5 bits
|
||
move.b pin(a6),d3 ;put blue in lo byte
|
||
lsr.b #3,d3 ;right flush blue
|
||
|
||
bAddPin16Main
|
||
move.l a4,a0 ;get working copy of srcptr
|
||
add.w d6,a0 ;index into pattern
|
||
move.l a5,a2 ;get working copy of dstptr
|
||
|
||
@loopTop
|
||
moveq #0,d7
|
||
move.w (a0),d7 ;get a pixel of the source xrgb
|
||
add a3,a0 ;bump bi-directionally
|
||
add.w d7,d7 ;waste high bit
|
||
lsl.l #5,d7 ;but red in byte 3
|
||
lsr.w #3,d7 ;but green in byte 2, blue in lo byte
|
||
lsr.b #3,d7 ;right flush blue
|
||
|
||
moveq #0,d5
|
||
move.w (a2),d5 ;get a pixel of the dest xrgb
|
||
add.w d5,d5 ;waste high bit
|
||
lsl.l #5,d5 ;but red in byte 3
|
||
lsr.w #3,d5 ;but green in byte 2, blue in lo byte
|
||
lsr.b #3,d5 ;right flush blue
|
||
|
||
add.l d5,d7 ;add all components at once
|
||
move.l d7,d0 ;prime result with red
|
||
cmp.l d3,d0 ;do we need to pin result?
|
||
bls.s @redOK ;no, don't pin
|
||
move.l d3,d0 ;use pin value instead
|
||
@redOK
|
||
move.w d7,d0 ;prime result with green
|
||
cmp.w d3,d0 ;do we need to pin result?
|
||
bls.s @greenOK ;no, don't pin
|
||
move.w d3,d0 ;use pin value instead
|
||
@greenOK
|
||
move.b d7,d0 ;prime result with blue
|
||
cmp.b d3,d0 ;do we need to pin result?
|
||
bls.s @blueOK ;no, don't pin
|
||
move.b d3,d0 ;use pin value instead
|
||
@blueOK
|
||
|
||
lsl.b #3,d0 ;rejoin green/blue
|
||
lsl.w #3,d0 ;rejoin red/green/blue
|
||
lsr.l #6,d0 ;right flush red/green/blue
|
||
|
||
move.w d0,(a2) ;move to the destination
|
||
add a3,a2 ;bump bi-directionally
|
||
addq.l #2,d6 ;bump pattern offset
|
||
and.l d4,d6 ;constrict to the source long if in a pattern mode
|
||
bne.s @patOK ;don't need to reload pat ptr
|
||
move.l a4,a0 ;reload pat ptr
|
||
@patOK DBRA D2,@loopTop ;do it for all pixels on the line
|
||
BRA NxtNewSrc32 ;LOOP BACK FOR MORE
|
||
|
||
endif ;<14>
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 38, 46, 62: DST - SRC --> DST (no pin)
|
||
;
|
||
; Note that D4 is unused
|
||
|
||
bSubOver
|
||
bSubOverIndexed
|
||
;
|
||
; if we are going backwards, align destination and mask <14AUG90 KON>
|
||
;
|
||
tst (sp) ;is bump amount negative? <14AUG90 KON>
|
||
bpl.s @RealbSubOver1 ; <14AUG90 KON>
|
||
sub.l (SP),D6 ;bump src right OR left by 1 pixel first time only <14AUG90 KON>
|
||
|
||
@RealbSubOver
|
||
tst (sp) ;is bump amount negative? <14AUG90 KON>
|
||
bpl.s @RealbSubOver1 ; <14AUG90 KON>
|
||
sub.l (SP),D0 ;align destination and mask each scan line <14AUG90 KON>
|
||
@RealbSubOver1
|
||
MOVE.L colorTable(A6),A1 ;set up color table
|
||
TST D2 ;is there only 1 long?
|
||
BGT.S @firstMask ;if not, use the first mask in D1
|
||
@forceLast
|
||
OR.B #3,doneMid(A6) ;note that the first part and mid part are done
|
||
@lastMask
|
||
MOVE pixInLong(A6),D2 ;loop once for each pixel in the long
|
||
AND.L lastMask(A6),D1 ;MASK:=MASK AND LASTMASK
|
||
@firstMask
|
||
@loopTop
|
||
AND patHMask(A6),D6 ;constrict to the source long if in a pattern mode
|
||
BFEXTU D1{D0:D7},D3 ;a pixel of the mask
|
||
BEQ.S @skip
|
||
|
||
BFEXTU (A4){D6:D7},D3 ;get a pixel of the source (zeros top word)
|
||
LEA red(A1,D3*8),A2 ;figure out where it lives in the color table
|
||
BFEXTU (A5){D0:D7},D3 ;a pixel of the destination
|
||
LEA red(A1,D3*8),A3 ;figure out where destination lives
|
||
MOVE (A3)+,D3 ;get destination
|
||
SUB (A2)+,D3 ;less source color value
|
||
ASL.L D5,D3 ;save the top 4 bits in the top word
|
||
MOVE (A3)+,D3 ;get destination
|
||
SUB (A2)+,D3 ;less source color value
|
||
ASL.L D5,D3 ;save the top 4 bits in the top word
|
||
MOVE (A3)+,D3 ;get destination
|
||
SUB (A2)+,D3 ;less source color value
|
||
ASL.L D5,D3 ;save the top 4 bits in the top word
|
||
SWAP D3 ;r, g, b in high word
|
||
MOVE.B itTable(A0,D3),D3 ;get the pixel value of the additive sum
|
||
BFINS D3,(A5){D0:D7} ;move to the destination
|
||
@skip
|
||
ADD.L (SP),D6 ;BUMP SRCPTR LEFT OR RIGHT by 1 pixel
|
||
ADD.L (SP),D0 ;bump destination and mask
|
||
DBRA D2,@loopTop ;do it for all of the pixels on the line (or within the mask)
|
||
MOVEQ #-1,D1 ;flush mask
|
||
BSET #0,doneMid(A6) ;has the middle part already been done?
|
||
BNE.S @midDone ;if so, skip it
|
||
MOVE midCount(A6),D2 ;reset to mid count
|
||
BMI.S @forceLast ;if none, just do the last part
|
||
BRA.S @loopTop
|
||
@midDone
|
||
BSET #1,doneMid(A6) ;already done the last mask part too?
|
||
BEQ.S @lastMask ;if not, do it
|
||
lea @RealbSubOver,A1 ;restore address to ourselves <14AUG90 KON>
|
||
BRA NxtNewSrc ;LOOP BACK FOR MORE
|
||
|
||
|
||
if blit32 then ;<14>
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
; a0 = tmpsrc d0 = high bit clearing mask
|
||
; a1 = modeCase d1 = high bit mask
|
||
; a2 = tmpdst d2 = longCnt
|
||
; a3 = hBump d3 = src msb's
|
||
; a4 = srcPtr/patPtr d4 = dst msb's
|
||
; a5 = dstPtr d5 = dest pixel
|
||
; a6 = locals d6 = pat offset
|
||
; a7^= d7 = src pixel
|
||
;-------------------------------------------------------
|
||
bSubOver32
|
||
move.l a4,a0 ;get working copy of srcptr
|
||
add.w d6,a0 ;index into pattern
|
||
move.l a5,a2 ;get working copy of dstptr
|
||
|
||
move.l #~$ff808080,d0 ;get high bit clearing mask
|
||
move.l #$00808080,d1 ;get high bit mask
|
||
|
||
@loopTop
|
||
move.l d1,d3 ;copy high bit mask
|
||
move.l (a0),d7 ;get a pixel of the source xrgb
|
||
and.l d7,d3 ;remember src msb's
|
||
eor.l d1,d3 ;invert src msb's
|
||
add.w a3,a0 ;bump bidirectionally
|
||
and.l d0,d7 ;mask out stragglers
|
||
|
||
move.l (a2),d5 ;get a pixel of the dest xrgb
|
||
move.l d1,d4 ;copy high bit mask
|
||
and.l d5,d4 ;remember dst msb's
|
||
and.l d0,d5 ;mask out high byte
|
||
or.l d1,d5 ;force high bits on
|
||
|
||
sub.l d7,d5 ;compute dst - src
|
||
eor.l d3,d4 ;compute partial sum of msb's
|
||
eor.l d4,d5 ;compute partial sum of msb's
|
||
move.l d5,(a2) ;move to the destination
|
||
add.w a3,a2 ;bump bidirectionally
|
||
addq.l #4,d6 ;bump pattern offset
|
||
and.w patHMask(a6),d6 ;constrict to the source long if in a pattern mode
|
||
bne.s @patOK ;don't need to reload pat ptr
|
||
move.l a4,a0 ;reload pat ptr
|
||
@patOK DBRA D2,@loopTop ;do it for all pixels on the line
|
||
BRA NxtNewSrc32 ;LOOP BACK FOR MORE
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
; a0 = tmpsrc d0 = high bit clearing mask
|
||
; a1 = modeCase d1 = high bit mask
|
||
; a2 = tmpdst d2 = longCnt
|
||
; a3 = hBump d3 = src msb's
|
||
; a4 = srcPtr/patPtr d4 = dst msb's
|
||
; a5 = dstPtr d5 = dest pixel
|
||
; a6 = locals d6 = pat offset
|
||
; a7^= d7 = src pixel
|
||
;-------------------------------------------------------
|
||
; as seen in QDciPatchROM.a <sm 6/9/92>stb
|
||
|
||
bSubOver16
|
||
move.l a4,a0 ;get working copy of srcptr
|
||
add.w d6,a0 ;index into pattern
|
||
move.l a5,a2 ;get working copy of dstptr
|
||
|
||
move.w #$3def,d0 ;get high bit clearing mask
|
||
move.w #$4210,d1 ;get high bit mask
|
||
|
||
@loopTop
|
||
move.w d1,d3 ;copy high bit mask
|
||
move.w (a0),d7 ;get a pixel of the source xrgb
|
||
add.w a3,a0 ;bump bidirectionally
|
||
and.w d7,d3 ;remember src msb's
|
||
eor.w d1,d3 ;invert src msb's
|
||
and.w d0,d7 ;mask out stragglers
|
||
|
||
move.w (a2),d5 ;get a pixel of the dest xrgb <SMC 26SEP90> <11>
|
||
move.w d1,d4 ;copy high bit mask
|
||
and.w d5,d4 ;remember dst msb's
|
||
and.w d0,d5 ;mask out high byte
|
||
or.w d1,d5 ;force high bits on
|
||
|
||
sub.w d7,d5 ;compute dst - src
|
||
eor.w d3,d4 ;compute partial sum of msb's
|
||
eor.w d4,d5 ;compute partial sum of msb's
|
||
|
||
move.w d5,(a2) ;move to the destination
|
||
add.w a3,a2 ;bump bidirectionally
|
||
addq.l #2,d6 ;bump pattern offset
|
||
and.w patHMask(a6),d6 ;constrict to the source long if in a pattern mode
|
||
bne.s @patOK ;don't need to reload pat ptr
|
||
move.l a4,a0 ;reload pat ptr
|
||
@patOK DBRA D2,@loopTop ;do it for all pixels on the line
|
||
BRA NxtNewSrc32 ;LOOP BACK FOR MORE
|
||
|
||
endif ;<14>
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 35, 43, 59: DST - SRC --> DST (pin to min)
|
||
|
||
bSubPin
|
||
bSubPinIndexed
|
||
;
|
||
; if we are going backwards, align destination and mask <14AUG90 KON>
|
||
;
|
||
tst (sp) ;is bump amount negative? <14AUG90 KON>
|
||
bpl.s @RealbSubPin1 ; <14AUG90 KON>
|
||
sub.l (SP),D6 ;bump src right OR left by 1 pixel first time only <14AUG90 KON>
|
||
|
||
@RealbSubPin
|
||
tst (sp) ;is bump amount negative? <14AUG90 KON>
|
||
bpl.s @RealbSubPin1 ; <14AUG90 KON>
|
||
sub.l (SP),D0 ;align destination and mask each scan line <14AUG90 KON>
|
||
@RealbSubPin1
|
||
MOVE.L colorTable(A6),A1 ;set up color table
|
||
TST D2 ;is there only 1 long?
|
||
BGT.S @firstMask ;if not, use the first mask in D1
|
||
@forceLast
|
||
OR.B #3,doneMid(A6) ;note that the first part and mid part are done
|
||
@lastMask
|
||
MOVE pixInLong(A6),D2 ;loop once for each pixel in the long
|
||
AND.L lastMask(A6),D1 ;MASK:=MASK AND LASTMASK
|
||
@firstMask
|
||
@loopTop
|
||
AND patHMask(A6),D6 ;constrict to the source long if in a pattern mode
|
||
BFEXTU D1{D0:D7},D3 ;a pixel of the mask
|
||
BEQ.S @skip
|
||
|
||
BFEXTU (A4){D6:D7},D3 ;get a pixel of the source (zeros top word)
|
||
LEA red(A1,D3*8),A2 ;figure out where it lives in the color table
|
||
BFEXTU (A5){D0:D7},D3 ;a pixel of the destination
|
||
LEA red(A1,D3*8),A3 ;figure out where destination lives
|
||
MOVE (A3)+,D3 ;destination color
|
||
SUB (A2)+,D3 ;less source color value
|
||
BCS.S @tooBigRed
|
||
CMP pin+4(A6),D3 ;smaller than pin value?
|
||
BHS.S @notTooBigRed ;no, no problem
|
||
@tooBigRed
|
||
MOVE pin+4(A6),D3
|
||
@notTooBigRed
|
||
ASL.L D5,D3 ;save the top 4 bits in the top word
|
||
MOVE (A3)+,D3 ;destination color
|
||
SUB (A2)+,D3 ;less source color value
|
||
BCS.S @tooBigGreen
|
||
CMP pin+2(A6),D3 ;smaller than pin value?
|
||
BHS.S @notTooBigGreen ;no, no problem
|
||
@tooBigGreen
|
||
MOVE pin+2(A6),D3
|
||
@notTooBigGreen
|
||
ASL.L D5,D3 ;save the top 4 bits in the top word
|
||
MOVE (A3)+,D3 ;destination color
|
||
SUB (A2)+,D3 ;less source color value
|
||
BCS.S @tooBigBlue
|
||
CMP pin(A6),D3 ;smaller than pin value?
|
||
BHS.S @notTooBigBlue ;no, no problem
|
||
@tooBigBlue
|
||
MOVE pin(A6),D3
|
||
@notTooBigBlue
|
||
ASL.L D5,D3 ;save the top 4 bits in the top word
|
||
SWAP D3 ;r, g, b in high word
|
||
MOVE.B itTable(A0,D3),D3 ;get the pixel value of the additive sum
|
||
BFINS D3,(A5){D0:D7} ;move to the destination
|
||
@skip
|
||
ADD.L (SP),D6 ;BUMP SRCPTR LEFT OR RIGHT by 1 pixel
|
||
ADD.L (SP),D0 ;bump destination and mask
|
||
DBRA D2,@loopTop ;do it for all of the pixels on the line (or within the mask)
|
||
MOVEQ #-1,D1 ;flush mask
|
||
BSET #0,doneMid(A6) ;has the middle part already been done?
|
||
BNE.S @midDone ;if so, skip it
|
||
MOVE midCount(A6),D2 ;reset to mid count
|
||
BMI.S @forceLast ;if none, just do the last part
|
||
BRA.S @loopTop
|
||
@midDone
|
||
BSET #1,doneMid(A6) ;already done the last mask part too?
|
||
BEQ.S @lastMask ;if not, do it
|
||
lea @RealbSubPin,A1 ;restore address to ourselves <14AUG90 KON>
|
||
BRA NxtNewSrc ;LOOP BACK FOR MORE
|
||
|
||
|
||
if blit32 then ;<14>
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
; a0 = tmpsrc d0 = result/scratch
|
||
; a1 = modeCase d1 = lo3Bytes mask
|
||
; a2 = tmpdst d2 = longCnt
|
||
; a3 = hBump d3 = pin pixel 0rgb
|
||
; a4 = srcPtr/patPtr d4 = patHMask (bytes)
|
||
; a5 = dstPtr d5 = src long
|
||
; a6 = locals d6 = pat offset (bytes)
|
||
; a7^= d7 = dst long
|
||
;-------------------------------------------------------
|
||
|
||
;set up pin pixel as 0rgb in D3 -> overwrites pattern bump
|
||
|
||
bSubPin32
|
||
lea bSubPin32Main,A1 ;go there from now on
|
||
moveq #0,d3 ;start fresh, waste iTabRes
|
||
move.b pin+4(a6),d3 ;pick up red
|
||
swap d3 ;put in byte 3
|
||
move.w pin+2(a6),d3 ;get green in byte 2
|
||
move.b pin(a6),d3 ;put blue in lo byte
|
||
|
||
bSubPin32Main
|
||
move.l a4,a0 ;get working copy of srcptr
|
||
add.w d6,a0 ;index into pattern
|
||
move.l a5,a2 ;get working copy of dstptr
|
||
move.l Lo3Bytes,d1 ;pick up mask
|
||
|
||
@loopTop
|
||
move.l (a0),d5 ;get a pixel of the source xrgb
|
||
and.l d1,d5 ;waste high byte
|
||
add a3,a0 ;bump bi-directionally
|
||
move.l (a2),d7 ;get a pixel of the dest xrgb
|
||
and.l d1,d7 ;waste high byte
|
||
move.l d7,d0 ;make a copy of the dst xrgb
|
||
|
||
st d0 ;prevent borrows from below
|
||
sub.w d5,d0 ;sub green components
|
||
BCS.S @PinGreen
|
||
cmp.w d3,d0 ;do we need to pin result?
|
||
bhs.s @GreenOK
|
||
@PinGreen
|
||
move.w d3,d0 ;use pin value instead
|
||
@GreenOK
|
||
move.b d7,d0 ;get dest blue
|
||
sub.b d5,d0 ;sub src blue
|
||
BCS.S @PinBlue
|
||
cmp.b d3,d0 ;do we need to pin result?
|
||
bhs.s @BlueOK
|
||
@PinBlue
|
||
move.b d3,d0 ;use pin value instead
|
||
@BlueOK
|
||
clr.w d5 ;now d5 has only red in byte 3
|
||
sub.l d5,d0 ;sub red components
|
||
cmp.l d3,d0 ;compare red components
|
||
bge.s @RedOK
|
||
@PinRed
|
||
swap d3 ;get max red in lo word
|
||
swap d0 ;get too big red in lo word
|
||
move.w d3,d0 ;pin to max red
|
||
swap d0 ;get back 0rgb
|
||
swap d3 ;restore pin pixel
|
||
@RedOK
|
||
move.l d0,(a2) ;move to the destination
|
||
add a3,a2 ;bump bi-directionally
|
||
addq.l #4,d6 ;bump pattern offset
|
||
and.l d4,d6 ;constrict to the source long if in a pattern mode
|
||
bne.s @patOK ;don't need to reload pat ptr
|
||
move.l a4,a0 ;reload pat ptr
|
||
@patOK DBRA D2,@loopTop ;do it for all pixels on the line
|
||
BRA NxtNewSrc32 ;LOOP BACK FOR MORE
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
; a0 = tmpsrc d0 = result/scratch
|
||
; a1 = modeCase d1 = borrow stopper
|
||
; a2 = tmpdst d2 = longCnt
|
||
; a3 = hBump d3 = pin pixel 0rgb
|
||
; a4 = srcPtr/patPtr d4 = patHMask (bytes)
|
||
; a5 = dstPtr d5 = src long
|
||
; a6 = locals d6 = pat offset (bytes)
|
||
; a7^= d7 = dst long
|
||
;-------------------------------------------------------
|
||
bSubPin16
|
||
lea bSubPin16Main,A1 ;go there from now on
|
||
moveq #0,d3 ;start fresh, waste iTabRes
|
||
move.b pin+4(a6),d3 ;pick up red
|
||
lsr.b #3,d3 ;get right aligned 5 bits
|
||
swap d3 ;put in byte 3
|
||
move.w pin+2(a6),d3 ;get green in byte 2
|
||
lsr.w #3,d3 ;get right aligned 5 bits
|
||
move.b pin(a6),d3 ;put blue in lo byte
|
||
lsr.b #3,d3 ;right flush blue
|
||
add.l #$808080,d3 ;prevent borrows from crossing byte boundaries
|
||
|
||
bSubPin16Main
|
||
move.l a4,a0 ;get working copy of srcptr
|
||
add.w d6,a0 ;index into pattern
|
||
move.l a5,a2 ;get working copy of dstptr
|
||
move.l #$808080,d1 ;borrow stopper
|
||
|
||
@loopTop
|
||
moveq #0,d5
|
||
move.w (a0),d5 ;get a pixel of the source xrgb
|
||
add a3,a0 ;bump bi-directionally
|
||
add.w d5,d5 ;waste high bit
|
||
lsl.l #5,d5 ;but red in byte 3
|
||
lsr.w #3,d5 ;but green in byte 2, blue in lo byte
|
||
lsr.b #3,d5 ;right flush blue
|
||
|
||
moveq #0,d7
|
||
move.w (a2),d7 ;get a pixel of the dest xrgb
|
||
add.w d7,d7 ;waste high bit
|
||
lsl.l #5,d7 ;but red in byte 3
|
||
lsr.w #3,d7 ;but green in byte 2, blue in lo byte
|
||
lsr.b #3,d7 ;right flush blue
|
||
add.l d1,d7 ;prevent borrows from crossing byte boundaries
|
||
|
||
sub.l d5,d7 ;sub all components at once
|
||
move.l d7,d0 ;prime result with red
|
||
cmp.l d3,d0 ;do we need to pin result?
|
||
bhs.s @redOK ;no, don't pin
|
||
move.l d3,d0 ;use pin value instead
|
||
@redOK
|
||
move.w d7,d0 ;prime result with green
|
||
cmp.w d3,d0 ;do we need to pin result?
|
||
bhs.s @greenOK ;no, don't pin
|
||
move.w d3,d0 ;use pin value instead
|
||
@greenOK
|
||
move.b d7,d0 ;prime result with blue
|
||
cmp.b d3,d0 ;do we need to pin result?
|
||
bhs.s @blueOK ;no, don't pin
|
||
move.b d3,d0 ;use pin value instead
|
||
@blueOK
|
||
|
||
lsl.b #3,d0 ;rejoin green/blue
|
||
lsl.w #3,d0 ;rejoin red/green/blue
|
||
lsr.l #6,d0 ;right flush red/green/blue
|
||
|
||
move.w d0,(a2) ;move to the destination
|
||
add a3,a2 ;bump bi-directionally
|
||
addq.l #2,d6 ;bump pattern offset
|
||
and.l d4,d6 ;constrict to the source long if in a pattern mode
|
||
bne.s @patOK ;don't need to reload pat ptr
|
||
move.l a4,a0 ;reload pat ptr
|
||
@patOK DBRA D2,@loopTop ;do it for all pixels on the line
|
||
BRA NxtNewSrc32 ;LOOP BACK FOR MORE
|
||
|
||
endif ;<14>
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 37, 45, 61: MAX(SRC, DST) --> DST
|
||
;
|
||
; Note: D4 is unused
|
||
|
||
bMax
|
||
bMaxIndexed
|
||
;
|
||
; if we are going backwards, align destination and mask <14AUG90 KON>
|
||
;
|
||
tst (sp) ;is bump amount negative? <14AUG90 KON>
|
||
bpl.s @RealbMax1 ; <14AUG90 KON>
|
||
sub.l (SP),D6 ;bump src right OR left by 1 pixel first time only <14AUG90 KON>
|
||
|
||
@RealbMax
|
||
tst (sp) ;is bump amount negative? <14AUG90 KON>
|
||
bpl.s @RealbMax1 ; <14AUG90 KON>
|
||
sub.l (SP),D0 ;align destination and mask each scan line <14AUG90 KON>
|
||
@RealbMax1
|
||
MOVE.L colorTable(A6),A1 ;set up color table
|
||
TST D2 ;is there only 1 long?
|
||
BGT.S @firstMask ;if not, use the first mask in D1
|
||
@forceLast
|
||
OR.B #3,doneMid(A6) ;note that the first part and mid part are done
|
||
@lastMask
|
||
MOVE pixInLong(A6),D2 ;loop once for each pixel in the long
|
||
AND.L lastMask(A6),D1 ;MASK:=MASK AND LASTMASK
|
||
@firstMask
|
||
@loopTop
|
||
AND patHMask(A6),D6 ;constrict to the source long if in a pattern mode
|
||
BFEXTU D1{D0:D7},D3 ;a pixel of the mask
|
||
BEQ.S @skip
|
||
|
||
BFEXTU (A4){D6:D7},D3 ;get a pixel of the source (zeros top word)
|
||
LEA red(A1,D3*8),A2 ;figure out where it lives in the color table
|
||
BFEXTU (A5){D0:D7},D3 ;a pixel of the destination
|
||
LEA red(A1,D3*8),A3 ;figure out where destination lives
|
||
MOVE (A2)+,D3 ;get source color value
|
||
CMP (A3),D3 ;combine source and destination
|
||
BHS.S @gotTheMaxRed
|
||
MOVE (A3),D3
|
||
@gotTheMaxRed
|
||
ADDQ #2,A3 ;advance to next color
|
||
ASL.L D5,D3 ;save the top bits in the top word
|
||
MOVE (A2)+,D3 ;get source color value
|
||
CMP (A3),D3 ;combine source and destination
|
||
BHS.S @gotTheMaxGreen
|
||
MOVE (A3),D3
|
||
@gotTheMaxGreen
|
||
ADDQ #2,A3 ;advance to next color
|
||
ASL.L D5,D3 ;save the top bits in the top word
|
||
MOVE (A2)+,D3 ;get source color value
|
||
CMP (A3),D3 ;combine source and destination
|
||
BHS.S @gotTheMaxBlue
|
||
MOVE (A3),D3
|
||
@gotTheMaxBlue
|
||
ASL.L D5,D3 ;save the top bits in the top word
|
||
SWAP D3 ;r, g, b in high word
|
||
MOVE.B itTable(A0,D3),D3 ;get the pixel value of the additive sum
|
||
BFINS D3,(A5){D0:D7} ;move to the destination
|
||
@skip
|
||
ADD.L (SP),D6 ;BUMP SRCPTR LEFT OR RIGHT by 1 pixel
|
||
ADD.L (SP),D0 ;bump destination and mask
|
||
DBRA D2,@loopTop ;do it for all of the pixels on the line (or within the mask)
|
||
MOVEQ #-1,D1 ;flush mask
|
||
BSET #0,doneMid(A6) ;has the middle part already been done?
|
||
BNE.S @midDone ;if so, skip it
|
||
MOVE midCount(A6),D2 ;reset to mid count
|
||
BMI.S @forceLast ;if none, just do the last part
|
||
BRA.S @loopTop
|
||
@midDone
|
||
BSET #1,doneMid(A6) ;already done the last mask part too?
|
||
BEQ.S @lastMask ;if not, do it
|
||
lea @RealbMax,A1 ;restore address to ourselves <14AUG90 KON>
|
||
BRA NxtNewSrc ;LOOP BACK FOR MORE
|
||
|
||
|
||
if blit32 then ;<14>
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
; a0 = tmpsrc d0 = result/scratch
|
||
; a1 = modeCase d1 =
|
||
; a2 = tmpdst d2 = longCnt
|
||
; a3 = hBump d3 = patHBump (bytes)
|
||
; a4 = srcPtr/patPtr d4 = patHMask (bytes)
|
||
; a5 = dstPtr d5 = dst long
|
||
; a6 = locals d6 = pat offset (bytes)
|
||
; a7 = d7 = src long
|
||
;-------------------------------------------------------
|
||
bMax32
|
||
move.l a4,a0 ;get working copy of srcptr
|
||
add.w d6,a0 ;index into pattern
|
||
move.l a5,a2 ;get working copy of dstptr
|
||
|
||
@loopTop
|
||
move.l (a0),d7 ;get a pixel of the source xrgb
|
||
add a3,a0 ;bump bi-directionally
|
||
move.l (a2),d5 ;get a pixel of the dest xrgb
|
||
move.l d5,d0 ;make a copy of the dest xrgb
|
||
cmp.w d7,d0 ;compare g,b components
|
||
BHI.S @gotTheMaxGreen
|
||
move.w d7,d0 ;keep the bigger of the two
|
||
move.b d5,d0 ;prime for blue
|
||
@gotTheMaxGreen
|
||
cmp.b d7,d5 ;compare blue components
|
||
BHI.S @gotTheMaxBlue
|
||
move.b d7,d0 ;keep the bigger of the two
|
||
@gotTheMaxBlue
|
||
swap d7
|
||
swap d0
|
||
cmp.b d7,d0 ;compare red components
|
||
BHI.S @gotTheMaxRed
|
||
move.b d7,d0 ;keep the bigger of the two
|
||
@gotTheMaxRed
|
||
swap d0 ;get new xrgb
|
||
move.l d0,(a2) ;move to the destination
|
||
add a3,a2 ;bump bi-directionally
|
||
addq.l #4,d6 ;bump pattern offset
|
||
and.l d4,d6 ;constrict to the source long if in a pattern mode
|
||
bne.s @patOK ;don't need to reload pat ptr
|
||
move.l a4,a0 ;reload pat ptr
|
||
@patOK DBRA D2,@loopTop ;do it for all pixels on the line
|
||
BRA NxtNewSrc32 ;LOOP BACK FOR MORE
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
; a0 = tmpsrc d0 = result/scratch
|
||
; a1 = modeCase d1 =
|
||
; a2 = tmpdst d2 = longCnt
|
||
; a3 = hBump d3 = patHBump (bytes)
|
||
; a4 = srcPtr/patPtr d4 = patHMask (bytes)
|
||
; a5 = dstPtr d5 = dst long
|
||
; a6 = locals d6 = pat offset (bytes)
|
||
; a7 = d7 = src long
|
||
;-------------------------------------------------------
|
||
bMax16
|
||
move.l a4,a0 ;get working copy of srcptr
|
||
add.w d6,a0 ;index into pattern
|
||
move.l a5,a2 ;get working copy of dstptr
|
||
|
||
@loopTop
|
||
moveq #0,d7
|
||
move.w (a0),d7 ;get a pixel of the source xrgb
|
||
add a3,a0 ;bump bi-directionally
|
||
add.w d7,d7 ;waste high bit
|
||
lsl.l #5,d7 ;but red in byte 3
|
||
lsr.w #3,d7 ;but green in byte 2, blue in lo byte
|
||
lsr.b #3,d7 ;right flush blue
|
||
|
||
moveq #0,d5
|
||
move.w (a2),d5 ;get a pixel of the dest xrgb
|
||
add.w d5,d5 ;waste high bit
|
||
lsl.l #5,d5 ;but red in byte 3
|
||
lsr.w #3,d5 ;but green in byte 2, blue in lo byte
|
||
lsr.b #3,d5 ;right flush blue
|
||
|
||
move.l d7,d0 ;prime result with src
|
||
cmp.l d5,d0 ;is dst greater?
|
||
bhs.s @gotRed ;no, use src
|
||
move.l d5,d0 ;use dst value instead
|
||
@gotRed
|
||
move.w d7,d0 ;prime result with src
|
||
cmp.w d5,d0 ;is dst greater?
|
||
bhs.s @gotGreen ;no, use src
|
||
move.w d5,d0 ;use dst value instead
|
||
@gotGreen
|
||
move.b d7,d0 ;prime result with src
|
||
cmp.b d5,d0 ;is dst greater?
|
||
bhs.s @gotBlue ;no, use src
|
||
move.b d5,d0 ;use dst value instead
|
||
@gotBlue
|
||
|
||
lsl.b #3,d0 ;rejoin green/blue
|
||
lsl.w #3,d0 ;rejoin red/green/blue
|
||
lsr.l #6,d0 ;right flush red/green/blue
|
||
|
||
move.w d0,(a2) ;move to the destination
|
||
add a3,a2 ;bump bi-directionally
|
||
addq.l #2,d6 ;bump pattern offset
|
||
and.l d4,d6 ;constrict to the source long if in a pattern mode
|
||
bne.s @patOK ;don't need to reload pat ptr
|
||
move.l a4,a0 ;reload pat ptr
|
||
@patOK DBRA D2,@loopTop ;do it for all pixels on the line
|
||
BRA NxtNewSrc32 ;LOOP BACK FOR MORE
|
||
|
||
endif ;<14>
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 39, 47, 63: MIN(SRC, DST) --> DST
|
||
;
|
||
; Note: D4 is unused
|
||
|
||
bMin
|
||
bMinIndexed
|
||
;
|
||
; if we are going backwards, align destination and mask <14AUG90 KON>
|
||
;
|
||
tst (sp) ;is bump amount negative? <14AUG90 KON>
|
||
bpl.s @RealbMin1 ; <14AUG90 KON>
|
||
sub.l (SP),D6 ;bump src right OR left by 1 pixel first time only <14AUG90 KON>
|
||
|
||
@RealbMin
|
||
tst (sp) ;is bump amount negative? <14AUG90 KON>
|
||
bpl.s @RealbMin1 ; <14AUG90 KON>
|
||
sub.l (SP),D0 ;align destination and mask each scan line <14AUG90 KON>
|
||
@RealbMin1
|
||
|
||
MOVE.L colorTable(A6),A1 ;set up color table
|
||
TST D2 ;is there only 1 long?
|
||
BGT.S @firstMask ;if not, use the first mask in D1
|
||
@forceLast
|
||
OR.B #3,doneMid(A6) ;note that the first part and mid part are done
|
||
@lastMask
|
||
MOVE pixInLong(A6),D2 ;loop once for each pixel in the long
|
||
AND.L lastMask(A6),D1 ;MASK:=MASK AND LASTMASK
|
||
@firstMask
|
||
@loopTop
|
||
AND patHMask(A6),D6 ;constrict to the source long if in a pattern mode
|
||
BFEXTU D1{D0:D7},D3 ;a pixel of the mask
|
||
BEQ.S @skip
|
||
|
||
BFEXTU (A4){D6:D7},D3 ;get a pixel of the source (zeros top word)
|
||
LEA red(A1,D3*8),A2 ;figure out where it lives in the color table
|
||
BFEXTU (A5){D0:D7},D3 ;a pixel of the destination
|
||
LEA red(A1,D3*8),A3 ;figure out where destination lives
|
||
MOVE (A2)+,D3 ;get source color value
|
||
CMP (A3),D3 ;combine source and destination
|
||
BLS.S @gotTheMinRed
|
||
MOVE (A3),D3
|
||
@gotTheMinRed
|
||
ADDQ #2,A3 ;advance to next color
|
||
ASL.L D5,D3 ;save the top bits in the top word
|
||
MOVE (A2)+,D3 ;get source color value
|
||
CMP (A3),D3 ;combine source and destination
|
||
BLS.S @gotTheMinGreen
|
||
MOVE (A3),D3
|
||
@gotTheMinGreen
|
||
ADDQ #2,A3 ;advance to next color
|
||
ASL.L D5,D3 ;save the top bits in the top word
|
||
MOVE (A2)+,D3 ;get source color value
|
||
CMP (A3),D3 ;combine source and destination
|
||
BLS.S @gotTheMinBlue
|
||
MOVE (A3),D3
|
||
@gotTheMinBlue
|
||
ASL.L D5,D3 ;save the top bits in the top word
|
||
SWAP D3 ;r, g, b in high word
|
||
MOVE.B itTable(A0,D3),D3 ;get the pixel value of the additive sum
|
||
BFINS D3,(A5){D0:D7} ;move to the destination
|
||
@skip
|
||
ADD.L (SP),D6 ;BUMP SRCPTR LEFT OR RIGHT by 1 pixel
|
||
ADD.L (SP),D0 ;bump destination and mask
|
||
DBRA D2,@loopTop ;do it for all of the pixels on the line (or within the mask)
|
||
MOVEQ #-1,D1 ;flush mask
|
||
BSET #0,doneMid(A6) ;has the middle part already been done?
|
||
BNE.S @midDone ;if so, skip it
|
||
MOVE midCount(A6),D2 ;reset to mid count
|
||
BMI.S @forceLast ;if none, just do the last part
|
||
BRA.S @loopTop
|
||
@midDone
|
||
BSET #1,doneMid(A6) ;already done the last mask part too?
|
||
BEQ.S @lastMask ;if not, do it
|
||
lea @RealbMin,A1 ;restore address to ourselves <14AUG90 KON>
|
||
BRA NxtNewSrc ;LOOP BACK FOR MORE
|
||
|
||
|
||
if blit32 then ;<14>
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
; a0 = tmpsrc d0 = result/scratch
|
||
; a1 = modeCase d1 =
|
||
; a2 = tmpdst d2 = longCnt
|
||
; a3 = hBump d3 = patHBump (bytes)
|
||
; a4 = srcPtr/patPtr d4 = patHMask (bytes)
|
||
; a5 = dstPtr d5 = dst long
|
||
; a6 = locals d6 = pat offset (bytes)
|
||
; a7 = d7 = src long
|
||
;-------------------------------------------------------
|
||
bMin32
|
||
move.l a4,a0 ;get working copy of srcptr
|
||
add.w d6,a0 ;index into pattern
|
||
move.l a5,a2 ;get working copy of dstptr
|
||
|
||
@loopTop
|
||
move.l (a0),d7 ;get a pixel of the source xrgb
|
||
add a3,a0 ;bump bi-directionally
|
||
move.l (a2),d5 ;get a pixel of the dest xrgb
|
||
move.l d5,d0 ;make a copy of the dest xrgb
|
||
cmp.w d7,d0 ;compare g,b components
|
||
BLS.S @gotTheMinGreen
|
||
move.w d7,d0 ;keep the smaller of the two
|
||
move.b d5,d0 ;prime for blue
|
||
@gotTheMinGreen
|
||
cmp.b d7,d5 ;compare blue components
|
||
BLS.S @gotTheMinBlue
|
||
move.b d7,d0 ;keep the smaller of the two
|
||
@gotTheMinBlue
|
||
swap d7
|
||
swap d0
|
||
cmp.b d7,d0 ;compare red components
|
||
BLS.S @gotTheMinRed
|
||
move.b d7,d0 ;keep the smaller of the two
|
||
@gotTheMinRed
|
||
swap d0 ;get new xrgb
|
||
move.l d0,(a2) ;move to the destination
|
||
add a3,a2 ;bump bi-directionally
|
||
addq.l #4,d6 ;bump pattern offset
|
||
and.l d4,d6 ;constrict to the source long if in a pattern mode
|
||
bne.s @patOK ;don't need to reload pat ptr
|
||
move.l a4,a0 ;reload pat ptr
|
||
@patOK DBRA D2,@loopTop ;do it for all pixels on the line
|
||
BRA NxtNewSrc32 ;LOOP BACK FOR MORE
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
; a0 = tmpsrc d0 = result/scratch
|
||
; a1 = modeCase d1 =
|
||
; a2 = tmpdst d2 = longCnt
|
||
; a3 = hBump d3 = patHBump (bytes)
|
||
; a4 = srcPtr/patPtr d4 = patHMask (bytes)
|
||
; a5 = dstPtr d5 = dst long
|
||
; a6 = locals d6 = pat offset (bytes)
|
||
; a7 = d7 = src long
|
||
;-------------------------------------------------------
|
||
bMin16
|
||
move.l a4,a0 ;get working copy of srcptr
|
||
add.w d6,a0 ;index into pattern
|
||
move.l a5,a2 ;get working copy of dstptr
|
||
|
||
@loopTop
|
||
moveq #0,d7
|
||
move.w (a0),d7 ;get a pixel of the source xrgb
|
||
add a3,a0 ;bump bi-directionally
|
||
add.w d7,d7 ;waste high bit
|
||
lsl.l #5,d7 ;but red in byte 3
|
||
lsr.w #3,d7 ;but green in byte 2, blue in lo byte
|
||
lsr.b #3,d7 ;right flush blue
|
||
|
||
moveq #0,d5
|
||
move.w (a2),d5 ;get a pixel of the dest xrgb
|
||
add.w d5,d5 ;waste high bit
|
||
lsl.l #5,d5 ;but red in byte 3
|
||
lsr.w #3,d5 ;but green in byte 2, blue in lo byte
|
||
lsr.b #3,d5 ;right flush blue
|
||
|
||
move.l d7,d0 ;prime result with src
|
||
cmp.l d5,d0 ;is dst smaller?
|
||
bls.s @gotRed ;no, use src
|
||
move.l d5,d0 ;use dst value instead
|
||
@gotRed
|
||
move.w d7,d0 ;prime result with src
|
||
cmp.w d5,d0 ;is dst smaller?
|
||
bls.s @gotGreen ;no, use src
|
||
move.w d5,d0 ;use dst value instead
|
||
@gotGreen
|
||
move.b d7,d0 ;prime result with src
|
||
cmp.b d5,d0 ;is dst smaller?
|
||
bls.s @gotBlue ;no, use src
|
||
move.b d5,d0 ;use dst value instead
|
||
@gotBlue
|
||
|
||
lsl.b #3,d0 ;rejoin green/blue
|
||
lsl.w #3,d0 ;rejoin red/green/blue
|
||
lsr.l #6,d0 ;right flush red/green/blue
|
||
|
||
move.w d0,(a2) ;move to the destination
|
||
add a3,a2 ;bump bi-directionally
|
||
addq.l #2,d6 ;bump pattern offset
|
||
and.l d4,d6 ;constrict to the source long if in a pattern mode
|
||
bne.s @patOK ;don't need to reload pat ptr
|
||
move.l a4,a0 ;reload pat ptr
|
||
@patOK DBRA D2,@loopTop ;do it for all pixels on the line
|
||
BRA NxtNewSrc32 ;LOOP BACK FOR MORE
|
||
|
||
endif ;<14>
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 32, 40, 56: AVG(SRC, DST, WEIGHT) --> DST
|
||
|
||
bAvg
|
||
bAvgIndexed
|
||
;
|
||
; if we are going backwards, align destination and mask <13AUG90 KON>
|
||
;
|
||
tst (sp) ;is bump amount negative? <13AUG90 KON>
|
||
bpl.s @RealbAvg1 ; <13AUG90 KON>
|
||
sub.l (SP),D6 ;bump src right OR left by 1 pixel first time only <13AUG90 KON>
|
||
|
||
@RealbAvg
|
||
tst (sp) ;is bump amount negative? <13AUG90 KON>
|
||
bpl.s @RealbAvg1 ; <13AUG90 KON>
|
||
sub.l (SP),D0 ;align destination and mask each scan line <13AUG90 KON>
|
||
@RealbAvg1
|
||
MOVE.L colorTable(A6),A1 ;set up color table
|
||
TST D2 ;is there only 1 long?
|
||
BGT.S @firstMask ;if not, use the first mask in D1
|
||
@forceLast
|
||
OR.B #3,doneMid(A6) ;note that the first part and mid part are done
|
||
@lastMask
|
||
MOVE pixInLong(A6),D2 ;loop once for each pixel in the long
|
||
AND.L lastMask(A6),D1 ;MASK:=MASK AND LASTMASK
|
||
@firstMask
|
||
@loopTop
|
||
AND patHMask(A6),D6 ;constrict to the source long if in a pattern mode
|
||
BFEXTU D1{D0:D7},D3 ;a pixel of the mask
|
||
BEQ.S @skip
|
||
|
||
BFEXTU (A4){D6:D7},D3 ;get a pixel of the source (zeros top word)
|
||
LEA red(A1,D3*8),A2 ;figure out where it lives in the color table
|
||
BFEXTU (A5){D0:D7},D3 ;a pixel of the destination
|
||
LEA red(A1,D3*8),A3 ;figure out where destination lives
|
||
MOVE.l D0,-(SP) ;preserve mask/destination offset <13AUG90 KON>
|
||
MOVEQ #2,D0 ;once for each color
|
||
MOVE invSize(A6),D4 ;do once for r, b and g
|
||
ADD D4,D4 ;initialize at 2x for shift count
|
||
CLR -(SP) ;make space & initialize average r, b, g
|
||
@nextColor
|
||
MOVE (A2)+,D3 ;get source color value
|
||
MULU (weight,A6,D0*2),D3 ;weight varies from 0 to 1
|
||
MOVE (A3)+,D5 ;get destination color value
|
||
MULU (notWeight,A6,D0*2),D5 ;weight varies from 1 to 0
|
||
ADD.L D5,D3 ;add source + dest
|
||
SWAP D3 ;high word is interesting part
|
||
MOVE rtShift(A6),D5 ;amount to shift right
|
||
LSR D5,D3 ;get top bits only
|
||
LSL D4,D3 ;shift by 2x, 1x, or 0 (for r, g, & b)
|
||
OR D3,(SP) ;combine r, g, b
|
||
SUB invSize(A6),D4 ;decrement shift, weight index
|
||
DBRA D0,@nextColor ;do for b & g as well
|
||
|
||
MOVE (SP)+,D3 ;r, g, b
|
||
MOVE.l (SP)+,D0 ;restore mask/destination offset <13AUG90 KON>
|
||
MOVE.B itTable(A0,D3),D3 ;get the pixel value of the additive sum
|
||
BFINS D3,(A5){D0:D7} ;move to the destination
|
||
@skip
|
||
ADD.L (SP),D6 ;BUMP SRCPTR LEFT OR RIGHT by 1 pixel
|
||
ADD.L (SP),D0 ;bump destination and mask
|
||
DBRA D2,@loopTop ;do it for all of the pixels on the line (or within the mask)
|
||
MOVEQ #-1,D1 ;flush mask
|
||
BSET #0,doneMid(A6) ;has the middle part already been done?
|
||
BNE.S @midDone ;if so, skip it
|
||
MOVE midCount(A6),D2 ;reset to mid count
|
||
BMI.S @forceLast ;if none, just do the last part
|
||
BRA.S @loopTop
|
||
@midDone
|
||
BSET #1,doneMid(A6) ;already done the last mask part too?
|
||
BEQ.S @lastMask ;if not, do it
|
||
lea @RealbAvg,a1 ;from now on, enter at @RealbAvg <13AUG90 KON>
|
||
BRA NxtNewSrc ;LOOP BACK FOR MORE
|
||
|
||
|
||
|
||
if blit32 then ;<14>
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
; a0 = tmpsrc d0 = high bit mask
|
||
; a1 = modeCase d1 = low bit mask
|
||
; a2 = tmpdst d2 = longCnt
|
||
; a3 = hBump d3 = lsb's of result
|
||
; a4 = srcPtr/patPtr d4 = patHMask
|
||
; a5 = dstPtr d5 = dest pixel
|
||
; a6 = locals d6 = pat offset
|
||
; a7^= patHBump d7 = src pixel
|
||
;-------------------------------------------------------
|
||
bAvg32Half
|
||
move.l a4,a0 ;get working copy of srcptr
|
||
add.w d6,a0 ;index into pattern
|
||
move.l a5,a2 ;get working copy of dstptr
|
||
|
||
move.l #~$ff808080,d0 ;get high bit mask
|
||
move.l #$10101,d1 ;get low bit mask
|
||
|
||
@loopTop
|
||
move.l d1,d3 ;copy low bit mask
|
||
move.l (a0),d7 ;get a pixel of the source xrgb
|
||
and.l d7,d3 ;remember src lsb's
|
||
add.w a3,a0 ;bump bidirectionally
|
||
lsr.l #1,d7 ;get almost 1/2 of it
|
||
and.l d0,d7 ;mask out stragglers
|
||
|
||
move.l (a2),d5 ;get a pixel of the dest xrgb
|
||
and.l d5,d3 ;compute carry out of lsb
|
||
lsr.l #1,d5 ;get almost 1/2 of it
|
||
and.l d0,d5 ;mask out stragglers
|
||
|
||
add.l d5,d7 ;merge src with dst
|
||
add.l d3,d7 ;propagate carrys
|
||
move.l d7,(a2) ;move to the destination
|
||
add.w a3,a2 ;bump bidirectionally
|
||
addq.l #4,d6 ;bump pattern offset
|
||
and.l d4,d6 ;constrict to the source long if in a pattern mode
|
||
bne.s @patOK ;don't need to reload pat ptr
|
||
move.l a4,a0 ;reload pat ptr
|
||
@patOK DBRA D2,@loopTop ;do it for all pixels on the line
|
||
BRA NxtNewSrc32 ;LOOP BACK FOR MORE
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
; a0 = tmpsrc d0 = high bit mask
|
||
; a1 = modeCase d1 = low bit mask
|
||
; a2 = tmpdst d2 = longCnt
|
||
; a3 = hBump d3 = lsb's of result
|
||
; a4 = srcPtr/patPtr d4 = patHMask
|
||
; a5 = dstPtr d5 = dest pixel
|
||
; a6 = locals d6 = pat offset
|
||
; a7^= patHBump d7 = src pixel
|
||
;-------------------------------------------------------
|
||
bAvg16Half
|
||
move.l a4,a0 ;get working copy of srcptr
|
||
add.w d6,a0 ;index into pattern
|
||
move.l a5,a2 ;get working copy of dstptr
|
||
|
||
move.w #$3def,d0 ;get high bit clearing mask
|
||
move.w #$0421,d1 ;get low bit mask
|
||
|
||
@loopTop
|
||
move.l d1,d3 ;copy low bit mask
|
||
move.w (a0),d7 ;get a pixel of the source xrgb
|
||
and.w d7,d3 ;remember src lsb's
|
||
add.w a3,a0 ;bump bidirectionally
|
||
lsr.w #1,d7 ;get almost 1/2 of it
|
||
and.w d0,d7 ;mask out stragglers
|
||
|
||
move.w (a2),d5 ;get a pixel of the dest xrgb
|
||
and.w d5,d3 ;compute carry out of lsb
|
||
lsr.w #1,d5 ;get almost 1/2 of it
|
||
and.w d0,d5 ;mask out stragglers
|
||
|
||
add.w d5,d7 ;merge src with dst
|
||
add.w d3,d7 ;propagate carrys
|
||
move.w d7,(a2) ;move to the destination
|
||
add.w a3,a2 ;bump bidirectionally
|
||
addq.l #2,d6 ;bump pattern offset
|
||
and.l d4,d6 ;constrict to the source long if in a pattern mode
|
||
bne.s @patOK ;don't need to reload pat ptr
|
||
move.l a4,a0 ;reload pat ptr
|
||
@patOK DBRA D2,@loopTop ;do it for all pixels on the line
|
||
BRA NxtNewSrc32 ;LOOP BACK FOR MORE
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
; a0 = tmpsrc d0 = red weight
|
||
; a1 = last dst/mcase d1 = blue/grn weight
|
||
; a2 = tmpdst d2 = longCnt
|
||
; a3 = hBump d3 = scratch
|
||
; a4 = srcPtr/patPtr d4 = scratch
|
||
; a5 = dstPtr d5 = dest pixel
|
||
; a6 = locals d6 = pat offset
|
||
; a7 = d7 = src pixel
|
||
;-------------------------------------------------------
|
||
bAvg32
|
||
lea weight(a6),a0 ;point at blue weight
|
||
move.l (a0)+,d1 ;get blue/green weight
|
||
move.w (a0),d0 ;get red weight
|
||
move.l a4,a0 ;get working copy of srcptr
|
||
add.w d6,a0 ;index into pattern
|
||
move.l a5,a2 ;get working copy of dstptr
|
||
|
||
@short0 moveq #0,d4 ;init last result
|
||
move.l d4,d3 ;init last src
|
||
move.l d4,a1 ;init last dst
|
||
|
||
@loopTop
|
||
move.l (a0),d7 ;get a pixel of the source xrgb
|
||
add.w a3,a0 ;bump bidirectionally for MCF
|
||
move.l (a2),d5 ;get a pixel of the dest xrgb
|
||
|
||
@short1 cmp.l d3,d7 ;same as last time?
|
||
bne.s @blue ;no, go do it
|
||
cmp.l a1,d5 ;same as last time?
|
||
beq.s @again ;yes, go fast
|
||
|
||
@blue moveq #0,d3 ;clr out high end
|
||
move.b d7,d3 ;get src blue
|
||
swap d1 ;get blue weight
|
||
mulu.w d1,d3 ;% blue
|
||
|
||
moveq #0,d4 ;clr out high end
|
||
move.b d5,d4 ;get dst blue
|
||
neg.w d1
|
||
mulu.w d1,d4 ;% blue
|
||
neg.w d1
|
||
|
||
add.l d3,d4 ;get 24 bits of dst blue
|
||
swap d4 ;dst blue
|
||
move.w d4,a1 ;a1 has 000B
|
||
|
||
@grn move.w d7,d3 ;get src grn
|
||
lsr.w #8,d3
|
||
swap d1 ;get grn weight
|
||
mulu.w d1,d3 ;% grn
|
||
|
||
move.w d5,d4 ;get dst grn
|
||
lsr.w #8,d4
|
||
neg.w d1
|
||
mulu.w d1,d4 ;% grn
|
||
neg.w d1
|
||
|
||
add.l d3,d4 ;get 24 bits of dst grn
|
||
swap d4 ;dst grn
|
||
lsl.w #8,d4
|
||
add.w d4,a1 ;a1 has 00GB
|
||
|
||
@red moveq #0,d3 ;clr out high end
|
||
swap d7
|
||
move.b d7,d3 ;get src red
|
||
mulu.w d0,d3 ;% red
|
||
|
||
moveq #0,d4 ;clr out high end
|
||
swap d5
|
||
move.b d5,d4 ;get dst red
|
||
neg.w d0
|
||
mulu.w d0,d4 ;% red
|
||
neg.w d0
|
||
|
||
add.l d3,d4 ;get 24 bits of dst red
|
||
move.w a1,d4 ;d4 has 0RGB
|
||
|
||
@short2 swap d5 ;get back dst
|
||
move.l d5,a1 ;save for short circuit
|
||
swap d7 ;get back src
|
||
move.l d7,d3 ;save for short circuit
|
||
|
||
@again
|
||
move.l d4,(a2) ;move to the destination
|
||
add.w a3,a2 ;bump bidirectionally for MCF
|
||
addq.w #4,d6 ;bump horizontally in pattern
|
||
and.w patHMask(a6),d6 ;force pattern offset to wrap
|
||
bne.s @patOK
|
||
move.l a4,a0 ;reload pat ptr
|
||
@patOK DBRA D2,@loopTop ;do it for all pixels on the line
|
||
lea bAvg32,a1 ;reload modecase
|
||
BRA NxtNewSrc32 ;LOOP BACK FOR MORE
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
; a0 = tmpsrc d0 = red weight
|
||
; a1 = last dst/mcase d1 = blue/grn weight
|
||
; a2 = tmpdst d2 = longCnt
|
||
; a3 = hBump d3 = scratch
|
||
; a4 = srcPtr/patPtr d4 = scratch
|
||
; a5 = dstPtr d5 = dest pixel
|
||
; a6 = locals d6 = pat offset
|
||
; a7 = d7 = src pixel
|
||
;-------------------------------------------------------
|
||
bAvg16
|
||
lea weight(a6),a0 ;point at blue weight
|
||
move.l (a0)+,d1 ;get blue/green weight
|
||
move.w (a0),d0 ;get red weight
|
||
move.l a4,a0 ;get working copy of srcptr
|
||
add.w d6,a0 ;index into pattern
|
||
move.l a5,a2 ;get working copy of dstptr
|
||
|
||
@short0 moveq #0,d4 ;init last result
|
||
move.l d4,d3 ;init last src
|
||
move.l d4,a1 ;init last dst
|
||
|
||
@loopTop
|
||
moveq #0,d7
|
||
move.w (a0),d7 ;get a pixel of the source xrgb
|
||
add.w a3,a0 ;bump bidirectionally for MCF
|
||
moveq #0,d5
|
||
move.w (a2),d5 ;get a pixel of the dest xrgb
|
||
|
||
@short1 cmp.w d3,d7 ;same as last time?
|
||
bne.s @hardway ;no, go do it
|
||
cmp.w a1,d5 ;same as last time?
|
||
beq.s @again ;yes, go fast
|
||
|
||
@hardway
|
||
add.w d7,d7 ;waste high bit
|
||
lsl.l #5,d7 ;but red in byte 3
|
||
lsr.w #3,d7 ;but green in byte 2, blue in lo byte
|
||
lsr.b #3,d7 ;right flush blue
|
||
|
||
add.w d5,d5 ;waste high bit
|
||
lsl.l #5,d5 ;but red in byte 3
|
||
lsr.w #3,d5 ;but green in byte 2, blue in lo byte
|
||
lsr.b #3,d5 ;right flush blue
|
||
|
||
@blue moveq #0,d3 ;clr out high end
|
||
move.b d7,d3 ;get src blue
|
||
swap d1 ;get blue weight
|
||
mulu.w d1,d3 ;% blue
|
||
|
||
moveq #0,d4 ;clr out high end
|
||
move.b d5,d4 ;get dst blue
|
||
neg.w d1
|
||
mulu.w d1,d4 ;% blue
|
||
neg.w d1
|
||
|
||
add.l d3,d4 ;get 21 bits of blue
|
||
swap d4 ;right align 5 blue bits
|
||
move.l d4,a1 ;a1 has 000B
|
||
|
||
@grn move.w d7,d3 ;get src grn
|
||
lsr.w #8,d3
|
||
swap d1 ;get grn weight
|
||
mulu.w d1,d3 ;% grn
|
||
|
||
move.w d5,d4 ;get dst grn
|
||
lsr.w #8,d4
|
||
neg.w d1
|
||
mulu.w d1,d4 ;% grn
|
||
neg.w d1
|
||
|
||
add.l d3,d4 ;get 21 bits of grn
|
||
swap d4 ;right align 5 green bits
|
||
lsl.w #5,d4 ;shift into place
|
||
add.w d4,a1 ;a1 has 00GB
|
||
|
||
@red moveq #0,d3 ;clr out high end
|
||
swap d7
|
||
move.b d7,d3 ;get src red
|
||
mulu.w d0,d3 ;% red
|
||
|
||
moveq #0,d4 ;clr out high end
|
||
swap d5
|
||
move.b d5,d4 ;get dst red
|
||
neg.w d0
|
||
mulu.w d0,d4 ;% red
|
||
neg.w d0
|
||
|
||
add.l d3,d4 ;get 21 bits of red
|
||
clr.w d4 ;clear lsb's
|
||
lsr.l #6,d4 ;shift into place
|
||
add.w a1,d4 ;d4 has 0RGB
|
||
|
||
@short2 swap d5 ;get back dst
|
||
lsl.b #3,d5 ;rejoin green/blue
|
||
lsl.w #3,d5 ;rejoin red/green/blue
|
||
lsr.l #6,d5 ;right flush red/green/blue
|
||
move.l d5,a1 ;save for short circuit
|
||
swap d7 ;get back src
|
||
lsl.b #3,d7 ;rejoin green/blue
|
||
lsl.w #3,d7 ;rejoin red/green/blue
|
||
lsr.l #6,d7 ;right flush red/green/blue
|
||
move.l d7,d3 ;save for short circuit
|
||
|
||
@again
|
||
move.w d4,(a2) ;move to the destination
|
||
add.w a3,a2 ;bump bidirectionally for MCF
|
||
addq.w #2,d6 ;bump horizontally in pattern
|
||
and.w patHMask(a6),d6 ;force pattern offset to wrap
|
||
bne.s @patOK
|
||
move.l a4,a0 ;reload pat ptr
|
||
@patOK DBRA D2,@loopTop ;do it for all pixels on the line
|
||
lea bAvg16,a1 ;reload modecase
|
||
BRA NxtNewSrc32 ;LOOP BACK FOR MORE
|
||
|
||
endif ;<14>
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODE 50: Hilite DST (similar to invert)
|
||
; if dst = background, foreground color -> background
|
||
; if dst = foreground color, background -> foreground color
|
||
; do a long at a time when possible
|
||
;
|
||
;input
|
||
; D0 background pixel D1 mask D2 long count D3 ---
|
||
; D4 background long D5 foreground pixel D6 --- D7 pixel size
|
||
; A0 foreground long A1 --- A2 32-pixel size A3 ---
|
||
; A4 --- A5 destination pointer
|
||
;registers used:
|
||
; D3 scratch D6 scratch
|
||
;locals used:
|
||
; lastMask(A6) the right most long mask
|
||
bHilite
|
||
SUBQ #1,D2 ;more than 1 long?
|
||
BMI.S @lastMask ;if only 1 long, just do last mask & first mask
|
||
BSR.S hiliteMask ;mask off first part
|
||
SUBQ #1,D2 ;make inner loop DBRA count
|
||
BMI.S @fullMask ;if only left and right, skip middle part of loop
|
||
@nextLong
|
||
CMP.L (A5),D4 ;is the next long the same as the background?
|
||
BNE.S @oneAtATime
|
||
@midSwitch
|
||
MOVE.L A0,(A5)+ ;save a long of the hilite color
|
||
@midLoop
|
||
DBRA D2,@nextLong ;do the next one
|
||
@fullMask
|
||
MOVEQ #-1,D1 ;flush mask for end10
|
||
@lastMask
|
||
AND.L lastMask(A6),D1 ;MASK:=MASK AND LASTMASK
|
||
BSR.S hiliteMask
|
||
BRA NxtSrc
|
||
|
||
@oneAtATime
|
||
CMP.L (A5),A0
|
||
BEQ.S @switch
|
||
; first see if it is the same as the "other" color
|
||
MOVE.L A2,D6 ;initial long position count
|
||
@nextPixel
|
||
BFEXTU (A5){D6:D7},D3 ;get a pixel of the destination
|
||
CMP.l D3,D0 ;same as the background color?
|
||
BNE.S @tryNew
|
||
BFINS D5,(A5){D6:D7}
|
||
BRA.S @skipToNext
|
||
@tryNew
|
||
CMP.l D5,D3 ;same as new color?
|
||
BNE.S @skipToNext
|
||
BFINS D0,(A5){D6:D7}
|
||
@skipToNext
|
||
SUB D7,D6 ;advance to next pixel
|
||
BPL.S @nextPixel
|
||
ADDQ #4,A5
|
||
BRA.S @midLoop
|
||
@switch
|
||
BFEXTU D4{0:D7},D5 ;set up a pixel sized highlight color
|
||
EXG A0,D4 ;switch the highlight color w/ the background color
|
||
BFEXTU D4{0:D7},D0 ;and a pixel sized background color
|
||
BRA.S @midSwitch
|
||
|
||
hiliteMask
|
||
MOVE.L D4,D3 ;get a long of background
|
||
AND.L D1,D3 ;mask background to right mask
|
||
MOVE.L (A5),D6 ;get a long of dst
|
||
AND.L D1,D6 ;mask it as well
|
||
CMP.L D3,D6 ;the same?
|
||
BNE.S @oneAtATime ;no, must do left part 1 pixel at a time
|
||
MOVE.L A0,D3 ;get the hilite color
|
||
AND.L D1,D3 ;mask it
|
||
NOT.L D1 ;flip the mask
|
||
AND.L (A5),D1 ;get the data already there
|
||
OR.L D3,D1 ;combine the two together
|
||
MOVE.L D1,(A5)+ ;deposit the result and move on
|
||
RTS
|
||
|
||
@oneAtATime
|
||
; first see if it is the same as the "other" color
|
||
MOVE.L A2,D6 ;start at last pixel position
|
||
@nextPixel
|
||
BFEXTU D1{D6:D7},D3 ;a pixel of the mask
|
||
BEQ.S @skipBlank ;if nothing, skip it
|
||
BFEXTU (A5){D6:D7},D3 ;get a pixel of the destination
|
||
CMP.l D3,D0 ;same as the background color?
|
||
BNE.S @tryNew
|
||
BFINS D5,(A5){D6:D7}
|
||
BRA.S @skipToNext
|
||
@tryNew
|
||
CMP.l D5,D3 ;same as new color?
|
||
BNE.S @skipToNext
|
||
BFINS D0,(A5){D6:D7}
|
||
@skipToNext
|
||
@skipBlank
|
||
SUB D7,D6 ;advance to next pixel
|
||
BPL.S @nextPixel
|
||
ADDQ #4,A5
|
||
RTS
|
||
|
||
|
||
if blit32 then ;<14>
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; chosen if the dst is 32 bits/pixel
|
||
;
|
||
|
||
bHilite32
|
||
MOVEQ #-1,D0
|
||
LSR.L #8,D0 ;get low3byte mask in d0
|
||
MOVE D2,D3 ;save a copy in d3
|
||
|
||
@nxtScan
|
||
MOVE D3,D2 ;reset longCnt
|
||
|
||
@nextLong
|
||
MOVE.L D0,D1 ;copy pixel mask
|
||
AND.L (A5),D1 ;remove alpha byte
|
||
CMP.L D1,D4 ;is the next long the same as the background?
|
||
BNE.S @chkOther
|
||
@midSwitch
|
||
MOVE.L A0,(A5)+ ;save a long of the hilite color
|
||
DBRA D2,@nextLong ;do the next one
|
||
BRA.S @NxtDst
|
||
|
||
@chkOther
|
||
CMP.L D1,A0
|
||
BNE.S @next
|
||
EXG A0,D4 ;switch the highlight color w/ the background color
|
||
BRA.S @midSwitch
|
||
@next
|
||
ADDQ #4,A5
|
||
DBRA D2,@nextLong ;do the next one
|
||
|
||
@NxtDst
|
||
ADD A3,A5 ;BUMP DSTADDR TO NEXT ROW
|
||
SUBQ #1,HEIGHT(A6) ;DECREMENT ROWCOUNT
|
||
BNE.S @nxtScan ;LOOP FOR ALL SRCROWS
|
||
BRA.S GOHOME ;THEN QUIT
|
||
|
||
endif ;<14>
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; chosen if the source was not a small pattern equal to black, so does not look for long
|
||
; optimizations
|
||
;
|
||
;Êfix from QDciPatchROM.a <sm 6/9/92>stb
|
||
; handle vertically aligned hilites (like that ever happens) and
|
||
; preserve a non-white background color through the entire blit (more common). <14SEP90 SMC>
|
||
|
||
bSloHilite
|
||
;
|
||
; if we are going backwards, align destination and mask <14AUG90 KON>
|
||
;
|
||
lea @RealbSloHilite1,a1 ; <13SEP90 SMC>
|
||
BFEXTU D4{0:D7},D4 ;set up pixel of the background color <13SEP90 SMC>
|
||
tst (sp) ;is bump amount negative? <14AUG90 KON>
|
||
bpl.s @RealbSloHilite1 ; <14AUG90 KON>
|
||
sub.l (SP),D6 ;bump src right OR left by 1 pixel first time only <14AUG90 KON>
|
||
lea @RealbSloHilite,a1 ;remember correct entry point for remaining scans <14AUG90 KON>
|
||
@RealbSloHilite
|
||
sub.l (SP),D0 ;align destination and mask each scan line <14AUG90 KON>
|
||
@RealbSloHilite1
|
||
|
||
cmp.w #32,d7 ;1 pixel per long? <08Jan89 BAL>
|
||
beq.s @firstMask ;yes, d2 is unfortunately zero <08Jan89 BAL>
|
||
|
||
TST D2 ;is there only 1 long?
|
||
BGT.S @firstMask ;if not, use the first mask in D1
|
||
@forceLast
|
||
OR.B #3,doneMid(A6) ;note that the first part and mid part are done
|
||
@lastMask
|
||
MOVE pixInLong(A6),D2;loop once for each pixel in the long
|
||
AND.L lastMask(A6),D1 ;MASK:=MASK AND LASTMASK
|
||
@firstMask
|
||
@loopTop
|
||
AND patHMask(A6),D6 ;constrict to the source long if in a pattern mode
|
||
BFEXTU D1{D0:D7},D3 ;a pixel of the mask
|
||
BEQ.S @skip
|
||
BFEXTU (A4){D6:D7},D3 ;get a pixel of the source (zeros top word)
|
||
CMP.l D3,D4 ;same as the background color? <08Jan89 BAL>
|
||
BEQ.S @skip
|
||
BFEXTU (A5){D0:D7},D3 ;get a pixel of the destination
|
||
CMP.l D3,D4 ;same as the background color? <08Jan89 BAL>
|
||
BNE.S @tryNew
|
||
BFINS D5,(A5){D0:D7}
|
||
BRA.S @skip
|
||
@tryNew
|
||
CMP.l D5,D3 ;same as new color?
|
||
BNE.S @skip
|
||
BFINS D4,(A5){D0:D7}
|
||
@skip
|
||
ADD.L (SP),D6 ;BUMP SRCPTR LEFT OR RIGHT by 1 pixel
|
||
ADD.L (SP),D0 ;bump destination and mask
|
||
DBRA D2,@loopTop ;do it for all of the pixels on the line (or within the mask)
|
||
MOVEQ #-1,D1 ;flush mask
|
||
BSET #0,doneMid(A6) ;has the middle part already been done?
|
||
BNE.S @midDone ;if so, skip it
|
||
MOVE midCount(A6),D2 ;reset to mid count
|
||
BMI.S @forceLast ;if none, just do the last part
|
||
BRA.S @loopTop
|
||
@midDone
|
||
BSET #1,doneMid(A6) ;already done the last mask part too?
|
||
BEQ.S @lastMask ;if not, do it
|
||
BRA NxtNewSrc ;LOOP BACK FOR MORE
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; MODES 36, 44, 60: SRC less bg --> DST
|
||
|
||
; (SP) hbump for a pixel
|
||
; A2 32 correctly signed
|
||
; D0 first destination/mask pixel position
|
||
; D2 number of pixels in a long, or 0 if only 1 long
|
||
; D4 background long
|
||
; D5 one background pixel
|
||
; D6 first source pixel position
|
||
; D7 pixel size
|
||
; doneMid(A6) cleared (byte)
|
||
; lastMask(A6) equal to D5 standard
|
||
; midCount(A6) equal to # of pixels on line less mask longs
|
||
; pixInLong(A6) equal to # of pixels in a long
|
||
|
||
bTransparent
|
||
;
|
||
; if we are going backwards, align destination and mask <14AUG90 KON>
|
||
;
|
||
; rolled in SMCÕs changes from QDciPatchROM.a <sm 6/9/92>stb
|
||
|
||
lea @RealbTransparent1,a1 ; <26SEP90 SMC> <10>
|
||
tst.l (sp) ;is bump amount negative? <14AUG90 KON>
|
||
bmi.s @1 ; <14AUG90 KON>
|
||
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode? <08Oct90 SMC> <72>
|
||
BEQ bTransparent8 ; <08Oct90 SMC> <72>
|
||
BRA.S @RealbTransparent1 ; <08Oct90 SMC> <72>
|
||
@1: sub.l (SP),D6 ;bump src right OR left by 1 pixel first time only <14AUG90 KON>
|
||
lea @RealbTransparent,a1 ;remember correct entry point for remaining scans <14AUG90 KON>
|
||
@RealbTransparent
|
||
sub.l (SP),D0 ;align destination and mask each scan line <14AUG90 KON>
|
||
@RealbTransparent1
|
||
|
||
cmp.w #32,d7 ;1 pixel per long? <08Jan89 BAL>
|
||
beq.s @firstMask ;yes, d2 is unfortunately zero <08Jan89 BAL>
|
||
|
||
TST D2 ;is there only 1 long?
|
||
BGT.S @firstMask ;if not, use the first mask in D1
|
||
@forceLast
|
||
OR.B #3,doneMid(A6) ;note that the first part and mid part are done
|
||
@lastMask
|
||
MOVE pixInLong(A6),D2 ;loop once for each pixel in the long
|
||
AND.L lastMask(A6),D1 ;MASK:=MASK AND LASTMASK
|
||
@firstMask
|
||
@loopTop
|
||
AND patHMask(A6),D6 ;constrict to the source long if in a pattern mode
|
||
BFEXTU D1{D0:D7},D3 ;a pixel of the mask
|
||
BEQ.S @skip
|
||
|
||
BFEXTU (A4){D6:D7},D3 ;get a pixel of the source (zeros top word)
|
||
CMP.L D3,A3 ;same as a pixel of the background?
|
||
BEQ.S @skip
|
||
BFINS D3,(A5){D0:D7} ;move to the destination
|
||
@skip
|
||
ADD.L (SP),D6 ;BUMP SRCPTR LEFT OR RIGHT by 1 pixel
|
||
ADD.L (SP),D0 ;bump destination and mask
|
||
DBRA D2,@loopTop ;do it for all of the pixels on the line (or within the mask)
|
||
@loopEnd
|
||
ADDQ #1,D2 ;check to see if we ended on a natural long
|
||
BEQ.S @noPixelAlign ;if so, expect a -1 here
|
||
SUB.L (SP),D6 ;unbump source
|
||
SUB.L (SP),D0 ;unbump destination
|
||
BRA.S @loopEnd
|
||
@noPixelAlign
|
||
MOVEQ #-1,D1 ;flush mask
|
||
BSET #0,doneMid(A6) ;has the middle part already been done?
|
||
BNE.S @midDone ;if so, skip it
|
||
MOVE midCount(A6),D2 ;reset to mid count
|
||
BMI.S @forceLast ;if none, just do the last part
|
||
BRA.S @loopTop
|
||
@midDone
|
||
BSET #1,doneMid(A6) ;already done the last mask part too?
|
||
BEQ.S @lastMask ;if not, do it
|
||
BRA NxtNewSrc ;LOOP BACK FOR MORE
|
||
|
||
|
||
if blit32 then ;<14>
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
; a0 = tmpsrc d0 = high byte clearing mask
|
||
; a1 = modeCase d1 =
|
||
; a2 = tmpdst d2 = longCnt
|
||
; a3 = hBump d3 = transColor (long)
|
||
; a4 = srcPtr/patPtr d4 = patHMask
|
||
; a5 = dstPtr d5 =
|
||
; a6 = locals d6 = pat offset
|
||
; a7^= patHBump d7 = src pixel
|
||
;-------------------------------------------------------
|
||
|
||
bTransparent32
|
||
MOVE.L BCOLOR(A6),D3 ;GET BKCOLOR (transColor if arithmetic mode)
|
||
move.l a4,a0 ;get working copy of srcptr
|
||
add.w d6,a0 ;index into pattern
|
||
move.l a5,a2 ;get working copy of dstptr
|
||
move.l maskBC,d0 ;get high byte clearing mask
|
||
|
||
@loopTop
|
||
move.l (a0),d7 ;get a pixel of the source xrgb
|
||
add.w a3,a0 ;bump bidirectionally
|
||
and.l d0,d7 ;mask off high byte
|
||
cmp.l d3,d7 ;same as transparent color?
|
||
beq.s @skip
|
||
move.l d7,(a2) ;move to the destination
|
||
@skip add.w a3,a2 ;bump bidirectionally
|
||
addq.l #4,d6 ;bump pattern offset
|
||
and.l d4,d6 ;constrict to the source long if in a pattern mode
|
||
bne.s @patOK ;don't need to reload pat ptr
|
||
move.l a4,a0 ;reload pat ptr
|
||
@patOK DBRA D2,@loopTop ;do it for all pixels on the line
|
||
BRA NxtNewSrc32 ;LOOP BACK FOR MORE
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------------
|
||
; a0 = tmpsrc d0 = high bit clearing mask
|
||
; a1 = modeCase d1 =
|
||
; a2 = tmpdst d2 = longCnt
|
||
; a3 = hBump d3 =
|
||
; a4 = srcPtr/patPtr d4 = patHMask
|
||
; a5 = dstPtr d5 = dest pixel
|
||
; a6 = locals d6 = pat offset
|
||
; a7^= patHBump d7 = src pixel
|
||
;-------------------------------------------------------
|
||
bTransparent16
|
||
MOVE.L BCOLOR(A6),D3 ;GET BKCOLOR (transColor if arithmetic mode)
|
||
move.l a4,a0 ;get working copy of srcptr
|
||
add.w d6,a0 ;index into pattern
|
||
move.l a5,a2 ;get working copy of dstptr
|
||
|
||
moveq #-1,d0 ;get high bit clearing mask
|
||
lsr.w #1,d0
|
||
|
||
@loopTop
|
||
move.w (a0),d7 ;get a pixel of the source xrgb
|
||
add.w a3,a0 ;bump bidirectionally
|
||
and.w d0,d7 ;mask off high bit
|
||
cmp.w d3,d7 ;same as transparent color?
|
||
beq.s @skip
|
||
move.w d7,(a2) ;move to the destination
|
||
@skip add.w a3,a2 ;bump bidirectionally
|
||
addq.l #2,d6 ;bump pattern offset
|
||
and.l d4,d6 ;constrict to the source long if in a pattern mode
|
||
bne.s @patOK ;don't need to reload pat ptr
|
||
move.l a4,a0 ;reload pat ptr
|
||
@patOK DBRA D2,@loopTop ;do it for all pixels on the line
|
||
BRA NxtNewSrc32 ;LOOP BACK FOR MORE
|
||
|
||
endif ;<14>
|
||
|
||
|
||
IF 0 THEN ;This is great code but it is only good if the dst left and right
|
||
;are both on byte boundaries. bFast0 has can now handle any left
|
||
;and right mask with comparable performance.
|
||
|
||
;******************************************************************************************
|
||
;
|
||
; Here's where Andy handles the case of MisAligned copyBits copy mode on a byte boundary.
|
||
;
|
||
; it's an 8 bit boundary, so handle it. Calculate the address adjustments in D7 from the
|
||
; bit offset in D6 and mask in D1. First decode the mask, casing out on the direction
|
||
; in A0
|
||
|
||
bFastMisaligned
|
||
|
||
MOVE.L D1,D3 ;get mask
|
||
MOVEQ #0,D1 ;assume minimum
|
||
|
||
MOVE.W D6,D0
|
||
ASR #3,D0 ;turn into byte number
|
||
|
||
MOVE.W A0,D5 ;remember direction
|
||
BPL.S @0 ;if positive, we're cool
|
||
|
||
NOT.L D3 ;invert the mask for other direction
|
||
@0
|
||
TST.L D3
|
||
BMI.S Got1stOffset ;if on, we're done
|
||
|
||
ADDQ #1,D1
|
||
LSL.L #8,D3
|
||
BMI.S Got1stOffset ;if on, we're done
|
||
|
||
ADDQ #1,D1
|
||
LSL.L #8,D3
|
||
BMI.S Got1stOffset ;if on, we're done
|
||
|
||
ADDQ #1,D1
|
||
|
||
; we got the mask offset in D1 and the byte offset in D0, so compute the bump factors
|
||
|
||
Got1stOffset
|
||
ADD.W D1,D0 ;compute byte offset
|
||
|
||
MOVE.W D0,D7 ;remember offset
|
||
SWAP D7
|
||
MOVE.W D1,D7 ;use mask offset for dest
|
||
|
||
MOVE.W D5,D0 ;remember bump direction
|
||
move.w destPixCnt(a6),d5 ;get pixel count
|
||
ext.l d5
|
||
move.w dstShift(a6),d1 ;get shift count
|
||
lsl.l d1,d5 ;convert pixels to bits
|
||
lsr.l #3,d5 ;convert bits to bytes
|
||
|
||
TST.W D0 ;test direction
|
||
BMI BlockMoveRight ;if right, go there and do it
|
||
BRA.S SL1Loop ;go to top of loop
|
||
|
||
|
||
;----------------------------------------------------------------------------
|
||
; done with this scan line, so bump to the next scan line and loop until done
|
||
|
||
SL1Done RTS ;go Home
|
||
SL1Next
|
||
SUB.W D7,A4 ;undo source offset
|
||
SWAP D7
|
||
SUB.W D7,A5 ;undo dest offset
|
||
|
||
MOVEQ #0,D0
|
||
MOVE.W LONGCNT(A6),D0 ;get long count
|
||
ADDQ #1,D0
|
||
ASL #2,D0 ;turn into byte count
|
||
|
||
ADD.L D0,A4
|
||
ADD.L D0,A5
|
||
|
||
ADD.W SRCBUMP(A6),A4 ;bump source ; <PB448 DBG>
|
||
ADD.W A3,A5 ;bump destination
|
||
|
||
SUBQ.W #1,HEIGHT(A6) ;decrement scan line count
|
||
BEQ.S SL1Done ;if no more, go home
|
||
|
||
|
||
; here's the top of the outer loop where we adjust the addresses by the offsets in D7
|
||
|
||
SL1Loop
|
||
ADD.W D7,A5
|
||
SWAP D7
|
||
ADD.W D7,A4
|
||
|
||
; get the byte count and blast the scan line
|
||
|
||
SL1Blast
|
||
MOVE.L D5,D0
|
||
MOVE.L A4,A0
|
||
MOVE.L A5,A1
|
||
|
||
|
||
; Special BlockMove subroutine optimized for this situation. The source is in A0
|
||
; and dest in A1, with byte count in D0. Note things are already pre-bumped for
|
||
; the MoveRight case. Note that we assume that no move is bigger than 32KBytes,
|
||
; to save a little speed (no scanline is that big!)
|
||
|
||
BlockMoveLeft
|
||
|
||
; for small moves, all this casing out is a losing battle, so dive in quickly
|
||
|
||
CMP.W #32,D0 ;is it really small?
|
||
BLT.S FinishUpLeft ;if so, finish up last few
|
||
|
||
; make sure the destination is always longword aligned by moving up to 3 bytes
|
||
|
||
MOVE.W A1,D1 ;get destination
|
||
AND.W #3,D1 ;low two bits only
|
||
BEQ.S MediumLeft ;if 0, skip
|
||
|
||
JMP LeftAlign(D1.W*4)
|
||
LeftAlign
|
||
NOP
|
||
NOP
|
||
|
||
MOVE.B (A0)+,(A1)+
|
||
SUBQ #1,D0
|
||
|
||
MOVE.B (A0)+,(A1)+
|
||
SUBQ #1,D0
|
||
|
||
MOVE.B (A0)+,(A1)+
|
||
SUBQ #1,D0
|
||
|
||
; we've got a medium-sized block to move (at least 32), so handle it with an unwound MOVE.L loop
|
||
|
||
MediumLeft
|
||
MOVE.W D0,D1
|
||
LSR.W #5,D1 ;divide by 32
|
||
BRA.S @2
|
||
|
||
@1
|
||
MOVE.L (A0)+,(A1)+ ;move 32 bytes
|
||
MOVE.L (A0)+,(A1)+
|
||
MOVE.L (A0)+,(A1)+
|
||
MOVE.L (A0)+,(A1)+
|
||
MOVE.L (A0)+,(A1)+
|
||
MOVE.L (A0)+,(A1)+
|
||
MOVE.L (A0)+,(A1)+
|
||
MOVE.L (A0)+,(A1)+
|
||
@2
|
||
DBRA D1,@1 ;move it
|
||
|
||
; now we have 31 or less bytes left to move
|
||
|
||
AND #31,D0
|
||
FinishUpLeft
|
||
MOVE.W LOffsetTable(D0.W*2),D0
|
||
JMP LastLeft(D0)
|
||
LastLeft
|
||
|
||
Left1F
|
||
MOVE.L (A0)+,(A1)+
|
||
Left1B
|
||
MOVE.L (A0)+,(A1)+
|
||
Left17
|
||
MOVE.L (A0)+,(A1)+
|
||
Left13
|
||
MOVE.L (A0)+,(A1)+
|
||
LeftF
|
||
MOVE.L (A0)+,(A1)+ ;move next 32 (64 total)
|
||
LeftB
|
||
MOVE.L (A0)+,(A1)+
|
||
Left7
|
||
MOVE.L (A0)+,(A1)+
|
||
Left3
|
||
MOVE.W (A0)+,(A1)+
|
||
Left1
|
||
MOVE.B (A0)+,(A1)+
|
||
Left0
|
||
|
||
DoneBlockMove
|
||
BRA.s SL1Next
|
||
Left1E
|
||
MOVE.L (A0)+,(A1)+
|
||
Left1A
|
||
MOVE.L (A0)+,(A1)+
|
||
Left16
|
||
MOVE.L (A0)+,(A1)+
|
||
Left12
|
||
MOVE.L (A0)+,(A1)+
|
||
LeftE
|
||
MOVE.L (A0)+,(A1)+
|
||
LeftA
|
||
MOVE.L (A0)+,(A1)+
|
||
Left6
|
||
MOVE.L (A0)+,(A1)+
|
||
Left2
|
||
MOVE.W (A0)+,(A1)+
|
||
|
||
BRA.s SL1Next
|
||
|
||
Left1C
|
||
MOVE.L (A0)+,(A1)+
|
||
Left18
|
||
MOVE.L (A0)+,(A1)+
|
||
Left14
|
||
MOVE.L (A0)+,(A1)+
|
||
Left10
|
||
MOVE.L (A0)+,(A1)+
|
||
LeftC
|
||
MOVE.L (A0)+,(A1)+
|
||
Left8
|
||
MOVE.L (A0)+,(A1)+
|
||
Left4
|
||
MOVE.L (A0)+,(A1)+
|
||
BRA.s SL1Next
|
||
Left1D
|
||
MOVE.L (A0)+,(A1)+
|
||
Left19
|
||
MOVE.L (A0)+,(A1)+
|
||
Left15
|
||
MOVE.L (A0)+,(A1)+
|
||
Left11
|
||
MOVE.L (A0)+,(A1)+
|
||
LeftD
|
||
MOVE.L (A0)+,(A1)+
|
||
Left9
|
||
MOVE.L (A0)+,(A1)+
|
||
Left5
|
||
MOVE.L (A0)+,(A1)+
|
||
MOVE.B (A0)+,(A1)+
|
||
BRA.s SL1Next
|
||
|
||
LOffsetTable
|
||
DC.W Left0-LastLeft
|
||
DC.W Left1-LastLeft
|
||
DC.W Left2-LastLeft
|
||
DC.W Left3-LastLeft
|
||
DC.W Left4-LastLeft
|
||
DC.W Left5-LastLeft
|
||
DC.W Left6-LastLeft
|
||
DC.W Left7-LastLeft
|
||
DC.W Left8-LastLeft
|
||
DC.W Left9-LastLeft
|
||
DC.W LeftA-LastLeft
|
||
DC.W LeftB-LastLeft
|
||
DC.W LeftC-LastLeft
|
||
DC.W LeftD-LastLeft
|
||
DC.W LeftE-LastLeft
|
||
DC.W LeftF-LastLeft
|
||
DC.W Left10-LastLeft
|
||
DC.W Left11-LastLeft
|
||
DC.W Left12-LastLeft
|
||
DC.W Left13-LastLeft
|
||
DC.W Left14-LastLeft
|
||
DC.W Left15-LastLeft
|
||
DC.W Left16-LastLeft
|
||
DC.W Left17-LastLeft
|
||
DC.W Left18-LastLeft
|
||
DC.W Left19-LastLeft
|
||
DC.W Left1A-LastLeft
|
||
DC.W Left1B-LastLeft
|
||
DC.W Left1C-LastLeft
|
||
DC.W Left1D-LastLeft
|
||
DC.W Left1E-LastLeft
|
||
DC.W Left1F-LastLeft
|
||
|
||
;----------------------------------------------------------------------------
|
||
; done with this scan line, so bump to the next scan line and loop until done
|
||
|
||
SR1Done RTS
|
||
SR1Next
|
||
SUB.W D7,A4 ;undo source offset
|
||
SWAP D7
|
||
SUB.W D7,A5 ;undo dest offset
|
||
|
||
MOVEQ #0,D0
|
||
MOVE.W LONGCNT(A6),D0 ;get long count
|
||
ADDQ #1,D0
|
||
ASL #2,D0 ;turn into byte count
|
||
NEG.L D0 ;negate it
|
||
|
||
ADD.L D0,A4
|
||
ADD.L D0,A5
|
||
|
||
ADD.W SRCBUMP(A6),A4 ;bump source ; <PB448 DBG>
|
||
ADD.W A3,A5 ;bump destination
|
||
|
||
SUBQ.W #1,HEIGHT(A6) ;decrement scan line count
|
||
BEQ.S SR1Done ;if no more, then go home
|
||
|
||
; here's the top of the outer loop where we adjust the addresses by the offsets in D7
|
||
|
||
BlockMoveRight
|
||
|
||
ADD.W D7,A5
|
||
SWAP D7
|
||
ADD.W D7,A4
|
||
|
||
; get the byte count and blast the scan line
|
||
|
||
SR1Blast
|
||
MOVE.L D5,D0 ;byte count stored in d5
|
||
MOVE.L A4,A0
|
||
MOVE.L A5,A1
|
||
|
||
|
||
; Handle the case of moving to the right
|
||
|
||
MoveRight
|
||
CMP.W #32,D0 ;is it really small?
|
||
BLT.S FinishUpRight ;if so, finish up last few
|
||
|
||
; make sure the destination is always longword aligned by moving up to 3 bytes
|
||
|
||
MOVE.W A1,D1 ;get destination
|
||
AND.W #3,D1 ;low two bits only
|
||
|
||
EOR.W #3,D1 ;flip sense
|
||
JMP RightAlign(D1.W*4)
|
||
RightAlign
|
||
MOVE.B -(A0),-(A1)
|
||
SUBQ #1,D0
|
||
|
||
MOVE.B -(A0),-(A1)
|
||
SUBQ #1,D0
|
||
|
||
MOVE.B -(A0),-(A1)
|
||
SUBQ #1,D0
|
||
|
||
; we've got a medium-sized block to move (at least 32), so handle it with an unwound MOVE.L loop
|
||
|
||
MediumRight
|
||
MOVE.W D0,D1
|
||
LSR.W #5,D1 ;divide by 32
|
||
BRA.S @2
|
||
@1
|
||
MOVE.L -(A0),-(A1) ;move 32 bytes
|
||
MOVE.L -(A0),-(A1)
|
||
MOVE.L -(A0),-(A1)
|
||
MOVE.L -(A0),-(A1)
|
||
MOVE.L -(A0),-(A1)
|
||
MOVE.L -(A0),-(A1)
|
||
MOVE.L -(A0),-(A1)
|
||
MOVE.L -(A0),-(A1)
|
||
@2
|
||
DBRA D1,@1 ;move the bulk of it
|
||
|
||
; now we have 31 or less bytes left to move
|
||
|
||
AND #31,D0
|
||
FinishUpRight
|
||
MOVE.W ROffsetTable(D0.W*2),D0
|
||
;+++ JMP LastRight(D0)
|
||
JMP (QGLastRight,PC,D0) ; this is a hack - this JMP must be immediately before the table
|
||
QGLastRight
|
||
|
||
Right1F
|
||
MOVE.L -(A0),-(A1)
|
||
Right1B
|
||
MOVE.L -(A0),-(A1)
|
||
Right17
|
||
MOVE.L -(A0),-(A1)
|
||
Right13
|
||
MOVE.L -(A0),-(A1)
|
||
RightF
|
||
MOVE.L -(A0),-(A1) ;move next 32 (64 total)
|
||
RightB
|
||
MOVE.L -(A0),-(A1)
|
||
Right7
|
||
MOVE.L -(A0),-(A1)
|
||
Right3
|
||
MOVE.W -(A0),-(A1)
|
||
Right1
|
||
MOVE.B -(A0),-(A1)
|
||
Right0
|
||
BRA.s SR1Next
|
||
|
||
Right1E
|
||
MOVE.L -(A0),-(A1)
|
||
Right1A
|
||
MOVE.L -(A0),-(A1)
|
||
Right16
|
||
MOVE.L -(A0),-(A1)
|
||
Right12
|
||
MOVE.L -(A0),-(A1)
|
||
RightE
|
||
MOVE.L -(A0),-(A1)
|
||
RightA
|
||
MOVE.L -(A0),-(A1)
|
||
Right6
|
||
MOVE.L -(A0),-(A1)
|
||
Right2
|
||
MOVE.W -(A0),-(A1)
|
||
|
||
BRA.s SR1Next
|
||
|
||
Right1C
|
||
MOVE.L -(A0),-(A1)
|
||
Right18
|
||
MOVE.L -(A0),-(A1)
|
||
Right14
|
||
MOVE.L -(A0),-(A1)
|
||
Right10
|
||
MOVE.L -(A0),-(A1)
|
||
RightC
|
||
MOVE.L -(A0),-(A1)
|
||
Right8
|
||
MOVE.L -(A0),-(A1)
|
||
Right4
|
||
MOVE.L -(A0),-(A1)
|
||
|
||
BRA.s SR1Next
|
||
|
||
Right1D
|
||
MOVE.L -(A0),-(A1)
|
||
Right19
|
||
MOVE.L -(A0),-(A1)
|
||
Right15
|
||
MOVE.L -(A0),-(A1)
|
||
Right11
|
||
MOVE.L -(A0),-(A1)
|
||
RightD
|
||
MOVE.L -(A0),-(A1)
|
||
Right9
|
||
MOVE.L -(A0),-(A1)
|
||
Right5
|
||
MOVE.L -(A0),-(A1)
|
||
MOVE.B -(A0),-(A1)
|
||
|
||
BRA.s SR1Next
|
||
|
||
ROffsetTable
|
||
DC.W Right0-QGLastRight
|
||
DC.W Right1-QGLastRight
|
||
DC.W Right2-QGLastRight
|
||
DC.W Right3-QGLastRight
|
||
DC.W Right4-QGLastRight
|
||
DC.W Right5-QGLastRight
|
||
DC.W Right6-QGLastRight
|
||
DC.W Right7-QGLastRight
|
||
DC.W Right8-QGLastRight
|
||
DC.W Right9-QGLastRight
|
||
DC.W RightA-QGLastRight
|
||
DC.W RightB-QGLastRight
|
||
DC.W RightC-QGLastRight
|
||
DC.W RightD-QGLastRight
|
||
DC.W RightE-QGLastRight
|
||
DC.W RightF-QGLastRight
|
||
DC.W Right10-QGLastRight
|
||
DC.W Right11-QGLastRight
|
||
DC.W Right12-QGLastRight
|
||
DC.W Right13-QGLastRight
|
||
DC.W Right14-QGLastRight
|
||
DC.W Right15-QGLastRight
|
||
DC.W Right16-QGLastRight
|
||
DC.W Right17-QGLastRight
|
||
DC.W Right18-QGLastRight
|
||
DC.W Right19-QGLastRight
|
||
DC.W Right1A-QGLastRight
|
||
DC.W Right1B-QGLastRight
|
||
DC.W Right1C-QGLastRight
|
||
DC.W Right1D-QGLastRight
|
||
DC.W Right1E-QGLastRight
|
||
DC.W Right1F-QGLastRight
|
||
|
||
|
||
ENDIF
|
||
|
||
DC.B '(c) Apple Computer Inc., 1983-1989'
|
||
|
||
|
||
ENDPROC
|
||
|
||
|
||
|
||
|
||
|