Initial revision of Mac OS X port code. Uses Objective-C++. Needs Mac OS 10.1

This commit is contained in:
nigel 2002-03-16 04:01:09 +00:00
parent 496ab59297
commit a3051c90fe
53 changed files with 9165 additions and 0 deletions

View File

@ -0,0 +1,52 @@
How to build this source
------------------------
1) Install the OS X Development tools
Source should build on either 10.0 or 10.1
(If anyone wants a version that will compile on Public Beta, email me)
2) If grabbing this source from a tarball, put this MacOSX directory in
BasiliskII-1.0/src. Source is currently only compatible with 1.0 snapshot.
3) Open a Terminal, and cd to BasiliskII-1.0/src/MacOSX
If the source was grabbed from CVS, run the following commands:
ln -s /usr/libexec/config.guess .
ln -s /usr/libexec/config.sub .
ln -s ../Unix/acconfig.h .
ln -s ../Unix/install-sh .
4) type autoconf
Ignore the warning. autoconf should generate ./configure
5) type ./configure
This should generate a Makefile and some header files
6) type make
This should generate some symlinks, the uae_cpu emulator core's source,
and then the application.
* It is also possible to use the OS X integrated development environment
(i.e. the "Project Builder" IDE) to build the application, instead of make.
Instead of step 6) above, do this:
6) make ide
This should generate some symlinks and the uae_cpu emulator core's source,
and then open the IDE with the file BasiliskII.pbproj
7) From the Build menu, choose 'Build' or 'Build & Run'
This should build everything
* There is one file in the source, cpuemu.cpp, which takes _ages_ to
compile, particularly if optimisation is on. The Unix source splits the
file into 8 smaller parts to compile separately, but I didn't find that
really helped on OS X. Basically, you just have to be patient.

View File

@ -0,0 +1,182 @@
// !$*UTF8*$!
{
00ED5A1AFF9F1BC995877872 = {
uiCtxt = {
sepNavWindowFrame = "{{38, 218}, {750, 502}}";
};
};
00F23976FFC35BA495877872 = {
uiCtxt = {
sepNavWindowFrame = "{{-2, 84}, {519, 662}}";
};
};
00F71683FF9E7CC595877872 = {
activeArgIndex = 2147483647;
argumentStrings = (
);
debuggerPlugin = GDBDebugging;
dylibVariantSuffix = "";
enableDebugStr = 1;
environmentEntries = (
{
active = NO;
name = MallocHelp;
value = YES;
},
);
isa = PBXExecutable;
shlibInfoDictList = (
);
sourceDirectories = (
);
};
0130A85800A96A627F000001 = {
uiCtxt = {
sepNavWindowFrame = "{{61, 197}, {750, 502}}";
};
};
01BDE8DE0078384A7F000001 = {
uiCtxt = {
sepNavWindowFrame = "{{38, 218}, {750, 502}}";
};
};
18AB34C500AA6EAE7F000001 = {
uiCtxt = {
sepNavWindowFrame = "{{84, 176}, {750, 502}}";
};
};
1A5BA122008C02B47F000001 = {
uiCtxt = {
sepNavWindowFrame = "{{38, 218}, {750, 502}}";
};
};
29B97313FDCFA39411CA2CEA = {
activeBuildStyle = 011D89AB0071AA4C7F000001;
activeTarget = 29B97326FDCFA39411CA2CEA;
addToTargets = (
29B97326FDCFA39411CA2CEA,
);
breakpoints = (
);
perUserDictionary = {
PBXWorkspaceConfiguration = {
ContentSize = "{795, 642}";
LeftSlideOut = {
ActiveTab = 0;
Frame = "{{0, 23}, {795, 619}}";
Split0 = {
Frame = "{{258, 0}, {537, 619}}";
Split0 = {
Frame = "{{0, 25}, {537, 594}}";
};
SplitCount = 1;
Tab0 = {
Debugger = {
ActiveTab = 0;
Frame = "{{0, 0}, {537, 241}}";
Split0 = {
Frame = "{{0, 75}, {537, 166}}";
Split0 = {
Frame = "{{0, 0}, {212, 166}}";
};
Split1 = {
Frame = "{{221, 0}, {316, 166}}";
};
SplitCount = 2;
};
SplitCount = 1;
Tab0 = {
Frame = "{{0, 0}, {537, 50}}";
};
Tab1 = {
Frame = "{{0, 0}, {657, 50}}";
};
TabCount = 2;
};
Frame = "{{0, 0}, {537, 241}}";
LauncherConfigVersion = 4;
};
Tab1 = {
Frame = "{{0, 0}, {537, 241}}";
LauncherConfigVersion = 3;
Runner = {
Frame = "{{0, 0}, {537, 241}}";
};
};
Tab2 = {
BuildMessageFrame = "{{0, 0}, {539, 120}}";
BuildTranscriptFrame = "{{0, 129}, {539, 114}}";
Frame = "{{0, 0}, {537, 241}}";
};
Tab3 = {
Frame = "{{0, 0}, {537, 241}}";
};
TabCount = 4;
};
SplitCount = 1;
Tab0 = {
Frame = "{{0, 0}, {233, 619}}";
};
Tab1 = {
ClassesFrame = "{{0, 0}, {202, 56}}";
Frame = "{{0, 0}, {200, 100}}";
MembersFrame = "{{0, 65}, {202, 35}}";
OptionsSetName = "Hierarchy, all classes";
};
Tab2 = {
Frame = "{{0, 0}, {200, 100}}";
};
Tab3 = {
Frame = "{{0, 0}, {200, 619}}";
Split0 = {
Frame = "{{0, 0}, {200, 301}}";
};
Split1 = {
Frame = "{{0, 310}, {200, 309}}";
};
SplitCount = 2;
};
Tab4 = {
Frame = "{{0, 0}, {250, 616}}";
};
TabCount = 5;
};
};
};
wantsIndex = 1;
wantsSCM = -1;
};
29B97326FDCFA39411CA2CEA = {
activeExec = 0;
targetExecs = {
macosx = (
00F71683FF9E7CC595877872,
);
};
};
F50E39510187F78A01877872 = {
uiCtxt = {
sepNavWindowFrame = "{{15, 239}, {750, 502}}";
};
};
F5495FEC018CD1890116CB19 = {
uiCtxt = {
sepNavWindowFrame = "{{38, 218}, {750, 502}}";
};
};
F59F459B020D559E01A80001 = {
uiCtxt = {
sepNavWindowFrame = "{{155, 209}, {750, 502}}";
};
};
F5B887500207D11D01A80001 = {
uiCtxt = {
sepNavWindowFrame = "{{0, 45}, {554, 701}}";
};
};
F66A596A021B9B1701877872 = {
uiCtxt = {
sepNavWindowFrame = "{{15, 239}, {750, 502}}";
};
};
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
Basilisk II is an open source, 68k Mac. emulator.
<BR>
It enables you to run 68k MacOS software on your computer, even if you are using a different operating system (however, you do need a copy of the MacOS and a Macintosh ROM image to use it).
<CENTER>
<A HREF="http://www.uni-mainz.de/~bauec002/B2Main.html"> The Official Basilisk II Home Page</A>
</CENTER>
<RIGHT>
MacOS X (native windowing) port
<BR>
by Nigel Pearson &lt;nigel@ind.tansu.com.au&gt;
</RIGHT>

View File

@ -0,0 +1,80 @@
/*
* Emulator.h - Class whose actions are attached GUI widgets in a window,
* used to control a single Basilisk II emulated Macintosh.
*
* $Id$
*
* Basilisk II (C) 1997-2001 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#import <Cocoa/Cocoa.h>
#import "EmulatorView.h"
#import "NNThread.h"
@interface Emulator : NSObject
{
NNThread *emul; // Run emulThread
NNTimer *RTC, // Invoke RTCinterrupt
*redraw, // Invoke redrawScreen
*tick, // Invoke tickInterrupt
*xPRAM; // Invoke xPRAMbackup
BOOL uaeCreated, // Has thread created the emulator environment?
running; // Is the emulator currently grinding away?
float redrawDelay; // Seconds until next screen update
// UI elements that this class changes the state of
IBOutlet NSProgressIndicator *barberPole;
IBOutlet NSButton *runOrPause;
IBOutlet EmulatorView *screen;
IBOutlet NSSlider *speed;
IBOutlet NSWindow *win;
}
// The following allow the Controller and PrefsEditor classes to access our internal data
- (BOOL) isRunning;
- (BOOL) uaeCreated;
- (EmulatorView *) screen;
- (NSSlider *) speed;
- (NSWindow *) window;
- (void) runUpdate; // Update some UI elements
- (IBAction) Benchmark: (id)sender;
- (IBAction) Interrupt: (id)sender;
- (IBAction) Suspend: (id)sender;
- (IBAction) PowerKey: (id)sender;
- (IBAction) Restart: (id)sender;
- (IBAction) Snapshot: (id)sender;
- (IBAction) SpeedChange: (NSSlider *)sender;
- (IBAction) Resume: (id)sender;
- (IBAction) Terminate: (id)sender;
- (IBAction) ToggleState: (NSButton *)sender;
- (IBAction) ZapPRAM: (id)sender;
- (void) createThreads;
- (void) exitThreads;
- (void) emulThread; // Thread for processor emulator
- (void) RTCinterrupt; // Emulator real time clock update
- (void) redrawScreen; // Draw emulator screen in window
- (void) tickInterrupt; // Draw emulator screen in window
- (void) xPRAMbackup; // PRAM watchdog
@end

View File

@ -0,0 +1,430 @@
/*
* Emulator.mm - Class whose actions are attached to GUI widgets in a window,
* used to control a single Basilisk II emulated Macintosh.
*
* $Id$
*
* Basilisk II (C) 1997-2002 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#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 <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?
#import <cpu_emulation.h>
#define DEBUG 1
#import <debug.h>
// NSWindow method, which is invoked via delegation
- (BOOL) windowShouldClose: (id)sender
{
if ( uaeCreated )
{
NSLog(@"windowShouldClose returning NO");
return NO; // Should initiate poweroff and return NSTerminateLater ?
}
NSLog(@"windowShouldClose returning YES");
return YES;
}
// Default methods
- (Emulator *) init
{
int frameSkip;
self = [super init];
running = NO; // Save churn when application loads
// running = YES;
uaeCreated = NO;
frameSkip = PrefsFindInt32("frameskip");
if ( frameSkip )
redrawDelay = frameSkip / 60.0;
else
redrawDelay = 0.0;
// We do this so that we can work out if we are in full screen mode:
parse_screen_prefs(PrefsFindString("screen"));
[self createThreads];
return self;
}
- (void) awakeFromNib
{
the_win = win; // Set global for access by Basilisk C++ code
[win setDelegate: self]; // Enable windowShouldClose calling
// Try to speed up everything
//[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
[speed setFloatValue: 60.0];
if ( runOrPause == nil )
NSLog(@"%s - runOrPause button pointer is nil!", __PRETTY_FUNCTION__);
[self runUpdate];
}
// Helpers which other classes use to access our private stuff
- (BOOL) isRunning { return running; }
- (BOOL) uaeCreated { return uaeCreated; }
- (EmulatorView *) screen { return screen; }
- (NSSlider *) speed { return speed; }
- (NSWindow *) window { return win; }
//#define DEBUG 1
//#include <debug.h>
// Update some UI elements
- (void) runUpdate
{
if ( running )
[runOrPause setState: NSOnState]; // Running. Change button label to 'Pause'
else
[runOrPause setState: NSOffState]; // Paused. Change button label to 'Run'
[win setDocumentEdited: uaeCreated]; // Set the little dimple in the close button
}
// Methods invoked by buttons & menu items
- (IBAction) Benchmark: (id)sender;
{
BOOL wasRunning = running;
if ( running )
[self Suspend: self];
[screen benchmark];
if ( wasRunning )
[self Resume: self];
}
- (IBAction) Interrupt: (id)sender;
{
WarningSheet (@"Interrupt action not yet supported", @"", @"OK", win);
}
- (IBAction) PowerKey: (id)sender;
{
if ( uaeCreated ) // If Mac has started
{
ADBKeyDown(0x7f); // Send power key, which is also
ADBKeyUp(0x7f); // called ADB_RESET or ADB_POWER
}
else
{
running = YES; // Start emulator
[self runUpdate];
[self Resume: nil];
}
}
- (IBAction) Restart: (id)sender
{
if ( running )
// reset680x0();
{
uaeCreated = NO;
[redraw suspend];
NSLog (@"%s - uae_cpu reset not yet supported, will try to fake it",
__PRETTY_FUNCTION__);
// [screen blacken];
[screen setNeedsDisplay: YES];
[emul terminate]; QuitEmuNoExit();
emul = [[NNThread alloc] init];
[emul perform:@selector(emulThread) of:self];
[emul start];
if ( display_type != DISPLAY_SCREEN )
[redraw resume];
uaeCreated = YES;
}
}
- (IBAction) Resume: (id)sender
{
[RTC resume];
[emul resume];
if ( display_type != DISPLAY_SCREEN )
[redraw resume];
[tick resume];
[xPRAM resume];
}
- (IBAction) Snapshot: (id) sender
{
if ( screen == nil || uaeCreated == NO )
WarningSheet(@"The emulator has not yet started.",
@"There is no screen output to snapshot",
@"OK", win);
else
{
NSData *TIFFdata;
[self Suspend: self];
TIFFdata = [screen TIFFrep];
if ( TIFFdata == nil )
NSLog(@"%s - Unable to convert Basilisk screen to a TIFF representation",
__PRETTY_FUNCTION__);
else
{
NSSavePanel *sp = [NSSavePanel savePanel];
[sp setRequiredFileType:@"tiff"];
if ( [sp runModalForDirectory:NSHomeDirectory()
file:@"B2-screen-snapshot.tiff"] == NSOKButton )
if ( ! [TIFFdata writeToFile:[sp filename] atomically:YES] )
NSLog(@"%s - Could not write TIFF data to file @%",
__PRETTY_FUNCTION__, [sp filename]);
}
if ( running )
[self Resume: self];
}
}
- (IBAction) SpeedChange: (NSSlider *)sender
{
float frequency = [sender floatValue];
[redraw suspend];
if ( frequency == 0.0 )
redrawDelay = 0.0;
else
{
frequencyToTickDelay(frequency);
redrawDelay = 1.0 / frequency;
[redraw changeIntervalTo: (int)(redrawDelay * 1e6)
units: NNmicroSeconds];
if ( running && display_type != DISPLAY_SCREEN )
[redraw resume];
}
}
- (IBAction) Suspend: (id)sender
{
[RTC suspend];
[emul suspend];
[redraw suspend];
[tick suspend];
[xPRAM suspend];
}
- (IBAction) ToggleState: (NSButton *)sender
{
running = [sender state]; // State of the toggled NSButton
if ( running )
[self Resume: nil];
else
[self Suspend: nil];
}
- (IBAction) Terminate: (id)sender;
{
[self exitThreads];
[win performClose: self];
}
#include <xpram.h>
#define XPRAM_SIZE 256
uint8 lastXPRAM[XPRAM_SIZE]; // Copy of PRAM
- (IBAction) ZapPRAM: (id)sender;
{
memset(XPRAM, 0, XPRAM_SIZE);
memset(lastXPRAM, 0, XPRAM_SIZE);
ZapPRAM();
}
//
// Threads, Timers and stuff to manage them:
//
- (void) createThreads
{
#ifdef USE_PTHREADS
[NSThread detachNewThreadSelector:(SEL)"" toTarget:nil withObject:nil]; // Make UI threadsafe
//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 perform:@selector(emulThread) of:self];
[RTC repeat:@selector(RTCinterrupt) of:self
every:1
units:NNseconds];
[redraw repeat:@selector(redrawScreen) of:self
every:(int)(1000*redrawDelay)
units:NNmilliSeconds];
[tick repeat:@selector(tickInterrupt) of:self
every:16625
units:NNmicroSeconds];
[xPRAM repeat:@selector(xPRAMbackup) of:self
every:60
units:NNseconds];
if ( running ) // Start emulator, then threads in most economical order
{
[emul start];
[xPRAM start];
[RTC start];
if ( display_type != DISPLAY_SCREEN )
[redraw start];
[tick start];
}
}
- (void) exitThreads
{
running = NO;
[emul terminate]; [emul release]; emul = nil;
[tick invalidate]; [tick release]; tick = nil;
[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.
InitEmulator();
if ( RAMBaseHost == NULL || ROMBaseHost == NULL )
ErrorSheet(@"Cannot start Emulator.",
@"Emulator memory not allocated", @"OK", 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?
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow: 1.0]];
// [screen readyToDraw];
[self runUpdate];
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];
}
- (void) RTCinterrupt
{
if ( uaeCreated )
WriteMacInt32 (0x20c, TimerDateTime() ); // Update MacOS time
}
- (void) redrawScreen
{
if ( display_type == DISPLAY_SCREEN )
{
NSLog(@"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: ...];
}
#include <main.h> // For #define INTFLAG_60HZ
#include <rom_patches.h> // For ROMVersion
#include "macos_util_macosx.h" // For HasMacStarted()
- (void) tickInterrupt
{
if ( ROMVersion != ROM_VERSION_CLASSIC || HasMacStarted() )
{
SetInterruptFlag (INTFLAG_60HZ);
TriggerInterrupt ();
}
}
- (void) xPRAMbackup
{
if ( uaeCreated &&
memcmp(lastXPRAM, XPRAM, XPRAM_SIZE) ) // if PRAM changed from copy
{
memcpy (lastXPRAM, XPRAM, XPRAM_SIZE); // re-copy
SaveXPRAM (); // and save to disk
}
}
@end

View File

@ -0,0 +1,94 @@
/*
* EmulatorView.h - Custom NSView for Basilisk II window input & output
*
* $Id$
*
* Basilisk II (C) 1997-2002 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifdef NSBITMAP
#import <AppKit/NSBitmapImageRep.h>
#endif
#import <AppKit/NSView.h>
@interface EmulatorView : NSView
{
#ifdef CGIMAGEREF
CGImageRef bitmap;
#endif
#ifdef NSBITMAP
NSBitmapImageRep *bitmap;
#endif
#ifdef CGDRAWBITMAP
void *bitmap;
short bps, spp, bpp;
int bytesPerRow;
BOOL isPlanar, hasAlpha;
#endif
short x, y;
BOOL drawView; // Set when the bitmap is all set up
// and ready to display
}
- (void) benchmark;
- (NSData *) TIFFrep; // Used for snapshot function
// Enable display of, and drawing into, the view
#ifdef NSBITMAP
- (void) readyToDraw: (NSBitmapImageRep *) theBitmap
imageWidth: (short) width
imageHeight: (short) height;
#endif
#ifdef CGIMAGEREF
- (void) readyToDraw: (CGImageRef) image
imageWidth: (short) width
imageHeight: (short) height;
#endif
#ifdef CGDRAWBITMAP
- (void) readyToDraw: (void *) theBitmap
width: (short) width
height: (short) height
bps: (short) bitsPerSample
spp: (short) samplesPerPixel
bpp: (short) bitsPerPixel
bpr: (int) bpr
isPlanar: (BOOL) planar
hasAlpha: (BOOL) alpha;
#endif
- (void) disableDrawing;
- (short) width;
- (short) height;
- (BOOL) mouseInView: (NSEvent *) event;
- (BOOL) mouseInView;
- (BOOL) processMouseMove: (NSEvent *) event;
#ifdef CGDRAWBITMAP
- (void) CGDrawBitmap;
#endif
#ifdef CGIMAGEREF
void cgDrawInto(NSRect rect, CGImageRef bitmap);
#endif
@end

View File

@ -0,0 +1,417 @@
/*
* EmulatorView.mm - Custom NSView for Basilisk II graphics output
*
* $Id$
*
* Basilisk II (C) 1997-2002 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#import "sysdeps.h" // Types used in Basilisk C++ code,
#define DEBUG 0
#import <debug.h>
#import <Cocoa/Cocoa.h>
#import "main_macosx.h" // For WarningAlert() et al prototypes
#import "misc_macosx.h" // For InfoSheet() prototype
#import "video_macosx.h" // For init_* globals, and bitmap drawing strategy
#import "EmulatorView.h"
@implementation EmulatorView
//
// Standard NSView methods that we override
//
- (id) initWithFrame: (NSRect) frameRect
{
self = [super initWithFrame: frameRect];
output = self; // Set global for access by Basilisk C++ code
// bitmap = nil; // Set by readyToDraw:
drawView = NO; // Disable drawing until later
#ifdef SAVE_GSTATE
[self allocateGState];
#endif
return self;
}
- (void) dealloc
{
#ifdef SAVE_GSTATE
[self releaseGState];
#endif
[super dealloc];
}
// Mouse click in this window. If window is not active, should click be passed to this view?
- (BOOL) acceptsFirstMouse: (NSEvent *) event
{
return [self mouseInView];
}
/*****
- (BOOL) acceptsFirstResponder
{
// return YES;
return [self mouseInView];
}
*****/
#include <adb.h>
static int prevFlags;
- (void) flagsChanged: (NSEvent *) event
{
int flags = [event modifierFlags];
if ( (flags & NSAlphaShiftKeyMask) != (prevFlags & NSAlphaShiftKeyMask) )
if ( flags & NSAlphaShiftKeyMask )
ADBKeyDown(0x39); // CAPS_LOCK
else
ADBKeyUp(0x39);
if ( (flags & NSShiftKeyMask) != (prevFlags & NSShiftKeyMask) )
if ( flags & NSShiftKeyMask )
ADBKeyDown(0x38); // SHIFT_LEFT
else
ADBKeyUp(0x38);
if ( (flags & NSControlKeyMask) != (prevFlags & NSControlKeyMask) )
if ( flags & NSControlKeyMask )
ADBKeyDown(0x36); // CTL_LEFT
else
ADBKeyUp(0x36);
if ( (flags & NSAlternateKeyMask) != (prevFlags & NSAlternateKeyMask) )
if ( flags & NSAlternateKeyMask )
ADBKeyDown(0x3a); // OPTION_LEFT
else
ADBKeyUp(0x3a);
if ( (flags & NSCommandKeyMask) != (prevFlags & NSCommandKeyMask) )
if ( flags & NSCommandKeyMask )
ADBKeyDown(0x37); // APPLE_LEFT
else
ADBKeyUp(0x37);
prevFlags = flags;
}
- (BOOL) mouseInView: (NSEvent *) event
{
NSPoint loc = [event locationInWindow];
NSRect box = [self frame];
D(NSLog (@"%s - loc.x=%f, loc.y=%f, box.origin.x=%f, box.origin.y=%f",
__PRETTY_FUNCTION__, loc.x, loc.y, box.origin.x, box.origin.y));
return [self mouse: loc inRect: box];
}
- (BOOL) mouseInView
{
NSPoint loc = [[self window] mouseLocationOutsideOfEventStream];
NSRect box = [self frame];
D(NSLog (@"%s - loc.x=%f, loc.y=%f, box.origin.x=%f, box.origin.y=%f",
__PRETTY_FUNCTION__, loc.x, loc.y, box.origin.x, box.origin.y));
return [self mouse: loc inRect: box];
}
//
// Custom methods
//
- (void) benchmark
{
int i;
float seconds;
NSDate *startDate;
if ( ! drawView )
return;
drawView = NO;
[self lockFocus];
startDate = [NSDate date];
for (i = 1; i < 300; ++i )
#ifdef NSBITMAP
[bitmap draw];
#endif
#ifdef CGIMAGEREF
cgDrawInto([self bounds], bitmap);
#endif
#ifdef CGDRAWBITMAP
[self CGDrawBitmap];
#endif
seconds = -[startDate timeIntervalSinceNow];
[self unlockFocus];
drawView = YES;
InfoSheet(@"Benchmark run. 300 frames.",
[NSString stringWithFormat:
@"%.2f seconds, %.3f frames per second", seconds, i/seconds],
@"Thanks", [self window]);
}
// Return a TIFF for a snapshot of the screen image
- (NSData *) TIFFrep
{
#ifdef NSBITMAP
return [bitmap TIFFRepresentation];
#else
WarningAlert("How do I get a TIFF from a CGImageRef?");
#endif
return nil;
}
// Enable display of, and drawing into, the view
#ifdef NSBITMAP
- (void) readyToDraw: (NSBitmapImageRep *) theBitmap
imageWidth: (short) width
imageHeight: (short) height
{
bitmap = theBitmap;
#endif
#ifdef CGIMAGEREF
- (void) readyToDraw: (CGImageRef) image
imageWidth: (short) width
imageHeight: (short) height
{
bitmap = image;
#endif
#ifdef CGDRAWBITMAP
- (void) readyToDraw: (void *) theBitmap
width: (short) width
height: (short) height
bps: (short) bitsPerSample
spp: (short) samplesPerPixel
bpp: (short) bitsPerPixel
bpr: (int) bpr
isPlanar: (BOOL) planar
hasAlpha: (BOOL) alpha
{
bitmap = theBitmap;
bps = bitsPerSample;
spp = samplesPerPixel;
bpp = bitsPerPixel;
bytesPerRow = bpr;
isPlanar = planar;
hasAlpha = alpha;
#endif
x = width, y = height;
drawView = YES;
[[self window] setAcceptsMouseMovedEvents: YES];
// [[self window] setInitialFirstResponder: self];
[[self window] makeFirstResponder: self];
}
- (void) disableDrawing
{
drawView = NO;
}
- (short) width
{
return (short)[self bounds].size.width;
}
- (short) height
{
return (short)[self bounds].size.height;
}
- (BOOL) isOpaque
{
return drawView;
}
- (BOOL) processKeyEvent: (NSEvent *) event
{
if ( [self acceptsFirstMouse: event] || FULLSCREEN )
if ( [event isARepeat] )
return NO;
else
return YES;
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
return NO;
}
- (void) keyDown: (NSEvent *) event
{
if ( [self processKeyEvent: event] )
ADBKeyDown([event keyCode]);
}
- (void) keyUp: (NSEvent *) event
{
if ( [self processKeyEvent: event] )
ADBKeyUp([event keyCode]);
}
static NSPoint mouse; // Previous/current mouse location
- (BOOL) processMouseMove: (NSEvent *) event
{
NSPoint locInView;
if ( FULLSCREEN )
locInView = [NSEvent mouseLocation];
else
locInView = [self convertPoint: [event locationInWindow] fromView:nil];
if ( NSEqualPoints(locInView, mouse) )
return NO;
mouse = locInView;
if ( FULLSCREEN )
{
ADBMouseMoved((int)mouse.x, screen_height - (int)mouse.y);
return YES;
}
#ifdef CAN_RESIZE_VIEW
int mouseY = y - y * mouse.y / [self height];
int mouseX = x * mouse.x / [self width];
#else
int mouseY = y - (int) mouse.y;
int mouseX = (int) mouse.x;
#endif
ADBMouseMoved(mouseX, mouseY);
return YES;
}
- (void) mouseDown: (NSEvent *) event
{
[self processMouseMove: event];
ADBMouseDown(0);
}
- (void) mouseDragged: (NSEvent *) event
{
[self processMouseMove: event];
}
- (void) mouseMoved: (NSEvent *) event
{
#if DEBUG
if ( ! [self mouseInView] )
{
NSLog (@"%s - Received event while outside of view", __PRETTY_FUNCTION__);
return;
}
#endif
[self processMouseMove: event];
}
- (void) mouseUp: (NSEvent *) event
{
[self processMouseMove: event];
ADBMouseUp(0);
}
#if DEBUG
- (void) randomise // Draw some coloured snow in the bitmap
{
unsigned char *pixel;
for ( int i = 0; i < 1000; ++i )
{
pixel = [bitmap bitmapData]
+ (int) (1.0 * [bitmap bytesPerRow] * 342 //[bitmap height]
* rand() / RAND_MAX);
*pixel = (unsigned char) (256.0 * rand() / RAND_MAX);
}
}
#endif
- (void) drawRect: (NSRect) rect
{
if ( ! drawView ) // If the emulator is still being setup,
return; // we do not want to draw
#if DEBUG
NSLog(@"In drawRect");
[self randomise];
#endif
#ifdef NSBITMAP
NSRectClip(rect);
[bitmap draw];
#endif
#ifdef CGIMAGEREF
cgDrawInto(rect, bitmap);
#endif
#ifdef CGDRAWBITMAP
[self CGDrawBitmap];
#endif
}
//
// Extra drawing stuff
//
#ifdef CGDRAWBITMAP
extern "C" void CGDrawBitmap();
- (void) CGDrawBitmap
{
CGContextRef cgContext = [[NSGraphicsContext currentContext]
graphicsPort];
NSRect rect = [self bounds];
CGRect cgRect = {
{rect.origin.x, rect.origin.y},
{rect.size.width, rect.size.height}
};
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGContextSetShouldAntialias(cgContext, NO); // Seems to have no effect?
CGDrawBitmap(cgContext, cgRect, x, y, bps, spp, bpp,
bytesPerRow, isPlanar, hasAlpha, colourSpace, &bitmap);
}
#endif
#ifdef CGIMAGEREF
void
cgDrawInto(NSRect rect, CGImageRef bitmap)
{
CGContextRef cgContext = [[NSGraphicsContext currentContext]
graphicsPort];
CGRect cgRect = {
{rect.origin.x, rect.origin.y},
{rect.size.width, rect.size.height}
};
CGContextSetShouldAntialias(cgContext, NO); // Seems to have no effect?
CGContextDrawImage(cgContext, cgRect, bitmap);
}
#endif
@end

View File

@ -0,0 +1,3 @@
/* Localized versions of Info.plist keys */
NSHumanReadableCopyright = "Copyright © 1997-2002 Christian Bauer et al. Freely distributable under the terms of the GNU General Public License.";

View File

@ -0,0 +1,118 @@
{
IBClasses = (
{
ACTIONS = {NewEmulator = id; PauseAll = id; RunAll = id; TerminateAll = id; };
CLASS = Controller;
LANGUAGE = ObjC;
OUTLETS = {theEmulator = id; thePrefsEditor = id; };
SUPERCLASS = NSApplication;
},
{
ACTIONS = {
Benchmark = id;
Interrupt = id;
PowerKey = id;
Restart = id;
Resume = id;
Snapshot = id;
SpeedChange = id;
Suspend = id;
Terminate = id;
ToggleState = id;
ZapPRAM = id;
};
CLASS = Emulator;
LANGUAGE = ObjC;
OUTLETS = {barberPole = id; runOrPause = id; screen = id; speed = id; win = id; };
SUPERCLASS = NSObject;
},
{CLASS = EmulatorView; LANGUAGE = ObjC; SUPERCLASS = NSView; },
{
ACTIONS = {
Interrupt = id;
PowerKey = id;
Restart = id;
Resume = id;
Snapshot = id;
Suspend = id;
Terminate = id;
ZapPRAM = id;
};
CLASS = FirstResponder;
LANGUAGE = ObjC;
SUPERCLASS = NSObject;
},
{
ACTIONS = {
AddSCSI = id;
AddVolume = id;
BrowseExtFS = id;
BrowseROM = id;
ChangeBootFrom = id;
ChangeCPU = id;
ChangeDisableCD = id;
ChangeDisableSound = id;
ChangeFPU = id;
ChangeModel = id;
ChangeScreen = id;
CreateVolume = id;
DeleteVolume = id;
EditBytes = id;
EditDelay = id;
EditEtherNetDevice = id;
EditExtFS = id;
EditFrequency = id;
EditMB = id;
EditModemDevice = id;
EditPrinterDevice = id;
EditROMpath = id;
RemoveSCSI = id;
RemoveVolume = id;
ResetPrefs = id;
SavePrefs = id;
ShowPrefs = id;
};
CLASS = PrefsEditor;
LANGUAGE = ObjC;
OUTLETS = {
CPU68000 = id;
CPU68020 = id;
CPU68030 = id;
CPU68040 = id;
FPU = id;
IIci = id;
MB = id;
ROMfile = id;
SCSIdisks = id;
bootFromAny = id;
bootFromCD = id;
bytes = id;
classic = id;
delay = id;
depth = id;
disableCD = id;
disableSound = id;
diskImages = id;
emuFreq = id;
emuWin = id;
etherNet = id;
extFS = id;
frequency = id;
height = id;
modem = id;
newVolumeSize = id;
newVolumeView = id;
openGL = id;
panel = id;
printer = id;
quadra900 = id;
screen = id;
theEmulator = id;
width = id;
window = id;
};
SUPERCLASS = NSObject;
}
);
IBVersion = 1;
}

View File

@ -0,0 +1,45 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
<key>IBDocumentLocation</key>
<string>3 11 521 240 0 4 1152 742 </string>
<key>IBFramework Version</key>
<string>219.0</string>
<key>IBMainMenuLocation</key>
<string>0 702 365 44 0 0 1024 746 </string>
<key>IBSystem Version</key>
<string>5Q45</string>
<key>IBUserGuides</key>
<dict>
<key>About</key>
<dict>
<key>guideLocations</key>
<array/>
<key>guidesLocked</key>
<string>NO</string>
</dict>
<key>Prefs</key>
<dict>
<key>guideLocations</key>
<array/>
<key>guidesLocked</key>
<string>NO</string>
</dict>
<key>VolumeSize</key>
<dict>
<key>guideLocations</key>
<array/>
<key>guidesLocked</key>
<string>NO</string>
</dict>
<key>Window</key>
<dict>
<key>guideLocations</key>
<array/>
<key>guidesLocked</key>
<string>NO</string>
</dict>
</dict>
</dict>
</plist>

Binary file not shown.

View File

@ -0,0 +1,176 @@
# MacOS X makefile for Basilisk II. Slightly based on the Unix one
## System specific configuration
@SET_MAKE@
SHELL = /bin/sh
CC = @CC@
CXX = @CXX@
CFLAGS = @CFLAGS@
CXXFLAGS = @CXXFLAGS@
CPPFLAGS = @CPPFLAGS@ -I../include -I. -I../uae_cpu
DEFS = @DEFS@ @DEFINES@ -D_REENTRANT
LDFLAGS = @LDFLAGS@
LIBS = @LIBS@
## Files
OBJ_DIR = build
GENSRCS = user_strings_unix.h cpudefs.cpp cpuemu.cpp cpustbl.cpp cputbl.h \
README.txt
SRCS = BasiliskII.icns Controller.h Controller.mm Credits.html \
Emulator.h Emulator.mm EmulatorView.h EmulatorView.mm English.lproj \
NNThread.h NNThread.m PrefsEditor.h PrefsEditor.mm \
ToDo.html Versions.html \
audio_macosx.cpp extfs_macosx.mm macos_util_macosx.h main_macosx.h \
main_macosx.mm misc_macosx.h misc_macosx.mm prefs_macosx.cpp \
sysdeps.h video_macosx.mm video_macosx.h
APP = $(OBJ_DIR)/BasiliskII.app
## Rules
.PHONY: mostlyclean clean distclean depend dep
.SUFFIXES:
.SUFFIXES: .c .cpp .s .o .h
all: $(APP)
ide: $(OBJ_DIR) $(GENSRCS) $(SRCS)
open BasiliskII.pbproj
test: $(APP)
open $(APP)
$(OBJ_DIR)::
@[ -d $(OBJ_DIR) ] || mkdir $(OBJ_DIR) > /dev/null 2>&1
$(APP): $(OBJ_DIR) $(GENSRCS) $(SRCS)
pbxbuild -buildstyle Deployment
# pbxbuild
README.txt : ../../README
ln -s $< $@
user_strings_unix.h : ../Unix/user_strings_unix.h
ln -s $< $@
mostlyclean:
rm -fr English.lproj/*~* $(OBJ_DIR)/* core* *.core *~ *.bak
clean: mostlyclean
rm -f $(GENSRCS)
rm -f cpudefs.cpp cputmp*.s cpufast*.s cpustbl.cpp
distclean: clean
rm -fr $(OBJ_DIR)
rm -f config.cache config.log config.status config.h
rm -f configure
rm -f Makefile
$(OBJ_DIR)/build68k: ../uae_cpu/build68k.c
$(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) $(LDFLAGS) $< -o $@
$(OBJ_DIR)/cpuopti: ../uae_cpu/cpuopti.c
$(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) $(LDFLAGS) $< -o $@
#$(OBJ_DIR)/gencpu: cpudefs.cpp ../uae_cpu/gencpu.c ../uae_cpu/readcpu.cpp
# $(CXX) $(CPPFLAGS) $(DEFS) $(CFLAGS) $(CXXFLAGS) $(LDFLAGS) $< -o $@
$(OBJ_DIR)/gencpu: $(OBJ_DIR)/gencpu.o $(OBJ_DIR)/readcpu.o $(OBJ_DIR)/cpudefs.o
$(CC) $(LDFLAGS) $^ -o $@
$(OBJ_DIR)/gencpu.o : ../uae_cpu/gencpu.c
$(CC) $(CPPFLAGS) $(DEFS) $(CFLAGS) -c $< -o $@
$(OBJ_DIR)/readcpu.o: ../uae_cpu/readcpu.cpp
$(CXX) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) -c $< -o $@
$(OBJ_DIR)/cpudefs.o: cpudefs.cpp
$(CXX) $(CPPFLAGS) $(DEFS) $(CXXFLAGS) -c $< -o $@
cpudefs.cpp: $(OBJ_DIR)/build68k ../uae_cpu/table68k
$(OBJ_DIR)/build68k < ../uae_cpu/table68k > $@
cpuemu.cpp cpustbl.cpp cputbl.h: $(OBJ_DIR)/gencpu
$<
$(OBJ_DIR)/cpuemu1.o: cpuemu.cpp
$(CXX) $(CPPFLAGS) $(DEFS) -DPART_1 $(CXXFLAGS) -c $< -o $@
$(OBJ_DIR)/cpuemu2.o: cpuemu.cpp
$(CXX) $(CPPFLAGS) $(DEFS) -DPART_2 $(CXXFLAGS) -c $< -o $@
$(OBJ_DIR)/cpuemu3.o: cpuemu.cpp
$(CXX) $(CPPFLAGS) $(DEFS) -DPART_3 $(CXXFLAGS) -c $< -o $@
$(OBJ_DIR)/cpuemu4.o: cpuemu.cpp
$(CXX) $(CPPFLAGS) $(DEFS) -DPART_4 $(CXXFLAGS) -c $< -o $@
$(OBJ_DIR)/cpuemu5.o: cpuemu.cpp
$(CXX) $(CPPFLAGS) $(DEFS) -DPART_5 $(CXXFLAGS) -c $< -o $@
$(OBJ_DIR)/cpuemu6.o: cpuemu.cpp
$(CXX) $(CPPFLAGS) $(DEFS) -DPART_6 $(CXXFLAGS) -c $< -o $@
$(OBJ_DIR)/cpuemu7.o: cpuemu.cpp
$(CXX) $(CPPFLAGS) $(DEFS) -DPART_7 $(CXXFLAGS) -c $< -o $@
$(OBJ_DIR)/cpuemu8.o: cpuemu.cpp
$(CXX) $(CPPFLAGS) $(DEFS) -DPART_8 $(CXXFLAGS) -c $< -o $@
cpuemu1.cpp: cpuemu.cpp
$(CXX) -E -DPART_1 $< >$@
cpuemu2.cpp: cpuemu.cpp
$(CXX) -E -DPART_2 $< >$@
cpuemu3.cpp: cpuemu.cpp
$(CXX) -E -DPART_3 $< >$@
cpuemu4.cpp: cpuemu.cpp
$(CXX) -E -DPART_4 $< >$@
cpuemu5.cpp: cpuemu.cpp
$(CXX) -E -DPART_5 $< >$@
cpuemu6.cpp: cpuemu.cpp
$(CXX) -E -DPART_6 $< >$@
cpuemu7.cpp: cpuemu.cpp
$(CXX) -E -DPART_7 $< >$@
cpuemu8.cpp: cpuemu.cpp
$(CXX) -E -DPART_8 $< >$@
cpufast.s: cpuemu.cpp $(OBJ_DIR)/cpuopti
$(CXX) $(CPPFLAGS) $(DEFS) -S $(CXXFLAGS) $< -o cputmp.s
$(OBJ_DIR)/cpuopti <cputmp.s >$@ || mv cputmp.s $@
rm -f cputmp.s
cpufast1.s: cpuemu.cpp $(OBJ_DIR)/cpuopti
$(CXX) $(CPPFLAGS) $(DEFS) -DPART_1 -S $(CXXFLAGS) $< -o cputmp1.s
$(OBJ_DIR)/cpuopti <cputmp1.s >$@ || mv cputmp1.s $@
rm -f cputmp1.s
cpufast2.s: cpuemu.cpp $(OBJ_DIR)/cpuopti
$(CXX) $(CPPFLAGS) $(DEFS) -DPART_2 -S $(CXXFLAGS) $< -o cputmp2.s
$(OBJ_DIR)/cpuopti <cputmp2.s >$@ || mv cputmp2.s $@
rm -f cputmp2.s
cpufast3.s: cpuemu.cpp $(OBJ_DIR)/cpuopti
$(CXX) $(CPPFLAGS) $(DEFS) -DPART_3 -S $(CXXFLAGS) $< -o cputmp3.s
$(OBJ_DIR)/cpuopti <cputmp3.s >$@ || mv cputmp3.s $@
rm -f cputmp3.s
cpufast4.s: cpuemu.cpp $(OBJ_DIR)/cpuopti
$(CXX) $(CPPFLAGS) $(DEFS) -DPART_4 -S $(CXXFLAGS) $< -o cputmp4.s
$(OBJ_DIR)/cpuopti <cputmp4.s >$@ || mv cputmp4.s $@
rm -f cputmp4.s
cpufast5.s: cpuemu.cpp $(OBJ_DIR)/cpuopti
$(CXX) $(CPPFLAGS) $(DEFS) -DPART_5 -S $(CXXFLAGS) $< -o cputmp5.s
$(OBJ_DIR)/cpuopti <cputmp5.s >$@ || mv cputmp5.s $@
rm -f cputmp5.s
cpufast6.s: cpuemu.cpp $(OBJ_DIR)/cpuopti
$(CXX) $(CPPFLAGS) $(DEFS) -DPART_6 -S $(CXXFLAGS) $< -o cputmp6.s
$(OBJ_DIR)/cpuopti <cputmp6.s >$@ || mv cputmp6.s $@
rm -f cputmp6.s
cpufast7.s: cpuemu.cpp $(OBJ_DIR)/cpuopti
$(CXX) $(CPPFLAGS) $(DEFS) -DPART_7 -S $(CXXFLAGS) $< -o cputmp7.s
$(OBJ_DIR)/cpuopti <cputmp7.s >$@ || mv cputmp7.s $@
rm -f cputmp7.s
cpufast8.s: cpuemu.cpp $(OBJ_DIR)/cpuopti
$(CXX) $(CPPFLAGS) $(DEFS) -DPART_8 -S $(CXXFLAGS) $< -o cputmp8.s
$(OBJ_DIR)/cpuopti <cputmp8.s >$@ || mv cputmp8.s $@
rm -f cputmp8.s
#-------------------------------------------------------------------------
# DO NOT DELETE THIS LINE -- make depend depends on it.

View File

@ -0,0 +1,4 @@
/* Localized versions of Info.plist keys */
CFBundleName = "BasiliskII";
NSHumanReadableCopyright = "Copyright 1997-2001 Christian Bauer et al., Freely distributable under the terms of the GNU GPL";

View File

@ -0,0 +1,118 @@
{
IBClasses = (
{
ACTIONS = {
NewEmulator = id;
PauseAll = id;
RunAll = id;
ShowAbout = id;
TerminateAll = id;
};
CLASS = Controller;
LANGUAGE = ObjC;
OUTLETS = {myEmulator = id; };
SUPERCLASS = NSObject;
},
{
ACTIONS = {
Interrupt = id;
PowerKey = id;
Restart = id;
Resume = id;
Snapshot = id;
SpeedChange = id;
Suspend = id;
Terminate = id;
ToggleState = id;
ZapPRAM = id;
};
CLASS = Emulator;
LANGUAGE = ObjC;
OUTLETS = {barberPole = id; runOrPause = id; screen = id; speed = id; win = id; };
SUPERCLASS = NSObject;
},
{CLASS = EmulatorView; LANGUAGE = ObjC; SUPERCLASS = NSView; },
{
ACTIONS = {
Interrupt = id;
PowerKey = id;
Restart = id;
Resume = id;
Snapshot = id;
Suspend = id;
Terminate = id;
ZapPRAM = id;
};
CLASS = FirstResponder;
LANGUAGE = ObjC;
SUPERCLASS = NSObject;
},
{
ACTIONS = {
AddSCSI = id;
AddVolume = id;
BrowseEtherNet = id;
BrowseExtFS = id;
BrowseModem = id;
BrowsePrinter = id;
BrowseROM = id;
ChangeBootFrom = id;
ChangeCPU = id;
ChangeDisableCD = id;
ChangeDisableSound = id;
ChangeFPU = id;
ChangeModel = id;
CreateVolume = id;
DeleteVolume = id;
EditBytes = id;
EditDelay = id;
EditDepth = id;
EditEtherNetDevice = id;
EditExtFS = id;
EditFrequency = id;
EditHeight = id;
EditMB = id;
EditModemDevice = id;
EditPrinterDevice = id;
EditROMpath = id;
EditWidth = id;
RemoveSCSI = id;
RemoveVolume = id;
ShowPrefs = id;
};
CLASS = PrefsEditor;
LANGUAGE = ObjC;
OUTLETS = {
CPU68000 = id;
CPU68020 = id;
CPU68030 = id;
CPU68040 = id;
FPU = id;
IIci = id;
MB = id;
Quadra900 = id;
ROMfile = id;
SCSIdisks = id;
bootFromAny = id;
bootFromCD = id;
bytes = id;
classic = id;
delay = id;
depth = id;
disableCD = id;
disableSound = id;
diskImages = id;
etherNet = id;
extFS = id;
frequency = id;
height = id;
modem = id;
panel = id;
printer = id;
width = id;
};
SUPERCLASS = NSObject;
}
);
IBVersion = 1;
}

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
<key>IBDocumentLocation</key>
<string>5 42 473 240 0 41 1024 705 </string>
<key>IBMainMenuLocation</key>
<string>0 702 365 44 0 42 1152 704 </string>
<key>IBUserGuides</key>
<dict>
<key>About</key>
<dict>
<key>guideLocations</key>
<array/>
<key>guidesLocked</key>
<string>NO</string>
</dict>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,32 @@
{
IBClasses = (
{
ACTIONS = {NewEmulator = id; ShowAbout = id; pauseAll = id; terminateAll = id; };
CLASS = Controller;
LANGUAGE = ObjC;
OUTLETS = {myEmulator = id; };
SUPERCLASS = NSObject;
},
{
ACTIONS = {
Interrupt = id;
PowerKey = id;
Restart = id;
Resume = id;
Snapshot = id;
SpeedChange = id;
Suspend = id;
Terminate = id;
ToggleState = id;
ZapPRAM = id;
};
CLASS = Emulator;
LANGUAGE = ObjC;
OUTLETS = {barberPole = id; runOrPause = id; screen = id; speed = id; win = id; };
SUPERCLASS = NSObject;
},
{CLASS = EmulatorView; LANGUAGE = ObjC; SUPERCLASS = NSView; },
{CLASS = FirstResponder; LANGUAGE = ObjC; SUPERCLASS = NSObject; }
);
IBVersion = 1;
}

View File

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist SYSTEM "file://localhost/System/Library/DTDs/PropertyList.dtd">
<plist version="0.9">
<dict>
<key>IBDocumentLocation</key>
<string>18 42 473 240 0 41 1024 705 </string>
<key>IBMainMenuLocation</key>
<string>0 702 365 44 0 41 1024 705 </string>
<key>IBUserGuides</key>
<dict>
<key>Window</key>
<dict>
<key>guideLocations</key>
<array/>
<key>guidesLocked</key>
<string>NO</string>
</dict>
</dict>
</dict>
</plist>

View File

@ -0,0 +1,5 @@
This is a version of the interface that would allow multiple emulations to
run side-by-side, in different windows. Currently, the uae_cpu engine is not
re-entrant, and some of the Basilisk glue would not allow this, so this will
probably never be used. I will save it here for educational purposes, and just
in case this feature is ever needed.

View File

@ -0,0 +1,89 @@
//
// NNThread.h -Not Nextstep Thread?
// Nigel's Nice Thread?
//
// Revision 1.1, Wed Nov 7 2001.
//
// Created by Nigel Pearson on Tue Nov 28 2000.
// Public Domain. No rights reserved.
//
// Define what flavour of threading to use:
#define USE_NSTHREAD
//#define USE_PTHREAD
#import <Cocoa/Cocoa.h>
#import <mach/mach.h>
#import <mach/kern_return.h>
#ifdef USE_PTHREAD
#include <pthread.h>
struct pthreadArgs // This duplicates most of the stuff in the NNThread object
{
id *object;
SEL *sel;
NSAutoreleasePool *pool;
BOOL allocPool,
*completed;
};
#endif
@interface NNThread : NSObject
{
id object;
SEL sel;
thread_t machThread;
#ifdef USE_PTHREAD
pthread_t pThread;
struct pthreadArgs pthreadArgs;
#endif
NSAutoreleasePool *pool;
BOOL allocPool,
completed,
suspended;
}
- (NNThread *) initWithAutoReleasePool;
- (NNThread *) initSuspended: (BOOL) startSuspended
withAutoreleasePool: (BOOL) allocatePool;
- (void) perform: (SEL)action of: (id)receiver;
- (void) resume;
- (BOOL) start;
- (void) suspend;
- (void) terminate;
@end
typedef enum _NNTimeUnits
{
NNnanoSeconds = 1,
NNmicroSeconds = 2,
NNmilliSeconds = 3,
NNseconds = 4
}
NNTimeUnits;
#import <sys/time.h>
@interface NNTimer : NNThread
{
struct timespec delay;
BOOL repeating;
id timerObject;
SEL timerSel;
}
- (void) changeIntervalTo: (int)number units: (NNTimeUnits)units;
- (void) invalidate;
- (void) perform: (SEL)action of: (id)receiver
after: (int)number units: (NNTimeUnits)units;
- (void) repeat: (SEL)action of: (id)receiver
every: (int)number units: (NNTimeUnits)units;
@end

View File

@ -0,0 +1,247 @@
//
// NNThread.m -Not Nextstep Thread?
// Nigel's Nice Thread?
//
// Revision 1.2, Wednesday Nov 7 2001
//
// Created by Nigel Pearson on Tue Nov 28 2000.
// Public Domain. No rights reserved.
//
#import "NNThread.h"
@implementation NNThread
// Define the wrapper first so that init knows about it without having to put it in the .h
#ifdef USE_NSTHREAD
- (void) wrapper
{
machThread = mach_thread_self();
if ( object == nil || sel == (SEL) nil || suspended )
thread_suspend (machThread); // Suspend myself
if ( allocPool )
pool = [[NSAutoreleasePool alloc] init];
// [object sel] caused "cannot find method" warnings, so I do it a non-obvious way:
objc_msgSend (object, sel);
completed = YES;
if ( allocPool )
[pool release];
}
#endif
#ifdef USE_PTHREAD
void *
pthreadWrapper (void *arg)
{
struct pthreadArgs *args = arg;
if ( args -> allocPool )
args -> pool = [[NSAutoreleasePool alloc] init];
objc_msgSend (*(args->object), *(args->sel));
*(args->completed) = YES;
if ( args -> allocPool )
[args -> pool release];
return NULL;
}
- (BOOL) wrapper
{
int error;
pthreadArgs.object = &object;
pthreadArgs.sel = &sel;
pthreadArgs.allocPool = allocPool;
pthreadArgs.completed = &completed;
pthreadArgs.pool = nil;
if ( object == nil || sel == (SEL) nil || suspended )
error = pthread_create_suspended_np (&pThread, NULL, &pthreadWrapper, &pthreadArgs);
else
error = pthread_create (&pThread, NULL, &pthreadWrapper, &pthreadArgs);
if ( error )
NSLog(@"%s - pthread_create failed");
else
machThread = pthread_mach_thread_np (pThread);
return ! error;
}
#endif
- (NNThread *) initSuspended: (BOOL) startSuspended
withAutoreleasePool: (BOOL) allocatePool
{
self = [super init];
allocPool = allocatePool;
completed = NO;
suspended = startSuspended;
object = nil;
sel = (SEL) nil;
#ifdef USE_NSTHREAD
[NSThread detachNewThreadSelector:@selector(wrapper)
toTarget:self
withObject:nil];
#endif
#ifdef USE_PTHREAD
if ( ! [self wrapper] ) // Wrapper does the thread creation
{
NSLog(@"%s - pthread wrapper failed", __PRETTY_FUNCTION__);
return nil;
}
#endif
return self;
}
- (NNThread *) init
{
return [self initSuspended: YES withAutoreleasePool: NO];
}
- (NNThread *) initWithAutoReleasePool
{
return [self initSuspended: YES withAutoreleasePool: YES];
}
- (BOOL) completed
{
return completed;
}
- (void) perform: (SEL)action of: (id)receiver
{
object = receiver, sel = action;
}
- (void) resume
{
if ( suspended )
[self start];
else
NSLog (@"%s - thread not suspended", __PRETTY_FUNCTION__);
}
- (BOOL) start
{
kern_return_t error;
if ( object == nil || sel == (SEL) nil )
{
NSLog (@"%s - cannot start thread, object or selector invalid", __PRETTY_FUNCTION__);
return NO;
}
if ( ( error = thread_resume (machThread) ) != KERN_SUCCESS )
NSLog (@"%s - thread_resume() failed, returned %d", __PRETTY_FUNCTION__, error);
suspended = NO;
return YES;
}
- (void) suspend
{
if ( ! suspended )
{
kern_return_t error;
if ( ( error = thread_suspend (machThread) ) != KERN_SUCCESS )
NSLog (@"%s - thread_resume() failed, returned %d", __PRETTY_FUNCTION__, error);
suspended = YES;
}
}
- (void) terminate
{
kern_return_t error;
if ( ( error = thread_terminate (machThread) ) != KERN_SUCCESS )
NSLog (@"%s - thread_terminate() failed, returned %d", __PRETTY_FUNCTION__, error);
}
@end
@implementation NNTimer
- (NNTimer *) init
{
self = [super init];
repeating = YES;
return self;
}
- (void) changeIntervalTo: (int)number
units: (NNTimeUnits)units
{
switch ( units )
{
case NNnanoSeconds:
delay.tv_nsec = number;
delay.tv_sec = 0;
break;
case NNmicroSeconds:
delay.tv_nsec = number * 1000;
delay.tv_sec = 0;
break;
case NNmilliSeconds:
delay.tv_nsec = number * 1000000;
delay.tv_sec = 0;
break;
case NNseconds:
delay.tv_nsec = 0;
delay.tv_sec = number;
break;
default:
NSLog (@"%s illegal units(%d)", __PRETTY_FUNCTION__, units);
}
}
- (void) invalidate
{
repeating = NO;
}
- (void) timerLoop
{
// For some strange reason, Mac OS X does not have this prototype
extern int nanosleep (const struct timespec *rqtp, struct timespec *rmtp);
while ( repeating )
{
nanosleep(&delay, NULL);
completed = NO;
// This caused a few warnings:
// [timerObject timerSel];
// so I do it a non-obvious way:
objc_msgSend (timerObject, timerSel);
completed = YES;
}
}
- (void) perform: (SEL)action of: (id)receiver
after: (int)number units: (NNTimeUnits)units
{
object = self, sel = @selector(timerLoop),
timerObject = receiver, timerSel = action, repeating = NO;
[self changeIntervalTo: number units: units];
}
- (void) repeat: (SEL)action of: (id)receiver
every: (int)number units: (NNTimeUnits)units
{
object = self, sel = @selector(timerLoop),
timerObject = receiver, timerSel = action, repeating = YES;
[self changeIntervalTo: number units: units];
}
@end

View File

@ -0,0 +1,143 @@
/*
* PrefsEditor.h - GUI stuff for Basilisk II preferences
* (which is a text file in the user's home directory)
*
* $Id$
*
* Basilisk II (C) 1997-2001 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#import <Cocoa/Cocoa.h>
@interface TableDS : NSObject
{
int numItems;
NSMutableArray *col1,
*col2;
}
- (void) addInt: (int)target
withPath: (NSString *)path;
- (void) addObject: (NSObject *)obj
withPath: (NSString *)path;
- (void) deleteAll;
- (BOOL) deleteRow: (int)row;
- (int) intAtRow: (int)row;
- (int) numberOfRowsInTableView: (NSTableView *)tView;
- (NSString *) pathAtRow: (int)row;
- (id) tableView: (NSTableView *)tView
objectValueForTableColumn: (NSTableColumn *)tColumn
row: (int)rowIndex;
@end
#include "Emulator.h"
@interface PrefsEditor : NSObject
{
IBOutlet NSSlider *emuFreq;
IBOutlet NSView *newVolumeView;
IBOutlet NSTextField *newVolumeSize;
IBOutlet NSWindow *panel;
IBOutlet Emulator *theEmulator;
IBOutlet NSButton *bootFromAny,
*bootFromCD;
IBOutlet NSTextField *bytes;
IBOutlet NSButton *classic,
*CPU68000,
*CPU68020,
*CPU68030,
*CPU68040;
IBOutlet NSTextField *delay,
*depth;
IBOutlet NSButton *disableCD,
*disableSound;
IBOutlet NSTableView *diskImages;
IBOutlet NSTextField *etherNet,
*extFS;
IBOutlet NSButton *FPU;
IBOutlet NSTextField *frequency,
*height;
IBOutlet NSButton *IIci;
IBOutlet NSTextField *MB,
*modem;
IBOutlet NSButton *openGL;
IBOutlet NSTextField *printer;
IBOutlet NSButton *quadra900;
IBOutlet NSTextField *ROMfile;
IBOutlet NSButton *screen;
IBOutlet NSTableView *SCSIdisks;
IBOutlet NSTextField *width;
IBOutlet NSButton *window;
NSString *devs,
*home;
TableDS *volsDS, // Object managing tha data in the Volumes,
*SCSIds; // and SCSI devices, tables
NSImage *locked,
*blank;
NSImageCell *lockCell;
BOOL edited; // Set if the user changes anything, reset on save
}
- (BOOL) hasEdited;
- (NSWindow *) window;
- (IBAction) AddSCSI: (id)sender;
- (IBAction) AddVolume: (id)sender;
//- (IBAction) BrowseEtherNet:(id)sender;
- (IBAction) BrowseExtFS: (id)sender;
//- (IBAction) BrowseModem: (id)sender;
//- (IBAction) BrowsePrinter: (id)sender;
- (IBAction) BrowseROM: (id)sender;
- (IBAction) ChangeBootFrom: (NSMatrix *)sender;
- (IBAction) ChangeCPU: (NSMatrix *)sender;
- (IBAction) ChangeDisableCD: (NSButton *)sender;
- (IBAction) ChangeDisableSound:(NSButton *)sender;
- (IBAction) ChangeFPU: (NSButton *)sender;
- (IBAction) ChangeModel: (NSMatrix *)sender;
- (IBAction) ChangeScreen: (id)sender;
- (IBAction) CreateVolume: (id)sender;
- (IBAction) DeleteVolume: (id)sender;
- (IBAction) EditBytes: (NSTextField *)sender;
- (IBAction) EditDelay: (NSTextField *)sender;
- (IBAction) EditEtherNetDevice:(NSTextField *)sender;
- (IBAction) EditExtFS: (NSTextField *)sender;
- (IBAction) EditFrequency: (NSTextField *)sender;
- (IBAction) EditMB: (NSTextField *)sender;
- (IBAction) EditModemDevice: (NSTextField *)sender;
- (IBAction) EditPrinterDevice: (NSTextField *)sender;
- (IBAction) EditROMpath: (NSTextField *)sender;
- (IBAction) RemoveSCSI: (id)sender;
- (IBAction) RemoveVolume: (id)sender;
- (const char *) RemoveVolumeEntry;
- (IBAction) ResetPrefs: (id)sender;
- (IBAction) ShowPrefs: (id)sender;
- (IBAction) SavePrefs: (id)sender;
@end

View File

@ -0,0 +1,722 @@
/*
* PrefsEditor.m - GUI stuff for Basilisk II preferences
* (which is a text file in the user's home directory)
*
* $Id$
*
* Basilisk II (C) 1997-2001 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#import "PrefsEditor.h"
@implementation TableDS
- (TableDS *) init
{
self = [super init];
numItems = 0;
col1 = [[NSMutableArray alloc] init];
col2 = [[NSMutableArray alloc] init];
return self;
}
- (void) dealloc
{
[col1 dealloc];
[col2 dealloc];
[super dealloc];
}
- (void) addInt: (int)target
withPath: (NSString *)path
{
[col1 addObject: [NSNumber numberWithInt: target]];
[col2 addObject: path];
++numItems;
}
- (void) addObject: (NSObject *)obj
withPath: (NSString *)path
{
[col1 addObject: obj];
[col2 addObject: path];
++numItems;
}
- (void) deleteAll
{
numItems = 0;
[col1 removeAllObjects];
[col2 removeAllObjects];
}
- (BOOL) deleteRow: (int)row
{
if ( row > numItems )
return NO;
[col1 removeObjectAtIndex: row];
[col2 removeObjectAtIndex: row];
-- numItems;
return YES;
}
- (int)intAtRow: (int)row
{
return [[col1 objectAtIndex: row] intValue];
}
- (int) numberOfRowsInTableView: (NSTableView *)tView
{
return numItems;
}
- (NSString *)pathAtRow: (int)row
{
return (NSString *) [col2 objectAtIndex: row];
}
- (id) tableView: (NSTableView *)tView
objectValueForTableColumn: (NSTableColumn *)tColumn
row: (int)row
{
if ( [[tColumn identifier] isEqualToString:@"path"] )
return [col2 objectAtIndex: row];
else
return [col1 objectAtIndex: row];
}
@end
@implementation PrefsEditor
#import <AppKit/NSImage.h> // For [NSBundle pathForImageResource:] proto
#import "sysdeps.h" // Types used in Basilisk C++ code
#import "video_macosx.h" // some items that we edit here
#import "misc_macosx.h" // WarningSheet() prototype
#import <prefs.h>
#define DEBUG 0
#import <debug.h>
- (PrefsEditor *) init
{
self = [super init];
edited = NO;
devs = @"/dev";
home = NSHomeDirectory();
volsDS = [[TableDS alloc] init];
SCSIds = [[TableDS alloc] init];
lockCell = [[NSImageCell alloc] init];
if ( lockCell == nil )
NSLog (@"%s - Can't create NSImageCell?", __PRETTY_FUNCTION__);
blank = [[NSImage alloc] init];
locked = [NSImage alloc];
if ( [locked initWithContentsOfFile:
[[NSBundle mainBundle]
pathForImageResource: @"nowrite.icns"]] == nil )
NSLog(@"%s - Couldn't open write protection image", __PRETTY_FUNCTION__);
return self;
}
- (void) dealloc
{
[volsDS dealloc];
[SCSIds dealloc];
[lockCell dealloc];
[locked dealloc];
[blank dealloc];
[super dealloc];
}
- (void) awakeFromNib
{
emuFreq = [theEmulator speed];
#if DEBUG
[self ShowPrefs: self]; // For testing
#endif
}
- (BOOL) hasEdited
{
return edited;
}
- (NSWindow *) window
{
return panel;
}
- (IBAction) AddSCSI: (id)sender
{
NSOpenPanel *oP = [NSOpenPanel openPanel];
if ( [oP runModalForDirectory:home file:nil types:nil] == NSOKButton )
{
[SCSIds addInt: -1
withPath: [oP filename] ];
[SCSIdisks reloadData];
edited = YES;
}
}
- (IBAction) AddVolume: (id)sender
{
NSOpenPanel *oP = [NSOpenPanel openPanel];
if ( [oP runModalForDirectory:home file:nil types:nil] == NSOKButton )
{
[volsDS addObject: (NSObject *) locked
withPath: [oP filename] ];
PrefsAddString("disk", [[oP filename] cString]);
[diskImages reloadData];
edited = YES;
}
}
- (IBAction) BrowseExtFS: (id)sender
{
NSOpenPanel *oP = [NSOpenPanel openPanel];
[oP setCanChooseDirectories: YES];
[oP setCanChooseFiles: NO];
[oP setPrompt: @"Select"];
[oP setTitle: @"Select a directory to mount"];
D(NSLog(@"%s - home = %@, [extFS stringValue] = %@",
__PRETTY_FUNCTION__, home, [extFS stringValue]));
if ( [oP runModalForDirectory: ([extFS stringValue] ? [extFS stringValue] : home)
file:nil
types:nil] == NSOKButton )
{
[extFS setStringValue: [oP directory] ];
PrefsReplaceString("extfs", [[oP directory] cString]);
edited = YES;
}
}
- (IBAction) BrowseROM: (id)sender
{
NSOpenPanel *oP = [NSOpenPanel openPanel];
[oP setCanChooseFiles: YES];
[oP setTitle: @"Open a ROM file"];
D(NSLog(@"%s - home = %@", __PRETTY_FUNCTION__, home));
if ( [oP runModalForDirectory: ([ROMfile stringValue] ? [ROMfile stringValue] : home)
file:nil
types:nil] == NSOKButton )
{
[ROMfile setStringValue: [oP filename] ];
PrefsReplaceString("rom", [[oP filename] cString]);
edited = YES;
}
}
#include <cdrom.h> // for CDROMRefNum
- (IBAction) ChangeBootFrom: (NSMatrix *)sender
{
if ( [sender selectedCell] == bootFromCD )
PrefsReplaceInt32("bootdriver", CDROMRefNum);
else
PrefsReplaceInt32("bootdriver", 0);
edited = YES;
}
- (IBAction) ChangeCPU: (NSMatrix *)sender
{
PrefsReplaceInt32("cpu", [[sender selectedCell] tag]);
edited = YES;
}
- (IBAction) ChangeDisableCD: (NSButton *)sender
{
PrefsReplaceBool("nocdrom", [disableCD state]);
edited = YES;
}
- (IBAction) ChangeDisableSound: (NSButton *)sender
{
PrefsReplaceBool("nosound", [disableSound state]);
edited = YES;
}
- (IBAction) ChangeFPU: (NSButton *)sender
{
PrefsReplaceBool("fpu", [FPU state]);
edited = YES;
}
- (IBAction) ChangeModel: (NSMatrix *)sender
{
PrefsReplaceInt32("modelid", [[sender selectedCell] tag]);
edited = YES;
}
// Screen/window changing stuff
// This is called when any of the screen/window, width, height or depth is changed
- (IBAction) ChangeScreen: (NSMatrix *)sender
{
short newx = [width intValue];
short newy = [height intValue];
short newbpp = [depth intValue];
short newtype = DISPLAY_WINDOW;
char str[20];
if ( [sender selectedCell] == openGL )
newtype = DISPLAY_OPENGL;
if ( [sender selectedCell] == screen )
newtype = DISPLAY_SCREEN;
// Check that a field actually changed
if ( newbpp == init_depth && newx == init_width &&
newy == init_height && newtype == display_type )
return;
// If we are changing type, supply some sensible defaults
if ( newtype != display_type )
{
if ( newtype == DISPLAY_SCREEN ) // If changing to full screen
{
// supply main screen dimensions as a default
NSScreen *s = [NSScreen mainScreen];
NSRect sr = [s frame];
newx = (short) sr.size.width;
newy = (short) sr.size.height;
// This always returns 24, despite the mode
//newbpp = NSBitsPerPixelFromDepth([s depth]);
newbpp = CGDisplayBitsPerPixel(kCGDirectMainDisplay);
}
if ( display_type == DISPLAY_SCREEN ) // If changing from full screen
newx = MIN_WIDTH, newy = MIN_HEIGHT;
[width setIntValue: newx];
[height setIntValue: newy];
[depth setIntValue: newbpp];
}
else
{
// Check size is within ranges of MIN_WIDTH ... MAX_WIDTH
// and MIN_HEIGHT ... MAX_HEIGHT
// ???
}
// Store new prefs
*str = '\0';
switch ( newtype )
{
case DISPLAY_WINDOW:
if ( newbpp )
sprintf(str, "win/%hd/%hd/%hd", newx, newy, newbpp);
else
sprintf(str, "win/%hd/%hd", newx, newy);
break;
case DISPLAY_OPENGL:
if ( newbpp )
sprintf(str, "opengl/%hd/%hd/%hd", newx, newy, newbpp);
else
sprintf(str, "opengl/%hd/%hd", newx, newy);
break;
case DISPLAY_SCREEN:
if ( newbpp )
sprintf(str, "full/%hd/%hd/%hd", newx, newy, newbpp);
else
sprintf(str, "full/%hd/%hd", newx, newy);
break;
};
PrefsReplaceString("screen", str);
parse_screen_prefs(str);
edited = YES;
if ( display_type != DISPLAY_SCREEN )
resizeWinTo(newx, newy);
}
- (IBAction) CreateVolume: (id)sender
{
NSSavePanel *sP = [NSSavePanel savePanel];
[sP setAccessoryView: newVolumeView];
[sP setPrompt: @"Create"];
[sP setTitle: @"Create new volume as"];
if ( [sP runModalForDirectory:NSHomeDirectory() file:@"basilisk-II.vol"] == NSOKButton )
{
char cmd[1024];
const char *filename = [[sP filename] cString];
int retVal,
size = [newVolumeSize intValue];
sprintf(cmd, "dd if=/dev/zero \"of=%s\" bs=1024k count=%d", filename, size);
retVal = system(cmd);
if (retVal != 0)
{
NSString *details = [NSString stringWithFormat:
@"The dd command failed.\nReturn status %d (%s)",
retVal, strerror(errno)];
WarningSheet(@"Unable to create volume", details, @"OK", panel);
}
else
{
[volsDS addObject: (NSObject *) blank
withPath: [sP filename] ];
PrefsAddString("disk", filename);
[diskImages reloadData];
}
}
}
- (IBAction) DeleteVolume: (id)sender
{
const char *path = [self RemoveVolumeEntry];
if ( unlink(path) == -1 )
{
NSLog(@"%s unlink(%s) failed", __PRETTY_FUNCTION__, path, strerror(errno));
}
}
- (IBAction) EditDelay: (NSTextField *)sender
{
int ticks = [delay intValue];
float freq;
if ( ticks )
freq = 60.0 / ticks;
else
freq = 60.0;
[frequency setFloatValue: freq];
[emuFreq setFloatValue: freq];
PrefsReplaceInt32("frameskip", ticks);
edited = YES;
}
- (IBAction) EditBytes: (NSTextField *)sender
{
int B = (int) [bytes floatValue];
float M = B / 1024 / 1024;
NSLog(@"%s = %f %d", __PRETTY_FUNCTION__, M, B);
PrefsReplaceInt32("ramsize", B);
[MB setFloatValue: M];
edited = YES;
}
- (IBAction) EditEtherNetDevice: (NSTextField *)sender
{
NSString *path = [etherNet stringValue];
PrefsReplaceString("ether", [path cString]);
edited = YES;
}
- (IBAction) EditExtFS: (NSTextField *)sender
{
NSString *path = [extFS stringValue];
PrefsReplaceString("extfs", [path cString]);
edited = YES;
}
- (IBAction) EditFrequency: (NSTextField *)sender
{
float freq = [frequency floatValue];
[delay setIntValue: frequencyToTickDelay(freq)];
[emuFreq setFloatValue: freq];
edited = YES;
}
- (IBAction) EditModemDevice: (NSTextField *)sender
{
NSString *path = [modem stringValue];
PrefsReplaceString("seriala", [path cString]);
edited = YES;
}
- (IBAction) EditMB: (NSTextField *)sender
{
float M = [MB floatValue];
int B = (int) (M * 1024 * 1024);
NSLog(@"%s = %f %d", __PRETTY_FUNCTION__, M, B);
PrefsReplaceInt32("ramsize", B);
[bytes setIntValue: B];
edited = YES;
}
- (IBAction) EditPrinterDevice: (NSTextField *)sender
{
NSString *path = [printer stringValue];
PrefsReplaceString("serialb", [path cString]);
edited = YES;
}
- (IBAction) EditRAMsize: (NSTextField *)sender
{
int B = [bytes intValue];
float M = B / (1024.0 * 1024.0);
NSLog(@"%s = %d %f", __PRETTY_FUNCTION__, B, M);
PrefsReplaceInt32("ramsize", B);
[MB setFloatValue: M];
edited = YES;
}
- (IBAction) EditROMpath: (NSTextField *)sender
{
NSString *path = [ROMfile stringValue];
PrefsReplaceString("rom", [path cString]);
}
- (IBAction) RemoveSCSI: (id)sender
{
char pref[6];
int row = [SCSIdisks selectedRow],
SCSIid = [SCSIds intAtRow: row];
if ( ! [SCSIds deleteRow: row] )
NSLog (@"%s - [SCSIds deleteRow: %d] failed", __PRETTY_FUNCTION__, row);
[SCSIdisks reloadData];
sprintf(pref, "scsi%d", SCSIid);
PrefsRemoveItem(pref,0);
}
- (const char *) RemoveVolumeEntry
{
int row = [diskImages selectedRow];
if ( row != -1 )
{
const char *path = [[volsDS pathAtRow: row] cString],
*str;
int tmp = 0;
while ( (str = PrefsFindString("disk", tmp) ) != NULL )
{
if ( strcmp(str, path) == 0 )
{
PrefsRemoveItem("disk", tmp);
D(NSLog(@"%s - Deleted prefs entry \"disk\", %d", __PRETTY_FUNCTION__, tmp));
edited = YES;
break;
}
++tmp;
}
if ( str == NULL )
{
NSLog(@"%s - Couldn't find any disk preference to match %s", __PRETTY_FUNCTION__, path);
return NULL;
}
if ( ! [volsDS deleteRow: row] )
NSLog (@"%s - RemoveVolume %d failed", __PRETTY_FUNCTION__, tmp);
[diskImages reloadData];
return path;
}
else
{
WarningSheet(@"Please select a volume first", @"", @"OK", panel);
return NULL;
}
}
- (IBAction) RemoveVolume: (id)sender
{
[self RemoveVolumeEntry];
}
- (IBAction) ResetPrefs: (id)sender
{
int argc = 0;
char **argv = NULL;
[panel close]; // Temporarily hide preferences panel
PrefsExit(); // Purge all the old pref values
PrefsInit(argc, argv);
AddPrefsDefaults();
AddPlatformPrefsDefaults(); // and only create basic ones
[SCSIds deleteAll]; // Clear out datasources for the tables
[volsDS deleteAll];
[self ShowPrefs: self]; // Reset items in panel, and redisplay
edited = NO;
}
- (void) setStringOf: (NSTextField *) field
fromPref: (const char *) prefName
{
const char *value = PrefsFindString(prefName, 0);
if ( value )
[field setStringValue: [NSString stringWithCString: value] ];
}
- (IBAction) SavePrefs: (id)sender
{
SavePrefs();
edited = NO;
}
- (IBAction) ShowPrefs: (id)sender
{
NSTableColumn *locks;
const char *str;
int cpu, tmp;
// Set simple single field items
tmp = PrefsFindInt32("frameskip");
[delay setIntValue: tmp];
if ( tmp )
[frequency setFloatValue: 60.0 / tmp];
else
[frequency setFloatValue: 60.0];
tmp = PrefsFindInt32("ramsize");
[bytes setIntValue: tmp];
[MB setFloatValue: tmp / (1024.0 * 1024.0)];
[disableCD setState: PrefsFindBool("nocdrom")];
[disableSound setState: PrefsFindBool("nosound")];
[FPU setState: PrefsFindBool("fpu") ];
[self setStringOf: etherNet fromPref: "ether" ];
[self setStringOf: extFS fromPref: "extfs" ];
[self setStringOf: modem fromPref: "seriala"];
[self setStringOf: printer fromPref: "serialb"];
[self setStringOf: ROMfile fromPref: "rom" ];
parse_screen_prefs(PrefsFindString("screen"));
[width setIntValue: init_width];
[height setIntValue: init_height];
[depth setIntValue: init_depth];
[window setState: NO];
switch ( display_type )
{
case DISPLAY_WINDOW: [window setState: YES]; break;
case DISPLAY_OPENGL: [openGL setState: YES]; break;
case DISPLAY_SCREEN: [screen setState: YES]; break;
}
[newVolumeSize setIntValue: 10];
// Radio button groups:
tmp = PrefsFindInt32("bootdriver");
[bootFromAny setState: tmp != CDROMRefNum];
[bootFromCD setState: tmp == CDROMRefNum];
cpu = PrefsFindInt32("cpu");
tmp = PrefsFindInt32("modelid");
#if REAL_ADDRESSING || DIRECT_ADDRESSING
puts("Current memory model does not support 24bit addressing");
if ( tmp == [classic tag] )
{
// Window already created by NIB file, just display
[panel makeKeyAndOrderFront:self];
WarningSheet(@"Compiled-in memory model does not support 24bit",
@"Disabling Mac Classic emulation", @"OK", panel);
cpu = [CPU68030 tag];
PrefsReplaceInt32("cpu", cpu);
tmp = [IIci tag];
PrefsReplaceInt32("modelid", tmp);
}
puts("Disabling 68000 & Mac Classic buttons");
[CPU68000 setEnabled:FALSE];
[classic setEnabled:FALSE];
#endif
[CPU68000 setState: [CPU68000 tag] == cpu];
[CPU68020 setState: [CPU68020 tag] == cpu];
[CPU68030 setState: [CPU68030 tag] == cpu];
[CPU68040 setState: [CPU68040 tag] == cpu];
[classic setState: [classic tag] == tmp];
[IIci setState: [IIci tag] == tmp];
[quadra900 setState: [quadra900 tag] == tmp];
// Lists of thingies:
for ( tmp = 0; tmp < 7; ++tmp)
{
char pref[6];
pref[0] = '\0';
sprintf (pref, "scsi%d", tmp);
if ( (str = PrefsFindString(pref, 0) ) )
[SCSIds addInt: tmp
withPath: [NSString stringWithCString: str] ];
}
[SCSIdisks setDataSource: SCSIds];
locks = [diskImages tableColumnWithIdentifier: @"locked"];
if ( locks == nil )
NSLog (@"%s - Can't find column for lock images", __PRETTY_FUNCTION__);
[locks setDataCell: lockCell];
tmp = 0;
while ( (str = PrefsFindString("disk", tmp++) ) != NULL )
{
if ( *str == '*' )
[volsDS addObject: (NSObject *) locked
withPath: [NSString stringWithCString: str+1]];
else
[volsDS addObject: (NSObject *) blank
withPath: [NSString stringWithCString: str]];
}
[diskImages setDataSource: volsDS];
[panel makeKeyAndOrderFront:self]; // Window already created by NIB file, just display
}
@end

View File

@ -0,0 +1,39 @@
Bugs:
<UL>
<LI>In window mode, if the framerate is low (<I>e.g.</I> if you leave it at the
default of 10fps), really fast mouse clicks are sometimes not picked up
by the Emulator. For now, click more slowly</LI>
<LI>Some special keys (<I>e.g.</I> the cursor keys) are not being correctly
passed through to the Emulator (<I>e.g.</I> up arrow causes the Emulator
to try and shut down). Looks like some further key decoding is needed</LI>
</UL>
Untested:
<UL>
<LI>Mac Classic emulation. I don't have a ROM, but I suspect it will crash</LI>
<LI>CD-ROM stuff. Should be the same as BSD, but who knows how Apple's stuff affects this</LI>
<LI>Floppy stuff. See above</LI>
<LI>Serial port code. See above</LI>
</UL>
Unimplemented:
<UL>
<LI>Ethernet</LI>
<LI>Reset and Interrupt functions for emulator</LI>
<LI>Sound</LI>
<LI>Window depth. It is currently stuck at 32bits, which Quartz dithers down
to whatever the user's display is set to. This is mainly due to the fact
that NSBitmapImageRep does not support any 16bit modes. The Core Graphics
primitives may allow a workaround, though</LI>
</UL>
Possible Enhancements:
<UL>
<LI>Use NSFileManager's movePath:toPath:handler to rename all a file's forks in extfs_macosx.mm</LI>
<LI>Emulator snapshot - save the current emulator state
(memory + registers) to a file for fast startup next time</LI>
<LI>Multiple emulators. The window stuff is mostly there,
but the uae_cpu code has lots of globals, and is not re-entrant</LI>
<LI>Real or Direct addressing mode for the emulator.
At the moment, OS X's mmap() call does not support anything useful</LI>
<LI>Get VOSF (Video on Seg Fault) working, to speed up screen redrawing</LI>
<LI>Implement OpenGL windowing mode (to speed up emulator screen redrawing)</LI>
<LI>Improve Objective-C object allocation. e.g. <A HREF="http://www.mulle-kybernetik.com/artikel/Optimisation/opti-5.html"> here</A>. </LI>
</UL>

View File

@ -0,0 +1,38 @@
Versions of MacOS X port of Basilisk II:
<OL>
<LI>Initial port to Public Beta, made minor changes to get it to compile under Final Release.
<BR>Gave a copy of this version to Gwenole Beauchesne (one of the other porters)</LI>
<LI>Ported to version 0.9 of the Basilisk II tarball.
<BR>Re-engineered autoconfig files to give a clean autoconf and make of cpu_uae code.
<BR>Fixed a bug in the EmulatorView class (I was customising release instead of dealloc).
<BR>Added:
<UL>
<LI>Transparency to icon</LI>
<LI>Port-specific doco: 0_HOW_TO_BUILD.txt, ToDo.html and Versions.html</LI>
<LI>Screen Snapshot code</LI>
<LI>Preferences saving and resetting</LI>
<LI>Delegate code, called when user attempts to close emulator window or quit application,
to check whether preferences need saving or application should be allowed to quit</LI>
<LI>ExtFS resource and type/creator access code</LI>
<LI>Window resizing stuff:
<OL>
<LI>The screensize can be set in the preferences. If the emulator has yet to
start then the window and emulator screen is resized. Otherwise, and</LI>
<LI>At any time, the window can be resized, which scales the emulator screen image</LI>
</OL>
</LI>
</UL>
<BR>Gave a copy of this to Max Horn</LI>
<LI>Some code fixes suggested by Max, doco updates, and porting to OS 10.1</LI>
<LI>Event handling re-write inspired by Max (subclassing NSApplication for custom sendEvent:).
Command key and double clicks are now passed correctly to the Emulator. Took out the custom
"About" window stuff, and added some credits (with an html link to the official Basilisk home
page) in the standard About box. Also has the standard README in the help menu.
<BR>Gave a copy to Max</LI>
<LI>Streamlining of event sending (filter mouseMoved events when not in Emulator screen)</LI>
<LI>Recompile in Project Builder, because the makefile generated binary dies at startup</LI>
<LI>Ported to the Basilisk II 1.0 snapshot's source and implemented video resolution switching.
Also uses Objective-C++, which eliminates some of the wrapper code which was previously needed.</LI>
<LI>Video preferences fixes, small tidyup of source.</LI>
<LI>Full screen mode added, more source tidied up.</LI>
</OL>

View File

@ -0,0 +1,182 @@
/*
* audio_MacOSX.cpp - Based on audio_dummy.cpp
*
* $Id$
*
* Basilisk II (C) 1997-2002 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sysdeps.h"
#include "prefs.h"
#include "audio.h"
#include "audio_defs.h"
#define DEBUG 1
#include "debug.h"
#include "main_macosx.h"
#import <CoreFoundation/CoreFoundation.h>
#import <CoreAudio/CoreAudio.h>
AudioDeviceID device = kAudioDeviceUnknown;
/*
* Initialization
*/
void AudioInit(void)
{
int count;
// Init audio status and feature flags
AudioStatus.sample_rate = 44100 << 16;
AudioStatus.sample_size = 16;
AudioStatus.channels = 2;
AudioStatus.mixer = 0;
AudioStatus.num_sources = 0;
audio_component_flags = cmpWantsRegisterMessage | kStereoOut | k16BitOut;
// Only one sample format is supported
audio_sample_rates.push_back(44100 << 16);
audio_sample_sizes.push_back(16);
audio_channel_counts.push_back(2);
// Sound disabled in prefs? Then do nothing
if (PrefsFindBool("nosound"))
return;
// Get default audio device
count = sizeof(device);
err = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice,
&count, (void *) &device);
if ( err != noErr || device == kAudioDeviceUnknown )
{
NSLog(@"Failed to get default audio output device");
audio_open = false;
return;
}
// Audio not available
audio_open = false;
}
/*
* Deinitialization
*/
void AudioExit(void)
{
}
/*
* First source added, start audio stream
*/
void audio_enter_stream()
{
}
/*
* Last source removed, stop audio stream
*/
void audio_exit_stream()
{
}
/*
* MacOS audio interrupt, read next data block
*/
void AudioInterrupt(void)
{
D(bug("AudioInterrupt\n"));
}
/*
* Set sampling parameters
* "index" is an index into the audio_sample_rates[] etc. vectors
* It is guaranteed that AudioStatus.num_sources == 0
*/
bool audio_set_sample_rate(int index)
{
}
bool audio_set_sample_size(int index)
{
}
bool audio_set_channels(int index)
{
}
/*
* Get/set volume controls (volume values received/returned have the left channel
* volume in the upper 16 bits and the right channel volume in the lower 16 bits;
* both volumes are 8.8 fixed point values with 0x0100 meaning "maximum volume"))
*/
bool audio_get_main_mute(void)
{
return false;
}
uint32 audio_get_main_volume(void)
{
return 0x01000100;
}
bool audio_get_speaker_mute(void)
{
return false;
}
uint32 audio_get_speaker_volume(void)
{
return 0x01000100;
}
void audio_set_main_mute(bool mute)
{
}
void audio_set_main_volume(uint32 vol)
{
}
void audio_set_speaker_mute(bool mute)
{
}
void audio_set_speaker_volume(uint32 vol)
{
}

View File

@ -0,0 +1,207 @@
/* config.h.in. Generated automatically from configure.in by autoheader. */
/* Define to empty if the keyword does not work. */
#undef const
/* Define as __inline if that's what the C compiler calls it. */
#undef inline
/* Define if your C compiler doesn't accept -c and -o together. */
#undef NO_MINUS_C_MINUS_O
/* Define to `long' if <sys/types.h> doesn't define. */
#undef off_t
/* Define as the return type of signal handlers (int or void). */
#undef RETSIGTYPE
/* Define to `unsigned' if <sys/types.h> doesn't define. */
#undef size_t
/* Define if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define if you can safely include both <sys/time.h> and <time.h>. */
#undef TIME_WITH_SYS_TIME
/* Define if your <sys/time.h> declares struct tm. */
#undef TM_IN_SYS_TIME
/* Define if your processor stores words with the most significant
byte first (like Motorola and SPARC, unlike Intel and VAX). */
#undef WORDS_BIGENDIAN
/* Define to 'off_t' if <sys/types.h> doesn't define. */
#undef loff_t
/* Define to 'int' if <sys/types.h> doesn't define. */
#undef socklen_t
/* Define if using "mon". */
#undef ENABLE_MON
/* Define if using video enabled on SEGV signals */
#undef ENABLE_VOSF
/* Define if your system requires signals to be reinstalled */
#undef SIGNAL_NEED_REINSTALL
/* Define if your system requires sigactions to be reinstalled */
#undef SIGACTION_NEED_REINSTALL
/* Define if your system support extended signals */
#undef HAVE_SIGINFO_T
/* Define if we know a hack to replace siginfo_t::si_addr member */
#undef HAVE_SIGCONTEXT_SUBTERFUGE
/* Define if your system has a working vm_allocate()-based memory allocator */
#undef HAVE_MACH_VM
/* Define if your system has a working mmap()-based memory allocator */
#undef HAVE_MMAP_VM
/* Define if <sys/mman.h> defines MAP_ANON and mmap()'ing with MAP_ANON works */
#undef HAVE_MMAP_ANON
/* Define if <sys/mman.h> defines MAP_ANONYMOUS and mmap()'ing with MAP_ANONYMOUS works */
#undef HAVE_MMAP_ANONYMOUS
/* The number of bytes in a int. */
#undef SIZEOF_INT
/* The number of bytes in a long. */
#undef SIZEOF_LONG
/* The number of bytes in a long long. */
#undef SIZEOF_LONG_LONG
/* The number of bytes in a short. */
#undef SIZEOF_SHORT
/* The number of bytes in a void *. */
#undef SIZEOF_VOID_P
/* Define if you have the atanh function. */
#undef HAVE_ATANH
/* Define if you have the cfmakeraw function. */
#undef HAVE_CFMAKERAW
/* Define if you have the clock_gettime function. */
#undef HAVE_CLOCK_GETTIME
/* Define if you have the feclearexcept function. */
#undef HAVE_FECLEAREXCEPT
/* Define if you have the fegetexceptflag function. */
#undef HAVE_FEGETEXCEPTFLAG
/* Define if you have the fegetround function. */
#undef HAVE_FEGETROUND
/* Define if you have the feraiseexcept function. */
#undef HAVE_FERAISEEXCEPT
/* Define if you have the fesetexceptflag function. */
#undef HAVE_FESETEXCEPTFLAG
/* Define if you have the fesetround function. */
#undef HAVE_FESETROUND
/* Define if you have the fetestexcept function. */
#undef HAVE_FETESTEXCEPT
/* Define if you have the isinf function. */
#undef HAVE_ISINF
/* Define if you have the isinfl function. */
#undef HAVE_ISINFL
/* Define if you have the isnan function. */
#undef HAVE_ISNAN
/* Define if you have the isnanl function. */
#undef HAVE_ISNANL
/* Define if you have the mach_task_self function. */
#undef HAVE_MACH_TASK_SELF
/* Define if you have the mmap function. */
#undef HAVE_MMAP
/* Define if you have the mprotect function. */
#undef HAVE_MPROTECT
/* Define if you have the munmap function. */
#undef HAVE_MUNMAP
/* Define if you have the pthread_cancel function. */
#undef HAVE_PTHREAD_CANCEL
/* Define if you have the sem_init function. */
#undef HAVE_SEM_INIT
/* Define if you have the sigaction function. */
#undef HAVE_SIGACTION
/* Define if you have the signal function. */
#undef HAVE_SIGNAL
/* Define if you have the strdup function. */
#undef HAVE_STRDUP
/* Define if you have the task_self function. */
#undef HAVE_TASK_SELF
/* Define if you have the timer_create function. */
#undef HAVE_TIMER_CREATE
/* Define if you have the vm_allocate function. */
#undef HAVE_VM_ALLOCATE
/* Define if you have the vm_deallocate function. */
#undef HAVE_VM_DEALLOCATE
/* Define if you have the vm_protect function. */
#undef HAVE_VM_PROTECT
/* Define if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define if you have the <fenv.h> header file. */
#undef HAVE_FENV_H
/* Define if you have the <history.h> header file. */
#undef HAVE_HISTORY_H
/* Define if you have the <readline.h> header file. */
#undef HAVE_READLINE_H
/* Define if you have the <readline/history.h> header file. */
#undef HAVE_READLINE_HISTORY_H
/* Define if you have the <readline/readline.h> header file. */
#undef HAVE_READLINE_READLINE_H
/* Define if you have the <sys/mman.h> header file. */
#undef HAVE_SYS_MMAN_H
/* Define if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
/* Define if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define if you have the readline library (-lreadline). */
#undef HAVE_LIBREADLINE
/* Define if you have the termcap library (-ltermcap). */
#undef HAVE_LIBTERMCAP
/* Get more functions for correct standard I/O */
#undef _USE_LARGEFILE_SOURCE
/* Get 64-bit file size support */
#undef _FILE_OFFSET_BITS

View File

@ -0,0 +1,690 @@
dnl Process this file with autoconf to produce a configure script.
dnl Based on Unix/configure.in
dnl Written in 1999 by Christian Bauer et al.
AC_INIT(main_macosx.mm)
AC_PREREQ(2.12)
AC_CONFIG_HEADER(config.h)
dnl These defines are necessary to get 64-bit file size support.
AC_DEFINE(_USE_LARGEFILE_SOURCE, 1, [Get more functions for correct standard I/O])
AC_DEFINE(_FILE_OFFSET_BITS, 64, [Get 64-bit file size support])
dnl Options.
AC_ARG_ENABLE(full,
[ --enable-full use full screen mode [default=no]], [WANT_FULL=$enableval], [WANT_FULL=no])
AC_ARG_ENABLE(multiwin,
[ --enable-multiwin allow multiple emulator windows [default=no]], [WANT_MWIN=$enableval], [WANT_MWIN=no])
dnl FPU emulation core.
AC_ARG_ENABLE(fpe,
[ --enable-fpe=which specify which fpu emulator to use [default=opt]],
[ case "$enableval" in
default) FPE_CORE="default";; dnl fpu_x86.cpp if i386 architecture, fpu_uae.cpp otherwise
uae) FPE_CORE="uae";;
*) AC_MSG_ERROR([--enable-fpe takes only one of the following values: default, uae]);;
esac
],
[ FPE_CORE="default"
])
dnl Addressing modes.
AC_ARG_ENABLE(addressing,
[ --enable-addressing=AM specify the addressing mode to use [default=fastest]],
[ case "$enableval" in
real) ADDRESSING_TEST_ORDER="real";;
direct) ADDRESSING_TEST_ORDER="direct";;
banks) ADDRESSING_TEST_ORDER="banks";;
fastest)ADDRESSING_TEST_ORDER="direct banks";;
*) AC_MSG_ERROR([--enable-addressing takes only one of the following values: fastest, real, direct, banks]);;
esac
],
[ ADDRESSING_TEST_ORDER="direct banks"
])
dnl External packages.
AC_ARG_WITH(mon, [ --with-mon use mon as debugger [default=yes]], [WANT_MON=$withval], [WANT_MON=yes])
dnl Canonical system information.
AC_CANONICAL_HOST
AC_CANONICAL_TARGET
dnl Target OS type
OS_TYPE=darwin
DEFINES="$DEFINES -DOS_$OS_TYPE"
dnl Target CPU type.
HAVE_I386=no
HAVE_M68K=no
HAVE_SPARC=no
HAVE_POWERPC=no
case "$target_cpu" in
i386* | i486* | i586* | i686* | i786* ) CPU_TYPE=i386 HAVE_I386=yes;;
m68k* ) CPU_TYPE=m68k HAVE_M68K=yes;;
sparc* ) CPU_TYPE=sparc HAVE_SPARC=yes;;
powerpc* ) CPU_TYPE=powerpc HAVE_POWERPC=yes;;
*) CPU_TYPE=`echo $target_cpu | sed -e 's/-/_/g'`;;
esac
DEFINES="$DEFINES -DCPU_$CPU_TYPE"
dnl Checks for programs.
AC_PROG_CC
AC_PROG_CC_C_O
AC_PROG_CPP
AC_PROG_CXX
AC_PROG_MAKE_SET
AC_PROG_INSTALL
dnl We use mon if possible.
MONSRCS=
if [[ "x$WANT_MON" = "xyes" ]]; then
AC_MSG_CHECKING(for mon)
mon_srcdir=../../../mon/src
if grep mon_init $mon_srcdir/mon.h >/dev/null 2>/dev/null; then
AC_MSG_RESULT(yes)
AC_DEFINE(ENABLE_MON)
MONSRCS="$mon_srcdir/mon.cpp $mon_srcdir/mon_6502.cpp $mon_srcdir/mon_z80.cpp $mon_srcdir/mon_cmd.cpp $mon_srcdir/mon_disass.cpp $mon_srcdir/mon_ppc.cpp $mon_srcdir/disass/floatformat.c $mon_srcdir/disass/i386-dis.c $mon_srcdir/disass/m68k-dis.c $mon_srcdir/disass/m68k-opc.c"
CXXFLAGS="$CXXFLAGS -I$mon_srcdir -I$mon_srcdir/disass"
AC_CHECK_LIB(readline, readline)
AC_CHECK_LIB(termcap, tputs)
AC_CHECK_HEADERS(readline.h history.h readline/readline.h readline/history.h)
else
AC_MSG_RESULT(no)
AC_MSG_WARN([Could not find mon, ignoring --with-mon.])
WANT_MON=no
fi
fi
dnl We want pthreads.
HAVE_PTHREADS=yes
AC_CHECK_FUNCS(pthread_cancel)
dnl If POSIX.4 semaphores are not available, we emulate them with pthread mutexes.
SEMSRC=
AC_CHECK_FUNCS(sem_init, , [
if test "x$HAVE_PTHREADS" = "xyes"; then
SEMSRC=posix_sem.cpp
fi
])
dnl We allow full screen mode if possible.
if [[ "x$WANT_FULL" = "xyes" ]]; then
WANT_FULL=yes
DEFINES="$DEFINES -DENABLE_FULL=1"
LIBS="$LIBS $FRMWKS/QuickTime.framework/QuickTime"
else
DEFINES="$DEFINES -DENABLE_FULL=0"
fi
dnl Ditto for multiple window support
if [[ "x$WANT_MWIN" = "xyes" ]]; then
WANT_MWIN=yes
DEFINES="$DEFINES -DENABLE_MULTIPLE"
fi
dnl Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS(unistd.h fcntl.h sys/time.h sys/mman.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_BIGENDIAN
AC_C_CONST
AC_C_INLINE
AC_CHECK_SIZEOF(short, 2)
AC_CHECK_SIZEOF(int, 4)
AC_CHECK_SIZEOF(long, 4)
AC_CHECK_SIZEOF(long long, 8)
AC_CHECK_SIZEOF(void *, 4)
AC_TYPE_OFF_T
AC_CHECK_TYPE(loff_t, off_t)
dnl TYPE_SOCKLEN_T
AC_CHECK_TYPE(socklen_t)
AC_TYPE_SIZE_T
AC_TYPE_SIGNAL
AC_HEADER_TIME
AC_STRUCT_TM
dnl Checks for library functions.
AC_CHECK_FUNCS(strdup cfmakeraw)
AC_CHECK_FUNCS(clock_gettime timer_create)
AC_CHECK_FUNCS(sigaction signal)
AC_CHECK_FUNCS(mmap mprotect munmap)
AC_CHECK_FUNCS(vm_allocate vm_deallocate vm_protect)
dnl Darwin seems to define mach_task_self() instead of task_self().
AC_CHECK_FUNCS(mach_task_self task_self)
dnl Select system-dependant source files.
DEFINES="$DEFINES -DBSD_COMP"
dnl Check for the CAM library
AC_CHECK_LIB(cam, cam_open_btl, HAVE_LIBCAM=yes, HAVE_LIBCAM=no)
if [[ "x$HAVE_LIBCAM" = "xno" ]]; then
AC_MSG_WARN([Cannot find libcam for SCSI management, disabling SCSI support.])
else
dnl Check for the sys kernel includes
AC_CHECK_HEADER(camlib.h)
if [[ "x$ac_cv_header_camlib_h" = "xno" ]]; then
dnl In this case I should fix this thing including a "patch"
dnl to access directly to the functions in the kernel :) --Orlando
AC_MSG_WARN([Cannot find includes for CAM library, disabling SCSI support.])
else
SCSISRC=FreeBSD/scsi_freebsd.cpp
LIBS="$LIBS -lcam"
DEFINES="$DEFINES -DCAM"
fi
fi
dnl Use 68k CPU natively?
WANT_NATIVE_M68K=no
SYSSRCS=$SCSISRC
dnl Define a macro that translates a yesno-variable into a C macro definition
dnl to be put into the config.h file
dnl $1 -- the macro to define
dnl $2 -- the value to translate
AC_DEFUN(AC_TRANSLATE_DEFINE, [
if [[ "x$2" = "xyes" -o "x$2" = "xguessing yes" ]]; then
AC_DEFINE($1)
fi
])
dnl Various checks if the system supports vm_allocate() and the like functions.
have_mach_vm=no
if [[ "x$ac_cv_func_vm_allocate" = "xyes" -a "x$ac_cv_func_vm_deallocate" = "xyes" -a \
"x$ac_cv_func_vm_protect" = "xyes" ]]; then
have_mach_vm=yes
fi
AC_TRANSLATE_DEFINE(HAVE_MACH_VM, "$have_mach_vm")
dnl Check that vm_allocate(), vm_protect() work
if [[ "x$have_mach_vm" = "xyes" ]]; then
AC_CACHE_CHECK("whether vm_protect works",
ac_cv_vm_protect_works, [
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
ac_cv_vm_protect_works=yes
dnl First the tests that should segfault
for test_def in NONE_READ NONE_WRITE READ_WRITE; do
AC_TRY_RUN([
#define CONFIGURE_TEST_VM_MAP
#define TEST_VM_PROT_$test_def
#include "vm_alloc.cpp"
], ac_cv_vm_protect_works=no, rm -f core,
dnl When cross-compiling, do not assume anything
ac_cv_vm_protect_works="guessing no"
)
done
AC_TRY_RUN([
#define CONFIGURE_TEST_VM_MAP
#define TEST_VM_PROT_RDWR_WRITE
#include "vm_alloc.cpp"
], , ac_cv_vm_protect_works=no,
dnl When cross-compiling, do not assume anything
ac_cv_vm_protect_works="guessing no"
)
AC_LANG_RESTORE
]
)
dnl Remove support for vm_allocate() if vm_protect() does not work
if [[ "x$have_mach_vm" = "xyes" ]]; then
case $ac_cv_vm_protect_works in
*yes) have_mach_vm=yes;;
*no) have_mach_vm=no;;
esac
fi
AC_TRANSLATE_DEFINE(HAVE_MACH_VM, "$have_mach_vm")
fi dnl HAVE_MACH_VM
dnl Various checks if the system supports mmap() and the like functions.
dnl ... and Mach memory allocators are not supported
have_mmap_vm=no
if [[ "x$ac_cv_func_mmap" = "xyes" -a "x$ac_cv_func_munmap" = "xyes" -a \
"x$ac_cv_func_mprotect" = "xyes" ]]; then
if [[ "x$have_mach_vm" = "xno" ]]; then
have_mmap_vm=yes
fi
fi
AC_TRANSLATE_DEFINE(HAVE_MMAP_VM, "$have_mmap_vm")
dnl Check that mmap() and associated functions work.
if [[ "x$have_mmap_vm" = "xyes" ]]; then
dnl Check if we have a working anonymous mmap()
AC_CACHE_CHECK("whether mmap supports MAP_ANON",
ac_cv_mmap_anon, [
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_TRY_RUN([
#define HAVE_MMAP_ANON
#define CONFIGURE_TEST_VM_MAP
#define TEST_VM_MMAP_ANON
#include "vm_alloc.cpp"
], ac_cv_mmap_anon=yes, ac_cv_mmap_anon=no,
dnl When cross-compiling, do not assume anything.
ac_cv_mmap_anon="guessing no"
)
AC_LANG_RESTORE
]
)
AC_TRANSLATE_DEFINE(HAVE_MMAP_ANON, "$ac_cv_mmap_anon")
AC_CACHE_CHECK("whether mmap supports MAP_ANONYMOUS",
ac_cv_mmap_anonymous, [
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_TRY_RUN([
#define HAVE_MMAP_ANONYMOUS
#define CONFIGURE_TEST_VM_MAP
#define TEST_VM_MMAP_ANON
#include "vm_alloc.cpp"
], ac_cv_mmap_anonymous=yes, ac_cv_mmap_anonymous=no,
dnl When cross-compiling, do not assume anything.
ac_cv_mmap_anonymous="guessing no"
)
AC_LANG_RESTORE
]
)
AC_TRANSLATE_DEFINE(HAVE_MMAP_ANONYMOUS, "$ac_cv_mmap_anonymous")
AC_CACHE_CHECK("whether mprotect works",
ac_cv_mprotect_works, [
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
ac_cv_mprotect_works=yes
dnl First the tests that should segfault
for test_def in NONE_READ NONE_WRITE READ_WRITE; do
AC_TRY_RUN([
#define CONFIGURE_TEST_VM_MAP
#define TEST_VM_PROT_$test_def
#include "vm_alloc.cpp"
], ac_cv_mprotect_works=no, rm -f core,
dnl When cross-compiling, do not assume anything
ac_cv_mprotect_works="guessing no"
)
done
AC_TRY_RUN([
#define CONFIGURE_TEST_VM_MAP
#define TEST_VM_PROT_RDWR_WRITE
#include "vm_alloc.cpp"
], , ac_cv_mprotect_works=no,
dnl When cross-compiling, do not assume anything
ac_cv_mprotect_works="guessing no"
)
AC_LANG_RESTORE
]
)
dnl Remove support for mmap() if mprotect() does not work
if [[ "x$have_mmap_vm" = "xyes" ]]; then
case $ac_cv_mprotect_works in
*yes) have_mmap_vm=yes;;
*no) have_mmap_vm=no;;
esac
fi
AC_TRANSLATE_DEFINE(HAVE_MMAP_VM, $have_mmap_vm)
fi dnl HAVE_MMAP_VM
dnl Check if we can mmap 0x2000 bytes from 0x0000
AC_CACHE_CHECK("whether we can map Low Memory area 0x0000-0x2000",
ac_cv_can_map_lm, [
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_TRY_RUN([
#include "vm_alloc.cpp"
int main(void) { /* returns 0 if we could map the lowmem globals */
volatile char * lm;
if (vm_init() < 0) exit(1);
if ((lm = (volatile char *)vm_acquire_fixed(0, 0x2000)) == VM_MAP_FAILED) exit(1);
lm[0] = 'z';
if (vm_release((char *)lm, 0x2000) < 0) exit(1);
vm_exit(); exit(0);
}
], ac_cv_can_map_lm=yes, ac_cv_can_map_lm=no,
dnl When cross-compiling, do not assume anything.
ac_cv_can_map_lm="guessing no"
)
AC_LANG_RESTORE
]
)
dnl Check signal handlers need to be reinstalled
AC_CACHE_CHECK("whether signal handlers need to be reinstalled",
ac_cv_signal_need_reinstall, [
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_TRY_RUN([
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <signal.h>
static int handled_signal = 0;
RETSIGTYPE sigusr1_handler(int) { handled_signal++; }
int main(void) { /* returns 0 if signals need not to be reinstalled */
signal(SIGUSR1, sigusr1_handler); raise(SIGUSR1); raise(SIGUSR1);
exit(handled_signal == 2);
}
], ac_cv_signal_need_reinstall=yes, ac_cv_signal_need_reinstall=no,
dnl When cross-compiling, do not assume anything.
ac_cv_signal_need_reinstall="guessing yes"
)
AC_LANG_RESTORE
]
)
AC_TRANSLATE_DEFINE(SIGNAL_NEED_REINSTALL, "$ac_cv_signal_need_reinstall")
dnl Check if sigaction handlers need to be reinstalled
AC_CACHE_CHECK("whether sigaction handlers need to be reinstalled",
ac_cv_sigaction_need_reinstall, [
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_TRY_RUN([
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <signal.h>
static int handled_signal = 0;
RETSIGTYPE sigusr1_handler(int) { handled_signal++; }
typedef RETSIGTYPE (*signal_handler)(int);
static signal_handler mysignal(int sig, signal_handler handler) {
struct sigaction old_sa;
struct sigaction new_sa;
new_sa.sa_handler = handler;
return ((sigaction(sig,&new_sa,&old_sa) < 0) ? SIG_IGN : old_sa.sa_handler);
}
int main(void) { /* returns 0 if signals need not to be reinstalled */
mysignal(SIGUSR1, sigusr1_handler); raise(SIGUSR1); raise(SIGUSR1);
exit(handled_signal == 2);
}
], ac_cv_sigaction_need_reinstall=yes, ac_cv_sigaction_need_reinstall=no,
dnl When cross-compiling, do not assume anything.
ac_cv_sigaction_need_reinstall="guessing yes"
)
AC_LANG_RESTORE
]
)
AC_TRANSLATE_DEFINE(SIGACTION_NEED_REINSTALL, "$ac_cv_sigaction_need_reinstall")
dnl Check if extended signals are supported.
AC_CACHE_CHECK("whether your system supports extended signal handlers",
ac_cv_have_extended_signals, [
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_TRY_RUN([
#define HAVE_SIGINFO_T 1
#define CONFIGURE_TEST_SIGSEGV_RECOVERY
#include "vm_alloc.cpp"
#include "sigsegv.cpp"
], ac_cv_have_extended_signals=yes, ac_cv_have_extended_signals=no,
dnl When cross-compiling, do not assume anything.
ac_cv_have_extended_signals=no
)
AC_LANG_RESTORE
]
)
AC_TRANSLATE_DEFINE(HAVE_SIGINFO_T, "$ac_cv_have_extended_signals")
dnl Otherwise, check for subterfuges.
if [[ "x$ac_cv_have_extended_signals" = "xno" ]]; then
AC_CACHE_CHECK("whether we then have a subterfuge for your system",
ac_cv_have_sigcontext_hack, [
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_TRY_RUN([
#define HAVE_SIGCONTEXT_SUBTERFUGE 1
#define CONFIGURE_TEST_SIGSEGV_RECOVERY
#include "vm_alloc.cpp"
#include "sigsegv.cpp"
], ac_cv_have_sigcontext_hack=yes, ac_cv_have_sigcontext_hack=no,
dnl When cross-compiling, do not assume anything.
ac_cv_have_sigcontext_hack=no
)
AC_LANG_RESTORE
])
AC_TRANSLATE_DEFINE(HAVE_SIGCONTEXT_SUBTERFUGE, "$ac_cv_have_sigcontext_hack")
fi
dnl Can we do Video on SEGV Signals ?
CAN_VOSF=no
if [[ "$ac_cv_have_extended_signals" = "yes" -o "$ac_cv_have_sigcontext_hack" = "yes" ]]; then
CAN_VOSF=yes
fi
dnl Determine the addressing mode to use
if [[ "x$WANT_NATIVE_M68K" = "xyes" ]]; then
ADDRESSING_MODE="real"
else
ADDRESSING_MODE=""
AC_MSG_CHECKING([for the addressing mode to use])
for am in $ADDRESSING_TEST_ORDER; do
case $am in
real)
dnl Requires ability to mmap() Low Memory globals
if [[ "x$ac_cv_can_map_lm" = "xno" ]]; then
continue
fi
dnl Requires VOSF screen updates
if [[ "x$CAN_VOSF" = "xno" ]]; then
continue
fi
dnl Real addressing will probably work.
ADDRESSING_MODE="real"
WANT_VOSF=yes dnl we can use VOSF and we need it actually
DEFINES="$DEFINES -DREAL_ADDRESSING"
break
;;
direct)
dnl Requires VOSF screen updates
if [[ "x$CAN_VOSF" = "xyes" ]]; then
ADDRESSING_MODE="direct"
WANT_VOSF=yes dnl we can use VOSF and we need it actually
DEFINES="$DEFINES -DDIRECT_ADDRESSING"
break
fi
;;
banks)
dnl Default addressing mode
ADDRESSING_MODE="memory banks"
break
;;
*)
AC_MSG_ERROR([Internal configure.in script error for $am addressing mode])
esac
done
AC_MSG_RESULT($ADDRESSING_MODE)
if [[ "x$ADDRESSING_MODE" = "x" ]]; then
AC_MSG_WARN([Sorry, no suitable addressing mode in $ADDRESSING_TEST_ORDER])
ADDRESSING_MODE="memory banks"
fi
fi
dnl Enable VOSF screen updates with this feature is requested and feasible
if [[ "x$WANT_VOSF" = "xyes" -a "x$CAN_VOSF" = "xyes" ]]; then
AC_DEFINE(ENABLE_VOSF)
else
WANT_VOSF=no
fi
dnl Check for GAS.
HAVE_GAS=no
AC_MSG_CHECKING(for GAS .p2align feature)
cat >conftest.S << EOF
.text
.p2align 5
EOF
if $CC conftest.S -c -o conftest.o >/dev/null 2>&1 ; then HAVE_GAS=yes; fi
AC_MSG_RESULT($HAVE_GAS)
dnl Check for GCC 2.7 or higher.
HAVE_GCC27=no
AC_MSG_CHECKING(for GCC 2.7 or higher)
AC_EGREP_CPP(yes,
[#if __GNUC__ - 1 > 1 || __GNUC_MINOR__ - 1 > 5
yes
#endif
], [AC_MSG_RESULT(yes); HAVE_GCC27=yes], AC_MSG_RESULT(no))
dnl Check for GCC 3.0 or higher.
HAVE_GCC30=no
AC_MSG_CHECKING(for GCC 3.0 or higher)
AC_EGREP_CPP(yes,
[#if __GNUC__ >= 3
yes
#endif
], [AC_MSG_RESULT(yes); HAVE_GCC30=yes], AC_MSG_RESULT(no))
dnl Set "-fomit-frame-pointer" on i386 GCC 2.7 or higher.
if [[ "x$HAVE_GCC27" = "xyes" -a "x$HAVE_I386" = "xyes" ]]; then
CFLAGS="$CFLAGS -fomit-frame-pointer"
CXXFLAGS="$CXXFLAGS -fomit-frame-pointer"
fi
dnl (gb) Do not merge constants since it breaks fpu/fpu_x86.cpp.
dnl As of 2001/08/02, this affects the following compilers:
dnl Official: probably gcc-3.1 (mainline CVS)
dnl Mandrake: gcc-2.96 >= 0.59mdk, gcc-3.0.1 >= 0.1mdk
dnl Red Hat : gcc-2.96 >= 89, gcc-3.0 >= 1
if [[ "x$HAVE_GCC27" = "xyes" ]]; then
SAVED_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS -fno-merge-constants"
AC_CACHE_CHECK([whether GCC supports constants merging], ac_cv_gcc_constants_merging, [
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_TRY_COMPILE([],[],[ac_cv_gcc_constants_merging=yes],[ac_cv_gcc_constants_merging=no])
AC_LANG_RESTORE
])
if [[ "x$ac_cv_gcc_constants_merging" != "xyes" ]]; then
CXXFLAGS="$SAVED_CXXFLAGS"
fi
fi
dnl Select appropriate CPU source and REGPARAM define.
ASM_OPTIMIZATIONS=none
CPUSRCS="cpuemu1.cpp cpuemu2.cpp cpuemu3.cpp cpuemu4.cpp cpuemu5.cpp cpuemu6.cpp cpuemu7.cpp cpuemu8.cpp"
FPUSRCS="../uae_cpu/fpu/fpu_uae.cpp"
if [[ "x$HAVE_GCC27" = "xyes" -a "x$HAVE_I386" = "xyes" -a "x$OS_TYPE" != "xfreebsd" ]]; then
dnl i386 CPU
DEFINES="$DEFINES -DREGPARAM=\"__attribute__((regparm(3)))\""
if [[ "x$HAVE_GAS" = "xyes" ]]; then
ASM_OPTIMIZATIONS=i386
DEFINES="$DEFINES -DX86_ASSEMBLY -DUNALIGNED_PROFITABLE -DOPTIMIZED_FLAGS"
CPUSRCS="cpufast1.s cpufast2.s cpufast3.s cpufast4.s cpufast5.s cpufast6.s cpufast7.s cpufast8.s"
FPUSRCS="../uae_cpu/fpu_x86.cpp"
fi
elif [[ "x$HAVE_GCC27" = "xyes" -a "x$HAVE_SPARC" = "xyes" -a "x$HAVE_GAS" = "xyes" ]]; then
dnl SPARC CPU
case "$target_os" in
solaris*)
AC_MSG_CHECKING(SPARC CPU architecture)
SPARC_TYPE=`Solaris/which_sparc`
AC_MSG_RESULT($SPARC_TYPE)
case "$SPARC_TYPE" in
SPARC_V8)
ASM_OPTIMIZATIONS="SPARC V8 architecture"
DEFINES="$DEFINES -DSPARC_V8_ASSEMBLY" dnl -DOPTIMIZED_FLAGS"
CFLAGS="$CFLAGS -Wa,-Av8"
CXXFLAGS="$CXXFLAGS -Wa,-Av8"
;;
SPARC_V9)
ASM_OPTIMIZATIONS="SPARC V9 architecture"
DEFINES="$DEFINES -DSPARC_V9_ASSEMBLY" dnl -DOPTIMIZED_FLAGS"
CFLAGS="$CFLAGS -Wa,-Av9"
CXXFLAGS="$CXXFLAGS -Wa,-Av9"
;;
esac
;;
esac
elif [[ "x$WANT_NATIVE_M68K" = "xyes" ]]; then
dnl Native m68k, no emulation
CPUINCLUDES="-I../native_cpu"
CPUSRCS="asm_support.s"
fi
dnl Select appropriate FPU source.
dnl 1. Optimized X86 assembly core if target is i386 architecture
SAVED_DEFINES=$DEFINES
if [[ "x$FPE_CORE" = "xdefault" ]]; then
if [[ "x$HAVE_GCC27" = "xyes" -a "x$HAVE_I386" = "xyes" -a "x$HAVE_GAS" = "xyes" ]]; then
DEFINES="$DEFINES -DFPU_X86"
FPE_CORE_STR="i386 optimized core"
FPUSRCS="../uae_cpu/fpu/fpu_x86.cpp"
FPE_CORE="i386"
else
FPE_CORE="uae"
fi
fi
dnl 2. JIT-FPU only supports IEEE-based implementation.
if [[ "x$WANT_JIT_FPU" = "xyes" -a "x$FPE_CORE" != "xieee" ]]; then
AC_MSG_WARN([Sorry, JIT-FPU supports only the "ieee" FPE implementation])
FPE_CORE="ieee"
dnl Restore previous variables. FPE_CORE_STR and FPUSRCS are overwritten
DEFINES=$SAVED_DEFINES
fi
dnl 3. Choose either IEEE-based implementation or the old UAE core
if [[ "x$FPE_CORE" = "xieee" ]]; then
AC_CHECK_HEADERS(fenv.h)
AC_CHECK_FUNCS(feclearexcept fegetexceptflag feraiseexcept fesetexceptflag fetestexcept)
AC_CHECK_FUNCS(fegetround fesetround)
DEFINES="$DEFINES -DFPU_IEEE"
FPE_CORE_STR="ieee-based fpu core"
FPUSRCS="../uae_cpu/fpu/fpu_ieee.cpp"
elif [[ "x$FPE_CORE" = "xuae" ]]; then
DEFINES="$DEFINES -DFPU_UAE"
FPE_CORE_STR="original uae core"
FPUSRCS="../uae_cpu/fpu/fpu_uae.cpp"
fi
dnl Check for certain math functions
AC_CHECK_FUNCS(atanh)
AC_CHECK_FUNCS(isnan isinf) dnl C99
AC_CHECK_FUNCS(isnanl isinfl) dnl IEEE ?
dnl UAE CPU sources for all non-m68k-native architectures.
if [[ "x$WANT_NATIVE_M68K" = "xno" ]]; then
CPUINCLUDES="-I../uae_cpu"
CPUSRCS="../uae_cpu/basilisk_glue.cpp ../uae_cpu/memory.cpp ../uae_cpu/newcpu.cpp ../uae_cpu/readcpu.cpp $FPUSRCS cpustbl.cpp cpudefs.cpp $CPUSRCS"
fi
dnl Remove the "-g" option if set for GCC.
if [[ "x$HAVE_GCC27" = "xyes" ]]; then
CFLAGS=`echo $CFLAGS | sed -e 's/-g//g'`
CXXFLAGS=`echo $CXXFLAGS | sed -e 's/-g//g'`
fi
dnl Or if we have -Ofast
if [[ "x$HAVE_OFAST" = "xyes" ]]; then
CFLAGS="`echo $CFLAGS | sed -e 's/-g//g'` -Ofast"
CXXFLAGS="`echo $CXXFLAGS | sed -e 's/-g//g'` -Ofast"
CXXFLAGS="-LANG:std $CXXFLAGS"
LDFLAGS="$LDFLAGS -Ofast"
fi
dnl Generate Makefile.
AC_SUBST(DEFINES)
AC_SUBST(SYSSRCS)
AC_SUBST(CPUINCLUDES)
AC_SUBST(CPUSRCS)
AC_OUTPUT(Makefile)
dnl Print summary.
echo
echo Basilisk II configuration summary:
echo
echo Full screen support .............. : $WANT_FULL
echo Multiple emulator windows ........ : $WANT_MWIN
echo Enable video on SEGV signals ..... : $WANT_VOSF
echo mon debugger support ............. : $WANT_MON
echo Floating-Point emulation core .... : $FPE_CORE_STR
echo Assembly optimizations ........... : $ASM_OPTIMIZATIONS
echo Addressing mode .................. : $ADDRESSING_MODE
echo
echo "Configuration done. Now type \"make\" (or \"gmake\")."

View File

@ -0,0 +1,538 @@
/*
* $Id$
*
* extfs_macosx.h - Work around some symbol clashes between
* CarbonCore and Basilisk II header files.
* Based on:
*
* extfs_defs.h - MacOS types and structures for external file system
*
* Basilisk II (C) 1997-2002 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef EXTFS_DEFS_H
#define EXTFS_DEFS_H
#include "macos_util_macosx.h"
#import <CarbonCore/Files.h>
// Gestalt selectors
enum {
gestaltFSAttr = FOURCC('f','s',' ',' '),
gestaltFullExtFSDispatching = 0,
gestaltHasFSSpecCalls = 1,
gestaltHasFileSystemManager = 2,
gestaltFSMDoesDynamicLoad = 3,
gestaltFSSupports4GBVols = 4,
gestaltFSSupports2TBVols = 5,
gestaltHasExtendedDiskInit = 6,
gestaltDTMgrSupportsFSM = 7
};
enum {
gestaltFSMVersion = FOURCC('f','s','m',' ')
};
// File attributes
enum {
faLocked = 0x01,
faRFOpen = 0x04,
faDFOpen = 0x08,
faIsDir = 0x10,
faOpen = 0x80
};
// Volume attributes
enum {
vaBusy = 0x40,
vaHardLock = 0x80,
vaSoftLock = 0x8000
};
// vMAttrib (GetVolParms) constants
enum {
kLimitFCBs = 1 << 31,
kLocalWList = 1 << 30,
kNoMiniFndr = 1 << 29,
kNoVNEdit = 1 << 28,
kNoLclSync = 1 << 27,
kTrshOffLine = 1 << 26,
kNoSwitchTo = 1 << 25,
kNoDeskItems = 1 << 20,
kNoBootBlks = 1 << 19,
kAccessCntl = 1 << 18,
kNoSysDir = 1 << 17,
kHasExtFSVol = 1 << 16,
kHasOpenDeny = 1 << 15,
kHasCopyFile = 1 << 14,
kHasMoveRename = 1 << 13,
kHasDesktopMgr = 1 << 12,
kHasShortName = 1 << 11,
kHasFolderLock = 1 << 10,
kHasPersonalAccessPrivileges = 1 << 9,
kHasUserGroupList = 1 << 8,
kHasCatSearch = 1 << 7,
kHasFileIDs = 1 << 6,
kHasBTreeMgr = 1 << 5,
kHasBlankAccessPrivileges = 1 << 4,
kSupportsAsyncRequests = 1 << 3
};
enum {
fsUsrCNID = 16,
kHFSBit = 9,
kHFSMask = 0x0200,
kAsyncBit = 10,
kAsyncMask = 0x0400
};
// HFSCIProc selectCode values
enum {
kFSMOpen = 0xA000,
kFSMClose = 0xA001,
kFSMRead = 0xA002,
kFSMWrite = 0xA003,
kFSMGetVolInfo = 0xA007,
kFSMCreate = 0xA008,
kFSMDelete = 0xA009,
kFSMOpenRF = 0xA00A,
kFSMRename = 0xA00B,
kFSMGetFileInfo = 0xA00C,
kFSMSetFileInfo = 0xA00D,
kFSMUnmountVol = 0xA00E,
kFSMMountVol = 0xA00F,
kFSMAllocate = 0xA010,
kFSMGetEOF = 0xA011,
kFSMSetEOF = 0xA012,
kFSMFlushVol = 0xA013,
kFSMGetVol = 0xA014,
kFSMSetVol = 0xA015,
kFSMEject = 0xA017,
kFSMGetFPos = 0xA018,
kFSMOffline = 0xA035,
kFSMSetFilLock = 0xA041,
kFSMRstFilLock = 0xA042,
kFSMSetFilType = 0xA043,
kFSMSetFPos = 0xA044,
kFSMFlushFile = 0xA045,
kFSMOpenWD = 0x0001,
kFSMCloseWD = 0x0002,
kFSMCatMove = 0x0005,
kFSMDirCreate = 0x0006,
kFSMGetWDInfo = 0x0007,
kFSMGetFCBInfo = 0x0008,
kFSMGetCatInfo = 0x0009,
kFSMSetCatInfo = 0x000A,
kFSMSetVolInfo = 0x000B,
kFSMLockRng = 0x0010,
kFSMUnlockRng = 0x0011,
kFSMXGetVolInfo = 0x0012,
kFSMCreateFileIDRef = 0x0014,
kFSMDeleteFileIDRef = 0x0015,
kFSMResolveFileIDRef = 0x0016,
kFSMExchangeFiles = 0x0017,
kFSMCatSearch = 0x0018,
kFSMOpenDF = 0x001A,
kFSMMakeFSSpec = 0x001B,
kFSMDTGetPath = 0x0020,
kFSMDTCloseDown = 0x0021,
kFSMDTAddIcon = 0x0022,
kFSMDTGetIcon = 0x0023,
kFSMDTGetIconInfo = 0x0024,
kFSMDTAddAPPL = 0x0025,
kFSMDTRemoveAPPL = 0x0026,
kFSMDTGetAPPL = 0x0027,
kFSMDTSetComment = 0x0028,
kFSMDTRemoveComment = 0x0029,
kFSMDTGetComment = 0x002A,
kFSMDTFlush = 0x002B,
kFSMDTReset = 0x002C,
kFSMDTGetInfo = 0x002D,
kFSMDTOpenInform = 0x002E,
kFSMDTDelete = 0x002F,
kFSMGetVolParms = 0x0030,
kFSMGetLogInInfo = 0x0031,
kFSMGetDirAccess = 0x0032,
kFSMSetDirAccess = 0x0033,
kFSMMapID = 0x0034,
kFSMMapName = 0x0035,
kFSMCopyFile = 0x0036,
kFSMMoveRename = 0x0037,
kFSMOpenDeny = 0x0038,
kFSMOpenRFDeny = 0x0039,
kFSMGetXCatInfo = 0x003A,
kFSMGetVolMountInfoSize = 0x003F,
kFSMGetVolMountInfo = 0x0040,
kFSMVolumeMount = 0x0041,
kFSMShare = 0x0042,
kFSMUnShare = 0x0043,
kFSMGetUGEntry = 0x0044,
kFSMGetForeignPrivs = 0x0060,
kFSMSetForeignPrivs = 0x0061
};
// UTDetermineVol status values
enum {
dtmvError = 0,
dtmvFullPathname = 1,
dtmvVRefNum = 2,
dtmvWDRefNum = 3,
dtmvDriveNum = 4,
dtmvDefault = 5
};
// Miscellaneous constants used by FSM
enum {
fsdVersion1 = 1,
fsmIgnoreFSID = 0xFFFE,
fsmGenericFSID = 0xFFFF
};
// compInterfMask bits common to all FSM components
enum {
fsmComponentEnableBit = 31,
fsmComponentEnableMask = (long)0x80000000,
fsmComponentBusyBit = 30,
fsmComponentBusyMask = 0x40000000
};
// compInterfMask bits specific to HFS component
enum {
hfsCIDoesHFSBit = 23,
hfsCIDoesHFSMask = 0x00800000,
hfsCIDoesAppleShareBit = 22,
hfsCIDoesAppleShareMask = 0x00400000,
hfsCIDoesDeskTopBit = 21,
hfsCIDoesDeskTopMask = 0x00200000,
hfsCIDoesDynamicLoadBit = 20,
hfsCIDoesDynamicLoadMask = 0x00100000,
hfsCIResourceLoadedBit = 19,
hfsCIResourceLoadedMask = 0x00080000,
hfsCIHasHLL2PProcBit = 18,
hfsCIHasHLL2PProcMask = 0x00040000,
hfsCIWantsDTSupportBit = 17,
hfsCIWantsDTSupportMask = 0x00020000
};
// FCBRec.fcbFlags bits
enum {
fcbWriteBit = 0,
fcbWriteMask = 0x01,
fcbResourceBit = 1,
fcbResourceMask = 0x02,
fcbWriteLockedBit = 2,
fcbWriteLockedMask = 0x04,
fcbSharedWriteBit = 4,
fcbSharedWriteMask = 0x10,
fcbFileLockedBit = 5,
fcbFileLockedMask = 0x20,
fcbOwnClumpBit = 6,
fcbOwnClumpMask = 0x40,
fcbModifiedBit = 7,
fcbModifiedMask = 0x80
};
// InformFSM messages
enum {
fsmNopMessage = 0,
fsmDrvQElChangedMessage = 1,
fsmGetFSIconMessage = 2
};
// Messages passed to the fileSystemCommProc
enum {
ffsNopMessage = 0,
ffsGetIconMessage = 1,
ffsIDDiskMessage = 2,
ffsLoadMessage = 3,
ffsUnloadMessage = 4,
ffsIDVolMountMessage = 5,
ffsInformMessage = 6,
ffsGetIconInfoMessage = 7
};
enum { // FSMGetIconRec struct
iconBufferPtr = 2,
requestSize = 6,
actualSize = 10,
iconType = 14,
isEjectable = 15,
driveQElemPtr = 16,
fileSystemSpecPtr = 20
};
enum { // VolumeMountInfoHeader struct
vmiLength = 0,
vmiMedia = 2,
vmiFlags = 6,
SIZEOF_VolumeMountInfoHeader = 8
};
enum { // GetVolParmsInfoBuffer struct
vMVersion = 0,
vMAttrib = 2,
vMLocalHand = 6,
vMServerAdr = 10,
vMVolumeGrade = 14,
vMForeignPrivID = 18,
SIZEOF_GetVolParmsInfoBuffer = 20
};
// Finder Flags
enum { // FInfo struct
fdType = 0,
fdCreator = 4,
fdFlags = 8,
fdLocation = 10,
fdFldr = 14,
SIZEOF_FInfo = 16
};
enum { // FXInfo struct
fdIconID = 0,
fdUnused = 2,
fdScript = 8,
fdXFlags = 9,
fdComment = 10,
fdPutAway = 12,
SIZEOF_FXInfo = 16
};
enum { // HFileParam/HFileInfo struct
ioFRefNum = 24,
ioFVersNum = 26,
ioFDirIndex = 28,
ioFlAttrib = 30,
ioACUser = 31,
ioFlFndrInfo = 32,
ioDirID = 48,
ioFlStBlk = 52,
ioFlLgLen = 54,
ioFlPyLen = 58,
ioFlRStBlk = 62,
ioFlRLgLen = 64,
ioFlRPyLen = 68,
ioFlCrDat = 72,
ioFlMdDat = 76,
ioFlBkDat = 80,
ioFlXFndrInfo = 84,
ioFlParID = 100,
ioFlClpSiz = 104
};
enum { // DInfo struct
frRect = 0,
frFlags = 8,
frLocation = 10,
frView = 14,
SIZEOF_DInfo = 16
};
enum { // DXInfo struct
frScroll = 0,
frOpenChain = 4,
frScript = 8,
frXFlags = 9,
frComment = 10,
frPutAway = 12,
SIZEOF_DXInfo = 16
};
enum { // HDirParam/DirInfo struct
ioDrUsrWds = 32,
ioDrDirID = 48,
ioDrNmFls = 52,
ioDrCrDat = 72,
ioDrMdDat = 76,
ioDrBkDat = 80,
ioDrFndrInfo = 84,
ioDrParID = 100
};
enum { // WDParam struct
ioWDIndex = 26,
ioWDProcID = 28,
ioWDVRefNum = 32,
ioWDDirID = 48,
SIZEOF_WDParam = 52
};
enum { // HVolumeParam struct
ioVolIndex = 28,
ioVCrDate = 30,
ioVLsMod = 34,
ioVAtrb = 38,
ioVNmFls = 40,
ioVBitMap = 42,
ioAllocPtr = 44,
ioVNmAlBlks = 46,
ioVAlBlkSiz = 48,
ioVClpSiz = 52,
ioAlBlSt = 56,
ioVNxtCNID = 58,
ioVFrBlk = 62,
ioVSigWord = 64,
ioVDrvInfo = 66,
ioVDRefNum = 68,
ioVFSID = 70,
ioVBkUp = 72,
ioVSeqNum = 76,
ioVWrCnt = 78,
ioVFilCnt = 82,
ioVDirCnt = 86,
ioVFndrInfo = 90
};
enum { // CMovePBRec struct
ioNewName = 28,
ioNewDirID = 36
};
enum { // FCBPBRec struct
ioFCBIndx = 28,
ioFCBFlNm = 32,
ioFCBFlags = 36,
ioFCBStBlk = 38,
ioFCBEOF = 40,
ioFCBPLen = 44,
ioFCBCrPs = 48,
ioFCBVRefNum = 52,
ioFCBClpSiz = 54,
ioFCBParID = 58
};
// Volume control block
enum { // VCB struct
vcbFlags = 6,
vcbSigWord = 8,
vcbCrDate = 10,
vcbLsMod = 14,
vcbAtrb = 18,
vcbNmFls = 20,
vcbVBMSt = 22,
vcbAllocPtr = 24,
vcbNmAlBlks = 26,
vcbAlBlkSiz = 28,
vcbClpSiz = 32,
vcbAlBlSt = 36,
vcbNxtCNID = 38,
vcbFreeBks = 42,
vcbVN = 44,
vcbDrvNum = 72,
vcbDRefNum = 74,
vcbFSID = 76,
vcbVRefNum = 78,
vcbMAdr = 80,
vcbBufAdr = 84,
vcbMLen = 88,
vcbDirIndex = 90,
vcbDirBlk = 92,
vcbVolBkUp = 94,
vcbVSeqNum = 98,
vcbWrCnt = 100,
vcbXTClpSiz = 104,
vcbCTClpSiz = 108,
vcbNmRtDirs = 112,
vcbFilCnt = 114,
vcbDirCnt = 118,
vcbFndrInfo = 122,
vcbVCSize = 154,
vcbVBMCSiz = 156,
vcbCtlCSiz = 158,
vcbXTAlBlks = 160,
vcbCTAlBlks = 162,
vcbXTRef = 164,
vcbCTRef = 166,
vcbCtlBuf = 168,
vcbDirIDM = 172,
vcbOffsM = 176,
SIZEOF_VCB = 178
};
// Working directory control block
enum { // WDCBRec struct
wdVCBPtr = 0,
wdDirID = 4,
wdCatHint = 8,
wdProcID = 12,
SIZEOF_WDCBRec = 16
};
// File control block
enum { // FCBRec struct
fcbFlNm = 0,
fcbFlags = 4,
fcbTypByt = 5,
fcbSBlk = 6,
fcbEOF = 8,
fcbPLen = 12,
fcbCrPs = 16,
fcbVPtr = 20,
fcbBfAdr = 24,
fcbFlPos = 28,
fcbClmpSize = 30,
fcbBTCBPtr = 34,
fcbExtRec = 38,
fcbFType = 50,
fcbCatPos = 54,
fcbDirID = 58,
fcbCName = 62
};
enum { // ParsePathRec struct
ppNamePtr = 0,
ppStartOffset = 4,
ppComponentLength = 6,
ppMoreName = 8,
ppFoundDelimiter = 9,
SIZEOF_ParsePathRec = 10
};
enum { // HFSCIRec struct
compInterfMask = 0,
compInterfProc = 4,
log2PhyProc = 8,
stackTop = 12,
stackSize = 16,
stackPtr = 20,
idSector = 28,
SIZEOF_HFSCIRec = 40
};
enum { // DICIRec struct
maxVolNameLength = 8,
blockSize = 10,
SIZEOF_DICIRec = 24
};
enum { // FSDRec struct
fsdLink = 0,
fsdLength = 4,
fsdVersion = 6,
fileSystemFSID = 8,
fileSystemName = 10,
fileSystemSpec = 42,
fileSystemGlobalsPtr = 112,
fileSystemCommProc = 116,
fsdHFSCI = 132,
fsdDICI = 172,
SIZEOF_FSDRec = 196
};
#endif

View File

@ -0,0 +1,386 @@
/*
* $Id$
*
* extfs_macosx.mm - Access Mac OS X Finder and resource information (using Carbon calls).
* Based on:
*
* extfs_unix.cpp - MacOS file system for access native file system access, Unix specific stuff
*
* Basilisk II (C) 1997-2002 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <errno.h>
#include "sysdeps.h"
#include "extfs_macosx.h"
#include "extfs.h"
#define DEBUG 0
#include "debug.h"
// Default Finder flags
const uint16 DEFAULT_FINDER_FLAGS = kHasBeenInited;
/*
* Initialization
*/
void extfs_init(void)
{
}
/*
* Deinitialization
*/
void extfs_exit(void)
{
}
/*
* Add component to path name
*/
void add_path_component(char *path, const char *component)
{
int l = strlen(path);
if (l < MAX_PATH_LENGTH-1 && path[l-1] != '/') {
path[l] = '/';
path[l+1] = 0;
}
strncat(path, component, MAX_PATH_LENGTH-1);
}
/*
* Add rsrc to path name
*/
void add_rsrc(const char *path, char *dest)
{
int l = strlen(path);
if ( l > MAX_PATH_LENGTH-5 ) // If there is no room to add "rsrc\0"
return;
*dest = '\0';
strncat(dest, path, l);
if (l < MAX_PATH_LENGTH-1 && path[l-1] != '/') {
dest[l] = '/';
dest[l+1] = 0;
}
strcat(dest, "rsrc");
}
/*
* Resource forks on Mac OS X are kept on a UFS volume as /path/file/rsrc
*
* On HFS volumes, there is of course the data and rsrc fork, but the Darwin
* filesystem layer presents the resource fork using the above psuedo path
*/
static int open_rsrc(const char *path, int flag)
{
char path_rsrc[MAX_PATH_LENGTH];
add_rsrc(path, path_rsrc);
return open(path_rsrc, flag);
}
/*
* Finder info is a little bit harder. We need to use Carbon library calls to access them
*/
/*
* Get/set finder info for file/directory specified by full path
*/
struct ext2type {
const char *ext;
uint32 type;
uint32 creator;
};
static const ext2type e2t_translation[] = {
{".Z", FOURCC('Z','I','V','M'), FOURCC('L','Z','I','V')},
{".gz", FOURCC('G','z','i','p'), FOURCC('G','z','i','p')},
{".hqx", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')},
{".bin", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')},
{".pdf", FOURCC('P','D','F',' '), FOURCC('C','A','R','O')},
{".ps", FOURCC('T','E','X','T'), FOURCC('t','t','x','t')},
{".sit", FOURCC('S','I','T','!'), FOURCC('S','I','T','x')},
{".tar", FOURCC('T','A','R','F'), FOURCC('T','A','R',' ')},
{".uu", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')},
{".uue", FOURCC('T','E','X','T'), FOURCC('S','I','T','x')},
{".zip", FOURCC('Z','I','P',' '), FOURCC('Z','I','P',' ')},
{".8svx", FOURCC('8','S','V','X'), FOURCC('S','N','D','M')},
{".aifc", FOURCC('A','I','F','C'), FOURCC('T','V','O','D')},
{".aiff", FOURCC('A','I','F','F'), FOURCC('T','V','O','D')},
{".au", FOURCC('U','L','A','W'), FOURCC('T','V','O','D')},
{".mid", FOURCC('M','I','D','I'), FOURCC('T','V','O','D')},
{".midi", FOURCC('M','I','D','I'), FOURCC('T','V','O','D')},
{".mp2", FOURCC('M','P','G',' '), FOURCC('T','V','O','D')},
{".mp3", FOURCC('M','P','G',' '), FOURCC('T','V','O','D')},
{".wav", FOURCC('W','A','V','E'), FOURCC('T','V','O','D')},
{".bmp", FOURCC('B','M','P','f'), FOURCC('o','g','l','e')},
{".gif", FOURCC('G','I','F','f'), FOURCC('o','g','l','e')},
{".lbm", FOURCC('I','L','B','M'), FOURCC('G','K','O','N')},
{".ilbm", FOURCC('I','L','B','M'), FOURCC('G','K','O','N')},
{".jpg", FOURCC('J','P','E','G'), FOURCC('o','g','l','e')},
{".jpeg", FOURCC('J','P','E','G'), FOURCC('o','g','l','e')},
{".pict", FOURCC('P','I','C','T'), FOURCC('o','g','l','e')},
{".png", FOURCC('P','N','G','f'), FOURCC('o','g','l','e')},
{".sgi", FOURCC('.','S','G','I'), FOURCC('o','g','l','e')},
{".tga", FOURCC('T','P','I','C'), FOURCC('o','g','l','e')},
{".tif", FOURCC('T','I','F','F'), FOURCC('o','g','l','e')},
{".tiff", FOURCC('T','I','F','F'), FOURCC('o','g','l','e')},
{".htm", FOURCC('T','E','X','T'), FOURCC('M','O','S','S')},
{".html", FOURCC('T','E','X','T'), FOURCC('M','O','S','S')},
{".txt", FOURCC('T','E','X','T'), FOURCC('t','t','x','t')},
{".rtf", FOURCC('T','E','X','T'), FOURCC('M','S','W','D')},
{".c", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".C", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".cc", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".cpp", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".cxx", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".h", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".hh", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".hpp", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".hxx", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".s", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".S", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".i", FOURCC('T','E','X','T'), FOURCC('R','*','c','h')},
{".mpg", FOURCC('M','P','E','G'), FOURCC('T','V','O','D')},
{".mpeg", FOURCC('M','P','E','G'), FOURCC('T','V','O','D')},
{".mov", FOURCC('M','o','o','V'), FOURCC('T','V','O','D')},
{".fli", FOURCC('F','L','I',' '), FOURCC('T','V','O','D')},
{".avi", FOURCC('V','f','W',' '), FOURCC('T','V','O','D')},
{".qxd", FOURCC('X','D','O','C'), FOURCC('X','P','R','3')},
{".hfv", FOURCC('D','D','i','m'), FOURCC('d','d','s','k')},
{".dsk", FOURCC('D','D','i','m'), FOURCC('d','d','s','k')},
{".img", FOURCC('r','o','h','d'), FOURCC('d','d','s','k')},
{NULL, 0, 0} // End marker
};
// Mac OS X way of doing the above
#import <Foundation/NSString.h>
extern "C"
{
NSString *NSHFSTypeOfFile (const NSString *);
uint32 NSHFSTypeCodeFromFileType (const NSString *); // Actually returns an OSType
}
uint32 fileType (const char *cPath)
{
NSString *copy = [NSString stringWithCString: cPath],
*type = NSHFSTypeOfFile(copy);
if ( type == nil )
{
D(NSLog(@"No type for file %s", cPath));
return 0; // Should this be '????' or ' ' ?
}
D(NSLog(@"Got type %@ for %s", type, cPath));
return NSHFSTypeCodeFromFileType(type);
}
void get_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir)
{
FSRef fsRef;
int32 status;
// Set default finder info
Mac_memset(finfo, 0, SIZEOF_FInfo);
if (fxinfo)
Mac_memset(fxinfo, 0, SIZEOF_FXInfo);
WriteMacInt16(finfo + fdFlags, DEFAULT_FINDER_FLAGS);
WriteMacInt32(finfo + fdLocation, (uint32)-1);
status = FSPathMakeRef((const uint8 *)path, &fsRef, NULL);
if ( status == noErr )
{
FSCatalogInfo cInfo;
uint32 AllFinderInfo = kFSCatInfoFinderInfo + kFSCatInfoFinderXInfo;
status = FSGetCatalogInfo(&fsRef, AllFinderInfo, &cInfo, NULL, NULL, NULL);
if ( status == noErr )
{
D(printf("get_finfo(%s,...) - Got info of '%16.16s'\n", path, cInfo.finderInfo));
Host2Mac_memcpy(finfo, cInfo.finderInfo, SIZEOF_FInfo);
if (fxinfo)
Host2Mac_memcpy(fxinfo, cInfo.extFinderInfo, SIZEOF_FXInfo);
return;
}
else
printf("get_finfo(%s,...) failed to get catalog info\n", path);
}
else
printf("get_finfo(%s,...) failed to get FSRef\n", path);
// No Finder info file, translate file name extension to MacOS type/creator
if (!is_dir) {
int path_len = strlen(path);
for (int i=0; e2t_translation[i].ext; i++) {
int ext_len = strlen(e2t_translation[i].ext);
if (path_len < ext_len)
continue;
if (!strcmp(path + path_len - ext_len, e2t_translation[i].ext)) {
WriteMacInt32(finfo + fdType, e2t_translation[i].type);
WriteMacInt32(finfo + fdCreator, e2t_translation[i].creator);
break;
}
}
}
// Use alternate code to get type
uint32 type = fileType(path);
if ( type )
WriteMacInt32(finfo + fdType, type);
}
void set_finfo(const char *path, uint32 finfo, uint32 fxinfo, bool is_dir)
{
FSRef fsRef;
OSErr status;
status = FSPathMakeRef((const uint8 *)path, &fsRef, NULL);
if ( status == noErr )
{
FSCatalogInfo cInfo;
status = FSGetCatalogInfo(&fsRef, kFSCatInfoFinderInfo, &cInfo, NULL, NULL, NULL);
if ( status == noErr )
{
Mac2Host_memcpy(cInfo.finderInfo, finfo, SIZEOF_FInfo);
Mac2Host_memcpy(cInfo.extFinderInfo, fxinfo, SIZEOF_FXInfo);
FSSetCatalogInfo(&fsRef, kFSCatInfoFinderInfo, &cInfo);
}
}
}
/*
* Resource fork emulation functions
*/
uint32 get_rfork_size(const char *path)
{
// Open resource file
int fd = open_rsrc(path, O_RDONLY);
if (fd < 0)
return 0;
// Get size
off_t size = lseek(fd, 0, SEEK_END);
// Close file and return size
close(fd);
return size < 0 ? 0 : size;
}
int open_rfork(const char *path, int flag)
{
return open_rsrc(path, flag);
}
void close_rfork(const char *path, int fd)
{
close(fd);
}
/*
* Read "length" bytes from file to "buffer",
* returns number of bytes read (or -1 on error)
*/
ssize_t extfs_read(int fd, void *buffer, size_t length)
{
return read(fd, buffer, length);
}
/*
* Write "length" bytes from "buffer" to file,
* returns number of bytes written (or -1 on error)
*/
ssize_t extfs_write(int fd, void *buffer, size_t length)
{
return write(fd, buffer, length);
}
/*
* Remove file/directory (and associated helper files),
* returns false on error (and sets errno)
*/
bool extfs_remove(const char *path)
{
// Remove helpers first, don't complain if this fails
char helper_path[MAX_PATH_LENGTH];
add_rsrc(path, helper_path);
remove(helper_path);
// Now remove file or directory (and helper directories in the directory)
if (remove(path) < 0) {
if (errno == EISDIR || errno == ENOTEMPTY) {
return rmdir(path) == 0;
} else
return false;
}
return true;
}
/*
* Rename/move file/directory (and associated helper files),
* returns false on error (and sets errno)
*/
bool extfs_rename(const char *old_path, const char *new_path)
{
// Rename helpers first, don't complain if this fails
char old_helper_path[MAX_PATH_LENGTH], new_helper_path[MAX_PATH_LENGTH];
add_rsrc(old_path, old_helper_path);
add_rsrc(new_path, new_helper_path);
rename(old_helper_path, new_helper_path);
// Now rename file
return rename(old_path, new_path) == 0;
}

View File

@ -0,0 +1,178 @@
/*
* $Id$
*
* macos_util_macosx.h - Work around clashes with the enums in <CarbonCore/OSUtils.h>
* Based on:
*
* macos_util.h - MacOS definitions/utility functions
*
* Basilisk II (C) 1997-2002 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef MACOS_UTIL_H
#define MACOS_UTIL_H
#include "cpu_emulation.h"
#import <CarbonCore/OSUtils.h>
/*
* Queues
*/
enum { // QElem struct
qLink = 0,
qType = 4,
qData = 6
};
enum { // QHdr struct
qFlags = 0,
qHead = 2,
qTail = 6
};
/*
* Definitions for Device Manager
*/
// Misc constants
enum { // IOParam struct
ioTrap = 6,
ioCmdAddr = 8,
ioCompletion = 12,
ioResult = 16,
ioNamePtr = 18,
ioVRefNum = 22,
ioRefNum = 24,
ioVersNum = 26,
ioPermssn = 27,
ioMisc = 28,
ioBuffer = 32,
ioReqCount = 36,
ioActCount = 40,
ioPosMode = 44,
ioPosOffset = 46,
ioWPosOffset = 46, // Wide positioning offset when ioPosMode has kWidePosOffsetBit set
SIZEOF_IOParam = 50
};
enum { // CntrlParam struct
csCode = 26,
csParam = 28
};
enum { // DrvSts struct
dsTrack = 0,
dsWriteProt = 2,
dsDiskInPlace = 3,
dsInstalled = 4,
dsSides = 5,
dsQLink = 6,
dsQType = 10,
dsQDrive = 12,
dsQRefNum = 14,
dsQFSID = 16,
dsTwoSideFmt = 18,
dsNewIntf = 19,
dsDiskErrs = 20,
dsMFMDrive = 22,
dsMFMDisk = 23,
dsTwoMegFmt = 24
};
enum { // DrvSts2 struct
dsDriveSize = 18,
dsDriveS1 = 20,
dsDriveType = 22,
dsDriveManf = 24,
dsDriveChar = 26,
dsDriveMisc = 28,
SIZEOF_DrvSts = 30
};
enum { // DCtlEntry struct
dCtlDriver = 0,
dCtlFlags = 4,
dCtlQHdr = 6,
dCtlPosition = 16,
dCtlStorage = 20,
dCtlRefNum = 24,
dCtlCurTicks = 26,
dCtlWindow = 30,
dCtlDelay = 34,
dCtlEMask = 36,
dCtlMenu = 38,
dCtlSlot = 40,
dCtlSlotId = 41,
dCtlDevBase = 42,
dCtlOwner = 46,
dCtlExtDev = 50,
dCtlFillByte = 51,
dCtlNodeID = 52
};
/*
* Definitions for Deferred Task Manager
*/
enum { // DeferredTask struct
dtFlags = 6,
dtAddr = 8,
dtParam = 12,
dtReserved = 16
};
// Definitions for DebugUtil() Selector
enum {
duDebuggerGetMax = 0,
duDebuggerEnter = 1,
duDebuggerExit = 2,
duDebuggerPoll = 3,
duGetPageState = 4,
duPageFaultFatal = 5,
duDebuggerLockMemory = 6,
duDebuggerUnlockMemory = 7,
duEnterSupervisorMode = 8
};
// Functions
extern void EnqueueMac(uint32 elem, uint32 list); // Enqueue QElem in list
extern int FindFreeDriveNumber(int num); // Find first free drive number, starting at "num"
extern void MountVolume(void *fh); // Mount volume with given file handle (see sys.h)
extern void FileDiskLayout(loff_t size, uint8 *data, loff_t &start_byte, loff_t &real_size); // Calculate disk image file layout given file size and first 256 data bytes
extern uint32 DebugUtil(uint32 Selector); // DebugUtil() Replacement
extern uint32 TimeToMacTime(time_t t); // Convert time_t value to MacOS time
// Construct four-character-code
#define FOURCC(a,b,c,d) (((uint32)(a) << 24) | ((uint32)(b) << 16) | ((uint32)(c) << 8) | (uint32)(d))
// Emulator identification codes (4 and 2 characters)
const uint32 EMULATOR_ID_4 = 0x62617369; // 'basi'
const uint16 EMULATOR_ID_2 = 0x6261; // 'ba'
// Test if basic MacOS initializations (of the ROM) are done
static inline bool HasMacStarted(void)
{
return ReadMacInt32(0xcfc) == FOURCC('W','L','S','C'); // Mac warm start flag
}
#endif

View File

@ -0,0 +1,29 @@
/*
* main_macosx.h - Prototypes for Mac OS X general definitions
*
* $Id$
*
* Basilisk II (C) 1997-2002 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
bool InitEmulator ();
void QuitEmuNoExit();
extern void ErrorAlert (const char *text);
extern void WarningAlert(const char *text);
extern bool ChoiceAlert (const char *text, const char *pos, const char *neg);

View File

@ -0,0 +1,549 @@
/*
* $Id$
*
* main_macosx.mm - Startup code for MacOS X
* Based (in a small way) on the default main.m,
and on Basilisk's main_unix.cpp
*
* Basilisk II (C) 1997-2002 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#define PTHREADS
#include "sysdeps.h"
#ifdef HAVE_PTHREADS
# include <pthread.h>
#endif
#if REAL_ADDRESSING || DIRECT_ADDRESSING
# include <sys/mman.h>
#endif
#include "cpu_emulation.h"
#include "macos_util_macosx.h"
#include "main.h"
#include "prefs.h"
#include "prefs_editor.h"
#include "rom_patches.h"
#include "sys.h"
#include "timer.h"
#include "user_strings.h"
#include "version.h"
#include "video.h"
#include "vm_alloc.h"
#include "xpram.h"
#ifdef ENABLE_MON
# include "mon.h"
#endif
#define DEBUG 0
#include "debug.h"
#import <AppKit/AppKit.h>
#include "main_macosx.h" // To bridge between main() and misc. classes
// Constants
const char ROM_FILE_NAME[] = "ROM";
const int SIG_STACK_SIZE = SIGSTKSZ; // Size of signal stack
const int SCRATCH_MEM_SIZE = 0x10000; // Size of scratch memory area
// CPU and FPU type, addressing mode
int CPUType;
bool CPUIs68060;
int FPUType;
bool TwentyFourBitAddressing;
// Global variables
#ifdef HAVE_PTHREADS
static pthread_mutex_t intflag_lock = PTHREAD_MUTEX_INITIALIZER; // Mutex to protect InterruptFlags
#define LOCK_INTFLAGS pthread_mutex_lock(&intflag_lock)
#define UNLOCK_INTFLAGS pthread_mutex_unlock(&intflag_lock)
#else
#define LOCK_INTFLAGS
#define UNLOCK_INTFLAGS
#endif
#if USE_SCRATCHMEM_SUBTERFUGE
uint8 *ScratchMem = NULL; // Scratch memory for Mac ROM writes
#endif
#if defined(HAVE_TIMER_CREATE) && defined(_POSIX_REALTIME_SIGNALS)
#define SIG_TIMER SIGRTMIN
static timer_t timer; // 60Hz timer
#endif
//#ifdef ENABLE_MON
static struct sigaction sigint_sa; // sigaction for SIGINT handler
static void sigint_handler(...);
//#endif
#if REAL_ADDRESSING
static bool lm_area_mapped = false; // Flag: Low Memory area mmap()ped
#endif
/*
* Main program
*/
static void usage(const char *prg_name)
{
printf("Usage: %s [OPTION...]\n", prg_name);
printf("\nUnix options:\n");
printf(" --help\n display this usage message\n");
printf(" --break ADDRESS\n set ROM breakpoint\n");
printf(" --rominfo\n dump ROM information\n");
PrefsPrintUsage();
exit(0);
}
int main(int argc, char **argv)
{
// Initialize variables
RAMBaseHost = NULL;
ROMBaseHost = NULL;
srand(time(NULL));
tzset();
// Print some info
printf(GetString(STR_ABOUT_TEXT1), VERSION_MAJOR, VERSION_MINOR);
printf(" %s\n", GetString(STR_ABOUT_TEXT2));
// Read preferences
PrefsInit(argc, argv);
// Parse command line arguments
for (int i=1; i<argc; i++) {
if (strcmp(argv[i], "--help") == 0) {
usage(argv[0]);
} else if (strncmp(argv[i], "-psn_", 5) == 0) {// OS X process identifier
i++;
} else if (strcmp(argv[i], "--break") == 0) {
i++;
if (i < argc)
ROMBreakpoint = strtol(argv[i], NULL, 0);
} else if (strcmp(argv[i], "--rominfo") == 0) {
PrintROMInfo = true;
} else if (argv[i][0] == '-') {
fprintf(stderr, "Unrecognized option '%s'\n", argv[i]);
usage(argv[0]);
}
}
// Init system routines
SysInit();
// Open display, attach to window server,
// load pre-instantiated classes from MainMenu.nib, start run loop
int i = NSApplicationMain(argc, (const char **)argv);
// We currently never get past here, because QuitEmulator() does an exit()
// Exit system routines
SysExit();
// Exit preferences
PrefsExit();
return i;
}
#define QuitEmulator() QuitEmuNoExit() ; return NO;
bool InitEmulator (void)
{
char str[256];
// Read RAM size
RAMSize = PrefsFindInt32("ramsize") & 0xfff00000; // Round down to 1MB boundary
if (RAMSize < 1024*1024) {
WarningAlert(GetString(STR_SMALL_RAM_WARN));
RAMSize = 1024*1024;
}
#if REAL_ADDRESSING || DIRECT_ADDRESSING
RAMSize = RAMSize & -getpagesize(); // Round down to page boundary
#endif
// Initialize VM system
vm_init();
#if REAL_ADDRESSING
// Flag: RAM and ROM are contigously allocated from address 0
bool memory_mapped_from_zero = false;
// Under Solaris/SPARC and NetBSD/m68k, Basilisk II is known to crash
// when trying to map a too big chunk of memory starting at address 0
#if defined(OS_solaris) || defined(OS_netbsd)
const bool can_map_all_memory = false;
#else
const bool can_map_all_memory = true;
#endif
// Try to allocate all memory from 0x0000, if it is not known to crash
if (can_map_all_memory && (vm_acquire_fixed(0, RAMSize + 0x100000) == 0)) {
D(bug("Could allocate RAM and ROM from 0x0000\n"));
memory_mapped_from_zero = true;
}
// Otherwise, just create the Low Memory area (0x0000..0x2000)
else if (vm_acquire_fixed(0, 0x2000) == 0) {
D(bug("Could allocate the Low Memory globals\n"));
lm_area_mapped = true;
}
// Exit on failure
else {
sprintf(str, GetString(STR_LOW_MEM_MMAP_ERR), strerror(errno));
ErrorAlert(str);
QuitEmulator();
}
#endif
// Create areas for Mac RAM and ROM
#if REAL_ADDRESSING
if (memory_mapped_from_zero) {
RAMBaseHost = (uint8 *)0;
ROMBaseHost = RAMBaseHost + RAMSize;
}
else
#endif
{
RAMBaseHost = (uint8 *)vm_acquire(RAMSize);
ROMBaseHost = (uint8 *)vm_acquire(0x100000);
if (RAMBaseHost == VM_MAP_FAILED || ROMBaseHost == VM_MAP_FAILED) {
ErrorAlert(STR_NO_MEM_ERR);
QuitEmulator();
}
}
#if USE_SCRATCHMEM_SUBTERFUGE
// Allocate scratch memory
ScratchMem = (uint8 *)vm_acquire(SCRATCH_MEM_SIZE);
if (ScratchMem == VM_MAP_FAILED) {
ErrorAlert(STR_NO_MEM_ERR);
QuitEmulator();
}
ScratchMem += SCRATCH_MEM_SIZE/2; // ScratchMem points to middle of block
#endif
#if DIRECT_ADDRESSING
// RAMBaseMac shall always be zero
MEMBaseDiff = (uintptr)RAMBaseHost;
RAMBaseMac = 0;
ROMBaseMac = Host2MacAddr(ROMBaseHost);
#endif
#if REAL_ADDRESSING
RAMBaseMac = (uint32)RAMBaseHost;
ROMBaseMac = (uint32)ROMBaseHost;
#endif
D(bug("Mac RAM starts at %p (%08x)\n", RAMBaseHost, RAMBaseMac));
D(bug("Mac ROM starts at %p (%08x)\n", ROMBaseHost, ROMBaseMac));
// Get rom file path from preferences
const char *rom_path = PrefsFindString("rom");
// Load Mac ROM
int rom_fd = open(rom_path ? rom_path : ROM_FILE_NAME, O_RDONLY);
if (rom_fd < 0) {
ErrorAlert(STR_NO_ROM_FILE_ERR);
QuitEmulator();
}
printf(GetString(STR_READING_ROM_FILE));
ROMSize = lseek(rom_fd, 0, SEEK_END);
if (ROMSize != 64*1024 && ROMSize != 128*1024 && ROMSize != 256*1024 && ROMSize != 512*1024 && ROMSize != 1024*1024) {
ErrorAlert(STR_ROM_SIZE_ERR);
close(rom_fd);
QuitEmulator();
}
lseek(rom_fd, 0, SEEK_SET);
if (read(rom_fd, ROMBaseHost, ROMSize) != (ssize_t)ROMSize) {
ErrorAlert(STR_ROM_FILE_READ_ERR);
close(rom_fd);
QuitEmulator();
}
// Initialize everything
if (!InitAll())
QuitEmulator();
D(bug("Initialization complete\n"));
#ifdef ENABLE_MON
// Setup SIGINT handler to enter mon
sigemptyset(&sigint_sa.sa_mask);
sigint_sa.sa_handler = (void (*)(int))sigint_handler;
sigint_sa.sa_flags = 0;
sigaction(SIGINT, &sigint_sa, NULL);
#endif
return YES;
}
#undef QuitEmulator()
/*
* Quit emulator
*/
void QuitEmuNoExit()
{
extern NSApplication *NSApp;
D(bug("QuitEmulator\n"));
// Exit 680x0 emulation
Exit680x0();
// Deinitialize everything
ExitAll();
// Free ROM/RAM areas
if (RAMBaseHost != VM_MAP_FAILED) {
vm_release(RAMBaseHost, RAMSize);
RAMBaseHost = NULL;
}
if (ROMBaseHost != VM_MAP_FAILED) {
vm_release(ROMBaseHost, 0x100000);
ROMBaseHost = NULL;
}
#if USE_SCRATCHMEM_SUBTERFUGE
// Delete scratch memory area
if (ScratchMem != (uint8 *)VM_MAP_FAILED) {
vm_release((void *)(ScratchMem - SCRATCH_MEM_SIZE/2), SCRATCH_MEM_SIZE);
ScratchMem = NULL;
}
#endif
#if REAL_ADDRESSING
// Delete Low Memory area
if (lm_area_mapped)
vm_release(0, 0x2000);
#endif
// Exit VM wrappers
vm_exit();
// Exit system routines
SysExit();
// Exit preferences
PrefsExit();
// Stop run loop
[NSApp terminate: nil];
}
void QuitEmulator(void)
{
QuitEmuNoExit();
exit(0);
}
/*
* Code was patched, flush caches if neccessary (i.e. when using a real 680x0
* or a dynamically recompiling emulator)
*/
void FlushCodeCache(void *start, uint32 size)
{
}
/*
* SIGINT handler, enters mon
*/
#ifdef ENABLE_MON
static void sigint_handler(...)
{
uaecptr nextpc;
extern void m68k_dumpstate(uaecptr *nextpc);
m68k_dumpstate(&nextpc);
VideoQuitFullScreen();
char *arg[4] = {"mon", "-m", "-r", NULL};
mon(3, arg);
QuitEmulator();
}
#endif
/*
* Mutexes
*/
#ifdef HAVE_PTHREADS
struct B2_mutex {
B2_mutex() { pthread_mutex_init(&m, NULL); }
~B2_mutex() { pthread_mutex_unlock(&m); pthread_mutex_destroy(&m); }
pthread_mutex_t m;
};
B2_mutex *B2_create_mutex(void)
{
return new B2_mutex;
}
void B2_lock_mutex(B2_mutex *mutex)
{
pthread_mutex_lock(&mutex->m);
}
void B2_unlock_mutex(B2_mutex *mutex)
{
pthread_mutex_unlock(&mutex->m);
}
void B2_delete_mutex(B2_mutex *mutex)
{
delete mutex;
}
#else
struct B2_mutex {
int dummy;
};
B2_mutex *B2_create_mutex(void)
{
return new B2_mutex;
}
void B2_lock_mutex(B2_mutex *mutex)
{
}
void B2_unlock_mutex(B2_mutex *mutex)
{
}
void B2_delete_mutex(B2_mutex *mutex)
{
delete mutex;
}
#endif
/*
* Interrupt flags (must be handled atomically!)
*/
uint32 InterruptFlags = 0;
void SetInterruptFlag(uint32 flag)
{
LOCK_INTFLAGS;
InterruptFlags |= flag;
UNLOCK_INTFLAGS;
}
void ClearInterruptFlag(uint32 flag)
{
LOCK_INTFLAGS;
InterruptFlags &= ~flag;
UNLOCK_INTFLAGS;
}
/*
* Display error alert
*/
//#import <Foundation/NSString.h>
#import <AppKit/NSPanel.h>
extern "C"
{
int NSRunAlertPanel (NSString *title, NSString *msg,
NSString *defaultButton,
NSString *alternateButton,
NSString *otherButton, ...);
int NSRunInformationalAlertPanel(NSString *title, NSString *msg,
NSString *defaultButton,
NSString *alternateButton,
NSString *otherButton, ...);
int NSRunCriticalAlertPanel (NSString *title, NSString *msg,
NSString *defaultButton,
NSString *alternateButton,
NSString *otherButton, ...);
}
void ErrorAlert(const char *text)
{
NSString *title = [NSString stringWithCString:
GetString(STR_ERROR_ALERT_TITLE) ];
NSString *error = [NSString stringWithCString: text];
NSString *button = [NSString stringWithCString: GetString(STR_QUIT_BUTTON) ];
// If we have a full screen mode, quit it here?
NSLog(error);
NSRunCriticalAlertPanel(title, error, button, nil, nil);
}
/*
* Display warning alert
*/
void WarningAlert(const char *text)
{
NSString *title = [NSString stringWithCString:
GetString(STR_WARNING_ALERT_TITLE) ];
NSString *warning = [NSString stringWithCString: text];
NSString *button = [NSString stringWithCString: GetString(STR_OK_BUTTON) ];
NSLog(warning);
NSRunAlertPanel(title, warning, button, nil, nil);
}
/*
* Display choice alert
*/
bool ChoiceAlert(const char *text, const char *pos, const char *neg)
{
NSString *title = [NSString stringWithCString:
GetString(STR_WARNING_ALERT_TITLE) ];
NSString *warning = [NSString stringWithCString: text];
NSString *yes = [NSString stringWithCString: pos];
NSString *no = [NSString stringWithCString: neg];
NSLog(warning);
return NSRunInformationalAlertPanel(title, warning, yes, no, nil);
}

View File

@ -0,0 +1,35 @@
/*
* $Id$
*
* misc_macosx.h - Some prototypes of functions defined in misc_macosx.mm
*
* Basilisk II (C) 1997-2001 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#if defined(__APPLE__) && defined(__MACH__)
// This means we are on Mac OS X of some sort
#endif
extern void ErrorSheet (NSString *msg1, NSString *msg2,
NSString *button, NSWindow *win),
WarningSheet (NSString *msg1, NSString *msg2,
NSString *button, NSWindow *win),
InfoSheet (NSString *msg1, NSString *msg2,
NSString *button, NSWindow * win);
extern int frequencyToTickDelay (float frequency);

View File

@ -0,0 +1,76 @@
/*
* $Id$
*
* misc_macosx.m - Miscellaneous Mac OS X routines.
*
* Basilisk II (C) 1997-2002 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#import <AppKit/AppKit.h>
#import "sysdeps.h" // Types used in Basilisk C++ code
#import <prefs.h>
#define DEBUG 0
#import <debug.h>
/************************************************************************/
/* Display Errors and Warnings in a sliding thingy attached to a */
/* particular window, instead of as a separate window (Panel or Dialog) */
/************************************************************************/
void ErrorSheet (NSString * message1, NSString * message2,
NSString * button, NSWindow * win)
{
NSBeginCriticalAlertSheet(message1, button, nil, nil, win,
nil, NULL, NULL, NULL, message2);
}
void WarningSheet (NSString * message1, NSString * message2,
NSString * button, NSWindow * win)
{
NSBeginAlertSheet(message1, button, nil, nil, win,
nil, NULL, NULL, NULL, message2);
}
void InfoSheet (NSString * message1, NSString * message2,
NSString * button, NSWindow * win)
{
NSBeginInformationalAlertSheet(message1, button, nil, nil, win,
nil, NULL, NULL, NULL, message2);
}
// Convert a frequency (i.e. updates per second) to a 60hz tick delay, and update prefs
int frequencyToTickDelay (float freq)
{
if ( freq == 0.0 )
return 0;
else
{
int delay = (int) (60.0 / freq);
PrefsReplaceInt32("frameskip", delay);
return delay;
}
}

View File

@ -0,0 +1,97 @@
/*
* $Id$
*
* prefs_macosx.cpp - Preferences handling, Unix specific.
* Based on prefs_unix.cpp
*
* Basilisk II (C) 1997-2002 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sysdeps.h"
#include <stdio.h>
#include <stdlib.h>
#include "prefs.h"
// Platform-specific preferences items
prefs_desc platform_prefs_items[] = {
{NULL, TYPE_END, false, NULL} // End of list
};
// Prefs file name and path
const char PREFS_FILE_NAME[] = ".basilisk_ii_prefs";
static char prefs_path[1024];
/*
* Load preferences from settings file
*/
void LoadPrefs(void)
{
// Construct prefs path
prefs_path[0] = 0;
char *home = getenv("HOME");
if (home != NULL && strlen(home) < 1000) {
strncpy(prefs_path, home, 1000);
strcat(prefs_path, "/");
}
strcat(prefs_path, PREFS_FILE_NAME);
// Read preferences from settings file
FILE *f = fopen(prefs_path, "r");
if (f != NULL) {
// Prefs file found, load settings
LoadPrefsFromStream(f);
fclose(f);
} else {
// No prefs file, save defaults
SavePrefs();
}
}
/*
* Save preferences to settings file
*/
void SavePrefs(void)
{
FILE *f;
if ((f = fopen(prefs_path, "w")) != NULL) {
SavePrefsToStream(f);
fclose(f);
}
}
/*
* Add defaults of platform-specific prefs items
* You may also override the defaults set in PrefsInit()
*/
void AddPlatformPrefsDefaults(void)
{
PrefsReplaceString("extfs", "/");
PrefsReplaceString("screen", "win/512/342/32");
}

View File

@ -0,0 +1,292 @@
/*
* sysdeps.h - System dependent definitions for Mac OS X.
* Based on Unix version
*
* $Id$
*
* Basilisk II (C) 1997-2001 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef SYSDEPS_H
#define SYSDEPS_H
#ifndef __STDC__
#error "Your compiler is not ANSI. Get a real one."
#endif
#include "config.h"
#include "user_strings_unix.h"
#ifndef STDC_HEADERS
#error "You don't have ANSI C header files."
#endif
#ifdef HAVE_UNISTD_H
# include <sys/types.h>
# include <unistd.h>
#endif
#include <netinet/in.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
/* Emulator and host address space are distinct */
#ifndef REAL_ADDRESSING
#define REAL_ADDRESSING 0
#endif
/* Linear address translation (i.e. just an offset between Emulator & host) */
#ifndef DIRECT_ADDRESSING
#define DIRECT_ADDRESSING 1
#endif
/* Using 68k emulator */
#define EMULATED_68K 1
/* The m68k emulator uses a prefetch buffer ? */
#define USE_PREFETCH_BUFFER 0
/* Mac ROM is write protected when banked memory is used */
#if REAL_ADDRESSING || DIRECT_ADDRESSING
# define ROM_IS_WRITE_PROTECTED 0
# define USE_SCRATCHMEM_SUBTERFUGE 1
#else
# define ROM_IS_WRITE_PROTECTED 1
#endif
/* ExtFS is supported */
#define SUPPORTS_EXTFS 1
/* Data types */
typedef unsigned char uint8;
typedef signed char int8;
#if SIZEOF_SHORT == 2
typedef unsigned short uint16;
typedef short int16;
#elif SIZEOF_INT == 2
typedef unsigned int uint16;
typedef int int16;
#else
#error "No 2 byte type, you lose."
#endif
#if SIZEOF_INT == 4
typedef unsigned int uint32;
typedef int int32;
#elif SIZEOF_LONG == 4
typedef unsigned long uint32;
typedef long int32;
#else
#error "No 4 byte type, you lose."
#endif
#if SIZEOF_LONG == 8
typedef unsigned long uint64;
typedef long int64;
#define VAL64(a) (a ## l)
#define UVAL64(a) (a ## ul)
#elif SIZEOF_LONG_LONG == 8
typedef unsigned long long uint64;
typedef long long int64;
#define VAL64(a) (a ## LL)
#define UVAL64(a) (a ## uLL)
#else
#error "No 8 byte type, you lose."
#endif
#if SIZEOF_VOID_P == 4
typedef uint32 uintptr;
typedef int32 intptr;
#elif SIZEOF_VOID_P == 8
typedef uint64 uintptr;
typedef int64 intptr;
#else
#error "Unsupported size of pointer"
#endif
/* Time data type for Time Manager emulation */
#ifdef HAVE_CLOCK_GETTIME
typedef struct timespec tm_time_t;
#else
typedef struct timeval tm_time_t;
#endif
/* Offset Mac->Unix time in seconds */
#define TIME_OFFSET 0x7c25b080
/* UAE CPU data types */
#define uae_s8 int8
#define uae_u8 uint8
#define uae_s16 int16
#define uae_u16 uint16
#define uae_s32 int32
#define uae_u32 uint32
#define uae_s64 int64
#define uae_u64 uint64
typedef uae_u32 uaecptr;
/* Alignment restrictions */
#if defined(__i386__) || defined(__powerpc__) || defined(__m68k__)
# define CPU_CAN_ACCESS_UNALIGNED
#endif
/* Timing functions */
extern uint64 GetTicks_usec(void);
extern void Delay_usec(uint32 usec);
/* UAE CPU defines */
#ifdef WORDS_BIGENDIAN
#ifdef CPU_CAN_ACCESS_UNALIGNED
/* Big-endian CPUs which can do unaligned accesses */
static inline uae_u32 do_get_mem_long(uae_u32 *a) {return *a;}
static inline uae_u32 do_get_mem_word(uae_u16 *a) {return *a;}
static inline void do_put_mem_long(uae_u32 *a, uae_u32 v) {*a = v;}
static inline void do_put_mem_word(uae_u16 *a, uae_u32 v) {*a = v;}
#else /* CPU_CAN_ACCESS_UNALIGNED */
#ifdef sgi
/* The SGI MIPSPro compilers can do unaligned accesses given enough hints.
* They will automatically inline these routines. */
#ifdef __cplusplus
extern "C" { /* only the C compiler does unaligned accesses */
#endif
extern uae_u32 do_get_mem_long(uae_u32 *a);
extern uae_u32 do_get_mem_word(uae_u16 *a);
extern void do_put_mem_long(uae_u32 *a, uae_u32 v);
extern void do_put_mem_word(uae_u16 *a, uae_u32 v);
#ifdef __cplusplus
}
#endif
#else /* sgi */
/* Big-endian CPUs which can not do unaligned accesses (this is not the most efficient way to do this...) */
static inline uae_u32 do_get_mem_long(uae_u32 *a) {uint8 *b = (uint8 *)a; return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];}
static inline uae_u32 do_get_mem_word(uae_u16 *a) {uint8 *b = (uint8 *)a; return (b[0] << 8) | b[1];}
static inline void do_put_mem_long(uae_u32 *a, uae_u32 v) {uint8 *b = (uint8 *)a; b[0] = v >> 24; b[1] = v >> 16; b[2] = v >> 8; b[3] = v;}
static inline void do_put_mem_word(uae_u16 *a, uae_u32 v) {uint8 *b = (uint8 *)a; b[0] = v >> 8; b[1] = v;}
#endif /* sgi */
#endif /* CPU_CAN_ACCESS_UNALIGNED */
#else /* WORDS_BIGENDIAN */
#ifdef __i386__
/* Intel x86 */
#define X86_PPRO_OPT
static inline uae_u32 do_get_mem_long(uae_u32 *a) {uint32 retval; __asm__ ("bswap %0" : "=r" (retval) : "0" (*a) : "cc"); return retval;}
#ifdef X86_PPRO_OPT
static inline uae_u32 do_get_mem_word(uae_u16 *a) {uint32 retval; __asm__ ("movzwl %w1,%k0\n\tshll $16,%k0\n\tbswapl %k0\n" : "=&r" (retval) : "m" (*a) : "cc"); return retval;}
#else
static inline uae_u32 do_get_mem_word(uae_u16 *a) {uint32 retval; __asm__ ("xorl %k0,%k0\n\tmovw %w1,%w0\n\trolw $8,%w0" : "=&r" (retval) : "m" (*a) : "cc"); return retval;}
#endif
#define HAVE_GET_WORD_UNSWAPPED
#define do_get_mem_word_unswapped(a) ((uae_u32)*((uae_u16 *)(a)))
static inline void do_put_mem_long(uae_u32 *a, uae_u32 v) {__asm__ ("bswap %0" : "=r" (v) : "0" (v) : "cc"); *a = v;}
#ifdef X86_PPRO_OPT
static inline void do_put_mem_word(uae_u16 *a, uae_u32 v) {__asm__ ("bswapl %0" : "=&r" (v) : "0" (v << 16) : "cc"); *a = v;}
#else
static inline void do_put_mem_word(uae_u16 *a, uae_u32 v) {__asm__ ("rolw $8,%0" : "=r" (v) : "0" (v) : "cc"); *a = v;}
#endif
#define HAVE_OPTIMIZED_BYTESWAP_32
/* bswap doesn't affect condition codes */
static inline uae_u32 do_byteswap_32(uae_u32 v) {__asm__ ("bswap %0" : "=r" (v) : "0" (v)); return v;}
#define HAVE_OPTIMIZED_BYTESWAP_16
#ifdef X86_PPRO_OPT
static inline uae_u32 do_byteswap_16(uae_u32 v) {__asm__ ("bswapl %0" : "=&r" (v) : "0" (v << 16) : "cc"); return v;}
#else
static inline uae_u32 do_byteswap_16(uae_u32 v) {__asm__ ("rolw $8,%0" : "=r" (v) : "0" (v) : "cc"); return v;}
#endif
#elif defined(CPU_CAN_ACCESS_UNALIGNED)
/* Other little-endian CPUs which can do unaligned accesses */
static inline uae_u32 do_get_mem_long(uae_u32 *a) {uint32 x = *a; return (x >> 24) | (x >> 8) & 0xff00 | (x << 8) & 0xff0000 | (x << 24);}
static inline uae_u32 do_get_mem_word(uae_u16 *a) {uint16 x = *a; return (x >> 8) | (x << 8);}
static inline void do_put_mem_long(uae_u32 *a, uae_u32 v) {*a = (v >> 24) | (v >> 8) & 0xff00 | (v << 8) & 0xff0000 | (v << 24);}
static inline void do_put_mem_word(uae_u16 *a, uae_u32 v) {*a = (v >> 8) | (v << 8);}
#else /* CPU_CAN_ACCESS_UNALIGNED */
/* Other little-endian CPUs which can not do unaligned accesses (this needs optimization) */
static inline uae_u32 do_get_mem_long(uae_u32 *a) {uint8 *b = (uint8 *)a; return (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];}
static inline uae_u32 do_get_mem_word(uae_u16 *a) {uint8 *b = (uint8 *)a; return (b[0] << 8) | b[1];}
static inline void do_put_mem_long(uae_u32 *a, uae_u32 v) {uint8 *b = (uint8 *)a; b[0] = v >> 24; b[1] = v >> 16; b[2] = v >> 8; b[3] = v;}
static inline void do_put_mem_word(uae_u16 *a, uae_u32 v) {uint8 *b = (uint8 *)a; b[0] = v >> 8; b[1] = v;}
#endif /* CPU_CAN_ACCESS_UNALIGNED */
#endif /* WORDS_BIGENDIAN */
#ifndef HAVE_OPTIMIZED_BYTESWAP_32
static inline uae_u32 do_byteswap_32(uae_u32 v)
{ return (((v >> 24) & 0xff) | ((v >> 8) & 0xff00) | ((v & 0xff) << 24) | ((v & 0xff00) << 8)); }
#endif
#ifndef HAVE_OPTIMIZED_BYTESWAP_16
static inline uae_u32 do_byteswap_16(uae_u32 v)
{ return (((v >> 8) & 0xff) | ((v & 0xff) << 8)); }
#endif
#define do_get_mem_byte(a) ((uae_u32)*((uae_u8 *)(a)))
#define do_put_mem_byte(a, v) (*(uae_u8 *)(a) = (v))
#define call_mem_get_func(func, addr) ((*func)(addr))
#define call_mem_put_func(func, addr, v) ((*func)(addr, v))
#define __inline__ inline
#define CPU_EMU_SIZE 0
#undef NO_INLINE_MEMORY_ACCESS
#undef MD_HAVE_MEM_1_FUNCS
#define ENUMDECL typedef enum
#define ENUMNAME(name) name
#define write_log printf
#undef USE_MAPPED_MEMORY
#undef CAN_MAP_MEMORY
#ifdef X86_ASSEMBLY
#define ASM_SYM_FOR_FUNC(a) __asm__(a)
#else
#define ASM_SYM_FOR_FUNC(a)
#endif
#ifndef REGPARAM
# define REGPARAM
#endif
#define REGPARAM2
#endif

View File

@ -0,0 +1,67 @@
/*
* video_macosx.h - Some video constants and globals
*
* $Id$
*
* Basilisk II (C) 1997-2001 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#import <video.h>
/* Set the strategy for drawing the bitmap in the Mac OS X window */
//#define CGIMAGEREF 15.05fps
//#define CGDRAWBITMAP 15.2fps
#define NSBITMAP 15.1fps
#define MIN_WIDTH 512
#define MIN_HEIGHT 342
#define MAX_WIDTH 1240
#define MAX_HEIGHT 1024
// Display types
enum
{
DISPLAY_OPENGL,
DISPLAY_SCREEN,
DISPLAY_WINDOW
};
extern uint8 display_type,
frame_skip;
extern uint16 init_width,
init_height,
init_depth,
screen_height;
extern uint8 bits_from_depth (const video_depth);
extern bool parse_screen_prefs (const char *);
extern void resizeWinTo (const uint16, const uint16);
#import <AppKit/NSWindow.h>
#import "EmulatorView.h"
extern NSWindow *the_win;
extern EmulatorView *output;
// These record changes we made in setting full screen mode
extern CGDirectDisplayID theDisplay;
extern CFDictionaryRef originalMode, newMode;
// Macro for checking if full screen mode has started
#define FULLSCREEN ( theDisplay || originalMode || newMode )

View File

@ -0,0 +1,746 @@
/*
* $Id$
*
* video_macosx.mm - Interface between Basilisk II and Cocoa windowing.
* Based on video_amiga.cpp and video_x.cpp
*
* Basilisk II (C) 1997-2002 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "sysdeps.h"
#ifdef HAVE_PTHREADS
# include <pthread.h>
#endif
#include <adb.h>
#include <cpu_emulation.h>
#include <main.h>
#include "macos_util_macosx.h"
#include <prefs.h>
#include <user_strings.h>
#include "video_macosx.h"
#define DEBUG 0
#include "debug.h"
// Global variables
uint8 display_type = DISPLAY_WINDOW, // These are used by PrefsEditor
frame_skip;
uint16 init_width = MIN_WIDTH, // as well as this code
init_height = MIN_HEIGHT,
init_depth = 32,
screen_height = MIN_HEIGHT; // Used by processMouseMove
EmulatorView *output = nil; // Set by [EmulatorView init]
NSWindow *the_win = nil; // Set by [Emulator awakeFromNib]
static void *the_buffer = NULL;
#import <Foundation/NSString.h> // Needed for NSLog(@"")
#ifdef CGIMAGEREF
static CGImageRef imageRef = nil;
#endif
#ifdef NSBITMAP
#import <AppKit/NSBitmapImageRep.h>
static NSBitmapImageRep *bitmap = nil;
#endif
// These record changes we made in setting full screen mode
CGDirectDisplayID theDisplay = NULL;
CFDictionaryRef originalMode = NULL,
newMode = NULL;
// Prototypes
static void add_mode (const uint16 width, const uint16 height,
const uint32 resolution_id,
const uint32 bytes_per_row,
const video_depth depth);
static void add_standard_modes (const video_depth depth);
static bool video_open (const video_mode &mode);
static void video_close (void);
/*
* Utility functions
*/
uint8 bits_from_depth(const video_depth depth)
{
int bits = 1 << depth;
// if (bits == 16)
// bits = 15;
// else if (bits == 32)
// bits = 24;
return bits;
}
char *
colours_from_depth(const video_depth depth)
{
switch ( depth )
{
case VDEPTH_1BIT : return "Monochrome";
case VDEPTH_2BIT : return "4 colours";
case VDEPTH_4BIT : return "16 colours";
case VDEPTH_8BIT : return "256 colours";
case VDEPTH_16BIT: return "Thousands of colours";
case VDEPTH_32BIT: return "Millions of colours";
}
return "illegal colour depth";
}
char *
colours_from_depth(const uint16 depth)
{
return colours_from_depth(DepthModeForPixelDepth(depth) );
}
bool
parse_screen_prefs(const char *mode_str)
{
if (sscanf(mode_str, "win/%hd/%hd/%hd",
&init_width, &init_height, &init_depth) == 3)
display_type = DISPLAY_WINDOW;
else if (sscanf(mode_str, "win/%hd/%hd", &init_width, &init_height) == 2)
display_type = DISPLAY_WINDOW;
else if (strcmp(mode_str, "full") == 0)
display_type = DISPLAY_SCREEN;
else if (sscanf(mode_str, "full/%hd/%hd/%hd",
&init_width, &init_height, &init_depth) == 3)
display_type = DISPLAY_SCREEN;
else if (sscanf(mode_str, "full/%hd/%hd", &init_width, &init_height) == 2)
display_type = DISPLAY_SCREEN;
else if (sscanf(mode_str, "opengl/%hd/%hd/%hd",
&init_width, &init_height, &init_depth) == 3)
display_type = DISPLAY_OPENGL;
else if (sscanf(mode_str, "opengl/%hd/%hd", &init_width, &init_height) == 2)
display_type = DISPLAY_OPENGL;
else return false;
return true;
}
// Add mode to list of supported modes
static void
add_mode(const uint16 width, const uint16 height,
const uint32 resolution_id, const uint32 bytes_per_row,
const video_depth depth)
{
video_mode mode;
mode.x = width;
mode.y = height;
mode.resolution_id = resolution_id;
mode.bytes_per_row = bytes_per_row;
mode.depth = depth;
D(bug("Added video mode: w=%ld h=%ld d=%ld(%d bits)\n",
width, height, depth, bits_from_depth(depth) ));
VideoModes.push_back(mode);
}
// Add standard list of windowed modes for given color depth
static void add_standard_modes(const video_depth depth)
{
D(bug("add_standard_modes: depth=%ld(%d bits)\n",
depth, bits_from_depth(depth) ));
add_mode(512, 384, 0x80, TrivialBytesPerRow(512, depth), depth);
add_mode(640, 480, 0x81, TrivialBytesPerRow(640, depth), depth);
add_mode(800, 600, 0x82, TrivialBytesPerRow(800, depth), depth);
add_mode(832, 624, 0x83, TrivialBytesPerRow(832, depth), depth);
add_mode(1024, 768, 0x84, TrivialBytesPerRow(1024, depth), depth);
add_mode(1152, 768, 0x85, TrivialBytesPerRow(1152, depth), depth);
add_mode(1152, 870, 0x86, TrivialBytesPerRow(1152, depth), depth);
add_mode(1280, 1024, 0x87, TrivialBytesPerRow(1280, depth), depth);
add_mode(1600, 1200, 0x88, TrivialBytesPerRow(1600, depth), depth);
}
// Helper function to get a 32bit int from a dictionary
static int32 getCFint32 (CFDictionaryRef dict, CFStringRef key)
{
int32 val = 0;
CFNumberRef ref = CFDictionaryGetValue(dict, key);
if ( ref && CFNumberGetValue(ref, kCFNumberSInt32Type, &val) )
if ( ! val )
NSLog(@"getCFint32() - Logic error - Got a value of 0");
return val;
}
static bool add_CGDirectDisplay_modes()
{
#define kMaxDisplays 8
CGDirectDisplayID displays[kMaxDisplays];
CGDisplayErr err;
CGDisplayCount n;
int32 oldRes = 0,
res_id = 0x80;
err = CGGetActiveDisplayList(kMaxDisplays, displays, &n);
if ( err != CGDisplayNoErr )
return false;
for ( CGDisplayCount dc = 0; dc < n; ++dc )
{
CGDirectDisplayID d = displays[dc];
CFArrayRef m = CGDisplayAvailableModes(d);
if ( m == NULL ) // Store the current display mode
add_mode(CGDisplayPixelsWide(d),
CGDisplayPixelsHigh(d),
res_id++, CGDisplayBytesPerRow(d),
DepthModeForPixelDepth(CGDisplayBitsPerPixel(d)));
else
{
CFIndex nModes = CFArrayGetCount(m);
for ( CFIndex mc = 0; mc < nModes; ++mc )
{
CFDictionaryRef modeSpec = CFArrayGetValueAtIndex(m, mc);
int32 bpp = getCFint32(modeSpec, kCGDisplayBitsPerPixel);
int32 height = getCFint32(modeSpec, kCGDisplayHeight);
int32 mode = getCFint32(modeSpec, kCGDisplayMode);
int32 width = getCFint32(modeSpec, kCGDisplayWidth);
video_depth depth = DepthModeForPixelDepth(bpp);
if ( ! bpp || ! height || ! width )
{
NSLog(@"Could not get details of mode %d, display %d",
mc, dc);
return false;
}
#if DEBUG
else
NSLog(@"Display %ld, spec = %@", d, modeSpec);
#endif
add_mode(width, height, res_id,
TrivialBytesPerRow(width, depth), depth);
if ( ! oldRes )
oldRes = width * height;
else
if ( oldRes != width * height )
{
oldRes = width * height;
++res_id;
}
}
}
}
return true;
}
// Set Mac frame layout and base address (uses the_buffer/MacFrameBaseMac)
static void set_mac_frame_buffer(video_depth depth)
{
#if !REAL_ADDRESSING && !DIRECT_ADDRESSING
switch ( depth )
{
// case VDEPTH_15BIT:
case VDEPTH_16BIT: MacFrameLayout = FLAYOUT_HOST_555; break;
// case VDEPTH_24BIT:
case VDEPTH_32BIT: MacFrameLayout = FLAYOUT_HOST_888; break;
default : MacFrameLayout = FLAYOUT_DIRECT;
}
VideoMonitor.mac_frame_base = MacFrameBaseMac;
// Set variables used by UAE memory banking
MacFrameBaseHost = the_buffer;
MacFrameSize = VideoMonitor.mode.bytes_per_row * VideoMonitor.mode.y;
InitFrameBufferMapping();
#else
VideoMonitor.mac_frame_base = Host2MacAddr(the_buffer);
#endif
D(bug("VideoMonitor.mac_frame_base = %08x\n", VideoMonitor.mac_frame_base));
}
void resizeWinBy(const short deltaX, const short deltaY)
{
NSRect rect = [the_win frame];
D(bug("resizeWinBy(%d,%d) - ", deltaX, deltaY));
D(bug("old x=%g, y=%g", rect.size.width, rect.size.height));
rect.size.width += deltaX;
rect.size.height += deltaY;
D(bug(", new x=%g, y=%g\n", rect.size.width, rect.size.height));
[the_win setFrame: rect display: YES];
rect = [the_win frame];
}
void resizeWinTo(const uint16 newWidth, const uint16 newHeight)
{
int deltaX = newWidth - [output width],
deltaY = newHeight - [output height];
D(bug("resizeWinTo(%d,%d)\n", newWidth, newHeight));
if ( deltaX || deltaY )
resizeWinBy(deltaX, deltaY);
}
// Open window
static bool init_window(const video_mode &mode)
{
#ifdef CGIMAGEREF
CGColorSpaceRef colourSpace;
CGDataProviderRef provider;
#endif
short bitsPer, samplesPer; // How big is each Pixel?
int the_buffer_size;
D(bug("init_window: depth=%ld(%d bits)\n",
mode.depth, bits_from_depth(mode.depth) ));
// Set absolute mouse mode
ADBSetRelMouseMode(false);
// Open window
if (the_win == NULL)
{
ErrorAlert(STR_OPEN_WINDOW_ERR);
return false;
}
resizeWinTo(mode.x, mode.y);
// Create frame buffer ("height + 2" for safety)
the_buffer_size = mode.bytes_per_row * (mode.y + 2);
the_buffer = calloc(the_buffer_size, 1);
if (the_buffer == NULL)
{
NSLog(@"calloc(%d) failed", the_buffer_size);
ErrorAlert(STR_NO_MEM_ERR);
return false;
}
D(bug("the_buffer = %p\n", the_buffer));
if ( mode.depth == VDEPTH_1BIT )
bitsPer = 1;
else
bitsPer = 8;
if ( mode.depth == VDEPTH_32BIT )
samplesPer = 3;
else
samplesPer = 1;
#ifdef CGIMAGEREF
switch ( mode.depth )
{
//case VDEPTH_1BIT: colourSpace = CGColorSpaceCreateDeviceMono(); break
case VDEPTH_8BIT: colourSpace = CGColorSpaceCreateDeviceGray(); break;
case VDEPTH_32BIT: colourSpace = CGColorSpaceCreateDeviceRGB(); break;
default: colourSpace = NULL;
}
if ( ! colourSpace )
{
ErrorAlert("No valid colour space");
return false;
}
provider = CGDataProviderCreateWithData(NULL, the_buffer,
the_buffer_size, NULL);
if ( ! provider )
{
ErrorAlert("Could not create CGDataProvider from buffer data");
return false;
}
imageRef = CGImageCreate(mode.x,
mode.y,
bitsPer,
bits_from_depth(mode.depth),
mode.bytes_per_row,
colourSpace,
kCGImageAlphaNoneSkipFirst,
provider,
NULL, // colourMap
NO, // shouldInterpolate
kCGRenderingIntentDefault);
if ( ! imageRef )
{
ErrorAlert("Could not create CGImage from CGDataProvider");
return false;
}
CGDataProviderRelease(provider);
CGColorSpaceRelease(colourSpace);
[output readyToDraw: imageRef
imageWidth: mode.x
imageHeight: mode.y];
#else
unsigned char *offsetBuffer = the_buffer;
offsetBuffer += 1; // OS X NSBitmaps are RGBA, but Basilisk generates ARGB
#endif
#ifdef NSBITMAP
bitmap = [NSBitmapImageRep alloc];
bitmap = [bitmap initWithBitmapDataPlanes: (unsigned char **) &offsetBuffer
pixelsWide: mode.x
pixelsHigh: mode.y
bitsPerSample: bitsPer
samplesPerPixel: samplesPer
hasAlpha: NO
isPlanar: NO
colorSpaceName: NSCalibratedRGBColorSpace
bytesPerRow: mode.bytes_per_row
bitsPerPixel: bits_from_depth(mode.depth)];
if ( bitmap == nil )
{
ErrorAlert("Could not allocate an NSBitmapImageRep");
return false;
}
[output readyToDraw: bitmap
imageWidth: mode.x
imageHeight: mode.y];
#endif
#ifdef CGDRAWBITMAP
[output readyToDraw: offsetBuffer
width: mode.x
height: mode.y
bps: bitsPer
spp: samplesPer
bpp: bits_from_depth(mode.depth)
bpr: mode.bytes_per_row
isPlanar: NO
hasAlpha: NO];
#endif
// Set VideoMonitor
VideoMonitor.mode = mode;
set_mac_frame_buffer(mode.depth);
return true;
}
#import <AppKit/NSEvent.h>
// How do I include this file?
// #import <Carbon/HIToolbox/Menus.h>
extern "C" void HideMenuBar(),
ShowMenuBar();
static bool init_screen(const video_mode &mode)
{
// Set absolute mouse mode
ADBSetRelMouseMode(false);
theDisplay = kCGDirectMainDisplay; // For now
originalMode = CGDisplayCurrentMode(theDisplay);
newMode = CGDisplayBestModeForParameters(theDisplay,
bits_from_depth(mode.depth),
mode.x, mode.y, NULL);
if ( NULL == newMode )
{
ErrorAlert("Could not find a matching screen mode");
return false;
}
[the_win miniaturize: nil];
// [the_win setLevel: CGShieldingWindowLevel()];
the_win = nil;
HideMenuBar();
CGDisplayCapture(theDisplay);
if ( CGDisplaySwitchToMode(theDisplay, newMode) != CGDisplayNoErr )
{
ErrorAlert("Could not switch to matching screen mode");
return false;
}
CGDisplayHideCursor(theDisplay);
the_buffer = CGDisplayBaseAddress(theDisplay);
if ( the_buffer == NULL )
{
ErrorAlert("Could not get base address of screen");
return false;
}
screen_height = mode.y; // For mouse co-ordinate flipping
// Send emulated mouse to current location
NSPoint mouse = [NSEvent mouseLocation];
ADBMouseMoved((int)mouse.x, screen_height - (int)mouse.y);
// Set VideoMonitor
VideoMonitor.mode = mode;
set_mac_frame_buffer(mode.depth);
return true;
}
static bool init_opengl(const video_mode &mode)
{
ErrorAlert("Sorry. OpenGL mode is not implemented yet");
return false;
}
/*
* Initialization
*/
bool VideoInit(bool classic)
{
// Read frame skip prefs
frame_skip = PrefsFindInt32("frameskip");
if (frame_skip == 0)
frame_skip = 1;
// Get screen mode from preferences
const char *mode_str;
if (classic)
mode_str = "win/512/342";
else
mode_str = PrefsFindString("screen");
// Determine display_type and init_width, height & depth
parse_screen_prefs(mode_str);
// Construct list of supported modes
if (classic)
add_mode(512, 342, 0x80, 64, VDEPTH_1BIT);
else
switch ( display_type )
{
case DISPLAY_SCREEN:
if ( ! add_CGDirectDisplay_modes() )
{
ErrorAlert("Unable to get list of displays for full screen mode");
return false;
}
break;
case DISPLAY_OPENGL:
// Same as window depths and sizes?
case DISPLAY_WINDOW:
//add_standard_modes(VDEPTH_1BIT);
//add_standard_modes(VDEPTH_8BIT);
//add_standard_modes(VDEPTH_16BIT);
add_standard_modes(VDEPTH_32BIT);
break;
}
video_init_depth_list();
#if DEBUG
bug("Available video modes:\n");
vector<video_mode>::const_iterator i, end = VideoModes.end();
for (i = VideoModes.begin(); i != end; ++i)
bug(" %dx%d (ID %02x), %s\n", i->x, i->y, i->resolution_id,
colours_from_depth(i->depth));
#endif
D(bug("VideoInit: width=%hd height=%hd depth=%ld\n",
init_width, init_height, init_depth));
// Find requested default mode and open display
if (VideoModes.size() > 0)
{
// Find mode with specified dimensions
std::vector<video_mode>::const_iterator i, end = VideoModes.end();
for (i = VideoModes.begin(); i != end; ++i)
{
D(bug("VideoInit: w=%ld h=%ld d=%ld\n",
i->x, i->y, bits_from_depth(i->depth)));
if (i->x == init_width && i->y == init_height
&& bits_from_depth(i->depth) == init_depth)
return video_open(*i);
}
}
char str[150];
sprintf(str, "Cannot open selected video mode\r(%hd x %hd, %s).\r%s",
init_width, init_height,
colours_from_depth(init_depth), "Using lowest resolution");
WarningAlert(str);
return video_open(VideoModes[0]);
}
// Open display for specified mode
static bool video_open(const video_mode &mode)
{
D(bug("video_open: width=%ld height=%ld depth=%ld bytes_per_row=%ld\n",
mode.x, mode.y, bits_from_depth(mode.depth), mode.bytes_per_row));
// Open display
switch ( display_type ) {
case DISPLAY_WINDOW:
if ( ! init_window(mode) )
return false;
break;
case DISPLAY_SCREEN:
if ( ! init_screen(mode) )
return false;
break;
case DISPLAY_OPENGL:
if ( ! init_opengl(mode) )
return false;
break;
}
return true;
}
static void video_close()
{
D(bug("video_close()\n"));
switch ( display_type ) {
case DISPLAY_WINDOW:
// Stop redraw thread
[output disableDrawing];
// Free frame buffer stuff
#ifdef CGIMAGEREF
CGImageRelease(imageRef);
#endif
#ifdef NSBITMAP
[bitmap release];
#endif
free(the_buffer);
break;
case DISPLAY_SCREEN:
if ( theDisplay && originalMode )
{
//CGDisplayShowCursor(theDisplay);
CGDisplaySwitchToMode(theDisplay, originalMode);
CGDisplayRelease(theDisplay);
ShowMenuBar();
}
break;
case DISPLAY_OPENGL:
break;
}
}
/*
* Deinitialization
*/
void VideoExit(void)
{
video_close();
}
/*
* Set palette
*/
void video_set_palette(uint8 *pal, int num)
{
if ( FULLSCREEN && CGDisplayCanSetPalette(theDisplay)
&& ! IsDirectMode(VideoMonitor.mode) )
{
CGDirectPaletteRef CGpal;
CGDisplayErr err;
CGpal = CGPaletteCreateWithByteSamples((CGDeviceByteColor *)pal, num);
err = CGDisplaySetPalette(theDisplay, CGpal);
if ( err != noErr )
NSLog(@"Failed to set palette, error = %d", err);
CGPaletteRelease(CGpal);
}
}
/*
* Switch video mode
*/
void video_switch_to_mode(const video_mode &mode)
{
// Close and reopen display
video_close();
if (!video_open(mode))
{
if ( display_type == DISPLAY_SCREEN )
ErrorAlert("Cannot switch screen to selected video mode");
else
ErrorAlert(STR_OPEN_WINDOW_ERR);
QuitEmulator();
}
}
/*
* Close down full-screen mode
* (if bringing up error alerts is unsafe while in full-screen mode)
*/
void VideoQuitFullScreen(void)
{
}
/*
* Mac VBL interrupt
*/
void VideoInterrupt(void)
{
}
// This function is called on non-threaded platforms from a timer interrupt
void VideoRefresh(void)
{
}