mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2025-03-19 08:31:06 +00:00
12035 lines
362 KiB
Plaintext
12035 lines
362 KiB
Plaintext
|
;
|
|||
|
; File: Stretch.a
|
|||
|
;
|
|||
|
; Copyright: <09> 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<73>t get built for
|
|||
|
; CubeE. (It<49>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.
|
|||
|
; <<3C>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
|
|||
|
; <<3C>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.
|
|||
|
; <<3C>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!
|
|||
|
;
|
|||
|
;<3B>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 <20> dst rect or maskBits <20> 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<6F>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 <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.
|
|||
|
|
|||
|
CombineTable
|
|||
|
;SRC DST MASK ENTRY
|
|||
|
dc.l Combine32in32-CombineTable ;32 ind 32 0
|
|||
|
dc.l Combine321632-CombineTable ;32 16 32 1
|
|||
|
dc.l Combine323232-CombineTable ;32 32 32 2
|
|||
|
|
|||
|
|
|||
|
;*******************************************************************
|
|||
|
;
|
|||
|
; CombineMaskCase
|
|||
|
;
|
|||
|
; Loop to combine d7 pixels of source and dest using mask
|
|||
|
;
|
|||
|
;ENTRY:
|
|||
|
; D0: (dst) A0: address of routine called
|
|||
|
; D1: (src) A1: mask ptr
|
|||
|
; D2: (dst component) A2: destination
|
|||
|
; D3: (mask) A3: src and dst ptr
|
|||
|
; D4: (build pixel) A4: src pmtable A5: rowbytes
|
|||
|
; D5: srcAlign A5:
|
|||
|
; 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.
|
|||
|
;
|
|||
|
;EXIT:
|
|||
|
;
|
|||
|
;
|
|||
|
;*******************************************************************
|
|||
|
;
|
|||
|
; handle merging with indexed destinations, assume source and mask are 32 bpp
|
|||
|
;
|
|||
|
; Promote destination pixel to 32-bits/pixel, combine with source on a
|
|||
|
; component by component basis according to value stored in mask
|
|||
|
;
|
|||
|
Combine32in32
|
|||
|
bfextu (a2){d5:d6},d0 ;get a pixel of destination
|
|||
|
add d6,d5 ;bump to next pixel
|
|||
|
moveq #0,d4
|
|||
|
move.w d4,d1 ;clear regs
|
|||
|
move.w d4,d2
|
|||
|
move.w d4,d3
|
|||
|
move.b 1(a3),d2 ;get red of source
|
|||
|
move.b ctTable+rgb+red(a4,d0.w*8),d1 ;get destination red into virgin reg
|
|||
|
|
|||
|
sub.w d2,d1 ;red dst - red source
|
|||
|
move.b 1(a1),d3 ;get red mask
|
|||
|
bpl.s @1
|
|||
|
addq #1,d3 ;make mask go from 0 to 256
|
|||
|
@1
|
|||
|
muls.w d3,d1
|
|||
|
lsl.w #8,d2 ;src*256
|
|||
|
add.w d2,d1 ;(dst-src)*mask+(src*256)
|
|||
|
move.w d1,d4 ;new red component (0000RRXX)
|
|||
|
;
|
|||
|
; now do green
|
|||
|
;
|
|||
|
move.w #0,d1 ;clear regs
|
|||
|
move.w d1,d2
|
|||
|
move.w d1,d3
|
|||
|
move.b 2(a3),d2 ;get green of source
|
|||
|
move.b ctTable+rgb+green(a4,d0.w*8),d1 ;get destination green into virgin reg
|
|||
|
|
|||
|
sub.w d2,d1 ;green dst - green src
|
|||
|
move.b 2(a1),d3 ;get green mask
|
|||
|
bpl.s @2
|
|||
|
addq #1,d3 ;make mask go from 0 to 256
|
|||
|
@2
|
|||
|
muls.w d3,d1 ;(dst-src)*mask
|
|||
|
lsl.w #8,d2 ;src*256
|
|||
|
add.w d2,d1 ;(dst-src)*mask+(src*256)
|
|||
|
lsr.w #8,d1
|
|||
|
move.b d1,d4 ;move in green component (0000RRGG)
|
|||
|
;
|
|||
|
; now do blue
|
|||
|
;
|
|||
|
move.w #0,d1 ;clear regs
|
|||
|
move.w d1,d2
|
|||
|
move.w d1,d3
|
|||
|
move.b 3(a3),d2 ;get blue of source
|
|||
|
move.b ctTable+rgb+blue(a4,d0.w*8),d1 ;get destination green into virgin reg
|
|||
|
|
|||
|
sub.w d2,d1 ;blue dst - blue src
|
|||
|
move.b 3(a1),d3 ;get green mask
|
|||
|
bpl.s @3
|
|||
|
addq #1,d3 ;make mask go from 0 to 256
|
|||
|
@3
|
|||
|
muls.w d3,d1 ;(dst-src)*mask
|
|||
|
lsl.w #8,d2 ;src*256
|
|||
|
add.w d2,d1 ;(dst-src)*mask+(src*256)
|
|||
|
lsr.w #8,d1
|
|||
|
lsl.l #8,d4 ;result = 00RRGG00
|
|||
|
move.b d1,d4 ;move in blue component (00RRGGBB)
|
|||
|
MOVE.L d4,(A3)+ ;PUT A LONG TO SRCBUF
|
|||
|
addq #4,a1 ;bump to next mask
|
|||
|
DBRA D7,Combine32in32 ;LOOP FOR ALL LONGS
|
|||
|
rts
|
|||
|
|
|||
|
;
|
|||
|
; Handle when src and mask are 32 bpp, dst is 16 bpp
|
|||
|
;
|
|||
|
Combine321632
|
|||
|
move.l maskBC,a0 ;get useful Konstantin
|
|||
|
Combine321632Loop
|
|||
|
move.l (a1)+,d5 ;get a pixel of mask
|
|||
|
bne.s @maskNonZero
|
|||
|
addq.l #4,a3 ;mask 0 -> all src so just skip
|
|||
|
addq.l #2,a2 ;bump destination
|
|||
|
dbra D7,Combine321632Loop ;LOOP FOR ALL LONGS
|
|||
|
rts
|
|||
|
@maskNonZero
|
|||
|
move.w (a2)+,d4 ;get a pixel of destination
|
|||
|
cmp.l d5,a0 ;mask $7FFF?
|
|||
|
beq @Writeout555 ;all dst, so write out d4
|
|||
|
|
|||
|
@DoSlowCase
|
|||
|
move.w d4,d0 ;copy destination pixel
|
|||
|
move.l (a3),d6 ;get a pixel of source
|
|||
|
|
|||
|
moveq #0,d4
|
|||
|
|
|||
|
move.w d4,d1 ;clear regs
|
|||
|
move.w d4,d3
|
|||
|
move.w d4,d2
|
|||
|
|
|||
|
swap d6
|
|||
|
move.b d6,d2 ;get red of source
|
|||
|
swap d6
|
|||
|
|
|||
|
move.w d0,d4 ;red destination in 14 - 10
|
|||
|
lsr.w #7,d4 ;move red to bits 7 - 3
|
|||
|
and.w #$00f8,d4 ;strip bits 2 - 0
|
|||
|
move.b d4,d3
|
|||
|
lsr.b #5,d3 ;replicate top 3 bits
|
|||
|
or.b d3,d4 ;merge top five bits with top 3 bits
|
|||
|
|
|||
|
sub.w d2,d4 ;red dst - red src
|
|||
|
swap d5
|
|||
|
move.b d5,d3 ;get red mask
|
|||
|
bpl.s @1
|
|||
|
addq #1,d3 ;make mask go from 0 to 256
|
|||
|
@1
|
|||
|
swap d5
|
|||
|
muls.w d3,d4 ;d2=(dst-src)*mask
|
|||
|
asr.l #8,d4 ;(dst-src)*mask/256
|
|||
|
add.l d2,d4 ;(dst-src)*mask/256+(src)
|
|||
|
swap d4 ;new red component (00RR0000)
|
|||
|
;
|
|||
|
; now do green
|
|||
|
;
|
|||
|
move.w d6,d1 ;get green of source
|
|||
|
lsr.w #8,d1 ;get green in low byte
|
|||
|
|
|||
|
move.w d0,d2 ;green destination in 9 - 5
|
|||
|
lsr.w #2,d2 ;green in bits 7 - 3
|
|||
|
and.w #$00f8,d2 ;strip bits 2 - 0
|
|||
|
move.b d2,d3
|
|||
|
lsr.b #5,d3 ;replicate top 3 bits
|
|||
|
or.b d3,d2 ;merge top five bits with top 3 bits
|
|||
|
|
|||
|
sub.w d1,d2 ;green dst - green src
|
|||
|
move.w d5,d3 ;get green mask
|
|||
|
lsr.w #8,d3
|
|||
|
tst.b d3
|
|||
|
bpl.s @2
|
|||
|
addq #1,d3 ;make mask go from 0 to 256
|
|||
|
@2
|
|||
|
muls.w d3,d2 ;d2 = (dst-src)*mask
|
|||
|
lsl.w #8,d1 ;src*256
|
|||
|
add.w d1,d2 ;(dst-src)*mask+(src*256)
|
|||
|
move.w d2,d4 ;move in green component (00RRGGxx)
|
|||
|
;
|
|||
|
; now do blue
|
|||
|
;
|
|||
|
move.w #0,d1 ;clear regs
|
|||
|
move.w d1,d3
|
|||
|
move.b d6,d1 ;get blue of source
|
|||
|
|
|||
|
move.b d0,d2 ;blue destination in 4 - 0
|
|||
|
lsl.w #3,d2 ;green in bits 7 - 3
|
|||
|
and.w #$00f8,d2 ;strip bits 2 - 0
|
|||
|
move.b d2,d3
|
|||
|
lsr.b #5,d3 ;replicate top 3 bits
|
|||
|
or.b d3,d2 ;merge top five bits with top 3 bits
|
|||
|
sub.w d1,d2 ;blue dst - blue src
|
|||
|
|
|||
|
move.b d5,d3 ;get green mask
|
|||
|
bpl.s @3
|
|||
|
addq #1,d3 ;make mask go from 0 to 256
|
|||
|
@3
|
|||
|
muls.w d3,d2 ;(dst-src)*mask
|
|||
|
lsl.w #8,d1 ;src*256
|
|||
|
add.w d1,d2 ;(src-dst)*mask+(dst*256)
|
|||
|
lsr.w #8,d2
|
|||
|
move.b d2,d4 ;move in blue component (00RRGGBB)
|
|||
|
@writeoutPixel
|
|||
|
move.l d4,(a3)+ ;PUT A LONG TO SRCBUF
|
|||
|
dbra D7,Combine321632Loop ;LOOP FOR ALL LONGS
|
|||
|
rts
|
|||
|
@Writeout555
|
|||
|
;
|
|||
|
; d4 has pixel to write out in 555: convert to 888 and write it out
|
|||
|
;
|
|||
|
moveq #0,d0
|
|||
|
move.w d4,d0 ;red in 14-10
|
|||
|
and.w #$7c00,d0
|
|||
|
swap d0 ;red in 31-24
|
|||
|
lsr.l #7,d0 ;red in 23-16
|
|||
|
move.w d4,d0 ;green in 9-5
|
|||
|
and.w #$03e0,d0
|
|||
|
lsl.w #6,d0 ;green in 15-8
|
|||
|
move.b d4,d0 ;blue in 4-0
|
|||
|
and.b #$1f,d0
|
|||
|
lsl.b #3,d0 ;blue in 7-0, green in 15-8, red in 23-16
|
|||
|
move.l d0,d4
|
|||
|
bra.s @writeoutPixel
|
|||
|
|
|||
|
;
|
|||
|
; Handle when src, mask, dst all 32 bpp
|
|||
|
;
|
|||
|
Combine323232
|
|||
|
move.l maskBC,a0 ;get useful Konstantin
|
|||
|
Combine323232Loop
|
|||
|
move.l (a1)+,d5 ;get a pixel of mask
|
|||
|
bne.s @maskNonZero ;no, go the hard way
|
|||
|
addq.l #4,a3 ;yes, all src so just skip
|
|||
|
addq.l #4,a2 ;bump dst
|
|||
|
dbra D7,Combine323232Loop ;LOOP FOR ALL LONGS
|
|||
|
rts
|
|||
|
@maskNonZero
|
|||
|
move.l (a2)+,d4 ;get a pixel of destination
|
|||
|
cmp.l d5,a0 ;mask $00FFFFFF?
|
|||
|
beq.s @WriteoutPixel ;all dst, so write out d4
|
|||
|
|
|||
|
@DoSlowCase
|
|||
|
move.l d4,d0 ;copy destination pixel
|
|||
|
move.l (a3),d6 ;get a pixel of source
|
|||
|
|
|||
|
moveq #0,d4
|
|||
|
|
|||
|
move.w d4,d1 ;clear regs
|
|||
|
move.w d4,d2
|
|||
|
move.w d4,d3
|
|||
|
|
|||
|
swap d6
|
|||
|
move.b d6,d2 ;get red of source
|
|||
|
swap d0
|
|||
|
swap d6
|
|||
|
move.b d0,d4 ;get a pixel of destination
|
|||
|
swap d0
|
|||
|
sub.w d2,d4 ;red dst - red src
|
|||
|
swap d5
|
|||
|
move.b d5,d3 ;get red mask
|
|||
|
bpl.s @1
|
|||
|
addq #1,d3 ;make mask go from 0 to 256
|
|||
|
@1
|
|||
|
swap d5
|
|||
|
muls.w d3,d4
|
|||
|
asr.l #8,d4 ;(dst-src)*mask/256
|
|||
|
add.l d2,d4 ;(dst-src)*mask/256+(src)
|
|||
|
swap d4 ;new red component (00RR0000)
|
|||
|
;
|
|||
|
; now do green
|
|||
|
;
|
|||
|
move.w d6,d1 ;get green of source
|
|||
|
move.w d0,d2 ;get a pixel of destination
|
|||
|
lsr.w #8,d1 ;get green in low byte
|
|||
|
lsr.w #8,d2 ;get green in low byte
|
|||
|
|
|||
|
sub.w d1,d2 ;green dst - green src
|
|||
|
move.w d5,d3 ;get green mask
|
|||
|
lsr.w #8,d3
|
|||
|
tst.b d3
|
|||
|
bpl.s @2
|
|||
|
addq #1,d3 ;make mask go from 0 to 256
|
|||
|
@2
|
|||
|
muls.w d3,d2 ;(dst-src)*mask
|
|||
|
lsl.w #8,d1 ;src*256
|
|||
|
add.w d1,d2 ;(dst-src)*mask+(src*256)
|
|||
|
move.w d2,d4 ;move in green component (00RRGGxx)
|
|||
|
;
|
|||
|
; now do blue
|
|||
|
;
|
|||
|
move.w #0,d1 ;clear regs
|
|||
|
move.w d1,d2
|
|||
|
move.w d1,d3
|
|||
|
move.b d6,d1 ;get blue of source
|
|||
|
move.b d0,d2 ;get blue of destination
|
|||
|
sub.w d1,d2 ;blue dst - blue src
|
|||
|
|
|||
|
move.b d5,d3 ;get green mask
|
|||
|
bpl.s @3
|
|||
|
addq #1,d3 ;make mask go from 0 to 256
|
|||
|
@3
|
|||
|
muls.w d3,d2 ;(dst-src)*mask
|
|||
|
lsl.w #8,d1 ;src*256
|
|||
|
add.w d1,d2 ;(src-dst)*mask+(dst*256)
|
|||
|
lsr.w #8,d2
|
|||
|
move.b d2,d4 ;move in blue component (00RRGGBB)
|
|||
|
@writeoutPixel
|
|||
|
move.l d4,(a3)+ ;PUT A LONG TO SRCBUF
|
|||
|
dbra D7,Combine323232Loop ;LOOP FOR ALL LONGS
|
|||
|
rts
|
|||
|
|
|||
|
;*********************************************************************
|
|||
|
;
|
|||
|
; Loop to expand and merge D7 scanlines of indexed pixels
|
|||
|
;
|
|||
|
;ENTRY:
|
|||
|
; D0: scratch A0: scratch ptr
|
|||
|
; D1: scratch A1: scratch ptr
|
|||
|
; D2: scratch A2: destination
|
|||
|
; D3: scratch A3: source
|
|||
|
; D4: src longs A4: src pmtable
|
|||
|
; D5: srcAlign A5: rowbytes
|
|||
|
; D6: realDepth (pixel size)
|
|||
|
; D7: Scanline Count (zero based)
|
|||
|
;
|
|||
|
;EXIT:
|
|||
|
;
|
|||
|
; a3: new srcaddr
|
|||
|
;
|
|||
|
;GLOBALS: AvgBufPtr(a6), AvgBufSize(a6)
|
|||
|
;
|
|||
|
;*********************************************************************
|
|||
|
|
|||
|
NDEEP
|
|||
|
|
|||
|
; LOOP FOR ALL LONGS IN SRC SCANLINE
|
|||
|
|
|||
|
move.l a3,a0 ;point to source
|
|||
|
move.l a2,a1 ;point to destination
|
|||
|
move d4,d1 ;get count of longs
|
|||
|
|
|||
|
@Align bfextu (a0){d5:0},d0 ;get an aligned long of source
|
|||
|
add #4,a0 ;bump to next long
|
|||
|
move.l d0,(a1)+ ;put a long to destination
|
|||
|
dbra d1,@Align ;loop for all longs
|
|||
|
|
|||
|
; add.l a5,a3 ;bump source to next row
|
|||
|
_pmVersion
|
|||
|
subq #1,d7
|
|||
|
bpl.s @1
|
|||
|
rts
|
|||
|
|
|||
|
; do verticle merging
|
|||
|
@1
|
|||
|
move d6,d3 ;get pixel depth
|
|||
|
move.w d4,a4 ;save count of longs
|
|||
|
NdeepMerge
|
|||
|
|
|||
|
move.l d7,-(sp) ;save count of lines to do
|
|||
|
move.l a3,a0 ;point to source
|
|||
|
move.l a2,a1 ;point to destination
|
|||
|
move a4,d6 ;get long count
|
|||
|
moveq #0,d4 ;start at beginning of long
|
|||
|
|
|||
|
ndlong bfextu (a0){d5:0},d0 ;extract a long from source
|
|||
|
move.l (a1),d1 ;get next long from destination
|
|||
|
|
|||
|
ndpxl bfextu d0{d4:d3},d2 ;get pixel from source
|
|||
|
bfextu d1{d4:d3},d7 ;get pixel from destination
|
|||
|
cmp.l d7,d2 ;which is greater?
|
|||
|
ble.s nochng ;only change if source is greater
|
|||
|
bfins d2,d1{d4:d3} ;replace pixel is destination
|
|||
|
NOCHNG add d3,d4 ;bump to next pixel within long
|
|||
|
and #$1f,d4 ;done with long?
|
|||
|
bne.s ndpxl ;no, keep looping
|
|||
|
|
|||
|
add #4,a0 ;bump src offset
|
|||
|
move.l d1,(a1)+ ;write to destination
|
|||
|
dbra d6,ndlong ;repeat for all longs
|
|||
|
|
|||
|
; add.l a5,a3 ;add rowbytes to src pointer
|
|||
|
_pmVersion
|
|||
|
move.l (sp)+,d7 ;retrieve line count
|
|||
|
dbra d7,NdeepMerge ;loop while there are lines left
|
|||
|
rts
|
|||
|
|
|||
|
;*********************************************************************
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;*********************************************************************
|
|||
|
;
|
|||
|
; Loop to expand and merge D7 scanlines (0-based) to direct destination
|
|||
|
;
|
|||
|
; Src sizes (d6) of 1-8 are promoted to 32-bit/pixel.
|
|||
|
; Src size (d6) of 16 are carried across to 16-bit destinations.
|
|||
|
;
|
|||
|
;ENTRY:
|
|||
|
; D0: scratch A0: scratch ptr
|
|||
|
; D1: scratch A1: scratch ptr
|
|||
|
; D2: scratch A2: destination
|
|||
|
; D3: scratch A3: source
|
|||
|
; D4: src longs A4: src pmtable A5: rowbytes
|
|||
|
; D5: srcAlign A5: rowbytes
|
|||
|
; D6: realDepth (pixel size)
|
|||
|
; D7: Scanline Count (zero based)
|
|||
|
;
|
|||
|
;EXIT:
|
|||
|
;
|
|||
|
; a3: new srcaddr
|
|||
|
;
|
|||
|
;GLOBALS: AvgBufPtr(a6), AvgBufSize(a6)
|
|||
|
;
|
|||
|
|
|||
|
Average16and32
|
|||
|
|
|||
|
; First check if only one scanline to be merged;
|
|||
|
; If so just copy from srcAddr to SrcBuf, expanding if nec.
|
|||
|
; else fill average buffer, calc average and move to srcbuf
|
|||
|
|
|||
|
tst.w d7 ;doing more than 1 scanline?
|
|||
|
bne @Average ;yes, average scan lines
|
|||
|
|
|||
|
;-------------------------------------------------------------------------
|
|||
|
;
|
|||
|
; Just copy srcAddr to SrcBuf, expanding pixels if necessary
|
|||
|
;
|
|||
|
move.l d4,d1 ;get srclongs
|
|||
|
move.l a3,a0
|
|||
|
|
|||
|
;
|
|||
|
; If dithering or averaging an indexed src then expand it to 32 bit/pixel RGB data.
|
|||
|
;
|
|||
|
cmp.w #16,d6 ;is srcpix indexed?
|
|||
|
bgt.s @Align ;32-bit => just copy
|
|||
|
beq.s @Align0 ;16-bit => just copy
|
|||
|
;
|
|||
|
; if there is no color table, ramp each entry between the foreground and background color.
|
|||
|
;
|
|||
|
tst.l a4 ;color table?
|
|||
|
beq.s @NoCTab
|
|||
|
|
|||
|
@Xpand BFEXTU (A0){D5:D6},D0 ;get a pixel of src
|
|||
|
add d6,d5 ;bump to next pixel
|
|||
|
move.l ctTable+rgb+red(a4,d0.w*8),d2 ;get RRRRGGGG in d2
|
|||
|
lsr.l #8,d2 ;get 00RRRRGG
|
|||
|
lsl.w #8,d2 ;get 00RRGG00
|
|||
|
move.b ctTable+rgb+blue(a4,d0.w*8),d2 ;get 00RRGGBB in d2
|
|||
|
MOVE.L d2,(A2)+ ;put a long to destination
|
|||
|
DBRA D1,@Xpand ;loop for all longs
|
|||
|
bra @SrcBufFull
|
|||
|
|
|||
|
@NoCTab BFEXTU (A0){D5:D6},D0 ;get a pixel of src
|
|||
|
add d6,d5 ;bump to next pixel
|
|||
|
|
|||
|
;
|
|||
|
; replicate pixel first to 8 bits and then to 24
|
|||
|
;
|
|||
|
move.w d0,d3
|
|||
|
MOVEQ #8,D2 ;replicate to byte size
|
|||
|
@NXTPXL SUB D6,D2 ;SAY WE'VE DONE A PIXEL
|
|||
|
BLE.S @RepDone ;=>IT WAS THE LAST ONE
|
|||
|
LSL.w D6,D0 ;replicate
|
|||
|
OR.w D3,D0 ;INSTALL FG PIXEL
|
|||
|
BRA.S @NXTPXL ;=>DO ENTIRE LONG
|
|||
|
; d0 has xxxxxxBB
|
|||
|
@RepDone
|
|||
|
not.b d0 ;invert it since 00 = black in RGB and white in index
|
|||
|
moveq #0,d2 ;clear high 8 bits
|
|||
|
move.b d0,d2
|
|||
|
swap d2
|
|||
|
move.b d0,d2
|
|||
|
lsl.w #8,d2
|
|||
|
move.b d0,d2
|
|||
|
MOVE.L d2,(A2)+ ;put a long to destination
|
|||
|
DBRA D1,@NoCTab ;loop for all longs
|
|||
|
bra.s @SrcBufFull
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
@Align0
|
|||
|
;
|
|||
|
; promote 16-bit src/mask to 32 bit if deep mask
|
|||
|
;
|
|||
|
tst d5 ;alignment
|
|||
|
beq.s @Align
|
|||
|
addq #2,a0 ;do alignment of 16 bit
|
|||
|
@Align
|
|||
|
tst.w maskshift(a6) ;promote 16 if deep mask
|
|||
|
beq.s @CopyLoop ;
|
|||
|
cmp.w #16,d6 ;16 bit?
|
|||
|
bne.s @CopyLoop
|
|||
|
;
|
|||
|
; Promote 16 bit to 32 bit using existing Scale16to32 routine
|
|||
|
;
|
|||
|
; a0 ptr to src
|
|||
|
; a1 ptr to beginning of dst
|
|||
|
; a2 ptr to end of dst
|
|||
|
;
|
|||
|
move.l a2,a1 ;get beginning of dst
|
|||
|
addq #1,d4 ;make destination 1-based
|
|||
|
lsl.l #2,d4 ;calc size of dst: longs->bytes *4 <7JULY90 KON>
|
|||
|
add.l d4,a2 ;calc end of dst ptr
|
|||
|
; add.l a5,a3 ;bump source to next row
|
|||
|
_pmVersion
|
|||
|
jmp Scale16to32 ;inherits return address
|
|||
|
|
|||
|
@CopyLoop
|
|||
|
move.l (a0)+,(a2)+ ;copy source to destination
|
|||
|
dbra D1,@CopyLoop ;loop for all longs
|
|||
|
|
|||
|
@SrcBufFull
|
|||
|
; add.l a5,a3 ;bump source to next row
|
|||
|
_pmVersion
|
|||
|
rts
|
|||
|
|
|||
|
;------------------------------------------------------------------------
|
|||
|
|
|||
|
|
|||
|
@Average
|
|||
|
;
|
|||
|
; average 16 or 32 bit source
|
|||
|
;
|
|||
|
useAverageBuf
|
|||
|
moveq #0,d1 ;get a useful constant
|
|||
|
|
|||
|
; Init R-G-B accumulation buffer to zero
|
|||
|
|
|||
|
move.w ABufSize(a6),d0 ;get count of longs in buffer
|
|||
|
move.l AvrgBuf(a6),a0 ;point at buffer
|
|||
|
@1 move.l d1,(a0)+ ;clear it out
|
|||
|
dbra d0,@1
|
|||
|
|
|||
|
;
|
|||
|
; Are we averaging 16-bit or 32-bit data?
|
|||
|
;
|
|||
|
move.w d7,-(sp) ;save scanline count
|
|||
|
cmp #16,d6 ;16-bit data?
|
|||
|
beq NextAverageV16 ;YES: do 16-bit average loop
|
|||
|
|
|||
|
; Top of 32-bit scanline averaging loop
|
|||
|
|
|||
|
NextAverageV32
|
|||
|
|
|||
|
; loop for all longs in source scanline
|
|||
|
|
|||
|
move.l d5,d2 ;GET SHIFT FOR SRC ALIGNMENT
|
|||
|
move.l a3,a0 ;point to source buffer
|
|||
|
move.l AvrgBuf(A6),A1 ;point to accumulation buffer
|
|||
|
move d4,d3 ;get count of source
|
|||
|
|
|||
|
;-------------------------------------------------------------------------
|
|||
|
;
|
|||
|
; If dithering or averaging an indexed src then first pre-Expand it
|
|||
|
; to 32 bit/pixel RGB data.
|
|||
|
;
|
|||
|
cmp.w #32,d6 ;promoting src to RGB?
|
|||
|
beq @NDLONG0 ;no, all ok
|
|||
|
;
|
|||
|
; if no color table, use grey scale
|
|||
|
;
|
|||
|
tst.l a4 ;color table?
|
|||
|
beq.s @NoCTab
|
|||
|
|
|||
|
@Xpand BFEXTU (a0){D2:D6},D0 ;get a pixel of src
|
|||
|
add d6,d2 ;bump to next pixel
|
|||
|
move.l ctTable+rgb+red(a4,d0.w*8),d1 ;get RRrrGGgg
|
|||
|
swap d1 ;get GGggRRrr
|
|||
|
lsr.w #8,d1 ;get GGgg00RR
|
|||
|
add.w d1,(a1)+ ;accumulate red value
|
|||
|
swap d1 ;get 00RRGGgg
|
|||
|
lsr.w #8,d1 ;get 00RR00GG
|
|||
|
add.w d1,(a1)+ ;accumulate green value
|
|||
|
move.b ctTable+rgb+blue(a4,d0.w*8),d1 ;get 00RR00BB
|
|||
|
add.w d1,(a1)+ ;accumulate blue value
|
|||
|
dbra d3,@Xpand ;LOOP FOR ALL LONGS
|
|||
|
; add.l a5,a3 ;bump to next source row
|
|||
|
_pmVersion
|
|||
|
dbra d7, NextAverageV32 ;accumulate d7 scanlines
|
|||
|
bra MakeAverage
|
|||
|
|
|||
|
|
|||
|
@NoCTab BFEXTU (A0){D5:D6},D0 ;get a pixel of src
|
|||
|
add d6,d5 ;bump to next pixel
|
|||
|
|
|||
|
;
|
|||
|
; replicate pixel first to 8 bits and then to 24
|
|||
|
;
|
|||
|
move.w d0,d1
|
|||
|
MOVEQ #8,D2 ;replicate to byte size
|
|||
|
@NXTPXL SUB D6,D2 ;SAY WE'VE DONE A PIXEL
|
|||
|
BLE.S @RepDone ;=>IT WAS THE LAST ONE
|
|||
|
LSL.w D6,D0 ;replicate
|
|||
|
OR.w D1,D0 ;INSTALL FG PIXEL
|
|||
|
BRA.S @NXTPXL ;=>DO ENTIRE LONG
|
|||
|
; d0 has xxxxxxBB
|
|||
|
@RepDone
|
|||
|
not.b d0 ;invert it since 00 = black in RGB and white in index
|
|||
|
and.w #$00FF,d0
|
|||
|
add.w d0,(a1)+ ;accumulate red value
|
|||
|
add.w d0,(a1)+ ;accumulate green value
|
|||
|
add.w d0,(a1)+ ;accumulate blue value
|
|||
|
dbra d3,@NoCTab ;LOOP FOR ALL LONGS
|
|||
|
; add.l a5,a3 ;bump to next source row
|
|||
|
_pmVersion
|
|||
|
dbra d7, NextAverageV32 ;accumulate d7 scanlines
|
|||
|
bra.s MakeAverage
|
|||
|
|
|||
|
;------------------------------------------------------------------------
|
|||
|
;
|
|||
|
;
|
|||
|
;
|
|||
|
@NDLONG0
|
|||
|
moveq #0,d1
|
|||
|
moveq #0,d2 ;use for extending to word data
|
|||
|
moveq #0,d5
|
|||
|
|
|||
|
@NDLONG move.l (a0)+,D0 ;EXTRACT A LONG FROM SRC
|
|||
|
move.b d0,d1 ;pick up blue component as a word
|
|||
|
|
|||
|
lsr.l #8,d0 ;toss blue
|
|||
|
move.b d0,d2 ;pick up green component as a word
|
|||
|
|
|||
|
lsr.l #8,d0 ;toss green
|
|||
|
move.b d0,d5 ;pick up red component as a word
|
|||
|
add.w d5,(a1)+ ;accumulate blue value
|
|||
|
add.w d2,(a1)+ ;accumulate green value
|
|||
|
add.w d1,(a1)+ ;accumulate red value
|
|||
|
DBRA d3,@NDLONG ;=>REPEAT FOR ALL LONGS
|
|||
|
; add.l a5,a3 ;bump to next source row
|
|||
|
_pmVersion
|
|||
|
dbra d7, NextAverageV32 ;accumulate d7 scanlines
|
|||
|
|
|||
|
MakeAverage
|
|||
|
move.w (sp)+,d7 ;restore scanline count (0-based)
|
|||
|
addq #1,d7 ;make it 1 based
|
|||
|
|
|||
|
; Now we must compute the average of the accumulated R-G-B's
|
|||
|
|
|||
|
move.l a2,a1 ;pointer to destination buffer
|
|||
|
move.l AvrgBuf(A6),A0 ;point to accumulation buffer
|
|||
|
move d4,d3 ;longs in source
|
|||
|
|
|||
|
cmp.w #2,d7 ;merged exactly 2 scanlines?
|
|||
|
beq.s @useShift ;avoid division by using a shift
|
|||
|
|
|||
|
@hardWay
|
|||
|
moveq #0,d1 ;use for extending to word data
|
|||
|
move.w (a0)+,d1 ;pick up red accumulation
|
|||
|
divu.w d7,d1 ;get red average
|
|||
|
move.b d1,d0 ;put in low byte of pixel <KON MAY90>
|
|||
|
lsl.l #8,d0 ;make room for next component
|
|||
|
|
|||
|
moveq #0,d1 ;use for extending to word data
|
|||
|
move.w (a0)+,d1 ;pick up green accumulation
|
|||
|
divu.w d7,d1 ;get green average
|
|||
|
move.b d1,d0 ;put in low byte of pixel
|
|||
|
lsl.l #8,d0 ;make room for next component
|
|||
|
|
|||
|
moveq #0,d1 ;use for extending to word data
|
|||
|
move.w (a0)+,d1 ;pick up blue accumulation
|
|||
|
divu.w d7,d1 ;get red average
|
|||
|
move.b d1,d0 ;put in low byte of pixel
|
|||
|
move.l d0,(a1)+ ;dump pixel into destination
|
|||
|
dbra d3,@hardWay ;loop for all src longs
|
|||
|
rts
|
|||
|
|
|||
|
@useShift
|
|||
|
moveq #0,d0 ;zero alpha channel <KON MAY90>
|
|||
|
move.w (a0)+,d1 ;pick up red accumulation
|
|||
|
lsr.w #1,d1 ;get red average
|
|||
|
move.b d1,d0 ;put in low byte of pixel <KON MAY90>
|
|||
|
lsl.l #8,d0 ;make room for next component
|
|||
|
move.w (a0)+,d1 ;pick up green accumulation
|
|||
|
lsr.w #1,d1 ;get green average
|
|||
|
move.b d1,d0 ;put in low byte of pixel
|
|||
|
lsl.l #8,d0 ;make room for next component
|
|||
|
move.w (a0)+,d1 ;pick up blue accumulation
|
|||
|
lsr.w #1,d1 ;get red average
|
|||
|
move.b d1,d0 ;put in low byte of pixel
|
|||
|
move.l d0,(a1)+ ;dump pixel into srcBuf
|
|||
|
dbra d3,@useShift ;loop for all src longs
|
|||
|
rts
|
|||
|
|
|||
|
;-------------- Top of 16-bit average loop -----------------
|
|||
|
; Top of 16-bit scanline averaging loop
|
|||
|
; d7 and word at top of stack is number of scanlines to merge
|
|||
|
;
|
|||
|
NextAverageV16
|
|||
|
|
|||
|
;
|
|||
|
; loop for all longs in source scanline
|
|||
|
;
|
|||
|
move.l a3,a0 ;get source address
|
|||
|
move.l AvrgBuf(A6),A1 ;point to accumulation buffer
|
|||
|
move d4,d5 ;get count of source
|
|||
|
moveq #0,d1 ;use for extending to word data
|
|||
|
moveq #0,d2 ;use for extending to word data
|
|||
|
moveq #0,d3 ;use for extending to word data
|
|||
|
|
|||
|
;------------------------------------------------------------------------
|
|||
|
|
|||
|
@NDLONG move.l (A0)+,D0 ;EXTRACT A LONG FROM SRC (2 pixels)
|
|||
|
move.b d0,d3 ;pick up blue component as a byte
|
|||
|
and.b #$1f,d3
|
|||
|
lsr.l #5,d0 ;toss blue
|
|||
|
move.b d0,d2 ;pick up green component as a byte
|
|||
|
and.b #$1f,d2
|
|||
|
lsr.l #5,d0 ;toss green
|
|||
|
move.b d0,d1 ;pick up red component as a word
|
|||
|
and.b #$1f,d1
|
|||
|
add.w d1,(a1)+ ;accumulate red value
|
|||
|
add.w d2,(a1)+ ;accumulate green value
|
|||
|
add.w d3,(a1)+ ;accumulate blue value
|
|||
|
;
|
|||
|
; Do second pixel in long
|
|||
|
;
|
|||
|
lsr.l #5+1,d0 ;move to second 16-bit pixel in long
|
|||
|
move.b d0,d3 ;pick up blue component as a byte
|
|||
|
and.b #$1f,d3
|
|||
|
lsr.l #5,d0 ;toss blue
|
|||
|
move.b d0,d2 ;pick up green component as a byte
|
|||
|
and.b #$1f,d2
|
|||
|
lsr.l #5,d0 ;toss green
|
|||
|
move.b d0,d1 ;pick up red component as a word
|
|||
|
and.b #$1f,d1
|
|||
|
add.w d1,(a1)+ ;accumulate red value
|
|||
|
add.w d2,(a1)+ ;accumulate green value
|
|||
|
add.w d3,(a1)+ ;accumulate blue value
|
|||
|
|
|||
|
dbra d5,@NDLONG ;repeat for all longs
|
|||
|
|
|||
|
; add.l a5,a3 ;bump source to next row
|
|||
|
_pmVersion
|
|||
|
dbra d7,NextAverageV16 ;loop while scan lines left
|
|||
|
|
|||
|
move.w (a7)+,d7 ;retrieve # scanlines merged (0-based)
|
|||
|
addq #1,d7 ;make it 1 based
|
|||
|
|
|||
|
; Now we must compute the average of the accumulated R-G-B's
|
|||
|
|
|||
|
move.l a2,a1 ;point to destination buffer
|
|||
|
move.l AvrgBuf(A6),A0 ;point to accumulation buffer
|
|||
|
move d4,d3 ;longs in source
|
|||
|
;
|
|||
|
; if it's a deep mask, we promote all 16-bit values to 32-bit
|
|||
|
;
|
|||
|
move.w maskshift(a6),d0
|
|||
|
cmp.w #4,d0
|
|||
|
bge Promote16Loop
|
|||
|
|
|||
|
cmp.w #2,d7 ;two scan lines merged?
|
|||
|
beq.s @useShift ;avoid division by using a shift
|
|||
|
|
|||
|
@hardWay
|
|||
|
moveq #0,d1 ;use for extending to word data
|
|||
|
move.w (a0)+,d1 ;pick up red accumulation
|
|||
|
divu.w d7,d1 ;get red average (alpha channel [bit 6] should be clear)
|
|||
|
move.w d1,d0 ;put in low byte of pixel (only 6 bits count)
|
|||
|
|
|||
|
lsl.l #5,d0 ;make room for next component
|
|||
|
moveq #0,d1 ;use for extending to word data
|
|||
|
move.w (a0)+,d1 ;pick up green accumulation
|
|||
|
divu.w d7,d1 ;get green average
|
|||
|
or.b d1,d0 ;put in low byte of pixel
|
|||
|
|
|||
|
lsl.l #5,d0 ;make room for next component
|
|||
|
moveq #0,d1 ;use for extending to word data
|
|||
|
move.w (a0)+,d1 ;pick up blue accumulation
|
|||
|
divu.w d7,d1 ;get red average
|
|||
|
or.b d1,d0 ;put in low byte of pixel
|
|||
|
|
|||
|
;
|
|||
|
; Now do second pixel in long
|
|||
|
;
|
|||
|
lsl.l #5+1,d0 ;bump to beginning of second pixel
|
|||
|
moveq #0,d1 ;use for extending to word data
|
|||
|
move.w (a0)+,d1 ;pick up red accumulation
|
|||
|
divu.w d7,d1 ;get red average (alpha channel [bit 6] should be clear)
|
|||
|
or.w d1,d0 ;put in low byte of pixel (only 5 bits count)
|
|||
|
|
|||
|
lsl.l #5,d0 ;make room for next component
|
|||
|
moveq #0,d1 ;use for extending to word data
|
|||
|
move.w (a0)+,d1 ;pick up green accumulation
|
|||
|
divu.w d7,d1 ;get green average
|
|||
|
or.b d1,d0 ;put in low byte of pixel
|
|||
|
|
|||
|
lsl.l #5,d0 ;make room for next component
|
|||
|
moveq #0,d1 ;use for extending to word data
|
|||
|
move.w (a0)+,d1 ;pick up blue accumulation
|
|||
|
divu.w d7,d1 ;get red average
|
|||
|
or.b d1,d0 ;put in low byte of pixel
|
|||
|
|
|||
|
swap d0 ;pixels mixed in AvrgBuf because of how constructed
|
|||
|
move.l d0,(a1)+ ;dump pixel into srcBuf
|
|||
|
dbra d3,@hardWay ;loop for all src longs
|
|||
|
rts
|
|||
|
|
|||
|
@useShift
|
|||
|
move.w (a0)+,d1 ;pick up red accumulation
|
|||
|
lsr.b #1,d1 ;get red average
|
|||
|
move.w d1,d0 ;put in low byte of pixel
|
|||
|
|
|||
|
lsl.l #5,d0 ;make room for next component
|
|||
|
move.w (a0)+,d1 ;pick up green accumulation
|
|||
|
lsr.b #1,d1 ;get green average
|
|||
|
or.b d1,d0 ;put in low byte of pixel
|
|||
|
|
|||
|
lsl.l #5,d0 ;make room for next component
|
|||
|
move.w (a0)+,d1 ;pick up blue accumulation
|
|||
|
lsr.b #1,d1 ;get red average
|
|||
|
or.b d1,d0 ;put in low byte of pixel
|
|||
|
;
|
|||
|
; do second pixel (2/long in 16-bit mode)
|
|||
|
;
|
|||
|
lsl.l #5+1,d0
|
|||
|
move.w (a0)+,d1 ;pick up red accumulation
|
|||
|
lsr.b #1,d1 ;get red average
|
|||
|
or.b d1,d0 ;put in low byte of pixel
|
|||
|
|
|||
|
lsl.l #5,d0 ;make room for next component
|
|||
|
move.w (a0)+,d1 ;pick up green accumulation
|
|||
|
lsr.b #1,d1 ;get green average
|
|||
|
or.b d1,d0 ;put in low byte of pixel
|
|||
|
|
|||
|
lsl.l #5,d0 ;make room for next component
|
|||
|
move.w (a0)+,d1 ;pick up blue accumulation
|
|||
|
lsr.b #1,d1 ;get red average
|
|||
|
or.b d1,d0 ;put in low byte of pixel
|
|||
|
|
|||
|
swap d0
|
|||
|
move.l d0,(a1)+ ;dump pixel into srcBuf
|
|||
|
dbra d3,@useShift ;loop for all src longs
|
|||
|
rts
|
|||
|
|
|||
|
Promote16Loop
|
|||
|
;
|
|||
|
; Average 16 bit values and put result back in AvrgBuf, then call
|
|||
|
; Scale16to32 to promote to 32 bits
|
|||
|
;
|
|||
|
move.l a0,a1 ;copy AvrgBuf ptr
|
|||
|
cmp.w #2,d7 ;two scan lines merged?
|
|||
|
beq.s @useShift ;avoid division by using a shift
|
|||
|
|
|||
|
@hardWay
|
|||
|
moveq #0,d1 ;use for extending to word data
|
|||
|
move.w (a0)+,d1 ;pick up red accumulation
|
|||
|
divu.w d7,d1 ;get red average (alpha channel [bit 6] should be clear)
|
|||
|
move.w d1,d0 ;put in low byte of pixel (only 6 bits count)
|
|||
|
|
|||
|
lsl.l #5,d0 ;make room for next component
|
|||
|
moveq #0,d1 ;use for extending to word data
|
|||
|
move.w (a0)+,d1 ;pick up green accumulation
|
|||
|
divu.w d7,d1 ;get green average
|
|||
|
or.b d1,d0 ;put in low byte of pixel
|
|||
|
|
|||
|
lsl.l #5,d0 ;make room for next component
|
|||
|
moveq #0,d1 ;use for extending to word data
|
|||
|
move.w (a0)+,d1 ;pick up blue accumulation
|
|||
|
divu.w d7,d1 ;get red average
|
|||
|
or.b d1,d0 ;put in low byte of pixel
|
|||
|
|
|||
|
;
|
|||
|
; Now do second pixel in long
|
|||
|
;
|
|||
|
lsl.l #5+1,d0 ;bump to beginning of second pixel
|
|||
|
moveq #0,d1 ;use for extending to word data
|
|||
|
move.w (a0)+,d1 ;pick up red accumulation
|
|||
|
divu.w d7,d1 ;get red average (alpha channel [bit 6] should be clear)
|
|||
|
or.w d1,d0 ;put in low byte of pixel (only 5 bits count)
|
|||
|
|
|||
|
lsl.l #5,d0 ;make room for next component
|
|||
|
moveq #0,d1 ;use for extending to word data
|
|||
|
move.w (a0)+,d1 ;pick up green accumulation
|
|||
|
divu.w d7,d1 ;get green average
|
|||
|
or.b d1,d0 ;put in low byte of pixel
|
|||
|
|
|||
|
lsl.l #5,d0 ;make room for next component
|
|||
|
moveq #0,d1 ;use for extending to word data
|
|||
|
move.w (a0)+,d1 ;pick up blue accumulation
|
|||
|
divu.w d7,d1 ;get red average
|
|||
|
or.b d1,d0 ;put in low byte of pixel
|
|||
|
|
|||
|
swap d0 ;pixels mixed in AvrgBuf because of how constructed
|
|||
|
move.l d0,(a1)+ ;dump pixel into srcBuf
|
|||
|
dbra d3,@hardWay ;loop for all src longs
|
|||
|
bra.s @DoPromote
|
|||
|
|
|||
|
@useShift
|
|||
|
move.w (a0)+,d1 ;pick up red accumulation
|
|||
|
lsr.b #1,d1 ;get red average
|
|||
|
move.w d1,d0 ;put in low byte of pixel
|
|||
|
|
|||
|
lsl.l #5,d0 ;make room for next component
|
|||
|
move.w (a0)+,d1 ;pick up green accumulation
|
|||
|
lsr.b #1,d1 ;get green average
|
|||
|
or.b d1,d0 ;put in low byte of pixel
|
|||
|
|
|||
|
lsl.l #5,d0 ;make room for next component
|
|||
|
move.w (a0)+,d1 ;pick up blue accumulation
|
|||
|
lsr.b #1,d1 ;get red average
|
|||
|
or.b d1,d0 ;put in low byte of pixel
|
|||
|
;
|
|||
|
; do second pixel (2/long in 16-bit mode)
|
|||
|
;
|
|||
|
lsl.l #5+1,d0
|
|||
|
move.w (a0)+,d1 ;pick up red accumulation
|
|||
|
lsr.b #1,d1 ;get red average
|
|||
|
or.b d1,d0 ;put in low byte of pixel
|
|||
|
|
|||
|
lsl.l #5,d0 ;make room for next component
|
|||
|
move.w (a0)+,d1 ;pick up green accumulation
|
|||
|
lsr.b #1,d1 ;get green average
|
|||
|
or.b d1,d0 ;put in low byte of pixel
|
|||
|
|
|||
|
lsl.l #5,d0 ;make room for next component
|
|||
|
move.w (a0)+,d1 ;pick up blue accumulation
|
|||
|
lsr.b #1,d1 ;get red average
|
|||
|
or.b d1,d0 ;put in low byte of pixel
|
|||
|
|
|||
|
swap d0
|
|||
|
move.l d0,(a1)+ ;dump pixel into srcBuf
|
|||
|
dbra d3,@useShift ;loop for all src longs
|
|||
|
@DoPromote
|
|||
|
;
|
|||
|
; Call Scale16to32 to promote pixels to 32 bpp
|
|||
|
;
|
|||
|
move.l AvrgBuf(A6),A0 ;pointer to source
|
|||
|
move.l a2,a1 ;pointer to destination
|
|||
|
lsl.l #3,d4 ;calc size of dst:
|
|||
|
;longs to bytes and 16 bit to 32 bit = *8 <7JULY90 KON>
|
|||
|
add.l d4,a2 ;calc end of dst buffer
|
|||
|
jmp Scale16to32 ;inherits return address.
|
|||
|
|
|||
|
;
|
|||
|
;----------------Bottom of 16-bit average loop ----------------
|
|||
|
;
|
|||
|
;*********************************************************************
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;*********************************************************************
|
|||
|
;
|
|||
|
; Loop to expand and merge D7 1-bit/pixel scanlines.
|
|||
|
;
|
|||
|
;ENTRY:
|
|||
|
; D0: scratch A0: scratch ptr
|
|||
|
; D1: scratch A1: scratch ptr
|
|||
|
; D2: scratch A2: destination
|
|||
|
; D3: scratch A3: source
|
|||
|
; D4: src longs A4: src pmtable A5: rowbytes
|
|||
|
; D5: srcAlign A5: rowbytes
|
|||
|
; D6: realDepth (pixel size)
|
|||
|
; D7: Scanline Count (zero based)
|
|||
|
;
|
|||
|
;EXIT:
|
|||
|
;
|
|||
|
; a3: new srcaddr
|
|||
|
;
|
|||
|
;GLOBALS: AvgBufPtr(a6), AvgBufSize(a6)
|
|||
|
;
|
|||
|
;*********************************************************************
|
|||
|
|
|||
|
ONEDEEP
|
|||
|
|
|||
|
; LOOP FOR ALL LONGS IN SRC SCANLINE
|
|||
|
|
|||
|
move.l a3,a0 ;point to source
|
|||
|
move.l a2,a1 ;point to destination
|
|||
|
move d4,d1 ;get count of longs
|
|||
|
|
|||
|
@Align bfextu (a0){d5:0},d0 ;get an aligned long of source
|
|||
|
add #4,a0 ;bump to next long
|
|||
|
move.l d0,(a1)+ ;put a long to destination
|
|||
|
dbra d1,@Align ;loop for all longs
|
|||
|
|
|||
|
; add.l a5,a3 ;bump source to next row
|
|||
|
_pmVersion
|
|||
|
dbra d7,@OneMerge ; <KON 1NOV90>
|
|||
|
rts
|
|||
|
@OneMerge
|
|||
|
|
|||
|
move.l a3,a0 ;point to source
|
|||
|
move.l a2,a1 ;point to destination
|
|||
|
move d4,d1 ;get count of longs
|
|||
|
@NXTLNG bfextu (a0){d5:0},d0 ;get an aligned long of source
|
|||
|
add #4,a0 ;bump to next long
|
|||
|
or.l d0,(a1)+ ;put a long to destination
|
|||
|
dbra d1,@NXTLNG ;loop for all longs <10July90 KON>
|
|||
|
|
|||
|
; add.l a5,a3 ;bump source to next row
|
|||
|
_pmVersion
|
|||
|
dbra d7,@OneMerge
|
|||
|
rts
|
|||
|
|
|||
|
;******************************************************************************************
|
|||
|
|
|||
|
;---------------------------------------------------------------;
|
|||
|
; ;
|
|||
|
; INTERFACE TO EACH OF THE STRETCHBITS SCANLINE LOOPS: ;
|
|||
|
; ;
|
|||
|
; REGISTERS: A0: D0: CLOBBERED ;
|
|||
|
; A1: D1: CLOBBERED ;
|
|||
|
; A2: MASKPTR D2: LONGCNT ;
|
|||
|
; A3: SRCPTR D3: FGCOLOR ;
|
|||
|
; A4: DSTPTR D4: BKCOLOR ;
|
|||
|
; A5: D5: CLOBBERED ;
|
|||
|
; A6: D6: DSTALIGN ;
|
|||
|
; A7: D7: INVERTFLAG ;
|
|||
|
; ;
|
|||
|
;---------------------------------------------------------------;
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
|||
|
;-------------------------------------------------------
|
|||
|
;
|
|||
|
; MODE 0 OR 4: SRC --> DST
|
|||
|
;
|
|||
|
; FOR PROPER INVERSION, ASSUME SRC IS COLORED. INVERT SRC AFTER
|
|||
|
; ADDING COLOR TO IT (RATHER THAN EXCHANGING FG AND BK, INVERT THEM).
|
|||
|
|
|||
|
;
|
|||
|
; On first entry, find fastest drawing case, and put it in ModeCase(a6)
|
|||
|
;
|
|||
|
stMask0 TST.B alphaMode(A6) ;drawing in alpha mode? <42>
|
|||
|
BEQ.S @1 ;no, use normal loops <42>
|
|||
|
LEA stAlphaMask0,A0 ;get address of alpha copy loop <42>
|
|||
|
BRA.S @RememberAndDoIt ;go remember and do it <42>
|
|||
|
@1: lea FaststMask0,a0 ;assume fast
|
|||
|
;
|
|||
|
; should we colorize here?
|
|||
|
;
|
|||
|
btst #ColorizeInModeCaseBit,XLateFlag(a6)
|
|||
|
bne.s @goslow
|
|||
|
;
|
|||
|
;if we got here, there's no colorizing
|
|||
|
;
|
|||
|
@DontColorize
|
|||
|
tst.l d6 ;need to shift?
|
|||
|
bne.s @ShiftNoColor
|
|||
|
tst.l d7 ;need to invert?
|
|||
|
bne.s @ShiftNoColor
|
|||
|
;
|
|||
|
;if we got here, it's the fast case
|
|||
|
|
|||
|
@RememberAndDoIt
|
|||
|
move.l a0,ModeCase(a6)
|
|||
|
jmp (a0)
|
|||
|
@goSlow
|
|||
|
lea stMask0Slow,a0 ;shift, invert, and colorize
|
|||
|
bra.s @RememberAndDoIt
|
|||
|
|
|||
|
@ShiftNoColor
|
|||
|
lea stMask0ShiftNoColorInvert,a0 ;shift, don't colorize, but invert
|
|||
|
bra.s @RememberAndDoIt
|
|||
|
;
|
|||
|
; Copy through alpha mask <42>
|
|||
|
;
|
|||
|
stAlphaMask0
|
|||
|
MOVE.L alphaMask(A6),D5
|
|||
|
@1: BFEXTU (A3){D6:0},D0 ;get an aligned long from bitmap
|
|||
|
ADD #4,A3 ;bump to next long of source
|
|||
|
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
|||
|
MOVE.L (A4),D1 ;GET DST DATA
|
|||
|
EOR.L D1,D0 ;apply src to dst
|
|||
|
AND.L (A2)+,D0 ;clip with mask
|
|||
|
AND.L D5,D0 ;clip with alpha mask
|
|||
|
EOR.L D1,D0 ;reapply src
|
|||
|
MOVE.L D0,(A4)+ ;PUT RESULT IN DST
|
|||
|
DBRA D2,@1 ;LOOP ALL LONGS THIS ROW
|
|||
|
EOR.L D4,D3 ;(THIS MAY NOT BE NEEDED)
|
|||
|
BRA NEXTDST ;GO FOR NEXT ROW
|
|||
|
|
|||
|
;
|
|||
|
;don't shift, invert, or colorize
|
|||
|
;
|
|||
|
FaststMask0
|
|||
|
;draw
|
|||
|
move.l (a3)+,d0 ;get source
|
|||
|
move.l (a4),d1 ;get dst
|
|||
|
eor.l d1,d0 ;src xor dst
|
|||
|
move.l (a2)+,d3
|
|||
|
and.l d3,d0 ;(src xor dst) and mask
|
|||
|
eor.l d0,d1
|
|||
|
move.l d1,(a4)+ ;dst = [(src xor dst) and mask] xor dst
|
|||
|
DBRA D2,FaststMask0 ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;GO FOR NEXT ROW
|
|||
|
;
|
|||
|
; shift, no colorize, and invert
|
|||
|
;
|
|||
|
stMask0ShiftNoColorInvert
|
|||
|
;shift
|
|||
|
BFEXTU (A3){D6:0},D0 ;get an aligned long from bitmap
|
|||
|
ADD #4,A3 ;bump to next long of source
|
|||
|
move.l (a2)+,d3
|
|||
|
;invert
|
|||
|
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
|||
|
;draw
|
|||
|
move.l (a4),d1 ;get dst
|
|||
|
eor.l d1,d0 ;src xor dst
|
|||
|
and.l d3,d0 ;(src xor dst) and mask
|
|||
|
eor.l d0,d1 ;dst = [(src xor dst) and mask] xor dst
|
|||
|
move.l d1,(a4)+
|
|||
|
DBRA D2,stMask0ShiftNoColorInvert ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;GO FOR NEXT ROW
|
|||
|
|
|||
|
if 0 then
|
|||
|
; shift, colorize, and invert
|
|||
|
stMask0Slow
|
|||
|
;shift
|
|||
|
BFEXTU (A3){D6:0},D0 ;get an aligned long from bitmap
|
|||
|
ADD #4,A3 ;bump to next long of source
|
|||
|
move.l (a2)+,d3 ;get mask
|
|||
|
;invert
|
|||
|
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
|||
|
;colorize
|
|||
|
MOVE.L D0,D5 ;COPY SRC
|
|||
|
AND.L D3,D0 ;ADD FG COLOR TO SRC
|
|||
|
move.l (a4),d1 ;get dst here to help pipelining
|
|||
|
NOT.L D5 ;GET NOT SRC
|
|||
|
AND.L D4,D5 ;ADD BK COLOR TO NOT SRC
|
|||
|
OR.L D5,D0 ;COMBINE FG/BK DATA
|
|||
|
;draw
|
|||
|
eor.l d1,d0 ;src xor dst
|
|||
|
and.l d3,d0 ;(src xor dst) and mask
|
|||
|
eor.l d0,d1 ;dst = [(src xor dst) and mask] xor dst
|
|||
|
move.l d1,(a4)+
|
|||
|
DBRA D2,stMASK0Slow ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;GO FOR NEXT ROW
|
|||
|
else
|
|||
|
|
|||
|
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
|||
|
|
|||
|
stMASK0Slow
|
|||
|
;-------------------------------------------------------
|
|||
|
;
|
|||
|
; MODE 0 OR 4: SRC --> DST
|
|||
|
;
|
|||
|
; FOR PROPER INVERSION, ASSUME SRC IS COLORED. INVERT SRC AFTER
|
|||
|
; ADDING COLOR TO IT (RATHER THAN EXCHANGING FG AND BK, INVERT THEM).
|
|||
|
;
|
|||
|
BFEXTU (A3){D6:0},D0 ;get an aligned long from bitmap
|
|||
|
ADD #4,A3 ;bump to next long of source
|
|||
|
MOVE.L (A2)+,D1 ;GET MASK
|
|||
|
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
|||
|
|
|||
|
MOVE.L D0,D5 ;COPY SRC
|
|||
|
AND.L D3,D0 ;ADD FG COLOR TO SRC
|
|||
|
NOT.L D5 ;GET NOT SRC
|
|||
|
AND.L D4,D5 ;ADD BK COLOR TO NOT SRC
|
|||
|
OR.L D5,D0 ;COMBINE FG/BK DATA
|
|||
|
AND.L D1,D0 ;MASK RESULT
|
|||
|
|
|||
|
NOT.L D1 ;FORM NOTMASK
|
|||
|
AND.L (A4),D1 ;GET DST DATA
|
|||
|
OR.L D1,D0 ;MERGE WITH SRC DATA
|
|||
|
MOVE.L D0,(A4)+ ;PUT RESULT IN DST
|
|||
|
DBRA D2,stMASK0Slow ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;GO FOR NEXT ROW
|
|||
|
endif
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;-------------------------------------------------------
|
|||
|
;
|
|||
|
; MODE 1 OR 5: SRC OR DST --> DST
|
|||
|
;
|
|||
|
; ASSUME SRC IS EXPANDED BLACK/WHITE PATTERN. SRC IS USED
|
|||
|
; TO PUNCH DST, FG APPLIED TO SRC, THEN COMBINED WITH DST.
|
|||
|
;
|
|||
|
stMASK1 BFEXTU (A3){D6:0},D0 ;get an aligned long from bitmap
|
|||
|
ADD #4,A3 ;bump to next long of source
|
|||
|
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
|||
|
MOVE.L (A2)+,D1 ;GET MASK
|
|||
|
|
|||
|
AND.L D1,D0 ;MASK SRC
|
|||
|
MOVE.L D0,D1 ;COPY MASKED SRC
|
|||
|
AND.L D3,D1 ;ADD FG COLOR TO SRC
|
|||
|
|
|||
|
NOT.L D0 ;GET NOT MASKED SRC
|
|||
|
AND.L (A4),D0 ;USE TO PUNCH OUT DST
|
|||
|
OR.L D1,D0 ;COMBINE SRC AND DST
|
|||
|
|
|||
|
MOVE.L D0,(A4)+ ;PUT RESULT TO DST
|
|||
|
DBRA D2,stMASK1 ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;-------------------------------------------------------
|
|||
|
;
|
|||
|
; MODE 2 OR 6: SRC XOR DST --> DST
|
|||
|
;
|
|||
|
stMASK2 BFEXTU (A3){D6:0},D0 ;get an aligned long from bitmap
|
|||
|
ADD #4,A3 ;bump to next long of source
|
|||
|
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
|||
|
AND.L (A2)+,D0 ;AND WITH MASK
|
|||
|
EOR.L D0,(A4)+ ;XOR RESULT INTO DST
|
|||
|
DBRA D2,stMASK2 ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;-------------------------------------------------------
|
|||
|
;
|
|||
|
; MODE 3 OR 7: SRC BIC DST --> DST
|
|||
|
;
|
|||
|
; ASSUME SRC IS EXPANDED BLACK/WHITE PATTERN. SRC IS USED
|
|||
|
; TO PUNCH DST, BK APPLIED TO SRC, THEN COMBINED WITH DST.
|
|||
|
;
|
|||
|
stMASK3
|
|||
|
if 0 then
|
|||
|
lea stMASK3NoColorize,a0 ;assume no colorizing
|
|||
|
;
|
|||
|
; should we colorize here?
|
|||
|
;
|
|||
|
btst #ColorizeInModeCaseBit,XLateFlag(a6)
|
|||
|
bne.s @goslow
|
|||
|
|
|||
|
@RememberAndDoIt
|
|||
|
move.l a0,ModeCase(a6)
|
|||
|
jmp (a0)
|
|||
|
@goSlow
|
|||
|
lea stMASK3Colorize,a0 ;shift, invert, and colorize
|
|||
|
bra.s @RememberAndDoIt
|
|||
|
endif
|
|||
|
|
|||
|
stMASK3Colorize
|
|||
|
BFEXTU (A3){D6:0},D0 ;get an aligned long from bitmap
|
|||
|
ADD #4,A3 ;bump to next long of source
|
|||
|
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
|||
|
MOVE.L (A2)+,D1 ;GET MASK
|
|||
|
|
|||
|
AND.L D1,D0 ;MASK SRC
|
|||
|
MOVE.L D0,D1 ;COPY MASKED SRC
|
|||
|
AND.L D4,D1 ;AND SRC WITH BG COLOR (FOR BIC)
|
|||
|
|
|||
|
NOT.L D0 ;GET BITS THAT AREN'T BIC'ED
|
|||
|
AND.L (A4),D0 ;GET DST THAT DOESN'T CHANGE
|
|||
|
OR.L D1,D0 ;FORM SRC BIC DST
|
|||
|
|
|||
|
MOVE.L D0,(A4)+ ;AND PUT TO DST
|
|||
|
DBRA D2,stMASK3Colorize ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
if 0 then
|
|||
|
stMASK3NoColorize
|
|||
|
BFEXTU (A3){D6:0},D0 ;get an aligned long from bitmap
|
|||
|
ADD #4,A3 ;bump to next long of source
|
|||
|
EOR.L D7,D0 ;INVERT SRC IF MODE BIT 2 SET
|
|||
|
MOVE.L (A2)+,D1 ;GET MASK
|
|||
|
|
|||
|
AND.L D1,D0 ;MASK SRC
|
|||
|
MOVE.L D0,D1 ;COPY MASKED SRC
|
|||
|
|
|||
|
NOT.L D0 ;GET BITS THAT AREN'T BIC'ED
|
|||
|
AND.L (A4),D0 ;GET DST THAT DOESN'T CHANGE
|
|||
|
OR.L D1,D0 ;FORM SRC BIC DST
|
|||
|
|
|||
|
MOVE.L D0,(A4)+ ;AND PUT TO DST
|
|||
|
DBRA D2,stMASK3NoColorize ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
endif
|
|||
|
|
|||
|
; note that arithmetic modes expect the destination pixel size instead of the invert state in D7
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
stAddOver
|
|||
|
@loopTop
|
|||
|
ADD.L D7,D6 ;bump source pointer
|
|||
|
BFEXTU (A2){D3:D7},D0 ;get a pixel of mask
|
|||
|
BEQ.S @skip ;if none, skip the pixel
|
|||
|
BFEXTU (A3){D6:D7},D0 ;get a pixel from bitmap
|
|||
|
LEA red(A5,D0*8),A0 ;figure out where it lives in the color table
|
|||
|
BFEXTU (A4){D3:D7},D0 ;a pixel of the destination
|
|||
|
LEA red(A5,D0*8),A1 ;figure out where destination lives
|
|||
|
MOVE (A0)+,D0 ;red get source color value
|
|||
|
ADD (A1)+,D0 ; combine source and destination
|
|||
|
ASL.L D5,D0 ; save the top bits in the top word
|
|||
|
MOVE (A0)+,D0 ;green get source color value
|
|||
|
ADD (A1)+,D0 ; combine source and destination
|
|||
|
ASL.L D5,D0 ; save the top bits in the top word
|
|||
|
MOVE (A0)+,D0 ;blue get source color value
|
|||
|
ADD (A1)+,D0 ; combine source and destination
|
|||
|
ASL.L D5,D0 ; save the top bits in the top word
|
|||
|
SWAP D0 ;r, g, b in high word
|
|||
|
MOVE.B ([invColor,A6],D0,itTable),D0 ;get the pixel value of the additive sum
|
|||
|
BFINS D0,(A4){D3:D7} ;move to the destination
|
|||
|
@skip
|
|||
|
ADD.L D7,D3 ;advance to next destination
|
|||
|
DBRA D2,@loopTop ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
stAddPin
|
|||
|
@loopTop
|
|||
|
ADD.L D7,D6 ;bump source pointer
|
|||
|
BFEXTU (A2){D3:D7},D0 ;get a pixel of mask
|
|||
|
BEQ.S @skip ;if none, skip the pixel
|
|||
|
BFEXTU (A3){D6:D7},D0 ;get a pixel from bitmap
|
|||
|
LEA red(A5,D0*8),A0 ;figure out where it lives in the color table
|
|||
|
BFEXTU (A4){D3:D7},D0 ;a pixel of the destination
|
|||
|
LEA red(A5,D0*8),A1 ;figure out where destination lives
|
|||
|
MOVE (A0)+,D0 ;red get source color value
|
|||
|
ADD (A1)+,D0 ; combine source and destination
|
|||
|
BCS.S @tooBigRed
|
|||
|
CMP pin+4(A6),D0 ; bigger than pin value?
|
|||
|
BLS.S @notTooBigRed ; no, no problem
|
|||
|
@tooBigRed
|
|||
|
MOVE pin+4(A6),D0
|
|||
|
@notTooBigRed
|
|||
|
ASL.L D5,D0 ;save the top bits in the top word
|
|||
|
MOVE (A0)+,D0 ;green get source color value
|
|||
|
ADD (A1)+,D0 ; combine source and destination
|
|||
|
BCS.S @tooBigGreen
|
|||
|
CMP pin+2(A6),D0 ; bigger than pin value?
|
|||
|
BLS.S @notTooBigGreen ; no, no problem
|
|||
|
@tooBigGreen
|
|||
|
MOVE pin+2(A6),D0
|
|||
|
@notTooBigGreen
|
|||
|
ASL.L D5,D0 ;save the top bits in the top word
|
|||
|
MOVE (A0)+,D0 ;blue get source color value
|
|||
|
ADD (A1)+,D0 ; combine source and destination
|
|||
|
BCS.S @tooBigBlue
|
|||
|
CMP pin(A6),D0 ; bigger than pin value?
|
|||
|
BLS.S @notTooBigBlue ; no, no problem
|
|||
|
@tooBigBlue
|
|||
|
MOVE pin(A6),D0
|
|||
|
@notTooBigBlue
|
|||
|
ASL.L D5,D0 ;save the top bits in the top word
|
|||
|
SWAP D0 ;r, g, b in high word
|
|||
|
MOVE.B ([invColor,A6],D0,itTable),D0 ;get the pixel value of the additive sum
|
|||
|
BFINS D0,(A4){D3:D7} ;move to the destination
|
|||
|
@skip
|
|||
|
ADD.L D7,D3 ;advance to next destination
|
|||
|
DBRA D2,@loopTop ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
stSubOver
|
|||
|
@loopTop
|
|||
|
ADD.L D7,D6 ;bump source pointer
|
|||
|
BFEXTU (A2){D3:D7},D0 ;get a pixel of mask
|
|||
|
BEQ.S @skip ;if none, skip the pixel
|
|||
|
BFEXTU (A3){D6:D7},D0 ;get a pixel from bitmap
|
|||
|
LEA red(A5,D0*8),A0 ;figure out where it lives in the color table
|
|||
|
BFEXTU (A4){D3:D7},D0 ;a pixel of the destination
|
|||
|
LEA red(A5,D0*8),A1 ;figure out where destination lives
|
|||
|
MOVE (A1)+,D0 ;red get destination color value
|
|||
|
SUB (A0)+,D0 ; less source
|
|||
|
ASL.L D5,D0 ; save the top bits in the top word
|
|||
|
MOVE (A1)+,D0 ;green get destination color value
|
|||
|
SUB (A0)+,D0 ; less source
|
|||
|
ASL.L D5,D0 ; save the top bits in the top word
|
|||
|
MOVE (A1)+,D0 ;blue get destination color value
|
|||
|
SUB (A0)+,D0 ; less source
|
|||
|
ASL.L D5,D0 ; save the top bits in the top word
|
|||
|
SWAP D0 ;r, g, b in high word
|
|||
|
MOVE.B ([invColor,A6],D0,itTable),D0 ;get the pixel value of the additive sum
|
|||
|
BFINS D0,(A4){D3:D7} ;move to the destination
|
|||
|
@skip
|
|||
|
ADD.L D7,D3 ;advance to next destination
|
|||
|
DBRA D2,@loopTop ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
stSubPin
|
|||
|
@loopTop
|
|||
|
ADD.L D7,D6 ;bump source pointer
|
|||
|
BFEXTU (A2){D3:D7},D0 ;get a pixel of mask
|
|||
|
BEQ.S @skip ;if none, skip the pixel
|
|||
|
BFEXTU (A3){D6:D7},D0 ;get a pixel from bitmap
|
|||
|
LEA red(A5,D0*8),A0 ;figure out where it lives in the color table
|
|||
|
BFEXTU (A4){D3:D7},D0 ;a pixel of the destination
|
|||
|
LEA red(A5,D0*8),A1 ;figure out where destination lives
|
|||
|
MOVE (A1)+,D0 ;red get destination color value
|
|||
|
SUB (A0)+,D0 ; less source
|
|||
|
BCS.S @tooSmallRed
|
|||
|
CMP pin+4(A6),D0 ; smaller than pin value?
|
|||
|
BHS.S @notTooSmallRed ; no, no problem
|
|||
|
@tooSmallRed
|
|||
|
MOVE pin+4(A6),D0
|
|||
|
@notTooSmallRed
|
|||
|
ASL.L D5,D0 ;save the top bits in the top word
|
|||
|
MOVE (A1)+,D0 ;green get destination color value
|
|||
|
SUB (A0)+,D0 ; less source
|
|||
|
BCS.S @tooSmallGreen
|
|||
|
CMP pin+2(A6),D0 ; smaller than pin value?
|
|||
|
BHS.S @notTooSmallGreen ; no, no problem
|
|||
|
@tooSmallGreen
|
|||
|
MOVE pin+2(A6),D0
|
|||
|
@notTooSmallGreen
|
|||
|
ASL.L D5,D0 ;save the top bits in the top word
|
|||
|
MOVE (A1)+,D0 ;blue get destination color value
|
|||
|
SUB (A0)+,D0 ; less source
|
|||
|
BCS.S @tooSmallBlue
|
|||
|
CMP pin(A6),D0 ; smaller than pin value?
|
|||
|
BHS.S @notTooSmallBlue ; no, no problem
|
|||
|
@tooSmallBlue
|
|||
|
MOVE pin(A6),D0
|
|||
|
@notTooSmallBlue
|
|||
|
ASL.L D5,D0 ;save the top bits in the top word
|
|||
|
SWAP D0 ;r, g, b in high word
|
|||
|
MOVE.B ([invColor,A6],D0,itTable),D0 ;get the pixel value of the additive sum
|
|||
|
BFINS D0,(A4){D3:D7} ;move to the destination
|
|||
|
@skip
|
|||
|
ADD.L D7,D3 ;advance to next destination
|
|||
|
DBRA D2,@loopTop ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
stMax
|
|||
|
@loopTop
|
|||
|
ADD.L D7,D6 ;bump source pointer
|
|||
|
BFEXTU (A2){D3:D7},D0 ;get a pixel of mask
|
|||
|
BEQ.S @skip ;if none, skip the pixel
|
|||
|
BFEXTU (A3){D6:D7},D0 ;get a pixel from bitmap
|
|||
|
LEA red(A5,D0*8),A0 ;figure out where it lives in the color table
|
|||
|
BFEXTU (A4){D3:D7},D0 ;a pixel of the destination
|
|||
|
LEA red(A5,D0*8),A1 ;figure out where destination lives
|
|||
|
MOVE (A0)+,D0 ;red get source color value
|
|||
|
CMP (A1),D0 ; compare source and destination
|
|||
|
BHS.S @gotTheMaxRed
|
|||
|
MOVE (A1),D0
|
|||
|
@gotTheMaxRed
|
|||
|
ADDQ #2,A1
|
|||
|
ASL.L D5,D0 ; save the top bits in the top word
|
|||
|
MOVE (A0)+,D0 ;green get source color value
|
|||
|
CMP (A1),D0 ; compare source and destination
|
|||
|
BHS.S @gotTheMaxGreen
|
|||
|
MOVE (A1),D0
|
|||
|
@gotTheMaxGreen
|
|||
|
ADDQ #2,A1
|
|||
|
ASL.L D5,D0 ; save the top bits in the top word
|
|||
|
MOVE (A0)+,D0 ;blue get source color value
|
|||
|
CMP (A1),D0 ; compare source and destination
|
|||
|
BHS.S @gotTheMaxBlue
|
|||
|
MOVE (A1),D0
|
|||
|
@gotTheMaxBlue
|
|||
|
ASL.L D5,D0 ; save the top bits in the top word
|
|||
|
SWAP D0 ;r, g, b in high word
|
|||
|
MOVE.B ([invColor,A6],D0,itTable),D0 ;get the pixel value of the additive sum
|
|||
|
BFINS D0,(A4){D3:D7} ;move to the destination
|
|||
|
@skip
|
|||
|
ADD.L D7,D3 ;advance to next destination
|
|||
|
DBRA D2,@loopTop ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
stMin
|
|||
|
@loopTop
|
|||
|
ADD.L D7,D6 ;bump source pointer
|
|||
|
BFEXTU (A2){D3:D7},D0 ;get a pixel of mask
|
|||
|
BEQ.S @skip ;if none, skip the pixel
|
|||
|
BFEXTU (A3){D6:D7},D0 ;get a pixel from bitmap
|
|||
|
LEA red(A5,D0*8),A0 ;figure out where it lives in the color table
|
|||
|
BFEXTU (A4){D3:D7},D0 ;a pixel of the destination
|
|||
|
LEA red(A5,D0*8),A1 ;figure out where destination lives
|
|||
|
MOVE (A0)+,D0 ;red get source color value
|
|||
|
CMP (A1),D0 ; compare source and destination
|
|||
|
BLS.S @gotTheMinRed
|
|||
|
MOVE (A1),D0
|
|||
|
@gotTheMinRed
|
|||
|
ADDQ #2,A1
|
|||
|
ASL.L D5,D0 ; save the top bits in the top word
|
|||
|
MOVE (A0)+,D0 ;green get source color value
|
|||
|
CMP (A1),D0 ; compare source and destination
|
|||
|
BLS.S @gotTheMinGreen
|
|||
|
MOVE (A1),D0
|
|||
|
@gotTheMinGreen
|
|||
|
ADDQ #2,A1
|
|||
|
ASL.L D5,D0 ; save the top bits in the top word
|
|||
|
MOVE (A0)+,D0 ;blue get source color value
|
|||
|
CMP (A1),D0 ; compare source and destination
|
|||
|
BLS.S @gotTheMinBlue
|
|||
|
MOVE (A1),D0
|
|||
|
@gotTheMinBlue
|
|||
|
ASL.L D5,D0 ; save the top bits in the top word
|
|||
|
SWAP D0 ;r, g, b in high word
|
|||
|
MOVE.B ([invColor,A6],D0,itTable),D0 ;get the pixel value of the additive sum
|
|||
|
BFINS D0,(A4){D3:D7} ;move to the destination
|
|||
|
@skip
|
|||
|
ADD.L D7,D3 ;advance to next destination
|
|||
|
DBRA D2,@loopTop ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
stAvg
|
|||
|
@loopTop
|
|||
|
ADD.L D7,D6 ;bump source pointer
|
|||
|
BFEXTU (A2){D3:D7},D0 ;get a pixel of mask
|
|||
|
BEQ.S @skip ;if none, skip the pixel
|
|||
|
BFEXTU (A3){D6:D7},D0 ;get a pixel from bitmap
|
|||
|
LEA red(A5,D0*8),A0 ;figure out where it lives in the color table
|
|||
|
BFEXTU (A4){D3:D7},D0 ;a pixel of the destination
|
|||
|
LEA red(A5,D0*8),A1 ;figure out where destination lives
|
|||
|
MOVEQ #2,D1 ;do three times
|
|||
|
MOVE invSize(A6),D5 ;do once for r, b and g
|
|||
|
ADD D5,D5 ;initialize at 2x for shift count
|
|||
|
CLR -(SP) ;make space & initialize average r, b, g
|
|||
|
@nextColor
|
|||
|
MOVE (A0)+,D0 ;get source color value
|
|||
|
MULU (weight,A6,D1*2),D0 ;weight varies from 0 to 1
|
|||
|
MOVE (A1)+,D4 ;get destination value
|
|||
|
MULU (notWeight,A6,D1*2),D4 ;weight varies from 1 to 0
|
|||
|
ADD.L D4,D0 ;combine them
|
|||
|
SWAP D0 ;high word is interesting part
|
|||
|
MOVE rtShift(A6),D4 ;amount to shift right
|
|||
|
LSR D4,D0 ;get top bits only
|
|||
|
LSL D5,D0 ;shift by 2x, 1x, or 0 (for r, g, & b)
|
|||
|
OR D0,(SP) ;combine r, g, b
|
|||
|
SUB invSize(A6),D5 ;decrement shift, weight index
|
|||
|
DBRA D1,@nextColor ;do for b & g as well
|
|||
|
|
|||
|
MOVE (SP)+,D0 ;r, g, b
|
|||
|
MOVE.B ([invColor,A6],D0,itTable),D0 ;get the pixel value of the additive sum
|
|||
|
BFINS D0,(A4){D3:D7} ;move to the destination
|
|||
|
@skip
|
|||
|
ADD.L D7,D3 ;advance to next destination
|
|||
|
DBRA D2,@loopTop ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
stTransparent
|
|||
|
@loopTop
|
|||
|
ADD.L D7,D6 ;bump source pointer
|
|||
|
@loopTop1
|
|||
|
BFEXTU (A3){D6:0},D0 ;get a long from the source
|
|||
|
CMP.L D0,D4 ;same as the background?
|
|||
|
BEQ.S @skipLong
|
|||
|
BFEXTU (A2){D3:D7},D0 ;get a pixel of mask
|
|||
|
BEQ.S @skip ;if none, skip the pixel
|
|||
|
BFEXTU (A3){D6:D7},D0 ;get a pixel from bitmap
|
|||
|
CMP.L D0,A5 ;same as a pixel of the background?
|
|||
|
BEQ.S @skip
|
|||
|
BFINS D0,(A4){D3:D7} ;move to the destination
|
|||
|
@skip
|
|||
|
ADD.L D7,D3 ;advance to next destination
|
|||
|
DBRA D2,@loopTop ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
@skipLong
|
|||
|
ADDQ #4,A3 ;bump the source by a long
|
|||
|
ADD #32,D3 ;bump mask and destination
|
|||
|
SUB D5,D2 ;a long<6E>s worth of pixels
|
|||
|
BGE.S @loopTop1
|
|||
|
MOVE.L bColor(A6),D4 ;set up colorMap backcolor for skipping coloring source
|
|||
|
BRA NEXTDST
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
|||
|
|
|||
|
stHilite
|
|||
|
BFEXTU D4{0:D7},D4 ;set up a pixel of the backcolor
|
|||
|
BFEXTU hilitColor(A6){0:D7},D5 ;and a pixel of the hilite color as well
|
|||
|
@loopTop
|
|||
|
ADD.L D7,D6 ;bump source pointer
|
|||
|
BFEXTU (A2){D3:D7},D0 ;get a pixel of mask
|
|||
|
BEQ.S @skip ;if none, skip the pixel
|
|||
|
BFEXTU (A3){D6:D7},D0 ;get a pixel from bitmap
|
|||
|
CMP.L D4,D0 ;is pixel same as background color? <45>
|
|||
|
BEQ.S @skip
|
|||
|
BFEXTU (A4){D3:D7},D0 ;get a pixel of the destination
|
|||
|
CMP.L D4,D0 ;same as the background color?
|
|||
|
BNE.S @tryNew
|
|||
|
BFINS D5,(A4){D3:D7}
|
|||
|
BRA.S @skip
|
|||
|
@tryNew
|
|||
|
CMP.L D5,D0 ;same as new color?
|
|||
|
BNE.S @skip
|
|||
|
BFINS D4,(A4){D3:D7} ;move to the destination
|
|||
|
@skip
|
|||
|
ADD.L D7,D3 ;advance to next destination
|
|||
|
DBRA D2,@loopTop ;LOOP ALL pixels THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
|
|||
|
; all of these loops are as seen in QDciPatchROM.a <sm 6/9/92>stb
|
|||
|
;--------------------------------------------------------------------------
|
|||
|
;
|
|||
|
;
|
|||
|
; Here begins the arithmetic transfer loops for 32 bits/pixel:
|
|||
|
;
|
|||
|
;
|
|||
|
;
|
|||
|
;--------------------------------------------------------------------------
|
|||
|
;
|
|||
|
; MODE 42: PAT + DST --> DST (no pin)
|
|||
|
;-------------------------------------------------------
|
|||
|
; a0 = hi bit mask d0 = hi bit clring mask
|
|||
|
; a1 = dstPtr d1 = src pixel
|
|||
|
; a2 = maskPtr d2 = run cnt
|
|||
|
; a3 = patPtr d3 = src msb's
|
|||
|
; a4 = d4 = patHMask
|
|||
|
; a5 = d5 = dest pixel
|
|||
|
; a6 = locals d6 = pattern offset
|
|||
|
; a7 = d7 = dst msb's
|
|||
|
;-------------------------------------------------------
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
stAddOver32
|
|||
|
BSR arithSetup32 ;set up registers for slab bitblt
|
|||
|
|
|||
|
move.l #~$ff808080,d0 ;get high bit clearing mask
|
|||
|
move.l #$00808080,a0 ;get high bit mask
|
|||
|
|
|||
|
@blit tst.l (a2)+ ;a pixel of the clip region
|
|||
|
beq.s @skip
|
|||
|
|
|||
|
move.l 0(a3,d6),d1 ;get src pixel
|
|||
|
move.l a0,d7 ;copy high bit mask
|
|||
|
and.l d1,d7 ;remember src msb's
|
|||
|
and.l d0,d1 ;mask out stragglers
|
|||
|
|
|||
|
move.l (a1),d5 ;get dest pixel
|
|||
|
move.l a0,d3 ;copy high bit mask
|
|||
|
and.l d5,d3 ;remember dst msb's
|
|||
|
and.l d0,d5 ;mask out stragglers
|
|||
|
|
|||
|
add.l d1,d5 ;merge src with dst
|
|||
|
eor.l d7,d3 ;compute partial sum of msb's
|
|||
|
eor.l d3,d5 ;compute partial sum of msb's
|
|||
|
MOVE.L d5,(a1) ;write pattern to dest
|
|||
|
|
|||
|
@skip addq.l #4,a1 ;bump dst ptr
|
|||
|
addq.l #4,d6 ;bump src index
|
|||
|
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|||
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
; Utility arithSetup
|
|||
|
; sets up registers for 32 bit arithmetic modes:
|
|||
|
;
|
|||
|
; INPUT
|
|||
|
; REGISTERS: A0: D0: CLOBBERED ;
|
|||
|
; A1: D1: CLOBBERED ;
|
|||
|
; A2: MASKPTR D2: LONGCNT ;
|
|||
|
; A3: SRCPTR D3: FGCOLOR ;
|
|||
|
; A4: DSTPTR D4: BKCOLOR ;
|
|||
|
; A5: D5: CLOBBERED ;
|
|||
|
; A6: D6: DSTALIGN ;
|
|||
|
; A7: D7: PixelSize ;
|
|||
|
; ;
|
|||
|
|
|||
|
arithSetup32
|
|||
|
move.l a4,a1 ;reroute dstPtr
|
|||
|
moveq #0,D6 ;zero src index
|
|||
|
; moveq #-1,D4 ;flush src modulus
|
|||
|
; move.l d4,patHMask(a6)
|
|||
|
RTS
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;-------------------------------------------------------
|
|||
|
;
|
|||
|
; MODE 41: PAT + DST --> DST (pin to max)
|
|||
|
;-------------------------------------------------------
|
|||
|
; a0 = d0 = result
|
|||
|
; a1 = dstPtr d1 = lo3Bytes mask
|
|||
|
; a2 = maskPtr d2 = run cnt
|
|||
|
; a3 = patPtr d3 = pin pixel 0rgb
|
|||
|
; a4 = d4 = patHMask
|
|||
|
; a5 = d5 = dest pixel
|
|||
|
; a6 = locals d6 = pattern offset
|
|||
|
; a7 = d7 = src pixel
|
|||
|
;-------------------------------------------------------
|
|||
|
stAddPin32
|
|||
|
BSR arithSetup32 ;set up registers for slab bitblt
|
|||
|
|
|||
|
;set up pin pixel as 0rgb in D3
|
|||
|
|
|||
|
moveq #0,d3 ;start fresh, waste iTabRes
|
|||
|
move.b pin+4(a6),d3 ;pick up red
|
|||
|
swap d3 ;put in byte 3
|
|||
|
move.w pin+2(a6),d3 ;get green in byte 2
|
|||
|
move.b pin(a6),d3 ;put blue in lo byte
|
|||
|
|
|||
|
move.l Lo3Bytes,d1 ;pick up mask
|
|||
|
|
|||
|
@blit tst.l (a2)+ ;a pixel of the clip region
|
|||
|
beq.s @skip
|
|||
|
|
|||
|
move.l 0(a3,d6),d7 ;get src pixel
|
|||
|
and.l d1,d7 ;waste high byte
|
|||
|
move.l d7,d0 ;make a copy of the src xrgb
|
|||
|
|
|||
|
move.l (a1),d5 ;get dest pixel
|
|||
|
and.l d1,d5 ;waste high byte
|
|||
|
|
|||
|
clr.b d0 ;prevent carries from below
|
|||
|
add.w d5,d0 ;add green components
|
|||
|
BCS.S @PinGreen
|
|||
|
cmp.w d3,d0 ;do we need to pin result?
|
|||
|
bls.s @GreenOK
|
|||
|
@PinGreen
|
|||
|
move.w d3,d0 ;use pin value instead
|
|||
|
@GreenOK
|
|||
|
move.b d7,d0 ;get src blue
|
|||
|
add.b d5,d0 ;add dest blue
|
|||
|
BCS.S @PinBlue
|
|||
|
cmp.b d3,d0 ;do we need to pin result?
|
|||
|
bls.s @BlueOK
|
|||
|
@PinBlue
|
|||
|
move.b d3,d0 ;use pin value instead
|
|||
|
@BlueOK
|
|||
|
clr.w d5 ;now d5 has only red in byte 3
|
|||
|
add.l d5,d0 ;add red components
|
|||
|
cmp.l d3,d0 ;compare red components
|
|||
|
bls.s @RedOK
|
|||
|
@PinRed
|
|||
|
swap d3 ;get max red in lo word
|
|||
|
swap d0 ;get too big red in lo word
|
|||
|
move.w d3,d0 ;pin to max red
|
|||
|
swap d0 ;get back 0rgb
|
|||
|
swap d3 ;restore pin pixel
|
|||
|
@RedOK
|
|||
|
MOVE.L d0,(a1) ;write pattern to dest
|
|||
|
|
|||
|
@skip addq.l #4,a1 ;bump dst ptr
|
|||
|
addq.l #4,d6 ;bump src index
|
|||
|
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|||
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;-------------------------------------------------------
|
|||
|
;
|
|||
|
; MODE 46: DST - PAT --> DST (no pin)
|
|||
|
;
|
|||
|
;-------------------------------------------------------
|
|||
|
; a0 = d0 = hi bit clring mask
|
|||
|
; a1 = dstPtr d1 = high bit mask
|
|||
|
; a2 = maskPtr d2 = run cnt
|
|||
|
; a3 = patPtr d3 = src msb's
|
|||
|
; a4 = d4 = dst msb's
|
|||
|
; a5 = d5 = dest pixel
|
|||
|
; a6 = locals d6 = pattern offset
|
|||
|
; a7 = d7 = src pixel
|
|||
|
;-------------------------------------------------------
|
|||
|
stSubOver32
|
|||
|
BSR arithSetup32 ;set up registers for slab bitblt
|
|||
|
|
|||
|
move.l #~$ff808080,d0 ;get high bit clearing mask
|
|||
|
move.l #$00808080,d1 ;get high bit mask
|
|||
|
|
|||
|
@blit tst.l (a2)+ ;a pixel of the clip region
|
|||
|
beq.s @skip
|
|||
|
|
|||
|
move.l 0(a3,d6),d7 ;get src pixel
|
|||
|
move.l d1,d3 ;copy high bit mask
|
|||
|
and.l d7,d3 ;remember src msb's
|
|||
|
eor.l d1,d3 ;invert src msb's
|
|||
|
and.l d0,d7 ;mask out stragglers
|
|||
|
|
|||
|
move.l (a1),d5 ;get dest pixel
|
|||
|
move.l d1,d4 ;copy high bit mask
|
|||
|
and.l d5,d4 ;remember dst msb's
|
|||
|
and.l d0,d5 ;mask out high byte
|
|||
|
or.l d1,d5 ;force high bits on
|
|||
|
|
|||
|
sub.l d7,d5 ;compute dst - src
|
|||
|
eor.l d3,d4 ;compute partial sum of msb's
|
|||
|
eor.l d4,d5 ;compute partial sum of msb's
|
|||
|
MOVE.L d5,(a1) ;write pattern to dest
|
|||
|
|
|||
|
@skip addq.l #4,a1 ;bump dst ptr
|
|||
|
addq.l #4,d6 ;bump src index
|
|||
|
; and.w patHMask(a6),d6 ;constrict to the source long if in a pattern mode
|
|||
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;-------------------------------------------------------
|
|||
|
;
|
|||
|
; MODE 43: DST - PAT --> DST (pin to min)
|
|||
|
;
|
|||
|
;-------------------------------------------------------
|
|||
|
; a0 = d0 = result
|
|||
|
; a1 = dstPtr d1 = lo3Bytes mask
|
|||
|
; a2 = maskPtr d2 = run cnt
|
|||
|
; a3 = patPtr d3 = pin pixel 0rgb
|
|||
|
; a4 = d4 = patHMask
|
|||
|
; a5 = d5 = src pixel
|
|||
|
; a6 = locals d6 = pattern offset
|
|||
|
; a7 = d7 = dst pixel
|
|||
|
;-------------------------------------------------------
|
|||
|
stSubPin32
|
|||
|
BSR arithSetup32 ;set up registers for slab bitblt
|
|||
|
|
|||
|
;set up pin pixel as 0rgb in D3
|
|||
|
|
|||
|
moveq #0,d3 ;start fresh, waste iTabRes
|
|||
|
move.b pin+4(a6),d3 ;pick up red
|
|||
|
swap d3 ;put in byte 3
|
|||
|
move.w pin+2(a6),d3 ;get green in byte 2
|
|||
|
move.b pin(a6),d3 ;put blue in lo byte
|
|||
|
|
|||
|
move.l Lo3Bytes,d1 ;pick up mask
|
|||
|
|
|||
|
@blit tst.l (a2)+ ;a pixel of the clip region
|
|||
|
beq.s @skip
|
|||
|
move.l 0(a3,d6),d5 ;get src pixel
|
|||
|
and.l d1,d5 ;waste high byte
|
|||
|
|
|||
|
move.l (a1),d7 ;get dest pixel
|
|||
|
and.l d1,d7 ;waste high byte
|
|||
|
move.l d7,d0 ;make a copy of the dst xrgb
|
|||
|
|
|||
|
st d0 ;prevent borrows from below
|
|||
|
sub.w d5,d0 ;sub green components
|
|||
|
BCS.S @PinGreen
|
|||
|
cmp.w d3,d0 ;do we need to pin result?
|
|||
|
bhs.s @GreenOK
|
|||
|
@PinGreen
|
|||
|
move.w d3,d0 ;use pin value instead
|
|||
|
@GreenOK
|
|||
|
move.b d7,d0 ;get dest blue
|
|||
|
sub.b d5,d0 ;sub src blue
|
|||
|
BCS.S @PinBlue
|
|||
|
cmp.b d3,d0 ;do we need to pin result?
|
|||
|
bhs.s @BlueOK
|
|||
|
@PinBlue
|
|||
|
move.b d3,d0 ;use pin value instead
|
|||
|
@BlueOK
|
|||
|
clr.w d5 ;now d5 has only red in byte 3
|
|||
|
sub.l d5,d0 ;sub red components
|
|||
|
cmp.l d3,d0 ;compare red components
|
|||
|
bge.s @RedOK
|
|||
|
@PinRed
|
|||
|
swap d3 ;get max red in lo word
|
|||
|
swap d0 ;get too big red in lo word
|
|||
|
move.w d3,d0 ;pin to max red
|
|||
|
swap d0 ;get back 0rgb
|
|||
|
swap d3 ;restore pin pixel
|
|||
|
@RedOK
|
|||
|
|
|||
|
MOVE.L d0,(a1) ;write pattern to dest
|
|||
|
|
|||
|
@skip addq.l #4,a1 ;bump dst ptr
|
|||
|
addq.l #4,d6 ;bump src index
|
|||
|
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|||
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;-------------------------------------------------------
|
|||
|
;
|
|||
|
; MODE 45: MAX(PAT, DST) --> DST
|
|||
|
;
|
|||
|
;-------------------------------------------------------
|
|||
|
; a0 = d0 = result
|
|||
|
; a1 = dstPtr d1 = src pixel
|
|||
|
; a2 = maskPtr d2 = run cnt
|
|||
|
; a3 = patPtr d3 =
|
|||
|
; a4 = d4 = patHMask
|
|||
|
; a5 = d5 = dest pixel
|
|||
|
; a6 = locals d6 = pattern offset
|
|||
|
; a7 = d7 =
|
|||
|
;-------------------------------------------------------
|
|||
|
stMax32
|
|||
|
BSR arithSetup32 ;set up registers for slab bitblt
|
|||
|
|
|||
|
@blit tst.l (a2)+ ;a pixel of the clip region
|
|||
|
beq.s @skip
|
|||
|
move.l 0(a3,d6),d1 ;get src pixel
|
|||
|
move.l (a1),d5 ;get dest pixel
|
|||
|
|
|||
|
move.l d5,d0 ;make a copy of the dest xrgb
|
|||
|
cmp.w d1,d0 ;compare g,b components
|
|||
|
BHI.S @gotMaxGreen
|
|||
|
move.w d1,d0 ;keep the bigger of the two
|
|||
|
move.b d5,d0 ;prime for blue
|
|||
|
@gotMaxGreen
|
|||
|
cmp.b d1,d5 ;compare blue components
|
|||
|
BHI.S @gotMaxBlue
|
|||
|
move.b d1,d0 ;keep the bigger of the two
|
|||
|
@gotMaxBlue
|
|||
|
swap d1
|
|||
|
swap d0
|
|||
|
cmp.b d1,d0 ;compare red components
|
|||
|
BHI.S @gotMaxRed
|
|||
|
move.b d1,d0 ;keep the bigger of the two
|
|||
|
@gotMaxRed
|
|||
|
swap d0 ;get new xrgb
|
|||
|
MOVE.L d0,(a1) ;write pattern to dest
|
|||
|
|
|||
|
@skip addq.l #4,a1 ;bump dst ptr
|
|||
|
addq.l #4,d6 ;bump src index
|
|||
|
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|||
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;-------------------------------------------------------
|
|||
|
;
|
|||
|
; MODE 47: MIN(PAT, DST) --> DST
|
|||
|
;
|
|||
|
;-------------------------------------------------------
|
|||
|
; a0 = d0 = result
|
|||
|
; a1 = dstPtr d1 = src pixel
|
|||
|
; a2 = maskPtr d2 = run cnt
|
|||
|
; a3 = patPtr d3 =
|
|||
|
; a4 = d4 = patHMask
|
|||
|
; a5 = d5 = dest pixel
|
|||
|
; a6 = locals d6 = pattern offset
|
|||
|
; a7 = d7 =
|
|||
|
;-------------------------------------------------------
|
|||
|
stMin32
|
|||
|
BSR arithSetup32 ;set up registers for slab bitblt
|
|||
|
|
|||
|
@blit tst.l (a2)+ ;a pixel of the clip region
|
|||
|
beq.s @skip
|
|||
|
move.l 0(a3,d6),d1 ;get src pixel
|
|||
|
move.l (a1),d5 ;get dest pixel
|
|||
|
|
|||
|
move.l d5,d0 ;make a copy of the dest xrgb
|
|||
|
cmp.w d1,d0 ;compare g,b components
|
|||
|
BLS.S @gotMinGreen
|
|||
|
move.w d1,d0 ;keep the smaller of the two
|
|||
|
move.b d5,d0 ;prime for blue
|
|||
|
@gotMinGreen
|
|||
|
cmp.b d1,d5 ;compare blue components
|
|||
|
BLS.S @gotMinBlue
|
|||
|
move.b d1,d0 ;keep the smaller of the two
|
|||
|
@gotMinBlue
|
|||
|
swap d1
|
|||
|
swap d0
|
|||
|
cmp.b d1,d0 ;compare red components
|
|||
|
BLS.S @gotMinRed
|
|||
|
move.b d1,d0 ;keep the smaller of the two
|
|||
|
@gotMinRed
|
|||
|
swap d0 ;get new xrgb
|
|||
|
MOVE.L d0,(a1) ;write pattern to dest
|
|||
|
|
|||
|
@skip addq.l #4,a1 ;bump dst ptr
|
|||
|
addq.l #4,d6 ;bump src index
|
|||
|
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|||
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;-------------------------------------------------------
|
|||
|
;
|
|||
|
; MODE 40: AVG(SRC, DST, WEIGHT) --> DST
|
|||
|
;
|
|||
|
; CLOBBERS: D0,D3,D2,A1,A2
|
|||
|
; A3,D6 (BUT NOT IN FASTSLAB)
|
|||
|
;-------------------------------------------------------
|
|||
|
; a0 = /last dst d0 = red weight
|
|||
|
; a1 = dstPtr d1 = blue/grn weight (scanCount)
|
|||
|
; a2 = maskPtr d2 = run cnt
|
|||
|
; a3 = patPtr d3 = /last src
|
|||
|
; a4 = d4 = /last result
|
|||
|
; a5 = d5 = dest pixel
|
|||
|
; a6 = locals d6 = pattern offset
|
|||
|
; a7 = d7 = src pixel
|
|||
|
;-------------------------------------------------------
|
|||
|
stAvg32
|
|||
|
lea @stAvg32Slow,a0 ;assume, general blend32 from now on
|
|||
|
move.l a0,modeCase(a6)
|
|||
|
lea weight(a6),a0 ;point to weights
|
|||
|
move.w (a0)+,d3
|
|||
|
cmp.w (a0)+,d3 ;is opColor gray?
|
|||
|
bne.s @stAvg32Slow
|
|||
|
cmp.w (a0),d3
|
|||
|
bne.s @stAvg32Slow
|
|||
|
addq #1,d3 ;yes, check for gray values of $8000 or $7fff
|
|||
|
and.w #$fffe,d3
|
|||
|
cmp.w #$8000,d3
|
|||
|
bne.s @stAvg32Slow
|
|||
|
lea @stAvg32Half,a0 ;use fast 50% blend32 from now on
|
|||
|
move.l a0,modeCase(a6)
|
|||
|
bra @stAvg32Half
|
|||
|
|
|||
|
;-------------------------------------------------------
|
|||
|
;
|
|||
|
; General blend case for non 50% gray weights
|
|||
|
;
|
|||
|
;
|
|||
|
@stAvg32Slow
|
|||
|
BSR arithSetup32 ;set up registers for slab bitblt
|
|||
|
|
|||
|
lea weight(a6),a0 ;point at blue weight
|
|||
|
move.l (a0)+,d1 ;get blue/green weight
|
|||
|
move.w (a0),d0 ;get red weight
|
|||
|
|
|||
|
@short0 moveq #0,d4 ;init last result
|
|||
|
move.l d4,d3 ;init last src
|
|||
|
move.l d4,a0 ;init last dst
|
|||
|
|
|||
|
@blit tst.l (A2)+ ;a pixel of the clip region
|
|||
|
BEQ.S @skip
|
|||
|
move.l 0(a3,d6),d7 ;get src pixel
|
|||
|
move.l (a1),d5 ;get dest pixel
|
|||
|
|
|||
|
@short1 cmp.l d3,d7 ;same as last time?
|
|||
|
bne.s @blue ;no, go do it
|
|||
|
cmp.l a0,d5 ;same as last time?
|
|||
|
beq.s @again ;yes, go fast
|
|||
|
|
|||
|
@blue moveq #0,d3 ;clr out high end
|
|||
|
move.b d7,d3 ;get src blue
|
|||
|
swap d1 ;get blue weight
|
|||
|
mulu.w d1,d3 ;% blue
|
|||
|
|
|||
|
moveq #0,d4 ;clr out high end
|
|||
|
move.b d5,d4 ;get dst blue
|
|||
|
neg.w d1
|
|||
|
mulu.w d1,d4 ;% blue
|
|||
|
neg.w d1
|
|||
|
|
|||
|
add.l d3,d4 ;get 24 bits of dst blue
|
|||
|
swap d4 ;dst blue
|
|||
|
move.w d4,a0 ;a0 has 000B
|
|||
|
|
|||
|
@grn move.w d7,d3 ;get src grn
|
|||
|
lsr.w #8,d3
|
|||
|
swap d1 ;get grn weight
|
|||
|
mulu.w d1,d3 ;% grn
|
|||
|
|
|||
|
move.w d5,d4 ;get dst grn
|
|||
|
lsr.w #8,d4
|
|||
|
neg.w d1
|
|||
|
mulu.w d1,d4 ;% grn
|
|||
|
neg.w d1
|
|||
|
|
|||
|
add.l d3,d4 ;get 24 bits of dst grn
|
|||
|
swap d4 ;dst grn
|
|||
|
lsl.w #8,d4
|
|||
|
add.w d4,a0 ;a0 has 00GB
|
|||
|
|
|||
|
@red moveq #0,d3 ;clr out high end
|
|||
|
swap d7
|
|||
|
move.b d7,d3 ;get src red
|
|||
|
mulu.w d0,d3 ;% red
|
|||
|
|
|||
|
moveq #0,d4 ;clr out high end
|
|||
|
swap d5
|
|||
|
move.b d5,d4 ;get dst red
|
|||
|
neg.w d0
|
|||
|
mulu.w d0,d4 ;% red
|
|||
|
neg.w d0
|
|||
|
|
|||
|
add.l d3,d4 ;get 24 bits of dst red
|
|||
|
move.w a0,d4 ;d4 has 0RGB
|
|||
|
|
|||
|
@short2 swap d5 ;get back dst
|
|||
|
move.l d5,a0 ;save for short circuit
|
|||
|
swap d7 ;get back src
|
|||
|
move.l d7,d3 ;save for short circuit
|
|||
|
|
|||
|
@again MOVE.L d4,(a1) ;write pattern to dest
|
|||
|
|
|||
|
@skip addq.l #4,a1 ;bump dst ptr
|
|||
|
addq.l #4,d6 ;bump src index
|
|||
|
; and.w patHMask(a6),d6 ;constrict to the source long if in a pattern mode
|
|||
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;--------------------------------------------
|
|||
|
;
|
|||
|
; Optimized 50% blend case for 32 bits/pixel
|
|||
|
;
|
|||
|
;-------------------------------------------------------
|
|||
|
; a0 = low bit mask d0 = high bit mask
|
|||
|
; a1 = dstPtr d1 = src pixel
|
|||
|
; a2 = maskPtr d2 = run cnt
|
|||
|
; a3 = patPtr d3 = lsb's of result
|
|||
|
; a4 = d4 = patHMask
|
|||
|
; a5 = d5 = dest pixel
|
|||
|
; a6 = locals d6 = pattern offset
|
|||
|
; a7 = d7 =
|
|||
|
;-------------------------------------------------------
|
|||
|
@stAvg32Half
|
|||
|
BSR arithSetup32 ;set up registers for slab bitblt
|
|||
|
|
|||
|
move.l #~$ff808080,d0 ;get high bit mask
|
|||
|
move.l #$10101,a0 ;get low bit mask
|
|||
|
|
|||
|
@blit2 tst.l (A2)+ ;a pixel of the clip region
|
|||
|
BEQ.S @skip2
|
|||
|
move.l 0(a3,d6),d1 ;get src pixel
|
|||
|
|
|||
|
move.l a0,d3 ;copy low bit mask
|
|||
|
and.l d1,d3 ;remember src lsb's
|
|||
|
lsr.l #1,d1 ;get almost 1/2 of it
|
|||
|
and.l d0,d1 ;mask out stragglers
|
|||
|
|
|||
|
move.l (a1),d5 ;get dest pixel
|
|||
|
and.l d5,d3 ;compute carry out of lsb
|
|||
|
lsr.l #1,d5 ;get almost 1/2 of it
|
|||
|
and.l d0,d5 ;mask out stragglers
|
|||
|
|
|||
|
add.l d5,d1 ;merge src with dst
|
|||
|
add.l d3,d1 ;propagate carrys
|
|||
|
MOVE.L d1,(a1) ;write pattern to dest
|
|||
|
|
|||
|
@skip2 addq.l #4,a1 ;bump dst ptr
|
|||
|
addq.l #4,d6 ;bump src index
|
|||
|
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|||
|
DBRA D2,@blit2 ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;--------------------------------------------
|
|||
|
;
|
|||
|
; Mode: 36 Transparent for 32 bits/pixel
|
|||
|
;
|
|||
|
;-------------------------------------------------------
|
|||
|
; a0 = d0 =
|
|||
|
; a1 = dstPtr d1 = src pixel
|
|||
|
; a2 = maskPtr d2 = run cnt
|
|||
|
; a3 = patPtr d3 =
|
|||
|
; a4 = d4 = patHMask
|
|||
|
; a5 = d5 = backColor
|
|||
|
; a6 = locals d6 = pattern offset
|
|||
|
; a7 = d7 =
|
|||
|
;-------------------------------------------------------
|
|||
|
stTransparent32
|
|||
|
BSR arithSetup32 ;set up registers for slab bitblt
|
|||
|
|
|||
|
move.l transColor(A6),D5 ;get a pixel of the transparent color
|
|||
|
|
|||
|
@blit tst.l (A2)+ ;a pixel of the clip region
|
|||
|
BEQ.S @skip
|
|||
|
move.l 0(a3,d6),d1 ;get src pixel
|
|||
|
|
|||
|
cmp.l d1,d5 ;is src backColor?
|
|||
|
beq.s @skip ;yes, don't write to dst
|
|||
|
MOVE.L d1,(a1) ;write pattern to dest
|
|||
|
|
|||
|
@skip addq.l #4,a1 ;bump dst ptr
|
|||
|
addq.l #4,d6 ;bump src index
|
|||
|
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|||
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
;<3B>all of these loops are as seen in QDciPatchROM.a <sm 6/9/92>stb
|
|||
|
;--------------------------------------------------------------------------
|
|||
|
;
|
|||
|
;
|
|||
|
; Here begin the arithmetic transfer loops for 16 bits/pixel:
|
|||
|
;
|
|||
|
;
|
|||
|
;
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;--------------------------------------------------------------------------
|
|||
|
;
|
|||
|
; MODE 42: PAT + DST --> DST (no pin)
|
|||
|
;-------------------------------------------------------
|
|||
|
; a0 = hi bit mask d0 = hi bit clring mask
|
|||
|
; a1 = dstPtr d1 = src pixel
|
|||
|
; a2 = maskPtr d2 = run cnt
|
|||
|
; a3 = patPtr d3 = src msb's
|
|||
|
; a4 = d4 = patHMask
|
|||
|
; a5 = d5 = dest pixel
|
|||
|
; a6 = locals d6 = pattern offset
|
|||
|
; a7 = d7 = dst msb's
|
|||
|
;-------------------------------------------------------
|
|||
|
stAddOver16
|
|||
|
BSR.s arithSetup16 ;set up registers for slab bitblt
|
|||
|
|
|||
|
move.w #$3def,d0 ;get high bit clearing mask
|
|||
|
move.w #$4210,a0 ;get high bit mask
|
|||
|
|
|||
|
@blit tst.w (a2)+ ;a pixel of the clip region
|
|||
|
beq.s @skip
|
|||
|
|
|||
|
move.w 0(a3,d6),d1 ;get src pixel
|
|||
|
move.w a0,d7 ;copy high bit mask
|
|||
|
and.w d1,d7 ;remember src msb's
|
|||
|
and.w d0,d1 ;mask out stragglers
|
|||
|
|
|||
|
move.w (a1),d5 ;get dest pixel
|
|||
|
move.w a0,d3 ;copy high bit mask
|
|||
|
and.w d5,d3 ;remember dst msb's
|
|||
|
and.w d0,d5 ;mask out stragglers
|
|||
|
|
|||
|
add.w d1,d5 ;merge src with dst
|
|||
|
eor.w d7,d3 ;compute partial sum of msb's
|
|||
|
eor.w d3,d5 ;compute partial sum of msb's
|
|||
|
MOVE.w d5,(a1) ;write pattern to dest
|
|||
|
|
|||
|
@skip addq.l #2,a1 ;bump dst ptr
|
|||
|
addq.l #2,d6 ;bump src index
|
|||
|
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|||
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
; Utility arithSetup
|
|||
|
; sets up registers for 16 bit arithmetic modes:
|
|||
|
;
|
|||
|
; INPUT
|
|||
|
; REGISTERS: A0: D0: CLOBBERED ;
|
|||
|
; A1: D1: CLOBBERED ;
|
|||
|
; A2: MASKPTR D2: LONGCNT ;
|
|||
|
; A3: SRCPTR D3: FGCOLOR ;
|
|||
|
; A4: DSTPTR D4: BKCOLOR ;
|
|||
|
; A5: D5: CLOBBERED ;
|
|||
|
; A6: D6: DSTALIGN ;
|
|||
|
; A7: D7: PixelSize ;
|
|||
|
; ;
|
|||
|
|
|||
|
arithSetup16
|
|||
|
move.l a4,a1 ;reroute dstPtr
|
|||
|
moveq #0,D6 ;zero src index
|
|||
|
; moveq #-1,D4 ;flush src modulus
|
|||
|
; move.l d4,patHMask(a6)
|
|||
|
tst dstAlign(a6) ;on longword boundary?
|
|||
|
beq.s @srcOK
|
|||
|
subq #2,a3 ;align src with mask
|
|||
|
@srcOK RTS
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;-------------------------------------------------------
|
|||
|
;
|
|||
|
; MODE 41: PAT + DST --> DST (pin to max)
|
|||
|
;-------------------------------------------------------
|
|||
|
; a0 = d0 = result
|
|||
|
; a1 = dstPtr d1 =
|
|||
|
; a2 = maskPtr d2 = run cnt
|
|||
|
; a3 = patPtr d3 = pin pixel 0rgb
|
|||
|
; a4 = d4 = patHMask
|
|||
|
; a5 = d5 = dest pixel
|
|||
|
; a6 = locals d6 = pattern offset
|
|||
|
; a7 = d7 = src pixel
|
|||
|
;-------------------------------------------------------
|
|||
|
stAddPin16
|
|||
|
BSR.s arithSetup16 ;set up registers for slab bitblt
|
|||
|
|
|||
|
;set up pin pixel as 0rgb in D3
|
|||
|
|
|||
|
moveq #0,d3 ;start fresh, waste iTabRes
|
|||
|
move.b pin+4(a6),d3 ;pick up red
|
|||
|
lsr.b #3,d3 ;get right aligned 5 bits
|
|||
|
swap d3 ;put in byte 3
|
|||
|
move.w pin+2(a6),d3 ;get green in byte 2
|
|||
|
lsr.w #3,d3 ;get right aligned 5 bits
|
|||
|
move.b pin(a6),d3 ;put blue in lo byte
|
|||
|
lsr.b #3,d3 ;right flush blue
|
|||
|
|
|||
|
@blit tst.w (a2)+ ;a pixel of the clip region
|
|||
|
beq.s @skip
|
|||
|
|
|||
|
moveq #0,d7
|
|||
|
move.w 0(a3,d6),d7 ;get src pixel
|
|||
|
add.w d7,d7 ;waste high bit
|
|||
|
lsl.l #5,d7 ;but red in byte 3
|
|||
|
lsr.w #3,d7 ;but green in byte 2, blue in lo byte
|
|||
|
lsr.b #3,d7 ;right flush blue
|
|||
|
|
|||
|
moveq #0,d5
|
|||
|
move.w (a1),d5 ;get dest pixel
|
|||
|
add.w d5,d5 ;waste high bit
|
|||
|
lsl.l #5,d5 ;but red in byte 3
|
|||
|
lsr.w #3,d5 ;but green in byte 2, blue in lo byte
|
|||
|
lsr.b #3,d5 ;right flush blue
|
|||
|
|
|||
|
add.l d5,d7 ;add all components at once
|
|||
|
move.l d7,d0 ;prime result with red
|
|||
|
cmp.l d3,d0 ;do we need to pin result?
|
|||
|
bls.s @redOK ;no, don't pin
|
|||
|
move.l d3,d0 ;use pin value instead
|
|||
|
@redOK
|
|||
|
move.w d7,d0 ;prime result with green
|
|||
|
cmp.w d3,d0 ;do we need to pin result?
|
|||
|
bls.s @greenOK ;no, don't pin
|
|||
|
move.w d3,d0 ;use pin value instead
|
|||
|
@greenOK
|
|||
|
move.b d7,d0 ;prime result with blue
|
|||
|
cmp.b d3,d0 ;do we need to pin result?
|
|||
|
bls.s @blueOK ;no, don't pin
|
|||
|
move.b d3,d0 ;use pin value instead
|
|||
|
@blueOK
|
|||
|
|
|||
|
lsl.b #3,d0 ;rejoin green/blue
|
|||
|
lsl.w #3,d0 ;rejoin red/green/blue
|
|||
|
lsr.l #6,d0 ;right flush red/green/blue
|
|||
|
MOVE.w d0,(a1) ;write pattern to dest
|
|||
|
|
|||
|
@skip addq.l #2,a1 ;bump dst ptr
|
|||
|
addq.l #2,d6 ;bump src index
|
|||
|
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|||
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;-------------------------------------------------------
|
|||
|
;
|
|||
|
; MODE 46: DST - PAT --> DST (no pin)
|
|||
|
;
|
|||
|
;-------------------------------------------------------
|
|||
|
; a0 = d0 = hi bit clring mask
|
|||
|
; a1 = dstPtr d1 = high bit mask
|
|||
|
; a2 = maskPtr d2 = run cnt
|
|||
|
; a3 = patPtr d3 = src msb's
|
|||
|
; a4 = d4 = dst msb's
|
|||
|
; a5 = d5 = dest pixel
|
|||
|
; a6 = locals d6 = pattern offset
|
|||
|
; a7 = d7 = src pixel
|
|||
|
;-------------------------------------------------------
|
|||
|
stSubOver16
|
|||
|
BSR arithSetup16 ;set up registers for slab bitblt
|
|||
|
|
|||
|
move.w #$3def,d0 ;get high bit clearing mask
|
|||
|
move.w #$4210,d1 ;get high bit mask
|
|||
|
|
|||
|
@blit tst.w (a2)+ ;a pixel of the clip region
|
|||
|
beq.s @skip
|
|||
|
|
|||
|
move.w 0(a3,d6),d7 ;get src pixel
|
|||
|
move.w d1,d3 ;copy high bit mask
|
|||
|
and.w d7,d3 ;remember src msb's
|
|||
|
eor.w d1,d3 ;invert src msb's
|
|||
|
and.w d0,d7 ;mask out stragglers
|
|||
|
|
|||
|
move.w (a1),d5 ;get dest pixel
|
|||
|
move.w d1,d4 ;copy high bit mask
|
|||
|
and.w d5,d4 ;remember dst msb's
|
|||
|
and.w d0,d5 ;mask out high byte
|
|||
|
or.w d1,d5 ;force high bits on
|
|||
|
|
|||
|
sub.w d7,d5 ;compute dst - src
|
|||
|
eor.w d3,d4 ;compute partial sum of msb's
|
|||
|
eor.w d4,d5 ;compute partial sum of msb's
|
|||
|
MOVE.w d5,(a1) ;write pattern to dest
|
|||
|
|
|||
|
@skip addq.l #2,a1 ;bump dst ptr
|
|||
|
addq.l #2,d6 ;bump src index
|
|||
|
; and.w patHMask(a6),d6 ;constrict to the source long if in a pattern mode
|
|||
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;-------------------------------------------------------
|
|||
|
;
|
|||
|
; MODE 43: DST - PAT --> DST (pin to min)
|
|||
|
;
|
|||
|
;-------------------------------------------------------
|
|||
|
; a0 = d0 = result
|
|||
|
; a1 = dstPtr d1 = lo3Bytes mask
|
|||
|
; a2 = maskPtr d2 = run cnt
|
|||
|
; a3 = patPtr d3 = pin pixel 0rgb
|
|||
|
; a4 = d4 = patHMask
|
|||
|
; a5 = d5 = src pixel
|
|||
|
; a6 = locals d6 = pattern offset
|
|||
|
; a7 = d7 = dst pixel
|
|||
|
;-------------------------------------------------------
|
|||
|
stSubPin16
|
|||
|
BSR arithSetup16 ;set up registers for slab bitblt
|
|||
|
|
|||
|
;set up pin pixel as 0rgb in D3
|
|||
|
|
|||
|
moveq #0,d3 ;start fresh, waste iTabRes
|
|||
|
move.b pin+4(a6),d3 ;pick up red
|
|||
|
lsr.b #3,d3 ;get right aligned 5 bits
|
|||
|
swap d3 ;put in byte 3
|
|||
|
move.w pin+2(a6),d3 ;get green in byte 2
|
|||
|
lsr.w #3,d3 ;get right aligned 5 bits
|
|||
|
move.b pin(a6),d3 ;put blue in lo byte
|
|||
|
lsr.b #3,d3 ;right flush blue
|
|||
|
move.l #$808080,d1 ;borrow stopper
|
|||
|
add.l d1,d3 ;prevent borrows from crossing byte boundaries
|
|||
|
|
|||
|
@blit tst.w (a2)+ ;a pixel of the clip region
|
|||
|
beq.s @skip
|
|||
|
|
|||
|
moveq #0,d5
|
|||
|
move.w 0(a3,d6),d5 ;get src pixel
|
|||
|
add.w d5,d5 ;waste high bit
|
|||
|
lsl.l #5,d5 ;but red in byte 3
|
|||
|
lsr.w #3,d5 ;but green in byte 2, blue in lo byte
|
|||
|
lsr.b #3,d5 ;right flush blue
|
|||
|
|
|||
|
moveq #0,d7
|
|||
|
move.w (a1),d7 ;get dest pixel
|
|||
|
add.w d7,d7 ;waste high bit
|
|||
|
lsl.l #5,d7 ;but red in byte 3
|
|||
|
lsr.w #3,d7 ;but green in byte 2, blue in lo byte
|
|||
|
lsr.b #3,d7 ;right flush blue
|
|||
|
add.l d1,d7 ;prevent borrows from crossing byte boundaries
|
|||
|
|
|||
|
sub.l d5,d7 ;sub all components at once
|
|||
|
move.l d7,d0 ;prime result with red
|
|||
|
cmp.l d3,d0 ;do we need to pin result?
|
|||
|
bhs.s @redOK ;no, don't pin
|
|||
|
move.l d3,d0 ;use pin value instead
|
|||
|
@redOK
|
|||
|
move.w d7,d0 ;prime result with green
|
|||
|
cmp.w d3,d0 ;do we need to pin result?
|
|||
|
bhs.s @greenOK ;no, don't pin
|
|||
|
move.w d3,d0 ;use pin value instead
|
|||
|
@greenOK
|
|||
|
move.b d7,d0 ;prime result with blue
|
|||
|
cmp.b d3,d0 ;do we need to pin result?
|
|||
|
bhs.s @blueOK ;no, don't pin
|
|||
|
move.b d3,d0 ;use pin value instead
|
|||
|
@blueOK
|
|||
|
|
|||
|
lsl.b #3,d0 ;rejoin green/blue
|
|||
|
lsl.w #3,d0 ;rejoin red/green/blue
|
|||
|
lsr.l #6,d0 ;right flush red/green/blue
|
|||
|
MOVE.w d0,(a1) ;write pattern to dest
|
|||
|
|
|||
|
@skip addq.l #2,a1 ;bump dst ptr
|
|||
|
addq.l #2,d6 ;bump src index
|
|||
|
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|||
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;-------------------------------------------------------
|
|||
|
;
|
|||
|
; MODE 45: MAX(PAT, DST) --> DST
|
|||
|
;
|
|||
|
;-------------------------------------------------------
|
|||
|
; a0 = d0 = result
|
|||
|
; a1 = dstPtr d1 = src pixel
|
|||
|
; a2 = maskPtr d2 = run cnt
|
|||
|
; a3 = patPtr d3 =
|
|||
|
; a4 = d4 = patHMask
|
|||
|
; a5 = d5 = dest pixel
|
|||
|
; a6 = locals d6 = pattern offset
|
|||
|
; a7 = d7 =
|
|||
|
;-------------------------------------------------------
|
|||
|
stMax16
|
|||
|
BSR arithSetup16 ;set up registers for slab bitblt
|
|||
|
|
|||
|
@blit tst.w (a2)+ ;a pixel of the clip region
|
|||
|
beq.s @skip
|
|||
|
|
|||
|
moveq #0,d7
|
|||
|
move.w 0(a3,d6),d7 ;get src pixel
|
|||
|
add.w d7,d7 ;waste high bit
|
|||
|
lsl.l #5,d7 ;but red in byte 3
|
|||
|
lsr.w #3,d7 ;but green in byte 2, blue in lo byte
|
|||
|
lsr.b #3,d7 ;right flush blue
|
|||
|
|
|||
|
moveq #0,d5
|
|||
|
move.w (a1),d5 ;get dest pixel
|
|||
|
add.w d5,d5 ;waste high bit
|
|||
|
lsl.l #5,d5 ;but red in byte 3
|
|||
|
lsr.w #3,d5 ;but green in byte 2, blue in lo byte
|
|||
|
lsr.b #3,d5 ;right flush blue
|
|||
|
|
|||
|
move.l d7,d0 ;prime result with src
|
|||
|
cmp.l d5,d0 ;is dst greater?
|
|||
|
bhs.s @gotRed ;no, use src
|
|||
|
move.l d5,d0 ;use dst value instead
|
|||
|
@gotRed
|
|||
|
move.w d7,d0 ;prime result with src
|
|||
|
cmp.w d5,d0 ;is dst greater?
|
|||
|
bhs.s @gotGreen ;no, use src
|
|||
|
move.w d5,d0 ;use dst value instead
|
|||
|
@gotGreen
|
|||
|
move.b d7,d0 ;prime result with src
|
|||
|
cmp.b d5,d0 ;is dst greater?
|
|||
|
bhs.s @gotBlue ;no, use src
|
|||
|
move.b d5,d0 ;use dst value instead
|
|||
|
@gotBlue
|
|||
|
|
|||
|
lsl.b #3,d0 ;rejoin green/blue
|
|||
|
lsl.w #3,d0 ;rejoin red/green/blue
|
|||
|
lsr.l #6,d0 ;right flush red/green/blue
|
|||
|
MOVE.w d0,(a1) ;write pattern to dest
|
|||
|
|
|||
|
@skip addq.l #2,a1 ;bump dst ptr
|
|||
|
addq.l #2,d6 ;bump src index
|
|||
|
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|||
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;-------------------------------------------------------
|
|||
|
;
|
|||
|
; MODE 47: MIN(PAT, DST) --> DST
|
|||
|
;
|
|||
|
;-------------------------------------------------------
|
|||
|
; a0 = d0 = result
|
|||
|
; a1 = dstPtr d1 = src pixel
|
|||
|
; a2 = maskPtr d2 = run cnt
|
|||
|
; a3 = patPtr d3 =
|
|||
|
; a4 = d4 = patHMask
|
|||
|
; a5 = d5 = dest pixel
|
|||
|
; a6 = locals d6 = pattern offset
|
|||
|
; a7 = d7 =
|
|||
|
;-------------------------------------------------------
|
|||
|
stMin16
|
|||
|
BSR arithSetup16 ;set up registers for slab bitblt
|
|||
|
|
|||
|
@blit tst.w (a2)+ ;a pixel of the clip region
|
|||
|
beq.s @skip
|
|||
|
|
|||
|
moveq #0,d7
|
|||
|
move.w 0(a3,d6),d7 ;get src pixel
|
|||
|
add.w d7,d7 ;waste high bit
|
|||
|
lsl.l #5,d7 ;but red in byte 3
|
|||
|
lsr.w #3,d7 ;but green in byte 2, blue in lo byte
|
|||
|
lsr.b #3,d7 ;right flush blue
|
|||
|
|
|||
|
moveq #0,d5
|
|||
|
move.w (a1),d5 ;get dest pixel
|
|||
|
add.w d5,d5 ;waste high bit
|
|||
|
lsl.l #5,d5 ;but red in byte 3
|
|||
|
lsr.w #3,d5 ;but green in byte 2, blue in lo byte
|
|||
|
lsr.b #3,d5 ;right flush blue
|
|||
|
|
|||
|
move.l d7,d0 ;prime result with src
|
|||
|
cmp.l d5,d0 ;is dst smaller?
|
|||
|
bls.s @gotRed ;no, use src
|
|||
|
move.l d5,d0 ;use dst value instead
|
|||
|
@gotRed
|
|||
|
move.w d7,d0 ;prime result with src
|
|||
|
cmp.w d5,d0 ;is dst smaller?
|
|||
|
bls.s @gotGreen ;no, use src
|
|||
|
move.w d5,d0 ;use dst value instead
|
|||
|
@gotGreen
|
|||
|
move.b d7,d0 ;prime result with src
|
|||
|
cmp.b d5,d0 ;is dst smaller?
|
|||
|
bls.s @gotBlue ;no, use src
|
|||
|
move.b d5,d0 ;use dst value instead
|
|||
|
@gotBlue
|
|||
|
|
|||
|
lsl.b #3,d0 ;rejoin green/blue
|
|||
|
lsl.w #3,d0 ;rejoin red/green/blue
|
|||
|
lsr.l #6,d0 ;right flush red/green/blue
|
|||
|
MOVE.w d0,(a1) ;write pattern to dest
|
|||
|
|
|||
|
@skip addq.l #2,a1 ;bump dst ptr
|
|||
|
addq.l #2,d6 ;bump src index
|
|||
|
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
|||
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;-------------------------------------------------------
|
|||
|
;
|
|||
|
; MODE 40: AVG(SRC, DST, WEIGHT) --> DST
|
|||
|
;
|
|||
|
; CLOBBERS: D0,D3,D2,A1,A2
|
|||
|
; A3,D6 (BUT NOT IN FASTSLAB)
|
|||
|
;-------------------------------------------------------
|
|||
|
; a0 = /last dst d0 = red weight
|
|||
|
; a1 = dstPtr d1 = blue/grn weight (scanCount)
|
|||
|
; a2 = maskPtr d2 = run cnt
|
|||
|
; a3 = patPtr d3 = /last src
|
|||
|
; a4 = d4 = /last result
|
|||
|
; a5 = d5 = dest pixel
|
|||
|
; a6 = locals d6 = pattern offset
|
|||
|
; a7 = d7 = src pixel
|
|||
|
;-------------------------------------------------------
|
|||
|
stAvg16
|
|||
|
lea @stAvg16Slow,a0 ;assume, general blend16 from now on
|
|||
|
move.l a0,modeCase(a6)
|
|||
|
lea weight(a6),a0 ;point to weights
|
|||
|
move.w (a0)+,d3
|
|||
|
cmp.w (a0)+,d3 ;is opColor gray?
|
|||
|
bne.s @stAvg16Slow
|
|||
|
cmp.w (a0),d3
|
|||
|
bne.s @stAvg16Slow
|
|||
|
addq #1,d3 ;yes, check for gray values of $8000 or $7fff
|
|||
|
and.w #$fffe,d3
|
|||
|
cmp.w #$8000,d3
|
|||
|
bne.s @stAvg16Slow
|
|||
|
lea @stAvg16Half,a0 ;use fast 50% blend16 from now on
|
|||
|
move.l a0,modeCase(a6)
|
|||
|
bra @stAvg16Half
|
|||
|
|
|||
|
;-------------------------------------------------------
|
|||
|
;
|
|||
|
; General blend case for non 50% gray weights
|
|||
|
;
|
|||
|
;
|
|||
|
@stAvg16Slow
|
|||
|
BSR arithSetup16 ;set up registers for slab bitblt
|
|||
|
|
|||
|
lea weight(a6),a0 ;point at blue weight
|
|||
|
move.l (a0)+,d1 ;get blue/green weight
|
|||
|
move.w (a0),d0 ;get red weight
|
|||
|
|
|||
|
@short0 moveq #0,d4 ;init last result
|
|||
|
move.l d4,d3 ;init last src
|
|||
|
move.l d4,a0 ;init last dst
|
|||
|
|
|||
|
@blit tst.w (A2)+ ;a pixel of the clip region
|
|||
|
BEQ @skip
|
|||
|
moveq #0,d7
|
|||
|
move.w 0(a3,d6),d7 ;get src pixel
|
|||
|
moveq #0,d5
|
|||
|
move.w (a1),d5 ;get dest pixel
|
|||
|
|
|||
|
@short1 cmp.w d3,d7 ;same as last time?
|
|||
|
bne.s @hardway ;no, go do it
|
|||
|
cmp.w a0,d5 ;same as last time?
|
|||
|
beq.s @again ;yes, go fast
|
|||
|
@hardway
|
|||
|
add.w d7,d7 ;waste high bit
|
|||
|
lsl.l #5,d7 ;but red in byte 3
|
|||
|
lsr.w #3,d7 ;but green in byte 2, blue in lo byte
|
|||
|
lsr.b #3,d7 ;right flush blue
|
|||
|
|
|||
|
add.w d5,d5 ;waste high bit
|
|||
|
lsl.l #5,d5 ;but red in byte 3
|
|||
|
lsr.w #3,d5 ;but green in byte 2, blue in lo byte
|
|||
|
lsr.b #3,d5 ;right flush blue
|
|||
|
|
|||
|
@blue moveq #0,d3 ;clr out high end
|
|||
|
move.b d7,d3 ;get src blue
|
|||
|
swap d1 ;get blue weight
|
|||
|
mulu.w d1,d3 ;% blue
|
|||
|
|
|||
|
moveq #0,d4 ;clr out high end
|
|||
|
move.b d5,d4 ;get dst blue
|
|||
|
neg.w d1
|
|||
|
mulu.w d1,d4 ;% blue
|
|||
|
neg.w d1
|
|||
|
|
|||
|
add.l d3,d4 ;get 21 bits of blue
|
|||
|
swap d4 ;right align 5 blue bits
|
|||
|
move.l d4,a0 ;a0 has 000B
|
|||
|
|
|||
|
@grn move.w d7,d3 ;get src grn
|
|||
|
lsr.w #8,d3
|
|||
|
swap d1 ;get grn weight
|
|||
|
mulu.w d1,d3 ;% grn
|
|||
|
|
|||
|
move.w d5,d4 ;get dst grn
|
|||
|
lsr.w #8,d4
|
|||
|
neg.w d1
|
|||
|
mulu.w d1,d4 ;% grn
|
|||
|
neg.w d1
|
|||
|
|
|||
|
add.l d3,d4 ;get 21 bits of grn
|
|||
|
swap d4 ;right align 5 green bits
|
|||
|
lsl.w #5,d4 ;shift into place
|
|||
|
add.w d4,a0 ;a0 has 00GB
|
|||
|
|
|||
|
@red moveq #0,d3 ;clr out high end
|
|||
|
swap d7
|
|||
|
move.b d7,d3 ;get src red
|
|||
|
mulu.w d0,d3 ;% red
|
|||
|
|
|||
|
moveq #0,d4 ;clr out high end
|
|||
|
swap d5
|
|||
|
move.b d5,d4 ;get dst red
|
|||
|
neg.w d0
|
|||
|
mulu.w d0,d4 ;% red
|
|||
|
neg.w d0
|
|||
|
|
|||
|
add.l d3,d4 ;get 21 bits of red
|
|||
|
clr.w d4 ;clear lsb's
|
|||
|
lsr.l #6,d4 ;shift into place
|
|||
|
add.w a0,d4 ;d4 has 0RGB
|
|||
|
|
|||
|
@short2 swap d5 ;get back dst
|
|||
|
lsl.b #3,d5 ;rejoin green/blue
|
|||
|
lsl.w #3,d5 ;rejoin red/green/blue
|
|||
|
lsr.l #6,d5 ;right flush red/green/blue
|
|||
|
move.l d5,a0 ;save for short circuit
|
|||
|
swap d7 ;get back src
|
|||
|
lsl.b #3,d7 ;rejoin green/blue
|
|||
|
lsl.w #3,d7 ;rejoin red/green/blue
|
|||
|
lsr.l #6,d7 ;right flush red/green/blue
|
|||
|
move.l d7,d3 ;save for short circuit
|
|||
|
|
|||
|
@again MOVE.w d4,(a1) ;write pattern to dest
|
|||
|
|
|||
|
@skip addq.l #2,a1 ;bump dst ptr
|
|||
|
addq.l #2,d6 ;bump src index
|
|||
|
; and.w patHMask(a6),d6 ;constrict to the source long if in a pattern mode
|
|||
|
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
|||
|
BRA NEXTDST ;LOOP FOR NEXT ROW
|
|||
|
|
|||
|
|
|||
|
ALIGN Alignment
|
|||
|
|
|||
|
;--------------------------------------------
|
|||
|
;
|
|||
|
; Optimized 50% blend case for 16 bits/pixel
|
|||
|
;
|
|||
|
;-------------------------------------------------------
|
|||
|
; a0 = low bit mask d0 = high bit mask
|
|||
|
; a1 = dstPtr d1 = src pixel
|
|||
|
; a2 = maskPtr d2 = run cnt
|
|||
|
; a3 = patPtr d3 = lsb's of result
|
|||
|
; a4 = d4 = patHMask
|
|||
|
; a5 = d5 = dest pixel
|
|||
|
; a6 = locals d6 = pattern offset
|
|||
|
; a7 = d7 =
|
|||
|
;-------------------------------------------------------
|
|||
|
@stAvg16Half
|
|||
|
BSR arithSetup16 ;set up registers for slab bitblt
|
|||
|
|
|||
|
move.w #$3def,d0 ;get high bit clearing mask
|
|||
|
move.w #$0421,a0 ;get low bit mask
|
|||
|
|
|||
|
@blit2 tst.w (A2)+ ;a pixel of the clip region
|
|||
|
BEQ.S @skip2
|
|||
|
move.w 0(a3,d6),d1 ;get src pixel
|
|||
|
|
|||
|
move.w a0,d3 ;copy low bit mask
|
|||
|
and.w d1,d3 ;remember src lsb's
|
|||
|