mini vMac compilation notes
Published 2020-06-28
Updated 2025-06-26
This is a transcluded section.
Mini vMac's Philosophy
...so. uh. If you don't want to pay for Paul's health insurance, there is another option. You can compile the code yourself. And, well, there's a few issues with that. Let's get into the design philosophy of Mini vMac. Straight from the website's about page:
The Mini vMac emulator collection allows modern computers to run software made for early Macintosh computers, the computers that Apple sold from 1984 to 1996 based upon Motorola's 680x0 microprocessors. The first member of this collection emulates the Macintosh Plus.
Mini vMac began in 2001 as a spin off of the program vMac. It was originally intended to be of limited interest, a simpler version to serve as a programmers introduction to vMac. But vMac hasn’t been updated in many years, so Mini vMac may now be considered its continuation.
The “Mini” in the name now means that each emulator in the collection is as small and simple as possible. The meta program and data that generate the emulators (the Mini vMac build system) are rather bigger. Besides the Macintosh Plus, there are also emulations of the Macintosh 128K, 512K, 512Ke, SE, Classic, and SE FDHD. Work is in progress on Macintosh II emulation. There are also numerous other options.
vMac was the original project. It only targeted the Macintosh Plus. It has not been updated since 1999. I'd download it to check it out, but that's broken. Mini vMac is the actively updated fork. That's fine, that's good.
Let me just shine a light onto the phrase "emulator collection". Like PCE, it's not one binary that emulates every system, it's one binary per system. However, PCE only ever published binaries for separate systems. Mini vMac requires a new "emulator in the collection" for every type of Macintosh.
The rationale behind this was to make every binary as small and simple as possible. And yes, the standard Macintosh Plus emulator for Windows is only 137 kilobytes. The 2010 build of Basilisk II is a whole two megabytes, not counting required libraries or the config program, which brings the total filesize up to about 19 megabytes. It's very impressive that Mini vMac is as small as it is, but I'm not convinced this was the right call.
Setting up the project
Let's actually work through the compilation steps. This program was written in the C programming language, so for comparison, here's the normal build steps for most C software.
git clone https://.../ program
cd program
./configure
make
You might get variations on the theme, using CMake or SCons or the like, but generally most projects are incredibly easy to compile on a Linux machine. (Windows is awful dev environment for C programs. Thankfully, WSL exists now.)
Thankfully, the process is documented on the website. So let's follow this, on a Windows machine. I want to compile with GCC using MinGW.
First off, there is no Git repo. No Subversion, Mercurial, or Fossil either. There is, however, a gzipped tarball. This is unfortunate, but servicable.
Download that and extract it. There's three directories: "extras", "setup", and "src". I go to Setup. The documentation wants me to modify "CONFIGUR.i" to set my compiler, so I set it to MinGW. What's interesting is the number of compilers this supports, including some really esoteric ones like "Pelles C Compiler", "Bloodshed Dev-C++", and Visual C++ 6.0. (k i'm roasting myself here)
The "Gryphel Build System" is a big C program, that you compile with a simple gcc tool.c -o tool.exe
. Those .i
files? C source code. No headers, they're just included as-is. They appear to verify and set various configuration flags in the final output. (For example, SPBLDOPT.i
handles configuration for each Macintosh model.) It's a bit clunky, but it works.
So, you do all that, you run tool.exe
, and it appears to produce a Bash script regardless of your target platform.
I will, however, note that the build script has code to output as either an Macintosh Programmer's Workshop (1980's era Macintosh IDE) script, a bash script, a VBScript, an AppleScript, or an "XP script", whatever that is. It's undocumented, but you can specify a specific output file by defining #gbo_script
to one of gbk_script_mpw
, gbk_script_applescript
, gbk_script_bash
, gbk_script_xp
, or gbk_script_vbscript
in CONFIGUR.i
. There's some obviously faulty logic to set this automatically based on your selected compiler somewhere.
What's really strange is that you have to set your compiler in CONFIGUR.i
, but you set your target on the tool.exe
commandline. So, yes, I could attempt to compile a 64-bit Windows program in MPW.
That shell script contains various commands that essentially write out each and every configuration header needed for the source code, along with creating the output directories and the makefiles. There's no logic in here beyond "don't create directory if it already exists", just a bunch of printf statements.
I am confused as to why tool.exe
didn't just create the files directly. It's also worth noting that this duplicates the functionality of CMake, although that probably didn't exist when this project was started.
Also, it's this build tool where you set all of your options, like the model of Mac to emulate and the screen resolution and the default speed and all of that. The only documentation on how to use it is in the website.
Compiling
Let's run our new tool.exe
.
$ setup/tool.exe -t wx64 > ./make.sh
$ ./make.sh
bash: ./make.sh: cannot execute binary file: Exec format error
$ file make.sh
make.sh: Bourne-Again shell script, Little-endian UTF-16 Unicode text executable, with CRLF line terminators
The problem here is that I'm running Windows. The Windows terminal, and all internal Windows functions, use UTF-16 character encoding. (Microsoft tried to jump on the Unicode bandwagon but did it too early.) Because of issues with the build system, the file it produced was UTF-16 formatted. I guess Git Bash doesn't like that.
So, you know what I need to do? I need to open this in a text editor and set the encoding to UTF-8.
$ ./make.sh
./make.sh: line 1: $'\357\273\277#!': command not found
UTF-8 with no BOM.
$ ./make.sh
./make.sh: line 460: printf: command not found
./make.sh: line 583: printf: command not found
And remove those garbage characters, however the heck they got there.
$ ./make.sh
$
And now I get my Makefile, and two new folders, bld/
and cfg/
. The output goes in bld/
, the configuration files generated by tool.exe
are in cfg/
.
In my opinion, it would make more sense to skip all of this and have an editable configuration header that can choose what to compile. The source code is already mostly set up for this. Let's continue.
$ make
gcc "src/MINEM68K.c" -o "bld/MINEM68K.o" -c -Wall -Wmissing-prototypes -Wno-uninitialized -Wundef -Wstrict-prototypes -Icfg/ -Isrc/ -Os
Cannot create temporary file in C:\WINDOWS\: Permission denied
make: *** [Makefile:18: bld/MINEM68K.o] Error 3
Right, okay, let's switch back to Powershell.
PS > make
gcc "src/MINEM68K.c" -o "bld/MINEM68K.o" -c -Wall -Wmissing-prototypes -Wno-uninitialized -Wundef -Wstrict-prototypes -Icfg/ -Isrc/ -Os
gcc "src/OSGLUWIN.c" -o "bld/OSGLUWIN.o" -c -Wall -Wmissing-prototypes -Wno-uninitialized -Wundef -Wstrict-prototypes -Icfg/ -Isrc/ -Os
...
gcc "src/PROGMAIN.c" -o "bld/PROGMAIN.o" -c -Wall -Wmissing-prototypes -Wno-uninitialized -Wundef -Wstrict-prototypes -Icfg/ -Isrc/ -Os
make: *** No rule to make target 'cfg/main.r', needed by 'bld/'. Stop.
PS >
So let's talk about Windows resource files. They're Microsoft's attempt to kinda do the same thing as the Macintosh resource forks. Basically, it's extra data like program icons, dialog boxes, translation strings, etc. that's independent from the code, and can be modified and translated without touching the binary. It's nice. More people should use them. The only issue is that Windows resource files are a very Windows-specific thing. But I digress.
The thing is that this Makefile is malformed. You see, it's laid out like this:
bld/GLOBGLUE.o : src/GLOBGLUE.c cfg/CNFGGLOB.h
gcc "src/GLOBGLUE.c" -o "bld/GLOBGLUE.o" $(mk_COptions)
bld/M68KITAB.o : src/M68KITAB.c cfg/CNFGGLOB.h
gcc "src/M68KITAB.c" -o "bld/M68KITAB.o" $(mk_COptions)
bld/MINEM68K.o : src/MINEM68K.c cfg/CNFGGLOB.h
gcc "src/MINEM68K.c" -o "bld/MINEM68K.o" $(mk_COptions)
bld/VIAEMDEV.o : src/VIAEMDEV.c cfg/CNFGGLOB.h
gcc "src/VIAEMDEV.c" -o "bld/VIAEMDEV.o" $(mk_COptions)
...
bld/: cfg/main.r
windres.exe -i "cfg/main.r" --input-format=rc -o "bld/" -O coff --include-dir SRC
and that fails, because things after the colons are considered prerequisites, files that need to exist before the compiler command is ran. The issue here is that make
has no idea what a .r
file is, because it's supposed to be .rc
. So rename that .r
file to a .rc
, modify the Makefile, continue.
PS > make
gcc \
-o "minivmac.exe" \
bld/MINEM68K.o bld/OSGLUWIN.o bld/GLOBGLUE.o bld/M68KITAB.o bld/VIAEMDEV.o bld/IWMEMDEV.o bld/SCCEMDEV.o bld/RTCEMDEV.o bld/ROMEMDEV.o bld/SCSIEMDV.o bld/SONYEMDV.o bld/SCRNEMDV.o bld/MOUSEMDV.o bld/KBRDEMDV.o bld/SNDEMDEV.o bld/PROGMAIN.o "bld/" -mwindows -lwinmm -lole32 -luuid
C:/WinProg/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/7.3.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find bld/: Permission denied
collect2.exe: error: ld returned 1 exit status
make: *** [Makefile:68: minivmac.exe] Error 1
PS >
You can't compile a directory. Remove "bld/"
from that final gcc
fine in the Makefile. Continue.
It compiles this time. Except the program has no icon, because the resource file was never linked into the final binary. In fact, looking at the windres
line, I'm realizing it's trying to set the output filename to "bld/"
, which is probably where that came from.
In the resource file command, change "bld/"
to "bld/main.res"
. Both instances. Move that target above ObjFiles
. Add bld/main.res
to ObjFiles. Recompile. Now it has an icon.
Code Review
This section came off a bit too mean-spirited, in retrospect. tl;dr:
- Use of Pascal-like typedefs for standard C types
- Excessive use of
#ifdef
on a per-line basis - Very few comments
- Opaque variable/function names
- Non-standard use of
#include
for templating - Flat directory structure and 8.3 naming for source files
- Excessively long files and functions
Conclusion
I really really want to like Mini vMac. I've actually started my own fork, µvMac, that's supposed to clean up the codebase of Mini vMac, update it to modern coding standards, and give the project new life. I've been working on-and-off on it (mostly off; I'm realizing that I can't really program as a hobby if I'm already programming for 40 hours a week at work, and I've spread myself too thin with projects honestly), and already I feel like it's easier to build and hack on.
I wish the best for the Mini vMac and the other emulators, I really do. Seriously, I know that emulator development is hard, thankless work. Throw some change at Paul C. Pratt, he genuinely deserves it. I hope that this article inspires others to help out with these projects and make them even better.