mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-26 01:49:19 +00:00
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
|
||
|
||
|
||
|
||
|
||
|