sys7.1-doc-wip/QuickDraw/Arith8Blt.a

2697 lines
59 KiB
Plaintext

;
; File: Arith8Blt.a
;
; Contains: xxx put contents here (or delete the whole line) xxx
;
; Written by: xxx put name of writer here (or delete the whole line) xxx
;
; Copyright: © 1987-1990 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <5> 10/8/90 SMC Removed patchciRom tests in bTransparent8 and rTransparent8.
; They are now handled in QDciPatchROM.a.
; <4> 8/16/90 SMC Fixed horizontal pattern alignment of complex patterns in
; transparent and arithmetic slab transfer modes.
; <3> 1/29/90 BAL Fixed conditionals for JP build.
; <2> 1/28/90 KON Conditionalized an equate table for ci Rom patch. This file is
; included by QDciPatchROM.a.
; <1.1> 11/18/89 BAL Made a real part of 32-Bit QuickDraw 1.2
; <1.0> 11/9/89 BAL Added to Ease
; <1.2> 1/16/89 CCH Merged 6.0.3 final sources into 7.0.
; <•1.1> 11/16/88 CCH Updated to newest version.
; <AJH> 2/23/88 fixed arithmetic mode cache initialization (add and sub modes) (1.1)
; <AJH> 2/22/88 fixed bug in 8-1 copybits (can't assume map is 0 or 1 only)
; <AJH> 2/21/88 fixed wrong reg (A4 -> A2) bump bug in oval handler (MacDraw crash)
; (1.0)
; <AJH> 2/21/88 fixed bug in arithmetic mode cache initialization
; <AJH> 2/18/88 fixed bug in transparent mode fill (LSR instead of ASR)
; <AJH> 2/18/88 fixed bug in unclipped, less than 5 wide arithmetic modes
; <AJH> 2/7/88 added configuration code at startup time (.99)
; <AJH> 2/4/88 fixed arithmetic mode bug with type 0 patterns (-$68, not -68!) (.987)
; AJH 05-Feb-88 converted to cdev
; <AJH> 2/4/88 added transparent modes
; <AJH> 2/2/88 added blend mode; fixed arithmetic copyBits bug AJH 03-Feb-88 removed
; hilite by invert hack (.985) AJH 03-Feb-88 further optimized
; hilite, 1 to 8 copybits
; <AJH> 2/1/88 added arithmetic transfer mode fills for clipped rects (.98)
; <AJH> 1/31/88 added arithmetic transfer mode fills for unclipped rects
; <AJH> 1/30/88 added arithmetic transfer mode fills for rrects/ovals
; <AJH> 1/29/88 added oval/rrects with complex patterns
; <AJH> 1/28/88 check if already installed; if so, display logo AJH 29-Jan-88 removed
; OR mode complex fills; fixed OR mode simple fills AJH 29-Jan-88
; reject patterns > 8 pixels wide
; <AJH> 1/28/88 INIT wasn't locked bug (.97)
; <AJH> 1/27/88 OR mode fills (simple and complex patterns) (.96)
; <AJH> 1/26/88 added oval/rrects in OR mode
; <AJH> 1/24/88 broke LogoPict into separate resource; separate 1-bit logo (.95) AJH
; 25-Jan-88 region counting for InvertClip AJH 26-Jan-88
; significantly improved oval/rrects when unclipped
; <AJH> 1/23/88 fixed bug when region is a mask (CB1to8 from CopyMask)
; <AJH> 1/22/88 fixed OR mode fill, added $335 for MacDraw Plus
; <AJH> 1/17/88 fixed scaling rejection bug in mapped copyBits AJH 18-Jan-88
; implemented fast 8 to 1 copyBits; fixed 1-8 seekRgn bug (.94)
; AJH 20-Jan-88 region counting for clipped blit
; <AJH> 1/16/88 fixed seek region bug in mapped copyBits (.93)
; <AJH> 1/14/88 fixed bug in unclipped pattern fill (.92)
; <AJH> 1/13/88 made fills work in modes other than 8-bit (.91)
; <AJH> 1/11/88 st Beta release, version .9
;
; To Do:
;
;EASE$$$ READ ONLY COPY of file “arith8blt.a”
; 1.1 BAL 11/18/1989 Made a real part of 32-Bit QuickDraw 1.2
; 1.0 BAL 11/09/1989 Added to Ease
; END EASE MODIFICATION HISTORY
; 1.2 CCH 01/16/1989 Merged 6.0.3 final sources into 7.0.
;•1.1 CCH 11/16/1988 Updated to newest version.
PRINT ON
; File QuickLoops.a
;-----------------------------------------------------------------------------
;
; High performance Mac II Color QuickDraw Inner Loops (for 8-bit mode)
;
; written by Andy Hertzfeld December 22, 1987
;
; This INIT patches out some of the Color QuickDraw inner loop traps
; to improve 8-bit performance by a factor of 2 to 3 (or even more!)
;
; Modification History:
;
; AJH 11-Jan-88 1st Beta release, version .9
; AJH 13-Jan-88 made fills work in modes other than 8-bit (.91)
; AJH 14-Jan-88 fixed bug in unclipped pattern fill (.92)
; AJH 16-Jan-88 fixed seek region bug in mapped copyBits (.93)
; AJH 17-Jan-88 fixed scaling rejection bug in mapped copyBits
; AJH 18-Jan-88 implemented fast 8 to 1 copyBits; fixed 1-8 seekRgn bug (.94)
; AJH 20-Jan-88 region counting for clipped blit
; AJH 22-Jan-88 fixed OR mode fill, added $335 for MacDraw Plus
; AJH 23-Jan-88 fixed bug when region is a mask (CB1to8 from CopyMask)
; AJH 24-Jan-88 broke LogoPict into separate resource; separate 1-bit logo (.95)
; AJH 25-Jan-88 region counting for InvertClip
; AJH 26-Jan-88 significantly improved oval/rrects when unclipped
; AJH 26-Jan-88 added oval/rrects in OR mode
; AJH 27-Jan-88 OR mode fills (simple and complex patterns) (.96)
; AJH 28-Jan-88 INIT wasn't locked bug (.97)
; AJH 28-Jan-88 check if already installed; if so, display logo
; AJH 29-Jan-88 removed OR mode complex fills; fixed OR mode simple fills
; AJH 29-Jan-88 reject patterns > 8 pixels wide
; AJH 29-Jan-88 added oval/rrects with complex patterns
; AJH 30-Jan-88 added arithmetic transfer mode fills for rrects/ovals
; AJH 31-Jan-88 added arithmetic transfer mode fills for unclipped rects
; AJH 01-Feb-88 added arithmetic transfer mode fills for clipped rects (.98)
; AJH 02-Feb-88 added blend mode; fixed arithmetic copyBits bug
; AJH 03-Feb-88 removed hilite by invert hack (.985)
; AJH 03-Feb-88 further optimized hilite, 1 to 8 copybits
; AJH 04-Feb-88 added transparent modes
; AJH 04-Feb-88 fixed arithmetic mode bug with type 0 patterns (-$68, not -68!) (.987)
; AJH 05-Feb-88 converted to cdev
; AJH 07-Feb-88 added configuration code at startup time (.99)
; AJH 18-Feb-88 fixed bug in transparent mode fill (LSR instead of ASR)
; AJH 18-Feb-88 fixed bug in unclipped, less than 5 wide arithmetic modes
; AJH 21-Feb-88 fixed bug in arithmetic mode cache initialization
; AJH 21-Feb-88 fixed wrong reg (A4 -> A2) bump bug in oval handler (MacDraw crash) (1.0)
; AJH 22-Feb-88 fixed bug in 8-1 copybits (can't assume map is 0 or 1 only)
; AJH 23-Feb-88 fixed arithmetic mode cache initialization (add and sub modes) (1.1)
;
;---- A New Life at Apple --------------------
;
; PB415 DAF/BAL 01Mar88 QuickerDraw integrated into system patch files
; PB427 BAL 17Mar88 Corrected some edge masking bugs in arithmetic modes.
; Return to ROM if arithmetic mode copybits from left to right.
; PB428 DAF 18Mar88 Fixed QuickerDraw to be A/UX friendly.
; PB433 DAF 22Mar88 Improved dispatches to ROM (saved a couple of bytes and cycles)
; BAL 25Mar88 Converted to use symbolic stack frame references
; PB446 DBG 29Mar88 Fixed up missed JMPs into ROM in QuickerDraw.a, which cause certain
; CopyBits cases to crash.
; PB448 DBG 30Mar88 Fixed erroneous references to HBUMP to be to SRCBUMP
; PB452 BAL 01Apr88 Fixed bug in DrawSlab OR mode handler ($381) to preserve fgColor
; PB471 BAL 18Apr88 Fixed 1 to 8 bit expansion to first insure CLUT is B/W.
; PB473 DAF 19Apr88 Modified PB471 to allow more cases to be accelerated.
; PB471 BAL/DVB 13Jun88 Fixed 1 to 8 bit expansion to first insure src = scalebuf
; (i.e. dest not before pixmap's baseAddr).
; PBnnn d√b 12Jul88 Fixed error in 8 to 1 when white doesn't map to white.
;
;--------------------------------------------------------------------------------------------------
fooo proc ; make following defines global
endproc
IF (&TYPE('patchciRom') = 'UNDEFINED') THEN
patchciRom EQU 0
ENDIF
MACHINE MC68020
; for reference, here are the patched traps
IF 0 THEN
InstToolTp AddOverFillO,$38A
InstToolTp SubOverFillO,$38E
InstToolTp AddPinFillO,$389
InstToolTp SubPinFillO,$38B
InstToolTp AddMaxFillO,$38D
InstToolTp AddMinFillO,$38F
InstToolTp BlendFillO,$388
InstToolTp TransFillO,$38C
InstToolTp AddOverFillR,$368
InstToolTp SubOverFillR,$36C
InstToolTp AddPinFillR,$367
InstToolTp SubPinFillR,$369
InstToolTp AddMaxFillR,$36B
InstToolTp AddMinFillR,$36D
InstToolTp BlendFillR,$366
InstToolTp TransFillR,$36A
InstToolTp AddOverUnClip,$352
InstToolTp SubOverUnClip,$356
InstToolTp AddPinUnClip,$351
InstToolTp SubPinUnClip,$353
InstToolTp AddMaxUnClip,$355
InstToolTp AddMinUnClip,$357
InstToolTp BlendUnClip,$350
InstToolTp TransUnClip,$354
ENDIF
;******************************************************************************************
;
; to make scoping for upcoming equates happier, we force the end of the previous procedure here
;
QuickerDraw PROC EXPORT
EXPORT slAddOver8
EXPORT slSubOver8
EXPORT slAddPin8
EXPORT slSubPin8
EXPORT slMax8
EXPORT slMin8
EXPORT slAvg8
EXPORT rAddOver8
EXPORT rSubOver8
EXPORT rAddPin8
EXPORT rSubPin8
EXPORT rMax8
EXPORT rMin8
EXPORT rAvg8
EXPORT bAddOver8
EXPORT bSubOver8
EXPORT bAddPin8
EXPORT bSubPin8
EXPORT bMax8
EXPORT bMin8
EXPORT bAvg8
EXPORT slTransparent8
EXPORT rTransparent8
EXPORT bTransparent8
if patchciRom THEN
; now patch the inner loop traps; so far we handle:
Old350 EQU $2DAD0 ; bAvg-- blend fill, unclipped rects
Old351 EQU $2D450 ; bAddPin-- addPin fill, unclipped rects
Old352 EQU $2D340 ; bAddOver-- addOver fill, unclipped rects (and bitmaps)
Old353 EQU $2D6E0 ; bSubPin-- subPin fill, unclipped rects
Old354 EQU $2DE80 ; bTransparent-- transparent fill, unclipped rects
Old355 EQU $2D870 ; bMax-- addMax fill, unclipped rects
Old356 EQU $2D5D0 ; bSubOver-- subOver fill, unclipped rects
Old357 EQU $2D9A0 ; bMin-- addMin fill, unclipped rects
Old366 EQU $2BBB0 ; rAvg-- blend fill, clipped rects
Old367 EQU $2B4C0 ; rAddPin-- addPin fill, clipped rects
Old368 EQU $2B3A0 ; rAddOver-- addOver fill, clipped rects (and bitmaps)
Old369 EQU $2B790 ; rSubPin-- subPin fill, clipped rects
Old36A EQU $2C060 ; rTransparent-- transparent fill, clipped rects
Old36B EQU $2B930 ; rMax-- addMax fill, clipped rects
Old36C EQU $2B660 ; rSubOver-- subOver fill, clipped rects
Old36D EQU $2BA70 ; rMin-- addMin fill, clipped rects
Old388 EQU $2F670 ; slAvg-- blend fill, ovals
Old389 EQU $2F3E0 ; slAddPin-- addPin fill, ovals
Old38A EQU $2F330 ; slAddOver-- addOver fill, ovals
Old38B EQU $2F4E0 ; slSubPin-- subPin fill, ovals
Old38C EQU $2F790 ; slTransparent-- transparent fill, ovals
Old38D EQU $2F570 ; slMax-- AddMax fill, ovals
Old38E EQU $2F470 ; slSubOver-- subOver fill, ovals
Old38F EQU $2F5F0 ; slMin-- AddMin fill, ovals
Old380 EQU $2F1C4 ; slMASK8-- oval/rrect copy mode scan line handler
Old381 EQU $2F1E6 ; slMASK9-- oval/rrect OR mode scan line handler
Old384 EQU $2F230 ; slXMask8-- oval/rrect complex fill, copy mode
ELSEIF 0 THEN ;these are the equates for MacII
Old350 EQU $1BF24 ; bAvg-- blend fill, unclipped rects
Old351 EQU $1BC6A ; bAddPin-- addPin fill, unclipped rects
Old352 EQU $1BBF4 ; bAddOver-- addOver fill, unclipped rects (and bitmaps)
Old353 EQU $1BD7C ; bSubPin-- subPin fill, unclipped rects
Old354 EQU $1C0B0 ; bTransparent-- transparent fill, unclipped rects
Old355 EQU $1BE18 ; bMax-- addMax fill, unclipped rects
Old356 EQU $1BD06 ; bSubOver-- subOver fill, unclipped rects
Old357 EQU $1BE9E ; bMin-- addMin fill, unclipped rects
Old366 EQU $1CF94 ; rAvg-- blend fill, clipped rects
Old367 EQU $1CDE8 ; rAddPin-- addPin fill, clipped rects
Old368 EQU $1CD9C ; rAddOver-- addOver fill, clipped rects (and bitmaps)
Old369 EQU $1CE88 ; rSubPin-- subPin fill, clipped rects
Old36A EQU $1D094 ; rTransparent-- transparent fill, clipped rects
Old36B EQU $1CEDC ; rMax-- addMax fill, clipped rects
Old36C EQU $1CE3C ; rSubOver-- subOver fill, clipped rects
Old36D EQU $1CF38 ; rMin-- addMin fill, clipped rects
Old388 EQU $1E1BE ; slAvg-- blend fill, ovals
Old389 EQU $1DF50 ; slAddPin-- addPin fill, ovals
Old38A EQU $1DEBA ; slAddOver-- addOver fill, ovals
Old38B EQU $1E042 ; slSubPin-- subPin fill, ovals
Old38C EQU $1E2CE ; slTransparent-- transparent fill, ovals
Old38D EQU $1E0CE ; slMax-- AddMax fill, ovals
Old38E EQU $1DFDA ; slSubOver-- subOver fill, ovals
Old38F EQU $1E146 ; slMin-- AddMin fill, ovals
Old380 EQU $1DD7E ; slMASK8-- oval/rrect copy mode scan line handler
Old381 EQU $1DD9A ; slMASK9-- oval/rrect OR mode scan line handler
Old384 EQU $1DDCE ; slXMask8-- oval/rrect complex fill, copy mode
ENDIF
;----------------------------------------------------
;
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
;
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
;
&CurFile SETC 'STRETCH'
INCLUDE 'DrawingVars.a'
;******************************************************************************************
; Arithmetic transfer modes start here...
;******************************************************************************************
; Here's where we implement the arithmetic transfer mode fills for ovals/rrects
; Use a common loop for all the transfer modes, with specialized handlers to do the
; pixel arithmetic.
; the first receiver is for AddOver mode for ovals and roundRects
;>>>>>>>>>>>
AddOverFillO
slAddOver8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BEQ.S @0 ;if not, skip
JMPRom Old38A ; continue in ROM <S433>
endif
; OK, first do the pattern setup
@0
MOVE.L A0,A3 ;set up pattern base
LEA AddOverHandler,A0 ;use addOver
DoArithMode
MOVEM.L D7/A4-A5,-(SP) ;save work regs
BSR.S ArithModeHandler ;invoke the handler
MOVEM.L (SP)+,D7/A4-A5 ;restore regs
RTS
; here is the general handler for a scan line of arithmetic fills
ArithModeHandler
MOVEQ #0,D6 ;init pattern index
MOVE.W PATROW(A6),D4 ;get pattern size in bytes
SUBQ #4,D4 ;is it a simple one?
BLE ArithSimplePat ;if so, handle faster
; sometimes simple patterns come in as 8 byte ones, so check for that
MOVE.W PATHPOS(A6),D6 ; <SMC 16Aug90>
ASR.W #3,D6 ;turn bits back into bytes <SMC 16Aug90>
ADD.W D0,D6 ; <SMC 16Aug90>
SUBQ #4,D4 ;is it 8 long?
BNE.S ArithComplexPat ;if not, skip
; fetch both halves of the pattern and see if they match
MOVE.W PATHMASK(A6),D4 ;get pattern mask
ASR #3,D4 ;turn bit index to byte index
AND.W D4,D6 ;mask it
MOVE.L EXPAT(A6),A4
ADD.l PATVPOS(A6),A4 ;compute pattern address
MOVE.L 0(A4,D6),D4 ;get source longword
EOR #4,D6
CMP.L 0(A4,D6),D4 ;is it really simple?
BEQ ArithSimplePat ;if so, go handle
EOR #4,D6 ;restore D6
; set up the pattern variables, since it's a complex pattern
ArithComplexPat
MOVE.L EXPAT(A6),A3
ADD.l PATVPOS(A6),A3 ;compute pattern address
ArithComplex1
MOVE.L D1,-(SP) ;remember right edge mask
MOVEQ #0,D1
MOVEQ #0,D7 ;clear for pixCache
; set up A0 to point to the proper handler, depending on the width of the inverse table
MOVE.L A0,A4 ;remember handler base
MOVE.W INVSIZE(A6),D4 ;get shift count (3,4,5)
SUBQ #3,D4
ADD.W 0(A0,D4.W*2),A0 ;point to proper handler
; init the single pixel cache, where D1 is last source, D7 is last dest, and D0 is last result
MOVEQ #0,D5
MOVE.L COLORTABLE(A6),A5 ;get color table ptr
MOVE.B D1,D5
LEA 0(A5,D5.W*8),A4 ;point to source color
MOVE.B D7,D5
LEA 0(A5,D5.W*8),A5 ;point to dest color
JSR (A0) ;map it
MOVE.B ([INVCOLOR,A6],D0.W,6),D0 ;look up in inverse table
; test for the single long case
TST.W D2
BRA ArithBot0
; here's the main loop for complex patterns, where we process a longword at a time
; use a single pixel cache for speed using D0, D1 and D7
ArithRight0
AND.L (SP)+,D3
ArithLoop0
MOVE.W PATHMASK(A6),D4 ;get pattern mask
ASR #3,D4 ;turn bit index to byte index
AND.W D4,D6 ;mask it
MOVE.L 0(A3,D6),D4 ;get source longword
ADDQ #4,D6
MOVE.L A2,D5 ;no clipping?
BEQ.S @0 ;if none, skip
AND.L (A2)+,D3 ;get region/edge mask in D3
BEQ ArithMask0
@0
MOVE.L (A1),D5 ;get dest longword
; map 1st byte
TST.B D3
BEQ.S @8 ;if mask zero, we can skip
; if same as previous, we can short-circuit the mapping
CMP.B D4,D1 ;source the same?
BNE.S @9 ;if not, skip
CMP.B D5,D7 ;dest the same?
BNE.S @9 ;if not, skip
; it's the same, so use it
MOVE.B D0,D5 ;use last result
BRA.S @8 ;skip the mapping
; it's different than the last one, so map it
@9
MOVE.B D4,D1
MOVE.L COLORTABLE(A6),A5
LEA 0(A5,D1.W*8),A4 ;point to source color
MOVE.B D5,D7
LEA 0(A5,D7.W*8),A5 ;point to dest color
JSR (A0) ;map according to Xfer mode
MOVE.B ([INVCOLOR,A6],D0.W,6),D5 ;look up in inverse table
MOVE.B D5,D0
@8
LSR.L #8,D3
LSR.L #8,D4
ROR.L #8,D5
; map 2nd byte
TST.B D3
BEQ.S @2 ;if mask zero, we can skip
; if same as previous, we can short-circuit the mapping
CMP.B D4,D1 ;source the same?
BNE.S @1 ;if not, skip
CMP.B D5,D7 ;dest the same?
BNE.S @1 ;if not, skip
; it's the same, so use it
MOVE.B D0,D5 ;use last result
BRA.S @2 ;skip the mapping
; it's different than the last one, so map it
@1
MOVE.B D4,D1
MOVE.L COLORTABLE(A6),A5
LEA 0(A5,D1.W*8),A4 ;point to source color
MOVE.B D5,D7
LEA 0(A5,D7.W*8),A5 ;point to dest color
JSR (A0) ;map according to Xfer mode
MOVE.B ([INVCOLOR,A6],D0.W,6),D5 ;look up in inverse table
MOVE.B D5,D0
@2
LSR.L #8,D3
LSR.L #8,D4
ROR.L #8,D5
; map 3rd byte
TST.B D3
BEQ.S @4 ;if mask zero, we can skip
; if same as previous, we can short-circuit the mapping
CMP.B D4,D1 ;source the same?
BNE.S @3 ;if not, skip
CMP.B D5,D7 ;dest the same?
BNE.S @3 ;if not, skip
; it's the same, so use it
MOVE.B D0,D5 ;use last result
BRA.S @4 ;skip the mapping
; it's different than the last one, so map it
@3
MOVE.B D4,D1
MOVE.L COLORTABLE(A6),A5
LEA 0(A5,D1.W*8),A4 ;point to source color
MOVE.B D5,D7
LEA 0(A5,D7.W*8),A5 ;point to dest color
JSR (A0) ;map according to Xfer mode
MOVE.B ([INVCOLOR,A6],D0.W,6),D5 ;look up in inverse table
MOVE.B D5,D0
@4
LSR.L #8,D3
LSR.L #8,D4
ROR.L #8,D5
; map final byte
TST.B D3
BEQ.S @6 ;if mask zero, we can skip
; if same as previous, we can short-circuit the mapping
CMP.B D4,D1 ;source the same?
BNE.S @5 ;if not, skip
CMP.B D5,D7 ;dest the same?
BNE.S @5 ;if not, skip
; it's the same, so use it
MOVE.B D0,D5 ;use last result
BRA.S @6 ;skip the mapping
; it's different than the last one, so map it
@5
MOVE.B D4,D1
MOVE.L COLORTABLE(A6),A5
LEA 0(A5,D1.W*8),A4 ;point to source color
MOVE.B D5,D7
LEA 0(A5,D7.W*8),A5 ;point to dest color
JSR (A0) ;map according to Xfer mode
MOVE.B ([INVCOLOR,A6],D0.W,6),D5 ;look up in inverse table
MOVE.B D5,D0
@6
ROR.L #8,D5
; it's all mapped, so store the result
MOVE.L D5,(A1)+ ;store the destination
ArithBotCommon
MOVEQ #-1,D3 ;set up the mask for the middle
SUBQ #1,D2
ArithBot0
BGT ArithLoop0
BEQ ArithRight0
; all done with this scan line
RTS
; handle a region of all zeros
ArithMask0
ADDQ #4,A1 ;skip over destination
BRA.S ArithBotCommon
; the pattern is simpler (it fits in a register), so use a separate loop to make things
;faster. Use a longword cache instead of the single pixel caches.
ArithSimplePat
MOVE.L D1,-(SP) ;save right edge mask
MOVEQ #0,D7 ;clear for pixIndexing
MOVE.L (A3),D4 ;keep pattern in D4
MOVE.L COLORTABLE(A6),A3 ;use A3 for color table ptr
; set up A0 to point to the proper handler, depending on the width of the inverse table
MOVE.L A0,A4 ;remember handler base
MOVE.W INVSIZE(A6),D0 ;get shift count (3,4,5)
SUBQ #3,D0
ADD.W 0(A0,D0.W*2),A0 ;point to proper handler
; init the longword pattern cache by mapping the four pixels in D4
MOVEQ #3,D5
MOVE.L D4,D6 ;init lastDest
BRA.S CacheILoop0 ;skip cache check 1st time
; if the next pixel in D4 is the same as the previous (in D7), take a shortcut
CacheInitLoop
CMP.B D4,D7 ;does it match?
BNE.S CacheILoop0 ;if not, must do the hard way
MOVE.B D0,D1 ;use last result
ROL.L #8,D1
ROL.L #8,D4
DBRA D5,CacheInitLoop
BRA.S CacheIDone
; it's not the same, so do it the hard way
CacheILoop0
MOVE.B D4,D7
LEA 0(A3,D7.W*8),A4 ;point to source color
MOVE.L A4,A5 ;source and dest are same
JSR (A0) ;map next pixel
MOVE.B ([INVCOLOR,A6],D0.W,6),D1 ;look up in inverse table
MOVE.L D1,D0 ;remember last result
ROL.L #8,D1
ROL.L #8,D4
DBRA D5,CacheInitLoop
; OK, here's the start of the main loop; first, see if there's only one long to do
CacheIDone
TST.W D2
BNE.S ArithLoop1
; here's the main loop for simple patterns, where we process a longword at a time
; We use a longword cache in D6
ArithRight1
AND.L (SP)+,D3
ArithLoop1
MOVE.L A2,D5 ;no clipping?
BEQ.S @0 ;if none, skip
AND.L (A2)+,D3 ;get mask in D4
BEQ ArithMask1
@0
MOVE.L (A1),D5 ;get dest longword
CMP.L #-1,D3 ;mask all ones?
BNE.S ArithMapIt1A ;if not, can't use cache
CMP.L D5,D6 ;same as last time?
BNE.S ArithMapIt1 ;if not, skip
; the long was the same as last time, so we can skip the mapping. Better make sure
; the mask was the same, too
MOVE.L D1,D5 ;use last result
BRA ArithStoreIt ;skip the mapping
; it was different, so we have to map it the hard way
ArithMapIt1
MOVE.L D5,D6 ;remember for next time
ArithMapIt1A
TST.B D3
BEQ.S @0 ;if mask zero, we can skip
MOVE.B D4,D7
LEA 0(A3,D7.W*8),A4 ;point to source color
MOVE.B D5,D7
LEA 0(A3,D7.W*8),A5 ;point to dest color
JSR (A0) ;map according to Xfer mode
MOVE.B ([INVCOLOR,A6],D0.W,6),D5 ;look up in inverse table
@0
ROR.L #8,D3
ROR.L #8,D4
ROR.L #8,D5
; map 2nd byte
TST.B D3
BEQ.S @2 ;if mask zero, we can skip
MOVE.B D4,D7
LEA 0(A3,D7.W*8),A4 ;point to source color
MOVE.B D5,D7
LEA 0(A3,D7.W*8),A5 ;point to dest color
JSR (A0) ;map according to Xfer mode
MOVE.B ([INVCOLOR,A6],D0.W,6),D5 ;look up in inverse table
@2
ROR.L #8,D3
ROR.L #8,D4
ROR.L #8,D5
; map 3rd byte
TST.B D3
BEQ.S @4 ;if mask zero, we can skip
; map it
MOVE.B D4,D7
LEA 0(A3,D7.W*8),A4 ;point to source color
MOVE.B D5,D7
LEA 0(A3,D7.W*8),A5 ;point to dest color
JSR (A0) ;map according to Xfer mode
MOVE.B ([INVCOLOR,A6],D0.W,6),D5 ;look up in inverse table
@4
ROR.L #8,D3
ROR.L #8,D4
ROR.L #8,D5
; map final byte
TST.B D3
BEQ.S @6 ;if mask zero, we can skip
; it's different than the last one, so map it
MOVE.B D4,D7
LEA 0(A3,D7.W*8),A4 ;point to source color
MOVE.B D5,D7
LEA 0(A3,D7.W*8),A5 ;point to dest color
JSR (A0) ;map according to Xfer mode
MOVE.B ([INVCOLOR,A6],D0.W,6),D5 ;look up in inverse table
@6
ROR.L #8,D4
ROR.L #8,D5
; it's all mapped, so store the result
ArithStoreIt
MOVE.L D5,(A1)+ ;store the destination
ADDQ.L #1,D3 ;was mask all ones?
BNE.S ArithCom1 ;if not, skip
MOVE.L D5,D1 ;remember last result
ArithCom1
MOVEQ #-1,D3 ;set up the mask for the middle
SUBQ #1,D2
ArithBot1
BGT ArithLoop1
BEQ ArithRight1
; all done with this scan line
RTS
; handle a region of all zeros
ArithMask1
ADDQ #4,A1 ;skip over destination
BRA.S ArithCom1
; Here is the handler for the AddOver mode. A4 points to the source RGBColor, while
; A5 points to the destination. Return the index in D0 (to be looked up in the
; inverse table). First there is a case table for using a static shift count
AddOverHandler
DC.W AddOver3-AddOverHandler
DC.W AddOver4-AddOverHandler
DC.W AddOver5-AddOverHandler
AddOver3
MOVEQ #0,D0
MOVE.W (A4)+,D0 ;red
ADD.W (A5)+,D0
LSL.L #3,D0
MOVE.W (A4)+,D0 ;green
ADD.W (A5)+,D0
LSL.L #3,D0
MOVE.W (A4),D0 ;blue
ADD.W (A5),D0
LSL.L #3,D0
SWAP D0 ;return inverse table index
RTS
AddOver4
MOVEQ #0,D0
MOVE.W (A4)+,D0 ;red
ADD.W (A5)+,D0
LSL.L #4,D0
MOVE.W (A4)+,D0 ;green
ADD.W (A5)+,D0
LSL.L #4,D0
MOVE.W (A4),D0 ;blue
ADD.W (A5),D0
LSL.L #4,D0
SWAP D0 ;return inverse table index
RTS
AddOver5
MOVEQ #0,D0
MOVE.W (A4)+,D0 ;red
ADD.W (A5)+,D0
LSL.L #5,D0
MOVE.W (A4)+,D0 ;green
ADD.W (A5)+,D0
LSL.L #5,D0
MOVE.W (A4),D0 ;blue
ADD.W (A5),D0
LSL.L #5,D0
SWAP D0 ;return inverse table index
RTS
;*************************************************************************************
; Here is the receiver for the SubOver arithmetic fill mode, for ovals and roundRects.
; It uses mainly common code with the other oval handlers
;>>>>>>>>>>>
SubOverFillO
slSubOver8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BEQ.S @0 ;if not, skip <S433>
JMPRom Old38E ; <S433>
endif
; OK, first do the pattern setup
@0 MOVE.L A0,A3 ;set up pattern base
LEA SubOverHandler,A0 ;use subOver
BRA DoArithMode
; Here is the handler for the SubOver mode. A4 points to the source RGBColor, while
; A5 points to the destination. Return the index in D0 (to be looked up in the
; inverse table). First there is a case table for using a static shift count
SubOverHandler
DC.W SubOver3-SubOverHandler
DC.W SubOver4-SubOverHandler
DC.W SubOver5-SubOverHandler
SubOver3
MOVEQ #0,D0
MOVE.W (A5)+,D0 ;red
SUB.W (A4)+,D0
LSL.L #3,D0
MOVE.W (A5)+,D0 ;red
SUB.W (A4)+,D0
LSL.L #3,D0
MOVE.W (A5)+,D0 ;red
SUB.W (A4)+,D0
LSL.L #3,D0
SWAP D0 ;return inverse table index
RTS
SubOver4
MOVEQ #0,D0
MOVE.W (A5)+,D0 ;red
SUB.W (A4)+,D0
LSL.L #4,D0
MOVE.W (A5)+,D0 ;red
SUB.W (A4)+,D0
LSL.L #4,D0
MOVE.W (A5)+,D0 ;red
SUB.W (A4)+,D0
LSL.L #4,D0
SWAP D0 ;return inverse table index
RTS
SubOver5
MOVEQ #0,D0
MOVE.W (A5)+,D0 ;red
SUB.W (A4)+,D0
LSL.L #5,D0
MOVE.W (A5)+,D0 ;red
SUB.W (A4)+,D0
LSL.L #5,D0
MOVE.W (A5)+,D0 ;red
SUB.W (A4)+,D0
LSL.L #5,D0
SWAP D0 ;return inverse table index
RTS
;*************************************************************************************
; Here is the receiver for the AddPin arithmetic fill mode, for ovals and roundRects.
; It uses mainly common code with the other oval handlers
;>>>>>>>>>>>
AddPinFillO
slAddPin8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BEQ.S @0 ;if not, skip <S433>
JMPRom Old389 ; <S433>
endif
; set up handlers and use common code
@0 MOVE.L A0,A3 ;set up pattern base
LEA AddPinHandler,A0 ;use addPin
BRA DoArithMode
; Here is the handler for the AddPin mode. A4 points to the source RGBColor, while
; A5 points to the destination. Return the index in D0 (to be looked up in the
; inverse table). First there is a case table for using a static shift count
AddPinHandler
DC.W AddPin3-AddPinHandler
DC.W AddPin4-AddPinHandler
DC.W AddPin5-AddPinHandler
AddPin3
MOVEQ #0,D0
MOVE.W (A4)+,D0 ;red
ADD.W (A5)+,D0
BCS.S @0
CMP.W WEIGHT+BLUE(A6),D0
BLS.S @1
@0
MOVE.W WEIGHT+BLUE(A6),D0
@1
LSL.L #3,D0
MOVE.W (A4)+,D0 ;green
ADD.W (A5)+,D0
BCS.S @2
CMP.W WEIGHT+GREEN(A6),D0
BLS.S @3
@2
MOVE.W WEIGHT+GREEN(A6),D0
@3
LSL.L #3,D0
MOVE.W (A4),D0 ;blue
ADD.W (A5),D0
BCS.S @4
CMP.W WEIGHT+RED(A6),D0
BLS.S @5
@4
MOVE.W WEIGHT+RED(A6),D0
@5
LSL.L #3,D0
SWAP D0 ;return inverse table index
RTS
AddPin4
MOVEQ #0,D0
MOVE.W (A4)+,D0 ;red
ADD.W (A5)+,D0
BCS.S @0
CMP.W WEIGHT+BLUE(A6),D0
BLS.S @1
@0
MOVE.W WEIGHT+BLUE(A6),D0
@1
LSL.L #4,D0
MOVE.W (A4)+,D0 ;green
ADD.W (A5)+,D0
BCS.S @2
CMP.W WEIGHT+GREEN(A6),D0
BLS.S @3
@2
MOVE.W WEIGHT+GREEN(A6),D0
@3
LSL.L #4,D0
MOVE.W (A4),D0 ;blue
ADD.W (A5),D0
BCS.S @4
CMP.W WEIGHT+RED(A6),D0
BLS.S @5
@4
MOVE.W WEIGHT+RED(A6),D0
@5
LSL.L #4,D0
SWAP D0 ;return inverse table index
RTS
AddPin5
MOVEQ #0,D0
MOVE.W (A4)+,D0 ;red
ADD.W (A5)+,D0
BCS.S @0
CMP.W WEIGHT+BLUE(A6),D0
BLS.S @1
@0
MOVE.W WEIGHT+BLUE(A6),D0
@1
LSL.L #5,D0
MOVE.W (A4)+,D0 ;green
ADD.W (A5)+,D0
BCS.S @2
CMP.W WEIGHT+GREEN(A6),D0
BLS.S @3
@2
MOVE.W WEIGHT+GREEN(A6),D0
@3
LSL.L #5,D0
MOVE.W (A4),D0 ;blue
ADD.W (A5),D0
BCS.S @4
CMP.W WEIGHT+RED(A6),D0
BLS.S @5
@4
MOVE.W WEIGHT+RED(A6),D0
@5
LSL.L #5,D0
SWAP D0 ;return inverse table index
RTS
;*************************************************************************************
; Here is the receiver for the SubPin arithmetic fill mode, for ovals and roundRects.
; It uses mainly common code with the other oval handlers
;>>>>>>>>>>>
SubPinFillO
slSubPin8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BEQ.S @0 ;if not, skip <S433>
JMPRom Old38B ; <S433>
endif
; set up handlers and use common code
@0 MOVE.L A0,A3 ;set up pattern base
LEA SubPinHandler,A0 ;use SubPin
BRA DoArithMode
; Here is the handler for the SubPin mode. A4 points to the source RGBColor, while
; A5 points to the destination. Return the index in D0 (to be looked up in the
; inverse table). First there is a case table for using a static shift count
SubPinHandler
DC.W SubPin3-SubPinHandler
DC.W SubPin4-SubPinHandler
DC.W SubPin5-SubPinHandler
SubPin3
MOVEQ #0,D0
MOVE.W (A5)+,D0 ;red
SUB.W (A4)+,D0
BCS.S @0
CMP.W WEIGHT+BLUE(A6),D0
BCC.S @1
@0
MOVE.W WEIGHT+BLUE(A6),D0
@1
LSL.L #3,D0
MOVE.W (A5)+,D0 ;red
SUB.W (A4)+,D0
BCS.S @2
CMP.W WEIGHT+GREEN(A6),D0
BCC.S @3
@2
MOVE.W WEIGHT+GREEN(A6),D0
@3
LSL.L #3,D0
MOVE.W (A5)+,D0 ;red
SUB.W (A4)+,D0
BCS.S @4
CMP.W WEIGHT+RED(A6),D0
BCC.S @5
@4
MOVE.W WEIGHT+RED(A6),D0
@5
LSL.L #3,D0
SWAP D0 ;return inverse table index
RTS
SubPin4
MOVEQ #0,D0
MOVE.W (A5)+,D0 ;red
SUB.W (A4)+,D0
BCS.S @0
CMP.W WEIGHT+BLUE(A6),D0
BCC.S @1
@0
MOVE.W WEIGHT+BLUE(A6),D0
@1
LSL.L #4,D0
MOVE.W (A5)+,D0 ;red
SUB.W (A4)+,D0
BCS.S @2
CMP.W WEIGHT+GREEN(A6),D0
BCC.S @3
@2
MOVE.W WEIGHT+GREEN(A6),D0
@3
LSL.L #4,D0
MOVE.W (A5)+,D0 ;red
SUB.W (A4)+,D0
BCS.S @4
CMP.W WEIGHT+RED(A6),D0
BCC.S @5
@4
MOVE.W WEIGHT+RED(A6),D0
@5
LSL.L #4,D0
SWAP D0 ;return inverse table index
RTS
SubPin5
MOVEQ #0,D0
MOVE.W (A5)+,D0 ;red
SUB.W (A4)+,D0
BCS.S @0
CMP.W WEIGHT+BLUE(A6),D0
BCC.S @1
@0
MOVE.W WEIGHT+BLUE(A6),D0
@1
LSL.L #5,D0
MOVE.W (A5)+,D0 ;red
SUB.W (A4)+,D0
BCS.S @2
CMP.W WEIGHT+GREEN(A6),D0
BCC.S @3
@2
MOVE.W WEIGHT+GREEN(A6),D0
@3
LSL.L #5,D0
MOVE.W (A5)+,D0 ;red
SUB.W (A4)+,D0
BCS.S @4
CMP.W WEIGHT+RED(A6),D0
BCC.S @5
@4
MOVE.W WEIGHT+RED(A6),D0
@5
LSL.L #5,D0
SWAP D0 ;return inverse table index
RTS
;*************************************************************************************
; Here is the receiver for the AddMax arithmetic fill mode, for ovals and roundRects.
; It uses mainly common code with the other oval handlers
;>>>>>>>>>>>
AddMaxFillO
slMax8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BEQ.S @0 ;if not, skip <S433>
JMPRom Old38D ; <S433>
endif
; OK, first do the pattern setup
@0 MOVE.L A0,A3 ;set up pattern base
LEA AddMaxHandler,A0 ;use AddMax
BRA DoArithMode
; Here is the handler for the AddMax mode. A4 points to the source RGBColor, while
; A5 points to the destination. Return the index in D0 (to be looked up in the
; inverse table). First there is a case table for using a static shift count
AddMaxHandler
DC.W AddMax3-AddMaxHandler
DC.W AddMax4-AddMaxHandler
DC.W AddMax5-AddMaxHandler
AddMax3
MOVEQ #0,D0
MOVE.W (A4)+,D0
CMP.W (A5),D0
BCC.S @0
MOVE.W (A5),D0
@0
ADDQ #2,A5
LSL.L #3,D0
MOVE.W (A4)+,D0
CMP.W (A5),D0
BCC.S @1
MOVE.W (A5),D0
@1
ADDQ #2,A5
LSL.L #3,D0
MOVE.W (A4)+,D0
CMP.W (A5),D0
BCC.S @2
MOVE.W (A5),D0
@2
ADDQ #2,A5
LSL.L #3,D0
SWAP D0 ;return inverse table index
RTS
AddMax4
MOVEQ #0,D0
MOVE.W (A4)+,D0
CMP.W (A5),D0
BCC.S @0
MOVE.W (A5),D0
@0
ADDQ #2,A5
LSL.L #4,D0
MOVE.W (A4)+,D0
CMP.W (A5),D0
BCC.S @1
MOVE.W (A5),D0
@1
ADDQ #2,A5
LSL.L #4,D0
MOVE.W (A4)+,D0
CMP.W (A5),D0
BCC.S @2
MOVE.W (A5),D0
@2
ADDQ #2,A5
LSL.L #4,D0
SWAP D0 ;return inverse table index
RTS
AddMax5
MOVEQ #0,D0
MOVE.W (A4)+,D0
CMP.W (A5),D0
BCC.S @0
MOVE.W (A5),D0
@0
ADDQ #2,A5
LSL.L #5,D0
MOVE.W (A4)+,D0
CMP.W (A5),D0
BCC.S @1
MOVE.W (A5),D0
@1
ADDQ #2,A5
LSL.L #5,D0
MOVE.W (A4)+,D0
CMP.W (A5),D0
BCC.S @2
MOVE.W (A5),D0
@2
ADDQ #2,A5
LSL.L #5,D0
SWAP D0 ;return inverse table index
RTS
;*************************************************************************************
; Here is the receiver for the AddMin arithmetic fill mode, for ovals and roundRects.
; It uses mainly common code with the other oval handlers
;>>>>>>>>>>>
AddMinFillO
slMin8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BEQ.S @0 ;if not, skip <S433>
JMPRom Old38F ; <S433>
endif
; OK, first do the pattern setup
@0 MOVE.L A0,A3 ;set up pattern base
LEA AddMinHandler,A0 ;use addMin
BRA DoArithMode
; Here is the handler for the AddMin mode. A4 points to the source RGBColor, while
; A5 points to the destination. Return the index in D0 (to be looked up in the
; inverse table). First there is a case table for using a static shift count
AddMinHandler
DC.W AddMin3-AddMinHandler
DC.W AddMin4-AddMinHandler
DC.W AddMin5-AddMinHandler
AddMin3
MOVEQ #0,D0
MOVE.W (A4)+,D0
CMP.W (A5),D0
BLS.S @0
MOVE.W (A5),D0
@0
ADDQ #2,A5
LSL.L #3,D0
MOVE.W (A4)+,D0
CMP.W (A5),D0
BLS.S @1
MOVE.W (A5),D0
@1
ADDQ #2,A5
LSL.L #3,D0
MOVE.W (A4)+,D0
CMP.W (A5),D0
BLS.S @2
MOVE.W (A5),D0
@2
ADDQ #2,A5
LSL.L #3,D0
SWAP D0 ;return inverse table index
RTS
AddMin4
MOVEQ #0,D0
MOVE.W (A4)+,D0
CMP.W (A5),D0
BLS.S @0
MOVE.W (A5),D0
@0
ADDQ #2,A5
LSL.L #4,D0
MOVE.W (A4)+,D0
CMP.W (A5),D0
BLS.S @1
MOVE.W (A5),D0
@1
ADDQ #2,A5
LSL.L #4,D0
MOVE.W (A4)+,D0
CMP.W (A5),D0
BLS.S @2
MOVE.W (A5),D0
@2
ADDQ #2,A5
LSL.L #4,D0
SWAP D0 ;return inverse table index
RTS
AddMin5
MOVEQ #0,D0
MOVE.W (A4)+,D0
CMP.W (A5),D0
BLS.S @0
MOVE.W (A5),D0
@0
ADDQ #2,A5
LSL.L #5,D0
MOVE.W (A4)+,D0
CMP.W (A5),D0
BLS.S @1
MOVE.W (A5),D0
@1
ADDQ #2,A5
LSL.L #5,D0
MOVE.W (A4)+,D0
CMP.W (A5),D0
BLS.S @2
MOVE.W (A5),D0
@2
ADDQ #2,A5
LSL.L #5,D0
SWAP D0 ;return inverse table index
RTS
;*************************************************************************************
; Here is the receiver for the blend arithmetic fill mode, for ovals and roundRects.
; It uses mainly common code with the other oval handlers
;>>>>>>>>>>>
BlendFillO
slAvg8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BEQ.S @0 ;if not, skip <S433>
JMPRom Old388 ; <S433>
endif
; OK, first do the pattern setup
@0 MOVE.L A0,A3 ;set up pattern base
LEA BlendHandler,A0 ;use blend
BRA DoArithMode
; Here is the handler for the Blend mode. A4 points to the source RGBColor, while
; A5 points to the destination. Return the index in D0 (to be looked up in the
; inverse table). First there is a case table for using a static shift count
BlendHandler
DC.W Blend3-BlendHandler
DC.W Blend4-BlendHandler
DC.W Blend5-BlendHandler
Blend3
MOVEM.L D1-D3,-(SP)
MOVEQ #3,D2 ;set up shift count
BRA.S BlendCommon
Blend4
MOVEM.L D1-D3,-(SP)
MOVEQ #4,D2
BlendCommon
MOVEQ #0,D0 ;clear accum reg
; do red
MOVE.W (A4)+,D1
MULU WEIGHT+BLUE(A6),D1
MOVE.W (A5)+,D3
MULU NOTWEIGHT+BLUE(A6),D3
ADD.L D1,D3
SWAP D3
MOVE.W D3,D0
ASL.L D2,D0
; do green
MOVE.W (A4)+,D1
MULU WEIGHT+GREEN(A6),D1
MOVE.W (A5)+,D3
MULU NOTWEIGHT+GREEN(A6),D3
ADD.L D1,D3
SWAP D3
MOVE.W D3,D0
ASL.L D2,D0
; do blue
MOVE.W (A4)+,D1
MULU WEIGHT+RED(A6),D1
MOVE.W (A5)+,D3
MULU NOTWEIGHT+RED(A6),D3
ADD.L D1,D3
SWAP D3
MOVE.W D3,D0
ASL.L D2,D0
SWAP D0
MOVEM.L (SP)+,D1-D3
RTS
Blend5
MOVEM.L D1-D3,-(SP)
MOVEQ #5,D2
BRA.S BlendCommon
;******************************************************************************************
; Now we start on the arithmetic fills for clipped rectangles. Use the common
; scan line handler for ovals/rrects to save code.
; First we handle AddOver mode
if patchciRom THEN
UseOld368
JMPROM Old368 ; <S433>
endif
;>>>>>>>>>>>
AddOverFillR
rAddOver8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BNE.S UseOld368 ;if not, skip
tst.l d3 ;right to left? <PB427 BAL>
bmi.s UseOld368 ;if so, skip <PB427 BAL>
endif
LEA AddOverHandler,A0 ;set up the handler
ArithFillCommon
MOVE.L A0,-(SP) ;remember handler address
; set up the registers and invoke the common scan-line handler
MOVE.L A4,A2 ;set up region pointer
ASR #3,D6 ;bit index to byte index
MOVE.L A5,A1 ;set up destination
ArithFillLoop
MOVEQ #-1,D1
MOVEQ #-1,D3 ;edge masks all ones (edges in region)
MOVE.W BUFSIZE(A6),D2 ;set up the count
ADDQ #4,D2 ;make one based <PB427 BAL>
LSR.W #2,D2
SUBQ #1,D2 ;make zero based <PB427 BAL>
MOVE.L (SP),A0 ;get handler address
; call the appropriate handle, depending on whether the pattern is simple or complex
CMP.W #8,PATROW(A6) ;is pattern real complex?
BGT.S @0 ;if so, go handle it
TST.B endSwitch(A6) ;test pattern mode
BMI.S @0 ;treat bitmap as complex
MOVE.L 0(A3,D6),D0 ;get left pattern
EOR #4,D6
CMP.L 0(A3,D6),D0 ;left same as right?
BEQ.S @1 ;if so, it's simple
EOR #4,D6 ;restore D6
@0
BSR ArithComplex1 ;invoke scan-line handler for complex pats
BRA.S @2
@1
EOR #4,D6
BSR ArithSimplePat
; bump pointers to next time, and loop until done
@2
MOVE.L patOffset(A6),D6 ;get pattern index
ASR.L #3,D6 ;bit index to byte index
moveq #0,d0 ;patPos should be a long
MOVE.W patPos(A6),D0
TST.B endSwitch(A6) ;test pattern mode
BEQ.S AFPat1 ;if zero, handle
BMI.S AFBitMap1 ;if <0, go handle bitmap
; handle bumping the pattern pointers
MOVE.L SRCADDR(A6),A3 ;set up pattern pointer
SUB.l D0,A3
ADD.W PATROW(A6),D0
AND.W PATVMASK(A6),D0
MOVE.W D0,patPos(A6)
ADD.l D0,A3
BRA.S AFSetPatPtr
; handle second type of pattern
AFPat1
ADDQ #1,D0
AND #15,D0
LEA ([EXPAT,A6],D0.W*4),A3
MOVE.W D0,patPos(A6)
AFSetPatPtr
MOVE.L A3,SRCADDR(A6)
; bump to the next scan line
ArithFillNextLine
MOVE.L DSTROW(A6),D0
ADD.L D0,DSTADDR(A6)
MOVE.W VERT(A6),D0
ADD.W VBUMP(A6),D0
MOVE.W D0,VERT(A6)
CMP.W LASTV(A6),D0
BNE.S @0
; all done, so strip stack and return
MOVE.L SAVESTK2(A6),A7
RTS
; set up registers and loop for the next line
@0
MOVE.L SEEKMASK(A6),A0
JSR (A0) ;seek new region
MOVE.L SRCADDR(A6),A3 ;set up pattern pointer
MOVE.L DSTADDR(A6),A1 ;set up dest ptr
MOVE.L RGNADDR(A6),A2 ;set up region ptr
BRA ArithFillLoop
; handle bumping the source if it's a bitmap
AFBitMap1
MOVE.L SRCROW(A6),D0
ADD.L D0,SRCADDR(A6)
BRA.S ArithFillNextLine
;******************************************************************************************
; Handle SubOver clipped rectangle fill
if patchciRom THEN
UseOld36C
JMPRom Old36C ; <PB433>
endif
;>>>>>>>>>>>
SubOverFillR
rSubOver8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BNE.S UseOld36C ;if not, skip
tst.l d3 ;right to left? <PB427 BAL>
bmi.s UseOld36c ;if so, skip <PB427 BAL>
endif
LEA SubOverHandler,A0 ;set up the handler
BRA ArithFillCommon ;use comon code
;******************************************************************************************
; Handle AddPin clipped rectangle fill
if patchciRom THEN
UseOld367
JMPRom Old367 ; <PB433>
endif
;>>>>>>>>>>>
AddPinFillR
rAddPin8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BNE.S UseOld367 ;if not, skip
tst.l d3 ;right to left? <PB427 BAL>
bmi.s UseOld367 ;if so, skip <PB427 BAL>
endif
LEA AddPinHandler,A0 ;set up the handler
BRA ArithFillCommon ;use comon code
;******************************************************************************************
; Handle SubPin clipped rectangle fill
if patchciRom THEN
UseOld369
JMPRom Old369 ; <PB433>
endif
;>>>>>>>>>>>
SubPinFillR
rSubPin8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BNE.S UseOld369 ;if not, skip
tst.l d3 ;right to left? <PB427 BAL>
bmi.s UseOld369 ;if so, skip <PB427 BAL>
endif
LEA SubPinHandler,A0 ;set up the handler
BRA ArithFillCommon ;use comon code
;******************************************************************************************
; Handle AddMax clipped rectangle fill
if patchciRom THEN
UseOld36B
JMPRom Old36B ; <PB433>
endif
;>>>>>>>>>>>
AddMaxFillR
rMax8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BNE.S UseOld36B ;if not, skip
tst.l d3 ;right to left? <PB427 BAL>
bmi.s UseOld36B ;if so, skip <PB427 BAL>
endif
LEA AddMaxHandler,A0 ;set up the handler
BRA ArithFillCommon ;use comon code
;******************************************************************************************
; Handle AddMin clipped rectangle fill
if patchciRom THEN
UseOld36D
JMPRom Old36D ; <PB433>
endif
;>>>>>>>>>>>
AddMinFillR
rMin8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BNE.S UseOld36D ;if not, skip
tst.l d3 ;right to left? <PB427 BAL>
bmi.s UseOld36D ;if so, skip <PB427 BAL>
endif
LEA AddMinHandler,A0 ;set up the handler
BRA ArithFillCommon ;use comon code
;******************************************************************************************
; Handle Blend clipped rectangle fill
if patchciRom THEN
UseOld366
JMPRom Old366 ; <PB433>
endif
;>>>>>>>>>>>
BlendFillR
rAvg8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BNE.S UseOld366 ;if not, skip
tst.l d3 ;right to left? <PB427 BAL>
bmi.s UseOld366 ;if s0, skip <PB427 BAL>
endif
LEA BlendHandler,A0 ;set up the handler
BRA ArithFillCommon ;use comon code
;******************************************************************************************
; Now we start on the arithmetic fills for unclipped rectangles. Use the common
; scan line handler for ovals/rrects to save code.
; First we handle AddOver mode, unclipped
if patchciRom THEN
UseOld352
JMPRom Old352 ; <PB433>
endif
;>>>>>>>>>>>
AddOverUnClip
bAddOver8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BNE.S UseOld352 ;if not, skip
tst.l (sp) ;right to left? <PB427 BAL>
bmi.s UseOld352 ;if so, skip <PB427 BAL>
endif
LEA AddOverHandler,A0 ;set up the handler
ArithUCCommon
MOVE.L A0,-(SP) ;remember handler address
; set up the registers and invoke the common scan-line handler
SUB.L A2,A2 ;no region pointer
ASR #3,D6 ;bit index to byte index
MOVE.L A4,A3 ;set up pattern pointer
MOVE.L A5,A1 ;set up destination
ArithUCLoop
MOVE.L FIRSTMASK(A6),D3 ;set up left edge
MOVE.L LASTMASK(A6),D1 ;set up right edge
; compute the count from the three pieces: left, mid and right
MOVE.W LONGCNT(A6),D2 ;get left count
BPL.S @3 ;if positive, we're cool
MOVEQ #0,D2 ;only one word
BRA.S @4
@3
ADD.W MIDCOUNT(A6),D2 ;add in the middle
ADD.W PIXINLONG(A6),D2 ;add in the right
ADDQ.W #2,D2 ;add for count bias
LSR.W #2,D2 ;bytes -> longs
@4
MOVE.L (SP),A0 ;get handler address
; call the appropriate handle, depending on whether the pattern is simple or complex
CMP.W #8,PATROW(A6) ;is pattern real complex?
BGT.S @0 ;if so, go handle it
TST.B ENDSWITCH(A6) ;test pattern mode
BMI.S @0 ;if bitmap, it's complex
MOVE.L 0(A3,D6),D0 ;get left pattern
EOR #4,D6
CMP.L 0(A3,D6),D0 ;left same as right?
BEQ.S @1 ;if so, it's simple
EOR #4,D6 ;restore D6
@0
MOVE.L A1,-(SP)
BSR ArithComplex1 ;invoke scan-line handler for complex pats
MOVE.L (SP)+,A1
BRA.S @2
@1
EOR #4,D6
MOVEM.L A1/A3,-(SP)
BSR ArithSimplePat
MOVEM.L (SP)+,A1/A3
; bump pointers to next time, and loop until done
@2
TST.B ENDSWITCH(A6) ;test pattern mode
BEQ.S AFUCPat1 ;if zero, handle
BMI.S AFUCBitMap1 ;if <0, go handle bitmap
; handle bumping the pattern pointers
moveq #0,d0 ;patPos should be a long
MOVE.W PATPOS(A6),D0
SUB.l D0,A3
ADD.W PATROW(A6),D0
AND.W PATVMASK(A6),D0
MOVE.W D0,PATPOS(A6)
ADD.l D0,A3
BRA.S ArithUCNextLine
; handle second type of pattern
AFUCPat1
MOVE.W PATPOS(A6),D0
ADDQ #1,D0
AND #15,D0
LEA ([EXPAT,A6],D0.W*4),A3
MOVE.W D0,PATPOS(A6)
; bump to the next scan line
ArithUCNextLine
MOVE.L PATOFFSET(A6),D6
ASR.L #3,D6 ;bits to bytes
ArithUCNL2
ADD.W DSTROW+2(A6),A1 ;bump destination
SUBQ.W #1,height(A6)
BNE ArithUCLoop
ADDQ #8,SP
RTS
; handle unclipped blits source setup
AFUCBitMap1
ADD.W D6,A3
ADD.W SRCBUMP(A6),A3 ;bump to next line <PB448 DBG>
MOVEQ #0,D6
BRA.S ArithUCNL2
;******************************************************************************************
; Handle SubOver unclipped rectangle fill
if patchciRom THEN
UseOld356
JMPRom Old356 ; <PB433>
endif
;>>>>>>>>>>>
SubOverUnclip
bSubOver8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BNE.S UseOld356 ;if not, skip
tst.l (sp) ;right to left? <PB427 BAL>
bmi.s UseOld356 ;if so, skip <PB427 BAL>
endif
LEA SubOverHandler,A0 ;set up the handler
BRA ArithUCCommon ;use comon code
;******************************************************************************************
; Handle AddPin unclipped rectangle fill
if patchciRom THEN
UseOld351
JMPRom Old351 ; <PB433>
endif
;>>>>>>>>>>>
AddPinUnclip
bAddPin8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BNE.S UseOld351 ;if not, skip
tst.l (sp) ;right to left? <PB427 BAL>
bmi.s UseOld351 ;if so, skip <PB427 BAL>
endif
LEA AddPinHandler,A0 ;set up the handler
BRA ArithUCCommon ;use comon code
;******************************************************************************************
; Handle SubPin unclipped rectangle fill
if patchciRom THEN
UseOld353
JMPRom Old353 ; <PB433>
endif
;>>>>>>>>>>>
SubPinUnclip
bSubPin8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BNE.S UseOld353 ;if not, skip
tst.l (sp) ;right to left? <PB427 BAL>
bmi.s UseOld353 ;if so, skip <PB427 BAL>
endif
LEA SubPinHandler,A0 ;set up the handler
BRA ArithUCCommon ;use comon code
;******************************************************************************************
; Handle AddMax unclipped rectangle fill
if patchciRom THEN
UseOld355
JMPRom Old355 ; <PB433>
endif
;>>>>>>>>>>>
AddMaxUnclip
bMax8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BNE.S UseOld355 ;if not, skip
tst.l (sp) ;right to left? <PB427 BAL>
bmi.s UseOld355 ;if so, skip <PB427 BAL>
endif
LEA AddMaxHandler,A0 ;set up the handler
BRA ArithUCCommon ;use comon code
;******************************************************************************************
; Handle AddMin unclipped rectangle fill
if patchciRom THEN
UseOld357
JMPRom Old357 ; <PB433>
endif
;>>>>>>>>>>>
AddMinUnclip
bMin8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BNE.S UseOld357 ;if not, skip
tst.l (sp) ;right to left? <PB427 BAL>
bmi.s UseOld357 ;if so, skip <PB427 BAL>
endif
LEA AddMinHandler,A0 ;set up the handler
BRA ArithUCCommon ;use comon code
;******************************************************************************************
; Handle Blend unclipped rectangle fill
if patchciRom THEN
UseOld350
JMPRom Old350 ; <PB433>
endif
;>>>>>>>>>>>
BlendUnclip
bAvg8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BNE.S UseOld350 ;if not, skip
tst.l (sp) ;right to left? <PB427 BAL>
bmi.s UseOld350 ;if so, skip <PB427 BAL>
endif
LEA BlendHandler,A0 ;set up the handler
BRA ArithUCCommon ;use comon code
;******************************************************************************************
; Here's where we handle transparent mode. The basic strategy is to create a mask from
; the pattern (for one and two long patterns) so we don't have to keep examining it
; pixel by pixel. (If the mask is all ones, fall into the standard fills).
; the first one is for transparent mode for ovals and roundRects
;>>>>>>>>>>>
TransFillO
slTransparent8
if patchciRom THEN
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BEQ.S @0 ;if not, skip
JMPRom Old38C ;
endif
@0 CMP.W #4,PATROW(A6) ;is it a simple pattern?
BGT.S TransComplexPat ;if not, inspect it closer
; it's a simple pattern, so make a mask according to the see-through color
TransSimple1
MOVE.L (A0),D6 ;fetch the pattern
MOVEQ #-1,D4 ;mask is initially all ones
MOVE.B TRANSCOLOR(A6),D5 ;get color to compare with
CMP.B D6,D5
BNE.S @0
CLR.B D4
@0
ROR.L #8,D4
ROR.L #8,D6
CMP.B D6,D5
BNE.S @1
CLR.B D4
@1
ROR.L #8,D4
ROR.L #8,D6
CMP.B D6,D5
BNE.S @2
CLR.B D4
@2
ROR.L #8,D4
ROR.L #8,D6
CMP.B D6,D5
BNE.S @3
CLR.B D4
@3
ROR.L #8,D4
ROR.L #8,D6
; if the mask is all ones, plot it quickly using the standard fill routine
MOVE.L A2,D0 ;if no clipping
BEQ.S @4 ;skip optimization (things not set up)
CMP.L #-1,D4 ;is mask all ones?
bne.s @4 ;no
jmp ([$E00+$380*4]) ;yes, use standard pattern fill
; OK, mask is in D4, A2 points to the region, pattern in D6 and A1 is the destination.
; use the straightforward loop, since region optimizations aren't worth it since we
; always have to read the destination.
@4
TST.W D2 ;only one long?
BNE.S TransSimpleLoop ;if not, skip
TSL0
AND.L D1,D3 ;combine edges for last one
TransSimpleLoop
MOVE.L A2,D0
BEQ.S @0
AND.L (A2)+,D3 ;pick up the region mask
@0
AND.L D4,D3 ;punch out transparent part
MOVE.L D6,D0
AND.L D3,D0
NOT.L D3
AND.L (A1),D3
OR.L D0,D3
MOVE.L D3,(A1)+
MOVEQ #-1,D3
SUBQ.W #1,D2 ;decrement counter
BGT.S TransSimpleLoop ;loop until done
BEQ.S TSL0
RTS
; see if the complex pattern is really a simple one, if so, we can speed things up
TransComplexPat
MOVE.W PATHPOS(A6),D6 ; <SMC 16Aug90>
ASR.W #3,D6 ;turn bits back into bytes <SMC 16Aug90>
ADD.W D0,D6 ; <SMC 16Aug90>
MOVE.W PATHMASK(A6),D4 ;get pattern mask
ASR #3,D4 ;turn bit index to byte index
AND.W D4,D6 ;mask it
MOVE.L EXPAT(A6),A3
ADD.l PATVPOS(A6),A3 ;compute pattern address
CMP.W #8,PATROW(A6) ;is it a double pattern?
BGT.S TransComplex1 ;if not, must be complex
MOVE.L 0(A3,D6),D4 ;get source longword
EOR #4,D6
CMP.L 0(A3,D6),D4 ;is it really simple?
BEQ TransSimple1 ;if so, go handle
EOR #4,D6 ;restore D6
TransComplex1
MOVE.L D7,-(SP)
MOVE.L TRANSCOLOR(A6),D5 ;get color to compare with
TST.W D2
BNE.S TCPatLoop
; it's complex, so plot it ourselves. First fetch the pattern.
TCPLoop0
AND.L D1,D3
TCPatLoop
MOVE.W PATHMASK(A6),D4 ;get pattern mask
ASR #3,D4 ;turn bit index to byte index
AND.W D4,D6 ;mask it
MOVE.L 0(A3,D6),D7 ;get source longword
ADDQ #4,D6
CMP.L D7,D5 ;all transparent?
BEQ.S TCPSkip
; now create a mask for it
MOVEQ #-1,D4 ;mask is initially all ones
CMP.B D7,D5
BNE.S @0
CLR.B D4
@0
ROR.L #8,D4
ROR.L #8,D7
CMP.B D7,D5
BNE.S @1
CLR.B D4
@1
ROR.L #8,D4
ROR.L #8,D7
CMP.B D7,D5
BNE.S @2
CLR.B D4
@2
ROR.L #8,D4
ROR.L #8,D7
CMP.B D7,D5
BNE.S @3
CLR.B D4
@3
ROR.L #8,D4
ROR.L #8,D7
; now we can finally plot it
MOVE.L A2,D0
BEQ.S @8
AND.L (A2)+,D3 ;pick up the region mask
@8
AND.L D4,D3 ;punch out transparent part
MOVE.L D7,D0
AND.L D3,D0
NOT.L D3
AND.L (A1),D3
OR.L D0,D3
MOVE.L D3,(A1)+
; loop until done
NextTCP
MOVEQ #-1,D3
SUBQ.W #1,D2 ;decrement counter
BGT.S TCPatLoop ;loop until done
BEQ.S TCPLoop0
MOVE.L (SP)+,D7
RTS
TCPSkip
MOVE.L A2,D0
BEQ.S @0
ADDQ.L #4,A2
@0
ADDQ #4,A1
BRA.S NextTCP
;******************************************************************************************
; Here's where we handle the clipped transparent mode rectangle fill
; if patchciRom THEN ;<SMC 08OCT90> <5>
if 0 THEN ;<SMC 08OCT90> <5>
UseOld36A
JMPRom Old36A ; <PB433>
endif
;>>>>>>>>>>>
TransFillR
rTransparent8
; if patchciRom THEN ;<SMC 08OCT90> <5>
if 0 THEN ;<SMC 08OCT90> <5>
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BNE.S UseOld36A ;if not, skip
tst.l d3 ;right to left? <PB427 BAL>
bmi.s UseOld36A ;if s0, skip <PB427 BAL>
endif
; set up the registers and invoke the common scan-line handler
MOVE.L A4,A2 ;set up region pointer
ASR #3,D6 ;bit index to byte index
MOVE.L A5,A1 ;set up destination
TransFillLoop
MOVEQ #-1,D1
MOVEQ #-1,D3 ;edge masks all ones (edges in region)
MOVE.W BUFSIZE(A6),D2 ;set up the count
ADDQ #4,D2 ;make one based <PB427 BAL>
LSR.W #2,D2
SUBQ #1,D2 ;make zero based <PB427 BAL>
; call the appropriate handle, depending on whether the pattern is simple or complex
CMP.W #8,PATROW(A6) ;is pattern real complex?
BGT.S @0 ;if so, go handle it
TST.B endSwitch(A6) ;test pattern mode
BMI.S @0 ;treat bitmap as complex
MOVE.L 0(A3,D6),D0 ;get left pattern
EOR #4,D6
CMP.L 0(A3,D6),D0 ;left same as right?
BEQ.S @1 ;if so, it's simple
EOR #4,D6 ;restore D6
@0
BSR TransComplex1 ;invoke scan-line handler for complex pats
BRA.S @2
@1
EOR #4,D6
MOVE.L A3,A0
BSR TransSimple1
; bump pointers to next time, and loop until done
@2
moveq #0,d0 ;patPos should be a long
MOVE.W patPos(A6),D0
TST.B endSwitch(A6) ;test pattern mode
BEQ.S TransPat1 ;if zero, handle
BMI.S TransBitMap1 ;if <0, go handle bitmap
MOVE.L patOffset(A6),D6 ;get pattern index
ASR.L #3,D6 ;bit index to byte index
; handle bumping the pattern pointers
MOVE.L SRCADDR(A6),A3 ;set up pattern pointer
SUB.l D0,A3
ADD.W PATROW(A6),D0
AND.W PATVMASK(A6),D0
MOVE.W D0,patPos(A6)
ADD.l D0,A3
BRA.S TransSetPatPtr
; handle second type of pattern
TransPat1
MOVE.L patOffset(A6),D6 ;get pattern index
ASR.L #3,D6 ;bit index to byte index
ADDQ #1,D0
AND #15,D0
LEA ([EXPAT,A6],D0.W*4),A3
MOVE.W D0,patPos(A6)
TransSetPatPtr
MOVE.L A3,SRCADDR(A6)
; bump to the next scan line
TransFillNextLine
MOVE.L DSTROW(A6),D0
ADD.L D0,DSTADDR(A6)
MOVE.W VERT(A6),D0
ADD.W VBUMP(A6),D0
MOVE.W D0,VERT(A6)
CMP.W LASTV(A6),D0
BNE.S @0
; all done, so strip stack and return
MOVE.L SAVESTK2(A6),A7
RTS
; set up registers and loop for the next line
@0
MOVE.L SEEKMASK(A6),A0
JSR (A0) ;seek new region
MOVE.L SRCADDR(A6),A3 ;set up pattern pointer
MOVE.L DSTADDR(A6),A1 ;set up dest ptr
MOVE.L RGNADDR(A6),A2 ;set up region ptr
BRA TransFillLoop
; handle bumping the source if it's a bitmap
TransBitMap1
MOVE.L SRCROW(A6),D0
;<PB427 BAL>
ADD.L D0,SRCADDR(A6)
MOVE.l patOffset(A6),D6
asr.l #3,d6 ;make byte offset <PB427 BAL>
BRA.S TransFillNextLine
;******************************************************************************************
; if patchciRom THEN ;<SMC 08OCT90> <5>
if 0 THEN ;<SMC 08OCT90> <5>
UseOld354
JMPRom Old354 ; <PB433>
endif
;>>>>>>>>>>>
TransUnClip
bTransparent8
; if patchciRom THEN ;<SMC 08OCT90> <5>
if 0 THEN ;<SMC 08OCT90> <5>
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;is it 8 bit mode?
BNE.S UseOld354 ;if not, skip
tst.l (sp) ;right to left? <PB427 BAL>
bmi.s UseOld354 ;if so, skip <PB427 BAL>
endif
; set up the registers and invoke the common scan-line handler
SUB.L A2,A2 ;no region pointer
ASR #3,D6 ;bit index to byte index
MOVE.L A4,A3 ;set up pattern pointer
MOVE.L A5,A1 ;set up destination
TransUCLoop
MOVE.L FIRSTMASK(A6),D3 ;set up left edge
MOVE.L LASTMASK(A6),D1 ;set up right edge
; compute the count from the three pieces: left, mid and right
MOVE.W LONGCNT(A6),D2 ;get left count
BPL.S @3 ;if positive, we're cool
MOVEQ #0,D2 ;only one word
BRA.S @4
@3
ADD.W MIDCOUNT(A6),D2 ;add in the middle
ADD.W PIXINLONG(A6),D2 ;add in the right
ADDQ.W #2,D2 ;add for count bias
LSR.W #2,D2 ;bytes -> longs
; call the appropriate handle, depending on whether the pattern is simple or complex
@4
CMP.W #8,PATROW(A6) ;is pattern real complex?
BGT.S @0 ;if so, go handle it
TST.B ENDSWITCH(A6) ;test pattern mode
BMI.S @0 ;if bitmap, handle as complex
MOVE.L 0(A3,D6),D0 ;get left pattern
EOR #4,D6
CMP.L 0(A3,D6),D0 ;left same as right?
BEQ.S @1 ;if so, it's simple
EOR #4,D6 ;restore D6
@0
MOVE.L A1,-(SP)
BSR TransComplex1 ;invoke scan-line handler for complex pats
MOVE.L (SP)+,A1
BRA.S @2
@1
EOR #4,D6
MOVEM.L A1/A3,-(SP)
MOVE.L A3,A0
BSR TransSimple1
MOVEM.L (SP)+,A1/A3
; bump pointers to next time, and loop until done
@2
TST.B ENDSWITCH(A6) ;test pattern mode
BEQ.S TransUCPat1 ;if zero, handle
BMI.S TransUCBitMap1 ;if <0, go handle bitmap
; handle bumping the pattern pointers
moveq #0,d0 ;patPos should be a long
MOVE.W PATPOS(A6),D0
SUB.l D0,A3
ADD.W PATROW(A6),D0
AND.W PATVMASK(A6),D0
MOVE.W D0,PATPOS(A6)
ADD.l D0,A3
BRA.S TransUCNextLine
; handle second type of pattern
TransUCPat1
MOVE.W PATPOS(A6),D0
ADDQ #1,D0
AND #15,D0
LEA ([EXPAT,A6],D0.W*4),A3
MOVE.W D0,PATPOS(A6)
; bump to the next scan line
TransUCNextLine
MOVE.L PATOFFSET(A6),D6
ASR.L #3,D6 ;bits to bytes
TransUCNL2
ADD.W DSTROW+2(A6),A1 ;bump destination
SUBQ.W #1,height(A6)
BNE TransUCLoop
ADDQ #4,SP
RTS
; handle unclipped blits source setup
TransUCBitMap1
ADD.W D6,A3
ADD.W SRCBUMP(A6),A3 ;bump to next line <PB448 DBG>
MOVEQ #0,D6
BRA.S TransUCNL2
;******************************************************************************************
; End of arithmetic transfer modes!
;******************************************************************************************
ENDPROC