4 |
|
* |
5 |
|
* $Id$ |
6 |
|
* |
7 |
< |
* Basilisk II (C) 1997-2002 Christian Bauer |
7 |
> |
* Basilisk II (C) 1997-2008 Christian Bauer |
8 |
|
* |
9 |
|
* This program is free software; you can redistribute it and/or modify |
10 |
|
* it under the terms of the GNU General Public License as published by |
24 |
|
#import "Emulator.h" |
25 |
|
#import "EmulatorView.h" |
26 |
|
|
27 |
– |
@implementation Emulator |
28 |
– |
|
27 |
|
#import "sysdeps.h" // Types used in Basilisk C++ code |
28 |
|
|
29 |
|
#import "main_macosx.h" // Prototypes for QuitEmuNoExit() and InitEmulator() |
30 |
|
#import "misc_macosx.h" // Some other prototypes |
31 |
|
#import "video_macosx.h" // Some window/view globals |
32 |
|
|
33 |
< |
#import <adb.h> |
34 |
< |
#import <main.h> |
35 |
< |
#import <prefs.h> |
36 |
< |
#import <timer.h> |
33 |
> |
#import "adb.h" |
34 |
> |
#import "main.h" |
35 |
> |
#import "prefs.h" |
36 |
> |
#import "timer.h" |
37 |
> |
|
38 |
> |
#undef check // memory.h defines a check macro, |
39 |
> |
// which may clash with an OS X one on 10.1 or 10.2 |
40 |
> |
#import "cpu_emulation.h" |
41 |
|
|
42 |
< |
#undef check() // memory.h defines a check macro, which clashes with an OS X one? |
43 |
< |
#import <cpu_emulation.h> |
42 |
> |
#define DEBUG 0 |
43 |
> |
#import "debug.h" |
44 |
|
|
45 |
< |
#define DEBUG 1 |
44 |
< |
#import <debug.h> |
45 |
> |
@implementation Emulator |
46 |
|
|
47 |
|
// NSWindow method, which is invoked via delegation |
48 |
|
|
95 |
|
//[win setHasShadow: NO]; // This causes view & window to now be drawn correctly |
96 |
|
[win useOptimizedDrawing: YES]; |
97 |
|
|
97 |
– |
// [win center]; |
98 |
|
[win makeKeyAndOrderFront:self]; |
99 |
|
|
100 |
– |
// [self resizeWinToWidth:x Height:y]; |
101 |
– |
|
100 |
|
if ( redrawDelay ) |
101 |
|
[speed setFloatValue: 1.0 / redrawDelay]; |
102 |
|
else |
118 |
|
- (NSSlider *) speed { return speed; } |
119 |
|
- (NSWindow *) window { return win; } |
120 |
|
|
123 |
– |
//#define DEBUG 1 |
124 |
– |
//#include <debug.h> |
121 |
|
|
122 |
|
// Update some UI elements |
123 |
|
|
145 |
|
[self Resume: self]; |
146 |
|
} |
147 |
|
|
148 |
+ |
#ifdef NIGEL |
149 |
+ |
- (IBAction) EjectCD: (id)sender; |
150 |
+ |
{ |
151 |
+ |
NSString *path; |
152 |
+ |
const char *cdrom = PrefsFindString("cdrom"); |
153 |
+ |
|
154 |
+ |
if ( cdrom ) |
155 |
+ |
{ |
156 |
+ |
#include <sys/param.h> |
157 |
+ |
#define KERNEL |
158 |
+ |
#include <sys/mount.h> |
159 |
+ |
|
160 |
+ |
struct statfs buf; |
161 |
+ |
if ( fsstat(path, &buf) < 0 ) |
162 |
+ |
return; |
163 |
+ |
|
164 |
+ |
path = [NSString stringWithCString: cdrom]; |
165 |
+ |
|
166 |
+ |
[[NSWorkspace sharedWorkspace] unmountAndEjectDeviceAtPath: path]; |
167 |
+ |
// [path release]; |
168 |
+ |
} |
169 |
+ |
} |
170 |
+ |
#endif |
171 |
+ |
|
172 |
|
- (IBAction) Interrupt: (id)sender; |
173 |
|
{ |
174 |
< |
WarningSheet (@"Interrupt action not yet supported", @"", @"OK", win); |
174 |
> |
WarningSheet (@"Interrupt action not yet supported", win); |
175 |
|
} |
176 |
|
|
177 |
|
- (IBAction) PowerKey: (id)sender; |
191 |
|
|
192 |
|
- (IBAction) Restart: (id)sender |
193 |
|
{ |
194 |
+ |
if ( ! running ) |
195 |
+ |
{ |
196 |
+ |
running = YES; // Start emulator |
197 |
+ |
[self runUpdate]; |
198 |
+ |
[self Resume: nil]; |
199 |
+ |
} |
200 |
+ |
|
201 |
|
if ( running ) |
202 |
< |
// reset680x0(); |
202 |
> |
#ifdef UAE_CPU_HAS_RESET |
203 |
> |
reset680x0(); |
204 |
> |
#else |
205 |
|
{ |
206 |
|
uaeCreated = NO; |
207 |
|
[redraw suspend]; |
208 |
|
NSLog (@"%s - uae_cpu reset not yet supported, will try to fake it", |
209 |
|
__PRETTY_FUNCTION__); |
210 |
|
|
211 |
< |
// [screen blacken]; |
212 |
< |
[screen setNeedsDisplay: YES]; |
211 |
> |
[screen clear]; |
212 |
> |
[screen display]; |
213 |
|
|
214 |
|
[emul terminate]; QuitEmuNoExit(); |
215 |
|
|
216 |
< |
emul = [[NNThread alloc] init]; |
216 |
> |
|
217 |
> |
// OK. We have killed & cleaned up. Now, start afresh: |
218 |
> |
#include <sys.h> |
219 |
> |
int argc = 0; |
220 |
> |
char **argv; |
221 |
> |
|
222 |
> |
PrefsInit(NULL, argc, argv); |
223 |
> |
SysInit(); |
224 |
> |
|
225 |
> |
emul = [NNThread new]; |
226 |
|
[emul perform:@selector(emulThread) of:self]; |
227 |
|
[emul start]; |
228 |
|
|
229 |
|
if ( display_type != DISPLAY_SCREEN ) |
230 |
|
[redraw resume]; |
193 |
– |
uaeCreated = YES; |
231 |
|
} |
232 |
+ |
#endif |
233 |
|
} |
234 |
|
|
235 |
|
- (IBAction) Resume: (id)sender |
242 |
|
[xPRAM resume]; |
243 |
|
} |
244 |
|
|
245 |
+ |
- (IBAction) ScreenHideShow: (NSButton *)sender; |
246 |
+ |
{ |
247 |
+ |
WarningSheet(@"Nigel doesn't know how to shrink or grow this window", |
248 |
+ |
@"Maybe you can grab the source code and have a go yourself?", |
249 |
+ |
nil, win); |
250 |
+ |
} |
251 |
+ |
|
252 |
|
- (IBAction) Snapshot: (id) sender |
253 |
|
{ |
254 |
|
if ( screen == nil || uaeCreated == NO ) |
255 |
|
WarningSheet(@"The emulator has not yet started.", |
256 |
|
@"There is no screen output to snapshot", |
257 |
< |
@"OK", win); |
257 |
> |
nil, win); |
258 |
|
else |
259 |
|
{ |
260 |
|
NSData *TIFFdata; |
348 |
|
- (void) createThreads |
349 |
|
{ |
350 |
|
#ifdef USE_PTHREADS |
351 |
< |
[NSThread detachNewThreadSelector:(SEL)"" toTarget:nil withObject:nil]; // Make UI threadsafe |
351 |
> |
// Make UI threadsafe: |
352 |
> |
[NSThread detachNewThreadSelector:(SEL)"" toTarget:nil withObject:nil]; |
353 |
|
//emul = [[NNThread alloc] initWithAutoReleasePool]; |
354 |
|
#endif |
355 |
< |
emul = [[NNThread alloc] init]; |
356 |
< |
RTC = [[NNTimer alloc] init]; |
357 |
< |
redraw = [[NNTimer alloc] init]; |
358 |
< |
tick = [[NNTimer alloc] init]; |
359 |
< |
xPRAM = [[NNTimer alloc] init]; |
355 |
> |
emul = [NNThread new]; |
356 |
> |
RTC = [NNTimer new]; |
357 |
> |
redraw = [[NNTimer alloc] initWithAutoRelPool]; |
358 |
> |
tick = [NNTimer new]; |
359 |
> |
xPRAM = [NNTimer new]; |
360 |
|
|
361 |
|
[emul perform:@selector(emulThread) of:self]; |
362 |
|
[RTC repeat:@selector(RTCinterrupt) of:self |
391 |
|
[redraw invalidate]; [redraw release]; redraw = nil; |
392 |
|
[RTC invalidate]; [RTC release]; RTC = nil; |
393 |
|
[xPRAM invalidate]; [xPRAM release]; xPRAM = nil; |
348 |
– |
if ( uaeCreated ) |
349 |
– |
QuitEmuNoExit(); |
394 |
|
} |
395 |
|
|
396 |
|
- (void) emulThread |
397 |
|
{ |
398 |
< |
extern uint8 *RAMBaseHost, *ROMBaseHost; |
355 |
< |
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; |
356 |
< |
|
357 |
< |
// [screen allocBitmap]; // Do this first, because InitEmulator() calls VideoInit(), which needs the_bitmap. |
398 |
> |
NSAutoreleasePool *pool = [NSAutoreleasePool new]; |
399 |
|
|
400 |
< |
InitEmulator(); |
400 |
> |
if ( ! InitEmulator() ) |
401 |
> |
{ |
402 |
> |
[redraw suspend]; // Stop the barberpole |
403 |
|
|
404 |
< |
if ( RAMBaseHost == NULL || ROMBaseHost == NULL ) |
405 |
< |
ErrorSheet(@"Cannot start Emulator.", |
363 |
< |
@"Emulator memory not allocated", @"OK", win); |
404 |
> |
ErrorSheet(@"Cannot start Emulator", @"", @"Quit", win); |
405 |
> |
} |
406 |
|
else |
407 |
|
{ |
408 |
|
memcpy(lastXPRAM, XPRAM, XPRAM_SIZE); |
409 |
|
|
410 |
|
uaeCreated = YES; // Enable timers to access emulated Mac's memory |
411 |
|
|
412 |
< |
while ( screen == nil ) // If init sets running, but we are still loading from Nib? |
412 |
> |
while ( screen == nil ) // If we are still loading from Nib? |
413 |
|
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow: 1.0]]; |
414 |
|
|
415 |
< |
// [screen readyToDraw]; |
374 |
< |
[self runUpdate]; |
415 |
> |
[self runUpdate]; // Set the window close gadget to dimpled |
416 |
|
|
417 |
|
Start680x0(); // Start 68k and jump to ROM boot routine |
418 |
|
|
419 |
|
puts ("Emulator exited normally"); |
420 |
|
} |
421 |
|
|
381 |
– |
running = NO; |
382 |
– |
uaeCreated = NO; |
383 |
– |
[self runUpdate]; // Update button & dimple |
422 |
|
[pool release]; |
423 |
< |
[self exitThreads]; |
423 |
> |
QuitEmulator(); |
424 |
|
} |
425 |
|
|
426 |
|
- (void) RTCinterrupt |
427 |
|
{ |
428 |
< |
if ( uaeCreated ) |
429 |
< |
WriteMacInt32 (0x20c, TimerDateTime() ); // Update MacOS time |
428 |
> |
if ( ! uaeCreated ) |
429 |
> |
return; |
430 |
> |
|
431 |
> |
WriteMacInt32 (0x20c, TimerDateTime() ); // Update MacOS time |
432 |
> |
|
433 |
> |
SetInterruptFlag(INTFLAG_1HZ); |
434 |
> |
TriggerInterrupt(); |
435 |
|
} |
436 |
|
|
437 |
|
- (void) redrawScreen |
438 |
|
{ |
439 |
|
if ( display_type == DISPLAY_SCREEN ) |
440 |
|
{ |
441 |
< |
NSLog(@"Why was redrawScreen() called?"); |
441 |
> |
NSLog(@"We are in fullscreen mode - why was redrawScreen() called?"); |
442 |
|
return; |
443 |
|
} |
444 |
|
[barberPole animate:self]; // wobble the pole |
445 |
|
[screen setNeedsDisplay: YES]; // redisplay next time through runLoop |
446 |
|
// Or, use a direct method. e.g. |
447 |
< |
// [screen cgDrawInto: ...]; |
447 |
> |
// [screen display] or [screen cgDrawInto: ...]; |
448 |
|
} |
449 |
|
|
450 |
|
#include <main.h> // For #define INTFLAG_60HZ |
470 |
|
} |
471 |
|
} |
472 |
|
|
473 |
< |
@end |
473 |
> |
@end |