65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 CodeLite IDE、Retro68 和 pce-macplus 模拟器开发复古 68K Macintosh 应用

2023年5月7日

CPOL

7分钟阅读

viewsIcon

2674

使用 CodeLite IDE、Retro68 和 pce-macplus 模拟器开发复古 68K Macintosh 应用

在我之前的文章中,我介绍了如何使用 Retro68 从现代 Linux 发行版编译 68K Macintosh 应用,并探讨了 Retro68 与 CodeLite 和 pce/macplus 模拟器如何构成一个非常好的 68k 开发环境。在这篇文章中,我将提供如何在常见的 Linux 发行版 Ubuntu 上创建这样的开发环境的详细信息。对于那些没有时间从头开始设置一切的人来说,在文章的最后,我将提供下载 VirtualBox 镜像的链接,该镜像在一个 Ubuntu 安装中包含了 Retro68、CodeLite、pce/macplus 以及其他必要的组件。

必备组件

在我们开始之前,你应该已经在你喜欢的 Linux 发行版上安装了Retro68pce/macplus,并且可选地安装了Basilisk II,例如,通过使用 sudo apt-get install basilisk2 sudo apt-get install codelite虽然任何版本的 CodeLite 都可以满足我们的需求,但如果你有时间,请尝试从最新源代码安装 CodeLite,因为一些旧版本的 CodeLite 可能存在自动补全问题,这在使用 Retro68 SDK 时会显现出来。

准备构建环境

我们的目标是在 CodeLite 中编译和运行 Retro68 应用,最好还能提供一些调试支持,因此我们的第一个任务是编写 bash 脚本来自动化各种任务。对于我们的目的,我们只需要以下脚本(有关完整源代码,请参阅文章末尾的下载链接)

  • build.sh:构建指定项目
  • build_and_run.sh:构建指定项目并在指定模拟器中运行。此脚本将调用 build.sh,完成后启动选定的 Mac OS 模拟器。
  • clean.sh:删除选定项目的所有构建输出。

从命令行构建 Retro68 应用以及启动 pce/macplus 模拟器非常简单。然而,将编译后的可执行文件复制到选定的模拟器,以便用户在模拟器启动完成后进行启动,这是一个挑战。幸运的是,Retro68 会生成 BinHex (.BIN) 或 800k 磁盘镜像 (.DSK) 的构建输出。你可以简单地将 .DSK 输出重命名为 .image,然后将其作为 800k 软盘驱动器挂载到 pce/macplus 中。或者,你可以使用 hformathmounthcopy(它们是 hfsutils 包的一部分)来创建一个 HFS 磁盘镜像,其中包含 .BIN 文件以及应用程序中的任何其他输入文件,并将其挂载到 pce/macplus 中。HFS 镜像将显示为一个 Hard Disk 20 硬盘驱动器,可以在装有标准 ROM 的 Macintosh Plus 及更新机型上读取,或者在装有 Macintosh Plus ROM 的 Macintosh 128K/512K 上读取。

我们的第一个 CodeLite 68k 项目现在准备创建了。我们将使用 CodeLite 的 C++ 模板,并为不同类型的 Mac OS 模拟器添加不同的项目配置。

codelite_project_config

对于每个项目配置,我们将在 **Workspace** > **Open Active Project Settings** 中配置我们的 bash 脚本。在 **General** 设置中,配置脚本以使用我们选定的模拟器构建和运行项目。

codelite_general

我们的 build_and_run.sh 脚本的参数指示要构建的项目和要运行它的模拟器,这需要在程序参数中正确指定。工作目录也需要正确设置。请记住勾选 _“This program is a GUI application”_,否则模拟器将无法启动。在 **Customize** > **Custom Build** 中,指定构建和运行项目的命令。

codelite_custom_build

在 **Code Completion** 中,指定 Macintosh Programmer’s Workshop C 头文件的路径,特别是 CIncludesRIncludes 文件夹,以便自动补全正常工作。

codelite_include

这些文件夹也需要在 **Global Settings** > **Additional Include Paths** 中指定。

codelite_include

还将这些文件夹添加到 **Settings** > **Code Completion** > **CTags** > **Search Paths**。

codelite_search_path

由于 MPW 使用 `.r` 文件,这些文件是用一种类似于 C 的语言编写的,用于对话框资源,因此我们也应该在 C++ 文件扩展名列表中添加 `*.r`。你可以在 **Settings** > **Colours and Fonts** > **Customize** > **C++** 中进行设置。

codelite_r_types

当然,你可能还想根据自己的需要调整自动补全和其他编辑器设置。对每个项目配置重复上述步骤,并记住更改命令行参数以指示要运行项目的 Mac OS 模拟器。完成后,选择 **Workspace** > **Parse Workspace** 并重新启动 CodeLite。你会注意到方法签名现在可以被检测到,自动补全也可以正常工作。

codelite_autocomplete

通过这种设置,常见的 CodeLite 任务,如构建、运行和清理,现在应该可以正常工作了。下面的屏幕截图显示 CodeLite 在 pce/macplus 下的 System 6.0.8 上运行 MenuSample 示例。

codelite_retro68

MenuSample 应用可以从模拟的 Test Apps 磁盘启动。

codelite_menusample

为了让 pce/macplus 从现有的带有 System 软件的硬盘启动,而不是从我们刚刚编译代码创建的 HFS 磁盘启动,设置 pce 配置中的 insert_delay 参数的值约为 3-5 秒非常重要。否则,模拟器将尝试从该 HFS 磁盘启动并失败,因为我们的 HFS 磁盘显然不是可引导的。

添加调试支持

pce/macplus 提供了一些调试支持,但其集成调试器只能在汇编语言级别工作,不适合我们的目的。而且,虽然 Retro68 生成 GDB 调试符号,但由于涉及模拟层,通过 pce/macplus 利用这些符号来调试我们的 68K 应用并非易事。我想到的唯一简单方法是将调试消息写入 Macintosh 串行端口,并配置将串行输出重定向到磁盘上的文本文件。这可以通过以下配置项完成。

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

上面的配置会将所有串行输出重定向到磁盘上名为 serial.out 的文件。然后可以使用以下代码从 pce 写入串行端口。

#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 

复古 Macintosh 计算机通常有两个串行端口:调制解调器端口和打印机端口。在我们的 pce/macplus 模拟器上,最好将调制解调器端口用于网络,并将打印机端口用于输出调试消息。CodeLite 也可以设置为“tail”串行输出文件以监控调试消息。

codelite_serial

CodeLite、Retro68 和 pce/macplus 作为 VirtualBox 镜像

你可以在这里下载一个 VirtualBox 镜像,该镜像在一个 Ubuntu 安装中包含了 Retro68、CodeLite、pce/macplus 和其他必要的组件。这个 10GB 的 ZIP 文件已被分割成 10 个部分,可以使用类似 FFSJ 的工具进行合并。用户名是 macdev,密码是 macdev。Retro68 安装在 Documents 文件夹中,与为 CodeLite 使用而改编的 HelloWorldMenuSampleDialog 示例一起。Basilisk 2 模拟器也已安装,并附带 System 7.6 磁盘镜像。我还包含了原始的 MPW 3.1 和 MPW 3.5 头文件,以及一本《Inside Macintosh》的副本,对于任何认真进行 68k Macintosh 编程的人来说,这都是必读的。

Mac OS Emulators 文件夹中安装的所有 pce/macplus 实例都已准备好与 CodeLite 一起使用。System 6.0.8 实例还包含 MacTCP 和其他有用的网络实用程序。通过使用包含的 Fetch,你还可以传输 System 6.0.8 实例和已安装 vsftpd 的 Ubuntu 主机之间的文件。为了允许从 TUN 接口访问 Internet,我还通过以下命令启用了 LAN 接口上 TUN 流量的 IP 伪装。

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

文章中提到的脚本可以在 Retro68kApps 文件夹中找到。还有一个 create_tun.sh 脚本,用于创建可以与 pce 一起使用的隧道(在更新接口名称和 IP 地址以反映你的网络配置之后)。如果 TUN 对你不起作用,你也可以使用 start_ppd.shstart_tty0tty.sh 来模拟一个 PPPD 服务器。

在 VirtualBox 上运行时,有时你无法打开 **Settings** > **Displays** 来更改分辨率。如果发生这种情况,你可以使用类似 **xrandr -s 1366×768** 的命令来设置首选分辨率。VirtualBox 鼠标集成应在 **Input** > **Mouse Integration** 菜单下禁用,否则鼠标在 Mac OS 模拟器中会 erratic 地移动。

以下 YouTube 视频(使用 VirtualBox 录制)演示了我们设置的所有内容如何协同工作,形成一个自定义的 68k 开发环境。

对于那些不想下载整个 VirtualBox 镜像的人来说,一个只包含 CodeLite 项目、bash 脚本和《Inside Macintosh》软拷贝的 ZIP 文件可以在这里下载。

另请参阅

© . All rights reserved.