Laying out the Foundation

The very first step was to figure out how to handle the most core abstraction of the emulation; how to handle memory interfacing. The Mac has a very strict memory map layout, with 68000 vectors residing in the beginning of address space, and all Toolbox low memory globals following them mixed with trap dispatcher routine addresses.

In a pure 32-bit environment, a cheap option might be just to allocate a contiguous area of memory to use as the emulated RAM, and offset the accesses so that emulated address 0x0 (zero) would be actually first byte of this memory block, and access any memory addresses from native code by just offsetting the native pointers. However, the recent transition to 64-bit causes new kind of headache; emulated pointers would be 32-bit while native pointers would require a double the space of 64 bits, not only requiring the offset, but also conversion from different data storage size.

To solve this, a “virtual” memory mapping scheme was devised, in which the emulated RAM would be divided into a number of “blocks”, each of which would have its own handler routine, which would handle the memory access. An additional benefit of this is, that for example VIA space can be mapped to a different handler, which would immediately trigger changes to emulated VIA registers without need to poll them from the generic system RAM; additionally, emulated “fake” ROM space could be implemented to have read-only access.

With this vision, we got a very simple Cocoa-based test app running, which did not yet emulate a real Mac address space, but rather a fixed 32KB RAM and 38KB VRAM for 640×480 monochrome buffer, with a static predefined test image (actually converted to C header with GraphicConverter!) shown in the video below:

A simple 640×480 monochrome framebuffer with static pre-defined raw image being scrolled