Mac OS 9
MixedMode.h File Reference

Mixed Mode Manager Interfaces. More...

#include <MacTypes.h>

Go to the source code of this file.

Data Structures

struct  RoutineRecord
 
struct  RoutineDescriptor
 
struct  MixedModeStateRecord
 

Macros

#define GetCurrentArchitecture()   0
 
#define BUILD_ROUTINE_DESCRIPTOR(procInfo, procedure)
 
#define BUILD_FAT_ROUTINE_DESCRIPTOR(m68kProcInfo, m68kProcPtr, powerPCProcInfo, powerPCProcPtr)
 
#define NewRoutineDescriptor(theProc, theProcInfo, theISA)    ((UniversalProcPtr)theProc)
 
#define DisposeRoutineDescriptor(theUPP)
 
#define SIZE_CODE(size)
 
#define RESULT_SIZE(sizeCode)   ((ProcInfoType)(sizeCode) << kResultSizePhase)
 
#define STACK_ROUTINE_PARAMETER(whichParam, sizeCode)
 
#define DISPATCHED_STACK_ROUTINE_PARAMETER(whichParam, sizeCode)
 
#define DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE(sizeCode)    ((ProcInfoType)(sizeCode) << kDispatchedSelectorSizePhase)
 
#define REGISTER_RESULT_LOCATION(whichReg)    ((ProcInfoType)(whichReg) << kRegisterResultLocationPhase)
 
#define REGISTER_ROUTINE_PARAMETER(whichParam, whichReg, sizeCode)
 
#define SPECIAL_CASE_PROCINFO(specialCaseCode)    (kSpecialCase | ((ProcInfoType)(specialCaseCode) << 4))
 
#define STACK_UPP_TYPE(name)   name
 
#define REGISTER_UPP_TYPE(name)   name
 
#define TVECTOR_UPP_TYPE(name)   name
 
#define CALL_ZERO_PARAMETER_UPP(upp, procInfo)   (*(upp))()
 
#define CALL_ONE_PARAMETER_UPP(upp, procInfo, p1)   (*(upp))((p1))
 
#define CALL_TWO_PARAMETER_UPP(upp, procInfo, p1, p2)   (*(upp))((p1), (p2))
 
#define CALL_THREE_PARAMETER_UPP(upp, procInfo, p1, p2, p3)    (*(upp))((p1), (p2), (p3))
 
#define CALL_FOUR_PARAMETER_UPP(upp, procInfo, p1, p2, p3, p4)    (*(upp))((p1), (p2), (p3), (p4))
 
#define CALL_FIVE_PARAMETER_UPP(upp, procInfo, p1, p2, p3, p4, p5)    (*(upp))((p1), (p2), (p3), (p4), (p5))
 
#define CALL_SIX_PARAMETER_UPP(upp, procInfo, p1, p2, p3, p4, p5, p6)    (*(upp))((p1), (p2), (p3), (p4), (p5), (p6))
 
#define CALL_SEVEN_PARAMETER_UPP(upp, procInfo, p1, p2, p3, p4, p5, p6, p7)    (*(upp))((p1), (p2), (p3), (p4), (p5), (p6), (p7))
 
#define CALL_EIGHT_PARAMETER_UPP(upp, procInfo, p1, p2, p3, p4, p5, p6, p7, p8)    (*(upp))((p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8))
 
#define CALL_NINE_PARAMETER_UPP(upp, procInfo, p1, p2, p3, p4, p5, p6, p7, p8, p9)    (*(upp))((p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8), (p9))
 
#define CALL_TEN_PARAMETER_UPP(upp, procInfo, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10)    (*(upp))((p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8), (p9), (p10))
 
#define CALL_ELEVEN_PARAMETER_UPP(upp, procInfo, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)    (*(upp))((p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8), (p9), (p10), (p11))
 
#define CALL_TWELVE_PARAMETER_UPP(upp, procInfo, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)
 
#define CALL_THIRTEEN_PARAMETER_UPP(upp, procInfo, p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13)
 

Typedefs

typedef unsigned short CallingConventionType
 
typedef SInt8 ISAType
 
typedef SInt8 RTAType
 
typedef unsigned short registerSelectorType
 
typedef unsigned long ProcInfoType
 
typedef unsigned short RoutineFlagsType
 
typedef struct RoutineRecord RoutineRecord
 
typedef RoutineRecordRoutineRecordPtr
 
typedef RoutineRecordPtrRoutineRecordHandle
 
typedef UInt8 RDFlagsType
 
typedef struct RoutineDescriptor RoutineDescriptor
 
typedef RoutineDescriptorRoutineDescriptorPtr
 
typedef RoutineDescriptorPtrRoutineDescriptorHandle
 
typedef struct MixedModeStateRecord MixedModeStateRecord
 

Enumerations

enum  { kRoutineDescriptorVersion = 7 }
 
enum  { _MixedModeMagic = 0xAAFE }
 
enum  { kCurrentMixedModeStateRecord = 1 }
 
enum  {
  kPascalStackBased = 0 , kCStackBased = 1 , kRegisterBased = 2 , kD0DispatchedPascalStackBased = 8 ,
  kD1DispatchedPascalStackBased = 12 , kD0DispatchedCStackBased = 9 , kStackDispatchedPascalStackBased = 14 , kThinkCStackBased = 5
}
 
enum  { kM68kISA = 0 , kPowerPCISA = 1 }
 
enum  { kOld68kRTA = 0 << 4 , kPowerPCRTA = 0 << 4 , kCFM68kRTA = 1 << 4 }
 
enum  {
  kRegisterD0 = 0 , kRegisterD1 = 1 , kRegisterD2 = 2 , kRegisterD3 = 3 ,
  kRegisterD4 = 8 , kRegisterD5 = 9 , kRegisterD6 = 10 , kRegisterD7 = 11 ,
  kRegisterA0 = 4 , kRegisterA1 = 5 , kRegisterA2 = 6 , kRegisterA3 = 7 ,
  kRegisterA4 = 12 , kRegisterA5 = 13 , kRegisterA6 = 14 , kCCRegisterCBit = 16 ,
  kCCRegisterVBit = 17 , kCCRegisterZBit = 18 , kCCRegisterNBit = 19 , kCCRegisterXBit = 20
}
 
enum  { kNoByteCode = 0 , kOneByteCode = 1 , kTwoByteCode = 2 , kFourByteCode = 3 }
 
enum  { kProcDescriptorIsAbsolute = 0x00 , kProcDescriptorIsRelative = 0x01 }
 
enum  { kFragmentIsPrepared = 0x00 , kFragmentNeedsPreparing = 0x02 }
 
enum  { kUseCurrentISA = 0x00 , kUseNativeISA = 0x04 }
 
enum  { kPassSelector = 0x00 , kDontPassSelector = 0x08 }
 
enum  { kRoutineIsNotDispatchedDefaultRoutine = 0x00 , kRoutineIsDispatchedDefaultRoutine = 0x10 }
 
enum  { kProcDescriptorIsProcPtr = 0x00 , kProcDescriptorIsIndex = 0x20 }
 
enum  { kSelectorsAreNotIndexable = 0x00 , kSelectorsAreIndexable = 0x01 }
 
enum  {
  kCallingConventionWidth = 4 , kCallingConventionPhase = 0 , kCallingConventionMask = 0x0F , kResultSizeWidth = 2 ,
  kResultSizePhase = kCallingConventionWidth , kResultSizeMask = 0x30 , kStackParameterWidth = 2 , kStackParameterPhase = (kCallingConventionWidth + kResultSizeWidth) ,
  kStackParameterMask , kRegisterResultLocationWidth = 5 , kRegisterResultLocationPhase , kRegisterParameterWidth = 5 ,
  kRegisterParameterPhase , kRegisterParameterMask = 0x7FFFF800 , kRegisterParameterSizePhase = 0 , kRegisterParameterSizeWidth = 2 ,
  kRegisterParameterWhichPhase = kRegisterParameterSizeWidth , kRegisterParameterWhichWidth , kDispatchedSelectorSizeWidth = 2 , kDispatchedSelectorSizePhase ,
  kDispatchedParameterPhase , kSpecialCaseSelectorWidth = 6 , kSpecialCaseSelectorPhase = kCallingConventionWidth , kSpecialCaseSelectorMask = 0x03F0
}
 
enum  { kSpecialCase = 0x000F }
 
enum  {
  kSpecialCaseHighHook = 0 , kSpecialCaseCaretHook = 0 , kSpecialCaseEOLHook = 1 , kSpecialCaseWidthHook = 2 ,
  kSpecialCaseTextWidthHook = 2 , kSpecialCaseNWidthHook = 3 , kSpecialCaseDrawHook = 4 , kSpecialCaseHitTestHook = 5 ,
  kSpecialCaseTEFindWord = 6 , kSpecialCaseProtocolHandler = 7 , kSpecialCaseSocketListener = 8 , kSpecialCaseTERecalc = 9 ,
  kSpecialCaseTEDoText = 10 , kSpecialCaseGNEFilterProc = 11 , kSpecialCaseMBarHook = 12
}
 

Functions

UniversalProcPtr NewRoutineDescriptor (ProcPtr theProc, ProcInfoType theProcInfo, ISAType theISA)
 
void DisposeRoutineDescriptor (UniversalProcPtr theUPP)
 
UniversalProcPtr NewFatRoutineDescriptor (ProcPtr theM68kProc, ProcPtr thePowerPCProc, ProcInfoType theProcInfo)
 
long CallUniversalProc (UniversalProcPtr theProcPtr, ProcInfoType procInfo,...)
 
long CallOSTrapUniversalProc (UniversalProcPtr theProcPtr, ProcInfoType procInfo,...)
 

Detailed Description

Mixed Mode Manager Interfaces.

Introduced In: Mac OS 8
Avaliable From: Universal Interfaces 3.4.1
Copyright: © 1992-2001 by Apple Computer, Inc., all rights reserved.

For bug reports, consult the following page on the World Wide Web:

http://developer.apple.com/bugreporter/

Macro Definition Documentation

◆ BUILD_FAT_ROUTINE_DESCRIPTOR

#define BUILD_FAT_ROUTINE_DESCRIPTOR (   m68kProcInfo,
  m68kProcPtr,
  powerPCProcInfo,
  powerPCProcPtr 
)

a macro which creates a static instance of a fat routine descriptor

◆ BUILD_ROUTINE_DESCRIPTOR

#define BUILD_ROUTINE_DESCRIPTOR (   procInfo,
  procedure 
)
Value:
{ \
_MixedModeMagic, \
kRoutineDescriptorVersion, \
kSelectorsAreNotIndexable, \
0, \
0, \
0, \
0, \
{ \
{ \
(procInfo), \
0, \
GetCurrentArchitecture(), \
kProcDescriptorIsAbsolute | \
kFragmentIsPrepared | \
kUseNativeISA, \
(ProcPtr)(procedure), \
0, \
0 \
} \
} \
}

Macros for building static Routine Descriptors (not available in Carbon) A macro which creates a static instance of a non-dispatched routine descriptor

◆ CALL_THIRTEEN_PARAMETER_UPP

#define CALL_THIRTEEN_PARAMETER_UPP (   upp,
  procInfo,
  p1,
  p2,
  p3,
  p4,
  p5,
  p6,
  p7,
  p8,
  p9,
  p10,
  p11,
  p12,
  p13 
)
Value:
(*(upp))((p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8), (p9), (p10), (p11), \
(p12), (p13))

◆ CALL_TWELVE_PARAMETER_UPP

#define CALL_TWELVE_PARAMETER_UPP (   upp,
  procInfo,
  p1,
  p2,
  p3,
  p4,
  p5,
  p6,
  p7,
  p8,
  p9,
  p10,
  p11,
  p12 
)
Value:
(*(upp))((p1), (p2), (p3), (p4), (p5), (p6), (p7), (p8), (p9), (p10), (p11), \
(p12))

◆ CALL_ZERO_PARAMETER_UPP

#define CALL_ZERO_PARAMETER_UPP (   upp,
  procInfo 
)    (*(upp))()

CALL_©_PARAMETER_UPP - used in Call©Proc macros

Example:

#define CallIOCompletionProc(userRoutine, paramBlock)   \
          CALL_TWO_PARAMETER_UPP((userRoutine), uppIOCompletionProcInfo,

(paramBlock))

◆ DISPATCHED_STACK_ROUTINE_PARAMETER

#define DISPATCHED_STACK_ROUTINE_PARAMETER (   whichParam,
  sizeCode 
)
Value:
((ProcInfoType)(sizeCode) \
<< (kDispatchedParameterPhase + (((whichParam)-1) * kStackParameterWidth)))
unsigned long ProcInfoType
Definition: MixedMode.h:151
@ kDispatchedParameterPhase
Definition: MixedMode.h:335
@ kStackParameterWidth
Definition: MixedMode.h:314

DISPATCHED_STACK_ROUTINE_PARAMETER - Return a parameter field of a ProcInfo, for a dispatched, stack based routine. The same macro is used regardless of the type of dispatching. whichParam - which parameter sizeCode

  • size code

◆ DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE

#define DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE (   sizeCode)     ((ProcInfoType)(sizeCode) << kDispatchedSelectorSizePhase)

DISPATCHED_STACK_ROUTINE_SELECTOR_SIZE - Return a the selector size field of a ProcInfo for a dispatched, stack based routine. The same macro is used regardless of the type of dispatching. sizeCode - size code

◆ REGISTER_RESULT_LOCATION

#define REGISTER_RESULT_LOCATION (   whichReg)     ((ProcInfoType)(whichReg) << kRegisterResultLocationPhase)

REGISTER_RESULT_LOCATION - Return the Result Location field of a ProcInfo, given the location. whichReg - which register

◆ REGISTER_ROUTINE_PARAMETER

#define REGISTER_ROUTINE_PARAMETER (   whichParam,
  whichReg,
  sizeCode 
)
Value:
((((ProcInfoType)(sizeCode) << kRegisterParameterSizePhase) | \
((ProcInfoType)(whichReg) << kRegisterParameterWhichPhase)) \
<< (kRegisterParameterPhase + \
(((whichParam)-1) * kRegisterParameterWidth)))
@ kRegisterParameterWidth
Definition: MixedMode.h:322

REGISTER_ROUTINE_PARAMETER - Return a parameter field of a ProcInfo for a register based routine.

◆ RESULT_SIZE

#define RESULT_SIZE (   sizeCode)    ((ProcInfoType)(sizeCode) << kResultSizePhase)

RESULT_SIZE - Return the result field of a ProcInfo, given the return object©s size. This is the same for all ProcInfos sizeCode - size code

◆ SIZE_CODE

#define SIZE_CODE (   size)
Value:
(((size) == 4) \
? kFourByteCode \
: (((size) == 2) ? kTwoByteCode : (((size) == 1) ? kOneByteCode : 0)))

CALL_NOT_IN_CARBON !TARGET_CPU_68K || TARGET_RT_MAC_CFM TARGET_CPU_68K


◆ SPECIAL_CASE_PROCINFO

#define SPECIAL_CASE_PROCINFO (   specialCaseCode)     (kSpecialCase | ((ProcInfoType)(specialCaseCode) << 4))

SPECIAL_CASE_PROCINFO - Returns the procInfo constant for the following special cases:

High Hook & Caret Hook -  (see I-379)
       C calling conventions, Rect on stack, pointer in A3, no return

value EOL Hook - (see VI-15-26) Register-based; inputs in D0, A3, A4; output is Z flag of status register Width Hook - (see VI-15-27) Register-based; inputs in D0, D1, A0, A3, A4; output in D1 NWidth Hook - (see VI-15-27) Register-based; inputs in D0, D1, D2, A0, A2, A3, A4; output in D1 TextWidthHook - (see VI-15-28) Register-based; inputs in D0, D1, A0, A3, A4; output in D1 DrawHook - (see VI-15-28) Register-based; inputs in D0, D1, A0, A3, A4; no output HitTestHook - (See VI-15-29) Register-based; inputs in D0, D1, D2, A0, A3, A4; outputs in D0, D1, D2 FindWord - (see VI-15-30) Register-based; inputs in D0, D2, A3, A4; outputs in D0, D1 ADBRoutines - (see V-371) Register-based; inputs in A0, A1, A2, D0; no outputs ProtocolHandler - (see II-326) Register-based; inputs in A0, A1, A2, A3, A4, D1.w; output in Z SocketListener - (see II-329) Register-based; inputs in A0, A1, A2, A3, A4, D0.b, D1.w; output in Z Reclac - (see I-391) Register-based; inputs in A3, D7; outputs in D2, D3, D4 DoText - (see I-391) Register-based; inputs in A3, D3, D4, D7; outputs in A0, D0 GNEFilterProc - (see tech note 85) Register & Stack Based; inputs in A1, D0 & on the stack; outputs on the stack MenuBarHook - (see I-356) Register & Stack Based; input on the stack; output in D0

◆ STACK_ROUTINE_PARAMETER

#define STACK_ROUTINE_PARAMETER (   whichParam,
  sizeCode 
)
Value:
((ProcInfoType)(sizeCode) \
<< (kStackParameterPhase + (((whichParam)-1) * kStackParameterWidth)))

STACK_ROUTINE_PARAMETER - Return a parameter field of a ProcInfo, for a simple, non-dispatched, stack based routine. whichParam - which parameter sizeCode - size code

◆ STACK_UPP_TYPE

#define STACK_UPP_TYPE (   name)    name

STACK_UPP_TYPE - used in typedefs to create ©UPP type REGISTER_UPP_TYPE - used in typedefs to create ©UPP type TVECTOR_UPP_TYPE - used in typedefs to create ©UPP type

Example:

typedef STACK_UPP_TYPE(ModalFilterProcPtr)      ModalFilterUPP;
typedef REGISTER_UPP_TYPE(IOCompletionProcPtr)  IOCompletionUPP;

other runtimes

Typedef Documentation

◆ CallingConventionType

typedef unsigned short CallingConventionType

Calling Conventions

◆ ISAType

typedef SInt8 ISAType

ISA Types

◆ ProcInfoType

typedef unsigned long ProcInfoType

Mixed Mode Routine Records

◆ RDFlagsType

typedef UInt8 RDFlagsType

Mixed Mode Routine Descriptors Definitions of the Routine Descriptor Flag Bits

◆ RoutineFlagsType

typedef unsigned short RoutineFlagsType

Routine Flag Bits

◆ RTAType

typedef SInt8 RTAType

RTA Types

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

Mixed Mode constants Current Routine Descriptor Version

◆ anonymous enum

anonymous enum

MixedModeMagic Magic Cookie/Trap number

◆ anonymous enum

anonymous enum

MixedModeState Version for CFM68K Mixed Mode

◆ anonymous enum

anonymous enum

Constants for specifing 68k registers

Enumerator
kCCRegisterCBit 

A7 is the same as the PowerPC SP

◆ anonymous enum

anonymous enum

SizeCodes we use everywhere

◆ anonymous enum

anonymous enum

CALL_NOT_IN_CARBON Mixed Mode ProcInfos

Enumerator
kCallingConventionWidth 

Calling Convention Offsets

kResultSizeWidth 

Result Offsets

kStackParameterWidth 

Parameter offsets & widths

kRegisterResultLocationWidth 

Register Result Location offsets & widths

kRegisterParameterWidth 

Register Parameter offsets & widths

kDispatchedSelectorSizeWidth 

Dispatched Stack Routine Selector offsets & widths

kDispatchedParameterPhase 

Dispatched Stack Routine Parameter offsets

kSpecialCaseSelectorWidth 

Special Case offsets & widths

◆ anonymous enum

anonymous enum
Enumerator
kSpecialCaseHighHook 

all of the special cases enumerated. The selector field is 6 bits wide

kSpecialCaseEOLHook 

same as kSpecialCaseHighHook

kSpecialCaseNWidthHook 

same as kSpecialCaseWidthHook

Function Documentation

◆ CallOSTrapUniversalProc()

long CallOSTrapUniversalProc ( UniversalProcPtr  theProcPtr,
ProcInfoType  procInfo,
  ... 
)

CallOSTrapUniversalProc()

Non-Carbon CFM: in InterfaceLib 7.1 and later
Carbon Lib: not available
Mac OS X: not available

◆ CallUniversalProc()

long CallUniversalProc ( UniversalProcPtr  theProcPtr,
ProcInfoType  procInfo,
  ... 
)

CALL_NOT_IN_CARBON TARGET_CPU_68K && !TARGET_RT_MAC_CFM CallUniversalProc is defined for all targets except classic 68k code. This will catch accidental calls from classic 68K code that previously only showed up as linker errors. CallUniversalProc()

Non-Carbon CFM: in InterfaceLib 7.1 and later
Carbon Lib: not available
Mac OS X: not available

◆ DisposeRoutineDescriptor()

void DisposeRoutineDescriptor ( UniversalProcPtr  theUPP)

DisposeRoutineDescriptor()

Non-Carbon CFM: in InterfaceLib 7.1 and later or as macro/inline
Carbon Lib: not available
Mac OS X: not available

◆ NewFatRoutineDescriptor()

UniversalProcPtr NewFatRoutineDescriptor ( ProcPtr  theM68kProc,
ProcPtr  thePowerPCProc,
ProcInfoType  theProcInfo 
)

CALL_NOT_IN_CARBON NewFatRoutineDescriptor()

Non-Carbon CFM: in InterfaceLib 7.1 and later
Carbon Lib: not available
Mac OS X: not available

◆ NewRoutineDescriptor()

UniversalProcPtr NewRoutineDescriptor ( ProcPtr  theProc,
ProcInfoType  theProcInfo,
ISAType  theISA 
)

NOTES ON USING ROUTINE DESCRIPTOR FUNCTIONS

When calling these routine from classic 68k code there are two possible intentions.

The first is source compatibility with code ported to CFM (either PowerPC or 68k CFM). When the code is compiled for CFM the functions create routine descriptors that can be used by the mixed mode manager operating on that machine. When the code is compiled for classic 68k these functions do nothing so that the code will run on Macintoshes that do not have a mixed mode manager. The dual nature of these functions is achieved by turning the CFM calls into "no-op" macros for classic 68k: You can put "NewRoutineDescriptor" in your source, compile it for any runtime or instruction set architecture, and it will run correctly on the intended runtime/instruction platform. All without source changes and/or conditional source.

The other intention is for code that "knows" that it is executing as classic 68k runtime and is specifically trying to call code of another architecture using mixed mode. Since the routines were designed with classic <-> CFM source compatibility in mind this second case is treated special. For classic 68k code to create routines descriptors for use by mixed mode it must call the "Trap" versions of the routines (NewRoutineDescriptorTrap). These versions are only available to classic 68k callers: rigging the interfaces to allow calling them from CFM code will result in runtime failure because no shared library implements or exports the functions.

This almost appears seamless until you consider "fat" routine descriptors and the advent of CFM-68K. What does "fat" mean? CFM-68K is not emulated on PowerPC and PowerPC is not emulated on CFM-68K. It makes no sense to create a routine descriptor having both a CFM-68K routine and a PowerPC native routine pointer. Therefore "fat" is defined to be a mix of classic and CFM for the hardware's native instruction set: on PowerPC fat is classic and PowerPC native, on a 68k machine with CFM-68K installed fat is classic and CFM-68K.

By definition fat routine descriptors are only constructed by code that is aware of the architecture it is executing as and that another architecture exists. Source compatibility between code intented as pure classic and pure CFM is not an issue and so NewFatRoutineDescriptor is not available when building pure classic code.

NewFatRoutineDescriptorTrap is available to classic code on both PowerPC and CFM-68K. The classic code can use the code fragment manager routine "FindSymbol" to obtain the address of a routine in a shared library and then construct a routine descriptor with both the CFM routine and classic routine. NewRoutineDescriptor()

Non-Carbon CFM: in InterfaceLib 7.1 and later or as macro/inline
Carbon Lib: not available
Mac OS X: not available