ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/thunks.cpp
Revision: 1.2
Committed: 2003-12-04T23:37:35Z (20 years, 11 months ago) by gbeauche
Branch: MAIN
Changes since 1.1: +45 -7 lines
Log Message:
Use a unique ExecuteNative() interface in any case, i.e. native & emulated

File Contents

# Content
1 /*
2 * thunks.cpp - Thunks to share data and code with MacOS
3 *
4 * SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include "sysdeps.h"
22 #include "thunks.h"
23 #include "emul_op.h"
24 #include "cpu_emulation.h"
25
26 // Native function declarations
27 #include "main.h"
28 #include "video.h"
29 #include "name_registry.h"
30 #include "serial.h"
31 #include "ether.h"
32 #include "macos_util.h"
33
34
35 /* NativeOp instruction format:
36 +------------+--------------------------+--+----------+------------+
37 | 6 | |FN| OP | 2 |
38 +------------+--------------------------+--+----------+------------+
39 0 5 |6 19 20 21 25 26 31
40 */
41
42 #define POWERPC_NATIVE_OP(LR, OP) \
43 (POWERPC_EMUL_OP | ((LR) << 11) | (((uint32)OP) << 6) | 2)
44
45 /*
46 * Return the fake PowerPC opcode to handle specified native code
47 */
48
49 #if EMULATED_PPC
50 uint32 NativeOpcode(int selector)
51 {
52 uint32 opcode;
53 switch (selector) {
54 case NATIVE_DISABLE_INTERRUPT:
55 case NATIVE_ENABLE_INTERRUPT:
56 opcode = POWERPC_NATIVE_OP(0, selector);
57 break;
58 case NATIVE_PATCH_NAME_REGISTRY:
59 case NATIVE_VIDEO_INSTALL_ACCEL:
60 case NATIVE_VIDEO_VBL:
61 case NATIVE_VIDEO_DO_DRIVER_IO:
62 case NATIVE_ETHER_IRQ:
63 case NATIVE_ETHER_INIT:
64 case NATIVE_ETHER_TERM:
65 case NATIVE_ETHER_OPEN:
66 case NATIVE_ETHER_CLOSE:
67 case NATIVE_ETHER_WPUT:
68 case NATIVE_ETHER_RSRV:
69 case NATIVE_SERIAL_NOTHING:
70 case NATIVE_SERIAL_OPEN:
71 case NATIVE_SERIAL_PRIME_IN:
72 case NATIVE_SERIAL_PRIME_OUT:
73 case NATIVE_SERIAL_CONTROL:
74 case NATIVE_SERIAL_STATUS:
75 case NATIVE_SERIAL_CLOSE:
76 case NATIVE_GET_RESOURCE:
77 case NATIVE_GET_1_RESOURCE:
78 case NATIVE_GET_IND_RESOURCE:
79 case NATIVE_GET_1_IND_RESOURCE:
80 case NATIVE_R_GET_RESOURCE:
81 case NATIVE_MAKE_EXECUTABLE:
82 opcode = POWERPC_NATIVE_OP(1, selector);
83 break;
84 default:
85 abort();
86 }
87 return opcode;
88 }
89 #endif
90
91
92 /*
93 * Initialize the thunks system
94 */
95
96 struct native_op_t {
97 uint32 tvect;
98 uint32 func;
99 };
100 static native_op_t native_op[NATIVE_OP_MAX];
101
102 bool ThunksInit(void)
103 {
104 #if EMULATED_PPC
105 for (int i = 0; i < NATIVE_OP_MAX; i++) {
106 uintptr base = SheepMem::Reserve(12);
107 WriteMacInt32(base + 0, base + 8);
108 WriteMacInt32(base + 4, 0); // Fake TVECT
109 WriteMacInt32(base + 8, NativeOpcode(i));
110 native_op[i].tvect = base;
111 native_op[i].func = base + 8;
112 }
113 #else
114 #if defined(__linux__)
115 #define DEFINE_NATIVE_OP(ID, FUNC) do { \
116 uintptr base = SheepMem::Reserve(8); \
117 WriteMacInt32(base + 0, (uint32)FUNC); \
118 WriteMacInt32(base + 4, 0); /*Fake TVECT*/ \
119 native_op[ID].tvect = base; \
120 native_op[ID].func = (uint32)FUNC; \
121 } while (0)
122 #elif defined(__BEOS__)
123 #define DEFINE_NATIVE_OP(ID, FUNC) do { \
124 native_op[ID].tvect = FUNC; \
125 native_op[ID].func = ((uint32 *)FUNC)[0]; \
126 } while (0)
127 #else
128 #error "FIXME: define NativeOp for your platform"
129 #endif
130 DEFINE_NATIVE_OP(NATIVE_PATCH_NAME_REGISTRY, DoPatchNameRegistry);
131 DEFINE_NATIVE_OP(NATIVE_VIDEO_INSTALL_ACCEL, VideoInstallAccel);
132 DEFINE_NATIVE_OP(NATIVE_VIDEO_VBL, VideoVBL);
133 DEFINE_NATIVE_OP(NATIVE_VIDEO_DO_DRIVER_IO, VideoDoDriverIO);
134 DEFINE_NATIVE_OP(NATIVE_ETHER_IRQ, EtherIRQ);
135 DEFINE_NATIVE_OP(NATIVE_ETHER_INIT, InitStreamModule);
136 DEFINE_NATIVE_OP(NATIVE_ETHER_TERM, TerminateStreamModule);
137 DEFINE_NATIVE_OP(NATIVE_ETHER_OPEN, ether_open);
138 DEFINE_NATIVE_OP(NATIVE_ETHER_CLOSE, ether_close);
139 DEFINE_NATIVE_OP(NATIVE_ETHER_WPUT, ether_wput);
140 DEFINE_NATIVE_OP(NATIVE_ETHER_RSRV, ether_rsrv);
141 DEFINE_NATIVE_OP(NATIVE_SERIAL_NOTHING, SerialNothing);
142 DEFINE_NATIVE_OP(NATIVE_SERIAL_OPEN, SerialOpen);
143 DEFINE_NATIVE_OP(NATIVE_SERIAL_PRIME_IN, SerialPrimeIn);
144 DEFINE_NATIVE_OP(NATIVE_SERIAL_PRIME_OUT, SerialPrimeOut);
145 DEFINE_NATIVE_OP(NATIVE_SERIAL_CONTROL, SerialControl);
146 DEFINE_NATIVE_OP(NATIVE_SERIAL_STATUS, SerialStatus);
147 DEFINE_NATIVE_OP(NATIVE_SERIAL_CLOSE, SerialClose);
148 DEFINE_NATIVE_OP(NATIVE_MAKE_EXECUTABLE, MakeExecutable);
149 #undef DEFINE_NATIVE_OP
150 #endif
151 return true;
152 }
153
154
155 /*
156 * Return the native function descriptor (TVECT)
157 */
158
159 uint32 NativeTVECT(int selector)
160 {
161 assert(selector < NATIVE_OP_MAX);
162 const uint32 tvect = native_op[selector].tvect;
163 assert(tvect != 0);
164 return tvect;
165 }
166
167
168 /*
169 * Return the native function address
170 */
171
172 uint32 NativeFunction(int selector)
173 {
174 assert(selector < NATIVE_OP_MAX);
175 const uint32 func = native_op[selector].func;
176 assert(func != 0);
177 return func;
178 }
179
180
181 /*
182 * Execute native code from EMUL_OP routine (real mode switch)
183 */
184
185 void ExecuteNative(int selector)
186 {
187 SheepRoutineDescriptor desc(0, NativeTVECT(selector));
188 M68kRegisters r;
189 Execute68k(desc.addr(), &r);
190 }