mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-29 20:49:19 +00:00
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
|