ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/uae_cpu/basilisk_glue.cpp
Revision: 1.18
Committed: 2006-04-30T21:16:48Z (18 years, 1 month ago) by gbeauche
Branch: MAIN
CVS Tags: nigel-build-19
Changes since 1.17: +2 -0 lines
Log Message:
Patch SynchIdleTime() to implement new "idlewait" prefs item.

File Contents

# Content
1 /*
2 * basilisk_glue.cpp - Glue UAE CPU to Basilisk II CPU engine interface
3 *
4 * Basilisk II (C) 1997-2005 Christian Bauer
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
23 #include "cpu_emulation.h"
24 #include "main.h"
25 #include "prefs.h"
26 #include "emul_op.h"
27 #include "rom_patches.h"
28 #include "timer.h"
29 #include "m68k.h"
30 #include "memory.h"
31 #include "readcpu.h"
32 #include "newcpu.h"
33 #include "compiler/compemu.h"
34
35
36 // RAM and ROM pointers
37 uint32 RAMBaseMac = 0; // RAM base (Mac address space) gb-- initializer is important
38 uint8 *RAMBaseHost; // RAM base (host address space)
39 uint32 RAMSize; // Size of RAM
40 uint32 ROMBaseMac; // ROM base (Mac address space)
41 uint8 *ROMBaseHost; // ROM base (host address space)
42 uint32 ROMSize; // Size of ROM
43
44 #if !REAL_ADDRESSING
45 // Mac frame buffer
46 uint8 *MacFrameBaseHost; // Frame buffer base (host address space)
47 uint32 MacFrameSize; // Size of frame buffer
48 int MacFrameLayout; // Frame buffer layout
49 #endif
50
51 #if DIRECT_ADDRESSING
52 uintptr MEMBaseDiff; // Global offset between a Mac address and its Host equivalent
53 #endif
54
55 #if USE_JIT
56 bool UseJIT = false;
57 #endif
58
59 // From newcpu.cpp
60 extern bool quit_program;
61
62
63 /*
64 * Initialize 680x0 emulation, CheckROM() must have been called first
65 */
66
67 bool Init680x0(void)
68 {
69 #if REAL_ADDRESSING
70 // Mac address space = host address space
71 RAMBaseMac = (uint32)RAMBaseHost;
72 ROMBaseMac = (uint32)ROMBaseHost;
73 #elif DIRECT_ADDRESSING
74 // Mac address space = host address space minus constant offset (MEMBaseDiff)
75 // NOTE: MEMBaseDiff is set up in main_unix.cpp/main()
76 RAMBaseMac = 0;
77 ROMBaseMac = Host2MacAddr(ROMBaseHost);
78 #else
79 // Initialize UAE memory banks
80 RAMBaseMac = 0;
81 switch (ROMVersion) {
82 case ROM_VERSION_64K:
83 case ROM_VERSION_PLUS:
84 case ROM_VERSION_CLASSIC:
85 ROMBaseMac = 0x00400000;
86 break;
87 case ROM_VERSION_II:
88 ROMBaseMac = 0x00a00000;
89 break;
90 case ROM_VERSION_32:
91 ROMBaseMac = 0x40800000;
92 break;
93 default:
94 return false;
95 }
96 memory_init();
97 #endif
98
99 init_m68k();
100 #if USE_JIT
101 UseJIT = compiler_use_jit();
102 if (UseJIT)
103 compiler_init();
104 #endif
105 return true;
106 }
107
108
109 /*
110 * Deinitialize 680x0 emulation
111 */
112
113 void Exit680x0(void)
114 {
115 #if USE_JIT
116 if (UseJIT)
117 compiler_exit();
118 #endif
119 exit_m68k();
120 }
121
122
123 /*
124 * Initialize memory mapping of frame buffer (called upon video mode change)
125 */
126
127 void InitFrameBufferMapping(void)
128 {
129 #if !REAL_ADDRESSING && !DIRECT_ADDRESSING
130 memory_init();
131 #endif
132 }
133
134 /*
135 * Reset and start 680x0 emulation (doesn't return)
136 */
137
138 void Start680x0(void)
139 {
140 m68k_reset();
141 #if USE_JIT
142 if (UseJIT)
143 m68k_compile_execute();
144 else
145 #endif
146 m68k_execute();
147 }
148
149
150 /*
151 * Trigger interrupt
152 */
153
154 void TriggerInterrupt(void)
155 {
156 idle_resume();
157 SPCFLAGS_SET( SPCFLAG_INT );
158 }
159
160 void TriggerNMI(void)
161 {
162 //!! not implemented yet
163 }
164
165
166 /*
167 * Get 68k interrupt level
168 */
169
170 int intlev(void)
171 {
172 return InterruptFlags ? 1 : 0;
173 }
174
175
176 /*
177 * Execute MacOS 68k trap
178 * r->a[7] and r->sr are unused!
179 */
180
181 void Execute68kTrap(uint16 trap, struct M68kRegisters *r)
182 {
183 int i;
184
185 // Save old PC
186 uaecptr oldpc = m68k_getpc();
187
188 // Set registers
189 for (i=0; i<8; i++)
190 m68k_dreg(regs, i) = r->d[i];
191 for (i=0; i<7; i++)
192 m68k_areg(regs, i) = r->a[i];
193
194 // Push trap and EXEC_RETURN on stack
195 m68k_areg(regs, 7) -= 2;
196 put_word(m68k_areg(regs, 7), M68K_EXEC_RETURN);
197 m68k_areg(regs, 7) -= 2;
198 put_word(m68k_areg(regs, 7), trap);
199
200 // Execute trap
201 m68k_setpc(m68k_areg(regs, 7));
202 fill_prefetch_0();
203 quit_program = false;
204 m68k_execute();
205
206 // Clean up stack
207 m68k_areg(regs, 7) += 4;
208
209 // Restore old PC
210 m68k_setpc(oldpc);
211 fill_prefetch_0();
212
213 // Get registers
214 for (i=0; i<8; i++)
215 r->d[i] = m68k_dreg(regs, i);
216 for (i=0; i<7; i++)
217 r->a[i] = m68k_areg(regs, i);
218 quit_program = false;
219 }
220
221
222 /*
223 * Execute 68k subroutine
224 * The executed routine must reside in UAE memory!
225 * r->a[7] and r->sr are unused!
226 */
227
228 void Execute68k(uint32 addr, struct M68kRegisters *r)
229 {
230 int i;
231
232 // Save old PC
233 uaecptr oldpc = m68k_getpc();
234
235 // Set registers
236 for (i=0; i<8; i++)
237 m68k_dreg(regs, i) = r->d[i];
238 for (i=0; i<7; i++)
239 m68k_areg(regs, i) = r->a[i];
240
241 // Push EXEC_RETURN and faked return address (points to EXEC_RETURN) on stack
242 m68k_areg(regs, 7) -= 2;
243 put_word(m68k_areg(regs, 7), M68K_EXEC_RETURN);
244 m68k_areg(regs, 7) -= 4;
245 put_long(m68k_areg(regs, 7), m68k_areg(regs, 7) + 4);
246
247 // Execute routine
248 m68k_setpc(addr);
249 fill_prefetch_0();
250 quit_program = false;
251 m68k_execute();
252
253 // Clean up stack
254 m68k_areg(regs, 7) += 2;
255
256 // Restore old PC
257 m68k_setpc(oldpc);
258 fill_prefetch_0();
259
260 // Get registers
261 for (i=0; i<8; i++)
262 r->d[i] = m68k_dreg(regs, i);
263 for (i=0; i<7; i++)
264 r->a[i] = m68k_areg(regs, i);
265 quit_program = false;
266 }