mirror of
https://github.com/elliotnunn/sys7.1-doc-wip.git
synced 2024-12-12 20:29:12 +00:00
1697 lines
66 KiB
Plaintext
1697 lines
66 KiB
Plaintext
;
|
||
; Hacks to match MacOS (most recent first):
|
||
;
|
||
; <Sys7.1> 8/3/92 Elliot make this change
|
||
; 9/2/94 SuperMario ROM source dump (header preserved below)
|
||
;
|
||
|
||
;
|
||
; 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):
|
||
;
|
||
; <SM5> 5/19/92 CS Integrated changes from Reality:
|
||
; <42> 4/9/92 JSM #1026795,<DTY>: gestaltSerialAttr should be the same for a Mac
|
||
; <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'
|
||
INCLUDE 'Devices.a'
|
||
|
||
PRINT ON
|
||
|
||
;;; 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 move.l 4(sp),a0
|
||
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 4(sp),a0
|
||
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>
|
||
|
||
|
||
************************************************************************
|
||
* 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
|
||
move.l ROMBase,A0 ; Get ROMBase
|
||
move.w ROMHeader.MachineNumber(A0),D1
|
||
lea bootGlobROMs,A0 ; Point to the table of bootGlobbed ROM Sigs
|
||
@cleanROMloop cmp.w (a0)+,d1
|
||
beq.s @hasBootGlobs
|
||
tst.w (a0)
|
||
bne.s @cleanROMloop
|
||
bra.s @noBootGlobs
|
||
@hasBootGlobs bset #gestaltBootGlobals,d3 ; we have boot globals
|
||
@noBootGlobs
|
||
|
||
move.w #UnimplementedTrap,d0
|
||
_GetTrapAddress ,newTool
|
||
move.l a0,d2
|
||
move.l #UserDelayTrap,d0
|
||
_GetTrapAddress ,newTool
|
||
cmp.l a0,d2
|
||
beq.s @noUserDelay
|
||
@userDelay bset #gestaltScrollingThrottle,d3
|
||
@noUserDelay
|
||
|
||
@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
|
||
|
||
; ROMs that have bootglobs
|
||
bootGlobROMs
|
||
dc.w $067C ; IIci ROM
|
||
dc.w 0 ; eot
|
||
|
||
|
||
************************************************************************
|
||
* 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?
|
||
blt @noPages ; oh well, no page size <2.9>
|
||
cmpi.b #PMMU851,MMUType ; do we have some kind of real mmu?
|
||
blt.s @normalSize ; nope, use default page size
|
||
Move.l ExpandMem,A0 ; find out where expandMem is
|
||
Move.l emGestalt(A0),A0 ; get global ptr
|
||
|
||
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!
|
||
|
||
@normalSize Move.l #DefaultPageSize,D0 ; use default pagesize
|
||
@saveResult bra stdResult ; save result and exit <2.9>
|
||
|
||
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>
|
||
|
||
************************************************************************
|
||
* 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>
|
||
************************************************************************
|
||
* 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 $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>
|
||
|
||
|
||
************************************************************************
|
||
* 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
|
||
|
||
************************************************************************
|
||
* 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
|
||
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
|
||
blt 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>
|
||
|
||
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>
|
||
move.l RomBase,a0
|
||
cmp.w #$67C,ROMHeader.MachineNumber(a0)
|
||
bne.s @noSoftPowerOff
|
||
move.l #gestaltHasUniversalROM,d1 ; Get the Gestalt bit for SoftpowerOff
|
||
bset d1,d0 ; Say we gots SoftPowerOff
|
||
@noSoftPowerOff
|
||
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 gestaltHasOrwell,OrwellExists
|
||
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
|
||
|
||
|
||
************************************************************************
|
||
* machine-specific selectors
|
||
************************************************************************
|
||
|
||
IF (1 OR 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 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>
|
||
|
||
move.l RomBase,A0 ; Check the ROM
|
||
cmp.w #$67C,8(A0) ; Is this a 32 bit clean (i.e. IIci) ROM?
|
||
bne.s @not32bitClean ; -> Nope. Use Memtop for Log & Phys
|
||
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>
|
||
beq.s @MachineType ; -> No VM <6>
|
||
bmi.s @MachineType ; -> No VM <6>
|
||
|
||
move.l D0,A1 ; Get VM globals Ptr <6>
|
||
|
||
IF NOT forROM THEN
|
||
move.l RomBase,A0 ; Check the ROM
|
||
cmp.w #$67C,8(A0) ; Is this a 32 bit clean (i.e. IIci) ROM?
|
||
beq.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
|
||
;
|
||
; Exit:
|
||
; D0 - Size in bytes
|
||
;---------------------------------------------------
|
||
GetEDiskSize
|
||
movem.l a1/a2/d2,-(sp)
|
||
move.l RomBase,a0
|
||
cmp.w #$37A,ROMHeader.MachineNumber(a0) ; Portable
|
||
beq.s @returnZero
|
||
|
||
lea DrvQHdr+QHead-QLink,a0
|
||
@dqloop move.l (a0),d0
|
||
beq.s @returnZero
|
||
move.l d0,a0
|
||
|
||
move.w dQDrive(a0),d1
|
||
move.w dQRefNum(a0),d0
|
||
move.w d0,d2
|
||
add.w #1,d0
|
||
neg.w d0
|
||
asl.w #2,d0
|
||
move.l UTableBase,a1
|
||
move.l (a1,d0),a1
|
||
move.l (a1),a1
|
||
btst #dRAMBased,dCtlFlags+1(a1)
|
||
beq.s @romBased
|
||
move.l (a1),a1
|
||
@romBased move.l (a1),a1
|
||
lea drvrName(a1),a1
|
||
lea @dotEDisk,a2
|
||
clr.l d0
|
||
move.b (a2),d0
|
||
@cmploop cmp.b (a2)+,(a1)+
|
||
bne.s @dqloop
|
||
dbra d0,@cmploop
|
||
|
||
lea -CntrlParam.size(sp),sp
|
||
move.l sp,a0
|
||
clr.l CntrlParam.ioCompletion(a0)
|
||
clr.w CntrlParam.ioVRefNum(a0)
|
||
move.w d2,CntrlParam.ioCRefNum(a0)
|
||
move.w d1,CntrlParam.ioVRefNum(a0)
|
||
move.w #drvSizeCode,CntrlParam.csCode(a0)
|
||
_Status ,immed
|
||
move.l CntrlParam.csParam(a0),d0
|
||
lea CntrlParam.size(sp),sp
|
||
bra.s @return
|
||
|
||
@returnZero clr.l d0
|
||
@return movem.l (sp)+,a1/a2/d2
|
||
rts
|
||
|
||
STRING AsIs
|
||
@dotEDisk dc.b 6, '.EDisk', 0
|
||
|
||
;-----
|
||
; 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 gestaltOSTable, getOSTable ; base of the OS trap table
|
||
Selector gestaltToolboxTable, getToolboxTable ; base of the toolbox trap table
|
||
Selector gestaltExtToolboxTable, getExtToolboxTable ; base of the ext. toolbox trap table
|
||
Selector gestaltFSAttr, getFSAttr ; return file system attributes
|
||
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?
|
||
Blt.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
|
||
Blt.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
|
||
|
||
tst.l (a3) ; parity error if it's a parity SIMM
|
||
nop ; wait for an interrupt
|
||
nop
|
||
|
||
st.b rpuReset(a1) ; sync up RPU serial line
|
||
clr.b (a1) ; write good parity mode
|
||
|
||
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.
|