mirror of
https://github.com/elliotnunn/supermario.git
synced 2024-11-22 19:31:02 +00:00
368 lines
11 KiB
C
368 lines
11 KiB
C
/*
|
||
File: MixedMode.h
|
||
|
||
Contains: Headers and interfaces for the Mixed Mode mechanism
|
||
|
||
Written by: Bruce Jones
|
||
|
||
Copyright: © 1992 by Apple Computer, Inc., all rights reserved.
|
||
|
||
Change History (most recent first):
|
||
|
||
<1> 12/7/92 DRF first checked in
|
||
<18> 11/13/92 DRF Fix a bug in BuildRoutineDescriptor macro. We were building
|
||
kLoadAndExecute RDs and not kExecute types! Of course,
|
||
CodeFragMgrDispatch and MixedModeDispatch were the only two
|
||
users of this macro, so nobody knew it was broken.
|
||
<17> 11/8/92 BKJ Rolled back
|
||
<13+> 10/26/92 SP Adding definition for m68KRegisterSizePhase
|
||
<13> 10/22/92 DRF Added inline 68K trap glue for NewRoutineDescriptor and
|
||
DisposeRoutineDescriptor
|
||
<12> 10/19/92 DRF Changed declaration of NewRoutineDescriptor and
|
||
DisposeRoutineDescriptor to match Sean’s clearer syntax.
|
||
<11> 10/13/92 SP Changing all m68k's to m68K
|
||
<10> 10/08/92 SP Adding phase and offset enum for the parameters.
|
||
<9> 10/4/92 BKJ Current version is 1
|
||
<8> 10/1/92 jrg Made smaller enum blocks and changed typedef for InterfaceTool
|
||
<7> 9/29/92 BKJ Fix bug in BuildRoutineDescriptor macro.
|
||
<6> 9/28/92 stb add special cases as used by the rest of the public interfaces
|
||
<5> 9/18/92 LC changing kGoMixedMode to 0xFEED0000
|
||
<4> 9/10/92 EPT Added (long) typecasts to enum constants. Changed constants to
|
||
conform to new procInfo definition.
|
||
<3> 9/9/92 LC Added Macro "BuildRoutineDescriptor, which allows static
|
||
declaration of a routine descriptor at compile time. In order
|
||
to have this macro, many private declarations had to be brought
|
||
over from MixedModeApplePrivate.h, including kGoMixedMode, and
|
||
kMixedModeMagicCookie.
|
||
<2> 9/2/92 BKJ Get rid of numParams parameter to BuildProcInfo &
|
||
CallRoutineDescriptor calls.
|
||
<1> 9/1/92 BKJ first checked in
|
||
8/28/92 BKJ change to reflect latest ERS
|
||
6/5/92 BKJ Continued Development
|
||
4/17/92 BKJ Created
|
||
|
||
*/
|
||
|
||
|
||
|
||
#ifndef __MIXEDMODE__
|
||
#define __MIXEDMODE__
|
||
|
||
#ifndef __TYPES__
|
||
#include <Types.h>
|
||
#endif
|
||
|
||
#define kGoMixedMode 0xFEED0000
|
||
|
||
#define kMixedModeMagicCookie 0x4B4F4348
|
||
|
||
#define PARAMETER_SIZE(size) \
|
||
(((size) == 4) ? 3 : (((size) == 2) ? 1 : (((size) == 1) ? 2 : 0)))
|
||
|
||
enum {
|
||
kResultPhase = 4, /* bit offset for result field */
|
||
kParameterPhase = 6,
|
||
kParameterOffset = 2,
|
||
m68KRegisterOffset = 6,
|
||
m68KRegisterOut = 0x20,
|
||
m68KRegisterIn = 0x10,
|
||
m68KRegisterParameterPhase = 2,
|
||
m68KRegisterA0 = 0,
|
||
m68KRegisterA1 = 1,
|
||
m68KRegisterD0 = 2,
|
||
m68KRegisterD1 = 3
|
||
};
|
||
|
||
|
||
enum {
|
||
kPStackBased = 0,
|
||
kCStackBased = 1,
|
||
kRegisterBased = 2,
|
||
kD0DispStackBased = 8,
|
||
kD1DispStackBased = 12,
|
||
kStackDispStackBased = 14,
|
||
kStackDispRegisterBased = 10,
|
||
kSpecialCaseProcInfoType = 5
|
||
};
|
||
typedef short CallingConventionType;
|
||
|
||
|
||
enum {
|
||
// the Mixed Mode error codes
|
||
mmInternalError = -2526,
|
||
kMMErr2 = -2527,
|
||
kMMErr3 = -2528,
|
||
kMMErr4 = -2529,
|
||
kMMErr5 = -2530,
|
||
kMMErr6 = -2531,
|
||
kMMErr7 = -2532,
|
||
kMMErr8 = -2533,
|
||
kMMErr9 = -2534,
|
||
kMMErr10 = -2535
|
||
};
|
||
typedef short MMErrType;
|
||
|
||
enum {
|
||
kRegisterD0 = 0,
|
||
kRegisterD1,
|
||
kRegisterD2,
|
||
kRegisterD3,
|
||
kRegisterD4,
|
||
kRegisterD5,
|
||
kRegisterD6,
|
||
kRegisterD7,
|
||
kRegisterA0,
|
||
kRegisterA1,
|
||
kRegisterA2,
|
||
kRegisterA3,
|
||
kRegisterA4,
|
||
kRegisterA5,
|
||
kRegisterA6,
|
||
kRegisterA7
|
||
};
|
||
typedef short RegisterSelectorType;
|
||
|
||
enum {kLoadAndExecute = 0, kExecute, kReturnFrom};
|
||
typedef short SelectorType;
|
||
|
||
enum {kCodeTypeUnknown = -1, kCodeTypeCurrentWorld, kCodeType68K, kCodeTypePower};
|
||
typedef long CodeType;
|
||
|
||
typedef long ProcInfoType;
|
||
|
||
typedef struct private_RoutineDescriptor* RoutineDescriptor;
|
||
|
||
|
||
/* ProcInfo selectors for each of the parameters */
|
||
|
||
/* Pascal and C Stack based parameter constants */
|
||
/* Stack-based dispatched uses these, but only P2 and up */
|
||
enum {
|
||
m68KStackP1Byte = (long)0x00000080,
|
||
m68KStackP1Word = (long)0x00000040,
|
||
m68KStackP1Long = (long)0x000000C0,
|
||
m68KStackP2Byte = (long)0x00000200,
|
||
m68KStackP2Word = (long)0x00000100,
|
||
m68KStackP2Long = (long)0x00000300,
|
||
m68KStackP3Byte = (long)0x00000800,
|
||
m68KStackP3Word = (long)0x00000400,
|
||
m68KStackP3Long = (long)0x00000C00,
|
||
m68KStackP4Byte = (long)0x00002000,
|
||
m68KStackP4Word = (long)0x00001000,
|
||
m68KStackP4Long = (long)0x00003000,
|
||
m68KStackP5Byte = (long)0x00008000,
|
||
m68KStackP5Word = (long)0x00004000,
|
||
m68KStackP5Long = (long)0x0000C000,
|
||
m68KStackP6Byte = (long)0x00020000,
|
||
m68KStackP6Word = (long)0x00010000,
|
||
m68KStackP6Long = (long)0x00030000,
|
||
m68KStackP7Byte = (long)0x00080000,
|
||
m68KStackP7Word = (long)0x00040000,
|
||
m68KStackP7Long = (long)0x000C0000,
|
||
m68KStackP8Byte = (long)0x00200000,
|
||
m68KStackP8Word = (long)0x00100000,
|
||
m68KStackP8Long = (long)0x00300000,
|
||
m68KStackP9Byte = (long)0x00800000,
|
||
m68KStackP9Word = (long)0x00400000,
|
||
m68KStackP9Long = (long)0x00C00000,
|
||
m68KStackP10Byte = (long)0x02000000,
|
||
m68KStackP10Word = (long)0x01000000,
|
||
m68KStackP10Long = (long)0x03000000,
|
||
m68KStackP11Byte = (long)0x08000000,
|
||
m68KStackP11Word = (long)0x04000000,
|
||
m68KStackP11Long = (long)0x0C000000,
|
||
m68KStackP12Byte = (long)0x20000000,
|
||
m68KStackP12Word = (long)0x10000000,
|
||
m68KStackP12Long = (long)0x30000000,
|
||
m68KStackP13Byte = (long)0x80000000,
|
||
m68KStackP13Word = (long)0x40000000,
|
||
m68KStackP13Long = (long)0xC0000000
|
||
};
|
||
|
||
enum {
|
||
/* Register based parameter constants */
|
||
/* Also used for register-based dispatching */
|
||
m68KRegisterP1In = (long)0x00000400,
|
||
m68KRegisterP1Out = (long)0x00000800,
|
||
m68KRegisterP1InOut = (long)0x00000C00,
|
||
m68KRegisterP2In = (long)0x00010000,
|
||
m68KRegisterP2Out = (long)0x00020000,
|
||
m68KRegisterP2InOut = (long)0x00030000,
|
||
m68KRegisterP3In = (long)0x00400000,
|
||
m68KRegisterP3Out = (long)0x00800000,
|
||
m68KRegisterP3InOut = (long)0x00C00000,
|
||
m68KRegisterP4In = (long)0x10000000,
|
||
m68KRegisterP4Out = (long)0x20000000,
|
||
m68KRegisterP4InOut = (long)0x30000000
|
||
};
|
||
|
||
enum {
|
||
m68KRegisterP1Byte = (long)0x00000200,
|
||
m68KRegisterP1Word = (long)0x00000100,
|
||
m68KRegisterP1Long = (long)0x00000300,
|
||
m68KRegisterP2Byte = (long)0x00008000,
|
||
m68KRegisterP2Word = (long)0x00004000,
|
||
m68KRegisterP2Long = (long)0x0000C000,
|
||
m68KRegisterP3Byte = (long)0x00200000,
|
||
m68KRegisterP3Word = (long)0x00100000,
|
||
m68KRegisterP3Long = (long)0x00300000,
|
||
m68KRegisterP4Byte = (long)0x08000000,
|
||
m68KRegisterP4Word = (long)0x04000000,
|
||
m68KRegisterP4Long = (long)0x0C000000
|
||
};
|
||
|
||
enum {
|
||
m68KRegisterP1A0 = (long)0x00000000,
|
||
m68KRegisterP1A1 = (long)0x00000040,
|
||
m68KRegisterP1D0 = (long)0x00000080,
|
||
m68KRegisterP1D1 = (long)0x000000C0,
|
||
m68KRegisterP2A0 = (long)0x00000000,
|
||
m68KRegisterP2A1 = (long)0x00001000,
|
||
m68KRegisterP2D0 = (long)0x00002000,
|
||
m68KRegisterP2D1 = (long)0x00003000,
|
||
m68KRegisterP3A0 = (long)0x00000000,
|
||
m68KRegisterP3A1 = (long)0x00040000,
|
||
m68KRegisterP3D0 = (long)0x00080000,
|
||
m68KRegisterP3D1 = (long)0x000C0000,
|
||
m68KRegisterP4A0 = (long)0x00000000,
|
||
m68KRegisterP4A1 = (long)0x01000000,
|
||
m68KRegisterP4D0 = (long)0x02000000,
|
||
m68KRegisterP4D1 = (long)0x03000000
|
||
};
|
||
|
||
enum {
|
||
|
||
/* Dispatched constants for kStackDispRegisterBased type (selector on stack) */
|
||
m68KStackSelectorByte = (long)0x00000020,
|
||
m68KStackSelectorWord = (long)0x00000010,
|
||
m68KStackSelectorLong = (long)0x00000030,
|
||
|
||
/* Dispatched constants for all dispatched stack-based types */
|
||
m68KRegSelectorByte = (long)0x00000080,
|
||
m68KRegSelectorWord = (long)0x00000040,
|
||
m68KRegSelectorLong = (long)0x000000C0,
|
||
|
||
/* Selectors for the ProcInfo result size fields */
|
||
kNoReturnValue = (long)0x00000000,
|
||
k68KByteReturned = (long)0x00000020,
|
||
k68KWordReturned = (long)0x00000010, /* 68K word - two bytes */
|
||
k68KLongReturned = (long)0x00000030 /* 68K long - four bytes */
|
||
};
|
||
|
||
/* all of the special cases enumerated */
|
||
enum {
|
||
kSpecialCaseHighHook = 0x0100,
|
||
kSpecialCaseCaretHook = 0x0100,
|
||
kSpecialCaseEOLHook = 0x0200,
|
||
kSpecialCaseWidthHook = 0x0300,
|
||
kSpecialCaseNWidthHook = 0x0400,
|
||
kSpecialCaseTextWidthHook = 0x0500,
|
||
kSpecialCaseDrawHook = 0x0600,
|
||
kSpecialCaseHitTestHook = 0x0700,
|
||
kSpecialCaseTEFindWord = 0x0800,
|
||
kSpecialCaseADBRoutines = 0x0900,
|
||
kSpecialCaseProtocolHandler = 0x0A00,
|
||
kSpecialCaseSocketListener = 0x0B00
|
||
};
|
||
/*
|
||
Explanation of special cases:
|
||
*****************************
|
||
1 = C calling conventions, Rect on stack, pointer in A3, no return value
|
||
2 = Register-based; inputs in D0, A3, A4; output is Z flag of
|
||
status register (see VI-15-26)
|
||
3 = Register-based; inputs in D0, D1, A0, A3, A4; output in D1 (see VI-15-27)
|
||
4 = Register-based; inputs in D0, D1, D2, A0, A2, A3, A4; output in D1
|
||
(see VI-15-27)
|
||
5 = Register-based; inputs in D0, D1, A0, A3, A4; output in D1 (see VI-15-28)
|
||
6 = Register-based; inputs in D0, D1, A0, A3, A4; no output (see VI-15-28)
|
||
7 = Register-based; inputs in D0, D1, D21, A0, A3, A4; outputs in
|
||
D0, D1, D2 (See VI-15-29)
|
||
8 = Register-based; inputs in D0, D2, A3, A4; outputs in D0, D1 (see VI-15-30)
|
||
9 = Register-based; inputs in A0, A1, A2, D0; no outputs (see V-371)
|
||
A = Register-based; inputs in A0, A1, A2, A3, A4, D1.w; output in Z (see II-326)
|
||
B = Register-based; inputs in A0, A1, A2, A3, A4, D0.b, D1.w; output in Z
|
||
(see II-329)
|
||
|
||
*/
|
||
|
||
RoutineDescriptor
|
||
NewRoutineDescriptor(ProcPtr theProc,
|
||
ProcInfoType procInfo,
|
||
CodeType typeOfCode)
|
||
= {0x303C,0x0000,0xAA59}; /* <13> */
|
||
|
||
void
|
||
DisposeRoutineDescriptor (RoutineDescriptor theDescriptor)
|
||
= {0x303C,0x0001,0xAA59}; /* <13> */
|
||
|
||
long
|
||
CallRoutineDescriptor (RoutineDescriptor theRoutine,
|
||
ProcInfoType procInfo,
|
||
...);
|
||
CodeType
|
||
GetCodeType (RoutineDescriptor theDescriptor);
|
||
|
||
OSErr
|
||
SetCodeType (RoutineDescriptor theDescriptor,
|
||
CodeType newCodeType);
|
||
|
||
ProcInfoType
|
||
BuildProcInfo(CallingConventionType callingConvention,
|
||
short resultSize,
|
||
...);
|
||
|
||
ProcInfoType
|
||
GetProcInfo (RoutineDescriptor theDescriptor);
|
||
|
||
OSErr
|
||
SetProcInfo (RoutineDescriptor theDescriptor,
|
||
ProcInfoType newProcInfo);
|
||
|
||
ProcPtr
|
||
GetTheProc (RoutineDescriptor theDescriptor);
|
||
|
||
OSErr
|
||
SetTheProc (RoutineDescriptor theDescriptor,
|
||
ProcPtr newProc);
|
||
|
||
long
|
||
GetEmulatorRegister (RegisterSelectorType registerSelector);
|
||
|
||
long
|
||
SetEmulatorRegister (RegisterSelectorType registerSelector,
|
||
long newValue);
|
||
|
||
|
||
enum {kRoutineDescriptorVersion = 1};
|
||
|
||
struct private_RoutineDescriptor {
|
||
long goMixedMode; // unused 68K instruction 0
|
||
long magicCookie; // unique identifier 4
|
||
SelectorType selector; // mixed mode selector 8
|
||
short version; // 0 for now, increment as needed 10
|
||
ProcInfoType procInfo; // calling conventions 12
|
||
ProcPtr customParamProc; // Procedure to convert params 16
|
||
CodeType executionMode; // to different types of code 20
|
||
ProcPtr procDescriptor; // Descriptor of routine we are going to call 24
|
||
long unused; // must be 0 28
|
||
};
|
||
|
||
typedef struct private_RoutineDescriptor private_RoutineDescriptor;
|
||
typedef private_RoutineDescriptor *private_RoutineDescriptorPtr, **private_RoutineDescriptorHandle;
|
||
|
||
/* a macro which creates a static instance of a routine descriptor */
|
||
#define BuildRoutineDescriptor(procInfo, procedure) \
|
||
{ \
|
||
kGoMixedMode, /* GoMixedMode instruction */ \
|
||
kMixedModeMagicCookie, /* Mixed Mode magic cookie */ \
|
||
kExecute, /* selector <18> */ \
|
||
kRoutineDescriptorVersion, /* version */ \
|
||
(procInfo), /* ProcInfo */ \
|
||
0, /* custom param proc */ \
|
||
kCodeTypePower, /* execution mode */ \
|
||
(void *) (procedure), /* theProc */ \
|
||
0, /* list terminator */ \
|
||
}
|
||
|
||
|
||
#endif |