;__________________________________________________________________________________________________ ; File: GDevice.a ; ; Contains: QuickDraw routines that manage GDevices ; ; Written by: Various Authors ; ; Copyright: © 1981-1993 by Apple Computer, Inc., all rights reserved. ; ; Change History (most recent first): ; ; 10-19-93 jmp Changed NewGDevice so it more intelligently handles mono-only ; devices. ; 4/8/93 IH Add some comments on Display Manager assumptions about ; InitGDevice to InitGDevice header. ; 2/4/93 CSS Update from Horror: ;

7/10/92 SWC Made a change to GetDevPixMap to fix a problem with fixed ; devices. It was generating a new ctSeed unconditionally, which ; caused problems with the IconUtilities package since the Palette ; Manager would say that the tolerance between the device's and ; system CLUTs wasn't close enough to draw a multi-bit icon. ; 6/11/92 stb stb Synched with QDciPatchROM.a, added comments to ; DisposGDevice and InitGDevice. ; <8> 7/24/90 gbm get rid of stupid branch ; <7> 2/20/90 BAL When disposing the LastTxGDevice, reset it to the MainDevice. ; <6> 2/1/90 DAF Add AllocCrsr before ShowCursor in CheckDevices (called from ; InitGraf). Changed ShieldCursor to HideCursor in InitGDevice. ; This is consistent with the CheckDevicesINIT.a. ; <5> 1/29/90 DVB Dont walk nonexistant portlist ; <4> 1/17/90 DVB Touch-up to InitGDevice ; <3> 1/12/90 DVB More InitGDevice ; <2> 1/8/90 DVB Make InitGDevice safer and smarter about changing baseAddr's ; <2.6> 9/25/89 BAL Defered InitGDevices paletteMgr notify until after the GDRect is ; valid. ; <¥2.5> 7/14/89 BAL For Aurora: Final CQD ; <2.4> 7/13/89 DAF FOR AURORA BUILD - Two fixes: 1) corrected startup gamma tables ; from scrn resource in CheckDevices; 2) rewrote fixed device ; color table handling in GetDevPixMap (fixes E-Machines Big ; Picture) ; <2.3> 7/6/89 GGD Changed the JSR OPENPIXMAP to a BSR.L so that it can reach when ; alignment is turned on. ; <2.2> 6/30/89 BAL Changed source to use mainScreen instead of mainScrn ; <2.1> 6/12/89 BAL Altered InitGDevice to not request grayscale versions for 1 and ; 2 bit modes. ; <2.0> 6/10/89 CEL Moved Private.a QuickDraw Equates into proper QuickDraw private ; file (colorequ.a), got rid of QuickDraw nFiles dependencies and ; fixed up necessary filesÉ ; <1.9> 5/30/89 DAF Fixed gdpMap rect offsets when then scrn resource is bad ; <¥1.8> 5/29/89 BAL Blasting in 32-Bit QuickDraw version 1.0 Final ; <¥1.7> 4/12/89 BAL Blasting in 32-Bit QuickDraw 1.0B1 ; 4/5/89 DAF Added more validity checking of scrn resource in CheckDevices ; (compares scrnRects,too). If scrn resource is invalid, then ; offset all inactive screens from (0,0) to help out people who ; forget to check scrnActive. ; 4/3/89 DAF Updated InitGDevice to set driver luminence mapping even if ; pixel depth doesn't change. ; 3/26/89 DAF Added linear gamma support from scrn resource; reordered ; CheckDevices; integrated CheckGray into CheckDevices; updated ; SetGray/getCTable support to the new world; plugged InitGDevice ; into Palette Manager; corrected fixed CLUT support in ; GetDevPixmap. ; 12/11/88 BAL Altered getDevPixMap to set high bit of pmVersion for 32 bit ; base addresses. ; 9/9/87 GWN 32-bit mode fix for Slot manager. Use DCE to get device base. ; 5/27/87 EHB Roll patch into CheckDevices to make sure color/gray is set. ; 2/2/87 JTC Change to new, word-length constants. ; 2/2/87 GWN Changed read of video parameters. ; 1/29/87 GWN Cleared spExtDev field where neccessary. ; 8/1/86 DAF InitGDevice to handle uninitialized theGDevice. ; 7/29/86 DAF Modified for color manager ; 5/8/86 EHB New Today ; ; To Do: ;__________________________________________________________________________________________________ ;EASE$$$ READ ONLY COPY of file Ògdevice.aÓ ; 2.6 BAL 09/25/1989 Defered InitGDevices paletteMgr notify until after the GDRect is valid. ;¥2.5 BAL 07/14/1989 For Aurora: Final CQD ; 2.4 DAF 07/13/1989 FOR AURORA BUILD - Two fixes: 1) corrected startup gamma ; tables from scrn resource in CheckDevices; 2) rewrote fixed device ; color table handling in GetDevPixMap (fixes E-Machines Big Picture) ; 2.3 GGD 07/06/1989 Changed the JSR OPENPIXMAP to a BSR.L so that it can reach when alignment ; is turned on. ; 2.2 BAL 06/30/1989 Changed source to use mainScreen instead of mainScrn ; 2.1 BAL 06/12/1989 Altered InitGDevice to not request grayscale versions for 1 and 2 bit modes. ; 2.0 CEL 06/10/1989 Moved Private.a QuickDraw Equates into proper QuickDraw ; private file (colorequ.a), got rid of QuickDraw nFiles dependencies ; and fixed up necessary filesÉ ; 1.9 DAF 05/30/1989 Fixed gdpMap rect offsets when then scrn resource is bad ;¥1.8 BAL 05/29/1989 Blasting in 32-Bit QuickDraw version 1.0 Final ;¥1.7 BAL 04/12/1989 Blasting in 32-Bit QuickDraw 1.0B1 ; File GDevice.a ; ; Copyright Apple Computer, Inc. 1981-1986 ; All Rights Reserved ; ; BLANKS ON STRING ASIS MACHINE MC68020 ;------------------------------------------------------ ; ; QuickDraw Routines to maintain the current grafDevice. ; ; MODIFICATION HISTORY ; ; 8May86 EHB New Today ; 29Jul86 DAF Modified for color manager ; DAF InitGDevice to handle uninitialized theGDevice. ; GWN Cleared spExtDev field where neccessary. ; JTC Change to new, word-length constants. ; GWN Changed read of video parameters. ; GWN 32-bit mode fix for Slot manager. Use DCE to get device base. ; ;---------------------------- Macintosh II ROMs ----------------------------- ; ; 27May87 EHB Roll patch into CheckDevices to make sure color/gray is set. ; ;---------------------------- 32-bit QuickDraw ------------------------------ ; ; 11Dec88 BAL Altered getDevPixMap to set high bit of pmVersion for 32 bit base addresses. ; 26Mar89 DAF Added linear gamma support from scrn resource; reordered CheckDevices; ; integrated CheckGray into CheckDevices; updated SetGray/getCTable support ; to the new world; plugged InitGDevice into Palette Manager; corrected ; fixed CLUT support in GetDevPixmap. ; 3Apr89 DAF Updated InitGDevice to set driver luminence mapping even if pixel depth ; doesn't change. ; 5Apr89 DAF Added more validity checking of scrn resource in CheckDevices (compares ; scrnRects,too). If scrn resource is invalid, then offset all inactive ; screens from (0,0) to help out people who forget to check scrnActive. NewGDevice PROC EXPORT IMPORT INITGDEVICE,OPENPIXMAP,SetGDevice,DisposGDHandles ;------------------------------------------------------------- ; ; FUNCTION NewGDevice (refNum: INTEGER; mode: LONGINT) : GDHandle; ; ; Allocate a new GDevice and all its handles, then call InitGDevice ; to initialize it for the specified device in the specified mode. ; The grafDevice and its pixMap are always locked down. ; ; If a memory request is unsuccessful, then a NIL handle is returned ; ; NOTE: Assumes that the driver has already been opened (it has a ; REFNUM and a DCE). ; PARAMSIZE EQU 6 ; total bytes of parameters RESULT EQU PARAMSIZE+8 ; LONG, GrafDevice REFNUM EQU RESULT-2 ; WORD, Driver reference number MODE EQU REFNUM-4 ; LONG, Mode for video card LINK A6,#0 ; no locals MOVEM.L A2/A3,-(SP) ; preserve work registers CLR.L RESULT(A6) ; indicate failure MOVE.L theZone,-(SP) ; save the current heap zone MOVE.L sysZone,theZone ; and get the system heap MOVEQ #GDRec,D0 ; get size of graf device record _RESRVMEM ; reserve space for it down low BNE NOMEM ; => couldn't get it MOVEQ #GDRec,D0 ; get size of graf device record _NEWHANDLE ,CLEAR ; allocate the handle _HLOCK ; and lock it MOVE.L A0,A2 ; A2 = graf device handle MOVE.L (A2),A3 ; A3 = graf device pointer MOVEQ #2,D0 ; initial size of inverse table _NEWHANDLE ,CLEAR ; get a handle for the inverse table ; allocated in system heap BNE NOMEM ; => couldn't get it MOVE.L A0,GDITable(A3) ; save handle to inverse table MOVEQ #2,D0 ; initial size of expanded cursor data _NEWHANDLE ,CLEAR ; get a handle for expanded cursor data ; allocated in system heap BNE.S NOMEM ; => couldn't get it MOVE.L A0,GDCCXDATA(A3) ; save handle to expanded cursor data MOVEQ #2,D0 ; initial size of expanded cursor mask _NEWHANDLE ,CLEAR ; get a handle for the expanded cursor mask ; allocated in system heap BNE.S NOMEM ; => couldn't get it MOVE.L A0,GDCCXMASK(A3) ; save handle to expanded cursor mask MOVEQ #CCSaveRec,D0 ; get size needed by openPixMap _ResrvMem ; reserve space down low BNE.S NOMEM ; => couldn't get it CLR.L -(SP) ; make room for function result BSR.L OPENPIXMAP ; get an uninitialize pixMap in sysHeap <2.3> MOVE.L (SP),GDPMap(A3) ; save pixel Map MOVE.L (SP)+,A0 ; get handle to pixMap _HLock ; and lock it down MOVE.L MODE(A6),D0 ; get the mode 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 @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 DONE MOVE.L (SP)+,theZone ; restore the zone MOVE.L A2,RESULT(A6) ; return graf device handle MOVEM.L (SP)+,A2/A3 ; restore work register UNLINK PARAMSIZE,'NEWGDEVI' NOMEM MOVE.L A2,-(SP) ; push grafDevice JSR DisposGDHandles ; and dispose of its handles BRA.S DONE ; => and return ; ; Ever since the first Edition of Cards & Drivers, the video driver call SetGray has been ; documented. This routine takes a byte (0=color, non-zero=gray), and tells the video ; driver to put itself into luminence mapping mode (gray) or not. This call has been ; defined as Òoptional,Ó so some video drivers may exclude it. Nevertheless, by using ; this call we can make a fairly intelligent guess as to whether to leave a multibit ; GDevice mono or not. Indeed, if we attempt to call SetGray(0), and we get back a non-zero, ; value, then we should leave the GDevice mono. All Apple video drivers have done this with ; their monochrome-only displays. ; With VDPageInfo TestForGray @SaveEm Reg A0-A1/D0 ; Movem.l @SaveEm,-(Sp) ; Borrow a few registers for a while. Suba.w #ioQElSize,Sp ; Allocate an I/O param block on the stack. Movea.l Sp,A0 ; Point to it. Subq #4,Sp ; Allocate a CS param block on the stack. Movea.l Sp,A1 ; Point to it. Clr.b csMode(A1) ; Say that we want mapping off. ; Set up for the Control call: Move.w RefNum(A6),ioRefNum(A0) ; ioRefNum, Move.w #cscSetGray,csCode(A0) ; csCode, Move.l A1,csParam(A0) ; csParam. _Control ,Immed ; SetGray. Bne.s @Error ; If failed, then just leave. Tst.b csMode(A1) ; Otherwise, see if we got back what we set. Bra.s @Done ; @Error Moveq #0,D0 ; Just set up to leave things alone. @Done Adda.w #ioQElSize+4,Sp ; Restore the stack space we used. Movem.l (Sp)+,@SaveEm ; Restore the regs we borrowed. Rts ; Vamoose. Endwith DisposGDevice PROC EXPORT EXPORT DisposGDHandles ;------------------------------------------------------------- ; ; PROCEDURE DisposGDevice (GDH: GDHandle); ; ; disposes of the gDevice record and its handles ; MOVE.L (SP)+,A1 ; get return address MOVE.L (SP),-(SP) ; push the grafDevice BSR.S DisposGDHandles ; and dispose of its handles ; as seen in QDciPatchROM.a stb MOVE.L (SP)+,A0 ; get the grafDevice cmp.l LastTxGDevice,A0 ; are we disposing it? bne.s @noProb ; no, continue move.l MainDevice,LastTxGDevice ; yes, reset it. @noProb ; _DisposHandle ; dispose of it JMP (A1) ; and exit DisposGDHandles MOVE.L A1,-(SP) ; save A1 MOVE.L 8(SP),A1 ; get handle to GDevice MOVE.L (A1),A1 ; point to GDevice MOVE.L GDPMap(A1),-(SP) ; push pixMap handle MOVE.L GDITable(A1),D0 ; get inverse table BEQ.S @0 ; => none MOVE.L D0,A0 ; else get it _DisposHandle ; and dispose it @0 MOVE.L GDCCXData(A1),D0 ; get cursor data BEQ.S @1 ; => none MOVE.L D0,A0 ; else get it _DisposHandle ; and dispose it @1 MOVE.L GDCCXMask(A1),D0 ; get cursor mask BEQ.S @2 ; => none MOVE.L D0,A0 ; else get it _DisposHandle ; and dispose it @2 MOVE.L (SP)+,D0 ; get pixMap handle BEQ.S @3 ; => it's not there MOVE.L D0,-(SP) ; else push it again _DisposPixMap ; and dispose of the pixMap @3 MOVE.L (SP)+,A1 ; restore A1 MOVE.L (SP)+,(SP) ; strip parameter RTS ; and return ; as seen in QDciPatchROM.a verbatim stb InitGDevice PROC EXPORT WITH VDPageInfo ;<1.1> IMPORT OneBitData,GetDevPixMap ;------------------------------------------------------------- ; ; PROCEDURE InitGDevice (refNum: INTEGER; mode: LONGINT; GDH: GDHandle); ; ; Initialize the specified device to the specified mode. The GDevice ; data is placed into the provided handle. ; ; If mode = -1 then the driver is not called. It is assumed that the pixmap ; has been set up before InitGDevice is called. ; ; Now has support for GDevices with baseAddrs that change across depths ; (Trident card) in a MultiFinder-friendly way. ; ; CAUTION: this routine is used during ROM boot; various Macintosh functions ; may not yet be available! ; ; CAUTION: Display Manager counts on the way some of the flags are used. Do ; not change without testing the resolution flipping in display manager. ; ; Are there patch implications (especially for the mainScreen flag) that ; mean I should handle this in a different way? Are there patches that count ; on these flags? Here are the flags Display Manager changes: ; ; ramInit -- Display Manager clears ramInit bit so rect will be fetched from the video card. ; gdMode -- Display Manager clears. When switching to a different resolution the enabled ; functional sResource has changed, however the spID is frequently the same for the ; same depth. By clearing gdMode, we know that InitGDevice will not bail because ; it thinks the modes are the same. ; mainScreen -- Display Manager clears mainScreen bit because it does not want InitGDevice to ; mess with the ports. Display Manager has more things to do to the ports (at a higher ; level) than it would be appropriate to do here. Some day we may roll in here, but ; for now I clear this bit to make sure InitGDevice does not try to fix ports. ; IGDVars RECORD {A6Link},DECREMENT result DS.B 0 ; no result REFNUM DS.B 2 MODE DS.B 4 ; LONG, mode for video card GDH DS.B 4 ; LONG, handle to devPort return DS.B 4 ; the return address A6Link DS.B 4 ; our link IOPBlk DS.B IOVQElSize ; [64] parameter blk for I/O calls VidParms DS.B 12 ; [12] size of mode params GDHState DS.B 2 ; [word] lock state of GDH GDPState DS.B 2 ; [word] lock state of GDP SaveDevice DS.B 4 ; [long] saved device handle 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 VARSIZE DS.B 0 ; size of locals ENDR WITH IGDVars LINK A6,#VARSIZE ; allocate stack frame MOVEM.L D3/A2-A4,-(SP) ; save off work registers MOVE.L GDH(A6),A0 ; get the gDevice handle _HGetState ; get the current lock state MOVE D0,GDHState(A6) ; save the state _HLOCK ; and lock down the gDevice MOVE.L (A0),A2 ; get pointer to gDevice record MOVE.L GDPMap(A2),A0 ; get handle to pixMap MOVE.L (A0),A1 ; A1->pixmap MOVE.L baseAddr(A1),oldBaseAddr(A6) ; save the base address, for later portfixing _HGetState ; get the current lock state of the pixmap MOVE D0,GDPState(A6) ; save the state _HLOCK ; lock it down MOVE.L (A0),A3 ; keep pointer in A3 MOVE.L theGDevice,SaveDevice(A6) ; save theGDevice TST.B QDExist ; qd around? 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 @noShield ; initialize the GDevice's mode and refnum MOVE REFNUM(A6),GDRefNum(A2) ; set up RefNum MOVE.L MODE(A6),D0 ; get the mode CMP.L MinusOne,D0 ; is the mode -1? BEQ ModeOK ; if so, then don't call the driver ; set up the driver parameter block in case we need to use it LEA IOPBlk(A6),A0 ; point to parameter block CLR.L ioCompletion(A0) ; no completion routine CLR.W ioVRefNum(A0) ; no volRefNum MOVE RefNum(A6),ioRefNum(A0) ; set device's refnum LEA VidParms(A6),A1 ; point to params for GetMode 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 MOVE.L D0,GDMode(A2) ; set up mode ; setup the gDevice fields for the new screen depth CLR GDCCDepth(A2) ; invalidate cursor depth MOVEM.L A0/A1,-(SP) ; save these regs MOVE REFNUM(A6),-(SP) ; push refnum MOVE.L MODE(A6),-(SP) ; push mode MOVE.L GDPMap(A2),-(SP) ; pixMap handle PEA GDType(A2) ; point to device type JSR GetDevPixMap ; read in pixMap from device MOVEM.L (SP)+,A0/A1 ; restore them ; first, set the mode (A0 points to IOPB, A1 to control parameter block) MOVE #2,csCode(A0) ; csc_GetMode MOVE.L mode(A6),D0 ; get the mode MOVE D0,csMode(A1) ; set desired mode CLR csPage(A1) ; set page 1 CLR.L csData(A1) ; no additional data _Control ,IMMED ; SetMode(Mode,Page,Data); ; then gray the screen MOVE #5,csCode(A0) ; csc_GrayPage _Control ,IMMED ; paint current page gray ; set the device to color or monochrome, according to GDFlags GrayOrColor MOVE GDFlags(A2),D0 ; get flags word NOT D0 ; flip all bits AND #1,D0 ; clear all but low bit MOVE.B D0,csMode(A1) ; csMode = color/gray scale MOVE #6,csCode(A0) ; csc_SetGray _Control ,IMMED ; set color or monochrome ; if the device has a color table, set the device's color table CMP #ClutType,GDType(A2) ; is there a lookup table? BNE.S NoTbl ; =>no, don't set one MOVE.L pmTable(A3),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.W #3,csCode(A0) ; csc_SetEntries MOVE.L A1,csParam(A0) ; move addr of parms into block _Control ,IMMED ; SetEntries(ColorTable); MOVE.L pmTable(A3),A0 ; get handle to color table _HUnlock ; unlock the color table NoTbl ; if CLUT or fixed color table, build inverse table CMP #DirectType,GDType(A2) ; should there be an inverse table? BEQ.S ModeOK ; =>no inverse table MOVE.L pmTable(A3),-(SP) ; push color table handle MOVE.L GDITable(A2),-(SP) ; push inverse table handle 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 ; 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 _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 (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 _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 (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 _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 _SetPort MOVE.L oldBaseAddr(A6),D1 CMP.L scrnBase,D1 ; fix scrnBase too, if neede BNE.S @notMain MOVE.L baseAddr(A3),scrnBase @notMain _AllocCursor _ShowCursor @noQD ; ; notify the Palette Manager that the mode has changed ; ; <2.6> moved after GDRect has been adjusted <2.6> CMP.L #-1,PMgrHandle ; has the Palette Mgr been initialized? BEQ.S @noPMgr ; nope, so skip this MOVE.L GDH(A6),-(SP) ; push the device handle _RestoreDeviceClut ; call the Palette Manager Unhook device vector @noPMgr MOVE.L SaveDevice(A6),theGDevice ; restore theGDevice MOVE.L GDPMap(A2),A0 ; get pixMap handle MOVE GDPState(A6),D0 ; get the lock state _HSetState ; restore prior state MOVE.L GDH(A6),A0 ; get the gDevice handle MOVE GDHState(A6),D0 ; get the lock state _HSetState ; restore prior state MOVEM.L (SP)+,D3/A2-A4 ; restore work registers UNLINK result-return-4,'INITGDEV' GetDevPixMap PROC EXPORT IMPORT CopyHandle, GetCTSeed, RSetHSize ;---------------------------------------------------------------- ; ; PROCEDURE GetDevPixMap(refNum: INTEGER; mode: LONGINT; PMH: PixMapHandle;VAR DevType:INTEGER); ; ; Calls the slot Manager to fill out the pixMap with info from the specified ; mode of the specified device. The device need not be configured to that ; mode. ; ; GetDevPixMap is called by InitGDevice. ; ;---------------------------------------------------------------- PARAMSIZE EQU 14 ; total bytes of parameters REFNUM EQU PARAMSIZE+8-2 ; WORD, Driver reference number MODE EQU REFNUM-4 ; LONG, Mode for video card PMH EQU MODE-4 ; LONG, PixMap Handle 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 WITH spBlock,vpBlock ; LINK A6,#VARSIZE ; allocate stack frame MOVEM.L D3-D5/A2-A4,-(SP) ; preserve work registers ; lock down the pixMap and get pointer in A2 MOVE.L PMH(A6),A0 ; get handle to pixMap _HGetState ; get the current state MOVE D0,PMHState(A6) ; save current state _HLock ; lock it down MOVE.L (A0),A2 ; get pointer in A2 ; look in the unit table for the specified device MOVE REFNUM(A6),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 ; get the resource list for the specified device LEA MYBLOCK(A6),A0 ; point to parameter block MOVE.B dCtlSlot(A1),spSlot(A0) ; get slot number MOVE.B dCtlSlotID(A1),spID(A0) ; get ID MOVE.B dCtlExtDev(A1),spExtDev(A0) ; External Device ID _sRsrcInfo ; get a pointer to the sResource list. BNE BadSlot ; => something wrong ; BaseAddr := dctlDevBase + MBaseOffset(Added later) MOVE.L dCtlDevBase(A1),D3 ; Get the 24-bit base address. MOVE.L MODE(A6),D0 ; get the mode MOVE.B D0,spId(A0) ; pass the requested mode _sFindStruct ; get pointer to list for that mode BNE BadSlot ; => something wrong MOVE.L spsPointer(A0),A4 ; A4 = pointer to list for that mode ; get devType MOVE #CLUTType,D4 ; assume device type = CLUT MOVE.B #mDevType,spId(A0) ; device type _sReadWord ; go read it BNE.S @CLUT ; => if none, assume CLUT MOVE spResult+2(A0),D4 ; get device type @CLUT MOVE.L DEVTYPE(A6),A1 ; get pointer to device type MOVE D4,(A1) ; return device type ; get video parameter sBlock and save values as needed MOVE.B #mVidParams,spId(A0) ; get the parameters _sGetBlock ; (in sBlock form) BNE BadSlot ; => something wrong MOVE.L spResult(A0),A1 ; save the pointer to the block ADD.L vpBaseOffset(A1),D3 ; calculate baseAddr MOVE.L D3,(A2)+ ; save baseAddr ; get rowbytes, bounds, and version. MOVE.W vpRowBytes(A1),D0 ; Number of bytes between scan lines. OR #PMFlag,D0 ; set pixMap flag MOVE D0,(A2)+ ; save rowbytes MOVE.L vpBounds(A1),(A2)+ ; read into our bounds MOVE.L vpBounds+4(A1),(A2)+ ; rect is eight bytes MOVE.W vpVersion(A1),(A2)+ ; pixMap version number if ADDRMODEFLAG then ; tst.w vpVersion(a1) ; is it standard? bne.s @useTheirs ; no, leave it alone move.w #fAddr32clean,-2(a2) ; yes, set 32 bit addressing flag @useTheirs endif ; clear packType, packSize fields CLR (A2)+ ; packType := 0 CLR.L (A2)+ ; packSize := 0 ; get hRes, vRes, pixelType, pixelSize, cmpType, cmpSize and planebytes. MOVE.L vpHRes(A1),(A2)+ ; horizontal resolution MOVE.L vpVRes(A1),(A2)+ ; vertical resolution MOVE.W vpPixelType(A1),(A2)+ ; the pixel type MOVE.W vpPixelSize(A1),D5 ; D5 = pixel size MOVE.W D5,(A2)+ ; the pixel size MOVE.W vpCmpCount(A1),(A2)+ ; the component count MOVE.W vpCmpSize(A1),(A2)+ ; the component size MOVE.L vpPlaneBytes(A1),(A2)+ ; offset from one plane to another ; dispose of the sBlock MOVE.L A1,spsPointer(A0) ; _sDisposePtr ; MOVE.L A4,spsPointer(A0) ; restore pointer to list ; use DevType to initialize the color table CMP #FixedType,D4 ; is it fixed? BEQ.S GetFromSlot ; =>yes, get from card CMP #CLUTType,D4 ; is it color lookup? BNE.S DirectCLUT ; =>no, must be direct; get unique seed ; Load in the color table and copy it to our handle. GetClut CLR.L -(SP) ; make room for function result MOVE D5,-(SP) ; push resource ID _GetCTable ; 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 BRA.S TableOK ; => and continue ; ; Read the color table from the ROM. This code is a little different than it's ancestor. <2.3> ; Rather than expecting a cSpecArray, this expects that mTable points to a color table ; image (including header). It's not bad to change this since there was a bug that ; prevented it from working at all before (spSize had been read as a word, rather than ; long, so it would never make the correct calculation). Get the fixed color table as ; a pointer, put in a new ctSeed, then make the pointer into a handle. ; GetFromSlot MOVE.B #mTable,spID(A0) ; the fixed table <2.3> _SReadPBSize ; find the table and get it's size <2.3> BNE.S GetClut ; => something wrong, use default table <2.3> SUB.L #4,spSize(A0) ; adjust for slot block header <2.3> MOVE.L spSize(A0),D0 ; get size of table <2.3> MOVE.L (A2),A0 ; get existing color table handle <2.3> _SetHandleSize ; set it to the new size <2.3> MOVE.L (A0),A1 ; deref handle <2.3> LEA MYBLOCK(A6),A0 ; point to parameter block MOVE.L A1,spResult(A0) ; put handle in destination <2.3> _sReadStruct ; read the table from the ROM <2.3> ;¥¥¥ CSS rollin patch GetDevPixMapPatch from horror MOVE.L ctSeed(A1),D0 ; get the current seed

BEQ.S @GetNewSeed ; -> it's zero, so generate a new one

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> 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. bra.s TableOK DirectCLUT ; Set up fake CLUT for direct devices MOVE.L PMH(A6),A0 ; get handle to pixMap move.l (a0),a0 ; get pixMap ptr move cmpSize(a0),d0 ; mulu cmpCount(a0),d0 ; compute seed value move.l pmTable(A0),a0 ; get clut handle move.l (a0),a0 ; clut ptr move.l d0,(a0) ; set up seed TableOK move.l (a2),a0 ; get pmTable move.l (a0),a0 ; get ptr to clut move.w #$8000,TransIndex(a0) ; set Device clut flag ADDQ #4,A2 ; skip over table CLR.L (A2)+ ; clear pmReserved ; Error, bad video card. BadSlot DONE MOVE.L PMH(A6),A0 ; get handle to pixMap MOVE PMHState(A6),D0 ; get prior state _HSetState ; restore lock state GOHOME MOVEM.L (SP)+,D3-D5/A2-A4 ; restore work registers UNLINK PARAMSIZE,'GETDEVPI' GoBadSlot ADDQ #4,SP ; strip pointer off stack BRA.S BadSlot ; and return with error ENDWITH CheckDevices PROC EXPORT WITH VDPageInfo ;<1.1> IMPORT CopyHandle ;---------------------------------------------------------- ; ; PROCEDURE CheckDevices; ; ; Look at the device list to see if it needs to be initialized. If so, read ; in the resource of type 'scrn'. If it is found, configure the devices as ; described in that resource. The format of the 'scrn' resource is: ; ; [count] ; [word] number of devices in resource ; FOR I := 1 TO COUNT DO ; [sResource Type] ; [word] spDrvrH of device n ; [slot] ; [word] slot number of device n ; [dCtlDevBase] ; [long] the dCtlDevBase of device n ; [mode] ; [word] the sRsrcID for the desired mode ; [flagMask] ; [word] masks off all bits used in flags ; [flags] ; [word] indicates the state of the device ; ; bit 0 = 0 if monochrome; 1 if color ; ; bit 11 = 1 if this device is main screen ; ; bit 15 = 1 if the screen is active ; [colorTable] ; [word] resource id of desired color table (-1=none) ; [gammaTable] ; [word] resource id of gamma table (-1=none) ; [global Rect] ; [rect] global rectangle for this device ; [CtlCount] ; [word] number of control calls following ; FOR J := 1 TO CtlCount DO ; [csCode] ; [word] control code for this call ; [length] ; [word] number of bytes in the param blk ; [param blk] ; [length] data to be passed in control call ; END; ; END; ; ; 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 ;------------------------------------------------------------- ; ; ROUTINES FOR ACCESSING THE DEVICE LIST ; GetGDevice PROC EXPORT ;---------------------------------------------------------- ; ; FUNCTION GetGDevice: GDHandle; ; ; Return the handle to the current device ; MOVE.L (SP)+,A0 ; get return address MOVE.L theGDevice,(SP) ; return device handle JMP (A0) ; and return SetGDevice PROC EXPORT ;---------------------------------------------------------- ; ; PROCEDURE SetGDevice (GDH: GDHandle); ; ; Set the device specifed in GDH to be the current device ; ; This routine needs to close the current video device if ; there is one, then it should open the new one. It should ; also call the device to let it set up anything it might ; need to set up (e.g. change the bottleneck procs). ; MOVE.L (SP)+,A0 ; get the return address MOVE.L (SP)+,theGDevice ; set the specified handle JMP (A0) ; and return GETDEVICELIST PROC EXPORT ;------------------------------------------------------------- ; ; FUNCTION GETDEVICELIST: GDHandle; ; ; RETURNS A HANDLE TO THE FIRST ELEMENT IN THE DEVICE LIST ; MOVE.L (SP)+,A0 ; GET RETURN ADDRESS MOVE.L DeviceList,(SP) ; RETURN DEVICE LIST JMP (A0) ; AND RETURN GETMAINDEVICE PROC EXPORT ;------------------------------------------------------------- ; ; FUNCTION GETMAINDEVICE: GDHandle; ; ; RETURNS A HANDLE TO THE MAIN SCREEN DEVICE ; MOVE.L (SP)+,A0 ; GET RETURN ADDRESS MOVE.L MainDevice,(SP) ; RETURN DEVICE LIST JMP (A0) ; AND RETURN GETNEXTDEVICE PROC EXPORT ;------------------------------------------------------------- ; ; FUNCTION GETNEXTDEVICE(GDH: GDHandle): GDHandle; ; ; RETURNS A HANDLE TO THE NEXT SCREEN DEVICE ; IF THERE IS NO NEXT DEVICE, RETURNS NIL ; MOVE.L (SP)+,A0 ; GET RETURN ADDRESS MOVE.L (SP)+,A1 ; GET GDH MOVE.L (A1),A1 ; POINT TO DEVICE MOVE.L GDNextGD(A1),(SP) ; RETURN NEXT DEVICE JMP (A0) ; AND RETURN TestDeviceAttribute PROC EXPORT ;------------------------------------------------------------- ; ; FUNCTION TestDeviceAttribute(GDH: GDHandle; attribute: INTEGER): BOOLEAN; ; ; Tests the specified attribute, returns TRUE if attribute is true ; MOVE.L (SP)+,A1 ; GET RETURN ADDRESS MOVE (SP)+,D0 ; GET ATTRIBUTE MOVE.L (SP)+,A0 ; GET GDH CLR.B (SP) ; ASSUME FALSE MOVE.L (A0),A0 ; POINT TO DEVICE MOVE GDFlags(A0),D1 ; GET FLAGS WORD BTST D0,D1 ; TEST ATTRIBUTE BEQ.S IsFalse ; => ATTRIBUTE NOT SET ADD.B #1,(SP) ; ELSE RETURN TRUE IsFalse JMP (A1) ; AND RETURN SetDeviceAttribute PROC EXPORT ;------------------------------------------------------------- ; ; PROCEDURE SetDeviceAttribute(GDH: GDHandle; attribute: INTEGER; state: Boolean); ; ; Sets the specified attribute to true or false ; MOVE.L (SP)+,A1 ; GET RETURN ADDRESS MOVE.B (SP)+,D0 ; GET BOOLEAN MOVE (SP)+,D1 ; GET ATTRIBUTE MOVE.L (SP)+,A0 ; GET GDH MOVE.L (A0),A0 ; POINT TO DEVICE MOVE GDFLAGS(A0),D2 ; GET FLAGS WORD TST.B D0 ; TEST BOOLEAN BNE.S SetIt ; =>SET FLAG BCLR D1,D2 ; CLEAR ATTRIBUTE BRA.S SDAShare ; RETURN VALUE AND RETURN SetIt BSET D1,D2 ; SET ATTRIBUTE SDAShare MOVE D2,GDFLAGS(A0) ; RETURN IT JMP (A1) ; AND RETURN GETMAXDEVICE PROC EXPORT ;------------------------------------------------------------- ; ; FUNCTION GETMAXDEVICE(r: Rect): GDHandle; ; ; RETURNS A HANDLE TO THE DEEPEST SCREEN DEVICE ; THAT INTERSECTS THE SPECIFIED GLOBAL RECTANGLE. ; PARAMSIZE EQU 4 ; TOTAL BYTES OF PARAMETERS RESULT EQU PARAMSIZE+8 ; LONG, GRAFDEVICE RECT EQU PARAMSIZE+8-4 ; LONG, ADDR OF GLOBAL RECTANGLE DSTRECT EQU -8 ; RECT, VAR FOR SECTRECT VARSIZE EQU DSTRECT ; SIZE OF LOCALS LINK A6,#VARSIZE ; ALLOCATE STACK FRAME MOVEM.L D3/A3,-(SP) ; SAVE WORK REGISTERS CLR.L RESULT(A6) ; ASSUME NO INTERSECTION MOVEQ #0,D3 ; MAX DEPTH = 0 MOVE.L DEVICELIST,A3 ; GET FIRST ELEMENT IN DEVICE LIST NEXTGD MOVE.L (A3),A0 ; POINT TO DEVICE TST GDFLAGS(A0) ; IS IT ACTIVE? BPL.S SKIPGD ; =>NO, SKIP IT CLR.B -(SP) ; MAKE ROOM FOR BOOLEAN RESULT MOVE.L RECT(A6),-(SP) ; PUSH SPECIFIED RECTANGLE PEA GDRECT(A0) ; PUSH DEVICE'S RECTANGLE PEA DSTRECT(A6) ; PUSH DESTINATION RECT (IGNORED) _SECTRECT ; IS THE RECT IN THE DEVICE TST.B (SP)+ ; TEST RESULT BEQ.S SKIPGD ; => NO INTERSECTION MOVE.L (A3),A0 ; POINT TO DEVICE MOVE.L GDPMAP(A0),A0 ; GET PIXMAP MOVE.L (A0),A0 ; POINT TO PIXMAP MOVE PIXELSIZE(A0),D0 ; GET PIXEL DEPTH CMP D3,D0 ; COMPARE TO SAVED DEPTH BLE.S SKIPGD ; => NO BIG DEAL MOVE D0,D3 ; ELSE UPDATE MAX DEPTH MOVE.L A3,RESULT(A6) ; AND RETURN RESULT SKIPGD MOVE.L (A3),A0 ; GET DEVICE MOVE.L GDNEXTGD(A0),D0 ; GET NEXT DEVICE MOVE.L D0,A3 ; SAVE IT BNE.S NEXTGD MOVEM.L (SP)+,D3/A3 ; RESTORE WORK REGISTERS UNLINK PARAMSIZE,'GETMAXDE' ; STRIP PARAMS AND RETURN GETDEVPIX PROC EXPORT ;------------------------------------------------------------- ; ; UTILITY GetDevPix; ; ; Returns a pointer to theGDevice's pixMap in A0 ; MOVE.L theGDevice,A0 ; GET A HANDLE TO THE GRAFDEVICE MOVE.L (A0),A0 ; GET A POINTER TO THE GRAFDEVICE MOVE.L GDPMAP(A0),A0 ; GET HANDLE TO THE DEVICE'S PIXMAP SHARE MOVE.L (A0),A0 ; GET PIXMAP POINTER RTS