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.
2643 lines
94 KiB
Plaintext
2643 lines
94 KiB
Plaintext
;
|
|
; File: BitMaps.a
|
|
;
|
|
; Copyright: © 1981-1990, 1992-1993 by Apple Computer, Inc., all rights reserved.
|
|
;
|
|
; Change History (most recent first):
|
|
;
|
|
; <SM3> 9/12/93 SAM Changed all instances of _Translate24to32 to _rTranslate24to32
|
|
; so they can conditionalized out of the build.
|
|
; <SM2> 6/11/92 stb <sm 6/9/92>stb Add patches and comments from QDciPatchROM.a
|
|
; synched-up with QDciPatchROM.a at StdBits, DevLoop, ScrollRect.
|
|
; <26> 3/20/91 KON gbm, WRKSHT#SAH-QD-056: Test to see if both src and destination
|
|
; are screen devices is backwards.
|
|
; <25> 1/25/91 KON DDG: BRC# 81599, Fix problem in SeedFill and CalcMask where area
|
|
; is not filled if bottom pixel in 1-pixel-wide line is the seed.
|
|
; <24> 1/23/91 KON dba: BRC #79398, Fix code which checks for overlapping gDevices
|
|
; in bitsDevLoop.
|
|
; <23> 12/13/90 KON If color table is NIL, put color table with special signature
|
|
; into picture. [smc]
|
|
; <22> 12/3/90 KON Color Table in pictures, take three. If color table is NIL on
|
|
; picture creation, put a minimal color table to the picture.
|
|
; [smc]
|
|
; <21> 11/28/90 gbm Fix problem in bitsdevloop where register a0 was getting
|
|
; trashed. [KON with csd]
|
|
; <20> 10/30/90 KON If color table is nil, don't save it to the picture! [SMC]
|
|
; <19> 9/17/90 BG Removed <17>. 040s are now behaving more reliably.
|
|
; <18> 8/2/90 gbm more warnings go away
|
|
; <17> 6/25/90 BG Added EclipseNOPs due to flakey 040s.
|
|
; <16> 5/31/90 KON Add new call KopyMask, which is CopyMask with a mode and rgn
|
|
; parameter.
|
|
; <15> 2/28/90 KON Added support for overlapping gDevices. If devices overlap, copy
|
|
; only to same device.
|
|
; <14> 2/3/90 BAL Fixed typo in previous.
|
|
; <13> 2/3/90 BAL Preserve the baseAddresses of screenDevices across the call to
|
|
; BitsToPix during the one screen optimization in StdBits.
|
|
; <12> 2/2/90 BAL Don't let non-zero pmversions be recorded into pictures
|
|
; <11> 2/2/90 BAL Made sure that the baseAddr passed to PutPMData and
|
|
; PutDirectPMData is 32-Bit clean. Also reinstantiated the DVB
|
|
; optimization for copybitsing from a single screen into a PICT
|
|
; since PutPMData and PutDirectPMData now operate in 32-bit
|
|
; addressing mode.
|
|
; <10> 2/1/90 KON Make register saving conventions the same as in the ROM to save
|
|
; space in the ptch.
|
|
; <9> 2/1/90 KON Made scrollrect only allocate a new region when it needs to.
|
|
; <8> 2/1/90 KON Dither mode should only be cleared for copy into old picture,
|
|
; not for copy to screen.
|
|
; <7> 1/31/90 KON Clear dither mode when drawing to an old picture by clearing bit 6 of MODE(a6).
|
|
; <6> 1/31/90 KON Flatten source pixmap to 1 bit when drawing a picture to
|
|
; an old port when a picture is being saved.
|
|
; <5> 1/30/90 DDG Fixed ScrollRect to update properly across multiple monitors.
|
|
; <4> 1/28/90 BAL Convert DitherCopy mode to copy mode when recording an old pict.
|
|
; Also Dither when flattening to 1-bit deep for old picts if the
|
|
; original transfer mode requests it.
|
|
; <3> 1/18/90 DG Fixed StdBits so that it checks for the source pixmap really
|
|
; being a bitmap before it tries to access one of the pixmap
|
|
; fields. This is right before it calls PutPMData to transfer the
|
|
; scanline to the current picture that is being recorded
|
|
; <2> 1/3/90 BAL Removed references to A5 global ScreenBits.baseAddr.
|
|
;
|
|
;¥1.6 BAL 07/14/1989 For Aurora: Final CQD
|
|
; 1.5 BAL 06/30/1989 Fixed bugs in copying from screen(s) into pictures.
|
|
;¥1.4 BAL 05/29/1989 Blasting in 32-Bit QuickDraw version 1.0 Final
|
|
;
|
|
BLANKS ON
|
|
STRING ASIS
|
|
|
|
MACHINE MC68020
|
|
|
|
;-----------------------------------------------------------
|
|
;
|
|
;
|
|
; **** *** ***** * * * **** ***
|
|
; * * * * ** ** * * * * * *
|
|
; * * * * * * * * * * * * *
|
|
; **** * * * * * * * **** ***
|
|
; * * * * * * ***** * *
|
|
; * * * * * * * * * * *
|
|
; **** *** * * * * * * ***
|
|
;
|
|
;
|
|
;
|
|
; QuickDraw Routines to operate on BitMaps.
|
|
;
|
|
;------------------------------------------------------------------
|
|
;
|
|
; MODIFICATIONS
|
|
;
|
|
; 5Jun86 EHB Modified to clear rowBytes flags
|
|
; 18Jun86 EHB Call StretchBits instead of RgnBlt
|
|
; 5Jul86 EHB Modified CopyBits to work with pixMaps
|
|
; 31Jul86 EHB Modified CopyMask to work with depths
|
|
; 9Oct86 EHB Added mask parameters to stretchbits calls
|
|
; 27Oct86 EHB Modified PackBits for bigger scanlines
|
|
; 31OCT86 EHB Rewrote ScrollRect to use CopyBits and EraseRgn
|
|
; 3Jan87 CRC pass color param to stretch
|
|
; 21Jan87 EHB Minor tweaks to devloop for copybits offscreen
|
|
; 23Jan87 CRC clear the pattern bit in case it was accidentally set by the user
|
|
; 24Jan87 EHB Bug fix in offscreen copybits when recording picture
|
|
; 04Feb87 EHB Didn't preserve enough regs when blitting from screen.
|
|
;
|
|
;---------------------------- Macintosh II ROMs -----------------------------
|
|
;
|
|
; 26May87 EHB Rolled in patch to map transfer mode if recording old picture
|
|
; 27May87 EHB Rolled in patch to set correct default device in DevLoop
|
|
; 27May87 EHB Rolled in patch to force printing through grafProc
|
|
; 17Jun88 BAL Added support for direct pixmaps to stdbits picture recording
|
|
; 19Sep88 BAL Altered StdBits to get SCREEN FLAG value from _BitsToPix;
|
|
; 08Jan89 BAL Vectorized CheckPic
|
|
;
|
|
;---------------------------- Jackson Pollock 1.0 -----------------------------
|
|
;
|
|
; 28May89 BAL Tweaked Copybits,CopyMask,DevLoop to not keep derefed port pixmap handles.
|
|
; 28May89 BAL StdBits/picture recording randomly mapped new transfer modes to old ones.
|
|
; 28May89 BAL Set up oldPic flag in stdBits earlier--not just if from screen!
|
|
|
|
StdBits PROC EXPORT
|
|
|
|
IF (&TYPE('PATCHMAC2') = 'UNDEFINED') THEN
|
|
|
|
EXPORT BitsDevLoop
|
|
IMPORT PutPicByte,PutPicWord,PutPicRgn,PutPicData,PutPicOp,SectRect,CopyMask
|
|
IMPORT StretchBits,PackBits,BitsToPix,PutPicTable,PutPMData,PortToMap,BitsToMap,SHFTTBL
|
|
|
|
ELSE
|
|
|
|
IMPORT PutBigPicData
|
|
|
|
CheckPic EQU $40820EF2
|
|
PutPicWord EQU $4082081E
|
|
PutPicRgn EQU $408208B8
|
|
PutPicData EQU $408207F0
|
|
PutPicOp EQU $4082088A
|
|
PutPicLong EQU $40820830
|
|
PutPicTable EQU $40820B74
|
|
PutPMData EQU $40820E48
|
|
|
|
SHFTTBL EQU $4081ec92
|
|
DevLoop EQU $408245ba
|
|
|
|
ENDIF
|
|
|
|
;---------------------------------------------------------------
|
|
;
|
|
; PROCEDURE StdBits(VAR srcBits: BitMap;
|
|
; VAR srcRect: Rect;
|
|
; VAR dstRect: Rect;
|
|
; mode: INTEGER;
|
|
; maskRgn: RgnHandle);
|
|
;
|
|
; as seen in QDciPatchROM.a <sm 6/9/92>stb
|
|
|
|
; SRC DEVICE RECORDS STORED ON STACK
|
|
|
|
FLAG EQU 0 ;OFFSET TO FLAG
|
|
DEV EQU FLAG+2 ;OFFSET TO DEVICE
|
|
RECT EQU DEV+4 ;OFFSET TO RECT
|
|
SIZE EQU RECT+8 ;SIZE OF RECORD
|
|
|
|
; A6 OFFSETS OF PARAMS AFTER LINK:
|
|
;
|
|
PARAMSIZE EQU 18
|
|
SRCBITS EQU PARAMSIZE+8-4 ;LONG, ADDR OF BITMAP
|
|
SRCRECT EQU SRCBITS-4 ;LONG, ADDR OF RECT
|
|
DSTRECT EQU SRCRECT-4 ;LONG, ADDR OF RECT
|
|
MODE EQU DSTRECT-2 ;WORD
|
|
MASKRGN EQU MODE-4 ;LONG, RGNHANDLE
|
|
|
|
SRCPIX EQU -(PMREC+CTREC+20) ;PIXMAP + COLOR TABLE
|
|
TEMPPIX EQU SRCPIX-PMREC ;PIXMAP
|
|
DSTBITS EQU TEMPPIX-4 ;DST BITMAP
|
|
GLOBALSRC EQU DSTBITS-8 ;GLOBAL COPY OF SRC RECT
|
|
GLOBALDST EQU GLOBALSRC-8 ;GLOBAL COPY OF DST RECT
|
|
SRCRECT1 EQU GLOBALDST-8 ;LOCAL COPY OF SRC RECT
|
|
DSTRECT1 EQU SRCRECT1-8 ;LOCAL COPY OF DST RECT (MUST FOLLOW SRCRECT1)
|
|
RECT1 EQU DSTRECT1-8 ;RESULT OF INTERSECTION
|
|
DEFSRC EQU RECT1-SIZE ;DEFAULT SRC RECORD
|
|
ENDSRC EQU DEFSRC-4 ;0 FOR TERMINATING SRC LIST
|
|
SRCDEV EQU ENDSRC-4 ;CURRENT SRC DEVICE RECORD
|
|
ENDDST EQU SRCDEV-4 ;0 FOR TERMINATING DST LIST
|
|
DSTDEV EQU ENDDST-4 ;CURRENT DST DEVICE
|
|
SRCLIST EQU DSTDEV-4 ;POINTER TO SORTED SRC RECT LIST
|
|
DSTLIST EQU SRCLIST-4 ;POINTER TO SORTED DST RECT LIST
|
|
SAVEDSP EQU DSTLIST-4 ;SAVED STACK POINTER
|
|
LASTSEED EQU SAVEDSP-4 ;LAST COLOR TABLE SEED
|
|
SAVEFG EQU LASTSEED-4 ;ORIGINAL FG COLOR
|
|
SAVEBK EQU SAVEFG-4 ;ORIGINAL BK COLOR
|
|
SAVEHILITE EQU SAVEBK-2 ;SAVED HILITE MODE FLAG
|
|
RGNA EQU SAVEHILITE-4 ;FIRST REGION FOR CLIPPING
|
|
RGNB EQU RGNA-4 ;SECOND REGION FOR CLIPPING
|
|
MASKBITS EQU RGNB-4 ;BITMAP FOR MASK
|
|
MASKRECT EQU MASKBITS-4 ;LONG, ADDR OF MASK RECT
|
|
isTmpHandle EQU MASKRECT-1 ;BYTE, FLAG SET IF temp memory used <1.5> BAL
|
|
OLDPIC EQU isTmpHandle-1 ;BYTE, FLAG SET IF OLD PICTURE <1.5> BAL
|
|
VARSIZE EQU OLDPIC ;TOTAL SIZE OF LOCALS
|
|
|
|
|
|
LINK A6,#VARSIZE ;ALLOCATE STACK FRAME
|
|
MOVEM.L D3-D7/A2-A4,-(SP) ;SAVE REGS
|
|
_CHECKPIC ;SET UP A4,A3 AND CHECK PICSAVE
|
|
BLE NOTPIC ;BRANCH IF NOT PICSAVE
|
|
|
|
;
|
|
; Set flag in OLDPIC(A6) if recording to old picture. <28May89 BAL>
|
|
;
|
|
MOVE.L PICSAVE(A3),A0 ;GET PICSAVE HANDLE <26May87 EHB>
|
|
MOVE.L (A0),A0 ;POINT TO PICSAVE RECORD <26May87 EHB>
|
|
CMP #PICTVERSION,PICVERSION(A0) ;IS IT AN OLD PICTURE? <26May87 EHB>
|
|
SEQ OLDPIC(A6) ;yes, set flag <26May87 EHB>
|
|
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; CONVERT SRCBITS TO A PIXMAP
|
|
; (A5 must contain global ptr)
|
|
;
|
|
MOVE.L SRCBITS(A6),A1 ;GET POINTER TO SRCBITS
|
|
TST ROWBYTES(A1) ;IS IT A BITMAP OR A PIXMAP
|
|
SPL D7 ;SET FLAG IF BITMAP
|
|
move d7,d6 ;Bits to pix clears pixmap/bitmap bit <30Jan90 KON>
|
|
or.b oldPic(a6),d7 ;d7=oldPic|bitMap <28May89 BAL>
|
|
LEA SRCPIX(A6),A2 ;COPY INTO SRCPIX
|
|
_BitsToPix ;BITMAP -> PIXMAP; RETURNS SCREEN FLAG IN D2 <BAL 19Sep88>
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; GET SHIFT AMOUNT FOR SRC DEPTH INTO D3
|
|
;
|
|
LEA SHFTTBL,A0 ;TO CONVERT DEPTH TO SHIFT
|
|
MOVE SRCPIX+PIXELSIZE(A6),D0 ;GET SRC PIXEL SIZE
|
|
MOVEQ #0,D3 ;DEFAULT SHIFT = 0
|
|
MOVE.B 0(A0,D0),D3 ;GET SHIFT AMOUNT
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; IF SRC IS THE SCREEN, THEN USE COPYBITS TO COPY THE SRC TO AN OFFSCREEN BITMAP
|
|
; THIS ENSURES THAT SRC IS CONTIGUOUS, ALL ONE DEPTH, ETC.
|
|
;
|
|
CLR.L RECT1(A6) ;CLEAR HANDLE TO SAVED BITS
|
|
TST.B D2 ;IS SRC THE SCREEN? <BAL 19Sep88>
|
|
Bne.s doScreen ;Yes, convert it <KON 30Jan90>
|
|
tst.b d6 ;is source a bitmap? <KON 30Jan90>
|
|
bne notScrn ;YES, don't convert <KON 30Jan90>
|
|
tst.b OldPic(a6) ;is dst old port? <KON 30Jan90>
|
|
beq notScrn ;No, then don't convert source <KON 30Jan90>
|
|
bra doConvert
|
|
|
|
doScreen
|
|
|
|
IF 1 THEN ;Can't optimize if screen needs 32-bit addressing
|
|
|
|
|
|
;<dÃb>
|
|
;----------------------------------------------------
|
|
; If the source is only one screen, copy straight across. (No need for
|
|
; temp offscreen pixmap.)
|
|
TST.B D7 ;Unless, that is, the dst is an OLD port,
|
|
BNE MultiMapSrc ;which'll require flattening.
|
|
|
|
MOVE.L SRCRECT(A6),A0 ;POINT TO SRC RECTANGLE
|
|
LEA SRCRECT1(A6),A1 ;POINT TO PLACE FOR COPY
|
|
MOVE.L (A0)+,(A1)+ ;COPY TOPLEFT
|
|
MOVE.L (A0)+,(A1)+ ;COPY BOTRIGHT
|
|
|
|
PEA SRCRECT1(A6) ;PUSH COPY OF SRCRECT
|
|
NEG.W D1 ;left (D1=topLeft from BitsToPix)
|
|
SWAP D1
|
|
NEG.W D1 ;top
|
|
SWAP D1
|
|
MOVE.L D1,-(SP)
|
|
_OffsetRect ;SRCRECT1 is the global srcrect. (it used to happen later on)
|
|
|
|
CLR D4 ;How many devices does src intersect? <pb535a>
|
|
MOVE.L DeviceList,A2 ;A0=handle to head of device list
|
|
@gdrt
|
|
MOVE.L (A2),A2 ;A2->device
|
|
TST GDFLAGS(A2) ;IS IT ACTIVE?
|
|
BPL.S @nextgd ;=>NO, SKIP TO NEXT
|
|
|
|
SUBQ #2,SP ;Boolean result
|
|
PEA gdRect(A2) ;device global rect
|
|
PEA SRCRECT1(A6) ;source bitmap rect in global
|
|
PEA DSTRECT1(A6) ;put the intersection here(throwaway).
|
|
_SectRect
|
|
TST.B (SP)+ ;Any intersection at all?
|
|
BEQ.S @nextgd ;=>No, go do the next gd.
|
|
ADDQ #1,D4 ;=>Yes, count it. <pb535a>
|
|
MOVE.L A2,DSTDEV(A6) ;stash this device ptr here (as SRC)
|
|
|
|
@nextgd
|
|
MOVE.L gdNextGD(A2),D0
|
|
MOVE.L D0,A2
|
|
BNE.S @gdrt
|
|
|
|
CMP #1,D4 ;If the srcrect intersects more than <pb535a>
|
|
BGT.S MultiMapSrc ;one gdevice, do offscreen map.
|
|
|
|
MOVE.L DSTDEV(A6),A1 ;A1->the single source gdevice
|
|
MOVE.L gdPMap(A1),A1 ;A1=handle to pixmap
|
|
MOVE.L (A1),A1 ;A1->pixmap
|
|
move.l baseAddr(a1),d4 ;save un-stripped screen base in d4
|
|
LEA SRCPIX(A6),A2 ;A2->our local srcpix record
|
|
_BitsToPix ;BITMAP -> PIXMAP; RETURNS SCREEN FLAG IN D2
|
|
|
|
move.l d4,SRCPIX+baseAddr(a6) ;prevent stripping on alternate screens
|
|
PEA SRCPIX+bounds(A6) ;Fix bounds for SRCPIX
|
|
MOVE.L SRCBITS(A6),A0 ;by offsetting by original source bounds
|
|
MOVE.L bounds+topLeft(A0),-(SP)
|
|
_OffsetRect
|
|
|
|
LEA SHFTTBL,A0 ;TO CONVERT DEPTH TO SHIFT
|
|
MOVE SRCPIX+PIXELSIZE(A6),D0 ;GET SRC PIXEL SIZE (redo for different gdevice)
|
|
MOVEQ #0,D3 ;DEFAULT SHIFT = 0
|
|
MOVE.B 0(A0,D0),D3 ;GET SHIFT AMOUNT (redo for different gdevice)
|
|
BRA NOTSCRN ;And pretend source isn't a screen.
|
|
|
|
MultiMapSrc ;2 or more active gdevices intersected
|
|
|
|
|
|
ENDIF
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; OFFSET SRCRECT TO GLOBAL COORDINATES AND GET SCREEN DEPTH
|
|
;
|
|
doConvert
|
|
MOVE.L SRCRECT(A6),A0 ;POINT TO SRC RECTANGLE
|
|
LEA SRCRECT1(A6),A1 ;POINT TO PLACE FOR COPY
|
|
MOVE.L (A0)+,(A1)+ ;COPY TOPLEFT
|
|
MOVE.L (A0)+,(A1)+ ;COPY BOTRIGHT
|
|
|
|
PEA SRCRECT1(A6) ;PUSH COPY OF SRCRECT
|
|
MOVE.L SRCBITS(A6),A0 ;GET SRCBITS
|
|
MOVE.L BOUNDS(A0),D0 ;GET BOUNDS.TOPLEFT
|
|
NEG D0 ;NEGATE BOUNDS.LEFT
|
|
SWAP D0 ;GET BOUNDS.TOP
|
|
NEG D0 ;NEGATE BOUNDS.TOP
|
|
SWAP D0 ;GET BOUNDS.TOPLEFT
|
|
MOVE.L D0,-(SP) ;PUSH BOUNDS.TOPLEFT
|
|
_OFFSETRECT ;OFFSET RECT TO GLOBAL COORDINATES
|
|
|
|
CLR.L -(SP) ;MAKE ROOM FOR HANDLE
|
|
PEA SRCRECT1(A6) ;POINT TO GLOBAL RECT
|
|
_GETMAXDEVICE ;GET DEEPEST SCREEN DEVICE
|
|
MOVE.L (SP)+,D0 ;POP DEVICE HANDLE
|
|
BEQ BITSOK ;=>NOT ON SCREEN, DON'T RECORD
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; Set up off screen GDevice for the Copy
|
|
; SET TEMP PIXMAP USING INFO FROM DEEPEST SCREEN
|
|
;
|
|
move.l theGDevice,-(sp) ;save current GDevice <BAL 23Jan89>
|
|
move.l d0,theGDevice ;set up offscreen GDevice <BAL 23Jan89>
|
|
|
|
MOVE.L D0,A0 ;GET HANDLE TO DEEPEST DEVICE
|
|
MOVE.L (A0),A0 ;POINT TO DEEPEST DEVICE
|
|
MOVE.L GDPMAP(A0),A0 ;GET HANDLE TO ITS PIXMAP
|
|
MOVE.L (A0),A0 ;POINT TO PIXMAP
|
|
LEA TEMPPIX(A6),A1 ;POINT TO DST
|
|
MOVEQ #(PMREC/2)-1,D0 ;GET NUMBER OF WORDS IN RECORD
|
|
@0 MOVE (A0)+,(A1)+ ;COPY A WORD
|
|
DBRA D0,@0 ;=>REPEAT UNTIL DONE
|
|
|
|
clr.w TEMPPIX+PMVERSION(A6) ;clear 32bit addressing flag <BAL 15Dec88>
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; SET TEMPPIX.BOUNDS TO SRCRECT
|
|
;
|
|
MOVE.L SRCRECT(A6),A0 ;POINT AT SRC RECTANGLE
|
|
LEA TEMPPIX+BOUNDS(A6),A1 ;POINT AT DST BOUNDS
|
|
MOVE.L (A0)+,D1 ;GET TOPLEFT
|
|
MOVE.L D1,(A1)+ ;COPY TOPLEFT
|
|
MOVE.L (A0)+,D0 ;GET BOTRIGHT
|
|
MOVE.L D0,(A1)+ ;COPY BOTRIGHT
|
|
|
|
MOVE D0,D5 ;GET A COPY OF RIGHT
|
|
SUB D1,D5 ;GET WIDTH IN PIXELS
|
|
EXT.L D5 ;MAKE IT LONG
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; FLAG IN D7 is set IF RECORDING A BITMAP or recording to old picture.
|
|
; GET DEPTH-SHIFT FOR PIXMAP IN D3 AND ROWBYTES FOR PICTURE IN D5.
|
|
; FORCE DEPTH TO 1 IF SRC IS BITMAP OR IF RECORDING OLD PICTURE.
|
|
;
|
|
MOVEQ #0,D3 ;DEFAULT SHIFT = 0
|
|
|
|
TST.B D7 ;IS IT A BITMAP? <BAL 28May89>
|
|
BNE.S ITSBITS ;=>YES, GO CALCULATE ROWBYTES
|
|
|
|
LEA SHFTTBL,A0 ;TO CONVERT DEPTH TO SHIFT
|
|
MOVE TEMPPIX+PIXELSIZE(A6),D2 ;GET BITS PER PIXEL
|
|
MOVE.B 0(A0,D2),D3 ;GET SHIFT AMOUNT
|
|
|
|
ITSBITS LSL.L D3,D5 ;CONVERT PIXELS TO BITS
|
|
MOVEQ #15,D2 ;GET 15
|
|
ADD.L D2,D5 ;ROUND UP TO NEAREST WORD BOUNDARY
|
|
ASR.L #4,D5 ;DIV BY 16
|
|
BLE BITSOK ;IGNORE IF NEWROW <= 0
|
|
ADD D5,D5 ;DOUBLE FOR NEW ROWBYTES
|
|
MOVE D5,TEMPPIX+ROWBYTES(A6) ;COPY ROWBYTES
|
|
MOVE D5,D4 ;OLD ROWBYTES := NEW ROWBYTES
|
|
TST.B D7 ;IS DST A PIXMAP?
|
|
BNE.S NOFLAG ;=>NO, DON'T NEED FLAG
|
|
OR #$8000,TEMPPIX+ROWBYTES(A6) ;SET PIXMAP FLAG
|
|
|
|
NOFLAG
|
|
;----------------------------------------------------
|
|
;
|
|
; ALLOCATE MEMORY FOR TEMP PIXMAP AND COPY TO IT
|
|
;
|
|
SWAP D1 ;GET LEFTTOP
|
|
SWAP D0 ;GET RIGHTBOT
|
|
SUB D1,D0 ;GET HEIGHT
|
|
MULU D5,D0 ;GET DATA SIZE IN BYTES
|
|
move.l d0,d5 ;copy size in d5 <1.5> BAL
|
|
clr.b isTmpHandle(a6) ;clear temp memory flag <1.5> BAL
|
|
_NEWHANDLE ;ALLOCATE MEMORY FOR BITMAP
|
|
beq.s @gotMem ;go use it <1.5> BAL
|
|
|
|
st isTmpHandle(a6) ;set temp memory flag <1.5> BAL
|
|
move.l d5,d0 ;request size <1.5> BAL
|
|
_NewTempHandle ;ask for it <1.5> BAL
|
|
cmp.l d5,d0 ;did we get it all? <1.5> BAL
|
|
bge.s @gotMem ;yes, go use it <1.5> BAL
|
|
|
|
move.l (sp)+,theGDevice ;restore the current GDevice <1.5> BAL
|
|
move.w #-143,qdErr ;return something <1.5> BAL
|
|
bra BITSOK ;=>ERROR, JUST TRY TO DRAW <1.5> BAL
|
|
|
|
@gotMem MOVE.L A0,RECT1(A6) ;SAVE FOR DISPOSE
|
|
_HLOCK ;LOCK THE HANDLE
|
|
MOVE.L (A0),d0 ;POINT AT THE STORAGE
|
|
_rTranslate24To32 ;map address in D0 <02Feb90 BAL>
|
|
MOVE.L d0,TEMPPIX+BASEADDR(A6) ;AND SET BASE ADDRESS OF TEMP
|
|
|
|
MOVE.L PICSAVE(A3),-(SP) ;SAVE PICSAVE ON THE STACK
|
|
CLR.L PICSAVE(A3) ;DISABLE PICTURE FOR COPY!
|
|
|
|
SUBQ #6,SP ;MAKE ROOM FOR RGBCOLOR
|
|
MOVE.L SP,-(SP) ;POINT TO VAR RGBCOLOR
|
|
_GETFORECOLOR ;SAVE THE RGBFORECOLOR
|
|
MOVEQ #BLACKCOLOR,D0 ;GET A LITTLE BLACK
|
|
MOVE.L D0,-(SP) ;AND SMACK IT ON THE STACK
|
|
_FORECOLOR ;SO OUR COPY'S BACK IN WHACK
|
|
|
|
PEA SRCPIX(A6) ;PUSH TRIMMED SRC PIXMAP
|
|
PEA TEMPPIX(A6) ;PUSH DST PIXMAP
|
|
MOVE.L SRCRECT(A6),-(SP) ;PUSH SRCRECT
|
|
MOVE.L (SP),-(SP) ;DSTRECT = SRCRECT
|
|
CLR -(SP) ;MODE = SRC COPY
|
|
btst.b #6,Mode+1(a6) ;dither? <KON 30Jan90>
|
|
beq.s @NoDither ; <KON 30Jan90>
|
|
move.w #$40,(sp) ;set dither mode <KON 30Jan90>
|
|
@NoDither
|
|
CLR.L -(SP) ;NO MASKRGN
|
|
_COPYBITS ;COPY THE PIXMAP
|
|
|
|
MOVE.L SP,-(SP) ;POINT AT FORECOLOR
|
|
_RGBFORECOLOR ;RESTORE IT
|
|
ADDQ #6,SP ;STRIP FORECOLOR
|
|
MOVE.L (SP)+,PICSAVE(A3) ;RESTORE PICTURE STATE
|
|
|
|
move.l (sp)+,theGDevice ;restore the current GDevice <BAL 23Jan89>
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; COPY TEMPPIX INTO SRCPIX AND USE AS NEW SRC PIXMAP
|
|
;
|
|
LEA TEMPPIX(A6),A0 ;POINT TO TEMPPIX
|
|
LEA SRCPIX(A6),A1 ;POINT TO SRCPIX
|
|
MOVEQ #(PMREC/2)-1,D0 ;GET NUMBER OF WORDS IN PIXMAP
|
|
@0 MOVE (A0)+,(A1)+ ;COPY A WORD
|
|
DBRA D0,@0 ;=>REPEAT UNTIL DONE
|
|
|
|
|
|
NOTSCRN
|
|
;----------------------------------------------------
|
|
;
|
|
; TRIM LOCAL COPY OF PIXMAP
|
|
;
|
|
|
|
LEA SRCPIX(A6),A1 ;POINT TO PIXMAP
|
|
MOVE.L BASEADDR(A1),A3 ;GET BASEADDR
|
|
MOVE ROWBYTES(A1),D4 ;GET OLD ROWBYTES
|
|
AND #nuRBMask,D4 ;CLEAR FLAG BITS
|
|
MOVE.L SRCRECT(A6),A0 ;POINT TO SRCRECT
|
|
MOVE TOP(A0),D0 ;GET SRCRECT.TOP
|
|
SUB BOUNDS+TOP(A1),D0 ;SKIPTOP:=SRCRECT.TOP-BOUNDS.TOP
|
|
BLE.S TOPOK ;CONTINUE IF SKIPTOP NEG
|
|
ADD D0,BOUNDS+TOP(A1) ;NEWTOP := SRCRECT TOP
|
|
MULU D4,D0 ;CALC VERT OFFSET
|
|
ADD.L D0,A3 ;ADJUST BASEADDR
|
|
|
|
TOPOK MOVE BOTTOM(A0),D0 ;GET SRCRECT.BOTTOM
|
|
CMP BOUNDS+BOTTOM(A1),D0 ;IS SRCRECT BOT < BOUNDS BOT ?
|
|
BGE.S BOTOK ;NO, CONTINUE
|
|
MOVE D0,BOUNDS+BOTTOM(A1) ;YES, TRIM BOUNDS BOTTOM
|
|
|
|
BOTOK MOVE LEFT(A0),D0 ;GET SRCRECT.LEFT
|
|
SUB BOUNDS+LEFT(A1),D0 ;CALC SKIPLEFT
|
|
BLE.S LEFTOK ;CONTINUE IF SKIPLEFT NEG
|
|
EXT.L D0 ;MAKE IT LONG
|
|
LSL.L D3,D0 ;CONVERT PIXELS TO BITS
|
|
ASR.L #3,D0 ;DIV BY 8 FOR SKIP BYTES
|
|
ADD.L D0,A3 ;OFFSET BASEADDR HORIZ
|
|
LSL.L #3,D0 ;BYTES TIMES 8 FOR BITS
|
|
ASR.L D3,D0 ;CONVERT BITS TO PIXELS
|
|
ADD D0,BOUNDS+LEFT(A1) ;ADD DOTS TO BOUNDS.LEFT
|
|
|
|
LEFTOK MOVE RIGHT(A0),D0 ;GET SRCRECT.RIGHT
|
|
SUB BOUNDS+LEFT(A1),D0 ;CONVERT TO GLOBAL
|
|
EXT.L D0 ;MAKE IT LONG
|
|
ADDQ.L #7,D0 ;ROUND UP
|
|
LSL.L D3,D0 ;CONVERT PIXELS TO BITS
|
|
AND #$FFF8,D0 ;TRUNC TO BYTE BOUNDARY
|
|
ASR.L D3,D0 ;CONVERT BITS TO PIXELS
|
|
ADD BOUNDS+LEFT(A1),D0 ;RETURN TO LOCAL
|
|
CMP BOUNDS+RIGHT(A1),D0 ;IS RESULT < BOUNDS.RIGHT ?
|
|
BGE.S RIGHTOK ;NO, CONTINUE
|
|
MOVE D0,BOUNDS+RIGHT(A1) ;YES, TRIM RIGHT
|
|
RIGHTOK
|
|
;
|
|
; CALC NEW ROWBYTES AFTER TRIMMING
|
|
;
|
|
MOVE BOUNDS+RIGHT(A1),D5 ;GET TRIMMED RIGHT
|
|
SUB BOUNDS+LEFT(A1),D5 ;CALC WIDTH IN PIXELS
|
|
EXT.L D5 ;MAKE IT LONG
|
|
LSL.L D3,D5 ;CONVERT PIXELS TO BITS
|
|
MOVEQ #15,D0 ;GET 15
|
|
ADD.L D0,D5 ;ROUND UP TO NEAREST WORD BOUNDARY
|
|
ASR.L #4,D5 ;DIV BY 16
|
|
BLE BITSOK ;IGNORE IF NEWROW <= 0
|
|
ADD D5,D5 ;DOUBLE FOR NEW ROWBYTES
|
|
MOVE D5,ROWBYTES(A1) ;COPY ROWBYTES
|
|
OR #$8000,ROWBYTES(A1) ;SET PIXMAP FLAG
|
|
|
|
clr.w SRCPIX+PMVERSION(A6) ;clear 32bit addressing flag <BAL 15Dec88>
|
|
|
|
;----------------------------------------------------
|
|
;
|
|
; PUT THE BITMAP TO THE PICTURE
|
|
;
|
|
MOVEQ #8,D6 ;GET A USEFUL NUMBER
|
|
MOVE #opBitsRect,-(SP) ;PUSH OPCODE=BITSRECT
|
|
TST.L MASKRGN(A6) ;IS MASKRGN NIL ?
|
|
BEQ.S NOTRGN ;YES, CONTINUE
|
|
ADD #1,(SP) ;REPLACE OPCODE=BITSRGN (IE. $91)
|
|
;FIXED BUG 12/3/83, RP
|
|
NOTRGN CMP D6,D5 ;IS NEWROW < 8 ?
|
|
Bge.s PACK ;YES, DONT BITPACK
|
|
move #1,SRCPIX+PACKTYPE(A6) ;replace with "UnPacked" packType
|
|
bra.s NoPack
|
|
PACK ADD #8,(SP) ;SET BIT 3 FOR BITPACK
|
|
NoPack TST.B D7 ;New Picture?
|
|
BNE.S OPOK ;=>NO, can't be direct data
|
|
|
|
clr.w SrcPix+pmVersion(a6) ;only let version zero be stored in pict.
|
|
|
|
MOVE.W SRCPIX+pixelType(A6),D2 ;get pixelType in d2 for later %%%
|
|
cmp #16,D2 ;is it chunky direct? %%%
|
|
bne.s OPOK ;NO, OPCODE IS OK %%%
|
|
OR.W #$A,(SP) ;YES, USE $9A AND $9B %%%
|
|
bsr PutPicOp ;PUT OPCODE TO THEPIC %%%
|
|
MOVE.L #$0FF,-(SP) ;PUT HACK TO PIC %%%
|
|
bsr PutPicLong
|
|
|
|
lea srcPix+packType(a6),a0 ;point at packType
|
|
CMP #1,(a0) ;PACKING? <BAL 11Jul88>
|
|
beq.s @PackOK ;no, don't need to adjust packType <BAL 11Jul88>
|
|
|
|
CMP #16,SRCPIX+PIXELSIZE(A6) ;16 bit/pixel? <BAL 15Dec88>
|
|
bne.s @pack32 ;no, check 32 bit/pixel packing types <BAL 15Dec88>
|
|
move #3,(a0) ;use only supported type
|
|
bra.s @PackOK
|
|
|
|
@pack32 cmp #2,(a0) ;drop pad byte only? <BAL 11Jul88>
|
|
beq.s @PackOK ;yes, don't need to adjust packType <BAL 11Jul88>
|
|
move #4,(a0) ;replace with only remaining supported packType <BAL 15Dec88>
|
|
|
|
|
|
@PackOK MOVE SRCPIX+BOUNDS+BOTTOM(A6),D1 ; %%%
|
|
SUB SRCPIX+BOUNDS+TOP(A6),D1 ;HEIGHT := BOUNDS BOT - TOP %%%
|
|
MULU D1,D5 ;SAVE PMDATA SIZE IN D5 %%%
|
|
|
|
PEA SRCPIX+ROWBYTES(A6) ;PUSH ADDR OF PIXMAP %%%
|
|
MOVE #PMREC-4,-(SP) ;PUSH SIZE OF PIXMAP (-BASEADDR)
|
|
bsr PutPicData ;PUT PIXMAP TO THEPIC %%%
|
|
BRA.S NOTABLE ;SKIP CLUT STUFF %%%
|
|
|
|
ARITHMODE ;avg addPin addOver subPin trans max subOver min
|
|
DC.B srcCopy, srcBic, srcXor, srcOr, srcOr, srcBic, srcXor, srcOr
|
|
|
|
|
|
OPOK bsr PutPicOp ;PUT OPCODE TO THEPIC
|
|
|
|
MOVEQ #PMREC-4,D0 ;GET SIZE OF PIXMAP (-BASEADDR)
|
|
TST.B D7 ;ARE WE RECORDING A BITMAP?
|
|
beq.s DOPM ;=>SRC IS BitMap, branch
|
|
|
|
MOVEQ #BITMAPREC-4,D0 ;GET SIZE OF BITMAP (-BASEADDR)
|
|
AND #nuRBMask,SRCPIX+ROWBYTES(A6) ;ELSE BITMAP, CLEAR FLAGS
|
|
DOPM PEA SRCPIX+ROWBYTES(A6) ;PUSH ADDR OF BITMAP/PIXMAP
|
|
MOVE D0,-(SP) ;PUSH BYTECOUNT
|
|
bsr PutPicData ;PUT BITMAP/PIXMAP TO THEPIC
|
|
|
|
; IF IT'S A PIXMAP, PUT THE COLOR TABLE TO THE PICTURE
|
|
|
|
TST.B D7 ;IS IT A PIXMAP?
|
|
BNE.S NOTABLE ;=>NO, DON'T DO TABLE
|
|
MOVE.L SRCPIX+PMTABLE(A6),d0 ;get CTabHandle
|
|
beq.s PutMinimalTable ;put minimal table if NIL <20> <KON 30OCT90>
|
|
move.l d0, -(SP) ;PUSH CTABHANDLE <20> <KON 30OCT90>
|
|
bsr PutPicTable ;ADD TABLE TO THEPIC
|
|
bra.s NoTable
|
|
;
|
|
; The following is a minimal color table. It is put to the picture if a PixMap has
|
|
; a NIL color table. <KON 29NOV90>
|
|
;
|
|
|
|
MinimalTable
|
|
dc.l 0 ;ctSeed
|
|
dc.w 0 ;flags
|
|
dc.w 0 ;0-based count of entries -> 1 entry
|
|
dc.w cTabSignature,0,0,0 ;ColorSpec for 1 entry with signature
|
|
|
|
MinTableSize EQU 16
|
|
|
|
;
|
|
; Put the minimal color table to the picture
|
|
;
|
|
PutMinimalTable
|
|
|
|
pea MinimalTable ;PUSH DATAPTR <KON 29NOV90>
|
|
move #MinTableSize,-(sp) ;GET SIZE IN ENTRIES <KON 29NOV90>
|
|
jsr PutPicData ;ADD TO THEPIC <KON 29NOV90>
|
|
|
|
NOTABLE MOVE.L SRCRECT(A6),-(SP)
|
|
MOVE D6,-(SP)
|
|
bsr PutPicData ;PUT SRCRECT
|
|
MOVE.L DSTRECT(A6),-(SP)
|
|
MOVE D6,-(SP)
|
|
bsr PutPicData ;PUT DSTRECT
|
|
|
|
MOVE MODE(A6),D0 ;get desired mode <26May87 EHB>
|
|
TST.B OLDPIC(A6) ;is it an old picture? <26May87 EHB>
|
|
BEQ.S @ModeOK ;=>no, mode is fine <26May87 EHB>
|
|
bclr #6,d0 ;don't record ditherCopy in old Picts
|
|
;since the laserWriter driver inverts it.
|
|
BTST #5,D0 ;an arithmetic mode? <26May87 EHB>
|
|
BEQ.S @ModeOK ;=>no, mode is fine <26May87 EHB>
|
|
AND #$07,D0 ;else strip to low 3 bits <26May87 EHB>
|
|
MOVE.B ARITHMODE(D0),D0 ;and remap it <26May87 EHB>
|
|
@ModeOK MOVE D0,-(SP) ;push mode <26May87 EHB>
|
|
bsr PutPicWord ;PUT MODE
|
|
|
|
TST.L MASKRGN(A6) ;IS MASKRGN NIL ?
|
|
BEQ.S NOMASK ;YES, SKIP IT
|
|
MOVE.L MASKRGN(A6),-(SP) ;NO, PUSH MASKRGN
|
|
bsr PutPicRgn ;PUT MASKRGN TO THEPIC
|
|
|
|
NOMASK tst.b d7 ;is it a pixmap ? If not, then <17Jan89 DDG>
|
|
bne.s @NOTD ;don't check pixmap fields ! <17Jan89 DDG>
|
|
cmp #16,SRCPIX+pixelType(A6) ;is it chunky direct? %%%
|
|
bne.s @NOTD ;NO, CALL PACKING STUFF %%%
|
|
LEA SRCPIX(A6),A0 ;GET PIXMAP POINTER
|
|
MOVE.L A0,-(SP) ;PUSH PIXMAP POINTER
|
|
MOVE.L A3,-(SP) ;PUSH ADJUSTED BASEADDR
|
|
MOVE D4,-(SP) ;PUSH OLD ROWBYTES
|
|
bsr PutDirectPMData ;AND PUT DATA TO PICTURE
|
|
BRA.S @DONE
|
|
|
|
@NOTD LEA SRCPIX(A6),A0 ;GET PIXMAP POINTER
|
|
MOVE.L A0,-(SP) ;PUSH PIXMAP POINTER
|
|
MOVE.L A3,-(SP) ;PUSH ADJUSTED BASEADDR
|
|
MOVE D4,-(SP) ;PUSH OLD ROWBYTES
|
|
bsr PutPMData ;AND PUT DATA TO PICTURE
|
|
|
|
@DONE MOVE.L RECT1(A6),D0 ;DID WE ALLOCATE DATA FOR A PIXMAP?
|
|
BEQ.S BITSOK ;=>NOPE, DON'T NEED TO DISPOSE
|
|
MOVE.L D0,A0 ;ELSE GET HANDLE
|
|
tst.b isTmpHandle(a6) ;is it from temp memory? <1.5> BAL
|
|
beq.s @notTmp ;no, dispose as usual <1.5> BAL
|
|
_DisposeTempBuffer ;yes, dispose as temp memory <1.5> BAL
|
|
bra.s BITSOK ; <1.5> BAL
|
|
|
|
@notTmp _DISPOSHANDLE ;AND DISPOSE OF IT
|
|
|
|
BITSOK MOVE.L THEPORT(A4),A3 ;RESTORE THEPORT
|
|
|
|
; CALL HEAVY-DUTY LOOP TO DRAW TO ALL DEVICES
|
|
|
|
NOTPIC TST PNVIS(A3) ;IS PNVIS >= 0 ?
|
|
BLT.S GOHOME ;NO, QUIT
|
|
LEA PORTBITS(A3),A0 ;GET DST BITMAP
|
|
MOVE.L A0,DSTBITS(A6) ;AND PLACE IN STACK FRAME
|
|
MOVE.L VISRGN(A3),RGNA(A6) ;PASS VISRGN
|
|
MOVE.L CLIPRGN(A3),RGNB(A6) ;AND CLIPRGN
|
|
CLR.L MASKBITS(A6) ;NO MASK BITMAP
|
|
CLR.L MASKRECT(A6) ;NO MASK RECTANGLE
|
|
_BitsDevLoop ;DRAW TO ALL DEVICES
|
|
|
|
GOHOME MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE REGS
|
|
UNLINK PARAMSIZE,'STDBITS '
|
|
|
|
|
|
BitsDevLoop
|
|
;---------------------------------------------------------------
|
|
;
|
|
; PROCEDURE DevLoop;
|
|
;
|
|
; On Entry: A3: GrafPort
|
|
; A6: StdBits' stack frame
|
|
; DSTBITS(A6): Destination bitmap/pixmap
|
|
; RGNA(A6): First region to clip to
|
|
; RGNB(A6): Second region to clip to
|
|
; MASKBITS(A6): Mask's bitmap
|
|
; MASKRECT(A6): Mask's rectangle
|
|
;
|
|
; D3-D7/A2-A4 have been preserved and can be used.
|
|
|
|
; from QDciPatchROM.a verbatim <sm 6/9/92>stb
|
|
|
|
; IF THERE IS ONLY ONE SCREEN DEVICE, THEN DO IT FAST
|
|
|
|
MOVE.L DEVICELIST,A0 ;GET HEAD OF DEVICE LIST
|
|
MOVE.L (A0),A0 ;POINT TO DEVICE
|
|
MOVE.L GDNEXTGD(A0),D0 ;CHECK NEXT DEVICE
|
|
BNE.S MANYVIDI ;=>GO DO MANY DEVICES
|
|
|
|
;ciBitsDevTop
|
|
MOVE.L SRCBITS(A6),-(SP) ;PUSH SRCBITS
|
|
MOVE.L MASKBITS(A6),-(SP) ;PUSH MASKBITS
|
|
MOVE.L DSTBITS(A6),-(SP) ;PUSH DSTBITS
|
|
MOVE.L SRCRECT(A6),-(SP) ;PUSH SRCRECT
|
|
MOVE.L MASKRECT(A6),-(SP) ;PUSH MASKRECT
|
|
MOVE.L DSTRECT(A6),-(SP) ;PUSH DSTRECT
|
|
MOVE MODE(A6),-(SP) ;PUSH MODE
|
|
AND #$FFF7,(SP) ;clear the pattern bit in case the user set it
|
|
CLR.L -(SP) ;NO PATTERN NEEDED
|
|
MOVE.L RGNA(A6),-(SP) ;PUSH FIRST REGION
|
|
MOVE.L RGNB(A6),-(SP) ;PUSH SECOND REGION
|
|
MOVE.L MASKRGN(A6),-(SP) ;PUSH MASKRGN
|
|
BNE.S MASKOK1 ;WAS IT NIL ?
|
|
MOVE.L GRAFGLOBALS(A5),A0 ;GET GRAFGLOBALS
|
|
MOVE.L WIDEOPEN(A0),(SP) ;YES, REPLACE WITH WIDEOPEN
|
|
MASKOK1 CLR -(SP) ;pass multicolor flag false
|
|
_STRETCHBITS ;CALL STRETCHBITS
|
|
RTS
|
|
|
|
MANYVIDI
|
|
|
|
; INITIALIZE THE DEFAULT DESTINATION DEVICE LIST
|
|
; THE LIST CONSISTS OF ONE DEVICE HANDLE FOLLOWED BY A 0
|
|
|
|
MOVE.L SP,SAVEDSP(A6) ;SAVE STACK POINTER
|
|
LEA DSTDEV(A6),A1 ;POINT TO START OF DEFAULT DST LIST
|
|
MOVE.L A1,DSTLIST(A6) ;SAVE POINTER TO DEFAULT DST LIST
|
|
MOVE.L THEGDEVICE,A0 ;GET DEFAULT DEVICE <07Jul88 BAL>
|
|
MOVE.L A0,(A1)+ ;DSTDEV := DEFAULT SCREEN DEVICE
|
|
CLR.L (A1)+ ;CLEAR FLAG AT END OF DST LIST
|
|
|
|
; INITIALIZE THE DEFAULT SRC DEVICE LIST
|
|
; THE LIST CONSISTS OF ONE RECORD POINTER FOLLOWED BY A 0
|
|
|
|
MOVE.L A1,SRCLIST(A6) ;SAVE POINTER TO DEFAULT SRC RECORD
|
|
LEA DEFSRC(A6),A2 ;POINT TO DEFAULT SRC RECORD
|
|
MOVE.L A2,(A1)+ ;INSTALL RECORD POINTER INTO LIST
|
|
CLR.L (A1)+ ;CLEAR FLAG AT END OF SRC LIST
|
|
MOVE.L A0,DEV(A2) ;INITIALIZE DEVICE FIELD OF RECORD
|
|
|
|
; DETERMINE WHETHER SRC AND DST ARE THE SCREEN AND SET UP DRAWING DIRECTIONS
|
|
|
|
; MOVE.L MAINDEVICE,A0 ;GET DEFAULT SCREEN DEVICE <10Jul88 BAL>
|
|
; MOVE.L (A0),A0 ;POINT TO DEFAULT SCREEN DEVICE
|
|
; MOVE.L GDPMAP(A0),A0 ;GET HANDLE TO PIXMAP
|
|
; MOVE.L (A0),A0 ;POINT TO PIXMAP
|
|
; MOVE.L BASEADDR(A0),D0 ;GET BASE ADDR OF SCREEN IN D0
|
|
MOVE.L ScrnBase,D0 ;GET BASE ADDR OF main SCREEN IN D0 <23Dec89 BAL>
|
|
|
|
MOVE.L DSTBITS(A6),A0 ;GET DESTINATION IN A0
|
|
_BITSTOMAP ;GET BIT/PIXMAP IN A0
|
|
; MOVE.L A0,DSTBITS(A6) ; <Don't carry derefed port's pixmap across rgbForeColor>
|
|
; <28May89 BAL>
|
|
MOVE.L A0,A1 ;KEEP DST PIXMAP IN A1
|
|
|
|
MOVE.L SRCBITS(A6),A0 ;POINT TO SRC BITMAP
|
|
_BITSTOMAP ;GET BIT/PIXMAP IN A0
|
|
MOVE.L A0,A2 ;SAVE SRC PIXMAP IN A2
|
|
|
|
CMP.L BASEADDR(A0),D0 ;SRC FROM THE SCREEN?
|
|
SEQ D6 ;IF SO, SET SRCSCRN FLAG
|
|
CMP.L BASEADDR(A1),D0 ;DST TO THE SCREEN?
|
|
SEQ D7 ;IF SO, SET DSTSCRN FLAG
|
|
|
|
MOVEQ #6,D2 ;ASSUME COPY FROM TOP TO BOTTOM
|
|
MOVE.B D6,D5 ;GET SRC FLAG
|
|
AND.B D7,D5 ;D5 SET IF SRC AND DST BOTH SCREEN
|
|
BEQ.S DIROK ;=>NO, DON'T WORRY ABOUT OVERLAP
|
|
|
|
; SRC AND DST BOTH ON SCREEN, AND THERE ARE MULTIPLE SCREENS. DETERMINE TRANSFER DIRECTION
|
|
|
|
MOVEQ #0,D2 ;ELSE ASSUME TRANSFER DOWN AND TO RIGHT
|
|
MOVE.L ([SRCRECT,A6]),D0 ;GET TOPLEFT OF SRCRECT
|
|
SUB BOUNDS+LEFT(A0),D0 ;CONVERT LEFT TO GLOBAL COORDINATES
|
|
MOVE.L ([DSTRECT,A6]),D1 ;GET TOPLEFT OF DSTRECT
|
|
SUB BOUNDS+LEFT(A1),D1 ;CONVERT LEFT TO GLOBAL COORDINATES
|
|
CMP D1,D0 ;IS SRC <= DST?
|
|
BLE.S TORT ;=>IF SO, TRANSFER IS TO RIGHT
|
|
ADDQ #2,D2 ;ELSE TRANSFER TO LEFT
|
|
|
|
TORT SWAP D0 ;GET TOP OF SRCRECT
|
|
SWAP D1 ;GET TOP OF DSTRECT
|
|
SUB BOUNDS+TOP(A0),D0 ;CONVERT TOP TO GLOBAL COORDINATES
|
|
SUB BOUNDS+TOP(A1),D1 ;CONVERT TOP TO GLOBAL COORDINATES
|
|
CMP D1,D0 ;IS SRC <= DST?
|
|
BLE.S DIROK ;=>IF SO, TRANSFER IS DOWNWARD
|
|
ADDQ #4,D2 ;ELSE TRANSFER IS UPWARD
|
|
|
|
DIROK LEA CMPTBL,A4 ;POINT TO TABLE OF OFFSETS
|
|
ADD 0(A4,D2),A4 ;A4 = RECT COMPARE ROUTINE
|
|
|
|
; COPY SRC RECT AND CONVERT COPY TO GLOBAL COORDINATES
|
|
|
|
TST.B D6 ;IS SRC THE SCREEN?
|
|
BEQ CHKDST ;=>NO, CHECK DEST
|
|
|
|
MOVE.L SRCRECT(A6),A1 ;POINT TO RECT
|
|
LEA GLOBALSRC(A6),A0 ;POINT TO LOCAL COPY
|
|
MOVE.L (A1)+,TOPLEFT(A0) ;COPY SRCRECT.TOPLEFT
|
|
MOVE.L (A1)+,BOTRIGHT(A0) ;COPY SRCRECT.BOTRIGHT
|
|
MOVE.L BOUNDS(A2),D0 ;GET SRCBITS.TOPLEFT
|
|
MOVE.L D0,D1 ;LEAVE LEFT IN D0
|
|
SWAP D1 ;AND TOP IN D1
|
|
SUB D1,(A0)+ ;OFFSET TOP
|
|
BVC.S @0 ;=>NO OVERFLOW
|
|
_PINIT ;ELSE PIN VALUE
|
|
@0 SUB D0,(A0)+ ;OFFSET LEFT
|
|
BVC.S @1 ;=>NO OVERFLOW
|
|
_PINIT ;ELSE PIN VALUE
|
|
@1 SUB D1,(A0)+ ;OFFSET BOTTOM
|
|
BVC.S @2 ;=>NO OVERFLOW
|
|
_PINIT ;ELSE PIN VALUE
|
|
@2 SUB D0,(A0)+ ;OFFSET RIGHT
|
|
BVC.S @3 ;=>NO OVERFLOW
|
|
_PINIT ;ELSE PIN VALUE
|
|
@3
|
|
|
|
; FOR EACH SRC DEVICE THAT INTERSECTS WITH THE SRCRECT, BUILD A RECORD ON THE STACK
|
|
; EACH RECORD IN LIST CONSISTS OF: [FLAG WORD] [DEVICE HANDLE] [RECTANGLE]
|
|
; [FLAG WORD]: O = END OF LIST; 1 = VALID RECORD; -1 = RECORD ALREADY USED IN SORT
|
|
|
|
MOVE.L DEVICELIST,A2 ;GET HANDLE TO FIRST DEVICE
|
|
CLR -(SP) ;[FLAG WORD] := END OF LIST
|
|
|
|
DONEXT1 MOVE.L (A2),A0 ;POINT AT CURRENT DEVICE
|
|
TST GDFLAGS(A0) ;IS THIS SCREEN ACTIVE?
|
|
BPL.S NXTDEV1 ;=>NO, SKIP TO NEXT
|
|
|
|
CLR.B -(SP) ;MAKE ROOM FOR BOOLEAN RESULT
|
|
PEA GLOBALSRC(A6) ;POINT TO SRC RECT
|
|
PEA GDRECT(A0) ;POINT AT DEVICE RECT
|
|
PEA RECT1(A6) ;GET RESULT IN RECT1
|
|
_SECTRECT ;INTERSECT THEM
|
|
TST.B (SP)+ ;DID THEY INTERSECT?
|
|
BEQ.S NXTDEV1 ;=>NO, KEEP LOOKING
|
|
|
|
LEA RECT1(A6),A0 ;POINT AT RESULT
|
|
MOVE.L 4(A0),-(SP) ;PUSH BOTRIGHT
|
|
MOVE.L (A0),-(SP) ;PUSH TOPLEFT
|
|
MOVE.L A2,-(SP) ;PUSH CURRENT DEVICE
|
|
MOVE #1,-(SP) ;FLAG VALID ENTRY
|
|
|
|
NXTDEV1 MOVE.L (A2),A0 ;POINT AT CURRENT DEVICE
|
|
MOVE.L GDNEXTGD(A0),D0 ;IS THERE ANOTHER DEVICE IN CHAIN?
|
|
MOVE.L D0,A2 ;GET IT INTO A0
|
|
BNE.S DONEXT1 ;=>YES, DO NEXT DEVICE
|
|
|
|
; BUILD SORTED LIST OF POINTERS TO THE DEVICE RECORDS
|
|
|
|
MOVE.L SP,A2 ;POINT TO FIRST DEVICE
|
|
CLR.L -(SP) ;AND FLAG END OF LIST
|
|
MOVEQ #0,D1 ;USEFUL CONSTANT
|
|
|
|
NXTLOOP MOVE.L A2,A0 ;POINT TO START OF LIST
|
|
MOVE.L D1,A1 ;INITIALIZE BEST FIT TO NONE
|
|
|
|
NXTRECT TST FLAG(A0) ;CHECK RECT STATUS?
|
|
BMI.S DONEXT ;=>RECT ALREADY USED, SKIP IT
|
|
BEQ.S LASTRECT ;=>LAST RECT, DONE WITH THIS LOOP
|
|
CMP.L A1,D1 ;SOMETHING TO COMPARE AGAINST?
|
|
BEQ.S NORECT ;=>NO, A WINNER BY DEFAULT
|
|
JSR (A4) ;COMPARE A0 TO A1
|
|
BEQ.S DONEXT ;=>A1 IS BETTER, TRY NEXT
|
|
NORECT MOVE.L A0,A1 ;ELSE PUT NEW BEST FIT IN A1
|
|
DONEXT ADD #SIZE,A0 ;BUMP TO NEXT RECORD
|
|
BRA.S NXTRECT ;=>DO NEXT RECT IN LIST
|
|
|
|
LASTRECT CMP.L A1,D1 ;DID WE FIND A BEST FIT?
|
|
BEQ.S ENDLOOP ;=>NO, ALL DONE
|
|
ST FLAG(A1) ;SAY IT'S USED
|
|
MOVE.L A1,-(SP) ;AND PUSH RECORD POINTER ONTO STACK
|
|
BRA.S NXTLOOP ;=>GO FIND NEXT BEST
|
|
|
|
ENDLOOP MOVE.L SP,SRCLIST(A6) ;SAVE POINTER TO SRC DEVICE LIST
|
|
|
|
|
|
; COPY DST RECT AND CONVERT COPY TO GLOBAL COORDINATES
|
|
|
|
CHKDST TST.B D7 ;IS DST THE SCREEN?
|
|
BEQ DRAWLOOP ;=>NO, GO TO DRAWING LOOP
|
|
MOVE.L DSTRECT(A6),a0 ;POINT TO RECT
|
|
LEA GLOBALDST(A6),a1 ;POINT TO LOCAL COPY
|
|
MOVE.L (a0)+,TOPLEFT(a1) ;COPY DSTRECT.TOPLEFT
|
|
MOVE.L (a0)+,BOTRIGHT(a1) ;COPY DSTRECT.BOTRIGHT
|
|
MOVE.L DSTBITS(A6),A0 ;GET DESTINATION IN A0
|
|
_BITSTOMAP ;make sure it's not a cportPtr <28May89 BAL>
|
|
MOVE.L BOUNDS(a0),D0 ;GET TOPLEFT
|
|
MOVE.L D0,D1 ;LEAVE LEFT IN D0
|
|
SWAP D1 ;AND TOP IN D1
|
|
SUB D1,(a1)+ ;OFFSET TOP
|
|
BVC.S @0 ;=>NO OVERFLOW
|
|
_PINIT ;ELSE PIN VALUE
|
|
@0 SUB D0,(a1)+ ;OFFSET LEFT
|
|
BVC.S @1 ;=>NO OVERFLOW
|
|
_PINIT ;ELSE PIN VALUE
|
|
@1 SUB D1,(a1)+ ;OFFSET BOTTOM
|
|
BVC.S @2 ;=>NO OVERFLOW
|
|
_PINIT ;ELSE PIN VALUE
|
|
@2 SUB D0,(a1)+ ;OFFSET RIGHT
|
|
BVC.S @3 ;=>NO OVERFLOW
|
|
_PINIT ;ELSE PIN VALUE
|
|
@3
|
|
|
|
; FOR EACH DST DEVICE THAT INTERSECTS WITH THE DSTRECT, BUILD A RECORD ON THE STACK
|
|
; EACH RECORD IN LIST CONSISTS OF: [FLAG WORD] [DEVICE HANDLE] [RECTANGLE]
|
|
; [FLAG WORD]: O = END OF LIST; 1 = VALID RECORD; -1 = RECORD ALREADY USED IN SORT
|
|
|
|
MOVE.L DEVICELIST,A2 ;GET HANDLE TO FIRST DEVICE
|
|
CLR -(SP) ;[FLAG WORD] := END OF LIST
|
|
|
|
DONEXT2 MOVE.L (A2),A0 ;POINT AT CURRENT DEVICE
|
|
TST GDFLAGS(A0) ;IS THIS SCREEN ACTIVE?
|
|
BPL.S NXTDEV2 ;=>NO, SKIP TO NEXT
|
|
|
|
CLR.B -(SP) ;MAKE ROOM FOR BOOLEAN RESULT
|
|
PEA GLOBALDST(A6) ;POINT TO DST RECT
|
|
PEA GDRECT(A0) ;POINT AT DEVICE RECT
|
|
PEA RECT1(A6) ;GET RESULT IN RECT1
|
|
_SECTRECT ;INTERSECT THEM
|
|
TST.B (SP)+ ;DID THEY INTERSECT?
|
|
BEQ.S NXTDEV2 ;=>NO, KEEP LOOKING
|
|
|
|
LEA RECT1(A6),A0 ;POINT AT RESULT
|
|
MOVE.L 4(A0),-(SP) ;PUSH BOTRIGHT
|
|
MOVE.L (A0),-(SP) ;PUSH TOPLEFT
|
|
MOVE.L A2,-(SP) ;PUSH CURRENT DEVICE
|
|
MOVE #1,-(SP) ;FLAG VALID ENTRY
|
|
|
|
NXTDEV2 MOVE.L (A2),A0 ;POINT AT CURRENT DEVICE
|
|
MOVE.L GDNEXTGD(A0),D0 ;IS THERE ANOTHER DEVICE IN CHAIN?
|
|
MOVE.L D0,A2 ;GET IT INTO A0
|
|
BNE.S DONEXT2 ;=>YES, DO NEXT DEVICE
|
|
|
|
; BUILD SORTED LIST OF DEVICES
|
|
|
|
MOVE.L SP,A2 ;POINT TO FIRST DEVICE
|
|
CLR.L -(SP) ;AND FLAG END OF LIST
|
|
MOVEQ #0,D1 ;USEFUL CONSTANT
|
|
|
|
NXTLUP2 MOVE.L A2,A0 ;POINT TO START OF LIST
|
|
MOVE.L D1,A1 ;INITIALIZE BEST FIT TO NONE
|
|
|
|
NXTRCT2 TST FLAG(A0) ;CHECK RECT STATUS?
|
|
BMI.S DONXT2 ;=>RECT ALREADY USED, SKIP IT
|
|
BEQ.S LSTRCT2 ;=>LAST RECT, DONE WITH THIS LOOP
|
|
CMP.L A1,D1 ;SOMETHING TO COMPARE AGAINST?
|
|
BEQ.S NORCT2 ;=>NO, A WINNER BY DEFAULT
|
|
JSR (A4) ;COMPARE A0 TO A1
|
|
BEQ.S DONXT2 ;=>A1 IS BETTER, TRY NEXT
|
|
NORCT2 MOVE.L A0,A1 ;ELSE PUT NEW BEST FIT IN A1
|
|
DONXT2 ADD #SIZE,A0 ;BUMP TO NEXT RECORD
|
|
BRA.S NXTRCT2 ;=>DO NEXT RECT IN LIST
|
|
|
|
LSTRCT2 CMP.L A1,D1 ;DID WE FIND A BEST FIT?
|
|
BEQ.S ENDLUP2 ;=>NO, ALL DONE
|
|
ST FLAG(A1) ;SAY IT'S USED
|
|
MOVE.L DEV(A1),-(SP) ;AND PUSH DEVICE HANDLE ONTO STACK
|
|
BRA.S NXTLUP2 ;=>GO FIND NEXT BEST
|
|
|
|
ENDLUP2 MOVE.L SP,DSTLIST(A6) ;SAVE POINTER TO DST DEVICE LIST
|
|
|
|
|
|
DRAWLOOP
|
|
|
|
; IN CASE WE ARE GOING TO SCREEN, SAVE OFF STATE INFO
|
|
|
|
MOVE.L THEGDEVICE,-(SP) ;SAVE DST DEVICE
|
|
MOVE.L SRCDEVICE,-(SP) ;SAVE SRC DEVICE
|
|
|
|
MOVE.L THEGDEVICE,A0 ;GET HANDLE TO THE GDEVICE
|
|
MOVE.L (A0),A0 ;POINT TO THE GDEVICE
|
|
MOVE.L GDPMAP(A0),A0 ;GET HANDLE TO ITS PIXMAP
|
|
MOVE.L (A0),A0 ;POINT AT PIXMAP
|
|
MOVE.L PMTABLE(A0),A0 ;GET COLOR TABLE HANDLE
|
|
MOVE.L (A0),A0 ;POINT TO COLOR TABLE
|
|
MOVE.L CTSEED(A0),LASTSEED(A6) ;SAVE LAST COLOR TABLE SEED
|
|
MOVE.L FGCOLOR(A3),SAVEFG(A6) ;SAVE FG COLOR
|
|
MOVE.L BKCOLOR(A3),SAVEBK(A6) ;SAVE BK COLOR
|
|
MOVE.B HiliteMode,saveHilite(A6) ;save the hilite state
|
|
|
|
; MAKE A LOCAL COPY OF THE SRC AND DST RECTS IN SRCRECT1 AND DSTRECT1
|
|
; AND SET D7 TO NON-ZERO IF WE ARE STRETCHING
|
|
|
|
LEA DSTRECT1(A6),A1 ;POINT TO DSTRECT1, SRCRECT1
|
|
MOVE.L DSTRECT(A6),A0 ;POINT TO DSTRECT
|
|
MOVE.L (A0)+,D0 ;GET TOPLEFT
|
|
MOVE.L D0,(A1)+ ;COPY TOPLEFT
|
|
MOVE.L (A0)+,D7 ;GET BOTRIGHT
|
|
MOVE.L D7,(A1)+ ;COPY BOTRIGHT
|
|
SUB D0,D7 ;GET DST WIDTH
|
|
SWAP D0 ;GET TOP
|
|
SWAP D7 ;GET BOTTOM
|
|
SUB D0,D7 ;GET DST HEIGHT
|
|
MOVE.L SRCRECT(A6),A0 ;POINT TO SRCRECT
|
|
MOVE.L (A0)+,D0 ;GET TOPLEFT
|
|
MOVE.L D0,(A1)+ ;COPY TOPLEFT
|
|
MOVE.L (A0)+,D1 ;GET BOTRIGHT
|
|
MOVE.L D1,(A1)+ ;COPY BOTRIGHT
|
|
SWAP D7 ;GET DST WIDTH
|
|
ADD D0,D7 ;SUBTRACT WIDTH OF SRC
|
|
SUB D1,D7 ;FROM WIDTH OF DST
|
|
SWAP D7 ;GET HEIGHT
|
|
SWAP D0 ;GET TOP
|
|
SWAP D1 ;GET BOTTOM
|
|
ADD D0,D7 ;SUBTRACT HEIGHT OF SRC
|
|
SUB D1,D7 ;FROM HEIGHT OF DST
|
|
;D7.L <> 0 IF STRETCHING
|
|
|
|
; FOR EACH DEVICE IN THE SRCLIST, DRAW TO EACH DEVICE IN THE DSTLIST
|
|
|
|
MOVE.L SRCLIST(A6),A2 ;POINT TO SRCLIST
|
|
NXTSRC MOVE.L DSTLIST(A6),A4 ;POINT TO DSTLIST
|
|
MOVE.L (A2)+,D0 ;GET NEXT SRC RECORD
|
|
MOVE.L D0,A0 ;GET RECORD POINTER
|
|
BEQ DONE ;=>NO MORE
|
|
MOVE.L DEV(A0),SRCDEVICE ;AND SET SRC DEVICE
|
|
NXTDST MOVE.L (A4)+,D1 ;GET NEXT DST DEVICE
|
|
BEQ.S NXTSRC ;=>NO MORE
|
|
|
|
MOVE.L D1,THEGDEVICE ;ELSE SET DST DEVICE
|
|
TST.B D6 ;IS SRC THE SCREEN?
|
|
BEQ CLIPOK ;=>NO, DON'T CHECK CLIPPING
|
|
;
|
|
; if source and destination are both screen devices and they overlap, copy only to
|
|
; destination devices which are the same gDevice as the source. This will be needed
|
|
; for devices which use a mask plane. It assures that items moved around in the mask
|
|
; plane are only copied to the mask plane, and items moved around on the screen are
|
|
; only copied to the screen. Without this, the mask would goto the screen and vice-versa.
|
|
; <KON 2/19/90>
|
|
;
|
|
tst.b d5 ;are both src and destination the screen? <KON 23JAN91>
|
|
beq.s @cont ;=>NO, Don't check for overlap <26>
|
|
cmp.l SRCDEVICE,d1 ;are src and destination the same device? <KON 28NOV90>
|
|
beq.s @cont ;=>YES, Don't check for overlap
|
|
;
|
|
; Src and Dst are different screen devices. If the top-left corner of their rectangles
|
|
; are the same, assume the devices overlap and don't copy between them.
|
|
;
|
|
MOVE.L srcDevice,A1 ;handle to source gDevice
|
|
move.l (a1),a1 ;pointer to source gDevice
|
|
move.l gdRect(a1),d0 ;get rect top.left
|
|
move.l theGDevice,a1 ;handle to destination gDevice
|
|
move.l (a1),a1 ;pointer to destination gDevice
|
|
cmp.l gdRect(a1),d0 ;dest and src gDevice have same top-left?
|
|
beq.s nxtdst ;devices overlap, skip drawing
|
|
|
|
|
|
@cont
|
|
;
|
|
; End of <KON 2/19/90>
|
|
;
|
|
|
|
; CLIP SRCRECT TO SRC DEVICE BOUNDARIES
|
|
|
|
MOVE.L -4(A2),A0 ;POINT TO SOURCE RECORD
|
|
ADDQ #RECT,A0 ;POINT TO CLIPPED RECT
|
|
MOVE.L (A0)+,D0 ;GET GLOBAL CLIPPED.TOPLEFT
|
|
MOVE.L (A0)+,D1 ;GET GLOBAL CLIPPED.BOTRIGHT
|
|
CMP.L GLOBALSRC+TOPLEFT(A6),D0 ;WAS TOPLEFT TRIMMED?
|
|
BNE.S DOTRIM ;=>YES, TRIM SRC, DST RECTS
|
|
CMP.L GLOBALSRC+BOTRIGHT(A6),D1 ;WAS BOTRIGHT TRIMMED?
|
|
BEQ.S CLIPOK ;=>NO, DON'T TRIM SRC, DST RECTS
|
|
|
|
DOTRIM MOVE.L DSTRECT(A6),A0 ;POINT TO DSTRECT
|
|
LEA DSTRECT1(A6),A1 ;POINT TO DSTRECT1, SRCRECT1
|
|
MOVE.L (A0)+,(A1)+ ;COPY TOPLEFT
|
|
MOVE.L (A0)+,(A1)+ ;COPY BOTRIGHT
|
|
MOVE.L SRCRECT(A6),A0 ;POINT TO SRCRECT
|
|
MOVE.L (A0)+,(A1)+ ;COPY TOPLEFT
|
|
MOVE.L (A0)+,(A1)+ ;COPY BOTRIGHT
|
|
|
|
SUB GLOBALSRC+LEFT(A6),D0 ;IS LEFT CLIPPED ON DEVICE?
|
|
BLE.S @1 ;=>LEFT OK
|
|
ADD D0,SRCRECT1+LEFT(A6) ;ELSE TRIM SRC
|
|
ADD D0,DSTRECT1+LEFT(A6) ;AND DST
|
|
@1 SWAP D0 ;GET TOP
|
|
SUB GLOBALSRC+TOP(A6),D0 ;IS TOP CLIPPED ON DEVICE?
|
|
BLE.S @2 ;=>TOP OK
|
|
ADD D0,SRCRECT1+TOP(A6) ;ELSE TRIM SRC
|
|
ADD D0,DSTRECT1+TOP(A6) ;AND DST
|
|
@2 SUB GLOBALSRC+RIGHT(A6),D1 ;IS RIGHT CLIPPED ON DEVICE?
|
|
BPL.S @3 ;=>RIGHT OK
|
|
ADD D1,SRCRECT1+RIGHT(A6) ;ELSE TRIM SRC
|
|
ADD D1,DSTRECT1+RIGHT(A6) ;AND DST
|
|
@3 SWAP D1 ;GET BOTTOM
|
|
SUB GLOBALSRC+BOTTOM(A6),D1 ;IS BOTTOM CLIPPED ON DEVICE?
|
|
BPL.S @4 ;=>BOTTOM OK
|
|
ADD D1,SRCRECT1+BOTTOM(A6) ;ELSE TRIM SRC
|
|
ADD D1,DSTRECT1+BOTTOM(A6) ;AND DST
|
|
|
|
@4 TST.L D7 ;ARE WE SCALING?
|
|
BEQ.S CLIPOK ;=>YES, DON'T NEED TO MAP DST
|
|
LEA SRCRECT1(A6),A0 ;ELSE GET TRIMMED SRC
|
|
LEA DSTRECT1(A6),A1 ;AND SAVE AS UNMAPPED TRIMMED DST
|
|
MOVE.L (A0)+,(A1)+ ;COPY SRCRECT1 TO DSTRECT1
|
|
MOVE.L (A0)+,(A1)+
|
|
PEA DSTRECT1(A6) ;PUSH RECT TO BE MAPPED
|
|
MOVE.L SRCRECT(A6),-(SP) ;PUSH SRC RECTANGLE
|
|
MOVE.L DSTRECT(A6),-(SP) ;PUSH DST RECTANGLE
|
|
_MAPRECT ;MAP RECTANGLE TO DST COORDINATES
|
|
|
|
CLIPOK MOVE.B saveHilite(A6),HiliteMode ;RESTORE HILITE FLAGS
|
|
TST PORTBITS+ROWBYTES(A3) ;IS IT AN OLD GRAFPORT?
|
|
BPL DOIT ;=>YES, COLORS ARE OK
|
|
MOVE.L THEGDEVICE,A0 ;GET THE DST DEVICE
|
|
MOVE.L (A0),A0 ;POINT AT IT
|
|
MOVE.L GDPMAP(A0),A0 ;GET PIXMAP
|
|
MOVE.L (A0),A0 ;POINT AT IT
|
|
MOVE.L PMTABLE(A0),A0 ;GET COLOR TABLE
|
|
MOVE.L (A0),A0 ;POINT AT IT
|
|
MOVE.L CTSEED(A0),D0 ;GET SEED
|
|
CMP.L LASTSEED(A6),D0 ;SAME AS CURRENT SEED?
|
|
BEQ.S DOIT ;=>YES, COLORS ARE OK
|
|
|
|
MOVE.L D0,LASTSEED(A6) ;SAVE LAST COLOR TABLE SEED
|
|
SUBQ #6,SP ;MAKE ROOM FOR A COLOR RECORD
|
|
CLR.L -(SP) ;CLEAR INDEX, FLAGS WORDS
|
|
|
|
; This is a patch rolled in <6Jun87 EHB>
|
|
; The idea here is that to keep the index field in the grafPort valid, we must
|
|
; check to see whether we should use palette manager or not.
|
|
|
|
MOVE.L GrafVars(A3),D0 ;get the grafVars handle
|
|
BEQ.S @NoPlt ;=>none there
|
|
MOVE.L D0,A0 ;get grafVars handle
|
|
MOVE.L (A0),A0 ;point at grafVars
|
|
TST.L PmFgColor(A0) ;is there a palette?
|
|
BEQ.S @NoPlt ;=>no, continue
|
|
|
|
MOVE PmFlags(A0),D2 ;else get flags
|
|
MOVE PmBkIndex(A0),2(SP) ;save bk index
|
|
BTST #PmBkBit,D2 ;bk set by palette mgr?
|
|
SNE (SP) ;if so set flag
|
|
|
|
BTST #PmFgBit,D2 ;fg set by palette mgr?
|
|
BEQ.S @NoPlt ;=>no, continue
|
|
|
|
MOVE PmFgIndex(A0),-(SP) ;else push last index
|
|
_PmForeColor ;and set that color
|
|
BRA.S @NoPlt1 ;=>no, do old way
|
|
|
|
@NoPlt PEA 4(SP) ;POINT AT RECORD FOR RGBFC
|
|
MOVE.L (SP),-(SP) ;AND AGAIN FOR GETFC
|
|
_GETFORECOLOR ;GET THE FOREGROUND COLOR
|
|
_RGBFORECOLOR ;SET THE FOREGROUND COLOR
|
|
|
|
@NoPlt1 TST.B (SP) ;bk set by palette mgr?
|
|
BEQ.S @NoPlt2 ;=>no, do old way
|
|
MOVE 2(SP),-(SP) ;else push bk index
|
|
_PmBackColor ;and set that color
|
|
BRA.S @BkDone ;=>done setting colors
|
|
|
|
@NoPlt2 PEA 4(SP) ;POINT AT RECORD
|
|
MOVE.L (SP),-(SP) ;AND AGAIN FOR GETFC
|
|
_GETBACKCOLOR ;GET THE BACKGROUND COLOR
|
|
_RGBBACKCOLOR ;SET THE BACKGROUND COLOR
|
|
|
|
@BkDone ADD #10,SP ;STRIP THE RECORD
|
|
|
|
DOIT MOVE.L SRCBITS(A6),-(SP) ;PUSH SRCBITS
|
|
MOVE.L MASKBITS(A6),-(SP) ;PUSH MASKBITS
|
|
MOVE.L DSTBITS(A6),-(SP) ;PUSH DSTBITS
|
|
PEA SRCRECT1(A6) ;PUSH SRCRECT
|
|
MOVE.L MASKRECT(A6),-(SP) ;PUSH MASKRECT
|
|
PEA DSTRECT1(A6) ;PUSH DSTRECT
|
|
MOVE MODE(A6),-(SP) ;PUSH MODE
|
|
AND #$FFF7,(SP) ;clear the pattern bit in case the user set it
|
|
CLR.L -(SP) ;NO PATTERN NEEDED
|
|
MOVE.L RGNA(A6),-(SP) ;PUSH FIRST REGION
|
|
MOVE.L RGNB(A6),-(SP) ;PUSH SECOND REGION
|
|
MOVE.L MASKRGN(A6),-(SP) ;PUSH MASKRGN
|
|
BNE.S MASKOK ;WAS IT NIL ?
|
|
MOVE.L GRAFGLOBALS(A5),A0 ;GET GRAFGLOBALS
|
|
MOVE.L WIDEOPEN(A0),(SP) ;YES, REPLACE WITH WIDEOPEN
|
|
MASKOK CLR -(SP) ;pass multicolor flag false
|
|
_STRETCHBITS ;CALL STRETCHBITS
|
|
|
|
BRA.S NXTDST ;=>TRY NEXT DESTINATION
|
|
|
|
DONE MOVE.L (SP)+,SRCDEVICE ;RESTORE SRC DEVICE
|
|
MOVE.L (SP)+,THEGDEVICE ;RESTORE DST DEVICE
|
|
|
|
MOVE.L SAVEFG(A6),FGCOLOR(A3) ;RESTORE FG COLOR
|
|
MOVE.L SAVEBK(A6),BKCOLOR(A3) ;RESTORE BK COLOR
|
|
BSET #HILITEBIT,HILITEMODE ;TURN OFF HILITING
|
|
|
|
MOVE.L SAVEDSP(A6),SP ;RESTORE THE STACK POINTER
|
|
RTS
|
|
|
|
|
|
;---------------------------------------------------------------
|
|
;
|
|
; ROUTINES TO COMPARE THE RECT IN A0 TO THE RECT IN A1.
|
|
; RETURN TRUE IF SPECIFIED RELATIONSHIP TRUE.
|
|
|
|
CMPTBL DC.W UPLEFT-CMPTBL
|
|
DC.W UPRIGHT-CMPTBL
|
|
DC.W DNLEFT-CMPTBL
|
|
DC.W DNRIGHT-CMPTBL
|
|
|
|
; IS THE RECT IN A0 TO THE UPPER LEFT OF THE RECT IN A1?
|
|
|
|
UPLEFT MOVE RECT+BOTTOM(A0),D0 ;GET BOTTOM OF NEW RECT
|
|
CMP RECT+TOP(A1),D0 ;IS IT ABOVE OLD RECT?
|
|
BLE.S XTRUE ;=>YES, RETURN TRUE
|
|
MOVE RECT+RIGHT(A0),D0 ;GET RIGHT OF NEW RECT
|
|
CMP RECT+LEFT(A1),D0 ;IS IT TO LEFT OF NEW RECT
|
|
BLE.S XTRUE ;=>YES, RETURN TRUE
|
|
XFALSE MOVEQ #0,D0 ;SET FLAG FALSE
|
|
RTS ;AND RETURN
|
|
|
|
XTRUE MOVEQ #1,D0 ;SET FLAG TRUE
|
|
RTS ;AND RETURN
|
|
|
|
; IS THE RECT IN A0 TO THE LOWER LEFT OF THE RECT IN A1?
|
|
|
|
DNLEFT MOVE RECT+TOP(A0),D0 ;GET TOP OF NEW RECT
|
|
CMP RECT+BOTTOM(A1),D0 ;IS IT BELOW OLD RECT?
|
|
BGE.S XTRUE ;=>YES, RETURN TRUE
|
|
MOVE RECT+RIGHT(A0),D0 ;GET RIGHT OF NEW RECT
|
|
CMP RECT+LEFT(A1),D0 ;IS IT TO LEFT OF NEW RECT
|
|
BLE.S XTRUE ;=>YES, RETURN TRUE
|
|
BRA.S XFALSE ;=>ELSE RETURN FALSE
|
|
|
|
; IS THE RECT IN A0 TO THE UPPER RIGHT OF THE RECT IN A1?
|
|
|
|
UPRIGHT MOVE RECT+BOTTOM(A0),D0 ;GET BOTTOM OF NEW RECT
|
|
CMP RECT+TOP(A1),D0 ;IS IT ABOVE OLD RECT?
|
|
BLE.S XTRUE ;=>YES, RETURN TRUE
|
|
MOVE RECT+LEFT(A0),D0 ;GET LEFT OF NEW RECT
|
|
CMP RECT+RIGHT(A1),D0 ;IS IT TO RIGHT OF NEW RECT
|
|
BGE.S XTRUE ;=>YES, RETURN TRUE
|
|
BRA.S XFALSE ;=>ELSE RETURN FALSE
|
|
|
|
; IS THE RECT IN A0 TO THE LOWER RIGHT OF THE RECT IN A1?
|
|
|
|
DNRIGHT MOVE RECT+TOP(A0),D0 ;GET TOP OF NEW RECT
|
|
CMP RECT+BOTTOM(A1),D0 ;IS IT BELOW OLD RECT?
|
|
BGE.S XTRUE ;=>YES, RETURN TRUE
|
|
MOVE RECT+LEFT(A0),D0 ;GET LEFT OF NEW RECT
|
|
CMP RECT+RIGHT(A1),D0 ;IS IT TO RIGHT OF NEW RECT
|
|
BGE.S XTRUE ;=>YES, RETURN TRUE
|
|
BRA.S XFALSE ;=>ELSE RETURN FALSE
|
|
|
|
|
|
|
|
CopyBits PROC EXPORT
|
|
IMPORT ShieldCursor,ShowCursor,StretchBits,BitsToMap,PortToMap,GODEVLOOP
|
|
;---------------------------------------------------------------
|
|
;
|
|
; PROCEDURE CopyBits(srcBits,dstBits: BitMap;
|
|
; srcRect,dstRect: Rect;
|
|
; mode: INTEGER;
|
|
; maskRgn: RgnHandle *);
|
|
;
|
|
;
|
|
; A6 OFFSETS OF PARAMS AND LOCALS AFTER LINK:
|
|
;
|
|
PARAMSIZE EQU 22 ;TOTAL BYTES OF PARAMS
|
|
SRCBITS EQU PARAMSIZE+8-4 ;LONG, ADDR OF BITMAP
|
|
DSTBITS EQU SRCBITS-4 ;LONG, ADDR OF BITMAP
|
|
SRCRECT EQU DSTBITS-4 ;LONG, ADDR OF RECT
|
|
DSTRECT EQU SRCRECT-4 ;LONG, ADDR OF RECT
|
|
MODE EQU DSTRECT-2 ;WORD
|
|
MASKRGN EQU MODE-4 ;LONG, RGNHANDLE
|
|
|
|
SRCRECT1 EQU -8 ;LOCAL SRC RECT
|
|
DSTRECT1 EQU SRCRECT1-8 ;LOCAL DST RECT (MUST FOLLOW SRCRECT1)
|
|
VARSIZE EQU DSTRECT1 ;SIZE OF LOCAL VARS
|
|
|
|
LINK A6,#VARSIZE ;NO LOCAL VARS
|
|
MOVEM.L d2/D6-D7/A2-A4,-(SP) ;SAVE REGS (save d2 for MS Works) <01Apr89 BAL>
|
|
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
|
|
MOVE.L THEPORT(A4),A3 ;POINT TO CURRENT GRAFPORT
|
|
MOVE.L SRCBITS(A6),A0 ;POINT TO SRCBITS
|
|
_BITSTOMAP ;GET POINTER TO BIT/PIXMAP IN A0
|
|
MOVE.L A0,A2 ;AND SAVE IN A2
|
|
|
|
; MOVE.L SCREENBITS+BASEADDR(A4),D6 ;GET BASE ADDRESS OF SCREEN
|
|
MOVE.L ScrnBase,D6 ;GET BASE ADDRESS OF main SCREEN
|
|
|
|
MOVE.L BASEADDR(A2),D7 ;GET SRCBITS.BASEADDR
|
|
CMP.L D6,D7 ;IS SRC FROM THE SCREEN ?
|
|
BNE.S SRCOK ;NO, CONTINUE
|
|
MOVE.L SRCRECT(A6),-(SP) ;YES, PUSH SRCRECT
|
|
MOVE.L BOUNDS+TOPLEFT(A2),-(SP) ;PUSH OFFSET POINT
|
|
_SHIELDCURSOR ;HIDE THE CURSOR IF IN SRCRECT
|
|
|
|
;-----------------------------------------------------
|
|
;
|
|
; TEST IF DST IS TO THEPORT, (IF SO WE CLIP)
|
|
;
|
|
SRCOK MOVE.L DSTBITS(A6),A0 ;POINT TO DSTBITS
|
|
_BITSTOMAP ;GET POINTER TO BIT/PIXMAP IN A0
|
|
MOVE.L A0,A1 ;SAVE IN A1
|
|
MOVE.L A3,D0 ;IS THEPORT NIL ?
|
|
BEQ.S NOTPORT ;YES, NOT TO THEPORT
|
|
BTST #0,D0 ;IS THEPORT ODD ?
|
|
BNE.S NOTPORT ;YES, NOT TO THEPORT
|
|
MOVE.L A3,A0 ;GET THEPORT
|
|
_PORTTOMAP ;CONVERT PORT TO BIT/PIXMAP
|
|
MOVE.L BASEADDR(A1),D1 ;GET DST.BASEADDR
|
|
CMP.L BASEADDR(A0),D1 ;IS PORTBITS.BASEADDR SAME ?
|
|
BEQ.S BASEOK ;YES, BASE IS SAME <26May87 EHB>
|
|
|
|
; IF BASEADDR = ROMBASE THEN GO THROUGH GRAFPROC TO MAKE PRINTING WORK
|
|
|
|
CMP.L D6,D1 ;DST.BASEADDR SAME AS SCREEN? <26May87 EHB>
|
|
BNE.S NOTPORT ;NO, NOT TO THE PORT <26May87 EHB>
|
|
move.l RomBase,d0 ;pick up rombase <10Apr89 BAL/JNP>
|
|
CMP.L BASEADDR(A0),d0 ;IS PORTBITS.BASEADDR ROM? <26May87 EHB>
|
|
BNE.S NOTPORT ;=>NO, NOT PORT <26May87 EHB>
|
|
BRA TOPORT ;=>ELSE GO THROUGH GRAFPROC <26May87 EHB>
|
|
|
|
BASEOK MOVE.L BOUNDS(A0),D0 ;GET PORT BOUNDS TOPLEFT
|
|
CMP.L BOUNDS(A1),D0 ;IS BOUNDS TOPLEFT SAME ?
|
|
BEQ TOPORT ;YES, ITS PROBABLY TO THEPORT
|
|
;
|
|
; DST IS DEFINITELY NOT TO THEPORT, SO WE CAN'T USE THE CAPTURE PROC.
|
|
; StretchBits(srcBits,maskBits,dstBits,srcRect,maskRect,dstRect,mode,pattern,wideOpen,wideOpen,maskRgn);
|
|
;
|
|
NOTPORT
|
|
|
|
; if src or dst is the screen, then call devloop
|
|
|
|
CMP.L D6,D7 ;is dst the screen?
|
|
BEQ UseDevLoop ;=>yes, use device loop
|
|
|
|
; The dst is not the screen so make sure the fgcolor and bkcolor are in
|
|
; sync with the dst gdevice in order to make offscreen pixmap copying independent
|
|
; of the depth of thePort's pixmap. <BAL 07Jul88>
|
|
|
|
movem.l d1/a1,-(sp) ;save
|
|
SUBQ #6,SP ;MAKE ROOM FOR A COLOR RECORD <BAL 07Jul88>
|
|
CLR.L -(SP) ;CLEAR INDEX, FLAGS WORDS <BAL 07Jul88>
|
|
PEA 4(SP) ;POINT AT RECORD FOR RGBFC <BAL 07Jul88>
|
|
MOVE.L (SP),-(SP) ;AND AGAIN FOR GETFC <BAL 07Jul88>
|
|
_GETFORECOLOR ;GET THE FOREGROUND COLOR <BAL 07Jul88>
|
|
_RGBFORECOLOR ;SET THE FOREGROUND COLOR <BAL 07Jul88>
|
|
PEA 4(SP) ;POINT AT RECORD <BAL 07Jul88>
|
|
MOVE.L (SP),-(SP) ;AND AGAIN FOR GETFC <BAL 07Jul88>
|
|
_GETBACKCOLOR ;GET THE BACKGROUND COLOR <BAL 07Jul88>
|
|
_RGBBACKCOLOR ;SET THE BACKGROUND COLOR <BAL 07Jul88>
|
|
ADD #10,SP ;STRIP THE RECORD <BAL 07Jul88>
|
|
movem.l (sp)+,d1/a1 ;restore
|
|
|
|
CMP.L D6,D1 ;is src the screen?
|
|
BEQ.S UseDevLoop ;=>yes, use device loop
|
|
|
|
MOVE.L SRCBITS(A6),-(SP) ;PUSH SRCBITS (not derefed) <BAL 28May89>
|
|
CLR.L -(SP) ;NO MASK
|
|
MOVE.L DSTBITS(A6),-(SP) ;PUSH DSTBITS (not derefed) <BAL 28May89>
|
|
MOVE.L SRCRECT(A6),-(SP) ;PUSH SRCRECT
|
|
CLR.L -(SP) ;NO MASKRECT)
|
|
MOVE.L DSTRECT(A6),-(SP) ;PUSH DSTRECT
|
|
MOVE MODE(A6),-(SP) ;PUSH MODE
|
|
AND #$FFF7,(SP) ;clear the pattern bit in case the user set it
|
|
CLR.L -(SP) ;NO PATTERN
|
|
MOVE.L WIDEOPEN(A4),-(SP) ;PUSH WIDEOPEN
|
|
MOVE.L (SP),-(SP) ;PUSH WIDEOPEN
|
|
MOVE.L MASKRGN(A6),-(SP) ;PUSH MASKRGN
|
|
BNE.S MASKOK ;WAS IT NIL ?
|
|
MOVE.L WIDEOPEN(A4),(SP) ;YES, REPLACE WITH WIDEOPEN
|
|
MASKOK CLR -(SP) ;pass multicolor flag false
|
|
_STRETCHBITS ;CALL STRETCHBITS
|
|
BRA CLEANUP ;AND CONTINUE
|
|
|
|
UseDevLoop
|
|
|
|
; CALL GODEVLOOP WITH SAME PARAMETERS AS STDBITS SO IT CAN USE DEVLOOP
|
|
|
|
MOVE.L SRCBITS(A6),-(SP) ;PUSH SRCBITS (not derefed) <BAL 28May89>
|
|
MOVE.L DSTBITS(A6),A1 ;Pass DSTBITS (not derefed) <BAL 28May89>
|
|
MOVE.L SRCRECT(A6),-(SP) ;PUSH SRCRECT
|
|
MOVE.L DSTRECT(A6),-(SP) ;PUSH DSTRECT
|
|
MOVE MODE(A6),-(SP) ;PUSH MODE
|
|
MOVE.L MASKRGN(A6),-(SP) ;PUSH MASKRGN (NIL OK)
|
|
JSR GODEVLOOP ;GO CALL DEVICE LOOP
|
|
BRA CLEANUP ;AND CONTINUE
|
|
|
|
;
|
|
; DST IS PROBABLY TO THEPORT, SO WE USE THE CAPTURE PROC.
|
|
;
|
|
; If we are drawing to an old grafport and the grafProc has been replaced,
|
|
; convert to bitMap first
|
|
;____________________________________________________________________________________
|
|
|
|
TOPORT MOVE rowBytes(A2),D1 ;is src an old bitMap?
|
|
BPL @ProcOK ;=>yes, it's safe
|
|
TST portBits+rowBytes(A3) ;is port old or new
|
|
BMI @ProcOK ;=>new is safe too
|
|
|
|
MOVE.L grafProcs(A3),D0 ;have the grafProcs been replaced?
|
|
BEQ @ProcOK ;=>no, use port
|
|
|
|
MOVE.L JStdBits,A1 ;get piece of trap table
|
|
EXG A1,D0 ;get grafProc pointer
|
|
CMP.L bitsProc(A1),D0 ;has it been replaced?
|
|
BEQ @ProcOK ;=>no, use port
|
|
|
|
; we have to do the conversion
|
|
|
|
@1 MOVE.L A0,-(SP) ;save dstBits
|
|
SUB #18,SP ;make room for bitMap, handle
|
|
|
|
MOVEQ #0,D0 ;clear high word
|
|
MOVE D1,D0 ;get rowbytes
|
|
LSL #3,D0 ;convert rowBytes to bits
|
|
MOVE pixelSize(A2),D1 ;get pixel size of source
|
|
DIVU D1,D0 ;get new rowBits
|
|
MOVEQ #15,D2 ;get 15
|
|
ADD.L D2,D0 ;round rowBits to nearest word
|
|
ASR.L #4,D0 ;divide by 16
|
|
BLE @Abort ;abort if newRow <= 0
|
|
ADD D0,D0 ;double for new rowBytes
|
|
MOVE D0,ROWBYTES(SP) ;set new rowBytes
|
|
|
|
; ALLOCATE MEMORY FOR TEMP BITMAP AND COPY TO IT
|
|
|
|
MOVE.L bounds+topLeft(A2),D1 ;get topLeft
|
|
MOVE.L bounds+botRight(A2),D2 ;get botRight
|
|
MOVE.L D1,bounds+topLeft(SP) ;set new topLeft
|
|
MOVE.L D2,bounds+botRight(SP) ;set new botRight
|
|
SWAP D1 ;get top
|
|
SWAP D2 ;get bottom
|
|
SUB D1,D2 ;get width
|
|
MULU D2,D0 ;get date size in bytes
|
|
_NEWHANDLE ;ALLOCATE MEMORY FOR BITMAP
|
|
BNE.S @Abort ;=>error, don't draw at all
|
|
|
|
MOVE.L A0,14(SP) ;SAVE FOR DISPOSE
|
|
_HLOCK ;LOCK THE HANDLE
|
|
MOVE.L (A0),A0 ;POINT AT THE STORAGE
|
|
MOVE.L A0,BASEADDR(SP) ;AND SET BASE ADDRESS OF SRCBITS
|
|
|
|
MOVE.L PICSAVE(A3),-(SP) ;SAVE PICSAVE ON THE STACK
|
|
CLR.L PICSAVE(A3) ;DISABLE PICTURE FOR COPY!
|
|
|
|
SUBQ #6,SP ;MAKE ROOM FOR RGBCOLOR
|
|
MOVE.L SP,-(SP) ;POINT TO VAR RGBCOLOR
|
|
_GETFORECOLOR ;SAVE THE RGBFORECOLOR
|
|
MOVEQ #BLACKCOLOR,D0 ;GET A LITTLE BLACK
|
|
MOVE.L D0,-(SP) ;AND SMACK IT ON THE STACK
|
|
_FORECOLOR ;SO OUR COPY'S BACK IN WHACK
|
|
|
|
MOVE.L SRCBITS(A6),-(SP) ;push source = caller's source
|
|
PEA 14(SP) ;push dst = our bitMap
|
|
MOVE.L SRCRECT(A6),-(SP) ;PUSH SRCRECT
|
|
MOVE.L (SP),-(SP) ;DSTRECT = SRCRECT
|
|
CLR -(SP) ;MODE = SRC COPY
|
|
btst #6,mode+1(a6) ;is the ditherCopy bit set
|
|
beq.s @noDither
|
|
move.w #$40,(sp) ;yes, use ditherCopy instead
|
|
@noDither CLR.L -(SP) ;NO MASKRGN
|
|
_COPYBITS ;COPY THE PIXMAP
|
|
|
|
MOVE.L SP,-(SP) ;POINT AT FORECOLOR
|
|
_RGBFORECOLOR ;RESTORE IT
|
|
ADDQ #6,SP ;STRIP FORECOLOR
|
|
MOVE.L (SP)+,PICSAVE(A3) ;RESTORE PICTURE STATE
|
|
|
|
MOVE.L SP,-(SP) ;PUSH SRCBITS
|
|
MOVE.L SRCRECT(A6),-(SP) ;PUSH SRCRECT
|
|
MOVE.L DSTRECT(A6),-(SP) ;PUSH DSTRECT
|
|
MOVE MODE(A6),-(SP) ;PUSH MODE
|
|
MOVE.L MASKRGN(A6),-(SP) ;PUSH MASKRGN (NIL OK)
|
|
MOVE.L GRAFPROCS(A3),D0 ;IS GRAFPROCS NIL ?
|
|
MOVE.L D0,A0
|
|
MOVE.L BITSPROC(A0),A0 ;NO, GET PROC PTR
|
|
JSR (A0) ;CALL IT
|
|
|
|
MOVE.L 14(SP),A0 ;get handle
|
|
_DisposHandle ;and dispose it
|
|
|
|
@Abort ADD #18,SP ;strip off bitMap, handle
|
|
MOVE.L (SP)+,A0 ;restore dstBits pointer
|
|
bra.s CLEANUP ;and return <PB302>
|
|
|
|
;
|
|
; CallBits(srcBits,srcRect,dstRect,mode,maskRgn)
|
|
;
|
|
|
|
@ProcOK
|
|
MOVE.L A2,-(SP) ;PUSH SRCBITS
|
|
MOVE.L SRCRECT(A6),-(SP) ;PUSH SRCRECT
|
|
MOVE.L DSTRECT(A6),-(SP) ;PUSH DSTRECT
|
|
MOVE MODE(A6),-(SP) ;PUSH MODE
|
|
MOVE.L MASKRGN(A6),-(SP) ;PUSH MASKRGN (NIL OK)
|
|
MOVE.L GRAFPROCS(A3),D0 ;IS GRAFPROCS NIL ?
|
|
MOVE.L JStdBits,A0 ;get piece of trap table
|
|
BEQ.S USESTD ;YES, USE STD PROC
|
|
MOVE.L D0,A0
|
|
MOVE.L BITSPROC(A0),A0 ;NO, GET PROC PTR
|
|
USESTD JSR (A0) ;CALL IT
|
|
|
|
CLEANUP CMP.L D6,D7 ;WAS SRC FROM THE SCREEN ?
|
|
BNE.S DONE ;NO, CONTINUE
|
|
_SHOWCURSOR ;YES, REPLACE CURSOR
|
|
DONE MOVEM.L (SP)+,d2/D6-D7/A2-A4 ;RESTORE REGS
|
|
UNLINK PARAMSIZE,'COPYBITS'
|
|
|
|
|
|
GoDevLoop PROC EXPORT
|
|
;---------------------------------------------------------------
|
|
;
|
|
; PROCEDURE GoDevLoop( VAR srcBits: BitMap;
|
|
; VAR srcRect: Rect;
|
|
; VAR dstRect: Rect;
|
|
; mode: INTEGER;
|
|
; maskRgn: RgnHandle);
|
|
;
|
|
; This is a mock version of StdBits used for calling DevLoop
|
|
; for transfers from multiple screen devices.
|
|
|
|
; A4 = QUICKDRAW GLOBALS
|
|
; A3 = THEPORT
|
|
; A1 = DSTBITS
|
|
|
|
; A6 OFFSETS OF PARAMS AFTER LINK:
|
|
;
|
|
PARAMSIZE EQU 18
|
|
SRCBITS EQU PARAMSIZE+8-4 ;LONG, ADDR OF BITMAP
|
|
SRCRECT EQU SRCBITS-4 ;LONG, ADDR OF RECT
|
|
DSTRECT EQU SRCRECT-4 ;LONG, ADDR OF RECT
|
|
MODE EQU DSTRECT-2 ;WORD
|
|
MASKRGN EQU MODE-4 ;LONG, RGNHANDLE
|
|
|
|
; SRC DEVICE RECORDS STORED ON STACK
|
|
|
|
FLAG EQU 0 ;OFFSET TO FLAG
|
|
DEV EQU FLAG+2 ;OFFSET TO DEVICE
|
|
RECT EQU DEV+4 ;OFFSET TO RECT
|
|
SIZE EQU RECT+8 ;SIZE OF RECORD
|
|
|
|
SRCPIX EQU -(PMREC+CTREC+20) ;PIXMAP + COLOR TABLE
|
|
TEMPPIX EQU SRCPIX-PMREC ;PIXMAP
|
|
DSTBITS EQU TEMPPIX-4 ;DST BITMAP
|
|
GLOBALSRC EQU DSTBITS-8 ;GLOBAL COPY OF SRC RECT
|
|
GLOBALDST EQU GLOBALSRC-8 ;GLOBAL COPY OF DST RECT
|
|
SRCRECT1 EQU GLOBALDST-8 ;LOCAL COPY OF SRC RECT
|
|
DSTRECT1 EQU SRCRECT1-8 ;LOCAL COPY OF DST RECT (MUST FOLLOW SRCRECT1)
|
|
RECT1 EQU DSTRECT1-8 ;RESULT OF INTERSECTION
|
|
DEFSRC EQU RECT1-SIZE ;DEFAULT SRC RECORD
|
|
ENDSRC EQU DEFSRC-4 ;0 FOR TERMINATING SRC LIST
|
|
SRCDEV EQU ENDSRC-4 ;CURRENT SRC DEVICE RECORD
|
|
ENDDST EQU SRCDEV-4 ;0 FOR TERMINATING DST LIST
|
|
DSTDEV EQU ENDDST-4 ;CURRENT DST DEVICE
|
|
SRCLIST EQU DSTDEV-4 ;POINTER TO SORTED SRC RECT LIST
|
|
DSTLIST EQU SRCLIST-4 ;POINTER TO SORTED DST RECT LIST
|
|
SAVEDSP EQU DSTLIST-4 ;SAVED STACK POINTER
|
|
LASTSEED EQU SAVEDSP-4 ;LAST COLOR TABLE SEED
|
|
SAVEFG EQU LASTSEED-4 ;ORIGINAL FG COLOR
|
|
SAVEBK EQU SAVEFG-4 ;ORIGINAL BK COLOR
|
|
SAVEHILITE EQU SAVEBK-2 ;SAVED HILITE MODE FLAG
|
|
RGNA EQU SAVEHILITE-4 ;FIRST REGION FOR CLIPPING
|
|
RGNB EQU RGNA-4 ;SECOND REGION FOR CLIPPING
|
|
MASKBITS EQU RGNB-4 ;BITMAP FOR MASK
|
|
MASKRECT EQU MASKBITS-4 ;LONG, ADDR OF MASK RECT
|
|
VARSIZE EQU MASKRECT ;TOTAL SIZE OF LOCALS
|
|
|
|
|
|
LINK A6,#VARSIZE ;ALLOCATE STDBITS STACK FRAME
|
|
MOVEM.L D3-D7,-(SP) ;SAVE REGISTERS
|
|
MOVE.L A1,DSTBITS(A6) ;SET UP DSTBITS
|
|
MOVE.L WIDEOPEN(A4),RGNA(A6) ;SET FIRST REGION TO WIDEOPEN
|
|
MOVE.L WIDEOPEN(A4),RGNB(A6) ;SET SECOND REGION TO WIDEOPEN
|
|
CLR.L MASKBITS(A6) ;NO MASK BITMAP
|
|
CLR.L MASKRECT(A6) ;NO MASK RECTANGLE
|
|
_BitsDevLoop ;DRAW TO ALL DEVICES
|
|
MOVEM.L (SP)+,D3-D7 ;RESTORE REGISTERS
|
|
UNLINK PARAMSIZE,'GODEVLOO'
|
|
|
|
|
|
|
|
CopyCIcon PROC EXPORT
|
|
EXPORT CopyMask
|
|
IMPORT PORTTOMAP,BITSTOMAP,CMDevLoop
|
|
;--------------------------------------------------------------
|
|
;
|
|
; PROCEDURE CopyCIcon(srcBits,maskBits,dstBits: BitMap;
|
|
; srcRect,maskRect,dstRect: Rect);
|
|
;
|
|
; Same as CopyMask but accepts another clipping region in A0
|
|
;
|
|
bra.s share
|
|
|
|
|
|
;--------------------------------------------------------------
|
|
;
|
|
; PROCEDURE CopyMask(srcBits,maskBits,dstBits: BitMap;
|
|
; srcRect,maskRect,dstRect: Rect);
|
|
;
|
|
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
|
;
|
|
PARAMSIZE EQU 24 ;total bytes of params
|
|
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
|
|
|
|
VARSIZE EQU 0
|
|
|
|
CopyMask
|
|
sub.l a0,a0 ;remember no maskrgn
|
|
share LINK A6,#VARSIZE ;ALLOCATE STACK FRAME
|
|
MOVEM.L D3-D7/A2-A4,-(SP) ;SAVE WORK REGISTERS FOR DEVLOOP
|
|
|
|
; SET UP REGISTERS FOR CALLING CMDEVLOOP
|
|
|
|
MOVE.L DSTBITS(A6),A1 ;GET DST BIT/PIXMAP
|
|
MOVE.L MASKBITS(A6),D0 ;GET MASK BIT/PIXMAP
|
|
MOVE.L MASKRECT(A6),D1 ;GET MASK RECTANGLE
|
|
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
|
|
MOVE.L THEPORT(A4),A3 ;GET THE PORT IN A3 FOR DEVLOOP
|
|
MOVE.L WIDEOPEN(A4),D2 ;ASSUME NO CLIPPING FOR FIRST RGN
|
|
MOVE.L D2,D3 ;ASSUME NO CLIPPING FOR SECOND RGN
|
|
|
|
; PUSH PARAMETERS FOR CALLING CMDEVLOOP (SAME AS STDBITS)
|
|
|
|
MOVE.L SRCBITS(A6),-(SP) ;PUSH SRC BIT/PIXMAP
|
|
MOVE.L SRCRECT(A6),-(SP) ;PUSH SRC RECTANGLE
|
|
MOVE.L DSTRECT(A6),-(SP) ;PUSH DST RECTANGLE
|
|
CLR -(SP) ;SRC COPY MODE
|
|
MOVE.L D2,-(SP) ;MASKRGN = WIDEOPEN
|
|
tst.l a0 ;a real maskRgn?
|
|
beq.s srcOK ;no, skip it
|
|
move.l a0,(sp) ;yes, overwrite wideOpen
|
|
|
|
;-----------------------------------------------------
|
|
;
|
|
; TEST IF DST IS TO THEPORT, (IF SO WE CLIP)
|
|
;
|
|
SRCOK MOVE.L DSTBITS(A6),A0 ;POINT TO DSTBITS
|
|
_BITSTOMAP ;GET POINTER TO BIT/PIXMAP IN A0
|
|
MOVE.L A0,A1 ;SAVE IN A1
|
|
MOVE.L A3,D4 ;IS THEPORT NIL ?
|
|
BEQ.S NOTPORT ;YES, NOT TO THEPORT
|
|
BTST #0,D4 ;IS THEPORT ODD ?
|
|
BNE.S NOTPORT ;YES, NOT TO THEPORT
|
|
MOVE.L D4,A0 ;GET THEPORT
|
|
_PORTTOMAP ;CONVERT PORT TO BIT/PIXMAP
|
|
MOVE.L BASEADDR(A0),D4 ;GET PORTBITS.BASEADDR
|
|
CMP.L BASEADDR(A1),D4 ;IS DST BASEADDR SAME ?
|
|
BNE.S NOTPORT ;NO, NOT TO THEPORT
|
|
MOVE.L BOUNDS(A0),D4 ;GET PORT BOUNDS TOPLEFT
|
|
CMP.L BOUNDS(A1),D4 ;IS BOUNDS TOPLEFT SAME ?
|
|
BNE.S NOTPORT ;=>NO, NOT TO THE PORT
|
|
|
|
MOVE.L CLIPRGN(A3),D2 ;YES, CLIP TO CLIPRGN
|
|
MOVE.L VISRGN(A3),D3 ;AND TO VISRGN
|
|
|
|
NOTPORT MOVE.L DSTBITS(A6),A1 ;Pass DSTBITS (not derefed) <BAL 28May89>
|
|
JSR CMDevLoop ;AND DRAW THE IMAGE
|
|
|
|
MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE WORK REGISTERS
|
|
UNLINK PARAMSIZE,'CopyMask'
|
|
|
|
KopyMask PROC EXPORT
|
|
IMPORT PORTTOMAP,BITSTOMAP,CMDevLoop
|
|
|
|
;--------------------------------------------------------------
|
|
;
|
|
; PROCEDURE KopyMask(srcBits,maskBits,dstBits: BitMap;
|
|
; srcRect,maskRect,dstRect: Rect;
|
|
; mode: INTEGER;
|
|
; maskRgn: RgnHandle *);
|
|
;
|
|
; A6 OFFSETS OF PARAMETERS AFTER LINK:
|
|
;
|
|
PARAMSIZE EQU 30 ;total bytes of params
|
|
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
|
|
MASKRGN EQU MODE-4 ;LONG, RGNHANDLE
|
|
|
|
VARSIZE EQU 0
|
|
|
|
share LINK A6,#VARSIZE ;ALLOCATE STACK FRAME
|
|
MOVEM.L D3-D7/A2-A4,-(SP) ;SAVE WORK REGISTERS FOR DEVLOOP
|
|
|
|
; SET UP REGISTERS FOR CALLING CMDEVLOOP
|
|
|
|
MOVE.L DSTBITS(A6),A1 ;GET DST BIT/PIXMAP
|
|
MOVE.L MASKBITS(A6),D0 ;GET MASK BIT/PIXMAP
|
|
MOVE.L MASKRECT(A6),D1 ;GET MASK RECTANGLE
|
|
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
|
|
MOVE.L THEPORT(A4),A3 ;GET THE PORT IN A3 FOR DEVLOOP
|
|
MOVE.L WIDEOPEN(A4),D2 ;ASSUME NO CLIPPING FOR FIRST RGN
|
|
MOVE.L D2,D3 ;ASSUME NO CLIPPING FOR SECOND RGN
|
|
|
|
; PUSH PARAMETERS FOR CALLING CMDEVLOOP (SAME AS STDBITS)
|
|
|
|
MOVE.L SRCBITS(A6),-(SP) ;PUSH SRC BIT/PIXMAP
|
|
MOVE.L SRCRECT(A6),-(SP) ;PUSH SRC RECTANGLE
|
|
MOVE.L DSTRECT(A6),-(SP) ;PUSH DST RECTANGLE
|
|
MOVE MODE(A6),-(SP) ;PUSH MODE
|
|
MOVE.L MASKRGN(A6),-(SP) ;PUSH MASKRGN
|
|
BNE.S MASKOK ;WAS IT NIL ?
|
|
MOVE.L D2,(SP) ;YES, REPLACE WITH WIDEOPEN
|
|
MASKOK
|
|
|
|
;-----------------------------------------------------
|
|
;
|
|
; TEST IF DST IS TO THEPORT, (IF SO WE CLIP)
|
|
;
|
|
|
|
SRCOK MOVE.L DSTBITS(A6),A0 ;POINT TO DSTBITS
|
|
_BITSTOMAP ;GET POINTER TO BIT/PIXMAP IN A0
|
|
MOVE.L A0,A1 ;SAVE IN A1
|
|
MOVE.L A3,D4 ;IS THEPORT NIL ?
|
|
BEQ.S NOTPORT ;YES, NOT TO THEPORT
|
|
BTST #0,D4 ;IS THEPORT ODD ?
|
|
BNE.S NOTPORT ;YES, NOT TO THEPORT
|
|
MOVE.L D4,A0 ;GET THEPORT
|
|
_PORTTOMAP ;CONVERT PORT TO BIT/PIXMAP
|
|
MOVE.L BASEADDR(A0),D4 ;GET PORTBITS.BASEADDR
|
|
CMP.L BASEADDR(A1),D4 ;IS DST BASEADDR SAME ?
|
|
BNE.S NOTPORT ;NO, NOT TO THEPORT
|
|
MOVE.L BOUNDS(A0),D4 ;GET PORT BOUNDS TOPLEFT
|
|
CMP.L BOUNDS(A1),D4 ;IS BOUNDS TOPLEFT SAME ?
|
|
BNE.S NOTPORT ;=>NO, NOT TO THE PORT
|
|
|
|
MOVE.L CLIPRGN(A3),D2 ;YES, CLIP TO CLIPRGN
|
|
MOVE.L VISRGN(A3),D3 ;AND TO VISRGN
|
|
|
|
NOTPORT MOVE.L DSTBITS(A6),A1 ;Pass DSTBITS (not derefed) <BAL 28May89>
|
|
JSR CMDevLoop ;AND DRAW THE IMAGE
|
|
|
|
MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE WORK REGISTERS
|
|
UNLINK PARAMSIZE,'KopyMask'
|
|
|
|
|
|
|
|
CMDevLoop PROC EXPORT
|
|
;---------------------------------------------------------------
|
|
;
|
|
; PROCEDURE CMDevLoop( VAR srcBits: BitMap;
|
|
; VAR srcRect: Rect;
|
|
; VAR dstRect: Rect;
|
|
; mode: INTEGER;
|
|
; maskRgn: RgnHandle);
|
|
;
|
|
; This is a mock version of StdBits used for calling DevLoop
|
|
; for transfers to multiple screen devices.
|
|
|
|
; A4 = QUICKDRAW GLOBALS
|
|
; A3 = THEPORT
|
|
; A1 = DSTBITS
|
|
|
|
; A6 OFFSETS OF PARAMS AFTER LINK:
|
|
;
|
|
PARAMSIZE EQU 18
|
|
SRCBITS EQU PARAMSIZE+8-4 ;LONG, ADDR OF BITMAP
|
|
SRCRECT EQU SRCBITS-4 ;LONG, ADDR OF RECT
|
|
DSTRECT EQU SRCRECT-4 ;LONG, ADDR OF RECT
|
|
MODE EQU DSTRECT-2 ;WORD
|
|
MASKRGN EQU MODE-4 ;LONG, RGNHANDLE
|
|
|
|
; SRC DEVICE RECORDS STORED ON STACK
|
|
|
|
FLAG EQU 0 ;OFFSET TO FLAG
|
|
DEV EQU FLAG+2 ;OFFSET TO DEVICE
|
|
RECT EQU DEV+4 ;OFFSET TO RECT
|
|
SIZE EQU RECT+8 ;SIZE OF RECORD
|
|
|
|
SRCPIX EQU -(PMREC+CTREC+20) ;PIXMAP + COLOR TABLE
|
|
TEMPPIX EQU SRCPIX-PMREC ;PIXMAP
|
|
DSTBITS EQU TEMPPIX-4 ;DST BITMAP
|
|
GLOBALSRC EQU DSTBITS-8 ;GLOBAL COPY OF SRC RECT
|
|
GLOBALDST EQU GLOBALSRC-8 ;GLOBAL COPY OF DST RECT
|
|
SRCRECT1 EQU GLOBALDST-8 ;LOCAL COPY OF SRC RECT
|
|
DSTRECT1 EQU SRCRECT1-8 ;LOCAL COPY OF DST RECT (MUST FOLLOW SRCRECT1)
|
|
RECT1 EQU DSTRECT1-8 ;RESULT OF INTERSECTION
|
|
DEFSRC EQU RECT1-SIZE ;DEFAULT SRC RECORD
|
|
ENDSRC EQU DEFSRC-4 ;0 FOR TERMINATING SRC LIST
|
|
SRCDEV EQU ENDSRC-4 ;CURRENT SRC DEVICE RECORD
|
|
ENDDST EQU SRCDEV-4 ;0 FOR TERMINATING DST LIST
|
|
DSTDEV EQU ENDDST-4 ;CURRENT DST DEVICE
|
|
SRCLIST EQU DSTDEV-4 ;POINTER TO SORTED SRC RECT LIST
|
|
DSTLIST EQU SRCLIST-4 ;POINTER TO SORTED DST RECT LIST
|
|
SAVEDSP EQU DSTLIST-4 ;SAVED STACK POINTER
|
|
LASTSEED EQU SAVEDSP-4 ;LAST COLOR TABLE SEED
|
|
SAVEFG EQU LASTSEED-4 ;ORIGINAL FG COLOR
|
|
SAVEBK EQU SAVEFG-4 ;ORIGINAL BK COLOR
|
|
SAVEHILITE EQU SAVEBK-2 ;SAVED HILITE MODE FLAG
|
|
RGNA EQU SAVEHILITE-4 ;FIRST REGION FOR CLIPPING
|
|
RGNB EQU RGNA-4 ;SECOND REGION FOR CLIPPING
|
|
MASKBITS EQU RGNB-4 ;BITMAP FOR MASK
|
|
MASKRECT EQU MASKBITS-4 ;LONG, ADDR OF MASK RECT
|
|
VARSIZE EQU MASKRECT ;TOTAL SIZE OF LOCALS
|
|
|
|
|
|
LINK A6,#VARSIZE ;ALLOCATE STDBITS STACK FRAME
|
|
MOVE.L A1,DSTBITS(A6) ;SET UP DSTBITS
|
|
MOVE.L D0,MASKBITS(A6) ;SET UP MASKBITS
|
|
MOVE.L D1,MASKRECT(A6) ;SET UP MASKRECT
|
|
MOVE.L D2,RGNA(A6) ;SET FIRST REGION TO WIDEOPEN
|
|
MOVE.L D3,RGNB(A6) ;SET SECOND REGION TO WIDEOPEN
|
|
_BitsDevLoop ;DRAW TO ALL DEVICES
|
|
UNLINK PARAMSIZE,'GODEVLOO'
|
|
|
|
|
|
|
|
SeedFill PROC EXPORT
|
|
EXPORT CalcMask
|
|
;-------------------------------------------------------------------------
|
|
;
|
|
; PROCEDURE SeedFill(srcPtr,dstPtr: Ptr;
|
|
; srcRow,dstRow,height,words: INTEGER;
|
|
; seedH,seedV: INTEGER)
|
|
;
|
|
MOVE.L (SP)+,A0 ;pop return addr
|
|
MOVEQ #-1,D0 ;get a long of -1
|
|
MOVE.L D0,-(SP) ;push edge = all ones
|
|
BRA.S SHARE ;share common code
|
|
|
|
|
|
;-------------------------------------------------------------------------
|
|
;
|
|
; PROCEDURE CalcMask(srcPtr,dstPtr: Ptr;
|
|
; srcRow,dstRow,height,words: INTEGER);
|
|
;
|
|
CalcMask MOVE.L (SP)+,A0 ;pop return addr
|
|
MOVEQ #-1,D0 ;get a long of -1
|
|
MOVE.L D0,-(SP) ;push seed = (-1,-1)
|
|
CLR.L -(SP) ;push edge = zeros
|
|
SHARE MOVE.L A0,-(SP) ;restore return addr
|
|
|
|
|
|
|
|
;-------------------------------------------------------------------------
|
|
;
|
|
; LOCAL PROCEDURE MakeMask(srcPtr,dstPtr: Ptr;
|
|
; srcRow,dstRow,height,words: INTEGER;
|
|
; seedH,seedV: INTEGER;
|
|
; edge: LongInt);
|
|
;
|
|
; A6 OFFSETS OF PARAMS AND LOCALS AFTER LINK:
|
|
;
|
|
PARAMSIZE EQU 24
|
|
srcPtr EQU PARAMSIZE+8-4 ;long
|
|
dstPtr EQU srcPtr-4 ;long
|
|
srcRow EQU dstPtr-2 ;word
|
|
dstRow EQU srcRow-2 ;word
|
|
height EQU dstRow-2 ;word
|
|
words EQU height-2 ;word
|
|
seedH EQU words-2 ;word
|
|
seedV EQU seedH-2 ;word
|
|
edge EQU seedV-4 ;long
|
|
|
|
|
|
dstBump EQU -2 ;word
|
|
saveStk EQU dstBump-4 ;long
|
|
varSize EQU saveStk ;total locals
|
|
|
|
|
|
LINK A6,#varSize ;allocate stack frame
|
|
MOVEM.L D3-D7/A2-A4,-(SP) ;save regs
|
|
MOVE.L SP,saveStk(A6) ;save stack pointer
|
|
|
|
;
|
|
; prepare height and words for DBRA count. Quit if either <= 0.
|
|
;
|
|
MOVE words(A6),D5 ;get count of words
|
|
BLE GOHOME ;quit if words <= 0
|
|
SUB #1,D5 ;subtract 1 for DBRA count
|
|
SUB #1,height(A6) ;convert height to DBRA
|
|
BLT GOHOME ;quit if height <= 0
|
|
|
|
;
|
|
; init dst to all ones:
|
|
;
|
|
MOVE words(A6),D0 ;get # of words
|
|
ADD D0,D0 ;double for bytes
|
|
MOVE dstRow(A6),D1 ;get dstRow
|
|
SUB D0,D1 ;subtract bytes for dstBump
|
|
MOVE D1,dstBump(A6) ;save dstBump for later
|
|
MOVE.L dstPtr(A6),A2 ;point to dst
|
|
MOVEQ #-1,D0 ;get some black
|
|
MOVE height(A6),D3 ;init DBRA rowCount
|
|
BLACK1 MOVE D5,D2 ;init DBRA wordCount
|
|
BLACK2 MOVE D0,(A2)+ ;put a word of black
|
|
DBRA D2,BLACK2 ;loop all words in row
|
|
ADD D1,A2 ;bump to next row
|
|
DBRA D3,BLACK1 ;loop height rows
|
|
|
|
;
|
|
; clear one dst pixel at seedH,seedV
|
|
;
|
|
MOVE seedV(A6),D0 ;get seed vert coord
|
|
BLT.S NOSEED ;skip if neg (no seed)
|
|
MULU dstRow(A6),D0 ;mul times dst row
|
|
MOVE.L dstPtr(A6),A0 ;point to dst
|
|
ADD.L D0,A0 ;add vertical offset <EHB 28-Oct-85>
|
|
MOVE seedH(A6),D0 ;get seed horiz coord
|
|
MOVE D0,D1 ;copy seedH
|
|
ASR #3,D0 ;div by 8 for byte
|
|
NOT D1 ;invert bit number
|
|
BCLR D1,0(A0,D0) ;clear seed pixel
|
|
NOSEED
|
|
;
|
|
; allocate a scanline buffer of ones or zeros on the stack:
|
|
;
|
|
MOVE.L edge(A6),D6 ;get zero or all ones
|
|
MOVE D5,D1 ;get longCount
|
|
NEXTBUF MOVE D6,-(SP) ;write a word of ones or zeros
|
|
DBRA D1,NEXTBUF ;loop all words
|
|
|
|
MOVE.L srcPtr(A6),A0 ;point to top of src
|
|
MOVE.L dstPtr(A6),A2 ;point to top of dst
|
|
st d7 ;set dirty flag to force <KON 24JAN91>
|
|
bra.s FirstPass ;search up and down <KON 24JAN91>
|
|
NXTPASS SF D7 ;clear dirty flag
|
|
FirstPass
|
|
MOVE height(A6),D4 ;get DBRA rowCount
|
|
MOVE.L SP,A1 ;point dst above to edgeBuf
|
|
|
|
;
|
|
; smear dst zeros down and to the right, smear limited by src.
|
|
;
|
|
NEXTROW MOVE.L D6,D1 ;init prev dst to edge
|
|
MOVE D5,D3 ;get DBRA wordCount
|
|
RNEXT MOVE (A2),D1 ;get dst word
|
|
BNE.S RDSTOK ;is it already zero ?
|
|
ADD #2,A0 ;yes, bump srcPtr
|
|
ADD #2,A1 ;bump dstAbove ptr
|
|
ADD #2,A2 ;bump dst ptr
|
|
SWAP D1 ;put prev dst in hi word
|
|
DBRA D3,RNEXT ;loop all words in row
|
|
BRA.S RDONE ;and continue below
|
|
RDSTOK MOVE (A0)+,D2 ;get src word
|
|
AND (A1)+,D1 ;smear zeros down
|
|
OR D2,D1 ;limit vertical smear by src
|
|
BRA.S RSTART ;go to loop start
|
|
RMORE MOVE D0,D1 ;update dst
|
|
RSTART MOVE.L D1,D0 ;copy dst and prev dst word
|
|
LSR.L #1,D0 ;shift right with carry from prev
|
|
AND D1,D0 ;smear zeros to the right
|
|
OR D2,D0 ;limit smear by src
|
|
CMP D1,D0 ;any changes ?
|
|
BNE RMORE ;yes, keep smearing
|
|
CMP (A2),D1 ;has dst changed ?
|
|
BEQ.S RSAME ;no, leave it alone
|
|
ST D7 ;yes, set dirty flag
|
|
RSAME MOVE D1,(A2)+ ;write dst to memory
|
|
SWAP D1 ;put prev dst in hi word
|
|
DBRA D3,RNEXT ;loop all words in row
|
|
RDONE
|
|
|
|
|
|
;
|
|
; smear dst zeros down and to the left, smear limited by src.
|
|
;
|
|
LSMEAR MOVE.L D6,D1 ;init prev dst to edge
|
|
MOVE D5,D3 ;get DBRA wordCount
|
|
LNEXT MOVE -(A2),D1 ;get dst word
|
|
BNE.S LDSTOK ;is dst already zero ?
|
|
SUB #2,A0 ;yes, just bump srcPtr
|
|
SUB #2,A1 ;bump dstAbove ptr
|
|
SWAP D1 ;put prev dst in hi word
|
|
DBRA D3,LNEXT ;loop all words in row
|
|
BRA.S LDONE ;and continue
|
|
LDSTOK MOVE -(A0),D2 ;get src word
|
|
AND -(A1),D1 ;smear zeros down
|
|
OR D2,D1 ;limit vertical smear by src
|
|
BRA.S LSTART ;go to loop start
|
|
LMORE MOVE D0,D1 ;update dst
|
|
LSTART MOVE.L D1,D0 ;copy dst and prev dst word
|
|
ROL.L #1,D0 ;shift left with carry from prev
|
|
AND D1,D0 ;smear zeros to the left
|
|
OR D2,D0 ;limit smear by src
|
|
CMP D1,D0 ;any changes ?
|
|
BNE LMORE ;yes, keep smearing
|
|
CMP (A2),D1 ;has dst changed ?
|
|
BEQ.S LSAME ;no, leave it alone
|
|
ST D7 ;yes, set dirty flag
|
|
MOVE D1,(A2) ;write dst to memory
|
|
LSAME SWAP D1 ;put prev dst in hi word
|
|
DBRA D3,LNEXT ;loop all words in row
|
|
LDONE
|
|
;
|
|
; bump three pointers down and loop for height scanlines
|
|
;
|
|
ADD srcRow(A6),A0 ;bump srcPtr down a row
|
|
ADD dstRow(A6),A2 ;bump dstPtr down a row
|
|
MOVE.L A2,A1 ;copy dstPtr
|
|
SUB dstRow(A6),A1 ;point to dst above
|
|
DBRA D4,NEXTROW ;loop all rows
|
|
;
|
|
; switch directions, adjust pointers, and loop till no change
|
|
;
|
|
NEG srcRow(A6) ;reverse src bump
|
|
NEG dstRow(A6) ;reverse dst bump
|
|
ADD srcRow(A6),A0 ;offset first src scanline
|
|
ADD dstRow(A6),A2 ;offset first dst scanline
|
|
TST.B D7 ;did anything change this pass ?
|
|
BNE NXTPASS ;yes go for another pass
|
|
;
|
|
; if seedFill, then invert dst
|
|
;
|
|
TST D6 ;is edge = black ?
|
|
BPL.S GOHOME ;no, we're done
|
|
MOVE dstBump(A6),D1 ;get dstBump
|
|
MOVE.L dstPtr(A6),A2 ;point to dst
|
|
MOVE height(A6),D3 ;init DBRA rowCount
|
|
INVERT1 MOVE D5,D2 ;init DBRA wordCount
|
|
INVERT2 NOT (A2)+ ;invert a word of dst
|
|
DBRA D2,INVERT2 ;loop all words in row
|
|
ADD D1,A2 ;bump to next row
|
|
DBRA D3,INVERT1 ;loop height rows
|
|
|
|
GOHOME MOVE.L saveStk(A6),SP ;restore stack pointer
|
|
MOVEM.L (SP)+,D3-D7/A2-A4 ;restore regs
|
|
UNLINK PARAMSIZE,'SEEDFILL'
|
|
|
|
|
|
|
|
|
|
ScrollRect PROC EXPORT
|
|
;---------------------------------------------------------------------
|
|
;
|
|
; PROCEDURE ScrollRect(srcRect: Rect; dh,dv: INTEGER; updateRgn: RgnHandle);
|
|
;
|
|
; Scroll a rectangular block of bits, erase and return an update region
|
|
; If the update region is nil, don't erase it.
|
|
;
|
|
; A6 OFFSETS OF PARAMS AND LOCALS AFTER LINK:
|
|
;
|
|
; as taken verbatim from QDciPatchROM.a <sm 6/9/92>stb
|
|
|
|
PARAMSIZE EQU 12 ;TOTAL BYTES OF PARAMS
|
|
SRCRECT EQU PARAMSIZE+8-4 ;LONG, ADDR OF RECT
|
|
DH EQU SRCRECT-2 ;WORD
|
|
DV EQU DH-2 ;WORD
|
|
THEUPDATERGN EQU DV-4 ;LONG, RGNHANDLE
|
|
|
|
DSTRECT EQU -8 ;RECT
|
|
tempRect1 EQU DSTRECT-8 ;rect
|
|
tempRect2 EQU tempRect1-8 ;rect
|
|
globalSrc EQU tempRect2-8 ;rect
|
|
VARSIZE EQU globalSrc ;TOTAL LOCALS
|
|
|
|
|
|
LINK A6,#VARSIZE ;ALLOCATE STACK FRAME
|
|
MOVEM.L D6-D7/A3-A4,-(SP) ;SAVE REGS
|
|
MOVE.L GRAFGLOBALS(A5),A4 ;POINT TO QUICKDRAW GLOBALS
|
|
MOVE.L THEPORT(A4),A3 ;POINT TO CURRENT GRAFPORT
|
|
MOVE.L PICSAVE(A3),-(SP) ;SAVE PICSAVE HANDLE
|
|
CLR.L PICSAVE(A3) ;DON'T RECORD TO PICTURES
|
|
|
|
TST PNVIS(A3) ;IS PNVIS < 0 ?
|
|
BLT ABORT ;YES, QUIT FAST
|
|
TST.L DV(A6) ;ARE DH AND DV BOTH 0 ?
|
|
BEQ ABORT ;YES, QUIT FAST
|
|
|
|
; SAVE FOREGROUND AND BACKGROUND COLORS, AND SET TO BLACK AND WHITE FOR SCROLL
|
|
|
|
|
|
sub.l #ColorSpecSize,sp ;make room for an ColorSpec <DDG 28Jan90>
|
|
move.l sp,-(sp) ;point to this record
|
|
_SaveFore
|
|
sub.l #ColorSpecSize,sp ;make room for an ColorSpec <DDG 28Jan90>
|
|
move.l sp,-(sp) ;point to this record
|
|
_SaveBack
|
|
|
|
MOVE.L #BLACKCOLOR,-(SP) ;PUSH BLACK
|
|
_FORECOLOR ;AND SET FOREGROUND COLOR TO BLACK
|
|
MOVE.L #WHITECOLOR,-(SP) ;PUSH WHITE
|
|
_BACKCOLOR ;AND SET BACKGROUND COLOR TO BLACK
|
|
|
|
; ALLOCATE TEMP REGIONS FOR CALCULATIONS
|
|
|
|
SUB #8,SP ;ROOM FOR 2 FCN RESULT
|
|
_NEWRGN ;ALLOCATE SRCRGN
|
|
MOVE.L (SP)+,D7 ;GET SRCRGN IN D7
|
|
_NEWRGN ;ALLOCATE DSTRGN
|
|
MOVE.L (SP)+,D6 ;GET DSTRGN IN D6
|
|
|
|
; srcRgn := srcRect SECT visRgn SECT clipRgn
|
|
|
|
MOVE.L D7,-(SP) ;PUSH SRCRGN
|
|
MOVE.L SRCRECT(A6),-(SP) ;PUSH SRCRECT
|
|
_RECTRGN ;RectRgn(srcRgn,srcRect);
|
|
|
|
MOVE.L D7,-(SP) ;PUSH SRCRGN
|
|
MOVE.L VISRGN(A3),-(SP) ;PUSH VISRGN
|
|
MOVE.L D7,-(SP) ;PUSH SRCRGN
|
|
_SECTRGN ;SectRgn(srcRgn,visRgn,srcRgn);
|
|
|
|
MOVE.L D7,-(SP) ;PUSH SRCRGN
|
|
MOVE.L CLIPRGN(A3),-(SP) ;PUSH CLIPRGN
|
|
MOVE.L D7,-(SP) ;PUSH SRCRGN
|
|
_SECTRGN ;SectRgn(srcRgn,clipRgn,srcRgn);
|
|
|
|
; dstRgn := offset srcRgn
|
|
|
|
MOVE.L D7,-(SP) ;PUSH SRCRGN
|
|
MOVE.L D6,-(SP) ;PUSH DSTRGN
|
|
_COPYRGN ;CopyRgn(srcRgn,dstRgn);
|
|
MOVE.L D6,-(SP) ;PUSH DSTRGN
|
|
MOVE.L DV(A6),-(SP) ;PUSH DH,DV
|
|
_OFSETRGN ;OffsetRgn(dstRgn,dh,dv);
|
|
|
|
; DSTRECT := OFFSETRECT(SRCRECT,DH,DV)
|
|
|
|
MOVE.L SRCRECT(A6),A0 ;POINT TO SRCRECT
|
|
MOVE.L (A0)+,DSTRECT(A6) ;COPY SRCRECT INTO DSTRECT
|
|
MOVE.L (A0)+,DSTRECT+4(A6)
|
|
MOVE.L DV(A6),D0 ;GET DH,DV
|
|
ADD D0,DSTRECT+LEFT(A6) ;OFFSET DSTRECT (DH,DV)
|
|
ADD D0,DSTRECT+RIGHT(A6)
|
|
SWAP D0 ;GET DV IN LO WORD
|
|
ADD D0,DSTRECT+TOP(A6)
|
|
ADD D0,DSTRECT+BOTTOM(A6)
|
|
|
|
; MASKRGN := SECTRGN(SRCRGN,DSTRGN)
|
|
; NOTE: UPDATERGN CAN'T BE USED AS MASKRGN BECAUSE IF UPDATERGN = VISRGN
|
|
; THEN NOTHING WILL BE SCROLLED
|
|
|
|
MOVE.L D7,-(SP) ;PUSH SRCRGN
|
|
MOVE.L D6,-(SP) ;PUSH DSTRGN
|
|
MOVE.L D6,-(SP) ;KEEP MASKRGN
|
|
_SECTRGN ;SectRgn(srcRgn,dstRgn,maskRgn);
|
|
|
|
|
|
;----------------------------------------------------------------------------------------------------
|
|
;
|
|
; Now we check for multiple devices and do the correct things here <DDG 28Jan90>
|
|
;
|
|
|
|
move.l DeviceList,a0 ;get the head of the device list <DDG 28Jan90>
|
|
move.l (a0),a0 ;deref it
|
|
move.l GDNextGD(a0),d0 ;check the next device field. If it's zero
|
|
beq oneDevice ;..then goto one device
|
|
|
|
;
|
|
; Allocate extra region used by cutOutDevices
|
|
;
|
|
movem.l d5/a2,-(sp) ;save reg.
|
|
clr.l -(sp) ;make room for result
|
|
_NewRgn ;allocate another RGN <DDG 28Jan90>
|
|
move.l (sp)+,d5 ;put our new region in d5
|
|
|
|
;
|
|
; convert the source rect to global coordinates
|
|
;
|
|
|
|
move.l srcRect(a6),a1 ;point to our source rect
|
|
lea globalSrc(a6),a0 ;point to out global source rect
|
|
move.l (a1)+,topleft(a0) ;copy srcRect.topleft
|
|
move.l (a1)+,botright(a0) ;copy srcRect.botRight
|
|
pea topleft(a0) ;convert the global rect to global coordinates
|
|
_LocalToGlobal
|
|
pea botright(a0)
|
|
_LocalToGlobal
|
|
|
|
;
|
|
; Start scanning through the device list
|
|
;
|
|
|
|
move.l DeviceList,a2 ;get the device list header into A2
|
|
|
|
@loop move.l (a2),a4 ;deref the current device list handle
|
|
tst GDFlags(a4) ;is the device active ?
|
|
bpl.s @next ;=>no, skip to the next device
|
|
|
|
clr.b -(sp) ;make space for boolean result
|
|
pea globalSrc(a6) ;pointer to the SrcRect in global coordinates
|
|
pea GDRect(a4) ;pointer to the device rect
|
|
pea tempRect1(a6) ;pointer to the result
|
|
_SectRect ;get the intersection
|
|
tst.b (sp)+ ;if they didn't intersect at all, then skip to
|
|
beq.s @next ;..the next device
|
|
|
|
move.l DV(a6),d0 ;get DV into high word and DH into low word
|
|
add d0,tempRect1+left(a6)
|
|
add d0,tempRect1+right(a6)
|
|
swap d0 ;get DV into the low word
|
|
add d0,tempRect1+top(a6)
|
|
add d0,tempRect1+bottom(a6)
|
|
|
|
move.l GDPMap(a4),a0 ;get handle to the source pixMap
|
|
move.l (a0),a0 ;deref it
|
|
move.l pmTable(a0),a0 ;get handle to source color table
|
|
move.l (a0),a0 ;deref it
|
|
move.l ctSeed(a0),d1 ;get color table seed into d1
|
|
|
|
bsr cutOutDevices ;this cuts out different devices from d5
|
|
|
|
@next move.l (a2),a4 ;deref the current device list handle
|
|
move.l GDNextGD(a4),d0 ;get the next device handle into D0
|
|
move.l d0,a2 ;move it to our current handle. If it's NOT null
|
|
bne.s @loop ;..then loop back.
|
|
|
|
MOVE.L D5,A0 ;GET tmp region used by cutOutDevices
|
|
_DISPOSHANDLE ;DISCARD IT
|
|
movem.l (sp)+,d5/a2 ;restore d5
|
|
|
|
;----------------------------------------------------------------------------------------------------
|
|
oneDevice
|
|
|
|
; Scroll the rect using CopyBits
|
|
|
|
PEA PORTBITS(A3) ;PUSH SRCBITS
|
|
MOVE.L (SP),-(SP) ;PUSH DSTBITS
|
|
MOVE.L SRCRECT(A6),-(SP) ;PUSH SRCRECT
|
|
PEA DSTRECT(A6) ;PUSH DSTRECT
|
|
CLR -(SP) ;PUSH MODE = SRCCOPY
|
|
MOVE.L D6,-(SP) ;PUSH MASK REGION
|
|
_COPYBITS ;COPY THE BITS
|
|
|
|
; RESTORE FOREGROUND AND BACKGROUND COLORS
|
|
|
|
move.l sp,-(sp) ;point to the saved back color and restore it
|
|
_RestoreBack ; <DDG 28Jan90>
|
|
add.l #ColorSpecSize,sp ;strip the ColorSpec off the stack
|
|
move.l sp,-(sp) ;point to the saved back color and restore it
|
|
_RestoreFore
|
|
add.l #ColorSpecSize,sp ;strip the ColorSpec off the stack
|
|
|
|
; IF UPDATERGN NOT NIL, COMPUTE UPDATERGN := DIFFRGN(SRCRGN,DSTRGN) AND ERASE
|
|
|
|
MOVE.L THEUPDATERGN(A6),D0 ;GET THEUPDATERGN
|
|
BEQ.S NOUDR ;=>NO UPDATE RGN
|
|
|
|
MOVE.L D0,-(SP) ;PUSH UPDATERGN FOR ERASE
|
|
MOVE.L D7,-(SP) ;PUSH SRCRGN
|
|
MOVE.L D6,-(SP) ;PUSH DSTRGN
|
|
MOVE.L D0,-(SP) ;PUSH UPDATERGN
|
|
_DIFFRGN ;DiffRgn(srcRgn,dstRgn,updateRgn);
|
|
_ERASERGN ;AND ERASE UPDATE REGION
|
|
|
|
NOUDR MOVE.L D7,A0 ;GET SRCRGN
|
|
_DISPOSHANDLE ;DISCARD IT
|
|
MOVE.L D6,A0 ;GET DSTRGN
|
|
_DISPOSHANDLE ;DISCARD IT
|
|
BRA.S DONE
|
|
|
|
ABORT MOVE.L THEUPDATERGN(A6),D0 ;IS THERE AN UPDATE REGION?
|
|
BEQ.S DONE ;=>NO, DON'T EMPTY IT
|
|
MOVE.L D0,-(SP) ;PUSH UPDATERGN HANDLE
|
|
_SETEMPTYRGN ;SET IT TO EMPTY
|
|
|
|
DONE MOVE.L (SP)+,PICSAVE(A3) ;RESTORE PICSAVE HANDLE
|
|
MOVEM.L (SP)+,D6-D7/A3-A4 ;RESTORE REGS
|
|
UNLINK PARAMSIZE,'SCROLLRE'
|
|
|
|
;----------------------------------------------------------------------------------------------------
|
|
cutOutDevices
|
|
move.l DeviceList,a1 ;get the device list header into A1
|
|
|
|
@loop move.l (a1),a0 ;deref the current device list handle
|
|
tst GDFlags(a0) ;is the device active ?
|
|
bpl @next ;=>no, skip to the next device
|
|
|
|
move.l GDPMap(a0),a0 ;get handle to the source pixMap
|
|
move.l (a0),a0 ;deref it
|
|
move.l pmTable(a0),a0 ;get handle to source color table
|
|
move.l (a0),a0 ;deref it
|
|
cmp.l ctSeed(a0),d1 ;do the color tables seeds match ?
|
|
beq.s @next
|
|
|
|
movem.l d1/a1,-(sp) ;save our scratch registers
|
|
|
|
clr.b -(sp) ;make space for boolean result
|
|
pea tempRect1(a6) ;pointer to the SrcRect in global coordinates
|
|
move.l (a1),a0 ;deref the current device list handle
|
|
pea GDRect(a0) ;pointer to the device rect
|
|
pea tempRect2(a6) ;pointer to the result
|
|
_SectRect ;get the intersection
|
|
tst.b (sp)+ ;if they didn't intersect at all, then skip to
|
|
beq.s @skip ;..the next device
|
|
|
|
lea tempRect2(a6),a0 ;point to our temp rect
|
|
pea topleft(a0) ;convert the temp rect back to local coordinates
|
|
_GlobalToLocal
|
|
pea botright(a0)
|
|
_GlobalToLocal
|
|
|
|
move.l d5,-(sp) ;convert tempRect2 into a region
|
|
pea tempRect2(a6)
|
|
_RectRgn
|
|
move.l d6,-(sp) ;subtract this little invalid rect out of the
|
|
move.l d5,-(sp) ;..mask region.
|
|
move.l d6,-(sp)
|
|
_DiffRgn
|
|
|
|
@skip movem.l (sp)+,d1/a1 ;restore our scratch registers
|
|
|
|
@next move.l (a1),a0 ;deref the current device list handle
|
|
move.l GDNextGD(a0),d0 ;get the next device handle into D0
|
|
move.l d0,a1 ;move it to our current handle. If it's NOT null
|
|
bne.s @loop ;..then loop back.
|
|
|
|
rts
|
|
;----------------------------------------------------------------------------------------------------
|
|
|
|
ENDP
|
|
|
|
|
|
PackBits PROC EXPORT
|
|
EXPORT UnpackBits
|
|
;---------------------------------------------------------------------
|
|
;
|
|
; PROCEDURE PackBits(VAR srcPtr,dstPtr: Ptr; srcBytes: INTEGER);
|
|
;
|
|
; Packs one scanline of data, compressing equal bytes.
|
|
; Returns updated srcPtr and dstPtr.
|
|
;
|
|
; Equates for parameters are shared with UnpackBits
|
|
;
|
|
PARAMSIZE EQU 10 ;TOTAL BYTES OF PARAMS
|
|
SRCPTR EQU PARAMSIZE+4-4 ;LONG, VAR
|
|
DSTPTR EQU SRCPTR-4 ;LONG,VAR
|
|
SRCBYTES EQU DSTPTR-2 ;WORD
|
|
DSTBYTES EQU SRCBYTES ;ALIAS
|
|
|
|
MOVEM.L D3-D4/A2,-(SP) ;SAVE REGS
|
|
MOVE #128,D4 ;GET USEFUL VALUE
|
|
MOVE.L SRCPTR+12(SP),A0 ;GET VAR ADDR
|
|
MOVE.L (A0),A0 ;GET SRCPTR ITSELF
|
|
MOVE.L DSTPTR+12(SP),A1 ;GET VAR ADDR
|
|
MOVE.L (A1),A1 ;GET DSTPTR ITSELF
|
|
MOVE SRCBYTES+12(SP),D3 ;GET SRCBYTES
|
|
SUB #1,D3 ;INIT SRC DBRA COUNT
|
|
BLT.S DONE ;QUIT IF SRCBYTES <= 0
|
|
GoStart MOVE.B (A0)+,D0 ;GET FIRST BYTE OF SRC
|
|
BRA.S START ;AND GO TO LOOP START
|
|
|
|
FILLOP MOVE.B -1(A0),D0 ;PUT SRCDATA IN DO
|
|
SUB A0,D2 ;COMPUTE FILLOP
|
|
ADD D2,D3 ;UPDATE BYTECOUNT
|
|
ADD #1,D2 ;-2..-128 -> -1..-127
|
|
MOVE.B D2,(A2) ;STORE FILLOP
|
|
|
|
START MOVEQ #127,D1 ;GET MAX BYTECOUNT-1 FOR A RUN
|
|
CMP D4,D3 ;THAT MANY BYTES LEFT?
|
|
BGE.S @1 ;=>YES, DO CHUNK OF 128
|
|
MOVE D3,D1 ;ELSE DO REMAINING BYTES
|
|
|
|
@1 MOVE A0,D2 ;REMEMBER SRCSTART
|
|
MOVE.L A1,A2 ;REMEMBER OPLOC
|
|
CLR.B (A1)+ ;RESERVE ROOM FOR OPCODE
|
|
CMP.B (A0),D0 ;IS NEXT SRC THE SAME ?
|
|
BNE.S DOCOPY ;NO, USE COPY LOOP
|
|
CMP.B 1(A0),D0 ;THREE IN A ROW ?
|
|
BNE.S DOCOPY ;NO, USE COPY LOOP
|
|
BRA.S DOFILL ;YES, USE FILL LOOP
|
|
|
|
NXTCOPY MOVE.B (A0)+,D0 ;GET BYTE OF SRC
|
|
CMP.B (A0),D0 ;IS THE NEXT THE SAME ?
|
|
BNE.S DOCOPY ;NO, CONTINUE
|
|
CMP.B 1(A0),D0 ;THREE IN A ROW ?
|
|
BEQ.S COPYOP ;YES, END OF COPY RUN
|
|
DOCOPY MOVE.B D0,(A1)+ ;COPY DATA TO DST
|
|
DBRA D1,NXTCOPY ;AND LOOP FOR MORE
|
|
|
|
ENDCOPY SUB A0,D2 ;COMPUTE COPYOP
|
|
NEG D2 ;NEGATE ONLY
|
|
MOVE.B D2,(A2) ;INSTALL COPYOP
|
|
SUB D4,D3 ;SUBTRACT NEXT CHUNK
|
|
BPL.S GoStart ;=>MORE TO DO, CONTINUE
|
|
BRA.S DONE ;AND QUIT
|
|
|
|
COPYOP TST D1 ;IS THIS THE LAST SRC BYTE ?
|
|
BEQ DOCOPY ;YES, FINISH OFF COPY RUN
|
|
SUB A0,D2 ;COMPUTE COPYOP
|
|
ADD D2,D3 ;UPDATE BYTECOUNT
|
|
NOT D2 ;NEGATE AND SUBTRACT 1
|
|
MOVE.B D2,(A2) ;STORE COPYOP
|
|
|
|
MOVEQ #127,D1 ;GET MAX BYTECOUNT FOR A RUN
|
|
CMP D4,D3 ;THAT MANY BYTES LEFT?
|
|
BGE.S @1 ;=>YES, DO CHUNK OF 128
|
|
MOVE D3,D1 ;ELSE DO REMAINING BYTES
|
|
|
|
@1 MOVE.L A0,D2 ;REMEMBER SRCSTART
|
|
MOVE.L A1,A2 ;REMEMBER OPLOC
|
|
CLR.B (A1)+ ;RESERVE ROOM FOR OPCODE
|
|
|
|
DOFILL MOVE.B D0,(A1)+ ;COPY THE DATA BYTE
|
|
NXTFILL CMP.B (A0)+,D0 ;IS NEXT BYTE THE SAME ?
|
|
DBNE D1,NXTFILL ;LOOP TILL NOT SAME OR END SRC
|
|
BEQ.S ENDFILL ;BRANCH IF SRC EXHAUSTED
|
|
SUB #1,D1 ;COMPENSATE FOR DBNE DIDNT SUB
|
|
BGE FILLOP ;BR IF SRC NOT EXHAUSTED
|
|
|
|
ENDFILL SUB #1,A0 ;BACK UP FOR LAST BYTE COMPARED
|
|
SUB A0,D2 ;COMPUTE FILLOP
|
|
MOVE.B D2,(A2) ;INSTALL FILLOP
|
|
SUB D4,D3 ;SUBTRACT NEXT CHUNK
|
|
BPL.S GoStart ;=>MORE TO DO, CONTINUE
|
|
|
|
DONE CLR.L D0 ;GET READY FOR WORD
|
|
MOVE SRCBYTES+12(SP),D0 ;GET SRCBYTES
|
|
MOVE.L SRCPTR+12(SP),A0 ;GET VAR ADDR OF SRCPTR
|
|
ADD.L D0,(A0) ;BUMP SRCPTR
|
|
MOVE.L DSTPTR+12(SP),A2 ;GET VAR ADDR OF DSTPTR
|
|
MOVE.L A1,(A2) ;UPDATE DSTPTR
|
|
MOVEM.L (SP)+,D3-D4/A2 ;RESTORE REGS
|
|
SHARE MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
|
ADD #PARAMSIZE,SP ;STRIP PARAMS
|
|
JMP (A0) ;AND RETURN
|
|
|
|
|
|
;--------------------------------------------------------
|
|
;
|
|
; PROCEDURE UnpackBits(VAR srcPtr,dstPtr: Ptr; dstBytes: INTEGER);
|
|
;
|
|
; Unpacks one scanline of data, as compressed by PackBits.
|
|
; Returns updated srcPtr and dstPtr.
|
|
;
|
|
; Equates for parameters are the same as PackBits!
|
|
;
|
|
UnpackBits
|
|
MOVE.L SRCPTR(SP),A0 ;GET ADDR OF SRCPTR
|
|
MOVE.L (A0),A0 ;GET SRCPTR ITSELF
|
|
MOVE.L DSTPTR(SP),A1 ;GET ADDR OF DSTPTR
|
|
MOVE.L (A1),A1 ;GET DSTPTR ITSELF
|
|
MOVE DSTBYTES(SP),D2 ;GET DSTBYTES
|
|
EXT.L D2 ;MAKE IT LONG
|
|
ADD.L A1,D2 ;LIMIT := DSTPTR + BYTECOUNT
|
|
BRA.S @3 ;GO TO LOOP START
|
|
@1 EXT.W D1 ;CLEAR HI BYTE OF COUNT
|
|
@2 MOVE.B (A0)+,(A1)+ ;COPY A BYTE OF DATA
|
|
DBRA D1,@2 ;LOOP ALL COPY BYTES
|
|
@3 CMP.L D2,A1 ;IS DSTPTR >= LIMIT ?
|
|
BHS.S @5 ;YES, WE'RE DONE
|
|
MOVE.B (A0)+,D1 ;NO, GET OPCODE
|
|
BPL.S @1 ;0..127 --> COPY 1..128 BYTES
|
|
NEG.B D1 ;-1..-127 --> FILL 2..128 BYTES
|
|
BVS.S @3 ;IGNORE $80 FOR BACKWARD COMPAT
|
|
EXT.W D1 ;CLEAR HI BYTE OF COUNT
|
|
MOVE.B (A0)+,D0 ;GET FILL DATA BYTE
|
|
@4 MOVE.B D0,(A1)+ ;COPY IT TO DST
|
|
DBRA D1,@4 ;LOOP ALL FILL BYTES
|
|
BRA.S @3 ;THEN GET NEXT OPCODE
|
|
@5 MOVE.L A0,D0 ;STASH SRCPTR
|
|
MOVE.L SRCPTR(SP),A0 ;GET VAR ADDR
|
|
MOVE.L D0,(A0) ;UPDATE VAR SRCPTR
|
|
MOVE.L DSTPTR(SP),A0 ;GET VAR ADDR
|
|
MOVE.L A1,(A0) ;UPDATE VAR DSTPTR
|
|
BRA.S SHARE
|
|
|
|
|
|
|
|
|
|
PackWords PROC EXPORT
|
|
EXPORT UnpackWords
|
|
;---------------------------------------------------------------------
|
|
;
|
|
; PROCEDURE PackWords(VAR srcPtr,dstPtr: Ptr; srcBytes: INTEGER);
|
|
;
|
|
; Packs one scanline of data, compressing equal words.
|
|
; Returns updated srcPtr and dstPtr.
|
|
;
|
|
; Equates for parameters are shared with UnpackWords
|
|
;
|
|
PARAMSIZE EQU 10 ;TOTAL BYTES OF PARAMS
|
|
SRCPTR EQU PARAMSIZE+4-4 ;LONG, VAR
|
|
DSTPTR EQU SRCPTR-4 ;LONG,VAR
|
|
SRCBYTES EQU DSTPTR-2 ;WORD
|
|
DSTBYTES EQU SRCBYTES ;ALIAS
|
|
|
|
MOVEM.L D3-D4/A2,-(SP) ;SAVE REGS
|
|
MOVE #128,D4 ;GET USEFUL VALUE
|
|
MOVE.L SRCPTR+12(SP),A0 ;GET VAR ADDR
|
|
MOVE.L (A0),A0 ;GET SRCPTR ITSELF
|
|
MOVE.L DSTPTR+12(SP),A1 ;GET VAR ADDR
|
|
MOVE.L (A1),A1 ;GET DSTPTR ITSELF
|
|
MOVE SRCBYTES+12(SP),D3 ;GET SRCBYTES
|
|
lsr.w #1,d3 ;make in to word count <BAL 25Mar89>
|
|
SUB #1,D3 ;INIT SRC DBRA COUNT
|
|
BLT DONE ;QUIT IF SRCBYTES <= 0
|
|
GoStart MOVE.w (A0)+,D0 ;GET FIRST word OF SRC <BAL 25Mar89>
|
|
BRA.S START ;AND GO TO LOOP START
|
|
|
|
FILLOP MOVE.w -2(A0),D0 ;PUT SRCDATA IN DO <BAL 25Mar89>
|
|
SUB A0,D2 ;COMPUTE FILLOP
|
|
asr.w #1,d2 ;make into word cnt
|
|
ADD D2,D3 ;UPDATE wordCOUNT
|
|
ADD #1,D2 ;-2..-128 -> -1..-127
|
|
MOVE.B D2,(A2) ;STORE FILLOP
|
|
|
|
START MOVEQ #127,D1 ;GET MAX wordCOUNT-1 FOR A RUN
|
|
CMP D4,D3 ;THAT MANY words LEFT?
|
|
BGE.S @1 ;=>YES, DO CHUNK OF 128
|
|
MOVE D3,D1 ;ELSE DO REMAINING BYTES
|
|
|
|
@1 MOVE A0,D2 ;REMEMBER SRCSTART
|
|
MOVE.L A1,A2 ;REMEMBER OPLOC
|
|
CLR.B (A1)+ ;RESERVE ROOM FOR OPCODE
|
|
CMP.w (A0),D0 ;IS NEXT SRC THE SAME ? <BAL 25Mar89>
|
|
BNE.S DOCOPY ;NO, USE COPY LOOP
|
|
CMP.w 2(A0),D0 ;THREE IN A ROW ? <BAL 25Mar89>
|
|
BNE.S DOCOPY ;NO, USE COPY LOOP
|
|
BRA.S DOFILL ;YES, USE FILL LOOP
|
|
|
|
NXTCOPY MOVE.w (A0)+,D0 ;GET word OF SRC <BAL 25Mar89>
|
|
CMP.w (A0),D0 ;IS THE NEXT THE SAME ? <BAL 25Mar89>
|
|
BNE.S DOCOPY ;NO, CONTINUE
|
|
CMP.w 2(A0),D0 ;THREE IN A ROW ? <BAL 25Mar89>
|
|
BEQ.S COPYOP ;YES, END OF COPY RUN
|
|
DOCOPY MOVE.w D0,(A1)+ ;COPY DATA TO DST <BAL 25Mar89>
|
|
DBRA D1,NXTCOPY ;AND LOOP FOR MORE
|
|
|
|
ENDCOPY SUB A0,D2 ;COMPUTE COPYOP
|
|
NEG D2 ;NEGATE ONLY
|
|
asr.w #1,d2 ;make word count <BAL 25Mar89>
|
|
MOVE.B D2,(A2) ;INSTALL COPYOP
|
|
SUB D4,D3 ;SUBTRACT NEXT CHUNK
|
|
BPL.S GoStart ;=>MORE TO DO, CONTINUE
|
|
BRA.S DONE ;AND QUIT
|
|
|
|
COPYOP TST D1 ;IS THIS THE LAST SRC BYTE ?
|
|
BEQ DOCOPY ;YES, FINISH OFF COPY RUN
|
|
SUB A0,D2 ;COMPUTE COPYOP
|
|
asr.w #1,d2 ;make word count <BAL 25Mar89>
|
|
ADD D2,D3 ;UPDATE BYTECOUNT
|
|
NOT D2 ;NEGATE AND SUBTRACT 1
|
|
MOVE.B D2,(A2) ;STORE COPYOP
|
|
|
|
MOVEQ #127,D1 ;GET MAX BYTECOUNT FOR A RUN
|
|
CMP D4,D3 ;THAT MANY BYTES LEFT?
|
|
BGE.S @1 ;=>YES, DO CHUNK OF 128
|
|
MOVE D3,D1 ;ELSE DO REMAINING BYTES
|
|
|
|
@1 MOVE.L A0,D2 ;REMEMBER SRCSTART
|
|
MOVE.L A1,A2 ;REMEMBER OPLOC
|
|
CLR.B (A1)+ ;RESERVE ROOM FOR OPCODE
|
|
|
|
DOFILL MOVE.w D0,(A1)+ ;COPY THE DATA word <BAL 25Mar89>
|
|
NXTFILL CMP.w (A0)+,D0 ;IS NEXT word THE SAME ? <BAL 25Mar89>
|
|
DBNE D1,NXTFILL ;LOOP TILL NOT SAME OR END SRC
|
|
BEQ.S ENDFILL ;BRANCH IF SRC EXHAUSTED
|
|
SUB #1,D1 ;COMPENSATE FOR DBNE DIDNT SUB
|
|
BGE FILLOP ;BR IF SRC NOT EXHAUSTED
|
|
|
|
ENDFILL SUB #2,A0 ;BACK UP FOR LAST word COMPARED <BAL 25Mar89>
|
|
SUB A0,D2 ;COMPUTE FILLOP
|
|
asr.w #1,d2 ;make word count <BAL 25Mar89>
|
|
MOVE.B D2,(A2) ;INSTALL FILLOP
|
|
SUB D4,D3 ;SUBTRACT NEXT CHUNK
|
|
BPL.S GoStart ;=>MORE TO DO, CONTINUE
|
|
|
|
DONE CLR.L D0 ;GET READY FOR WORD
|
|
MOVE SRCBYTES+12(SP),D0 ;GET SRCBYTES
|
|
MOVE.L SRCPTR+12(SP),A0 ;GET VAR ADDR OF SRCPTR
|
|
ADD.L D0,(A0) ;BUMP SRCPTR
|
|
MOVE.L DSTPTR+12(SP),A2 ;GET VAR ADDR OF DSTPTR
|
|
MOVE.L A1,(A2) ;UPDATE DSTPTR
|
|
MOVEM.L (SP)+,D3-D4/A2 ;RESTORE REGS
|
|
SHARE MOVE.L (SP)+,A0 ;POP RETURN ADDR
|
|
ADD #PARAMSIZE,SP ;STRIP PARAMS
|
|
JMP (A0) ;AND RETURN
|
|
|
|
|
|
;--------------------------------------------------------
|
|
;
|
|
; PROCEDURE UnpackWords(VAR srcPtr,dstPtr: Ptr; dstBytes: INTEGER);
|
|
;
|
|
; Unpacks one scanline of data, as compressed by PackWords.
|
|
; Returns updated srcPtr and dstPtr.
|
|
;
|
|
; Equates for parameters are the same as PackWords!
|
|
;
|
|
UnpackWords
|
|
MOVE.L SRCPTR(SP),A0 ;GET ADDR OF SRCPTR
|
|
MOVE.L (A0),A0 ;GET SRCPTR ITSELF
|
|
MOVE.L DSTPTR(SP),A1 ;GET ADDR OF DSTPTR
|
|
MOVE.L (A1),A1 ;GET DSTPTR ITSELF
|
|
MOVE DSTBYTES(SP),D2 ;GET DSTBYTES
|
|
EXT.L D2 ;MAKE IT LONG
|
|
ADD.L A1,D2 ;LIMIT := DSTPTR + BYTECOUNT
|
|
BRA.S @3 ;GO TO LOOP START
|
|
@1 EXT.W D1 ;CLEAR HI BYTE OF COUNT
|
|
@2 MOVE.w (A0)+,(A1)+ ;COPY A word OF DATA <BAL 25Mar89>
|
|
DBRA D1,@2 ;LOOP ALL COPY words
|
|
@3 CMP.L D2,A1 ;IS DSTPTR >= LIMIT ?
|
|
BHS.S @5 ;YES, WE'RE DONE
|
|
MOVE.B (A0)+,D1 ;NO, GET OPCODE
|
|
BPL.S @1 ;0..127 --> COPY 1..128 BYTES
|
|
NEG.B D1 ;-1..-127 --> FILL 2..128 BYTES
|
|
BVS.S @3 ;IGNORE $80 FOR BACKWARD COMPAT
|
|
EXT.W D1 ;CLEAR HI BYTE OF COUNT
|
|
MOVE.w (A0)+,D0 ;GET FILL DATA word <BAL 25Mar89>
|
|
@4 MOVE.w D0,(A1)+ ;COPY IT TO DST <BAL 25Mar89>
|
|
DBRA D1,@4 ;LOOP ALL FILL words
|
|
BRA.S @3 ;THEN GET NEXT OPCODE
|
|
@5 MOVE.L A0,D0 ;STASH SRCPTR
|
|
MOVE.L SRCPTR(SP),A0 ;GET VAR ADDR
|
|
MOVE.L D0,(A0) ;UPDATE VAR SRCPTR
|
|
MOVE.L DSTPTR(SP),A0 ;GET VAR ADDR
|
|
MOVE.L A1,(A0) ;UPDATE VAR DSTPTR
|
|
BRA.S SHARE
|
|
|
|
|
|
|
|
|
|
ENDPROC
|
|
|
|
|
|
|
|
|