Advanced Mac Substitute


Advanced Mac Substitute is an API-level reimplementation of classic Mac OS. It runs in the xv68k emulation rig.

Current support includes

Example

xv68k --screen=$screen_file 8< $events -m [ ams-core --events-fd=8 ] -m ams-rsrc -m ams-ui $program

The screen is 21888 bytes of raw 512x342 bitmap data (with 0 coding for white and 1 for black). The file will be created if it doesn’t exist.

Mac OS support is split into several modules: ams-rsrc implements the Resource Manager, and ams-ui provides the Window Manager. Everything else (e.g. the Event Manager) is in ams-core.

Since InitWindows() calls GetPattern(), which calls GetResource(), ams-ui depends on ams-rsrc. Both depend on ams-core.

GetResource() attempts to communicate with a Freemount server on file descriptors 6 and 7, as would be the case if you ran tcpclient $host $port xv68k .... A resource like 'PAT ' id=16 (the desktop pattern) is mapped to the path "System/r/0010.PAT " and requested from the server. You can either run freemountd in MacRelix with an actual resource file called "System" at top level, and let MacRelix interpret the "r" path component as resource access, or create a "System/r" directory structure with the resources as actual files.

If CurApName is non-empty, it’s the name of the currently running application. GetResource() now checks for resources in the application file first, and if not found, then checks in "System".

If ams-rsrc is unable to reach a file server, or the request fails, then GetResource() sets ResErr to resNotFound (or possibly memFullErr) and returns NULL, and InitWindows() will use qd.gray instead of 'PAT ' id=16 from the System file.

GetNextEvent() and WaitNextEvent() receive user input events from outside via the SPIEL (Simple, Platform-Inclusive Event Lode) protocol. MacRelix’s eventtap view provides this.

Launching Mac applications

Launching a Mac application in xv68k is a complex process because it has a number of moving parts. First, we’ll use FORGE to open a window:

cd /gui/new/port

echo 512x342 > size

ln new/stack view

ln new/eventtap v/events/view
ln new/bitmap   v/screen/view

echo 512x342 > v/screen/v/size

touch window

That creates a window whose interior size matches the original Macintosh screen resolution. It contains an eventtap view Z-stacked onto a bitmap view. The eventtap view captures user input events for transport into the emulator (but doesn’t draw anything); the bitmap view displays graphics output.

We also need a way to get the CODE resources from the application file. We’ll use the graft utility to launch a Freemount server, with xv68k as its client, connected by a socket pair:

CTTY=--ctty=tty
SCREEN=--screen=v/screen/v/bits
EVENTS=--events-fd=8
STREAM=v/events/v/stream
APP=$tools/app
App=TestApp

daemonize --cwd $CTTY             -- \
    graft freemountd --root $dir  // \
    xv68k --screen=$SCREEN 8< $STREAM -m [ ams-core $EVENTS ] -mams-{rsrc,ui} $APP TestApp

Let’s tackle this in order: