mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-22 19:31:02 +00:00
1898 lines
70 KiB
Plaintext
1898 lines
70 KiB
Plaintext
;
|
||
; File: DockingMgr.a
|
||
;
|
||
; Contains: support for docking portable Macintoshes into desktop docking modules
|
||
;
|
||
; Written by: Steve Christensen
|
||
;
|
||
; Copyright: © 1992-1993 by Apple Computer, Inc. All rights reserved.
|
||
;
|
||
; This file is used in these builds: ROM
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <SM8> 12/13/93 PN Roll in KAOs and Horror changes to support Malcom and AJ
|
||
; machines.
|
||
; <SM7> 9/2/93 KH Rolled in the Horror changes (finally)
|
||
; <SM7> 9/2/93 SKH My fixes are back in now...
|
||
; <SM6> 9/1/93 SKH Backed out my changes until I was certain they wouldn't break builds.
|
||
; <SM5> 9/1/93 SKH Rolled in Horror version of docking code (with dock cache control stuff)
|
||
; <SM4> 12/4/92 GD Added a forRomulator conditional so that we don't (re)initialize
|
||
; the SCC when debugging.
|
||
; <SM3> 11/20/92 SWC Rolled in the rest of the Horror changes. Changed INCLUDEs to
|
||
; use new filenames.
|
||
; <H26> 8/13/92 SWC Added a new selector call in SetupDockBases to do any last
|
||
; minute pre-boot initialization. This is provided as a means of
|
||
; allowing the config ROMs to patch up anything we might have
|
||
; forgotten.
|
||
; <H25> 8/11/92 SWC Exported DockInitSCC and fixed it to preserve its registers.
|
||
; <H24> 8/10/92 SWC Specifically check for (and handle) the ‘docking slot’ selector
|
||
; in DockingDispatch so handlers, etc., have a way of determining
|
||
; which slot they're in.
|
||
; <H23> 7/29/92 SWC Fixed a typo (ended up looking at the wrong thing).
|
||
; <H22> 7/27/92 SWC Block checking for eject until after we get to the Finder.
|
||
; <H21> 7/24/92 SWC Added a check if a bar was added during sleep that's not
|
||
; supposed to be added then, and if so, the next time we wake up,
|
||
; remove its handler, etc. (takes care of the case of trying to
|
||
; add it multiple times).
|
||
; <H20> 7/8/92 SWC Made some changes to GracefulShutdown to make it better at
|
||
; successfully shutting down. DockingFilter now prevents waking up
|
||
; if we'd have to run without the LCD display since we currently
|
||
; can't handle removing a monitor from the desktop.
|
||
; <H19> 7/1/92 SWC Reset internal [and external] SCCs in SetHardwareBases so we
|
||
; won't get spurious interrupts from the unused SCC when a bar
|
||
; with another SCC is connected during sleep.
|
||
; <H18> 6/29/92 HJR SWC/Fixed my fix to Dave Wong's external32bit code from <H14>.
|
||
; <H17> 6/29/92 SWC Added in code to allow us to do a graceful shutdown when the
|
||
; eject button is pressed on a docking station.
|
||
; <H16> 6/25/92 SWC Pulled out the save/restore A2 code in <H13> since that's all
|
||
; fixed now. TravelBarHandler now returns SWIM2 power status if a
|
||
; SWIM2 exists.
|
||
; <H15> 6/18/92 SWC As part of our continuing incestuous relationship with the Power
|
||
; Manager, clear the clamshellClosed flag in the ‘sleep denied’
|
||
; Notification Manager completion routine so we won't try to keep
|
||
; posting messages until the current one goes away. Added
|
||
; RegisterVideo to the wakeup installation so we'll have a hook to
|
||
; let the system know about the addition of a new video device. It
|
||
; currently does nothing.
|
||
; <H14> 6/15/92 ag Added code to set the external32bit flag in the gdflags of
|
||
; gdevice data structure based the information from the slot
|
||
; manager.
|
||
; <H13> 6/3/92 SWC Cleaned up some of my duplicated code. Temporarily save/restore
|
||
; A2 around calls to the docking handler because the DeskBar and
|
||
; Gemini docking handlers trash it (a bug to be fixed).
|
||
; <H12> 6/1/92 HJR Changed CheckConnectNiagra for our current implementation. Call
|
||
; InitDefGamma in vAddVideoDevice.
|
||
; <H11> 5/29/92 SWC Set up docking support for Dartanian. Added a routine to notify
|
||
; the user that they tried to attach a bar during sleep that's not
|
||
; supposed to be added during sleep.
|
||
; <H10> 5/20/92 SWC Now pass the CPU's clock speed to the docking handler so it can
|
||
; configure any of its hardware that cares.
|
||
; <H9> 5/8/92 SWC Added a new routine to call Alex Kazim's Comm Toolbox hack to
|
||
; resolve which serial ports are currently available. Abort wakeup
|
||
; docking handler installation if that kind of bar is not allowed
|
||
; to be added during sleep.
|
||
; <SM2> 10/22/92 CS Change some branch short instructions to branches.
|
||
; <1> 5/16/92 kc first checked in
|
||
; <H8> 4/22/92 SWC Changed DockingWakeup so that it will only add video if video is
|
||
; supported AND a monitor is connected, so we can handle the case
|
||
; of adding a bar to use the floppy disk and then remove it when
|
||
; we're done (with video it would be locked in until shutdown).
|
||
; Added a new routine (DockingSleepDenied) to put up a
|
||
; Notification Manager dialog to let the user know that they can't
|
||
; put the system to sleep when a bar won't allow it.
|
||
; <H7> 4/13/92 SWC Added a flag to show that a bar was added during sleep. Added a
|
||
; check for eject from a docking station. Did some code cleanup.
|
||
; <H6> 4/3/92 SWC Increased the overpatch padding size to 4K.
|
||
; <H5> 3/20/92 SWC Rolled in Dave Wong's new Slot Manager support, and fixed how
|
||
; the sleep and wakeup code works. Vectored some more routines.
|
||
; Increased the overpatch file size from 1K to 2K since it
|
||
; overflowed.
|
||
; <H4> 3/6/92 SWC Enable/disable docking slot interrupts depending on whether or
|
||
; not a bar is connected. Make the built-in docking handlers
|
||
; return the SCC ports available when no bar is connected.
|
||
; <H3> 3/3/92 SWC Moved the check for SCSI Disk Mode to SCSIDiskMode.a since
|
||
; that's now part of the build, and the logical place to put it.
|
||
; <H2> 2/17/92 SWC Load the bar's docking attributes into the Power Manager globals
|
||
; so we can decide if we want to sleep, power cycle, etc.
|
||
; <H1> 2/14/92 SWC First checked in.
|
||
|
||
|
||
PRINT OFF
|
||
LOAD 'StandardEqu.d'
|
||
INCLUDE 'HardwarePrivateEqu.a'
|
||
INCLUDE 'UniversalEqu.a'
|
||
INCLUDE 'GestaltEqu.a'
|
||
INCLUDE 'MFPrivate.a'
|
||
INCLUDE 'Notification.a'
|
||
INCLUDE 'PowerPrivEqu.a'
|
||
INCLUDE 'Processes.a'
|
||
INCLUDE 'ROMEqu.a'
|
||
INCLUDE 'Slots.a'
|
||
INCLUDE 'SCSI.a'
|
||
INCLUDE 'SCSIPriv.a'
|
||
INCLUDE 'Shutdown.a'
|
||
INCLUDE 'DockingEqu.a'
|
||
PRINT ON
|
||
|
||
BLANKS ON
|
||
STRING ASIS
|
||
MACHINE MC68020
|
||
|
||
|
||
Unimplement EQU $A89F ; _Unimplemented trap
|
||
SyncIdleTime EQU $ABF7
|
||
|
||
|
||
|
||
DockingMgr PROC EXPORT
|
||
|
||
EXPORT DockingDispatch, InitDocking, SetupDockBases, DockInitSCC, GracefulShutdown
|
||
EXPORT DockingSleep, DockingWakeup, DockingSleepDenied, DockingWakeupDenied
|
||
|
||
IMPORT InitSCC, CacheFlush
|
||
|
||
WITH DockingGlobRec, NMRec, PmgrRec, pmCommandRec, scsiGlobalRecord, SEBlock, SpBlock
|
||
WITH DecoderInfo, DecoderKinds, NubusInfo, ProductInfo, ProcessInfoRec
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; pascal long DockingDispatch(OSType selector, long params)
|
||
;
|
||
; dispatches to the appropriate docking handler
|
||
;__________________________________________________________________________________________________
|
||
|
||
DockingDispatch
|
||
MOVEA.L DockingGlobals,A0 ; point to our variables
|
||
MOVEA.L dockingHandler(A0),A1 ; and get the address of our handler
|
||
CMPI.L #dockDockingSlot,8(SP) ; is this the ‘docking slot’ selector? <H24>
|
||
BNE.S @CallHandler ; -> no, pass it thru to the docking handler <H24>
|
||
MOVEA.L (SP)+,A1 ; pop the return address <H24>
|
||
ADDQ.W #8,SP ; and toss the parameters <H24>
|
||
MOVEQ #0,D0 ; <H24>
|
||
MOVE.B dockingSlotNum(A0),D0 ; get the docking slot number <H24>
|
||
MOVE.L D0,(SP) ; and return it as the result <H24>
|
||
@CallHandler
|
||
JMP (A1) ; call the docking handler or just return
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; pascal long NoBoardHandler(OSType selector, long params)
|
||
;
|
||
; docking handler when no docking module is connected
|
||
;__________________________________________________________________________________________________
|
||
|
||
NoBoardHandler
|
||
MOVEA.L (SP)+,A1 ; pop the return address
|
||
ADDQ.W #4,SP ; and toss params
|
||
MOVEQ #0,D0 ; assume an unsupported selector
|
||
CMPI.L #dockSCCPorts,(SP)+ ; is it the port list selector?
|
||
BNE.S @Done ; -> nope
|
||
MOVEA.L DockingGlobals,A0 ; point to the Docking Manager globals
|
||
MOVE.L builtInSCCPorts(A0),D0 ; get which ports are built in
|
||
|
||
@Done MOVE.L D0,(SP) ; return the selector result
|
||
JMP (A1)
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; pascal long TravelBarHandler(OSType selector, long params)
|
||
;
|
||
; docking handler for a travel bar (since it has no configuration ROM)
|
||
;__________________________________________________________________________________________________
|
||
|
||
TravelBarHandler
|
||
MOVEA.L (SP)+,A1 ; pop the return address
|
||
ADDQ.W #4,SP ; and toss params
|
||
MOVE.L (SP)+,D1 ; get the selector
|
||
|
||
MOVEQ #0,D0 ; assume an unsupported selector
|
||
|
||
MOVEA.L DockingGlobals,A0 ; point to the Docking Manager globals
|
||
CMPI.L #dockSCCPorts,D1 ; is it the port list selector?
|
||
BNE.S @NotSCCPorts ; -> nope
|
||
MOVE.L builtInSCCPorts(A0),D0 ; get which ports are built in
|
||
BRA.S @Done
|
||
@NotSCCPorts
|
||
CMPI.L #dockPowerStatus,D1 ; is it a power status call?
|
||
BNE.S @NotPowerStatus ; -> no
|
||
BSR.S @TestForSWIM ; yes, do we have a SWIM2?
|
||
BNE.S @Done ; -> no
|
||
MOVEQ #1<<dockSWIMPower,D0 ; yes, so the SWIM2 is always on
|
||
BRA.S @Done
|
||
@NotPowerStatus
|
||
CMPI.L #dockHardwareAttr,D1 ; is it the hardware attributes selector?
|
||
BNE.S @Done ; -> nope
|
||
MOVE.L #(1<<dockHasADB)|\
|
||
(1<<dockWakeADB),D0 ; assume we support at least ADB
|
||
BSR.S @TestForSWIM ; do we have a SWIM2?
|
||
BNE.S @Done ; -> nope
|
||
ORI.L #(1<<dockHasSWIM)|\
|
||
(1<<dockWakeSWIM),D0 ; yes, set its bits too
|
||
|
||
@Done MOVE.L D0,(SP) ; stuff the result
|
||
JMP (A1)
|
||
|
||
|
||
@TestForSWIM
|
||
MOVE SR,-(SP) ; save the SR
|
||
ORI #$0700,SR ; and lock everyone out while we test
|
||
MOVE.L BusErrVct,-(SP) ; save the old bus error vector
|
||
PEA @NoSWIM2 ; and point it to ours
|
||
MOVE.L (SP)+,BusErrVct
|
||
MOVE.L SP,D2 ; save the stack pointer in case we bus error
|
||
|
||
MOVEQ #$F8-256,D1
|
||
MOVE.B D1,([IWM],wPhase) ; write a value to the phase register
|
||
TST.B ([ROMBase],4) ; read from the ROM to clear the bus lines
|
||
CMP.B ([IWM],rPhase),D1 ; did we get back what was originally written?
|
||
BNE.S @NoSWIM2 ; -> nope, we don't have a SWIM2 connected
|
||
MOVEQ #0,D1
|
||
|
||
@NoSWIM2 MOVEA.L D2,SP ; trash the exception frame if we bus errored
|
||
MOVE.L (SP)+,BusErrVct ; restore the previous bus error vector
|
||
MOVE (SP)+,SR ; re-enable interrupts
|
||
TST.L D1 ; set the CCR
|
||
RTS
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: InitDocking
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: initializes the Docking Manager if this machine has a slot allocated for docking
|
||
;__________________________________________________________________________________________________
|
||
|
||
InitDocking MOVEM.L D0-D2/A0-A2,-(SP)
|
||
MOVEA.L UnivInfoPtr,A1 ; point to this machine's ProductInfo table
|
||
ADDA.L NuBusInfoPtr(A1),A1 ; and from there, point to the NubusInfo table
|
||
MOVEQ #$0F,D1
|
||
@SearchLoop BTST #dockingSlot,(A1)+ ; is this slot used for docking?
|
||
DBNE D1,@SearchLoop ; -> keep looping if not
|
||
BEQ @NoDocking ; -> no docking slots
|
||
SUBI.W #$0F,D1 ; calculate the real slot number
|
||
NEG.W D1
|
||
|
||
MOVEQ #DockingGlobalSize/2,D0 ; allocate docking globals
|
||
ADD.L D0,D0
|
||
_NewPtr ,SYS,CLEAR
|
||
BNE @NoDocking ; -> couldn't do it, so bail on docking support
|
||
MOVE.L A0,DockingGlobals ; save the pointer
|
||
MOVEA.L A0,A2
|
||
|
||
LEA NoBoardHandler,A1
|
||
MOVE.L A1,(A0)+ ; default docking handler = no board
|
||
MOVE.B D1,(A0)+ ; save the docking slot number
|
||
|
||
; setup to check if a docking station's eject button has been hit...
|
||
|
||
LEA ejectVBLTask+vblCount+2(A2),A0
|
||
MOVE.W #ejectVBLCount,-(A0) ; vblCount
|
||
LEA CheckForEject,A1
|
||
MOVE.L A1,-(A0) ; vblAddr
|
||
ADDQ.W #vType,-(A0) ; vblType
|
||
SUBQ.W #vblType-vblink,A0 ; point to the VBL task element
|
||
_VInstall ; and install the task
|
||
|
||
LEA ejectNMEntry(A2),A0 ; set up the eject Notification Manager record
|
||
LEA EjectNMResponse,A1 ; response procedure
|
||
BSR.S @SetupNMRec
|
||
|
||
LEA sleepNMEntry(A2),A0 ; set up the sleep Notification Manager record
|
||
LEA SleepNMResponse,A1 ; response procedure
|
||
BSR.S @SetupNMRec
|
||
|
||
LEA wakeupNMEntry(A2),A0 ; set up the wakeup Notification Manager record
|
||
LEA WakeupNMResponse,A1 ; response procedure
|
||
BSR.S @SetupNMRec
|
||
|
||
; initialize the vector table...
|
||
|
||
MOVEA.L UnivInfoPtr,A1 ; point to this machine's ProductInfo table
|
||
MOVE.B DecoderKind(A1),D0 ; and get the decoder type
|
||
LEA DockingVectorTable-4,A1
|
||
@NextDecoder
|
||
ADDQ.W #4,A1 ; skip over the offset to this decoder's table
|
||
MOVE.W (A1)+,D1 ; get the next decoder
|
||
BMI.S @FoundTable ; -> end of table: use default vectors
|
||
CMP.B D0,D1 ; is this the correct table?
|
||
BNE.S @NextDecoder ; -> no, try the next one
|
||
@FoundTable ADDA.L (A1),A1 ; point to the vector table
|
||
|
||
LEA builtInSCCPorts(A2),A0
|
||
MOVE.L (A1)+,(A0)+ ; copy the built-in SCC ports
|
||
@InitDispatch
|
||
MOVE.L (A1)+,D1 ; get the next offset
|
||
BEQ.S @InitDone ; -> end of table
|
||
ADD.L A1,D1 ; convert it into an absolute address
|
||
MOVE.L D1,(A0)+ ; and stuff it into our vector table
|
||
BRA.S @InitDispatch
|
||
|
||
; install the docking handler...
|
||
|
||
@InitDone MOVEQ #0,D1 ; (boot call)
|
||
BSR InstallHandler ; now install the correct handler
|
||
@Done MOVEM.L (SP)+,D0-D2/A0-A2
|
||
RTS
|
||
|
||
|
||
@SetupNMRec ADDQ.W #nmType,qType(A0) ; queue type
|
||
MOVEQ #-1,D0 ; sound: use system sound
|
||
MOVE.L D0,nmSound(A0)
|
||
MOVE.L A1,nmResp(A0) ; response procedure
|
||
RTS
|
||
|
||
|
||
@NoDocking MOVE.W #Unimplement,D0 ; get the _Unimplemented trap's address
|
||
_GetTrapAddress ,NEWTOOL
|
||
MOVE.W DockTrap,D0 ; and turn off docking
|
||
_SetTrapAddress ,NEWTOOL
|
||
BRA.S @Done
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: SetupDockBases
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0-D2, A0-A1
|
||
;
|
||
; Function: using the current bar's hardware attributes, initialize "standard" chip base addresses
|
||
; (this is called after enough of the hardware managers are initialized to be able to
|
||
; stuff base addresses into their globals)
|
||
;__________________________________________________________________________________________________
|
||
|
||
SetupDockBases
|
||
BSR.S DockingDispatchExists ; does the _DockingDispatch trap exist?
|
||
BEQ Done ; -> nope, no special initialization is required
|
||
MOVE.L A2,-(SP) ; <H16>
|
||
MOVEA.L DockingGlobals,A2 ; <H16>
|
||
BSR GetDockingAttributes ; get the docking attributes <H11>
|
||
MOVEA.L (SP)+,A2 ; <H16>
|
||
MOVE.L #dockHardwareAttr,D0 ; get the hardware attributes
|
||
BSR DockStatus
|
||
BSR SetHardwareBases ; and initialize any chip base addresses we care about
|
||
MOVE.L #dockBootHook,D0 ; do any last minute pre-boot setup <H26>
|
||
BRA DockStatus ; <H26>
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: DockingDispatchExists
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: CCR - BNE: _DockingDispatch trap exists
|
||
;
|
||
; Trashes: D0, A0-A1
|
||
;
|
||
; Function: checks if the _DockingDispatch trap exists on this machine
|
||
;__________________________________________________________________________________________________
|
||
|
||
DockingDispatchExists
|
||
MOVE.W #Unimplement,D0 ; does the _DockingDispatch trap exist?
|
||
_GetTrapAddress ,NEWTOOL
|
||
MOVEA.L A0,A1
|
||
MOVE.W DockTrap,D0
|
||
_GetTrapAddress ,NEWTOOL
|
||
CMPA.L A0,A1
|
||
RTS
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: DockingSleep
|
||
;
|
||
; Inputs: A1 - return address
|
||
;
|
||
; Outputs: A1 - return address
|
||
;
|
||
; Trashes: D0-D2
|
||
;
|
||
; Function: calls the handler to save its hardware state before going to sleep.
|
||
;__________________________________________________________________________________________________
|
||
|
||
DockingSleep
|
||
MOVE.L ([DockingGlobals],jDockingSleep),-(SP)
|
||
RTS
|
||
|
||
vDockingSleep
|
||
MOVEM.L A0-A1,-(SP)
|
||
MOVE.L #dockSleepSave,D0 ; have the handler save the bar's state
|
||
BSR DockStatus
|
||
MOVE.L D0,([DockingGlobals],savedSleepState) ; save the pointer to the state
|
||
MOVE.L PMgrBase,a0 ; get PMgr globals <H31>
|
||
BCLR #HDPowerOn,PmgrFlags(a0); clear the hard disk semaphor again, to make sure <H31>
|
||
CLR.L LastHD(A0) ; clear LastHD too <H32>
|
||
MOVEM.L (SP)+,A0-A1
|
||
JMP (A1)
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: DockingWakeup
|
||
;
|
||
; Inputs: A1 - return address
|
||
;
|
||
; Outputs: A1 - return address
|
||
;
|
||
; Trashes: D0-D2
|
||
;
|
||
; Function: Checks if a docking module as been added, changed, or removed across sleep.
|
||
; If it's been added or changed, clean up after any old handlers and install a new one.
|
||
; If it's been removed, clean up after its handler and install the "no board" handler.
|
||
;__________________________________________________________________________________________________
|
||
|
||
DockingWakeup
|
||
MOVE.L ([DockingGlobals],jDockingWakeup),-(SP)
|
||
RTS
|
||
|
||
vDockingWakeup
|
||
@savedRegs REG D3-D4/A0-A2
|
||
MOVEM.L @savedRegs,-(SP)
|
||
MOVEA.L DockingGlobals,A2 ; point to our globals
|
||
|
||
BCLR #dockForceRemoval,dockingFlags(A2) ; did user try to install a "no sleep add" bar? <H21>
|
||
BNE.S @SwitchBars ; -> yes, force removal since they could try multiple times <H21>
|
||
|
||
BSR CheckConnect ; is a docking module currently attached?
|
||
BEQ.S @SwitchBars ; -> no
|
||
|
||
; a module is currently connected; see if it's been added or changed...
|
||
|
||
BSR CheckBarChanged ; has the bar changed across sleep?
|
||
BNE.S @SwitchBars ; -> yes, do the switch
|
||
|
||
MOVE.L #dockWakeupRestore,D0 ; restore the state of anything that was turned off
|
||
MOVEA.L savedSleepState(A2),A0
|
||
BSR DockControl
|
||
CLR.L savedSleepState(A2) ; mark the state info as updated
|
||
|
||
MOVE.L #dockHardwareAttr,D0 ; get the hardware attributes <H19>
|
||
BSR DockStatus ; <H19>
|
||
BSR SetHardwareBases ; force an SCC initialization <H19>
|
||
BRA @Done
|
||
|
||
; no docking module is connected or a new one has been installed, so tell its software...
|
||
|
||
@SwitchBars BSR @GetNubusSlots ; find out if there are any NuBus connectors on this bar
|
||
|
||
MOVE.L #dockRemoved,D0 ; tell the board software that its board is gone
|
||
BSR DockStatus ; (if it was previously installed)
|
||
MOVE.L savedSleepState(A2),D0 ; Get the state info.
|
||
Cmpi.l #-1,D0 ; Was it -1?
|
||
BEQ.S @NoSavedState1 ; -> yes
|
||
Tst.l D0 ; Was it zero?
|
||
Beq.s @NoSavedState ; -> yes
|
||
MOVEA.L D0,A0 ; no, get the pointer
|
||
_DisposPtr ; and get rid of the block
|
||
@NoSavedState1
|
||
CLR.L savedSleepState(A2) ; mark the state info as updated
|
||
@NoSavedState
|
||
|
||
; clean up after any slots that went away (including the docking slot)...
|
||
|
||
Moveq #0,D1 ; Always do Slot #0 first.
|
||
Btst D1,D3 ; If Slot #0 doesn’t to be removed,
|
||
Beq.s @SkipZeroRmv ; then just go on.
|
||
Bsr RemoveVideo ; Unregister Slot #0’s video.
|
||
Bsr RemoveSlot ; And make slot zero go away.
|
||
@SkipZeroRmv
|
||
MOVEQ #sLastSlot,D1
|
||
@RemoveSlot BTST D1,D3 ; does this slot need to be removed?
|
||
BEQ.S @DontRemove ; -> nope, skip it
|
||
BSR RemoveVideo ; unregister any video associated with this slot <H16>
|
||
BSR RemoveSlot ; make the slot go away <poof!>
|
||
@DontRemove Subq #1,D1 ; decrement down to…
|
||
Bne.s @RemoveSlot ; …next slot (skipping zero)
|
||
|
||
; set everything back up for the new bar...
|
||
|
||
MOVE.B dockingSlotNum(A2),D1 ; install the bar in the docking slot
|
||
BSR AddSlot
|
||
|
||
BSET #dockSleepAddition,dockingFlags(A2)
|
||
; remember that this bar was added during sleep
|
||
MOVEQ #(1<<dockWakeupInit),D1 ; (this is a wakeup call)
|
||
BSR InstallHandler ; install the appropriate docking code
|
||
BTST #dockNoWakeup,D0 ; should we allow wakeup with this bar connected? <H9>
|
||
BNE.S @Done ; -> no, bail out <H9>
|
||
|
||
MOVE.L #dockHardwareAttr,D0 ; get the hardware attributes
|
||
BSR DockStatus
|
||
SWAP D0 ; and use the wakeup attributes
|
||
MOVE.W D0,D4 ; <H8>
|
||
; <H8>
|
||
TST.B D4 ; video support AND monitor plugged in? <H8>
|
||
BPL.S @NoBarVideo ; -> nope <H8>
|
||
|
||
BSR.S @GetNubusSlots ; find out if there are any NuBus connectors on this bar
|
||
|
||
Moveq #0,D1 ; Always do Slot #0 first (it’s never the docking slot).
|
||
Btst D1,D3 ; If Slot #0 doesn’t to be removed,
|
||
Beq.s @SkipZeroAdd ; then just go on.
|
||
Bsr AddSlot ; Make the slot appear.
|
||
Bsr AddVideoDevice ; Initialize its video.
|
||
Beq.s @SkipZeroAdd ; If failed, skip.
|
||
Bsr RegisterVideo ; Otherwise, register the new device.
|
||
@SkipZeroAdd
|
||
MOVEQ #sLastSlot,D1
|
||
@AddSlot BTST D1,D3 ; does this slot need to be added?
|
||
BEQ.S @DontAdd ; -> nope, skip it
|
||
CMP.B dockingSlotNum(A2),D1 ; is this the docking slot? <H15>
|
||
BEQ.S @IsAdded ; -> yes, it's already added: just do the video thing <H15>
|
||
BSR AddSlot ; make the slot appear <whoosh!>
|
||
@IsAdded BSR AddVideoDevice ; and initialize its video (if any)
|
||
BEQ.S @DontAdd ; -> no video or error <H15>
|
||
BSR RegisterVideo ; register the new device with the system <H15>
|
||
@DontAdd Subq #1,D1 ; decrement down to…
|
||
Bne.s @AddSlot ; …next slot (skipping zero)
|
||
|
||
@NoBarVideo MOVE.W D4,D0 ; get the wakeup attributes <H8>
|
||
BSR.S SetHardwareBases ; and use them to setup base hardware addresses
|
||
|
||
BSR ResolveSerialPorts ; make sure serial ports are properly registered <H9>
|
||
|
||
Move.l #dockFlush,D0 ; We’re done waking up,
|
||
Bsr DockStatus ; so alert the handler.
|
||
|
||
@Done MOVEM.L (SP)+,@savedRegs
|
||
JMP (A1)
|
||
|
||
|
||
@GetNubusSlots
|
||
MOVE.L #dockNuBusConnectors,D0 ; find out if there are any NuBus connectors on this bar
|
||
BSR DockStatus
|
||
MOVE.L D0,D3 ; and save which slots they're in
|
||
MOVEQ #0,D0
|
||
MOVE.B dockingSlotNum(A2),D0 ; mark the docking slot as well
|
||
BSET D0,D3
|
||
RTS
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: SetHardwareBases
|
||
;
|
||
; Inputs: D0 - bitmap of hardware available on the bar
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0-D2, A0-A1
|
||
;
|
||
; Function: handles installation of hardware base addresses for "standard" chips on the bar
|
||
;__________________________________________________________________________________________________
|
||
|
||
SetHardwareBases
|
||
MOVE.L ([DockingGlobals],jSetHardwareBases),-(SP)
|
||
RTS
|
||
|
||
vSetHardwareBases
|
||
@savedRegs REG A2-A4
|
||
MOVEM.L @savedRegs,-(SP)
|
||
|
||
MOVEA.L UnivInfoPtr,A0 ; point to the DecoderInfo table
|
||
ADDA.L ProductInfo.DecoderInfoPtr(A0),A0
|
||
MOVEM.L SCCRdAddr(A0),A0-A1 ; copy the internal SCC's base addresses
|
||
MOVEM.L A0-A1,SCCRd ; to the low-mem vectors
|
||
|
||
BTST #dockHasSCC,D0 ; does the bar contain a SCC?
|
||
BEQ.S @NoSCC ; -> no
|
||
|
||
MOVE.L #dockSCCReadAddr,D0 ; call the handler to get the SCC base read address
|
||
BSR DockStatus
|
||
BEQ.S @NoSCC ; -> it returned zero (confusion), so just use built-in
|
||
MOVE.L D0,A3 ; save the SCC base read address <H19>
|
||
MOVE.L #dockSCCWriteAddr,D0 ; call the handler to get the SCC base write address
|
||
BSR DockStatus
|
||
BEQ.S @NoSCC ; -> it returned zero (confusion), so just use built-in
|
||
MOVE.L D0,A4 ; save the SCC base write address <H19>
|
||
|
||
BSR.S DockInitSCC ; reset the internal SCC so it doesn't cause us trouble <H19>
|
||
MOVEM.L A3-A4,SCCRd ; stuff in the new SCC base addresses <H19>
|
||
@NoSCC BSR.S DockInitSCC ; initialize the SCC we'll be using <H19>
|
||
|
||
MOVEA.L SCSIGlobals,A2
|
||
MOVE.L #dockSCSIAddr,D0 ; call the handler to get the SCSI registers base address
|
||
BSR DockStatus
|
||
MOVE.L D0,base5380_2(A2) ; and save it in the SCSI Manager's variables
|
||
BNE.S @HaveSCSI2 ; -> second SCSI chip's base is valid
|
||
MOVEQ #-1,D0 ; otherwise set SCSI2Base to -1
|
||
@HaveSCSI2 MOVE.L D0,SCSI2Base
|
||
|
||
MOVE.L #dockSCSIDMAAddr,D0 ; call the handler to get the SCSI DMA base address
|
||
BSR DockStatus
|
||
MOVE.L D0,pdma5380_2(A2) ; and save it in the SCSI Manager's variables
|
||
|
||
MOVE.L #dockSCSIHskAddr,D0 ; call the handler to get the SCSI handshake base address
|
||
BSR DockStatus
|
||
MOVE.L D0,hhsk5380_2(A2) ; and save it in the SCSI Manager's variables
|
||
|
||
MOVEM.L (SP)+,@savedRegs
|
||
Done RTS
|
||
|
||
|
||
DockInitSCC MOVEM.L D0-D2/A0-A2,-(SP) ; <H25>
|
||
BSR DockingDispatchExists ; is the Docking Manager initialized? <H25>
|
||
BEQ.S @Done ; -> no, skip it <H25>
|
||
IF forRomulator THEN
|
||
TestInRam a0 ; are we running the ROM image from RAM?
|
||
bne.s @Done ; if so, then don't init the SCC
|
||
ENDIF
|
||
MOVEQ #sccOn-256,D0 ; turn SCC power on <H19>
|
||
BSR.S @SCCPower
|
||
BSR.L InitSCC ; reset the SCC so it doesn't cause us trouble
|
||
MOVEQ #sccOff,D0 ; turn SCC power off
|
||
BSR.S @SCCPower ; <H25>
|
||
@Done MOVEM.L (SP)+,D0-D2/A0-A2 ; <H25>
|
||
RTS ; <H25>
|
||
@SCCPower
|
||
IF hasPwrControls THEN
|
||
IF isUniversal THEN
|
||
TestFor hwCbPwrMgr ; does this machine have a Power Manager?
|
||
BEQ.S @NoPMGR ; -> nope, skip
|
||
ENDIF
|
||
MOVE.B D0,-(SP)
|
||
MOVE.L SP,-(SP) ; pmRBuffer
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
MOVE.W #1,-(SP) ; pmLength = 1 byte to send
|
||
MOVE.W #powerCntl,-(SP) ; pmCommand = power control
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; turn SCC power on or off
|
||
LEA pmRBuffer+4+2(SP),SP ; toss the parameter block and buffer
|
||
@NoPMGR
|
||
ENDIF
|
||
RTS
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: CheckConnect
|
||
;
|
||
; Inputs: A2 - pointer to Docking Manager's globals
|
||
;
|
||
; Outputs: CCR - BNE: bar connected
|
||
;
|
||
; Trashes: A0, D0
|
||
;
|
||
; Function: checks if a connector bar is currently plugged in
|
||
;__________________________________________________________________________________________________
|
||
|
||
CheckConnect
|
||
MOVE.L jCheckConnect(A2),-(SP)
|
||
RTS
|
||
|
||
vCheckConnect
|
||
MOVEQ #0,D0 ; return BEQ as default case
|
||
RTS
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: TurnOffBarIO, TurnOnBarIO
|
||
;
|
||
; Inputs: A2 - pointer to Docking Manager's globals
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: A0, D0
|
||
;
|
||
; Function: turns bar I/O clock on or off
|
||
;__________________________________________________________________________________________________
|
||
|
||
TurnOffBarIO
|
||
MOVE.L jTurnOffBarIO(A2),-(SP)
|
||
RTS
|
||
|
||
TurnOnBarIO MOVE.L jTurnOnBarIO(A2),-(SP)
|
||
RTS
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: InstallHandler
|
||
;
|
||
; Inputs: D1 - startup/wakeup flag to pass to docking handler's initialization code
|
||
; - (if D1.l is -1, then we just want to reload the docking attributes)
|
||
; A2 - pointer to Docking Manager's globals
|
||
;
|
||
; Outputs: D0 - docking attributes returned by the new bar
|
||
;
|
||
; Trashes: D0-D2, A0-A1
|
||
;
|
||
; Function: installs the appropriate support code into the docking selector for the
|
||
; currently installed board (or no board)
|
||
;__________________________________________________________________________________________________
|
||
|
||
InstallHandler
|
||
MOVE.L jInstallHandler(A2),-(SP)
|
||
RTS
|
||
|
||
vInstallHandler
|
||
Cmpi.l #-1,D1 ; If we just want to reload the docking attributes,
|
||
Beq.s GetDockingAttributes ; then go there now.
|
||
|
||
MOVEA.L NoBoardAddr(A2),A1 ; default to "no board"
|
||
|
||
BSR.S TurnOffBarIO ; turn off bar I/O
|
||
|
||
BSR.S CheckConnect ; is a board connected?
|
||
BEQ.S @DoInstall ; -> nope
|
||
|
||
BSR.S TurnOnBarIO ; turn on bar I/O
|
||
|
||
BSR GetDockingHandler ; try to load the docking handler for this bar
|
||
BEQ.S @DoInstall ; -> got it
|
||
MOVEA.L TravelBarAddr(A2),A1 ; bar doesn't have a handler, so use the travel bar's
|
||
|
||
@DoInstall MOVEA.L dockingHandler(A2),A0 ; get the address of the old docking handler
|
||
MOVE.L A1,dockingHandler(A2) ; and install the new one
|
||
|
||
CMPA.L noBoardAddr(A2),A0 ; is the old handler the "no board" one?
|
||
BEQ.S @Done ; -> yes, we're done
|
||
CMPA.L travelBarAddr(A2),A0 ; is the old handler the travel bar one?
|
||
BEQ.S @Done ; -> yes, we're done
|
||
_DisposPtr ; dispose of the block it occupied
|
||
|
||
@Done
|
||
IF NOT forRomulator THEN ; <H27>
|
||
MOVE.L D1,-(SP) ; save startup/wakeup flag <H28>
|
||
Move.l #dockCacheStatus,D0 ; Set up to determine if an external cache…
|
||
Movea.l #dockCacheCPU,A0 ; …works with our CPU.
|
||
Bsr.s DockControl ; Do it.
|
||
MOVE.L (SP)+,D1 ; restore startup/wakeup flag <H28>
|
||
Moveq #0,D2 ; Clear D2 for good measure.
|
||
Move.b CPUFlag,D2 ; Get the current CPU flag.
|
||
Addq #1,D2 ; De-normalize it.
|
||
Btst D2,D0 ; If we can deal with this cache,
|
||
Bne.s @UseExtCache ; then do so.
|
||
BSET #dockIgnoreExtCache,D1 ; Otherwise, just ignore it.
|
||
@UseExtCache
|
||
ENDIF ; <H27>
|
||
MOVE.L #dockInit,D0 ; call the new handler to initialize itself…
|
||
MOVEA.L D1,A0 ; …with the appropriate flags
|
||
BSR.S DockControl ; <H2>
|
||
|
||
IF hasPwrControls THEN ; <H2>
|
||
IF isUniversal THEN ; <H2>
|
||
TestFor hwCbPwrMgr ; does this machine have a Power Manager? <H2>
|
||
BEQ.S GetDockingAttributes ; -> nope, skip <H2>
|
||
ENDIF ; <H2>
|
||
MOVEQ #PowerDispRec.CPUSpeedDisp,D0 ; <H10>
|
||
_PowerDispatch ; get the CPU's maximum and current speed in MHz <H10>
|
||
EXT.L D0 ; sign-extend it to a long <H10>
|
||
BMI.S GetDockingAttributes ; -> either very fast, or selector is not supported :) <H10>
|
||
MOVEA.L D0,A0 ; stuff it into ‘params’ <H10>
|
||
MOVE.L #dockCPUSpeed,D0 ; go tell the docking handler what it is <H10>
|
||
BSR.S DockControl ; <H10>
|
||
ENDIF ; <H2>
|
||
|
||
GetDockingAttributes
|
||
MOVE.L #dockDockingAttr,D0 ; get the docking attributes for this bar <H2>
|
||
BSR.S DockStatus ; <H2>
|
||
BTST #dockSleepAddition,dockingFlags(A2) ; is this a startup or wakeup case? <H11>
|
||
BNE.S @SaveAttr ; -> wakeup: pass the attributes unmodified <H11>
|
||
BCLR #dockNoWakeup,D0 ; startup: if we go to sleep, we want to wake up again <H11>
|
||
|
||
@SaveAttr BSR.S DockingFilter ; do any filtering before we save it <H16>
|
||
|
||
IF hasPwrControls THEN ; <H2>
|
||
IF isUniversal THEN ; <H2>
|
||
TestFor hwCbPwrMgr ; does this machine have a Power Manager? <H2>
|
||
BEQ.S @NoPMgr ; -> nope, skip <H2>
|
||
ENDIF ; <H2>
|
||
MOVEA.L PmgrBase,A1 ; and save them in the Power Manager's globals <H2>
|
||
MOVE.B D0,PmgrRec.dockFlags(A1); <H2>
|
||
@NoPMgr ; <H2>
|
||
ENDIF ; <H2>
|
||
RTS ; <H2>
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: DockStatus,DockControl
|
||
;
|
||
; Inputs: D0 - docking selector
|
||
; A0 - parameters for control calls (nil for status calls)
|
||
;
|
||
; Outputs: D0 - function result
|
||
;
|
||
; Trashes: D1-D2, A0-A1
|
||
;
|
||
; Function: executes the handler code for the currently installed docking module
|
||
;__________________________________________________________________________________________________
|
||
|
||
DockStatus SUBA.L A0,A0 ; no parameters for status calls
|
||
DockControl SUBQ.W #4,SP ; result
|
||
MOVE.L D0,-(SP) ; docking selector
|
||
MOVE.L A0,-(SP) ; params
|
||
DockTrap _DockingDispatch ; call the handler
|
||
MOVE.L (SP)+,D0 ; get the result
|
||
RTS
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: DockingFilter
|
||
;
|
||
; Inputs: D0 - docking attributes returned by the bar
|
||
; A2 - pointer to Docking Manager's globals
|
||
;
|
||
; Outputs: D0 - filtered docking attributes
|
||
;
|
||
; Trashes: D1,D2,A0,A1
|
||
;
|
||
; Function: filters the docking attributes so we can decide how to behave depending on what kind
|
||
; of system software support we have (currently we don't have much)
|
||
;__________________________________________________________________________________________________
|
||
|
||
DockingFilter
|
||
MOVE.L jDockingFilter(A2),-(SP)
|
||
RTS
|
||
|
||
vDockingFilter
|
||
MOVE.L D0,-(SP)
|
||
MOVE.L #dockHardwareAttr,D0 ; get the hardware attributes
|
||
BSR DockStatus
|
||
MOVE.L D0,D1
|
||
MOVE.L (SP)+,D0
|
||
BTST #dockSleepAddition,dockingFlags(A2) ; is this a startup or wakeup case?
|
||
BEQ.S @Startup ; -> wakeup
|
||
SWAP D1 ; use the wakeup hardware attributes
|
||
BTST #dockNoLCDScreen,D0 ; do we need to lose the LCD screen? <H20>
|
||
BEQ.S @Startup ; -> no <H20>
|
||
BSET #dockNoWakeup,D0 ; yes, we can't wakeup since we don't support screen removal<H20>
|
||
@Startup ANDI.W #(1<<dockHasFPU)|\
|
||
(1<<dockHasVideo),D1 ; does this bar have either an FPU or video?
|
||
BEQ.S @Done ; -> no
|
||
BSET #dockNoSleep,D0 ; yes, we don't let it sleep
|
||
@Done RTS
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: CheckBarChanged
|
||
;
|
||
; Inputs: A2 - pointer to Docking Manager's globals
|
||
;
|
||
; Outputs: CCR - BNE: bar has changed
|
||
;
|
||
; Trashes: A0, D0
|
||
;
|
||
; Function: checks whether or not the currently connected bar is the same one we think is connected
|
||
;__________________________________________________________________________________________________
|
||
|
||
CheckBarChanged
|
||
MOVE.L jCheckBarChanged(A2),-(SP)
|
||
RTS
|
||
|
||
vCheckBarChanged
|
||
LEA -spBlockSize(SP),SP ; allocate a parameter block on the stack
|
||
MOVEA.L SP,A0 ; and point to it
|
||
MOVE.B dockingSlotNum(A2),spSlot(A0) ; spSlot = docking slot
|
||
* _CheckSlot ; find the board sResource
|
||
|
||
MOVEQ #$27,D0
|
||
_SlotManager
|
||
|
||
LEA spBlockSize(SP),SP ; clean up the stack
|
||
RTS
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: AddSlot
|
||
;
|
||
; Inputs: A2 - pointer to Docking Manager's globals
|
||
; D1 - slot number
|
||
;
|
||
; Outputs: CCR - BNE: bar has changed
|
||
;
|
||
; Trashes: A0, D0
|
||
;
|
||
; Function: given that a slot is currently empty, sets up the slot so we can use it
|
||
;__________________________________________________________________________________________________
|
||
|
||
AddSlot MOVE.L jAddSlot(A2),-(SP)
|
||
RTS
|
||
|
||
vAddSlot MOVEQ #spBlockSize/2-1,D0 ; allocate a cleared parameter block on the stack <H33>
|
||
@ClearBlock CLR.W -(SP) ; <H33>
|
||
DBRA D0,@ClearBlock ; <H33>
|
||
MOVEA.L SP,A0 ; and point to it
|
||
MOVE.B D1,spSlot(A0) ; spSlot = slot to add
|
||
* _AddCard ; initialize a newly-installed card
|
||
|
||
MOVEQ #$1E,D0
|
||
_SlotManager
|
||
|
||
LEA spBlockSize(SP),SP ; clean up the stack
|
||
RTS
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: RemoveSlot
|
||
;
|
||
; Inputs: A2 - pointer to Docking Manager's globals
|
||
; D1 - slot number
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: A0, D0
|
||
;
|
||
; Function: cleans up a slot after a bar has gone away
|
||
;__________________________________________________________________________________________________
|
||
|
||
RemoveSlot MOVE.L jRemoveSlot(A2),-(SP)
|
||
RTS
|
||
|
||
vRemoveSlot MOVEQ #spBlockSize/2-1,D0 ; allocate a cleared parameter block on the stack <H33>
|
||
@ClearBlock CLR.W -(SP) ; <H33>
|
||
DBRA D0,@ClearBlock ; <H33>
|
||
MOVEA.L SP,A0 ; and point to it
|
||
MOVE.B D1,spSlot(A0) ; spSlot = slot to kill
|
||
* _RemoveCard ; throw everything away
|
||
|
||
MOVEQ #$1F,D0
|
||
_SlotManager
|
||
|
||
LEA spBlockSize(SP),SP ; clean up the stack
|
||
RTS
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: GetDockingHandler
|
||
;
|
||
; Inputs: A2 - pointer to Docking Manager's globals
|
||
;
|
||
; Outputs: A1 - pointer to docking handler if it's found
|
||
; CCR - BNE: couldn't load the docking handler
|
||
;
|
||
; Trashes: A0, D0-D1
|
||
;
|
||
; Function: tries to load the docking handler if it can find one
|
||
;__________________________________________________________________________________________________
|
||
|
||
GetDockingHandler
|
||
MOVE.L jGetDockingHandler(A2),-(SP)
|
||
RTS
|
||
|
||
vGetDockingHandler
|
||
LEA -spBlockSize(SP),SP ; allocate a parameter block on the stack
|
||
MOVEA.L SP,A0 ; and point to it
|
||
MOVE.W #CatDock,spCategory(A0) ; spCategory = docking handler
|
||
CLR.W spCType(A0) ; spCType = 0
|
||
CLR.W spDrvrSW(A0) ; spDrvrSW = 0
|
||
CLR.W spDrvrHW(A0) ; spDrvrHW = 0
|
||
MOVE.B #7,spTBMask(A0) ; spTBMask = mask cType, DrSW, DrHW
|
||
MOVE.B dockingSlotNum(A2),spSlot(A0) ; spSlot = docking slot
|
||
CLR.B spId(A0) ; spId = 0
|
||
CLR.B spExtDev(A0) ; no external devices
|
||
CLR.W spHwDev(A0) ; spHWDev = 0
|
||
Clr.l spParamData(A0) ; (The docking sRsrc must be enabled.)
|
||
Bset #foneslot,spParamData+3(A0) ; Limit search to this slot.
|
||
_GetTypeSRsrc ; Get the spsPointer.
|
||
BNE.S @NoHandler ; -> can't find a docking handler
|
||
|
||
MOVE.B #sRsrcDock,spId(A0) ; spId = docking handler
|
||
_SGetBlock ; load the docking handler into the system heap
|
||
BNE.S @NoHandler ; -> couldn't do it
|
||
MOVEA.L spResult(A0),A1 ; get the address of the docking handler
|
||
|
||
Bsr.l CacheFlush ; Flush those caches (trashes reg D1).
|
||
Moveq #0,D0 ; Make sure we return BEQ here.
|
||
|
||
@NoHandler LEA spBlockSize(SP),SP ; toss the parameter block
|
||
RTS
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: AddVideoDevice
|
||
;
|
||
; Inputs: A2 - pointer to Docking Manager's globals
|
||
; D1 - slot number
|
||
;
|
||
; Outputs: D0 - video driver's refNum
|
||
; CCR - BNE: video device was successfully installed
|
||
;
|
||
; Trashes: D0, D2, A0, A1
|
||
;
|
||
; Function: Looks for a video driver in the specified slot. If it finds one, it installs it,
|
||
; and then sets up and initializes a GDevice for that monitor.
|
||
;__________________________________________________________________________________________________
|
||
|
||
AddVideoDevice
|
||
MOVE.L jAddVideoDevice(A2),-(SP)
|
||
RTS
|
||
|
||
AVStack RECORD {A6Save},DECREMENT
|
||
result DS.W 1
|
||
A6Save DS.L 1
|
||
driverName DS.B 256
|
||
sExecBlock DS.B seBlockSize
|
||
slotPB DS.B spBlockSize
|
||
AVStackSz EQU *
|
||
ENDR
|
||
|
||
WITH AVStack
|
||
vAddVideoDevice
|
||
@savedRegs REG D1/D3/A2-A3 ; <H14>
|
||
MOVEM.L @savedRegs,-(SP) ; <H14>
|
||
CLR.W -(SP) ; assume we can't setup a video device <H15>
|
||
|
||
LINK A6,#AVStackSz ; allocate a parameter block on the stack
|
||
MOVEA.L SP,A0 ; and point to it
|
||
MOVEQ #1<<foneslot,D0 ; look only in the given slot
|
||
MOVE.L D0,spParamData(A0)
|
||
MOVE.W #CatDisplay,spCategory(A0) ; category = display
|
||
MOVE.W #typVideo,spCType(A0) ; type = video
|
||
MOVE.W #drSwApple,spDrvrSW(A0) ; software type = Apple
|
||
CLR.W spDrvrHW(A0) ; hardware type = any
|
||
MOVE.B #1,spTBMask(A0) ; mask = ignore spDrvrHW
|
||
MOVE.B D1,spSlot(A0) ; spSlot = slot to check
|
||
CLR.B spID(A0) ; begin at ID 0
|
||
CLR.B spExtDev(A0) ; no external devices
|
||
_GetTypeSRsrc ; look for any video driver
|
||
BNE @NoDriver ; -> couldn't find one
|
||
|
||
MOVEA.L spsPointer(A0),A2 ; save ptr to sRsrc <H14>
|
||
|
||
LEA driverName(A6),A1 ; point to the driver name string
|
||
MOVE.L A1,spResult(A0)
|
||
_sReadDrvrName ; get the driver's name
|
||
BNE @NoDriver ; -> couldn't find it
|
||
|
||
MOVE.W spSlot(A0),sExecBlock+seSlot(A6) ; copy slot number and sRsrc ID
|
||
MOVE.L A1,sExecBlock+seIOFileName(A6) ; pointer to driver's name
|
||
MOVE.B spExtDev(A0),sExecBlock+seDevice(A6); which device to read from
|
||
|
||
LEA -ioQElSize(SP),SP ; allocate a parameter block on the stack
|
||
MOVE.L spResult(A0),ioFileName(SP) ; driver name
|
||
CLR.B ioPermssn(SP) ; permission = whatever goes
|
||
CLR.L ioMix(SP) ; this needs to be zero
|
||
MOVEQ #1<<fMulti,D0 ; show that we're using an SEBlock
|
||
MOVE.W D0,ioFlags(SP)
|
||
LEA sExecBlock(A6),A1
|
||
MOVE.L A1,ioSEBlkPtr(SP) ; pointer to SEBlock
|
||
MOVE.L A0,A1 ; save the pointer to the spBlock
|
||
MOVEA.L SP,A0 ; and point to the I/O pb
|
||
_Open ,IMMED ; open the driver
|
||
MOVEQ #0,D3 ; <H15>
|
||
MOVE.W ioRefNum(A0),D3 ; save the driver's reference number <H15>
|
||
MOVEA.L A1,SP ; toss the parameter block
|
||
MOVEA.L A1,A0 ; point back at the slot pb
|
||
|
||
LEA -SizesPRAMRec(SP),SP ; allocate a slot PRAM record on the stack
|
||
MOVE.L SP,spResult(A0) ; and point to it
|
||
_sReadPRAMRec ; get info about this video device
|
||
MOVEQ #0,D0
|
||
MOVE.B 2(SP),D0 ; get the default video mode
|
||
LEA SizesPRAMRec(SP),SP ; clean up
|
||
|
||
MOVE.L D0,-(SP) ; save mode <H14>
|
||
MOVE.B #sRsrcFlags,spID(A0) ; look for sRsrcFlags <H14>
|
||
MOVE.L A2,spsPointer(A0) ; set spsPointer to sRsrc <H14>
|
||
_sReadWord ; read flag word <H14>
|
||
BNE.S @Use24Bit ; no flag field - default to 24 bit mode <H14>
|
||
MOVEQ #1<<f32BitMode,D0 ; is this a 32-bit device? <H14>
|
||
AND.L spResult(A0),D0 ; d0 = flag word <H14>
|
||
BEQ.S @Use24Bit ; -> no <H14>
|
||
BSET #31,D3 ; yes - set flag in d3 <H18>
|
||
@Use24Bit MOVE.L (SP)+,D0 ; restore mode <H14>
|
||
|
||
SUBQ.W #4,SP
|
||
MOVE.W D3,-(SP) ; refNum <H18>
|
||
MOVE.L D0,-(SP) ; mode
|
||
_NewGDevice ; allocate a new GDevice for our card
|
||
MOVE.L (SP)+,D0 ; was it allocated?
|
||
BEQ.S @NoDriver ; -> no, bail
|
||
MOVEA.L D0,A3 ; save the GDHandle
|
||
|
||
LEA DeviceList-gdNextGD,A0
|
||
MOVEQ #0,D1 ; initialize rightmost screen location
|
||
BRA.S @FirstDevice
|
||
|
||
@NextDevice MOVEA.L D0,A0 ; get the handle to the next GDevice
|
||
MOVEA.L (A0),A0 ; and de-reference it
|
||
MOVE.W gdRect+right(A0),D0 ; get the right edge of this device
|
||
CMP.W D0,D1 ; is this one farther right than the last?
|
||
BGE.S @FirstDevice ; -> nope
|
||
MOVE.W D0,D1 ; yes, keep track of it
|
||
@FirstDevice
|
||
MOVE.L gdNextGD(A0),D0 ; any more GDevices in the list?
|
||
BNE.S @NextDevice ; -> yes
|
||
|
||
MOVE.L A3,gdNextGD(A0) ; tack our GDevice onto the end of the list
|
||
MOVEA.L (A3),A0 ; de-reference the handle
|
||
BSET #screenDevice-8,gdFlags(A0) ; mark our GDevice as a screen device
|
||
TST.L D3 ; test flag whether this a 32 bit device <H18>
|
||
BPL.S @Not32 ; no <H18>
|
||
BSET.B #ext32Device-8,gdFlags(A0) ; mark as 32 bit frame buffer <H14>
|
||
|
||
@Not32 PEA gdRect(A0) ; theRect = device's bounds
|
||
MOVE.L D1,-(SP) ; dv,dh
|
||
|
||
MOVEA.L gdPMap(A0),A0 ; get the PixMap handle
|
||
MOVEA.L (A0),A0 ; and de-reference it
|
||
PEA pmBounds(A0) ; theRect = PixMap's bounds
|
||
MOVE.L D1,-(SP) ; dv,dh
|
||
_OffsetRect ; move the PixMap's bounds
|
||
_OffsetRect ; and gdRect to their new location
|
||
|
||
MOVEA.L A3,A0 ; put the GDevice handle into A0 <H12>
|
||
IMPORT InitDefGamma ; <H12>
|
||
BSR.L InitDefGamma ; call this to test <H12>
|
||
|
||
MOVE.W D3,result(A6) ; show success <H15>
|
||
@NoDriver UNLK A6 ; clean up the stack
|
||
MOVE.W (SP)+,D0 ; save the refNum and setup the CCR <H15>
|
||
MOVEM.L (SP)+,@savedRegs ; restore them regs correctly <H14>
|
||
RTS
|
||
|
||
ENDWITH ; {AVStack}
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: RegisterVideo
|
||
;
|
||
; Inputs: A2 - pointer to Docking Manager's globals
|
||
; D0 - video driver's refNum
|
||
; D1 - slot number
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0, D2, A0, A1
|
||
;
|
||
; Function: Given that we've successfully installed a video driver from the docking bar's ROM,
|
||
; this routine makes the system aware of the new device, ála the Monitors control panel.
|
||
;__________________________________________________________________________________________________
|
||
|
||
RegisterVideo
|
||
MOVE.L jRegisterVideo(A2),-(SP)
|
||
RTS
|
||
|
||
vRegisterVideo
|
||
RTS
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: RemoveVideo
|
||
;
|
||
; Inputs: A2 - pointer to Docking Manager's globals
|
||
; D1 - slot number
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0, D2, A0, A1
|
||
;
|
||
; Function: Provides an expansion hook for future system software to allow us to gracefully
|
||
; remove a monitor from the desktop.
|
||
;__________________________________________________________________________________________________
|
||
|
||
RemoveVideo MOVE.L jRemoveVideo(A2),-(SP)
|
||
RTS
|
||
|
||
vRemoveVideo
|
||
RTS
|
||
|
||
|
||
;__________________________________________________________________________________________________ <H9>
|
||
;
|
||
; Routine: ResolveSerialPorts
|
||
;
|
||
; Inputs: A2 - pointer to Docking Manager's globals
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0, D1, D2, A0, A1
|
||
;
|
||
; Function: Calls Alex Kazim's hack to the Comm Toolbox to remove and add the appropriate serial
|
||
; port resources.
|
||
;__________________________________________________________________________________________________
|
||
|
||
ResolveSerialPorts
|
||
MOVE.L jResolveSerialPorts(A2),-(SP)
|
||
RTS
|
||
|
||
vResolveSerialPorts
|
||
MOVE.W #CTB_ModemIconID,-(SP) ; remove the modem port (if it exists)
|
||
_CTBRemovePort
|
||
|
||
MOVE.W #CTB_PrinterIconID,-(SP); remove the printer port (if it exists)
|
||
_CTBRemovePort
|
||
|
||
MOVE.W #CTB_ModemIconID,-(SP) ; add in the modem port (if it exists)
|
||
_CTBAddPort
|
||
|
||
MOVE.W #CTB_PrinterIconID,-(SP); add in the printer port (if it exists)
|
||
_CTBAddPort
|
||
RTS
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: DockSleepDenied
|
||
;
|
||
; Inputs: A0 - pointer to the Power Manager's variables
|
||
;
|
||
; Outputs: CCR - BNE: NM task was successfully installed, BEQ: can't install
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: If the Docking Manager was initialized, install a Notification Manager request to
|
||
; let the user know that they can't put the portable to sleep because the connected
|
||
; bar doesn't think that's a good idea.
|
||
;__________________________________________________________________________________________________
|
||
|
||
DockingSleepDenied
|
||
MOVE.L ([DockingGlobals],jDockingSleepDenied),-(SP)
|
||
RTS
|
||
|
||
vDockingSleepDenied
|
||
@savedRegs REG D0-D2/A0-A1
|
||
MOVEM.L @savedRegs,-(SP)
|
||
BSR DockingDispatchExists ; is the Docking Manager initialized?
|
||
BEQ.S @NoDocking ; -> no, bail
|
||
|
||
MOVEA.L DockingGlobals,A0 ; point to our globals
|
||
LEA sleepNMEntry(A0),A0 ; and then to the NM record
|
||
BSR NMInstall ; install the NM request if it's not already installed
|
||
@NoDocking MOVEM.L (SP)+,@savedRegs
|
||
RTS
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: DockingWakeupDenied
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: If the Docking Manager was initialized, install a Notification Manager request to
|
||
; let the user know that they tried to wakeup with a new bar attached that's not
|
||
; supposed to be added during sleep. After this call is made, the system will go
|
||
; back to sleep, so the message will be displayed when we succussfully wake up.
|
||
;__________________________________________________________________________________________________
|
||
|
||
DockingWakeupDenied
|
||
MOVE.L ([DockingGlobals],jDockingWakeDenied),-(SP)
|
||
RTS
|
||
|
||
vDockingWakeupDenied
|
||
@savedRegs REG D0-D2/A0-A1
|
||
MOVEM.L @savedRegs,-(SP)
|
||
BSR DockingDispatchExists ; is the Docking Manager initialized?
|
||
BEQ.S @NoDocking ; -> no, bail
|
||
|
||
MOVE.L #dockEjectCPU,D0 ; tell the docking station to eject when the power goes off
|
||
BSR DockStatus
|
||
|
||
MOVEA.L DockingGlobals,A0 ; remember we have to remove the current handler next time we wake up
|
||
BSET #dockForceRemoval,dockingFlags(A0) ; <H21>
|
||
LEA wakeupNMEntry(A0),A0 ; point to the NM record
|
||
BSR NMInstall ; install the NM request if it's not already installed
|
||
@NoDocking MOVEM.L (SP)+,@savedRegs
|
||
RTS
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; pascal void SleepNMResponse(NMRec *nmReq)
|
||
;
|
||
; Notification Manager response procedure for signaling that the sleep notification is complete.
|
||
;__________________________________________________________________________________________________
|
||
|
||
SleepNMResponse
|
||
MOVEA.L PMgrBase,A1
|
||
BCLR #InSleep,PmgrFlags(A1) ; show that we're not in the sleep code anymore
|
||
BCLR #ClamshellClosed,PmgrFlags(A1) ; and that the clamshell switch is fair game again <H15>
|
||
BRA.S WakeupNMResponse ; branch to the standard response procedure
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; pascal void EjectNMResponse(NMRec *nmReq)
|
||
;
|
||
; Notification Manager response procedure for signaling that the eject notification is complete.
|
||
;__________________________________________________________________________________________________
|
||
|
||
EjectNMResponse
|
||
MOVEA.L DockingGlobals,A1 ; <H17>
|
||
CLR.B dockingEjectFlags(A1) ; back us out of the eject <H17>
|
||
MOVE.L #dockEjectStatus,D0 ; reset the eject switch in case the user pressed it <H17>
|
||
BSR DockStatus ; while the NM dialog was up <H17>
|
||
* BRA.S WakeupNMResponse ; fall thru into the standard response procedure
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; pascal void WakeupNMResponse(NMRec *nmReq)
|
||
;
|
||
; Notification Manager response procedure for signaling that the wakeup notification is complete.
|
||
;__________________________________________________________________________________________________
|
||
|
||
WakeupNMResponse
|
||
MOVEA.L (SP)+,A1 ; pop the return address
|
||
MOVEA.L (SP)+,A0 ; and the pointer to the NM record
|
||
CLR.B nmRefCon(A0) ; flag that the notification has been received
|
||
_NMRemove ; remove the request from the queue
|
||
JMP (A1)
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: CheckForEject
|
||
;
|
||
; Inputs: A0 - pointer to VBL task element
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0, D1, D2, A0, A1, A2
|
||
;
|
||
; Function: Checks if the user has pushed the eject button on a docking station (assuming there
|
||
; is one). If so, it shuts down and ejects the CPU if it's not locked into the station.
|
||
; If it is locked, we'll put up a message telling them why they can't eject.
|
||
;__________________________________________________________________________________________________
|
||
|
||
CheckForEject
|
||
MOVE.L A0,-(SP)
|
||
MOVE.W #Unimplement,D0 ; is _SyncIdleTime implemented?
|
||
_GetTrapAddress ,NEWTOOL
|
||
MOVEA.L A0,A1
|
||
MOVE.W #SyncIdleTime,D0
|
||
_GetTrapAddress ,NEWTOOL
|
||
CMPA.L A0,A1
|
||
BEQ.S @NoSyncIdle ; -> no, we're done
|
||
|
||
MOVEA.L DockingGlobals,A2
|
||
MOVE.L A0,dockOldSyncIdleTime(A2) ; save the old trap address
|
||
LEA EjectShutdown,A0 ; and head patch us
|
||
MOVE.W #SyncIdleTime,D0
|
||
_SetTrapAddress ,NEWTOOL
|
||
|
||
LEA CheckForEject2,A1
|
||
MOVE.L A1,ejectVBLTask+vblAddr(A2) ; shorten this VBL task (no _SyncIdleTime check now)
|
||
@NoSyncIdle MOVEA.L (SP)+,A0
|
||
|
||
CheckForEject2
|
||
MOVE.W #ejectVBLCount,vblCount(A0) ; reset the counter
|
||
|
||
IF hasPwrControls THEN ; <H22>
|
||
MOVEA.L PMgrBase,A1 ; <H22>
|
||
TST.B SysTaskFlag(A1) ; has SystemTask been called yet? <H22>
|
||
BEQ.S NMDone ; -> no, don't allow ejects yet (the system will freak) <H22>
|
||
ENDIF ; <H22>
|
||
|
||
MOVEA.L DockingGlobals,A2 ; point to the docking globals
|
||
IF dockEjectPressed=7 THEN
|
||
TST.B dockingEjectFlags(A2) ; is a request pending?
|
||
BMI.S NMDone ; -> yes, let it complete
|
||
ELSE
|
||
BTST #dockEjectPressed,dockingEjectFlags(A2) ; is a request pending?
|
||
BNE.S NMDone ; -> yes, let it complete
|
||
ENDIF
|
||
|
||
MOVE.L #dockEjectStatus,D0 ; get the eject status
|
||
BSR DockStatus
|
||
BTST #dockEjectEnabled,D0 ; was the eject button hit?
|
||
BEQ.S NMDone ; -> no, done
|
||
|
||
BSET #dockEjectPressed,dockingEjectFlags(A2) ; set a flag to prevent re-entrancy
|
||
|
||
MOVE.L #dockLockAttr,D0 ; get the lock attributes
|
||
BSR DockStatus
|
||
BTST #dockLockEnabled,D0 ; is the CPU locked into the docking station?
|
||
BNE.S @Locked ; -> yes, put up a message
|
||
|
||
MOVE.L #dockEjectCPU,D0 ; tell the docking station to eject on power off
|
||
BSR DockStatus
|
||
TST.L dockOldSyncIdleTime(A2) ; is the _SyncIdleTime patch installed?
|
||
BNE.S NMDone ; -> yes, we'll finish later
|
||
|
||
_SDPowerOff ; just shutdown the system since the Finder's not running anyway
|
||
BRA.S *
|
||
|
||
@Locked LEA ejectNMEntry(A2),A0 ; point to the NM record
|
||
;••• MOVE.L lockedEjectMsg(A2),nmStr(A0); load the “CPU is locked to docking bar” message
|
||
NMInstall TST.B nmRefCon(A0) ; is this request already pending?
|
||
BNE.S NMDone ; -> yes, let it complete
|
||
TST.L nmStr(A0) ; is there a string to use to notify the user?
|
||
BEQ.S NMDone ; -> no, can't do anything
|
||
_NMInstall ; and install the request
|
||
SEQ D0 ; mark the request installed if successful
|
||
MOVE.B D0,nmRefCon(A0) ; force CCR to BNE if it was installed
|
||
NMDone RTS
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; pascal void EjectShutdown(void)
|
||
;
|
||
; This is a head patch to _SyncIdleTime ($ABF7) to send a shutdown message to
|
||
; the Finder at a time when it can do something.
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
EjectShutdown ; <H17>
|
||
MOVEA.L DockingGlobals,A1 ; point to the Docking Manager's globals
|
||
IF dockEjectPressed=7 THEN
|
||
TST.B dockingEjectFlags(A1) ; has the user pressed the eject button?
|
||
BPL.S @NoEject ; -> no, just passing thru
|
||
ELSE
|
||
BTST #dockEjectPressed,dockingEjectFlags(A1) ; has the user pressed the eject button?
|
||
BEQ.S @NoEject ; -> no, just passing thru
|
||
ENDIF
|
||
TST.B ejectNMEntry+nmRefCon(A1) ; is a NM dialog up?
|
||
BNE.S @NoEject ; -> yes, problems, so don't do the eject thing
|
||
BSET #dockShuttingDown,dockingEjectFlags(A1) ; have we been here before?
|
||
BNE.S @NoEject ; -> yes, once is enough
|
||
MOVEA.L jGracefulShutdown(A1),A0 ; call the graceful shutdown routine
|
||
JSR (A0)
|
||
BEQ.S @NoEject ; -> the shutdown is under way
|
||
|
||
BCLR #dockShuttingDown,dockingEjectFlags(A1) ; we couldn't shutdown now
|
||
TST.W D0 ; are we waiting on the Finder?
|
||
BGT.S @NoEject ; -> yes, we'll finish up later
|
||
|
||
LEA ejectNMEntry(A1),A0 ; point to the NM record
|
||
;••• MOVE.L finderBlockedMsg(A1),nmStr(A0); load the “something’s blocking shutdown” message
|
||
BSR.S NMInstall ; install the NM request if it's not already installed
|
||
BNE.S @NoEject ; -> task was installed
|
||
BCLR #dockEjectPressed,dockingEjectFlags(A1) ; back us out of the eject
|
||
|
||
@NoEject MOVEA.L dockOldSyncIdleTime(A1),A0 ; return so the Finder can do the shutdown
|
||
JMP (A0)
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: GracefulShutdown
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: D0 - result code
|
||
; =0: shutdown message successfully sent to the Finder
|
||
; >0: waiting for the Finder to become the front process
|
||
; <0: a problem occurred (no Finder, something blocking, etc.)
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: Sends a shutdown event to the Finder (if the Finder is running) so it will
|
||
; quit all running applications. If the required OS support is not present,
|
||
; we'll back down to doing just a straight shutdown instead.
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
receiverIDisPSN EQU $00008000 ; use a process number for the receiver ID
|
||
|
||
GracefulShutdown
|
||
@savedRegs REG D1-D2/A0-A2
|
||
MOVEM.L @savedRegs,-(SP)
|
||
|
||
; check if the Process Manager/MultiFinder is installed...
|
||
|
||
MOVE.W #Unimplement,D0 ; get the address of the _Unimplemented trap
|
||
_GetTrapAddress ,NEWTOOL
|
||
MOVEA.L A0,A1
|
||
MOVE.W #$A88F,D0 ; get the address of _OSDispatch
|
||
_GetTrapAddress ,NEWTOOL
|
||
CMPA.L A0,A1 ; is _OSDispatch implemented?
|
||
BEQ @JustShutDown ; -> no, do it the old way
|
||
|
||
MOVE.W @Gestalt,D0 ; is Gestalt implemented?
|
||
_GetTrapAddress ,NEWOS
|
||
CMPA.L A0,A1
|
||
BEQ @JustShutDown ; -> no
|
||
|
||
MOVE.L #gestaltAppleEventsAttr,D0 ; get AppleEvents attributes
|
||
@Gestalt _Gestalt
|
||
MOVE.L A0,D0
|
||
BTST #gestaltAppleEventsPresent,D0 ; are AppleEvents supported?
|
||
BEQ @JustShutDown ; -> no, can't send a message
|
||
|
||
; try to find the Finder in the list of active processes...
|
||
|
||
LINK A6,#-ProcessInfoRec.size ; allocate a process info record on the stack
|
||
MOVEQ #ProcessInfoRec.size,D0 ; initialize the record
|
||
MOVE.L D0,processInfoLength(SP)
|
||
CLR.L processName(SP)
|
||
CLR.L processNumber.highLongOfPSN(SP)
|
||
MOVE.L #kNoProcess,processNumber.lowLongOfPSN(SP)
|
||
CLR.L processAppSpec(SP)
|
||
MOVEA.L SP,A2 ; point to the process info record
|
||
|
||
SUBQ.W #2,SP ; space for result (this gets left on the stack)
|
||
@FindFinder PEA processNumber(A2) ; PSN
|
||
_GetNextProcess ; get the next process' PSN
|
||
MOVE.W (SP),D0
|
||
BNE @NoFinder ; -> no more processes: couldn't find the Finder
|
||
|
||
PEA processNumber(A2) ; PSN
|
||
MOVE.L A2,-(SP) ; info
|
||
_GetProcessInformation ; get information about this process
|
||
MOVE.W (SP),D0
|
||
BNE.S @NoFinder ; -> bad PSN?
|
||
|
||
CMPI.L #'FNDR',processType(A2) ; is this process the Finder?
|
||
BNE.S @FindFinder ; -> no, keep looking
|
||
|
||
; make sure the Finder's the front process before telling it to shut down...
|
||
|
||
LEA -ProcessSerialNumber.size-2(SP),SP ; <H20>
|
||
PEA 2(SP) ; PSN <H20>
|
||
_GetFrontProcess ; get the process number of the front process <H20>
|
||
TST.W (SP)+ ; is there a front process? <H20>
|
||
BNE.S @JustShutDown ; -> no, just shut down (why no foreground process?) <H20>
|
||
|
||
CLR.L -(SP) ; space for ‘result’ + result code <H20>
|
||
PEA processNumber(A2) ; PSN1 <H20>
|
||
PEA 4+2+2(SP) ; PSN2 <H20>
|
||
PEA 4+4+2(SP) ; result <H20>
|
||
_SameProcess ; compare process numbers <H20>
|
||
TST.W (SP)+ ; <H20>
|
||
BNE.S @JustShutDown ; -> bad process number? <H20>
|
||
TST.B (SP)+ ; is the Finder the front process? <H20>
|
||
LEA ProcessSerialNumber.size(SP),SP ; (toss the process number record) <H20>
|
||
BNE.S @FinderInFront ; -> yes, we're ready to shutdown <H20>
|
||
|
||
PEA processNumber(A2) ; PSN
|
||
_SetFrontProcess ; force the Finder to the front
|
||
MOVE.W (SP),D0 ; is it going to happen?
|
||
BNE.S @NoFinder ; -> nope, something's preventing it
|
||
MOVEQ #1,D0 ; show the Finder is being brought to the front <H20>
|
||
BRA.S @NoFinder ; <H20>
|
||
|
||
; the Finder's now in front so tell it to shut everybody down...
|
||
|
||
@FinderInFront
|
||
_BeginSystemMode ; enter system mode
|
||
|
||
PEA @ShutDownEvent ; theEvent
|
||
PEA processNumber(A2) ; receiverID
|
||
CLR.L -(SP) ; msgRefCon
|
||
CLR.L -(SP) ; msgBuff
|
||
CLR.L -(SP) ; msgLen
|
||
MOVE.L #receiverIDisPSN,-(SP) ; postingOptions
|
||
_PostHighLevelEvent ; send the event to the Finder (leave result on stack)
|
||
|
||
_EndSystemMode ; exit system mode
|
||
|
||
MOVEQ #0,D0 ; show no error
|
||
@NoFinder UNLK A6 ; toss the stack frame
|
||
MOVEM.L (SP)+,@savedRegs
|
||
RTS
|
||
|
||
@JustShutDown
|
||
_SDPowerOff ; ‘single’ Finder: shutdown the system
|
||
BRA.S *
|
||
|
||
@ShutDownEvent ; HighLevel EventRecord to tell the Finder to shutdown
|
||
DC.W 0 ; what
|
||
DC.L 'FNDR' ; message = event class (Finder's application signature)
|
||
DC.L 0 ; ticks
|
||
DC.L 'shut' ; where = event ID (shutdown)
|
||
CLR.W 0 ; meta
|
||
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; The following tables are used for initializing the routine vectors for a particular machine.
|
||
; If there are no special machine-specific characteristics, there doesn't need to be a vector
|
||
; table since in that case the default vectors will be used.
|
||
;__________________________________________________________________________________________________
|
||
|
||
DockingVectorTable
|
||
IF hasMSC THEN
|
||
DC.B 0,MSCDecoder ; handle MSC Decoder
|
||
DC.L MSCVectors-*
|
||
ENDIF
|
||
|
||
IF hasNiagra THEN ; <H11>
|
||
DC.B 0,NiagraDecoder ; handle Niagra decoder <H11>
|
||
DC.L NiagraVectors-* ; <H11>
|
||
ENDIF ; <H11>
|
||
|
||
IF hasPratt THEN ; <K2>
|
||
DC.B 0,PrattDecoder ; handle Pratt decoder <K2>
|
||
DC.L PrattVectors-* ; <K2>
|
||
ENDIF ; <K2>
|
||
|
||
DC.W -1 ; default vectors (this should be the last entry)
|
||
DC.L DefaultVectors-*
|
||
|
||
|
||
DefaultVectors
|
||
DC.L (1<<dockSCCModemPort) |\; both SCC ports are available
|
||
(1<<dockSCCPrinterPort)
|
||
DC.L NoBoardHandler-(*+4)
|
||
DC.L TravelBarHandler-(*+4)
|
||
DC.L vDockingSleep-(*+4)
|
||
DC.L vDockingWakeup-(*+4)
|
||
DC.L vInstallHandler-(*+4)
|
||
DC.L vSetHardwareBases-(*+4)
|
||
DC.L vCheckConnect-(*+4)
|
||
DC.L vCheckBarChanged-(*+4)
|
||
DC.L vAddSlot-(*+4)
|
||
DC.L vRemoveSlot-(*+4)
|
||
DC.L vGetDockingHandler-(*+4)
|
||
DC.L Done-(*+4)
|
||
DC.L Done-(*+4)
|
||
DC.L vAddVideoDevice-(*+4)
|
||
DC.L vRegisterVideo-(*+4)
|
||
DC.L vRemoveVideo-(*+4)
|
||
DC.L vResolveSerialPorts-(*+4)
|
||
DC.L vDockingSleepDenied-(*+4)
|
||
DC.L vDockingWakeupDenied-(*+4)
|
||
DC.L vDockingFilter-(*+4)
|
||
DC.L GracefulShutdown-(*+4)
|
||
DC.L 0
|
||
|
||
|
||
IF hasMSC THEN
|
||
;•••••••••••••••••••••••••••••••••••••••••••••• MSC •••••••••••••••••••••••••••••••••••••••••••••••
|
||
|
||
MSCVectors DC.L (1<<dockSCCModemPort) ; just the modem port is available
|
||
DC.L NoBoardHandler-(*+4)
|
||
DC.L TravelBarHandler-(*+4)
|
||
DC.L vDockingSleep-(*+4)
|
||
DC.L vDockingWakeup-(*+4)
|
||
DC.L vInstallHandler-(*+4)
|
||
DC.L vSetHardwareBases-(*+4)
|
||
DC.L CheckConnectMSC-(*+4)
|
||
DC.L vCheckBarChanged-(*+4)
|
||
DC.L vAddSlot-(*+4)
|
||
DC.L vRemoveSlot-(*+4)
|
||
DC.L vGetDockingHandler-(*+4)
|
||
DC.L ClockOffMSC-(*+4)
|
||
DC.L ClockOnMSC-(*+4)
|
||
DC.L vAddVideoDevice-(*+4)
|
||
DC.L vRegisterVideo-(*+4)
|
||
DC.L vRemoveVideo-(*+4)
|
||
DC.L vResolveSerialPorts-(*+4)
|
||
DC.L vDockingSleepDenied-(*+4)
|
||
DC.L vDockingWakeupDenied-(*+4)
|
||
DC.L vDockingFilter-(*+4)
|
||
DC.L GracefulShutdown-(*+4)
|
||
DC.L 0
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: CheckConnectMSC
|
||
;
|
||
; Inputs: A2 - pointer to Docking Manager's globals
|
||
;
|
||
; Outputs: CCR - BNE: bar is connected, BEQ: no bar (bar none?)
|
||
;
|
||
; Trashes: A0,D0
|
||
;
|
||
; Function: calls the Power Manager to determine if a bar is connected
|
||
;__________________________________________________________________________________________________
|
||
|
||
CheckConnectMSC
|
||
CLR.W -(SP) ; make space for the result
|
||
MOVE.L SP,-(SP) ; pmRBuffer
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
CLR.W -(SP) ; pmLength
|
||
MOVE.W #readExtSwitches,-(SP) ; pmCommand
|
||
MOVEA.L SP,A0 ; point to the buffer
|
||
_PMgrOp ; get the info
|
||
LEA pmRBuffer+4(SP),SP ; toss the parameter block
|
||
BTST #dockingBar,(SP)+ ; setup the CCR for exit
|
||
RTS
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: ClockOffMSC
|
||
;
|
||
; Inputs: A2 - pointer to Docking Manager's globals
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: turns off the I/O clock going to the connector when a bar is not plugged in
|
||
;__________________________________________________________________________________________________
|
||
|
||
ClockOffMSC MOVEA.L VIA2,A0
|
||
BCLR #MSCIOClk,MSCClkCntl(A0); turn off the I/O clock to the bar
|
||
MOVE.B #(0<<ifIRQ) | (1<<RvIRQ6En),MSCSlotIER(A0) ; disable slot E interrupts
|
||
RTS
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: ClockOnMSC
|
||
;
|
||
; Inputs: A2 - pointer to Docking Manager's globals
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: turns on the I/O clock going to the connector when a bar IS plugged in
|
||
;__________________________________________________________________________________________________
|
||
|
||
ClockOnMSC MOVEA.L VIA2,A0
|
||
BSET #MSCIOClk,MSCClkCntl(A0); turn on the I/O clock to the bar
|
||
MOVE.B #(1<<ifIRQ) | (1<<RvIRQ6En),MSCSlotIER(A0) ; enable slot E interrupts
|
||
RTS
|
||
|
||
ENDIF ; {hasMSC}
|
||
|
||
|
||
IF hasNiagra THEN ; <H11>
|
||
;•••••••••••••••••••••••••••••••••••••••••••• Niagra ••••••••••••••••••••••••••••••••••••••••••••••
|
||
|
||
NiagraVectors
|
||
DC.L (1<<dockSCCModemPort) |\; both SCC ports are available
|
||
(1<<dockSCCPrinterPort)
|
||
DC.L NoBoardHandler-(*+4)
|
||
DC.L NoBoardHandler-(*+4)
|
||
DC.L vDockingSleep-(*+4)
|
||
DC.L vDockingWakeup-(*+4)
|
||
DC.L vInstallHandler-(*+4)
|
||
DC.L vSetHardwareBases-(*+4)
|
||
DC.L CheckConnectNiagra-(*+4)
|
||
DC.L vCheckBarChanged-(*+4)
|
||
DC.L vAddSlot-(*+4)
|
||
DC.L vRemoveSlot-(*+4)
|
||
DC.L vGetDockingHandler-(*+4)
|
||
DC.L Done-(*+4)
|
||
DC.L Done-(*+4)
|
||
DC.L vAddVideoDevice-(*+4)
|
||
DC.L vRegisterVideo-(*+4)
|
||
DC.L vRemoveVideo-(*+4)
|
||
DC.L Done-(*+4) ; <H12>
|
||
DC.L vDockingSleepDenied-(*+4)
|
||
DC.L vDockingWakeupDenied-(*+4)
|
||
DC.L vDockingFilter-(*+4)
|
||
DC.L GracefulShutdown-(*+4)
|
||
DC.L 0
|
||
|
||
ENDIF ; {hasNiagra}
|
||
|
||
;__________________________________________________________________________________________________ <H12>
|
||
;
|
||
; Routine: CheckConnectNiagra, CheckConnectPratt
|
||
;
|
||
; Inputs: A2 - pointer to Docking Manager's globals
|
||
;
|
||
; Outputs: CCR - BNE: bar is connected, BEQ: no bar (bar none?)
|
||
;
|
||
; Trashes: A0,D0
|
||
;
|
||
; Function: returns ‘connected’ if the VSC video is turned on since Dartanian's ‘bar’ is built
|
||
; into the box.
|
||
;__________________________________________________________________________________________________
|
||
|
||
CheckConnectPratt
|
||
CheckConnectNiagra
|
||
lea -spBlockSize(sp),sp ; alloc spBlock
|
||
movea.l sp,a0
|
||
move.b dockingSlotNum(a2),spSlot(a0) ; slot VSC video is on
|
||
_sCkCardStat ; see if card was added ok
|
||
lea spBlockSize(sp),sp ; dealloc spBlock
|
||
seq d0 ; if bad, return "not connected"
|
||
tst.b d0 ; set the CCR
|
||
rts
|
||
|
||
|
||
|
||
IF hasPratt THEN ; <K2>
|
||
;•••••••••••••••••••••••••••••••••••••••••••• Pratt ••••••••••••••••••••••••••••••••••••••••••••••
|
||
|
||
PrattVectors
|
||
DC.L (1<<dockSCCModemPort) ; only port A (modem port) is available
|
||
DC.L NoBoardHandler-(*+4)
|
||
DC.L NoBoardHandler-(*+4)
|
||
DC.L vDockingSleep-(*+4)
|
||
DC.L vDockingWakeup-(*+4)
|
||
DC.L vInstallHandler-(*+4)
|
||
DC.L Done-(*+4)
|
||
DC.L CheckConnectPratt-(*+4)
|
||
DC.L CheckBarChangedPratt-(*+4)
|
||
DC.L vAddSlot-(*+4)
|
||
DC.L vRemoveSlot-(*+4)
|
||
DC.L vGetDockingHandler-(*+4)
|
||
DC.L Done-(*+4)
|
||
DC.L Done-(*+4)
|
||
DC.L vAddVideoDevice-(*+4)
|
||
DC.L vRegisterVideo-(*+4)
|
||
DC.L vRemoveVideo-(*+4)
|
||
DC.L Done-(*+4)
|
||
DC.L vDockingSleepDenied-(*+4)
|
||
DC.L vDockingWakeupDenied-(*+4)
|
||
DC.L PrattDockingFilter-(*+4)
|
||
DC.L GracefulShutdown-(*+4)
|
||
DC.L 0
|
||
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: PrattDockingFilter
|
||
;
|
||
; Inputs: D0 - docking attributes returned by the bar
|
||
; A2 - pointer to Docking Manager's globals
|
||
;
|
||
; Outputs: D0 - filtered docking attributes
|
||
;
|
||
; Trashes: D1,D2,A0,A1
|
||
;
|
||
; Function: Filters the docking attributes so we can decide how to behave depending on what kind
|
||
; of system software support we have. The Display Manager is (currently) a disk thing,
|
||
; so we’ll patch this filter out on disk if the Display Manager is around, otherwise
|
||
; we don’t allow sleeping if external video is enabled.
|
||
;
|
||
; Note: This filter differs from the “standard” filters in that we don’t need to check
|
||
; for the case where the LCD screen isn’t useable (since all-in-one PowerBooks
|
||
; don’t “dock” per se), and since Pratt is ’040 based, the FPU doesn’t matter.
|
||
; (I believe that the FPU won’t matter for the PowerPC case, either.)
|
||
;__________________________________________________________________________________________________
|
||
|
||
PrattDockingFilter
|
||
MOVE.L D0,-(SP)
|
||
MOVE.L #dockHardwareAttr,D0 ; get the hardware attributes
|
||
BSR DockStatus
|
||
MOVE.L D0,D1
|
||
MOVE.L (SP)+,D0
|
||
BTST #dockSleepAddition,dockingFlags(A2) ; is this a startup or wakeup case?
|
||
BEQ.S @Startup ; -> wakeup
|
||
SWAP D1 ; use the wakeup hardware attributes
|
||
@Startup ANDI.W #(1<<dockHasVideo),D1 ; does this bar have video?
|
||
BEQ.S @Done ; -> no
|
||
BSET #dockNoSleep,D0 ; yes, we don't let it sleep
|
||
@Done RTS
|
||
|
||
;__________________________________________________________________________________________________
|
||
;
|
||
; Routine: CheckBarChangedPratt
|
||
;
|
||
; Inputs: A2 - pointer to Docking Manager's globals
|
||
;
|
||
; Outputs: CCR - BNE: bar has changed
|
||
;
|
||
; Trashes: A0, D0
|
||
;
|
||
; Function: Since the “bar” on Pratt-based CPUs is built-in, the Docking Handler would never be
|
||
; swapped out. So, we now call the Docking Handler to ask it if the world changed.
|
||
; If it did, then “BNE”.
|
||
;__________________________________________________________________________________________________
|
||
|
||
CheckBarChangedPratt
|
||
Bsr.s DockingDispatchExists ; If DockingDispatch is around,
|
||
Bne.s @CallHandler ; then call the Docking Handler.
|
||
Moveq #0,D0 ; Otherwise, just say things are okay.
|
||
Rts ; And Vamoose.
|
||
@CallHandler
|
||
Move.l #(1<<dockWorldChanged),D0 ; Inform the Docking Handler that we
|
||
Movea.l D0,A0 ; …want to know if the world changed.
|
||
Move.l #dockInit,D0 ; The Docking Handler will return
|
||
Bsr.s DockControl ; #(1<<dockWorldChanged) if so.
|
||
Rts
|
||
|
||
ENDIF ; {hasPratt}
|
||
|
||
|
||
ENDWITH
|
||
|
||
END
|