Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / system

Developing Vintage 68K Macintosh Apps with CodeLite IDE, Retro68 and pce-macplus Emulator

4.50/5 (2 votes)
7 May 2023CPOL7 min read 2.4K  
Developing vintage 68K Macintosh apps with CodeLite IDE, Retro68 and pce-macplus emulator
The post details the setup of a comprehensive 68k Macintosh development environment on Ubuntu Linux, including Retro68, CodeLite, and pce/macplus, with optional VirtualBox image download.

In my previous post, I described how Retro68 can be used to compile 68K Macintosh apps from your modern Linux distribution and also explored how Retro68 together with CodeLite and pce/macplus emulator can form a very good 68k development environment. In this post, I will provide the details of how such a development environment can be created based on Ubuntu, a common Linux distribution. For those who do not have the time to set up everything from scratch, towards the end of the post, I will also provide links to download a VirtualBox image with Retro68, CodeLite, pce/macplus and other necessary components in a single Ubuntu installation.

Prerequisites

Before we start, you should already have Retro68, pce/macplus and optionally Basilisk II installed on your preferred Linux distribution, for example, by using sudo apt-get install basilisk2 and sudo apt-get install codelite. Although any version of CodeLite will work for our purposes, if you have the time, try to install CodeLite from the latest source code as some older versions of CodeLite might have autocompletion issues which will manifest when used with the Retro68 SDK.

Preparing the Build Environment

As our objective is to be able to compile and run Retro68 apps within CodeLite, preferably with some debugging support, the first task is to write bash scripts to automate various tasks. For our purposes, we only need the following scripts (refer to the download links at the end of the article for the complete source code):

  • build.sh: build the specified project
  • build_and_run.sh: build the specified project and runs in in the specified emulator. This script will call build.sh and once done, start the selected Mac OS emulator.
  • clean.sh: remove all build output for the selected project.

Building Retro68 apps as well as starting the pce/macplus emulator from command line is trivial. However, there is a challenge of copying the compiled executable to the selected emulator, to be started by the user once the emulator has finished booting. Fortunately, Retro68 produces build output in both BinHex (.BIN) or 800k disk image (.DSK). You can simply rename the .DSK output to .image and mount it as a 800k floppy drive with pce/macplus. Alternatively, you can use hformat, hmount and hcopy, part of the hfsutils package, to create a HFS disk image with the .BIN file as well as any other input files from your application, and mount it with pce/macplus. The HFS image will appear as a Hard Disk 20 disk drive and can be read on the Macintosh Plus and later with the stock ROM, or on a Macintosh 128K/512K with the Macintosh Plus ROM.

Our first CodeLite 68k project is now ready to be created. We will use CodeLite’s C++ template and add different project configuration for different types of Mac OS emulators:

codelite_project_config

For each project configuration, we will configure our bash scripts under Workspace > Open Active Project Settings. In General settings, configure the script to build and run the project with our selected emulator:

codelite_general

The parameters for our build_and_run.sh script indicates the project to be built and the emulator to run it on, which need to be specified correctly in program arguments. The working directory also needs to be set correctly. Remember to tick “This program is a GUI application” otherwise the emulator won’t start. Under Customize > Custom Build, specify the command to build and run the project:

codelite_custom_build

Under Code Completion, specify the path to the Macintosh Programmer’s Workshop C headers, in particular, the CIncludes and RIncludes folders, for autocomplete to work:

codelite_include

These folders will also need to be specified under Global Settings > Additional Include Paths:

codelite_include

Also add these folders to Settings > Code Completion > CTags > Search Paths:

codelite_search_path

As MPW uses .r files that are written in a language similar to C, for dialog resources, we should also add *.r in the list of C++ file extensions. You can do this in Settings > Colours and Fonts > Customize > C++:

codelite_r_types

Of course, you might also want to tweak autocompletion and other editor settings to suit your needs. Repeat the above steps for each of the project configuration and remember to change the command line parameters to indicate the Mac OS emulator to run the project on. Once done, choose Workspace > Parse Workspace and restart CodeLite. You will notice that method signatures can now be detected and autocomplete can work:

codelite_autocomplete

With this setup, common CodeLite tasks such as build, run and clean should now work properly. The following screenshot shows CodeLite running the MenuSample example on System 6.0.8 under pce/macplus:

codelite_retro68

The MenuSample app can be started from the emulated Test Apps disk:

codelite_menusample

To get pce/macplus to boot from the existing hard disk with System software and not from the HFS disk, we created with just the compiled code, it is important to set a value of around 3-5 seconds for the insert_delay parameter in pce configuration. Otherwise, the emulator will attempt to boot from this HFS disk and fail since our HFS disk is obviously not bootable.

Adding Debug Support

There is some support for debugging in pce/macplus, but its integrated debugger can only work at assembly language level and will not suit our purposes. And although Retro68 produces GDB debug symbols, making use of these symbols to debug our 68K apps via pce/macplus will not be trivial due to the emulation layer involved. The only simple way I can think of is to write debug messages to the Macintosh serial port, and configure redirection of serial output to a text file on disk. This can be done using the following configuration entry:

Bash
serial {
    port = 1
    drive = "stdio:file=serial.out"
}

The above configuration will redirect all serial output to a file named serial.out on disk. Writing to the serial port from pce can then be done with the following code:

Bash
#include <Serial.h>
#include <Devices.h>

OSErr writeSerialPort(short refNum, const char* str)
{
#define MODEM_PORT_OUT   "\p.AOut"
#define MODEM_PORT_IN    "\p.AIn"
#define PRINTER_PORT_OUT "\p.BOut"
#define PRINTER_PORT_IN  "\p.BIn"

    const char* nameStr = "";
    switch (refNum)
    {
        case aoutRefNum:
            nameStr = MODEM_PORT_OUT;
            break;
        case boutRefNum:
            nameStr = PRINTER_PORT_OUT;
            break;   

        // input device not valid for writing data
        /*
        case ainRefNum:
            nameStr = MODEM_PORT_IN;
            break;
        case binRefNum:
            nameStr = MODEM_PORT_IN;
            break;
        */

        default:
            return -1;
    }

    short serialPort = 0;
    OSErr err = MacOpenDriver(nameStr, &serialPort);
    if (err < 0) return err;

    CntrlParam cb;
    cb.ioCRefNum = serialPort;
    cb.csCode = 8;
    cb.csParam[0] = stop10 | noParity | data8 | baud9600;
    err = PBControl ((ParmBlkPtr) & cb, 0);
    if (err < 0) return err;

    IOParam pb2;
    pb2.ioRefNum = serialPort;

    char str2[255];
    sprintf(str2, "%s\n", str);
    pb2.ioBuffer = (Ptr) str2;
    pb2.ioReqCount = strlen(str2);

    err = PBWrite((ParmBlkPtr)& pb2, 0);
    if (err < 0) return err;

    err = MacCloseDriver(serialPort);
    return err;
}

writeSerialPort(aoutRefNum, "Hello World"); // write to Modem Port
writeSerialPort(boutRefNum, "Hello World"); // write to Printer Port 

There are usually two serial ports on vintage Macintosh computers, modem port and printer port. On our pce/macplus emulators, preferably you should reserve the modem port for networking and use the printer port to output debug messages. CodeLite can also be set to ‘tail’ the serial output file to monitor debug messages:

codelite_serial

CodeLite, Retro68 and pce/macplus as a VirtualBox image

You can download a VirtualBox image with Retro68, CodeLite, pce/macplus and other necessary components in a single Ubuntu installation here. The 10GB ZIP file has been split into 10 parts, which can be joined using a tool such as FFSJ. The username is macdev and password is macdev. Retro68 is installed in the Documents folder, together with the HelloWorld, MenuSample and Dialog examples adapted for use with CodeLite. Basilisk 2 emulator is also installed with System 7.6 disk image. I have also included original MPW 3.1 and MPW 3.5 header files as well a copy of Inside Macintosh, which is a must-read for anyone serious about 68k Macintosh programming.

All pce/macplus instances installed in the Mac OS Emulators folders are ready for use with CodeLite. The System 6.0.8 instance also contains MacTCP and other useful network utilities. By using the included Fetch, you can also transfer files between the System 6.0.8 instance and the Ubuntu host, which has vsftpd installed. To allow Internet access from the TUN interface, I have also enabled IP masquerade on the LAN interface for TUN traffic with the following command:

Bash
iptables -t nat -A POSTROUTING -s 192.168.0.0/24 -o enp0s3 -j MASQUERADE 

The scripts mentioned in the article can be found in the Retro68kApps folder. There is also a create_tun.sh script to create a tunnel that can be used with pce (after updating the interface name and IP address to reflect your network configuration). If TUN doesn’t work for you, you can also use start_ppd.sh and start_tty0tty.sh to emulate a PPPD server instead.

When running on VirtualBox, sometimes, you will not be able to open Settings > Displays to change the resolution. If this happens, you can use something like xrandr -s 1366×768 to set the preferred resolution. VirtualBox mouse integration should be disabled under Input > Mouse Integration menu, otherwise the mouse will move erratically inside the Mac OS emulators.

The following YouTube video, captured using VirtualBox, demonstrates how everything we set up can work together to form a custom 68k development environment:

For those who do not want to download the entire VirtualBox image, a ZIP file with just the CodeLite projects, bash scripts and a soft copy of Inside Macintosh, can be downloaded here.

See Also

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)