mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-29 07:29:15 +00:00
0ba83392d4
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
11960 lines
361 KiB
Plaintext
11960 lines
361 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>
|
||
;******************************************************************************************
|
||
;******************************************************************************************
|
||
|
||
|