What’s going on here?

I started playing around using Retro68 on a modern Linux-based machine to do development work for old Macintosh computers in the spirit of one of my previous posts. In doing so, I ran into many problems while getting started and coming up with my own workflow. I hope that others can find this guide helpful in getting up and running with their own classic Macintosh dev stories.

Who can use this guide? Anyone who wants to get up and running with Mac development being cross compiled from a modern Linux environment as quickly as possible. I’ve laid out the commands and explanations in the most straightforward way I could with the simple goal of running a hello world application. I do not go very in depth as to what I am laying out here but link out to other resources for you to learn more.

I used a few other guides to build up to what I ultimately wound up using for my development workflow. You should read them if you get stuck or are interested in further reading:

I used Ubuntu running on an intel-based Mac Mini for my build environment. To run the complete toolchain that I’ll outline in this post and several other following posts, you’ll need a Linux-based environment as that is the only way I’m aware of to make full use of pce-macplus’s serial port. I’ve additionally tested running though this guide on an ARM64 Ubuntu 20 VM using UTM on an M1 Mac Mini. Off we go…

Setting up Retro68

There are complete instructions and in-depth available online already, these are abridged for Ubuntu between the toughdev and Retro68 docs:

First ensure prereqs are installed:

1
sudo apt-get install cmake libgmp-dev libmpfr-dev libmpc-dev libboost-all-dev bison flex texinfo ruby g++ hfsutils

Then clone the Retro68 git repo:

1
2
3
4
5
git clone https://github.com/autc04/Retro68.git
cd Retro68
git pull
git submodule update --init
cd ..

Get the MPW includes downloaded and in place:

1
2
wget https://henlin.net/images/Interfaces\&Libraries.zip
unzip "Interfaces&Libraries.zip" -d Retro68/InterfacesAndLibraries

Now build Retro68:

1
2
3
mkdir Retro68-build
cd Retro68-build
../Retro68/build-toolchain.bash

If everything went well, you should now have a functional Retro68 environment! Back to that in a bit…

Optional: Setting up serial port emulation

One of the motivations here is that we have full serial communication to enable the development of software utilizing the serial port on the Macintosh for bidirectional communication. Check out one of my other posts here for more information. We emulate that locally with tty0tty. This step is marked as optional, because if you don’t care about working with CoprocessorJS you may not need this step.

1
2
3
4
5
6
7
8
git clone https://github.com/freemed/tty0tty
cd tty0tty/module
make
sudo cp tty0tty.ko /lib/modules/$(uname -r)/kernel/drivers/misc/
sudo depmod
sudo modprobe tty0tty
sudo chmod 666 /dev/tnt*
cd ~
1
2
3
4
5
6
7
8
9
10
note! I got a build error on my most recent test with these instructions.
You may have to modify module/tty0tty.c. Change line :258 from:

static unsigned int tty0tty_write_room(struct tty_struct *tty)

to:

static int tty0tty_write_room(struct tty_struct *tty)

then re-run make to resolve the error.

You should now have functional fake serial port pairs at /dev/tnt* (ex, /dev/tnt0 is linked to /dev/tnt1, etc)

note: you may have to do this after every reboot. Some of the tty0tty docs describe how to persist across reboots but I haven’t been able to get that working and also haven’t spent much time on it.

Setting up pce-macplus

pce-macplus is the emulator environment we’re going to use. Again, complete instructions are available here.

We choose pce-macplus because it emulates full serial communication and works well on Linux. To run pce-macplus on latest Ubuntu, we need to compile it ourselves. We’ll do that with the following:

First we need some prereqs:

1
sudo apt-get install libx11-dev libx11-doc libxau-dev libxcb1-dev libxdmcp-dev x11proto-core-dev x11proto-input-dev x11proto-kb-dev xorg-sgml-doctools xtrans-dev libsdl1.2-dev libsdl1.2debian

Then we’ll download and install pce-macplus:

1
2
3
4
5
6
7
wget http://www.hampa.ch/pub/pce/pce-0.2.2.tar.gz
tar -xvf pce-0.2.2.tar.gz
cd pce-0.2.2
./configure -with-x --with-sdl --enable-tun --enable-char-ppp --enable-char-tcp --enable-sound-oss --enable-char-slip --enable-char-pty --enable-char-posix --enable-char-termios
make
sudo make install
cd ~

Getting a sample application in place

Download a sample application to start working with. There are some included in Retro68 that you can try out or you can continue on to try one of mine. I recommend https://github.com/CamHenlin/nuklear-quickdraw as a Macintosh project base and I will use it as the example here as I know it will function in this environment.

1
git clone https://github.com/CamHenlin/nuklear-quickdraw

Setting up VSCode

We’re about ready to start coding. VSCode is a great place to do development work on Retro68 projects. You want to add this to your includePath setting to get code completion on Mac-specific libraries. VSCode should prompt you to import the includePath the first time you open your project:

1
~/Retro68/InterfacesAndLibraries/**

Running our sample application

We have code in place. We have everything set up. Now we just need a few convenience scripts in place to run our code for us. From this ToughDev article we can get a set of scripts to help us out. I’ve conveniently cloned them and edited them to work with the directory structure outlined here. The other set of files that we need to retrieve is the pre-built configuration for pce-macplus:

1
2
3
4
wget https://henlin.net/images/retro68scripts.zip
unzip retro68scripts.zip
wget https://henlin.net/images/pcemacclassic.zip
unzip pcemacclassic.zip

Now that we have our hello world app in place, we should be able to run our project for the first time. Assuming you started with the nuklear-quickdraw project listed above, try:

1
./build_and_run.sh nuklear-quickdraw/

This should compile your code, launch the pce-macplus VM with its printer serial port pointed at ~/pce-mac-classic/ser_b.out and its modem port pointed at /dev/tnt1 (which will be bi-directional with /dev/tnt0)

Development workflow strategies

I am going to outline my own personal workflow here. Everyone’s preferences are a bit different here so take this and modify it to suit your own needs:

Writing code

For coding, I use VSCode for everything. I like to open the entire project directory (like nuklear-quickdraw for example.) VSCode offers good autocomplete support and is fast and usable.

Debugging code

Retro68 offers no debugging capabilities from what I can tell which poses a bit of a problem. If you google around, you’ll probably find people telling you to use CodeWarrior or ThinkC if you want a debugger. What we can do is log output (as identified by this article) over the serial port.

In my nuklear-quickdraw for example, I implemented the same writeSerialPort function as outlined in this ToughDev article). You can use it like this:

In your code:

1
writeSerialPort(boutRefNum, "my test output");

Where my test output will be appended to ~/pce-mac-classic/ser_b.out any time that code is called.

I recommend always having one terminal window open and tailing ~/pce-mac-classic/ser_b.out

note: if you leave any logging code in place when you take your program to a physical Mac, it will be dumping data out the printer serial port to whatever is hooked up to it!

Profiling code

See my other post here regarding profiling your Retro68 application. nuklear-quickdraw contains example profiling code.

Running code after changes

Any time you’re ready to run new code, just use the line that we used to test our hello world application earlier:

1
./build_and_run.sh nuklear-quickdraw/

I like to keep a terminal window open just for this use case.

Next steps

Go hog wild! Write the custom app of your dreams! You’re finally ready to do Macintosh development You could look into using the CoprocessorJS or Nuklear libraries too.

Did you enjoy my post?

I'm really excited about the work that I'm doing here. If you enjoyed my post and my work, please consider tipping me with a coffee. I appreciate you taking the time to read my post!

Comments

⬆︎top