mac-rom/QuickDraw/Stretch.a
Elliot Nunn 9c249dafab Reverse 68k Color QuickDraw
The ROM now round-trips with QuickDraw mostly built from source.
(~30% of the ROM is now built from source.)
2017-12-26 09:52:55 +08:00

12035 lines
362 KiB
Plaintext
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;
; File: Stretch.a
;
; Copyright: © 1981-1993 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <SM5> 9/12/93 SAM Changed all instances of _Translate24to32 to _rTranslate24to32
; so they can coditionalized out of the build.
; <SM4> 7/16/92 CSS Update from Reality:
; <66> 6/25/92 SAH #1033729: Fixed a bug where we don't always recognize when we're
; drawing to the alpha channel (just before calling ScaleBlt). We
; now do this correctly and take Stretch if drawing alpha,
; otherwise take the faster loops in ScaleBlt (which zero out the
; alpha channel).
; <65> 6/10/92 SAH Fixed a problem where we would defer to stretch if ScaleBlt did
; not hande the copy and the src was greater than one bits deep.
; This was causing crashes with Aldus Freehand and Macromind
; Director. Also fixed a problem where Stretch would munge
; StkLowPt, HieHeapMark and your stack in low-memory situations.
; <64> 6/8/92 SAH #1031825: Brought the ScaleBlt loops back to life. Now use
; ScaleBlt for indexed to direct (16 and 32) as well as indexed to
; indexed. Make use of new srcBlackWhiteOnly flag to enable us to
; use BitBlt when this is set and the src and dst are the same
; depths. Check to see if we need to change ScaleColor to
; ColorizeInModeCase if ScaleBlt fails. Also, test if using an
; alpha mode before calling ScaleBlt, in which case we take
; stretch.
; <SM3> 6/11/92 stb <sm 6/9/92>stb Synch with QDciPatchROM.a; added comments to
; StretchBits, MapModeTable, SRCONE, stNoStack, stMask0,
; stMASK0Slow, stHilite, arith. transfer loops for 16 & 32
; bits/pixel, OneColor, DoubleColor, QUADColor, EightLoop,
; BWtoD15Alpha, BWtoD24Alpha, AverageH16, Dither32toIndexed,
; Dither16toIndexed, Dither32toGray, Dither16toGray,
; Dither16toBitmap, Search32to32, Search32toInd, SeedCFill32,
; Search32to16, Search16toIndexed, SeedCFill16, Search16to32,
; Search16to16.
; <63> 5/5/92 SAH Put fix for clipped vertical stretch back in for Cube-E
; <62> 1/15/92 KC Fix "Short branch to the next instruction changed to a NOP"
; assembler warning.
; <61> 10/4/91 JSM Change PsychoticFarmerOrLater conditionals to TheFuture.
; <60> 10/2/91 DTY Conditionalise last changes for TheFuture.
; <59> 10/2/91 KON Fix bug where CopyBits was crashing when vertically stretching a
; pixmap that is clipped at the top.
; <58> 10/2/91 KON Save and restore stklowPt (rather than just setting it to sp on
; exit) in stretch. This fixes a bug where someone turns off the
; stack sniffer and then calls stretch which turns it back on.
; Also, abort picture playback when QDError = AbortPicPlayBackErr.
; <57> 10/2/91 KON Save and restore stklowPt (rather than just setting it to sp on
; exit) in stretch. This fixes a bug where someone turns off the
; stack sniffer and then calls stretch which turns it back on.
; Abort picture playback when QDError = AbortPicPlayBackErr.
; <56> 9/13/91 DTY Conditionalise previous change so it doesnÕt get built for
; CubeE. (ItÕll get built for PsychoticFarmerAndLater.) Move in
; code that was taken out between <54> and <55>, and build it for
; CubeE only.
; <55> 7/23/91 KON Speed up indexed to 32-bit srcCopy mode. Speed up colorized
; text: don't take scale case when depths are the same.
; <54> 3/19/91 KON DTY, WRKSHT#SAH-QD-055: Some pixmaps created with an old version
; of ResEdit had the high bit of pmVersion set. This causes the
; pmVersion macro to crash, so I removed it.
; <53> 3/18/91 KON GSC and JT: WKSHT# SAH-QD-054 16-bit source shrinks crash
; because the average buffer is calculated from the promoted
; depth, rather than the real depth.
; <52> 3/6/91 KON CEL: BRC# 84369 Register D0 was getting trashed when search
; procs were attached to direct destinations. Also, color
; calculation for 16-bits was incorrect when search proc is
; installed.
; <51> 2/19/91 KON DDG: WorkSheet #KS-003, MaskAddr in stackframe is not
; initialized if there is not a mask. This was causing crashes in
; some cases since verticle merge scanline routines look at the
; maskaddr.
; <50> 1/25/91 KON DDG: BRC# 81625, A fix in QDciPatchROM.a required reorganizing
; part of stretch. This change keeps the files in synchronization.
; <49> 1/23/91 KON Optimize and clean up code that was rushed for B4. [SMC]
; <48> 1/14/91 KON Fix PixMaps with nil color tables and CopyDeepMask with 1-bit
; mask. Fix bug in pmVersion macro. [SMC]
; <47> 1/11/91 KON Register was getting trashed around call to SeekMask. This
; caused CopyBits with more 3 regions to get trashed as in the
; KeyCaps CDEV. [DDG]
; <46> 12/17/90 KON Fix one of the problems with NIL color tables. [smc]
; <45> 11/26/90 SMC Fixed pattern hilite once and for all, and forced arithmetic
; transfers to direct devices into rgnblt instead of the slower
; loops in bitblt. With BAL.
; <44> 11/12/90 KON Fix problem with colorizing when dithering from an indexed src
; to an indexed destination. [smc]
; <43> 11/9/90 KON Copy rectangles to local stack and fixed problems with negative
; pmVersions.
; <42> 10/31/90 SMC Fixed alpha channel bugs with BAL.
; <41> 9/25/90 KON If source is 1-bit black and white and we are not shrinking,
; clear dither bit. (With SMC).
; <40> 9/18/90 SMC Fix transparent, addMax, subOver, and addMin transfers with a
; pattern.
; <39> 9/18/90 BG Removed <25>. 040s are behaving more reliably now.
; <38> 9/14/90 SMC Commented out all of the QuickerDraw routines and changed the
; logic to send those cases through ScaleBlt which are now faster
; and smaller (by about 1K). This implicitly fixes a bus error
; problem under AU/X when scaling from a 1-bit screen to the left
; edge of an 8-bit screen.
; <37> 9/13/90 KON NEEDED FOR BETA: Fix problem where promoting source to RGB is
; messed up. This showed up when the source is 1-bit. Also fixed
; in QDciPatchROM.a.
; <36> 9/10/90 KON Fixed one-bit to one-bit colorized copy.
; <35> 9/6/90 KON Fix 16 to indexed search loop.
; <34> 9/5/90 KON Fix copymask from an indexed src. The pmtable was not set
; correctly.
; <33> 9/4/90 KON fix problem where ctseed for 1-bit sources was getting trashed.
; If direct destination and search proc installed, use versions of
; fg and bg colors which have not been changed by the proc to do
; colorizing.
; <32> 8/26/90 KON Fix Search16to32 and Search32to16 stack frame referencing. Add
; 32-bit clean versions of MaskPixPmTable and SrcPixPmTable to
; stack frame.
; <31> 8/21/90 KON Always call search proc if one exists. If search proc fails,
; still use search procs RGBColor. Replicate bits when passing
; 16-bit source color to search procs.
; <30> 8/15/90 KON Fixed transparent mode which was writing outside the destination
; rectangle. Turned off colorizing for arithmetic modes.
; <29> 7/23/90 KON Fix CopyMask in cases where left and right edge are displaying
; garbage.
; <28> 7/20/90 gbm Change some identifiers to avoid assembly conflicts
; <27> 7/17/90 KON Fix 16-bit source notCopy mode.
; <26> 7/10/90 KON Fixed CopyMask for 16-bit sources, and cases where 16-bit masks
; were failing. Also fixed vertical shrinking of 1-bit sources.
; <26> 7/9/90 KON Fixed CopyMask for 16-bit sources, and cases where16-bit masks
; were failing.
; <25> 6/28/90 BG Added EclipseNOPs for flakey 040s.
; <24> 6/5/90 KON Speed up notCopy mode for direct src to direct dst by using
; invert flag.
; <23> 6/4/90 KON Speed things that slowed down up by checking if colorizing is a
; nop.
; <22> 5/29/90 HJR Fix Mac32 build problem by moving table8 and some code saving
; mods.
; <21> 5/24/90 KON Fix transfer modes for direct devices, and fix colorizing for
; indexed devices.
; <19+> 4/12/90 KON Add deep masks for copymask.
; <19> 4/11/90 KON Suppress colorizing in src blits when the src clut is nil (i.e.
; the colors are a ramp between the foreground and background
; colors.
; <18> 3/13/90 KON Part of file got trashed. Now fixed.
; <17> 3/13/90 KON Fixed bug in 16-bit search proc.
; <16> 3/6/90 KON Fixed error term for vertical shrinking so expanding and then
; shrinking by an integral amount does not alter the image.
; <15> 2/23/90 KON Fixed buffer problem in Dither16toGray.
; <14> 2/23/90 KON Fixed Dither32toGray and Dither16toGray. Random dots were
; displayed because error term was not calculated right.
; <13> 2/23/90 KON Added 16-bit shrink.
; <12> 2/16/90 KON Cleared out high end of register of ErrBuf size calculation.
; <11> 2/14/90 KON Try to get 256K in stNoStack. Memory requirement calculation now
; use longs so high bits aren't lost. StackFree is updated
; correctly.
; <10> 2/14/90 BAL Changed MFTemp memory stack allocation to try for upto 128K
; chunk.
; <9> 2/9/90 BAL Fixed dither 8-bit to 32-bit stretched copybits.
; <8> 2/5/90 BAL Fixed bug in vertical shrinking while performing indexed to
; indexed dither.
; <7> 2/1/90 BAL Dither16toIndexed: Fix dither error calculation for 16 bit
; sources being displayed on color indexed devices.
; <6> 2/1/90 BAL Special cased SeedCFill/CalcCMask search procs for 16 and 32 bit
; sources.
; <5> 1/30/90 BAL Fixed bugs in underflow of error when dithering to a grayscale
; or bitmap destination. This affects Dither32toGray/Bitmap and
; Dither16toGray/Bitmap.
; <4> 1/28/90 KON Fix clipping when destination is clipped at the top.
; <3> 1/28/90 BAL Added the depth conversion routines Dither32toBitmap and
; Dither16toBitmap and changed the decision tree to utilize them.
; <1+> 1/3/90 BAL FOR 6.0.5: Submitted latest version to BBS. Changes include
; indexed to indexed dithering support.
; <1.9> 12/9/89 BAL Fixed bug in accumulation of dither error in some of the loops.
; Should fix in others. Fixed a bug and optimized the case of
; source rects with tops above srcbits.bounds.
; <1.8> 9/25/89 BAL Changed "NOT forROM" conditionals to "useColorICON" and
; defaulted it to false
; <1.7> 7/16/89 GGD GGD for the vacationing BAL, Fixed bug in AverageH when
; averaging 2 pixels, and optimized the entire loop at the same
; time.
; <¥1.6> 7/14/89 BAL For Aurora: Final CQD
; <1.5> 6/30/89 BAL Make A5 valid and return to 24 bit mode before calling search
; procs
; <¥1.4> 5/29/89 BAL Blasting in 32-Bit QuickDraw version 1.0 Final
; 5/26/89 BAL Fixed bug in call to MakeITable if seed mismatch during direct
; to indexed copy.
; <¥1.3> 4/12/89 BAL Blasting in 32-Bit QuickDraw 1.0B1
; 9/26/88 BAL Replace successfully TrimRect'ed rgns with wideopen to avoid
; multiple Trims.
; 9/22/88 BAL Moved initialization of region state records into GetSeek.
; 9/19/88 BAL Altered to use common stack frame file 'Drawing Vars.a'
; 9/18/88 BAL Altered to get CRSRFLAG value from _BitsToPix; Removed
; references to PIXSRC;
; 9/4/88 BAL Added area averaging for shrinking of 32 bit pixmaps.
; 8/29/88 BAL Changed 32 to 8-1bit dither to carry 2-D error.
; 6/28/88 BAL Added special scaling routine for B/W 1 bit to direct RGB in a
; 32 bit pixel.
; 6/27/88 BAL Changed pattern expansion routines for 16 and 32 bits to
; optimize for solid.
; 6/17/88 BAL Added routines to depth scale from direct to indexed devices.
; 5/9/88 BAL Altered depth scaling code to use long sized pixel translation
; table.
; 5/4/88 BAL fixed bug in n*8x scaling (n=3,5,6,7...)
; 5/3/88 BAL fixed 2 scaling bugs where word-sized operations overflowed
; 4/9/88 BAL altered to use 32bit addressing during blit to screens
; 12/7/87 BAL Changed <C947> to restore D7 (invertFlag) before returning to
; rgn/bitBlt. <C983>
; 11/8/87 BAL Forced stretch to only do color table pixel translation if
; absolutely necessary. <C947>
; 11/8/87 BAL Forced stretch to TrimRect(clipRgn,MinRect) before submitting to
; rgnBlt. <C951>
; 11/8/87 BAL Fixed computation of bufSize for more accurate region clipping
; at at depths greater than 1. <C954>
; 2/3/87 EHB Added error checking
; 1/3/87 CRC expect color param in stretch
; 12/12/86 CRC Added arithmetic modes
; 10/9/86 EHB Added mask parameters to stretchbits calls
; 9/11/86 EHB Added depth translation (N-bit to M-bit)
; 9/8/86 EHB Added full-ratio color scaling (N-bit to N-bit)
; 7/29/86 EHB Allocate EXPAT buffer on stack so long aligned
; 7/26/86 EHB Added support for expanded patterns
; 7/22/86 EHB Pass MODE to PatExpand for colorizing
; 7/7/86 EHB Revised use of color in blt routines.
; 7/5/86 EHB Replaced SeekMask and GetXRtn with GetSeek
; 6/24/86 EHB Big re-org: Create one stack frame shared by stretch, rgnblt,
; bitblt Set up all shared locals here, then call rgnblt, bitblt
; with parms in stack frame and registers (since stretchbits
; called from everywhere).
; 6/23/86 EHB Rearranged for shared stack frame between stretch, rgnblt,
; bitblt Set up all common fields before calls to rgnblt Removed
; all parameters passed to rgnblt (only called from here)
; 6/21/86 EHB Do expansion in 2 passes: one for data, next for chunks
; 6/20/86 EHB New params to COLORMAP Added FCOLOR and BCOLOR to stack frame
; 6/19/86 EHB Use longs in horiz calculations for big pixels
; 6/18/86 EHB Take depth into account for scaling
; 6/18/86 EHB Added a pattern param so it can be called instead of RgnBlt
; 6/16/86 EHB Added routine GetSizeShift to avoid multiplies
; 6/15/86 EHB Convert BitsToPix, and use pixelSize
; 6/14/86 EHB Call GetXRtn to set expand routine for SeekMask Changed
; SRCBITS/DSTBITS to SRCPIX/DSTPIX
; 6/13/86 EHB Moved SeekMask to another file Rearranged stack frame with
; SeekMask stuff at top
; 6/11/86 EHB Modified Stretch to use longwords and 020 instructions Made sure
; that stack buffers all longword aligned
; 6/5/86 EHB Masked off flag bits in all references to rowBytes
;
; To Do:
;
BLANKS ON
STRING ASIS
MACHINE MC68020
;------------------------------------------------------------------
;
; --> STRETCH.TEXT
;
; TO DO: TWO IDENTICAL EXPAND ROUTINES IS TOO MUCH!!!
;
;------------------------------------------------------------------
;
; MODIFICATIONS
;
; 5Jun86 EHB Masked off flag bits in all references to rowBytes
; 11Jun86 EHB Modified Stretch to use longwords and 020 instructions
; Made sure that stack buffers all longword aligned
; 13Jun86 EHB Moved SeekMask to another file
; Rearranged stack frame with SeekMask stuff at top
; 14Jun86 EHB Call GetXRtn to set expand routine for SeekMask
; Changed SRCBITS/DSTBITS to SRCPIX/DSTPIX
; 15Jun86 EHB Convert BitsToPix, and use pixelSize
; 16Jun86 EHB Added routine GetSizeShift to avoid multiplies
; 18Jun86 EHB Take depth into account for scaling
; 18Jun86 EHB Added a pattern param so it can be called instead of RgnBlt
; 19Jun86 EHB Use longs in horiz calculations for big pixels
; 20Jun86 EHB New params to COLORMAP
; Added FCOLOR and BCOLOR to stack frame
; 21Jun86 EHB Do expansion in 2 passes: 32 for data, next for chunks
; 23Jun86 EHB Rearranged for shared stack frame between stretch, rgnblt, bitblt
; Set up all common fields before calls to rgnblt
; Removed all parameters passed to rgnblt (only called from here)
; 24Jun86 EHB Big re-org: Create one stack frame shared by stretch, rgnblt, bitblt
; Set up all shared locals here, then call rgnblt, bitblt with parms
; in stack frame and registers (since stretchbits called from everywhere).
; 5Jul86 EHB Replaced SeekMask and GetXRtn with GetSeek
; 7Jul86 EHB Revised use of color in blt routines.
; 22Jul86 EHB Pass MODE to PatExpand for colorizing
; 26Jul86 EHB Added support for expanded patterns
; 29Jul86 EHB Allocate EXPAT buffer on stack so long aligned
; 8Sep86 EHB Added full-ratio color scaling (N-bit to N-bit)
; 11Sep86 EHB Added depth translation (N-bit to M-bit)
; 9Oct86 EHB Added mask parameters to stretchbits calls
; 12Dec86 CRC Added arithmetic modes
; 3Jan87 CRC expect color param in stretch
; 3Feb87 EHB Added error checking
;
;________________________________ Post Mac II _____________________________________
;
; 08Nov87 BAL Forced stretch to only do color table pixel translation if
; absolutely necessary. <C947>
; 08Nov87 BAL Forced stretch to TrimRect(clipRgn,MinRect) before submitting to rgnBlt. <C951>
; 08Nov87 BAL Fixed computation of bufSize for more accurate region clipping at
; at depths greater than 1. <C954>
; 07Dec87 BAL Changed <C947> to restore D7 (invertFlag) before returning to rgn/bitBlt. <C983>
; 09Apr88 BAL altered to use 32bit addressing during blit to screens
; 03May88 BAL fixed 2 scaling bugs where word-sized operations overflowed
; 04May88 BAL fixed bug in n*8x scaling (n=3,5,6,7...)
; 09May88 BAL Altered depth scaling code to use long sized pixel translation table.
; 17Jun88 BAL Added routines to depth scale from direct to indexed devices.
; 27Jun88 BAL Changed pattern expansion routines for 16 and 32 bits to optimize for solid.
; 28Jun88 BAL Added special scaling routine for B/W 1 bit to direct RGB in a 32 bit pixel.
; 29Aug88 BAL Changed 32 to 8-1bit dither to carry 2-D error.
; 04Sep88 BAL Added area averaging for shrinking of 32 bit pixmaps.
; 18Sep88 BAL Altered to get CRSRFLAG value from _BitsToPix; Removed references to PIXSRC;
; 19Sep88 BAL Altered to use common stack frame file 'Drawing Vars.a'
; 22Sep88 BAL Moved initialization of region state records into GetSeek.
; 26Sep88 BAL Replace successfully TrimRect'ed rgns with wideopen to avoid multiple Trims.
;
;________________________________ Post Jackson Pollack _____________________________________
;
; 26May89 BAL Fixed bug in call to MakeITable if seed mismatch during direct to indexed copy.
;
; Output: A3 contains address of current scanline.
;
MACRO
_pmVersion
if 0 then
cmp.l maskaddr(a6),a3
bne.s @CheckSrc
add.l a5,a3 ;bump mask to next row
tst.w maskpix+pmVersion(a6)
bpl.s @DoLittle
move.l a0,-(sp)
move.l maskpix+baseaddr(a6),a0
jsr (a0)
move.l (sp)+,a0
move.l a3,maskaddr(a6)
bra.s @DoLittle
@CheckSrc
;must be src.
endif
add.l a5,a3 ;bump src to next row
if 0 then
tst.w srcpix+pmVersion(a6)
bpl.s @DoLittle
move.l a0,-(sp)
move.l srcpix+baseaddr(a6),a0
jsr (a0)
move.l (sp)+,a0
@DoLittle
endif
ENDM
;
; The first time bruce is called, D3 contains the starting scan line number
; On output: A3 contains first scanline address
;
MACRO
_pmVersionSrcFirstTime
if 0 then
tst.w srcpix+pmVersion(a6)
bpl.s @NoSrcPmVersion
move.l a0,-(sp)
move.l srcpix+baseaddr(a6),a0
jsr (a0)
move.l (sp)+,a0
@NoSrcPmVersion
endif
ENDM
MACRO
_pmVersionMaskFirstTime
if 0 then
tst.l maskbits(a6) ;is there a mask?
bne.s @DoIt
moveq #0,a3 ;init MaskAddr to zero <KON 19FEB91>
bra.s @WriteIt
@DoIt
tst.w maskpix+pmVersion(a6)
bpl.s @DoLittle
move.l a0,-(sp)
move.l srcpix+baseaddr(a6),a0
jsr (a0)
move.l (sp)+,a0
@WriteIt
move.l a3,maskaddr(a6) ;a3 is returned by the routine
@DoLittle
endif
ENDM
StretchBits PROC EXPORT
IMPORT Scale32toIndexed, Scale16toIndexed, ScaleIndexedToIndexed, Scale32ToBitMap
IMPORT Scale32toGray, Scale16toGray, Scale32to16, Scale16to32, Scale16ToBitMap
IMPORT Search32toIndexed, Search16toIndexed, Search32to16, Search16to32
IMPORT Dither32toIndexed, Dither16toIndexed, Dither32toGray, Dither16toGray
IMPORT CB8to8Clip, CB8to1Clip, CB1to8Clip, Dither32toBitmap, Dither16toBitmap
IMPORT scaleBlt, Search32to32, Search16to16
IMPORT SHFTTBL
EXPORT stMASK0, stMASK1, stMASK2, stMASK3, stAvg, stAddPin, stAddOver
EXPORT stSubPin, stTransparent, stMax, stSubOver, stMin, stHilite
EXPORT Table2,TABLE4,TABLE8, setUpStretch, stNoStack
EXPORT stArith16Tab,stArith32Tab,stColorTab,stGrayTab,stSearchTab
EXPORT EXTBL,PATEXTBL,DoneStretch,OneBitProc,BlitCase,stScanLoop
EXPORT NOPfgColorTable
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
;--------------------------------------------------------------
;
; PROCEDURE StretchBits(srcBits,maskBits,dstBits: BitMap;
; srcRect,maskRect,dstRect: Rect;
; mode: INTEGER; pat: Pattern;
; rgnA,rgnB,rgnC: RgnHandle);
;
; Transfer a rectangle of bits from srcBits to dstBits,
; stretching or compressing according to srcRect and dstRect.
; The transfer is clipped to the intersection of rgnA, rgnB, and rgnC.
; It is also clipped to the specified mask. If MaskBits is NIL, then
; no masking is done.
;
; Restrictions:
;
; if numer <> denom, then src and dst bitmaps do not overlap.
;
;
; COPYRIGHT APPLE COMPUTER INC.
; DESIGNED AND WRITTEN BY BILL ATKINSON
;
;----------------------------------------------------
;
; A6 OFFSETS OF PARAMETERS AFTER LINK:
;
PARAMSIZE EQU 44 ;SIZE OF PARAMETERS
SRCBITS EQU PARAMSIZE+8-4 ;LONG, ADDR OF BITMAP
MASKBITS EQU SRCBITS-4 ;LONG, ADDR OF BITMAP
DSTBITS EQU MASKBITS-4 ;LONG, ADDR OF BITMAP
SRCRECT EQU DSTBITS-4 ;LONG, ADDR OF RECT
MASKRECT EQU SRCRECT-4 ;LONG, ADDR OF RECT
DSTRECT EQU MASKRECT-4 ;LONG, ADDR OF RECT
MODE EQU DSTRECT-2 ;WORD
PAT EQU MODE-4 ;LONG, ADDR OF PATTERN
RGNA EQU PAT-4 ;LONG, RGNHANDLE
RGNB EQU RGNA-4 ;LONG, RGNHANDLE
RGNC EQU RGNB-4 ;LONG, RGNHANDLE
multColor EQU RGNC-2 ;byte, set if source contains nonblack/white colors
;----------------------------------------------------
;
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
;
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
;
&CurFile SETC 'STRETCH'
INCLUDE 'DrawingVars.a'
IF (&TYPE('useColorICON') = 'UNDEFINED') THEN
useColorICON EQU 0
ENDIF
;----------------------------------------------------
LINK A6,#VARSIZE ;ALLOCATE LOCAL VARIABLES
MOVEM.L D0-D7/A1-A5,-(SP) ;SAVE REGS
MOVE.L SP,SAVESTK(A6) ;REMEMBER STACK FOR LATER
move.l stklowPt,saveStkLowPt(a6) ;keep track of the sniffer <57>
;
; Copy rectangles to stack since they might be part of a handle and could move.
; Some people don't know that CopyBits moves memory... just call me SlowDraw.
; <KON 7NOV90>
;
move.l srcrect(a6),a0
lea newSrcRect(a6),a1
move.l a1,srcrect(a6)
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l maskrect(a6),a0
lea newMaskRect(a6),a1
move.l a1,maskrect(a6)
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
move.l dstrect(a6),a0
lea newDstRect(a6),a1
move.l a1,dstrect(a6)
move.l (a0)+,(a1)+
move.l (a0)+,(a1)+
MOVE.W MODE(A6),D1 ;get mode <42>
BTST #3,D1 ;pattern mode? <42>
BNE.S @0 ;yes, alpha already stripped <42>
_GetStreamMode ;get alpha mode bits <42>
MOVE.W D1,MODE(A6) ;save stripped mode <42>
@0: MOVE.L A5,SAVEA5(A6) ;REMEMBER GLOBAL POINTER
move.b mmu32Bit,MMUSave(a6) ;save mmu mode for cheap exit
CLR.L DSTMASKBUF(A6) ;ASSUME NO MASK
CLR.L stackHandle(A6) ;init alternate stack not used
;----------------------------------------------------------------
;
; MAKE SURE THE STACK IS ON A LONGWORD BOUNDARY (FOR FAST BUFFERS)
;
MOVE.L SP,D1 ;GET THE STACK POINTER
AND.B #$FC,D1 ;FORCE LONG ALIGNMENT
MOVE.L D1,SP ;USE IT
;----------------------------------------------------
;
; CONVERT SRCBITS AND DSTBITS TO PIXMAPS
; (A5 must contain global ptr)
;
; BITSTOPIX TAKES DEFAULT DEVICE FROM THEGDEVICE
MOVE.L THEGDEVICE,-(SP) ;SAVE THEGDEVICE
MOVE.L SRCDEVICE,THEGDEVICE ;SET UP SRC DEVICE
MOVE.L SRCBITS(A6),A1 ;GET POINTER TO SRCBITS
IF useColorICON THEN
;----------------------------------------------------
; SLIMEY HACK to draw Jackson Pollack Icon in Full Color:
;
move.l baseAddr(a1),d0 ;get baseAddr
_rTranslate24To32 ;clean up the address
clr.w filler2(a6) ;set myIcon flag false
tst.l d0 ;is it in slot space?
bmi.s @1 ;yes, skip chk
move.l d0,a0 ;to prevent Bus Errors
; cmp.l #$EBF557E2,108(a0) ;check for race car signature
; cmp.l #$cc45c929,108(a0) ;check for painting signature
lea 80(a0),a0 ;point into data
cmp.l #$842ba003,(a0)+ ;check for prism signature
bne.s @1
cmp.l #$8445d455,(a0)+ ;check for prism signature
bne.s @1
cmp.l #$8882e803,(a0)+ ;check for prism signature
bne.s @1
cmp.l #$89017855,(a0) ;check for prism signature
bne.s @1
move.l jpCicn,a1 ; get cicn handle
move.l (a1),a1 ; point at pixmap
move.l (sp),a0 ; get the dst gdevice handle
move.l (a0),a0 ; point to it
move.l gdPMap(a0),a0 ; get its pixmap handle
move.l (a0),a0 ; point to it
cmp.w #4,pixelsize(a0) ; check depth
bge.s @usePMap ; 4 bit or deeper-> use pixmap data
add #IconBMap,a1 ; else use bitmap data
sub #1,filler2(a6) ; using bitmap, don't hack colors
@usePMap
cmp.w #3,Mode(a6) ; BIC mode?
bne.s @2 ; no, draw the icon
bra done
@2 clr.w Mode(a6) ; use copy mode
add #1,filler2(a6) ; flag hack in progress
;
;----------------------------------------------------
ENDIF
@1 LEA SRCPIX(A6),A2 ;COPY INTO SRCPIX
_BitsToPix ;BITMAP -> PIXMAP
MOVE.L (SP)+,THEGDEVICE ;RESTORE THEGDEVICE AS DST DEVICE
MOVE.L DSTBITS(A6),A1 ;GET POINTER TO DSTBITS
LEA DSTPIX(A6),A2 ;COPY INTO DSTPIX
_BitsToPix ;BITMAP -> PIXMAP
MOVE.L D1,REALBOUNDS(A6) ;SAVE REAL DST BOUNDS.TOPLEFT
MOVE.B D2,CRSRFLAG(A6) ;REMEMBER IF DST IS SCREEN <BAL 18Sep88>
;----------------------------------------------------
;
; GET SHIFT AMOUNTS FOR SRC (D3) AND DST (D4) DEPTHS
; THE PIXSRC FLAG IS SET IF SRC IS A PIXMAP THAT ISN'T ONE BIT PER PIXEL
;
LEA SHFTTBL,A0 ;POINT TO SHIFT TABLE
MOVE SRCPIX+PIXELSIZE(A6),D0 ;GET SRC PIXEL SIZE
MOVEQ #0,D3 ;DEFAULT SHIFT = 0
MOVE.B 0(A0,D0),D3 ;GET SRC SHIFT
MOVE D3,SRCSHIFT(A6) ;AND SAVE SRC SHIFT AMOUNT
MOVE DSTPIX+PIXELSIZE(A6),D0 ;GET DST PIXEL SIZE
MOVEQ #0,D4 ;DEFAULT SHIFT = 0
MOVE.B 0(A0,D0),D4 ;GET DST SHIFT
MOVE D4,DSTSHIFT(A6) ;AND SAVE DST SHIFT AMOUNT
;----------------------------------------------------
;
; CONVERT MASKBITS TO MASKPIX, AND GET SHIFT AMOUNT FOR MASK DEPTH
; If mask is direct, pass depth through. If mask is 2, 4, or 8 bit
; promote mask to 32 bit/pixel.
;
CLR MASKSHIFT(A6) ;ASSUME DEPTH = 1
MOVE.L MASKBITS(A6),D0 ;IS THERE A MASK?
BEQ.S NOMASK ;=>NO, SKIP MASK SETUP
MOVE.L D0,A1 ;GET POINTER TO MASKBITS
LEA MASKPIX(A6),A2 ;COPY INTO MASKPIX
_BitsToPix ;BITMAP -> PIXMAP
LEA SHFTTBL,A0 ;POINT TO SHIFT TABLE
MOVE MASKPIX+PIXELSIZE(A6),D0 ;GET MASK PIXEL SIZE
moveq #0,d5 ;default shift=0
move.b 0(a0,d0),d5
bne.s @PromoteIt ;mask is 1-bit/pixel
;
; should promote 1-bit masks unless it's copy mode
;
move.w MODE(A6),d0 ;COPY MODE and 1-bit deep?
and.w #$37,d0 ;mask pattern and dither bits
beq.s NoMask ;yes, don't promote it
@PromoteIt
cmp.b #4,d5 ;if it's 16 bpp, save mask depth
beq.s @gotMaskDepth
move #5,d5 ;otherwise force it to 32 bits/pixel
@gotMaskDepth
move d5,maskshift(a6)
NOMASK
;-------------------------------------------------------------------
;
; CALC MINRECT = INTERSECTION OF DSTRECT, DSTBITS.BOUNDS, AND THREE
; REGION BOUNDING BOXES. QUIT IF THE INTERSECTION IS EMPTY.
;
MOVE.L DSTRECT(A6),-(SP) ;PUSH ADDR OF DSTRECT
PEA DSTPIX+BOUNDS(A6) ;PUSH ADDR OF DSTPIX.BOUNDS
MOVE.L RGNA(A6),A0 ;GET RGNHANDLE
MOVE.L (A0),A0 ;DE-REFERENCE IT
PEA RGNBBOX(A0) ;PUSH RGN BBOX
MOVE.L RGNB(A6),A0 ;GET RGNHANDLE
MOVE.L (A0),A0 ;DE-REFERENCE IT
PEA RGNBBOX(A0) ;PUSH RGN BBOX
MOVE.L RGNC(A6),A0 ;GET RGNHANDLE
MOVE.L (A0),A0 ;DE-REFERENCE IT
PEA RGNBBOX(A0) ;PUSH RGN BBOX
MOVE #5,-(SP) ;PUSH NRECTS
PEA MINRECT(A6) ;PUSH WHERE TO PUT RESULT
_RSECT ;INTERSECT ALL RECTS
BEQ GOHOME ;QUIT IF RESULT IS EMPTY
;----------------------------------------------------------------
;
; SET UP NEWPATTERN TO INDICATE OLD OR NEW STYLE PATTERN
; ALSO SET UP LOCAL PATTERN POINTER, LOCPAT(A6)
;
MOVE.L PAT(A6),LOCPAT(A6) ;COPY PATTERN POINTER
MOVE MODE(A6),LOCMODE(A6) ;COPY MODE
TST ([DSTBITS,A6],ROWBYTES) ;IS THE DST OLD OR NEW?
SMI NEWPATTERN(A6) ;FLAG = TRUE IF NEW PATTERN
CLR PATROW(A6) ;FLAG NOT DOING BIG PATTERNS
bclr #6,LocMode+1(a6) ;clear dither bit <07Jul88 BAL>
sne useDither(a6) ;remember whether it was set <07Jul88 BAL>
;----------------------------------------------------------------
;
; ADJUST MODE AND PATTERN FOR COLOR SEPARATION.
; (A5 must contain global ptr)
;
btst #1,multColor+1(a6) ;check if src is a color font <05JUNE92 SAH>
sne multiColor(a6) ;set multiColor flag for ColorMap
_COLORMAP ;ALTER FOR COLOR SEPARATION
;---------------------------------------
;
; SET UP INVERT FLAG IN D7 TO REFLECT MODE BIT 2
; CHECK TO SEE IF PATTERN WILL BE USED
;
MOVE LOCMODE(A6),D2 ;GET TRANSFER MODE
IF useColorICON THEN
tst filler2(a6) ;cicn hack
beq.s @1
cmp #8,srcPix+pixelSize(a6) ;8-bit clut on icon?
bne.s @1
lea srcPix+pmtable(a6),a0 ;pnt to pmtable handle
move.l (a0),a0 ;get handle
move.l (a0),a0 ;pnt to table
pea ctTable+rgb+red(a0) ;push address of entry zero (white)
pea 255*8+ctTable+rgb+red(a0) ;push address of entry 255 (black)
_GetForeColor ;fill in entry 255
_GetBackColor ;fill in entry zero
MOVE LOCMODE(A6),D2 ;restore TRANSFER MODE
@1
ENDIF
;--------------------------------------------------------------
;
; Use table lookup to map input mode, src type, and dst type
; to a new mode, colorize location, swap fg/bk, use stretch (slow)
; and whether or not to invert.
;
; Index value is five bits: SRCTYPE DSTTYPE MODE (3 bits)
; For SRCTYPE and DSTTYPE 1 = direct, 0 = indexed
; MODE is bottom 3 bits of mode
;
; Lookup value is a byte: INVERT 0 STRETCH? SWAP FG/BG CLRXLATE NEWMODE
; For INVERT, 1 means invert in blit loop, 0 means don't
; STRETCH, 1 means go through stretch, 0 means fast case ok
; SWAP FG/BG 1 means swap, 0 means don't
; CLRXLATE 1 means colorize in blit loop, 0 means translate in makescaletable
; NEWMODE 3 bits determine which blit loop to take
;
moveq #0,d0 ;default for patterns and arithmetic modes
btst #3,d2 ;is it a pattern mode?
bne DoPattern ;=>yes, don't remap mode
btst #5,d2 ;is it a arithmetic mode?
bne.s @useCopyMode ;yes, pretend copy mode
moveq #7,d0 ;prepare to get mode
and.w d2,d0 ;get mode in bottom 3 bits
@useCopyMode
cmp.w #4,d4 ;destination indexed?
blt.s @destind
bset #3,d0 ;set dest direct bit
@destind
cmp.w #4,d3 ;src indexed?
blt.s @srcind
bset #4,d0 ;set dest direct bit
@srcind
lea MapModeTable,a0
move.w (a0,d0*2),d0 ;get table lookup value
bra.s skipTable ;temporary, move table later
ScaleColorBit EQU 3
SwapFGBGBit EQU 4
UseStretchBit EQU 5
InvertItBit EQU 7
ColorizeInModeCaseBit EQU 8
ColorizeInSrcBufBit EQU 9
InvertIt EQU 1 << InvertItBit
UseStretch EQU 1 << UseStretchBit
SwapFGBG EQU 1 << SwapFGBGBit
ScaleColor EQU 1 << ScaleColorBit ;colorize in make scale table
ColorizeInModeCase EQU 1 << ColorizeInModeCaseBit
ColorizeInSrcBuf EQU 1 << ColorizeInSrcBufBit
; from QDciPatchROM.a verbatim (with the exception of CubeE stuff put back in this file) <sm 6/9/92>stb
MapModeTable
;
; indexed src, indexed dst
;
dc.w ScaleColor + srcCopy ;
dc.w ColorizeInModeCase + srcOr ;
dc.w ColorizeInModeCase + srcXor ;
dc.w ColorizeInModeCase + srcBic ;
dc.w UseStretch + SwapFGBG + ScaleColor + SrcCopy
dc.w InvertIt + ColorizeInModeCase + notSrcOr ;
dc.w InvertIt + ColorizeInModeCase + notSrcXor ;
dc.w InvertIt + ColorizeInModeCase + notSrcBic ;
;
; indexed src, direct dst
;
dc.w ScaleColor + srcCopy ;+ UseStretch + <05JUNE92 SAH>
dc.w InvertIt + UseStretch + notSrcBic + SwapFGBG + ColorizeInModeCase
dc.w InvertIt + UseStretch + notSrcXor + SwapFGBG + ColorizeInModeCase
dc.w InvertIt + UseStretch + notSrcOr + SwapFGBG + ColorizeInModeCase
dc.w SwapFGBG + ScaleColor + SrcCopy ; UseStretch + <05JUNE92 SAH>
dc.w UseStretch + ColorizeInModeCase + srcBic + SwapFGBG
dc.w UseStretch + ColorizeInModeCase + srcXor + SwapFGBG
dc.w UseStretch + ColorizeInModeCase + srcOr + SwapFGBG
;
; direct src, indexed dst
;
dc.w ColorizeInSrcBuf + srcCopy ;
dc.w ColorizeInModeCase + srcOr ;
dc.w ColorizeInModeCase + srcXor ;
dc.w ColorizeInModeCase + srcBic ;
dc.w ColorizeInSrcBuf + SwapFGBG + srcCopy
dc.w ColorizeInModeCase + InvertIt + notSrcOr ;
dc.w ColorizeInModeCase + InvertIt + notSrcXor ;
dc.w ColorizeInModeCase + InvertIt + notSrcBic ;
;
; direct src, direct dst
;
dc.w SwapFGBG + ColorizeInModeCase + srcCopy ;
dc.w SwapFGBG + InvertIt + ColorizeInModeCase + notSrcBic ;
dc.w SwapFGBG + InvertIt + ColorizeInModeCase + notSrcXor ;
dc.w SwapFGBG + InvertIt + ColorizeInModeCase + notSrcOr ;
dc.w SwapFGBG + InvertIt + ColorizeInModeCase + SrcCopy
dc.w SwapFGBG + ColorizeInModeCase + SrcBic ;
dc.w SwapFGBG + ColorizeInModeCase + srcXor ;
dc.w SwapFGBG + ColorizeInModeCase + srcOr ;
NOPfgColorTable
dc.l $FFFFFFFF ;1-bit white
dc.l $FFFFFFFF ;2-bit white
dc.l $FFFFFFFF ;4-bit white
dc.l $FFFFFFFF ;8-bit white
dc.l $7FFF7FFF ;16-bit white
dc.l $00FFFFFF ;32-bit white
;
; This next section of code figures out how much work we're going to have to do.
; First we change the mode to that from the mapModeTable.
; Next, find the correct foreground and background colors
; Swap FG/BG colors
; Figure out if colorizing is a NOP
;
skipTable
;
; Reintroduced code from <54> for CubeE.
;
if CubeE then ; <56>
; <56>
; <56> d0 has table value, if pmVersion is negative, always use Stretch
; <56>
tst.w srcpix+pmVersion(a6) ; <56> if pmVersion negative, always use stretch
bmi.s @ForceStretch ; <56>
TST.L MASKBITS(A6) ; <56> IS THERE A MASK?
beq.s @DontForceStretch ; <56> Check if mask needs pmVersion
tst.w maskpix+pmVersion(a6) ; <56> if pmVersion negative, always use stretch
bpl.s @DontForceStretch ; <56>
@ForceStretch ; <56>
bset #useStretchBit,d0 ; <56>
@DontForceStretch ; <56>
endif ; <56>
btst #5,d2 ;is it a arithmetic mode?
beq.s @ChangeLocMode ;no, then remap mode
;
; arithmetic modes aren't colorized
;
and.w #~(ScaleColor+ColorizeInModeCase+ColorizeInSrcBuf),d0 ;clear colorize bits
bra.s @ChangeLocModeDone
@ChangeLocMode
and.b #$f8,d2 ;clear low three bits
moveq #3,d1
and.b d0,d1 ;get low bits of new mode
or.b d1,d2 ;merge with old mode
@ChangeLocModeDone
move.w d2,locMode(a6) ;store for modecase, BitBlt, RgnBlt
;
; if ScaleCase colorizing and src and dst bit depths are the same and source
; is black and white only (multColor bit 0) or is direct, change to ModeCase
; colorizing as an optimization. This allows us to take BitBlt. <05JUNE92 SAH>
;
btst.l #ScaleColorBit,d0 ;ScaleCase colorizing? <55>
beq.s @ScaleOptimizationDone ;Not scalecase, then branch <55>
cmp.w #4,d3 ;src direct? <05JUNE92 SAH>
bge.s @checkDepth
btst #0,multColor+1(a6) ;src Black/White only
beq.s @ScaleOptimizationDone ;no, can't do anything
@checkDepth
cmp.w d3,d4 ;src and dst same depth? <55>
bne.s @ScaleOptimizationDone ;no, branch and don't change to modecase <55>
eor.l #(ScaleColor+ColorizeInModeCase),d0 ;clear scale color; set modecase color <55>
@ScaleOptimizationDone
;
; Use stretch if a search proc is installed <2May90 KON>
;
move.l ([theGDevice]),A0 ; get a pointer to the device
tst.l GDSearchProc(A0) ; check the head of the search chain
beq @CheckSwapping ; no search proc: go on
bset.l #UseStretchBit,d0 ; force stretch
;
; if modecase colorizing, search proc is installed, and direct use unmapped fg and bg colors
;
cmp.w #4,d4 ; destination direct?
blt @CheckSwapping ; nope.
btst.l #ColorizeInModeCaseBit,d0
beq @CheckSwapping ; not modecase: go on
;
; This code reintroduced from version 54 for CubeE.
;
if CubeE then ; <56>
move.l ([theGDevice]),a0 ; <56> get a pointer to the device
tst.l GDSearchProc(A0) ; <56> check the head of the search chain
beq @CheckSwapping ; <56> no search proc: go on
endif ; <56>
;
; fcolor and bcolor were mapped using search proc by colormap. We want to use
; the unmapped versions.
;
PEA RGBFrColor(a6) ;get fg color for colorizing
PEA RGBBgColor(a6)
move.w d0,XLateFlag(a6) ;save translation flags <KON 5MAR91>
_GetBackColor ;get bg color for colorizing
_GetForeColor
move.w XLateFlag(a6),d0 ;restore translation flags <KON 5MAR91>
cmp.w #4,d4 ; 16-Bit?
beq.s @Do16Bit ;
;
; Convert RGB colors to 32-bit colors for foreground
;
moveq #0,d1
move.b RGBFrColor(a6),d1 ;red
swap d1
move.b RGBFrColor+2(a6),d1 ;green
lsl #8,d1
move.b RGBFrColor+4(a6),d1 ;blue
move.l d1,fcolor(a6)
moveq #0,d1 ;do background
move.b RGBBgColor(a6),d1 ;red
swap d1
move.b RGBBgColor+2(a6),d1 ;green
lsl #8,d1
move.b RGBBgColor+4(a6),d1 ;blue
move.l d1,bcolor(a6)
bra.s @CheckSwapping
@Do16Bit
;
; Convert RGB colors to 32-bit colors for background
;
moveq #0,d1
move.b RGBFrColor(a6),d1 ;red
lsl #5,d1 ; rrrrrrrr00000
move.b RGBFrColor+2(a6),d1 ;green rrrrrgggggggg
lsl.l #5,d1 ; rrrrrgggggggg00000 <KON 5MAR91>
move.b RGBFrColor+4(a6),d1 ;blue rrrrrgggggbbbbbbbb
lsr.l #3,d1 ; 000rrrrrgggggbbbbb <KON 5MAR91>
move.w d1,fcolor(a6)
move.w d1,fcolor+2(a6)
moveq #0,d1
move.b RGBBgColor(a6),d1 ;red
lsl #5,d1
move.b RGBBgColor+2(a6),d1 ;green
lsl.l #5,d1 ; <KON 5MAR91>
move.b RGBBgColor+4(a6),d1 ;blue
lsr.l #3,d1 ; <KON 5MAR91>
move.w d1,bcolor(a6)
move.w d1,bcolor+2(a6)
@CheckSwapping
btst.l #SwapFGBGBit,d0 ;swap fg/bg colors?
beq.s swapdone
swapfgbk
move.l fcolor(a6),d1 ;swap fg/bk color
move.l bcolor(a6),fcolor(a6)
move.l d1,bcolor(a6)
swapdone
;------------------------------------------------------------------------------
; Check if colorizing is a NOP. If it is, clear the colorize bits.
; There are three cases: ModeCase, ScaleCase, and SrcBuf colorizing
;
; SrcBuf and ScaleCase colorizing is a NOP IF
;
; for 1-bit sources:
; fcolor = $FFFFFFFF and bcolor = 0
;
; for deep sources:
; RGBFrColor = 0 and RGBBgColor = $00FFFFFF (32-bit)
; or RGBBgColor = $7FFF7FFF (16-bit)
;
; ModeCase colorizing is NOP if bcolor=0 and fcolor=NOPfgColorTable
;
; If ModeCase or ScaleCase colorizing, check for NOP
;
btst.l #ColorizeInModeCaseBit,d0
beq @CheckColorizeInSrcBuf ;branch if SrcBuf or ScaleCase colorizing
;
; Do ModeCase NOP check
;
move.l bcolor(a6),d1 ;is bg color a NOP ($00000000)?
bne @CheckColorizeNOPDone ;bk not a NOP, go slow
move.l fcolor(a6),d1 ;is fg color a NOP?
lea NOPfgColorTable,a0
cmp.l (a0,d4*4),d1
bne @CheckColorizeNOPDone ;no, it's not a NOP
;
; It's a NOP, clear colorize bits
;
and.w #~(ColorizeInModeCase),d0 ;turn off modecase colorizing
bra @CheckColorizeNOPDone
@CheckColorizeInSrcBuf
;
; Check SrcBuf or ScaleCase colorizing
;
; if src is indexed and destination indexed:
; NOP if fcolor = $FFFFFFFF and bcolor = 0
; if src is indexed and destination is direct:
; NOP if fcolor = 0 and bcolor = $00FFFFFF (32-bit)
; bcolor = $7FFF7FFF (16-bit)
;
; Get fg and bg color in RGB space if colorizing at srcbuf, since our source is
; still in RGB space at that time.
;
; D3 contains src pixel depth.
; D4 contains dst pixel depth.
;
cmp.w #4,d3 ;deep src?
bge.s @DeepSrc
cmp.w #4,d4 ;dst indexed?
bge.s @DoDirectNOPCheck
tst.l bcolor(a6) ;bcolor a NOP?
bne @CheckColorizeNOPDone
move.l fcolor(a6),d1 ;fcolor a NOP?
addq.l #1,d1
bne @CheckColorizeNOPDone
bra.s @ClearColorizeBits ;it's a NOP, clear the colorize bits
@DoDirectNOPCheck
tst.l fcolor(a6)
bne @CheckColorizeNOPDone ;fcolor not a NOP for direct device
move.l bcolor(a6),d1 ;is fg color a NOP?
lea NOPfgColorTable,a0
cmp.l (a0,d4*4),d1
bne @CheckColorizeNOPDone
bra.s @ClearColorizeBits ;it's a NOP, clear the colorize bits
@DeepSrc
;
; if swapfgbgBit is set, we need to swap RGB fg/bg color
;
move.w d0,XLateFlag(a6) ;save translation flags
btst #swapfgbgBit,XLateFlag+1(a6) ;rgb invert?
beq.s @DontSwap ;don't invert
PEA RGBBgColor(a6)
PEA RGBFrColor(a6) ;get fg color for colorizing
bra.s @SwapDone
@DontSwap
PEA RGBFrColor(a6) ;get fg color for colorizing
PEA RGBBgColor(a6)
@SwapDone
_GetBackColor ;get bg color for colorizing
_GetForeColor
;
; convert 16-16-16 to 8-8-8 for 32-bit src (D3=5)
;
cmp.w #4,d3 ;16-bit src?
beq.s @ConvertTo555 ;yes, convert to 555
move.l RGBBgColor(a6),d0 ;get RRRRGGGG
lsr.l #8,d0 ;get 00RRRRGG
lsl.w #8,d0 ;put green where it belongs, now 00RRGG00
move.b RGBBgColor+4(a6),d0 ;get blue: 00RRGGBB
move.l d0,RGBBgColor(a6)
move.l RGBFrColor(a6),d0 ;get RRRRGGGG
lsr.l #8,d0 ;get 00RRRRGG
lsl.w #8,d0 ;put green where it belongs, now 00RRGG00
move.b RGBFrColor+4(a6),d0 ;get blue: 00RRGGBB
move.l d0,RGBFrColor(a6)
move.w XLateFlag(a6),d0 ;get translation flags
;
; if RGBFrColor and RGBBgColor are white and black, colorizing is a nop so clear
; ColorizeInSrcBufBit. This is backwards from normal since it is a direct device.
;
tst.l RGBFrColor(a6) ;is Fr color black, ie a NOP for colorizing?
bne.s @CheckColorizeNOPDone ;no, colorizing is not a nop
cmp.l #$00FFFFFF,RGBBgColor(a6) ;is bg color white ($00FFFFFF) (a NOP)
bne.s @CheckColorizeNOPDone
@ClearColorizeBits
and.w #~(ColorizeInSrcBuf+ScaleColor),d0 ;turn off SrcBuf and scale case colorizing
bra.s @CheckColorizeNOPDone
;
; convert 16-16-16 to 5-5-5 for 16-bit src (D3=4)
;
@ConvertTo555
moveq #0,d0 ;clear alpha
move.w RGBBgColor(a6),d0 ;get RRRR
lsl.l #5,d0 ;put correct red in high word
move.w RGBBgColor+2(a6),d0 ;get GGGG
lsl.l #5,d0 ;put correct green in high word
move.w RGBBgColor+4(a6),d0 ;get BBBB
lsl.l #5,d0 ;put correct blue in high word
swap d0
move.w d0,RGBBgColor(a6)
move.w d0,RGBBgColor+2(a6)
moveq #0,d0 ;clear alpha
move.w RGBFrColor(a6),d0 ;get RRRR
lsl.l #5,d0 ;put correct red in high word
move.w RGBFrColor+2(a6),d0 ;get GGGG
lsl.l #5,d0 ;put correct green in high word
move.w RGBFrColor+4(a6),d0 ;get BBBB
lsl.l #5,d0 ;put correct blue in high word
swap d0
move.w d0,RGBFrColor(a6)
move.w d0,RGBFrColor+2(a6)
;
; if RGBFrColor and RGBBgColor are white and black, colorizing is a nop so clear
; ColorizeInSrcBufBit. This is backwards from normal since it is a direct device.
;
move.w XLateFlag(a6),d0 ;save translation flags
tst.l RGBFrColor(a6) ;is Fg color black, ie a NOP for colorizing?
bne.s @CheckColorizeNOPDone ;no, colorizing is not a nop
cmp.l #$7FFF7FFF,RGBBgColor(a6) ;is bg color white ($00FFFFFF) (a NOP)
if CubeE or TheFuture then ; appease the assembler gods <62>
bne.s @CheckColorizeNOPDone
endif ; <62>
and.w #~(ColorizeInSrcBuf+ScaleColor),d0 ;turn off SrcBuf and scale case colorizing
@CheckColorizeNOPDone
move.w d0,XLateFlag(a6) ;save translation flags
btst #InvertItBit,XLateFlag+1(a6) ;TEST INVERT BIT
SNE D7 ;set byte flag in d7
EXTB.L D7 ;INVERTED; D7 GETS ALL 1'S
LEA NOPfgColorTable,A0 ;get address of white table <42>
AND.L 0(A0,D4.W*4),D7 ;remove alpha byte/bit from mask <42>
MOVE.L D7,INVERTFLAG(A6) ;SAVE INVERT FLAG
BRA.S NOTPAT ;=>NO, USE SOURCE INSTEAD
;------------------------------------------------------------------
;
; PATTERN WILL BE USED. EXPAND PATTERN TO THE CURRENT DEPTH.
;
DoPattern
MOVEQ #0,D7 ;if mode is arithmetic, use 0 for <SMC 18SEP90>
BTST #5,D2 ; the ivert flag and skip bit 2 clear <SMC 18SEP90>
BNE.S @notnot ; <SMC 18SEP90>
BCLR #2,D2 ;TEST AND CLR INVERT BIT
SNE D7 ;set byte flag in d7
EXTB.L D7 ;INVERTED; D7 GETS ALL 1'S
@notnot MOVE.L D7,INVERTFLAG(A6) ;SAVE INVERT FLAG <SMC 18SEP90>
; move.w d2,locMode(a6) ;store for modecase, BitBlt, RgnBlt
_PATEXPAND ;EXPAND PATTERN
;----------------------------------------------------
;
; HIDE THE CURSOR IF TO THE SCREEN AND INTERSECTS MINRECT
; (A5 must contain global ptr)
;
NOTPAT
TST.B CRSRFLAG(A6) ;IS DST TO A SCREEN? <BAL 19Sep88>
BEQ.S NOTSCREEN ;=>NO
PEA MINRECT(A6) ;PUSH SHIELD RECT
MOVE.L REALBOUNDS(A6),-(SP) ;PUSH DELTA FOR GLOBAL
_SHIELDCURSOR ;REMOVE CURSOR IF INTERSECT
NOTSCREEN
;----------------------------------------------------------------
;
; SET UP SRC ROWBYTES, MASK ROWBYTES, AND DST ROWBYTES
; GET SRCPIX INTO A4 AND DSTPIX INTO A5
; GET SRCRECT INTO A2 AND DSTRECT INTO A3
;
LEA SRCPIX(A6),A4 ;POINT TO SRCPIX
MOVE #nuRBMask,D0 ;GET MASK FOR ROWBYTE FLAGS
EXT.L D0 ;MAKE IT LONG
MOVE ROWBYTES(A4),D1 ;GET SRC ROWBYTES
AND.L D0,D1 ;CLEAR OUT FLAG BITS
MOVE.L D1,SRCROW(A6) ;SRCROW := SRC ROWBYTES
@1 LEA MASKPIX(A6),A0 ;POINT TO MASKPIX
MOVE ROWBYTES(A0),D1 ;GET DST ROWBYTES
AND.L D0,D1 ;CLEAR OUT FLAG BITS
MOVE.L D1,MASKROW(A6) ;MASKROW := MASK ROWBYTES
LEA DSTPIX(A6),A5 ;POINT TO DSTPIX
MOVE ROWBYTES(A5),D1 ;GET DST ROWBYTES
AND.L D0,D1 ;CLEAR OUT FLAG BITS
MOVE.L D1,DSTROW(A6) ;DSTROW := DST ROWBYTES
MOVE.L srcRect(a6),a2 ;get srcRect 24 bit ptr @@@@ BAL 12Jan89
MOVE.L a2,d0 ;get srcRect ptr @@@@ BAL 09Apr88
_rTranslate24To32
move.l d0,srcRect(a6) ;save 32 bit ptr @@@@ BAL 07Jul88
MOVE.L dstRect(a6),a3 ;get dstRect 24 bit ptr @@@@ BAL 12Jan89
MOVE.L a3,d0 ;get dstRect ptr @@@@ BAL 09Apr88
_rTranslate24To32
move.l d0,dstRect(a6) ;save 32 bit ptr @@@@ BAL 07Jul88
;----------------------------------------------------------------
;
; IF PATTERN MODE, GO DECIDE BETWEEN RGNBLT AND BITBLT
;
MOVE LOCMODE(A6),D0 ;GET MODE
ROR #4,D0 ;IS PATTERN BIT SET ?
BCS NOTSTR ;=>YES, DON'T USE STRETCH
;----------------------------------------------------------------
;
; CALC NUMER AND DENOM BASED ON DSTRECT AND SRCRECT.
; IF NUMER = DENOM AND SRC DEPTH = DST DEPTH THEN JUST CALL RGNBLT.
;
MOVE BOTTOM(A2),D1
SUB TOP(A2),D1 ;CALC SRC HEIGHT
SWAP D1 ;PUT IN HI WORD
MOVE RIGHT(A2),D1
SUB LEFT(A2),D1 ;CALC SRC WIDTH
MOVE D1,D0 ;COPY SRC PIXCNT
SUBQ #1,D0 ;MAKE IT 0 BASED
MOVE D0,SRCPIXCNT(A6) ;SAVE SRC PIXEL COUNT
MOVE BOTTOM(A3),D0
SUB TOP(A3),D0 ;CALC DST HEIGHT
SWAP D0 ;PUT IN HI WORD
MOVE RIGHT(A3),D0
SUB LEFT(A3),D0 ;CALC DST WIDTH
_BlitCase ;Go determine blit style
;----------------------------------------------------------------
;
; Determine whether to use Stretch, Scale, Rgn, or Bit Bliting
;
BlitCase
; clr.b FastCase(a6) ;assume not a fun case <14SEP90 SMC>
TST.L MASKBITS(A6) ;*** IS THERE A MASK?
BNE STRETCH ;=>YES, USE STRETCH FOR NOW
CMP.L D0,D1 ;ARE SRC AND DST THE SAME SIZE
BNE STRETCH ;=>NO, STRETCH THE BITS
;
; Use stretch if UseStretchBit or ColorizeInSrcBufBit is set
;
move.w XLateFlag(a6),d2
and.w #~(UseStretch+ColorizeInSrcBuf),d2 ;use stretch? <05JUNE92 SAH>
cmp.w XLateFlag(a6),d2
bne Stretch
;
; Use ScaleBlt if ScaleColorBit is set <05JUNE92 SAH>
;
btst #ScaleColorBit,XlateFlag+1(a6)
bne xScaleBlt
CMP D3,D4 ;ARE THE DEPTHS THE SAME?
bne xScaleBlt ;=>no, use ScaleBlt
;
; source and destination are the same depth, check if color table seeds are the same
;
cmp #16,dstpix+pixelType(a6) ;is it a direct device?
beq.s notstr ;yes, don't check seeds
MOVE.L SRCPIX+PMTABLE(A6),d2 ;GET SRC COLOR TABLE HANDLE <BAL>
beq XScaleBLT ;nil table so must remap colors <BAL>
move.l d2,a0 ;get handle for deref <BAL>
MOVE.L (A0),A0 ;POINT TO IT
MOVE.L CTSEED(A0),D2 ;GET SEED
MOVE.L DSTPIX+PMTABLE(A6),A0 ;GET DST COLOR TABLE HANDLE
MOVE.L (A0),A0 ;POINT TO IT
CMP.L CTSEED(A0),D2 ;DO THE SEEDS MATCH?
BNE xScaleBlt ;=>NO, use scaleBlt
NOTSTR
;----------------------------------------------------------------
;
; NOW DECIDE BETWEEN BITBLT AND RGNBLT
;
; ARE ALL THREE REGIONS RECTANGULAR ? IF SO, USE BITBLT.
;
; If the visRgn or the clipRgn is non-rectangular then call TrimRect
; to see if the intersection of the region and MinRect is rectangular,
; empty, or regional. <C951> 08Nov87 BAL
;
; <45> If going to a direct device in an arithmetic mode, force into rgnblt. Those
; blit loops are effectively as fast as the ones in bitblt through their use of
; runmasking. This change allows those cases to be stripped out of bitblt.
;
CMP #4,D4 ;direct device?
BLT @noforce ;no, do normal checks
MOVE.W locMode(A6),D0 ;get penmode
BTST #5,D0 ;arithmetic?
BNE XRGNBLT ;yes, force into rgnblt
@noforce
MOVEQ #10,D0 ;GET SIZE OF RECT RGN
MOVE.L RGNC(A6),A0 ;GET RGNHANDLE
MOVE.L (A0),A0 ;DE-REFERENCE IT
CMP RGNSIZE(A0),D0 ;IS RGNC RECTANGULAR ?
BNE XRGNBLT ;=>NO, USE RGNBLT
@chkVis MOVE.L RGNB(A6),A0 ;GET RGNHANDLE
MOVE.L (A0),A0 ;DE-REFERENCE IT
CMP RGNSIZE(A0),D0 ;IS visRgn RECTANGULAR ? <C951>
BEQ.S @chkClip ;=>yes, go check clipRgn <C951>
MOVE.L RGNB(A6),-(SP) ;PUSH visRgn HANDLE <C951>
PEA MINRECT(A6) ;PUSH ADDR OF MINRECT
MOVE.W #-1,-(SP) ;pass Trim = True
_TRIMRECT ;CALL TRIMRECT
BLT DONE ;=>INTERSECTION EMPTY, QUIT & SHOW CURSOR
BGT XRGNBLT ;=>USE RGNBLT
; In case we fall into RgnBlt, replace visRgn with WideOpen
; so that TrimRect doesn't get called again by seekMask.
MOVE.L SAVEA5(A6),A1 ;Get global ptr <BAL 26Sep88>
MOVE.L GRAFGLOBALS(A1),A1 ;point to QD globals <BAL 26Sep88>
MOVE.L WIDEOPEN(A1),RGNB(A6) ;replace visRgn with wideOpen <BAL 26Sep88>
@chkClip
MOVE.L RGNA(A6),A0 ;GET RGNHANDLE
MOVE.L (A0),A0 ;DE-REFERENCE IT
CMP RGNSIZE(A0),D0 ;IS clipRgn RECTANGULAR ?
BEQ XBITBLT ;=>YES, GO USE BITBLT
MOVE.L RGNA(A6),-(SP) ;PUSH clipRgn HANDLE <C951>
PEA MINRECT(A6) ;PUSH ADDR OF MINRECT <C951>
MOVE.W #-1,-(SP) ;pass Trim = True
_TRIMRECT ;CALL TRIMRECT <C951>
BLT DONE ;=>INTERSECTION EMPTY, QUIT & SHOW CURSOR
BEQ XBITBLT ;=>USE BITBLT
; Since we will fall into RgnBlt, swap the clipRgn and the userRgn
; so that TrimRect doesn't get called again by seekMask.
MOVE.L RGNA(A6),A1 ;copy clipRgn <BAL 26Sep88>
MOVE.L RGNC(A6),RGNA(A6) ;replace clipRgn with userRgn <BAL 26Sep88>
MOVE.L A1,RGNC(A6) ;replace userRgn with clipRgn <BAL 26Sep88>
BRA XRGNBLT ;=>USE RGNBLT <BAL 26Sep88>
XScaleBLT
;--------------------------------------------------------------
;
; Must do depth scaling but no spatial resizing and no bit mask.
; Only supports copy and dither modes. No fg/bk colorizing.
; No search procs supported for direct sources.
;
; REGISTER USE:
;
; A2: SRCRECT (24 bit addr)
; A3: DSTRECT (24 bit addr)
; A4: SRCPIX
; A5: DSTPIX
;
; D3: SRCSHIFT
; D4: DSTSHIFT
; D7: INVERT FLAG
tst locMode(a6) ;copy mode?
bne Stretch ;if not copy mode then use stretch
;
; Use Stretch if an alpha mode is set by looking at the streamMode <23JUN92 SAH>
;
; Rather than looking at the stream mode directly here, we should add a call to the alpha
; routines that returns the alpha mode so that we can localize the code! Do this before it
; goes into ROM!
;
move.l savea5(a6),a0 ;get the real a5
move.l GrafGlobals(a0),a0 ;get the qd globals
move.l thePort(a0),a0 ;get the port
TST portBits+rowBytes(A0) ;is it an old port?
BPL @noalpha ;yes, alpha mode is illegal
MOVE.W dstPix+pixelSize(A6),D2 ;get depth of destination
CMP.W #16,D2 ;direct device?
BLT.S @noalpha ;no, skip this stuff
MOVE.L grafVars(A0),D2 ;get grafvars handle
BEQ @noalpha ;no grafvars, no alpha
MOVE.L D2,A0 ;copy handle
MOVE.L (A0),A0 ;dereference handle
BTST #PmNewGVBit-8,pmFlags(A0) ;make sure grafvars have been expanded
BEQ.S @noalpha ;if not, bail
TST.B streamMode(A0) ;is there an alpha mode
bne Stretch ;yes, so go slow
;
; now look at the actual alpha channel byte/bit to see if it contains zero. If not, we
; must go slow. This is because a streamMode of zero means that we write to both graphics
; and alpha. As an optimization, we might be able to just do this check alone for any
; streamMode so that we can go fast when writing an alpha of zero.
;
; For the purposes of Cube-E, this code is remaining as it is below, but it would be wise
; to make the tests just test memory directly to save code space!
;
MOVE.W dstPix+pixelSize(A6),D2 ;get depth of destination
cmp.w #16,d2
beq.s @check16bit
;dst is 32 bit
move.l fcolor(a6),d2
rol.l #8,d2 ;get the alpha channel in the low byte
tst.b d2 ;is it non-zero
bne Stretch ;yes, so go slow
move.l bcolor(a6),d2
rol.l #8,d2 ;get the alpha channel in the low byte
tst.b d2 ;is it non-zero
bne Stretch ;yes, so go slow
bra.s @noalpha ;ok, we can go fast!
@check16bit
;dst is 16 bit
move.l fcolor(a6),d2
btst #15,d2 ;is the alpha bit zero?
bne Stretch ;yes, so go slow
move.l bcolor(a6),d2
btst #15,d2 ;is the alpha bit zero?
bne Stretch ;yes, so go slow
@noalpha
;
; if colorize in modecase or srcbuf flag is set, use stretch
;
move.w XlateFlag(a6),d2
and.w #~(ColorizeinSrcBuf+ColorizeInModeCase),d2
cmp.w XlateFlag(a6),d2
bne.s @toStretch ;if applying color then use stretch
tst.w d7 ;invert the src?
bne.s @toStretch ;if so then use stretch
; st FastCase(a6) ;remember fastCase for Andy <14SEP90 SMC>
cmp.w #4,d4 ;dst < 16 bits/pixel? <05JUNE92 SAH>
blt.s @chkSrc ; <05JUNE92 SAH>
cmp.w #3,d3 ;src <16 bits/pixel?
bgt.s @toStretch
@fast
move.l stNoStackPtr,goShow(a6) ;pass go home routine
_ScaleBlt ;CALL scaleBlt
tst d0 ;did it handle it?
bne DONE ;RESTORE CURSOR AND QUIT
;
; ScaleBlt didn't handle it, so we need to make sure that if the depths
; are one bit and ScaleColor is set, we set ColorizeInModeCase so that
; BitBlt or RgnBlt colorizes
;
btst #ScaleColorBit,XlateFlag+1(a6)
beq.s notStr ;go ahead and use BitBlt
eor.w #(ScaleColor+ColorizeInModeCase),XlateFlag(a6)
BRA.s notStr
@chkSrc
cmp.w #5,d3 ;src 32 bits/pixel?
bne.s @more ;(was Stretch) <14SEP90 SMC>
cmp.w #3,d4 ;dst = 8 bits/pixel?
bne.s Stretch
bra.s @fast
@more cmp.w #4,d3 ;src 16 bits?
beq.s Stretch ;yes, dont do it here
bra.s @fast
@toStretch
BRA.S Stretch ;end of <14SEP90 SMC>
XBITBLT
;--------------------------------------------------------------
;
; SINCE ALL THREE REGIONS ARE RECTANGULAR, WE WILL USE BITBLT.
;
; REGISTER USE:
;
; A2: SRCRECT (32 bit addr)
; A3: DSTRECT (32 bit addr)
; A4: SRCPIX
; A5: DSTPIX
;
; D3: SRCSHIFT
; D4: DSTSHIFT
; D7: INVERT FLAG
moveq #true32b,d0 ;switch to 32 bit addressing
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
move.b d0,MMUsave(a6) ;save previous state for later
move.l srcRect(A6),a2 ;reload srcRect 32 bit ptr
move.l dstRect(A6),a3 ;reload dstRect 32 bit ptr
_BITBLT ;CALL BITBLT
BRA DONE ;RESTORE CURSOR AND QUIT
;----------------------------------------------------------------
;
; CALL RGNBLT WITH ALL SHARED LOCAL VARS SET UP AND REGS LIKE THIS:
;
; A2: SRCRECT (24 bit addr)
; A3: DSTRECT (24 bit addr)
; A4: SRCPIX
; A5: DSTPIX
;
; D3: SRCSHIFT
; D4: DSTSHIFT
; D7: INVERT FLAG
XRGNBLT
move.l stNoStackPtr,goShow(a6) ;pass go home routine to getSeek <BAL 21Mar89>
_StackAvail ;GET STACK AVAIL IN D0.L
LSR.L #2,D0 ;CONVERT BYTES TO LONGS
SUB.L #qdStackXtra/4,D0 ;SUBTRACT SLOP FACTOR <1.5> BAL
MOVE.L D0,STACKFREE(A6) ;AND SAVE FREE LONGS ON STACK
_RGNBLT ;CALL RGNBLT
BRA DONE ;RESTORE CURSOR AND QUIT
STRETCH
;
; if not shrinking and source is 1-bit b&w, clear dither flag <24Sept90 KON>
;
cmp.l d0,d1 ;src, dst same size? <24Sept90 KON>
bne.s @dontClearDither ;branch if no <24Sept90 KON>
move.l srcpix+pmtable(a6),d2 ;get source color table handle <24Sept90 KON>
beq.s @dontClearDither ;nil table: not 1-bit <24Sept90 KON>
move.l d2,a0 ;get handle for deref <24Sept90 KON>
move.l (a0),a0 ;point to it <24Sept90 KON>
moveq #1,d2 ; <24Sept90 KON>
cmp.l ctseed(a0),d2 ;one-bit b&w? <24Sept90 KON>
bne.s @dontClearDither ; <24Sept90 KON>
clr.b useDither(a6) ;don't promote source to 32-bits <24Sept90 KON>
@dontClearDither
;----------------------------------------------------------------
;
; (If dither flag or mask is deep) AND source is indexed data then
; pretend the source is 32 bit/pixel RGB data and remember
; real depth/srcShift for later.
;
move.w d3,realSrcShift(a6) ;make it real anyway
st realDepth(a6) ;assume not promoting source to RGB
cmp.w #16,srcPix+pixelType(a6) ;is src direct?
beq @dontUseRGB ;yes, leave source depth alone
tst.b useDither(a6) ;is the dither bit set?
bne.s @UseRGB ;yes, promote source depth
move maskshift(a6),d2
beq.s @dontUseRGB
@UseRGB
move.w #16,srcPix+pixelType(a6) ;pretend direct data
move.w srcPix+pixelSize(a6),realDepth(a6)
move.w #32,srcPix+pixelSize(a6) ;pretend 32 bits/pixel
moveq #5,d3 ;reset src shift
move.w d3,srcShift(a6)
;
; if scalecase colorizing was used, change to srcbuf colorizing since the scale table
; is not used when the src is 32-bits. <12NOV90 KON>
;
bclr #ScaleColorBit,XLateFlag+1(a6) ;Colorize in scale table?
beq.s @NoColorizing ;no, we're cool
;
; colorizing -> change to srcbuf colorizing and setup RGBFrColor and RGBBgColor
;
bset #ColorizeInSrcBufBit,XLateFlag(a6) ;colorize at srcbuf time
movem.l A5/D0/D1,-(SP) ;Need to preserve a5, d0, and d1
move.l SAVEA5(A6),A5 ;restore 15 for GetFore and GetBack color calls
btst #swapfgbgBit,XLateFlag+1(a6) ;rgb invert?
beq.s @DontSwap ;don't invert
PEA RGBBgColor(a6)
PEA RGBFrColor(a6) ;get fg color for colorizing
bra.s @SwapDone
@DontSwap
PEA RGBFrColor(a6) ;get fg color for colorizing
PEA RGBBgColor(a6)
@SwapDone
_GetBackColor ;get bg color for colorizing
_GetForeColor
;
; convert 16-16-16 to 8-8-8 for 32-bit src (D3=5)
;
move.l RGBBgColor(a6),d0 ;get RRRRGGGG
lsr.l #8,d0 ;get 00RRRRGG
lsl.w #8,d0 ;put green where it belongs, now 00RRGG00
move.b RGBBgColor+4(a6),d0 ;get blue: 00RRGGBB
move.l d0,RGBBgColor(a6)
move.l RGBFrColor(a6),d0 ;get RRRRGGGG
lsr.l #8,d0 ;get 00RRRRGG
lsl.w #8,d0 ;put green where it belongs, now 00RRGG00
move.b RGBFrColor+4(a6),d0 ;get blue: 00RRGGBB
move.l d0,RGBFrColor(a6)
movem.l (SP)+,a5/D0/D1 ;Restore a5,d0, and d1
@NoColorizing
@dontUseRGB
;-----------------------------------------------------------------------
; Change source pixel size to 32 bits if deep mask and src is 16-bit
;
cmp #4,d3 ;is it 16 bit?
bne.s KON
tst.w maskshift(a6)
beq.s KON
moveq #5,d3
KON
;----------------------------------------------------------------
;
; USE SRC AND DST SIZES TO DETERMINE STRETCHING ROUTINE
;
MOVE.L D0,NUMER(A6) ;NUMER := DST SIZE
MOVE.L D1,DENOM(A6) ;DENOM := SRC SIZE
MOVEM.L D3/D4,-(SP) ;SAVE D3/D4
_SetupStretch ;CALC CASEJUMP AND HORIZ FRACT (CLOBBER D3,D4)
MOVE.L A0,RATIOCASE(A6) ;SAVE CASE JUMP FOR LATER
MOVE D0,HORIZFRACTION(A6) ;SAVE FRACTION FOR LATER
MOVEM.L (SP)+,D3/D4 ;RESTORE D3/D4
clr.l SrcPixPmTable(a6) ; <KON 13DEC90>
MOVE.L SRCPIX+PMTABLE(A6),d0 ;GET SRC COLOR TABLE HANDLE <2Sep90 KON>
beq.s @BAL ;table not nil so continue <2Sep90 KON>
MOVE.L d0,a0
MOVE.L (A0),d0 ;POINT TO IT <2Sep90 KON>
_rTranslate24To32 ;clean master pointer <20AUG90 KON and BAL>
move.l d0,SrcPixPmTable(a6) ; <20AUG90 KON and BAL>
@BAL
;----------------------------------------------------------------
;
; DETERMINE AMOUNT OF STACK SPACE WE CAN USE
; Raised amount left for interupts from 1024 to 1600 bytes <BAL 10Apr89>
;
_StackAvail ;GET STACK AVAIL IN D0.L
LSR.L #2,D0 ;CONVERT BYTES TO LONGS
SUB.L #qdStackXtra/4,D0 ;SUBTRACT SLOP FACTOR <1.5> BAL
MOVE.L D0,STACKFREE(A6) ;AND SAVE FREE LONGS ON STACK
bpl.s @stkOK
_stNoStack ;=>NOT ENOUGH STACK, QUIT
@stkOK
;----------------------------------------------------------------
;
; Check to see if we are shrinking 16 or 32 bit source data OR if we are
; shrinking a deep mask. If we are, allocate a buffer for the larger of the
; two. *** Currently assuming source and mask are the same size ***
;
clr.b useAverage(a6) ;assume not averaging
move.w numer+v(A6),D0 ; get destination height
move.w denom+v(A6),D1 ; get source height
cmp.w d1,d0 ;is source larger than dest?
bge.s @noAvrg ;NO=> don't average
;yes, so average if 32 bit/pixel or deep mask
cmp.w #4,d3 ;is src indexed? <KON 2/22/90>
blt.s @noAvrg ;yes, skip averaging <KON 2/22/90>
@shrink
sge useAverage(a6) ;always average if 16 or 32bit src <KON 2/22/90>
moveq #0,d1
move.w denom+h(a6),d1 ;src width
move.l d1,d2 ;make a copy src width <16Feb90 KON and BAL>
add.l d2,d2 ;6 bytes (R.w,G.w,B.w) per pixel <BAL and KON 14Feb90>
add.l d1,d2 ;d2 is byte cnt/2 of AvrgBuf <BAL and KON 14Feb90>
;
; allocate the larger of source buffer or mask buffer
;
cmp.w #4,maskshift(a6) ;mask 16-bit data?
beq.s @DoWords ;yes, allocate twice the error buffer
; cmp.w #4,d3 ;source 16-bit data? <KON 2/22/90>
cmp.w #4,realSrcShift(a6) ;source 16-bit data (check real source)? <KON 3/18/91>
beq.s @DoWords ;Twice as many pixels, allocate twice the error buffer <KON 2/22/90>
lsr.l #1,d2 ;both 32-bit, 1/2 as many pixels
@DoWords
move.w d2,ABufSize(a6) ;save long cnt for later
SUB.L D2,STACKFREE(A6) ;IS THERE ENOUGH STACK?
bpl.s @stkOK2
_stNoStack ;=>NOT ENOUGH STACK, QUIT
@stkOK2
CLR.L -(SP) ;CLEAR ANOTHER LONG OF SLOP
@ClrBuf CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
DBRA D2,@ClrBuf ;LOOP ENTIRE BUFFER
MOVE.L SP,AvrgBuf(A6) ;REMEMBER WHERE AvrgBuf IS
@noAvrg
;----------------------------------------------------------------
;
; if dstPix is direct and we aren't averaging then no
; reason to promote source to RGB, unless using deep mask.
;
tst.b realDepth(a6) ;promoting src to RGB?
bmi.s @LeaveItAlone ;no, all ok
cmp.w #16,dstPix+pixelType(a6) ;is dst direct data?
bne.s @LeaveItAlone ;no, we will be dithering
tst.b useAverage(a6) ;are we averaging
bne.s @LeaveItAlone ;yes, promote source
tst.w maskshift(a6) ;deep mask?
bne.s @LeaveItAlone ;yes: promote
;
;no, don't promote source
;
move.w realDepth(a6),srcPix+pixelSize(a6)
move.w realSrcShift(a6),d3 ;don't fake 32-bit source
move.w d3,srcShift(a6) ;remember it for later
st realDepth(a6) ;don't expand source to 32-bit
clr.w SRCPIX+pixelType(A6) ;don't fake
;
; Change colorizing back to Scalecase colorizing since the scale table
; is used for indexed sources. <12NOV90 KON>
;
bclr #ColorizeInSrcBufBit,XLateFlag(a6) ;colorize at srcbuf time?
beq.s @NoColorizing ;no, we're cool
;
; colorizing -> change back to scalecase colorizing
;
bset #ScaleColorBit,XLateFlag+1(a6) ;Colorize in scale table
@NoColorizing
@LeaveItAlone
;----------------------------------------------------------------
;
; IF THE SRC AND DST ARE DIFFERENT DEPTHS, THEN MUST DO PIXEL SCALING
; IF THEY ARE THE SAME DEPTH, BUT DIFFERENT COLOR TABLES, DO PIXEL SCALING
;
CLR.L SCALECASE(A6) ;ASSUME NO PIXEL DEPTH SCALING
MOVE.W SRCPIX+pixelType(A6),D0 ;IS PIXELTYPE DIRECT? %%%
BEQ HasClut ;NO, IT HAS A CLUT %%%
cmp #16,d0 ;is it RGBDirect?
bne done ;unknown pixeltype -> go home
;@@@@ should also check cmpCount, cmpSize
MOVE.L ([theGDevice]),A2 ; get the current device (trash A2)
tst.l gdSearchProc(A2) ; get the search proc head
bne.s @Slow
cmp d3,d4 ;are the depths the same
beq PIXELOK ;yes, don't depth scale
;----------------------------------------------------------------
;
; The src is direct data (16 or 32 bits/pixel).
; Compute D5 as index into direct mode table based on
;
; src16 -> add 4
; dstIndexed -> add 1
; searchProc -> add 16
; dithering -> add 2
; dst16 -> add 2
; dstAllGray -> add 8
;
; D3=srcShift D4=dstShift
;
@Slow
moveq #4,d0 ; init direct scaleRtn with src=16
move.l d0,d5
cmp.w d3,d5 ; is src 16 bits/pixel?
beq.s @src16
moveq #0,d5 ; init src to 32 bits/pixel
@src16
cmp.w d4,d0 ; is dst 16 bits/pixel?
bne.s @dst32
addq #2,d5 ; remember dst is 16 bits/pixel
@dst32
cmp #16,DSTPIX+pixelType(A6) ;IS PIXELTYPE DIRECT? %%%
beq @noCLUT ;don't makeItable on direct device
; IF THE DST IS AN OLD GRAFPORT AND ONE BIT PER PIXEL, THEN OVERRIDE THE
; scaleCase FOR PROPER MAPPING
TST d4 ;ONE BIT PER PIXEL?
BNE.S @notBitmap ;=>NO, PROC IS OK
MOVE.L DSTBITS(A6),A1 ;GET DST BITMAP
TST ROWBYTES(A1) ;IS IT OLD?
BMI.S @notBitmap ;=>NO, PROC IS OK
addq #8,d5 ;force bitmap procs
bra @chkDither ;go check dither <BAL 28Jan90>
@notBitmap
addq #1,d5 ; remember dst is indexed
MOVE.L ([GDPMap,A2]),A1 ; get pixMap's handle
MOVE.L PMTable(A1),A0 ; get the device colorTable's handle
MOVE.L ([A0],CTSeed),D1 ; get the device colorTable's ctSeed
MOVE.L ([GDITable,A2]),A0 ; get the Itable's master pointer
CMP.L ITabSeed(A0),D1 ; has the colortable changed?
BEQ.S @1 ; if equal, then the iTable is OK
; if table is not up to date, build a new one
MOVE.L PMTable(A1),-(SP) ; push theGDevice's color table handle <BAL 26May89>
MOVE.L GDITable(A2),-(SP) ; push theGDevice's current iTabHandle
MOVE.W GDResPref(A2),-(SP) ; push the preferred iTableResolution
_MakeITable ; make a new table
TST.W QDErr ; was this sucessful?
BEQ.S @noErr ; nope, so quit
ADDQ #4,SP ; flush saved register
BRA doneErr ; <BAL 26May89>
@noErr MOVE.L ([theGDevice]),A2 ; redereference in case it moved <BAL 31Mar89>
MOVE.L ([GDITable,A2]),A0 ; get the iTable's master pointer
@1
ADD.w #ITTable,A0 ; point directly at data
MOVE.L A0,stITabPtr(A6) ; save in stack frame
SUB.w #ITTable,A0 ; get the iTable's master pointer
MOVE.W ITabRes(A0),stITabRes(A6) ; get the iTable resolution
MOVE.L ([GDPMap,A2]),A1 ; get pixMap's handle
MOVE.L ([PMTable,A1]),stCLUTPtr(A6) ; get the device colorTable's ptr
MOVE.L gdSearchProc(A2),D0 ; get the search proc head
bne.s @search ; go use search routines
; Here we know that the dst is indexed and no search proc is present,
; so determine if the dst clut is all grays and/or we are dithering.
; the iTable's master pointer is in A0
MOVEQ #1,D0 ; prime the register again
MOVE ITabRes(A0),D2 ; get the inverse table resolution (and Bit-field width)
LSL.L D2,D0 ; calculate 2^^res
LSL.L D2,D0 ; square it
LSL.L D2,D0 ; cube it
LEA ITTable(A0,D0.L),A1 ; point us at the ITabInfo
tst.w iTabFlags(a1) ; is this a grayITab?
bpl.s @chkDither ; no, go see if dithering
add.w #ITabInfo,a1 ; point past header
move.l a1,stITabInfo(a6) ; save for later
addq #8,d5 ; remember to use gray routines
moveq #40,d0
cmp.l ITabSeed(a0),d0 ; is dst the standard 8-bit gray clut?
beq.s @readyProc ; yes, ignore dithering for speeed!
@chkDither
tst.b useDither(a6) ; should we dither?
beq.s @readyProc ; no, we're set
addq #2,d5 ; remember to use dither routines
;
; Compute and allocate scanline buffer for dither error from previous scan <BAL 29Aug88>
;
MOVEQ #0,D0 ;CLEAR HIGH WORD OF D0
MOVE NUMER+H(A6),D0 ;GET WIDTH OF DST
lsl.l d4,d0 ;get bit width
add.l #31,d0 ;round to long boundary
lsr.l d4,d0 ;get adjusted pixel width
btst #3,d5 ;is dst a grayscale clut?
bne.s @gray ;only need 2 bytes per pixel for gray error <BAL 18Mar89>
move.l d0,d1 ;make a copy <BAL and KON 14Feb90>
ADD.l D0,D0 ;6 bytes (R.w,G.w,B.w) per pixel <BAL and KON 14Feb90>
add.l d1,d0 ;d0 is byte cnt/2 of ErrBuf <BAL and KON 14Feb90>
@gray LSR.l #1,D0 ;AND DIV BY 2 FOR LONGS <BAL and KON 14Feb90>
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
bpl.s @stkOK3
_stNoStack ;=>NOT ENOUGH STACK, QUIT
@stkOK3
CLR.L -(SP) ;CLEAR ANOTHER LONG OF SLOP
@ClearB CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
DBRA D0,@ClearB ;LOOP ENTIRE BUFFER
MOVE.L SP,ErrBUF(A6) ;REMEMBER WHERE ErrBuf IS
clr.b ErrDir(a6) ;init to carry error to right
BRA.S @readyProc ; and continue
; Here we know that the dst is direct so check if search proc is present.
@noCLUT
MOVE.L gdSearchProc(A2),D0 ; get the search proc head
beq.s @readyProc
@search
MOVE.L D0,stSProc(A6) ; put search procs list head in stack frame
bset #4,d5 ; use search routines
; We have the scaleCase routine selector in D5 so compute address
; of routine and stuff it in scaleCase for later
@readyProc
move.w d5,d0 ;copy selector
lsr.w #3,d0 ;determine table to use
lea (stColorTabPtr,ZA0,d0*4),A0 ;POINT TO MODE TABLE
move.l (a0),a0 ;get table
and.w #7,d5 ;get position in this table
add.l 0(A0,D5*4),A0 ;GET CASE JUMP ADDRESS
MOVE.L A0,scaleCase(A6) ; put depth scaling routine in stack frame
BRA PIXELOK ;=>ALREADY GOT ROUTINE
Bogus ;_debugger
bra Done
ALIGN 4
;Color Blits
stColorTab
DC.L Bogus-stColorTab ;0 32 to 32
DC.L Scale32toIndexed-stColorTab ;1 32 to Indexed
DC.L Scale32to16-stColorTab ;2 32 to 16
DC.L Dither32toIndexed-stColorTab ;3 32 to Indexed Dither
DC.L Scale16to32-stColorTab ;4 16 to 32
DC.L Scale16toIndexed-stColorTab ;5 16 to Indexed
DC.L Bogus-stColorTab ;6 16 to 16
DC.L Dither16toIndexed-stColorTab ;7 16 to Indexed Dither
;Gray Blits
stGrayTab
DC.L Scale32toBitmap-stGrayTab ;8 32 to BitMap
DC.L Scale32toGray-stGrayTab ;9 32 to Indexed
DC.L Dither32toBitmap-stGrayTab ;A 32 to (16) ->BitMap Dither <BAL 28Jan90>
DC.L Dither32toGray-stGrayTab ;B 32 to Indexed Dither
DC.L Scale16ToBitMap-stGrayTab ;C 16 to BitMap
DC.L Scale16toGray-stGrayTab ;D 16 to Indexed
DC.L Dither16toBitmap-stGrayTab ;E 16 to (16) ->BitMap Dither <BAL 28Jan90>
DC.L Dither16toGray-stGrayTab ;F 16 to Indexed Dither
;Search Blits
stSearchTab
DC.L Search32to32-stSearchTab ;10 32 to 32 <20AUG90 KON>
DC.L Search32toIndexed-stSearchTab ;11 32 to Indexed
DC.L Search32to16-stSearchTab ;12 32 to 16
DC.L Bogus-stSearchTab ;13 32 to Indexed Dither
DC.L Search16to32-stSearchTab ;14 16 to 32
DC.L Search16toIndexed-stSearchTab ;15 16 to Indexed
DC.L Search16to16-stSearchTab ;16 16 to 16 <20AUG90 KON>
DC.L Bogus-stSearchTab ;17 16 to Indexed Dither
;----------------------------------------------------------------
;
; The src is indexed data (1,2,4,8 bits/pixel).
; If seeds don't match or depths are different then make a scale table.
; Special case 1-bit source.
;
HasClut
MOVE.L SRCPIX+PMTABLE(A6),d0 ;GET SRC COLOR TABLE HANDLE <BAL>
beq.s DOXLATE ;table not nil so continue <BAL>
move.l d0,a0 ;get handle for deref <BAL>
move.l (a0),a0 ;point to it <KON>
MOVE.L CTSEED(A0),D0 ;GET SEED
MOVE.L DSTPIX+PMTABLE(A6),A0 ;GET DST COLOR TABLE HANDLE
cmp #16,DstPix+pixelType(a6) ;is it a direct device?
beq.s @chk1 ;yes, don't check seeds
MOVE.L (A0),A0 ;POINT TO IT
CMP.L CTSEED(A0),D0 ;DO THE SEEDS MATCH?
BNE.S @chk1 ;=>NO, MUST TRANSLATE
CMP D3,D4 ;DOES SRC DEPTH = DST DEPTH?
bne.s @chk1 ;no, then scale pixels
;
; check fg and bk color and if they aren't black and white
; then take chk1 case, otherwise, take pixelok case.
;
; <KON 5MAR91> begins here... This fixes a problem with drawing to bitmaps. The problem
; is when the main device is direct and the app sets the fg color to black and the
; bg color to white, we think we are colorizing since the sense of what is black and
; what is white is reversed. This can only happen when the destination pixmap is
; 1-bit and the destination GDevice is a direct device. Thus, I special case this
; situation and check the fg and bg colors for black and white correctly. There is
; probably a more elegant fix for this, but with 7.0 ready to ship this implementation
; causes the least risk since it should effect only the case we are interested in. If
; it's not this particular case, we branch to @OldWay and processing continues as before.
; YUK!
;
;Êfrom QDciPatchROM.a verbatim (down through the RTD) <sm 6/9/92>stb
;
; if destination device is direct, and dst pixmap 1-bit bcolor = FFFFFFFF and
; fcolor = 0 is NOP
; else, bcolor = 0, fcolor = $FFFFFFFF is NOP
;
cmp #1,d3 ;1-bit?
bne.s @OldWay ;no, do it as before
MOVE.L ([theGDevice]),A2 ; get the current device
MOVE.L ([GDPMap,A2]),A1 ; get pixMap
cmp #16,pixelType(A1) ; is dest. GDevice direct?
bne.s @OldWay ;
;
; Destination pixmap is indexed but GDevice is direct. Assume we are going to
; an old 1-bit port.
;
move.l fcolor(a6),d1
bne.s @chk1 ;fg not black, go slow
move.l bcolor(a6),d1
addq #1,d1
beq PIXELOK ;bk white, fg black, go fast
bra.s @chk1
; <KON 5MAR91> ends here...
@OldWay
move.l bcolor(a6),d1
bne.s @chk1 ;fg not black, go slow
move.l fcolor(a6),d1
addq #1,d1
beq PIXELOK ;bk white, fg black, go fast
@chk1 TST D3 ;IS SRC ONE BIT PER PIXEL?
BNE.S DOXLATE ;=>NO, Build mapping table
MOVEQ #1,D1 ;GET CTSEED FOR DEFAULT ONE BIT TABLE
CMP.L D0,D1 ;IS IT THE DEFAULT?
BEQ SRCONE ;=>YES, USE EXPAND TABLES FOR SPEED
DOXLATE MOVE SRCPIX+PIXELSIZE(A6),D1 ;GET SRC BITS PER PIXEL
MOVEQ #1,D0 ;# ENTRIES = 2^ PIXELSIZE
LSL D1,D0 ;CALC # ENTRIES
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
bpl.s @stkOK
_stNoStack ;=>NOT ENOUGH STACK, QUIT
@stkOK
; IF THE DST IS AN OLD GRAFPORT AND IS ONE BIT PER PIXEL, THEN OVERRIDE THE
; SEARCH PROC FOR PROPER MAPPING
MOVEQ #0,D7 ;ASSUME NO PROC INSTALLED
CMP #1,DSTPIX+PIXELSIZE(A6) ;ONE BIT PER PIXEL?
BNE.S @PROCOK ;=>NO, PROC IS OK
MOVE.L DSTBITS(A6),A1 ;GET DST BITMAP
TST ROWBYTES(A1) ;IS IT OLD?
BMI.S @PROCOK ;=>NO, PROC IS OK
MOVEQ #1,D7 ;FLAG PROC INSTALLED
PEA ONEBITPROC ;POINT TO OUR PROC
_ADDSEARCH ;AND INSTALL IT
@PROCOK MOVE.L SAVEA5(A6),A5 ;GET A5 FOR MAKESCALETBL
MOVE.L A4,-(SP) ;PUSH SRCPIX POINTER
;
; If bit 0 = 1, then MakeScaleTbl colorizes, otherwise it don't.
; if mode is BIC or OR, then don't colorize in MakeScaleTbl
;
MOVE.w XLateFlag(a6),-(SP) ;pass arithmetic mode to get fg/bg relative colors
_MakeScaleTbl ;AND MAKE PIXEL TRANSLATION TABLE
;------------------------------------------------------------------------------------------
;
; <C947> 08Nov87 BAL begins here:
;
;------------------------------------------------------------------------------------------
;
; MakeScaleTbl is called whenever the src and dst pixmaps have different
; pixel depths or different color table seeds. MakeScaleTbl returns a
; pixel translation table used to map each src pixel to a dst pixel.
;
; Here I check to see if the translation table returned by MakeScaleTbl is in
; actuality an identity mapping--in which case no mapping at all is required!
; In order for an identity mapping to result the src and dst pixMaps must be of the same
; depth.
;
; If an identity mapping is detected, I must decide whether a stretch blit loop is
; really required (ie src rect ­ dst rect or maskBits ­ nil) or whether a much faster
; region blit or bit blit loop would suffice.
;
;------------------------------------------------------------------------------------------
move SRCPIX+PIXELSIZE(A6),d1 ;get src bits/pixel
cmp DSTPIX+PIXELSIZE(A6),d1 ;is it the same as dst bits/pixel?
bne.s @ScaleOK ;no, have to do pixel scaling
;inspect scale table for equality
@chkTbl MOVEQ #1,D0 ;# ENTRIES = 2^ PIXELSIZE
LSL D1,D0 ;CALC # ENTRIES in d0
move d0,d1 ;make a copy of long count
lsl #2,d1 ;get size of table
subq #1,d0 ;make counter zero based for dbra
move.l sp,a0 ;point to scale tbl
add d1,a0 ;point past end of table
@1 cmp.l -(a0),d0 ;compare with dst pixel value
dbne d0,@1
bne.s @ScaleOK ;tables are not equal so perform pixel scaling
CLR.L ScaleCase(a6) ;remember no pixel xlation needed <BAL 09Apr90>
MOVE.L SP,ScaleTbl(A6) ;SAVE TRANSLATION TABLE just in case <BAL 09Apr90>
;if we installed a proc get rid of it before short circuiting stretch
TST D7 ;DID WE INSTALL A PROC
BEQ.S @NOPRC ;=>NO, DON'T NEED TO REMOVE
PEA ONEBITPROC ;ELSE PUSH OUR PROC
_DELSEARCH ;AND DELETE IT
@NOPRC LEA DSTPIX(A6),A5 ;RESTORE DSTPIX POINTER
TST.L MASKBITS(A6) ;*** IS THERE A MASK?
BNE PIXELOK ;=>YES, USE STRETCH BUT DON'T PIXEL TRANSLATE
;----------------------------------------------------------------
;
; CALC NUMER AND DENOM BASED ON DSTRECT AND SRCRECT.
; IF NUMER = DENOM AND SRC DEPTH = DST DEPTH THEN JUST CALL RGNBLT.
;
MOVE.L NUMER(A6),D0 ;GET WIDTH,HEIGHT OF DST
CMP.L DENOM(A6),D0 ;SAME AS WIDTH,HEIGHT OF SRC?
BNE PIXELOK ;no, must call stretch
MOVE.L INVERTFLAG(A6),D7 ;restore invert flag <<C983>>
BRA NOTSTR ;jump back and decide between bitblt and rgnblt
;don't really have to use stretch at all!
;------------------------------------------------------------------------------------------
;
; <C947> 08Nov87 BAL ends here.
;
;------------------------------------------------------------------------------------------
@ScaleOK
MOVE.L SP,ScaleTbl(A6) ;SAVE POINTER TO TRANSLATION TABLE
LEA DSTPIX(A6),A5 ;RESTORE DSTPIX POINTER
TST D7 ;DID WE INSTALL A PROC
BEQ.S @NOPROC ;=>NO, DON'T NEED TO REMOVE
PEA ONEBITPROC ;ELSE PUSH OUR PROC
_DELSEARCH ;AND DELETE IT
@NOPROC move.l stIndexedSrc,A0 ;POINT TO THE SCALING ROUTINE
MOVE.L A0,SCALECASE(A6) ;AND SAVE CASE JUMP FOR LATER
BRA PIXELOK ;=>ALREADY GOT ROUTINE
ALIGN Alignment
ONEBITPROC
;----------------------------------------------------------------
; FUNCTION ONEBITPROC(MYCOLOR:RGBCOLOR; VAR INDEX: LONG): BOOLEAN;
;
; THIS IS A COLOR MANAGER CUSTOM SEARCH PROC THAT MAPS RGB TO
; BLACK AND WHITE FOR MAPPING TO OLD GRAFPORTS.
; Algorithm modified to use [5 9 2] luminance mapping. <BAL 30Mar89>
;
MYINDEX EQU 4
MYRGB EQU 8
RESULT EQU 12
ST.B RESULT(SP) ;ALWAYS RETURN TRUE
MOVE.L MYRGB(SP),A0 ;POINT TO RGB
moveq #0,d0 ;clear out high end
moveq #0,d1 ;clear out high end
move.w red(a0),d0 ;get red
move.l d0,a1 ;keep red in a1
move.w green(a0),d1 ;get green
add.l d0,d1 ;accumulate luminance in d1
move blue(a0),d0
add.l d0,d1 ;accumulate luminance in d1
add.l d0,d1 ;accumulate luminance in d1
lsr.l #2,d1
add.l a1,d1 ;accumulate luminance in d1
move green(a0),d0
add.l d0,d1 ;accumulate luminance in d1
add.l d0,d1 ;accumulate luminance in d1
lsr.l #2,d1
MOVE.L MYINDEX(SP),A1 ;POINT TO INDEX
CLR.L (A1) ;ASSUME INDEX = WHITE
tst d1 ;check luminance
BMI.S @RESOK ;=>IF >= $8000 THEN WHITE
ADDQ.L #1,(A1) ;ELSE RETURN BLACK
@RESOK RTD #8 ;STRIP PARAMS AND RETURN
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
;----------------------------------------------------------------
;
; FOR 1 BIT TO N BIT PIXEL-STRETCHING, SET UP EXPAND ROUTINE.
;
SRCONE move.l ExTblPtr,A0 ;POINT TO ROUTINE TABLE
CMP.W #4,D4 ;are we going to a direct device? <42>
BLT.S @2 ;no, take normal path <42>
MOVE.W locMode(A6),D0 ;get transfer mode <42>
BTST #5,D0 ;arithmetic? <42>
BNE.S @2 ;yes, take normal path <42>
AND.W #3,D0 ;is the mode copy? <42>
BEQ.S @2 ;yes, take normal path (colors swapped) <42>
MOVE.L alphaMask(A6),D1 ;get the alpha mask <42>
TST.L INVERTFLAG(A6) ;are we inverting? <42>
BEQ.S @1 ;no, leave invertflag alone <42>
MOVE.L D1,INVERTFLAG(A6) ;yes, change invertflag to alphamask <42>
@1: CLR.L alphaFore(A6) ;foreground is zeroes <42>
MOVE.L D1,alphaBack(A6) ;background is alphamask <42>
ADD.L 40(A0,D4*4),A0 ;get address of special expansion loop <42>
BRA.S @gotScale ;jump to common code <42>
@2: ;take normal path <42>
;
;take special loops if colorizing
;
btst #ScaleColorBit,XLateFlag+1(a6) ;colorize in expansion?
beq.s @nocolorize ;no, colorize in blit loop
@colorize
add.l 32(A0,d4*4),a0 ;colorize in expansion
if 0 then ;why? <10Sept90 KON>
;
; if swapfgbgBit is set, we need to swap fg/bg color again
;
btst #swapfgbgBit,XLateFlag+1(a6) ;rgb invert?
beq.s @gotScale ;don't invert
move.l fcolor(a6),d1 ;swap fg/bk color
move.l bcolor(a6),fcolor(a6)
move.l d1,bcolor(a6)
endif
bra.s @gotScale
@nocolorize
cmp.w #4,d4
blt.s @indexedDst
add.l 8(A0,D4*4),A0 ;choose between direct loops
bra.s @gotScale
@indexedDst
add.l 0(A0,D4*4),A0 ;USE DSTSHIFT TO SELECT ROUTINE
@gotScale
MOVE.L A0,SCALECASE(A6) ;SAVE CASE JUMP FOR LATER
;-----------------------------------------------------------------------
;
; We've got our ScaleCase.
;
PIXELOK
;-----------------------------------------------------------------------
;
; ALLOCATE AND CLEAR SRCBUF TO HOLD SRCWIDTH.
;
MOVEQ #0,D0 ;CLEAR HIGH WORD OF D0
MOVE DENOM+H(A6),D0 ;GET WIDTH OF SRC
LSL.l D3,D0 ;SCALE WIDTH BY SRC DEPTH
SUBq.l #1,D0 ;SUBTRACT 1 BIT
LSR.l #5,D0 ;AND DIV BY 32 FOR LONGS
MOVE D0,SRCLONGS(A6) ;SAVE FOR LATER
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
bpl.s @stkOK
_stNoStack ;=>NOT ENOUGH STACK, QUIT
@stkOK
CLR.L -(SP) ;CLEAR A LONG OF SLOP AT RIGHT
CLRSRC CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
DBRA D0,CLRSRC ;LOOP ENTIRE BUFFER
MOVE.L SP,SRCBUF(A6) ;REMEMBER WHERE SRCBUF IS
MOVE.L SP,DSTBUF(A6) ;ASSUME NO HORIZONTAL STRETCHING
MOVE.L SP,SCALEBUF(A6) ;ASSUME NO PIXEL TRANSLATION
;-----------------------------------------------------------------------
;
; ALLOCATE AND CLEAR DSTBUF TO HOLD DSTLONGS.
;
MOVEQ #0,D0 ;CLEAR HIGH WORD OF D0
MOVE NUMER+H(A6),D0 ;GET WIDTH OF DST
CMP DENOM+H(A6),D0 ;SAME AS WIDTH OF SRC?
BEQ.S NOHSTRETCH ;=>YES, NO HORIZONTAL STRETCHING
LSL.l D3,D0 ;SCALE WIDTH BY SRC DEPTH
SUBq.l #1,D0 ;SUBTRACT 1 BIT
LSR.l #5,D0 ;AND DIV BY 32 FOR LONGS
MOVE D0,DSTLONGS(A6) ;SAVE FOR LATER
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
bpl.s @stkOK
_stNoStack ;=>NOT ENOUGH STACK, QUIT
@stkOK
CLR.L -(SP) ;CLEAR ANOTHER LONG OF SLOP
CLRDST CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
DBRA D0,CLRDST ;LOOP ENTIRE BUFFER
MOVE.L SP,DSTBUF(A6) ;REMEMBER WHERE DSTBUF IS
MOVE.L SP,SCALEBUF(A6) ;DEFAULT SCALEBUF = DSTBUF
NOHSTRETCH
;-----------------------------------------------------------------------
;
; ALLOCATE AND CLEAR MASK TO HOLD srcMASKlongs.
;
CLR.L MASKNUMER(A6) ;SRC MASK WIDTH
CLR.L MASKDENOM(A6) ; = DST MASK WIDTH
MOVE.L MASKBITS(A6),D0 ;IS THERE A MASK?
BEQ NODST ;=>NO, DON'T ALLOCATE MASK BUFFERS
;----------------------------------------------------------------
;
; CALC NUMER AND DENOM BASED ON DSTRECT AND MASKRECT.
;
MOVE.L MASKRECT(A6),A0 ;POINT TO MASKRECT
MOVE BOTTOM(A0),D1
SUB TOP(A0),D1 ;CALC MASK HEIGHT
SWAP D1 ;PUT IN HI WORD
MOVE RIGHT(A0),D1
SUB LEFT(A0),D1 ;CALC MASK WIDTH
MOVE BOTTOM(A3),D0
SUB TOP(A3),D0 ;CALC DST HEIGHT
SWAP D0 ;PUT IN HI WORD
MOVE RIGHT(A3),D0
SUB LEFT(A3),D0 ;CALC DST WIDTH
;----------------------------------------------------------------
;
; USE MASK AND DST SIZES TO DETERMINE MASK STRETCHING ROUTINE
;
MOVEM.L D3/D4,-(SP) ;SAVE D3/D4
MOVE.L D0,MASKNUMER(A6) ;NUMER := DST SIZE
MOVE.L D1,MASKDENOM(A6) ;DENOM := SRC SIZE
_SetupStretch ;CALC CASEJUMP AND HORIZ FRACT (CLOBBER D3,D4)
MOVE.L A0,MASKCASE(A6) ;SAVE CASE JUMP FOR LATER
MOVE D0,MASKFRACT(A6) ;SAVE FRACTION FOR LATER
MOVEM.L (SP)+,D3/D4 ;RESTORE D3/D4
MOVEQ #0,D2 ;CLEAR HIGH WORD OF D0
move.w MASKDENOM+H(A6),d2 ;get width of mask
;
;unless depth = 1, depth promoted to 32 bit/pix
;
move.w maskshift(a6),d1
beq.s @onebitmask
move.l maskpix+pmTable(a6),a0
move.l (a0),d0 ;get pointer to color table <20AUG90 KON and BAL>
_rTranslate24To32 ;clean master pointer <20AUG90 KON and BAL>
move.l d0,MaskPixPmTable(a6) ; <20AUG90 KON and BAL>
moveq #5,d1
lsl.l d1,d2 ;scale width by mask depth
@onebitmask
SUB.l #1,D2 ;SUBTRACT 1 BIT
LSR.l #5,D2 ;AND DIV BY 32 FOR LONGS
MOVE D2,SRCMASKLONGS(A6) ;SAVE FOR LATER
SUB.L D2,STACKFREE(A6) ;IS THERE ENOUGH STACK?
bpl.s @stkOK
_stNoStack ;=>NOT ENOUGH STACK, QUIT
@stkOK
CLR.L -(SP) ;CLEAR A LONG OF SLOP AT RIGHT
CLRMSK1 CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
DBRA D2,CLRMSK1 ;LOOP ENTIRE BUFFER
MOVE.L SP,SRCMASKBUF(A6) ;REMEMBER WHERE SRCMASKBUF IS
;-----------------------------------------------------------------------
;
; ALLOCATE AND CLEAR DSTMASKBUF TO HOLD MASKLONGS.
;
MOVE.L SP,DSTMASKBUF(A6) ;ASSUME NO DSTBUF
MOVEQ #0,D0 ;CLEAR HIGH WORD OF D0
MOVE MASKNUMER+H(A6),D0 ;GET WIDTH OF DST
CMP MASKDENOM+H(A6),D0 ;SAME AS WIDTH OF SRC?
BEQ.S NODST ;=>YES, NO DSTMASKBUF
;mask depth in d1 from above
lsl.l d1,d0 ;scale width by mask depth
@onebitmask
SUB.l #1,D0 ;SUBTRACT 1 BIT
LSR.l #5,D0 ;AND DIV BY 32 FOR LONGS
MOVE D0,DSTMASKLONGS(A6) ;SAVE FOR LATER
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
bpl.s @stkOK
_stNoStack ;=>NOT ENOUGH STACK, QUIT
@stkOK
CLR.L -(SP) ;CLEAR A LONG OF SLOP AT RIGHT
CLRMSK2 CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
DBRA D0,CLRMSK2 ;LOOP ENTIRE BUFFER
MOVE.L SP,DSTMASKBUF(A6) ;REMEMBER WHERE DSTMASKBUF IS
;-----------------------------------------------------------------------
;
; ALLOCATE AND CLEAR SCALEBUF TO HOLD SCALELONGS.
;
NODST TST.L SCALECASE(A6) ;IS THERE A SCALE ROUTINE?
BEQ.S NOSCALE ;=>NO, DON'T ALLOCATE BUFFER
DOSCALE MOVEQ #0,D0 ;CLEAR HIGH WORD OF D0
MOVE NUMER+H(A6),D0 ;GET DST WIDTH
SUB.l #1,D0 ;SUBTRACT 1 BIT @@@@ altered to use longs 03May88 BAL
LSL.l D4,D0 ;SCALE DSTBUF BY DSTSHIFT @@@@ altered to use longs 03May88 BAL
LSR.l #5,D0 ;AND DIV BY 32 FOR LONGS @@@@ altered to use longs 03May88 BAL
MOVE D0,SCALELONGS(A6)
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
bpl.s @stkOK
_stNoStack ;=>NOT ENOUGH STACK, QUIT
@stkOK
CLR.L -(SP) ;CLEAR A LONG OF SLOP AT RIGHT
CLR.L -(SP) ;CLEAR ANOTHER LONG OF SLOP
CLRCHNK CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
DBRA D0,CLRCHNK ;LOOP ENTIRE BUFFER
MOVE.L SP,SCALEBUF(A6) ;REMEMBER WHERE SCALEBUF IS
;_________________________________________________________________________________________
;
; CALC expansion buffer = [ (minRect.right-minRect.left) div 32 + 1 ] * pixelsize - 0
; CALC bufSize = [ (minRect.right-minRect.left) * pixelsize - 1 ] div 32 + 1 <C954> 08Nov87 BAL
;
NOSCALE MOVE.L DSTRECT(A6),A0 ;POINT TO DSTRECT
MOVE LEFT(A0),D1 ;GET DSTRECT LEFT
SUB BOUNDS+LEFT(A5),D1 ;CONVERT TO GLOBAL COORDS
LSL.L D4,D1 ;CONVERT DST PIXELS TO BITS
AND #$FFE0,D1 ;TRUNC TO MULT OF 32
ASR.L D4,D1 ;CONVERT DST BITS TO PIXELS
ADD BOUNDS+LEFT(A5),D1 ;CONVERT BACK TO LOCAL
MOVE D1,BUFLEFT(A6) ;SAVE AS BUFLEFT
MOVEQ #0,D0 ;CLEAR HIGH WORD OF D0
MOVE MINRECT+RIGHT(A6),D0 ;GET MINRECT RIGHT
SUB D1,D0 ;CALC WIDTH IN DOTS
MOVE D0,bufSize(A6) ;for arithmetic modes, prime bufSize with dot size
move d0,d1 ;save for expansion scanline buffer <C954>
ext.l d1 ;clear out high word <C954>
lsl.l d4,d1 ;convert to bits <C954>
subq.l #1,d1 ;force downward round <C954>
LSR.l #5,D1 ;GET NUMBER OF LONGS IN SCANBUF - 1 <C954>
addq.l #1,d1 ;***make it one based for stretch!! <C954>
BTST #5,locMode+1(A6) ;arithmetic?
BNE.S @skipDotToLong ;if so, donÕt update bufSize
MOVE D1,BUFSIZE(A6) ;BUFSIZE = # LONGS -1 <C954>
@skipDotToLong
LSR #5,D0 ;GET NUMBER OF LONGS IN SCANBUF
ADDQ #1,D0 ;MAKE IT ONE BASED
LSL D4,D0 ;MULTIPLY BY DST PIXEL DEPTH
;*** Leave it one based !!!?
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
bpl.s @stkOK
_stNoStack ;=>NOT ENOUGH STACK, QUIT
@stkOK
;-----------------------------------------------------------------------
;
; ALLOCATE AND CLEAR A SCANLINE BUFFER FOR THE COMPOSITE MASK.
;
CLR.L -(SP) ;TWO FOR SLOP
CLR.L -(SP) ;ONE FOR SLOP
CLRMASK CLR.L -(SP) ;ALLOCATE AND CLEAR
DBRA D0,CLRMASK ;LOOP TILL DONE
MOVE.L SP,RGNBUFFER(A6) ;REMEMBER WHERE RGNBUFFER IS
;--------------------------------------------------------------------
;
; ALLOCATE BUFFERS AND INIT STATE RECORDS FOR EACH NON-RECT REGION
; GET SEEK ROUTINE INTO SEEKMASK(A6)
; GET EXPAND ROUTINE INTO EXRTN(A6) FOR SEEK ROUTINE
; Clobbers: A0-A3, D0-D6
;
move.l stNoStackPtr,goShow(a6) ;pass go home routine to getSeek <BAL 21Mar89>
clr.l runBuf(a6) ;don't use run clipping <1.5> BAL
move.l dstmaskbuf(a6),d7 ;save dstmaskbuf
tst.w maskshift(a6) ;deep mask?
beq.s @dontTrickGetSeek ;branch if no
clr.l dstmaskbuf(a6) ;make seek think there is no mask
@dontTrickGetSeek
MOVE.L RGNC(A6),-(SP) ;PUSH USER RGNHANDLE (never TrimRect'ed)
MOVE.L RGNB(A6),-(SP) ;PUSH VIS RGNHANDLE
MOVE.L RGNA(A6),-(SP) ;PUSH CLIP RGNHANDLE
MOVE.L #2,-(SP) ;PUSH HANDLE COUNT - 1
_GETSEEK ;GET EXPAND ROUTINE INTO EXRTN(A6)
;AND SEEK ROUTINE INTO SEEKMASK(A6)
move.l d7,dstmaskbuf(a6) ;restore
;--------------------------------------------------
;
; CALCULATE CASE JUMP FOR DIFFERENT TRANSFER MODES
; GET INVERTFLAG INTO D7
;
SETMODE MOVE LOCMODE(A6),D0 ;GET THE MODE
BTST #5,D0 ;arithmetic mode?
BEQ.S @notArithMode
CMP #$40,D0 ;source modes are $20 É $27, $32
BGT DONE ;if bigger, undefined
BTST #3,D0 ;pattern?
BNE DONE
AND #$17,D0 ;consider only 8 mode variants
BCLR #4,D0 ;clear hilite bit
BEQ.S @notHilite
SUBQ #2,D0 ;hilite?
BNE DONE
ADDQ #8,D0 ;advance to hilite ($0C - 4)
@notHilite
cmp #16,dstPix+pixelSize(A6) ;dst 32 bits/pixel?
bge.s @useLoops16 ;yes, use alternate table
ADDQ #4,D0 ;advance past normal src modes
BRA.S @setupJump
@useLoops16
bne.s @useLoops32 ;yes, use alternate table
move.l stArith16TabPtr,A0 ;POINT TO 16 bit MODE TABLE
@getMode
BCLR #4,D0 ;clear hilite bit
add.l 0(A0,D0*4),A0 ;GET CASE JUMP ADDRESS
move.l a0,modeCase(a6) ;save for later
bra.s @gotMode
@useLoops32
move.l stArith32TabPtr,A0 ;POINT TO 32 bit MODE TABLE
bra.s @getMode
@notArithMode
MOVE.L INVERTFLAG(A6),D7 ;GET THE INVERT FLAG
BCLR #2,D0 ;CLEAR INVERT BIT
CMP #7,D0 ;IS MODE > 7 ?
BGT DONE ;YES, QUIT
@setupJump
LEA StretchModeTab,A0 ;POINT TO MODE TABLE (in trap table)
MOVE.L 0(A0,D0*4),MODECASE(A6) ;SAVE FOR LATER
@gotMode
;------------------------------------------------
;
; SET UP srcMergeCase.
;
@noPromote
move.w srcshift(a6),d3 ;src depth
lea VMergeTable,a0 ;get base
add.l (a0,d3.w*4),a0 ;get routine offset from base
move.l a0,srcMergeCase(a6)
SourceMergeSetupDone
;------------------------------------------------
;
; SET UP maskMergeCase
;
clr.l CombineMaskCase(a6) ;assume no mask
clr.l maskMergeCase(a6) ;assume no mask
tst.l maskbits(a6) ;is there a mask?
beq nomask1 ;=>NO
move.w maskshift(a6),d0 ;mask depth, currently 0, 4, or 5
lea VMergeTable,a0 ;get base
add.l (a0,d0.w*4),a0 ;get displacement to routine
move.l a0,maskMergeCase(a6)
MergeSetupDone
;------------------------------------------------
;
; set up CombineMaskCase
;
tst maskshift(a6)
beq.s CombineMaskSetupDone ;one bpp mask
;
; Table is disorganized as follows:
;
; SRC DST MASK ENTRY
; 32 ind 32 0
; 32 16 32 1
; 32 32 32 2
;
; calc routine based on dst
;
;
; want indexed values to goto 0, 16 bit to 1, 32 bit to 2
;
move dstshift(a6),d0
subq #3,d0
spl d1
and d1,d0
lea CombineTable,a0 ;get base
add.l (a0,d0.w*4),a0 ;get displacement to routine
move.l a0,CombineMaskCase(a6)
CombineMaskSetupDone
;------------------------------------------------
;
; SET UP MASKALIGN AND MASKADDR IF THERE IS A MASK
;
MOVE MASKSHIFT(A6),D3 ;GET MASKSHIFT
LEA MASKPIX(A6),A2 ;POINT TO MASKPIX
MOVE.L MASKROW(A6),D2 ;GET MASK ROWBYTES
MOVE.L MASKRECT(A6),A0 ;POINT TO MASKRECT
MOVE LEFT(A0),D1 ;GET MASKRECT LEFT
SUB BOUNDS+LEFT(A2),D1 ;CONVERT TO MASK GLOBAL
EXT.L D1 ;MAKE LONG FOR BIG PIXELS
lsl.l d3,d1 ;convert pixels to bits
MOVEQ #$1F,D5 ;TREAT MOD 32 FOR MASKALIGN
AND.L D1,D5 ;MAKE A COPY
MOVE.L D5,MASKALIGN(A6) ;SAVE ALIGNMENT OF MASK
MOVE TOP(A0),D0 ;GET MASKRECT TOP
SUB BOUNDS+TOP(A2),D0 ;CONVERT TO MASK GLOBAL
MULS D2,D0 ;MULT BY MASK ROWBYTES BAL 02Dec88
ADD.L BASEADDR(A2),D0 ;GET START OF MASK BITMAP
SUB.L D5,D1 ;ADJUST MASKLEFT FOR MASKALIGN
ASR.L #3,D1 ;CONVERT BITS TO BYTES
ADD.L D1,D0 ;ADD BYTES TO MASKADDR
MOVE.L D0,MASKADDR(A6) ;SAVE AS MASKADDR
NOMASK1
;----------------------------------------------------------
;
; Jump into 32 bit addressing mode for blitting. @@@@ BAL 09Apr88
;
moveq #true32b,d0 ;switch to 32 bit addressing @@@@ BAL 09Apr88
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
move.b d0,MMUsave(a6) ;save previous state for later @@@@ BAL 09Apr88
;------------------------------------------------
;
; SET UP SRCROW, SRCSCANS, SRCSHIFT, AND SRCADDR
;
MOVE realSRCSHIFT(A6),D3 ;GET SRCSHIFT
LEA SRCPIX(A6),A2 ;POINT TO SRCPIX
MOVE.L SRCROW(A6),D2 ;GET SRC ROWBYTES
MOVE BOUNDS+BOTTOM(A2),D1 ;GET SRCBITS.BOUNDS.BOTTOM
SUB BOUNDS+TOP(A2),D1 ;MAKE IT GLOBAL
MOVE D1,SRCSCANS(A6) ;SAVE NUMBER OF SCANS TO DO
MOVE.L SRCRECT(A6),A0 ;POINT TO SRCRECT
MOVE LEFT(A0),D1 ;GET SRCRECT LEFT
SUB BOUNDS+LEFT(A2),D1 ;CONVERT TO SRC GLOBAL
EXT.L D1 ;MAKE LONG FOR BIG PIXELS
LSL.L D3,D1 ;CONVERT SRC PIXELS TO BITS
MOVEQ #$1F,D5 ;TREAT MOD 32 FOR SRCSHIFT
AND.L D1,D5 ;MAKE A COPY
MOVE.L D5,SRCALIGN(A6) ;SAVE ALIGNMENT OF SOURCE
MOVE TOP(A0),D0 ;GET SRCRECT TOP
SUB BOUNDS+TOP(A2),D0 ;CONVERT TO SRC GLOBAL
MULS D2,D0 ;MULT BY SRC ROWBYTES BAL 02Dec88
ADD.L BASEADDR(A2),D0 ;GET START OF SRC BITMAP
SUB.L D5,D1 ;ADJUST SRCLEFT FOR SRCSHIFT
ASR.L #3,D1 ;CONVERT BITS TO BYTES
ADD.L D1,D0 ;ADD BYTES TO SRCADDR
MOVE.L D0,SRCADDR(A6) ;SAVE AS SRCADDR
if 0 then
; If srcAlign is a multiple of 8 there is no reason to make a copy of the src. <BAL 17Mar89>
tst d5
; and #7,d5 ;alignment required? <BAL 17Mar89>
bra.s @mustAlign
clr.l SRCALIGN(A6) ;remember to skip alignment pass <BAL 17Mar89>
clr.l dstBufBump(A6) ;init to no bump <BAL 17Mar89>
clr.l scaleBufBump(A6) ;init to no bump <BAL 17Mar89>
move.l SRCBUF(A6),d1 ;REMEMBER WHERE SRCBUF was <BAL 17Mar89>
move.l srcRow(a6),d2
sub.l d2,d0 ;anticipate initial bump <BAL 17Mar89>
move.l d0,srcBuf(a6) ;use srcAddr as srcBuf <BAL 17Mar89>
cmp.l DSTBUF(A6),d1 ;is dstBuf same as srcBuf? <BAL 17Mar89>
bne.s @mustAlign
move.l d0,dstBuf(a6) ;use srcAddr as dstBuf <BAL 17Mar89>
move.l d2,dstBufBump(a6) ;set up rowBump for dstBuf <BAL 17Mar89>
cmp.l SCALEBUF(A6),d1 ;is scaleBuf same as srcBuf? <BAL 17Mar89>
bne.s @mustAlign
move.l d0,scaleBuf(a6) ;use srcAddr as scaleBuf <BAL 17Mar89>
move.l d2,scaleBufBump(a6) ;set up rowBump for scaleBuf <BAL 17Mar89>
endif
@mustAlign
;----------------------------------------------------
;
; CALC STARTING DSTROW, DSTSHIFT, AND DSTADDR
;
MOVE DSTSHIFT(A6),D4 ;GET DST SHIFT
MOVE.L DSTROW(A6),D2 ;GET DST ROWBYTES
MOVE.L DSTRECT(A6),A0
MOVE TOP(A0),VERT(A6) ;INIT CURRENT VERTICAL
MOVE LEFT(A0),D1 ;GET DSTRECT LEFT
SUB BOUNDS+LEFT(A5),D1 ;CONVERT TO GLOBAL COORDS
EXT.L D1 ;MAKE LONG FOR BIG PIXELS
LSL.L D4,D1 ;CONVERT DST PIXELS TO BITS
MOVEQ #$1F,D6
AND.L D1,D6 ;TREAT MOD 32 FOR SHIFTCNT
NEG.L D6 ;AND NEGATE IT
MOVE.L D6,DSTALIGN(A6) ;SAVE FOR LATER
MOVE.L D6,D0 ;GET ALIGNMENT
ASR.L D4,D0 ;CONVERT TO PIXELS
MOVE.L D0,DSTMASKALIGN(A6) ;AND SAVE FOR MASK
MOVE MINRECT+TOP(A6),D0 ;GET MINRECT TOP
SUB BOUNDS+TOP(A5),D0 ;CONVERT TO GLOBAL COORDS
MULS D2,D0 ;MULT BY DST ROWBYTES BAL 02Dec88
ADD.L BASEADDR(A5),D0 ;GET START OF DST BITMAP
ASR.L #5,D1 ;CONVERT BITS TO LONGS
LSL.L #2,D1 ;AND BACK TO BYTES (MOD 4)
ADD.L D1,D0 ;ADD BYTES TO DSTADDR
MOVE.L D0,DSTADDR(A6) ;SAVE AS DSTADDR
_stScanLoop
stScanLoop
;-----------------------------------------------------
;
; Perform quick checks to see if we can use special cases
;
if 0 then ;<14SEP90 SMC>
tst.b FastCase(a6) ;FG Black, BG White, no scaling, copy mode, no mask?
beq.s @goSlow ;no, must go slow
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;destination 8 bits/pixel?
BNE.S @ChkDst1Bit ;if not, skip
CMP.W #8,SRCPIX+PIXELSIZE(A6) ;src 8 bits/pixel?
BEQ CB8to8Clip ;yes, go fast
CMP.W #1,SRCPIX+PIXELSIZE(A6) ;src 1 bits/pixel?
BNE.S @goSlow
move.l ExTblPtr,A0 ;POINT TO ROUTINE TABLE
add.l 3*4(A0),A0 ;get 1 to 8 bit routine
CMP.L ScaleCase(a6),a0 ;standard 1 bit src?
BNE.S @goSlow
BRA CB1to8Clip
@ChkDst1Bit
CMP.W #1,DSTPIX+PIXELSIZE(A6) ;destination 8 bits/pixel?
BNE.S @goSlow ;if not, can't handle
CMP.W #8,SRCPIX+PIXELSIZE(A6) ;src 8 bits/pixel?
BEQ CB8to1Clip ;if not, skip
@goSlow
endif ;<14SEP90 SMC>
;-----------------------------------------------------
;
; INIT ERROR TERM FOR DDA
;
MOVE DENOM+V(A6),D0 ;get source height <5MAR90 KON>
cmp.w Numer+v(a6),d0 ;check against destination height <5MAR90 KON>
ble.s Expand ;src height <= destination : stretch <5MAR90 KON>
move d0,d1 ;save source height <5MAR90 KON>
ext.l d1 ;
divu.w numer+v(a6),d1 ;src MOD dst to high word of d1 <5MAR90 KON>
swap d1 ;get remainder in low word <5MAR90 KON>
tst d1 ;exact shrink? <5MAR90 KON>
bne.s Expand ; no, use general error <5MAR90 KON>
sub.w #1,d0 ;yes, use src height-1 <5MAR90 KON>
bra.s Expand1
Expand
lsr #1,d0
Expand1
neg d0
move d0, verror(a6)
move d0, maskerror(a6)
;
; Calc num destinations to skip, put in D1
;
SKIPDST
moveq #0,d3 ;assume starting on line 0 in source
move.l srcaddr(A6),a3 ;get source address in register
MOVE MINRECT+TOP(A6),D1 ;
SUB VERT(A6),D1 ;Clipped scans at top
BLE @DontSkipSource ;no, DST NOT CLIPPED
;
; Skip source while error is negative, D3 contains number of source scans to skip
;
@nxtSrc MOVE.L MASKROW(A6),D0 ;GET MASK ROWBYTES
ADD.L D0,MASKADDR(A6) ;BUMP MASK TO NEXT ROW, even if there isn't one
MOVE.L SRCROW(A6),D2 ;GET SRC ROWBYTES
ADD.L D2,a3 ;BUMP SRC TO NEXT ROW
addq #1,d3 ;number of source scan lines skipped
MOVE maskNumer+V(A6),D0 ;update mask error: assume same as source
ADD D0,maskError(A6)
MOVE numer+V(A6),D0 ;GET NUMER.V
ADD D0,verror(A6) ;VERROR := VERROR + NUMER.V
ble.s @nxtSrc ;SKIP IF VERROR > 0
;
;Error is +, skip destinations until we've skipped D1 of them
;
MOVE DENOM+V(A6),D0 ;src height
move maskDenom+v(a6),d2
@nxtDst ADD #1,VERT(A6) ;BUMP TO NEXT VERTICAL on dest
sub d2,maskerror(a6) ;update mask error: assume same as source
SUB D0,VERROR(A6) ;VERROR := VERROR - DENOM.V
subq.w #1,d1 ;dst lines to skip
ble.s @ReadyToDraw
tst.w VERROR(A6)
blt.s @nxtSrc
bra.s @nxtDst ;IF MORE, THEN CONTINUE
@ReadyToDraw
tst.w VERROR(A6) ;don't bump further than we need to
ble.s @DestIsOK ; <63>
move.L SRCROW(A6),D2 ;GET SRC ROWBYTES
sub.L d2,a3 ;bump src to previous row
move.L MASKROW(A6),D0 ;GET SRC ROWBYTES
sub.L D0,MASKADDR(A6) ;BUMP SRC TO NEXT ROW
subq #1,d3 ;number of source scan lines skipped
move NUMER+V(A6),D0 ;GET NUMER.V
if not(TheFuture) then ; <60> Build old code for now
move maskDenom+v(a6),d2 ; <60>
endif ; <60>
if TheFuture then ; <60> New code for later
move maskNumer+v(a6),d2 ; <59>
endif ; <60>
sub d2,maskerror(a6)
sub D0,VERROR(A6) ;VERROR := VERROR + NUMER.V
bgt.s @ReadyToDraw ;
@DestIsOK
;
; here d3 contains number of first src line (# of src lines skipped)
; a3 contains starting address
;
@DontSkipSource
_pmVersionSrcFirstTime ;D3 contains starting scan line no.
move.l a3,srcaddr(a6) ;put src address back
_pmVersionMaskFirstTime ;D3 contains starting scan line no.
;-----------------------------------------------------
;
; GET FIRST SCANLINE OF SRC INTO SRCBUF
;
NEXTSRC TST SRCSCANS(A6) ;ANY SCANS LEFT?
BLE DONE ;=>NO, QUIT
;-----------------------------------------------------
;
; Do MergeCase moves a line of source into srcbuf and does vertical
; averaging if necessary.
;
; Do MergeCase for vertical shrinking of mask
; Do MergeCase for vertical shrinking of src
;
; Clobbers: D0-D4,D6,D7,A0,A1
;
DoMergeCase
;
; Calculate 0-based scanline count in d7.
;
move.l maskMergeCase(a6),d0
beq.s DoSrcMergeCase ;no mask
move.l d0,a0
moveq #-1,d7
move srcscans(a6),d1
move masknumer+v(a6),d0
@AnotherLine
addq #1,d7
subq #1,d1
blt.s @maskDone
add d0,maskerror(a6)
ble.s @AnotherLine ;done when maskerror > 0
@maskDone
moveq #0,d4 ;clear high word of srclongs <17JUL90 KON>
move.w srcmasklongs(a6),d4
move.l maskalign(a6),d5
move.w maskPix+pixelSize(a6),d6
move.l srcmaskbuf(a6),a2 ;dest buffer pointer
move.l maskaddr(a6),a3
move.l MaskPixPmTable(a6),a4
; move.l maskpix+pmTable(a6),a4
; move.l (a4),a4 ;get pointer to color table
move.l maskrow(a6),a5 ;row bytes
jsr (a0) ;returns to DoSrcMergeCase
move.l a3,maskaddr(a6)
DoSrcMergeCase
;
; Calculate 0-based scanline count in d7.
;
moveq #-1,d7 ;
@AnotherLine
addq #1,d7
subq #1,srcscans(A6)
blt.s @srcScansDone
move numer+v(a6),d0
add d0,verror(a6)
ble.s @AnotherLine ;done when verror > 0
@srcScansDone
moveq #0,d4 ;clear high word of srclongs <17JUL90 KON>
move.w srclongs(a6),d4
move.l srcalign(a6),d5
move.w srcPix+pixelSize(a6),d6
tst.b realDepth(a6) ;promoting src to RGB?
bmi.s @notPromoting ;no, all ok
move.w realDepth(a6),d6
@notPromoting
move.l srcbuf(a6),a2 ;dest buffer pointer
move.l srcaddr(a6),a3
move.l SrcPixPmTable(a6),a4
; move.l (a4),a4 ;get pointer to color table
move.l srcrow(a6),a5 ;row bytes
move.l srcMergeCase(a6),a0
jsr (a0)
move.l a3,srcaddr(a6)
;
; srcbuf is setup and shrunk, do colorizing if necessary.
; this is done when the source is direct and the XLateFlag is setup by mapModeTable
;
btst #ColorizeInSrcBufBit, XLateFlag(a6) ; Colorize during expansion?
beq.s @ColorizeDone ;branch if no
move.w srclongs(a6),d1
move.l srcbuf(a6),a2 ;dest buffer pointer
move.l RGBFrColor(A6),D4 ;GET FG COLOR
move.l RGBBgColor(A6),D3 ;GET BK COLOR
@ColorMe
move.l (a2),d2
;
; colorize, the fg/bk are in RGB space and hence switched
;
move.l d2,d7 ;copy source
AND.L D3,D2 ;ADD BG COLOR TO SRC
NOT.L d7 ;GET NOT SRC
AND.L D4,d7 ;ADD FG COLOR TO NOT SRC
OR.L D2,d7 ;COMBINE FG/BK DATA
MOVE.L d7,(A2)+ ;put a long to destination
DBRA D1,@ColorMe ;loop for all longs
@ColorizeDone
SRCOK
MOVE.L DSTALIGN(A6),D6 ;RESTORE DSTALIGN
MOVE.L INVERTFLAG(A6),D7 ;RESTORE INVERT FLAG
;----------------------------------------------------------
;
; HORIZONTALLY STRETCH SRCBUF INTO DSTBUF
;
; USES: D0:(CLOBBERED) D1:(CLOBBERED) D2:(CLOBBERED) D3:(CLOBBERED)
; D4:(CLOBBERED) D5:(DSTPIXSIZE) D6:!DSTALIGN D7:!(INVERTFLAG)
; A0:(CLOBBERED) A1:(CLOBBERED) A2:(MASKADDR) A3:(CASEJUMP)
; A4:(SRCLONGS) A5: A6: A7:
;
MOVE NUMER+H(A6),D0 ;GET DST WIDTH
CMP DENOM+H(A6),D0 ;SAME AS SRC WIDTH?
BEQ.S SOK ;=>YES, NO STRETCHING NEEDED
MOVE DSTLONGS(A6),D0 ;GET DSTLONGS
MOVE.L SRCBUF(A6),A0 ;POINT TO SRCBUF
MOVE.L DSTBUF(A6),A1 ;POINT TO DSTBUF
LEA 4(A1,D0*4),A2 ;SET UP DSTLIMIT
MOVE HORIZFRACTION(A6),D4 ;GET HORIZONTAL FRACTION
MOVE SRCPIX+PIXELSIZE(A6),D5 ;GET SIZE OF DST PIXELS (= SRC PIXELS)
;
; if it's a deep mask and the pixel depth is 16, then it's really 32 bpp
;
cmp #16,d5
bne.s @allok
move.w maskshift(a6),d2 ;deep mask?
cmp #4,d2
blt.s @allok ;not deep mask, don't change pix depth
move.w #32,d5 ;really 32 bpp
@allok
MOVE.L RATIOCASE(A6),A3 ;GET CASE JUMP
MOVEQ #0,D0 ;CASE JUMP ROUTINE USES BYTE
JSR (A3) ;AND CALL STRETCHROW
;----------------------------------------------------------
;
; HORIZONTALLY STRETCH SRCMASKBUF INTO DSTMASKBUF
;
; USES: D0:(CLOBBERED) D1:(CLOBBERED) D2:(CLOBBERED) D3:(CLOBBERED)
; D4:(CLOBBERED) D5:(DSTPIXSIZE) D6:!DSTALIGN D7:!(INVERTFLAG)
; A0:(CLOBBERED) A1:(CLOBBERED) A2:(MASKADDR) A3:(CASEJUMP)
; A4:(SRCLONGS) A5: A6: A7:
;
SOK MOVE MASKNUMER+H(A6),D0 ;GET DSTMASK WIDTH
CMP MASKDENOM+H(A6),D0 ;SAME AS SRCMASK WIDTH?
BEQ.S @DoMasking ;=>YES, NO STRETCHING NEEDED
MOVE DSTMASKLONGS(A6),D0 ;GET NUMBER OF LONGS
MOVE.L SRCMASKBUF(A6),A0 ;POINT TO SRCMASKBUF
MOVE.L DSTMASKBUF(A6),A1 ;POINT TO DSTMASKBUF
LEA 4(A1,D0*4),A2 ;SET UP DSTLIMIT
MOVE MASKFRACT(A6),D4 ;GET HORIZONTAL FRACTION
MOVE maskpix+pixelsize(a6),d5 ;***GET PIXELSIZE
cmp.w #1,d5 ;is it 1?
beq.s @sizeok ;if yes, leave it alone
moveq #32,d5 ;otherwise it's really 32
@sizeok
MOVE.L MASKCASE(A6),A3 ;GET CASE JUMP
MOVEQ #0,D0 ;CASE JUMP ROUTINE USES BYTE
JSR (A3) ;AND CALL STRETCHROW
@DoMasking
;----------------------------------------------------------
;
; Combine src and dest using mask. Only called for deep masks
;
; USES: D0: D1: D2: D3:
; D4: D5:!dstAlign D6:dst pixel size D7:pixel count
; A0: scratch A1:mask ptr A2:destination A3: src and dst ptr
; A4: src pmtable A5: not used A6: not used A7: not used
;
move.l CombineMaskCase(a6),d0
beq.s dstok ;no mask merging
move.l d0,a0 ;merge routine address
move.l dstalign(a6),d5 ;get !dstalign
neg.l d5
move.l dstbuf(a6),a3
move numer+h(a6),d7 ;number of pixels to do (width of dest)
move.l dstmaskbuf(a6),a1
move.l dstaddr(a6),a2 ;destination
move.l dstPix+pmTable(a6),a4
move.l (a4),a4 ;get clutptr
move.w dstpix+pixelsize(a6),d6 ;1, 2, 4, 8, 16, 32
jsr (a0) ;combine src w/ dst using mask
;----------------------------------------------------------
;
; Change dstbuf depth to destination depth and put result in scalebuf
;
; USES: D0:(CLOBBERED) D1:(CLOBBERED) D2:(CLOBBERED) D3:!(SRCPIXSIZE)
; D4:!(DSTPIXSIZE)D5:(CLOBBERED) D6:!DSTALIGN D7:!INVERTFLAG
; A0:(DSTBUF) A1:(SCALEBUF) A2:(DSTLIMIT) A3:
; A4:!(SCALETBL) A5:! A6:! A7:!
;
DSTOK move.l dstalign(a6),d6
MOVE.L INVERTFLAG(A6),D7 ;GET THE INVERT FLAG
MOVE.L SCALECASE(A6),D1 ;NEED TO EXPAND PIXELS?
BEQ.S NXTMASK ;=>NO, DON'T BOTHER STRETCHING
MOVE SRCPIX+PIXELSIZE(A6),D3 ;GET SOURCE PIXEL SIZE
;
; if it's a deep mask and the pixel depth is 16, then it's really 32 bpp
;
cmp #16,d3
bne.s @allok
tst.w maskshift(a6) ;deep mask?
beq.s @allok ;not deep mask, don't change pix depth
move.w #32,d3 ;really 32 bpp
@allok
MOVE DSTPIX+PIXELSIZE(A6),D4 ;GET DST PIXEL SIZE
MOVE.L DSTBUF(A6),A0 ;POINT TO SRC
MOVE.L SCALEBUF(A6),A1 ;POINT TO DST
MOVE SCALELONGS(A6),D0 ;GET SIZE
LEA 4(A1,D0*4),A2 ;SET UP DSTLIMIT
MOVE.L D1,A3 ;GET CASE JUMP ROUTINE
MOVE.L ScaleTbl(A6),A4 ;POINT TO TRANSLATION TABLE
MOVEQ #0,D0 ;CASE JUMP ROUTINE USES BYTE
JSR (A3) ;AND CALL STRETCHROW
;-------------------------------------------------------
;
; TRANSFER ONE OR MORE COPIES OF SCALEBUF INTO DSTBITS
;
; USES: D0: D1: D2: D3:!(FGCOLOR)
; D4:!(BKCOLOR) D5:arith stuff D6:!DSTALIGN D7:!INVERTFLAG
; A0: A1: A2: A3:
; A4: A5:arith stuff A6: A7:
;
NXTMASK MOVE.L FCOLOR(A6),D3 ;GET FG COLOR
MOVE.L BCOLOR(A6),D4 ;GET BK COLOR
BTST #5,locMode+1(A6) ;an arithmetic mode?
BEQ.S @skipArith
MOVEQ #0,D7
MOVE dstPix+pixelSize(A6),D7 ;get the number of bits in a pixel
MOVEQ #32,D5
DIVU D7,D5 ;# of pixels in a long
if 0 then ; don't colorize arithmetic modes anymore
; color the source first
; color only if colorizing in mode case
@doColor
BTST #ColorizeInModeCaseBit, XLateFlag(a6)
beq.s @skipColor
cmp #36,locMode(A6) ;transparent mode? ** should be an equ ** <<PB465 BAL>>
beq.s @skipColor ;if so, skip colorizing. <KON>
MOVE.L SCALEBUF(A6),A3 ;INIT SRCPTR
MOVE BUFSIZE(A6),D2 ;INIT COUNT OF LONGS
@nxtSrc
MOVE.L (A3),D0 ;get a long from source
move.l d0,d1
AND.L D3,D0 ;ADD FG COLOR TO SRC
NOT.L d1 ;GET NOT SRC
AND.L D4,d1 ;ADD BK COLOR TO NOT SRC
OR.L D0,d1 ;COMBINE FG/BK DATA
move.l d1,(A3)+ ;write it out
SUB D5,D2 ;do for all of the pixels on this row
BGE.S @nxtSrc
@skipColor
endif
MOVE.L colorTable(A6),A5 ;set up for arithmetic modes
CMP #$24,locMode(A6) ;transparent?
BNE.S @skipArith ;if not, regs are fine
BFEXTU transColor(A6){0:D7},D0
MOVE.L D0,A5
@skipArith
NXTMSK1 MOVE VERT(A6),D0 ;GET CURRENT VERT COORD
CMP MINRECT+TOP(A6),D0 ;IS VERT < MINV ?
BLT.S NODRAW ;YES, DON'T DRAW
;
; if mask is >1 bit/pixel, trick seek into ignoring mask by zeroing dstmaskbuf
;
move.l dstmaskbuf(a6),a4 ;save dstmaskbuf <KON 9JAN90>
tst maskshift(a6)
beq.s @NoTrickorTreat
clr.l dstmaskbuf(a6) ;make seek think there is no mask
@NoTrickorTreat
JSR ([SEEKMASK,A6]) ;MAKE MASK BUFFER CURRENT
move.l a4,dstmaskbuf(a6) ; <KON 9JAN90>
MOVE.L SCALEBUF(A6),A3 ;INIT SRCPTR
MOVE.L DSTADDR(A6),A4 ;INIT DSTPTR FOR ROW
MOVE.L RGNBUFFER(A6),A2 ;INIT MASKPTR FOR ROW
MOVE BUFSIZE(A6),D2 ;INIT COUNT OF LONGS
MOVE.L MODECASE(A6),A0 ;GET MODE CASE JUMP
BTST #5,locMode+1(A6) ;an arithmetic mode?
BEQ.S @skipArith
MOVE.L transColor(A6),D4 ;set up transparent color in case different from bg
CMP #$24,locMode(A6) ;transparent?
BEQ.S @skipInvTbl ;if so, D5 contains the pixels per long value
MOVE invSize(A6),D5 ;set up resolution of inverse table for arith. modes
@skipInvTbl
MOVEQ #0,D3 ;initialize destination pixel offset
MOVE.L dstAlign(A6),D6 ;reset alignment since it is bumped by arith. modes
SUB.L D7,D6 ;bump source pixel offset back by 1
@skipArith
CMP.L DSTPIX+BASEADDR(A6),A4 ;IS IT BEFORE THE PIXMAP?
BLO.S DSTNEG ;=>YES, DON'T PUT TO DST
DOBLT JMP (A0) ;TAKE MODE JUMP
NEXTDST MOVE.L DSTROW(A6),D0 ;GET DST ROWBYTES
ADD.L D0,DSTADDR(A6) ;BUMP DST TO NEXT ROW
NODRAW ADD #1,VERT(A6) ;BUMP TO NEXT VERT
MOVE VERT(A6),D0 ;GET VERT
CMP MINRECT+BOTTOM(A6),D0 ;ARE WE AT THE LAST SCAN LINE ?
BEQ.S DONE ;YES, QUIT
MOVE maskdenom+V(A6),D0 ;update mask error
SUB D0,maskERROR(A6)
MOVE DENOM+V(A6),D0
SUB D0,VERROR(A6) ;VERROR := VERROR - DENOM.V
BLT NEXTSRC ;IF VERROR < 0 THEN GET NEXT SRC <BAL 19Mar89>
tst.b useDither(a6) ; are we dithering? <BAL 19Mar89>
bne.s dstOK ; yes dither this scan again with current error <BAL 19Mar89>
BRA NXTMSK1 ;ELSE continue to draw from this src <BAL 19Mar89>
;-----------------------------------------------------------------
;
; HANDLE CASE WHERE DST IS NEGATIVE
;
DSTNEG MOVE.L DSTPIX+BASEADDR(A6),D1 ;GET ELUSIVE BASE ADDRESS
BTST #5,locMode+1(A6) ;AN ARITHMETIC MODE?
BEQ.S @NoRith ;=>NOPE, DO NORMAL
; IF ARITHMETIC MODE, BUMP ONE PIXEL AT A TIME UNTIL DST ISN'T NEGATIVE
@LOOP LEA 0(A4,D3),A1 ;GET CURRENT ADDRESS
CMP.L A1,D1 ;ARE WE STILL NEGATIVE?
BLS.S DOBLT ;=>NO, BLIT REST OF SCANLINE
SUBQ #1,D2 ;SKIP A DOT
BMI.S NEXTDST ;=>DONE WITH SCANLINE
ADD.L D7,D6 ;BUMP SRC POINTER ONE DOT
ADD.L D7,D3 ;BUMP DST POINTER ONE DOT
BRA.S @LOOP ;=>YES, KEEP SKIPPING
; IF NORMAL MODE, BUMP ONE LONG AT A TIME UNTIL DST ISN'T NEGATIVE
@NoRith LEA 4(A4),A1 ;GET NEXT LONG OF DST
CMP.L A1,D1 ;ARE WE STILL NEGATIVE
BLS.S DOBLT ;=>NO, BLIT REST OF SCANLINE
SUBQ #1,D2 ;SKIP NEXT LONG
BMI.S NEXTDST ;=>DONE WITH SCANLINE
ADDQ.L #4,A2 ;BUMP MASKPTR
ADDQ.L #4,A3 ;BUMP SRCPTR
ADDQ.L #4,A4 ;BUMP DSTPTR
BRA.S @NoRith ;=>TRY, TRY AGAIN
;-----------------------------------------------------------------
;
; ENTIRE STRETCHBITS COMPLETE. RESTORE REGS AND STACK AND GO HOME.
;
DoneStretch
DONE clr.w QDErr ;signal no error
doneErr move.b MMUsave(a6),d0 ;get previous MMU state in d0
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
SHOW MOVE.L SAVEA5(A6),A5 ;RESTORE A5
TST.B CRSRFLAG(A6) ;DID WE SHIELD THE CURSOR?
BEQ.S GOHOME ;=>NO, JUST RETURN
_SHOWCURSOR ;RESTORE CURSOR
GOHOME BSET #hiliteBit,HiliteMode ;reset hilite override, in case colormap was skipped
MOVE.L SAVESTK(A6),SP ;STRIP VARIABLE SIZED BUFFER
move.l stackHandle(a6),d0 ;did we allocate a handle?
beq.s @noTemp ;no, forget it.
move.l d0,a0 ;pass handle in a0
_DisposeTempBuffer ;dispose it.
move.l saveStkLowPt(a6),stkLowPt ;restart the sniffer <57>
move.l oldHiHeapMark(a6),HiHeapMark ;restore extent of stack
@noTemp MOVEM.L (SP)+,D0-D7/A1-A5 ;RESTORE REGISTERS
UNLINK PARAMSIZE,'STRETCHB'
ALIGN Alignment
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
stNoStack
tst.l StackFree(a6) ;did we run out of stack?
bpl.s SHOW ;no, just go home
movem.l d0-d3/a0-a2,-(sp) ;save state
neg.l d0 ;<BAL and KON 14Feb90>
move.l d0,stackFree(a6) ;<BAL and KON 14Feb90>
tst.l stackHandle(a6) ;have we been here before?
bne.s @noMem ;yes, forget it.
move.l HiHeapMark,oldHiHeapMark(a6) ;save extent of stack
moveq #4,d0 ; <KON 14Feb90>
swap d0 ;try for 256K <BAL 14Feb90>
_NewTempBuffer ;returns a0=handle, d0=size
move.l d0,d2 ;copy the actual size
beq.s @noMem ;if zero, we didn't get it.
@gotit move.l a0,stackHandle(a6) ;remember to dispose it later
sub.l #qdStackXtra,d2 ;leave room for interrupts
asr.l #2,d2 ;make cnt of longs
add.l d2,stackFree(a6) ;new free cnt
bmi.s @noMem ;didn't get enough
clr.l stkLowPt ;disable stack sniffer
move.l a7,a2 ;remember where save regs are
move.l (a0),a0 ;get ptr
exg a0,d0 ;get ptr in d0, size in a0
_rTranslate24To32 ;strip it
move.l d0,HiHeapMark ;set up stack limit for _stackSpace
add.l d0,a0 ;point to end of block
move.l 7*4(a7),-(a0) ;copy over return address
move.l a0,a7 ;move the stack there
movem.l (a2),d0-d3/a0-a2 ;restore state
rts
@noMem move.w #nsStackerr,QDErr
bra.s SHOW
;******************************************************************************************
;--------------------------------------------
;
; Source scanline merge routines.
; There are 3 routines: OneDeep, NDeep, and Average16and32
; These routines copy from srcaddr to srcbuf and do vertical
; merging of source if necessary.
;
; When promoting source (ie dither mode) to 32 bit/pixel, Average16and32
; is called.
;
; EXPECTS: D0: D1: D2: D3:
; D4: D5:!SRCALIGN D6:!DSTALIGN D7:!INVERTFLAG
; A0: A1: A2: A3:
; A4: A5: A6: A7:
;--------------------------------------------
VMergeTable
dc.l oneDeep-VMergeTable ;src 1-bit/pixel
dc.l ndeep-VMergeTable ;src 2-bit/pixel
dc.l ndeep-VMergeTable ;src 4-bit/pixel
dc.l ndeep-VMergeTable ;src 8-bit/pixel
dc.l Average16and32-VMergeTable ;src 16-bit/pixel
dc.l Average16and32-VMergeTable ;src 32-bit/pixel
;--------------------------------------------
;
; Loop to combine d7 pixels of source and dest using mask
;
; ENTRY:
; D0: scratch A0: scratch
; D1: scratch A1: mask ptr
; D2: scratch A2: destination
; D3: scratch A3: src and dst ptr
; D4: scratch A4: src pmtable A5: rowbytes
; D5: srcAlign A5: rowbytes
; D6: realDepth (pixel size)
; D7: byte Count (zero based)
;
; There are 12 different cases: all combinations of source and mask
; being either 16- or 32-bits/pixel and dest being any depth. A mask
; of $ff means take source. The mask value ranges from 0-$7f,$81-$100.