supermario/base/SuperMarioProj.1994-02-09/OS/SysUtil.a

1648 lines
59 KiB
Plaintext
Raw Normal View History

2019-06-29 15:17:50 +00:00
;__________________________________________________________________________________________________
;
; 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 Managers 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