mirror of
https://github.com/elliotnunn/mac-rom.git
synced 2025-01-05 08:30:14 +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.
1648 lines
59 KiB
Plaintext
1648 lines
59 KiB
Plaintext
;__________________________________________________________________________________________________
|
||
;
|
||
; File: SysUtil.a
|
||
;
|
||
; Contains: This file contains system utility core routines: ReadParam, WriteParam,
|
||
; ReadDateTime, SetDateTime, InitUtil, Delay, CmpString
|
||
;
|
||
; Written by: Larry Kenyon
|
||
;
|
||
; Copyright © 1982-1993 by Apple Computer, Inc. All rights reserved.
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <SM10> 10/25/93 SAM Roll in <MC2> from mc900ftjesus.
|
||
; <MC2> 10/25/93 SAM Changed InitUtil to explicitly set the memory manager PRAM
|
||
; location to a nonzero default (Figment on, 32 bit heaps).
|
||
; Changed the default mouse speed setting from 2 to 3.
|
||
; <SM9> 6/21/93 SAM Changed the comparison in _Delay to be unsigned (ugh) and bumped
|
||
; the default disk cache size from 32 to 96k.
|
||
; <SM8> 6/14/93 kc Roll in Ludwig.
|
||
; <LW2> 6/11/93 chp Replace the Reliability ManagerÕs Time Manager task with a
|
||
; _DTInstall of the original task code. It is better to call
|
||
; _ReadXPram and _WriteXPram with interrupts enabled since
|
||
; interrupts are used to communicate with Egret/CUDA.
|
||
; <SM7> 1/29/93 RB Made the Delay trap compatible with NuKernel by changing the way
|
||
; it uses the status register.
|
||
; <SM6> 10/18/92 CCH Added NoSound conditional for build-time zeroing of volume.
|
||
; <SM5> 9/28/92 RB The old Sound Manager used to update the low mem global
|
||
; sdVolume, but the new one does not. So I chose the ReadPram and
|
||
; WritePRam routines to update sdVolume after the volume level is
|
||
; changed by the Control Panel, which writes PRAM. Removed the
|
||
; NoSound code used for Cyclone bringup.
|
||
; <SM4> 6/29/92 RB Re-enable sound for the New New Sound Manager.
|
||
; <SM3> 5/28/92 kc Roll in Horror Changes. Comments Follow:
|
||
; <P3> 5/13/92 KW (HJR,H7) Fix problem in InitCPHardware where it was calling a
|
||
; RAMless routine without having the return address in A6.
|
||
; <P2> 02/12/92 jmp ¥¥¥Temporarily set the default sound volume to zero to effectively¥¥¥
|
||
; disable sound on Cyclone.
|
||
; <H6> 11/12/91 jmp Just went back and marked my previous change.
|
||
; <H5> 11/12/91 jmp Changed the pRAM table to default to having the color desktop
|
||
; pattern enabled for CQD-capable CPUs.
|
||
; <H4> 11/6/91 SWC Re-wrote clock and PRAM routines to be table-driven so that
|
||
; future expansion should be really simple (and clean). Hardware
|
||
; dependent routines will now be found in ClockPRAMPrimitives.a.
|
||
; <H3> 10/18/91 SWC Exported ReadTime so the ROM will link (changes in progress
|
||
; caused a little problem with sources out of sync).
|
||
; <H2> 8/6/91 SWC Modified ReadPRAM and WritePRAM so they use extended PRAM calls
|
||
; to get the original 20 PRAM bytes.
|
||
; <SM2> 5/21/92 kc Append "Trap" to the names of
|
||
; SysEnvirons,WriteParam,ReadDateTime,SetDateTime,UprString and
|
||
; RelString to avoid name conflict with the glue.
|
||
; <10> 9/9/91 JSM Cleanup header, use SysEnvirons stuff defined in SysEqu.a
|
||
; instead of redefining it here.
|
||
; <9> 6/12/91 LN Changed #include 'HardwareEqu.a' to 'HardwarePrivateEqu.a'
|
||
; <8> 7/23/90 MSH WriteParam did the read back verify all wrong.
|
||
; <7> 3/22/90 MSH SysUtil and Clock rewritten to place all hardware dependent
|
||
; routines in clock and to remove redundant parameter RAM reading
|
||
; and writing routines. Also added Waimea versions of these
|
||
; routines.
|
||
; <6> 2/28/90 GMR Made changes for Egret code to match new Egret equates.
|
||
; <5> 2/10/90 GMR Put in temporary fix for Egret, using Wr6805Addr instead of
|
||
; WrPram.
|
||
; <4> 2/5/90 GMR Added Egret clock support to ReadTime, WriteTime, and ReadPram,
|
||
; WritePram, making them universal.
|
||
; <3> 1/3/90 CCH Changed Gestalt equate filename back to GestaltEqu.a.
|
||
; <2> 1/2/90 CCH Changed name of Gestalt equate file.
|
||
; <3.7> 11/13/89 MSH Pmgr equates now in record format.
|
||
; <3.6> 8/28/89 PKE Delete LwrString from this file and just use the one in the
|
||
; Script Manager file ScriptMgrPAtch.a (same code, no sense in
|
||
; duplicating it here; should have done this a long time ago).
|
||
; Also delete include of PackMacs.a, ScriptPriv.a.
|
||
; <3.5> 8/27/89 PKE Deleted local newItl2Tables symbol (used for LwrString, was set
|
||
; to 1 here) and cleaned up conditionals based on it.
|
||
; <3.4> 8/24/89 PKE FOR F-19, WE SHOULD DO CHANGE #2 HERE: Rolling in changes from
|
||
; patch files: (1) Change LwrString to save IntlForce flag then
|
||
; clear it before IUGetIntl call, restoring it afterward. This is
|
||
; so we get the itl2 tables for the correct script (instead of the
|
||
; tables for the system script). (2) Put UpperTab bug back in (was
|
||
; removed in 1.5) so file system sorting via RelString works on
|
||
; old volumes.
|
||
; <3.3> 8/22/89 SES Removed references to nFiles. Changed EnvBadSel & EnvSelTooBig
|
||
; to EnvBadVers and EnvVersTooBig.
|
||
; <3.2> 8/9/89 CCH Changed gestaltQuickdrawType to gestaltQuickdrawVersion.
|
||
; <3.1> 7/16/89 CCH NEEDED FOR AURORA: Made SysEnvirons check Gestalt error codes.
|
||
; <3.0> 7/8/89 PKE NEEDED FOR AURORA: Fixed error code returned by LwrString if
|
||
; 'itl2' not found.
|
||
; <2.9> 6/20/89 SWC Changed default mouse tracking from 0 (tablet) to 3
|
||
; (medium-slow) so the mouse won't move like a slug when parameter
|
||
; RAM gets reset. Also to make Ed Birss happy, I hear.
|
||
; <2.8> 6/14/89 SWC Missed an '@' on a label. I know: "bad dog!"
|
||
; <2.7> 6/14/89 SWC Exported PRAMInit and PRAMInitTbl so they can be used by
|
||
; ValidatePRAM (Clock.a). Reformatted the PRAMInit table to make
|
||
; it more readable. Cleaned up code.
|
||
; <2.6> 6/5/89 PKE In LwrString, add more error checking after IUGetIntl call and
|
||
; set error return if necessary.
|
||
; <2.5> 5/25/89 CCH Revised again to deal with new Gestalt equates.
|
||
; <2.4> 5/25/89 rwh added the aptly named Reliability Manager
|
||
; <2.3> 5/24/89 GGD Converted to feature based conditionals.
|
||
; <2.2> 5/23/89 CCH Added check of Gestalt return codes to detect unknown results.
|
||
; <2.1> 5/18/89 CCH Updated SysEnvirons to use new Gestalt interface.
|
||
; <2.0> 4/16/89 CCH Changed Gestalt equates to new prefix convention.
|
||
; <1.9> 4/7/89 PKE Updated LwrString to use noMarkListOffset instead of
|
||
; lowerNoMarkListOffset.
|
||
; <1.8> 3/28/89 PKE Use OS trap bits 9-10 to control function of LwrString
|
||
; <1.7> 3/6/89 CCH Fix some minor bugs in SysEnvirons.
|
||
; <1.6> 3/3/89 CCH Gutted SysEnvirons, and replaced it with calls to Gestalt.
|
||
; <1.5> 3/1/89 PKE Save & restore a2 in LwrString; fixed err in UpperTab (UprString
|
||
; gave 'a' as the uppercase of '`').
|
||
; <1.4> 2/28/89 PKE Revert UprString to version from Mac IIx ROMs, which doesn't
|
||
; move memory or depend on a5 world (the planned version could
|
||
; have done both).
|
||
; <1.3> 2/21/89 PKE Fix LwrString/UprString to get char class & case conversion
|
||
; tables from itl2, not itlR (itlR is going away and these tables
|
||
; are being moved to a newly extended itl2). Note: changing
|
||
; UprString to get tables from any resource could break apps, so
|
||
; it will be reverted to to an old, non-International version as
|
||
; soon as I find the old source. All the Intl stuff will be done
|
||
; thru enhancements to LwrString.
|
||
; <1.2> 1/16/89 GGD Added a scratch register parameter to the BigJSR macro calls
|
||
; since it will be needed when they change to use PC relative
|
||
; addressing.
|
||
; <1.1> 11/10/88 CCH Fixed Header.
|
||
; <1.0> 11/9/88 CCH Adding to EASE.
|
||
; <1.2> 10/27/88 PKE modified by Carl Hewitt and Brian McGhie as part of the process
|
||
; of putting Script Manager in ROM
|
||
; <¥1.1> 9/23/88 CCH Got rid of inc.sum.d and empty nFiles
|
||
; <1.0> 2/10/88 BBM Adding file for the first time into EASEÉ
|
||
; <C982> 12/2/87 JTC Add SysEnvirons trap from patches as new PROC here.
|
||
; <C914> 10/29/87 rwh Port to Modern Victorian
|
||
; <C919> 10/27/87 MSH Bug fixes and added a retry to writetime.
|
||
; <C881> 9/3/87 MSH Port to HcMac (Laguna). Also removed some leftover trash at the
|
||
; end of the file.
|
||
; <C774> 2/9/87 SHF Changed parameter RAM initialization value for boot device: now
|
||
; defaults to SCSI ID 0 (internal).
|
||
; <C551> 12/19/86 GWN Extended PRAM init table.
|
||
; <C518> 12/12/86 GWN Replaced 'Bugs' with 'NuMc' to determine when PRAM is to be
|
||
; initialized with the data in PRAMInitTbl (instead of zeros).
|
||
; <A368> 11/7/86 bbm added an async patch mech.
|
||
; <C206> 10/9/86 bbm Modified to mpw aincludes.
|
||
; 2/19/86 BBM Made some modifications to work under MPW
|
||
; 10/30/85 LAK Incorporated init of new parameter RAM into InitUtil. Set bit 5
|
||
; (13) of Hardware vector if parameter RAM was valid at boot.
|
||
; 10/3/85 BBM added three new Defs for new clock.text
|
||
; 7/24/85 RDC Deleted ClkRW routine (moved to new Clock.text) Changed BSR to
|
||
; JSR for ref's to ClkRW routine
|
||
; 6/7/85 JTC Modified to return long to OS dispatcher. <07Jun85>
|
||
; 2/27/85 JTC Add RelString to return -1,0,1 (<,=,>) rather than simply 0,1.
|
||
; Increase size, but speed, too. Marked... <27Feb85>
|
||
; 1/31/85 LAK Removed false RTE. Exclude all ints when talking to clock chip.
|
||
; 1/23/85 LAK Adapted for new equate files.
|
||
; 9/5/83 SC Changed default volume control to 3; changed init.
|
||
; 8/22/83 LAK Init port A parameter RAM to 9600 baud, etc.
|
||
; 8/21/83 SC Fixed "" "".
|
||
; 8/20/83 LAK Added new parameter ram stuff and changed init.
|
||
; 8/17/83 JTC changed CmpString, UprString for international character sets.
|
||
; 8/17/83 LAK initutil nolonger mucks with the time if param ram check byte is
|
||
; invalid. serial port a is no longer initialized to async.
|
||
; 5/25/83 LAK changed CmpString, UprString to general-purpose string
|
||
; operators.
|
||
; 4/29/83 LAK changed param ram cksum byte to $A6 to reset all machines.
|
||
; 4/27/83 LAK corrected serial port init values for 2 stop bit (not 1 1/2)
|
||
; 4/19/83 LAK added UprString routine; put in SCC config values for default
|
||
; param mem init (9600 baud, 8 data, 2 stop, no parity: both
|
||
; ports).
|
||
; 4/4/83 AJH changed initial value of misc2 param byte
|
||
; 3/10/83 LAK Updated defaults for font, menu flash, volume control.
|
||
; 3/8/83 LAK Fixed bug in Delay.
|
||
; 3/3/83 LAK Updated documentation on CmpString.
|
||
; 2/17/83 LAK ReadParam and WriteParam now preserve A2. InitUtil writes
|
||
; initial values to clock chip if it was not initialized. Added
|
||
; read verify to WriteParam. InitUtil is now a trap and observes
|
||
; Pascal regsave conventions.
|
||
; 2/10/83 LAK moved clock chip r/w procs here from boot code.
|
||
; 2/4/83 LAK put delay back in.
|
||
; 1/12/83 LAK removed Alert, Delay, and CoreWakeUp.
|
||
; 6/10/82 LAK SetDateTime now sets CLasTime to Ticks value.
|
||
; 6/9/82 ALO added Alert proc
|
||
; 6/7/82 LAK added an initialization routine which reads the clock.
|
||
; 5/27/82 LAK changed ReadDateTime, SetDateTime to use keyboard driver to do
|
||
; the work; ReadParam, WriteParam, ReadDateTime, SetDateTime
|
||
; interfaces have all been changed.
|
||
; 5/26/82 LAK changed ReadParam to read copy in memory instead of clock ram
|
||
; changed WriteParam to use keyboard driver to do the work
|
||
;__________________________________________________________________________________________________
|
||
|
||
BLANKS ON
|
||
STRING ASIS
|
||
|
||
LOAD 'StandardEqu.d'
|
||
INCLUDE 'HardwarePrivateEqu.a'
|
||
INCLUDE 'InternalOnlyEqu.a'
|
||
INCLUDE 'GestaltEqu.a'
|
||
INCLUDE 'IOPrimitiveEqu.a'
|
||
INCLUDE 'ReliabilityEqu.a'
|
||
INCLUDE 'UniversalEqu.a'
|
||
|
||
IF &TYPE('NoSound') = 'UNDEFINED' THEN
|
||
NoSound EQU 0 ; If conditional isn't set, default to sound on <SM6>
|
||
ENDIF
|
||
|
||
SysUtil PROC EXPORT
|
||
|
||
EXPORT ReadParam,WriteParamTrap,ReadDateTimeTrap,SetDateTimeTrap
|
||
EXPORT InitUtil,DelayTrap,CmpString,UprStringTrap,RelStringTrap
|
||
EXPORT ASyncPatch
|
||
EXPORT PRAMINITTBL,PRAMINIT,READTIME
|
||
PRINT NOGEN
|
||
|
||
;______________________________________________________________________
|
||
;
|
||
; Routine: ASyncPatch
|
||
; Arguments: none
|
||
; Function: none
|
||
;
|
||
;______________________________________________________________________
|
||
|
||
ASyncPatch ; <A368>
|
||
rts ; <A368>
|
||
|
||
;______________________________________________________________________
|
||
;
|
||
; Routine: ReadParam
|
||
; A0 (input) -- pointer to buffer which returns parameters
|
||
; D0 (input) -- bits 0-19 indicate which of parameter bytes
|
||
; 0-19 to return in the buffer. bytes are
|
||
; returned in 0-19 order.
|
||
; Arguments: D0 (output) -- result code
|
||
; Function: This routine returns the requested bytes from the copy
|
||
; of parameter ram kept in low memory (SysParam).
|
||
;
|
||
;______________________________________________________________________
|
||
|
||
ReadParam LEA SysParam,A1 ; ptr to parameter ram copy in memory
|
||
BSR.S XferPRam ; return requested bytes
|
||
MOVEQ #0,D0 ; never any errors
|
||
RTS
|
||
|
||
XferPRam MOVEQ #20-1,D2 ; D2 is the loop counter (for 20 bytes . . .)
|
||
|
||
XPLoop LSR.L #1,D0 ; read a byte for each one set
|
||
BCC.S @1 ; skip if bit is not set
|
||
MOVE.B (A1),(A0)+ ; load the next byte in return buffer
|
||
@1 ADDQ.L #1,A1 ; incr pointer into parameter ram
|
||
DBRA D2,XPLoop
|
||
RTS
|
||
|
||
;______________________________________________________________________
|
||
;
|
||
; Routine: WriteParam
|
||
; Input: A0 (input) -- pointer to PRAM buffer
|
||
; Arguments: D0 (output) -- result code
|
||
; Function: This routine writes the parameter ram copy in SysParam
|
||
; to the clock chip and then reads it back to verify.
|
||
;______________________________________________________________________
|
||
|
||
WriteParamTrap
|
||
MOVEM.L A0/A1,-(SP) ; save copy of original pointer
|
||
BSR WritePram ; write out SysParam to the chip <30Oct85> LAK
|
||
|
||
LEA GetParam,A1 ; now read it back to verify
|
||
BSR ReadPram ; use our special scratch area
|
||
LEA SysParam,A0 ; point to original data
|
||
MOVEQ #PRWrErr,D0 ; assume parameter ram write error
|
||
MOVEQ #20/4-1,D2 ; loop count for 5 longs
|
||
|
||
@2 CMPM.L (A0)+,(A1)+
|
||
BNE.S @3 ; exit on compare error
|
||
DBRA D2,@2
|
||
|
||
MOVEQ #0,D0 ; no errors
|
||
@3 MOVEM.L (SP)+,A0/A1 ; restore copy of original pointer
|
||
RTS
|
||
|
||
;______________________________________________________________________
|
||
;
|
||
; Routine: ReadDateTime
|
||
; A0 (input) -- pointer to buffer in which time is returned
|
||
; Arguments: D0 (output) -- result code
|
||
; Function: This routine updates Time in memory and then writes
|
||
; it out to the clock chip.
|
||
;
|
||
;______________________________________________________________________
|
||
|
||
ReadDateTimeTrap
|
||
BSR ReadTime
|
||
MOVE.L Time,(A0) ; give it back to requester in buffer
|
||
RTS
|
||
|
||
;______________________________________________________________________
|
||
;
|
||
; Routine: SetDateTime
|
||
; Arguments: D0 (input) -- 32-bit value to write to clock
|
||
; D0 (output) -- result code
|
||
; Function: This routine updates Time in memory and then writes
|
||
; it out to the clock chip.
|
||
;
|
||
;______________________________________________________________________
|
||
|
||
SetDateTimeTrap
|
||
MOVE.L D0,Time ; update the time variable in memory
|
||
BRA WriteTime ;
|
||
|
||
;______________________________________________________________________
|
||
;
|
||
; Routine: Delay
|
||
; Arguments: A0 (input) -- number of tick counts to delay
|
||
; D0 (output) -- value of Ticks after delay
|
||
; interrupt level 0 is set
|
||
; Function: Delay is a simple routine which just waits the
|
||
; specified number of ticks (each tick is 1/60 second).
|
||
;
|
||
;______________________________________________________________________
|
||
|
||
DelayTrap ANDI.W #$F8FF,SR ; have to let interrupts in <SM7> rb
|
||
MOVE.L Ticks,D0
|
||
ADD.L A0,D0
|
||
|
||
@1 CMP.L Ticks,D0 ; have enough ticks ticked?
|
||
BHI.S @1 ; -> No. Keep waiting. <SM9> (now use unsigned comparison)
|
||
RTS
|
||
|
||
|
||
|
||
;______________________________________________________________________
|
||
;
|
||
; Routine: UprString
|
||
; Arguments: D0.W (input) -- string length
|
||
; A0.L (input) -- pointer to string to canonize
|
||
; Opcode bit 10 -- 0 - map to upper case; 1 - case sensitive
|
||
; Opcode bit 9 -- 0 - diacritical sensitive; 1 - strip diacrits
|
||
; All registers are preserved.
|
||
; Function: UprString is a utility routine which, according to
|
||
; a pair of input booleans, strips diacritical marks
|
||
; and/or maps all characters to upper case.
|
||
;
|
||
; Reverted to this version from Mac IIx ROMs; removing .S on a BRA and BSR <02/28/89 pke>
|
||
;______________________________________________________________________
|
||
|
||
UprStringTrap
|
||
;
|
||
; Register usage:
|
||
; D0 = string length = loop index
|
||
; D1 = trap opcode, with booleans
|
||
; D2 = string input/output buffer
|
||
;
|
||
; A0 = string 0 pointer
|
||
;
|
||
BSR EntString ; changed
|
||
|
||
BRA.S USLoopEntry
|
||
USLoopTop
|
||
;
|
||
; Get next character, canonize it, and replace it.
|
||
;
|
||
MOVE.B (A0),D2
|
||
BSR.S Canonizer
|
||
MOVE.B D2,(A0)+
|
||
USLoopEntry
|
||
DBRA D0,USLoopTop
|
||
MOVEQ #0,D0 ; don't risk interp of error
|
||
BRA ExtString
|
||
|
||
|
||
;______________________________________________________________________ <27Feb85>...
|
||
;
|
||
; Routine: CmpString, RelString
|
||
; Arguments: D0.L (input) -- high-order word = string 0 length
|
||
; low-order word = string 1 length
|
||
; A0.L (input) -- pointer to string 0
|
||
; A1.L (input) -- pointer to string 1
|
||
; D0.W (output) --
|
||
; CmpString -- result code = 0, 1 for equal, unequal.
|
||
; RelString -- result code = -1, 0, 1 according as string 0 <27Feb85>
|
||
; is <, =, > than string 1, respectively.
|
||
; Opcode bit 10 -- 0 - map to upper case; 1 - case sensitive
|
||
; Opcode bit 9 -- 0 - diacritical sensitive; 1 - strip diacrits
|
||
; Pascal register conventions are observed.
|
||
;
|
||
; Calling Sequence for Pascal strings:
|
||
; LEA str0,A0
|
||
; LEA str1,A1
|
||
; MOVEQ #0,D0
|
||
; MOVE.B (A0)+,D0
|
||
; SWAP D0
|
||
; MOVE.B (A1)+,D0
|
||
; _CmpString
|
||
;
|
||
; Function: CmpString is a utility routine to compare two strings for
|
||
; equality. The strings are pointed to by A0 and A1
|
||
; on entry; the result is returned in D0.
|
||
; Two booleans determine the flavor of the compare:
|
||
; Marks --
|
||
; if set, all diacritical marks are ignored.
|
||
; Case --
|
||
; if set, all characters are mapped to upper case.
|
||
;______________________________________________________________________
|
||
|
||
;
|
||
; To expedite CmpString, test for length differences first. If they're the same,
|
||
; use the absolute value of RelString's return.
|
||
;
|
||
CmpString
|
||
MOVE.W D0,D2 ; str 1 length
|
||
SWAP D0 ; str 0 length
|
||
CMP.W D0,D2
|
||
BNE.S CSQuickNE
|
||
SWAP D0 ; realign for fresh start in RelString
|
||
BSR.S RelStringTrap ; count on CCR from last D0 store
|
||
BPL.S @1
|
||
NEG.L D0 ; -1 ---> 1
|
||
@1
|
||
RTS
|
||
CSQuickNE
|
||
MOVEQ #1,D0 ; must differ since lengths do
|
||
RTS
|
||
|
||
|
||
;
|
||
; Register usage:
|
||
; D0 = shorter string length = loop index
|
||
; D1 = trap opcode, with embedded booleans
|
||
; D2 = string 0 input buffer
|
||
; D3 = string 1 input buffer
|
||
; D4 = -1, 0, 1 according to string lengths
|
||
;
|
||
; A0 = string 0 pointer
|
||
; A1 = string 1 pointer
|
||
;
|
||
; Output:
|
||
; D0 = -1, 0, 1
|
||
; CCR reflects D0
|
||
; D1-D2/A0-A1 trash
|
||
;
|
||
RelStringTrap
|
||
BSR.S EntString
|
||
;
|
||
; Prime D4 to be -1, 0, 1 according to string 0 being shorter, equal, longer than string 1.
|
||
; Get shorter string length into D0.
|
||
;
|
||
MOVEQ #0,D4 ; presume they're equal
|
||
MOVE.W D0,D2 ; str 1 length
|
||
SWAP D0 ; str 0 length
|
||
CMP.W D0,D2 ; str1len - str0len
|
||
BEQ.S ICLoopEntry ; D4 and D1 OK!
|
||
BHI.S ICStr1Long ; str1len > str0len (unsigned, of course, Holmes)
|
||
|
||
MOVEQ #1,D4 ; str0 is longer
|
||
MOVE.W D2,D0 ; get shorter length
|
||
CMP.W D4,D4 ; set CCR to show EQ
|
||
BRA.S ICLoopEntry
|
||
ICStr1Long
|
||
MOVEQ #-1,D4
|
||
CMP.W D4,D4 ; set CCR to show EQ
|
||
BRA.S ICLoopEntry
|
||
;
|
||
; Get next characters, canonize, and compare them.
|
||
; *********** NOTE: Must enter loop at ICLoopEntry with CCR indicated EQ!!!! **********
|
||
;
|
||
ICLoopTop
|
||
MOVEQ #0,D2 ; clear hi bits for Canonizer
|
||
MOVE.B (A0)+,D2
|
||
BSR.S Canonizer
|
||
ADD.W D2,D2 ; need word index
|
||
MOVE.W 0(A3,D2.W),D3 ; D3.W := canonical string 0 char
|
||
|
||
MOVEQ #0,D2
|
||
MOVE.B (A1)+,D2
|
||
BSR.S Canonizer
|
||
ADD.W D2,D2
|
||
CMP.W 0(A3,D2.W),D3 ; string 0 char - string 1 char
|
||
ICLoopEntry
|
||
DBNE D0,ICLoopTop ; fall through if NE or exhausted
|
||
;
|
||
; Falling through means chars found unequal above, or shorter string exhausted.
|
||
; The DBNE leaves CCR untainted, so use it!
|
||
;
|
||
BEQ.S ICEqual ; strings = to end; let D4 decide...
|
||
BHI.S ICHigh
|
||
|
||
MOVEQ #-1,D0 ; str0 < str1
|
||
BRA.S ICExit
|
||
ICHigh
|
||
MOVEQ #1,D4 ; str0 > str1, fall through...
|
||
ICEqual
|
||
MOVE.L D4,D0
|
||
ICExit
|
||
BRA.S ExtString
|
||
|
||
;______________________________________________________________________
|
||
;
|
||
; Utility Canonizer looks at bits in D1.W (Dxxx xxxx Cxx1 010x)
|
||
; maps the character in D2.B to some canonical form.
|
||
;
|
||
; Input: D2.B = character to be mapped, with high bits of D2.W zero.
|
||
; Output: D2.B
|
||
;______________________________________________________________________
|
||
Canonizer
|
||
TST.W D1 ; MI-strip PL-keep
|
||
BPL.S dontStrip
|
||
|
||
MOVE.B StripTab(D2.W),D2
|
||
dontStrip
|
||
TST.B D1 ; PL-upper MI-keep
|
||
BMI.S dontUpper
|
||
|
||
MOVE.B 0(A2,D2.W),D2 ; UpperTab in A2
|
||
dontUpper
|
||
RTS
|
||
|
||
|
||
;______________________________________________________________________
|
||
;
|
||
; Utility EntString saves regs D3-D4/A2-A3, sets up opword for quick
|
||
; test in Canonizer, and primes A2 with UpperTab and A3 with CmpTab.
|
||
; D2 is cleared for use by Canonizer.
|
||
;
|
||
; Utility ExtString cleans up and returns, leaving CCR. It is jumped to...
|
||
;______________________________________________________________________
|
||
EntString
|
||
MOVE.L (SP)+,D2 ; return address
|
||
MOVEM.L D2-D4/A2-A3,-(SP) ; return on top
|
||
LEA UpperTab,A2
|
||
LEA CmpTab,A3
|
||
;
|
||
; Opword = 1010 xCDx xxxx xxxx , where C=caseBit and D=diacBit. Align to form
|
||
; Dxxx xxxx Cxx1 010x to facilitate testing D and C.
|
||
;
|
||
ROL.W #6,D1 ; Dxxx xxxx xx10 10xC
|
||
ROR.B #1,D1 ; Dxxx xxxx Cxx1 010x
|
||
MOVEQ #0,D2 ; clear hi bits for Canonizer
|
||
RTS
|
||
|
||
ExtString
|
||
MOVEM.L (SP)+,D3-D4/A2-A3
|
||
RTS
|
||
|
||
|
||
;
|
||
; Handy macro allows for ease in building big, regular tables.
|
||
; ASSEMBLER WON'T ALLOW EIGHTH ARGUMENT ON SAME LINE!!!!!!!!!!!!!!
|
||
;
|
||
MACRO
|
||
crow
|
||
DC.B (&Syslst[1]),( &Syslst[1]+1),( &Syslst[1]+2),( &Syslst[1]+3),( &Syslst[1]+4),( &Syslst[1]+5),( &Syslst[1]+6)
|
||
DC.B (&Syslst[1]+7)
|
||
ENDM
|
||
|
||
MACRO
|
||
dcrow
|
||
crow &Syslst[1]
|
||
crow &Syslst[1]+8
|
||
ENDM
|
||
|
||
|
||
;_________________________________________________________________________________________________________
|
||
;
|
||
StripTab
|
||
|
||
; No diacriticals in low ASCII.
|
||
dcrow $00
|
||
dcrow $10
|
||
dcrow $20
|
||
dcrow $30
|
||
dcrow $40
|
||
dcrow $50
|
||
dcrow $60
|
||
dcrow $70
|
||
|
||
; Diacritical city.
|
||
DC.B ('A'),( 'A'),( 'C'),( 'E'),( 'N'),( 'O'),( 'U'),( 'a')
|
||
DC.B ('a'),( 'a'),( 'a'),( 'a'),( 'a'),( 'c'),( 'e'),( 'e')
|
||
|
||
DC.B ('e'),( 'e'),( 'i'),( 'i'),( 'i'),( 'i'),( 'n'),( 'o')
|
||
DC.B ('o'),( 'o'),( 'o'),( 'o'),( 'u'),( 'u'),( 'u'),( 'u')
|
||
|
||
; O-slash at end.
|
||
crow $A0
|
||
DC.B $A8, $A9, $AA, $AB, $AC, $AD, $AE,( 'O')
|
||
|
||
; a-under, o-under, and o-slash.
|
||
crow $B0
|
||
DC.B $B8, $B9, $BA,( 'a'),( 'o'), $BD, $BE,( 'o')
|
||
|
||
; Diacrits at end.
|
||
crow $C0
|
||
DC.B $C8, $C9, $CA,( 'A'),( 'A'),( 'O'), $CE, $CF
|
||
|
||
; Beware of y-umlaut, CHANGE FROM MAC-1
|
||
crow $D0
|
||
DC.B ('y'), $D9, $DA, $DB, $DC, $DD, $DE, $DF
|
||
|
||
dcrow $E0
|
||
dcrow $F0
|
||
|
||
; End of StripTab
|
||
;_________________________________________________________________________________________________________
|
||
|
||
|
||
|
||
;_________________________________________________________________________________________________________
|
||
;
|
||
UpperTab
|
||
; Special chars, punctuation, digits, upper-case letters.
|
||
dcrow $00
|
||
dcrow $10
|
||
dcrow $20
|
||
dcrow $30
|
||
dcrow $40
|
||
dcrow $50
|
||
|
||
; Lower-case letters and some symbols.
|
||
; fixed bug in which "`" is upper-cased as "a" <02/29/89 pke>
|
||
; restored above bug, so "`" ($60) goes to "a" ($61); needed for HFS. <3.4><08/24/89 pke>
|
||
DC.B $61,( 'A'),( 'B'),( 'C'),( 'D'),( 'E'),( 'F'),( 'G')
|
||
crow $48
|
||
crow $50
|
||
DC.B ('X'),( 'Y'),( 'Z'), $7B, $7C, $7D, $7E, $7F
|
||
|
||
; Accented characters.
|
||
crow $80
|
||
DC.B $CB, $89, $80, $CC, $81, $82, $83, $8F
|
||
DC.B $90, $91, $92, $93, $94, $95, $84, $97
|
||
DC.B $98, $99, $85, $CD, $9C, $9D, $9E, $86
|
||
|
||
; Symbols and upper-case AE and O-slash
|
||
dcrow $A0
|
||
|
||
; Symbols and ae, o-slash
|
||
crow $B0
|
||
DC.B $B8, $B9, $BA, $BB, $BC, $BD, $AE, $AF
|
||
|
||
; Symbols, upper A-acute, A-tilde, O-tilde, OE, and oe
|
||
crow $C0
|
||
DC.B $C8, $C9, $CA, $CB, $CC, $CD, $CE, $CE
|
||
|
||
; Symbols and undefineds. y-umlaut cannot map up.
|
||
dcrow $D0
|
||
dcrow $E0
|
||
dcrow $F0
|
||
|
||
; End of UpperTab
|
||
;_________________________________________________________________________________________________________
|
||
|
||
|
||
;
|
||
; Entries in the CmpTab are given as words, with the "root" char in the high byte, and
|
||
; fine tuning in the low byte.
|
||
;
|
||
MACRO
|
||
basec
|
||
DC.B (&Syslst[1]),( $00)
|
||
ENDM
|
||
|
||
MACRO
|
||
modc
|
||
DC.B (&Syslst[1]),( &Syslst[2])
|
||
ENDM
|
||
|
||
;
|
||
; Macro baserow sets up a sequence of 8 base characters, that is, with modifier=0.
|
||
; It's handy for setting up the punctuation and alphabetic characters.
|
||
; Macro dbaserow just does two rows.
|
||
;
|
||
MACRO
|
||
baserow
|
||
basec &Syslst[1]
|
||
basec &Syslst[1]+1
|
||
basec &Syslst[1]+2
|
||
basec &Syslst[1]+3
|
||
basec &Syslst[1]+4
|
||
basec &Syslst[1]+5
|
||
basec &Syslst[1]+6
|
||
basec &Syslst[1]+7
|
||
ENDM
|
||
|
||
MACRO
|
||
dbaserow
|
||
baserow &Syslst[1]
|
||
baserow &Syslst[1]+8
|
||
ENDM
|
||
|
||
;
|
||
; Macro lower11 is a convenience for setting up two-byte entries for a sequence of 11 lower-case
|
||
; characters. There are two such sequences: 'a'-'k' and 'p'-'z'.
|
||
;
|
||
MACRO
|
||
lower11
|
||
modc &Syslst[1], $80
|
||
modc &Syslst[1]+1, $80
|
||
modc &Syslst[1]+2, $80
|
||
modc &Syslst[1]+3, $80
|
||
modc &Syslst[1]+4, $80
|
||
modc &Syslst[1]+5, $80
|
||
modc &Syslst[1]+6, $80
|
||
modc &Syslst[1]+7, $80
|
||
modc &Syslst[1]+8, $80
|
||
modc &Syslst[1]+9, $80
|
||
modc &Syslst[1]+$A, $80
|
||
ENDM
|
||
|
||
;
|
||
; Macro ldiac takes two args: a lower case vanilla alphabetic and the name of a diacritical.
|
||
; It sets up a two-byte table entry with the corresponding upper-case character and a low-order
|
||
; modifier of the form $80+n where small n depends upon the diacritical in question. They are ordered
|
||
; plain < acute < grave < circumflex < umlaut < tilde < circle < slash < cedilla < under < ligature
|
||
; in order to give as nearly the flavor of the international string comparisons as possible.
|
||
;
|
||
MACRO
|
||
ldiac
|
||
.*
|
||
DC.B (&Syslst[1]-$20)
|
||
.*
|
||
IF &Eval(&Syslst[2]) = 'acute' THEN
|
||
DC.B ($82)
|
||
ENDIF
|
||
.*
|
||
IF &Eval(&Syslst[2]) = 'grave' THEN
|
||
DC.B ($84)
|
||
ENDIF
|
||
.*
|
||
IF &Eval(&Syslst[2]) = 'circumflex' THEN
|
||
DC.B ($86)
|
||
ENDIF
|
||
.*
|
||
IF &Eval(&Syslst[2]) = 'umlaut' THEN
|
||
DC.B ($88)
|
||
ENDIF
|
||
.*
|
||
IF &Eval(&Syslst[2]) = 'tilde' THEN
|
||
DC.B ($8A)
|
||
ENDIF
|
||
.*
|
||
IF &Eval(&Syslst[2]) = 'circle' THEN
|
||
DC.B ($8C)
|
||
ENDIF
|
||
.*
|
||
IF &Eval(&Syslst[2]) = 'slash' THEN
|
||
DC.B ($8E)
|
||
ENDIF
|
||
.*
|
||
IF &Eval(&Syslst[2]) = 'cedilla' THEN
|
||
DC.B ($90)
|
||
ENDIF
|
||
.*
|
||
IF &Eval(&Syslst[2]) = 'under' THEN
|
||
DC.B ($92)
|
||
ENDIF
|
||
.*
|
||
IF &Eval(&Syslst[2]) = 'ligature' THEN
|
||
DC.B ($94)
|
||
ENDIF
|
||
.*
|
||
ENDM
|
||
|
||
|
||
|
||
|
||
;
|
||
; Macro udiac takes two args: an upper-case vanilla alphabetic and the name of a diacritical.
|
||
; It sets up a two-byte table entry with the upper-case character and a low-order
|
||
; modifier of the form n where small n depends upon the diacritical in question. They are ordered
|
||
; plain < acute < grave < circumflex < umlaut < tilde < circle < slash < under < ligature
|
||
; in order to give as nearly the flavor of the international string comparisons as possible.
|
||
;
|
||
MACRO
|
||
udiac
|
||
.*
|
||
DC.B (&Syslst[1])
|
||
.*
|
||
IF &Eval(&Syslst[2]) = 'acute' THEN
|
||
DC.B ($02)
|
||
ENDIF
|
||
.*
|
||
IF &Eval(&Syslst[2]) = 'grave' THEN
|
||
DC.B ($04)
|
||
ENDIF
|
||
.*
|
||
IF &Eval(&Syslst[2]) = 'circumflex' THEN
|
||
DC.B ($06)
|
||
ENDIF
|
||
.*
|
||
IF &Eval(&Syslst[2]) = 'umlaut' THEN
|
||
DC.B ($08)
|
||
ENDIF
|
||
.*
|
||
IF &Eval(&Syslst[2]) = 'tilde' THEN
|
||
DC.B ($0A)
|
||
ENDIF
|
||
.*
|
||
IF &Eval(&Syslst[2]) = 'circle' THEN
|
||
DC.B ($0C)
|
||
ENDIF
|
||
.*
|
||
IF &Eval(&Syslst[2]) = 'slash' THEN
|
||
DC.B ($0E)
|
||
ENDIF
|
||
.*
|
||
IF &Eval(&Syslst[2]) = 'cedilla' THEN
|
||
DC.B ($10)
|
||
ENDIF
|
||
.*
|
||
IF &Eval(&Syslst[2]) = 'under' THEN
|
||
DC.B ($12)
|
||
ENDIF
|
||
.*
|
||
IF &Eval(&Syslst[2]) = 'ligature' THEN
|
||
DC.B ($14)
|
||
ENDIF
|
||
.*
|
||
ENDM
|
||
|
||
|
||
;_________________________________________________________________________________________________________
|
||
;
|
||
CmpTab
|
||
|
||
; The control characters are vanilla
|
||
dbaserow $00
|
||
dbaserow $10
|
||
|
||
; Punctuation, digits, and upper case are all base chars
|
||
dbaserow $20
|
||
dbaserow $30
|
||
dbaserow $40
|
||
dbaserow $50
|
||
|
||
; Map lower case up and use punctuation as base chars.
|
||
basec $61
|
||
lower11 $41
|
||
modc $4C, $80
|
||
modc $4D, $80
|
||
modc $4E, $80
|
||
modc $4F, $80
|
||
lower11 $50
|
||
basec $7B
|
||
basec $7C
|
||
basec $7D
|
||
basec $7E
|
||
basec $7F
|
||
|
||
; Grotesque diacriticals!
|
||
udiac 'A', 'umlaut'
|
||
udiac 'A', 'circle'
|
||
udiac 'C', 'cedilla'
|
||
udiac 'E', 'acute'
|
||
udiac 'N', 'tilde'
|
||
udiac 'O', 'umlaut'
|
||
udiac 'U', 'umlaut'
|
||
ldiac 'a', 'acute'
|
||
|
||
ldiac 'a', 'grave'
|
||
ldiac 'a', 'circumflex'
|
||
ldiac 'a', 'umlaut'
|
||
ldiac 'a', 'tilde'
|
||
ldiac 'a', 'circle'
|
||
ldiac 'c', 'cedilla'
|
||
ldiac 'e', 'acute'
|
||
ldiac 'e', 'grave'
|
||
|
||
ldiac 'e', 'circumflex'
|
||
ldiac 'e', 'umlaut'
|
||
ldiac 'i', 'acute'
|
||
ldiac 'i', 'grave'
|
||
ldiac 'i', 'circumflex'
|
||
ldiac 'i', 'umlaut'
|
||
ldiac 'n', 'tilde'
|
||
ldiac 'o', 'acute'
|
||
|
||
ldiac 'o', 'grave'
|
||
ldiac 'o', 'circumflex'
|
||
ldiac 'o', 'umlaut'
|
||
ldiac 'o', 'tilde'
|
||
ldiac 'u', 'acute'
|
||
ldiac 'u', 'grave'
|
||
ldiac 'u', 'circumflex'
|
||
ldiac 'u', 'umlaut'
|
||
|
||
; Column $A is cool up to s-zet; then up to AE and O-slash.
|
||
basec $A0
|
||
basec $A1
|
||
basec $A2
|
||
basec $A3
|
||
basec $A4
|
||
basec $A5
|
||
basec $A6
|
||
modc 'S', $82
|
||
basec $A8
|
||
basec $A9
|
||
basec $AA
|
||
basec $AB
|
||
basec $AC
|
||
basec $AD
|
||
udiac 'A', 'ligature'
|
||
udiac 'O', 'slash'
|
||
|
||
; Column $B is cool up to last five.
|
||
baserow $B0
|
||
basec $B8
|
||
basec $B9
|
||
basec $BA
|
||
ldiac 'a', 'under'
|
||
ldiac 'o', 'under'
|
||
basec $BD
|
||
ldiac 'a', 'ligature'
|
||
ldiac 'o', 'slash'
|
||
|
||
; Column $C has quote special case, non-breaking space, and 5 diacs
|
||
basec $C0
|
||
basec $C1
|
||
basec $C2
|
||
basec $C3
|
||
basec $C4
|
||
basec $C5
|
||
basec $C6
|
||
modc '"', $06
|
||
modc '"', $08
|
||
basec $C9
|
||
basec ' ', $02
|
||
udiac 'A', 'grave'
|
||
udiac 'A', 'tilde'
|
||
udiac 'O', 'tilde'
|
||
udiac 'O', 'ligature'
|
||
ldiac 'o', 'ligature'
|
||
|
||
; Column $D has quotes and y.
|
||
basec $D0
|
||
basec $D1
|
||
modc '"', $02
|
||
modc '"', $04
|
||
modc $27, $02
|
||
modc $27, $04
|
||
basec $D6
|
||
basec $D7
|
||
ldiac 'y', 'umlaut'
|
||
basec $D9
|
||
basec $DA
|
||
basec $DB
|
||
basec $DC
|
||
basec $DD
|
||
basec $DE
|
||
basec $DF
|
||
|
||
; Columns $E and $F are vanilla
|
||
dbaserow $E0
|
||
dbaserow $F0
|
||
|
||
; End of CmpTab
|
||
;_________________________________________________________________________________________________________
|
||
|
||
|
||
; the following are lower-level routines which actually access the clock chip
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; Routine: ReadPram
|
||
;
|
||
; Arguments: A1 (input) -- pointer to buffer where 20 bytes are placed
|
||
; all regs preserved
|
||
;
|
||
; Function: All 20 bytes clock pram are read into buffer.
|
||
;
|
||
; Notes: Disables VIA interrupts for long periods of time (60 usec).
|
||
;_______________________________________________________________________
|
||
|
||
ReadPram MOVE.L A0,-(SP) ; <H2>
|
||
|
||
MOVE.B SPVolCtl,D0 ; get the sound volume control <SM5> rb
|
||
ANDI.B #7,D0 ; and mask out the sound res ID <SM5> rb
|
||
MOVE.B D0,sdVolume ; now store it low mem <SM5> rb
|
||
|
||
MOVEA.L A1,A0 ; <H2>
|
||
MOVE.L #(16<<16)+(16<<0),D0 ; first 16 bytes are at extended PRAM address 16<H2>
|
||
_ReadXPRAM ; <H2>
|
||
|
||
LEA 16(A1),A0 ; <H2>
|
||
MOVE.L #(4<<16)+(8<<0),D0 ; last 4 bytes are at extended PRAM address 8 <H2>
|
||
_ReadXPRAM ; <H2>
|
||
|
||
MOVEA.L (SP)+,A0 ; <H2>
|
||
RTS ; <H2>
|
||
|
||
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; Routine: InitUtil
|
||
;
|
||
; Arguments: D0 (output) -- result code (0 if clock was already initialized)
|
||
;
|
||
; Function: The clock ram and time are read and stored in the low-memory
|
||
; buffer used by the clock utility routines. If the clock ram
|
||
; validity bit is not $A8, the values in Time and SysParam are
|
||
; initialized.
|
||
;_______________________________________________________________________
|
||
|
||
InitUtil CLR.W -(SP) ; assume no reset of PRam values <30Oct85> LAK
|
||
|
||
BSR InitCPHardware ; initialize the hardware, if necessary <H4>
|
||
|
||
LEA SysParam,A1 ; where parameter ram is read to
|
||
BSR.S ReadPram ; read parameter ram and
|
||
BSR ReadTime ; time into SysParam and Time <C518>
|
||
|
||
MOVEQ #0,D0 ; assume valid clock data
|
||
CMP.B #$A8,(A1) ; is the clock data valid?
|
||
BEQ.S CkNewPram ; branch if so
|
||
MOVE.W #PRInitErr,(SP) ; report non-zero result <30Oct85> LAK
|
||
|
||
MOVEQ #4,D1
|
||
LEA PramInit,A0 ; point to initial values
|
||
@1 MOVE.L (A0)+,(A1)+ ; set parameter ram to initial values
|
||
DBRA D1,@1
|
||
|
||
BSR WritePram ; and put initial values into clk chip
|
||
|
||
CkNewPram BTST #6,HWCfgFlags ; new clock chip present? <30oct85> BBM
|
||
BEQ.S ClkXit ; exit if not <30oct85> BBM
|
||
LEA GetParam,A0 ; get pointer to useful buffer <30oct85> BBM
|
||
|
||
MOVE.L #$4000C,D0 ; Command to read 4 bytes at addr C <30oct85> BBM
|
||
_ReadXPRam ; <30oct85> BBM
|
||
|
||
MOVE.L #'NuMc',D1 ; put validity bytes into D1 <C518>
|
||
|
||
CMP.L (A0),D1 ; is the extra parameter ram valid? <30oct85> BBM
|
||
BEQ.S ClkXit ; exit if so <30oct85> BBM
|
||
|
||
MOVE.W #PRInitErr,(SP) ; report non-zero result <30Oct85> LAK
|
||
MOVE.L D1,(A0) ; store out true validity bytes <30oct85> BBM
|
||
MOVE.L #$4000C,D0 ; Command to write 4 bytes at addr C <30oct85> BBM
|
||
_WriteXPRam ; <30oct85> BBM
|
||
|
||
MOVEQ #32,D1 ; starting address to clear out XPRam <30oct85> BBM
|
||
@0 MOVEQ #4,D0 ; number of bytes to write
|
||
SWAP D0 ; finish the command byte <30oct85> BBM
|
||
MOVE.W D1,D0 ; get the current address in XPRam <30oct85> BBM
|
||
CLR.L (A0) ; clear out the buffer <30oct85> BBM
|
||
_WriteXPRam ;
|
||
ADDQ.B #4,D1 ; get the next address to write to ... <30oct85> BBM
|
||
; we want wrap at 256!!!! <30oct85> BBM
|
||
CMP.B #8,D1 ; Check if we wrote the last address <30oct85> BBM
|
||
BNE.S @0 ; if not loop back untill we are done <30oct85> BBM
|
||
|
||
MOVEM.L A1,-(SP) ;Save A1
|
||
LEA PRAMInitTbl,A0 ;Copy the data from the PRAMInit table. <C518>
|
||
LEA GetParam,A1 ; into the GetParam buffer. <C518>
|
||
MOVEQ #5-1,D0 ;Loop 5 times (20 bytes) <C518><C779>
|
||
@10 MOVE.L (A0)+,(A1)+ ;Copy 4 bytes <C518>
|
||
DBRA D0,@10 ;Branch if not done. <C518>
|
||
|
||
MOVE.L #$00140076,D0 ;Write 20 bytes beginning at PRAM address $76 <C518><C779>
|
||
LEA GetParam,A0 ; from the buffer <C518>
|
||
_WriteXPRam ; into the PRAM. <C518>
|
||
|
||
; Write the default memory mgr flags to location $8A. Since this is the only xpram whose default
|
||
; is non zero, we write it explicitly (as opposed to writing a default table full of zeros) <MC2>
|
||
|
||
LEA MMFlags,A0 ; Point A0 at the Memory Manager flags lomem <MC2>
|
||
MOVE.B #MMFlagsDefault,(A0) ; Put the default MMFlags into MMFlags
|
||
MOVE.L #MMPRAMloc,D0 ; Write MMFlags to PRAM
|
||
_WriteXPRam ; Store it.
|
||
MOVEM.L (SP)+,A1 ;Restore A1
|
||
|
||
ClkXit MOVE.W (SP)+,D0 ; pass back error code <30oct85> LAK
|
||
BNE.S @1 ; br if we had to reset clock/pram <30oct85> LAK
|
||
BSET #5,HWCfgFlags ; note the good values <30oct85> LAK
|
||
@1 EXT.L D0 ; OS errors are long <30oct85> LAK
|
||
RTS
|
||
|
||
|
||
; original 20-byte parameter RAM initialization values
|
||
|
||
PRAMInit DC.B $A8 ; old PRAM validity byte <2.7>
|
||
DC.B 0 ; AppleTalk node ID hint for modem port <2.7>
|
||
DC.B 0 ; AppleTalk node ID hint for printer port <2.7>
|
||
DC.B (0<<4)+(0<<0) ; serial port usage = neither port in use <2.7>
|
||
; port A config: <2.7>
|
||
DC.W (3<<14)+ \ ; ¥ stop bits = 2 <2.7>
|
||
(0<<12)+ \ ; ¥ parity = none <2.7>
|
||
(3<<10)+ \ ; ¥ data bits = 8 <2.7>
|
||
(10<<0) ; ¥ baud = 9600 <2.7>
|
||
; port B config: <2.7>
|
||
DC.W (3<<14)+ \ ; ¥ stop bits = 2 <2.7>
|
||
(0<<12)+ \ ; ¥ parity = none <2.7>
|
||
(3<<10)+ \ ; ¥ data bits = 8 <2.7>
|
||
(10<<0) ; ¥ baud = 9600 <2.7>
|
||
|
||
DC.L 0 ; alarm time (midnight, January 1, 1904) <2.7>
|
||
|
||
DC.W Geneva-1 ; application font number - 1 <2.7>
|
||
|
||
DC.B ((24/4)<<4)+ \ ; ¥ auto-key threshold = 24 ticks <2.7>
|
||
(6/2) ; ¥ auto-key rate = 6 ticks <2.7>
|
||
|
||
DC.B 0 ; ¥ printer connection = 0 (printer port) <2.7>
|
||
|
||
If NoSound Then ; Kill Sound if build-time conditional is set. <SM6> cch
|
||
DC.B (0<<7)+ \ ; ¥ alarm enable = 0 (disabled)
|
||
(2<<3)+ \ ; ¥ mouse tracking = 2 (medium slow)
|
||
0 ; ¥ speaker volume = 0 (off!)
|
||
Else
|
||
DC.B (0<<7)+ \ ; ¥ alarm enable = 0 (disabled)
|
||
(3<<3)+ \ ; ¥ mouse tracking = 3 (medium slow) <MC2>
|
||
3 ; ¥ speaker volume = 3 (medium)
|
||
Endif
|
||
|
||
DC.B ((32/4)<<4)+ \ ; ¥ double-click time = 32 ticks <2.7>
|
||
(32/4) ; ¥ caret-blink time = 32 ticks <2.7>
|
||
|
||
DC.B 3 ; ram cache size in 32K blocks (96k default) <SM9>
|
||
|
||
DC.B (1<<7)+ \ ; ¥ color desk pattern = 1 (use if CQD around) <2.7><H5/6>
|
||
(1<<6)+ \ ; ¥ mouse scaling = 1 (on) <2.7>
|
||
(0<<5)+ \ ; ¥ cache active = 0 (not active) <2.7>
|
||
(0<<4)+ \ ; ¥ preferred boot disk = 0 (internal drive) <2.7>
|
||
(3<<2) ; ¥ menu blink = 3 <2.7>
|
||
|
||
;Start Manager <C518>
|
||
PRAMInitTbl DC.B 00 ; [$76] Reserved. <C518>
|
||
DC.B 01 ; [$77] Default OS. <C518>
|
||
DC.W $FFFF,$FFDF ; [$78-$7B] Default boot. <C774>
|
||
|
||
;Sound Manager? <C518>
|
||
DC.W 0 ; [$7C-$7D] Sound alert id <C518>
|
||
|
||
;Menu Manager? <C518>
|
||
DC.B 0 ; [$7E] Hierar menu dsply <C518>
|
||
DC.B 0 ; [$7F] Hierar menu drag <C518>
|
||
|
||
;Start Manager <C518>
|
||
DC.W 0 ; [$80-$81] Default video. <C518>
|
||
|
||
;Quick Draw <C518>
|
||
DC.W 0,0,0 ; [$82-$87] Default Hilite Color (black) <C802>
|
||
;Reserved <C779>
|
||
DC.B 0,0 ; [$88-$89] <C779>
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: ReadTime
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: D0 - result code
|
||
; "Time" contains the 32-bit time value read from the clock
|
||
;
|
||
; Trashes: 8 bytes at "GetParam"
|
||
;
|
||
; Function: reads the time from the realtime clock
|
||
;________________________________________________________________________________________
|
||
|
||
ReadTime MOVEM.L A0/A2-A3/D1-D2/D4-D5,-(SP) ; <H4>
|
||
MOVEQ #ClkRdErr,D0 ; assume an error <H4>
|
||
MOVEA.L UnivInfoPtr,A0 ; point to this machine's product info <H4>
|
||
ADDA.L ProductInfo.ClockPRAMPtr(A0),A0 ; and get the address of its clock/PRAM table <H4>
|
||
MOVE.L 4*cpReadTime(A0),D1 ; get the offset to the routine <H4>
|
||
BEQ.S @NoEntry ; -> this function is not supported <H4>
|
||
ADDA.L D1,A0 ; calculate the routine's address <H4>
|
||
JSR (A0) ; and call it <H4>
|
||
MOVE.L GetParam,Time ; save the time, good or bad <H4>
|
||
@NoEntry MOVEM.L (SP)+,A0/A2-A3/D1-D2/D4-D5 ; <H4>
|
||
TST.W D0 ; set condition codes (for WriteTime) <H4>
|
||
RTS ; <H4>
|
||
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: WriteTime
|
||
;
|
||
; Inputs: "Time" contains the 32-bit time value to write to the clock
|
||
;
|
||
; Outputs: D0 - result code: 0 = no error
|
||
; -2 = clock read error
|
||
; -3 = time written did not verify
|
||
;
|
||
; Trashes: 8 bytes at "GetParam"
|
||
;
|
||
; Function: Writes the time to the realtime clock. The clock is read after write for
|
||
; verification; if verification fails, a second attempt is made to read the clock.
|
||
;________________________________________________________________________________________
|
||
|
||
WriteTime MOVEM.L A0/D1-D5,-(SP) ; <H4>
|
||
MOVEQ #ClkWrErr,D0 ; assume an error <H4>
|
||
MOVEA.L UnivInfoPtr,A0 ; point to this machine's product info <H4>
|
||
ADDA.L ProductInfo.ClockPRAMPtr(A0),A0 ; and get the address of its clock/PRAM table <H4>
|
||
MOVE.L 4*cpWriteTime(A0),D1 ; get the offset to the routine <H4>
|
||
BEQ.S @NoEntry ; -> this function is not supported <H4>
|
||
ADDA.L D1,A0 ; calculate the routine's address <H4>
|
||
JSR (A0) ; and call it <H4>
|
||
@NoEntry MOVEM.L (SP)+,A0/D1-D5 ; <H4>
|
||
RTS ; <H4>
|
||
|
||
|
||
;________________________________________________________________________________________
|
||
;
|
||
; Routine: InitCPHardware
|
||
;
|
||
; Inputs: none
|
||
;
|
||
; Outputs: none
|
||
;
|
||
; Trashes: A0,A1,D0,D1,D2
|
||
;
|
||
; Function: initializes the clock/PRAM hardware, if necessary
|
||
;________________________________________________________________________________________
|
||
|
||
InitCPHardware ; <H4>
|
||
MOVEM.L A2/A5/A6,-(SP) ; <H4>
|
||
MOVEA.L UnivInfoPtr,A1 ; point to this machine's product info <H4>
|
||
MOVEA.L A1,A0 ; and get the address of its clock/PRAM table <H4>
|
||
ADDA.L ProductInfo.ClockPRAMPtr(A0),A0 ; <H4>
|
||
MOVE.L 4*cpInitHardware(A0),D1 ; get the offset to the routine <H4>
|
||
BEQ.S @NoEntry ; -> this function is not supported <H4>
|
||
LEA @NoEntry,A6 ; set up return address <H7>
|
||
ADDA.L D1,A0 ; calculate the routine's address <H4>
|
||
JMP (A0) ; and call it <H7>
|
||
@NoEntry MOVEM.L (SP)+,A2/A5/A6 ; <H4>
|
||
RTS ; <H4>
|
||
|
||
;_______________________________________________________________________
|
||
;
|
||
; Routine: WritePram
|
||
;
|
||
; Arguments: SysParam contains the 20 bytes to write.
|
||
; all regs preserved
|
||
;
|
||
; Function: Writes all 20 bytes of parameter ram from SysParam.
|
||
;
|
||
; Notes: disables VIA interrupts for long periods of time (60 usec)
|
||
; no verification of write data is done
|
||
;_______________________________________________________________________
|
||
|
||
WritePram MOVE.L A0,-(SP) ; <H2>
|
||
|
||
MOVE.B SPVolCtl,D0 ; get the sound volume control <SM5> rb
|
||
ANDI.B #7,D0 ; and mask out the sound res ID <SM5> rb
|
||
MOVE.B D0,sdVolume ; now store it low mem <SM5> rb
|
||
|
||
LEA SysParam,A0 ; <H2>
|
||
MOVE.L #(16<<16)+(16<<0),D0 ; first 16 bytes are at extended PRAM address 16 <H2>
|
||
_WriteXPRAM ; <H2>
|
||
|
||
LEA SysParam+16,A0 ; <H2>
|
||
MOVE.L #(4<<16)+(8<<0),D0 ; last 4 bytes are at extended PRAM address 8 <H2>
|
||
_WriteXPRAM ; <H2>
|
||
|
||
MOVEA.L (SP)+,A0 ; <H2>
|
||
RTS ; <H2>
|
||
|
||
ENDPROC ;SysUtil
|
||
|
||
|
||
;-----------------------------------------------------------------------------
|
||
; SysEnvirons call.
|
||
;
|
||
; Fix File Date Patch# Fix Routine(s) Routine(s) Fixed
|
||
;AppleSystemPatch PatchIIROM.a 28Mar87 #PABM150 (SysEnvirons) (SysEnvirons)
|
||
;
|
||
; SysEnvirons -- an environs call
|
||
;
|
||
; *** Note ***: SysEnvirons now calls uses the Gestalt call to determine it's
|
||
; information. Previous versions still operate normally, however,
|
||
; the latest (and last) version is updated as Gestalt entries are updated.
|
||
;
|
||
; Register Usage:
|
||
;
|
||
; INPUT
|
||
; D0.W: Selector
|
||
; A0.L: Pointer to theWorld
|
||
;
|
||
; USAGE
|
||
; D0: scratch
|
||
; D1: holds requested version number
|
||
; D2: holds EnvErr
|
||
; A0: scratch
|
||
; A2: hold pointer to theWorld!!! Don't touch this !
|
||
;
|
||
; OUTPUT
|
||
; D0.W: error code
|
||
; A0.L: pointer to theWorld
|
||
;-----------------------------------------------------------------------------
|
||
|
||
;-----------------------------------------------------------------------------------------
|
||
|
||
; FUNCTION SysEnvirons(VersionRequested: Integer; VAR theWorld: SysEnvRec): OSErr; <PB302>
|
||
SysEnvironsTrap PROC EXPORT ; <PB302>
|
||
; Proc header moved up to clear up dupl <A/UX>
|
||
; label problems. <PB302>
|
||
|
||
;-----------------------------------------------------------------------------------------
|
||
; Equates
|
||
;-----------------------------------------------------------------------------------------
|
||
envTRUE EQU 1 ; IM V1 p.86: "Boolean value in bit 0" -- FALSE EQU 0
|
||
TheVersion EQU 2 ; Current version of this call
|
||
MAXINT EQU $7fffffff ; max number
|
||
|
||
SysWDProcID EQU 'ERIK' ; for use with OpenWD
|
||
TwoBitsClear EQU $3FFF ; for compare below (two high bits clear)
|
||
|
||
;-----------------------------------------------------------------------------------------
|
||
; The code starts here
|
||
;-----------------------------------------------------------------------------------------
|
||
WITH SysEnvRec ; <10>
|
||
MOVEM.L A0/D2,-(SP) ; save regs
|
||
MOVE.L A0,A2 ; Pointer to theWorld
|
||
|
||
;-----------------------------------------------------------------------------------------
|
||
; Check for negative selector, or for selector too high -- Selector is in D0 at this point
|
||
;-----------------------------------------------------------------------------------------
|
||
MOVE.W #EnvBadVers,D2 ; assume error number in D2 <3.3>
|
||
TST.W D0 ; test the selector
|
||
BLE EXIT ; if less than or equal to zero, then exit
|
||
|
||
MOVE.W #noErr,D2 ; error return, set to zero for now, MPW will generate CLR.W here
|
||
MOVE.W D0,D1 ; save requested version number in D1
|
||
CMP.W #curSysEnvVers,D0 ; test to see if requested version was bigger than current version <10>
|
||
BLE.S GetSize ; if not, then continue
|
||
MOVE.W #EnvVersTooBig,D2 ; put error here, but continue <3.3>
|
||
MOVE.W #SysEnvRec.size,D0 ; change this as versions increase (which they won't) <10>
|
||
BRA.S ZeroWorld ; start filling in
|
||
|
||
;-----------------------------------------------------------------------------------------
|
||
;-> Since all the environment records for versions 1-2 are the same size, we can
|
||
; use the same size for all of them.
|
||
;-----------------------------------------------------------------------------------------
|
||
GetSize MOVE.W #SysEnvRec.size,D0 ; for now, just do this <10>
|
||
|
||
;-----------------------------------------------------------------------------------------
|
||
; ZeroWorld
|
||
; routine to zero out bytes of record
|
||
;
|
||
; On Input: D0 == bytes to zero
|
||
; D1 == requested version
|
||
; A0 == pointer to the world
|
||
; A2 == (copy of) pointer to the world
|
||
;
|
||
; Register usage:
|
||
; A0 == copy of world pointer
|
||
;-----------------------------------------------------------------------------------------
|
||
ZeroWorld
|
||
ASR.W #1,D0 ;count by words
|
||
SUBQ #1,D0 ;adjust for Debra
|
||
ZeroLoop
|
||
CLR.W (A0)+ ;clear next word
|
||
DBRA D0,ZeroLoop ;loop till done.
|
||
; now we've zeroed out the record
|
||
|
||
FillInWorld1
|
||
MOVE.W D1,environsVersion(A2) ; put in version number <10>
|
||
|
||
;-----------------------------------------------------------------------------------------
|
||
; Get MachineType -- assumes 4.1 and later will not even run on 64K ROMs
|
||
; so we don't need to check for XLs or even 64K ROM Macs
|
||
; WARNING -- if run on old ROMS, this will return Env512KE!!
|
||
; this also assumes that future Macs will have 8(ROMBase) > 0
|
||
;
|
||
;-> Actually get this from _Gestalt.
|
||
;-----------------------------------------------------------------------------------------
|
||
GetMachineType
|
||
Move.l #gestaltMachineType,D0 ; ask for machine type
|
||
_Gestalt ; ask gestalt for the info
|
||
tst.w d0 ; any errors?
|
||
Beq.s OkMach ; if not, return result
|
||
moveq #envMachUnknown,A0 ; oh well, use SysEnvs bad way of saying unknown
|
||
Bra.s SaveMach
|
||
|
||
OkMach Sub.w #2,A0 ; convert gestalt result to sysEnv result
|
||
SaveMach Move.w A0,machineType(A2) ; save the result in the record <10>
|
||
|
||
;-----------------------------------------------------------------------------------------
|
||
; SYSTEM VERSION code
|
||
;-----------------------------------------------------------------------------------------
|
||
Move.l #gestaltSystemVersion,D0 ; ask for system version
|
||
_Gestalt ; ask gestalt for the info
|
||
tst.w d0 ; any errors?
|
||
Beq.s @ok ; if not, return result
|
||
sub.l a0,a0 ; otherwise, return zero
|
||
@ok Move.w A0,systemVersion(A2) ; no problem, dude.. <10>
|
||
|
||
;-----------------------------------------------------------------------------------------
|
||
; Get Processor Stuff
|
||
;-----------------------------------------------------------------------------------------
|
||
Move.l #gestaltProcessorType,D0 ; ask for processor type
|
||
_Gestalt ; ask gestalt for the info
|
||
tst.w d0 ; any errors?
|
||
Beq.s OkProc ; if not, return result
|
||
moveq #envCPUUnknown,A0 ; oh well, use SysEnvs bad way of saying unknown
|
||
|
||
OkProc Move.w a0,processor(A2) ; save it <10>
|
||
|
||
;-----------------------------------------------------------------------------------------
|
||
; HasFPU
|
||
;-----------------------------------------------------------------------------------------
|
||
Move.l #gestaltFPUType,D0 ; ask for fpu type
|
||
_Gestalt ; ask gestalt for the info
|
||
tst.w d0 ; any errors?
|
||
bne.s NoFPU ; whoops
|
||
move.l a0,d0 ; this will be nonzero if an FPU exists, else zero
|
||
Beq.s NoFPU ; oh well.. entry is already zero
|
||
Move.b #envTRUE,hasFPU(A2) ; cool, we have one <10>
|
||
NoFPU
|
||
|
||
;-----------------------------------------------------------------------------------------
|
||
; Has ColorQD
|
||
;-----------------------------------------------------------------------------------------
|
||
ColorQD Move.l #gestaltQuickdrawVersion,D0 ; ask for QD version
|
||
_Gestalt ; ask gestalt for the info
|
||
tst.w d0 ; any errors?
|
||
bne.s NoCQD ; whoops
|
||
move.l a0,d0 ; this will be nonzero if CQD exists, else zero
|
||
Beq.s NoCQD ; oh well.. entry is already zero
|
||
MOVE.B #envTRUE,hasColorQD(A2) ; <10>
|
||
NoCQD
|
||
|
||
;-----------------------------------------------------------------------------------------
|
||
; Get Keyboard type
|
||
;-----------------------------------------------------------------------------------------
|
||
Move.l #gestaltKeyboardType,D0 ; ask for keyboard type
|
||
_Gestalt ; ask gestalt for the info
|
||
tst.w d0 ; any errors?
|
||
Beq.s OkKeyBd ; whew..
|
||
moveq #envUnknownKbd,A0 ; oh well, use SysEnvs bad way of saying unknown
|
||
|
||
OkKeyBd MOVE.W a0,keyBoardType(A2) ; move in the value and we're done <10>
|
||
|
||
;-----------------------------------------------------------------------------------------
|
||
; Get AppleTalk Driver Version Number
|
||
;-----------------------------------------------------------------------------------------
|
||
Move.l #gestaltAppleTalkVersion,D0 ; ask for ATalk driver version num
|
||
_Gestalt ; ask gestalt for the info
|
||
tst.w d0 ; any errors?
|
||
Beq.s @ok ; if not, return result
|
||
sub.l a0,a0 ; otherwise, return zero
|
||
@ok Move.w a0,atDrvrVersNum(A2) ; put version number in record <10>
|
||
|
||
;-----------------------------------------------------------------------------------------
|
||
; Get SysVRef -- returns WDRefNum of directory that contains
|
||
; open system file in D0 -- if this call fails, returns 0
|
||
; We use GetFCBInfo here -- slower but smaller
|
||
;
|
||
; NOTE -- 4.1 will patch BootDrive code so BootDrive is always accurate
|
||
; we still need to use this method because DAs or unscrupulous
|
||
; apps may change BootDrive.
|
||
;
|
||
; Assumes system 4.1 and 128K or greater ROMs (HFS)
|
||
;-----------------------------------------------------------------------------------------
|
||
getSysVRef Clr.l D0 ; in case we get an error below
|
||
|
||
Move.w #(ioHVQElSize/2)-1,D1 ; this many CLR.Ws, minus one for the DBRA
|
||
@1 Clr.w -(SP) ; push zeros on stack, worse case 2 too many.
|
||
DBra D1,@1 ; branch if not done
|
||
|
||
Move.l SP,A0 ; A0 points to cleared param blk for HFS calls
|
||
Move.w SysMap,ioRefNum(A0) ; get the fileRefNum of System File
|
||
_GetFCBInfo ; get info
|
||
Bne.s FixStack ; oops, clean up stack and leave
|
||
|
||
; now we need to do a PBHGetVInfo call -- we've already established that we're running HFS
|
||
|
||
Move.w ioFCBVRefNum(A0),ioVRefNum(A0) ; Thanks Bill B. -- no thanks Inside Mac
|
||
_HGetVInfo ; get VFndrInfo (blessed folder's dirID)
|
||
Bne.s FixStack ; oops, clean up stack and leave
|
||
|
||
; we're OK so far, now we just do a OpenWD, the VRef is set up we just need to
|
||
; get the id of the blessed folder from ioVFndrInfo[1] and put it into the dirID
|
||
; field of the parameter block, and away we go!
|
||
|
||
VInfoOK Move.L ioVFndrInfo(A0),ioWDDirID(A0) ; set up the "blessed folder"
|
||
Move.L #SysWDProcID,ioWDProcID(A0) ; put 'ERIK' into WDProcID
|
||
_OpenWD ; open a working directory (probably already open?)
|
||
Bne.s FixStack ; oops, clean up stack and leave
|
||
Move.w ioVRefNum(A0),sysVRefNum(A2) ; put result in parameter block <10>
|
||
FixStack Adda #ioHVQelSize,SP ; clean up the stack, same count as above.
|
||
|
||
;-----------------------------------------------------------------------------------------
|
||
; End of FillInWorld1 - for future versions (>=2) put checking in here to see how
|
||
; much more to fill in, based on selector passed in in D0
|
||
;-----------------------------------------------------------------------------------------
|
||
|
||
ENDWITH
|
||
|
||
Exit MOVE.W D2,D0 ; put error number in D0
|
||
MOVEM.L (SP)+,A0/D2 ; restore regs, including A0 (pointer to record)
|
||
RTS ; return to caller (Return address should be on stack)
|
||
|
||
ENDPROC ; SysEnvirons <C982>
|
||
|
||
;----- <2.4>
|
||
;
|
||
; The Reliability Manager
|
||
;
|
||
; This new "manager" is responsible for monitoring the operation of the machine
|
||
; and recording pertinent information in parameter RAM.
|
||
;
|
||
; Written by Bob Herold, May 24, 1989
|
||
;
|
||
;-----
|
||
|
||
;-----
|
||
; InitReliability - sets time of 1st power on, and initializes the Usage Statistics time
|
||
; manager task
|
||
;
|
||
; The time of 1st power on is kept as the number of 48 hour periods since Jan 1 1989. To
|
||
; calculate this, we first get the number of seconds since Jan 1 1989. On 020 and higher
|
||
; machines, we could divide by the number of seconds in 48 hours. To work on 68000
|
||
; machines, we separate out factors of two to get the divisor into the 16 bit range:
|
||
;
|
||
; # 48 hrs since Jan 1 1989 = (# secs since Jan 1 1989) / (# secs in 48 hours)
|
||
; = (# secs) / (60 * 60 * 24 * 2)
|
||
; = (# secs) / (2*2*15) * (2*2*15) * (2*2*2*3) * 2
|
||
; = (# secs) / (15 * 15 * 3) * 2^^8
|
||
; = ((# secs) / 2^^8) / (15 * 15 * 3)
|
||
;---
|
||
|
||
InitReliability PROC EXPORT
|
||
IMPORT RelTimeTask, RelDeferredTimeTask
|
||
|
||
IF hasPowerMgr THEN
|
||
rts
|
||
ELSE
|
||
|
||
;---
|
||
; Initialize the 'time of 1st power on'
|
||
;---
|
||
|
||
subq #RelPram>>16,sp ; allocate buffer on stack
|
||
move.l Time,d1 ; get current # secs
|
||
sub.l #Jan1st89,d1 ; get # secs since Jan 1 1989
|
||
blo.s @doneStart ; if earlier, clock chip set wrong!
|
||
movea.l sp,a0 ; get buffer ptr
|
||
move.l #RelPram,d0 ; get #, addr PRAM bytes
|
||
_ReadXPram ; read 'em and weep
|
||
move.l (sp),d0 ; get 'da bytes
|
||
and.l #Rel1stMask,d0 ; mask all except 1st powered on time
|
||
bne.s @doneStart ; if already set, do nothing
|
||
lsr.l #8,d1 ; divide # secs by 2^^8
|
||
divu.w #15*15*3,d1 ; get # 48 hour periods (see comment above)
|
||
moveq #Rel1stBit,d0 ; get shift count
|
||
lsl.l d0,d1 ; shift our value into position
|
||
and.l #Rel1stMask,d1 ; mask unneeded high bits
|
||
and.l #-1-Rel1stMask,(sp) ; zero our bits in result
|
||
or.l d1,(sp) ; overlay our value into result
|
||
move.l #RelPram,d0 ; get #, addr PRAM bytes
|
||
_WriteXPram ; write out 1st power on time
|
||
@doneStart addq #RelPram>>16,sp ; de-allocate buffer
|
||
|
||
;---
|
||
; Set up time manager task for power on time measurement
|
||
;---
|
||
|
||
WITH RelGlobals
|
||
|
||
moveq #rlRecSize,d0 ; get size Reliability Mgr globals
|
||
move.b d0,d1 ; save for later
|
||
_NewPtr ,sys,clear ; allocate space for it
|
||
bne.s @done ; don't bother if no room
|
||
move.l ExpandMem,a1 ; get ptr to low memory expansion
|
||
move.l a0,ExpandMemRec.emReliability(a1) ; save ptr to Reliability globals there
|
||
move.b d1,rlGlobalsSize(a0) ; save size of globals
|
||
move.b #rlRecVers,rlGlobalsVers(a0); save version number of globals
|
||
bclr #usRelTaskRun,UnSwitchedFlags; signal we are timing
|
||
|
||
; Initialize a deferred task queue element to schedule execution of the original Time Manager
|
||
; task, now called RelDeferredTimeTask. Pass a pointer to the Time Manager task in dtParm so
|
||
; that the original code still gets its expected parameter in A1.
|
||
|
||
move.w #dtQType,rlDeferredTask.qType(a0)
|
||
lea RelDeferredTimeTask,a1
|
||
move.l a1,rlDeferredTask.dtAddr(a0)
|
||
lea rlTimeBlock(a0),a1
|
||
move.l a1,rlDeferredTask.dtParm(a0)
|
||
|
||
lea rlTimeBlock(a0),a0 ; point to time manager task block
|
||
lea RelTimeTask,a1 ; point to our time task
|
||
move.l a1,tmAddr(a0) ; stuff it into task block
|
||
_InsXTime ; install our task
|
||
move.l #RelMsCount,d0 ; get # ms between calls
|
||
clr.l tmWakeUp(a0) ; signal its the first time
|
||
_PrimeTime ; fire up time mgr task
|
||
@done rts
|
||
|
||
ENDWITH ; {RelGlobals}
|
||
|
||
ENDIF
|
||
|
||
ENDPROC ; {InitReliability}
|
||
|
||
|
||
;-----
|
||
; RelTimeTask - the time manager task for doing all this reliability stuff
|
||
;
|
||
; Called by the Time Manager
|
||
;
|
||
; Entry
|
||
; a0 - points to this routine (not too useful, huh?)
|
||
; a1 - points to task block (now there's something useful!)
|
||
;
|
||
;
|
||
; RelDeferredTimeTask - the deferred Time Manager task for doing all this reliability stuff
|
||
;
|
||
; Called by the Deferred Task Manager
|
||
;
|
||
; Entry
|
||
; A1 - dtParm points to the originating Time Manager task block
|
||
;---
|
||
|
||
RelTimeTask PROC EXPORT
|
||
|
||
; If PRAM is in Egret/CUDA, _ReadXPram and _WriteXPram require interrupts enabled
|
||
; to execute efficiently. Therefore, the periodic Reliability task now uses the
|
||
; Deferred Task Manager to be more interrupt-friendly.
|
||
|
||
; This helps MIDI SysEx dumps and other interrupt tasks run more punctually.
|
||
|
||
lea tmXQSize(a1),a0 ; deferred task element follows TM task element
|
||
_DTInstall
|
||
rts
|
||
|
||
|
||
entry RelDeferredTimeTask
|
||
|
||
RelDeferredTimeTask
|
||
|
||
subq #RelPram>>16,sp ; allocate buffer on stack
|
||
movea.l sp,a0 ; get buffer ptr
|
||
move.l #RelPram,d0 ; get #, addr PRAM bytes
|
||
_ReadXPram ; read 'em and weep
|
||
move.l (sp),d0 ; get 'da bytes
|
||
move.l d0,d1 ; save a copy
|
||
and.l #RelPwrMask,d0 ; mask to get power on time
|
||
addq.l #1,d0 ; increment power on time
|
||
and.l #RelPwrMask,d0 ; mask again, in case of rollover
|
||
and.l #-1-RelPwrMask,d1 ; zero power on time bits
|
||
or.l d0,d1 ; replace the power on time bits
|
||
move.l d1,(a0) ; put new PRAM value in buffer
|
||
move.l #RelPram,d0 ; get #, addr PRAM bytes
|
||
_WriteXPRAM ; write 'em back
|
||
addq #RelPram>>16,sp ; deallocate buffer
|
||
move.l a1,a0 ; get ptr to task block
|
||
move.l #RelMsCount,d0 ; get # ms between calls
|
||
_PrimeTime ; re-fire up time mgr task
|
||
rts
|
||
|
||
ENDPROC ; {RelTimeTask}
|
||
|
||
END
|