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