mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2024-12-28 01:29:20 +00:00
4325cdcc78
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included. The Tools directory, containing mostly junk, is also excluded.
1432 lines
50 KiB
Plaintext
1432 lines
50 KiB
Plaintext
;
|
||
; File: PowerMgrPatches.a
|
||
;
|
||
; Contains: patches for the power manager
|
||
;
|
||
; Copyright: © 1990-1992 by Apple Computer, Inc., all rights reserved.
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <SM3> 9/1/93 SKH Rolling in from Horror. These patches will get removed and rolled into PowerMgr
|
||
; when Kaos has stopped changing.
|
||
;
|
||
; <16> 5/5/92 DTY #1026866: fixed a bug where the code was testing the pointer to
|
||
; the buffer not the buffer. "pmSBuffer" is a pointer, not the
|
||
; buffer.
|
||
; <15> 4/21/92 DTY #1026866: rolled in fixes for powerbooks. bugs fixed includes
|
||
; the following ... 1) aborting sleep queue if result was non zero
|
||
; in in all sleep case (routines were shuffled around to allow
|
||
; reuse by second patch) 2) serial speed problems due to 100us
|
||
; delay when powering off the floppy 3) floppy eject problem when
|
||
; HD inserted and waking up.
|
||
;
|
||
; <14> 2/17/92 DTY Add hasTerror conditional to PowerMiscPatches InstallProc so
|
||
; that it only loads on Terror ROM machines.
|
||
; <13> 2/12/92 JSM Moved this file to PowerMgr folder, keeping all the old
|
||
; revisions; cleanup header.
|
||
; <12> 12/31/91 RB Removed some definitions that are now in Traps.a and
|
||
; PowerPrivEqu.a
|
||
; <11> 12/30/91 RB Added a few WITH's needed for this file because the PowerMgr
|
||
; interfaces changed and were moved to PowerPrivEqu.a.
|
||
; <10> 10/28/91 SAM/KSM Rolled in Regatta file:
|
||
; (HJR) Fix bug where system crashes when a new a low power dialog
|
||
; comes in after the shorted battery dialog is set. This is done
|
||
; by patching the BatInt to handle remove messages appropriately.
|
||
; (ag) don't patch sound watch on asahi. allow rom code to turn
|
||
; off sound power when not in use.
|
||
; (eva) fixed bug that was causing 976 to crash by saving out and
|
||
; restoring d7 at beginning and end of the PMgrTrapII routine.
|
||
; oops.
|
||
; (djw) Fix modem sound feedback problem by disabling playthrough
|
||
; on modem sound off routine.
|
||
; (HJR) removed default _IdleDelay time patch. Fixed bug in
|
||
; _PmgrOp delay patch. Added wake task routine to set power
|
||
; warning level back to 5.90V. Patch BatWatch VBL task to change
|
||
; power warning level to 6.09V on first occurrence 10sec warning.
|
||
; Fixed ROM problem on invalid PRAM, sleep and HD times were not
|
||
; set to defaults. Fixed bug in Portable BatWatch code using low
|
||
; mem scratch area (GetParam) instead of stack at interrupt time.
|
||
; (djw) Changed default _IdleDelay time from 15 to 6 secs.
|
||
; Patched out SerialPowerOn to power on SCC before releasing modem
|
||
; reset (as per request from Paris guys).
|
||
; (HJR) Changed the SetCursor patch to look in the right place on
|
||
; the stack for the cursor
|
||
; (djw) Rearranged Terror power manager patches to use a single
|
||
; InstallProc instead of many separate ones. Lowered the max
|
||
; number of power cycling iterations. Patch _Sleep to fix
|
||
; reentrancy problem. Install general sleep queue element for
|
||
; all system type sleep queue bug fixes. Patch _SetCursor to
|
||
; disable powercycling on watch cursor and to detect activity.
|
||
; Replace SndWatch VBL task to take DFAC activity into account
|
||
; before powering off Batman. Patch _PmgrOp to add a 100µs delay
|
||
; to avoid a race condition between 68K and pmgr micro. Add
|
||
; sleep queue task on wake to turn on Batman if DFAC enabled.
|
||
; Replace ModemSound interrupt handlers to route sound thru
|
||
; attenuator. On Portable, do a KdbReset earlier in wake routine.
|
||
; (ag) Changed low power warning level in power manager micro to
|
||
; increase wake hysteresis.
|
||
; (HJR) Added InstallProc for new sleepqueue element to save and
|
||
; restore cursor appropriately before and after sleep.
|
||
; (MSH) Changed the SCCWakeFix to not wake up the modem while
|
||
; servicing the Serial wake up IRQ.
|
||
; (ag) Installed "bad battery" strings into power manager globals.
|
||
; Changed threshold level to 5.60 volts cutoff.
|
||
; added bypass of network sleep dialog. added ashai to backlight
|
||
; test in patches. changed network warning dialog to default to
|
||
; sleep
|
||
; (ag) added ashai to backlight test in patches. (HJR) Added
|
||
; "with PMgrRec" everywhere.
|
||
; Split off from 7.0 GM sources. Added low power and SCSI Link
|
||
; warnings.
|
||
; <9> 8/30/91 DTY Define onHcMac here, since itÕs not an available feature in
|
||
; BBSStartup any more.
|
||
; <8> 4/10/91 ag HJR: changed the location of the insleep semaphore. the old
|
||
; location was being overwritten by other parts of the power
|
||
; manager. moved an installproc to the head of the file in insure
|
||
; it is executed BEFORE the patchproc which uses variables it
|
||
; initializes.
|
||
; <7> 2/22/91 ag MSH: Added aruba support to the powermgr install code, new low
|
||
; power string, and patched vbls.
|
||
; <6> 2/15/91 ag MSH: #BRC 80886 - Changed sleep code and wake code to allow
|
||
; sleep queue elements to use network services. This included
|
||
; moving the close of appletalk until after the sleep queue is run
|
||
; on sleep, and opening appletalk before running the sleep queue
|
||
; on wake. the running the sleep queue on sleep, the queue is run
|
||
; in reverse order to allow service consumers to be run before
|
||
; service producers. finally, a change was added to avoid
|
||
; re-entering the sleep code (this would be very bad!!!).
|
||
; <5> 2/1/91 eh (hjr) Fixed bug that was causing serial data bytes to
|
||
; occassionally be transposed. Now all code paths call PollProc
|
||
; BEFORE re-enabling interrupts.
|
||
; <4> 12/19/90 ag As it turns out, elements of the sleep queue need interrupt on
|
||
; (the old bug kept it working!). Therefore, the wake code must be
|
||
; patched to handle restoring context and interrupts BEFORE waking
|
||
; the sleep queue. Also removed changes made in <3> since the
|
||
; change in wakeup removes the necessity of avoiding the Delay
|
||
; trap.(reviewed by MSH).
|
||
; <3> 12/14/90 ag changed delay trap calls to dbra loops. this avoids turning on
|
||
; interrupts. added patch to serial power off to allow patching
|
||
; delay call in power off trap. (reviewed by DJW)
|
||
; <2> 9/21/90 VL Removed unnecessary include files.
|
||
; <1> 9/21/90 VL Moved the PowerMgr patches from PatchPortableROM.a. All the
|
||
; patches in this file are linked patches. The whole exodus was
|
||
; prompted by the need to load the Notification Manager patches
|
||
; before anything else (including the PowerMgr patches).
|
||
;
|
||
|
||
if (&type('onHcMac') = 'UNDEFINED') then
|
||
onHcMac: equ 1
|
||
endif
|
||
|
||
load 'StandardEqu.d'
|
||
include 'LinkedPatchMacros.a'
|
||
include 'HardwarePrivateEqu.a'
|
||
include 'ATalkEqu.a'
|
||
include 'UniversalEqu.a'
|
||
include 'IOPrimitiveEqu.a'
|
||
include 'PowerPrivEqu.a'
|
||
|
||
|
||
AllClose ROMBind (Portable,$4946)
|
||
BatIntCont ROMBind (IIci,$88660)
|
||
CloseAppleTalk ROMBind (IIci,$8957E)
|
||
didqueue ROMBind (IIci,$89194)
|
||
DoQueue ROMBind (Portable,$4776)
|
||
DreamAway ROMBind (IIci,$8911C)
|
||
GetLevel ROMBind (Portable,$4176),(IIci,$887B2)
|
||
InitSCSI ROMBind (Portable,$0732)
|
||
InstallMsg ROMBind (Portable,$413A),(IIci,$8877A)
|
||
KbdReset ROMBind (Portable,$496c)
|
||
PMGRrecv ROMBind (Portable,$4014),(IIci,$885d2)
|
||
PMGRsend ROMBind (Portable,$4016),(IIci,$885d4)
|
||
RemoveMsg ROMBind (Portable,$4124),(IIci,$8875C)
|
||
ROMCheckAppleTalk ROMBind (IIci,$89488)
|
||
ROMPmgrOp ROMBind (IIci,$888ec)
|
||
SlpQInstall ROMBind (IIci,$8976C)
|
||
SlpQRemove ROMBind (IIci,$89784)
|
||
SetSupervisorMode ROMBind (IIci,$89474)
|
||
|
||
|
||
pollProcRegs reg d0-d6/a0-a4
|
||
|
||
;-----------------------------------------------------------------------------------------
|
||
;
|
||
; 1/29/90 MSH SCCWakeFix - Can you beleive another hardware problem with the serial <8>
|
||
; ports? This one concerns external modems connected while the SCC is turned
|
||
; off. The machine will lock up after going to sleep and waking a few times
|
||
; because the external device somehow makes the SCC generate an interrupt.
|
||
; The fix is an entry in the sleep queue that resets the SCC when no drivers
|
||
; are using it.
|
||
;
|
||
;-----------------------------------------------------------------------------------------
|
||
|
||
|
||
SCCWakeFix PROC EXPORT
|
||
EXPORT WakeQRec
|
||
|
||
CMP.W #SleepWakeUp,D0 ; Execute only during wake up
|
||
BNE.S @boogie
|
||
|
||
MOVE.B PortAUse,D0 ; And only if the serial ports are free
|
||
AND.B PortBUse,D0
|
||
BPL.S @boogie
|
||
|
||
MOVE.B #1,D0 ; Power up a channel (no modem) <6> MSH
|
||
_SerialPower
|
||
|
||
MOVE.L SCCWr,A0 ; Reset the SCC
|
||
MOVE.B #9,actl(A0)
|
||
MOVE.B #$C0,actl(A0)
|
||
|
||
MOVE.B #$81,D0 ; Power off the channel (no modem) <6> MSH
|
||
_SerialPower
|
||
|
||
@boogie MOVEQ #0,D0
|
||
RTS
|
||
|
||
WakeQRec DC.L 0
|
||
DC.L 0
|
||
DC.L 0
|
||
|
||
ENDPROC
|
||
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; SndWatch - A vbl task called once every ten seconds. 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. Leave power on to the sound
|
||
; circuit on backlighted units, noise problems.
|
||
;_______________________________________________________________________
|
||
|
||
SndWatch PROC
|
||
WITH PmgrRec
|
||
|
||
MOVE.L PmgrBase,A2
|
||
LEA SwVBLTask(A2),A0 ; Get pointer to vbl task
|
||
MOVE.W #SndWFreq,vblCount(A0) ; Do it again
|
||
|
||
SUB.W #4,SP ; Create stack frame
|
||
MOVE.L SP,A0
|
||
MOVE.W #SoundRead,D0 ; PMGR command, get sound state
|
||
jsrROM PMGRrecv
|
||
MOVE.B (A0),D2 ; Get sound state
|
||
BTST #1,D2
|
||
; (SKH) BEQ.S @Clearlatch ; Branch if latch is set
|
||
bra.s @noSound
|
||
|
||
_IdleUpdate ; update activity indicator
|
||
|
||
@Clearlatch MOVE.B #sndOnclrLtch,(A0) ; Turn on sound power and clear the latch
|
||
MOVEQ #1,D1 ; One byte to send
|
||
MOVE.W #SoundSet,D0 ; PMGR command, set sound state
|
||
jsrROM PMGRsend
|
||
|
||
@noSound
|
||
ADD.W #4,SP ; Release stack frame
|
||
RTS
|
||
endproc
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; BatWatch - Battery monitoring for low power conditions. If so,
|
||
; the user is alerted via the notification manager. Dirty sleep and
|
||
; hard disk time outs are updated too.
|
||
;
|
||
; Upon entry: A1 - VIA base
|
||
;
|
||
;
|
||
; A0-A3, D0-D3 are preserved by the interrupt dispatcher.
|
||
;
|
||
;_______________________________________________________________________
|
||
|
||
BatWatch PROC
|
||
WITH PmgrRec
|
||
WITH SleepQRec,pmCommandRec ; <11> rb
|
||
MOVE.L PmgrBase,A2 ;
|
||
TST.B SysTaskFlag(A2) ; is it ok to use notification manager
|
||
BNE.S @didsystask ; ... if yes, check battery
|
||
LEA BatVBLTask(A2),A0 ; Get pointer to vbl task
|
||
MOVE.W #BatFreq,vblCount(A0) ; Do it again
|
||
RTS
|
||
|
||
@didsystask jsrRom GetLevel ; Read, average, and convert battery level
|
||
BNE.S @valid ; into level -1 - 4, branch if data not ready
|
||
|
||
MOVE.B #-1,LastLevel(A2) ; Reset last level
|
||
BRA.S BatWatchOut
|
||
|
||
@valid TST.B D0 ; Test for negative current level
|
||
BPL.S @positive
|
||
|
||
@negative jsrRom RemoveMsg ; Remove old message (if any)
|
||
MOVE.B D0,LastLevel(A2) ; Save level
|
||
BRA.S BatWatchOut
|
||
|
||
@positive BEQ.S @lesser ; Level 0, do nothing
|
||
CMP.B #2,D0 ; Level 2, remap to level 1 (last dialog level)
|
||
BNE.S @lpowermode ; <2> É continue with low power stuff
|
||
MOVEQ #1,D0 ; <2> É remap level 2 to level 1
|
||
|
||
@lpowermode TST.B LastLevel(A2) ; If LasLevel was -1 then new message
|
||
BMI.S @newmsg
|
||
|
||
CMP.B LastLevel(A2),D0 ; If NewLevel<=LastLevel then branch
|
||
BLS.S @lesser
|
||
|
||
@newmsg jsrRom RemoveMsg ; Remove previous level message
|
||
jsrRom InstallMsg ; Install this level message
|
||
CLR.B Level4Cnt(A2) ; Clear level 4 count down timer
|
||
MOVE.B D0,LastLevel(A2) ; Save level
|
||
BRA.S BatWatchOut
|
||
|
||
@lesser CMP.B #4,LastLevel(A2) ; If level 4 then inc timer
|
||
BNE.S BatWatchOut
|
||
|
||
ADD.B #1,Level4Cnt(A2)
|
||
|
||
BatWatchOut LEA BatVBLTask(A2),A0 ; Get pointer to vbl task
|
||
MOVE.W #BatFreq,vblCount(A0) ; Do it again
|
||
|
||
MOVE.L Rombase,A1 ; Check for version of PRAM <12> HJR
|
||
CMP.W #$67C,8(A1) ; Are we running a Terror Machine <12> HJR
|
||
BEQ.S @TerrorMachines ; Branch not portable or asahi. <12> HJR
|
||
|
||
TST.B TOdirtyFlag(A2) ; Check for new timeouts
|
||
BEQ.S @exit
|
||
|
||
CLR.B TOdirtyFlag(A2) ; Clear the dirty flag
|
||
SUB.W #8,SP ; allocate buffer <12> HJR
|
||
MOVE.L SP,A0 ; Set buffer pointer <12> HJR
|
||
MOVE.L #$080070,D0 ; Read our parameters
|
||
_ReadXPRam
|
||
|
||
MOVE.B 7(A0),SleepFlags(A2) ; Portable & Asahi use PRAM 77 as SleepFlags <12> to next <12> HJR
|
||
MOVE.W (A0),SleepTime(A2) ; Get latest timeouts
|
||
ADD.W #8,SP ; Free buffer
|
||
_IdleUpdate
|
||
BRA.S @exit
|
||
|
||
@TerrorMachines
|
||
TST.B LastLevel(A2) ; Is the level -1
|
||
BPL.S @Next ; Not try next check
|
||
BCLR #PmgrWakeLvlSet,PmgrFlags(A2) ; Is the semaphor set
|
||
BEQ.S @FinishUp ; Nope. Then skip and go on
|
||
MOVE.B #(PMGRWARNLEVEL-STDOFFSET),D0 ; Otherwise, set warning level to 5.90 V
|
||
BSR.S @SetPmgrLevl ; go do it...
|
||
BRA.S @FinishUp ; and get on with life
|
||
|
||
@Next CMP.B #4,LastLevel(A2) ; Check if we are in level 4
|
||
BNE.S @FinishUp ; If not, go on
|
||
|
||
TST.B Level4Cnt(A2) ; Is it the first time through
|
||
BNE.S @FinishUp ; If not, go On
|
||
|
||
MOVE.B #(PGMRWAKELEVEL-STDOFFSET),D0 ; Set hysteresis to 6.09
|
||
BSET #PmgrWakeLvlSet,PmgrFlags(A2) ; Set the semaphor
|
||
BSR.S @SetPmgrLevl ; go do it...
|
||
|
||
|
||
@FinishUp TST.B TOdirtyFlag(A2) ; Check for new timeouts
|
||
BEQ.S @exit
|
||
|
||
CLR.B TOdirtyFlag(A2) ; Clear the dirty flag
|
||
SUB.W #8,SP ; allocate some stack space
|
||
MOVE.L SP,A0 ; set param block
|
||
MOVE.L #$080070,D0 ; Read our parameters
|
||
_ReadXPRam
|
||
|
||
MOVE.B 2(A0),SleepFlags(A2) ; Terror use Pram 72 as SleepFlags <r9> HJR
|
||
MOVE.W (A0),SleepTime(A2) ; Get latest timeouts
|
||
ADD.W #8,SP ; free the buffer
|
||
_IdleUpdate
|
||
|
||
@exit RTS
|
||
|
||
@SetPmgrLevl
|
||
LEA -(PmBlkSize+4)(SP),SP ; Get a little storage
|
||
LEA @SetLvlParm,A0 ; point to the packet
|
||
MOVE.B D0,2(A0) ; set the appropriate level
|
||
MOVE.L A0,pmSBuffer(SP) ; point to the packet
|
||
MOVE.W #3,pmLength(SP) ; send 3 bytes
|
||
MOVE.W #xPramWrite,pmCommand(SP); write to x pram
|
||
MOVE.L SP,A0 ; set pointer
|
||
_PmgrOp
|
||
LEA (PmBlkSize+4)(SP),SP ; Release stack frame
|
||
RTS
|
||
|
||
@SetLvlParm
|
||
DC.B ($42) ; pram byte 0x42
|
||
DC.B 1 ; one bytes of data
|
||
DC.B 0 ; warn level to set on pmgr <12> from last <12> HJR
|
||
|
||
ENDPROC
|
||
|
||
|
||
|
||
;=================================================================================== <r9> thru next <r9> djw
|
||
; PowerMiscPatches - collection of all the Terror patches
|
||
;
|
||
; This routine calls all the different Terror ROM specific patches.
|
||
;
|
||
;===================================================================================
|
||
|
||
machine mc68030
|
||
|
||
InstallPowerMgrPatches PROC EXPORT
|
||
|
||
bsr ResetSoftwareCutoff ; reset the power mgr's shutdown level
|
||
bsr InitializeStrings ; init all warning and alert strings
|
||
bsr InstallSleepTask ; install sleep queue task to do general patches
|
||
bsr PatchSetCursor ; patch _SetCursor to check for activity
|
||
bsr PatchSndVBL ; install a new SndWatch VBL
|
||
bsr PatchBatInt ; install a new BatInt handler <r16> HJR
|
||
bsr PatchBatWatchVBL ; install a new BatWatch VBL <r9> HJR
|
||
bsr PatchPmgrOp ; patch _PmgrOp
|
||
|
||
rts ; <r9> from last <r9> djw
|
||
|
||
;___________________________________________________________________________________
|
||
; Routine: ResetSoftwareCutoff
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Destroys: a1
|
||
;
|
||
;___________________________________________________________________________________
|
||
|
||
ResetSoftwareCutoff
|
||
|
||
WITH PmgrRec,PmgrPramRec ; <12> HJR
|
||
WITH SleepQRec,pmCommandRec ; <11> rb
|
||
|
||
; set 68k cutoff voltage in pmgr globals
|
||
move.l PmgrBase,A1
|
||
lea -(PmBlkSize+4)(SP),SP ; Get a little storage
|
||
|
||
; set pmgr cutoff voltage
|
||
lea @PRAM_PACKET,a0 ; point to the packet
|
||
move.l a0,pmSBuffer(sp) ; point to the packet
|
||
move.w #4,pmLength(SP) ; <12> HJR
|
||
move.w #xPramWrite,pmCommand(SP) ; write to x pram
|
||
move.l SP,A0
|
||
_PmgrOp
|
||
BCLR #PmgrWakeLvlSet,PmgrFlags(A1) ; Clear Hysterosis semaphor <12> to next <12> HJR
|
||
move.b #(NEWCUTOFF-STDOFFSET),Cutoff(a1) ; set the new cutoff threshold to 5.75
|
||
MOVE.B #(PMGRWARNLEVEL-STDOFFSET),LowWarn(a1) ; set the new low warning threshold
|
||
MOVE.L #((PmgrPramSize<<16)+\
|
||
PmgrPramBase),D0 ; Read all PMGR/Esprit data
|
||
_ReadXPRam
|
||
|
||
TST.B SlpTimeOut(A0) ; Check for zeroed Sleep time out
|
||
BEQ.S @dowrite
|
||
|
||
TST.B HDTimeOut(A0) ; Check for zeroed time outs and warning levels
|
||
BNE.S @skipwrite
|
||
|
||
@dowrite MOVE.B #DfltSlpTime,(A0) ; Init default time outs
|
||
MOVE.B #DfltHDTime,1(A0)
|
||
MOVE.L #((2<<16)+PmgrPramBase\
|
||
+SlpTimeOut),D0 ; Write
|
||
_WriteXPRam ; Set them
|
||
|
||
MOVE.W #((DfltSlpTime << 8) +\
|
||
DfltHDTime),SleepTime(A1) ; Writeout values to globals
|
||
|
||
@skipwrite lea (PmBlkSize+4)(SP),SP ; Release stack frame
|
||
|
||
move.w #$c0,PwrCycProgMax(a1) ; set max powercycle level lower <12> from last <12> HJR
|
||
|
||
rts
|
||
|
||
@PRAM_PACKET dc.b ($42) ; pram byte 0x42
|
||
dc.b 2 ; <8> two bytes of data
|
||
dc.b (PMGRWARNLEVEL-STDOFFSET) ; <8> warn level to set on pmgr
|
||
dc.b (NEWCUTOFF-STDOFFSET) ; cutoff to set tono pmgr
|
||
align 4 ; <r9> djw
|
||
|
||
|
||
;___________________________________________________________________________________
|
||
; Routine: InitializeStrings
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Destroys: d0-d3,a0-a2
|
||
;
|
||
;___________________________________________________________________________________
|
||
|
||
InitializeStrings
|
||
|
||
LPsicnNum EQU -16386 ; Small battery icon
|
||
LPstr0NumBL EQU -16511
|
||
LPstr2NumBL EQU -16516 ; Added new one for Andy <r9> HJR
|
||
LPstr3NumBL EQU -16513
|
||
|
||
BatstrWarn0 EQU -16514 ; <t5> new bad battery strings
|
||
BatstrWarn1 EQU -16515
|
||
|
||
WITH PmgrRec
|
||
|
||
MOVE.L PmgrBase,A2
|
||
MOVE.L #'SICN',D1
|
||
|
||
MOVE.W #LPsicnNum,D2
|
||
BSR GetDetachRes ; Get the battery icon
|
||
BEQ.S @getstrings
|
||
MOVE.L A1,lpSICNHndl(A2) ; Save the handle locally
|
||
|
||
@getstrings move.w #LPstr0NumBL,D2 ; get first warning string
|
||
move.l #lpSTR0Ptr,D3
|
||
bsr LoadString
|
||
|
||
move.w #LPstr2NumBL,D2 ; get 25% warning string
|
||
move.l #lpSTR2Ptr,D3
|
||
bsr.s LoadString
|
||
|
||
move.w #LPstr3NumBL,D2 ; get 10 second warning
|
||
move.l #lpSTR3Ptr,D3
|
||
bsr.s LoadString
|
||
|
||
|
||
@batterywarn move.w #BatstrWarn0,D2 ; <t5> get 1st battery warning
|
||
move.l #BBSTR0Ptr,D3
|
||
bsr.s LoadString
|
||
|
||
move.w #BatstrWarn1,D2 ; <t5> get 2nd battery warning
|
||
move.l #BBSTR1Ptr,D3
|
||
bsr.s LoadString
|
||
|
||
rts
|
||
|
||
;------------------------------------------------------------------------------------------
|
||
;
|
||
; LoadString - used to load a low power string into the power manager globals
|
||
;
|
||
; input
|
||
; a2 - pointer to powermgr
|
||
; d2 - string resource id
|
||
; d3 - offset of string pointer in powermanager
|
||
;
|
||
; output
|
||
; none
|
||
;
|
||
; usage
|
||
; d d1 - resource type
|
||
; d2 - string resource id
|
||
; d3 - offset of string pointer in powermanager
|
||
; d a1 - handle to string
|
||
; a2 - pointer to powermgr
|
||
;------------------------------------------------------------------------------------------
|
||
|
||
LoadString move.l #'STR ',d1 ; set to string resource type
|
||
bsr.s GetDetachRes ; get and detach string resource
|
||
beq.s @exit ; if no string, exit
|
||
move.l (a1),(a2,d3) ; else install pointer in pmgr globals
|
||
@exit rts ; done
|
||
|
||
; Gets and detaches a resource.
|
||
; Parameters:
|
||
; D1 Resource Type
|
||
; D2 Resource ID
|
||
; Returns:
|
||
; A1 Handle to resource
|
||
; Registers:
|
||
; D0/A0 destroyed
|
||
|
||
GetDetachRes
|
||
SUBQ.L #4, SP ; For return address
|
||
MOVE.L D1, -(SP) ; Resource type
|
||
MOVE.W D2, -(SP) ; Resource ID
|
||
_GetResource
|
||
MOVE.L (SP), A1 ; Get resource handle to return
|
||
_DetachResource
|
||
MOVE.L A1,D0 ; Set result code
|
||
RTS
|
||
|
||
|
||
;___________________________________________________________________________________ <r9> thru next <r9> djw
|
||
; Routine: InstallSleepTask
|
||
;
|
||
; Install a new sleep queue element to handle miscellaneous system sleep patches.
|
||
; These include saving the state of the cursor before going to sleep and restore
|
||
; it after waking up. On wakeup, check the state of DFAC (sound input). If a
|
||
; source is selected, then power on Batman, otherwise do nothing (the ROM already
|
||
; powered Batman off).
|
||
;
|
||
; Also patch out the Sleep trap to fix a re-entrancy problem.
|
||
;
|
||
; Inputs: none
|
||
; Outputs: none
|
||
;___________________________________________________________________________________
|
||
InstallSleepTask
|
||
|
||
MOVE.L A1,-(SP) ; Save Register
|
||
|
||
LeaResident SleepPtch,A0 ; Get address of sleep code
|
||
MOVE.W #$A08A,D0 ; Set the trap
|
||
_SetTrapAddress ,newOS ; Install the trap
|
||
|
||
MOVE.L #SleepqSize+12,D0 ; Size pf Sleep Queue element plus some extra
|
||
_NewPtr ,SYS,CLEAR
|
||
LeaResident SleepMiscTask,A1 ; Get pointer to Sleep Queue element
|
||
MOVE.L A1,SleepqProc(A0) ; Set the Proc Pointer to our handle
|
||
MOVE.W #slpQType,SleepqType(A0) ; Set the proper type
|
||
_SlpQInstall ;
|
||
MOVE.L (SP)+,A1 ; Restore Register
|
||
RTS
|
||
|
||
|
||
;_________________________________________________________________________________________
|
||
; PatchSetCursor - head patch setcursor
|
||
;
|
||
; Head patch setcursor to check for activity.
|
||
;_________________________________________________________________________________________
|
||
|
||
|
||
PatchSetCursor
|
||
move.w #$a851,d0 ; trap number for _SetCursor
|
||
_GetTrapAddress ,NewTool ; get addr of _SetCursor
|
||
leaResident OldSetCursor,a1
|
||
move.l a0,(a1) ; save the old address to chain to
|
||
|
||
move.w #$a851,d0 ; trap number for _SetCursor
|
||
leaResident SetCursorPatch,a0 ; address of head patch
|
||
_SetTrapAddress ,NewTool ; install head patch
|
||
rts
|
||
|
||
|
||
;_________________________________________________________________________________________
|
||
; PatchSndVBL - install SndWatch VBL
|
||
;
|
||
; Replace the ROM SndWatch VBL because it does not take DFAC activity into
|
||
; consideration before it clears the sound latch. This will correct a problem where
|
||
; on waking from sleep, if recording was on before sleep, it is now off.
|
||
;_________________________________________________________________________________________
|
||
|
||
PatchSndVBL
|
||
movea.l PmgrBase,a2 ; get power mgr globals
|
||
lea SwVBLTask(a2),a0 ; a0 = ptr to SndWatch VBL queue blk
|
||
_VRemove ; remove it from the queue
|
||
leaResident NewSndWatch,a1 ; a1 = addr of new SndWatch resident code
|
||
move.l a1,vblAddr(a0)
|
||
move.w #1,vblCount(a0) ; enable vbl element
|
||
_Vinstall
|
||
|
||
leaResident ModemSndOnInt,a0 ; patch out modem sound int handler
|
||
move.l PmgrBase,a1 ; get pointer to globals
|
||
move.l a0,MdmSndVect(a1) ; set new modem sound handler
|
||
|
||
rts
|
||
|
||
;_________________________________________________________________________________________
|
||
; PatchBatInt - install the new BatInt <r16> HJR
|
||
;
|
||
; Fix bug where system crashes when a new a low power dialog comes in after the shorted
|
||
; battery dialog is set.
|
||
;_________________________________________________________________________________________
|
||
|
||
PatchBatInt
|
||
movea.l PmgrBase,a2 ; get power mgr globals
|
||
leaResident NewBatInt,a1 ; a1 = ptr to NewBatInt handler
|
||
move.l a1,vBatInt(a2) ; save the vector
|
||
rts
|
||
|
||
;_________________________________________________________________________________________
|
||
; PatchBatWatchVBL - install BatWatch VBL <r9> HJR
|
||
;
|
||
; Replace the ROM Batwatch VBL because it does not work.
|
||
;_________________________________________________________________________________________
|
||
|
||
PatchBatWatchVBL
|
||
movea.l PmgrBase,a2 ; get power mgr globals
|
||
lea BatVBLTask(a2),a0 ; get pointer to vbl queue element
|
||
_VRemove ; remove it from the queue
|
||
leaResident BatWatch,a1
|
||
move.l a1,vblAddr(a0)
|
||
move.w #1,vblCount(a0) ; enable vbl element
|
||
_Vinstall
|
||
rts
|
||
|
||
;_________________________________________________________________________________________
|
||
; PatchPmgrOp - patch _PmgrOp
|
||
;
|
||
; Install a patch to _PmgrOp to delay 100µs after a power on/off command before
|
||
; returning to the caller. This is a preventative measure to take into account that
|
||
; the pmgr micro may not have actually executed the command request when it acknowledges.
|
||
; A race condition exist where the caller may assume the power on something is on or off
|
||
; when it actually is not.
|
||
;_________________________________________________________________________________________
|
||
|
||
PatchPmgrOp
|
||
move.w #$a085,d0 ; trap number for _PmgrOp
|
||
leaResident PmgrOpPatches,a0 ; address of patch
|
||
_SetTrapAddress ,NewOS ; install patch
|
||
rts
|
||
|
||
endp ; end installproc
|
||
|
||
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
; ABOVE THIS POINT IS INSTALL CODE FOR TERROR PATCHES. BELOW THIS POINT IS RESIDENT
|
||
; PATCH CODE.
|
||
;=========================================================================================
|
||
;=========================================================================================
|
||
|
||
;_________________________________________________________________________________________
|
||
; SleepPatch
|
||
;
|
||
; This is a patch to the sleep trap so to fix a reentracy bug.
|
||
; Sleep Selector (only valid selectors)
|
||
; d0 - 1 - SleepRequest
|
||
; 2 - SleepDemand
|
||
; 6 - SleepNow
|
||
;
|
||
; input
|
||
; d0 sleep type
|
||
; d1 trapword
|
||
;
|
||
; output
|
||
; none
|
||
;
|
||
; usage
|
||
; d0 sleep type
|
||
; d1 trap word
|
||
; d2 copy of sleep type
|
||
; d3 condition code test register
|
||
;
|
||
; a0 pointer to first element/ ptr to pmgrglobals
|
||
; a1 pointer to network hook
|
||
;_________________________________________________________________________________________
|
||
|
||
SleepPtch PROC
|
||
WITH PmgrRec
|
||
|
||
BTST #9,D1 ; $A28A
|
||
BEQ.S @TryNext ; Check if condition code is set
|
||
JmpROM SlpQInstall
|
||
@TryNext
|
||
BTST #10,D1 ; $A48A
|
||
BEQ.S @Sleep ; Check if condition code is set
|
||
JmpROM SlpQRemove
|
||
@Sleep ; $A08A
|
||
MOVE.L PMgrBase,A0 ; Get Power Manager Base Pointer
|
||
BTST #InSleep,PmgrFlags(A0) ; test and set sleep semaphore
|
||
BNE.S @Exit ; if in sleep, exit! don't re-enter
|
||
|
||
MOVE.L D0,D1 ; Save the sleep type
|
||
JsrROM SetSupervisorMode ; Set the machine to supervisor mode
|
||
MOVE.W D0,PwrCycSave.PCRSRsave(A0) ; Save the store away the status register
|
||
MOVE.L D1,D0 ; restore the sleep type
|
||
bsr.s DreamAway ; <15> Take a snooze the new way
|
||
MOVE.W PwrCycSave.PCRSRsave(A0),SR ; Restore the Status Register to the proper world
|
||
@Exit
|
||
RTS
|
||
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ <8> HJR
|
||
; <15> Sleep queue fix.
|
||
|
||
DreamAway ; <15>
|
||
SleepRegs REG A0-A6/D1-D7
|
||
MOVEM.L SleepRegs,-(SP) ; Save registers
|
||
MOVE.L D0,D2 ; Save a sleep type in D2
|
||
|
||
@checkinprogress
|
||
BSET #InSleep,PmgrFlags(A0) ; test and set sleep semaphore <17> ag
|
||
BNE.S @exitsleep ; if in sleep, exit! don't re-enter
|
||
|
||
@checkAuto
|
||
CMP.B #SleepRequest,D0 ; auto sleep request
|
||
BEQ.S @validselector
|
||
|
||
@checkDemand
|
||
CMP.B #SleepDemand,D0 ; User sleep, from finder or command key
|
||
BEQ.S @validselector
|
||
|
||
@checkNow
|
||
CMP.B #SleepNow,D0 ; Critical low power sleep <v1.4>
|
||
BNE.S @abortsleep
|
||
|
||
@validselector
|
||
MOVE.W PwrCycSave.PCRSRsave(A0),SR ; Restore the SR so that when VM is on the queue is run in User Mode
|
||
|
||
BCLR #AvoidNetDiag,PmgrFlags(A0) ; <t3> tst/clear the avoid bit
|
||
BNE.S @traverse ; <t30> if bit was set, skip dialog
|
||
|
||
MOVE.L SleepNetHook(A0),D1 ; Test for presence of valid hook
|
||
BEQ.S @closeAT ; Nope. Branch
|
||
|
||
MOVEA.L D1,A1
|
||
JSR (A1) ; Hook
|
||
BNE.S @abortsleep ; IF Bad Close THEN branch
|
||
BRA.S @traverse ; ELSE run the queue
|
||
|
||
@closeAT jsrRom ROMCheckAppleTalk ; Close AppleTalk <v1.4>
|
||
BNE.S @abortsleep ; Branch if close denied
|
||
|
||
@traverse MOVE.W D2,D0 ; Restore D0
|
||
CMP.W #SleepNow,D0 ; If passing sleepnow to sleepq then change it
|
||
BNE.S @doQ ; to a sleep demand
|
||
MOVEQ #SleepDemand,D0 ; sleepNow -> sleepDemand
|
||
|
||
@doQ BSR DoQueueStack ; Walk the queue
|
||
MOVE.L D0,D1 ; Save a copy of DoQueueStack result
|
||
jsrRom SetSupervisorMode ; Return to supervisor mode so that we may continue
|
||
TST.L D1 ; DoQueueStack == Ok to goto sleep ?
|
||
BNE.S @abortsleep ; Nope. Get out!
|
||
jsrRom CloseAppleTalk ; Else shut down atalk
|
||
BCLR #InSleep,PmgrFlags(A0) ; clr the sleep indicator <17> ag
|
||
jmpRom didqueue ; Do the sleep shutdown
|
||
|
||
@abortsleep jsrRom SetSupervisorMode ; Set the machine to supervisor mode <22> ag
|
||
BCLR #InSleep,PmgrFlags(A0) ; Clear the sleep indicator <17> ag
|
||
|
||
@exitsleep MOVE.W D2,D0 ; Restore sleep type to D0
|
||
MOVEM.L (SP)+,SleepRegs
|
||
RTS
|
||
|
||
ENDPROC ; SleepPtch
|
||
|
||
;_________________________________________________________________________________________
|
||
; SleepMiscTask
|
||
;
|
||
; This sleep task is run for both sleep and wakeup. It executes all the miscellaneous
|
||
; system patches which can fit in a sleep queue task.
|
||
;
|
||
; Cursor state across sleep:
|
||
; Save the state of the cursor in extra space of the sleep queue element on sleep, and
|
||
; restore the state of the cursor on wakeup.
|
||
;
|
||
; Batman power state on wakeup:
|
||
; If sound input is active (i.e. there is an input source selected on DFAC), then power
|
||
; on Batman.
|
||
;
|
||
; Input: A0 = Ptr to sleep queue element
|
||
; D0 = sleep command
|
||
;
|
||
; Output: D0 - Result code.
|
||
;_________________________________________________________________________________________
|
||
|
||
Proc
|
||
Export SleepMiscTask
|
||
WITH PMgrRec ; <12> HJR
|
||
WITH SleepQRec,pmCommandRec ; <11> rb
|
||
|
||
SleepMiscTask
|
||
BRA.S @HandleCommand ; Handle Sleep Queue Demand
|
||
|
||
@SlpQueueDisp ; Table of offset to selector routines
|
||
DC.W @SlpRequest-@SlpQueueDisp ; SleepRequest = 1
|
||
DC.W @SlpDemand-@SlpQueueDisp ; SleepDemand = 2
|
||
DC.W @SlpWakeUp-@SlpQueueDisp ; SleepWakeUp = 3
|
||
DC.W @SlpUnlock-@SlpQueueDisp ; SleepUnlock = 4
|
||
DC.W @SlpDeny-@SlpQueueDisp ; SleepDeny = 5
|
||
@LastVect DC.W @SlpNow-@SlpQueueDisp ; SleepNow = 6
|
||
|
||
@HandleCommand
|
||
SUBQ.W #1,D0 ; Convert commands to zero base
|
||
CMP.W #(@LastVect-@SlpQueueDisp)/2,D0; check if in range
|
||
BHI.S @OutOfRange ; Nope. Out of here folks
|
||
MOVE.W @SlpQueueDisp(D0.W*2),D0 ; get the offset to that routine
|
||
JMP @SlpQueueDisp(D0) ; Jump to that routine
|
||
|
||
@OutOfRange
|
||
MOVE.W #paramErr,D0 ; Abort and return error
|
||
RTS
|
||
|
||
@SlpRequest BRA.S @Done ; Bye folks
|
||
|
||
@SlpDemand BSR.S SaveCursor ; Time to save the cursor
|
||
moveq #SleepDemand,d0 ; tell blocksonyvbl what kind of queue event<15> ag
|
||
BSR BlockSonyVBL ; <15> ag
|
||
BRA.S @Done
|
||
|
||
@SlpWakeUp BSR.S RestoreCursor ; Restore Cursor
|
||
BSR.S BatmanPower ; decide whether to power on sound
|
||
BSR.S SetPwrLvlTask ; Set PowerMgr power level <12> HJR
|
||
moveq #SleepWakeUp,d0 ; tell blocksonyvbl what kind of queue event<15> ag
|
||
BSR BlockSonyVBL ; <15> ag
|
||
BRA.S @Done
|
||
|
||
@SlpUnlock
|
||
@SlpDeny BRA.S @Done ; Bye folks
|
||
|
||
@SlpNow BSR.S SaveCursor ; Time to save the cursor
|
||
** BRA.S @Done ; (fall thru)
|
||
|
||
@Done MOVEQ #0,D0 ; Return noErr
|
||
RTS
|
||
|
||
;_________________________________________________________________________________________
|
||
; SaveCursor - misc sleep queue task
|
||
;
|
||
; This routine will save the current cursor in some extra space allocated in the
|
||
; sleep queue element.
|
||
;
|
||
; Enter: A0 - Ptr to sleep queue element
|
||
;
|
||
; Exit: none
|
||
;_________________________________________________________________________________________
|
||
|
||
SaveCursor
|
||
MOVE.L A1,-(SP) ; Save register
|
||
MOVE.L (A5),A1 ; point to QuickDraw globals
|
||
LEA Arrow(A1),A1 ; Get pointer to current cursor
|
||
MOVE.L A1,SleepqSize(A0) ; save the address of cursor in our little storage
|
||
MOVE.L (SP)+,A1 ; Restore register
|
||
RTS ; Goodbye
|
||
|
||
;_________________________________________________________________________________________
|
||
; RestoreCursor - misc sleep queue task
|
||
;
|
||
; This routine will restore the state of the cursor after wake-up with the cursor stored
|
||
; in the queue element.
|
||
;
|
||
; Enter: A0 - Ptr to sleep queue element
|
||
;
|
||
; Exit: none
|
||
;_________________________________________________________________________________________
|
||
|
||
RestoreCursor
|
||
MOVE.L SleepqSize(A0),-(SP) ; Get ptr to saved crsr in slpqueue element
|
||
_SetCursor ; Set the cursor
|
||
_ShowCursor ; Show it to the world
|
||
RTS ; Goodbye
|
||
|
||
;_________________________________________________________________________________________
|
||
; BatmanPower - misc sleep queue task
|
||
;
|
||
; The ROM on waking from sleep has powered off Batman. Because we forgot to do this
|
||
; in the ROM, we must now check the state of DFAC. If a sound input source has been
|
||
; selected, then power Batman back on so sound input will work.
|
||
;
|
||
; Input: a0 = ptr to sleep queue element
|
||
;
|
||
; Output: none
|
||
;_________________________________________________________________________________________
|
||
|
||
BatmanPower
|
||
jsrTbl sndInputSource ; get current DFAC input source
|
||
tst.b d0 ; anything selected?
|
||
beq.s @Done ; nothing selected
|
||
|
||
move.l a0,-(sp) ; save reg
|
||
suba.w #4,sp
|
||
movea.l sp,a0 ; a0 = ptr to data buf
|
||
move.b #sndOnclrLtch,(a0) ; Turn on sound power and clear the latch
|
||
moveq.l #1,d1 ; One byte to send
|
||
move.w #SoundSet,d0 ; PMGR command, set sound state
|
||
jsrROM PMGRsend
|
||
adda.w #4,sp ; restore stack
|
||
movea.l (sp)+,a0 ; restore reg
|
||
@Done
|
||
rts
|
||
;_________________________________________________________________________________________ <12> HJR
|
||
; SetPwrLvlTask -
|
||
;
|
||
; This routine on wakeup set the power manager power levels to appropriate wakeup
|
||
; values since it might have changed due to the 10 second level 4 count down.
|
||
;
|
||
; Input: None
|
||
;
|
||
; Output: None
|
||
;_________________________________________________________________________________________
|
||
SetPwrLvlTask
|
||
MOVE.L A0,-(SP) ; Save this guy
|
||
MOVE.L PMgrBase,A0 ; Get our globals
|
||
BCLR #PmgrWakeLvlSet,PmgrFlags(A0) ; Clear Hysteresis semaphore
|
||
LEA -(PmBlkSize+4)(SP),SP ; Get a little storage
|
||
LEA @PramPak,A0 ; point to the packet
|
||
MOVE.L A0,pmSBuffer(SP) ; point to the packet
|
||
MOVE.W #3,pmLength(SP)
|
||
MOVE.W #xPramWrite,pmCommand(SP); write to x pram
|
||
MOVE.L SP,A0
|
||
_PmgrOp
|
||
LEA (PmBlkSize+4)(SP),SP ; Release stack frame
|
||
MOVE.L (SP)+,A0 ; Restore this guy
|
||
RTS
|
||
|
||
@PramPak
|
||
DC.B ($42) ; pram byte 0x42
|
||
DC.B 1 ; one bytes of data
|
||
DC.B (PMGRWARNLEVEL-STDOFFSET); warn level to set on pmgr
|
||
@pad dc.b 0 ; pad
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: BlockSonyVBL <15> ag
|
||
;
|
||
; Inputs: D0 - sleep flag
|
||
;
|
||
; Outputs: D0 - result code (always zero)
|
||
;
|
||
; Trashes: none
|
||
;
|
||
; Function: disables the Sony driver's VBL task before going to sleep, and then enables it
|
||
; after waking up so the VBL task can't run before the SWIM chip is re-initialized
|
||
;________________________________________________________________________________________
|
||
BlockSonyVBL
|
||
|
||
active EQU 25 ; 0: .Sony driver is busy
|
||
|
||
MOVE.L A1,-(SP)
|
||
MOVEA.L SonyVars,A1 ; point to the Sony driver's variables
|
||
SUBQ.W #SleepWakeUp,D0 ; are we going to sleep or waking up?
|
||
SNE active(A1) ; $00=wakeup, $FF=sleep
|
||
MOVEA.L (SP)+,A1
|
||
MOVEQ #0,D0 ; always return zero
|
||
RTS
|
||
|
||
ENDPROC
|
||
|
||
;_________________________________________________________________________________________
|
||
; SetCursorPatch - check for activity
|
||
;
|
||
; Head patch SetCursor to check for activity. If SetCursor is called and the cursor
|
||
; is different from the current cursor, then we use this to indicate some level of
|
||
; program activity. Also, check specifically for the system watch cursor, and if set,
|
||
; then disable idle. If the cursor is just changing, then do an _IdleUpdate to give
|
||
; back some time.
|
||
;
|
||
; Input: 4(sp) = ptr to cursor record
|
||
;
|
||
; Output: none
|
||
;
|
||
;_________________________________________________________________________________________
|
||
|
||
Proc
|
||
Export SetCursorPatch
|
||
Export OldSetCursor
|
||
|
||
SetCursorPatch
|
||
|
||
|
||
with PowerDispRec,PmgrRec
|
||
|
||
|
||
; Check if we are updating to a different cursor from the last time
|
||
|
||
move.l a2,-(sp) ; save reg
|
||
|
||
movea.l PmgrBase,a2 ; a2 = ptr to power mgr globals
|
||
move.l 4+4(sp),d0 ; get current addr of curRec (skipping past the saved A2)
|
||
_StripAddress ; make it clean
|
||
cmp.l RAMwatchPtr(a2),d0 ; are we updating the same cursor?
|
||
beq.s @Done ; same one - do nothing
|
||
move.l d0,RAMwatchPtr(a2) ; different - update to latest addr of curRec
|
||
|
||
; Check the new cursor mask to see if it is the watch cursor
|
||
|
||
lea @WatchMask,a0 ; get mask of watch cursor
|
||
movea.l d0,a1 ; a1 = ptr to cursRec
|
||
adda.w #mask,a1 ; a1 = ptr to mask of new cursor
|
||
moveq.l #8-1,d0 ; compare 8 longs (adjusted for dbra)
|
||
@Loop
|
||
cmpm.l (a0)+,(a1)+
|
||
dbne d0,@Loop ; loop until not equal
|
||
tst.b d0 ; did we finish loop?
|
||
bpl.s @notWatch ; not the watch cursor
|
||
|
||
; Watch cursor found - disable power cycling
|
||
|
||
bset.b #0,watchCrsr(a2) ; test and set watch cursor flag
|
||
bne.s @Done ; watch already detected
|
||
moveq.l #IdleDisableDisp,d0
|
||
_PowerDispatch ; disable power cycling
|
||
bra.s @Done
|
||
|
||
; Not the watch cursor - do an _IdleUpdate
|
||
|
||
@notWatch
|
||
_IdleUpdate ; give time back to system
|
||
bclr.b #0,watchCrsr(a2) ; test and clr watch cursor flag
|
||
beq.s @Done ; not changing from the watch cursor
|
||
moveq.l #IdleEnableDisp,d0
|
||
_PowerDispatch ; enable power cycling
|
||
|
||
; Continue with the _SetCursor
|
||
|
||
@Done
|
||
movea.l (sp)+,a2 ; restore reg
|
||
movea.l OldSetCursor(pc),a0 ; chain to old code
|
||
jmp (a0)
|
||
|
||
; Watch cursor mask data
|
||
|
||
@WatchMask
|
||
dc.w $3f00
|
||
dc.w $3f00
|
||
dc.w $3f00
|
||
dc.w $3f00
|
||
dc.w $7f80
|
||
dc.w $ffc0
|
||
dc.w $ffc0
|
||
dc.w $ffc0
|
||
dc.w $ffc0
|
||
dc.w $ffc0
|
||
dc.w $ffc0
|
||
dc.w $7f80
|
||
dc.w $3f00
|
||
dc.w $3f00
|
||
dc.w $3f00
|
||
dc.w $3f00
|
||
|
||
align 4
|
||
|
||
OldSetCursor dc.l 0 ; location of old setcursor address
|
||
|
||
|
||
;_________________________________________________________________________________________
|
||
; NewSndWatch - patch to SndWatch VBL task
|
||
;
|
||
; This routine replaces the SndWatch VBL task in ROM. The ROM routine does not check
|
||
; whether DFAC (sound input) is active when it decides to clear the sound latch.
|
||
;
|
||
; Input: a0 = ptr to VBL queue block
|
||
;
|
||
;_________________________________________________________________________________________
|
||
|
||
Proc
|
||
Export NewSndWatch
|
||
|
||
NewSndWatch
|
||
move.w #SndWFreq,vblCount(a0) ; reset vbl count
|
||
|
||
suba.w #4,sp ; Create stack frame
|
||
movea.l sp,a0
|
||
move.w #SoundRead,d0 ; PMGR command, get sound state
|
||
jsrROM PMGRrecv
|
||
move.b (a0),d2 ; Get sound state
|
||
; (SKH) beq.s @noSound ; branch if no sound activity
|
||
bra.s @noSound ; SKH - Never power down sound.
|
||
|
||
btst.l #1,d2
|
||
bne.s @sndActive ; the latch is set
|
||
|
||
jsrTBL sndInputSource ; does DFAC have a source selected?
|
||
tst.b d0
|
||
bne.s @noSound ; sound input is active - do not power off sound
|
||
|
||
move.b #soundoff,(a0) ; Turn off sound power
|
||
moveq.l #1,d1 ; One byte to send
|
||
move.w #SoundSet,d0 ; PMGR command, set sound state
|
||
jsrROM PMGRsend
|
||
bra.s @noSound
|
||
|
||
@sndActive
|
||
move.b #sndOnclrLtch,(a0) ; Turn on sound power and clear the latch
|
||
moveq.l #1,d1 ; One byte to send
|
||
move.w #SoundSet,d0 ; PMGR command, set sound state
|
||
jsrROM PMGRsend
|
||
|
||
_IdleUpdate ; update activity indicator
|
||
|
||
@noSound
|
||
adda.w #4,sp ; Release stack frame
|
||
rts
|
||
endproc
|
||
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ <r16> HJR to next <r16>
|
||
;
|
||
; NewBatInt -
|
||
;
|
||
; This is a bug fix where the BatInt in rom does not handle remove message
|
||
; properly. Remove message first checks whether the message to be removed
|
||
; is a low power dialog or not. Since the shorted battery dialog is not
|
||
; a low power dialog it disregards the remove. Thus, when a low dialog
|
||
; comes in, the system crashes. The fix is to aviod the check for low power
|
||
; dialog in remove message.
|
||
;
|
||
; Upon entry: A0 - Ptr to power manager data: [flags] [battery] [Gas] [Therm]
|
||
; A1 - VIA base
|
||
; A2 - Ptr to power manager globals
|
||
;
|
||
;
|
||
; A0-A3, D0-D3 are preserved by the interrupt dispatcher.
|
||
;
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
|
||
Proc
|
||
Export NewBatInt
|
||
With PmgrRec
|
||
NewBatInt
|
||
moveq.l #0,d2 ; clear reg
|
||
move.b 1(a0),d2 ; get battery flags
|
||
move.b d2,Charger(a2) ; save charger state
|
||
|
||
btst.l #ShortedBat,d2 ; is there a shorted battery?
|
||
beq.s @Done ; not this time
|
||
|
||
; Shorted battery condition detected - post notification message
|
||
; Remove any pending low power messages and prevent any more from showing up so they
|
||
; don't try to remove the bad battery message.
|
||
|
||
bsr.s @MyRmvMsg ; Remove any pending messages
|
||
st lpMSGvalid(A2) ; Yes, then set the flag in order to remove msg
|
||
JmpRom BatIntCont ; Go back into the rom code
|
||
|
||
@Done rts ;
|
||
|
||
@MyRmvMsg TST.B lpMSGvalid(A2) ; If no messages pending then nothing to remove
|
||
beq.s @nomsg ; Yes. remove low power message
|
||
|
||
MOVE.L D0,-(SP)
|
||
LEA BNmQEntry(A2),A0
|
||
_NMRemove ; Remove low power warning message
|
||
MOVE.L (SP)+,D0
|
||
CLR.B lpMSGvalid(A2) ; No messages pending
|
||
@nomsg RTS
|
||
|
||
endproc ; NewBatInt <r16> HJR
|
||
|
||
|
||
;_________________________________________________________________________________________
|
||
; PmgrOpPatches - _PmgrOp patch
|
||
;
|
||
; This patch is around _PmgrOp. It notes the command to _PmgrOp, and if it is "set
|
||
; power control", then call _PmgrOp but delay returning to the caller for 100µs to
|
||
; give the power manager time to actually execute the command. This avoids a race
|
||
; condition of code trying to access some hardware before it is actually turned on.
|
||
;
|
||
; Input: a0 = ptr to pmgr command pkt
|
||
; d1 = trap word
|
||
; Output: none
|
||
;_________________________________________________________________________________________
|
||
|
||
|
||
Proc
|
||
Export PmgrOpPatches
|
||
WITH PMgrRec ; <12> HJR
|
||
WITH SleepQRec,pmCommandRec ; <11> rb
|
||
|
||
PmgrOpPatches
|
||
|
||
; Head patch to PmgrOp to add a 100µs delay after power control commands
|
||
|
||
cmp.w #powerCntl,pmCommand(a0) ; power control command ?
|
||
bne.s @NewPmgrOp ; no - jmp to power mgr
|
||
|
||
@powerCommand ; <15> <ag>
|
||
movea.l pmSBuffer(a0),a1 ; load pointer to buffer in a1 <16> <ag>
|
||
btst.b #7,(a1) ; test the power on bit <16> <ag>
|
||
beq.s @NewPmgrOp ; if off command, skip delay <15> <ag>
|
||
|
||
jsr @NewPmgrOp ; jsr _PmgrOp
|
||
move.w TimeDBRA,d1 ; <12> HJR
|
||
divu #10,d1 ; divide down to 100µs <12> HJR
|
||
@Loop dbra d1,@Loop ; delay 100µs
|
||
tst.w d0 ; set condition codes
|
||
rts ; we are done
|
||
|
||
; Patch to PmgrOp to patch SerPowerOn
|
||
|
||
@NewPmgrOp
|
||
and.w #$0600,d1 ; extract bits 9 and 10 from trap word
|
||
cmp.w #$0600,d1 ; is it $a685 - SerialPower?
|
||
beq.s @NewSerialPower
|
||
jmpROM ROMPmgrOp ; execute PmgrOp in ROM
|
||
|
||
; New SerialPower patch. On SerPowerOn, assert DTR before modem reset.
|
||
; The code is the same as ROM except for DTR and reset ordering.
|
||
|
||
@NewSerialPower
|
||
btst.l #SerialOff,d0 ; power on or off
|
||
beq.s @SerPowerOn ; do new serial power on
|
||
jmpROM ROMPmgrOp ; start from beginning in ROM
|
||
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
; SerPowerOn - determine power on for serial port
|
||
;
|
||
; Determine what needs to be powered on for the SCC port that is being opened. There
|
||
; are two SCC ports (A/B) which may be connected to the external ports (the modem and
|
||
; printer ports), or the internal modem (for port B only).
|
||
;
|
||
; The following is a summary of the devices and which power manager commands to use
|
||
; to control them.
|
||
;
|
||
; device Pmgr cmd port0 bit signal name
|
||
; ----- --------- ------- -----------
|
||
; SCC powerCntl P01/sccOn *SCC_CNTL
|
||
; external port powerCntl P04/serOn *SERIAL_POWER
|
||
; internal modem powerCntl P03/ModemOn MODEM_PWR
|
||
; modemSet P06 *MODEM_PWROUT
|
||
;
|
||
; Additionally for the internal modem, MODEM_RESET (a Orca/via2 signal) must be
|
||
; manipulated by changing it from an input to and output to de-assert reset.
|
||
;
|
||
; Powering on the SCC and the external ports only involves sending the correct power
|
||
; manager commands. Powering on the internal modem involves some timing delays and a
|
||
; specific sequence of commands.
|
||
;
|
||
; To power the SCC and external ports:
|
||
; turn on SCC
|
||
; turn on external line drivers
|
||
;
|
||
; To power the internal modem:
|
||
; make MODEM_RESET an input (to assert reset) - signal will float up
|
||
; turn on +5V and -5V to modem (MODEM_PWROUT)
|
||
; wait >2ms to allow +5V and -5V to settle
|
||
; enable the modem (*MODEM_PWR)
|
||
; turn on SCC
|
||
; wait >5ms to allow reset time
|
||
; make MODEM_RESET an output
|
||
; write a zero to MODEM_RESET to de-assert reset - drive it low
|
||
;
|
||
; Input : d0 = bit 0: 0 = use internal modem, 1 = ignore internal modem
|
||
; bit 2: 0 = port B, 1 = port A
|
||
;
|
||
|
||
@SerPowerOn
|
||
@savedregs reg d0-d1/a0-a1
|
||
|
||
movem.l @savedregs,-(sp)
|
||
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)
|
||
movea.l sp,a0 ; a0 = ptr to pmgr command pkt
|
||
|
||
; Check whether we should bypass the modem check
|
||
|
||
bclr.l #BypassModem,d0 ; set = ignore modem
|
||
bne @externalPort ; use the external ports
|
||
|
||
; Determine which port we are powering on - if port A then check for modem.
|
||
; The modem may only be connected to port A.
|
||
|
||
tst.b d0 ; d0 = port indicator
|
||
beq @externalPort ; 1 = port A, 0 = port B
|
||
|
||
; On port A - read the modem status. If the modem is not installed power the
|
||
; external port.
|
||
|
||
move.w #modemRead,pmCommand(a0); read the modem's status
|
||
clr.w pmLength(a0) ; clear the count field
|
||
_PmgrOp ; get the modem status
|
||
|
||
move.b pmData(a0),d1 ; d1 = modem status bits
|
||
btst.l #ModemInstalled,d1 ; check the modem installed bit
|
||
beq @externalPort ; modem not installed - use the port
|
||
|
||
; Modem is installed - read extended PRAM to see if modem should be powered on
|
||
|
||
move.l #((1<<16)+PmgrPramBase\
|
||
+PmgrPramRec.PmgrStatusFlags),d0; read Power Manager Flag byte
|
||
_ReadXPRAM ; a0 = ptr to buf (writing over cmd word in pkt)
|
||
btst.b #UseIntrnlModem,(a0) ; check cdev bit for modem
|
||
bne @externalPort ; set - don't power modem
|
||
|
||
; Power on the modem
|
||
|
||
bclr.b #7,([VIA2],vDIRB) ; set MODEM_RESET by making it an input
|
||
|
||
and.b #7,d1 ; mask only <ring wakeup><port select><modem power>
|
||
bset.l #ModemPwr,d1 ; set bit in saved modem status bits
|
||
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
|
||
|
||
move.w TimeDBRA,d0
|
||
asl.w #1,d0 ; calc 2ms delay
|
||
@Delay dbra d0,@Delay ; wait for +5v and -5V to ramp
|
||
|
||
move.b #(sccOn),pmData(a0) ; set bits to power on SCC
|
||
move.w #1,pmLength(a0) ; xmit one byte
|
||
move.w #powerCntl,pmCommand(a0); power control command
|
||
_PmgrOp ; call the power manager
|
||
|
||
move.b #(ModemOn),pmData(a0) ; enable modem - sense of bit is reversed
|
||
move.w #1,pmLength(a0) ; xmit one byte
|
||
move.w #powerCntl,pmCommand(a0); power control command
|
||
_PmgrOp ; call the power manager
|
||
|
||
move.w TimeDBRA,d0
|
||
asl.w #3,d0 ; calc 8ms delay
|
||
@Delay2 dbra d0,@Delay2 ; wait for reset time
|
||
|
||
move.l PmgrBase,a1 ; get pointer to globals
|
||
move.l MdmSndVect(a1),jModemSnd; install in Level 1 VIA1 dispatch table
|
||
move.b #((1<<ifIRQ)+\
|
||
(1<<ifCB2)),([VIA],vIER) ; enable modem sound interrupt
|
||
|
||
bset.b #7,([VIA2],vDIRB) ; clear MODEM_RESET by making it an output
|
||
bclr.b #7,([VIA2],vBufB) ; drive MODEM_RESET low to disable reset
|
||
bra.s @Done
|
||
|
||
; Power on the SCC for the external port
|
||
|
||
@externalPort
|
||
move.b #(sccOn),pmData(a0) ; set bits to power on SCC
|
||
move.w #1,pmLength(a0) ; xmit one byte
|
||
move.w #powerCntl,pmCommand(a0); power control command
|
||
_PmgrOp ; call the power manager
|
||
|
||
@Done
|
||
adda.w #pmBlkSize,sp ; pop power mgr pkt
|
||
movem.l (sp)+,@savedregs
|
||
rts ; <r11> from last <r11> djw
|
||
|
||
|
||
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
|
||
; Modem Sound Interrupt Handlers
|
||
;
|
||
; Modem sound in ROM is implemented through DFAC's aux channel. The aux channel is
|
||
; routed through the by-pass path which does not allow any volume control. People
|
||
; complained, so this patch routes modem sound through the attenuator which allows
|
||
; volume control. The problem is this path is shared with sound input. This patch
|
||
; does not implement any priority to the users of the patch. The last person to
|
||
; set the input source gets it.
|
||
;
|
||
; The modem demands and releases the sound path through the MODEM_SND_ENABLE signal
|
||
; (on VIA1 CB2). The system monitors that bit to determine whether it should enable
|
||
; or disable the modem sound path.
|
||
;
|
||
; When the modem is powered, a CB2 interrupt handler is installed. When the modem
|
||
; demands sound, we immediately enable the sound path. The interrupt handler then
|
||
; re-configures the VIA CB2 interrupt to trigger on the falling edge. A new interrupt
|
||
; handler is installed which disables the sound path. The interrupt handlers ping-pongs
|
||
; back a
|
||
;
|
||
; Input: none
|
||
; Output: none
|
||
;
|
||
|
||
Proc
|
||
Export ModemSndOnInt
|
||
|
||
ModemSndOnInt
|
||
move.b #(1<<ifCB2),([VIA],vIFR) ; clear interrupt flag reg
|
||
move.b SDVolume,d0 ; get current volume
|
||
jsrTBL sndPlayThruVol ; set volume for playthrough
|
||
moveq.l #sndAuxiliary,d0
|
||
jsrTbl sndInputSelect ; select aux source
|
||
|
||
bclr.b #6,([VIA],vPCR) ; change from pos to neg edge int
|
||
lea ModemSndOffInt,a0 ; disable sound routine
|
||
move.l a0,jModemSnd ; install in Level 1 VIA1 dispatch table
|
||
|
||
rts
|
||
|
||
ModemSndOffInt
|
||
move.b #(1<<ifCB2),([VIA],vIFR) ; clear interrupt flag reg
|
||
moveq.l #0,d0 ; disable playthrough <r13> djw
|
||
jsrTBL sndPlayThruVol ; <r13> djw
|
||
moveq.l #sndInputOff,d0
|
||
jsrTbl sndInputSelect ; disable aux source
|
||
|
||
bset.b #6,([VIA],vPCR) ; change from neg to pos edge int
|
||
lea ModemSndOnInt,a0 ; enable sound routine
|
||
move.l a0,jModemSnd ; install in Level 1 VIA1 disÅ table
|
||
|
||
rts
|
||
|
||
|
||
endp ; <r9> from last <r9> djw
|
||
|
||
End
|