mac-rom/OS/Gestalt/GestaltFunction.a
Elliot Nunn 4325cdcc78 Bring in CubeE sources
Resource forks are included only for .rsrc files. These are DeRezzed into their data fork. 'ckid' resources, from the Projector VCS, are not included.

The Tools directory, containing mostly junk, is also excluded.
2017-12-26 09:52:23 +08:00

2016 lines
83 KiB
Plaintext

;
; File: GestaltFunction.a
;
; Contains: Entry point for Gestalt trap, and pre-defined Gestalt functions.
;
; Written by: Carl C. Hewitt
;
; Copyright: © 1989-1993 by Apple Computer, Inc., all rights reserved.
;
; Change History (most recent first):
;
; <SM49> 11/19/93 chp When testing for hasEnhancedLTalk, always use ProductInfo flags.
; Remove Cyclone/Tempest boxFlag checks.
; <SM48> 11/8/93 SAM Roll in <MC4> from mc900ftjesus.
; <MC4> 11/8/93 SAM Updated TestForEmu to correctly adjust the logical RAM size when
; an EDisk is present.
; <SM47> 10/28/93 SAM Roll in <MC3> from mc900ftjesus.
; <MC3> 10/28/93 SAM Changed getNativeCPUType to put the PowerPC cpus in the $100
; range.
; <SM46> 10/10/93 SAM Roll in <MC2> from mc900ftjesus.
; <MC2> 10/10/93 SAM Added a universal check for hasEnhancedLTalk in gestaltHardware.
; <SM45> 8/12/93 BG Converted references to gestaltCyclone40 to gestaltQuadra840AV.
; <SM44> 8/7/93 SAM Removed temporary fix to LRAM size made in <SM41>.
; <SM43> 8/4/93 JDR Integrate Sound Manager 3.0 project.
; <SM42> 7/20/93 SAM Added a macro for setting the assembler machine directive to the
; appropriate thing (based on the build time flag "CPU").
; <SM41> 6/29/93 SAM Removed all references to gEDiskSize cuz its not needed. The
; lram value is updated to include the Edisk at initalization (as
; it was in 7.0.1). This still doesnt cover the case of VM
; loading after gestalt (a gibbly fix for PDM is a temporary
; solution). Cyclone this is broken in your ROM.
; <SM40> 6/14/93 SAM Added a test for the hasHardPower bit in Universal info so we no
; longer have to use boxflags for the shutdown dialog crap.
; <SM39> 6/14/93 kc Roll in Ludwig.
; <SM38> 6/3/93 SAM Updated that stupid list of boxflags in hassoftpoweroff to
; reflect the new PDM boxflags.
; <SM37> 5/21/93 CSS Set bits in gestaltFontAttr to indicate settings for double byte
; support.
; <SM36> 4/23/93 SAM Added the temporary PDMEvt2 boxflag to the brain-dead list of
; boxflag based cmp/bne for hassoftpoweroff.
; <SM35> 4/11/93 chp Added a selector to return the HAL type for the runtime CPU.
; This just returns an encoded resource ID from ProductInfo. Also
; added the AppleTalk interrupt level selector from Cyclone.
; <SM34> 4/8/93 KW changed gestaltids for cyclone/tempest products when determining
; if enhanced localtalk is present.
; <SM33> 4/8/93 CSS Use gestalt global for edisk size as the boot globals get hosed
; by VM.
; <SM32> 4/5/93 jb Added TestFor AwacsExists in GetSoundHardware.
; <SM31> 3/30/93 CSS Add EDisk size to logical RAM size in gestaltLogicalRAMSize.
; Before SuperMario, VM was inited before Gestalt. Now this has
; changed. The Gestalt expandmem var realTop(An) used to be fixed
; by Gestalt by taking VM version of RealMemTop and adding the
; Edisk size. Because of how thing are in SuperMario, VM doesn't
; get to affect realTop(An), therefore rather than returning that
; variable, we return RealMemTop (which is the one that VM
; changed). However, for About this MacintoshÉ to work correctly
; (and show the RAM disk as part of the System Software), we need
; to add the RAM disk size whenever we return RealMemTop.
; <SM30> 2/20/93 SAM Updated all the EMMU stuff. MMU page size, emulator present,
; sys architecture, all updated. Fixed up the Universal ROM
; check.
; <SM29> 02/10/93 HY Remove <SM26> change. We no longer need the gestaltNoAppleTalk bit.
; <SM28> 2/5/93 SAM Added support for Emulated page size.
; <SM27> 2/5/93 SAM Updated the System architecture selector to use universal info.
; <SM26> 01/11/93 HY Added code into getMisc for setting gestaltNoAtlkSupport bit.
; If this bit is set then this machines DOESN'T support AppleTalk.
; <SM25> 1/10/93 RC Soft Power Off now works correctly for PDM
; <SM24> 12/13/92 SAM Added gestaltNativeCPUtype and gestaltSysArchitecture. Restored
; universal code in the hdwr selector. Cleaned things up.
; <SM23> 12/4/92 fau Added gestaltTempest33 to soft-power off. Added all
; Cyclone-type machines to say they have enhanced localtalk --
; this should not be box-flag based. I'll get to it soon.
; <SM22> 11/13/92 mal Added MACE Ethernet to hardware attributes gestalt.
; <SM21> 11/11/92 RB The Mac LC II does not have Soft Power Off.
; <SM20> 11/11/92 fau Changed soundhardware to check for the 'DSPExists' feature flag.
; This means that a DSP is installed and used for sound. Made
; tempest not have a soft power off flag.
; <SM19> 11/9/92 fau Made gestaltSoundHardware return 'dsp ' for a Tempest. Rolled
; back change in <SM18> so the Text-to-speech guys fix it.
; <SM18> 11/6/92 FU Made Cyclone/Tempest return ASC for hardware attributes -- will
; back this as soon as a name-revision is done. This will work
; around a Text-to-speech bug.
; <SM17> 11/3/92 RB (Murali) Under SM, return RealMemTop instead of the cached
; realTop in the gestalt globals. Gestalt was loaded before VM
; did, and so realMemTop may have changed by VM, so always use the
; real thing.
; <SM16> 10/27/92 fau Forgot to change a label to actually execute the
; enhancedlocaltalk code.
; <SM15> 10/27/92 fau Added a gestaltHasEnhancedLtalk check to hardwareAttr to enable
; the bit on Cyclone and Tempest.
; <SM14> 9/3/92 PN Nuke the check for IIci because this is SuperMario.
; <SM13> 8/20/92 CS Fix another problem with BootGlobs changing to StartGlobals per
; roll-in from Reality.
; <SM12> 8/17/92 CCH Change getHardwareAttr to not use OrwellExists bit since it was
; removed.
; <SM11> 7/24/92 RLM change GetEDiskSize, now uses BootGlobs, this removes the
; requirement to have drivres installed before Gestalt
; <SM10> 7/20/92 CSS Names of the sound hardware attributes have changed because they were moved
; from GestaltEqu.a to GestaltEquPriv.a by JDR.
; <SM9> 7/14/92 RB Added a function to return the gestaltSoundHardware attributes.
; <SM8> 7/1/92 RB Added the selectors for the gestalt script manager attributes.
; The script Mgr function for gestalt is in ScripMgrExtensions.a
; <SM5> 5/19/92 CS Integrated changes from Reality:
; <42> 4/9/92 JSM #1026795,<DTY>: gestaltSerialAttr should be the same for a Mac
; LC II as a Mac LC.
; <SM4> 4/30/92 SES Rolled in a fix of the parity check routine from PatchIIciROM.a.
; Removed check for bootglobs - all ROMs now have bootglobs, so no
; need to check.
; <SM3> 4/28/92 PN Fix OutlineFont Gestalt so that getFontMgrAtr returns the
; correct result
; <SM2> 4/22/92 PN Roll in hasSoftPowerOff to hardware attribute. Add GetOSTable,
; GetToolboxTable, GetExtToolboxTable, GetFSAttr into ROM build.
; Roll in GetQDFeatures and GestaltFontMgrAttr from
; GestaltPatches.a and BassPatches.a.
; <41> 12/4/91 csd #1016451: Added support for Scruffy. If Scruffy is running, we
; need to set 32-bit capable flag for the
; gestaltAddressingModeAttr selector.
; <40> 12/2/91 SAM Using official boxflag equates now.
; <39> 10/28/91 SAM/KSM Rolled in Regatta Changes. Removed sound selector code from this
; file cuz its in SoundMgrLowLevel.a
;
; Regatta Change History:
;
; <11> 8/28/91 SAM The logical RAM size is now gotten from RealMemTop on IIci
; machines.
; <10> 7/18/91 SAM Using the new MemoryDispatch calls to get the logical & physical
; RAM sizes when VM is on.
; <9> 7/9/91 SAM Removing the gestaltSoundAttr selector. It will get installed by
; the SoundMgr patch.
; <8> 7/2/91 SAM Extended the keyBdTable to include entries for Tim & Asahi.
; <7> 7/1/91 SAM Correcting logical RAM size while VM is running to assure the
; correct value in the case where a 24-bit system is used with
; more than 8mb of VM (in this case VM sets memtop to the wrong
; value!)
; <5> 6/15/91 SAM The size of the EDisk is added to the Logical RAM size that gets
; returned from Gestalt. This is so the RAM disk size shows up in
; the About the Finder dialog. The functionality of the "Is the
; New/ReplaceGestalt Proc Ptr zero?" linked patch has been Added
; to this file (and the patch removed).
; <4> 5/23/91 SAM This time for real (tough typo!)
; <3> 5/23/91 SAM Typo fix.
; <2> 5/23/91 SAM ORR, Added selectors for Jaws, Sonic, SCSC961, SCSI962 and DAFB
; to the Harware attribute table.
; <1> 5/15/91 SAM Split off from 7.0 GM sources. Changed the internal setup of
; MemSize (physical RAM size) and RealTop (logical RAM size) so
; that MemSize is obtained from RealMemTop (the low mem) on
; IIciROM machines and MemTop (the low mem) on all other machines.
;
; 7.0 Change History:
;
; <38> 9/30/91 JSM DonÕt use is32BitClean conditional in getAddrMode, all future
; ROMs will be.
; <37> 9/10/91 JSM Cleanup header.
; <36> 8/30/91 DTY Change the QuickDraw selector code so that it doesnÕt depend on
; the hasCQD conditional. Remove isUniversal check in parity
; selector since we make only universal ROMs now.
; <35> 7/10/91 dba end of the forPost70 conditional; we are past 7.0 for good
; <34> 6/12/91 LN removed #include 'HardwareEqu.a'
; <33> 6/11/91 gbm dba: add new Gestalt bit to indicate that the hardware requires
; a RESET when resetting the machine
; <32> 3/7/91 dnf dty,#DNF-009:Move the latest version of the function for 'fs '
; into here.
; <31> 2/20/91 KON smc BRC #83172: Gestalt should call the QDOffscreen version trap
; to get the 'qd ' version if 32-bit QD is present.
; <30> 2/6/91 KON smc: BRC# Gang of 5: Remove GestaltOriginalQD1 and change to
; GestaltOriginalQD as per Gang Of 5 discussion.
; <29> 1/23/91 KON bbm: no BRC #, Make Gestalt on B&W machines return version 1.
; <28> 1/8/91 SAM Changed all occurrences of gestaltXO to GestaltMacClassic
; <27> 10/22/90 JJ Rex V8: Change VISAChipBit to V8ChipBit.
; <26> 9/22/90 dnf add gestaltFSAttrs for file system attributes
; <25> 9/14/90 MSH Added additional feature based conditionals for inclusion of
; power manager stuff.
; <24> 9/12/90 SAM Changing GestaltElsie to GestaltMacLC.
; <23> 8/13/90 JWK NEEDED FOR SIXPACK: Added NuBus and Serial Gestalt selectors.
; <22> 8/13/90 gbm add selectors for trap table bases
; <21> 7/24/90 gbm Get rid of useless branch
; <20> 7/18/90 CCH Moved machine icon selector to linked patch version in
; GestaltPatches.a.
; <19> 6/20/90 CCH Modified FPU routine to support 68040's when not running in ROM.
; <18> 6/1/90 CCH Added 68040 support to page size selector.
; <17> 5/1/90 CCH Added specific entry for XO (to indicate that it doesn't have a
; PDS slot.) Also added SquareMenuBar response to misc selector.
; <16> 4/11/90 dba add selector that gets the resource ID of the model icon
; <15> 3/26/90 CCH Added check for VISA and renamed gestalt Headphone selector.
; <14> 3/1/90 GMR Fixed bug in parity check for Zone-5, where longword was not
; being written back with good parity after each SIMM check.
; <13> 2/14/90 CCH Made sure external cache on Zone 5 does not interfere with the
; check to see if parity RAM is installed.
; <12> 1/30/90 CCH NEEDED FOR 6.0.5: - Modified gestaltHardwareAttr to set
; gestaltHasSCC bit in result if in IOP bypass mode. - Also
; modified hardware selector to check for 32-bit cleanliness on
; any machine running a/ux.
; <11> 1/25/90 CCH Added values for Elmer keyboards.
; <10> 1/22/90 CCH Added in machine-specific slot information for pre-universal
; ROMs.
; <9> 1/22/90 CCH Added gestaltNotificationMgrAttr selector.
; <8> 1/17/90 CCH NEEDED FOR 6.0.5: moved restoration of cache register in parity
; check routine.
; <7> 1/16/90 CCH turn off cache when checking RPU for parity.
; <6> 1/11/90 CCH Added include of ÒHardwarePrivateEqu.aÓ.
; <5> 1/10/90 CCH Don't check for parity on XO.
; <4> 1/8/90 CCH Added gestaltMisc selector.
; <3> 1/5/90 CCH Changes: (NEEDED FOR 6.0.5) - Added slot selectors back in
; temporarily. - Added RPU and Orwell bits to hardware selector. -
; Added Zone 5 parity support - Reorganized some code to determine
; FPU and MMU types only at startup. - Also removed those
; selectors that only returned SCC, VIA or RBV base addresses.
; <2> 1/3/90 CCH Changed Gestalt equate filename.
; <1> 1/2/90 CCH Changed name from Gestalt.a. Also removed slot-related
; selectors.
; <3.3> 12/15/89 CCH Changes: (NEEDED FOR 6.0.5)
; - Modified gestaltROMSize selector to work with XO
; - GestaltSCCReadAddr and gestaltSCCWriteAddr return
; an error when not in bypass mode on Zone 5.
; - Modified to return machine-specific info for XO.
; <3.2> 11/1/89 CCH Changed gestaltVMInstalled to gestaltVMExists.
; <3.1> 9/29/89 CCH Added gestalt32BitCapable bit to gestaltAddressingModeAttr.
; <3.0> 8/9/89 CCH Changes: (NEEDED FOR 6.0.4)
; - Changed gestaltQuickdrawType to gestaltQuickdrawVersion
; and made it return two-byte versions.
; - Fixed bug in gestaltVersion selector
; <2.9> 7/16/89 CCH Changes: (NEEDED FOR AURORA AND 6.0.4)
; - Started using common exit code for Gestalt functions.
; - Got rid of unecessary HLocks and HUnlocks
; <2.8> 7/10/89 CCH Changes: (NEEDED FOR AURORA)
; - Removed gestaltFirstSlotNumber selector.
; <2.7> 6/30/89 CCH Changes:
; - Added gestaltLowMemSize selector.
; - Fixed bug that caused gestaltLogicalPageSize to write to
; ROM.
; - gestaltAUXVersion now returns an unknown error if a/ux
; is not installed.
; <2.6> 6/26/89 CCH Changes:
; - Added gestaltLogicalPageSize and gestaltFirstSlotNumber
; selectors
; - Rewrote built-in selector
; installation routine
; <2.5> 6/9/89 CCH Changes:
; - Added gestaltAddressingModeAttr, gestaltAUXVersion,
; gestaltSlotAttr, gestaltSoundAttr, gestaltTimeMgrVersion,
; GestaltRBVAddr, gestaltHardwareAttr, gestaltNuBusSlotCount
; selectors.
; - Fixed gestaltLogicalRAMSize to take video RAM into
; account on IIci.
; <2.4> 5/25/89 CCH Changes:
; - Took out concept of internal-only codes, added internal
; gestalt function
; - added NewGestalt, ReplaceGestalt calls
; <2.3> 5/23/89 CCH Changes:
; - Added VIA,SCC,ROM version,VM info, and power mgr selectors
; - changed gestalt function interface to use pascal
; conventions so they can be written in high-level languages
; - save registers before calling gestalt functions
; <2.2> 5/18/89 CCH Several changes:
; - wrote getGestalt in assembly, and moved from Gestalt.c
; - started using new error codes
; - changed interface to use A0 to return results
; - get ROM size routine now uses size word in new ROMs
; - removed code to return system vrefnum, moved to SysEnvirons
; - changed trap number to $A1AD
; <2.1> 4/20/89 CCH Added equate for virtual RAM size.
; <2.0> 4/16/89 CCH Took out a debugger statement.
; <1.9> 4/16/89 CCH Wrote initialization routine in assembly, merged patch
; initialization code into this file, and changed Gestalt equates
; to new naming convention.
; <1.8> 4/3/89 CCH Added international keyboards to keyboard info.
; <1.7> 3/30/89 CCH Took out all functionality except for basic _Gestalt function.
; <1.6> 3/24/89 CCH Now pushes 4 bytes on the stack for shorts when calling C
; functions.
; <1.5> 3/16/89 CCH Re-did selector dispatcher. Thanks, Gary!
; <1.4> 3/16/89 CCH Moved global data in from GestaltEqu.a.
; <1.3> 3/6/89 CCH Uppercased GestaltTrap and changed MMU code to use new equates.
; <1.2> 3/3/89 CCH Added assembly versions of Atalk driver code, and sys refnum
; code.
; <1.1> 2/22/89 CCH Started using global ptr in ExpandMem.
; <1.0> 2/21/89 CCH Adding to EASE for the first time.
; 2/14/89 CCH New Today.
;
TITLE 'Gestalt'
CASE OBJ
PRINT OFF
LOAD 'StandardEqu.d'
INCLUDE 'HardwarePrivateEqu.a'
INCLUDE 'UniversalEqu.a'
INCLUDE 'SANEMacs881.a'
INCLUDE 'MMUEqu.a'
INCLUDE 'GestaltEqu.a'
INCLUDE 'GestaltPrivateEqu.a'
include 'InternalOnlyEqu.a'
INCLUDE 'EDiskEqu.a'
INCLUDE 'BootEqu.a'
PRINT ON
MACRO
SETMACHINE
IF CPU = 020 THEN
MACHINE MC68020
ELSEIF CPU = 030 THEN
MACHINE MC68030
ELSEIF CPU = 040 THEN
MACHINE MC68040
ELSE
AERROR 'Unknown CPU type'
ENDIF
ENDM
SETMACHINE
;;; Gestalt private equates
GestaltTrapID EQU $A1AD ; Gestalt trap number
NewGestaltTrapID EQU $A3AD ; newGestalt trap number
ReplaceGestaltTrapID EQU $A5AD ; ReplaceGestalt trap number
HighestProc EQU $7fffffff
LongEntrySz EQU 8 ; size of an entry in table
RomVersionOffset EQU 8 ; offset from base of ROM to ROM version word
AUXVersion EQU $110 ; version 1.1 is default
addFlag EQU 0 ; flag to add a code
replaceFlag EQU 1 ; flag to replace a code
VIA2Base EQU $50f02000 ; via 2 base on all pre-universal ROM machines <2.9>
UnimplementedTrap EQU $A89F ; unimplemented trap
PMgrOpTrap EQU $A085 ; power manager trap
UserDelayTrap EQU $A84C ; user delay trap <17>
VMGlobals EQU $B78 ; Pointer to VM's globals <5>
************************************************************************
* purpose: entry point for the Gestalt function
*
* on entry: d0 = selector
* a0 = gestalt function (add,replace)
* on exit: a0 = result (gestalt)
* a0 = old gestalt function (replace)
* d0 = error code
*
************************************************************************
GESTALTTRAP FUNC EXPORT
IMPORT newGestalt
EXPORT INITGESTALT
cmp.w #GestaltTrapID,d1 ; Gestalt?
beq.s @getGestalt ; yup
move.l a0,-(sp) ; space for oldProc (preserves a0 otherwise)
move.l sp,-(sp) ; put address of scratch space on stack
move.l a0,-(sp) ; put gestalt function ptr on stack
move.l d0,-(sp) ; put selector on stack
tst.l 12(SP) ; Is the Proc/Var ptr nil? <5>
beq.s @err ; -> Yes, bail out <5>
cmp.w #NewGestaltTrapID,d1 ; NewGestalt?
beq.s @newGestalt ; yup
cmp.w #ReplaceGestaltTrapID,d1 ; ReplaceGestalt?
bne.s @err ; nope, oh oh
move.l #replaceFlag,-(sp) ; push replace flag
bra.s @callNew
@newGestalt move.l #addFlag,-(sp) ; push add flag
@callNew jsr newGestalt ; call newGestalt
add.l #16,sp ; clean up stack
move.l (sp)+,a0 ; return oldProc or original a0
bra.s @takeOff
@getGestalt movem.l a2-a4/d3-d7,-(sp) ; save registers
Jsr getGestalt ; go get an entry
movem.l (sp)+,a2-a4/d3-d7 ; restore regs
Bra.s @takeOff ; branch
@err add.l #16,sp ; clean up stack
Move.l #paramErr,D0
@takeOff Rts
************************************************************************
*
* function: getGestalt( selector, result )
* long selector;
* long *result;
*
* entry: d0.l = function code
*
* exit: a0.l = result
* d0.w = error code
*
* destroys: d0-d3/a0-a1
*
************************************************************************
getGestalt
WITH GestaltGlobals, ExpandMemRec
IMPORT findLong
move.l d0,d3 ; save selector
subq.l #4,sp ; clear space for index
move.l sp,-(sp) ; put ptr to it on stack
move.l d0,-(sp) ; put code to find on stack
jsr findLong ; try to find it
addq.l #8,sp ; get rid of parameters
move.l (sp)+,d2 ; get index into d2
tst.w d0 ; did we find the code?
beq.s undefErr ; nope, exit
move.l ExpandMem,a0 ; get expandmem ptr
move.l emGestalt(a0),a1 ; get gestalt global ptr
move.l TableH(a1),a0 ; get table handle
move.l (a0),a1 ; get ptr to table
lsl.l #3,d2 ; turn index into offset
move.l 4(a1,d2.l),a1 ; get proc ptr
; call the gestalt function to determine the result
clr.l -(sp) ; space for result to be stored
clr.w -(sp) ; space for error code
move.l d3,-(sp) ; selector
pea 6(sp) ; address of space to store result
jsr (a1) ; call the function
move.w (sp)+,d0 ; get error code into d0
move.l (sp)+,a0 ; return result in a0
bra.s exit ; see ya..
undefErr move.l #gestaltUndefSelectorErr,d0 ; fall through
exit rts
************************************************************************
*
* Built-in codes
*
* Gestalt Function Description:
*
* pascal OSErr GestaltProc( longint selector, var longint result )
*
************************************************************************
GestaltProcParms RECORD 0,INCREMENT
returnAddr DS.L 1
resultPtr DS.L 1
selector DS.L 1
error DS.W 1
ENDR
WITH GestaltProcParms, ExpandMemRec, GestaltGlobals, ProductInfo
************************************************************************
* System Version
************************************************************************
getSysVersion clr.l d0 ; clear result register <2.9>
Move.w SysVersion,d0 ; save system version in lsw of result
bra stdResult ; save result and exit <2.9>
************************************************************************
* ROM Version
************************************************************************
getRomVersion Move.l RomBase,A1 ; get base of ROM
clr.l d0 ; clear result register <2.9>
move.w RomVersionOffset(a1),d0 ; put version in lsw of result
bra stdResult ; save result and exit <2.9>
************************************************************************
* A/UX Version
************************************************************************
getAuxVersion Btst #hwCbAUX-8,HWCfgFlags ; check for A/UX -- if bit set, A/UX is running (-8 because
; equates for HwCfgFlags are based on 16-bit word)
Beq stdUnknown ; if not running, give an error <2.9>
clr.l d0 ; clear result register <2.9>
move.w #AUXVersion,d0 ; blob in default a/ux version (no better way, yet)
bra stdResult ; save result and exit <2.9>
************************************************************************
* Machine Type
************************************************************************
getMachineType Move.l ExpandMem,A1 ; find out where expandMem is
Move.l emGestalt(A1),A1 ; get global ptr
clr.l d0 ; clear result register <2.9>
Move.w machType(A1),d0 ; put machineType in lsw of result
bra stdResult ; save result and exit <2.9>
************************************************************************
* Processor Type
************************************************************************
getProcessor moveq.l #0,d0 ; clear d0
Move.b CPUFlag,D0 ; get processor type
Addq #1,D0 ; adjust to make it the correct result #
bra stdResult ; save result and exit <2.9>
************************************************************************ <SM24><SM30>
* System Architecture
************************************************************************
getSysArchitecture ; If we're running (68k code) and Emu is installed
; for now, assume Architecture is PPC.
MOVE.L ExpandMem,A1 ; find out where expandMem is
MOVE.L emGestalt(A1),A1 ; get global ptr
TST.B Emu68k(A1) ; Do the globals say we have an emulator? <SM29>
BEQ.S @MC68k ; -> Nope, ol' slow boy. <SM29>
@PowerPC MOVEQ #gestaltPowerPC,D0 ; Emulator is running. Signal PowerPC architecture
BRA stdResult ; -> Return
@MC68k MOVEQ #gestalt68k,D0 ; Emu is off. Assume 68k
BRA stdResult ; -> Return
IsEmuInstalled TestFor has68kEmulator
RTS ; On Exit z set = PowerPC, clear = 68k
************************************************************************ <SM24>
* Native Processor Type
************************************************************************
getNativeCPUtype
MOVE.L ExpandMem,A1 ; find out where expandMem is
MOVE.L emGestalt(A1),A1 ; get global ptr
TST.B Emu68k(A1) ; Do the globals say we have an emulator? <SM30>
BEQ.S @MC68k ; -> Nope, ol' slow boy. <SM30>
MOVEQ.L #0,D0 ; Clear out D0
MOVE.B nativeCPU(A1),D0 ; Get the PowerPC processor type <SM30>
ADD.W #$100,D0 ; Bump the PowerPC CPU type into the $100 range <MC3>
BRA stdResult ; -> Return
@MC68k MOVE.B CPUFlag,D0 ; Return CPU flag <MC3>
BRA stdResult
************************************************************************
* Keyboard Type
* Note: To add new keyboards, simply add types to table before EOT.
************************************************************************
getKeyboard Move.b KbdType,D0 ; get keyboard type
Lea keyBdTable,A0 ; get table into A0
move.l a0,a1 ; save a copy
keyBdLoop Move.b (A0)+,D1 ; get an entry from table
Beq stdUnknown ; if we get to the end, unknown keyboard <2.9>
Cmp.b D0,D1 ; does our keyboard match this entry?
Bne.s keyBdLoop ; yep, we found it
keyBdFound Sub.l A1,A0 ; get the index into the table
Move.l A0,D0 ; get ready to store the result
keyBdDone bra stdResult ; save result and exit <2.9>
keyBdTable DC.B $03 ; Macintosh Keyboard
DC.B $13 ; Macintosh keyboard & keypad
DC.B $0B ; Mac Plus Keyboard
DC.B $02 ; Apple Extended Keyboard
DC.B $01 ; Standard Apple Keyboard
DC.B $06 ; Standard Portable ADB Keyboard
DC.B $07 ; Portable ISO ADB Keyboard
DC.B $04 ; Standard ISO ADB Keyboard
DC.B $05 ; Extended ISO ADB Keyboard
DC.B $08 ; Elmer ADB Keyboard
DC.B $09 ; Elmer ISO ADB Keyboard
DC.B $0C ; Tim/Asahi ADB Keyboard
DC.B $0D ; Tim/Asahi ISO ADB Keyboard
DC.B $00 ; EOT
************************************************************************
* FPU Type
************************************************************************
getFPUType Move.l ExpandMem,A1 ; find out where expandMem is
Move.l emGestalt(A1),A1 ; get global ptr
clr.l d0 ; clear result register
Move.b fpu(A1),d0 ; put fpu type in lsb of result
bra stdResult ; save result and exit
************************************************************************
* MMU Type
************************************************************************
getMMUType Move.l ExpandMem,A1 ; find out where expandMem is
Move.l emGestalt(A1),A1 ; get global ptr
clr.l d0 ; clear result register
Move.b mmu(A1),d0 ; put mmu type in lsb of result
bra stdResult ; save result and exit
************************************************************************
* parity attributes
************************************************************************
getParityStatus Move.l ExpandMem,A1 ; find out where expandMem is
Move.l emGestalt(A1),A1 ; get global ptr
Move.l parityStatus(A1),d0 ; put parity status into result
bra stdResult ; save result and exit
************************************************************************
* miscellaneous attributes
************************************************************************
getMisc clr.l d3 ; clear result
IF not forROM THEN
move.l ROMBase,A0 ; Get ROMBase <SM23>
lea universalROMs,A1 ; Point to the table of Clean/Univeral ROM Sigs
move.w (A1)+,D1 ; Get a ROM id (list is null terminated)
beq.s @checkMemCtrlr ; -> End of table means not universal (huh)
cmp.w D1,ROMHeader.MachineNumber(A0) ; Check a table entry
beq.s @userDelay ; -> Yep, set the hasBootGLobs ROM bit <SM23>
ENDIF
bset #gestaltBootGlobals,d3 ; we have boot globals
@userDelay bset #gestaltScrollingThrottle,d3 ; <SM3> <17>
@squareMenus move.b NTSC,d0 ; get a copy of the NTSC byte <17>
andi.b #$0F,d0 ; only look at bottom nibble <17>
bne.s @next ; if it's non-zero, menus aren't square <17>
bset #gestaltSquareMenuBar,d3 ; otherwise, it is! <17>
@next move.l d3,d0 ; put result into d0 <17>
bra stdResult ; save result and exit
; <SM4><SES>
; Removed ROM version compare - all ROMs now have bootglobs
************************************************************************
* Logical Page Size
************************************************************************
DefaultPageSize EQU $8000 ; default page size = 32k
EmulatorPageSize EQU $1000 ; emulator page size = 4k
getPageSize
IF hasMMU or (not ForRom) THEN ; <2.9>
clr.l d0 ; clear result <18>
cmpi.b #cpu68040,CPUFlag ; are we on an 040? <18>
bne.s @1 ; IF we are on an 040 <18>
MACHINE MC68040 ; <18>
movec tc,d1 ; get tc <18>
btst #14,d1 ; are we in 8k page mode? <18>
bne.s @0 ; if so, skip this <18>
bset #12,d0 ; if not, set page size to 4k <18>
bra.s @saveResult ; take off <18>
@0
bset #13,d0 ; set page size to 8k <18>
bra.s @saveResult ; <18>
MACHINE MC68030
@1
cmpi.b #2,CPUFlag ; are we on at least an 020?
blo @noPages ; oh well, no page size <2.9>
cmpi.b #PMMU851,MMUType ; do we have some kind of real mmu?
blo.s @normalSize ; nope, use default page size
Move.l ExpandMem,A0 ; find out where expandMem is
Move.l emGestalt(A0),A0 ; get global ptr
tst.b emu68k(A0) ; Do the globals say we have a 68k Emulator? <SM30>
bne.s @GetEmuPageSize ; -> Yes, get the saved page size <SM30>
lea myScratch(A0),a0 ; get address of scratch area
pmove tc,(a0) ; get a copy of the TC
bfextu (a0){8,4},d1 ; get # addr bits for pageSize <2.8>
bset d1,d0 ; get our pagesize <2.8>
bra.s @saveResult ; done!
@GetEmuPageSize Move.l nativePageSize(A0),D0 ; Grab the NanoKernel's page size <SM30>
bra.s @saveResult ; save result and exit <SM28>
@normalSize Move.l #DefaultPageSize,D0 ; use default pagesize
@saveResult bra stdResult ; save result and exit <2.9>
SETMACHINE ; <SM42>
ENDIF ; <2.9>
@noPages
bra stdUnknown ; there are no pages to have sizes <2.9>
************************************************************************
* Low Memory Size
************************************************************************
getLowMemSize move.l SysZone,d0 ; system zone starts at top of low-mem
bra stdResult ; save result and exit <2.9>
************************************************************************
* RAM Size
************************************************************************
getRAMSize
Move.l ExpandMem,A1 ; find out where expandMem is
Move.l emGestalt(A1),A1 ; get global ptr
cmp.l #gestaltLogicalRAMSize,selector(sp) ; asking for logical size?
bne.s @physicalSize ; nope, physical size
Move.l realTop(A1),d0 ; store adjusted amount of RAM in d0 <2.9>
bra.s @gotMemSize ; go store the info
@physicalSize Move.l memSize(A1),d0 ; store amount of RAM in d0
@gotMemSize bra stdResult ; save result and exit <2.9>
************************************************************************
* ROM Size
************************************************************************
MachCount EQU 14
getROMSize move.l RomBase,a0 ; get base of ROM <3.3>
IF not ForRom THEN ; <2.9>
cmp.b #3,ROMHeader.MachineNumber(a0) ; >= 3 knows size <3.3>
bcc.s romKnows ; size is in header, use that for response <3.3>
Move.l ExpandMem,A0 ; otherwise, get expandMem pointer
Move.l emGestalt(A0),A0 ; get global ptr
Move.w machType(A0),D1 ; get machineType
cmp.w #gestaltMacSE,d1 ; SE or later? <3.3>
bcs.s smallROM ; nope, has to be 128k <3.3>
move.l #$40000,d0 ; otherwise, 256k if no size in ROM header <3.3>
bra.s machExit ; return result <3.3>
smallROM move.l #$20000,d0 ; for Mac Plus and 512ke (puny) <3.3>
bra.s machExit ; return result <3.3>
ENDIF ; <2.9>
romKnows move.l ROMHeader.RomSize(a0),d0 ; get size of the ROM <3.3>
machExit bra stdResult ; save result and exit <2.9>
IF ForRom THEN ;<SM2> <PN> <22>
************************************************************************
* OS trap table base
************************************************************************
getOSTable ; <22>
move.l #$00000400, d0 ; this is the same on all machines <22>
bra stdResult ; <22>
************************************************************************
* Toolbox trap table base
************************************************************************
getToolboxTable ; <22>
move.l RomBase, a0 ; get base of the rom... duh... <22>
cmp.w #$0075, ROMHeader.MachineNumber(a0) ; are we on a MacPlus? <22>
bne.s @notPlus ; <22>
move.l #$00000C00, d0 ; this is only different on MacPlus <22>
bra stdResult ; <22>
@notPlus ; <22>
move.l #$00000E00, d0 ; this is where it goes on everything else <22>
bra stdResult ; <22>
************************************************************************
* Extended Toolbox trap table base
************************************************************************
getExtToolboxTable ; <22>
move.l RomBase, a0 ; get base of the rom... duh... <22>
cmp.w #$0075, ROMHeader.MachineNumber(a0) ; are we on a MacPlus? <22>
beq.s @plusOrSE ; yes, return the table base address <22>
cmp.w #$0276, ROMHeader.MachineNumber(a0) ; are we on an SE? <22>
bne stdUnknown ; not MacPlus or SE, we take the fifth <22>
@plusOrSE ; <22>
move.l XToolTable, d0 ; get the table base from the vector... <22>
bra stdResult ; <22>
************************************************************************
* Extended File System dispatching flags
************************************************************************
getFSAttr ; <26>
moveq #0, d0 ; <26>
move.w # \ ; <32>
(1<<gestaltFullExtFSDispatching) | \ ; <32>
(1<<gestaltHasFSSpecCalls) | \ ; <32>
(0<<gestaltHasFileSystemManager) \ ; <32>
, d0 ; <32>
bra stdResult ; <26>
; <26>
************************************************************************
* Quickdraw feature flags ;<14>
************************************************************************
getQuickdrawFeatures
moveq #0, d0 ; <SM2> <PN> <26>
move.l # \ ; <SM2> <PN> ;<14>
(1<<gestaltHasColor) | \ ; <SM2> <PN> ;<14>
(1<<gestaltHasDeepGWorlds) | \ ; <SM2> <PN> ;<14>
(1<<gestaltHasDirectPixMaps) | \ ; <SM2> <PN> ;<14>
(1<<gestaltHasGrayishTextOr) \ ; <SM2> <PN> ;<14>
, d0 ; <SM2> <PN>
bra stdResult ;<SM2> <PN> <26>
************************************************************************
* FontManager Attribute ;<14>
************************************************************************
IF hasSplineFonts THEN
getFontMgrAttr
move.l #(1 << gestaltOutlineFonts) | \
(1 << gestaltPartialFonts) | \
(1 << gestaltDiskCachedFonts) \
, d0 ;<SM37> CSS
bra stdResult ;<SM2> <PN> <26>
ENDIF
ENDIF ; IF ForRom <22>
************************************************************************
* QD Version
************************************************************************
qdVersion
IF not ForRom THEN ; <2.9>
cmp.w #$3fff,Rom85 ; do we have color quickdraw?
bgt.s @noCQD ; nope..
Move.w #UnimplementedTrap,D0 ; get loc of unimplemented trap
_GetTrapAddress ,newTool ; get the address into A0
Move.l A0,D2 ; save it for a sec
Move.l #$AB03,D0 ; trap ID to check for 32-bit QD
_GetTrapAddress ,newTool ; get the address of it
Move.l #gestalt8BitQD,D0 ; assume 8-bit CQD
Cmp.l A0,D2 ; is it unimplemented?
Bne.s @fullCQD ; Yep..
bra.s qdDone
ENDIF ; <2.9>
;
; We donÕt make ROMs without Color QuickDraw any more, so we donÕt need the <36>
; second part of this conditional. (And this code is always here for the <36>
; RAM version of the selector.) <36>
;
IF (not ForRom) THEN ; <2.9>
@noCQD move.l #gestaltOriginalQD,d0 ; original qd, fall through
bra.s qdDone
ENDIF ; <2.9>
@fullCQD
subq #4,sp ; leave room for result <31>
_OffScreenVersion ; use offscreen version + $100 <31>
move.l (sp)+,d0 ; <31>
add.w #$100, d0
qdDone bra stdResult ; save result and exit <2.9>
************************************************************************
* AppleTalk Driver Version Number
************************************************************************
getATalkVersion
;Is the B serial port in use?
Clr.l D0 ; assume it's not installed
Tst.b PortBUse ; if so, this will be positive.
Bmi.s ATalkVersDone ; oops - not in use, I thought so, return 0
;Port B is in use. Is it in use by AppleTalk?
Move.b SPConfig,D1 ; get port configuration info
And.b #$0F,D1 ; mask off to Port B info only
Cmp.b #useATalk,D1 ; is it AppleTalk?
Bne.s ATalkVersDone ; nope, return 0
;Port B is in use by AppleTalk. Get the DCE pointer
Move.l ABusDCE,A0 ; get .MPP's DCE pointer
Move.b DCtlQueue+1(A0),D0 ; put version number in D0
ATalkVersDone bra stdResult ; save result and exit <2.9>
************************************************************************
* Power Manager
************************************************************************
noPMgrMask EQU (0<<gestaltPMgrExists)|\ ; power manager doesn't exist
(0<<gestaltPMgrCPUIdle)|\ ; can't put SCC into idle mode
(0<<gestaltPMgrSCC)|\ ; can't put CPU into idle mode
(0<<gestaltPMgrSound) ; can't put ADB into idle mode
portablePMgrMask EQU (1<<gestaltPMgrExists)|\ ; power manager exists
(1<<gestaltPMgrCPUIdle)|\ ; can put SCC into idle mode
(1<<gestaltPMgrSCC)|\ ; can put CPU into idle mode
(1<<gestaltPMgrSound) ; can idle sound hardware
PowerMgr
IF hasPwrControls|PwrMgrADB|hasPwrMgrClock OR (not ForRom) THEN ; <2.9>
Move.l ExpandMem,A0 ; find out where expandMem is
Move.l emGestalt(A0),A0 ; get global ptr
cmp.w #gestaltPortable,machType(A0) ; must be portable or later to have pmgr
blt.s @noPmgr ; save time..
Move.w #UnimplementedTrap,D0 ; get loc of unimplemented trap
_GetTrapAddress ,newTool ; get the address into A0
Move.l A0,D2 ; save addr
Move.l #PMgrOpTrap,D0 ; trap ID to check for power manager
_GetTrapAddress ,newOS ; get the address of it
Cmp.l A0,D2 ; is it unimplemented?
Beq.s @noPmgr ; Yep..
Move.l #portablePMgrMask,d0 ; the mask for the current power mgr
bra.s pMgrDone
ENDIF ; <2.9>
@noPmgr Move.l #noPMgrMask,D0 ; assume non-existent
pMgrDone bra stdResult ; save the result and exit <2.9>
************************************************************************
* Addressing mode attributes
************************************************************************
getAddrMode clr.l d0 ; clear result <3.1>
IF NOT ForROM THEN ; <3.1>
btst #hwCbAUX-8,HWCfgFlags ; check for A/UX <12>
bne.s cleanROM ; a/ux uses IIci memory manager <12>
move.l RomBase,a0 ; get ptr to base of ROM <3.1>
move.w 8(a0),d1 ; get ROM version <3.1>
lea cleanROMs,a0 ; point to table of 32-bit clean ROMs <3.1>
cleanROMloop cmp.w (a0)+,d1 ; is this a clean ROM? <3.1>
beq.s cleanROM ; "ajax was here" <3.1>
tst.w (a0) ; any more to check? <3.1>
bne.s cleanROMloop ; if so, go check <3.1>
cmp.w #$0178, D1 ; Mac-II class machine? <41>
bne stdResult ; if not, Scruffy canÕt be here <41>
cmp.l #$00002000, SysZone ; is Scruffy running? <41>
beq.s cleanROM ; if so, weÕre now 32-bit clean <41>
bra stdResult ; what a dirty old ROM <3.1>
ENDIF ; <3.1>
cleanROM move.b SystemInfo,d0 ; get status byte into d1 <2.9>
not.b d0 ; invert status bits so we can use them
and.l #3,d0 ; only want bit 0 and bit 1
bset #gestalt32BitCapable,d0 ; return that machine is 32-bit clean <3.1>
bra stdResult ; save result and exit <2.9>
universalROMs
cleanROMs dc.w $077D ; SuperMario ROM <PN>
dc.w $067C ; IIci ROM <PN>
dc.w 0 ; eot <3.1>
************************************************************************
* Time Manager type (stolen from Gary's ERS)
************************************************************************
getTimeMgrType suba.w #tmQSize,sp ; allocate a TMTask
movea.l sp,a0 ; pointer to task for time manager traps
clr.l TMCount(a0) ; avoid bug in standard time mgr
move.w #$ffff,QType(a0) ; set all bits of QType
_InsTime ; install the task
moveq.l #1,d1 ; assume version is standard version
move.b QType(a0),d0 ; should be unchanged for std time mgr
bmi.s @remove ; if still negative, must be std time mgr
addq.l #1,d1 ; assume version is revised version
add.b d0,d0 ; next highest bit unchanged
bmi.s @remove ; will be cleared on extended version
addq.l #1,d1 ; version must be extended version
@remove _RmvTime ; didn't even have to start the timer!
adda.w #tmQSize,sp ; restore stack pointer
move.l d1,d0 ; put result into d0 <2.9>
bra stdResult ; save result and exit <2.9>
************************************************************************
* VM Info
************************************************************************
VMInfo clr.l d0 ; VM installs itself, otherwise off <3.3>
bra stdResult ; save result and exit <2.9>
************************************************************************
* Sound Hardware
************************************************************************
GetSoundHardware
move.l #gestaltASCSnd,d0 ; default is Apple Sound Chip <SM9> rb <SM10> CSS <SM19> <SM20> fau
TestFor AwacsExists ; Do we have an Awacs audio codec?
beq @check4dsp ; nope, try DSP
move.l #gestaltAwacsSnd, d0 ; yep, so return the appropriate thing
bra stdResult
@check4dsp TestFor DSPExists ; Are we using the DSP for sound
beq stdResult ; Nope
move.l #gestaltDSPSnd,d0 ; set the DSP type
bra stdResult ; and exit
************************************************************************
* Notification Manager <9>
************************************************************************
notification clr.l d0 ; clear result
bset #gestaltNotificationPresent,d0 ; Notification Manager now always exists
@noNMgr bra stdResult ; save result and exit
************************************************************************
* Serial attributes <23>
************************************************************************
getSerialAttr
movea.l ExpandMem,a0 ; get ptr to expandmem rec
movea.l emGestalt(a0),a0 ; get gestalt global ptr
moveq.l #0,d0 ; assume no GPI connections
cmpi.w #gestaltMacPlus,machType(a0)
beq.s @toStdResult
cmpi.w #gestaltMacClassic,machType(a0)
beq.s @toStdResult
cmpi.w #gestaltMacLC,machType(a0) ; <24>
beq.s @toStdResult
cmpi.w #gestaltMacLCII,machType(a0) ; <SM5> CSS <42>
beq.s @toStdResult ; <SM5> CSS <42>
; all other machines have GPI connected
moveq.l #(1<<gestaltHasGPIaToDCDa)|\ ; GPIa connected to DCDa
(1<<gestaltHasGPIaToRTxCa)|\ ; GPIa connected to RTxCa clock input)
(1<<gestaltHasGPIbToDCDb),d0 ; GPIb connected to DCDb
@toStdResult bra stdResult
************************************************************************
* Serial HAL Type (universal ROM only)
************************************************************************
getSerialHALType
moveq #0,d0 ; clear result
TestFor SerialDMA
beq stdUnknown ; hardware does not use SerialDMA so HAL type is not valid
move.l #ProductInfo.SHALMask,d0
and.l UnivROMFlags1,d0 ; get HAL type from universal info
lsr.l #2,d0 ; right justify
bra stdResult
************************************************************************
* get slot info <2.9>
************************************************************************
getSlotInfo
IF not ForRom THEN ;
movea.l ExpandMem,a0 ; get ptr to expandmem rec
movea.l emGestalt(a0),a0 ; get gestalt global ptr
cmpi.w #gestaltMacIIci,machType(a0) ; Mac IIci is first universal ROM
blt getMachSpecific ; if so, don't use this routine
cmpi.w #gestaltMacClassic,machType(a0) ; no universal tables on XO either
beq getMachSpecific ;
cmpi.w #gestaltPowerBook100,machType(a0) ; no universal tables on Asahi either <40>
beq getMachSpecific ;
ENDIF ;
IF hasSlotMgr or (not ForRom) THEN ;
WITH NuBusInfo
movea.l UnivInfoPtr,a0 ; get universal info ptr
adda.l NuBusInfoPtr(a0),a0 ; add in offset to NuBus info
clr.l d0 ; clear index
clr.l d1 ; clear bitmap of NuBus connectors <23>
@slotLoop btst #hasConnector,(a0,d0.w) ; does this slot have a connector?
beq.s @next ; if not, go look at next slot
bset.l d0,d1 ; note that this slot has a NuBus connector <23>
@next addq #1,d0 ; bump up to next slot
cmpi.l #gestaltMaxNuBusSlots,d0 ; have we gone through all slots? <LW6>
bne.s @slotLoop ; if not, keep going
move.l d1,d0 ; return the bitmap of NuBus connectors <23>
bra stdResult ; return the info
ENDWITH
ELSE
bra stdUnknown ; by here, there are no slots with connectors
ENDIF
*************************************************************************
* hardware attributes ¥¥¥ This code assumes a universal ROM!!! ¥¥¥
* ¥¥¥ It cannot be used in the System file!! ¥¥¥
*************************************************************************
getHardwareAttr
IF ForROM THEN ;<SM2> <PN>
movea.l ExpandMem,a0 ; get ptr to expandmem rec
movea.l emGestalt(a0),a0 ; get gestalt global ptr
cmpi.w #gestaltMacIIci,machType(a0) ; must use tables for pre Mac IIci machines
blo getMachSpecific ; if so, don't use this routine
cmpi.w #gestaltMacClassic,machType(a0) ; no universal tables on XO either <3.3>
beq getMachSpecific ; <3.3>
cmpi.w #gestaltPowerBook100,machType(a0); no universal tables on Asahi either <6><40>
beq getMachSpecific ; <6>
ENDIF ;
clr.l d0 ; clear result
lea AttrTable,a0 ; get gestalt->universal mapping table
move.l AddrMapFlags,d1 ; get universal info attributes
@attrLoop move.b (a0)+,d2 ; get gestalt attribute bit number
bmi @loopDone ; if negative, we're done
move.b (a0)+,d3 ; get universal attribute bit number
btst d3,d1 ; is attribute set for this machine?
beq.s @attrLoop ; if not, check next bit
bset d2,d0 ; set bit is gestalt result
bra.s @attrLoop ; check next bit
@loopDone move.l UnivROMFlags,d1 ; get external feature bits
btst #PGCInstalled,d1 ; check if a parity chip exists
beq.s @PGCDone ; if not, return d0 as is
bset #gestaltHasPGC,d0 ; otherwise, set PGC exists bit
@PGCDone
btst #v8ChipBit,d1 ; check if a VISA chip exists <27>
beq.s @visaDone ; if not, return d0 as is
bset #gestaltHasVisa,d0 ; otherwise, set Visa exists bit
@visaDone
move.l #gestaltHasSCCIOP,d1 ; bit number to test for SCC IOP <12>
btst d1,d0 ; do we have one? <12>
beq.s @HasSoftPowerOff ; if not, don't check for bypass mode <12>
btst #0,SCCIOPFlag ; are we in bypass mode? <12>
beq.s @HasSoftPowerOff ; IF in Bypass Mode <12>
move.l #gestaltHasSCC,d1 ; get SCC exists bit <12>
bset d1,d0 ; set SCC exists bit in result <12>
; ENDIF <12>
;Roll in NewGestaltSelectors from GestaltPatches.a <SM2> <PN>
@HasSoftPowerOff
; Check for HardPower/SoftPower supplies (please dont use boxflag) <SM39>
IF forROM THEN
TestFor hasHardPowerOff ; See if this power supply is cheap, stupid and manual! <SM39>
bne.s @noSoftPowerOff ; -> Has a cheap power switch. <SM39>
ELSE ; <SM39>
movea.l ExpandMem,a0 ; get ptr to expandmem rec <SM2> <PN>
movea.l emGestalt(a0),a0 ; get gestalt global ptr <SM2> <PN>
cmpi.w #gestaltMacSE30,machType(a0) ; if this is an SE/30, we donÕt have soft power-off <SM2> <PN>
beq.s @noSoftPowerOff
cmpi.w #gestaltMacLC,machType(a0) ; if this is an LC, we donÕt have soft power-off <SM2> <PN>
beq.s @noSoftPowerOff
cmpi.w #gestaltMacLCII,machType(a0) ; if this is an LC II, we donÕt have soft power-off <SM26> rb
beq.s @noSoftPowerOff
cmpi.w #boxClassicII,machType(a0) ; if this is an Apollo, we donÕt have soft power-off <5><22> <SM2> <PN>
beq.s @noSoftPowerOff ; <SM2> <PN>
cmpi.w #gestaltTempest25,machType(a0) ; if this is a Tempest, we donÕt have soft power-off <SM20> fau
beq.s @noSoftPowerOff ; <SM20> fau
cmpi.w #gestaltTempest33,machType(a0) ; if this is a Tempest, we donÕt have soft power-off <SM23> fau
beq.s @noSoftPowerOff ; <SM23> fau
ENDIF ; <SM39>
move.l #gestaltHasSoftPowerOff,d1 ; Get the Gestalt bit for SoftpowerOff
bset d1,d0 ; Say we gots SoftPowerOff
@noSoftPowerOff
@IsUniversal
IF not forROM THEN
bsr.s IsROMUniversal ; See if this ROM is universal <SM29>
beq.s @checkMemCtrlr ; -> Nope, skip it <SM29>
ENDIF
@HasUniv move.l #gestaltHasUniversalROM,d1 ; Get the Gestalt bit for Univ <6>
bset d1,d0 ; Say we gots a Universal ROM! <6>
@checkMemCtrlr move.l UnivInfoPtr,a0 ; Get pointer to ProductInfo record <SM11>
cmp.b #DecoderKinds.OrwellDecoder,DecoderKind(a0) ; Do we have an orwell?
bne.s @EnhLtalk ; IF we have an Orwell THEN
bset #gestaltHasOrwell,d0 ; set the corresponding Gestalt bit
@EnhLtalk TestFor hasEnhancedLTalk ; Do we have CURIO LocalTalk enhancements?
beq.b @checkMACE ; no, check next feature
bset #gestaltHasEnhancedLtalk,d0 ; ThatÕs a big 10-4.
@checkMACE TestFor MACEExists ; do we have MACE Ethernet Controller?
beq.s @hardwareExit ; no, exit
bset #gestaltHasMace,d0
* bra.s @hardwareExit
@hardwareExit
bra stdResult ; return the result in d0
WITH DecoderInfo
AttrTable dc.b gestaltHasVIA1,VIA1Exists
dc.b gestaltHasSCC,SCCRdExists
dc.b gestaltHasIWM,IWMExists
dc.b gestaltHasPWM,PWMExists
dc.b gestaltHasSoundBuffer,SoundExists
dc.b gestaltHasSCSI,SCSIExists
dc.b gestaltHasVIA2,VIA2Exists
dc.b gestaltHasASC,ASCExists
dc.b gestaltHasRBV,RBVExists
dc.b gestaltHasVDAC,VDACExists
dc.b gestaltHasSCSIDMA,SCSIDMAExists
dc.b gestaltHasSWIMIOP,SWIMIOPExists
dc.b gestaltHasSCCIOP,SCCIOPExists
dc.b gestaltHasOSS,OSSExists
dc.b gestaltHasFMC,FMCExists
dc.b gestaltHasRPU,RPUExists
dc.b gestaltHasJaws,JAWSExists ;<2>
dc.b gestaltHasSonic,SonicExists ;<2>
dc.b gestaltHasSCSI961,SCSI96_1Exists ;<2>
dc.b gestaltHasSCSI962,SCSI96_2Exists ;<2>
dc.b gestaltHasDAFB,DAFBExists ;<2>
dc.b -1,-1
ENDWITH
************************************************************************ <SM30>
* Universal ROM check
************************************************************************
IsROMUniversal
IF NOT forROM THEN
move.l A1,-(SP) ; Save A1
move.l ROMBase,A0 ; Get ROMBase
lea universalROMs,A1 ; Point to the table of Clean/Univeral ROM Sigs
@UnivLupe move.w (A1)+,D1 ; Get a ROM id (list is null terminated)
beq.s @done ; -> End of table means not universal (huh)
cmp.w D1,ROMHeader.MachineNumber(A0) ; Check a table entry
bne.s @UnivLupe ; -> Nope, keep looping
ELSE
moveq #1,D1 ; Yes, set D0
@Done movem.l (SP)+,A1 ; Restore A1
rts
ENDIF
************************************************************************
************************************************************************
* AppleTalk Interrupt Disable Level
* - for new machines to supply AppleTalk with the appropriate
* interrupt mask, so AppleTalk doesn't default to disabling Level 4
* and below interrupts ($2400).
* - initially needed for Cyclone/Tempest
*
************************************************************************
GetAtlkIntLevel
TestFor MACEExists ; Do we have a MACE Ethernet Controller?
Beq stdUnknown ; no, give an error
TestFor PSCExists ; Do we have a PSC DMA/Interrupt Controller?
Beq stdUnknown ; no, give an error
Move.l #$2,d0 ; return interrupt mask level 2
Bra stdResult ; and exit
************************************************************************
* machine-specific selectors
************************************************************************
IF ( ForRom) THEN ; <2.9>
getMachSpecific lea Selectors,a0 ; get address of selector table
clr.l d1 ; use d1 as second index
@selectLoop move.l (a0,d1.l),d0 ; selector to check against
cmp.l selector(sp),d0 ; is it for this selector?
beq.s @foundIt ; yep
tst.l d0 ; is it the end?
beq stdUnknown ; oh,oh.. <2.9>
addq.l #4,d1 ; bump up index
bra.s @selectLoop ; selector loop
@foundIt Move.l ExpandMem,A0 ; find out where expandMem is
Move.l emGestalt(A0),A0 ; get global ptr
Move.w machType(A0),D0 ; get machineType
cmp.w InfoMax,d0 ; greater than max?
bls.s @inTable ; nope, it's in the table <3.3>
cmp.w #gestaltMacClassic,d0 ; is it an XO? <3.3>
bne.s @nextSpecial ; no, maybe an Asahi <2.9><6>
lea MacXO,a0 ; an XO is a special case <17>
bra.s @skipIndex ; because it's boxflag is so high <17>
@nextSpecial cmp.w #gestaltPowerBook100,d0 ; is it an Asahi? <6><40>
bne stdUnknown ; whoops <6>
lea MacAsahi,a0 ; an Asahi is also a special case <6>
bra.s @skipIndex ; because it's boxflag is so high <6>
@inTable subq.l #1,d0 ; machines start at 1, table at 0
lsl.w #2,d0 ; we're indexing into longs
mulu.w SelectorMax,d0 ; times number of longs per machine
lea InfoTable,a0 ; get base of table
adda.w d0,a0 ; point at info for this machine
@skipIndex move.l (a0,d1.l),d0 ; get result <17>
cmp.l #-1,d0 ; a -1 means unknown <2.9>
beq stdUnknown ; return an error <2.9>
bra stdResult ; save it and exit <2.9>
;------
; selectors in table
;------
SelectorMax dc.w (SelEnd-Selectors)/4
Selectors
dc.l gestaltHardwareAttr ; hardware attributes <10>
dc.l gestaltNuBusConnectors ; bitmap of NuBus connectors <23>
SelEnd dc.l 0 ; EOT
SelectorCount EQU (SelEnd-Selectors)/4 ; number of selectors
;------
; table by machine
;
; NOTE: An entry of -1 will cause a gestaltUnknownErr to be returned.
;------
InfoMax dc.w ((InfoEnd-InfoTable)/4)/(SelectorCount) ; max number of machines
InfoTable ; <10>
Old128 dc.l \ ; gestaltHardwareAttr
(1<<gestaltHasVIA1)|\ ; has a via 1
(1<<gestaltHasSCC)|\ ; has an scc
(1<<gestaltHasPWM)|\ ; has a PWM buffer <2.9>
(1<<gestaltHasSoundBuffer)|\ ; has a sound buffer in RAM <2.9>
(1<<gestaltNeedsRESET) ; needs a hard RESET <33>
dc.l 0 ; gestaltNuBusConnectors (no slots) <23>
MacXL dc.l \ ; gestaltHardwareAttr
(1<<gestaltHasVIA1)|\ ; has a via 1
(1<<gestaltHasSCC)|\ ; has an scc
(1<<gestaltNeedsRESET) ; needs a hard RESET <33>
dc.l 0 ; gestaltNuBusConnectors (no slots) <23>
Ke512 dc.l \ ; gestaltHardwareAttr
(1<<gestaltHasVIA1)|\ ; has a via 1
(1<<gestaltHasSCC)|\ ; has an scc
(1<<gestaltNeedsRESET) ; needs a hard RESET <33>
dc.l 0 ; gestaltNuBusConnectors (no slots) <23>
MacPlus dc.l \ ; gestaltHardwareAttr
(1<<gestaltHasVIA1)|\ ; has a via 1
(1<<gestaltHasSCC)|\ ; has an scc
(1<<gestaltHasIWM)|\ ; has an IWM chip <2.9>
(1<<gestaltHasPWM)|\ ; has a PWM buffer <2.9>
(1<<gestaltHasSoundBuffer)|\ ; has a sound buffer in RAM <2.9>
(1<<gestaltHasSCSI)|\ ; has SCSI <2.9>
(1<<gestaltNeedsRESET) ; needs a hard RESET <33>
dc.l 0 ; gestaltNuBusConnectors (no slots) <23>
MacSE dc.l \ ; gestaltHardwareAttr
(1<<gestaltHasVIA1)|\ ; has a via 1
(1<<gestaltHasSCC)|\ ; has an scc
(1<<gestaltHasIWM)|\ ; has an IWM chip <2.9>
(1<<gestaltHasPWM)|\ ; has a PWM buffer <2.9>
(1<<gestaltHasSoundBuffer)|\ ; has a sound buffer in RAM <2.9>
(1<<gestaltHasSCSI)|\ ; has SCSI <2.9>
(1<<gestaltNeedsRESET) ; needs a hard RESET <33>
dc.l 0 ; gestaltNuBusConnectors (no slots) <23>
MacII dc.l \ ; gestaltHardwareAttr
(1<<gestaltHasVIA1)|\ ; has a via 1
(1<<gestaltHasVIA2)|\ ; has a via 2
(1<<gestaltHasASC)|\ ; has an asc
(1<<gestaltHasSCC)|\ ; has an scc
(1<<gestaltHasIWM)|\ ; has an IWM chip <2.9>
(1<<gestaltHasSCSI) ; has SCSI <2.9>
dc.l $00007E00 ; gestaltNuBusConnectors (9-E) <23>
MacIIx dc.l \ ; gestaltHardwareAttr
(1<<gestaltHasVIA1)|\ ; has a via 1
(1<<gestaltHasVIA2)|\ ; has a via 2
(1<<gestaltHasASC)|\ ; has an asc
(1<<gestaltHasSCC)|\ ; has an scc
(1<<gestaltHasIWM)|\ ; has an IWM chip <2.9>
(1<<gestaltHasSCSI) ; has SCSI <2.9>
dc.l $00007E00 ; gestaltNuBusConnectors (9-E) <23>
MacIIcx dc.l \ ; gestaltHardwareAttr
(1<<gestaltHasVIA1)|\ ; has a via 1
(1<<gestaltHasVIA2)|\ ; has a via 2
(1<<gestaltHasASC)|\ ; has an asc
(1<<gestaltHasSCC)|\ ; has an scc
(1<<gestaltHasIWM)|\ ; has an IWM chip <2.9>
(1<<gestaltHasSCSI) ; has SCSI <2.9>
dc.l $00000E00 ; gestaltNuBusConnectors (9-B) <23>
MacSE30 dc.l \ ; gestaltHardwareAttr
(1<<gestaltHasVIA1)|\ ; has a via 1
(1<<gestaltHasVIA2)|\ ; has a via 2
(1<<gestaltHasASC)|\ ; has an asc
(1<<gestaltHasSCC)|\ ; has an scc
(1<<gestaltHasIWM)|\ ; has an IWM chip <2.9>
(1<<gestaltHasSCSI) ; has SCSI <2.9>
dc.l 0 ; gestaltNuBusConnectors (no slots) <23>
Portable dc.l \ ; gestaltHardwareAttr
(1<<gestaltHasVIA1)|\ ; has a via 1
(1<<gestaltHasASC)|\ ; has an asc
(1<<gestaltHasSCC)|\ ; has an scc
(1<<gestaltHasIWM)|\ ; has an IWM chip <2.9>
(1<<gestaltHasSCSI) ; has SCSI <2.9>
dc.l 0 ; gestaltNuBusConnectors (no slots) <23>
InfoEnd
MacXO dc.l \ ; gestaltHardwareAttr <17>
(1<<gestaltHasVIA1)|\ ; has a via 1
(1<<gestaltHasSCC)|\ ; has an scc
(1<<gestaltHasIWM)|\ ; has an IWM chip
(1<<gestaltHasPWM)|\ ; has a PWM buffer
(1<<gestaltHasSoundBuffer)|\ ; has a sound buffer in RAM
(1<<gestaltHasSCSI)|\ ; has SCSI
(1<<gestaltNeedsRESET) ; needs a hard RESET <33>
dc.l 0 ; gestaltNuBusConnectors (no slots) <23>
MacAsahi dc.l \ ; gestaltHardwareAttr <6>
(1<<gestaltHasVIA1)|\ ; has a via 1 <6>
(1<<gestaltHasASC)|\ ; has an asc <6>
(1<<gestaltHasSCC)|\ ; has an scc <6>
(1<<gestaltHasIWM)|\ ; has an IWM chip <6>
(1<<gestaltHasSCSI) ; has SCSI <6>
dc.l 0 ; gestaltNuBusConnectors (no slots) <6>
ENDIF ; <2.9>
************************************************************************
* Internal
************************************************************************
Internal move.l selector(sp),d0 ; get selector into d0
cmp.l #gestaltVersion,d0 ; return gestalt version
beq.s @version
cmp.l #gestaltLongHandle,d0 ; return table handle
beq.s @tableHdl
cmp.l #13,d0
beq.s @bbm
cmp.l #7,d0
bne.s stdUnknown ; undefined code
move.l #'carl',d0 ; signature
bra.s stdResult ; <3.0>
@bbm move.l #'bbmc',d0 ; signature
bra.s stdResult ; <3.0>
@version move.l #gestaltVers,d0 ; return version number
bra.s stdResult ; <3.0>
@tableHdl move.l ExpandMem,a0 ; get expandmem ptr
move.l emGestalt(a0),a1 ; get gestalt global ptr
move.l TableH(a1),d0 ; get table handle
bra.s stdResult ; save result and exit
************************************************************************
* Common Gestalt Function Return Code <2.9>
************************************************************************
stdUnknown move.w #gestaltUnknownErr,error(sp) ; return gestaltUnknownErr
bra.s stdExit
stdResult move.l resultPtr(sp),a0 ; get ptr to place result
move.l d0,(a0) ; return value in d0
noError move.w #noErr,error(sp) ; return noErr
stdExit move.l (sp)+,a0 ; get return address off stack
addq.l #8,sp ; clean up stack
jmp (a0) ; return
ENDWITH
; ***************************************************************************
; ***************************************************************************
; *** END OF GESTALT FUNCTIONS
; ***************************************************************************
; ***************************************************************************
IF (NOT ForRom) THEN
; **************************** EntryTable Macro ****************************
Macro
EntryTable &entryPt, &trapID
If (&entryPt <> '0') Then
Import Start
DC.L &entryPt-Start
DC.W &trapID
Else
DC.L 0
EndIf
EndM
; ***************************************************************************
; *** CUT-BACK POINT
; ***************************************************************************
CutBackPt EntryTable GESTALTTRAP,GestaltTrapID
EntryTable 0 ; <=== Last table entry
; ***************************************************************************
; *** INITIALIZATION CODE FOR PATCH
; ***************************************************************************
EXPORT BootInit
BootInit
BSR INITGESTALT ; Initialize Gestalt
Lea CutBackPt,A0 ; <=== Keep these two linesÉ
Rts ; <=== in any case
ENDIF ; if (NOT ForROM)
;---------------------------------------------------------
; Gestalt initialization routine
;
; Initializes Gestalt. Allocates space for globals and for proc ptr
; table in system heap. Also initializes proc ptrs for built-in
; functions.
;---------------------------------------------------------
MACRO
Selector &code, &addr
dc.l &code ; gestalt selector
dc.l &addr-SelectorTable ; offset of routine
ENDM
INITGESTALT
WITH GestaltGlobals,ExpandMemRec
move.l #GestaltRecSize,d0 ; size of globals
_NewPtr Sys,Clear ; get some space
move.l a0,d0 ; did we get the space?
beq memError ; whoops...
move.l ExpandMem,a1 ; get ptr to expandmem area
move.l a0,emGestalt(a1) ; save our global ptr
move.l a0,a2 ; keep it in a2
moveq #LongEntrySz,d0 ; size of long entry
_NewHandle Sys ; get block for proc ptr table
move.l a0,TableH(a2) ; did we get it?
beq memError ; whoops..
move.l (a0),a1 ; dereference the handle
move.l #HighestProc,(a1) ; the highest function code
move.l #$12345678,4(a1) ; a neat number for debugging
move.l #1,slotsUsed(a2) ; there's one entry in the table
;------
; Add predefined selectors
;------
lea SelectorTable,a3 ; get address of selector table
moveq #0,d3 ; clear counter
addLoop tst.l (a3,d3) ; end of table?
beq.s initGlobals ; yup, see ya..
move.l 4(a3,d3),d0 ; get offset of routine
add.l a3,d0 ; convert to an address
move.l d0,-(sp) ; push address of gestalt function
move.l (a3,d3),-(sp) ; push selector of gestalt function
move.l #addFlag,-(sp) ; specify that we are _adding_ a code
jsr newGestalt ; add it.
lea 12(sp),sp ; get rid of stack parameters
addq.l #8,d3 ; bump to next entry in table
bra.s addLoop ; do it again...
;------
; Put Gestalt into the trap table
; We assume that no interrupt routines will call Gestalt to get any of
;------
;------
; Initialize gestalt global values
;------
initGlobals bsr.s TestForEmu ; Test for a 68k emulator. Update globals if so. <SM30>
bne.s @MachineType ; -> (hasEmu) Everything is setup. <SM30>
move.l MemTop,D2 ; Get the current Logical RAM size <5>
bsr.s GetEDiskSize ; Get the EDisk size in bytes in D0 <5>
add.l D0,D2 ; add it to the LRAM size. <5>
@SaveLRAM move.l D2,realTop(a2) ; Save Logical RAM size <2.9>
IF NOT forROM THEN
bsr.s IsROMUniversal ; Is this a 32 bit clean ROM? <SM29>
beq.s @not32bitClean ; -> Nope. Use Memtop for Log & Phys <1>
ENDIF
move.l RealMemTop,D2 ; On IIci ROM get Logical from RealMem <11>
add.l D0,D2 ; Add in size of RAM disk to logical <11>
move.l D2,realTop(a2) ; Save the adjusted Logical size <11>
move.l PhysMemTop,memSize(A2) ; Get Physical RAM size <1>
bra.s @CheckForVM ; -> See if we need to redo these #s <1>
@not32bitClean move.l MemTop,memSize(a2) ; save Physical memory size
@CheckForVM move.l VMGlobals,D0 ; Get the Ptr to VM's globals <6>
bmi.s @MachineType ; -> No VM <6>
move.l D0,A1 ; Get VM globals Ptr <6>
IF NOT forROM THEN
bsr.s IsROMUniversal ; Is this a 32 bit clean ROM? <SM29>
bne.s @GetLogical ; -> Yes The Phys size is already correct <6>
moveq #-5,D0 ; GetPhysicalBytes
_MemoryDispatch ; Ask VM how much Physical RAM is in the machine
move.l D0,memSize(A2) ; Store the result
ENDIF
@GetLogical moveq #-6,D0 ; GetLogicalSize
_MemoryDispatch ; Ask VM how much logical RAM we have
move.l D0,D2 ; Save the reuslt in D2
bsr.s GetEDiskSize ; Get the EDisk size in bytes in D0 <6>
add.l D2,D0 ; Add in the size of the EDisk (if any) <6>
move.l D0,realTop(A2) ; Save Logical size in Gestalt's GLobs <6>
@MachineType jsr findMachType ; what kind of machine is this?
move.w d0,machType(a2) ; save it, since it won't change
jsr findFPUType ; what kind of FPU do we have?
move.b d0,fpu(a2)
jsr findMMUType ; what kind of MMU do we have?
move.b d0,mmu(a2)
jsr findParityStatus ; do we have parity, and is it on?
move.l d0,parityStatus(a2)
bra done
;---------------------------------------------------
; GetEDiskSize
; uses the value stored in BootGlobs record
; at bgRamDiskSize
;
; Exit:
; D0 - Size in bytes
;---------------------------------------------------
WITH StartGlobals ; <SM11> RLM <SM13> CSS
GetEDiskSize move.l BootGlobPtr,a0 ; get ptr to boot globals at top of RAM <SM11> RLM
move.l sgRamDiskSize(a0), D0 ; size of ram disk, if any <SM11> RLM
rts ; <SM11> RLM
ENDWITH ; (BootGlobs) <SM11> RLM
;__________________________________________________________________________________________ <SM30> SAM
; TestForEmu
;
; Tests for the existence of a 68k emulator. Implies a PowerPC architecture. Get the
; CPU id from the 60x processor and save it in Gestalt's globals. Update Gestalt's
; logical and physical RAM size globals if Emu is running.
;
; Entry:
; A2 - Ptr to Gestalt's Globals
; Exit:
; D0 - Clear if no Emulator. Nothing else touched.
; Set if emulator installed, GestaltGlobals.realTop/memSize/pageSize updated
;ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
With NKSystemInfo, ProcessorInfo
TestForEmu MOVE.L Line1111,-(SP) ; Save the F-Line vector
PEA @Continue ; Push the addr of our routine
MOVE.L (SP)+,Line1111 ; Update the vector
MOVE.L SP,D1 ; Save the Stack Ptr case we take an F-Line
MOVEQ #0,D0 ; Clear the "has and emulator" flag
NOP ; Sync the pipeline
_RiscCoprocessorNop ; Either do nothing, or skip the next instructon
MOVEQ #1,D0 ; Set the "has a 68k emulator" flag
@Continue MOVE.L D1,SP ; Restore the SP (trash the exception frame if we made one)
MOVE.L (SP)+,Line1111 ; Restore the Vector
NOP ; See above
MOVE.B D0,emu68k(A2) ; Save the Result in Gestalt's globals
BEQ.S @Done ; -> No, emu. No data page.
MOVE.L ProcessorInfoPtr,A3 ; Point to the NanoKernel's Processor Info record
MOVE.L PageSize(A3),nativePageSize(A2) ; Save the native page size in Gestalt's globals
MOVE.W ProcessorVersionReg(A3),D1 ; Get the PowerPC CPU version
MOVE.B D1,nativeCPU(A2) ; Save the native CPU type
MOVE.L NKSystemInfoPtr,A3 ; Point to the NanoKernel's System Info record
MOVE.L PhysicalMemorySize(A3),D3 ; Get the Physical Memory Size
MOVE.L D3,memSize(A2) ; Save it in Gestalt's globals
TST.L VMGlobals ; Is VM on?
BMI.S @noVM ; -> Nope
MOVEQ #-6,D0 ; GetLogicalSize
_MemoryDispatch ; Ask VM how much logical RAM we have
SUB.L UsableMemorySize(A3),D3 ; Calc ram allocated by the NanoKernel
ADD.L D0,D3 ; Add that to VM's logical size.
@noVM MOVE.L D3,realTop(A2) ; Save the Logical RAM size
@Done RTS
EndWith
IMPORT GESTALTSCRIPTMGR ; <SM8> rb
IMPORT GetSoundAttributes ; found in SndLowLevel.a
;-----
; Table of built-in Gestalt selectors
;
; Selector Routine Description
; -------- ------- -----------
;-----
SelectorTable Selector gestaltMachineType, getMachineType ; machine type
Selector gestaltSystemVersion, getSysVersion ; system version
Selector gestaltProcessorType, getProcessor ; processor type
Selector gestaltKeyboardType, getKeyboard ; keyboard type
Selector gestaltAppleTalkVersion, getATalkVersion ; atalk driver
Selector gestaltFPUType, getFPUType ; fpu type
Selector gestaltMMUType, getMMUType ; mmu type
Selector gestaltPhysicalRAMSize, getRAMSize ; physical ram size
Selector gestaltLogicalRAMSize, getRAMSize ; virtual ram size
Selector gestaltQuickdrawVersion, qdVersion ; qd version
Selector gestaltROMSize, getROMSize ; ROM size
Selector gestaltVMAttr, VMInfo ; return VM Info
Selector gestaltPowerMgrAttr, PowerMgr ; power mgr attrs
Selector gestaltROMVersion, getRomVersion ; get ROM version
Selector gestaltVersion, Internal ; version of gestalt
Selector gestaltLongHandle, Internal ; handle to table of longs
Selector gestaltHardwareAttr, getHardwareAttr ; hardware attributes
Selector gestaltNuBusConnectors, getSlotInfo ; NuBus connector bitmap <23>
Selector gestaltTimeMgrVersion, getTimeMgrType ; time mgr version
Selector gestaltAddressingModeAttr, getAddrMode ; addressing mode
Selector gestaltAUXVersion, getAuxVersion ; a/ux version
Selector gestaltLogicalPageSize, getPageSize ; logical page size
Selector gestaltLowMemorySize, getLowMemSize ; low-mem size
Selector gestaltParityAttr, getParityStatus ; parity attributes
Selector gestaltMiscAttr, getMisc ; misc attributes
Selector gestaltNotificationMgrAttr, notification ; nmgr attributes
Selector gestaltSerialAttr, getSerialAttr ; serial attributes
Selector gestaltSerialHALType, getSerialHALType ; serial HAL resource ID
IF ForRom THEN ; <PN> <SM2>
Selector gestaltOSTable, getOSTable ; base of the OS trap table <PN> <SM2>
Selector gestaltToolboxTable, getToolboxTable ; base of the toolbox trap table <PN> <SM2>
Selector gestaltExtToolboxTable, getExtToolboxTable ; base of the ext. toolbox trap table <PN> <SM2>
Selector gestaltFSAttr, getFSAttr ; return file system attributes <PN> <SM2>
Selector gestaltQuickdrawFeatures, getQuickdrawFeatures ; return ColorQuickdrawfeatures <PN> <SM2>
IF hasSplineFonts THEN
Selector gestaltFontMgrAttr, getFontMgrAttr ; return true if outline fonts <PN> <SM2>
ENDIF
Selector gestaltScriptMgrVersion, GESTALTSCRIPTMGR ; Script Manager version number <SM8> rb
Selector gestaltScriptCount, GESTALTSCRIPTMGR ; Script Manger count of scripts <SM8> rb
Selector gestaltSoundAttr, GetSoundAttributes ; get the sound attributes
Selector gestaltSoundHardware, GetSoundHardware ; get the sound harwdware chip type <SM9> rb
Selector gestaltAtlkIntLevel, GetAtlkIntLevel ; get cpu's desired appletalk interrupt mask level
ENDIF ; <22>
Selector gestaltSysArchitecture, getSysArchitecture ; System Architecture <SM24>
Selector gestaltNativeCPUtype, getNativeCPUtype ; Native Processor Type <SM24>
Selector 13, Internal ; special
Selector 7, Internal ; special
Selector 0, 0 ; EOT
done move.w #noErr,D0 ; return noErr
initExit rts
memError move.w #memFullErr,d0 ; tell caller what went wrong
bra.s initExit
;---------------------------------------------------------
; findMachType
;
; Determines machine type.
;
; Entry: nothing
;
; Exit: d0.l = machine type
;
; Trashes d0,a0
;---------------------------------------------------------
findMachType
move.l RomBase,a0 ; get ptr to base of ROM
move.b 8(a0),d0 ; get ROM's 'machine ID'
bgt.s @noClass ; IF its a 'classic' (machine ID = 0)
move.l #gestaltMac512KE,d0 ; assume its a 512ke
tst.w HwCfgFlags ; check if SCSI present (high bit 1?)
bpl.s @doneVers ; IF it has SCSI
move.l #gestaltMacPlus,d0 ; its a MacPlus
bra.s @doneVers ; ENDIF
@noClass ; ELSE
moveq #0,d0 ; clear a register
move.b BoxFlag,d0 ; get our RAM based machine ID
addq.b #6,d0 ; make it Gestalt based (must use '.b' so that $FF
; .becomes $000, not $100!)
@doneVers ; ENDIF
rts ; seeee ya...
;---------------------------------------------------------
; findFPUType
;
; Figures out what type of FPU is installed, if any
;
; Entry: nothing
;
; Exit: d0.l = fpu type
;
; Trashes d0,a0
;---------------------------------------------------------
findFPUType
IF (CPU >= 20) or (not ForRom) THEN ; <19>
Btst #hwCbFPU-8,HWCfgFlags ; check for FPU -- if bit set, we have FPU (-8 'cuz
; equates for HwCfgFlags are based on 16-bit word)
Beq.s @noFPU ; we have one, now figure out which one
cmp.b #cpu68040,CPUFlag ; are we on a 68040? <19>
bne.s @notAn040 ; IF we are on an 040 THEN <19>
move.l #gestalt68040FPU,d0 ; we know what kind of FPU it has <19>
bra.s @fpuExit ; ENDIF <19>
@notAn040 Move.l SP,A0 ; get base of (soon to be) FPU state frame
FNop ; synchronize FPU with us
FSave -(SP) ; get an "idle" state frame
Move.w (SP),D0 ; get format word for this state frame
Move.l A0,SP ; restore stack pointer
Cmp.w #$1f18,D0 ; an 881?
Beq.s @M68881
Cmp.w #$3f18,D0 ; this also indicates an 881
Beq.s @M68881
Cmp.w #$3f38,D0 ; how 'bout an 882?
Beq.s @M68882
Cmp.w #$1f38,D0 ; this is also an 882
Beq.s @M68882
move.l #0,d0 ; assume no FPU <3>
bra.s @fpuExit
@M68881 Move.l #gestalt68881,D0 ; we have an 881
Bra.s @fpuExit
@M68882 Move.l #gestalt68882,D0 ; we have an 882
Bra.s @fpuExit
ENDIF ;
@noFPU Move.l #gestaltNoFPU,D0 ; no FPU installed
@fpuExit rts ; return
;---------------------------------------------------------
; findMMUType
;
; Figures out what type of MMU is present, if any
;
; Entry: nothing
;
; Exit: d0.l = mmu type
;
; Trashes d0,a0
;---------------------------------------------------------
findMMUType
IF not ForRom THEN ;
Move.l ExpandMem,A0 ; find out where expandMem is
Move.l emGestalt(A0),A0 ; get global ptr
Cmp.w #gestaltMacSE,machType(A0) ; should we bother to find out?
Blo.s @noMMU ; nothing before SE can have one (yes)
ENDIF
IF hasMMU or (not ForRom) THEN ;
Moveq #0,D0 ; start clean
Move.b MMUType,D0 ; get MMU
cmp.b #HMMU,d0 ; is it an AMU?
beq.s @MMUDone ; then we're done
cmp.b #PMMU851,d0 ; then make sure there is one at all
Blo.s @noMMU ; no mmu
Subq #1,D0 ; convert to right format
Bra.s @MMUDone ; go return result
ENDIF ;
@noMMU Move.l #gestaltNoMMU,D0 ; tell the user we don't have one
@MMUDone rts ; exit
;---------------------------------------------------------
; findParityStatus
;
; Figures out if there is a parity chip on board, and
; if so, if there is parity RAM installed.
;
; Entry: nothing
;
; Exit: d0.l = parity status
;
; Trashes a0/a1/a3/a4/d0-d4
;---------------------------------------------------------
WITH DecoderInfo, ProductInfo
MACHINE MC68030
findParityStatus
IF (not ForRom) THEN ; <36> We only build universal ROMs now.
clr.l d0 ; clear result
movea.l ExpandMem,a0 ; get ptr to expandmem rec
movea.l emGestalt(a0),a0 ; get gestalt global ptr
cmpi.w #gestaltMacIIci,machType(a0) ; Mac IIci is first parity machine
blt @parityExit ; if before ci, definitely no parity
cmpi.w #gestaltMacClassic,machType(a0) ; XO's machine number screws everything up
beq @parityExit ; if on XO, definitely no parity
cmpi.w #gestaltPowerBook100,machType(a0) ; Asahi's machine number screws everything up <40>
beq @parityExit ; if on Asahi, definitely no parity
move.l UnivROMFlags,d1 ; get external feature bits
btst #PGCInstalled,d1 ; check if a parity chip exists
bne.s @checkPGC ; yep, go see if parity is enabled
move.l AddrMapFlags,d1 ; get universal info attributes
btst #RPUExists,d1 ; do we have an RPU chip?
bne.s @checkRPU ; then go check RPU
bra @parityExit ; if not, return zero as result
; checkPGC - check the parity VIA bit to see if it is enabled.
@checkPGC move.l VIA,a0 ; load up Via base address
btst #6,VBufB(a0) ; check if parity enabled
beq @parityOn ; if clear, parity is enabled
bra @parityOff ; otherwise, it's off
; checkRPU - First set RPU to generate bad parity, then access all four SIMMs in
; both banks by accessing location 0 and the last longword in memory.
; Parity is only fully active if all four SIMMs generate a parity interrupt.
; trashes a0/a1/a3/a4/d1-d4
@checkRPU movec cacr,d3 ; get contents of cache
move.l d3,-(sp) ; save them
move.l #$1111,d3 ; enable caches with bursting <13>
movec d3,cacr ; write into cache register <13>
move.l RomBase,a0 ; point to base of rom <13>
move.l #$2000,d3 ; cache size/long = 32k/4 = 8k <13>
@fillLoop tst.l (a0)+ ; load a long <13>
dbra d3,@fillLoop ; keep doing it for 8k <13>
move.l #$0808,d3 ; clear data and inst cache
movec d3,cacr ; write into cache register
move.l UnivInfoPtr,a0 ; get pointer to universal information
add.l (a0),a0 ; point to decoderInfo record
move.l RPUAddr(a0),a1 ; get RPU base address
move.l sp,d3 ; save our stack pointer
move.l AutoInt7,d4 ; save NMI vector
lea @parityInt,a4 ; address to return to from parity intrpt
lea @nmiHandler,a0 ; get address of our NMI handler
move #$2700,sr ; turn all interrupts off
move.l a0,AutoInt7 ; point vector to our handler
moveq #0,a3 ; check first bank (0 is in first bank)
@checkBank moveq #4-1,d2 ; check all four SIMMs
move.l (a3),d1 ; get contents of longword
@nextByte clr.l (a3) ; write a long with correct parity <14>
st.b rpuReset(a1) ; reset serial ptr
st.b (a1) ; write wrong parity mode
clr.b (a3,d2.w) ; write one SIMM with bad parity
st.b rpuReset(a1) ; sync up RPU serial line <SM4><SES>
clr.b (a1) ; write good parity mode <SM4><SES>
tst.l (a3) ; parity error if it's a parity SIMM
nop ; wait for an interrupt
nop
move.l d1,(a3) ; restore contents of longword
move #$2000,sr ; turn interrupts back on
move.l d4,AutoInt7 ; restore NMI vector
move.l (sp)+,d3 ; get original state of cache <8>
movec d3,cacr ; restore original state of cache <8>
bra.s @parityOff ; if we get here, it's a non-parity SIMM
@parityInt st.b rpuReset(a1) ; sync up RPU serial line
clr.b (a1) ; write good parity mode
dbra d2,@nextByte ; go check next SIMM
@allParityBank move.l d1,(a3) ; restore contents of longword
move.l a3,d1 ; did we just check location 0?
bne.s @restoreNMI ; if not, we're done and parity is on
movea.l ExpandMem,a0 ; get ptr to expandmem rec
movea.l emGestalt(a0),a0 ; get gestalt global ptr
movea.l memSize(a0),a3 ; total amount of memory
subq #4,a3 ; point to last longword in memory
bra.s @checkBank ; go check bank B
@restoreNMI move #$2000,sr ; turn interrupts back on
move.l d4,AutoInt7 ; restore NMI vector
move.l (sp)+,d3 ; get original state of cache <8>
movec d3,cacr ; restore original state of cache <8>
bra.s @parityOn ; go return that parity is on
; Interrupt handler for checkRPU routine. It is assumed that the NMI button is
; not pressed during this routine.
; d3 = stack pointer of routine
; a1 = RPU base address
; a4 = return address
@nmiHandler st.b rpuReset(a1) ; reset serial ptr
clr.b (a1) ; write good parity mode
st.b (a1) ; clear the parity error
move.l d3,sp ; restore the stack pointer
jmp (a4) ; return to the checkRPU routine
@parityOn bset #gestaltParityEnabled,d0 ; by here it is
@parityOff bset #gestaltHasParityCapability,d0 ; set parity capability bit
ELSE ; (not ForRom) OR isUniversal
@parityUnknown clr.l d0 ; set everything to zero
ENDIF
@parityExit rts
ENDWITH
END.