1 |
|
/* |
2 |
|
* main_unix.cpp - Startup code for Unix |
3 |
|
* |
4 |
< |
* Basilisk II (C) 1997-1999 Christian Bauer |
4 |
> |
* Basilisk II (C) 1997-2000 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 |
27 |
|
|
28 |
|
#include "cpu_emulation.h" |
29 |
|
#include "sys.h" |
30 |
+ |
#include "rom_patches.h" |
31 |
|
#include "xpram.h" |
32 |
|
#include "timer.h" |
32 |
– |
#include "sony.h" |
33 |
– |
#include "disk.h" |
34 |
– |
#include "cdrom.h" |
35 |
– |
#include "scsi.h" |
36 |
– |
#include "audio.h" |
33 |
|
#include "video.h" |
38 |
– |
#include "serial.h" |
39 |
– |
#include "ether.h" |
40 |
– |
#include "clip.h" |
41 |
– |
#include "rom_patches.h" |
34 |
|
#include "prefs.h" |
35 |
|
#include "prefs_editor.h" |
36 |
|
#include "macos_util.h" |
38 |
|
#include "version.h" |
39 |
|
#include "main.h" |
40 |
|
|
41 |
< |
#define DEBUG 1 |
41 |
> |
#define DEBUG 0 |
42 |
|
#include "debug.h" |
43 |
|
|
44 |
|
|
48 |
|
#include <gtk/gtk.h> |
49 |
|
#endif |
50 |
|
|
51 |
< |
#if ENABLE_DGA |
51 |
> |
#if ENABLE_XF86_DGA |
52 |
|
#include <X11/Xlib.h> |
53 |
|
#include <X11/Xutil.h> |
54 |
|
#include <X11/extensions/xf86dga.h> |
55 |
|
#endif |
56 |
|
|
57 |
+ |
#if ENABLE_MON |
58 |
+ |
#include "mon.h" |
59 |
+ |
#endif |
60 |
+ |
|
61 |
+ |
#ifdef USE_MAPPED_MEMORY |
62 |
+ |
#include <sys/mman.h> |
63 |
+ |
extern char *address_space, *good_address_map; |
64 |
+ |
#endif |
65 |
+ |
|
66 |
|
|
67 |
|
// Constants |
68 |
|
const char ROM_FILE_NAME[] = "ROM"; |
96 |
|
static timer_t timer; // 60Hz timer |
97 |
|
#endif |
98 |
|
|
99 |
+ |
#if ENABLE_MON |
100 |
+ |
static struct sigaction sigint_sa; // sigaction for SIGINT handler |
101 |
+ |
static void sigint_handler(...); |
102 |
+ |
#endif |
103 |
+ |
|
104 |
|
|
105 |
|
// Prototypes |
106 |
|
static void *xpram_func(void *arg); |
146 |
|
for (int i=1; i<argc; i++) { |
147 |
|
if (strcmp(argv[i], "-display") == 0 && ++i < argc) |
148 |
|
x_display_name = argv[i]; |
149 |
+ |
else if (strcmp(argv[i], "-break") == 0 && ++i < argc) |
150 |
+ |
ROMBreakpoint = strtol(argv[i], NULL, 0); |
151 |
+ |
else if (strcmp(argv[i], "-rominfo") == 0) |
152 |
+ |
PrintROMInfo = true; |
153 |
|
} |
154 |
|
|
155 |
|
// Open display |
161 |
|
QuitEmulator(); |
162 |
|
} |
163 |
|
|
164 |
< |
#if ENABLE_DGA |
164 |
> |
#if ENABLE_XF86_DGA && !ENABLE_MON |
165 |
|
// Fork out, so we can return from fullscreen mode when things get ugly |
166 |
< |
XF86DGAForkApp(XDefaultScreen(x_display)); |
166 |
> |
XF86DGAForkApp(DefaultScreen(x_display)); |
167 |
|
#endif |
168 |
|
|
169 |
|
#if ENABLE_GTK |
183 |
|
if (!PrefsEditor()) |
184 |
|
QuitEmulator(); |
185 |
|
|
186 |
< |
// Create area for Mac RAM |
186 |
> |
// Read RAM size |
187 |
|
RAMSize = PrefsFindInt32("ramsize") & 0xfff00000; // Round down to 1MB boundary |
188 |
|
if (RAMSize < 1024*1024) { |
189 |
|
WarningAlert(GetString(STR_SMALL_RAM_WARN)); |
190 |
|
RAMSize = 1024*1024; |
191 |
|
} |
182 |
– |
RAMBaseHost = new uint8[RAMSize]; |
192 |
|
|
193 |
< |
// Create area for Mac ROM |
193 |
> |
// Create areas for Mac RAM and ROM |
194 |
> |
#ifdef USE_MAPPED_MEMORY |
195 |
> |
int fd = open("/dev/zero", O_RDWR); |
196 |
> |
good_address_map = (char *)mmap(NULL, 1<<24, PROT_READ, MAP_PRIVATE, fd, 0); |
197 |
> |
address_space = (char *)mmap(NULL, 1<<24, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); |
198 |
> |
if ((int)address_space < 0 || (int)good_address_map < 0) { |
199 |
> |
ErrorAlert(GetString(STR_NOT_ENOUGH_MEMORY_ERR)); |
200 |
> |
QuitEmulator(); |
201 |
> |
} |
202 |
> |
RAMBaseHost = (uint8 *)mmap(address_space, RAMSize, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0); |
203 |
> |
ROMBaseHost = (uint8 *)mmap(address_space + 0x00400000, 0x80000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fd, 0); |
204 |
> |
close(fd); |
205 |
> |
char *nam = tmpnam(NULL); |
206 |
> |
int good_address_fd = open(nam, O_CREAT | O_RDWR, 0600); |
207 |
> |
char buffer[4096]; |
208 |
> |
memset(buffer, 1, sizeof(buffer)); |
209 |
> |
write(good_address_fd, buffer, sizeof(buffer)); |
210 |
> |
unlink(nam); |
211 |
> |
for (int i=0; i<RAMSize; i+=4096) |
212 |
> |
mmap(good_address_map + i, 4096, PROT_READ, MAP_FIXED | MAP_PRIVATE, good_address_fd, 0); |
213 |
> |
for (int i=0; i<0x80000; i+=4096) |
214 |
> |
mmap(good_address_map + i + 0x00400000, 4096, PROT_READ, MAP_FIXED | MAP_PRIVATE, good_address_fd, 0); |
215 |
> |
#else |
216 |
> |
RAMBaseHost = new uint8[RAMSize]; |
217 |
|
ROMBaseHost = new uint8[0x100000]; |
218 |
+ |
#endif |
219 |
|
|
220 |
|
// Get rom file path from preferences |
221 |
|
const char *rom_path = PrefsFindString("rom"); |
240 |
|
QuitEmulator(); |
241 |
|
} |
242 |
|
|
243 |
< |
// Check ROM version |
244 |
< |
if (!CheckROM()) { |
212 |
< |
ErrorAlert(GetString(STR_UNSUPPORTED_ROM_TYPE_ERR)); |
243 |
> |
// Initialize everything |
244 |
> |
if (!InitAll()) |
245 |
|
QuitEmulator(); |
214 |
– |
} |
215 |
– |
|
216 |
– |
// Set CPU and FPU type (UAE emulation) |
217 |
– |
switch (ROMVersion) { |
218 |
– |
case ROM_VERSION_64K: |
219 |
– |
case ROM_VERSION_PLUS: |
220 |
– |
case ROM_VERSION_CLASSIC: |
221 |
– |
CPUType = 0; |
222 |
– |
FPUType = 0; |
223 |
– |
TwentyFourBitAddressing = true; |
224 |
– |
break; |
225 |
– |
case ROM_VERSION_II: |
226 |
– |
CPUType = 2; |
227 |
– |
FPUType = PrefsFindBool("fpu") ? 1 : 0; |
228 |
– |
TwentyFourBitAddressing = true; |
229 |
– |
break; |
230 |
– |
case ROM_VERSION_32: |
231 |
– |
CPUType = 3; |
232 |
– |
FPUType = PrefsFindBool("fpu") ? 1 : 0; |
233 |
– |
TwentyFourBitAddressing = false; |
234 |
– |
break; |
235 |
– |
} |
236 |
– |
CPUIs68060 = false; |
237 |
– |
|
238 |
– |
// Load XPRAM |
239 |
– |
XPRAMInit(); |
240 |
– |
|
241 |
– |
// Set boot volume |
242 |
– |
int16 i16 = PrefsFindInt16("bootdrive"); |
243 |
– |
XPRAM[0x78] = i16 >> 8; |
244 |
– |
XPRAM[0x79] = i16 & 0xff; |
245 |
– |
i16 = PrefsFindInt16("bootdriver"); |
246 |
– |
XPRAM[0x7a] = i16 >> 8; |
247 |
– |
XPRAM[0x7b] = i16 & 0xff; |
246 |
|
|
247 |
|
// Start XPRAM watchdog thread |
248 |
|
xpram_thread_active = (pthread_create(&xpram_thread, NULL, xpram_func, NULL) == 0); |
249 |
|
|
252 |
– |
// Init drivers |
253 |
– |
SonyInit(); |
254 |
– |
DiskInit(); |
255 |
– |
CDROMInit(); |
256 |
– |
SCSIInit(); |
257 |
– |
|
258 |
– |
// Init serial ports |
259 |
– |
SerialInit(); |
260 |
– |
|
261 |
– |
// Init network |
262 |
– |
EtherInit(); |
263 |
– |
|
264 |
– |
// Init Time Manager |
265 |
– |
TimerInit(); |
266 |
– |
|
267 |
– |
// Init clipboard |
268 |
– |
ClipInit(); |
269 |
– |
|
270 |
– |
// Init audio |
271 |
– |
AudioInit(); |
272 |
– |
|
273 |
– |
// Init video |
274 |
– |
if (!VideoInit(ROMVersion == ROM_VERSION_64K || ROMVersion == ROM_VERSION_PLUS || ROMVersion == ROM_VERSION_CLASSIC)) |
275 |
– |
QuitEmulator(); |
276 |
– |
|
277 |
– |
// Init 680x0 emulation (this also activates the memory system which is needed for PatchROM()) |
278 |
– |
if (!Init680x0()) |
279 |
– |
QuitEmulator(); |
280 |
– |
|
281 |
– |
// Install ROM patches |
282 |
– |
if (!PatchROM()) { |
283 |
– |
ErrorAlert(GetString(STR_UNSUPPORTED_ROM_TYPE_ERR)); |
284 |
– |
QuitEmulator(); |
285 |
– |
} |
286 |
– |
|
250 |
|
#if defined(HAVE_TIMER_CREATE) && defined(_POSIX_REALTIME_SIGNALS) |
251 |
|
// Start 60Hz timer |
252 |
|
sigemptyset(&timer_sa.sa_mask); |
268 |
|
req.it_value.tv_nsec = 16625000; |
269 |
|
req.it_interval.tv_sec = 0; |
270 |
|
req.it_interval.tv_nsec = 16625000; |
271 |
< |
if (timer_settime(timer, TIMER_RELTIME, &req, NULL) < 0) { |
271 |
> |
if (timer_settime(timer, 0, &req, NULL) < 0) { |
272 |
|
printf("FATAL: cannot start timer\n"); |
273 |
|
QuitEmulator(); |
274 |
|
} |
293 |
|
} |
294 |
|
#endif |
295 |
|
|
296 |
+ |
#if ENABLE_MON |
297 |
+ |
// Setup SIGINT handler to enter mon |
298 |
+ |
sigemptyset(&sigint_sa.sa_mask); |
299 |
+ |
sigint_sa.sa_flags = 0; |
300 |
+ |
sigint_sa.sa_handler = sigint_handler; |
301 |
+ |
sigaction(SIGINT, &sigint_sa, NULL); |
302 |
+ |
#endif |
303 |
+ |
|
304 |
|
// Start 68k and jump to ROM boot routine |
305 |
|
Start680x0(); |
306 |
|
|
341 |
|
pthread_join(xpram_thread, NULL); |
342 |
|
} |
343 |
|
|
344 |
< |
// Save XPRAM |
345 |
< |
XPRAMExit(); |
375 |
< |
|
376 |
< |
// Exit video |
377 |
< |
VideoExit(); |
378 |
< |
|
379 |
< |
// Exit audio |
380 |
< |
AudioExit(); |
381 |
< |
|
382 |
< |
// Exit clipboard |
383 |
< |
ClipExit(); |
384 |
< |
|
385 |
< |
// Exit Time Manager |
386 |
< |
TimerExit(); |
387 |
< |
|
388 |
< |
// Exit serial ports |
389 |
< |
SerialExit(); |
390 |
< |
|
391 |
< |
// Exit network |
392 |
< |
EtherExit(); |
393 |
< |
|
394 |
< |
// Exit drivers |
395 |
< |
SCSIExit(); |
396 |
< |
CDROMExit(); |
397 |
< |
DiskExit(); |
398 |
< |
SonyExit(); |
344 |
> |
// Deinitialize everything |
345 |
> |
ExitAll(); |
346 |
|
|
347 |
|
// Delete ROM area |
348 |
|
delete[] ROMBaseHost; |
375 |
|
} |
376 |
|
#endif |
377 |
|
|
378 |
+ |
|
379 |
+ |
/* |
380 |
+ |
* SIGINT handler, enters mon |
381 |
+ |
*/ |
382 |
+ |
|
383 |
+ |
#if ENABLE_MON |
384 |
+ |
extern void m68k_dumpstate(uaecptr *nextpc); |
385 |
+ |
static void sigint_handler(...) |
386 |
+ |
{ |
387 |
+ |
uaecptr nextpc; |
388 |
+ |
m68k_dumpstate(&nextpc); |
389 |
+ |
char *arg[2] = {"rmon", NULL}; |
390 |
+ |
mon(1, arg); |
391 |
+ |
QuitEmulator(); |
392 |
+ |
} |
393 |
+ |
#endif |
394 |
+ |
|
395 |
|
|
396 |
|
/* |
397 |
|
* Interrupt flags (must be handled atomically!) |