--- BasiliskII/src/MacOSX/Emulator.mm 2002/05/23 12:48:38 1.2 +++ BasiliskII/src/MacOSX/Emulator.mm 2004/05/25 05:26:41 1.9 @@ -2,9 +2,9 @@ * Emulator.mm - Class whose actions are attached to GUI widgets in a window, * used to control a single Basilisk II emulated Macintosh. * - * $Id: Emulator.mm,v 1.2 2002/05/23 12:48:38 nigel Exp $ + * $Id: Emulator.mm,v 1.9 2004/05/25 05:26:41 nigel Exp $ * - * Basilisk II (C) 1997-2002 Christian Bauer + * Basilisk II (C) 1997-2004 Christian Bauer * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -24,25 +24,25 @@ #import "Emulator.h" #import "EmulatorView.h" -@implementation Emulator - #import "sysdeps.h" // Types used in Basilisk C++ code #import "main_macosx.h" // Prototypes for QuitEmuNoExit() and InitEmulator() #import "misc_macosx.h" // Some other prototypes #import "video_macosx.h" // Some window/view globals -#import -#import -#import -#import +#import "adb.h" +#import "main.h" +#import "prefs.h" +#import "timer.h" -#undef check() // memory.h defines a check macro, which clashes with an OS X one? +#undef check // memory.h defines a check macro, clashes with an OS X one? #import -#define DEBUG 1 +#define DEBUG 0 #import +@implementation Emulator + // NSWindow method, which is invoked via delegation - (BOOL) windowShouldClose: (id)sender @@ -94,11 +94,8 @@ //[win setHasShadow: NO]; // This causes view & window to now be drawn correctly [win useOptimizedDrawing: YES]; -// [win center]; [win makeKeyAndOrderFront:self]; -// [self resizeWinToWidth:x Height:y]; - if ( redrawDelay ) [speed setFloatValue: 1.0 / redrawDelay]; else @@ -120,8 +117,6 @@ - (NSSlider *) speed { return speed; } - (NSWindow *) window { return win; } -//#define DEBUG 1 -//#include // Update some UI elements @@ -149,9 +144,33 @@ [self Resume: self]; } +#ifdef NIGEL +- (IBAction) EjectCD: (id)sender; +{ + NSString *path; + const char *cdrom = PrefsFindString("cdrom"); + + if ( cdrom ) + { + #include + #define KERNEL + #include + + struct statfs buf; + if ( fsstat(path, &buf) < 0 ) + return; + + path = [NSString stringWithCString: cdrom]; + + [[NSWorkspace sharedWorkspace] unmountAndEjectDeviceAtPath: path]; +// [path release]; + } +} +#endif + - (IBAction) Interrupt: (id)sender; { - WarningSheet (@"Interrupt action not yet supported", @"", @"OK", win); + WarningSheet (@"Interrupt action not yet supported", win); } - (IBAction) PowerKey: (id)sender; @@ -171,27 +190,45 @@ - (IBAction) Restart: (id)sender { + if ( ! running ) + { + running = YES; // Start emulator + [self runUpdate]; + [self Resume: nil]; + } + if ( running ) -// reset680x0(); +#ifdef UAE_CPU_HAS_RESET + reset680x0(); +#else { uaeCreated = NO; [redraw suspend]; NSLog (@"%s - uae_cpu reset not yet supported, will try to fake it", __PRETTY_FUNCTION__); -// [screen blacken]; - [screen setNeedsDisplay: YES]; + [screen clear]; + [screen display]; [emul terminate]; QuitEmuNoExit(); - emul = [[NNThread alloc] init]; + + // OK. We have killed & cleaned up. Now, start afresh: + #include + int argc = 0; + char **argv; + + PrefsInit(argc, argv); + SysInit(); + + emul = [NNThread new]; [emul perform:@selector(emulThread) of:self]; [emul start]; if ( display_type != DISPLAY_SCREEN ) [redraw resume]; - uaeCreated = YES; } +#endif } - (IBAction) Resume: (id)sender @@ -216,7 +253,7 @@ if ( screen == nil || uaeCreated == NO ) WarningSheet(@"The emulator has not yet started.", @"There is no screen output to snapshot", - @"OK", win); + nil, win); else { NSData *TIFFdata; @@ -310,14 +347,15 @@ uint8 lastXPRAM[XPRAM_SIZE]; // Copy of - (void) createThreads { #ifdef USE_PTHREADS - [NSThread detachNewThreadSelector:(SEL)"" toTarget:nil withObject:nil]; // Make UI threadsafe + // Make UI threadsafe: + [NSThread detachNewThreadSelector:(SEL)"" toTarget:nil withObject:nil]; //emul = [[NNThread alloc] initWithAutoReleasePool]; #endif - emul = [[NNThread alloc] init]; - RTC = [[NNTimer alloc] init]; - redraw = [[NNTimer alloc] init]; - tick = [[NNTimer alloc] init]; - xPRAM = [[NNTimer alloc] init]; + emul = [NNThread new]; + RTC = [NNTimer new]; + redraw = [[NNTimer alloc] initWithAutoReleasePool] + tick = [NNTimer new]; + xPRAM = [NNTimer new]; [emul perform:@selector(emulThread) of:self]; [RTC repeat:@selector(RTCinterrupt) of:self @@ -352,44 +390,36 @@ uint8 lastXPRAM[XPRAM_SIZE]; // Copy of [redraw invalidate]; [redraw release]; redraw = nil; [RTC invalidate]; [RTC release]; RTC = nil; [xPRAM invalidate]; [xPRAM release]; xPRAM = nil; - if ( uaeCreated ) - QuitEmuNoExit(); } - (void) emulThread { - extern uint8 *RAMBaseHost, *ROMBaseHost; - NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; - -// [screen allocBitmap]; // Do this first, because InitEmulator() calls VideoInit(), which needs the_bitmap. + NSAutoreleasePool *pool = [NSAutoreleasePool new]; - InitEmulator(); + if ( ! InitEmulator() ) + { + [redraw suspend]; // Stop the barberpole - if ( RAMBaseHost == NULL || ROMBaseHost == NULL ) - ErrorSheet(@"Cannot start Emulator.", - @"Emulator memory not allocated", @"OK", win); + ErrorSheet(@"Cannot start Emulator", @"", @"Quit", win); + } else { memcpy(lastXPRAM, XPRAM, XPRAM_SIZE); uaeCreated = YES; // Enable timers to access emulated Mac's memory - while ( screen == nil ) // If init sets running, but we are still loading from Nib? + while ( screen == nil ) // If we are still loading from Nib? [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow: 1.0]]; -// [screen readyToDraw]; - [self runUpdate]; + [self runUpdate]; // Set the window close gadget to dimpled Start680x0(); // Start 68k and jump to ROM boot routine puts ("Emulator exited normally"); } - running = NO; - uaeCreated = NO; - [self runUpdate]; // Update button & dimple [pool release]; - [self exitThreads]; + QuitEmulator(); } - (void) RTCinterrupt @@ -402,13 +432,13 @@ uint8 lastXPRAM[XPRAM_SIZE]; // Copy of { if ( display_type == DISPLAY_SCREEN ) { - NSLog(@"Why was redrawScreen() called?"); + NSLog(@"We are in fullscreen mode - why was redrawScreen() called?"); return; } [barberPole animate:self]; // wobble the pole [screen setNeedsDisplay: YES]; // redisplay next time through runLoop // Or, use a direct method. e.g. - // [screen cgDrawInto: ...]; + // [screen display] or [screen cgDrawInto: ...]; } #include // For #define INTFLAG_60HZ