Advanced Mac Substitute is an API-level reimplementation of 1980s-era Mac OS

www.v68k.org
zdw
yesterday
261points
67 comments

Comments

keepamovinyesterday
This is super cool. I love that look. Something about classic black & white macos has a timeless "alternative timeline" L'Air de Panache aesthetic that to me says credibility and stability. Maybe it's the memory of the rows of Macintosh SE or Plus, those solid little upright beige bricks, in the computer room at my elementary school.

I made a MacOS system 7 web desktop UI with real web browsing: https://win9-5.com/macos/

A re-imagining.

jjuranyesterday
Oh wow. Once I saw the smiling machine and empty progress bar, I went straight to NoScript and enabled your domain without a moment's hesitation — highly unusual for me. It's charming! I laughed out loud when I saw your screen-saver.

It's familiar and alien at the same time, like I'm seeing an alternate universe.

I made my own web-based Mac simulator some time ago: https://www.metamage.com/apps/maxim/

It was a way to become more familiar with CSS and JS (and indulge my classic Mac OS nostalgia), but my biggest takeaway was that the web wasn't a foundation I wanted to build complex structures on, and indirectly helped spur me to create Advanced Mac Substitute.

hyperhello9 hours ago
Sharing our Mac themes simulators? Here is my entrant: https://hcsimulator.com/ Full compatibility with HyperCard stacks, including their resource forks if they are in StuffIt archives.
rcarmoyesterday
This is pretty neat. I have been spending the past few months adding an ARM64 JIT to Basilisk II (https://github.com/rcarmo/macemu) and totally appreciate what's involved (I'm currently stuck patching a Quadra ROM to bypass NuBus hardware detection...)

Will definitely give it a try, since I would _love_ to have a Classic Mac environment with some modern creature comforts (like file sharing) in tiny machines.

londons_exploreyesterday
I am amazed that 1980's software works on binary API compatibility rather than relying on API quirks like timing, memory alignment quirks, memory layout from specific allocator behaviour, etc.

It only takes one unintentional reliance on an implementation detail to make an application not run on another OS implementation...

Lercyesterday
The Mac classic was about as pure as you could get from an architectural point of view.

A 1 bit framebuffer and a CPU gets you most of what the machine can do.

Most of the quirk abuse of 8-bit machines came from features that were provided with limitations. Sprites, but only 8 of them, colours but only 2 in any 8x8 cell. Multicolour but only in one of two palettes and you'll hate both.

Almost all of the hacks were to get around the limitations of the features.

I don't know if the decision apple made was specifically with future machines in mind. It certainly would have been a headache to make new machines 5 generations down the track if the first one had player missile graphics.

philistine10 hours ago
They absolutely knew that they were making a platform that needed as much hardware independence as possible. The 512k was already in development before they even finished the original, and they had the experience of the Apple II, which for all of Wozniak’s legendary work, was a dead-end because it relied too heavily on hardware hacks.
jjuran7 hours ago
A Mac 512K of sorts was already built before the Macintosh introduction at the 1984 shareholders meeting — the demo wouldn't run in 128K of RAM.
wmfyesterday
There were plenty of apps that relied on implementation quirks.
eschatonyesterday
They mostly relied on OS/Toolbox implementation quirks though, not hardware implementation quirks, because applications that relied on the latter wouldn’t run on the Macintosh XL and that mattered to certain market segments. (Like some people using spreadsheets, who were willing to trade CPU speed for screen size.) Similarly anything that tried to use floppy copy protection tricks wouldn’t work due to the different system design, so that wasn’t common among applications.

So even things that wrote directly to the framebuffer would ask the OS for the address and bounds rather than hardcode them, copy protection would be implemented using license keys (crypto/hashes, not dongles) rather than weird track layouts on floppies, etc. It led to good enough forward compatibility that the substantial architectural changes in the Macintosh II were possible, and things just improved from there.

icodestuffyesterday
Eh, there were plenty of games that were coded for a particular clock speed, and then once the SE came out, had an update that included a software version of a turbo button, let you select which of two speeds to run at. They run FAST on an SE/30 or Mac II and unusably fast on anything newer.
eschatonyesterday
I didn’t encounter too many of those back in the day, I think because there was the VBL task mechanism for synchronizing with screen refresh that made it easy to avoid using instruction loops for timing.

Much more common in my experience was the assumption that the framebuffer was 1-bit, but such games would still run on my IIci if I switched to black & white—they’d just use the upper left 3/4 of the screen since they still paid proper attention to the bytes-per-row in its GrafPort.

Could be that by the time I was using a Mac II though that all the games that didn’t meet that minimum bar had already been weeded out.

flomoyesterday
Yeah, there were a bunch of floppy games which only ran on an original Mac or maybe a Plus. No go with even my Mac SE.
hyperrail18 hours ago
Indeed, even ones from companies as big as Microsoft!

There is a story in Writing Solid Code by Steve Maguire [1] where Apple asked Microsoft to fix hacks in its Mac apps that didn't conform to the developer docs in Inside Macintosh because such workarounds were required when the apps were first developed alongside the original Macintoshes. However, Microsoft's workarounds would be broken by a major System Software update under development at Apple, which naturally wanted to avoid having to permanently add back the implementation bugs and quirks that the workarounds either relied on or were meant to avoid.

As Maguire told it, removing one such workaround in Microsoft Excel was hotly debated by the Excel team because it was in a hot-path 68k assembly function and rewriting the code to remove it would add 12 CPU cycles to the function runtime. The debate was eventually resolved by one developer who ran Excel's "3-hour torture test" and counted how many times the function in question was called. The total: about 76,000 times, so 12 more cycles each time would be about 910,000 cycles total... which on the Macintosh 128k's ~7 MHz 68000 CPU would be about 0.15 seconds added to a 3-hour test run. With the slowdown from removing the workaround thus proven to be utterly trivial, it was indeed removed.

[1] https://openlibrary.org/books/OL1407270M/Writing_solid_code - page 136, heading "Don't Overestimate the Cost"

CharlesWyesterday
Out of curiosity, what app are you thinking of? Of all of types of software used with classic Mac OS (INITs, CDEVs, FKEYs, Desk Accessories, Drivers, etc.), apps would be the least likely to rely on implemention quirks.
wk_endyesterday
Macintosh Common Lisp - at least the versions floating around Mac Garden and such - seems to refuse to run on anything besides accurate emulators and real hardware.
imoverclockedyesterday
I can't imagine how fast this is compared to the original hardware that ran it. I remember using a Mac 512k with a single floppy drive (no hard drive support) and doing the insert-floppy-dance. Computers were far more mechanical then.

It would be fun to have a "slow it down" feature that also has the various floppy read/write noises paired with it. Bonus points for different generations of hardware and having the OG HD noises to pair with those too!

drzaiusx11yesterday
There was a show HN retro HW project somewhat recently that included sound emulation on board. Maybe that author is reading this, but their sound emulation was probably my favorite part (not to disregard the actual hard parts! I just found it charming)
jdwithityesterday
"Fond" memories of playing King's Quest IV as a little kid on my parents' Apple IIe. You had to swap in a new 5.25" floppy almost every time you walked to another screen. I was fascinated by the game but my god was it tedious to constantly flip and swap the disks around. Google says it came on 8 double sided disks, I could have sworn it was a couple dozen.
technothrasheryesterday
The game I played for hours on the Apple ][+ was "FantasyLand 2041". It came on six double sided disks, and I was bummed to find out after quite a lot of game time that disk six was corrupted. I then found out many years later that it wasn't corrupted, the game wasn't ever finished. I then further discovered that John Bell, who produced that and other popular games (Sand of Mars, Beneath the Pyramids, House of Usher), is utterly batty and has written a few "the government is hiding UFOs from us" books.
steve-atx-7600yesterday
Just tried out this apple II emulator that’s close to what you’re describing, but for Apple II https://www.virtualii.com/ . Has floppy sounds as well as speed settings.
homarpyesterday
how does it compare to executor? https://en.wikipedia.org/wiki/Executor_(software)
epennyesterday
Very cool! This reminds me of ARDI Executor [1] - a piece of (discontinued) commercial software first released in 1990 that took the same API-level reimplementation approach used here. And it did so jaw-droppingly fast considering that it was running on 90s PC hardware. As a little kid using it to play a few Mac games on my Windows PC, it was genuinely inspiring to me to see that this was possible at a time when I was first learning how to code. :) Great to see something with a more modern implementation doing this as well!

It was discontinued in 2005, but the developers subsequently open sourced it and put the code on GitHub a couple years later. [2]

[1] https://en.wikipedia.org/wiki/Executor_(software)

[2] https://github.com/ctm/executor

Bonus: One of the engineers from ARDI, the startup that created Executor, was very briefly featured in Bob Cringely's 1996 documentary Triumph of the Nerds talking about the lifestyle of working at prototypical mid-90s Silicon Valley startup.

jjuran6 hours ago
I knew of Executor, but never saw it in action. Winning back performance lost to emulation was critical when competing with contemporary real hardware, and kudos to ctm and ARDI for their clever solution.

Decades later, though, emulation performance is mostly a non-issue (and even improves automatically with faster hosts). What matters now is portability (which requires ongoing maintenance) and renovation of programs designed around having the CPU to themselves (via dynamically applied patches).

hyperhelloyesterday
I'd like to see something like Carbon for old apps so that they boot in modern window frames (without the missing Tahoe corners) and can save to files.
jjuranyesterday
Advanced Mac Substitute stores documents and preference files in sandboxed host directories.

For example, check out the MacPaint demo:

https://www.v68k.org/advanced-mac-substitute/demo/MacPaint-A...

If you were to double-click the Hello document in macOS' Finder, it would launch and open in MacPaint.app.

eschatonyesterday
This is exactly the sort of project that can serve as the basis for such a system.
msephtonyesterday
So has this beaten MACE to the finish line? Or are the goals different? https://mace.home.blog
shermantanktopyesterday
But will it run Dark Castle??

Many hours were wasted on that game.

rvnxyesterday
Still wondering why the main character looks like Sammy from Scooby Doo

and yes:

https://github.com/jjuran/metamage_1/commit/30cb0e260d5ff478...

Chazprimeyesterday
Hell, I’d go straight for Beyond Dark Castle… it really took the series to a whole different level.
azinman2yesterday
This is quite the feat. I’d love to know more about the process to make this, the motivation, how much time was spent, etc.
whartungyesterday
I'm guessing they reimplemented the toolbox at the TRAP level (most MacOS calls at the time were accessed through the 68K TRAP instruction).

So, rather than emulating hardware to run native ROMs, they "simply" reimplemented the ROMs.

A friend of mine did this at another level. He basically rewrote the bulk of the toolbox as a C library so that the company, who had a Mac application, could port it to run on a PC, while sharing the source code.

This was before Windows, and it worked! Launched it from DOS, takes over the entire screen. He didn't copy the Mac look and feel. Instead he used OpenLook for his gadgets and what not (since it was, you know, "open").

But he rewrote the bulk of it: QuickDraw, Event Manager, Memory Manager, Window Manager, etc. Just ate it like an elephant. I don't think his regions were as clever as the Mac. Pretty sure he just stuck with rectangles.

jjuranyesterday
Correction: 68K Mac OS calls were A-line traps — in other words, they had opcodes of the form `$Axxx`. To the processor, they're unimplemented instructions that each take an exception through the same vector. The exception handler is the Mac OS trap dispatcher.

`TRAP` is a different instruction, with opcodes `$4E4x`. Each one gets its own exception vector.

It's not just trap calls, though — sometimes applications write directly to the sound buffer or use hardware page flipping.

bitwizeyesterday
As I recall MacOS system calls were done through invalid instructions which would cause the CPU to "trap" (raise an interrupt). Giving rise to the question Mac extension writers asked of each other: "How many traps did you patch?"
tmoertel8 hours ago
The question serious patch trappers ask is whether you patched the traps used to patch traps to make sure that, when you patched traps, no other INIT could patch those traps after you to get in line before you when the traps were handled.
jjuran18 hours ago
You want to talk trap patches? Your Mac's INITs have minimal trap patches, touch the Toolbox in boring places like SysBeep() and GetNextEvent(). The Developator's Mac has big, tricky INITs with trap patches that hook into half of the Device Manager.[1] The Developator is in touch with the metal, starts like a warm boot off the ROM reset vector, stops on an NMI.

[1] See https://www.macrelics.com/legacynth/

jjuranyesterday
My earliest recollection of what motivated me is a desire to resurrect The Fool's Errand.

The irony is not lost on me. :-)

azinman2yesterday
Hey, I’ve been thinking about building a genesis emulator to play Revenge of Shinobi. Never thought about trying to replace the genesis rom.. let’s get the game working first :)
jjuran20 hours ago
A Genesis has to start somewhere. ;-)