From 9c249dafab61013b7301aad0f9bd5cc089ed17c5 Mon Sep 17 00:00:00 2001 From: Elliot Nunn Date: Sun, 8 Oct 2017 23:26:23 +0800 Subject: [PATCH] Reverse 68k Color QuickDraw The ROM now round-trips with QuickDraw mostly built from source. (~30% of the ROM is now built from source.) --- BuildResults/RISC/Lib/CQD.lib | Bin 155760 -> 0 bytes BuildResults/RISC/Lib/MoreCQD.lib | Bin 0 -> 15874 bytes Interfaces/AIncludes/Processes.a | 3 +- Internal/Asm/ColorEqu.a | 4 +- Internal/Asm/fontPrivate.a | 78 +- QuickDraw/BitMaps.a | 171 ++- QuickDraw/CCrsrCore.a | 1828 ++--------------------------- QuickDraw/CQD.a | 2 + QuickDraw/CheckDevicesINIT.a | 810 +------------ QuickDraw/ColorMgr.a | 2 +- QuickDraw/ColorQD.make | 5 +- QuickDraw/DeviceLoop.a | 184 ++- QuickDraw/DrawText.a | 2 +- QuickDraw/FastTraps.a | 3 +- QuickDraw/GDevice.a | 912 ++++++-------- QuickDraw/GWorld.a | 32 +- QuickDraw/GrafAsm.a | 3 +- QuickDraw/LCursor.a | 60 +- QuickDraw/PaletteMgr.a | 350 +++--- QuickDraw/Patterns.a | 51 +- QuickDraw/Pictures.a | 161 +-- QuickDraw/QDExtensions2.a | 44 + QuickDraw/QDUtil.a | 21 +- QuickDraw/ScaleBlt.a | 2 +- QuickDraw/Stretch.a | 97 +- Tools/ToolSource/Vectorize.c | 1 + 26 files changed, 1240 insertions(+), 3586 deletions(-) delete mode 100644 BuildResults/RISC/Lib/CQD.lib create mode 100644 BuildResults/RISC/Lib/MoreCQD.lib create mode 100644 QuickDraw/QDExtensions2.a diff --git a/BuildResults/RISC/Lib/CQD.lib b/BuildResults/RISC/Lib/CQD.lib deleted file mode 100644 index b970d22bb0cbc9f6676aca7583924af1c9b95e35..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 155760 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

*{N27s|Bj>oC{hhN)Ip;pX!T#Bv=hE8M41Q(Nna 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 z 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%0Dwt3X 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 diff --git a/BuildResults/RISC/Lib/MoreCQD.lib b/BuildResults/RISC/Lib/MoreCQD.lib new file mode 100644 index 0000000000000000000000000000000000000000..c2f65e0e62c3d9b7f1dce0b1bfb50d52f180cc7c GIT binary patch literal 15874 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 BAL +qdStackXtra EQU $0800 ; stack space left for interrupts <1.4> BAL isPixMap EQU 15 ; for testing high bit of pRowbytes isCPort EQU 14 ; indicates that "bitmap" belongs to port @@ -376,7 +376,7 @@ CCSTATEREGS EQU CCDEPTH+2 ;[16 BYTES] STATE INFO OF SAVED DATA CCBYTES EQU CCSTATEREGS+16 ;[WORD] ROWBYTES OF EXPANDED DATA CCMAXDEPTH EQU CCBYTES+2 ;[WORD] MAXIMUM SCREEN DEPTH -CCSAVEREC EQU CCMAXDEPTH+2 ;SIZE OF CURSOR SAVE AREA +CCSAVEREC EQU CCMAXDEPTH+2+8 ;SIZE OF CURSOR SAVE AREA ; Font Manager low mem ; diff --git a/Internal/Asm/fontPrivate.a b/Internal/Asm/fontPrivate.a index 405a0b4..a2b1f90 100644 --- a/Internal/Asm/fontPrivate.a +++ b/Internal/Asm/fontPrivate.a @@ -265,70 +265,110 @@ selectInitializediskCache equ $0010 ; <24> MACRO _sbIsOutline IMPORT SplineMgr - MOVEQ #sbIsOutline,D0 + LCLC &OLDOPT +&OLDOPT SETC &Setting('OPT') + OPT NONE + MOVE #sbIsOutline,D0 + OPT &OLDOPT _SplineMgr ENDM MACRO _sbRetrieveGlyph IMPORT SplineMgr - MOVEQ #sbRetrieveGlyph,D0 + LCLC &OLDOPT +&OLDOPT SETC &Setting('OPT') + OPT NONE + MOVE #sbRetrieveGlyph,D0 + OPT &OLDOPT _SplineMgr ENDM MACRO _sbKillSomeCaches IMPORT SplineMgr - MOVEQ #sbKillSomeCaches,D0 + LCLC &OLDOPT +&OLDOPT SETC &Setting('OPT') + OPT NONE + MOVE #sbKillSomeCaches,D0 + OPT &OLDOPT _SplineMgr ENDM MACRO _sbFillWidthTab IMPORT SplineMgr - MOVEQ #sbFillWidthTab,D0 + LCLC &OLDOPT +&OLDOPT SETC &Setting('OPT') + OPT NONE + MOVE #sbFillWidthTab,D0 + OPT &OLDOPT _SplineMgr ENDM MACRO _sbResetWorkSpace IMPORT SplineMgr - MOVEQ #sbResetWorkSpace,D0 + LCLC &OLDOPT +&OLDOPT SETC &Setting('OPT') + OPT NONE + MOVE #sbResetWorkSpace,D0 + OPT &OLDOPT _SplineMgr ENDM MACRO _sbInitMemory IMPORT SplineMgr - MOVEQ #sbInitMemory,D0 + LCLC &OLDOPT +&OLDOPT SETC &Setting('OPT') + OPT NONE + MOVE #sbInitMemory,D0 + OPT &OLDOPT _SplineMgr ENDM MACRO _sbSetFontState IMPORT SplineMgr - MOVEQ #sbSetFontState,D0 + LCLC &OLDOPT +&OLDOPT SETC &Setting('OPT') + OPT NONE + MOVE #sbSetFontState,D0 + OPT &OLDOPT _SplineMgr ENDM MACRO _sbSearchForCache IMPORT SplineMgr - MOVEQ #sbSearchForCache,D0 + LCLC &OLDOPT +&OLDOPT SETC &Setting('OPT') + OPT NONE + MOVE #sbSearchForCache,D0 + OPT &OLDOPT _SplineMgr ENDM MACRO _sbPreFlightFontMem IMPORT SplineMgr - MOVEQ #sbPreFlightFontMem,D0 + LCLC &OLDOPT +&OLDOPT SETC &Setting('OPT') + OPT NONE + MOVE #sbPreFlightFontMem,D0 + OPT &OLDOPT _SplineMgr ENDM MACRO _fsLowestPPEM IMPORT SplineMgr - MOVEQ #fsLowestPPEM,D0 + LCLC &OLDOPT +&OLDOPT SETC &Setting('OPT') + OPT NONE + MOVE #fsLowestPPEM,D0 + OPT &OLDOPT _SplineMgr ENDM @@ -341,19 +381,31 @@ selectInitializediskCache equ $0010 ; <24> MACRO _sbFlushFonts IMPORT SplineMgr - MOVEQ #sbFlushFonts,D0 + LCLC &OLDOPT +&OLDOPT SETC &Setting('OPT') + OPT NONE + MOVE #sbFlushFonts,D0 + OPT &OLDOPT _SplineMgr ENDM Macro ; <24> _InitializePartialFonts ; <24> - moveq #selectInitializePartialFonts,d0 ; <24> + LCLC &OLDOPT +&OLDOPT SETC &Setting('OPT') + OPT NONE + MOVE #selectInitializePartialFonts,d0 ; <24> + OPT &OLDOPT _SplineMgr ; <24> EndM ; <24> Macro ; <24> _InitializeDiskCache ; <24> - moveq #selectInitializeDiskCache,d0 ; <24> + LCLC &OLDOPT +&OLDOPT SETC &Setting('OPT') + OPT NONE + MOVE #selectInitializeDiskCache,d0 ; <24> + OPT &OLDOPT _SplineMgr ; <24> EndM ; <24> diff --git a/QuickDraw/BitMaps.a b/QuickDraw/BitMaps.a index 2283875..eab2aba 100644 --- a/QuickDraw/BitMaps.a +++ b/QuickDraw/BitMaps.a @@ -1071,12 +1071,42 @@ NXTDST MOVE.L (A4)+,D1 ;GET NEXT DST DEVICE 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 - - + move.l theGDevice,a0 ;handle to destination gDevice + move.l (a0),a0 ;pointer to destination gDevice + + CMP $24(A0), D0 + BGT.S @L5 + BLT.S @L2 + SWAP D0 + CMP gdRect+0(A0), D0 + BGT.S @L6 + BLT.S @L3 + MOVE.L gdRect+4(A1), D0 + CMP gdRect+6(A0), D0 + BLT.S @L7 + BGT.S @L4 + BRA.S nxtdst +@L2 SWAP D0 + CMP gdRect+0(A0), D0 + BGT.S @cont +@L3 MOVE.L gdRect+4(A1), D0 + CMP gdRect+6(A0), D0 + BLT.S @cont +@L4 SWAP D0 + CMP gdRect+4(A0), D0 + BLT.S @cont + BRA.S nxtdst +@L5 SWAP D0 + CMP gdRect+0(A0), D0 + BLT.S @cont +@L6 MOVE.L gdRect+4(A1), D0 + CMP gdRect+6(A0), D0 + BGT.S @cont +@L7 SWAP D0 + CMP gdRect+4(A0), D0 + BGT.S @cont + BRA.S nxtdst + @cont ; ; End of @@ -1711,11 +1741,91 @@ DSTRECT EQU MASKRECT-4 ;long, addr of Rect MODE EQU DSTRECT-2 ;WORD MASKRGN EQU MODE-4 ;LONG, RGNHANDLE -VARSIZE EQU 0 +VARSIZE EQU -4 share LINK A6,#VARSIZE ;ALLOCATE STACK FRAME MOVEM.L D3-D7/A2-A4,-(SP) ;SAVE WORK REGISTERS FOR DEVLOOP - + + CLR.L -4(A6) + MOVE.L MASKBITS(A6), D0 + BEQ @skip + MOVEA.L D0, A0 + CMPI #$1, $20(A0) + BNE @skip + MOVEA.L $16(A6), A0 + MOVEA.L $E(A6), A1 + MOVE $4(A0), D0 + SUB (A0), D0 + SUB $4(A1), D0 + ADD (A1), D0 + BGT.B @L0 + MOVE $6(A0), D0 + SUB $2(A0), D0 + SUB $6(A1), D0 + ADD $2(A0), D0 + BLE @skip +@L0 SUBQ #$4, SP + DC.W $AA18 ;_GetCTable + MOVE.L (SP)+, D3 + BEQ @skip + SUBQ #$2, SP + PEA.L -4(A6) + MOVE #$2, -(SP) + PEA.L MASKRECT(A6) + MOVE.L D3, -(SP) + CLR.L -(SP) + PEA 4 + MOVE.L #$160000,D0 ;_QDExtensions -> _NewGWorld + DC.W $AB1D + MOVE (SP)+, D4 + BNE.B @L1 + TST.L -4(A6) + BNE.B @L2 +@L1 SUBQ #$2, SP + PEA.L -4(A6) + MOVE #$2, -(SP) + PEA.L MASKRECT(A6) + MOVE.L D3, -(SP) + CLR.L -(SP) + CLR.L -(SP) + MOVE.L #$160000,D0 ;_QDExtensions -> _NewGWorld + DC.W $AB1D + MOVE (SP)+, D4 +@L2 MOVE.L D3, -(SP) + DC.W $AA24 ;_DisposCTable + TST D4 + BNE.B @skip + MOVE.L -4(A6), D0 + BEQ.B @skip + MOVEA.L D0, A3 + SUBQ #$8, SP + PEA.L $4(SP) + PEA.L $4(SP) + MOVE.L #$80005,D0 ;_QDExtensions -> _GetGWorld + DC.W $AB1D + MOVE.L -4(A6), -(SP) + CLR.L -(SP) + MOVE.L #$80006,D0 ;_QDExtensions -> _SetGWorld + DC.W $AB1D + MOVE.L MASKBITS(A6), -(SP) + PEA.L $2(A3) + MOVE.L MASKRECT(A6), -(SP) + PEA.L $10(A3) + CLR -(SP) + CLR.L -(SP) + DC.W $A8EC ;_CopyBits + SUBQ #$2, SP + MOVE.L $2(A3), -(SP) + MOVE.L #$40001,D0 ;_QDExtensions -> _LockPixels + DC.W $AB1D + ADDQ #$2, SP + MOVEA.L $2(A3), A0 + _HLock + MOVE.L (A0), MASKBITS(A6) + MOVE.L #$80005,D0 ;_QDExtensions -> _GetGWorld + DC.W $AB1D +@skip + ; SET UP REGISTERS FOR CALLING CMDEVLOOP MOVE.L DSTBITS(A6),A1 ;GET DST BIT/PIXMAP @@ -1763,7 +1873,15 @@ SRCOK MOVE.L DSTBITS(A6),A0 ;POINT TO DSTBITS NOTPORT MOVE.L DSTBITS(A6),A1 ;Pass DSTBITS (not derefed) JSR CMDevLoop ;AND DRAW THE IMAGE - + + MOVE.L -4(A6),D0 + BEQ.S @skipQDCall + + MOVE.L D0,-(SP) + MOVE.L #$40004,D0 ;_QDExtensions -> _DisposeGWorld + DC.W $AB1D +@skipQDCall + MOVEM.L (SP)+,D3-D7/A2-A4 ;RESTORE WORK REGISTERS UNLINK PARAMSIZE,'KopyMask' @@ -2296,9 +2414,9 @@ cutOutDevices 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 + beq @next - movem.l d1/a1,-(sp) ;save our scratch registers + movem.l d1/a1-a3,-(sp) ;save our scratch registers clr.b -(sp) ;make space for boolean result pea tempRect1(a6) ;pointer to the SrcRect in global coordinates @@ -2307,7 +2425,34 @@ cutOutDevices 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 + beq @skip ;..the next device + + move.l (a1),a0 + move.l GDPMap(a0),a0 + move.l (a0),a0 + move.l pmTable(a0),a0 + move.l (a0),a0 + move.l (DeviceList),a2 +@again move.l (a2),a2 + move.l GDPMap(a2),a3 + move.l (a3),a3 + move.l pmTable(a3),a3 + move.l (a3),a3 + move.l (a3),d0 + cmp.l (a0),d0 + bne @done + sub.l #8,sp + clr.b -(sp) + pea.l tempRect1(a6) + pea.l $22(a2) + pea.l $a(sp) + _SectRect + tst.b (sp)+ + add.l #8,sp + bne @skip +@done move.l GDNextGD(a2),d0 + move.l d0,a2 + bne.s @again lea tempRect2(a6),a0 ;point to our temp rect pea topleft(a0) ;convert the temp rect back to local coordinates @@ -2323,7 +2468,7 @@ cutOutDevices move.l d6,-(sp) _DiffRgn -@skip movem.l (sp)+,d1/a1 ;restore our scratch registers +@skip movem.l (sp)+,d1/a1-a3 ;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 diff --git a/QuickDraw/CCrsrCore.a b/QuickDraw/CCrsrCore.a index 914e811..3fa53e7 100644 --- a/QuickDraw/CCrsrCore.a +++ b/QuickDraw/CCrsrCore.a @@ -102,330 +102,60 @@ cursorShadow EQU 0 -CRSRCORE PROC EXPORT - EXPORT CrsrVBLTask +ShieldCursor PROC EXPORT +;--------------------------------------------------------- +; +; PROCEDURE ShieldCursor(shieldRect: Rect; offset: Point); +; +; ALL REGS PRESERVED. +; +; Lifted from LCursor.a +; + IMPORT QDNew_OtherShieldCursor + + MOVEM.L D0-D2/A0-A1,-(SP) ;SAVE REGS + MOVE.L 28(SP),D0 + MOVE.L 24(SP),D1 + MOVE.L D0,-(SP) ;PUSH GLOBAL TOP + MOVE.L D1,-(SP) ;PUSH GLOBAL LEFT + JSR QDNew_OtherShieldCursor + MOVEM.L (SP)+,D0-D2/A0-A1 ;RESTORE REGS + RTD #8 + + +CRSRCORE PROC EXPORT EXPORT InitCrTable EXPORT PinRect - IMPORT ScrnAddress - IMPORT ScrnSize - IMPORT ScrnBitMap - IMPORT PATCONVERT ; expand routine for color cursors/patterns - IMPORT AllocCrsr ; proc at end of file - IMPORT SETCRSRDATA ; PROC AT END OF FILE - IMPORT SHFTTBL ; TO CONVERT DEPTH TO SHIFT - IMPORT RGetHSize + IMPORT _HideCursor + IMPORT _ShowCursor + IMPORT _ShieldCursor + IMPORT _ScrnAddress + IMPORT _ScrnSize + IMPORT _InitCursor + IMPORT _SetCursor + IMPORT _ObscureCursor + IMPORT AllocCrsr + IMPORT _SetCCursor - IMPORT BLITCURSOR,UNBLITCURSOR ; Cursor Pixelling - EXPORT DRAWCURSOR,ERASECURSOR ; Cursor Displaying - EXPORT CursorSect - EXPORT GETMAINCRSR ;JUST USED INTERNALLY ; ; offset table for jump table initialization ; InitCrTable - DC.W HideCursor-InitCrTable - DC.W ShowCursor-InitCrTable - DC.W ShieldCursor-InitCrTable - DC.W ScrnAddress-InitCrTable - DC.W ScrnSize-InitCrTable - DC.W InitCursor-InitCrTable - DC.W SetCursor-InitCrTable - DC.W ObscureCursor-InitCrTable + DC.W _HideCursor-InitCrTable + DC.W _ShowCursor-InitCrTable + DC.W _ShieldCursor-InitCrTable + DC.W _ScrnAddress-InitCrTable + DC.W _ScrnSize-InitCrTable + DC.W _InitCursor-InitCrTable + DC.W _SetCursor-InitCrTable + DC.W _ObscureCursor-InitCrTable DC.W AllocCrsr-InitCrTable - DC.W SetCCursor-InitCrTable + DC.W _SetCCursor-InitCrTable ;_______________________________________________________________________ -; -; CrsrVBLTask - executed once each vertical retrace -; - -; ugly equs - stay here for now! -adbCount EQU 0 ; word: number of valid error deltas -MaxCnt EQU adbCount+2 ; word: limit on number of error deltas -Err7 EQU MaxCnt+2 ; word: time-7 error magnitude -Err6 EQU Err7+2 ; word: time-6 error magnitude -Err5 EQU Err6+2 ; word: time-5 error magnitude -Err4 EQU Err5+2 ; word: time-4 error magnitude -Err3 EQU Err4+2 ; word: time-3 error magnitude -Err2 EQU Err3+2 ; word: time-2 error magnitude -Err1 EQU Err2+2 ; word: time-1 error magnitude -Error EQU Err1+2 ; word: accumulated error -GSize EQU Error+2 - -CrsrVBLTask ;COME HERE ON VERTICAL RETRACE - - If Not forRom Then ;

- TST.B CrsrNew ; Mouse changed? - BEQ TrackDone ; No É return - TST.B CrsrBusy ; Cursor locked? - BNE TrackDone ; Yes É return - - TST.B CrsrCouple ; Cursor coupled to mouse? - BEQ NoComp ; No É skip computation - - MOVE.W MTemp+H,D0 ; Find ÆMx - SUB.W RawMouse+H,D0 - - MOVE.W MTemp+V,D1 ; Find ÆMy - SUB.W RawMouse+V,D1 - - MOVE.W D0,D2 ; x := |ÆMx| - BGE.S AbslXl - NEG.W D2 -AbslXl - - MOVE.W D1,D3 ; y := |ÆMy| - BGE.S AbslYl - NEG.W D3 -AbslYl - - move.l MickeyBytes,a0 ; <10/7/86 SMH> get globals - CMP.W D2,D3 ; D3 := magnitude(x,y) - BLS.S MagDone - EXG D2,D3 -MagDone ASR.W #1,D3 - ADD.W D2,D3 - - BNE.S DoComp ; Zero magnitude É donÕt compute - MOVE.W #1,adbCount(A0) ; No hits - CLR.W Error(A0) ; No errors - BRA DoPin ; Update the cursor -DoComp -; - MOVEM.L D4-D5,-(A7) ; Save off registers - MOVE.W adbCount(A0),D4 ; D4 is the number of samples - CMP.W MaxCnt(A0),D4 ; Is Count less than MaxCnt - BGE.S CountOK - ADD.W #1,adbCount(A0) ; Yes É we will have one more error -CountOK - - MOVE.W D3,D5 ; Magnitude at current time - - MOVE.W D4,D2 ; Get Count - SUB.W #1,D2 ; Index into JTab - ASL.W #1,D2 ; REQUIRES BRA.SÕs IN JUMP TABLES - JMP JTab(PC,D2.W) ; Jump to the right code per Count - -JTab BRA.S E1 ; Count = 1 - BRA.S E2 ; Count = 2 - BRA.S E3 ; Count = 3 - BRA.S E4 ; Count = 4 - BRA.S E5 ; Count = 5 - BRA.S E6 ; Count = 6 - BRA.S E7 ; Count = 7 - -E8 ADD.W Err7(A0),D5 ; Accumulate time-7 magnitude - -E7 ADD.W Err6(A0),D5 ; Accumulate time-6 magnitude - MOVE.W Err6(A0),Err7(A0) ; Shift out time-6 magnitude - -E6 ADD.W Err5(A0),D5 ; Accumulate time-5 magnitude - MOVE.W Err5(A0),Err6(A0) ; Shift out time-5 magnitude - -E5 ADD.W Err4(A0),D5 ; Accumulate time-4 magnitude - MOVE.W Err4(A0),Err5(A0) ; Shift out time-4 magnitude - -E4 ADD.W Err3(A0),D5 ; Accumulate time-3 magnitude - MOVE.W Err3(A0),Err4(A0) ; Shift out time-3 magnitude - -E3 ADD.W Err2(A0),D5 ; Accumulate time-2 magnitude - MOVE.W Err2(A0),Err3(A0) ; Shift out time-2 magnitude - -E2 ADD.W Err1(A0),D5 ; Accumulate time-1 magnitude - MOVE.W Err1(A0),Err2(A0) ; Shift out time-1 magnitude - -E1 MOVE.W D3,Err1(A0) ; Shift out current magnitude - - MOVE.W D4,D2 ; Round up the divide - ASR.W #1,D2 ; by half the denominator - ADD.W D2,D5 - EXT.L D5 ; Set up for the divide - DIVU D4,D5 ; Find the average magnitude - - MOVE.W D3,D4 ; Get the original magnitude - SUB.W D5,D3 ; Find distance to average magnitude - ADD.W Error(A0),D3 ; Add on the accumulated error - CMP.W #-1,D3 ; Define -1 div 2 = 0 - BNE.S DivOK - CLR.W D3 -DivOK ASR.W #1,D3 ; Get half of it - MOVE.W D3,Error(A0) ; Update it - ADD.W D5,D3 ; Desired mag is average+Error - - CMP.W #255,D5 ; mag := MAX(mag,255) - BLS.S MaxDone - MOVE.B #255,D5 -MaxDone - - move.l MickeyBytes,a0 ; <10/7/86 SMH> get at globals - add #GSize,a0 ; <10/24/86 SMH> point to table - - CLR.W D2 ; i := 0 - -Search ADD.B #1,D2 ; repeat - CMP.B (A0)+,D5 ; i := i+1 - BHI.S Search ; until mag ² Table[i] - - MULS D2,D3 ; D4 := i*(Mag(ÆM)+Error) - - MULS D3,D0 ; ÆCx := (ÆMx*i*(Mag(ÆM)+Error))/Mag(ÆM) - DIVS D4,D0 ; <<<<<< D3 >>>>>>> - BMI.S @1 ; branch if minus - ANDI.W #$007F,D0 ; control max displacement (fix mouse jump) - BRA.S @3 -@1 - ORI.W #$FF80,D0 ; control max displacement (fix mouse jump) -@3 - MULS D3,D1 ; ÆCy := (ÆMy*i*(Mag(ÆM)+Error))/Mag(ÆM) - DIVS D4,D1 ; <<<<<< D3 >>>>>>> - BMI.S @5 ; branch if minus - ANDI.W #$007F,D1 ; control max displacement (fix mouse jump) - BRA.S @7 -@5 - ORI.W #$FF80,D1 ; control max displacement (fix mouse jump) -@7 - MOVEM.L (A7)+,D4-D5 ; Restore registers - ADD.W D0,RawMouse+H ; Update raw mouse location - ADD.W D1,RawMouse+V -; -DoPin ; - LEA CrsrPin,A0 ; Bounding rect for cursor - MOVE.L RawMouse,D0 ; Pin mouse inside rect - - Endif ; Not forRom

- - BSR.S ScrnPin ; return to SHOWIT if screen changes - - MOVE.L D0,RawMOUSE ; update cursor loc with clipped pt - MOVE.L D0,MTEMP ; Update real mouse location with "" - - AND.L MOUSEMASK,D0 ; do jerky masking to drop low order bits - MOVE.L MOUSEOffset,D1 ; Get the offset - BEQ.S skipPin ; and skip 2nd pin if not - ADD.L D1,D0 ; do jerky offset - BSR.S ScrnPin ; return to SHOWIT if screen changes - -skipPin MOVE.L D0,MOUSE - -NotCup BSR ERASECURSOR ; HIDE THE CURSOR -SHOWIT CLR.B CRSRNEW ; RESET THE CURSOR CHANGED FLAG - CLR.B CRSROBSCURE ; it's no longer obscured - BSR DRAWCURSOR ; AND SHOW CURSOR IN NEW POSITION - -CRSRDONE ;AND RETURN - RTS - -TrackDone - move.l MickeyBytes,a0 ; <10/7/86 SMH> get globals - MOVE.W #1,adbCount(A0) ; No hits - CLR.W Error(A0) ; No errors - RTS ; Goodbye - -NoComp move.l MickeyBytes,a0 ; <10/7/86 SMH> get globals - MOVE.W #1,adbCount(A0) ; No hits - CLR.W Error(A0) ; No errors - BRA.S NotCup ; Update the cursor - - -; --------end of ugly jcrsrcoreTask - - - -ScrnPin CMP LEFT(A0),D0 ;less than left? - BGE.S LEFTOK ;if not, no problem - BSR.S FindScreen ;=>look for new screen - MOVE LEFT(A0),D0 ;pin to the left - -LEFTOK CMP RIGHT(A0),D0 ;greater than right? - BLT.S RIGHTOK ;if not, no problem WAS BLE!! <05Apr85> - BSR.S FindScreen ;=>look for new screen - MOVE RIGHT(A0),D0 ;pin to the right - SUBQ #1,D0 ;really want one less - -RIGHTOK SWAP D0 ;consider y - CMP TOP(A0),D0 ;less than top? - BGE.S TOPOK ;if not, no problem - SWAP D0 - BSR.S FindScreen ;=>look for new screen - SWAP D0 - MOVE TOP(A0),D0 ;pin to the top - -TOPOK CMP BOTTOM(A0),D0 ;greater than bottom? - BLT.S BOTOK ;if not, no problem WAS BLE!! <05Apr85> - SWAP D0 - BSR.S FindScreen ;=>look for new screen - SWAP D0 - MOVE BOTTOM(A0),D0 ;pin to the bottom - SUBQ #1,D0 ;really want one less - -BOTOK SWAP D0 - RTS ;and return - -; Check to see if cursor has moved to another screen. -; If not, returns with D0 unchanged. -; If so, hides the cursor, updates cursor globals and does messy return. -; -; Clobbers D1-D3/A0-A3 which are preserved by interrupt handler - -FindScreen MOVE D0,D3 ;pt.h in D3 - MOVE.L D0,D1 ;pt.v in D1 - SWAP D1 ;pt.v in D1 - MOVE.L DeviceList,D2 ;get the first GDevice - BMI.S NoDev ;=>just in case no GDevice -DoDev MOVE.L D2,A3 ;get device handle - MOVE.L (A3),A3 ;get device pointer - TST GDFlags(A3) ;is screen active? - BPL.S NxtDev ;=>no, try next device - LEA GDRect(A3),A1 ;point to rect - CMP (A1)+,D1 ;above top? - BLT.S NxtDev ;=>yes, check next device - CMP (A1)+,D3 ;to left of screen? - BLT.S NxtDev ;=>yes, check next device - CMP (A1)+,D1 ;to bottom of screen? - BGE.S NxtDev ;=>yes, check next device - CMP (A1)+,D3 ;to right of screen? - BLT.S GotDev ;=>no, cursor is on this screen -NxtDev MOVE.L GDNextGD(A3),D2 ;get next device in chain - BNE.S DoDev ;=>there is one, check it -NoDev RTS ;else return and pin to current screen - -; cursor has changed devices, update depth and rowbytes for current device - -GotDev MOVE.L CRSRPTR,A0 ;get handle to cursor data - MOVE.L (A0),A0 ;get pointer to cursor data - MOVE.L CrsrDevice,A1 ;get handle to current device - MOVE.L (A1),A1 ;point to current device - MOVE CCDEPTH(A0),GDCCDEPTH(A1) ;copy depth - MOVE CCBYTES(A0),GDCCBYTES(A1) ;copy expanded rowbytes - -; now get the data, depth and rowbytes for the new device - - BSR ERASECURSOR ;else erase the cursor -@0 SWAP D3 ;get pt.h in high word - MOVE D1,D3 ;get pt.v in low word - SWAP D3 ;now get them in the right order - MOVE.L D3,MTEMP ;update real mouse location with "" - MOVE.L D3,RawMOUSE ;update cursor loc with clipped pt - MOVE.L D3,MOUSE ;update mouse position - MOVE.L D2,CrsrDevice ;set the current cursor device - MOVE.L A3,A1 ;get pointer to grafDevice - JSR SetCrsrData ;and set up low-memory stuff for cursor - - MOVE GDREFNUM(A3),D0 ;get the refNum - NOT D0 ;refNum -> unitnum - ASL #2,D0 ;get offset in unitTable - MOVE.L UTableBase,A0 ;get the base of the unit table - MOVE.L (A0,D0),A3 ;A3 = handle to the DCE - MOVE.L (A3),A0 ;get pointer to the DCE - MOVEQ #0,D0 ;clear out D0 - MOVE.B dCtlSlot(A0),D0 ;get the slot number - _ATTACHVBL ;attach vbl to this slot - - ADDQ #8,SP ;strip 2 RTS's from stack - BRA SHOWIT ;=>and go display cursor on new screen ; This routine is used by the pinrect routine below and is also called directly @@ -473,68 +203,6 @@ PinRect JMP (A0) ;return to caller -;_______________________________________________________________________ ; -; ; -; PROCEDURE CursorSect -- called by shieldcursor, showcursor ; -; ; -; Does a sectrect of CrsrRect and ShieldRect, all global-cošrd like. ; -; CLEAR the z-flag if they DO intersect: BNE YesTheyIntersect. -; This code is was moved out of ShieldCursor. ; -; -; Since CrsrRect is in local screen cošrds, and ShieldRect is in globals, -; the CrsrDevice's GDRect is used as an offset. -;_______________________________________________________________________ ; -CursorSect MOVEM.L A0/A1/D0,-(SP) ;save the approprate regs - - TST ShieldDepth ;Any shielding? - BEQ.s @NoSect - - LEA CrsrRect,A0 ;point to crsr rect ; - MOVE.L CrsrDevice,A1 ;GET CURSOR DEVICE ; - MOVE.L (A1),A1 ;POINT TO CURSOR DEVICE ; - ADD #GDRECT,A1 ;POINT TO DEVICE'S RECT ; - - MOVE ShieldRect+Bottom,D0 ;GET SHIELD BOTTOM ; - SUB TOP(A1),D0 ;CONVERT TO SCREEN LOCAL; - CMP (A0)+,D0 ;IS SHIELDBOTTOM < SAVETOP ? ; - BLT.S @NOSECT ;YES, NO INTERSECTION ; - - MOVE ShieldRect+Right,D0 ;GET SHIELD RIGHT - SUB LEFT(A1),D0 ;CONVERT TO SCREEN LOCAL - CMP (A0)+,D0 ;IS SHIELDRIGHT <= SAVELEFT ? - BLE.S @NOSECT ;YES, NO INTERSECTION - - MOVE ShieldRect+Top,D0 ;GET SHIELD TOP - SUB TOP(A1),D0 ;CONVERT TO SCREEN LOCAL - CMP (A0)+,D0 ;IS SHIELDTOP >= SAVEBOTTOM ? - BGE.S @NOSECT ;YES, NO INTERSECTION - - MOVE ShieldRect+Left,D0 ;GET SHIELD LEFT - SUB LEFT(A1),D0 ;CONVERT TO SCREEN LOCAL - CMP (A0),D0 ;IS SHIELDLEFT >= SAVERIGHT ? - BGE.S @NOSECT ;YES, NO INTERSECTION - -@SECT MOVEQ #1,D0 ;Clear the Z-flag - BRA.S @out ; - -@NOSECT CLR D0 ;Set the Z-flag -@out MOVEM.L (SP)+,A0/A1/D0 ;Restore regs - RTS ;bye. - -;_______________________________________________________________________ -; -; PROCEDURE ObscureCursor -- called via the jump table -; -; Removes the cursor from the screen without hiding it, so the next -; time the mouse moves, it will show up again. -; -;_______________________________________________________________________ - -ObscureCursor - MOVE.B #1,CrsrBusy ;"Occupado" - MOVE.B #1,CrsrObscure ;Mark it as obscure - BRA.S EraseCursor ;and erase it - ;_______________________________________________________________________ ; ; HIDECURSOR - is called from CrsrVBLTask, and via jump table. @@ -542,44 +210,13 @@ ObscureCursor ; Subtracts 1 from crsrstate and hides the cursor if visible. ; ; -HideCursor - MOVE.B #1,CrsrBusy ;MARK CHANGE IN PROGRESS - SUB #1,CRSRSTATE ;CURSOR HIDDEN ONE DEEPER - - ;Fall into EraseCursor - -;________________________________________________________________________ -; CSS Horror vectorized this vector. We are supporting this to be -; compatible with Horror. -; EraseCursor calls a vectorized version of the routine via lomem. -; EraseCursor is vectorized to gain access to low level cursor blit routines. -; (NOTE: Vector is initialized in StartInit.a to routine named VEraseCursor.) - -; EraseCursor is much like HideCursor, but doesn't decrement the CrsrState - -EraseCursor - move.l EraseCrsrVector,-(sp) ; CSS - rts ;jump to the vectored routine CSS -DoneHid CLR.B CRSRBUSY ;CHANGE COMPLETE +_HideCursor PROC EXPORT + MOVEM.L D0-D2/A0-A1,-(SP) + IMPORT QDNEW_HIDECURSOR + JSR QDNEW_HIDECURSOR + MOVEM.L (SP)+,D0-D2/A0-A1 RTS - -;_______________________________________________________________________ -; -; PROCEDURE InitCursor; -; -; Definitely redisplay the cursor, independent of previous calls to -; HideCursor, ShieldCursor and ObscureCursor. It falls into showCursor. -; -InitCursor - MOVE.B #1,CrsrBusy ;mark it busy - CLR.B CrsrObscure ;we wont be obscure no more - CLR CrsrState ;reset state to 0 - CLR ShieldDepth -; -; fall into ShowCursor -; - ;_______________________________________________________________________ ; ; SHOWCURSOR - Called from CrsrVBLTask and via Jump Table. @@ -587,39 +224,12 @@ InitCursor ; Adds 1 to CRSRSTATE and paints cursor if zero and cursor is ; not already visible. ; -;Êthis reflects the fix from QDciPatchROM.a where obscure/show/hide left stb -; the cursor hidden only, and obscure/hide/show left the cursor obscured only. stb -ShowCursor - MOVE.B #1,CRSRBUSY ;MARK CHANGE IN PROGRESS - - TST ShieldDepth ;Any shielding? - BEQ.s @2 - -@1 SUBQ #1,ShieldDepth ;If so, this ShowCursor unshields, - BRA.s DrawCursor ;but doesn't up the cursor level. - -@2 ADDQ #1,CRSRSTATE ;CURSOR HIDDEN ONE LESS DEEP - bmi.s DoneSho - beq.s DrawCursor ; - clr.b CrsrObscure ;unobscure cursor if level went past zero - - ;fall into DrawCursor - -;________________________________________________________________________ -; CSS Horror vectorized this vector. We are supporting this to be -; compatible with Horror. -; DrawCursor calls a vectorized version of the routine via lomem. -; DrawCursor is vectorized to gain access to low level cursor blit routines. -; (NOTE: Vector is initialized in StartInit.a to routine named VDrawCursor.) - -; DrawCursor is much like ShowCursor, but doesn't increment the CrsrState - -DrawCursor - move.l DrawCrsrVector,-(sp) ; CSS - rts ;jump to the vectored routine CSS - -DoneSho CLR.B CRSRBUSY ;CHANGE COMPLETE +_ShowCursor PROC EXPORT + MOVEM.L D0-D2/A0-A1,-(SP) + IMPORT QDNEW_SHOWCURSOR + JSR QDNEW_SHOWCURSOR + MOVEM.L (SP)+,D0-D2/A0-A1 RTS ;_______________________________________________________________________ @@ -634,207 +244,21 @@ DoneSho CLR.B CRSRBUSY ;CHANGE COMPLETE ; ALL REGISTERS RESTORED. ; -ShieldVars RECORD {return},DECREMENT ; -ShieldLeft DS.W 1 ; -ShieldTop DS.W 1 ; -ShieldRight DS.W 1 ; -ShieldBot DS.W 1 ; -return DS.L 1 ; - ENDR - - WITH ShieldVars -ShieldCursor - TST ShieldDepth ;Any shielding already? ; - BEQ.s @2 ;No=>don't unionrect - - MOVEM.L D0/A0,-(SP) ;Save some regs (and +8 our vars below*) - LEA ShieldRect+right,A0 ;A0->ShieldRect.right - - MOVE.L ShieldBot+8(SP),D0 ;D0 = New shield bot,right (*) - CMP (A0),D0 ;Compare to ShieldRect.right - BLE.s @u1 ;Is the new right bigger? - MOVE D0,(A0) - -@u1 SWAP D0 ;D0 = New shield bottom - CMP -(A0),D0 ;Compare to ShieldRect.bottom - BLE.s @u2 ;Is the new bottom bigger? - MOVE D0,(A0) ;If so, replace with it. - -@u2 MOVE.L ShieldTop+8(SP),D0 ;D0 = New shield top,left (*) - CMP -(A0),D0 ;Compare to ShieldRect.left - BGE.s @u3 ;Is the new left smaller? - MOVE D0,(A0) - -@u3 SWAP D0 ;D0 = New shield top - CMP -(A0),D0 ;Compare to ShieldRect.top - BGE.s @u4 ;Is the new top smaller? - MOVE D0,(A0) - -@u4 MOVEM.L (SP)+,D0/A0 - BRA.s @3 - -@2 MOVE.L ShieldBot(SP),ShieldRect+botRight ;save shieldrect ; - MOVE.L ShieldTop(SP),ShieldRect+topLeft ; -@3 ADDQ #1,ShieldDepth ;Shielding officially on - MOVE.B #1,CrsrBusy - BSR CursorSect ; - BEQ.s @1 ; - - BSR EraseCursor ;IT DOES INTERSECT, REMOVE IT - -@1 CLR.B CrsrBusy - MOVE.L (SP)+,(SP) ;STRIP 8 bytes of PARAMETERS, MOVING - MOVE.L (SP)+,(SP) ;RETURN ADDR UP ON STACK - RTS - - ENDWITH - - IMPORT CopyHandle,PatConvert -;_______________________________________________________________________ -; -; PROCEDURE SetCCursor(cCrsr: CCrsrHandle); -; -; This procedure copies the data in the specified color cursor into the -; system's cursor save area. If the depth > 2, it expands it. - -; this routine was taken from QDciPatchROM.a because A2 was getting trashed stb -; when setting CCursor on multiple device systems stb - -SetCCursor MOVEM.L D3-D4/A2-A4,-(SP) ;save work registers - move.l 24(sp),a2 ;get ccrsrHandle - move.l a2,a0 ;make a copy - _HGetState - move d0,-(sp) ;save state for later - move.l a2,a0 ;make a copy - _HLock - MOVE.L (a2),A2 ;GET POINTER TO NEW CURSOR - - MOVE.L ([CRSRPTR]),A3 ;point to current cursor (LOCKED) - MOVE.L crsrID(A2),D0 ;and get ID of new cursor - CMP #CCrsrPat,ccType(A3) ;is current cursor a color cursor? - BNE.S NotCC ;=>no, it has definitely changed - CMP.L ccID(A3),D0 ;same as current one? - BEQ SCCDONE ;=>yes, just return - -NotCC MOVE.B #1,CRSRBUSY ;flag the cursor as busy - MOVE.L D0,ccID(A3) ;set new ID - LEA crsr1Data(A2),A0 ;point to old-cursor data - LEA THECRSR,A1 ;put it here - MOVEQ #16,D0 ;data+mask+hotspot = 17 longs -@0 MOVE.L (A0)+,(A1)+ ;copy data - DBRA D0,@0 ;until done - - LEA crsr1Data(A2),A0 ;point to old-cursor data - LEA CCLASTCRSR(A3),A1 ;save here to indicate cursor changed - MOVEQ #7,D0 ;move 8 longs -@1 MOVE.L (A0)+,(A1)+ ;copy data - DBRA D0,@1 ;=>loop until done - - MOVE crsrType(A2),ccType(A3) ;copy the type - -; NOTE: ALL THE DST HANDLES ARE LOCKED, BUT THEY HAVE BEEN SET TO THE PROPER SIZE - - MOVE.L crsrMap(A2),-(SP) ;push src pixMap handle - MOVE.L ccMap(A3),-(SP) ;push dst pixMap handle - _CopyPixMap ;copy the pixMap - - MOVE.L crsrData(A2),-(SP) ;push src data handle - MOVE.L ccData(A3),-(SP) ;push dst data handle - _CopyHandle ;copy the cursor data - -; FOR EACH ACTIVE SCREEN DEVICE, EXPAND CURSOR, IF NECESSARY - - MOVE.L DEVICELIST,D4 ;D4 = CURRENT DEVICE - MOVE.L D4,A4 ;GET HANDLE TO CURRENT DEVICE -NXTSCR MOVE.L (A4),A4 ;A4 = POINTER TO CURRENT DEVICE - TST.W GDFLAGS(A4) ;IS THE DEVICE ACTIVE? - BPL CHKNXT ;=>NO, CHECK NEXT DEVICE - ;ACTIVE DEVICES ARE LOCKED DOWN - MOVE.L GDPMAP(A4),A0 ;GET HANDLE TO DEVICE'S PIXMAP - MOVE.L (A0),A0 ;POINT TO DEVICE'S PIXMAP - MOVE PIXELSIZE(A0),D3 ;GET DEVICE'S PIXELSIZE - -; IF THE PATTERN IS PRE-EXPANDED TO THE RIGHT DEPTH, JUST COPY THAT DATA - - CLR GDCCDEPTH(A4) ;flag to expand one-bit data - MOVE CRSRXVALID(A2),D0 ;is there pre-expanded data? - BEQ.S GOEXP ;=>no, do expansion - CMP D3,D0 ;is the expanded data the right depth? - BNE.S GOEXP ;=>no, expand from the source - MOVE D0,GDCCDEPTH(A4) ;else copy the expanded depth - MOVE.L crsrXData(A2),-(SP) ;push the src xdata handle - MOVE.L CCXDATA(A3),-(SP) ;push the dst xdata handle - _CopyHandle ;and copy it - BRA.S CHKNXT ;=>data already expanded, just exit - -GOEXP CMP #CCRSRPAT,CCTYPE(A3) ;IS IT A COLOR CURSOR? - BNE.S DONEONE ;=>NO, EXIT WITH DEPTH = 0 - CMP #2,D3 ;IS DEPTH GREATER THAN 2? - BLE.S DONEONE ;=>NO, EXIT WITH DEPTH = 0 - - MOVE D3,GDCCDEPTH(A4) ;RECORD THE EXPANDED DEPTH - MOVE.L GDCCXDATA(A4),CCXDATA(A3) ;GET DEVICE'S EXPANDED DATA FOR PATCONVERT - MOVE.L THEGDEVICE,-(SP) ;SAVE GRAFDEVICE (USED BY PATCONVERT) - MOVE.L D4,THEGDEVICE ;SET IT TO CURRENT DEVICE - MOVE.L CRSRPTR,-(SP) ;PUSH HANDLE TO CURSOR (LOCKED) - _PATCONVERT ;AND EXPAND TO CURRENT DEPTH - MOVE.L (SP)+,THEGDEVICE ;RESTORE GRAFDEVICE - -; EXPAND THE MASK TO THE CURRENT DEPTH - - MOVE D3,D0 ;GET DEPTH - MOVEQ #0,D1 ;DEFAULT SHIFT = 0 -NXTSHFT1 LSR #1,D0 ;CHECK NEXT DEPTH BIT - BCS.S GOTSHFT1 ;=>GOT SHIFT - ADDQ #1,D1 ;ELSE ADD ONE TO SHIFT - BRA.S NXTSHFT1 ;LOOP UNTIL WE HIT A ONE - -GOTSHFT1 LEA THECRSR+MASK,A0 ;SRC = CURSOR MASK - MOVE.L ([GDCCXMASK,A4]),A1 ;POINT TO EXPANDED MASK (LOCKED) - - move.l a2,d4 ;save pointer to new cursor <25APR91 KON> - MOVE.L A1,A2 ;GET START OF DST BUFFER <27May87 EHB> - MOVE #32,D0 ;GET #BYTES OF SOURCE <27May87 EHB> - LSL D1,D0 ;MULTIPLY BY DEPTH <27May87 EHB> - ADD D0,A2 ;POINT TO END OF BUFFER <27May87 EHB> - - move.l ExTblPtr,A3 ;POINT TO ROUTINE TABLE - add.l 0(A3,D1*4),A3 ;USE DEPTH TO SELECT ROUTINE - MOVEQ #0,D0 ;CLEAR HIGH PART OF D0 - JSR (A3) ;EXPAND 32*DEPTH BYTES - MOVE.L ([CRSRPTR]),A3 ;GET BACK POINTER TO CURSOR (LOCKED) - move.l d4,a2 ;restore pointer to new cursor <25APR91 KON> - -DONEONE MOVE GDCCDEPTH(A4),D0 ;GET EXPANDED DEPTH - ADD D0,D0 ;DOUBLE IT - MOVE D0,GDCCBYTES(A4) ;AND SAVE AS CURSOR'S ROWBYTES - -CHKNXT MOVE.L GDNEXTGD(A4),D4 ;IS THERE A NEXT DEVICE? - MOVE.L D4,A4 ;GET HANDLE TO NEXT DEVICE - BNE NXTSCR ;=>THERE IS ONE, PREPARE ITS CURSOR - - BSR.S GETMAINCRSR ;RESTORE EXPAND DATA FOR MAIN CURSOR - BSR ERASECURSOR ;HIDE THE OLD CURSOR - BSR DRAWCURSOR ;DISPLAY THE NEW CURSOR -SCCDONE CLR.B CRSRBUSY ;CURSOR NOT BUSY ANYMORE - move (sp)+,d0 ;get ccrsrhandle state - move.l 24(sp),a0 ;get ccrsrHandle - _HSetState - MOVEM.L (SP)+,D3-D4/A2-A4 ;restore work registers - MOVE.L (SP)+,(SP) ;strip parameter - RTS ;and return +_ShieldCursor PROC EXPORT + IMPORT QDNEW_SHIELDCURSOR + JMP QDNEW_SHIELDCURSOR ;_______________________________________________________________________ +; +; PROCEDURE InitCursor; +; +; Definitely redisplay the cursor, independent of previous calls to +; HideCursor, ShieldCursor and ObscureCursor. It falls into showCursor. +; -GETMAINCRSR MOVE.L CRSRDEVICE,A0 ;GET HANDLE TO CURSOR DEVICE - MOVE.L (A0),A0 ;GET POINTER TO CURSOR DEVICE - MOVE.L CRSRPTR,A1 ;GET HANDLE TO CURSOR SAVE AREA - MOVE.L (A1),A1 ;GET POINTER TO CURSOR SAVE - MOVE.L GDCCXDATA(A0),CCXDATA(A1) ;GET CURRENT EXPANDED DATA - MOVE.L GDCCXMASK(A0),CCXMASK(A1) ;GET CURRENT EXPANDED MASK - MOVE GDCCDEPTH(A0),CCDEPTH(A1) ;GET EXPANDED DEPTH - MOVE GDCCBYTES(A0),CCBYTES(A1) ;GET EXPANDED ROWBYTES - RTS ;AND RETURN +_InitCursor PROC EXPORT + IMPORT QDNEW_INITCURSOR + JMP QDNEW_INITCURSOR ;_______________________________________________________________________ ; @@ -847,1127 +271,45 @@ GETMAINCRSR MOVE.L CRSRDEVICE,A0 ;GET HANDLE TO CURSOR DEVICE ; It ignores the height and mask parameters. It assumes that the mask immediately ; follows the data (as it does when called from LisaGraf) ; -SetCursor MOVE.L ([CRSRPTR]),A0 ;point to crsr data structure (LOCKED) - move.b #1,crsrBusy ;don't allow vbl drawing until we're done <09Aug88> - MOVE #oldCrsrPat,ccType(A0) ;say that it's an old cursor - MOVE.L 8(SP),A0 ;get address of data mask - LEA THECRSR,A1 ;point to system cursor buffer - MOVEQ #15,D2 ;have 16 longs to move - MOVEQ #0,D1 ;flag that its not different +_SetCursor PROC EXPORT + IMPORT QDNEW_SETCURSOR + JMP QDNEW_SETCURSOR -SetCurLoop MOVE.L (A0)+,D0 ;get next longWord of new cursor - CMP.L (A1),D0 ;is it the same as what's there - BEQ.S @1 ;if so, skip - ADDQ #1,D1 ;flag that its different -@1 MOVE.L D0,(A1)+ ;move it into the cursor buffer - DBRA D2,SetCurLoop ;move all 64 bytes - - MOVE.L 14(SP),D0 ;get the alleged hotspot <23Apr85> - -; Clean up the two coordinates to lie between 0 and 16. <23Apr85> - - MOVEQ #16,D2 ; VERY handy temp, from loop above <23Apr85> - CMP.W D2,D0 ; <23Apr85> - BLS.S @31 ; D0 LowerorSame as 16 is ok <23Apr85> - MOVE.W D2,D0 ;pin it at 16 <23Apr85> - -@31 SWAP D0 ;align the high-order coord <23Apr85> - CMP.W D2,D0 ; <23Apr85> - BLS.S @33 ; D0 LowerorSame as 16 is ok <23Apr85> - MOVE.W D2,D0 ; <23Apr85> - -@33 SWAP D0 ;realign coords <23Apr85> - CMP.L TheCrsr+HotSpot,D0 ;is it new? <05Apr85> - BEQ.S @3 ; <05Apr85> - ADDQ #1,D1 ;flag it's different <05Apr85> - MOVE.L D0,TheCrsr+HotSpot ;move in the hotSpot <05Apr85> -@3 - -; DID THE CURSOR CHANGE? - - clr.b crsrBusy ;re-allow vbl drawing <09Aug88> - TST D1 ;did it change? - BEQ.S @6 ;skip if it didn't - -; IF SO, FORCE THE CURSOR TO BE REDISPLAYED BY HIDING AND THEN SHOWING IT - - BSR EraseCursor ;hide it - BSR DrawCursor ;then show it again to redraw it - -@6 MOVE.L (SP)+,A0 ;get return address - ADD #14,SP ;strip parameters - JMP (A0) ;return to caller - - - -SetCrsrData PROC EXPORT -;------------------------------------------------ -; UTILITY SetCrsrData +;_______________________________________________________________________ ; -; This routine is called to initialize low-memory locations -; to the necessary values for the grafDevice pointer in A1. +; PROCEDURE ObscureCursor -- called via the jump table +; +; Removes the cursor from the screen without hiding it, so the next +; time the mouse moves, it will show up again. ; - IMPORT SetCrsrDelay ; CSS - bsr.l SetCrsrDelay ; CSS - MOVE.L CRSRPTR,A0 ;get handle to cursor data - MOVE.L (A0),A0 ;get pointer to cursor data -; initialize the grafDevice's cursor variables +_ObscureCursor PROC EXPORT + IMPORT QDNEW_OBSCURECURSOR + JMP QDNEW_OBSCURECURSOR - MOVE.L GDCCXDATA(A1),CCXDATA(A0) ;copy handle to expanded data - MOVE.L GDCCXMASK(A1),CCXMASK(A0) ;copy handle to expanded mask - MOVE GDCCDEPTH(A1),CCDEPTH(A0) ;copy depth - MOVE GDCCBYTES(A1),CCBYTES(A0) ;copy expanded rowbytes - -; set the pinning rectangle to the current screen - - LEA GDRect(A1),A0 ;get rect for current device - MOVE.L (A0)+,crsrPin ;and set pinning rectangle - MOVE.L (A0),crsrPin+4 ;from device's rectangle - -; set the depth, rowbytes, height, and width of the current screen - - MOVE.L GDPMap(A1),A0 ;get pixMap of current device - MOVE.L (A0),A0 ;point at pixmap - MOVE PixelSize(A0),chunkyDepth ;set depth of cursor's screen - MOVE.L (A0)+,crsrBase ;update base address for cursor - MOVE (A0)+,D0 ;get rowbytes - AND #nuRBMask,D0 ;clear flag bits - MOVE D0,crsrRow ;set cursor rowbytes - MOVE bottom(A0),D0 ;get bottom of cursor's screen - SUB top(A0),D0 ;calc height of cursor's screen - MOVE D0,ColLines ;save height of cursor's screen - MOVE right(A0),D0 ;get right of cursor's screen - SUB left(A0),D0 ;calc width of cursor's screen - MOVE D0,RowBits ;save width of cursor's screen - RTS - - -ALLOCCRSR PROC EXPORT - IMPORT PatConvert,GETMAINCRSR,SetCrsrData - IMPORT RNEWHANDLE,ERASECURSOR,DRAWCURSOR ;-------------------------------------------------- ; ; PROCEDURE AllocCrsr; ; ; Allocates all global cursor data structures. A maximum depth of 8 is assumed. ; -; CRSRPTR IS USED AS A HANDLE TO AN EXTENDED PATTERN WHICH CONTAINS THESE FIELDS: -; -; CCTYPE EQU 0 ;[WORD] CURSOR TYPE -; CCMAP EQU CCTYPE+2 ;[LONG] HANDLE TO CURSOR'S PIXMAP -; CCDATA EQU CCMAP+4 ;[LONG] HANDLE TO CURSOR'S COLOR DATA -; CCXDATA EQU CCDATA+4 ;[LONG] HANDLE TO EXPANDED DATA -; CCXMASK EQU CCXDATA+4 ;[LONG] HANDLE TO EXPANDED MASK -; CCSAVE EQU CCXMASK+4 ;[LONG] HANDLE TO SAVE BITS UNDER CURSOR -; CCLASTCRSR EQU CCSAVE+4 ;[32 BYTES] DATA FOR LAST B/W CURSOR DRAWN -; CCID EQU CCLASTCRSR ;[LONG] ID FOR LAST COLOR CURSOR DRAWN -; CCTABLE EQU CCID+4 ;[LONG] TABLE ID FOR LAST COLOR CURSOR -; CCDEPTH EQU CCLASTCRSR+32 ;[WORD] DEPTH FOR LAST CURSOR DRAWN -; CCSTATEREGS EQU CCDEPTH+2 ;[20 BYTES] STATE INFO OF SAVED DATA -; CCBYTES EQU CCSTATEREGS+16 ;[WORD] ROWBYTES OF EXPANDED DATA -; CCMAXDEPTH EQU CCBYTES+2 ;[WORD] MAXIMUM CURSOR DEPTH - - MOVEM.L D0-D6/A0-A4/A6,-(SP) ;PRESERVE ALL REGS - MOVE.L THEZONE,-(SP) ;SAVE THE CURRENT HEAP ZONE - MOVE.L SYSZONE,THEZONE ;SET CURRENT ZONE TO SYS ZONE - -; ALLOCATE MAIN CURSOR STRUCTURE AND DATA AREAS IF NECESSARY - - BSR ERASECURSOR ;HIDE THE CURSOR - MOVE.B #1,CRSRBUSY ;MARK CHANGE IN PROGRESS - - MOVE.L CRSRPTR,D0 ;GET CRSRPTR (REALLY HANDLE) - CMP.L MINUSONE,D0 ;IS IT ALLOCATED? - BNE.S MAINOK ;=>ALREADY ALLOCATED, CONTINUE - -; RESERVE MEMORY FOR AND ALLOCATE CURSOR STRUCTURE. -; THE CURSOR SAVE RECORD CONTAINS A PIXMAP, A DATA HANDLE, AND A SAVE HANDLE. - - clr.b CrsrObscure ;we wont be obscure no more - clr CrsrState ;reset state to 0 - clr ShieldDepth ;no more shielding - - MOVEQ #CCSAVEREC,D1 ;GET SIZE OF CURSOR SAVE RECORD - BSR GETLOWHANDLE ;ALLOCATE RECORD DOWN LOW AND LOCK - MOVE.L A0,CRSRPTR ;SAVE HANDLE TO CURSOR - MOVE.L (A0),A4 ;KEEP POINTER IN A4 - - MOVEQ #PMREC,D0 ;WE'RE GOING TO LOCK THIS - _RESRVMEM ;SO RESERVE SPACE DOWN LOW - CLR.L -(SP) ;MAKE ROOM FOR FUNCTION RESULT - _NEWPIXMAP ;ALLOCATE A PIXMAP - MOVE.L (SP)+,A0 ;GET HANDLE TO PIXMAP - MOVE.L A0,CCMAP(A4) ;SAVE PIXMAP IN CURSOR RECORD - _HLOCK ;LOCK IT DOWN - - MOVEQ #2,D0 ;DEFAULT SIZE OF DATA HANDLE - JSR RNEWHANDLE ;ALLOCATE IT - MOVE.L A0,CCDATA(A4) ;AND SAVE FOR CURSOR DATA - -; RESERVE AND ALLOCATE MEMORY IN WHICH TO SAVE THE BITS BEHIND THE CURSOR. -; MAGIC AMOUNT OF MEMORY RESERVED IS FOR 32 BIT DEEP, LONG ALIGNED CURSOR. - - if cursorShadow then - MOVE.L #$400*4,D1 ;GET REQUIRED SIZE 32*32*4 - else - MOVE.L #$400,D1 ;GET REQUIRED SIZE 16*16*4 - endif - BSR GETLOWHANDLE ;GET LOW,LOCKED HANDLE - MOVE.L A0,CCSAVE(A4) ;SAVE INTO RECORD - -; INITIALIZE THE CURSOR TO THE ARROW CURSOR. - - MOVE #OLDCRSRPAT,CCTYPE(A4) ;SAY THAT IT'S AN OLD CURSOR - CLR CCDEPTH(A4) ;CLEAR DEPTH TO SAY NOT EXPANDED - - MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO GRAFGLOBALS - LEA ARROW(A0),A0 ;POINT TO ARROW CURSOR - LEA THECRSR,A1 ;PUT IT HERE - MOVEQ #16,D0 ;DATA+MASK+HOTSPOT = 17 LONGS -@2 MOVE.L (A0)+,(A1)+ ;COPY DATA - DBRA D0,@2 ;UNTIL DONE - - -; FOR EACH ACTIVE SCREEN DEVICE, ALLOCATE EXPANDED CURSOR MEMORY IF NECESSARY -; ALL DEVICES ARE GUARANTEED TO BE LOCKED. - -MAINOK MOVE.L CRSRPTR,A4 ;GET HANDLE TO CURSOR STUFF - MOVE.L (A4),A4 ;GET POINTER (LOCKED) - MOVE.L DEVICELIST,D4 ;D4 = CURRENT DEVICE - MOVE.L D4,A6 ;GET HANDLE TO CURRENT DEVICE -NXTDEVICE MOVE.L (A6),A6 ;A6 = POINTER TO CURRENT DEVICE - TST.W GDFLAGS(A6) ;IS THE DEVICE ACTIVE? - BPL CHKNEXT ;=>NO, CHECK NEXT DEVICE - - TST GDCCDEPTH(A6) ;HAS MEMORY BEEN ALLOCATED? - BNE.S DOEXPAND ;=>YES, EXPAND CURSOR IF NECESSARY - - MOVE.L GDCCXDATA(A6),A0 ;GET HANDLE TO EXPANDED DATA - _DISPOSHANDLE ;DISPOSE THE CURRENT HANDLE - MOVE.L #$400,D1 ;GET SIZE OF EXPANDED HANDLE @@@@ used to be $100 - BSR GETLOWHANDLE ;GET A LOW, LOCKED HANDLE - MOVE.L A0,GDCCXDATA(A6) ;AND SAVE IT - - MOVE.L GDCCXMASK(A6),A0 ;GET HANDLE TO EXPANDED DATA - _DISPOSHANDLE ;DISPOSE THE CURRENT HANDLE - BSR GETLOWHANDLE ;GET A LOW, LOCKED HANDLE - MOVE.L A0,GDCCXMASK(A6) ;AND SAVE IT - -DOEXPAND -; MAKE SURE ALL THE HANDLES ARE THE RIGHT SIZE FOR THE CURRENT DEPTH. -; IF COLOR CURSOR AND DEPTH IS > 2 BITS PER PIXEL, THEN EXPAND TO CURRENT DEPTH. -; BLACK AND WHITE (AND 2 BIT) CURSORS ARE EXPANDED BY SHOWCURSOR. - - MOVE.L GDPMAP(A6),A0 ;GET HANDLE TO DEVICE'S PIXMAP - MOVE.L (A0),A0 ;POINT TO DEVICE'S PIXMAP - MOVE PIXELSIZE(A0),D3 ;GET DEVICE'S PIXELSIZE - CMP GDCCDEPTH(A6),D3 ;HAS DEPTH CHANGED? - BEQ.S CHKNEXT ;=>NO, THIS DEVICE IS OK - -; CONVERT DEPTH TO SHIFT AMOUNT IN D6 - - MOVE D3,D0 ;GET DEPTH - MOVEQ #0,D6 ;DEFAULT SHIFT = 0 -NXTSHFT LSR #1,D0 ;CHECK NEXT DEPTH BIT - BCS.S GOTSHFT ;=>GOT SHIFT - ADDQ #1,D6 ;ELSE ADD ONE TO SHIFT - BRA.S NXTSHFT ;LOOP UNTIL WE HIT A ONE - -GOTSHFT CMP #CCRSRPAT,CCTYPE(A4) ;IS IT A COLOR CURSOR? - BNE.S CHKNEXT ;=>NO - CMP #2,D3 ;IS DEPTH GREATER THAN 2? - BLE.S CHKNEXT ;=>NO - - MOVE.L GDCCXDATA(A6),CCXDATA(A4) ;GET EXPAND HANDLE FOR PATCONVERT - MOVE.L THEGDEVICE,-(SP) ;SAVE GRAFDEVICE - MOVE.L D4,THEGDEVICE ;SET IT TO CURRENT DEVICE - MOVE.L CRSRPTR,-(SP) ;PUSH HANDLE TO CURSOR - _PATCONVERT ;AND EXPAND TO CURRENT DEPTH - MOVE.L (SP)+,THEGDEVICE ;RESTORE GRAFDEVICE - -; EXPAND THE MASK TO THE CURRENT DEPTH - - LEA THECRSR+MASK,A0 ;SRC = CURSOR MASK - MOVE.L ([GDCCXMASK,A6]),A1 ;POINT TO EXPANDED MASK (LOCKED) - MOVE.L A1,A2 ;GET START OF DST BUFFER - MOVE #32,D0 ;GET #BYTES OF SOURCE - LSL D6,D0 ;MULTIPLY BY DEPTH - ADD D0,A2 ;POINT TO END OF BUFFER - - move.l ExTblPtr,A3 ;POINT TO ROUTINE TABLE - add.l 0(A3,D6*4),A3 ;USE DEPTH TO SELECT ROUTINE - MOVEQ #0,D0 ;CLEAR HIGH PART OF D0 - JSR (A3) ;EXPAND 32*DEPTH BYTES - - MOVE D3,GDCCDEPTH(A6) ;SAVE DEPTH OF EXPANDED CURSOR - ADD D3,D3 ;GET 2*DEPTH - MOVE D3,GDCCBYTES(A6) ;SAVE ROWBYTES FOR EXPANDED CURSOR - -CHKNEXT MOVE.L GDNEXTGD(A6),D4 ;IS THERE A NEXT DEVICE? - MOVE.L D4,A6 ;GET HANDLE TO NEXT DEVICE - BNE NXTDEVICE ;=>THERE IS ONE, PREPARE ITS CURSOR - - BSR GETMAINCRSR ;SET UP FIELDS FOR MAIN CURSOR - MOVE.L CRSRDEVICE,A1 ;GET HANDLE TO CURSOR DEVICE - MOVE.L (A1),A1 ;GET POINTER TO CURSOR DEVICE - JSR SetCrsrData ;AND SET UP LOW-MEM FOR THIS DEVICE - - MOVE.L (SP)+,THEZONE ;RESTORE THE ZONE - CLR.B CRSRBUSY ;CHANGE COMPLETE - BSR DRAWCURSOR - MOVEM.L (SP)+,D0-D6/A0-A4/A6 ;RESTORE ALL REGS - RTS - - -GETLOWHANDLE -;-------------------------------------------------- -; UTILITY GETLOWHANDLE -; -; THIS ROUTINE RESERVES MEMORY FOR A HANDLE, ALLOCATES THE HANDLE -; AND THEN LOCKS IT DOWN. THE DESIRED SIZE IS IN D1. THE RETURNED HANDLE IS IN A0 -; ONLY D0 IS TRASHED - - MOVE.L D1,D0 ;GET THE DESIRED SIZE - _RESRVMEM ;RESERVE SPACE FOR THE HANDLE DOWN LOW - BNE.S MEMFULL ;=>ON ERROR, JUST BOMB - MOVE.L D1,D0 ;GET THE DESIRED SIZE - _NEWHANDLE ,CLEAR ;ALLOCATE THE HANDLE - _HLOCK ;LOCK IT - RTS ;AND RETURN - -MEMFULL MOVEQ #25,D0 ;MEM FULL ERROR - _SYSERROR ;FLAG IT - DC.W $A9FF ;JUST IN CASE WE RETURN +AllocCrsr PROC EXPORT + IMPORT QDNEW_ALLOCCRSR + JMP QDNEW_ALLOCCRSR ;_______________________________________________________________________ ; -; BLITCURSOR +; PROCEDURE SetCCursor(cCrsr: CCrsrHandle); ; -; The only thing that will stop this routine from blitting the cursor -; to the screen is ShieldRect. Since the new CrsrRect isn't known -; until pretty far through the process, it's checked here, not -; DrawCursor. CrsrState and CrsrObscure are _not_ checked here. -; It seems likely that patching this routine will have use on accelerator -; cards etc. - -BLITCURSOR PROC EXPORT - IMPORT CursorSect, SHFTTBL - - TST.L CRSRPTR ;CURSOR ALLOCATED? - BMI NoBlit ;=>NO, JUST RETURN - MOVEM.L D0-D7/A0-A6,-(SP) ;SAVE REGISTERS - LEA THECRSR+DATA,A2 ;POINT TO THE CURSOR - - -;----------------------------------------------- +; This procedure copies the data in the specified color cursor into the +; system's cursor save area. If the depth > 2, it expands it. ; -; CONVERT CHUNKY DEPTH TO SHIFT AMOUNT IN D7 -; - LEA SHFTTBL,A0 ;TO CONVERT DEPTH TO SHIFT - MOVE CHUNKYDEPTH,D1 ;GET DEPTH - MOVEQ #0,D7 ;DEFAULT SHIFT = 0 - MOVE.B 0(A0,D1),D7 ;GET SHIFT AMOUNT IN D7 - - -;----------------------------------------------- -; -; CHECK THE CURSOR TO SEE IF IT HAS CHANGED -; OLD CURSORS: CHECK CURSOR DATA AND DEPTH -; NEW CURSORS: CHECK DEPTH -; -GOTSHFT MOVE.L ([CRSRPTR]),A4 ;GET POINTER TO CURSOR DATA (LOCKED) - CMP #CCRSRPAT,CCTYPE(A4) ;IS IT A COLOR CURSOR? - BNE.S OLDCUR ;=>NO, JUST AN OLD ONE - CMP CCDEPTH(A4),D1 ;HAS DEPTH CHANGED? - BEQ NOEXPAND ;=>NO, DON'T EXPAND - CMP #2,D1 ;IS DEPTH 2 or 1? - BGT EXPMASK ;=>NO, JUST EXPAND MASK - BRA.S CPYDATA ;=>ELSE JUST COPY DATA - -OLDCUR LEA CCLASTCRSR(A4),A0 ;POINT TO SAVED DATA - MOVE.L A2,A1 ;GET POINTER TO CURSOR - MOVEQ #7,D0 ;CHECK 8 LONGS -@0 CMP.L (A0)+,(A1)+ ;ARE THEY THE SAME? - BNE.S GOEXPAND ;=>NO, EXPAND IT - DBRA D0,@0 ;=>LOOP UNTIL DONE - - CMP CCDEPTH(A4),D1 ;HAS DEPTH CHANGED? - BEQ NOEXPAND ;=>NO, DON'T EXPAND - -GOEXPAND -;----------------------------------------------- -; -; INVALIDATE EXPANDED DATA FOR EACH DEVICE BY CLEARING DEPTH -; THIS MUST BE DONE SO THAT ALL EXPANDED CURSOR IMAGES ARE RENDERED INVALID AFTER -; AN OLD CURSOR HAS BEEN SET. IF THE CURSOR IS NEW, SETCCURSOR ALREADY DID THIS. - - MOVE.L DEVICELIST,A0 ;GET FIRST HANDLE IN DEVICE LIST -NXTGD MOVE.L (A0),A0 ;POINT TO FIRST DEVICE - TST GDFLAGS(A0) ;IS IT ACTIVE? - BPL.S NOTACT ;=>NO, SKIP TO NEXT - CLR GDCCDEPTH(A0) ;ELSE INVALIDATE EXPANDED DATA -NOTACT MOVE.L GDNEXTGD(A0),D0 ;GET NEXT GRAFDEVICE - MOVE.L D0,A0 ;GET INTO A0 - BNE.S NXTGD ;=>REPEAT FOR ALL DEVICES - -; COPY THE CURSOR DATA TO IDENTIFY THIS CURSOR - -CPYDATA LEA CCLASTCRSR(A4),A0 ;POINT TO SAVED DATA - MOVE.L A2,A1 ;GET CURSOR - MOVEQ #7,D0 ;MOVE 8 LONGS -@0 MOVE.L (A1)+,(A0)+ ;MOVE A LONG - DBRA D0,@0 ;=>LOOP UNTIL DONE - -; UPDATE THE ROWBYTES AND DEPTH FOR THE EXPANDED DATA - - ; MOVE D1,(A0)+ ;COPY THE DEPTH TOO - MOVE D1,CCDEPTH(A4) ;SET DEPTH TO SAY IT'S EXPANDED - ADD D1,D1 ;DOUBLE FOR CURSOR'S ROWBYTES - MOVE D1,CCBYTES(A4) ;AND UPDATE ROWBYTES - - -;----------------------------------------------- -; -; EXPAND THE CURSOR TO THE CURRENT DEPTH -; - MOVE.L A2,A0 ;SRC = CURSOR - MOVE.L ([CCXDATA,A4]),A1 ;POINT TO EXPANDED DATA (LOCKED) - MOVE.L A1,A2 ;GET START OF DST BUFFER - MOVE #32,D5 ;GET #BYTES OF SOURCE - LSL D7,D5 ;MULTIPLY BY DEPTH - ADD D5,A2 ;POINT TO END OF BUFFER - - move d7,d0 - cmp #4,d0 ;16/32 bits per pixel? - blt.s @1 ;no, don't hack depth conversion - addq #2,d0 ;get address of spiffy 1 to 15/24 bit expand - -@1 move.l ExTblPtr,A3 ;POINT TO ROUTINE TABLE - add.l 0(A3,D0*4),A3 ;USE DEPTH TO SELECT ROUTINE - MOVEQ #0,D0 ;CLEAR HIGH PART OF D0 - JSR (A3) ;EXPAND 32*DEPTH BYTES - - -;----------------------------------------------- -; -; EXPAND THE MASK TO THE CURRENT DEPTH -; -EXPMASK LEA THECRSR+MASK,A0 ;SRC = CURSOR MASK - MOVE.L ([CCXMASK,A4]),A1 ;POINT TO EXPANDED MASK (LOCKED) - MOVE.L A1,A2 ;GET START OF DST BUFFER - MOVE #32,D5 ;GET #BYTES OF SOURCE - LSL D7,D5 ;MULTIPLY BY DEPTH - ADD D5,A2 ;POINT TO END OF BUFFER - - move.l ExTblPtr,A3 ;POINT TO ROUTINE TABLE - add.l 0(A3,D7*4),A3 ;USE DEPTH TO SELECT ROUTINE - MOVEQ #0,D0 ;CLEAR HIGH PART OF D0 - JSR (A3) ;EXPAND 32*DEPTH BYTES - -;----------------------------------------------- -; -; PREPARE TO BLT THE CURSOR ON THE SCREEN IN ANY DEPTH -; (SUBTITLE: WALTZ OF THE REGISTERS) -; -NOEXPAND - MOVE.L ([CCXDATA,A4]),d0 ;A2 = EXPANDED DATA FOR BLT (LOCKED) - _rTranslate24To32 ;strip off high byte - move.l d0,a2 - MOVE.L ([CCXMASK,A4]),d0 ;A3 = EXPANDED MASK FOR BLT (LOCKED) - _rTranslate24To32 ;strip off high byte - move.l d0,a3 - MOVEQ #16,D5 ;D5 = 16 - -;----------------------------------------------- -; -; CLIP THE CURSOR VERTICALLY AND GET THE TOP AND BOTTOM INTO D2 AND D3. -; IF THE TOP IS CLIPPED, UPDATE THE DATA BASE ADDRESSES IN A2 AND A3. -; - MOVE MOUSE+V,D2 ;MOUSE POSITION Y - SUB CRSRPIN+TOP,D2 ;CONVERT TO SCREEN LOCAL COORDS - SUB THECRSR+HOTSPOT+V,D2 ; - HOTSPOT = TOP EDGE - MOVE D2,D3 ;GET CURSOR BOTTOM - ADD D5,D3 ; = TOP + 16 - CMP D5,D3 ;AT TOP? - BGE.S CHKBOT ;=>NOT AT TOP - NEG D2 ;GET NUMBER OF CLIPPED ROWS - CMP D5,D2 ;ARE ALL 16 CLIPPED? - BEQ SkipBlit ;=>IF SO, NOTHING TO SHOW - MULU CCBYTES(A4),D2 ; * ROWBYTES FOR OFFSET - ADD.L D2,A2 ;ADD VERTICAL OFFSET INTO CURSOR - ADD.L D2,A3 ;ADD VERTICAL OFFSET INTO MASK - MOVEQ #0,D2 ;AND PIN CURSOR TO TOP - -CHKBOT MOVE COLLINES,D4 ;GET BOTTOM OF SCREEN - CMP D4,D3 ;PAST BOTTOM? - BLE.S CHKLFT ;=>NO, VERTICAL OK - MOVE D4,D3 ;ELSE PIN TO BOTTOM EDGE - - -;----------------------------------------------- -; -; CLIP THE CURSOR HORIZONTALLY AND GET THE LEFT AND RIGHT INTO D0 AND D1 -; IF THE LEFT OF THE CURSOR IS CLIPPED, ADJUST THE OFFET IN D6. - -CHKLFT MOVEQ #0,D6 ;INIT SRC/DST OFFSET TO 0 - MOVE MOUSE+H,D0 ;MOUSE POSITION X - SUB CRSRPIN+LEFT,D0 ;CONVERT TO SCREEN LOCAL COORDS - SUB THECRSR+HOTSPOT+H,D0 ; - HOTSPOT = CURSOR LEFT - MOVE D0,D1 ;GET CURSOR RIGHT - ADD D5,D1 ; = LEFT + 16 - CMP D5,D1 ;AT LEFT EDGE? - BGE.S CHKRT ;=>NOT AT LEFT EDGE - SUB D0,D6 ;OFFSET = AMOUNT CLIPPED - MOVEQ #0,D0 ;AND PIN TO LEFT EDGE - -CHKRT MOVE ROWBITS,D4 ;GET RIGHT EDGE OF SCREEN - CMP D4,D1 ;PAST RIGHT EDGE? - BLE.S RTOK ;=>NO, HORIZONTAL OK - MOVE D4,D1 ;ELSE PIN TO RIGHT EDGE -RTOK - -;----------------------------------------------- -; -; USE TOP AND LEFT TO CALCULATE THE LONG ALIGNED SCREEN BASE ADDRESS - - MOVE.L CRSRBASE,A5 ;A5 = POINTER TO BASE OF SCREEN - MOVE CRSRROW,A0 ;A0 = SCREEN ROWBYTES - MOVE A0,D4 ;COPY FOR MULU - MULU D2,D4 ;TOP * ROWBYTES - ADD.L D4,A5 ;ADD VERT OFFSET INTO SCREEN - ext.l d0 ;make it a long - LSL.l D7,D0 ;CONVERT LEFT PIXELS TO BITS - MOVE.l D0,D4 ;GET LEFT EDGE - AND.l #~$1F,D4 ;LONGWORD ALIGNED - MOVE.l D4,D5 ;MAKE A COPY - ASR.l #3,D5 ;CONVERT BITS TO BYTES - ADD.l D5,A5 ;GET BASE OFFSET IN SCREEN - -;----------------------------------------------- -; -; SAVE THE CRSRRECT FOR CURSHIELD - - LEA CrsrRect,A1 ;SET UP CRSRRECT - MOVE D2,(A1)+ ;TOP - MOVE.l D4,D5 ;GET LONG ALIGNED LEFT IN BITS - LSR.l D7,D5 ;CONVERT TO PIXELS - MOVE D5,(A1)+ ;LONG ALIGNED LEFT - MOVE D3,(A1)+ ;BOTTOM - MOVE D5,(A1) ;RIGHT = LEFT + longcount/pixs in long - - if cursorShadow then - add.w #16,-2(a1) ;grow height for shadow - add.w #16,(a1) ;grow width for shadow - endif - -SAMELONG -;----------------------------------------------- -; -; ADJUST DST/SRC OFFSET IN D6 -; GET NUMBER OF ROWS TO DO IN D3 -; GET LONGCNT IN D5 AND USE TO ADJUST DSTBUMP IN A0 - - AND #$1F,D0 ;GET LEFT EDGE MOD 32 - LSL D7,D6 ;CONVERT OFFSET TO BITS - SUB D0,D6 ; = NEG OFFSET FROM SOURCE - - ext.l d1 ;make it a long - LSL.l D7,D1 ;CONVERT RIGHT EDGE TO BITS - MOVE.l D1,D5 ;MAKE COPY - SUB.l D4,D5 ;GET WIDTH OF CURSOR - ble SkipBlit ;crsr fits in 0 or fewer longs so don't draw - subq #1,d5 ;force multiples of 32 to round down - - LSR.l #5,D5 ;GET LONGS-1 - - SUB D2,D3 ;D3 = # ROWS TO DO - SUBQ #1,D3 ;MAKE IT 0 BASED - - MOVE.l D5,D2 ;GET LONGS - ADDQ.l #1,D2 ;MAKE ONE BASED - LSL.l #2,D2 ;CONVERT TO BYTES - SUB.l D2,A0 ;ADJUST DST BUMP - - lsl.l #3,d2 ;get long aligned bit width - lsr.l d7,d2 ;get effective cursr pixel width - add d2,(a1) ;adjust crsrRect.right = left+width - - BSR CursorSect ;Now then, do we intersect shield? - BNE SkipBlit ;If so, ththat's all. - -;----------------------------------------------- -; -; CONVERT LEFT EDGE AND RIGHT EDGE TO LEFTMASK AND RIGHTMASK IN D4 AND D2 - - MOVEQ #-1,D4 ;FILL LONG WITH ONES - LSR.L D0,D4 ;AND SHIFT IN 0'S FOR LEFTMASK - - MOVEQ #-1,D2 ;FILL LONG WITH ONES - AND #$1F,D1 ;GET RIGHT MOD 32 - beq.s @1 ;does right have a real mask? no, flush it - LSR.L D1,D2 ;AND SHIFT 0'S IN FROM RIGHT - NOT.L D2 ;GET RIGHTMASK - -;----------------------------------------------- -; -; SAVE DSTLEFT/DSTBUMP/LONGCNT/ROWCNT INTO CRSRPTR SO THAT -; HIDECURSOR KNOWS HOW MUCH SCREEN TO REPLACE. - -@1 LEA CCBYTES(A4),A6 ;POINT TO END OF SAVE STATE AREA - MOVE (A6),A1 ;A1 = ROWBYTES FOR EXPANDED CURSOR - MOVE.L ([CCSAVE,A4]),d0 ;A4 = POINTER TO SAVE AREA (LOCKED) - _rTranslate24To32 ;strip off high byte - move.l d0,a4 - MOVEM.L A5/A0/D5/D3,-(A6) ;SAVE DSTLEFT/DSTBUMP/LONGCNT/ROWCNT - - moveq #true32b,d0 ;switch to 32 bit addressing - movem.l a0-a2,-(sp) ;save off registers - _rSwapMMUMode ;get previous mode in d0.b (can trash a0/a2, d0/d2) - movem.l (sp)+,a0-a2 ;restore registers - move.b d0,-(sp) ;save previous state for later - - MOVE.L D5,A6 ;SAVE LONGCNT - EXT.L D6 ;BFEXTU LIKES LONG OFFSETS - MOVE.L D6,-(SP) ;SAVE OFFSET ON STACK - MOVE.L D4,-(SP) ;SAVE LEFTMASK ON STACK - - ;use alternate loop if on Direct Device - - cmp #4,d7 ;are we 16 or 32 bits/pixel (direct device) ? - bge Direct ;no, don't hack - - if cursorShadow then - cmp #3,d7 - beq Shadow8 - endif - - TST D5 ;CHECK FOR JUST ONE LONG - BRA.S START ;AND JUMP INTO MIDDLE - -;----------------------------------------------- -; -; DISPLAY THE CURSOR AND SAVE THE BITS BEHIND IT (DO THE CURSOR LIMBO!!) -; -; THE FUNNY TRANSFER MODE USED HERE WORKS THE SAME AS BEFORE FOR ONE BIT -; MODE, AND SIMILARLY FOR COLOR. IN COLOR, THE DATA PIXELS WITHIN THE MASK -; REPLACE THE DESTINATION; THE DATA PIXELS OUTSIDE THE MASK ARE XORED WITH -; THE DST. IF THE DATA PIXELS OUTSIDE OF THE MASK ARE BLACK (ALL F'S), -; THEN THE DST IS SIMPLY INVERTED. IF THEY ARE OTHER COLORS, INTERESTING -; EFFECTS WILL MANIFEST THEMSELVES. -; -; REGISTER USE: D0: SCRATCH A0: DSTBUMP -; D1: SCRATCH A1: SRCBUMP -; D2: RIGHTMASK A2: SRCPTR -; D3: ROWCNT A3: MASKPTR -; D4: LEFTMASK A4: SAVEPTR -; D5: LONGCNT A5: DSTPTR -; D6: OFFSET A6: COPY LONGCNT -; D7: SCRATCH (A7): LEFTMASK -; 4(A7): COPY OFFSET - -END AND.L D2,D4 ;AND RIGHTMASK INTO LEFTMASK -MAIN BFEXTU (A2){D6:0},D0 ;EXTRACT A LONG OF SRC - BFEXTU (A3){D6:0},D1 ;EXTRACT A LONG OF MASK - ADD.L #32,D6 ;BUMP TO NEXT LONG - AND.L D4,D0 ;AND SRC WITH LEFTMASK - AND.L D4,D1 ;AND MASK WITH LEFTMASK - MOVE.L D0,D7 ;COPY SRC - - AND.L D1,D7 ;GET MASK AND SRC (PIXELS TO REPLACE) - NOT.L D1 ;GET NOTMASK - MOVE.L (A5),d4 ;get a long of screen - move.l d4,(A4)+ ;SAVE A LONG OF SCREEN - - AND.L D1,D0 ;GET NOTMASK AND SRC (PIXELS TO INVERT) - AND.L d4,D1 ;PUNCH HOLE FOR PIXELS TO REPLACE (used to be A5) - OR.L D7,D1 ;REPLACE PIXELS WITHIN MASK - EOR.L D0,D1 ;INVERT PIXELS OUTSIDE OF MASK - MOVE.L D1,(A5)+ ;AND PUT TO DST - MOVEQ #-1,D4 ;FLUSH LEFTMASK - SUB #1,D5 ;DECREMENT LONGCNT -START BGT.S MAIN ;=>MORE THAN ONE TO DO - BEQ.S END ;=>DO LAST LONG - MOVE.L 4(SP),D6 ;RESTORE OFFSET - MOVE.L (SP),D4 ;RESTORE LEFTMASK - ADD.L A1,A3 ;BUMP CURSOR DATA - ADD.L A1,A2 ;BUMP CURSOR MASK - ADD.L A0,A5 ;BUMP SCREEN POINTER - MOVE.L A6,D5 ;RESTORE LONGCNT (TEST D5) - DBRA D3,START ;=>DO NEXT ROW - - bra DoneBlit - - -Direct - bgt.s Direct32 - -;----------------------------------------------- -; -; DISPLAY THE CURSOR AND SAVE THE BITS BEHIND IT (DO THE CURSOR LIMBO!!) -; -; THE FUNNY TRANSFER MODE USED HERE WORKS THE SAME AS BEFORE FOR ONE BIT -; MODE, AND SIMILARLY FOR COLOR. IN COLOR, THE DATA PIXELS WITHIN THE MASK -; REPLACE THE DESTINATION; THE DATA PIXELS OUTSIDE THE MASK ARE XORED WITH -; THE DST. IF THE DATA PIXELS OUTSIDE OF THE MASK ARE BLACK (ALL F'S), -; THEN THE DST IS SIMPLY INVERTED. IF THEY ARE OTHER COLORS, INTERESTING -; EFFECTS WILL MANIFEST THEMSELVES. -; -; REGISTER USE: D0: SCRATCH A0: DSTBUMP -; D1: SCRATCH A1: SRCBUMP -; D2: RIGHTMASK A2: SRCPTR -; D3: ROWCNT A3: MASKPTR -; D4: LEFTMASK A4: SAVEPTR -; D5: LONGCNT A5: DSTPTR -; D6: OFFSET A6: COPY LONGCNT -; D7: SCRATCH (A7): LEFTMASK -; 4(A7): COPY OFFSET -Direct16 - swap d4 - - addq #1,d5 ;make one based - add d5,d5 ;convert longcnt to word cnt - move d5,d0 ;save pixel cnt - subq #2,d5 ;make zero based - 1 - move d5,a6 ;save a copy for later scans - - moveq #-1,d7 - lsr.w #1,d7 ;make into low15bits mask - - add d0,d0 ;make into byte cnt - sub d0,a1 ;make srcRow into srcBump - - asr #3,d6 ;make offset into bytes - add d6,a2 ;adjust src ptr - add d6,a3 ;adjust mask ptr - -@first tst d4 ;is left pixel masked? - bne.s @MAIN ;no, go to it - move.w (a5)+,(a4)+ ;save first pixel - addq #2,a2 ;bump past first src pixel - addq #2,a3 ;bump past first mask pixel - bra.s @next - -@MAIN move.w (A2)+,D0 ;EXTRACT A LONG OF SRC - MOVE.w (A5),d1 ;get a long of screen - move.w d1,(A4)+ ;SAVE A LONG OF SCREEN - tst.w (A3)+ ;EXTRACT A LONG OF MASK - bne.s @inside - not.w d0 ;flip src so that black is all 1's - and.w d7,d0 ;mask off high bit - beq.s @skipit ;no use in xoring with zero - eor.w d1,d0 ;xor dst with src -@inside - move.w d0,(a5) -@skipit addq #2,a5 -@next dbra D5,@MAIN ;DECREMENT LONGCNT - - tst d2 ;is right pixel masked? - bne.s @last ;no, go to it - move.w (a5)+,(a4)+ ;save first pixel - addq #2,a2 ;bump past first src pixel - addq #2,a3 ;bump past first mask pixel - bra.s @nxtScn - -@last move.w (A2)+,D0 ;EXTRACT A LONG OF SRC - MOVE.w (A5),d1 ;get a long of screen - move.w d1,(A4)+ ;SAVE A LONG OF SCREEN - tst.w (A3)+ ;EXTRACT A LONG OF MASK - bne.s @in - not.w d0 ;flip src so that black is all 1's - and.w d7,d0 ;mask off high bit - beq.s @skip ;no use in xoring with zero - eor.w d1,d0 ;xor dst with src -@in - move.w d0,(a5) -@skip addq #2,a5 -@nxtScn ADD.L A1,A3 ;BUMP CURSOR DATA - ADD.L A1,A2 ;BUMP CURSOR MASK - ADD.L A0,A5 ;BUMP SCREEN POINTER - MOVE.L A6,D5 ;RESTORE LONGCNT - DBRA D3,@First ;=>DO NEXT ROW - bra DoneBlit - - - - -;----------------------------------------------- -; -; DISPLAY THE CURSOR AND SAVE THE BITS BEHIND IT (DO THE CURSOR LIMBO!!) -; -; THE FUNNY TRANSFER MODE USED HERE WORKS THE SAME AS BEFORE FOR ONE BIT -; MODE, AND SIMILARLY FOR COLOR. IN COLOR, THE DATA PIXELS WITHIN THE MASK -; REPLACE THE DESTINATION; THE DATA PIXELS OUTSIDE THE MASK ARE XORED WITH -; THE DST. IF THE DATA PIXELS OUTSIDE OF THE MASK ARE BLACK (ALL F'S), -; THEN THE DST IS SIMPLY INVERTED. IF THEY ARE OTHER COLORS, INTERESTING -; EFFECTS WILL MANIFEST THEMSELVES. -; -; REGISTER USE: D0: SCRATCH A0: DSTBUMP -; D1: SCRATCH A1: SRCBUMP -; D2: RIGHTMASK A2: SRCPTR -; D3: ROWCNT A3: MASKPTR -; D4: LEFTMASK A4: SAVEPTR -; D5: LONGCNT A5: DSTPTR -; D6: OFFSET A6: COPY LONGCNT -; D7: SCRATCH (A7): LEFTMASK -; 4(A7): COPY OFFSET - - if cursorShadow then - -Direct32 - move d5,d0 ;get a copy of long cnt - addq #1,d0 ;make one based - lsl #2,d0 ;make into byte cnt - sub d0,a1 ;make srcRow into srcBump - - asr #3,d6 ;make offset into bytes - add d6,a2 ;adjust src ptr - add d6,a3 ;adjust mask ptr - - -voff equ 4 -hoff equ 4 - -;----------------------------------------------- -; -; SAVE DSTLEFT/DSTBUMP/LONGCNT/ROWCNT INTO CRSRPTR SO THAT -; HIDECURSOR KNOWS HOW MUCH SCREEN TO REPLACE. - - movem.l d3/d5/a6/a5/a0,-(sp) - MOVE.L ([CRSRPTR]),D0 ;GET POINTER TO CURSOR DATA (LOCKED) - _rTranslate24To32 - MOVE.L D0,A6 - LEA CCBYTES(A6),A6 ;POINT TO END OF SAVE STATE AREA - move.w mouse,d0 ;get vert pos - lsr.w #6,d0 - ; add.w #voff,d3 - add.w d0,d3 - move.w mouse+2,d0 ;get horiz pos - lsr.w #6,d0 - ; add.w #hoff,d5 - add.w d0,d5 - lsl.w #2,d0 - ; sub.w #hoff*4,a0 - sub.w d0,a0 - MOVEM.L A5/A0/D5/D3,-(A6) ;SAVE DSTLEFT/DSTBUMP/LONGCNT/ROWCNT - MOVE.L D5,A6 ;SAVE LONGCNT - -@MAIN2 MOVE.L (A5)+,d1 ;get a long of screen - move.l d1,(a4)+ ;save a long of screen - dbra D5,@MAIN2 ;DECREMENT LONGCNT - - ADD.L A0,A5 ;BUMP SCREEN POINTER - MOVE.L A6,D5 ;RESTORE LONGCNT - DBRA D3,@MAIN2 ;=>DO NEXT ROW - movem.l (sp)+,a5/d3/d5/a6/a0 - - - movem.l d3/a2-a5,-(sp) - - ; moveq #voff,d0 - move.w mouse,d0 ;get vert pos - lsr.w #6,d0 - bra.s @1 - -@0 ADD.w CRSRROW,A5 ;offset SCREEN POINTER vertically -@1 dbra d0,@0 - - move.w mouse+2,d0 ;get horiz pos - lsr.w #6,d0 - lsl.w #2,d0 - ; add.w #hoff*4,a5 - add.w d0,a5 - -@MAIN1 MOVE.L (A5),d1 ;get a long of screen - move.l (A2)+,d0 ;combine A LONG OF src - not.l d0 ;interested in nothing , dammit!!@! - and.l $31a,d0 ; shit line - or.l (A3)+,d0 ;EXTRACT A LONG OF MASK - beq.s @skipit1 - ;d0 = 0 - moveq #0,d0 ;assume result is black - moveq #$3f,d4 ;amount to remove from screen - swap d4 ;d4 = $3f0000 - sub.l d4,d1 ;darken the red channel - bcs.s @pinred - move.l d1,d0 ;take the red channel -@pinred - lsr.l #8,d4 - sub.w d4,d1 ;darken the grn channel - bcs.s @pingrn - move.w d1,d0 ;take the grn channel -@pingrn - lsr.w #8,d4 - sub.b d4,d1 ;darken the blu channel - bcs.s @pinblu - move.b d1,d0 ;take the blu channel -@pinblu - - move.l d0,(a5) -@skipit1 - addq #4,a5 - dbra D5,@MAIN1 ;DECREMENT LONGCNT - - ADD.L A1,A3 ;BUMP CURSOR DATA - ADD.L A1,A2 ;BUMP CURSOR MASK - ADD.L A0,A5 ;BUMP SCREEN POINTER - MOVE.L A6,D5 ;RESTORE LONGCNT - DBRA D3,@MAIN1 ;=>DO NEXT ROW - - movem.l (sp)+,d3/a2-a5 - - - -@MAIN move.l (A2)+,D0 ;EXTRACT A LONG OF SRC - MOVE.L (A5),d1 ;get a long of screen - tst.l (A3)+ ;EXTRACT A LONG OF MASK - bne.s @inside - not.l d0 ;flip src so that black is all 1's - beq.s @skipit ;no use in xoring with zero - eor.l d1,d0 ;xor dst with src -@inside - move.l d0,(a5) -@skipit addq #4,a5 - dbra D5,@MAIN ;DECREMENT LONGCNT - - ADD.L A1,A3 ;BUMP CURSOR DATA - ADD.L A1,A2 ;BUMP CURSOR MASK - ADD.L A0,A5 ;BUMP SCREEN POINTER - MOVE.L A6,D5 ;RESTORE LONGCNT - DBRA D3,@MAIN ;=>DO NEXT ROW - bra DoneBlit - - -; REGISTER USE: D0: SCRATCH A0: DSTBUMP -; D1: SCRATCH A1: SRCBUMP -; D2: RIGHTMASK A2: SRCPTR -; D3: ROWCNT A3: MASKPTR -; D4: LEFTMASK A4: SAVEPTR -; D5: LONGCNT A5: DSTPTR -; D6: OFFSET A6: COPY LONGCNT -; D7: SCRATCH (A7): LEFTMASK -; 4(A7): COPY OFFSET -Shadow8 - move d5,d0 ;get a copy of long cnt - addq #1,d0 ;make one based - lsl #2,d0 ;make into byte cnt - sub d0,a1 ;make srcRow into srcBump - - asr #3,d6 ;make offset into bytes - add d6,a2 ;adjust src ptr - add d6,a3 ;adjust mask ptr - - -;----------------------------------------------- -; -; SAVE DSTLEFT/DSTBUMP/LONGCNT/ROWCNT INTO CRSRPTR SO THAT -; HIDECURSOR KNOWS HOW MUCH SCREEN TO REPLACE. - - movem.l d3/d5/a6/a5/a0,-(sp) - MOVE.L ([CRSRPTR]),D0 ;GET POINTER TO CURSOR DATA (LOCKED) - _rTranslate24To32 - MOVE.L D0,A6 - LEA CCBYTES(A6),A6 ;POINT TO END OF SAVE STATE AREA - move.w mouse,d0 ;get vert pos - lsr.w #6,d0 ;d0=voff - ; add.w #voff,d3 - add.w d0,d3 - move.w mouse+2,d0 ;get horiz pos - lsr.w #6,d0 ;d0=hoff - ; add.w #hoff,d5 - addq #3,d0 - lsr.w #2,d0 ;d0=shadow width longs - add.w d0,d5 - - lsl.w #2,d0 - ; sub.w #hoff*4,a0 - sub.w d0,a0 - MOVEM.L A5/A0/D5/D3,-(A6) ;SAVE DSTLEFT/DSTBUMP/LONGCNT/ROWCNT - MOVE.L D5,A6 ;SAVE LONGCNT - -;------------------------------------------- -; Save bits under cursor/shadow -;------------------------------------------- -@MAIN2 MOVE.L (A5)+,d1 ;get a long of screen - move.l d1,(a4)+ ;save a long of screen - dbra D5,@MAIN2 ;DECREMENT LONGCNT - - ADD.L A0,A5 ;BUMP SCREEN POINTER - MOVE.L A6,D5 ;RESTORE LONGCNT - DBRA D3,@MAIN2 ;=>DO NEXT ROW - movem.l (sp)+,a5/d3/d5/a6/a0 - - -;------------------------------------------- -; Draw Shadow -;------------------------------------------- - movem.l d3/a2-a5,-(sp) - - ; moveq #voff-1,d0 - move.w mouse,d0 ;get vert pos - lsr.w #6,d0 - bra.s @1 - -@0 ADD.w CRSRROW,A5 ;offset SCREEN POINTER vertically -@1 dbra d0,@0 - - move.w mouse+2,d0 ;get horiz pos - lsr.w #6,d0 - add.w d0,a5 - ; add.w #hoff,a5 - -@MAIN1 MOVE.l (A5),d1 ;get a long of screen - move.l (A2)+,d0 ;combine A LONG OF src - or.l (A3)+,d0 ;EXTRACT A LONG OF MASK - beq.s @skipit1 - ;d0 = 0 - moveq #0,d0 ;assume result is black - moveq #$3f,d4 ;amount to remove from screen - swap d4 ;d4 = $3f0000 - sub.l d4,d1 ;darken the red channel - bcs.s @pinred - move.l d1,d0 ;take the red channel -@pinred - lsr.l #8,d4 - sub.w d4,d1 ;darken the grn channel - bcs.s @pingrn - move.w d1,d0 ;take the grn channel -@pingrn - lsr.w #8,d4 - sub.b d4,d1 ;darken the blu channel - bcs.s @pinblu - move.b d1,d0 ;take the blu channel -@pinblu - - ; move.l d0,(a5) -@skipit1 - addq #4,a5 - dbra D5,@MAIN1 ;DECREMENT LONGCNT - - ADD.L A1,A3 ;BUMP CURSOR DATA - ADD.L A1,A2 ;BUMP CURSOR MASK - ADD.L A0,A5 ;BUMP SCREEN POINTER - MOVE.L A6,D5 ;RESTORE LONGCNT - DBRA D3,@MAIN1 ;=>DO NEXT ROW - - movem.l (sp)+,d3/a2-a5 - -;------------------------------------------- -; Draw cursor atop shadow -;------------------------------------------- - -@MAIN move.l (A2)+,D0 ;EXTRACT A LONG OF SRC - tst.l (A3)+ ;EXTRACT A LONG OF MASK - bne.s @inside - tst.l d0 ;flip src so that black is all 1's - beq.s @skipit ;no use in xoring with zero - MOVE.L (A5),d1 ;get a long of screen - eor.l d1,d0 ;xor dst with src -@inside - move.l d0,(a5) -@skipit addq #4,a5 - dbra D5,@MAIN ;DECREMENT LONGCNT - - ADD.L A1,A3 ;BUMP CURSOR DATA - ADD.L A1,A2 ;BUMP CURSOR MASK - ADD.L A0,A5 ;BUMP SCREEN POINTER - MOVE.L A6,D5 ;RESTORE LONGCNT - DBRA D3,@MAIN ;=>DO NEXT ROW - - else - -Direct32 - moveq #-1,d4 - lsr.l #8,d4 ;get low3bytes in d4 - move d5,d0 ;get a copy of long cnt - addq #1,d0 ;make one based - lsl #2,d0 ;make into byte cnt - sub d0,a1 ;make srcRow into srcBump - - asr #3,d6 ;make offset into bytes - add d6,a2 ;adjust src ptr - add d6,a3 ;adjust mask ptr - -@MAIN move.l (A2)+,D0 ;EXTRACT A LONG OF SRC - MOVE.L (A5),d1 ;get a long of screen - move.l d1,(A4)+ ;SAVE A LONG OF SCREEN - tst.l (A3)+ ;EXTRACT A LONG OF MASK - bne.s @inside - not.l d0 ;flip src so that black is all 1's - and.l d4,d0 ;mask off high byte - beq.s @skipit ;no use in xoring with zero - eor.l d1,d0 ;xor dst with src -@inside - move.l d0,(a5) -@skipit addq #4,a5 - dbra D5,@MAIN ;DECREMENT LONGCNT - - ADD.L A1,A3 ;BUMP CURSOR DATA - ADD.L A1,A2 ;BUMP CURSOR MASK - ADD.L A0,A5 ;BUMP SCREEN POINTER - MOVE.L A6,D5 ;RESTORE LONGCNT - DBRA D3,@MAIN ;=>DO NEXT ROW - - endif - - -DoneBlit - ADDQ #8,SP ;STRIP LEFTMASK AND OFFSET - MOVE.B #1,CrsrVis ;CURSOR VISIBLE - - moveq #0,d0 - move.b (sp)+,d0 ;get previous MMU state in d0 - _rSwapMMUMode ;restore MMU mode from d0.b -SkipBlit - MOVEM.L (SP)+,D0-D7/A0-A6 ;THE WALTZ IS OVER...(TANGO VERY MUCH) -NoBlit - RTS - - - -;_______________________________________________________________________ -; -; UNBLITCURSOR -; -; This routine unconditionally removes cursor according to the data in -; CCSTATEREGS. -; Such things as crsrstate, crsrvis, and other nonsense have already been -; checked. Vectoring this routine may prove useful for later cursor -; enhancements. - -UNBLITCURSOR PROC EXPORT - TST.L CRSRPTR ;CURSOR ALLOCATED? - BMI.S DONEHIDE ;=>NO, JUST RETURN - MOVEM.L D1-D4/A0-A2,-(SP) ;SAVE REGS USED - - MOVE.L ([CRSRPTR]),A0 ;GET POINTER TO CURSOR SAVE DATA (LOCKED) - MOVE.L CCSAVE(A0),A1 ;GET HANDLE TO SAVED BITS - MOVE.L (A1),d0 ;POINT TO SAVED BITS - _rTranslate24To32 ;mask off high byte - move.l d0,a1 - LEA CCSTATEREGS(A0),A0 ;POINT TO SAVE STATE AREA - MOVEM.L (A0)+,D2/D3/D4/A2 ;GET /ROWCNT/LONGCNT/DSTBUMP/DSTLEFT - - moveq #true32b,d0 ;switch to 32 bit mode - movem.l d2/a1/a2,-(sp) ;save off registers - _rSwapMMUMode ;get previous mode in d0.b (can trash a0/a2, d0/d2) - movem.l (sp)+,d2/a1/a2 ;restore registers - - MOVE.L D3,A0 ;SAVE LONGCNT -@1 MOVE.L (A1)+,(A2)+ ;RESTORE A LONG OF SOURCE - DBRA D3,@1 ;=>DO ENTIRE ROW - MOVE.L A0,D3 ;RESTORE LONGCNT - ADD D4,A2 ;BUMP DST - DBRA D2,@1 ;=>DO FOR ALL LINES - - _rSwapMMUMode ;restore original mode from d0.b - - CLR.B CRSRVIS ;MARK IT AS INVISIBLE - MOVEM.L (SP)+,D1-D4/A0-A2 ;RESTORE REGS USED -DONEHIDE RTS +_SetCCursor PROC EXPORT + IMPORT QDNEW_SETCCURSOR + JMP QDNEW_SETCCURSOR ; ;_______________________________________________________________________ @@ -1976,7 +318,7 @@ DONEHIDE RTS ; ; return a pointer to the start of the bit-map display ; -ScrnAddress PROC EXPORT +_ScrnAddress PROC EXPORT MOVE.L ScrnBase,4(SP) ;get screenBase set up by OS RTS ;that was easy! @@ -1987,7 +329,7 @@ ScrnAddress PROC EXPORT ; ; return the size of the screen in pixels ; -ScrnSize PROC EXPORT +_ScrnSize PROC EXPORT MOVE.L (SP)+,D0 ;get the return address MOVE.L MainDevice,A0 ;get handle to main screen device MOVE.L (A0),A0 ;point to main screen device diff --git a/QuickDraw/CQD.a b/QuickDraw/CQD.a index 02ddf1a..0a37691 100644 --- a/QuickDraw/CQD.a +++ b/QuickDraw/CQD.a @@ -50,6 +50,7 @@ PrNonPortable EQU 1 WholeErrors EQU 1 AddrModeFlag EQU 0 Quicker EQU 1 +has32BitQD EQU 1 ROMPaletteMgr EQU 1 ;set to zero for System Disk, 1 for ROM build @@ -155,6 +156,7 @@ BlockHead PROC EXPORT endif INCLUDE 'BITBLT.a' INCLUDE 'cCrsrCore.a' + INCLUDE 'QDExtensions2.a' INCLUDE 'QDUtil.a' INCLUDE 'Colorasm.a' INCLUDE 'Patterns.a' diff --git a/QuickDraw/CheckDevicesINIT.a b/QuickDraw/CheckDevicesINIT.a index 794a824..5c9d41b 100644 --- a/QuickDraw/CheckDevicesINIT.a +++ b/QuickDraw/CheckDevicesINIT.a @@ -221,8 +221,8 @@ SlotParms EQU IOPBlk-spBlock.SPBlockSize ; parameter block for slot manag VidParms EQU SlotParms-12 ; [12] size of mode params StartList EQU VidParms-4 ; [long] pointer to start of resource -VARSIZE EQU StartList ; size of local vars for CheckDevices -UTILVARS EQU VidParms ; size of local vars for utility routines +VARSIZE EQU StartList-4 ; size of local vars for CheckDevices +UTILVARS EQU VidParms-$30 ; size of local vars for utility routines ; ¥¥¥ Start of Code ¥¥¥ ; @@ -317,557 +317,42 @@ SetDevGamma ; ---------------------------------------------------------------------------------------------------------- + +NewFunc + + Link A6,#-$B4 + Move.l A2,-(SP) + Move.l (A0),A2 + + Lea.l -$94(A6),A1 + Move.l #-2,(A1) + + Lea.l -$B4(A6),A0 + Move.l A0,$C(A1) + Lea.l -$40(A6),A0 + + Move (A2),$18(A0) + Move #$14,$1A(A0) + Move.l A1,$1C(A0) + dc.w $A205 ; _PBStatusImmed + Move.l (SP)+,A2 + Unlk A6 + Rts + + + CheckDevices ; <19>: Moved label from within if-endif to embed utility ; routines. It would be nice to be able to the the LINK ; stuff AFTER the GotScrn entrypoint. LINK A6,#VARSIZE ; allocate local stack frame - MOVEM.L A0-A6/D0-D7,-(SP) ; so we donÕt screw up the boot process -;+++ MOVEM.L D6-D7/A2-A4,-(SP) ; save work registers + MOVEM.L A0-A4/D0-D7,-(SP) ; so we donÕt screw up the boot process -;+++; check to see if the device list needs to be initialized -;+++ -;+++ MOVE.L DeviceList,A0 ; get handle to device list -;+++ MOVE.L (A0),A0 ; point to head of device list -;+++ MOVE GDFlags(A0),D0 ; get the flags word -;+++ BTST #allInit,D0 ; test initialize flag? -;+++ BNE GoHome ; => devices already initialized - -; ¥¥¥ 1st INIT ¥¥¥ -; -; Try to load in the resource. If none, then just do a SetEntries on the boot device (see -; the comments on the NoScrn code below). -; -GetScrn - CLR.L -(SP) ; make room for function result - MOVE.L #'scrn',-(SP) ; push desired resource type - CLR -(SP) ; resource ID = 0 - _GetResource ; get the resource - MOVE.L (SP)+,D0 ; get the resource handle - Beq.s NoScrn ; if nil, do the no 'scrn' code - -; ¥¥¥ 2nd INIT ¥¥¥ -; -; Test the scrnInval low-mem to make sure the screen resource is valid. (Note: scrnInval -; will generally be cleared by the video cardÕs primaryInit IF the information in -; pRAM doesnÕt match the current set up). This is ALSO a case where we need to -; make a SetEntries call so the screen colors donÕt change on the the first SetEntries -; and/or SetGamma call. -; -ChkScrn - Tst.b scrnInval ; If the 'scrn' resource is not invalid, - Bne.s GotScrn ; then just go on. - - Move.l D0,A4 ; Save the 'scrn' resource handle. - - Move.l #gestaltDisplayMgrAttr,D0 ; We need to know if the Display Manager is around. - _Gestalt ; Ask, and ye shall receive. - Bne.s @NoDM ; Oops, got an error. - Move.l A0,D0 ; Get the result into D0. - Btst #gestaltDisplayMgrPresent,D0 ; If the Display Manager is around, then - Bne.s NoScrn ; donÕt dispose of the 'scrn' resource so -@NoDM ; so that the Display Manager can deal with it. - - Clr.w -(Sp) ; Make room for resFile refNum. - Move.l A4,-(Sp) ; Push 'scrn' resource handle for resFile. - _HomeResFile ; Get refNum. - - Move.l A4,-(Sp) ; Push 'scrn' resource handle for remove. - _RmveResource ; Try to remove it. - Tst.w ResErr ; If everything is okay, then - Beq.s @DisposeIt ; just go on. - - Tst.w (Sp)+ ; Clean up the stack. - Move.l A4,D0 ; Get 'scrn' resource handle back into D0. - Bra.s GotScrn ; And weÕre screwed. - -@DisposeIt Movea.l A4,A0 ; Get 'scrn' resource handle into A0. - _DisposHandle ; Dispose it. - - _UpdateResFile ; Update the 'scrn's resFile lest we die later. - -; If a 'scrn' resource is NOT around weÕll get here. The only thing we want to do at this -; point is to call SetDevEntries on the boot device so that the screen will not change colors -; after a SetEntries/SetGamma call is made later. -; -NoScrn Move.l DeviceList,A0 ; A0 contains gDevice. Move.l #-1,A1 ; Use gDeviceÕs PixMap for colorTable. Bsr.s SetDevEntries ; Bra NoGammaFix -; ¥¥¥ 3rd INIT ¥¥¥ -; -; Lock down the 'scrn' handle, and point at the data (in A4). -; -GotScrn - MOVE.L DeviceList,A0 ; get handle to device list - MOVE.L (A0),A0 ; point to head of device list - BSET #allInit,GDFlags(A0) ; say list has been initialized - - MOVE.L D0,-(SP) ; save 'scrn' resource for ReleaseResource - MOVE.L D0,A0 ; get the resource - _HLock ; lock it down - MOVE.L (A0),A4 ; A4 = resource pointer - -; Validate the 'scrn' resource. There must be a descriptor for every screen device. -; I assume that there are no duplicate entries and that screens don't overlap. -; In addition the devices in the 'scrn' resource must be in slot order. -; - MOVE.L A4,StartList(A6) ; save pointer to start of list - MOVE (A4)+,D7 ; get the number of screens in resource - - WITH spBlock,vpBlock - - LEA SlotParms(A6),A0 ; get pointer to parameter block - MOVE.L #((CatDisplay << 16) ++ TypVideo),spCategory(A0) - ; set category ID, type - MOVE.W #drSwApple,spDrvrSw(A0) ; set software, hardware ID - MOVE.B #$01,spTBMask(A0) ; ignore spDrvrHw - MOVE.B #0,spSlot(A0) ; start with desired slot (0 to check built-in devices) - MOVE.B #0,spID(A0) ; start with first (zeroth) ID - CLR.B spExtDev(A0) ; -NxtDev _sNextTypesRsrc ; get next video device - BEQ.S GotDev ; => there is one - -; There are no more screens; are there any more entries in the 'scrn' resource? -; - TST D7 ; there should have been one per device - BEQ GoodRsrc ; => there was, go initialize them - BRA BadScrn ; - -; Scan through 'scrn' resource entry for this device. -; -GotDev MOVE (A4)+,D0 ; get type - CMP spDrvrHw(A0),D0 ; does it match? - BNE BadScrn ; => nope, bad screen resource - MOVE (A4)+,D0 ; get slot - CMP.B spSlot(A0),D0 ; does it match? - BNE.S BadScrn ; => nope, bad screen resource - -; Get the DCE entry for the device and check dCtlDevBase. -; If no match, look for other devices in the same slot. -; -SlotOK MOVE spRefNum(A0),D0 ; get the refNum - NOT D0 ; refNum to unitnum - ASL #2,D0 ; offset in unitTable - MOVE.L UTableBase,A1 ; get the base of the unit table - MOVE.L (A1,D0),A3 ; A3 = handle to the DCE - MOVE.L (A3),A1 ; get pointer to the DCE - MOVE.L dCtlDevBase(A1),D0 ; get dCtlDevBase - CMP.L (A4)+,D0 ; do they match? - BNE.S BadScrn ; => nope, bad screen resource - -; Test to make sure that the requested mode (screen depth) is valid in this video -; sRsrc list. -; - MOVE.B spID(A0),D1 ; save the spID (so that itÕs correct for the sNextTypesRsrc) - MOVE.W (A4)+,D0 ; get the mode - MOVE.B D0,spID(A0) ; insert into spBlock - _sFindStruct ; find the sRsrc list entry for this mode - BNE.S BadScrn ; if not, then the scrn resource is no good - MOVE.B D1,spID(A0) ; restore the spID - -; To be completely compulsive about it, make sure there's a gDevice. -; - MOVE.L DeviceList,A3 ; A3 = first gDevice in list - MOVE spRefNum(A0),D1 ; get refnum (unaffected by sFindStruct) -@NxtGD MOVE.L (A3),A1 ; get pointer to device - CMP gdRefNum(A1),D1 ; does refnum match? - BEQ.S RectCheck ; => yes, this device matches! - MOVE.L gdNextGD(A1),D0 ; get handle of next device - MOVE.L D0,A3 ; get in A3 - BNE.S @NxtGD ; => check all gDevices - BRA.S BadScrn ; => no such gDevice, bad 'scrn' - -; Compare the size of the remembered screenRect to the size of this gDevice's -; gdRect. At this point, the gdRects are still topleft={0,0} from InitGDevice -; so we can just check 'scrn' rect against botRight. -; -RectCheck - ADD #8,A4 ; skip to global rect in 'scrn' - MOVE.W bottom(A4),D0 ; get bottom - SUB.W top(A4),D0 ; = height - CMP.W gdRect+bottom(A1),D0 ; is it equal? - BNE.S BadScrn ; nope, we're out - MOVE.W right(A4),D0 ; get right - SUB.W left(A4),D0 ; = width - CMP.W gdRect+right(A1),D0 ; is it equal? - BNE.S BadScrn ; nope, we're out - -; This device matches! Go check the next one. -; -SkipData ADD #8,A4 ; skip to control field - MOVE (A4)+,D0 ; get number of control calls - BRA.S SkipCtl ; skip control call -SkipNxt MOVE.L (A4)+,D1 ; get control code, size of params - ADD D1,A4 ; add size of params to skip block -SkipCtl DBRA D0,SkipNxt ; => skip next control - - SUBQ #1,D7 ; decrement device count - BMI.S BadScrn ; => oops, bad screen resource - - LEA SlotParms(A6),A0 ; get pointer to parameter block <14> - BRA.s NxtDev ; => check next device <19>: .s - -; If the 'scrn' resource is bad, then let's walk down the device list and offset -; the invalid screens' gdRects so that they don't all pile up at (0,0). Let's keep -; it simple--just put them all edge-to-edge, with the top edge at 0 (unchanged) and -; to the right of the previous guys'. Offset the gdPMap's rect also. -; -BadScrn - MOVE.L DeviceList,A0 ; get the head of the list (the boot screen) - MOVE.L (A0),A0 ; hndl->ptr - MOVE.W gdRect+right(A0),D1 ; get the boot screen's right edge (if the scrn - ; is invalid, then this is the real right edge) -@Loop MOVE.L gdNextGD(A0),D0 ; get handle to next screen - BEQ ScrnDone ; when NIL we're out of here <19>: Done -> ScrnDone - MOVE.L D0,A0 ; get this device - MOVE.L (A0),A0 ; handle to ptr - ADD.W D1,gdRect+left(A0) ; offset the left edge (normally zero) - ADD.W D1,gdRect+right(A0) ; offset the right edge - MOVE.L gdPMap(A0),A1 ; get the gdPMap handle - MOVE.L (A1),A1 ; get the gdPMap pointer - ADD.W D1,pmBounds+left(A1) ; offset the left edge (normally zero) - ADD.W D1,pmBounds+right(A1) ; offset the right edge - - MOVE.W gdRect+right(A0),D1 ; get the new right edge for the next device - BRA.S @Loop ; for each screen - -GoodRsrc _HideCursor ; cursor must be hidden here - MOVE.B #true,CrsrBusy ; MARK CHANGE IN PROGRESS - -; Configure each entry in the scrn resource -; - MOVE.L StartList(A6),A4 ; save pointer to start of list - MOVE (A4)+,D7 ; get the number of screens in resource - SUBQ #1,D7 ; make it 0 based - -; It would be nice if this routine could use sRsrcInfo or sNextsRsrc here, but we -; don't keep the video sRsrc spID in the scrn resource, just the hw ID!!! To -; make up for this, we must do a search by type. -; -DoNxt LEA SlotParms(A6),A0 ; get pointer to parameter block - MOVE.L #((CatDisplay << 16) ++ TypVideo),spCategory(A0) - ; set category ID, type - MOVE.W #drSwApple,spDrvrSw(A0) ; - ; set software, (invalid) hardware ID - MOVE (A4)+,spDrvrHw(A0) ; set driver hardware ID - MOVE.B #$00,spTBMask(A0) ; all fields valid - MOVE (A4)+,D0 ; get slot - MOVE.B D0,spSlot(A0) ; does it match? - MOVE.B #0,spID(A0) ; start with first ID - CLR.B spExtDev(A0) ; - _sNextTypesRsrc ; get next video device -;+++ BNE BadScrn ; => this should never be taken (so letÕs comment it out) <12> - -; We found a device that matches the given description! Find its gDevice and configure it. -; - MOVE spRefNum(A0),D1 ; D1 = refnum - - MOVE.L DeviceList,A3 ; A3 = first gDevice in list -@NxtGD MOVE.L (A3),A0 ; get pointer to device - CMP gdRefNum(A0),D1 ; does refnum match? - BEQ.S @GotGD ; => yes, got the gDevice - MOVE.L gdNextGD(A0),D0 ; get handle of next device - MOVE.L D0,A3 ; get in A3 - BNE.S @NxtGD ; => check all gDevices -;+++ BRA BadScrn ; => this should never be taken (so letÕs comment it out) <12> - -@GotGD MOVE.L (A4)+,D0 ; discard dCtlDevBase - -; Set up the GDFlags word before calling InitGDevice. -; - MOVE.L (A3),A1 ; point at the grafDevice - MOVE gdFlags(A1),D0 ; get the flags word - AND 2(A4),D0 ; turn off the bits that are used - OR 4(A4),D0 ; turn on new bits - BSET #ramInit,D0 ; say we've initialized it - BSET #screenDevice,D0 ; and flag it as a screen device - MOVE D0,GDFlags(A1) ; set the flags word - -; If main device, set up low-memory handles. (Wait: If the ramInit and screenDevice -; flags are NOT setup, then why would the mainScreen flag be setup? -- jmp) -; - MOVE gdFlags(A1),D0 ; get the flags word - BTST #mainScreen,D0 ; is it the main scrn? - BEQ.S @InitGD ; => no, go init device - - MOVE.L A3,MainDevice ; set up as main screen device - MOVE.L A3,TheGDevice ; set up as default destination device - MOVE.L A3,SrcDevice ; set up as default source device - ; AllocCursor called by InitCursor to init cursor - MOVE.L (A3),A0 ; point to gDevice - MOVE.L gdPMap(A0),A0 ; get pixMap handle - MOVE.L (A0),A0 ; point to pixMap - MOVE.L baseAddr(A0),D0 ; get base address - MOVE.L D0,scrnBase ; and set up screen base - - LEA SlotParms(A6),A0 ; point at slot manager block again (it's still positioned from above) - MOVE (A4),D0 ; get the requested mode - MOVE.B #oneBitMode,spId(A0) ; pass the default mode (assumed to be 1-bit mode) - _sFindStruct ; point to this mode information - - MOVE.B #mVidParams,spID(A0) ; now get the device pixmap - _sGetBlock ; on the current heap (system normally here) - MOVE.L spResult(A0),A1 ; get the result pointer - MOVE.w vpRowBytes(A1),screenRow ; get the screen row bytes (WORD) - -; Set up the low-mem for screen resolution too. TheyÕre only WORD/WORD rather then FIXED/FIXED. -; - MOVE.W vpHRes(A1),ScrHRes ; Take the high word of vpHRes - MOVE.W vpVRes(A1),ScrVRes ; Take the high word of vpVRes - - MOVE.L spResult(A0),A0 ; Do what it says in IM V (p 446) instead of - _DisposPtr ; of using _sDispose. <12> - -@InitGD MOVE D1,-(SP) ; push refnum - MOVE (A4)+,-(SP) ; push mode - CLR -(SP) ; which should be long - MOVE.L A3,-(SP) ; push gDevice - _InitGDevice ; configure the gDevice - ADDQ #4,A4 ; mask and flags already used - -; If there is a gamma table resource id, get the gamma correction table and call the driver. -; We need to do this before setting the color table (via SetEntries) to make sure it takes -; effect right away. -; - MOVE 2(A4),D0 ; get the gamma table resource id - CMP #-1,D0 ; is it -1? - BEQ.S ChkTbl ; => yes, no table - -; If the gamma table resource id = -2, then request linear gamma from the driver. -; - CMP #-2,D0 ; is it -2? - BNE.S @GetFromSys ; nope, so load the system resource - -;+++ LEA VidParms(A6),A1 ; point to parameter block -;+++ CLR.L csGTable(A1) ; pass NIL to tell new drivers to set linear -;+++ BSR.S GammaControl ; call a common routine to set gamma - -; <19>: Use SetDevGamma instead of GammaControl -; - Move.l A3,A0 ; Put gDevice in A0 for SetDevGamma call. - Move.l #0,A1 ; (nil) gammaTable Ptr in A1 (to set linear). - Bsr.s SetDevGamma -; - BRA.S ChkTbl - -; Load the gamma resource from the system and set it. -; -@GetFromSys CLR.L -(SP) ; make room for function result - MOVE.L #'gama',-(SP) ; push gamma table rsrc type - MOVE D0,-(SP) ; else push resource id - _GetResource ; try to read in gamma table - MOVE.L (SP)+,D0 ; get the result - BEQ.S ChkTbl ; => couldn't find it, use default - MOVE.L D0,-(SP) ; save a copy for later - MOVE.L D0,A0 ; setup for HLock - _HLock ; - -;+++ LEA VidParms(A6),A1 ; point to params for SetGamma -;+++ MOVE.L (A0),csGTable(A1) ; gamma table pointer is only param -;+++ BSR.S GammaControl ; call a common routine - -; <19>: Use SetDevGamma instead of GammaControl. For <23>, the setup for the -; SetDevGamma call was backwards. -; - Move.l (A0),A1 ; Put pointer to gammaTable in A1, and - Move.l A3,A0 ; put pointer to GDevice in A0. - Bsr.s SetDevGamma -; - MOVE.L (SP),A0 ; get the resource handle back - _HUnlock ; free it - _ReleaseResource ; and release it (fixing the stack) - -; <19>: Commented out GammaControl as it is replaced by the SetDevGamma utility -; above. Also, the branch around the GammaControl routine is commented -; out. -; -;+++ BRA.S ChkTbl ; continue on -; -; Here's an imbedded utility. I know I burn 2 bytes always BSRing around it, but I -; would burn two with a word branch if the utility were outside. This routine sets -; up the iopb and csParam block for a SetGamma control call. It expects the csGTable -; field to be set up, the csParam block pointer in A1, and the gdevice pointer in A3. -; -;GammaControl -; -; LEA IOPBlk(A6),A0 ; point to parameter block -; MOVE.L A1,csParam(A0) ; move addr of parms into block -; MOVE.W #cscSetGamma,csCode(A0) ; cscSetGamma <12> -;+++ CLR.L ioCompletion(A0) ; no completion routine <16>: not necessary -;+++ CLR.W ioVRefNum(A0) ; no volRefNum <16>: not necessary -; MOVE.L (A3),A1 ; point to gdevice -; MOVE GDRefNum(A1),ioRefNum(A0) ; set device's refnum -; _Control ,IMMED ; SetGamma(GammaTable) -; ; if error here (likely if -2 were passed to -; ; and old driver) then just use default table -; RTS ; and back -; -; -; Previously, if there was a color table resource id, this part loaded that table. Now, -; it checks the state of the gdDevType bit. If it is monochrome (=0), then this routine -; substitutes pixelSize+32 for the resID. If it is color (=1) and in 2- or 4-bit mode, then -; pixelSize+64 is substituted to yield a modified color table that includes the highlight -; color. -; -; If we EVER have a gamma ID <> -1 (not default), then be sure to set the color table -; to flush this gamma into the CLUT hardware. -; -; The pointer to the gDevice is still in A1. -; -; -ChkTbl - MOVE.L (A3),A1 ; point to the gDevice again - MOVE.L gdPMap(A1),A0 ; get pixmap - MOVE.L (A0),A0 ; get pixmap ptr - MOVE.W pmPixelSize(A0),D0 ; get depth - - CMP #clutType,gdType(A1) ; is it a direct/fixed (SKH) device? - BNE SetGRect ; if so, then do nothing <19>:s CSS - - BTST #gdDevType,gdFlags+1(A1) ; is it color or monochrome mode? - BNE.S @ClrMode ; if set, then this is color - CMP.W #2,D0 ; 1 or 2 bit/pixel? - BLE.S @RegClr ; don't do anything funky -@MonoMode - ADD #32,D0 ; add 32 to pixelsize in all modes for linear gray - BRA.S @GetClut ; -@ClrMode - MOVE.W D0,D1 ; copy the depth - AND #9,D1 ; is it 1- or 8-bit mode? - BNE.S @RegClr ; if so, then do regular behavior -@Is2or4 - ADD #64,D0 ; for 2- or 4-bit, add 64 to pixel depth (gives color+highlight) -;!!! BRA.S @GetClut ; - -@RegClr -;!!! MOVE (A4),D1 ; get the color table resource id -;!!! CMP #-1,D1 ; is it -1? -;!!! BNE.S @GetClut ; if not, then set the CLUT -;!!! CMP #-1,2(A4) ; if CLUTid=-1, and gammaID<>-1, then set CLUT to flush -;!!! BEQ.S SetGRect ; if both are default, then continue - -@GetClut CLR.L -(SP) ; make room for function result - MOVE D0,-(SP) ; push resource id - _GetCTable ; get a color table - MOVE.L (SP)+,D0 ; get the result - BEQ.S SetGRect ; => couldn't find it, use default - - MOVE.L D0,A0 ; save source handle in A0 - MOVE.L (A3),A1 ; point at the gDevice - MOVE.L gdPMap(A1),A1 ; get handle to its pixMap - MOVE.L (A1),A1 ; point at the pixMap - MOVE.L pmTable(A1),A1 ; get handle to existing color table - MOVE.L A1,-(SP) ; push the color table for later - MOVE.L A0,-(SP) ; push new table handle for dispose - - _GetHandleSize ; get the source size - MOVE.L D0,D1 ; save size in D1 - EXG A0,A1 ; get dest handle in A0 - _SetHandleSize ; set the dest handle size - EXG A0,A1 ; swap dest back to A1, src to A0 - - MOVE.L (A0),A0 ; get source ptr - MOVE.L (A1),A1 ; get dst ptr - MOVE.L D1,D0 ; get size to move - _BlockMove ; copy it - - _DisposCTable ; and dispose new handle - -; Now call the driver to set this color table (handle on stack) -; <19>: Use SetDevEntries call instead of in-line code. -; - Move.l A3,A0 ; A0 contains gDevice. - Move.l (Sp),A1 ; A1 contain colorTable Handle - Bsr.s SetDevEntries ; - -; MOVE.L (SP),A0 ; get handle to color table -; _HLock ; lock down the color table -; LEA VidParms(A6),A1 ; point to params for SetEntries -; MOVE.L (A0),A0 ; get ctabPtr -; CLR.W csStart(A1) ; start at zero, use sequence mode -; MOVE.W ctSize(A0),csCount(A1) ; for the length of the table -; LEA ctTable(A0),A0 ; get pointer to colorspecs -; MOVE.L A0,csTable(A1) ; color table pointer is first param -; LEA IOPBlk(A6),A0 ; point to parameter block -; MOVE.L A1,csParam(A0) ; move addr of parms into block -; MOVE.W #cscSetEntries,csCode(A0) ; cscSetEntries <12> -;+++ CLR.L ioCompletion(A0) ; no completion routine <14>: not necessary -;+++ CLR.W ioVRefNum(A0) ; no volRefNum <14>: not necessary -; MOVE.L (A3),A1 ; point to gdevice -; MOVE gdRefNum(A1),ioRefNum(A0) ; set device's refnum -; _Control ,IMMED ; do a SetEntries on color table -; -; MOVE.L (SP),A0 ; get handle to color table -; _HUnLock ; unlock the color table - -; Finally, generate an inverse table for the table (handle on stack) -; - MOVE.L (A3),A1 ; point at the gDevice - MOVE.L gdITable(A1),-(SP) ; push inverse table handle - MOVEQ #4,D0 ; make 4-4-4 inverse tables - MOVE D0,gdResPref(A1) ; save in GDevice - MOVE D0,-(SP) ; and push res - _MakeITable ; and generate inverse table (color/inverse table handles still on stack) - -; Use the specified rectangle to determine the device's global coordinates -; -SetGRect - ADDA #4,A4 ; skip the CLUT and gamma resID's - MOVE.L (A3),A0 ; point to the grafDevice - MOVE.L gdPmap(A0),A1 ; get handle to pixMap - MOVE.L (A1),A1 ; get pointer to pixMap - ADDQ #bounds,A1 ; point to pixMap.bounds - LEA gdRect(A0),A0 ; point to its rectangle - MOVE.L (A4)+,D0 ; get topLeft for mouse offset - MOVE.L D0,(A1)+ ; copy topLeft to pixMap.bounds - MOVE.L D0,(A0)+ ; copy topLeft to GDRect - MOVE.L (A4),(A1) ; copy botRight to pixMap.bounds - MOVE.L (A4)+,(A0)+ ; copy botRight to GDRect - -; Parse and execute the additional control commands -; - MOVE (A4)+,D6 ; get number of control calls - BRA.S ChkNxtCtl ; => jump into end of dbra loop -DoCtl LEA IOPBlk(A6),A0 ; point to parameter block - LEA 4(A4),A1 ; point to call parameters - MOVE.L A1,csParam(A0) ; move addr of parms into block - MOVE.W (A4)+,csCode(A0) ; set control code -;+++ CLR.L ioCompletion(A0) ; no completion routine <14>: not necessary -;+++ CLR.W ioVRefNum(A0) ; no volRefNum <14>: not necessary - MOVE.L (A3),A1 ; point to gdevice - MOVE gdRefNum(A1),ioRefNum(A0) ; set device's refnum - _Control ,IMMED ; and issue the control call - - MOVE (A4)+,D0 ; get size of param block - ADD D0,A4 ; skip param block -ChkNxtCtl DBRA D6,DoCtl ; loop for all control calls - -ChkNxt DBRA D7,DoNxt ; loop for all screens in resource - - MOVE.L MainDevice,a0 - move.l a0,CrsrDevice ; cursor is now on main device, no longer on boot device - - import GetDCtlEntry - - subq #4,sp ; room for resulting DCE handle - move.l (a0),a0 - move.w gdRefnum(a0),-(sp) ; get the refNum - jsr GetDCtlEntry - move.l (sp)+,a0 ; get handle to DCE - move.l (a0),a0 ; get pointer to DCE - move.l #0,d0 ; clear out D0 - move.b dCtlSlot(a0),d0 ; get the slot number - _AttachVBL ; attach VBL to this slot - - CLR.B CrsrBusy ; end of change - _AllocCursor ; make sure all cursor structs are updated - _ShowCursor ; now redisplay cursor - -ScrnDone _ReleaseResource ; all done with the resource <19>: Done -> ScrnDone - ; ¥¥¥ 4th INIT ¥¥¥ ; ; As explained above in the SixPack update notes, the NoGammaFix is for $067C-class @@ -879,14 +364,7 @@ ScrnDone _ReleaseResource ; all done with the resource <19>: Done -> ScrnDone ; NoGammaFix - Move.l ROMBase,A0 ; Point to ROMBase with A0. - If Not ForROM Then - Cmp.w #$067C,8(A0) ; If weÕre not running on a $67C - Bne GoHome ; ROM, then just go on. - Else - Cmp.w #$077D,8(A0) ; If weÕre not running on a $77D - Bne GoHome ; ROM, then just go on. - Endif + WITH spBlock,vpBlock ; Get the default gamma table from ROM (so we donÕt have to get it every time ; we find a card that needs it -- if we donÕt find any cards that need @@ -925,6 +403,15 @@ NoGammaFix Move.l (A0),A0 ; DCE Ptr. Move.b dCtlSlot(A0),D0 ; Save slot number. + + Cmp.b #15,D0 + Bcs.b @dont + Move.l A3,A0 + Bsr.w NewFunc + Bne.s @reallyDont + Bra.s @skipGD +@dont + Lea SlotParms(A6),A0 ; Fill out SpBlock: Move.b D0,spSlot(A0) ; spSlot = slot number Clr.w spID(A0) ; spID = 0 @@ -947,6 +434,8 @@ NoGammaFix ; We found a non-TFB card that contains no gamma table directory. So, we need to ; employ our fix, which is to make a SetGamma and then a SetEntries call. +@reallyDont + Move.l A2,A0 ; Lock down the gammaTable Handle. _Hlock @@ -969,11 +458,6 @@ NoGammaFix Move.l A2,A0 ; Dispose of the storage used for the _DisposHandle ; gammaTable Handle. -GoHome -;+++ MOVEM.L (SP)+,D6-D7/A2-A4 ; restore work registers - MOVEM.L (SP)+,A0-A6/D0-D7 ; so we donÕt screw up the boot process - UNLK A6 - ; ¥¥¥ 5th INIT ¥¥¥ ; ;---------------------------------------------------------------- @@ -1139,7 +623,7 @@ DoDrvrPatches ; ; Save all registers to prevent problems with the ROM INIT running code. ; - MOVEM.L A0-A6/D0-D7,-(SP) ; so we donÕt screw up the boot process + MOVEM.L A5-A6,-(SP) ; so we donÕt screw up the boot process ; ; Point to UnitTable in A2. @@ -1195,7 +679,12 @@ NxtSlotLoop MOVE.L (A2,D0*4),A1 ; get DCE handle MOVE.L (A1),A1 ; get DCE pointer - MOVE.L A1,A4 ; save this for driver patching code below + MOVE.L (A1),A4 + MOVE dCtlFlags(A1),D0 + BTST.L #6,D0 + BEQ.S @dont + MOVE.L (A4),A4 +@dont ; ; Point to spBlock. @@ -1235,13 +724,7 @@ NxtSlotLoop ; Take the DCE pointer in A4 (from above), and test to see if we want to patch this driver. ; @IntPtch - If Not ForROM Then - BTST #dRAMBased,dCtlFlags+1(A4) ; test if this is a driver in ROM (Erickson overpatch) <7.0> - BEQ NxtSlot ; if so, then continue to next slot <7.0> - Endif - - MOVE.L dCtlDriver(A4),A1 ; get handle to driver - MOVE.L (A1),A1 ; get pointer to driver + MOVE.L A4,A1 ; get pointer to driver MOVE.L drvrName+2(A1),D0 ; get a unique long from the name CMP.L #'DrWV',D0 ; is it the 2-Page card? @@ -1342,201 +825,10 @@ Out LEA spBlockSize(SP),SP ; clean up the stack ; ; Lets restore more registers than have ever been restored before. (Hey, you can never be too careful.) ; - MOVEM.L (SP)+,A0-A6/D0-D7 ; so we donÕt screw up the boot process + MOVEM.L (SP)+,A5-A6 + MOVEM.L (SP)+,A0-A4/D0-D7 ; so we donÕt screw up the boot process -; ¥¥¥ 6th INIT ¥¥¥ -; - if asINIT then -; -; Early in the boot process an _InitGraf was performed (for the Welcome to Mac box). -; It's not correct if the main screen moved away from the boot screen, so let's call -; InitGraf on these early globals to correct the problem. This will fix a problem -; with the LMgr "init" which didn't do an InitGraf while setting up the environment -; for an alert dialog. -; -; Note that for the new boot process this is no longer necessary. -; - - PEA -4(A5) - _InitGraf - - endif - -; ¥¥¥ 7th INIT ¥¥¥ -; - If Not ForROM Then - -;--------------------------------------------------------------------- -; Local variables, definitions, etc.... -;--------------------------------------------------------------------- - -drHwDAFB Equ $001C ; Built-in Video Hardware ID for Macintosh Quadras 700/900/950. -DrvrVer950 Equ $0001 ; Version number of the Macintosh Quadra 950Õs video driver. - -badEntry Equ $38 ; Location of bad table entry in the Macintosh Quadra 950 driver. - -; Straight from the Macintosh Quadra 950 ROMÕs source codeÉ -; -DAFBVidPrivates RECORD 0 -saveBaseAddr DS.L 1 ; the screen base address (NOT ST corrected!) -saveScreenBase DS.L 1 ; ST corrected version of saveBaseAddr. -saveSQElPtr DS.L 1 ; the SQ element pointer (for _SIntRemove) -saveGammaPtr DS.L 1 ; the pointer to the Gamma correction table -saveGamDispPtr DS.L 1 ; the pointer to the Gamma block -saveVDACBase DS.L 1 ; the base addr of the VDAC -saveDAFBBase DS.L 1 ; the base addr of the DAFB -saveVidPtr DS.L 1 ; pointer to a big block of DAFB video parameters -GFlags DS.W 1 ; flags word -has16bppACDC Ds.b 1 ; true if AC842A is around -pageModeSet Ds.b 1 ; true if the pRam PageMode enable bit is set -saveMode DS.W 1 ; the current mode setting (in lo-byte) -saveMonID DS.W 1 ; monitor type ID (in lo-byte) -saveSlotId DS.W 1 ; spID of video sRsrc (hi-order byte only!) -DAFBVidPrivSize EQU * - ENDR - -; Flags within GFlags wordÉ -; -GrayFlag EQU 15 ; luminance mapped if GFlags(GrayFlag) = 1 -IntDisFlag EQU 14 ; interrupts disabled if GFlags(IntFlag) =1 -IsMono EQU 13 ; true if monochrome only display (Portrait/Kong) -UseSeq EQU 12 ; true if sequence mode SetEntries -UseTrans Equ 12 ; True if weÕre supposed to translate 5-bit into 8 (DAFB 16bpp). -Is16 EQU 11 ; true if 16Mhz (Slow) CPU -IsSlow Equ 11 ; True if Slow CPU (for DAFB, 25Mhz is slow). -IsDirect EQU 10 ; true if direct video mode, else chunkyIndexed -PsuedoIndex EQU 9 ; true if SetEntries request was mapped to indexed from sequential - ; (due to screen depth hardware requirements) -Has16bppSRsrc Equ 9 ; True if FifthVidMode is 16bpp instead of 32bpp (DAFB). -SyncOnGreen Equ 8 ; True if weÕre supposed to put sync on green (DAFB). - - - bra.s PatchQuadra950Driver ; skip over the title - - String Pascal - -DAFBVideoTitle Dc.b '.Display_Video_Apple_DAFB' - Align 2 - -;--------------------------------------------------------------------- -; Main -;--------------------------------------------------------------------- - -PatchQuadra950Driver - String AsIs - With SpBlock,DAFBVidPrivates - -Quadra950SaveRegs Reg D4-D6 ; Define work registers. - - If AsInit Then - Cmp.w #$3FFF,ROM85 ; If Color QuickDraw is not around, - Bne @ExitNow ; then just leave. - EndIf - - Tst.l DeviceList ; If the device list is empty, - Beq @ExitNow ; then just leave. - - Move.l DeviceList,A0 ; Get the DeviceList Handle. - Move.l (A0),A0 ; Make it a pointer. - Move.w gdRefNum(A0),D0 ; If thereÕs no driver, then - Beq @ExitNow ; we canÕt do anything here. - - Movem.l Quadra950SaveRegs,-(Sp) ; Save work registers. - Suba.w #spBlockSize,Sp ; Allocate SpBlock - -; The shipping version of the Macintosh Quadra 950Õs ROM (1.7F2) has a bug in the built-in video -; driver which prevents the DirectSetEntries call from working correctly when the attached display -; is put into 32 bit-per-pixel mode. To fix this problem, we just patch the bad table in place -; since it resides in the System heap. -; - Move.l Sp,A0 ; Get spBlock ptr into A0. - Clr.b spId(A0) ; Begin at id 0. - Clr.b spSlot(A0) ; We only care about Slot $0. - Clr.b spExtDev(A0) ; No external device. - Clr.b spTBMask(A0) ; No mask in search. - Move.w #catDisplay,spCategory(A0) ; Look for: Display, - Move.w #typVideo,spCType(A0) ; Video, - Move.w #drSwApple,spDrvrSW(A0) ; Apple, - Move.w #drHwDAFB,spDrvrHW(A0) ; DAFB. - Clr.l spParamData(A0) ; Look only for enabled sRsrcs. - Bset #foneslot,spParamData+3(A0) ; Limit search to this slot only. - _GetTypeSRsrc ; If built-in video is not enabled, then - Bne.s @AllDone ; just quit. - -; We found the DAFB-based (Macintosh Quadra 700/900/950) built-in video in Slot $0. -; - Moveq #0,D5 ; Prepare D5. - Move.w spRefNum(A0),D5 ; Get the refNum. - Beq.s @AllDone ; If nil, then just leave (no driver). - Not.w D5 ; Convert the refNum intoÉ - Lsl.w #2,D5 ; Éa UTable index. - - Add.l UTableBase,D5 ; Get a ptr to the AuxDCEHandle. - Move.l D5,A0 ; Get it into A0. - - Move.l (A0),A0 ; Get the AuxDCEHandle. - Move.l (A0),A0 ; Get the AuxDCEPtr. - Move.l A0,D5 ; Save it for later. - - move.w dCtlFlags(a0),d0 ; <27> Get driver flags - Move.l dCtlDriver(A0),A0 ; Get driver. - btst #dRAMBased,d0 ; <27> Check to see if dCtlDriver is a handle or a pointer - bz.s @gotDriverPointer ; <27> A ROM based driver means itÕs a pointer - Move.l (A0),A0 ; Get ptr to driver. -@gotDriverPointer - Move.l A0,D6 ; Save it for later. - - Moveq #0,D0 ; Prepare D0. - Lea drvrName(A0),A0 ; Point to the driver name. - Move.l A0,D4 ; Save it for later. - Move.b (A0)+,D0 ; Get its length. - Swap D0 ; Save it. - Lea DAFBVideoTitle,A1 ; Point to the driver name we want. - Move.b (A1)+,D0 ; Get its length. - _CmpString ; Compare the names. - Tst.w D0 ; If they are not equal, then we donÕt know about - Bne.s @AllDone ; this DAFB driver, so just leave. - - Moveq #0,D0 ; Re-prepare D0. - Move.l D4,A0 ; Re-point to the driver name. - Move.b (A0),D0 ; Get its length. - Addq #2,D0 ; Adjust offset to version field. - Bclr #0,D0 ; Adjust offset for word alignment. - Move.w (A0,D0),D4 ; Get the driverÕs version number. - Cmp.w #DrvrVer950,D4 ; If this isnÕt the Quadra 950Õs driver version, - Bne.s @AllDone ; then just leave. - - Adda.w D0,A0 ; Point to version part of driver name. - Move.l A0,D4 ; Save it for later. - -; We found the Macintosh Quadra 950Õs version of the DAFB driver. -; - Move.l D5,A0 ; Re-point to the AuxDCEPtr. - Move.l dCtlStorage(A0),A0 ; Get the Handle to DAFB private storage. - Move.l (A0),A0 ; Make it a pointer. - - Btst #Has16bppSRsrc,GFlags(A0) ; If a 16bpp-capable sRsrc is not in use, - Beq.s @AllDone ; then just leave. - - Move.l D6,A0 ; Re-point to the DAFB driver. - Move.b #$FF,badEntry(A0) ; Fix the bad table entry. - - Move.l D4,A0 ; Re-point to the DAFB driver version number. - Move.w #DrvrVer950+1,(A0) ; Update it. - -@AllDone - Add.w #spBlockSize,Sp ; Deallocate SpBlock. - Movem.l (Sp)+,Quadra950SaveRegs ; Restore work registers. - -@ExitNow ; Outta here, dudes. - Rts - - Endwith - - Else - - Rts - - Endif + UNLK A6 + RTS END diff --git a/QuickDraw/ColorMgr.a b/QuickDraw/ColorMgr.a index 2175257..ca971cc 100644 --- a/QuickDraw/ColorMgr.a +++ b/QuickDraw/ColorMgr.a @@ -637,7 +637,7 @@ Seed MOVE.L D5,D4 ; copy total # of color (and cleared hi word) SUBQ #2,D4 ; this is the number of colors remaining - BLE.S QVille ; if zero or negative, all done + BLT.S QVille ; if zero or negative, all done MOVEQ #1,D5 ; start at color #1 (zero based) @TheRestOfUs ; a temporary label for the rest of us BSR.S QUtil ; queue it diff --git a/QuickDraw/ColorQD.make b/QuickDraw/ColorQD.make index bca464a..fbd3364 100644 --- a/QuickDraw/ColorQD.make +++ b/QuickDraw/ColorQD.make @@ -21,6 +21,7 @@ QDPatchesDir = {ColorQDDir}Patches: CQDObjs = "{ObjDir}CheckDevicesINIT.a.o" ¶ "{ObjDir}CQD.a.o" ¶ + "{LibDir}MoreCQD.lib" ¶ "{ObjDir}DeviceLoop.a.o" @@ -28,8 +29,8 @@ CQDObjs = "{ObjDir}CheckDevicesINIT.a.o" Rez {StdROpts} -o "{Targ}" "{ColorQDDir}CQD.r" -i "{QDPatchesDir}" -# "{LibDir}CQD.lib" Ä {CQDObjs} -# Lib {StdLibOpts} -o "{Targ}" {CQDObjs} +"{LibDir}CQD.lib" Ä {CQDObjs} + Lib {StdLibOpts} -o "{Targ}" {CQDObjs} "{ObjDir}CheckDevicesINIT.a.o" Ä "{ColorQDDir}CheckDevicesINIT.a" diff --git a/QuickDraw/DeviceLoop.a b/QuickDraw/DeviceLoop.a index 303b0f6..671ae3c 100644 --- a/QuickDraw/DeviceLoop.a +++ b/QuickDraw/DeviceLoop.a @@ -105,8 +105,38 @@ LocalSize EQU * link A6, #LocalSize movem.l D3-D7/A2-A4, callerRegs(A6) ; save the callers registers - btst #6, ROM85 ; Color QuickDraw available? - bnz @classicQD ; if not, handle old case + machine MC68030 + move.l ([$2b6],$1fc),a0 + machine MC68020 + + tst.b $b5(a0) + beq.s @noShield + + move.l drawingRgn(a6),d0 + beq.s @noConversion + + move.l d0,a0 + move.l (a0),a0 + move.l $2(a0),localRect+0(a6) + move.l $6(a0),localRect+4(a6) + + pea localRect+0(a6) + _LocalToGlobal + + pea localRect+4(a6) + _LocalToGlobal + + bra.s @proceedWithShield +@noConversion + + move.l #$80008000,localRect+0(a6) + move.l #$7fff7fff,localRect+4(a6) + +@proceedWithShield + pea localRect+0(a6) + clr.l -(sp) + _ShieldCursor +@noShield move.l TheGDevice, D0 ; Get the handle to the current GDevice move.l MainDevice, D1 ; Get the handle to the main device @@ -149,11 +179,11 @@ LocalSize EQU * beq @noMore ; if so, no more devices move.l (A4), A3 ; point at the GDevice record bsr TestAndIntersect ; is device good for drawing? - bz.s @nextDevice ; if not, keep searching + bz @nextDevice ; if not, keep searching move.l flags(A6), D0 ; get the callerÕs options btst #allDevicesBit, D0 ; are we ignoring regions? - bnz.s @visRgnSetup ; if so, donÕt change the visRgn + bnz @visRgnSetup ; if so, donÕt change the visRgn move.l D4, -(SP) ; rectangle region handle pea localRect(A6) ; this device (local coords) @@ -175,10 +205,12 @@ LocalSize EQU * move.l ctSeed(A0), D7 ; stash deviceÕs ctab seed move.l flags(A6), D0 ; get callerÕs flags btst #singleDevicesBit, D0 ; should we group devices? - bnz.s @groupingDone ; if not, donÕt call AddSimilar + bnz @groupingDone ; if not, donÕt call AddSimilar bsr AddSimilarDevices ; find all the like devices @groupingDone movem.l D3-D7/A2-A4/A6, -(SP) ; save OUR registers + bsr NewFunc1 + move D2,-(SP) swap D6 move.l D6, -(SP) ; pass depth and flags move.l A4, -(SP) ; and the GDHandle @@ -187,6 +219,8 @@ LocalSize EQU * movem.l callerRegs(A6), D3-D7/A2-A4 ; restore callerÕs registers move.l A6Link(A6), A6 ; and restore callerÕs A6 jsr (A0) ; call the drawing procedure + move (SP)+,D2 + bsr NewFunc2 movem.l (SP)+, D3-D7/A2-A4/A6 ; get OUR register set back move.l (A4), A3 ; fix GDevicePtr @nextDevice @@ -194,13 +228,6 @@ LocalSize EQU * addq #1, D3 ; increment device number bra.s @deviceIntersect ; try this one -@classicQD - move.l A6, -(SP) ; save our stack frame ptr - move.w #1, -(SP) ; pass depth (always 1) - move.w #fakeDeviceFlags, -(SP) ; and gdflags (something reasonable) - clr.l -(SP) ; NIL for GDHandle - bra.s @simpleDeviceCommon - @oneDevice move.l A6, -(SP) ; save our stack frame ptr move.l gdPMap(A0), A1 ; PixMapHandle @@ -230,6 +257,17 @@ LocalSize EQU * _DisposRgn move.l savedVis(A6), visRgn(A2) ; put original visRgn back @exit + + machine MC68030 + move.l ([$2b6],$1fc),a0 + machine MC68020 + + tst.b $b5(a0) + beq.s @noShow + + _ShowCursor +@noShow + movem.l callerRegs(A6), D3-D7/A2-A4 ; restore regs unlk A6 move.l (SP)+, A0 ; clean stack and return @@ -252,27 +290,30 @@ AddSimilarDevices movem.l A3-A4/D3/D6, -(SP) ; save original state andi.w #importantFlagsMask, D6 ; keep only pertinent flags + move.l A3, A1 move.l gdNextGD(A3), A4 ; start with next device addq #1, D3 ; which is next in number, too @addLoop move.l A4, D0 ; is there a GDHandle? - bz.s @noMore ; if NIL, then weÕre done + bz @noMore ; if NIL, then weÕre done move.l (A4), A3 ; handle->ptr - bsr.s TestAndIntersect ; see if device is okay by itself - bz.s @nextDevice ; if not, try next one + move.l A1, -(SP) + bsr TestAndIntersect ; see if device is okay by itself + move.l (SP)+, A1 + bz @nextDevice ; if not, try next one move.w gdFlags(A3), D0 ; get device attributes andi.w #importantFlagsMask, D0 ; strip unimportant ones cmp.w D0, D6 ; is this device similar to test device? - bne.s @nextDevice ; if not, donÕt use it + bne @nextDevice ; if not, donÕt use it move.l gdPMap(A3), A0 ; get deviceÕs PixMapHandle move.l (A0), A0 ; get deviceÕs PixMapPtr move.l D6, D0 ; get depth and flags swap D0 ; get depth into low word cmp.w pmPixelSize(A0), D0 ; save depth as test device? - bne.s @nextDevice ; if not, donÕt use it + bne @nextDevice ; if not, donÕt use it move.l flags(A6), D0 ; get the option flags btst #dontMatchSeedsBit, D0 ; should we check ctSeeds? @@ -280,12 +321,49 @@ AddSimilarDevices move.l pmTable(A0), A0 ; handle to color table move.l (A0), A0 cmp.l ctSeed(A0), D7 ; are the seeds the same? - bne.s @nextDevice ; if not, donÕt use this one + bne @nextDevice ; if not, donÕt use this one @seedsChecked + move.l A3, A0 + move.l $22(A1), D0 + cmp $24(A0), D0 + bgt.s @L4 + blt.s @L1 + swap D0 + cmp $22(A0), D0 + bgt.s @L5 + blt.s @L2 + move.l $26(A1), D0 + cmp $28(A0), D0 + blt.s @L6 + bgt.s @L3 + bra.s @nextDevice +@L1 swap D0 + cmp $22(A0), D0 + bgt.s @doneWhateverThatWas +@L2 move.l $26(A1), D0 + cmp $28(A0), D0 + blt.s @doneWhateverThatWas +@L3 swap D0 + cmp $26(A0), D0 + blt.s @doneWhateverThatWas + bra.s @nextDevice +@L4 swap D0 + cmp $22(A0), D0 + blt.s @doneWhateverThatWas +@L5 move.l $26(A1), D0 + cmp $28(A0), D0 + bgt.s @doneWhateverThatWas +@L6 swap D0 + cmp $26(A0), D0 + bgt.s @doneWhateverThatWas + bra.s @nextDevice +@doneWhateverThatWas + move.l flags(A6), D0 ; what are the current options? btst #allDevicesBit, D0 ; are we ignoring drawingRgn? bnz.s @visRgnSetup ; if so, no regions to setup + move.l A1, -(SP) move.l D4, -(SP) ; rectangle region handle pea localRect(A6) ; this device (local coords) @@ -299,6 +377,7 @@ AddSimilarDevices move.l (SP), -(SP) ; get ORed together _XorRgn ; XOr is a fast way to Union when guaranteed no overlap move.l (A4), A3 ; fix GDevicePtr + move.l (SP)+, A1 @visRgnSetup bset.l D3, D5 ; mark this device done @@ -347,4 +426,73 @@ TestAndIntersect @exit rts + +NewFunc1 + moveq #0, D2 + move.l (DeviceList), D0 + beq.s @return + moveq #0, D1 +@L0 movea.l D0, A0 + movea.l (A0), A0 + cmp D3, D1 + beq.s @L8 + tst $14(A0) + bpl.s @L8 + movea.l (A4), A1 + move.l $22(A1), D0 + cmp $24(A0), D0 + bgt.s @L4 + blt.s @L1 + swap D0 + cmp $22(A0), D0 + bgt.s @L5 + blt.s @L2 + move.l $26(A1), D0 + cmp $28(A0), D0 + blt.s @L6 + bgt.s @L3 + bra.s @L7 +@L1 swap D0 + cmp $22(A0), D0 + bgt.s @L8 +@L2 move.l $26(A1), D0 + cmp $28(A0), D0 + blt.s @L8 +@L3 swap D0 + cmp $26(A0), D0 + blt.s @L8 + bra.s @L7 +@L4 swap D0 + cmp $22(A0), D0 + blt.s @L8 +@L5 move.l $26(A1), D0 + cmp $28(A0), D0 + bgt.s @L8 +@L6 swap D0 + cmp $26(A0), D0 + bgt.s @L8 +@L7 bclr.s #7, $14(A0) + bset.l D1, D2 +@L8 addq #1, D1 + move.l $1E(A0), D0 + bne.s @L0 +@return Rts + + +NewFunc2 + tst D2 + beq.s @return + move.l (DeviceList), D0 + beq.s @return +@L10 move.l D0, A0 + move.l (A0), A0 + lsr #1, D2 + bcc.s @L11 + bset.s #7, $14(A0) + tst D2 + beq.s @return +@L11 move.l $1E(A0), D0 + bne.s @L10 +@return Rts + END diff --git a/QuickDraw/DrawText.a b/QuickDraw/DrawText.a index 980912b..aed426d 100644 --- a/QuickDraw/DrawText.a +++ b/QuickDraw/DrawText.a @@ -2861,6 +2861,7 @@ renderIt @singleByteFont endif + ; 72624 MOVE.L WidthTabHandle, -(SP) ;2) Push the Width Table Handle onto the stack PEA fontID(A6) ;1) Push the Glyph Rec Ptr TST.B FASTFLAG(A6) ;if slow no need for 32-bit stuff @@ -2868,7 +2869,6 @@ renderIt TST.B needs32bit(A6) ;running 32 bit clean BEQ.S @skip32 ;NOPE, so skip it move.b MMUsave(a6),d0 ;get previous MMU state in d0 - _rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2) _sbRetrieveGlyph ;Call the routine via SplineDispatch moveq #true32b,d0 ;switch to 32 bit addressing _rSwapMMUMode ;get previous mode in d0.b (can trash a0/a1/a2, d0/d1/d2) diff --git a/QuickDraw/FastTraps.a b/QuickDraw/FastTraps.a index 9cb9093..304dc38 100644 --- a/QuickDraw/FastTraps.a +++ b/QuickDraw/FastTraps.a @@ -1005,7 +1005,7 @@ selectGetGray equ 25 MACRO _ZapLinks - DoPaletteDispatch selectZapLinks,0 + DoPaletteDispatch selectZapLinks,4 ENDM MACRO @@ -2921,6 +2921,7 @@ _EmptyHandle OPWORD $A000+43 _InitApplZone OPWORD $A000+44 _SetApplLimit OPWORD $A000+45 _BlockMove OPWORD $A000+46 +_BlockMoveData OPWORD $A000+46+$200 ; Here are the event manager routines diff --git a/QuickDraw/GDevice.a b/QuickDraw/GDevice.a index 93dc4aa..e4d56f4 100644 --- a/QuickDraw/GDevice.a +++ b/QuickDraw/GDevice.a @@ -201,8 +201,6 @@ MODE EQU REFNUM-4 ; LONG, Mode for video card CMP.L #-1,D0 ; if mode = -1, then don't init beq.s Done ; => go home - CMP.W #OneBitMode,D0 ; is it one bit per pixel? - BEQ.S @Mono ; => yes, default to black and white Bsr TestForGray ; is it monochrome only? Bne.s @Mono ; => yes, leave GDevice mono BSET #GDDevType,GDFlags+1(A3) ; else default to color @@ -210,7 +208,7 @@ MODE EQU REFNUM-4 ; LONG, Mode for video card @Mono MOVE.W REFNUM(A6),-(SP) ; pass device to initialize MOVE.L MODE(A6),-(SP) ; pass mode to initialize MOVE.L A2,-(SP) ; and pass gDevice handle - _InitGDevice ; initialize the device port + JSR ([$16B8]) ; initialize the device port DONE MOVE.L (SP)+,theZone ; restore the zone MOVE.L A2,RESULT(A6) ; return graf device handle @@ -364,6 +362,8 @@ oldBaseAddr DS.B 4 ; old base address, for later comparison oldPort DS.B 4 ; thePort, before we got here oldColor DS.B 8 ; a colorSpec used to reinstantiate fg/bk + DS.B 356 + VARSIZE DS.B 0 ; size of locals ENDR @@ -372,6 +372,13 @@ VARSIZE DS.B 0 ; size of locals LINK A6,#VARSIZE ; allocate stack frame MOVEM.L D3/A2-A4,-(SP) ; save off work registers + MOVE.L ExpandMem,A0 + MOVE.L $1FC(A0),A1 + TST.B $B5(A1) + BNE.S @true + CLR $276(A0) +@true + MOVE.L GDH(A6),A0 ; get the gDevice handle _HGetState ; get the current lock state MOVE D0,GDHState(A6) ; save the state @@ -390,16 +397,13 @@ VARSIZE DS.B 0 ; size of locals BNE.S @noShield ; no, don't shield cursor BTST #screenDevice,gdFlags(A2) ; is it screen (check hi byte with #>8) BEQ.S @noShield -;+++ PEA gdRect(A2) -;+++ CLR.L -(SP) ; in global cošrds -;+++ _ShieldCursor - _HideCursor ; changed to Hide from Shield to fix - ; problems when cursor is on the move - ; during InitGDevice + JSR ([$F48]) + @noShield ; initialize the GDevice's mode and refnum + SF.B -$6E(A6) MOVE REFNUM(A6),GDRefNum(A2) ; set up RefNum MOVE.L MODE(A6),D0 ; get the mode CMP.L MinusOne,D0 ; is the mode -1? @@ -415,7 +419,8 @@ VARSIZE DS.B 0 ; size of locals MOVE.L A1,csParam(A0) ; point to param list CMP.L GDMode(A2),D0 ; has the mode changed? - BEQ GrayOrColor ; => no, so don't set depth + BEQ.S GrayOrColor ; => no, so don't set depth + ST.B -$6E(A6) MOVE.L D0,GDMode(A2) ; set up mode ; setup the gDevice fields for the new screen depth @@ -491,97 +496,246 @@ NoTbl MOVEQ #4,D0 ; make 4-4-4 inverse tables MOVE D0,GDResPref(A2) ; save in GDevice MOVE D0,-(SP) ; and push res - _MakeITable ; and generate table + JSR ([$16E4]) ; and generate table -; If this device has not been initialized from the system file, then copy the -; bounds from the pixMap to the GDRect. Otherwise copy the GDRect to the Bounds. ModeOK - LEA BOUNDS(A3),A0 ; point to pixmap.bounds - LEA GDRECT(A2),A1 ; point to device's global rect - MOVE GDFlags(A2),D0 ; get the flags word - BTST #RAMInit,D0 ; initialized from RAM? - BEQ.S BndsOK ; => no, copy pixMap.bounds to GDRect - EXG A0,A1 ; else copy GDRect to pixMap.bounds -BndsOK MOVE.L (A0)+,(A1)+ ; copy topLeft - MOVE.L (A0)+,(A1)+ ; copy botRight - -; -; if we're about the main device, then fix all those -; potentially errant ports. -; - TST.B QDExist ; (Unless QuickDraw don't exist) - BNE @noQD - MOVE.L portList,D1 ; or if portlist = 0 or -1 - BEQ @noQD - ADDQ.L #1,D1 - BEQ @noQD - - BTST #mainScreen,D0 ; is it the main scrn? (flags already in D0) - BEQ @notMain - - PEA oldPort(A6) ; Save the current port + MOVE.L ([$2B6],$1FC),A0 + TST.B $B5(A0) + BEQ @L13 + MOVE $14(A2),D0 + BTST.L #$D,D0 + BEQ @L13 + BTST.L #$A,D0 + BEQ @L13 + TST (A2) + BEQ @L13 + TST.B -$6E(A6) + BEQ @L13 + MOVE.L $22(A2),-$6C(A6) + MOVE.L $26(A2),-$68(A6) + TST.B (QDExist) + BNE @L9 + MOVE.L A5,-$7A(A6) + LEA.L -$7E(A6),A5 + MOVE.L $6(A3),$22(A2) + MOVE.L $A(A3),$26(A2) + MOVE.L (ScrnBase),-$1BC(A6) + MOVE.L -$58(A6),D1 + CMP.L (ScrnBase),D1 + BNE.S @L0 + MOVE $14(A2),D0 + BTST.L #$B,D0 + BEQ @L0 + MOVE.L (A3),(ScrnBase) +@L0 PEA.L -$82(A6) + _InitGraf + PEA.L -$1B8(A6) + _OpenPort + MOVE.L D2,-(SP) + MOVEQ.L #$0,D1 + MOVEQ.L #$1,D2 + MOVE.L (DeviceList),D0 +@L1 BEQ.S @L5 + MOVE.L D0,A0 + CMPA.L $8(A6),A0 + MOVE.L (A0),A0 + BNE.S @L2 + BSET.B #$7,$14(A0) + BNE.S @L4 + BRA.S @L3 +@L2 BTST.B #$7,$14(A0) + BEQ.S @L4 + BCLR.B #$7,$14(A0) +@L3 OR D2,D1 +@L4 LSL #$1,D2 + MOVE.L $1E(A0),D0 + BRA.S @L1 +@L5 MOVE.L (SP)+,D2 + MOVE D1,-(SP) + SUBQ.L #$4,SP + _NewRgn + MOVE.L (SP),-(SP) + MOVE.L (SP),-(SP) + PEA.L $6(A3) + _RectRgn + LEA.L -$1B8(A6),A0 + MOVE.L $18(A0),-(SP) + MOVE.L (SP),-(SP) + _UnionRgn + _DisposRgn + MOVE $C(A3),D0 + SUB $8(A3),D0 + MOVE -$66(A6),D1 + SUB -$6A(A6),D1 + SUB D1,D0 + ASR #$1,D0 + MOVE D0,-$1C6(A6) + MOVE $A(A3),D0 + SUB $6(A3),D0 + MOVE -$68(A6),D1 + SUB -$6C(A6),D1 + SUB D1,D0 + ASR #$1,D0 + MOVE D0,-$1C8(A6) + MOVE $8(A3),D0 + ADD -$1C6(A6),D0 + MOVE.L $6(A3),-$76(A6) + MOVE $A(A3),-$72(A6) + MOVE D0,-$70(A6) + PEA.L -$76(A6) + MOVE.L (A5),A1 + PEA.L -$10(A1) + _FillRect + MOVE $6(A3),D0 + ADD -$1C8(A6),D0 + MOVE $C(A3),-$70(A6) + MOVE D0,-$72(A6) + PEA.L -$76(A6) + MOVE.L (A5),A1 + PEA.L -$10(A1) + _FillRect + MOVE $A(A3),D0 + SUB -$1C8(A6),D0 + MOVE.L $A(A3),-$72(A6) + MOVE $8(A3),-$74(A6) + MOVE D0,-$76(A6) + PEA.L -$76(A6) + MOVE.L (A5),A1 + PEA.L -$10(A1) + _FillRect + MOVE $C(A3),D0 + SUB -$1C6(A6),D0 + MOVE $6(A3),-$76(A6) + MOVE D0,-$74(A6) + PEA.L -$76(A6) + MOVE.L (A5),A1 + PEA.L -$10(A1) + _FillRect + MOVE (SP)+,D1 + BEQ.S @L8 + MOVE.L (DeviceList),D0 +@L6 BEQ.S @L8 + MOVE.L D0,A0 + MOVE.L (A0),A0 + LSR #$1,D1 + BCC.S @L7 + BSET.B #$7,$14(A0) + TST D1 + BEQ.S @L8 +@L7 MOVE.L $1E(A0),D0 + BRA.S @L6 +@L8 PEA.L -$1B8(A6) + _ClosePort + MOVE.L -$1BC(A6),(ScrnBase) + MOVE.L -$6C(A6),$22(A2) + MOVE.L -$68(A6),$26(A2) + MOVE.L -$7A(A6),A5 +@L9 MOVE D2,-(SP) + MOVE.L $16(A2),A0 + MOVE.L (A0),A0 + MOVE $4(A0),D0 + ANDI #$7FFF,D0 + MOVE $A(A0),D1 + SUB $6(A0),D1 + ADD -$6C(A6),D1 + SUB -$68(A6),D1 + ASR #$1,D1 + MULU D1,D0 + MOVE $C(A0),D1 + SUB $8(A0),D1 + ADD -$6A(A6),D1 + SUB -$66(A6),D1 + ASR #$1,D1 + MOVE $20(A0),D2 + CMPI #$8,D2 + BGT.S @L11 + BEQ.S @L12 +@L10 ASR #$1,D1 + ASL #$1,D2 + CMPI #$8,D2 + BLT.S @L10 + BRA.S @L12 +@L11 ASR #$3,D2 + MULU D2,D1 +@L12 EXT.L D1 + ADD.L D1,D0 + ADD.L D0,(A0) + MOVE (SP)+,D2 +@L13 LEA.L $6(A3),A0 + LEA.L $22(A2),A1 + MOVE $14(A2),D0 + BTST.L #$A,D0 + BEQ.S @L14 + EXG.L A0,A1 +@L14 MOVE.L (A0)+,(A1)+ + MOVE.L (A0)+,(A1)+ + TST.B (QDExist) + BNE @L20 + MOVE.L (PortList),D1 + BEQ @L20 + ADDQ.L #$1,D1 + BEQ @L20 + BTST.L #$B,D0 + BEQ @L19 + PEA.L -$5C(A6) _GetPort - MOVE.L mainDevice,theGDevice ; and set to the screen - - MOVE.L PortList,A4 ; A4 = handle to list of ALL ports - MOVE.L (A4),A4 ; A4->list of all ports - MOVE (A4),D3 ; D3 = number of ports that exist - BRA.S @portWalkEnd - -@portWalkLoop - MOVE.L PortList,A4 + MOVE.L (MainDevice),(TheGDevice) + MOVE.L (PortList),A4 MOVE.L (A4),A4 - MOVE.L 2(A4,D3.W*4),A4 ; A4 = this port - MOVE.L A4,-(SP) ; Set to each port in the port list + MOVE (A4),D3 + BRA.S @L17 +@L15 MOVE.L (PortList),A4 + MOVE.L (A4),A4 + MOVE.L $2(A4,D3.W*4),A4 + MOVE.L A4,-(SP) _SetPort - - MOVE.L oldBaseAddr(A6),D1 ; D1 = the scrnbase of ports to change - BTST #7,portVersion(A4) ; high bit set? - BEQ.S @oldPort - MOVE.L portPixMap(A4),A4 ; A4 = handle to the port's pixmap - MOVE.L (A4),A4 ; A4->port's pixmap - CMP.L baseAddr(A4),D1 ; same as the screen's? - BNE.S @portWalkEnd ; no, skip this port - - MOVE.L baseAddr(A3),baseAddr(A4) ; replace a bunch of fields - MOVE rowBytes(A3),rowBytes(A4) - MOVE.L pixelType(A3),pixelType(A4) ; (gets pixelSize, too) - MOVE.L cmpCount(A3),cmpCount(A4) ; (gets cmpSize, too) - MOVE.L planeBytes(A3),planeBytes(A4) - - PEA oldColor(A6) ; placeholder for reinstantiating colors + MOVE.L -$58(A6),D1 + BTST.B #$7,$6(A4) + BEQ.S @L16 + MOVE.L $2(A4),A4 + MOVE.L (A4),A4 + CMP.L (A4),D1 + BNE.S @L17 + MOVE.L (A3),(A4) + MOVE $4(A3),$4(A4) + MOVE.L $1E(A3),$1E(A4) + MOVE.L $22(A3),$22(A4) + MOVE.L $26(A3),$26(A4) + PEA.L -$64(A6) MOVE.L (SP),-(SP) MOVE.L (SP),-(SP) MOVE.L (SP),-(SP) - _SaveFore ; Save and restore the foreground color - _RestoreFore ; (Allowing for pmFore) - _SaveBack ; And the same for the background + _SaveFore + _RestoreFore + _SaveBack _RestoreBack - BRA.S @portWalkEnd - -@oldPort - CMP.L portBits+baseAddr(A4),D1 ; same base on old port? - BNE.S @portWalkEnd - MOVE.L baseAddr(A3),portBits+baseAddr(A4) - MOVE rowBytes(A3),D1 - AND #nurbMask,D1 ; handle NURBs here - MOVE D1,portBits+rowBytes(A4) - -@portWalkEnd - DBRA D3,@portWalkLoop - MOVE.L oldPort(A6),-(SP) ; restore the pre-existing port + BRA.S @L17 +@L16 CMP.L $2(A4),D1 + BNE.S @L17 + MOVE.L (A3),$2(A4) + MOVE $4(A3),D1 + ANDI #$7FFF,D1 + MOVE D1,$6(A4) +@L17 DBF D3,@L15 + MOVE.L -$5C(A6),-(SP) _SetPort - - MOVE.L oldBaseAddr(A6),D1 - CMP.L scrnBase,D1 ; fix scrnBase too, if neede - BNE.S @notMain - MOVE.L baseAddr(A3),scrnBase - -@notMain + MOVE.L -$58(A6),D1 + CMP.L (ScrnBase),D1 + BNE.S @L18 + MOVE.L (A3),(ScrnBase) +@L18 MOVE.L -$58(A6),D1 + MOVE.L (A5),A0 + CMP.L -$7A(A0),D1 + BNE.S @L19 + MOVE.L (A3),-$7A(A0) +@L19 BTST.B #$D,$14(A2) + BEQ.S @L20 _AllocCursor _ShowCursor -@noQD +@L20 BSR.S NewFunc + MOVE.L (ExpandMem),A0 + MOVE D0,$276(A0) ; ; notify the Palette Manager that the mode has changed @@ -605,6 +759,62 @@ BndsOK MOVE.L (A0)+,(A1)+ ; copy topLeft UNLINK result-return-4,'INITGDEV' +NewFunc + MOVE.L (TheGDevice),D0 + BEQ @L32 + MOVE.L (MainDevice),D1 + CMP.L D0,D0 + BNE.S @L22 + MOVE.L (DeviceList),D0 + BEQ.S @L32 +@L22 MOVE.L D0,A0 + MOVE.L (A0),A0 + MOVE.L $1E(A0),D1 + BEQ.S @L32 +@L23 MOVE.L D1,A1 + MOVE.L (A1),A1 + MOVE.L $22(A1),D0 + CMP $24(A0),D0 + BGT.S @L27 + BLT.S @L24 + SWAP D0 + CMP $22(A0),D0 + BGT.S @L28 + BLT.S @L25 + MOVE.L $26(A1),D0 + CMP $28(A0),D0 + BLT.S @L29 + BGT.S @L26 + BRA.S @L30 +@L24 SWAP D0 + CMP $22(A0),D0 + BGT.S @L31 +@L25 MOVE.L $26(A1),D0 + CMP $28(A0),D0 + BLT.S @L31 +@L26 SWAP D0 + CMP $26(A0),D0 + BLT.S @L31 + BRA.S @L30 +@L27 SWAP D0 + CMP $22(A0),D0 + BLT.S @L31 +@L28 MOVE.L $26(A1),D0 + CMP $28(A0),D0 + BGT.S @L31 +@L29 SWAP D0 + CMP $26(A0),D0 + BGT.S @L31 +@L30 MOVEQ.L #$1,D0 + RTS +@L31 MOVE.L $1E(A1),D1 + BNE.S @L23 + MOVE.L $1E(A0),D0 + BNE.S @L22 +@L32 MOVEQ.L #$0,D0 + RTS + + GetDevPixMap PROC EXPORT IMPORT CopyHandle, GetCTSeed, RSetHSize ;---------------------------------------------------------------- @@ -627,7 +837,7 @@ DEVTYPE EQU PMH-4 ; LONG, VAR DevType MYBLOCK EQU -spBlock.SPBLOCKSIZE ; allocate room for parameter block PMHState EQU MyBlock-2 ; save pixMap lockState -VARSIZE EQU PMHState ; size of locals +VARSIZE EQU PMHState-$9A ; size of locals WITH spBlock,vpBlock ; @@ -636,6 +846,7 @@ VARSIZE EQU PMHState ; size of locals ; lock down the pixMap and get pointer in A2 + CLR.B -$D3(A6) MOVE.L PMH(A6),A0 ; get handle to pixMap _HGetState ; get the current state MOVE D0,PMHState(A6) ; save current state @@ -651,6 +862,46 @@ VARSIZE EQU PMHState ; size of locals MOVE.L (A1,D0),A3 ; A3 = handle to the DCE MOVE.L (A3),A1 ; get pointer to the DCE + LEA.L -$D2(A6),A4 + LEA.L -$82(A6),A0 + MOVE.L A4,$1C(A0) + MOVE $18(A1),$18(A0) + MOVE #$A,$1A(A0) + CLR.L $C(A0) + CLR.L $12(A0) + CLR $16(A0) + DC.W $A205 ; _PBStatusImmed + BNE.S @nope + MOVE.L $2(A4),-$3E(A6) + MOVE.L $8(A4),-$42(A6) + MOVE.L $2A(A1),D3 + LEA.L -$AC(A6),A0 + LEA.L -$C2(A6),A4 + MOVE.L A0,$6(A4) + MOVE.L $10(A6),D0 + MOVE D0,$4(A4) + MOVE.L -$3E(A6),(A4) + LEA.L -$82(A6),A0 + MOVE.L A4,$1C(A0) + MOVE $14(A6),$18(A0) + MOVE #$12,$1A(A0) + CLR.L $C(A0) + CLR.L $12(A0) + CLR $16(A0) + DC.W $A205 ; _PBStatusImmed + BNE.S @nope + LEA.L -$C2(A6),A4 + MOVE.B #$1,-$D3(A6) + MOVE.L -$42(A6),D3 + MOVE.L D3,$2A(A1) + MOVE.L $8(A6),A1 + MOVE.L $E(A4),D4 + MOVE D4,(A1) + LEA.L -$38(A6),A0 + LEA.L -$AC(A6),A1 + BRA.S @saveVals +@nope + ; get the resource list for the specified device LEA MYBLOCK(A6),A0 ; point to parameter block @@ -687,6 +938,7 @@ VARSIZE EQU PMHState ; size of locals BNE BadSlot ; => something wrong MOVE.L spResult(A0),A1 ; save the pointer to the block +@saveVals ADD.L vpBaseOffset(A1),D3 ; calculate baseAddr MOVE.L D3,(A2)+ ; save baseAddr @@ -731,11 +983,13 @@ VARSIZE EQU PMHState ; size of locals MOVE.L vpPlaneBytes(A1),(A2)+ ; offset from one plane to another - ; dispose of the sBlock + TST.B -$D3(A6) + BNE.S @dont MOVE.L A1,spsPointer(A0) ; - _sDisposePtr ; + _SDisposePtr ; MOVE.L A4,spsPointer(A0) ; restore pointer to list +@dont ; use DevType to initialize the color table @@ -748,14 +1002,14 @@ VARSIZE EQU PMHState ; size of locals GetClut CLR.L -(SP) ; make room for function result MOVE D5,-(SP) ; push resource ID - _GetCTable ; load in the color table resource + JSR ([$1660]) ; load in the color table resource MOVE.L (SP)+,D0 ; did we get one? BEQ TableOK ; => no, just punt MOVE.L D0,-(SP) ; push new handle for dispose MOVE.L D0,-(SP) ; push source handle MOVE.L (A2),-(SP) ; push destination handle - _CopyHandle ; copy table into our handle - _DisposCTable ; and dispose of new color table + JSR ([$1A14]) ; copy table into our handle + JSR ([$1690]) ; and dispose of new color table BRA.S TableOK ; => and continue ; @@ -788,10 +1042,11 @@ GetFromSlot MOVE.B #mTable,spID(A0) ; the fixed table <2.3> CMPI.L #minSeed,D0 ; is it a resource ID?

BLE.S @UseOriginalSeed ; -> yes, assume we know what we're doing

@GetNewSeed SUBQ #4,SP ; make room for function result <2.3> - _rGetCTSeed ; get a new, unique ctable seed <2.3> + JSR ([$16A0]) ; get a new, unique ctable seed MOVE.L (SP)+,ctSeed(A1) ; put in the new seed <2.3> @UseOriginalSeed ; transindex/ctflags set below <2.3> + ;¥¥¥ CSS end rollin GetDevPixMapPatch from Horror MOVE.L A4,spsPointer(A0) ; Restore the pointer to mode list. @@ -868,472 +1123,7 @@ CheckDevices PROC EXPORT ; CheckDevices is called by InitGraf. -PARAMSIZE EQU 0 - -IOPBlk EQU -IOVQElSize ; [64] parameter blk for I/O calls -SlotParms EQU IOPBlk-spBlock.SPBlockSize ; parameter block for slot manager calls -VidParms EQU SlotParms-12 ; [12] size of mode params -StartList EQU VidParms-4 ; [long] pointer to start of resource -VARSIZE EQU StartList ; size of locals - - - LINK A6,#VARSIZE ; allocate local stack frame - MOVEM.L D6-D7/A2-A4,-(SP) ; save work registers - -; check to see if the device list needs to be initialized - - MOVE.L DeviceList,A0 ; get handle to device list - MOVE.L (A0),A0 ; point to head of device list - MOVE GDFlags(A0),D0 ; get the flags word - BTST #AllInit,D0 ; test initialize flag? - BNE GoHome ; => devices already initialized - -; test the scrnInval lo-mem to make sure the screen resource is valid. - - TST.B scrnInval ; if this byte is cleared, then invalid - BEQ GoHome ; - -; try to load in the resource. If none, then exit - - CLR.L -(SP) ; make room for function result - MOVE.L #'scrn',-(SP) ; push desired resource type - CLR -(SP) ; resource ID = 0 - _GetResource ; get the resource - MOVE.L (SP)+,D0 ; get the resource handle - BEQ GoHome ; => none, don't configure - -; lock down the handle, and point at the data - - MOVE.L DeviceList,A0 ; get handle to device list - MOVE.L (A0),A0 ; point to head of device list - BSET #AllInit,GDFlags(A0) ; say list has been initialized - - MOVE.L D0,-(SP) ; save resource for ReleaseResource - MOVE.L D0,A0 ; get the resource - _HLock ; lock it down - MOVE.L (A0),A4 ; A4 = resource pointer - -; validate the 'scrn' resource. There must be a descriptor for every screen device. -; I assume that there are no duplicate entries and that screens don't overlap. -; In addition the devices in the 'scrn' resource must be in slot order. - - MOVE.L A4,StartList(A6) ; save pointer to start of list - MOVE (A4)+,D7 ; get the number of screens in resource - - WITH spBlock,vpBlock - - LEA SlotParms(A6),A0 ; get pointer to parameter block - MOVE.L #((CatDisplay << 16) ++ TypVideo),spCategory(A0) ; - ; set category ID, type - MOVE.W #DrSwApple,spDrvrSw(A0) ; set software, hardware ID - MOVE.B #$01,spTBMask(A0) ; ignore spDrvrH - MOVE.B #0,spSlot(A0) ; start with desired slot - MOVE.B #0,spID(A0) ; start with first ID - CLR.B spExtDev(A0) ; -NxtDev LEA SlotParms(A6),A0 ; get pointer to parameter block - _sNextTypesRsrc ; get next video device - BEQ.S GotDev ; => there is one - -; there are no more screens, are there more resources? - - TST D7 ; there should have been one per device - BEQ GoodRsrc ; => there was, go initialize them - BRA.S BadScrn ; - -; scan through scrn resource for this device - -GotDev MOVE (A4)+,D0 ; get type - CMP spDrvrHw(A0),D0 ; does it match? - BNE.S badScrn ; => nope, bad screen resource - MOVE (A4)+,D0 ; get slot - CMP.B spSlot(A0),D0 ; does it match? - BNE.S badScrn ; => nope, bad screen resource - -; get the DCE entry for the device and check dCtlDevBase -; if no match look for more devices in same slot - -SlotOK MOVE spRefNum(A0),D0 ; get the refNum - NOT D0 ; refNum -> unitnum - ASL #2,D0 ; get offset in unitTable - MOVE.L UTableBase,A1 ; get the base of the unit table - MOVE.L (A1,D0),A3 ; A3 = handle to the DCE - MOVE.L (A3),A1 ; get pointer to the DCE - MOVE.L dCtlDevBase(A1),D0 ; get dCtlDevBase - CMP.L (A4)+,D0 ; do they match? - BNE.S badScrn ; => nope, bad screen resource - -; to be completely compulsive about it, make sure there's a grafDevice for it - - MOVE.L DeviceList,A3 ; A3 = first grafdevice in list - MOVE spRefNum(A0),D1 ; get refnum -@NxtGD MOVE.L (A3),A1 ; get pointer to device - CMP GDRefNum(A1),D1 ; does refnum match? - BEQ.S RectCheck ; => yes, this device matches! - MOVE.L GDNextGD(A1),D0 ; get handle of next device - MOVE.L D0,A3 ; get in A3 - BNE.S @NxtGD ; => check all grafDevices - BRA.S badScrn ; => no such grafDevice, bad 'scrn' - -; -; compare the size of the remembered screen rect to the size of this gDevice's -; gdRect. At this point, the GDRects are still topleft=(0,0) from InitGDevice -; so we can just check 'scrn' rect against botRight. - -RectCheck - ADD #10,A4 ; skip to global rect in scrn - MOVE.W bottom(A4),D0 ; get bottom - SUB.W top(A4),D0 ; = height - CMP.W GDRect+bottom(A1),D0 ; is it equal? - BNE.S badScrn ; nope, we're out - MOVE.W right(A4),D0 ; get right - SUB.W left(A4),D0 ; = width - CMP.W GDRect+right(A1),D0 ; is it equal? - BNE.S badScrn ; nope, we're out - -; this device matches! go check next one - -SkipData ADD #8,A4 ; skip to control field - MOVE (A4)+,D0 ; get number of control calls - BRA.S SkipCtl ; skip control call -SkipNxt MOVE.L (A4)+,D1 ; get control code, size of params - ADD D1,A4 ; add size of params to skip block -SkipCtl DBRA D0,SkipNxt ; => skip next control - - SUBQ #1,D7 ; decrement device count - BMI.S badScrn ; => oops, bad screen resource - BRA NxtDev ; => check next device - -BadScrn -; If the screen resource is bad, then let's walk down the device list and offset -; the invalid screens' GDRects so that they don't all pile up at (0,0). Let's keep -; is simple- I just put them all edge to edge, top edge at 0 (unchanged) and to the -; right of the previous guys. Offset the GDPMap's rect also. - - MOVE.L DeviceList,A0 ; get the head of the list (the boot screen) - MOVE.L (A0),A0 ; hndl->ptr - MOVE.W GDRect+right(A0),D1 ; get the boot screen's right edge (if the scrn - ; is invalid, then this is the real right edge) -@Loop MOVE.L GDNextGD(A0),D0 ; get handle to next screen - BEQ Done ; if NIL, then we're out of here - MOVE.L D0,A0 ; get this device - MOVE.L (A0),A0 ; hndl->ptr - ADD.W D1,GDRect+left(A0) ; offset the left edge (normally zero) - ADD.W D1,GDRect+right(A0) ; offset the right edge - MOVE.L gdPMap(A0),A1 ; get the GDPMap handle - MOVE.L (A1),A1 ; get the gdPMap pointer - ADD.W D1,pmBounds+left(A1) ; offset the left edge (normally zero) - ADD.W D1,pmBounds+right(A1) ; offset the right edge - - MOVE.W GDRect+right(A0),D1 ; get the new right edge for the next device - BRA.S @Loop ; for each screen - -GoodRsrc _HideCursor ; cursor must be hidden here - MOVE.B #1,CRSRBUSY ; MARK CHANGE IN PROGRESS - MOVE.L CRSRDEVICE,A0 ; GET HANDLE TO CURSOR DEVICE - MOVE.L (A0),A0 ; POINT TO CURSOR DEVICE - MOVE.L GDRECT+TOPLEFT(A0),D0 ; GET SCREEN TOPLEFT - SUB D0,MOUSE+H ; CONVERT MOUSE TO SCREEN LOCAL - SWAP D0 ; GET SCREEN TOP - SUB D0,MOUSE+V ; CONVERT MOUSE TO SCREEN LOCAL - MOVE.L MOUSE,MTEMP ; copy to mouse temp - MOVE.L MOUSE,RAWMOUSE ; and to raw coordinates - -; configure each entry in the scrn resource - - MOVE.L StartList(A6),A4 ; save pointer to start of list - MOVE (A4)+,D7 ; get the number of screens in resource - SUBQ #1,D7 ; make it 0 based - -DoNxt LEA SlotParms(A6),A0 ; get pointer to parameter block - MOVE.L #((CatDisplay << 16) ++ TypVideo),spCategory(A0) ; - ; set category ID, type - MOVE.W #DrSwApple,spDrvrSw(A0) ; - ; set software, (invalid) hardware ID - MOVE (A4)+,spDrvrHw(A0) ; set driver hardware ID - MOVE.B #$00,spTBMask(A0) ; all fields valid - MOVE (A4)+,D0 ; get slot - MOVE.B D0,spSlot(A0) ; does it match? - MOVE.B #0,spID(A0) ; start with first ID - CLR.B spExtDev(A0) ; - _sNextTypesRsrc ; get next video device - BNE BadScrn ; => this should never be taken - -; we found a device that matches the given description! Find its GDevice and configure it - - MOVE spRefNum(A0),D1 ; D1 = refnum - - MOVE.L DeviceList,A3 ; A3 = first grafdevice in list -@NxtGD MOVE.L (A3),A0 ; get pointer to device - CMP GDRefNum(A0),D1 ; does refnum match? - BEQ.S @GotGD ; => yes, got the grafDevice - MOVE.L GDNextGD(A0),D0 ; get handle of next device - MOVE.L D0,A3 ; get in A0 - BNE.S @NxtGD ; => check all grafDevices - BRA BadScrn ; => this should never be taken - -@GotGD MOVE.L (A4)+,D0 ; discard dCtlDevBase - -; set up the GDFlags word before calling InitGDevice - -@0 MOVE.L (A3),A1 ; point at the grafDevice - MOVE GDFlags(A1),D0 ; get the flags word - AND 2(A4),D0 ; turn off the bits that are used - OR 4(A4),D0 ; turn on new bits - BSET #RAMInit,D0 ; say we've initialized it - BSET #ScreenDevice,D0 ; and flag it as a screen device - MOVE D0,GDFlags(A1) ; set the flags word - -; if main device, set up low-memory handles - -ChkMain MOVE GDFlags(A1),D0 ; get the flags word - BTST #mainScreen,D0 ; is it the main scrn? <2.2> - BEQ.S @InitGD ; => no, go init device - - MOVE.L A3,MainDevice ; set up as main screen device - MOVE.L A3,TheGDevice ; set up as default destination device - MOVE.L A3,SrcDevice ; set up as default source device - ; allocCursor called by initgraf to init cursor - MOVE.L (A3),A0 ; point to gDevice - MOVE.L gdPMap(A0),A0 ; get pixMap handle - MOVE.L (A0),A0 ; point to pixMap - MOVE.L baseAddr(A0),D0 ; get base address - MOVE.L D0,scrnBase ; and set up screen base - - LEA SlotParms(A6),A0 ; point at slot manager block again (it's still positioned from above) - MOVE (A4),D0 ; get the requested mode -;+++ MOVE.B D0,spID(A0) ; put in block - MOVE.B #128,spId(A0) ; pass the default mode (assumed to be 1-bit mode) - _sFindStruct ; point to this mode information - - MOVE.B #mVidParams,spID(A0) ; now get the device pixmap - _sGetBlock ; on the system heap (I guess this is OK) - MOVE.L spResult(A0),A1 ; get the result pointer - MOVE.w vpRowBytes(A1),screenRow ; get the screen row bytes (WORD) - -; set up the lo-mem for screen resolution too. It's only WORD/WORD rather then FIXED/FIXED - MOVE.W vpHRes(A1),ScrHRes ; Take the high word of vpHRes - MOVE.W vpVRes(A1),ScrVRes ; Take the high word of vpVRes - - MOVE.L A1,spsPointer(A0) ; now, release the sBlock - _sDisposePtr ; - -@InitGD - MOVE D1,-(SP) ; push refnum - MOVE (A4)+,-(SP) ; push mode - CLR -(SP) ; which should be long - MOVE.L A3,-(SP) ; push grafDevice - _InitGDevice ; configure the grafDevice - ADDQ #4,A4 ; mask and flags already used - -; -; if there is a gamma table resource id, get the gamma correction table and call the driver -; We need to do this before the color table to make sure it takes effect right away. -; - - MOVE 2(A4),D0 ; get the gamma table resource id - CMP #-1,D0 ; is it -1? - BEQ.S ChkTbl ; => yes, no table - -; -; if the gamma table resource id = -2, then request linear gamma from the driver -; - - CMP #-2,D0 ; is it -2? - BNE.S @GetFromSys ; nope, so load the system resource - - LEA VidParms(A6),A1 ; point to parameter block - CLR.L csGTable(A1) ; pass NIL to tell new drivers to set linear - BSR.S GammaControl ; call a common routine to set gamma - BRA.S ChkTbl ; - -; -; load the gamma resource from the system and set it -; - -@GetFromSys - CLR.L -(SP) ; make room for function result - MOVE.L #'gama',-(SP) ; push gamma table rsrc type - MOVE D0,-(SP) ; else push resource id - _GetResource ; try to read in gamma table - MOVE.L (SP)+,D0 ; get the result - BEQ.S ChkTbl ; => couldn't find it, use default - MOVE.L D0,-(SP) ; save a copy for later - MOVE.L D0,A0 ; setup for HLock - _HLock ; - LEA VidParms(A6),A1 ; point to params for SetGamma - MOVE.L (A0),csGTable(A1) ; gamma table pointer is only param - BSR.S GammaControl ; call a common routine - MOVE.L (SP),A0 ; get the resource handle back - _HUnlock ; free it - _ReleaseResource ; and release it (fixing the stack) - BRA.S ChkTbl ; continue on - -; -; here's an imbedded utility. I know I burn 2 bytes always BSRing around it, but I -; would burn two with a word branch if the utility were outside. This routine sets -; up the iopb and csParam block for a SetGamma control call. It expects the csGTable -; field to be set up, the csParam block pointer in A1, and the gdevice pointer in A3. -; - -GammaControl - LEA IOPBlk(A6),A0 ; point to parameter block - MOVE.L A1,csParam(A0) ; move addr of parms into block - MOVE.W #4,csCode(A0) ; csc_SetGamma - CLR.L ioCompletion(A0) ; no completion routine - CLR.W ioVRefNum(A0) ; no volRefNum - MOVE.L (A3),A1 ; point to gdevice - MOVE GDRefNum(A1),ioRefNum(A0) ; set device's refnum - _Control ,IMMED ; SetGamma(GammaTable) - ; if error here (likely if -2 were passed to - ; and old driver) then just use default table - RTS ; and back - -; -; Previously, if there was a color table resource id, this part loaded that table. Now, -; it checks the state of the gdDevType bit. If it is monochrome (=0), then this routine -; substitutes pixelSize+32 for the resID. If it is color (=1) and 2- or 4-bit mode, then -; pixelSize+64 is substituted to yield a modified color table that includes the highlight -; color. -; -; If we EVER have a gamma ID <> -1 (not default), then be sure to set the color table <2.3> -; to flush this gamma into the CLUT hardware. -; -; The pointer to the gDevice is still in A1. -; - -ChkTbl - MOVE.L (A3),A1 ; point to the gDevice again - MOVE.L gdPMap(A1),A0 ; get pixmap - MOVE.L (A0),A0 ; get pixmap ptr - MOVE.W pmPixelSize(A0),D0 ; get depth - - CMP #DirectType,gdType(A1) ; is it a direct device? - BEQ SetGRect ; if so, then do nothing - - BTST #gdDevType,gdFlags+1(A1) ; is it color or monochrome mode? - BNE.S @ClrMode ; if set, then this is color - cmp.w #2,d0 ; 1 or 2 bit/pixel? <2.1> - ble.s @regClr ; don't do anything funky <2.1> -@MonoMode - ADD #32,D0 ; add 32 to pixelsize in all modes for linear gray - BRA.S @GetClut ; -@ClrMode - MOVE.W D0,D1 ; copy the depth - AND #9,D1 ; is it 1- or 8-bit mode? - BNE.S @regClr ; if so, then do regular behavior -@is2or4 - ADD #64,D0 ; for 2- or 4-bit, add 64 to pixel depth (gives color+highlight) - BRA.S @GetClut ; - -@regClr - MOVE (A4),D1 ; get the color table resource id - CMP #-1,D1 ; is it -1? - BNE @GetClut ; if not, then set the CLUT <2.3> - CMP #-1,2(A4) ; if CLUTid=-1, and gammaID<>-1, then set CLUT to flush <2.3> - BEQ.S SetGRect ; if both are default, then continue <2.3> - -@GetClut CLR.L -(SP) ; make room for function result - MOVE D0,-(SP) ; else push resource id - _GetCTable ; get a color table - MOVE.L (SP)+,D0 ; get the result - BEQ.S SetGRect ; => couldn't find it, use default - - MOVE.L (A3),A0 ; point at the grafDevice - MOVE.L GDPMap(A0),A0 ; get handle to its pixmap - MOVE.L (A0),A0 ; point at the pixmap - MOVE.L pmTable(A0),-(SP) ; push our color table for set entries - MOVE.L D0,-(SP) ; push new table handle for dispose - MOVE.L D0,-(SP) ; push source color table - MOVE.L pmTable(A0),-(SP) ; push destination color table - _CopyHandle ; copy new table into our handle - _DisposCTable ; and dispose new handle - -; now call the driver to set this color table (handle on stack) - - MOVE.L (SP),A0 ; get handle to color table - _HLock ; lock down the color table - LEA VidParms(A6),A1 ; point to params for SetEntries - MOVE.L (A0),A0 ; get ctabPtr - CLR.W csStart(A1) ; start at zero, use sequence mode - MOVE.W ctSize(A0),csCount(A1) ; for the length of the table - LEA ctTable(A0),A0 ; get pointer to colorspecs - MOVE.L A0,csTable(A1) ; color table pointer is first param - LEA IOPBlk(A6),A0 ; point to parameter block - MOVE.L A1,csParam(A0) ; move addr of parms into block - MOVE.W #3,csCode(A0) ; csc_SetEntries - CLR.L ioCompletion(A0) ; no completion routine - CLR.W ioVRefNum(A0) ; no volRefNum - MOVE.L (A3),A1 ; point to gdevice - MOVE GDRefNum(A1),ioRefNum(A0) ; set device's refnum - _Control ,IMMED ; SetEntries(ColorTable); - MOVE.L (SP),A0 ; get handle to color table - _HUnLock ; unlock the color table - -; finally, generate an inverse table for the table (handle on stack) - - ; color table handle on stack - MOVE.L (A3),A1 ; point at the grafDevice - MOVE.L GDITable(A1),-(SP) ; push inverse table handle - MOVEQ #4,D0 ; make 4-4-4 inverse tables - MOVE D0,GDResPref(A1) ; save in GDevice - MOVE D0,-(SP) ; and push res - _MakeITable ; and generate inverse table - -; use the specified rectangle to determine the device's global coordinates - -SetGRect - ADDA #4,A4 ; skip the CLUT and gamma resID's - MOVE.L (A3),A0 ; point to the grafDevice - MOVE.L GDPMap(A0),A1 ; get handle to pixMap - MOVE.L (A1),A1 ; get pointer to pixMap - ADDQ #Bounds,A1 ; point to pixMap.bounds - LEA GDRect(A0),A0 ; point to its rectangle - MOVE.L (A4)+,D0 ; get topLeft for mouse offset - MOVE.L D0,(A1)+ ; copy topLeft to pixMap.bounds - MOVE.L D0,(A0)+ ; copy topLeft to GDRect - MOVE.L (A4),(A1) ; copy botRight to pixMap.bounds - MOVE.L (A4)+,(A0)+ ; copy botRight to GDRect - -; parse and execute the additional control commands - - MOVE (A4)+,D6 ; get number of control calls - BRA.S ChkNxtCtl ; => jump into end of dbra loop -DoCtl LEA IOPBlk(A6),A0 ; point to parameter block - LEA 4(A4),A1 ; point to call parameters - MOVE.L A1,csParam(A0) ; move addr of parms into block - MOVE.W (A4)+,csCode(A0) ; set control code - CLR.L ioCompletion(A0) ; no completion routine - CLR.W ioVRefNum(A0) ; no volRefNum - MOVE.L (A3),A1 ; point to gdevice - MOVE GDRefNum(A1),ioRefNum(A0) ; set device's refnum - _Control ,IMMED ; and issue the control call - - MOVE (A4)+,D0 ; get size of param block - ADD D0,A4 ; skip param block -ChkNxtCtl DBRA D6,DoCtl ; loop for all control calls - -ChkNxt DBRA D7,DoNxt ; loop for all screens in resource - -; NOW UPDATE THE MOUSE TO THE COORDINATE SYSTEM OF ITS SCREEN AND DISPLAY IT - - MOVE.L CRSRDEVICE,A0 ; GET HANDLE TO CURSOR DEVICE - MOVE.L (A0),A0 ; POINT TO CURSOR DEVICE - MOVE.L GDRECT+TOPLEFT(A0),D0 ; GET SCREEN TOPLEFT - ADD D0,MOUSE+H ; CONVERT MOUSE TO GLOBAL - SWAP D0 ; GET SCREEN TOP - ADD D0,MOUSE+V ; CONVERT MOUSE TO GLOBAL - MOVE.L MOUSE,MTEMP ; copy to mouse temp - MOVE.L MOUSE,RAWMOUSE ; and to raw coordinates - CLR.B CRSRBUSY ; end of change - _AllocCursor ; make sure cache structures are OK <5+> - _ShowCursor ; now redisplay cursor - -DONE _ReleaseResource ; all done with the resource - -GoHome MOVEM.L (SP)+,D6-D7/A2-A4 ; restore work registers - UNLINK PARAMSIZE,'CHECKDEV' - - ENDWITH + RTS ;------------------------------------------------------------- ; diff --git a/QuickDraw/GWorld.a b/QuickDraw/GWorld.a index c2a1838..3165b6f 100644 --- a/QuickDraw/GWorld.a +++ b/QuickDraw/GWorld.a @@ -695,6 +695,9 @@ varSize equ localRect ; size of local variables move #noErr,result(a6) ; flag a successful operation, + move.l offscreenGWorld(a6),a0 + clr.l (a0) + ;------------------------------------------------------------------------- ; Initialize all offscreen local variables to zero. ; If an error happens during this function, we deallocate the memory for @@ -765,6 +768,14 @@ varSize equ localRect ; size of local variables cmp #32,d7 ; illegal if > 32 bhi badPixelDepth ; exit with error +;------------------------------------------------------------------------- +; Treat 24-bit color as 32-bit. + + cmp #24,d7 + bne.s @dontSetTo32 + moveq #32,d7 +@dontSetTo32 + ;------------------------------------------------------------------------- ; If pixelDepth is not 0, don't try to align offscreen pixmap to screen @@ -1003,6 +1014,17 @@ createPixMap moveq #5,d0 ; no, cmpSize = 5 @0 move d0,pmCmpSize(a1) ; store cmpSize in pixmap + btst.l #$1,d3 + beq.s @skipthisnonsense + move.l ([museDevice,a6]),a0 + move.l ([gdPMap,a0]),a0 + move.l gdMode(a0),a0 + move.l a0,offscreenCTable(a6) + move.l ([offscreenPixMap,a6]),a1 + move.l a0,gdMode(a1) + bra createDevice +@skipthisnonsense + ; Create an empty color table. move #ctRec,d0 ; size of an empty color table @@ -1025,7 +1047,7 @@ createPixMap ; Create a dummy inverse table (doesn't have to be a seed) - moveq #2,d0 ; small handle for dummy inverse table + moveq #4,d0 ; small handle for dummy inverse table _NewHandle ,CLEAR ; allocate it bne reportError ; if Memory Manager error, report it and quit @@ -1149,7 +1171,7 @@ dontCloneCTab ; Allocate inverse table to its initial size - moveq #2,d0 ; initial size is 2 + moveq #4,d0 ; initial size is 2 _NewHandle ,CLEAR ; allocate it bne reportError ; if Memory Manager error, report it and quit @@ -1393,9 +1415,9 @@ disposOffscreenHandles move portVersion(a0),d0 ; get portVersion and #cPortFlag,d0 ; check if cPortFlag set cmp #cPortFlag,d0 ; is it set? - bne @0 ; if not set, don't close port + bne.s @0 ; if not set, don't close port move.l (a0),-(sp) ; push pointer to port - _ClosePort ; close it down + _CloseCPort ; close it down @0 move.l d7,a0 ; get handle to offscreen port _DisposHandle ; dispose it @@ -1732,7 +1754,7 @@ dontDisposeBaseAddr dontDisposeGDevice move.l offscreenGWorld(sp),-(sp) ; push pointer to offscreen port - _ClosePort ; get rid of all substructures + _CloseCPort ; get rid of all substructures move.l offscreenGWorld(sp),a0 ; get pointer to grafport _RecoverHandle ; find handle to grafport diff --git a/QuickDraw/GrafAsm.a b/QuickDraw/GrafAsm.a index 99d678d..cefa226 100644 --- a/QuickDraw/GrafAsm.a +++ b/QuickDraw/GrafAsm.a @@ -72,7 +72,7 @@ SIZEOK _NewHandle ,CLEAR ; ask OS to do request ; handle the memory full error by deep-shitting MemFull MOVEQ #25,D0 ;Deep Shit memory full error code - _SysError + DC.W $A9C9 ;_SysError JacksonPollock DC.W $A9FF ;invoke debugger just in case it comes back @@ -315,7 +315,6 @@ CRSRLP MOVE.L (A0)+,(A4)+ ;COPY A LONG INTO GLOBALS ; IF SCREENS NOT INITIALIZED FROM 'scrn' RESOURCE, INIT THEM - bsr.l CheckDevices ; configure screens, if needed MOVE.L MainDevice,A0 ; get main device MOVE.L A0,theGDevice ; set gDevice MOVE.L A0,srcDevice ; and srcDevice just in case diff --git a/QuickDraw/LCursor.a b/QuickDraw/LCursor.a index 0dcf8cf..1e2ea5b 100644 --- a/QuickDraw/LCursor.a +++ b/QuickDraw/LCursor.a @@ -40,11 +40,7 @@ AllocCursor PROC EXPORT ; PROCEDURE AllocCursor; ; - LEA AllocCrsr,A0 ;get default cursor routine - MOVE.L JAllocCrsr,D0 ;has vector been initialized? - BEQ.S @0 ;=>no, use default routine - MOVE.L D0,A0 ;else use routine in vector -@0 JMP (A0) ;and call it + JMP AllocCrsr InitCursor PROC EXPORT @@ -55,8 +51,8 @@ InitCursor PROC EXPORT MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS PEA ARROW(A0) ;PUSH ADDR OF ARROW _SetCursor ;INSTALL ARROW CURSOR - MOVE.L JInitCrsr,A0 ;get lo mem pointer - JMP (A0) ;and call it + IMPORT _InitCursor + JMP _InitCursor @@ -70,8 +66,8 @@ SetCursor PROC EXPORT MOVE #16,-(SP) ;HEIGHT:=16 PEA DATA(A0) ;PUSH ADDR OF DATA PEA MASK(A0) ;PUSH ADDR OF MASK - MOVE.L JSetCrsr,A0 ;get lo mem vector - JSR (A0) ;call vector + IMPORT _SetCursor + JSR _SetCursor MOVE.L (SP)+,(SP) ;strip param RTS ;and return @@ -92,8 +88,8 @@ SetCCursor PROC EXPORT ; _SetCursor ; and set it the old way MOVE.L 4(SP),-(SP) ; Push handle to color cursor - MOVE.L JSetCCrsr,A0 ; get lo mem vector - JSR (A0) ; call vector (but don't call him hector) + IMPORT _SetCCursor + JSR _SetCCursor ; _ShowCursor ; balance is a virtue MOVE.L (SP)+,(SP) ; strip param RTS ; and return @@ -107,8 +103,8 @@ HideCursor PROC EXPORT ; ; ALL REGS PRESERVED. ; - MOVE.L JHideCursor,-(SP) ;get lo mem vector - RTS ;and call it + IMPORT _HideCursor + JMP _HideCursor @@ -119,36 +115,8 @@ ShowCursor PROC EXPORT ; ; ALL REGS PRESERVED. ; - MOVE.L JShowCursor,-(SP) ;get lo mem vector - RTS ;and call it - - - -ShieldCursor PROC EXPORT -;--------------------------------------------------------- -; -; PROCEDURE ShieldCursor(shieldRect: Rect; offset: Point); -; -; ALL REGS PRESERVED. -; - MOVEM.L D0-D3/A0-A1,-(SP) ;SAVE REGS - MOVE.L 32(SP),A0 ;POINT TO SHIELDRECT - MOVEM.W (A0)+,D0/D1/D2/D3 ;GET TOP ... RIGHT - LEA 28(SP),A1 - SUB (A1),D0 ;TOP - OFFSET.V - SUB (A1)+,D2 ;BOTTOM - OFFSET.V - SUB (A1),D1 ;LEFT - OFFSET.H - SUB (A1),D3 ;RIGHT - OFFSET.H - MOVE D1,-(SP) ;PUSH GLOBAL LEFT - MOVE D0,-(SP) ;PUSH GLOBAL TOP - MOVE D3,-(SP) ;PUSH GLOBAL RIGHT - MOVE D2,-(SP) ;PUSH GLOBAL BOTTOM - MOVE.L JShieldCursor,A0 ;get lo mem vector - JSR (A0) ;and call it - MOVEM.L (SP)+,D0-D3/A0-A1 ;RESTORE REGS - MOVE.L (SP)+,(SP) - MOVE.L (SP)+,(SP) ;STRIP 8 BYTES - RTS ;AND RETURN + IMPORT _ShowCursor + JMP _ShowCursor @@ -159,10 +127,8 @@ ObscureCursor PROC EXPORT ; ; Hide the cursor image until the next time the mouse moves. ; - MOVE.L JCrsrObscure,A0 ;get lo mem vector - JMP (A0) ;and call it - - + IMPORT _ObscureCursor + JMP _ObscureCursor ENDPROC diff --git a/QuickDraw/PaletteMgr.a b/QuickDraw/PaletteMgr.a index cad5eb0..f75181a 100644 --- a/QuickDraw/PaletteMgr.a +++ b/QuickDraw/PaletteMgr.a @@ -172,7 +172,7 @@ plttUpdates Equ $0002 ; value passed to SetPalette [short] AWC.PB457 ;ctReserveBit EQU 6 ;ctReserveVal EQU $4000 -PMgrVersNum EQU $0202 ; Version number (VVss: version subversion) +PMgrVersNum EQU $0203 ; Version number (VVss: version subversion) ;----------------------------------------------------------- ; Let's talk about PMgrVersNum -- ; @@ -228,6 +228,46 @@ PMgrVersNum EQU $0202 ; Version number (VVss: version subversion) ; GetNewCWindow which is patched in PatchIIROM.a +FlushPalettes PROC EXPORT ; THIEVED FROM THE MEMORY MGR +;----------------------------------------------------------------------- +; Call DisposePalette for all palettes in the app heap. +; +; Registers: D0-D2/A0-A1 +; Called by vIAZInit. +;---------------------------------------------------------------------- + IMPORT AppZoneAddr + + MOVEM.L A2-A3/D3,-(SP) ; save work registers + MOVE.L PMgrHandle,A2 ; get paletteMgr handle + CMP.L MinusOne,A2 ; is it there? + BEQ.S @DONE ; => no, just return + MOVE.L (A2),A1 ; point to data structure + MOVE.L PListHandle(A1),A0 ; get handle to palette list + _HLock ; and lock it down + MOVE.L (A0),A3 ; point to palette list + + Move APalettes(A1),D3 ; get number of active handles + Beq.s @NoPals ; no friends => go home + Add FreeSpaces(A1),D3 ; calculate total number of entries + BRA.S @FindEnd ; => check for no entries + +@FindLoop Move.L PaletteRef(A3),D1 ; get first entry + BEQ.S @FindNext ; => no palette in entry + MOVE.L D1,D0 ; and get for routine + JSR AppZoneAddr ; in application area (or zero)? + BNE.S @FindNext ; => not in app heap + MOVE.L D1,-(SP) ; push palette handle + DC.W $AA93 ; _DisposePalette ; and dispose it in place +@FindNext AddQ #PLstEntrySz,A3 ; bump to the next entry +@FindEnd DBra D3,@FindLoop ; repeat for all spaces + +@NoPals MOVE.L (A2),A1 ; point to palette stuff + MOVE.L PListHandle(A1),A0 ; get handle to palette list + _HUnlock ; and unlock it + +@DONE MOVEM.L (SP)+,A2-A3/D3 ; restore work registers + RTS + ;--------------------------------------------------- ; ; PROCEDURE ActivatePalette(dstWindow: WindowPtr); INLINE $AA94; @@ -584,14 +624,8 @@ gLoopEnd DBRA D3,gLoop ; loop for all devices ; return Z-flag Clear if the process mgr is here (BNE ProcMgrTrue) CheckForProcessMgr PROC EXPORT - MOVE.L #'os ',D0 ; type of question - _Gestalt - TST D0 ; OSErr from Gestalt? - BEQ.S @a ; No=>test result - SUBA A0,A0 ; Yes=>assume there's no procMgr -@a - MOVE.L A0,D0 - BTST #gestaltLaunchControl,D0 ; clear the Z-flag if procmgr here + MOVE.L ExpandMem,A0 + TST $128(A0) RTS ;--------------------------------------------------- @@ -624,7 +658,7 @@ linkSize DS.B 0 ; linky number movem.l a0-a2/d0-d2,-(sp) ; Those pesky c routines sub.l a0,a0 ; Pass the current process (0) - move.w #12,d0 ; _TrashProcess + moveq #12,d0 ; _TrashProcess ;_FigmentDispatch ; let everyone know this stuff is gone dc.w $A0A4 movem.l (sp)+,a0-a2/d0-d2 ; Restore em @@ -660,7 +694,7 @@ linkSize DS.B 0 ; linky number PEA inFront(A6) _SameProcess ; are we the front process? ADDQ #2,SP ; OSErr leaves inFront true from above - TST inFront(A6) + TST.B inFront(A6) BEQ.S @doNothing @front @@ -1805,8 +1839,9 @@ linkSize DS.B 0 ;linky number MOVE.L (A2),A3 ; A3->gDevice TST gdType(A3) ; a clut device? BNE.S GoHome ; No=> go home w/false - TST gdFlags(A3) ; Device active? - BPL.S GoHome ; No=> ditto + MOVE $14(A3),D0 + AND #$8010,D0 + BEQ.S GoHome ; No=> ditto SUBQ #4,SP ; space for result MOVE.L A2,-(SP) ; push gDevice handle JSR GetClut ; get the appropriate default clut @@ -2505,8 +2540,9 @@ FoundAPltt Move.L A2,srcPalette(A6) ; save it so we can unlock it AWC.PB520 BEQ.s @a ; is it a clut device? SUBQ #1,D1 ; fixed type? BNE.S UnlockPltt ; no => we're almost done -@a TST gdFlags(A0) ; is it active? - BPL.S UnlockPltt ; no => ditto +@a MOVE $14(A3),D0 + AND #$8010,D0 + BEQ.S UnlockPltt Move ciUsage(A3),D1 ; get flags MoveQ #0,D0 ; clear high word Move srcEntry(A6),D0 ; set D0 in case it is an explicit index @@ -3152,8 +3188,9 @@ SetDev Move.L (A0),A0 ; dereference it TST gdType(A0) ; is it CLUT type (zero)? dvb1 BNE GoHome ; No => do nothing - TST gdFlags(A0) ; is it active - BPL GoHome ; No=>go home + MOVE $14(A0),D0 + AND #$8010,D0 + BEQ GoHome ; No=>go home Move.L gdPMap(A0),A0 ; get handle to pixmap Move.L (A0),A0 ; dereference pixmap Move.L pmTable(A0),A0 ; get handle to CTab @@ -4542,66 +4579,7 @@ ReleaseList PROC EXPORT ; FindModeID FUNC Export - WITH SpBlock,VPBlock - -FMVars RECORD {A6Link},Decrement -result DS.B 2 ; integer result -gd DS.B 4 ; input: GDevice -depth DS.B 2 ; input: depth -return DS.B 4 ; return address -A6Link DS.B 4 ; link -spBlk DS.B spBlockSize ; slot parameter block -vpPtr DS.B 4 ; pointer to vidParams block -linkSize DS.B 0 ; size of record - ENDR - - WITH FMVars - - LINK A6,#linkSize - MOVEM.L A2/D3,-(SP) ; save 'em - - CLR result(A6) ; default to failure! - - MOVE.L gd(A6),A0 ; A0 = gDevice handle - MOVE.L (A0),A1 ; A1->gDevice - - MOVE.L UTableBase,A0 ; A0->unit table - MOVE gdRefNum(A1),D0 ; D0 = refnum - NEG D0 - SUBQ #1,D0 - MOVE.L (A0,D0.W*4),A1 ; A1 = AuxDCEHandle for gDevice - MOVE.L (A1),A1 ; A1 = AuxDCEPtr for gDevice - LEA spBlk(A6),A0 ; A0 -> spBlock - MOVE.B dCtlSlot(A1),spSlot(A0) ; stash gDevice slot - CLR.B spID(A0) ; clear the ID - MOVE #catDisplay,spCategory(A0) ; category: display - MOVE #typVideo,spCType(A0) - MOVE #drSwApple,spDrvrSW(A0) ; Appleª style driver - MOVE.B #1,spTBMask(A0) - _sNextTypeSRsrc - BNE.S @goHome ; failure - - MOVE.L spsPointer(A0),A2 ; keep saving it here - MOVE #127,D3 ; the 0th mode we'll look for - -@depthScan - ADDQ #1,D3 ; bump to next mode - MOVE.B D3,spID(A0) ; look for the next mode - MOVE.L A2,spsPointer(A0) ; sFindStruct wipes out each time - _sFindStruct ; look for it - BNE.S @goHome ; failure - MOVE.B #mVidParams,spID(A0) ; now we look for video params - _sGetBlock - BNE.S @goHome ; failure - MOVE.L spResult(A0),A1 ; A1->vidParam block, finally - MOVE vpPixelSize(A1),D0 ; D0 = depth for this description - CMP depth(A6),D0 ; the one we want? - BNE.S @depthScan ; scan 'til found, or slot error - - MOVE D3,result(A6) -@goHome MOVEM.L (SP)+,A2/D3 - UNLK A6 - RTD #result-return-4 + RTS @@ -4625,6 +4603,7 @@ A6Link DS.B 4 ; link r DS.B 4 ; regionhandle oldPort DS.B 4 ; previous port myRect DS.B 8 ; rectangle for little black corners +moreStuff DS.B 10 ; not sure what for? linkSize DS.B 0 ; size of record ENDR @@ -4634,10 +4613,31 @@ linkSize DS.B 0 ; size of record MOVEM.L A2-A3/D3-D5,-(SP) ; <6> MOVE #paramErr,result(A6) ; default to failure! + MOVE.B #1,myRect+6(A6) + MOVEQ #0,D0 + MOVE depth(A6),D0 + MOVE.L D0,r(A6) - MOVE.L gd(A6),A0 ; A0 = gDevice handle - MOVE.L (A0),A1 ; A1->gDevice + CLR -(SP) + MOVE.L gd(A6),-(SP) + CLR.L -(SP) + MOVE.L r(A6),-(SP) + PEA oldPort(A6) + CLR.L -(SP) + PEA myRect+7(A6) + MOVE #$C12,D0 ; _DMRemoveDisplay + DC.W $ABEB + + TST (SP)+ + BNE.S @goHome + + MOVE.L oldPort(A6),D0 + BTST.L #1,D0 + BNE.S @goHome + + MOVE.L gd(A6),A1 + MOVE.L (A1),A1 MOVE whichFlags(A6),D0 ; D0 = mask of flags to change ANDI #whichMask,D0 ; D0 = only the ones we let them change MOVE D0,D1 ; D1 = mask of flags to change @@ -4646,137 +4646,21 @@ linkSize DS.B 0 ; size of record AND gdFlags(A1),D0 ; D0 = all the unchanged gdFlags OR D1,D0 ; D0 = new gdFlags word MOVE D0,gdFlags(A1) ; Put back into gDevice - MOVE gdRefNum(A1),D3 ; D3 = refnum, for later use - - MOVE depth(A6),D4 ; get the depth or mode - TST.B D4 ; see which it is - BMI.S @gotMode - SUBQ #2,SP + CLR -(SP) MOVE.L gd(A6),-(SP) - MOVE D4,-(SP) - Import FindModeID - BSR FindModeID ; find the mode number, if it exists - MOVE (SP)+,D4 ; did we find one? - BEQ @goHome - -@gotMode Movea.l gd(A6),A2 ; Get GDHandle into A2. - Movea.l (A2),A2 ; Get a GDPtr into A2. - Btst #mainScreen,gdFlags(A2) ; If weÕre not on the menubar screen, - Beq.s @NotMain1 ; then just keep going. - Move.w theMenu,D5 ; Get the currently hilited menuID. - Clr.w -(Sp) ; And unhilite it. - _HiliteMenu -@NotMain1 - -; Originally, DVB wasnÕt getting the current port until corner-rounding code -; was about to be executed (below). That seemed to cause port problems, so -; I move the port getting/setting code to here (which is the way Monitors -; does it). -; -; -- jmp -- - - PEA oldPort(A6) ; Save the current port - _GetPort - MOVE.L WMgrPort,-(SP) ; We want to use the WMgrPort - _SetPort - - MOVE D3,-(SP) ; push refnum - EXT.L D4 - MOVE.L D4,-(SP) ; push new gdev mode - MOVE.L gd(A6),-(SP) ; push the handle - _InitGDevice - - Btst #mainScreen,gdFlags(A2) ; If weÕre not on the menubar screen, - Beq.s @NotMain2 ; then just keep going. - Move.w D5,-(Sp) ; Get the hilite state. - _HiliteMenu ; Restore it. - _DrawMenuBar ; Draw the MenuBar. -@NotMain2 - - CLR.L -(SP) ; Activate the front palette - _FrontWindow ; before drawing anything. - _ActivatePalette - -; In Monitors (the cdev) this is the point in the code where -; the PortList is walked to update all the CGrafPorts to the -; new depth. We donÕt need to do that here because InitGDevice -; does that for us with Save/ResoreFore and Save/RestoreBack -; calls. -; -; -- jmp -- - -; If the LayerManger is around, we need to start at the root, otherwise -; we just use FrontWindow. Originally, DVB had PaintOne instead of -; PaintBehind here but VL said that was wrong. Also, Monitors uses the -; PaintOne/PaintBehind method instead of PaintOne/PaintOne method. -; -; -- jmp -- - - If HasLayers Then - _RedrawAll ; CheckUpdate on all layers <42> - Else - SUBQ #4,SP - _NewRgn - MOVE.L (SP),r(A6) ; get a fresh region, LEAVE ON STACK - - MOVE.L gd(A6),A0 ; A0 = gd handle - MOVE.L (A0),A0 ; A0->gdevice - PEA gdRect(A0) ; push rectangle to RectRgn - _RectRgn ; r is now our region - CLR.L -(SP) - MOVE.L r(A6),-(SP) - _PaintOne + PEA r(A6) + CLR.L -(SP) + CLR.L -(SP) - SUBQ #4,SP - _FrontWindow - MOVE.L r(A6),-(SP) - _PaintBehind + MOVE #$A11,D0 ; _DMEnableDisplay + DC.W $ABEB - MOVE.L r(A6),-(SP) ; Done with region - _DisposRgn - Endif - - CLR.L myRect+topLeft(A6) ; Set the empty rect - CLR.L myRect+botRight(A6) - MOVE.L deviceList,A2 ; A2 = 1st GDHandle -@dloop MOVE.L (A2),A2 ; A2 -> GDevice - BTST #screenActive,gdFlags(A2) ; bit 15 in upper byte of word - BEQ.S @dloopEnd ; Inactive screen? - PEA gdRect(A2) - PEA myRect(A6) - MOVE.L (SP),-(SP) - _UnionRect -@dloopEnd MOVE.L gdNextGD(A2),A2 - MOVE.L A2,D0 - BNE.S @dloop + MOVE (SP)+,result(A6) - PEA myRect(A6) ; Set a nice big clip - _ClipRect - PEA myRect(A6) - MOVE.L #$FFFDFFFD,-(SP) ; outset by three - _InsetRect - MOVE.L #$00030003,-(SP) ; pensize is three - _PenSize - PEA myRect(A6) - MOVE.L #$00160016,-(SP) ; and a radius for nice rounding - _FrameRoundRect ; and black out the corners - - _PenNormal - - MOVE.L oldPort(A6),-(SP) ; restore the previous port - _SetPort - - MOVE.L gd(A6),A0 - MOVE.L (A0),A0 - BTST #mainScreen,gdFlags(A0) ; (mainScreen=11, in upper byte) - BEQ.S @notMain - _DrawMenuBar -@notMain - CLR result(A6) ; success @goHome - MOVEM.L (SP)+,A2/D3-D5 + MOVEM.L (SP)+,A2-A3/D3-D5 UNLK A6 RTD #result-return-4 @@ -4790,13 +4674,15 @@ HasDepth FUNC EXPORT whichMask EQU $FFFE ; the lowest bit is settable, else fail SDVars RECORD {A6Link},DECREMENT -result DS.B 2 ; boolean result -gd DS.B 4 ; input: GDevice to set -depth DS.B 2 ; input: depth to set to -whichFlags DS.B 2 ; which GDFlags to affect -flags DS.B 2 ; input: various flags -return DS.B 4 ; return address on stack +result DS.B 2 ; 18 $12 boolean result +gd DS.B 4 ; 14 $E input: GDevice to set +depth DS.B 2 ; 12 $C input: depth to set to +whichFlags DS.B 2 ; 10 $A which GDFlags to affect +flags DS.B 2 ; 8 $8 input: various flags +return DS.B 4 ; 4 $4 return address on stack A6Link DS.B 4 ; link +myDepth DS.B 4 +moreStuff DS.B 24 linkSize DS.B 0 ; size of record ENDR @@ -4809,13 +4695,43 @@ linkSize DS.B 0 ; size of record MOVE whichFlags(A6),D0 ; D0 = mask of flags to change AND flags(A6),D0 ; D0 = new flags to set AND #whichMask,D0 ; D0 = all the bits we can't change - BNE.S @goHome ; User tried to set bits we don't yet do! + BNE @goHome ; User tried to set bits we don't yet do! + + MOVEQ #0,D0 + MOVE depth(A6),D0 + MOVE.L D0,myDepth(A6) + + CLR moreStuff+0(A6) + CLR.L moreStuff+2(A6) + CLR moreStuff+6(A6) + CLR.L moreStuff+8(A6) + CLR.L moreStuff+12(A6) + + CLR -(SP) + MOVE.L gd(A6), -(SP) + PEA moreStuff(A6) + MOVE.L myDepth(A6), -(SP) + PEA -$C(A6) + CLR.L -(SP) + + MOVE #$AF3,D0 ; unknown _DisplayDispatch selector + DC.W $ABEB + + TST (SP)+ + BNE.B @goHome + + MOVEQ.L #$7F, D0 + MOVEQ.L #0, D1 + MOVE depth(A6), D1 + CMP.L D1, D0 + BLT.B @whaaa + + MOVE $C(A6), D0 + CMP -$C(A6), D0 + BNE.B @goHome + +@whaaa MOVE -$1C(A6), $12(A6) - SUBQ #2,SP - MOVE.L gd(A6),-(SP) - MOVE depth(A6),-(SP) - BSR FindModeID ; find the mode number, if it exists - MOVE (SP)+,result(A6) ; did we find one? @goHome UNLK A6 RTD #result-return-4 @@ -5087,6 +5003,7 @@ linkSize DS.B 0 ; size of record _HLock MOVE.L (A0),A2 ; A2->color table to check MOVE ctSize(A2),D3 ; D3 = last color in table + BEQ.S @goHome MOVEQ #0, D5 ; initialized number of colors checked ; MOVE D3,D0 ; ADDQ #1,D0 @@ -5108,6 +5025,9 @@ linkSize DS.B 0 ; size of record @next ADDQ #8,A2 ; Bump to next color DBRA D3,@loop ; loop through all colors + TST D5 + BEQ.S @goHome + DIVU D5,D7 ; compute average tolerance ; DIVU colorCount(A6),D7 ; compute average tolerance CMP maxAveTol(A6),D7 ; in range? diff --git a/QuickDraw/Patterns.a b/QuickDraw/Patterns.a index fcd6b49..7e0a641 100644 --- a/QuickDraw/Patterns.a +++ b/QuickDraw/Patterns.a @@ -2308,12 +2308,12 @@ VARSIZE EQU DstRgnPtr move.w dstPix+pixelSize(A6),d0 ; preload dst depth in case not screen sub.l a0,a0 ; clear maskrgn in case not screen move.w d2,d3 ; remember screen flag in d3 - beq.s NotScreen1 + beq NotScreen1 MOVE.L DEVICELIST,A2 ; GET FIRST ELEMENT IN DEVICE LIST MOVE.L (A2),A1 ; POINT TO DEVICE TST.L GDNEXTGD(A1) ; CHECK NEXT DEVICE - beq.s NotScreen1 ; only 1 device so skip devloop + beq NotScreen1 ; only 1 device so skip devloop ; Copy dst rect and convert to global coordinates @@ -2321,38 +2321,41 @@ VARSIZE EQU DstRgnPtr lea globalRect(a6),a1 ; point at our copy move.l (a0)+,(a1)+ ; copy topleft move.l (a0),(a1)+ ; copy botRight - move.l dstPix+bounds+top(a6),d0 ; get topleft - move.w d0,d1 ; get left - swap d0 ; get top - sub.w d1,-(a1) ; convert right to global - sub.w d0,-(a1) ; convert bottom to global - sub.w d1,-(a1) ; convert left to global - sub.w d0,-(a1) ; convert top to global - lea DstRectRgn(a6),A0 - move.l a0,DstRgnPtr(a6) ; build master pointer - move.w #10,(a0) ; set region size + lea globalRect(a6),a1 + move.l a1,d0 + move.l a1,-(sp) + jsr ([$FC0]) ; _LocalToGlobal? -NEXTGD MOVE.L (A2),A0 ; POINT TO DEVICE - TST GDFLAGS(A0) ; IS IT ACTIVE? - BPL.S SKIPGD ; =>NO, SKIP IT + add #4,d0 + move.l d0,-(sp) + jsr ([$FC0]) ; _LocalToGlobal? + + lea.l DstRectRgn(a6),a0 + move.l a0,DstRgnPtr(a6) + move #10,(a0) + +NEXTGD move.l (a2),a0 + tst $14(a0) + bpl.s SKIPGD CLR.B -(SP) ; MAKE ROOM FOR BOOLEAN RESULT PEA globalRect(A6) ; PUSH SPECIFIED RECTANGLE PEA gdRect(A0) ; PUSH DEVICE'S RECTANGLE PEA dstRectRgn+rgnBBox(A6) ; PUSH DESTINATION RECT - _SECTRECT ; IS THE RECT IN THE DEVICE + JSR ([$10A8]) ; SECTRECT -- IS THE RECT IN THE DEVICE TST.B (SP)+ ; TEST RESULT BEQ.S SKIPGD ; => NO INTERSECTION - move.l dstPix+bounds+top(a6),d0 ; get topleft - move.w d0,d1 ; get left - swap d0 ; get top - lea dstRectRgn+rgnBBox(a6),a0 ; point to rect - add.w d0,(a0)+ ; convert top to local coords - add.w d1,(a0)+ ; convert left to local coords - add.w d0,(a0)+ ; convert bottom to local coords - add.w d1,(a0) ; convert right to local coords + lea dstRectRgn+rgnBBox(A6),a0 + move.l a0,d0 + move.l a0,-(sp) + jsr ([$FC4]) ; _GlobalToLocal? + + add #4,d0 + move.l d0,-(sp) + jsr ([$FC4]) ; _GlobalToLocal? + MOVE.L (A2),A0 ; POINT TO DEVICE MOVE.L GDPMAP(A0),A0 ; GET PIXMAP MOVE.L (A0),A0 ; POINT TO PIXMAP diff --git a/QuickDraw/Pictures.a b/QuickDraw/Pictures.a index ed4e136..0008db4 100644 --- a/QuickDraw/Pictures.a +++ b/QuickDraw/Pictures.a @@ -860,77 +860,6 @@ KillPicture PROC EXPORT _DisposHandle ;discard it JMP (A1) ;and return -;-----------------------Calc GCD --------------------- -CalcGCD PROC EXPORT -; Routine returns GCD( d0, d1 ) using Euclidean method -; On Entry: D0 and D1 contain word size values to reduce -; On Exit: D0 and D1 both contain GCD -; - cmp.l d0,d1 ;while d0 != d1 (unsigned word compare) - beq.s @FoundGCD - bgt.s @D1isBigger ; if( d1 < d0 ) - exg d0,d1 ; swap( d1, d0 ) -@D1isBigger - sub d0,d1 ; d1 = d1 - d0 - bra.s CalcGCD ;end while -@FoundGCD - rts ;d0 and d1 contain GCD - ENDPROC - -ReduceD3D4 PROC EXPORT - IMPORT CalcGCD -; Routine returns ReduceD3D4( d3, d4 ) reduces d3.w and d4.w by GCD for -; both the low and high words -; -; On Entry: D3 and D4 contain two word size values to reduce -; On Exit: D3 and D4 contain reduced values -; -; -; Divide Numer and Denom for width and height by GCD to prevent overflow. -; - moveq #0,d0 ;make sure high word is zero for next 2 divides - move.l d0,d1 ;CalcGCD exchanges regs, so both need to be cleared - move.w d3,d0 ;D0 has denom.v, d1 has numer.v - beq.s @Done ;abort if zero. - move.w d4,d1 ;D0 has denom.v, d1 has numer.v - beq.s @Done ;abort if zero. - jsr CalcGCD ;returns GCD in d0 - move.w d3,d1 ;D0 has denom.v, d1 has numer.v - divu.w d0,d1 ;dividing by GCD should never leave remainder - move.w d1,d3 ;save reduced numer.v - move.w d4,d1 ;D0 has denom.v, d1 has numer.v - divu.w d0,d1 - move.w d1,d4 ;save reduced denom.v -; -; Now do width: Could have different scale factor than height did -; - swap d3 ;operate on high word - swap d4 - move.w d3,d0 ;D0 has denom.h, d1 has numer.h - beq.s @DoneSwap ;abort if zero. - move.w d4,d1 ;D0 has denom.h, d1 has numer.h - beq.s @DoneSwap ;abort if zero. - jsr CalcGCD ;returns GCD in d0 - move.w d3,d1 ;D0 has denom.h, d1 has numer.h - divu.w d0,d1 ;dividing by GCD should never leave remainder - move.w d1,d3 ;save reduced numer.h - move.w d4,d1 ;D0 has denom.h, d1 has numer.h - divu.w d0,d1 - move.w d1,d4 ;save reduced denom.h -@DoneSwap - swap d3 ;put things back - swap d4 -@Done - rts ;all done -; -; End -; - ENDPROC - -;-----------------------END GCD --------------------- - -; as seen in QDciPatchROM.a stb - DrawPicture PROC EXPORT IMPORT PicItem1,NewRgn,InitColorStuff,ReduceD3D4 ;------------------------------------------------------------------ @@ -4316,7 +4245,7 @@ MORE1 MOVE.L A3,A0 ;PTR TO FIRST byte of src move.l d5,d0 ;get rowbytes in d0 - _BlockMove ;copy from there to here + _BlockMoveData ;copy from there to here ;assumes here is a 24 bit address moveq #false32b,d0 ;switch back before calling PutPicProc @@ -4339,47 +4268,6 @@ DONE MOVE.L SAVEDSP(A6),SP ;RESTORE STACK POINTER ; -PutBigPicData PROC EXPORT ;17Jun88 BAL -;------------------------------------------------------ -; -; PROCEDURE PutBigPicData(dataPtr: QDPtr; byteCount:LONG); -; ADD many BYTES TO THEPIC. -; -; This is the same as PutPicData except the byteCount is a long -; -partSize EQU $4000 -partShift EQU $E - - MOVEM.L D7/A3-A4,-(SP) ;save a couple of registers - - MOVE.L 20(SP),A3 ;get the pointer to data - MOVE.L 16(SP),A4 ;get data length - MOVE.L A4,D7 ;copy pointer - MOVEQ #partShift,D0 ;get a constant for the upcoming shift - LSR.L D0,D7 ;find the number of 16K "pages" - BEQ.S LeftOvers ;no, so do the remaining part of the picture - -@1 - MOVE.L A3,-(SP) ;PUSH DATA POINTER - MOVE #partSize,-(SP) ;move 16K of data - JSR PutPicData ;AND CALL GET PROC - ADD.W #partSize,A3 ;move data start pointer up - SUB.W #partSize,A4 ;subtract for remainder later - SUBQ.L #1,D7 ;decrease the number of pages - BNE.S @1 ;loop for each page - -LeftOvers - MOVE.L A3,-(SP) ;PUSH DATA POINTER - MOVE.W A4,-(SP) ;move remainder - JSR PutPicData ;AND CALL GET PROC - - MOVEM.L (SP)+,D7/A2-A4 ;restore registers - RTD #8 ;and return - -; -;GetPMData now included in GetPMData.a -; - PutPMData PROC EXPORT IMPORT PutPicByte,PutPicWord,PutPicData ;------------------------------------------------------ @@ -4956,53 +4844,6 @@ MapRect PROC EXPORT BRA MAPPT ;MAP BOTRIGHT AND RETURN -MapRatio PROC EXPORT -;------------------------------------------------------------- -; -; PROCEDURE MapRatio(VAR numer, denom: Point; fromRect: Rect); -; -; Map ratio so that denom.h/.v = height/width of fromRect. -; This is so that later scaling of the numerator will have some -; range to work within. -; -; NOTE: Only necessary because fractional numer, denom not used -; -; numer.h := numer.h * fromWidth / denom.h -; denom.h := fromWidth -; numer.v := numer.v * fromHeight / denom.v -; denom.v := fromHeight - -PARAMSIZE EQU 12 ; TOTAL BYTES OF PARAMS -NUMER EQU PARAMSIZE+8-4 ; LONG, ADDR OF POINT -DENOM EQU NUMER-4 ; LONG, ADDR OF POINT -FROMRECT EQU DENOM-4 ; LONG, ADDR OF RECT - - LINK A6,#0 ; NO LOCALS - MOVEM.L D0-D1/A0-A2,-(SP) ; SAVE REGS - MOVE.L NUMER(A6),A0 ; point to numer - MOVE.L DENOM(A6),A1 ; point to denom - MOVE.L FROMRECT(A6),A2 ; point to fromRect - - MOVE.W right(A2),D0 ; get fromRect right - SUB.W left(A2),D0 ; get fromWidth - MOVE.W h(A0),D1 ; get numer.h - MULU D0,D1 ; multiply by fromWidth - DIVU h(A1),D1 ; divide by denom.h - MOVE.W D1,h(A0) ; update numer.h - MOVE.W D0,h(A1) ; update denom.h - - MOVE.W bottom(A2),D0 ; get fromRect bottom - SUB.W top(A2),D0 ; get fromHeight - MOVE.W v(A0),D1 ; get numer.v - MULU D0,D1 ; multiply by fromHeight - DIVU v(A1),D1 ; divide by denom.v - MOVE.W D1,v(A0) ; update numer.v - MOVE.W D0,v(A1) ; update denom.v - -DONE MOVEM.L (SP)+,D0-D1/A0-A2 ; RESTORE REGS - UNLINK PARAMSIZE,'MAPRATIO' - - ENDPROC diff --git a/QuickDraw/QDExtensions2.a b/QuickDraw/QDExtensions2.a new file mode 100644 index 0000000..1f0dc78 --- /dev/null +++ b/QuickDraw/QDExtensions2.a @@ -0,0 +1,44 @@ +QDEXTENSIONS2 PROC EXPORT + + + cmp #10,D0 + bhi @bad_selector + jmp @jmptbl(D0.W * 4) + + +@jmptbl + import QDEXTENSIONS2_SELECTOR_0 + jmp QDEXTENSIONS2_SELECTOR_0 + import QDEXTENSIONS2_SELECTOR_1 + jmp QDEXTENSIONS2_SELECTOR_1 + import QDEXTENSIONS2_SELECTOR_2 + jmp QDEXTENSIONS2_SELECTOR_2 + import QDEXTENSIONS2_SELECTOR_3 + jmp QDEXTENSIONS2_SELECTOR_3 + import QDEXTENSIONS2_SELECTOR_4 + jmp QDEXTENSIONS2_SELECTOR_4 + import QDEXTENSIONS2_SELECTOR_5 + jmp QDEXTENSIONS2_SELECTOR_5 + import QDEXTENSIONS2_SELECTOR_6 + jmp QDEXTENSIONS2_SELECTOR_6 + import QDEXTENSIONS2_SELECTOR_7 + jmp QDEXTENSIONS2_SELECTOR_7 + import QDEXTENSIONS2_SELECTOR_8 + jmp QDEXTENSIONS2_SELECTOR_8 + import QDEXTENSIONS2_SELECTOR_9 + jmp QDEXTENSIONS2_SELECTOR_9 + import QDEXTENSIONS2_SELECTOR_10 + jmp QDEXTENSIONS2_SELECTOR_10 + + +@bad_selector + ; The upper half of D0 contains the number of bytes of parameters + ; on the stack + + move.l (SP)+,A0 + swap D0 + ext.l D0 + add.l D0,SP + move #paramErr,D0 + move D0,QDErr + jmp (A0) diff --git a/QuickDraw/QDUtil.a b/QuickDraw/QDUtil.a index 775369f..2431604 100644 --- a/QuickDraw/QDUtil.a +++ b/QuickDraw/QDUtil.a @@ -1389,7 +1389,7 @@ GETPIXEL MOVEQ #0,D2 ;ROUTINE = GETPIXEL SHARE LINK A6,#VARSIZE ;ALLOCATE STACKFRAME - MOVEM.L D4-D5/A2-A3,-(SP) ;SAVE WORK REGISTERS + MOVEM.L D4-D6/A2-A3,-(SP) ;SAVE WORK REGISTERS MOVE.L THEGDEVICE,-(SP) ;SAVE CURRENT GRAFDEVICE MOVE.L GRAFGLOBALS(A5),A0 ;POINT TO QUICKDRAW GLOBALS MOVE.L THEPORT(A0),A0 ;GET THEPORT @@ -1420,8 +1420,15 @@ OLDRB MOVE VLOC(A6),D4 ;GET VERTICAL MOVE D4,-(SP) ;PUSH GLOBAL TOP MOVE D5,-(SP) ;PUSH GLOBAL RIGHT MOVE D4,-(SP) ;PUSH GLOBAL BOTTOM - MOVE.L JShieldCursor,A1 ;get lo mem vector - JSR (A1) ;and call it + + MOVE.L SP,A0 + CLR.L -(SP) + MOVE.L A0,-(SP) + CLR.L -(SP) + MOVE.L #$80000,D0 + DC.W $ABE0 ;_QDExtensions2 + MOVE.L (SP)+,D6 + ADDQ #8,SP MOVE.L DEVICELIST,A3 ;GET FIRST IN DEVICE LIST @@ -1518,9 +1525,11 @@ NOCOLOR cmp.w #16,pixelType(a3) ;direct device? DONE tst.b (sp)+ ;pop and check crsrFlag beq.s @noShow ;need to show cursor? - _SHOWCURSOR ;show it + move.l D6,-(SP) + move.l #$40001,D0 + dc.w $ABE0 ;_QDExtensions2 @noShow MOVE.L (SP)+,THEGDEVICE ;RESTORE CURRENT GRAFDEVICE - MOVEM.L (SP)+,D4-D5/A2-A3 ;RESTORE WORK REGISTERS + MOVEM.L (SP)+,D4-D6/A2-A3 ;RESTORE WORK REGISTERS UNLINK PARAMSIZE,'GETCPIXEL' @@ -4722,7 +4731,7 @@ DSTH EQU SRCH-4 MOVE.L (A0),A0 ; get SRC pointer MOVE.L (A1),A1 ; get DST pointer MOVE.L D1,D0 ; D0 = size - _BlockMove ; copy the data + _BlockMoveData ; copy the data DONE MOVE.L (SP)+,A0 ; get return address ADDQ #8,SP ; strip parameters diff --git a/QuickDraw/ScaleBlt.a b/QuickDraw/ScaleBlt.a index 31ea259..24376e1 100644 --- a/QuickDraw/ScaleBlt.a +++ b/QuickDraw/ScaleBlt.a @@ -127,7 +127,7 @@ multColor EQU RGNC-2 ;byte, set if source contains nonblack/white colors ; _StackAvail ;GET STACK AVAIL IN D0.L LSR.L #2,D0 ;CONVERT BYTES TO LONGS - SUB.L #qdStackXtra,D0 ;SUBTRACT SLOP FACTOR <1.2> BAL + SUB.L #$200,D0 ;SUBTRACT SLOP FACTOR <1.2> BAL MOVE.L D0,STACKFREE(A6) ;AND SAVE FREE LONGS ON STACK bpl.s @stkOK _stNoStack ;=>NOT ENOUGH STACK, QUIT diff --git a/QuickDraw/Stretch.a b/QuickDraw/Stretch.a index b9dc7ac..bae0b7a 100644 --- a/QuickDraw/Stretch.a +++ b/QuickDraw/Stretch.a @@ -9589,32 +9589,107 @@ Scale32to16 PROC EXPORT ; CLOBBERS A0-A1/D0-D5 ; + tst.b -$a5(a6) + bne.s @different_implementation + + lea @sexy_code,a4 + move.l a4,-$228(a6) + +@sexy_code move.l a2,d2 ;get ptr to end sub.l a1,d2 ;sub ptr to beginning lsr.l #2,d2 ;get long cnt in d1 subq #1,d2 ;make zero based + move.l #$7fff7fff,d3 + @NXTSLNG MOVE.L (A0)+,D0 ;GET NEXT LONG OF SRC - ror.l #8,d0 - lsr.w #3,d0 - ror.l #5,d0 - lsr.w #3,d0 - ror.l #6,d0 ;16 bit pixel in high word + lsr.l #3,d0 + lsl.b #3,d0 + lsl #3,d0 + lsr.l #6,d0 + swap d0 MOVE.L (A0)+,D1 ;GET NEXT LONG OF SRC - ror.l #8,d1 - lsr.w #3,d1 - ror.l #5,d1 - lsr.w #3,d1 - ror.l #6,d1 ;16 bit pixel in high word + lsr.l #3,d1 + lsl.b #3,d1 + lsl #3,d1 + lsr.l #6,d1 - swap d1 ;merge pixels move.w d1,d0 + and.l d3,d0 move.l d0,(a1)+ ;write out 2 pixels dbra d2,@NXTSLNG ;loop for all longs in dst scanline RTS +@different_implementation + clr.b -$2a9(a6) + lea @sexy_code_2,a4 + move.l a4,-$228(a6) + +@sexy_code_2 + move.l a2,d2 + sub.l a1,d2 + lsr.l #2,d2 + subq #1,d2 + moveq.l #3,d0 + and.b -$2a9(a6),d0 + move.l @data_tbl(d0.w*4),d3 + addq.b #1,-$2a9(a6) + +@loop + moveq.l #0,d1 + move.l (a0)+,d0 + swap d0 + add.b d3,d0 + scs.b d1 + or.b d0,d1 + lsl.l #5,d1 + swap d0 + move.b d0,d4 + lsr #8,d0 + add.b d3,d0 + scs.b d1 + or.b d0,d1 + lsl.l #5,d1 + add.b d3,d4 + scs.b d1 + or.b d4,d1 + lsr.l #3,d1 + move d1,d5 + rol.l #8,d3 + swap d5 + moveq.l #0,d1 + move.l (a0)+,d0 + swap d0 + add.b d3,d0 + scs.b d1 + or.b d0,d1 + lsl.l #5,d1 + swap d0 + move.b d0,d4 + lsr #8,d0 + add.b d3,d0 + scs.b d1 + or.b d0,d1 + lsl.l #5,d1 + add.b d3,d4 + scs.b d1 + or.b d4,d1 + lsr.l #3,d1 + move d1,d5 + move.l d5,(a1)+ + rol.l #8,d3 + dbf d2,@loop + rts + +@data_tbl + dc.l $05010400 + dc.l $03070206 + dc.l $04000501 + dc.l $02060307 + ; from QDciPatchROM.a verbatim stb diff --git a/Tools/ToolSource/Vectorize.c b/Tools/ToolSource/Vectorize.c index 22bf22b..07714b9 100644 --- a/Tools/ToolSource/Vectorize.c +++ b/Tools/ToolSource/Vectorize.c @@ -687,6 +687,7 @@ int main(int argc, char **argv) my_name = patchstack[pi]->name; original_size = longfrom(mod_sizeobj + 2); + if(original_size & 1) original_size ++; /* even-align the patches -- found this bug while reversing QuickDraw */ if(l) fprintf(l, " File \"{RomDump}\"; Line 0; File \"{RomDump}\"; Find /Entry=¶\"%.*s¶\"/ # patch ID %d, ", *my_name, my_name+1, patchstack[pi]->clean_id); if(l) debug_print_about_patch(l, patchstack[pi]->data, patchstack[pi]->len);