mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-08-29 08:29:03 +00:00
5195 lines
241 KiB
Plaintext
5195 lines
241 KiB
Plaintext
;
|
||
; File: PowerMgrPrimitives.a
|
||
;
|
||
; Contains: low-level routines for managing Power Management tasks
|
||
;
|
||
; Written by: Helder J. Ramalho
|
||
;
|
||
; Copyright: © 1992-1993 by Apple Computer, Inc. All rights reserved.
|
||
;
|
||
; This file is used in these builds: ROM
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <SM8> 12/13/93 PN Roll in KAOs and Horror changes to support Malcom and AJ
|
||
; machines.
|
||
; <SM7> 9/17/93 KH I'm not Eva (EH), but this BBS installation is apparently
|
||
; screwed up.
|
||
; <SM6> 9/17/93 SKH Fix a bug with sleep. Don't use A3 to acces PMgr globals, use
|
||
; A2. (SaveSleepInfo)
|
||
; <SM5> 8/4/93 JDR Private sound defines were moved to SoundPrivate.a.
|
||
; <SM4> 01-12-93 jmp Changed name from drHwDBLite to the more appropriate drHwGSC.
|
||
; <SM3> 11/20/92 SWC Rolled in the rest of the Horror changes.
|
||
; <H44> 8/13/92 SWC Changed GetExtLevel to change warning levels at the 1/3 and 2/3
|
||
; levels instead of at the x/4 levels so we get better spaced
|
||
; warnings.
|
||
; <H43> 8/4/92 SWC Save and restore the current GrafPort around the call to
|
||
; PaintBehind since PaintBehind will clobber it. This was causing
|
||
; the screen to be incorrectly updated (portions remained gray).
|
||
; <H42> 7/27/92 SWC Point to the correct SendSleep routine for DBLite (we
|
||
; distinguish between a normal and low power sleep).
|
||
; <H41> 7/23/92 SWC Fixed a bug in GetExtLevel that was keeping us from displaying
|
||
; low power messages.
|
||
; <H40> 7/22/92 SWC In SaveMSC, turn on IOClk before we go to sleep in case a bar is
|
||
; added during sleep so that the clock will be running as soon as
|
||
; power is turned back on. If it turns out no bar is attached, the
|
||
; Docking Manager will turn this back off.
|
||
; <H39> 7/14/92 ag Change the LeadScaledBattery routine to use globals and avoid
|
||
; hitting the power manager. Instead of current battery level,
|
||
; use averaged battery level.
|
||
; <H38> 7/14/92 djw (HJR) Remove NiagraChkIdle since it is not used.
|
||
; <H37> 7/14/92 SWC Hopefully I finally got the scaled battery stuff working (those
|
||
; Dart guys will be mighty pissed if we need to do a patch...).
|
||
; <H36> 7/14/92 HJR Modify dimming so that a screen update will only occur if some
|
||
; device supported the LowPwrSelect control call.
|
||
; <H35> 7/13/92 HJR Fix a bug in Dimming where if External Monitor is startup
|
||
; device, internal display does not unblank itself after dimming.
|
||
; Problem was that A0=IOPB was being trashed by PaletteDispatch.
|
||
; <H34> 7/13/92 HJR Rewrote External monitor alerts so that if an External Monitor
|
||
; Alert is displayed, the charger state will not remove alert.
|
||
; Added ChkDimming so that DBlite may use it more readily.
|
||
; <H33> 7/13/92 ag Added constants to the info tables for delay time before shorted
|
||
; battery dialog and delta battery warn level if external monitor
|
||
; is being used.
|
||
; <H32> 7/11/92 HJR Rewrote VidLowPwrSelect so that it runs throught the device list
|
||
; and powers down all available screens. Cleaned up things here
|
||
; and there.
|
||
; <H31> 7/10/92 ag added modem primitive tables and routines. added vectorize
|
||
; shutdown with retry.
|
||
; <H30> 7/1/92 ag Clear sound power control before turning on power amps.
|
||
; <H29> 7/1/92 ag Add code to turn off power to sound circuits controlled by ponti
|
||
; asic during sleep. Added power amplifiers controls to niagra
|
||
; sleep and wake routines.
|
||
; <H28> 6/30/92 HJR In SaveGSC and RestoreGSC, call the driver to Blank the screen
|
||
; on going to sleep and grey the screen on wakeup.
|
||
; <H27> 6/25/92 SWC Fixed the clamshell logic (was crashing if a docking bar
|
||
; prevented sleep). We no longer shutdown on clamshell close since
|
||
; that had a lot of problems. Upped the padding size to 8K since
|
||
; we're getting full (and more stuff is expected. :)
|
||
; <H26> 6/11/92 djw Modify PostUserNmMsg to accept completion routine parameter.
|
||
; Add code to check for posting a warning msg based on a flag set
|
||
; by the external video's primaryInit (if no charger attached) in
|
||
; NiagraRunIdleRoutineProc.
|
||
; <H25> 6/10/92 HJR Disable GDevice when dimming and fix bug where if external
|
||
; device is main device, bus error occurs after dimming.
|
||
; <H24> 6/9/92 ag change the batman save and restore code the the one used on
|
||
; terror. The order which things are done is very critical. if you
|
||
; must change the code, do so carefully.
|
||
; <H23> 6/5/92 SWC Finished up the scaled battery info routines.
|
||
; <H22> 6/2/92 djw Added check for external video without a charger in
|
||
; NiagraRunIdleRoutineProc. If condition found, post alert to the
|
||
; user. Added PostUserNmMsg utility routine.
|
||
; <H21> 6/1/92 HJR Disable GDevice if we are powering down the device.
|
||
; <H20> 5/19/92 HJR Generalized IdleMindTable with RunIdleRoutines so that various
|
||
; miscellaneous routines can be localized. Add
|
||
; NiagraRunIdleRoutineProc which now check whether to power down
|
||
; screens.
|
||
; <H19> 5/15/92 SWC Added the battery and sound monitoring VBL tasks to the list of
|
||
; primitives for each machine, and moved SndWatch and
|
||
; SndWatchPonti here from PowerMgr.a.
|
||
; <H18> 5/8/92 SWC Fixed a copy/paste typo in the MSC table that could cause a
|
||
; crash. Removed CPUSpeedNiagraRead since it's no longer used.
|
||
; <H17> 5/7/92 HJR Added primitives for WakeScreenRefresh and necessary code for
|
||
; VSCPowerSelect. Rewrote CPUSpeedNiagra to that it matches
|
||
; hardware. Blank GSC during wakeup.
|
||
; <H16> 5/7/92 ag Added softshutdown to Dartanian timeout checks.
|
||
; <H15> 5/7/92 SWC Added primitives to return a scaled battery level so the Battery
|
||
; DA, etc., won't have to be rev'd each time we do a new portable.
|
||
; Added a check to ChkHDSpinDown to prevent the hard disk from
|
||
; being spun down if we're connected to a docking station (AC
|
||
; power is assumed).
|
||
; <SM2> 11/19/92 SWC Exported the primitives tables so they can be used in
|
||
; UniversalTables.a. Changed ShutdownEqu.a->Shutdown.a.
|
||
; <1> 5/17/92 kc first checked in
|
||
; <SM0> 5/2/92 kc Roll in Horror. Comments follow:
|
||
; <H14> 4/24/92 HJR Updated NiagraChkIdle for current state of hardware. Changed
|
||
; PRAM base in NiagraPrimInfo to $46 since slot E is now needed
|
||
; for VSC.
|
||
; <H13> 4/17/92 SWC Added a check to GetExtLevel to see if the charger is connected
|
||
; since the returned battery voltage will be zero if we're running
|
||
; without a battery (causing the system to go to sleep all the
|
||
; time).
|
||
; <H12> 4/13/92 SWC Modified GetExtLevel to actually check for the existance of a
|
||
; battery. Zeroed the MSC default battery warning level values
|
||
; since they'll change depending on what kind of battery is
|
||
; connected. The PMGR will determine what these should be each
|
||
; time a new battery type is installed.
|
||
; <H11> 4/8/92 SWC Fixed a bug in the clamshell switch check.
|
||
; <H10> 3/20/92 SWC Added calls to DockingSleep and DockingWakeup to DBLite's sleep
|
||
; and wakeup tables so everything will be kept up-to-date.
|
||
; <H9> 3/16/92 SWC Modified CPUSpeedMSC to support 16, 20, 25, and 33MHz machines.
|
||
; We're only planning to do 25 and 33, but if marketing wants to
|
||
; do the slower ones, at least the support's done for free.
|
||
; <H8> 3/13/92 SWC Fixed a couple of bugs in CPUSpeedMSC.
|
||
; <H7> 3/11/92 SWC Added an entry to the info tables for the address of the power
|
||
; cycling register. Added a routine entry for a clamshell switch
|
||
; monitoring VBL task. Added an IdleMind routine for DBLite to
|
||
; check if the clamshell has been closed.
|
||
; <H6> 3/6/92 SWC Added a routine to reset the internal SCC's channel B on wakeup
|
||
; since it seems to be getting into a weird state (this may go
|
||
; away later once I figure out what's happening, but it will help
|
||
; for now).
|
||
; <H5> 2/21/92 HJR Added Power cycling to the PrimsRec. Added WakeLvl hysteresis to
|
||
; the PrimInfos.
|
||
; <H4> 2/7/92 SWC Added default hysteresis and low/dead battery warning levels to
|
||
; the primitives info tables.
|
||
; <H3> 2/7/92 SWC Added support for determining battery level so we can handle
|
||
; different hardware implementations. Made the table offsets in
|
||
; PmgrPrimLookup self-relative.
|
||
; <H2> 2/4/92 SWC Added support for sleep and wakeup tables. Fixed a bug in
|
||
; CPUSpeedMSC. Added assembly conditionals (by decoder) just to be
|
||
; thorough. Cleaned up the code here and there. Added padding to
|
||
; make the code fixed-size.
|
||
; <H1> 2/3/92 HJR first checked in
|
||
|
||
BLANKS ON
|
||
STRING ASIS
|
||
|
||
PRINT OFF
|
||
LOAD 'StandardEqu.d'
|
||
INCLUDE 'HardwarePrivateEqu.a'
|
||
INCLUDE 'SoundPrivate.a'
|
||
INCLUDE 'UniversalEqu.a'
|
||
INCLUDE 'PowerPrivEqu.a'
|
||
INCLUDE 'PowerMgrDispatchEqu.a'
|
||
INCLUDE 'MMUEqu.a'
|
||
INCLUDE 'IOPrimitiveEqu.a'
|
||
INCLUDE 'DockingEqu.a'
|
||
INCLUDE 'ShutDown.a'
|
||
INCLUDE 'ROMEqu.a'
|
||
INCLUDE 'Video.a'
|
||
INCLUDE 'Notification.a'
|
||
INCLUDE 'GestaltEqu.a'
|
||
INCLUDE 'Processes.a'
|
||
INCLUDE 'SlotMgrEqu.a'
|
||
INCLUDE 'DepVideoEqu.a'
|
||
INCLUDE 'Palettes.a'
|
||
INCLUDE 'LayerEqu.a'
|
||
INCLUDE 'ENETEqu.a'
|
||
PRINT ON
|
||
|
||
MACHINE MC68030
|
||
MC68881
|
||
|
||
|
||
PowerMgrPrimitives PROC EXPORT
|
||
|
||
IF hasPwrControls THEN
|
||
|
||
IMPORT AbsoluteBattery ; PowerMgr.a
|
||
IMPORT BatWatch ; PowerMgr.a
|
||
IMPORT DockingSleep ; DockingMgr.a
|
||
IMPORT DockingWakeup ; DockingMgr.a
|
||
IMPORT GracefulShutdown ; PowerMgr.a
|
||
IMPORT PMGRrecv ; PowerMgr.a
|
||
IMPORT PMGRsend ; PowerMgr.a
|
||
IMPORT PrivateFeatures ; PowerMgr.a
|
||
IMPORT SetSupervisorMode ; PowerMgr.a
|
||
|
||
EXPORT GetLevel
|
||
|
||
WITH PmgrRec,PowerDispRec,PmgrPramRec
|
||
WITH PmgrPrimitivesRec,PmgrRoutineRec,PrimInfoTbleRec,IdleMindTblRec
|
||
WITH pmCommandRec,nmRec,PmgrPramRec,ProcessInfoRec
|
||
WITH DecoderInfo,DecoderKinds,ProductInfo,VideoInfo
|
||
|
||
|
||
IF hasJAWS THEN
|
||
;••••••••••••••••••••••••••••••••••••••••• JAWS ••••••••••••••••••••••••••••••••••••••••••
|
||
|
||
EXPORT JawsPmgrPrims
|
||
|
||
ALIGN 4
|
||
DC.L PrimsTypeTable ; flags
|
||
DC.L (JawsPmgrPrimsEnd-JawsPmgrPrims) ; size of table
|
||
JawsPmgrPrims ; Table of Primitive Tables
|
||
DC.L JawsRoutines-JawsPmgrPrims ; offset to table of Jaws routines
|
||
DC.L JawsPrimInfo-JawsPmgrPrims ; offset to table decoder-specific constants
|
||
DC.L JawsIdleMindTable-JawsPmgrPrims ; offset to table of Idlemind routines
|
||
DC.L JawsSleepTable-JawsPmgrPrims ; offset to table of sleep routines
|
||
DC.L JawsWakeTable-JawsPmgrPrims ; offset to table of wakeup routines
|
||
DC.L 0 ; no PMgrOp exception table
|
||
DC.L ModemTable-JawsPmgrPrims ; offset to table modem routines <H31>
|
||
DC.L PwrDispatchVects-JawsPmgrPrims ; offset to power dispatch table
|
||
DC.L 0 ; no PMgr hook table
|
||
DC.L CommsPowerTable-JawsPmgrPrims ; offset to table of comms power routines <K12>
|
||
DC.L PMgrOpTbl-JawsPmgrPrims ; offset to routine for PmgrOp
|
||
DC.L 0 ; offset to backlight tables
|
||
JawsPmgrPrimsEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (JawsRoutinesEnd-JawsRoutines) ; size of table
|
||
JawsRoutines ; machine-specific routines
|
||
DC.L PowerCycle030-JawsRoutines ; offset to routine for power cycling <H5>
|
||
DC.L Restore030-JawsRoutines ; offset to routine for power cycling restore <H5>
|
||
DC.L BatWatch-JawsRoutines ; offset to VBL task to check the battery level <H19>
|
||
DC.L GetLevel-JawsRoutines ; offset to routine for determining battery level
|
||
DC.L LeadScaledBatteryInfo-JawsRoutines ; offset to routine to return scaled battery level<H15>
|
||
DC.L 0 ; no enviromental int
|
||
DC.L 0 ; no clamshell
|
||
DC.L CPUSpeedJaws-JawsRoutines ; offset to routine for determining CPU speed
|
||
DC.L SndWatch-JawsRoutines ; offset to VBL task to check for sound usage <H19>
|
||
DC.L RedrawScrn-JawsRoutines ; offset to routine for refreshing the screen <H17>
|
||
DC.L LeadAbsoluteBatteryVoltage-JawsRoutines; routine to return absolute battery level<H54>
|
||
DC.L 0 ; no routine to return info about battery times
|
||
DC.L 0 ; dynamic CPU speed change is not supported <H56>
|
||
JawsRoutinesEnd
|
||
|
||
DC.L PrimsTypeInfo ; flags
|
||
DC.L (JawsPrimInfoEnd-JawsPrimInfo) ; size of table
|
||
JawsPrimInfo ; machine-specific constants:
|
||
DC.B $70 ; PRAM base address
|
||
DC.B DefHysteresis ; default hysteresis
|
||
DC.B PMGRWARNLEVEL-STDOFFSET ; default low battery warning level <H5>
|
||
DC.B PMGRCUTOFF-STDOFFSET ; default dead battery warning level <H5>
|
||
DC.B PGMRWAKELEVEL-STDOFFSET ; hysteresis setting for pmgr wake level <H5>
|
||
DC.B (1-1) ; display shorted battery at second interrupt <H33><H7>
|
||
DC.B 0 ; no external video correction needed <H7><H33>
|
||
DC.B 0 ; no charger features
|
||
DC.L $50FA0000 ; address of power cycling register <H7>
|
||
DC.L 0 |\ ; bitmap of public Power Manager features <H52>
|
||
(0<<hasWakeupTimer) |\
|
||
(1<<hasSharedModemPort) |\
|
||
(1<<hasProcessorCycling) |\
|
||
(0<<mustProcessorCycle) |\
|
||
(1<<hasReducedSpeed) |\
|
||
(0<<dynamicSpeedChange) |\
|
||
(0<<hasSCSIDiskMode)
|
||
DC.L 0 |\ ; bitmap of private Power Manager features <H53>
|
||
(0<<hasExtdBattInfo) |\
|
||
(0<<hasBatteryID) |\
|
||
(0<<canSwitchPower)
|
||
DC.W 1 ; number of batteries
|
||
DC.B 0 ; Power manager has a parallel interface
|
||
DC.B 0 ; padding for now
|
||
DC.L 0 ; no extended charge time
|
||
DC.B 0 ; value for power cycling register <K22>
|
||
DC.B 0 ; value for sleep register <K22>
|
||
DC.B 0 ; padding for now
|
||
DC.B 0 ; padding for now
|
||
JawsPrimInfoEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (JawsIdleMindTableEnd-JawsIdleMindTable); size of table
|
||
JawsIdleMindTable ; machine specific IdleMind Routines
|
||
DC.L CheckCountDownTimer-JawsIdleMindTable ; offset to count down timer
|
||
DC.L RunIdleRoutinesProc-JawsIdleMindTable ; offset to run idle procs
|
||
DC.L ChkSleepTimeOut-JawsIdleMindTable ; offset to sleep time out
|
||
DC.L ChkIdle-JawsIdleMindTable ; offset to check idle
|
||
DC.L CalcProgressive-JawsIdleMindTable ; offset to calc progressive
|
||
DC.L GoPowerCycle-JawsIdleMindTable ; offset to go power cycle
|
||
JawsIdleMindTableEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (JawsSleepTableEnd-JawsSleepTable) ; size of table
|
||
JawsSleepTable ; list of routines to execute when going to sleep:
|
||
DC.L SleepHD-JawsSleepTable ; sleep the hard drive if currently running <K22>
|
||
DC.L SaveVIA1-JawsSleepTable ; save VIA1 registers
|
||
DC.L SaveASCBatman-JawsSleepTable ; save ASC/Batman registers
|
||
DC.L SaveFPU-JawsSleepTable ; save FPU registers
|
||
DC.L SaveVIA2-JawsSleepTable ; save VIA2 registers
|
||
DC.L SendSleep-JawsSleepTable ; send a sleep command
|
||
DC.L SaveSlp030-JawsSleepTable ; save MMU registers
|
||
DC.L SaveSleepInfo-JawsSleepTable ; save sleep info in video RAM
|
||
DC.L 0 ; (end of table)
|
||
JawsSleepTableEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (JawsWakeTableEnd-JawsWakeTable) ; size of table
|
||
JawsWakeTable ; list of routines to execute when waking up:
|
||
DC.L RestoreSlp030-JawsWakeTable ; restore MMU, SPs, cache registers
|
||
DC.L RestoreVIA2-JawsWakeTable ; restore VIA2 registers
|
||
DC.L RestoreFPU-JawsWakeTable ; restore FPU registers
|
||
DC.L RestoreASCBatman-JawsWakeTable ; restore ASC and Batman registers
|
||
DC.L RestoreVIA1-JawsWakeTable ; restore VIA1 registers
|
||
DC.L WakeClrInts-JawsWakeTable ; clear any pending PmgrInterrupts
|
||
DC.L WakeSoundSetJaws-JawsWakeTable ; set state for sound out of sleep
|
||
DC.L 0 ; (end of table)
|
||
JawsWakeTableEnd
|
||
|
||
|
||
ALIGN 4
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: CPUSpeedJaws
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: D0 - [maximum CPU speed][current CPU speed]
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: returns the maximum and current (econo-mode or full) CPU speeds for
|
||
; JAWS-based machines
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
CPUSpeedJaws
|
||
MOVEA.L UnivInfoPtr,A0 ; point to the ProductInfo table,
|
||
ADDA.L DecoderInfoPtr(A0),A0 ; then to the DecoderInfo table,
|
||
MOVEA.L JawsAddr(A0),A0 ; then to the JAWS base address,
|
||
ADDA.L #JAWSGetCPUClock,A0 ; and finally to the CPU clock register
|
||
BTST #0,(A0) ; are we a 25MHz or 16MHz machine?
|
||
ADDA.L #JAWSEconoMode-JAWSGetCPUClock,A0 ; (point to the econo-mode register)
|
||
BEQ.S @16MHz ; -> 16MHz
|
||
MOVE.L #(CPUSpeed25MHz<<16)|\ ; assume we're running full-speed at 25MHz
|
||
(CPUSpeed25MHz<<0),D0
|
||
BTST #1,(A0) ; are we in econo-mode?
|
||
BEQ.S @NoEcono25 ; -> nope, we're done
|
||
MOVE.W #CPUSpeed16MHz,D0 ; yes, we're currently running at 16MHz
|
||
@NoEcono25 RTS
|
||
|
||
@16MHz MOVE.L #(CPUSpeed16MHz<<16)|\ ; assume we're running full-speed at 16MHz
|
||
(CPUSpeed16MHz<<0),D0
|
||
BTST #1,(A0) ; are we in econo-mode?
|
||
BEQ.S @NoEcono16 ; -> nope, we're done
|
||
MOVE.W #CPUSpeed8MHz,D0 ; yes, we're currently running at 8MHz
|
||
@NoEcono16 RTS
|
||
|
||
ENDIF
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Wakeup routine for setting sound (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
WakeSoundSetNiagra
|
||
WakeSoundSetJaws
|
||
MOVEM.L A0-A1,-(SP) ; save special registers
|
||
SUBQ.W #4,SP ; Create stack frame
|
||
MOVE.L SP,A0
|
||
MOVE.B #sndClrLtch,(A0) ; Clear the Sound latch
|
||
MOVEQ #1,D1 ; One long to send
|
||
MOVE.W #SoundSet,D0 ; PMGR command, Set Sound Control
|
||
MOVE.L A2,-(SP)
|
||
BigJSR PMGRsend,A2 ; have the PMGR clear the sound latch
|
||
MOVE.L (SP)+,A2
|
||
ADDQ.W #4,SP ; Remove stack frame
|
||
|
||
With ExpandmemRec,SoundIOHeader
|
||
MOVEA.L ([Expandmem],\
|
||
emSndPrimitives),A0 ; Get pointer to Expandmem
|
||
MOVE.B DFAClast(A0),D0 ; get last byte sent to DFAC
|
||
jsrTBL sndDFACSend,A0 ; send byte to DFAC
|
||
Endwith
|
||
MOVEM.L (SP)+,A0-A1 ; restore special registers
|
||
JMP (A1) ; go home
|
||
|
||
IF hasMSC THEN
|
||
;••••••••••••••••••••••••••••••••••••••••• MBT •••••••••••••••••••••••••••••••••••••••••••
|
||
|
||
EXPORT MBTPmgrPrims
|
||
|
||
ALIGN 4
|
||
DC.L PrimsTypeTable ; flags
|
||
DC.L (MBTPmgrPrimsEnd-MBTPmgrPrims) ; size of table
|
||
MBTPmgrPrims ; Table of Primitives tables
|
||
DC.L MBTRoutines-MBTPmgrPrims ; offset to table of MSC routines
|
||
DC.L MBTPrimInfo-MBTPmgrPrims ; offset to decoder-specific constants
|
||
DC.L MBTIdleMindTable-MBTPmgrPrims ; offset to table of Idlemind routines <H7>
|
||
DC.L MBTSleepTable-MBTPmgrPrims ; offset to table of sleep routines
|
||
DC.L MBTWakeTable-MBTPmgrPrims ; offset to table of wakeup routines
|
||
DC.L MBTModemTable-MBTPmgrPrims ; offset to table of modem routines <H31>
|
||
DC.L MBTPMgrOpExceptions-MBTPmgrPrims ; offset to PMgrOp exception table
|
||
DC.L PwrDispatchVects-MBTPmgrPrims ; offset to table of PwrDispatchVects
|
||
DC.L PMgrHookVects-MBTPmgrPrims ; offset to table of PmgrMgr Hooks
|
||
DC.L 0 ; no comms power routines <K12>
|
||
DC.L PMgrOpTbl-MBTPmgrPrims ; offset to routine for PmgrOp
|
||
DC.L 0 ; offset to backlight tables
|
||
MBTPmgrPrimsEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (MBTRoutinesEnd-MBTRoutines) ; size of table
|
||
MBTRoutines ; machine-specific routines
|
||
DC.L PowerCycle040-MBTRoutines ; offset to routine for power cycling <H5>
|
||
DC.L Restore040-MBTRoutines ; offset to routine for power cycling restore <H5>
|
||
DC.L BatWatch-MBTRoutines ; offset to VBL task to check the battery level <H19>
|
||
DC.L GetExtLevel-MBTRoutines ; offset to routine for determining battery level
|
||
DC.L MultiScaledBatteryInfo-MBTRoutines ; offset to routine to return scaled battery level <H15>
|
||
DC.L 0 ; no environment interrupts
|
||
DC.L ClamshellVBL-MBTRoutines ; offset to VBL task to check for clamshell closed <H7>
|
||
DC.L CPUSpeedMSC-MBTRoutines ; offset to routine for determining CPU speed
|
||
DC.L SndWatchMSC-MBTRoutines ; offset to VBL task to check for sound usage <H19>
|
||
DC.L RedrawScrn-MBTRoutines ; offset to routine for refreshing the screen <H18>
|
||
DC.L PGEAbsoluteBatteryVoltage-MBTRoutines ; routine to return absolute battery level <H54>
|
||
DC.L 0 ; no routine to return info about battery times
|
||
DC.L 0 ; dynamic CPU speed change is not supported
|
||
MBTRoutinesEnd
|
||
|
||
DC.L PrimsTypeInfo ; flags
|
||
DC.L (MBTPrimInfoEnd-MBTPrimInfo) ; size of table
|
||
MBTPrimInfo ; machine-specific constants:
|
||
DC.B $46 ; PRAM base address
|
||
DC.B DefHysteresis ; default hysteresis
|
||
DC.B 0 ; default low battery warning level (none) <H12>
|
||
DC.B 0 ; default dead battery warning level (none) <H12>
|
||
DC.B 0 ; hysteresis setting for wake level (none) <H12>
|
||
DC.B 0 ; shorted battery at first interrupt (none) <H33> <H7>
|
||
DC.B 0 ; no external video correction needed <H7>
|
||
DC.B 0 |\ ; bitmap of charger attributes
|
||
(1<<hasSleepLED) |\
|
||
(1<<hasForcedDischarge) |\
|
||
(0<<hasDBCharger) |\
|
||
(1<<hasEscherCharger)
|
||
DC.L $50FA0000 ; address of power cycling register <H7>
|
||
DC.L 0 |\ ; bitmap of Power Manager features <H52>
|
||
(1<<hasWakeupTimer) |\
|
||
(0<<hasSharedModemPort) |\
|
||
(1<<hasProcessorCycling) |\
|
||
(0<<mustProcessorCycle) |\
|
||
(0<<hasReducedSpeed) |\
|
||
(0<<dynamicSpeedChange) |\
|
||
(1<<hasSCSIDiskMode)
|
||
DC.L 0 |\ ; bitmap of private Power Manager features <H53>
|
||
(1<<hasExtdBattInfo) |\
|
||
(1<<hasBatteryID) |\
|
||
(0<<canSwitchPower)
|
||
DC.W 1 ; number of batteries
|
||
DC.B 2 ; Power Manager Serial Interface <H7>
|
||
DC.B 0 ; padding for now
|
||
DC.L 0 ; no extended charging
|
||
DC.B $5A ; value for power cycling register <K22>
|
||
DC.B 0 ; value for sleep register <K22>
|
||
DC.B 0 ; padding for now
|
||
DC.B 0 ; padding for now
|
||
MBTPrimInfoEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (MBTIdleMindTableEnd-MBTIdleMindTable); size of table
|
||
MBTIdleMindTable ; machine specific IdleMind Routines
|
||
DC.L CheckCountDownTimer-MBTIdleMindTable; offset to count down timer
|
||
DC.L CheckClamshell-MBTIdleMindTable ; offset to clam shell <H20>
|
||
DC.L ChkSleepTimeOut-MBTIdleMindTable ; offset to sleep time out
|
||
DC.L ChkIdle-MBTIdleMindTable ; offset to check idle
|
||
DC.L CalcProgressive-MBTIdleMindTable ; offset to calc progressive
|
||
DC.L GoPowerCycle-MBTIdleMindTable ; offset to go power cycle
|
||
MBTIdleMindTableEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (MBTSleepTableEnd-MBTSleepTable) ; size of table
|
||
MBTSleepTable ; list of routines to execute when going to sleep:
|
||
DC.L SleepHD-MBTSleepTable ; sleep the hard drive if currently running <K22>
|
||
DC.L DockingSleep-MBTSleepTable ; save state of currently connected bar <H10>
|
||
DC.L SaveVIA1-MBTSleepTable ; save VIA1 registers
|
||
DC.L SaveASCBatman-MBTSleepTable ; save ASC/Batman registers
|
||
DC.L SaveFPU-MBTSleepTable ; save FPU registers
|
||
DC.L SaveLCD-MBTSleepTable ; save GSC (built-in LCD video) registers
|
||
DC.L SaveMSC-MBTSleepTable ; save MSC registers
|
||
DC.L SendSleepLP-MBTSleepTable ; send a sleep command <H42>
|
||
DC.L SaveSlp040-MBTSleepTable ; save MMU registers
|
||
DC.L SaveSleepInfo-MBTSleepTable ; save sleep info in Power Manager globals
|
||
DC.L MSCKillPower-MBTSleepTable ; have MSC pull the plug as well
|
||
DC.L 0 ; (end of table)
|
||
MBTSleepTableEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (MBTWakeTableEnd-MBTWakeTable) ; size of table
|
||
MBTWakeTable ; list of routines to execute when waking up:
|
||
DC.L RestoreSlp040-MBTWakeTable ; restore MMU, SPs, cache registers
|
||
DC.L RestoreMSC-MBTWakeTable ; restore volatile MSC registers
|
||
DC.L RestoreLCD-MBTWakeTable ; restore GSC (built-in LCD video) registers
|
||
DC.L RestoreFPU-MBTWakeTable ; restore FPU registers
|
||
DC.L RestoreASCBatman-MBTWakeTable ; restore ASC and Batman registers
|
||
DC.L RestoreVIA1-MBTWakeTable ; restore VIA1 registers
|
||
DC.L MSCInitSCC-MBTWakeTable ; reset channel B on internal SCC <H6>
|
||
DC.L DockingWakeup-MBTWakeTable ; restore state of currently connected bar <H10>
|
||
DC.L WakeClrInts-MBTWakeTable ; clear any pending PmgrInterrupts
|
||
DC.L WakeSoundSet-MBTWakeTable ; set state for sound out of sleep
|
||
DC.L 0 ; (end of table)
|
||
MBTWakeTableEnd
|
||
|
||
DC.L PrimsTypePMgrEx ; flags
|
||
DC.L (MBTPMgrOpExceptionsEnd-MBTPMgrOpExceptions) ; size of table
|
||
MBTPMgrOpExceptions ; PMgrOp exceptions:
|
||
DC.B $FF,powerCntl ; $10 - power control
|
||
DC.L MSCPowerControl-*
|
||
DC.B $FF,powerRead ; $18 - power status
|
||
DC.L MSCPowerStatus-*
|
||
DC.B $FF,$1F ; $1F - fake power status (for MSC/PG&E)
|
||
DC.L MSCFakePowerStatus-*
|
||
DC.B $FE,batteryRead ; $68, $69 - read battery status
|
||
DC.L MSCReadBattery-*
|
||
DC.B $FF,soundSet ; $90 - clear sound latch, turn sound power on/off
|
||
DC.L MSCSetSound-*
|
||
DC.B $FF,soundRead ; $98 - return sound latch, sound power status
|
||
DC.L MSCReadSound-*
|
||
DC.W 0 ; (end of table)
|
||
MBTPMgrOpExceptionsEnd
|
||
|
||
DC.L PrimsTypePtr ; flags <K10>
|
||
DC.L (MBTModemTableEnd-MBTModemTable) ; size of table
|
||
MBTModemTable
|
||
DC.L 0 ; offset to routine to turn on modem
|
||
DC.L 0 ; offset to routine to turn off modem
|
||
DC.L DBLiteModemType-MBTModemTable ; offset to routine to get modem type
|
||
MBTModemTableEnd
|
||
|
||
ALIGN 4
|
||
|
||
;••••••••••••••••••••••••••••••••••••••••• MSC2 •••••••••••••••••••••••••••••••••••••••••••
|
||
|
||
EXPORT MSC2PmgrPrims
|
||
|
||
ALIGN 4
|
||
DC.L PrimsTypeTable ; flags
|
||
DC.L (MSC2PmgrPrimsEnd-MSC2PmgrPrims) ; size of table
|
||
MSC2PmgrPrims ; Table of Primitives tables
|
||
DC.L MSC2Routines-MSC2PmgrPrims ; offset to table of MSC routines
|
||
DC.L MSC2PrimInfo-MSC2PmgrPrims ; offset to decoder-specific constants
|
||
DC.L MSC2IdleMindTable-MSC2PmgrPrims ; offset to table of Idlemind routines <H7>
|
||
DC.L MSC2SleepTable-MSC2PmgrPrims ; offset to table of sleep routines
|
||
DC.L MSC2WakeTable-MSC2PmgrPrims ; offset to table of wakeup routines
|
||
DC.L MSC2ModemTable-MSC2PmgrPrims ; offset to table of modem routines <H31>
|
||
DC.L MSC2PMgrOpExceptions-MSC2PmgrPrims ; offset to PMgrOp exception table
|
||
DC.L PwrDispatchVects-MSC2PmgrPrims ; offset to table of PwrDispatchVects
|
||
DC.L PMgrHookVects-MSC2PmgrPrims ; offset to table of PmgrMgr Hooks
|
||
DC.L 0 ; no comms power routines <K12>
|
||
DC.L PMgrOpTbl-MSC2PmgrPrims ; offset to routine for PmgrOp
|
||
DC.L 0 ; offset to backlight tables
|
||
MSC2PmgrPrimsEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (MSC2RoutinesEnd-MSC2Routines) ; size of table
|
||
MSC2Routines ; machine-specific routines
|
||
DC.L PowerCycle040-MSC2Routines ; offset to routine for power cycling <H5>
|
||
DC.L Restore040-MSC2Routines ; offset to routine for power cycling restore <H5>
|
||
DC.L BatWatch-MSC2Routines ; offset to VBL task to check the battery level <H19>
|
||
DC.L GetExtLevel-MSC2Routines ; offset to routine for determining battery level
|
||
DC.L MultiScaledBatteryInfo-MSC2Routines ; offset to routine to return scaled battery level <H15>
|
||
DC.L 0 ; no environment interrupts
|
||
DC.L ClamshellVBL-MSC2Routines ; offset to VBL task to check for clamshell closed <H7>
|
||
DC.L CPUSpeedMSC-MSC2Routines ; offset to routine for determining CPU speed
|
||
DC.L SndWatchMSC-MSC2Routines ; offset to VBL task to check for sound usage <H19>
|
||
DC.L RedrawScrn-MSC2Routines ; offset to routine for refreshing the screen <H18>
|
||
DC.L PGEAbsoluteBatteryVoltage-MSC2Routines ; routine to return absolute battery level <H54>
|
||
DC.L 0 ; no routine to return info about battery times
|
||
DC.L 0 ; dynamic CPU speed change is not supported
|
||
MSC2RoutinesEnd
|
||
|
||
DC.L PrimsTypeInfo ; flags
|
||
DC.L (MSC2PrimInfoEnd-MSC2PrimInfo) ; size of table
|
||
MSC2PrimInfo ; machine-specific constants:
|
||
DC.B $46 ; PRAM base address
|
||
DC.B DefHysteresis ; default hysteresis
|
||
DC.B 0 ; default low battery warning level (none) <H12>
|
||
DC.B 0 ; default dead battery warning level (none) <H12>
|
||
DC.B 0 ; hysteresis setting for wake level (none) <H12>
|
||
DC.B 0 ; shorted battery at first interrupt (none) <H33> <H7>
|
||
DC.B 0 ; no external video correction needed <H7>
|
||
DC.B 0 |\ ; bitmap of charger attributes
|
||
(1<<hasSleepLED) |\
|
||
(1<<hasForcedDischarge) |\
|
||
(0<<hasDBCharger) |\
|
||
(1<<hasEscherCharger)
|
||
DC.L $50FA0000 ; address of power cycling register <H7>
|
||
DC.L 0 |\ ; bitmap of Power Manager features <H52>
|
||
(1<<hasWakeupTimer) |\
|
||
(0<<hasSharedModemPort) |\
|
||
(1<<hasProcessorCycling) |\
|
||
(0<<mustProcessorCycle) |\
|
||
(0<<hasReducedSpeed) |\
|
||
(0<<dynamicSpeedChange) |\
|
||
(1<<hasSCSIDiskMode)
|
||
DC.L 0 |\ ; bitmap of private Power Manager features <H53>
|
||
(1<<hasExtdBattInfo) |\
|
||
(1<<hasBatteryID) |\
|
||
(0<<canSwitchPower)
|
||
DC.W 1 ; number of batteries
|
||
DC.B 2 ; Power Manager Serial Interface <H7>
|
||
DC.B 0 ; padding for now
|
||
DC.L 0 ; no extended charging
|
||
DC.B $5A ; value for power cycling register <K22>
|
||
DC.B 0 ; value for sleep register <K22>
|
||
DC.B 0 ; padding for now
|
||
DC.B 0 ; padding for now
|
||
MSC2PrimInfoEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (MSC2IdleMindTableEnd-MSC2IdleMindTable); size of table
|
||
MSC2IdleMindTable ; machine specific IdleMind Routines
|
||
DC.L CheckCountDownTimer-MSC2IdleMindTable; offset to count down timer
|
||
DC.L CheckClamshell-MSC2IdleMindTable ; offset to clam shell <H20>
|
||
DC.L ChkSleepTimeOut-MSC2IdleMindTable ; offset to sleep time out
|
||
DC.L ChkIdle-MSC2IdleMindTable ; offset to check idle
|
||
DC.L CalcProgressive-MSC2IdleMindTable ; offset to calc progressive
|
||
DC.L GoPowerCycle-MSC2IdleMindTable ; offset to go power cycle
|
||
MSC2IdleMindTableEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (MSC2SleepTableEnd-MSC2SleepTable) ; size of table
|
||
MSC2SleepTable ; list of routines to execute when going to sleep:
|
||
DC.L SleepHD-MSC2SleepTable ; sleep the hard drive if currently running <K22>
|
||
DC.L DockingSleep-MSC2SleepTable ; save state of currently connected bar <H10>
|
||
DC.L SaveVIA1-MSC2SleepTable ; save VIA1 registers
|
||
DC.L SaveASCBatman-MSC2SleepTable ; save ASC/Batman registers
|
||
DC.L SaveFPU-MSC2SleepTable ; save FPU registers
|
||
DC.L SaveLCD-MSC2SleepTable ; save GSC (built-in LCD video) registers
|
||
DC.L SaveMSC-MSC2SleepTable ; save MSC registers
|
||
DC.L SendSleepLP-MSC2SleepTable ; send a sleep command <H42>
|
||
DC.L SaveSlp040-MSC2SleepTable ; save MMU registers
|
||
DC.L SaveSleepInfo-MSC2SleepTable ; save sleep info in Power Manager globals
|
||
DC.L MSCKillPower-MSC2SleepTable ; have MSC pull the plug as well
|
||
DC.L 0 ; (end of table)
|
||
MSC2SleepTableEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (MSC2WakeTableEnd-MSC2WakeTable) ; size of table
|
||
MSC2WakeTable ; list of routines to execute when waking up:
|
||
DC.L RestoreSlp040-MSC2WakeTable ; restore MMU, SPs, cache registers
|
||
DC.L RestoreMSC-MSC2WakeTable ; restore volatile MSC registers
|
||
DC.L RestoreLCD-MSC2WakeTable ; restore GSC (built-in LCD video) registers
|
||
DC.L RestoreFPU-MSC2WakeTable ; restore FPU registers
|
||
DC.L RestoreASCBatman-MSC2WakeTable ; restore ASC and Batman registers
|
||
DC.L RestoreVIA1-MSC2WakeTable ; restore VIA1 registers
|
||
DC.L MSCInitSCC-MSC2WakeTable ; reset channel B on internal SCC <H6>
|
||
DC.L DockingWakeup-MSC2WakeTable ; restore state of currently connected bar <H10>
|
||
DC.L WakeClrInts-MSC2WakeTable ; clear any pending PmgrInterrupts
|
||
DC.L WakeSoundSet-MSC2WakeTable ; set state for sound out of sleep
|
||
DC.L 0 ; (end of table)
|
||
MSC2WakeTableEnd
|
||
|
||
DC.L PrimsTypePMgrEx ; flags
|
||
DC.L (MSC2PMgrOpExceptionsEnd-MSC2PMgrOpExceptions) ; size of table
|
||
MSC2PMgrOpExceptions ; PMgrOp exceptions:
|
||
DC.B $FF,powerCntl ; $10 - power control
|
||
DC.L MSCPowerControl-*
|
||
DC.B $FF,powerRead ; $18 - power status
|
||
DC.L MSCPowerStatus-*
|
||
DC.B $FF,$1F ; $1F - fake power status (for MSC/PG&E)
|
||
DC.L MSCFakePowerStatus-*
|
||
DC.B $FE,batteryRead ; $68, $69 - read battery status
|
||
DC.L MSCReadBattery-*
|
||
DC.B $FF,soundSet ; $90 - clear sound latch, turn sound power on/off
|
||
DC.L MSCSetSound-*
|
||
DC.B $FF,soundRead ; $98 - return sound latch, sound power status
|
||
DC.L MSCReadSound-*
|
||
DC.W 0 ; (end of table)
|
||
MSC2PMgrOpExceptionsEnd
|
||
|
||
DC.L PrimsTypePtr ; flags <K10>
|
||
DC.L (MSC2ModemTableEnd-MSC2ModemTable) ; size of table
|
||
MSC2ModemTable
|
||
DC.L 0 ; offset to routine to turn on modem
|
||
DC.L 0 ; offset to routine to turn off modem
|
||
DC.L DBLiteModemType-MSC2ModemTable ; offset to routine to get modem type
|
||
MSC2ModemTableEnd
|
||
|
||
ALIGN 4
|
||
|
||
|
||
;••••••••••••••••••••••••••••••••••••••••• MSC •••••••••••••••••••••••••••••••••••••••••••
|
||
|
||
EXPORT MSCPmgrPrims
|
||
|
||
ALIGN 4
|
||
DC.L PrimsTypeTable ; flags
|
||
DC.L (MSCPmgrPrimsEnd-MSCPmgrPrims) ; size of table
|
||
MSCPmgrPrims ; Table of Primitives tables
|
||
DC.L MSCRoutines-MSCPmgrPrims ; offset to table of MSC routines
|
||
DC.L MSCPrimInfo-MSCPmgrPrims ; offset to decoder-specific constants
|
||
DC.L MSCIdleMindTable-MSCPmgrPrims ; offset to table of Idlemind routines <H7>
|
||
DC.L MSCSleepTable-MSCPmgrPrims ; offset to table of sleep routines
|
||
DC.L MSCWakeTable-MSCPmgrPrims ; offset to table of wakeup routines
|
||
DC.L MSCModemTable-MSCPmgrPrims ; offset to table of modem routines <H31>
|
||
DC.L MSCPMgrOpExceptions-MSCPmgrPrims ; offset to PMgrOp exception table
|
||
DC.L PwrDispatchVects-MSCPmgrPrims ; offset to table of PwrDispatchVects
|
||
DC.L PMgrHookVects-MSCPmgrPrims ; offset to table of PmgrMgr Hooks
|
||
DC.L 0 ; no comms power routines <K12>
|
||
DC.L PMgrOpTbl-MSCPmgrPrims ; offset to routine for PmgrOp
|
||
DC.L 0 ; offset to backlight tables
|
||
MSCPmgrPrimsEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (MSCRoutinesEnd-MSCRoutines) ; size of table
|
||
MSCRoutines ; machine-specific routines
|
||
DC.L PowerCycle030-MSCRoutines ; offset to routine for power cycling <H5>
|
||
DC.L Restore030-MSCRoutines ; offset to routine for power cycling restore <H5>
|
||
DC.L BatWatch-MSCRoutines ; offset to VBL task to check the battery level <H19>
|
||
DC.L GetExtLevel-MSCRoutines ; offset to routine for determining battery level
|
||
DC.L MultiScaledBatteryInfo-MSCRoutines ; offset to routine to return scaled battery level <H15>
|
||
DC.L 0 ; no environment interrupts
|
||
DC.L ClamshellVBL-MSCRoutines ; offset to VBL task to check for clamshell closed <H7>
|
||
DC.L CPUSpeedMSC-MSCRoutines ; offset to routine for determining CPU speed
|
||
DC.L SndWatchMSC-MSCRoutines ; offset to VBL task to check for sound usage <H19>
|
||
DC.L RedrawScrn-MSCRoutines ; offset to routine for refreshing the screen <H18>
|
||
DC.L PGEAbsoluteBatteryVoltage-MSCPmgrPrims ; routine to return absolute battery level <H54>
|
||
DC.L 0 ; no routine to return info about battery times
|
||
DC.L ChangeCPUSpeedMSC-MSCPmgrPrims ; routine to do a dynamic CPU speed change <H56>
|
||
MSCRoutinesEnd
|
||
|
||
DC.L PrimsTypeInfo ; flags
|
||
DC.L (MSCPrimInfoEnd-MSCPrimInfo) ; size of table
|
||
MSCPrimInfo ; machine-specific constants:
|
||
DC.B $46 ; PRAM base address
|
||
DC.B DefHysteresis ; default hysteresis
|
||
DC.B 0 ; default low battery warning level (none) <H12>
|
||
DC.B 0 ; default dead battery warning level (none) <H12>
|
||
DC.B 0 ; hysteresis setting for wake level (none) <H12>
|
||
DC.B 0 ; shorted battery at first interrupt (none) <H33> <H7>
|
||
DC.B 0 ; no external video correction needed <H7>
|
||
DC.B 0 ; no charger features
|
||
DC.L $50FA0000 ; address of power cycling register <H7>
|
||
DC.L 0 |\ ; bitmap of Power Manager features <H52>
|
||
(1<<hasWakeupTimer) |\
|
||
(0<<hasSharedModemPort) |\
|
||
(1<<hasProcessorCycling) |\
|
||
(0<<mustProcessorCycle) |\
|
||
(1<<hasReducedSpeed) |\
|
||
(1<<dynamicSpeedChange) |\
|
||
(1<<hasSCSIDiskMode)
|
||
DC.L 0 |\ ; bitmap of private Power Manager features <H53>
|
||
(1<<hasExtdBattInfo) |\
|
||
(1<<hasBatteryID) |\
|
||
(0<<canSwitchPower)
|
||
DC.W 1 ; number of batteries
|
||
DC.B 2 ; Power Manager Serial Interface <H7>
|
||
DC.B 0 ; padding for now
|
||
DC.L 0 ; no extended charging
|
||
DC.B $5A ; value for power cycling register <K22>
|
||
DC.B 0 ; value for sleep register <K22>
|
||
DC.B 0 ; padding for now
|
||
DC.B 0 ; padding for now
|
||
MSCPrimInfoEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (MSCIdleMindTableEnd-MSCIdleMindTable); size of table
|
||
MSCIdleMindTable ; machine specific IdleMind Routines
|
||
DC.L CheckCountDownTimer-MSCIdleMindTable; offset to count down timer
|
||
DC.L CheckClamshell-MSCIdleMindTable ; offset to clam shell <H20>
|
||
DC.L ChkSleepTimeOut-MSCIdleMindTable ; offset to sleep time out
|
||
DC.L ChkIdle-MSCIdleMindTable ; offset to check idle
|
||
DC.L CalcProgressive-MSCIdleMindTable ; offset to calc progressive
|
||
DC.L GoPowerCycle-MSCIdleMindTable ; offset to go power cycle
|
||
MSCIdleMindTableEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (MSCSleepTableEnd-MSCSleepTable) ; size of table
|
||
MSCSleepTable ; list of routines to execute when going to sleep:
|
||
DC.L SleepHD-MSCSleepTable ; sleep the hard drive if currently running
|
||
DC.L DockingSleep-MSCSleepTable ; save state of currently connected bar <H10>
|
||
DC.L SaveVIA1-MSCSleepTable ; save VIA1 registers
|
||
DC.L SaveASCBatman-MSCSleepTable ; save ASC/Batman registers
|
||
DC.L SaveFPU-MSCSleepTable ; save FPU registers
|
||
DC.L SaveLCD-MSCSleepTable ; save GSC (built-in LCD video) registers
|
||
DC.L SaveMSC-MSCSleepTable ; save MSC registers
|
||
DC.L SendSleepLP-MSCSleepTable ; send a sleep command <H42>
|
||
DC.L SaveSlp030-MSCSleepTable ; save MMU registers
|
||
DC.L SaveSleepInfo-MSCSleepTable ; save sleep info in Power Manager globals
|
||
DC.L MSCKillPower-MSCSleepTable ; have MSC pull the plug as well
|
||
DC.L 0 ; (end of table)
|
||
MSCSleepTableEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (MSCWakeTableEnd-MSCWakeTable) ; size of table
|
||
MSCWakeTable ; list of routines to execute when waking up:
|
||
DC.L RestoreSlp030-MSCWakeTable ; restore MMU, SPs, cache registers
|
||
DC.L RestoreMSC-MSCWakeTable ; restore volatile MSC registers
|
||
DC.L RestoreLCD-MSCWakeTable ; restore GSC (built-in LCD video) registers
|
||
DC.L RestoreFPU-MSCWakeTable ; restore FPU registers
|
||
DC.L RestoreASCBatman-MSCWakeTable ; restore ASC and Batman registers
|
||
DC.L RestoreVIA1-MSCWakeTable ; restore VIA1 registers
|
||
DC.L MSCInitSCC-MSCWakeTable ; reset channel B on internal SCC <H6>
|
||
DC.L DockingWakeup-MSCWakeTable ; restore state of currently connected bar <H10>
|
||
DC.L WakeClrInts-MSCWakeTable ; clear any pending PmgrInterrupts
|
||
DC.L WakeSoundSet-MSCWakeTable ; set state for sound out of sleep
|
||
DC.L 0 ; (end of table)
|
||
MSCWakeTableEnd
|
||
|
||
DC.L PrimsTypePMgrEx ; flags
|
||
DC.L (MSCPMgrOpExceptionsEnd-MSCPMgrOpExceptions) ; size of table
|
||
MSCPMgrOpExceptions ; PMgrOp exceptions:
|
||
DC.B $FF,powerCntl ; $10 - power control
|
||
DC.L MSCPowerControl-*
|
||
DC.B $FF,powerRead ; $18 - power status
|
||
DC.L MSCPowerStatus-*
|
||
DC.B $FF,$1F ; $1F - fake power status (for MSC/PG&E)
|
||
DC.L MSCFakePowerStatus-*
|
||
DC.B $FE,batteryRead ; $68, $69 - read battery status
|
||
DC.L MSCReadBattery-*
|
||
DC.B $FF,soundSet ; $90 - clear sound latch, turn sound power on/off
|
||
DC.L MSCSetSound-*
|
||
DC.B $FF,soundRead ; $98 - return sound latch, sound power status
|
||
DC.L MSCReadSound-*
|
||
DC.W 0 ; (end of table)
|
||
MSCPMgrOpExceptionsEnd
|
||
|
||
DC.L PrimsTypePtr ; flags <K10>
|
||
DC.L (MSCModemTableEnd-MSCModemTable) ; size of table
|
||
MSCModemTable
|
||
DC.L 0 ; offset to routine to turn on modem
|
||
DC.L 0 ; offset to routine to turn off modem
|
||
DC.L DBLiteModemType-MSCModemTable ; offset to routine to get modem type
|
||
MSCModemTableEnd
|
||
|
||
ALIGN 4
|
||
|
||
;_______________________________________________________________________________________
|
||
;
|
||
; Routine: MSCReadBattery
|
||
;
|
||
; Inputs: A0 -- pointer to caller's parameter block
|
||
;
|
||
; Outputs: D0 -- result code
|
||
; CCR-- always BEQ
|
||
;
|
||
; Trashes: D1,A0-A1
|
||
;
|
||
; Function: Emulates the read battery status ($68) and instantaneous battery status ($69)
|
||
; calls since they're not supported by PG&E. The contents of the receive buffer
|
||
; are mapped as follows:
|
||
;
|
||
; extended status ($6B) read status ($68 or $69)
|
||
; +0 flags (bits) flags (bits)
|
||
; 7: chargeable battery 7: 0
|
||
; 6: "energy used" count valid 6: 0
|
||
; 5: 0 5: charger state change
|
||
; 4: battery termperature valid 4: low battery
|
||
; 3: dead battery 3: dead battery (always 0)
|
||
; 2: battery connected 2: hi-charge counter overflow
|
||
; 1: hi-charge enabled 1: hi-charge enabled
|
||
; 0: charger installed 0: charger installed
|
||
; +1 voltage (H) 0-511 -> 7-21 volts power
|
||
; +2 voltage (L) ambient temperature
|
||
; +3 ambient temperature (°C) -
|
||
; +4 battery temperature (°C) -
|
||
; +5 power usage rate (* 66.9 = mW) -
|
||
; +6 energy used (H) -
|
||
; +7 energy used (L) -
|
||
;_______________________________________________________________________________________
|
||
|
||
MSCReadBattery
|
||
MOVEA.L A0,A1 ; save the parameter block pointer
|
||
SUBQ.W #8,SP ; make space for a buffer
|
||
MOVE.L SP,-(SP) ; pmRBuffer
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
CLR.W -(SP) ; pmLength = 0 (no bytes sent)
|
||
MOVE.W #readExtBatt,-(SP) ; pmCommand = read extended battery status
|
||
MOVE.L SP,A0
|
||
_PMgrOp ; get extended battery status
|
||
LEA pmRBuffer+4(SP),SP ; (get rid of the parameter block)
|
||
BNE.S @CantRead ; -> error
|
||
|
||
MOVEA.L SP,A0 ; point to our reply buffer
|
||
MOVE.W #3,pmLength(A1) ; stuff the reply count
|
||
MOVEA.L pmRBuffer(A1),A1 ; point to the reply buffer
|
||
MOVEQ #%00001011,D1 ; mask off the relevant flag bits
|
||
AND.B (A0),D1
|
||
MOVE.B D1,(A1)+ ; and stuff them into the buffer
|
||
|
||
MOVEQ #0,D1 ; assume no battery
|
||
BTST #2,(A0)+ ; is there one?
|
||
BEQ.S @NoBattery ; -> no, return zero volts
|
||
MOVE.W (A0),D1 ; get the battery voltage
|
||
LSR.W #1,D1 ; for now, just scale it into 0-255
|
||
@NoBattery MOVE.B D1,(A1)+
|
||
|
||
ADDQ.W #2,A0 ; (skip over voltage)
|
||
MOVE.B (A0)+,(A1)+ ; •••for now, just copy the temperature across
|
||
|
||
@CantRead ADDQ.W #8,SP ; get rid of the buffer
|
||
MOVEQ #0,D1 ; set CCR for BEQ
|
||
RTS
|
||
|
||
|
||
;_______________________________________________________________________________________
|
||
;
|
||
; Routine: MSCPowerControl
|
||
;
|
||
; Inputs: A0 -- pointer to caller's parameter block
|
||
;
|
||
; Outputs: D0 -- result code
|
||
; CCR-- BEQ if the call was emulated, else BNE
|
||
;
|
||
; Trashes: D1-D2, A1
|
||
;
|
||
; Function: Emulates all or part of the powerCntl call ($10) for systems where not all
|
||
; power planes are controlled by the PMGR. The send buffer will contain a
|
||
; byte with the following bits used:
|
||
;
|
||
; bit 0: 1=IWM power
|
||
; 1: 1=SCC power
|
||
; 2: 1=hard disk power
|
||
; 3: 1=internal modem power
|
||
; 4: 1=serial output driver power
|
||
; 5: 1=sound power
|
||
; 6: 1=minus 5 volt power
|
||
; 7: 1=turn on, 0=turn off devices corresponding to 1's in bits 0-6
|
||
;_______________________________________________________________________________________
|
||
|
||
Unimplement EQU $A89F ; _Unimplemented trap
|
||
|
||
MSCPowerControl
|
||
MOVEA.L pmSBuffer(A0),A1 ; point to the transmit buffer
|
||
MOVEQ #0,D1
|
||
MOVE.B (A1),D1 ; get the data byte
|
||
|
||
MOVEM.L D1/A0,-(SP)
|
||
MOVE.W #Unimplement,D0 ; does the _DockingDispatch trap exist?
|
||
_GetTrapAddress ,NEWTOOL
|
||
MOVEA.L A0,A1
|
||
MOVE.W @DockTrap,D0
|
||
_GetTrapAddress ,NEWTOOL
|
||
CMPA.L A0,A1
|
||
BEQ.S @NoDocking ; -> no, just turn internal power planes on/off
|
||
SUBQ.W #4,SP ; result
|
||
PEA dockPowerControl ; docking selector = power control
|
||
MOVE.L D1,-(SP) ; params = which power planes to affect
|
||
@DockTrap _DockingDispatch ; call the handler
|
||
ADDQ.W #4,SP ; toss the result
|
||
@NoDocking MOVEM.L (SP)+,D1/A0
|
||
|
||
MOVEA.L VIA2,A1 ; point to the base of the MSC
|
||
MOVEQ #(1<<pSCC) | (1<<pSerDrvr),D0 ; mask off the SCC power and serial drivers bits
|
||
AND.B D1,D0 ; are either of them set?
|
||
BEQ.S @NoSCC ; -> nope
|
||
EOR.B D0,D1 ; turn them both off
|
||
TST.B D1 ; turn power on or off?
|
||
BMI.S @TurnOnSCC
|
||
BCLR #MSCSCCClk,MSCClkCntl(A1) ; turn off SCC PCLK, RTXC
|
||
BRA.S @NoSCC
|
||
@TurnOnSCC BSET #MSCSCCClk,MSCClkCntl(A1) ; turn on SCC PCLK, RTXC
|
||
|
||
@NoSCC BTST #pHD,D1 ; is hard disk power being turned on/off?
|
||
BEQ.S @NoHD ; -> no
|
||
TST.B D1 ; turn power on or off?
|
||
BMI.S @TurnOnSCSI
|
||
BCLR #MSCSCSIReset,MSCClkCntl(A1) ; drive SCSI chip reset low to stop clocks
|
||
BRA.S @NoHD
|
||
@TurnOnSCSI BSET #MSCSCSIReset,MSCClkCntl(A1) ; drive SCSI chip reset high to start it up
|
||
|
||
@NoHD BCLR #pASC,D1 ; is sound power being turned on/off?
|
||
BEQ.S @NoSound ; -> nope
|
||
TST.B D1 ; turn power on or off?
|
||
BMI.S @TurnOnSnd
|
||
BCLR #MSCSndPower,MSCSndCntl(A1) ; turn off sound power
|
||
BRA.S @NoSound
|
||
@TurnOnSnd BSET #MSCSndPower,MSCSndCntl(A1) ; turn off sound power
|
||
|
||
@NoSound BCLR #pIWM,D1 ; clear the SWIM power bit
|
||
|
||
@NoSWIM MOVEQ #$7F,D0 ; return BNE if any bits are still set
|
||
AND.B D1,D0 ; so we can pass it on to the PMGR
|
||
BNE.S @MorePower ; -> more for the PMGR to do
|
||
CLR.W pmLength(A0) ; fix the returned length since we're done
|
||
@MorePower RTS
|
||
|
||
|
||
;_______________________________________________________________________________________
|
||
;
|
||
; Routine: MSCPowerStatus
|
||
;
|
||
; Inputs: A0 -- pointer to caller's parameter block
|
||
;
|
||
; Outputs: D0 -- result code
|
||
; CCR-- BEQ if the call was emulated, else BNE
|
||
;
|
||
; Trashes: D1-D2, A0-A1
|
||
;
|
||
; Function: Emulates all or part of the powerRead call ($18) for systems where not all
|
||
; power planes are controlled by the PMGR. On exit, the receive buffer will
|
||
; contain a byte with the following bits used:
|
||
;
|
||
; bit 0: 1=IWM power
|
||
; 1: 1=SCC power
|
||
; 2: 1=hard disk power
|
||
; 3: 1=internal modem power
|
||
; 4: 1=serial output driver power
|
||
; 5: 1=sound power
|
||
; 6: 1=minus 5 volt power
|
||
; 7: 1=turn on, 0=turn off devices corresponding to 1's in bits 0-6
|
||
;_______________________________________________________________________________________
|
||
|
||
MSCPowerStatus
|
||
MOVEQ #0,D1
|
||
MOVE.L A0,-(SP)
|
||
MOVE.W #Unimplement,D0 ; does the _DockingDispatch trap exist?
|
||
_GetTrapAddress ,NEWTOOL
|
||
MOVEA.L A0,A1
|
||
MOVE.W @DockTrap,D0
|
||
_GetTrapAddress ,NEWTOOL
|
||
CMPA.L A0,A1
|
||
BEQ.S @NoDocking ; -> no, just turn internal power planes on/off
|
||
SUBQ.W #4,SP ; result
|
||
PEA dockPowerStatus ; docking selector = power status
|
||
CLR.L -(SP) ; params = nil
|
||
@DockTrap _DockingDispatch ; call the handler
|
||
ADDQ.W #4,SP ; toss the result
|
||
@NoDocking MOVEM.L (SP)+,D1/A0
|
||
|
||
MOVEA.L VIA2,A1 ; point to the base of the MSC
|
||
MOVEQ #(1<<pSCC) | (1<<pSerDrvr),D0 ; mask off the SCC power and serial drivers bits
|
||
AND.B D1,D0 ; are either of them set?
|
||
BEQ.S @NoSCC ; -> nope
|
||
EOR.B D0,D1 ; turn them both off
|
||
TST.B D1 ; turn power on or off?
|
||
BMI.S @TurnOnSCC
|
||
BCLR #MSCSCCClk,MSCClkCntl(A1) ; turn off SCC PCLK, RTXC
|
||
BRA.S @NoSCC
|
||
@TurnOnSCC BSET #MSCSCCClk,MSCClkCntl(A1) ; turn on SCC PCLK, RTXC
|
||
|
||
@NoSCC BTST #pHD,D1 ; is hard disk power being turned on/off?
|
||
BEQ.S @NoHD ; -> no
|
||
TST.B D1 ; turn power on or off?
|
||
BMI.S @TurnOnSCSI
|
||
BCLR #MSCSCSIReset,MSCClkCntl(A1) ; drive SCSI chip reset low to stop clocks
|
||
BRA.S @NoHD
|
||
@TurnOnSCSI BSET #MSCSCSIReset,MSCClkCntl(A1) ; drive SCSI chip reset high to start it up
|
||
|
||
@NoHD BCLR #pASC,D1 ; is sound power being turned on/off?
|
||
BEQ.S @NoSound ; -> nope
|
||
TST.B D1 ; turn power on or off?
|
||
BMI.S @TurnOnSnd
|
||
BCLR #MSCSndPower,MSCSndCntl(A1) ; turn off sound power
|
||
BRA.S @NoSound
|
||
@TurnOnSnd BSET #MSCSndPower,MSCSndCntl(A1) ; turn off sound power
|
||
|
||
@NoSound BCLR #pIWM,D1 ; clear the SWIM power bit
|
||
|
||
@NoSWIM MOVEQ #$7F,D0 ; return BNE if any bits are still set
|
||
AND.B D1,D0 ; so we can pass it on to the PMGR
|
||
BNE.S @MorePower ; -> more for the PMGR to do <H31>
|
||
CLR.W pmLength(A0) ; fix the returned length since we're done <H31>
|
||
@MorePower RTS
|
||
|
||
;_______________________________________________________________________________________
|
||
;
|
||
; Routine: MSCFakePowerStatus
|
||
;
|
||
; Inputs: A0 -- pointer to caller's parameter block
|
||
;
|
||
; Outputs: CCR-- always BNE
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: This is a skanky way of letting us call the Power Manager and getting control
|
||
; back to do further processing. This converts the powerRead+1 command sent
|
||
; by the PowerStatus routine above into a powerRead command so it can get the
|
||
; status PG&E knows about before filling in the rest of the bits that are now
|
||
; handled by the MSC. What can I say? The price of extensibility?
|
||
;_______________________________________________________________________________________
|
||
|
||
MSCFakePowerStatus
|
||
SUBQ.W #$1F-powerRead,pmCommand(A0) ; convert this to a powerRead command ($18)
|
||
RTS ; get here with BNE to send the command to the PMGR
|
||
|
||
|
||
;_______________________________________________________________________________________
|
||
;
|
||
; Routine: MSCSetSound
|
||
;
|
||
; Inputs: A0 -- pointer to caller's parameter block
|
||
;
|
||
; Outputs: D0 -- result code
|
||
; CCR-- BEQ if the call was emulated, else BNE
|
||
;
|
||
; Trashes: D1,A1
|
||
;
|
||
; Function: Emulates the soundSet call ($90) for systems that don't control sound
|
||
; power and latch with the PMGR micro. The send buffer will contain a
|
||
; byte with the following bits used:
|
||
;
|
||
; bit 0: 1=sound power enabled
|
||
; 1: 1=clear sound latch
|
||
;_______________________________________________________________________________________
|
||
|
||
MSCSetSound CLR.W pmLength(A0) ; no bytes returned
|
||
MOVEA.L pmSBuffer(A0),A1 ; point to the transmit buffer
|
||
MOVEQ #3,D1 ; mask off valid bits
|
||
AND.B (A1),D1
|
||
MOVEA.L VIA2,A1 ; get the MSC's base address
|
||
MOVE.B @MSCSound(D1),MSCSndCntl(A1) ; stuff the right value into the sound control register
|
||
MOVEQ #0,D0 ; return "no error"
|
||
RTS
|
||
|
||
; on MSC, the sound latch is cleared simply by accessing the sound control register
|
||
|
||
@MSCSound DC.B (0<<MSCSndPower)|(0<<MSCSndBusy) ; [0] do nothing
|
||
DC.B (1<<MSCSndPower)|(0<<MSCSndBusy) ; [1] just turn on sound power
|
||
DC.B (0<<MSCSndPower)|(1<<MSCSndBusy) ; [2] turn off sound power, clear sound latch
|
||
DC.B (1<<MSCSndPower)|(1<<MSCSndBusy) ; [3] turn on sound power, clear sound latch
|
||
|
||
|
||
;_______________________________________________________________________________________
|
||
;
|
||
; Routine: MSCReadSound
|
||
;
|
||
; Inputs: A0 -- pointer to caller's parameter block
|
||
;
|
||
; Outputs: D0 -- result code
|
||
; CCR-- BEQ if the call was emulated, else BNE
|
||
;
|
||
; Trashes: D1,A1
|
||
;
|
||
; Function: Emulates the soundRead call ($98) for systems that don't control sound
|
||
; power and latch with the PMGR micro. On exit, the send buffer will contain
|
||
; a byte with the following bits used:
|
||
;
|
||
; bit 0: 1=sound power is on
|
||
; 1: 1=sound latch is set
|
||
;_______________________________________________________________________________________
|
||
|
||
MSCReadSound
|
||
MOVEA.L VIA2,A1 ; get the MSC's base address
|
||
MOVEQ #(1<<mscSndBusy)|(1<<MSCSndPower),D1
|
||
AND.B MSCSndCntl(A1),D1 ; mask off sound busy and sound power bits
|
||
BCLR #mscSndBusy,D1 ; is the sound latch set?
|
||
BEQ.S @NoLatch
|
||
ADDQ.B #(1<<1),D1 ; yes, set bit 1=1
|
||
@NoLatch MOVE.W #1,pmLength(A0) ; 1 byte returned
|
||
MOVEA.L pmRBuffer(A0),A1 ; point to the receive buffer
|
||
MOVE.B D1,(A1) ; and stuff in the result
|
||
MOVEQ #0,D0 ; return "no error"
|
||
RTS
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: CPUSpeedMSC
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: D0 - [maximum CPU speed][current CPU speed]
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: returns the maximum and current (econo-mode or full) CPU speeds for
|
||
; MSC-based machines
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
CPUSpeedMSC MOVEA.L UnivInfoPtr,A0 ; point to our ProductInfo table
|
||
MOVEQ #7,D0 ; mask off the machine type from our CPU ID
|
||
AND.W CPUIDValue(A0),D0
|
||
MOVE.L @speedTable(D0.W*4),D0 ; get the maximum CPU speed in both halves <H9>
|
||
CMPI.W #CPUSpeed16MHz,D0 ; is this a 16MHz machine? <H9>
|
||
BLE.S @NoMSCEcono ; -> yes, econo-mode isn't supported <H9>
|
||
|
||
ADDA.L DecoderInfoPtr(A0),A0 ; point to our decoder table
|
||
MOVEA.L RBVAddr(A0),A0 ; then to the base of the MSC
|
||
BTST #MSCEconoBit,MSCConfig(A0) ; are we in econo-mode?
|
||
BEQ.S @NoMSCEcono ; -> nope <H8>
|
||
MOVE.W #CPUSpeed16MHz,D0 ; current speed is 16MHz
|
||
@NoMSCEcono RTS
|
||
|
||
@speedTable DC.W CPUSpeed33MHz, CPUSpeed33MHz ; ID=0 (boxYeager) <H71>
|
||
DC.W $484A , $5221 ; ID=1 (reserved HJR!) <H9>
|
||
DC.W CPUSpeed33MHz, CPUSpeed33MHz ; ID=2 (boxEscher) <H46>
|
||
DC.W CPUSpeed20MHz, CPUSpeed20MHz ; ID=3 (reserved-wasPenLite) <H71>
|
||
DC.W CPUSpeed25MHz, CPUSpeed25MHz ; ID=4 (boxDuo210) <H9>
|
||
DC.W CPUSpeed33MHz, CPUSpeed33MHz ; ID=5 (boxDuo230) <H9>
|
||
DC.W CPUSpeed16MHz, CPUSpeed16MHz ; ID=6 (boxDBLite16) <H9>
|
||
DC.W CPUSpeed16MHz, CPUSpeed16MHz ; ID=7 (reserved 16MHz) <H9>
|
||
|
||
|
||
|
||
;———————————————————————————————————————————————————————————————————————————————————————— <H56>
|
||
; Routine: ChangeCPUSpeedMSC
|
||
;
|
||
; Inputs: D1 - ≠0: switch to reduced speed, =0: switch to full speed
|
||
;
|
||
; Outputs: D0 - =1: speed was changed, =0: speed was not changed
|
||
;
|
||
; Trashes: D1, A0
|
||
;
|
||
; Function: switches the CPU speed based on the passed parameter, and returns 1 if the
|
||
; speed change was actually done
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
ChangeCPUSpeedMSC
|
||
MOVEA.L VIA2,A1 ; point to the MSC's configuration register
|
||
LEA MSCConfig(A1),A1
|
||
MOVEQ #~(1<<EconoBit),D0 ; mask out the econo-mode bit
|
||
AND.B (A1),D0 ; in the configuration register
|
||
OR.B D0,D1 ; OR in the new setting
|
||
CMP.B (A1),D1 ; are we changing the setting?
|
||
BEQ.S @NoChange ; -> no
|
||
MOVE.B D1,(A1) ; yes, write out the new setting
|
||
|
||
MOVEQ #CPUSpeedDisp,D0 ; get the current CPU speed
|
||
_PowerDispatch
|
||
BCLR #MSC25MHz,(A1) ; assume 33MHz
|
||
CMPI.W #CPUSpeed25MHz,D0 ; are we running at 25MHz or less?
|
||
BGT.S @SpeedChanged ; -> no, we're done
|
||
BSET #MSC25MHz,(A1) ; yes, optimize the state machines for slower speed
|
||
@SpeedChanged
|
||
MOVEQ #1,D0
|
||
RTS
|
||
|
||
@NoChange MOVEQ #0,D0
|
||
RTS
|
||
|
||
|
||
;———————————————————————————————————————————————————————————————————————————————————————— <H7>
|
||
; Routine: ClamshellVBL
|
||
;
|
||
; Inputs: A0 - pointer to VBL task queue element
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0,A0,A1
|
||
;
|
||
; Function: checks to see if the clamshell is closed, and if so, sets a flag so we can
|
||
; handle it at a _IdleMind time
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
ClamshellVBL
|
||
MOVE.W #ClamshellVBLFreq,vblCount(A0) ; reset the counter
|
||
|
||
MOVEA.L PMgrBase,A1 ; point to Power Manager variables
|
||
BTST #ignoreClamshell,PmgrFlags3(A1) ; what do we want to do? <H27>
|
||
BNE.S @InStation ; -> nothing <H27>
|
||
|
||
BTST #dockingStation,dockFlags(A1) ; are we in a docking station?
|
||
BNE.S @InStation ; -> yes, clamshell closed is OK
|
||
|
||
BTST #ClamshellClosed,PmgrFlags(A1) ; have we already detected the close?
|
||
BNE.S @Done ; -> yes, we're done this time
|
||
|
||
CLR.W -(SP)
|
||
MOVE.L SP,-(SP) ; pmRBuffer
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
CLR.W -(SP) ; pmLength = 0
|
||
MOVE.W #readExtSwitches,-(SP) ; pmCommand
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; get the clamshell info
|
||
LEA pmRBuffer+4(SP),SP ; toss the parameter block
|
||
BTST #clamshell,(SP)+ ; is the clamshell closed?
|
||
BEQ.S @Done ; -> nope, all done
|
||
|
||
BSET #ClamshellClosed,PmgrFlags(A1) ; flag that the clamshell is closed
|
||
@Done RTS
|
||
|
||
@InStation BCLR #ClamshellClosed,PmgrFlags(A1) ; flag that the clamshell is open
|
||
RTS
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: CheckClamshell (IdleMind)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager variables
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0, A0
|
||
;
|
||
; Function: does the appropriate thing if the clamshell was closed (sleep or nothing),
|
||
; and then runs the "standard" countdown checking code
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
CheckClamshell
|
||
BTST #InSleep,PmgrFlags(A2) ; IF !InSleep THEN
|
||
BNE @Exit ;
|
||
CLR.W -(SP) ; Setup PB for PmgrCommand
|
||
MOVE.L SP,-(SP) ; pmRBuffer
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
CLR.W -(SP) ; pmLength = 0
|
||
MOVE.W #readExtSwitches,-(SP) ; pmCommand = ReadSwitch
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; get the clamshell info
|
||
LEA pmRBuffer+4(SP),SP ; toss the parameter block
|
||
BTST #clamshell,(SP)+ ; IF ClamShell Open THEN
|
||
BNE.S @doClamshellClosed ;
|
||
BCLR.B #ClamshellClosed,PmgrFlags(A2) ; flag that the clamshell is open
|
||
BRA RunIdleRoutinesProc ; ELSE
|
||
|
||
@doClamshellClosed
|
||
BTST.B #ignoreClamshell,PmgrFlags3(A2) ; IF ignore Clamshell THEN
|
||
BNE.S @Exit ; bail
|
||
|
||
BTST.B #dockingStation,dockFlags(A2) ; ELSE IF in a dockingstation THEN
|
||
BNE.S @Exit ; bail
|
||
|
||
BSR CurFrontProcEqual ; ELSE IF Processes <> THEN
|
||
BEQ.S @Exit ; bail
|
||
|
||
BSET.B #ClamshellClosed,PmgrFlags(A2) ; ELSE IF Clamshell = closed THEN
|
||
BNE.S @Exit ; bail
|
||
|
||
MOVE.B PmgrFlags(A2),-(SP) ; ELSE save PmgrFlags
|
||
BSET #AvoidNetDiag,PmgrFlags(A2) ; and set the ‘no AppleTalk dialogs’ flag
|
||
MOVEQ #SleepNow,D0 ; force a sleep
|
||
_Sleep
|
||
BTST #AvoidNetDiag,(SP)+ ; was the ‘no AppleTalk dialogs’ flag set before?
|
||
BEQ.S @NoDialog ; -> no, leave it alone
|
||
BSET #AvoidNetDiag,PmgrFlags(A2) ; yes, restore it
|
||
@NoDialog MOVE.L Ticks,LastAct(A2) ; waking updates last activity
|
||
@Exit BRA RunIdleRoutinesProc ; ENDIF
|
||
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: SndWatchMSC
|
||
;
|
||
; Inputs: A0 - pointer to VBL task queue element
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0, A0, A2
|
||
;
|
||
; Function: A VBL task called once every ten seconds that checks the sound latch for
|
||
; ASC new use. If so then sound power is turned on. If power is already on
|
||
; then then the latch is cleared. If the latch stays clear for two VBLs then
|
||
; sound power is turned off.
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
SndWatchMSC MOVE.W #SndWFreq,vblCount(A0) ; reset the counter
|
||
|
||
MOVEA.L VIA2,A0 ; point to the MSC's sound control register
|
||
LEA MSCSndCntl(A0),A0
|
||
BTST #MSCSndBusy,(A0) ; was sound used in the last 10 sec
|
||
BNE.S @SoundOn ; -> yes
|
||
|
||
MOVEA.L PMgrBase,A2 ; no, sound's been on but now it's not
|
||
TST.B SysTaskFlag(A2) ; are the sound input primitives set up?
|
||
BEQ.S @NoSoundAct ; -> no, there can't be a sound input source selected
|
||
|
||
jsrTBL sndInputSource ; is a sound source selected?
|
||
TST.B D0
|
||
BNE.S @NoSound ; -> yes, sound input is active so don't power off sound
|
||
|
||
@NoSoundAct BCLR #MSCSndPower,(A0) ; turn off sound power
|
||
RTS
|
||
|
||
@SoundOn BSET #MSCSndPower,(A0) ; turn on sound power (latch is cleared by any register access)
|
||
_IdleUpdateDispatch
|
||
@NoSound RTS
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; _Sleep routine to save the volatile MSC chip registers (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
SaveMSC MOVEA.L VIA2,A2 ; point to the base of the MSC
|
||
MOVEQ #$80-256,D0 ; save slot IER with bit 7 set so interrupts
|
||
OR.B MSCSlotIER(A2),D0 ; will be re-enabled upon wakeup
|
||
MOVE.B D0,-(SP)
|
||
MOVEQ #$80-256,D0 ; do the same with VIA2 IER
|
||
OR.B MSCVIA2IER(A2),D0
|
||
MOVE.B D0,-(SP)
|
||
BSET #MSCIOClk,MSCClkCntl(A2) ; make sure IOClk is on in case a bar's attached <H40>
|
||
MOVE.B MSCClkCntl(A2),-(SP) ; save the clock control register
|
||
JMP (A1) ; and return
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; _Sleep routine to have MSC turn off system power (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
MSCKillPower
|
||
MOVEA.L VIA2,A2 ; point to the power cycle/sleep register
|
||
ADDA.L #MSCPowerCycle,A2
|
||
MOVEQ #-1,D0
|
||
MOVE.L D0,(A2) ; write -1 to the register to kill the power
|
||
JMP (A1) ; we might optimistically get here
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Wakeup routine to restore the volatile MSC chip registers (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
RestoreMSC MOVEA.L VIA2,A2 ; point to the base of the MSC
|
||
MOVE.B (SP)+,MSCClkCntl(A2) ; restore volatile registers
|
||
MOVE.B (SP)+,MSCVIA2IER(A2)
|
||
MOVE.B (SP)+,MSCSlotIER(A2)
|
||
JMP (A1) ; and return
|
||
|
||
|
||
;———————————————————————————————————————————————————————————————————————————————————————— <H6>
|
||
; Wakeup routine to put the SCC into a known state (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
MSCInitSCC MOVEA.L VIA2,A2 ; turn on the internal SCC clock
|
||
BSET #MSCSCCClk,MSCClkCntl(A2)
|
||
|
||
MOVEA.L UnivInfoPtr,A2 ; point to the ProductInfo table
|
||
ADDA.L DecoderInfoPtr(A2),A2 ; then to the DecoderInfo table
|
||
MOVEM.L SCCRdAddr(A2),A2-A3 ; get the SCC base read/write addresses (channel B)
|
||
MOVEA.L VIA,A4 ; point to the VIA for delays
|
||
|
||
MOVE.B (A2),D0 ; do a read to make sure the SCC is synched up
|
||
TST.B (A4) ; delay a bit
|
||
MOVE.B #9,(A3) ; select register 9
|
||
TST.B (A4) ; delay some more
|
||
MOVE.B #$40,(A3) ; reset channel B
|
||
TST.B (A4) ; delay a little more
|
||
|
||
MOVEA.L VIA2,A2 ; turn off the internal SCC clock
|
||
BCLR #MSCSCCClk,MSCClkCntl(A2)
|
||
JMP (A1)
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: DBLiteModemType
|
||
;
|
||
; Input:
|
||
;
|
||
; Outputs: d0.l has the modem Type
|
||
;
|
||
; Trashes: d0
|
||
;
|
||
; Function: Returns type of modem installed in DBLite Modem
|
||
;
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
DBLiteModemType
|
||
moveq.l #ModemTypeDUO,d0 ; dbmodem
|
||
rts
|
||
|
||
ENDIF ; {hasMSC}
|
||
|
||
|
||
IF hasNiagra THEN
|
||
;•••••••••••••••••••••••••••••••••••••••• Niagra •••••••••••••••••••••••••••••••••••••••••
|
||
|
||
EXPORT NiagraPmgrPrims
|
||
|
||
ALIGN 4
|
||
DC.L PrimsTypeTable ; padding, for now
|
||
DC.L (NiagraPmgrPrimsEnd-NiagraPmgrPrims); size of table
|
||
NiagraPmgrPrims ; Table of Niagra Primitives Tables
|
||
DC.L NiagraRoutines-NiagraPmgrPrims ; offset to table of NiagraRoutines
|
||
DC.L NiagraPrimInfo-NiagraPmgrPrims ; offset to decoder-specific constants
|
||
DC.L NiagraIdleMindTable-NiagraPmgrPrims ; offset to table of Idlemind routines
|
||
DC.L NiagraSleepTable-NiagraPmgrPrims ; offset to table of sleep routines
|
||
DC.L NiagraWakeTable-NiagraPmgrPrims ; offset to table of wakeup routines
|
||
DC.L NiagraPMgrOpExceptions-NiagraPmgrPrims; offset to PMgrOp exception table
|
||
DC.L NiagraModemTable-NiagraPmgrPrims ; offset to Modem Table <H31>
|
||
DC.L PwrDispatchVects-NiagraPmgrPrims ; offset to power dispatch table
|
||
DC.L PMgrHookVects-NiagraPmgrPrims ; offset to PMgr hook table
|
||
DC.L CommsPowerTable-NiagraPmgrPrims ; offset to table of comms power routines <K12>
|
||
DC.L PMgrOpTbl-NiagraPmgrPrims ; offset to routine for PmgrOp
|
||
DC.L 0 ; offset to backlight tables
|
||
NiagraPmgrPrimsEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (NiagraRoutinesEnd-NiagraRoutines) ; size of table
|
||
NiagraRoutines ; Table of Niagra Specific Routines
|
||
DC.L PowerCycle030-NiagraRoutines ; offset to routine for power cycling down <H5>
|
||
DC.L Restore030-NiagraRoutines ; offset to routine for power cycling restore <H5>
|
||
DC.L BatWatch-NiagraRoutines ; offset to VBL task to check the battery level<H19>
|
||
DC.L GetLevel-NiagraRoutines ; offset to routine for determining battery level
|
||
DC.L LeadScaledBatteryInfo-NiagraRoutines; offset to routine to return scaled battery level <H15>
|
||
DC.L NiagraEnvInt-NiagraRoutines ; offset to environment interrupt handler
|
||
DC.L 0 ; no clamshellvbl
|
||
DC.L CPUSpeedNiagra-NiagraRoutines ; offset to routine for determining CPU speed
|
||
DC.L SndWatchPonti-NiagraRoutines ; offset to VBL task to check for sound usage <H19>
|
||
DC.L RedrawScrn-NiagraRoutines ; offset to routine for refreshing the screen <H17>
|
||
DC.L LeadAbsoluteBatteryVoltage-NiagraPmgrPrims; routine to return absolute battery level<H54>
|
||
DC.L 0 ; no routine to return info about battery times
|
||
DC.L 0 ; dynamic CPU speed change is not supported <H56>
|
||
NiagraRoutinesEnd
|
||
|
||
DC.L PrimsTypeInfo ; flags
|
||
DC.L (NiagraPrimInfoEnd-NiagraPrimInfo) ; size of table
|
||
NiagraPrimInfo ; machine-specific constants:
|
||
DC.B $46 ; PRAM base address <H14>
|
||
DC.B DefHysteresis ; default hysteresis
|
||
DC.B PMGRWARNLEVEL-STDOFFSET ; default low battery warning level <H5>
|
||
DC.B PMGRCUTOFF-STDOFFSET ; default dead battery warning level <H5>
|
||
DC.B PGMRWAKELEVEL-STDOFFSET ; hysteresis setting for pmgr wake level <H5>
|
||
DC.B (2-1) ; display shorted battery at second interrupt <H33>
|
||
DC.B 10 ; add 100mv to low bat warn if external video <H33>
|
||
DC.B 0 ; no charger features
|
||
DC.L $50FA0000 ; address of power cycling register <H7>
|
||
DC.L 0 |\ ; bitmap of Power Manager features <H52>
|
||
(0<<hasWakeupTimer) |\
|
||
(1<<hasSharedModemPort) |\
|
||
(1<<hasProcessorCycling) |\
|
||
(1<<mustProcessorCycle) |\
|
||
(1<<hasReducedSpeed) |\
|
||
(0<<dynamicSpeedChange) |\
|
||
(1<<hasSCSIDiskMode)
|
||
DC.L 0 |\ ; bitmap of private Power Manager features <H53>
|
||
(0<<hasExtdBattInfo) |\
|
||
(0<<hasBatteryID) |\
|
||
(0<<canSwitchPower)
|
||
DC.W 1 ; number of batteries
|
||
DC.B 0 ; Power Manager Parallel Interface
|
||
DC.B 0 ; padding for now
|
||
DC.L 0 ; no extended charge time
|
||
DC.B 0 ; value for power cycling register <K22>
|
||
DC.B 0 ; value for sleep register <K22>
|
||
DC.B 0 ; padding for now
|
||
DC.B 0 ; padding for now
|
||
NiagraPrimInfoEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (NiagraIdleMindTableEnd-NiagraIdleMindTable) ; size of table
|
||
NiagraIdleMindTable ; Machine specific Idlemind routines
|
||
DC.L CheckCountDownTimer-NiagraIdleMindTable ; offset to countdown timer
|
||
DC.L NiagraRunIdleRoutinesProc-NiagraIdleMindTable ; offset to run idle procs <H20>
|
||
DC.L ChkSleepTimeOut-NiagraIdleMindTable ; offset to check sleep
|
||
DC.L ChkIdle-NiagraIdleMindTable ; offset to check idle
|
||
DC.L CalcProgressive-NiagraIdleMindTable ; offset to calc progressive
|
||
DC.L GoPowerCycle-NiagraIdleMindTable ; offset to power cycle
|
||
NiagraIdleMindTableEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (NiagraSleepTableEnd-NiagraSleepTable) ; size of table
|
||
NiagraSleepTable ; list of routines to execute when going to sleep:
|
||
DC.L SleepHD-NiagraSleepTable ; sleep the hard drive if currently running
|
||
DC.L SaveVIA1-NiagraSleepTable ; save VIA1 registers
|
||
DC.L SaveASCBatmanDART-NiagraSleepTable ; save ASC/Batman registers <H29>
|
||
DC.L SoundPowerDownNiagra-NiagraSleepTable; power off sound <H29>
|
||
DC.L SaveFPU-NiagraSleepTable ; save FPU registers
|
||
DC.L SaveLCD-NiagraSleepTable ; save built-in LCD video registers
|
||
DC.L SaveVIA2-NiagraSleepTable ; save VIA2 registers
|
||
DC.L SendSleep-NiagraSleepTable ; send a sleep command
|
||
DC.L SaveSlp030-NiagraSleepTable ; save MMU registers
|
||
DC.L SaveSleepInfo-NiagraSleepTable ; save sleep info in video RAM
|
||
DC.L 0 ; (end of table)
|
||
NiagraSleepTableEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (NiagraWakeTableEnd-NiagraWakeTable) ; size of table
|
||
NiagraWakeTable ; list of routines to execute when waking up:
|
||
DC.L RestoreSlp030-NiagraWakeTable ; restore MMU, SPs, cache registers
|
||
DC.L RestoreVIA2-NiagraWakeTable ; restore VIA2 registers
|
||
DC.L RestoreLCD-NiagraWakeTable ; restore GSC (built-in LCD video) registers
|
||
DC.L RestoreFPU-NiagraWakeTable ; restore FPU registers
|
||
DC.L RestoreASCBatman-NiagraWakeTable ; restore ASC and Batman registers
|
||
DC.L RestoreDartAmp-NiagraWakeTable ; turn on amps <H29>
|
||
DC.L RestoreVIA1-NiagraWakeTable ; restore VIA1 registers
|
||
DC.L RestorePmgrMisc-NiagraWakeTable ; restore Misc PmgrVars
|
||
DC.L DockingWakeup-NiagraWakeTable ; restore state of currently connected bar <H10>
|
||
DC.L WakeClrInts-NiagraWakeTable ; clear any pending PmgrInterrupts
|
||
DC.L WakeSoundSetNiagra-NiagraWakeTable ; set state for sound out of sleep
|
||
DC.L 0 ; (end of table)
|
||
NiagraWakeTableEnd
|
||
|
||
DC.L PrimsTypePMgrEx ; flags
|
||
DC.L (NiagraPMgrOpExceptionsEnd-NiagraPMgrOpExceptions) ; size of table
|
||
NiagraPMgrOpExceptions ; PMgrOp exceptions:
|
||
DC.B $F0,$50 ; $5x - modem commands
|
||
DC.L DartModemCmds-* ;
|
||
DC.B $F7,$71 ; $71,$79 - modem commands
|
||
DC.L DartSPI-* ;
|
||
DC.B $F0,$A0 ; $Ax - modem commands
|
||
DC.L DartSPI-* ;
|
||
DC.W 0 ; (end of table)
|
||
NiagraPMgrOpExceptionsEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (NiagraModemTableEnd-NiagraModemTable) ; size of table
|
||
NiagraModemTable
|
||
DC.L DartModemOn-NiagraModemTable ; offset to routine to turn on modem
|
||
DC.L DartModemOff-NiagraModemTable ; offset to routine to turn off modem
|
||
DC.L DartModemType-NiagraModemTable ; offset to routine to get modem type <K10>
|
||
NiagraModemTableEnd
|
||
|
||
ALIGN 4
|
||
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: DartModemCmds
|
||
;
|
||
; Input: A0 - points the pmgrop PB
|
||
;
|
||
; Destroys: d1
|
||
;
|
||
; Called by: Bra from NewPmgrOp
|
||
;
|
||
; Function: filter the modem $5X commands, $50 should still go the power manager
|
||
;————————————————————————————————————————————————————————————————————————————————
|
||
|
||
DartModemCmds
|
||
cmp.w #modemSet,pmCommand(A0)
|
||
bne.s DartSPI ; Handle call through SPI
|
||
moveq #1,d1 ; set CC to not handled here
|
||
rts ; return
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: DartSPI <H16>
|
||
;
|
||
; Input: A0 - points the pmgrop PB
|
||
;
|
||
; Destroys: d1
|
||
;
|
||
; Called by: Bra from NewPmgrOp
|
||
;
|
||
; Function: transfer data through new SPI port
|
||
;————————————————————————————————————————————————————————————————————————————————
|
||
|
||
DartSPI
|
||
@savedRegs REG D1-D4/A0-A3
|
||
|
||
|
||
; ----- dynamic test for SPI ----
|
||
movea.l PMgrBase,a3 ; point to the Power Manager's variables
|
||
btst.b #PmgrDartSPI,PmgrFlags1(a3) ; test if SPI modem installed
|
||
bne.s @SPIStart ; Handle call through SPI
|
||
moveq #1,d1 ; set CC to not handled here
|
||
rts ; return
|
||
|
||
@SPIStart
|
||
movem.l @savedRegs,-(sp)
|
||
MOVEA.L UnivInfoPtr,a2 ; point to the ProductInfo table,
|
||
ADDA.L DecoderInfoPtr(a2),a2 ; then to the DecoderInfo table,
|
||
MOVEA.L JAWSAddr(a2),a2 ; then to the Niagra base address,
|
||
|
||
ADDA.L #NiagraGUR,a2 ; point to the base of the GUR space
|
||
|
||
; ----- send command and count ----
|
||
|
||
move.w pmCommand(a0),d3
|
||
move.w d3,d1
|
||
bsr SendSPI ; send command byte
|
||
bne.s @PMgrOpExit ; exit if error returned
|
||
|
||
MOVEA.L PMgrBase,A1 ; point to the Power Manager's variables
|
||
MOVEA.L vSendCountTbl(A1),A1 ; and get the send count table
|
||
move.w pmLength(a0),d2 ; pop the count into d2
|
||
tst.b (a1,d3)
|
||
bpl.s @noCount ; if positive, no count
|
||
|
||
move.w d2,d1
|
||
bsr SendSPI ; send count byte
|
||
bne.s @PMgrOpExit ; exit if error returned
|
||
|
||
; ----- send data ----
|
||
|
||
@noCount movea.l pmSBuffer(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 SendSPI ; and send it
|
||
@StartSend DBNE d2,@SendData ; -> more bytes to send
|
||
BNE.S @PMgrOpExit ; -> error
|
||
|
||
; ----- receive data -----
|
||
MOVEA.L PMgrBase,A1 ; point to the Power Manager's variables
|
||
MOVEA.L vRecvCountTbl(A1),A1 ; and get the receive count table
|
||
clr.l d4 ; clear count register
|
||
move.b (a1,d3),d4 ; initialize to count
|
||
bmi.s @readReplyCount ; (<0)
|
||
cmp.b #1,d4 ; test against 1
|
||
ble.s @readData ; if ( =0 or =1 ) go to read
|
||
subq #1,d4 ; (>1) correct count
|
||
bra.s @readData ; if 0 or 1 go to read
|
||
|
||
@readReplyCount
|
||
bsr ReceiveSPI ; read first byte for receive count
|
||
bne.s @PMgrOpExit ; exit if error returned
|
||
move.w d1,d4 ; move count into d4
|
||
|
||
@readData ; d4 has receive byte count
|
||
movea.l pmRBuffer(a0),a3 ; a3 new points
|
||
move.w d4,pmLength(a0) ;
|
||
bra.s @StartReceive ; start receiving data
|
||
|
||
@ReceiveByte
|
||
bsr.s ReceiveSPI ; read a byte into d1
|
||
bne.s @PMgrOpExit ; -> error
|
||
move.b d1,(a3)+ ; move data byte into buffer
|
||
|
||
@StartReceive
|
||
dbra d4,@ReceiveByte ; -> more bytes to send
|
||
|
||
@PMgrOpExit
|
||
moveq #0,d1 ; indicate we handled call
|
||
@exit
|
||
movem.l (sp)+,@savedRegs ; restore working registers
|
||
rts
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: WaitSPIAckHi
|
||
;
|
||
; Input: a2.l - pointer to GUR space
|
||
;
|
||
; Returns CCR - BNE if ACK went hi, BEQ if timed out
|
||
;
|
||
; Function: wait for SPI ack high
|
||
;————————————————————————————————————————————————————————————————————————————————
|
||
|
||
WaitSPIAckHi
|
||
@workRegs reg D1-d2
|
||
|
||
movem.l @workRegs,-(sp) ; save working set
|
||
moveq #32,d2 ; loop to max 32 msec
|
||
@nextmsec move.w timedbra,d1 ; 1 msec count
|
||
@waitAckhi btst.b #PontiSPIAck,PontiSPIMdmCtl(a2) ; test ack
|
||
dbne d1,@waitAckhi ; loop for upto 1 msec
|
||
dbne d2,@nextmsec ; loop for d2 msec
|
||
movem.l (sp)+,@workRegs
|
||
rts
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: WaitSPIAckLo
|
||
;
|
||
; Input: a2 - pointer to GUR space
|
||
;
|
||
; Returns CCR - BEQ if ACK went lo, BNE if timed out
|
||
;
|
||
; Function: wait for SPI ack lo
|
||
;————————————————————————————————————————————————————————————————————————————————
|
||
|
||
WaitSPIAckLo
|
||
@workRegs reg D1-d2
|
||
|
||
movem.l @workRegs,-(sp) ; save working set
|
||
moveq #32,d2 ; loop to max 32 msec
|
||
@nextmsec move.w timedbra,d1 ; 1 msec count
|
||
@waitAcklo btst.b #PontiSPIAck,PontiSPIMdmCtl(a2) ; test ack
|
||
dbeq d1,@waitAcklo ; loop for upto 1 msec
|
||
dbeq d2,@nextmsec ; loop for d2 msec
|
||
movem.l (sp)+,@workRegs
|
||
rts
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: SendSPI
|
||
;
|
||
; Input: a2.l - pointer to GUR space
|
||
; d1.b - byte to send
|
||
;
|
||
; Returns d0.w - 0 = ok, non-zero = error
|
||
;
|
||
; Function: send a byte thru the SPI
|
||
;————————————————————————————————————————————————————————————————————————————————
|
||
|
||
SendSPI MOVE.W #pmSendStartErr,D0 ; assume a send error
|
||
bsr.s WaitSPIAckHi ; (1) wait for pmgr idle
|
||
beq.s @error ; if bit low, error
|
||
;begin transaction
|
||
bset.b #PontiLmpSPIDir,PontiLmpSftCtl(a2) ; (2) set direction to output
|
||
move.b d1,PontiSPISftReg(a2) ; (3) write data
|
||
bclr.b #PontiSPIReq,PontiSPIMdmCtl(a2) ; (4) assert data valid
|
||
bsr.s WaitSPIAckLo ; (5) --> modem shift data
|
||
; (6) wait for data accepted
|
||
bne.s @error ; if bit low, error
|
||
bset.b #PontiSPIReq,PontiSPIMdmCtl(a2) ; (7) clear data valid
|
||
|
||
MOVEQ #noErr,D0 ; report no error
|
||
@error tst.w d0
|
||
rts
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: ReceiveSPI
|
||
;
|
||
; Input: a2.l - pointer to GUR space
|
||
; d1.b - byte to send
|
||
;
|
||
; Returns d0.w - 0 = ok, non-zero = error
|
||
;
|
||
; Function: read a byte from the spi
|
||
;————————————————————————————————————————————————————————————————————————————————
|
||
|
||
ReceiveSPI MOVE.W #pmRecvStartErr,D0 ; assume a receive error
|
||
bsr.s WaitSPIAckHi ; (1) wait for pmgr idle
|
||
beq.s @error ; if bit low, error
|
||
|
||
;begin transaction
|
||
bclr.b #PontiLmpSPIDir,PontiLmpSftCtl(a2) ; (2) set direction to input
|
||
bclr.b #PontiSPIReq,PontiSPIMdmCtl(a2) ; (3) (RFD) ready for data
|
||
bsr.s WaitSPIAckLo ; (4) acknowledge req
|
||
; (5) <-- modem shifting
|
||
bne.s @error ; if bit low, error
|
||
bset.b #PontiSPIReq,PontiSPIMdmCtl(a2) ; (6) acknowledge ack
|
||
|
||
bsr.s WaitSPIAckHi ; (7) wait (DAV)
|
||
beq.s @error ; if bit low, error
|
||
move.b PontiSPISftReg(a2),d1 ; (8) read data
|
||
|
||
MOVEQ #noErr,D0 ; report no error
|
||
@error tst.w d0
|
||
rts
|
||
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: CPUSpeedNiagra
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: D0 - [maximum CPU speed][current CPU speed]
|
||
;
|
||
; Trashes: D1, A0
|
||
;
|
||
; Function: returns the maximum and current (econo-mode or full) CPU speeds for
|
||
; Niagra-based machines
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
CPUSpeedNiagra
|
||
MOVEA.L UnivInfoPtr,A0 ; point to the ProductInfo table,
|
||
ADDA.L DecoderInfoPtr(A0),A0 ; then to the DecoderInfo table,
|
||
MOVEA.L JawsAddr(A0),A0 ; then to the JAWS base address,
|
||
ADDA.L #NiagraSpeedReg,A0 ; and finally to the CPU clock register
|
||
MOVEQ #%00000011,D1 ; only care about last two bits
|
||
AND.B (A0),D1 ;
|
||
LSL.B #2,D1 ; convert to long words
|
||
MOVE.L @CPUSpeedNiagraTable(D1.W),D0 ; get our table entry
|
||
|
||
ADDA.L #JAWSEconoMode-NiagraSpeedReg,A0; (point to the econo-mode register)
|
||
BTST #1,(A0) ; IF inEconoMode THEN
|
||
BNE.S @InEcono ; Exit we're done
|
||
MOVE.W @CPUSpeedNiagraTable(D1.W),D0 ; Else we are running full speed
|
||
@InEcono RTS
|
||
|
||
@CPUSpeedNiagraTable
|
||
DC.W CPUSpeed16MHz,CPUSpeed16MHz
|
||
DC.W CPUSpeed20MHz,CPUSpeed16MHz
|
||
DC.W CPUSpeed25MHz,CPUSpeed16MHz
|
||
DC.W CPUSpeed33MHz,CPUSpeed16MHz
|
||
|
||
|
||
ALIGN 4
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: NiagraRunIdleRoutinesProc (IdleMind) <H20>
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager variables
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0, A0
|
||
;
|
||
; Function: does the appropriate thing if the shutdown request bit is set
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
NiagraRunIdleRoutinesProc
|
||
btst.b #PmgrShutdownReq,PmgrFlags1(A2) ; test request
|
||
BEQ.S @exitSoftReset ; exit if no request
|
||
movea.l vSoftShutdown(a2),a0 ;
|
||
jsr (a0) ; call shutdown vector
|
||
bne.s @exitSoftReset ; if error, don't clear flag
|
||
bclr.b #PmgrShutdownReq,PmgrFlags1(A2) ; clear request
|
||
@exitSoftReset
|
||
|
||
; Convienient place to check whether a notification message must be posted regarding <H34>
|
||
; the use of external video and the charger. If the user boots or wakes the machine |
|
||
; with an external monitor but no charger, then external video will be disabled by the v
|
||
; primaryInit code. PrimaryInit will also set the flag "PmgrExtVidAlrt" indicating
|
||
; the condition for a warning to be posted. If while external video is on, and the
|
||
; charger is disconnected, a different warning should be posted about the hardware
|
||
; becoming unstable unless the charger is attached.
|
||
|
||
BCLR #PmgrExtVidAlrt,PmgrFlags1(A2) ; IF AlertUser THEN
|
||
BEQ.S @NoVidAlrt ; .
|
||
MOVE.L NoVidSTRPtr(a2),a0 ; Load Appropriate String
|
||
MOVEQ #1,d0 ; Tell Message Handler to use completion routine
|
||
BRA.S @postMsg ; Post Message
|
||
@NoVidAlrt
|
||
BTST #PmgrExtVidOn,PmgrFlags1(a2) ; IF External Video THEN
|
||
BEQ.S @Cont ; .
|
||
BTST #HasCharger,Charger(a2) ; IF ChargerNotConnected THEN
|
||
BNE.S @clearFlag ; .
|
||
MOVE.L NoChrgrSTRPtr(a2),a0 ; Get handle to alert string
|
||
MOVEQ #0,d0 ; Set empty completion routine
|
||
@postMsg BSR PostUserNmMsg ; Post the notification mgr message
|
||
BRA.S @Cont
|
||
@clearFlag ; ELSE
|
||
BTST #PmgrAvoidUsrMsg,PmgrFlags1(a2) ; IF warning messages enabled THEN
|
||
BEQ.S @Cont ; .
|
||
LEA UNmQEntry(a2),a0 ; Get address of notification record
|
||
_NMRemove ; Remove Message
|
||
BCLR #PmgrAvoidUsrMsg,PmgrFlags1(a2) ; after doing NMRemove then clr flag (steve)
|
||
|
||
@Cont BRA RunIdleRoutinesProc ; Continue with RunIdle
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: DartModemOn
|
||
;
|
||
; Input: a0.l = ptr to powermanager pb + 4 byte general data buffer
|
||
; d1.b = modem status bits from power manager
|
||
;
|
||
; Outputs: condition codes
|
||
;
|
||
; Trashes: d0
|
||
;
|
||
; Function: turn Power on to the internal dartanian modem
|
||
;
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
DartModemOn
|
||
bsr StdModemOn ; turn on the modem the standard way
|
||
|
||
; test for spi
|
||
move.l a2,-(sp) ; save a2
|
||
movea.l UnivInfoPtr,a2 ; point to the ProductInfo table,
|
||
adda.l DecoderInfoPtr(a2),a2 ; then to the DecoderInfo table,
|
||
movea.l JAWSAddr(a2),a2 ; then to the Niagra base address,
|
||
adda.l #NiagraGUR,a2 ; and finally general utility register space
|
||
;
|
||
bclr.b #PmgrDartSPI, \ ;
|
||
([PmgrBase],PmgrFlags1) ; preset - disable spi interface
|
||
btst.b #PontiSPIMdmId,PontiSPIMdmCtl(a2); check the new modem interface bit (spi)
|
||
beq.s @exitSPI ; if not set, old modem, exit CCR set
|
||
|
||
bset.b #PmgrDartSPI,\
|
||
([PmgrBase],PmgrFlags1) ; enable spi interface
|
||
bclr.b #PontiSndSPIIrqMsk,PontiSndCtl(a2); enable spi interrupts
|
||
moveq.l #1,d0 ; set CCR, don't turn on power to SCC
|
||
|
||
@exitSPI move.l (sp)+,a2 ; restore a2
|
||
RTS
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: DartModemOff
|
||
;
|
||
; Input: a0.l = ptr to powermanager pb + 4 byte general data buffer
|
||
; d1.b = modem status bits from power manager
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: d0
|
||
;
|
||
; Function: turn Power off to the internal dartanian modem
|
||
;
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
DartModemOff ;
|
||
move.l a2,-(sp) ; save a2
|
||
movea.l UnivInfoPtr,a2 ; point to the ProductInfo table,
|
||
adda.l DecoderInfoPtr(a2),a2 ; then to the DecoderInfo table,
|
||
movea.l JAWSAddr(a2),a2 ; then to the Niagra base address,
|
||
adda.l #NiagraGUR+PontiSndCtl,a2 ; and finally to the modem register
|
||
bclr.b #PmgrDartSPI,\
|
||
([PmgrBase],PmgrFlags1) ; disable spi interface
|
||
bset.b #PontiSndSPIIrqMsk,(a2) ; disable spi interrupts
|
||
bsr StdModemOff ; power off modem the standard way
|
||
move.l (sp)+,a2 ; restore a2
|
||
RTS
|
||
|
||
;———————————————————————————————————————————————————————————————————————————————————————— <K10>
|
||
; Routine: DartModemType
|
||
;
|
||
; Input:
|
||
;
|
||
; Outputs: d0.l has the modem Type
|
||
;
|
||
; Trashes: d0
|
||
;
|
||
; Function: Returns type of modem installed in Dartanian Modem
|
||
;
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
DartModemType
|
||
move.l a0,-(sp)
|
||
|
||
moveq.l #ModemTypeSerial,d0 ; assume serialmodem
|
||
movea.l UnivInfoPtr, a0 ; point to product info table,
|
||
movea.l DecoderInfoPtr(a0), a0 ; then to the DecoderInfo table,
|
||
movea.l JAWSAddr(a0),a0 ; then to the Niagra base address,
|
||
adda.l #NiagraGUR+PontiSPIMdmCtl, a0 ; and finally to the modem ctl register
|
||
btst.b #PontiSPIMdmId,(a0) ; test the modem bit
|
||
beq.s @exit
|
||
moveq.l #ModemTypeDUOPlus,d0 ; load new modem id
|
||
|
||
@exit movem.l (sp)+,a0
|
||
rts
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: SndWatchPonti
|
||
;
|
||
; Inputs: A0 - pointer to VBL task queue element
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0, A0, A2
|
||
;
|
||
; Function: A VBL task called once every ten seconds that checks the sound latch for
|
||
; ASC new use. If so then sound power is turned on. If power is already on
|
||
; then then the latch is cleared. If the latch stays clear for two VBLs then
|
||
; sound power is turned off.
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
SndWatchPonti
|
||
MOVE.W #SndWFreq,vblCount(A0) ; reset the counter
|
||
|
||
MOVEA.L UnivInfoPtr,A0 ; point to the ProductInfo table,
|
||
ADDA.L DecoderInfoPtr(A0),A0 ; then to the DecoderInfo table,
|
||
MOVEA.L JAWSAddr(A0),A0 ; then to the Niagra base address,
|
||
ADDA.L #NiagraGUR+PontiSndCtl,A0 ; and finally to the sound register
|
||
|
||
BTST #PontiSndLatchData,(A0) ; was sound used in the last 10 sec
|
||
BNE.S @SoundOn ; -> yes
|
||
|
||
MOVEA.L PMgrBase,A2 ; no, sound's been on but now it's not
|
||
TST.B SysTaskFlag(A2) ; are the sound input primitives set up?
|
||
BEQ.S @NoSoundAct ; -> no, there can't be a sound input source selected
|
||
|
||
jsrTBL sndInputSource ; is a sound source selected?
|
||
TST.B D0
|
||
BNE.S @NoSound ; -> yes, sound input is active so don't power off sound
|
||
|
||
@NoSoundAct BCLR #PontiSndPwrOn,(A0) ; turn off sound power
|
||
RTS
|
||
|
||
@SoundOn BSET #PontiSndPwrOn,(A0) ; turn on sound power
|
||
BSET #PontiSndLatchClr,(A0) ; pulse (positive) latch clear bit
|
||
BCLR #PontiSndLatchClr,(A0)
|
||
_IdleUpdateDispatch
|
||
@NoSound RTS
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: NiagraEnvInt
|
||
;
|
||
; 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 environment interrupts by attempting a soft shutdown, if allowed.
|
||
;________________________________________________________________________________________
|
||
|
||
NiagraEnvInt
|
||
_IdleUpdateDispatch
|
||
btst.b #ScsiDiskModeOn,PmgrFlags(a2) ; check for scsi disk mode
|
||
beq.s @normalRequest ; if not, continue
|
||
_PowerOff ; ... else power off
|
||
bra.s * ; ... wait for the plug
|
||
|
||
@normalRequest
|
||
btst.b #PmgrShutdownEnb,PmgrFlags1(a2) ; is shutdown allowed
|
||
beq.s @exit ; if not just exit
|
||
bset.b #PmgrShutdownReq,PmgrFlags1(a2) ; set shutdown request
|
||
@exit rts
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; _Sleep routine to poweroff Sound (A1 = return address) <H29>
|
||
;———————————————————————————————————————————————————————————————————————————————————————— |
|
||
SoundPowerDownNiagra ; V
|
||
MOVEA.L UnivInfoPtr,A0 ; point to the ProductInfo table,
|
||
ADDA.L DecoderInfoPtr(A0),A0 ; then to the DecoderInfo table,
|
||
MOVEA.L JAWSAddr(A0),A0 ; then to the Niagra base address,
|
||
ADDA.L #NiagraGUR+PontiSndCtl,A0 ; and finally to the sound register
|
||
;
|
||
BSET #PontiSndLatchClr,(A0) ; pulse (positive) latch clear bit
|
||
BCLR #PontiSndLatchClr,(A0) ;
|
||
;
|
||
BCLR #PontiSndPwrOn,(A0) ; turn off sound power
|
||
;
|
||
JMP (A1) ; and return
|
||
|
||
ENDIF ; {hasNiagra} IF hasNiagra THEN
|
||
|
||
IF hasPratt THEN
|
||
;•••••••••••••••••••••••••••••••••••••••• Pratt •••••••••••••••••••••••••••••••••••••••••
|
||
EXPORT PrattPmgrPrims
|
||
import PrattBkltPrims
|
||
|
||
ALIGN 4
|
||
DC.L PrimsTypeTable ; flags
|
||
DC.L (PrattPmgrPrimsEnd-PrattPmgrPrims) ; size of table
|
||
PrattPmgrPrims ; Table of Primitives tables
|
||
DC.L PrattRoutines-PrattPmgrPrims ; offset to table of Pratt routines
|
||
DC.L PrattPrimInfo-PrattPmgrPrims ; offset to decoder-specific constants
|
||
DC.L PrattIdleMindTable-PrattPmgrPrims ; offset to table of Idlemind routines
|
||
DC.L PrattSleepTable-PrattPmgrPrims ; offset to table of sleep routines
|
||
DC.L PrattWakeTable-PrattPmgrPrims ; offset to table of wakeup routines
|
||
DC.L PrattPMgrOpExceptions-PrattPmgrPrims; offset to PMgrOp exception table
|
||
DC.L PrattModemTable-PrattPmgrPrims ; offset to table of modem routines
|
||
DC.L PwrDispatchVects-PrattPmgrPrims ; offset to table of PwrDispatchVects
|
||
DC.L PMgrHookVects-PrattPmgrPrims ; offset to table of PmgrMgr Hooks
|
||
DC.L PrattCommsPowerTable-PrattPmgrPrims ; offset to table of comms power routines <K12>
|
||
DC.L PMgrOpTbl-PrattPmgrPrims ; offset to table for PmgrOp
|
||
DC.L PrattBkltPrims-PrattPmgrPrims ; offset to backlight tables
|
||
PrattPmgrPrimsEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (PrattRoutinesEnd-PrattRoutines) ; size of table
|
||
PrattRoutines ; machine-specific routines
|
||
DC.L PowerCycle040-PrattRoutines ; offset to routine for power cycling
|
||
DC.L Restore040-PrattRoutines ; offset to routine for power cycling restore
|
||
DC.L BatWatch-PrattRoutines ; offset to VBL task to check the battery level
|
||
DC.L GetExtLevelPratt-PrattRoutines ; offset to routine for determining battery level
|
||
DC.L MultiScaledBatteryInfo-PrattRoutines; offset to routine to return scaled battery level
|
||
DC.L 0 ; no environment interrupts
|
||
DC.L CPUSpeedMSC-PrattRoutines ; offset to routine for determining CPU speed
|
||
DC.L SndWatchPratt-PrattRoutines ; offset to VBL task to check for sound usage
|
||
DC.L RedrawScrn-PrattRoutines ; offset to routine for refreshing the screen
|
||
DC.L PGEAbsoluteBatteryVoltage-PrattRoutines ; routine to return absolute battery level <H54>
|
||
DC.L PrattGetBatteryTimes-PrattRoutines ; routine to return info about battery times
|
||
DC.L 0 ; dynamic CPU speed change is not supported
|
||
PrattRoutinesEnd
|
||
|
||
DC.L PrimsTypeInfo ; flags
|
||
DC.L (PrattPrimInfoEnd-PrattPrimInfo) ; size of table
|
||
PrattPrimInfo ; machine-specific constants:
|
||
DC.B $46 ; PRAM base address
|
||
DC.B DefHysteresis ; default hysteresis
|
||
DC.B 40 ; default low battery warning level (20%)
|
||
DC.B 10 ; default dead battery warning level (5%)
|
||
DC.B 0 ; hysteresis setting for wake level (none)
|
||
DC.B 0 ; shorted battery at first interrupt (none)
|
||
DC.B 0 ; no external video correction needed
|
||
DC.B 0 ; no charger features
|
||
DC.L $5008001B ; address of power cycling register
|
||
DC.L 0 |\ ; bitmap of Power Manager features
|
||
(0<<hasWakeupTimer) |\
|
||
(1<<hasSharedModemPort) |\
|
||
(1<<hasProcessorCycling) |\
|
||
(1<<mustProcessorCycle) |\
|
||
(0<<hasReducedSpeed) |\
|
||
(0<<dynamicSpeedChange) |\
|
||
(1<<hasSCSIDiskMode)
|
||
DC.L 0 |\ ; bitmap of private Power Manager features <H53>
|
||
(1<<hasExtdBattInfo) |\
|
||
(1<<hasBatteryID) |\
|
||
(0<<canSwitchPower)
|
||
DC.W 1 ; number of batteries
|
||
DC.B 2 ; Power Manager Serial Interface
|
||
DC.B 0 ; padding for now
|
||
DC.L 0 ; no extended charging
|
||
DC.B $01 ; value for power cycling register <K22>
|
||
DC.B 0 ; value for sleep register <K22>
|
||
DC.B 0 ; padding for now
|
||
DC.B 0 ; padding for now
|
||
PrattPrimInfoEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (PrattIdleMindTableEnd-PrattIdleMindTable) ; size of table
|
||
PrattIdleMindTable ; machine specific IdleMind Routines
|
||
DC.L CheckCountDownTimer-PrattIdleMindTable; offset to count down timer
|
||
DC.L CheckClamshell-PrattIdleMindTable ; offset to clam shell
|
||
DC.L ChkSleepTimeOut-PrattIdleMindTable ; offset to sleep time out
|
||
DC.L ChkIdle-PrattIdleMindTable ; offset to check idle
|
||
DC.L CalcProgressive-PrattIdleMindTable ; offset to calc progressive
|
||
DC.L GoPowerCycle-PrattIdleMindTable ; offset to go power cycle
|
||
PrattIdleMindTableEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (PrattSleepTableEnd-PrattSleepTable); size of table
|
||
PrattSleepTable ; list of routines to execute when going to sleep:
|
||
DC.L SleepHD-PrattSleepTable ; sleep the hard drive if currently running
|
||
DC.L DockingSleep-PrattSleepTable ; save state of currently connected bar
|
||
DC.L EnetSleep-PrattSleepTable ; sleep the onboard Enet <K17>
|
||
DC.L SaveLCD-PrattSleepTable ; save GSC (built-in LCD video) registers
|
||
DC.L SaveFPU-PrattSleepTable ; save FPU registers
|
||
DC.L SaveVIA1-PrattSleepTable ; save VIA1 registers
|
||
DC.L SaveVIA2-PrattSleepTable ; save VIA2 registers
|
||
DC.L SaveWhitney-PrattSleepTable ; save Whitney registers
|
||
DC.L SaveSlp040-PrattSleepTable ; save MMU registers
|
||
DC.L SaveSleepInfo-PrattSleepTable ; save sleep info in Power Manager globals
|
||
DC.L SendSleep-PrattSleepTable ; send a sleep command
|
||
DC.L 0 ; (end of table)
|
||
PrattSleepTableEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (PrattWakeTableEnd-PrattWakeTable) ; size of table
|
||
PrattWakeTable ; list of routines to execute when waking up:
|
||
DC.L RestoreSlp040-PrattWakeTable ; restore MMU, SPs, cache registers
|
||
DC.L RestoreWhitney-PrattWakeTable ; restore Whitney registers
|
||
DC.L RestoreVIA2-PrattWakeTable ; restore VIA2 registers
|
||
DC.L RestoreVIA1-PrattWakeTable ; restore VIA1 registers
|
||
DC.L RestoreFPU-PrattWakeTable ; restore FPU registers
|
||
DC.L RestoreLCD-PrattWakeTable ; restore CSC (built-in LCD video) registers
|
||
DC.L EnetWake-PrattWakeTable ; wake the onboard Enet <K17>
|
||
DC.L DockingWakeup-PrattWakeTable ; restore state of currently connected bar
|
||
DC.L WakeClrInts-PrattWakeTable ; clear any pending PmgrInterrupts
|
||
DC.L 0 ; (end of table)
|
||
PrattWakeTableEnd
|
||
|
||
DC.L PrimsTypePMgrEx ; flags
|
||
DC.L (PrattPMgrOpExceptionsEnd-PrattPMgrOpExceptions) ; size of table
|
||
PrattPMgrOpExceptions ; PMgrOp exceptions:
|
||
DC.B $F7,SetModemInts ; $71,$79 - modem commands
|
||
DC.L PrattModemOp-* ;
|
||
DC.W 0 ; none for the moment
|
||
PrattPMgrOpExceptionsEnd
|
||
|
||
DC.L PrimsTypePtr ; flags <K10>
|
||
DC.L (PrattModemTableEnd-PrattModemTable); size of table
|
||
PrattModemTable
|
||
DC.L 0 ; offset to routine to turn on modem
|
||
DC.L 0 ; offset to routine to turn off modem
|
||
DC.L BlackBirdModemType-PrattModemTable ; offset to routine to get modem type
|
||
PrattModemTableEnd
|
||
|
||
DC.L PrimsTypePtr ; flags <K12>
|
||
DC.L (PrattCommsPowerTableEnd-PrattCommsPowerTable); number of entries
|
||
PrattCommsPowerTable
|
||
@PwrOn DC.L 0 ; no Port B serial
|
||
DC.L PrattPortAOn-PrattCommsPowerTable ; A serial
|
||
DC.L PortCOn-PrattCommsPowerTable ; C serial (internal modem)
|
||
DC.L PrattSonicOn-PrattCommsPowerTable ; onboard ethernet
|
||
|
||
@PwrOff DC.L 0 ; no Port B serial
|
||
DC.L PrattPortAOff-PrattCommsPowerTable ; A serial
|
||
DC.L PortCOff-PrattCommsPowerTable ; C serial (internal modem)
|
||
DC.L PrattSonicOff-PrattCommsPowerTable ; onboard ethernet
|
||
PrattCommsPowerTableEnd
|
||
ALIGN 4
|
||
|
||
ENDIF
|
||
|
||
|
||
;———————————————————————————————————————————————————————————————————————————————————————— <K26> thru
|
||
; Routine: GetExtLevelPratt |
|
||
; v
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - normalized battery level (-1 to 4)
|
||
; CCR - BNE if a valid battery level is being returned
|
||
;
|
||
; Trashes: D0-D3, A0
|
||
;
|
||
; Function: Reads the extended battery power level from the Power Manager (which is
|
||
; pre-averaged by the PMGR). Next, the value is compared with the warning
|
||
; and cutoff values in the globals. Warning being the first alert, midway from
|
||
; warning to cutoff being the second, and the cutoff being the 10 second
|
||
; countdown.
|
||
;
|
||
; Note: The extended battery status command supports a word-sized battery
|
||
; level. Currently the PMGR on Blackbird returns a value in half
|
||
; percentages, that is from 0-200.
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
GetExtLevelPratt
|
||
CLR.L -(SP)
|
||
CLR.L -(SP)
|
||
MOVE.L SP,-(SP) ; pmRBuffer
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
CLR.W -(SP) ; pmLength = 0
|
||
MOVE.W #readExtBatt,-(SP) ; pmCommand = get extended battery data
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; send the command
|
||
LEA pmRBuffer+4(SP),SP ; toss the parameter block
|
||
|
||
MOVEA.L SP,A0 ; point to the buffer
|
||
MOVEQ #%00001011,D0 ; mask off the bits we want in the flags byte,
|
||
AND.B (A0),D0
|
||
MOVE.B Charger(A2),D1 ; get the old charger state,
|
||
MOVE.B D0,Charger(A2) ; and save the new charger state
|
||
MOVE.B (A0)+,D0 ; get the unmodified flags
|
||
EOR.B D0,D1 ; has the charger state changed since last time?
|
||
BTST #HasCharger,D1 ;
|
||
BEQ.S @ChargeSame ; -> no
|
||
ST TOdirtyFlag(A2) ; yes, flag that timeouts need updating
|
||
|
||
@ChargeSame MOVE.W (A0),D3
|
||
MOVE.B D3,BatAvg(A2) ; save the 8-bit battery voltage
|
||
ADDQ.W #8,SP ; toss the buffer
|
||
|
||
BTST #HasCharger,D0 ; is a charger connected?
|
||
BNE.S @HaveCharger ; -> yes, we don't care about the battery level
|
||
BTST #2,D0 ; is a battery connected?
|
||
BEQ.S @HaveCharger ; -> no, don't bother with battery level
|
||
|
||
|
||
MOVEQ #0,D0 ; level 0
|
||
CMP.B LowWarn(A2),D3 ;
|
||
BHI.S @foundlevel
|
||
|
||
MOVEQ #1,D0 ; level 1
|
||
MOVEQ #0,D1 ; clr register
|
||
MOVE.B LowWarn(A2),D1 ; get low-warning level
|
||
ADD.B CutOff(A2),D1 ; add cutoff
|
||
LSR.B #1,D1 ; average the two
|
||
CMP.B D1,D3 ; are we there yet?
|
||
BHI.S @foundlevel ;
|
||
|
||
MOVEQ #3,D0 ; level 3
|
||
CMP.B CutOff(A2),D3 ; are we at cutoff yet?
|
||
BHI.S @foundlevel ;
|
||
|
||
MOVEQ #4,D0 ; level 4
|
||
BRA.S @foundlevel ; 10 second countdown
|
||
|
||
@HaveCharger
|
||
MOVEQ #-1,D0 ; return a "charged" battery level in case someone cares
|
||
|
||
@foundlevel MOVEQ #1,D1 ; always return BNE for data valid
|
||
RTS
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: SndWatchPratt
|
||
;
|
||
; Inputs: A0 - pointer to VBL task queue element
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0, A0, A2
|
||
;
|
||
; Function: A VBL task called once every ten seconds that checks the sound latch for
|
||
; ASC new use. If so then sound power is turned on. If power is already on
|
||
; then then the latch is cleared. If the latch stays clear for two VBLs then
|
||
; sound power is turned off.
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
SndWatchPratt
|
||
MOVE.W #SndWFreq,vblCount(A0) ; reset the counter
|
||
|
||
MOVEA.L ASCBase,A0 ; point to the ProductInfo table,
|
||
LEA wSndControl(A0),A0 ; A0 = Ptr to Sound Control Register
|
||
BTST #wSingerSNDFlag,(A0) ; IF wSingerSNDFlag THEN
|
||
BNE.S @SoundOn ; there was a sound in the last 10 sec
|
||
|
||
MOVEA.L PMgrBase,A2 ; no, sound's been on but now it's not
|
||
TST.B SysTaskFlag(A2) ; are the sound input primitives set up?
|
||
BEQ.S @NoSoundAct ; -> no, there can't be a sound input source selected
|
||
|
||
jsrTBL sndInputSource ; is a sound source selected?
|
||
TST.B D0
|
||
BNE.S @NoSound ; -> yes, sound input is active so don't power off sound
|
||
|
||
@NoSoundAct BCLR #wSingerPower,(A0) ; turn off sound power
|
||
RTS
|
||
|
||
@SoundOn BSET #wSingerPower,(A0) ; turn on sound power
|
||
BSET #wSingerSNDFlag,(A0) ; Clear the latch
|
||
_IdleUpdateDispatch ;
|
||
@NoSound RTS ; <K26>
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: PrattGetBatteryTimes
|
||
;
|
||
; Inputs: - 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.
|
||
;________________________________________________________________________________________
|
||
PrattGetBatteryTimes
|
||
|
||
@NoBattery CLR.L (A0)+ ; zero out the fields
|
||
CLR.L (A0)+
|
||
CLR.L (A0)+
|
||
CLR.L (A0)+
|
||
MOVEQ #0,D0
|
||
RTS
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: PrattModemOp
|
||
;
|
||
; Input: A0 - points the pmgrop PB
|
||
;
|
||
; Destroys: d1
|
||
;
|
||
; Called by: PmgrOp
|
||
;
|
||
; Function: transfer data through modem
|
||
;————————————————————————————————————————————————————————————————————————————————
|
||
PrattModemOp
|
||
moveq #1,d1 ; set CC to not handled here
|
||
rts ; return
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; _Sleep routine to save the Whitney registers (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
SaveWhitney
|
||
MOVEA.L ASCBase,A2 ; point to the base of the ASC/Batman
|
||
MOVE.B ascMode(A2),-(SP) ; save the chip mode
|
||
MOVE.B ascVolControl(A2),-(SP) ; save the external sound volume control
|
||
MOVE.B ascPlayRecA(A2),-(SP) ; save channel A play/record register
|
||
MOVE.B bmIntControlA(A2),-(SP) ; save sound input control register a
|
||
MOVE.B bmIntControlB(A2),-(SP) ; save sound input control register b
|
||
MOVE.B wSndControl(A2),-(SP) ; save sound control regiser
|
||
MOVE.L wSndFIFOBase(A2),-(SP) ; save sound FIF0 Base address
|
||
MOVE.L wSndSingerCtl1(A2),-(SP) ; save Singer Control Register 1 & 2
|
||
MOVE.B WhitneyPwrCtl,-(SP) ; save Power Control Register
|
||
JMP (A1) ; and return
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; _Sleep routine to Restore the Whitney registers (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
RestoreWhitney
|
||
MOVE.B (SP)+,WhitneyPwrCtl ; restore Power Control Register
|
||
MOVEA.L ASCBase,A2 ; point to the base of the ASC/Batman
|
||
MOVE.L (SP)+,wSndSingerCtl1(A2) ; restore Singer Control Register 1 & 2
|
||
MOVE.L (SP)+,wSndFIFOBase(A2) ; restore sound FIF0 Base address
|
||
MOVE.B (SP)+,wSndControl(A2) ; restore sound control regiser
|
||
MOVE.B (SP)+,bmIntControlB(A2) ; restore sound input control register b
|
||
MOVE.B (SP)+,bmIntControlA(A2) ; restore sound input control register a
|
||
MOVE.B (SP)+,ascPlayRecA(A2) ; restore channel A play/record register
|
||
MOVE.B (SP)+,ascVolControl(A2) ; restore the external sound volume control
|
||
MOVE.B (SP)+,ascMode(A2) ; restore the chip mode <K15>
|
||
JMP (A1) ; and return
|
||
|
||
|
||
;———————————————————————————————————————————————————————————————————————————————————————— <K10>
|
||
; Routine: BlackbirdModemType
|
||
;
|
||
; Input:
|
||
;
|
||
; Outputs: d0.l has the modem Type
|
||
;
|
||
; Trashes: d0
|
||
;
|
||
; Function: Returns type of modem installed in TIM Modem
|
||
;
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
BlackbirdModemType
|
||
move d0, d0 ; do something stupid for now so I can test this
|
||
rts
|
||
|
||
;_______________________________________________________________________________________ <K12>
|
||
; PrattPortAOn -- turns on serial port A
|
||
;
|
||
; Inputs:
|
||
; Outputs:
|
||
; Trashes:
|
||
; Notes: No need to do A -> C mapping. No need to Port B check (we don't have one).
|
||
;_______________________________________________________________________________________
|
||
PrattPortAOn
|
||
bset.b #SerPortAPwr,\
|
||
([PMgrBase],PmgrFlags2) ; log power state
|
||
bclr.b #WhitneySCCpwr,WhitneyPwrCtl ; turn on SCC driver chip
|
||
bclr.b #WhitneySCCclk,WhitneyPwrCtl ; start clock to SCC
|
||
rts
|
||
;_______________________________________________________________________________________ <K12> <K23>
|
||
; PrattPortAOff -- turns off serial port A
|
||
;
|
||
; Inputs:
|
||
; Outputs:
|
||
; Trashes:
|
||
;
|
||
; Notes: No need to do A -> C mapping. No need to Port B check (we don't have one).
|
||
; Disable interrupts so we don't get any by mistake on wake.
|
||
;_______________________________________________________________________________________
|
||
PrattPortAOff
|
||
bclr.b #SerPortAPwr,\
|
||
([PMgrBase],PmgrFlags2) ; log power state
|
||
move.l SCCRd, a0 ; Point to SCC
|
||
move.l SCCWr, a1
|
||
addq.l #2, a0 ; point to port A
|
||
addq.l #2, a1
|
||
move.b (a0), d0 ; sync up
|
||
move.b #9,(a1) ; write register 9
|
||
move.b #2,(a1) ; disable all SCC interrupts
|
||
bset.b #WhitneySCCpwr,WhitneyPwrCtl ; turn off SCC driver chip
|
||
bset.b #WhitneySCCclk,WhitneyPwrCtl ; stop clock to SCC
|
||
|
||
rts
|
||
|
||
;_______________________________________________________________________________________ <K12>
|
||
; PrattSonicOn -- turns on Sonic ethernet power
|
||
;
|
||
; Inputs:
|
||
; Outputs:
|
||
; Trashes: d2
|
||
;
|
||
;_______________________________________________________________________________________
|
||
PrattSonicOn
|
||
bset.b #EnetPwr,\
|
||
([PMgrBase],PmgrFlags3) ; log power state
|
||
bclr.b #WhitneyEnetPwr,WhitneyPwrCtl ; turn on power to Sonic
|
||
|
||
; wait for crystal to stabilize
|
||
move.w TimeVIAdb,d2 ; 1 ms delay
|
||
lsl.w #6,d2 ; 64 ms delay
|
||
@loop tst.b ([VIA])
|
||
dbra d2,@loop
|
||
|
||
bset.b #WhitneyEnetReset,WhitneyPwrCtl ; deassert _sleep pin <K17>
|
||
rts
|
||
;_______________________________________________________________________________________ <K12>
|
||
; PrattSonicOff -- turns off Sonic ethernet power
|
||
;
|
||
; Inputs:
|
||
; Outputs:
|
||
; Trashes:
|
||
;
|
||
;_______________________________________________________________________________________
|
||
PrattSonicOff
|
||
bclr.b #EnetPwr,\
|
||
([PMgrBase],PmgrFlags3) ; log power state
|
||
bclr.b #WhitneyEnetReset, WhitneyPwrCtl ; assert _sleep pin
|
||
bset.b #WhitneyEnetPwr,WhitneyPwrCtl ; turn off power to Sonic
|
||
rts
|
||
|
||
;_______________________________________________________________________________________ <K17>
|
||
; IsDriverInstalled -- looks to see if given driver is installed in the unit table
|
||
;
|
||
; Inputs: a0.l points to input driver name
|
||
; d1.l is the input driver name length
|
||
; Outputs: CCR has Z=0 for found, Z=1 for not found
|
||
; d0 = pointer to the DCE
|
||
; Trashes: d0
|
||
; Called by: Sleep Table code in Power Mgr
|
||
; Calls: .ENET driver _Open and _Control
|
||
;
|
||
;_______________________________________________________________________________________
|
||
IsDriverInstalled
|
||
@workregs REG a0-a3/d1-d4
|
||
movem.l @workregs, -(sp) ; save our working regs
|
||
|
||
MOVE.L UTableBase, A3 ; get address of the unit I/O table
|
||
MOVE.W UnitNtryCnt, D2 ; number of units to check
|
||
|
||
@CkInstLoop
|
||
MOVE.L (A3)+,D0 ; get next Device Control Entry handle
|
||
BEQ.S @nextEntry ; branch if no entry installed
|
||
MOVE.L D0,A2 ; DCE handle
|
||
MOVE.L (A2),D0 ; dereference handle
|
||
BEQ.S @nextEntry ; branch if null
|
||
MOVE.L D0,A1 ; A1 -> Device Control Entry
|
||
move.l d0, d4 ; save a pointer to the DCE
|
||
|
||
BTST #DRAMBased,DCtlFlags+1(A1) ; ROM-based?
|
||
MOVE.L DCtlDriver(A1), A1 ; driver ptr/handle
|
||
BEQ.S @1 ; br if ROM-based (A1 is a pointer)
|
||
MOVE.L A1, D0 ; be clean and check for 0 handle
|
||
BEQ.S @nextEntry ; skip if so
|
||
MOVE.L (A1), A1 ; deref handle
|
||
@1 MOVE.L A1, D0 ; is driver ptr nil?
|
||
BEQ.S @nextEntry ; br if so
|
||
|
||
LEA DrvrName(A1),A1 ; point A1 to driver name
|
||
MOVE.L D1, D0 ;
|
||
SWAP D0
|
||
MOVE.B (A1)+, D0 ; string 2 length
|
||
CMP.B D0, D1 ; are lengths the same?
|
||
BNE.S @nextEntry ; br if not (names shouldn't match if not)
|
||
_CmpString
|
||
BEQ @found ; found the driver!
|
||
|
||
@nextEntry SUBQ.W #1,D2 ; next unit table entry
|
||
BGT.S @CkInstLoop ; continue searching through all drivers
|
||
|
||
@found move.l d4, d0 ; return pointer to the DCE
|
||
bra.s @out ;
|
||
@notfound moveq #0, d0 ; driver not found
|
||
@out movem.l (sp)+, @workregs ; restore our working regs
|
||
rts
|
||
|
||
;_______________________________________________________________________________________ <K17>
|
||
; IsDriverOpen -- looks at driver flags in DCE to see if driver is open
|
||
;
|
||
; Inputs: d0 points to driver
|
||
; Outputs: CCR has Z=0 for open, Z=1 for not open
|
||
; d0 = pointer to the DCE
|
||
; Trashes: d0
|
||
; Called by: Sleep Table code in Power Mgr
|
||
; Calls: .ENET driver _Open and _Control
|
||
;
|
||
;_______________________________________________________________________________________
|
||
IsDriverOpen
|
||
@workregs REG a0-a3/d1-d4
|
||
movem.l @workregs, -(sp) ; save our working regs
|
||
|
||
movea.l d0, a0 ; point to the driver
|
||
move.w dCtlFlags(a0), d0 ; get driver flags
|
||
btst #5, d0 ; is the driver Open?
|
||
beq.s @notopen ; nope
|
||
|
||
@open moveq #1, d0 ; driver open
|
||
bra.s @out
|
||
@notopen moveq #0, d0 ; driver not open
|
||
@out movem.l (sp)+, @workregs ; restore our working regs
|
||
rts
|
||
|
||
;_______________________________________________________________________________________ <K17>
|
||
; EnetSleep/EnetWake -- Calls .ENET driver to sleep or wake SONIC
|
||
;
|
||
; Inputs: a1 points to return address
|
||
; Outputs: none
|
||
; Trashes: none
|
||
; Called by: Sleep Table code in Power Mgr
|
||
; Calls: .ENET driver _Open and _Control
|
||
;
|
||
;_______________________________________________________________________________________
|
||
ESleep EQU 254 ; Sleep the SONIC
|
||
EWake EQU 255 ; Wake the SONIC
|
||
EDetachPH EQU 248 ; Detach the protocol handler
|
||
|
||
EnetSleep
|
||
move.l #ESleep, d0 ; We're sleeping now
|
||
bra.s EnetWakeSleep
|
||
EnetWake
|
||
move.l #Ewake, d0 ; We're waking now
|
||
|
||
EnetWakeSleep
|
||
@workregs REG a0-a2/d1-d2
|
||
MOVEM.L @workregs,-(SP) ; save some reg's
|
||
move.l d0, d2 ; save our request
|
||
|
||
TestFor SONICExists ; do we have a SONIC?
|
||
beq.s @out ; no SONIC
|
||
lea EnetName, a0 ; point to driver name
|
||
moveq.l #0,d1
|
||
move.b (a0)+, d1 ; get the driver name length
|
||
bsr.w IsDriverInstalled ; is the .ENET driver installed?
|
||
beq.s @out ; driver not installed
|
||
bsr.w IsDriverOpen ; is the .ENET driver open?
|
||
beq.s @out ; driver not open
|
||
|
||
moveq #ioQElSize, d0 ; size the io stack frame
|
||
sub.w d0,sp ; Allocate IO stack frame
|
||
asr.w #1, d0 ; number of words in frame
|
||
subi.w #1, d0 ; our friend dbra
|
||
move.l sp, a2 ; point to start of frame
|
||
@clr clr.w (a2)+ ; clear frame
|
||
dbra d0, @clr
|
||
|
||
MOVE.L SP,A0 ; Save this place
|
||
LEA EnetName,A2 ; Get Ethernet refnum
|
||
MOVE.L A2,ioVNPtr(A0)
|
||
MOVE.B #fsCurPerm,ioPermssn(A0)
|
||
_Open
|
||
MOVE.w d2,csCode(A0) ; Sleep/Wake the Sonic
|
||
_Control ; (synchronously)
|
||
|
||
; MOVE #EDetachPH,CSCode(A0); Set code for detach PH
|
||
; MOVE #0,EProtType(A0) ; Set for 802.2
|
||
; _Control ; (synchronously)
|
||
|
||
add.w #ioQElSize,SP ; Allocate IO stack frame
|
||
|
||
@out movem.l (sp)+, @workregs ; restore the registers
|
||
JMP (A1) ; and return
|
||
|
||
|
||
EnetName dc.b 5 ; length of '.ENET'
|
||
dc.b '.ENET' ; driver name
|
||
|
||
|
||
;••••••••••••••••••••••••••••••••••••• Dispatch Tables ••••••••••••••••••••••••••••••••••••••••
|
||
|
||
IMPORT BasePRAM;••
|
||
IMPORT CPUSpeed;••
|
||
IMPORT ExternaVideoOnproc;••
|
||
IMPORT IdleDelay;••
|
||
IMPORT IdleDisable;••
|
||
IMPORT IdleEnable;••
|
||
IMPORT IdleMind
|
||
IMPORT IdleRead
|
||
IMPORT IdleState
|
||
IMPORT IdleUpdate;••
|
||
IMPORT IdleUpdateTrap;••
|
||
IMPORT ModemStatusRT ;••
|
||
IMPORT ModemTypeProc ;••
|
||
IMPORT PmgrTrap
|
||
IMPORT PowerMgrHook
|
||
IMPORT PDimScreens
|
||
IMPORT ScaledBattery
|
||
IMPORT ScsiDiskModeproc;••
|
||
IMPORT SecondaryInitproc
|
||
IMPORT SerialPower;••
|
||
|
||
ALIGN 4
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (PwrDispatchEnd-PwrDispatchVects) ; number of table entries
|
||
PwrDispatchVects
|
||
DC.L PmgrTrap-PwrDispatchVects ; Selector #0
|
||
DC.L IdleUpdate-PwrDispatchVects ; Selector #1
|
||
DC.L IdleDelay-PwrDispatchVects ; Selector #2
|
||
DC.L IdleMind-PwrDispatchVects ; Selector #3
|
||
DC.L IdleRead-PwrDispatchVects ; Selector #4
|
||
DC.L IdleEnable-PwrDispatchVects ; Selector #5
|
||
DC.L IdleDisable-PwrDispatchVects ; Selector #6
|
||
DC.L CPUSpeed-PwrDispatchVects ; Selector #7
|
||
DC.L BasePRAM-PwrDispatchVects ; Selector #8
|
||
DC.L ScaledBattery-PwrDispatchVects ; Selector #9
|
||
DC.L PowerMgrHook-PwrDispatchVects ; Selector #10
|
||
DC.L PDimScreens-PwrDispatchVects ; Selector #11
|
||
DC.L 0 ; Selector #12 (FactoryDisp patched on disk)
|
||
DC.L PrivateFeatures-PwrDispatchVects ; Selector #13
|
||
PwrDispatchEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (PMgrHookEnd-PMgrHookVects) ; number of table entries
|
||
PMgrHookVects
|
||
DC.L SecondaryInitproc-PMgrHookVects ; Selector #0
|
||
DC.L ScsiDiskModeproc-PMgrHookVects ; Selector #1
|
||
DC.L ExternaVideoOnproc-PMgrHookVects ; Selector #2
|
||
DC.L ModemTypeProc-PMgrHookVects ; Selector #3
|
||
PMgrHookEnd
|
||
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (PMgrOpTblEnd-PMgrOpTbl) ; number of table entries
|
||
PMgrOpTbl
|
||
DC.L PmgrTrap-PMgrOpTbl ; Pmgr Trap #A085
|
||
DC.L IdleUpdateTrap-PMgrOpTbl ; Pmgr Trap #A285
|
||
DC.L IdleState-PMgrOpTbl ; Pmgr Trap #A485
|
||
DC.L SerialPower-PMgrOpTbl ; Pmgr Trap #A685
|
||
PMgrOpTblEnd
|
||
|
||
|
||
;••••••••••••••••••••••••••••••••••••••• Sound VBL •••••••••••••••••••••••••••••••••••••••
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: SndWatch
|
||
;
|
||
; Inputs: A0 - pointer to VBL task queue element
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0-D1, A0
|
||
;
|
||
; Function: A VBL task called once every ten seconds that checks the sound latch for
|
||
; ASC new use. If so then sound power is turned on. If power is already on
|
||
; then then the latch is cleared. If the latch stays clear for two VBLs then
|
||
; sound power is turned off.
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
SndWatch ;MOVE.L PmgrBase,A2
|
||
;LEA SwVBLTask(A2),A0 ; Get pointer to vbl task
|
||
MOVE.W #SndWFreq,vblCount(A0) ; reset the counter
|
||
|
||
CLR.W -(SP) ; allocate a buffer on the stack
|
||
MOVE.L SP,-(SP) ; pmRBuffer
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
CLR.W -(SP) ; pmLength = 0
|
||
MOVE.W #SoundRead,-(SP) ; pmCommand = get sound latch state
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; send the command
|
||
LEA pmRBuffer+4(SP),SP ; toss the parameter block
|
||
|
||
MOVE.B (SP)+,D0 ; get the sound state
|
||
BEQ.S @NoSound ; -> no sound activity
|
||
|
||
MOVEQ #sndOnclrLtch,D1 ; assume the latch is set (turn sound on, clear latch)
|
||
BTST #1,D0 ; is the latch set?
|
||
BNE.S @SndActive ; -> yes
|
||
|
||
MOVEA.L PMgrBase,A0 ; no, sound's been on but now it's not
|
||
TST.B SysTaskFlag(A0) ; are the sound input primitives set up?
|
||
BEQ.S @NoInputs ; -> no, there can't be a sound input source selected
|
||
|
||
jsrTBL sndInputSource ; is a sound source selected?
|
||
TST.B D0
|
||
BNE.S @NoSound ; -> yes, sound input is active so don't power off sound
|
||
|
||
@NoInputs MOVEQ #soundOff,D1 ; nothing's on so turn sound off
|
||
@SndActive MOVE.B D1,-(SP) ; put the new sound state into a buffer
|
||
MOVE.L SP,-(SP) ; pmRBuffer
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
MOVE.W #1,-(SP) ; pmLength = 1
|
||
MOVE.W #SoundSet,-(SP) ; pmCommand = set sound state
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; send the command
|
||
LEA pmRBuffer+4+2(SP),SP ; toss the parameter block and buffer
|
||
|
||
TST.B D1 ; is sound turned off?
|
||
BEQ.S @NoSound ; -> yes
|
||
_IdleUpdateDispatch
|
||
@NoSound RTS ; all done
|
||
|
||
|
||
|
||
;••••••••••••••••••••••••••••••••••••••• IdleMind ••••••••••••••••••••••••••••••••••••••••
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: RunIdleRoutinesProc (IdleMind)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager variables
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0-D2, A0 (must preserve A1)
|
||
;
|
||
; Function: Runs IdleMind routines which are not based on LastAct. These routines
|
||
; have priority over the LastAct based ones with the exception of the
|
||
; countdown timers.
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
RunIdleRoutinesProc
|
||
BSR.S ChkDimming ; is it time to Power Down the Screen
|
||
BSR.S ChkHdSpinDown ; Is it time to Power Down the HD
|
||
RTS
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: ChkDimming
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager variables
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0-D2, A0 (must preserve A1)
|
||
;
|
||
; Function: Runs IdleMind routines which are not based on LastAct. These routines
|
||
; have priority over the LastAct based ones with the exception of the
|
||
; countdown timers.
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
ChkDimming
|
||
TST.B DimmingDisable(A2) ; IF counting semaphor = 0 THEN
|
||
BNE.S @Exit ;
|
||
|
||
BSR CurFrontProcEqual ; IF Process are the same THEN
|
||
BEQ.S @Exit ;
|
||
|
||
MOVE.L Ticks,D0 ; D0 = Current time
|
||
SUB.L LastUsrAct(A2),D0 ; Calc elapsed time since last user activity
|
||
BMI.S @hadActivityNoDim ; IF LastUsrAct > Tick THEN exit
|
||
MOVEQ #0,D1 ; Clear register
|
||
CMP.L DimmingWaitTime(A2),D0 ; IF TimeToWait <= TimeSinceLastAct THEN
|
||
BLO.S @hadActivityNoDim ;
|
||
BSET #PmgrDimStatus,PmgrFlags2(A2) ; Set the flag that we are dimmed
|
||
BNE.S @Exit ; IF not already dimmed THEN
|
||
MOVEQ #1,D0 ; Set Video for Power Down
|
||
BRA VidLowPwrSelect ; Set Video State
|
||
@hadActivityNoDim ; ELSE
|
||
BCLR #PmgrDimStatus,PmgrFlags2(A2) ; Clear the flag that we are dimmed
|
||
BEQ.S @Exit ; IF dimmed THEN
|
||
MOVEQ #0,D0 ; Set Video for Power Up
|
||
BRA VidLowPwrSelect ; Set Video State
|
||
@Exit ; ENDIF
|
||
RTS ; ENDIF
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: CheckCountDownTimer (IdleMind)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager variables
|
||
;
|
||
; Outputs: CCR - BEQ = not in countdown mode, BNE = go to sleep
|
||
;
|
||
; Trashes: D0
|
||
;
|
||
; Function: returns whether or not we're in a countdown condition
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
CheckCountDownTimer
|
||
CMP.B #4,LastLevel(A2) ; Test for level 4 sleep
|
||
BNE.S @NotCountingDown ; IF LastLevel != 4 THEN exit
|
||
CMP.B #SleepWait,Level4Cnt(A2) ; Test for standing 10 count
|
||
BLS.S @NotCountingDown ; IF Level4Cnt != 10 THEN exit
|
||
|
||
BSET #LowPowerSleep,PMgrFlags2(A2) ; set the low power sleep flag <H27>
|
||
MOVEQ #-1,D0 ; Set to force sleep
|
||
RTS ; Goodnight
|
||
|
||
@NotCountingDown
|
||
MOVEQ #0,D0 ; Set condition codes
|
||
RTS ; exit
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: ChkHdSpinDown (IdleMind)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager variables
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0-D2, A0 (must preserve A1)
|
||
;
|
||
; Function: determines whether to spin down the hard drive. If so, then jumps through
|
||
; a vector to spin down the hard drive
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
ChkHdSpinDown
|
||
MOVE.L LastHd(A2),D2 ; Get last HD activity
|
||
BEQ.S @Done ; IF DriveSpunDown THEN exit
|
||
|
||
MOVE.L HDvector(A2),D0 ; IF HDvector = null THEN <H15>
|
||
BEQ.S @Done ; exit
|
||
|
||
BTST #dockingStation,dockFlags(A2) ; are we in a docking station? <H15>
|
||
BNE.S @Done ; -> yes, never spin down the hard disk <H15>
|
||
|
||
BTST.B #HasCharger,Charger(A2) ; Check for Battery
|
||
BEQ.S @OnBattery ; IF !HasCharger THEN On Battery
|
||
|
||
BTST.B #ChargeSleep,SleepFlags(A2) ; Check if in ChargeSleep since no spin down while charging
|
||
BNE.S @Done ; IF ChargeSleep THEN exit
|
||
|
||
@OnBattery MOVEA.L D0,A0 ; get the spin down routine vector <H15>
|
||
MOVEQ #0,D0
|
||
MOVE.B HDTime(A2),D0 ; Get current HD timeout
|
||
BNE.S @hdTOok ; IF HDTime = null THEN
|
||
MOVE.B #DfltHDTime,D0 ; Set Default
|
||
@hdTOok MULU.W #pram2ticks,D0 ; Convert HD time out to ticks
|
||
MOVE.L Ticks,D1 ; Get current time
|
||
SUB.L D2,D1 ; D1 = elapsed time since last HD activity
|
||
CMP.L D1,D0 ; Check for HD timeout
|
||
BGT.S @Done ; IF elapsedTime > TimeOut THEN
|
||
JSR (A0) ; Call spin down routine
|
||
@Done RTS
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: ChkSleepTimeOut (IdleMind)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager variables
|
||
;
|
||
; Outputs: CCR - BEQ = continue, BNE = request sleep
|
||
;
|
||
; Trashes: D0
|
||
;
|
||
; Function: returns whether to issue a sleep request
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
ChkSleepTimeOut
|
||
BTST.B #HasCharger,Charger(A2) ; Check for Battery
|
||
BEQ.S @OnBattery ; IF !HasCharger THEN On Battery
|
||
|
||
BTST.B #ChargeSleep,SleepFlags(A2) ; Check if in ChargeSleep since no spin down while charging
|
||
BNE.S @Done ; IF ChargeSleep THEN exit
|
||
|
||
@OnBattery MOVEQ #0,D0
|
||
MOVE.B SleepTime(A2),D0 ; Get current Sleep timeout
|
||
BNE.S @slpTOok ; IF SleepTime = null THEN
|
||
MOVE.B #DfltSlpTime,D0 ; Set Default
|
||
@slpTOok MULU.W #pram2ticks,D0 ; Convert Sleep timeout to ticks
|
||
ADD.L LastAct(A2),D0 ; Calc time to go to sleep
|
||
CMP.L Ticks,D0 ; IF TimeToSleep >= CurrentTime THEN
|
||
BGE.S @Done ; exit
|
||
|
||
TST.B AutoSlpDisable(A2) ; IF counting semaphor > 0 THEN
|
||
BGT.S @Done ; exit
|
||
|
||
BSR CurFrontProcEqual ; IF Processes <> THEN
|
||
BEQ.S @Done ; exit
|
||
|
||
MOVEQ #-1,D0 ; Set a sleep request
|
||
RTS ; Try to Sleep
|
||
|
||
@Done MOVEQ #0,D0 ; Set condition codes
|
||
RTS ; Return
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: ChkIdle (IdleMind)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager variables
|
||
;
|
||
; Outputs: CCR - BEQ = continue, BNE = go idle
|
||
;
|
||
; Trashes: D0-D1
|
||
;
|
||
; Function: determines whether or not we're in idle
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
ChkIdle
|
||
BTST #dockNoPowerCycle,dockFlags(A2) ; is power cycling allowed? <H5>
|
||
BNE.S @hadActivity ; -> no, bail <H5>
|
||
|
||
TST.B MBState ; IF mouse down THEN
|
||
BEQ.S @UpdateOut ; Update Activity and Exit
|
||
|
||
TST.B watchCrsr(A2) ; IF watchCrsr THEN
|
||
BNE.S @UpdateOut ; Update Activity and Exit
|
||
|
||
BTST.B #IdleBit,SleepFlags(A2) ; IF idleDisable THEN
|
||
BNE.S @hadActivity ; Exit and set Activity
|
||
|
||
TST.B IdleFlagCnt(A2) ; IF IdleFlagCnt THEN
|
||
BGT.S @hadActivity ; Exit and set Activity
|
||
|
||
MOVE.L Ticks,D0 ; Mouse activity woke us up
|
||
SUB.L LastAct(A2),D0 ; Calc elapsed time since last activity
|
||
BMI.S @hadActivity ; IF LastAct > Tick THEN exit
|
||
MOVEQ #0,D1 ; Clear register
|
||
MOVE.W PwrCycWaitTime(A2),D1 ; Get the time to wait
|
||
CMP.L D0,D1 ; IF TimeToWait >= TimeSinceLastAct THEN
|
||
BGE.S @hadActivity ; Exit
|
||
@noActivity
|
||
MOVEQ #-1,D0 ; Set condition codes
|
||
RTS
|
||
@UpdateOut
|
||
MOVE.L Ticks,LastAct(A2) ; Update activity
|
||
@hadActivity
|
||
MOVEQ #0,D0 ; Set condition codes
|
||
RTS
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: CalcProgressive (IdleMind)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager variables
|
||
;
|
||
; Outputs: D1 - power cycling count
|
||
;
|
||
; Trashes: D0
|
||
;
|
||
; Function: calculates the number of power cycles we will follow through
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
CalcProgressive
|
||
MOVE.W PwrCycCounter(A2),D1 ; Power cycle a limited number of times
|
||
MOVE.L LastAct(A2),D0 ; D0 = LastAct
|
||
CMP.L PMgrScratch.ProgLastAct(A2),D0 ; Check for no activity
|
||
BNE.S @SomeAct ; Some Activity. Branch.
|
||
MOVE.W PMgrScratch.ProgCounter(A2),D1 ; Get current power cycle counter
|
||
ADD.W PwrCycProgGrow(A2),D1 ; Increment counter
|
||
CMP.W PwrCycProgMax(A2),D1 ; Set power cycle number to new value
|
||
BHS.S @SetMax ; Have we reached maximum value
|
||
|
||
MOVE.W D1,PMgrScratch.ProgCounter(A2) ; Save it for next time
|
||
RTS
|
||
|
||
@SetMax MOVE.W PwrCycProgMax(A2),D1 ; Set power cycling count to maximum level
|
||
RTS
|
||
|
||
@SomeAct MOVE.L D0,PMgrScratch.ProgLastAct(A2) ; Reset Activity for next check
|
||
MOVE.W D1,PMgrScratch.ProgCounter(A2) ; Reset counter
|
||
RTS
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: GoPowerCycle (IdleMind)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager variables
|
||
;
|
||
; Outputs: CCR - BEQ = continue, BNE = go idle
|
||
;
|
||
; Trashes: D0-D1
|
||
;
|
||
; Function: high-level power cycling call
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
GoPowerCycle
|
||
BSR.L SetSupervisorMode ; Set the machine to supervisor mode
|
||
MOVE.W D0,SaveCPUState.CPUSRsave(A2) ; Save the the SR
|
||
MOVE.L AutoInt7,SaveCPUState.CPUNMIsave(A2); Save the NMI Vector
|
||
MOVE.L ResetSP,-(SP) ; save current ResetSP
|
||
MOVE.L ResetPC,-(SP) ; save current ResetPC
|
||
BTST.B #hwCbFPU,HWCfgFlags ; Do we have an FPU?
|
||
BEQ.S @docycle ; IF hasFPU THEN
|
||
FMOVEM.L FPCR/FPSR/FPIAR,-(SP) ; Save them regs
|
||
FMOVEM.X FP0-FP7,-(SP) ; Save more them regs
|
||
@docycle MOVE.L LastAct(A2),-(SP) ; Save lastact as an activity flag
|
||
MOVE.L PwrCycProc(A2),A0 ; Get pointer to power cycling routine
|
||
JSR (A0) ; Go power cycle
|
||
MOVE.L (SP)+,D0 ; Get the previous lastact
|
||
CMP.L LastAct(A2),D0 ; Test for any activity
|
||
DBNE D1,@docycle ; Go through another loop if none
|
||
|
||
BTST.B #hwCbFPU,HWCfgFlags ; Do we have an FPU?
|
||
BEQ.S @noFPU ; IF hasFPU THEN
|
||
FMOVEM.X (SP)+,FP0-FP7 ; Restore more them regs
|
||
FMOVEM.L (SP)+,FPCR/FPSR/FPIAR ; Restore them regs
|
||
@noFPU MOVE.L (SP)+,ResetPC ; Restore the ResetPC
|
||
MOVE.L (SP)+,ResetSP ; Restore the ResetSP
|
||
MOVE.W SaveCPUState.CPUSRsave(A2),SR ; Restore the Status Register from power cycle
|
||
MOVE.L SaveCPUState.CPUNMIsave(A2),AutoInt7; Restore the NMI Vector
|
||
RTS
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: CurFrontProcEqual
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: CCR - BEQ = Processes Not Equal, BNE = Processes Equal
|
||
;
|
||
; Trashes: D0
|
||
;
|
||
; Function: returns whether the process managers front and current process are the same.
|
||
; This is important since we can neither sleep nor dim if they are different.
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
CurFrontEqFrame RECORD 0,DECR
|
||
FrontSerialNum DS.B ProcessSerialNumber
|
||
CurSerialNum DS.B ProcessSerialNumber
|
||
Result DS.W 1
|
||
CurFrontEqFrameSz EQU *
|
||
ENDR
|
||
|
||
CurFrontProcEqual
|
||
CurFrontProcRegs REG A0-A1
|
||
WITH CurFrontEqFrame
|
||
LINK A6,#CurFrontEqFrameSz ; Build StackFrame
|
||
MOVEM.L CurFrontProcRegs,-(SP) ; Save them regs
|
||
SUBQ.W #2,SP ; Make space for OSErr
|
||
PEA CurSerialNum(A6) ; Set pointer to CurSerialNum
|
||
_GetCurrentProcess ; Get Process Managers Current Process
|
||
PEA FrontSerialNum(A6) ; Set pointer to FrontSerialNum
|
||
_GetFrontProcess ; Get Process Managers Front Process
|
||
TST.W (SP) ; IF Error THEN
|
||
BNE.S @ProcessEqual ; NoFrontProcesses Exit, Assume ProcessEqual
|
||
|
||
PEA CurSerialNum(A6) ; Set pointer to CurSerialNum
|
||
PEA FrontSerialNum(A6) ; Set pointer to FrontSerialNum
|
||
PEA Result(A6) ; Set pointer to result
|
||
_SameProcess ; IF CurrentProcess = FrontProcess THEN
|
||
TST.W (SP) ; IF Err THEN
|
||
BNE.S @ProcessNotEqual ; ProcessNotEqual
|
||
TST.B Result(A6) ; ELSE
|
||
BEQ.S @ProcessNotEqual ; ProcessEqual
|
||
@ProcessEqual
|
||
MOVEQ #1,D0 ; Set condition codes for Processes Equal
|
||
BRA.S @Exit ; That's all folks
|
||
@ProcessNotEqual
|
||
MOVEQ #0,D0 ; Set condition codes for no sleep
|
||
@Exit
|
||
ADDQ.W #2,SP ; Clean up the stack
|
||
MOVEM.L (SP)+,CurFrontProcRegs ; Restore them regs
|
||
UNLK A6 ; Release stack fram
|
||
TST.L D0 ; Set Condition codes
|
||
RTS ; <5>
|
||
|
||
;••••••••••••••••••••••••••••••••••••••• PowerCycling •••••••••••••••••••••••••••••••••••••••
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
;
|
||
; PowerCycle
|
||
;
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
PowerCycleRegs REG D0-D7/A0-A6
|
||
|
||
WITH CPUStateRec
|
||
|
||
;———————————————————————————————————————————————————————————————————————
|
||
MACHINE MC68040
|
||
PowerCycle040
|
||
@SaveSetRegs REG D0-D7/A3-A6
|
||
MOVE.W SR,-(SP) ; Save status register
|
||
ORI.W #HiIntMask,SR ; No more interrupts
|
||
MOVEM.L PowerCycleRegs,-(SP) ; save them registers
|
||
MOVE.L PMgrBase,A2 ; get pointer to globals
|
||
LEA SaveCPUState(A2),A1 ; get pointer to SaveCPUState area
|
||
|
||
MOVEC CACR,D7 ; get current Cache Register
|
||
MOVEQ #0,D0 ; clear register
|
||
MOVEC D0,CACR ; disable caches
|
||
CPUSHA bc ; flush both caches entirely
|
||
|
||
|
||
; Get CPU Internal State Registers
|
||
MOVEC URP,D0 ; Save User Root Pointer
|
||
MOVEC SRP,D1 ; Save Supervisor Root Pointer
|
||
MOVEC TC,D2 ; Save TC
|
||
MOVEC DTT0,D3 ; Save Data TT0
|
||
MOVEC DTT1,D4 ; Save Data TT1
|
||
MOVEC ITT0,D5 ; Save Instruction TT0
|
||
MOVEC ITT1,D6 ; Save Instruction TT1
|
||
|
||
MOVEC VBR,A3 ; Save vector base reg
|
||
MOVE.L AutoInt7(A3),-(SP) ; Save the NMI Vector
|
||
MOVEC USP,A4 ; Save User Stack Pointer
|
||
MOVEC MSP,A5 ; Save Master Stack Pointer
|
||
MOVEC ISP,A6 ; Save Interrupt Stack Pointer
|
||
|
||
MOVEM.L @SaveSetRegs,(A1) ; Save all them special regs
|
||
|
||
; Last Chance for SCC
|
||
MOVEQ #(1<<SerPortAPwr)+\
|
||
(1<<SerPortBPwr),D1 ; IF SCC_Pwr THEN
|
||
AND.B PmgrFlags2(A2),D1 ; SCC may have data
|
||
BEQ.S @NoSCC ; ELSE branch
|
||
|
||
BTST #0,([SccRd]) ; IF SCC has Data THEN
|
||
BNE.S @DontCycle ; Don't kill the power
|
||
|
||
@NoSCC
|
||
MOVE.L PwrCycRestore(A2),\
|
||
AutoInt7(A3) ; Set NMIVec to our PwrCycling NMI handler
|
||
MOVE.L PwrCycRestore(A2),\
|
||
ResetPC ; Set the PC to restore code when coming up
|
||
MOVE.L A1,ResetSP ; Save it in ResetSP for powering up
|
||
|
||
; Kill Power
|
||
MOVE.L PowerCycleReg(A2),A0 ; Get pointer to Pratt Nap mode register
|
||
MOVE.B PwrCycRegValue(A2),(A0) ; set the magic value <K22>
|
||
BRA.S * ; Wait for the drugs to take effect
|
||
|
||
@DontCycle
|
||
MOVEC D0,CACR ; restore them caches
|
||
ADDQ.W #4,SP ; clear the NMI from the stack
|
||
MOVEM.L (SP)+,PowerCycleRegs ; Restore them regs
|
||
MOVE.W (SP)+,SR
|
||
RTS
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
MACHINE MC68030
|
||
PowerCycle030
|
||
MOVE.W SR,-(SP)
|
||
OR.W #HiIntMask,SR ; No more interrupts
|
||
|
||
MOVEM.L PowerCycleRegs,-(SP) ; save all for now, Save only the important registers
|
||
|
||
MOVEC CACR,D0 ; Now save cache regs
|
||
OR.W #(1<<11)+(1<<3),D0 ; Flush caches upon return
|
||
MOVEC CAAR,D1 ;
|
||
MOVEC VBR,A0 ; Also save vector base
|
||
MOVE.L USP,A1 ; and alternats stack pointers
|
||
MOVEC MSP,A2 ; .
|
||
|
||
MOVEM.L D0/D1/A0-A2,-(SP) ; Save some cool registers
|
||
|
||
MOVEQ #0,D0
|
||
MOVEC D0,VBR ; need to put return addr right at the start
|
||
|
||
MOVE.L PmgrBase,A1 ; get pmgr locals
|
||
MOVEA.L PowerCycleReg(A1),A2 ; Get powercycling register in A2 <H29>
|
||
|
||
MOVE.L PwrCycRestore(A1),ResetPC; Set the PC to restore code when coming up
|
||
|
||
MOVE.L SP,SaveCPUState.CPUISPsave(A1) ; save old SP
|
||
PMOVE TC,SaveCPUState.CPUMMUTCsave(A1); Save TC
|
||
PMOVE CRP,SaveCPUState.CPUMMUCRPsave(A1) ; Save CRP
|
||
PMOVE TT1,SaveCPUState.CPUMMUTT1save(A1) ; Save TT1
|
||
PMOVE TT0,SaveCPUState.CPUMMUTT0save(A1) ; Save TT2
|
||
|
||
MOVE.L PmgrVarPhysPtr(A1),A3 ; Get the physical address of the PMgr Globasl <25> HJR
|
||
LEA SaveCPUState(A3),A3 ; PwrCycGlobals-4 Byte below must be free for NMIStkFrm <25> HJR
|
||
MOVE.L A3,ResetSP ; Save it in ResetSP for powering up <25> HJR
|
||
MOVE.L PwrCycRestore(A1),AutoInt7 ; Set NMIVec to our PwrCycling NMI handler <24> HJR
|
||
|
||
MOVE.L SccRd,A3 ; SCC may have data to get
|
||
BTST #0,(A3) ; Is there any SCC Data
|
||
BNE.S @DontCycle ; Yes.. Forget killing the power
|
||
|
||
MOVE.L D0,([RomBase]) ; Clear the Bus. Yes I Know it's in ROM... <6> HJR
|
||
MOVE.L D0,(A2) ; Pull the pin <6> HJR
|
||
BRA.S * ; Wait for the drugs to take effect
|
||
|
||
@DontCycle MOVEC A0,VBR ; Restore the VBR <37> HJR
|
||
MOVE.L SaveCPUState.\
|
||
CPUNMIsave(A1),AutoInt7 ; Restore the NMI Vector <33> HJR
|
||
ADDA.L #5*4,SP ; Restore stack state
|
||
MOVEM.L (SP)+,PowerCycleRegs ; Restore them regs
|
||
MOVE.W (SP)+,SR
|
||
RTS
|
||
|
||
;———————————————————————————————————————————————————————————————————————
|
||
PowerCycle020
|
||
MOVE.W SR,-(SP)
|
||
OR.W #HiIntMask,SR ; No more interrupts
|
||
|
||
MOVEM.L PowerCycleRegs,-(SP) ; save all for now, Save only the important registers
|
||
|
||
MOVEC CACR,D0 ; Now save cache regs
|
||
OR.W #(1<<11)+(1<<3),D0 ; Flush caches upon return
|
||
MOVEC CAAR,D1 ;
|
||
MOVEC VBR,A0 ; Also save vector base
|
||
MOVE.L USP,A1 ; and alternats stack pointers
|
||
MOVEC MSP,A2 ; .
|
||
|
||
MOVEM.L D0/D1/A0-A2,-(SP) ; Save some cool registers
|
||
|
||
MOVEQ #0,D0
|
||
MOVEC D0,VBR ; need to put return addr right at the start
|
||
|
||
MOVE.L PmgrBase,A1 ; get pmgr locals
|
||
MOVEA.L PowerCycleReg(A1),A2 ; Get powercycling register in A1 <H29>
|
||
|
||
MOVE.L PwrCycRestore(A1),ResetPC; Set the PC to restore code when coming up
|
||
MOVE.L SP,ResetSP ; Save the stack pointer in ResetSP for power up
|
||
MOVE.L PwrCycRestore(A1),AutoInt7; Set NMIVec to our PwrCycling NMI handler <24> HJR
|
||
|
||
MOVE.L SccRd,A3 ; SCC may have data to get
|
||
BTST #0,(A3) ; Is there any SCC Data
|
||
BNE.S @DontCycle ; Yes.. Forget killing the power
|
||
|
||
MOVE.L D0,([RomBase]) ; Clear the Bus. Yes I Know it's in ROM... <6> HJR
|
||
MOVE.L D0,(A2) ; Pull the pin <6> HJR
|
||
BRA.S * ; Wait for the drugs to take effect
|
||
|
||
@DontCycle
|
||
MOVEC A0,VBR ; Restore the VBR <37> HJR
|
||
MOVE.L SaveCPUState.\
|
||
CPUNMIsave(A1),AutoInt7 ; Restore the NMI Vector <33> HJR
|
||
ADDA.L #5*4,SP ; Restore stack state
|
||
MOVEM.L (SP)+,PowerCycleRegs ; Restore them regs
|
||
MOVE.W (SP)+,SR
|
||
RTS
|
||
|
||
;———————————————————————————————————————————————————————————————————————
|
||
MACHINE MC68040
|
||
Restore040
|
||
@SaveSetRegs REG D0-D7/A3-A6
|
||
MOVEM.L (SP),@SaveSetRegs ; get some saved special regs
|
||
MOVEC D0,URP ; restore User Root Pointer
|
||
MOVEC D1,SRP ; restore Supervisor Root Pointer
|
||
MOVEC D3,DTT0 ; restore Data TT0
|
||
MOVEC D4,DTT1 ; restore Data TT1
|
||
MOVEC D5,ITT0 ; restore Instruction TT0
|
||
MOVEC D6,ITT1 ; restore Instruction TT1
|
||
MOVEC A3,VBR ; restore VBR
|
||
MOVEC A4,USP ; restore User Stack pointer
|
||
MOVEC A5,MSP ; restore Master Stack pointer
|
||
MOVEC A6,ISP ; restore Interrupt Stack pointer
|
||
|
||
PFLUSHA ; flush ATC
|
||
MOVEC D2,TC ; restore TC
|
||
|
||
CINVA BC ; invalidate both caches
|
||
MOVEC D7,CACR ; Restore Vital CPU registers
|
||
MOVE.L (SP)+,AutoInt7(A3) ; Restore the NMI Vector
|
||
MOVEM.L (SP)+,PowerCycleRegs ; Restore them regs
|
||
MOVE.W (SP)+,SR
|
||
RTS
|
||
|
||
;———————————————————————————————————————————————————————————————————————
|
||
MACHINE MC68030
|
||
Restore030
|
||
MOVE.L ResetSP,A0 ; Save the Power Manager globals in the stack <25> HJR
|
||
|
||
MOVE.L CPUISPsave(A0),SP ; Restore the stack to the previous life
|
||
PMOVE CPUMMUTT0save(A0),TT0 ; "Pop" the MMU regs of the video stack
|
||
PMOVE CPUMMUTT1save(A0),TT1
|
||
PMOVE CPUMMUCRPsave(A0),CRP
|
||
PMOVE CPUMMUTCsave(A0),TC ; MMU is now restored, we have memory
|
||
|
||
MOVEM.L (SP)+,D0/D1/A0-A2
|
||
|
||
MOVEC D0,CACR ; Restore Vital CPU registers
|
||
MOVEC D1,CAAR
|
||
MOVEC A0,VBR
|
||
MOVEC A1,USP
|
||
MOVEC A2,MSP
|
||
|
||
MOVE.L PMgrBase,A0 ; Get the Globals <24> HJR
|
||
MOVE.L SaveCPUState.\
|
||
CPUNMIsave(A0),AutoInt7 ; Restore the NMI Vector <24> HJR
|
||
|
||
MOVEM.L (SP)+,PowerCycleRegs ; Restore them regs
|
||
MOVE.W (SP)+,SR
|
||
RTS
|
||
|
||
|
||
|
||
;———————————————————————————————————————————————————————————————————————
|
||
Restore020
|
||
MOVEM.L (SP)+,D0/D1/A0-A2 ; restore cool registers
|
||
MOVEC D0,CACR ; Restore Vital CPU registers
|
||
MOVEC D1,CAAR
|
||
MOVEC A0,VBR
|
||
MOVE.L A1,USP
|
||
MOVEC A2,MSP
|
||
|
||
MOVE.L PMgrBase,A0 ; Get the Globals <25> HJR
|
||
MOVE.L SaveCPUState.\
|
||
CPUNMIsave(A0),AutoInt7 ; Restore the NMI Vector <25> HJR
|
||
|
||
MOVEM.L (SP)+,PowerCycleRegs ; Restore them regs
|
||
MOVE.W (SP)+,SR
|
||
RTS
|
||
|
||
ENDWITH
|
||
|
||
;•••••••••••••••••••••••••••••••••••••••• Sleep ••••••••••••••••••••••••••••••••••••••••••
|
||
;
|
||
; The following are a set of possible routines that are used to save the state, or
|
||
; set necessary conditions in order for the machine to sleep. For each machine there
|
||
; is a corresponding table of entries which point to the necessary routines. The
|
||
; register convention is that A0/A1 must be PRESERVED throughout all routines. All
|
||
; other register can be trashed and should not be relied upon.
|
||
;
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; _Sleep routine to power down hard drive (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
SleepHD MOVEA.L PMgrBase,A2 ; get pointer to globals
|
||
BTST #HDPowerOn,PmgrFlags(A2); Clear the Hard Disk semaphor
|
||
BEQ.S @SkipHDSpinDown ; If set, spin down the hard disk
|
||
MOVE.L HDvector(A2),D0 ; Does the vector exist
|
||
BEQ.S @SkipHDSpinDown ; Nope... Go on
|
||
MOVEA.L D0,A2 ; Get vector to hard disk spin down task
|
||
JSR (A2) ; Spin down hard disk
|
||
@SkipHDSpinDown
|
||
JMP (A1) ; and return
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; _Sleep routine to save the VIA1 registers (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
SaveVIA1 MOVEA.L VIA,A2
|
||
MOVE.B vBufB(A2),D0 ; load up all the VIA registers
|
||
MOVE.B vDIRB(A2),D1
|
||
MOVE.B vBufA(A2),D2
|
||
MOVE.B vDIRA(A2),D3
|
||
MOVE.B vIER(A2),D4
|
||
ORI.B #(1<<7),D4 ; set the Via Set bit so that value will stick
|
||
MOVE.B vACR(A2),D5
|
||
MOVE.B vPCR(A2),D6
|
||
MOVEM.W D0-D6,-(SP) ; save the VIA registers
|
||
JMP (A1) ; and return
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; _Sleep routine to save the VIA2 registers (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
SaveVIA2 MOVEA.L VIA2,A2
|
||
MOVE.B vBufB(A2),D0 ; load up all the VIA registers
|
||
MOVE.B vDIRB(A2),D1
|
||
MOVE.B vBufA(A2),D2
|
||
MOVE.B vDIRA(A2),D3
|
||
MOVE.B vIER(A2),D4
|
||
ORI.B #(1<<7),D4 ; set the Via Set bit so that value will stick
|
||
MOVE.B vACR(A2),D5
|
||
MOVE.B vPCR(A2),D6
|
||
MOVEM.W D0-D6,-(SP) ; save the VIA registers
|
||
BCLR.B #v2CDis2,vBufB(A2) ; lower the cache disable line to save power
|
||
JMP (A1) ; and return
|
||
|
||
IF hasNiagra THEN
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Dartanian ASC/Batman save code (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
SaveASCBatmanDart ;
|
||
MOVEA.L UnivInfoPtr,A2 ; point to the ProductInfo table,
|
||
ADDA.L DecoderInfoPtr(A2),A2 ; then to the DecoderInfo table,
|
||
MOVEA.L JAWSAddr(A2),A2 ; then to the Niagra base address,
|
||
ADDA.L #NiagraGUR+PontiSndCtl,A2 ; and finally to the sound register
|
||
;
|
||
BSET #PontiSndPWMOff,(A2) ; turn off power amps
|
||
ENDIF
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; _Sleep routine to save the ASC and Batman registers (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
batmanSnd EQU $B0 ; version number for Batman Chip
|
||
|
||
SaveASCBatman
|
||
MOVEA.L ASCBase,A2 ; point to the base of the ASC/Batman
|
||
MOVE.B ascMode(A2),-(SP) ; save the chip mode
|
||
MOVE.B ascVolControl(A2),-(SP) ; save the external sound volume control
|
||
MOVE.B $80A(A2),-(SP) ; save channel A play/record register
|
||
CMPI.B #batmanSnd,ascVersion(A2) ; is this a Batman?
|
||
BNE.S @NotBatman ; -> nope, that's all we save
|
||
MOVE.B ascTestReg(A2),-(SP) ; save test control register
|
||
|
||
MOVE.L A1,D2 ; save the return address
|
||
|
||
MOVEQ.L #0,D1 ; reg D1 = channel offset (0=A,$20=B)
|
||
@saveBatReg LEA $F09+1(A2),a1 ; save Batman channel control regs ($F00-$F09)
|
||
ADDA.L D1,a1 ; add channel offset for A or B
|
||
MOVEQ.L #10-1,D0 ;
|
||
@saveBatC MOVE.B -(a1),-(SP) ;
|
||
DBRA D0,@saveBatC ;
|
||
LEA $F17+1(A2),a1 ; save CDXA coefficient regs ($F10-$F17)
|
||
ADDA.L D1,a1 ; add channel offset for A or B
|
||
MOVEQ.L #8-1,D0 ;
|
||
@saveCDXA MOVE.B -(a1),-(SP) ;
|
||
DBRA D0,@saveCDXA ;
|
||
TST.L D1 ; channel A or B
|
||
BNE.S @BatmanDone ; already saved both channels A and B
|
||
MOVE.L #$20,D1 ; set channel offset to channel B
|
||
BRA.S @saveBatReg ; save channel B registers
|
||
@BatmanDone
|
||
|
||
MOVEA.L D2,A1 ; restore the return address
|
||
@NotBatman JMP (A1) ; and return
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; _Sleep routine to poweroff Sound (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
SoundPowerDown ;
|
||
MOVEA.L UnivInfoPtr,A2 ; point to the ProductInfo table,
|
||
ADDA.L DecoderInfoPtr(A2),A2 ; then to the DecoderInfo table,
|
||
MOVEA.L JAWSAddr(A2),A2 ; then to the Niagra base address,
|
||
ADDA.L #NiagraGUR+PontiSndCtl,A2 ; and finally to the sound register
|
||
;
|
||
BSET #PontiSndLatchClr,(A2) ; pulse (positive) latch clear bit
|
||
BCLR #PontiSndLatchClr,(A2) ;
|
||
;
|
||
BCLR #PontiSndPwrOn,(A2) ; turn off sound power
|
||
;
|
||
JMP (A1) ; and return
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; _Sleep routine to save the video registers (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
SaveLCD Moveq #0,D1 ; Say we’re about to sleep.
|
||
Bsr SaveRestoreLCD ; Go save the world.
|
||
Jmp (A1) ; Vamoose.
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; _Sleep routine to save the FPU registers (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
SaveFPU BTST #hwCbFPU,HWCfgFlags ; do we have an FPU?
|
||
BEQ.S @NoFPU ; -> no
|
||
FMOVEM.X FP0-FP7,-(SP) ; save general purpose registers
|
||
FMOVEM.L FPCR/FPSR/FPIAR,-(SP) ; save FPU condition registers
|
||
@NoFPU JMP (A1) ; and return
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; _Sleep routine to save the 68040 registers (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
SaveSlp040
|
||
@SaveSetRegs REG D0-D7/A3-A6
|
||
MACHINE MC68040
|
||
|
||
MOVEA.L PmgrBase,A2 ; get pointer to globals
|
||
MOVEC CACR,D7 ; get current Cache Register
|
||
MOVEQ #0,D0 ; clear register
|
||
MOVEC D0,CACR ; disable caches
|
||
CPUSHA BC ; flush both caches entirely
|
||
|
||
; Get CPU Internal State Registers
|
||
MOVEC URP,D0 ; Save User Root Pointer
|
||
MOVEC SRP,D1 ; Save Supervisor Root Pointer
|
||
MOVEC TC,D2 ; Save TC
|
||
MOVEC DTT0,D3 ; Save Data TT0
|
||
MOVEC DTT1,D4 ; Save Data TT1
|
||
MOVEC ITT0,D5 ; Save Instruction TT0
|
||
MOVEC ITT1,D6 ; Save Instruction TT1
|
||
MOVEC VBR,A3 ; Save vector base reg
|
||
MOVEC USP,A4 ; Save User Stack Pointer
|
||
MOVEC MSP,A5 ; Save Master Stack Pointer
|
||
MOVEC ISP,A6 ; Save Interrupt Stack Pointer
|
||
|
||
MOVEM.L @SaveSetRegs,SaveCPUState(A2) ; Save all them special regs
|
||
JMP (A1) ; and return
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; _Sleep routine to save the 68030 registers (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
SaveSlp030
|
||
@SaveSetRegs REG D0-D5
|
||
MACHINE MC68030
|
||
|
||
MOVEA.L PmgrBase,A2 ; Get pointer to our globals
|
||
PMOVE CRP,SaveCPUState.CPUMMUCRPsave(A2); Save CRP
|
||
PMOVE TC,SaveCPUState.CPUMMUTCsave(A2) ; Save TC
|
||
PMOVE TT0,SaveCPUState.CPUMMUTT0save(A2); Save TT2
|
||
PMOVE TT1,SaveCPUState.CPUMMUTT1save(A2); Save TT1
|
||
|
||
MOVEC VBR,D0 ; Also save vector base
|
||
MOVEC USP,D1 ; and alternats stack pointers
|
||
MOVEC MSP,D2 ; .
|
||
MOVEC ISP,D3 ; and old sp
|
||
MOVEC CACR,D4 ; Now save cache regs
|
||
OR.W #(1<<11)+(1<<3),D4 ; Flush caches upon return
|
||
MOVEC CAAR,D5 ;
|
||
|
||
MOVEM.L @SaveSetRegs,\
|
||
SaveCPUState.CPUVBRsave(A2) ; Save some cool registers
|
||
JMP (A1) ; and return
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; _Sleep routine to setup state info before going to sleep (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
SaveSleepInfo
|
||
MOVEA.L PMgrBase,A2 ; Get pointer to our globals
|
||
MOVE.L #SleepConst,SleepSaveFlag(A2) ; set a flag that sleep has been entered
|
||
JMP (A1)
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; _Sleep routine to send a sleep command to the PMGR (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
IF hasMSC THEN
|
||
SendSleepLP PEA 'BORG' ; low power sleep signature
|
||
BCLR #LowPowerSleep,PMgrFlags2(A2) ; are we sleeping because of a low power condition?
|
||
BNE.S HaveSig ; -> yes
|
||
ADDQ.W #4,SP ; no, toss the low power signature
|
||
ENDIF
|
||
SendSleep MOVE.L A0,-(SP) ; save this dam thing
|
||
PEA SleepSig ; put the sleep signature into a buffer
|
||
HaveSig MOVE.L SP,-(SP) ; pmRBuffer
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
MOVE.W #4,-(SP) ; pmLength = 4
|
||
MOVE.W #SleepReq,-(SP) ; pmCommand = sleep…
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; send the sleep command
|
||
LEA pmRBuffer+4+4(SP),SP ; clean up the stack
|
||
MOVEA.L (SP)+,A0 ; restore it
|
||
JMP (A1) ; and return
|
||
|
||
|
||
;•••••••••••••••••••••••••••••••••••••••• Wakeup •••••••••••••••••••••••••••••••••••••••••
|
||
;
|
||
; The following are a set of possible routines that are used to restore the state, or
|
||
; set necessary conditions in order for the machine to wake from sleep. For each machine
|
||
; there is a corresponding table of entries which point to the necessary routines. The
|
||
; register convention is that A0/A1 must be PRESERVED throughout all routines. All
|
||
; other register can be trashed and should not be relied upon.
|
||
;
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Wakeup routine to restore the MMU registers for '040 (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
RestoreSlp040
|
||
@RestoreSetRegs REG D0-D7/A3-A6
|
||
MACHINE MC68040
|
||
|
||
MOVEA.L PmgrBase,A2 ; get pointer to our Globals
|
||
MOVEM.L SaveCPUState(A2),@RestoreSetRegs; get some saved special regs
|
||
MOVEC D0,URP ; restore User Root Pointer
|
||
MOVEC D1,SRP ; restore Supervisor Root Pointer
|
||
MOVEC D3,DTT0 ; restore Data TT0
|
||
MOVEC D4,DTT1 ; restore Data TT1
|
||
MOVEC D5,ITT0 ; restore Instruction TT0
|
||
MOVEC D6,ITT1 ; restore Instruction TT1
|
||
MOVEC A3,VBR ; restore VBR
|
||
MOVEC A4,USP ; restore User Stack pointer
|
||
MOVEC A5,MSP ; restore Master Stack pointer
|
||
MOVEC A6,ISP ; restore Interrupt Stack pointer
|
||
|
||
PFLUSHA ; flush ATC
|
||
MOVEC D2,TC ; restore TC
|
||
|
||
CINVA BC ; invalidate both caches
|
||
MOVEC D7,CACR ; Restore Vital CPU registers
|
||
MOVEQ #0,D7 ; Clear register for WakeRoutine to work
|
||
JMP (A1) ; return
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Wakeup routine to restore the MMU registers for '030 (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
RestoreSlp030
|
||
@RestoreSetRegs REG D0-D5
|
||
MACHINE MC68030
|
||
|
||
MOVEA.L PmgrBase,A2 ; get pointer to our Globals
|
||
MOVEM.L SaveCPUState.CPUVBRsave(A2),\
|
||
@RestoreSetRegs ; get some special registers
|
||
|
||
MOVEC D0,VBR ; restore the Vector Base Register
|
||
MOVEC D1,USP ; restore the User Stack Pointer
|
||
MOVEC D2,MSP ; restore the Master Stack Pointer
|
||
MOVEC D3,ISP ; restore the Interrupt Stack Pointer
|
||
|
||
PMOVE SaveCPUState.CPUMMUCRPsave(A2),\;
|
||
CRP ; restore CRP
|
||
PMOVE SaveCPUState.CPUMMUTT1save(A2),\;
|
||
TT1 ; restore TT1
|
||
PMOVE SaveCPUState.CPUMMUTT0save(A2),\;
|
||
TT0 ; restore TT2
|
||
PFLUSHA ; flush ATC
|
||
PMOVE SaveCPUState.CPUMMUTCsave(A2),\ ;
|
||
TC ; restore TC and turn on MMU
|
||
|
||
MOVEC D4,CACR ; restore the Cache register
|
||
MOVEC D5,CAAR ; restore the Cache Address register
|
||
JMP (A1) ; and return
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Wakeup routine to restore the FPU registers (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
RestoreFPU
|
||
BTST #hwCbFPU,HWCfgFlags ; do we have an FPU?
|
||
BEQ.S @NoFPU ; -> no
|
||
FMOVEM.L (SP)+,FPCR/FPSR/FPIAR ; restore FPU condition registers
|
||
FMOVEM.X (SP)+,FP0-FP7 ; restore general purpose registers
|
||
@NoFPU JMP (A1) ; and return
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Wakeup routine to save the video registers (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
RestoreLCD
|
||
MOVEQ #1,D1 ; Say we’re about to sleep.
|
||
BSR SaveRestoreLCD ; Go save the world.
|
||
JMP (A1) ; Vamoose.
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Wakeup routine to restore the ASC and Batman registers (A1 = return address)
|
||
;
|
||
; These registers must be restored in the given order. If the CDXA registers
|
||
; are restored in the incorrect order Batman will be confused and not function
|
||
; appropriately. Also if the FIFO control register is set prior to the SRC
|
||
; Time Increment it will not function properly.
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
RestoreASCBatman
|
||
MOVE.L ASCBase,A2
|
||
CMPI.B #batmanSnd,ascVersion(A2) ; is this a Batman?
|
||
BNE.S @NotBatman ; -> nope, that's all we save
|
||
MOVE.L A1,D2 ; save the return address
|
||
|
||
MOVEQ #$20,D1 ; reg D1 = channel offset (0=A,$20=B) <H24>
|
||
@restBatReg LEA $F10(a2),a1 ; restore CDXA coefficient regs ($F10-$F17) <H24>
|
||
ADDA.L D1,a1 ; add channel offset for A or B <H24>
|
||
MOVEQ #8-1,D0 ; <H24>
|
||
@restCDXA MOVE.B (SP)+,(a1)+ ; <H24>
|
||
DBRA D0,@restCDXA ; <H24>
|
||
|
||
LEA $F00(a2),a1 ; restore Batman channel control regs ($F00-$F09) <H24>
|
||
ADDA.L D1,a1 ; add channel offset for A or B <H24>
|
||
MOVEQ #10-1,D0 ; <H24>
|
||
@restBatC MOVE.B (SP)+,(a1)+ ; <H24>
|
||
DBRA D0,@restBatC ; <H24>
|
||
TST.L D1 ; Are we done with both channels <H24>
|
||
BEQ.S @restCont ; Yes??? Go on... <H24>
|
||
MOVEQ #0,D1 ; Set Channel A Offset <H24>
|
||
BRA.S @restBatReg ; restore channel B registers <H24>
|
||
@restCont
|
||
MOVE.B (SP)+,ascTestReg(a2) ; restore test control register <H24>
|
||
MOVEA.L D2,A1 ; restore return address <H24>
|
||
|
||
@NotBatman MOVE.B (SP)+,$80A(A2) ; restore Channel A play/record register
|
||
MOVE.B (SP)+,ascVolControl(A2) ; restore external sound volume control
|
||
MOVE.B (SP)+,ascMode(A2) ; restore chip mode
|
||
JMP (A1)
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Reenable Sound amps (A1 = return address) <H29>
|
||
;———————————————————————————————————————————————————————————————————————————————————————— |
|
||
RestoreDartAmp ; V
|
||
MOVEA.L UnivInfoPtr,A0 ; point to the ProductInfo table,
|
||
ADDA.L DecoderInfoPtr(A0),A0 ; then to the DecoderInfo table,
|
||
MOVEA.L JAWSAddr(A0),A0 ; then to the Niagra base address,
|
||
ADDA.L #NiagraGUR+PontiSndCtl,A0 ; and finally to the sound register
|
||
; |
|
||
BSET #PontiSndLatchClr,(A0) ; pulse (positive) latch clear bit <H30>
|
||
BCLR #PontiSndLatchClr,(A0) ; <H30>
|
||
; <H30>
|
||
BCLR #PontiSndPwrOn,(A0) ; turn off sound power <H30>
|
||
; |
|
||
BCLR #PontiSndPWMOff,(A0) ; turn on power amps V
|
||
JMP (A1) ; done <H29>
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Wakeup routine to restore misc PmgrVars (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
RestorePmgrMisc
|
||
MOVE.L A1,-(SP) ; push return address on stack
|
||
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 #batteryRead,-(SP) ; pmCommand = batteryRead <H18>
|
||
MOVEA.L SP,A0 ; point to the parameter block <H18>
|
||
_PMgrOp ; send the command <H18>
|
||
MOVEA.L pmRBuffer(A0),A2 ; get pointer to receive buffer
|
||
MOVEA.L PmgrBase,a0 ; get pointer to globals
|
||
MOVE.B (A2),Charger(A0) ; Initialize charger state
|
||
LEA pmBlkSize(SP),SP ; Remove stack frame
|
||
RTS ; that's all folks
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Wakeup routine to restore the VIA1 registers (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
RestoreVIA1
|
||
MOVEA.L VIA,A2
|
||
MOVEM.W (SP)+,D0-D6 ; get the saved registers off the stack
|
||
MOVE.B D0,vBufB(A2) ; and stuff them back into the VIA
|
||
MOVE.B D1,vDIRB(A2)
|
||
MOVE.B D2,vBufA(A2)
|
||
MOVE.B D3,vDIRA(A2)
|
||
MOVE.B D4,vIER(A2)
|
||
MOVE.B D5,vACR(A2)
|
||
MOVE.B D6,vPCR(A2)
|
||
|
||
MOVE.B vT2CH(A2),vT2CH(A2) ; restart the timer
|
||
MOVE.B vT1CH(A2),vT1CH(A2)
|
||
JMP (A1)
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Wakeup routine to restore the VIA2 registers (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
RestoreVIA2
|
||
MOVEA.L VIA2,A2
|
||
MOVEM.W (SP)+,D0-D6 ; get the saved registers off the stack
|
||
MOVE.B D0,vBufB(A2) ; and stuff them back into the VIA
|
||
MOVE.B D1,vDIRB(A2)
|
||
MOVE.B D2,vBufA(A2)
|
||
MOVE.B D3,vDIRA(A2)
|
||
MOVE.B D4,vIER(A2)
|
||
MOVE.B D5,vACR(A2)
|
||
MOVE.B D6,vPCR(A2)
|
||
JMP (A1)
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Wakeup routine for clearing interrupts (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
WakeClrInts
|
||
MOVEM.L A0-A1,-(SP) ; save very important registers
|
||
MOVEA.L VIA,A0 ; get VIA base address
|
||
MOVE.B #(1<<ifIRQ)+(1<<ifCB1),vIFR(A0) ; clear PMGR interrupts
|
||
LEA -12(SP),SP ; read any pending interrupt data from the PMGR so we
|
||
MOVE.L SP,A0 ; don't hang in ADBReInit
|
||
ADDQ.L #2,A0 ;
|
||
MOVEQ #ReadINT,D0 ; PMGR command, get interrupt flags
|
||
MOVE.L A2,-(SP)
|
||
BigJSR PMGRrecv,A2 ;
|
||
MOVE.L (SP)+,A2
|
||
LEA 12(SP),SP ;
|
||
MOVEM.L (SP)+,A0-A1 ; restore very important registers
|
||
JMP (A1) ; go home
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Wakeup routine for setting sound (A1 = return address)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
WakeSoundSet
|
||
MOVEM.L A0-A1,-(SP) ; save special registers
|
||
SUBQ.W #4,SP ; Create stack frame
|
||
MOVE.L SP,A0
|
||
MOVE.B #sndClrLtch,(A0) ; Clear the Sound latch
|
||
MOVEQ #1,D1 ; One long to send
|
||
MOVE.W #SoundSet,D0 ; PMGR command, Set Sound Control
|
||
MOVE.L A2,-(SP)
|
||
BigJSR PMGRsend,A2 ; have the PMGR clear the sound latch
|
||
MOVE.L (SP)+,A2
|
||
ADDQ.W #4,SP ; Remove stack frame
|
||
MOVEM.L (SP)+,A0-A1 ; restore special registers
|
||
JMP (A1) ; go home
|
||
|
||
;•••••••••••••••••••••••••••••••••• Screen Misc ••••••••••••••••••••••••••••••••••••••
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: RedrawScrn
|
||
;
|
||
; Inputs: A5 - Quickdraw globals
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: A0
|
||
;
|
||
; Function: updates the screen
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
RedrawScrn
|
||
BSR ScreenWakeInit ; update all slept devices <K14>
|
||
TST.B WWExist ; is the Window Manager initialized?
|
||
BNE.S @NoWW ; -> no, just leave the screen alone
|
||
|
||
SUBQ.W #4,SP ; Get some space on the stack <13>
|
||
MOVE.L SP,-(SP) ; Push pointer for GrafPort <13>
|
||
_GetPort ; Get our current port <13>
|
||
_RedrawAll ; CheckUpdate on all layers
|
||
_SetPort ; Restore port to original <13>
|
||
@NoWW
|
||
RTS ; That's all folks
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: SaveRestoreLCD (SleepLCD/RestoreLCD)
|
||
;
|
||
; Inputs: D1 - 0 -> SaveLCD, non-zero -> RestoreLCD.
|
||
;
|
||
; Outputs: None
|
||
;
|
||
; Trashes: D0
|
||
;
|
||
; Function: This routine uses the VideoInfo record to tell it the DrHwID of the driver
|
||
; it is supposed to use in order to save the state of the LCD controller/panel.
|
||
;
|
||
; Notes: The SleepWake call in the video driver is required to do all that is necessary
|
||
; to save the state of LCD video controller so that it may be restored correctly
|
||
; upon wake. Also, the SleepWake call should paint the screen gray itself (because
|
||
; VRAM will have been non-refreshed during sleep) due to the fact that our having
|
||
; to make an addition control call from here could potentially be quite
|
||
; aesthetically unpleasing.
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
With SpBlock
|
||
|
||
SaveRestoreLCD
|
||
Move.l A0,-(SP) ; Save that register
|
||
Movea.l UnivInfoPtr,A0 ; Point to the ProductInfo record.
|
||
Adda.l VideoInfoPtr(A0),A0 ; Point to the VideoInfo record.
|
||
Move.w DrvrHwID(A0),D0 ; If the DrvrHwID is zero,
|
||
Beq.s @Done ; then just leave.
|
||
|
||
Suba.w #SpBlockSize,Sp ; Allocate an SpBlock on the stack.
|
||
Movea.l Sp,A0 ; Point to it with A0.
|
||
Clr.b spSlot(A0) ; We’re only looking in Slot $0 here.
|
||
Clr.b spID(A0) ; Begin at sRsrcID 0.
|
||
Clr.b spExtDev(A0) ; No external device.
|
||
Clr.b spTBMask(A0) ; No mask in search.
|
||
Move.w #catDisplay,spCategory(A0) ; Look for: Display,
|
||
Move.w #typVideo,spCType(A0) ; Video,
|
||
Move.w #drSwApple,spDrvrSW(A0) ; Apple,
|
||
Move.w D0,spDrvrHw(A0) ; <DrHwID>.
|
||
Clr.l spParamData(A0) ; Look only for enabled sRsrcs.
|
||
Bset #foneslot,spParamData+3(A0) ; Limit search to this slot only.
|
||
_GetTypeSRsrc ; If we didn’t find the target,
|
||
Bne.s @Cleanup ; then just leave.
|
||
Move.w spRefNum(A0),D0 ; If there’s no driver, then
|
||
Beq.s @Cleanup ; just go on.
|
||
|
||
Suba.w #ioQElSize,Sp ; Allocate ioCore pBlock.
|
||
Movea.l Sp,A0 ; Set up for the control call:
|
||
Move.w D0,ioRefNum(A0) ; ioRefNum,
|
||
Move.w #cscSleepWake,csCode(A0) ; csCode,
|
||
Move.b D1,-(Sp) ; csParam,
|
||
Move.l Sp,csParam(A0) ; csParamPtr,
|
||
_Control ,Immed ; SleepWake.
|
||
Tst.b (Sp)+ ; Remove param from stack.
|
||
Adda.w #ioQElSize,Sp ; Deallocate ioCore pBlock.
|
||
|
||
@Cleanup Adda.w #SpBlockSize,Sp ; Deallocate SpBlock.
|
||
@Done Movea.l (SP)+,A0 ; restore that register
|
||
Rts
|
||
|
||
Endwith
|
||
|
||
|
||
|
||
;_PaletteDispatch OPWORD $AAA2 ; PaletteDispatch is NOT defined in this ROM.
|
||
;selectSetDepth EQU $0A13 ; SetDepth -> $0A is paramsize, $13 is the selector.
|
||
|
||
SetScreenBrightness EQU $4301
|
||
GetScreenBrightness EQU $5301 ;
|
||
DimLevel EQU 1 ;
|
||
|
||
VidStkFrame RECORD 0, DECR
|
||
VidStkCntBlk DS.B IOVQElSize ; control call parm block
|
||
VidStkVDPageInfo DS.B VDPageInfo ; params
|
||
VidStkFrameSize EQU * ; size of frame
|
||
ENDR
|
||
|
||
;———————————————————————————————————————————————————————————————————————————————————————— <Kxx>
|
||
; Routine: ScreenWakeInit |
|
||
; v
|
||
; Inputs: none
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0
|
||
;
|
||
; Function: SetDepth in order to set the driver in appropriate state and to tell Quickdraw
|
||
; to rebuild the world.
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
ScreenWakeInit
|
||
ScreenWakeInitRegs REG D1-D2/A0-A4
|
||
WITH VidStkFrame,VDPageInfo
|
||
LINK A6,#VidStkFrameSize ; allocate variable space
|
||
MOVEM.L ScreenWakeInitRegs,-(SP) ; save them regs
|
||
|
||
LEA VidStkCntBlk(A6),A3 ; get pointer to IOPB
|
||
LEA VidStkVDPageInfo(A6),A4 ; get pointer to csParams
|
||
MOVE.L A4,csParam(A3) ; set csParams
|
||
MOVE.W #cscPowerSelect,csCode(A3) ; cscPowerSelect
|
||
|
||
MOVE.L DeviceList,D1 ; If the DeviceList is empty,
|
||
BEQ.S @ScreenWakeInitDone ; then we can’t do anything!
|
||
MOVEQ #0,D2 ; Initialize PowerSelect supported flag
|
||
|
||
@ScreenWakeInitLp ; DO {
|
||
MOVEA.L D1,A2 ; Get gDevice Handle
|
||
MOVEA.L (A2),A2 ; Dereference the handle
|
||
MOVEQ #0,D0 ; Clear both halves of D0.l.
|
||
MOVE.W gdRefNum(A2),D0 ; Get driver refnum.
|
||
BEQ.S @NoSetDepth ; If not non-zero, skip.
|
||
MOVEA.L A3,A0 ; A0 := IOPB
|
||
ORI.W #-1,D2 ; Set Flag
|
||
MOVE.L D1,-(SP) ; Push gdHandle
|
||
MOVE.W gdMode+2(A2),-(SP) ; Push the depth
|
||
CLR.L gdMode(A2) ; Clear it so stupid trap doesn't freak out
|
||
CLR.L -(SP) ; Clear all flags
|
||
MOVE.W #selectSetDepth,D0 ; Set selector to set depth
|
||
_PaletteDispatch ; Call it
|
||
@NoSetDepth
|
||
MOVE.L gdNextGD(A2),D1 ; Device := NextDevice
|
||
BNE.S @ScreenWakeInitLp ; } While !EndOfDeviceLoop
|
||
@ScreenWakeInitDone
|
||
MOVEM.L (SP)+,ScreenWakeInitRegs ; restore reg
|
||
UNLK A6 ; release stack frame
|
||
RTS ; that's all folks
|
||
|
||
|
||
;———————————————————————————————————————————————————————————————————————————————————————— <H32>
|
||
; Routine: VidLowPwrSelect |
|
||
; v
|
||
; Inputs: D0 0 = PowerOn , nonzero = PowerDown
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: D0
|
||
;
|
||
; Function: Call the video driver to set the power state to the appropriate position.
|
||
; In the case of power up, power up the hardware and call SetDepth in order to
|
||
; set the driver in appropriate state and to tell Quickdraw to rebuild the
|
||
; world.
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
VidLowPwrSelect
|
||
VidLowPwrSelectRegs REG D1-D2/A0-A4
|
||
|
||
WITH VidStkFrame,VDPageInfo
|
||
LINK A6,#VidStkFrameSize ; allocate variable space
|
||
MOVEM.L VidLowPwrSelectRegs,-(SP) ; save them regs
|
||
|
||
LEA VidStkCntBlk(A6),A3 ; get pointer to IOPB
|
||
LEA VidStkVDPageInfo(A6),A4 ; get pointer to csParams
|
||
MOVE.L A4,csParam(A3) ; set csParams
|
||
Move.l #powerSelSig,csParam+4(A3) ; (For Radius, csParams is not a pointer in some cases.)
|
||
MOVE.W #cscPowerSelect,csCode(A3) ; cscPowerSelect
|
||
|
||
MOVE.L DeviceList,D1 ; If the DeviceList is empty,
|
||
Beq.s @VidLowPwrSelectDone ; then we can’t do anything!
|
||
MOVEQ #0,D2 ; Initialize PowerSelect supported flag
|
||
|
||
TST.L D0 ; IF PowerDown THEN
|
||
BNE @VidPowerDown ; branch…
|
||
|
||
@PwrUpgDevLoop ; DO {
|
||
MOVEA.L D1,A2 ; Get gDevice Handle
|
||
MOVEA.L (A2),A2 ; Dereference the handle
|
||
Moveq #0,D0 ; Clear both halves of D0.l.
|
||
MOVE.W gdRefNum(A2),D0 ; Get driver refnum.
|
||
Beq.s @NoSetDepth ; If not non-zero, skip.
|
||
MOVEA.L A3,A0 ; A0 := IOPB
|
||
Bsr PowerSelectSupported ; IF cscPowerSelect NOT supported THEN
|
||
Beq.s @NoSetDepth ; just go on.
|
||
Move.w D0,ioRefNum(A0) ; Set driver refnum
|
||
CLR.W csMODE(A4) ; Set PowerUpMode in csMode
|
||
_Control ,IMMED ; Power Up Device
|
||
BNE.S @NoSetDepth ; IF cscPowerSelect supported THEN
|
||
|
||
ORI.W #-1,D2 ; Set Flag
|
||
MOVE.L D1,-(SP) ; Push gdHandle
|
||
MOVE.W gdMode+2(A2),-(SP) ; Push the depth
|
||
CLR.L gdMode(A2) ; Clear it so stupid trap doesn't freak out
|
||
CLR.L -(SP) ; Clear all flags
|
||
MOVE.W #selectSetDepth,D0 ; Set selector to set depth
|
||
_PaletteDispatch ; Call it
|
||
@NoSetDepth
|
||
MOVE.L gdNextGD(A2),D1 ; Device := NextDevice
|
||
BNE.S @PwrUpgDevLoop ; } While !EndOfDeviceLoop
|
||
TST.W D2 ; IF SetDepthCalled THEN
|
||
BEQ.S @NoRestore ;
|
||
TST.B WWExist ; is the Window Manager initialized?
|
||
BNE.S @NoRestore ; -> no, just leave the screen alone
|
||
|
||
SUBQ.W #4,SP ; Get some space on the stack
|
||
MOVE.L SP,-(SP) ; Push pointer for GrafPort
|
||
_GetPort ; Get our current port
|
||
_RedrawAll ; CheckUpdate on all layers
|
||
_SetPort ; Restore port to original
|
||
@NoRestore
|
||
_ShowCursor ; Show Cursor
|
||
|
||
@VidLowPwrSelectDone
|
||
MOVEM.L (SP)+,VidLowPwrSelectRegs ; restore reg
|
||
UNLK A6 ; release stack frame
|
||
RTS ; that's all folks
|
||
|
||
; Power-Down Video Devices
|
||
; Set up IOPB for control call
|
||
|
||
@VidPowerDown
|
||
Moveq #0,D2 ; Assume that we’re not hiding the cursor.
|
||
MOVEA.L A3,A0 ; A0 := IOPB
|
||
|
||
@PwrDowngDevLoop ; DO {
|
||
MOVEA.L D1,A2 ; Get gDevice Handle
|
||
MOVEA.L (A2),A2 ; Dereference the handle
|
||
Moveq #0,D0 ; Clear both halve of D0.l.
|
||
Move.w gdRefNum(A2),D0 ; Get driver refNum
|
||
Beq.s @NextGD ; If not non-zero, skip.
|
||
Bsr PowerSelectSupported ; If cscPowerSelect NOT supported THEN
|
||
Beq.s @NextGD ; just go on
|
||
Move.w D0,ioRefNum(A0) ; Set driver refnum
|
||
MOVE.W #-1,csMODE(A4) ; Set PowerDown in csMode
|
||
_Control ,IMMED ; Power Down Device
|
||
Bne.s @NextGD ; If failed, keep going.
|
||
Moveq #-1,D2 ; Otherwise, hiding the cursor is okay.
|
||
@NextGD MOVE.L gdNextGD(A2),D1 ; Device := NextDevice
|
||
BNE.S @PwrDowngDevLoop ; } While !EndOfDeviceLoop
|
||
|
||
; Kill the BackLight. <H33>
|
||
LEA DBLiteBackLite,A2 ; Get pointer to Backlight driver name. |
|
||
MOVE.L A2,ioFileName(A0) ; Load it. v
|
||
_Open ; Open driver to get the refNum.
|
||
BNE.S @NoDriver ; IF Open==Successful THEN
|
||
|
||
MOVE.W #GetScreenBrightness,csCode(A0) ; get current brightness level <H49>
|
||
_Status ,IMMED ; <H49>
|
||
CMP.W #DimLevel,csParam(a0) ; only dim if level is greater than dim value <H49>
|
||
BLE.S @NoDriver ; level is already lower than dimming value <H49>
|
||
|
||
MOVE.W #SetScreenBrightness,csCode(A0) ; turn off screen brightness
|
||
MOVE.W #DimLevel,csParam(A0) ; set brightness level <H49>
|
||
_Control ,IMMED ; do it
|
||
Bne.s @NoDriver ; don't hide cursor if failed
|
||
Ori.w #-1,D2 ; otherwise, flag that we can hide the cursor
|
||
|
||
@NoDriver Tst.l D2 ; If we shouldn’t hide the cursor,
|
||
Beq.s @VidLowPwrSelectDone ; then just go on.
|
||
_HideCursor ; Otherwise, hide it.
|
||
BRA.S @VidLowPwrSelectDone ; And go on.
|
||
ENDWITH
|
||
|
||
STRING Pascal
|
||
DBLiteBackLite DC.B '.Backlight' ; Name of Backlight Driver for DBLite.
|
||
ALIGN 2
|
||
VSCDrvrName Dc.b '.VSC_Video' ; Name of Mini/Duo Dock Video Driver.
|
||
Align 2
|
||
KeyStoneDrvrName Dc.b '.Display_Video_Apple_ViSC' ; Name of Dart-class version of the VSC Video Driver.
|
||
Align 2
|
||
STRING Asis
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: PowerSelectSupported
|
||
;
|
||
; Inputs: D0.l - refNum of a video driver
|
||
; A0.l - pointer to video driver control/status IOPB for cscPowerSelect
|
||
;
|
||
; Outputs: D0.w - if non-zero, is video driver’s refNum and PowerSelect is
|
||
; supported by the video driver.
|
||
;
|
||
; Trashes: D0
|
||
;
|
||
; Function: Returns whether or not a particular video driver supports the cscPowerSelect
|
||
; call. Note that for the original two Apple video drivers that supported
|
||
; this call, we just do a name check. From now on, though, we call the
|
||
; corresponding status call. If we get back an error, we assume that the
|
||
; call is not supported. Otherwise, we check the csData field for the
|
||
; appropriate signature to be sure that cscPowerSelect is really supported.
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
PowerSelectSupported
|
||
|
||
Move.w D0,-(Sp) ; Save the refNum for later.
|
||
Beq @ExitNow ; If nil, then just leave.
|
||
|
||
; Get the video driver’s name…
|
||
;
|
||
Movem.l A0-A1/D7,-(Sp) ; Save some work registers.
|
||
|
||
Not.w D0 ; Convert the refNum into…
|
||
Lsl.w #2,D0 ; …a UTable index.
|
||
|
||
Add.l UTableBase,D0 ; Get a pointer to the AuxDCEHandle.
|
||
Movea.l D0,A0 ; Get it into A0.
|
||
|
||
Movea.l (A0),A0 ; Get the AuxDCEHandle.
|
||
Movea.l (A0),A0 ; Get the AuxDCEPtr.
|
||
|
||
Move.w dCtlFlags(A0),D0 ; Get the device flags.
|
||
Movea.l dCtlDriver(A0),A0 ; Get the driver.
|
||
Btst #dRAMBased,D0 ; If it’s not in RAM, then
|
||
Beq.s @GetName ; it’s already a pointer.
|
||
Movea.l (A0),A0 ; Otherwise, get pointer to driver.
|
||
@GetName Lea drvrName(A0),A0 ; Point to the driver name.
|
||
Move.l A0,D7 ; Save it for later.
|
||
|
||
; Check for the Mini/Duo Dock Video Driver…
|
||
;
|
||
Moveq #0,D0 ; Clear both halves of D0.l.
|
||
Move.b (A0)+,D0 ; Get the length of the driver name.
|
||
Swap D0 ; Save it.
|
||
Lea VSCDrvrName,A1 ; Point to the Mini/Duo Dock Video Driver’s name.
|
||
Move.b (A1)+,D0 ; Get the length of the driver name.
|
||
_CmpString ; Compare the two names.
|
||
Tst.w D0 ; If they match,
|
||
Beq.s @Supported ; then just go on.
|
||
|
||
; Check for the Dart-class version of the VSC Video Driver.
|
||
;
|
||
Movea.l D7,A0 ; Re-point to the driver we’re checking.
|
||
Moveq #0,D0 ; Clear both halves of D0.
|
||
Move.b (A0)+,D0 ; Get the length of the driver name.
|
||
Swap D0 ; Save it.
|
||
Lea KeyStoneDrvrName,A1 ; Point to the Dart-class version of the VSC Video Driver.
|
||
Move.b (A1)+,D0 ; Get the length of the driver name.
|
||
_CmpString ; Compare the two names.
|
||
Tst.w D0 ; If they match,
|
||
Beq.s @Supported ; then just go on.
|
||
|
||
; Now, generically check the driver by making the cscPowerSelect status call…
|
||
;
|
||
With VDPageInfo
|
||
|
||
Movem.l (Sp)+,A0-A1/D7 ; Restore work registers.
|
||
Move.l A0,D0 ; Save A0 (IOPB ptr) for now.
|
||
Movea.l csParam(A0),A0 ; Point to csParams data.
|
||
Clr.l csData(A0) ; Clear the verification field.
|
||
Movea.l D0,A0 ; Restore A0.
|
||
Move.w (Sp),ioRefNum(A0) ; Get the driver refNum.
|
||
_Status ,Immed ; If cscPowerSelect is not supported,
|
||
Bne.s @NotThere ; then just say so.
|
||
|
||
Move.l A0,-(Sp) ; Save A0.
|
||
Movea.l csParam(A0),A0 ; Point to the csParams data.
|
||
Cmpi.l #powerSelSig,csData(A0) ; Check for cscPowerSelect.
|
||
Movea.l (Sp)+,A0 ; Restore A0.
|
||
Beq.s @Supported1 ; If cscPowerSelect is supported, then just go on.
|
||
|
||
@NotThere Addq #2,Sp ; Strip refNum off the stack.
|
||
Moveq #0,D0 ; Say that cscPowerSelect is not supported.
|
||
Rts ; And leave.
|
||
|
||
Endwith
|
||
|
||
; Clean up and go home…
|
||
;
|
||
@Supported Movem.l (Sp)+,A0-A1/D7 ; Restore the work registers.
|
||
@Supported1 Move.w (Sp)+,D0 ; Get the refNum back into D0.
|
||
@ExitNow Rts ; Return to caller.
|
||
|
||
|
||
;•••••••••••••••••••••••••••••••••••• Battery Stuff •••••••••••••••••••••••••••••••••••••
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: GetLevel
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - normalized battery level (-1 to 4)
|
||
; CCR - BNE if a valid battery level is being returned
|
||
;
|
||
; Trashes: D0-D3, A0
|
||
;
|
||
; Function: Reads the battery power level from the Power Manager and adds this value into
|
||
; an eight value circular queue. If the queue is full then an average of these
|
||
; values is calculated. Next, the averaged value is compared with the warning
|
||
; and cutoff values in PRAM to determine if the average is greater then reserve
|
||
; or what fractional part of reserve (1, 3/4, 1/2, or 1/4).
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
GetLevel CLR.L -(SP) ; make space for a buffer
|
||
MOVE.L SP,-(SP) ; pmRBuffer
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
CLR.W -(SP) ; pmLength = 0
|
||
MOVE.W #batteryNow,-(SP) ; pmCommand = get battery data
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; send the command
|
||
LEA pmRBuffer+4(SP),SP ; toss the parameter block
|
||
|
||
MOVEA.L SP,A0 ; point to the buffer
|
||
MOVEQ #0,D3
|
||
MOVE.B (A0)+,Charger(A2) ; get the charger state
|
||
MOVE.B (A0),D3 ; and the battery level
|
||
ADDQ.W #4,SP ; toss the stack frame
|
||
|
||
BTST #ChrgState,Charger(A2) ; get the charger state (connected/disconnected)
|
||
BEQ.S @ChargeSame ; -> no change in charger state
|
||
ST TOdirtyFlag(A2) ; Flag TOs need updating
|
||
|
||
@ChargeSame MOVEQ #0,D0
|
||
MOVE.B BatQIndex(A2),D0 ; get the next index into the circular queue
|
||
SUBQ.B #1,D0
|
||
BPL.S @IndexOK ; -> index is still valid
|
||
MOVEQ #7,D0 ; it wrapped, so reset it
|
||
@IndexOK MOVE.B D0,BatQIndex(A2) ; save the new index
|
||
|
||
MOVE.B D3,BatQ(A2,D0.W) ; put the latest battery level into queue
|
||
TST.B BatQ(A2) ; wait for full queue before averaging
|
||
BEQ.S GetLevel
|
||
|
||
MOVEQ #0,D3
|
||
MOVE.B BatQ(A2),D0 ; calculate the average of the last 8 samples
|
||
ADD.W D0,D3
|
||
MOVE.B BatQ+1(A2),D0
|
||
ADD.W D0,D3
|
||
MOVE.B BatQ+2(A2),D0
|
||
ADD.W D0,D3
|
||
MOVE.B BatQ+3(A2),D0
|
||
ADD.W D0,D3
|
||
MOVE.B BatQ+4(A2),D0
|
||
ADD.W D0,D3
|
||
MOVE.B BatQ+5(A2),D0
|
||
ADD.W D0,D3
|
||
MOVE.B BatQ+6(A2),D0
|
||
ADD.W D0,D3
|
||
MOVE.B BatQ+7(A2),D0
|
||
ADD.W D0,D3
|
||
LSR.W #1,D3 ; D3 = 4*avg
|
||
|
||
MOVEQ #0,D2
|
||
MOVE.B LowWarn(A2),D2 ; D2 = low warning level
|
||
MOVEQ #0,D1
|
||
MOVE.B CutOff(A2),D1 ; D1 = cutoff level
|
||
SUB.W D1,D2 ; D2 = warning - cutoff
|
||
ASL.W #2,D1 ; D1 = 4*cutoff
|
||
|
||
MOVEQ #4,D0 ; level 4
|
||
ADD.W D2,D1 ; D1 = 4*cutoff + 1(warning - cutoff)
|
||
CMP.W D1,D3 ; power ≤ 1/4 reserve
|
||
BLS.S @foundlevel
|
||
|
||
MOVEQ #3,D0 ; level 3
|
||
ADD.W D2,D1 ; D1 = 4*cutoff + 2(warning - cutoff)
|
||
CMP.W D1,D3 ; power ≤ 1/2 reserve
|
||
BLS.S @foundlevel
|
||
|
||
MOVEQ #2,D0 ; level 2
|
||
ADD.W D2,D1 ; D1 = 4*cutoff + 3(warning - cutoff)
|
||
CMP.W D1,D3 ; power ≤ 3/4 reserve
|
||
BLS.S @foundlevel
|
||
|
||
MOVEQ #1,D0 ; level 1
|
||
ADD.W D2,D1 ; D1 = 4*cutoff + 4(warning - cutoff)
|
||
CMP.W D1,D3 ; power ≤ reserve
|
||
BLS.S @foundlevel
|
||
|
||
MOVEQ #0,D0 ; level 0
|
||
MOVE.W Hysteresis(A2),D2 ; D2 = hysteresis
|
||
ASL.W #2,D2 ; D2 = 4 * hysteresis
|
||
ADD.W D2,D1 ; D1 = 4*cutoff + 4(warning - cutoff) + 4*hysteresis
|
||
CMP.W D1,D3 ; power ≤ reserve + hysteresis
|
||
BLS.S @foundlevel
|
||
|
||
MOVEQ #-1,D0 ; power > reserve + hysteresis
|
||
|
||
@foundlevel LSR.W #2,D3 ; D3 = average
|
||
MOVE.B D3,BatAvg(A2) ; save it
|
||
TST.B BatQ(A2) ; set data valid condition
|
||
RTS
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: GetExtLevel
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - normalized battery level (-1 to 4)
|
||
; CCR - BNE if a valid battery level is being returned
|
||
;
|
||
; Trashes: D0-D3, A0
|
||
;
|
||
; Function: Reads the extended battery power level from the Power Manager (which is
|
||
; pre-averaged by the PMGR). Next, the value is compared with the warning
|
||
; and cutoff values in PRAM to determine if the average is greater then
|
||
; reserve or what fractional part of reserve (1, 2/3, or 1/3).
|
||
;
|
||
; Note: The extended battery status command supports a word-sized battery
|
||
; level. Currently the PMGR on DBLite uses a 9-bit A/D to sample
|
||
; the battery voltage.
|
||
;
|
||
; The battery warning levels returned will be zero if no battery is
|
||
; currently connected.
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
GetExtLevel CLR.W -(SP) ; setup a buffer for the result
|
||
MOVE.L SP,-(SP) ; pmRBuffer
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
CLR.W -(SP) ; pmLength = 0
|
||
MOVE.W #readBattWarning,-(SP) ; pmCommand = get warning/cutoff levels
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; go get them
|
||
LEA pmRBuffer+4(SP),SP ; toss the parameter block
|
||
MOVE.W (SP)+,LowWarn(A2) ; save the new warning/cutoff levels
|
||
|
||
CLR.L -(SP)
|
||
CLR.L -(SP)
|
||
MOVE.L SP,-(SP) ; pmRBuffer
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
CLR.W -(SP) ; pmLength = 0
|
||
MOVE.W #readExtBatt,-(SP) ; pmCommand = get extended battery data
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; send the command
|
||
LEA pmRBuffer+4(SP),SP ; toss the parameter block
|
||
|
||
MOVEA.L SP,A0 ; point to the buffer
|
||
MOVEQ #%00001011,D0 ; mask off the bits we want in the flags byte,
|
||
AND.B (A0),D0
|
||
MOVE.B Charger(A2),D1 ; get the old charger state, <H13>
|
||
MOVE.B D0,Charger(A2) ; and save the new charger state
|
||
MOVE.B (A0)+,D0 ; get the unmodified flags <H41>
|
||
EOR.B D0,D1 ; has the charger state changed since last time? <H13>
|
||
BTST #HasCharger,D1 ; <H13>
|
||
BEQ.S @ChargeSame ; -> no <H13>
|
||
ST TOdirtyFlag(A2) ; yes, flag that timeouts need updating <H13>
|
||
|
||
@ChargeSame MOVE.W (A0),D3
|
||
LSR.W #1,D3
|
||
MOVE.B D3,BatAvg(A2) ; save the 8-bit battery voltage
|
||
ADD.W (A0)+,D3 ; D3 = 3*(8 bit battery voltage)
|
||
ADDQ.W #8,SP ; toss the buffer
|
||
|
||
BTST #HasCharger,D0 ; is a charger connected? <H13>
|
||
BNE.S @HaveCharger ; -> yes, we don't care about the battery level <H13>
|
||
BTST #2,D0 ; is a battery connected? <H41>
|
||
BEQ.S @HaveCharger ; -> no, don't bother with battery level
|
||
|
||
MOVEQ #0,D2 ; <H44>
|
||
MOVE.B LowWarn(A2),D2 ; D2 = low warning level |
|
||
MOVEQ #0,D1 ; V
|
||
MOVE.B CutOff(A2),D1 ; D1 = cutoff level
|
||
SUB.W D1,D2 ; D2 = warning - cutoff
|
||
MOVE.W D1,D0
|
||
ADD.W D0,D1
|
||
ADD.W D0,D1 ; D1 = 3*cutoff
|
||
|
||
MOVEQ #4,D0 ; level 4
|
||
ADD.W D2,D1 ; D1 = 3*cutoff + 1(warning - cutoff)
|
||
CMP.W D1,D3 ; power ≤ 1/3 reserve
|
||
BLS.S @foundlevel
|
||
|
||
MOVEQ #3,D0 ; level 3
|
||
ADD.W D2,D1 ; D1 = 3*cutoff + 2(warning - cutoff)
|
||
CMP.W D1,D3 ; power ≤ 2/3 reserve
|
||
BLS.S @foundlevel
|
||
|
||
; (level 2 is not used, so we don't return it)
|
||
|
||
MOVEQ #1,D0 ; level 1
|
||
ADD.W D2,D1 ; D1 = 3*cutoff + 3(warning - cutoff)
|
||
CMP.W D1,D3 ; power ≤ reserve
|
||
BLS.S @foundlevel
|
||
|
||
MOVEQ #0,D0 ; level 0
|
||
MOVE.W Hysteresis(A2),D2 ; D2 = hysteresis
|
||
ADD.W D2,D1
|
||
ADD.W D2,D1
|
||
ADD.W D2,D1 ; D1 = 3*cutoff + 3(warning - cutoff) + 3*hysteresis
|
||
CMP.W D1,D3 ; power ≤ 1.0 reserve + hysteresis
|
||
BLS.S @foundlevel
|
||
|
||
@HaveCharger
|
||
MOVEQ #-1,D0 ; return a "charged" battery level in case someone cares
|
||
|
||
@foundlevel MOVEQ #1,D1 ; always return BNE for data valid
|
||
RTS
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: LeadScaledBatteryInfo (PowerDispatch selector #9)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - bits 31: 1=battery installed
|
||
; 30: 1=battery is charging
|
||
; 29: 1=charger connected
|
||
; 23-16: warning level (0-255)
|
||
; 15: don't use this one (needs to be set if the selector isn't implemented)
|
||
; 7- 0: battery level (0-255)
|
||
;
|
||
; Trashes: D1, D2, A0
|
||
;
|
||
; Function: Returns scaled warning and battery levels, plus a couple of flags for
|
||
; portables that support sealed lead acid batteries.
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
LeadScaledBatteryInfo
|
||
MOVEQ #3,D0 ; mask off the battery charging and charger installed bits
|
||
AND.B charger(a2),D0 ; <H39>
|
||
MOVEQ #0,D2 ; get the maximum battery voltage
|
||
MOVE.B @MaxVolts(D0),D2
|
||
SUB.B CutOff(A2),D2 ; <H37>
|
||
ADDQ.B #1<<2,D0 ; set the battery installed bit
|
||
ROR.W #3,D0 ; put the battery flags into bits 15-13 (temporarily)
|
||
|
||
MOVEQ #0,D1 ; scale the warning level (256*warning/max)
|
||
MOVE.B LowWarn(A2),D1
|
||
SUB.B CutOff(A2),D1 ; <H37>
|
||
BSR.S ScaleLevel ; pin the level and save it
|
||
SWAP D0 ; put it all in the upper word
|
||
|
||
MOVEQ #0,D1 ; scale the battery level (256*batt/max)
|
||
move.b BatAvg(A2),d1 ; get the current averaged battery <H39>
|
||
SUB.B CutOff(A2),D1 ; <H37>
|
||
BSR.S ScaleLevel ; pin the level and save it
|
||
RTS
|
||
|
||
@MaxVolts DC.B 123 ; [6.35v] not charging, no charger
|
||
DC.B 188 ; [7.00v] not charging, has charger
|
||
DC.B 123 ; [6.35v] is charging, no charger (can't get here)
|
||
DC.B 208 ; [7.20v] is charging, has charger
|
||
|
||
|
||
ScaleLevel ASL.L #8,D1 ; multiply by 256
|
||
DIVU D2,D1 ; divide a level by the maximum
|
||
CMPI.W #255,D1 ; higher than max (well, it _might_ happen)?
|
||
BLS.S @SaveLevel ; -> no, use it as is
|
||
MOVE.B #255,D1 ; yes, pin it at maximum
|
||
@SaveLevel MOVE.B D1,D0 ; save the scaled level
|
||
RTS
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: MultiScaledBatteryInfo (PowerDispatch selector #9)
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - bits 31: 1=battery installed
|
||
; 30: 1=battery is charging
|
||
; 29: 1=charger connected
|
||
; 23-16: warning level (0-255)
|
||
; 15: don't use this one (needs to be set if the selector isn't implemented)
|
||
; 7- 0: battery level (0-255)
|
||
;
|
||
; Trashes: D1, D2, A0
|
||
;
|
||
; Function: Returns scaled warning and battery levels, plus a couple of flags for
|
||
; portables that support multiple battery types. If no battery is currently
|
||
; connected, it will return zero for both the warning and battery levels.
|
||
; It uses the extended battery status command which returns the following info:
|
||
;
|
||
; +0 flags (bits)
|
||
; 7: chargeable battery
|
||
; 6: "energy used" count valid
|
||
; 5: 0
|
||
; 4: battery termperature valid
|
||
; 3: dead battery
|
||
; 2: battery connected
|
||
; 1: hi-charge enabled
|
||
; 0: charger installed
|
||
; +1 voltage (H)
|
||
; +2 voltage (L)
|
||
; +3 ambient temperature (°C)
|
||
; +4 battery temperature (°C)
|
||
; +5 power usage rate
|
||
; +6 energy used (H)
|
||
; +7 energy used (L)
|
||
;
|
||
; and the battery info command, which returns the following info:
|
||
;
|
||
; +0 max energy used count (H)
|
||
; +1 max energy used count (L)
|
||
; +2 min voltage--charging (H)
|
||
; +3 min voltage--charging (L)
|
||
; +4 max voltage--charging (H)
|
||
; +5 max voltage--charging (L)
|
||
; +6 min voltage--discharging (H)
|
||
; +7 min voltage--discharging (L)
|
||
; +8 max voltage--discharging (H)
|
||
; +9 max voltage--discharging (L)
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
MultiScaledBatteryInfo
|
||
LINK A6,#0
|
||
|
||
; get parameters associated with the current type of battery...
|
||
|
||
CLR.W -(SP) ; put a buffer on the stack
|
||
CLR.L -(SP)
|
||
CLR.L -(SP)
|
||
MOVE.L SP,-(SP) ; pmRBuffer
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
CLR.W -(SP) ; pmLength = 0
|
||
MOVE.W #readBatteryInfo,-(SP) ; pmCommand = return battery info
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; send the command
|
||
LEA pmRBuffer+4(SP),SP ; toss the parameter block
|
||
|
||
; get the current battery state and battery level...
|
||
|
||
CLR.L -(SP)
|
||
CLR.L -(SP)
|
||
MOVE.L SP,-(SP) ; pmRBuffer
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
CLR.W -(SP) ; pmLength = 0
|
||
MOVE.W #readExtBatt,-(SP) ; pmCommand = get extended battery data
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; send the command
|
||
LEA pmRBuffer+4(SP),SP ; toss the parameter block
|
||
|
||
MOVEA.L SP,A0 ; point to the buffer
|
||
MOVEQ #%01000111,D0 ; mask off the "energy used" count valid,
|
||
AND.B (A0)+,D0 ; battery installed, charging, and charger connected bits
|
||
ROR.W #3,D0 ; shift them into bits 15-13 and 3 (temporarily)
|
||
MOVE.L (A0)+,D2 ; get the battery voltage into the upper word (NOTE: unaligned read)
|
||
ADDQ.W #1,A0 ; skip over the power usage rate
|
||
MOVE.W (A0)+,D2 ; get the "energy used" count into the lower word
|
||
MOVE.L A0,SP ; toss the buffer
|
||
|
||
TST.W D0 ; is a battery installed?
|
||
BPL.S @NoBattery ; -> no, just swap the flags and exit
|
||
|
||
BCLR #6-3,D0 ; is the "energy used" count valid?
|
||
BEQ.S @UseVolts ; -> no, use the voltages
|
||
|
||
; calculate the current level based on the "energy used" count...
|
||
|
||
@UseCount SWAP D0 ; put the flags into the upper word, set warning level=0
|
||
MOVEQ #0,D1 ; get the maximum energy count (zero-extended)
|
||
MOVE.W (SP),D1
|
||
SUB.W D2,D1 ; calculate how much energy is left (max-used)
|
||
BLE.S @Done ; -> max≤used, so pin at zero
|
||
MOVE.W (SP),D2 ; get the maximum
|
||
BSR.S ScaleLevel ; scale the level and save it
|
||
BRA.S @Done
|
||
|
||
; calculate the current level based on voltages...
|
||
|
||
@UseVolts LEA 4(SP),A0 ; point to the charge parameters
|
||
BTST #14,D0 ; are we charging?
|
||
BNE.S @Charging ; -> yes, we're pointing to the right place
|
||
ADDQ.W #4,A0 ; no, point to the discharge parameters
|
||
@Charging MOVE.W (A0),D2 ; calculate max-min
|
||
SUB.W -(A0),D2
|
||
BLE.S @NoBattery ; -> max≤min (strange…), so bail
|
||
|
||
BTST #14,D0 ; are we charging? <H37>
|
||
BNE.S @NoWarning ; -> yes, there's no warning level <H37>
|
||
MOVEQ #0,D1
|
||
MOVE.B LowWarn(A2),D1 ; calculate warning-min
|
||
ADD.B D1,D1
|
||
SUB.W (A0),D1
|
||
BLE.S @NoWarning ; -> warning≤min, so pin at zero
|
||
BSR.S ScaleLevel ; scale the level and save it
|
||
@NoWarning SWAP D0 ; put it all in the upper word
|
||
|
||
MOVE.L D2,D1 ; get the battery voltage
|
||
CLR.W D1 ; and zero extend it
|
||
SWAP D1
|
||
SUB.W (A0),D1 ; calculate battery-min
|
||
BLE.S @Done ; -> battery≤min, so pin at zero
|
||
BSR.S ScaleLevel ; scale the level and save it
|
||
|
||
@Done UNLK A6 ; get rid of any lingering buffers
|
||
RTS
|
||
|
||
@NoBattery CLR.B D0 ; make sure the battery level is zero
|
||
SWAP D0 ; put the flags in the upper word
|
||
BRA.S @Done ; and exit
|
||
|
||
;———————————————————————————————————————————————————————————————————————————————————————— <H54>
|
||
; Routine: LeadAbsoluteBatteryVoltage
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - fixed-point representation of the absolute battery voltage
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: Calculates the absolute battery voltage for lead acid batteries. The result
|
||
; is returned as a fixed point number (16 bits integer + 16 bits fraction),
|
||
; giving a range from 0 to 32767.999984741 volts. This should be enough to
|
||
; handle the next few batteries we do.
|
||
;
|
||
; For lead acid batteries, the voltage is calculated as:
|
||
;
|
||
; voltage = ((power/100) + 5.12) volts
|
||
;
|
||
; For a ‘power’ range of 0 to 255, we get a voltage range of 5.12 to 7.67 volts.
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
LeadAbsoluteBatteryVoltage
|
||
MOVEQ #0,D0 ; zero-extend the battery level
|
||
MOVE.B BatAvg(A2),D0
|
||
SWAP D0 ; convert it to fixed-point
|
||
DIVU #100,D0 ; divide by 100 to convert to relative volts
|
||
SWAP D0 ; get the result back in the right order
|
||
ADDI.L #(5<<16)+(65536*12/100),D0 ; add 5.12v to convert to absolute
|
||
RTS
|
||
|
||
|
||
|
||
;———————————————————————————————————————————————————————————————————————————————————————— <H54>
|
||
; Routine: PGEAbsoluteBatteryVoltage
|
||
;
|
||
; Inputs: A2 - pointer to Power Manager globals
|
||
;
|
||
; Outputs: D0 - fixed-point representation of the absolute battery voltage
|
||
;
|
||
; Trashes: A0, D1
|
||
;
|
||
; Function: Calculates the absolute battery voltage for PG&E-based machines. The result
|
||
; is returned as a fixed point number (16 bits integer + 16 bits fraction),
|
||
; giving a range from 0 to 32767.999984741 volts. This should be enough to
|
||
; handle the next few batteries we do.
|
||
;
|
||
; PG&E essentially uses a 9-bit A/D for a voltage range of 7 to 21 volts.
|
||
; So the voltage is calculated as:
|
||
;
|
||
; voltage = ((power*14/512) + 7) volts
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
PGEAbsoluteBatteryVoltage
|
||
CLR.L -(SP) ; allocate space for the extended battery info
|
||
CLR.L -(SP)
|
||
MOVE.L SP,-(SP) ; pmRBuffer
|
||
MOVE.L (SP),-(SP) ; pmSBuffer
|
||
CLR.W -(SP) ; pmLength = 0
|
||
MOVE.W #readExtBatt,-(SP) ; pmCommand = get extended battery data
|
||
MOVEA.L SP,A0 ; point to the parameter block
|
||
_PMgrOp ; send the command
|
||
LEA pmRBuffer+4(SP),SP ; toss the parameter block
|
||
|
||
MOVEQ #0,D0
|
||
MOVEA.L SP,A0 ; point to the buffer
|
||
BTST #2,(A0)+ ; is a battery connected?
|
||
BEQ.S @NoBattery ; -> no, we're done
|
||
MOVEQ #14,D0 ; battery level * 14
|
||
MULU (A0),D0 ; (NOTE: unaligned read)
|
||
SWAP D0 ; convert it to fixed point
|
||
MOVEQ #9,D1
|
||
LSR.L D1,D0 ; divide by 512 to convert to relative volts
|
||
ADDI.L #7<<16,D0 ; add 7v to convert to absolute
|
||
|
||
@NoBattery ADDQ.W #8,SP ; toss the buffer
|
||
RTS
|
||
|
||
|
||
;•••••••••••••••••••••••••••••••••••••• Utilities •••••••••••••••••••••••••••••••••••••••
|
||
|
||
;———————————————————————————————————————————————————————————————————————————————————————— <H22>
|
||
; PostUserNmMsg - post user warning notification msg
|
||
;
|
||
; General routine which will post a user warning notification mgr message using the
|
||
; "UNmQEntry" PmgrRec notification mgr record.
|
||
;
|
||
; Input: a0.l = ptr to notification string
|
||
; d0.w = indicates which completion routine
|
||
; 0 -> does nothing - leaves flashing icon (default)
|
||
; 1 -> removes message and icon
|
||
;
|
||
; Output: none
|
||
;
|
||
Export PostUserNmMsg
|
||
PostUserNmMsg
|
||
@regs reg d1/a0/a2
|
||
movem.l @regs,-(sp)
|
||
|
||
movea.l PmgrBase,a2 ; a2 = ptr to pmgr globals
|
||
bset.b #PmgrAvoidUsrMsg,PmgrFlags1(a2) ; are warning messages enabled?
|
||
bne.s @skip ; not enabled - skip it
|
||
move.l a0,d1 ; is there a string? <H26>
|
||
beq.s @skip ; no message to post
|
||
|
||
lea UNmQEntry(a2),a0 ; addr of notification record
|
||
move.l d1,nmStr(a0) ; set the string
|
||
move.w #8,qType(a0)
|
||
move.l #-1,nmSound(a0) ; use default sound
|
||
clr.w nmMark(a0) ; No mark
|
||
move.l lpSICNHndl(a2),nmIcon(a0) ; Use the icon
|
||
lea @nmproc,a2 ; no completion routine
|
||
subq.w #1,d0 ; the "other" completion routine? <H26>
|
||
bne.s @postmsg ; no - use default <H26>
|
||
lea @oneShot,a2 ; use routine which removes icon <H26>
|
||
@postMsg
|
||
move.l a2,nmResp(a0) ; set completion routine
|
||
_NMInstall ; post message
|
||
@skip
|
||
movem.l (sp)+,@regs
|
||
@nmproc rts ; empty completion routine <H26>
|
||
|
||
@oneShot ; <H26>
|
||
movea.l (sp)+,a1 ; save return addr <H26>
|
||
movea.l (sp)+,a0 ; get ptr to BNmQEntry <H26>
|
||
_NMRemove ; remove the bad battery notification <H26>
|
||
movea.l PmgrBase,a0 ; get ptr to pmgr globals <H26>
|
||
bclr.b #PmgrAvoidUsrMsg,PmgrFlags1(a0) ; allow user messages again <H26>
|
||
jmp (a1) ; return to caller <H26>
|
||
|
||
|
||
|
||
;••••••••••••••••••••••••••••••••••••••• ModemTables •••••••••••••••••••••••••••••••••••••••• <H31>
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Modem Table
|
||
;
|
||
; Tables of offsets to low level hardware dependent routines which are used for
|
||
; internal modem control
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
ALIGN 4
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (ModemTableEnd-ModemTable) ; size of table
|
||
ModemTable DC.L StdModemOn-ModemTable ; standard routine to turn on modem
|
||
DC.L StdModemOff-ModemTable ; standard routine to turn off modem
|
||
DC.L StdModemType-ModemTable ; standard routine to get modem type
|
||
ModemTableEnd
|
||
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: TurnModemPowerOn/Off
|
||
;
|
||
; Input: a0.l = ptr to powermanager pb + 4 byte general data buffer(pmData)
|
||
; - pre-initialized so pmSend/pmReceive points to pmData
|
||
; d1.b = modem status bits from power manager
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: Power control for the internal modem
|
||
;
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
TurnModemPowerOff
|
||
bclr.l #ModemPwr,d1 ; clear bit in saved modem status bits
|
||
bra.s SetData
|
||
TurnModemPowerOn
|
||
and.b #7,d1 ; mask only <ring wakeup><port select><modem power>
|
||
bset.l #ModemPwr,d1 ; set bit in saved modem status bits
|
||
SetData move.b d1,pmData(a0) ; turn on +5V and -5V to modem bit
|
||
move.w #1,pmLength(a0) ; xmit one byte
|
||
move.w #modemSet,pmCommand(a0) ; modem set command
|
||
_PmgrOp ; turn on +5V and -5V to modem
|
||
rts
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: Enable/DisableModem
|
||
;
|
||
; Input: a0.l = ptr to powermanager pb + 4 byte general data buffer
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: Controls the modem enable line
|
||
;
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
DisableModem
|
||
move.b #ModemOff,pmData(a0) ; disable modem - sense of bit is reversed
|
||
bra.s SetCount
|
||
EnableModem
|
||
move.b #ModemOn,pmData(a0) ; enable modem - sense of bit is reversed
|
||
SetCount move.w #1,pmLength(a0) ; xmit one byte
|
||
move.w #powerCntl,pmCommand(a0) ; power control command
|
||
_PmgrOp ; call the power manager
|
||
rts
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: TurnOffModemSoundSelect
|
||
;
|
||
; Input: none
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: d0
|
||
;
|
||
; Function: turns off input source if modem selected
|
||
;
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
TurnOffModemSoundSelect
|
||
jsrTBL sndInputSource ; is a sound source selected?
|
||
cmp.B #2,D0 ; is the modem input selected ?
|
||
bne.s @exitSoundInput ; continue with code
|
||
|
||
move.b #0,d0 ; get current volume
|
||
jsrTBL sndPlayThruVol ; set volume for playthrough
|
||
moveq.l #sndInputOff,d0
|
||
jsrTbl sndInputSelect ; select aux source
|
||
@exitSoundInput
|
||
rts
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: DelayNMsec
|
||
;
|
||
; Input: d0.l = msec to delay
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: Spin wait for N milliseconds
|
||
;
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
EXPORT DelayNMsec
|
||
DelayNMsec
|
||
@savedregs reg d0-d1 ; working set of register
|
||
movem.l @savedregs,-(sp) ; save working set
|
||
move.w d0,d1 ; number of msec
|
||
subq #1,d1 ; subtract 1 for dbra loop
|
||
@msec move.w TimeDBRA,d0 ; load 1ms delay in d0
|
||
@Delay dbra d0,@Delay ; wait 1 ms
|
||
dbra d1,@msec ; repeat 1ms d1 times
|
||
movem.l (sp)+,@savedregs ; restore working set
|
||
rts
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: StdModemOn
|
||
;
|
||
; Input: a0.l = ptr to powermanager pb + 4 byte general data buffer
|
||
; d1.b = modem status bits from power manager
|
||
;
|
||
; Outputs: condition codes
|
||
;
|
||
; Trashes: d0
|
||
;
|
||
; Function: Power the internal dartanian modem
|
||
;
|
||
; 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:
|
||
; clear MODEM_RESET
|
||
; turn on +5V and -5V to modem (MODEM_PWROUT)
|
||
; ... wait >2ms to allow +5V and -5V to settle
|
||
; set MODEM_RESET
|
||
; enable the modem (*MODEM_PWR)
|
||
; wait >5ms to allow reset time
|
||
; clear MODEM_RESET
|
||
;
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
StdModemOn
|
||
bclr.b #7,([VIA2],vBufB) ; clear modem-reset before turning on power
|
||
|
||
bsr.s TurnModemPowerOn ; turn on power
|
||
|
||
moveq.l #3,d0 ; delay 3 msec (50% margin)
|
||
bsr.s DelayNMsec ; ... wait for +5v and -5V to ramp
|
||
|
||
bset.b #7,([VIA2],vBufB) ; set reset before enabling modem
|
||
bsr EnableModem ; enable modem
|
||
|
||
moveq.l #8,d0 ; delay 8 msec
|
||
bsr.s DelayNMsec ; ... for reset pulse
|
||
|
||
bclr.b #7,([VIA2],vBufB) ; clear modem-reset
|
||
|
||
; enable modem sound interrupt
|
||
move.l ([PmgrBase],MdmSndVect),jModemSnd; install in Level 1 VIA1 dispatch table
|
||
move.b #((1<<ifIRQ)+\
|
||
(1<<ifCB2)),([VIA],vIER) ; enable modem sound interrupt
|
||
|
||
moveq.l #0,d0 ; set CCR, turn on scc power on return
|
||
RTS
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: StdModemOff
|
||
;
|
||
; Input: a0.l = ptr to powermanager pb + 4 byte general data buffer
|
||
; d1.b = modem status bits from power manager
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: d0
|
||
;
|
||
; Function: Power off the internal dartanian modem
|
||
;
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
StdModemOff
|
||
move.b #(1<<ifCB2),([VIA],vIER) ; disable the modem sound interrupt <t28>
|
||
|
||
bsr.s TurnOffModemSoundSelect ; turn off modem sound if needed
|
||
bsr.s DisableModem ; disable modem
|
||
|
||
move.l #512,d0 ; Delay 512ms for modem to save some of its state
|
||
bsr.s DelayNMsec ; ... wait for +5v and -5V to ramp
|
||
|
||
bsr.s TurnModemPowerOff ; power off modem
|
||
|
||
moveq.l #8,d0 ; delay 8 msec
|
||
bsr.s DelayNMsec ; ... wait for power ramp down
|
||
moveq.l #0,d0 ; set CCR, turn off scc power on return
|
||
rts ; <H45>
|
||
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Routine: StdModemType
|
||
;
|
||
; Input:
|
||
;
|
||
; Outputs: d0.l has the modem Type
|
||
;
|
||
; Trashes: d0
|
||
;
|
||
; Function: Returns type of modem installed in TIM Modem
|
||
;
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
StdModemType
|
||
moveq.l #ModemTypeSerial,d0 ; serial modem on TIM
|
||
rts
|
||
|
||
|
||
ENDIF ; {hasPwrControls}
|
||
|
||
;••••••••••••••••••••••••••••••••••••••• CommsPowerTables •••••••••••••••••••••••••••••••••••••••• <K12>
|
||
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
; Comms Power Table
|
||
;
|
||
; Tables of offsets to low level hardware dependent routines which are used for
|
||
; powering on and off the various communication ports, be they serial, modem, or Ethernet.
|
||
;————————————————————————————————————————————————————————————————————————————————————————
|
||
|
||
ALIGN 4
|
||
DC.L PrimsTypePtr ; flags
|
||
DC.L (CommPowerTableEnd-CommsPowerTable) ; number of entries
|
||
CommsPowerTable
|
||
@PwrOn DC.L PortBOn-CommsPowerTable ; B serial
|
||
DC.L PortAOn-CommsPowerTable ; A serial
|
||
DC.L PortCOn-CommsPowerTable ; C serial (internal modem)
|
||
DC.L 0 ; no ethernet
|
||
|
||
@PwrOff DC.L PortBOff-CommsPowerTable ; B serial
|
||
DC.L PortAOff-CommsPowerTable ; A serial
|
||
DC.L PortCOff-CommsPowerTable ; C serial (internal modem)
|
||
DC.L 0 ; no ethernet
|
||
CommPowerTableEnd
|
||
|
||
with ModemTblRec
|
||
|
||
;——————————————————————————————————————————————————————————————————————————————————————— <K12>
|
||
; PortAOn - setup for port A use
|
||
;
|
||
;
|
||
; Input : d0 = bit 0: 0 = use internal modem, 1 = ignore internal modem
|
||
;
|
||
PortAOn
|
||
|
||
@savedregs reg d0-d3/a0-a2 ;
|
||
|
||
movem.l @savedregs,-(sp)
|
||
move.l d0,d2 ; d2 = indicator bits
|
||
|
||
move.l PmgrBase,a2 ; Get pmgr locals
|
||
bset #SerPortAPwr,PmgrFlags2(a2); set port a powered
|
||
|
||
; Check whether we should bypass the modem check
|
||
|
||
bclr.l #BypassModem,d0 ; set = ignore modem
|
||
bne.s @powerScc ; use the external ports
|
||
|
||
; check modem type
|
||
LoadTbl ModemTblPtr,a2,a0
|
||
beq.s @powerScc ; <K14>
|
||
JsrPrimTbl GetModemType,a0
|
||
cmpi.b #ModemTypeSerial,d0 ; is this a serial modem ?
|
||
bne.s @powerScc ; power on external port
|
||
|
||
; Modem is installed - read extended PRAM to see if modem should be powered on
|
||
|
||
MOVE.L #(1<<16)+(PmgrStatusFlags<<0),D0 ;
|
||
ADD.B PRAMBase(a2),D0 ; read the Power Manager flag byte
|
||
|
||
suba.w #2,sp ; alloc pmgr command pkt
|
||
movea.l sp,a0
|
||
_ReadXPRAM ; a0 = ptr to buf (writing over cmd word in pkt)
|
||
btst.b #UseIntrnlModem,(a0) ; check cdev bit for modem
|
||
adda.w #2,sp
|
||
bne @powerScc ; set - don't power modem
|
||
|
||
; Power on the modem
|
||
move.b #%00001000,d0 ; power on channel C
|
||
_SerialPower
|
||
|
||
move.b #(1<<ifCB2),([VIA],vIFR) ; clear interrupt flag reg
|
||
bset.b #6,([VIA],vPCR) ; change from neg to pos edge int
|
||
move.l MdmSndVect(A2),jModemSnd ; install sound on interrupt handler.
|
||
; Power on scc
|
||
@powerScc
|
||
bsr PowerSccOn ; turn on scc
|
||
|
||
@Done
|
||
movem.l (sp)+,@savedregs
|
||
rts
|
||
|
||
|
||
;——————————————————————————————————————————————————————————————————————————————————————— <K12>
|
||
; PortBOn - setup for port B use
|
||
;
|
||
;
|
||
; Input : d0 = bit 0: 0 = use internal modem, 1 = ignore internal modem
|
||
;
|
||
|
||
PortBOn bset #SerPortBPwr, \
|
||
([PMgrBase],PmgrFlags2) ; log power state
|
||
bsr PowerSccOn ; turn on scc
|
||
rts
|
||
|
||
;——————————————————————————————————————————————————————————————————————————————————————— <K12>
|
||
; PortCOn - setup for port C use
|
||
;
|
||
;
|
||
; Input : d0 = bit 0: 0 = use internal modem, 1 = ignore internal modem
|
||
;
|
||
|
||
PortCOn bset #SerPortCPwr, \
|
||
([PMgrBase],PmgrFlags2) ; log power state
|
||
bsr ModemPowerON ; power on modem
|
||
rts
|
||
|
||
;——————————————————————————————————————————————————————————————————————————————————————— <K12>
|
||
; PortAOff - release port a resources
|
||
;
|
||
;
|
||
|
||
PortAOff
|
||
|
||
@savedregs reg d0-d3/a0-a2 ;
|
||
|
||
movem.l @savedregs,-(sp)
|
||
move.l d0,d2 ; d2 = indicator bits
|
||
move.l PmgrBase,a2 ; Get pmgr locals
|
||
|
||
bclr.b #SerPortAPwr,PmgrFlags2(a2); read the Power Manager flag byte
|
||
|
||
; check modem type
|
||
LoadTbl ModemTblPtr,a2,a0
|
||
bne.s @powerOffScc ; <K14>
|
||
JsrPrimTbl GetModemType,a0
|
||
cmpi.b #ModemTypeSerial,d0 ; is this a serial modem ?
|
||
bne.s @powerOffScc ; power on external port
|
||
|
||
; Power off modem
|
||
move.b #%10001000,d0 ; power off channel C
|
||
_SerialPower
|
||
|
||
@powerOffScc
|
||
bsr HandleABPower ; power off scc if necessary
|
||
@Done
|
||
movem.l (sp)+,@savedregs
|
||
rts
|
||
|
||
;——————————————————————————————————————————————————————————————————————————————————————— <K12>
|
||
; PortBOff - release port a resources
|
||
;
|
||
;
|
||
|
||
PortBOff bclr.b #SerPortBPwr,\
|
||
([PMgrBase],PmgrFlags2) ; read the Power Manager flag byte
|
||
bsr HandleABPower
|
||
rts
|
||
|
||
;——————————————————————————————————————————————————————————————————————————————————————— <K12>
|
||
; PortCOn - setup for port C use
|
||
;
|
||
;
|
||
; Input : d0 = bit 0: 0 = use internal modem, 1 = ignore internal modem
|
||
;
|
||
|
||
PortCOff bclr #SerPortCPwr, \
|
||
([PMgrBase],PmgrFlags2) ; log power state
|
||
bsr ModemPowerOFF ; power on modem
|
||
rts
|
||
|
||
;——————————————————————————————————————————————————————————————————————————————————————— <K12>
|
||
; HandleABPower - given the current port usage, adjust power manager power control lines
|
||
;
|
||
;
|
||
|
||
HandleABPower
|
||
move.l d0,-(sp) ; save working set
|
||
move.b ([PMgrBase],PmgrFlags2),d0 ; get a copy of the flags
|
||
andi.b #((1<<SerPortAPwr) \ ; see if port A or B
|
||
+ (1<<SerPortBPwr)),d0 ; ... is currently in use
|
||
bne.s @done ; if non zero, then at least one is in use, exit
|
||
bsr PowerSccOff
|
||
@Done move.l (sp)+,d0
|
||
rts
|
||
|
||
;——————————————————————————————————————————————————————————————————————————————————————— <K12>
|
||
; SccOn/PowerSccOff - power control for SCC
|
||
;
|
||
;
|
||
; Power on scc
|
||
|
||
; power on scc
|
||
;
|
||
PowerSccOn
|
||
pSCCworkreg reg d0-d1/a0-a1
|
||
|
||
movem.l pSCCworkreg,-(sp)
|
||
moveq #0, d0
|
||
move.b #(sccOn|serOn), d0 ; load on command
|
||
bra.s SendCmd
|
||
|
||
; power off scc
|
||
;
|
||
PowerSccOff movem.l pSCCworkreg,-(sp)
|
||
moveq #0, d0
|
||
move.b #(sccOff|serOff),d0 ; load off command
|
||
; bra.s SendCmd
|
||
|
||
|
||
SendCmd
|
||
move.l d0, -(sp) ; data to send
|
||
move.l sp, -(sp) ; pmRBuffer
|
||
move.l 7(SP),-(sp) ; pmSBuffer
|
||
move.w #1, -(sp) ; pmLength
|
||
move.w #powerCntl,-(sp) ; pmCommand
|
||
MOVEA.L sp,a0 ; point to the parameter block
|
||
_PMgrOp ; get the modem info
|
||
move.l (sp), d0 ; return the status byte
|
||
adda.l #pmBlkSize, sp ; pop buffer
|
||
|
||
movem.l (sp)+,pSCCworkreg
|
||
rts
|
||
|
||
;——————————————————————————————————————————————————————————————————————————————————————— <K12>
|
||
; ModemPowerON/ModemPowerOFF - power control for modem slot
|
||
;
|
||
;
|
||
; Power on scc
|
||
; Power off modem
|
||
ModemPowerON
|
||
powerreg reg d0-d2/a0-a2
|
||
movem.l powerreg,-(sp) ; save working set
|
||
move.l #PowerOnModem,d2 ; load offset into modem primitives table for off
|
||
bra.s sendCommand
|
||
|
||
ModemPowerOFF
|
||
movem.l powerreg,-(sp) ; save working set
|
||
move.l #PowerOffModem,d2 ; load offset into modem primitives table for off
|
||
; bra.s sendCommand
|
||
|
||
sendCommand move.l PmgrBase,a2 ; Get pmgr locals
|
||
move.l vPMgrPrimitives(a2),d0 ; IF NoPrimitives THEN
|
||
beq.s @Done ; Exit
|
||
|
||
movea.l d0,a2 ; get pointer to primitives
|
||
move.l ModemTblPtr(a2),d0 ; get offset to ModemTblPtr
|
||
beq.s @Done ; Exit
|
||
|
||
move.l d0,-(sp)
|
||
bsr.l ModemStatusRT
|
||
move.l d0,d1 ; setup modem status for primitive routines
|
||
move.l (sp)+,d0
|
||
lea (a2,d0.L),a2 ; get pointer to ModemTblPtr
|
||
move.l (a2,d2.L),d0 ; load offset to routine
|
||
|
||
suba.w #pmBlkSize,sp ; alloc pmgr command pkt
|
||
lea pmData(sp),a0 ; get addr of buffer
|
||
move.l a0,pmRBuffer(sp) ; set ptr to rcv buffer
|
||
move.l a0,pmSBuffer(sp) ; set same ptr to xmit buffer (it's expected or error)
|
||
move.l sp,a0
|
||
jsr (a2,d0.L) ; Run the routine
|
||
adda.w #pmBlkSize,sp ; pop power mgr pkt
|
||
@Done
|
||
movem.l (sp)+,powerreg ; |
|
||
rts ; V
|
||
|
||
endwith ; {ModemTblRec}
|
||
END
|