VS Code DOS 开发扩展是一种即插即用解决方案,用于在 C/C++ 中编写和调试 32 位保护模式 DOS 应用程序。

dos-dev - Visual Studio Marketplace

特征

  • 自动安装所需工具

  • 简单的项目初始化

    • 基于 CMake 的构建,无论是在 VS Code 中还是在命令行上

    • 用于调试的 VS 代码启动配置

    • C/C++ 开发的合理默认设置

    • 用于调试的 GDB 存根集成

    • 演示应用程序0x13等待按键时绘制像素的简单模式

    • 明智的 .gitignore

  • 通过 GDB 在 VS Code 和命令行中调试支持

快速入门

  • 安装 CMake

    • 在 Linux 上,通过包管理器安装这些包

      libncurses5 libfl-dev libslirp-dev libfluidsynth-dev

  • 在 VS Code 中安装扩展

    • CTRL+SHIFT+P(或在 macOS 上)CMD+SHIFT+P

    • ext install badlogicgames.dos-dev

  • 打开一个新的空文件夹,然后

    • CTRL+SHIFT+P(或在 macOS 上)CMD+SHIFT+P

    • DOS: Init Project

      • 当系统要求安装 DOS 工具时,请选择 Yes

      • 当系统要求安装 clangd 时,请选择 Yes

    • 按下可在 DOSBox-x 中构建和调试演示应用程序。F5

要求

您需要安装以下第三方软件:

  • 清。确保它通过环境变量在命令行上可用。PATH

    • Windows:使用CMake下载页面中的安装程序。

    • Linux:使用你的包管理器,例如 sudo apt install cmake

    • macOS:使用自制软件,brew install cmake

  • 在 Linux 上,通过包管理器安装。libncurses5 libfl-dev libslirp-dev libfluidsynth-dev

    • Ubuntu/Debian:sudo apt install libncurses5 libfl-dev libslirp-dev libfluidsynth-dev

其他一切都由自动工具安装负责。

用法

安装工具

  • CTRL+SHIFT+P(或在 macOS 上)CMD+SHIFT+P

  • 键入并选择 DOS: Install tools

这会将 DJGPP、GDB、DOSBox-x、Ninja、用于调试的 DOSBox-x 配置文件和用于 DJGPP 的 CMake 工具链文件下载到文件夹中。$HOME/.dos

您只需要安装一次工具。然后,您的所有DOS项目都可以使用它们。

初始化新项目

  • 在 VS Code 中打开一个新的空文件夹

  • CTRL+SHIFT+P(或在 macOS 上)CMD+SHIFT+P

  • 键入并选择 DOS: Init project

首次在 VS Code 中运行此命令时,如果尚未安装开发工具,系统将询问你是否要安装它们。

您可能还会被要求选择一个“套件”。从列表中选择。djgpp

系统可能会要求您安装 。选择。clangdYes

最后,系统可能会询问您是否要“配置”项目。选择。Yes

该命令将生成如下所示的项目:

文档/项目布局.png

在项目的根目录中,您可以找到

  • .clang-format,用于格式化 、 或 文件的格式定义。Th文件在保存时配置格式。.h.c``.cpp.vscode/settings.json

  • .gitignore,以排除不应提交到 Git 存储库的文件夹。

  • CMakeLists.txt、CMake 生成定义。

该文件夹包含应用的源。默认情况下,将添加 2 个文件:src/

  • gdbstub.h,GDB 存根实现作为仅头库文件,可以包含在应用中以支持调试。

  • main.c,一个简单的演示应用程序,用于设置模式0x13、绘制随机像素并等待按键退出。

CMake 版本将自动选取 的文件夹或子文件夹中的任何新源文件。src/src/

该文件夹是您播放资产文件的地方,例如图形、声音等。CMake 版本会将这些内容复制到应用的可执行文件旁边。请注意,通常,DOS 仅支持 8.3 文件名。一些DOS环境,例如DOSBox-x确实支持长文件名。为了提供最大的兼容性,请坚持使用资产和可执行文件的 8.3 文件名格式。assets/

该文件夹包含各种配置文件、定义启动配置、C/C++ 开发的合理设置等。通常,您不必触摸它们。.vscode/

调试和运行

项目模板提供两种启动配置:

  • DOS debug target

  • DOS run target

若要调试应用,请在面板中选择配置。DOS debug targetRun and Debug

此外,请确保已选择 CMake 变体,这可以通过 VS Code 底部的状态栏完成。Debug

按下开始调试。调试器将在调用 之后的语句处停止。您可以像往常一样设置断点、单步执行、继续和检查局部变量。F5gdb_start()

如果应用正在运行,则可以随时使用调试器控件的按钮中断它。Pause

调试器将在调用 之后的语句处停止。gdb_checkpoint()

注意:您无法在应用运行时设置断点。

如果要在未附加调试器的情况下运行应用,请在面板中选择启动配置。DOS run targetRun and Debug

此外,请确保已选择 CMake 变体,这可以通过 VS Code 底部的状态栏完成。Release

按下可开始运行未附加调试器的应用。F5

两种启动配置都将启动当前选定的 CMake 启动目标。如果在文件中添加了其他可执行目标,请确保通过状态栏中的 CMake 启动目标设置选择要启动的目标。CMakeLists.txt

默认情况下,只有一个可执行目标被调用,该目标会自动选择为 CMake 启动目标。main

注意:如果启动配置和 CMake 变体不匹配,例如 和变体,或和变体,调试器无法连接,或者应用将挂起。DOS debug targetRelease``DOS run targetDebug

在命令行上构建和运行

下面假设你在一个类似的环境中运行,例如macOS或Linux上的任何shell,在Windows上的Git Bash。Bash

您也可以在Windows或Powershell上运行以下内容。但是,您需要调整以 开头的任何路径,以指向用户主目录中的相应目录。cmd.exe~/.dos

所有命令都应在项目的根文件夹中执行。

建筑

1
2
3


cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_MAKE_PROGRAM=~/.dos/ninja -DCMAKE_TOOLCHAIN_FILE=~/.dos/toolchain-djgpp.cmake -S . -B build -G Ninja

这会将生成配置为生成调试二进制文件。对于发布二进制文件,请指定 。通常,仅当生成类型发生更改或对文件进行了更改时,才运行此命令。-DCMAKE_BUILD_TYPE=ReleaseCMakeLists.txt

配置完成后,您可以按如下方式构建程序:

1
2
3


cmake --build build

每次添加、删除或修改源代码或资产时,您都会运行此操作。

这会将可执行文件和资产放在目录中。build/

运行

1
2
3


~/.dos/dosbox-x/dosbox-x -fastlaunch -exit -conf tools/dosbox-x.conf build/main.exe

在 DOSBox-x 中启动可执行文件。请确保在启动之前进行配置和构建。-DCMAKE_BUILD_TYPE=Release

Debugging

1
2
3


~/.dos/dosbox-x/dosbox-x -fastlaunch -exit -conf tools/dosbox-x.conf build/main.exe

Launches the executable in DOSBox-x. Make sure to build with before launching.-DCMAKE_BUILD_TYPE=Debug

In a second shell:

1
2
3
4
5
6
7
8
9


~/.dos/gdb/gdb


(gdb) file build/main.exe


(gdb) target remote localhost:5123

GDB will connect to the program running in DOSBox-x. See the GDB cheat sheet on how to use the command line driver of GDB.

Adding debugging support to your application

默认情况下,源文件设置为支持调试,因此您不必手动执行以下操作。main.c

如果从头开始,并希望向应用程序添加调试支持,则必须集成 GDB 存根

调试是通过 中实现的 GDB 存根完成的,这是一个仅标头库,这需要应用程序的合作。src/gdbstub.h

在包含函数的源文件中,包含存根,如下所示:main()

1
2
3
4
5
6


#define GDB_IMPLEMENTATION


#include "gdbstub.h"

在函数开始时,调用:main()gdb_start()

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12


int void main(void) {


    gdb_start();





    // Rest of your code

编译应用以进行调试时,将等待调试器连接。gdb_start()

最后,如果你的应用有一个主循环,请在循环结束时添加:gdb_checkpoint()

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15


do {


    // Your main loop implementation





    gdb_checkpoint();


} while (some_condition)

这将允许调试器中断程序。

在发布模式下编译应用时,并且是无操作的。gdb_start()gdb_checkpoint()

已知问题

调试器有一些限制和陷阱:

  • 不能在程序运行时设置断点。在启动调试会话之前设置断点,或者在遇到断点、单步执行或中断后程序停止时设置断点。

  • 调试器比您可能习惯的要慢得多。这是由于使用串行端口仿真进行通信。

  • 始终确保在启动新的调试会话之前关闭 DOSBox-x 窗口。

  • 如果调试器似乎停滞不前,请等待它超时,或从命令面板执行命令。Debug: Stop

  • 一般来说,调试支持是一个大黑客,可能有龙。还是比过日子好!printf

这些工具目前不适用于ARM64 Linux或ARM64 Windows。他们确实在macOS上的Apple Silicon上工作。

常见问题

DOS 开发资源

查看以下资源,让您的 DOS 编程源源不断:

调试如何工作?

我很高兴你问!这是一个邪恶的胶带球,由以下部分组成:

  • GDB 存根,在 src/gdbstub.h 中作为仅头文件库实现。它实现了 GDB 远程协议并包含在程序本身中,然后它将控制并“公开”给调试器进行检查和修改。它是Glenn Engel和Jonathan Brogdon GDB存根的大量修改和扩展版本,因此它实际上可以完成现代调试器所期望的所有事情。我建议不要查看该文件。它不是用爱或关怀建造的,只是足够的尽管,所以它放弃并开始工作。主要。

  • GDB 7.1a 的自定义最小版本,GDB <>.<>a 是支持 DJGPP 生成的可执行文件的 GDB 的最后一个版本之一。COFF_GO32

  • DOSBox-x的修改版本,这是必要的,因为通过TCP / IP的串行端口通信在macOS上被破坏了。我的拉取请求已合并,因此希望此模板最终可以切换到官方的DOSBox-x版本。

以下是它的工作原理:

  1. DOSBox-x 配置为在空调制解调器、非握手模式下通过端口 0 上的 TCP 向外界公开串行端口 1 (COM5123)。

  2. 该程序在DOSBox-x中启动并首次调用。此函数初始化串行端口以使用可能的最高波特率,然后通过 触发断点。这反过来又触发了在 GDB 存根中实现的特殊信号处理程序,该处理程序侦听来自串行端口的传入数据。gdb_start()int 3

  3. 调试器 (GDB) 被告知通过地址为 localhost:5123 的 TCP 连接到远程进程。这将建立与信号处理程序的连接,该处理程序等待串行端口上的数据传入。

  4. GDB 发送命令,例如设置断点、步骤或继续,信号处理程序解释和执行这些命令。

  5. 作为特殊情况,如果程序正在运行并且调试器想要中断它以设置更多断点或获取信息,则 GDB 存根还会挂钩计时器中断以轮询串行端口状态。如果有数据等待,它会设置一个内部标志,该标志将提示通过 触发软件断点,进而调用信号处理程序。gdb_checkpoint()int 3

从理论上讲,所有这些都非常简单。在实践中,它可以以最具创造性的方式分崩离析。该实现使用包含的 GDB 版本以及位于包含的 GDB 版本之上的本机调试器扩展进行了测试。

我不能保证它可以与其他 GDB 版本或更高级别的调试器一起使用,例如 CLion 等。应该的。但它可能不会,因为大多数调试器不遵守协议规范。

发行说明

[1.3.0]

  • 通过不显示本机调试扩展内部控制台窗口进行改进。DOS debug target

[1.2.0]

  • 修复了Windows上的启动配置。需要通过 Powershell 中的文件运行才能获得相同的行为。DOS run target.bat

  • 显示调试配置中的调用时间。Waiting for debuggergdb_start()

  • 修复了在 Windows 上项目初始化后配置项目的问题。

[1.1.0]

  • README.md 更新

[1.0.0]

  • 初始版本