mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2025-01-03 09:31:04 +00:00
9c249dafab
The ROM now round-trips with QuickDraw mostly built from source. (~30% of the ROM is now built from source.)
4742 lines
144 KiB
Plaintext
4742 lines
144 KiB
Plaintext
;
|
|
; File: QDUtil.a
|
|
;
|
|
; Copyright: © 1981-1990, 1992-1993 by Apple Computer, Inc., all rights reserved.
|
|
;
|
|
; This file is used in these builds: Mac32 BigBang
|
|
;
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <SM7> 9/12/93 joe seperately conditionalize out ElsieTranslate24To32.
|
|
; <SM6> 9/12/93 SAM Changed all instances of _Translate24to32 to _rTranslate24to32
|
|
; so they can conditionalized out of the build.
|
|
; <SM5> 1/26/93 kc Fix bug in GetAlphaMask. (renamed mask to alphaMask to avoid
|
|
; name collision)
|
|
; <SM4> 1/25/93 kc Roll in Shannon Holland's alpha channel stuff.
|
|
; <SM3> 7/16/92 CSS Update from Reality:
|
|
; <R21> 6/8/92 SAH #1031825: Changed ColorMap to ignore the multColor flag.
|
|
; <SM2> 6/11/92 stb <sm 6/9/92>stb Synch with QDciPatch.a; added comments to
|
|
; ColorMap, AlphaDispatch, GetPixel, GetCPixel, FillClipScanLine,
|
|
; FillClipOrLine, FAST11, FillClipXLine.
|
|
; <20> 11/26/90 SMC Fixed slab pattern hiliting. With BAL.
|
|
; <19> 11/6/90 SMC Fixed NOPfgColorTable range problem in Mac32 build. With KON.
|
|
; <18> 11/5/90 SMC Fixed FastTab range problem in Mac32 build. With KON.
|
|
; <17> 10/31/90 SMC Fixed alpha channel bugs with BAL.
|
|
; <16> 10/17/90 SMC Fixed pattern alignment problem in FillClipXLine. With KON.
|
|
; <15> 10/17/90 SMC Changed speedup method used in <13> to work in cases where
|
|
; someone has put a semi-legal value in fgcolor or bkcolor, such
|
|
; as -1 instead of 1. With BAL.
|
|
; <14> 10/17/90 KON The default colors in ColorMap should be inverted if Multcolor
|
|
; is set and destination is direct. With SMC.
|
|
; <13> 10/1/90 KON Speedup to 1-bit fg/bg pixel replication. With BAL.
|
|
; <12> 9/27/90 SMC Fixed pattern hilite setup in SlabMode for 16 and 32-bit.
|
|
; Slabbed pattern hilite still has problems but now it has one
|
|
; less.
|
|
; <11> 9/18/90 SMC Fixed GetCPixel to return valid color at points along top and
|
|
; left edges of gdevice.
|
|
; <10> 9/18/90 BG Removed <6>, <8>. 040s are behaving more reliably now.
|
|
; <9> 8/16/90 dba fix up the implementation of VisRgnChanged
|
|
; <8> 7/20/90 BG Added some more EclipseNOPs for flakey 040s.
|
|
; <7> 7/20/90 gbm Change comment to reflect new reality
|
|
; <6> 6/27/90 BG Added NOPs for flakey 040s.
|
|
; <5> 6/21/90 KON Fix getPixel and getCPixel so they work with pixmap with
|
|
; pmVersion=4 (needs 32-bit addressing).
|
|
; <4> 6/4/90 KON Hack to make 1-bit old port copy mode work.
|
|
; <3> 3/26/90 KON Add VisRgnChanged call (trap $A0A5).
|
|
; <2> 2/28/90 JJ Added the routine ElsieTranslate24To32, a new address
|
|
; translation routine appropriate for the VISA decoder.
|
|
; <1.8> 11/18/89 BAL Added in QuickerDraw loops for copy mode and 8-bit arithmetic
|
|
; DrawSlab
|
|
; <¥1.7> 7/14/89 BAL For Aurora: Final CQD
|
|
; <1.6> 6/30/89 BAL Init FG = black and BK = white flags in ColorMap¶
|
|
; <1.5> 6/10/89 CEL Moved Private.a QuickDraw Equates into proper QuickDraw private
|
|
; file (colorequ.a), got rid of QuickDraw nFiles dependencies and
|
|
; fixed up necessary filesÉ
|
|
; <¥1.4> 5/29/89 BAL Blasting in 32-Bit QuickDraw version 1.0 Final
|
|
; 1/22/89 BAL Altered DrawSlab loops to use patVPos as a long.
|
|
; 9/19/88 BAL Altered ColorMap, DrawSlab to use common stack frame file
|
|
; 'Drawing Vars.a'
|
|
; 9/15/88 BAL Compute slab bit-width as a long
|
|
; 5/6/88 BAL Rolled in fix to set bcolor to white during transparent blit
|
|
; 5/6/88 BAL Altered ColorMap to clean invColor and colorTable ptrs
|
|
; 5/4/88 BAL Modified XorSlab to maintain bit width as a long
|
|
; 4/14/88 BAL Modified GetCPixel to operate in 32 bit addressing mode
|
|
; 1/21/87 EHB Modified colorMap to check grafPort type before using colors
|
|
; 1/3/87 CRC color correction in colorMap; bug fixes in arithmetic modes
|
|
; 12/30/86 EHB Modified colorMap to check grafPort type before using colors
|
|
; 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 In PatExpand, only colorize pattern if copy mode Added color to
|
|
; pattern OR and pattern BIC transfer modes in DrawSlab
|
|
; 7/7/86 EHB In ColorMap, use portBits+rowBytes (not rowBytes) (oops!)
|
|
; 7/2/86 EHB In ColorMap, use bit 13 of rowbytes to draw old-style colors
|
|
; into new-style ports.
|
|
; 6/22/86 EHB Added multi-depth patexpand (version 0.1)
|
|
; 6/20/86 EHB Added compatibility color mapping to COLORMAP
|
|
; 6/17/86 EHB Tweaked GetPixel to work with cGrafPorts
|
|
; 6/10/86 EHB Redid DrawSlab to use longwords and 020 instructions.
|
|
; 6/9/86 EHB Removed long mask routines in lieu of macros (found a better
|
|
; way)
|
|
; 6/8/86 EHB Redid XORSlab using 020 instructions
|
|
; 6/6/86 EHB Added routines LLeftMask,LRightMask,LBitMask
|
|
; 4/16/86 EHB Added 0 byte at end of file for alignment
|
|
;
|
|
|
|
|
|
BLANKS ON
|
|
STRING ASIS
|
|
|
|
MACHINE MC68020
|
|
|
|
;-------------------------------------------------------------
|
|
;
|
|
; --> UTIL.TEXT
|
|
;
|
|
; SMALL UTILITY ROUTINES USED BY QuickDraw
|
|
;
|
|
|
|
; MODIFICATIONS
|
|
|
|
; 16Apr86 EHB Added 0 byte at end of file for alignment
|
|
; 6Jun86 EHB Added routines LLeftMask,LRightMask,LBitMask
|
|
; 8Jun86 EHB Redid XORSlab using 020 instructions
|
|
; 9Jun86 EHB Removed long mask routines in lieu of macros (found a better way)
|
|
; 10Jun86 EHB Redid DrawSlab to use longwords and 020 instructions.
|
|
; 17Jun86 EHB Tweaked GetPixel to work with cGrafPorts
|
|
; 20Jun86 EHB Added compatibility color mapping to COLORMAP
|
|
; 22Jun86 EHB Added multi-depth patexpand (version 0.1)
|
|
; 2Jul86 EHB In ColorMap, use bit 13 of rowbytes to draw old-style colors
|
|
; into new-style ports.
|
|
; 7Jul86 EHB In ColorMap, use portBits+rowBytes (not rowBytes) (oops!)
|
|
; 22Jul86 EHB In PatExpand, only colorize pattern if copy mode
|
|
; Added color to pattern OR and pattern BIC transfer modes in DrawSlab
|
|
; 26Jul86 EHB Added support for expanded patterns
|
|
; 29Jul86 EHB Use new stack-based EXPAT buffer
|
|
; 12Dec86 CRC Added arithmetic modes
|
|
; 30Dec86 EHB Modified colorMap to check grafPort type before using colors
|
|
; 3Jan87 CRC color correction in colorMap; bug fixes in arithmetic modes
|
|
; 21Jan87 EHB Modified colorMap to check grafPort type before using colors
|
|
|
|
; 14Apr88 BAL Modified GetCPixel to operate in 32 bit addressing mode
|
|
; 04May88 BAL Modified XorSlab to maintain bit width as a long
|
|
; 06May88 BAL Altered ColorMap to clean invColor and colorTable ptrs
|
|
; 06May88 BAL Rolled in fix to set bcolor to white during transparent blit
|
|
; 15Sep88 BAL Compute slab bit-width as a long
|
|
; 19Sep88 BAL Altered ColorMap, DrawSlab to use common stack frame file 'Drawing Vars.a'
|
|
; 22Jan89 BAL Altered DrawSlab loops to use patVPos as a long.
|
|
|
|
|
|
; ; <SM4>.start
|
|
; Macros to set the alpha channel mask.
|
|
; These will be moved into an interface file as soon as
|
|
; the High Level API for manipulating the alpha channel is complete.
|
|
;
|
|
MACRO
|
|
_GetForeAlphaMask
|
|
MOVE.W #$0F,d0
|
|
JSR ([$E00+$3C0*4])
|
|
ENDM
|
|
|
|
MACRO
|
|
_GetBackAlphaMask
|
|
MOVE.W #$10,d0
|
|
JSR ([$E00+$3C0*4])
|
|
ENDM ; <SM4>.end
|
|
|
|
|
|
VisRgnChanged PROC EXPORT ;<26MAR90 KON>
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Procedure VisRgnChanged(thePort: GrafPort);
|
|
;
|
|
; This call will be needed for video windows so the mask plane
|
|
; for touchstone can be updated. Non-video QD simply returns.
|
|
;
|
|
rts
|
|
ENDPROC
|
|
|
|
BitNot FUNC EXPORT
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Function BitNot(long: LongInt): LongInt;
|
|
;
|
|
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
|
NOT.L (SP) ;INVERT LONG
|
|
MOVE.L (SP)+,(SP) ;STORE INTO RESULT
|
|
JMP (A0) ;AND RETURN
|
|
|
|
|
|
BitAnd FUNC EXPORT
|
|
EXPORT BitXor,BitOr,BitShift
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Function BitAnd(long1,long2: LongInt): LongInt;
|
|
;
|
|
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
|
MOVE.L (SP)+,D0 ;GET ONE LONG
|
|
AND.L (SP)+,D0 ;AND IT WITH THE OTHER
|
|
BRA.S DONE ;AND STORE RESULT
|
|
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Function BitXor(long1,long2: LongInt): LongInt;
|
|
;
|
|
BitXor MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
|
MOVE.L (SP)+,D0 ;GET ONE LONG
|
|
MOVE.L (SP)+,D1 ;GET THE SECOND
|
|
EOR.L D1,D0 ;XOR BOTH
|
|
BRA.S DONE ;AND STORE RESULT
|
|
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Function BitOr(long1,long2: LongInt): LongInt;
|
|
;
|
|
BitOr MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
|
MOVE.L (SP)+,D0 ;GET ONE LONG
|
|
OR.L (SP)+,D0 ;OR IT WITH THE OTHER
|
|
BRA.S DONE ;AND STORE RESULT
|
|
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Function BitShift(long: LongInt; count: INTEGER): LongInt;
|
|
;
|
|
; positive count --> shift left.
|
|
; negative count --> shift right.
|
|
;
|
|
BitShift MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
|
MOVE (SP)+,D1 ;GET COUNT
|
|
BPL.S SHLEFT ;SHIFT LEFT IF POSITIVE
|
|
NEG D1 ;MAKE COUNT POSITIVE
|
|
MOVE.L (SP)+,D0 ;GET LONG
|
|
LSR.L D1,D0 ;SHIFT IT RIGHT
|
|
BRA.S DONE ;AND STORE RESULT
|
|
SHLEFT MOVE.L (SP)+,D0 ;GET LONG
|
|
LSL.L D1,D0 ;SHIFT IT LEFT
|
|
DONE MOVE.L D0,(SP) ;STORE THE RESULT
|
|
JMP (A0) ;AND RETURN
|
|
|
|
|
|
BitTst FUNC EXPORT
|
|
EXPORT BitSet,BitClr
|
|
;---------------------------------------------------------
|
|
;
|
|
; FUNCTION BitTst(bytePtr: Ptr; bitNum: LongInt): BOOLEAN;
|
|
;
|
|
BSR.S SHARE
|
|
MOVE.L (SP)+,A1 ;GET PTR
|
|
BTST D0,0(A1,D1.L) ;TEST THE BIT
|
|
SNE (SP) ;SET OR CLEAR RESULT
|
|
NEG.B (SP) ;CONVERT -1 TO 1
|
|
JMP (A0) ;RETURN
|
|
|
|
|
|
;---------------------------------------------------------
|
|
;
|
|
; PROCEDURE BitSet(bytePtr: Ptr; bitNum: LongInt);
|
|
;
|
|
BitSet BSR.S SHARE
|
|
MOVE.L (SP)+,A1 ;GET PTR
|
|
BSET D0,0(A1,D1.L) ;SET THE BIT
|
|
; needed for flakey 040s <6>
|
|
JMP (A0)
|
|
|
|
|
|
;---------------------------------------------------------
|
|
;
|
|
; PROCEDURE BitClr(bytePtr: Ptr; bitNum: LongInt);
|
|
;
|
|
BitClr BSR.S SHARE
|
|
MOVE.L (SP)+,A1 ;GET PTR
|
|
BCLR D0,0(A1,D1.L) ;SET THE BIT
|
|
JMP (A0)
|
|
;
|
|
;
|
|
;
|
|
SHARE MOVE.L (A7)+,A1
|
|
MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
|
MOVE.L (SP)+,D1 ;GET BITNUM
|
|
MOVE D1,D0 ;COPY IT
|
|
ASR.L #3,D1 ;CONVERT BITS TO BYTES
|
|
NOT D0 ;REVERSE BIT SENSE
|
|
JMP (A1)
|
|
|
|
|
|
|
|
Random FUNC EXPORT
|
|
;--------------------------------------------------------------
|
|
;
|
|
; FUNCTION Random: INTEGER;
|
|
;
|
|
; returns a signed 16 bit number, and updates unsigned 32 bit randSeed.
|
|
;
|
|
; recursion is randSeed := (randSeed * 16807) MOD 2147483647.
|
|
;
|
|
; See paper by Linus Schrage, A More Portable Fortran Random Number Generator
|
|
; ACM Trans Math Software Vol 5, No. 2, June 1979, Pages 132-138.
|
|
;
|
|
; Clobbers D0-D2, A0
|
|
;
|
|
;
|
|
; GET LO 16 BITS OF SEED AND FORM LO PRODUCT
|
|
; xalo := A * LoWord(seed)
|
|
;
|
|
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QuickDraw GLOBALS
|
|
MOVE #16807,D0 ;GET A = 7^5
|
|
MOVE D0,D2 ;GET A = 7^5
|
|
MULU RANDSEED+2(A0),D0 ;CALC LO PRODUCT = XALO
|
|
;
|
|
; FORM 31 HIGHEST BITS OF LO PRODUCT
|
|
; fhi:=HiWord(seed) * ORD4(a) + HiWord(xalo);
|
|
;
|
|
MOVE.L D0,D1 ;COPY xalo
|
|
CLR.W D1
|
|
SWAP D1 ;GET HiWord(xalo) as a long
|
|
MULU RANDSEED(A0),D2 ;MULT BY HiWord(seed)
|
|
ADD.L D1,D2 ;ADD LEFTLO = FHI
|
|
;
|
|
; GET OVERFLOW PAST 31ST BIT OF FULL PRODUCT
|
|
; k:=fhi DIV 32768;
|
|
;
|
|
MOVE.L D2,D1 ;COPY FHI
|
|
ADD.L D1,D1 ;CALC 2 TIMES FHI
|
|
CLR.W D1
|
|
SWAP D1 ;CALC FHI SHIFTED RIGHT 15 FOR K
|
|
;
|
|
; ASSEMBLE ALL THE PARTS AND PRE-SUBTRACT P
|
|
; seed:=((BitAnd(XALO,$0000FFFF) - P) + BitAnd(fhi,$00007FFF) * b16) + K;
|
|
;
|
|
AND.L #$0000FFFF,D0 ;GET LO WORD XALO
|
|
SUB.L #$7FFFFFFF,D0 ;SUBTRACT P = 2^31-1
|
|
AND.L #$00007FFF,D2 ;BitAnd(fhi,$00007FFF)
|
|
SWAP D2 ;TIMES 64K
|
|
ADD.L D1,D2 ;PLUS K
|
|
ADD.L D2,D0 ;CALC TOTAL
|
|
;
|
|
; IF seed < 0 THEN seed:=seed+p;
|
|
;
|
|
BPL.S UPDATE
|
|
ADD.L #$7FFFFFFF,D0
|
|
UPDATE MOVE.L D0,RANDSEED(A0) ;UPDATE SEED
|
|
CMP.W #$8000,D0 ;IS NUMBER -32768 ?
|
|
BNE.S NUMOK ;NO, CONTINUE
|
|
CLR D0 ;YES, RETURN ZERO INSTEAD
|
|
NUMOK MOVE.W D0,4(SP) ;RETURN LO WORD AS RESULT
|
|
RTS
|
|
|
|
|
|
|
|
ForeColor PROC EXPORT
|
|
EXPORT BackColor,PortLong,ColorBit,PortWord
|
|
;--------------------------------------------------------------
|
|
;
|
|
; PROCEDURE ForeColor(color: LongInt);
|
|
;
|
|
MOVEQ #FGCOLOR,D0 ;GET OFFSET TO FGCOLOR
|
|
|
|
CSHARE MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QuickDraw GLOBALS
|
|
MOVE.L THEPORT(A0),A0 ;POINT TO THEPORT
|
|
TST PORTBITS+ROWBYTES(A0) ;OLD OR NEW PORT?
|
|
BPL.S PORTLONG ;=>OLD PORT, INSTALL LONG INTO PORT
|
|
MOVE D0,-(SP) ;SAVE OFFSET TO COLOR FIELD
|
|
MOVE.L 6(SP),D0 ;GET COLOR (xxxC MYBr gbwb)
|
|
|
|
MOVE.L PORTBITS+BASEADDR(A0),A0 ;GET HANDLE TO PORT PIXMAP
|
|
MOVE.L (A0),A0 ;POINT TO PIXMAP
|
|
|
|
; CONVERT THE PLANAR BITS (xxxC MYBr gbwb) TO AN RGB VALUE
|
|
|
|
LSR.L #1,D0 ;CHECK FOR WHITE (->CMYB rgbw)
|
|
BCS.S @0 ;=>NOT WHITE
|
|
OR #$00E0,D0 ;ELSE SET WHITE BITS (CMY = 111)
|
|
@0 LSR #5,D0 ;SHIFT CMYÊINTO LOW NIBBLE
|
|
AND #$7,D0 ;CLEAR ALL BUT LOW NIBBLE
|
|
MOVE.L QDCOLORS,A0 ;POINT TO DEFAULT COLORS
|
|
|
|
; SET THE SPECIFIED COLOR
|
|
|
|
PEA 2(A0,D0*8) ;PUSH ADDRESS OF RGB
|
|
CMP #FGCOLOR,4(SP) ;ARE WE SETTING THE FORECOLOR?
|
|
BNE.S DOBACK ;=> NO, SET BACKCOLOR
|
|
_RGBFORECOLOR ;SET THE FOREGROUND COLOR
|
|
BRA.S DONE ;=>AND RETURN
|
|
|
|
DOBACK _RGBBACKCOLOR ;ELSE SET THE BACKGROUND COLOR
|
|
DONE MOVE (SP)+,D0 ;POP THE OFFSET
|
|
MOVE.L (SP)+,A1 ;GET THE RETURN ADDRESS
|
|
ADDQ #4,SP ;STRIP THE PARAMETER
|
|
JMP (A1) ;AND RETURN
|
|
|
|
|
|
;--------------------------------------------------------------
|
|
;
|
|
; PROCEDURE BackColor(color: LongInt);
|
|
;
|
|
BackColor
|
|
MOVEQ #BKCOLOR,D0 ;GET OFFSET TO BKCOLOR
|
|
BRA.S CSHARE ;INSTALL COLOR INTO PORT
|
|
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; PROCEDURE PortLong(long: LongInt);
|
|
; INSTALL A LONG INTO CURRENT GRAFPORT. ENTER WITH OFFSET IN D0
|
|
;
|
|
PortLong
|
|
MOVE.L (SP)+,A1 ;POP RETURN ADDR
|
|
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QuickDraw GLOBALS
|
|
MOVE.L THEPORT(A0),A0 ;POINT TO THEPORT
|
|
MOVE.L (SP)+,0(A0,D0) ;INSTALL LONG INTO THEPORT
|
|
JMP (A1) ;AND RETURN
|
|
|
|
|
|
;--------------------------------------------------------------
|
|
;
|
|
; PROCEDURE ColorBit(whichBit: INTEGER);
|
|
;
|
|
ColorBit
|
|
MOVEQ #COLRBIT,D0 ;GET OFFSET TO COLRBIT
|
|
;FALL THRU INTO PORTWORD
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; PROCEDURE PortWord(word: INTEGER);
|
|
; INSTALL A WORD INTO CURRENT GRAFPORT. ENTER WITH OFFSET IN D0
|
|
;
|
|
PortWord
|
|
MOVE.L (SP)+,A1 ;POP RETURN ADDR
|
|
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QuickDraw GLOBALS
|
|
MOVE.L THEPORT(A0),A0 ;POINT TO THEPORT
|
|
MOVE.W (SP)+,0(A0,D0) ;INSTALL WORD INTO THEPORT
|
|
JMP (A1) ;AND RETURN
|
|
|
|
|
|
|
|
GetMaskTab PROC EXPORT
|
|
EXPORT LeftMask,RightMask,BitMask,MaskTab
|
|
;----------------------------------------------------------
|
|
;
|
|
; ASSEMBLY LANGUAGE CALLABLE PROCEDURES LEFTMASK, RIGHTMASK, AND BITMASK:
|
|
;
|
|
; ENTER WITH COORDINATE IN D0, RETURNS WITH 16 BIT MASK IN D0
|
|
; NO OTHER REGISTERS ALTERED.
|
|
;
|
|
LEA MaskTab,A0 ;POINT TO MASK TABLE
|
|
RTS ;AND RETURN
|
|
|
|
LeftMask
|
|
AND #$F,D0 ;TREAT MOD 16
|
|
ADD D0,D0 ;DOUBLE FOR TABLE
|
|
MOVE MASKTAB+32(D0),D0 ;GET LEFTMASK
|
|
RTS
|
|
|
|
RIGHTMASK
|
|
AND #$F,D0 ;TREAT MOD 16
|
|
ADD D0,D0 ;DOUBLE FOR TABLE
|
|
MOVE MASKTAB(D0),D0 ;GET RIGHT MASK
|
|
RTS
|
|
|
|
BITMASK AND #$F,D0 ;TREAT MOD 16
|
|
ADD D0,D0 ;DOUBLE FOR TABLE
|
|
MOVE MASKTAB+64(D0),D0 ;GET BITMASK
|
|
RTS
|
|
|
|
MASKTAB DC.W $0000,$8000,$C000,$E000 ;TABLE OF 16 RIGHT MASKS
|
|
DC.W $F000,$F800,$FC00,$FE00
|
|
DC.W $FF00,$FF80,$FFC0,$FFE0
|
|
DC.W $FFF0,$FFF8,$FFFC,$FFFE
|
|
|
|
DC.W $FFFF,$7FFF,$3FFF,$1FFF ;TABLE OF 16 LEFT MASKS
|
|
DC.W $0FFF,$07FF,$03FF,$01FF
|
|
DC.W $00FF,$007F,$003F,$001F
|
|
DC.W $000F,$0007,$0003,$0001
|
|
|
|
DC.W $8000,$4000,$2000,$1000 ;TABLE OF 16 BIT MASKS
|
|
DC.W $0800,$0400,$0200,$0100
|
|
DC.W $0080,$0040,$0020,$0010
|
|
DC.W $0008,$0004,$0002,$0001
|
|
|
|
|
|
; translation for arithmetic modes when drawn at 1 bit per pixel
|
|
|
|
arithMode PROC EXPORT
|
|
; hilite
|
|
;avg addPin addOver subPin trans max subOver min
|
|
DC.B srcCopy, srcBic, srcXor, srcOr, srcOr, srcBic, srcXor, srcOr
|
|
|
|
|
|
|
|
ColorMap PROC EXPORT
|
|
IMPORT arithMode
|
|
IMPORT NOPfgColorTable
|
|
|
|
;Êrolled in from QDciPatchROM.a <sm 6/9/92>stb
|
|
|
|
;----------------------------------------------------------------
|
|
;
|
|
; PROCEDURE ColorMap: (pat: Pattern; mode: INTEGER);
|
|
;
|
|
; ADJUST INPUT MODE AND PATTERN TO ACCOMPLISH COLOR SEPARATION.
|
|
; POTENTIALLY MODIFIES: LOCMODE, NEWPATTERN, LOCPAT, FCOLOR, BCOLOR.
|
|
;
|
|
; ADJUSTED MODE IS RETURNED IN LOCMODE(A6).
|
|
; IF PATTERN IS ADJUSTED, THEN NEWPATTERN(A6) IS SET FALSE AND LOCPAT(A6) IS MODIFIED.
|
|
; FCOLOR(A6) AND BCOLOR(A6) ARE MODIFIED AS DESCRIBED BELOW.
|
|
;
|
|
; IF OLD PORT, TRANSLATES OLD-STYLE FGCOLOR, BKCOLOR INTO AN RGB,
|
|
; AND THEN GETS THE INDEX FOR THAT COLOR. FOR ALL PORTS, THE
|
|
; RETURNED COLOR CONTAINS THE PIXEL REPLICATED THROUGHOUT THE LONG
|
|
; (SUITABLE FOR MASKING).
|
|
;
|
|
; FOR EITHER MODE, IF THE DESTINATION IS ONE BIT DEEP, DO PLANAR REMAPPING
|
|
; SO THAT FASTEST COPYBITS BLT ROUTINES DON'T NEED TO APPLY COLOR.
|
|
;
|
|
; CLOBBERS A0-A1,D0-D2
|
|
;
|
|
; CALLED BY: DRAWARC, DRAWLINE, STRETCH
|
|
|
|
; A6 STACK FRAME ALLOCATED BY CALLER, USED LOCALLY.
|
|
|
|
;-------------------------------------------------
|
|
;
|
|
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
|
;
|
|
;
|
|
&CurFile SETC 'COLORMAP'
|
|
|
|
INCLUDE 'DrawingVars.a'
|
|
|
|
|
|
;-------------------------------------------------
|
|
|
|
PARAMSIZE EQU 0 ;SIZE OF PARAMETERS
|
|
|
|
VARSIZE EQU 0 ;SIZE OF LOCALS
|
|
|
|
; LINK A4,#VARSIZE ;MAKE A STACK FRAME
|
|
MOVEM.L D3-D7/A2-A3,-(SP) ;SAVE REGS
|
|
|
|
MOVE.L GRAFGLOBALS(A5),A2 ;POINT TO QUICKDRAW GLOBALS
|
|
MOVE.L THEPORT(A2),A2 ;POINT TO THE PORT
|
|
MOVE locMode(A6),D3 ;get the mode
|
|
MOVE.L FGCOLOR(A2),D6 ;GET FOREGROUND COLOR INTO D6
|
|
MOVE.L BKCOLOR(A2),D7 ;GET BACKGROUND COLOR INTO D7
|
|
; <1.6> BAL
|
|
@modeOK MOVE D3,D1 ;make a copy of the mode
|
|
AND #$FFF7,D3 ;clear the pattern bit
|
|
EOR D3,D1 ;set only the pattern bit
|
|
CMP #srcXor,D3 ;could it be replaced by hilite?
|
|
BNE.S @noXorSub
|
|
BSET #hiliteBit,HiliteMode ;check to see if highlight bit was set
|
|
BNE.S @noXorSub ;if not, invert old way
|
|
MOVE #$32,D3 ;set to src highlight
|
|
@noXorSub
|
|
BTST #5,D3 ;an arithmetic mode?
|
|
BEQ.S @leaveModeAlone ;skip if no mode
|
|
CMP #1,dstPix+pixelSize(A6) ;1 bit per pixel on the destination
|
|
BNE.S @leaveModeAlone
|
|
AND #$07,D3 ;get variants
|
|
MOVE.B arithMode(D3),D3 ;get mapped mode in 1 bit
|
|
@leaveModeAlone
|
|
OR D1,D3 ;combine mapped mode and pattern bit
|
|
MOVE D3,locMode(A6) ;save off altered mode
|
|
|
|
; <17> Beginning of alpha channel changes
|
|
|
|
CLR.B alphaMode(A6) ;clear the alpha mode to default
|
|
BTST #5,D3 ;check again for arithmetic modes
|
|
BNE @noalpha ;skip alpha stuff if arithmetic
|
|
MOVE.W dstShift(A6),D0 ;yes, get pixel size
|
|
|
|
; MOVE.L ((NOPfgColorTable-*).L,PC,D0.W*4),D0
|
|
|
|
LEA (NOPfgColorTable-*).L,A1 ;get distance from here to NOPfgColorTable
|
|
LEA *-6(A1.L),A1 ;get address of "white" table
|
|
MOVE.L 0(A1,D0.W*4),D0 ;get default mask for current depth
|
|
MOVE.L D0,alphaBack(A6) ;save for later use
|
|
MOVE.W D3,D5 ;make copy of adjusted mode
|
|
AND.W #$03,D5 ;mask off all but base mode
|
|
CMP.W #srcXor,D5 ;are we xoring?
|
|
BEQ.S @1 ;yes, use normal default mask
|
|
MOVEQ #-1,D0 ;get all ones
|
|
@1: MOVE.L D0,alphaMask(A6) ;save default alphaMask
|
|
|
|
TST portBits+rowBytes(A2) ;is it an old port?
|
|
BPL @noalpha ;yes, alpha mode is illegal
|
|
MOVE.W dstPix+pixelSize(A6),D0 ;get depth of destination
|
|
CMP.W #16,D0 ;direct device?
|
|
BLT @noalpha ;no, skip this stuff ; <SM4>
|
|
MOVE.L grafVars(A2),D4 ;get grafvars handle
|
|
BEQ @noalpha ;no grafvars, no alpha
|
|
MOVE.L D4,A0 ;copy handle
|
|
MOVE.L (A0),A1 ;dereference handle
|
|
BTST #PmNewGVBit-8,pmFlags(A1) ;make sure grafvars have been expanded
|
|
BEQ.S @noalpha ;if not, bail
|
|
MOVE.B streamMode(A1),alphaMode(A6);save alpha mode in stack frame
|
|
SUB #18,SP ;make room on stack for results and first error ; <SM4>.start
|
|
move.l a0,-(sp) ;push GrafVars handle
|
|
PEA 14(SP) ;push pointer to where we want results for background stream
|
|
subq #2,sp ;room for error
|
|
move.l a0,-(sp) ;push GrafVars handle
|
|
PEA 16(SP) ;push pointer to where we want results for foreground stream
|
|
_GetForeAlphaMask ;get foreground stream and ratio
|
|
addq #2,sp ;clear error
|
|
_GetBackAlphaMask ;get background stream and ratio
|
|
addq #2,sp ;clear error ; <SM4>.end
|
|
MOVE.L (SP)+,D0 ;get alpha mask
|
|
MOVE.L (SP)+,D4 ;get alpha fore color
|
|
CMP.W #srcXor,D5 ;are we xoring?
|
|
BNE.S @2 ;no, use normal default mask
|
|
MOVE.L D4,D0 ;yes, use alpha fore color as alpha mask
|
|
@2: MOVE.L D0,alphaFore(A6) ;save alpha mask
|
|
ADDQ #4,SP ;throw away background mask
|
|
MOVE.L (SP)+,D5 ;get alpha back color
|
|
MOVEQ #0,D2 ;clear out alpha mask
|
|
MOVE.B alphaMode(A6),D0 ;get alpha again
|
|
BNE.S @3 ;if non-zero, use that value
|
|
MOVEQ #3,D0 ;if zero, draw to both
|
|
@3: BTST #1,D0 ;are we drawing to graphics?
|
|
BEQ.S @4 ;no, skip
|
|
OR.L alphaFore(A6),D2 ;yes, add alpha bits to mask
|
|
OR.L D4,D6 ;apply alphaFgColor to the foreground color
|
|
OR.L D5,D7 ;apply alphaBkColor to the background color
|
|
@4: BTST #0,D0 ;is the alpha going to be drawn?
|
|
BEQ.S @5 ;no, then don't apply alpha to fg,bk colors
|
|
OR.L alphaBack(A6),D2 ;yes, add graphic bits to mask
|
|
@5: MOVE.L D2,alphaMask(A6) ;save alpha mask in stack frame
|
|
NOT.L D2 ;check for mask of all ones
|
|
SNE alphaMode(A6) ;if mask of all ones, set alphamode to true
|
|
@noalpha
|
|
|
|
; <17> End of alpha channel changes
|
|
|
|
MOVE COLRBIT(A2),D2 ;GET COLOR BIT SELECT
|
|
MOVEQ #-1,D4 ;DEFAULT VALUE FOR FGLONG
|
|
MOVEQ #0,D5 ;DEFAULT VALUE FOR BKLONG
|
|
|
|
|
|
; IF IT IS AN OLD PORT, AND WE ARE GOING TO THE SCREEN, THEN DON'T DO
|
|
; SEPARATION, JUST MAP PLANAR COLOR VALUES INTO COLOR INDICES.
|
|
; IF IT IS A NEW PORT, DON'T NEED TO REMAP THE VALUES (UNLESS ONE BIT DEEP).
|
|
|
|
|
|
; if pattern mode and new pattern, leave black and white
|
|
|
|
MOVE D3,D0 ;copy the mode
|
|
BCLR #3,D0 ;clear pattern bit
|
|
|
|
; not necessary since d1 already has pattern bit
|
|
; SNE D1 ;remember that the pattern bit was set
|
|
|
|
; CMP #$32,D0 ;is it hilite? <¥¥¥>
|
|
; BEQ COLOROK ;if so, use black/white <¥¥¥>
|
|
CMP #srcXor,D0 ;is it srcXor or patXor?
|
|
BEQ COLOROK ;if so, use black/white
|
|
CMP #notSrcXor,D0 ;is it notSrcXor or notPatXor?
|
|
BEQ COLOROK ;if so, use black/white
|
|
TST.B D1 ;IS IT A PATTERN MODE?
|
|
BEQ.S DestBitMap ;if not skip, otherwise check if its a multibit pattern <08JUNE92 SAH>
|
|
|
|
ISPAT TST.B NEWPATTERN(A6) ;FLAG TRUE IF DESTINATION IS PIXMAP
|
|
BEQ.S DestBitMap ;=>YES, GET COLOR PIXEL MASKS
|
|
MOVE.L LOCPAT(A6),A0 ;GET PATTERN POINTER
|
|
MOVE.L (A0),A0 ;GET HANDLE TO PATTERN
|
|
MOVE.L (A0),A0 ;GET POINTER TO PATTERN
|
|
TST PATTYPE(A0) ;WHAT TYPE OF PATTERN IS IT?
|
|
BNE COLOROK ;=>A NEW ONE, BLACK FG & WHITE BK
|
|
|
|
DestBitMap
|
|
;here src is either an old pattern or image data
|
|
TST PORTBITS+ROWBYTES(A2) ;old port or new?
|
|
BPL.S REMAP ;if old, go check color bit
|
|
|
|
CMP #2,DSTPIX+PIXELSIZE(A6) ;worry about fg remapping?
|
|
BGT.S REP ;if 4 or 8 bit, just replicate the pixel
|
|
|
|
CMP.L D6,D7 ;is the fg color the same as the bk color?
|
|
BNE.S REP ;if not, no conflict; just replicate the pixel
|
|
|
|
; If the source RGBs are identical, donÕt change the foreground. But, if they started out
|
|
; different, and they mapped to be the same thing, then flip (invert) the foreground color.
|
|
|
|
LEA RGBFgColor(A2),A0 ;get the forecolor RGB from the port
|
|
LEA RGBBkColor(A2),A1 ;and get the backcolor as well
|
|
CMP.L (A0)+,(A1)+ ;if the R or G are not equal, flip the back color
|
|
BNE.S @goOnAndFlip
|
|
CMP (A0)+,(A1)+ ;if R, G and B are equal, donÕt flip the back color
|
|
BEQ.S REP
|
|
@goOnAndFlip
|
|
tst d2 ;color bit set? <1.6> BAL
|
|
bne.s rep ;yes, fg=bk is ok <1.6> BAL
|
|
LEA RGBFgColor(A2),A0 ;get the forecolor RGB from the port
|
|
SUBQ #6,SP ;make room for the color
|
|
MOVE.L SP,A1 ;set up as destination
|
|
MOVE.L (A0)+,(A1)+ ;copy R, G to stack
|
|
MOVE (A0)+,(A1)+ ;copy B to stack
|
|
MOVE.L SP,-(SP) ;push the copy of the forecolor RGB
|
|
_InvertColor ;get the furthest thing from it
|
|
SUBQ #4,SP ;make room for the function result
|
|
PEA 4(SP) ;push the inverted RGB
|
|
_Color2Index ;get its index
|
|
MOVE.L (SP)+,D6 ;and put it in the forecolor register
|
|
ADDQ #6,SP ;throw away the color placeholder
|
|
BRA.S REP ;now the foreground, background longs can be made
|
|
|
|
REMAP TST D2 ;GET COLOR BIT SELECT
|
|
BMI COLOROK ;COLRBIT NEG MEANS NO COLOR
|
|
BNE.S REMAP2 ;=>DOING PLANES, DO OLD WAY
|
|
CMP #1,DSTPIX+PIXELSIZE(A6) ;IS PIXELSIZE 1?
|
|
BEQ.S remapOld1bit ;=>yes, REMAP COLORS FOR old 1-bit pixels
|
|
|
|
MOVE.L D7,D0 ;GET BKCOLOR (xxIC MYBr gbwb)
|
|
BSR mapToColor
|
|
MOVE.L D0,D7 ;get mapped back color
|
|
MOVE.L D6,D0 ;GET FGCOLOR (xxIC MYBr gbwb)
|
|
BSR mapToColor
|
|
MOVE.L D0,D6 ;get mapped fore color
|
|
|
|
; REPLICATE THE RETURNED COLOR THROUGHOUT THE LONG
|
|
|
|
REP MOVE DSTPIX+PIXELSIZE(A6),D0 ;GET THE SIZE OF THE PIXEL
|
|
cmp #1,d0
|
|
beq.s DoOneBit
|
|
MOVE.L D6,D4 ;COPY FG PIXEL
|
|
MOVE.L D7,D5 ;COPY BK PIXEL
|
|
MOVEQ #32,D1 ;GET SIZE OF A LONG
|
|
NXTPXL SUB D0,D1 ;SAY WE'VE DONE A PIXEL
|
|
BLE.S COLOROK ;=>IT WAS THE LAST ONE
|
|
LSL.L D0,D4 ;PREPARE FOR NEXT FG PIXEL
|
|
LSL.L D0,D5 ;PREPARE FOR NEXT BK PIXEL
|
|
OR.L D6,D4 ;INSTALL FG PIXEL
|
|
OR.L D7,D5 ;INSTALL BK PIXEL
|
|
BRA.S NXTPXL ;=>DO ENTIRE LONG
|
|
DoOneBit
|
|
LSR.L #1,D6 ;if 1-bit, fg and bk end up as 0 or -1
|
|
SUBX.L D4,D4 ;note that this ignores whatever is in the other
|
|
LSR.L #1,D7 ; 31 bits incase someone (like the standard MBDF)
|
|
SUBX.L D5,D5 ; puts -1 instead of 1 in forecolor.
|
|
bra.s COLOROK
|
|
|
|
; From here to COLOROK, the port is old, the destination is 1 bit, the modes are old
|
|
|
|
remapOld1bit ;Special case colorbit is zero
|
|
btst #0,d6
|
|
bne.s @fgOK
|
|
moveq #0,d4
|
|
@fgOK
|
|
btst #0,d7
|
|
beq.s ColorOK
|
|
moveq #-1,d5
|
|
bra.s ColorOK
|
|
|
|
REMAP2 MOVEQ #3,D0 ;MASK FOR BOTTOM 2 BITS
|
|
AND D3,D0 ;GET 2 BITS OF MODE
|
|
BEQ.S COPY ;BR IF COPY MODE
|
|
;
|
|
; THE XOR MODES DEPEND ON NEITHER FOREGROUND OR BACKGROUND COLOR
|
|
;
|
|
CMP #2,D0 ;IS IT SOME KIND OF XOR ?
|
|
BEQ.S COLOROK ;YES, THEY DON'T CHANGE
|
|
BGT.S BICMODE ;BRANCH IF BIC
|
|
;ELSE MUST BE OR
|
|
;
|
|
; THE OR MODES DEPEND ONLY ON THE FOREGROUND COLOR
|
|
;
|
|
ORMODE MOVE.L D6,D1 ;GET FOREGROUND COLOR
|
|
SHARE BTST D2,D1 ;TEST FOREGROUND COLOR BIT
|
|
BNE.S COLOROK ;NO CHANGE IF FG TRUE
|
|
EOR #2,D3 ;ELSE INVERT MODE BIT 2
|
|
BRA.S NEWMODE ;UPDATE MODE AND QUIT
|
|
|
|
;
|
|
; THE BIC MODES DEPEND ONLY ON THE BACKGROUND COLOR
|
|
;
|
|
BICMODE MOVE.L D7,D1 ;GET BACKGROUND COLOR
|
|
NOT.L D1 ;INVERT IT
|
|
BRA SHARE ;AND SHARE CODE
|
|
|
|
;
|
|
; THE COPY MODES DEPEND ON BOTH FOREGOUND AND BACKGROUND
|
|
;
|
|
COPY MOVE.L D6,D0 ;GET FOREGROUND COLOR
|
|
MOVE.L D7,D1 ;GET BACKGROUND COLOR
|
|
BTST D2,D0 ;TEST FOREGROUND COLOR BIT
|
|
BEQ.S FORE0 ;BRANCH IF IT'S ZERO
|
|
|
|
FORE1 BTST D2,D1 ;TEST BACKGROUND COLOR BIT
|
|
BEQ.S COLOROK ;NO CHANGE IF BKGND FALSE
|
|
MOVEQ #8,D3 ;ELSE REPLACE MODE = PAT COPY
|
|
USEPAT MOVE.L GRAFGLOBALS(A5),A0 ;GET GLOBAL POINTER
|
|
LEA BLACK(A0),A0 ;POINT TO BLACK PATTERN
|
|
MOVE.L A0,LOCPAT(A6) ;REPLACE PATTERN WITH BLACK
|
|
SF NEWPATTERN(A6) ;AND SET NEWPATTERN FALSE
|
|
BRA.S NEWMODE ;UPDATE MODE AND QUIT
|
|
|
|
FORE0 BTST D2,D1 ;TEST BACKGROUND COLOR BIT
|
|
BNE.S INVMODE ;IF BK TRUE, INVERT MODE
|
|
MOVEQ #12,D3 ;ELSE REPLACE MODE = NOTPAT COPY
|
|
BRA.S USEPAT ;AND PATTERN WITH BLACK
|
|
|
|
INVMODE EOR #4,D3 ;USE INVERSE OF MODE <HACK>
|
|
NEWMODE MOVE D3,LOCMODE(A6) ;CHANGE INPUT MODE
|
|
|
|
COLOROK MOVE.L D4,FCOLOR(A6) ;RETURN EXTENDED PIXEL
|
|
MOVE.L D5,BCOLOR(A6) ;RETURN EXTENDED PIXEL
|
|
|
|
BTST #5,D3 ;is it an arithmetic mode?
|
|
BEQ noArith ;no arithmetic inputs to set up
|
|
MOVE DSTPIX+PIXELSIZE(A6),D7 ;GET THE SIZE OF THE PIXEL
|
|
MOVE.L bkColor(A2),D5 ;get the background color
|
|
TST PORTBITS+ROWBYTES(A2) ;OLD OR NEW GRAFPORT?
|
|
BMI.S setOpColor ;new grafPort, use fields in port
|
|
|
|
; check mode to see if new arithmetic mode in old port
|
|
; if so, set up pin and weight to default values
|
|
; add with pin default pin is white
|
|
; sub with pin default pin is black
|
|
; blend default weight is 50% gray
|
|
|
|
MOVE.L D5,D0 ;pass background color to mapToColor
|
|
BSR mapToColor ;turn the old QD bits into a color long
|
|
MOVE.L D0,D5 ;save it for later
|
|
LEA HiliteRGB,A2 ;get hilite color from low memory
|
|
MOVEQ #$07,D0 ;arithmetic mode variants 0 É 7
|
|
AND D3,D0 ;get masked mode
|
|
SUBQ #1,D0 ;less add with pin variant
|
|
BEQ.S @setWhite ;if add with pin, set to white
|
|
BMI.S @setGray ;if average, set to gray
|
|
LEA xrgbBlack,A0 ;point to black
|
|
BRA.S setUpPinWeight
|
|
@setWhite
|
|
LEA xrgbWhite,A0 ;point to white
|
|
BRA.S setUpPinWeight
|
|
@setGray
|
|
LEA xrgbGray,A0 ;point at gray
|
|
BRA.S setUpPinWeight
|
|
|
|
setOpColor
|
|
; set up pin, weight rgbÕs for modes max, min, and avg
|
|
; set up weightÕs complement for average
|
|
; note that rgb in pin & notWeight are in reverse order from source
|
|
|
|
MOVE.L ([grafVars,A2]),A0 ;point to weight value
|
|
LEA 6(A0),A2 ;point to hilite color
|
|
|
|
; Set up locals in A6 for arithmetic modes in bltBlt, rgnBlt, drawSlab, stretch
|
|
|
|
setUpPinWeight
|
|
MOVEQ #2,D1 ;do three times
|
|
LEA pin+6(A6),A1 ;word past last pin value
|
|
LEA notWeight+6(A6),A3 ;word past last not weight value
|
|
@nextPin
|
|
MOVE (A0)+,D0 ;get red components of pin, weight
|
|
BNE.S @notZero ;if input is zero, change it to 1
|
|
MOVEQ #1,D0 ;so that complement will be -1 (FFFF)
|
|
@notZero
|
|
MOVE D0,-(A1) ;save red as is for pin, weight
|
|
NEG D0 ;flip for complement of weight
|
|
MOVE D0,-(A3) ;save red destination weight
|
|
DBRA D1,@nextPin
|
|
|
|
SUBQ #6,SP ;make room for the color
|
|
SUBQ #4,SP ;space for function result
|
|
MOVE.L A2,-(SP) ;pass pointer to hilite color
|
|
_Color2Index ;leave pixel on stack (hilite color)
|
|
CMP.L (SP),D5 ;same as the background?
|
|
BNE.S @notSame
|
|
LEA 4(SP),A1
|
|
MOVE.L A2,A0
|
|
MOVE.L (A0)+,(A1)+ ;copy R, G to stack
|
|
MOVE (A0)+,(A1)+ ;copy B to stack
|
|
PEA 4(SP) ;push the copy of the background RGB
|
|
_InvertColor ;get the furthest thing from it
|
|
PEA 4(SP) ;pass pointer to hilite color
|
|
_Color2Index ;leave pixel on stack (hilite color)
|
|
@notSame
|
|
|
|
; set up pointers to color table, inverse color table and table resolution in locals
|
|
|
|
MOVE.L ([theGDevice]),A0 ;get a pointer to the current device
|
|
MOVE.L ([GDPMap,A0]),A1 ;get pixMap's handle
|
|
MOVE.L ([GDITable,A0]),A0 ;get the inverse color table's master pointer
|
|
MOVE ITabRes(A0),D0
|
|
MOVE D0,invSize(A6) ;save resolution of inverse color table
|
|
MOVEQ #16,D1
|
|
SUB D0,D1
|
|
MOVE D1,rtShift(A6) ;set up for Average, how far to shift mulu result
|
|
move.l a0,d0
|
|
_rTranslate24To32 ;strip high byte @@@@ BAL
|
|
MOVE.L d0,invColor(A6) ;save pointer to inverse color table
|
|
MOVE.L ([PMTable,A1]),A1 ;pointer to color table
|
|
LEA ctTable+rgb+red(A1),A1 ;location of "red" of first color in color table
|
|
move.l a1,d0
|
|
_rTranslate24To32 ;strip high byte @@@@ BAL
|
|
MOVE.L d0,colorTable(A6) ;save a pointer to the device colortable
|
|
MOVE.L D5,D2 ;COPY BK PIXEL
|
|
MOVE.L (SP),D4 ;copy of hilite pixel
|
|
|
|
;note that weÕre comparing against the port background (which may not be the drawing background)
|
|
|
|
MOVEQ #32,D1 ;GET SIZE OF A LONG
|
|
@nxtPixel
|
|
SUB D7,D1 ;SAY WE'VE DONE A PIXEL
|
|
BLE.S @done ;=>IT WAS THE LAST ONE
|
|
LSL.L D7,D2 ;PREPARE FOR NEXT BK PIXEL
|
|
OR.L D5,D2 ;INSTALL BK PIXEL
|
|
LSL.L D7,D4 ;shift hilite pixel up a notch
|
|
OR.L (SP),D4 ;add in a pixel to the low order pixel position
|
|
BRA.S @nxtPixel
|
|
@done
|
|
MOVE.L D2,transColor(A6) ;save for transparent
|
|
MOVE.L D4,hilitColor(A6) ;save for hilite
|
|
ADD #10,SP ;throw away hilite pixel, rgb inverse
|
|
noArith
|
|
|
|
|
|
MOVEM.L (SP)+,D3-D7/A2-A3 ;RESTORE REGS
|
|
; UNLK A4 ;DONE WITH STACK FRAME
|
|
RTS ;JUST RETURN
|
|
|
|
|
|
; GET COLORS FROM PORT AND MAP FOR PROPER DEPTH
|
|
|
|
; MAP THE RGB IN THE OLD-STYLE COLOR INTO A NEW COLOR INDEX
|
|
; KEEP INTENSITY IN BIT 9.
|
|
|
|
; THE BITS IN THE OLD STYLE COLORS ARE IN THE ORDER:
|
|
|
|
; BIT 0: BK/FG BIT (0 IF WHITE, ELSE 1)
|
|
; BIT 1: NOT BK/FG BIT (1 IF WHITE, ELSE 0)
|
|
; RGB BITS
|
|
; BIT 2: NOT BLUE
|
|
; BIT 3: NOT GREEN
|
|
; BIT 4: NOT RED
|
|
; CMY BITS
|
|
; BIT 5: BLACK BIT
|
|
; BIT 6: YELLOW BIT
|
|
; BIT 7: MAGENTA BIT
|
|
; BIT 8: CYAN BIT
|
|
; INTENSITY BIT
|
|
; BIT 9: 0 = FULL INTENSITY, 1 = HALF INTENSITY
|
|
|
|
|
|
mapToColor
|
|
LSR #1,D0 ;CHECK FOR WHITE (I CMYB rgbw)
|
|
BCS.S @0 ;=>NOT WHITE
|
|
OR #$00E0,D0 ;ELSE SET WHITE BITS (CMY = 111)
|
|
@0 LSR #5,D0 ;SHIFT ICMYÊINTO LOW NIBBLE
|
|
AND #$7,D0 ;CLEAR ALL BUT LOW NIBBLE
|
|
MOVE.L QDColors,A0 ;GET DEFAULT COLORS
|
|
MOVE.L 4(A0,D0*8),-(SP) ;PUSH GREEN, BLUE
|
|
MOVE.W 2(A0,D0*8),-(SP) ;PUSH RED
|
|
CLR.L -(SP) ;MAKE ROOM FOR FUNCTION RESULT
|
|
PEA 4(SP) ;POINT TO VAR RGB
|
|
_COLOR2INDEX ;CONVERT IT TO AN INDEX
|
|
MOVE.L (SP)+,D0 ;GET MAPPED COLOR
|
|
ADDQ #6,SP ;STRIP COLORSPEC
|
|
RTS
|
|
|
|
xrgbBlack DC.W $0000,$0000,$0000 ;BLACK
|
|
xrgbWhite DC.W $FFFF,$FFFF,$FFFF ;WHITE
|
|
xrgbGray DC.W $7FFF,$7FFF,$7FFF ;GRAY
|
|
|
|
|
|
;----------------------------------------------------------------
|
|
;
|
|
; Dispatcher for alpha channel utility routines (Trap $ABC0)
|
|
; Added in revision <17>.
|
|
;
|
|
; as seen in QDciPatchROM.a <sm 6/9/92>stb
|
|
|
|
AlphaDispatch PROC EXPORT
|
|
|
|
IMPORT RSetHSize
|
|
IMPORT SetForeAlpha ; <SM4>.start
|
|
IMPORT SetBackAlpha
|
|
IMPORT GetForeAlpha
|
|
IMPORT GetBackAlpha
|
|
IMPORT GetForeAlphaMask
|
|
IMPORT GetBackAlphaMask ; <SM4>.end
|
|
|
|
JMP @dispatch(PC,D0.W*4)
|
|
@dispatch
|
|
BRA.W AlphaVersion
|
|
BRA.W SetForeStream
|
|
BRA.W SetForeTransparency
|
|
BRA.W SetBackStream
|
|
BRA.W SetBackTransparency
|
|
BRA.W GetForeStream
|
|
BRA.W GetForeTransparency
|
|
BRA.W GetBackStream
|
|
BRA.W GetBackTransparency
|
|
BRA.W ResizeGrafVars
|
|
BRA.W GetStreamMode
|
|
BRA.W SetForeAlpha ; <SM4>.start
|
|
BRA.W SetBackAlpha
|
|
BRA.W GetForeAlpha
|
|
BRA.W GetBackAlpha
|
|
BRA.W GetForeAlphaMask
|
|
BRA.W GetBackAlphaMask ; <SM4>.end
|
|
|
|
;
|
|
; FUNCTION AlphaVersion:INTEGER;
|
|
;
|
|
AlphaVersion
|
|
MOVE.W #$0100,4(SP) ;return version 1.0
|
|
RTS
|
|
|
|
|
|
;
|
|
; PROCEDURE SetForeStream(streamID: LongInt);
|
|
; PROCEDURE SetBackStream(streamID: LongInt);
|
|
;
|
|
SetForeStream
|
|
MOVEQ #foreStream,D1 ;point at foreStream/foreRatio in grafvars
|
|
BRA.S SetStream ;jump into common code
|
|
SetBackStream
|
|
MOVEQ #backStream,D1 ;point at backStream/backRatio in grafvars
|
|
SetStream
|
|
BSR.S SetSub
|
|
BEQ.S @exit
|
|
MOVE.L 4(SP),(A0) ;move stream from stack to grafvars
|
|
@exit RTD #4 ;clean off stack and return
|
|
|
|
|
|
;
|
|
; PROCEDURE SetForeTransparency(streamRatio: INTEGER);
|
|
; PROCEDURE SetBackTransparency(streamRatio: INTEGER);
|
|
;
|
|
SetForeTransparency
|
|
MOVEQ #foreRatio,D1 ;point at foreStream/foreRatio in grafvars
|
|
BRA.S SetTrans ;jump into common code
|
|
SetBackTransparency
|
|
MOVEQ #backRatio,D1 ;point at backStream/backRatio in grafvars
|
|
SetTrans
|
|
BSR.S SetSub
|
|
BEQ.S @exit
|
|
MOVE.W 4(SP),(A0) ;move ratio from stack to grafvars
|
|
@exit RTD #2 ;clean off stack and return
|
|
|
|
|
|
SetSub MOVE.L grafGlobals(A5),A0 ;point to QuickDraw globals
|
|
MOVE.L thePort(A0),A0 ;get pointer to current port
|
|
TST portBits+rowBytes(A0) ;new port?
|
|
BPL.S @exit ;no, then don't access grafVars
|
|
MOVE.L grafVars(A0),D0 ;get grafVars handle from port
|
|
BEQ.S @exit ;if null, exit
|
|
MOVE.L D0,A0 ;move grafvars handle to more useful register
|
|
MOVE.L (A0),A0 ;deref it
|
|
BTST #PmNewGVBit-8,pmFlags(A0) ;check for new grafvars flag
|
|
BNE.S @1 ;if it was set, no need to grow grafvars
|
|
MOVE.L D0,-(SP) ;save grafvars handle
|
|
MOVE.L D0,-(SP) ;push grafvars handle for resize call
|
|
_ResizeGrafVars ;grow grafvars to new size
|
|
MOVE.L (SP)+,A0 ;restore grafvars handle
|
|
MOVE.L (A0),A0 ;deref it again
|
|
@1: ADD.W D1,A0 ;bump to field being modified
|
|
ST D0 ;set do it flag to true
|
|
RTS
|
|
@exit CLR D0 ;set do it flag to false
|
|
RTS
|
|
|
|
;
|
|
; PROCEDURE GetForeStream: INTEGER;
|
|
; PROCEDURE GetBackStream: INTEGER;
|
|
;
|
|
GetForeStream
|
|
MOVEQ #foreStream,D1 ;point at foreStream in grafvars
|
|
BRA.S GetStream ;jump into common code
|
|
GetBackStream
|
|
MOVEQ #backStream,D1 ;point at backStream in grafvars
|
|
GetStream
|
|
MOVE.L grafGlobals(A5),A0 ;point to QuickDraw globals
|
|
MOVE.L thePort(A0),A0 ;get pointer to current port
|
|
TST portBits+rowBytes(A0) ;new port?
|
|
BPL.S @default ;no, then don't access grafVars
|
|
MOVE.L grafVars(A0),D0 ;get grafVars handle from port
|
|
BEQ.S @default ;if null, return default info
|
|
MOVE.L D0,A0 ;move grafvars handle to more useful register
|
|
MOVE.L (A0),A0 ;deref it
|
|
BTST #PmNewGVBit-8,pmFlags(A0) ;check for new grafvars flag
|
|
BEQ.S @default ;if it was clear, return default info
|
|
ADD.W D1,A0 ;bump to either foreStream or backStream
|
|
MOVE.L (A0),4(SP) ;move stream from grafvars to user variable
|
|
RTS
|
|
@default
|
|
CLR.L 4(SP) ;move default stream to user variable
|
|
RTS
|
|
|
|
;
|
|
; PROCEDURE GetForeTransparency: INTEGER;
|
|
; PROCEDURE GetBackTransparency: INTEGER;
|
|
;
|
|
GetForeTransparency
|
|
MOVEQ #foreRatio,D1 ;point at foreRatio in grafvars
|
|
BRA.S GetTrans ;jump into common code
|
|
GetBackTransparency
|
|
MOVEQ #backRatio,D1 ;point at backRatio in grafvars
|
|
GetTrans
|
|
MOVE.L grafGlobals(A5),A0 ;point to QuickDraw globals
|
|
MOVE.L thePort(A0),A0 ;get pointer to current port
|
|
TST portBits+rowBytes(A0) ;new port?
|
|
BPL.S @default ;no, then don't access grafVars
|
|
MOVE.L grafVars(A0),D0 ;get grafVars handle from port
|
|
BEQ.S @default ;if null, return default info
|
|
MOVE.L D0,A0 ;move grafvars handle to more useful register
|
|
MOVE.L (A0),A0 ;deref it
|
|
BTST #PmNewGVBit-8,pmFlags(A0) ;check for new grafvars flag
|
|
BEQ.S @default ;if it was clear, return default info
|
|
ADD.W D1,A0 ;bump to either foreStream or backStream
|
|
MOVE.W (A0),4(SP) ;move ratio from grafvars to user variable
|
|
RTS
|
|
@default
|
|
CLR.W 4(SP) ;move default ratio to user variable
|
|
RTS
|
|
|
|
|
|
;
|
|
; On Entry:
|
|
; (on stack): grafvars handle
|
|
;
|
|
; ONLY TRASHES D0/A0
|
|
;
|
|
ResizeGrafVars
|
|
MOVE.L 4(SP),A0 ;get grafVars handle
|
|
MOVE.L (A0),A0 ;deref grafvars handle
|
|
BSET #PmNewGVBit-8,pmFlags(A0) ;check new grafvars flag and set it if not already
|
|
BNE.S @exit ;if it was set, then we are too
|
|
MOVE.L 4(SP),A0 ;get grafVars handle agian
|
|
MOVE.L #newGrafVarRec,D0 ;get size of new grafvars
|
|
BSR RSetHSize ;set the handle to be that size
|
|
MOVE.L (A0),A0 ;deref again
|
|
LEA foreStream(A0),A0 ;bump to beginning of our stuff
|
|
CLR.L (A0)+ ;clear foreStream
|
|
CLR.L (A0)+ ;clear foreRatio, half of backStream
|
|
CLR.L (A0)+ ;clear half of backStream, backRatio
|
|
CLR.W (A0)+ ;clear stream mode and filler
|
|
@exit RTD #4 ;all done
|
|
|
|
;
|
|
; On Entry:
|
|
; D1: penmode (not necessarily from the current port)
|
|
;
|
|
; On Exit:
|
|
; D1: penmode stripped of alpha transfer bits
|
|
;
|
|
GetStreamMode
|
|
MOVE.L grafGlobals(A5),A0 ;point to QuickDraw globals
|
|
MOVE.L thePort(A0),A0 ;get pointer to current port
|
|
TST portBits+rowBytes(A0) ;new port?
|
|
BPL.S @exit ;no, then don't access grafVars
|
|
MOVE.L grafVars(A0),D0 ;get grafVars handle from port
|
|
BEQ.S @exit ;if null, exit
|
|
MOVE.L D0,-(SP) ;save copy of grafvars handle
|
|
MOVE.L D0,-(SP) ;put grafVars handle on stack
|
|
_ResizeGrafVars ;make sure grafvars are big enough
|
|
MOVE.L (SP)+,A0 ;get grafVars handle off stack
|
|
MOVE.L (A0),A0 ;dereference it
|
|
MOVE.W D1,D0 ;make copy of penmode
|
|
LSR.W #8,D0 ;right align alpha bits
|
|
AND.W #3,D0 ;mask off all but alpha bits
|
|
MOVE.B D0,streamMode(A0) ;put alphamode into streamMode
|
|
@exit AND.W #$FCFF,D1 ;remove alpha bits from penmode
|
|
RTS ;return stripped penmode
|
|
|
|
|
|
;
|
|
; On Entry:
|
|
; (on stack): pointer to streamID and ratio
|
|
; (on stack): pointer to where to put
|
|
; alphamask (long) and alphacolor (long)
|
|
;
|
|
StreamToMask PROC EXPORT
|
|
MOVE.L 8(SP),A0 ;get pointer to streamID/ratio
|
|
MOVE.L 4(SP),A1 ;get pointer to result destination
|
|
MOVE.W 4(A0),D0 ;get ratio
|
|
TST.L (A0) ;check if stream is graphics (zero)
|
|
BEQ.S @1 ;yes, skip
|
|
NOT.W D0 ;no, reverse context of transparency
|
|
@1: MOVE.W D0,D1
|
|
SWAP D0
|
|
MOVE.W D1,D0
|
|
MOVE.L THEGDEVICE,A0 ;get handle of current gdevice
|
|
MOVE.L (A0),A0 ;deref it
|
|
MOVE.L gdPMap(A0),A0 ;get handle of gdevice's pixmap
|
|
MOVE.L (A0),A0 ;deref it
|
|
MOVE.W pmPixelSize(A0),D1 ;get its pixel size
|
|
CMP #16,D1 ;is it 16-bits per pixel?
|
|
BEQ.S @16bits
|
|
MOVE.L MaskBC,D1 ;get 32-bits per pixel not mask
|
|
BRA.S @2
|
|
@16bits MOVE.L #$7FFF7FFF,D1 ;get 16-bits per pixel not mask
|
|
@2: NOT.L D1 ;reverse the mask
|
|
AND.L D1,D0 ;mask alpha color
|
|
MOVE.L D1,(A1)+ ;save alphamask
|
|
MOVE.L D0,(A1)+ ;save alphacolor
|
|
RTD #8
|
|
|
|
|
|
; ; <SM4>.start
|
|
; FUNCTION SetForeAlpha(type: LONG; value: INTEGER) : OSErr
|
|
;
|
|
; On Entry:
|
|
; (on stack): return address
|
|
; (on stack): unsigned short alpha value
|
|
; (on stack): long alpha type
|
|
; (on stack): OSErr result
|
|
;
|
|
; On Exit:
|
|
; (on stack}: OSErr result
|
|
|
|
SetForeAlpha PROC EXPORT
|
|
|
|
alpha EQU 4 ;[unsigned word] alpha value
|
|
type EQU alpha+2 ;[long] alpha type
|
|
error EQU type+4 ;[word] OSErr result
|
|
paramSize EQU type ;size of parameters
|
|
|
|
clr.w error(sp) ;clear error result
|
|
move.w alpha(sp),-(sp) ;push alpha value
|
|
_SetForeTransparency ;set the foreground transparency
|
|
RTD #paramSize
|
|
|
|
|
|
;
|
|
; FUNCTION SetBackAlpha(type: LONG; value: INTEGER) : OSErr
|
|
;
|
|
; On Entry:
|
|
; (on stack): return address
|
|
; (on stack): unsigned short alpha value
|
|
; (on stack): long alpha type
|
|
; (on stack): OSErr result
|
|
;
|
|
; On Exit:
|
|
; (on stack}: OSErr result
|
|
|
|
SetBackAlpha PROC EXPORT
|
|
|
|
alpha EQU 4 ;[unsigned word] alpha value
|
|
type EQU alpha+2 ;[long] alpha type
|
|
error EQU type+4 ;[word] OSErr result
|
|
paramSize EQU type ;size of parameters
|
|
|
|
clr.w error(sp) ;clear error result
|
|
move.w alpha(sp),-(sp) ;push alpha value
|
|
_SetBackTransparency ;set the background transparency
|
|
RTD #paramSize
|
|
|
|
|
|
|
|
;
|
|
; FUNCTION GetForeAlpha(VAR type: LONG; VAR value: INTEGER) : OSErr
|
|
;
|
|
; On Entry:
|
|
; (on stack): return address
|
|
; (on stack): long *alpha
|
|
; (on stack): long *type
|
|
; (on stack): OSErr result
|
|
;
|
|
; On Exit:
|
|
; (on stack}: OSErr result
|
|
|
|
GetForeAlpha PROC EXPORT
|
|
|
|
alpha EQU 4 ;[long] alpha value
|
|
type EQU alpha+4 ;[long] alpha type
|
|
error EQU type+4 ;[word] OSErr result
|
|
paramSize EQU type ;size of parameters
|
|
|
|
clr.w error(sp) ;clear error result
|
|
subq #2,sp ;room for short result
|
|
_GetForeTransparency ;get the foreground transparency
|
|
move.w (sp)+,d0 ;get alpha result
|
|
move.l alpha(sp),a0 ;get alpha var
|
|
move.w d0,(a0) ;write alpha
|
|
move.l type(sp),a0 ;get type var
|
|
move.l #'vido',(a0) ;write type
|
|
RTD #paramSize
|
|
|
|
|
|
;
|
|
; FUNCTION GetBackAlpha(VAR type: LONG; VAR value: INTEGER) : OSErr
|
|
;
|
|
; On Entry:
|
|
; (on stack): return address
|
|
; (on stack): long *alpha
|
|
; (on stack): long *type
|
|
; (on stack): OSErr result
|
|
;
|
|
; On Exit:
|
|
; (on stack}: OSErr result
|
|
|
|
GetBackAlpha PROC EXPORT
|
|
|
|
alpha EQU 4 ;[long] alpha value
|
|
type EQU alpha+4 ;[long] alpha type
|
|
error EQU type+4 ;[word] OSErr result
|
|
paramSize EQU type ;size of parameters
|
|
|
|
clr.w error(sp) ;clear error result
|
|
subq #2,sp ;room for short result
|
|
_GetBackTransparency ;get the background transparency
|
|
move.w (sp)+,d0 ;get alpha result
|
|
move.l alpha(sp),a0 ;get alpha var
|
|
move.w d0,(a0) ;write alpha
|
|
move.l type(sp),a0 ;get type var
|
|
move.l #'vido',(a0) ;write type
|
|
RTD #paramSize
|
|
|
|
|
|
|
|
;
|
|
; FUNCTION GetForeAlphaMask(grafVars: Handle,mask^: LONG) : OSErr
|
|
;
|
|
; On Entry:
|
|
; (on stack): return address
|
|
; (on stack): long mask ptr
|
|
; (on stack): long grafVars Handle
|
|
; (on stack): OSErr result
|
|
;
|
|
; On Exit:
|
|
; (on stack}: OSErr result
|
|
;
|
|
; Note:
|
|
; We assume that the GrafVars are expanded
|
|
;
|
|
|
|
GetForeAlphaMask PROC EXPORT
|
|
|
|
alphaMask EQU 4 ;[long] grafVars handle
|
|
GrafVarsH EQU alphaMask+4 ;[long] grafVars handle <SM5>
|
|
error EQU grafVars+4 ;[word] OSErr result
|
|
paramSize EQU grafVars ;size of parameters
|
|
|
|
clr.w error(sp) ;clear error
|
|
move.l ([GrafVarsH,sp]),a0 ;get ptr to GrafVars
|
|
pea foreStream(a0) ;push pointer to foreground stream and ratio
|
|
move.l alphaMask+4(sp),-(sp) ;push ptr to stream and mask
|
|
_StreamToMask
|
|
RTD #paramSize
|
|
|
|
|
|
|
|
;
|
|
; FUNCTION GetBackAlphaMask(grafVars: Handle,mask^: LONG) : OSErr
|
|
;
|
|
; On Entry:
|
|
; (on stack): return address
|
|
; (on stack): long mask ptr
|
|
; (on stack): long grafVars Handle
|
|
; (on stack): OSErr result
|
|
;
|
|
; On Exit:
|
|
; (on stack}: OSErr result
|
|
;
|
|
; Note:
|
|
; We assume that the GrafVars are expanded
|
|
;
|
|
|
|
GetBackAlphaMask PROC EXPORT
|
|
|
|
alphaMask EQU 4 ;[long] grafVars handle
|
|
GrafVarsH EQU alphaMask+4 ;[long] grafVars handle <SM5>
|
|
error EQU grafVars+4 ;[word] OSErr result
|
|
paramSize EQU grafVars ;size of parameters
|
|
|
|
clr.w error(sp) ;clear error
|
|
move.l ([GrafVarsH,sp]),a0 ;get ptr to GrafVars
|
|
pea backStream(a0) ;push pointer to background stream and ratio
|
|
move.l alphaMask+4(sp),-(sp) ;push ptr to stream and mask
|
|
_StreamToMask
|
|
RTD #paramSize ; <SM4>.end
|
|
|
|
|
|
GetCPixel FUNC EXPORT
|
|
EXPORT GETPIXEL
|
|
IMPORT HideCursor,ShowCursor,PortToMap
|
|
;---------------------------------------------------------
|
|
;
|
|
; FUNCTION GetPixel(h,v: INTEGER): BOOLEAN;
|
|
; PROCEDURE GetCPixel(h,v: INTEGER; myColor: RGBColor);
|
|
;
|
|
; Returns TRUE if the pixel at (h,v) is set to black.
|
|
; h and v are in local coords of the current grafport.
|
|
;
|
|
; WATCH OUT FOR STACK TRICKERY WHEN GETCPIXEL CALLS GETPIXEL!!
|
|
;
|
|
; CLOBBERS A0,A1,D0,D1,D2
|
|
;
|
|
; reflect the patch from QDciPatchROM.a so that SwapMMUMode is called <sm 6/9/92>stb
|
|
;Êif the pixmap needs 32-bit addressing (pmVersion = 4). <sm 6/9/92>stb
|
|
|
|
PARAMSIZE EQU 4
|
|
RETURN EQU PARAMSIZE+8 ;ADDRESS OF BOOLEAN/RGBCOLOR
|
|
HLOC EQU PARAMSIZE+8-2 ;HORIZONTAL POSITION
|
|
VLOC EQU HLOC-2 ;VERTICAL POSITION
|
|
|
|
VARSIZE EQU 0 ;TOTAL SIZE OF LOCALS
|
|
|
|
MOVE.L 8(SP),-(SP) ;PUSH H,V
|
|
MOVEQ #1,D2 ;ROUTINE = GETCPIXEL
|
|
BSR.S SHARE ;USE COMMON CODE
|
|
RTD #8 ;STRIP PARAMS AND RETURN
|
|
|
|
GETPIXEL
|
|
MOVEQ #0,D2 ;ROUTINE = GETPIXEL
|
|
|
|
SHARE LINK A6,#VARSIZE ;ALLOCATE STACKFRAME
|
|
MOVEM.L D4-D6/A2-A3,-(SP) ;SAVE WORK REGISTERS
|
|
MOVE.L THEGDEVICE,-(SP) ;SAVE CURRENT GRAFDEVICE
|
|
MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS
|
|
MOVE.L THEPORT(A0),A0 ;GET THEPORT
|
|
_PORTTOMAP ;GET BIT/PIXMAP IN A0
|
|
|
|
; GET GLOBAL COORDINATES OF VLOC INTO D4 AND HLOC INTO D5
|
|
|
|
OLDRB MOVE VLOC(A6),D4 ;GET VERTICAL
|
|
SUB BOUNDS+TOP(A0),D4 ;CONVERT TO GLOBAL COORDS
|
|
MOVE HLOC(A6),D5 ;GET HORIZ COORD
|
|
SUB BOUNDS+LEFT(A0),D5 ;CONVERT TO GLOBAL
|
|
|
|
; IS IT FROM THE SCREEN?
|
|
|
|
MOVE.L MAINDEVICE,A2 ;GET MAIN DEVICE
|
|
MOVE.L (A2),A2 ;POINT TO IT
|
|
MOVE.L GDPMAP(A2),A2 ;GET PIXMAP HANDLE
|
|
MOVE.L (A2),A2 ;POINT TO PIXMAP
|
|
MOVE.L BASEADDR(A0),D1 ;GET PORT'S BASEADDR
|
|
CMP.L BASEADDR(A2),D1 ;SAME AS SCREEN'S?
|
|
seq.b -(sp) ;push crsrFlag @@@@ BAL 14Apr88
|
|
move.l a0,a3 ;save pixmap in a3
|
|
BNE.S NOTSCRN ;=>NO, NOT SCREEN
|
|
|
|
; IT IS FROM THE SCREEN! Shield the Cursor. @@@@ BAL 14Apr88
|
|
|
|
MOVE D5,-(SP) ;PUSH GLOBAL LEFT
|
|
MOVE D4,-(SP) ;PUSH GLOBAL TOP
|
|
MOVE D5,-(SP) ;PUSH GLOBAL RIGHT
|
|
MOVE D4,-(SP) ;PUSH GLOBAL BOTTOM
|
|
|
|
MOVE.L SP,A0
|
|
CLR.L -(SP)
|
|
MOVE.L A0,-(SP)
|
|
CLR.L -(SP)
|
|
MOVE.L #$80000,D0
|
|
DC.W $ABE0 ;_QDExtensions2
|
|
MOVE.L (SP)+,D6
|
|
ADDQ #8,SP
|
|
|
|
MOVE.L DEVICELIST,A3 ;GET FIRST IN DEVICE LIST
|
|
|
|
DONXT MOVE.L (A3),A2 ;POINT TO DEVICE
|
|
TST GDFLAGS(A2) ;IS DEVICE ACTIVE?
|
|
BPL.S NXTDEV ;=>NO, NOT ACTIVE
|
|
LEA GDRECT(A2),A1 ;POINT TO DEVICE'S RECT
|
|
CMP (A1)+,D4 ;IS VERTICAL < GDRECT.TOP ? <SMC 18SEP90> <11>
|
|
BLT.S NXTDEV ;=>YES, CHECK NEXT DEVICE <SMC 18SEP90> <11>
|
|
CMP (A1)+,D5 ;IS HORIZONTAL < GDRECT.LEFT ? <SMC 18SEP90> <11>
|
|
BLT.S NXTDEV ;=>YES, CHECK NEXT DEVICE <SMC 18SEP90> <11>
|
|
CMP (A1)+,D4 ;IS VERTICAL >= GDRECT.BOTTOM ?
|
|
BGE.S NXTDEV ;=>YES, CHECK NEXT DEVICE
|
|
CMP (A1)+,D5 ;IS HORIZONTAL >= GDRECT.RIGHT ?
|
|
BLT.S GOTDEV ;=>NO, FOUND DEVICE
|
|
|
|
NXTDEV MOVE.L GDNEXTGD(A2),D0 ;GET HANDLE TO NEXT DEVICE
|
|
MOVE.L D0,A3 ;KEEP IN A3
|
|
BNE.S DONXT ;=>THERE IS A DEVICE
|
|
BRA DONE ;=>DEVICE NOT FOUND, JUST RETURN
|
|
|
|
; FOUND THE DEVICE! SET DEVICE AND OFFSET POINT TO DEVICE LOCAL COORDINATES
|
|
|
|
GOTDEV MOVE.L A3,THEGDEVICE ;MAKE DEVICE CURRENT
|
|
LEA GDRECT(A2),A1 ;POINT TO DEVICE'S RECT
|
|
SUB (A1)+,D4 ;OFFSET VERTICAL
|
|
SUB (A1)+,D5 ;OFFSET HORIZONTAL
|
|
MOVE.L GDPMAP(A2),A3 ;GET PIXMAP HANDLE
|
|
MOVE.L (A3),d0 ;POINT TO PIXMAP
|
|
_rTranslate24To32 ;strip off high byte @@@@ BAL 14Apr88
|
|
move.l d0,a3
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
; Switch to 32 bit addressing mode
|
|
;
|
|
Needs32BitMode
|
|
move.b #$ff,(sp) ;flag the fact that MMU mode must be swapped <KON 20JUN90>
|
|
moveq #true32b,d0 ;switch to 32 bit addressing
|
|
move.w d2,-(sp) ;save color/ bw flag across call
|
|
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a2, d0/d2)
|
|
move.w (sp)+,d2 ;restore flag in d2
|
|
;save previous state in d0 for later
|
|
bra.s MMUModeOK
|
|
|
|
NOTSCRN
|
|
;
|
|
; Check if pixmap needs 32-bit addressing <KON 20JUN90>
|
|
;
|
|
baseAddr32Bit EQU 2
|
|
|
|
tst.w rowbytes(a3) ; <KON 20JUN90>
|
|
bpl.s MMUModeOK ;it's a bitmap <KON 20JUN90>
|
|
btst #baseAddr32Bit,pmVersion+1(a3) ; <KON 20JUN90>
|
|
bne.s Needs32BitMode ;pixmap needs 32-bit addressing <KON 20JUN90>
|
|
|
|
MMUModeOK
|
|
MOVE ROWBYTES(A3),D1 ;GET ROWBYTES
|
|
AND #nuRBMask,D1 ;AND MASK OFF FLAG BITS
|
|
MULU D4,D1 ;CALC VERT * ROWBYTES
|
|
MOVE.L BASEADDR(A3),A1 ;GET BASEADDR
|
|
ADD.L D1,A1 ;ADD VERTICAL OFFSET
|
|
MOVEQ #1,D1 ;ASSUME PIXELSIZE = 1
|
|
TST ROWBYTES(A3) ;NEW PIXMAP?
|
|
BPL.S OLDMAP ;=>NO, USE PIXSIZE = 1
|
|
MOVE PIXELSIZE(A3),D1 ;ELSE GET TRUE PIXELSIZE
|
|
OLDMAP MULU D1,D5 ;PIXEL OFFSET = PIXELSIZE*HLOC
|
|
BFEXTU (A1){D5:D1},D4 ;EXTRACT THE PIXEL
|
|
|
|
tst.b (sp)
|
|
beq.s @noSwap ;need to swap modes again?
|
|
;previous MMU state still in d0
|
|
move.l d2,d5 ;protect flag in d5
|
|
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a2, d0/d2)
|
|
move.l d5,d2 ;restore flag
|
|
|
|
@noSwap TST D2 ;COLOR OR NOT?
|
|
BEQ.S NOCOLOR ;=>NO COLOR
|
|
MOVE.L D4,-(SP) ;PUSH INDEX
|
|
MOVE.L RETURN+4(A6),-(SP) ;POINT TO RGBCOLOR
|
|
_INDEX2COLOR ;CONVERT THE INDEX TO A COLOR
|
|
BRA.S DONE ;=>RESTORE CURSOR AND RETURN
|
|
|
|
NOCOLOR cmp.w #16,pixelType(a3) ;direct device?
|
|
bne.s @clut ;no, don't hack pixel value
|
|
tst.l d4 ;is it all zeros?
|
|
seq d4 ;yes, flag black
|
|
bra.s @ret
|
|
|
|
@clut TST D4 ;ELSE TEST PIXEL
|
|
SNE D4 ;SET BOOLEAN RESULT
|
|
@ret NEG D4 ;MAKE $FF --> $01
|
|
MOVE.B D4,RETURN(A6) ;AND RETURN IT
|
|
|
|
DONE tst.b (sp)+ ;pop and check crsrFlag
|
|
beq.s @noShow ;need to show cursor?
|
|
move.l D6,-(SP)
|
|
move.l #$40001,D0
|
|
dc.w $ABE0 ;_QDExtensions2
|
|
@noShow MOVE.L (SP)+,THEGDEVICE ;RESTORE CURRENT GRAFDEVICE
|
|
MOVEM.L (SP)+,D4-D6/A2-A3 ;RESTORE WORK REGISTERS
|
|
UNLINK PARAMSIZE,'GETCPIXEL'
|
|
|
|
|
|
|
|
|
|
Translate24To32 PROC EXPORT ;BAL 26Dec88
|
|
IF forROM THEN ; SuperMario is 32 bit only ROM
|
|
RTS
|
|
ELSE
|
|
;-------------------------------------------------------
|
|
;
|
|
; FUNCTION Translate24To32(Addr24:long) : Addr32;
|
|
;
|
|
; Translate a 24 Bit address to a valid 32 Bit address.
|
|
; (Will be toolbox trap $AB03)
|
|
;
|
|
; INPUT D0=Addr24;
|
|
; OUTPUT D0=Addr32;
|
|
;
|
|
; All registers preserved
|
|
;
|
|
; Translation algorithm from Mac Family Hardware Reference Table 17-1:
|
|
;
|
|
; Old first 3 nibbles New first 3 nibbles
|
|
; ------------------- -------------------
|
|
; xx0 000
|
|
; : :
|
|
; xx7 007
|
|
; xx8 400-->408 for safety in 24 bit mode; also since the emulator doesn't alias
|
|
; xx9 F90
|
|
; : :
|
|
; xxE FE0
|
|
; xxF 500
|
|
;
|
|
;
|
|
;
|
|
; NOTE: Unlike _StripAddress, this routine does not necessarily
|
|
; return an address which can also be used in 24 bit mode.
|
|
; Furthermore, Translate24To32 can not be called meaningfully
|
|
; with the result of a previous translation.
|
|
;
|
|
;
|
|
AND.L Lo3Bytes,D0 ;Clean high byte for fast exit
|
|
BCLR #23,D0 ;Is the address in RAM?
|
|
BNE.S @NotRam ;no, go patch up address
|
|
RTS ;quick exit
|
|
|
|
@NotRam
|
|
MOVE.W D1,-(SP) ;Save a work register
|
|
MOVE.W #12,D1 ;prepare for shift and clear our word, Scotty
|
|
ROL.L D1,D0 ;get 3rd nibble
|
|
MOVE.B D0,D1 ;keep for indexing
|
|
beq.s @inROM ;handle ROM case for emulator
|
|
LSR.L #4,D0 ;clear out 3rd nibble
|
|
MOVE.B (TRANSLATE,PC,D1.W),D0 ;compute new high byte
|
|
MOVE.W (SP)+,D1 ;Restore work register
|
|
ROR.L #8,D0 ;reposition high byte
|
|
RTS
|
|
|
|
@inROM
|
|
or.w #$0408,d0 ;set up ROM address
|
|
ROR.L #4,D0 ;restore address
|
|
ROR.L #8,D0 ;restore address
|
|
MOVE.W (SP)+,D1 ;Restore work register
|
|
RTS
|
|
|
|
|
|
TRANSLATE
|
|
DC.B $40,$F9,$FA,$FB,$FC,$FD,$FE,$50
|
|
ENDIF ; forROM
|
|
|
|
|
|
|
|
ElsieTranslate24To32 PROC EXPORT ;JJ&BA 2/23/90
|
|
IF forROM THEN ; SuperMario is 32 bit only ROM
|
|
RTS
|
|
ELSE
|
|
;-----------------------------------------------------------------------------------------
|
|
;
|
|
; FUNCTION ElsieTranslate24To32(Addr24: long): Addr32;
|
|
;
|
|
; Translate an Elsie 24-bit address to a valid Elsie 32-bit address.
|
|
;
|
|
; INPUT D0=Addr24;
|
|
; OUTPUT D0=Addr32;
|
|
;
|
|
; All other registers preserved
|
|
;
|
|
; Translation algorithm from Elsie Hardware ERS:
|
|
;
|
|
; High 3 nibbles (24) High 3 nibbles (32)
|
|
; ------------------- -------------------
|
|
; xx0 000 (RAM)
|
|
; : : :
|
|
; xx9 009 (RAM)
|
|
; -------------------------------------------
|
|
; xxA 40A (ROM)
|
|
; : : :
|
|
; xxD 40D (ROM)
|
|
; -------------------------------------------
|
|
; xxE FE0 (Direct Slot)
|
|
; xxF 50F (I/O Space)
|
|
;
|
|
; NOTE: Unlike _StripAddress, this routine does not necessarily
|
|
; return an address which can also be used in 24 bit mode.
|
|
; Furthermore, Translate24To32 can not be called meaningfully
|
|
; with the result of a previous translation.
|
|
;
|
|
|
|
AND.L Lo3Bytes,D0 ;Clean high byte for fast exit
|
|
BCLR #23,D0 ;Is the address in lower 8 MB of RAM?
|
|
BNE.S @LOOKUP ;no, go patch up address
|
|
RTS ;quick exit
|
|
@LOOKUP MOVE.W D1,-(SP) ;save a work register
|
|
SWAP D0 ;get relevant nibbles into low word
|
|
MOVE.W D0,D1 ;...and into index register
|
|
LSR.W #4,D1 ;move nibble 3 to use as index
|
|
ADD.W (@TABLE,PC,D1.W*2),D0 ;translate by adding table value
|
|
SWAP D0 ;move translated nibbles back to high word
|
|
MOVE.W (SP)+,D1 ;restore work register
|
|
RTS
|
|
|
|
@TABLE DC.W $0080,$0080,$4080,$4080,$4080,$4080,$FDA0,$5080
|
|
ENDIF ; forROM
|
|
|
|
StuffHex PROC EXPORT
|
|
;-------------------------------------------------------
|
|
;
|
|
; PROCEDURE STUFFHEX(THINGPTR: WORDPTR; S: STR255);
|
|
;
|
|
; CONVENIENCE ROUTINE TO STUFF HEX INTO ANY VARIABLE.
|
|
; BEWARE, NO RANGE-CHECKING.
|
|
;
|
|
MOVE.L 4(SP),A0 ;A0:=ADDR OF STRING
|
|
MOVE.L 8(SP),A1 ;A1:=THINGPTR
|
|
MOVE.L (SP),8(SP) ;CLEAN OFF STACK
|
|
ADD #8,SP ;POINT TO RETURN ADDR
|
|
MOVE.B (A0)+,D2 ;GET STRING LENGTH
|
|
AND #$00FE,D2 ;TRUNCATE LENGTH TO EVEN
|
|
BEQ.S ENDHEX ;QUIT IF LENGTH = 0
|
|
HEXLOOP BSR.S NEXTHEX ;GET HEX DIGIT AND CONVERT TO BINARY
|
|
MOVE.B D0,D1 ;SAVE MOST SIG DIGIT
|
|
BSR.S NEXTHEX ;GET HEX DIGIT AND CONVERT TO BINARY
|
|
LSL.B #4,D1 ;SHIFT MOST SIG INTO PLACE
|
|
ADD.B D0,D1 ;FILL IN LS NIBBLE
|
|
MOVE.B D1,(A1)+ ;STUFF BYTE INTO THING
|
|
SUB #2,D2 ;2 LESS CHARS TO GO
|
|
BNE.S HEXLOOP ;LOOP FOR STRING LENGTH
|
|
ENDHEX RTS ;RETURN TO PASCAL
|
|
;
|
|
; LOCAL ROUTINE TO GET NEXT HEX DIGIT AND CONVERT ASCII TO BINARY
|
|
;
|
|
NEXTHEX MOVE.B (A0)+,D0 ;GET HEX DIGIT FROM STRING
|
|
CMP.B #$39,D0 ;IS IT GTR THAN '9' ?
|
|
BLE.S SMALL ;NO, DO IT
|
|
ADD.B #9,D0 ;YES, ADD CORRECTION
|
|
SMALL AND.B #$F,D0 ;TREAT MOD 16, EVEN LOWER CASE OK
|
|
RTS
|
|
|
|
|
|
XorSlab PROC EXPORT
|
|
;-----------------------------------------------------------
|
|
;
|
|
; LOCAL PROCEDURE XorSlab(bufAddr: Ptr; left,right: INTEGER);
|
|
;
|
|
; Enter with:
|
|
;
|
|
; A0: bufAddr
|
|
; D0: pixelShift
|
|
; D3: left coord
|
|
; D4: right coord
|
|
;
|
|
; Clobbers: A0,D0,D1,D3,D4,D5,D6
|
|
;
|
|
|
|
; Calc bitcount. If <= 32 then use single BFCHG
|
|
|
|
ext.l d4 ; clear out high word
|
|
ext.l d3 ; ditto
|
|
LSL.l D0,D4 ; convert left pixel to left bit
|
|
LSL.l D0,D3 ; convert right pixel to right bit
|
|
MOVE.l D4,D0 ; get right edge
|
|
SUB.l D3,D0 ; get bitcount (right-left)
|
|
BLE.S DONE ; => none to do
|
|
CMP.l #32,D0 ; BFCHG can only do 32 bits
|
|
BGT.S NOTIN1 ; => slab > 32 bits
|
|
BFCHG (A0){D3:D0} ; XOR from left to right
|
|
DONE RTS ; and return
|
|
|
|
; calc left field, right field, and number of longs in middle
|
|
|
|
NOTIN1 MOVEQ #$1F,D1 ; get useful value
|
|
MOVE D3,D0 ; get a copy of left edge
|
|
AND D1,D0 ; get left edge mod 32
|
|
MOVEQ #-1,D5 ; fill leftmask with ones
|
|
LSR.L D0,D5 ; D5 = LEFTMASK
|
|
|
|
MOVE D4,D0 ; get a copy of right edge
|
|
AND D1,D0 ; get right edge mod 32
|
|
MOVEQ #-1,D6 ; fill rightmask with ones
|
|
LSR.L D0,D6 ; shift in 0's from left
|
|
NOT.L D6 ; D6 = RIGHTMASK
|
|
|
|
ASR.l #5,D3 ; convert left dots to longs
|
|
ASR.l #5,D4 ; convert right dots to longs
|
|
SUB D3,D4 ; LONGCOUNT = rightlong-leftlong
|
|
SUBQ #1,D4 ; get longcount-1 for DBRA
|
|
|
|
LSL #2,D3 ; convert left to bytes
|
|
ADD D3,A0 ; add to bufAddr
|
|
|
|
; do the left, the middle, then the right part of the slab
|
|
|
|
EOR.L D5,(A0)+ ; XOR the left part of the slab
|
|
BRA.S TEST ; see if there is a middle one
|
|
NXTLONG NOT.L (A0)+ ; do a middle long
|
|
TEST DBRA D4,NXTLONG ; any longs left?
|
|
EOR.L D6,(A0) ; XOR the right part of the slab
|
|
RTS
|
|
|
|
|
|
|
|
DrawSlab PROC EXPORT
|
|
EXPORT SlabMode,FastSlabMode
|
|
EXPORT slMASK8,slMASK9,slMASK10,slMASK11,slXMASK8,slXMASK9,slXMASK10,slXMASK11
|
|
EXPORT slAvg,slAddPin,slAddOver,slSubPin,slTransparent,slMax,slSubOver,slMin,slHilite
|
|
EXPORT slArith16Tab,slArith32Tab
|
|
|
|
;--------------------------------------------------------------
|
|
;
|
|
; LOCAL PROCEDURE DRAWSLAB
|
|
;
|
|
; INPUTS:
|
|
;
|
|
; D0: shift/scratch A0:
|
|
; D1: left A1: DSTLEFT, clobbered
|
|
; D2: right A2: RGNBUFFER, clobbered
|
|
; D3: scratch A3: MINRECT
|
|
; D4: FGCOLOR A4: MODECASE
|
|
; D5: BKCOLOR A5:
|
|
; D6: PATTERN A6: SHARED STACKFRAME
|
|
; D7: A7: stack
|
|
;
|
|
; CLOBBERS: D0-D3,A0,A1,A2
|
|
;
|
|
; CLIP LEFT AND RIGHT TO MINRECT:
|
|
;
|
|
; CALLED BY DRAWARC AND DRAWLINE
|
|
;
|
|
; HERE ARE THE SHARED LOCALS FOR THOSE ROUTINES:
|
|
;--------------------------------------------------------------
|
|
|
|
&CurFile SETC 'DRAWSLAB'
|
|
|
|
INCLUDE 'DrawingVars.a'
|
|
|
|
|
|
;--------------------------------------------------------------
|
|
|
|
CMP LEFT(A3),D1 ;IS LEFT < MINRECT.LEFT ?
|
|
BGE.S LEFTOK ;NO, CONTINUE
|
|
MOVE LEFT(A3),D1 ;YES, LEFT := MINRECT.LEFT
|
|
LEFTOK CMP RIGHT(A3),D2 ;IS RIGHT > MINRECT.RIGHT ?
|
|
BLE.S RIGHTOK ;NO, CONTINUE
|
|
MOVE RIGHT(A3),D2 ;YES, RIGHT := MINRECT.RIGHT
|
|
RIGHTOK CMP D2,D1 ;IS LEFT >= RIGHT ?
|
|
BGE.S DONESLAB ;YES, QUIT
|
|
|
|
; GOT LEFT AND RIGHT, CONVERT PIXELS TO BITS
|
|
|
|
ext.l d1 ;compute result in a long <BAL 15Sep88>
|
|
ext.l d2 ;compute result in a long <BAL 15Sep88>
|
|
|
|
LSL.l D0,D1 ;CONVERT LEFT PIXELS TO BITS
|
|
move.l d1,slabLeft(a6) ;copy for below, arith setup <BAL 17Jan89>
|
|
LSL.l D0,D2 ;CONVERT RIGHT PIXELS TO BITS
|
|
|
|
; SET UP LEFTMASK AND RIGHTMASK
|
|
|
|
MOVEQ #$1F,D0 ;NEED RIGHT MOD 32
|
|
AND D0,D1 ;GET LEFT MOD 32
|
|
MOVEQ #-1,D3 ;GET ONES INTO D3
|
|
LSR.L D1,D3 ;GET LEFTMASK IN D3
|
|
|
|
AND D2,D0 ;GET RIGHT MOD 32
|
|
MOVEQ #-1,D1 ;GET ONES INTO D1
|
|
LSR.L D0,D1 ;GET LEFTMASK IN D1
|
|
NOT.L D1 ;TURN INTO A RIGHTMASK
|
|
|
|
MOVE.l slabLeft(a6),D0 ;GET LEFT IN D0 <BAL 15Sep88>
|
|
;
|
|
; CALC WORDCOUNT, DSTPTR, MASKPTR, AND TAKE CASE JUMP
|
|
;
|
|
ASR.l #5,D2 ;CONVERT RIGHT TO LONGS <BAL 15Sep88>
|
|
ASR.l #5,D0 ;CONVERT LEFT TO LONGS <BAL 15Sep88>
|
|
SUB D0,D2 ;CALC LONG COUNT
|
|
ADD D0,D0 ;DOUBLE FOR WORDS
|
|
ADD D0,D0 ;QUAD FOR BYTES
|
|
ADD D0,A1 ;OFFSET DSTPTR
|
|
ADD D0,A2 ;OFFSET MASKPTR
|
|
;D0 USED BY BIG PATTERN ROUTINES
|
|
TST D2 ;SET Z-FLAG BASED ON WORDCOUNT
|
|
JMP (A4) ;TAKE MODECASE TO DRAW SLAB
|
|
DONESLAB RTS
|
|
|
|
|
|
|
|
|
|
;---------------------------------------------------------
|
|
;
|
|
; INTERFACE TO EACH SCAN LINE ROUTINE:
|
|
;
|
|
; ENTER WITH Z-FLAG SET IF ALL IN ONE LONG
|
|
;
|
|
; INPUTS: A1: DSTPTR
|
|
; A2: MASKPTR
|
|
; D1: RIGHTMASK
|
|
; D2: LONGCNT
|
|
; D3: LEFTMASK
|
|
; D4: FGCOLOR
|
|
; D5: BKCOLOR
|
|
; D6: PATTERN
|
|
;
|
|
; CLOBBERS: D0,D3,D2,A1,A2
|
|
; A3,D6 (BUT NOT IN FASTSLAB)
|
|
;
|
|
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 8 OR 12: PATTERN --> DST
|
|
;
|
|
; Slab copy using alpha mask <17>
|
|
;
|
|
; This exact code is in QDciROMPatches.a
|
|
|
|
slMASK8A
|
|
MOVE.L alphaMask(A6),D0 ;get alpha mask
|
|
AND.L D0,D1 ;clip left mask with alpha mask
|
|
AND.L D0,D3 ;clip right mask with alpha mask
|
|
MOVE.L D0,A0 ;save copy of alpha mask
|
|
TST D2 ;re-test long count
|
|
BRA.S DO8A
|
|
END8A AND.L D1,D3 ;COMBINE RIGHT AND LEFT MASK
|
|
NEXT8A MOVE.L D6,D0 ;GET PATTERN DATA
|
|
AND.L (A2)+,D3 ;MERGE MASK AND CLIPRGN MASK
|
|
AND.L D3,D0 ;MASK PATTERN DATA
|
|
NOT.L D3 ;MAKE NOTMASK
|
|
AND.L (A1),D3 ;AND NOTMASK WITH OLD DST
|
|
OR.L D0,D3 ;FILL HOLE WITH PATTERN
|
|
MOVE.L D3,(A1)+ ;UPDATE DST
|
|
MOVE.L A0,D3 ;FLUSH MASK to alpha mask
|
|
SUB #1,D2 ;DEC LONG COUNT
|
|
DO8A BGT NEXT8A ;LOOP FOR ALL LONGS IN ROW
|
|
BEQ END8A ;DO LAST LONG WITH MASK
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 8 OR 12: BIG PATTERN --> DST
|
|
;
|
|
; Slab copy using alpha mask <17>
|
|
;
|
|
slXMASK8A
|
|
MOVE D7,-(SP) ;SAVE WORK REGISTER
|
|
MOVE PATHMASK(A6),D7 ;GET HORIZ MASK
|
|
MOVE D0,D6 ;GET LEFT AS INDEX INTO PATTERN
|
|
ADD PATHPOS(A6),D6 ;GET OFFSET FROM PATTERN BASE
|
|
AND D7,D6 ;MASK INDEX INTO PATTERN
|
|
MOVE.L EXPAT(A6),A3 ;GET PATTERN POINTER
|
|
ADD.L PATVPOS(A6),A3 ;ADD VERT OFFSET INTO PATTERN <BAL 22Jan89>
|
|
MOVE.L alphaMask(A6),D0 ;get alpha mask
|
|
AND.L D0,D1 ;clip left mask with alpha mask
|
|
AND.L D0,D3 ;clip right mask with alpha mask
|
|
MOVE.L D0,A0 ;save copy of alpha mask
|
|
TST D2 ;re-test long count
|
|
BRA.S XDO8A
|
|
|
|
XEND8A AND.L D1,D3 ;COMBINE RIGHT AND LEFT MASK
|
|
XNEXT8A MOVE.L 0(A3,D6),D0 ;GET PATTERN DATA
|
|
ADDQ #4,D6 ;BUMP PATTERN INDEX
|
|
AND D7,D6 ;MASK INDEX INTO PATTERN
|
|
AND.L (A2)+,D3 ;MERGE MASK AND CLIPRGN MASK
|
|
AND.L D3,D0 ;MASK PATTERN DATA
|
|
NOT.L D3 ;MAKE NOTMASK
|
|
AND.L (A1),D3 ;AND NOTMASK WITH OLD DST
|
|
OR.L D0,D3 ;FILL HOLE WITH PATTERN
|
|
MOVE.L D3,(A1)+ ;UPDATE DST
|
|
MOVE.L A0,D3 ;FLUSH MASK to alpha mask
|
|
SUB #1,D2 ;DEC LONG COUNT
|
|
XDO8A BGT XNEXT8A ;LOOP FOR ALL LONGS IN ROW
|
|
BEQ XEND8A ;DO LAST LONG WITH MASK
|
|
MOVE (SP)+,D7 ;RESTORE WORK REGISTER
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
if 0 then
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 8 OR 12: PATTERN --> DST
|
|
;
|
|
END8 AND.L D1,D3 ;COMBINE RIGHT AND LEFT MASK
|
|
NEXT8 MOVE.L D6,D0 ;GET PATTERN DATA
|
|
AND.L (A2)+,D3 ;MERGE MASK AND CLIPRGN MASK
|
|
AND.L D3,D0 ;MASK PATTERN DATA
|
|
NOT.L D3 ;MAKE NOTMASK
|
|
AND.L (A1),D3 ;AND NOTMASK WITH OLD DST
|
|
OR.L D0,D3 ;FILL HOLE WITH PATTERN
|
|
MOVE.L D3,(A1)+ ;UPDATE DST
|
|
MOVEQ #-1,D3 ;FLUSH MASK
|
|
SUB #1,D2 ;DEC LONG COUNT
|
|
slMASK8 BGT NEXT8 ;LOOP FOR ALL LONGS IN ROW
|
|
BEQ END8 ;DO LAST LONG WITH MASK
|
|
RTS
|
|
|
|
endif
|
|
|
|
;******************************************************************************************
|
|
; QuickerDraw
|
|
; Scan line handler for clipped pattern fill copy mode (called by oval, rrect) -- trap $380
|
|
;Êjust like whatÕs in QDciPatchROM.a <sm 6/9/92>stb
|
|
|
|
FillClipScanLine
|
|
FCSL1 ; << PB452 BAL>>
|
|
FCSL2
|
|
slMASK8
|
|
|
|
AND.L (A2)+,D3 ;use left mask to start with
|
|
SUBQ #1,D2
|
|
BMI.S DoFCLast0
|
|
|
|
; special case the left edge
|
|
|
|
MOVE.L D6,D0 ;get pattern
|
|
AND.L D3,D0 ;mask it
|
|
NOT.L D3 ;flip mask
|
|
AND.L (A1),D3 ;combine with source
|
|
OR.L D3,D0 ;form dest longword
|
|
MOVE.L D0,(A1)+ ;deposit it
|
|
|
|
MOVE.L (A2)+,D3
|
|
|
|
SUBQ #1,D2
|
|
BMI.S DoFCLast0
|
|
|
|
; see if we're in the unclipped case; if so, use a faster loop
|
|
|
|
MOVE.L SEEKMASK(A6),A0 ;get seekRgn address
|
|
; CMP.W #$4E75,(A0) ;is it a RTS?
|
|
CMP.L #$343C7fff,(A0) ;is it "move.w #$7fff,d2"
|
|
BEQ.S DoFCUnclipped ;if so, handle specially
|
|
|
|
BRA.S FCNotOn1
|
|
|
|
; here's the loop -- use standard technique of special casing region masks
|
|
|
|
FCLineLoop
|
|
MOVE.L (A2)+,D3 ;fetch region mask
|
|
BEQ.S FCOff ;if all zero, can optimize
|
|
FCNotOff1
|
|
CMP.L MINUSONE,D3 ;all ones? << PB452 BAL>>
|
|
BEQ.S FCOn ;if so, optimize
|
|
FCNotOn1
|
|
MOVE.L D6,D0 ;get pattern
|
|
AND.L D3,D0 ;mask it
|
|
NOT.L D3 ;flip mask
|
|
AND.L (A1),D3 ;combine with source
|
|
OR.L D3,D0 ;form dest longword
|
|
MOVE.L D0,(A1)+ ;deposit it
|
|
|
|
DBRA D2,FCLineLoop
|
|
|
|
; handle the last one, using the mask in D1
|
|
|
|
DoFCLast
|
|
MOVE.L (A2)+,D3
|
|
DoFCLast0
|
|
AND.L D1,D3 ;use right mask
|
|
|
|
MOVE.L D6,D0 ;get pattern
|
|
AND.L D3,D0 ;mask it
|
|
NOT.L D3 ;flip mask
|
|
AND.L (A1),D3 ;combine with source
|
|
OR.L D3,D0 ;form dest longword
|
|
MOVE.L D0,(A1)+ ;deposit it
|
|
|
|
RTS
|
|
|
|
; handle the case of an all zero region mask
|
|
|
|
FCOff
|
|
ADDQ #4,A1 ;skip over it
|
|
|
|
SUBQ #1,D2
|
|
BMI.S DoFCLast
|
|
|
|
FCOffLoop
|
|
MOVE.L (A2)+,D3
|
|
BNE.S FCNotOff1
|
|
|
|
ADDQ #4,A1 ;skip it
|
|
|
|
DBRA D2,FCOffLoop
|
|
BRA.S DoFCLast
|
|
|
|
; handle the case of an all one's region mask
|
|
|
|
FCOn
|
|
MOVE.L D6,(A1)+
|
|
|
|
SUBQ #1,D2
|
|
BMI.S DoFCLast
|
|
FCOnLoop
|
|
MOVE.L (A2)+,D3
|
|
CMP.L MINUSONE,D3 ; << PB452 BAL>>
|
|
BNE.S FCNotOn1
|
|
|
|
MOVE.L D6,(A1)+
|
|
|
|
DBRA D2,FCOnLoop
|
|
BRA.S DoFCLast
|
|
|
|
; handle the unclipped case with faster unwound code
|
|
|
|
DoFCUnclipped
|
|
LEA 0(A2,D2.W*4),A2 ;bump region ptr
|
|
|
|
ADDQ #1,D2 ;compute count to do
|
|
|
|
CMP.W #8,D2
|
|
BLT.S FinishFCUnClip
|
|
|
|
MOVE.W D2,D0
|
|
LSR #3,D0 ;divide by 8
|
|
SUBQ #1,D0 ;bias for DBRA
|
|
FCUnClipLoop
|
|
MOVE.L D6,(A1)+
|
|
MOVE.L D6,(A1)+
|
|
MOVE.L D6,(A1)+
|
|
MOVE.L D6,(A1)+
|
|
MOVE.L D6,(A1)+
|
|
MOVE.L D6,(A1)+
|
|
MOVE.L D6,(A1)+
|
|
MOVE.L D6,(A1)+
|
|
|
|
DBRA D0,FCUnClipLoop
|
|
|
|
; now finish up the last 7 or less
|
|
|
|
FinishFCUnClip
|
|
AND #7,D2
|
|
EOR #7,D2
|
|
JMP FinishFCUCTab(D2.W*2)
|
|
FinishFCUCTab
|
|
MOVE.L D6,(A1)+
|
|
MOVE.L D6,(A1)+
|
|
MOVE.L D6,(A1)+
|
|
MOVE.L D6,(A1)+
|
|
MOVE.L D6,(A1)+
|
|
MOVE.L D6,(A1)+
|
|
MOVE.L D6,(A1)+
|
|
|
|
BRA.S DoFCLast
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 9 OR 13: PATTERN OR DST --> DST
|
|
;
|
|
END9 AND.L D1,D3 ;COMBINE RIGHT AND LEFT MASK
|
|
NEXT9 AND.L D6,D3 ;MASK PATTERN DATA
|
|
AND.L (A2)+,D3 ;MERGE MASK AND CLIPRGN MASK
|
|
MOVE.L D3,D0 ;COPY MASKED, CLIPPED SRC
|
|
AND.L D4,D0 ;APPLY FG COLOR TO SRC
|
|
NOT.L D3 ;GET NOT MASKED, CLIPPED SRC
|
|
AND.L (A1),D3 ;USE TO PUNCH OUT DST
|
|
OR.L D3,D0 ;COMBINE SRC AND DST
|
|
MOVE.L D0,(A1)+ ;MOVE RESULT INTO DST
|
|
MOVEQ #-1,D3 ;FLUSH MASK
|
|
SUB #1,D2 ;DEC LONG COUNT
|
|
oldslMASK9
|
|
BGT NEXT9 ;LOOP FOR ALL LONGS IN ROW
|
|
BEQ END9 ;DO LAST LONG WITH MASK
|
|
RTS
|
|
|
|
|
|
;******************************************************************************************
|
|
; QuickerDraw
|
|
; Scan line handler for clipped pattern fill OR mode (called by oval, rrect) -- trap $381
|
|
; similar to above, but in OR mode. We can only handle if the foreground pattern
|
|
; is all ones; if so, use the copy mode routine to fill.
|
|
; just like whatÕs in QDciPatchROM.a <sm 6/9/92>stb
|
|
|
|
UseOld381
|
|
TST.W D2
|
|
bra.s oldslMASK9
|
|
|
|
FillClipOrLine
|
|
slMASK9
|
|
CMP.L #-1,D6 ;all foreground?
|
|
BNE.S UseOld381 ;if not, we can't handle
|
|
|
|
MOVE.L D4,D6 ;set up fill pattern
|
|
BRA slMASK8 ;use common code
|
|
|
|
|
|
;******************************************************************************************
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 10 OR 14: PATTERN XOR DST --> DST
|
|
;
|
|
END10 AND.L D1,D3 ;COMBINE RIGHT AND LEFT MASK
|
|
NEXT10 AND.L D6,D3 ;GET PATTERN DATA
|
|
AND.L (A2)+,D3 ;MERGE MASK AND CLIPRGN MASK
|
|
EOR.L D3,(A1)+ ;XOR RESULT INTO DST
|
|
MOVEQ #-1,D3 ;FLUSH MASK
|
|
SUB #1,D2 ;DEC LONG COUNT
|
|
slMASK10
|
|
BGT NEXT10 ;LOOP FOR ALL LONGS IN ROW
|
|
BEQ END10 ;DO LAST LONG WITH MASK
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 11 OR 15: PATTERN BIC DST --> DST
|
|
;
|
|
END11 AND.L D1,D3 ;COMBINE RIGHT AND LEFT MASK
|
|
NEXT11 AND.L D6,D3 ;MASK PATTERN DATA
|
|
AND.L (A2)+,D3 ;GET MASKED, CLIPPED SRC
|
|
MOVE.L D3,D0 ;COPY MASKED, CLIPPED SRC
|
|
AND.L D5,D0 ;APPLY BK TO SRC
|
|
NOT.L D3 ;GET NOT MASKED, CLIPPED SRC
|
|
AND.L (A1),D3 ;PUNCH OUT DST DATA
|
|
OR.L D3,D0 ;COMBINE SRC AND DST
|
|
MOVE.L D0,(A1)+ ;PUT RESULT TO DST
|
|
MOVEQ #-1,D3 ;FLUSH MASK
|
|
SUB #1,D2 ;DEC LONG COUNT
|
|
slMASK11
|
|
BGT NEXT11 ;LOOP FOR ALL LONGS IN ROW
|
|
BEQ END11 ;DO LAST LONG WITH MASK
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 8 OR 12: BIG PATTERN --> DST
|
|
;
|
|
slXMASK8big
|
|
MOVE D7,-(SP) ;SAVE WORK REGISTER
|
|
MOVE PATHMASK(A6),D7 ;GET HORIZ MASK
|
|
MOVE D0,D6 ;GET LEFT AS INDEX INTO PATTERN
|
|
ADD PATHPOS(A6),D6 ;GET OFFSET FROM PATTERN BASE
|
|
AND D7,D6 ;MASK INDEX INTO PATTERN
|
|
MOVE.L EXPAT(A6),A3 ;GET PATTERN POINTER
|
|
ADD.l PATVPOS(A6),A3 ;ADD VERT OFFSET INTO PATTERN <BAL 22Jan89>
|
|
TST D2
|
|
BRA.S XDO8
|
|
|
|
XEND8 AND.L D1,D3 ;COMBINE RIGHT AND LEFT MASK
|
|
XNEXT8 MOVE.L 0(A3,D6),D0 ;GET PATTERN DATA
|
|
ADDQ #4,D6 ;BUMP PATTERN INDEX
|
|
AND D7,D6 ;MASK INDEX INTO PATTERN
|
|
AND.L (A2)+,D3 ;MERGE MASK AND CLIPRGN MASK
|
|
AND.L D3,D0 ;MASK PATTERN DATA
|
|
NOT.L D3 ;MAKE NOTMASK
|
|
AND.L (A1),D3 ;AND NOTMASK WITH OLD DST
|
|
OR.L D0,D3 ;FILL HOLE WITH PATTERN
|
|
MOVE.L D3,(A1)+ ;UPDATE DST
|
|
MOVEQ #-1,D3 ;FLUSH MASK
|
|
SUB #1,D2 ;DEC LONG COUNT
|
|
XDO8 BGT XNEXT8 ;LOOP FOR ALL LONGS IN ROW
|
|
BEQ XEND8 ;DO LAST LONG WITH MASK
|
|
MOVE (SP)+,D7 ;RESTORE WORK REGISTER
|
|
RTS
|
|
|
|
|
|
;******************************************************************************************
|
|
; QuickerDraw
|
|
; Scan line handler for clipped pattern fill copy mode (called by oval, rrect)
|
|
; for complex patterns-- trap $384
|
|
; this has fixes exactly as shown in QDciPatchROM.a <sm 6/9/92>stb
|
|
|
|
FillClipXLine
|
|
slXMASK8
|
|
|
|
CMP.W #4,PATHMASK(A6) ;pattern too complex?
|
|
BGT.S slXMASK8big ;if so, don't handle
|
|
|
|
MOVE.L D7,-(SP) ;save work register
|
|
|
|
; keep the pattern in D6 and D7
|
|
|
|
ADD.W PATHPOS(A6),D0
|
|
AND #4,D0
|
|
|
|
MOVE.L EXPAT(A6),A0
|
|
ADD.l PATVPOS(A6),A0 ; <BAL 07Nov89>
|
|
|
|
MOVE.L 0(A0,D0),D6 ;get left pattern
|
|
EOR.W #4,D0
|
|
MOVE.L 0(A0,D0),D7 ;get right pattern
|
|
|
|
; fetch the leftmost region mask
|
|
|
|
MOVEQ #-1,D4 ;all ones for comparing
|
|
AND.L (A2)+,D3 ;use left mask to start with
|
|
|
|
SUBQ #1,D2
|
|
BMI.S DoFCXLast0
|
|
|
|
; special case the left edge
|
|
|
|
MOVE.L D6,D0 ;get pattern
|
|
AND.L D3,D0 ;mask it
|
|
NOT.L D3 ;flip mask
|
|
AND.L (A1),D3 ;combine with source
|
|
OR.L D3,D0 ;form dest longword
|
|
MOVE.L D0,(A1)+ ;deposit it
|
|
|
|
EXG.L D6,D7
|
|
|
|
MOVE.L (A2)+,D3
|
|
|
|
SUBQ #1,D2
|
|
BMI.S DoFCXLast0
|
|
|
|
; see if we're in the unclipped case; if so, use a faster loop
|
|
|
|
MOVE.L SEEKMASK(A6),A0 ;get seekRgn address
|
|
; CMP.W #$4E75,(A0) ;is it a RTS?
|
|
CMP.L #$343C7fff,(A0) ;is it "move.w #$7fff,d2"
|
|
BEQ.S DoFCXUnclipped ;if so, handle specially
|
|
|
|
BRA.S FCXNotOn1
|
|
|
|
; here's the loop -- use standard technique of special casing region masks
|
|
|
|
FCXLineLoop
|
|
MOVE.L (A2)+,D3 ;fetch region mask
|
|
BEQ.S FCXOff ;if all zero, can optimize
|
|
FCXNotOff1
|
|
CMP.L D4,D3 ;all ones?
|
|
BEQ.S FCXOn ;if so, optimize
|
|
FCXNotOn1
|
|
MOVE.L D6,D0 ;get pattern
|
|
AND.L D3,D0 ;mask it
|
|
NOT.L D3 ;flip mask
|
|
AND.L (A1),D3 ;combine with source
|
|
OR.L D3,D0 ;form dest longword
|
|
MOVE.L D0,(A1)+ ;deposit it
|
|
|
|
EXG.L D6,D7
|
|
DBRA D2,FCXLineLoop
|
|
|
|
; handle the last one, using the mask in D1
|
|
|
|
DoFCXLast
|
|
MOVE.L (A2)+,D3
|
|
DoFCXLast0
|
|
AND.L D1,D3 ;use right mask
|
|
|
|
MOVE.L D6,D0 ;get pattern
|
|
AND.L D3,D0 ;mask it
|
|
NOT.L D3 ;flip mask
|
|
AND.L (A1),D3 ;combine with source
|
|
OR.L D3,D0 ;form dest longword
|
|
MOVE.L D0,(A1)+ ;deposit it
|
|
|
|
MOVE.L (SP)+,D7 ;restore work reg
|
|
RTS
|
|
|
|
; handle the case of an all zero region mask
|
|
|
|
FCXOff
|
|
ADDQ #4,A1 ;skip over it
|
|
EXG.L D6,D7 ;exchange pattern parts even if skipping <SMC 17Oct90> <16>
|
|
|
|
SUBQ #1,D2
|
|
BMI.S DoFCXLast
|
|
|
|
FCXOffLoop
|
|
MOVE.L (A2)+,D3
|
|
BNE.S FCXNotOff1
|
|
|
|
ADDQ #4,A1 ;skip it
|
|
EXG.L D6,D7 ;exchange pattern parts even if skipping <SMC 17Oct90> <16>
|
|
|
|
DBRA D2,FCXOffLoop
|
|
BRA.S DoFCXLast
|
|
|
|
; handle the case of an all one's region mask
|
|
|
|
FCXOn
|
|
MOVE.L D6,(A1)+
|
|
EXG.L D6,D7
|
|
|
|
SUBQ #1,D2
|
|
BMI.S DoFCXLast
|
|
FCXOnLoop
|
|
MOVE.L (A2)+,D3
|
|
CMP.L D4,D3
|
|
BNE.S FCXNotOn1
|
|
|
|
MOVE.L D6,(A1)+
|
|
EXG.L D6,D7
|
|
|
|
DBRA D2,FCXOnLoop
|
|
BRA.S DoFCXLast
|
|
|
|
; handle the unclipped case with faster unwound code
|
|
|
|
DoFCXUnclipped
|
|
LEA 0(A2,D2.W*4),A2 ;bump region ptr
|
|
|
|
ADDQ #1,D2 ;compute count to do
|
|
|
|
CMP.W #8,D2
|
|
BLT.S FinishFCXUnClip
|
|
|
|
MOVE.W D2,D0
|
|
LSR #3,D0 ;divide by 8
|
|
SUBQ #1,D0 ;bias for DBRA
|
|
FCXUnClipLoop
|
|
MOVE.L D6,(A1)+
|
|
MOVE.L D7,(A1)+
|
|
MOVE.L D6,(A1)+
|
|
MOVE.L D7,(A1)+
|
|
MOVE.L D6,(A1)+
|
|
MOVE.L D7,(A1)+
|
|
MOVE.L D6,(A1)+
|
|
MOVE.L D7,(A1)+
|
|
|
|
DBRA D0,FCXUnClipLoop
|
|
|
|
; now finish up the last 7 or less
|
|
|
|
FinishFCXUnClip
|
|
AND #7,D2
|
|
EOR #7,D2
|
|
|
|
BTST #0,D2
|
|
BEQ.S @0
|
|
|
|
EXG.L D6,D7
|
|
@0
|
|
JMP FinishFCXUCTab(D2.W*2)
|
|
FinishFCXUCTab
|
|
MOVE.L D6,(A1)+
|
|
MOVE.L D7,(A1)+
|
|
MOVE.L D6,(A1)+
|
|
MOVE.L D7,(A1)+
|
|
MOVE.L D6,(A1)+
|
|
MOVE.L D7,(A1)+
|
|
MOVE.L D6,(A1)+
|
|
|
|
EXG.L D6,D7
|
|
BRA DoFCXLast
|
|
|
|
|
|
;******************************************************************************************
|
|
|
|
ALIGN Alignment
|
|
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 9 OR 13: BIG PATTERN OR DST --> DST
|
|
;
|
|
slXMASK9
|
|
MOVE D7,-(SP) ;SAVE WORK REGISTER
|
|
MOVE PATHMASK(A6),D7 ;GET HORIZ MASK
|
|
MOVE D0,D6 ;GET LEFT AS INDEX INTO PATTERN
|
|
ADD PATHPOS(A6),D6 ;GET OFFSET FROM PATTERN BASE
|
|
AND D7,D6 ;MASK INTEX INTO PATTERN
|
|
MOVE.L EXPAT(A6),A3 ;GET PATTERN POINTER
|
|
ADD.l PATVPOS(A6),A3 ;ADD VERT OFFSET INTO PATTERN <BAL 22Jan89>
|
|
TST D2 ;TEST NUMBER OF BYTES TO DO
|
|
BRA.S XDO9 ;AND JUMP INTO LOOP
|
|
|
|
XEND9 AND.L D1,D3 ;COMBINE RIGHT AND LEFT MASK
|
|
XNEXT9 AND.L 0(A3,D6),D3 ;MASK PATTERN DATA
|
|
ADDQ #4,D6 ;BUMP INDEX INTO PATTERN
|
|
AND D7,D6 ;MASK INDEX INTO PATTERN
|
|
AND.L (A2)+,D3 ;MERGE MASK AND CLIPRGN MASK
|
|
MOVE.L D3,D0 ;COPY MASKED, CLIPPED SRC
|
|
AND.L D4,D0 ;APPLY FG COLOR TO SRC
|
|
NOT.L D3 ;GET NOT MASKED, CLIPPED SRC
|
|
AND.L (A1),D3 ;USE TO PUNCH OUT DST
|
|
OR.L D3,D0 ;COMBINE SRC AND DST
|
|
MOVE.L D0,(A1)+ ;MOVE RESULT INTO DST
|
|
MOVEQ #-1,D3 ;FLUSH MASK
|
|
SUB #1,D2 ;DEC LONG COUNT
|
|
XDO9 BGT XNEXT9 ;LOOP FOR ALL LONGS IN ROW
|
|
BEQ XEND9 ;DO LAST LONG WITH MASK
|
|
MOVE (SP)+,D7 ;RESTORE WORK REGISTER
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 10 OR 14: BIG PATTERN XOR DST --> DST
|
|
;
|
|
slXMASK10
|
|
MOVE D7,-(SP) ;SAVE WORK REGISTER
|
|
MOVE PATHMASK(A6),D7 ;GET HORIZ MASK
|
|
MOVE D0,D6 ;GET LEFT AS INDEX INTO PATTERN
|
|
ADD PATHPOS(A6),D6 ;GET OFFSET FROM PATTERN BASE
|
|
AND D7,D6 ;MASK INDEX INTO PATTERN
|
|
MOVE.L EXPAT(A6),A3 ;GET PATTERN POINTER
|
|
ADD.l PATVPOS(A6),A3 ;ADD VERT OFFSET INTO PATTERN <BAL 22Jan89>
|
|
TST D2 ;TEST NUMBER OF BYTES TO DO
|
|
BRA.S XDO10 ;AND JUMP INTO LOOP
|
|
|
|
XEND10 AND.L D1,D3 ;COMBINE RIGHT AND LEFT MASK
|
|
XNEXT10 AND.L 0(A3,D6),D3 ;MASK PATTERN DATA
|
|
ADDQ #4,D6 ;BUMP INDEX INTO PATTERN
|
|
AND D7,D6 ;MASK INDEX INTO PATTERN
|
|
AND.L (A2)+,D3 ;MERGE MASK AND CLIPRGN MASK
|
|
EOR.L D3,(A1)+ ;XOR RESULT INTO DST
|
|
MOVEQ #-1,D3 ;FLUSH MASK
|
|
SUB #1,D2 ;DEC LONG COUNT
|
|
XDO10 BGT XNEXT10 ;LOOP FOR ALL LONGS IN ROW
|
|
BEQ XEND10 ;DO LAST LONG WITH MASK
|
|
MOVE (SP)+,D7 ;RESTORE WORK REGISTER
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 11 OR 15: BIG PATTERN BIC DST --> DST
|
|
;
|
|
slXMASK11
|
|
MOVE D7,-(SP) ;SAVE WORK REGISTER
|
|
MOVE PATHMASK(A6),D7 ;GET HORIZ MASK
|
|
MOVE D0,D6 ;GET LEFT AS INDEX INTO PATTERN
|
|
ADD PATHPOS(A6),D6 ;GET OFFSET FROM PATTERN BASE
|
|
AND D7,D6 ;MASK INDEX INTO PATTERN
|
|
MOVE.L EXPAT(A6),A3 ;GET PATTERN POINTER
|
|
ADD.l PATVPOS(A6),A3 ;ADD VERT OFFSET INTO PATTERN <BAL 22Jan89>
|
|
TST D2 ;TEST NUMBER OF BYTES TO DO
|
|
BRA.S XDO11 ;AND JUMP INTO LOOP
|
|
|
|
XEND11 AND.L D1,D3 ;COMBINE RIGHT AND LEFT MASK
|
|
XNEXT11 AND.L 0(A3,D6),D3 ;MASK PATTERN DATA
|
|
ADDQ #4,D6 ;BUMP INDEX INTO PATTERN
|
|
AND D7,D6 ;MASK INDEX INTO PATTERN
|
|
AND.L (A2)+,D3 ;GET MASKED, CLIPPED SRC
|
|
MOVE.L D3,D0 ;COPY MASKED, CLIPPED SRC
|
|
AND.L D5,D0 ;APPLY BK TO SRC
|
|
NOT.L D3 ;GET NOT MASKED, CLIPPED SRC
|
|
AND.L (A1),D3 ;PUNCH OUT DST DATA
|
|
OR.L D3,D0 ;COMBINE SRC AND DST
|
|
MOVE.L D0,(A1)+ ;PUT RESULT TO DST
|
|
MOVEQ #-1,D3 ;FLUSH MASK
|
|
SUB #1,D2 ;DEC LONG COUNT
|
|
XDO11 BGT XNEXT11 ;LOOP FOR ALL LONGS IN ROW
|
|
BEQ XEND11 ;DO LAST LONG WITH MASK
|
|
MOVE (SP)+,D7 ;RESTORE WORK REGISTER
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 42: PAT + DST --> DST (no pin)
|
|
|
|
; D4 is destination offset rather than foreground color
|
|
; D5 is inverse table size rather than background color
|
|
|
|
slAddOver
|
|
MOVEM.L D7/A4-A5,-(SP) ;preserve extra registers
|
|
BSR.S arithSetup ;set up registers for slab bit blt
|
|
TST D2 ;TEST NUMBER OF BYTES TO DO
|
|
BRA.S @loopEnd
|
|
@loopRight
|
|
AND.L D1,D3 ;combine left and right masks
|
|
@loopTop
|
|
ADD.L D7,D6 ;advance the pattern
|
|
AND patHMask(A6),D6 ;constrict it to the width of the pattern
|
|
|
|
BFEXTU D3{D4:D7},D0 ;a pixel of the mask
|
|
BEQ.S @skip
|
|
BFEXTU (A2){D4:D7},D0 ;a pixel of the clip region
|
|
BEQ.S @skip
|
|
BFEXTU (A3){D6:D7},D0 ;get a pixel of the pattern
|
|
LEA red(A0,D0*8),A4 ;figure out where it lives in the color table
|
|
BFEXTU (A1){D4:D7},D0 ;a pixel of the destination
|
|
LEA red(A0,D0*8),A5 ;figure out where destination lives
|
|
MOVE (A4)+,D0 ;red get source color value
|
|
ADD (A5)+,D0 ; combine source and destination
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
MOVE (A4)+,D0 ;green get source color value
|
|
ADD (A5)+,D0 ; combine source and destination
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
MOVE (A4)+,D0 ;blue get source color value
|
|
ADD (A5)+,D0 ; combine source and destination
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
SWAP D0 ;r, g, b in high word
|
|
MOVE.B ([invColor,A6],D0,itTable),D0 ;get the pixel value of the additive sum
|
|
BFINS D0,(A1){D4:D7} ;move to the destination
|
|
@skip
|
|
ADD.L D7,D4 ;bump destination and mask
|
|
MOVE D4,D0 ;copy destination offset
|
|
AND #31,D0 ;combine with long sized mask
|
|
BNE.S @loopTop ;loop if havenÕt finished a long yet
|
|
MOVEQ #-1,D3 ;flush the mask
|
|
SUBQ #1,D2 ;decrement long counter
|
|
@loopEnd
|
|
BGT.S @loopTop ;do it for all of the pixels on the line (or within the mask)
|
|
BEQ.S @loopRight
|
|
MOVEM.L (SP)+,D7/A4-A5 ;restore regs
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Utility arithSetup
|
|
; sets up registers for arithmetic modes:
|
|
;
|
|
; A0 = base offset in bits (left * pixelSize)
|
|
;
|
|
; D4 = 0 (destination bit offset) D5 = inverse color table resolution
|
|
; D6 = source bit offset D7 = bits per pixel
|
|
; A0 = color table pointer A3 = source pointer
|
|
;
|
|
|
|
arithSetup
|
|
MOVEQ #0,D4 ;start off dest. at 0
|
|
MOVE invSize(A6),D5 ;set up resolution of inverse color table
|
|
MOVEQ #0,D6 ;start with left side of pattern
|
|
MOVEQ #0,D7 ;zero high word
|
|
MOVE dstPix+pixelSize(A6),D7 ;set up pixel size
|
|
MOVE.L A0,A3 ;set up pointer to pat long in case pattern is small
|
|
CMP #4,patRow(A6) ;big pat?
|
|
BLE.S @skipBig
|
|
move.l slabLeft(a6),d6 ;get bit offset into src <BAL 17Jan89>
|
|
and.l #~$1f,d6 ;truncate to long boundary <BAL 18Jan89>
|
|
move.w patHPos(a6),a0 ;make into a long <BAL 17Jan89>
|
|
add.l a0,D6 ;compute src offset in d6 <BAL 17Jan89>
|
|
MOVE.L EXPAT(A6),A3 ;GET PATTERN POINTER
|
|
ADD.l PATVPOS(A6),A3 ;ADD VERT OFFSET INTO PATTERN <BAL 22Jan89>
|
|
@skipBig
|
|
SUB.L D7,D6 ;less 1 since bumped before used
|
|
MOVE.L colorTable(A6),A0 ;set up pointer to color table
|
|
RTS
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 41: PAT + DST --> DST (pin to max)
|
|
|
|
; D4 is destination offset rather than foreground color
|
|
; D5 is inverse table size rather than background color
|
|
|
|
slAddPin
|
|
MOVEM.L D7/A4-A5,-(SP) ;preserve extra registers
|
|
BSR.S arithSetup ;set up registers for slab bitblt
|
|
TST D2 ;TEST NUMBER OF BYTES TO DO
|
|
BRA.S @loopEnd
|
|
@loopRight
|
|
AND.L D1,D3 ;combine left and right masks
|
|
@loopTop
|
|
ADD.L D7,D6 ;advance the pattern
|
|
AND patHMask(A6),D6 ;constrict it to the width of the pattern
|
|
|
|
BFEXTU D3{D4:D7},D0 ;a pixel of the mask
|
|
BEQ.S @skip
|
|
BFEXTU (A2){D4:D7},D0 ;a pixel of the clip region
|
|
BEQ.S @skip
|
|
BFEXTU (A3){D6:D7},D0 ;get a pixel of the pattern
|
|
LEA red(A0,D0*8),A4 ;figure out where it lives in the color table
|
|
BFEXTU (A1){D4:D7},D0 ;a pixel of the destination
|
|
LEA red(A0,D0*8),A5 ;figure out where destination lives
|
|
MOVE (A4)+,D0 ;red get source color value
|
|
ADD (A5)+,D0 ; combine source and destination
|
|
BCS.S @tooBigRed
|
|
CMP pin+4(A6),D0 ;bigger than pin value?
|
|
BLS.S @notTooBigRed ;no, no problem
|
|
@tooBigRed
|
|
MOVE pin+4(A6),D0
|
|
@notTooBigRed
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
MOVE (A4)+,D0 ;green get source color value
|
|
ADD (A5)+,D0 ; combine source and destination
|
|
BCS.S @tooBigGreen
|
|
CMP pin+2(A6),D0 ;bigger than pin value?
|
|
BLS.S @notTooBigGreen ;no, no problem
|
|
@tooBigGreen
|
|
MOVE pin+2(A6),D0
|
|
@notTooBigGreen
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
MOVE (A4)+,D0 ;blue get source color value
|
|
ADD (A5)+,D0 ; combine source and destination
|
|
BCS.S @tooBigBlue
|
|
CMP pin(A6),D0 ;bigger than pin value?
|
|
BLS.S @notTooBigBlue ;no, no problem
|
|
@tooBigBlue
|
|
MOVE pin(A6),D0
|
|
@notTooBigBlue
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
SWAP D0 ;r, g, b in high word
|
|
MOVE.B ([invColor,A6],D0,itTable),D0 ;get the pixel value of the additive sum
|
|
BFINS D0,(A1){D4:D7} ;move to the destination
|
|
@skip
|
|
ADD.L D7,D4 ;bump destination and mask
|
|
MOVE D4,D0 ;copy destination offset
|
|
AND #31,D0 ;combine with long sized mask
|
|
BNE.S @loopTop ;loop if havenÕt finished a long yet
|
|
MOVEQ #-1,D3 ;flush the mask
|
|
SUBQ #1,D2 ;decrement long counter
|
|
@loopEnd
|
|
BGT.S @loopTop ;do it for all of the pixels on the line (or within the mask)
|
|
BEQ.S @loopRight
|
|
MOVEM.L (SP)+,D7/A4-A5 ;restore regs
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 46: DST - PAT --> DST (no pin)
|
|
|
|
; D4 is destination offset rather than foreground color
|
|
; D5 is inverse table size rather than background color
|
|
|
|
slSubOver
|
|
MOVEM.L D7/A4-A5,-(SP) ;preserve extra registers
|
|
BSR arithSetup ;set up registers for slab bitblt
|
|
TST D2 ;TEST NUMBER OF BYTES TO DO
|
|
BRA.S @loopEnd
|
|
@loopRight
|
|
AND.L D1,D3 ;combine left and right masks
|
|
@loopTop
|
|
ADD.L D7,D6 ;advance the pattern
|
|
AND patHMask(A6),D6 ;constrict it to the width of the pattern
|
|
|
|
BFEXTU D3{D4:D7},D0 ;a pixel of the mask
|
|
BEQ.S @skip
|
|
BFEXTU (A2){D4:D7},D0 ;a pixel of the clip region
|
|
BEQ.S @skip
|
|
BFEXTU (A3){D6:D7},D0 ;get a pixel of the pattern
|
|
LEA red(A0,D0*8),A4 ;figure out where it lives in the color table
|
|
BFEXTU (A1){D4:D7},D0 ;a pixel of the destination
|
|
LEA red(A0,D0*8),A5 ;figure out where destination lives
|
|
MOVE (A5)+,D0 ;red get source color value
|
|
SUB (A4)+,D0 ; combine source and destination
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
MOVE (A5)+,D0 ;green get source color value
|
|
SUB (A4)+,D0 ; combine source and destination
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
MOVE (A5)+,D0 ;blue get source color value
|
|
SUB (A4)+,D0 ; combine source and destination
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
SWAP D0 ;r, g, b in high word
|
|
MOVE.B ([invColor,A6],D0,itTable),D0 ;get the pixel value of the additive sum
|
|
BFINS D0,(A1){D4:D7} ;move to the destination
|
|
@skip
|
|
ADD.L D7,D4 ;bump destination and mask
|
|
MOVE D4,D0 ;copy destination offset
|
|
AND #31,D0 ;combine with long sized mask
|
|
BNE.S @loopTop ;loop if havenÕt finished a long yet
|
|
MOVEQ #-1,D3 ;flush the mask
|
|
SUBQ #1,D2 ;decrement long counter
|
|
@loopEnd
|
|
BGT.S @loopTop ;do it for all of the pixels on the line (or within the mask)
|
|
BEQ.S @loopRight
|
|
MOVEM.L (SP)+,D7/A4-A5 ;restore regs
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 43: DST - PAT --> DST (pin to min)
|
|
|
|
; D4 is destination offset rather than foreground color
|
|
; D5 is inverse table size rather than background color
|
|
|
|
slSubPin
|
|
MOVEM.L D7/A4-A5,-(SP) ;preserve extra registers
|
|
BSR arithSetup ;set up registers for slab bitblt
|
|
TST D2 ;TEST NUMBER OF BYTES TO DO
|
|
BRA.S @loopEnd
|
|
@loopRight
|
|
AND.L D1,D3 ;combine left and right masks
|
|
@loopTop
|
|
ADD.L D7,D6 ;advance the pattern
|
|
AND patHMask(A6),D6 ;constrict it to the width of the pattern
|
|
|
|
BFEXTU D3{D4:D7},D0 ;a pixel of the mask
|
|
BEQ.S @skip
|
|
BFEXTU (A2){D4:D7},D0 ;a pixel of the clip region
|
|
BEQ.S @skip
|
|
BFEXTU (A3){D6:D7},D0 ;get a pixel of the pattern
|
|
LEA red(A0,D0*8),A4 ;figure out where it lives in the color table
|
|
BFEXTU (A1){D4:D7},D0 ;a pixel of the destination
|
|
LEA red(A0,D0*8),A5 ;figure out where destination lives
|
|
MOVE (A5)+,D0 ;red get destination color value
|
|
SUB (A4)+,D0 ; less source color
|
|
BCS.S @tooBigRed
|
|
CMP pin+4(A6),D0 ;bigger than pin value?
|
|
BHS.S @notTooBigRed ;no, no problem
|
|
@tooBigRed
|
|
MOVE pin+4(A6),D0
|
|
@notTooBigRed
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
MOVE (A5)+,D0 ;green get destination color value
|
|
SUB (A4)+,D0 ; less source color
|
|
BCS.S @tooBigGreen
|
|
CMP pin+2(A6),D0 ;bigger than pin value?
|
|
BHS.S @notTooBigGreen ;no, no problem
|
|
@tooBigGreen
|
|
MOVE pin+2(A6),D0
|
|
@notTooBigGreen
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
MOVE (A5)+,D0 ;blue get destination color value
|
|
SUB (A4)+,D0 ; less source color
|
|
BCS.S @tooBigBlue
|
|
CMP pin(A6),D0 ;bigger than pin value?
|
|
BHS.S @notTooBigBlue ;no, no problem
|
|
@tooBigBlue
|
|
MOVE pin(A6),D0
|
|
@notTooBigBlue
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
SWAP D0 ;r, g, b in high word
|
|
MOVE.B ([invColor,A6],D0,itTable),D0 ;get the pixel value of the additive sum
|
|
BFINS D0,(A1){D4:D7} ;move to the destination
|
|
@skip
|
|
ADD.L D7,D4 ;bump destination and mask
|
|
MOVE D4,D0 ;copy destination offset
|
|
AND #31,D0 ;combine with long sized mask
|
|
BNE.S @loopTop ;loop if havenÕt finished a long yet
|
|
MOVEQ #-1,D3 ;flush the mask
|
|
SUBQ #1,D2 ;decrement long counter
|
|
@loopEnd
|
|
BGT.S @loopTop ;do it for all of the pixels on the line (or within the mask)
|
|
BEQ.S @loopRight
|
|
MOVEM.L (SP)+,D7/A4-A5 ;restore regs
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 45: MAX(PAT, DST) --> DST
|
|
;
|
|
slMax
|
|
MOVEM.L D7/A4-A5,-(SP) ;preserve extra registers
|
|
BSR arithSetup ;set up registers for slab bitblt
|
|
TST D2 ;TEST NUMBER OF BYTES TO DO
|
|
BRA.S @loopEnd
|
|
@loopRight
|
|
AND.L D1,D3 ;combine left and right masks
|
|
@loopTop
|
|
ADD.L D7,D6 ;advance the pattern
|
|
AND patHMask(A6),D6 ;constrict it to the width of the pattern
|
|
|
|
BFEXTU D3{D4:D7},D0 ;a pixel of the mask
|
|
BEQ.S @skip
|
|
BFEXTU (A2){D4:D7},D0 ;a pixel of the clip region
|
|
BEQ.S @skip
|
|
BFEXTU (A3){D6:D7},D0 ;get a pixel of the pattern
|
|
LEA red(A0,D0*8),A4 ;figure out where it lives in the color table
|
|
BFEXTU (A1){D4:D7},D0 ;a pixel of the destination
|
|
LEA red(A0,D0*8),A5 ;figure out where destination lives
|
|
MOVE (A4)+,D0 ;Red get pattern color value
|
|
CMP (A5),D0 ; compare with destination color
|
|
BHS.S @gotTheMaxRed ; if pattern is larger, use pattern
|
|
MOVE (A5),D0 ; if destination is larger, use destination
|
|
@gotTheMaxRed
|
|
ADDQ #2,A5 ; advance to next color
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
MOVE (A4)+,D0 ;Blue get pattern color value
|
|
CMP (A5),D0 ; compare with destination color
|
|
BHS.S @gotTheMaxBlue ; if pattern is larger, use pattern
|
|
MOVE (A5),D0 ; if destination is larger, use destination
|
|
@gotTheMaxBlue
|
|
ADDQ #2,A5 ; advance to next color
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
MOVE (A4)+,D0 ;Green get pattern color value
|
|
CMP (A5),D0 ; compare with destination color
|
|
BHS.S @gotTheMaxGreen ; if pattern is larger, use pattern
|
|
MOVE (A5),D0 ; if destination is larger, use destination
|
|
@gotTheMaxGreen
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
SWAP D0 ;r, g, b in high word
|
|
MOVE.B ([invColor,A6],D0,itTable),D0 ;get the pixel value of the additive sum
|
|
BFINS D0,(A1){D4:D7} ;move to the destination
|
|
@skip
|
|
ADD.L D7,D4 ;bump destination and mask
|
|
MOVE D4,D0 ;copy destination offset
|
|
AND #31,D0 ;combine with long sized mask
|
|
BNE.S @loopTop ;loop if havenÕt finished a long yet
|
|
MOVEQ #-1,D3 ;flush the mask
|
|
SUBQ #1,D2 ;decrement long counter
|
|
@loopEnd
|
|
BGT.S @loopTop ;do it for all of the pixels on the line (or within the mask)
|
|
BEQ.S @loopRight
|
|
MOVEM.L (SP)+,D7/A4-A5 ;restore regs
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 47: MIN(PAT, DST) --> DST
|
|
;
|
|
slMin
|
|
MOVEM.L D7/A4-A5,-(SP) ;preserve extra registers
|
|
BSR arithSetup ;set up registers for slab bitblt
|
|
TST D2 ;TEST NUMBER OF BYTES TO DO
|
|
BRA.S @loopEnd
|
|
@loopRight
|
|
AND.L D1,D3 ;combine left and right masks
|
|
@loopTop
|
|
ADD.L D7,D6 ;advance the pattern
|
|
AND patHMask(A6),D6 ;constrict it to the width of the pattern
|
|
|
|
BFEXTU D3{D4:D7},D0 ;a pixel of the mask
|
|
BEQ.S @skip
|
|
BFEXTU (A2){D4:D7},D0 ;a pixel of the clip region
|
|
BEQ.S @skip
|
|
BFEXTU (A3){D6:D7},D0 ;get a pixel of the pattern
|
|
LEA red(A0,D0*8),A4 ;figure out where it lives in the color table
|
|
BFEXTU (A1){D4:D7},D0 ;a pixel of the destination
|
|
LEA red(A0,D0*8),A5 ;figure out where destination lives
|
|
MOVE (A4)+,D0 ;Red get pattern color value
|
|
CMP (A5),D0 ; compare with destination color
|
|
BLS.S @gotTheMinRed ; if pattern is larger, use pattern
|
|
MOVE (A5),D0 ; if destination is larger, use destination
|
|
@gotTheMinRed
|
|
ADDQ #2,A5 ; advance to next color
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
MOVE (A4)+,D0 ;Blue get pattern color value
|
|
CMP (A5),D0 ; compare with destination color
|
|
BLS.S @gotTheMinBlue ; if pattern is larger, use pattern
|
|
MOVE (A5),D0 ; if destination is larger, use destination
|
|
@gotTheMinBlue
|
|
ADDQ #2,A5 ; advance to next color
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
MOVE (A4)+,D0 ;Green get pattern color value
|
|
CMP (A5),D0 ; compare with destination color
|
|
BLS.S @gotTheMinGreen ; if pattern is larger, use pattern
|
|
MOVE (A5),D0 ; if destination is larger, use destination
|
|
@gotTheMinGreen
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
SWAP D0 ;r, g, b in high word
|
|
MOVE.B ([invColor,A6],D0,itTable),D0 ;get the pixel value of the additive sum
|
|
BFINS D0,(A1){D4:D7} ;move to the destination
|
|
@skip
|
|
ADD.L D7,D4 ;bump destination and mask
|
|
MOVE D4,D0 ;copy destination offset
|
|
AND #31,D0 ;combine with long sized mask
|
|
BNE.S @loopTop ;loop if havenÕt finished a long yet
|
|
MOVEQ #-1,D3 ;flush the mask
|
|
SUBQ #1,D2 ;decrement long counter
|
|
@loopEnd
|
|
BGT.S @loopTop ;do it for all of the pixels on the line (or within the mask)
|
|
BEQ.S @loopRight
|
|
MOVEM.L (SP)+,D7/A4-A5 ;restore regs
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 40: AVG(SRC, DST, WEIGHT) --> DST
|
|
|
|
slAvg
|
|
MOVEM.L D7/A4-A5,-(SP) ;preserve extra registers
|
|
MOVE.L D1,-(SP) ;free up register
|
|
BSR arithSetup ;set up registers for slab bitblt
|
|
TST D2 ;TEST NUMBER OF BYTES TO DO
|
|
BRA @loopEnd
|
|
@loopRight
|
|
AND.L (SP)+,D3 ;combine left and right masks
|
|
@loopTop
|
|
ADD.L D7,D6 ;advance the pattern
|
|
AND patHMask(A6),D6 ;constrict it to the width of the pattern
|
|
|
|
BFEXTU D3{D4:D7},D0 ;a pixel of the mask
|
|
BEQ.S @skip
|
|
BFEXTU (A2){D4:D7},D0 ;a pixel of the clip region
|
|
BEQ.S @skip
|
|
BFEXTU (A3){D6:D7},D0 ;get a pixel of the pattern
|
|
LEA red(A0,D0*8),A4 ;figure out where it lives in the color table
|
|
BFEXTU (A1){D4:D7},D0 ;a pixel of the destination
|
|
LEA red(A0,D0*8),A5 ;figure out where destination lives
|
|
|
|
MOVE (A4)+,D0 ;red get source color value
|
|
MULU weight+4(A6),D0 ; weight varies from 0 to 1
|
|
MOVE (A5)+,D1 ; get destination
|
|
MULU notWeight+4(A6),D1 ; weight varies from 1 to 0
|
|
ADD.L D1,D0 ; combine them
|
|
CLR D0 ; clear low word
|
|
SWAP D0 ; high word is interesting part
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
SWAP D0 ; and toss remaining bits
|
|
ASL D5,D0 ; move to the green position
|
|
ASL D5,D0 ; move to the red position
|
|
MOVE D0,-(SP) ; save it
|
|
MOVE (A4)+,D0 ;green get source color value
|
|
MULU weight+2(A6),D0 ; weight varies from 0 to 1
|
|
MOVE (A5)+,D1 ; get destination
|
|
MULU notWeight+2(A6),D1 ; weight varies from 1 to 0
|
|
ADD.L D1,D0 ; combine them
|
|
CLR D0 ; clear low word
|
|
SWAP D0 ; high word is interesting part
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
SWAP D0 ; and toss remaining bits
|
|
ASL D5,D0 ; move to the green position
|
|
OR D0,(SP) ;combine with the red bits
|
|
MOVE (A4)+,D0 ;blue get source color value
|
|
MULU weight(A6),D0 ; weight varies from 0 to 1
|
|
MOVE (A5)+,D1 ; get destination
|
|
MULU notWeight(A6),D1 ; weight varies from 1 to 0
|
|
ADD.L D1,D0 ; combine them
|
|
CLR D0 ; clear low word
|
|
SWAP D0 ; high word is interesting part
|
|
ASL.L D5,D0 ; save the top bits in the top word
|
|
SWAP D0 ; and toss remaining bits
|
|
OR (SP)+,D0 ;add in the red and green
|
|
|
|
MOVE.B ([invColor,A6],D0,itTable),D0 ;get the pixel value of the additive sum
|
|
BFINS D0,(A1){D4:D7} ;move to the destination
|
|
@skip
|
|
ADD.L D7,D4 ;bump destination and mask
|
|
MOVE D4,D0 ;copy destination offset
|
|
AND #31,D0 ;combine with long sized mask
|
|
BNE.S @loopTop ;loop if havenÕt finished a long yet
|
|
MOVEQ #-1,D3 ;flush the mask
|
|
SUBQ #1,D2 ;decrement long counter
|
|
@loopEnd
|
|
BGT.S @loopTop ;do it for all of the pixels on the line (or within the mask)
|
|
BEQ.S @loopRight
|
|
MOVEM.L (SP)+,D7/A4-A5 ;restore regs
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 58: (pat as mask) background color <--> hilite color
|
|
;
|
|
;
|
|
; Note that a fast case could be implemented (like in rgnblt, bitblt) if the pattern source
|
|
; was known to be black.
|
|
;
|
|
; Contains the fix from QDciPatchROM.a
|
|
|
|
slHilite
|
|
MOVEM.L D7/A4-A5,-(SP) ;preserve extra registers
|
|
BSR arithSetup ;set up registers for slab bitblt
|
|
BFEXTU transColor(A6){0:D7},D5 ;get a pixel of the background color
|
|
BFEXTU hilitColor(A6){0:D7},D0 ;get a pixel of the hilite color
|
|
MOVE.L D0,A0 ;save the hilite color pixel in a free register
|
|
TST D2 ;TEST NUMBER OF BYTES TO DO
|
|
BRA.S @loopEnd
|
|
@loopRight
|
|
AND.L D1,D3 ;combine left and right masks
|
|
@loopTop
|
|
ADD.L D7,D6 ;advance the pattern
|
|
AND patHMask(A6),D6 ;constrict it to the width of the pattern
|
|
|
|
BFEXTU D3{D4:D7},D0 ;a pixel of the mask
|
|
BEQ.S @skip
|
|
BFEXTU (A2){D4:D7},D0 ;a pixel of the clip region
|
|
BEQ.S @skip
|
|
BFEXTU (A3){D6:D7},D0 ;get a pixel of the pattern
|
|
CMP.L D5,D0 ; <¥¥¥>
|
|
BEQ.S @skip
|
|
|
|
BFEXTU (A1){D4:D7},D0 ;get a pixel of the destination
|
|
CMP.L D5,D0 ;same as the background color?
|
|
BNE.S @tryNew
|
|
MOVE.L A0,D0 ;put hilite color in data register
|
|
BFINS D0,(A1){D4:D7} ;move hilite color to destination
|
|
BRA.S @skip
|
|
@tryNew
|
|
CMP.L A0,D0 ;same as new color?
|
|
BNE.S @skip
|
|
|
|
BFINS D5,(A1){D4:D7} ;move to the destination
|
|
@skip
|
|
ADD.L D7,D4 ;bump destination and mask
|
|
MOVE D4,D0 ;copy destination offset
|
|
AND #31,D0 ;combine with long sized mask
|
|
BNE.S @loopTop ;loop if havenÕt finished a long yet
|
|
MOVEQ #-1,D3 ;flush the mask
|
|
SUBQ #1,D2 ;decrement long counter
|
|
@loopEnd
|
|
BGT.S @loopTop ;do it for all of the pixels on the line (or within the mask)
|
|
BEQ.S @loopRight
|
|
MOVEM.L (SP)+,D7/A4-A5 ;restore regs
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 44: PAT less bg --> DST
|
|
|
|
; Note that unlike the BitBlt and RgnBlt cases, this has no optimization for when a
|
|
; long of the pattern equals the background. The optimizations in BitBlt and RgnBlt
|
|
; are intended to allow sources other than patterns to be quickly masked and blitted.
|
|
|
|
slTransparent
|
|
MOVEM.L D7/A4-A5,-(SP) ;preserve extra registers
|
|
BSR arithSetup ;set up registers for slab bitblt
|
|
BFEXTU transColor(A6){0:D7},D5 ;get a pixel of the transparent color
|
|
TST D2 ;TEST NUMBER OF BYTES TO DO
|
|
BRA.S @loopEnd
|
|
@loopRight
|
|
AND.L D1,D3 ;combine left and right masks
|
|
@loopTop
|
|
ADD.L D7,D6 ;advance the pattern
|
|
AND patHMask(A6),D6 ;constrict it to the width of the pattern
|
|
|
|
BFEXTU D3{D4:D7},D0 ;a pixel of the mask
|
|
BEQ.S @skip
|
|
BFEXTU (A2){D4:D7},D0 ;a pixel of the clip region
|
|
BEQ.S @skip
|
|
BFEXTU (A3){D6:D7},D0 ;get a pixel of the pattern
|
|
CMP.l D5,D0 ;same as the background? <BAL 17Jan89>
|
|
BEQ.S @skip
|
|
BFINS D0,(A1){D4:D7} ;move to the destination
|
|
@skip
|
|
ADD.L D7,D4 ;bump destination and mask
|
|
MOVE D4,D0 ;copy destination offset
|
|
AND #31,D0 ;combine with long sized mask
|
|
BNE.S @loopTop ;loop if havenÕt finished a long yet
|
|
MOVEQ #-1,D3 ;flush the mask
|
|
SUBQ #1,D2 ;decrement long counter
|
|
@loopEnd
|
|
BGT.S @loopTop ;do it for all of the pixels on the line (or within the mask)
|
|
BEQ.S @loopRight
|
|
MOVEM.L (SP)+,D7/A4-A5 ;restore regs
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;--------------------------------------------------------------------------
|
|
;
|
|
;
|
|
; Here begins the arithmetic transfer loops for 32 bits/pixel:
|
|
;
|
|
;
|
|
;
|
|
;--------------------------------------------------------------------------
|
|
;
|
|
; MODE 42: PAT + DST --> DST (no pin)
|
|
;-------------------------------------------------------
|
|
; a0 = hi bit mask d0 = hi bit clring mask
|
|
; a1 = dstPtr d1 = src pixel
|
|
; a2 = maskPtr d2 = run cnt
|
|
; a3 = patPtr d3 = src msb's
|
|
; a4 = d4 = patHMask
|
|
; a5 = d5 = dest pixel
|
|
; a6 = locals d6 = pattern offset
|
|
; a7 = d7 = dst msb's
|
|
;-------------------------------------------------------
|
|
slAddOver32
|
|
move.l d7,-(sp) ;preserve d7
|
|
BSR arithSetup32 ;set up registers for slab bitblt
|
|
|
|
move.l #~$ff808080,d0 ;get high bit clearing mask
|
|
move.l #$00808080,a0 ;get high bit mask
|
|
|
|
@blit tst.l (a2)+ ;a pixel of the clip region
|
|
beq.s @skip
|
|
|
|
move.l 0(a3,d6),d1 ;get src pixel
|
|
move.l a0,d7 ;copy high bit mask
|
|
and.l d1,d7 ;remember src msb's
|
|
and.l d0,d1 ;mask out stragglers
|
|
|
|
move.l (a1),d5 ;get dest pixel
|
|
move.l a0,d3 ;copy high bit mask
|
|
and.l d5,d3 ;remember dst msb's
|
|
and.l d0,d5 ;mask out stragglers
|
|
|
|
add.l d1,d5 ;merge src with dst
|
|
eor.l d7,d3 ;compute partial sum of msb's
|
|
eor.l d3,d5 ;compute partial sum of msb's
|
|
MOVE.L d5,(a1) ;write pattern to dest
|
|
|
|
@skip addq.l #4,a1 ;bump dst ptr
|
|
addq.l #4,d6 ;bump src index
|
|
and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|
move.l (sp)+,d7 ;restore d7
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Utility arithSetup
|
|
; sets up registers for 32 bit arithmetic modes:
|
|
;
|
|
;
|
|
; INPUTS: A1: DSTPTR
|
|
; A2: MASKPTR
|
|
; D1: RIGHTMASK
|
|
; D2: LONGCNT
|
|
; D3: LEFTMASK
|
|
; D4: FGCOLOR
|
|
; D5: BKCOLOR
|
|
; D6: PATTERN
|
|
;
|
|
; CLOBBERS: D0,D3,D2,A1,A2
|
|
; A3,D6 (BUT NOT IN FASTSLAB)
|
|
|
|
arithSetup32
|
|
subq #1,d2 ;make zero based
|
|
MOVE PATHMASK(A6),D4 ;GET HORIZ MASK
|
|
MOVE D0,D6 ;GET LEFT AS INDEX INTO PATTERN
|
|
ADD PATHPOS(A6),D6 ;GET OFFSET FROM PATTERN BASE
|
|
AND D4,D6 ;MASK INDEX INTO PATTERN
|
|
MOVE.L EXPAT(A6),A3 ;GET PATTERN POINTER
|
|
ADD.l PATVPOS(A6),A3 ;ADD VERT OFFSET INTO PATTERN <BAL 22Jan89>
|
|
RTS
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 41: PAT + DST --> DST (pin to max)
|
|
;-------------------------------------------------------
|
|
; a0 = d0 = result
|
|
; a1 = dstPtr d1 = lo3Bytes mask
|
|
; a2 = maskPtr d2 = run cnt
|
|
; a3 = patPtr d3 = pin pixel 0rgb
|
|
; a4 = d4 = patHMask
|
|
; a5 = d5 = dest pixel
|
|
; a6 = locals d6 = pattern offset
|
|
; a7 = d7 = src pixel
|
|
;-------------------------------------------------------
|
|
slAddPin32
|
|
move.l d7,a0 ;save d7 in a0
|
|
BSR arithSetup32 ;set up registers for slab bitblt
|
|
|
|
;set up pin pixel as 0rgb in D3
|
|
|
|
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
|
|
|
|
move.l Lo3Bytes,d1 ;pick up mask
|
|
|
|
@blit tst.l (a2)+ ;a pixel of the clip region
|
|
beq.s @skip
|
|
|
|
move.l 0(a3,d6),d7 ;get src pixel
|
|
and.l d1,d7 ;waste high byte
|
|
move.l d7,d0 ;make a copy of the src xrgb
|
|
|
|
move.l (a1),d5 ;get dest pixel
|
|
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,(a1) ;write pattern to dest
|
|
|
|
@skip addq.l #4,a1 ;bump dst ptr
|
|
addq.l #4,d6 ;bump src index
|
|
and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|
move.l a0,d7 ;restore d7
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 46: DST - PAT --> DST (no pin)
|
|
;
|
|
;-------------------------------------------------------
|
|
; a0 = d0 = hi bit clring mask
|
|
; a1 = dstPtr d1 = high bit mask
|
|
; a2 = maskPtr d2 = run cnt
|
|
; a3 = patPtr d3 = src msb's
|
|
; a4 = d4 = dst msb's
|
|
; a5 = d5 = dest pixel
|
|
; a6 = locals d6 = pattern offset
|
|
; a7 = d7 = src pixel
|
|
;-------------------------------------------------------
|
|
slSubOver32
|
|
move.l d7,a0 ;save d7 in a0
|
|
BSR arithSetup32 ;set up registers for slab bitblt
|
|
|
|
move.l #~$ff808080,d0 ;get high bit clearing mask
|
|
move.l #$00808080,d1 ;get high bit mask
|
|
|
|
@blit tst.l (a2)+ ;a pixel of the clip region
|
|
beq.s @skip
|
|
|
|
move.l 0(a3,d6),d7 ;get src pixel
|
|
move.l d1,d3 ;copy high bit mask
|
|
and.l d7,d3 ;remember src msb's
|
|
eor.l d1,d3 ;invert src msb's
|
|
and.l d0,d7 ;mask out stragglers
|
|
|
|
move.l (a1),d5 ;get dest pixel
|
|
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,(a1) ;write pattern to dest
|
|
|
|
@skip addq.l #4,a1 ;bump dst ptr
|
|
addq.l #4,d6 ;bump src index
|
|
and.w patHMask(a6),d6 ;constrict to the source long if in a pattern mode
|
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|
move.l a0,d7 ;restore d7
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 43: DST - PAT --> DST (pin to min)
|
|
;
|
|
;-------------------------------------------------------
|
|
; a0 = d0 = result
|
|
; a1 = dstPtr d1 = lo3Bytes mask
|
|
; a2 = maskPtr d2 = run cnt
|
|
; a3 = patPtr d3 = pin pixel 0rgb
|
|
; a4 = d4 = patHMask
|
|
; a5 = d5 = src pixel
|
|
; a6 = locals d6 = pattern offset
|
|
; a7 = d7 = dst pixel
|
|
;-------------------------------------------------------
|
|
slSubPin32
|
|
move.l d7,a0 ;save d7 in a0
|
|
BSR arithSetup32 ;set up registers for slab bitblt
|
|
|
|
;set up pin pixel as 0rgb in D3
|
|
|
|
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
|
|
|
|
move.l Lo3Bytes,d1 ;pick up mask
|
|
|
|
@blit tst.l (a2)+ ;a pixel of the clip region
|
|
beq.s @skip
|
|
move.l 0(a3,d6),d5 ;get src pixel
|
|
and.l d1,d5 ;waste high byte
|
|
|
|
move.l (a1),d7 ;get dest pixel
|
|
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,(a1) ;write pattern to dest
|
|
|
|
@skip addq.l #4,a1 ;bump dst ptr
|
|
addq.l #4,d6 ;bump src index
|
|
and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|
move.l a0,d7 ;restore d7
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 45: MAX(PAT, DST) --> DST
|
|
;
|
|
;-------------------------------------------------------
|
|
; a0 = d0 = result
|
|
; a1 = dstPtr d1 = src pixel
|
|
; a2 = maskPtr d2 = run cnt
|
|
; a3 = patPtr d3 =
|
|
; a4 = d4 = patHMask
|
|
; a5 = d5 = dest pixel
|
|
; a6 = locals d6 = pattern offset
|
|
; a7 = d7 =
|
|
;-------------------------------------------------------
|
|
slMax32
|
|
BSR arithSetup32 ;set up registers for slab bitblt
|
|
|
|
@blit tst.l (a2)+ ;a pixel of the clip region
|
|
beq.s @skip
|
|
move.l 0(a3,d6),d1 ;get src pixel
|
|
move.l (a1),d5 ;get dest pixel
|
|
|
|
move.l d5,d0 ;make a copy of the dest xrgb
|
|
cmp.w d1,d0 ;compare g,b components
|
|
BHI.S @gotMaxGreen
|
|
move.w d1,d0 ;keep the bigger of the two
|
|
move.b d5,d0 ;prime for blue
|
|
@gotMaxGreen
|
|
cmp.b d1,d5 ;compare blue components
|
|
BHI.S @gotMaxBlue
|
|
move.b d1,d0 ;keep the bigger of the two
|
|
@gotMaxBlue
|
|
swap d1
|
|
swap d0
|
|
cmp.b d1,d0 ;compare red components
|
|
BHI.S @gotMaxRed
|
|
move.b d1,d0 ;keep the bigger of the two
|
|
@gotMaxRed
|
|
swap d0 ;get new xrgb
|
|
MOVE.L d0,(a1) ;write pattern to dest
|
|
|
|
@skip addq.l #4,a1 ;bump dst ptr
|
|
addq.l #4,d6 ;bump src index
|
|
and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 47: MIN(PAT, DST) --> DST
|
|
;
|
|
;-------------------------------------------------------
|
|
; a0 = d0 = result
|
|
; a1 = dstPtr d1 = src pixel
|
|
; a2 = maskPtr d2 = run cnt
|
|
; a3 = patPtr d3 =
|
|
; a4 = d4 = patHMask
|
|
; a5 = d5 = dest pixel
|
|
; a6 = locals d6 = pattern offset
|
|
; a7 = d7 =
|
|
;-------------------------------------------------------
|
|
slMin32
|
|
BSR arithSetup32 ;set up registers for slab bitblt
|
|
|
|
@blit tst.l (a2)+ ;a pixel of the clip region
|
|
beq.s @skip
|
|
move.l 0(a3,d6),d1 ;get src pixel
|
|
move.l (a1),d5 ;get dest pixel
|
|
|
|
move.l d5,d0 ;make a copy of the dest xrgb
|
|
cmp.w d1,d0 ;compare g,b components
|
|
BLS.S @gotMinGreen
|
|
move.w d1,d0 ;keep the smaller of the two
|
|
move.b d5,d0 ;prime for blue
|
|
@gotMinGreen
|
|
cmp.b d1,d5 ;compare blue components
|
|
BLS.S @gotMinBlue
|
|
move.b d1,d0 ;keep the smaller of the two
|
|
@gotMinBlue
|
|
swap d1
|
|
swap d0
|
|
cmp.b d1,d0 ;compare red components
|
|
BLS.S @gotMinRed
|
|
move.b d1,d0 ;keep the smaller of the two
|
|
@gotMinRed
|
|
swap d0 ;get new xrgb
|
|
MOVE.L d0,(a1) ;write pattern to dest
|
|
|
|
@skip addq.l #4,a1 ;bump dst ptr
|
|
addq.l #4,d6 ;bump src index
|
|
and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 40: AVG(SRC, DST, WEIGHT) --> DST
|
|
;
|
|
; CLOBBERS: D0,D3,D2,A1,A2
|
|
; A3,D6 (BUT NOT IN FASTSLAB)
|
|
;-------------------------------------------------------
|
|
; a0 = /last dst d0 = red weight
|
|
; a1 = dstPtr d1 = blue/grn weight (scanCount)
|
|
; a2 = maskPtr d2 = run cnt
|
|
; a3 = patPtr d3 = /last src
|
|
; a4 = d4 = /last result
|
|
; a5 = d5 = dest pixel
|
|
; a6 = locals d6 = pattern offset
|
|
; a7 = d7 = src pixel
|
|
;-------------------------------------------------------
|
|
slAvg32
|
|
lea @slAvg32Slow,a4 ;assume, general blend32 from now on
|
|
lea weight(a6),a0 ;point to weights
|
|
move.w (a0)+,d3
|
|
cmp.w (a0)+,d3 ;is opColor gray?
|
|
bne.s @slAvg32Slow
|
|
cmp.w (a0),d3
|
|
bne.s @slAvg32Slow
|
|
addq #1,d3 ;yes, check for gray values of $8000 or $7fff
|
|
and.w #$fffe,d3
|
|
cmp.w #$8000,d3
|
|
bne.s @slAvg32Slow
|
|
lea @slAvg32Half,a4 ;use fast 50% blend32 from now on
|
|
bra @slAvg32Half
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; General blend case for non 50% gray weights
|
|
;
|
|
;
|
|
@slAvg32Slow
|
|
MOVE.L D7,-(SP) ;preserve extra registers
|
|
BSR arithSetup32 ;set up registers for slab bitblt
|
|
|
|
lea weight(a6),a0 ;point at blue weight
|
|
move.l (a0)+,d1 ;get blue/green weight
|
|
move.w (a0),d0 ;get red weight
|
|
|
|
@short0 moveq #0,d4 ;init last result
|
|
move.l d4,d3 ;init last src
|
|
move.l d4,a0 ;init last dst
|
|
|
|
@blit tst.l (A2)+ ;a pixel of the clip region
|
|
BEQ.S @skip
|
|
move.l 0(a3,d6),d7 ;get src pixel
|
|
move.l (a1),d5 ;get dest pixel
|
|
|
|
@short1 cmp.l d3,d7 ;same as last time?
|
|
bne.s @blue ;no, go do it
|
|
cmp.l a0,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,a0 ;a0 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,a0 ;a0 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 a0,d4 ;d4 has 0RGB
|
|
|
|
@short2 swap d5 ;get back dst
|
|
move.l d5,a0 ;save for short circuit
|
|
swap d7 ;get back src
|
|
move.l d7,d3 ;save for short circuit
|
|
|
|
@again MOVE.L d4,(a1) ;write pattern to dest
|
|
|
|
@skip addq.l #4,a1 ;bump dst ptr
|
|
addq.l #4,d6 ;bump src index
|
|
and.w patHMask(a6),d6 ;constrict to the source long if in a pattern mode
|
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|
|
|
MOVE.L (SP)+,D7 ;restore regs
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;--------------------------------------------
|
|
;
|
|
; Optimized 50% blend case for 32 bits/pixel
|
|
;
|
|
;-------------------------------------------------------
|
|
; a0 = low bit mask d0 = high bit mask
|
|
; a1 = dstPtr d1 = src pixel
|
|
; a2 = maskPtr d2 = run cnt
|
|
; a3 = patPtr d3 = lsb's of result
|
|
; a4 = d4 = patHMask
|
|
; a5 = d5 = dest pixel
|
|
; a6 = locals d6 = pattern offset
|
|
; a7 = d7 =
|
|
;-------------------------------------------------------
|
|
@slAvg32Half
|
|
BSR arithSetup32 ;set up registers for slab bitblt
|
|
|
|
move.l #~$ff808080,d0 ;get high bit mask
|
|
move.l #$10101,a0 ;get low bit mask
|
|
|
|
@blit2 tst.l (A2)+ ;a pixel of the clip region
|
|
BEQ.S @skip2
|
|
move.l 0(a3,d6),d1 ;get src pixel
|
|
|
|
move.l a0,d3 ;copy low bit mask
|
|
and.l d1,d3 ;remember src lsb's
|
|
lsr.l #1,d1 ;get almost 1/2 of it
|
|
and.l d0,d1 ;mask out stragglers
|
|
|
|
move.l (a1),d5 ;get dest pixel
|
|
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,d1 ;merge src with dst
|
|
add.l d3,d1 ;propagate carrys
|
|
MOVE.L d1,(a1) ;write pattern to dest
|
|
|
|
@skip2 addq.l #4,a1 ;bump dst ptr
|
|
addq.l #4,d6 ;bump src index
|
|
and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|
DBRA D2,@blit2 ;LOOP ALL LONGS THIS ROW
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;--------------------------------------------
|
|
;
|
|
; Mode: 36 Transparent for 32 bits/pixel
|
|
;
|
|
;-------------------------------------------------------
|
|
; a0 = d0 =
|
|
; a1 = dstPtr d1 = src pixel
|
|
; a2 = maskPtr d2 = run cnt
|
|
; a3 = patPtr d3 =
|
|
; a4 = d4 = patHMask
|
|
; a5 = d5 = backColor
|
|
; a6 = locals d6 = pattern offset
|
|
; a7 = d7 =
|
|
;-------------------------------------------------------
|
|
slTransparent32
|
|
BSR arithSetup32 ;set up registers for slab bitblt
|
|
|
|
move.l transColor(A6),D5 ;get a pixel of the transparent color
|
|
|
|
@blit tst.l (A2)+ ;a pixel of the clip region
|
|
BEQ.S @skip
|
|
move.l 0(a3,d6),d1 ;get src pixel
|
|
|
|
cmp.l d1,d5 ;is src backColor?
|
|
beq.s @skip ;yes, don't write to dst
|
|
MOVE.L d1,(a1) ;write pattern to dest
|
|
|
|
@skip addq.l #4,a1 ;bump dst ptr
|
|
addq.l #4,d6 ;bump src index
|
|
and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|
RTS
|
|
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;--------------------------------------------------------------------------
|
|
;
|
|
;
|
|
; Here begin the arithmetic transfer loops for 16 bits/pixel:
|
|
;
|
|
;
|
|
;
|
|
;--------------------------------------------------------------------------
|
|
;
|
|
; MODE 42: PAT + DST --> DST (no pin)
|
|
;-------------------------------------------------------
|
|
; a0 = hi bit mask d0 = hi bit clring mask
|
|
; a1 = dstPtr d1 = src pixel
|
|
; a2 = maskPtr d2 = run cnt
|
|
; a3 = patPtr d3 = src msb's
|
|
; a4 = d4 = patHMask
|
|
; a5 = d5 = dest pixel
|
|
; a6 = locals d6 = pattern offset
|
|
; a7 = d7 = dst msb's
|
|
;-------------------------------------------------------
|
|
slAddOver16
|
|
move.l d7,-(sp) ;preserve d7
|
|
BSR.s arithSetup16 ;set up registers for slab bitblt
|
|
|
|
move.w #$3def,d0 ;get high bit clearing mask
|
|
move.w #$4210,a0 ;get high bit mask
|
|
|
|
@blit tst.w (a2)+ ;a pixel of the clip region
|
|
beq.s @skip
|
|
|
|
move.w 0(a3,d6),d1 ;get src pixel
|
|
move.w a0,d7 ;copy high bit mask
|
|
and.w d1,d7 ;remember src msb's
|
|
and.w d0,d1 ;mask out stragglers
|
|
|
|
move.w (a1),d5 ;get dest pixel
|
|
move.w a0,d3 ;copy high bit mask
|
|
and.w d5,d3 ;remember dst msb's
|
|
and.w d0,d5 ;mask out stragglers
|
|
|
|
add.w d1,d5 ;merge src with dst
|
|
eor.w d7,d3 ;compute partial sum of msb's
|
|
eor.w d3,d5 ;compute partial sum of msb's
|
|
MOVE.w d5,(a1) ;write pattern to dest
|
|
|
|
@skip addq.l #2,a1 ;bump dst ptr
|
|
addq.l #2,d6 ;bump src index
|
|
and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|
move.l (sp)+,d7 ;restore d7
|
|
RTS
|
|
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
|
; Utility arithSetup
|
|
; sets up registers for 16 bit arithmetic modes:
|
|
;
|
|
; INPUT
|
|
; REGISTERS: A0: D0: CLOBBERED ;
|
|
; A1: DSTPTR D1: CLOBBERED ;
|
|
; A2: MASKPTR D2: LONGCNT ;
|
|
; A3: SRCPTR D3: FGCOLOR ;
|
|
; A4: modecase D4: BKCOLOR ;
|
|
; A5: D5: CLOBBERED ;
|
|
; A6: D6: DSTALIGN ;
|
|
; A7: D7: PixelSize ;
|
|
; ;
|
|
|
|
arithSetup16
|
|
asl.w #1,d2 ;2 pixels per long
|
|
beq.s @oneLong
|
|
subq #1,d2 ;make zero based
|
|
neg d1 ;convert mask to extra pixel cnt
|
|
add d1,d2 ;include right pixel of last long
|
|
swap d1
|
|
neg d1 ;convert mask to extra pixel cnt
|
|
add d1,d2 ;include right pixel of last long
|
|
@noRight
|
|
tst.l d3 ;worry about first pixel?
|
|
bmi.s @noLeft ;yes, do it!
|
|
subq #1,d2 ;shorten count
|
|
@skipLeft
|
|
addq #2,a2 ;bump mask past first pixel
|
|
addq #2,a3 ;bump src past first pixel
|
|
addq #2,a1 ;bump dst past first pixel
|
|
addq #2,d0 ;bump pat index*
|
|
@noLeft
|
|
MOVE PATHMASK(A6),D4 ;GET HORIZ MASK
|
|
MOVE D0,D6 ;GET LEFT AS INDEX INTO PATTERN
|
|
ADD PATHPOS(A6),D6 ;GET OFFSET FROM PATTERN BASE
|
|
AND D4,D6 ;MASK INDEX INTO PATTERN
|
|
MOVE.L EXPAT(A6),A3 ;GET PATTERN POINTER
|
|
ADD.l PATVPOS(A6),A3 ;ADD VERT OFFSET INTO PATTERN <BAL 22Jan89>
|
|
RTS
|
|
|
|
@oneLong
|
|
and.l d1,d3 ;combine left and right mask
|
|
bpl.s @skipLeft ;skip first pixel
|
|
neg.w d3 ;turn right pixel in to bump
|
|
add.w d3,d2 ;conditionally bump count
|
|
bra.s @noLeft
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 41: PAT + DST --> DST (pin to max)
|
|
;-------------------------------------------------------
|
|
; a0 = d0 = result
|
|
; a1 = dstPtr d1 = lo3Bytes mask
|
|
; a2 = maskPtr d2 = run cnt
|
|
; a3 = patPtr d3 = pin pixel 0rgb
|
|
; a4 = d4 = patHMask
|
|
; a5 = d5 = dest pixel
|
|
; a6 = locals d6 = pattern offset
|
|
; a7 = d7 = src pixel
|
|
;-------------------------------------------------------
|
|
slAddPin16
|
|
move.l d7,-(sp) ;preserve d7
|
|
BSR.s arithSetup16 ;set up registers for slab bitblt
|
|
|
|
;set up pin pixel as 0rgb in D3
|
|
|
|
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
|
|
|
|
@blit tst.w (a2)+ ;a pixel of the clip region
|
|
beq.s @skip
|
|
|
|
moveq #0,d7
|
|
move.w 0(a3,d6),d7 ;get src pixel
|
|
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 (a1),d5 ;get dest pixel
|
|
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,(a1) ;write pattern to dest
|
|
|
|
@skip addq.l #2,a1 ;bump dst ptr
|
|
addq.l #2,d6 ;bump src index
|
|
and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|
move.l (sp)+,d7 ;restore d7
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 46: DST - PAT --> DST (no pin)
|
|
;
|
|
;-------------------------------------------------------
|
|
; a0 = d0 = hi bit clring mask
|
|
; a1 = dstPtr d1 = high bit mask
|
|
; a2 = maskPtr d2 = run cnt
|
|
; a3 = patPtr d3 = src msb's
|
|
; a4 = d4 = dst msb's
|
|
; a5 = d5 = dest pixel
|
|
; a6 = locals d6 = pattern offset
|
|
; a7 = d7 = src pixel
|
|
;-------------------------------------------------------
|
|
slSubOver16
|
|
move.l d7,-(sp) ;preserve d7
|
|
BSR arithSetup16 ;set up registers for slab bitblt
|
|
|
|
move.w #$3def,d0 ;get high bit clearing mask
|
|
move.w #$4210,d1 ;get high bit mask
|
|
|
|
@blit tst.w (a2)+ ;a pixel of the clip region
|
|
beq.s @skip
|
|
|
|
move.w 0(a3,d6),d7 ;get src pixel
|
|
move.w d1,d3 ;copy high bit mask
|
|
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 (a1),d5 ;get dest pixel
|
|
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,(a1) ;write pattern to dest
|
|
|
|
@skip addq.l #2,a1 ;bump dst ptr
|
|
addq.l #2,d6 ;bump src index
|
|
and.w patHMask(a6),d6 ;constrict to the source long if in a pattern mode
|
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|
move.l (sp)+,d7 ;restore d7
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 43: DST - PAT --> DST (pin to min)
|
|
;
|
|
;-------------------------------------------------------
|
|
; a0 = d0 = result
|
|
; a1 = dstPtr d1 = lo3Bytes mask
|
|
; a2 = maskPtr d2 = run cnt
|
|
; a3 = patPtr d3 = pin pixel 0rgb
|
|
; a4 = d4 = patHMask
|
|
; a5 = d5 = src pixel
|
|
; a6 = locals d6 = pattern offset
|
|
; a7 = d7 = dst pixel
|
|
;-------------------------------------------------------
|
|
slSubPin16
|
|
move.l d7,-(sp) ;preserve d7
|
|
BSR arithSetup16 ;set up registers for slab bitblt
|
|
|
|
;set up pin pixel as 0rgb in D3
|
|
|
|
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
|
|
move.l #$808080,d1 ;borrow stopper
|
|
add.l d1,d3 ;prevent borrows from crossing byte boundaries
|
|
|
|
@blit tst.w (a2)+ ;a pixel of the clip region
|
|
beq.s @skip
|
|
|
|
moveq #0,d7
|
|
move.w 0(a3,d6),d7 ;get src pixel
|
|
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 (a1),d5 ;get dest pixel
|
|
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 d1,d5 ;prevent borrows from crossing byte boundaries
|
|
|
|
sub.l d7,d5 ;sub all components at once
|
|
move.l d5,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 d5,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 d5,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,(a1) ;write pattern to dest
|
|
|
|
@skip addq.l #2,a1 ;bump dst ptr
|
|
addq.l #2,d6 ;bump src index
|
|
and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|
move.l (sp)+,d7 ;restore d7
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 45: MAX(PAT, DST) --> DST
|
|
;
|
|
;-------------------------------------------------------
|
|
; a0 = d0 = result
|
|
; a1 = dstPtr d1 = src pixel
|
|
; a2 = maskPtr d2 = run cnt
|
|
; a3 = patPtr d3 =
|
|
; a4 = d4 = patHMask
|
|
; a5 = d5 = dest pixel
|
|
; a6 = locals d6 = pattern offset
|
|
; a7 = d7 =
|
|
;-------------------------------------------------------
|
|
slMax16
|
|
move.l d7,-(sp) ;preserve d7
|
|
BSR arithSetup16 ;set up registers for slab bitblt
|
|
|
|
@blit tst.w (a2)+ ;a pixel of the clip region
|
|
beq.s @skip
|
|
|
|
moveq #0,d7
|
|
move.w 0(a3,d6),d7 ;get src pixel
|
|
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 (a1),d5 ;get dest pixel
|
|
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,(a1) ;write pattern to dest
|
|
|
|
@skip addq.l #2,a1 ;bump dst ptr
|
|
addq.l #2,d6 ;bump src index
|
|
and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|
move.l (sp)+,d7 ;restore d7
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 47: MIN(PAT, DST) --> DST
|
|
;
|
|
;-------------------------------------------------------
|
|
; a0 = d0 = result
|
|
; a1 = dstPtr d1 = src pixel
|
|
; a2 = maskPtr d2 = run cnt
|
|
; a3 = patPtr d3 =
|
|
; a4 = d4 = patHMask
|
|
; a5 = d5 = dest pixel
|
|
; a6 = locals d6 = pattern offset
|
|
; a7 = d7 =
|
|
;-------------------------------------------------------
|
|
slMin16
|
|
move.l d7,-(sp) ;preserve d7
|
|
BSR arithSetup16 ;set up registers for slab bitblt
|
|
|
|
@blit tst.w (a2)+ ;a pixel of the clip region
|
|
beq.s @skip
|
|
|
|
moveq #0,d7
|
|
move.w 0(a3,d6),d7 ;get src pixel
|
|
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 (a1),d5 ;get dest pixel
|
|
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,(a1) ;write pattern to dest
|
|
|
|
@skip addq.l #2,a1 ;bump dst ptr
|
|
addq.l #2,d6 ;bump src index
|
|
and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|
move.l (sp)+,d7 ;restore d7
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; MODE 40: AVG(SRC, DST, WEIGHT) --> DST
|
|
;
|
|
; CLOBBERS: D0,D3,D2,A1,A2
|
|
; A3,D6 (BUT NOT IN FASTSLAB)
|
|
;-------------------------------------------------------
|
|
; a0 = /last dst d0 = red weight
|
|
; a1 = dstPtr d1 = blue/grn weight (scanCount)
|
|
; a2 = maskPtr d2 = run cnt
|
|
; a3 = patPtr d3 = /last src
|
|
; a4 = d4 = /last result
|
|
; a5 = d5 = dest pixel
|
|
; a6 = locals d6 = pattern offset
|
|
; a7 = d7 = src pixel
|
|
;-------------------------------------------------------
|
|
slAvg16
|
|
lea @slAvg16Slow,a4 ;assume, general blend16 from now on
|
|
lea weight(a6),a0 ;point to weights
|
|
move.w (a0)+,d5
|
|
cmp.w (a0)+,d5 ;is opColor gray?
|
|
bne.s @slAvg16Slow
|
|
cmp.w (a0),d5
|
|
bne.s @slAvg16Slow
|
|
addq #1,d5 ;yes, check for gray values of $8000 or $7fff
|
|
and.w #$fffe,d5
|
|
cmp.w #$8000,d5
|
|
bne.s @slAvg16Slow
|
|
lea @slAvg16Half,a4 ;use fast 50% blend16 from now on
|
|
bra @slAvg16Half
|
|
|
|
ALIGN Alignment
|
|
|
|
;-------------------------------------------------------
|
|
;
|
|
; General blend case for non 50% gray weights
|
|
;
|
|
;
|
|
@slAvg16Slow
|
|
move.l d7,-(sp) ;preserve d7
|
|
BSR arithSetup16 ;set up registers for slab bitblt
|
|
|
|
lea weight(a6),a0 ;point at blue weight
|
|
move.l (a0)+,d1 ;get blue/green weight
|
|
move.w (a0),d0 ;get red weight
|
|
|
|
@short0 moveq #0,d4 ;init last result
|
|
move.l d4,d3 ;init last src
|
|
move.l d4,a0 ;init last dst
|
|
|
|
@blit tst.w (A2)+ ;a pixel of the clip region
|
|
BEQ @skip
|
|
moveq #0,d7
|
|
move.w 0(a3,d6),d7 ;get src pixel
|
|
moveq #0,d5
|
|
move.w (a1),d5 ;get dest pixel
|
|
|
|
@short1 cmp.w d3,d7 ;same as last time?
|
|
bne.s @hardway ;no, go do it
|
|
cmp.w a0,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,a0 ;a0 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,a0 ;a0 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 a0,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,a0 ;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,(a1) ;write pattern to dest
|
|
|
|
@skip addq.l #2,a1 ;bump dst ptr
|
|
addq.l #2,d6 ;bump src index
|
|
and.w patHMask(a6),d6 ;constrict to the source long if in a pattern mode
|
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|
move.l (sp)+,d7 ;restore d7
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;--------------------------------------------
|
|
;
|
|
; Optimized 50% blend case for 16 bits/pixel
|
|
;
|
|
;-------------------------------------------------------
|
|
; a0 = low bit mask d0 = high bit mask
|
|
; a1 = dstPtr d1 = src pixel
|
|
; a2 = maskPtr d2 = run cnt
|
|
; a3 = patPtr d3 = lsb's of result
|
|
; a4 = d4 = patHMask
|
|
; a5 = d5 = dest pixel
|
|
; a6 = locals d6 = pattern offset
|
|
; a7 = d7 =
|
|
;-------------------------------------------------------
|
|
@slAvg16Half
|
|
BSR arithSetup16 ;set up registers for slab bitblt
|
|
|
|
move.w #$3def,d0 ;get high bit clearing mask
|
|
move.w #$0421,a0 ;get low bit mask
|
|
|
|
@blit2 tst.w (A2)+ ;a pixel of the clip region
|
|
BEQ.S @skip2
|
|
move.w 0(a3,d6),d1 ;get src pixel
|
|
|
|
move.w a0,d3 ;copy low bit mask
|
|
and.w d1,d3 ;remember src lsb's
|
|
lsr.w #1,d1 ;get almost 1/2 of it
|
|
and.w d0,d1 ;mask out stragglers
|
|
|
|
move.w (a1),d5 ;get dest pixel
|
|
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,d1 ;merge src with dst
|
|
add.w d3,d1 ;propagate carrys
|
|
MOVE.w d1,(a1) ;write pattern to dest
|
|
|
|
@skip2 addq.l #2,a1 ;bump dst ptr
|
|
addq.l #2,d6 ;bump src index
|
|
and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|
DBRA D2,@blit2 ;LOOP ALL LONGS THIS ROW
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;--------------------------------------------
|
|
;
|
|
; Mode: 36 Transparent for 16 bits/pixel
|
|
;
|
|
;-------------------------------------------------------
|
|
; a0 = d0 =
|
|
; a1 = dstPtr d1 = src pixel
|
|
; a2 = maskPtr d2 = run cnt
|
|
; a3 = patPtr d3 =
|
|
; a4 = d4 = patHMask
|
|
; a5 = d5 = backColor
|
|
; a6 = locals d6 = pattern offset
|
|
; a7 = d7 =
|
|
;-------------------------------------------------------
|
|
slTransparent16
|
|
BSR arithSetup16 ;set up registers for slab bitblt
|
|
|
|
move.l transColor(A6),D5 ;get a pixel of the transparent color
|
|
|
|
@blit tst.w (A2)+ ;a pixel of the clip region
|
|
BEQ.S @skip
|
|
move.w 0(a3,d6),d1 ;get src pixel
|
|
|
|
cmp.w d1,d5 ;is src backColor?
|
|
beq.s @skip ;yes, don't write to dst
|
|
MOVE.w d1,(a1) ;write pattern to dest
|
|
|
|
@skip addq.l #2,a1 ;bump dst ptr
|
|
addq.l #2,d6 ;bump src index
|
|
and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|
RTS
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;--------------------------------------------
|
|
;
|
|
; PROCEDURE SlabMode
|
|
;
|
|
; INPUT: D2: MODE, CLOBBERED
|
|
; OUTPUT: A4: MODECASE
|
|
;
|
|
; for arithmetic modes, also set up patHMask, patHPos
|
|
;
|
|
SlabMode
|
|
AND #$37,D2 ;toss all but arithmetic, hilite bits + variant bits
|
|
BCLR #5,D2 ;arithmetic mode?
|
|
BEQ.S @clrInvBit ;if so, donÕt clear the invert bit
|
|
BCLR #4,D2 ;hilite?
|
|
BEQ.S @skipHilite ;if not, donÕt add hilite offset
|
|
MOVEQ #8,D2 ;hilite is at $20, so put ($20 / 2) - 8 here
|
|
BRA.S @2 ; <SMC 26SEP90> <12>
|
|
@skipHilite
|
|
cmp #16,dstPix+pixelSize(A6) ;dst 16,32 bits/pixel?
|
|
bge @useLoops32 ;yes, use alternate table
|
|
@2 MOVE #$1F,patHMask(A6) ;set up patHMask for 1 long for small patterns
|
|
CMP #4,PATROW(A6) ;NEED EXPANDED PATTERN?
|
|
BLE.S @1 ;if not, all ready to go
|
|
MOVEM.L D2/D3,-(SP) ;save work registers
|
|
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
|
|
MOVE patRow(A6),D2 ;get pattern row size
|
|
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
|
|
MOVE patHPos(A6),D2 ;get pattern offset <BAL 17Jan89>
|
|
ASL #3,D2 ;convert from bytes to bits <BAL 17Jan89>
|
|
MOVE D2,patHPos(A6) ;save for arith setup <BAL 17Jan89>
|
|
MOVEM.L (SP)+,D2/D3 ;restore work registers
|
|
@1
|
|
cmp #16,dstPix+pixelSize(A6) ;dst 16,32 bits/pixel? <SMC 26SEP90> <12>
|
|
bge.s @useLoops32 ;yes, use alternate table <SMC 26SEP90> <12>
|
|
ADDQ #8,D2 ;point to arithmetic modes <SMC 26SEP90> <12>
|
|
;ciPatPrep (from QDciPatchROM.a) <sm 6/9/92>stb
|
|
if Quicker then
|
|
cmp #8,dstPix+pixelSize(A6) ;dst 8 bits/pixel?
|
|
blt.s @goTable ;yes, use alternate table <sm 6/9/92>stb
|
|
|
|
subq #8,d2 ;make average mode zero based
|
|
lea slArith8Tab,A4 ;point to 8 bit arithmetic mode table
|
|
add.l 0(A4,D2*4),A4 ;GET CASE JUMP ADDRESS
|
|
RTS
|
|
else
|
|
bra.s @goTable <sm 6/9/92>stb
|
|
endif
|
|
|
|
@clrInvBit
|
|
AND #$3,D2 ;GET LO 2 BITS OF MODE, clearing bit 4 also
|
|
BNE.S @4 ;if not a copy mode, skip over this stuff <17>
|
|
TST.B alphaMode(A6) ;are drawing in alpha mode? <17>
|
|
BEQ.S @4 ;no, use normal loops <17>
|
|
LEA slMASK8A,A4 ;get address of small pat alpha copy loop <17>
|
|
CMP #4,PATROW(A6) ;large pattern? <17>
|
|
BLE.S @3 ;no, exit <17>
|
|
LEA slXMASK8A,A4 ;yes, use big pattern copy loop <17>
|
|
@3 RTS ; <17>
|
|
|
|
@4 CMP #4,PATROW(A6) ;NEED EXPANDED PATTERN?
|
|
BLE.S @goTable ;=>NO <sm 6/9/92>stb
|
|
ADDQ #4,D2 ;ELSE BUMP TO EXPANDED ROUTINES
|
|
@goTable ; <sm 6/9/92>stb
|
|
LEA SlabModeTab,A4 ;POINT TO MODE TABLE
|
|
MOVE.L 0(A4,D2*4),A4 ;GET CASE JUMP ADDRESS
|
|
RTS
|
|
|
|
@useLoops32
|
|
beq.s @useLoops16
|
|
move.l slArith32TabPtr,A4 ;POINT TO MODE TABLE
|
|
add.l 0(A4,D2*4),A4 ;GET CASE JUMP ADDRESS
|
|
RTS
|
|
|
|
@useLoops16
|
|
move.l slArith16TabPtr,A4 ;POINT TO MODE TABLE
|
|
add.l 0(A4,D2*4),A4 ;GET CASE JUMP ADDRESS
|
|
MOVE PATHMASK(A6),D2 ;GET HORIZ MASK
|
|
bset #1,d2 ;make into word mask
|
|
MOVE d2,PATHMASK(A6) ;put HORIZ MASK
|
|
RTS
|
|
|
|
IF 0 THEN
|
|
MODETAB DC.W MODETAB-MASK8
|
|
DC.W MODETAB-MASK9
|
|
DC.W MODETAB-MASK10
|
|
DC.W MODETAB-MASK11
|
|
|
|
DC.W MODETAB-XMASK8
|
|
DC.W MODETAB-XMASK9
|
|
DC.W MODETAB-XMASK10
|
|
DC.W MODETAB-XMASK11
|
|
|
|
DC.W ModeTab-Avg ;10 AVG(PAT, DST, WEIGHT) --> DST
|
|
DC.W ModeTab-AddPin ;12 PAT + DST --> DST (pin to max)
|
|
DC.W ModeTab-AddOver ;13 PAT + DST --> DST (no pin)
|
|
DC.W ModeTab-SubPin ;16 DST - PAT --> DST (pin to min)
|
|
DC.W ModeTab-Transparent ;18 PAT less bg --> DST
|
|
DC.W ModeTab-Max ;1A MAX(PAT, DST) --> DST
|
|
DC.W ModeTab-SubOver ;1C DST - PAT --> DST (no pin)
|
|
DC.W ModeTab-Min ;1E MIN(PAT, DST) --> DST
|
|
DC.W ModeTab-Hilite ;20 (pat as mask) hilite <--> background
|
|
ENDIF
|
|
|
|
|
|
Align 4
|
|
|
|
if Quicker then
|
|
|
|
IMPORT slAddOver8
|
|
IMPORT slSubOver8
|
|
IMPORT slAddPin8
|
|
IMPORT slSubPin8
|
|
IMPORT slMax8
|
|
IMPORT slMin8
|
|
IMPORT slAvg8,slTransparent8
|
|
|
|
slArith8Tab
|
|
DC.L slAvg8-slArith8Tab ;10 AVG(PAT, DST, WEIGHT) --> DST
|
|
DC.L slAddPin8-slArith8Tab ;12 PAT + DST --> DST (pin to max)
|
|
DC.L slAddOver8-slArith8Tab ;13 PAT + DST --> DST (no pin)
|
|
DC.L slSubPin8-slArith8Tab ;16 DST - PAT --> DST (pin to min)
|
|
DC.L slTransparent8-slArith8Tab ;18 PAT less bg --> DST
|
|
DC.L slMax8-slArith8Tab ;1A MAX(PAT, DST) --> DST
|
|
DC.L slSubOver8-slArith8Tab ;1C DST - PAT --> DST (no pin)
|
|
DC.L slMin8-slArith8Tab ;1E MIN(PAT, DST) --> DST
|
|
DC.L slHilite-slArith8Tab ;20 MIN(PAT, DST) --> DST
|
|
|
|
endif
|
|
|
|
slArith16Tab
|
|
DC.L slAvg16-slArith16Tab ;10 AVG(PAT, DST, WEIGHT) --> DST
|
|
DC.L slAddPin16-slArith16Tab ;12 PAT + DST --> DST (pin to max)
|
|
DC.L slAddOver16-slArith16Tab ;13 PAT + DST --> DST (no pin)
|
|
DC.L slSubPin16-slArith16Tab ;16 DST - PAT --> DST (pin to min)
|
|
DC.L slTransparent16-slArith16Tab ;18 PAT less bg --> DST
|
|
DC.L slMax16-slArith16Tab ;1A MAX(PAT, DST) --> DST
|
|
DC.L slSubOver16-slArith16Tab ;1C DST - PAT --> DST (no pin)
|
|
DC.L slMin16-slArith16Tab ;1E MIN(PAT, DST) --> DST
|
|
DC.L slHilite-slArith16Tab ;20 (pat as mask) hilite <--> background
|
|
|
|
slArith32Tab
|
|
DC.L slAvg32-slArith32Tab ;10 AVG(PAT, DST, WEIGHT) --> DST
|
|
DC.L slAddPin32-slArith32Tab ;12 PAT + DST --> DST (pin to max)
|
|
DC.L slAddOver32-slArith32Tab ;13 PAT + DST --> DST (no pin)
|
|
DC.L slSubPin32-slArith32Tab ;16 DST - PAT --> DST (pin to min)
|
|
DC.L slTransparent32-slArith32Tab ;18 PAT less bg --> DST
|
|
DC.L slMax32-slArith32Tab ;1A MAX(PAT, DST) --> DST
|
|
DC.L slSubOver32-slArith32Tab ;1C DST - PAT --> DST (no pin)
|
|
DC.L slMin32-slArith32Tab ;1E MIN(PAT, DST) --> DST
|
|
DC.L slHilite-slArith32Tab ;20 (pat as mask) hilite <--> background
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;---------------------------------------------------------------
|
|
;
|
|
; FAST LOOPS, OPTIMIZED FOR SOLID PATTERN AND RECTANGLE CLIPPED
|
|
;
|
|
; FAST FOREGROUND SLAB:
|
|
;
|
|
FAST11 MOVE.L D5,D4 ; <sm 6/9/92>stb
|
|
TST D2 ; <sm 6/9/92>stb
|
|
FAST8 BEQ.S MERGE8 ;BR IF ALL IN ONE LONG
|
|
MOVE.L D3,D0 ;GET LEFTMASK
|
|
NOT.L D0 ;GET NOT LEFTMASK
|
|
AND.L (A1),D0 ;PUNCH OUT DST
|
|
AND.L D4,D3 ;OR FGCOLOR INTO LEFTMASK
|
|
OR.L D3,D0 ;COMBINE SRC AND DST
|
|
MOVE.L D0,(A1)+ ;AND PUT TO DST
|
|
SUB #2,D2 ;ADJUST LONGCOUNT FOR DBRA
|
|
BLT.S LAST8 ;BR IF NO UNMASKED LONGS
|
|
LOOP8 MOVE.L D4,(A1)+ ;WRITE A LONG OF FOREGROUND
|
|
DBRA D2,LOOP8 ;LOOP ALL UNMASKED LONGS
|
|
BRA.S LAST8 ;GO DO LAST LONG
|
|
MERGE8 AND.L D3,D1 ;COMBINE LEFTMASK AND RIGHTMASK
|
|
LAST8 MOVE.L D1,D0 ;GET MASK
|
|
AND.L D4,D0 ;APPLY FGCOLOR TO MASK
|
|
NOT.L D1 ;GET NOTMASK
|
|
AND.L (A1),D1 ;PUNCH OUT DST
|
|
OR.L D1,D0 ;COMBINE SRC AND DST
|
|
MOVE.L D0,(A1)+ ;OR RIGHTMASK INTO DST
|
|
RTS ;AND RETURN
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;
|
|
; FAST XOR SLAB:
|
|
;
|
|
FAST10 BEQ.S MERGE10 ;BR IF ALL IN ONE LONG
|
|
EOR.L D3,(A1)+ ;XOR LEFTMASK INTO DST
|
|
SUB #2,D2 ;ADJUST LONGCOUNT FOR DBRA
|
|
BLT.S LAST10 ;BR IF NO UNMASKED LONGS
|
|
LOOP10 NOT.L (A1)+ ;INVERT A LONG OF DST
|
|
DBRA D2,LOOP10 ;LOOP ALL UNMASKED LONGS
|
|
LAST10 EOR.L D1,(A1)+ ;XOR RIGHTMASK INTO DST
|
|
RTS ;AND RETURN
|
|
MERGE10 AND.L D3,D1 ;COMBINE LEFTMASK AND RIGHTMASK
|
|
EOR.L D1,(A1)+ ;XOR RIGHTMASK INTO DST
|
|
RTS ;AND RETURN
|
|
|
|
|
|
IF 0 THEN ;¥¥¥
|
|
ALIGN Alignment
|
|
|
|
; FAST BACKGROUND SLAB:
|
|
|
|
FAST11 BEQ.S MERGE11 ;BR IF ALL IN ONE LONG
|
|
MOVE.L D3,D0 ;GET LEFTMASK
|
|
NOT.L D0 ;GET NOT LEFTMASK
|
|
AND.L (A1),D0 ;PUNCH OUT DST
|
|
AND.L D5,D3 ;OR BKCOLOR INTO LEFTMASK
|
|
OR.L D3,D0 ;COMBINE SRC AND DST
|
|
MOVE.L D0,(A1)+ ;AND PUT TO DST
|
|
SUB #2,D2 ;ADJUST LONGCOUNT FOR DBRA
|
|
BLT.S LAST11 ;BR IF NO UNMASKED LONGS
|
|
LOOP11 MOVE.L D5,(A1)+ ;WRITE A LONG OF BACKGROUND
|
|
DBRA D2,LOOP11 ;LOOP ALL UNMASKED LONGS
|
|
BRA.S LAST11 ;GO DO LAST LONG
|
|
MERGE11 AND.L D3,D1 ;COMBINE LEFTMASK AND RIGHTMASK
|
|
LAST11 MOVE.L D1,D0 ;GET MASK
|
|
AND.L D5,D0 ;APPLY BKCOLOR TO MASK
|
|
NOT.L D1 ;GET NOTMASK
|
|
AND.L (A1),D1 ;PUNCH OUT DST
|
|
OR.L D1,D0 ;COMBINE SRC AND DST
|
|
MOVE.L D0,(A1)+ ;OR RIGHTMASK INTO DST
|
|
RTS ;AND RETURN
|
|
ENDIF ;¥¥¥
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
; FAST FOREGROUND/BACKGROUND SLAB USING ALPHA MASK: <17>
|
|
|
|
FAST11A MOVE.L D5,D4 ;USE BKCOLOR INSTEAD OF FGCOLOR
|
|
FAST8A MOVE.L alphaMask(A6),D0 ;GET ALPHA MASK
|
|
AND.L D0,D1 ;CLIP LEFTMASK WITH ALPHAMASK
|
|
AND.L D0,D3 ;CLIP RIGHTMASK WITH ALPHAMASK
|
|
MOVE.L D0,A0 ;save copy of alpha mask
|
|
TST D2 ;RETEST THE LONG COUNT
|
|
BEQ.S MERGE8A ;BR IF ALL IN ONE LONG
|
|
MOVE.L D3,D0 ;GET LEFTMASK
|
|
NOT.L D0 ;GET NOT LEFTMASK
|
|
AND.L (A1),D0 ;PUNCH OUT DST
|
|
AND.L D4,D3 ;OR FGCOLOR INTO LEFTMASK
|
|
OR.L D3,D0 ;COMBINE SRC AND DST
|
|
MOVE.L D0,(A1)+ ;AND PUT TO DST
|
|
SUB #2,D2 ;ADJUST LONGCOUNT FOR DBRA
|
|
BLT.S LAST8A ;BR IF NO UNMASKED LONGS
|
|
MOVE.L A0,D3 ;GET CENTER MASK
|
|
NOT.L D3 ;GET NOT OF MASK
|
|
LOOP8A MOVE.L (A1),D0 ;GET THE DST
|
|
EOR.L D4,D0 ;APPLY FGCOLOR
|
|
AND.L D3,D0 ;MASK OUT PART OF DST
|
|
EOR.L D4,D0 ;REAPPLY FGCOLOR
|
|
MOVE.L D0,(A1)+ ;AND PUT TO DST
|
|
DBRA D2,LOOP8A ;LOOP ALL UNMASKED LONGS
|
|
BRA.S LAST8A ;GO DO LAST LONG
|
|
MERGE8A AND.L D3,D1 ;COMBINE LEFTMASK AND RIGHTMASK
|
|
LAST8A MOVE.L D1,D0 ;GET RIGHTMASK
|
|
NOT.L D0 ;GET NOT RIGHTMASK
|
|
AND.L (A1),D0 ;PUNCH OUT DST
|
|
AND.L D4,D1 ;OR FGCOLOR INTO RIGHTMASK
|
|
OR.L D1,D0 ;COMBINE SRC AND DST
|
|
MOVE.L D0,(A1)+ ;AND PUT TO DST
|
|
RTS ;AND RETURN
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
; FAST XOR SLAB USING ALPHA MASK: <17>
|
|
|
|
FAST10A MOVE.L alphaMask(A6),D0 ;GET ALPHAMASK
|
|
AND.L D0,D1 ;CLIP LEFTMASK WITH ALPHAMASK
|
|
AND.L D0,D3 ;CLIP RIGHTMASK WITH ALPHAMASK
|
|
TST D2 ;RETEST THE LONG COUNT
|
|
BEQ.S MERGE10A ;BR IF ALL IN ONE LONG
|
|
EOR.L D3,(A1)+ ;XOR LEFTMASK INTO DST
|
|
SUB #2,D2 ;ADJUST LONGCOUNT FOR DBRA
|
|
BLT.S LAST10A ;BR IF NO UNMASKED LONGS
|
|
LOOP10A EOR.L D0,(A1)+ ;INVERT A LONG OF DST
|
|
DBRA D2,LOOP10A ;LOOP ALL UNMASKED LONGS
|
|
LAST10A EOR.L D1,(A1)+ ;XOR RIGHTMASK INTO DST
|
|
RTS ;AND RETURN
|
|
MERGE10A AND.L D3,D1 ;COMBINE LEFTMASK AND RIGHTMASK
|
|
EOR.L D1,(A1)+ ;XOR RIGHTMASK INTO DST
|
|
RTS ;AND RETURN
|
|
|
|
|
|
ALIGN Alignment
|
|
|
|
;--------------------------------------------------------------------
|
|
;
|
|
; PROCEDURE FastSlabMode, Call when rect clipped and pattern black.
|
|
;
|
|
; INPUT: D2: MODE, CLOBBERED mode 0=black, 1=xor, 2=white
|
|
; OUTPUT: A4: MODECASE
|
|
;
|
|
; This code has the improvements from QDciPatchROM.a
|
|
|
|
FastSlabMode
|
|
AND #$3,D2 ;GET LO 2 BITS OF MODE
|
|
TST.B alphaMode(A6) ;are we drawing in alpha mode? <17>
|
|
BEQ.S @1 ;no, use original fast cases <17>
|
|
ADDQ #3,D2 ;no, use new fast cases <18>
|
|
@1 LEA FASTTAB,A4 ;POINT TO MODE TABLE
|
|
SUB.W 0(A4,D2*2),A4 ;GET OFFSET FROM FASTTAB <18>
|
|
RTS
|
|
|
|
FASTTAB DC.W FASTTAB-FAST8 ;BLACK
|
|
DC.W FASTTAB-FAST10 ;XOR
|
|
DC.W FASTTAB-FAST11 ;WHITE
|
|
|
|
DC.W FASTTAB-FAST8A ;alpha BLACK (foreground) <17>
|
|
DC.W FASTTAB-FAST10A ;alpha XOR <17>
|
|
DC.W FASTTAB-FAST11A ;alpha WHITE (background) <17>
|
|
|
|
|
|
COPYHANDLE PROC EXPORT
|
|
IMPORT RSetHSize
|
|
;----------------------------------------------------------
|
|
;
|
|
; PROCEDURE COPYHANDLE (SRCH,DSTH: Handle);
|
|
;
|
|
; Copies SRCH into DSTH, resizing it if necesary.
|
|
; OK if srcH is purgeable. <1.7> BAL
|
|
;
|
|
PARAMSIZE EQU 8
|
|
SRCH EQU PARAMSIZE
|
|
DSTH EQU SRCH-4
|
|
|
|
MOVE.L SRCH(SP),D0 ; GET SRC HANDLE
|
|
BEQ.S DONE ; =>EXIT IF NO SRC
|
|
MOVE.L D0,A0 ; A0 = SRCH
|
|
MOVE.L DSTH(SP),D0 ; GET DST HANDLE
|
|
BEQ.S DONE ; =>EXIT IF NO DST
|
|
MOVE.L D0,A1 ; A1 = DSTH
|
|
|
|
_HGetState ; get src purge/lock state <1.7> BAL
|
|
move.b d0,-(sp) ; save for later restore <1.7> BAL
|
|
_HNoPurge ; don't let it purge <1.7> BAL
|
|
|
|
_GetHandleSize ; D0 = size of SRCH
|
|
MOVE.L D0,D1 ; save size in D1
|
|
EXG A0,A1 ; get DSTH in A0
|
|
JSR RSetHSize ; make it the same size
|
|
|
|
EXG A0,A1 ; A0 = SRCH, A1 = DSTH
|
|
move.b (sp)+,d0 ; get saved state <1.7> BAL
|
|
_HSetState ; restore it <1.7> BAL
|
|
|
|
MOVE.L (A0),A0 ; get SRC pointer
|
|
MOVE.L (A1),A1 ; get DST pointer
|
|
MOVE.L D1,D0 ; D0 = size
|
|
_BlockMoveData ; copy the data
|
|
|
|
DONE MOVE.L (SP)+,A0 ; get return address
|
|
ADDQ #8,SP ; strip parameters
|
|
JMP (A0) ; and return
|
|
|
|
|
|
ENDPROC
|