mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-27 22:51:28 +00:00
11960 lines
362 KiB
Plaintext
11960 lines
362 KiB
Plaintext
;
|
||
; File: Stretch.a
|
||
;
|
||
; Copyright: © 1981-1993 by Apple Computer, Inc., all rights reserved.
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <SM5> 9/12/93 SAM Changed all instances of _Translate24to32 to _rTranslate24to32
|
||
; so they can coditionalized out of the build.
|
||
; <SM4> 7/16/92 CSS Update from Reality:
|
||
; <66> 6/25/92 SAH #1033729: Fixed a bug where we don't always recognize when we're
|
||
; drawing to the alpha channel (just before calling ScaleBlt). We
|
||
; now do this correctly and take Stretch if drawing alpha,
|
||
; otherwise take the faster loops in ScaleBlt (which zero out the
|
||
; alpha channel).
|
||
; <65> 6/10/92 SAH Fixed a problem where we would defer to stretch if ScaleBlt did
|
||
; not hande the copy and the src was greater than one bits deep.
|
||
; This was causing crashes with Aldus Freehand and Macromind
|
||
; Director. Also fixed a problem where Stretch would munge
|
||
; StkLowPt, HieHeapMark and your stack in low-memory situations.
|
||
; <64> 6/8/92 SAH #1031825: Brought the ScaleBlt loops back to life. Now use
|
||
; ScaleBlt for indexed to direct (16 and 32) as well as indexed to
|
||
; indexed. Make use of new srcBlackWhiteOnly flag to enable us to
|
||
; use BitBlt when this is set and the src and dst are the same
|
||
; depths. Check to see if we need to change ScaleColor to
|
||
; ColorizeInModeCase if ScaleBlt fails. Also, test if using an
|
||
; alpha mode before calling ScaleBlt, in which case we take
|
||
; stretch.
|
||
; <SM3> 6/11/92 stb <sm 6/9/92>stb Synch with QDciPatchROM.a; added comments to
|
||
; StretchBits, MapModeTable, SRCONE, stNoStack, stMask0,
|
||
; stMASK0Slow, stHilite, arith. transfer loops for 16 & 32
|
||
; bits/pixel, OneColor, DoubleColor, QUADColor, EightLoop,
|
||
; BWtoD15Alpha, BWtoD24Alpha, AverageH16, Dither32toIndexed,
|
||
; Dither16toIndexed, Dither32toGray, Dither16toGray,
|
||
; Dither16toBitmap, Search32to32, Search32toInd, SeedCFill32,
|
||
; Search32to16, Search16toIndexed, SeedCFill16, Search16to32,
|
||
; Search16to16.
|
||
; <63> 5/5/92 SAH Put fix for clipped vertical stretch back in for Cube-E
|
||
; <62> 1/15/92 KC Fix "Short branch to the next instruction changed to a NOP"
|
||
; assembler warning.
|
||
; <61> 10/4/91 JSM Change PsychoticFarmerOrLater conditionals to TheFuture.
|
||
; <60> 10/2/91 DTY Conditionalise last changes for TheFuture.
|
||
; <59> 10/2/91 KON Fix bug where CopyBits was crashing when vertically stretching a
|
||
; pixmap that is clipped at the top.
|
||
; <58> 10/2/91 KON Save and restore stklowPt (rather than just setting it to sp on
|
||
; exit) in stretch. This fixes a bug where someone turns off the
|
||
; stack sniffer and then calls stretch which turns it back on.
|
||
; Also, abort picture playback when QDError = AbortPicPlayBackErr.
|
||
; <57> 10/2/91 KON Save and restore stklowPt (rather than just setting it to sp on
|
||
; exit) in stretch. This fixes a bug where someone turns off the
|
||
; stack sniffer and then calls stretch which turns it back on.
|
||
; Abort picture playback when QDError = AbortPicPlayBackErr.
|
||
; <56> 9/13/91 DTY Conditionalise previous change so it doesn’t get built for
|
||
; CubeE. (It’ll get built for PsychoticFarmerAndLater.) Move in
|
||
; code that was taken out between <54> and <55>, and build it for
|
||
; CubeE only.
|
||
; <55> 7/23/91 KON Speed up indexed to 32-bit srcCopy mode. Speed up colorized
|
||
; text: don't take scale case when depths are the same.
|
||
; <54> 3/19/91 KON DTY, WRKSHT#SAH-QD-055: Some pixmaps created with an old version
|
||
; of ResEdit had the high bit of pmVersion set. This causes the
|
||
; pmVersion macro to crash, so I removed it.
|
||
; <53> 3/18/91 KON GSC and JT: WKSHT# SAH-QD-054 16-bit source shrinks crash
|
||
; because the average buffer is calculated from the promoted
|
||
; depth, rather than the real depth.
|
||
; <52> 3/6/91 KON CEL: BRC# 84369 Register D0 was getting trashed when search
|
||
; procs were attached to direct destinations. Also, color
|
||
; calculation for 16-bits was incorrect when search proc is
|
||
; installed.
|
||
; <51> 2/19/91 KON DDG: WorkSheet #KS-003, MaskAddr in stackframe is not
|
||
; initialized if there is not a mask. This was causing crashes in
|
||
; some cases since verticle merge scanline routines look at the
|
||
; maskaddr.
|
||
; <50> 1/25/91 KON DDG: BRC# 81625, A fix in QDciPatchROM.a required reorganizing
|
||
; part of stretch. This change keeps the files in synchronization.
|
||
; <49> 1/23/91 KON Optimize and clean up code that was rushed for B4. [SMC]
|
||
; <48> 1/14/91 KON Fix PixMaps with nil color tables and CopyDeepMask with 1-bit
|
||
; mask. Fix bug in pmVersion macro. [SMC]
|
||
; <47> 1/11/91 KON Register was getting trashed around call to SeekMask. This
|
||
; caused CopyBits with more 3 regions to get trashed as in the
|
||
; KeyCaps CDEV. [DDG]
|
||
; <46> 12/17/90 KON Fix one of the problems with NIL color tables. [smc]
|
||
; <45> 11/26/90 SMC Fixed pattern hilite once and for all, and forced arithmetic
|
||
; transfers to direct devices into rgnblt instead of the slower
|
||
; loops in bitblt. With BAL.
|
||
; <44> 11/12/90 KON Fix problem with colorizing when dithering from an indexed src
|
||
; to an indexed destination. [smc]
|
||
; <43> 11/9/90 KON Copy rectangles to local stack and fixed problems with negative
|
||
; pmVersions.
|
||
; <42> 10/31/90 SMC Fixed alpha channel bugs with BAL.
|
||
; <41> 9/25/90 KON If source is 1-bit black and white and we are not shrinking,
|
||
; clear dither bit. (With SMC).
|
||
; <40> 9/18/90 SMC Fix transparent, addMax, subOver, and addMin transfers with a
|
||
; pattern.
|
||
; <39> 9/18/90 BG Removed <25>. 040s are behaving more reliably now.
|
||
; <38> 9/14/90 SMC Commented out all of the QuickerDraw routines and changed the
|
||
; logic to send those cases through ScaleBlt which are now faster
|
||
; and smaller (by about 1K). This implicitly fixes a bus error
|
||
; problem under AU/X when scaling from a 1-bit screen to the left
|
||
; edge of an 8-bit screen.
|
||
; <37> 9/13/90 KON NEEDED FOR BETA: Fix problem where promoting source to RGB is
|
||
; messed up. This showed up when the source is 1-bit. Also fixed
|
||
; in QDciPatchROM.a.
|
||
; <36> 9/10/90 KON Fixed one-bit to one-bit colorized copy.
|
||
; <35> 9/6/90 KON Fix 16 to indexed search loop.
|
||
; <34> 9/5/90 KON Fix copymask from an indexed src. The pmtable was not set
|
||
; correctly.
|
||
; <33> 9/4/90 KON fix problem where ctseed for 1-bit sources was getting trashed.
|
||
; If direct destination and search proc installed, use versions of
|
||
; fg and bg colors which have not been changed by the proc to do
|
||
; colorizing.
|
||
; <32> 8/26/90 KON Fix Search16to32 and Search32to16 stack frame referencing. Add
|
||
; 32-bit clean versions of MaskPixPmTable and SrcPixPmTable to
|
||
; stack frame.
|
||
; <31> 8/21/90 KON Always call search proc if one exists. If search proc fails,
|
||
; still use search procs RGBColor. Replicate bits when passing
|
||
; 16-bit source color to search procs.
|
||
; <30> 8/15/90 KON Fixed transparent mode which was writing outside the destination
|
||
; rectangle. Turned off colorizing for arithmetic modes.
|
||
; <29> 7/23/90 KON Fix CopyMask in cases where left and right edge are displaying
|
||
; garbage.
|
||
; <28> 7/20/90 gbm Change some identifiers to avoid assembly conflicts
|
||
; <27> 7/17/90 KON Fix 16-bit source notCopy mode.
|
||
; <26> 7/10/90 KON Fixed CopyMask for 16-bit sources, and cases where 16-bit masks
|
||
; were failing. Also fixed vertical shrinking of 1-bit sources.
|
||
; <26> 7/9/90 KON Fixed CopyMask for 16-bit sources, and cases where16-bit masks
|
||
; were failing.
|
||
; <25> 6/28/90 BG Added EclipseNOPs for flakey 040s.
|
||
; <24> 6/5/90 KON Speed up notCopy mode for direct src to direct dst by using
|
||
; invert flag.
|
||
; <23> 6/4/90 KON Speed things that slowed down up by checking if colorizing is a
|
||
; nop.
|
||
; <22> 5/29/90 HJR Fix Mac32 build problem by moving table8 and some code saving
|
||
; mods.
|
||
; <21> 5/24/90 KON Fix transfer modes for direct devices, and fix colorizing for
|
||
; indexed devices.
|
||
; <19+> 4/12/90 KON Add deep masks for copymask.
|
||
; <19> 4/11/90 KON Suppress colorizing in src blits when the src clut is nil (i.e.
|
||
; the colors are a ramp between the foreground and background
|
||
; colors.
|
||
; <18> 3/13/90 KON Part of file got trashed. Now fixed.
|
||
; <17> 3/13/90 KON Fixed bug in 16-bit search proc.
|
||
; <16> 3/6/90 KON Fixed error term for vertical shrinking so expanding and then
|
||
; shrinking by an integral amount does not alter the image.
|
||
; <15> 2/23/90 KON Fixed buffer problem in Dither16toGray.
|
||
; <14> 2/23/90 KON Fixed Dither32toGray and Dither16toGray. Random dots were
|
||
; displayed because error term was not calculated right.
|
||
; <13> 2/23/90 KON Added 16-bit shrink.
|
||
; <12> 2/16/90 KON Cleared out high end of register of ErrBuf size calculation.
|
||
; <11> 2/14/90 KON Try to get 256K in stNoStack. Memory requirement calculation now
|
||
; use longs so high bits aren't lost. StackFree is updated
|
||
; correctly.
|
||
; <10> 2/14/90 BAL Changed MFTemp memory stack allocation to try for upto 128K
|
||
; chunk.
|
||
; <9> 2/9/90 BAL Fixed dither 8-bit to 32-bit stretched copybits.
|
||
; <8> 2/5/90 BAL Fixed bug in vertical shrinking while performing indexed to
|
||
; indexed dither.
|
||
; <7> 2/1/90 BAL Dither16toIndexed: Fix dither error calculation for 16 bit
|
||
; sources being displayed on color indexed devices.
|
||
; <6> 2/1/90 BAL Special cased SeedCFill/CalcCMask search procs for 16 and 32 bit
|
||
; sources.
|
||
; <5> 1/30/90 BAL Fixed bugs in underflow of error when dithering to a grayscale
|
||
; or bitmap destination. This affects Dither32toGray/Bitmap and
|
||
; Dither16toGray/Bitmap.
|
||
; <4> 1/28/90 KON Fix clipping when destination is clipped at the top.
|
||
; <3> 1/28/90 BAL Added the depth conversion routines Dither32toBitmap and
|
||
; Dither16toBitmap and changed the decision tree to utilize them.
|
||
; <1+> 1/3/90 BAL FOR 6.0.5: Submitted latest version to BBS. Changes include
|
||
; indexed to indexed dithering support.
|
||
; <1.9> 12/9/89 BAL Fixed bug in accumulation of dither error in some of the loops.
|
||
; Should fix in others. Fixed a bug and optimized the case of
|
||
; source rects with tops above srcbits.bounds.
|
||
; <1.8> 9/25/89 BAL Changed "NOT forROM" conditionals to "useColorICON" and
|
||
; defaulted it to false
|
||
; <1.7> 7/16/89 GGD GGD for the vacationing BAL, Fixed bug in AverageH when
|
||
; averaging 2 pixels, and optimized the entire loop at the same
|
||
; time.
|
||
; <•1.6> 7/14/89 BAL For Aurora: Final CQD
|
||
; <1.5> 6/30/89 BAL Make A5 valid and return to 24 bit mode before calling search
|
||
; procs
|
||
; <•1.4> 5/29/89 BAL Blasting in 32-Bit QuickDraw version 1.0 Final
|
||
; 5/26/89 BAL Fixed bug in call to MakeITable if seed mismatch during direct
|
||
; to indexed copy.
|
||
; <•1.3> 4/12/89 BAL Blasting in 32-Bit QuickDraw 1.0B1
|
||
; 9/26/88 BAL Replace successfully TrimRect'ed rgns with wideopen to avoid
|
||
; multiple Trims.
|
||
; 9/22/88 BAL Moved initialization of region state records into GetSeek.
|
||
; 9/19/88 BAL Altered to use common stack frame file 'Drawing Vars.a'
|
||
; 9/18/88 BAL Altered to get CRSRFLAG value from _BitsToPix; Removed
|
||
; references to PIXSRC;
|
||
; 9/4/88 BAL Added area averaging for shrinking of 32 bit pixmaps.
|
||
; 8/29/88 BAL Changed 32 to 8-1bit dither to carry 2-D error.
|
||
; 6/28/88 BAL Added special scaling routine for B/W 1 bit to direct RGB in a
|
||
; 32 bit pixel.
|
||
; 6/27/88 BAL Changed pattern expansion routines for 16 and 32 bits to
|
||
; optimize for solid.
|
||
; 6/17/88 BAL Added routines to depth scale from direct to indexed devices.
|
||
; 5/9/88 BAL Altered depth scaling code to use long sized pixel translation
|
||
; table.
|
||
; 5/4/88 BAL fixed bug in n*8x scaling (n=3,5,6,7...)
|
||
; 5/3/88 BAL fixed 2 scaling bugs where word-sized operations overflowed
|
||
; 4/9/88 BAL altered to use 32bit addressing during blit to screens
|
||
; 12/7/87 BAL Changed <C947> to restore D7 (invertFlag) before returning to
|
||
; rgn/bitBlt. <C983>
|
||
; 11/8/87 BAL Forced stretch to only do color table pixel translation if
|
||
; absolutely necessary. <C947>
|
||
; 11/8/87 BAL Forced stretch to TrimRect(clipRgn,MinRect) before submitting to
|
||
; rgnBlt. <C951>
|
||
; 11/8/87 BAL Fixed computation of bufSize for more accurate region clipping
|
||
; at at depths greater than 1. <C954>
|
||
; 2/3/87 EHB Added error checking
|
||
; 1/3/87 CRC expect color param in stretch
|
||
; 12/12/86 CRC Added arithmetic modes
|
||
; 10/9/86 EHB Added mask parameters to stretchbits calls
|
||
; 9/11/86 EHB Added depth translation (N-bit to M-bit)
|
||
; 9/8/86 EHB Added full-ratio color scaling (N-bit to N-bit)
|
||
; 7/29/86 EHB Allocate EXPAT buffer on stack so long aligned
|
||
; 7/26/86 EHB Added support for expanded patterns
|
||
; 7/22/86 EHB Pass MODE to PatExpand for colorizing
|
||
; 7/7/86 EHB Revised use of color in blt routines.
|
||
; 7/5/86 EHB Replaced SeekMask and GetXRtn with GetSeek
|
||
; 6/24/86 EHB Big re-org: Create one stack frame shared by stretch, rgnblt,
|
||
; bitblt Set up all shared locals here, then call rgnblt, bitblt
|
||
; with parms in stack frame and registers (since stretchbits
|
||
; called from everywhere).
|
||
; 6/23/86 EHB Rearranged for shared stack frame between stretch, rgnblt,
|
||
; bitblt Set up all common fields before calls to rgnblt Removed
|
||
; all parameters passed to rgnblt (only called from here)
|
||
; 6/21/86 EHB Do expansion in 2 passes: one for data, next for chunks
|
||
; 6/20/86 EHB New params to COLORMAP Added FCOLOR and BCOLOR to stack frame
|
||
; 6/19/86 EHB Use longs in horiz calculations for big pixels
|
||
; 6/18/86 EHB Take depth into account for scaling
|
||
; 6/18/86 EHB Added a pattern param so it can be called instead of RgnBlt
|
||
; 6/16/86 EHB Added routine GetSizeShift to avoid multiplies
|
||
; 6/15/86 EHB Convert BitsToPix, and use pixelSize
|
||
; 6/14/86 EHB Call GetXRtn to set expand routine for SeekMask Changed
|
||
; SRCBITS/DSTBITS to SRCPIX/DSTPIX
|
||
; 6/13/86 EHB Moved SeekMask to another file Rearranged stack frame with
|
||
; SeekMask stuff at top
|
||
; 6/11/86 EHB Modified Stretch to use longwords and 020 instructions Made sure
|
||
; that stack buffers all longword aligned
|
||
; 6/5/86 EHB Masked off flag bits in all references to rowBytes
|
||
;
|
||
; To Do:
|
||
;
|
||
BLANKS ON
|
||
STRING ASIS
|
||
|
||
MACHINE MC68020
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; --> STRETCH.TEXT
|
||
;
|
||
; TO DO: TWO IDENTICAL EXPAND ROUTINES IS TOO MUCH!!!
|
||
;
|
||
;------------------------------------------------------------------
|
||
;
|
||
; MODIFICATIONS
|
||
;
|
||
; 5Jun86 EHB Masked off flag bits in all references to rowBytes
|
||
; 11Jun86 EHB Modified Stretch to use longwords and 020 instructions
|
||
; Made sure that stack buffers all longword aligned
|
||
; 13Jun86 EHB Moved SeekMask to another file
|
||
; Rearranged stack frame with SeekMask stuff at top
|
||
; 14Jun86 EHB Call GetXRtn to set expand routine for SeekMask
|
||
; Changed SRCBITS/DSTBITS to SRCPIX/DSTPIX
|
||
; 15Jun86 EHB Convert BitsToPix, and use pixelSize
|
||
; 16Jun86 EHB Added routine GetSizeShift to avoid multiplies
|
||
; 18Jun86 EHB Take depth into account for scaling
|
||
; 18Jun86 EHB Added a pattern param so it can be called instead of RgnBlt
|
||
; 19Jun86 EHB Use longs in horiz calculations for big pixels
|
||
; 20Jun86 EHB New params to COLORMAP
|
||
; Added FCOLOR and BCOLOR to stack frame
|
||
; 21Jun86 EHB Do expansion in 2 passes: 32 for data, next for chunks
|
||
; 23Jun86 EHB Rearranged for shared stack frame between stretch, rgnblt, bitblt
|
||
; Set up all common fields before calls to rgnblt
|
||
; Removed all parameters passed to rgnblt (only called from here)
|
||
; 24Jun86 EHB Big re-org: Create one stack frame shared by stretch, rgnblt, bitblt
|
||
; Set up all shared locals here, then call rgnblt, bitblt with parms
|
||
; in stack frame and registers (since stretchbits called from everywhere).
|
||
; 5Jul86 EHB Replaced SeekMask and GetXRtn with GetSeek
|
||
; 7Jul86 EHB Revised use of color in blt routines.
|
||
; 22Jul86 EHB Pass MODE to PatExpand for colorizing
|
||
; 26Jul86 EHB Added support for expanded patterns
|
||
; 29Jul86 EHB Allocate EXPAT buffer on stack so long aligned
|
||
; 8Sep86 EHB Added full-ratio color scaling (N-bit to N-bit)
|
||
; 11Sep86 EHB Added depth translation (N-bit to M-bit)
|
||
; 9Oct86 EHB Added mask parameters to stretchbits calls
|
||
; 12Dec86 CRC Added arithmetic modes
|
||
; 3Jan87 CRC expect color param in stretch
|
||
; 3Feb87 EHB Added error checking
|
||
;
|
||
;________________________________ Post Mac II _____________________________________
|
||
;
|
||
; 08Nov87 BAL Forced stretch to only do color table pixel translation if
|
||
; absolutely necessary. <C947>
|
||
; 08Nov87 BAL Forced stretch to TrimRect(clipRgn,MinRect) before submitting to rgnBlt. <C951>
|
||
; 08Nov87 BAL Fixed computation of bufSize for more accurate region clipping at
|
||
; at depths greater than 1. <C954>
|
||
; 07Dec87 BAL Changed <C947> to restore D7 (invertFlag) before returning to rgn/bitBlt. <C983>
|
||
; 09Apr88 BAL altered to use 32bit addressing during blit to screens
|
||
; 03May88 BAL fixed 2 scaling bugs where word-sized operations overflowed
|
||
; 04May88 BAL fixed bug in n*8x scaling (n=3,5,6,7...)
|
||
; 09May88 BAL Altered depth scaling code to use long sized pixel translation table.
|
||
; 17Jun88 BAL Added routines to depth scale from direct to indexed devices.
|
||
; 27Jun88 BAL Changed pattern expansion routines for 16 and 32 bits to optimize for solid.
|
||
; 28Jun88 BAL Added special scaling routine for B/W 1 bit to direct RGB in a 32 bit pixel.
|
||
; 29Aug88 BAL Changed 32 to 8-1bit dither to carry 2-D error.
|
||
; 04Sep88 BAL Added area averaging for shrinking of 32 bit pixmaps.
|
||
; 18Sep88 BAL Altered to get CRSRFLAG value from _BitsToPix; Removed references to PIXSRC;
|
||
; 19Sep88 BAL Altered to use common stack frame file 'Drawing Vars.a'
|
||
; 22Sep88 BAL Moved initialization of region state records into GetSeek.
|
||
; 26Sep88 BAL Replace successfully TrimRect'ed rgns with wideopen to avoid multiple Trims.
|
||
;
|
||
;________________________________ Post Jackson Pollack _____________________________________
|
||
;
|
||
; 26May89 BAL Fixed bug in call to MakeITable if seed mismatch during direct to indexed copy.
|
||
|
||
;
|
||
; Output: A3 contains address of current scanline.
|
||
;
|
||
MACRO
|
||
_pmVersion
|
||
if 0 then
|
||
cmp.l maskaddr(a6),a3
|
||
bne.s @CheckSrc
|
||
add.l a5,a3 ;bump mask to next row
|
||
tst.w maskpix+pmVersion(a6)
|
||
bpl.s @DoLittle
|
||
move.l a0,-(sp)
|
||
move.l maskpix+baseaddr(a6),a0
|
||
jsr (a0)
|
||
move.l (sp)+,a0
|
||
move.l a3,maskaddr(a6)
|
||
bra.s @DoLittle
|
||
@CheckSrc
|
||
;must be src.
|
||
endif
|
||
add.l a5,a3 ;bump src to next row
|
||
if 0 then
|
||
tst.w srcpix+pmVersion(a6)
|
||
bpl.s @DoLittle
|
||
move.l a0,-(sp)
|
||
move.l srcpix+baseaddr(a6),a0
|
||
jsr (a0)
|
||
move.l (sp)+,a0
|
||
@DoLittle
|
||
endif
|
||
ENDM
|
||
|
||
;
|
||
; The first time bruce is called, D3 contains the starting scan line number
|
||
; On output: A3 contains first scanline address
|
||
;
|
||
MACRO
|
||
_pmVersionSrcFirstTime
|
||
if 0 then
|
||
tst.w srcpix+pmVersion(a6)
|
||
bpl.s @NoSrcPmVersion
|
||
move.l a0,-(sp)
|
||
move.l srcpix+baseaddr(a6),a0
|
||
jsr (a0)
|
||
move.l (sp)+,a0
|
||
@NoSrcPmVersion
|
||
endif
|
||
ENDM
|
||
|
||
MACRO
|
||
_pmVersionMaskFirstTime
|
||
if 0 then
|
||
tst.l maskbits(a6) ;is there a mask?
|
||
bne.s @DoIt
|
||
moveq #0,a3 ;init MaskAddr to zero <KON 19FEB91>
|
||
bra.s @WriteIt
|
||
@DoIt
|
||
tst.w maskpix+pmVersion(a6)
|
||
bpl.s @DoLittle
|
||
move.l a0,-(sp)
|
||
move.l srcpix+baseaddr(a6),a0
|
||
jsr (a0)
|
||
move.l (sp)+,a0
|
||
@WriteIt
|
||
move.l a3,maskaddr(a6) ;a3 is returned by the routine
|
||
@DoLittle
|
||
endif
|
||
ENDM
|
||
|
||
StretchBits PROC EXPORT
|
||
IMPORT Scale32toIndexed, Scale16toIndexed, ScaleIndexedToIndexed, Scale32ToBitMap
|
||
IMPORT Scale32toGray, Scale16toGray, Scale32to16, Scale16to32, Scale16ToBitMap
|
||
IMPORT Search32toIndexed, Search16toIndexed, Search32to16, Search16to32
|
||
IMPORT Dither32toIndexed, Dither16toIndexed, Dither32toGray, Dither16toGray
|
||
IMPORT CB8to8Clip, CB8to1Clip, CB1to8Clip, Dither32toBitmap, Dither16toBitmap
|
||
IMPORT scaleBlt, Search32to32, Search16to16
|
||
IMPORT SHFTTBL
|
||
EXPORT stMASK0, stMASK1, stMASK2, stMASK3, stAvg, stAddPin, stAddOver
|
||
EXPORT stSubPin, stTransparent, stMax, stSubOver, stMin, stHilite
|
||
EXPORT Table2,TABLE4,TABLE8, setUpStretch, stNoStack
|
||
EXPORT stArith16Tab,stArith32Tab,stColorTab,stGrayTab,stSearchTab
|
||
EXPORT EXTBL,PATEXTBL,DoneStretch,OneBitProc,BlitCase,stScanLoop
|
||
EXPORT NOPfgColorTable
|
||
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
;--------------------------------------------------------------
|
||
;
|
||
; PROCEDURE StretchBits(srcBits,maskBits,dstBits: BitMap;
|
||
; srcRect,maskRect,dstRect: Rect;
|
||
; mode: INTEGER; pat: Pattern;
|
||
; rgnA,rgnB,rgnC: RgnHandle);
|
||
;
|
||
; Transfer a rectangle of bits from srcBits to dstBits,
|
||
; stretching or compressing according to srcRect and dstRect.
|
||
; The transfer is clipped to the intersection of rgnA, rgnB, and rgnC.
|
||
; It is also clipped to the specified mask. If MaskBits is NIL, then
|
||
; no masking is done.
|
||
;
|
||
; Restrictions:
|
||
;
|
||
; if numer <> denom, then src and dst bitmaps do not overlap.
|
||
;
|
||
;
|
||
; COPYRIGHT APPLE COMPUTER INC.
|
||
; DESIGNED AND WRITTEN BY BILL ATKINSON
|
||
;
|
||
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
||
;
|
||
PARAMSIZE EQU 44 ;SIZE OF PARAMETERS
|
||
SRCBITS EQU PARAMSIZE+8-4 ;LONG, ADDR OF BITMAP
|
||
MASKBITS EQU SRCBITS-4 ;LONG, ADDR OF BITMAP
|
||
DSTBITS EQU MASKBITS-4 ;LONG, ADDR OF BITMAP
|
||
SRCRECT EQU DSTBITS-4 ;LONG, ADDR OF RECT
|
||
MASKRECT EQU SRCRECT-4 ;LONG, ADDR OF RECT
|
||
DSTRECT EQU MASKRECT-4 ;LONG, ADDR OF RECT
|
||
MODE EQU DSTRECT-2 ;WORD
|
||
PAT EQU MODE-4 ;LONG, ADDR OF PATTERN
|
||
RGNA EQU PAT-4 ;LONG, RGNHANDLE
|
||
RGNB EQU RGNA-4 ;LONG, RGNHANDLE
|
||
RGNC EQU RGNB-4 ;LONG, RGNHANDLE
|
||
multColor EQU RGNC-2 ;byte, set if source contains nonblack/white colors
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
IF (&TYPE('useColorICON') = 'UNDEFINED') THEN
|
||
useColorICON EQU 0
|
||
ENDIF
|
||
|
||
|
||
;----------------------------------------------------
|
||
|
||
LINK A6,#VARSIZE ;ALLOCATE LOCAL VARIABLES
|
||
MOVEM.L D0-D7/A1-A5,-(SP) ;SAVE REGS
|
||
MOVE.L SP,SAVESTK(A6) ;REMEMBER STACK FOR LATER
|
||
move.l stklowPt,saveStkLowPt(a6) ;keep track of the sniffer <57>
|
||
;
|
||
; Copy rectangles to stack since they might be part of a handle and could move.
|
||
; Some people don't know that CopyBits moves memory... just call me SlowDraw.
|
||
; <KON 7NOV90>
|
||
;
|
||
move.l srcrect(a6),a0
|
||
lea newSrcRect(a6),a1
|
||
move.l a1,srcrect(a6)
|
||
move.l (a0)+,(a1)+
|
||
move.l (a0)+,(a1)+
|
||
|
||
move.l maskrect(a6),a0
|
||
lea newMaskRect(a6),a1
|
||
move.l a1,maskrect(a6)
|
||
move.l (a0)+,(a1)+
|
||
move.l (a0)+,(a1)+
|
||
|
||
move.l dstrect(a6),a0
|
||
lea newDstRect(a6),a1
|
||
move.l a1,dstrect(a6)
|
||
move.l (a0)+,(a1)+
|
||
move.l (a0)+,(a1)+
|
||
|
||
MOVE.W MODE(A6),D1 ;get mode <42>
|
||
BTST #3,D1 ;pattern mode? <42>
|
||
BNE.S @0 ;yes, alpha already stripped <42>
|
||
_GetStreamMode ;get alpha mode bits <42>
|
||
MOVE.W D1,MODE(A6) ;save stripped mode <42>
|
||
@0: MOVE.L A5,SAVEA5(A6) ;REMEMBER GLOBAL POINTER
|
||
move.b mmu32Bit,MMUSave(a6) ;save mmu mode for cheap exit
|
||
CLR.L DSTMASKBUF(A6) ;ASSUME NO MASK
|
||
CLR.L stackHandle(A6) ;init alternate stack not used
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; MAKE SURE THE STACK IS ON A LONGWORD BOUNDARY (FOR FAST BUFFERS)
|
||
;
|
||
MOVE.L SP,D1 ;GET THE STACK POINTER
|
||
AND.B #$FC,D1 ;FORCE LONG ALIGNMENT
|
||
MOVE.L D1,SP ;USE IT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; CONVERT SRCBITS AND DSTBITS TO PIXMAPS
|
||
; (A5 must contain global ptr)
|
||
;
|
||
; BITSTOPIX TAKES DEFAULT DEVICE FROM THEGDEVICE
|
||
|
||
MOVE.L THEGDEVICE,-(SP) ;SAVE THEGDEVICE
|
||
MOVE.L SRCDEVICE,THEGDEVICE ;SET UP SRC DEVICE
|
||
MOVE.L SRCBITS(A6),A1 ;GET POINTER TO SRCBITS
|
||
|
||
|
||
IF useColorICON THEN
|
||
|
||
;----------------------------------------------------
|
||
; SLIMEY HACK to draw Jackson Pollack Icon in Full Color:
|
||
;
|
||
move.l baseAddr(a1),d0 ;get baseAddr
|
||
_rTranslate24To32 ;clean up the address
|
||
clr.w filler2(a6) ;set myIcon flag false
|
||
tst.l d0 ;is it in slot space?
|
||
bmi.s @1 ;yes, skip chk
|
||
move.l d0,a0 ;to prevent Bus Errors
|
||
; cmp.l #$EBF557E2,108(a0) ;check for race car signature
|
||
; cmp.l #$cc45c929,108(a0) ;check for painting signature
|
||
lea 80(a0),a0 ;point into data
|
||
cmp.l #$842ba003,(a0)+ ;check for prism signature
|
||
bne.s @1
|
||
cmp.l #$8445d455,(a0)+ ;check for prism signature
|
||
bne.s @1
|
||
cmp.l #$8882e803,(a0)+ ;check for prism signature
|
||
bne.s @1
|
||
cmp.l #$89017855,(a0) ;check for prism signature
|
||
bne.s @1
|
||
|
||
move.l jpCicn,a1 ; get cicn handle
|
||
move.l (a1),a1 ; point at pixmap
|
||
move.l (sp),a0 ; get the dst gdevice handle
|
||
move.l (a0),a0 ; point to it
|
||
move.l gdPMap(a0),a0 ; get its pixmap handle
|
||
move.l (a0),a0 ; point to it
|
||
cmp.w #4,pixelsize(a0) ; check depth
|
||
bge.s @usePMap ; 4 bit or deeper-> use pixmap data
|
||
add #IconBMap,a1 ; else use bitmap data
|
||
sub #1,filler2(a6) ; using bitmap, don't hack colors
|
||
|
||
@usePMap
|
||
cmp.w #3,Mode(a6) ; BIC mode?
|
||
bne.s @2 ; no, draw the icon
|
||
bra done
|
||
|
||
|
||
@2 clr.w Mode(a6) ; use copy mode
|
||
add #1,filler2(a6) ; flag hack in progress
|
||
;
|
||
;----------------------------------------------------
|
||
|
||
ENDIF
|
||
|
||
|
||
@1 LEA SRCPIX(A6),A2 ;COPY INTO SRCPIX
|
||
_BitsToPix ;BITMAP -> PIXMAP
|
||
|
||
MOVE.L (SP)+,THEGDEVICE ;RESTORE THEGDEVICE AS DST DEVICE
|
||
MOVE.L DSTBITS(A6),A1 ;GET POINTER TO DSTBITS
|
||
LEA DSTPIX(A6),A2 ;COPY INTO DSTPIX
|
||
_BitsToPix ;BITMAP -> PIXMAP
|
||
MOVE.L D1,REALBOUNDS(A6) ;SAVE REAL DST BOUNDS.TOPLEFT
|
||
MOVE.B D2,CRSRFLAG(A6) ;REMEMBER IF DST IS SCREEN <BAL 18Sep88>
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; GET SHIFT AMOUNTS FOR SRC (D3) AND DST (D4) DEPTHS
|
||
; THE PIXSRC FLAG IS SET IF SRC IS A PIXMAP THAT ISN'T ONE BIT PER PIXEL
|
||
;
|
||
LEA SHFTTBL,A0 ;POINT TO SHIFT TABLE
|
||
MOVE SRCPIX+PIXELSIZE(A6),D0 ;GET SRC PIXEL SIZE
|
||
MOVEQ #0,D3 ;DEFAULT SHIFT = 0
|
||
MOVE.B 0(A0,D0),D3 ;GET SRC SHIFT
|
||
MOVE D3,SRCSHIFT(A6) ;AND SAVE SRC SHIFT AMOUNT
|
||
|
||
MOVE DSTPIX+PIXELSIZE(A6),D0 ;GET DST PIXEL SIZE
|
||
MOVEQ #0,D4 ;DEFAULT SHIFT = 0
|
||
MOVE.B 0(A0,D0),D4 ;GET DST SHIFT
|
||
MOVE D4,DSTSHIFT(A6) ;AND SAVE DST SHIFT AMOUNT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; CONVERT MASKBITS TO MASKPIX, AND GET SHIFT AMOUNT FOR MASK DEPTH
|
||
; If mask is direct, pass depth through. If mask is 2, 4, or 8 bit
|
||
; promote mask to 32 bit/pixel.
|
||
;
|
||
CLR MASKSHIFT(A6) ;ASSUME DEPTH = 1
|
||
MOVE.L MASKBITS(A6),D0 ;IS THERE A MASK?
|
||
BEQ.S NOMASK ;=>NO, SKIP MASK SETUP
|
||
|
||
MOVE.L D0,A1 ;GET POINTER TO MASKBITS
|
||
LEA MASKPIX(A6),A2 ;COPY INTO MASKPIX
|
||
_BitsToPix ;BITMAP -> PIXMAP
|
||
|
||
LEA SHFTTBL,A0 ;POINT TO SHIFT TABLE
|
||
MOVE MASKPIX+PIXELSIZE(A6),D0 ;GET MASK PIXEL SIZE
|
||
moveq #0,d5 ;default shift=0
|
||
move.b 0(a0,d0),d5
|
||
bne.s @PromoteIt ;mask is 1-bit/pixel
|
||
;
|
||
; should promote 1-bit masks unless it's copy mode
|
||
;
|
||
move.w MODE(A6),d0 ;COPY MODE and 1-bit deep?
|
||
and.w #$37,d0 ;mask pattern and dither bits
|
||
beq.s NoMask ;yes, don't promote it
|
||
@PromoteIt
|
||
cmp.b #4,d5 ;if it's 16 bpp, save mask depth
|
||
beq.s @gotMaskDepth
|
||
move #5,d5 ;otherwise force it to 32 bits/pixel
|
||
@gotMaskDepth
|
||
move d5,maskshift(a6)
|
||
|
||
NOMASK
|
||
|
||
;-------------------------------------------------------------------
|
||
;
|
||
; CALC MINRECT = INTERSECTION OF DSTRECT, DSTBITS.BOUNDS, AND THREE
|
||
; REGION BOUNDING BOXES. QUIT IF THE INTERSECTION IS EMPTY.
|
||
;
|
||
MOVE.L DSTRECT(A6),-(SP) ;PUSH ADDR OF DSTRECT
|
||
PEA DSTPIX+BOUNDS(A6) ;PUSH ADDR OF DSTPIX.BOUNDS
|
||
MOVE.L RGNA(A6),A0 ;GET RGNHANDLE
|
||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||
PEA RGNBBOX(A0) ;PUSH RGN BBOX
|
||
MOVE.L RGNB(A6),A0 ;GET RGNHANDLE
|
||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||
PEA RGNBBOX(A0) ;PUSH RGN BBOX
|
||
MOVE.L RGNC(A6),A0 ;GET RGNHANDLE
|
||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||
PEA RGNBBOX(A0) ;PUSH RGN BBOX
|
||
MOVE #5,-(SP) ;PUSH NRECTS
|
||
PEA MINRECT(A6) ;PUSH WHERE TO PUT RESULT
|
||
_RSECT ;INTERSECT ALL RECTS
|
||
BEQ GOHOME ;QUIT IF RESULT IS EMPTY
|
||
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; SET UP NEWPATTERN TO INDICATE OLD OR NEW STYLE PATTERN
|
||
; ALSO SET UP LOCAL PATTERN POINTER, LOCPAT(A6)
|
||
;
|
||
MOVE.L PAT(A6),LOCPAT(A6) ;COPY PATTERN POINTER
|
||
MOVE MODE(A6),LOCMODE(A6) ;COPY MODE
|
||
TST ([DSTBITS,A6],ROWBYTES) ;IS THE DST OLD OR NEW?
|
||
SMI NEWPATTERN(A6) ;FLAG = TRUE IF NEW PATTERN
|
||
CLR PATROW(A6) ;FLAG NOT DOING BIG PATTERNS
|
||
|
||
bclr #6,LocMode+1(a6) ;clear dither bit <07Jul88 BAL>
|
||
sne useDither(a6) ;remember whether it was set <07Jul88 BAL>
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; ADJUST MODE AND PATTERN FOR COLOR SEPARATION.
|
||
; (A5 must contain global ptr)
|
||
;
|
||
btst #1,multColor+1(a6) ;check if src is a color font <05JUNE92 SAH>
|
||
sne multiColor(a6) ;set multiColor flag for ColorMap
|
||
_COLORMAP ;ALTER FOR COLOR SEPARATION
|
||
|
||
;---------------------------------------
|
||
;
|
||
; SET UP INVERT FLAG IN D7 TO REFLECT MODE BIT 2
|
||
; CHECK TO SEE IF PATTERN WILL BE USED
|
||
;
|
||
MOVE LOCMODE(A6),D2 ;GET TRANSFER MODE
|
||
|
||
IF useColorICON THEN
|
||
|
||
tst filler2(a6) ;cicn hack
|
||
beq.s @1
|
||
cmp #8,srcPix+pixelSize(a6) ;8-bit clut on icon?
|
||
bne.s @1
|
||
lea srcPix+pmtable(a6),a0 ;pnt to pmtable handle
|
||
move.l (a0),a0 ;get handle
|
||
move.l (a0),a0 ;pnt to table
|
||
pea ctTable+rgb+red(a0) ;push address of entry zero (white)
|
||
pea 255*8+ctTable+rgb+red(a0) ;push address of entry 255 (black)
|
||
_GetForeColor ;fill in entry 255
|
||
_GetBackColor ;fill in entry zero
|
||
MOVE LOCMODE(A6),D2 ;restore TRANSFER MODE
|
||
@1
|
||
ENDIF
|
||
|
||
|
||
;--------------------------------------------------------------
|
||
;
|
||
; Use table lookup to map input mode, src type, and dst type
|
||
; to a new mode, colorize location, swap fg/bk, use stretch (slow)
|
||
; and whether or not to invert.
|
||
;
|
||
; Index value is five bits: SRCTYPE DSTTYPE MODE (3 bits)
|
||
; For SRCTYPE and DSTTYPE 1 = direct, 0 = indexed
|
||
; MODE is bottom 3 bits of mode
|
||
;
|
||
; Lookup value is a byte: INVERT 0 STRETCH? SWAP FG/BG CLRXLATE NEWMODE
|
||
; For INVERT, 1 means invert in blit loop, 0 means don't
|
||
; STRETCH, 1 means go through stretch, 0 means fast case ok
|
||
; SWAP FG/BG 1 means swap, 0 means don't
|
||
; CLRXLATE 1 means colorize in blit loop, 0 means translate in makescaletable
|
||
; NEWMODE 3 bits determine which blit loop to take
|
||
;
|
||
moveq #0,d0 ;default for patterns and arithmetic modes
|
||
|
||
btst #3,d2 ;is it a pattern mode?
|
||
bne DoPattern ;=>yes, don't remap mode
|
||
|
||
btst #5,d2 ;is it a arithmetic mode?
|
||
bne.s @useCopyMode ;yes, pretend copy mode
|
||
|
||
moveq #7,d0 ;prepare to get mode
|
||
and.w d2,d0 ;get mode in bottom 3 bits
|
||
@useCopyMode
|
||
cmp.w #4,d4 ;destination indexed?
|
||
blt.s @destind
|
||
bset #3,d0 ;set dest direct bit
|
||
|
||
@destind
|
||
cmp.w #4,d3 ;src indexed?
|
||
blt.s @srcind
|
||
bset #4,d0 ;set dest direct bit
|
||
@srcind
|
||
lea MapModeTable,a0
|
||
move.w (a0,d0*2),d0 ;get table lookup value
|
||
bra.s skipTable ;temporary, move table later
|
||
|
||
ScaleColorBit EQU 3
|
||
SwapFGBGBit EQU 4
|
||
UseStretchBit EQU 5
|
||
InvertItBit EQU 7
|
||
ColorizeInModeCaseBit EQU 8
|
||
ColorizeInSrcBufBit EQU 9
|
||
|
||
InvertIt EQU 1 << InvertItBit
|
||
UseStretch EQU 1 << UseStretchBit
|
||
SwapFGBG EQU 1 << SwapFGBGBit
|
||
ScaleColor EQU 1 << ScaleColorBit ;colorize in make scale table
|
||
ColorizeInModeCase EQU 1 << ColorizeInModeCaseBit
|
||
ColorizeInSrcBuf EQU 1 << ColorizeInSrcBufBit
|
||
|
||
; from QDciPatchROM.a verbatim (with the exception of CubeE stuff put back in this file) <sm 6/9/92>stb
|
||
MapModeTable
|
||
;
|
||
; indexed src, indexed dst
|
||
;
|
||
dc.w ScaleColor + srcCopy ;
|
||
dc.w ColorizeInModeCase + srcOr ;
|
||
dc.w ColorizeInModeCase + srcXor ;
|
||
dc.w ColorizeInModeCase + srcBic ;
|
||
dc.w UseStretch + SwapFGBG + ScaleColor + SrcCopy
|
||
dc.w InvertIt + ColorizeInModeCase + notSrcOr ;
|
||
dc.w InvertIt + ColorizeInModeCase + notSrcXor ;
|
||
dc.w InvertIt + ColorizeInModeCase + notSrcBic ;
|
||
|
||
;
|
||
; indexed src, direct dst
|
||
;
|
||
dc.w ScaleColor + srcCopy ;+ UseStretch + <05JUNE92 SAH>
|
||
dc.w InvertIt + UseStretch + notSrcBic + SwapFGBG + ColorizeInModeCase
|
||
dc.w InvertIt + UseStretch + notSrcXor + SwapFGBG + ColorizeInModeCase
|
||
dc.w InvertIt + UseStretch + notSrcOr + SwapFGBG + ColorizeInModeCase
|
||
dc.w SwapFGBG + ScaleColor + SrcCopy ; UseStretch + <05JUNE92 SAH>
|
||
dc.w UseStretch + ColorizeInModeCase + srcBic + SwapFGBG
|
||
dc.w UseStretch + ColorizeInModeCase + srcXor + SwapFGBG
|
||
dc.w UseStretch + ColorizeInModeCase + srcOr + SwapFGBG
|
||
;
|
||
; direct src, indexed dst
|
||
;
|
||
dc.w ColorizeInSrcBuf + srcCopy ;
|
||
dc.w ColorizeInModeCase + srcOr ;
|
||
dc.w ColorizeInModeCase + srcXor ;
|
||
dc.w ColorizeInModeCase + srcBic ;
|
||
dc.w ColorizeInSrcBuf + SwapFGBG + srcCopy
|
||
dc.w ColorizeInModeCase + InvertIt + notSrcOr ;
|
||
dc.w ColorizeInModeCase + InvertIt + notSrcXor ;
|
||
dc.w ColorizeInModeCase + InvertIt + notSrcBic ;
|
||
;
|
||
; direct src, direct dst
|
||
;
|
||
dc.w SwapFGBG + ColorizeInModeCase + srcCopy ;
|
||
dc.w SwapFGBG + InvertIt + ColorizeInModeCase + notSrcBic ;
|
||
dc.w SwapFGBG + InvertIt + ColorizeInModeCase + notSrcXor ;
|
||
dc.w SwapFGBG + InvertIt + ColorizeInModeCase + notSrcOr ;
|
||
dc.w SwapFGBG + InvertIt + ColorizeInModeCase + SrcCopy
|
||
dc.w SwapFGBG + ColorizeInModeCase + SrcBic ;
|
||
dc.w SwapFGBG + ColorizeInModeCase + srcXor ;
|
||
dc.w SwapFGBG + ColorizeInModeCase + srcOr ;
|
||
|
||
NOPfgColorTable
|
||
dc.l $FFFFFFFF ;1-bit white
|
||
dc.l $FFFFFFFF ;2-bit white
|
||
dc.l $FFFFFFFF ;4-bit white
|
||
dc.l $FFFFFFFF ;8-bit white
|
||
dc.l $7FFF7FFF ;16-bit white
|
||
dc.l $00FFFFFF ;32-bit white
|
||
|
||
;
|
||
; This next section of code figures out how much work we're going to have to do.
|
||
; First we change the mode to that from the mapModeTable.
|
||
; Next, find the correct foreground and background colors
|
||
; Swap FG/BG colors
|
||
; Figure out if colorizing is a NOP
|
||
;
|
||
skipTable
|
||
|
||
;
|
||
; Reintroduced code from <54> for CubeE.
|
||
;
|
||
|
||
if CubeE then ; <56>
|
||
|
||
; <56>
|
||
; <56> d0 has table value, if pmVersion is negative, always use Stretch
|
||
; <56>
|
||
tst.w srcpix+pmVersion(a6) ; <56> if pmVersion negative, always use stretch
|
||
bmi.s @ForceStretch ; <56>
|
||
TST.L MASKBITS(A6) ; <56> IS THERE A MASK?
|
||
beq.s @DontForceStretch ; <56> Check if mask needs pmVersion
|
||
tst.w maskpix+pmVersion(a6) ; <56> if pmVersion negative, always use stretch
|
||
bpl.s @DontForceStretch ; <56>
|
||
@ForceStretch ; <56>
|
||
bset #useStretchBit,d0 ; <56>
|
||
@DontForceStretch ; <56>
|
||
|
||
endif ; <56>
|
||
|
||
|
||
btst #5,d2 ;is it a arithmetic mode?
|
||
beq.s @ChangeLocMode ;no, then remap mode
|
||
;
|
||
; arithmetic modes aren't colorized
|
||
;
|
||
and.w #~(ScaleColor+ColorizeInModeCase+ColorizeInSrcBuf),d0 ;clear colorize bits
|
||
bra.s @ChangeLocModeDone
|
||
@ChangeLocMode
|
||
and.b #$f8,d2 ;clear low three bits
|
||
moveq #3,d1
|
||
and.b d0,d1 ;get low bits of new mode
|
||
or.b d1,d2 ;merge with old mode
|
||
@ChangeLocModeDone
|
||
move.w d2,locMode(a6) ;store for modecase, BitBlt, RgnBlt
|
||
|
||
;
|
||
; if ScaleCase colorizing and src and dst bit depths are the same and source
|
||
; is black and white only (multColor bit 0) or is direct, change to ModeCase
|
||
; colorizing as an optimization. This allows us to take BitBlt. <05JUNE92 SAH>
|
||
;
|
||
btst.l #ScaleColorBit,d0 ;ScaleCase colorizing? <55>
|
||
beq.s @ScaleOptimizationDone ;Not scalecase, then branch <55>
|
||
cmp.w #4,d3 ;src direct? <05JUNE92 SAH>
|
||
bge.s @checkDepth
|
||
btst #0,multColor+1(a6) ;src Black/White only
|
||
beq.s @ScaleOptimizationDone ;no, can't do anything
|
||
@checkDepth
|
||
cmp.w d3,d4 ;src and dst same depth? <55>
|
||
bne.s @ScaleOptimizationDone ;no, branch and don't change to modecase <55>
|
||
eor.l #(ScaleColor+ColorizeInModeCase),d0 ;clear scale color; set modecase color <55>
|
||
|
||
@ScaleOptimizationDone
|
||
;
|
||
; Use stretch if a search proc is installed <2May90 KON>
|
||
;
|
||
move.l ([theGDevice]),A0 ; get a pointer to the device
|
||
tst.l GDSearchProc(A0) ; check the head of the search chain
|
||
beq @CheckSwapping ; no search proc: go on
|
||
bset.l #UseStretchBit,d0 ; force stretch
|
||
|
||
;
|
||
; if modecase colorizing, search proc is installed, and direct use unmapped fg and bg colors
|
||
;
|
||
cmp.w #4,d4 ; destination direct?
|
||
blt @CheckSwapping ; nope.
|
||
btst.l #ColorizeInModeCaseBit,d0
|
||
beq @CheckSwapping ; not modecase: go on
|
||
|
||
;
|
||
; This code reintroduced from version 54 for CubeE.
|
||
;
|
||
|
||
if CubeE then ; <56>
|
||
move.l ([theGDevice]),a0 ; <56> get a pointer to the device
|
||
tst.l GDSearchProc(A0) ; <56> check the head of the search chain
|
||
beq @CheckSwapping ; <56> no search proc: go on
|
||
endif ; <56>
|
||
|
||
;
|
||
; fcolor and bcolor were mapped using search proc by colormap. We want to use
|
||
; the unmapped versions.
|
||
;
|
||
PEA RGBFrColor(a6) ;get fg color for colorizing
|
||
PEA RGBBgColor(a6)
|
||
|
||
move.w d0,XLateFlag(a6) ;save translation flags <KON 5MAR91>
|
||
_GetBackColor ;get bg color for colorizing
|
||
_GetForeColor
|
||
move.w XLateFlag(a6),d0 ;restore translation flags <KON 5MAR91>
|
||
|
||
cmp.w #4,d4 ; 16-Bit?
|
||
beq.s @Do16Bit ;
|
||
;
|
||
; Convert RGB colors to 32-bit colors for foreground
|
||
;
|
||
moveq #0,d1
|
||
move.b RGBFrColor(a6),d1 ;red
|
||
swap d1
|
||
move.b RGBFrColor+2(a6),d1 ;green
|
||
lsl #8,d1
|
||
move.b RGBFrColor+4(a6),d1 ;blue
|
||
move.l d1,fcolor(a6)
|
||
|
||
moveq #0,d1 ;do background
|
||
move.b RGBBgColor(a6),d1 ;red
|
||
swap d1
|
||
move.b RGBBgColor+2(a6),d1 ;green
|
||
lsl #8,d1
|
||
move.b RGBBgColor+4(a6),d1 ;blue
|
||
move.l d1,bcolor(a6)
|
||
bra.s @CheckSwapping
|
||
@Do16Bit
|
||
;
|
||
; Convert RGB colors to 32-bit colors for background
|
||
;
|
||
moveq #0,d1
|
||
move.b RGBFrColor(a6),d1 ;red
|
||
lsl #5,d1 ; rrrrrrrr00000
|
||
move.b RGBFrColor+2(a6),d1 ;green rrrrrgggggggg
|
||
lsl.l #5,d1 ; rrrrrgggggggg00000 <KON 5MAR91>
|
||
move.b RGBFrColor+4(a6),d1 ;blue rrrrrgggggbbbbbbbb
|
||
lsr.l #3,d1 ; 000rrrrrgggggbbbbb <KON 5MAR91>
|
||
move.w d1,fcolor(a6)
|
||
move.w d1,fcolor+2(a6)
|
||
|
||
moveq #0,d1
|
||
move.b RGBBgColor(a6),d1 ;red
|
||
lsl #5,d1
|
||
move.b RGBBgColor+2(a6),d1 ;green
|
||
lsl.l #5,d1 ; <KON 5MAR91>
|
||
move.b RGBBgColor+4(a6),d1 ;blue
|
||
lsr.l #3,d1 ; <KON 5MAR91>
|
||
move.w d1,bcolor(a6)
|
||
move.w d1,bcolor+2(a6)
|
||
|
||
@CheckSwapping
|
||
|
||
btst.l #SwapFGBGBit,d0 ;swap fg/bg colors?
|
||
beq.s swapdone
|
||
swapfgbk
|
||
move.l fcolor(a6),d1 ;swap fg/bk color
|
||
move.l bcolor(a6),fcolor(a6)
|
||
move.l d1,bcolor(a6)
|
||
swapdone
|
||
|
||
|
||
;------------------------------------------------------------------------------
|
||
; Check if colorizing is a NOP. If it is, clear the colorize bits.
|
||
; There are three cases: ModeCase, ScaleCase, and SrcBuf colorizing
|
||
;
|
||
; SrcBuf and ScaleCase colorizing is a NOP IF
|
||
;
|
||
; for 1-bit sources:
|
||
; fcolor = $FFFFFFFF and bcolor = 0
|
||
;
|
||
; for deep sources:
|
||
; RGBFrColor = 0 and RGBBgColor = $00FFFFFF (32-bit)
|
||
; or RGBBgColor = $7FFF7FFF (16-bit)
|
||
;
|
||
; ModeCase colorizing is NOP if bcolor=0 and fcolor=NOPfgColorTable
|
||
;
|
||
; If ModeCase or ScaleCase colorizing, check for NOP
|
||
;
|
||
btst.l #ColorizeInModeCaseBit,d0
|
||
beq @CheckColorizeInSrcBuf ;branch if SrcBuf or ScaleCase colorizing
|
||
;
|
||
; Do ModeCase NOP check
|
||
;
|
||
move.l bcolor(a6),d1 ;is bg color a NOP ($00000000)?
|
||
bne @CheckColorizeNOPDone ;bk not a NOP, go slow
|
||
move.l fcolor(a6),d1 ;is fg color a NOP?
|
||
lea NOPfgColorTable,a0
|
||
cmp.l (a0,d4*4),d1
|
||
bne @CheckColorizeNOPDone ;no, it's not a NOP
|
||
;
|
||
; It's a NOP, clear colorize bits
|
||
;
|
||
and.w #~(ColorizeInModeCase),d0 ;turn off modecase colorizing
|
||
bra @CheckColorizeNOPDone
|
||
|
||
@CheckColorizeInSrcBuf
|
||
;
|
||
; Check SrcBuf or ScaleCase colorizing
|
||
;
|
||
; if src is indexed and destination indexed:
|
||
; NOP if fcolor = $FFFFFFFF and bcolor = 0
|
||
; if src is indexed and destination is direct:
|
||
; NOP if fcolor = 0 and bcolor = $00FFFFFF (32-bit)
|
||
; bcolor = $7FFF7FFF (16-bit)
|
||
;
|
||
; Get fg and bg color in RGB space if colorizing at srcbuf, since our source is
|
||
; still in RGB space at that time.
|
||
;
|
||
; D3 contains src pixel depth.
|
||
; D4 contains dst pixel depth.
|
||
;
|
||
cmp.w #4,d3 ;deep src?
|
||
bge.s @DeepSrc
|
||
cmp.w #4,d4 ;dst indexed?
|
||
bge.s @DoDirectNOPCheck
|
||
tst.l bcolor(a6) ;bcolor a NOP?
|
||
bne @CheckColorizeNOPDone
|
||
move.l fcolor(a6),d1 ;fcolor a NOP?
|
||
addq.l #1,d1
|
||
bne @CheckColorizeNOPDone
|
||
bra.s @ClearColorizeBits ;it's a NOP, clear the colorize bits
|
||
@DoDirectNOPCheck
|
||
tst.l fcolor(a6)
|
||
bne @CheckColorizeNOPDone ;fcolor not a NOP for direct device
|
||
move.l bcolor(a6),d1 ;is fg color a NOP?
|
||
lea NOPfgColorTable,a0
|
||
cmp.l (a0,d4*4),d1
|
||
bne @CheckColorizeNOPDone
|
||
bra.s @ClearColorizeBits ;it's a NOP, clear the colorize bits
|
||
@DeepSrc
|
||
|
||
;
|
||
; if swapfgbgBit is set, we need to swap RGB fg/bg color
|
||
;
|
||
move.w d0,XLateFlag(a6) ;save translation flags
|
||
btst #swapfgbgBit,XLateFlag+1(a6) ;rgb invert?
|
||
beq.s @DontSwap ;don't invert
|
||
|
||
PEA RGBBgColor(a6)
|
||
PEA RGBFrColor(a6) ;get fg color for colorizing
|
||
bra.s @SwapDone
|
||
@DontSwap
|
||
PEA RGBFrColor(a6) ;get fg color for colorizing
|
||
PEA RGBBgColor(a6)
|
||
@SwapDone
|
||
_GetBackColor ;get bg color for colorizing
|
||
_GetForeColor
|
||
;
|
||
; convert 16-16-16 to 8-8-8 for 32-bit src (D3=5)
|
||
;
|
||
cmp.w #4,d3 ;16-bit src?
|
||
beq.s @ConvertTo555 ;yes, convert to 555
|
||
|
||
move.l RGBBgColor(a6),d0 ;get RRRRGGGG
|
||
lsr.l #8,d0 ;get 00RRRRGG
|
||
lsl.w #8,d0 ;put green where it belongs, now 00RRGG00
|
||
move.b RGBBgColor+4(a6),d0 ;get blue: 00RRGGBB
|
||
move.l d0,RGBBgColor(a6)
|
||
|
||
move.l RGBFrColor(a6),d0 ;get RRRRGGGG
|
||
lsr.l #8,d0 ;get 00RRRRGG
|
||
lsl.w #8,d0 ;put green where it belongs, now 00RRGG00
|
||
move.b RGBFrColor+4(a6),d0 ;get blue: 00RRGGBB
|
||
move.l d0,RGBFrColor(a6)
|
||
|
||
move.w XLateFlag(a6),d0 ;get translation flags
|
||
;
|
||
; if RGBFrColor and RGBBgColor are white and black, colorizing is a nop so clear
|
||
; ColorizeInSrcBufBit. This is backwards from normal since it is a direct device.
|
||
;
|
||
tst.l RGBFrColor(a6) ;is Fr color black, ie a NOP for colorizing?
|
||
bne.s @CheckColorizeNOPDone ;no, colorizing is not a nop
|
||
cmp.l #$00FFFFFF,RGBBgColor(a6) ;is bg color white ($00FFFFFF) (a NOP)
|
||
bne.s @CheckColorizeNOPDone
|
||
|
||
@ClearColorizeBits
|
||
and.w #~(ColorizeInSrcBuf+ScaleColor),d0 ;turn off SrcBuf and scale case colorizing
|
||
bra.s @CheckColorizeNOPDone
|
||
|
||
;
|
||
; convert 16-16-16 to 5-5-5 for 16-bit src (D3=4)
|
||
;
|
||
@ConvertTo555
|
||
moveq #0,d0 ;clear alpha
|
||
move.w RGBBgColor(a6),d0 ;get RRRR
|
||
lsl.l #5,d0 ;put correct red in high word
|
||
move.w RGBBgColor+2(a6),d0 ;get GGGG
|
||
lsl.l #5,d0 ;put correct green in high word
|
||
move.w RGBBgColor+4(a6),d0 ;get BBBB
|
||
lsl.l #5,d0 ;put correct blue in high word
|
||
swap d0
|
||
move.w d0,RGBBgColor(a6)
|
||
move.w d0,RGBBgColor+2(a6)
|
||
|
||
moveq #0,d0 ;clear alpha
|
||
move.w RGBFrColor(a6),d0 ;get RRRR
|
||
lsl.l #5,d0 ;put correct red in high word
|
||
move.w RGBFrColor+2(a6),d0 ;get GGGG
|
||
lsl.l #5,d0 ;put correct green in high word
|
||
move.w RGBFrColor+4(a6),d0 ;get BBBB
|
||
lsl.l #5,d0 ;put correct blue in high word
|
||
swap d0
|
||
move.w d0,RGBFrColor(a6)
|
||
move.w d0,RGBFrColor+2(a6)
|
||
|
||
;
|
||
; if RGBFrColor and RGBBgColor are white and black, colorizing is a nop so clear
|
||
; ColorizeInSrcBufBit. This is backwards from normal since it is a direct device.
|
||
;
|
||
move.w XLateFlag(a6),d0 ;save translation flags
|
||
tst.l RGBFrColor(a6) ;is Fg color black, ie a NOP for colorizing?
|
||
bne.s @CheckColorizeNOPDone ;no, colorizing is not a nop
|
||
cmp.l #$7FFF7FFF,RGBBgColor(a6) ;is bg color white ($00FFFFFF) (a NOP)
|
||
|
||
if CubeE or TheFuture then ; appease the assembler gods <62>
|
||
bne.s @CheckColorizeNOPDone
|
||
endif ; <62>
|
||
|
||
and.w #~(ColorizeInSrcBuf+ScaleColor),d0 ;turn off SrcBuf and scale case colorizing
|
||
|
||
@CheckColorizeNOPDone
|
||
move.w d0,XLateFlag(a6) ;save translation flags
|
||
btst #InvertItBit,XLateFlag+1(a6) ;TEST INVERT BIT
|
||
SNE D7 ;set byte flag in d7
|
||
EXTB.L D7 ;INVERTED; D7 GETS ALL 1'S
|
||
LEA NOPfgColorTable,A0 ;get address of white table <42>
|
||
AND.L 0(A0,D4.W*4),D7 ;remove alpha byte/bit from mask <42>
|
||
MOVE.L D7,INVERTFLAG(A6) ;SAVE INVERT FLAG
|
||
BRA.S NOTPAT ;=>NO, USE SOURCE INSTEAD
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; PATTERN WILL BE USED. EXPAND PATTERN TO THE CURRENT DEPTH.
|
||
;
|
||
DoPattern
|
||
MOVEQ #0,D7 ;if mode is arithmetic, use 0 for <SMC 18SEP90>
|
||
BTST #5,D2 ; the ivert flag and skip bit 2 clear <SMC 18SEP90>
|
||
BNE.S @notnot ; <SMC 18SEP90>
|
||
BCLR #2,D2 ;TEST AND CLR INVERT BIT
|
||
SNE D7 ;set byte flag in d7
|
||
EXTB.L D7 ;INVERTED; D7 GETS ALL 1'S
|
||
@notnot MOVE.L D7,INVERTFLAG(A6) ;SAVE INVERT FLAG <SMC 18SEP90>
|
||
; move.w d2,locMode(a6) ;store for modecase, BitBlt, RgnBlt
|
||
|
||
_PATEXPAND ;EXPAND PATTERN
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; HIDE THE CURSOR IF TO THE SCREEN AND INTERSECTS MINRECT
|
||
; (A5 must contain global ptr)
|
||
;
|
||
NOTPAT
|
||
TST.B CRSRFLAG(A6) ;IS DST TO A SCREEN? <BAL 19Sep88>
|
||
BEQ.S NOTSCREEN ;=>NO
|
||
PEA MINRECT(A6) ;PUSH SHIELD RECT
|
||
MOVE.L REALBOUNDS(A6),-(SP) ;PUSH DELTA FOR GLOBAL
|
||
_SHIELDCURSOR ;REMOVE CURSOR IF INTERSECT
|
||
|
||
NOTSCREEN
|
||
;----------------------------------------------------------------
|
||
;
|
||
; SET UP SRC ROWBYTES, MASK ROWBYTES, AND DST ROWBYTES
|
||
; GET SRCPIX INTO A4 AND DSTPIX INTO A5
|
||
; GET SRCRECT INTO A2 AND DSTRECT INTO A3
|
||
;
|
||
LEA SRCPIX(A6),A4 ;POINT TO SRCPIX
|
||
MOVE #nuRBMask,D0 ;GET MASK FOR ROWBYTE FLAGS
|
||
EXT.L D0 ;MAKE IT LONG
|
||
MOVE ROWBYTES(A4),D1 ;GET SRC ROWBYTES
|
||
AND.L D0,D1 ;CLEAR OUT FLAG BITS
|
||
MOVE.L D1,SRCROW(A6) ;SRCROW := SRC ROWBYTES
|
||
|
||
@1 LEA MASKPIX(A6),A0 ;POINT TO MASKPIX
|
||
MOVE ROWBYTES(A0),D1 ;GET DST ROWBYTES
|
||
AND.L D0,D1 ;CLEAR OUT FLAG BITS
|
||
MOVE.L D1,MASKROW(A6) ;MASKROW := MASK ROWBYTES
|
||
|
||
LEA DSTPIX(A6),A5 ;POINT TO DSTPIX
|
||
MOVE ROWBYTES(A5),D1 ;GET DST ROWBYTES
|
||
AND.L D0,D1 ;CLEAR OUT FLAG BITS
|
||
MOVE.L D1,DSTROW(A6) ;DSTROW := DST ROWBYTES
|
||
|
||
MOVE.L srcRect(a6),a2 ;get srcRect 24 bit ptr @@@@ BAL 12Jan89
|
||
MOVE.L a2,d0 ;get srcRect ptr @@@@ BAL 09Apr88
|
||
_rTranslate24To32
|
||
move.l d0,srcRect(a6) ;save 32 bit ptr @@@@ BAL 07Jul88
|
||
MOVE.L dstRect(a6),a3 ;get dstRect 24 bit ptr @@@@ BAL 12Jan89
|
||
MOVE.L a3,d0 ;get dstRect ptr @@@@ BAL 09Apr88
|
||
_rTranslate24To32
|
||
move.l d0,dstRect(a6) ;save 32 bit ptr @@@@ BAL 07Jul88
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; IF PATTERN MODE, GO DECIDE BETWEEN RGNBLT AND BITBLT
|
||
;
|
||
MOVE LOCMODE(A6),D0 ;GET MODE
|
||
ROR #4,D0 ;IS PATTERN BIT SET ?
|
||
BCS NOTSTR ;=>YES, DON'T USE STRETCH
|
||
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; CALC NUMER AND DENOM BASED ON DSTRECT AND SRCRECT.
|
||
; IF NUMER = DENOM AND SRC DEPTH = DST DEPTH THEN JUST CALL RGNBLT.
|
||
;
|
||
MOVE BOTTOM(A2),D1
|
||
SUB TOP(A2),D1 ;CALC SRC HEIGHT
|
||
SWAP D1 ;PUT IN HI WORD
|
||
MOVE RIGHT(A2),D1
|
||
SUB LEFT(A2),D1 ;CALC SRC WIDTH
|
||
MOVE D1,D0 ;COPY SRC PIXCNT
|
||
SUBQ #1,D0 ;MAKE IT 0 BASED
|
||
MOVE D0,SRCPIXCNT(A6) ;SAVE SRC PIXEL COUNT
|
||
|
||
MOVE BOTTOM(A3),D0
|
||
SUB TOP(A3),D0 ;CALC DST HEIGHT
|
||
SWAP D0 ;PUT IN HI WORD
|
||
MOVE RIGHT(A3),D0
|
||
SUB LEFT(A3),D0 ;CALC DST WIDTH
|
||
|
||
_BlitCase ;Go determine blit style
|
||
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; Determine whether to use Stretch, Scale, Rgn, or Bit Bliting
|
||
;
|
||
BlitCase
|
||
; clr.b FastCase(a6) ;assume not a fun case <14SEP90 SMC>
|
||
|
||
TST.L MASKBITS(A6) ;*** IS THERE A MASK?
|
||
BNE STRETCH ;=>YES, USE STRETCH FOR NOW
|
||
|
||
CMP.L D0,D1 ;ARE SRC AND DST THE SAME SIZE
|
||
BNE STRETCH ;=>NO, STRETCH THE BITS
|
||
;
|
||
; Use stretch if UseStretchBit or ColorizeInSrcBufBit is set
|
||
;
|
||
move.w XLateFlag(a6),d2
|
||
and.w #~(UseStretch+ColorizeInSrcBuf),d2 ;use stretch? <05JUNE92 SAH>
|
||
cmp.w XLateFlag(a6),d2
|
||
bne Stretch
|
||
|
||
;
|
||
; Use ScaleBlt if ScaleColorBit is set <05JUNE92 SAH>
|
||
;
|
||
btst #ScaleColorBit,XlateFlag+1(a6)
|
||
bne xScaleBlt
|
||
|
||
CMP D3,D4 ;ARE THE DEPTHS THE SAME?
|
||
bne xScaleBlt ;=>no, use ScaleBlt
|
||
|
||
;
|
||
; source and destination are the same depth, check if color table seeds are the same
|
||
;
|
||
cmp #16,dstpix+pixelType(a6) ;is it a direct device?
|
||
beq.s notstr ;yes, don't check seeds
|
||
|
||
MOVE.L SRCPIX+PMTABLE(A6),d2 ;GET SRC COLOR TABLE HANDLE <BAL>
|
||
beq XScaleBLT ;nil table so must remap colors <BAL>
|
||
move.l d2,a0 ;get handle for deref <BAL>
|
||
|
||
MOVE.L (A0),A0 ;POINT TO IT
|
||
MOVE.L CTSEED(A0),D2 ;GET SEED
|
||
MOVE.L DSTPIX+PMTABLE(A6),A0 ;GET DST COLOR TABLE HANDLE
|
||
MOVE.L (A0),A0 ;POINT TO IT
|
||
CMP.L CTSEED(A0),D2 ;DO THE SEEDS MATCH?
|
||
BNE xScaleBlt ;=>NO, use scaleBlt
|
||
|
||
NOTSTR
|
||
;----------------------------------------------------------------
|
||
;
|
||
; NOW DECIDE BETWEEN BITBLT AND RGNBLT
|
||
;
|
||
; ARE ALL THREE REGIONS RECTANGULAR ? IF SO, USE BITBLT.
|
||
;
|
||
; If the visRgn or the clipRgn is non-rectangular then call TrimRect
|
||
; to see if the intersection of the region and MinRect is rectangular,
|
||
; empty, or regional. <C951> 08Nov87 BAL
|
||
;
|
||
|
||
; <45> If going to a direct device in an arithmetic mode, force into rgnblt. Those
|
||
; blit loops are effectively as fast as the ones in bitblt through their use of
|
||
; runmasking. This change allows those cases to be stripped out of bitblt.
|
||
;
|
||
CMP #4,D4 ;direct device?
|
||
BLT @noforce ;no, do normal checks
|
||
MOVE.W locMode(A6),D0 ;get penmode
|
||
BTST #5,D0 ;arithmetic?
|
||
BNE XRGNBLT ;yes, force into rgnblt
|
||
@noforce
|
||
|
||
MOVEQ #10,D0 ;GET SIZE OF RECT RGN
|
||
MOVE.L RGNC(A6),A0 ;GET RGNHANDLE
|
||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||
CMP RGNSIZE(A0),D0 ;IS RGNC RECTANGULAR ?
|
||
BNE XRGNBLT ;=>NO, USE RGNBLT
|
||
|
||
@chkVis MOVE.L RGNB(A6),A0 ;GET RGNHANDLE
|
||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||
CMP RGNSIZE(A0),D0 ;IS visRgn RECTANGULAR ? <C951>
|
||
BEQ.S @chkClip ;=>yes, go check clipRgn <C951>
|
||
|
||
MOVE.L RGNB(A6),-(SP) ;PUSH visRgn HANDLE <C951>
|
||
PEA MINRECT(A6) ;PUSH ADDR OF MINRECT
|
||
MOVE.W #-1,-(SP) ;pass Trim = True
|
||
_TRIMRECT ;CALL TRIMRECT
|
||
BLT DONE ;=>INTERSECTION EMPTY, QUIT & SHOW CURSOR
|
||
BGT XRGNBLT ;=>USE RGNBLT
|
||
|
||
; In case we fall into RgnBlt, replace visRgn with WideOpen
|
||
; so that TrimRect doesn't get called again by seekMask.
|
||
|
||
MOVE.L SAVEA5(A6),A1 ;Get global ptr <BAL 26Sep88>
|
||
MOVE.L GRAFGLOBALS(A1),A1 ;point to QD globals <BAL 26Sep88>
|
||
MOVE.L WIDEOPEN(A1),RGNB(A6) ;replace visRgn with wideOpen <BAL 26Sep88>
|
||
|
||
@chkClip
|
||
MOVE.L RGNA(A6),A0 ;GET RGNHANDLE
|
||
MOVE.L (A0),A0 ;DE-REFERENCE IT
|
||
CMP RGNSIZE(A0),D0 ;IS clipRgn RECTANGULAR ?
|
||
BEQ XBITBLT ;=>YES, GO USE BITBLT
|
||
|
||
MOVE.L RGNA(A6),-(SP) ;PUSH clipRgn HANDLE <C951>
|
||
PEA MINRECT(A6) ;PUSH ADDR OF MINRECT <C951>
|
||
MOVE.W #-1,-(SP) ;pass Trim = True
|
||
_TRIMRECT ;CALL TRIMRECT <C951>
|
||
BLT DONE ;=>INTERSECTION EMPTY, QUIT & SHOW CURSOR
|
||
BEQ XBITBLT ;=>USE BITBLT
|
||
|
||
; Since we will fall into RgnBlt, swap the clipRgn and the userRgn
|
||
; so that TrimRect doesn't get called again by seekMask.
|
||
|
||
MOVE.L RGNA(A6),A1 ;copy clipRgn <BAL 26Sep88>
|
||
MOVE.L RGNC(A6),RGNA(A6) ;replace clipRgn with userRgn <BAL 26Sep88>
|
||
MOVE.L A1,RGNC(A6) ;replace userRgn with clipRgn <BAL 26Sep88>
|
||
BRA XRGNBLT ;=>USE RGNBLT <BAL 26Sep88>
|
||
|
||
|
||
XScaleBLT
|
||
;--------------------------------------------------------------
|
||
;
|
||
; Must do depth scaling but no spatial resizing and no bit mask.
|
||
; Only supports copy and dither modes. No fg/bk colorizing.
|
||
; No search procs supported for direct sources.
|
||
;
|
||
; REGISTER USE:
|
||
;
|
||
; A2: SRCRECT (24 bit addr)
|
||
; A3: DSTRECT (24 bit addr)
|
||
; A4: SRCPIX
|
||
; A5: DSTPIX
|
||
;
|
||
; D3: SRCSHIFT
|
||
; D4: DSTSHIFT
|
||
; D7: INVERT FLAG
|
||
|
||
|
||
tst locMode(a6) ;copy mode?
|
||
bne Stretch ;if not copy mode then use stretch
|
||
|
||
;
|
||
; Use Stretch if an alpha mode is set by looking at the streamMode <23JUN92 SAH>
|
||
;
|
||
; Rather than looking at the stream mode directly here, we should add a call to the alpha
|
||
; routines that returns the alpha mode so that we can localize the code! Do this before it
|
||
; goes into ROM!
|
||
;
|
||
move.l savea5(a6),a0 ;get the real a5
|
||
move.l GrafGlobals(a0),a0 ;get the qd globals
|
||
move.l thePort(a0),a0 ;get the port
|
||
TST portBits+rowBytes(A0) ;is it an old port?
|
||
BPL @noalpha ;yes, alpha mode is illegal
|
||
MOVE.W dstPix+pixelSize(A6),D2 ;get depth of destination
|
||
CMP.W #16,D2 ;direct device?
|
||
BLT.S @noalpha ;no, skip this stuff
|
||
MOVE.L grafVars(A0),D2 ;get grafvars handle
|
||
BEQ @noalpha ;no grafvars, no alpha
|
||
MOVE.L D2,A0 ;copy handle
|
||
MOVE.L (A0),A0 ;dereference handle
|
||
BTST #PmNewGVBit-8,pmFlags(A0) ;make sure grafvars have been expanded
|
||
BEQ.S @noalpha ;if not, bail
|
||
TST.B streamMode(A0) ;is there an alpha mode
|
||
bne Stretch ;yes, so go slow
|
||
|
||
;
|
||
; now look at the actual alpha channel byte/bit to see if it contains zero. If not, we
|
||
; must go slow. This is because a streamMode of zero means that we write to both graphics
|
||
; and alpha. As an optimization, we might be able to just do this check alone for any
|
||
; streamMode so that we can go fast when writing an alpha of zero.
|
||
;
|
||
; For the purposes of Cube-E, this code is remaining as it is below, but it would be wise
|
||
; to make the tests just test memory directly to save code space!
|
||
;
|
||
|
||
MOVE.W dstPix+pixelSize(A6),D2 ;get depth of destination
|
||
cmp.w #16,d2
|
||
beq.s @check16bit
|
||
|
||
;dst is 32 bit
|
||
move.l fcolor(a6),d2
|
||
rol.l #8,d2 ;get the alpha channel in the low byte
|
||
tst.b d2 ;is it non-zero
|
||
bne Stretch ;yes, so go slow
|
||
move.l bcolor(a6),d2
|
||
rol.l #8,d2 ;get the alpha channel in the low byte
|
||
tst.b d2 ;is it non-zero
|
||
bne Stretch ;yes, so go slow
|
||
bra.s @noalpha ;ok, we can go fast!
|
||
@check16bit
|
||
|
||
;dst is 16 bit
|
||
move.l fcolor(a6),d2
|
||
btst #15,d2 ;is the alpha bit zero?
|
||
bne Stretch ;yes, so go slow
|
||
move.l bcolor(a6),d2
|
||
btst #15,d2 ;is the alpha bit zero?
|
||
bne Stretch ;yes, so go slow
|
||
@noalpha
|
||
|
||
;
|
||
; if colorize in modecase or srcbuf flag is set, use stretch
|
||
;
|
||
|
||
move.w XlateFlag(a6),d2
|
||
and.w #~(ColorizeinSrcBuf+ColorizeInModeCase),d2
|
||
cmp.w XlateFlag(a6),d2
|
||
bne.s @toStretch ;if applying color then use stretch
|
||
|
||
tst.w d7 ;invert the src?
|
||
bne.s @toStretch ;if so then use stretch
|
||
; st FastCase(a6) ;remember fastCase for Andy <14SEP90 SMC>
|
||
|
||
cmp.w #4,d4 ;dst < 16 bits/pixel? <05JUNE92 SAH>
|
||
blt.s @chkSrc ; <05JUNE92 SAH>
|
||
cmp.w #3,d3 ;src <16 bits/pixel?
|
||
bgt.s @toStretch
|
||
|
||
@fast
|
||
move.l stNoStackPtr,goShow(a6) ;pass go home routine
|
||
_ScaleBlt ;CALL scaleBlt
|
||
tst d0 ;did it handle it?
|
||
bne DONE ;RESTORE CURSOR AND QUIT
|
||
;
|
||
; ScaleBlt didn't handle it, so we need to make sure that if the depths
|
||
; are one bit and ScaleColor is set, we set ColorizeInModeCase so that
|
||
; BitBlt or RgnBlt colorizes
|
||
;
|
||
|
||
btst #ScaleColorBit,XlateFlag+1(a6)
|
||
beq.s notStr ;go ahead and use BitBlt
|
||
eor.w #(ScaleColor+ColorizeInModeCase),XlateFlag(a6)
|
||
BRA.s notStr
|
||
|
||
@chkSrc
|
||
cmp.w #5,d3 ;src 32 bits/pixel?
|
||
bne.s @more ;(was Stretch) <14SEP90 SMC>
|
||
cmp.w #3,d4 ;dst = 8 bits/pixel?
|
||
bne.s Stretch
|
||
bra.s @fast
|
||
|
||
@more cmp.w #4,d3 ;src 16 bits?
|
||
beq.s Stretch ;yes, dont do it here
|
||
bra.s @fast
|
||
@toStretch
|
||
BRA.S Stretch ;end of <14SEP90 SMC>
|
||
|
||
|
||
XBITBLT
|
||
;--------------------------------------------------------------
|
||
;
|
||
; SINCE ALL THREE REGIONS ARE RECTANGULAR, WE WILL USE BITBLT.
|
||
;
|
||
; REGISTER USE:
|
||
;
|
||
; A2: SRCRECT (32 bit addr)
|
||
; A3: DSTRECT (32 bit addr)
|
||
; A4: SRCPIX
|
||
; A5: DSTPIX
|
||
;
|
||
; D3: SRCSHIFT
|
||
; D4: DSTSHIFT
|
||
; D7: INVERT FLAG
|
||
|
||
moveq #true32b,d0 ;switch to 32 bit addressing
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
move.b d0,MMUsave(a6) ;save previous state for later
|
||
move.l srcRect(A6),a2 ;reload srcRect 32 bit ptr
|
||
move.l dstRect(A6),a3 ;reload dstRect 32 bit ptr
|
||
_BITBLT ;CALL BITBLT
|
||
BRA DONE ;RESTORE CURSOR AND QUIT
|
||
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; CALL RGNBLT WITH ALL SHARED LOCAL VARS SET UP AND REGS LIKE THIS:
|
||
;
|
||
; A2: SRCRECT (24 bit addr)
|
||
; A3: DSTRECT (24 bit addr)
|
||
; A4: SRCPIX
|
||
; A5: DSTPIX
|
||
;
|
||
; D3: SRCSHIFT
|
||
; D4: DSTSHIFT
|
||
; D7: INVERT FLAG
|
||
|
||
|
||
XRGNBLT
|
||
move.l stNoStackPtr,goShow(a6) ;pass go home routine to getSeek <BAL 21Mar89>
|
||
_StackAvail ;GET STACK AVAIL IN D0.L
|
||
LSR.L #2,D0 ;CONVERT BYTES TO LONGS
|
||
SUB.L #qdStackXtra/4,D0 ;SUBTRACT SLOP FACTOR <1.5> BAL
|
||
MOVE.L D0,STACKFREE(A6) ;AND SAVE FREE LONGS ON STACK
|
||
_RGNBLT ;CALL RGNBLT
|
||
BRA DONE ;RESTORE CURSOR AND QUIT
|
||
|
||
STRETCH
|
||
;
|
||
; if not shrinking and source is 1-bit b&w, clear dither flag <24Sept90 KON>
|
||
;
|
||
cmp.l d0,d1 ;src, dst same size? <24Sept90 KON>
|
||
bne.s @dontClearDither ;branch if no <24Sept90 KON>
|
||
move.l srcpix+pmtable(a6),d2 ;get source color table handle <24Sept90 KON>
|
||
beq.s @dontClearDither ;nil table: not 1-bit <24Sept90 KON>
|
||
move.l d2,a0 ;get handle for deref <24Sept90 KON>
|
||
move.l (a0),a0 ;point to it <24Sept90 KON>
|
||
moveq #1,d2 ; <24Sept90 KON>
|
||
cmp.l ctseed(a0),d2 ;one-bit b&w? <24Sept90 KON>
|
||
bne.s @dontClearDither ; <24Sept90 KON>
|
||
clr.b useDither(a6) ;don't promote source to 32-bits <24Sept90 KON>
|
||
|
||
@dontClearDither
|
||
;----------------------------------------------------------------
|
||
;
|
||
; (If dither flag or mask is deep) AND source is indexed data then
|
||
; pretend the source is 32 bit/pixel RGB data and remember
|
||
; real depth/srcShift for later.
|
||
;
|
||
move.w d3,realSrcShift(a6) ;make it real anyway
|
||
st realDepth(a6) ;assume not promoting source to RGB
|
||
cmp.w #16,srcPix+pixelType(a6) ;is src direct?
|
||
beq @dontUseRGB ;yes, leave source depth alone
|
||
tst.b useDither(a6) ;is the dither bit set?
|
||
bne.s @UseRGB ;yes, promote source depth
|
||
move maskshift(a6),d2
|
||
beq.s @dontUseRGB
|
||
|
||
@UseRGB
|
||
move.w #16,srcPix+pixelType(a6) ;pretend direct data
|
||
move.w srcPix+pixelSize(a6),realDepth(a6)
|
||
move.w #32,srcPix+pixelSize(a6) ;pretend 32 bits/pixel
|
||
moveq #5,d3 ;reset src shift
|
||
move.w d3,srcShift(a6)
|
||
;
|
||
; if scalecase colorizing was used, change to srcbuf colorizing since the scale table
|
||
; is not used when the src is 32-bits. <12NOV90 KON>
|
||
;
|
||
bclr #ScaleColorBit,XLateFlag+1(a6) ;Colorize in scale table?
|
||
beq.s @NoColorizing ;no, we're cool
|
||
;
|
||
; colorizing -> change to srcbuf colorizing and setup RGBFrColor and RGBBgColor
|
||
;
|
||
bset #ColorizeInSrcBufBit,XLateFlag(a6) ;colorize at srcbuf time
|
||
|
||
movem.l A5/D0/D1,-(SP) ;Need to preserve a5, d0, and d1
|
||
move.l SAVEA5(A6),A5 ;restore 15 for GetFore and GetBack color calls
|
||
btst #swapfgbgBit,XLateFlag+1(a6) ;rgb invert?
|
||
beq.s @DontSwap ;don't invert
|
||
|
||
PEA RGBBgColor(a6)
|
||
PEA RGBFrColor(a6) ;get fg color for colorizing
|
||
bra.s @SwapDone
|
||
@DontSwap
|
||
PEA RGBFrColor(a6) ;get fg color for colorizing
|
||
PEA RGBBgColor(a6)
|
||
@SwapDone
|
||
_GetBackColor ;get bg color for colorizing
|
||
_GetForeColor
|
||
;
|
||
; convert 16-16-16 to 8-8-8 for 32-bit src (D3=5)
|
||
;
|
||
move.l RGBBgColor(a6),d0 ;get RRRRGGGG
|
||
lsr.l #8,d0 ;get 00RRRRGG
|
||
lsl.w #8,d0 ;put green where it belongs, now 00RRGG00
|
||
move.b RGBBgColor+4(a6),d0 ;get blue: 00RRGGBB
|
||
move.l d0,RGBBgColor(a6)
|
||
|
||
move.l RGBFrColor(a6),d0 ;get RRRRGGGG
|
||
lsr.l #8,d0 ;get 00RRRRGG
|
||
lsl.w #8,d0 ;put green where it belongs, now 00RRGG00
|
||
move.b RGBFrColor+4(a6),d0 ;get blue: 00RRGGBB
|
||
move.l d0,RGBFrColor(a6)
|
||
movem.l (SP)+,a5/D0/D1 ;Restore a5,d0, and d1
|
||
|
||
@NoColorizing
|
||
@dontUseRGB
|
||
|
||
;-----------------------------------------------------------------------
|
||
; Change source pixel size to 32 bits if deep mask and src is 16-bit
|
||
;
|
||
cmp #4,d3 ;is it 16 bit?
|
||
bne.s KON
|
||
tst.w maskshift(a6)
|
||
beq.s KON
|
||
moveq #5,d3
|
||
KON
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; USE SRC AND DST SIZES TO DETERMINE STRETCHING ROUTINE
|
||
;
|
||
MOVE.L D0,NUMER(A6) ;NUMER := DST SIZE
|
||
MOVE.L D1,DENOM(A6) ;DENOM := SRC SIZE
|
||
MOVEM.L D3/D4,-(SP) ;SAVE D3/D4
|
||
|
||
_SetupStretch ;CALC CASEJUMP AND HORIZ FRACT (CLOBBER D3,D4)
|
||
MOVE.L A0,RATIOCASE(A6) ;SAVE CASE JUMP FOR LATER
|
||
MOVE D0,HORIZFRACTION(A6) ;SAVE FRACTION FOR LATER
|
||
MOVEM.L (SP)+,D3/D4 ;RESTORE D3/D4
|
||
|
||
clr.l SrcPixPmTable(a6) ; <KON 13DEC90>
|
||
MOVE.L SRCPIX+PMTABLE(A6),d0 ;GET SRC COLOR TABLE HANDLE <2Sep90 KON>
|
||
beq.s @BAL ;table not nil so continue <2Sep90 KON>
|
||
MOVE.L d0,a0
|
||
MOVE.L (A0),d0 ;POINT TO IT <2Sep90 KON>
|
||
_rTranslate24To32 ;clean master pointer <20AUG90 KON and BAL>
|
||
move.l d0,SrcPixPmTable(a6) ; <20AUG90 KON and BAL>
|
||
@BAL
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; DETERMINE AMOUNT OF STACK SPACE WE CAN USE
|
||
; Raised amount left for interupts from 1024 to 1600 bytes <BAL 10Apr89>
|
||
;
|
||
_StackAvail ;GET STACK AVAIL IN D0.L
|
||
LSR.L #2,D0 ;CONVERT BYTES TO LONGS
|
||
SUB.L #qdStackXtra/4,D0 ;SUBTRACT SLOP FACTOR <1.5> BAL
|
||
MOVE.L D0,STACKFREE(A6) ;AND SAVE FREE LONGS ON STACK
|
||
bpl.s @stkOK
|
||
_stNoStack ;=>NOT ENOUGH STACK, QUIT
|
||
@stkOK
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; Check to see if we are shrinking 16 or 32 bit source data OR if we are
|
||
; shrinking a deep mask. If we are, allocate a buffer for the larger of the
|
||
; two. *** Currently assuming source and mask are the same size ***
|
||
;
|
||
clr.b useAverage(a6) ;assume not averaging
|
||
move.w numer+v(A6),D0 ; get destination height
|
||
move.w denom+v(A6),D1 ; get source height
|
||
cmp.w d1,d0 ;is source larger than dest?
|
||
bge.s @noAvrg ;NO=> don't average
|
||
|
||
;yes, so average if 32 bit/pixel or deep mask
|
||
|
||
cmp.w #4,d3 ;is src indexed? <KON 2/22/90>
|
||
blt.s @noAvrg ;yes, skip averaging <KON 2/22/90>
|
||
@shrink
|
||
sge useAverage(a6) ;always average if 16 or 32bit src <KON 2/22/90>
|
||
moveq #0,d1
|
||
move.w denom+h(a6),d1 ;src width
|
||
move.l d1,d2 ;make a copy src width <16Feb90 KON and BAL>
|
||
add.l d2,d2 ;6 bytes (R.w,G.w,B.w) per pixel <BAL and KON 14Feb90>
|
||
add.l d1,d2 ;d2 is byte cnt/2 of AvrgBuf <BAL and KON 14Feb90>
|
||
;
|
||
; allocate the larger of source buffer or mask buffer
|
||
;
|
||
cmp.w #4,maskshift(a6) ;mask 16-bit data?
|
||
beq.s @DoWords ;yes, allocate twice the error buffer
|
||
; cmp.w #4,d3 ;source 16-bit data? <KON 2/22/90>
|
||
cmp.w #4,realSrcShift(a6) ;source 16-bit data (check real source)? <KON 3/18/91>
|
||
beq.s @DoWords ;Twice as many pixels, allocate twice the error buffer <KON 2/22/90>
|
||
lsr.l #1,d2 ;both 32-bit, 1/2 as many pixels
|
||
@DoWords
|
||
move.w d2,ABufSize(a6) ;save long cnt for later
|
||
SUB.L D2,STACKFREE(A6) ;IS THERE ENOUGH STACK?
|
||
bpl.s @stkOK2
|
||
_stNoStack ;=>NOT ENOUGH STACK, QUIT
|
||
@stkOK2
|
||
|
||
CLR.L -(SP) ;CLEAR ANOTHER LONG OF SLOP
|
||
@ClrBuf CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
|
||
DBRA D2,@ClrBuf ;LOOP ENTIRE BUFFER
|
||
MOVE.L SP,AvrgBuf(A6) ;REMEMBER WHERE AvrgBuf IS
|
||
|
||
@noAvrg
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; if dstPix is direct and we aren't averaging then no
|
||
; reason to promote source to RGB, unless using deep mask.
|
||
;
|
||
tst.b realDepth(a6) ;promoting src to RGB?
|
||
bmi.s @LeaveItAlone ;no, all ok
|
||
cmp.w #16,dstPix+pixelType(a6) ;is dst direct data?
|
||
bne.s @LeaveItAlone ;no, we will be dithering
|
||
tst.b useAverage(a6) ;are we averaging
|
||
bne.s @LeaveItAlone ;yes, promote source
|
||
tst.w maskshift(a6) ;deep mask?
|
||
bne.s @LeaveItAlone ;yes: promote
|
||
;
|
||
;no, don't promote source
|
||
;
|
||
move.w realDepth(a6),srcPix+pixelSize(a6)
|
||
move.w realSrcShift(a6),d3 ;don't fake 32-bit source
|
||
move.w d3,srcShift(a6) ;remember it for later
|
||
st realDepth(a6) ;don't expand source to 32-bit
|
||
clr.w SRCPIX+pixelType(A6) ;don't fake
|
||
;
|
||
; Change colorizing back to Scalecase colorizing since the scale table
|
||
; is used for indexed sources. <12NOV90 KON>
|
||
;
|
||
bclr #ColorizeInSrcBufBit,XLateFlag(a6) ;colorize at srcbuf time?
|
||
beq.s @NoColorizing ;no, we're cool
|
||
;
|
||
; colorizing -> change back to scalecase colorizing
|
||
;
|
||
bset #ScaleColorBit,XLateFlag+1(a6) ;Colorize in scale table
|
||
|
||
@NoColorizing
|
||
|
||
@LeaveItAlone
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; IF THE SRC AND DST ARE DIFFERENT DEPTHS, THEN MUST DO PIXEL SCALING
|
||
; IF THEY ARE THE SAME DEPTH, BUT DIFFERENT COLOR TABLES, DO PIXEL SCALING
|
||
;
|
||
|
||
CLR.L SCALECASE(A6) ;ASSUME NO PIXEL DEPTH SCALING
|
||
MOVE.W SRCPIX+pixelType(A6),D0 ;IS PIXELTYPE DIRECT? %%%
|
||
BEQ HasClut ;NO, IT HAS A CLUT %%%
|
||
cmp #16,d0 ;is it RGBDirect?
|
||
bne done ;unknown pixeltype -> go home
|
||
|
||
;@@@@ should also check cmpCount, cmpSize
|
||
|
||
MOVE.L ([theGDevice]),A2 ; get the current device (trash A2)
|
||
tst.l gdSearchProc(A2) ; get the search proc head
|
||
bne.s @Slow
|
||
|
||
cmp d3,d4 ;are the depths the same
|
||
beq PIXELOK ;yes, don't depth scale
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; The src is direct data (16 or 32 bits/pixel).
|
||
; Compute D5 as index into direct mode table based on
|
||
;
|
||
; src16 -> add 4
|
||
; dstIndexed -> add 1
|
||
; searchProc -> add 16
|
||
; dithering -> add 2
|
||
; dst16 -> add 2
|
||
; dstAllGray -> add 8
|
||
;
|
||
; D3=srcShift D4=dstShift
|
||
;
|
||
|
||
@Slow
|
||
moveq #4,d0 ; init direct scaleRtn with src=16
|
||
move.l d0,d5
|
||
cmp.w d3,d5 ; is src 16 bits/pixel?
|
||
beq.s @src16
|
||
moveq #0,d5 ; init src to 32 bits/pixel
|
||
@src16
|
||
cmp.w d4,d0 ; is dst 16 bits/pixel?
|
||
bne.s @dst32
|
||
addq #2,d5 ; remember dst is 16 bits/pixel
|
||
@dst32
|
||
|
||
cmp #16,DSTPIX+pixelType(A6) ;IS PIXELTYPE DIRECT? %%%
|
||
beq @noCLUT ;don't makeItable on direct device
|
||
|
||
|
||
; IF THE DST IS AN OLD GRAFPORT AND ONE BIT PER PIXEL, THEN OVERRIDE THE
|
||
; scaleCase FOR PROPER MAPPING
|
||
|
||
TST d4 ;ONE BIT PER PIXEL?
|
||
BNE.S @notBitmap ;=>NO, PROC IS OK
|
||
MOVE.L DSTBITS(A6),A1 ;GET DST BITMAP
|
||
TST ROWBYTES(A1) ;IS IT OLD?
|
||
BMI.S @notBitmap ;=>NO, PROC IS OK
|
||
addq #8,d5 ;force bitmap procs
|
||
bra @chkDither ;go check dither <BAL 28Jan90>
|
||
@notBitmap
|
||
|
||
addq #1,d5 ; remember dst is indexed
|
||
MOVE.L ([GDPMap,A2]),A1 ; get pixMap's handle
|
||
MOVE.L PMTable(A1),A0 ; get the device colorTable's handle
|
||
MOVE.L ([A0],CTSeed),D1 ; get the device colorTable's ctSeed
|
||
MOVE.L ([GDITable,A2]),A0 ; get the Itable's master pointer
|
||
CMP.L ITabSeed(A0),D1 ; has the colortable changed?
|
||
BEQ.S @1 ; if equal, then the iTable is OK
|
||
|
||
; if table is not up to date, build a new one
|
||
|
||
MOVE.L PMTable(A1),-(SP) ; push theGDevice's color table handle <BAL 26May89>
|
||
MOVE.L GDITable(A2),-(SP) ; push theGDevice's current iTabHandle
|
||
MOVE.W GDResPref(A2),-(SP) ; push the preferred iTableResolution
|
||
_MakeITable ; make a new table
|
||
TST.W QDErr ; was this sucessful?
|
||
BEQ.S @noErr ; nope, so quit
|
||
ADDQ #4,SP ; flush saved register
|
||
BRA doneErr ; <BAL 26May89>
|
||
@noErr MOVE.L ([theGDevice]),A2 ; redereference in case it moved <BAL 31Mar89>
|
||
MOVE.L ([GDITable,A2]),A0 ; get the iTable's master pointer
|
||
@1
|
||
ADD.w #ITTable,A0 ; point directly at data
|
||
MOVE.L A0,stITabPtr(A6) ; save in stack frame
|
||
SUB.w #ITTable,A0 ; get the iTable's master pointer
|
||
MOVE.W ITabRes(A0),stITabRes(A6) ; get the iTable resolution
|
||
MOVE.L ([GDPMap,A2]),A1 ; get pixMap's handle
|
||
MOVE.L ([PMTable,A1]),stCLUTPtr(A6) ; get the device colorTable's ptr
|
||
|
||
MOVE.L gdSearchProc(A2),D0 ; get the search proc head
|
||
bne.s @search ; go use search routines
|
||
|
||
|
||
; Here we know that the dst is indexed and no search proc is present,
|
||
; so determine if the dst clut is all grays and/or we are dithering.
|
||
|
||
; the iTable's master pointer is in A0
|
||
|
||
MOVEQ #1,D0 ; prime the register again
|
||
MOVE ITabRes(A0),D2 ; get the inverse table resolution (and Bit-field width)
|
||
LSL.L D2,D0 ; calculate 2^^res
|
||
LSL.L D2,D0 ; square it
|
||
LSL.L D2,D0 ; cube it
|
||
LEA ITTable(A0,D0.L),A1 ; point us at the ITabInfo
|
||
tst.w iTabFlags(a1) ; is this a grayITab?
|
||
bpl.s @chkDither ; no, go see if dithering
|
||
add.w #ITabInfo,a1 ; point past header
|
||
move.l a1,stITabInfo(a6) ; save for later
|
||
addq #8,d5 ; remember to use gray routines
|
||
|
||
moveq #40,d0
|
||
cmp.l ITabSeed(a0),d0 ; is dst the standard 8-bit gray clut?
|
||
beq.s @readyProc ; yes, ignore dithering for speeed!
|
||
|
||
@chkDither
|
||
|
||
tst.b useDither(a6) ; should we dither?
|
||
beq.s @readyProc ; no, we're set
|
||
addq #2,d5 ; remember to use dither routines
|
||
|
||
;
|
||
; Compute and allocate scanline buffer for dither error from previous scan <BAL 29Aug88>
|
||
;
|
||
|
||
MOVEQ #0,D0 ;CLEAR HIGH WORD OF D0
|
||
MOVE NUMER+H(A6),D0 ;GET WIDTH OF DST
|
||
lsl.l d4,d0 ;get bit width
|
||
add.l #31,d0 ;round to long boundary
|
||
lsr.l d4,d0 ;get adjusted pixel width
|
||
btst #3,d5 ;is dst a grayscale clut?
|
||
bne.s @gray ;only need 2 bytes per pixel for gray error <BAL 18Mar89>
|
||
|
||
move.l d0,d1 ;make a copy <BAL and KON 14Feb90>
|
||
ADD.l D0,D0 ;6 bytes (R.w,G.w,B.w) per pixel <BAL and KON 14Feb90>
|
||
add.l d1,d0 ;d0 is byte cnt/2 of ErrBuf <BAL and KON 14Feb90>
|
||
@gray LSR.l #1,D0 ;AND DIV BY 2 FOR LONGS <BAL and KON 14Feb90>
|
||
|
||
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
|
||
bpl.s @stkOK3
|
||
_stNoStack ;=>NOT ENOUGH STACK, QUIT
|
||
@stkOK3
|
||
|
||
CLR.L -(SP) ;CLEAR ANOTHER LONG OF SLOP
|
||
@ClearB CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
|
||
DBRA D0,@ClearB ;LOOP ENTIRE BUFFER
|
||
MOVE.L SP,ErrBUF(A6) ;REMEMBER WHERE ErrBuf IS
|
||
clr.b ErrDir(a6) ;init to carry error to right
|
||
BRA.S @readyProc ; and continue
|
||
|
||
|
||
; Here we know that the dst is direct so check if search proc is present.
|
||
|
||
|
||
@noCLUT
|
||
MOVE.L gdSearchProc(A2),D0 ; get the search proc head
|
||
beq.s @readyProc
|
||
@search
|
||
MOVE.L D0,stSProc(A6) ; put search procs list head in stack frame
|
||
bset #4,d5 ; use search routines
|
||
|
||
|
||
; We have the scaleCase routine selector in D5 so compute address
|
||
; of routine and stuff it in scaleCase for later
|
||
|
||
|
||
@readyProc
|
||
move.w d5,d0 ;copy selector
|
||
lsr.w #3,d0 ;determine table to use
|
||
lea (stColorTabPtr,ZA0,d0*4),A0 ;POINT TO MODE TABLE
|
||
move.l (a0),a0 ;get table
|
||
and.w #7,d5 ;get position in this table
|
||
add.l 0(A0,D5*4),A0 ;GET CASE JUMP ADDRESS
|
||
MOVE.L A0,scaleCase(A6) ; put depth scaling routine in stack frame
|
||
BRA PIXELOK ;=>ALREADY GOT ROUTINE
|
||
|
||
Bogus ;_debugger
|
||
bra Done
|
||
|
||
|
||
ALIGN 4
|
||
|
||
|
||
;Color Blits
|
||
stColorTab
|
||
DC.L Bogus-stColorTab ;0 32 to 32
|
||
DC.L Scale32toIndexed-stColorTab ;1 32 to Indexed
|
||
DC.L Scale32to16-stColorTab ;2 32 to 16
|
||
DC.L Dither32toIndexed-stColorTab ;3 32 to Indexed Dither
|
||
DC.L Scale16to32-stColorTab ;4 16 to 32
|
||
DC.L Scale16toIndexed-stColorTab ;5 16 to Indexed
|
||
DC.L Bogus-stColorTab ;6 16 to 16
|
||
DC.L Dither16toIndexed-stColorTab ;7 16 to Indexed Dither
|
||
|
||
|
||
;Gray Blits
|
||
stGrayTab
|
||
DC.L Scale32toBitmap-stGrayTab ;8 32 to BitMap
|
||
DC.L Scale32toGray-stGrayTab ;9 32 to Indexed
|
||
DC.L Dither32toBitmap-stGrayTab ;A 32 to (16) ->BitMap Dither <BAL 28Jan90>
|
||
DC.L Dither32toGray-stGrayTab ;B 32 to Indexed Dither
|
||
DC.L Scale16ToBitMap-stGrayTab ;C 16 to BitMap
|
||
DC.L Scale16toGray-stGrayTab ;D 16 to Indexed
|
||
DC.L Dither16toBitmap-stGrayTab ;E 16 to (16) ->BitMap Dither <BAL 28Jan90>
|
||
DC.L Dither16toGray-stGrayTab ;F 16 to Indexed Dither
|
||
|
||
|
||
;Search Blits
|
||
stSearchTab
|
||
DC.L Search32to32-stSearchTab ;10 32 to 32 <20AUG90 KON>
|
||
DC.L Search32toIndexed-stSearchTab ;11 32 to Indexed
|
||
DC.L Search32to16-stSearchTab ;12 32 to 16
|
||
DC.L Bogus-stSearchTab ;13 32 to Indexed Dither
|
||
DC.L Search16to32-stSearchTab ;14 16 to 32
|
||
DC.L Search16toIndexed-stSearchTab ;15 16 to Indexed
|
||
DC.L Search16to16-stSearchTab ;16 16 to 16 <20AUG90 KON>
|
||
DC.L Bogus-stSearchTab ;17 16 to Indexed Dither
|
||
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; The src is indexed data (1,2,4,8 bits/pixel).
|
||
; If seeds don't match or depths are different then make a scale table.
|
||
; Special case 1-bit source.
|
||
;
|
||
|
||
HasClut
|
||
MOVE.L SRCPIX+PMTABLE(A6),d0 ;GET SRC COLOR TABLE HANDLE <BAL>
|
||
beq.s DOXLATE ;table not nil so continue <BAL>
|
||
move.l d0,a0 ;get handle for deref <BAL>
|
||
move.l (a0),a0 ;point to it <KON>
|
||
MOVE.L CTSEED(A0),D0 ;GET SEED
|
||
|
||
MOVE.L DSTPIX+PMTABLE(A6),A0 ;GET DST COLOR TABLE HANDLE
|
||
cmp #16,DstPix+pixelType(a6) ;is it a direct device?
|
||
beq.s @chk1 ;yes, don't check seeds
|
||
MOVE.L (A0),A0 ;POINT TO IT
|
||
CMP.L CTSEED(A0),D0 ;DO THE SEEDS MATCH?
|
||
BNE.S @chk1 ;=>NO, MUST TRANSLATE
|
||
|
||
|
||
CMP D3,D4 ;DOES SRC DEPTH = DST DEPTH?
|
||
bne.s @chk1 ;no, then scale pixels
|
||
;
|
||
; check fg and bk color and if they aren't black and white
|
||
; then take chk1 case, otherwise, take pixelok case.
|
||
;
|
||
; <KON 5MAR91> begins here... This fixes a problem with drawing to bitmaps. The problem
|
||
; is when the main device is direct and the app sets the fg color to black and the
|
||
; bg color to white, we think we are colorizing since the sense of what is black and
|
||
; what is white is reversed. This can only happen when the destination pixmap is
|
||
; 1-bit and the destination GDevice is a direct device. Thus, I special case this
|
||
; situation and check the fg and bg colors for black and white correctly. There is
|
||
; probably a more elegant fix for this, but with 7.0 ready to ship this implementation
|
||
; causes the least risk since it should effect only the case we are interested in. If
|
||
; it's not this particular case, we branch to @OldWay and processing continues as before.
|
||
; YUK!
|
||
;
|
||
; from QDciPatchROM.a verbatim (down through the RTD) <sm 6/9/92>stb
|
||
;
|
||
; if destination device is direct, and dst pixmap 1-bit bcolor = FFFFFFFF and
|
||
; fcolor = 0 is NOP
|
||
; else, bcolor = 0, fcolor = $FFFFFFFF is NOP
|
||
;
|
||
cmp #1,d3 ;1-bit?
|
||
bne.s @OldWay ;no, do it as before
|
||
MOVE.L ([theGDevice]),A2 ; get the current device
|
||
MOVE.L ([GDPMap,A2]),A1 ; get pixMap
|
||
cmp #16,pixelType(A1) ; is dest. GDevice direct?
|
||
bne.s @OldWay ;
|
||
;
|
||
; Destination pixmap is indexed but GDevice is direct. Assume we are going to
|
||
; an old 1-bit port.
|
||
;
|
||
move.l fcolor(a6),d1
|
||
bne.s @chk1 ;fg not black, go slow
|
||
move.l bcolor(a6),d1
|
||
addq #1,d1
|
||
beq PIXELOK ;bk white, fg black, go fast
|
||
bra.s @chk1
|
||
|
||
; <KON 5MAR91> ends here...
|
||
@OldWay
|
||
move.l bcolor(a6),d1
|
||
bne.s @chk1 ;fg not black, go slow
|
||
move.l fcolor(a6),d1
|
||
addq #1,d1
|
||
beq PIXELOK ;bk white, fg black, go fast
|
||
|
||
@chk1 TST D3 ;IS SRC ONE BIT PER PIXEL?
|
||
BNE.S DOXLATE ;=>NO, Build mapping table
|
||
MOVEQ #1,D1 ;GET CTSEED FOR DEFAULT ONE BIT TABLE
|
||
CMP.L D0,D1 ;IS IT THE DEFAULT?
|
||
BEQ SRCONE ;=>YES, USE EXPAND TABLES FOR SPEED
|
||
|
||
DOXLATE MOVE SRCPIX+PIXELSIZE(A6),D1 ;GET SRC BITS PER PIXEL
|
||
MOVEQ #1,D0 ;# ENTRIES = 2^ PIXELSIZE
|
||
LSL D1,D0 ;CALC # ENTRIES
|
||
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
|
||
bpl.s @stkOK
|
||
_stNoStack ;=>NOT ENOUGH STACK, QUIT
|
||
@stkOK
|
||
|
||
; IF THE DST IS AN OLD GRAFPORT AND IS ONE BIT PER PIXEL, THEN OVERRIDE THE
|
||
; SEARCH PROC FOR PROPER MAPPING
|
||
|
||
MOVEQ #0,D7 ;ASSUME NO PROC INSTALLED
|
||
CMP #1,DSTPIX+PIXELSIZE(A6) ;ONE BIT PER PIXEL?
|
||
BNE.S @PROCOK ;=>NO, PROC IS OK
|
||
MOVE.L DSTBITS(A6),A1 ;GET DST BITMAP
|
||
TST ROWBYTES(A1) ;IS IT OLD?
|
||
BMI.S @PROCOK ;=>NO, PROC IS OK
|
||
|
||
MOVEQ #1,D7 ;FLAG PROC INSTALLED
|
||
PEA ONEBITPROC ;POINT TO OUR PROC
|
||
_ADDSEARCH ;AND INSTALL IT
|
||
|
||
@PROCOK MOVE.L SAVEA5(A6),A5 ;GET A5 FOR MAKESCALETBL
|
||
MOVE.L A4,-(SP) ;PUSH SRCPIX POINTER
|
||
|
||
;
|
||
; If bit 0 = 1, then MakeScaleTbl colorizes, otherwise it don't.
|
||
; if mode is BIC or OR, then don't colorize in MakeScaleTbl
|
||
;
|
||
MOVE.w XLateFlag(a6),-(SP) ;pass arithmetic mode to get fg/bg relative colors
|
||
_MakeScaleTbl ;AND MAKE PIXEL TRANSLATION TABLE
|
||
|
||
;------------------------------------------------------------------------------------------
|
||
;
|
||
; <C947> 08Nov87 BAL begins here:
|
||
;
|
||
;------------------------------------------------------------------------------------------
|
||
;
|
||
; MakeScaleTbl is called whenever the src and dst pixmaps have different
|
||
; pixel depths or different color table seeds. MakeScaleTbl returns a
|
||
; pixel translation table used to map each src pixel to a dst pixel.
|
||
;
|
||
; Here I check to see if the translation table returned by MakeScaleTbl is in
|
||
; actuality an identity mapping--in which case no mapping at all is required!
|
||
; In order for an identity mapping to result the src and dst pixMaps must be of the same
|
||
; depth.
|
||
;
|
||
; If an identity mapping is detected, I must decide whether a stretch blit loop is
|
||
; really required (ie src rect ≠ dst rect or maskBits ≠ nil) or whether a much faster
|
||
; region blit or bit blit loop would suffice.
|
||
;
|
||
;------------------------------------------------------------------------------------------
|
||
|
||
move SRCPIX+PIXELSIZE(A6),d1 ;get src bits/pixel
|
||
cmp DSTPIX+PIXELSIZE(A6),d1 ;is it the same as dst bits/pixel?
|
||
bne.s @ScaleOK ;no, have to do pixel scaling
|
||
|
||
;inspect scale table for equality
|
||
@chkTbl MOVEQ #1,D0 ;# ENTRIES = 2^ PIXELSIZE
|
||
LSL D1,D0 ;CALC # ENTRIES in d0
|
||
move d0,d1 ;make a copy of long count
|
||
lsl #2,d1 ;get size of table
|
||
subq #1,d0 ;make counter zero based for dbra
|
||
move.l sp,a0 ;point to scale tbl
|
||
add d1,a0 ;point past end of table
|
||
|
||
@1 cmp.l -(a0),d0 ;compare with dst pixel value
|
||
dbne d0,@1
|
||
bne.s @ScaleOK ;tables are not equal so perform pixel scaling
|
||
|
||
CLR.L ScaleCase(a6) ;remember no pixel xlation needed <BAL 09Apr90>
|
||
MOVE.L SP,ScaleTbl(A6) ;SAVE TRANSLATION TABLE just in case <BAL 09Apr90>
|
||
|
||
;if we installed a proc get rid of it before short circuiting stretch
|
||
|
||
TST D7 ;DID WE INSTALL A PROC
|
||
BEQ.S @NOPRC ;=>NO, DON'T NEED TO REMOVE
|
||
PEA ONEBITPROC ;ELSE PUSH OUR PROC
|
||
_DELSEARCH ;AND DELETE IT
|
||
|
||
@NOPRC LEA DSTPIX(A6),A5 ;RESTORE DSTPIX POINTER
|
||
TST.L MASKBITS(A6) ;*** IS THERE A MASK?
|
||
BNE PIXELOK ;=>YES, USE STRETCH BUT DON'T PIXEL TRANSLATE
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; CALC NUMER AND DENOM BASED ON DSTRECT AND SRCRECT.
|
||
; IF NUMER = DENOM AND SRC DEPTH = DST DEPTH THEN JUST CALL RGNBLT.
|
||
;
|
||
MOVE.L NUMER(A6),D0 ;GET WIDTH,HEIGHT OF DST
|
||
CMP.L DENOM(A6),D0 ;SAME AS WIDTH,HEIGHT OF SRC?
|
||
BNE PIXELOK ;no, must call stretch
|
||
MOVE.L INVERTFLAG(A6),D7 ;restore invert flag <<C983>>
|
||
BRA NOTSTR ;jump back and decide between bitblt and rgnblt
|
||
;don't really have to use stretch at all!
|
||
|
||
;------------------------------------------------------------------------------------------
|
||
;
|
||
; <C947> 08Nov87 BAL ends here.
|
||
;
|
||
;------------------------------------------------------------------------------------------
|
||
@ScaleOK
|
||
MOVE.L SP,ScaleTbl(A6) ;SAVE POINTER TO TRANSLATION TABLE
|
||
LEA DSTPIX(A6),A5 ;RESTORE DSTPIX POINTER
|
||
|
||
TST D7 ;DID WE INSTALL A PROC
|
||
BEQ.S @NOPROC ;=>NO, DON'T NEED TO REMOVE
|
||
PEA ONEBITPROC ;ELSE PUSH OUR PROC
|
||
_DELSEARCH ;AND DELETE IT
|
||
|
||
@NOPROC move.l stIndexedSrc,A0 ;POINT TO THE SCALING ROUTINE
|
||
MOVE.L A0,SCALECASE(A6) ;AND SAVE CASE JUMP FOR LATER
|
||
BRA PIXELOK ;=>ALREADY GOT ROUTINE
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
ONEBITPROC
|
||
;----------------------------------------------------------------
|
||
; FUNCTION ONEBITPROC(MYCOLOR:RGBCOLOR; VAR INDEX: LONG): BOOLEAN;
|
||
;
|
||
; THIS IS A COLOR MANAGER CUSTOM SEARCH PROC THAT MAPS RGB TO
|
||
; BLACK AND WHITE FOR MAPPING TO OLD GRAFPORTS.
|
||
; Algorithm modified to use [5 9 2] luminance mapping. <BAL 30Mar89>
|
||
;
|
||
MYINDEX EQU 4
|
||
MYRGB EQU 8
|
||
RESULT EQU 12
|
||
|
||
ST.B RESULT(SP) ;ALWAYS RETURN TRUE
|
||
MOVE.L MYRGB(SP),A0 ;POINT TO RGB
|
||
moveq #0,d0 ;clear out high end
|
||
moveq #0,d1 ;clear out high end
|
||
move.w red(a0),d0 ;get red
|
||
move.l d0,a1 ;keep red in a1
|
||
move.w green(a0),d1 ;get green
|
||
add.l d0,d1 ;accumulate luminance in d1
|
||
move blue(a0),d0
|
||
add.l d0,d1 ;accumulate luminance in d1
|
||
add.l d0,d1 ;accumulate luminance in d1
|
||
lsr.l #2,d1
|
||
add.l a1,d1 ;accumulate luminance in d1
|
||
move green(a0),d0
|
||
add.l d0,d1 ;accumulate luminance in d1
|
||
add.l d0,d1 ;accumulate luminance in d1
|
||
lsr.l #2,d1
|
||
MOVE.L MYINDEX(SP),A1 ;POINT TO INDEX
|
||
CLR.L (A1) ;ASSUME INDEX = WHITE
|
||
tst d1 ;check luminance
|
||
BMI.S @RESOK ;=>IF >= $8000 THEN WHITE
|
||
ADDQ.L #1,(A1) ;ELSE RETURN BLACK
|
||
@RESOK RTD #8 ;STRIP PARAMS AND RETURN
|
||
|
||
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
;----------------------------------------------------------------
|
||
;
|
||
; FOR 1 BIT TO N BIT PIXEL-STRETCHING, SET UP EXPAND ROUTINE.
|
||
;
|
||
|
||
SRCONE move.l ExTblPtr,A0 ;POINT TO ROUTINE TABLE
|
||
CMP.W #4,D4 ;are we going to a direct device? <42>
|
||
BLT.S @2 ;no, take normal path <42>
|
||
MOVE.W locMode(A6),D0 ;get transfer mode <42>
|
||
BTST #5,D0 ;arithmetic? <42>
|
||
BNE.S @2 ;yes, take normal path <42>
|
||
AND.W #3,D0 ;is the mode copy? <42>
|
||
BEQ.S @2 ;yes, take normal path (colors swapped) <42>
|
||
MOVE.L alphaMask(A6),D1 ;get the alpha mask <42>
|
||
TST.L INVERTFLAG(A6) ;are we inverting? <42>
|
||
BEQ.S @1 ;no, leave invertflag alone <42>
|
||
MOVE.L D1,INVERTFLAG(A6) ;yes, change invertflag to alphamask <42>
|
||
@1: CLR.L alphaFore(A6) ;foreground is zeroes <42>
|
||
MOVE.L D1,alphaBack(A6) ;background is alphamask <42>
|
||
ADD.L 40(A0,D4*4),A0 ;get address of special expansion loop <42>
|
||
BRA.S @gotScale ;jump to common code <42>
|
||
@2: ;take normal path <42>
|
||
;
|
||
;take special loops if colorizing
|
||
;
|
||
btst #ScaleColorBit,XLateFlag+1(a6) ;colorize in expansion?
|
||
beq.s @nocolorize ;no, colorize in blit loop
|
||
@colorize
|
||
add.l 32(A0,d4*4),a0 ;colorize in expansion
|
||
if 0 then ;why? <10Sept90 KON>
|
||
;
|
||
; if swapfgbgBit is set, we need to swap fg/bg color again
|
||
;
|
||
btst #swapfgbgBit,XLateFlag+1(a6) ;rgb invert?
|
||
beq.s @gotScale ;don't invert
|
||
move.l fcolor(a6),d1 ;swap fg/bk color
|
||
move.l bcolor(a6),fcolor(a6)
|
||
move.l d1,bcolor(a6)
|
||
endif
|
||
bra.s @gotScale
|
||
|
||
@nocolorize
|
||
cmp.w #4,d4
|
||
blt.s @indexedDst
|
||
add.l 8(A0,D4*4),A0 ;choose between direct loops
|
||
bra.s @gotScale
|
||
@indexedDst
|
||
add.l 0(A0,D4*4),A0 ;USE DSTSHIFT TO SELECT ROUTINE
|
||
@gotScale
|
||
MOVE.L A0,SCALECASE(A6) ;SAVE CASE JUMP FOR LATER
|
||
|
||
;-----------------------------------------------------------------------
|
||
;
|
||
; We've got our ScaleCase.
|
||
;
|
||
PIXELOK
|
||
|
||
;-----------------------------------------------------------------------
|
||
;
|
||
; ALLOCATE AND CLEAR SRCBUF TO HOLD SRCWIDTH.
|
||
;
|
||
MOVEQ #0,D0 ;CLEAR HIGH WORD OF D0
|
||
MOVE DENOM+H(A6),D0 ;GET WIDTH OF SRC
|
||
LSL.l D3,D0 ;SCALE WIDTH BY SRC DEPTH
|
||
SUBq.l #1,D0 ;SUBTRACT 1 BIT
|
||
LSR.l #5,D0 ;AND DIV BY 32 FOR LONGS
|
||
MOVE D0,SRCLONGS(A6) ;SAVE FOR LATER
|
||
|
||
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
|
||
bpl.s @stkOK
|
||
_stNoStack ;=>NOT ENOUGH STACK, QUIT
|
||
@stkOK
|
||
|
||
CLR.L -(SP) ;CLEAR A LONG OF SLOP AT RIGHT
|
||
CLRSRC CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
|
||
DBRA D0,CLRSRC ;LOOP ENTIRE BUFFER
|
||
MOVE.L SP,SRCBUF(A6) ;REMEMBER WHERE SRCBUF IS
|
||
MOVE.L SP,DSTBUF(A6) ;ASSUME NO HORIZONTAL STRETCHING
|
||
MOVE.L SP,SCALEBUF(A6) ;ASSUME NO PIXEL TRANSLATION
|
||
|
||
|
||
;-----------------------------------------------------------------------
|
||
;
|
||
; ALLOCATE AND CLEAR DSTBUF TO HOLD DSTLONGS.
|
||
;
|
||
MOVEQ #0,D0 ;CLEAR HIGH WORD OF D0
|
||
MOVE NUMER+H(A6),D0 ;GET WIDTH OF DST
|
||
CMP DENOM+H(A6),D0 ;SAME AS WIDTH OF SRC?
|
||
BEQ.S NOHSTRETCH ;=>YES, NO HORIZONTAL STRETCHING
|
||
|
||
LSL.l D3,D0 ;SCALE WIDTH BY SRC DEPTH
|
||
|
||
SUBq.l #1,D0 ;SUBTRACT 1 BIT
|
||
LSR.l #5,D0 ;AND DIV BY 32 FOR LONGS
|
||
MOVE D0,DSTLONGS(A6) ;SAVE FOR LATER
|
||
|
||
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
|
||
bpl.s @stkOK
|
||
_stNoStack ;=>NOT ENOUGH STACK, QUIT
|
||
@stkOK
|
||
|
||
CLR.L -(SP) ;CLEAR ANOTHER LONG OF SLOP
|
||
CLRDST CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
|
||
DBRA D0,CLRDST ;LOOP ENTIRE BUFFER
|
||
MOVE.L SP,DSTBUF(A6) ;REMEMBER WHERE DSTBUF IS
|
||
MOVE.L SP,SCALEBUF(A6) ;DEFAULT SCALEBUF = DSTBUF
|
||
|
||
|
||
NOHSTRETCH
|
||
;-----------------------------------------------------------------------
|
||
;
|
||
; ALLOCATE AND CLEAR MASK TO HOLD srcMASKlongs.
|
||
;
|
||
CLR.L MASKNUMER(A6) ;SRC MASK WIDTH
|
||
CLR.L MASKDENOM(A6) ; = DST MASK WIDTH
|
||
MOVE.L MASKBITS(A6),D0 ;IS THERE A MASK?
|
||
BEQ NODST ;=>NO, DON'T ALLOCATE MASK BUFFERS
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; CALC NUMER AND DENOM BASED ON DSTRECT AND MASKRECT.
|
||
;
|
||
MOVE.L MASKRECT(A6),A0 ;POINT TO MASKRECT
|
||
MOVE BOTTOM(A0),D1
|
||
SUB TOP(A0),D1 ;CALC MASK HEIGHT
|
||
SWAP D1 ;PUT IN HI WORD
|
||
MOVE RIGHT(A0),D1
|
||
SUB LEFT(A0),D1 ;CALC MASK WIDTH
|
||
|
||
MOVE BOTTOM(A3),D0
|
||
SUB TOP(A3),D0 ;CALC DST HEIGHT
|
||
SWAP D0 ;PUT IN HI WORD
|
||
MOVE RIGHT(A3),D0
|
||
SUB LEFT(A3),D0 ;CALC DST WIDTH
|
||
|
||
;----------------------------------------------------------------
|
||
;
|
||
; USE MASK AND DST SIZES TO DETERMINE MASK STRETCHING ROUTINE
|
||
;
|
||
MOVEM.L D3/D4,-(SP) ;SAVE D3/D4
|
||
MOVE.L D0,MASKNUMER(A6) ;NUMER := DST SIZE
|
||
MOVE.L D1,MASKDENOM(A6) ;DENOM := SRC SIZE
|
||
_SetupStretch ;CALC CASEJUMP AND HORIZ FRACT (CLOBBER D3,D4)
|
||
MOVE.L A0,MASKCASE(A6) ;SAVE CASE JUMP FOR LATER
|
||
MOVE D0,MASKFRACT(A6) ;SAVE FRACTION FOR LATER
|
||
MOVEM.L (SP)+,D3/D4 ;RESTORE D3/D4
|
||
MOVEQ #0,D2 ;CLEAR HIGH WORD OF D0
|
||
move.w MASKDENOM+H(A6),d2 ;get width of mask
|
||
;
|
||
;unless depth = 1, depth promoted to 32 bit/pix
|
||
;
|
||
move.w maskshift(a6),d1
|
||
beq.s @onebitmask
|
||
|
||
move.l maskpix+pmTable(a6),a0
|
||
move.l (a0),d0 ;get pointer to color table <20AUG90 KON and BAL>
|
||
_rTranslate24To32 ;clean master pointer <20AUG90 KON and BAL>
|
||
move.l d0,MaskPixPmTable(a6) ; <20AUG90 KON and BAL>
|
||
|
||
moveq #5,d1
|
||
lsl.l d1,d2 ;scale width by mask depth
|
||
@onebitmask
|
||
SUB.l #1,D2 ;SUBTRACT 1 BIT
|
||
LSR.l #5,D2 ;AND DIV BY 32 FOR LONGS
|
||
MOVE D2,SRCMASKLONGS(A6) ;SAVE FOR LATER
|
||
|
||
SUB.L D2,STACKFREE(A6) ;IS THERE ENOUGH STACK?
|
||
bpl.s @stkOK
|
||
_stNoStack ;=>NOT ENOUGH STACK, QUIT
|
||
@stkOK
|
||
|
||
CLR.L -(SP) ;CLEAR A LONG OF SLOP AT RIGHT
|
||
CLRMSK1 CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
|
||
DBRA D2,CLRMSK1 ;LOOP ENTIRE BUFFER
|
||
MOVE.L SP,SRCMASKBUF(A6) ;REMEMBER WHERE SRCMASKBUF IS
|
||
|
||
|
||
;-----------------------------------------------------------------------
|
||
;
|
||
; ALLOCATE AND CLEAR DSTMASKBUF TO HOLD MASKLONGS.
|
||
;
|
||
MOVE.L SP,DSTMASKBUF(A6) ;ASSUME NO DSTBUF
|
||
MOVEQ #0,D0 ;CLEAR HIGH WORD OF D0
|
||
MOVE MASKNUMER+H(A6),D0 ;GET WIDTH OF DST
|
||
CMP MASKDENOM+H(A6),D0 ;SAME AS WIDTH OF SRC?
|
||
BEQ.S NODST ;=>YES, NO DSTMASKBUF
|
||
;mask depth in d1 from above
|
||
lsl.l d1,d0 ;scale width by mask depth
|
||
@onebitmask
|
||
SUB.l #1,D0 ;SUBTRACT 1 BIT
|
||
LSR.l #5,D0 ;AND DIV BY 32 FOR LONGS
|
||
MOVE D0,DSTMASKLONGS(A6) ;SAVE FOR LATER
|
||
|
||
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
|
||
bpl.s @stkOK
|
||
_stNoStack ;=>NOT ENOUGH STACK, QUIT
|
||
@stkOK
|
||
|
||
CLR.L -(SP) ;CLEAR A LONG OF SLOP AT RIGHT
|
||
CLRMSK2 CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
|
||
DBRA D0,CLRMSK2 ;LOOP ENTIRE BUFFER
|
||
MOVE.L SP,DSTMASKBUF(A6) ;REMEMBER WHERE DSTMASKBUF IS
|
||
|
||
|
||
;-----------------------------------------------------------------------
|
||
;
|
||
; ALLOCATE AND CLEAR SCALEBUF TO HOLD SCALELONGS.
|
||
;
|
||
NODST TST.L SCALECASE(A6) ;IS THERE A SCALE ROUTINE?
|
||
BEQ.S NOSCALE ;=>NO, DON'T ALLOCATE BUFFER
|
||
|
||
DOSCALE MOVEQ #0,D0 ;CLEAR HIGH WORD OF D0
|
||
MOVE NUMER+H(A6),D0 ;GET DST WIDTH
|
||
SUB.l #1,D0 ;SUBTRACT 1 BIT @@@@ altered to use longs 03May88 BAL
|
||
LSL.l D4,D0 ;SCALE DSTBUF BY DSTSHIFT @@@@ altered to use longs 03May88 BAL
|
||
LSR.l #5,D0 ;AND DIV BY 32 FOR LONGS @@@@ altered to use longs 03May88 BAL
|
||
MOVE D0,SCALELONGS(A6)
|
||
|
||
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
|
||
bpl.s @stkOK
|
||
_stNoStack ;=>NOT ENOUGH STACK, QUIT
|
||
@stkOK
|
||
|
||
CLR.L -(SP) ;CLEAR A LONG OF SLOP AT RIGHT
|
||
CLR.L -(SP) ;CLEAR ANOTHER LONG OF SLOP
|
||
CLRCHNK CLR.L -(SP) ;ALLOCATE AND CLEAR A LONG
|
||
DBRA D0,CLRCHNK ;LOOP ENTIRE BUFFER
|
||
MOVE.L SP,SCALEBUF(A6) ;REMEMBER WHERE SCALEBUF IS
|
||
|
||
|
||
;_________________________________________________________________________________________
|
||
;
|
||
; CALC expansion buffer = [ (minRect.right-minRect.left) div 32 + 1 ] * pixelsize - 0
|
||
; CALC bufSize = [ (minRect.right-minRect.left) * pixelsize - 1 ] div 32 + 1 <C954> 08Nov87 BAL
|
||
;
|
||
NOSCALE MOVE.L DSTRECT(A6),A0 ;POINT TO DSTRECT
|
||
MOVE LEFT(A0),D1 ;GET DSTRECT LEFT
|
||
SUB BOUNDS+LEFT(A5),D1 ;CONVERT TO GLOBAL COORDS
|
||
LSL.L D4,D1 ;CONVERT DST PIXELS TO BITS
|
||
AND #$FFE0,D1 ;TRUNC TO MULT OF 32
|
||
ASR.L D4,D1 ;CONVERT DST BITS TO PIXELS
|
||
ADD BOUNDS+LEFT(A5),D1 ;CONVERT BACK TO LOCAL
|
||
MOVE D1,BUFLEFT(A6) ;SAVE AS BUFLEFT
|
||
MOVEQ #0,D0 ;CLEAR HIGH WORD OF D0
|
||
MOVE MINRECT+RIGHT(A6),D0 ;GET MINRECT RIGHT
|
||
SUB D1,D0 ;CALC WIDTH IN DOTS
|
||
MOVE D0,bufSize(A6) ;for arithmetic modes, prime bufSize with dot size
|
||
move d0,d1 ;save for expansion scanline buffer <C954>
|
||
|
||
ext.l d1 ;clear out high word <C954>
|
||
lsl.l d4,d1 ;convert to bits <C954>
|
||
subq.l #1,d1 ;force downward round <C954>
|
||
LSR.l #5,D1 ;GET NUMBER OF LONGS IN SCANBUF - 1 <C954>
|
||
addq.l #1,d1 ;***make it one based for stretch!! <C954>
|
||
BTST #5,locMode+1(A6) ;arithmetic?
|
||
BNE.S @skipDotToLong ;if so, don’t update bufSize
|
||
|
||
MOVE D1,BUFSIZE(A6) ;BUFSIZE = # LONGS -1 <C954>
|
||
|
||
@skipDotToLong
|
||
LSR #5,D0 ;GET NUMBER OF LONGS IN SCANBUF
|
||
ADDQ #1,D0 ;MAKE IT ONE BASED
|
||
LSL D4,D0 ;MULTIPLY BY DST PIXEL DEPTH
|
||
;*** Leave it one based !!!?
|
||
SUB.L D0,STACKFREE(A6) ;IS THERE ENOUGH STACK?
|
||
bpl.s @stkOK
|
||
_stNoStack ;=>NOT ENOUGH STACK, QUIT
|
||
@stkOK
|
||
|
||
;-----------------------------------------------------------------------
|
||
;
|
||
; ALLOCATE AND CLEAR A SCANLINE BUFFER FOR THE COMPOSITE MASK.
|
||
;
|
||
CLR.L -(SP) ;TWO FOR SLOP
|
||
CLR.L -(SP) ;ONE FOR SLOP
|
||
CLRMASK CLR.L -(SP) ;ALLOCATE AND CLEAR
|
||
DBRA D0,CLRMASK ;LOOP TILL DONE
|
||
MOVE.L SP,RGNBUFFER(A6) ;REMEMBER WHERE RGNBUFFER IS
|
||
|
||
|
||
;--------------------------------------------------------------------
|
||
;
|
||
; ALLOCATE BUFFERS AND INIT STATE RECORDS FOR EACH NON-RECT REGION
|
||
; GET SEEK ROUTINE INTO SEEKMASK(A6)
|
||
; GET EXPAND ROUTINE INTO EXRTN(A6) FOR SEEK ROUTINE
|
||
; Clobbers: A0-A3, D0-D6
|
||
;
|
||
move.l stNoStackPtr,goShow(a6) ;pass go home routine to getSeek <BAL 21Mar89>
|
||
clr.l runBuf(a6) ;don't use run clipping <1.5> BAL
|
||
|
||
move.l dstmaskbuf(a6),d7 ;save dstmaskbuf
|
||
tst.w maskshift(a6) ;deep mask?
|
||
beq.s @dontTrickGetSeek ;branch if no
|
||
clr.l dstmaskbuf(a6) ;make seek think there is no mask
|
||
@dontTrickGetSeek
|
||
MOVE.L RGNC(A6),-(SP) ;PUSH USER RGNHANDLE (never TrimRect'ed)
|
||
MOVE.L RGNB(A6),-(SP) ;PUSH VIS RGNHANDLE
|
||
MOVE.L RGNA(A6),-(SP) ;PUSH CLIP RGNHANDLE
|
||
MOVE.L #2,-(SP) ;PUSH HANDLE COUNT - 1
|
||
_GETSEEK ;GET EXPAND ROUTINE INTO EXRTN(A6)
|
||
;AND SEEK ROUTINE INTO SEEKMASK(A6)
|
||
move.l d7,dstmaskbuf(a6) ;restore
|
||
;--------------------------------------------------
|
||
;
|
||
; CALCULATE CASE JUMP FOR DIFFERENT TRANSFER MODES
|
||
; GET INVERTFLAG INTO D7
|
||
;
|
||
SETMODE MOVE LOCMODE(A6),D0 ;GET THE MODE
|
||
BTST #5,D0 ;arithmetic mode?
|
||
BEQ.S @notArithMode
|
||
CMP #$40,D0 ;source modes are $20 … $27, $32
|
||
BGT DONE ;if bigger, undefined
|
||
BTST #3,D0 ;pattern?
|
||
BNE DONE
|
||
AND #$17,D0 ;consider only 8 mode variants
|
||
BCLR #4,D0 ;clear hilite bit
|
||
BEQ.S @notHilite
|
||
SUBQ #2,D0 ;hilite?
|
||
BNE DONE
|
||
ADDQ #8,D0 ;advance to hilite ($0C - 4)
|
||
@notHilite
|
||
cmp #16,dstPix+pixelSize(A6) ;dst 32 bits/pixel?
|
||
bge.s @useLoops16 ;yes, use alternate table
|
||
ADDQ #4,D0 ;advance past normal src modes
|
||
BRA.S @setupJump
|
||
|
||
@useLoops16
|
||
bne.s @useLoops32 ;yes, use alternate table
|
||
move.l stArith16TabPtr,A0 ;POINT TO 16 bit MODE TABLE
|
||
@getMode
|
||
BCLR #4,D0 ;clear hilite bit
|
||
add.l 0(A0,D0*4),A0 ;GET CASE JUMP ADDRESS
|
||
move.l a0,modeCase(a6) ;save for later
|
||
bra.s @gotMode
|
||
@useLoops32
|
||
move.l stArith32TabPtr,A0 ;POINT TO 32 bit MODE TABLE
|
||
bra.s @getMode
|
||
|
||
@notArithMode
|
||
MOVE.L INVERTFLAG(A6),D7 ;GET THE INVERT FLAG
|
||
BCLR #2,D0 ;CLEAR INVERT BIT
|
||
CMP #7,D0 ;IS MODE > 7 ?
|
||
BGT DONE ;YES, QUIT
|
||
@setupJump
|
||
LEA StretchModeTab,A0 ;POINT TO MODE TABLE (in trap table)
|
||
MOVE.L 0(A0,D0*4),MODECASE(A6) ;SAVE FOR LATER
|
||
@gotMode
|
||
|
||
;------------------------------------------------
|
||
;
|
||
; SET UP srcMergeCase.
|
||
;
|
||
@noPromote
|
||
move.w srcshift(a6),d3 ;src depth
|
||
lea VMergeTable,a0 ;get base
|
||
add.l (a0,d3.w*4),a0 ;get routine offset from base
|
||
move.l a0,srcMergeCase(a6)
|
||
|
||
SourceMergeSetupDone
|
||
;------------------------------------------------
|
||
;
|
||
; SET UP maskMergeCase
|
||
;
|
||
clr.l CombineMaskCase(a6) ;assume no mask
|
||
clr.l maskMergeCase(a6) ;assume no mask
|
||
tst.l maskbits(a6) ;is there a mask?
|
||
beq nomask1 ;=>NO
|
||
|
||
move.w maskshift(a6),d0 ;mask depth, currently 0, 4, or 5
|
||
lea VMergeTable,a0 ;get base
|
||
add.l (a0,d0.w*4),a0 ;get displacement to routine
|
||
move.l a0,maskMergeCase(a6)
|
||
|
||
|
||
MergeSetupDone
|
||
|
||
;------------------------------------------------
|
||
;
|
||
; set up CombineMaskCase
|
||
;
|
||
tst maskshift(a6)
|
||
beq.s CombineMaskSetupDone ;one bpp mask
|
||
;
|
||
; Table is disorganized as follows:
|
||
;
|
||
; SRC DST MASK ENTRY
|
||
; 32 ind 32 0
|
||
; 32 16 32 1
|
||
; 32 32 32 2
|
||
;
|
||
; calc routine based on dst
|
||
;
|
||
;
|
||
; want indexed values to goto 0, 16 bit to 1, 32 bit to 2
|
||
;
|
||
move dstshift(a6),d0
|
||
subq #3,d0
|
||
spl d1
|
||
and d1,d0
|
||
|
||
lea CombineTable,a0 ;get base
|
||
add.l (a0,d0.w*4),a0 ;get displacement to routine
|
||
move.l a0,CombineMaskCase(a6)
|
||
|
||
CombineMaskSetupDone
|
||
|
||
;------------------------------------------------
|
||
;
|
||
; SET UP MASKALIGN AND MASKADDR IF THERE IS A MASK
|
||
;
|
||
|
||
MOVE MASKSHIFT(A6),D3 ;GET MASKSHIFT
|
||
LEA MASKPIX(A6),A2 ;POINT TO MASKPIX
|
||
MOVE.L MASKROW(A6),D2 ;GET MASK ROWBYTES
|
||
|
||
MOVE.L MASKRECT(A6),A0 ;POINT TO MASKRECT
|
||
MOVE LEFT(A0),D1 ;GET MASKRECT LEFT
|
||
SUB BOUNDS+LEFT(A2),D1 ;CONVERT TO MASK GLOBAL
|
||
EXT.L D1 ;MAKE LONG FOR BIG PIXELS
|
||
lsl.l d3,d1 ;convert pixels to bits
|
||
MOVEQ #$1F,D5 ;TREAT MOD 32 FOR MASKALIGN
|
||
AND.L D1,D5 ;MAKE A COPY
|
||
MOVE.L D5,MASKALIGN(A6) ;SAVE ALIGNMENT OF MASK
|
||
|
||
MOVE TOP(A0),D0 ;GET MASKRECT TOP
|
||
SUB BOUNDS+TOP(A2),D0 ;CONVERT TO MASK GLOBAL
|
||
MULS D2,D0 ;MULT BY MASK ROWBYTES BAL 02Dec88
|
||
ADD.L BASEADDR(A2),D0 ;GET START OF MASK BITMAP
|
||
|
||
SUB.L D5,D1 ;ADJUST MASKLEFT FOR MASKALIGN
|
||
ASR.L #3,D1 ;CONVERT BITS TO BYTES
|
||
ADD.L D1,D0 ;ADD BYTES TO MASKADDR
|
||
MOVE.L D0,MASKADDR(A6) ;SAVE AS MASKADDR
|
||
|
||
|
||
NOMASK1
|
||
;----------------------------------------------------------
|
||
;
|
||
; Jump into 32 bit addressing mode for blitting. @@@@ BAL 09Apr88
|
||
;
|
||
|
||
moveq #true32b,d0 ;switch to 32 bit addressing @@@@ BAL 09Apr88
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
move.b d0,MMUsave(a6) ;save previous state for later @@@@ BAL 09Apr88
|
||
|
||
|
||
;------------------------------------------------
|
||
;
|
||
; SET UP SRCROW, SRCSCANS, SRCSHIFT, AND SRCADDR
|
||
;
|
||
MOVE realSRCSHIFT(A6),D3 ;GET SRCSHIFT
|
||
LEA SRCPIX(A6),A2 ;POINT TO SRCPIX
|
||
MOVE.L SRCROW(A6),D2 ;GET SRC ROWBYTES
|
||
|
||
MOVE BOUNDS+BOTTOM(A2),D1 ;GET SRCBITS.BOUNDS.BOTTOM
|
||
SUB BOUNDS+TOP(A2),D1 ;MAKE IT GLOBAL
|
||
MOVE D1,SRCSCANS(A6) ;SAVE NUMBER OF SCANS TO DO
|
||
|
||
MOVE.L SRCRECT(A6),A0 ;POINT TO SRCRECT
|
||
MOVE LEFT(A0),D1 ;GET SRCRECT LEFT
|
||
SUB BOUNDS+LEFT(A2),D1 ;CONVERT TO SRC GLOBAL
|
||
EXT.L D1 ;MAKE LONG FOR BIG PIXELS
|
||
LSL.L D3,D1 ;CONVERT SRC PIXELS TO BITS
|
||
MOVEQ #$1F,D5 ;TREAT MOD 32 FOR SRCSHIFT
|
||
AND.L D1,D5 ;MAKE A COPY
|
||
MOVE.L D5,SRCALIGN(A6) ;SAVE ALIGNMENT OF SOURCE
|
||
|
||
MOVE TOP(A0),D0 ;GET SRCRECT TOP
|
||
SUB BOUNDS+TOP(A2),D0 ;CONVERT TO SRC GLOBAL
|
||
MULS D2,D0 ;MULT BY SRC ROWBYTES BAL 02Dec88
|
||
ADD.L BASEADDR(A2),D0 ;GET START OF SRC BITMAP
|
||
|
||
SUB.L D5,D1 ;ADJUST SRCLEFT FOR SRCSHIFT
|
||
ASR.L #3,D1 ;CONVERT BITS TO BYTES
|
||
ADD.L D1,D0 ;ADD BYTES TO SRCADDR
|
||
MOVE.L D0,SRCADDR(A6) ;SAVE AS SRCADDR
|
||
|
||
if 0 then
|
||
|
||
; If srcAlign is a multiple of 8 there is no reason to make a copy of the src. <BAL 17Mar89>
|
||
|
||
tst d5
|
||
|
||
; and #7,d5 ;alignment required? <BAL 17Mar89>
|
||
bra.s @mustAlign
|
||
clr.l SRCALIGN(A6) ;remember to skip alignment pass <BAL 17Mar89>
|
||
clr.l dstBufBump(A6) ;init to no bump <BAL 17Mar89>
|
||
clr.l scaleBufBump(A6) ;init to no bump <BAL 17Mar89>
|
||
move.l SRCBUF(A6),d1 ;REMEMBER WHERE SRCBUF was <BAL 17Mar89>
|
||
move.l srcRow(a6),d2
|
||
sub.l d2,d0 ;anticipate initial bump <BAL 17Mar89>
|
||
move.l d0,srcBuf(a6) ;use srcAddr as srcBuf <BAL 17Mar89>
|
||
cmp.l DSTBUF(A6),d1 ;is dstBuf same as srcBuf? <BAL 17Mar89>
|
||
bne.s @mustAlign
|
||
move.l d0,dstBuf(a6) ;use srcAddr as dstBuf <BAL 17Mar89>
|
||
move.l d2,dstBufBump(a6) ;set up rowBump for dstBuf <BAL 17Mar89>
|
||
cmp.l SCALEBUF(A6),d1 ;is scaleBuf same as srcBuf? <BAL 17Mar89>
|
||
bne.s @mustAlign
|
||
move.l d0,scaleBuf(a6) ;use srcAddr as scaleBuf <BAL 17Mar89>
|
||
move.l d2,scaleBufBump(a6) ;set up rowBump for scaleBuf <BAL 17Mar89>
|
||
|
||
endif
|
||
|
||
@mustAlign
|
||
;----------------------------------------------------
|
||
;
|
||
; CALC STARTING DSTROW, DSTSHIFT, AND DSTADDR
|
||
;
|
||
MOVE DSTSHIFT(A6),D4 ;GET DST SHIFT
|
||
MOVE.L DSTROW(A6),D2 ;GET DST ROWBYTES
|
||
|
||
MOVE.L DSTRECT(A6),A0
|
||
MOVE TOP(A0),VERT(A6) ;INIT CURRENT VERTICAL
|
||
MOVE LEFT(A0),D1 ;GET DSTRECT LEFT
|
||
SUB BOUNDS+LEFT(A5),D1 ;CONVERT TO GLOBAL COORDS
|
||
EXT.L D1 ;MAKE LONG FOR BIG PIXELS
|
||
LSL.L D4,D1 ;CONVERT DST PIXELS TO BITS
|
||
MOVEQ #$1F,D6
|
||
AND.L D1,D6 ;TREAT MOD 32 FOR SHIFTCNT
|
||
NEG.L D6 ;AND NEGATE IT
|
||
MOVE.L D6,DSTALIGN(A6) ;SAVE FOR LATER
|
||
|
||
MOVE.L D6,D0 ;GET ALIGNMENT
|
||
ASR.L D4,D0 ;CONVERT TO PIXELS
|
||
MOVE.L D0,DSTMASKALIGN(A6) ;AND SAVE FOR MASK
|
||
|
||
MOVE MINRECT+TOP(A6),D0 ;GET MINRECT TOP
|
||
SUB BOUNDS+TOP(A5),D0 ;CONVERT TO GLOBAL COORDS
|
||
MULS D2,D0 ;MULT BY DST ROWBYTES BAL 02Dec88
|
||
ADD.L BASEADDR(A5),D0 ;GET START OF DST BITMAP
|
||
|
||
ASR.L #5,D1 ;CONVERT BITS TO LONGS
|
||
LSL.L #2,D1 ;AND BACK TO BYTES (MOD 4)
|
||
ADD.L D1,D0 ;ADD BYTES TO DSTADDR
|
||
MOVE.L D0,DSTADDR(A6) ;SAVE AS DSTADDR
|
||
|
||
_stScanLoop
|
||
|
||
|
||
|
||
stScanLoop
|
||
;-----------------------------------------------------
|
||
;
|
||
; Perform quick checks to see if we can use special cases
|
||
;
|
||
|
||
if 0 then ;<14SEP90 SMC>
|
||
|
||
tst.b FastCase(a6) ;FG Black, BG White, no scaling, copy mode, no mask?
|
||
beq.s @goSlow ;no, must go slow
|
||
|
||
CMP.W #8,DSTPIX+PIXELSIZE(A6) ;destination 8 bits/pixel?
|
||
BNE.S @ChkDst1Bit ;if not, skip
|
||
|
||
CMP.W #8,SRCPIX+PIXELSIZE(A6) ;src 8 bits/pixel?
|
||
BEQ CB8to8Clip ;yes, go fast
|
||
|
||
CMP.W #1,SRCPIX+PIXELSIZE(A6) ;src 1 bits/pixel?
|
||
BNE.S @goSlow
|
||
move.l ExTblPtr,A0 ;POINT TO ROUTINE TABLE
|
||
add.l 3*4(A0),A0 ;get 1 to 8 bit routine
|
||
CMP.L ScaleCase(a6),a0 ;standard 1 bit src?
|
||
BNE.S @goSlow
|
||
BRA CB1to8Clip
|
||
|
||
@ChkDst1Bit
|
||
CMP.W #1,DSTPIX+PIXELSIZE(A6) ;destination 8 bits/pixel?
|
||
BNE.S @goSlow ;if not, can't handle
|
||
|
||
CMP.W #8,SRCPIX+PIXELSIZE(A6) ;src 8 bits/pixel?
|
||
BEQ CB8to1Clip ;if not, skip
|
||
@goSlow
|
||
|
||
endif ;<14SEP90 SMC>
|
||
|
||
;-----------------------------------------------------
|
||
;
|
||
; INIT ERROR TERM FOR DDA
|
||
;
|
||
MOVE DENOM+V(A6),D0 ;get source height <5MAR90 KON>
|
||
cmp.w Numer+v(a6),d0 ;check against destination height <5MAR90 KON>
|
||
ble.s Expand ;src height <= destination : stretch <5MAR90 KON>
|
||
move d0,d1 ;save source height <5MAR90 KON>
|
||
ext.l d1 ;
|
||
divu.w numer+v(a6),d1 ;src MOD dst to high word of d1 <5MAR90 KON>
|
||
swap d1 ;get remainder in low word <5MAR90 KON>
|
||
tst d1 ;exact shrink? <5MAR90 KON>
|
||
bne.s Expand ; no, use general error <5MAR90 KON>
|
||
sub.w #1,d0 ;yes, use src height-1 <5MAR90 KON>
|
||
bra.s Expand1
|
||
Expand
|
||
lsr #1,d0
|
||
Expand1
|
||
neg d0
|
||
move d0, verror(a6)
|
||
move d0, maskerror(a6)
|
||
|
||
;
|
||
; Calc num destinations to skip, put in D1
|
||
;
|
||
SKIPDST
|
||
moveq #0,d3 ;assume starting on line 0 in source
|
||
move.l srcaddr(A6),a3 ;get source address in register
|
||
MOVE MINRECT+TOP(A6),D1 ;
|
||
SUB VERT(A6),D1 ;Clipped scans at top
|
||
BLE @DontSkipSource ;no, DST NOT CLIPPED
|
||
;
|
||
; Skip source while error is negative, D3 contains number of source scans to skip
|
||
;
|
||
@nxtSrc MOVE.L MASKROW(A6),D0 ;GET MASK ROWBYTES
|
||
ADD.L D0,MASKADDR(A6) ;BUMP MASK TO NEXT ROW, even if there isn't one
|
||
MOVE.L SRCROW(A6),D2 ;GET SRC ROWBYTES
|
||
|
||
ADD.L D2,a3 ;BUMP SRC TO NEXT ROW
|
||
addq #1,d3 ;number of source scan lines skipped
|
||
MOVE maskNumer+V(A6),D0 ;update mask error: assume same as source
|
||
ADD D0,maskError(A6)
|
||
MOVE numer+V(A6),D0 ;GET NUMER.V
|
||
ADD D0,verror(A6) ;VERROR := VERROR + NUMER.V
|
||
ble.s @nxtSrc ;SKIP IF VERROR > 0
|
||
|
||
;
|
||
;Error is +, skip destinations until we've skipped D1 of them
|
||
;
|
||
MOVE DENOM+V(A6),D0 ;src height
|
||
move maskDenom+v(a6),d2
|
||
@nxtDst ADD #1,VERT(A6) ;BUMP TO NEXT VERTICAL on dest
|
||
sub d2,maskerror(a6) ;update mask error: assume same as source
|
||
SUB D0,VERROR(A6) ;VERROR := VERROR - DENOM.V
|
||
subq.w #1,d1 ;dst lines to skip
|
||
ble.s @ReadyToDraw
|
||
tst.w VERROR(A6)
|
||
blt.s @nxtSrc
|
||
bra.s @nxtDst ;IF MORE, THEN CONTINUE
|
||
|
||
@ReadyToDraw
|
||
tst.w VERROR(A6) ;don't bump further than we need to
|
||
ble.s @DestIsOK ; <63>
|
||
move.L SRCROW(A6),D2 ;GET SRC ROWBYTES
|
||
sub.L d2,a3 ;bump src to previous row
|
||
move.L MASKROW(A6),D0 ;GET SRC ROWBYTES
|
||
sub.L D0,MASKADDR(A6) ;BUMP SRC TO NEXT ROW
|
||
subq #1,d3 ;number of source scan lines skipped
|
||
move NUMER+V(A6),D0 ;GET NUMER.V
|
||
if not(TheFuture) then ; <60> Build old code for now
|
||
move maskDenom+v(a6),d2 ; <60>
|
||
endif ; <60>
|
||
if TheFuture then ; <60> New code for later
|
||
move maskNumer+v(a6),d2 ; <59>
|
||
endif ; <60>
|
||
sub d2,maskerror(a6)
|
||
sub D0,VERROR(A6) ;VERROR := VERROR + NUMER.V
|
||
bgt.s @ReadyToDraw ;
|
||
|
||
|
||
@DestIsOK
|
||
;
|
||
; here d3 contains number of first src line (# of src lines skipped)
|
||
; a3 contains starting address
|
||
;
|
||
@DontSkipSource
|
||
_pmVersionSrcFirstTime ;D3 contains starting scan line no.
|
||
move.l a3,srcaddr(a6) ;put src address back
|
||
|
||
_pmVersionMaskFirstTime ;D3 contains starting scan line no.
|
||
;-----------------------------------------------------
|
||
;
|
||
; GET FIRST SCANLINE OF SRC INTO SRCBUF
|
||
;
|
||
NEXTSRC TST SRCSCANS(A6) ;ANY SCANS LEFT?
|
||
BLE DONE ;=>NO, QUIT
|
||
|
||
|
||
;-----------------------------------------------------
|
||
;
|
||
; Do MergeCase moves a line of source into srcbuf and does vertical
|
||
; averaging if necessary.
|
||
;
|
||
; Do MergeCase for vertical shrinking of mask
|
||
; Do MergeCase for vertical shrinking of src
|
||
;
|
||
; Clobbers: D0-D4,D6,D7,A0,A1
|
||
;
|
||
DoMergeCase
|
||
;
|
||
; Calculate 0-based scanline count in d7.
|
||
;
|
||
move.l maskMergeCase(a6),d0
|
||
beq.s DoSrcMergeCase ;no mask
|
||
move.l d0,a0
|
||
|
||
moveq #-1,d7
|
||
move srcscans(a6),d1
|
||
move masknumer+v(a6),d0
|
||
@AnotherLine
|
||
addq #1,d7
|
||
subq #1,d1
|
||
blt.s @maskDone
|
||
add d0,maskerror(a6)
|
||
ble.s @AnotherLine ;done when maskerror > 0
|
||
@maskDone
|
||
moveq #0,d4 ;clear high word of srclongs <17JUL90 KON>
|
||
move.w srcmasklongs(a6),d4
|
||
move.l maskalign(a6),d5
|
||
move.w maskPix+pixelSize(a6),d6
|
||
|
||
move.l srcmaskbuf(a6),a2 ;dest buffer pointer
|
||
move.l maskaddr(a6),a3
|
||
move.l MaskPixPmTable(a6),a4
|
||
; move.l maskpix+pmTable(a6),a4
|
||
; move.l (a4),a4 ;get pointer to color table
|
||
move.l maskrow(a6),a5 ;row bytes
|
||
jsr (a0) ;returns to DoSrcMergeCase
|
||
move.l a3,maskaddr(a6)
|
||
|
||
DoSrcMergeCase
|
||
;
|
||
; Calculate 0-based scanline count in d7.
|
||
;
|
||
moveq #-1,d7 ;
|
||
@AnotherLine
|
||
addq #1,d7
|
||
subq #1,srcscans(A6)
|
||
blt.s @srcScansDone
|
||
move numer+v(a6),d0
|
||
add d0,verror(a6)
|
||
ble.s @AnotherLine ;done when verror > 0
|
||
@srcScansDone
|
||
moveq #0,d4 ;clear high word of srclongs <17JUL90 KON>
|
||
move.w srclongs(a6),d4
|
||
move.l srcalign(a6),d5
|
||
move.w srcPix+pixelSize(a6),d6
|
||
tst.b realDepth(a6) ;promoting src to RGB?
|
||
bmi.s @notPromoting ;no, all ok
|
||
move.w realDepth(a6),d6
|
||
@notPromoting
|
||
move.l srcbuf(a6),a2 ;dest buffer pointer
|
||
move.l srcaddr(a6),a3
|
||
|
||
move.l SrcPixPmTable(a6),a4
|
||
; move.l (a4),a4 ;get pointer to color table
|
||
move.l srcrow(a6),a5 ;row bytes
|
||
move.l srcMergeCase(a6),a0
|
||
jsr (a0)
|
||
move.l a3,srcaddr(a6)
|
||
;
|
||
; srcbuf is setup and shrunk, do colorizing if necessary.
|
||
; this is done when the source is direct and the XLateFlag is setup by mapModeTable
|
||
;
|
||
btst #ColorizeInSrcBufBit, XLateFlag(a6) ; Colorize during expansion?
|
||
beq.s @ColorizeDone ;branch if no
|
||
|
||
move.w srclongs(a6),d1
|
||
move.l srcbuf(a6),a2 ;dest buffer pointer
|
||
move.l RGBFrColor(A6),D4 ;GET FG COLOR
|
||
move.l RGBBgColor(A6),D3 ;GET BK COLOR
|
||
@ColorMe
|
||
move.l (a2),d2
|
||
;
|
||
; colorize, the fg/bk are in RGB space and hence switched
|
||
;
|
||
move.l d2,d7 ;copy source
|
||
AND.L D3,D2 ;ADD BG COLOR TO SRC
|
||
NOT.L d7 ;GET NOT SRC
|
||
AND.L D4,d7 ;ADD FG COLOR TO NOT SRC
|
||
OR.L D2,d7 ;COMBINE FG/BK DATA
|
||
|
||
MOVE.L d7,(A2)+ ;put a long to destination
|
||
DBRA D1,@ColorMe ;loop for all longs
|
||
|
||
@ColorizeDone
|
||
SRCOK
|
||
MOVE.L DSTALIGN(A6),D6 ;RESTORE DSTALIGN
|
||
MOVE.L INVERTFLAG(A6),D7 ;RESTORE INVERT FLAG
|
||
|
||
;----------------------------------------------------------
|
||
;
|
||
; HORIZONTALLY STRETCH SRCBUF INTO DSTBUF
|
||
;
|
||
; USES: D0:(CLOBBERED) D1:(CLOBBERED) D2:(CLOBBERED) D3:(CLOBBERED)
|
||
; D4:(CLOBBERED) D5:(DSTPIXSIZE) D6:!DSTALIGN D7:!(INVERTFLAG)
|
||
; A0:(CLOBBERED) A1:(CLOBBERED) A2:(MASKADDR) A3:(CASEJUMP)
|
||
; A4:(SRCLONGS) A5: A6: A7:
|
||
;
|
||
MOVE NUMER+H(A6),D0 ;GET DST WIDTH
|
||
CMP DENOM+H(A6),D0 ;SAME AS SRC WIDTH?
|
||
BEQ.S SOK ;=>YES, NO STRETCHING NEEDED
|
||
MOVE DSTLONGS(A6),D0 ;GET DSTLONGS
|
||
MOVE.L SRCBUF(A6),A0 ;POINT TO SRCBUF
|
||
MOVE.L DSTBUF(A6),A1 ;POINT TO DSTBUF
|
||
LEA 4(A1,D0*4),A2 ;SET UP DSTLIMIT
|
||
MOVE HORIZFRACTION(A6),D4 ;GET HORIZONTAL FRACTION
|
||
MOVE SRCPIX+PIXELSIZE(A6),D5 ;GET SIZE OF DST PIXELS (= SRC PIXELS)
|
||
;
|
||
; if it's a deep mask and the pixel depth is 16, then it's really 32 bpp
|
||
;
|
||
cmp #16,d5
|
||
bne.s @allok
|
||
move.w maskshift(a6),d2 ;deep mask?
|
||
cmp #4,d2
|
||
blt.s @allok ;not deep mask, don't change pix depth
|
||
move.w #32,d5 ;really 32 bpp
|
||
@allok
|
||
MOVE.L RATIOCASE(A6),A3 ;GET CASE JUMP
|
||
MOVEQ #0,D0 ;CASE JUMP ROUTINE USES BYTE
|
||
JSR (A3) ;AND CALL STRETCHROW
|
||
|
||
|
||
;----------------------------------------------------------
|
||
;
|
||
; HORIZONTALLY STRETCH SRCMASKBUF INTO DSTMASKBUF
|
||
;
|
||
; USES: D0:(CLOBBERED) D1:(CLOBBERED) D2:(CLOBBERED) D3:(CLOBBERED)
|
||
; D4:(CLOBBERED) D5:(DSTPIXSIZE) D6:!DSTALIGN D7:!(INVERTFLAG)
|
||
; A0:(CLOBBERED) A1:(CLOBBERED) A2:(MASKADDR) A3:(CASEJUMP)
|
||
; A4:(SRCLONGS) A5: A6: A7:
|
||
;
|
||
SOK MOVE MASKNUMER+H(A6),D0 ;GET DSTMASK WIDTH
|
||
CMP MASKDENOM+H(A6),D0 ;SAME AS SRCMASK WIDTH?
|
||
BEQ.S @DoMasking ;=>YES, NO STRETCHING NEEDED
|
||
MOVE DSTMASKLONGS(A6),D0 ;GET NUMBER OF LONGS
|
||
MOVE.L SRCMASKBUF(A6),A0 ;POINT TO SRCMASKBUF
|
||
MOVE.L DSTMASKBUF(A6),A1 ;POINT TO DSTMASKBUF
|
||
LEA 4(A1,D0*4),A2 ;SET UP DSTLIMIT
|
||
MOVE MASKFRACT(A6),D4 ;GET HORIZONTAL FRACTION
|
||
MOVE maskpix+pixelsize(a6),d5 ;***GET PIXELSIZE
|
||
cmp.w #1,d5 ;is it 1?
|
||
beq.s @sizeok ;if yes, leave it alone
|
||
moveq #32,d5 ;otherwise it's really 32
|
||
@sizeok
|
||
MOVE.L MASKCASE(A6),A3 ;GET CASE JUMP
|
||
MOVEQ #0,D0 ;CASE JUMP ROUTINE USES BYTE
|
||
JSR (A3) ;AND CALL STRETCHROW
|
||
|
||
@DoMasking
|
||
;----------------------------------------------------------
|
||
;
|
||
; Combine src and dest using mask. Only called for deep masks
|
||
;
|
||
; USES: D0: D1: D2: D3:
|
||
; D4: D5:!dstAlign D6:dst pixel size D7:pixel count
|
||
; A0: scratch A1:mask ptr A2:destination A3: src and dst ptr
|
||
; A4: src pmtable A5: not used A6: not used A7: not used
|
||
;
|
||
move.l CombineMaskCase(a6),d0
|
||
beq.s dstok ;no mask merging
|
||
move.l d0,a0 ;merge routine address
|
||
|
||
move.l dstalign(a6),d5 ;get !dstalign
|
||
neg.l d5
|
||
|
||
move.l dstbuf(a6),a3
|
||
move numer+h(a6),d7 ;number of pixels to do (width of dest)
|
||
move.l dstmaskbuf(a6),a1
|
||
move.l dstaddr(a6),a2 ;destination
|
||
move.l dstPix+pmTable(a6),a4
|
||
move.l (a4),a4 ;get clutptr
|
||
|
||
move.w dstpix+pixelsize(a6),d6 ;1, 2, 4, 8, 16, 32
|
||
|
||
jsr (a0) ;combine src w/ dst using mask
|
||
|
||
|
||
;----------------------------------------------------------
|
||
;
|
||
; Change dstbuf depth to destination depth and put result in scalebuf
|
||
;
|
||
; USES: D0:(CLOBBERED) D1:(CLOBBERED) D2:(CLOBBERED) D3:!(SRCPIXSIZE)
|
||
; D4:!(DSTPIXSIZE)D5:(CLOBBERED) D6:!DSTALIGN D7:!INVERTFLAG
|
||
; A0:(DSTBUF) A1:(SCALEBUF) A2:(DSTLIMIT) A3:
|
||
; A4:!(SCALETBL) A5:! A6:! A7:!
|
||
;
|
||
DSTOK move.l dstalign(a6),d6
|
||
MOVE.L INVERTFLAG(A6),D7 ;GET THE INVERT FLAG
|
||
MOVE.L SCALECASE(A6),D1 ;NEED TO EXPAND PIXELS?
|
||
BEQ.S NXTMASK ;=>NO, DON'T BOTHER STRETCHING
|
||
MOVE SRCPIX+PIXELSIZE(A6),D3 ;GET SOURCE PIXEL SIZE
|
||
;
|
||
; if it's a deep mask and the pixel depth is 16, then it's really 32 bpp
|
||
;
|
||
cmp #16,d3
|
||
bne.s @allok
|
||
tst.w maskshift(a6) ;deep mask?
|
||
beq.s @allok ;not deep mask, don't change pix depth
|
||
move.w #32,d3 ;really 32 bpp
|
||
@allok
|
||
|
||
MOVE DSTPIX+PIXELSIZE(A6),D4 ;GET DST PIXEL SIZE
|
||
MOVE.L DSTBUF(A6),A0 ;POINT TO SRC
|
||
MOVE.L SCALEBUF(A6),A1 ;POINT TO DST
|
||
MOVE SCALELONGS(A6),D0 ;GET SIZE
|
||
LEA 4(A1,D0*4),A2 ;SET UP DSTLIMIT
|
||
MOVE.L D1,A3 ;GET CASE JUMP ROUTINE
|
||
MOVE.L ScaleTbl(A6),A4 ;POINT TO TRANSLATION TABLE
|
||
MOVEQ #0,D0 ;CASE JUMP ROUTINE USES BYTE
|
||
JSR (A3) ;AND CALL STRETCHROW
|
||
|
||
|
||
;-------------------------------------------------------
|
||
;
|
||
; TRANSFER ONE OR MORE COPIES OF SCALEBUF INTO DSTBITS
|
||
;
|
||
; USES: D0: D1: D2: D3:!(FGCOLOR)
|
||
; D4:!(BKCOLOR) D5:arith stuff D6:!DSTALIGN D7:!INVERTFLAG
|
||
; A0: A1: A2: A3:
|
||
; A4: A5:arith stuff A6: A7:
|
||
;
|
||
NXTMASK MOVE.L FCOLOR(A6),D3 ;GET FG COLOR
|
||
MOVE.L BCOLOR(A6),D4 ;GET BK COLOR
|
||
BTST #5,locMode+1(A6) ;an arithmetic mode?
|
||
BEQ.S @skipArith
|
||
|
||
MOVEQ #0,D7
|
||
MOVE dstPix+pixelSize(A6),D7 ;get the number of bits in a pixel
|
||
MOVEQ #32,D5
|
||
DIVU D7,D5 ;# of pixels in a long
|
||
|
||
if 0 then ; don't colorize arithmetic modes anymore
|
||
; color the source first
|
||
; color only if colorizing in mode case
|
||
|
||
@doColor
|
||
BTST #ColorizeInModeCaseBit, XLateFlag(a6)
|
||
beq.s @skipColor
|
||
|
||
cmp #36,locMode(A6) ;transparent mode? ** should be an equ ** <<PB465 BAL>>
|
||
beq.s @skipColor ;if so, skip colorizing. <KON>
|
||
|
||
MOVE.L SCALEBUF(A6),A3 ;INIT SRCPTR
|
||
MOVE BUFSIZE(A6),D2 ;INIT COUNT OF LONGS
|
||
@nxtSrc
|
||
MOVE.L (A3),D0 ;get a long from source
|
||
move.l d0,d1
|
||
AND.L D3,D0 ;ADD FG COLOR TO SRC
|
||
NOT.L d1 ;GET NOT SRC
|
||
AND.L D4,d1 ;ADD BK COLOR TO NOT SRC
|
||
OR.L D0,d1 ;COMBINE FG/BK DATA
|
||
move.l d1,(A3)+ ;write it out
|
||
SUB D5,D2 ;do for all of the pixels on this row
|
||
BGE.S @nxtSrc
|
||
@skipColor
|
||
endif
|
||
|
||
MOVE.L colorTable(A6),A5 ;set up for arithmetic modes
|
||
CMP #$24,locMode(A6) ;transparent?
|
||
BNE.S @skipArith ;if not, regs are fine
|
||
BFEXTU transColor(A6){0:D7},D0
|
||
MOVE.L D0,A5
|
||
@skipArith
|
||
|
||
NXTMSK1 MOVE VERT(A6),D0 ;GET CURRENT VERT COORD
|
||
CMP MINRECT+TOP(A6),D0 ;IS VERT < MINV ?
|
||
BLT.S NODRAW ;YES, DON'T DRAW
|
||
;
|
||
; if mask is >1 bit/pixel, trick seek into ignoring mask by zeroing dstmaskbuf
|
||
;
|
||
move.l dstmaskbuf(a6),a4 ;save dstmaskbuf <KON 9JAN90>
|
||
tst maskshift(a6)
|
||
beq.s @NoTrickorTreat
|
||
clr.l dstmaskbuf(a6) ;make seek think there is no mask
|
||
@NoTrickorTreat
|
||
JSR ([SEEKMASK,A6]) ;MAKE MASK BUFFER CURRENT
|
||
|
||
move.l a4,dstmaskbuf(a6) ; <KON 9JAN90>
|
||
|
||
MOVE.L SCALEBUF(A6),A3 ;INIT SRCPTR
|
||
MOVE.L DSTADDR(A6),A4 ;INIT DSTPTR FOR ROW
|
||
MOVE.L RGNBUFFER(A6),A2 ;INIT MASKPTR FOR ROW
|
||
MOVE BUFSIZE(A6),D2 ;INIT COUNT OF LONGS
|
||
MOVE.L MODECASE(A6),A0 ;GET MODE CASE JUMP
|
||
BTST #5,locMode+1(A6) ;an arithmetic mode?
|
||
BEQ.S @skipArith
|
||
MOVE.L transColor(A6),D4 ;set up transparent color in case different from bg
|
||
CMP #$24,locMode(A6) ;transparent?
|
||
BEQ.S @skipInvTbl ;if so, D5 contains the pixels per long value
|
||
MOVE invSize(A6),D5 ;set up resolution of inverse table for arith. modes
|
||
@skipInvTbl
|
||
MOVEQ #0,D3 ;initialize destination pixel offset
|
||
MOVE.L dstAlign(A6),D6 ;reset alignment since it is bumped by arith. modes
|
||
SUB.L D7,D6 ;bump source pixel offset back by 1
|
||
@skipArith
|
||
CMP.L DSTPIX+BASEADDR(A6),A4 ;IS IT BEFORE THE PIXMAP?
|
||
BLO.S DSTNEG ;=>YES, DON'T PUT TO DST
|
||
DOBLT JMP (A0) ;TAKE MODE JUMP
|
||
NEXTDST MOVE.L DSTROW(A6),D0 ;GET DST ROWBYTES
|
||
ADD.L D0,DSTADDR(A6) ;BUMP DST TO NEXT ROW
|
||
|
||
NODRAW ADD #1,VERT(A6) ;BUMP TO NEXT VERT
|
||
MOVE VERT(A6),D0 ;GET VERT
|
||
CMP MINRECT+BOTTOM(A6),D0 ;ARE WE AT THE LAST SCAN LINE ?
|
||
BEQ.S DONE ;YES, QUIT
|
||
MOVE maskdenom+V(A6),D0 ;update mask error
|
||
SUB D0,maskERROR(A6)
|
||
MOVE DENOM+V(A6),D0
|
||
SUB D0,VERROR(A6) ;VERROR := VERROR - DENOM.V
|
||
BLT NEXTSRC ;IF VERROR < 0 THEN GET NEXT SRC <BAL 19Mar89>
|
||
tst.b useDither(a6) ; are we dithering? <BAL 19Mar89>
|
||
bne.s dstOK ; yes dither this scan again with current error <BAL 19Mar89>
|
||
BRA NXTMSK1 ;ELSE continue to draw from this src <BAL 19Mar89>
|
||
|
||
;-----------------------------------------------------------------
|
||
;
|
||
; HANDLE CASE WHERE DST IS NEGATIVE
|
||
;
|
||
DSTNEG MOVE.L DSTPIX+BASEADDR(A6),D1 ;GET ELUSIVE BASE ADDRESS
|
||
BTST #5,locMode+1(A6) ;AN ARITHMETIC MODE?
|
||
BEQ.S @NoRith ;=>NOPE, DO NORMAL
|
||
|
||
; IF ARITHMETIC MODE, BUMP ONE PIXEL AT A TIME UNTIL DST ISN'T NEGATIVE
|
||
|
||
@LOOP LEA 0(A4,D3),A1 ;GET CURRENT ADDRESS
|
||
CMP.L A1,D1 ;ARE WE STILL NEGATIVE?
|
||
BLS.S DOBLT ;=>NO, BLIT REST OF SCANLINE
|
||
SUBQ #1,D2 ;SKIP A DOT
|
||
BMI.S NEXTDST ;=>DONE WITH SCANLINE
|
||
ADD.L D7,D6 ;BUMP SRC POINTER ONE DOT
|
||
ADD.L D7,D3 ;BUMP DST POINTER ONE DOT
|
||
BRA.S @LOOP ;=>YES, KEEP SKIPPING
|
||
|
||
; IF NORMAL MODE, BUMP ONE LONG AT A TIME UNTIL DST ISN'T NEGATIVE
|
||
|
||
@NoRith LEA 4(A4),A1 ;GET NEXT LONG OF DST
|
||
CMP.L A1,D1 ;ARE WE STILL NEGATIVE
|
||
BLS.S DOBLT ;=>NO, BLIT REST OF SCANLINE
|
||
SUBQ #1,D2 ;SKIP NEXT LONG
|
||
BMI.S NEXTDST ;=>DONE WITH SCANLINE
|
||
ADDQ.L #4,A2 ;BUMP MASKPTR
|
||
ADDQ.L #4,A3 ;BUMP SRCPTR
|
||
ADDQ.L #4,A4 ;BUMP DSTPTR
|
||
BRA.S @NoRith ;=>TRY, TRY AGAIN
|
||
|
||
;-----------------------------------------------------------------
|
||
;
|
||
; ENTIRE STRETCHBITS COMPLETE. RESTORE REGS AND STACK AND GO HOME.
|
||
;
|
||
DoneStretch
|
||
DONE clr.w QDErr ;signal no error
|
||
doneErr move.b MMUsave(a6),d0 ;get previous MMU state in d0
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
SHOW MOVE.L SAVEA5(A6),A5 ;RESTORE A5
|
||
TST.B CRSRFLAG(A6) ;DID WE SHIELD THE CURSOR?
|
||
BEQ.S GOHOME ;=>NO, JUST RETURN
|
||
_SHOWCURSOR ;RESTORE CURSOR
|
||
GOHOME BSET #hiliteBit,HiliteMode ;reset hilite override, in case colormap was skipped
|
||
MOVE.L SAVESTK(A6),SP ;STRIP VARIABLE SIZED BUFFER
|
||
move.l stackHandle(a6),d0 ;did we allocate a handle?
|
||
beq.s @noTemp ;no, forget it.
|
||
move.l d0,a0 ;pass handle in a0
|
||
_DisposeTempBuffer ;dispose it.
|
||
move.l saveStkLowPt(a6),stkLowPt ;restart the sniffer <57>
|
||
move.l oldHiHeapMark(a6),HiHeapMark ;restore extent of stack
|
||
@noTemp MOVEM.L (SP)+,D0-D7/A1-A5 ;RESTORE REGISTERS
|
||
UNLINK PARAMSIZE,'STRETCHB'
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
|
||
stNoStack
|
||
tst.l StackFree(a6) ;did we run out of stack?
|
||
bpl.s SHOW ;no, just go home
|
||
movem.l d0-d3/a0-a2,-(sp) ;save state
|
||
neg.l d0 ;<BAL and KON 14Feb90>
|
||
move.l d0,stackFree(a6) ;<BAL and KON 14Feb90>
|
||
tst.l stackHandle(a6) ;have we been here before?
|
||
bne.s @noMem ;yes, forget it.
|
||
|
||
move.l HiHeapMark,oldHiHeapMark(a6) ;save extent of stack
|
||
moveq #4,d0 ; <KON 14Feb90>
|
||
swap d0 ;try for 256K <BAL 14Feb90>
|
||
_NewTempBuffer ;returns a0=handle, d0=size
|
||
move.l d0,d2 ;copy the actual size
|
||
beq.s @noMem ;if zero, we didn't get it.
|
||
@gotit move.l a0,stackHandle(a6) ;remember to dispose it later
|
||
sub.l #qdStackXtra,d2 ;leave room for interrupts
|
||
asr.l #2,d2 ;make cnt of longs
|
||
add.l d2,stackFree(a6) ;new free cnt
|
||
bmi.s @noMem ;didn't get enough
|
||
clr.l stkLowPt ;disable stack sniffer
|
||
move.l a7,a2 ;remember where save regs are
|
||
move.l (a0),a0 ;get ptr
|
||
exg a0,d0 ;get ptr in d0, size in a0
|
||
_rTranslate24To32 ;strip it
|
||
move.l d0,HiHeapMark ;set up stack limit for _stackSpace
|
||
add.l d0,a0 ;point to end of block
|
||
move.l 7*4(a7),-(a0) ;copy over return address
|
||
move.l a0,a7 ;move the stack there
|
||
|
||
movem.l (a2),d0-d3/a0-a2 ;restore state
|
||
rts
|
||
|
||
@noMem move.w #nsStackerr,QDErr
|
||
bra.s SHOW
|
||
|
||
;******************************************************************************************
|
||
|
||
;--------------------------------------------
|
||
;
|
||
; Source scanline merge routines.
|
||
; There are 3 routines: OneDeep, NDeep, and Average16and32
|
||
; These routines copy from srcaddr to srcbuf and do vertical
|
||
; merging of source if necessary.
|
||
;
|
||
; When promoting source (ie dither mode) to 32 bit/pixel, Average16and32
|
||
; is called.
|
||
;
|
||
; EXPECTS: D0: D1: D2: D3:
|
||
; D4: D5:!SRCALIGN D6:!DSTALIGN D7:!INVERTFLAG
|
||
; A0: A1: A2: A3:
|
||
; A4: A5: A6: A7:
|
||
;--------------------------------------------
|
||
|
||
|
||
VMergeTable
|
||
dc.l oneDeep-VMergeTable ;src 1-bit/pixel
|
||
dc.l ndeep-VMergeTable ;src 2-bit/pixel
|
||
dc.l ndeep-VMergeTable ;src 4-bit/pixel
|
||
dc.l ndeep-VMergeTable ;src 8-bit/pixel
|
||
dc.l Average16and32-VMergeTable ;src 16-bit/pixel
|
||
dc.l Average16and32-VMergeTable ;src 32-bit/pixel
|
||
|
||
;--------------------------------------------
|
||
;
|
||
; Loop to combine d7 pixels of source and dest using mask
|
||
;
|
||
; ENTRY:
|
||
; D0: scratch A0: scratch
|
||
; D1: scratch A1: mask ptr
|
||
; D2: scratch A2: destination
|
||
; D3: scratch A3: src and dst ptr
|
||
; D4: scratch A4: src pmtable A5: rowbytes
|
||
; D5: srcAlign A5: rowbytes
|
||
; D6: realDepth (pixel size)
|
||
; D7: byte Count (zero based)
|
||
;
|
||
; There are 12 different cases: all combinations of source and mask
|
||
; being either 16- or 32-bits/pixel and dest being any depth. A mask
|
||
; of $ff means take source. The mask value ranges from 0-$7f,$81-$100.
|
||
|
||
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’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
|
||
|
||
;——————————————————————————————————————————————————————
|
||
; 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
|
||
|
||
|
||
; 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
|
||
|
||
;——————————————————————————————————————————————————————
|
||
; 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
|
||
lsr.w #1,d1 ;get almost 1/2 of it
|
||
and.w d0,d1 ;mask out stragglers
|
||
|
||
move.w (a1),d5 ;get dest pixel
|
||
and.w d5,d3 ;compute carry out of lsb
|
||
lsr.w #1,d5 ;get almost 1/2 of it
|
||
and.w d0,d5 ;mask out stragglers
|
||
|
||
add.w d5,d1 ;merge src with dst
|
||
add.w d3,d1 ;propagate carrys
|
||
MOVE.w d1,(a1) ;write pattern to dest
|
||
|
||
@skip2 addq.l #2,a1 ;bump dst ptr
|
||
addq.l #2,d6 ;bump src index
|
||
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
||
DBRA D2,@blit2 ;LOOP ALL LONGS THIS ROW
|
||
BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;--------------------------------------------
|
||
;
|
||
; Mode: 36 Transparent for 16 bits/pixel
|
||
;
|
||
;-------------------------------------------------------
|
||
; a0 = d0 =
|
||
; a1 = dstPtr d1 = src pixel
|
||
; a2 = maskPtr d2 = run cnt
|
||
; a3 = patPtr d3 =
|
||
; a4 = d4 = patHMask
|
||
; a5 = d5 = backColor
|
||
; a6 = locals d6 = pattern offset
|
||
; a7 = d7 =
|
||
;-------------------------------------------------------
|
||
stTransparent16
|
||
BSR arithSetup16 ;set up registers for slab bitblt
|
||
|
||
move.l transColor(A6),D5 ;get a pixel of the transparent color
|
||
|
||
@blit tst.w (A2)+ ;a pixel of the clip region
|
||
BEQ.S @skip
|
||
move.w 0(a3,d6),d1 ;get src pixel
|
||
|
||
cmp.w d1,d5 ;is src backColor?
|
||
beq.s @skip ;yes, don't write to dst
|
||
MOVE.w d1,(a1) ;write pattern to dest
|
||
|
||
@skip addq.l #2,a1 ;bump dst ptr
|
||
addq.l #2,d6 ;bump src index
|
||
; and.w d4,d6 ;constrict to the source long if in a pattern mode
|
||
DBRA D2,@blit ;LOOP ALL LONGS THIS ROW
|
||
BRA NEXTDST ;LOOP FOR NEXT ROW
|
||
|
||
|
||
|
||
|
||
|
||
IF 0 THEN
|
||
MODETAB DC.W MODETAB-MASK0
|
||
DC.W MODETAB-MASK1
|
||
DC.W MODETAB-MASK2
|
||
DC.W MODETAB-MASK3
|
||
|
||
DC.W ModeTab-Avg ;8 AVG(SRC, DST, WEIGHT) --> DST
|
||
DC.W ModeTab-AddPin ;A SRC + DST --> DST (pin to max)
|
||
DC.W ModeTab-AddOver ;C SRC + DST --> DST (no pin)
|
||
DC.W ModeTab-SubPin ;E DST - SRC --> DST (pin to min)
|
||
DC.W ModeTab-Transparent ;10 SRC less bg --> DST
|
||
DC.W ModeTab-Max ;12 MAX(SRC, DST) --> DST
|
||
DC.W ModeTab-SubOver ;14 DST - SRC --> DST (no pin)
|
||
DC.W ModeTab-Min ;16 MIN(SRC, DST) --> DST
|
||
DC.W ModeTab-Hilite ;18 src as mask, bg <--> hilite
|
||
ENDIF
|
||
|
||
Align 4
|
||
|
||
stArith16Tab
|
||
DC.L stAvg16-stArith16Tab ;10 AVG(PAT, DST, WEIGHT) --> DST
|
||
DC.L stAddPin16-stArith16Tab ;12 PAT + DST --> DST (pin to max)
|
||
DC.L stAddOver16-stArith16Tab ;13 PAT + DST --> DST (no pin)
|
||
DC.L stSubPin16-stArith16Tab ;16 DST - PAT --> DST (pin to min)
|
||
DC.L stTransparent16-stArith16Tab ;18 PAT less bg --> DST
|
||
DC.L stMax16-stArith16Tab ;1A MAX(PAT, DST) --> DST
|
||
DC.L stSubOver16-stArith16Tab ;1C DST - PAT --> DST (no pin)
|
||
DC.L stMin16-stArith16Tab ;1E MIN(PAT, DST) --> DST
|
||
DC.L stHilite-stArith16Tab ;20 (pat as mask) hilite <--> background
|
||
|
||
stArith32Tab
|
||
DC.L stAvg32-stArith32Tab ;10 AVG(PAT, DST, WEIGHT) --> DST
|
||
DC.L stAddPin32-stArith32Tab ;12 PAT + DST --> DST (pin to max)
|
||
DC.L stAddOver32-stArith32Tab ;13 PAT + DST --> DST (no pin)
|
||
DC.L stSubPin32-stArith32Tab ;16 DST - PAT --> DST (pin to min)
|
||
DC.L stTransparent32-stArith32Tab ;18 PAT less bg --> DST
|
||
DC.L stMax32-stArith32Tab ;1A MAX(PAT, DST) --> DST
|
||
DC.L stSubOver32-stArith32Tab ;1C DST - PAT --> DST (no pin)
|
||
DC.L stMin32-stArith32Tab ;1E MIN(PAT, DST) --> DST
|
||
DC.L stHilite-stArith32Tab ;20 (pat as mask) hilite <--> background
|
||
|
||
ALIGN Alignment
|
||
|
||
SetupStretch
|
||
;--------------------------------------------------------------
|
||
;
|
||
; Routine to setup case jump for StretchRow,
|
||
; based on horiz numer and denom.
|
||
;
|
||
; Call SetupStretch with numer in D0, denom in D1.
|
||
; Returns case jump in A0, fraction in D0.
|
||
;
|
||
; Has support for 16-bit stretching (from QDciPatchROM.a)
|
||
;
|
||
; Call resulting case jump with:
|
||
;
|
||
; A0: srcPtr
|
||
; A1: dstPtr
|
||
; A2: dstLimit
|
||
; D4: fraction
|
||
;
|
||
; clobbers D0-D4,A0-A1
|
||
;
|
||
|
||
MOVE D3,-(SP) ;SAVE SRC DEPTH
|
||
|
||
LEA DONE,A0 ;POINT TO ABORT
|
||
TST D0 ;IS NUMER <= 0 ?
|
||
BLE FOUND ;YES, POINT TO ABORT
|
||
TST D1 ;IS DENOM <= 0 ?
|
||
BLE FOUND ;YES, POINT TO ABORT
|
||
LEA ONE,A0 ;POINT TO FAST COPY
|
||
CMP D1,D0 ;IS NUMER = DENOM ?
|
||
BEQ FOUND ;YES, USE FAST COPY
|
||
BLT SHRNKING ;NO, BRANCH IF SHRINKING
|
||
;
|
||
; We will be stretching. Calc fract = denom/numer and check for fast.
|
||
;
|
||
STRCHING MOVE D0,D3 ;MAKE A COPY OF NUMER
|
||
MOVE D1,D4 ;MAKE A COPY OF DENOM
|
||
CLR.L -(SP) ;ROOM FOR FCN RESULT
|
||
MOVE D1,-(SP) ;PUSH DENOM
|
||
MOVE D0,-(SP) ;PUSH NUMER
|
||
_FixRatio ;CALL FIXRATIO, < 1.0
|
||
MOVE.L (SP)+,D0 ;POP RESULT
|
||
|
||
LEA PIXSTR,A0 ;ASSUME WE'RE STRETCHING PIXELS
|
||
TST (SP) ;ARE WE?
|
||
BNE.S FOUND ;=>YES, SRCSHIFT > 0
|
||
|
||
LEA DOUBLE,A0 ;CHECK FOR FAST RATIOS
|
||
CMP #$8000,D0
|
||
BEQ.S FOUND
|
||
LEA QUAD,A0
|
||
CMP #$4000,D0
|
||
BEQ.S FOUND
|
||
LEA EIGHT,A0
|
||
CMP #$2000,D0
|
||
BEQ.S FOUND
|
||
LEA SIXTEEN,A0
|
||
CMP #$1000,D0
|
||
BEQ.S FOUND
|
||
LEA THRTWO,A0
|
||
CMP #$0800,D0
|
||
BEQ.S FOUND
|
||
LEA ONE_5,A0
|
||
CMP #$AAAA,D0
|
||
BEQ.S FOUND
|
||
LEA TRIPLE,A0
|
||
CMP #$5555,D0
|
||
BEQ.S FOUND
|
||
LEA SIX,A0
|
||
CMP #$2AAA,D0
|
||
BEQ.S FOUND
|
||
;
|
||
; check for any multiple of 8:
|
||
;
|
||
EXT.L D3 ;CLEAR HI WORD OF NUMER
|
||
DIVU D4,D3 ;CALC NUMER DIV DENOM
|
||
MOVE D3,D1 ;SAVE QUOTIENT
|
||
AND.L #$FFFF0007,D3 ;IS SCALE AN EVEN MULT OF 8 ?
|
||
BNE.S NOMATCH ;NO, USE GENERAL STRETCH
|
||
MOVE D1,D0 ;YES RETURN QUOTIENT IN D0
|
||
LEA EIGHTS,A0 ;POINT TO FAST ROUTINE
|
||
BRA.S FOUND ;AND RETURN
|
||
NOMATCH LEA STRCH,A0 ;POINT TO SLOW GENERAL CODE
|
||
FOUND ADDQ #2,SP ;POP SRC SHIFT (IGNORE VALUE)
|
||
RTS ;RETURN WITH CASE JUMP IN A0
|
||
|
||
|
||
|
||
;
|
||
; We will be shrinking. Calc fract = numer/denom and check for fast.
|
||
;
|
||
SHRNKING
|
||
CLR.L -(SP) ;ROOM FOR FCN RESULT
|
||
MOVE D0,-(SP) ;PUSH NUMER
|
||
MOVE D1,-(SP) ;PUSH DENOM
|
||
_FixRatio ;CALL FIXRATIO, < 1.0
|
||
MOVE.L (SP)+,D0 ;POP RESULT
|
||
|
||
LEA PIXSHRNK,A0 ;ASSUME WE'RE SHRINKING PIXELS
|
||
TST (SP) ;ARE WE?
|
||
BNE.S FOUND ;=>YES, SRCSHIFT > 0
|
||
|
||
;ciFastRatios
|
||
LEA EIGHTH,A0 ;CHECK FOR FAST RATIOS
|
||
CMP #$2000,D0
|
||
BEQ.S FOUND
|
||
LEA QRTR,A0
|
||
CMP #$4000,D0
|
||
BEQ.S FOUND
|
||
LEA HALF,A0
|
||
CMP #$8000,D0
|
||
BEQ.S FOUND
|
||
LEA THREE4,A0
|
||
CMP #$C000,D0
|
||
BEQ.S FOUND
|
||
LEA SHRINK,A0
|
||
BRA FOUND
|
||
|
||
|
||
ALIGN 4
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; TABLE OF POINTERS TO THE STRETCH ROUTINES
|
||
; USED BY STRETCH AND CCRSRCORE
|
||
;
|
||
EXTBL DC.L ONE-EXTBL ;0
|
||
DC.L DOUBLE-EXTBL ;4
|
||
DC.L QUAD-EXTBL ;8
|
||
DC.L EIGHT-EXTBL ;12
|
||
DC.L SIXTEEN-EXTBL ;16
|
||
DC.L THRTWO-EXTBL ;20
|
||
DC.L BWtoD15-EXTBL ;24
|
||
DC.L BWtoD24-EXTBL ;28
|
||
;
|
||
; loops that do colorizing
|
||
;
|
||
DC.L ONEColor-EXTBL ;32
|
||
DC.L DOUBLEColor-EXTBL
|
||
DC.L QUADColor-EXTBL
|
||
DC.L EIGHTColor-EXTBL
|
||
DC.L SIXTEENColor-EXTBL
|
||
DC.L THRTWOColor-EXTBL
|
||
DC.L BWtoD15Alpha-EXTBL ;56 <42>
|
||
DC.L BWtoD24Alpha-EXTBL ;60 <42>
|
||
; DC.L BWtoD15-EXTBL
|
||
; DC.L BWtoD24-EXTBL
|
||
|
||
|
||
ALIGN 4
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; TABLE OF POINTERS TO THE STRETCH ROUTINES
|
||
; USED BY PATEXPAND
|
||
;
|
||
PATEXTBL
|
||
DC.L ONE1-PATEXTBL
|
||
DC.L DOUBLE1-PATEXTBL
|
||
DC.L QUAD1-PATEXTBL
|
||
DC.L EIGHT1-PATEXTBL
|
||
DC.L SXTN1-PATEXTBL
|
||
DC.L THRTWO1-PATEXTBL
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; NUMERATOR = DENOMINATOR, JUST COPY LONGS
|
||
;
|
||
ONE SUB.L A1,A2 ;Get byte count
|
||
MOVE.L A2,D0 ;
|
||
LSR.L #2,D0 ;Get count of longs
|
||
SUBQ #1,D0 ;less one for the dbra
|
||
@1 MOVE.L (A0)+,(A1)+ ;COPY ONE LONG
|
||
DBRA D0,@1 ;IS DSTPTR >= DSTLIMIT ?
|
||
RTS ;ALL DONE
|
||
|
||
ALIGN Alignment
|
||
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
|
||
OneColor
|
||
move.l fcolor(a6),d3
|
||
move.l bcolor(a6),d4
|
||
|
||
MOVE.L A2,D1 ; D3->last address we write to
|
||
SUB.L A1,D1 ; D3 = number of bytes to write
|
||
LSR #2,D1 ; divided in 4 to write longs
|
||
SUBQ #1,D1 ; less one for DBRA
|
||
@a MOVE.l (A0)+,D2 ; fetch long
|
||
;
|
||
;colorize
|
||
;
|
||
MOVE.L D2,D5 ;copy of source
|
||
NOT.L D2 ;turn on background bits
|
||
AND.L D3,D5 ;color same as background color
|
||
AND.L D4,D2 ;color foreground bits same as foreground color
|
||
OR.L D5,D2 ;combine colored foreground and background bits
|
||
move.l d2,(A1)+ ; send its double out
|
||
DBRA D1,@a
|
||
RTS
|
||
|
||
ALIGN Alignment
|
||
|
||
; EXPAND AN 8*8 PATTERN (ONE BIT DEEP)
|
||
|
||
ONE1 CLR.W (A1)+ ;CLEAR PATROW
|
||
CLR.L (A1)+ ;CLEAR PATHMASK, PATVMASK
|
||
MOVE.L (A1),A1 ;GET EXPAT POINTER
|
||
MOVE.B (A0)+,D0 ;GET FIRST BYTE OF PATTERN
|
||
bra.s @first
|
||
|
||
@0 MOVE.B (A0)+,D0 ;GET A BYTE OF PATTERN
|
||
cmp.b D5,D0 ;Same as last time?
|
||
beq.s @again
|
||
@first move.b D0,D5 ;cache for later
|
||
|
||
EOR.B D7,D0 ;INVERT IT IF MODE BIT 2
|
||
ROL.B D2,D0 ;ALIGN TO LOCAL COORDS
|
||
|
||
MOVE.B D0,D1 ;JUST REPLICATE
|
||
LSL.L #8,D1
|
||
MOVE.B D0,D1 ;TWICE IN LOW WORD
|
||
MOVE D1,D0
|
||
SWAP D1
|
||
MOVE D0,D1 ;PUT IN HIGH WORD TOO
|
||
|
||
MOVE.L D1,D0 ;COPY PATTERN BYTE
|
||
AND.L D3,D0 ;GET LONG OF FG DATA
|
||
NOT.L D1 ;GET NOTMASK
|
||
AND.L D4,D1 ;GET LONG OF BK DATA
|
||
OR.L D0,D1 ;COMBINE THEM
|
||
@again MOVE.L D1,(A1)+ ;PUT A LONG
|
||
MOVE.L D1,32-4(A1) ;PUT ANOTHER LONG
|
||
|
||
DBRA D6,@0 ;REPEAT FOR ALL BYTES
|
||
RTS
|
||
|
||
ALIGN Alignment
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; SHRINK TO THREE QUARTERS.
|
||
;
|
||
THREE4 MOVEQ #3,D3 ;MASK FOR HI 2 BITS
|
||
ROR.L #2,D3 ;IE. $C0000000
|
||
THREE4A MOVE.L (A0)+,D0 ;GET A LONG OF SRC
|
||
MOVEQ #7,D2 ;INIT COUNT OF 24 DST BITS
|
||
THREE4B ADD.L D0,D0 ;GET 1 BIT OF SRC
|
||
ADDX.L D1,D1 ;PUT 1 BIT TO DST
|
||
ADD.L D3,D0 ;PUT HI 2 BITS INTO CARRY
|
||
ADDX.L D1,D1 ;SHIFT INTO DST
|
||
LSL.L #3,D0 ;SHIFT LEFT 3 BITS
|
||
ADDX.L D1,D1 ;PUT CARRY BIT INTO DST
|
||
DBRA D2,THREE4B ;LOOP 8 TIMES
|
||
|
||
BFINS D1,(A1){0:24}
|
||
ADDQ #3,A1
|
||
CMP.L A2,A1 ;IS DSTPTR >= DSTLIMIT ?
|
||
BLO THREE4A ;NO, CONTINUE
|
||
RTS ;AND QUIT
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; SHRINK TO ONE HALF.
|
||
;
|
||
|
||
Half MOVE.L A2,D3
|
||
SUB.L A1,D3
|
||
LSR #2,D3 ; We'll be doing longwords
|
||
SUBQ #1,D3 ; less one for dbra
|
||
MOVE.L #$55555555,D2 ; alternate bits
|
||
MOVE.L #$00FF00FF,D5 ; mask for byte index
|
||
|
||
@a MOVE.L (A0)+,D0 ; fetch a source word
|
||
MOVE.L D0,D1 ; copy it
|
||
LSR.L #1,D1 ; shift copy right
|
||
OR.L D0,D1 ; or original with shift
|
||
AND.L D2,D1 ; Do some masking. bits: F.E.D.C.B.A.9.8.7.6.5.4.3.2.1.0
|
||
MOVE.L D1,D0 ; copy masked ored word
|
||
LSR.L #7,D0 ; downshift: D0 = ........F.E.D.C.B.A.9.8.7.6.5.4.
|
||
OR.L D1,D0 ; or the low bits: D0 = ........FBEAD9C8xxxxxxxx73625140
|
||
AND.L D5,D0 ; Mask it to two byte indices
|
||
SWAP D0
|
||
MOVE.B TableHalf(D0),D4 ; unscramble the bits
|
||
LSL #8,D4
|
||
SWAP D0
|
||
MOVE.B TableHalf(D0),D4
|
||
SWAP D4 ; D4 has 1st two words to send out
|
||
|
||
MOVE.L (A0)+,D0 ; fetch another source word
|
||
MOVE.L D0,D1 ; copy it
|
||
LSR.L #1,D1 ; shift copy right
|
||
OR.L D0,D1 ; or original with shift
|
||
AND.L D2,D1 ; Do some masking. bits: F.E.D.C.B.A.9.8.7.6.5.4.3.2.1.0
|
||
MOVE.L D1,D0 ; copy masked ored word
|
||
LSR.L #7,D0 ; downshift: D0 = ........F.E.D.C.B.A.9.8.7.6.5.4.
|
||
OR.L D1,D0 ; or the low bits: D0 = ........FBEAD9C8xxxxxxxx73625140
|
||
AND.L D5,D0 ; Mask it to two byte indices
|
||
SWAP D0
|
||
MOVE.B TableHalf(D0),D4 ; unscramble the bits
|
||
LSL #8,D4
|
||
SWAP D0
|
||
MOVE.B TableHalf(D0),D4
|
||
MOVE.L D4,(A1)+ ; put out four bytes (from eight)
|
||
DBRA D3,@a
|
||
RTS
|
||
|
||
TableHalf
|
||
DC.B $00,$01,$10,$11,$02,$03,$12,$13,$20,$21,$30,$31,$22,$23,$32,$33
|
||
DC.B $04,$05,$14,$15,$06,$07,$16,$17,$24,$25,$34,$35,$26,$27,$36,$37
|
||
DC.B $40,$41,$50,$51,$42,$43,$52,$53,$60,$61,$70,$71,$62,$63,$72,$73
|
||
DC.B $44,$45,$54,$55,$46,$47,$56,$57,$64,$65,$74,$75,$66,$67,$76,$77
|
||
DC.B $08,$09,$18,$19,$0a,$0b,$1a,$1b,$28,$29,$38,$39,$2a,$2b,$3a,$3b
|
||
DC.B $0c,$0d,$1c,$1d,$0e,$0f,$1e,$1f,$2c,$2d,$3c,$3d,$2e,$2f,$3e,$3f
|
||
DC.B $48,$49,$58,$59,$4a,$4b,$5a,$5b,$68,$69,$78,$79,$6a,$6b,$7a,$7b
|
||
DC.B $4c,$4d,$5c,$5d,$4e,$4f,$5e,$5f,$6c,$6d,$7c,$7d,$6e,$6f,$7e,$7f
|
||
DC.B $80,$81,$90,$91,$82,$83,$92,$93,$a0,$a1,$b0,$b1,$a2,$a3,$b2,$b3
|
||
DC.B $84,$85,$94,$95,$86,$87,$96,$97,$a4,$a5,$b4,$b5,$a6,$a7,$b6,$b7
|
||
DC.B $c0,$c1,$d0,$d1,$c2,$c3,$d2,$d3,$e0,$e1,$f0,$f1,$e2,$e3,$f2,$f3
|
||
DC.B $c4,$c5,$d4,$d5,$c6,$c7,$d6,$d7,$e4,$e5,$f4,$f5,$e6,$e7,$f6,$f7
|
||
DC.B $88,$89,$98,$99,$8a,$8b,$9a,$9b,$a8,$a9,$b8,$b9,$aa,$ab,$ba,$bb
|
||
DC.B $8c,$8d,$9c,$9d,$8e,$8f,$9e,$9f,$ac,$ad,$bc,$bd,$ae,$af,$be,$bf
|
||
DC.B $c8,$c9,$d8,$d9,$ca,$cb,$da,$db,$e8,$e9,$f8,$f9,$ea,$eb,$fa,$fb
|
||
DC.B $cc,$cd,$dc,$dd,$ce,$cf,$de,$df,$ec,$ed,$fc,$fd,$ee,$ef,$fe,$ff
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; SHRINK TO ONE QUARTER.
|
||
;
|
||
QRTR MOVE.L #$F0000000,D3 ;MASK FOR HI 4 BITS
|
||
QRTR1 MOVE.L (A0)+,D0 ;GET A LONG OF SRC
|
||
MOVEQ #7,D2 ;INIT COUNT OF 8 DST BITS
|
||
QRTR2 ADD.L D3,D0 ;PUT OR OF HI BITS INTO CARRY
|
||
ADDX.L D1,D1 ;SHIFT BIT INTO DST
|
||
LSL.L #4,D0 ;SHIFT LEFT 4 BITS
|
||
DBRA D2,QRTR2 ;LOOP 8 TIMES
|
||
MOVE.B D1,(A1)+ ;THEN PUT A BYTE TO DST
|
||
CMP.L A2,A1 ;IS DSTPTR >= DSTLIMIT ?
|
||
BLO QRTR1 ;NO, CONTINUE
|
||
RTS ;YES, QUIT
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;---------------------------------------------------
|
||
;
|
||
; SHRINK TO ONE EIGHTH.
|
||
;
|
||
EIGHTH MOVE.L #$FF000000,D3 ;MASK FOR HI 8 BITS
|
||
EIGHTH1 MOVE.L (A0)+,D0 ;GET A LONG OF SRC
|
||
MOVEQ #3,D2 ;INIT COUNT OF 4 DST BITS
|
||
EIGHTH2 ADD.L D3,D0 ;PUT OR OF HI BITS INTO CARRY
|
||
ADDX.L D1,D1 ;SHIFT BIT INTO DST
|
||
LSL.L #8,D0 ;SHIFT LEFT 8 BITS
|
||
DBRA D2,EIGHTH2 ;LOOP 8 TIMES
|
||
MOVE.L (A0)+,D0 ;GET A LONG OF SRC
|
||
MOVEQ #3,D2 ;INIT COUNT OF 4 DST BITS
|
||
EIGHTH3 ADD.L D3,D0 ;PUT OR OF HI BITS INTO CARRY
|
||
ADDX.L D1,D1 ;SHIFT BIT INTO DST
|
||
LSL.L #8,D0 ;SHIFT LEFT 8 BITS
|
||
DBRA D2,EIGHTH3 ;LOOP 8 TIMES
|
||
MOVE.B D1,(A1)+ ;THEN PUT A BYTE TO DST
|
||
CMP.L A2,A1 ;IS DSTPTR >= DSTLIMIT ?
|
||
BLO EIGHTH1 ;NO, CONTINUE
|
||
RTS ;YES, QUIT
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; STRETCH TO 1.5 TIMES AS WIDE
|
||
;
|
||
ONE_5 MOVE.B (A0)+,D0 ;GET FIRST BYTE FROM SRC
|
||
MOVE D0,D1 ;MAKE AN EXTRA COPY
|
||
LSR.B #4,D1 ;GET HI NIBBLE
|
||
MOVE.B TABLE15(D1),D2 ;EXPAND TO 6 BITS
|
||
LSL.L #6,D2 ;SHIFT OVER 6
|
||
AND #$F,D0 ;GET LO NIBBLE
|
||
MOVE.B TABLE15(D0),D2 ;EXPAND TO 6 BITS
|
||
LSL.L #6,D2 ;SHIFT OVER 6
|
||
MOVE.B (A0)+,D0 ;GET SECOND BYTE FROM SRC
|
||
MOVE D0,D1 ;MAKE AN EXTRA COPY
|
||
LSR.B #4,D1 ;GET HI NIBBLE
|
||
MOVE.B TABLE15(D1),D2 ;EXPAND TO 6 BITS
|
||
LSL.L #6,D2 ;SHIFT OVER 6
|
||
AND #$F,D0 ;GET LO NIBBLE
|
||
MOVE.B TABLE15(D0),D2 ;EXPAND TO 6 BITS
|
||
LSR.L #2,D2 ;RIGHT JUSTIFY
|
||
SWAP D2 ;FLIP WORDS
|
||
MOVE.B D2,(A1)+ ;PUT FIRST BYTE TO DST
|
||
SWAP D2 ;FLIP BACK AGAIN
|
||
MOVE D2,D1
|
||
ROR #8,D1
|
||
MOVE.B D1,(A1)+ ;PUT SECOND BYTE TO DST
|
||
MOVE.B D2,(A1)+ ;PUT THIRD BYTE TO DST
|
||
CMP.L A2,A1 ;IS DSTPTR >= DSTLIMIT ?
|
||
BLO ONE_5 ;NO, LOOP FOR MORE
|
||
RTS ;ALL DONE
|
||
|
||
TABLE15 DC.B $00,$0C,$10,$1C ;1.5 TIMES TABLE
|
||
DC.B $60,$6C,$70,$7C
|
||
DC.B $80,$8C,$90,$9C
|
||
DC.B $E0,$EC,$F0,$FC
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; DOUBLE USING TABLE LOOKUP
|
||
;
|
||
|
||
Double1 CLR.W (A1)+ ;CLEAR PATROW
|
||
CLR.L (A1)+ ;CLEAR PATHMASK, PATVMASK
|
||
MOVE.L (A1),A1 ;GET EXPAT POINTER
|
||
moveq #0,d0
|
||
MOVE.B (A0)+,D0 ;GET First BYTE OF PATTERN
|
||
bra.s @first
|
||
|
||
@0 MOVEQ #0,D0 ;CLEAR OUT HIGH PART
|
||
MOVE.B (A0)+,D0 ;GET A BYTE OF PATTERN
|
||
cmp.b D5,D0 ;Same as last time?
|
||
beq.s @again
|
||
@first move.b D0,D5 ;cache for later
|
||
|
||
EOR.B D7,D0 ;INVERT IT IF MODE BIT 2
|
||
ROL.B D2,D0 ;ALIGN TO LOCAL COORDS
|
||
|
||
MOVE.W D0,D1 ;MAKE AN EXTRA COPY
|
||
MOVE Table2(D1*2),D1 ;DOUBLE Byte to Word
|
||
MOVE D1,D0 ;COPY
|
||
SWAP D1 ;SWAP
|
||
MOVE D0,D1 ;RETURN ENTIRE LONG
|
||
|
||
MOVE.L D1,D0 ;COPY FOR NOTMASK
|
||
AND.L D3,D0 ;GET LONG OF FG DATA
|
||
NOT.L D1 ;GET NOTMASK
|
||
AND.L D4,D1 ;GET LONG OF BK DATA
|
||
OR.L D0,D1 ;COMBINE THEM
|
||
@again MOVE.L D1,32(A1) ;PUT ANOTHER LONG
|
||
MOVE.L D1,(A1)+ ;PUT A LONG
|
||
|
||
DBRA D6,@0 ;REPEAT FOR EACH BYTE
|
||
RTS ;ALL DONE
|
||
|
||
ALIGN Alignment
|
||
|
||
Double CLR D0 ; incoming bytes'll go here
|
||
MOVE.L A2,D3 ; D3->last address we write to
|
||
SUB.L A1,D3 ; D3 = number of bytes to write
|
||
LSR #1,D3 ; divided in half, because we write words
|
||
SUBQ #1,D3 ; less one for DBRA
|
||
@a MOVE.B (A0)+,D0 ; fetch a byte
|
||
MOVE Table2(D0*2),(A1)+ ; send its double out
|
||
DBRA D3,@a
|
||
RTS
|
||
|
||
ALIGN Alignment
|
||
|
||
; from QDciPatchROM.a without trashing A3 <sm 6/9/92>stb
|
||
|
||
DoubleColor
|
||
move.l fcolor(a6),d3
|
||
move.l bcolor(a6),d4
|
||
|
||
CLR D0 ; incoming bytes'll go here
|
||
MOVE.L A2,D1 ; D3->last address we write to
|
||
SUB.L A1,D1 ; D3 = number of bytes to write
|
||
LSR #1,D1 ; divided in half, because we write words
|
||
SUBQ #1,D1 ; less one for DBRA
|
||
@a MOVE.B (A0)+,D0 ; fetch a byte
|
||
MOVE Table2(D0*2),d2
|
||
;
|
||
;colorize
|
||
;
|
||
MOVE.L D2,D5 ;copy of source
|
||
NOT.L D2 ;turn on background bits
|
||
AND.L D3,D5 ;color same as background color
|
||
AND.L D4,D2 ;color foreground bits same as foreground color
|
||
OR.L D5,D2 ;combine colored foreground and background bits
|
||
move.w d2,(A1)+ ; send its double out
|
||
DBRA D1,@a
|
||
RTS
|
||
|
||
Table2
|
||
DC $0000,$0003,$000c,$000f,$0030,$0033,$003c,$003f
|
||
DC $00c0,$00c3,$00cc,$00cf,$00f0,$00f3,$00fc,$00ff
|
||
DC $0300,$0303,$030c,$030f,$0330,$0333,$033c,$033f
|
||
DC $03c0,$03c3,$03cc,$03cf,$03f0,$03f3,$03fc,$03ff
|
||
DC $0c00,$0c03,$0c0c,$0c0f,$0c30,$0c33,$0c3c,$0c3f
|
||
DC $0cc0,$0cc3,$0ccc,$0ccf,$0cf0,$0cf3,$0cfc,$0cff
|
||
DC $0f00,$0f03,$0f0c,$0f0f,$0f30,$0f33,$0f3c,$0f3f
|
||
DC $0fc0,$0fc3,$0fcc,$0fcf,$0ff0,$0ff3,$0ffc,$0fff
|
||
DC $3000,$3003,$300c,$300f,$3030,$3033,$303c,$303f
|
||
DC $30c0,$30c3,$30cc,$30cf,$30f0,$30f3,$30fc,$30ff
|
||
DC $3300,$3303,$330c,$330f,$3330,$3333,$333c,$333f
|
||
DC $33c0,$33c3,$33cc,$33cf,$33f0,$33f3,$33fc,$33ff
|
||
DC $3c00,$3c03,$3c0c,$3c0f,$3c30,$3c33,$3c3c,$3c3f
|
||
DC $3cc0,$3cc3,$3ccc,$3ccf,$3cf0,$3cf3,$3cfc,$3cff
|
||
DC $3f00,$3f03,$3f0c,$3f0f,$3f30,$3f33,$3f3c,$3f3f
|
||
DC $3fc0,$3fc3,$3fcc,$3fcf,$3ff0,$3ff3,$3ffc,$3fff
|
||
DC $c000,$c003,$c00c,$c00f,$c030,$c033,$c03c,$c03f
|
||
DC $c0c0,$c0c3,$c0cc,$c0cf,$c0f0,$c0f3,$c0fc,$c0ff
|
||
DC $c300,$c303,$c30c,$c30f,$c330,$c333,$c33c,$c33f
|
||
DC $c3c0,$c3c3,$c3cc,$c3cf,$c3f0,$c3f3,$c3fc,$c3ff
|
||
DC $cc00,$cc03,$cc0c,$cc0f,$cc30,$cc33,$cc3c,$cc3f
|
||
DC $ccc0,$ccc3,$cccc,$cccf,$ccf0,$ccf3,$ccfc,$ccff
|
||
DC $cf00,$cf03,$cf0c,$cf0f,$cf30,$cf33,$cf3c,$cf3f
|
||
DC $cfc0,$cfc3,$cfcc,$cfcf,$cff0,$cff3,$cffc,$cfff
|
||
DC $f000,$f003,$f00c,$f00f,$f030,$f033,$f03c,$f03f
|
||
DC $f0c0,$f0c3,$f0cc,$f0cf,$f0f0,$f0f3,$f0fc,$f0ff
|
||
DC $f300,$f303,$f30c,$f30f,$f330,$f333,$f33c,$f33f
|
||
DC $f3c0,$f3c3,$f3cc,$f3cf,$f3f0,$f3f3,$f3fc,$f3ff
|
||
DC $fc00,$fc03,$fc0c,$fc0f,$fc30,$fc33,$fc3c,$fc3f
|
||
DC $fcc0,$fcc3,$fccc,$fccf,$fcf0,$fcf3,$fcfc,$fcff
|
||
DC $ff00,$ff03,$ff0c,$ff0f,$ff30,$ff33,$ff3c,$ff3f
|
||
DC $ffc0,$ffc3,$ffcc,$ffcf,$fff0,$fff3,$fffc,$ffff
|
||
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; TRIPLE USING TABLE LOOKUP
|
||
;
|
||
TRIPLE MOVE.B (A0)+,D0 ;GET A BYTE FROM SRC
|
||
MOVE D0,D1 ;MAKE AN EXTRA COPY
|
||
MOVE D0,D2 ;MAKE A THIRD COPY
|
||
LSR.B #5,D2 ;GET 3 HI BITS
|
||
MOVE.B TABLE3A(D2),(A1)+ ;PUT FIRST BYTE TO DST
|
||
LSR.B #2,D1
|
||
AND #$F,D1 ;GET MIDDLE 4 BITS
|
||
MOVE.B TABLE3B(D1),(A1)+ ;PUT SECOND BYTE TO DST
|
||
AND #$7,D0 ;GET 3 LO BITS
|
||
MOVE.B TABLE3C(D0),(A1)+ ;PUT THIRD BYTE TO DST
|
||
CMP.L A2,A1 ;IS DSTPTR >= DSTLIMIT ?
|
||
BLO TRIPLE ;NO, LOOP FOR MORE
|
||
RTS ;ALL DONE
|
||
|
||
TABLE3A DC.B $00,$03,$1C,$1F ;TRIPLING TABLE
|
||
DC.B $E0,$E3,$FC,$FF
|
||
TABLE3B DC.B $00,$01,$0E,$0F
|
||
DC.B $70,$71,$7E,$7F
|
||
DC.B $80,$81,$8E,$8F
|
||
DC.B $F0,$F1,$FE,$FF
|
||
TABLE3C DC.B $00,$07,$38,$3F
|
||
DC.B $C0,$C7,$F8,$FF
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; QUADRUPLE USING TABLE LOOKUP
|
||
;
|
||
|
||
QUAD SUB.L A1,A2 ;Get byte count
|
||
MOVE.L A2,D1 ;
|
||
LSR.L #2,D1 ;Get count of longs
|
||
SUBQ #1,D1 ;less one for the dbra
|
||
@4 MOVE.B (A0)+,D0 ;GET A BYTE FROM SRC
|
||
MOVE.L TABLE4(D0*4),(A1)+ ;AND SPIT OUT A LONG
|
||
DBRA D1,@4 ;IS DSTPTR >= DSTLIMIT ?
|
||
RTS ;ALL DONE
|
||
|
||
ALIGN Alignment
|
||
|
||
; from QDciPatchROM.a without trashing A3 <sm 6/9/92>stb
|
||
|
||
QUADColor
|
||
move.l fcolor(a6),d3
|
||
move.l bcolor(a6),d4
|
||
|
||
SUB.L A1,A2 ;Get byte count
|
||
MOVE.L A2,D1 ;
|
||
LSR.L #2,D1 ;Get count of longs
|
||
SUBQ #1,D1 ;less one for the dbra
|
||
@4 MOVE.B (A0)+,D0 ;GET A BYTE FROM SRC
|
||
MOVE.L TABLE4(D0*4),D2 ;convert to a 4 bit/pixel
|
||
;
|
||
;colorize
|
||
;
|
||
MOVE.L D2,D5 ;copy of source
|
||
NOT.L D2 ;turn on background bits
|
||
AND.L D3,D5 ;color same as background color
|
||
AND.L D4,D2 ;color foreground bits same as foreground color
|
||
OR.L D5,D2 ;combine colored foreground and background bits
|
||
move.l d2,(A1)+ ;AND SPIT OUT A LONG
|
||
DBRA D1,@4 ;IS DSTPTR >= DSTLIMIT ?
|
||
RTS ;ALL DONE
|
||
|
||
; QUAD INTO A LONG FOR PATTERNS
|
||
|
||
QUAD1 CLR.W (A1)+ ;CLEAR PATROW
|
||
CLR.L (A1)+ ;CLEAR PATHMASK, PATVMASK
|
||
MOVE.L (A1),A1 ;GET EXPAT POINTER
|
||
moveq #0,d0
|
||
MOVE.B (A0)+,D0 ;GET First BYTE OF PATTERN
|
||
bra.s @first
|
||
|
||
@0 MOVEQ #0,D0 ;CLEAR OUT HIGH PART
|
||
MOVE.B (A0)+,D0 ;GET A BYTE OF PATTERN
|
||
cmp.b D5,D0 ;Same as last time?
|
||
beq.s @again
|
||
@first move.b D0,D5 ;cache for later
|
||
|
||
EOR.B D7,D0 ;INVERT IT IF MODE BIT 2
|
||
ROL.B D2,D0 ;ALIGN TO LOCAL COORDS
|
||
|
||
MOVE.L TABLE4(D0*4),D1 ;PUT A LONG TO D1
|
||
MOVE.L D1,D0 ;COPY FOR NOTMASK
|
||
AND.L D3,D0 ;GET LONG OF FG DATA
|
||
NOT.L D1 ;GET NOTMASK
|
||
AND.L D4,D1 ;GET LONG OF BK DATA
|
||
OR.L D0,D1 ;COMBINE THEM
|
||
@again MOVE.L D1,(A1)+ ;PUT A LONG
|
||
MOVE.L D1,32-4(A1) ;PUT ANOTHER LONG
|
||
|
||
DBRA D6,@0 ;REPEAT FOR EACH BYTE
|
||
RTS ;ALL DONE
|
||
|
||
|
||
ALIGN 4
|
||
|
||
TABLE4 DC.L $00000000,$0000000F,$000000F0,$000000FF ;QUADRUPLING TABLE
|
||
DC.L $00000F00,$00000F0F,$00000FF0,$00000FFF
|
||
DC.L $0000F000,$0000F00F,$0000F0F0,$0000F0FF
|
||
DC.L $0000FF00,$0000FF0F,$0000FFF0,$0000FFFF
|
||
|
||
DC.L $000F0000,$000F000F,$000F00F0,$000F00FF ;QUADRUPLING TABLE
|
||
DC.L $000F0F00,$000F0F0F,$000F0FF0,$000F0FFF
|
||
DC.L $000FF000,$000FF00F,$000FF0F0,$000FF0FF
|
||
DC.L $000FFF00,$000FFF0F,$000FFFF0,$000FFFFF
|
||
|
||
DC.L $00F00000,$00F0000F,$00F000F0,$00F000FF ;QUADRUPLING TABLE
|
||
DC.L $00F00F00,$00F00F0F,$00F00FF0,$00F00FFF
|
||
DC.L $00F0F000,$00F0F00F,$00F0F0F0,$00F0F0FF
|
||
DC.L $00F0FF00,$00F0FF0F,$00F0FFF0,$00F0FFFF
|
||
|
||
DC.L $00FF0000,$00FF000F,$00FF00F0,$00FF00FF ;QUADRUPLING TABLE
|
||
DC.L $00FF0F00,$00FF0F0F,$00FF0FF0,$00FF0FFF
|
||
DC.L $00FFF000,$00FFF00F,$00FFF0F0,$00FFF0FF
|
||
DC.L $00FFFF00,$00FFFF0F,$00FFFFF0,$00FFFFFF
|
||
|
||
DC.L $0F000000,$0F00000F,$0F0000F0,$0F0000FF ;QUADRUPLING TABLE
|
||
DC.L $0F000F00,$0F000F0F,$0F000FF0,$0F000FFF
|
||
DC.L $0F00F000,$0F00F00F,$0F00F0F0,$0F00F0FF
|
||
DC.L $0F00FF00,$0F00FF0F,$0F00FFF0,$0F00FFFF
|
||
|
||
DC.L $0F0F0000,$0F0F000F,$0F0F00F0,$0F0F00FF ;QUADRUPLING TABLE
|
||
DC.L $0F0F0F00,$0F0F0F0F,$0F0F0FF0,$0F0F0FFF
|
||
DC.L $0F0FF000,$0F0FF00F,$0F0FF0F0,$0F0FF0FF
|
||
DC.L $0F0FFF00,$0F0FFF0F,$0F0FFFF0,$0F0FFFFF
|
||
|
||
DC.L $0FF00000,$0FF0000F,$0FF000F0,$0FF000FF ;QUADRUPLING TABLE
|
||
DC.L $0FF00F00,$0FF00F0F,$0FF00FF0,$0FF00FFF
|
||
DC.L $0FF0F000,$0FF0F00F,$0FF0F0F0,$0FF0F0FF
|
||
DC.L $0FF0FF00,$0FF0FF0F,$0FF0FFF0,$0FF0FFFF
|
||
|
||
DC.L $0FFF0000,$0FFF000F,$0FFF00F0,$0FFF00FF ;QUADRUPLING TABLE
|
||
DC.L $0FFF0F00,$0FFF0F0F,$0FFF0FF0,$0FFF0FFF
|
||
DC.L $0FFFF000,$0FFFF00F,$0FFFF0F0,$0FFFF0FF
|
||
DC.L $0FFFFF00,$0FFFFF0F,$0FFFFFF0,$0FFFFFFF
|
||
|
||
DC.L $F0000000,$F000000F,$F00000F0,$F00000FF ;QUADRUPLING TABLE
|
||
DC.L $F0000F00,$F0000F0F,$F0000FF0,$F0000FFF
|
||
DC.L $F000F000,$F000F00F,$F000F0F0,$F000F0FF
|
||
DC.L $F000FF00,$F000FF0F,$F000FFF0,$F000FFFF
|
||
|
||
DC.L $F00F0000,$F00F000F,$F00F00F0,$F00F00FF ;QUADRUPLING TABLE
|
||
DC.L $F00F0F00,$F00F0F0F,$F00F0FF0,$F00F0FFF
|
||
DC.L $F00FF000,$F00FF00F,$F00FF0F0,$F00FF0FF
|
||
DC.L $F00FFF00,$F00FFF0F,$F00FFFF0,$F00FFFFF
|
||
|
||
DC.L $F0F00000,$F0F0000F,$F0F000F0,$F0F000FF ;QUADRUPLING TABLE
|
||
DC.L $F0F00F00,$F0F00F0F,$F0F00FF0,$F0F00FFF
|
||
DC.L $F0F0F000,$F0F0F00F,$F0F0F0F0,$F0F0F0FF
|
||
DC.L $F0F0FF00,$F0F0FF0F,$F0F0FFF0,$F0F0FFFF
|
||
|
||
DC.L $F0FF0000,$F0FF000F,$F0FF00F0,$F0FF00FF ;QUADRUPLING TABLE
|
||
DC.L $F0FF0F00,$F0FF0F0F,$F0FF0FF0,$F0FF0FFF
|
||
DC.L $F0FFF000,$F0FFF00F,$F0FFF0F0,$F0FFF0FF
|
||
DC.L $F0FFFF00,$F0FFFF0F,$F0FFFFF0,$F0FFFFFF
|
||
|
||
DC.L $FF000000,$FF00000F,$FF0000F0,$FF0000FF ;QUADRUPLING TABLE
|
||
DC.L $FF000F00,$FF000F0F,$FF000FF0,$FF000FFF
|
||
DC.L $FF00F000,$FF00F00F,$FF00F0F0,$FF00F0FF
|
||
DC.L $FF00FF00,$FF00FF0F,$FF00FFF0,$FF00FFFF
|
||
|
||
DC.L $FF0F0000,$FF0F000F,$FF0F00F0,$FF0F00FF ;QUADRUPLING TABLE
|
||
DC.L $FF0F0F00,$FF0F0F0F,$FF0F0FF0,$FF0F0FFF
|
||
DC.L $FF0FF000,$FF0FF00F,$FF0FF0F0,$FF0FF0FF
|
||
DC.L $FF0FFF00,$FF0FFF0F,$FF0FFFF0,$FF0FFFFF
|
||
|
||
DC.L $FFF00000,$FFF0000F,$FFF000F0,$FFF000FF ;QUADRUPLING TABLE
|
||
DC.L $FFF00F00,$FFF00F0F,$FFF00FF0,$FFF00FFF
|
||
DC.L $FFF0F000,$FFF0F00F,$FFF0F0F0,$FFF0F0FF
|
||
DC.L $FFF0FF00,$FFF0FF0F,$FFF0FFF0,$FFF0FFFF
|
||
|
||
DC.L $FFFF0000,$FFFF000F,$FFFF00F0,$FFFF00FF ;QUADRUPLING TABLE
|
||
DC.L $FFFF0F00,$FFFF0F0F,$FFFF0FF0,$FFFF0FFF
|
||
DC.L $FFFFF000,$FFFFF00F,$FFFFF0F0,$FFFFF0FF
|
||
DC.L $FFFFFF00,$FFFFFF0F,$FFFFFFF0,$FFFFFFFF
|
||
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; STRETCH BY SIX USING TABLE LOOKUP
|
||
;
|
||
SIX MOVE.B (A0)+,D0 ;GET A BYTE FROM SRC
|
||
MOVE D0,D1 ;MAKE AN EXTRA COPY
|
||
AND #$E0,D1 ;MASK FOR HI 3 BITS
|
||
LSR.B #4,D1 ;SHIFT FOR TABLE INDEX
|
||
MOVE.W TABLE6A(D1),(A1)+ ;PUT A WORD TO DST
|
||
MOVE D0,D1 ;GET SRC BYTE AGAIN
|
||
AND #$3C,D1 ;MASK FOR MIDDLE 4 BITS
|
||
LSR.B #1,D1 ;SHIFT FOR TABLE INDEX
|
||
MOVE.W TABLE6B(D1),(A1)+ ;PUT A WORD TO DST
|
||
MOVE D0,D1 ;GET SRC BYTE AGAIN
|
||
AND #7,D1 ;MASK FOR LO 3 BITS
|
||
ADD D1,D1 ;DOUBLE FOR TABLE INDEX
|
||
MOVE.W TABLE6C(D1),(A1)+ ;PUT A WORD TO DST
|
||
CMP.L A2,A1 ;IS DSTPTR >= DSTLIMIT ?
|
||
BLO SIX ;NO, LOOP FOR MORE
|
||
RTS ;ALL DONE
|
||
|
||
TABLE6A DC.W $0000,$000F,$03F0,$03FF ;SIX TIMES TABLE
|
||
DC.W $FC00,$FC0F,$FFF0,$FFFF
|
||
TABLE6B DC.W $0000,$0003,$00FC,$00FF
|
||
DC.W $3F00,$3F03,$3FFC,$3FFF
|
||
DC.W $C000,$C003,$C0FC,$C0FF
|
||
DC.W $FF00,$FF03,$FFFC,$FFFF
|
||
TABLE6C DC.W $0000,$003F,$0FC0,$0FFF
|
||
DC.W $F000,$F03F,$FFC0,$FFFF
|
||
|
||
ALIGN Alignment
|
||
|
||
; EXPAND AN 8*8 PATTERN FOR EIGHT BITS PER PIXEL
|
||
|
||
EIGHT1 MOVE #8,(A1)+ ;PATROW = 8
|
||
MOVE #$0004,(A1)+ ;PATHMASK = $0004
|
||
MOVE #$003F,(A1)+ ;PATVMASK = $003F
|
||
|
||
; IF PATTERN REPEATS ITSELF, THEN DO OLD WAY FOR SPEED.
|
||
|
||
MOVE.L A0,A2 ;COPY PATTERN POINTER
|
||
MOVEQ #7,D0 ;DO EIGHT BYTES
|
||
@0 MOVE.B (A2),D1 ;GET A BYTE
|
||
ROR.B #4,D1 ;SWAP NIBBLES
|
||
CMP.B (A2)+,D1 ;ARE THEY THE SAME?
|
||
DBNE D0,@0 ;REPEAT FOR 8 BYTES
|
||
BNE.S @1 ;=>NO, DO NEW WAY
|
||
|
||
CLR -6(A1) ;AND SET PATROW = 0
|
||
BRA.S Small8 ;Pattern is in 1 long wide
|
||
|
||
@1 MOVE.L (A1),A1 ;GET EXPAT POINTER
|
||
|
||
FULL8 MOVEQ #0,D1 ;MAKE SURE HIGH PART IS 0
|
||
MOVE.B (A0)+,D1 ;GET A BYTE OF PATTERN
|
||
EOR.B D7,D1 ;INVERT IT IF MODE BIT 2
|
||
ROL.B D2,D1 ;ALIGN TO LOCAL COORDS
|
||
MOVE D1,D5 ;SAVE IN D5
|
||
|
||
AND #$F0,D1 ;MASK FOR HI NIBBLE
|
||
LSR #2,D1 ;SHIFT FOR TABLE INDEX
|
||
MOVE.L TABLE8(D1),D1 ;PUT FIRST LONG TO DST
|
||
MOVE.L D1,D0 ;COPY FOR NOTMASK
|
||
AND.L D3,D0 ;GET LONG OF FG DATA
|
||
NOT.L D1 ;GET NOTMASK
|
||
AND.L D4,D1 ;GET LONG OF BK DATA
|
||
OR.L D0,D1 ;COMBINE THEM
|
||
MOVE.L D1,(A1)+ ;PUT A LONG
|
||
|
||
AND #$0F,D5 ;MASK FOR LO NIBBLE
|
||
MOVE.L TABLE8(D5*4),D1 ;PUT SECOND LONG TO DST
|
||
MOVE.L D1,D0 ;COPY FOR NOTMASK
|
||
AND.L D3,D0 ;GET LONG OF FG DATA
|
||
NOT.L D1 ;GET NOTMASK
|
||
AND.L D4,D1 ;GET LONG OF BK DATA
|
||
OR.L D0,D1 ;COMBINE THEM
|
||
MOVE.L D1,(A1)+ ;PUT A LONG
|
||
|
||
DBRA D6,FULL8 ;REPEAT FOR EACH LONG
|
||
RTS ;ALL DONE
|
||
|
||
|
||
|
||
Small8 MOVE.L (A1),A1 ;GET EXPAT POINTER
|
||
moveq #0,d0
|
||
MOVE.B (A0)+,D0 ;GET First BYTE OF PATTERN
|
||
bra.s @first
|
||
|
||
@NXT8 MOVEQ #0,D0 ;MAKE SURE HIGH PART IS 0
|
||
MOVE.B (A0)+,D0 ;GET A BYTE OF PATTERN
|
||
cmp.b D5,D0 ;Same as last time?
|
||
beq.s @again
|
||
@first move.b D0,D5 ;cache for later
|
||
|
||
EOR.B D7,D0 ;INVERT IT IF MODE BIT 2
|
||
ROL.B D2,D0 ;ALIGN TO LOCAL COORDS
|
||
|
||
AND #$F0,D0 ;MASK FOR HI NIBBLE
|
||
LSR #2,D0 ;SHIFT FOR TABLE INDEX
|
||
MOVE.L TABLE8(D0),D1 ;PUT FIRST LONG TO DST
|
||
MOVE.L D1,D0 ;COPY FOR NOTMASK
|
||
AND.L D3,D0 ;GET LONG OF FG DATA
|
||
NOT.L D1 ;GET NOTMASK
|
||
AND.L D4,D1 ;GET LONG OF BK DATA
|
||
OR.L D0,D1 ;COMBINE THEM
|
||
@again MOVE.L D1,(A1)+ ;PUT A LONG
|
||
MOVE.L D1,32-4(A1) ;MAKE 2 COPIES
|
||
DBRA D6,@NXT8 ;REPEAT FOR EACH LONG
|
||
RTS ;ALL DONE
|
||
|
||
ALIGN 4 ;MOVED TABLE TO KEEP TABLE IN RANGE <22>
|
||
|
||
TABLE8 DC.L $00000000,$000000FF,$0000FF00,$0000FFFF
|
||
DC.L $00FF0000,$00FF00FF,$00FFFF00,$00FFFFFF
|
||
DC.L $FF000000,$FF0000FF,$FF00FF00,$FF00FFFF
|
||
DC.L $FFFF0000,$FFFF00FF,$FFFFFF00,$FFFFFFFF
|
||
|
||
ALIGN Alignment
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; SCALE UP BY EIGHT USING TABLE LOOKUP
|
||
;
|
||
|
||
Eight
|
||
MOVE.B (A0)+,D0 ;GET A BYTE OF SRC
|
||
MOVE D0,D1 ;MAKE AN EXTRA COPY
|
||
AND #$F0,D1 ;MASK FOR HI NIBBLE
|
||
LSR #2,D1 ;SHIFT FOR TABLE INDEX
|
||
MOVE.L TABLE8(D1),(A1)+ ;PUT FIRST LONG TO DST
|
||
AND #$0F,D0 ;MASK FOR LO NIBBLE
|
||
MOVE.L TABLE8(D0*4),(A1)+ ;PUT second LONG TO DST
|
||
CMP.L A2,A1 ;IS DSTPTR >= DSTLIMIT ?
|
||
BLO.s Eight ;NO, GO FOR MORE
|
||
RTS ;ALL DONE
|
||
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; SCALE UP BY EIGHT USING TABLE LOOKUP, then colorize
|
||
;
|
||
|
||
; from QDciPatchROM.a but doesn’t use A3 here <sm 6/9/92>stb
|
||
|
||
EightLoop
|
||
MOVE.B (A0)+,D0 ;GET A BYTE OF SRC
|
||
MOVE D0,D1 ;MAKE AN EXTRA COPY
|
||
AND #$F0,D1 ;MASK FOR HI NIBBLE
|
||
LSR #2,D1 ;SHIFT FOR TABLE INDEX
|
||
MOVE.L TABLE8(D1),d2 ;get four pixels
|
||
AND #$0F,D0 ;MASK FOR LO NIBBLE
|
||
MOVE.L TABLE8(D0*4),D0 ;get second set of four pixels
|
||
;
|
||
;colorize
|
||
;
|
||
MOVE.L D2,D5 ;copy of source
|
||
NOT.L D2 ;turn on background bits
|
||
AND.L D3,D5 ;color same as background color
|
||
AND.L D4,D2 ;color foreground bits same as foreground color
|
||
OR.L D5,D2 ;combine colored foreground and background bits
|
||
move.l d2,(A1)+ ;PUT FIRST LONG TO DST
|
||
;
|
||
;colorize
|
||
;
|
||
MOVE.L D0,D5 ;copy of source
|
||
NOT.L D0 ;turn on background bits
|
||
AND.L D3,D5 ;color same as background color
|
||
AND.L D4,D0 ;color foreground bits same as foreground color
|
||
OR.L D5,D0 ;combine colored foreground and background bits
|
||
|
||
move.l D0,(A1)+ ;PUT SECOND LONG TO DST
|
||
CMP.L A2,A1 ;IS DSTPTR >= DSTLIMIT ?
|
||
BLO.s EightLoop ;NO, GO FOR MORE
|
||
RTS ;ALL DONE
|
||
|
||
|
||
EIGHTColor
|
||
move.l fcolor(a6),d3
|
||
move.l bcolor(a6),d4
|
||
bra.s EightLoop ; HACK!!! Needed to keep Table8 in 8 bit range...<22>
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------
|
||
;
|
||
; SCALE UP BY 16 (thanks to Gary Davidian)
|
||
;
|
||
SIXTEEN
|
||
MOVEQ #15,D2 ;16 output longs
|
||
MOVE.L (A0)+,D0 ;fetch a long of src
|
||
@NxtBit ADD.L D0,D0 ;extend first bit into hi word
|
||
SUBX.L D1,D1
|
||
ADD.L D0,D0 ;extend next bit into lo word
|
||
SUBX.W D1,D1
|
||
MOVE.L D1,(A1)+
|
||
CMP.L A2,A1 ;IS DSTPTR >= DSTLIMIT ?
|
||
DBHS D2,@NxtBit ;process remaining bits
|
||
BLO SIXTEEN ;fetch next input long
|
||
RTS ;ALL DONE
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
; EXPAND AN 8*8 PATTERN FOR 16 BITS PER PIXEL
|
||
; *** DOESN'T CHECK FOR POSSIBLE SHORTCUT
|
||
|
||
SXTN1 MOVE #16,(A1)+ ;PATROW = 16
|
||
MOVE #$000C,(A1)+ ;PATHMASK = $000C
|
||
MOVE #$007F,(A1)+ ;PATVMASK = $007F
|
||
|
||
; IF PATTERN REPEATS ITSELF, THEN DO OLD WAY FOR SPEED. <BAL 26Jun88>
|
||
|
||
MOVE.L A0,A2 ;COPY PATTERN POINTER
|
||
MOVEQ #7,D0 ;DO EIGHT BYTES
|
||
@0 MOVE.B (A2)+,D1 ;GET A BYTE
|
||
MOVE.B D1,D5 ;MAKE A COPY
|
||
ROR.B #1,D1 ;REALIGN BITS
|
||
EOR.B D1,D5 ;ARE THEY THE SAME?
|
||
BNE.S @1 ;=>NO, DO NEW WAY
|
||
DBRA D0,@0 ;REPEAT FOR 8 BYTES
|
||
|
||
BSET #31,D6 ;ELSE FLAG OLD WAY
|
||
CLR -6(A1) ;AND SET PATROW = 0
|
||
|
||
@1 MOVE.L (A1),A1 ;GET EXPAT POINTER
|
||
|
||
SXTN2 MOVE.B (A0)+,D0 ;GET A BYTE OF PATTERN
|
||
EOR.B D7,D0 ;INVERT IT IF MODE BIT 2
|
||
ROL.B D2,D0 ;ALIGN TO LOCAL COORDS
|
||
|
||
MOVEQ #7,D1 ;ELSE 8 BITS PER BYTE
|
||
SXTN3 ADD.B D0,D0 ;GET ONE BIT OF SRC
|
||
BCS.S FORE16 ;BR IF FOREGROUND
|
||
|
||
BACK16 MOVE D4,(A1)+ ;PUT A WORD OF BACKGROUND TO DST
|
||
TST.L D6 ;DO OLD WAY?
|
||
BPL.S @1 ;NO, SKIP
|
||
MOVE D4,32-2(A1) ;YES, MAKE 2 COPIES
|
||
SUBQ #3,D1 ;SHORT CIRCUIT INNER LOOP
|
||
@1 DBRA D1,SXTN3 ;LOOP UNTIL DONE
|
||
NXTBYT DBRA D6,SXTN2 ;REPEAT FOR EACH BYTE
|
||
RTS ;AND RETURN
|
||
|
||
FORE16 MOVE D3,(A1)+ ;PUT A WORD OF FOREGROUND TO DST
|
||
TST.L D6 ;DO OLD WAY?
|
||
BPL.S @1 ;NO, SKIP
|
||
MOVE D3,32-2(A1) ;YES, MAKE 2 COPIES
|
||
SUBQ #3,D1 ;SHORT CIRCUIT INNER LOOP
|
||
@1 DBRA D1,SXTN3 ;LOOP UNTIL DONE
|
||
DBRA D6,SXTN2 ;REPEAT FOR EACH BYTE
|
||
RTS ;AND RETURN
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
; EXPAND AN 8*8 PATTERN FOR 32 BITS PER PIXEL
|
||
|
||
THRTWO1 MOVE #$20,(A1)+ ;PATROW = 32
|
||
MOVE #$001C,(A1)+ ;PATHMASK = $001C
|
||
MOVE #$00FF,(A1)+ ;PATVMASK = $00FF
|
||
|
||
; IF SOLID PATTERN, THEN DO OLD WAY FOR SPEED. <BAL 27Jun88>
|
||
|
||
MOVE.L A1,D5 ;SAVE A COPY IN D5
|
||
MOVE.L (A1),A1 ;GET EXPAT POINTER
|
||
MOVE.L A0,A2 ;COPY PATTERN POINTER
|
||
MOVEQ #7,D0 ;DO EIGHT BYTES
|
||
|
||
@NXTBYT MOVE.B (A2)+,D1 ;GET A BYTE
|
||
EOR.B D7,D1 ;INVERT IT IF MODE BIT 2
|
||
BNE.S @TRYFG ;SOLID 0's ?
|
||
MOVE.L D4,(A1)+ ;YES, PUT A LONG OF BACKGROUND TO DST
|
||
MOVE.L D4,32-4(A1) ;YES, PUT A LONG OF BACKGROUND TO DST
|
||
BRA.S @LOOP
|
||
|
||
@TRYFG ADDQ.B #1,D1 ;SOLID 1's ?
|
||
BNE.S @DONEW ;=>NO, DO NEW WAY
|
||
MOVE.L D3,(A1)+ ;YES, PUT A LONG OF FOREGROUND TO DST
|
||
MOVE.L D3,32-4(A1) ;YES, PUT A LONG OF FOREGROUND TO DST
|
||
@LOOP DBRA D0,@NXTBYT ;REPEAT FOR 8 BYTES
|
||
|
||
MOVE.L D5,A1 ;RESTORE A1
|
||
CLR -6(A1) ;FLAG OLD WAY: SET PATROW = 0
|
||
RTS
|
||
|
||
; PATTERN DOESN'T FIT IN A LONG SO DO NEW WAY
|
||
|
||
@DONEW MOVE.L D5,A1 ;RESTORE A1
|
||
MOVE.L (A1),A1 ;GET EXPAT POINTER
|
||
|
||
THRTWO2 MOVE.B (A0)+,D0 ;GET A BYTE OF PATTERN
|
||
EOR.B D7,D0 ;INVERT IT IF MODE BIT 2
|
||
ROL.B D2,D0 ;ALIGN TO LOCAL COORDS
|
||
|
||
MOVEQ #7,D1 ;8 BITS PER BYTE
|
||
THRTWO3 ADD.B D0,D0 ;GET ONE BIT OF SRC
|
||
BCS.S FORE32 ;BR IF FOREGROUND
|
||
|
||
BACK32 MOVE.L D4,(A1)+ ;PUT A LONG OF BACKGROUND TO DST
|
||
DBRA D1,THRTWO3 ;LOOP UNTIL DONE
|
||
DBRA D6,THRTWO2 ;REPEAT FOR EACH BYTE
|
||
RTS ;AND RETURN
|
||
|
||
FORE32 MOVE.L D3,(A1)+ ;PUT A LONG OF FOREGROUND TO DST
|
||
DBRA D1,THRTWO3 ;LOOP UNTIL DONE
|
||
DBRA D6,THRTWO2 ;REPEAT FOR EACH BYTE
|
||
RTS ;AND RETURN
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; SCALE UP BY 32 (thanks to gary)
|
||
;
|
||
THRTWO
|
||
MOVEQ #31,D2 ;32 output longs
|
||
MOVE.L (A0)+,D0 ;fetch a long of src
|
||
@NxtBit ADD.L D0,D0 ;extend high bit into long
|
||
SUBX.L D1,D1
|
||
MOVE.L D1,(A1)+
|
||
CMP.L A2,A1 ;IS DSTPTR >= DSTLIMIT ?
|
||
DBHS D2,@NxtBit ;process remaining bits
|
||
BLO THRTWO ;fetch next input long
|
||
RTS ;ALL DONE
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; SCALE UP FROM B/W 1-bit to 15 bit direct device (16 bits/pixel) <BAL 06Dec88>
|
||
;
|
||
BWtoD15 MOVE.W #$7fff,D2 ;get high bit mask
|
||
MOVE.L A2,D3 ;get limit ptr
|
||
SUB.L A1,D3 ;get byte count in D3
|
||
ROR.L #6,D3 ;D3.w = # of 32 words to build
|
||
BRA.S @Do32
|
||
|
||
@NxtLng MOVEQ #31,D4 ;init bits per long counter
|
||
MOVE.L (A0)+,D0 ;get next src long
|
||
NOT.L D0 ;make 1's go to 1's
|
||
@NxtBit ADD.L D0,D0 ;get one bit of src into X bit
|
||
SUBX.W D1,D1 ;get a word of X bits
|
||
AND.W D2,D1 ;clear out high bit of pixel
|
||
MOVE.W D1,(A1)+ ;dump out result
|
||
DBRA D4,@NxtBit ;continue for all bits in long
|
||
@Do32 DBRA D3,@NxtLng ;go reload the source long
|
||
|
||
CLR.W D3 ;clr out low word
|
||
ROL.L #5,D3 ;get word cnt mod 32
|
||
MOVE.L (A0)+,D0 ;get last src long
|
||
NOT.L D0
|
||
BRA.S @DoRest
|
||
|
||
@NxtOne ADD.L D0,D0 ;get one bit of src into X bit
|
||
SUBX.W D1,D1 ;get a word of X bits
|
||
AND.W D2,D1 ;clear out high bit of pixel
|
||
MOVE.W D1,(A1)+ ;dump out result
|
||
@DoRest DBRA D3,@NxtOne ;go process another bit
|
||
RTS
|
||
|
||
ALIGN Alignment
|
||
|
||
;-------------------------------------------------
|
||
;
|
||
; SCALE UP BY 16 (thanks to Gary Davidian)
|
||
; with colorizing
|
||
;
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
|
||
BWtoD15Alpha
|
||
MOVE.L alphaFore(A6),D3 ;get alpha fg expansion mask <42>
|
||
MOVE.L alphaBack(A6),D4 ;get alpha bk expansion mask <42>
|
||
BRA.S XXSIXTEEN ;fall into expansion code <42>
|
||
SIXTEENColor
|
||
move.l fcolor(a6),d3
|
||
move.l bcolor(a6),d4
|
||
XXSIXTEEN
|
||
@SIXTEEN
|
||
MOVEQ #15,D2 ;16 output longs
|
||
MOVE.L (A0)+,D0 ;fetch a long of src
|
||
@NxtBit ADD.L D0,D0 ;extend first bit into hi word
|
||
SUBX.L D1,D1
|
||
ADD.L D0,D0 ;extend next bit into lo word
|
||
SUBX.W D1,D1
|
||
;
|
||
;colorize
|
||
;
|
||
MOVE.L D1,D5 ;copy of source
|
||
NOT.L D1 ;turn on background bits
|
||
AND.L D3,D5 ;color same as background color
|
||
AND.L D4,D1 ;color foreground bits same as foreground color
|
||
OR.L D5,D1 ;combine colored foreground and background bits
|
||
|
||
MOVE.L D1,(A1)+
|
||
CMP.L A2,A1 ;IS DSTPTR >= DSTLIMIT ?
|
||
DBHS D2,@NxtBit ;process remaining bits
|
||
BLO @SIXTEEN ;fetch next input long
|
||
RTS ;ALL DONE
|
||
|
||
ALIGN Alignment
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; SCALE UP BY 32 (thanks to gary)
|
||
;
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
|
||
BWtoD24Alpha
|
||
MOVE.L alphaFore(A6),D3 ;get alpha fg expansion mask <42>
|
||
MOVE.L alphaBack(A6),D4 ;get alpha bk expansion mask <42>
|
||
BRA.S XXTHRTWO ;fall into expansion code <42>
|
||
THRTWOColor
|
||
move.l fcolor(a6),d3
|
||
move.l bcolor(a6),d4
|
||
XXTHRTWO
|
||
@THRTWO
|
||
MOVEQ #31,D2 ;32 output longs
|
||
MOVE.L (A0)+,D0 ;fetch a long of src
|
||
@NxtBit ADD.L D0,D0 ;extend high bit into long
|
||
SUBX.L D1,D1
|
||
;
|
||
;colorize
|
||
;
|
||
MOVE.L D1,D5 ;copy of source
|
||
NOT.L D1 ;turn on background bits
|
||
AND.L D3,D5 ;color same as background color
|
||
AND.L D4,D1 ;color foreground bits same as foreground color
|
||
OR.L D5,D1 ;combine colored foreground and background bits
|
||
|
||
MOVE.L D1,(A1)+
|
||
CMP.L A2,A1 ;IS DSTPTR >= DSTLIMIT ?
|
||
DBHS D2,@NxtBit ;process remaining bits
|
||
BLO @THRTWO ;fetch next input long
|
||
RTS ;ALL DONE
|
||
|
||
ALIGN Alignment
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; SCALE UP FROM B/W 1-bit to 24 bit direct device (32 bits/pixel) <BAL 28Jun 88>
|
||
;
|
||
BWtoD24 MOVE.L maskBC,D2 ;high byte clearing mask
|
||
MOVE.L A2,D3 ;get limit ptr
|
||
SUB.L A1,D3 ;get byte count in D3
|
||
ROR.L #7,D3 ;D3.w = # of 32 longs to build
|
||
BRA.S @Do32
|
||
|
||
@NxtLng MOVEQ #31,D4 ;init bits per long counter
|
||
MOVE.L (A0)+,D0 ;get next src long
|
||
NOT.L D0
|
||
@NxtBit ADD.L D0,D0 ;get one bit of src into X bit
|
||
SUBX.L D1,D1 ;get a word of X bits
|
||
AND.L D2,D1 ;clear out high bit of pixel
|
||
MOVE.L D1,(A1)+ ;dump out result
|
||
DBRA D4,@NxtBit ;continue for all bits in long
|
||
@Do32 DBRA D3,@NxtLng ;go reload the source long
|
||
|
||
CLR.W D3 ;clr out low word
|
||
ROL.L #5,D3 ;get long cnt mod 32
|
||
MOVE.L (A0)+,D0 ;get last src long
|
||
NOT.L D0
|
||
BRA.S @DoRest
|
||
|
||
@NxtOne ADD.L D0,D0 ;get one bit of src into X bit
|
||
SUBX.L D1,D1 ;get a word of X bits
|
||
AND.L D2,D1 ;clear out high bit of pixel
|
||
MOVE.L D1,(A1)+ ;dump out result
|
||
@DoRest DBRA D3,@NxtOne ;go process another bit
|
||
RTS
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
|
||
;-----------------------------------------------
|
||
;
|
||
; SCALE UP BY ANY MULTIPLE OF 8 GREATER THAN 2
|
||
;
|
||
EIGHTS LSR #3,D4 ;DIVIDE SCALE FACTOR BY 8
|
||
SUB #1,D4 ;SUB 1 FOR LOOP COUNT
|
||
MOVE #$8000,D0 ;INIT SRC DATA
|
||
EIGHTS1 ADD D0,D0 ;GET ONE SRC BIT IN CARRY
|
||
BNE.S EIGHTS2 ;TIME FOR NEW SRC ?
|
||
MOVE (A0)+,D0 ;YES, GET NEXT SRC LONG
|
||
ADDX D0,D0 ;SHIFT SRC BIT OUT, 1 BIT IN
|
||
EIGHTS2 SCS D1 ;SET OR CLR A BYTE
|
||
MOVE D4,D2 ;INIT LOOP COUNT
|
||
EIGHTS3 MOVE.B D1,(A1)+ ;PUT ONE BYTE TO DST
|
||
CMP.L A2,A1 ;IS DSTPTR >= DSTLIMIT ?
|
||
DBHI D2,EIGHTS3 ;LOOP TILL SCALE OR DST FULL
|
||
BLS EIGHTS1 ;MORE SRC IF DST NOT FULL
|
||
rts ;THEN QUIT @@@@ 04May88 BAL used to be BRA DONE
|
||
|
||
|
||
IF 0 THEN
|
||
;------------------------------------------------------------------
|
||
;
|
||
; DO FULL RATIO SCALING, SHRINKING ONE BIT AT A TIME
|
||
;
|
||
SHRINK MOVEM.L D7/D6,-(SP) ;save d7
|
||
|
||
MOVEQ #0,D1 ;INIT DST WORD
|
||
MOVE #$1F,D2 ;init bit counter
|
||
MOVEQ #1,D0 ;GET 1 INTO HIGH BIT
|
||
ROR.L #1,D0 ;TO INIT DATA STREAM
|
||
MOVE.L D4,D3 ;COPY RATIO
|
||
LSR.L #1,D3 ;INIT ERR TO RATIO/2
|
||
MOVE.L D3,D7 ;init bit accum to ratio/2
|
||
MOVEQ #1,D6 ;use D6 to test for overflow
|
||
SWAP D6 ;into high word
|
||
|
||
NXTSRC1 ADD.L D0,D0 ;GET SRC BIT
|
||
BCC.S WHITE1 ;BRANCH IF WHITE
|
||
BNE.S BLACK1 ;BRANCH IF BLACK
|
||
MOVE.L (A0)+,D0 ;ELSE GET NEW SRC WORD
|
||
ADDX.L D0,D0 ;GET SRC BIT
|
||
BCC.S WHITE1 ;AND CONTINUE
|
||
|
||
BLACK1 ADD.L D4,D7 ;add weight of a set bit
|
||
WHITE1 CMP.L D6,D7 ;overflow into high word yet?
|
||
BLE.S FSCAN ;=>no, continue scanning
|
||
BSET D2,D1 ;else set the bit
|
||
BNE.S FSCAN ;=>if already set, save for next time
|
||
SUB.L D6,D7 ;subtract one for bit we set
|
||
FSCAN ADD D4,D3 ;TIME FOR NEXT DSTBIT ?
|
||
BCC NXTSRC1 ;NO, LOOP MORE SRC
|
||
SUBQ #1,D2 ;yes, do next bit
|
||
BPL.S NXTSRC1 ;loop if dst word ok
|
||
MOVE.L D1,(A1)+ ;ELSE WRITE WORD TO DST
|
||
MOVEQ #0,D1 ;INIT DST WORD
|
||
MOVE #$1F,D2 ;and reset bit counter
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT ?
|
||
BLO.S NXTSRC1 ;NO, LOOP
|
||
|
||
MOVEM.L (SP)+,D7/D6 ;restore d7
|
||
RTS ;YES, QUIT
|
||
|
||
ELSE
|
||
|
||
ALIGN Alignment
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; DO FULL RATIO SCALING, SHRINKING ONE BIT AT A TIME
|
||
;
|
||
SHRINK CLR D1 ;INIT DST WORD
|
||
MOVE #$8000,D0 ;INIT SRC WORD
|
||
MOVE D0,D2 ;INIT MASK
|
||
MOVE D4,D3 ;COPY RATIO
|
||
LSR #1,D3 ;INIT ERR TO RATIO/2
|
||
|
||
NXTSRC1 ADD D0,D0 ;GET SRC BIT
|
||
BCC.S WHITE1 ;BRANCH IF WHITE
|
||
BNE.S BLACK1 ;BRANCH IF BLACK
|
||
MOVE (A0)+,D0 ;ELSE GET NEW SRC WORD
|
||
ADDX D0,D0 ;GET SRC BIT
|
||
BCC.S WHITE1 ;AND CONTINUE
|
||
|
||
BLACK1 OR D2,D1 ;SET A BIT IN DST
|
||
WHITE1 ADD D4,D3 ;TIME FOR NEXT DSTBIT ?
|
||
BCC NXTSRC1 ;NO, LOOP MORE SRC
|
||
ROR #1,D2 ;YES, ROTATE MASK
|
||
BCC NXTSRC1 ;LOOP IF DST WORD OK
|
||
MOVE D1,(A1)+ ;ELSE WRITE WORD TO DST
|
||
CLR D1 ;RESET DST WORD
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT ?
|
||
BLO NXTSRC1 ;NO, LOOP
|
||
RTS ;YES, QUIT
|
||
|
||
ENDIF
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; DO FULL RATIO SCALING, STRETCHING ONE BIT AT A TIME
|
||
;
|
||
STRCH CLR D1 ;INIT DST WORD
|
||
MOVE #$8000,D0 ;INIT SRC WORD
|
||
MOVE D0,D2 ;INIT MASK
|
||
MOVE D4,D3 ;COPY RATIO
|
||
LSR #1,D3 ;INIT ERR TO RATIO/2
|
||
|
||
@NXTSRC ADD D0,D0 ;GET SRC BIT
|
||
BCC.S @WHITE ;BRANCH IF WHITE
|
||
BNE.S @BLACK ;BRANCH IF BLACK
|
||
MOVE (A0)+,D0 ;ELSE GET NEW SRC WORD
|
||
ADDX D0,D0 ;GET SRC BIT
|
||
BCC.S @WHITE ;CONTINUE WITH WHITE
|
||
BRA.S @BLACK ;CONTINUE WITH BLACK
|
||
|
||
@BLKOK ADD D4,D3 ;TIME FOR NEXT SRC BIT ?
|
||
BCS @NXTSRC ;YES, LOOP FOR SRC
|
||
@BLACK OR D2,D1 ;SET A BIT OF DST
|
||
ROR #1,D2 ;ROTATE MASK
|
||
BCC @BLKOK ;LOOP IF DST WORD OK
|
||
MOVE D1,(A1)+ ;ELSE WRITE WORD TO DST
|
||
CLR D1 ;RESET DST WORD
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT ?
|
||
BLO @BLKOK ;NO, LOOP
|
||
RTS ;YES, QUIT
|
||
|
||
@WHTOK ADD D4,D3 ;TIME FOR NEXT SRC BIT ?
|
||
BCS @NXTSRC ;YES, LOOP FOR SRC
|
||
@WHITE ROR #1,D2 ;ROTATE MASK
|
||
BCC @WHTOK ;LOOP IF DST WORD OK
|
||
MOVE D1,(A1)+ ;ELSE WRITE WORD TO DST
|
||
CLR D1 ;RESET DST WORD
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT ?
|
||
BLO @WHTOK ;NO, LOOP
|
||
|
||
@DONE RTS
|
||
|
||
IF 0 THEN
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; DO FULL-RATIO COLOR SCALING, SHRINKING ONE PIXEL AT A TIME
|
||
; altered to use area averaging 9/3/88 BAL
|
||
;
|
||
|
||
; D0.L = src data A0.L = ptr to src scan
|
||
; D1.L = dst data A1.L = ptr to dst scan
|
||
; D2.L = src offset A2.L = limit ptr
|
||
; D3.W = error term A3.W = ratio < 1.0
|
||
; D4.L = scratch A4 = scratch
|
||
; D5.W = bits/pixel A5 = scratch
|
||
; D6.L = dst offset A6 = locals
|
||
; D7.W = long mask A7 = stack
|
||
|
||
;ciPIXSHRNK
|
||
PIXSHRNK
|
||
tst.b useAverage(a6) ;use area averaging?
|
||
bne.s averageH ;yes, average pixels
|
||
|
||
;Not 32 bit deep so point sample for now:
|
||
|
||
MOVEM.L D6/D7,-(SP) ;SAVE WORK REGISTERS
|
||
MOVE D4,A3 ;GET RATIO IN A3
|
||
MOVE D4,D3 ;COPY RATIO
|
||
LSR #1,D3 ;INIT ERR TO RATIO/2
|
||
MOVEQ #0,D2 ;INIT OFFSET INTO SRC
|
||
MOVEQ #0,D6 ;INIT OFFSET INTO DST
|
||
MOVEQ #$1F,D7 ;GET MASK FOR LONGS
|
||
;EXT.L D5 ;MAKE SURE D5 IS LONG
|
||
MOVE.L (A0)+,D0 ;GET FIRST SRC LONG
|
||
MOVEQ #0,D1 ;INIT FIRST DST LONG TO 0
|
||
@NXTDST ;SUB.L A4,A4 ;INIT DST PIXEL VALUE TO 0
|
||
@NXTSRC ;BFEXTU D0{D2:D5},D4 ;GET A PIXEL OF SRC
|
||
;CMP.L A4,D4 ;COMPARE AGAINST DST
|
||
;BLS.S @ADVSRC ;IF SRC < DST, DON'T REPLACE
|
||
;BFINS D4,D1{D6:D5} ;ELSE REPLACE PIXEL
|
||
;MOVE.L D4,A4 ;AND SAVE AS DST CONTENTS
|
||
@ADVSRC ADD.L D5,D2 ;BUMP TO NEXT SRC PIXEL
|
||
AND D7,D2 ;TIME FOR NEXT SRC LONG?
|
||
BNE.S @0 ;=>NO
|
||
MOVE.L (A0)+,D0 ;ELSE GET NEXT SRC LONG
|
||
@0 ADD A3,D3 ;TIME FOR NEXT DST PIXEL?
|
||
BCC.S @NXTSRC ;NO, GET NEXT SRC PIXEL
|
||
|
||
BFEXTU D0{D2:D5},D4 ;GET A PIXEL OF SRC
|
||
BFINS D4,D1{D6:D5} ;ELSE REPLACE PIXEL
|
||
|
||
ADD.L D5,D6 ;ADVANCE TO NEXT DST PIXEL
|
||
AND D7,D6 ;TIME FOR NEXT DST LONG?
|
||
BNE.S @NXTDST ;=>NO
|
||
MOVE.L D1,(A1)+ ;ELSE SAVE CURRENT DST LONG
|
||
MOVEQ #0,D1 ;INIT DST LONG TO 0
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @NXTDST ;=>NO, COPY NEXT SRC TO NEXT DST
|
||
MOVEM.L (SP)+,D6/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
ELSE
|
||
|
||
ALIGN Alignment
|
||
|
||
;32 bit deep pixels —— do full color pixel averaging:
|
||
|
||
; D0.L = src data A0.L = ptr to src scan
|
||
; D1.L = dst data A1.L = ptr to dst scan
|
||
; D2.W = ratio < 1.0 A2.L = limit ptr
|
||
; D3.W = error term A3.L = red accum
|
||
; D4.W = src pix cnt A4.L = grn accum
|
||
; D5.L = scratch A5.L = blu accum
|
||
; D6.L = preserved A6 = locals
|
||
; D7.L = preserved A7 = stack
|
||
|
||
AverageH32
|
||
MOVEM.L D5/A5,-(SP) ;SAVE WORK REGISTERS
|
||
MOVE D4,D2 ;GET RATIO IN D2
|
||
MOVE D4,D3 ;COPY RATIO
|
||
LSR #1,D3 ;INIT ERR TO RATIO/2
|
||
cmp.w #16,d5 ;16 bits/pixel? <KON 2/22/90>
|
||
beq.s averageH16 ;yes, average <KON 2/22/90>
|
||
|
||
MOVEQ #0,D5 ;clear out working register
|
||
move.l d5,a3 ;clear out working register <29AUG90 KON>
|
||
bra.s @NXTDST ; enter the loop <1.7>
|
||
|
||
@1to1 MOVE.L (A0)+,(A1)+ ;copy source to dest <1.7>
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT? <1.7>
|
||
bhs.s HShrinkDone ;=>yes, all done <1.7>
|
||
@NXTDST add.w D2,D3 ;is mapping 1 to 1? <1.7>
|
||
bcs.s @1to1 ;if so, just copy the pixel <1.7>
|
||
|
||
MOVE.L (A0)+,D0 ;GET A PIXEL OF SRC <1.7>
|
||
move.b d0,d5 ;get blue component <1.7>
|
||
move.w d5,a5 ;INIT accumulated blu <1.7>
|
||
lsr.w #8,d0 ;get green component <1.7>
|
||
move.w d0,a4 ;INIT accumulated grn <1.7>
|
||
swap d0 ;get red component <1.7>
|
||
move.b d0,d5 ;extend to word <1.7>
|
||
move.w d5,a3 ;INIT accumulated red <1.7>
|
||
moveq #1,d4 ;init src pixel count <1.7>
|
||
|
||
@NXTSRC MOVE.L (A0)+,D0 ;GET A PIXEL OF SRC
|
||
addq.w #1,d4 ;inc cnt of src pixels for this dst
|
||
move.b d0,d5 ;extend to word
|
||
add.w d5,a5 ;accumulate blue component
|
||
lsr.w #8,d0 ;toss blue component
|
||
add.w d0,a4 ;accumulate green component
|
||
swap d0 ;toss green component
|
||
move.b d0,d5 ;extend to word
|
||
add.w d5,a3 ;accumulate red component
|
||
|
||
ADD D2,D3 ;TIME FOR NEXT DST PIXEL?
|
||
BCC.S @NXTSRC ;NO, GET NEXT SRC PIXEL
|
||
|
||
cmp.w #2,d4 ;how many pixels are being averaged?
|
||
blt.s @noDiv ;only one src pixel so skip divides
|
||
beq.s @doShift ;two src pixels so use shifts
|
||
|
||
@hardWay
|
||
moveq #0,d1 ;clear out dst pixel
|
||
move.l a3,d0 ;get red total
|
||
divu.w d4,d0 ;get red avrg
|
||
move.b d0,d1 ;save result
|
||
lsl.l #8,d1 ;make room for next component
|
||
move.l a4,d0 ;get grn total
|
||
divu.w d4,d0 ;get grn avrg
|
||
move.b d0,d1 ;save result
|
||
lsl.l #8,d1 ;make room for next component
|
||
move.l a5,d0 ;get blu total
|
||
divu.w d4,d0 ;get blu avrg
|
||
move.b d0,d1 ;save result
|
||
bra.s @noDiv
|
||
|
||
@doShift
|
||
move.l a3,d1 ;get red total, clear out dst pixel <1.7>
|
||
lsl.w #7,d1 ;get red avrg, make room for next component <1.7>
|
||
move.l a4,d0 ;get grn total
|
||
lsr.w #1,d0 ;get grn avrg <1.7>
|
||
move.b d0,d1 ;save result
|
||
lsl.l #8,d1 ;make room for next component <1.7>
|
||
move.l a5,d0 ;get blu total
|
||
lsr.w #1,d0 ;get blu avrg
|
||
move.b d0,d1 ;save result
|
||
|
||
@noDiv
|
||
MOVE.L D1,(A1)+ ;ELSE SAVE CURRENT DST LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @NXTDST ;=>NO, COPY NEXT SRC TO NEXT DST
|
||
HShrinkDone
|
||
MOVEM.L (SP)+,D5/A5 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
;------------16 bit average <KON 2/22/90> -----------------------
|
||
;
|
||
;16 bit deep pixels —— do full color pixel averaging:
|
||
|
||
; D0.L = src data A0.L = ptr to src scan
|
||
; D1.L = dst data A1.L = ptr to dst scan
|
||
; D2.W = ratio < 1.0 A2.L = limit ptr
|
||
; D3.W = error term A3.L = red accum
|
||
; D4.W = src pix cnt A4.L = grn accum
|
||
; D5.L = scratch A5.L = blu accum
|
||
; D6.L = preserved A6 = locals
|
||
; D7.L = preserved A7 = stack
|
||
|
||
; from QDciPatchROM.a verbatim (except for commented-out stack stuff) <sm 6/9/92>stb
|
||
|
||
; MOVEM.L D5/A5,-(SP) ;SAVE WORK REGISTERS (saved above in 32-bit case)
|
||
; MOVE D4,D2 ;GET RATIO IN D2 (done in 32-bit case above)
|
||
; MOVE D4,D3 ;COPY RATIO (done in 32-bit case above)
|
||
; LSR #1,D3 ;INIT ERR TO RATIO/2 (done in 32-bit case above)
|
||
AverageH16
|
||
|
||
MOVEQ #0,D5 ;clear out working register
|
||
bra.s @NXTDST ; enter the loop
|
||
|
||
@1to1 MOVE.w (A0)+,(A1)+ ;copy source to dest
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
bhs.s HShrinkDone ;=>yes, all done
|
||
|
||
@NXTDST moveq #0,d0 ;to extend to long
|
||
add.w D2,D3 ;is mapping 1 to 1?
|
||
bcs.s @1to1 ;if so, just copy the pixel
|
||
|
||
MOVE.w (A0)+,D0 ;GET a PIXEL OF SRC
|
||
move.b d0,d5 ;get blue component
|
||
and.b #$1F,d5
|
||
move.w d5,a5 ;INIT accumulated blu
|
||
|
||
lsr.w #5,d0 ;get green component
|
||
move.b d0,d5 ;INIT accumulated grn
|
||
and.b #$1F,d5
|
||
move.w d5,a4
|
||
|
||
lsr.w #5,d0 ;get red component
|
||
and.b #$1F,d0 ;extend to word
|
||
move.w d0,a3 ;INIT accumulated red
|
||
moveq #1,d4 ;init src pixel count
|
||
|
||
@NXTSRC MOVE.w (A0)+,D0 ;GET A PIXEL OF SRC
|
||
addq.w #1,d4 ;inc cnt of src pixels for this dst
|
||
move.b d0,d5 ;extend to word
|
||
and.b #$1F,d5 ;5-bits of blue
|
||
add.w d5,a5 ;accumulate blue component
|
||
|
||
lsr.w #5,d0 ;toss blue component
|
||
move.b d0,d5
|
||
and.b #$1F,d5
|
||
add.w d5,a4 ;accumulate green component
|
||
|
||
lsr.w #5,d0 ;toss green component
|
||
and.b #$1F,d0 ;extend to word
|
||
add.w d0,a3 ;accumulate red component
|
||
|
||
ADD D2,D3 ;TIME FOR NEXT DST PIXEL?
|
||
BCC.S @NXTSRC ;NO, GET NEXT SRC PIXEL
|
||
|
||
cmp.w #2,d4 ;how many pixels are being averaged?
|
||
; blt.s @noDiv ;Can't Happen ;;only one src pixel so skip divides
|
||
beq.s @doShift ;two src pixels so use shifts
|
||
|
||
@hardWay
|
||
moveq #0,d1 ;clear out dst pixel
|
||
move.l a3,d0 ;get red total
|
||
divu.w d4,d0 ;get red avrg
|
||
move.b d0,d1 ;save result
|
||
|
||
lsl.l #5,d1 ;make room for next component
|
||
move.l a4,d0 ;get grn total
|
||
divu.w d4,d0 ;get grn avrg
|
||
or.b d0,d1 ;save result
|
||
|
||
lsl.l #5,d1 ;make room for next component
|
||
move.l a5,d0 ;get blu total
|
||
divu.w d4,d0 ;get blu avrg
|
||
or.b d0,d1 ;save result
|
||
bra.s @noDiv
|
||
|
||
@doShift
|
||
move.l a3,d1 ;get red total, clear out dst pixel <1.7>
|
||
and.w #$003E,d1 ;only want 5 bits.
|
||
lsl.w #4,d1 ;get red avrg, make room for next component <1.7>
|
||
move.l a4,d0 ;get grn total
|
||
lsr.w #1,d0 ;get grn avrg <1.7>
|
||
or.b d0,d1 ;save result
|
||
lsl.l #5,d1 ;make room for next component <1.7>
|
||
move.l a5,d0 ;get blu total
|
||
lsr.w #1,d0 ;get blu avrg
|
||
or.b d0,d1 ;save result
|
||
|
||
@noDiv
|
||
MOVE.w D1,(A1)+ ;ELSE SAVE CURRENT DST word
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @NXTDST ;=>NO, COPY NEXT SRC TO NEXT DST
|
||
bra.s HShrinkDone
|
||
;@done MOVEM.L (SP)+,D5/A5 ;RESTORE WORK REGISTERS
|
||
; RTS
|
||
|
||
NOAVRG
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; DO FULL-RATIO COLOR SCALING, SHRINKING ONE PIXEL AT A TIME
|
||
;
|
||
|
||
; D0.L = src data A0.L = ptr to src scan
|
||
; D1.L = dst data A1.L = ptr to dst scan
|
||
; D2.L = src offset A2.L = limit ptr
|
||
; D3.W = error term A3.W = ratio < 1.0
|
||
; D4.L = scratch A4 = scratch
|
||
; D5.W = bits/pixel A5 = scratch
|
||
; D6.L = dst offset A6 = locals
|
||
; D7.L = long mask A7 = stack
|
||
|
||
PIXSHRNK
|
||
|
||
; tst.b useAverage(a6) ;use area averaging?
|
||
cmp.w #16,d5 ;32 bits/pixel?
|
||
bge.s averageH32 ;yes, average pixels
|
||
ENDIF
|
||
|
||
MOVEM.L D6/D7,-(SP) ;SAVE WORK REGISTERS
|
||
MOVE D4,A3 ;GET RATIO IN A3
|
||
MOVE D4,D3 ;COPY RATIO
|
||
LSR #1,D3 ;INIT ERR TO RATIO/2
|
||
MOVEQ #0,D2 ;INIT OFFSET INTO SRC
|
||
MOVEQ #0,D6 ;INIT OFFSET INTO DST
|
||
MOVEQ #$1F,D7 ;GET MASK FOR LONGS
|
||
EXT.L D5 ;MAKE SURE D5 IS LONG
|
||
MOVE.L (A0)+,D0 ;GET FIRST SRC LONG
|
||
MOVEQ #0,D1 ;INIT FIRST DST LONG TO 0
|
||
NXTDST SUB.L A4,A4 ;INIT DST PIXEL VALUE TO 0
|
||
NXTSRC BFEXTU D0{D2:D5},D4 ;GET A PIXEL OF SRC
|
||
CMP.L A4,D4 ;COMPARE AGAINST DST
|
||
BLS.S ADVSRC ;IF SRC < DST, DON'T REPLACE
|
||
BFINS D4,D1{D6:D5} ;ELSE REPLACE PIXEL
|
||
MOVE.L D4,A4 ;AND SAVE AS DST CONTENTS
|
||
ADVSRC ADD.L D5,D2 ;BUMP TO NEXT SRC PIXEL
|
||
AND D7,D2 ;TIME FOR NEXT SRC LONG?
|
||
BNE.S @0 ;=>NO
|
||
MOVE.L (A0)+,D0 ;ELSE GET NEXT SRC LONG
|
||
@0 ADD A3,D3 ;TIME FOR NEXT DST PIXEL?
|
||
BCC.S NXTSRC ;NO, GET NEXT SRC PIXEL
|
||
ADD.L D5,D6 ;ADVANCE TO NEXT DST PIXEL
|
||
AND D7,D6 ;TIME FOR NEXT DST LONG?
|
||
BNE.S NXTDST ;=>NO
|
||
MOVE.L D1,(A1)+ ;ELSE SAVE CURRENT DST LONG
|
||
MOVEQ #0,D1 ;INIT DST LONG TO 0
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S NXTDST ;=>NO, COPY NEXT SRC TO NEXT DST
|
||
MOVEM.L (SP)+,D6/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
|
||
ALIGN Alignment
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; DO FULL-RATIO COLOR SCALING, STRETCHING ONE PIXEL AT A TIME
|
||
;
|
||
PIXSTR MOVEM.L D6/D7,-(SP) ;SAVE WORK REGISTERS
|
||
MOVE D4,A3 ;GET RATIO IN A3
|
||
MOVE D4,D3 ;COPY RATIO
|
||
LSR #1,D3 ;INIT ERR TO RATIO/2
|
||
MOVEQ #0,D2 ;INIT OFFSET INTO SRC
|
||
MOVEQ #0,D6 ;INIT OFFSET INTO DST
|
||
MOVEQ #$1F,D7 ;GET MASK FOR LONGS
|
||
EXT.L D5 ;MAKE SURE D5 IS LONG
|
||
NXTSRC3 MOVE.L (A0)+,D0 ;GET FIRST LONG OF SRC
|
||
NXTSRC4 BFEXTU D0{D2:D5},D4 ;GET A PIXEL OF SRC
|
||
NXTDST1 BFINS D4,D1{D6:D5} ;PUT TO DST LONG
|
||
ADD.L D5,D6 ;BUMP TO NEXT DST PIXEL
|
||
AND D7,D6 ;TIME FOR NEXT DST LONG?
|
||
BNE.S @0 ;=>NO
|
||
MOVE.L D1,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BHS.S DONESTR ;=>YES, RETURN
|
||
@0 ADD.W A3,D3 ;TIME FOR NEXT SRC PIXEL?
|
||
BCC.S NXTDST1 ;=>NO, PUT NEXT DST PIXEL
|
||
ADD.L D5,D2 ;ADVANCE TO NEXT SRC PIXEL
|
||
AND D7,D2 ;TIME FOR NEXT SRC LONG?
|
||
BNE.S NXTSRC4 ;=>NO, GET NEXT SRC PIXEL
|
||
BRA.S NXTSRC3 ;=>ELSE GET NEXT SRC LONG
|
||
DONESTR MOVEM.L (SP)+,D6/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
|
||
|
||
ScaleIndexedToIndexed PROC EXPORT
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM ONE DEPTH TO ANOTHER
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
; A4: PIXEL TRANSLATE TABLE
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
MOVEM.L D6/D7,-(SP) ;SAVE WORK REGISTERS
|
||
MOVEQ #0,D1 ;INIT OFFSET INTO SRC
|
||
MOVEQ #0,D2 ;INIT OFFSET INTO DST
|
||
MOVEQ #$1F,D7 ;GET MASK FOR LONGS
|
||
BRA.S NXTSLNG
|
||
|
||
NXTDPXL ADD D3,D1 ;ADVANCE TO NEXT SRC PIXEL
|
||
AND D7,D1 ;TIME FOR NEXT SRC LONG?
|
||
BNE.S NXTSPXL ;ELSE GET NEXT PIXEL
|
||
NXTSLNG MOVE.L (A0)+,D5 ;GET FIRST LONG OF SRC
|
||
NXTSPXL BFEXTU D5{D1:D3},D0 ;GET A PIXEL OF SRC
|
||
move.l 0(A4,D0*4),D0 ;TRANSLATE IT <BAL 09May88> @@@@
|
||
BFINS D0,D6{D2:D4} ;PUT TO DST LONG
|
||
ADD D4,D2 ;BUMP TO NEXT DST PIXEL
|
||
AND D7,D2 ;TIME FOR NEXT DST LONG?
|
||
BNE.S NXTDPXL ;=>NO
|
||
MOVE.L D6,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S NXTDPXL ;=>YES, RETURN
|
||
DONESCL MOVEM.L (SP)+,D6/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
|
||
Dither32toIndexed PROC EXPORT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 1-8 BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
; A4: PIXEL TRANSLATE TABLE
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
|
||
MOVEM.L A3/A5/D6/D7,-(SP) ;SAVE WORK REGISTERS
|
||
|
||
MOVE.L ErrBuf(a6),A4 ;get ptr to ErrBuf
|
||
MOVEQ #0,D2 ;INIT OFFSET INTO DST
|
||
MOVE.L D2,D5 ;init redAccum
|
||
MOVE.L D2,D6 ;init grnAccum
|
||
MOVE.L D2,D7 ;init bluAccum
|
||
not.b errDir(a6) ;check and toggle diffusion direction
|
||
bne.s @forward
|
||
|
||
move.l ErrSrcBuf(a6),a0 ;point to end of srcBuf
|
||
moveq #32,d2 ;init dst offset in long
|
||
|
||
@back2
|
||
sub.w D4,D2 ;pre-BUMP TO NEXT DST PIXEL
|
||
@backward
|
||
sub.w #6,a4
|
||
MOVE.L -(A0),D0 ;GET NEXT LONG OF SRC
|
||
bsr.s ditherCore
|
||
|
||
moveq #0,d3
|
||
asr.w #1,d5 ;get half red error
|
||
move.w d5,0(a4) ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d5
|
||
asr.w #1,d6 ;get half grn error
|
||
move.w d6,2(a4) ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d6
|
||
asr.w #1,d7 ;get half blu error
|
||
move.w d7,4(a4) ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d7
|
||
|
||
sub.w D4,D2 ;BUMP TO NEXT DST PIXEL
|
||
bge.s @backward ;TIME FOR NEXT DST LONG? =>NO
|
||
moveq #32,d2
|
||
MOVE.L D1,-(A2) ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @back2 ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
bra.s donescl
|
||
|
||
@forward
|
||
MOVE.L (A0)+,D0 ;GET NEXT LONG OF SRC
|
||
bsr.s ditherCore
|
||
|
||
moveq #0,d3
|
||
asr.w #1,d5 ;get half red error
|
||
move.w d5,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d5
|
||
asr.w #1,d6 ;get half grn error
|
||
move.w d6,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d6
|
||
asr.w #1,d7 ;get half blu error
|
||
move.w d7,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d7
|
||
|
||
@again
|
||
ADD D4,D2 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1F,D2 ;TIME FOR NEXT DST LONG?
|
||
BNE.S @forward ;=>NO
|
||
MOVE.L D1,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @forward ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
move.l a0,ErrSrcBuf(a6) ;point to end of srcBuf for right to left diffusion
|
||
|
||
DONESCL
|
||
MOVEM.L (SP)+,A3/A5/D6/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
DitherCore
|
||
add.w (a4),D5 ;consume red error from above
|
||
add.w 2(a4),D6 ;consume grn error from above
|
||
add.w 4(a4),D7 ;consume blu error from above
|
||
moveq #0,d3 ;clear out temp
|
||
|
||
move.b d0,d3 ;get blue as a word
|
||
add.w d3,d7 ;accumulate blue
|
||
lsr.w #8,d0 ;toss blue
|
||
|
||
add.w d0,d6 ;accumulate green
|
||
swap d0 ;toss green
|
||
|
||
move.b d0,d3 ;get red as a word
|
||
add.w d3,d5 ;accumulate red
|
||
|
||
swap d4 ;save dst pixel size in high word
|
||
move.w stITabRes(A6),D0 ;get the iTable resolution
|
||
|
||
tst.w d5 ;get desired red
|
||
spl d3 ;get pin value if neg
|
||
cmp.w d3,d5 ;is it too big
|
||
sgt d4 ;get pin value if too big
|
||
and.b d5,d3 ;pin to zero
|
||
or.b d4,d3 ;pin to 255
|
||
|
||
moveq #0,d5
|
||
move.b d3,d5
|
||
|
||
lsl.l d0,d3 ;move it up
|
||
|
||
tst.w d6 ;get desired green
|
||
spl d3 ;get pin value if neg
|
||
cmp.w #$ff,d6 ;is it too big
|
||
sgt d4 ;get pin value if too big
|
||
and.b d6,d3 ;pin to zero
|
||
or.b d4,d3 ;pin to 255
|
||
|
||
moveq #0,d6
|
||
move.b d3,d6
|
||
|
||
lsl.l d0,d3 ;move it up
|
||
|
||
tst.w d7 ;get desired blue
|
||
spl d3 ;get pin value if neg
|
||
cmp.w #$ff,d7 ;is it too big
|
||
sgt d4 ;get pin value if too big
|
||
and.b d7,d3 ;pin to zero
|
||
or.b d4,d3 ;pin to 255
|
||
neg d0
|
||
addq #8,d0
|
||
|
||
moveq #0,d7
|
||
move.b d3,d7
|
||
|
||
lsr.l d0,d3 ;throw out the insignificant bits
|
||
|
||
swap d4 ;get back dst pixel size
|
||
moveq #0,d0 ;clear out high end
|
||
MOVE.L stITabPtr(A6),A3 ;get pointer to the inverse table (past header)
|
||
move.b (a3,d3.L),d0 ;get the index in D0 (hi 3 bytes still clear)
|
||
|
||
BFINS D0,D1{D2:D4} ;PUT TO DST LONG
|
||
MOVE.L stCLUTPtr(a6),A3 ;get clut ptr
|
||
lea CTTable+rgb+red(A3,D0.L*8),a5 ;point at red value
|
||
move.l (a5)+,d3 ;get RRRRGGGG <05JUNE92 SAH>
|
||
|
||
lsr.l #8,d3 ;get high byte of green <05JUNE92 SAH>
|
||
move.b d3,d0 ;make it a word (hi 3 bytes d0 clear) <05JUNE92 SAH>
|
||
sub.w d0,d6 ;compute green error <05JUNE92 SAH>
|
||
|
||
swap d3 ;get high byte of red <05JUNE92 SAH>
|
||
sub.w d3,d5 ;compute red error <05JUNE92 SAH>
|
||
|
||
move.b (a5)+,d0 ;get high byte of blue <05JUNE92 SAH>
|
||
sub.w d0,d7 ;compute blue error <05JUNE92 SAH>
|
||
|
||
rts
|
||
|
||
|
||
|
||
Dither16toIndexed PROC EXPORT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 1-8 BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
; A4: PIXEL TRANSLATE TABLE
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
|
||
MOVEM.L A3/A5/D6/D7,-(SP) ;SAVE WORK REGISTERS
|
||
|
||
@1 MOVE.L ErrBuf(a6),A4 ;get ptr to ErrBuf
|
||
MOVEQ #0,D2 ;INIT OFFSET INTO DST
|
||
MOVE.L D2,D5 ;init redAccum
|
||
MOVE.L D2,D6 ;init grnAccum
|
||
MOVE.L D2,D7 ;init bluAccum
|
||
moveq #0,d3
|
||
not.b errDir(a6) ;check and toggle diffusion direction
|
||
bne.s @forward
|
||
|
||
move.l ErrSrcBuf(a6),a0 ;point to end of srcBuf
|
||
moveq #32,d2 ;init dst offset in long
|
||
|
||
@back2
|
||
sub.w D4,D2 ;pre-BUMP TO NEXT DST PIXEL
|
||
@backward
|
||
sub.w #6,a4
|
||
MOVE.w -(A0),D0 ;GET NEXT word OF SRC
|
||
bsr.s ditherCore
|
||
|
||
moveq #0,d3
|
||
asr.w #1,d5 ;get half red error
|
||
move.w d5,0(a4) ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d5
|
||
asr.w #1,d6 ;get half grn error
|
||
move.w d6,2(a4) ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d6
|
||
asr.w #1,d7 ;get half blu error
|
||
move.w d7,4(a4) ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d7
|
||
|
||
sub.w D4,D2 ;BUMP TO NEXT DST PIXEL
|
||
bge.s @backward ;TIME FOR NEXT DST LONG? =>NO
|
||
moveq #32,d2
|
||
MOVE.L D1,-(A2) ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @back2 ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
bra.s donescl
|
||
|
||
@forward
|
||
MOVE.w (A0)+,D0 ;GET NEXT LONG OF SRC
|
||
bsr.s ditherCore
|
||
|
||
moveq #0,d3
|
||
asr.w #1,d5 ;get half red error
|
||
move.w d5,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d5
|
||
asr.w #1,d6 ;get half grn error
|
||
move.w d6,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d6
|
||
asr.w #1,d7 ;get half blu error
|
||
move.w d7,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d7
|
||
|
||
@again
|
||
ADD D4,D2 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1F,D2 ;TIME FOR NEXT DST LONG?
|
||
BNE.S @forward ;=>NO
|
||
MOVE.L D1,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @forward ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
move.l a0,ErrSrcBuf(a6) ;point to end of srcBuf for right to left diffusion
|
||
|
||
DONESCL
|
||
MOVEM.L (SP)+,A3/A5/D6/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
DitherCore
|
||
add.w (a4),D5 ;consume red error from above
|
||
add.w 2(a4),D6 ;consume grn error from above
|
||
add.w 4(a4),D7 ;consume blu error from above
|
||
; moveq #0,d3 ;clear out temp ;cleared on entry
|
||
swap d4 ;save dst pixel size in high word
|
||
|
||
move.b d0,d3 ;get blue as a word
|
||
lsl.b #3,d3 ;left justify 5 bits
|
||
move.b d3,d4
|
||
lsr.b #5,d4 ;right justify high 3 bits
|
||
or.b d4,d3 ;replicate into 8 bits
|
||
add.w d3,d7 ;accumulate blue
|
||
lsr.l #5,d0 ;toss blue
|
||
|
||
move.b d0,d3 ;get green as a word
|
||
lsl.b #3,d3 ;left justify 5 bits
|
||
move.b d3,d4
|
||
lsr.b #5,d4 ;right justify high 3 bits
|
||
or.b d4,d3 ;replicate into 8 bits
|
||
add.w d3,d6 ;accumulate green
|
||
lsr.l #5,d0 ;toss green
|
||
|
||
move.b d0,d3 ;get red as a word
|
||
lsl.b #3,d3 ;left justify 5 bits
|
||
move.b d3,d4
|
||
lsr.b #5,d4 ;right justify high 3 bits
|
||
or.b d4,d3 ;replicate into 8 bits
|
||
add.w d3,d5 ;accumulate red
|
||
|
||
move.w stITabRes(A6),D0 ;get the iTable resolution
|
||
|
||
tst.w d5 ;get desired red
|
||
spl d3 ;get pin value if neg
|
||
cmp.w d3,d5 ;is it too big
|
||
sgt d4 ;get pin value if too big
|
||
and.b d5,d3 ;pin to zero
|
||
or.b d4,d3 ;pin to 255
|
||
|
||
moveq #0,d5
|
||
move.b d3,d5
|
||
|
||
lsl.l d0,d3 ;move it up
|
||
|
||
tst.w d6 ;get desired green
|
||
spl d3 ;get pin value if neg
|
||
cmp.w #$ff,d6 ;is it too big
|
||
sgt d4 ;get pin value if too big
|
||
and.b d6,d3 ;pin to zero
|
||
or.b d4,d3 ;pin to 255
|
||
|
||
moveq #0,d6
|
||
move.b d3,d6
|
||
|
||
lsl.l d0,d3 ;move it up
|
||
|
||
tst.w d7 ;get desired blue
|
||
spl d3 ;get pin value if neg
|
||
cmp.w #$ff,d7 ;is it too big
|
||
sgt d4 ;get pin value if too big
|
||
and.b d7,d3 ;pin to zero
|
||
or.b d4,d3 ;pin to 255
|
||
neg d0
|
||
addq #8,d0
|
||
|
||
moveq #0,d7
|
||
move.b d3,d7
|
||
|
||
lsr.l d0,d3 ;throw out the insignificant bits
|
||
|
||
swap d4 ;get back dst pixel size
|
||
moveq #0,d0 ;clear out high end
|
||
MOVE.L stITabPtr(A6),A3 ;get pointer to the inverse table (past header)
|
||
move.b (a3,d3.L),d0 ;get the index in D0 (hi 3 bytes still clear)
|
||
BFINS D0,D1{D2:D4} ;PUT TO DST LONG
|
||
MOVE.L stCLUTPtr(a6),A3 ;get clut ptr
|
||
lea CTTable+rgb+red(A3,D0.L*8),a5 ;point at red value
|
||
move.l (a5)+,d0 ;get RRRRGGGG
|
||
|
||
moveq #0,d3 ;clear out high end
|
||
lsr.l #8,d0 ;get high byte of green
|
||
move.b d0,d3 ;make it a word
|
||
sub.w d3,d6 ;compute green error
|
||
|
||
swap d0 ;get high byte of red
|
||
move.b d0,d3 ;make it a word
|
||
sub.w d3,d5 ;compute red error
|
||
|
||
move.w (a5),d0 ;get BBBBxxxx
|
||
lsr.w #8,d0 ;get high byte of blue
|
||
move.b d0,d3 ;make it a word
|
||
sub.w d3,d7 ;compute blue error
|
||
|
||
rts
|
||
ENDPROC
|
||
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
|
||
Dither32toGray PROC EXPORT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
MACRO
|
||
_DitherGray
|
||
|
||
move.b d3,d2 ; get the blue component
|
||
lsr.l #8,d3 ; get red,green in low word
|
||
move.b d3,d1 ; get the green component
|
||
lsr.w #8,d3 ; get red in low byte
|
||
move.b d3,d0 ; get the red component
|
||
|
||
; Compute Luminance = ((((((r+g)/2)+b)/2+r)/2)+g)/2
|
||
|
||
add.w d1,d3
|
||
add.w d2,d3
|
||
add.w d2,d3
|
||
lsr.w #2,d3
|
||
add.w d0,d3
|
||
add.w d1,d3
|
||
add.w d1,d3
|
||
lsr.w #2,d3
|
||
|
||
add.w d3,d7 ; consume error from right (or left)
|
||
add.w (a4),d7 ; consume error from above
|
||
spl d2 ; get pin value if neg
|
||
cmp.w d2,d7 ; is it too big
|
||
sgt d1 ; get pin value if too big
|
||
and.b d2,d7 ; pin to zero
|
||
or.b d1,d7 ; pin to 255
|
||
move.b d7,d1 ; extend to a word
|
||
|
||
move.b (a3,d1),d0 ; pick up index for this luminance
|
||
BFINS D0,D6{D5:D4} ; PUT TO DST LONG
|
||
move.w d1,d7 ; get requested luminance as a word <BAL 30Jan90>
|
||
move.b (a5,d1),d1 ; get actual luminance as a word <BAL 30Jan90>
|
||
sub.w d1,d7 ; get luminance error as a word <BAL 30Jan90>
|
||
|
||
ENDM
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 1-8 BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
; A4: PIXEL TRANSLATE TABLE
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
MOVEM.L A3/A5/D6/D7,-(SP) ;SAVE WORK REGISTERS
|
||
|
||
MOVE.L stITabInfo(A6),A3 ;get pointer to the luminance table (past header)
|
||
lea ITabLuma-ITabInfo(a3),a5 ;point to luma table
|
||
|
||
@1 MOVE.L ErrBuf(a6),A4 ;get ptr to ErrBuf
|
||
MOVEQ #0,D5 ;INIT OFFSET INTO DST
|
||
MOVE.L D5,D0 ;clear high end
|
||
MOVE.L D5,D1 ;clear high end
|
||
MOVE.L D5,D2 ;clear high end
|
||
not.b errDir(a6) ;check and toggle diffusion direction
|
||
bne.s @forward
|
||
|
||
move.l ErrSrcBuf(a6),a0 ;point to end of srcBuf
|
||
moveq #32,d5 ;init dst offset in long
|
||
|
||
@back2
|
||
sub.w D4,D5 ;pre-BUMP TO NEXT DST PIXEL
|
||
@backward
|
||
sub.w #2,a4
|
||
MOVE.L -(A0),D3 ;GET NEXT LONG OF SRC
|
||
_DitherGray
|
||
|
||
moveq #0,d3 ; <23Feb90 KON>
|
||
asr.w #1,d7 ;get half error (signed)
|
||
move.w d7,(a4) ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d7 ;prevent error from accumulating <23Feb90 KON>
|
||
|
||
sub.w D4,D5 ;BUMP TO NEXT DST PIXEL
|
||
bge.s @backward ;TIME FOR NEXT DST LONG? =>NO
|
||
moveq #32,d5
|
||
MOVE.L D6,-(A2) ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @back2 ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
bra.s @donescl
|
||
|
||
@forward
|
||
MOVE.L (A0)+,D3 ;GET NEXT LONG OF SRC
|
||
_DitherGray
|
||
|
||
moveq #0,d3 ; <23Feb90 KON>
|
||
asr.w #1,d7 ;get half error (signed)
|
||
move.w d7,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d7 ;prevent error from accumulating <23Feb90 KON>
|
||
|
||
ADD D4,D5 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1F,D5 ;TIME FOR NEXT DST LONG?
|
||
BNE.S @forward ;=>NO
|
||
MOVE.L D6,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @forward ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
move.l a0,ErrSrcBuf(a6) ;point to end of srcBuf for right to left diffusion
|
||
|
||
@DONESCL
|
||
MOVEM.L (SP)+,A3/A5/D6/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
ENDPROC
|
||
|
||
|
||
Dither32toBitmap PROC EXPORT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
MACRO
|
||
_DitherBitmap32
|
||
|
||
move.b d3,d2 ; get the blue component
|
||
lsr.l #8,d3 ; get red,green in low word
|
||
move.b d3,d1 ; get the green component
|
||
lsr.w #8,d3 ; get red in low byte
|
||
move.b d3,d0 ; get the red component
|
||
|
||
; Compute Luminance = ((((((r+g)/2)+b)/2+r)/2)+g)/2
|
||
|
||
add.w d1,d3
|
||
add.w d2,d3
|
||
add.w d2,d3
|
||
lsr.w #2,d3
|
||
add.w d0,d3
|
||
add.w d1,d3
|
||
add.w d1,d3
|
||
lsr.w #2,d3
|
||
|
||
add.w d3,d7 ; consume error from right (or left)
|
||
add.w (a4),d7 ; consume error from above
|
||
spl d2 ; get pin value if neg
|
||
cmp.w d2,d7 ; is it too big
|
||
sgt d1 ; get pin value if too big
|
||
and.b d2,d7 ; pin to zero
|
||
or.b d1,d7 ; pin to 255
|
||
move.b d7,d1 ; extend to a word
|
||
|
||
spl d0 ; ≥$80 -> $00; <$80 -> $ff
|
||
BFINS D0,D6{D5:D4} ; PUT TO DST LONG
|
||
not.b d0 ; get luminance value of output pixel as a word
|
||
move.w d1,d7 ; get requested luminance as a word <BAL 30Jan90>
|
||
sub.w d0,d7 ; get luminance error as a word <BAL 30Jan90>
|
||
|
||
ENDM
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 1-8 BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
; A4: PIXEL TRANSLATE TABLE
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
MOVEM.L D6/D7,-(SP) ;SAVE WORK REGISTERS
|
||
|
||
@1 MOVE.L ErrBuf(a6),A4 ;get ptr to ErrBuf
|
||
MOVEQ #0,D5 ;INIT OFFSET INTO DST
|
||
MOVE.L D5,D0 ;clear high end
|
||
MOVE.L D5,D1 ;clear high end
|
||
MOVE.L D5,D2 ;clear high end
|
||
not.b errDir(a6) ;check and toggle diffusion direction
|
||
bne.s @forward
|
||
|
||
move.l ErrSrcBuf(a6),a0 ;point to end of srcBuf
|
||
moveq #32,d5 ;init dst offset in long
|
||
|
||
@back2
|
||
sub.w D4,D5 ;pre-BUMP TO NEXT DST PIXEL
|
||
@backward
|
||
sub.w #2,a4
|
||
MOVE.L -(A0),D3 ;GET NEXT LONG OF SRC
|
||
_DitherBitmap32
|
||
|
||
asr.w #1,d7 ;get half error (signed)
|
||
move.w d7,(a4) ;save 1/2 for next scanline and carry 1/2 to right
|
||
|
||
sub.w D4,D5 ;BUMP TO NEXT DST PIXEL
|
||
bge.s @backward ;TIME FOR NEXT DST LONG? =>NO
|
||
moveq #32,d5
|
||
MOVE.L D6,-(A2) ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @back2 ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
bra.s @donescl
|
||
|
||
@forward
|
||
MOVE.L (A0)+,D3 ;GET NEXT LONG OF SRC
|
||
_DitherBitmap32
|
||
|
||
asr.w #1,d7 ;get half error (signed)
|
||
move.w d7,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
|
||
ADD D4,D5 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1F,D5 ;TIME FOR NEXT DST LONG?
|
||
BNE.S @forward ;=>NO
|
||
MOVE.L D6,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @forward ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
move.l a0,ErrSrcBuf(a6) ;point to end of srcBuf for right to left diffusion
|
||
|
||
@DONESCL
|
||
MOVEM.L (SP)+,D6/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
ENDPROC
|
||
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
|
||
Dither16toGray PROC EXPORT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
MACRO
|
||
_DitherGray16
|
||
|
||
lsl.l #3,d3 ; left justify lo 5 bits
|
||
move.b d3,d2 ; get the blue component
|
||
lsl.w #5,d2 ; save 5 bits
|
||
move.b d3,d2 ; get 5 more bits
|
||
lsr.w #5,d2 ; chuck 2 of the ten
|
||
|
||
lsr.l #5,d3 ; left justify lo 5 bits
|
||
move.b d3,d1 ; get 5 of the green bits
|
||
lsl.w #5,d1 ; save 5 bits
|
||
move.b d3,d1 ; get 5 more bits
|
||
lsr.w #5,d1 ; chuck 2 of the ten
|
||
|
||
lsr.l #5,d3 ; left justify lo 5 bits
|
||
move.b d3,d0 ; get 5 of the red bits
|
||
lsl.w #5,d0 ; save 5 bits
|
||
move.b d3,d0 ; get 5 more bits
|
||
lsr.w #5,d0 ; chuck 2 of the ten
|
||
move.w d0,d3 ; make a copy of the red
|
||
|
||
|
||
; Compute Luminance = ((((((r+g)/2)+b)/2+r)/2)+g)/2
|
||
|
||
add.w d1,d3
|
||
add.w d2,d3
|
||
add.w d2,d3
|
||
lsr.w #2,d3
|
||
add.w d0,d3
|
||
add.w d1,d3
|
||
add.w d1,d3
|
||
lsr.w #2,d3
|
||
|
||
add.w d3,d7 ; consume error from right (or left)
|
||
add.w (a4),d7 ; consume error from above
|
||
spl d2 ; get pin value if neg
|
||
cmp.w d2,d7 ; is it too big
|
||
sgt d1 ; get pin value if too big
|
||
and.b d2,d7 ; pin to zero
|
||
or.b d1,d7 ; pin to 255
|
||
move.b d7,d1 ; extend to a word
|
||
|
||
move.b (a3,d1),d0 ; pick up index for this luminance
|
||
BFINS D0,D6{D5:D4} ; PUT TO DST LONG
|
||
move.w d1,d7 ; get requested luminance as a word <BAL 30Jan90>
|
||
move.b (a5,d1),d1 ; get actual luminance as a word <BAL 30Jan90>
|
||
sub.w d1,d7 ; get luminance error as a word <BAL 30Jan90>
|
||
|
||
ENDM
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 1-8 BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
; A4: PIXEL TRANSLATE TABLE
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
MOVEM.L A3/A5/D6/D7,-(SP) ;SAVE WORK REGISTERS
|
||
|
||
moveq #0,d3 ;clear out high word
|
||
MOVE.L stITabInfo(A6),A3 ;get pointer to the luminance table (past header)
|
||
lea ITabLuma-ITabInfo(a3),a5 ;point to luma table
|
||
|
||
@1 MOVE.L ErrBuf(a6),A4 ;get ptr to ErrBuf
|
||
MOVEQ #0,D5 ;INIT OFFSET INTO DST
|
||
MOVE.L D5,D0 ;clear high end
|
||
MOVE.L D5,D1 ;clear high end
|
||
MOVE.L D5,D2 ;clear high end
|
||
not.b errDir(a6) ;check and toggle diffusion direction
|
||
bne.s @forward
|
||
|
||
move.l ErrSrcBuf(a6),a0 ;point to end of srcBuf
|
||
moveq #32,d5 ;init dst offset in long
|
||
|
||
@back2
|
||
sub.w D4,D5 ;pre-BUMP TO NEXT DST PIXEL
|
||
@backward
|
||
sub.w #2,a4
|
||
MOVE.w -(A0),D3 ;GET NEXT LONG OF SRC
|
||
_DitherGray16
|
||
|
||
moveq #0,d3 ; <23Feb90 KON>
|
||
asr.w #1,d7 ;get half error (signed)
|
||
move.w d7,(a4) ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d7 ;prevent error from accumulating <23Feb90 KON>
|
||
|
||
sub.w D4,D5 ;BUMP TO NEXT DST PIXEL
|
||
bge.s @backward ;TIME FOR NEXT DST LONG? =>NO
|
||
moveq #32,d5
|
||
MOVE.L D6,-(A2) ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @back2 ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
bra.s @donescl
|
||
|
||
@forward
|
||
MOVE.w (A0)+,D3 ;GET NEXT LONG OF SRC
|
||
_DitherGray16
|
||
|
||
moveq #0,d3 ; <23Feb90 KON>
|
||
asr.w #1,d7 ;get half error (signed)
|
||
move.w d7,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
addx.w d3,d7 ;prevent error from accumulating <23Feb90 KON>
|
||
|
||
ADD D4,D5 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1F,D5 ;TIME FOR NEXT DST LONG?
|
||
BNE.S @forward ;=>NO
|
||
MOVE.L D6,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @forward ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
move.l a0,ErrSrcBuf(a6) ;point to end of srcBuf for right to left diffusion
|
||
|
||
@DONESCL
|
||
MOVEM.L (SP)+,A3/A5/D6/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
ENDPROC
|
||
|
||
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
|
||
Dither16toBitmap PROC EXPORT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
MACRO
|
||
_DitherBitmap16
|
||
|
||
lsl.l #3,d3 ; left justify lo 5 bits
|
||
move.b d3,d2 ; get the blue component
|
||
lsl.w #5,d2 ; save 5 bits
|
||
move.b d3,d2 ; get 5 more bits
|
||
lsr.w #5,d2 ; chuck 2 of the ten
|
||
|
||
lsr.l #5,d3 ; left justify lo 5 bits
|
||
move.b d3,d1 ; get 5 of the green bits
|
||
lsl.w #5,d1 ; save 5 bits
|
||
move.b d3,d1 ; get 5 more bits
|
||
lsr.w #5,d1 ; chuck 2 of the ten
|
||
|
||
lsr.l #5,d3 ; left justify lo 5 bits
|
||
move.b d3,d0 ; get 5 of the red bits
|
||
lsl.w #5,d0 ; save 5 bits
|
||
move.b d3,d0 ; get 5 more bits
|
||
lsr.w #5,d0 ; chuck 2 of the ten
|
||
move.w d0,d3 ; make a copy of the red
|
||
|
||
|
||
; Compute Luminance = ((((((r+g)/2)+b)/2+r)/2)+g)/2
|
||
|
||
add.w d1,d3
|
||
add.w d2,d3
|
||
add.w d2,d3
|
||
lsr.w #2,d3
|
||
add.w d0,d3
|
||
add.w d1,d3
|
||
add.w d1,d3
|
||
lsr.w #2,d3
|
||
|
||
add.w d3,d7 ; consume error from right (or left)
|
||
add.w (a4),d7 ; consume error from above
|
||
spl d2 ; get pin value if neg
|
||
cmp.w d2,d7 ; is it too big
|
||
sgt d1 ; get pin value if too big
|
||
and.b d2,d7 ; pin to zero
|
||
or.b d1,d7 ; pin to 255
|
||
move.b d7,d1 ; extend to a word
|
||
|
||
spl d0 ; ≥$80 -> $00; <$80 -> $ff
|
||
BFINS D0,D6{D5:D4} ; PUT TO DST LONG
|
||
not.b d0 ; get luminance value of output pixel as a word
|
||
move.w d1,d7 ; get requested luminance as a word <BAL 30Jan90>
|
||
sub.w d0,d7 ; get luminance error as a word <BAL 30Jan90>
|
||
|
||
ENDM
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 1-8 BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
; A4: PIXEL TRANSLATE TABLE
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
MOVEM.L D6/D7,-(SP) ;SAVE WORK REGISTERS
|
||
|
||
moveq #0,d3 ;clear out high word
|
||
|
||
@1 MOVE.L ErrBuf(a6),A4 ;get ptr to ErrBuf
|
||
MOVEQ #0,D5 ;INIT OFFSET INTO DST
|
||
MOVE.L D5,D0 ;clear high end
|
||
MOVE.L D5,D1 ;clear high end
|
||
MOVE.L D5,D2 ;clear high end
|
||
not.b errDir(a6) ;check and toggle diffusion direction
|
||
bne.s @forward
|
||
|
||
move.l ErrSrcBuf(a6),a0 ;point to end of srcBuf
|
||
moveq #32,d5 ;init dst offset in long
|
||
|
||
@back2
|
||
sub.w D4,D5 ;pre-BUMP TO NEXT DST PIXEL
|
||
@backward
|
||
sub.w #2,a4
|
||
MOVE.w -(A0),D3 ;GET NEXT LONG OF SRC
|
||
_DitherBitmap16
|
||
|
||
asr.w #1,d7 ;get half error (signed)
|
||
move.w d7,(a4) ;save 1/2 for next scanline and carry 1/2 to right
|
||
|
||
sub.w D4,D5 ;BUMP TO NEXT DST PIXEL
|
||
bge.s @backward ;TIME FOR NEXT DST LONG? =>NO
|
||
moveq #32,d5
|
||
MOVE.L D6,-(A2) ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @back2 ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
bra.s @donescl
|
||
|
||
@forward
|
||
MOVE.w (A0)+,D3 ;GET NEXT LONG OF SRC
|
||
_DitherBitmap16
|
||
|
||
asr.w #1,d7 ;get half error (signed)
|
||
move.w d7,(a4)+ ;save 1/2 for next scanline and carry 1/2 to right
|
||
|
||
ADD D4,D5 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1F,D5 ;TIME FOR NEXT DST LONG?
|
||
BNE.S @forward ;=>NO
|
||
MOVE.L D6,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @forward ;if lower, continue to next pixel
|
||
move.l a4,ErrBuf(a6) ;point to end of errBuf for right to left diffusion
|
||
move.l a0,ErrSrcBuf(a6) ;point to end of srcBuf for right to left diffusion
|
||
|
||
@DONESCL
|
||
MOVEM.L (SP)+,D6/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
ENDPROC
|
||
|
||
Scale32toIndexed PROC EXPORT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
anyCmpSize equ 0
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 1-8 BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
; A4: PIXEL TRANSLATE TABLE
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
MOVEM.L A3/A5/D6/D7,-(SP) ;SAVE WORK REGISTERS
|
||
MOVEQ #0,D2 ;INIT OFFSET INTO DST
|
||
|
||
MOVE.L stITabPtr(A6),A3 ;get pointer to the inverse table (past header)
|
||
MOVE.W stITabRes(A6),D1 ;get the iTable resolution
|
||
; move.w srcCmpSize(a6),d3 ;get size of each cmp
|
||
moveq #8,d3
|
||
move.w d3,d7 ;
|
||
sub.w d1,d7 ;d7 is cmp size - itabres
|
||
move.l (a0)+,d5 ;get first long of src
|
||
bra.s @first
|
||
@NXTSLNG
|
||
MOVE.L (A0)+,D5 ;GET NEXT LONG OF SRC
|
||
cmp.l d5,a5 ;same as last long?
|
||
beq.s @again ;yes, go fast
|
||
@first
|
||
move.l d5,a5 ;save last 32 bit pixel value
|
||
|
||
; BFEXTU D5{8:D1},D0 ;5,8,8 ;extract iTabRes bits of red (clearing hi bits)
|
||
; LSL.L D1,D0 ;3,6,6 ;shift over by iTabRes
|
||
; BFEXTU D5{16:D1},D3 ;5,8,8 ;get the green component
|
||
; OR.L D3,D0 ;0,2,3 ;put them together
|
||
; LSL.L D1,D0 ;3,6,6 ;shift again
|
||
; BFEXTU D5{24:D1},D3 ;5,8,8 ;get the blue component
|
||
; OR.L D3,D0 ;0,2,3 ;put them together to form iTable index
|
||
;21,40,42
|
||
|
||
if anyCmpSize then
|
||
|
||
lsr.l d7,d5 ;3,6,6 ;normalize data by trashing extra bits
|
||
move.b d5,d0 ;0,2,3 ;get blue
|
||
ror.l d1,d0 ;5,8,8 ;save itabres bits of blue in high word
|
||
lsr.l d3,d5 ;3,6,6 ;chuck blue and get green cmp
|
||
move.b d5,d0 ;0,2,3 ;get green
|
||
ror.l d1,d0 ;5,8,8 ;save itabres bits of green in high word
|
||
lsr.l d3,d5 ;3,6,6 ;chuck green and get red cmp
|
||
move.b d5,d0 ;0,2,3 ;get red
|
||
ror.l d1,d0 ;5,8,8 ;save itabres bits of red in high word
|
||
clr.w d0 ;0,2,3 ;remove alpha bits
|
||
move d1,d5 ;0,2,3
|
||
add d5,d5 ;0,2,3
|
||
add d1,d5 ;0,2,3
|
||
rol.l d5,d0 ;5,8,8 ;rol back by 3 * itabres
|
||
;29,64,71
|
||
|
||
else
|
||
|
||
moveq #0,d0 ;0,2,3 ;start fresh
|
||
move.w d5,d3 ;0,2,3 ;save blue/green for later
|
||
swap d5 ;1,4,4 ;get red in low byte
|
||
move.b d5,d0 ;0,2,3
|
||
lsl.l d1,d0 ;3,6,6 ;save itabres bits of red in high bytes
|
||
lsr.l #8,d3 ;1,4,4 ;chuck blue and get green cmp
|
||
move.b d3,d0 ;0,2,3 ;get green
|
||
lsl.l d1,d0 ;3,6,6 ;save itabres bits of green in high bytes
|
||
swap d5 ;1,4,4 ;get blue in low byte
|
||
move.b d5,d0 ;0,2,3 ;get red
|
||
lsr.l d7,d0 ;3,6,6 ;shift back by cmpsize-itabres
|
||
;12,40,45
|
||
|
||
endif
|
||
|
||
MOVE.B (A3,D0.w),D0 ;get the index in D0
|
||
@again
|
||
BFINS D0,D6{D2:D4} ;PUT TO DST LONG
|
||
ADD D4,D2 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1f,D2 ;TIME FOR NEXT DST LONG?
|
||
BNE.S @NXTSLNG ;=>NO
|
||
MOVE.L D6,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @NXTSLNG ;if lower, continue to next pixel
|
||
DONESCL
|
||
MOVEM.L (SP)+,A3/A5/D6/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
|
||
|
||
|
||
Scale32toGray PROC EXPORT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 1-8 BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
; A4: PIXEL TRANSLATE TABLE
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
MOVEM.L A3/A5/D6,-(SP) ;SAVE WORK REGISTERS
|
||
MOVEQ #0,D5 ;INIT OFFSET INTO DST
|
||
|
||
moveq #0,d0 ; clear out high end
|
||
moveq #0,d1 ; clear out high end
|
||
moveq #0,d2 ; clear out high end
|
||
MOVE.L stITabInfo(A6),A3 ;get pointer to the luminance table (past header)
|
||
move.l (a0)+,d3 ;get first long of src
|
||
bra.s @first
|
||
@NXTSLNG
|
||
MOVE.L (A0)+,D3 ;GET NEXT LONG OF SRC
|
||
cmp.l d3,a5 ;same as last long?
|
||
beq.s @again ;yes, go fast
|
||
@first
|
||
move.l d3,a5 ;save last 32 bit pixel value
|
||
|
||
move.b d3,d2 ; get the blue component
|
||
lsr.l #8,d3 ; get red,green in low word
|
||
move.b d3,d1 ; get the green component
|
||
lsr.w #8,d3 ; get red in low byte
|
||
move.b d3,d0 ; get the red component
|
||
|
||
; Compute Luminance = ((((((r+g)/2)+b)/2+r)/2)+g)/2
|
||
|
||
add.w d1,d3
|
||
add.w d2,d3
|
||
add.w d2,d3
|
||
lsr.w #2,d3
|
||
add.w d0,d3
|
||
add.w d1,d3
|
||
add.w d1,d3
|
||
lsr.w #2,d3
|
||
move.b (a3,d3),d0 ; pick up index for this luminance
|
||
@again
|
||
BFINS D0,D6{D5:D4} ;PUT TO DST LONG
|
||
ADD D4,D5 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1f,D5 ;TIME FOR NEXT DST LONG?
|
||
BNE.S @NXTSLNG ;=>NO
|
||
MOVE.L D6,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @NXTSLNG ;if lower, continue to next pixel
|
||
DONESCL
|
||
MOVEM.L (SP)+,A3/A5/D6 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
|
||
Scale32toBitMap PROC EXPORT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO A B/W BitMap
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
; A4: PIXEL TRANSLATE TABLE
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
MOVEM.L A3/A5/D6,-(SP) ;SAVE WORK REGISTERS
|
||
MOVEQ #0,D5 ;INIT OFFSET INTO DST
|
||
|
||
moveq #0,d0 ; clear out high end
|
||
moveq #0,d1 ; clear out high end
|
||
moveq #0,d2 ; clear out high end
|
||
move.l (a0)+,d3 ;get first long of src
|
||
bra.s @first
|
||
@NXTSLNG
|
||
MOVE.L (A0)+,D3 ;GET NEXT LONG OF SRC
|
||
cmp.l d3,a5 ;same as last long?
|
||
beq.s @again ;yes, go fast
|
||
@first
|
||
move.l d3,a5 ;save last 32 bit pixel value
|
||
|
||
move.b d3,d2 ; get the blue component
|
||
lsr.l #8,d3 ; get red,green in low word
|
||
move.b d3,d1 ; get the green component
|
||
lsr.w #8,d3 ; get red in low byte
|
||
move.b d3,d0 ; get the red component
|
||
|
||
; Compute Luminance = ((((((r+g)/2)+b)/2+r)/2)+g)/2
|
||
|
||
add.w d1,d3
|
||
add.w d2,d3
|
||
add.w d2,d3
|
||
lsr.w #2,d3
|
||
add.w d0,d3
|
||
add.w d1,d3
|
||
add.w d1,d3
|
||
lsr.w #2,d3
|
||
|
||
tst.b d3 ; check high bit of luminance
|
||
spl d0 ; put a 1 in low bit for black
|
||
@again
|
||
BFINS D0,D6{D5:D4} ;PUT TO DST LONG
|
||
ADD D4,D5 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1f,D5 ;TIME FOR NEXT DST LONG?
|
||
BNE.S @NXTSLNG ;=>NO
|
||
MOVE.L D6,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @NXTSLNG ;if lower, continue to next pixel
|
||
DONESCL
|
||
MOVEM.L (SP)+,A3/A5/D6 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
|
||
|
||
|
||
Scale16toGray PROC EXPORT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 16 BIT DIRECT TO 1-8 BIT GrayScale Clut
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
; A4: PIXEL TRANSLATE TABLE
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
MOVEM.L A3/A5/D6,-(SP) ;SAVE WORK REGISTERS
|
||
MOVEQ #0,D5 ;INIT OFFSET INTO DST
|
||
|
||
moveq #0,d0 ; clear out high end
|
||
moveq #0,d1 ; clear out high end
|
||
moveq #0,d2 ; clear out high end
|
||
MOVE.L stITabInfo(A6),A3 ;get pointer to the luminance table (past header)
|
||
move.w (a0)+,d3 ;get first long of src
|
||
bra.s @first
|
||
@NXTSLNG
|
||
MOVE.w (A0)+,D3 ;GET NEXT LONG OF SRC
|
||
cmp.w d3,a5 ;same as last long?
|
||
beq.s @again ;yes, go fast
|
||
@first
|
||
move.w d3,a5 ;save last 32 bit pixel value
|
||
|
||
|
||
lsl.l #3,d3 ; left justify lo 5 bits
|
||
move.b d3,d2 ; get the blue component
|
||
lsl.w #5,d2 ; save 5 bits
|
||
move.b d3,d2 ; get 5 more bits
|
||
lsr.w #5,d2 ; chuck 2 of the ten
|
||
|
||
lsr.l #5,d3 ; left justify lo 5 bits
|
||
move.b d3,d1 ; get 5 of the green bits
|
||
lsl.w #5,d1 ; save 5 bits
|
||
move.b d3,d1 ; get 5 more bits
|
||
lsr.w #5,d1 ; chuck 2 of the ten
|
||
|
||
lsr.l #5,d3 ; left justify lo 5 bits
|
||
move.b d3,d0 ; get 5 of the red bits
|
||
lsl.w #5,d0 ; save 5 bits
|
||
move.b d3,d0 ; get 5 more bits
|
||
lsr.w #5,d0 ; chuck 2 of the ten
|
||
move.w d0,d3 ; make a copy of the red
|
||
|
||
; Compute Luminance = ((((((r+g)/2)+b)/2+r)/2)+g)/2
|
||
|
||
add.w d1,d3
|
||
add.w d2,d3
|
||
add.w d2,d3
|
||
lsr.w #2,d3
|
||
add.w d0,d3
|
||
add.w d1,d3
|
||
add.w d1,d3
|
||
lsr.w #2,d3
|
||
move.b (a3,d3),d0 ; pick up index for this luminance
|
||
@again
|
||
BFINS D0,D6{D5:D4} ;PUT TO DST LONG
|
||
ADD D4,D5 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1f,D5 ;TIME FOR NEXT DST LONG?
|
||
BNE.S @NXTSLNG ;=>NO
|
||
MOVE.L D6,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @NXTSLNG ;if lower, continue to next pixel
|
||
DONESCL
|
||
MOVEM.L (SP)+,A3/A5/D6 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
|
||
|
||
Scale16toBitMap PROC EXPORT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 16 BIT DIRECT TO B/W BitMap
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
; A4: PIXEL TRANSLATE TABLE
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
MOVEM.L A3/A5/D6,-(SP) ;SAVE WORK REGISTERS
|
||
MOVEQ #0,D5 ;INIT OFFSET INTO DST
|
||
|
||
moveq #0,d0 ; clear out high end
|
||
moveq #0,d1 ; clear out high end
|
||
moveq #0,d2 ; clear out high end
|
||
move.w (a0)+,d3 ;get first long of src
|
||
bra.s @first
|
||
@NXTSLNG
|
||
MOVE.w (A0)+,D3 ;GET NEXT LONG OF SRC
|
||
cmp.w d3,a5 ;same as last long?
|
||
beq.s @again ;yes, go fast
|
||
@first
|
||
move.w d3,a5 ;save last 32 bit pixel value
|
||
|
||
|
||
lsl.l #3,d3 ; left justify lo 5 bits
|
||
move.b d3,d2 ; get the blue component
|
||
lsl.w #5,d2 ; save 5 bits
|
||
move.b d3,d2 ; get 5 more bits
|
||
lsr.w #5,d2 ; chuck 2 of the ten
|
||
|
||
lsr.l #5,d3 ; left justify lo 5 bits
|
||
move.b d3,d1 ; get 5 of the green bits
|
||
lsl.w #5,d1 ; save 5 bits
|
||
move.b d3,d1 ; get 5 more bits
|
||
lsr.w #5,d1 ; chuck 2 of the ten
|
||
|
||
lsr.l #5,d3 ; left justify lo 5 bits
|
||
move.b d3,d0 ; get 5 of the red bits
|
||
lsl.w #5,d0 ; save 5 bits
|
||
move.b d3,d0 ; get 5 more bits
|
||
lsr.w #5,d0 ; chuck 2 of the ten
|
||
move.w d0,d3 ; make a copy of the red
|
||
|
||
; Compute Luminance = ((((((r+g)/2)+b)/2+r)/2)+g)/2
|
||
|
||
add.w d1,d3
|
||
add.w d2,d3
|
||
add.w d2,d3
|
||
lsr.w #2,d3
|
||
add.w d0,d3
|
||
add.w d1,d3
|
||
add.w d1,d3
|
||
lsr.w #2,d3
|
||
|
||
tst.b d3 ; check high bit of luminance
|
||
spl d0 ; put a 1 in low bit for black
|
||
@again
|
||
BFINS D0,D6{D5:D4} ;PUT TO DST LONG
|
||
ADD D4,D5 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1f,D5 ;TIME FOR NEXT DST LONG?
|
||
BNE.S @NXTSLNG ;=>NO
|
||
MOVE.L D6,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @NXTSLNG ;if lower, continue to next pixel
|
||
DONESCL
|
||
MOVEM.L (SP)+,A3/A5/D6 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
ENDPROC
|
||
|
||
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
|
||
Search32to32 PROC EXPORT ; <20AUG90 KON>
|
||
;
|
||
; this routine draws a 32-bit direct pixel to a 32 bit destination
|
||
; first applying the search proc for this device, then using a direct lookup
|
||
; if that fails.
|
||
;
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 16 BIT DIRECT
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
MOVEM.L A3-A5/D7,-(SP) ;SAVE WORK REGISTERS
|
||
MOVE.L A0,A4 ;copy source buffer address to non-volatile register
|
||
MOVE.L A1,A3 ;copy dest buffer address
|
||
|
||
move.l saveA5(a6),a5 ;set up caller's A5 for the search proc <1.5> BAL
|
||
|
||
moveq #0,d0 ;force 24-bit mode <1.5>
|
||
move.l a2,d7 ;save a2 just for grins <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
move.l d7,a2 ;restore a2 just in case <1.5>
|
||
|
||
CLR.L -(SP) ;make room for SearchProc result
|
||
CLR.L -(SP) ;make room for an RGBColor and clear it
|
||
CLR.W -(SP) ;
|
||
Loop
|
||
MOVE.L (A4)+,D5 ;pick up a 32-bit source pixel
|
||
MOVE.B D5,blue(SP) ;put blue byte in hi byte of blue component
|
||
MOVE.B D5,blue+1(SP) ;put blue byte in lo byte of blue component
|
||
lsR.L #8,D5 ;get green in the lo byte
|
||
MOVE.B D5,green(SP) ;put green byte in hi byte of green component
|
||
MOVE.B D5,green+1(SP) ;put green byte in lo byte of green component
|
||
lsR.L #8,D5 ;get red in the lo byte
|
||
MOVE.B D5,red(SP) ;put in red channel
|
||
MOVE.B D5,red+1(SP) ;put in red channel lo
|
||
MOVE.L stSProc(A6),stTmpProc(A6) ;make a copy of the search proc head
|
||
NxtProc
|
||
MOVE.L stTmpProc(A6),D0 ;get sProcRec handle
|
||
BEQ.S OurTurn ;if not found using procs, use ITable
|
||
MOVE.L D0,A0 ;move handle to address register
|
||
MOVE.L (A0),A0 ;get sProcRec pointer
|
||
MOVE.L nxtSrch(A0),stTmpProc(A6) ;save handle to next sProcRec for later (might be NIL)
|
||
|
||
CLR.B -(SP) ;leave room for boolean result
|
||
PEA 2(SP) ;push pointer to stack colorspec
|
||
PEA 12(SP) ;push pointer to var result
|
||
|
||
MOVE.L srchProc(A0),A0 ;get search proc address
|
||
JSR (A0) ;call search proc
|
||
|
||
TST.B (SP)+ ;test result
|
||
BEQ.S NxtProc ;if FALSE, go to next searchProc
|
||
|
||
MOVE.L 6(SP),D0 ;get result in D0
|
||
bra.s writeItOut ;and put into output buffer
|
||
|
||
OurTurn ;go here if no search proc matched
|
||
moveq #0,d0
|
||
move.b red(sp),D0 ;get red
|
||
swap d0
|
||
move.b green(sp),d0 ;get green
|
||
lsl.w #8,d0
|
||
move.b blue(sp),d0 ;get blue
|
||
|
||
writeItOut
|
||
move.l d0,(A3)+ ;SAVE CURRENT LONG
|
||
CMP.L A2,A3 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S Loop ;if lower, continue to next pixel
|
||
DONESCL
|
||
moveq #1,d0 ;force 32-bit mode <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
|
||
ADDA.W #10,SP ;release buffers
|
||
MOVEM.L (SP)+,A3-A5/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
ENDPROC
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; Perform a one time check to see if the search proc is the standard
|
||
; SeedCFill or CalcCMask search procedure. If it is then use an optimized
|
||
; loop instead.
|
||
|
||
Search32toIndexed PROC EXPORT
|
||
IMPORT MySProc,MyCProc,SeedCFill32,CalcCMask32
|
||
|
||
movem.l a0-a2,-(sp) ;save work registers
|
||
lea Search32toInd,a0 ;assume the hard case
|
||
MOVE.L stSProc(A6),a1 ;get the search proc head
|
||
MOVE.L (a1),a1 ;get sProcRec pointer
|
||
MOVE.L srchProc(a1),a1 ;get search proc address
|
||
lea MySProc,a2 ;point to seedCFill proc
|
||
cmp.l a1,a2 ;are they the same?
|
||
bne.s @tryC
|
||
lea SeedCFill32,a0
|
||
bra.s @gotit
|
||
|
||
@tryC lea MyCProc,a2 ;point to seedCFill proc
|
||
cmp.l a1,a2 ;are they the same?
|
||
bne.s @gotIt
|
||
lea CalcCMask32,a0
|
||
@gotIt
|
||
MOVE.L A0,scaleCase(A6) ;remember to go there from now on
|
||
move.l a0,d0 ;save scalecase in d0
|
||
movem.l (sp)+,a0-a2 ;restore work registers
|
||
jmp (ZA0,d0.l) ;go there
|
||
|
||
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
|
||
Search32toInd
|
||
;
|
||
; this routine converts a 32-bit direct pixel to a 1,2,4, or 8 bit destination
|
||
; first applying the search proc for this device, then using a direct lookup
|
||
; into the appropriate inverse table if that fails. The stack frame is included
|
||
; solely to copy the stack frame offsets from the caller in Stretch.
|
||
;
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 1-8 BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
|
||
MOVEM.L A3-A5/D6-D7,-(SP) ;SAVE WORK REGISTERS
|
||
MOVE.L A0,A4 ;copy source buffer address to non-volatile register
|
||
MOVE.L A1,A3 ;copy dest buffer address
|
||
move.l saveA5(a6),a5 ;set up caller's A5 for the search proc <1.5> BAL
|
||
|
||
moveq #0,d0 ;force 24-bit mode <1.5>
|
||
move.l a2,d7 ;save a2 just for grins <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
move.l d7,a2 ;restore a2 just in case <1.5>
|
||
|
||
MOVEQ #0,D7 ;init offset into destination
|
||
CLR.L -(SP) ;make room for SearchProc result
|
||
CLR.L -(SP) ;make room for an RGBColor and clear it
|
||
CLR.W -(SP) ;
|
||
|
||
NXTSLNG
|
||
MOVE.L (A4)+,D5 ;pick up a 32-bit source pixel
|
||
MOVE.B D5,blue(SP) ;put blue byte in hi byte of blue component
|
||
MOVE.B D5,blue+1(SP) ;put blue byte in lo byte of blue component
|
||
ROR.L #8,D5 ;get green in the lo byte
|
||
MOVE.B D5,green(SP) ;put green byte in hi byte of green component
|
||
MOVE.B D5,green+1(SP) ;put green byte in lo byte of green component
|
||
ROR.L #8,D5 ;get red in the lo byte
|
||
MOVE.B D5,red(SP) ;put in hi red channel
|
||
MOVE.B D5,red+1(SP) ;put in lo red channel
|
||
MOVE.L stSProc(A6),stTmpProc(A6) ;make a copy of the search proc head
|
||
NxtProc
|
||
MOVE.L stTmpProc(A6),D0 ;get sProcRec handle
|
||
BEQ.S UseITable ;if not found using procs, use ITable
|
||
MOVE.L D0,A0 ;move handle to address register
|
||
MOVE.L (A0),A0 ;get sProcRec pointer
|
||
MOVE.L nxtSrch(A0),stTmpProc(A6) ;save handle to next sProcRec for later (might be NIL)
|
||
|
||
CLR.B -(SP) ;leave room for boolean result
|
||
PEA 2(SP) ;push pointer to stack colorspec
|
||
PEA 12(SP) ;push pointer to var result
|
||
|
||
MOVE.L srchProc(A0),A0 ;get search proc address
|
||
JSR (A0) ;call search proc
|
||
|
||
TST.B (SP)+ ;test result
|
||
BEQ.S NxtProc ;if FALSE, go to next searchProc
|
||
|
||
MOVE.L 6(SP),D3 ;get result in D3
|
||
BRA.S BuildLong ;and put into output buffer
|
||
|
||
UseITable ;go here if no search proc matched
|
||
|
||
MOVE.L stITabPtr(A6),A0 ;get pointer to the inverse table (past header)
|
||
MOVE.W stITabRes(A6),D1 ;get the iTable resolution
|
||
move.b red(sp),d5 ;get red
|
||
BFEXTU D5{24:D1},D0 ;extract iTabRes bits of red (clearing hi bits)
|
||
LSL.L D1,D0 ;shift over by iTabRes
|
||
|
||
move.b green(sp),d5
|
||
BFEXTU D5{24:D1},D3 ;get the green component
|
||
OR.L D3,D0 ;put them together
|
||
LSL.L D1,D0 ;shift again
|
||
|
||
move.b blue(sp),d5
|
||
BFEXTU D5{24:D1},D3 ;get the blue component
|
||
OR.L D3,D0 ;put them together to form iTable index
|
||
|
||
MOVE.B (A0,D0.L),D3 ;get the index in D3 (hi 3 bytes still clear)
|
||
|
||
BuildLong
|
||
BFINS D3,D6{D7:D4} ;PUT TO DST LONG
|
||
ADD D4,D7 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1F,D7 ;TIME FOR NEXT DST LONG?
|
||
BNE.S NXTSLNG ;=>NO
|
||
MOVE.L D6,(A3)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A3 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S NXTSLNG ;if lower, continue to next pixel
|
||
DONESCL
|
||
moveq #1,d0 ;force 32-bit mode <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
|
||
ADDA.W #10,SP ;release buffers
|
||
MOVEM.L (SP)+,A3-A5/D6-D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
ENDPROC ;Search32toIndexed
|
||
|
||
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
|
||
SeedCFill32 PROC EXPORT
|
||
Export CalcCMask32
|
||
;
|
||
; this routine converts a 32-bit direct pixel to a 1 bit destination with zero's
|
||
; wherever the source matches the color pointed to by the GDRefcon field and
|
||
; one's everywhere else.
|
||
;
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
moveq #0,d1 ;clear high bit of d1 to signal SeedCFill
|
||
bra.s share
|
||
|
||
CalcCMask32
|
||
moveq #-1,d1 ;set high bit of d1 to signal CalcCMask
|
||
|
||
share
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 1- BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
|
||
move.l a2,D5 ;save end of dst buffer in D5
|
||
MOVE.L theGDevice,A2 ;get handle to the gDevice
|
||
MOVE.L (A2),A2 ;point to theGDevice
|
||
MOVE.L GDRefCon(A2),A2 ;point to seed RGB
|
||
move.l (a2)+,d3 ;get RRrrGGgg
|
||
lsr.l #8,d3 ;get 00RRrrGG
|
||
lsl.w #8,d3 ;get 00RRGG00
|
||
move.b (a2),d3 ;get 00RRGGBB
|
||
move.l d5,a2 ;restore end of dst buffer
|
||
|
||
move.l MaskBC,d0 ;get low3bytes mask
|
||
MOVEQ #0,D4 ;init offset into destination
|
||
|
||
NXTSLNG
|
||
MOVE.L (A0)+,D5 ;pick up a 32-bit source pixel
|
||
and.l d0,d5 ;clear high byte for compare
|
||
cmp.l d5,d3 ;compare to seed value
|
||
sne.b d1 ;match ? d1=0 : d1=FF
|
||
|
||
BuildLong
|
||
BFINS D1,D2{D4:1} ;PUT TO DST LONG
|
||
ADDq #1,D4 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1F,D4 ;TIME FOR NEXT DST LONG?
|
||
BNE.S NXTSLNG ;=>NO
|
||
|
||
addx.l d1,d1 ;tst high bit of d1
|
||
subx.l d1,d1 ;extend high bit throughout long
|
||
eor.l d1,d2 ;conditionally invert resulting bits
|
||
|
||
MOVE.L D2,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S NXTSLNG ;if lower, continue to next pixel
|
||
DONESCL
|
||
|
||
RTS
|
||
ENDPROC
|
||
|
||
|
||
Scale32to16 PROC EXPORT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 16 BIT DIRECT
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
; ASSUMES DST IS COMPOSED OF TWO BYTES OF THE FORM 'X:1 R:5 G:5 B:5'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
; A4: PIXEL TRANSLATE TABLE
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
|
||
move.l a2,d2 ;get ptr to end
|
||
sub.l a1,d2 ;sub ptr to beginning
|
||
lsr.l #2,d2 ;get long cnt in d1
|
||
subq #1,d2 ;make zero based
|
||
|
||
@NXTSLNG
|
||
MOVE.L (A0)+,D0 ;GET NEXT LONG OF SRC
|
||
ror.l #8,d0
|
||
lsr.w #3,d0
|
||
ror.l #5,d0
|
||
lsr.w #3,d0
|
||
ror.l #6,d0 ;16 bit pixel in high word
|
||
|
||
MOVE.L (A0)+,D1 ;GET NEXT LONG OF SRC
|
||
ror.l #8,d1
|
||
lsr.w #3,d1
|
||
ror.l #5,d1
|
||
lsr.w #3,d1
|
||
ror.l #6,d1 ;16 bit pixel in high word
|
||
|
||
swap d1 ;merge pixels
|
||
move.w d1,d0
|
||
move.l d0,(a1)+ ;write out 2 pixels
|
||
dbra d2,@NXTSLNG ;loop for all longs in dst scanline
|
||
RTS
|
||
|
||
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
|
||
Search32to16 PROC EXPORT
|
||
|
||
;
|
||
; this routine converts a 32-bit direct pixel to a 16 bit destination
|
||
; first applying the search proc for this device, then using a direct lookup
|
||
; if that fails.
|
||
;
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 16 BIT DIRECT
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
MOVEM.L A3-A5/D7,-(SP) ;SAVE WORK REGISTERS
|
||
MOVE.L A0,A4 ;copy source buffer address to non-volatile register
|
||
MOVE.L A1,A3 ;copy dest buffer address
|
||
|
||
move.l saveA5(a6),a5 ;set up caller's A5 for the search proc <1.5> BAL
|
||
|
||
moveq #0,d0 ;force 24-bit mode <1.5>
|
||
move.l a2,d7 ;save a2 just for grins <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
move.l d7,a2 ;restore a2 just in case <1.5>
|
||
|
||
CLR.L -(SP) ;make room for SearchProc result
|
||
CLR.L -(SP) ;make room for an RGBColor and clear it
|
||
CLR.W -(SP) ;
|
||
bra.s loop
|
||
|
||
DoOne
|
||
MOVE.L (A4)+,D5 ;pick up a 32-bit source pixel
|
||
MOVE.B D5,blue+4(SP) ;put blue byte in hi byte of blue component
|
||
MOVE.B D5,blue+5(SP) ;put blue byte in lo byte of blue component
|
||
ROR.L #8,D5 ;get green in the lo byte
|
||
MOVE.B D5,green+4(SP) ;put green byte in hi byte of green component
|
||
MOVE.B D5,green+5(SP) ;put green byte in lo byte of green component
|
||
ROR.L #8,D5 ;get red in the lo byte
|
||
MOVE.B D5,red+4(SP) ;put in red channel hi
|
||
MOVE.B D5,red+5(SP) ;put in red channel lo
|
||
MOVE.L stSProc(A6),stTmpProc(A6) ;make a copy of the search proc head
|
||
NxtProc
|
||
MOVE.L stTmpProc(A6),D0 ;get sProcRec handle
|
||
BEQ.S OurTurn ;if not found using procs, use ITable
|
||
MOVE.L D0,A0 ;move handle to address register
|
||
MOVE.L (A0),A0 ;get sProcRec pointer
|
||
MOVE.L nxtSrch(A0),stTmpProc(A6) ;save handle to next sProcRec for later (might be NIL)
|
||
|
||
CLR.B -(SP) ;leave room for boolean result
|
||
PEA 2+4(SP) ;push pointer to stack colorspec
|
||
PEA 12+4(SP) ;push pointer to var result
|
||
|
||
MOVE.L srchProc(A0),A0 ;get search proc address
|
||
JSR (A0) ;call search proc
|
||
|
||
TST.B (SP)+ ;test result
|
||
BEQ.S NxtProc ;if FALSE, go to next searchProc
|
||
|
||
MOVE.L 6+4(SP),D0 ;get result in D0
|
||
rts ;and put into output buffer
|
||
|
||
OurTurn ;go here if no search proc matched
|
||
;
|
||
; take rgb from stack and convert to 5-5-5
|
||
;
|
||
moveq #0,d0
|
||
move.b red+4(sp),d0 ;get high byte of red 00000000rrrrrrrr
|
||
lsl.w #5,d0 ;xxxrrrrrrrr00000
|
||
move.b green+4(sp),d0 ;get high byte of green xxxrrrrrgggggggg
|
||
lsl.l #5,d0 ;0rr|rrrgggggggg00000
|
||
move.b blue+4(sp),d0 ;0rr|rrrgggggbbbbbbbb
|
||
lsr.l #3,d0 ;0rrrrrgggggbbbbb
|
||
rts
|
||
|
||
|
||
Loop bsr.s DoOne ;process one input long
|
||
move.w d0,d7 ;get low word
|
||
swap d7
|
||
bsr.s DoOne ;process one input long
|
||
move.w d0,d7 ;get low word
|
||
MOVE.L D7,(A3)+ ;SAVE CURRENT LONG
|
||
CMP.L A2,A3 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S Loop ;if lower, continue to next pixel
|
||
DONESCL
|
||
moveq #1,d0 ;force 32-bit mode <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
|
||
ADDA.W #10,SP ;release buffers
|
||
MOVEM.L (SP)+,A3-A5/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
ENDPROC
|
||
|
||
|
||
Scale16toIndexed PROC EXPORT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 16 BIT DIRECT TO 1-8 BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF TWO BYTES OF THE FORM 'xrrrrrgg gggbbbbb'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
; A4: PIXEL TRANSLATE TABLE
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
MOVEM.L A3/A5/D6/D7,-(SP) ;SAVE WORK REGISTERS
|
||
MOVEQ #0,D2 ;INIT OFFSET INTO DST
|
||
|
||
MOVE.L stITabPtr(A6),A3 ;get pointer to the inverse table (past header)
|
||
MOVE.W stITabRes(A6),D1 ;get the iTable resolution
|
||
move.l (a0)+,d5 ;get first long of src
|
||
bra.s @first
|
||
@NXTSLNG
|
||
MOVE.L (A0)+,D5 ;GET NEXT LONG OF SRC
|
||
cmp.l d5,a5 ;same as last long?
|
||
beq.s @again ;yes, go fast
|
||
@first
|
||
move.l d5,a5 ;save last 32 bit pixel value
|
||
|
||
BFEXTU D5{1:D1},D0 ;5,8,8 ;extract iTabRes bits of red (clearing hi bits)
|
||
LSL.L D1,D0 ;3,6,6 ;shift over by iTabRes
|
||
BFEXTU D5{6:D1},D3 ;5,8,8 ;get the green component
|
||
OR.L D3,D0 ;0,2,3 ;put them together
|
||
LSL.L D1,D0 ;3,6,6 ;shift again
|
||
BFEXTU D5{11:D1},D3 ;5,8,8 ;get the blue component
|
||
OR.L D3,D0 ;0,2,3 ;put them together to form iTable index
|
||
;21,40,42
|
||
MOVE.B (A3,D0.w),D0 ;get the index in D0
|
||
|
||
BFEXTU D5{17:D1},D7 ;5,8,8 ;extract iTabRes bits of red (clearing hi bits)
|
||
LSL.L D1,D7 ;3,6,6 ;shift over by iTabRes
|
||
BFEXTU D5{22:D1},D3 ;5,8,8 ;get the green component
|
||
OR.L D3,D7 ;0,2,3 ;put them together
|
||
LSL.L D1,D7 ;3,6,6 ;shift again
|
||
BFEXTU D5{27:D1},D3 ;5,8,8 ;get the blue component
|
||
OR.L D3,D7 ;0,2,3 ;put them together to form iTable index
|
||
;21,40,42
|
||
MOVE.B (A3,D7.w),D7 ;get the index in D7
|
||
|
||
@again
|
||
BFINS D0,D6{D2:D4} ;PUT TO DST LONG
|
||
ADD D4,D2 ;BUMP TO NEXT DST PIXEL
|
||
BFINS D7,D6{D2:D4} ;PUT TO DST LONG
|
||
ADD D4,D2 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1f,D2 ;TIME FOR NEXT DST LONG?
|
||
BNE.S @NXTSLNG ;=>NO
|
||
MOVE.L D6,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S @NXTSLNG ;if lower, continue to next pixel
|
||
DONESCL
|
||
MOVEM.L (SP)+,A3/A5/D6/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; Perform a one time check to see if the search proc is the standard
|
||
; SeedCFill or CalcCMask search procedure. If it is then use an optimized
|
||
; loop instead.
|
||
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
|
||
Search16toIndexed PROC EXPORT
|
||
IMPORT MySProc,MyCProc,SeedCFill16,CalcCMask16
|
||
|
||
movem.l a0-a2,-(sp) ;save work registers
|
||
lea Search16toInd,a0 ;assume the hard case
|
||
MOVE.L stSProc(A6),a1 ;get the search proc head
|
||
MOVE.L (a1),a1 ;get sProcRec pointer
|
||
MOVE.L srchProc(a1),a1 ;get search proc address
|
||
lea MySProc,a2 ;point to seedCFill proc
|
||
cmp.l a1,a2 ;are they the same?
|
||
bne.s @tryC
|
||
lea SeedCFill16,a0
|
||
bra.s @gotit
|
||
|
||
@tryC lea MyCProc,a2 ;point to seedCFill proc
|
||
cmp.l a1,a2 ;are they the same?
|
||
bne.s @gotIt
|
||
lea CalcCMask16,a0
|
||
@gotIt
|
||
MOVE.L A0,scaleCase(A6) ;remember to go there from now on
|
||
move.l a0,d0 ;save scalecase in d0
|
||
movem.l (sp)+,a0-a2 ;restore work registers
|
||
jmp (ZA0,d0.l) ;go there
|
||
|
||
|
||
Search16toInd
|
||
|
||
;
|
||
; this routine converts a 16-bit direct pixel to a 1,2,4, or 8 bit destination
|
||
; first applying the search proc for this device, then using a direct lookup
|
||
; into the appropriate inverse table if that fails. The stack frame is included
|
||
; solely to copy the stack frame offsets from the caller in Stretch.
|
||
;
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 16 BIT DIRECT TO 1-8 BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF TWO BYTES OF THE FORM 'xrrrrrgggggbbbbb'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
|
||
MOVEM.L A3-A5/D6-D7,-(SP) ;SAVE WORK REGISTERS
|
||
MOVE.L A0,A4 ;copy source buffer address to non-volatile register
|
||
MOVE.L A1,A3 ;copy dest buffer address
|
||
|
||
move.l saveA5(a6),a5 ;set up caller's A5 for the search proc <1.5> BAL
|
||
|
||
moveq #0,d0 ;force 24-bit mode <1.5>
|
||
move.l a2,d7 ;save a2 just for grins <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
move.l d7,a2 ;restore a2 just in case <1.5>
|
||
|
||
MOVEQ #0,D7 ;init offset into destination
|
||
CLR.L -(SP) ;make room for SearchProc result
|
||
CLR.L -(SP) ;make room for an RGBColor and clear it
|
||
CLR.W -(SP) ;
|
||
|
||
NXTSLNG
|
||
MOVE.W (A4)+,D5 ;pick up a 16-bit source pixel
|
||
lsl.l #3,d5 ;left align blue in lo byte
|
||
move.b d5,d0 ;get 5 bits of blue
|
||
lsl.l #5,d0
|
||
move.b d5,d0 ;10 bits of blue
|
||
lsl.l #5,d0
|
||
move.b d5,d0 ;15 bits of blue
|
||
lsl.l #5,d0
|
||
move.b d5,d0 ;blue up the wazoo
|
||
lsr.l #7,d0 ;make a word of blue
|
||
MOVE.w D0,blue(SP) ;store out in color spec
|
||
|
||
lsr.l #5,d5 ;left align green in lo byte
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;get 5 bits of green
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 10 bits of green
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 15 bits of green
|
||
move.b d5,d0
|
||
lsr.l #7,d0 ;get a word of green
|
||
MOVE.w D0,green(SP) ;store out in color spec
|
||
|
||
lsr.l #5,d5 ;left align red in lo byte
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;get 5 bits of red
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 10 bits of red
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 15 bits of red
|
||
move.b d5,d0
|
||
lsr.l #7,d0 ;get a word of red
|
||
MOVE.w D0,red(SP) ;store out in color spec
|
||
|
||
MOVE.L stSProc(A6),stTmpProc(A6) ;make a copy of the search proc head
|
||
NxtProc
|
||
MOVE.L stTmpProc(A6),D0 ;get sProcRec handle
|
||
BEQ.S OurTurn ;if not found using procs, use ITable
|
||
MOVE.L D0,A0 ;move handle to address register
|
||
MOVE.L (A0),A0 ;get sProcRec pointer
|
||
MOVE.L nxtSrch(A0),stTmpProc(A6) ;save handle to next sProcRec for later (might be NIL)
|
||
|
||
CLR.B -(SP) ;leave room for boolean result
|
||
PEA 2(SP) ;push pointer to stack colorspec
|
||
PEA 12(SP) ;push pointer to var result
|
||
|
||
MOVE.L srchProc(A0),A0 ;get search proc address
|
||
JSR (A0) ;call search proc
|
||
|
||
TST.B (SP)+ ;test result
|
||
BEQ.S NxtProc ;if FALSE, go to next searchProc
|
||
|
||
MOVE.L 6(SP),D3 ;get result in D3
|
||
BRA.S BuildLong ;and put into output buffer
|
||
|
||
OurTurn ;go here if no search proc matched
|
||
|
||
MOVE.L stITabPtr(A6),A0 ;get pointer to the inverse table (past header)
|
||
MOVE.W stITabRes(A6),D1 ;get the iTable resolution
|
||
|
||
move.b red(sp),d5
|
||
BFEXTU D5{24:D1},D0 ;5,8,8 ;extract iTabRes bits of red (clearing hi bits)
|
||
LSL.L D1,D0 ;3,6,6 ;shift over by iTabRes
|
||
move.b green(sp),d5
|
||
BFEXTU D5{24:D1},D3 ;5,8,8 ;get the green component
|
||
OR.L D3,D0 ;0,2,3 ;put them together
|
||
LSL.L D1,D0 ;3,6,6 ;shift again
|
||
move.b blue(sp),d5
|
||
BFEXTU D5{24:D1},D3 ;5,8,8 ;get the blue component
|
||
OR.L D3,D0 ;0,2,3 ;put them together to form iTable index
|
||
;21,40,42
|
||
MOVE.B (A0,D0.w),D3 ;get the index in D3 <KON 12MAR90>
|
||
|
||
BuildLong
|
||
BFINS D3,D6{D7:D4} ;PUT TO DST LONG <KON 12MAR90>
|
||
ADD D4,D7 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1F,D7 ;TIME FOR NEXT DST LONG?
|
||
BNE.S NXTSLNG ;=>NO
|
||
MOVE.L D6,(A3)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A3 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S NXTSLNG ;if lower, continue to next pixel
|
||
DONESCL
|
||
moveq #1,d0 ;force 32-bit mode <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
|
||
ADDA.W #10,SP ;release buffers
|
||
MOVEM.L (SP)+,A3-A5/D6-D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
|
||
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
|
||
SeedCFill16 PROC EXPORT
|
||
Export CalcCMask16
|
||
;
|
||
; this routine converts a 16-bit direct pixel to a 1 bit destination with zero's
|
||
; wherever the source matches the color pointed to by the GDRefcon field and
|
||
; one's everywhere else.
|
||
;
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
moveq #0,d1 ;clear high bit of d1 to signal SeedCFill
|
||
bra.s share
|
||
|
||
CalcCMask16
|
||
moveq #-1,d1 ;set high bit of d1 to signal CalcCMask
|
||
|
||
share
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 32 BIT DIRECT TO 1- BIT INDEXED
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
|
||
move.l a2,D5 ;save end of dst buffer in D5
|
||
MOVE.L theGDevice,A2 ;get handle to the gDevice
|
||
MOVE.L (A2),A2 ;point to theGDevice
|
||
MOVE.L GDRefCon(A2),A2 ;point to seed RGB
|
||
move.w (a2)+,d3 ;get RRrr
|
||
lsr.w #1,d3 ;clear high bit
|
||
lsl.l #6,d3 ;save 6 bits in high word
|
||
move.w (a2)+,d3 ;get GGrr
|
||
lsl.l #5,d3 ;save 5 more bits in high word
|
||
move.w (a2),d3 ;get BBbb
|
||
lsr.l #8,d3
|
||
lsr.l #3,d3 ; convert to 5-5-5 pixel in low word
|
||
move.l d5,a2 ;restore end of dst buffer
|
||
|
||
moveq #-1,d0 ;get low 15 bits mask
|
||
lsr.w #1,d0
|
||
MOVEQ #0,D4 ;init offset into destination
|
||
|
||
NXTSLNG
|
||
MOVE.w (A0)+,D5 ;pick up a 32-bit source pixel
|
||
and.w d0,d5 ;clear high byte for compare
|
||
cmp.w d5,d3 ;compare to seed value
|
||
sne.b d1 ;match ? d1=0 : d1=FF
|
||
|
||
BuildLong
|
||
BFINS D1,D2{D4:1} ;PUT TO DST LONG
|
||
ADDq #1,D4 ;BUMP TO NEXT DST PIXEL
|
||
AND #$1F,D4 ;TIME FOR NEXT DST LONG?
|
||
BNE.S NXTSLNG ;=>NO
|
||
|
||
addx.l d1,d1 ;tst high bit of d1
|
||
subx.l d1,d1 ;extend high bit throughout long
|
||
eor.l d1,d2 ;conditionally invert resulting bits
|
||
|
||
MOVE.L D2,(A1)+ ;ELSE SAVE CURRENT LONG
|
||
CMP.L A2,A1 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S NXTSLNG ;if lower, continue to next pixel
|
||
DONESCL
|
||
|
||
RTS
|
||
ENDPROC
|
||
|
||
|
||
|
||
Scale16to32 PROC EXPORT
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 16 BIT DIRECT TO 32 BIT DIRECT
|
||
; ASSUMES DST IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
; ASSUMES SRC IS COMPOSED OF TWO BYTES OF THE FORM 'X:1 R:5 G:5 B:5'
|
||
;
|
||
; USES: A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
|
||
move.l a2,d4 ;get ptr to end
|
||
sub.l a1,d4 ;sub ptr to beginning
|
||
lsr.l #3,d4 ;get double long cnt in d4
|
||
subq #1,d4 ;make zero based
|
||
bmi.s @do1More ;if only one, go do it <BAL 26Apr89>
|
||
MOVE.l (A0)+,D5 ;GET FIRST LONG OF SRC
|
||
bra.s @first
|
||
|
||
@NXTSLNG
|
||
MOVE.l (A0)+,D5 ;GET NEXT LONG OF SRC
|
||
cmp.l d0,d5 ;same as last time?
|
||
beq.s @again ;yes, go fast
|
||
@first move.l d5,d0 ;save this long of src
|
||
|
||
; Build second pixel in D3
|
||
@last
|
||
moveq #0,d3 ;0,2,3 ;start fresh
|
||
move.w d5,d1 ;0,2,3 ;make a copy
|
||
lsr.w #7,d1 ;1,4,4 ;left align red in low byte
|
||
move.b d1,d3 ;0,2,3 ;start with 5 bits of red
|
||
lsl.l #5,d3 ;1,4,4 ;save dstcmpsize (5) bits of red in high bytes
|
||
move.b d1,d3 ;0,2,3 ;get 3 bits of red
|
||
lsl.l #3,d3 ;1,4,4 ;save the 3 bits of red as well
|
||
move.w d5,d1 ;0,2,3 ;make a copy
|
||
lsr.w #2,d1 ;1,4,4 ;left align green in low byte
|
||
move.b d1,d3 ;0,2,3 ;start with 5 bits of green
|
||
lsl.l #5,d3 ;1,4,4 ;save dstcmpsize (5) bits of green in high bytes
|
||
move.b d1,d3 ;0,2,3 ;get 3 bits of green
|
||
lsl.l #3,d3 ;1,4,4 ;save the 3 bits of green as well
|
||
move.b d5,d1 ;0,2,3 ;make a copy
|
||
lsl.b #3,d1 ;1,4,4 ;left align blue in low byte
|
||
move.b d1,d3 ;0,2,3 ;start with 5 bits of blue
|
||
lsl.l #5,d3 ;1,4,4 ;save dstcmpsize (5) bits of blue in high bytes
|
||
move.b d1,d3 ;0,2,3 ;get 3 more bits of blue
|
||
lsr.l #5,d3 ;1,4,4 ;shift away extra blue bits
|
||
|
||
; Build first pixel in D2
|
||
|
||
swap d5 ;get first pixel
|
||
moveq #0,d2 ;0,2,3 ;start fresh
|
||
move.w d5,d1 ;0,2,3 ;make a copy
|
||
lsr.w #7,d1 ;1,4,4 ;left align red in low byte
|
||
move.b d1,d2 ;0,2,3 ;start with 5 bits of red
|
||
lsl.l #5,d2 ;1,4,4 ;save dstcmpsize (5) bits of red in high bytes
|
||
move.b d1,d2 ;0,2,3 ;get 3 bits of red
|
||
lsl.l #3,d2 ;1,4,4 ;save the 3 bits of red as well
|
||
move.w d5,d1 ;0,2,3 ;make a copy
|
||
lsr.w #2,d1 ;1,4,4 ;left align green in low byte
|
||
move.b d1,d2 ;0,2,3 ;start with 5 bits of green
|
||
lsl.l #5,d2 ;1,4,4 ;save dstcmpsize (5) bits of green in high bytes
|
||
move.b d1,d2 ;0,2,3 ;get 3 bits of green
|
||
lsl.l #3,d2 ;1,4,4 ;save the 3 bits of green as well
|
||
lsl.b #3,d5 ;1,4,4 ;left align blue in low byte
|
||
move.b d5,d2 ;0,2,3 ;start with 5 bits of blue
|
||
lsl.l #5,d2 ;1,4,4 ;save dstcmpsize (5) bits of blue in high bytes
|
||
move.b d5,d2 ;0,2,3 ;get 3 more bits of blue
|
||
lsr.l #5,d2 ;1,4,4 ;shift away extra blue bits
|
||
|
||
@again MOVE.L D2,(A1)+ ;SAVE FIRST PIXEL
|
||
MOVE.L D3,(A1)+ ;SAVE SECOND PIXEL
|
||
dbra d4,@NXTSLNG ;loop for all longs in dst scanline
|
||
cmp.l a1,a2 ;is there one more left?
|
||
bne.s @do1More ;yes go to it
|
||
RTS
|
||
@do1More
|
||
; moveq #0,d4 ;only do one <BAL 26Apr89>
|
||
; subq #4,a1 ;do last one again " "
|
||
; swap d5 ;put previous pixel first
|
||
move.w (a0)+,d5 ;do this pixel last
|
||
; bra.s @last
|
||
|
||
moveq #0,d2 ;0,2,3 ;start fresh
|
||
move.w d5,d1 ;0,2,3 ;make a copy
|
||
lsr.w #7,d1 ;1,4,4 ;left align red in low byte
|
||
move.b d1,d2 ;0,2,3 ;start with 5 bits of red
|
||
lsl.l #5,d2 ;1,4,4 ;save dstcmpsize (5) bits of red in high bytes
|
||
move.b d1,d2 ;0,2,3 ;get 3 bits of red
|
||
lsl.l #3,d2 ;1,4,4 ;save the 3 bits of red as well
|
||
move.w d5,d1 ;0,2,3 ;make a copy
|
||
lsr.w #2,d1 ;1,4,4 ;left align green in low byte
|
||
move.b d1,d2 ;0,2,3 ;start with 5 bits of green
|
||
lsl.l #5,d2 ;1,4,4 ;save dstcmpsize (5) bits of green in high bytes
|
||
move.b d1,d2 ;0,2,3 ;get 3 bits of green
|
||
lsl.l #3,d2 ;1,4,4 ;save the 3 bits of green as well
|
||
lsl.b #3,d5 ;1,4,4 ;left align blue in low byte
|
||
move.b d5,d2 ;0,2,3 ;start with 5 bits of blue
|
||
lsl.l #5,d2 ;1,4,4 ;save dstcmpsize (5) bits of blue in high bytes
|
||
move.b d5,d2 ;0,2,3 ;get 3 more bits of blue
|
||
lsr.l #5,d2 ;1,4,4 ;shift away extra blue bits " "
|
||
MOVE.L D2,(A1) ;write last pixel <BAL 26Apr89>
|
||
rts
|
||
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
|
||
Search16to32 PROC EXPORT
|
||
|
||
;
|
||
; this routine converts a 16-bit direct pixel to a 32 bit destination
|
||
; first applying the search proc for this device, then using a direct lookup
|
||
; if that fails.
|
||
;
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 16 BIT DIRECT TO 32 BIT DIRECT
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
|
||
MOVEM.L A3-A5/D7,-(SP) ;SAVE WORK REGISTERS
|
||
MOVE.L A0,A4 ;copy source buffer address to non-volatile register
|
||
MOVE.L A1,A3 ;copy dest buffer address
|
||
|
||
move.l saveA5(a6),a5 ;set up caller's A5 for the search proc <1.5> BAL
|
||
|
||
moveq #0,d0 ;force 24-bit mode <1.5>
|
||
move.l a2,d7 ;save a2 just for grins <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
move.l d7,a2 ;restore a2 just in case <1.5>
|
||
|
||
CLR.L -(SP) ;make room for SearchProc result
|
||
CLR.L -(SP) ;make room for an RGBColor and clear it
|
||
CLR.W -(SP) ;
|
||
|
||
DoOne
|
||
MOVE.W (A4)+,D5 ;pick up a 16-bit source pixel
|
||
lsl.l #3,d5 ;left align blue in lo byte
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;get 5 bits of blue
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 10 bits of blue
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 15 bits of blue
|
||
move.b d5,d0
|
||
lsr.l #7,d0 ;get a word of blue
|
||
MOVE.w D0,blue(SP) ;store out in color spec
|
||
|
||
lsr.l #5,d5 ;left align green in lo byte
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;get 5 bits of green
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 10 bits of green
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 15 bits of green
|
||
move.b d5,d0
|
||
lsr.l #7,d0 ;get a word of green
|
||
MOVE.w D0,green(SP) ;store out in color spec
|
||
|
||
lsr.l #5,d5 ;left align red in lo byte
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;get 5 bits of red
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 10 bits of red
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 15 bits of red
|
||
move.b d5,d0
|
||
lsr.l #7,d0 ;get a word of red
|
||
MOVE.w D0,red(SP) ;store out in color spec
|
||
|
||
MOVE.L stSProc(A6),stTmpProc(A6) ;make a copy of the search proc head
|
||
NxtProc
|
||
MOVE.L stTmpProc(A6),D0 ;get sProcRec handle
|
||
BEQ.S OurTurn ;if not found using procs, use ITable
|
||
MOVE.L D0,A0 ;move handle to address register
|
||
MOVE.L (A0),A0 ;get sProcRec pointer
|
||
MOVE.L nxtSrch(A0),stTmpProc(A6) ;save handle to next sProcRec for later (might be NIL)
|
||
|
||
CLR.B -(SP) ;leave room for boolean result
|
||
PEA 2(SP) ;push pointer to stack colorspec
|
||
PEA 12(SP) ;push pointer to var result
|
||
|
||
MOVE.L srchProc(A0),A0 ;get search proc address
|
||
JSR (A0) ;call search proc
|
||
|
||
TST.B (SP)+ ;test result
|
||
BEQ.S NxtProc ;if FALSE, go to next searchProc
|
||
|
||
MOVE.L 6(SP),D0 ;get result in D0
|
||
bra.s Loop ;and put into output buffer
|
||
|
||
OurTurn ;go here if no search proc matched
|
||
; moveq #0,d0 ;d0 is already 0
|
||
move.b red(sp),D0 ;get red
|
||
swap d0
|
||
move.b green(sp),d0 ;get green
|
||
lsl.w #8,d0
|
||
move.b blue(sp),d0 ;get blue
|
||
|
||
Loop
|
||
MOVE.L D0,(A3)+ ;SAVE CURRENT LONG
|
||
CMP.L A2,A3 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S DoOne ;if lower, continue to next pixel
|
||
DONESCL
|
||
moveq #1,d0 ;force 32-bit mode <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
|
||
ADDA.W #10,SP ;release buffers
|
||
MOVEM.L (SP)+,A3-A5/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
|
||
ENDPROC
|
||
|
||
|
||
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
||
|
||
Search16to16 PROC EXPORT ;<20AUG90 KON>
|
||
|
||
;
|
||
; this routine converts a 16-bit direct pixel to a 16 bit destination
|
||
; first applying the search proc for this device, then using a direct lookup
|
||
; if that fails.
|
||
;
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
;------------------------------------------------------------------
|
||
;
|
||
; SCALES A SCANLINE OF PIXELS FROM 16 BIT DIRECT TO 32 BIT DIRECT
|
||
; ASSUMES SRC IS COMPOSED OF FOUR BYTES OF THE FORM 'XRGB'
|
||
;
|
||
; USES: D3: SRC PIXEL SIZE
|
||
; D4: DST PIXEL SIZE
|
||
; A0: SRC BUFFER
|
||
; A1: DST BUFFER
|
||
; A2: END OF DST BUFFER
|
||
;
|
||
; CLOBBERS A0-A1/D0-D5
|
||
;
|
||
|
||
MOVEM.L A3-A5/D7,-(SP) ;SAVE WORK REGISTERS
|
||
MOVE.L A0,A4 ;copy source buffer address to non-volatile register
|
||
MOVE.L A1,A3 ;copy dest buffer address
|
||
|
||
move.l saveA5(a6),a5 ;set up caller's A5 for the search proc <1.5> BAL
|
||
|
||
moveq #0,d0 ;force 24-bit mode <1.5>
|
||
move.l a2,d7 ;save a2 just for grins <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
move.l d7,a2 ;restore a2 just in case <1.5>
|
||
|
||
CLR.L -(SP) ;make room for SearchProc result
|
||
CLR.L -(SP) ;make room for an RGBColor and clear it
|
||
CLR.W -(SP) ;
|
||
bra loop ;do 2 at a time <20AUG90 KON>
|
||
DoOne
|
||
MOVE.W (A4)+,D5 ;pick up a 16-bit source pixel
|
||
lsl.l #3,d5 ;left align blue in lo byte
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;get 5 bits of blue
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 10 bits of blue
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 15 bits of blue
|
||
move.b d5,d0
|
||
lsr.l #7,d0 ;get a word of blue
|
||
MOVE.w D0,blue+4(SP) ;store out in color spec
|
||
|
||
lsr.l #5,d5 ;left align green in lo byte
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;get 5 bits of green
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 10 bits of green
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 15 bits of green
|
||
move.b d5,d0
|
||
lsr.l #7,d0 ;get a word of green
|
||
MOVE.w D0,green+4(SP) ;store out in color spec
|
||
|
||
lsr.l #5,d5 ;left align red in lo byte
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;get 5 bits of red
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 10 bits of red
|
||
move.b d5,d0
|
||
lsl.l #5,d0 ;make into 15 bits of red
|
||
move.b d5,d0
|
||
lsr.l #7,d0 ;get a word of red
|
||
MOVE.w D0,red+4(SP) ;store out in color spec
|
||
|
||
MOVE.L stSProc(A6),stTmpProc(A6) ;make a copy of the search proc head
|
||
NxtProc
|
||
MOVE.L stTmpProc(A6),D0 ;get sProcRec handle
|
||
BEQ.S OurTurn ;if not found using procs, use ITable
|
||
MOVE.L D0,A0 ;move handle to address register
|
||
MOVE.L (A0),A0 ;get sProcRec pointer
|
||
MOVE.L nxtSrch(A0),stTmpProc(A6) ;save handle to next sProcRec for later (might be NIL)
|
||
|
||
CLR.B -(SP) ;leave room for boolean result
|
||
PEA 2+4(SP) ;push pointer to stack colorspec
|
||
PEA 12+4(SP) ;push pointer to var result
|
||
|
||
MOVE.L srchProc(A0),A0 ;get search proc address
|
||
JSR (A0) ;call search proc
|
||
|
||
TST.B (SP)+ ;test result
|
||
BEQ.S NxtProc ;if FALSE, go to next searchProc
|
||
|
||
MOVE.L 6+4(SP),D3 ;get result in D0
|
||
rts ;and put into output buffer
|
||
|
||
OurTurn ;go here if no search proc matched
|
||
;
|
||
; take rgb from stack and convert to 5-5-5
|
||
;
|
||
moveq #0,d0
|
||
move.b red+4(sp),d0 ;get high byte of red 00000000rrrrrrrr
|
||
lsl.w #5,d0 ;xxxrrrrrrrr00000
|
||
move.b green+4(sp),d0 ;get high byte of green xxxrrrrrgggggggg
|
||
lsl.l #5,d0 ;0rr|rrrgggggggg00000
|
||
move.b blue+4(sp),d0 ;0rr|rrrgggggbbbbbbbb
|
||
lsr.l #3,d0 ;0rrrrrgggggbbbbb
|
||
rts
|
||
|
||
Loop
|
||
bsr.s DoOne
|
||
move.w d0,d7
|
||
swap d7
|
||
bsr.s DoOne
|
||
move.w d0,d7
|
||
MOVE.L d7,(A3)+ ;SAVE CURRENT LONG
|
||
CMP.L A2,A3 ;DSTPTR >= DSTLIMIT?
|
||
BLO.S Loop ;if lower, continue to next pixel
|
||
DONESCL
|
||
moveq #1,d0 ;force 32-bit mode <1.5>
|
||
_rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2)
|
||
|
||
ADDA.W #10,SP ;release buffers
|
||
MOVEM.L (SP)+,A3-A5/D7 ;RESTORE WORK REGISTERS
|
||
RTS
|
||
ENDPROC
|
||
|
||
Include 'scaleBlt.a'
|
||
|
||
|
||
|
||
|
||
|
||
;******************************************************************************************
|
||
;******************************************************************************************
|
||
if 0 then ;<14SEP90 SMC>
|
||
;******************************************************************************************
|
||
;******************************************************************************************
|
||
|
||
ANDY PROC EXPORT
|
||
EXPORT CB8to8Clip, CB8to1Clip, CB1to8Clip
|
||
IMPORT DoneStretch
|
||
|
||
;----------------------------------------------------
|
||
;
|
||
; A6 OFFSETS OF LOCAL VARIABLES AFTER LINK:
|
||
;
|
||
; STACKFRAME LINKED AND LOCALS INITIALIZED BY STRETCHBITS.
|
||
;
|
||
&CurFile SETC 'STRETCH'
|
||
|
||
INCLUDE 'DrawingVars.a'
|
||
|
||
|
||
|
||
; The world according to Andy:
|
||
|
||
;******************************************************************************************
|
||
;
|
||
; CB1To8Clip ($373) is the clipped copyBits loop used in the 1 to 8 expansion blits,
|
||
; common in programs like HyperCard and Servant. If it's the typical case we can handle
|
||
; (black and white, source 1 bit,dest 8 bits), expand on the fly, right onto the screen,
|
||
; for a pretty big gain.
|
||
|
||
; it really shouldn't be named CB1to8, as it's the routine used for any scaling or lookup
|
||
; blit. We also optimize the 8-bit to 8-bit blits that require table lookup, and also
|
||
; handle the 8 to 1 case
|
||
|
||
|
||
|
||
CB1To8Clip
|
||
|
||
|
||
; MOVE.L SRCROW(A6),D0
|
||
; SUB.L D0,SRCADDR(A6) ;back up one line
|
||
|
||
|
||
@NXTMSK1
|
||
MOVE VERT(A6),D0 ;GET CURRENT VERT COORD
|
||
CMP MINRECT+TOP(A6),D0 ;IS VERT < MINV ?
|
||
BLT.S @NODRAW ;YES, DON'T DRAW
|
||
|
||
JSR ([SEEKMASK,A6]) ;MAKE MASK BUFFER CURRENT
|
||
Bra.s @GoForIt ;TAKE MODE JUMP
|
||
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 doneStretch ;YES, QUIT
|
||
MOVE.L SRCROW(A6),D2 ;GET SRC ROWBYTES
|
||
ADD.L D2,SRCADDR(A6) ;BUMP SRC TO NEXT ROW
|
||
BRA @NXTMSK1 ;ELSE continue to draw from this src <BAL 19Mar89>
|
||
|
||
|
||
@GoForIt
|
||
SUBQ #1,BUFSIZE(A6) ;one less than they say
|
||
MOVEQ #0,d7 ;inhibit zooming
|
||
MOVE.L DSTADDR(A6),A4 ;INIT DSTPTR FOR ROW
|
||
MOVE.L RGNBUFFER(A6),A2 ;INIT MASKPTR FOR ROW
|
||
|
||
; its our case, so handle it. Pick up the shifted source with a bit-field instruction,
|
||
; then use it to plot 8 longwords, indirecting a nibble at a time through an expansion
|
||
; table. Special case the edges, so we can really zoom if the middle's region is all ones.
|
||
|
||
; A2 has the region mask, A4 has the destination; use A3 to hold the source.
|
||
; D7 holds the "OK to zoom" (region all ones) flag
|
||
|
||
CB1to8Outer
|
||
MOVE.L DSTALIGN(A6),D0
|
||
ASR.L #3,D0
|
||
|
||
MOVEQ #15,D3 ;D3 has 4 bit mask
|
||
MOVEQ #-1,D6 ;D6 has -1 for region compare
|
||
LEA Table8,A1
|
||
|
||
MOVE.L SRCADDR(A6),A3 ;get source pointer
|
||
|
||
MOVE.L SRCALIGN(A6),D5 ;get shift count
|
||
ADD.L D0,D5
|
||
|
||
; OK, first do the left edge (one nybble worth)
|
||
|
||
BFEXTU (A3){D5:16},D4 ;pick up next word of source
|
||
ADDQ.L #4,D5 ;bump to next nibble
|
||
ROL.W #4,D4 ;get next nibble
|
||
|
||
MOVE.L (A2)+,D1 ;get region mask
|
||
BEQ.S @0 ;<14SEP90 SMC>
|
||
|
||
MOVE.W D4,D0 ;get low 4 bits
|
||
AND.W D3,D0
|
||
MOVE.L 0(A1,D0.W*4),D0 ;get source longword
|
||
AND.L D1,D0
|
||
|
||
NOT.L D1 ;flip mask
|
||
AND.L (A4),D1
|
||
OR.L D1,D0 ;combine source and dest
|
||
MOVE.L D0,(A4) ;+ ;stuff it ;<14SEP90 SMC>
|
||
@0: ADDQ #4,A4 ;<14SEP90 SMC>
|
||
|
||
; OK, here's the loop that handles the middle, which is where all the action is
|
||
|
||
MOVE.W BUFSIZE(A6),D2 ;get destination count
|
||
|
||
CMP.W #4,D2 ;four or less we can't optimize
|
||
BLE FinishLastFew
|
||
|
||
; if we have a multiple of 4 left to do, don't do last 4
|
||
|
||
MOVE.W D2,D0
|
||
AND #3,D0
|
||
BNE.S @1
|
||
|
||
SUBQ #1,D2
|
||
@1
|
||
LSR #2,D2 ;do 4 longwords each iteration
|
||
SUBQ #1,D2
|
||
|
||
TST.B D7 ;is region all ones?
|
||
BNE CB1to8SpLoop0 ;if so, we can go super-fast
|
||
|
||
ST D7 ;assume next like is special
|
||
CB1to8Loop
|
||
BFEXTU (A3){D5:16},D4 ;pick up next word of source
|
||
ADDQ #2,A3 ;bump it
|
||
BEQ CB1to8AllZeros ;special case all zeros
|
||
CB1to8AltEntry
|
||
ROL.W #4,D4 ;get high nibble first
|
||
|
||
; OK, expand the low 4 bits in D4 into a longword, then plot it. Fetch the region mask
|
||
; first, since it may not even be necessary
|
||
|
||
CB1to8Inner
|
||
LEA CB1to8Nib2,A5
|
||
|
||
MOVE.L (A2)+,D1 ;get region mask
|
||
|
||
MOVE.W D4,D0 ;get low 4 bits
|
||
AND.W D3,D0
|
||
MOVE.L 0(A1,D0.W*4),D0 ;get source longword
|
||
|
||
CMP.L D6,D1 ;mask all ones?
|
||
BNE CB1to8HardPlot ;if not, plot it the hard way
|
||
|
||
MOVE.L D0,(A4)+ ;plot the longword
|
||
|
||
; now plot the 2nd nibble
|
||
|
||
CB1to8Nib2
|
||
LEA CB1to8Nib3,A5
|
||
|
||
ROL.W #4,D4 ;get next nybble
|
||
|
||
MOVE.L (A2)+,D1 ;get region mask
|
||
|
||
MOVE.W D4,D0 ;get low 4 bits
|
||
AND.W D3,D0
|
||
MOVE.L 0(A1,D0.W*4),D0 ;get source longword
|
||
|
||
CMP.L D6,D1 ;mask all ones?
|
||
BNE.S CB1to8HardPlot ;if not, plot it the hard way
|
||
|
||
MOVE.L D0,(A4)+ ;plot the longword
|
||
|
||
; now plot the 3rd nibble
|
||
|
||
CB1to8Nib3
|
||
LEA CB1to8Nib4,A5
|
||
ROL.W #4,D4 ;get next nybble
|
||
|
||
MOVE.L (A2)+,D1 ;get region mask
|
||
|
||
MOVE.W D4,D0 ;get low 4 bits
|
||
AND.W D3,D0
|
||
MOVE.L 0(A1,D0.W*4),D0 ;get source longword
|
||
|
||
CMP.L D6,D1 ;mask all ones?
|
||
BNE.S CB1to8HardPlot ;if not, plot it the hard way
|
||
|
||
MOVE.L D0,(A4)+ ;plot the longword
|
||
|
||
; now plot the last nibble
|
||
|
||
CB1to8Nib4
|
||
LEA CB1to8NibBot,A5
|
||
|
||
ROL.W #4,D4 ;get next nybble
|
||
|
||
MOVE.L (A2)+,D1 ;get region mask
|
||
|
||
MOVE.W D4,D0 ;get low 4 bits
|
||
AND.W D3,D0
|
||
MOVE.L 0(A1,D0.W*4),D0 ;get source longword
|
||
|
||
CMP.L D6,D1 ;mask all ones?
|
||
BNE.S CB1to8HardPlot ;if not, plot it the hard way
|
||
|
||
MOVE.L D0,(A4)+ ;plot the longword
|
||
CB1to8NibBot
|
||
DBRA D2,CB1to8Loop ;loop until done
|
||
|
||
; clean up the last 0 to 3 nibbles; 4 remaining handled specially
|
||
|
||
FinishLastFew
|
||
BFEXTU (A3){D5:16},D4 ;pick up last word of source
|
||
LEA BotFin1to8Loop,A5
|
||
MOVE.W BUFSIZE(A6),D2 ;get the number left to do
|
||
BEQ CB1to8NextLine ;if zero, we're done
|
||
|
||
AND.W #3,D2 ;0 to 3 only
|
||
BNE.S BotFin1to8Loop
|
||
|
||
MOVEQ #3,D2 ;4 to do
|
||
TopFin1to8Loop
|
||
ROL.W #4,D4
|
||
|
||
MOVE.L (A2)+,D1 ;get region mask
|
||
|
||
MOVE.W D4,D0 ;get low 4 bits
|
||
AND.W D3,D0
|
||
MOVE.L 0(A1,D0.W*4),D0 ;get source longword
|
||
|
||
CMP.L D6,D1 ;mask all ones?
|
||
BNE.S CB1to8HPNoInval ;if not, plot it the hard way (no edge)
|
||
|
||
MOVE.L D0,(A4)+ ;plot the longword
|
||
BotFin1to8Loop
|
||
DBRA D2,TopFin1to8Loop
|
||
BRA.S CB1to8NextLine
|
||
|
||
; handle the case where the region mask is all zeros
|
||
|
||
CB1to8NoPlot
|
||
ADDQ.L #4,A4 ;bump dest ptr
|
||
JMP (A5) ;advance to next one
|
||
|
||
; handle the more difficult case of a heterogenous region mask
|
||
|
||
CB1to8HardPlot
|
||
MOVEQ #0,D7 ;not all ones
|
||
CB1to8HPNoInval
|
||
TST.L D1
|
||
BEQ.S CB1to8NoPlot
|
||
|
||
AND.L D1,D0
|
||
|
||
NOT.L D1 ;flip mask
|
||
AND.L (A4),D1
|
||
OR.L D1,D0 ;combine source and dest
|
||
MOVE.L D0,(A4)+ ;stuff it
|
||
JMP (A5)
|
||
|
||
; to speed things up, we special case words of all zero and blast 4 long words of zero out as
|
||
; fast as we can, without having to do any lookups.
|
||
|
||
CB1to8AllZeros
|
||
MOVE.L (A2)+,D1 ;get region mask
|
||
BEQ.S CBZEmpty1 ;if all zeros, skip
|
||
|
||
CMP.L D6,D1 ;all ones?
|
||
BNE.S CBZBIC1 ;if not, skip
|
||
|
||
CLR.L (A4)+ ;plot the zeros
|
||
CBZLong2
|
||
MOVE.L (A2)+,D1 ;get region mask
|
||
BEQ.S CBZEmpty2 ;if all zeros, skip
|
||
|
||
CMP.L D6,D1 ;all ones?
|
||
BNE.S CBZBIC2 ;if not, skip
|
||
|
||
CLR.L (A4)+ ;plot the zeros
|
||
CBZLong3
|
||
MOVE.L (A2)+,D1 ;get region mask
|
||
BEQ.S CBZEmpty3 ;if all zeros, skip
|
||
|
||
CMP.L D6,D1 ;all ones?
|
||
BNE.S CBZBIC3 ;if not, skip
|
||
|
||
CLR.L (A4)+ ;plot the zeros
|
||
CBZLong4
|
||
MOVE.L (A2)+,D1 ;get region mask
|
||
BEQ.S CBZEmpty4 ;if all zeros, skip
|
||
|
||
CMP.L D6,D1 ;all ones?
|
||
BNE.S CBZBIC4 ;if not, skip
|
||
|
||
CLR.L (A4)+ ;plot the zeros
|
||
BRA.S CB1to8NibBot ;dive back in
|
||
CBZEmpty1
|
||
MOVEQ #0,D7
|
||
ADDQ #4,A4
|
||
BRA.S CBZLong2
|
||
CBZEmpty2
|
||
MOVEQ #0,D7
|
||
ADDQ #4,A4
|
||
BRA.S CBZLong3
|
||
CBZEmpty3
|
||
MOVEQ #0,D7
|
||
ADDQ #4,A4
|
||
BRA.S CBZLong4
|
||
CBZEmpty4
|
||
MOVEQ #0,D7
|
||
ADDQ #4,A4
|
||
BRA CB1to8NibBot
|
||
CBZBIC1
|
||
MOVEQ #0,D7
|
||
NOT.L D1
|
||
AND.L D1,(A4)+
|
||
BRA.S CBZLong2
|
||
CBZBIC2
|
||
MOVEQ #0,D7
|
||
NOT.L D1
|
||
AND.L D1,(A4)+
|
||
BRA.S CBZLong3
|
||
CBZBIC3
|
||
MOVEQ #0,D7
|
||
NOT.L D1
|
||
AND.L D1,(A4)+
|
||
BRA.S CBZLong4
|
||
CBZBIC4
|
||
MOVEQ #0,D7
|
||
NOT.L D1
|
||
AND.L D1,(A4)+
|
||
BRA CB1to8NibBot
|
||
|
||
|
||
; all done with this line, so bump the pointers and loop until done
|
||
|
||
CB1to8NextLine
|
||
MOVE.L DSTROW(A6),D0
|
||
ADD.L D0,DSTADDR(A6) ;bump to next line of destination
|
||
|
||
MOVE.L SRCROW(A6),D0
|
||
ADD.L D0,SRCADDR(A6) ;bump to next line of source
|
||
|
||
; bump line count and see if we're done
|
||
|
||
MOVE.W VERT(A6),D0
|
||
ADDQ #1,D0
|
||
MOVE.W D0,VERT(A6)
|
||
|
||
CMP.W MINRECT+BOTTOM(A6),D0 ;all done?
|
||
BEQ DoneStretch ;if so, go Home
|
||
|
||
; create the region mask for the new scan line, and maintain the all one's flag
|
||
|
||
CMP.W STATEB+NEXTV(A6),D0 ;rebuild the region?
|
||
BGE.S CB1to8NewRgn ;if so, go do it
|
||
|
||
CMP.W STATEB+THISV(A6),D0 ;need to rebuild?
|
||
BLT.S CB1to8NewRgn ;if so, go do it
|
||
|
||
CMP.W STATEC+NEXTV(A6),D0 ;rebuild the region?
|
||
BGE.S CB1to8NewRgn ;if so, go do it
|
||
|
||
CMP.W STATEC+THISV(A6),D0 ;need to rebuild?
|
||
BLT.S CB1to8NewRgn ;if so, go do it
|
||
|
||
CMP.W STATEA+NEXTV(A6),D0 ;rebuild the region?
|
||
BGE.S CB1to8NewRgn ;if so, go do it
|
||
|
||
CMP.W STATEA+THISV(A6),D0 ;need to rebuild?
|
||
BGE.S Skip1to8Rgn ;if not, skip
|
||
CB1to8NewRgn
|
||
MOVEQ #0,D7 ;invalidate region all ones flag
|
||
|
||
MOVE.L SEEKMASK(A6),A0
|
||
JSR (A0) ;make new region mask
|
||
|
||
; set up registers and go handle the next line
|
||
|
||
Skip1to8Rgn
|
||
MOVE.L RGNBUFFER(A6),A2
|
||
MOVE.L DSTADDR(A6),A4
|
||
|
||
BRA CB1to8Outer ;go process next line
|
||
|
||
|
||
|
||
; here's where we go when we've detected that region masking isn't necessary, so we can really
|
||
; blast things 4 longwords at a time
|
||
|
||
CB1to8SpLoop0
|
||
MOVE.W D2,D7 ;remember the count
|
||
|
||
CB1to8SpLoop
|
||
BFEXTU (A3){D5:16},D4 ;pick up next word of source
|
||
ADDQ #2,A3 ;bump it
|
||
BEQ.S CB1to8SpAllZeros ;special case all zeros
|
||
|
||
CMP.W D4,D6 ;all ones?
|
||
BEQ.S CB1to8SpAllOnes
|
||
|
||
swap d4 ;keep src data in high word
|
||
ROL.l #4,D4 ;get first nibble
|
||
AND.W D3,d4 ;get low 4 bits
|
||
MOVE.L 0(A1,D4.W*4),(A4)+ ;plot expanded longword
|
||
|
||
ROL.l #4,D4 ;get next nibble
|
||
AND.W D3,D4
|
||
MOVE.L 0(A1,D4.W*4),(A4)+ ;plot expanded longword
|
||
|
||
ROL.l #4,D4 ;get next nibble
|
||
AND.W D3,D4
|
||
MOVE.L 0(A1,D4.W*4),(A4)+ ;plot expanded longword
|
||
|
||
ROL.l #4,D4 ;get next nibble
|
||
AND.W D3,D4
|
||
MOVE.L 0(A1,D4.W*4),(A4)+ ;plot expanded longword
|
||
|
||
BotCB1to8SpLoop
|
||
DBRA D2,CB1to8SpLoop
|
||
|
||
; finish up the special case by adjusting A2 and diving back into common code
|
||
|
||
Finish1to8Sp
|
||
ADDQ #1,D7 ;add one for real count
|
||
LSL.W #4,D7 ;4 longs (16 bytes) per iteration
|
||
ADD.W D7,A2 ;bump region pointer
|
||
BRA FinishLastFew ;finish the last few
|
||
|
||
; handle the case when the source word is all zero and there's no region clipping -- we
|
||
; can go as fast as we can.
|
||
|
||
CB1to8SpAllZeros
|
||
CLR.L (A4)+
|
||
CLR.L (A4)+
|
||
CLR.L (A4)+
|
||
CLR.L (A4)+
|
||
|
||
BRA.S BotCB1to8SpLoop
|
||
|
||
CB1to8SpAllOnes
|
||
MOVE.L D6,(A4)+
|
||
MOVE.L D6,(A4)+
|
||
MOVE.L D6,(A4)+
|
||
MOVE.L D6,(A4)+
|
||
|
||
BRA.S BotCB1to8SpLoop
|
||
|
||
|
||
;******************************************************************************************
|
||
|
||
CB8to81st0
|
||
ADDQ #4,A3 ;bump source ptr
|
||
ADDQ #4,A4 ;bump dest ptr
|
||
BRA CB8to8Middle
|
||
|
||
|
||
; Handler for the 8 to 8 copyBits case (with mapping). The basic strategy is the usual
|
||
; region counting, with the added twist of a single element cache for the longword mapping,
|
||
; using A1 to hold the pre-map and D7 to hold the post-mapped values.
|
||
|
||
CB8to8Clip
|
||
; MOVE.L SRCROW(A6),D0
|
||
; SUB.L D0,SRCADDR(A6) ;back up one line
|
||
|
||
|
||
@NXTMSK1
|
||
MOVE VERT(A6),D0 ;GET CURRENT VERT COORD
|
||
CMP MINRECT+TOP(A6),D0 ;IS VERT < MINV ?
|
||
BLT.S @NODRAW ;YES, DON'T DRAW
|
||
|
||
JSR ([SEEKMASK,A6]) ;MAKE MASK BUFFER CURRENT
|
||
Bra.s @GoForIt ;TAKE MODE JUMP
|
||
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 doneStretch ;YES, QUIT
|
||
MOVE.L SRCROW(A6),D2 ;GET SRC ROWBYTES
|
||
ADD.L D2,SRCADDR(A6) ;BUMP SRC TO NEXT ROW
|
||
BRA @NXTMSK1 ;ELSE continue to draw from this src <BAL 19Mar89>
|
||
|
||
|
||
@GoForIt
|
||
SUBQ #1,BUFSIZE(A6) ;one less than they say
|
||
MOVEQ #-1,D6 ;D6 has -1 for region compare
|
||
|
||
MOVEQ #0,D4
|
||
MOVEQ #0,D3 ;init region counting regs
|
||
|
||
MOVE.L SCALETBL(A6),A5 ;get mapping table
|
||
SUB.L A1,A1 ;use zero for initial input cache <BAL 30Apr89>
|
||
MOVE.L (A5),D0 ;compute output cache value <BAL 30Apr89>
|
||
MOVE.B D0,D7 ;map 1st byte <BAL 30Apr89>
|
||
LSL.L #8,D7 ; <BAL 30Apr89>
|
||
MOVE.B D0,D7 ;map 2nd byte <BAL 30Apr89>
|
||
MOVE.W D7,D0 ;get 2 mapped bytes <BAL 30Apr89>
|
||
SWAP D7 ; <BAL 30Apr89>
|
||
MOVE.W D0,D7 ;map 3rd and 4th bytes <BAL 30Apr89>
|
||
|
||
CB8to8Outer
|
||
MOVE.L RGNBUFFER(A6),A2
|
||
MOVE.L SRCADDR(A6),A3 ;get source pointer
|
||
MOVE.L DSTADDR(A6),A4 ;get destptr
|
||
MOVE.L SCALETBL(A6),A5 ;get mapping table
|
||
|
||
; offset source pointer according to bit offsets
|
||
|
||
MOVE.L DSTALIGN(A6),D0 ;get shift count
|
||
ASR.L #3,D0
|
||
MOVE.L SRCALIGN(A6),D1
|
||
ASR.L #3,D1
|
||
ADD.L D1,D0
|
||
ADD.L D0,A3 ;offset source ptr
|
||
|
||
; OK, first do the left edge
|
||
|
||
MOVE.W BUFSIZE(A6),D2 ;get the count
|
||
|
||
MOVEQ #0,D5
|
||
|
||
MOVE.L (A2)+,D1 ;get region mask
|
||
BEQ.S CB8to81st0 ;if zero, handle it
|
||
|
||
; fetch the 1st source longword and map it through the table pointed to by A5
|
||
|
||
MOVE.L (A3)+,D0 ;get source longword
|
||
MOVE.L D0,A1 ;remember it
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 1st byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 2nd byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 3rd byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 4th byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.L D0,D7 ;remember result of mapping
|
||
|
||
; plot it using the region mask
|
||
|
||
AND.L D1,D0
|
||
NOT.L D1 ;flip mask
|
||
AND.L (A4),D1
|
||
OR.L D1,D0 ;combine source and dest
|
||
MOVE.L D0,(A4)+ ;stuff it
|
||
|
||
SUBQ #1,D2
|
||
BMI.S CB8to8NextLine
|
||
|
||
; if the region runs in D4 are still valid, we can use special code to really plot super
|
||
; fast.
|
||
|
||
CB8to8Middle
|
||
TST.W D4 ;is it valid?
|
||
BNE V8to8PlotRgnRuns ;if so, go super fast
|
||
|
||
MOVEQ #-1,D4 ;validate it for next time
|
||
MOVEQ #0,D3 ;zero the run count
|
||
|
||
; see what the next region longword is. Go to three different loops depending on whether
|
||
; the region is all ones, zeros or both
|
||
|
||
MOVE.L (A2)+,D1 ;fetch next word of region mask
|
||
BEQ V8to8FirstZero0 ;if zero, go handle
|
||
|
||
CMP.L D6,D1 ;all one's?
|
||
BNE V8to8StartSecondRun ;if not, skip
|
||
|
||
BRA.S V8to8FirstOnes1
|
||
|
||
; here's the loop that counts and plots the first run of all ones
|
||
|
||
V8to8FirstOnes
|
||
MOVE.L (A2)+,D1
|
||
|
||
CMP.L D6,D1 ;is it still all ones?
|
||
BNE V8to8StartSecondRun ;if not, end the run
|
||
V8to8FirstOnes1
|
||
ADDQ.W #1,D3 ;bump the run count
|
||
|
||
MOVE.L (A3)+,D0 ;fetch from source
|
||
CMP.L D0,A1 ;same as before?
|
||
BNE.S @0
|
||
|
||
MOVE.L D7,D0
|
||
BRA.S @1
|
||
@0
|
||
MOVE.L D0,A1
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 1st byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 2nd byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 3rd byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 4th byte
|
||
ROL.L #8,D0
|
||
MOVE.L D0,D7
|
||
@1
|
||
MOVE.L D0,(A4)+ ;store at destination
|
||
|
||
DBRA D2,V8to8FirstOnes ;loop until we're done
|
||
|
||
; OK, all done with this line, so bump the pointers and loop until done
|
||
|
||
CB8to8NextLine
|
||
MOVE.L DSTROW(A6),D0
|
||
ADD.L D0,DSTADDR(A6) ;bump to next line of destination
|
||
|
||
MOVE.L SRCROW(A6),D0
|
||
ADD.L D0,SRCADDR(A6) ;bump to next line of source
|
||
|
||
; bump line count and see if we're done
|
||
|
||
MOVE.W VERT(A6),D0
|
||
ADDQ #1,D0
|
||
MOVE.W D0,VERT(A6)
|
||
|
||
CMP.W MINRECT+BOTTOM(A6),D0 ;all done?
|
||
BEQ DoneStretch ;if so, use common exit
|
||
|
||
; create the region mask for the new scan line, and maintain the all ones flag
|
||
|
||
CMP.W STATEB+NEXTV(A6),D0 ;rebuild the region?
|
||
BGE.S CB8to8NewRgn ;if so, go do it
|
||
|
||
CMP.W STATEB+THISV(A6),D0 ;need to rebuild?
|
||
BLT.S CB8to8NewRgn ;if so, go do it
|
||
|
||
CMP.W STATEC+NEXTV(A6),D0 ;rebuild the region?
|
||
BGE.S CB8to8NewRgn ;if so, go do it
|
||
|
||
CMP.W STATEC+THISV(A6),D0 ;need to rebuild?
|
||
BLT.S CB8to8NewRgn ;if so, go do it
|
||
|
||
CMP.W STATEA+NEXTV(A6),D0 ;rebuild the region?
|
||
BGE.S CB8to8NewRgn ;if so, go do it
|
||
|
||
CMP.W STATEA+THISV(A6),D0 ;need to rebuild?
|
||
BGE CB8to8Outer ;if not, skip
|
||
CB8to8NewRgn
|
||
MOVEQ #0,D4 ;invalidate region all ones flag
|
||
|
||
MOVE.L A1,-(SP)
|
||
MOVE.L SEEKMASK(A6),A0
|
||
JSR (A0) ;make new region mask
|
||
MOVE.L (SP)+,A1
|
||
|
||
; go handle the next line
|
||
|
||
BRA CB8to8Outer ;go process next line
|
||
|
||
Fin8to8Zeros
|
||
ADDQ #4,A4
|
||
BRA.S CB8to8NextLine
|
||
|
||
; here's the loop that counts and plots the first run of all zeros
|
||
|
||
V8to8FirstZero
|
||
MOVE.L (A2)+,D1
|
||
BNE.S V8to8StartSecondRun
|
||
V8to8FirstZero0
|
||
SUBQ.W #1,D3 ;decrement run count for zeros
|
||
|
||
ADDQ #4,A3
|
||
ADDQ #4,A4
|
||
DBRA D2,V8to8FirstZero
|
||
|
||
BRA.S CB8to8NextLine
|
||
|
||
; the region mask is heterogenous, so plot the word and start the second run.
|
||
|
||
V8to8StartSecondRun
|
||
SWAP D3
|
||
|
||
MOVE.L (A3)+,D0 ;fetch from source
|
||
CMP.L D0,A1 ;same as before?
|
||
BNE.S @0
|
||
|
||
MOVE.L D7,D0
|
||
BRA.S @1
|
||
@0
|
||
MOVE.L D0,A1
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 1st byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 2nd byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 3rd byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 4th byte
|
||
ROL.L #8,D0
|
||
MOVE.L D0,D7
|
||
@1
|
||
AND.L D1,D0 ;mask it
|
||
NOT.L D1 ;flip mask
|
||
AND.L (A4),D1 ;combine with source
|
||
OR.L D1,D0 ;form dest longword
|
||
MOVE.L D0,(A4)+ ;deposit it
|
||
|
||
SUBQ #1,D2
|
||
BMI.S Done8to8SecondRun
|
||
|
||
; sample the region and case out for the 2nd time
|
||
|
||
MOVE.L (A2)+,D1 ;fetch next word of region mask
|
||
BEQ.S V8to8Zero0 ;if zero, go handle
|
||
|
||
CMP.L D6,D1 ;all one's?
|
||
BNE.S V8to8StartLastRun ;if not, skip
|
||
|
||
BRA.S V8to8Ones1
|
||
|
||
; here's the loop that counts and plots the second run of all ones
|
||
|
||
V8to8Ones
|
||
MOVE.L (A2)+,D1
|
||
|
||
CMP.L D6,D1 ;is it still all ones?
|
||
BNE.S V8to8StartLastRun ;if not, end the run
|
||
V8to8Ones1
|
||
ADDQ.W #1,D3 ;bump the run count
|
||
|
||
MOVE.L (A3)+,D0 ;fetch from source
|
||
CMP.L D0,A1 ;same as before?
|
||
BNE.S @0
|
||
|
||
MOVE.L D7,D0
|
||
BRA.S @1
|
||
@0
|
||
MOVE.L D0,A1
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 1st byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 2nd byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 3rd byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 4th byte
|
||
ROL.L #8,D0
|
||
MOVE.L D0,D7
|
||
@1
|
||
MOVE.L D0,(A4)+ ;store at destination
|
||
|
||
DBRA D2,V8to8Ones ;loop until we're done
|
||
Done8to8SecondRun
|
||
SWAP D3
|
||
BRA CB8to8NextLine ;all done
|
||
|
||
; here's the loop that counts the 2nd run of zeros
|
||
|
||
V8to8Zero
|
||
MOVE.L (A2)+,D1
|
||
BNE.S V8to8StartLastRun
|
||
V8to8Zero0
|
||
SUBQ.W #1,D3
|
||
|
||
ADDQ #4,A3
|
||
ADDQ #4,A4 ;bump dest reg
|
||
|
||
DBRA D2,V8to8Zero ;loop until it changes
|
||
|
||
BRA.S Done8to8SecondRun
|
||
|
||
; OK, we've accumulated two runs, so finish up the line without counting
|
||
|
||
V8to8StartLastRun
|
||
SWAP D3
|
||
|
||
TST.L D1
|
||
BEQ.S V8to8LastZero
|
||
BRA.S V8to8LastLoopA
|
||
V8to8LastLoop
|
||
MOVE.L (A2)+,D1 ;get region
|
||
BEQ.S V8to8LastZero
|
||
V8to8LastLoopA
|
||
CMP.L D6,D1
|
||
BNE.S V8to8LastHard
|
||
|
||
MOVE.L (A3)+,D0 ;fetch from source
|
||
CMP.L D0,A1 ;same as before?
|
||
BNE.S @0
|
||
|
||
MOVE.L D7,D0
|
||
BRA.S @1
|
||
@0
|
||
MOVE.L D0,A1
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 1st byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 2nd byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 3rd byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 4th byte
|
||
ROL.L #8,D0
|
||
MOVE.L D0,D7
|
||
@1
|
||
MOVE.L D0,(A4)+ ;store at destination
|
||
DBRA D2,V8to8LastLoop
|
||
|
||
BRA CB8to8NextLine
|
||
V8to8LastZero
|
||
ADDQ #4,A4
|
||
ADDQ #4,A3
|
||
DBRA D2,V8to8LastLoop
|
||
BRA CB8to8NextLine
|
||
V8to8LastHard
|
||
MOVE.L (A3)+,D0 ;fetch from source
|
||
CMP.L D0,A1 ;same as before?
|
||
BNE.S @0
|
||
|
||
MOVE.L D7,D0
|
||
BRA.S @1
|
||
@0
|
||
MOVE.L D0,A1
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 1st byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 2nd byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 3rd byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 4th byte
|
||
ROL.L #8,D0
|
||
MOVE.L D0,D7
|
||
@1
|
||
AND.L D1,D0 ;mask it
|
||
NOT.L D1 ;flip mask
|
||
AND.L (A4),D1 ;combine with source
|
||
OR.L D1,D0 ;form dest longword
|
||
MOVE.L D0,(A4)+ ;deposit it
|
||
|
||
DBRA D2,V8to8LastLoop
|
||
BRA CB8to8NextLine
|
||
|
||
; Here's where we have the ultra fast plotting by interpreting the 2 region runs in D3.
|
||
|
||
V8to8PlotRgnRuns
|
||
TST.W D3 ;which type of run?
|
||
BPL.S V8to8BlastPat1 ;if ones, go blast it
|
||
BEQ V8to8PlotRHard1 ;if zero, plot one slowly, then plot 2nd run
|
||
|
||
; it's negative, so just skip over 4 times the count
|
||
|
||
MOVE.W D3,D0
|
||
|
||
NEG.W D0 ;turn into longword count
|
||
LSL.W #2,D0 ;times 4
|
||
|
||
ADD.W D0,A2 ;skip over region
|
||
ADD.W D0,A3 ;skip over source
|
||
ADD.W D0,A4 ;skip over destination
|
||
|
||
ADD.W D3,D2 ;decrement count
|
||
BMI CB8to8NextLine ;if done, skip
|
||
|
||
; now handle the second run
|
||
|
||
V8to8PRRun2
|
||
LEA @0,A0 ;plot the break longword
|
||
BRA V8to8PlotHardCommon
|
||
@0
|
||
MOVE.L D3,D0 ;which type of run?
|
||
BPL.S V8to8BlastPat2 ;if ones, go blast it
|
||
BEQ.S V8to8PlotRHard2
|
||
|
||
; it's negative, so we can skip over like above
|
||
|
||
SWAP D0
|
||
NEG.W D0 ;turn into longword count
|
||
SUB.W D0,D2 ;decrement count
|
||
|
||
LSL.W #2,D0 ;times 4
|
||
|
||
ADD.W D0,A2 ;skip over region
|
||
ADD.W D0,A3 ;skip over source
|
||
ADD.W D0,A4 ;skip over destination
|
||
|
||
TST.W D2
|
||
BMI CB8to8NextLine ;if done, skip
|
||
|
||
; we've interpreted both runs, so finish up using common code
|
||
|
||
BRA V8to8LastLoop
|
||
|
||
; Handle blasting out the first run
|
||
|
||
V8to8BlastPat1
|
||
MOVE.W D3,D0 ;get the size
|
||
|
||
MOVE.W D0,D1
|
||
LSL #2,D1 ;times 4
|
||
ADD.W D1,A2 ;bump region ptr
|
||
SUB.W D0,D2
|
||
|
||
LEA V8to8PRRun2,A0
|
||
BRA.S V8to8BlastPatBot
|
||
|
||
; Blast out the second run
|
||
|
||
V8to8BlastPat2
|
||
SWAP D0 ;use high word for 2nd run
|
||
|
||
MOVE.W D0,D1
|
||
LSL #2,D1 ;times 4
|
||
ADD.W D1,A2 ;bump region ptr
|
||
SUB.W D0,D2
|
||
|
||
LEA V8to8LastLoop,A0
|
||
BRA.S V8to8BlastPatBot
|
||
V8to8BlastPat
|
||
MOVE.L (A3)+,D1 ;fetch from source
|
||
CMP.L D1,A1 ;same as before?
|
||
beq.s @1
|
||
|
||
MOVE.L D1,A1
|
||
MOVE.B D1,D5
|
||
MOVE.B 3(A5,D5.W*4),D1 ;map 1st byte
|
||
ROL.L #8,D1
|
||
|
||
MOVE.B D1,D5
|
||
MOVE.B 3(A5,D5.W*4),D1 ;map 2nd byte
|
||
ROL.L #8,D1
|
||
|
||
MOVE.B D1,D5
|
||
MOVE.B 3(A5,D5.W*4),D1 ;map 3rd byte
|
||
ROL.L #8,D1
|
||
|
||
MOVE.B D1,D5
|
||
MOVE.B 3(A5,D5.W*4),D1 ;map 4th byte
|
||
ROL.L #8,D1
|
||
MOVE.L D1,D7
|
||
@1
|
||
MOVE.L d7,(A4)+ ;store at destination
|
||
V8to8BlastPatBot
|
||
DBRA D0,V8to8BlastPat
|
||
|
||
; all done with plotting run of ones
|
||
|
||
TST.W D2
|
||
BMI CB8to8NextLine
|
||
|
||
JMP (A0)
|
||
|
||
; handle the heterogenous plots between runs
|
||
|
||
V8to8PlotRHard1
|
||
LEA V8to8PRRun2,A0
|
||
BRA.S V8to8PlotHardCommon
|
||
V8to8PlotRHard2
|
||
LEA V8to8LastLoop,A0
|
||
V8to8PlotHardCommon
|
||
MOVE.L (A2)+,D1 ;get region mask
|
||
|
||
MOVE.L (A3)+,D0 ;fetch from source
|
||
CMP.L D0,A1 ;same as before?
|
||
BNE.S @0
|
||
|
||
MOVE.L D7,D0
|
||
BRA.S @1
|
||
@0
|
||
MOVE.L D0,A1
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 1st byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 2nd byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 3rd byte
|
||
ROL.L #8,D0
|
||
|
||
MOVE.B D0,D5
|
||
MOVE.B 3(A5,D5.W*4),D0 ;map 4th byte
|
||
ROL.L #8,D0
|
||
MOVE.L D0,D7
|
||
@1
|
||
AND.L D1,D0 ;mask it
|
||
NOT.L D1 ;flip mask
|
||
AND.L (A4),D1 ;combine with source
|
||
OR.L D1,D0 ;form dest longword
|
||
MOVE.L D0,(A4)+ ;deposit it
|
||
|
||
SUBQ #1,D2 ;count it
|
||
BMI CB8to8NextLine
|
||
|
||
JMP (A0)
|
||
|
||
|
||
|
||
;******************************************************************************************
|
||
|
||
|
||
; Handler for the 8 to 1 copyBits case (mapped ). The basic strategy is the usual
|
||
; region counting, with the added twist of a single element cache for the longword mapping,
|
||
; using A1 to hold the pre-map and D7 to hold the post-mapped values.
|
||
|
||
|
||
CB8to11st0
|
||
ADD.W #32,A3 ;bump source ptr
|
||
ADDQ #4,A4 ;bump dest ptr
|
||
BRA.S CB8to1Middle
|
||
|
||
|
||
CB8to1Clip
|
||
; MOVE.L SRCROW(A6),D0
|
||
; SUB.L D0,SRCADDR(A6) ;back up one line
|
||
|
||
|
||
@NXTMSK1
|
||
MOVE VERT(A6),D0 ;GET CURRENT VERT COORD
|
||
CMP MINRECT+TOP(A6),D0 ;IS VERT < MINV ?
|
||
BLT.S @NODRAW ;YES, DON'T DRAW
|
||
|
||
JSR ([SEEKMASK,A6]) ;MAKE MASK BUFFER CURRENT
|
||
Bra.s @GoForIt ;TAKE MODE JUMP
|
||
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 doneStretch ;YES, QUIT
|
||
MOVE.L SRCROW(A6),D2 ;GET SRC ROWBYTES
|
||
ADD.L D2,SRCADDR(A6) ;BUMP SRC TO NEXT ROW
|
||
BRA @NXTMSK1 ;ELSE continue to draw from this src <BAL 19Mar89>
|
||
|
||
|
||
@GoForIt
|
||
SUBQ #1,BUFSIZE(A6) ;one less than they say
|
||
MOVEQ #-1,D6 ;D6 has -1 for region compare
|
||
|
||
MOVEQ #0,D4
|
||
MOVEQ #0,D3 ;init region counting regs
|
||
|
||
SUB.L A1,A1
|
||
SUBQ.L #1,A1 ;all ones for initial
|
||
MOVEQ #-1,D7 ;map cache values
|
||
CB8to1Outer
|
||
MOVE.L RGNBUFFER(A6),A2
|
||
MOVE.L SRCADDR(A6),A3 ;get source pointer
|
||
MOVE.L DSTADDR(A6),A4 ;get destptr
|
||
MOVE.L SCALETBL(A6),A5 ;get mapping table
|
||
|
||
; offset source pointer according to bit offsets
|
||
|
||
MOVE.L DSTALIGN(A6),D0 ;get shift count
|
||
MOVE.L SRCALIGN(A6),D1
|
||
ASR.L #3,D1
|
||
ADD.L D1,D0
|
||
ADD.L D0,A3 ;offset source ptr
|
||
|
||
; OK, first do the left edge
|
||
|
||
MOVE.W BUFSIZE(A6),D2 ;get the count
|
||
|
||
MOVEQ #0,D5
|
||
|
||
MOVE.L (A2)+,D1 ;get region mask
|
||
BEQ.S CB8to11st0 ;if zero, handle it
|
||
|
||
; fetch the 1st source longword and map it through the table pointed to by A5
|
||
|
||
BSR Map8to1
|
||
|
||
; plot it using the region mask
|
||
|
||
AND.L D1,D0
|
||
NOT.L D1 ;flip mask
|
||
AND.L (A4),D1
|
||
OR.L D1,D0 ;combine source and dest
|
||
MOVE.L D0,(A4)+ ;stuff it
|
||
|
||
SUBQ #1,D2
|
||
BMI.S CB8to1NextLine
|
||
|
||
; if the region runs in D4 are still valid, we can use special code to really plot super
|
||
; fast.
|
||
|
||
CB8to1Middle
|
||
TST.W D4 ;is it valid?
|
||
BNE V8to1PlotRgnRuns ;if so, go super fast
|
||
|
||
MOVEQ #-1,D4 ;validate it for next time
|
||
MOVEQ #0,D3 ;zero the run count
|
||
|
||
; see what the next region longword is. Go to three different loops depending on whether
|
||
; the region is all ones, zeros or both
|
||
|
||
MOVE.L (A2)+,D1 ;fetch next word of region mask
|
||
BEQ.S V8to1FirstZero0 ;if zero, go handle
|
||
|
||
CMP.L D6,D1 ;all one's?
|
||
BNE V8to1StartSecondRun ;if not, skip
|
||
|
||
BRA.S V8to1FirstOnes1
|
||
|
||
; here's the loop that counts and plots the first run of all ones
|
||
|
||
V8to1FirstOnes
|
||
MOVE.L (A2)+,D1
|
||
|
||
CMP.L D6,D1 ;is it still all ones?
|
||
BNE.S V8to1StartSecondRun ;if not, end the run
|
||
V8to1FirstOnes1
|
||
ADDQ.W #1,D3 ;bump the run count
|
||
|
||
BSR Map8to1
|
||
MOVE.L D0,(A4)+ ;store at destination
|
||
|
||
DBRA D2,V8to1FirstOnes ;loop until we're done
|
||
|
||
; OK, all done with this line, so bump the pointers and loop until done
|
||
|
||
CB8to1NextLine
|
||
MOVE.L DSTROW(A6),D0
|
||
ADD.L D0,DSTADDR(A6) ;bump to next line of destination
|
||
|
||
MOVE.L SRCROW(A6),D0
|
||
ADD.L D0,SRCADDR(A6) ;bump to next line of source
|
||
|
||
; bump line count and see if we're done
|
||
|
||
MOVE.W VERT(A6),D0
|
||
ADDQ #1,D0
|
||
MOVE.W D0,VERT(A6)
|
||
|
||
CMP.W MINRECT+BOTTOM(A6),D0 ;all done?
|
||
BEQ DoneStretch ;if so, use common exit
|
||
|
||
; create the region mask for the new scan line, and maintain the all ones flag
|
||
|
||
CMP.W STATEB+NEXTV(A6),D0 ;rebuild the region?
|
||
BGE.S CB8to1NewRgn ;if so, go do it
|
||
|
||
CMP.W STATEB+THISV(A6),D0 ;need to rebuild?
|
||
BLT.S CB8to1NewRgn ;if so, go do it
|
||
|
||
CMP.W STATEC+NEXTV(A6),D0 ;rebuild the region?
|
||
BGE.S CB8to1NewRgn ;if so, go do it
|
||
|
||
CMP.W STATEC+THISV(A6),D0 ;need to rebuild?
|
||
BLT.S CB8to1NewRgn ;if so, go do it
|
||
|
||
CMP.W STATEA+NEXTV(A6),D0 ;rebuild the region?
|
||
BGE.S CB8to1NewRgn ;if so, go do it
|
||
|
||
CMP.W STATEA+THISV(A6),D0 ;need to rebuild?
|
||
BGE CB8to1Outer ;if so, go do it
|
||
CB8to1NewRgn
|
||
MOVEQ #0,D4 ;invalidate region all ones flag
|
||
|
||
MOVE.L A1,-(SP)
|
||
MOVE.L SEEKMASK(A6),A0
|
||
JSR (A0) ;make new region mask
|
||
MOVE.L (SP)+,A1
|
||
|
||
; go handle the next line
|
||
|
||
BRA CB8to1Outer ;go process next line
|
||
|
||
Fin8to1Zeros
|
||
ADDQ #4,A4
|
||
BRA.S CB8to1NextLine
|
||
|
||
; here's the loop that counts and plots the first run of all zeros
|
||
|
||
V8to1FirstZero
|
||
MOVE.L (A2)+,D1
|
||
BNE.S V8to1StartSecondRun
|
||
V8to1FirstZero0
|
||
SUBQ.W #1,D3 ;decrement run count for zeros
|
||
|
||
ADD.W #32,A3
|
||
ADDQ #4,A4
|
||
DBRA D2,V8to1FirstZero
|
||
|
||
BRA.S CB8to1NextLine
|
||
|
||
; the region mask is heterogenous, so plot the word and start the second run.
|
||
|
||
V8to1StartSecondRun
|
||
SWAP D3
|
||
|
||
BSR Map8to1
|
||
|
||
AND.L D1,D0 ;mask it
|
||
NOT.L D1 ;flip mask
|
||
AND.L (A4),D1 ;combine with source
|
||
OR.L D1,D0 ;form dest longword
|
||
MOVE.L D0,(A4)+ ;deposit it
|
||
|
||
SUBQ #1,D2
|
||
BMI.S Done8to1SecondRun
|
||
|
||
; sample the region and case out for the 2nd time
|
||
|
||
MOVE.L (A2)+,D1 ;fetch next word of region mask
|
||
BEQ.S V8to1Zero0 ;if zero, go handle
|
||
|
||
CMP.L D6,D1 ;all one's?
|
||
BNE.S V8to1StartLastRun ;if not, skip
|
||
|
||
BRA.S V8to1Ones1
|
||
|
||
; here's the loop that counts and plots the second run of all ones
|
||
|
||
V8to1Ones
|
||
MOVE.L (A2)+,D1
|
||
|
||
CMP.L D6,D1 ;is it still all ones?
|
||
BNE.S V8to1StartLastRun ;if not, end the run
|
||
V8to1Ones1
|
||
ADDQ.W #1,D3 ;bump the run count
|
||
BSR Map8to1 ;fetch and map it
|
||
MOVE.L D0,(A4)+ ;store at destination
|
||
|
||
DBRA D2,V8to1Ones ;loop until we're done
|
||
Done8to1SecondRun
|
||
SWAP D3
|
||
BRA CB8to1NextLine ;all done
|
||
|
||
; here's the loop that counts the 2nd run of zeros
|
||
|
||
V8to1Zero
|
||
MOVE.L (A2)+,D1
|
||
BNE.S V8to1StartLastRun
|
||
V8to1Zero0
|
||
SUBQ.W #1,D3
|
||
|
||
ADD.W #32,A3
|
||
ADDQ #4,A4 ;bump dest reg
|
||
|
||
DBRA D2,V8to1Zero ;loop until it changes
|
||
|
||
BRA.S Done8to1SecondRun
|
||
|
||
; OK, we've accumulated two runs, so finish up the line without counting
|
||
|
||
V8to1StartLastRun
|
||
SWAP D3
|
||
|
||
TST.L D1
|
||
BEQ.S V8to1LastZero
|
||
BRA.S V8to1LastLoopA
|
||
V8to1LastLoop
|
||
MOVE.L (A2)+,D1 ;get region
|
||
BEQ.S V8to1LastZero
|
||
V8to1LastLoopA
|
||
CMP.L D6,D1
|
||
BNE.S V8to1LastHard
|
||
|
||
BSR Map8to1
|
||
|
||
MOVE.L D0,(A4)+ ;store at destination
|
||
DBRA D2,V8to1LastLoop
|
||
|
||
BRA CB8to1NextLine
|
||
V8to1LastZero
|
||
ADDQ #4,A4
|
||
ADD.W #32,A3
|
||
DBRA D2,V8to1LastLoop
|
||
BRA CB8to1NextLine
|
||
V8to1LastHard
|
||
BSR Map8to1
|
||
|
||
AND.L D1,D0 ;mask it
|
||
NOT.L D1 ;flip mask
|
||
AND.L (A4),D1 ;combine with source
|
||
OR.L D1,D0 ;form dest longword
|
||
MOVE.L D0,(A4)+ ;deposit it
|
||
|
||
DBRA D2,V8to1LastLoop
|
||
BRA CB8to1NextLine
|
||
|
||
; Here's where we have the ultra fast plotting by interpreting the 2 region runs in D3.
|
||
|
||
V8to1PlotRgnRuns
|
||
TST.W D3 ;which type of run?
|
||
BPL.S V8to1BlastPat1 ;if ones, go blast it
|
||
BEQ.S V8to1PlotRHard1 ;if zero, plot one slowly, then plot 2nd run
|
||
|
||
; it's negative, so just skip over 4 times the count
|
||
|
||
MOVE.W D3,D0
|
||
|
||
NEG.W D0 ;turn into longword count
|
||
LSL.W #2,D0 ;times 4
|
||
|
||
ADD.W D0,A2 ;skip over region
|
||
ADD.W D0,A4 ;skip over destination
|
||
LSL #3,D0 ;times 8 for source
|
||
ADD.W D0,A3 ;skip over source
|
||
|
||
ADD.W D3,D2 ;decrement count
|
||
BMI CB8to1NextLine ;if done, skip
|
||
|
||
; now handle the second run
|
||
|
||
V8to1PRRun2
|
||
LEA @0,A0 ;plot the break longword
|
||
BRA.S V8to1PlotHardCommon
|
||
@0
|
||
MOVE.L D3,D0 ;which type of run?
|
||
BPL.S V8to1BlastPat2 ;if ones, go blast it
|
||
BEQ.S V8to1PlotRHard2
|
||
|
||
; it's negative, so we can skip over like above
|
||
|
||
SWAP D0
|
||
NEG.W D0 ;turn into longword count
|
||
SUB.W D0,D2 ;decrement count
|
||
|
||
LSL.W #2,D0 ;times 4
|
||
|
||
ADD.W D0,A2 ;skip over region
|
||
ADD.W D0,A4 ;skip over destination
|
||
LSL #3,D0 ;times 8 for source
|
||
ADD.W D0,A3 ;skip over source
|
||
|
||
TST.W D2
|
||
BMI CB8to1NextLine ;if done, skip
|
||
|
||
; we've interpreted both runs, so finish up using common code
|
||
|
||
BRA.S V8to1LastLoop
|
||
|
||
; Handle blasting out the first run
|
||
|
||
V8to1BlastPat1
|
||
MOVE.W D3,D0 ;get the size
|
||
|
||
MOVE.W D0,D1
|
||
LSL #2,D1 ;times 4
|
||
ADD.W D1,A2 ;bump region ptr
|
||
SUB.W D0,D2
|
||
|
||
MOVE.W D0,D1
|
||
LEA V8to1PRRun2,A0
|
||
BRA.S V8to1BlastPatBot
|
||
|
||
; Blast out the second run
|
||
|
||
V8to1BlastPat2
|
||
SWAP D0 ;use high word for 2nd run
|
||
|
||
MOVE.W D0,D1
|
||
LSL #2,D1 ;times 4
|
||
ADD.W D1,A2 ;bump region ptr
|
||
SUB.W D0,D2
|
||
|
||
MOVE.W D0,D1
|
||
LEA V8to1LastLoop,A0
|
||
BRA.S V8to1BlastPatBot
|
||
V8to1BlastPat
|
||
BSR.S Map8to1
|
||
MOVE.L D0,(A4)+ ;store at destination
|
||
V8to1BlastPatBot
|
||
DBRA D1,V8to1BlastPat
|
||
|
||
; all done with plotting run of ones
|
||
|
||
TST.W D2
|
||
BMI CB8to1NextLine
|
||
|
||
JMP (A0)
|
||
|
||
; handle the heterogenous plots between runs
|
||
|
||
V8to1PlotRHard1
|
||
LEA V8to1PRRun2,A0
|
||
BRA.S V8to1PlotHardCommon
|
||
V8to1PlotRHard2
|
||
LEA V8to1LastLoop,A0
|
||
V8to1PlotHardCommon
|
||
MOVE.L (A2)+,D1 ;get region mask
|
||
|
||
BSR.S Map8to1
|
||
|
||
AND.L D1,D0 ;mask it
|
||
NOT.L D1 ;flip mask
|
||
AND.L (A4),D1 ;combine with source
|
||
OR.L D1,D0 ;form dest longword
|
||
MOVE.L D0,(A4)+ ;deposit it
|
||
|
||
SUBQ #1,D2 ;count it
|
||
BMI CB8to1NextLine
|
||
|
||
JMP (A0)
|
||
|
||
; Map8to1 is the routine that takes 8 longwords from the source (pointed to by A3)
|
||
; and returns the single longword result in D0.
|
||
|
||
Map8to1
|
||
; MOVEQ #0,D0 ;start dest at 0
|
||
MOVE.L (A5),D0 ;check mapping for color 0 <BAL 04Apr89>
|
||
BEQ.s @a ;if white->white, ok <d√b> 12Jul88
|
||
MOVEQ #$F,D0 ;else, its black <d√b> 12Jul88
|
||
@a ; <d√b> 12Jul88
|
||
|
||
MOVEQ #7,D7 ;8 longs to process
|
||
SUB.L A1,A1 ;set last source to 0
|
||
Map8to1Loop
|
||
MOVE.L (A3)+,D6 ;fetch from source
|
||
CMP.L A1,D6 ;same as last time?
|
||
BEQ.S Map8to1Fast ;if so, we've got the
|
||
|
||
MOVE.L D6,A1 ;remember for next time
|
||
|
||
swap d6 ;get next pixel
|
||
MOVE.B D6,D5 ;get current pixel
|
||
lsr.w #8,d6
|
||
MOVE.B 3(A5,D6.W*4),D6 ;get mapped bit
|
||
LSR.W #1,D6 ;get bit into carry
|
||
ADDX.L D0,D0 ;shift it in optimized 04Jul89 GGD
|
||
|
||
MOVE.B 3(A5,D5.W*4),D5 ;get mapped bit
|
||
LSR.W #1,D5 ;get bit into carry
|
||
ADDX.L D0,D0 ;shift it in optimized 04Jul89 GGD
|
||
|
||
swap d6 ;get next pixel
|
||
MOVE.B D6,D5 ;get current pixel
|
||
lsr.w #8,d6
|
||
MOVE.B 3(A5,D6.W*4),D6 ;get mapped bit
|
||
LSR.W #1,D6 ;get bit into carry
|
||
ADDX.L D0,D0 ;shift it in optimized 04Jul89 GGD
|
||
|
||
MOVE.B 3(A5,D5.W*4),D5 ;get mapped bit
|
||
LSR.W #1,D5 ;get bit into carry
|
||
ADDX.L D0,D0 ;shift it in optimized 04Jul89 GGD
|
||
|
||
DBRA D7,Map8to1Loop
|
||
|
||
MOVEQ #-1,D6 ;restore comparison mask
|
||
RTS
|
||
|
||
; handle the case where it was the same as the last one, so we can repeat the
|
||
; high 4 bits
|
||
|
||
Map8to1Fast
|
||
MOVEQ #$0f,D5 ; optimized 04Jul89 GGD
|
||
AND.B D0,D5 ; optimized 04Jul89 GGD
|
||
LSL.L #4,D0
|
||
OR.B D5,D0
|
||
|
||
DBRA D7,Map8to1Loop
|
||
|
||
MOVEQ #-1,D6
|
||
RTS
|
||
|
||
ENDPROC
|
||
|
||
;******************************************************************************************
|
||
;******************************************************************************************
|
||
ENDIF ;<14SEP90 SMC>
|
||
;******************************************************************************************
|
||
;******************************************************************************************
|
||
|
||
|