mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-26 01:49:19 +00:00
455 lines
16 KiB
Plaintext
455 lines
16 KiB
Plaintext
;------------------------------------------------------------------------
|
||
;
|
||
; File: GestaltGlue.a
|
||
;
|
||
; Contains: Glue for Gestalt traps.
|
||
;
|
||
; Written by: Carl C. Hewitt
|
||
;
|
||
; Copyright: © 1990 by Apple Computer, Inc., all rights reserved.
|
||
;
|
||
; This file is used in these builds: ROM System
|
||
;
|
||
; Change History (most recent first):
|
||
;
|
||
; <8> 6/12/91 LN added #include 'SysPrivateEqu.a'
|
||
; <7> 1/14/91 SAM Updated ‘mach’ glue so that it works on Mac Plus and SEs.
|
||
; <6> 6/15/90 CCH Took out unconditional branch left over from testing.
|
||
; <5> 6/13/90 CCH Added glue for gestaltLogicalRAM and gestaltPhysicalRAM
|
||
; selectors.
|
||
; <4> 4/18/90 CCH The result code from _Gestalt is no longer trashed.
|
||
; <3> 4/11/90 CCH NewGestalt and ReplaceGestalt glue will now work correctly on
|
||
; machines that implement the Gestalt trap.
|
||
; <2> 3/9/90 CCH Added glue to allow support certain Gestalt calls if the trap is
|
||
; unimplemented. Currently, SysEnvirons equivalents are supported.
|
||
;
|
||
; To Do:
|
||
;
|
||
;------------------------------------------------------------------------
|
||
|
||
*************************************************************************
|
||
* Pascal Declarations:
|
||
*
|
||
* FUNCTION Gestalt(selector : OSType; VAR result : LONGINT) : OSErr;
|
||
* FUNCTION NewGestalt(selector : OSType; gestaltFunction : ProcPtr) : OSErr;
|
||
* FUNCTION ReplaceGestalt(selector : OSType; gestaltFunction : ProcPtr; VAR oldGestaltFunction : ProcPtr) : OSErr;
|
||
*
|
||
*************************************************************************
|
||
* C Prototypes:
|
||
*
|
||
* pascal OSErr Gestalt(OSType selector, long *result);
|
||
* pascal OSErr NewGestalt(OSType selector, ProcPtr gestaltFunction);
|
||
* pascal OSErr ReplaceGestalt(OSType selector, ProcPtr gestaltFunction, ProcPtr *oldGestaltFunction);
|
||
*
|
||
*************************************************************************
|
||
|
||
MC68881
|
||
INCLUDE 'Traps.a'
|
||
INCLUDE 'SysEqu.a'
|
||
INCLUDE 'SysPrivateEqu.a'
|
||
INCLUDE 'MMUEqu.a'
|
||
INCLUDE 'InternalOnlyEqu.a'
|
||
INCLUDE 'SysErr.a'
|
||
INCLUDE 'GestaltEqu.a'
|
||
INCLUDE 'GestaltPrivateEqu.a'
|
||
|
||
HWCfgFlags EQU $b22 ; (word) HW Configuration flags
|
||
hwCbFPU EQU 12 ; FPU chip present.
|
||
|
||
Unimplemented EQU $a89f ; unimplemented trap number
|
||
GestaltTrap EQU $a0ad ; gestalt trap number
|
||
|
||
;--------------------------------------------------------------------------------------
|
||
; Stack frame for Gestalt and NewGestalt calls
|
||
;--------------------------------------------------------------------------------------
|
||
|
||
gestaltParmFrame record {oldA6},decrement
|
||
result ds.w 1 ; OSErr
|
||
argSize equ *-8
|
||
selector ds.l 1 ; packed array [1..4] of char
|
||
responsePtr ds.l 1 ; addr of longint result for Gestalt
|
||
procPtr equ * ; addr of gestalt function for NewGestalt
|
||
return ds.l 1
|
||
oldA6 ds.l 1
|
||
localFrame equ *
|
||
endR
|
||
|
||
;--------------------------------------------------------------------------------------
|
||
; Stack frame for ReplaceGestalt calls
|
||
;--------------------------------------------------------------------------------------
|
||
|
||
replaceGestaltFrame record {oldA6},decrement
|
||
result ds.w 1 ; OSErr
|
||
argSize equ *-8
|
||
selector ds.l 1 ; packed array [1..4] of char
|
||
procPtr ds.l 1 ; address of new gestalt function
|
||
oldProcPtr ds.l 1 ; ptr to addr of old gestalt function
|
||
return ds.l 1
|
||
oldA6 ds.l 1
|
||
localFrame equ *
|
||
endR
|
||
|
||
;--------------------------------------------------------------------------------------
|
||
; NewGestalt Glue
|
||
;--------------------------------------------------------------------------------------
|
||
|
||
NewGestalt PROC EXPORT
|
||
|
||
with gestaltParmFrame
|
||
link a6,#localFrame
|
||
|
||
move.l #Unimplemented,d0 ; get unimplemented trap number
|
||
_GetTrapAddress newTool ; find out it's address
|
||
move.l a0,-(sp) ; save the unimplemented trap address
|
||
move.l #GestaltTrap,d0 ; get Gestalt's trap number
|
||
_GetTrapAddress newOS ; find out it's address
|
||
cmpa.l (sp)+,a0 ; are they the same?
|
||
|
||
beq.s @noGestalt ; IF gestalt exists THEN
|
||
move.l selector(a6),d0 ; put selector into d0
|
||
move.l procPtr(a6),a0 ; put proc ptr into a0
|
||
_NewGestalt ; call NewGestalt trap
|
||
move.w d0,result(a6) ; return the result to our caller
|
||
bra.s @newGestaltExit ; clean up and exit
|
||
@noGestalt ; ELSE
|
||
move.w #unimpErr,result(a6) ; return unimplemented core routine result
|
||
; ENDIF
|
||
@newGestaltExit ;
|
||
unlk a6 ; get rid of our local frame
|
||
move.l (sp)+,a0 ; get return value
|
||
add.l #argSize,sp ; restore stack pointer
|
||
jmp (a0) ; return
|
||
|
||
ENDP
|
||
|
||
|
||
;--------------------------------------------------------------------------------------
|
||
; ReplaceGestalt Glue
|
||
;--------------------------------------------------------------------------------------
|
||
|
||
ReplaceGestalt PROC EXPORT
|
||
|
||
with replaceGestaltFrame
|
||
link a6,#localFrame
|
||
|
||
move.l #Unimplemented,d0 ; get unimplemented trap number
|
||
_GetTrapAddress newTool ; find out it's address
|
||
move.l a0,-(sp) ; save the unimplemented trap address
|
||
move.l #GestaltTrap,d0 ; get Gestalt's trap number
|
||
_GetTrapAddress newOS ; find out it's address
|
||
cmpa.l (sp)+,a0 ; are they the same?
|
||
|
||
beq.s @noGestalt ; IF gestalt exists THEN
|
||
move.l selector(a6),d0 ; put selector into d0
|
||
move.l procPtr(a6),a0 ; put proc ptr into a0
|
||
_ReplaceGestalt ; call NewGestalt trap
|
||
move.w d0,result(a6) ; return the result to our caller
|
||
movea.l oldProcPtr(a6),a1 ; get address to place old proc ptr
|
||
move.l a0,(a1) ; return old proc ptr to our caller
|
||
bra.s @repGestaltExit ; clean up and exit
|
||
@noGestalt ; ELSE
|
||
move.w #unimpErr,result(a6) ; return unimplemented core routine result
|
||
; ENDIF
|
||
@repGestaltExit ;
|
||
unlk a6 ; get rid of our local frame
|
||
move.l (sp)+,a0 ; get return value
|
||
add.l #argSize,sp ; restore stack pointer
|
||
jmp (a0) ; return
|
||
|
||
ENDP
|
||
|
||
|
||
;--------------------------------------------------------------------------------------
|
||
; Gestalt Glue
|
||
;--------------------------------------------------------------------------------------
|
||
|
||
Gestalt PROC EXPORT
|
||
|
||
with gestaltParmFrame
|
||
link a6,#localFrame
|
||
|
||
move.l #Unimplemented,d0 ; get unimplemented trap number
|
||
_GetTrapAddress newTool ; find out it's address
|
||
move.l a0,-(sp) ; save the unimplemented trap address
|
||
move.l #GestaltTrap,d0 ; get Gestalt's trap number
|
||
_GetTrapAddress newOS ; find out it's address
|
||
cmpa.l (sp)+,a0 ; are they the same?
|
||
|
||
beq.s @fakeGestalt ; IF gestalt exists THEN
|
||
move.l selector(a6),d0 ; put selector into d0
|
||
_Gestalt ; call Gestalt trap
|
||
move.l responsePtr(a6),a1 ; get address of result <4>
|
||
move.l a0,(a1) ; put result into result area <4>
|
||
bra.s gestaltGlueExit ; ELSE <4>
|
||
@fakeGestalt lea selectorTable,a0 ; get address of supported selectors
|
||
move.w #gestaltUndefSelectorErr,d0 ; assume we won't find it
|
||
move.l selector(a6),d1 ; get selector in d1
|
||
@selectorLoop ; LOOP
|
||
cmp.l (a0)+,d1 ; found one we're looking for?
|
||
beq.s @foundIt ; >>EXITROUTINE if we did
|
||
tst.l (a0)+ ; at end of table?
|
||
beq.s gestaltGlueExit ; >>EXITROUTINE if so
|
||
bra.s @selectorLoop ; END
|
||
@foundIt
|
||
lea selectorTable,a1 ; get address of table
|
||
add.l (a0),a1 ; get address of requested routine
|
||
jmp (a1) ; go to it
|
||
|
||
gestaltGlueCommon
|
||
move.l responsePtr(a6),a1 ; get address of result
|
||
move.l d0,(a1) ; put result into result area
|
||
move.w #noErr,d0 ; return no error
|
||
gestaltGlueExit
|
||
move.w d0,result(a6) ; put the error result
|
||
unlk a6
|
||
move.l (sp)+,a0 ; get return value
|
||
add.l #argSize,sp ; restore stack pointer
|
||
jmp (a0) ; return
|
||
|
||
gestaltUnknown move.w #gestaltUnknownErr,d0 ; return unknown error
|
||
bra.s gestaltGlueExit
|
||
|
||
ENDWITH
|
||
|
||
selectorTable
|
||
dc.l gestaltVersion, getVersion-selectorTable
|
||
dc.l gestaltMachineType, getMachineType-selectorTable
|
||
dc.l gestaltSystemVersion, getSysVersion-selectorTable
|
||
dc.l gestaltProcessorType, getProcessor-selectorTable
|
||
dc.l gestaltFPUType, getFPUType-selectorTable
|
||
dc.l gestaltQuickdrawVersion, qdVersion-selectorTable
|
||
dc.l gestaltKeyboardType, getKeyboard-selectorTable
|
||
dc.l gestaltAppleTalkVersion, getATalkVersion-selectorTable
|
||
dc.l gestaltMMUType, getMMUType-selectorTable
|
||
dc.l gestaltPhysicalRAMSize, getRAMSize-selectorTable
|
||
dc.l gestaltLogicalRAMSize, getRAMSize-selectorTable
|
||
dc.l 0, 0
|
||
|
||
|
||
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
|
||
|
||
************************************************************************
|
||
* Version
|
||
************************************************************************
|
||
|
||
getVersion Moveq #1,d0 ; return current version
|
||
bra.s gestaltGlueCommon ; save result and exit <2.9>
|
||
|
||
|
||
************************************************************************
|
||
* Machine Type
|
||
************************************************************************
|
||
|
||
getMachineType move.l ROMBase,A1 ; Get base address of ROM <7>
|
||
moveq #gestaltMacPlus,D0 ; Assume MacPlus <7>
|
||
|
||
cmp.w #$0075,8(A1) ; Is this a Plus? <7>
|
||
beq.s @machineDone ; -> Yes, say so <7>
|
||
cmp.w #$0276,8(A1) ; Howa bout an SE? <7>
|
||
bne.s @useBoxFlag ; -> no, it's ok to use BoxFlag <7>
|
||
addq #1,D0 ; Bump result up to gestaltMacSE <7>
|
||
bra.s @machineDone ; -> exit. <7>
|
||
|
||
@useBoxFlag move.b BoxFlag,d0 ; put machineType in result
|
||
addq.l #6,d0 ; convert to Gestalt result
|
||
@machineDone bra.s gestaltGlueCommon ; save result and exit <2.9>
|
||
|
||
|
||
************************************************************************
|
||
* System Version
|
||
************************************************************************
|
||
|
||
getSysVersion clr.l d0 ; clear result register <2.9>
|
||
Move.w SysVersion,d0 ; save system version in lsw of result
|
||
bra gestaltGlueCommon ; 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 gestaltGlueCommon ; save result and exit <2.9>
|
||
|
||
|
||
************************************************************************
|
||
* FPU Type
|
||
************************************************************************
|
||
|
||
getFPUType cmp.b #cpu68040,CPUFlag ; are we on an 040?
|
||
beq.s @on040 ; if so, we know what kind we have
|
||
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
|
||
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
|
||
@on040 move.l #gestalt68040FPU,d0 ; we know what kind of FPU it has
|
||
bra.s @fpuExit
|
||
|
||
@noFPU Move.l #gestaltNoFPU,D0 ; no FPU installed
|
||
|
||
@fpuExit bra gestaltGlueCommon ; save result and exit
|
||
|
||
|
||
************************************************************************
|
||
* QD Version
|
||
************************************************************************
|
||
|
||
qdVersion
|
||
cmp.w #$3fff,Rom85 ; do we have color quickdraw?
|
||
bgt.s @noCQD ; nope..
|
||
Move.w #Unimplemented,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
|
||
|
||
@noCQD move.l #gestaltOriginalQD,d0 ; original qd, fall through
|
||
bra.s qdDone
|
||
|
||
@fullCQD Move.l #gestalt32BitQD,D0 ; we have 32-bit cqd..
|
||
|
||
qdDone bra gestaltGlueCommon ; 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 gestaltUnknown ; 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 gestaltGlueCommon ; 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 $00 ; EOT
|
||
|
||
|
||
************************************************************************
|
||
* 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 gestaltGlueCommon ; save result and exit <2.9>
|
||
|
||
|
||
************************************************************************
|
||
* MMU Type
|
||
************************************************************************
|
||
|
||
getMMUType Cmp.b #cpu68020,CPUFlag ; should we bother to find out?
|
||
Blt.s @noMMU ; nothing before Mac II can have one
|
||
Clr.l 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
|
||
|
||
@noMMU Move.l #gestaltNoMMU,D0 ; tell the user we don't have one
|
||
|
||
@MMUDone bra gestaltGlueCommon ; save result and exit
|
||
|
||
|
||
************************************************************************
|
||
* RAM Size
|
||
************************************************************************
|
||
OSDispatchTrap EQU $A88F ;MultiFinder trap
|
||
|
||
getRAMSize
|
||
move.w #Unimplemented,D0 ; get loc of unimplemented trap
|
||
_GetTrapAddress ,newTool ; get the address into A0
|
||
move.l A0,D2 ; save it for a sec
|
||
move.l #OSDispatchTrap,D0 ; trap ID to check for multifinder
|
||
_GetTrapAddress ,newTool ; get the address of it
|
||
move.l MemTop,d0 ; assume multifinder is not running
|
||
cmp.l A0,D2 ; is it unimplemented?
|
||
beq.s @ramDone ; if not, we're done
|
||
subq.l #4,sp ; make room for result
|
||
move.w #$0016,-(sp) ; selector for total physical memory
|
||
_OSDispatch ; get the value
|
||
move.l (sp)+,d0 ; get it into d0
|
||
|
||
@ramDone bra gestaltGlueCommon ; save result and exit
|
||
|
||
|
||
ENDWITH
|
||
|
||
|
||
ENDP
|
||
|
||
|
||
END
|