mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2026-03-12 05:42:13 +00:00
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.
6210 lines
227 KiB
Plaintext
6210 lines
227 KiB
Plaintext
;
|
||
; File: PowerMgr.a
|
||
;
|
||
; Contains: 680x0 Interface to the Power Manager.
|
||
;
|
||
; Written by: Mike Hanlon
|
||
; Remangled by Portable Terror Squad
|
||
;
|
||
; Copyright: © 1986-1993 by Apple Computer, Inc. All rights reserved.
|
||
;
|
||
; This file is used in these builds: ROM
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <SM10> 12/13/93 PN Roll in KAOs and Horror changes to support Malcom and AJ
|
||
; machines.
|
||
; <SM9> 9/1/93 SKH Rolled in from Horror. The old supermario copy of PowerMgr was
|
||
; hopelessly out of date, this is an almost straight copy of the Horror
|
||
; version.
|
||
; <H97> 6/24/93 SWC Clear the Ôdisable hard disk spindownÕ flag before calling the
|
||
; spindown routine so that the hard disk really does get turned
|
||
; off.
|
||
; <H96> 6/22/93 SWC Fixed a bug that causes a crash when getting ADB packets (when a
|
||
; timeout occurred, it was jumping to the wrong label).
|
||
; <H95> 6/21/93 SWC Changed the bit ordering in the modem info selectors and munged
|
||
; the SetWakeupTimerEnable into that mess. Get/SetWakeupTimer now
|
||
; take a record containing the wakeup time and an enable flag.
|
||
; <H94> 6/16/93 SWC The polarity of the hasInternalModem bit in the modem info
|
||
; selector was backwards, mainly because the PRAM bit,
|
||
; UseIntrnlModem, is set to 1 when using an EXTERNAL modem. Added
|
||
; a Ôwakeup on ringÕ bit to the modem info selector. Added a new
|
||
; selector to set/clear the Ôwakeup on ringÕ bit. Changed the
|
||
; default SCSI Disk Mode address from 1 to 2 so it doesn't
|
||
; conflict with the ID of a built-in hard disk in a DuoDock.
|
||
; <H93> 6/2/93 SWC Rolled in the modem type entry in the PowerDispatch hook from
|
||
; Excelsior. Added the modem type to the modem info selector on
|
||
; the public dispatch. Copied the public dispatch vector table
|
||
; into RAM.
|
||
; <H92> 6/1/93 SWC Only run the reduced speed routines if that feature is supported
|
||
; on a particular machine. Filled in the FactoryDisp entry in the
|
||
; PowerDispatch table wth a stub so that the RAM-based table gets
|
||
; built correctly.
|
||
; <H91> 5/31/93 RLE change set/getmachineid to set/getmachineattr (this way PG&E
|
||
; won't need to be updated for each and every new machine)
|
||
; <H90> 5/28/93 SWC Moved the absolute battery voltage from private to public
|
||
; dispatch. Added several new selectors to the public dispatch.
|
||
; <H89> 5/5/93 SWC Moved RunHardDiskQueue into the hard disk spindown routine so
|
||
; that it will only be called when the hard disk will really be
|
||
; spun down. Fixed a bug in SelectIntModem: it was always
|
||
; selecting the external modem.
|
||
; <H88> 5/4/93 SWC Allocated a buffer for reading/writing PRAM since the old buffer
|
||
; (a PMgr command parameter block) isn't available anymore. Always
|
||
; clear the NTSC low-mem so we'll get square corners on the main
|
||
; screen and menu bar.
|
||
; <H87> 5/4/93 SWC Made sure HardDiskQInstall/Remove return zero if no error.
|
||
; <H86> 5/4/93 SWC Added include of PowerMgrDispatchEqu.a. Added code to
|
||
; SetProcessorSpeed to allow for dynamically switching the
|
||
; processor speed on machines that support this feature.
|
||
; <H85> 4/23/93 SWC Moved the new PowerDispatch selectors down one in the table
|
||
; because #12 was used by the factory and patched in on disk.
|
||
; <H84> 4/22/93 RLE for SetMachineID/GetMachineID, force the count to be sent as
|
||
; part of the message packet
|
||
; <H83> 4/21/93 SWC Changed all routines that reference the primitives tables to
|
||
; assume that they exist instead of checking for a nil pointer.
|
||
; The initialization code will now hang if a table hasn't been set
|
||
; up. Added some more info to the modem info selector, and two new
|
||
; selectors to deal with disabling hard disk spindown. Added a new
|
||
; selector to _PowerDispatch to return a bitmap of private Power
|
||
; Manager features.
|
||
; <H82> 4/19/93 SWC Changed the primitives table initialization since there's now a
|
||
; vector to it in the ProductInfo table. Added new
|
||
; _PowerMgrDispatch selectors. Moved DoSpinDown here from
|
||
; SCSIMiscPatch.a.
|
||
; <H81> 4/16/93 SWC Pass the pointer to the queue element into the hdProc in
|
||
; RunHardDiskQueue
|
||
; <H80> 4/15/93 SWC Added in support for the public Power Manager interface trap,
|
||
; PowerMgrDisp ($A09E).
|
||
; <H79> 4/14/93 RLE add commands to set and get cutoff voltage
|
||
; <H78> 3/29/93 RLE add SetMachineID/GetMachineID commands to provide a mechanism to
|
||
; inform microcontroller what machine it might be running on; do
|
||
; SetMachine command as part of InitPmgrVars, but move part of the
|
||
; routine into MorePmgrInit to fit within the patch space
|
||
; <H77> 03-11-93 jmp Rolled back to the <H74> rev because we now handle the turning
|
||
; on/off the CSC in the CSCPrimaryInit.
|
||
; <H76> 3/9/93 RLE in the Power1Control call, add a 50 msec delay after powering up
|
||
; the CSC's PNLPWR output to allow it to fully charge
|
||
; <H75> 3/5/93 RLE add Power1Cntl and Power1Read to list of pmgr commands not
|
||
; entirely supported by PG&E microcontroller
|
||
; <H74> 3/3/93 RLE toss <H73> and prepare to do the LCD screen save/restore in the
|
||
; driver instead of in the power manager
|
||
; <H73> 2/24/93 RLE change InitPmgrPrimitives to support multiple table entries for
|
||
; a given decoder type
|
||
; <H72> 8/10/92 ag Fixed (aX,aY.w) addressing problem in serial power. aY being
|
||
; only size word does not allow for large movement of the
|
||
; primitives record (such as into ram).
|
||
; <H71> 8/4/92 ag Fixed (aX,aY.w) addressing problem. aY being only size word does
|
||
; not allow for large movement of the primitives record (such as
|
||
; into ram).
|
||
; <H70> 8/3/92 SWC ag/IdleMind wasn't using a long table offset. This causes a
|
||
; problem if the table is moved to RAM for patching.
|
||
; <H69> 7/31/92 SWC Backed out <H68> and instead just set D0=0 on exit of Wakeup.
|
||
; <H68> 7/30/92 SWC Added D0 to the list of SleepRegs so that the original sleep
|
||
; type will be returned on exit.
|
||
; <H67> 7/29/92 SWC Added a new call in the wakeup code to make sure we have the
|
||
; appropriate AppleTalk connection selected. This mostly applies
|
||
; to a docking environment where available SCC ports may change
|
||
; during sleep.
|
||
; <H66> 7/16/92 HJR In WakeUp move the SetSupervisorMode to the very end so that we
|
||
; can run on the UserStack. Since the interrupt stack is smaller,
|
||
; this fixes a problem where PaintBehind overflows the stack doing
|
||
; region calls.
|
||
; <H65> 7/14/92 ag Initialize the shorted battery alert delay if the charger is
|
||
; installed at powerup.
|
||
; <H64> 7/13/92 SWC In Wakeup, added a call to SCSIDiskWakeAlert to put up a
|
||
; DeepShit alert if the user has a SCSI Disk Mode cable plugged in
|
||
; when we wake up from sleep.
|
||
; <H63> 7/13/92 HJR Cleaned-up PowerMgrHook a little bit.
|
||
; <H62> 7/13/92 ag Rewrote the battery interrupt handler. Added new subhandlers to
|
||
; handle the battery shorted interrupt and the changer state
|
||
; change interrupt. Added new constants to the primitive
|
||
; infotable for delay of shorted battery dialog and delta battery
|
||
; warn level when using an external monitor.
|
||
; <H61> 7/11/92 ag Changed SecondaryInitDisp to PowerMgrHookDisp. The selector is
|
||
; now a general purpose selector with data passed in the upper
|
||
; word of d0. Added 3rd level dispatch table for PowerMgrHookDisp.
|
||
; Added scsi disk mode handler, and external monitor on handler.
|
||
; <H60> 7/11/92 HJR Changed the name of WakeScrnPtr to ScreenRedrawPtr and slightly
|
||
; modified the RestoreScreen routine.
|
||
; <H59> 7/10/92 ag Added softpower vector support. Created modem primitives, so
|
||
; moved all the serial overpatch stuff and part of the serial
|
||
; power stuff to PowerMgrPrimitives.a. With the new space in the
|
||
; serial power section moved the modem sound int stuff back to
|
||
; it's original location.
|
||
; <H58> 7/1/92 ag Add new modem commands to the dartexception table. ($71,$79).
|
||
; Commented command ($5D) as a general purpose modem command which
|
||
; is modem dependent.
|
||
; <H57> 7/1/92 SWC Disable level 3 modem interrupts as well as level 1 PMGR
|
||
; interrupts on DBLite. Put a line back into InitPMgrVars to clear
|
||
; the PMGR interrupt bit in the IFR (this seems to have been lost
|
||
; in the course of changes).
|
||
; <H56> 6/30/92 HJR Moved ADBReInit earlier in WakeUp so that user will have cursor
|
||
; feedback in wake.
|
||
; <H55> 6/29/92 GMR Updated a couple of the PMGROp modem cmd/reply counts in the
|
||
; tables.
|
||
; <H54> 6/26/92 GMR Added another modem command (SetDAAID) to the PmgrOp command
|
||
; table.
|
||
; <H53> 6/25/92 djw Fixed a bug in SerPowerOff (found by Steve Christensen) where
|
||
; the data length was not being set calling the _PmgrOp. The
|
||
; result was 5v was not being turned off to the modem.
|
||
; <H52> 6/18/92 SWC Setup PMgrOp to use vectors to make patching easier. These are
|
||
; now initialized in InitPMgrVars. Also in PMgrOp, don't point to
|
||
; the SCC if no PollProc is installed to avoid overflowing the
|
||
; stack when AppleTalk is running on port A (lotsa bytes stashed).
|
||
; Added a low power warning flag to IdleMind so we can tell that's
|
||
; why we're going to sleep.
|
||
; <H51> 6/11/92 djw Removed code to post a video warning message from PSecondaryInit
|
||
; because it did not take into account video waking from sleep
|
||
; case.
|
||
; <H50> 6/4/92 SWC Temporarily changed the reply count for the battery info command
|
||
; ($6D) until the PG&E code is updated to fix a bug.
|
||
; <H49> 6/2/92 SWC Fixed a bug I introduced in <H46>.
|
||
; <H48> 6/1/92 HJR Initialized PmgrRec.Charger in InitPmgrVars. Provided support in
|
||
; PSecondaryInit for external video warning if no charger
|
||
; installed.
|
||
; <H47> 5/29/92 SWC When waking up, check if a docking bar was attached that's not
|
||
; supposed to be attached during sleep, and if so, put the machine
|
||
; back to sleep.
|
||
; <H46> 5/28/92 SWC In NewPMgrTrap, A0 was trashed when we checked if we needed to
|
||
; delay for a power control command. It isn't anymore.
|
||
; <H45> 5/27/92 SWC Converted changes in <H44> into overpatches cuz as written they
|
||
; caused code to move (ROMBind problems in system disk patches).
|
||
; <H44> 5/20/92 ag Added DartSPI flag code to enable and disable the SPI interface
|
||
; depending on the modem connected.
|
||
; <H43> 5/19/92 HJR Added new selector, PDimScreens, to PowerDispatch Trap and added
|
||
; accompanying routine which powers down video. Changed
|
||
; HdDSpinDown to RunIdleRoutines, a more generalized routine.
|
||
; <H42> 5/15/92 SWC Added PMGR diagnostics (selector-based) command ($ED) entry to
|
||
; send and receive tables. Moved SndWatch, SndWatchPonti to
|
||
; PowerManagerPrimitives as yet another primitive, and fixed
|
||
; InitPMgrVars to look up the addresses from the primitives table.
|
||
; Sound VBLs are no longer installed by secondary init dispatch,
|
||
; since the sound VBLs check to make sure that patches are
|
||
; installed before calling the sound input primitives. Changed the
|
||
; way the PMgrOp exception table is set up to make the search
|
||
; faster.
|
||
; <H41> 5/12/92 ag Added secondary init dispatch routine for code execution at
|
||
; secondary init time. Removed sound primitives check for sound
|
||
; vbl code, vbl now installed at secondary init time. All patches
|
||
; should be in by then. Added Dart exception table for SPI. Moved
|
||
; init of softshutdown vars to secondary init code.
|
||
; <H40> 5/8/92 ag Fixed SoundPonti to check expand mem vector before using the
|
||
; vector.
|
||
; <H39> 5/8/92 ag Added dartanian busy check to NewPmgrTrap.
|
||
; <H38> 5/8/92 HJR Added new primitive for refreshing the screen from wake.
|
||
; <H37> 5/7/92 ag Added soft shutdown for Dartanian. Rolled in Modem sound
|
||
; patches. Added busy check in power manager protocal.
|
||
; <H36> 5/7/92 SWC Added a check in IdleMind to bail on sleeping if sleep is not
|
||
; allowed because of the kind of bar that's attached (avoids a
|
||
; dialog). Moved the beginning and end parts of NewPMgrTrap around
|
||
; a bit so I could add SCC polling to the delay loop for power
|
||
; control commands. Added a new selector to PowerDispatch to
|
||
; return a scaled battery level.
|
||
; <H35> 4/27/92 ag Added new sound watch to use registers in Ponti to control sound
|
||
; power.
|
||
; <H34> 4/24/92 HJR Fix some alignment problems.
|
||
; <H33> 4/24/92 HJR Added new SndWatchPtch to handle DFAC activity. Changed
|
||
; CheckForNewPMgr so the Niagra uses new PMgrTrap. Fixed
|
||
; Handle_Element bug where a QueueProc element returning error
|
||
; would still cause the machine to sleep.
|
||
; <H32> 4/22/92 SWC In GoToSleep, changed the BTST to a BSET to block re-entry into
|
||
; the sleep code earlier on in the process, and removed the BSET
|
||
; in DreamAway (duplication). Added a call to DockingSleepDenied
|
||
; (DockingMgr.a) if someone tries to put the system to sleep when
|
||
; connected to a bar that doesn't want that to happen.
|
||
; <H31> 4/17/92 SWC Fixed bugs in the power control/status emulation routines that
|
||
; sometimes cause the wrong information to be returned.
|
||
; <H30> 4/13/92 SWC Changed the table entry for "send DFAC command" to 2 bytes since
|
||
; we need to pass a byte for the input source as well so the PMGR
|
||
; can switch the MUX. Changed the readBattery command emulation to
|
||
; return a scaled battery level instead of maximum since we now
|
||
; check for the existance of a battery in the battery monitoring
|
||
; routine. Fixed a bug in InitPmgrPrimitives (hysteresis was
|
||
; being copied into a byte instead of a word).
|
||
; <H29> 3/11/92 SWC In InitPmgrVars, get the address of the power cycle register
|
||
; from the primitives table instead of a chain of TestFors.
|
||
; Installed a VBL task (for machines that support it) to monitor a
|
||
; clamshell switch so we can put the machine to sleep or shut it
|
||
; down. In Wakeup, always do an ADBReInit since new cursor stuff
|
||
; needs this to handle adding devices across sleep. Renamed
|
||
; JawsPwrCycReg to PowerCycleReg since non-Jaws machines use it
|
||
; too.
|
||
; <H28> 3/9/92 SWC Fixed the receive count for the PMGR soft reset command.
|
||
; <H27> 3/3/92 SWC Exported GetLevel for use in the SCSI DiskMode code.
|
||
; <H26> 2/26/92 SWC In NewPMgrTrap, fixed register usage and saving relating to
|
||
; polling the SCC since some registers aren't setup right, and
|
||
; others are getting trashed by the PollProc. Added a 125usec
|
||
; delay to the end of NewPMgrTrap on powerCntl calls to give the
|
||
; power planes a chance to stabilize.
|
||
; <H25> 2/21/92 HJR Cleaned up InitPmgrVars a bit. Fixed Batwatch to utilize to 3
|
||
; battery levels instead of 4. Also added sleep hysteresis to
|
||
; batwatch. Fixed reentrancy problem with sleep.
|
||
; <H24> 2/19/92 SWC Fixed the Wakeup padding (off by 2 bytes).
|
||
; <H23> 2/17/92 SWC Added docking checks to see if power cycling and/or sleep are
|
||
; allowed when we're connected to certain bars on DBLite.
|
||
; <H22> 2/14/92 SWC Added docking support to power control/status emulation on
|
||
; DBLite.
|
||
; <H21> 2/13/92 SWC Moved an emulated command in the table. Fixed a typo.
|
||
; <H20> 2/13/92 SWC Fixed a patch that the assembler had optimized to make 2 bytes
|
||
; shorter (I specified BSR.W, I got BSR.S).
|
||
; <H19> 2/10/92 SWC Added a new PowerDispatch selector to return the base Power
|
||
; Manager PRAM address so our clients won't have to go looking
|
||
; thru our globals.
|
||
; <H18> 2/7/92 SWC Write out default low/dead battery warning levels if the values
|
||
; read aren't valid. Default values now come from the ever popular
|
||
; primitives info table.
|
||
; <H17> 2/7/92 SWC Modified other places that reference Power Manager PRAM bytes to
|
||
; use the base address in the globals. Removed old HcMac code cuz
|
||
; it's confusing and more than likely won't be used again.
|
||
; <H16> 2/5/92 SWC Fixed a cut and paste boo-boo in <H15>.
|
||
; <H15> 2/5/92 SWC Moved a couple of the PMGR battery commands down in the tables
|
||
; since they were stomping on a pre-existing command. Changed how
|
||
; we get the low battery warning and dead battery levels from
|
||
; reading them from PRAM to using a specific command (available
|
||
; from the TIM days and carried on by DBLite).
|
||
; <H14> 2/4/92 SWC Adjusted padding since some stuff has moved a bit (wreaks havoc
|
||
; with patches). Re-wrote the sleep and wakeup code to use
|
||
; primitives tables to determine what needs to be done.
|
||
; <H13> 2/3/92 HJR Added support for PowerManagerPrimitives. Use PmgrPrim for
|
||
; default PRAM base, new IdleMind, and new CPUSpeed. Fixed
|
||
; HandleElement improperly aborting when encountering non-zero
|
||
; sleep queue return in DemandSleep.
|
||
; <H12> 1/28/92 SWC Did a bit of re-ordering in InitPMgrPatch2 to reduce the
|
||
; possibility of a race condition in clearing any unexpected PMGR
|
||
; interrupts.
|
||
; <H11> 1/27/92 SWC Updated NewPMgrTrap's transfer tables for new commands.
|
||
; <H10> 1/24/92 SWC Fixed the code to save/restore GSC registers over sleep. The new
|
||
; PMgrOp code (for DBLite) now uses only a 32ms timeout instead of
|
||
; having both long and short timeouts, so that when PG&E gets
|
||
; multiple interrupts we won't time out while waiting for it to
|
||
; respond.
|
||
; <H9> 1/9/92 SWC Rolled in changes for final chips: removed special case checks
|
||
; for PMGR interrupts on CA2 (now on CB1), extend DB-Lite's CPU
|
||
; speed code to support 25MHz/33MHz versions plus econo-mode.
|
||
; Added _PMgrOp emulation for SCSI and SCC clock control/status to
|
||
; the power control/status commands since these functions are now
|
||
; handled by the MSC. Save and restore GSC registers in the sleep
|
||
; code for DB-Lite.
|
||
; <H8> 10/29/91 SWC Cleared the interrupt flag before doing a blind interrupt read
|
||
; in InitPMgrPatch to make sure it isn't left in a weird state.
|
||
; Did miscellaneous cleanup in NewPMgrTrap. Turn on/off the
|
||
; serial driver chips as well as the SCC in SerialPower.
|
||
; <H7> 10/22/91 SWC Changed SCC polling in NewPMgrTrap to look at the SCC directly
|
||
; instead of using the VIA bit. Changed references to NoVRAMVidRam
|
||
; to point to the end of the record since the offsets are
|
||
; negative.
|
||
; <H6> 9/10/91 SWC Set battery voltage for ReadBattery emulation at maximum for
|
||
; now. Fixed the returned byte counts for the set/read sound
|
||
; emulated routines.
|
||
; <H5> 8/27/91 SWC Fixed the [temporary] jump to OneSecInt so that it instead jumps
|
||
; 6 bytes into the routine so the VIA's IFR is not cleared a
|
||
; second time. Depending on when one-second and ADB interrupts
|
||
; came along, it was possible to lose an ADB interrupt if it
|
||
; occurred just before the IFR bit was cleared in OneSecInt.
|
||
; <H4> 8/26/91 SWC Added Set Screen Brightness command ($41) to the command tables.
|
||
; <H3> 8/22/91 SWC Added in a call to the one-second interrupt handler from the
|
||
; PMgrInt. Vectored the send and receive count tables for
|
||
; NewPMgrTrap so we can make changes and additions without having
|
||
; to roll the ROM.
|
||
; <H2> 8/8/91 SWC Added universal PMgrOp code which will run on any Power
|
||
; Manager-based system. Universalized PMGR interrupt setup.
|
||
; Fixed sleep/wakeup sound chip register saving so Batman-specific
|
||
; registers are only saved if we've got a Batman. Added an MSC
|
||
; entry to the CPUSpeed routine. Added DB-Lite support to the
|
||
; sleep code. Fixed an unpatchable bug in InitPMgrVars that was
|
||
; found after TERROR was frozen (it just requires moving an
|
||
; instruction down).
|
||
; ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
; Pre-HORROR ROM comments begin here.
|
||
; ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
; <40> 7/11/91 HJR Call HDSpinDown in sleep if HDSpindownflag is not clear and on
|
||
; wakeup move KdbReset before interrupts are enabled. Also added
|
||
; SleepHook and WakeUpHook to sleep code, and vectorized ModemSnd
|
||
; Routines in PMgrGlobals.
|
||
; <39> 7/9/91 HJR Added CPUSpeed to PowerDispatch Trap and set SaveSpeedo to
|
||
; appropriate speed in InitPMgrVars.
|
||
; <38> 7/7/91 HJR Add some more reset for the progressive power cycling.
|
||
; <37> 7/3/91 HJR Fix VM powercycling problem by restoring the VBR if we decide to
|
||
; skip power cycling due to character pending on SCC.
|
||
; <36> 6/25/91 HJR Updated IdleMind to reset progressive power cycling
|
||
; appropriately. Fixed bug in PowerCycling030 and PowerCycling020
|
||
; to set AutoInt7 appropriately.
|
||
; <35> 6/25/91 ag added hysteresis low power value to power manager globals.
|
||
; <34> 6/25/91 HJR Set cursor to a watchcursor when going to sleep and fix a bug in
|
||
; IdleDelay where a BGE should have been a BLE.
|
||
; <33> 6/24/91 HJR Individually test SlpTimeOut and HDTimeOut for zero in
|
||
; InitPmgrVars. Determine whether running on '020 or '030 at
|
||
; InitPmgrVar and load appropriate power cycling code. Added
|
||
; IdleRead, IdleEnable, and IdleDisable to the list of
|
||
; PowerDispatchVectors and rewrote IdleState to use these new
|
||
; routines.
|
||
; <32> 6/24/91 djw Moved init code for notification mgr record from InstallMsg to
|
||
; InitPmgr. Added code to install and remove message in case of a
|
||
; bad battery condition interrupt from power mgr. Removed modem
|
||
; sound int handler from InitPmgr. Add support to disable posting
|
||
; notification messages for low power. Fixed bug in SerPowerOff
|
||
; and external ports. Added code to call LAPMgr for status of
|
||
; port B.
|
||
; <31> 6/12/91 ag changed the default of the network check to sleep.
|
||
; <30> 6/12/91 ag added network warning override bit in PmgrFlags.
|
||
; <29> 6/11/91 HJR Parameterized progressive power cycling with PwrCycProgGrow and
|
||
; PwrCycProgMax in PMgrRec. Fixed bug in Installmsg where stack
|
||
; was corrupted if message string was null.
|
||
; <28> 6/11/91 djw Fix modem sound support using VIA interrupt handlers.
|
||
; <27> 6/9/91 HJR Used new Default equates in InitPMgrVar for Power Cycling. Fixed
|
||
; bug in checking whether there has been enough elapsed time
|
||
; before power cycling. Added IdleDelay to PowerDispatch in order
|
||
; to improve IO performance. Modified the Batman saving and
|
||
; restoring from sleep so that the registers are written out in
|
||
; appropriate order. Cleared the Sound Latch after restoring from
|
||
; sleep to hopefully kill the buzzing sound while waking up.
|
||
; <26> 5/31/91 djw Add modem sound interrupt routines and install them in
|
||
; _SerialPower
|
||
; <25> 5/23/91 HJR Returned to a more universal power cycling scheme. Added include
|
||
; for PowerPrivEqu.a. Removed WaitStates sleep queue element since
|
||
; problem is now solved in hardware, HOPEFULLY!
|
||
; <24> 5/10/91 HJR Removed references of ResetSP since it is now saved in
|
||
; PMgrGlobalsRec. Changed PMgrTrap to call PollProc before
|
||
; interrupts re-enbled. Correct problem VM/NMI bug by setting and
|
||
; restoring NMIvector to the restore code during power cycling.
|
||
; <23> 4/29/91 HJR Added semaphor for power-up conditions in power cycling. Made
|
||
; sleep more universal by calculating the video-ram space from
|
||
; universal instead of using hard-coded addresses.
|
||
; <22> 4/23/91 ag switch back to supervisor mode on exit of sleep.
|
||
; <21> 4/23/91 ag alerts must be run in user mode! so we moved the restore to
|
||
; user mode earlier.
|
||
; <20> 4/22/91 ag Fixed missing dereference in data structure.
|
||
; <19> 4/16/91 HJR Somebody forgot to add a semicolon to the comment part of their
|
||
; line!
|
||
; <18> 4/15/91 ag added sound vbl code to turn off power to the sound circuits if
|
||
; not in use.
|
||
; <17> 4/12/91 ag changed the location of "insleep" flag in the power manager
|
||
; locals. Changed name of pram flags to avoid conflict with
|
||
; reality sources.
|
||
; <16> 4/4/91 ag slight correction to test for null proc.
|
||
; <15> 4/4/91 ag fixed bug with sleep queue execution. added check for null proc
|
||
; pointer.
|
||
; <14> 4/3/91 HJR Restore DFAC state on sleep wakeup
|
||
; <13> 4/1/91 HJR Modified the switching from User Mode to Supervisor Mode so that
|
||
; interrupts may be enable prior to running the queue out of
|
||
; wakeup since .MPP needs them enabled. Save all necessary Batman
|
||
; sound registers.
|
||
; <12> 3/29/91 ag Removed power manager bus contention check. the protocal has
|
||
; been changed to just check for busy and retry. Also changed
|
||
; timeout to take the new retry protocal into account (extended
|
||
; timeouts).
|
||
; <11> 3/19/91 jmp Oops, sombody forgot to put a semicolon in front of a comment.
|
||
; <10> 3/19/91 HJR Restore SP during wakeup since JumpintoRom sets it. Changed
|
||
; register useage in InitPMgrVars since GetRealProc trashes
|
||
; d1/a1-a2.
|
||
; <9> 3/18/91 HJR Rolled in sleep changes from Reality. Moved sleep to Ram based
|
||
; instead of video for performance improvement. Made sure that
|
||
; all access to the Video storage is done when the MMU is off
|
||
; because of
|
||
; MMU wrap.
|
||
; <8> 2/18/91 HJR Added DebugUtil call in IdleMind and GotoSleep to set the
|
||
; machine into Supervisor mode so that VM will be happy.
|
||
; <7> 1/30/91 HJR Changed PwrCycleCount to be part of PwrMgrVars and initialized
|
||
; in InitPwrMgrVars.
|
||
; <6> 1/24/91 HJR Cleared the bus prior to entering into power cycling by writing
|
||
; a zero to rom space. Also changed the write to the Jaws
|
||
; register to a Move.l and hit the waitstate register coming out
|
||
; of powercycle.
|
||
; <5> 1/24/91 HJR Moved IdleMind from PwrControlPatches.a. Also rewrote
|
||
; PowerCycling code for speed improvements and MMU bug fixes.
|
||
; <4> 1/22/91 djw Replace SerPowerOn and SerPowerOff in SerialPower trap code to
|
||
; work with TIM and the TIM modem.
|
||
; <3> 1/15/91 HJR Add WaitSSleepTask and install code to InitPMgrVars
|
||
; <2> 12/11/90 HJR Updated to the latest PowerMgr interface.
|
||
; <2.2> 6/10/89 SWC Moved InitPmgrVars here from StartInit.a.
|
||
; <2.1> 4/13/89 MSH Removed level 3 low power warning.
|
||
; <2.0> 4/7/89 MSH Gave battery and environment interrupts new names. PmgrInt now
|
||
; uses vectors to dispatch to handlers. Clearing low battery bit
|
||
; removes any low power message. CloseATalk saves D2.
|
||
; <1.9> 3/31/89 MSH Power off turns off the modem, then the rest of power, then
|
||
; calls sleep. CloseATalk rewritten. DOQueue now knows about
|
||
; sleepnow. If more than two ADB devices in use then ADBReInit
|
||
; called at wake up. A sleepnow hides the cursor. Batterymon
|
||
; replaced with SndWatch and made a vbl task.
|
||
; <1.8> 3/14/89 MSH CloseAtalk needed to close MPP. Mild warning didn't close XPP.
|
||
; At WakeUp restart timers the right way. ReInit Normandy test
|
||
; register after sleep. Ignore ENV interrupt.
|
||
; <1.7> 3/10/89 MSH PowerOff does a SleepNow
|
||
; <1.6> 3/9/89 MSH Forgot to check for any mounted file servers when sleep time
|
||
; out.
|
||
; <1.5> 3/2/89 MSH Reset keymap when sleep called. Spin down and sleep time outs
|
||
; reduced to one value each. Low power warning resources are
|
||
; loaded into local memory at init. No low power warning may occur
|
||
; before system task gets called once. Some local storage use got
|
||
; proper equ names.
|
||
; <1.4> 2/8/89 MSH Added high temperature warning support, moved all hard disk and
|
||
; sleep time out to systemtask, low power warnings are now four in
|
||
; number. The last warning goes to sleep in ten seconds. Sleep now
|
||
; has request, demand, and now, the last is for low power
|
||
; condition. Before calling the sleep queue a check is made of the
|
||
; AppleTalk world and if any servers or other activity is present.
|
||
; If so the user is warned and given the option to undo sleep. A7
|
||
; is now saved in undisplayed video ram rather than in SERegs
|
||
; where it interfered with Macsbug. Make use of charger status
|
||
; bits to determine if charger connection state has changed.
|
||
; <1.3> 12/14/88 MSH Save and restore RAM wait state register, power off uses jump to
|
||
; startboot instead of RESET, kick on timer 1 after sleep.
|
||
; <1.2> 11/30/88 MSH Fixed the sound control stuff. Gave time out flags legit name.
|
||
; Save and restore speed from stack.
|
||
; <1.1> 11/10/88 CCH Fixed Header.
|
||
; <1.0> 11/9/88 CCH Adding to EASE.
|
||
; <2.2> 11/1/88 MSH Added a whole bunch of stuff. First, the sound watchdog is in
|
||
; and running. If no one hits on the ASC for ten seconds then the
|
||
; amplifier power is turned off. Also save and restore the ASC
|
||
; control registers at sleep. Second, the battery monitor and low
|
||
; power interrupt handler are in place. The user is alerted via
|
||
; the background notification manager of entering reserve power
|
||
; use, half reserve left, and a quarter of reserve power left. One
|
||
; SICN and three STR resources required on system disk. Last, the
|
||
; power off code called from the shutdown manager is found here.
|
||
; <2.1> 9/29/88 MSH Moved the reading of the charger state and time outs from the
|
||
; one second stuff to an interrupt routine. BatteryAlrt handles
|
||
; the charger connected state change interrupt from the power
|
||
; manager. BatteryMon checks the dirty time out data flag to see
|
||
; if it is necessary to update the time outs due to a change to
|
||
; them from the battery desk accessory.
|
||
; <1.9> 9/12/88 MSH Fixed bug in stack framse usage. One second interrupt now points
|
||
; to BatteryMon. BatteryMon first calls the one second interrupt
|
||
; then checks the state of the battery charger and the time outs.
|
||
; Screen saving no longer allocates memory.
|
||
; <1.8> 8/5/88 MSH Made WakeUp vectored. Added sleep q calling code.
|
||
; <1.7> 7/19/88 MSH Fixed potential stack error in PMGRInt. Save the state of the
|
||
; PMGR interrupt bit from VIA at entry and restore on exit. Also
|
||
; do more VIA save and restore at wake up.
|
||
; <1.6> 6/24/88 MSH Many revisions: Use pmgr local vars to save clock speed. Check
|
||
; for valid pmgr vars pointer before using it. Went back to
|
||
; original busy test of pmgr chip. Sleep command now has signature
|
||
; word sent with command. Removed InitIWM call, didn't actually do
|
||
; anything anyway. Temporarily removed call to ADBreInit and added
|
||
; kludge to keep old power managers auto polling after sleep.
|
||
; <1.5> 6/15/88 MSH Removed one too many SWAPs from PmgrDone. Also changed the test
|
||
; for pmgr ready to only use the upper half of the port.
|
||
; <1.4> 5/23/88 MSH Trashing speed code saved in upper half of D3 with a MOVEQ.
|
||
; <1.3> 5/19/88 BBM Changed two MOVEQs to MOVE.Ls as they were out of range
|
||
; <1.2> 4/21/88 MSH Fixed reset vector getting trashed when saving screen.
|
||
; <1.1> 3/28/88 BBM Made sure that this code runs at 16M. Blank screen before sleep.
|
||
; <1.0> 2/10/88 BBM Adding file for the first time into EASEÉ
|
||
; <C988> 12/21/87 MSH Exported GoToSleep for use by toolevents.
|
||
; <C984> 12/16/87 MSH Made start of handshake more tolerant of interrupts.
|
||
; <C937> 11/6/87 MSH Mask out PMGR interrupts while in PmgrOp.
|
||
; <C930> 11/5/87 MSH Rewrote PmgrInt to use new interrupt interface to PMGR.
|
||
; <C916> 10/21/87 MSH More of the same.
|
||
; <C915> 10/20/87 MSH Fixed some bugs, turned off interrupts while waiting for pmgr
|
||
; ack, and preserved sound bits that may be in VIA port A.
|
||
; 9/21/87 MSH New today.
|
||
;
|
||
|
||
BLANKS ON
|
||
STRING ASIS
|
||
|
||
PRINT OFF
|
||
LOAD 'StandardEqu.d'
|
||
INCLUDE 'HardwarePrivateEqu.a'
|
||
INCLUDE 'UniversalEqu.a'
|
||
INCLUDE 'PowerPrivEqu.a'
|
||
INCLUDE 'PowerMgrDispatchEqu.a'
|
||
INCLUDE 'Appletalk.a'
|
||
INCLUDE 'LAPEqu.a'
|
||
INCLUDE 'Notification.a'
|
||
INCLUDE 'IopEqu.a'
|
||
INCLUDE 'Egretequ.a'
|
||
INCLUDE 'AppleDeskBusPriv.a'
|
||
INCLUDE 'MMUEqu.a'
|
||
INCLUDE 'IOPrimitiveEqu.a'
|
||
INCLUDE 'DockingEqu.a'
|
||
INCLUDE 'GestaltEqu.a'
|
||
|
||
INCLUDE 'ROMEqu.a'
|
||
INCLUDE 'Slots.a'
|
||
PRINT ON
|
||
|
||
MACHINE MC68030
|
||
MC68881
|
||
|
||
|
||
Unimplement EQU $A89F ; _Unimplemented trap
|
||
|
||
|
||
|
||
PowerMngr PROC EXPORT
|
||
|
||
EXPORT InitPmgrVars
|
||
|
||
IF hasPwrControls THEN
|
||
EXPORT BatInt
|
||
EXPORT BatWatch
|
||
EXPORT GoToSleep
|
||
EXPORT PmgrInt
|
||
EXPORT PmgrOp
|
||
EXPORT PortableCheck
|
||
EXPORT PowerDispatch
|
||
EXPORT PowerDownAll
|
||
EXPORT SetSupervisorMode
|
||
EXPORT WakeUp
|
||
EXPORT PmgrTrap
|
||
EXPORT IdleUpdate
|
||
EXPORT IdleUpdateTrap
|
||
EXPORT IdleDelay
|
||
EXPORT IdleMind
|
||
EXPORT IdleRead
|
||
EXPORT IdleEnable
|
||
EXPORT IdleDisable
|
||
EXPORT IdleState
|
||
EXPORT CPUSpeed
|
||
EXPORT BasePRAM
|
||
EXPORT ScaledBattery
|
||
EXPORT PowerMgrHook
|
||
EXPORT PDimScreens
|
||
EXPORT PMGRrecv
|
||
EXPORT PMGRsend
|
||
EXPORT PrivateFeatures
|
||
EXPORT SecondaryInitproc
|
||
EXPORT SerialPower
|
||
EXPORT ScsiDiskModeproc
|
||
EXPORT ExternaVideoOnproc
|
||
EXPORT ModemTypeProc
|
||
EXPORT PowerMgrDispatch
|
||
EXPORT ModemStatusRT
|
||
EXPORT LCDScreenChk
|
||
EXPORT GetButtonValues
|
||
EXPORT SetHDState
|
||
|
||
IMPORT CacheFlush ; Dispatch.a
|
||
IMPORT DelayNMsec ; PowerMgrPrimitives.a
|
||
IMPORT DockingSleepDenied ; DockingMgr.a
|
||
IMPORT DockingWakeupDenied ; DockingMgr.a
|
||
IMPORT GetHardwareInfo ; Universal.a
|
||
IMPORT GetRealProc ; GetReal.a
|
||
IMPORT GracefulShutdown ; DockingMgr.a
|
||
IMPORT InitQueue ; Queue.a
|
||
IMPORT InitSCSIHW ; SCSIMgrInit.a
|
||
IMPORT InitWallyWorld ; WallyWorld.a
|
||
IMPORT RdXByte ; USTPram.a
|
||
IMPORT RSetKMap ; ADBMgr.a
|
||
IMPORT SCSIDiskWakeAlert ; SCSIDiskMode.a
|
||
IMPORT SetupTimeK ; StartInit.a
|
||
IMPORT USTPMgrSendByte ; USTStartUp.a
|
||
IMPORT USTPMGRSendCommand ; USTStartUp.a
|
||
|
||
WITH NMRec,PmgrRec,ADBVars,ADBDeviceEntry
|
||
WITH DecoderInfo,DecoderKinds,ProductInfo,VideoInfo,SpBlock
|
||
WITH pmCommandRec,SleepqRec,PowerCycleRec,PowerDispRec,PmgrPramRec
|
||
WITH PmgrPrimitivesRec,PmgrRoutineRec,PrimInfoTbleRec
|
||
WITH IdleMindTblRec,ModemTblRec,HDQueueElement
|
||
ENDIF
|
||
|
||
;¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥ Initialization ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
|
||
;
|
||
; Contains:
|
||
;
|
||
; InitPMgrVars
|
||
; SetUpPmgrBase
|
||
; SizeTables
|
||
; BuildTables
|
||
; InitPmgrGlobals
|
||
; InitPMgrOp
|
||
; DoPmgrCommands
|
||
; GetPmgrPRAM
|
||
; InstallVBLs
|
||
;________________________________________________________________________________________
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: InitPMgrVars
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: allocates and initialized system heap space for the Power Manager's variables,
|
||
; installs VBL tasks, etc.
|
||
;________________________________________________________________________________________
|
||
|
||
InitPmgrVars
|
||
IF hasPwrControls THEN
|
||
TestFor hwCbPwrMgr
|
||
BNE.S @DoPMgrInit ; IF pmgr exists THEN intall pmgr stuff
|
||
ENDIF ; {hasPwrControls}
|
||
|
||
LEA @Traps,A1 ; ELSE remove the PmgrOp and Sleep traps
|
||
MOVE.W (A1)+,D0 ; Get the Unimplimented trap location
|
||
_GetTrapAddress ,newTool ;
|
||
@TrapLoop ; WHILE !EndOfList DO {
|
||
MOVE.W (A1)+,D0 ; Get the next trap to remove
|
||
BEQ.S @exit ;
|
||
_SetTrapAddress ,newOS ; Replace the trap with the Unimplimented
|
||
BRA.S @TrapLoop ; } LOOP
|
||
@exit ;
|
||
RTS ; EndELSE
|
||
|
||
@Traps _Unimplemented
|
||
_PmgrOp
|
||
_PowerDispatch
|
||
_Sleep
|
||
DC.W 0
|
||
|
||
IF hasPwrControls THEN
|
||
|
||
@DoPMgrInit
|
||
@WorkingSet REG D0-D3/A0-A3
|
||
MOVEM.L @WorkingSet,-(SP) ; save them regs
|
||
|
||
BSR SetUpPmgrBase ; set up the PMgr Globas A3 = PmgrGlobals
|
||
BSR InitPmgrGlobals ; Initialize our primitives table
|
||
BSR InitPMgrOp ; Initialize variables used by PMgrOp
|
||
BSR DoPmgrCommands ; Initialize variables through the PMgrOp Call
|
||
|
||
BSR DoDynamicSpeedChange ; Initialize timing constants for full/reduced speed
|
||
BSR GetPmgrPRAM ; Initialize variables through PRam
|
||
|
||
LEA SleepQHdr(A3),A1 ; init sleep queue
|
||
BSR.L InitQueue ; go do it
|
||
|
||
BSR InstallVBLs ; Install our VBLs
|
||
; BSR.L HandleChargeTime ; setup for bulk charge extension
|
||
|
||
LEA PMGRInt,A0 ; get addr of PMGR interrupt handler
|
||
MOVE.L A0,Lvl1DT+(4*ifCB1) ; install as PMGR interrupt receiver
|
||
|
||
BSR ResetPMGRInts ; clear any pending PMGR interrupts
|
||
MOVEM.L (SP)+,@WorkingSet ; restore them regs
|
||
RTS
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: SetUpPmgrBase
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: A3 - Ptr to PmgrGlobals
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: Determines the appropriate size of the PmgrGlobals section. It takes as a base
|
||
; the PmgrVarSize and walks through the primitives table and sums up there sizes.
|
||
;________________________________________________________________________________________
|
||
SetUpPmgrBase
|
||
@WorkingSet REG D0/A0-A2
|
||
MOVEM.L @WorkingSet,-(SP) ; Save them regs
|
||
MOVEA.L UnivInfoPtr,A1 ; point to the ProductInfo table
|
||
ADDA.L PowerManagerPtr(A1),A1 ; then to the Power Manager's primitives
|
||
MOVE.L #PmgrVarSize,D0 ; Start with the Vars Size
|
||
BSR SizeTables ; Size the table for new ptr
|
||
_NewPtr ,SYS,CLEAR ; allocate space on heap and clear
|
||
MOVE.L A0,PmgrBase ; save ptr to it
|
||
LEA PmgrVarSize+8(A0),A2 ; get the vPrimitives pointer
|
||
MOVE.L A2,vPMgrPrimitives(A0) ; set the vPMgrPrimitives vector
|
||
MOVEA.L A2,A0 ; set pointer to beginning of our memory chunk
|
||
BSR BuildTable ; build table
|
||
BSR.L CacheFlush ; flush caches to be safe
|
||
MOVE.L PmgrBase,A3 ; A3 = Ptr to PmgrGlobals
|
||
|
||
MOVEQ #4/4,D0 ; get the size of the public dispatch table
|
||
ADD.W PwrMgrDispVects-2,D0 ;
|
||
ASL.L #2,D0 ;
|
||
_NewPtr ,SYS ; and allocate space for it in the system heap
|
||
BNE.S @GetOut ; -> errors aren't allowed
|
||
|
||
LEA PwrMgrDispVects-4,A1 ;
|
||
MOVE.L (A1)+,D0 ; get the flags and routine count
|
||
MOVE.L D0,(A0)+ ; and copy them to RAM
|
||
MOVE.L A0,vPublicDispatch(A3) ; save the pointer to the start of the table
|
||
MOVE.L A1,D1 ; remember where the table starts in ROM
|
||
SUBQ.W #1,D0 ; adjust the count for the DBRA
|
||
@CopyPublic MOVE.L (A1)+,(A0) ; copy the routine offset into RAM
|
||
ADD.L D1,(A0)+ ; and convert it into an address
|
||
DBRA D0,@CopyPublic ; next entry
|
||
@GetOut
|
||
MOVEM.L (SP)+,@WorkingSet ; Restore them regs
|
||
RTS
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: SizeTables
|
||
;
|
||
; Inputs: A1 - Pointer to top of table
|
||
; D0 - Initial size of to be incremented
|
||
;
|
||
; Outputs: D0 - Incremented Size of Table
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: Determines the appropriate size of the tables.
|
||
;________________________________________________________________________________________
|
||
SizeTables
|
||
@WorkingSet REG D1-D3/A1-A2
|
||
|
||
MOVEM.L @WorkingSet,-(SP) ; save them registers
|
||
|
||
MOVE.L -8(A1),D1 ; get the flags
|
||
ANDI.L #PrimsTypeMask,D1 ; mask out all but last two bits
|
||
MOVE.W @EntryType(D1.W*2),D1 ; get the offset to that routine
|
||
JMP @EntryType(D1) ; go to that routine
|
||
|
||
@Table ; Size a Table of Tables
|
||
MOVE.L -4(A1),D1 ; setup dbra counter
|
||
LSR.L #2,D1 ; arrange it as long word entries
|
||
MOVEA.L A1,A2 ; A2 = Beginning rom base of table
|
||
ADD.L -4(A1),D0 ; increment for size of table
|
||
ADDQ #8,D0 ; account for the size byte and the flags
|
||
MOVEQ #0,D2 ; clear the register
|
||
@TblLoop ; FOR 0 to MaxNum DO
|
||
MOVE.L (A2,D2.L*4),D3 ; get the offset of the first routine
|
||
BEQ.S @NilValue ; if offset = 0 then bail
|
||
LEA (A2,D3.L),A1 ; get pointer to table
|
||
BSR SizeTables ; build the table
|
||
@NilValue ADDQ.L #1,D2 ; increment index
|
||
CMP.L D1,D2 ; .
|
||
BLT.S @TblLoop ; LOOP
|
||
BRA.S @Done
|
||
@PmgrEx
|
||
@Ptr
|
||
@Info
|
||
ADD.L -4(A1),D0 ; increment the size
|
||
ADDI.L #8,D0 ; add in flags and size field
|
||
@Done
|
||
MOVEM.L (SP)+,@WorkingSet ; restore them registers
|
||
RTS
|
||
|
||
@EntryType
|
||
DC.W @Table-@EntryType ; Table of Tables
|
||
DC.W @Ptr-@EntryType ; Table of pointers
|
||
DC.W @Info-@EntryType ; Table of info
|
||
DC.W @PmgrEx-@EntryType ; Table of Power Manager Op Exceptions
|
||
DC.W 0 ; Expansion
|
||
DC.W 0 ; Expansion
|
||
DC.W 0 ; Expansion
|
||
DC.W 0 ; Expansion
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: BuildTables
|
||
;
|
||
; Inputs: A0 - Ptr to location where table is to be built
|
||
; A1 - Ptr to ROM table
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: Build all the tables into ram and convert all offsets into pointers for easier
|
||
; patching.
|
||
;________________________________________________________________________________________
|
||
BuildTable
|
||
@WorkingSet REG D0-D3/A0-A3
|
||
|
||
MOVEM.L @WorkingSet,-(SP) ; save them registers
|
||
LEA -8(A1),A1 ; get pointer to flags
|
||
MOVE.L (A1)+,D0 ; get a copy of the flags
|
||
MOVE.L (A1)+,D1 ; get a copy of the size
|
||
|
||
MOVE.L D0,-8(A0) ; copy out the flags
|
||
MOVE.L D1,-4(A0) ; copy out the size
|
||
|
||
LSR.L #2,D1 ; arrange it as long word entries
|
||
ANDI.L #PrimsTypeMask,D0 ; mask out all but last two bits
|
||
MOVE.W @EntryType(D0.W*2),D0 ; get the offset to that routine
|
||
JMP @EntryType(D0) ; go to that routine
|
||
|
||
@EntryType
|
||
DC.W @Table-@EntryType ; Table of Tables
|
||
DC.W @Ptr-@EntryType ; Table of pointers
|
||
DC.W @Info-@EntryType ; Table of info
|
||
DC.W @PmgrExLoop-@EntryType ; Table of Power Manager Op Exceptions
|
||
DC.W 0 ; Expansion
|
||
DC.W 0 ; Expansion
|
||
DC.W 0 ; Expansion
|
||
DC.W 0 ; Expansion
|
||
|
||
@Table ; Build a Table of Tables
|
||
MOVEA.L A0,A3 ; A3 = Beginning ram base of table
|
||
MOVEA.L A1,A2 ; A2 = Pointer to rom base of table
|
||
MOVEQ #0,D2 ; clear the register
|
||
@TblLoop ; FOR 0 to MaxNum DO
|
||
ADD.L -4(A1),A0 ; increment ram pointer for size of table
|
||
ADDQ.W #8,A0 ; account for the size byte and the flags
|
||
@Cont MOVE.L (A2,D2.L*4),D3 ; get the offset of the first routine
|
||
BEQ.S @NullVal ; IF offset != 0 THEN
|
||
MOVE.L A0,(A3,D2.L*4) ; save pointer to table in table
|
||
LEA (A2,D3.L),A1 ; make it a pointer
|
||
BSR.S BuildTable ; build the table
|
||
ADDQ.L #1,D2 ; increment index
|
||
CMP.L D1,D2 ; .
|
||
BLT.S @TblLoop ; LOOP
|
||
BRA.S @Done
|
||
|
||
@NullVal ADDQ.L #1,D2 ; increment index
|
||
CMP.L D1,D2 ; .
|
||
BLT.S @Cont ; LOOP
|
||
BRA.S @Done ; and continue on
|
||
|
||
@Ptr ; Build a Table of Pointers
|
||
MOVEQ #0,D2 ; clear the register
|
||
@PtrLoop ; FOR 0 to MaxNum DO
|
||
MOVE.L (A1,D2.L*4),D3 ; get the offset of the first routine
|
||
BEQ.S @NullValue ; IF offset != 0 THEN
|
||
ADD.L A1,D3 ; add the offset
|
||
@NullValue MOVE.L D3,(A0)+ ; save it in the table
|
||
ADDQ.L #1,D2 ; increment index
|
||
CMP.L D1,D2 ; .
|
||
BLT.S @PtrLoop ; LOOP
|
||
BRA.S @Done
|
||
@Info ; Build a Table of Info
|
||
SUBQ.W #1,D1 ; help out dbra god
|
||
@InfoLoop ; FOR 0 to MaxNum DO
|
||
MOVE.L (A1)+,(A0)+ ; copy info directly
|
||
DBRA D1,@InfoLoop ; LOOP
|
||
BRA.S @Done
|
||
|
||
@PmgrExLoop ; WHILE notDone DO { <K12>
|
||
MOVE.W (A1)+,D0 ; get the mask & Exception |
|
||
MOVE.W D0,(A0)+ ; copy them directly into Ram Tables v
|
||
BEQ.S @Done ; IF mask & Exception == NULL THEN notDone = FALSE
|
||
MOVE.L A1,D0 ; get pointer to entry
|
||
ADD.L (A1)+,D0 ; calculate the handler's address
|
||
MOVE.L D0,(A0)+ ; stuff address in the Ram Tables
|
||
BRA.S @PmgrExLoop ; } <K12>
|
||
@Done
|
||
MOVEM.L (SP)+,@WorkingSet ; restore them registers
|
||
RTS
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: InitPmgrGlobals
|
||
;
|
||
; Inputs: A3 -- Pointer to PmgrVars
|
||
;
|
||
; Outputs: none.
|
||
;
|
||
; Trashes: D0/A0-A2
|
||
;
|
||
; Function: Determines the appropriate size of the tables.
|
||
;
|
||
;________________________________________________________________________________________
|
||
|
||
InitPmgrGlobals
|
||
|
||
; Initialize using InfoTbl
|
||
LoadTbl PrimInfoTblPtr,A3,A2
|
||
MOVE.B PrimPRAMBase(A2),\
|
||
PRAMbase(A3) ; Save value in globals for future reference
|
||
MOVEQ #0,D0 ; clear D0
|
||
MOVE.B PrimDefHyst(A2),D0 ; get a byte from primitives
|
||
MOVE.W D0,Hysteresis(A3) ; set default hysteresis value <H30>
|
||
MOVE.W PrimLowWarn(A2),\
|
||
LowWarn(A3) ; set default low/dead battery warning levels
|
||
MOVE.W PrimPRAMBase(A2),D0 ; get PrimWakeLvl:PrimBatWarnCt in d0 <H62>
|
||
EXT.W D0 ; extend the byte value to word (value should be < 127) <H62>
|
||
MOVE.W D0,BatteryWarnDly(A3) ; load the dialog delay count for shorted battery int's <H62>
|
||
MOVE.W D0,BatteryWarnCnt(A3) ; init battery warning count for shorted battery int's
|
||
MOVE.L PowerCycRegAddr(A2),\
|
||
PowerCycleReg(A3) ; get the address of the power cycle register
|
||
MOVE.B PrimCycRegValue(A2),\
|
||
PwrCycRegValue(A3) ; get the value for the power cycle register <K20>
|
||
|
||
; Initialize using RoutinesTbl
|
||
LoadTbl PmgrRoutineTbl,A3,A2
|
||
MOVE.L PowerCycPtr(A2),D0
|
||
MOVE.L D0,PwrCycProc(A3) ; Save pointer in Globals <H24>
|
||
|
||
MOVE.L PowerCycResPtr(A2),D0
|
||
MOVE.L D0,PwrCycRestore(A3) ; Save pointer in Globals <H24>
|
||
|
||
MOVE.W #PwrCycWaitTmDef,\
|
||
PwrCycWaitTime(A3) ; Set PwrCycWaitTime
|
||
MOVE.W #PwrCycSynCntDef,\
|
||
PwrCycSyncCount(A3) ; Set number of SyncIdles <27> HJR
|
||
MOVE.W #PwrCycleDef,\
|
||
PwrCycCounter(A3) ; Set number of power cycle loops. <7> HJR
|
||
MOVE.W #PwrCycDelayDef,\
|
||
PwrCycDelay(A3) ; Set default delay <27> HJR
|
||
MOVE.W #PwrCycProgGrowDef,\
|
||
PwrCycProgGrow(A3) ; Set growth increment for power cycling <29> HJR
|
||
MOVE.W #PwrCycProgMaxDef,\
|
||
PwrCycProgMax(A3) ; Set maximum size for power cycling <29> HJR
|
||
MOVE.L #$0FFFFFFF,\
|
||
DimmingWaitTime(A3) ; Set Time till we start dimming
|
||
|
||
|
||
MOVE.L EnvIntPtr(A2),D0
|
||
MOVE.L D0,vEnvInt(A3) ; save the handler address (or nil if none)
|
||
|
||
; Initialize the rest
|
||
|
||
MOVEQ #1,D0
|
||
MOVE.L D0,LastAct(A3) ; Init last activity and disk counters <v3.7>
|
||
MOVE.L D0,LastHd(A3)
|
||
|
||
ADDQ.W #nmType,BNmQEntry+qType(A3) ; initialize some notification record fields <H52>
|
||
MOVEQ #-1,D0
|
||
MOVE.L D0,BNmQEntry+nmSound(A3); Use default sound <H52>
|
||
|
||
LEA BatInt,A1 ; Set up int handlers <v4.9>
|
||
MOVE.L A1,vBatInt(A3)
|
||
|
||
LEA WakeUp,A1 ; Get Address of WakeUp Routine
|
||
MOVE.L A1,WakeVector(A3) ; Save in the Globals
|
||
|
||
MOVE.L A3,A0 ; Param A0 = Ptr to Pmgr Globals
|
||
IF NOT forRomulator THEN ; <SM4>
|
||
BSR.L GetRealProc ; Get the physical address of PMgrVars--Warning Destroys Regs D1/A1-A2
|
||
ENDIF
|
||
MOVE.L A0,PmgrVarPhysPtr(A3) ; Save it off in PwrMgr Globals
|
||
|
||
MOVE.W #CPUSpeedDisp,D0 ; Find out what speed we are running <39> HJR
|
||
_PowerDispatch ; <39> HJR
|
||
MOVE.B D0,SaveSpeedo(A3) ; Set saveSpeedo to current speed <39> HJR
|
||
|
||
LEA DoSpinDown,A1 ; initialize the hard disk spindown vector <H82>
|
||
MOVE.L A1,HDvector(A3) ; <H82>
|
||
|
||
LEA DoHDSpinUP,A1 ; initialize the hard disk spinup vector <H82>
|
||
MOVE.L A1,HDSpinUpVector(A3) ; <H82>
|
||
|
||
BigLEA GracefulShutdown,A1 ; issue shutdown command (AppleEvent) <H59>
|
||
MOVE.L A1,vSoftShutdown(A3) ; <H59>
|
||
|
||
LEA ModemSndOnInt,A1 ; get addr of modem sound interrupt handler <t28> djw
|
||
MOVE.L A1,MdmSndVect(A3) ; install PmgrGlobal <40> HJR
|
||
|
||
ST TOdirtyFlag(A3) ; set time outs to be dirty
|
||
|
||
BSET.B #ClamshellClosed,\
|
||
PmgrFlags(A3) ; initialize the value to be closed <K26>
|
||
RTS
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: InitPMgrOp
|
||
;
|
||
; Inputs: A3 -- pointer to Power Manager's variables
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D1/A0-A2
|
||
;
|
||
; Function: initializes all the variables required by PMgrOp
|
||
;________________________________________________________________________________________
|
||
|
||
InitPMgrOp LEA cmdCounts,A0 ; save pointers to the PMgrOp send/receive count tables <H52>
|
||
MOVE.L A0,vSendCountTbl(A3) ; <H52>
|
||
LEA replyCounts,A0 ; <H52>
|
||
MOVE.L A0,vRecvCountTbl(A3) ; <H52>
|
||
BSR.S SetupPMgrOpInterface ; get the PMgrOp exception table <H52>
|
||
MOVE.L A1,pmgrOpExceptions(A3) ; and save it <H52>
|
||
RTS ; <H52>
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: SetupPMgrOpInterface
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: D1 -- communications protocol (0=parallel, 2=serial, ...)
|
||
; D2 -- 0 = Rom Exception Tables <K15>
|
||
; A1 -- pointer to the start of an exception table
|
||
;
|
||
; Function: returns the protocol type, and a pointer to an exception table for
|
||
; handling commands that are either partially or not handled by the
|
||
; PMGR microcontroller due to differences in hardware implementations.
|
||
;
|
||
; Each entry consists of a byte for the "don't care bits" mask,
|
||
; a byte for the command number, and a long word for a relative
|
||
; offset from the current location to the special handler.
|
||
;________________________________________________________________________________________
|
||
|
||
SetupPMgrOpInterface
|
||
MOVE.L PmgrBase,A3 ; get pointer to PmgrBase
|
||
MOVEQ #0,D1 ; clear register
|
||
MOVE.L A3,D2 ;
|
||
|
||
ADDQ.L #1,D2 ; IF Power Manager vars valid THEN
|
||
BEQ.S @UseROMExceptions ;
|
||
|
||
LoadTbl PrimInfoTblPtr,A3,A1 ; A0 = Power Managers Info table (RAM)
|
||
MOVE.B PrimPMgrCommType(A1),D1 ; D1 = communications protocol type (RAM)
|
||
LoadTbl PMgrOpExcepTbl,A3,A1 ; A1 = Power Managers Exception Table (RAM)
|
||
RTS ; ELSE
|
||
|
||
@UseROMExceptions ;
|
||
MOVEA.L UnivInfoPtr,A1 ; A1 = ProductInfo table (ROM)
|
||
ADDA.L PowerManagerPtr(A1),A1 ; A1 = ROM Power Manager's primitives (ROM)
|
||
MOVEA.L A1,A2 ; A2 = A1
|
||
ADDA.L PrimInfoTblPtr(A2),A2 ; A2 = Power Managers Info table (ROM)
|
||
|
||
MOVE.B PrimPMgrCommType(A2),D1 ; D1 = communications protocol type (ROM)
|
||
ADDA.L PMgrOpExcepTbl(A1),A1 ; A1 = Power Managers Exception Table (ROM)
|
||
RTS ;
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: DoPmgrCommands
|
||
;
|
||
; Inputs: A3 -- Pointer to PmgrVars
|
||
;
|
||
; Outputs: none.
|
||
;
|
||
; Trashes: D0/A0-A1
|
||
;
|
||
; Function: Determines the appropriate size of the tables.
|
||
;
|
||
;________________________________________________________________________________________
|
||
|
||
DoPmgrCommands
|
||
CLR.L -(SP) ; zero the buffer <H18>
|
||
MOVE.L SP,-(SP) ; pmRBuffer <H18>
|
||
MOVE.L (SP),-(SP) ; pmSBuffer <H18>
|
||
CLR.W -(SP) ; pmLength = 0 <H18>
|
||
MOVE.W #PmgrADBoff,-(SP) ; pmCommand = turn off ADB auto poll <H18>
|
||
MOVEA.L SP,A0 ; point to the parameter block <H18>
|
||
_PMgrOp ; send the command <H18>
|
||
|
||
LoadTbl PrimInfoTblPtr,A3,A1 ; get pointer to info table
|
||
TST.B PrimChargerAttr(A1) ; IF charger attributes THEN
|
||
BEQ.S @noChargerAttribs
|
||
MOVE.B #ChargerOn,pmData(A0) ; ensure charger turned on <H43>
|
||
MOVE.W #1,pmLength(A0) ; pmLength = 1 <H43>
|
||
MOVE.W #power1Cntl,pmCommand(A0) ; pmCommand = power 1 control <H43>
|
||
_PMgrOp ; send the command <H43>
|
||
|
||
LoadTbl PrimInfoTblPtr,A3,A1 ; get pointer to info table
|
||
MOVE.B PrimChargerAttr(A1),\ ;
|
||
pmData(A0) ; stuff the attr <H42>
|
||
MOVE.W #1,pmLength(A0) ; pmLength = 1
|
||
MOVE.W #setMachineAttr,\ ;
|
||
pmCommand(A0) ; pmCommand = send cpu attributes to microcontroller
|
||
_PMgrOp ; send the command
|
||
|
||
@noChargerAttribs
|
||
MOVE.W LowWarn(A3),D0 ; get the low warning
|
||
MOVE.W D0,pmData(A0) ; stuff the default Pmgr low warning and cutoff <H18>
|
||
BEQ.S @NoDefWarnings ; -> no defaults, so trust the PMGR to be right <H30>
|
||
MOVE.W #2,pmLength(A0) ; pmLength = 2 <H18>
|
||
MOVE.W #setBattWarning,\
|
||
pmCommand(A0) ; pmCommand = set low/dead battery levels <H18>
|
||
_PMgrOp ; send the command <H18>
|
||
@NoDefWarnings
|
||
|
||
CLR.W pmLength(A0) ; pmLength = 0 <H48>
|
||
MOVE.W #batteryRead,pmCommand(A0) ; pmCommand = read Battery State <H48>
|
||
_PMgrOp ; send the command <H48>
|
||
MOVEA.L pmRBuffer(A0),A0 ; get pointer to receive buffer <H48>
|
||
MOVE.B (A0),Charger(A3) ; Initialize charger state <H48>
|
||
|
||
BTST.B #HasCharger,Charger(A3) ; is the charger inserted <H65>
|
||
BEQ.S @exitChrgStateInt ; if not, do nothing <H65>
|
||
MOVE.W BatteryWarnDly(A3),\
|
||
BatteryWarnCnt(A3) ; load battery warn counter <H65>
|
||
@exitChrgStateInt
|
||
LEA pmBlkSize(SP),SP ; Remove stack frame <H2>
|
||
RTS
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: DoDynamicSpeedChange
|
||
;
|
||
; Inputs: A3 -- Pointer to PmgrVars
|
||
;
|
||
; Outputs: none.
|
||
;
|
||
; Trashes: D0/A0-A1
|
||
;
|
||
; Function: setup timing constants for full/reduced speed
|
||
;
|
||
;________________________________________________________________________________________
|
||
|
||
DoDynamicSpeedChange
|
||
LoadTbl PrimInfoTblPtr,A3,A0 ; point to the info table for this machine
|
||
MOVEQ #1<<dynamicSpeedChange,\;
|
||
D0 ; does this machine support dynamic speed changes?
|
||
AND.L PrimPubFeatures(A0),D0 ;
|
||
BEQ.S @NotDynamic ; -> no
|
||
|
||
_FullProcessorSpeed ; find out if we're running at full or reduced speed
|
||
EORI.W #1,D0 ; 1=reduced, 0=full
|
||
IF EconoBit THEN
|
||
LSL.W #EconoBit,D0 ; shift it into the correct position
|
||
ENDIF
|
||
MOVE.W D0,D3 ; and save it for later
|
||
|
||
BSR.S @SetProcessorSpeed ; save current timing constants and flip to the opposite speed mode
|
||
|
||
MOVEA.L VIA,A0 ; save the VIA1 registers,
|
||
MOVE.B vIER(A0),-(SP)
|
||
MOVE.B vACR(A0),-(SP)
|
||
MOVEA.L VIA2,A0 ; save the VIA2 interrupt enables
|
||
MOVE.B Rv2IER(A0),-(SP)
|
||
BSET #7,(SP)
|
||
MOVE.B Rv2SEnb(A0),-(SP)
|
||
BSET #7,(SP)
|
||
MOVEQ #$7F,D0
|
||
MOVE.B D0,Rv2IER(A0) ; and disable the interrupts
|
||
MOVE.B D0,Rv2SEnb(A0)
|
||
MOVE.L A3,-(SP) ; save A3
|
||
|
||
BSR.L SetupTimeK ; go calculate the timing constants
|
||
|
||
MOVEA.L (SP)+,A3 ; restore A3,
|
||
MOVEA.L VIA2,A0 ; the VIA2 interrupt enables,
|
||
MOVE.B (SP)+,Rv2SEnb(A0)
|
||
MOVE.B (SP)+,Rv2IER(A0)
|
||
MOVEA.L VIA,A0 ; and the VIA registers
|
||
MOVE.B (SP)+,vACR(A0)
|
||
MOVE.B (SP)+,vIER(A0)
|
||
|
||
BSR.S @SetProcessorSpeed ; save the constants for the opposite speed mode, and restore the speed
|
||
|
||
LEA fullSpeedDBRAs(A3),A1 ; assume we're running at full speed
|
||
TST.W D3 ; are we?
|
||
BEQ.S @RestoreDBRAs ; -> yep
|
||
ADDQ.W #lowSpeedDBRAs-fullSpeedDBRAs,A1
|
||
@RestoreDBRAs
|
||
MOVE.W (A1)+,TimeDBRA ; restore the original timing constants
|
||
MOVE.W (A1)+,TimeSCCDB
|
||
MOVE.W (A1)+,TimeSCSIDB
|
||
MOVE.W (A1)+,TimeVIADB
|
||
@NotDynamic
|
||
RTS
|
||
|
||
|
||
@SetProcessorSpeed
|
||
LEA fullSpeedDBRAs(A3),A1 ; assume we're running at full speed
|
||
TST.W D3 ; are we?
|
||
BEQ.S @CopyDBRAs ; -> yep
|
||
ADDQ.W #lowSpeedDBRAs-fullSpeedDBRAs,A1
|
||
@CopyDBRAs MOVE.W TimeDBRA,(A1)+ ; copy the timing constants from low mem
|
||
MOVE.W TimeSCCDB,(A1)+
|
||
MOVE.W TimeSCSIDB,(A1)+
|
||
MOVE.W TimeVIADB,(A1)+
|
||
|
||
MOVEQ #1<<EconoBit,D1 ; toggle the full/reduced state
|
||
EOR.W D1,D3
|
||
MOVE.W D3,D1
|
||
JmpRoutine SpeedChangePtr,A3,A0; and go do the switch
|
||
|
||
;________________________________________________________________________________________
|
||
; Routine: GetPmgrPRAM
|
||
;
|
||
; Inputs: A3 -- Pointer to PmgrVars
|
||
;
|
||
; Outputs: none.
|
||
;
|
||
; Trashes: D0/A0
|
||
;
|
||
; Function: Determines the appropriate size of the tables.
|
||
;
|
||
;________________________________________________________________________________________
|
||
|
||
GetPmgrPRAM
|
||
LEA -PmgrPramSize(SP),SP ; get a param block
|
||
MOVEA.L SP,A0
|
||
|
||
MOVEQ #PmgrPramSize,D0 ; hi-word = number of PRAM bytes to read <H14>
|
||
SWAP D0 ; <H14>
|
||
MOVE.B PRAMbase(A3),D0 ; lo-word = base address <H13>
|
||
_ReadXPRam ; read in the PMGR PRAM settings
|
||
|
||
CLR.B NTSC ; clear the NTSC flag (square corners)
|
||
|
||
TST.W SlpTimeOut(A0) ; are sleep and hard disk timeouts valid? <H14>
|
||
BNE.S @skipwrite ; -> yes
|
||
|
||
MOVE.B #DfltSlpTime,\
|
||
SlpTimeOut(A0) ; Init default time outs <v5.6>
|
||
MOVE.B #DfltHDTime,HDTimeOut(A0)
|
||
MOVEQ #2,D0 ; hi-word = number of PRAM bytes to write <H14>
|
||
SWAP D0 ; <H14>
|
||
MOVE.B PRAMbase(A3),D0 ; lo-word = base address <H13>
|
||
_WriteXPRam ; write out the default sleep and hard disk timeouts
|
||
|
||
@skipwrite MOVE.B SlpTimeOut(A0),\
|
||
SleepTime(A3) ; Init default time outs for sleep <v5.6>
|
||
MOVE.B HDTimeOut(A0),HDTime(A3); for hard disk
|
||
LEA PmgrPramSize(SP),SP ; kill param block
|
||
RTS
|
||
|
||
;________________________________________________________________________________________
|
||
|
||
; Routine: InstallVBLs
|
||
;
|
||
; Inputs: A3 -- Pointer to PmgrVars
|
||
;
|
||
; Outputs: none.
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: Determines the appropriate size of the tables.
|
||
;
|
||
;________________________________________________________________________________________
|
||
|
||
InstallVBLs
|
||
LoadTbl PmgrRoutineTbl,A3,A1 ; get pointer to Routine Table
|
||
|
||
; install the battery monitoring VBL task...
|
||
|
||
MOVE.L BatteryVBLPtr(A1),D0 ; does this machine monitor the battery level? <H42>
|
||
BEQ.S @NoBatteryVBL ; -> no, don't install the VBL task <H42>
|
||
LEA BatVBLTask+vblCount(A3),\
|
||
A0 ; point to the end of the VBL task record <H42>
|
||
MOVE.W #BatFreq,(A0) ; vblCount <H42>
|
||
MOVE.L D0,-(A0) ; vblAddr <H42>
|
||
ADDQ.W #vType,-(A0) ; vblType = vType <H42>
|
||
SUBQ.W #vblType-vblink,A0 ; point to the beginning of the record <H42>
|
||
_VInstall ; install the task <H42>
|
||
@NoBatteryVBL
|
||
|
||
; install the sound usage monitoring VBL task...
|
||
|
||
MOVE.L SoundVBLPtr(A1),D0 ; does this machine monitor sound usage? <H42>
|
||
BEQ.S @NoSoundVBL ; -> no, don't install the VBL task <H42>
|
||
LEA SwVBLTask+vblCount(A3),\
|
||
A0 ; point to the end of the VBL task record <H42>
|
||
MOVE.W #SndWFreq,(A0) ; vblCount <H42>
|
||
MOVE.L D0,-(A0) ; vblAddr <H42>
|
||
ADDQ.W #vType,-(A0) ; vblType = vType <H42>
|
||
SUBQ.W #vblType-vblink,A0 ; point to the beginning of the record <H42>
|
||
_VInstall ; install the task <H42>
|
||
@NoSoundVBL
|
||
|
||
RTS
|
||
;¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥ End Of Initialization ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
|
||
|
||
|
||
;¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥ VBL's & Interrupts ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
|
||
;
|
||
; Contains:
|
||
;
|
||
; BatWatch
|
||
; RemoveMsg
|
||
; InstallMsg
|
||
; PMGRInt
|
||
; BatInt
|
||
;________________________________________________________________________________________
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: BatWatch
|
||
;
|
||
; Inputs: A1 - pointer to VIA1 base
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: none (D0-D3, A0-A3 are preserved by the interrupt dispatcher)
|
||
;
|
||
; Function: Monitors the battery for low power conditions, and then alerts the user via
|
||
; the Notification Manager. Also updates dirty sleep and hard disk timeouts.
|
||
;________________________________________________________________________________________
|
||
|
||
BatWatch
|
||
MOVE.L PmgrBase,A2
|
||
LEA BatVBLTask(A2),A0 ; Get pointer to vbl task
|
||
MOVE.W #BatFreq,vblCount(A0) ; Do it again
|
||
TST.B SysTaskFlag(A2)
|
||
BEQ @exit
|
||
|
||
@didsystask
|
||
JsrRoutine GetLevelPtr,A2,A0 ; Read, average, and convert battery level
|
||
BNE.S @valid ; into level -1 - 4, branch if data not ready
|
||
|
||
MOVE.B #-1,LastLevel(A2) ; Reset last level
|
||
BRA.S @BatWatchOut
|
||
|
||
@valid TST.B D0 ; Test for negative current level
|
||
BPL.S @positive
|
||
|
||
@negative BSR RemoveMsg ; Remove old message (if any)
|
||
MOVE.B D0,LastLevel(A2) ; Save level
|
||
BRA.S @BatWatchOut
|
||
|
||
@positive BEQ.S @lesser ; Level 0, do nothing
|
||
|
||
CMP.B #2,D0 ; Level 2, remap to level 1 (last dialog level) <H25>
|
||
BNE.S @lpowermode ; <2> É continue with low power stuff <H25>
|
||
MOVEQ #1,D0 ; <2> É remap level 2 to level 1 <H25>
|
||
|
||
@lpowermode TST.B LastLevel(A2) ; If LasLevel was -1 then new message
|
||
BMI.S @newmsg
|
||
|
||
CMP.B LastLevel(A2),D0 ; If NewLevel<=LastLevel then branch
|
||
BLS.S @lesser
|
||
|
||
@newmsg BSR RemoveMsg ; Remove previous level message
|
||
BSR InstallMsg ; Install this level message
|
||
CLR.B Level4Cnt(A2) ; Clear level 4 count down timer
|
||
MOVE.B D0,LastLevel(A2) ; Save level
|
||
BRA.S @BatWatchOut
|
||
|
||
@lesser CMP.B #4,LastLevel(A2) ; If level 4 then inc timer
|
||
BNE.S @BatWatchOut
|
||
|
||
ADD.B #1,Level4Cnt(A2)
|
||
|
||
@BatWatchOut
|
||
LEA BatVBLTask(A2),A0 ; Get pointer to vbl task
|
||
MOVE.W #BatFreq,vblCount(A0) ; Do it again
|
||
LoadTbl PrimInfoTblPtr,A2,A0 ; Get pointer to info table
|
||
TST.B LastLevel(A2) ; Is the level -1? <H25>
|
||
BPL.S @Next ; No, try next check <H25>
|
||
BCLR #PmgrWakeLvlSet,PmgrFlags(A2) ; Is the semaphor set? <H25>
|
||
BEQ.S @FinishUp ; Nope. Then skip and go on <H25>
|
||
|
||
MOVE.W PrimLowWarn(A0),D0 ; Get low power values <H25>
|
||
BRA.S @SetPmgrLvl ; Set level and get on with life <H30>
|
||
|
||
@Next CMP.B #4,LastLevel(A2) ; Check if we are in level 4 <H25>
|
||
BNE.S @FinishUp ; If not, go on <H25>
|
||
|
||
TST.B Level4Cnt(A2) ; Is it the first time through? <H25>
|
||
BNE.S @FinishUp ; If not, go On <H25>
|
||
|
||
BSET #PmgrWakeLvlSet,PmgrFlags(A2) ; Set the semaphor <H25>
|
||
MOVE.W PrimLowWarn(A0),D0 ; Get low power values <H25>
|
||
MOVE.B PrimWakeLvl(A0),D0 ; Get wake level values <H25>
|
||
@setPmgrLvl
|
||
TST.W D0 ; are there valid levels? <H30>
|
||
BEQ.S @FinishUp ; -> no, figure the PMGR knows what to do <H30>
|
||
SWAP D0 ; set the values in the top of buffer
|
||
MOVE.L D0,-(SP) ; Set the parameter in the buffer
|
||
MOVE.L SP,-(SP) ; pmRBuffer
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
MOVE.W #2,-(SP) ; pmLength = 0
|
||
MOVE.W #setBattWarning,-(SP) ; pmCommand = set Battery warning level
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; send the command
|
||
LEA pmBlkSize(SP),SP ; Remove stack frame
|
||
|
||
@FinishUp TST.B TOdirtyFlag(A2) ; Check for new timeouts <H25>
|
||
BEQ.S @exit
|
||
|
||
CLR.B TOdirtyFlag(A2) ; Clear the dirty flag <H25>
|
||
SUB.W #8,SP ; allocate some stack space <H25>
|
||
MOVE.L SP,A0 ; set param block <H25>
|
||
MOVEQ #PmgrPramSize,D0 ; hi-word = number of PRAM bytes to read <H25>
|
||
SWAP D0 ; <H25>
|
||
MOVE.B PRAMbase(A2),D0 ; lo-word = base address <H25>
|
||
_ReadXPRam
|
||
|
||
MOVE.B PmgrStatusFlags(A0),SleepFlags(A2) ; Get the sleep flags <H25>
|
||
MOVE.W SlpTimeOut(A0),SleepTime(A2) ; Get latest timeouts <H25>
|
||
ADD.W #8,SP ; free the buffer <H25>
|
||
_IdleUpdateDispatch ;
|
||
@exit RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: RemoveMsg
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager's variables
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: removes any pending low power warning messages
|
||
;________________________________________________________________________________________
|
||
|
||
RemoveMsg
|
||
BTST.B #AvoidLowPMsg,PmgrFlags(A2) ; are low power messages enabled? <t32> djw
|
||
BNE.S nomsg ; no - don't do anything <t32> djw
|
||
BatIntRemoveMsg
|
||
TST.B lpMSGvalid(A2) ; If no messages pending then nothing to remove
|
||
beq.s nomsg ; Yes. remove low power message
|
||
|
||
MOVE.L D0,-(SP)
|
||
LEA BNmQEntry(A2),A0
|
||
_NMRemove ; Remove low power warning message
|
||
MOVE.L (SP)+,D0
|
||
CLR.B lpMSGvalid(A2) ; No messages pending
|
||
nomsg RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: InstallMsg
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager's variables
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: installs a low power warning message if they're allowed
|
||
;________________________________________________________________________________________
|
||
|
||
InstallMsg
|
||
BTST.B #AvoidLowPMsg,PmgrFlags(A2) ; are low power messages enabled? <t32> djw
|
||
BNE.S @nmproc ; don't post any message <t32> djw
|
||
MOVE.L D0,-(SP)
|
||
LEA BNmQEntry(A2),A0 ; Create notification entry
|
||
LEA @nmproc,A1
|
||
MOVE.L A1,nmResp(A0) ; Use empty response routine below
|
||
MOVE.L lpSICNHndl(A2),nmIcon(A0) ; Use the icon
|
||
|
||
MOVE.W D0,D2 ; Copy level into D2
|
||
SUBQ.W #1,D2 ; Adjust for range 0 - 3
|
||
LSL.W #2,D2 ; Convert to offset
|
||
MOVE.L lpSTR0Ptr(A2,D2.W),nmStr(A0) ; Index into messages strings
|
||
TST.L nmStr(A0) ; Do we have a string?
|
||
BEQ.S @nonminst ; Nope. Get out...
|
||
_NMInstall ; Notify user of low power condition
|
||
ST lpMSGvalid(A2) ; Message pending <29> HJR
|
||
@nonminst MOVE.L (SP)+,D0 ; <29> HJR
|
||
|
||
@nmproc RTS ; No notification proc now
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: PMGRInt
|
||
;
|
||
; Inputs: A1 - pointer to VIA1 base
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: none (D0-D3 and A0-A3 are preserved by the interrupt dispatcher)
|
||
;
|
||
; Function: This is the Power Manager interrupt handler. It dispatches to the right
|
||
; interrupt handler for the type of interrupt received.
|
||
;________________________________________________________________________________________
|
||
|
||
PMGRInt
|
||
MOVE.B #(1<<ifIRQ)+(1<<ifCB1),vIFR(A1) ; clear PMGR interrupt
|
||
LEA -12(SP),SP ; Create stack frame
|
||
MOVE.L SP,A0
|
||
ADDQ.L #2,A0 ; point 2 bytes into buffer
|
||
MOVEQ #ReadINT,D0 ; PMGR command, get interrupt flags
|
||
BSR PMGRrecv
|
||
TST.W D0
|
||
BNE.S @exit
|
||
|
||
MOVE.B (A0),D0 ; Flag byte [int/adb]
|
||
LSR.B #4,D0 ; interrupt bits were in upper half
|
||
|
||
MOVE.W @intPriority(D0.W*2),D0 ; get the offset to that routine
|
||
JMP @intPriority(D0) ; jump to that routine
|
||
|
||
@intPriority
|
||
DC.W @exit-@intPriority ; 0 0 0 0
|
||
DC.W @isADBint-@intPriority ; 0 0 0 1
|
||
DC.W @isBATint-@intPriority ; 0 0 1 0
|
||
DC.W @isADBint-@intPriority ; 0 0 1 1
|
||
DC.W @isEnvInt-@intPriority ; 0 1 0 0
|
||
DC.W @isADBint-@intPriority ; 0 1 0 1
|
||
DC.W @isBATint-@intPriority ; 0 1 1 0
|
||
DC.W @isADBint-@intPriority ; 0 1 1 1
|
||
IF BlackBirdDebug THEN ; goes away when BB handles one sec ints for real
|
||
DC.W @exit-@intPriority ; 1 0 0 0
|
||
ELSE
|
||
DC.W @oneSecInt-@intPriority ; 1 0 0 0
|
||
ENDIF
|
||
DC.W @isADBint-@intPriority ; 1 0 0 1
|
||
DC.W @isBATint-@intPriority ; 1 0 1 0
|
||
DC.W @isADBint-@intPriority ; 1 0 1 1
|
||
IF BlackBirdDebug THEN ; goes away when BB handles one sec ints for real
|
||
DC.W @exit-@intPriority ; 1 1 0 0
|
||
ELSE
|
||
DC.W @oneSecInt-@intPriority ; 1 1 0 0
|
||
ENDIF
|
||
DC.W @isADBint-@intPriority ; 1 1 0 1
|
||
DC.W @isBATint-@intPriority ; 1 1 1 0
|
||
DC.W @isADBint-@intPriority ; 1 1 1 1
|
||
|
||
|
||
@oneSecInt LEA 12(SP),SP ; clean up PB on stack
|
||
MOVEA.L VIA,A1 ; OneSecInt expects pointer to VIA in A1 <H3>
|
||
MOVEA.L Lvl1DT+(4*ifCA2),A0 ; get the address of the one-second interrupt handler <H3>
|
||
JMP (A0) ; and call it <H3>
|
||
|
||
@isEnvInt MOVE.L PMgrBase,A2
|
||
MOVE.L vENVInt(A2),D0 ; Check for valid vector
|
||
BRA.S @callHandler
|
||
|
||
@isBATint MOVE.L PMgrBase,A2
|
||
MOVE.L vBatInt(A2),D0 ; Check for valid vector
|
||
bra.s @callHandler
|
||
|
||
@isADBint andi.b #$0F,(a0) ; mask off interrupt status bits
|
||
move.b 1(a0),-(a0) ; [cmd] [stat] [cmd]
|
||
subq.b #2,d1 ; actual count
|
||
move.b d1,2(a0) ; [cmd] [stat] [len]
|
||
move.l Lvl1DT+8,d0 ; Check for valid vector
|
||
|
||
@callHandler
|
||
beq.s @exit ; no handler, exit
|
||
move.l d0,a1
|
||
jsr (a1) ; call handler
|
||
@exit lea 12(sp),SP ; Done with stack frame
|
||
rts
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: BatInt
|
||
;
|
||
; Inputs: A0 - pointer to PMGR interrupt data: [flags][battery][gas][therm]
|
||
; A1 - pointer to VIA1 base
|
||
; A2 - pointer to Power Manager's variables
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: none (D0-D3 and A0-A3 are preserved by the interrupt dispatcher)
|
||
;
|
||
; Function: Handles PMGR interrupts that occur because of a change in charger connection
|
||
; state, or a shorted battery condition is detected.
|
||
;________________________________________________________________________________________
|
||
|
||
BatInt
|
||
moveq.l #0,d2 ; clear reg
|
||
move.b 1(a0),d2 ; get battery flags
|
||
move.b d2,Charger(a2) ; save charger state
|
||
|
||
; Charger Change interrupt
|
||
btst.l #ChrgState,d2 ; was there a charger int
|
||
beq.s @exitChargeState ; procede to next test
|
||
btst.l #HasCharger,d2 ; is the charger inserted
|
||
beq.s @exitChargeState ; if not, do nothing
|
||
move.w BatteryWarnDly(a2),BatteryWarnCnt(a2); load battery warn counter
|
||
@exitChargeState
|
||
|
||
; batter shorted interrupt
|
||
btst.l #ShortedBat,d2 ; is there a shorted battery?
|
||
beq.s @shortTestexit ; not this time
|
||
tst.w BatteryWarnCnt(a2) ; if counter
|
||
ble.s @postShortedBatt ; if less than or equal, post message
|
||
|
||
subq.w #1,BatteryWarnCnt(a2) ; update counter
|
||
bra.s @shortTestexit ; exit handler
|
||
|
||
; Shorted battery condition detected - post notification message
|
||
; Remove any pending low power messages and prevent any more from showing up so they
|
||
; don't try to remove the bad battery message.
|
||
@postShortedBatt
|
||
bsr BatIntRemoveMsg ; remove any old message
|
||
bset.b #AvoidLowPMsg,PmgrFlags(a2) ; avoid confict with low power messages
|
||
|
||
lea bbSTR0Ptr(a2),a1 ; get first vectored string
|
||
bset.b #BadBatDet,PmgrFlags(a2) ; is this the first bad message?
|
||
beq.s @continue
|
||
addq.l #4,a1 ; index to second harsher message
|
||
bclr.b #BadBatDet,PmgrFlags(a2) ; reset bad battery level for next time
|
||
@continue
|
||
tst.l (a1) ; does the string exist?
|
||
beq.s @shortTestexit ; no string - do not post message
|
||
lea BNmQEntry(a2),a0 ; a0 = ptr to notification mgr record
|
||
move.l (a1),nmStr(a0) ; set string message
|
||
lea @BatResp,a1 ; address of response routine
|
||
move.l a1,nmResp(a0) ; set response routine
|
||
move.l lpSICNHndl(a2),nmIcon(a0) ; Use the icon
|
||
_NMInstall ; notify user of defective battery condition
|
||
|
||
subq.l #4,sp
|
||
movea.l sp,a0 ; a0 = pmgr pkt data buffer
|
||
move.b #writePmgrRAM,d0 ; pmgr command
|
||
moveq.l #3,d1 ; 3 bytes to send
|
||
move.w #$0021,(a0) ; set addr to write to
|
||
andi.l #~((1<<ShortedBat)+\
|
||
(1<<hasCharger)),d2 ; clear short and charger condition
|
||
move.b d2,2(a0) ; set data byte
|
||
bsr PmgrSend ; tell pmgr to clear the interrupt
|
||
addq.l #4,sp ; free buffer
|
||
@shortTestexit
|
||
rts ; exit interrupt handler
|
||
|
||
@BatResp movea.l (sp)+,a1 ; save return addr
|
||
movea.l (sp)+,a0 ; get ptr to BNmQEntry
|
||
_NMRemove ; remove the bad battery notification
|
||
movea.l PmgrBase,a0 ; get ptr to pmgr globals |
|
||
bclr.b #AvoidLowPMsg,PmgrFlags(a0) ; allow low power messages again V
|
||
jmp (a1) ; return to caller <H62>
|
||
|
||
;¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥ End of VBL's & Ints ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
|
||
|
||
;¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥ Traps ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
|
||
;
|
||
; Contains:
|
||
;
|
||
; PowerDispatch
|
||
; IdleUpdate (Selector #1)
|
||
; IdleDelay (Selector #2)
|
||
; IdleMind (Selector #3)
|
||
; IdleRead (Selector #4)
|
||
; IdleEnable (Selector #5)
|
||
; IdleDisable (Selector #6)
|
||
; CPUSpeed (Selector #7)
|
||
; BasePRAM (Selector #8)
|
||
; ScaledBattery (Selector #9)
|
||
; PowerMgrHook (Selector #10)
|
||
; SecondaryInitproc
|
||
; ScsiDiskModeproc
|
||
; ExternaVideoOnproc
|
||
; ModemTypeProc
|
||
; PDimScreens (Selector #11)
|
||
; PrivateFeatures (Selector #13)
|
||
; GetButtonValues (Selector #15)
|
||
; SetHDState (Selector #16)
|
||
;
|
||
; PmgrOp
|
||
; IdleUpdate
|
||
; IdleState
|
||
; SerialPower
|
||
; Sleep
|
||
; SlpQInstall
|
||
; SlpQRemove
|
||
;________________________________________________________________________________________
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: PowerDispatch (trap $A09F)
|
||
;
|
||
; Inputs: D0 - selector
|
||
;
|
||
; Outputs: D0 - selector result, or error code if bad selector
|
||
;
|
||
; Trashes: varies by selector
|
||
;
|
||
; Function: This is the Power Manager's private dispatch trap, and provides a variety of
|
||
; miscellaneous functions.
|
||
;________________________________________________________________________________________
|
||
|
||
PowerDispatch
|
||
WITH PwrDispatchRec
|
||
MOVE.L PmgrBase,A0 ; Get pointer to globals
|
||
LoadTbl PwrDispatchTbl,A0,A0 ; Get pointer to Table
|
||
MOVEQ #0,D1 ; Clear D1
|
||
MOVE.W D0,D1 ; Get selector in D1
|
||
LSL.W #2,D1 ; Convert selector to bytes
|
||
CMP.L PwrDispCount(A0),D1 ; IF Dispatch Out of Range THEN
|
||
BHI.S @Error ; Get Out Of Here
|
||
TST.L ([A0,D1.L]) ; ELSE Dispatch Non Existent THEN
|
||
BEQ.S @Error ; Get Out of Here
|
||
JMP ([A0,D1.L]) ; Go do that routine
|
||
|
||
@Error
|
||
MOVEQ #paramErr,D0 ; Abort and return error
|
||
RTS
|
||
ENDWITH
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: IdleUpdate ($A285) (PowerDispatch selector #1)
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: D0 - time of last activity, in ticks
|
||
;
|
||
; Trashes: A1
|
||
;
|
||
; Function: resets the idle compare time to Ticks unless the idle compare time is
|
||
; already pushed out beyond Ticks.
|
||
;________________________________________________________________________________________
|
||
|
||
IdleUpdateTbl
|
||
DC.W Exit-IdleUpdateTbl ; $00 => OverallAct <K20>
|
||
DC.W UsrAct-IdleUpdateTbl ; $01 => UsrActivity |
|
||
DC.W NetAct-IdleUpdateTbl ; $02 => NetActivity v
|
||
DC.W HDAct-IdleUpdateTbl ; $03 => HardDriveActivity
|
||
TblEnd DC.W 0 ; $04 => padding for now
|
||
|
||
IdleUpdateTrap
|
||
MOVEQ #0,D0 ; clear selector
|
||
|
||
IdleUpdate
|
||
SWAP D0 ; Get our selector
|
||
MOVE.W D0,D1 ; Get a copy of the selector
|
||
MOVE.W SR,-(SP) ; No ints at this time
|
||
OR.W #HiIntMask,SR
|
||
MOVE.L PmgrBase,A1 ; get pmgr local
|
||
MOVE.L LastAct(A1),D0 ; If LastAct > Ticks then branch
|
||
CMP.L Ticks,D0
|
||
BHI.S @noLastActupdate
|
||
MOVE.L Ticks,LastAct(A1) ; reset sleep/idle time
|
||
@noLastActupdate
|
||
|
||
CMP.W #(TblEnd-IdleUpdateTbl)/2,D1 ; IF entry outofbounds THEN
|
||
BHI.S Exit ; exit
|
||
|
||
MOVE.W IdleUpdateTbl(D1.W*2),D1 ; Get the relative offset to the routine.
|
||
JMP IdleUpdateTbl(D1.W) ; GOTO the proper routine.
|
||
|
||
UsrAct MOVE.L LastUsrAct(A1),D0 ; IF LastUsrAct > Ticks THEN
|
||
CMP.L Ticks,D0 ; Exit
|
||
BHI.S Exit ; ELSE
|
||
MOVE.L Ticks,LastUsrAct(A1) ; Update user activity
|
||
BRA.S Exit
|
||
|
||
NetAct MOVE.L LastNetAct(A1),D0 ; IF LastUsrAct > Ticks THEN
|
||
CMP.L Ticks,D0 ; Exit
|
||
BHI.S Exit ; ELSE
|
||
MOVE.L Ticks,LastNetAct(A1) ; Update user activity
|
||
BRA.S Exit
|
||
|
||
HDAct MOVE.L Ticks,LastHd(A1) ; Update user activity
|
||
|
||
Exit MOVE.L LastAct(A1),D0 ;
|
||
MOVE.W (SP)+,SR ; <K20>
|
||
RTS
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: IdleDelay (PowerDispatch selector #2)
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0,A1
|
||
;
|
||
; Function: This routine will delay Idling (Power Cycling) by setting LastAct to some
|
||
; future time. This is in particular useful in Reads, and Writes where the
|
||
; PwrCycWaitTime might not be enough time for them to function properly.
|
||
;________________________________________________________________________________________
|
||
|
||
IdleDelay MOVE.W SR,-(SP) ; Save the status register
|
||
ORI.W #HiIntMask,SR ; Turn off those interrupts
|
||
MOVE.L PMgrBase,A1 ; Get the Globals
|
||
MOVEQ #0,D0 ; Clear the register
|
||
MOVE.W PwrCycDelay(A1),D0 ; Get the time delay used
|
||
ADD.L Ticks,D0 ; update it with Ticks
|
||
CMP.L LastAct(A1),D0 ; IF LastAct > New One THEN
|
||
BLE.S @Done ; Get Out! <34> HJR
|
||
MOVE.L D0,LastAct(A1) ; ELSE set new LastAct
|
||
@Done MOVE.W (SP)+,SR ; Restore status register
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: IdleMind (PowerDispatch selector #3)
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: Checks for hard disk time out, sleep time out, idle time out, and low power
|
||
; sleep. The first check is for a low power condition, if so then sleep is
|
||
; immediately called. The next check is for hard disk spin down time out and
|
||
; sleep time out. These time outs may be disabled when on the battery if a
|
||
; special bit is set. The last check is for idle time out.
|
||
;________________________________________________________________________________________
|
||
|
||
IdleMind
|
||
@savedRegs REG D0-D2/A0-A2
|
||
MOVEM.L @savedRegs,-(SP) ; Save some registers
|
||
|
||
MOVE.L PmgrBase,A2 ; Get pmgr locals
|
||
MOVE.W PwrCycSyncCount(A2),D0 ; Get the number of syncIdle before IdleMind
|
||
ADDI.W #1,PMgrScratch.SyncCounter(A2) ; Increment scratch counter
|
||
CMP.W PMgrScratch.SyncCounter(A2),D0 ; Have we done enough SyncIdles
|
||
BLT @CommonOut
|
||
|
||
CLR.W PMgrScratch.SyncCounter(A2) ; reset counter
|
||
LoadTbl IdleMindTblPtr,A2,A1 ; Get pointer to IdleMindTble
|
||
|
||
ST SysTaskFlag(A2) ; Flag that systemtask has been called
|
||
JsrPrimTbl CountDownTimer,A1 ; Check if we are in countdown condition
|
||
BNE.S @ForceSleep ; IF CountDownTimer THEN sleep
|
||
|
||
JsrPrimTbl RunIdleRoutines,A1 ; Get pointer to Check for spin down HD <H43>
|
||
|
||
MOVE.L LastAct(A2),D0 ; Get LastAct
|
||
CMP.L Ticks,D0 ; IF LastAct > Ticks THEN
|
||
BGT.S @CommonOut ; exit
|
||
|
||
JsrPrimTbl SleepTimeOut,A1 ; Get pointer to Check for going to sleep
|
||
BNE.S @RequestSlp ; IF SleepTimeOut THEN sleep
|
||
|
||
JsrPrimTbl CheckIdle,A1 ; Get pointer to Check for going to power cycle
|
||
BEQ.S @ClrOut ; IF activity THEN clearout
|
||
JsrPrimTbl CalcProgPwrCyc,A1 ; Else calculate progressive count
|
||
JsrPrimTbl CyclePower,A1 ; Get pointer to Go Power Cycling
|
||
BRA.S @CommonOut ; That's All Folks
|
||
|
||
@RequestSlp
|
||
MOVEQ #SleepRequest,D0 ; Set a sleep request
|
||
BRA.S @DoSleep ; Go ajourn
|
||
@ForceSleep
|
||
MOVEQ #SleepNow,D0 ; Set to force sleep
|
||
@DoSleep BTST #dockNoSleep,dockFlags(A2) ; is sleeping allowed (if we're connected to a bar) <H36>
|
||
BNE.S @SleepDeny ; -> no, avoid putting up a dialog <H36>
|
||
_Sleep ; Go to sleep
|
||
@SleepDeny BCLR #LowPowerSleep,PMgrFlags2(A2) ; clear the low power sleep flag <H52>
|
||
MOVE.L Ticks,LastAct(A2) ; Waking updates last activity <H36>
|
||
@ClrOut
|
||
CLR.L PMgrScratch.ProgLastAct(A2) ; Reset progressive power cycling
|
||
@CommonOut
|
||
MOVEM.L (SP)+,@savedRegs ; Restore registers
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: IdleRead (PowerDispatch selector #4)
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: D0 - current CPU speed, in MHz
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: returns the current CPU speed
|
||
;________________________________________________________________________________________
|
||
|
||
IdleRead
|
||
MOVE.W SR,-(SP) ; Save the status register
|
||
ORI.W #HiIntMask,SR ; Kill those vicious interrupts
|
||
MOVE.L PMgrBase,A0 ; Get pmgr locals
|
||
MOVEQ #0,D0 ; Clear the register
|
||
MOVE.B saveSpeedo(A0),D0 ; return current speed
|
||
MOVE.W (SP)+,SR ; restore the status register
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: IdleEnable (PowerDispatch selector #5)
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: D0 - idle disable count
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: returns the idle disable flag count
|
||
;________________________________________________________________________________________
|
||
|
||
IdleEnable
|
||
MOVE.W SR,-(SP) ; Save the status register
|
||
ORI.W #HiIntMask,SR ; Kill those vicious interrupts
|
||
MOVEQ #0,D0 ; Clear the register
|
||
MOVE.L PMgrBase,A0 ; Get pmgr locals
|
||
SUBQ.B #1,IdleFlagCnt(A0) ; pop a level
|
||
BPL.S @DontClr ; IF IdleFlagCnt < 0 THEN
|
||
CLR.B IdleFlagCnt(A0) ; IdleFlagCnt = 0
|
||
@DontClr MOVE.B IdleFlagCnt(A0),D0 ; return idle disable count
|
||
MOVE.W (SP)+,SR ; restore the status register
|
||
RTS
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: IdleDisable (PowerDispatch selector #6)
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: D0 - idle disable count
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: returns the idle disable flag count
|
||
;________________________________________________________________________________________
|
||
|
||
IdleDisable
|
||
MOVE.W SR,-(SP) ; Save the status register
|
||
ORI.W #HiIntMask,SR ; Kill those vicious interrupts
|
||
MOVEQ #0,D0 ; Clear the register
|
||
MOVE.L PMgrBase,A0 ; Get pgmr locals
|
||
ADD.B #1,IdleFlagCnt(A0) ; push a level
|
||
MOVE.B IdleFlagCnt(A0),D0 ; return idle disable count
|
||
MOVE.W (SP)+,SR ; restore the status register
|
||
NoPrimRTS RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: CPUSpeed (PowerDispatch selector #7)
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: D0 - [maximum CPU speed (high word)][current CPU speed (low word)]
|
||
;
|
||
; Trashes: A0,A1
|
||
;
|
||
; Function: returns the maximum and current CPU speeds, in MHz
|
||
;________________________________________________________________________________________
|
||
|
||
CPUSpeed
|
||
MOVEA.L PMgrBase,A2 ; get pointer to Power Manager globals
|
||
MOVEQ #0,D0 ; assume no speed
|
||
JmpRoutine CPUSpeedPtr,A2,A0 ; go do that routine
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: BasePRAM (PowerDispatch selector #8)
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: D0 - base PRAM address used by the Power Manager
|
||
;
|
||
; Trashes: A0,A1
|
||
;
|
||
; Function: returns the base PRAM address that the Power Manager uses for keeping its
|
||
; permanent state information
|
||
;________________________________________________________________________________________
|
||
|
||
BasePRAM
|
||
MOVEA.L PMgrBase,A2 ; get pointer to Power Manager globals
|
||
MOVEQ #0,D0
|
||
MOVE.B PRAMbase(A2),D0 ; stuff in the base PRAM address we use
|
||
RTS
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: ScaledBattery (PowerDispatch selector #9)
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: D0 - battery information:
|
||
; bits 31: 1=battery installed
|
||
; 30: 1=battery is charging
|
||
; 29: 1=charger connected
|
||
; 23-16: warning level (0-255)
|
||
; 7- 0: battery level (0-255)
|
||
;
|
||
; Trashes: D1-D2, A0-A2
|
||
;
|
||
; Function: returns battery and warning levels scaled into the range 0-255
|
||
;________________________________________________________________________________________
|
||
|
||
ScaledBattery
|
||
MOVEA.L PMgrBase,A2 ; get pointer to Power Manager globals
|
||
MOVEQ #0,D0 ; assume no battery info
|
||
JmpRoutine ScaledBattPtr,A2,A0 ; go do that routine
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: PowerMgrHook (PowerDispatch selector #10)
|
||
;
|
||
; Inputs: D0 - [hook selector (high word)][PowerDispatch selector=10 (low word)]
|
||
;
|
||
; Outputs: varies with selector
|
||
;
|
||
; Trashes: D1-D2, A0-A2
|
||
;
|
||
; Function: secondary dispatch selector for various functions
|
||
;________________________________________________________________________________________
|
||
|
||
PowerMgrHook
|
||
WITH PMgrHookRec
|
||
MOVE.L PmgrBase,A2 ; Get pointer to globals
|
||
LoadTbl PmgrHookTbl,A2,A0 ; Get pointer to Table
|
||
MOVEQ #0,D1 ; Clear D1
|
||
SWAP D0 ; Get selector
|
||
MOVE.W D0,D1 ; Get selector in D1
|
||
LSL.W #2,D1 ; Convert selector to bytes
|
||
CMP.L PmgrHookCount(A0),D1 ; IF Dispatch Out of Range THEN
|
||
BHI.S @OutOfRange ; Get Out Of Here
|
||
JMP ([A0,D1.L]) ; Go do that routine
|
||
|
||
@OutOfRange
|
||
MOVEQ #paramErr,D0 ; Abort and return error
|
||
RTS
|
||
ENDWITH
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: SecondaryInitproc (PowerMgrHook selector #0)
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: code to execute at secondary init time
|
||
;________________________________________________________________________________________
|
||
|
||
SecondaryInitproc
|
||
BCLR #PmgrShutdownReq,PmgrFlags1(A2) ; clear any pending shutdown requests
|
||
BSET #PmgrShutdownEnb,PmgrFlags1(A2) ; enable shutdown requests
|
||
MOVEQ #noErr,D0
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: ScsiDiskModeproc (PowerMgrHook selector #1)
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: code to execute if SCSI Disk Mode was entered
|
||
;________________________________________________________________________________________
|
||
|
||
ScsiDiskModeproc
|
||
BSET #7,PmgrFlags(A2)
|
||
MOVEQ #noErr,D0
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: ExternaVideoOnproc (PowerMgrHook selector #2)
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: code to execute if external video is running
|
||
;________________________________________________________________________________________
|
||
|
||
ExternaVideoOnproc
|
||
LoadTbl PrimInfoTblPtr,A2,A1 ; Get pointer to primitives table
|
||
MOVE.B PrimExtVidCor(A1),D0 ; Get Delta Threshold
|
||
ADD.B D0,LowWarn(A2) ; add delta threshold to LowWarn
|
||
BSR SetPwrLvlTask ; update the power manager micro
|
||
MOVEQ #noErr,D0 ; Indicate no problems
|
||
RTS ;
|
||
|
||
;________________________________________________________________________________________ <K9>
|
||
;
|
||
; Routine: ModemTypeProc (PowerMgrHook selector #3)
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: d0.l -- modem type
|
||
;
|
||
; Trashes: a0
|
||
;
|
||
; Function: returns modem type constant
|
||
;________________________________________________________________________________________
|
||
ModemTypeProc
|
||
WITH ModemTblRec
|
||
|
||
bsr.l ModemStatusRT ; d0 has the modem status
|
||
btst.l #ModemInstalled,d0 ; is the modem physically installed
|
||
beq.s @noModem ; if not set, no modem, exit
|
||
|
||
move.l PmgrBase,a0 ; Get pointer to globals
|
||
moveq.l #ModemTypeUnk,d0 ; assume modem installed of unknown type
|
||
LoadTbl ModemTblPtr,a0,a0 ; load the Modem table pointer
|
||
beq.s @exit ; yes
|
||
JsrPrimTbl GetModemType,A0 ; get modem type
|
||
rts
|
||
|
||
@noModem moveq.l #ModemTypeNone,d0 ; no modem
|
||
@exit rts
|
||
ENDWITH
|
||
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ <K9>
|
||
; Routine: ModemStatus
|
||
;
|
||
; Inputs: none
|
||
; Outputs: d0.b - modem status byte
|
||
; Trashes: none
|
||
;
|
||
; Called by: ModemTypeProc
|
||
; Calls: PMgrOp
|
||
; Function: return the modem status byte in d0
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
ModemStatusRT
|
||
@workingset reg a0
|
||
|
||
movem.l @workingset,-(sp)
|
||
;
|
||
; read power manager's modem bit
|
||
;
|
||
MOVEQ.L #0,D0 ; clear the result register
|
||
CLR.L -(SP) ; allocate a buffer for the result
|
||
MOVE.L SP,-(SP) ; pmRBuffer
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
CLR.W -(SP) ; pmLength
|
||
MOVE.W #modemRead,-(SP) ; pmCommand
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; get the modem info
|
||
MOVE.B pmData(SP),D0 ; return the status byte
|
||
ADDA.L #pmBlkSize, sp ; pop buffer
|
||
|
||
MOVEA.L (SP)+,A0 ; <K28>
|
||
RTS
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: PDimScreens (PowerDispatch selector #11)
|
||
;
|
||
; Inputs: D0 - high word: 0=power up, 1=power down
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: sets a flag so that IdleMind handles changing state of screens
|
||
;________________________________________________________________________________________
|
||
|
||
PDimScreens
|
||
MOVEA.L PmgrBase,A0 ; get pointer to globals
|
||
MOVE SR,D0 ; save the sr
|
||
SWAP D0 ; Let get the parameter
|
||
ORI #HiIntMask,SR ; Mask Interrupts
|
||
BSET #PmgrDimReq,PmgrFlags1(A0) ; set the request
|
||
BSET #PmgrDimState,PmgrFlags1(A0) ; assume Power Down state
|
||
TST.W D0 ; IF Powering Up THEN
|
||
BNE.S @Done ;
|
||
BCLR #PmgrDimState,PmgrFlags1(A0) ; set Power Up State
|
||
@Done
|
||
SWAP D0 ; get saved sr
|
||
MOVE D0,SR ; restore sr
|
||
MOVEQ #0,D0 ; noErr
|
||
RTS ; goodbye
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: PrivateFeatures (PowerDispatch selector #13)
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: D0: bits 0: 1=extended battery status call is supported by PMGR
|
||
; 1: 1=battery ID call is supported by PMGR
|
||
; 2: 1=switch AC power on/off call is supported by PMGR
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: Returns a bitmap of private Power Manager features.
|
||
;________________________________________________________________________________________
|
||
|
||
PrivateFeatures
|
||
MOVEA.L PMgrBase,A2 ; get pointer to Power Manager globals
|
||
LoadTbl PrimInfoTblPtr,A2,A0 ; get pointer to Info
|
||
MOVE.L PrimPrivFeatures(A0),D0 ; return the bitmap
|
||
RTS
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: GetButtonValues (PowerDispatch selector #15)
|
||
;
|
||
; Inputs: D0 - high word: 0=Brightness Button, 1=Contrass Button
|
||
;
|
||
; Outputs: D0 - Normalized value from 0-31
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: Return the current state of the appropriate button
|
||
;________________________________________________________________________________________
|
||
|
||
GetButtonValues
|
||
SWAP D0 ; Let get the parameter
|
||
MOVE.B D0,-(SP) ; data to send = Brightness or Contrass
|
||
MOVE.L SP,-(SP) ; pmRBuffer
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
MOVE.W #1,-(SP) ; pmLength
|
||
MOVE.W #readButton,-(SP) ; pmCommand
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; turn off the hard disk
|
||
LEA pmRBuffer+4(SP),SP ; clean up the stack
|
||
MOVEQ #0,D0 ; clear the register
|
||
MOVE.B (SP)+,D0 ; get the result value and clean off the stack
|
||
RTS
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: SetHDState (PowerDispatch selector #16)
|
||
;
|
||
; Inputs: D0 - high word: 0=Spin down HD, 1=Spin Up HD
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: Return the current state of the appropriate button
|
||
;________________________________________________________________________________________
|
||
|
||
SetHDState
|
||
SWAP D0 ; Let get the parameter
|
||
MOVEA.L PMgrBase,A0 ; Get pointer to the globas
|
||
TST.W D0 ;
|
||
BEQ.S @DoSpinDown
|
||
|
||
@DoHDSpinUp
|
||
MOVE.L HDSpinUpVector(A0),D0 ; is there a spin up routine?
|
||
BEQ.S @Done ; -> no, just exit
|
||
MOVEA.L D0,A0 ; yes, call the spinup down routine
|
||
JSR (A0)
|
||
BRA.S @Done
|
||
|
||
@DoSpinDown
|
||
MOVE.L LastHD(A0),D0 ; is the hard disk spinning?
|
||
BEQ.S @Done ; -> no, just exit
|
||
MOVE.L HDvector(A0),D0 ; is there a spindown routine?
|
||
BEQ.S @Done ; -> no, just exit
|
||
MOVEA.L D0,A0 ; yes, call the spindown routine
|
||
JSR (A0)
|
||
|
||
@Done MOVEQ #noErr,D0 ; return no error
|
||
RTS ; going home
|
||
|
||
|
||
;________________________________________________________________________________________ <K16>
|
||
; |
|
||
; Routine: PmgrOp v
|
||
;
|
||
; Inputs: D1 - trap word
|
||
;
|
||
; Outputs: D0 - selector result, or error code if bad selector
|
||
;
|
||
; Trashes: varies by selector
|
||
;
|
||
; Function: This is the PmgrOp trap, and provides which provide for
|
||
; PmgrTrap ($A085)
|
||
; IdleUpdate ($A285)
|
||
; IdleState ($A485)
|
||
; SerialPower ($A685)
|
||
;________________________________________________________________________________________
|
||
|
||
PmgrOp
|
||
WITH PMgrOpTblRec
|
||
ANDI.L #$00000F00,D1 ; Clear all but the trap modifier bits
|
||
LSR.W #7,D1 ; Convert selector to bytes
|
||
|
||
MOVE.L PmgrBase,A1 ; Get pointer to globals
|
||
CMPA.L #-1,A1 ; IF Power Manager Var valid THEN
|
||
BEQ.S @UseROMTable ; .
|
||
LoadTbl PMgrOpTblPtr,A1,A1 ; Get pointer to Table
|
||
CMP.L PMgrOpTblCount(A1),D1 ; IF Trap Out of Range THEN
|
||
BHI.S @OutOfRange ; Get Out Of Here
|
||
JMP ([A1,D1.L]) ; Do the TRAP
|
||
@UseROMTable ; ELSE
|
||
MOVEA.L UnivInfoPtr,A1 ; A0 = ProductInfo table (ROM)
|
||
ADDA.L PowerManagerPtr(A1),A1 ; A0 = ROM Power Manager's primitives (ROM)
|
||
ADDA.L PMgrOpTblPtr(A1),A1 ; A0 = Power Managers PMgrOpTblPtr (ROM)
|
||
CMP.L PMgrOpTblCount(A1),D1 ; IF Trap Out of Range THEN
|
||
BHI.S @OutOfRange ; Get Out Of Here
|
||
MOVE.L (A1,D1.L),D1 ; get offset to the trap
|
||
JMP (A1,D1.L) ; Do the TRAP
|
||
|
||
@OutOfRange
|
||
MOVEQ #paramErr,D0 ; Abort and return error
|
||
RTS ; <K16>
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: PmgrTrap
|
||
;
|
||
; Inputs: A0 -- pointer to Power Manager parameter block
|
||
; [word] command/reply
|
||
; [word] number of bytes to send/receive
|
||
; [long] pointer to send buffer
|
||
; [long] pointer to receive buffer
|
||
;
|
||
; Outputs: D0 -- result code: 0 if successful, else error code
|
||
; (all other registers are preserved)
|
||
;
|
||
; Uses: D1 -- byte to send/byte received
|
||
; D2 -- timeout value for handshaking
|
||
; D3 -- loop counter / miscellaneous
|
||
; D4 -- saved copy of parameter block pointer
|
||
; D5 -- timeout value
|
||
; D6 -- [saved SR][interface model: 0=parallel, 2=serial, ...]
|
||
; D7 -- pointer to top of SCC poll stack
|
||
; A1 -- pointer to VIA1 base
|
||
; A2 -- pointer to VIA2 base
|
||
; A3 -- send or receive buffer pointer
|
||
; A4 -- saved return addresses (Wait4AckLo, Wait4AckHi)
|
||
; A5 -- saved return addresses (SendByte, ReceiveByte)
|
||
; A6 -- pointer to SCC channel A data register
|
||
;
|
||
; Function: This is the Power Manager interface trap ($A085).
|
||
;________________________________________________________________________________________
|
||
|
||
|
||
PMack EQU v2PMack
|
||
PMreq EQU v2PMreq
|
||
PMbuf EQU vBufAH
|
||
PMbufDir EQU vDirA
|
||
|
||
|
||
PMgrTrap
|
||
pmgrPollRegs REG D3/D4/D5/D6/A0/A1/A2/A4
|
||
@numPollRegs EQU 4+4
|
||
@savedRegs REG D1-D7/A0-A6
|
||
|
||
MOVEM.L @savedRegs,-(SP) ; save working registers
|
||
|
||
BSR SetupPMgrOpInterface ; get the setup information
|
||
MOVE.W SR,D6 ; save the entry SR in the upper half of D6
|
||
SWAP D6
|
||
MOVE.W D1,D6 ; and the interface model in the lower half
|
||
MOVEA.L A1,A3 ; save the table pointer
|
||
|
||
; remember the current PMGR interrupt setting, and then disable PMGR interrupts...
|
||
|
||
MOVEA.L VIA,A1 ; point to VIA1
|
||
MOVEA.L VIA2,A2 ; point to the VIA with the handshake lines
|
||
|
||
MOVEQ #(1<<ifCB1),D1 ; uses CB1 for IRQ
|
||
AND.B vIER(A1),D1 ; mask off the PMGR interrupt enable bit(s)
|
||
MOVE.B D1,vIER(A1) ; and disable any that are enabled
|
||
BEQ.S @NoPMGRInt ; -> interrupts are currently disabled
|
||
BSET #ifIRQ,D1 ; be sure to re-enable them on exit
|
||
@NoPMGRInt MOVE.B D1,-(SP)
|
||
|
||
; set up for SCC polling...
|
||
|
||
LEA -4*@numPollRegs(SP),SP ; allocate space for registers saved if we call PollProc
|
||
MOVE.L SP,D7 ; point to the stack top for our SCC poll stack
|
||
|
||
MOVEA.L SccRd,A6 ; point to the SCC channel A's data register <H26>
|
||
ADDQ.W #aData,A6 ; <H26>
|
||
TST.L PollProc ; is a poll proc installed? <H52>
|
||
BNE.S @WillPoll ; -> yes <H52>
|
||
LEA @NoPollSCC+sccData,A6 ; no, avoid collecting bytes no one will use <H52>
|
||
@WillPoll
|
||
|
||
; run thru the exception table for this machine to see if this command is emulated...
|
||
|
||
MOVE.L A0,D4 ; save the pointer to the parameter block
|
||
MOVE.W pmCommand(A0),D0 ; get the command
|
||
TST.L A3 ; IF Exception pointer <> NULL THEN
|
||
BEQ.S @NoExceptions ;
|
||
LEA -4(A3),A3 ; subtract 4 bytes for the loop
|
||
@NextException ; WHILE notDone DO {
|
||
ADDQ.W #4,A3 ; skip over the offset to the previous handler
|
||
MOVE.B (A3)+,D1 ; get the mask
|
||
BEQ.S @NoExceptions ; IF mask = NULL THEN end of list
|
||
AND.B D0,D1 ; mask off the bits we care about
|
||
CMP.B (A3)+,D1 ; IF this command emulated THEN
|
||
BNE.S @NextException ;
|
||
MOVEM.L A0-A2,-(SP) ; save state
|
||
ORI #HiIntMask,SR ; mask interrupts
|
||
TST.L D2 ; IF rom tables THEN <K15>
|
||
BNE.S @RamTables ; .
|
||
ADDA.L (A3),A3 ; calculate the handler's address
|
||
JSR (A3) ; and call the handler
|
||
BRA.S @ExceptDone ;
|
||
@RamTables
|
||
JSR ([A3]) ; call the handler
|
||
@ExceptDone
|
||
MOVEM.L (SP)+,A0-A2 ; restore state
|
||
BEQ @PMgrOpExit ; and exit
|
||
@NoExceptions ; }
|
||
|
||
MOVE.W TimeVIAdb,D5 ; calculate a 32ms timeout value
|
||
LSL.W #5,D5
|
||
|
||
MOVE.W #8*64-1,D3 ; initialize the retry count (8 ms)
|
||
MOVE.W (A0)+,D1 ; get the command byte
|
||
|
||
; wait for /ack to go away in case the PMGR is busy...
|
||
|
||
@CmdRetry MOVE.W #pmBusyErr,D0 ; assume a timeout
|
||
MOVE.W timeVIAdb,D2 ; use a 4 ms timeout value
|
||
LSL.W #2,D2
|
||
BSR Wait4AckHi ; wait for /ack to go high if it's currently low
|
||
BEQ @PMgrOpExit ; -> timed out waiting for initial conditions
|
||
|
||
IF hasNiagra THEN ; <H39>
|
||
IF isUniversal THEN ; <H39>
|
||
TestFor NiagraExistsBit ; <H39>
|
||
beq @pmgrFree ; call old routine <H39>
|
||
ENDIF ; <H39>
|
||
@BusyCheck
|
||
MOVE.W timeVIAdb,D2 ; Get 1ms timeout value <H39>
|
||
LSL.W #4,D2 ; multiply by 16 <H39>
|
||
MOVE.B #0,PMBufDir(A2) ; set Port A is input <H39>
|
||
@pmgrbusy
|
||
CMP.B #$07,PMbuf(A2) ; Get port status <H39>
|
||
DBNE D2,@pmgrbusy ; Wait pmgr not busy <H39>
|
||
BNE.S @pmgrFree ; if not busy status, continue <H39>
|
||
MOVE.L #pmBusyErr,D0 ; Timeout, flag error <H39>
|
||
BRA @PMgrOpExit ; Timed out waiting for initial conditions <H39>
|
||
@pmgrFree
|
||
ENDIF ; <H39>
|
||
|
||
; send the command byte...
|
||
|
||
ORI #HiIntMask,SR ; no interrupts while sending the command bytes
|
||
BSR SendByte ; send the command byte
|
||
BEQ.S @SendCount ; -> success
|
||
|
||
BSR UnloadPollstack ; unload any SCC data stashed while trying to send the command byte
|
||
|
||
MOVE.W D5,D2 ; wait for the handshake to abort
|
||
SWAP D6
|
||
@spin MOVE.W D6,SR ; restore the interrupt level
|
||
DBRA D2,@spin
|
||
SWAP D6
|
||
|
||
DBRA D3,@CmdRetry ; try again
|
||
BRA @PMgrOpExit ; -> enough retries: just abort
|
||
|
||
; send the byte count...
|
||
;
|
||
; As an optimization, commands with fixed length data do not have their
|
||
; count byte sent to the PMGR since both sides know what the count is.
|
||
|
||
@SendCount MOVE.W (A0)+,D3 ; get the byte count
|
||
TestFor PMgrNewIntf ; new PMGR?
|
||
BEQ.S @SendTheCnt ; -> no, it still sends the count anyway
|
||
LEA cmdCounts,A3
|
||
MOVEA.L PMgrBase,A4 ; point to the Power Manager's variables <H3>
|
||
CMPA.W #-1,A4 ; are they valid yet (-1 if not initialized)? <H3>
|
||
BEQ.S @NoSendTbl ; -> no, use the default table <H3>
|
||
MOVEA.L vSendCountTbl(A4),A3 ; yes, use the vectored send table <H52>
|
||
@NoSendTbl TST.B 0(A3,D1) ; do we need to send the count? <H3>
|
||
BPL.S @NoSendCnt ; -> no, both sides know what it is
|
||
@SendTheCnt MOVE.W D3,D1 ; use the count passed in
|
||
BSR SendByte ; send the byte count to the PMGR
|
||
BNE.S @PMgrOpExit ; -> error
|
||
|
||
; send the command's data bytes to the PMGR...
|
||
|
||
@NoSendCnt MOVEA.L (A0),A3 ; get the pointer to the command's data bytes
|
||
MOVEQ #0,D1 ; (set CCR for BEQ so DBNE below won't fall thru)
|
||
BRA.S @StartSend
|
||
|
||
@SendData MOVE.B (A3)+,D1 ; get the next data byte
|
||
BSR SendByte ; and send it
|
||
@StartSend DBNE D3,@SendData ; -> more bytes to send
|
||
BNE.S @PMgrOpExit ; -> error
|
||
|
||
; the command has been sent, so check if we need to wait for a reply...
|
||
|
||
SUBQ.W #pmSBuffer-pmCommand,A0 ; point to the start of the parameter block
|
||
MOVE.W (A0),D1 ; get the command byte before it gets trashed
|
||
LEA replyCounts,A3
|
||
MOVEA.L PMgrBase,A4 ; point to the Power Manager's variables <H3>
|
||
CMPA.W #-1,A4 ; are they valid yet (-1 if not initialized)? <H3>
|
||
BEQ.S @NoRecvTbl ; -> no, use the default table <H3>
|
||
MOVEA.L vRecvCountTbl(A4),A3 ; yes, use the vectored receive table <H52>
|
||
@NoRecvTbl MOVE.B 0(A3,D1),D3 ; get the reply byte count <H3>
|
||
EXT.W D3
|
||
MOVE.W D3,pmLength(A0) ; stuff the count in case there's no reply <H31>
|
||
BEQ.S @PMgrOpExit ; -> no reply, so we're done
|
||
|
||
; read in the reply byte...
|
||
;
|
||
; We don't expect a reply byte except for specific commands.
|
||
|
||
TestFor PMgrNewIntf ; new PMGR?
|
||
BEQ.S @ReadReply ; -> no, it still wants the reply byte anyway
|
||
SUBQ.W #1,D3 ; do we need to get a reply byte?
|
||
BNE.S @NoReply ; -> nope
|
||
@ReadReply BSR ReceiveByte ; get the reply byte
|
||
BNE.S @ReplyTO ; -> error
|
||
|
||
@NoReply MOVE.W D1,(A0)+ ; save the reply byte in the parameter block
|
||
|
||
; read in the reply byte count...
|
||
;
|
||
; As an optimization, replies with fixed length data do not have their
|
||
; count byte sent by the PMGR since both sides know what the count is.
|
||
|
||
TestFor PMgrNewIntf ; new PMGR?
|
||
BEQ.S @ReadCount ; -> no, it still wants the count anyway
|
||
TST.W D3 ; is the PMGR sending us a byte count?
|
||
BPL.S @NoReplyCnt ; -> no, we both know what it is
|
||
|
||
@ReadCount BSR ReceiveByte ; get the count byte
|
||
BNE.S @PMgrOpExit ; -> error
|
||
MOVE.W D1,D3 ; update the reply data byte count
|
||
|
||
@NoReplyCnt MOVE.W D3,(A0)+ ; save the byte count in the parameter block
|
||
|
||
; get the reply's data bytes from the PMGR...
|
||
|
||
ADDQ.W #pmRBuffer-pmSBuffer,A0
|
||
MOVEA.L (A0)+,A3 ; get the pointer to where the reply bytes will go
|
||
BRA.S @StartReply
|
||
|
||
@ReplyData BSR ReceiveByte ; get the next reply data byte
|
||
BNE.S @PMgrOpExit ; -> error
|
||
MOVE.B D1,(A3)+ ; save the byte in the reply data buffer
|
||
@StartReply DBRA D3,@ReplyData ; -> more bytes to get
|
||
|
||
; special-case the power control command, and add a delay if anything was turned on...
|
||
|
||
@PMgrOpExit MOVEA.L VIA,A1
|
||
MOVEA.L D4,A0 ; restore the pointer to the parameter block <H49>
|
||
|
||
MOVE.W D0,D4 ; save the result code
|
||
BNE.S @NotPC ; -> no point in delaying if the command failed <H46>
|
||
|
||
CMPI.W #powerCntl,pmCommand(A0); was this a power control command? <H26>
|
||
BNE.S @NotPC ; -> nope, really all done <H26>
|
||
MOVEA.L pmSBuffer(A0),A2 ; point to the send buffer <H36>
|
||
CMPI.B #(1<<pTurnOn),(A2) ; was something being turned on? <H36>
|
||
BLS.S @NotPC ; -> nope, no need to wait <H36>
|
||
MOVE.W TimeVIAdb,D2 ; wait 125usec for the power planes to stabilize <H36>
|
||
LSR.W #3,D2 ; <H36>
|
||
@Wait125us TST.B (A1) ; (throttle execution speed with a VIA access) <H36>
|
||
BTST #RxCA,-sccData(A6) ; SCC data available? <H36>
|
||
BEQ.S @NoSCCData ; <H36>
|
||
MOVE.B (A6),-(SP) ; yes, push it on the stack <H36>
|
||
@NoSCCData DBRA D2,@Wait125us ; -> keep looping if not <H36>
|
||
|
||
; check if any SCC bytes were collected so we can send them to the serial driver...
|
||
|
||
@NotPC BSR UnloadPollstack ; unload any SCC data stashed while interrupts were disabled
|
||
LEA 4*@numPollRegs(SP),SP ; de-allocate PollProc saved register frame
|
||
|
||
; clean everything up...
|
||
|
||
MOVE.B (SP)+,vIER(A1) ; restore the PMGR interrupt state
|
||
SWAP D6
|
||
MOVE.W D6,SR
|
||
MOVE.W D4,D0 ; restore the result
|
||
EXT.L D0 ; set condition codes
|
||
MOVEM.L (SP)+,@savedRegs ; restore working registers
|
||
RTS
|
||
|
||
@ReplyTO MOVE.W #pmReplyTOErr,D0 ; timed out waiting for the reply
|
||
BRA.S @PMgrOpExit
|
||
|
||
@NoPollSCC DC.W 0 ; A6 points here if no PollProc to avoid stack overflow <H52>
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
|
||
;
|
||
; Routine: Wait4AckLo
|
||
;
|
||
; Inputs: D2 -- timeout count
|
||
; A1 -- pointer to VIA1 base
|
||
; A2 -- pointer to VIA2 base
|
||
; A6 -- pointer to SCC channel A data register
|
||
;
|
||
; Outputs: CCR-- BEQ: /ack has gone low, BNE: timed out
|
||
;
|
||
; Trashes: D2,A4
|
||
;
|
||
; Function: waits for the /ack handshake line to go low (may time out)
|
||
;________________________________________________________________________________________
|
||
|
||
|
||
Wait4AckLo MOVEA.L (SP)+,A4 ; save the return address
|
||
BRA.S @WaitLoop
|
||
|
||
@CheckSCC TST.B (A1) ; (throttle execution speed with a VIA access)
|
||
BTST #RxCA,-sccData(A6) ; SCC data available? <H26>
|
||
BEQ.S @WaitLoop ; <H7>
|
||
MOVE.B (A6),-(SP) ; yes, push it on the stack <H26>
|
||
@WaitLoop BTST.B #PMack,(A2) ; has /ack gone low yet?
|
||
DBEQ D2,@CheckSCC ; -> keep looping if not
|
||
JMP (A4)
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
|
||
;
|
||
; Routine: Wait4AckHi
|
||
;
|
||
; Inputs: D2 -- timeout count
|
||
; A1 -- pointer to VIA1 base
|
||
; A2 -- pointer to VIA2 base
|
||
; A6 -- pointer to SCC channel A data register
|
||
;
|
||
; Outputs: CCR-- BNE: /ack has gone high, BEQ: timed out
|
||
;
|
||
; Trashes: D2,A4
|
||
;
|
||
; Function: waits for the /ack handshake line to go high (may time out)
|
||
;________________________________________________________________________________________
|
||
|
||
|
||
Wait4AckHi MOVEA.L (SP)+,A4 ; save the return address
|
||
BRA.S @WaitLoop
|
||
|
||
@CheckSCC TST.B (A1) ; (throttle execution speed with a VIA access)
|
||
BTST #RxCA,-sccData(A6) ; SCC data available? <H26>
|
||
BEQ.S @WaitLoop ; <H7>
|
||
MOVE.B (A6),-(SP) ; yes, push it on the stack <H26>
|
||
@WaitLoop BTST.B #PMack,(A2) ; has /ack gone high yet?
|
||
DBNE D2,@CheckSCC ; -> keep looping if not
|
||
JMP (A4)
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
|
||
;
|
||
; Routine: ReceiveByte
|
||
;
|
||
; Inputs: D6 -- interface type
|
||
; 0=parallel
|
||
; 2=serial
|
||
; A1 -- pointer to VIA1 base
|
||
; A2 -- pointer to VIA2 base
|
||
; A6 -- pointer to SCC channel A data register
|
||
;
|
||
; Outputs: D0 -- result code (0 if successful)
|
||
; D1 -- byte received
|
||
;
|
||
; Trashes: D2,A4,A5
|
||
;
|
||
; Function: handshakes a byte from the PMGR micro
|
||
;________________________________________________________________________________________
|
||
|
||
|
||
ReceiveByte MOVE.W D5,D2 ; use the standard timeout value
|
||
MOVE.W #pmRecvStartErr,D0 ; assume we'll time out
|
||
MOVEA.L (SP)+,A5 ; save the return address <H7>
|
||
JMP @ReadByte(D6.W) ; go read a byte
|
||
|
||
@ReadByte BRA.S @RecvParallel
|
||
; BRA.S @RecvSerial
|
||
|
||
|
||
@RecvSerial
|
||
ORI.B #%00001100,vACR(A1) ; ***for BlackBird_EVT0 HJR***
|
||
BCLR #4,vACR(A1) ; set shift register to shift in under external clock
|
||
TST.B vSR(A1) ; read a byte to reset the shifter
|
||
|
||
BCLR #PMreq,(A2) ; assert /req to start the handshake
|
||
|
||
BSR.S Wait4AckLo ; wait for /ack to go low
|
||
BNE.S SendRcvDone ; -> timed out
|
||
|
||
BSET #PMreq,(A2) ; de-assert /req since we've seen /ack asserted
|
||
|
||
MOVE.W #pmRecvEndErr,D0 ; assume we'll time out
|
||
MOVE.W D5,D2
|
||
BSR.S Wait4AckHi ; wait for /ack to go high
|
||
BEQ.S SendRcvDone ; -> timed out
|
||
|
||
MOVE.B vSR(A1),D1 ; read in the byte
|
||
|
||
MOVEQ #NoErr,D0 ; success!
|
||
BRA.S SendRcvDone
|
||
|
||
|
||
@RecvParallel
|
||
MOVE.B #$00,PMBufDir(A2) ; make the data port an input
|
||
|
||
BSR.S Wait4AckLo ; wait for /ack to go low
|
||
BNE.S SendRcvDone ; -> timed out
|
||
|
||
BCLR #PMreq,(A2) ; assert the /req line
|
||
|
||
MOVE.B PMbuf(A2),D1 ; read in the byte
|
||
|
||
MOVE.W #pmRecvEndErr,D0 ; assume we'll time out
|
||
FinishHshk MOVE.W D5,D2
|
||
BSR.S Wait4AckHi ; wait for /ack to go high
|
||
BEQ.S SendRcvDone ; -> timed out
|
||
|
||
MOVEQ #NoErr,D0 ; success!
|
||
|
||
SendRcvDone BSET #PMreq,(A2) ; be sure /req is not asserted
|
||
JSR DisableBuf(D6.W) ; turn off the data buffer
|
||
TST.W D0 ; set the condition codes
|
||
JMP (A5) ; <H7>
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: SendByte
|
||
;
|
||
; Inputs: D1 -- byte to send
|
||
; D2 -- timeout count
|
||
; D6 -- interface type
|
||
; 0=parallel
|
||
; 2=serial
|
||
; A1 -- pointer to VIA1 base
|
||
; A2 -- pointer to VIA2 base
|
||
; A6 -- pointer to SCC channel A data register
|
||
;
|
||
; Outputs: D0 -- result code (0 if successful)
|
||
;
|
||
; Trashes: D2,A4,A5
|
||
;
|
||
; Function: handshakes a byte to the PMGR micro
|
||
;________________________________________________________________________________________
|
||
|
||
SendByte MOVE.L D5,D2 ; use the standard timeout value
|
||
MOVEA.L (SP)+,A5 ; save the return address <H7>
|
||
|
||
JSR @SendByte(D6.W) ; send the byte
|
||
|
||
BCLR #PMreq,(A2) ; assert the /req line
|
||
|
||
MOVE.W #pmSendStartErr,D0 ; assume we'll time out
|
||
BSR Wait4AckLo ; wait for /ack to go low
|
||
BNE.S SendRcvDone ; -> timed out
|
||
|
||
BSET #PMreq,(A2) ; de-assert the /req line
|
||
|
||
MOVE.W #pmSendEndErr,D0 ; assume we'll time out
|
||
BRA.S FinishHshk ; wait for /ack to go high
|
||
|
||
|
||
@SendByte BRA.S @SendParallel ; [0] parallel interface
|
||
; BRA.S @SendSerial ; [2] serial interface
|
||
|
||
@SendSerial
|
||
ORI.B #%00011100,vACR(A1) ; ***for BlackBird_EVT0 HJR***
|
||
; BSET #4,vACR(A1) ; set shift register to shift out under external clock
|
||
MOVE.B D1,vSR(A1) ; write out the byte to the shift register
|
||
RTS
|
||
|
||
@SendParallel
|
||
MOVE.B #$FF,PMBufDir(A2) ; make the data port an output
|
||
MOVE.B D1,PMBuf(A2) ; and write out the byte
|
||
RTS
|
||
|
||
|
||
DisableBuf BRA.S @Buf2Input ; [0] parallel interface
|
||
; BRA.S @DisableSR ; [2] serial interface
|
||
|
||
@DisableSR
|
||
ORI.B #%00011100,vACR(A1) ; ***for BlackBird_EVT0 HJR***
|
||
; BSET #4,vACR(A1) ; make the shift register shift out
|
||
RTS
|
||
|
||
@Buf2Input MOVE.B #0,PMBufDir(A2) ; switch the data port back to an input
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
|
||
;
|
||
; Routine: UnloadPollstack
|
||
;
|
||
; Inputs: D7 -- pointer to top of poll stack
|
||
; A1 -- pointer to VIA1 base
|
||
; A6 -- pointer to SCC channel A data register
|
||
; SP -- pointer to bottom of poll stack
|
||
;
|
||
; Outputs: D7 -- pointer to top of poll stack
|
||
; A1 -- pointer to VIA1 base
|
||
; A6 -- pointer to SCC channel A data register
|
||
; SP -- pointer to top of poll stack
|
||
;
|
||
; Trashes: D0,D1,D2,A3,A4,A5
|
||
;
|
||
; Function: calls the poll proc to unload any bytes stashed from SCC
|
||
; port A while interrupts were disabled
|
||
;________________________________________________________________________________________
|
||
|
||
|
||
UnloadPollstack
|
||
MOVEA.L (SP)+,A4 ; pop the return address
|
||
CMPA.L D7,SP ; is there any poll data?
|
||
BEQ.S @NoSCCData ; -> no
|
||
MOVE.L PollProc,D0 ; is there a poll proc?
|
||
BEQ.S @NoPollProc ; -> no
|
||
MOVE.L D7,PollStack ; stuff the PollStack
|
||
|
||
MOVEA.L D7,A3
|
||
MOVEM.L pmgrPollRegs,(A3) ; save regs while calling poll proc W/O USING STACK
|
||
|
||
LEA vBufA(A1),A5 ; point to the register with the SCC WR/REQ bit in VIA 1<H26>
|
||
|
||
MOVEA.L D0,A3
|
||
JSR (A3) ; run the poll proc
|
||
|
||
MOVEA.L D7,A3
|
||
MOVEM.L (A3),pmgrPollRegs ; restore our registers
|
||
@NoPollProc MOVEA.L D7,SP ; toss any bytes left on the pollstack <H26>
|
||
@NoSCCData JMP (A4)
|
||
|
||
|
||
;_______________________________________________________________________________________
|
||
;
|
||
; This table is used to determine if the 680x0 needs to send a count byte to the PMGR.
|
||
; A positive value means that the count is known by both sides, and so it is not sent.
|
||
; A negative value means that the command can send variable amounts of data, so the
|
||
; count byte needs to be sent.
|
||
;
|
||
; Unused commands will be marked as expecting the count to be sent so that commands
|
||
; may be added without having to change the ROM.
|
||
|
||
cmdCounts DC.B -1 ; [$00] -
|
||
DC.B -1 ; [$01] -
|
||
DC.B -1 ; [$02] -
|
||
DC.B -1 ; [$03] -
|
||
DC.B -1 ; [$04] -
|
||
DC.B -1 ; [$05] -
|
||
DC.B -1 ; [$06] -
|
||
DC.B -1 ; [$07] -
|
||
DC.B -1 ; [$08] -
|
||
DC.B -1 ; [$09] -
|
||
DC.B -1 ; [$0A] -
|
||
DC.B -1 ; [$0B] -
|
||
DC.B -1 ; [$0C] -
|
||
DC.B -1 ; [$0D] -
|
||
DC.B -1 ; [$0E] -
|
||
DC.B -1 ; [$0F] -
|
||
|
||
DC.B 1 ; [$10] Subsystem Power/Clock Control
|
||
DC.B 1 ; [$11] Subsystem Power/Clock Control (yet more)
|
||
DC.B -1 ; [$12] -
|
||
DC.B -1 ; [$13] -
|
||
DC.B -1 ; [$14] -
|
||
DC.B -1 ; [$15] -
|
||
DC.B -1 ; [$16] -
|
||
DC.B -1 ; [$17] -
|
||
DC.B 0 ; [$18] Read Power/Clock Status
|
||
DC.B 0 ; [$19] Read Power/Clock Status (yet more)
|
||
DC.B -1 ; [$1A] -
|
||
DC.B -1 ; [$1B] -
|
||
DC.B -1 ; [$1C] -
|
||
DC.B -1 ; [$1D] -
|
||
DC.B -1 ; [$1E] -
|
||
DC.B 0 ; [$1F] RESERVED FOR MSC/PG&E EMULATION
|
||
|
||
DC.B -1 ; [$20] Set New Apple Desktop Bus Command
|
||
DC.B 0 ; [$21] ADB Autopoll Abort
|
||
DC.B 2 ; [$22] ADB Set Keyboard Addresses
|
||
DC.B 1 ; [$23] ADB Set Hang Threshold
|
||
DC.B 1 ; [$24] ADB Enable/Disable Programmers Key
|
||
DC.B -1 ; [$25] -
|
||
DC.B -1 ; [$26] -
|
||
DC.B -1 ; [$27] -
|
||
DC.B 0 ; [$28] ADB Transaction Read
|
||
DC.B -1 ; [$29] -
|
||
DC.B -1 ; [$2A] -
|
||
DC.B -1 ; [$2B] -
|
||
DC.B -1 ; [$2C] -
|
||
DC.B -1 ; [$2D] -
|
||
DC.B -1 ; [$2E] -
|
||
DC.B -1 ; [$2F] -
|
||
|
||
DC.B 4 ; [$30] Set Realtime Clock.
|
||
DC.B 20 ; [$31] Write Parameter RAM
|
||
DC.B -1 ; [$32] Write Extended Parameter RAM.
|
||
DC.B -1 ; [$33] -
|
||
DC.B -1 ; [$34] -
|
||
DC.B -1 ; [$35] -
|
||
DC.B -1 ; [$36] -
|
||
DC.B -1 ; [$37] -
|
||
DC.B 0 ; [$38] Read Realtime Clock.
|
||
DC.B 0 ; [$39] Read Parameter RAM
|
||
DC.B 2 ; [$3A] Read Extended Parameter RAM.
|
||
DC.B -1 ; [$3B] -
|
||
DC.B -1 ; [$3C] -
|
||
DC.B -1 ; [$3D] -
|
||
DC.B -1 ; [$3E] -
|
||
DC.B -1 ; [$3F] -
|
||
|
||
DC.B 1 ; [$40] Set Screen Contrast
|
||
DC.B 1 ; [$41] Set Screen Brightness <H4>
|
||
DC.B -1 ; [$42] -
|
||
DC.B -1 ; [$43] -
|
||
DC.B -1 ; [$44] -
|
||
DC.B -1 ; [$45] -
|
||
DC.B -1 ; [$46] -
|
||
DC.B -1 ; [$47] -
|
||
DC.B 0 ; [$48] Read Screen Contrast
|
||
DC.B 0 ; [$49] Read Screen Brightness
|
||
DC.B -1 ; [$4A] -
|
||
DC.B -1 ; [$4B] -
|
||
DC.B -1 ; [$4C] -
|
||
DC.B -1 ; [$4D] -
|
||
DC.B -1 ; [$4E] -
|
||
DC.B -1 ; [$4F] -
|
||
|
||
DC.B 1 ; [$50] Set Internal Modem Control Bits
|
||
DC.B 0 ; [$51] Clear FIFOs
|
||
DC.B 2 ; [$52] Set FIFO Interrupt Marks
|
||
DC.B 2 ; [$53] Set FIFO Sizes
|
||
DC.B -1 ; [$54] Write Data to Modem
|
||
DC.B 1 ; [$55] Set Data Mode
|
||
DC.B 3 ; [$56] Set Flow Control Mode <H55>
|
||
DC.B 1 ; [$57] Set DAA control lines <H54>
|
||
DC.B 0 ; [$58] Read Internal Modem Status
|
||
DC.B 1 ; [$59] Get DAA Identification <H55>
|
||
DC.B 0 ; [$5A] Get FIFO Counts
|
||
DC.B 0 ; [$5B] Get Maximum FIFO Sizes
|
||
DC.B 0 ; [$5C] Read Data From Modem
|
||
DC.B -1 ; [$5D] General Purpose modem command (modem dependent) <H58>
|
||
DC.B -1 ; [$5E] -
|
||
DC.B -1 ; [$5F] -
|
||
|
||
DC.B 2 ; [$60] Set low power warning and cutoff levels
|
||
DC.B -1 ; [$61] -
|
||
DC.B -1 ; [$62] -
|
||
DC.B -1 ; [$63] -
|
||
DC.B -1 ; [$64]
|
||
DC.B -1 ; [$65] -
|
||
DC.B -1 ; [$66] -
|
||
DC.B -1 ; [$67] -
|
||
DC.B 0 ; [$68] Read Charger State, Battery Voltage, Temperature
|
||
DC.B 0 ; [$69] Read Instantaneous Charger, Battery, Temperature
|
||
DC.B 0 ; [$6A] Read low power warning and cutoff levels
|
||
DC.B 0 ; [$6B] Read Extended Battery Status
|
||
DC.B 0 ; [$6C] Read Battery ID
|
||
DC.B 0 ; [$6D] Battery Parameters
|
||
DC.B -1 ; [$6E] -
|
||
DC.B -1 ; [$6F] -
|
||
|
||
DC.B 1 ; [$70] Set One-Second Interrupt
|
||
DC.B 1 ; [$71] Modem Interrupt Control
|
||
DC.B 1 ; [$72] Set Modem Interrupt
|
||
DC.B -1 ; [$73] -
|
||
DC.B -1 ; [$74] -
|
||
DC.B -1 ; [$75] -
|
||
DC.B -1 ; [$76] -
|
||
DC.B -1 ; [$77] -
|
||
DC.B 0 ; [$78] Read Interrupt Flag Register.
|
||
DC.B 0 ; [$79] Read Modem Interrupt Data
|
||
DC.B -1 ; [$7A] -
|
||
DC.B -1 ; [$7B] -
|
||
DC.B -1 ; [$7C] -
|
||
DC.B -1 ; [$7D] -
|
||
DC.B 4 ; [$7E] Enter Shutdown Mode
|
||
DC.B 4 ; [$7F] Enter Sleep Mode
|
||
|
||
DC.B 4 ; [$80] Set Wakeup Timer
|
||
DC.B -1 ; [$81] -
|
||
DC.B 0 ; [$82] Disable Wakeup Timer
|
||
DC.B -1 ; [$83] -
|
||
DC.B -1 ; [$84] -
|
||
DC.B -1 ; [$85] -
|
||
DC.B -1 ; [$86] -
|
||
DC.B -1 ; [$87] -
|
||
DC.B 0 ; [$88] Read Wakeup Timer
|
||
DC.B -1 ; [$89] -
|
||
DC.B -1 ; [$8A] -
|
||
DC.B -1 ; [$8B] -
|
||
DC.B -1 ; [$8C] -
|
||
DC.B -1 ; [$8D] -
|
||
DC.B -1 ; [$8E] -
|
||
DC.B -1 ; [$8F] -
|
||
|
||
DC.B 1 ; [$90] Set Sound Control Bits
|
||
DC.B 2 ; [$91] Set DFAC Control Register
|
||
DC.B -1 ; [$92] -
|
||
DC.B -1 ; [$93] -
|
||
DC.B -1 ; [$94] -
|
||
DC.B -1 ; [$95] -
|
||
DC.B -1 ; [$96] -
|
||
DC.B -1 ; [$97] -
|
||
DC.B 0 ; [$98] Read Sound Control Status
|
||
DC.B 0 ; [$99] Read DFAC Control Register
|
||
DC.B -1 ; [$9A] -
|
||
DC.B -1 ; [$9B] -
|
||
DC.B -1 ; [$9C] -
|
||
DC.B -1 ; [$9D] -
|
||
DC.B -1 ; [$9E] -
|
||
DC.B -1 ; [$9F] -
|
||
|
||
DC.B 2 ; [$A0] Write Modem Register
|
||
DC.B 2 ; [$A1] Clear Modem Register Bits
|
||
DC.B 2 ; [$A2] Set Modem Register Bits
|
||
DC.B 4 ; [$A3] Write DSP RAM
|
||
DC.B -1 ; [$A4] Set Filter Coefficients
|
||
DC.B 0 ; [$A5] Reset Modem
|
||
DC.B -1 ; [$A6] -
|
||
DC.B -1 ; [$A7] -
|
||
DC.B 1 ; [$A8] Read Modem Register
|
||
DC.B 1 ; [$A9] Send Break
|
||
DC.B 3 ; [$AA] Dial Digit
|
||
DC.B 2 ; [$AB] Read DSP RAM
|
||
DC.B -1 ; [$AC] -
|
||
DC.B -1 ; [$AD] -
|
||
DC.B -1 ; [$AE] -
|
||
DC.B -1 ; [$AF] -
|
||
|
||
DC.B -1 ; [$B0] -
|
||
DC.B -1 ; [$B1] -
|
||
DC.B -1 ; [$B2] -
|
||
DC.B -1 ; [$B3] -
|
||
DC.B -1 ; [$B4] -
|
||
DC.B -1 ; [$B5] -
|
||
DC.B -1 ; [$B6] -
|
||
DC.B -1 ; [$B7] -
|
||
DC.B -1 ; [$B8] -
|
||
DC.B -1 ; [$B9] -
|
||
DC.B -1 ; [$BA] -
|
||
DC.B -1 ; [$BB] -
|
||
DC.B -1 ; [$BC] -
|
||
DC.B -1 ; [$BD] -
|
||
DC.B -1 ; [$BE] -
|
||
DC.B -1 ; [$BF] -
|
||
|
||
DC.B -1 ; [$C0] -
|
||
DC.B -1 ; [$C1] -
|
||
DC.B -1 ; [$C2] -
|
||
DC.B -1 ; [$C3] -
|
||
DC.B -1 ; [$C4] -
|
||
DC.B -1 ; [$C5] -
|
||
DC.B -1 ; [$C6] -
|
||
DC.B -1 ; [$C7] -
|
||
DC.B -1 ; [$C8] -
|
||
DC.B -1 ; [$C9] -
|
||
DC.B -1 ; [$CA] -
|
||
DC.B -1 ; [$CB] -
|
||
DC.B -1 ; [$CC] -
|
||
DC.B -1 ; [$CD] -
|
||
DC.B -1 ; [$CE] -
|
||
DC.B -1 ; [$CF] -
|
||
|
||
DC.B 0 ; [$D0] Reset CPU
|
||
DC.B -1 ; [$D1] -
|
||
DC.B -1 ; [$D2] -
|
||
DC.B -1 ; [$D3] -
|
||
DC.B -1 ; [$D4] -
|
||
DC.B -1 ; [$D5] -
|
||
DC.B -1 ; [$D6] -
|
||
DC.B -1 ; [$D7] -
|
||
DC.B 1 ; [$D8] Read A/D Status
|
||
DC.B 1 ; [$D9] Read User Input
|
||
DC.B -1 ; [$DA] -
|
||
DC.B -1 ; [$DB] -
|
||
DC.B 0 ; [$DC] read external switches
|
||
DC.B 0 ; [$DD] -
|
||
DC.B -1 ; [$DE] -
|
||
DC.B -1 ; [$DF] -
|
||
|
||
DC.B -1 ; [$E0] Write to internal PMGR memory
|
||
DC.B 4 ; [$E1] Download Flash EEPROM Code
|
||
DC.B 0 ; [$E2] Get Flash EEPROM Status
|
||
DC.B -1 ; [$E3] -
|
||
DC.B -1 ; [$E4] -
|
||
DC.B -1 ; [$E5] -
|
||
DC.B -1 ; [$E6] -
|
||
DC.B -1 ; [$E7] -
|
||
DC.B 3 ; [$E8] Read PMGR internal memory
|
||
DC.B -1 ; [$E9] -
|
||
DC.B 0 ; [$EA] Read PMGR firmware version number
|
||
DC.B -1 ; [$EB] -
|
||
DC.B 0 ; [$EC] Execute self test
|
||
DC.B -1 ; [$ED] PMGR diagnostics (selector-based)
|
||
DC.B -1 ; [$EE] -
|
||
DC.B 0 ; [$EF] PMGR soft reset
|
||
|
||
DC.B -1 ; [$F0] -
|
||
DC.B -1 ; [$F1] -
|
||
DC.B -1 ; [$F2] -
|
||
DC.B -1 ; [$F3] -
|
||
DC.B -1 ; [$F4] -
|
||
DC.B -1 ; [$F5] -
|
||
DC.B -1 ; [$F6] -
|
||
DC.B -1 ; [$F7] -
|
||
DC.B -1 ; [$F8] -
|
||
DC.B -1 ; [$F9] -
|
||
DC.B -1 ; [$FA] -
|
||
DC.B -1 ; [$FB] -
|
||
DC.B -1 ; [$FC] -
|
||
DC.B -1 ; [$FD] -
|
||
DC.B -1 ; [$FE] -
|
||
DC.B -1 ; [$FF] -
|
||
|
||
|
||
; This table is used to determine how the 680x0 needs to handle the reply:
|
||
;
|
||
; =0: no reply should be expected.
|
||
; =1: only a reply byte will be sent (this is a special case for a couple of commands)
|
||
; <0: a reply is expected and the PMGR will send a count byte.
|
||
; >1: a reply is expected and the PMGR will not send a count byte,
|
||
; but the count will be (value-1).
|
||
;
|
||
; Unused commands in the range $x8 to $xF will be marked as expecting a reply (with count)
|
||
; so that commands may be added without having to change the ROM.
|
||
|
||
replyCounts DC.B 0 ; [$00] -
|
||
DC.B 0 ; [$01] -
|
||
DC.B 0 ; [$02] -
|
||
DC.B 0 ; [$03] -
|
||
DC.B 0 ; [$04] -
|
||
DC.B 0 ; [$05] -
|
||
DC.B 0 ; [$06] -
|
||
DC.B 0 ; [$07] -
|
||
DC.B -1 ; [$08] -
|
||
DC.B -1 ; [$09] -
|
||
DC.B -1 ; [$0A] -
|
||
DC.B -1 ; [$0B] -
|
||
DC.B -1 ; [$0C] -
|
||
DC.B -1 ; [$0D] -
|
||
DC.B -1 ; [$0E] -
|
||
DC.B -1 ; [$0F] -
|
||
|
||
DC.B 0 ; [$10] Subsystem Power/Clock Control
|
||
DC.B 0 ; [$11] Subsystem Power/Clock Control (yet more)
|
||
DC.B 0 ; [$12] -
|
||
DC.B 0 ; [$13] -
|
||
DC.B 0 ; [$14] -
|
||
DC.B 0 ; [$15] -
|
||
DC.B 0 ; [$16] -
|
||
DC.B 0 ; [$17] -
|
||
DC.B 1+1 ; [$18] Read Power/Clock Status
|
||
DC.B 1+1 ; [$19] Read Power/Clock Status (yet more)
|
||
DC.B -1 ; [$1A] -
|
||
DC.B -1 ; [$1B] -
|
||
DC.B -1 ; [$1C] -
|
||
DC.B -1 ; [$1D] -
|
||
DC.B -1 ; [$1E] -
|
||
DC.B 0 ; [$1F] RESERVED FOR MSC/PG&E EMULATION
|
||
|
||
DC.B 0 ; [$20] Set New Apple Desktop Bus Command
|
||
DC.B 0 ; [$21] ADB Autopoll Abort
|
||
DC.B 0 ; [$22] ADB Set Keyboard Addresses
|
||
DC.B 0 ; [$23] ADB Set Hang Threshold
|
||
DC.B 0 ; [$24] ADB Enable/Disable Programmers Key
|
||
DC.B 0 ; [$25] -
|
||
DC.B 0 ; [$26] -
|
||
DC.B 0 ; [$27] -
|
||
DC.B -1 ; [$28] ADB Transaction Read
|
||
DC.B -1 ; [$29] -
|
||
DC.B -1 ; [$2A] -
|
||
DC.B -1 ; [$2B] -
|
||
DC.B -1 ; [$2C] -
|
||
DC.B -1 ; [$2D] -
|
||
DC.B -1 ; [$2E] -
|
||
DC.B -1 ; [$2F] -
|
||
|
||
DC.B 0 ; [$30] Set Realtime Clock.
|
||
DC.B 0 ; [$31] Write Parameter RAM
|
||
DC.B 0 ; [$32] Write Extended Parameter RAM.
|
||
DC.B 0 ; [$33] -
|
||
DC.B 0 ; [$34] -
|
||
DC.B 0 ; [$35] -
|
||
DC.B 0 ; [$36] -
|
||
DC.B 0 ; [$37] -
|
||
DC.B 4+1 ; [$38] Read Realtime Clock.
|
||
DC.B 20+1 ; [$39] Read Parameter RAM
|
||
DC.B -1 ; [$3A] Read Extended Parameter RAM.
|
||
DC.B -1 ; [$3B] -
|
||
DC.B -1 ; [$3C] -
|
||
DC.B -1 ; [$3D] -
|
||
DC.B -1 ; [$3E] -
|
||
DC.B -1 ; [$3F] -
|
||
|
||
DC.B 0 ; [$40] Set Screen Contrast
|
||
DC.B 0 ; [$41] Set Screen Brightness <H4>
|
||
DC.B 0 ; [$42] -
|
||
DC.B 0 ; [$43] -
|
||
DC.B 0 ; [$44] -
|
||
DC.B 0 ; [$45] -
|
||
DC.B 0 ; [$46] -
|
||
DC.B 0 ; [$47] -
|
||
DC.B 1+1 ; [$48] Read Screen Contrast
|
||
DC.B 1+1 ; [$49] Read Screen Brightness
|
||
DC.B -1 ; [$4A] -
|
||
DC.B -1 ; [$4B] -
|
||
DC.B -1 ; [$4C] -
|
||
DC.B -1 ; [$4D] -
|
||
DC.B -1 ; [$4E] -
|
||
DC.B -1 ; [$4F] -
|
||
|
||
DC.B 0 ; [$50] Set Internal Modem Control Bits
|
||
DC.B 0 ; [$51] Clear FIFOs
|
||
DC.B 0 ; [$52] Set FIFO Interrupt Marks
|
||
DC.B 0 ; [$53] Set FIFO Sizes
|
||
DC.B 0 ; [$54] Write Data to Modem
|
||
DC.B 0 ; [$55] Set Data Mode
|
||
DC.B 0 ; [$56] Set Flow Control Mode
|
||
DC.B 0 ; [$57] Set DAA control lines <H54>
|
||
DC.B 1+1 ; [$58] Read Internal Modem Status
|
||
DC.B 0 ; [$59] Get DAA Identification <H55>
|
||
DC.B 2+1 ; [$5A] Get FIFO Counts
|
||
DC.B 2+1 ; [$5B] Get Maximum FIFO Sizes
|
||
DC.B -1 ; [$5C] Read Data From Modem
|
||
DC.B -1 ; [$5D] General Purpose modem command (modem dependent) <H58>
|
||
DC.B -1 ; [$5E] -
|
||
DC.B -1 ; [$5F] -
|
||
|
||
DC.B 0 ; [$60] Set low power warning and cutoff levels
|
||
DC.B 0 ; [$61] -
|
||
DC.B 0 ; [$62] -
|
||
DC.B 0 ; [$63] -
|
||
DC.B 0 ; [$64] -
|
||
DC.B 0 ; [$65] -
|
||
DC.B 0 ; [$66] -
|
||
DC.B 0 ; [$67] -
|
||
DC.B 3+1 ; [$68] Read Charger State, Battery Voltage, Temperature
|
||
DC.B 3+1 ; [$69] Read Instantaneous Charger, Battery, Temperature
|
||
DC.B 2+1 ; [$6A] Read low power warning and cutoff levels
|
||
DC.B 8+1 ; [$6B] Read Extended Battery Status
|
||
DC.B -1 ; [$6C] Read Battery ID
|
||
DC.B -1 ;10+1 ; [$6D] Battery Parameters
|
||
DC.B -1 ; [$6E] -
|
||
DC.B -1 ; [$6F] -
|
||
|
||
DC.B 0 ; [$70] Set One-Second Interrupt
|
||
DC.B 0 ; [$71] Modem Interrupt Control
|
||
DC.B 0 ; [$72] Set Modem Interrupt
|
||
DC.B 0 ; [$73] -
|
||
DC.B 0 ; [$74] -
|
||
DC.B 0 ; [$75] -
|
||
DC.B 0 ; [$76] -
|
||
DC.B 0 ; [$77] -
|
||
DC.B -1 ; [$78] Read Interrupt Flag Register.
|
||
DC.B -1 ; [$79] Read Modem Interrupt Data
|
||
DC.B -1 ; [$7A] -
|
||
DC.B -1 ; [$7B] -
|
||
DC.B -1 ; [$7C] -
|
||
DC.B -1 ; [$7D] -
|
||
DC.B 0+1 ; [$7E] Enter Shutdown Mode
|
||
DC.B 0+1 ; [$7F] Enter Sleep Mode
|
||
|
||
DC.B 0 ; [$80] Set Wakeup Timer
|
||
DC.B 0 ; [$81] -
|
||
DC.B 0 ; [$82] Disable Wakeup Timer
|
||
DC.B 0 ; [$83] -
|
||
DC.B 0 ; [$84] -
|
||
DC.B 0 ; [$85] -
|
||
DC.B 0 ; [$86] -
|
||
DC.B 0 ; [$87] -
|
||
DC.B 5+1 ; [$88] Read Wakeup Timer
|
||
DC.B -1 ; [$89] -
|
||
DC.B -1 ; [$8A] -
|
||
DC.B -1 ; [$8B] -
|
||
DC.B -1 ; [$8C] -
|
||
DC.B -1 ; [$8D] -
|
||
DC.B -1 ; [$8E] -
|
||
DC.B -1 ; [$8F] -
|
||
|
||
DC.B 0 ; [$90] Set Sound Control Bits
|
||
DC.B 0 ; [$91] Set DFAC Control Register
|
||
DC.B 0 ; [$92] -
|
||
DC.B 0 ; [$93] -
|
||
DC.B 0 ; [$94] -
|
||
DC.B 0 ; [$95] -
|
||
DC.B 0 ; [$96] -
|
||
DC.B 0 ; [$97] -
|
||
DC.B 1+1 ; [$98] Read Sound Control Status
|
||
DC.B 1+1 ; [$99] Read DFAC Control Register
|
||
DC.B -1 ; [$9A] -
|
||
DC.B -1 ; [$9B] -
|
||
DC.B -1 ; [$9C] -
|
||
DC.B -1 ; [$9D] -
|
||
DC.B -1 ; [$9E] -
|
||
DC.B -1 ; [$9F] -
|
||
|
||
DC.B 0 ; [$A0] Write Modem Register
|
||
DC.B 0 ; [$A1] Clear Modem Register Bits
|
||
DC.B 0 ; [$A2] Set Modem Register Bits
|
||
DC.B 0 ; [$A3] Write DSP RAM
|
||
DC.B 0 ; [$A4] Set Filter Coefficients
|
||
DC.B 0 ; [$A5] Reset Modem
|
||
DC.B 0 ; [$A6] -
|
||
DC.B 0 ; [$A7] -
|
||
DC.B 1+1 ; [$A8] Read Modem Register
|
||
DC.B 0 ; [$A9] Send Break
|
||
DC.B 0 ; [$AA] Dial Digit
|
||
DC.B 0 ; [$AB] Read DSP RAM
|
||
DC.B -1 ; [$AC] -
|
||
DC.B -1 ; [$AD] -
|
||
DC.B -1 ; [$AE] -
|
||
DC.B -1 ; [$AF] -
|
||
|
||
DC.B 0 ; [$B0] -
|
||
DC.B 0 ; [$B1] -
|
||
DC.B 0 ; [$B2] -
|
||
DC.B 0 ; [$B3] -
|
||
DC.B 0 ; [$B4] -
|
||
DC.B 0 ; [$B5] -
|
||
DC.B 0 ; [$B6] -
|
||
DC.B 0 ; [$B7] -
|
||
DC.B -1 ; [$B8] -
|
||
DC.B -1 ; [$B9] -
|
||
DC.B -1 ; [$BA] -
|
||
DC.B -1 ; [$BB] -
|
||
DC.B -1 ; [$BC] -
|
||
DC.B -1 ; [$BD] -
|
||
DC.B -1 ; [$BE] -
|
||
DC.B -1 ; [$BF] -
|
||
|
||
DC.B 0 ; [$C0] -
|
||
DC.B 0 ; [$C1] -
|
||
DC.B 0 ; [$C2] -
|
||
DC.B 0 ; [$C3] -
|
||
DC.B 0 ; [$C4] -
|
||
DC.B 0 ; [$C5] -
|
||
DC.B 0 ; [$C6] -
|
||
DC.B 0 ; [$C7] -
|
||
DC.B -1 ; [$C8] -
|
||
DC.B -1 ; [$C9] -
|
||
DC.B -1 ; [$CA] -
|
||
DC.B -1 ; [$CB] -
|
||
DC.B -1 ; [$CC] -
|
||
DC.B -1 ; [$CD] -
|
||
DC.B -1 ; [$CE] -
|
||
DC.B -1 ; [$CF] -
|
||
|
||
DC.B 0 ; [$D0] Reset CPU
|
||
DC.B 0 ; [$D1] -
|
||
DC.B 0 ; [$D2] -
|
||
DC.B 0 ; [$D3] -
|
||
DC.B 0 ; [$D4] -
|
||
DC.B 0 ; [$D5] -
|
||
DC.B 0 ; [$D6] -
|
||
DC.B 0 ; [$D7] -
|
||
DC.B 1+1 ; [$D8] Read A/D Status
|
||
DC.B 1+1 ; [$D9] Read User Input
|
||
DC.B -1 ; [$DA] -
|
||
DC.B -1 ; [$DB] -
|
||
DC.B 1+1 ; [$DC] read external switches
|
||
DC.B -1 ; [$DD] -
|
||
DC.B -1 ; [$DE] -
|
||
DC.B -1 ; [$DF] -
|
||
|
||
DC.B 0 ; [$E0] Write to internal PMGR memory
|
||
DC.B 0 ; [$E1] Download Flash EEPROM Code
|
||
DC.B 0+1 ; [$E2] Get Flash EEPROM Status
|
||
DC.B 0 ; [$E3] -
|
||
DC.B 0 ; [$E4] -
|
||
DC.B 0 ; [$E5] -
|
||
DC.B 0 ; [$E6] -
|
||
DC.B 0 ; [$E7] -
|
||
DC.B -1 ; [$E8] Read PMGR internal memory
|
||
DC.B -1 ; [$E9] -
|
||
DC.B 1+1 ; [$EA] Read PMGR firmware version number
|
||
DC.B -1 ; [$EB] -
|
||
DC.B -1 ; [$EC] Execute self test
|
||
DC.B -1 ; [$ED] PMGR diagnostics (selector-based)
|
||
DC.B -1 ; [$EE] -
|
||
DC.B 0 ; [$EF] PMGR soft reset
|
||
|
||
DC.B 0 ; [$F0] -
|
||
DC.B 0 ; [$F1] -
|
||
DC.B 0 ; [$F2] -
|
||
DC.B 0 ; [$F3] -
|
||
DC.B 0 ; [$F4] -
|
||
DC.B 0 ; [$F5] -
|
||
DC.B 0 ; [$F6] -
|
||
DC.B 0 ; [$F7] -
|
||
DC.B -1 ; [$F8] -
|
||
DC.B -1 ; [$F9] -
|
||
DC.B -1 ; [$FA] -
|
||
DC.B -1 ; [$FB] -
|
||
DC.B -1 ; [$FC] -
|
||
DC.B -1 ; [$FD] -
|
||
DC.B -1 ; [$FE] -
|
||
DC.B -1 ; [$FF] -
|
||
|
||
;________________________________________________________________________________________ <K11>
|
||
;
|
||
; _CommsPower - Communications' port power control
|
||
; _SerialPower ($A685) - Serial port power control
|
||
;
|
||
; Enter with: D0 = bit pattern
|
||
; BIT INDICATION
|
||
; 0 1 = ignore internal modem
|
||
; 1 not used
|
||
; 2-6 0000 = Do something to port B serial
|
||
; 0001 = Do something to port A serial/modem
|
||
; 0010 = Do something to port C modem
|
||
; 0011 = Do something to Ethernet Port
|
||
; 0100 thru 1111 are not used (yet)
|
||
; 7 1 = power port OFF
|
||
; 0 = power port ON
|
||
; Enter with: D1 - trap word
|
||
;
|
||
; Implementation:
|
||
; The SerialPower (now also CommsPower) code now resides in the CommsPowerTables of the
|
||
; Power Manager Primitives.
|
||
;
|
||
; History:
|
||
; The TIM internal (serial) modem is multiplexed thru port A. So bit 0 controls
|
||
; the use of the internal modem. When port C was created (for Dart), the used of it
|
||
; was backpatched to TIM. Now if you power ON port A and a serial modem is installed,
|
||
; as in TIM, the 'power A ON' code calls 'power C ON', which turns the modem on.
|
||
;
|
||
; On Dart, the internal modem is not multiplexed thru serial port A. To Power on the
|
||
; modem, call 'power C ON' directly.
|
||
;
|
||
; On Blackbird, the internal modem is not multiplexed thru serial port A. To Power on the
|
||
; modem, call 'power C ON' directly. Onboard Ethernet is treated like another port; Call
|
||
; 'Power Enet ON' directly.
|
||
;
|
||
; To power the SONIC LP:
|
||
; Turn on power to the SONIC (assert Whitney signal ENET_RESET_L)
|
||
; Wait for crystal to stabilize (50 ms, a LONG time)
|
||
; Deassert SLEEP line (deassert Whitney signal ENET_RESET_L)
|
||
;
|
||
; -------------------
|
||
; For Posterity, the TIM Algorithm:
|
||
; Determine what needs to be powered on for the SCC port that is being opened. There
|
||
; are two SCC ports (A/B) which may be connected to the external ports (the modem and
|
||
; printer ports), or the internal modem (for port B only).
|
||
;
|
||
; The following is a summary of the devices and which power manager commands to use
|
||
; to control them.
|
||
;
|
||
; device Pmgr cmd port0 bit signal name
|
||
; ----- --------- ------- -----------
|
||
; SCC powerCntl P01/sccOn *SCC_CNTL
|
||
; external port powerCntl P04/serOn *SERIAL_POWER
|
||
; internal modem powerCntl P03/ModemOn MODEM_PWR
|
||
; modemSet P06 *MODEM_PWROUT
|
||
;
|
||
; Additionally for the internal modem, MODEM_RESET (a Orca/via2 signal) must be
|
||
; manipulated by changing it from an input to and output to de-assert reset.
|
||
;
|
||
; Powering on the SCC and the external ports only involves sending the correct power
|
||
; manager commands. Powering on the internal modem involves some timing delays and a
|
||
; specific sequence of commands.
|
||
;
|
||
; To power the SCC and external ports:
|
||
; turn on SCC
|
||
; turn on external line drivers
|
||
;
|
||
; To power the internal modem:
|
||
; make MODEM_RESET an input (to assert reset) - signal will float up
|
||
; turn on +5V and -5V to modem (MODEM_PWROUT)
|
||
; wait >2ms to allow +5V and -5V to settle
|
||
; enable the modem (*MODEM_PWR)
|
||
; turn on SCC
|
||
; wait >5ms to allow reset time
|
||
; make MODEM_RESET an output
|
||
; write a zero to MODEM_RESET to de-assert reset - drive it low
|
||
;
|
||
;________________________________________________________________________________________
|
||
CommsPower
|
||
SerialPower
|
||
with PrimInfoTbleRec,PmgrRec,PmgrPramRec,PmgrPrimitivesRec,ModemTblRec,CommsPwrTblRec
|
||
@workregs REG d1-d2/a0 ; <K19>
|
||
movem.l @workregs,-(sp) ; save our regs <K19>
|
||
|
||
move.l PMgrBase, a0 ; point to Power Manager globals <K14>
|
||
LoadTbl PmgrCommTblPtr,a0,a0 ; get pointer to Comms Power primitive table <K14>
|
||
beq @OutOfRange ; sorry no table
|
||
|
||
clr.l d1 ; clear work register
|
||
move.w d0,d1 ; get a copy of d0 to work on
|
||
asr.w #2,d1 ; right justify selector field
|
||
andi.w #$1f,d1 ; mask only selector field
|
||
|
||
move.l CommsPwrCount(a0), d2 ; length of table
|
||
asr.l #2, d2 ; number of entries in table
|
||
asr.l #1, d2 ; half as many valid selectors as entries
|
||
cmp.l d2, d1 ; are we in range?
|
||
bhs.s @OutOfRange ; no, so punt
|
||
|
||
btst #7,d0 ; is it on or off
|
||
beq.s @on ; on, so look at first half of table
|
||
|
||
add.l d2, d1 ; off, so look at second half of table
|
||
@on
|
||
tst.l ([a0, d1.l*4]) ; is there a routine?
|
||
beq.s @done ; zero offset means no rtn
|
||
jsr ([a0, d1.l*4]) ; go execute routine <K19>
|
||
moveq #noErr, d0 ; everything just dandy <K19>
|
||
bra.s @done ; <K19>
|
||
|
||
@OutOfRange
|
||
MOVE.W #paramErr,D0 ; Abort and return error
|
||
@done movem.l (sp)+,@workregs ; restore our regs <K19>
|
||
RTS
|
||
|
||
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ <t28> djw
|
||
; Modem Sound Interrupt Handlers
|
||
;
|
||
; Modem sound on Tim is implemented through DFAC's aux channel. The modem demands
|
||
; and releases the sound path through the MODEM_SND_ENABLE signal (on VIA1 CB2). The
|
||
; system monitors that bit to determine whether it should enable or disable the modem
|
||
; sound path.
|
||
;
|
||
; When the modem is powered, a CB2 interrupt handler is installed. When the modem
|
||
; demands sound, we immediately enable the sound path. The interrupt handler then
|
||
; re-configures the VIA CB2 interrupt to trigger on the falling edge. A new interrupt
|
||
; handler is installed which disables the sound path. The interrupt handlers ping-pongs
|
||
; back a
|
||
;
|
||
; Input: none
|
||
; Output: none
|
||
;
|
||
|
||
ModemSndOnInt
|
||
move.b #(1<<ifCB2),([VIA],vIFR) ; clear interrupt flag reg
|
||
move.b SDVolume,d0 ; get current volume <H37>
|
||
jsrTBL sndPlayThruVol ; set volume for playthrough <H37>
|
||
moveq.l #sndAuxiliary,d0 ; <H37>
|
||
jsrTbl sndInputSelect ; select aux source <H37>
|
||
|
||
bclr.b #6,([VIA],vPCR) ; change from pos to neg edge int
|
||
lea ModemSndOffInt,a0 ; disable sound routine
|
||
move.l a0,jModemSnd ; install in Level 1 VIA1 dispatch table
|
||
|
||
rts
|
||
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ <H59>
|
||
; Modem Sound Interrupt Handlers |
|
||
; V
|
||
; Modem sound on Tim is implemented through DFAC's aux channel. The modem demands
|
||
; and releases the sound path through the MODEM_SND_ENABLE signal (on VIA1 CB2). The
|
||
; system monitors that bit to determine whether it should enable or disable the modem
|
||
; sound path.
|
||
;
|
||
; When the modem is powered, a CB2 interrupt handler is installed. When the modem
|
||
; demands sound, we immediately enable the sound path. The interrupt handler then
|
||
; re-configures the VIA CB2 interrupt to trigger on the falling edge. A new interrupt
|
||
; handler is installed which disables the sound path. The interrupt handlers ping-pongs
|
||
; back a
|
||
;
|
||
; Input: none
|
||
; Output: none
|
||
;
|
||
ModemSndOffInt
|
||
move.b #(1<<ifCB2),([VIA],vIFR) ; clear interrupt flag reg
|
||
moveq.l #0,d0 ; disable playthrough
|
||
jsrTBL sndPlayThruVol ;
|
||
moveq.l #sndInputOff,d0
|
||
jsrTbl sndInputSelect ; disable aux source
|
||
|
||
bset.b #6,([VIA],vPCR) ; change from neg to pos edge int
|
||
lea ModemSndOnInt,a0 ; enable sound routine
|
||
move.l a0,jModemSnd ; install in Level 1 VIA1 disÅ table
|
||
|
||
rts
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; IdleState ($A485) - Increments/decrements the idle enable flag count and returns
|
||
; the current speed.
|
||
;
|
||
; Enter with: D0 < 0, read speed
|
||
; Exit with: D0 = current speed
|
||
;
|
||
; Enter with: D0 = 0, enable idle
|
||
; Exit with: D0 = idle disable count
|
||
;
|
||
; Enter with: D0 > 0, disable idle
|
||
; Exit with: D0 = idle disable count
|
||
;________________________________________________________________________________________
|
||
IdleState
|
||
TST.L D0 ; What selector do we have
|
||
BGT IdleDisable ; D0 > 0
|
||
BEQ IdleEnable ; D0 = 0
|
||
BMI IdleRead ; D0 < 0
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; GoToSleep, WakeUp, SleepQInstall, SleepQRemove
|
||
;
|
||
; Enter : D1 = trap word
|
||
; D0 = Sleep type
|
||
;
|
||
; Exit : All regs unchanged
|
||
;
|
||
; SlpQInstall adds a sleep queue entry into the sleep queue.
|
||
;
|
||
; SlpQRemove deletes a sleep queue entry from the sleep queue.
|
||
;
|
||
; GoToSleep is called by the event manager when it determines that
|
||
; there is no work being done. Drivers are called to save their state,
|
||
; then the PMGR is ordered to put the system to sleep. When a waking
|
||
; event occurs, the PMGR powers up the system. The reset code jumps to
|
||
; WakeUp if the sleep flag is set. WakeUp restores the system hardware
|
||
; state, reloads the 68000 regs, and returns to the calling routine.
|
||
;________________________________________________________________________________________
|
||
|
||
GoToSleep BTST #9,D1 ; $A28A
|
||
BNE SlpQInstall
|
||
BTST #10,D1 ; $A48A
|
||
BNE SlpQRemove
|
||
*** BRA @Sleep ; $A08A
|
||
@Sleep
|
||
MOVE.L PMgrBase,A0 ; Get Power Manager Base Pointer
|
||
BSET #InSleep,PmgrFlags(A0) ; test and set sleep semaphore
|
||
BNE.S @Exit ; if in sleep, exit! don't re-enter
|
||
|
||
MOVE.L D0,D1 ; Save the sleep type
|
||
BSR.W SetSupervisorMode ; Set the machine to supervisor mode
|
||
MOVE.W D0,SaveCPUState.\
|
||
CPUSRsave(A0) ; Save the store away the status register
|
||
MOVE.W D0,PwrCycSave.\
|
||
PCRSRsave(A0) ; Save this stupid value for historical purposes
|
||
MOVE.L D1,D0 ; restore the sleep type
|
||
BSR.S TakeASnooze ; Take a snooze
|
||
MOVE.W SaveCPUState.\
|
||
CPUSRsave(A0),SR ; Restore the Status Register to the proper world
|
||
@Exit
|
||
RTS
|
||
|
||
;________________________________________________________________________________________
|
||
;________________________________________________________________________________________
|
||
|
||
TakeASnooze
|
||
SleepRegs REG A0-A6/D1-D7
|
||
MOVEM.L SleepRegs,-(SP) ; Save registers
|
||
MOVE.L D0,D2 ; Save a sleep type in D2
|
||
|
||
@checkinprogress
|
||
BTST #dockNoSleep,\
|
||
dockFlags(A0) ; is sleeping allowed (if we're connected to a bar)
|
||
BEQ.S @checkAuto ; -> yes, onward!
|
||
BSR.L DockingSleepDenied ; have the Docking Manager put up a notification
|
||
BRA AbortSleep ; then abort!
|
||
|
||
@checkAuto CMP.B #SleepRequest,D0 ; auto sleep request
|
||
BEQ.S @validselector
|
||
|
||
@checkDnd CMP.B #SleepDemand,D0 ; User sleep, from finder or command key
|
||
BEQ.S @validselector
|
||
|
||
@checkNow CMP.B #SleepNow,D0 ; Critical low power sleep
|
||
BNE AbortSleep
|
||
|
||
@validselector
|
||
MOVE.W SaveCPUState.\
|
||
CPUSRsave(A0),SR ; Restore the SR so that when VM is on the queue is run in User Mode
|
||
|
||
BCLR #AvoidNetDiag,\
|
||
PmgrFlags(A0) ; tst/clear the avoid bit
|
||
BNE.S @traverse ; if bit was set, skip dialog
|
||
|
||
MOVE.L SleepNetHook(A0),D1 ; IF SleepNetHook present THEN
|
||
BEQ.S @nextHook ;
|
||
MOVEA.L D1,A1 ; Get pointer
|
||
JSR (A1) ; Call Hook
|
||
BNE AbortSleep ; IF Bad Close THEN exit
|
||
@nextHook ; ELSE
|
||
MOVE.L SleepHook(A0),D1 ; IF SleepNetHook present THEN
|
||
BEQ.S @closeAT ;
|
||
MOVEA.L D1,A1 ; Get pointer
|
||
JSR (A1) ; Call Hook
|
||
@closeAT ; ENDIF
|
||
BSR.W CheckAppleTalk ; Close AppleTalk
|
||
BNE AbortSleep ; Branch if close denied
|
||
|
||
@traverse MOVE.W D2,D0 ; Restore D0
|
||
CMP.W #SleepNow,D0 ; If passing sleepnow to sleepq then change it
|
||
BNE.S @doQ ; to a sleep demand
|
||
MOVEQ #SleepDemand,D0 ; sleepNow -> sleepDemand
|
||
|
||
@doQ BSR.W DoQueueStack ; Walk the queue
|
||
MOVE.L D0,D1 ; Save a copy of DoQueueStack result
|
||
BSR.W SetSupervisorMode ; Return to supervisor mode so that we may continue
|
||
TST.L D1 ; DoQueueStack == Ok to goto sleep ?
|
||
BNE.W AbortSleep ; Nope. Get out!
|
||
BSR.W CloseAppleTalk ; Else shut down atalk
|
||
BCLR #InSleep,PmgrFlags(A0) ; clr the sleep indicator
|
||
|
||
BCLR #PmgrShutdownEnb,\
|
||
PmgrFlags1(A0) ; disable shutdown across sleep
|
||
|
||
MOVEA.L A0,A2 ; A2 = Power Manager Vars
|
||
BSR.W SaveSetCrsr ; Save and Set cursor to a watch cursor
|
||
|
||
; run thru the table of machine-specific operations to perform for going to sleep...
|
||
ORI.W #HiIntMask,SR ; Disable interrupts
|
||
BackToSleep
|
||
LoadTbl SleepTblPtr,A2,A0 ; get pointer to the SleepTable
|
||
LEA @Resume,A1 ; set up return address in A1
|
||
BRA.S @Resume ; WHILE tableItem != NIL DO {
|
||
@SaveLoop MOVEA.L D0,A2 ; get address of calling routine
|
||
JMP (A2) ; do the routine
|
||
@Resume MOVE.L (A0)+,D0 ; increment to the next table item
|
||
BNE.S @SaveLoop ; }
|
||
|
||
BRA.S * ; wait for sleep (yawn...)
|
||
|
||
AbortSleep BSR.W SetSupervisorMode ; Set the machine to supervisor mode
|
||
BCLR #InSleep,PmgrFlags(A0) ; Clear the sleep indicator
|
||
MOVE.W D2,D0 ; Restore sleep type to D0
|
||
MOVEM.L (SP)+,SleepRegs
|
||
RTS ; Return to caller
|
||
|
||
;________________________________________________________________________________________
|
||
; WakeUp is reached from the reset (power up) code if the sleep flag is set.
|
||
;
|
||
; Enter : A2 = Pointer to Pmgr Globals
|
||
; Exit : All regs unchanged
|
||
;________________________________________________________________________________________
|
||
WakeUp
|
||
ORI.W #HiIntMask,SR ; no more interrupts
|
||
MOVEA.L PmgrBase,A0 ; make sure that we have pointer to PmgrBase
|
||
LoadTbl WakeTblPtr,A0,A0 ; get pointer to the WakeTable
|
||
LEA @Resume,A1 ; set up return address in A1
|
||
BRA.S @Resume ; WHILE tableItem != NIL DO {
|
||
@RestoreLp MOVEA.L D0,A2 ; get address of calling routine
|
||
JMP (A2) ; do the routine
|
||
@Resume MOVE.L (A0)+,D0 ; increment to the next table item
|
||
BNE.S @RestoreLp ; }
|
||
|
||
MOVEA.L PmgrBase,A2 ; point to the Power Manager globals <H47>
|
||
BTST #dockNoWakeup,\ ; <H47>
|
||
dockFlags(A2) ; can we wakeup with this bar attached? <H47>
|
||
BEQ.S @CanWakeup ; -> yes, continue waking up <H47>
|
||
MOVEM.L (SP),SleepRegs ; restore the registers but don't touch the stack <H47>
|
||
MOVEA.L PmgrBase,A2 ; point to the Power Manager globals again <H47>
|
||
BSR.L DockingWakeupDenied ; setup the notification message <H47>
|
||
BRA BackToSleep ; then go put the machine back to sleep <H47>
|
||
@CanWakeup ; <H47>
|
||
MOVEM.L (SP),SleepRegs ; Restore the registers but don't touch the stack
|
||
|
||
BSR.L SCSIDiskWakeAlert ; check if a disk mode cable is plugged in <H64>
|
||
BSR.L InitSCSIHW ; Init the SCSI chip
|
||
|
||
LEA Time,A0 ; load parameter for ReadDateTime
|
||
_ReadDateTime
|
||
|
||
BSR KbdReset ; clear the keyboard maps
|
||
|
||
MOVEA.L PmgrBase,A2 ; Get Power Manager globals base
|
||
TST.L WakeUpHook(A2) ; Do we have a sleep hook?
|
||
BEQ.S @noHook ; Nope... go on
|
||
MOVE.L WakeUpHook(A2),A0 ; Get the sleep hook
|
||
JSR (A0) ; Go do it...
|
||
@noHook
|
||
MOVE.W SaveCPUState.\
|
||
CPUSRsave(A2),SR ; Restore the SR so that when VM is on the queue is run in User Mode
|
||
_ADBReInit ; Init the ADB devices <H56>
|
||
_ShowCursor ; Alive now tell the user it's OK <H56>
|
||
|
||
BSR.W MPPOpen ; Open the driver since elements in the queue might need some MPP services
|
||
MOVEQ #SleepWakeUp,D0 ; Go through wake queue
|
||
BSR.W DoQueue ; Run through the queue in proper order
|
||
|
||
MOVEA.L PmgrBase,A2 ; Get Power Manager globals base
|
||
BSR.W RemoveMsg
|
||
CLR.B Level4Cnt(A2) ; Clear level 4 count down timer
|
||
MOVE.B #-1,LastLevel(A2) ; Reset battery level <v2.8>
|
||
CLR.L BatQ(A2) ; Clear queue
|
||
CLR.L BatQ+4(A2)
|
||
MOVE.B #8,BatQIndex(A2) ; Reset index
|
||
|
||
BCLR #PmgrShutdownReq,\
|
||
PmgrFlags1(A2) ; clear any shutdown request <H37>
|
||
BSET #PmgrShutdownEnb,\
|
||
PmgrFlags1(A2) ; enable shutdown <H37>
|
||
|
||
BSR.W RestoreScreen ; Restore cursor and screen and back into the world.
|
||
BSR.W SetSupervisorMode ; Return to supervisor mode <H66>
|
||
MOVEM.L (SP)+,SleepRegs ; Now really restore the world
|
||
MOVEQ #0,D0 ; and return a zero result <H69>
|
||
RTS
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; CheckAppleTalk - checks AppleTalk drivers depending on the sleep
|
||
; level, what is open, and what the user OK's.
|
||
;
|
||
;________________________________________________________________________________________
|
||
|
||
STRING PASCAL
|
||
CheckAppleTalk
|
||
MOVEM.L A0-A3/D1-D2,-(SP) ; Try to close AppleTalk and warn user of this <v1.4>
|
||
SUB.W #ioQElSize,SP ; Allocate IO stack frame
|
||
MOVE.L SP,A3 ; Save this place
|
||
|
||
MOVE.L PmgrBase,A2 ;
|
||
MOVEQ #$0F,D1 ; Lower nibble indicates ATalk in use
|
||
AND.B PortBUse,D1
|
||
CMP.B #1,D1
|
||
BNE @okexit ; Do exit if no Atalk
|
||
|
||
MOVE.W D0,D1 ; Case on request, demand, and now sleeps
|
||
CMP.B #SleepRequest,D0 ; Request case
|
||
BNE.S @dmndcase
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
; Request sleep (time out) case. If plugged in or chooser bit set or server mounted then sleep
|
||
; denied, else ok.
|
||
;________________________________________________________________________________________
|
||
|
||
@reqcase BTST #noATChg,ChooserBits ; If magic chooser bit set then no sleep
|
||
BEQ @done
|
||
|
||
BTST #HasCharger,Charger(A2) ; If plugged in then no sleep
|
||
BNE @done
|
||
|
||
BTST #XPPLoadedBit,PortBUse ; Test for XPP in use
|
||
BNE.S @reqcase1 ; Branch if so
|
||
|
||
MOVE.B #ClosedMPP,WakeWarn(A2) ; Set flag for wake up warning (MPP closed)
|
||
BRA @okexit ; Bye now
|
||
|
||
@reqcase1 BSR XPPCheck ; Try to close XPP
|
||
BNE @done ; Branch if not
|
||
|
||
MOVE.B #ClosedXPP,WakeWarn(A2) ; Set flag for wake up warning (XPP closed)
|
||
BRA @okexit
|
||
|
||
;________________________________________________________________________________________
|
||
; Demand sleep (Finder - Battery DA) case. User warned of different conditions and given the choice
|
||
; to sleep or not.
|
||
;________________________________________________________________________________________
|
||
|
||
@dmndcase CMP.B #SleepDemand,D0 ; Demand case
|
||
BNE.S @nowcase
|
||
|
||
BTST #noATChg,ChooserBits ; If no magic chooser bit then branch
|
||
BNE.S @dmndcase1
|
||
|
||
; Magic chooser bit is set so give the user the big bad warning.
|
||
|
||
BSR.W HarshWarn ; Warn user of impending doom
|
||
BNE @done ; No sleep if user is scared off
|
||
|
||
MOVE.B #ClearedChsr,WakeWarn(A2) ; Set flag for wake up warning (magic bit cleared)
|
||
BSET #noATChg,ChooserBits ; Clear magic chooser bit
|
||
BRA @okexit
|
||
|
||
; Only MPP is open so give the user the wimpy warning.
|
||
|
||
@dmndcase1 BTST #XPPLoadedBit,PortBUse ; Test for XPP in use
|
||
BNZ.S @dmndcase2 ; Branch if so
|
||
|
||
BSR.W WimpyWarn ; Warn user of possible problems
|
||
BNE.S @done ; Branch if chickened out
|
||
|
||
MOVE.B #ClosedMPP,WakeWarn(A2) ; Set flag for wake up warning (MPP closed)
|
||
BRA.S @okexit ; We're cool
|
||
|
||
; XPP is open and a server may be mounted. If no server then give the wimpy warning, else
|
||
; give a stronger one.
|
||
|
||
@dmndcase2 BSR XPPCheck ; Try to close XPP
|
||
BNE.S @dmndcase3 ; Branch if not able
|
||
|
||
BSR.W WimpyWarn ; Warn user of possible problems
|
||
BNE.S @done ; Branch if chickened out
|
||
|
||
MOVE.B #ClosedXPP,WakeWarn(A2) ; Set flag for wake up warning (XPP closed)
|
||
BRA.S @okexit ; We're cool
|
||
|
||
; Server is mounted so give the strong warning.
|
||
|
||
@dmndcase3 BSR.W StrongWarn ; Be firm but gentle
|
||
BNE.S @done ; Talked him out of it
|
||
|
||
MOVE.B #ClosedSvr,WakeWarn(A2) ; Set flag for wake up warning (server lost)
|
||
BRA.S @okexit ; It was rough but we're fine
|
||
|
||
;________________________________________________________________________________________
|
||
; Now sleep (Low power) case. Close any and all but select the right wake up warning.
|
||
;________________________________________________________________________________________
|
||
|
||
@nowcase MOVE.B #ClearedChsr,WakeWarn(A2) ; Set flag for wake up warning (magic bit cleared)
|
||
BSET #noATChg,ChooserBits ; Clear magic chooser bit
|
||
BEQ.S @nowcase4 ; Branch if bit was active
|
||
|
||
MOVE.B #ClosedMPP,WakeWarn(A2) ; Set flag for wake up warning (MPP closed)
|
||
BTST #XPPLoadedBit,PortBUse ; Test for XPP in use
|
||
BNZ.S @nowcase4 ; Branch if so
|
||
|
||
MOVE.B #ClosedXPP,WakeWarn(A2) ; Set flag for wake up warning (XPP closed)
|
||
BSR XPPCheck ; Try to close XPP
|
||
BEQ.S @nowcase4 ; Branch if did
|
||
|
||
MOVE.B #ClosedSvr,WakeWarn(A2) ; Set flag for wake up warning (server lost)
|
||
|
||
@nowcase4
|
||
@okexit MOVEQ #0,D0
|
||
|
||
@done ADD.W #ioQElSize,SP ; Release stack frame
|
||
MOVEM.L (SP)+,A0-A3/D1-D2
|
||
TST.W D0
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; 91/02/13 - AG
|
||
;
|
||
; Close appletalk drivers if necessary
|
||
;
|
||
;________________________________________________________________________________________
|
||
CloseAppleTalk
|
||
MOVEM.L A0-A3/D1-D2,-(SP) ; Try to close AppleTalk and warn user of this <v1.4>
|
||
SUB.W #ioQElSize,SP ; Allocate IO stack frame
|
||
MOVE.L SP,A3 ; Save this place
|
||
|
||
MOVE.L PmgrBase,A2 ;
|
||
MOVEQ #$0F,D1 ; Lower nibble indicates ATalk in use
|
||
AND.B PortBUse,D1
|
||
CMP.B #1,D1
|
||
BNE @Closedone ; Do exit if no Atalk
|
||
BSR.W AllClose ; Shutdown everything
|
||
|
||
@Closedone ADD.W #ioQElSize,SP ; Release stack frame
|
||
MOVEM.L (SP)+,A0-A3/D1-D2
|
||
TST.W D0
|
||
RTS
|
||
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
; CloseATalk support routines.
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
|
||
StrongWarn MOVE.W #-16386,D0
|
||
BRA.S Warn
|
||
|
||
WimpyWarn MOVE.W #-16387,D0
|
||
BRA.S Warn
|
||
|
||
HarshWarn MOVE.W #-16388,D0
|
||
|
||
Warn CLR.W -(SP) ; Send the warning
|
||
MOVE.W D0,-(SP)
|
||
CLR.L -(SP)
|
||
_Alert
|
||
MOVE.W (SP)+,D0 ; D0 non-zero if canceled
|
||
SUBQ.W #1,D0 ; <t31> 1 is sleep button
|
||
RTS
|
||
|
||
MPPClose MOVE.L A3,A0 ; Get stack frame pointer
|
||
MOVE #~MPPUnitNum,ioRefNum(A0) ; Close MPP
|
||
_Close
|
||
TST.W D0
|
||
RTS ; Sucess returned in status
|
||
|
||
XPPClose MOVE.L A3,A0 ; Get stack frame pointer
|
||
LEA #'.XPP',A1 ; Get XPP refnum
|
||
MOVE.L A1,ioVNPtr(A0)
|
||
MOVE.B #fsCurPerm,ioPermssn(A0)
|
||
_Open
|
||
_Close ; Close XPP
|
||
TST.W D0
|
||
RTS ; Sucess returned in status
|
||
|
||
AllClose MOVE.L A3,A0 ; Get stack frame pointer
|
||
LEA #'.XPP',A1 ; Get XPP refnum
|
||
MOVE.L A1,ioVNPtr(A0)
|
||
MOVE.B #fsCurPerm,ioPermssn(A0)
|
||
_Open
|
||
MOVE #CloseAll,csCode(A0) ; Close everything
|
||
_Control
|
||
_Close
|
||
MOVE #~MPPUnitNum,ioRefNum(A0); Close MPP
|
||
_Close
|
||
TST.W D0
|
||
RTS ; Sucess returned in status
|
||
|
||
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
;
|
||
; MPPOpen - routine to open the MPP driver. If the driver is not necessary, the open
|
||
; will fail, so just try to open the driver blindly
|
||
;
|
||
; input
|
||
; none
|
||
;
|
||
; output
|
||
; none
|
||
;
|
||
; usage
|
||
; a0 - pointer to iopb
|
||
; a1 - pointer to driver name
|
||
;
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
|
||
MPPOpen MOVEM.L A0-A3/D1-D2,-(SP)
|
||
;¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥ <K14>
|
||
; temporarily don't even call this!
|
||
; so we stop switching from ethertalk to localtalk across sleep
|
||
IF BlackBirdDebug THEN
|
||
TestFor PrattExists
|
||
bne.s @skipit
|
||
BSR SelectAtlkPort ; make sure AppleTalk knows which port to use <H67>
|
||
@skipit
|
||
ENDIF
|
||
;¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥ <K14>
|
||
LEA -ioQElSize(SP),SP ; Allocate IO stack frame
|
||
MOVEA.L SP,A0 ; Save this place
|
||
|
||
LEA #'.MPP',A1 ; Get MPP refnum
|
||
MOVE.L A1,ioVNPtr(A0)
|
||
MOVE.B #fsCurPerm,ioPermssn(A0)
|
||
_Open
|
||
|
||
LEA ioQElSize(SP),SP ; Release stack frame
|
||
MOVEM.L (SP)+,A0-A3/D1-D2
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: SelectAtlkPort
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0-D1/A0-A1
|
||
;
|
||
; Function: Calls the lmgr to see if the AppleTalk connection in use
|
||
; before going to sleep is still available. If it isn't, it
|
||
; switches to the preferred connection (usually SCC port B).
|
||
;________________________________________________________________________________________
|
||
|
||
SelectAtlkPort ; <H67>
|
||
MOVE.W #mapTrue,RomMapInsert ; map the ROM into the resource chain
|
||
SUBQ.W #4,SP
|
||
PEA 'lmgr' ; theType
|
||
CLR.W -(SP) ; theID
|
||
_GetResource ; try to load the ÔlmgrÕ
|
||
MOVE.L (SP)+,D0 ; did we get it
|
||
BEQ.S @NoLmgr ; -> no, just exit
|
||
MOVEA.L D0,A0 ; get the handle to the ÔlmgrÕ
|
||
MOVE.L A0,-(SP) ; and push a copy for ReleaseResource
|
||
|
||
CLR.L -(SP) ; param1 (none)
|
||
CLR.L -(SP) ; param2 (none)
|
||
PEA 6 ; selector
|
||
MOVEA.L (A0),A0
|
||
JSR 2(A0) ; call the ÔlmgrÕ to switch the ÔatlkÕ if necessary
|
||
LEA 12(SP),SP ; (toss parameters, C style)
|
||
|
||
_ReleaseResource ; all done, so unload the resource
|
||
@NoLmgr RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; 91/02/13 - AG
|
||
;
|
||
; DoQueueStack - this routine is called to traverse the sleep queue. if
|
||
; the sleep type is "now", "demand", or "WakeUp", the queue will only
|
||
; be run once. otherwise, the queue will be run twice. once to check if
|
||
; its ok to sleep, if ok, the sleep type is changed to "demand" and the
|
||
; queue is rerun. if not ok, then the sleep type is change to "Unlock"
|
||
; and the queue is rerun, Each proc is passed its queue entry in A0.
|
||
;
|
||
; input
|
||
; d0 sleep type
|
||
; a0 ptr to pmgrglobals
|
||
;
|
||
; output
|
||
; d0
|
||
; == 0 ok to sleep
|
||
; != 0 queue rejected auto sleep
|
||
;
|
||
; usage
|
||
; d d0 sleep type/result
|
||
; a0 pointer to first element/ ptr to pmgrglobals
|
||
;
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
|
||
DoQueueStack
|
||
MOVEM.L A0/D1,-(SP) ; save pmgrglobals ptr
|
||
MOVE.L SlpQHead(A0),A0 ; Get ptr to first element
|
||
|
||
CMP.W #SleepRequest,D0 ; is it auto sleep ?
|
||
BNE.S @runTheQueue ; if no, just run the queue
|
||
|
||
@testTheQueue
|
||
BSR.s Handle_Element ; ask queue about auto sleep
|
||
BNE.s @undosleepreq ; if error returned, undo sleep
|
||
MOVEQ #SleepDemand,D0 ; ... else set to sleep demand
|
||
|
||
@runTheQueue
|
||
BSR.S Handle_Element ; handle element
|
||
CLR.L D0 ; return no error
|
||
|
||
@exit MOVEM.L (SP)+,A0/D1 ; restore pmgrglobals ptr
|
||
RTS
|
||
|
||
@undosleepreq
|
||
MOVEQ #SleepUnlock,D0 ; Since sleep denied, set to unsleep
|
||
BSR.S Handle_Element ; handle element
|
||
MOVEQ #SleepUnlock,D0 ; return non zero result
|
||
BRA.S @exit
|
||
|
||
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
;
|
||
; Handle Element - this is a routine which is used to execute a queue element. if the
|
||
; element pointer is null, the routine exits and returns 0 in d0. if the element
|
||
; pointer is not null, then the routine will do two thing:
|
||
; 1) handle the next element recursively
|
||
; 2) execute the current element's sleep proc
|
||
; the queue will essentially be traversed in post fixed order
|
||
;
|
||
; input
|
||
; a0 pointer to queue element
|
||
; d0 sleep type
|
||
;
|
||
; output
|
||
; d0 result
|
||
; == 0 ok to sleep
|
||
; != 0 sleep rejected
|
||
;
|
||
; Usage
|
||
; a0 pointer to element
|
||
; d a1 pointer to sleep proc
|
||
; d d0 sleep type/result
|
||
; d d1 saved sleep type/ condition code check
|
||
;
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
ProcRegs REG a0-a6/d1-d7
|
||
|
||
Handle_Element
|
||
MOVE.L a0,d1 ; test element pointer
|
||
BEQ.S @noelement ; if invalid element ptr, exit with d0 clear
|
||
MOVE.L d0,d1 ; save a copy of type in d1
|
||
|
||
@validelement
|
||
MOVEM.L a0/d1,-(sp) ; save element pointer and type
|
||
MOVE.L SleepqLink(a0),a0 ; pass in pointer to next element
|
||
BSR.S Handle_Element ; handle the next element in queue
|
||
MOVEM.L (sp)+,a0/d1 ; restore pointer and type
|
||
BNE.S @exit ; if result != zero, exit
|
||
|
||
@callproc
|
||
MOVE.L SleepqProc(a0),D0 ; get a pointer to the proc <H33>
|
||
BEQ.S @noelement ; if no pointer, exit; flags set by move <H33>
|
||
MOVEA.L d0,a1 ; load pointer in address register for execution <H33>
|
||
|
||
MOVE.L d1,d0 ; restore type to d0
|
||
MOVEM.L ProcRegs,-(sp) ; save the world before calling proc <15> ag
|
||
JSR (a1) ; call sleep proc
|
||
MOVEM.L (sp)+,ProcRegs ; restore the world
|
||
|
||
CMP.W #SleepRequest,D1 ; is this request or demand? <H13>
|
||
BNE.S @noelement ; IF NOT Request THEN clear result & exit <H13>
|
||
TST.L d0 ; ELSE set condition codes on result <H13>
|
||
RTS ; <H13>
|
||
|
||
@noelement moveq #0,d0 ; clear result
|
||
@exit RTS ; exit
|
||
|
||
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
;
|
||
; XPPCheck - this is a routine checks to see if any servers are mounted.
|
||
; D0 will return the error from the close. if no error, no servers!
|
||
; to restore the world, reopen the driver after.
|
||
;
|
||
; input
|
||
; a3 pointer to pb
|
||
;
|
||
; output
|
||
; d0 result
|
||
; == 0 no servers mounted
|
||
; != 0 servers mounted
|
||
;
|
||
; Usage
|
||
; a0 pointer to pb
|
||
; a1 pointer to driver name
|
||
; a3 pointer to pb
|
||
;
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
XPPCheck MOVE.L a3,a0 ; Get pb pointer
|
||
|
||
MOVE.W #~xppUnitNum,ioRefNum(A0) ;
|
||
_Close ; Close XPP
|
||
|
||
MOVE.L d0,-(sp) ; save result
|
||
LEA #'.XPP',a1 ; Get XPP refnum
|
||
MOVE.L a1,ioVNPtr(a0) ; load pointer to driver
|
||
MOVE.B #fsCurPerm,ioPermssn(a0) ; set permission
|
||
_Open ; get refnum
|
||
MOVE.L (sp)+,d0 ; restore result
|
||
|
||
TST.W d0 ; test close result
|
||
RTS ; Sucess returned in status
|
||
|
||
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
;
|
||
; DoQueue - Call each procedure in the sleep/wake queue with the parameter passed
|
||
; in D0. Each proc is passed its queue entry in A0.
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
|
||
DoQueue CMP.W #SleepNow,D0 ; Sleep now
|
||
BEQ.S @mustsleep
|
||
CMP.W #SleepDemand,D0 ; Sleep demand
|
||
BEQ.S @mustsleep
|
||
CMP.W #SleepWakeUp,D0 ; or wake calls are not denied
|
||
BEQ.S @mustsleep
|
||
|
||
@startreq MOVE.L D0,D7 ; Save call type
|
||
MOVE.L PmgrBase,A1
|
||
|
||
MOVE.L SlpQHead(A1),A0 ; Get head pointer to sleep queue entries
|
||
MOVE.L A0,D2
|
||
BEQ @noentries ; Skip rest if no entries
|
||
|
||
@getreq MOVE.L SleepqProc(A0),A2 ; Get sleep proc
|
||
MOVE.L A2,D2
|
||
BEQ.S @nextreq ; Go to next if no proc
|
||
MOVE.W D7,D0
|
||
MOVEM.L A0-A1,-(SP)
|
||
JSR (A2) ; Execute proc
|
||
MOVEM.L (SP)+,A0-A1
|
||
TST.L D0
|
||
BEQ.S @nextreq ; Request ok
|
||
|
||
CMP.W #SleepUnlock,D7 ; If unlocking then continue
|
||
BEQ.S @nextreq
|
||
|
||
MOVEQ #SleepUnlock,D0 ; Since sleep denied
|
||
MOVE.L D0,D7
|
||
BRA.S @startreq ; unlock everything
|
||
|
||
@nextreq CMP.L SlpQTail(A1),A0 ; Check for more entries
|
||
BEQ.S @checkreq ; Branch if no more
|
||
|
||
MOVE.L SleepqLink(A0),A0 ; Get next queue entry
|
||
BRA.S @getreq
|
||
|
||
@checkreq MOVEQ #SleepDemand,D0 ; Queue says sleep is ok
|
||
CMP.W #SleepUnlock,D7 ; If we were unlocking then we are done now
|
||
BNE.S @mustsleep
|
||
|
||
MOVEQ #SleepDeny,D0 ; Sleep request failed
|
||
RTS
|
||
|
||
; Sleep demand case
|
||
|
||
@mustsleep MOVE.W D0,D7 ; Save command
|
||
MOVE.L PmgrBase,A1
|
||
|
||
MOVE.L SlpQHead(A1),A0 ; Get head pointer to sleep queue entries
|
||
MOVE.L A0,D2
|
||
BEQ.S @noentries ; Skip rest if no entries
|
||
|
||
@getdemand MOVE.L SleepqProc(A0),A2 ; Get sleep proc
|
||
MOVE.L A2,D2
|
||
BEQ.S @nextdemand ; Go to next if no proc
|
||
MOVE.W D7,D0
|
||
MOVEM.L A0-A1,-(SP)
|
||
JSR (A2) ; Execute proc
|
||
MOVEM.L (SP)+,A0-A1
|
||
|
||
@nextdemand CMP.L SlpQTail(A1),A0 ; Check for more entries
|
||
BEQ.S @noentries ; Branch if no more
|
||
|
||
MOVE.L SleepqLink(A0),A0 ; Get next queue entry
|
||
BRA.S @getdemand
|
||
|
||
@noentries CLR.L D0
|
||
RTS
|
||
|
||
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
; KbdReset - Clears all keymaps
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
|
||
KbdReset BigJSR RSetKMap,A1 ; Reset global keymap <v2.9>
|
||
|
||
MOVEQ #numFDBAdr, D1 ; Number of table entries
|
||
MOVE.L ADBBase, A1 ; Put Base in A1
|
||
BRA.S @10 ; Skip past record increment
|
||
|
||
@loop ADD #FRecSize, A1 ; Get to next record
|
||
|
||
@10 MOVEQ #2, D0 ; We're looking for keyboards
|
||
CMP.B FDBOAddr(A1), D0 ; Is this one?
|
||
BNE.S @notkbd ; Nope, skip around
|
||
|
||
MOVE.L FDBOpData(A1),A0 ; Retrieve pointer to kbd data
|
||
LEA 4(A0),A0 ; Get address of keybits
|
||
|
||
MOVEQ #0,D0
|
||
MOVE.L D0,(A0)+ ; Clear the key bits
|
||
MOVE.L D0,(A0)+
|
||
MOVE.L D0,(A0)+
|
||
MOVE.L D0,(A0)+
|
||
|
||
@notkbd DBRA D1, @loop ; Loop until no more
|
||
RTS
|
||
|
||
|
||
STRING ASIS
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
;
|
||
; SlpQInstall/SlpQRemove - Installs/Removes entries in the sleep queue.
|
||
;
|
||
; Enrty: A0 = SlpQRec (pointer)
|
||
;
|
||
; Exit: D0 = Result code (word)
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
|
||
SlpQInstall
|
||
CMP.W #slpQType,SleepqType(A0)
|
||
BNE.S SlpQErr
|
||
|
||
MOVE.L PmgrBase,A1
|
||
LEA SleepQHdr(A1),A1
|
||
_Enqueue
|
||
RTS
|
||
|
||
SlpQErr MOVEQ #SlpTypeErr,D0
|
||
RTS
|
||
|
||
SlpQRemove CMP.W #slpQType,SleepqType(A0)
|
||
BNE.S SlpQErr
|
||
|
||
MOVE.L PmgrBase,A1
|
||
LEA SleepQHdr(A1),A1
|
||
_Dequeue
|
||
RTS
|
||
;¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥ End of Traps ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
|
||
|
||
;¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥ Misc ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
|
||
;
|
||
; Contains:
|
||
;
|
||
; ResetPMGRInts
|
||
; SaveSetCrsr
|
||
; RestoreScreen
|
||
; SetSupervisorMode
|
||
; PMGRsend/recv
|
||
; SetPwrLvlTask
|
||
; DoSpinDown
|
||
; DoHDSpinUP
|
||
; PowerDownAll
|
||
; PortableCheck
|
||
;
|
||
;________________________________________________________________________________________
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: ResetPMGRInts
|
||
;
|
||
; Inputs: A1 - VIA1 base address
|
||
;
|
||
; Outputs: A1 - VIA1 base address
|
||
;
|
||
; Trashes: D0, D1, A0
|
||
;
|
||
; Function: clears any pending PMGR interupts and disables modem interrupts
|
||
;________________________________________________________________________________________
|
||
ResetPMGRInts ; clear any pending PMGR interrupts
|
||
MOVE.L VIA,A1 ; get VIA base address
|
||
MOVE.B #(1<<ifIRQ)+(1<<ifCB1),\
|
||
vIFR(A1) ; clear PMGR interrupts in the VIA
|
||
; read any pending PMGR interrupt data from PG&E so we don't hang in InitADB...
|
||
|
||
LEA -12(SP),SP ; allocate a buffer for interrupt data <H8>
|
||
MOVE.L SP,A0 ; and point to it <H8>
|
||
ADDQ.L #2,A0 ; (why do we have to do this?) <H8>
|
||
MOVEQ #ReadINT,D0 ; PMGR command = get interrupt data <H8>
|
||
BSR PMGRrecv ; go get the interrupt data (we'll just toss it) <H8>
|
||
|
||
; disable all modem interrupt sources so we won't get spurious level 3 interrupts from PG&E...
|
||
|
||
CLR.B (A0) ; data to send = disable all modem interrupt sources <H57>
|
||
MOVEQ #1,D1 ; 1 bytes to send <H57>
|
||
MOVEQ #SetModemInts,D0 ; command = set modem interrupt sources <H57>
|
||
BSR PMGRsend ; tell PG&E to turn them all off <H57>
|
||
LEA 12(SP),SP ; toss the buffer <H8>
|
||
|
||
MOVE.B #(1<<ifIRQ)+(1<<ifCB1),\
|
||
vIER(A1) ; enable PMGR interrupts in the VIA
|
||
RTS ; <H57>
|
||
|
||
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
; Routine: SaveSetCrsr
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager variables
|
||
; A5 - Quickdraw globals
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: A0 - A1
|
||
;
|
||
; Function: Save current state of cursor and set cursor to a watch cursor.
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
SaveSetCrsr
|
||
MOVE.L (A5),A0 ; point to QuickDraw globals
|
||
LEA Arrow(A0),A0 ; Get pointer to current cursor
|
||
MOVE.L A0,SleepSaveCrsr(A2) ; save the address of cursor in our little storage
|
||
SUBA.L #4,SP ; Get some stack space <34> HJR
|
||
MOVE.W #watchCursor,-(SP) ; Get the watch cursor
|
||
_GetCursor
|
||
MOVE.L (SP)+,A0 ; Get handle to cursor
|
||
MOVE.L (A0),A0 ; Dereference once
|
||
MOVE.L A0,-(SP) ; push parameter on stack
|
||
_SetCursor
|
||
_HideCursor ; <H56>
|
||
RTS
|
||
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
; Routine: RestoreScreen
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager variables
|
||
; A5 - Quickdraw globals
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: Restores the cursor to its previous state and updates the screen (but not
|
||
; in that order :-)
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
RestoreScreen
|
||
JsrRoutine ScreenRedrawPtr,A2,A0 ; (Calls RedrawScrn from the Primitives.)
|
||
MOVE.L SleepSaveCrsr(A2),-(SP) ; Get ptr to saved crsr
|
||
_SetCursor ; Set the cursor
|
||
_ShowCursor ; Show it to the world
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
; SetSupervisorMode
|
||
;
|
||
; Input: None
|
||
;
|
||
; Destroys: D0/A1
|
||
;
|
||
; Called by: BSR from DreamAway & Wakeup.
|
||
;
|
||
; Function: When VM is running we must switch to supervisor mode so
|
||
; that we may run necessary priviledged instructions. Yes
|
||
; we are the operatorating system and that is acceptable!!!
|
||
;________________________________________________________________________________________
|
||
SetSupervisorMode
|
||
MOVE.L (SP)+,A1 ; Save a copy of return address since we might switch stacks
|
||
MOVEQ #8,D0 ; Set selector to Set Supervisor Mode for VM
|
||
_DebugUtil ;
|
||
CMPI.W #paramErr,D0 ; IF VM is on THEN D0 = Status Register
|
||
BNE.S @Cont ; ELSE
|
||
MOVE.W SR,D0 ; Save the current Status Register
|
||
@Cont ANDI.W #$EFFF,SR ; Make sure that we are in the interrupt stack
|
||
JMP (A1) ; Get out of here
|
||
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
; Routine: PMGRsend/recv
|
||
;
|
||
; Inputs: A0 - data buffer
|
||
; D0 - command
|
||
; D1 - length
|
||
;
|
||
; Outputs: A0 - data buffer
|
||
; D0 - result code
|
||
;
|
||
; Trashes: A0 - A1
|
||
;
|
||
; Function: Handy PmgrOp calling routines.
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
PMGRrecv MOVEQ #0,D1 ; Get data from pmgr <v2.4>
|
||
|
||
PMGRsend MOVE.L A0,-(SP) ; pmRBuffer
|
||
MOVE.L A0,-(SP) ; pmSBuffer
|
||
MOVE.W D1,-(SP) ; pmLength
|
||
MOVE.W D0,-(SP) ; pmCommand
|
||
MOVE.L SP,A0
|
||
_PmgrOp
|
||
MOVE.W pmLength(sp),d1 ; return count <gmr>
|
||
LEA pmRBuffer(SP),SP ; Release stack frame
|
||
MOVE.L (SP)+,A0 ; pmRBuffer
|
||
RTS
|
||
|
||
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
; Routine: SetPwrLvlTask
|
||
;
|
||
; Inputs: A2 - PMgrBase
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: set the power manager micro levels to match those set in the 680x0 pmgr globals
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
SetPwrLvlTask
|
||
@SetPwrLvlRegs REG A0-A1/D0-D1
|
||
|
||
MOVEM.L @SetPwrLvlRegs,-(SP) ; working registers
|
||
MOVE.W #$4201,-(SP) ; pushpram byte 0x42 + one byte of data
|
||
MOVE.W LowWarn(A2),-(SP) ; move the current 68K pmgr setting into buffer for set
|
||
MOVEA.L SP,A0 ; set up data buffer
|
||
MOVEQ #xPramWrite,D0 ; command to send
|
||
MOVEQ #3,D1 ; number of data bytes
|
||
BSR.S PMGRsend ; send command
|
||
CLR.L (SP)+ ; clean up buffer
|
||
MOVEM.L (SP)+,@SetPwrLvlRegs ; Restore working registers
|
||
RTS
|
||
|
||
;________________________________________________________________________________________ <H82>
|
||
;
|
||
; Routine: DoSpinDown
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0, A0
|
||
;
|
||
; Function: kills power to the internal hard disk, unless spindown is disabled
|
||
;________________________________________________________________________________________
|
||
|
||
DoSpinDown
|
||
MOVEM.L A0-A1,-(SP) ; save some registers
|
||
MOVEA.L PMgrBase,A1 ; point to the Power Manager's globals <H83>
|
||
BTST.B #QuickHDSpinDwn,PmgrFlags2(A1) ; quick spin down enabled? <H83>
|
||
BNE.S @MustSpindown ; -> yes, have to spin down even if disabled<H83>
|
||
IF HDSpinDownDisable=7 THEN
|
||
TST.B PmgrFlags2(A1) ; is spindown allowed? <H83>
|
||
BMI.S @Done ; -> no, ignore it <H83>
|
||
ELSE
|
||
BTST #HDSpinDownDisable,PmgrFlags2(A1) ; is spindown allowed? <H83>
|
||
BNE.S @Done ; -> no, ignore it <H83>
|
||
ENDIF
|
||
@MustSpindown ; <H83>
|
||
BCLR #HDPowerOn,PMgrFlags(A1); clear the flag, indicating that the drive is now spun down <K36>
|
||
|
||
; call each of the routines in the hard disk queue to notify anyone who cares
|
||
; that the hard disk is about to be spun down
|
||
|
||
MOVEM.L D1-D2/A1-A2,-(SP)
|
||
LEA hdQHead(A1),A2 ; point to the start of the hard disk queue
|
||
BRA.S @NoProc
|
||
@NextElement
|
||
MOVEA.L D0,A2 ; point to the next queue element
|
||
MOVE.L hdProc(A2),D0 ; get the pointer to the routine
|
||
BEQ.S @NoProc ; -> there isn't one
|
||
MOVE.L A2,-(SP) ; push a pointer to the queue element <H81>
|
||
MOVEA.L D0,A0 ; point to the routine
|
||
JSR (A0) ; and call it
|
||
@NoProc MOVE.L hdQLink(A2),D0 ; end of the queue?
|
||
BNE.S @NextElement ; -> no, keep running (huff! puff!)
|
||
MOVEM.L (SP)+,D1-D2/A1-A2
|
||
|
||
; finally, spin down the internal hard disk
|
||
|
||
MOVE.B #hdOff,-(SP) ; data to send = turn off hard disk power plane
|
||
MOVE.L SP,-(SP) ; pmRBuffer (not used)
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
MOVE.W #1,-(SP) ; pmLength
|
||
MOVE.W #powerCntl,-(SP) ; pmCommand
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; turn off the hard disk
|
||
LEA pmRBuffer+4+2(SP),SP ; clean up the stack
|
||
BNE.S @Done ; -> an error occurred
|
||
|
||
CLR.L LastHD(A1) ; stop calling - disk is spun down
|
||
BCLR #HDPowerOn,PMgrFlags(A1); clear the flag, indicating that the drive is now spun down
|
||
MOVEM.L (SP)+,A0-A1 ; restore some registers
|
||
@Done RTS
|
||
|
||
;________________________________________________________________________________________ <H82>
|
||
;
|
||
; Routine: DoHDSpinUp
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0, A0
|
||
;
|
||
; Function: restores power to the internal hard disk
|
||
;________________________________________________________________________________________
|
||
|
||
DoHDSpinUp
|
||
|
||
; This portion of code freezes the "Spin Down" timer for the hard disk, preventing
|
||
; the Power Mgr from cutting hard disk power during ANY SCSI transaction.
|
||
|
||
MOVEM.L A0-A1/D0,-(SP) ; save them regs
|
||
|
||
MOVEA.L PmgrBase,A1 ; point to Pmgr locals
|
||
MOVE.L #0,LastHd(A1) ; always freeze the spin down timer
|
||
BTST.B #HDPowerOn,PmgrFlags(A1) ; set flag indicating drive is now spun up <t11> djw
|
||
BNE.S @Done ; drive already spun up - skip PmgrOp call <t11> djw
|
||
|
||
MOVE.B #hdOn,-(SP) ; data to send = turn off hard disk power plane
|
||
MOVE.L SP,-(SP) ; pmRBuffer (not used)
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
MOVE.W #1,-(SP) ; pmLength
|
||
MOVE.W #powerCntl,-(SP) ; pmCommand
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; turn off the hard disk
|
||
LEA pmRBuffer+4+2(SP),SP ; clean up the stack
|
||
BNE.S @Done ; -> an error occurred
|
||
|
||
MOVE.L #250,D0 ; wait 250 Miliseconds
|
||
BigJsr DelayNMsec,A0 ; É Spin are wheels
|
||
|
||
BSET.B #HDPowerOn,PmgrFlags(A1) ; set flag indicating drive is now spun up <t11> djw
|
||
|
||
@Done MOVEM.L (SP)+,A0-A1/D0 ; restore them registers
|
||
RTS ; return to SCSIGet
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: PowerDownAll
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0, A0
|
||
;
|
||
; Function: called by StartInit to power down all peripheral subsystems
|
||
;________________________________________________________________________________________
|
||
|
||
PowerDownAll
|
||
TestFor hwCbPwrMgr ; is there Power Mgr in this Mac ?
|
||
BEQ.S @NoPMGR ; -> no, skip
|
||
MOVE.B #allOff,-(SP) ; buffer contains "turn off unused devices"
|
||
IF forRomulator THEN
|
||
ANDI.B #~((1<<pSCC)|(1<<pSerDrvr)|(1<<pMinus5V)),(SP) ; don't kill the nub! <SM69>
|
||
ENDIF
|
||
MOVE.L SP,-(SP) ; point to receive buffer
|
||
MOVE.L (SP),-(SP) ; point to transmit buffer
|
||
MOVE.W #1,-(SP) ; one byte of transmit data
|
||
MOVE.W #PowerCntl,-(SP) ; PMGR command: power control
|
||
MOVE.L SP,A0 ; A0 gets pointer to parameter block
|
||
_PmgrOp
|
||
LEA pmRBuffer+4+2(SP),SP ; Remove stack frame
|
||
MOVEA.L PmgrBase,A0 ; get addr of globals <t25>
|
||
BCLR.B #HDPowerOn,PmgrFlags(A0) ; clear HD powered on flag <t25>
|
||
@NoPMGR RTS
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: PortableCheck
|
||
;
|
||
; Inputs: D2 - Bits 31..16, hwCfgFlags info (possibly unknown)
|
||
; D2 - Bits 7..0, Address Decoder Kind (zero if unknown)
|
||
; A1 - Productinfo
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0-D1, A0-A6
|
||
;
|
||
; Function: Called by a BSR6 from StartInit to check if we're booting
|
||
; or waking up. Since we've just called JumpIntoROM, D2
|
||
; has the decoder kind.
|
||
;________________________________________________________________________________________
|
||
|
||
|
||
beok EQU 27 ;a BusError is expected and is OK (copied from STEqu.a to avoid duplicate label if included)
|
||
|
||
PortableCheck
|
||
IF isUniversal THEN
|
||
BTST.L #(hwCbPwrMgr+16),D2 ; Are we running on Pmgr System
|
||
BEQ.W NonPwrMgr ; NOPE. Branch...
|
||
ENDIF
|
||
|
||
MOVEA.L A6,A5 ; save return addr <H34>
|
||
LEA @NoRAM,A6 ; load return addr in case of bus error <H34>
|
||
|
||
MOVE.L PmgrBase,A2 ; get the addr of PMgrVars <H34>
|
||
CMP.L #SleepConst,SleepSaveFlag(A2) ; are we waking from sleep?
|
||
BNE.S @noRAM ; branch if not <H34>
|
||
|
||
CLR.L SleepSaveFlag(A2) ; clear the sleep flag
|
||
MOVE.L WakeVector(A2),A0 ; Go restore ourself
|
||
JMP (A0) ; .
|
||
|
||
NOP ; keep everything aligned <H34>
|
||
|
||
@NoRAM MOVEA.L A5,A6 ; restore return addr <H34>
|
||
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
; Routine: CheckEconoMode
|
||
;
|
||
; Input: D2 - Bits 31..16, hwCfgFlags info (possibly unknown)
|
||
; D2 - Bits 7..0, Address Decoder Kind (zero if unknown)
|
||
;
|
||
; Destroys: A0-A7,D0-D6
|
||
;
|
||
; Called by: BSR6 from StartInit.
|
||
;
|
||
; Function: checks to see if a portable needs to be switched into econo-mode
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
|
||
CheckEconoMode
|
||
; do we have a Pratt?
|
||
btst #(PrattExists//8),(ProductInfo.BasesValid1+3-(PrattExists/8))(a1)
|
||
bne NonPwrMgr ; yes don't do anything
|
||
MOVEA.L A6,A7 ; save the return address <H18>
|
||
|
||
BigBSR6 InitWallyWorld,A1 ; download code into the PMGR, if necessary <H18>
|
||
|
||
MOVEQ #0,D2 ; <H18>
|
||
BigBSR6 GetHardwareInfo,A0 ; figure out what we're running on
|
||
|
||
MOVE.L D2,D4 ; save the decoder type around the PRAM calls <H18>
|
||
MOVEQ #$10,D1 ; read the PRAM validation byte <H18>
|
||
MOVEA.L DecoderInfo.VIA1Addr(A0),A2 ; point to base of VIA1 <H19>
|
||
BigBSR6 RdXByte,A0 ; <H18>
|
||
MOVEQ #$A8-256,D0 ; compare what was read against expected value <H18>
|
||
SUB.B D1,D0 ; <H18>
|
||
MOVEQ #0,D1 ; (assume PRAM's invalid) <H18>
|
||
TST.B D0 ; is PRAM OK? <H18>
|
||
BNE.S @BadPRAM ; -> no, run at full speed for now <H18>
|
||
|
||
MOVEQ #PmgrPramBase+PmgrPramRec.PmgrOtherFlags,D1 ; default to standard PRAM location <H7>
|
||
MOVE.L PowerManagerPtr(A1),D0 ; does this box have a PMgr primitives table? <H36><H37>
|
||
|
||
IF 0 THEN
|
||
BEQ.S @UseDefPRAM ; -> no, use the default location <H36>
|
||
MOVEA.L A1,A2 ; <H36><H37>
|
||
ADDA.L D0,A2 ; point to the primitives table for this box <H36>
|
||
ADDA.L PmgrPrimsRec.PrimInfoPtr(A2),A2 ; and then to the primitives info table <H7>
|
||
MOVE.B PrimInfoTbleRec.PrimPRAMBase(A2),D1 ; get the base Power Manager PRAM byte <H7>
|
||
ADDQ.B #PmgrPramRec.PmgrOtherFlags,D1 ; and adjust for the byte we want <H7>
|
||
ENDIF
|
||
|
||
@UseDefPRAM MOVEA.L A1,A0 ; point back to the DecoderInfo table <H37>
|
||
ADDA.L DecoderInfoPtr(A0),A0 ; <H37>
|
||
MOVEA.L DecoderInfo.VIA1Addr(A0),A2 ; point to the base of VIA1
|
||
BigBSR6 RdXByte,A0 ; read the desired econo-mode setting from PRAM
|
||
ANDI.B #(1<<EconoBit),D1 ; and mask off the econo-mode bit
|
||
@BadPRAM MOVE.L D4,D2 ; restore the decoder type
|
||
|
||
|
||
MOVEA.L A1,A0 ; point back to the DecoderInfo table <H37>
|
||
ADDA.L DecoderInfoPtr(A0),A0 ; one last time <H37>
|
||
|
||
; at this point:
|
||
; A0 - pointer to DecoderInfo table
|
||
; A1 - pointer to ProductInfo table
|
||
; D2 - decoder type
|
||
|
||
|
||
IF hasJAWS | hasNiagra THEN
|
||
;¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥ JAWS ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
|
||
SPIN_WAIT equ $40000 ; delay for power manager to hit reset <H23>
|
||
SPEED25MHZBIT equ 0 ; 1 = running at 25mhz
|
||
|
||
IF isUniversal THEN
|
||
cmp.b #Decoderkinds.NiagraDecoder,D2 ; Do we have a Niagra decoder? <H14>
|
||
beq.s @DoNiagra ; -> yes, go do it.. <H14>
|
||
cmp.b #Decoderkinds.JAWSDecoder,D2 ; Do we have a JAWS decoder ?
|
||
bne.s NotJaws ; -> no, do next one
|
||
ENDIF
|
||
|
||
IF hasJAWS THEN
|
||
@DoJaws MOVEA.L DecoderInfo.JAWSAddr(A0),A1 ; A1 = pointer to the base of the JAWS decoder <H19>
|
||
MOVE.L #JAWSGetCPUClock,D0 ; get the offset to the CPU clock frequency register
|
||
BTST #SPEED25MHZBIT,0(A1,D0.L) ; are we running at 25MHz?
|
||
BEQ.S @JAWSDone ; -> no, done
|
||
ENDIF
|
||
|
||
@DoNiagra MOVEA.L DecoderInfo.JAWSAddr(A0),A1 ; A1 = pointer to the base of the JAWS decoder <H19>
|
||
MOVEQ #(1<<EconoBit),D2 ; mask off the econo bit in the econo-mode register
|
||
AND.B JAWSEconoMode(A1),D2
|
||
CMP.B D1,D2 ; are we currently in the right mode?
|
||
BEQ.S @JAWSDone ; -> yes, done
|
||
MOVE.B D1,JAWSEconoMode(A1) ; stuff the new mode into the econo register
|
||
|
||
MOVE.W #(0<<8)+(resetCPU<<0),D3 ; data length=0, command=reset PMGR
|
||
BigBSR6 USTPMGRSendCommand,A2 ; reset the system
|
||
|
||
MOVE.L #SPIN_WAIT,D3 ; wait awhile for the PMGR to reset the system
|
||
@spin SUBQ.L #1,D3
|
||
BNE.S @spin
|
||
|
||
@JAWSDone ; <H23>
|
||
bra ExitEconoMode ; <H23>
|
||
NotJaws
|
||
ENDIF
|
||
|
||
|
||
IF hasMSC THEN
|
||
;¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥ MSC ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
|
||
IF isUniversal THEN
|
||
CMPI.B #DecoderKinds.MSCDecoder,D2 ; do we have a MSC decoder?
|
||
BNE NotMSC ; -> nope, bail
|
||
ENDIF
|
||
ORI.B #MSCDefConfig,D1 ; this sets 25Mhz mode by default
|
||
|
||
; <H45> D2 now has the value of the Econo Mode bit in PRAM. Yeager needs
|
||
; to make sure that this bit is never set, or it will break!
|
||
|
||
MOVEQ #$1F,D2 ; mask off the CPU ID
|
||
AND.W CPUIDValue(A1),D2 ;
|
||
BEQ.S @MSC33MHz ; is it a new Yeager MBT 040
|
||
CMP.W #16,D2 ; is it a Yeager (040)?
|
||
BEQ.S @MSC33MHz ; -> yes, do setup
|
||
AND.W #7,D2 ; mask off the CPU ID
|
||
CMP.W #5,D2 ; is it a 33MHz system (DB Lite)? <H38>
|
||
BEQ.S @MSC33MHz ; -> yes, do setup <H38>
|
||
CMP.W #2,D2 ; maybe it's a 33MHz Escher? <H38>
|
||
BEQ.S @MSC33MHz ; -> yes, do setup <H38>
|
||
|
||
BTST #EconoBit,D1 ; are we in going to run in econo-mode? <H15>
|
||
BNE.S @NotMSC33MHz ; -> yes, we'll be running at 16MHz regardless <H15>
|
||
|
||
@MSC33MHz BCLR #MSC25MHz,D1 ; setup the state machines to run at 33MHz <H10>
|
||
@NotMSC33MHz
|
||
MOVEA.L DecoderInfo.RBVAddr(A0),A1 ; point to the base of the MSC decoder
|
||
MOVEQ #(%11111000)-256,D2 ; mask off the RAM size information <H15>
|
||
AND.B MSCConfig(A1),D2 ; <H15>
|
||
OR.B D2,D1 ; and add it to the base configuration <H15>
|
||
MOVE.B D1,MSCConfig(A1) ; stuff the configuration into the register <H6>
|
||
|
||
MOVE.L #(0<<16)|(1<<8)|(SetModemInts<<0),D3 ; <H30>
|
||
BigBSR6 USTPmgrSendCommand,A2 ; turn off modem interrupts <H30>
|
||
|
||
;×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× <H31>
|
||
;
|
||
; This is the nasty hack. When a DBLite is docked to a Gemini or DeskBar with an external SCSI
|
||
; hard disk connected and powered up, the SCC gets charged up a little bit and ends up in a weird
|
||
; state, usually generating level 4 interrupts. Normally we initialize the SCC later, but since
|
||
; the Docking Manager isn't initialized soon enough, as soon as interrupts are opened up, we get
|
||
; stuck in the level 4 interrupt handler (which is hopefully set up). This hack will talk to the
|
||
; Gemini/DeskBar hardware directly and reset the external SCC.
|
||
|
||
ROMSigAddr EQU $FEFFFFE4 ; where to find the ROM signature
|
||
ROMSigLo EQU 'Russ' ; and what it is
|
||
ROMSigHi EQU 'SWC!'
|
||
|
||
vscClockPwr EQU $FEE00021 ; VSC power control register
|
||
vscSCCclock EQU 1 ; 1=turn on SCC clock
|
||
vscSCCAddr EQU $FEE08000 ; SCC base address
|
||
NastyHack
|
||
If Not ForRomulator Then
|
||
MOVEA.L SP,A5 ; save the return address
|
||
BSET #beok,D7 ; allow bus errors
|
||
BSR6 @WhackSCC ; go whack the SCC (bad SCC! bad SCC! blah blah)
|
||
BCLR #beok,D7 ; disallow bus errors
|
||
Endif
|
||
BRA.S ExitEconoMode
|
||
|
||
@InitBData DC.B 9,$C0 ; do a hard reset
|
||
DC.B 9,$40 ; reset the channel
|
||
DC.B 4,$4C ; set async mode (magic?)
|
||
DC.B 2,$00 ; zero interrupt vector for dispatcher
|
||
DC.B 3,$C0 ; DCD not an auto-enable
|
||
DC.B 15,$00 ; no interrupts
|
||
DC.B 0,$10 ; reset ext/sts interrupts twice
|
||
DC.B 0,$10
|
||
DC.B 1,$00 ; no interrupts
|
||
|
||
@InitAData DC.B 9,$80 ; reset the channel
|
||
DC.B 4,$4C ; set async mode (magic?)
|
||
DC.B 3,$C0 ; DCD not an auto-enable
|
||
DC.B 15,$00 ; no interrupts
|
||
DC.B 0,$10 ; reset ext/sts interrupts twice
|
||
DC.B 0,$10
|
||
DC.B 1,$00 ; no interrupts
|
||
|
||
@WhackSCC CMPI.L #ROMSigLo,ROMSigAddr ; is the signature in the config ROM?
|
||
BNE.S @NotGemini ; -> no, not the ROM we're looking for
|
||
CMPI.L #ROMSigHi,ROMSigAddr+4 ; ditto with the other part of the signature
|
||
BNE.S @NotGemini ; -> no, not the ROM we're looking for
|
||
|
||
BSET #vscSCCclock,vscClockPwr ; turn on clocks to the SCC
|
||
|
||
LEA vscSCCAddr,A0
|
||
LEA @InitBData,A2 ; point to channel B init data
|
||
MOVEQ #@InitAData-@InitBData,D1
|
||
LEA @ResumeB,A1
|
||
BRA.S @WriteSCC
|
||
@ResumeB ADDQ.W #ACtl,A0 ; point to channel A
|
||
MOVEQ #@WhackSCC-@InitAData,D1
|
||
LEA @ResumeA,A1
|
||
@WriteSCC MOVE.B (A0),D2 ; read to make sure the SCC is sync'ed up
|
||
BRA.S @2 ; delay for timing, too
|
||
@1 MOVE.L (SP),(SP) ; delay long for reset
|
||
MOVE.L (SP),(SP)
|
||
MOVE.B (A2)+,(A0)
|
||
@2 DBRA D1,@1
|
||
JMP (A1)
|
||
|
||
@ResumeA BCLR #vscSCCclock,vscClockPwr ; turn off clocks to the SCC
|
||
@NotGemini RTS6
|
||
|
||
;×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× <H31>
|
||
|
||
NotMSC
|
||
ENDIF
|
||
|
||
ExitEconoMode
|
||
MOVEA.L A7,A6 ; restore the return address <H23>
|
||
|
||
;________________________________________________________________________________________
|
||
; Routine: InitAndBlankScreen |
|
||
; V
|
||
; Input: a6 - return address
|
||
;
|
||
; Destroys: A0-A7,D0-D6
|
||
;
|
||
; Called by: BSR6 from StartInit.
|
||
;
|
||
; Function: initialize and blank the screen to meet timing requirements
|
||
;________________________________________________________________________________________
|
||
|
||
InitAndBlankScreen
|
||
IF hasNiagra | hasMSC THEN
|
||
movea.l a6,a7 ; save original return address
|
||
MOVEQ #0,D2 ;
|
||
BigBSR6 GetHardwareInfo,A0 ; figure out what we're running on
|
||
cmp.b #Decoderkinds.NiagraDecoder,D2 ; Do we have a Niagra decoder?
|
||
beq.s @BlankNiagra ; -> yes
|
||
cmpi.b #DecoderKinds.MSCDecoder,D2 ; do we have a MSC decoder?
|
||
bne @ExitInitAndBlank ; -> no, continue
|
||
|
||
IF hasMSC THEN ; <H29>
|
||
MOVEA.L DecoderInfo.RBVAddr(A0),A2 ; point to the base of the MSC <H29>
|
||
BSET #MSCLCDReset,MSCClkCntl(A2) ; turn on clocks to the GSC so we can program it<H29>
|
||
BRA.S @TestForGSC ; <H29>
|
||
ENDIF ; <H29>
|
||
|
||
IF hasNiagra THEN
|
||
; send command to power manager to blank the screen and delay before talking to the gsc
|
||
; D3- [data2] [data1] [length] [command]
|
||
; A0- pointer to DecoderInfo
|
||
; A6- return address
|
||
|
||
@BlankNiagra
|
||
MOVE.l #($E0<<0) | \ ; Write Pmgr Ram
|
||
(03<<8) | \ ; count 3, 2 address + 1 data
|
||
(00<<16) | \ ; addrH - $00xxH
|
||
($EA<<24),D3 ; addrL - $xxEA
|
||
BigBSR6 USTPMGRSendCommand,A2 ; reset the system
|
||
|
||
move.b #$0A,D3 ; port 4: d[2] = 0 (blank), d[0] = 1 adb inactive
|
||
BigBSR5 USTPMgrSendByte,A4 ; and send it
|
||
* bra.s @TestForGSC ; <H29>
|
||
ENDIF
|
||
|
||
; test for gsc chip
|
||
@TestForGSC MOVEA.L DecoderInfo.VDACAddr(A0),A0 ; point to base of gsc
|
||
movea.l a7,a5 ; save return address in case of bus error <H26>
|
||
bset.l #beok,d7 ; allow bus errors
|
||
bsr6 @checkforGSC ; check for gsc chip
|
||
bra @ExitInitAndBlank ; if not zero, buserror, no gsc, exit
|
||
; bne @ExitInitAndBlank ; if not zero, buserror, no gsc, exit
|
||
|
||
; initialize GSC early to meet hardware timing spec
|
||
@loadSetup
|
||
moveq.l #7,D0 ; mask off the display ID
|
||
And.b GSCPanelID(A0),D0 ; get the display id
|
||
|
||
MULU #(GSCPanelSkew-GSCPanelSetup+1)+(GSCDiag2-GSCDiag0+1),D0 ;
|
||
LEA @GSCInitTable,A2 ; point to the entry for this display
|
||
ADDA.L D0,A2
|
||
|
||
ADDQ.W #GSCPanelSetup,A0 ; point to the first register to blast <H25>
|
||
MOVE.L (A2)+,(A0)+ ; initialize the main display registers <H25>
|
||
MOVE.L (A2)+,(A0)+ ; <H25>
|
||
LEA GSCDiag0-GSCPanelSkew-1(A0),A0 ; point to the diagnostic registers <H25>
|
||
MOVE.B (A2)+,(A0)+ ; and initialize them too <H25>
|
||
MOVE.W (A2)+,(A0)+ ; <H25>
|
||
bra.s @ExitInitAndBlank ; done
|
||
|
||
@checkforGSC
|
||
move.b GSCPanelID(A0),D0 ; try reading a register
|
||
moveq #0,d0 ; set CC to Equal, buserr will return not Equal <H26>
|
||
rts6
|
||
|
||
|
||
; GSC initialization table. Each entry is based on the LCD panel ID.
|
||
;
|
||
; panel gray poly panel ACD refresh blank panel
|
||
; setup scale adjust adjust clock rate shade skew diag0 diag1 diag2
|
||
@GSCInitTable
|
||
DC.B $10, $00, $64, $00, $80, $02, $00, $A0, $00, $00, $03 ; ID=0 TFT1Bit <H27>
|
||
DC.B $12, $00, $64, $00, $80, $02, $00, $FF, $00, $00, $03 ; ID=1 TFT3Bit <H27>
|
||
DC.B $10, $00, $64, $00, $80, $02, $00, $FF, $00, $00, $03 ; ID=2 TFT4Bit <H27>
|
||
DC.B $10, $00, $64, $00, $80, $02, $00, $A0, $00, $00, $03 ; ID=3 NotAssignedTFT <H27>
|
||
DC.B $10, $00, $64, $00, $80, $05, $00, $A0, $00, $00, $03 ; ID=4 NotAssignedSTN <H27>
|
||
DC.B $10, $00, $64, $00, $80, $05, $00, $A0, $00, $00, $03 ; ID=5 TimSTN <H27>
|
||
DC.B $10, $00, $63, $00, $80, $05, $00, $9C, $00, $00, $03 ; ID=6 DBLiteSTN <H29>
|
||
DC.B $10, $00, $64, $00, $80, $05, $00, $A0, $00, $00, $03 ; ID=7 No Display <H27>
|
||
|
||
|
||
@ExitInitAndBlank
|
||
bclr.l #beok,d7 ; disallow bus errors
|
||
movea.l a7,a6 ; restore original return address
|
||
|
||
ENDIF ; {hasNiagra | hasMSC}
|
||
|
||
;________________________________________________________________________________________
|
||
; Routine: Exit
|
||
;________________________________________________________________________________________ ; V
|
||
NonPwrMgr RTS6 ; return to start init <H23> ; All done
|
||
|
||
|
||
;¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥ End of Misc. ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
|
||
|
||
|
||
;¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥ Public Power Manager ¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥¥
|
||
;
|
||
; Contains:
|
||
;
|
||
;________________________________________________________________________________________
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: PowerMgrDispatch (trap $A09E)
|
||
;
|
||
; Inputs: D0 - selector
|
||
;
|
||
; Outputs: D0 - selector result, or error code if bad selector
|
||
;
|
||
; Trashes: varies by selector
|
||
;
|
||
; Function: This is the Power Manager's public dispatch trap, which provides a variety of
|
||
; miscellaneous functions to the public, hackers, etc.
|
||
;
|
||
; NOTE: The offset-based dispatch table is copied into RAM and converted to
|
||
; absolute addresses by InitPMgrVars.
|
||
;________________________________________________________________________________________
|
||
|
||
PowerMgrDispatch
|
||
MOVEA.L PMgrBase,A2 ; point to the Power Manager's globals
|
||
MOVE.L vPublicDispatch(A2),A1 ; and then to the public dispatch table
|
||
CMP.W -2(A1),D0 ; is the selector in range?
|
||
BHS.S @OutOfRange ; -> no, bail with an error
|
||
MOVEA.L 0(A1,D0.W*4),A1 ; point to the routine <H93>
|
||
JMP (A1) ; and call it
|
||
|
||
@OutOfRange MOVEQ #paramErr,D0 ; abort and return error
|
||
RTS
|
||
|
||
|
||
ALIGN 4
|
||
|
||
DC.W 0 ; flags
|
||
DC.W (PwrMgrDispEnd-PwrMgrDispVects)/4 ; number of table entries
|
||
PwrMgrDispVects
|
||
DC.L PMSelectorCount-PwrMgrDispVects ; [ 0] return the number of selectors supported
|
||
DC.L PMFeatures-PwrMgrDispVects ; [ 1] return bitmap of Power Manager features
|
||
DC.L GetSleepTimeout-PwrMgrDispVects ; [ 2] get the sleep timeout
|
||
DC.L SetSleepTimeout-PwrMgrDispVects ; [ 3] set the sleep timeout
|
||
DC.L GetHardDiskTimeout-PwrMgrDispVects ; [ 4] get the hard disk spindown timeout
|
||
DC.L SetHardDiskTimeout-PwrMgrDispVects ; [ 5] set the hard disk spindown timeout
|
||
DC.L HardDiskPowered-PwrMgrDispVects ; [ 6] returns true if hard disk is powered up
|
||
DC.L SpinDownHardDisk-PwrMgrDispVects ; [ 7] spin down the hard disk
|
||
DC.L IsSpindownDisabled-PwrMgrDispVects ; [ 8] returns whether or not spindown is disabled
|
||
DC.L SetSpindownDisable-PwrMgrDispVects ; [ 9] enables/disables hard disk spindown
|
||
DC.L HardDiskQInstall-PwrMgrDispVects ; [10] add element to HD queue
|
||
DC.L HardDiskQRemove-PwrMgrDispVects ; [11] remove element from HD queue
|
||
DC.L ScaledBattery-PwrMgrDispVects ; [12] return the scaled battery level
|
||
DC.L AutoSleepControl-PwrMgrDispVects ; [13] enables/disables auto sleep
|
||
DC.L GetIntModemInfo-PwrMgrDispVects ; [14] return information about an internal modem
|
||
DC.L SetIntModemState-PwrMgrDispVects ; [15] sets the state of the internal modem
|
||
DC.L MaximumProcessorSpeed-PwrMgrDispVects ; [16] return maximum processor speed
|
||
DC.L CurrentProcessorSpeed-PwrMgrDispVects ; [17] return current processor speed
|
||
DC.L FullProcessorSpeed-PwrMgrDispVects ; [18] returns true if processor running at full speed
|
||
DC.L SetProcessorSpeed-PwrMgrDispVects ; [19] set full/reduced processor speed
|
||
DC.L GetSCSIDiskModeAddress-PwrMgrDispVects ; [20] get SCSI Disk Mode HD address
|
||
DC.L SetSCSIDiskModeAddress-PwrMgrDispVects ; [21] set SCSI Disk Mode HD address
|
||
DC.L GetWakeupTimer-PwrMgrDispVects ; [22] get wakeup time
|
||
DC.L SetWakeupTimer-PwrMgrDispVects ; [23] set wakeup time
|
||
DC.L GetProcessorCycling-PwrMgrDispVects ; [24] get processor cycling state
|
||
DC.L SetProcessorCycling-PwrMgrDispVects ; [25] set processor cycling state
|
||
DC.L BatteryCount-PwrMgrDispVects ; [26] returns number of internal batteries
|
||
DC.L GetBatteryVoltage-PwrMgrDispVects ; [27] return absolute battery voltage
|
||
DC.L GetBatteryTimes-PwrMgrDispVects ; [28] returns information about battery times
|
||
DC.L GetDimTimeout-PwrMgrDispVects ; [29] get the dimming timeout
|
||
DC.L SetDimTimeout-PwrMgrDispVects ; [30] set the dimming timeout
|
||
DC.L DimControl-PwrMgrDispVects ; [31] enables/disables dimming
|
||
DC.L IsDimmingDisabled-PwrMgrDispVects ; [32] returns whether or not dimming is disabled
|
||
DC.L IsAutoSlpDisabled-PwrMgrDispVects ; [33] returns whether or not autosleep is disabled
|
||
PwrMgrDispEnd
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: PMSelectorCount (PowerMgrDispatch selector #0)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - number of selectors
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: returns the number of selectors so users can determine what selectors are
|
||
; supported
|
||
;________________________________________________________________________________________
|
||
|
||
PMSelectorCount
|
||
MOVEQ #0,D0
|
||
MOVE.L vPublicDispatch(A2),A0 ; point to the public dispatch table
|
||
MOVE.W -(A0),D0 ; and get the number of selectors
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: PMFeatures (PowerMgrDispatch selector #1)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - bitmap of supported features
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: returns a bitmap containing bits describing which software/hardware
|
||
; features are supported on this machine
|
||
;________________________________________________________________________________________
|
||
|
||
PMFeatures
|
||
LoadTbl PrimInfoTblPtr,A2,A0 ; get pointer to Info
|
||
MOVE.L PrimPubFeatures(A0),D0 ; get the features bits
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: GetSleepTimeout (PowerMgrDispatch selector #2)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - sleep timeout (number of 15 second intervals)
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: returns the current sleep timeout time
|
||
;________________________________________________________________________________________
|
||
|
||
GetSleepTimeout
|
||
MOVEQ #SlpTimeOut,D0 ; which byte to read
|
||
BRA.S ReadPMgrPRAM ; go read and return the value
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: SetSleepTimeout (PowerMgrDispatch selector #3)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
; D0 - high word: sleep time to set (number of 15 second intervals)
|
||
;
|
||
; Outputs: D0 - result code (always zero)
|
||
;
|
||
; Trashes: D1, A0
|
||
;
|
||
; Function: sets the current sleep timeout
|
||
;________________________________________________________________________________________
|
||
|
||
SetSleepTimeout
|
||
SWAP D0 ; get the new value
|
||
TST.B D0 ; is it zero?
|
||
BNE.S @NotZero ; -> no
|
||
MOVEQ #DfltSlpTime,D0 ; yes, set it to the default
|
||
@NotZero
|
||
MOVE.B D0,SleepTime(A2) ; save it
|
||
MOVE.B D0,D1
|
||
MOVEQ #SlpTimeOut,D0 ; where to put it
|
||
BRA.S WritePMgrPRAM ; go write it out
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: GetHardDiskTimeout (PowerMgrDispatch selector #4)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - hard disk time (number of 15 second intervals)
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: returns the amount of time the system will wait after the last hard disk
|
||
; access before shutting down power to the hard disk
|
||
;________________________________________________________________________________________
|
||
|
||
GetHardDiskTimeout
|
||
MOVEQ #HDTimeOut,D0 ; which byte to read
|
||
|
||
; Inputs: D0 - PRAM address (upper word must be zero)
|
||
;
|
||
; Outputs: D0 - byte read from PRAM
|
||
;
|
||
; Trashes: D0
|
||
|
||
ReadPMgrPRAM
|
||
ADD.B PRAMBase(A2),D0 ; get the absolute PRAM address
|
||
SWAP D0
|
||
ADDQ.W #1,D0 ; one byte
|
||
SWAP D0
|
||
CLR.W -(SP) ; make space for a buffer on the stack
|
||
MOVEA.L SP,A0 ; and point to it
|
||
_ReadXPRAM ; read the byte
|
||
MOVEQ #0,D0
|
||
MOVE.B (SP)+,D0 ; and return it in D0
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: SetHardDiskTimeout (PowerMgrDispatch selector #5)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
; D0 - high word: hard disk time to set (number of 15 second intervals)
|
||
;
|
||
; Outputs: D0 - result code (always zero)
|
||
;
|
||
; Trashes: D1, A0
|
||
;
|
||
; Function: sets the amount of time the system will wait after the last hard disk
|
||
; access before shutting down power to the hard disk
|
||
;________________________________________________________________________________________
|
||
|
||
SetHardDiskTimeout
|
||
SWAP D0 ; get the new value
|
||
TST.B D0 ; is it zero?
|
||
BNE.S @NotZero ; -> no
|
||
MOVEQ #DfltHDTime,D0 ; yes, set it to the default
|
||
@NotZero
|
||
MOVE.B D0,HDTime(A2) ; save it
|
||
MOVE.B D0,D1
|
||
MOVEQ #HDTimeOut,D0 ; where to put it
|
||
|
||
; Inputs: D0 - PRAM address (upper word must be zero)
|
||
; D1 - byte to write
|
||
;
|
||
; Outputs: D0 - none
|
||
;
|
||
; Trashes: D0
|
||
|
||
WritePMgrPRAM
|
||
MOVE.B D1,-(SP) ; push the byte to write
|
||
MOVEA.L SP,A0 ; and point to it
|
||
ADD.B PRAMBase(A2),D0 ; get the absolute PRAM address
|
||
SWAP D0
|
||
ADDQ.W #1,D0 ; one byte
|
||
SWAP D0
|
||
_WriteXPRAM ; write the byte
|
||
ADDQ.W #2,SP
|
||
ST TODirtyFlag(A2) ; force an update of the new values
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: HardDiskPowered (PowerMgrDispatch selector #6)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - 1=hard disk spinning, 0=hard disk powered down
|
||
;
|
||
; Trashes: A2
|
||
;
|
||
; Function: spins down the internal hard disk immediately
|
||
;________________________________________________________________________________________
|
||
|
||
HardDiskPowered
|
||
MOVEQ #0,D0 ; zero-extend the result
|
||
TST.L LastHd(A2) ; is the hard disk powered up?
|
||
SNE D0 ; $FF if so, $00 if not
|
||
NEG.B D0 ; 1 if so, 0 if not
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: SpinDownHardDisk (PowerMgrDispatch selector #7)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - result code (always zero)
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: spins down the internal hard disk immediately
|
||
;________________________________________________________________________________________
|
||
|
||
SpinDownHardDisk
|
||
_SpinDownHardDrive
|
||
MOVEQ #0,D0
|
||
@Done RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: IsSpindownDisabled (PowerMgrDispatch selector #8)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - boolean: 1=disabled, 0=enabled
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: returns a boolean telling whether hard disk spindown is enabled or disabled
|
||
;________________________________________________________________________________________
|
||
|
||
IsSpindownDisabled
|
||
MOVEQ #0,D0
|
||
IF HDSpinDownDisable=7 THEN
|
||
TST.B PmgrFlags2(A2)
|
||
SMI D0
|
||
ELSE
|
||
BTST #HDSpinDownDisable,PmgrFlags2(A2)
|
||
SNE D0
|
||
ENDIF
|
||
NEG.B D0
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: SetSpindownDisable (PowerMgrDispatch selector #9)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
; D0 - high word: 1=disable, 0=enable
|
||
;
|
||
; Outputs: D0 - result code (always zero)
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: enables or disables hard disk spindown
|
||
;________________________________________________________________________________________
|
||
|
||
SetSpindownDisable
|
||
SWAP D0
|
||
TST.B D0 ; is it to be disabled?
|
||
BNE.S @disable ; -> yes
|
||
BCLR #HDSpinDownDisable,PmgrFlags2(A2)
|
||
BRA.S @Done ; no, enable it
|
||
|
||
@disable BSET #HDSpinDownDisable,PmgrFlags2(A2)
|
||
@Done MOVEQ #0,D0
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: HardDiskQInstall (PowerMgrDispatch selector #10)
|
||
;
|
||
; Inputs: A0 - pointer to queue element
|
||
; A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - result code (always zero)
|
||
;
|
||
; Trashes: A0, A1, D0
|
||
;
|
||
; Function: adds an element to the hard disk spindown notification queue
|
||
;________________________________________________________________________________________
|
||
|
||
HardDiskQInstall
|
||
MOVEQ #slpTypeErr,D0 ; assume bad queue type
|
||
CMP.W #HDPwrQType,hdQType(A0) ; is it?
|
||
BNE.S @Done ; -> yes, bail
|
||
|
||
LEA HardDiskQHdr(A2),A1 ; point to the hard disk queue
|
||
_Enqueue ; and add the element to the queue
|
||
MOVEQ #0,D0 ; <H87>
|
||
@Done RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: HardDiskQRemove (PowerMgrDispatch selector #11)
|
||
;
|
||
; Inputs: A0 - pointer to queue element
|
||
; A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - result code
|
||
;
|
||
; Trashes: A0, A1, D0
|
||
;
|
||
; Function: removes an element from the hard disk spindown notification queue
|
||
;________________________________________________________________________________________
|
||
|
||
HardDiskQRemove
|
||
MOVEQ #slpTypeErr,D0 ; assume bad queue type
|
||
CMP.W #HDPwrQType,hdQType(A0) ; is it?
|
||
BNE.S @Done ; -> yes, bail
|
||
|
||
LEA HardDiskQHdr(A2),A1 ; point to the hard disk queue
|
||
_Dequeue ; and remove the element from the queue
|
||
MOVEQ #0,D0 ; <H87>
|
||
@Done RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: AutoSleepControl (PowerMgrDispatch selector #13)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
; D0 - high word: 0=disable sleep, 1=enable sleep
|
||
;
|
||
; Outputs: D0 - result code (always zero)
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: Disables or enables auto sleep by incrementing or decrementing the auto sleep
|
||
; semaphone. Note that since the semaphore supports multiple ÔlevelsÕ, if it's
|
||
; been disabled n times in a row, it needs to be enabled n times before auto
|
||
; sleep will really be enabled.
|
||
;________________________________________________________________________________________
|
||
|
||
AutoSleepControl
|
||
SWAP D0 ; get the flag <H85>
|
||
TST.W D0 ; enable or disable? <H85>
|
||
BEQ.S @disable ; -> disable <H85>
|
||
SUBQ.B #1,AutoSlpDisable(A2) ; ÔpopÕ a level towards sleep enabled <H85>
|
||
BGE.S @done ; -> haven't rolled over <H85>
|
||
CLR.B AutoSlpDisable(A2) ; pin the semaphore a zero <H85>
|
||
BRA.S @done ; <H85>
|
||
|
||
@disable ADDQ.B #1,AutoSlpDisable(A2) ; set the semaphore to >0 (ÔpushÕ a level) <H85>
|
||
BHI.S @done ; -> we're done if it's still >0 <H85>
|
||
SUBQ.B #1,AutoSlpDisable(A2) ; it rolled over, so make it >0 again <H85>
|
||
@done MOVEQ #0,D0 ; <H85>
|
||
RTS ; <H85>
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: GetIntModemInfo (PowerMgrDispatch selector #14)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - bitmap of internal modem info:
|
||
; 0: 1=modem installed
|
||
; 1: 1=modem ring detected
|
||
; 2: 1=modem off hook
|
||
; 3: 1=wakeup on ring is enabled
|
||
; 4: 1=external modem selected
|
||
; 15-3: 0=reserved
|
||
; 31-16: modem type
|
||
; -1 = modem installed but type unknown
|
||
; 0 = no modem installed
|
||
; 1 = original serial modem
|
||
; 2 = Rockwell data pump modem (RC144DPL)
|
||
; 3 = Rockwell data pump modem (RC144DPL) + 6805 controller
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: returns a bitmap of information about the internal modem, if any
|
||
;________________________________________________________________________________________
|
||
|
||
GetIntModemInfo
|
||
CLR.W -(SP) ; allocate a buffer for the result
|
||
MOVE.L SP,-(SP) ; pmRBuffer
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
CLR.W -(SP) ; pmLength
|
||
MOVE.W #modemRead,-(SP) ; pmCommand
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; get the modem info
|
||
LEA pmRBuffer+4(SP),SP ; toss the parameter block
|
||
|
||
MOVEQ #PmgrStatusFlags,D0 ; read the byte containing modem status <H83>
|
||
BSR ReadPMgrPRAM ; <H83>
|
||
MOVEQ #1<<UseIntrnlModem,D1 ; mask off the bit, <H83>
|
||
AND.B D0,D1 ; <H83>
|
||
LSL.B #extModemSelected-UseIntrnlModem,D1 ; and shift it into position <H95>
|
||
MOVEQ #(1<<RingWakeEnable)|(1<<ModemInstalled)|(1<<RingDetect)|(1<<ModemHook),D0 ; <H95>
|
||
AND.B (SP)+,D0 ; mask off the bits we want, <H83>
|
||
ROR.B #ModemInstalled-hasInternalModem,D0 ; <H94>
|
||
; and shift them into position <H83>
|
||
BCLR #8-(ModemInstalled-hasInternalModem)+RingWakeEnable,D0 ; <H94>
|
||
BEQ.S @NoWake ; -> the Ôwakeup on ringÕ bit isn't set <H94>
|
||
ADDQ.B #1<<intModemRingWakeEnb,D0 ; set the bit in the output <H94>
|
||
@NoWake OR.B D1,D0 ; combine all the bits so far <H83>
|
||
|
||
BTST #hasInternalModem,D0 ; is an internal modem installed? <H93>
|
||
BEQ.S @Done ; -> no, we're done <H93>
|
||
MOVE.L D0,-(SP) ; save the rest of the information <H93>
|
||
BSR ModemTypeProc ; find out what kind of modem is installed <H93>
|
||
SWAP D0 ; and move it into bits 16-31 <H93>
|
||
CLR.W D0 ; (make sure we don't have any stray bits) <H93>
|
||
OR.L (SP)+,D0 ; then OR in the rest of the info <H93>
|
||
@Done RTS
|
||
|
||
|
||
;________________________________________________________________________________________ <H95>
|
||
;
|
||
; Routine: SetIntModemState (PowerMgrDispatch selector #15)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
; D0 - high word: bitmap of bits to set or clear
|
||
; 18: 1=wakeup on ring is enabled if bit 31=1, or disabled if bit 31=0
|
||
; 19: 1=external modem selected if bit 31=1, or external if bit 31=0
|
||
; 31: 1=set all other 1-bits, 0=clear all other 1-bits
|
||
;
|
||
;
|
||
; Outputs: D0 - result code (always zero)
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: Configures some of the state information for the internal modem.
|
||
;________________________________________________________________________________________
|
||
|
||
SetIntModemState
|
||
SWAP D0 ; get the flags
|
||
BTST #intModemRingWakeEnb,D0 ; do we need to update Ôwakeup on ringÕ?
|
||
BEQ.S @NoWake ; -> nope
|
||
LoadTbl PrimInfoTblPtr,A2,A0
|
||
MOVE.L PrimPubFeatures(A0),D1 ; does this machine support Ôwakeup on ringÕ?
|
||
BTST #canWakeupOnRing,D1
|
||
BEQ.S @NoWake ; -> no, skip it
|
||
|
||
MOVE.W D0,-(SP) ; save the flags
|
||
SMI D0 ; $FF=enabled, $00=disabled
|
||
MOVEQ #1<<RingWakeEnable,D1 ; mask off the Ôwakeup on ringÕ bit
|
||
AND.L D0,D1
|
||
|
||
CLR.W -(SP) ; allocate a buffer for the result
|
||
MOVE.L SP,-(SP) ; pmRBuffer
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
CLR.W -(SP) ; pmLength
|
||
MOVE.W #modemRead,-(SP) ; pmCommand
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; get the modem info
|
||
|
||
ANDI.B #~(1<<RingWakeEnable),pmRBuffer+4(SP) ; mask out the Ôwakeup on ringÕ bit
|
||
OR.B D1,pmRBuffer+4(SP) ; and OR in the new value
|
||
MOVE.W #modemSet,pmCommand(SP)
|
||
_PMgrOp ; write it back out
|
||
LEA pmRBuffer+4(SP),SP ; toss the parameter block
|
||
|
||
MOVE.W (SP)+,D0 ; get the flags back
|
||
|
||
@NoWake BTST #extModemSelected,D0 ; do we need to update internal/external modem?
|
||
BEQ.S @Done ; -> nope, all done
|
||
|
||
TST.W D0 ; test for zero/non-zero
|
||
SMI -(SP) ; push $00=internal/$FF=external on stack
|
||
|
||
MOVEQ #PmgrStatusFlags,D0 ; read the byte containing modem status
|
||
BSR ReadPMgrPRAM
|
||
|
||
MOVEQ #~(1<<UseIntrnlModem),D1 ; mask off everything but the modem bit
|
||
AND.B D0,D1
|
||
MOVEQ #1<<UseIntrnlModem,D0 ; mask off the passed in flag
|
||
AND.B (SP)+,D0
|
||
OR.B D0,D1 ; and OR it in with the other bits
|
||
|
||
MOVE.B D1,SleepFlags(A2) ; save it
|
||
MOVEQ #PmgrStatusFlags,D0 ; write the byte containing modem status back out
|
||
BRA WritePMgrPRAM
|
||
|
||
@Done RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: MaximumProcessorSpeed (PowerMgrDispatch selector #16)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - processor speed
|
||
;
|
||
; Trashes: D1, A0
|
||
;
|
||
; Function: returns the maximum processor speed, in MHz
|
||
;________________________________________________________________________________________
|
||
|
||
MaximumProcessorSpeed
|
||
MOVEQ #CPUSpeedDisp,D0 ; get the current/max CPU speed
|
||
_PowerDispatch
|
||
CLR.W D0 ; clear the current speed
|
||
SWAP D0 ; and move the max speed into the lower word
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: CurrentProcessorSpeed (PowerMgrDispatch selector #17)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - processor speed
|
||
;
|
||
; Trashes: D1, A0
|
||
;
|
||
; Function: returns the current processor speed, in MHz
|
||
;________________________________________________________________________________________
|
||
|
||
CurrentProcessorSpeed
|
||
MOVEQ #CPUSpeedDisp,D0 ; get the current/max CPU speed
|
||
_PowerDispatch
|
||
EXT.L D0 ; clear the maximum speed speed
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: FullProcessorSpeed (PowerMgrDispatch selector #18)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - boolean: 1=full speed, 0=reduced speed
|
||
;
|
||
; Trashes: D1, A0
|
||
;
|
||
; Function: returns a boolean indicating whether the CPU will start up at full or
|
||
; reduced speed
|
||
;________________________________________________________________________________________
|
||
|
||
FullProcessorSpeed
|
||
MOVEQ #1,D0 ; assume full speed <H92>
|
||
LoadTbl PrimInfoTblPtr,A2,A0
|
||
MOVEQ #1<<hasReducedSpeed,D1 ; is reduced speed supported? <H92>
|
||
AND.L PrimPubFeatures(A0),D1 ; <H92>
|
||
BEQ.S @Done ; -> no, we're done <H92>
|
||
|
||
MOVEQ #PmgrOtherFlags,D0 ; read the byte containing the CPU speed bit
|
||
BSR.S ReadPMgrPRAM
|
||
IF EconoBit0 THEN
|
||
LSR.B #EconoBit,D0 ; shift the bit into bit zero
|
||
ENDIF
|
||
MOVEQ #1,D1
|
||
EOR.B D1,D0 ; invert the bit so true=full speed
|
||
AND.B D1,D0 ; and mask off the bit
|
||
@Done RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: SetProcessorSpeed (PowerMgrDispatch selector #19)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
; D0 - high word: 1=full speed, 0=half speed
|
||
;
|
||
; Outputs: D0 - boolean: true=speed was changed, false=only PRAM was changed
|
||
;
|
||
; Trashes: D1, D2, A0, A1, A2
|
||
;
|
||
; Function: Updates PRAM to reflect the desired CPU speed on the next restart. If the
|
||
; machine supports dynamic speed switching, the hardware will be whacked to
|
||
; change the speed, the low-mem timing constants (TimeDBRA, etc.) will be
|
||
; updated, and the AppleTalk Transition Queue will be run to notify anyone
|
||
; who cares that they need to recalculate their timing parameters.
|
||
;________________________________________________________________________________________
|
||
|
||
ATQEntry RECORD 0,INCREMENT
|
||
qLink DS.L 1 ; pointer to next queue entry
|
||
qType DS.W 1 ; queue type
|
||
CallAddr DS.L 1 ; pointer to routine to be called
|
||
ENDR
|
||
|
||
ATTransSpeedChange EQU 'sped' ; event = speed change
|
||
|
||
SetProcessorSpeed
|
||
SWAP D0 ; get the boolean,
|
||
MOVEQ #1,D1
|
||
EOR.B D1,D0 ; invert it so true=reduced speed,
|
||
AND.B D0,D1 ; mask it off to a single bit,
|
||
IF EconoBit=1 THEN
|
||
ADD.B D1,D1 ; and then shift it into the correct bit position
|
||
ELSEIF EconoBit>1
|
||
LSL.B #EconoBit,D1 ; and then shift it into the correct bit position
|
||
ENDIF
|
||
|
||
MOVEQ #1,D0 ; assume full speed <H92>
|
||
LoadTbl PrimInfoTblPtr,A2,A0
|
||
MOVEQ #1<<hasReducedSpeed,D2 ; is reduced speed supported? <H92>
|
||
AND.L PrimPubFeatures(A0),D2 ; <H92>
|
||
BEQ @Done ; -> no, we're done <H92>
|
||
|
||
; update the setting in PRAM
|
||
|
||
MOVEQ #PmgrOtherFlags,D0 ; read the byte containing the CPU speed bit
|
||
BSR.S ReadPMgrPRAM
|
||
MOVE.B D0,D2
|
||
ANDI.B #~(1<<EconoBit),D0 ; mask out the econo-mode bit
|
||
OR.B D0,D1 ; and insert the new value into the byte
|
||
MOVEQ #0,D0
|
||
CMP.B D2,D1 ; will the speed change?
|
||
BEQ @Done ; -> no, just exit
|
||
MOVEQ #PmgrOtherFlags,D0 ; yes, write the PRAM byte back out
|
||
BSR.S WritePMgrPRAM
|
||
|
||
MOVEQ #1<<EconoBit,D0 ; mask off the econo-mode bit
|
||
AND.W D0,D1
|
||
|
||
; change the speed if it can be done dynamically
|
||
|
||
LoadTbl PrimInfoTblPtr,A2,A0
|
||
MOVEQ #1<<dynamicSpeedChange,D0 ; is dynamic speed change supported? <H90>
|
||
AND.L PrimPubFeatures(A0),D0 ; <H90>
|
||
BEQ.S @Done ; -> no, we're done <H90>
|
||
|
||
MOVE.W D1,-(SP) ; (save D1 across the call)
|
||
JsrRoutine SpeedChangePtr,A2,A0 ; and go do the switch
|
||
MOVE.W (SP)+,D1 ; (restore D1)
|
||
TST.W D0 ; did we do the speed switch?
|
||
BEQ.S @Done ; -> no, we're done
|
||
|
||
MOVEQ #CPUSpeedDisp,D0 ; get the current CPU speed
|
||
_PowerDispatch
|
||
MOVE.B D0,saveSpeedo(A0) ; and update speedo for people using IdleRead
|
||
|
||
; setup new timing constants for the TimeDBRA low-mems
|
||
|
||
LSL.W #3-EconoBit,D1 ; convert D1 to an index (0 or 8)
|
||
LEA fullSpeedDBRAs(A2),A1 ; point to the correct table
|
||
ADDA.W D1,A1
|
||
MOVE.W (A1)+,TimeDBRA ; copy the timing constants to low mem
|
||
MOVE.W (A1)+,TimeSCCDB
|
||
MOVE.W (A1)+,TimeSCSIDB
|
||
MOVE.W (A1)+,TimeVIADB
|
||
|
||
; run the AppleTalk transition queue
|
||
|
||
MOVE.L #gestaltAppleTalkVersion,D0 ; get the version of AppleTalk
|
||
_Gestalt
|
||
BNE.S @NoATalk ; -> error means it's not installed
|
||
MOVE.L A0,D0 ; get the AppleTalk version
|
||
BEQ.S @NoATalk ; -> zero means AppleTalk is turned off
|
||
|
||
MOVEQ #25,D0 ; get a pointer to the transition queue
|
||
MOVEA.L AtalkHk2,A0
|
||
JSR LapMgrCall(A0)
|
||
LEA qHead(A1),A2 ; point to the head of the queue
|
||
BRA.S @StartQueue
|
||
|
||
@NextQueue MOVE.L D0,A2 ; point to the queue element
|
||
|
||
MOVEM.L D3-D7/A2-A6,-(SP) ; save registers cuz apparently some procs do trash them
|
||
|
||
CLR.L -(SP) ; no routine-specific parameters
|
||
MOVE.L A2,-(SP) ; *ATQEntry
|
||
PEA ATTransSpeedChange ; selector = speed change
|
||
MOVEA.L ATQEntry.CallAddr(A2),A0 ; call the transition queue element's routine
|
||
JSR (A0)
|
||
LEA 4+4+4(SP),SP ; toss the parameters
|
||
|
||
MOVEM.L (SP)+,D3-D7/A2-A6
|
||
|
||
@StartQueue MOVE.L qLink(A2),D0 ; point to the next queue element; end of the queue?
|
||
BNE.S @NextQueue ; -> no, keep looping
|
||
@NoATalk MOVEQ #1,D0
|
||
|
||
@Done RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: GetSCSIDiskModeAddress (PowerMgrDispatch selector #20)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - SCSI bus addresse internal hard disk (1-6)
|
||
;
|
||
; Trashes: D1, A0
|
||
;
|
||
; Function: returns the SCSI Disk Mode address of the internal hard disk
|
||
;________________________________________________________________________________________
|
||
|
||
GetSCSIDiskModeAddress
|
||
LoadTbl PrimInfoTblPtr,A2,A0
|
||
MOVEQ #1<<hasSCSIDiskMode,D0 ; is SCSI Disk Mode supported on this machine?
|
||
AND.L PrimPubFeatures(A0),D0
|
||
BEQ.S @Done
|
||
|
||
MOVEQ #PmgrOtherFlags,D0 ; read the byte containing the address
|
||
BSR.S ReadPMgrPRAM
|
||
IF DiskModeAddr0 THEN
|
||
LSR.B #DiskModeAddr,D0 ; and shift it down to bit zero
|
||
ENDIF
|
||
IF DiskModeAddr<5 THEN
|
||
ANDI.B #%111,D0 ; mask to just the 3 lsb's
|
||
ENDIF
|
||
MOVE.B mapSCSIAddr(D0),D0 ; make sure we return a valid address
|
||
@Done RTS
|
||
|
||
mapSCSIAddr DC.B 2,1,2,3,4,5,6,2 ; <H94>
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: SetSCSIDiskModeAddress (PowerMgrDispatch selector #21)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
; D0 - high word: SCSI bus address of the internal hard disk (1-6)
|
||
;
|
||
; Outputs: D0 - result code (always zero)
|
||
;
|
||
; Trashes: D0, D1, A0
|
||
;
|
||
; Function: updates PRAM with the SCSI Disk Mode address for the internal hard disk
|
||
;________________________________________________________________________________________
|
||
|
||
SetSCSIDiskModeAddress
|
||
LoadTbl PrimInfoTblPtr,A2,A0
|
||
MOVEQ #1<<hasSCSIDiskMode,D1 ; is SCSI Disk Mode supported on this machine?
|
||
AND.L PrimPubFeatures(A0),D1
|
||
BEQ.S @Done
|
||
|
||
SWAP D0 ; get the ID
|
||
CMPI.W #7,D0 ; is it in range?
|
||
BLS.S @MapID ; -> yes
|
||
MOVEQ #7,D0 ; no, pin it
|
||
@MapID MOVE.B mapSCSIAddr(D0),D0 ; make sure the address is valid,
|
||
IF DiskModeAddr0 THEN
|
||
LSL.B #DiskModeAddr,D0 ; and then shift it into the correct bit position
|
||
ENDIF
|
||
MOVE.B D0,D1 ; save it for the write
|
||
MOVEQ #PmgrOtherFlags,D0 ; read the byte containing the CPU speed bit
|
||
BSR ReadPMgrPRAM
|
||
ANDI.W #~(%111<<DiskModeAddr),D0 ; mask out the disk mode address bits
|
||
OR.B D0,D1 ; and insert the new value into the byte
|
||
MOVEQ #PmgrOtherFlags,D0 ; then write the PRAM byte back out
|
||
BRA WritePMgrPRAM
|
||
|
||
@Done MOVEQ #0,D0
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: GetWakeupTimer (PowerMgrDispatch selector #22)
|
||
;
|
||
; Inputs: A0 - pointer to buffer to hold wakeup time and enable/disable flag byte
|
||
; A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - none
|
||
;
|
||
; Trashes: A0,A1
|
||
;
|
||
; Function: returns the time when the PowerBook will wake up
|
||
;________________________________________________________________________________________
|
||
|
||
GetWakeupTimer
|
||
LoadTbl PrimInfoTblPtr,A2,A1
|
||
MOVEQ #1<<hasWakeupTimer,D0 ; does this machine have a wakeup timer?
|
||
AND.L PrimPubFeatures(A1),D0
|
||
BEQ.S @NoTimer ; -> no, we're done
|
||
|
||
MOVE.L A0,-(SP) ; pmRBuffer <H95>
|
||
CLR.L -(SP) ; pmSBuffer
|
||
CLR.W -(SP) ; pmLength
|
||
MOVE.W #timerRead,-(SP) ; pmCommand
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; read the wakeup time
|
||
LEA pmRBuffer+4(SP),SP ; toss the parameter block
|
||
RTS
|
||
|
||
@NoTimer CLR.L (A0)+ ; zero out all the fields <H95>
|
||
CLR.B (A0)+ ; <H95>
|
||
RTS ; <H95>
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: SetWakeupTimer (PowerMgrDispatch selector #23)
|
||
;
|
||
; Inputs: A0 - pointer to buffer that contains the wakeup time and enable/disable flag byte
|
||
; A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - none
|
||
;
|
||
; Trashes: D0,A0,A1
|
||
;
|
||
; Function: sets the time when the PowerBook will wake up
|
||
;________________________________________________________________________________________
|
||
|
||
SetWakeupTimer
|
||
LoadTbl PrimInfoTblPtr,A2,A1
|
||
MOVEQ #1<<hasWakeupTimer,D0 ; does this machine have a wakeup timer?
|
||
AND.L PrimPubFeatures(A1),D0
|
||
BEQ.S @NoTimer ; -> no, we're done
|
||
|
||
MOVEA.L A0,A1 ; save a copy of the buffer pointer
|
||
|
||
CLR.L -(SP) ; pmRBuffer <H95>
|
||
MOVE.L A0,-(SP) ; pmSBuffer <H95>
|
||
MOVE.W #4,-(SP) ; pmLength
|
||
MOVE.W #timerSet,-(SP) ; pmCommand
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; set the timer
|
||
|
||
TST.B 4(A1) ; is the timer to be disabled? <H95>
|
||
BNE.S @Done ; -> nope, all done
|
||
|
||
MOVE.W #$82,pmCommand(A0) ; send a Ôdisable wakeup timerÕ command <H95>
|
||
CLR.W pmLength(A0) ; <H95>
|
||
_PMgrOp ; <H95>
|
||
|
||
@Done LEA pmRBuffer+4(SP),SP ; clean up the stack
|
||
@NoTimer RTS
|
||
|
||
|
||
;________________________________________________________________________________________ <H90>
|
||
;
|
||
; Routine: GetProcessorCycling (PowerMgrDispatch selector #24)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - boolean: 1=cycling is enabled, 0=cycling is disabled
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: returns whether or not processor cycling is enabled
|
||
;________________________________________________________________________________________
|
||
|
||
GetProcessorCycling
|
||
MOVEQ #PmgrStatusFlags,D0 ; read the byte containing modem status <H85>
|
||
BSR ReadPMgrPRAM ; <H85>
|
||
BTST #IdleBit,D0 ; 1=disabled, 0=enabled
|
||
SEQ D0
|
||
NEG.B D0 ; 1=enabled, 0=disabled
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________ <H90>
|
||
;
|
||
; Routine: SetProcessorCycling (PowerMgrDispatch selector #25)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
; D0 - boolean: 1=enable cycling, 0=disable cycling
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: enables/disables processor cycling
|
||
;________________________________________________________________________________________
|
||
|
||
SetProcessorCycling
|
||
SWAP D0 ; get the boolean
|
||
TST.W D0 ; enable or disable?
|
||
BNE.S @enable
|
||
|
||
BSET #IdleBit,SleepFlags(A2) ; disable idle
|
||
BRA.S @common
|
||
|
||
@enable BCLR #IdleBit,SleepFlags(A2) ; enable idle
|
||
|
||
@common MOVEQ #PmgrStatusFlags,D0 ; write the byte containing idle status
|
||
MOVE.B SleepFlags(A2),D1
|
||
BRA WritePMgrPRAM
|
||
|
||
|
||
;________________________________________________________________________________________ <H90>
|
||
;
|
||
; Routine: BatteryCount (PowerMgrDispatch selector #26)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - number of internal batteries we can have
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: returns the number of internal batteries we can have
|
||
;________________________________________________________________________________________
|
||
|
||
BatteryCount
|
||
MOVEA.L PMgrBase,A2 ; get pointer to Power manager globals
|
||
LoadTbl PrimInfoTblPtr,A2,A0
|
||
MOVEQ #0,D0 ; get the number of internal batteries we can have
|
||
MOVE.W PrimBatteryCount(A0),D0
|
||
RTS
|
||
|
||
|
||
;________________________________________________________________________________________ <H83>
|
||
;
|
||
; Routine: GetBatteryVoltage (PowerMgrDispatch selector #27)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
; D0 - high word: battery number (0-n)
|
||
;
|
||
; Outputs: D0 - battery voltage
|
||
;
|
||
; Trashes: A0-A1, D1-D2
|
||
;
|
||
; Function: returns the battery voltage as a fixed-point number so that nobody external
|
||
; to the Power Manager needs to do the calculation anymore.
|
||
;________________________________________________________________________________________
|
||
|
||
GetBatteryVoltage
|
||
MOVEA.L PMgrBase,A2 ; get pointer to Power manager globals
|
||
LoadTbl PrimInfoTblPtr,A2,A0
|
||
SWAP D0 ; get the battery number <H90>
|
||
CMP.W PrimBatteryCount(A0),D0 ; do we support this many batteries? <H90>
|
||
BHS.S @NoBattery ; -> no, return zero <H90>
|
||
|
||
JmpRoutine AbsoluteBattPtr,A2,A0; run the routine
|
||
|
||
@NoBattery MOVEQ #0,D0 ; return zero volts <H90>
|
||
RTS ; <H90>
|
||
|
||
|
||
;________________________________________________________________________________________ <H90>
|
||
;
|
||
; Routine: GetBatteryTimes (PowerMgrDispatch selector #28)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
; A0 - pointer to BatteryTimeRec record:
|
||
; expectedBatteryTime DS.L 1 ; estimated battery time remaining
|
||
; minimumBatteryTime DS.L 1 ; minimum battery time remaining
|
||
; maximumBatteryTime DS.L 1 ; maximum battery time remaining
|
||
; timeUntilCharged DS.L 1 ; time remaining until the battery is fully charged
|
||
; D0 - high word: system total (0) - battery number (1-n)
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: A0-A1, D0-D2
|
||
;
|
||
; Function: fills in a record containing fields that describe battery times.
|
||
;________________________________________________________________________________________
|
||
|
||
GetBatteryTimes
|
||
MOVEA.L PMgrBase,A2 ; get pointer to Power manager globals
|
||
LoadTbl PrimInfoTblPtr,A2,A1
|
||
SWAP D0 ; get the battery number
|
||
CMP.W PrimBatteryCount(A1),D0 ; do we support this many batteries?
|
||
BHS.S @NoBattery ; -> no, return zero
|
||
|
||
JmpRoutine BatteryTimePtr,A2,A1 ; run the routine (D0.W contains battery number or system)
|
||
|
||
@NoBattery CLR.L (A0)+ ; zero out the fields
|
||
CLR.L (A0)+
|
||
CLR.L (A0)+
|
||
CLR.L (A0)+
|
||
MOVEQ #0,D0
|
||
RTS
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: LCDScreenChk
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: CCR - BNE if LCD screen
|
||
;
|
||
; Trashes: D0, A0, A1
|
||
;
|
||
; Function: For Color QuickDraw machines, check if a flag in the video attributes sRsrc
|
||
; says we have an LCD screen for built-in video. If the sRsrc doesn't exist,
|
||
; or the flag isn't set, we assume a CRT.
|
||
;________________________________________________________________________________________
|
||
|
||
LCDScreenChk
|
||
WITH SpBlock
|
||
|
||
Cmp.w #$3FFF,ROM85 ; If Color QuickDraw is not around,
|
||
Bne.s @NoCQD ; then just leave.
|
||
Tst.l DeviceList ; If the DeviceList is empty,
|
||
Beq.s @NoDevices ; then just leave.
|
||
Move.l MainDevice,D0 ; If there isnÕt a MainDevice,
|
||
Beq.s @NoDevices ; then just leave.
|
||
|
||
Move.l D0,A0 ; Get the Handle to the MainDevice.
|
||
Move.l (A0),A0 ; Make it a pointer.
|
||
Moveq #0,D0 ; Prepare D0 for unsigned .w references.
|
||
Move.w gdRefNum(A0),D0 ; If thereÕs no driver, then
|
||
Beq.s @NoDevices ; we canÕt do anything here.
|
||
|
||
Not.w D0 ; Convert the refNum intoÉ
|
||
Lsl.w #2,D0 ; Éa UTable index.
|
||
Add.l UTableBase,D0 ; Get a ptr to the AuxDCEHandle.
|
||
Move.l D0,A1 ; Get it into A1.
|
||
Move.l (A1),A1 ; Get the AuxDCEHandle.
|
||
Move.l (A1),A1 ; Get the AuxDCEPtr.
|
||
|
||
Lea -spBlockSize(sp),Sp ; Put a slot parameter block on the stack.
|
||
Move.l Sp,A0 ; Point to it with A0.
|
||
Move.b dCtlSlot(A1),spSlot(A0) ; Get the slot number.
|
||
Move.b dCtlSlotID(A1),spID(A0) ; Get the spID of the video sRsrc.
|
||
Clr.b spExtDev(A0) ; DonÕt ask why, just clear this guy.
|
||
_sRsrcInfo ; Get the spsPointer.
|
||
Bne.s @AssumeCRT ; If failed, just quit.
|
||
|
||
Move.b #sVidAttributes,spID(A0); Say to get the video sRsrc attributes.
|
||
_sReadWord ; Get Õem.
|
||
Bne.s @AssumeCRT ; If failed, just quit.
|
||
|
||
Moveq #1<<fLCDScreen,D0 ; Mask off the LCD bit in the sRsrc attributes.
|
||
And.w spResult+2(A0),D0
|
||
|
||
@Done Lea spBlockSize(sp),Sp ; Clean up the stack.
|
||
@NoDevices Rts ; Return to caller.
|
||
|
||
@AssumeCRT Moveq #0,D0 ; Set CCR appropriately.
|
||
Bra.s @Done
|
||
|
||
@NoCQD Moveq #0,D0 ; Set CCR appropriately.
|
||
Rts ; Return to caller.
|
||
|
||
|
||
;________________________________________________________________________________________ <K12>
|
||
; |
|
||
; Routine: GetDimTimeout (PowerMgrDispatch selector #29) v
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - sleep timeout (number of 15 second intervals)
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: returns the current sleep timeout time
|
||
;________________________________________________________________________________________
|
||
GetDimTimeout
|
||
MOVEQ #0,D0 ; assume the result is zero
|
||
MOVE.L DimmingWaitTime(A2),D1 ; get value from globals
|
||
BEQ.S @Done
|
||
DIVU.L #pram2ticks,D1 ; convert from ticks value to 15 sec intervals
|
||
MOVE.B D1,D0 ; return result
|
||
@Done RTS
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: SetDimTimeout (PowerMgrDispatch selector #30)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
; D0 - high word: sleep time to set (number of 15 second intervals)
|
||
;
|
||
; Outputs: D0 - result code (always zero)
|
||
;
|
||
; Trashes: D1, A0
|
||
;
|
||
; Function: sets the current sleep timeout
|
||
;________________________________________________________________________________________
|
||
SetDimTimeout
|
||
SWAP D0 ; get the new value
|
||
MOVEQ #0,D1 ; clear reg
|
||
MOVE.B D0,D1 ; get the new value
|
||
MULU.W #pram2ticks,D1 ; set ticks value
|
||
MOVE.L D1,DimmingWaitTime(A2) ; save value in globals
|
||
_UsrIdleUpdate
|
||
MOVEQ #0,D0 ; return noErr
|
||
RTS
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: DimControl (PowerMgrDispatch selector #31)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
; D0 - high word: 0=disable sleep, 1=enable sleep
|
||
;
|
||
; Outputs: D0 - result code (always zero)
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: Disables or enables auto sleep by incrementing or decrementing the auto sleep
|
||
; semaphone. Note that since the semaphore supports multiple ÔlevelsÕ, if it's
|
||
; been disabled n times in a row, it needs to be enabled n times before auto
|
||
; sleep will really be enabled.
|
||
;________________________________________________________________________________________
|
||
DimControl
|
||
SWAP D0 ; get the flag
|
||
TST.W D0 ; enable or disable?
|
||
BEQ.S @disable ; -> disable
|
||
SUBQ.B #1,DimmingDisable(A2) ; ÔpopÕ a level towards sleep enabled
|
||
BGE.S @done ; -> haven't rolled over
|
||
CLR.B DimmingDisable(A2) ; pin the semaphore a zero
|
||
BRA.S @done ;
|
||
|
||
@disable ADDQ.B #1,DimmingDisable(A2) ; set the semaphore to >0 (ÔpushÕ a level)
|
||
BHI.S @done ; -> we're done if it's still >0
|
||
SUBQ.B #1,DimmingDisable(A2) ; it rolled over, so make it >0 again
|
||
@done MOVEQ #0,D0 ;
|
||
RTS ; <K12>
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: IsDimmingDisabled (PowerMgrDispatch selector #32)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - boolean: 1=disabled, 0=enabled
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: returns a boolean telling whether dimming is enabled or disabled
|
||
;________________________________________________________________________________________
|
||
|
||
IsDimmingDisabled
|
||
MOVEQ #0,D0 ; assume enabled
|
||
TST.B DimmingDisable(A2) ; IF counting semaphor not nil THEN
|
||
BEQ.S @Done ;
|
||
MOVEQ #1,D0 ; tell the world it's disabled
|
||
@Done RTS ; that's all folks
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: IsAutoSlpDisabled (PowerMgrDispatch selector #33)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - boolean: 1=disabled, 0=enabled
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: returns a boolean telling whether autosleep is enabled or disabled
|
||
;________________________________________________________________________________________
|
||
|
||
IsAutoSlpDisabled
|
||
MOVEQ #0,D0 ; assume enabled
|
||
TST.B AutoSlpDisable(A2) ; IF counting semaphor not nil THEN
|
||
BEQ.S @Done ;
|
||
MOVEQ #1,D0 ; tell the world it's disabled
|
||
@Done RTS ; that's all folks
|
||
RTS
|
||
|
||
ENDIF ; {hasPwrControls}
|
||
END |