Repository: badlogic/dos-dev-template
Branch: main
Commit: 521398021647
Files: 19
Total size: 140.2 KB
Directory structure:
gitextract_b7a8hb4w/
├── .clang-format
├── .github/
│ └── FUNDING.yml
├── .gitignore
├── .vscode/
│ ├── cmake-kits.json
│ ├── launch.json
│ ├── run-windows.bat
│ ├── settings.json
│ └── tasks.json
├── CMakeLists.txt
├── LICENSE
├── README.md
├── assets/
│ └── test.txt
├── doc/
│ └── examples/
│ ├── debugger.c
│ └── keyboard.c
├── download-tools.sh
├── src/
│ ├── gdbstub.h
│ └── main.c
└── tools/
├── dosbox-x.conf
└── toolchain-djgpp.cmake
================================================
FILE CONTENTS
================================================
================================================
FILE: .clang-format
================================================
# Generated from CLion C/C++ Code Style settings
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: None
AlignOperands: Align
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Always
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: true
AlwaysBreakAfterReturnType: None
AlwaysBreakTemplateDeclarations: Yes
BreakBeforeBraces: Custom
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: false
SplitEmptyRecord: true
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
ColumnLimit: 0
CompactNamespaces: false
ContinuationIndentWidth: 8
IndentCaseLabels: true
IndentPPDirectives: None
IndentWidth: 4
KeepEmptyLinesAtTheStartOfBlocks: true
MaxEmptyLinesToKeep: 2
NamespaceIndentation: All
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PointerAlignment: Right
ReflowComments: false
SortIncludes: false
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 0
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
TabWidth: 4
UseTab: ForContinuationAndIndentation
================================================
FILE: .github/FUNDING.yml
================================================
github: [badlogic]
================================================
FILE: .gitignore
================================================
build
tools/djgpp
tools/dosbox-x
tools/gdb
.cache
tools/capture
serial.txt
================================================
FILE: .vscode/cmake-kits.json
================================================
[
{
"name": "djgpp",
"toolchainFile": "${workspaceFolder}/tools/toolchain-djgpp.cmake"
}
]
================================================
FILE: .vscode/launch.json
================================================
{
"version": "0.2.0",
"configurations": [
{
"type": "gdb",
"request": "attach",
"name": "debug target",
"executable": "${command:cmake.getLaunchTargetPath}.exe",
"target": "localhost:5123",
"remote": true,
"cwd": "${workspaceRoot}",
"gdbpath": "${workspaceFolder}/tools/gdb/gdb",
"preLaunchTask": "task-dosbox-debug",
"internalConsoleOptions": "neverOpen",
"stopAtConnect": true
},
{
"type": "node-terminal",
"name": "run target",
"request": "launch",
"command": "cmake --build build && ${workspaceFolder}/tools/dosbox-x/dosbox-x -conf ${workspaceFolder}/tools/dosbox-x.conf -fastlaunch -exit ${command:cmake.getLaunchTargetPath}.exe && exit",
"windows": {
"name": "DOS run target",
"type": "node-terminal",
"request": "launch",
"command": ".vscode/run-windows.bat ${command:cmake.getLaunchTargetPath}; exit",
"cwd": "${workspaceFolder}"
}
}
]
}
================================================
FILE: .vscode/run-windows.bat
================================================
cmake --build build
IF %ERRORLEVEL% NEQ 0 (Exit /b 1)
dos\tools\dosbox-x\dosbox-x -conf dos\tools\dosbox-x.conf -fastlaunch -exit %1.exe
IF %ERRORLEVEL% NEQ 0 (Exit /b 1)
================================================
FILE: .vscode/settings.json
================================================
{
"C_Cpp.intelliSenseEngine": "disabled",
"cmake.configureOnOpen": true,
"editor.formatOnSave": true,
"editor.tabSize": 4
}
================================================
FILE: .vscode/tasks.json
================================================
{
"version": "2.0.0",
"tasks": [
{
"type": "shell",
"label": "task-dosbox-debug",
"command": "${workspaceFolder}/tools/dosbox-x/dosbox-x",
"args": [
"-conf",
"${workspaceFolder}/tools/dosbox-x.conf",
"-fastlaunch",
"-exit",
"${command:cmake.getLaunchTargetPath}.exe"
],
"dependsOn": "task-dosbox-build",
"isBackground": true,
"problemMatcher": [
{
"pattern": [
{
"regexp": ".",
"file": 1,
"location": 2,
"message": 3
}
],
"background": {
"activeOnStart": true,
"beginsPattern": ".",
"endsPattern": "."
}
}
]
},
{
"type": "shell",
"label": "task-dosbox-build",
"command": "cmake --build build"
}
]
}
================================================
FILE: CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.7)
project(dos-app)
set(CMAKE_GENERATOR Ninja)
set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
add_compile_options(-Wall -std=gnu99 -save-temps)
file(GLOB sources CONFIGURE_DEPENDS "src/*.c" "src/*.cpp" "src/*.h" )
add_executable(main ${sources})
add_custom_target(assets
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_CURRENT_SOURCE_DIR}/assets
${CMAKE_BINARY_DIR}/assets
)
add_dependencies(main assets)
add_executable(keyboard doc/examples/keyboard.c)
add_executable(debugger doc/examples/debugger.c)
================================================
FILE: LICENSE
================================================
BSD 2-Clause License
Copyright (c) 2022, Mario Zechner
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
================================================
FILE: README.md
================================================
# DOS demo/game development template
# Attention: for an even better experience, use my new [VSCode DOS development extension](https://marketplace.visualstudio.com/items?itemName=badlogicgames.dos-dev)

Want to relive the 90ies and create little demos and games for DOS using C/C++ with "modern" tools? Then this project template is for you.
It's a turn key solution to setup a develpoment environment to create DOS demos/apps. consisting of:
* [DJGPP](https://www.delorie.com/djgpp/), the GCC-based C/C++ compiler for DOS (DPMI/protected mode).
* [GDB](https://www.sourceware.org/gdb/), the debugger used to debug the DOS demo/game.
* [DOSBox-x](https://dosbox-x.com/), the bells and whistles DOS-emulator to develop and run the DOS demo/game in.
* [CMake](https://cmake.org/), to define what needs to be build how.
* [Ninja](https://github.com/ninja-build/ninja/releases), to execute the build defined by CMake.
* [Visual Studio Code](https://code.visualstudio.com/), to tie all the above together and provide an integrated development environment.
## Quickstart Guide
### Installation
Install:
* [Git](https://git-scm.com/): On Windows, install [Git for Windows](https://gitforwindows.org/). You will need `Git Bash` to run a shell script later.
* [CMake](https://cmake.org/): ensure `cmake` is in your `PATH`.
* [Ninja](https://github.com/ninja-build/ninja/releases)
* Windows: Put the ninja.exe file somewhere and make sure it's available on the command line via your system PATH.
* Linux, e.g. Debian/Ubuntu: `sudo apt install ninja-build`
* macOS, through [brew](https://brew.sh/): `brew install ninja`
* [Visual Studio Code](https://code.visualstudio.com/): ensure [command line interface is installed](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-the-visual-studio-code-vs-code-command-line-interface) and in your `PATH`.
Open a shell (Git Bash on Windows), then:
```
git clone https://github.com/badlogic/dos-dev-template
cd dos-dev-template
./download-tools.sh
```
The `download-tools.sh` script will download everything you need to start developing for DOS.
> Note: On Linux, you need to install the following packages using your distribution's package manager: `libncurses5 libfl-dev libslirp-dev libfluidsynth-dev`
Once complete, open the `dos-dev-template/` folder in Visual Studio Code.
The first time you start Visual Studio Code, you may be promoted to install the clangd language service. Make sure you click "Install!"

You may also be prompted to select a kit. Select `djgpp`.
### Project structure
```
.vscode/ <- configuration files for VS Code & extensions
assets/ <- files used by the program
doc/ <- documentation and example programs
src/ <- source code goes here
main.c <- a little mode 13h demo app
tools/ <- contains GDB, DJGPP, DOSBOX after download
dosbox-x.conf <- DOSBox-x config enabling debugging via serial port
toolchain-djgpp.cmake <- CMake toolchain definition file for DJGPP
CMakeLists.txt <- CMake build definition.
download-tools.sh <- Script to download GDB, DJGPP, DOSBOX,
and Visual Studio Code extensions
```
### Running and debugging
Open the `Run and debug` view as shown in the screenshot above, then start one of the two launch configurations:
* `debug target`: builds and launches the currently selected [CMake launch target](https://vector-of-bool.github.io/docs/vscode-cmake-tools/debugging.html) in DOSBox-x, and attaches the debugger.
* `run target`: builds and launches the currently selected CMake launch target in DOSBox-x without attaching a debugger.
> Make sure the [Cmake Build Variant](https://stackoverflow.com/a/73329010) matches the launch configuration, e.g. set the `Debug` variant when launching `debug target`, and the `Release` variant when launching the `run target`. Otherwise, the debugger may not be able to attach (`Release` variant when launching `debug target`), or the program may hang, waiting for the debugger (`Debug` variant when launching `release target`)
For your program to support debugging, you have to do 3 things:
1. In one `.c` or `.cpp` files, add the following code:
```
#define GDB_IMPLEMENTATION
#include "gdbstub.h"
```
2. In your `main()`, call `gdb_start()`.
3. In your main loop, call `gdb_checkpoint()` to give the debugger a chance to interrupt your program.
The debugger has a few limitations & gotchas:
* You can not set breakpoints while the program is running. Set breakpoints before launching a debugging session, or while the program is halted after hitting a breakpoint, stepping, or was interrupted.
* The debugger is quite a bit slower than what you may be used to. This is due to the use of the serial port emulation for communication.
* Always make sure to close the DOSBox-x window before launching a new debugging session.
* If the debugger appears to be stuck, either wait for it to timeout, or execute the `Debug: Stop` command from the command palette.
* When you click the debugger's `Pause` button or press `F6` to pause the program, you will end up in `gdb_checkpoint()`.
* In general, the debugging support is one big hack, there may be dragons. Still better than `printf`-ing your way through life!
## Writing code
Easy, just open or create a new `.h`, `.c`, or `.cpp` file in the `src/` folder and type away. You will get full code completion, navigation and what young people call "lints". Newly created files will be added to the build automatically.
Your code is compiled with [DJGPP](https://www.delorie.com/djgpp/doc/eli-m17n99.html), which means it will become a beautiful 32-bit protected mode application. Check out the resources below to get your DOS programming juices flowing:
* [256-Color VGA Programming in C](http://www.brackeen.com/vga/index.html), a 5 part tutorial on VGA programming, using DJGPP.
* [The Art of Demomaking](https://www.flipcode.com/archives/The_Art_of_Demomaking-Issue_01_Prologue.shtml), a 16 part series explaining and demonstrating various demo effects, using DJGPP.
* [Brennan's Guide to Inline Assembly](http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html), in case you want to speed up your app with some artisan, hand-crafted assembly.
## Asset files
While you can do a lot with just code, sometimes you need a good old file. Put the files for your program in the `assets/` folder. The file will then be available to your program via the path `assets/<your-file-name>`, which you can pass to e.g. `fopen()`.
## Building and running from the command line
If you don't like graphical user interfaces, you can also do all of the above from the command line.
### Building
```
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE=tools/toolchain-djgpp.cmake -S . -B build -G Ninja
```
This configures your build to produce a debug binary. For a release binary, specify `-DCMAKE_BUILD_TYPE=Release`. You generally run this command only when your build type changes.
Once configured, you can build the program as follows:
```
cmake --build build
```
This puts the executable file and assets in the `build/` directory.
### Running
```
./tools/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 `-DCMAKE_BUILD_TYPE=Release` before launching.
### Debugging
```
./tools/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 `-DCMAKE_BUILD_TYPE=Debug` before launching.
In a second shell:
```
./tools/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](https://darkdust.net/files/GDB%20Cheat%20Sheet.pdf) on how to use the command line driver of GDB.
## FAQ
Here are a few questions you may have, if you want to dig deeper into the entire setup to modify it to your liking.
### What does `download-tools.sh` do?
It will download the following tools for your operating system to the `tools/` folder:
* My fork of [GDB 7.1a](https://github.com/badlogic/gdb-7.1a-djgpp), which is specifically build to debug DOS programs compiled with DJGPP remotely, e.g. running in DOSBox-x.
* [DJGPP binaries](https://github.com/badlogic/dosbox-x) provided by [Andrew Wu](https://github.com/andrewwutw)
* My fork of [DOSBox-x](https://github.com/badlogic/dosbox-x), which fixes a few things required for debugging, such as [serial port emulation through TCP/IP on macOS](https://github.com/joncampbell123/dosbox-x/pull/3892).
After downloading the tools, it will install these Visual Studio Code extensions necessary for C/C++ development:
* [clangd](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd), the superior C/C++ code completion, navigation, and insights language service.
* [CMake Tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cmake-tools), for CMake support in VS Code
* [C/C++ for Visual Studio Code](https://code.visualstudio.com/docs/languages/cpp), needed to do anything C/C++ in VS Code. Its less than great intellisense service is replaced by clangd though.
* [Native Debug Extension](https://marketplace.visualstudio.com/items?itemName=webfreak.debug), provides the high-level debugger capanble of using GDB.
### How does the debugging work?
I'm glad you ask! It's an unholy ball of duct tape consisting of:
* [A GDB stub](/src/gdbstub.h), implemented as a header-file only library. It implements the [GDB remote protocol](https://sourceware.org/gdb/onlinedocs/gdb/Remote-Protocol.html) and is included in the program itself, which it will then control and "expose" to the debugger for inspection and modification. It's a heavily modified and extended version of [Glenn Engel & Jonathan Brogdon GDB stub](http://ftp.lanet.lv/ftp/mirror/x2ftp/msdos/programming/djgpp/v2misc//gdbst01s.zip), so it can actually do all the things expected of a somewhat modern debugger. I would suggest not looking into that file. It was not build with love or care, just enough spite so it gave up and started working. Mostly.
* [A custom, minimal build of GDB 7.1a](https://github.com/badlogic/gdb-7.1a-djgpp), one of the last versions of GDB to support `COFF_GO32` executables as produced by DJGPP.
* [A modified version of DOSBox-x](https://github.com/badlogic/dosbox-x), which was necessary as serial port communication over TCP/IP was broken on macOS. My [pull request](https://github.com/joncampbell123/dosbox-x/pull/3892) was merged, so hopefully this template can switch over to the official DOSBox-x build eventually.
And here's how it works:
1. DOSBox-x is configured to expose serial port 0 (COM1) to the outside world via TCP on port 5123 in nullmodem, non-handshake mode.
1. The program is started in DOSBox-x and first calls `gdb_start()`. This function initializes the serial port to use the highest baud rate possible, then triggers a breakpoint via `int 3`. This in turn triggers a special signal handler implemented in the GDB stub which listens for incoming data from the serial port.
1. The debugger (GDB) is told to connect to a remote process via TCP at address localhost:5123. This establishes a connection to the signal handler that waits for data coming in on the serial port.
1. GDB sends commands, like set a breakpoint, step, or continue, which the signal handler interprets and executes.
1. As a special case, if the program is running and the debugger wants to interrupt it to set further breakpoints or get information, the GDB stub also hooks the timer interrupt to poll the serial port state. In case there's data waiting, it set an internal flag, which will prompt `gdb_checkpoint()` to trigger a software breakpoint via `int 3`, which in turn will invoke the signal handler.
In theory, all of this is very simple. In practice, it can fall apart in the most creative ways. The implementation was tested with the included GDB version, as well as the Native Debugger extension which sits on top the included GDB version.
I can make no guarantees it will work with other GDB versions or higher level debuggers as found in e.g. CLion, etc. It should. But it might not, as most debuggers don't stick to the protocol spec.
### What are all those files in `.vscode`?
These are configuration files for the various extensions and VS Code itself to provide you with a passable out-of-the-box experience.
* [cmake-kits.json](.vscode/cmake-kits.json) tells the CMake Tools extension about the DJGPP toolchain, which is defined as a CMake toolchain file in [tools/toolchain-djgpp.cmake](tools/toolchain-djgpp.cmake)
* [launch.json](.vscode/launch.json) defines the 2 launch configurations `debug target` and `run target`. They in turn depend on tasks defined in [tasks.json](.vscode/tasks.json)
* [settings.json](.vscode/settings.json) turns off the not great C/C++ extension intellisense and configures a few other minor things.
================================================
FILE: assets/test.txt
================================================
Hello DOS!
================================================
FILE: doc/examples/debugger.c
================================================
#include "pc.h"
#include <stdio.h>
#include <stdlib.h>
// To add the code of the debugger to your program, define
// GDB_IMPLEMENTATION in one .c or .cpp file and include
// 'gdbstub.h'
#define GDB_IMPLEMENTATION
#include "../../src/gdbstub.h"
int foo(int a, int b) {
for (int i = 0; i < 10; i++) {
a += 12;
b += a * i;
}
return a + b;
}
int main(void) {
// To start the debugger, call gdb_start()
gdb_start();
while (!kbhit()) {
int a = rand();
int b = rand();
printf("%i\n", foo(a, b));
// To give the debugger a chance to interrupt your program
// call 'gdb_checkpoint()' somewhere in your main loop.
gdb_checkpoint();
}
}
================================================
FILE: doc/examples/keyboard.c
================================================
#include "pc.h"
#include "sys/segments.h"
#include "unistd.h"
#include <dpmi.h>
#include <stdio.h>
#include <stdint.h>
#define GDB_IMPLEMENTATION
#include "../../src/gdbstub.h"
#define KEY_EXTENDED 0x60
#define KEY_LEFT (KEY_EXT_SHIFT + 75)
#define KEY_RIGHT (KEY_EXT_SHIFT + 77)
#define KEY_UP (KEY_EXT_SHIFT + 72)
#define KEY_DOWN (KEY_EXT_SHIFT + 80)
#define KEY_ESC 1
#define KEYBOARD_INTERRUPT 0x9
#define PAGE_SIZE 4096;
typedef struct keyboard_state {
_go32_dpmi_seginfo old_keyboard_handler;
_go32_dpmi_seginfo new_keyboard_handler;
uint8_t keys[0xc0];
uint8_t extended_key;
} keyboad_state;
keyboad_state keyboard;
void keyboard_handler() {
uint8_t raw_code = inp(0x60);
uint8_t pressed = !(raw_code & 0x80);
int scan_code = raw_code & 0x7F;
if (keyboard.extended_key == 0xE0) {
if (scan_code < 0x60) {
keyboard.keys[KEY_EXTENDED + scan_code] = pressed;
}
keyboard.extended_key = 0;
} else if (keyboard.extended_key >= 0xE1 && keyboard.extended_key <= 0xE2) {
keyboard.extended_key = 0;
} else if (raw_code >= 0xE0 && raw_code <= 0xE2) {
keyboard.extended_key = raw_code;
} else if (scan_code < 0x60) {
keyboard.keys[scan_code] = pressed;
}
outportb(0x20, 0x20);
}
void setup_keyboard() {
_go32_dpmi_lock_data(&keyboard, sizeof(keyboard));
_go32_dpmi_lock_code(keyboard_handler, 4096);
_go32_dpmi_get_protected_mode_interrupt_vector(KEYBOARD_INTERRUPT, &keyboard.old_keyboard_handler);
keyboard.new_keyboard_handler.pm_offset = (int) keyboard_handler;
keyboard.new_keyboard_handler.pm_selector = _my_cs();
_go32_dpmi_allocate_iret_wrapper(&keyboard.new_keyboard_handler);
_go32_dpmi_set_protected_mode_interrupt_vector(KEYBOARD_INTERRUPT, &keyboard.new_keyboard_handler);
}
void reset_keyboard() {
_go32_dpmi_set_protected_mode_interrupt_vector(KEYBOARD_INTERRUPT, &keyboard.old_keyboard_handler);
_go32_dpmi_free_iret_wrapper(&keyboard.new_keyboard_handler);
}
int main(void) {
gdb_start();
setup_keyboard();
printf("Press some keys\n");
while (!keyboard.keys[KEY_ESC]) {
uint8_t key_pressed = 0;
for (int i = 0; i < 0xc0; i++) {
if (keyboard.keys[i]) {
printf("%i, ", i);
key_pressed = 1;
}
}
if (key_pressed) printf("\n");
gdb_checkpoint();
}
reset_keyboard();
return 0;
}
================================================
FILE: download-tools.sh
================================================
#!/bin/bash
set -e
rm -rf tools/gdb
rm -rf tools/djgpp
rm -rf tools/dosbox-x
base_url="https://marioslab.io/dump/dos"
gdb_url=""
djgpp_url=""
dosbox_url=""
os=$OSTYPE
if [[ "$os" == "linux-gnu"* ]]; then
gdb_url="https://github.com/badlogic/gdb-7.1a-djgpp/releases/download/gdb-7.1a-djgpp/gdb-7.1a-djgpp-linux.zip";
djgpp_url="https://github.com/andrewwutw/build-djgpp/releases/download/v3.3/djgpp-linux64-gcc1210.tar.bz2";
dosbox_url="https://github.com/badlogic/dosbox-x/releases/download/dosbox-x-gdb-v0.84.5/dosbox-x-0.84.5-linux.zip";
elif [[ "$os" == "darwin"* ]]; then
gdb_url="https://github.com/badlogic/gdb-7.1a-djgpp/releases/download/gdb-7.1a-djgpp/gdb-7.1a-djgpp-macos-x86_64.zip";
djgpp_url="https://github.com/andrewwutw/build-djgpp/releases/download/v3.3/djgpp-osx-gcc1210.tar.bz2";
dosbox_url="https://github.com/badlogic/dosbox-x/releases/download/dosbox-x-gdb-v0.84.5/dosbox-x-macosx-x86_64-20221223232510.zip";
elif [[ "$os" == "cygwin" ]] || [[ "$os" == "msys" ]] || [[ $(uname -r) =~ WSL ]]; then
gdb_url="https://github.com/badlogic/gdb-7.1a-djgpp/releases/download/gdb-7.1a-djgpp/gdb-7.1a-djgpp-windows.zip";
djgpp_url="https://github.com/andrewwutw/build-djgpp/releases/download/v3.3/djgpp-mingw-gcc1210-standalone.zip";
dosbox_url="https://github.com/badlogic/dosbox-x/releases/download/dosbox-x-gdb-v0.84.5/dosbox-x-mingw-win64-20221223232734.zip";
else
echo "Sorry, this template doesn't support $os"
exit
fi
pushd tools &> /dev/null
echo "Installing GDB"
echo "$gdb_url"
mkdir -p gdb
pushd gdb &> /dev/null
curl -L $gdb_url --output gdb.zip &> /dev/null
unzip -o gdb.zip > /dev/null
rm gdb.zip > /dev/null
popd &> /dev/null
echo "Installing DJGPP"
echo "$djgpp_url"
if [[ "$os" == "cygwin" ]] || [[ "$os" == "msys" ]] || [[ $(uname -r) =~ WSL ]]; then
curl -L $djgpp_url --output djgpp.zip &> /dev/null
unzip djgpp.zip &> /dev/null
rm djgpp.zip
else
curl -L $djgpp_url --output djgpp.tar.bz2 &> /dev/null
tar xf djgpp.tar.bz2
rm djgpp.tar.bz2
fi
echo "Installing DOSBox-x"
echo "$dosbox_url"
curl -L $dosbox_url --output dosbox.zip &> /dev/null
unzip -o dosbox.zip &> /dev/null
rm dosbox.zip
echo "Installing VS Code extensions"
if [[ $(code --version) ]]; then
code --install-extension llvm-vs-code-extensions.vscode-clangd --install-extension ms-vscode.cmake-tools --install-extension ms-vscode.cpptools --install-extension webfreak.debug
else
echo "WARNING: could not find 'code' on path. Could not install VS Code extensions!"
echo " Ensure 'code' is on your PATH and re-run 'download-tools.sh' to install"
echo " the VS Code extensions."
fi
if [[ "$os" == "linux-gnu"* ]]; then
chmod a+x gdb/gdb > /dev/null
chmod a+x djgpp/bin/*
chmod a+x djgpp/i586-pc-msdosdjgpp/bin/*
chmod a+x dosbox-x/dosbox-x-sdl1
ln -s $(pwd)/dosbox-x/dosbox-x-sdl1 dosbox-x/dosbox-x
echo
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
echo
echo " Please install the following packages using your Linux distribution's "
echo " package manager:"
echo
echo " libncurses5 libfl-dev libslirp-dev libfluidsynth-dev"
echo
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
elif [[ "$os" == "darwin"* ]]; then
chmod a+x gdb/gdb > /dev/null
chmod a+x djgpp/bin/*
chmod a+x djgpp/i586-pc-msdosdjgpp/bin/*
chmod a+x dosbox-x/dosbox-x.app/Contents/MacOS/dosbox-x
ln -s $(pwd)/dosbox-x/dosbox-x.app/Contents/MacOS/dosbox-x dosbox-x/dosbox-x
elif [[ "$os" == "cygwin" ]] || [[ "$os" == "msys" ]] || [[ $(uname -r) =~ WSL ]]; then
rm -rf "COPYING"
mv mingw-build/mingw dosbox-x
rm -rf mingw-build
fi
popd &> /dev/null
================================================
FILE: src/gdbstub.h
================================================
#pragma once
#include <stdbool.h>
#ifdef NDEBUG
#define gdb_start()
#define gdb_checkpoint()
#else
#ifdef DJGPP
#define gdb_start() \
_gdb_start(); \
printf("Waiting for debugger...\n"); \
asm("int $3");
#define gdb_checkpoint() \
if (_gdb_checkpoint()) asm("int $3");
#else
#define gdb_start()
#define gdb_checkpoint()
#endif
#endif
#ifdef GDB_IMPLEMENTATION
#ifdef NDEBUG
void _gdb_start() {}
bool _gdb_checkpoint() { return false; }
#elif !defined(DJGPP)
void _gdb_start() {}
bool _gdb_checkpoint() { return false; }
#else
#include <bios.h>
#include <dpmi.h>
#include <go32.h>
#include <pc.h>
#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/exceptn.h>
#include <sys/farptr.h>
void _gdb_start();
bool _gdb_checkpoint();
void gdb_loop(int exception_number);
void gdb_tick_handler();
static unsigned char *gdb_read_packet();
static void gdb_write_packet(unsigned char *buffer);
#ifdef GDB_DEBUG_PRINT
#define gdb_debug(...) printf(__VA_ARGS__)
#else
#define gdb_debug(...)
#endif
#include <crt0.h>
int _crt0_startup_flags = _CRT0_FLAG_LOCK_MEMORY;
#define UART_LINE_CONTROL 3
#define UART_LCR_DIVISOR_LATCH 0x80
#define UART_DIVISOR_LATCH_WORD 0
#define UART_BPS_DIVISOR_115200 1
#define IO_BUFFER_SIZE 1024 * 1024
// clang-format off
enum gdb_register { EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, EIP, EFLAGS, CS, SS, DS, ES, FS, GS, NUM_REGISTERS };
static char *register_names[] = {"EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI", "EIP", "EFLAGS", "CS", "SS", "DS", "ES", "FS", "GS"};
static char hex_chars[] = "0123456789abcdef";
// clang-format on
typedef struct gdb_context {
int registers[NUM_REGISTERS];
char input_buffer[IO_BUFFER_SIZE];
char output_buffer[IO_BUFFER_SIZE];
int mem_error;
void (*mem_error_callback)();
int no_ack_mode;
int was_interrupted;
_go32_dpmi_seginfo old_tick_handler;
_go32_dpmi_seginfo tick_handler;
} gdb_context;
gdb_context ctx = {0};
static int handler_mutex;
static void serial_port_init() {
_bios_serialcom(_COM_INIT, 0,
(char) (_COM_9600 | _COM_NOPARITY | _COM_STOP1 | _COM_CHR8));
unsigned int base = _farpeekw(0x0040, 0);
outp(base + UART_LINE_CONTROL,
inp(base + UART_LINE_CONTROL) | UART_LCR_DIVISOR_LATCH);
outpw(base + UART_DIVISOR_LATCH_WORD, UART_BPS_DIVISOR_115200);
outp(base + UART_LINE_CONTROL,
inp(base + UART_LINE_CONTROL) & ~UART_LCR_DIVISOR_LATCH);
}
static void serial_port_putc(char c) { _bios_serialcom(_COM_SEND, 0, c); }
static int serial_port_getc() {
return _bios_serialcom(_COM_RECEIVE, 0, 0) & 0xff;
}
static void set_mem_error(void) { ctx.mem_error = 1; }
static int hex_to_byte(char ch) {
if ((ch >= 'a') && (ch <= 'f'))
return (ch - 'a' + 10);
if ((ch >= '0') && (ch <= '9'))
return (ch - '0');
if ((ch >= 'A') && (ch <= 'F'))
return (ch - 'A' + 10);
return (-1);
}
static int hex_to_int(char **ptr, int *intValue) {
int numChars = 0;
*intValue = 0;
while (**ptr) {
int hexValue = hex_to_byte(**ptr);
if (hexValue >= 0) {
*intValue = (*intValue << 4) | hexValue;
numChars++;
} else
break;
(*ptr)++;
}
return (numChars);
}
static int mem_get_byte(char *addr) { return *addr; }
static void mem_set_byte(char *addr, int val) { *addr = val; }
static char *mem_to_hex(char *mem, char *buf, int count, int may_fault) {
if (may_fault)
ctx.mem_error_callback = set_mem_error;
for (int i = 0; i < count; i++) {
unsigned char ch = mem_get_byte(mem++);
gdb_debug("%x ", ch);
if (may_fault && ctx.mem_error)
return (buf);
*buf++ = hex_chars[ch >> 4];
*buf++ = hex_chars[ch % 16];
}
*buf = 0;
if (may_fault)
ctx.mem_error_callback = NULL;
return (buf);
}
static char *hex_to_mem(char *buf, char *mem, int count, int may_fault) {
if (may_fault)
ctx.mem_error_callback = set_mem_error;
for (int i = 0; i < count; i++) {
unsigned char ch = hex_to_byte(*buf++) << 4;
ch = ch + hex_to_byte(*buf++);
gdb_debug("%x ", ch);
mem_set_byte(mem++, ch);
if (may_fault && ctx.mem_error)
return (mem);
}
if (may_fault)
ctx.mem_error_callback = NULL;
return (mem);
}
static void exception_save_registers(void) {
ctx.registers[EAX] = (int) __djgpp_exception_state->__eax;
ctx.registers[ECX] = (int) __djgpp_exception_state->__ecx;
ctx.registers[EDX] = (int) __djgpp_exception_state->__edx;
ctx.registers[EBX] = (int) __djgpp_exception_state->__ebx;
ctx.registers[ESP] = (int) __djgpp_exception_state->__esp;
ctx.registers[EBP] = (int) __djgpp_exception_state->__ebp;
ctx.registers[ESI] = (int) __djgpp_exception_state->__esi;
ctx.registers[EDI] = (int) __djgpp_exception_state->__edi;
ctx.registers[EIP] = (int) __djgpp_exception_state->__eip;
ctx.registers[EFLAGS] = (int) __djgpp_exception_state->__eflags;
ctx.registers[CS] = (int) __djgpp_exception_state->__cs;
ctx.registers[SS] = (int) __djgpp_exception_state->__ss;
ctx.registers[DS] = (int) __djgpp_exception_state->__ds;
ctx.registers[ES] = (int) __djgpp_exception_state->__es;
ctx.registers[FS] = (int) __djgpp_exception_state->__fs;
ctx.registers[GS] = (int) __djgpp_exception_state->__gs;
}
extern void exception_return();
asm(".text");
asm(".globl _exception_return");
asm("_exception_return:");
asm(" movw _ctx+44, %ss");
asm(" movl _ctx+16, %esp");
asm(" movl _ctx+4, %ecx");
asm(" movl _ctx+8, %edx");
asm(" movl _ctx+12, %ebx");
asm(" movl _ctx+20, %ebp");
asm(" movl _ctx+24, %esi");
asm(" movl _ctx+28, %edi");
asm(" movw _ctx+48, %ds");
asm(" movw _ctx+52, %es");
asm(" movw _ctx+56, %fs");
asm(" movw _ctx+60, %gs");
asm(" movl _ctx+36, %eax");
asm(" pushl %eax");
asm(" movl _ctx+40, %eax");
asm(" pushl %eax");
asm(" movl _ctx+32, %eax");
asm(" pushl %eax");
asm(" movl _ctx, %eax");
asm(" iret");
static void exception_sigsegv_handler(int exception_number) {
exception_save_registers();
gdb_loop(exception_number);
exception_return();
}
static void exception_handler(int exception_number) {
exception_save_registers();
gdb_loop(exception_number);
exception_return();
}
static int exception_to_signal(int exception_number) {
int signal_number;
switch (exception_number) {
case 0:
signal_number = 8;
break; /* divide by zero */
case 1:
signal_number = 5;
break; /* debug exception */
case 302:
case 3:
signal_number = 5;
break; /* breakpoint */
case 4:
signal_number = 16;
break; /* into instruction (overflow) */
case 5:
signal_number = 16;
break; /* bound instruction */
case 6:
signal_number = 4;
break; /* Invalid opcode */
case 7:
signal_number = 8;
break; /* coprocessor not available */
case 8:
signal_number = 7;
break; /* double fault */
case 9:
signal_number = 11;
break; /* coprocessor segment overrun */
case 10:
signal_number = 11;
break; /* Invalid TSS */
case 11:
signal_number = 11;
break; /* Segment not present */
case 12:
signal_number = 11;
break; /* stack exception */
case 13:
signal_number = 11;
break; /* general protection */
case 14:
signal_number = 11;
break; /* page fault */
case 16:
signal_number = 7;
break; /* coprocessor error */
default:
signal_number = 7; /* "software generated"*/
}
return (signal_number);
}
static void exception_init() {
_go32_dpmi_lock_data(register_names, sizeof(register_names));
for (int i = 0; i < NUM_REGISTERS; i++)
_go32_dpmi_lock_data(register_names[0], 3);
_go32_dpmi_lock_data(hex_chars, sizeof(hex_chars));
_go32_dpmi_lock_data(&ctx, sizeof(ctx));
_go32_dpmi_lock_data(&handler_mutex, sizeof(handler_mutex));
_go32_dpmi_lock_code(serial_port_init, 4096);
_go32_dpmi_lock_code(serial_port_putc, 4096);
_go32_dpmi_lock_code(serial_port_getc, 4096);
_go32_dpmi_lock_code(set_mem_error, 4096);
_go32_dpmi_lock_code(hex_to_byte, 4096);
_go32_dpmi_lock_code(hex_to_int, 4096);
_go32_dpmi_lock_code(mem_get_byte, 4096);
_go32_dpmi_lock_code(mem_set_byte, 4096);
_go32_dpmi_lock_code(mem_to_hex, 4096);
_go32_dpmi_lock_code(hex_to_mem, 4096);
_go32_dpmi_lock_code(exception_save_registers, 4096);
_go32_dpmi_lock_code(exception_return, 4096);
_go32_dpmi_lock_code(exception_sigsegv_handler, 4096);
_go32_dpmi_lock_code(exception_handler, 4096);
_go32_dpmi_lock_code(exception_to_signal, 4096);
_go32_dpmi_lock_code(_gdb_start, 4096);
_go32_dpmi_lock_code(gdb_read_packet, 4096);
_go32_dpmi_lock_code(gdb_write_packet, 4096);
_go32_dpmi_lock_code(gdb_loop, 4096);
_go32_dpmi_lock_code(_gdb_checkpoint, 4096);
signal(SIGSEGV, exception_sigsegv_handler);
signal(SIGFPE, exception_handler);
signal(SIGTRAP, exception_handler);
signal(SIGILL, exception_handler);
_go32_dpmi_get_protected_mode_interrupt_vector(0x1c, &ctx.old_tick_handler);
ctx.tick_handler.pm_offset = (int) gdb_tick_handler;
ctx.tick_handler.pm_selector = _go32_my_cs();
_go32_dpmi_allocate_iret_wrapper(&ctx.tick_handler);
_go32_dpmi_set_protected_mode_interrupt_vector(0x1c, &ctx.tick_handler);
}
static void exception_dispose() {
signal(SIGSEGV, SIG_DFL);
signal(SIGFPE, SIG_DFL);
signal(SIGTRAP, SIG_DFL);
signal(SIGILL, SIG_DFL);
_go32_dpmi_set_protected_mode_interrupt_vector(0x1c, &ctx.old_tick_handler);
}
void _gdb_start(void) {
((void) register_names[0]);
serial_port_init();
exception_init();
atexit(exception_dispose);
}
static unsigned char *gdb_read_packet() {
register unsigned char *buffer = (unsigned char *) ctx.input_buffer;
register unsigned char checksum;
register unsigned char xmitcsum;
register int count;
register char ch;
while (1) {
while ((ch = serial_port_getc()) != '$')
;
retry:
checksum = 0;
xmitcsum = -1;
count = 0;
while (count < IO_BUFFER_SIZE) {
ch = serial_port_getc();
if (ch == '$') {
gdb_debug("Retrying\n");
goto retry;
}
if (ch == '#') {
gdb_debug("Found end of packet\n");
break;
}
checksum = checksum + ch;
buffer[count] = ch;
count = count + 1;
}
buffer[count] = 0;
if (ch == '#') {
ch = serial_port_getc();
xmitcsum = hex_to_byte(ch) << 4;
ch = serial_port_getc();
xmitcsum += hex_to_byte(ch);
if (checksum != xmitcsum) {
if (!ctx.no_ack_mode)
serial_port_putc('-');
} else {
if (!ctx.no_ack_mode)
serial_port_putc('+');
if (buffer[2] == ':') {
serial_port_putc(buffer[0]);
serial_port_putc(buffer[1]);
return &buffer[3];
}
return &buffer[0];
}
}
}
}
static void gdb_write_packet(unsigned char *buffer) {
unsigned char checksum;
int count;
char ch;
do {
serial_port_putc('$');
checksum = 0;
count = 0;
while ((ch = buffer[count])) {
serial_port_putc(ch);
checksum += ch;
count += 1;
}
serial_port_putc('#');
serial_port_putc(hex_chars[checksum >> 4]);
serial_port_putc(hex_chars[checksum % 16]);
if (ctx.no_ack_mode)
break;
} while (serial_port_getc() != '+');
}
void gdb_loop(int exception_number) {
if (handler_mutex)
return;
handler_mutex = 1;
int stepping, addr, length;
char *ptr;
/* reply to host that an exception has occurred */
int sigval = exception_to_signal(exception_number);
gdb_debug("\n=== STOPPED: sig: %i, evec: %i, ip %p, [ip] %x\n", sigval,
exception_number, (void *) ctx.registers[EIP],
*(unsigned char *) ctx.registers[EIP]);
for (int l = 0; l < NUM_REGISTERS; l++)
gdb_debug("%s: %x ", register_names[l], ctx.registers[l]);
gdb_debug("\n");
ctx.output_buffer[0] = 'S';
ctx.output_buffer[1] = hex_chars[sigval >> 4];
ctx.output_buffer[2] = hex_chars[sigval % 16];
ctx.output_buffer[3] = 0;
gdb_write_packet((unsigned char *) ctx.output_buffer);
stepping = 0;
while (1 == 1) {
ctx.output_buffer[0] = 0;
ptr = (char *) gdb_read_packet();
char cmd = *ptr++;
switch (cmd) {
case '?':
gdb_debug("? (Query the reason the target halted on connect)\n");
ctx.output_buffer[0] = 'S';
ctx.output_buffer[1] = hex_chars[sigval >> 4];
ctx.output_buffer[2] = hex_chars[sigval % 16];
ctx.output_buffer[3] = 0;
break;
case 'D':
gdb_debug("D (Detach)\n");
exit(0);
break;
case 'H':
gdb_debug("H (Set thread for subsequent operations)\n");
strcpy(ctx.output_buffer, "OK");
break;
case 'q':
if (!strcmp(ptr, "C")) {
gdb_debug("qC (Return the current thread ID.)\n");
ctx.output_buffer[0] = 'Q';
ctx.output_buffer[1] = 'C';
ctx.output_buffer[2] = '0';
ctx.output_buffer[3] = 0;
} else if (!strcmp(ptr, "Attached")) {
gdb_debug("qAttached (Check if attached to existing or new process)\n");
ctx.output_buffer[0] = '1';
ctx.output_buffer[1] = 0;
} else if (!strcmp(ptr, "fThreadInfo")) {
gdb_debug("qfThreadInfo (Obtain a list of all active thread IDs)\n");
ctx.output_buffer[0] = 'm';
ctx.output_buffer[1] = '0';
ctx.output_buffer[2] = 0;
} else if (!strcmp(ptr, "sThreadInfo")) {
gdb_debug("qsThreadInfo (Obtain a list of all active thread IDs, "
"subsequent)\n");
ctx.output_buffer[0] = 'l';
ctx.output_buffer[1] = 0;
} else if (!strcmp(ptr, "Symbol::")) {
gdb_debug("Symbol:: (Notify the target that GDB is prepared to serve "
"symbol lookup requests)\n");
strcpy(ctx.output_buffer, "OK");
} else if (!strcmp(ptr, "Supported")) {
gdb_debug("qSupported");
strcpy(ctx.output_buffer, "QStartNoAckMode+;PacketSize=1048576;");
} else if (!strcmp(ptr, "Offsets")) {
gdb_debug("qOffsets");
strcpy(ctx.output_buffer, "Text=0;Data=0;Bss=0;");
} else {
gdb_debug("Unhandled: %c%s\n", cmd, ptr);
}
break;
case 'Q':
if (!strcmp(ptr, "StartNoAckMode")) {
gdb_debug("QStartNoAckMode");
strcpy(ctx.output_buffer, "OK");
ctx.no_ack_mode = 1;
} else {
gdb_debug("Unhandled: %c%s\n", cmd, ptr);
}
break;
case 'd':
gdb_debug("d (Toggle debug flag)\n");
break;
case 'g':
gdb_debug("g (Read general registers)\n");
for (int l = 0; l < NUM_REGISTERS; l++)
gdb_debug("%s: %x "
"",
register_names[l], ctx.registers[l]);
gdb_debug("\n");
mem_to_hex((char *) ctx.registers, ctx.output_buffer, NUM_REGISTERS * 4,
0);
break;
case 'G':
gdb_debug("G (Write general registers)\n");
hex_to_mem(ptr, (char *) ctx.registers, NUM_REGISTERS * 4, 0);
strcpy(ctx.output_buffer, "OK");
break;
case 'P': {
gdb_debug("P (Write register n with value r)\n");
int register_number;
if (hex_to_int(&ptr, ®ister_number) && *ptr++ == '=')
if (register_number >= 0 && register_number < NUM_REGISTERS) {
gdb_debug("set reg: %i, ", register_number);
hex_to_mem(ptr, (char *) &ctx.registers[register_number], 4, 0);
gdb_debug("\n");
strcpy(ctx.output_buffer, "OK");
break;
}
strcpy(ctx.output_buffer, "E01");
break;
}
case 'm':
gdb_debug("m (Read length addressable memory units starting at address "
"addr)\n");
if (hex_to_int(&ptr, &addr)) {
gdb_debug("read, addr: %p, ", (void *) addr);
if (*(ptr++) == ',') {
if (hex_to_int(&ptr, &length)) {
ptr = 0;
ctx.mem_error = 0;
mem_to_hex((char *) addr, ctx.output_buffer, length, 1);
if (ctx.mem_error) {
strcpy(ctx.output_buffer, "E03");
}
}
}
}
gdb_debug("\n");
if (ptr) {
strcpy(ctx.output_buffer, "E01");
}
break;
case 'M':
gdb_debug("M (Write length addressable memory units starting at address "
"addr)\n");
if (hex_to_int(&ptr, &addr)) {
gdb_debug("write, addr: %p, ", (void *) addr);
if (*(ptr++) == ',') {
if (hex_to_int(&ptr, &length))
if (*(ptr++) == ':') {
ctx.mem_error = 0;
hex_to_mem(ptr, (char *) addr, length, 1);
if (ctx.mem_error) {
strcpy(ctx.output_buffer, "E03");
} else {
strcpy(ctx.output_buffer, "OK");
}
ptr = 0;
}
}
gdb_debug("\n");
}
if (ptr) {
strcpy(ctx.output_buffer, "E02");
}
break;
case 's':
stepping = 1;
case 'c': {
addr = 0;
if (hex_to_int(&ptr, &addr)) {
ctx.registers[EIP] = addr;
}
gdb_debug("%c, offset: %p, ip: %p (%s)\n", cmd, (void *) addr,
(void *) ctx.registers[EIP], cmd == 'c' ? "Continue" : "Step");
ctx.registers[EFLAGS] &= 0xfffffeff;
if (stepping)
ctx.registers[EFLAGS] |= 0x100;
handler_mutex = 0;
return;
}
case 'k':
break;
default:
gdb_debug("Unhandled: %c%s\n", cmd, ptr);
}
gdb_write_packet((unsigned char *) ctx.output_buffer);
}
handler_mutex = 0;
return;
}
void gdb_tick_handler(void) {
int status = _bios_serialcom(_COM_STATUS, 0, 0);
if (status & (1 << 8) && !handler_mutex) {
ctx.was_interrupted = 1;
}
}
bool _gdb_checkpoint() {
if (ctx.was_interrupted) {
ctx.was_interrupted = 0;
return true;
}
return false;
}
#endif
#endif
================================================
FILE: src/main.c
================================================
#include <bios.h>
#include <dpmi.h>
#include <sys/nearptr.h>
#include <stdlib.h>
#include <stdio.h>
#define GDB_IMPLEMENTATION
#include "gdbstub.h"
void set_video_mode(int mode) {
__dpmi_regs regs = {0};
regs.x.ax = mode;
__dpmi_int(0x10, ®s);
}
int main(void) {
gdb_start();
// Go mode 0x13!
set_video_mode(0x13);
// Draw 200 pixels each iteration until a key is pressed
while (!kbhit()) {
__djgpp_nearptr_enable();
unsigned char *vram = (unsigned char *) (__djgpp_conventional_base + 0xa0000);
for (int i = 0; i < 200; i++) {
int x = rand() % 320;
int y = rand() % 200;
int color = rand() % 255;
vram[x + y * 320] = color;
}
__djgpp_nearptr_disable();
// Set a GDB checkpoint, needed to receive interrupt commands
// from the debugger. You should do this in all your game loops.
gdb_checkpoint();
}
// Return to text mode
set_video_mode(0x3);
// Read an asset file and print its content
FILE *file = fopen("assets/test.txt", "r");
fseek(file, 0, SEEK_END);
long int num_bytes = ftell(file);
fseek(file, 0, SEEK_SET);
unsigned char *file_content = (unsigned char *) malloc(num_bytes + 1);
fread(file_content, 1, num_bytes, file);
file_content[num_bytes] = 0;
printf("%s\n", file_content);
return 0;
}
================================================
FILE: tools/dosbox-x.conf
================================================
# This is the configuration file for DOSBox-X 2022.09.0. (Please use the latest version of DOSBox-X)
# Lines starting with a # are comment lines and are ignored by DOSBox-X.
# They are used to (briefly) document the effect of each option.
# To write out ALL options, use command 'config -all' with -wc or -writeconf options.
[sdl]
# fullscreen: Start DOSBox-X directly in fullscreen. (Press [F11/F12]+F to go back)
# fulldouble: Use double buffering in fullscreen. It can reduce screen flickering, but it can also result in a slow DOSBox-X.
# fullresolution: What resolution to use for fullscreen: original, desktop or a fixed size (e.g. 1024x768).
# Using your monitor's native resolution with aspect=true might give the best results.
# If you end up with small window on a large screen, try an output different from surface.
# windowresolution: Scale the window to this size IF the output device supports hardware scaling.
# (output=surface does not!)
# windowposition: Set the window position at startup in the positionX,positionY format (e.g.: 1300,200).
# The window will be centered with "," (or empty), and will be in the original position with "-".
# display: Specify a screen/display number to use for a multi-screen setup (0 = default).
# output: What video system to use for output (openglnb = OpenGL nearest; openglpp = OpenGL perfect; ttf = TrueType font output).
# Possible values: default, surface, overlay, ttf, opengl, openglnb, openglhq, openglpp, ddraw, direct3d.
# videodriver: Forces a video driver (e.g. windib/windows, directx, x11, fbcon, dummy, etc) for the SDL library to use.
# transparency: Set the transparency of the DOSBox-X screen (both windowed and full-screen modes, on SDL2 and Windows SDL1 builds).
# The valid value is from 0 (no transparency, the default setting) to 90 (high transparency).
# maximize: If set, the DOSBox-X window will be maximized at start (SDL2 and Windows SDL1 builds only; use fullscreen for TTF output).
# autolock: Mouse will automatically lock, if you click on the screen. (Press CTRL-F10 to unlock)
# autolock_feedback: Autolock status feedback type, i.e. visual, auditive, none.
# Possible values: none, beep, flash.
# middle_unlock: Whether you can press the middle mouse button to unlock the mouse when the mouse has been locked.
# If set to "manual", it works only with "autolock=false"; if set to "auto", it works only with "autolock=true".
# Possible values: none, manual, auto, both.
# clip_mouse_button: Select the mouse button or use arrow keys for the shared clipboard copy/paste function.
# The default mouse button is "right", which means using the right mouse button to select text, copy to and paste from the host clipboard.
# Set to "middle" to use the middle mouse button, "arrows" to use arrow keys instead of a mouse button, or "none" to disable this feature.
# For "arrows", press Home key (or Fn+Shift+Left on Mac laptops) to start selection, and End key (or Fn+Shift+Right on Mac laptops) to end selection.
# Possible values: none, middle, right, arrows.
# clip_key_modifier: Change the keyboard modifier for the shared clipboard copy/paste function using a mouse button or arrow keys.
# The default modifier is "shift" (both left and right shift keys). Set to "none" if no modifier is desired.
# Possible values: none, ctrl, lctrl, rctrl, alt, lalt, ralt, shift, lshift, rshift, ctrlalt, ctrlshift, altshift, lctrlalt, lctrlshift, laltshift, rctrlalt, rctrlshift, raltshift.
# clip_paste_bios: Specify whether to use BIOS keyboard functions for the clipboard pasting instead of the keystroke method.
# For pasting clipboard text into Windows 3.x/9x applications (e.g. Notepad), make sure to use the keystroke method.
# Possible values: true, false, 1, 0, default.
# clip_paste_speed: Set keyboard speed for pasting text from the shared clipboard.
# If the default setting of 30 causes lost keystrokes, increase the number.
# Or experiment with decreasing the number for applications that accept keystrokes quickly.
# sensitivity: Mouse sensitivity. The optional second parameter specifies vertical sensitivity (e.g. 100,-50).
# usesystemcursor: Use the mouse cursor of the host system instead of drawing a DOS mouse cursor. Activated when the mouse is not locked.
# mouse_emulation: When is mouse emulated ?
# integration: when not locked
# locked: when locked
# always: every time
# never: at no time
# If disabled, the mouse position in DOSBox-X is exactly where the host OS reports it.
# When using a high DPI mouse, the emulation of mouse movement can noticeably reduce the
# sensitiveness of your device, i.e. the mouse is slower but more precise.
# Possible values: integration, locked, always, never.
# mouse_wheel_key: Convert mouse wheel movements into keyboard presses such as arrow keys.
# 0: disabled; 1: up/down arrows; 2: left/right arrows; 3: PgUp/PgDn keys.
# 4: Ctrl+up/down arrows; 5: Ctrl+left/right arrows; 6: Ctrl+PgUp/PgDn keys.
# 7: Ctrl+W/Z, as supported by text editors like WordStar and MS-DOS EDIT.
# Putting a minus sign in front will disable the conversion for guest systems.
# waitonerror: Wait before closing the console if DOSBox-X has an error.
# priority: Priority levels for DOSBox-X. Second entry behind the comma is for when DOSBox-X is not focused/minimized.
# pause is only valid for the second entry.
# Possible values: lowest, lower, normal, higher, highest, pause.
# mapperfile: File used to load/save the key/event mappings from. Resetmapper only works with the default value.
# usescancodes: Avoid usage of symkeys, in favor of scancodes. Might not work on all operating systems.
# If set to "auto" (default), it is enabled when using non-US keyboards in SDL1 builds.
# Possible values: true, false, 1, 0, auto.
# overscan: Width of the overscan border (0 to 10) for the "surface" output.
# titlebar: Change the string displayed in the DOSBox-X title bar.
# showbasic: If set, DOSBox-X will show basic information including the DOSBox-X version number and current running speed in the title bar.
# showdetails: If set, DOSBox-X will show the cycles count (FPS) and emulation speed relative to realtime in the title bar.
# showmenu: Whether to show the menu bar (if supported). Default true.
#
# Advanced options (see full configuration reference file [dosbox-x.reference.full.conf] for more details):
# -> mapperfile_sdl1; mapperfile_sdl2; forcesquarecorner
#
fullscreen = false
fulldouble = false
fullresolution = desktop
windowresolution = original
windowposition = -
display = 0
output = default
videodriver =
transparency = 0
maximize = false
autolock = false
autolock_feedback = beep
middle_unlock = manual
clip_mouse_button = right
clip_key_modifier = shift
clip_paste_bios = default
clip_paste_speed = 30
sensitivity = 100
usesystemcursor = false
mouse_emulation = locked
mouse_wheel_key = -1
waitonerror = true
priority = higher,normal
mapperfile = mapper-dosbox-x.map
usescancodes = auto
overscan = 0
titlebar =
showbasic = true
showdetails = false
showmenu = true
[log]
# logfile: file where the log messages will be saved to
# debuggerrun: The run mode when the DOSBox-X Debugger starts.
# Possible values: debugger, normal, watch.
#
# Advanced options (see full configuration reference file [dosbox-x.reference.full.conf] for more details):
# -> vga; vgagfx; vgamisc; int10; sblaster; dma_control; fpu; cpu; paging; fcb; files; ioctl; exec; dosmisc; pit; keyboard; pic; mouse; bios; gui; misc; io; pci; sst; int21; fileio
#
logfile =
debuggerrun = debugger
[dosbox]
# language: Select a language file for DOSBox-X to use. Encoded with either UTF-8 or a DOS code page.
# You can set code page either in the language file or with "country" setting in [config] section.
# title: Additional text to place in the title bar of the window.
# fastbioslogo: If set, DOSBox-X will skip the BIOS screen by activating fast BIOS logo mode (without 1-second pause).
# startbanner: If set (default), DOSBox-X will display the welcome banner when it starts.
# bannercolortheme: You can specify a different background color theme for the welcome banner from the default one.
# Possible values: default, black, red, green, yellow, blue, magenta, cyan, white.
# dpi aware: Set this option (auto by default) to indicate to your OS that DOSBox-X is DPI aware.
# If it is not set, Windows Vista/7/8/10 and higher may upscale the DOSBox-X window
# on higher resolution monitors which is probably not what you want.
# Possible values: true, false, 1, 0, auto.
# quit warning: Set this option to indicate whether DOSBox-X should show a warning message when the user tries to close its window.
# If set to auto (default), DOSBox-X will warn if a DOS program, game or a guest system is currently running.
# If set to autofile, DOSBox-X will warn if there are open file handles or a guest system is currently running.
# Possible values: true, false, 1, 0, auto, autofile.
# working directory option: Select an option for DOSBox-X's working directory when it runs.
# autoprompt: DOSBox-X will auto-decide whether to prompt for a working directory.
# config: DOSBox-X will use the primary config file directory as the working directory.
# custom: Specify a working directory via the "working directory default" option.
# default: Similar to autoprompt, but DOSBox-X will ask whether to save the selected folder.
# force: Similar to "custom", while overriding -defaultdir command-line option if used.
# noprompt: DOSBox-X uses the current directory and never prompts for a working directory.
# program: DOSBox-X will use the DOSBox-X program directory as the working directory.
# prompt: DOSBox-X will always ask the user to select a working directory when it runs.
# userconfig: DOSBox-X will use its user configuration directory as the working directory.
# Possible values: autoprompt, config, custom, default, force, noprompt, program, prompt, userconfig.
# working directory default: The default directory to act as DOSBox-X's working directory. See also the setting "working directory option".
# For working directory option=prompt, the specified directory becomes the default directory for the folder selection.
# show advanced options: If set, the Configuration Tool will display all config options (including advanced ones) by default.
# resolve config path: If set to true, DOSBox-X will resolve options containing paths in the config file (except [autoexec] section).
# This includes environment variables (%VAR% [DOS/Windows] or ${VAR} [Linux/macOS] and tilde (~) in Linux/macOS.
# If set to dosvar, DOSBox-X forces to resolve DOS-style environment variables (%VAR%) in all platforms (and tilde).
# If set to tilde, DOSBox-X will only resolve tilde (~) in Linux/macOS but will not resolve environment variables.
# Possible values: true, false, dosvar, tilde, 1, 0.
# hostkey: By default, DOSBox-X uses the mapper-defined host key, which defaults to F11 on Windows and F12 on other platforms.
# You may alternatively specify a host key with this setting and bypass the host key as defined in the mapper.
# This can also be done from the menu ("Main" => "Select host key").
# Possible values: ctrlalt, ctrlshift, altshift, mapper.
# mapper send key: Select the key the mapper SendKey function will send.
# Possible values: winlogo, winmenu, alttab, ctrlesc, ctrlbreak, ctrlaltdel.
# ime: Enables support for the system input methods (IME) for inputting characters in Windows and Linux builds.
# If set to auto, this feature is only enabled if DOSBox-X starts with a Chinese/Japanese/Korean code page.
# Possible values: true, false, 1, 0, auto.
# synchronize time: If set, DOSBox-X will try to automatically synchronize time with the host, unless you decide to change the date/time manually.
# machine: The type of machine DOSBox-X tries to emulate.
# Possible values: mda, cga, cga_mono, cga_rgb, cga_composite, cga_composite2, hercules, tandy, pcjr, pcjr_composite, pcjr_composite2, amstrad, ega, ega200, jega, mcga, vgaonly, svga_s3, svga_s386c928, svga_s3vision864, svga_s3vision868, svga_s3vision964, svga_s3vision968, svga_s3trio32, svga_s3trio64, svga_s3trio64v+, svga_s3virge, svga_s3virgevx, svga_et3000, svga_et4000, svga_paradise, vesa_nolfb, vesa_oldvbe, vesa_oldvbe10, pc98, pc9801, pc9821, fm_towns.
# captures: Directory where things like wave, midi, screenshot get captured.
# autosave: Enable the auto-save state feature. Specify a time interval in seconds, and optionally a save slot or start and end save slots.
# For example, "autosave=10 11-20" will set a 10-second time interval for auto-saving, and the save slots used will be between 11 and 20.
# You can additionally specify up to 9 programs for this feature, e.g. "autosave=10 11-20 EDIT:21-30 EDITOR:35" for "EDIT" and "EDITOR".
# Putting a minus sign (-) before the time interval causes the auto-saving function to not be activated at start.
# saveslot: Select the default save slot (1-100) to save/load states.
# savefile: Select the default save file to save/load states. If specified it will be used instead of the save slot.
# saveremark: If set, the save state feature will ask users to enter remarks when saving a state.
# forceloadstate: If set, DOSBox-X will load a saved state even if it finds there is a mismatch in the DOSBox-X version, machine type, program name and/or the memory size.
# a20: A20 gate emulation mode.
# The on/off/on_fake/off_fake options are intended for testing and debugging DOS development,
# or to emulate obscure hardware, or to work around potential extended memory problems with DOS programs.
# on_fake/off_fake are intended to test whether a program carries out a memory test to ensure the A20
# gate is set as intended (as HIMEM.SYS does). If it goes by the gate bit alone, it WILL crash.
# This parameter is also changeable from the builtin A20GATE command.
# fast Emulate A20 gating by remapping the first 64KB @ 1MB boundary (fast, mainline DOSBox behavior)
# mask Emulate A20 gating by masking memory I/O address (accurate)
# off Lock A20 gate off (Software/OS cannot enable A20)
# on Lock A20 gate on (Software/OS cannot disable A20)
# off_fake Lock A20 gate off but allow bit to toggle (hope your DOS game tests the HMA!)
# on_fake Lock A20 gate on but allow bit to toggle
# memsize: Amount of memory DOSBox-X has in megabytes.
# This value is best left at its default to avoid problems with some games,
# although other games and applications may require a higher value.
# Programs that use 286 protected mode like Windows 3.0 in Standard Mode may crash with more than 15MB.
# nocachedir: If set, MOUNT commands will mount with -nocachedir (disable directory caching) by default.
# freesizecap: If set to "cap" (="true"), the value of MOUNT -freesize will apply only if the actual free size is greater than the specified value.
# If set to "relative", the value of MOUNT -freesize will change relative to the specified value.
# If set to "fixed" (="false"), the value of MOUNT -freesize will be a fixed one to be reported all the time.
# Possible values: true, false, fixed, relative, cap, 2, 1, 0.
# convertdrivefat: If set, DOSBox-X will auto-convert mounted non-FAT drives (such as local drives) to FAT format for use with guest systems.
#
# Advanced options (see full configuration reference file [dosbox-x.reference.full.conf] for more details):
# -> disable graphical splash; allow quit after warning; keyboard hook; weitek; bochs debug port e9; compresssaveparts; show recorded filename; skip encoding unchanged frames; capture chroma format; capture format; shell environment size; private area size; turn off a20 gate on boot; cbus bus clock; isa bus clock; pci bus clock; call binary on reset; unhandled irq handler; call binary on boot; ibm rom basic; rom bios allocation max; rom bios minimum size; irq delay ns; iodelay; iodelay16; iodelay32; acpi; acpi rsd ptr location; acpi sci irq; acpi iobase; acpi reserved size; memsizekb; dos mem limit; isa memory hole at 512kb; reboot delay; memalias; convert fat free space; convert fat timeout; leading colon write protect image; locking disk image mount; unmask keyboard on int 16 read; int16 keyboard polling undocumented cf behavior; allow port 92 reset; enable port 92; enable 1st dma controller; enable 2nd dma controller; allow dma address decrement; enable 128k capable 16-bit dma; enable dma extra page registers; dma page registers write-only; cascade interrupt never in service; cascade interrupt ignore in service; enable slave pic; enable pc nmi mask; allow more than 640kb base memory; enable pci bus
#
language =
title =
fastbioslogo = true
startbanner = true
bannercolortheme = default
dpi aware = auto
quit warning = false
working directory option = default
working directory default =
show advanced options = false
resolve config path = true
hostkey = mapper
mapper send key = ctrlaltdel
ime = auto
synchronize time = false
machine = svga_s3
captures = capture
autosave =
saveslot = 1
savefile =
saveremark = true
forceloadstate = false
a20 = mask
memsize = 16
nocachedir = false
freesizecap = cap
convertdrivefat = true
[render]
# frameskip: How many frames DOSBox-X skips before drawing one.
# aspect: Aspect ratio correction mode. Can be set to the following values:
# 'false' (default):
# 'direct3d'/opengl outputs: image is simply scaled to full window/fullscreen size, possibly resulting in disproportional image
# 'surface' output: it does no aspect ratio correction (default), resulting in disproportional images if VGA mode pixel ratio is not 4:3
# 'true':
# 'direct3d'/opengl outputs: uses output driver functions to scale / pad image with black bars, correcting output to proportional 4:3 image
# In most cases image degradation should not be noticeable (it all depends on the video adapter and how much the image is upscaled).
# Should have none to negligible impact on performance, mostly being done in hardware
# For the pixel-perfect scaling (output=openglpp), it is recommended to enable this whenever the emulated display has an aspect ratio of 4:3
# 'surface' output: inherits old DOSBox aspect ratio correction method (adjusting rendered image line count to correct output to 4:3 ratio)
# Due to source image manipulation this mode does not mix well with scalers, i.e. multiline scalers like hq2x/hq3x will work poorly
# Slightly degrades visual image quality. Has a tiny impact on performance
# When using xBRZ scaler with 'surface' output, aspect ratio correction is done by the scaler itself, so none of the above apply
# Possible values: false, true, 0, 1, yes, no, nearest, bilinear.
# aspect_ratio: Set the aspect ratio (e.g. 16:9) in the aspect ratio correction mode. 0:0 means the default ratio of 4:3, and -1:-1 means the original image ratio.
# char9: Allow 9-pixel wide text mode fonts instead of 8-pixel wide fonts.
# euro: Display Euro symbol instead of the specified ASCII character (33-255).
# For example, setting it to 128 allows Euro symbol to be displayed instead of C-cedilla.
# doublescan: If set, doublescanned output emits two scanlines for each source line, in the
# same manner as the actual VGA output (320x200 is rendered as 640x400 for example).
# If clear, doublescanned output is rendered at the native source resolution (320x200 as 320x200).
# This affects the raster PRIOR to the software or hardware scalers. Choose wisely.
# For pixel-perfect scaling (output=openglpp), it is recommended to turn this option off.
# scaler: Scaler used to enlarge/enhance low resolution modes. If 'forced' is appended,
# then the scaler will be used even if the result might not be desired.
# Appending 'prompt' will cause a confirmation message for forcing the scaler.
# To fit a scaler in the resolution used at full screen may require a border or side bars.
# To fill the screen entirely, depending on your hardware, a different scaler/fullresolution might work.
# Scalers should work with most output options, but they are ignored for openglpp and TrueType font outputs.
# Possible values: none, normal2x, normal3x, normal4x, normal5x, advmame2x, advmame3x, advinterp2x, advinterp3x, hq2x, hq3x, 2xsai, super2xsai, supereagle, tv2x, tv3x, rgb2x, rgb3x, scan2x, scan3x, gray, gray2x, hardware_none, hardware2x, hardware3x, hardware4x, hardware5x, xbrz, xbrz_bilinear.
# glshader: Path to GLSL shader source to use with OpenGL output ("none" to disable, or "default" for default shader).
# Can be either an absolute path, a file in the "glshaders" subdirectory of the DOSBox-X configuration directory,
# or one of the built-in shaders (e.g. "sharp" for the pixel-perfect scaling mode):
# advinterp2x, advinterp3x, advmame2x, advmame3x, rgb2x, rgb3x, scan2x, scan3x, tv2x, tv3x, sharp.
# pixelshader: Set Direct3D pixel shader program (effect file must be in Shaders subdirectory). If 'forced' is appended,
# then the pixel shader will be used even if the result might not be desired.
# autofit: Best fits image to window
# - Intended for output=direct3d, fullresolution=original, aspect=true
# monochrome_pal: Specify the color of monochrome display.
# Possible values: green, amber, gray, white
# Append 'bright' for a brighter look.
# Possible values: green, amber, gray, white.
#
# Advanced options (see full configuration reference file [dosbox-x.reference.full.conf] for more details):
# -> alt render; xbrz slice; xbrz fixed scale factor; xbrz max scale factor
#
frameskip = 0
aspect = false
aspect_ratio = 0:0
char9 = true
euro = -1
doublescan = true
scaler = normal2x
glshader = none
pixelshader = none
autofit = true
monochrome_pal = green
[pc98]
# pc-98 BIOS copyright string: If set, the PC-98 BIOS copyright string is placed at E800:0000. Enable this for software that detects PC-98 vs Epson.
# pc-98 fm board: In PC-98 mode, selects the FM music board to emulate.
# Possible values: auto, off, false, board14, board26k, board86, board86c.
# pc-98 enable 256-color: Allow 256-color graphics mode if set, disable if not set
# pc-98 enable 16-color: Allow 16-color graphics mode if set, disable if not set
# pc-98 enable grcg: Allow GRCG graphics functions if set, disable if not set
# pc-98 enable egc: Allow EGC graphics functions if set, disable if not set
# pc-98 bus mouse: Enable PC-98 bus mouse emulation. Disabling this option does not disable INT 33h emulation.
# pc-98 force ibm keyboard layout: Force to use a default keyboard layout like IBM US-English for PC-98 emulation.
# Will only work with apps and games using BIOS for keyboard.
# Possible values: true, false, 1, 0, auto.
# pc-98 try font rom: If enabled, DOSBox-X will first try to load FONT.ROM as generated by T98Tools for PC-98 emulation.
# pc-98 anex86 font: Specify an Anex86 compatible font to load as supported by the Anex86 emulator for PC-98 emulation.
# By default DOSBox-X tries to load ANEX86.BMP followed by FREECG98.BMP after trying to load FONT.ROM.
# If you specify a font here then it will be tried first, perhaps before FONT.ROM (see previous option).
#
# Advanced options (see full configuration reference file [dosbox-x.reference.full.conf] for more details):
# -> pc-98 int 1b fdc timer wait; pc-98 pic init to read isr; pc-98 fm board irq; pc-98 fm board io port; pc-98 sound bios; pc-98 load sound bios rom file; pc-98 buffer page flip; pc-98 enable 256-color planar; pc-98 enable 188 user cg; pc-98 start gdc at 5mhz; pc-98 allow scanline effect; pc-98 video mode; pc-98 timer always cycles; pc-98 timer master frequency; pc-98 allow 4 display partition graphics; pc-98 show graphics layer on initialize
#
pc-98 BIOS copyright string = false
pc-98 fm board = auto
pc-98 enable 256-color = true
pc-98 enable 16-color = true
pc-98 enable grcg = true
pc-98 enable egc = true
pc-98 bus mouse = true
pc-98 force ibm keyboard layout = auto
pc-98 try font rom = true
pc-98 anex86 font =
[dosv]
# dosv: Enable DOS/V emulation and specify which version to emulate. This option is intended for use with games or software
# originating from East Asia (China, Japan, Korea) that use the double byte character set (DBCS) encodings and DOS/V extensions
# to display Japanese (jp), Chinese (chs/cht/cn/tw), or Korean (ko) text. Note that enabling DOS/V replaces 80x25 text mode with
# a EGA/VGA graphics mode that emulates text mode to display the characters and may be incompatible with non-Asian software that
# assumes direct access to the text mode via segment 0xB800. For a general DOS environment with CJK support please disable DOS/V
# emulation and use TrueType font (TTF) output with a CJK code page (932, 936, 949, 950) and TTF font with CJK characters instead.
# Possible values: off, jp, ko, chs, cht, cn, tw.
# getsysfont: If enabled, DOSBox-X will try to get and use the system fonts on Windows and Linux platforms for the DOS/V emulation.
# If this cannot be done, then DOSBox-X will try to use the internal Japanese DOS/V font, or you can specify a different font.
# fontxsbcs: FONTX2 file used to rendering SBCS characters (8x19) in DOS/V or JEGA mode. If not specified, the default one will be used.
# Loading the ASC16 and ASCFONT.15 font files (from the UCDOS and ETen Chinese DOS systems) is also supported for the DOS/V mode.
# fontxsbcs16: FONTX2 file used to rendering SBCS characters (8x16) in DOS/V or JEGA mode. If not specified, the default one will be used.
# Loading the ASC16 and ASCFONT.15 font files (from the UCDOS and ETen Chinese DOS systems) is also supported for the DOS/V mode.
# fontxsbcs24: FONTX2 file used to rendering SBCS characters (12x24) in DOS/V mode (with V-text). If not specified, the default one will be used.
# Loading the ASC24 and ASCFONT.24? font files (the latter from the ETen Chinese DOS system) is also supported for the DOS/V mode.
# fontxdbcs: FONTX2 file used to rendering DBCS characters (16x16) in DOS/V or VGA/JEGA mode. If not specified, the default one will be used.
# Alternatively, you can load a BDF or PCF font file (16x16 or 15x15), such as the free bitmap fonts from WenQuanYi (https://wenq.org/).
# For Simplified Chinese DOS/V, loading the HZK16 font file (https://github.com/aguegu/BitmapFont/tree/master/font) is also supported.
# For Traditional Chinese DOS/V, loading the STDFONT.15 font file from the ETen Chinese DOS system is also supported.
# fontxdbcs14: FONTX2 file used to rendering DBCS characters (14x14) for Configuration Tool or EGA mode. If not specified, the default one will be used.
# Alternatively, you can load a BDF or PCF font file (14x14 or 15x15), such as the free bitmap fonts from WenQuanYi (https://wenq.org/).
# For Simplified Chinese DOS/V, loading the HZK14 font file (https://github.com/aguegu/BitmapFont/tree/master/font) is also supported.
# For Traditional Chinese DOS/V, loading the STDFONT.15 font file from the ETen Chinese DOS system is also supported.
# fontxdbcs24: FONTX2 file used to rendering DBCS characters (24x24) in DOS/V mode (with V-text and 24-pixel fonts enabled).
# For Simplified Chinese DOS/V, loading the HZK24? font file (https://github.com/aguegu/BitmapFont/tree/master/font) is also supported.
# For Traditional Chinese DOS/V, loading the STDFONT.24 font file from the ETen Chinese DOS system is also supported.
# showdbcsnodosv: Enables rendering of Chinese/Japanese/Korean characters for DBCS code pages in standard VGA and EGA machine types in non-DOS/V and non-TTF mode.
# DOS/V fonts will be used in such cases, which can be adjusted by the above config options (such as fontxdbcs, fontxdbcs14, and fontxdbcs24).
# Setting to "auto" enables Chinese/Japanese/Korean character rendering if a language file is loaded (or with "autodbcs" option set) in such cases.
# Possible values: true, false, 1, 0, auto.
# yen: Enables the Japanese yen symbol at 5ch if it is found at 7fh in a custom SBCS font for the Japanese DOS/V or JEGA emulation.
# fepcontrol: FEP control API for the DOS/V emulation.
# Possible values: ias, mskanji, both.
# vtext1: V-text screen mode 1 for the DOS/V emulation. Enter command "VTEXT 1" for this mode. Note that XGA/SXGA mode is only supported by the svga_s3trio and svga_et4000 machine types.
# Possible values: xga, xga24, sxga, sxga24, svga.
# vtext2: V-text screen mode 2 for the DOS/V emulation. Enter command "VTEXT 2" for this mode. Note that XGA/SXGA mode is only supported by the svga_s3trio and svga_et4000 machine types.
# Possible values: xga, xga24, sxga, sxga24, svga.
# use20pixelfont: Enables the 20 pixel font to be used instead of the 24 pixel system font for the Japanese DOS/V emulation (with V-text enabled).
# j3100: With the setting dosv=jp and a non-off value of this option, the Toshiba J-3100 machine will be emulated with DCGA support.
# Setting to "on" or "auto" starts J-3100 automatically, and with the setting "manual" you can enter J-3100 mode with DCGA command.
# Possible values: off, on, auto, manual, 0, 1, 2.
# j3100type: Specifies the Toshiba J-3100 machine type if J-3100 mode is enabled. The color palette will be changed with different machine types.
# Possible values: default, gt, sgt, gx, gl, sl, sgx, ss, gs, sx, sxb, sxw, sxp, ez, zs, zx.
# j3100colorscroll: Specifies that the color display can be used for scrolling, which is currently incompatible with for example the J-3100 version of the SimCity game.
# The VGA version of the Toshiba Windows 3.1 works fine with the "false" value of this setting, whereas its CGA/EGA version requires a "true" value for this.
#
# Advanced options (see full configuration reference file [dosbox-x.reference.full.conf] for more details):
# -> del; j3100backcolor; j3100textcolor
#
dosv = off
getsysfont = true
fontxsbcs =
fontxsbcs16 =
fontxsbcs24 =
fontxdbcs =
fontxdbcs14 =
fontxdbcs24 =
showdbcsnodosv = auto
yen = false
fepcontrol = both
vtext1 = svga
vtext2 = xga
use20pixelfont = false
j3100 = off
j3100type = default
j3100colorscroll = false
[video]
# vmemsize: Amount of video memory in megabytes.
# The maximum resolution and color depth the svga_s3 will be able to display
# is determined by this value.
# -1: auto (vmemsizekb is ignored)
# 0: 512k (800x600 at 256 colors) if vmemsizekb=0
# 1: 1024x768 at 256 colors or 800x600 at 64k colors
# 2: 1600x1200 at 256 colors or 1024x768 at 64k colors or 640x480 at 16M colors
# 4: 1600x1200 at 64k colors or 1024x768 at 16M colors
# 8: up to 1600x1200 at 16M colors
# For build engine games, use more memory than in the list above so it can
# use triple buffering and thus won't flicker.
#
# vmemsizekb: Amount of video memory in kilobytes, in addition to vmemsize.
# high intensity blinking: Set to false if you want to see high-intensity background colors instead of blinking foreground text.
# This option has no effect in PC-98 and some other video modes.
#
# Advanced options (see full configuration reference file [dosbox-x.reference.full.conf] for more details):
# -> vmemdelay; vbe window granularity; vbe window size; enable 8-bit dac; svga lfb base; pci vga; vga attribute controller mapping; vga bios use rom image; vga bios rom image; vga bios size override; video bios dont duplicate cga first half rom font; video bios always offer 14-pixel high rom font; video bios always offer 16-pixel high rom font; video bios enable cga second half rom font; forcerate; sierra ramdac; sierra ramdac lock 565; vga fill active memory; page flip debug line; vertical retrace poll debug line; cgasnow; vga 3da undefined bits; rom bios 8x8 CGA font; rom bios video parameter table; int 10h points at vga bios; unmask timer on int 10 setmode; vesa bank switching window mirroring; vesa bank switching window range check; vesa zero buffer on get information; vesa set display vsync; vesa lfb base scanline adjust; vesa map non-lfb modes to 128kb region; ega per scanline hpel; allow hpel effects; allow hretrace effects; hretrace effect weight; vesa modelist cap; vesa modelist width limit; vesa modelist height limit; vesa vbe put modelist in vesa information; vesa vbe 1.2 modes are 32bpp; allow low resolution vesa modes; allow explicit 24bpp vesa modes; allow high definition vesa modes; allow unusual vesa modes; allow 32bpp vesa modes; allow 24bpp vesa modes; allow 16bpp vesa modes; allow 15bpp vesa modes; allow 8bpp vesa modes; allow 4bpp vesa modes; allow 4bpp packed vesa modes; allow tty vesa modes; double-buffered line compare; ignore vblank wraparound; ignore extended memory bit; enable vga resize delay; resize only on vga active display width increase; vga palette update on full load; ignore odd-even mode in non-cga modes; ignore sequencer blanking
#
vmemsize = -1
vmemsizekb = 0
high intensity blinking = true
[vsync]
# vsyncmode: Synchronize vsync timing to the host display. Requires calibration within DOSBox-X.
# Possible values: off, on, force, host.
# vsyncrate: Vsync rate used if vsync is enabled. Ignored if vsyncmode is set to host (win32).
# Possible values:.
vsyncmode = off
vsyncrate = 75
[cpu]
# core: CPU Core used in emulation. auto will switch to dynamic if available and appropriate.
# For the dynamic core, both dynamic_x86 and dynamic_rec are supported (dynamic_x86 is preferred).
# Windows 95 or other preemptive multitasking OSes will not work with the dynamic_rec core.
# Possible values: auto, dynamic, dynamic_x86, dynamic_nodhfpu, dynamic, dynamic_rec, normal, full, simple.
# fpu: Enable FPU emulation
# Possible values: true, false, 1, 0, auto, 8087, 287, 387.
# segment limits: Enforce checks for segment limits on 80286 and higher CPU types.
# cputype: CPU Type used in emulation. "auto" emulates a 486 which tolerates Pentium instructions.
# "experimental" enables newer instructions not normally found in the CPU types emulated by DOSBox-X, such as FISTTP.
# Possible values: auto, 8086, 8086_prefetch, 80186, 80186_prefetch, 286, 286_prefetch, 386, 386_prefetch, 486old, 486old_prefetch, 486, 486_prefetch, pentium, pentium_mmx, ppro_slow, pentium_ii, pentium_iii, experimental.
# cycles: Number of instructions DOSBox-X tries to emulate each millisecond.
# Setting this value too high results in sound dropouts and lags.
# Cycles can be set in 3 ways:
# 'auto' tries to guess what a game needs.
# It usually works, but can fail for certain games.
# 'fixed #number' will set a fixed number of cycles. This is what you usually
# need if 'auto' fails (Example: fixed 4000).
# 'max' will allocate as much cycles as your computer is able to
# handle. Recommended if better performance is desired.
# Possible values: auto, fixed, max.
# cycleup: Amount of cycles to decrease/increase with the mapped keyboard shortcut.
# cycledown: Setting it lower than 100 will be a percentage.
# turbo: Enables Turbo (Fast Forward) mode to speed up operations.
# apmbios: Emulate Advanced Power Management (APM) BIOS calls.
# integration device: Enable DOSBox-X's integration I/O device, a way for additional software to talk to DOSBox-X. It is currently experimental.
# This can for example be used to return DOSBox-X's current status and by the guest OS to match the mouse pointer position.
# isapnpbios: Emulate ISA Plug & Play BIOS. Enable if using DOSBox-X to run a PnP aware DOS program or if booting Windows 9x.
# Do not disable if Windows 9x is configured around PnP devices, you will likely confuse it.
#
# Advanced options (see full configuration reference file [dosbox-x.reference.full.conf] for more details):
# -> processor serial number; double fault; clear trap flag on unhandled int 1; reset on triple fault; always report double fault; always report triple fault; mask stack pointer for enter leave instructions; allow lmsw to exit protected mode; report fdiv bug; enable msr; enable cmpxchg8b; enable syscall; ignore undefined msr; interruptible rep string op; dynamic core cache block size; cycle emulation percentage adjust; stop turbo on key; stop turbo after second; use dynamic core with paging on; ignore opcode 63; apmbios pnp; apm power button event; apmbios version; apmbios allow realmode; apmbios allow 16-bit protected mode; apmbios allow 32-bit protected mode; integration device pnp; isapnpport; realbig16
#
core = dynamic
fpu = true
segment limits = true
cputype = auto
cycles = auto
cycleup = 10
cycledown = 20
turbo = false
apmbios = true
integration device = false
isapnpbios = true
[keyboard]
# aux: Enable emulation of the 8042 auxiliary port. PS/2 mouse emulation requires this to be enabled.
# You should enable this if you will be running Windows ME or any other OS that does not use the BIOS to receive mouse events.
# allow output port reset: If set (default), allow the application to reset the CPU through the keyboard controller.
# This option is required to allow Windows ME to reboot properly, whereas Windows 9x and earlier
# will reboot without this option using INT 19h
# controllertype: Type of keyboard controller (and keyboard) attached.
# auto Automatically pick according to machine type
# at AT (PS/2) type keyboard
# xt IBM PC/XT type keyboard
# pcjr IBM PCjr type keyboard (only if machine=pcjr)
# pc98 PC-98 keyboard emulation (only if machine=pc98)
# Possible values: auto, at, xt, pcjr, pc98.
# auxdevice: Type of PS/2 mouse attached to the AUX port
# Possible values: none, 2button, 3button, intellimouse, intellimouse45.
aux = true
allow output port reset = true
controllertype = auto
auxdevice = intellimouse
[ttf]
# font: Specifies a TrueType font to use for the TTF output. If not specified, the built-in TrueType font will be used.
# Either a font name or full font path can be specified. If file ends with the .TTF extension then the extension can be omitted.
# For a font name or relative path, directories such as the working directory and default system font directory will be searched.
# For example, setting it to "consola" or "consola.ttf" will use Consola font (included in Windows); similar for other TTF fonts.
# Additionally, OTF fonts (e.g. OratorStd.otf), .FON fonts (e.g. vgasys.fon), and .TTC fonts (e.g. msgothic.ttc) are also supported.
# To display Chinese/Japanese/Korean text in these code pages, a font with CJK characters is needed (e.g. GNU Unifont or Sarasa Gothic).
# fontbold: You can optionally specify a bold TrueType font for use with the TTF output that will render the bold text style.
# It requires a word processor be set with the wp option, and this actual bold font will be used for the bold style.
# For example, setting it to "consolab" or "consolab.ttf" will use the Consolab font; similar for other TTF fonts.
# fontital: You can optionally specify an italic TrueType font for use with the TTF output that will render the italic text style.
# It requires a word processor be set with the wp option, and this actual italic font will be used for the italic style.
# For example, setting it to "consolai" or "consolai.ttf" will use the Consolai font; similar for other TTF fonts.
# fontboit: You can optionally specify a bold italic TrueType font for use with the TTF output that will render the bold italic text style.
# It requires a word processor be set with the wp option, and this actual bold-italic font will be used for the bold-italic style.
# For example, setting it to "consolaz" or "consolaz.ttf" will use the Consolaz font; similar for other TTF fonts.
# colors: Specifies a color scheme to use for the TTF output by supply all 16 color values in RGB: (r,g,b) or hexadecimal as in HTML: #RRGGBB
# The original DOS colors (0-15): #000000 #0000aa #00aa00 #00aaaa #aa0000 #aa00aa #aa5500 #aaaaaa #555555 #5555ff #55ff55 #55ffff #ff5555 #ff55ff #ffff55 #ffffff
# gray scaled color scheme: (0,0,0) #0e0e0e (75,75,75) (89,89,89) (38,38,38) (52,52,52) #717171 #c0c0c0 #808080 (28,28,28) (150,150,150) (178,178,178) (76,76,76) (104,104,104) (226,226,226) (255,255,255)
# An optional leading "+" sign allows the preset color scheme to be used when switching from another output.
# outputswitch: Specifies the output that DOSBox-X should switch to from the TTF output when a graphical mode is requested, or auto for automatic selection.
# Possible values: auto, surface, opengl, openglnb, openglhq, openglpp, direct3d.
# winperc: Specifies the window percentage for the TTF output (100 = full screen). Ignored if the ptsize setting is specified.
# ptsize: Specifies the font point size for the TTF output. If specified (minimum: 9), it will override the winperc setting.
# lins: Specifies the number of rows on the screen for the TTF output (0 = default).
# cols: Specifies the number of columns on the screen for the TTF output (0 = default).
# righttoleft: If set, DOSBox-X will display text from right to left instead of left to right on the screen for the TTF output.
# This is especially useful for languages which use right-to-left scripts (such as Arabic and Hebrew).
# wp: You can specify a word processor for the TTF output and optionally also a version number for the word processor.
# Supported word processors are WP=WordPerfect, WS=WordStar, XY=XyWrite, FE=FastEdit, and an optional version number.
# For example, WP6 will set the word processor as WordPerfect 6, and XY4 will set the word processor as XyWrite 4.
# Word processor-specific features like on-screen text styles and 512-character font will be enabled based on this.
# bold: If set, DOSBox-X will display bold text in visually (requires a word processor be set) for the TTF output.
# This is done either with the actual bold font specified by the fontbold option, or by making it bold automatically.
# italic: If set, DOSBox-X will display italicized text visually (requires a word processor be set) for the TTF output.
# This is done either with the actual italic font specified by the fontital option, or by slanting the characters automatically.
# underline: If set, DOSBox-X will display underlined text visually (requires a word processor be set) for the TTF output.
# strikeout: If set, DOSBox-X will display strikeout text visually (requires a word processor be set) for the TTF output.
# printfont: If set, DOSBox-X will force to use the current TrueType font (set via font option) for printing in addition to displaying.
# autodbcs: If set, DOSBox-X enables Chinese/Japanese/Korean DBCS (double-byte) characters when these code pages are active by default.
# Only applicable when using a DBCS code page (932: Japanese, 936: Simplified Chinese; 949: Korean; 950: Traditional Chinese)
# This applies to both the display and printing of these characters (see the [printer] section for details of the latter).
# blinkc: If set to true, the cursor blinks for the TTF output; setting it to false will turn the blinking off.
# You can also change the blinking rate by setting an integer between 1 (fastest) and 7 (slowest), or 0 for no cursor.
# gbk: Enables the GBK extension (in addition to the standard GB2312 charset) for the Simplified Chinese TTF output or DOS/V emulation.
# chinasea: Enables the ChinaSea and Big5-2003 extension (in addition to the standard Big5-1984 charset) for the Traditional Chinese TTF output.
# A TTF/OTF font containing such characters (such as the included SarasaGothicFixed TTF font) is needed to correctly render ChinaSea characters.
# dosvfunc: If set, enables FEP control to function for Japanese DOS/V applications, and changes the blinking of character attributes to high brightness.
#
# Advanced options (see full configuration reference file [dosbox-x.reference.full.conf] for more details):
# -> wpbg; wpfg; char512; autoboxdraw; halfwidthkana; uao
#
font =
fontbold =
fontital =
fontboit =
colors =
outputswitch = auto
winperc = 60
ptsize = 0
lins = 0
cols = 0
righttoleft = false
wp =
bold = true
italic = true
underline = true
strikeout = false
printfont = true
autodbcs = true
blinkc = true
gbk = false
chinasea = false
dosvfunc = false
[voodoo]
# voodoo_card: Enable support for the 3dfx Voodoo card.
# Possible values: false, software, opengl, auto.
# voodoo_maxmem: Specify whether to enable maximum memory size for the Voodoo card.
# If set (on by default), the memory size will be 12MB (4MB front buffer + 2x4MB texture units)
# Otherwise, the memory size will be the standard 4MB (2MB front buffer + 1x2MB texture unit)
# glide: Enable Glide emulation (Glide API passthrough to the host).
# Requires a Glide wrapper - glide2x.dll (Windows), libglide2x.so (Linux), or libglide2x.dylib (macOS).
# lfb: Enable LFB access for Glide. OpenGlide does not support locking aux buffer, please use _noaux modes.
# Possible values: full, full_noaux, read, read_noaux, write, write_noaux, none.
# splash: Show 3dfx splash screen for Glide emulation (Windows; requires 3dfxSpl2.dll).
voodoo_card = auto
voodoo_maxmem = true
glide = false
lfb = full_noaux
splash = true
[mixer]
# nosound: Enable silent mode, sound is still emulated though.
# sample accurate: Enable sample accurate mixing, at the expense of some emulation performance. Enable this option for DOS games and demos
# that require such accuracy for correct Tandy/OPL output including digitized speech. This option can also help eliminate
# minor errors in Gravis Ultrasound emulation that result in random echo/attenuation effects.
# swapstereo: Swaps the left and right stereo channels.
# rate: Mixer sample rate, setting any device's rate higher than this will probably lower their sound quality.
# blocksize: Mixer block size, larger blocks might help sound stuttering but sound will also be more lagged.
# Possible values: 1024, 2048, 4096, 8192, 512, 256.
# prebuffer: How many milliseconds of data to keep on top of the blocksize.
nosound = false
sample accurate = false
swapstereo = false
rate = 44100
blocksize = 1024
prebuffer = 25
[midi]
# mpu401: Type of MPU-401 to emulate.
# Possible values: intelligent, uart, none.
# mpubase: The IO address of the MPU-401.
# Set to 0 to use a default I/O address.
# 300h to 330h are for use with IBM PC mode.
# C0D0h to F8D0h (in steps of 800h) are for use with NEC PC-98 mode (MPU98).
# 80D2h through 80DEh are for use with NEC PC-98 Sound Blaster 16 MPU-401 emulation.
# If not assigned (0), 330h is the default for IBM PC and E0D0h is the default for PC-98.
# Possible values: 0, 300, 310, 320, 330, 332, 334, 336, 340, 360, c0d0, c8d0, d0d0, d8d0, e0d0, e8d0, f0d0, f8d0, 80d2, 80d4, 80d6, 80d8, 80da, 80dc, 80de.
# mididevice: Device that will receive the MIDI data from MPU-401.
# Possible values: default, win32, alsa, oss, coreaudio, coremidi, mt32, synth, fluidsynth, timidity, none.
# midiconfig: Special configuration options for the device driver. This is usually the id or part of the name of the device you want to use
# (find the id/name with mixer/listmidi).
# Or in the case of coreaudio or synth, you can specify a soundfont here.
# When using a Roland MT-32 rev. 0 as midi output device, some games may require a delay in order to prevent 'buffer overflow' issues.
# In that case, add 'delaysysex', for example: midiconfig=2 delaysysex
# See the README/Manual for more details.
# samplerate: Sample rate for MIDI synthesizer, if applicable.
# Possible values: 49716, 48000, 44100, 32000, 22050, 16000, 11025, 8000.
# mpuirq: MPU-401 IRQ. -1 to automatically choose.
# mt32.romdir: Name of the directory where MT-32 Control and PCM ROM files can be found. Emulation requires these files to work.
# Accepted file names are as follows:
# MT32_CONTROL.ROM or CM32L_CONTROL.ROM - control ROM file.
# MT32_PCM.ROM or CM32L_PCM.ROM - PCM ROM file.
# mt32.model: Model of the MT-32 synthesizer to use.
# Possible values: cm32l, mt32, auto.
# fluid.driver: Driver to use with Fluidsynth, not needed under Windows. Available drivers depend on what Fluidsynth was compiled with.
# Possible values: pulseaudio, alsa, oss, coreaudio, dsound, portaudio, sndman, jack, file, default.
# fluid.soundfont: Soundfont (.SF2 or .SF3) to use with Fluidsynth. One must be specified (e.g. GeneralUser_GS.sf2).
#
# Advanced options (see full configuration reference file [dosbox-x.reference.full.conf] for more details):
# -> mt32.reverse.stereo; mt32.verbose; mt32.thread; mt32.chunk; mt32.prebuffer; mt32.partials; mt32.dac; mt32.analog; mt32.output.gain; mt32.reverb.mode; mt32.reverb.output.gain; mt32.reverb.time; mt32.reverb.level; mt32.rate; mt32.src.quality; mt32.niceampramp; fluid.samplerate; fluid.gain; fluid.polyphony; fluid.cores; fluid.periods; fluid.periodsize; fluid.reverb; fluid.chorus; fluid.reverb.roomsize; fluid.reverb.damping; fluid.reverb.width; fluid.reverb.level; fluid.chorus.number; fluid.chorus.level; fluid.chorus.speed; fluid.chorus.depth; fluid.chorus.type
#
mpu401 = intelligent
mpubase = 0
mididevice = default
midiconfig =
samplerate = 44100
mpuirq = -1
mt32.romdir =
mt32.model = auto
fluid.driver = default
fluid.soundfont =
[sblaster]
# sbtype: Type of Sound Blaster to emulate. 'gb' is Game Blaster.
# Possible values: sb1, sb2, sbpro1, sbpro2, sb16, sb16vibra, gb, ess688, reveal_sc400, none.
# sbbase: The IO address of the Sound Blaster.
# 220h to 2E0h are for use with IBM PC Sound Blaster emulation.
# D2h to DEh are for use with NEC PC-98 Sound Blaster 16 emulation.
# Possible values: 220, 240, 260, 280, 2a0, 2c0, 2e0, d2, d4, d6, d8, da, dc, de.
# irq: The IRQ number of the Sound Blaster (usually 5 or 7, depending on the sound card type and the game).
# Set to 0 for the default setting of the sound card, or set to -1 to start DOSBox-X with the IRQ unassigned.
# Possible values: 7, 5, 3, 9, 10, 11, 12, 0, -1.
# dma: The DMA number of the Sound Blaster. Set to -1 to start DOSBox-X with the DMA unassigned.
# Possible values: 1, 5, 0, 3, 6, 7, -1.
# hdma: The High DMA number of the Sound Blaster. Set to -1 to start DOSBox-X with the High DMA unassigned.
# Possible values: 1, 5, 0, 3, 6, 7, -1.
# enable speaker: Start the DOS virtual machine with the Sound Blaster speaker enabled.
# Sound Blaster Pro and older cards have a speaker disable/enable command.
# Normally the card boots up with the speaker disabled. If a DOS game or demo
# attempts to play without enabling the speaker, set this option to true to
# compensate. This setting has no meaning if emulating a Sound Blaster 16 card.
# sbmixer: Allow the Sound Blaster mixer to modify the DOSBox-X mixer.
# oplmode: Type of OPL emulation. On 'auto' the mode is determined by the 'sbtype' setting.
# All OPL modes are AdLib-compatible, except for 'cms' (set 'sbtype=none' with 'cms' for a Game Blaster).
# Possible values: auto, cms, opl2, dualopl2, opl3, opl3gold, none, hardware, hardwaregb.
# oplemu: Provider for the OPL emulation. 'compat' might provide better quality.
# 'nuked' is the most accurate (but the most CPU-intensive). See oplrate as well.
# Possible values: default, compat, fast, nuked, mame, opl2board, opl3duoboard, retrowave_opl3.
# oplrate: Sample rate of OPL music emulation. Use 49716 for highest quality (set the mixer rate accordingly).
# Possible values: 49716, 48000, 44100, 32000, 22050, 16000, 11025, 8000.
# oplport: Serial port of the OPL2 Audio Board when oplemu=opl2board, opl2mode will become 'opl2' automatically.
# retrowave_bus: Bus of the Retrowave series board (serial/spi). SPI is only supported on Linux.
# retrowave_port: Serial port of the Retrowave series board.
# hardwarebase: base address of the real hardware Sound Blaster:
# 210,220,230,240,250,260,280
# goldplay: Enable goldplay emulation.
# blaster environment variable: Whether or not to set the BLASTER environment variable automatically at startup
#
# Advanced options (see full configuration reference file [dosbox-x.reference.full.conf] for more details):
# -> mindma; irq hack; dsp command aliases; pic unmask irq; enable asp; disable filtering; dsp write buffer status must return 0x7f or 0xff; pre-set sbpro stereo; adlib force timer overflow on detect; retrowave_spi_cs; force dsp auto-init; force goldplay; goldplay stereo; dsp require interrupt acknowledge; dsp write busy delay; sample rate limits; instant direct dac; stereo control with sbpro only; dsp busy cycle rate; dsp busy cycle always; dsp busy cycle duty; io port aliasing
#
sbtype = sb16
sbbase = 220
irq = 7
dma = 1
hdma = 5
enable speaker = false
sbmixer = true
oplmode = auto
oplemu = default
oplrate = 44100
oplport =
retrowave_bus = serial
retrowave_port =
hardwarebase = 220
goldplay = true
blaster environment variable = true
[gus]
# gus: Enable the Gravis Ultrasound emulation.
# gusrate: Sample rate of Ultrasound emulation.
# Possible values: 49716, 48000, 44100, 32000, 22050, 16000, 11025, 8000.
# gusmemsize: Amount of RAM on the Gravis Ultrasound in KB. Set to -1 for default.
# gus master volume: Master Gravis Ultrasound GF1 volume, in decibels. Reducing the master volume can help with games or demoscene productions where the music is too loud and clipping.
# gusbase: The IO base address of the Gravis Ultrasound.
# Possible values: 240, 220, 260, 280, 2a0, 2c0, 2e0, 300, 210, 230, 250.
# gusirq: The IRQ number of the Gravis Ultrasound.
# Possible values: 5, 3, 7, 9, 10, 11, 12.
# gusdma: The DMA channel of the Gravis Ultrasound.
# Possible values: 3, 0, 1, 5, 6, 7.
# gustype: Type of Gravis Ultrasound to emulate.
# classic Original Gravis Ultrasound chipset
# classic37 Original Gravis Ultrasound with ICS Mixer (rev 3.7)
# max Gravis Ultrasound MAX emulation (with CS4231 codec)
# interwave Gravis Ultrasound Plug & Play (interwave)
# Possible values: classic, classic37, max, interwave.
# ultradir: Path to Ultrasound directory. In this directory
# there should be a MIDI directory that contains
# the patch files for GUS playback. Patch sets used
# with Timidity should work fine.
#
# Advanced options (see full configuration reference file [dosbox-x.reference.full.conf] for more details):
# -> autoamp; unmask dma; ignore channel count while active; pic unmask irq; startup initialized; dma enable on dma control polling; clear dma tc irq if excess polling; force master irq enable; gus panning table; gus fixed render rate; irq hack
#
gus = false
gusrate = 44100
gusmemsize = -1
gus master volume = 0.00
gusbase = 240
gusirq = 5
gusdma = 3
gustype = classic
ultradir = C:\ULTRASND
[innova]
# innova: Enable the Innovation SSI-2001 emulation.
# samplerate: Sample rate of Innovation SSI-2001 emulation
# Possible values: 49716, 48000, 44100, 32000, 22050, 16000, 11025, 8000.
# sidbase: SID base port (typically 280h).
# Possible values: 240, 220, 260, 280, 2a0, 2c0, 2e0, 300.
# quality: Set SID emulation quality level (0 to 3).
# Possible values: 0, 1, 2, 3.
innova = false
samplerate = 22050
sidbase = 280
quality = 0
[speaker]
# pcspeaker: Enable PC-Speaker emulation.
# pcrate: Sample rate of the PC-Speaker sound generation.
# Possible values: 65536, 49716, 48000, 44100, 32000, 22050, 16000, 11025, 8000.
# tandy: Enable Tandy Sound System emulation. For 'auto', emulation is present only if machine is set to 'tandy'.
# Possible values: auto, on, off.
# tandyrate: Sample rate of the Tandy 3-Voice generation.
# Possible values: 49716, 48000, 44100, 32000, 22050, 16000, 11025, 8000.
# disney: Enable Disney Sound Source emulation. (Covox Voice Master and Speech Thing compatible).
# ps1audio: Enable PS1 audio emulation.
# Possible values: on, off.
# ps1audiorate: Sample rate of the PS1 audio emulation.
# Possible values: 49716, 48000, 44100, 32000, 22050, 16000, 11025, 8000.
#
# Advanced options (see full configuration reference file [dosbox-x.reference.full.conf] for more details):
# -> pcspeaker clock gate enable at startup; initial frequency
#
pcspeaker = true
pcrate = 65536
tandy = auto
tandyrate = 44100
disney = false
ps1audio = off
ps1audiorate = 22050
[joystick]
# joysticktype: Type of joystick to emulate: auto (default),
# none (disables joystick emulation),
# 2axis (supports two joysticks),
# 4axis (supports one joystick, first joystick used),
# 4axis_2 (supports one joystick, second joystick used),
# fcs (Thrustmaster), ch (CH Flightstick).
# auto chooses emulation depending on real joystick(s).
# (Remember to reset DOSBox-X's mapperfile if you saved it earlier)
# Possible values: auto, 2axis, 4axis, 4axis_2, fcs, ch, none.
# timed: enable timed intervals for axis. Experiment with this option, if your joystick drifts (away).
# autofire: continuously fires as long as you keep the button pressed.
# swap34: swap the 3rd and the 4th axis. can be useful for certain joysticks.
# buttonwrap: enable button wrapping at the number of emulated buttons.
#
# Advanced options (see full configuration reference file [dosbox-x.reference.full.conf] for more details):
# -> joy1deadzone1; joy1deadzone2; joy2deadzone1; joy1response1; joy1response2; joy2response1; joy1axis0; joy1axis1; joy1axis2; joy1axis3; joy1axis4; joy1axis5; joy1axis6; joy1axis7; joy2axis0; joy2axis1; joy2axis2; joy2axis3; joy2axis4; joy2axis5; joy2axis6; joy2axis7
#
joysticktype = auto
timed = true
autofire = false
swap34 = false
buttonwrap = false
[mapper]
# joy1deadzone0-: deadzone for joystick 1 axis 0-
# joy1deadzone0+: deadzone for joystick 1 axis 0+
# joy1deadzone1-: deadzone for joystick 1 axis 1-
# joy1deadzone1+: deadzone for joystick 1 axis 1+
# joy1deadzone2-: deadzone for joystick 1 axis 2-
# joy1deadzone2+: deadzone for joystick 1 axis 2+
# joy1deadzone3-: deadzone for joystick 1 axis 3-
# joy1deadzone3+: deadzone for joystick 1 axis 3+
# joy1deadzone4-: deadzone for joystick 1 axis 4-
# joy1deadzone4+: deadzone for joystick 1 axis 4+
# joy1deadzone5-: deadzone for joystick 1 axis 5-
# joy1deadzone5+: deadzone for joystick 1 axis 5+
# joy1deadzone6-: deadzone for joystick 1 axis 6-
# joy1deadzone6+: deadzone for joystick 1 axis 6+
# joy1deadzone7-: deadzone for joystick 1 axis 7-
# joy1deadzone7+: deadzone for joystick 1 axis 7+
# joy2deadzone0-: deadzone for joystick 2 axis 0-
# joy2deadzone0+: deadzone for joystick 2 axis 0+
# joy2deadzone1-: deadzone for joystick 2 axis 1-
# joy2deadzone1+: deadzone for joystick 2 axis 1+
# joy2deadzone2-: deadzone for joystick 2 axis 2-
# joy2deadzone2+: deadzone for joystick 2 axis 2+
# joy2deadzone3-: deadzone for joystick 2 axis 3-
# joy2deadzone3+: deadzone for joystick 2 axis 3+
# joy2deadzone4-: deadzone for joystick 2 axis 4-
# joy2deadzone4+: deadzone for joystick 2 axis 4+
# joy2deadzone5-: deadzone for joystick 2 axis 5-
# joy2deadzone5+: deadzone for joystick 2 axis 5+
# joy2deadzone6-: deadzone for joystick 2 axis 6-
# joy2deadzone6+: deadzone for joystick 2 axis 6+
# joy2deadzone7-: deadzone for joystick 2 axis 7-
# joy2deadzone7+: deadzone for joystick 2 axis 7+
joy1deadzone0- = 0.60
joy1deadzone0+ = 0.60
joy1deadzone1- = 0.60
joy1deadzone1+ = 0.60
joy1deadzone2- = 0.60
joy1deadzone2+ = 0.60
joy1deadzone3- = 0.60
joy1deadzone3+ = 0.60
joy1deadzone4- = 0.60
joy1deadzone4+ = 0.60
joy1deadzone5- = 0.60
joy1deadzone5+ = 0.60
joy1deadzone6- = 0.60
joy1deadzone6+ = 0.60
joy1deadzone7- = 0.60
joy1deadzone7+ = 0.60
joy2deadzone0- = 0.60
joy2deadzone0+ = 0.60
joy2deadzone1- = 0.60
joy2deadzone1+ = 0.60
joy2deadzone2- = 0.60
joy2deadzone2+ = 0.60
joy2deadzone3- = 0.60
joy2deadzone3+ = 0.60
joy2deadzone4- = 0.60
joy2deadzone4+ = 0.60
joy2deadzone5- = 0.60
joy2deadzone5+ = 0.60
joy2deadzone6- = 0.60
joy2deadzone6+ = 0.60
joy2deadzone7- = 0.60
joy2deadzone7+ = 0.60
[serial]
# serial1: serial1-9 -- set type of device connected to the serial (COM) port.
# Can be disabled, dummy, file, modem, nullmodem, directserial.
# Additional parameters must be in the same line in the form of
# parameter:value. Parameter for all types is irq (optional).
# for file: specify an output file
# Additional parameters:
# timeout:<milliseconds> = how long to wait before closing the file on inactivity (default:0),
# squote to use single quotes instead of double quotes for quoted program commands.
# shellhide to hide the command window when opening programs on the Windows platform.
# openwith:<program>: start a program to open the output file.
# openerror:<program>: start a program to open the output file if an error had occurred.
# Example: serial1=file file:output1.txt timeout:1000 openwith:notepad
# for directserial: realport (required), rxdelay (optional).
# (realport:COM1 realport:ttyS0).
# for modem: listenport (optional).
# for nullmodem: server, rxdelay, txdelay, telnet, usedtr,
# transparent, port, inhsocket, sock, nonlocal (all optional).
# connections are limited to localhost unless you specify nonlocal:1
# "sock" parameter specifies the protocol to be used by both sides
# of the connection. 0 for TCP and 1 for ENet reliable UDP.
# Example: serial1=modem listenport:5000 sock:1
# Note: COM1-4 are standard COM ports in DOS, whereas COM5-9 are extended COM ports.
# You can optionally specify base addresses and IRQs for them with base: and irq: options.
# Serial port settings can also be changed via the built-in SERIAL command.
# Possible values: dummy, disabled, modem, nullmodem, serialmouse, directserial, log, file.
# serial2: see serial1
# Possible values: dummy, disabled, modem, nullmodem, serialmouse, directserial, log, file.
# serial3: see serial1
# Possible values: dummy, disabled, modem, nullmodem, serialmouse, directserial, log, file.
# serial4: see serial1
# Possible values: dummy, disabled, modem, nullmodem, serialmouse, directserial, log, file.
# serial5: see serial1
# Possible values: dummy, disabled, modem, nullmodem, serialmouse, directserial, log, file.
# serial6: see serial1
# Possible values: dummy, disabled, modem, nullmodem, serialmouse, directserial, log, file.
# serial7: see serial1
# Possible values: dummy, disabled, modem, nullmodem, serialmouse, directserial, log, file.
# serial8: see serial1
# Possible values: dummy, disabled, modem, nullmodem, serialmouse, directserial, log, file.
# serial9: see serial1
# Possible values: dummy, disabled, modem, nullmodem, serialmouse, directserial, log, file.
# phonebookfile: File used to map fake phone numbers to addresses.
serial1 = nullmodem transparent:1 port:5123 sock:0
serial2 = dummy
serial3 = disabled
serial4 = disabled
serial5 = disabled
serial6 = disabled
serial7 = disabled
serial8 = disabled
serial9 = disabled
phonebookfile = phonebook-dosbox-x.txt
[parallel]
# parallel1: parallel1-9 -- set type of device connected to the parallel (LPT) port.
# Can be:
# reallpt (direct parallel port passthrough),
# file (records data to a file or passes it to a device),
# printer (virtual dot-matrix printer, see [printer] section)
# disney (attach Disney Sound Source emulation to this port)
# Additional parameters must be in the same line in the form of
# parameter:value.
# for reallpt:
# Windows:
# realbase (the base address of your real parallel port).
# Default: 378
# ecpbase (base address of the ECP registers, optional).
# Linux: realport (the parallel port device i.e. /dev/parport0).
# for file:
# dev:<devname> (i.e. dev:lpt1) to forward data to a device,
# or append:<file> appends data to the specified file.
# Without the above parameters data is written to files in the capture dir.
# Additional parameters:
# timeout:<milliseconds> = how long to wait before closing the file on inactivity (default:0 or 500),
# squote to use single quotes instead of double quotes for quoted program commands.
# shellhide to hide the command window when opening programs on the Windows platform.
# addFF to add a formfeed when closing, addLF to add a linefeed if the app doesn't.
# cp:<codepage number> to perform codepage translation, i.e. cp:437
# openps:<program>: start a program to open the file if the print output is detected to be PostScript.
# openpcl:<program>: start a program to open the file if the print output is detected to be PCL.
# openwith:<program>: start a program to open the file in all other conditions.
# openerror:<program>: start a program to open the file if an error had occurred.
# Example: parallel1=file file:output1.prn timeout:1000 openpcl:pcl6 openps:gswin32c openwith:notepad
# for printer:
# printer still has its own configuration section above.
# Note: LPT1-3 are standard LPT ports in DOS, whereas LPT4-9 are extended LPT ports.
# You can optionally specify base addresses and IRQs for them with base: and irq: options.
# Parallel port settings can also be changed via the built-in PARALLEL command.
# parallel2: see parallel1
# parallel3: see parallel1
# parallel4: see parallel1
# parallel5: see parallel1
# parallel6: see parallel1
# parallel7: see parallel1
# parallel8: see parallel1
# parallel9: see parallel1
# dongle: Enable dongle
parallel1 = printer
parallel2 = disabled
parallel3 = disabled
parallel4 = disabled
parallel5 = disabled
parallel6 = disabled
parallel7 = disabled
parallel8 = disabled
parallel9 = disabled
dongle = false
[printer]
# printer: Enable printer emulation.
# dpi: Resolution of printer (default 360).
# width: Width of paper in 1/10 inch (default 85 = 8.5'').
# height: Height of paper in 1/10 inch (default 110 = 11.0'').
# printoutput: Output method for finished pages:
# png : Creates PNG images (default)
# ps : Creates PostScript
# bmp : Creates BMP images (very huge files, not recommended)
# printer : Send to an actual printer in Windows (specify a printer, or Print dialog will appear)
# multipage: Adds all pages to one PostScript file or printer job until CTRL-F2 is pressed.
# device: Specify the Windows printer device to use. You can see the list of devices from the Help
# menu ('List printer devices') or the Status Window. Then make your choice and put either
# the printer device number (e.g. 2) or your printer name (e.g. Microsoft Print to PDF).
# Leaving it empty will show the Windows Print dialog (or '-' for showing once).
# docpath: The path (directory) where the output files are stored.
# fontpath: The path (directory) where the printer fonts (courier.ttf, ocra.ttf, roman.ttf, sansserif.ttf, script.ttf) are located.
# openwith: Start the specified program to open the output file.
# openerror: Start the specified program to open the output file if an error had occurred.
# printdbcs: Allows DOSBox-X to print Chinese/Japanese/Korean DBCS (double-byte) characters when these code pages are active.
# If set to auto (default), this is enabled only for the TrueType font (TTF) output with the DBCS support enabled.
# Only applicable when using a DBCS code page (932: Japanese, 936: Simplified Chinese; 949: Korean; 950: Traditional Chinese)
# Possible values: true, false, 1, 0, auto.
# shellhide: If set, the command window will be hidden for openwith/openerror options on the Windows platform.
# timeout: (in milliseconds) if nonzero: the time the page will be ejected automatically after when no more data arrives at the printer.
printer = true
dpi = 360
width = 85
height = 110
printoutput = png
multipage = false
device = -
docpath = .
fontpath = FONTS
openwith =
openerror =
printdbcs = auto
shellhide = false
timeout = 0
[dos]
# xms: Enable XMS support.
# xms handles: Number of XMS handles available for the DOS environment, or 0 to use a reasonable default
# shell configuration as commands: Allow entering dosbox-x.conf configuration parameters as shell commands to get and set settings.
# This is disabled by default to avoid conflicts between commands and executables.
# It is recommended to get and set dosbox-x.conf settings using the CONFIG command instead.
# Compatibility with DOSBox SVN can be improved by enabling this option.
# hma: Report through XMS that HMA exists (not necessarily available)
# hard drive data rate limit: Slow down (limit) hard disk throughput. This setting controls the limit in bytes/second.
# Set to 0 to disable the limit, or -1 (default) to use a reasonable limit.
# The disk I/O performance as in DOSBox SVN can be achieved by setting this to 0.
# floppy drive data rate limit: Slow down (limit) floppy disk throughput. This setting controls the limit in bytes/second.
# Set to 0 to disable the limit, or -1 (default) to use a reasonable limit.
# The disk I/O performance as in DOSBox SVN can be achieved by setting this to 0.
# ansi.sys: If set (by default), ANSI.SYS emulation is on. If clear, ANSI.SYS is not emulated and will not appear to be installed.
# NOTE: This option has no effect in PC-98 mode where MS-DOS systems integrate ANSI.SYS into the DOS kernel.
# log console: If set, log DOS CON output to the log file. Setting to "quiet" will log DOS CON output only (no debugging output).
# Possible values: true, false, 1, 0, quiet.
# share: Reports SHARE.EXE as resident and provides functions such as file-locking and record-locking, although not all SHARE functions are emulated.
# file access tries: If a positive integer is set, DOSBox-X will try to read/write/lock files directly on mounted local drives for the specified number of times without caching before failing on Windows systems.
# For networked database applications (e.g. dBase, FoxPro, etc), it is strongly recommended to set this to e.g. 3 for correct operations.
# network redirector: Report DOS network redirector as resident. This will allow the host name to be returned unless the secure mode is enabled.
# You can also directly access UNC network paths in the form \\MACHINE\SHARE even if they are not mounted as drives on Windows systems.
# Set either "ipx=true" in [ipx] section or "ne2000=true" in [ne2000] section for a full network redirector environment.
# minimum mcb free: Minimum free segment value to leave free. At startup, the DOS kernel will allocate memory
# up to this point. This can be used to deal with EXEPACK issues or DOS programs that cannot
# be loaded too low in memory. If you want more free conventional memory to be reported,
# you can for example set its value to 1.
# ems: Enable EMS support. The default (=true) provides the best
# compatibility but certain applications may run better with
# other choices, or require EMS support to be disabled (=false)
# to work at all.
# Possible values: true, emsboard, emm386, false, 1, 0.
# umb: Enable UMB support.
# quick reboot: If set, the DOS restart call will reboot the emulated DOS (integrated DOS or guest DOS) instead of the virtual machine.
#
# ver: Set DOS version. Specify as major.minor format. A single number is treated as the major version (compatible with LFN support). Common settings are:
# auto (or unset) Pick a DOS kernel version automatically
# 3.3 MS-DOS 3.3 emulation (not tested!)
# 5.0 MS-DOS 5.0 emulation (recommended for DOS gaming)
# 6.22 MS-DOS 6.22 emulation
# 7.0 MS-DOS 7.0 (or Windows 95 pure DOS mode) emulation
# 7.1 MS-DOS 7.1 (or Windows 98 pure DOS mode) emulation
# Long filename (LFN) support will be enabled with a reported DOS version of 7.0 or higher with "lfn=auto" (default).
# Similarly, FAT32 disk images will be supported with a reported DOS version of 7.1 or higher.
#
# lfn: Enable long filename support. If set to auto (default), LFN support is enabled if the reported DOS version is at least 7.0.
# If set to autostart, the built-in VER command won't activate/deactivate LFN support according to the reported DOS version.
# Possible values: true, false, 1, 0, auto, autostart.
# fat32setversion: Whether DOSBox-X should automatically set the reported DOS version to 7.0/7.10 when it is less than 7.0/7.10 and mounting LBA/FAT32 disk images is requested.
# If set to "ask", a popup message will show up to ask whether DOSBox-X should automatically change the reported DOS version in order to mount the disk image.
# Possible values: ask, auto, manual.
# shellhigh: Load the DOSBox-X command shell into the upper memory when the UMB is available.
# If set to auto (default), it is enabled if the reported DOS version is at least 7.0.
# Possible values: true, false, 1, 0, auto.
# automount: Enable automatic drive mounting in Windows.
# automountall: Automatically mount all available Windows drives at start.
# Possible values: true, false, 1, 0, quiet.
# mountwarning: If set, a warning message will be displayed while trying to auto-mount your Windows host drives.
# autofixwarning: If set to true or both, DOSBox-X shows messages while trying to automatically fix the "Packed file is corrupt" error.
# If set to false or none, DOSBox-X will not show such messages on the screen when the error occurred.
# If set to "a20fix" or "loadfix", DOSBox-X will show the message for the a20fix or the loadfix only.
# Possible values: true, false, 1, 0, both, a20fix, loadfix, none.
# startcmd: Enable START command to start programs to run on the host system. On Windows host programs or commands may also be launched directly.
# starttranspath: Specify whether DOSBox-X should automatically translate all paths in the command-line to host system paths when starting programs to run on the host system.
# startwait: Specify whether DOSBox-X should wait for the host system applications after they are started.
# startquiet: If set, before launching host system applications to run on the host DOSBox-X will not show messages like "Now run it as a Windows application".
# vmware: Enable VMware interface emulation including guest mouse integration (when used along with e.g. VMware mouse driver for Windows 3.x).
# int33: Enable INT 33H for mouse support.
# keyboardlayout: Language code of the keyboard layout (or none).
# customcodepage: Set a custom code page for CHCP command and specify a SBCS code page file, following the standard SBCS code page format.
# Examples of SBCS code pages are available from the Unicode Consortium website: https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/PC/
# dbcs: Enable DBCS table and Chinese, Japanese, Korean support for the TrueType font (TTF) output.
# CAUTION: Some software will crash without the DBCS table, including the Open Watcom installer.
# dos clipboard device enable: If enabled, a DOS device will be added for bidirectional communications with the shared clipboard.
# Setting to "read" will only allow read access, and setting to "write" will only allow write access.
# Setting to "full" or "true" enables both; setting to "false" or "disabled" disables the access or device.
# The default device name is CLIP$, but can be changed with the "dos clipboard device name" setting below.
# dos clipboard device name: Set DOS device name (up to 8 characters) for bidirectional communications with the shared clipboard.
# If unset or invalid, the default name CLIP$ will be used (e.g. "TYPE CLIP$" shows the clipboard contents).
# It has no effect if "dos clipboard device enable" is disabled, and it is deactivated if the secure mode is enabled.
# dos clipboard api: If set, DOS APIs for communications with the Windows clipboard will be enabled for shared clipboard communications.
#
# Advanced options (see full configuration reference file [dosbox-x.reference.full.conf] for more details):
# -> badcommandhandler; hma allow reservation; special operation file prefix; drive z is remote; drive z convert fat; drive z expand path; drive z hide files; hidenonrepresentable; hma minimum allocation; dos sda size; hma free space; cpm compatibility mode; minimum dos initial private segment; minimum mcb segment; enable dummy device mcb; maximum environment block size on exec; additional environment block size on exec; enable a20 on windows init; zero memory on xms memory allocation; vcpi; unmask timer on disk io; zero int 67h if no ems; zero unused int 68h; emm386 startup active; zero memory on ems memory allocation; ems system handle memory size; ems system handle on even megabyte; umb start; umb end; kernel allocation in umb; keep umb on boot; keep private area on boot; private area in umb; autoa20fix; autoloadfix; startincon; int33 hide host cursor if interrupt subroutine; int33 hide host cursor when polling; int33 disable cell granularity; int 13 disk change detect; int 13 extensions; biosps2; int15 wait force unmask irq; int15 mouse callback does not preserve registers; filenamechar; collating and uppercase; con device use int 16h to detect keyboard input; zero memory on int 21h memory allocation; pipe temporary device
#
xms = true
xms handles = 0
shell configuration as commands = false
hma = true
hard drive data rate limit = -1
floppy drive data rate limit = -1
ansi.sys = true
log console = false
share = true
file access tries = 0
network redirector = true
minimum mcb free = 0
ems = true
umb = true
quick reboot = false
ver =
lfn = auto
fat32setversion = ask
shellhigh = auto
automount = true
automountall = false
mountwarning = true
autofixwarning = false
startcmd = false
starttranspath = true
startwait = true
startquiet = false
vmware = true
int33 = true
keyboardlayout = auto
customcodepage =
dbcs = true
dos clipboard device enable = false
dos clipboard device name = CLIP$
dos clipboard api = true
[ipx]
# ipx: Enable ipx over UDP/IP emulation.
ipx = false
[ne2000]
# ne2000: Enable NE2000 Ethernet emulation. Either pcap or slirp backend can be used, switchable via "backend" option.
# Settings for the pcap and slirp backends can be found in the [ethernet, pcap] and [ethernet, slirp] sections.
# Once properly set, load the NE2000 packet driver inside DOSBox-X with base address and interrupt specified below.
# nicbase: The base address of the NE2000 board.
# nicirq: The interrupt it uses. Note serial2 uses IRQ3 as default.
# macaddr: The MAC address the emulator will use for its network adapter.
# If you have multiple DOSBox-Xes running on the same network,
# this has to be changed for each. AC:DE:48 is an address range reserved for
# private use, so modify the last three number blocks, e.g. AC:DE:48:88:99:AB.
# backend: The backend (either pcap or slirp is supported) used for the NE2000 Ethernet emulation.
# If set to "auto", then "slirp" is selected when available, otherwise "pcap" is selected when available.
# NE2000 Ethernet emulation will be disabled if no backend is available (or the specified backend if unavailable).
# Possible values: pcap, slirp, auto, none.
ne2000 = false
nicbase = 300
nicirq = 3
macaddr = AC:DE:48:88:99:AA
backend = slirp
[ethernet, pcap]
# realnic: Specifies which of your host network interfaces is used for pcap.
# Write 'list' here to see the list of devices from the Help
# menu ('List network interfaces') or from the Status Window.
# Then make your choice and put either the interface number
# (e.g. 2) or a part of your adapters name (e.g. VIA here).
# timeout: Specifies the read timeout for the device in milliseconds for the pcap backend, or the default value will be used.
realnic = 01
timeout = default
[ethernet, slirp]
# ipv4_network: The IPv4 network the guest and host services are on.
# ipv4_netmask: The netmask for the IPv4 network.
# ipv4_host: The address of the guest on the IPv4 network.
# ipv4_nameserver: The address of the nameserver service provided by the host on the IPv4 network.
# ipv4_dhcp_start: The start address used for DHCP by the host services on the IPv4 network.
#
# Advanced options (see full configuration reference file [dosbox-x.reference.full.conf] for more details):
# -> restricted; disable_host_loopback; mtu; mru; tcp_port_forwards; udp_port_forwards
#
ipv4_network = 10.0.2.0
ipv4_netmask = 255.255.255.0
ipv4_host = 10.0.2.2
ipv4_nameserver = 10.0.2.3
ipv4_dhcp_start = 10.0.2.15
[ide, primary]
# enable: Enable IDE interface
# pnp: List IDE device in ISA PnP BIOS enumeration
#
# Advanced options (see full configuration reference file [dosbox-x.reference.full.conf] for more details):
# -> irq; io; altio; int13fakeio; int13fakev86io; enable pio32; ignore pio32; cd-rom spinup time; cd-rom spindown timeout; cd-rom insertion delay
#
enable = true
pnp = true
[ide, secondary]
enable = true
pnp = true
[ide, tertiary]
enable = false
pnp = true
[ide, quaternary]
enable = false
pnp = true
[ide, quinternary]
enable = false
pnp = true
[ide, sexternary]
enable = false
pnp = true
[ide, septernary]
enable = false
pnp = true
[ide, octernary]
enable = false
pnp = true
[fdc, primary]
# enable: Enable floppy controller interface
# pnp: List floppy controller in ISA PnP BIOS enumeration
# mode: Floppy controller mode. What the controller acts like.
# ps2 PS/2 mode (most common)
# ps2_model30 PS/2 model 30
# at AT mode
# xt PC/XT mode
#
# Advanced options (see full configuration reference file [dosbox-x.reference.full.conf] for more details):
# -> irq; io; dma; int13fakev86io; instant mode; auto-attach to int 13h; chip
#
enable = false
pnp = true
mode = ps2
[4dos]
rem = This section is the 4DOS.INI file, if you use 4DOS as the command shell
[config]
# rem: Records comments (remarks).
# break: Sets or clears extended CTRL+C checking.
# Possible values: on, off.
# numlock: Sets the initial state of the NumLock key.
# Possible values: on, off.
# shell: Specifies the command shell (COMMAND.COM or 4DOS.COM).
# dos: Reports whether DOS occupies HMA and allocates UMB memory (if available).
# fcbs: Number of FCB handles available to DOS programs (1-255).
# files: Number of file handles available to DOS programs (8-255).
# country: Country code for date/time/decimal formats and optionally code page for TTF output and language files.
# lastdrive: The maximum drive letter (A-Z) that can be accessed by programs.
# Possible values: a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z.
rem = This section is DOS's CONFIG.SYS file, not all CONFIG.SYS options supported
break = off
numlock =
shell =
dos = high, umb
fcbs = 100
files = 200
country =
lastdrive = a
set path = Z:\;Z:\SYSTEM;Z:\BIN;Z:\DOS;Z:\4DOS;Z:\DEBUG;Z:\TEXTUTIL
set prompt = $P$G
set temp =
install =
installhigh =
device =
devicehigh =
[autoexec]
# Lines in this section will be run at startup.
# You can put your MOUNT lines here.
================================================
FILE: tools/toolchain-djgpp.cmake
================================================
#
# CMake toolchain file for DJGPP. Usage:
#
# 1. Download and extract DGJPP
# 2. Place this file into the root folder of DJGPP
# 3. When configuring your CMake project, specify the toolchain file like this:
#
# cmake -DCMAKE_TOOLCHAIN_FILE=/path/to/djgpp/toolchain-djgpp.cmake -B build
#
set (CMAKE_SYSTEM_NAME linux-djgpp)
set (DJGPP TRUE)
# specify the cross compiler
if(WIN32)
set (CMAKE_C_COMPILER ${CMAKE_CURRENT_LIST_DIR}/djgpp/bin/i586-pc-msdosdjgpp-gcc.exe)
set (CMAKE_CXX_COMPILER ${CMAKE_CURRENT_LIST_DIR}/djgpp/bin/i586-pc-msdosdjgpp-g++.exe)
else()
set (CMAKE_C_COMPILER ${CMAKE_CURRENT_LIST_DIR}/djgpp/bin/i586-pc-msdosdjgpp-gcc)
set (CMAKE_CXX_COMPILER ${CMAKE_CURRENT_LIST_DIR}/djgpp/bin/i586-pc-msdosdjgpp-g++)
endif()
# where is the target environment
set (CMAKE_FIND_ROOT_PATH ${CMAKE_CURRENT_LIST_DIR})
# search for programs in the build host directories
set (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
# for libraries and headers in the target directories
set (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set (CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
# add sys-include dir to c/c++ flags by default. ides using
# compile-commands.json can't otherwise find includes.
set (CMAKE_C_FLAGS -I${CMAKE_CURRENT_LIST_DIR}/djgpp/i586-pc-msdosdjgpp/sys-include/)
set (CMAKE_CXX_FLAGS -I${CMAKE_CURRENT_LIST_DIR}/djgpp/i586-pc-msdosdjgpp/sys-include/)
gitextract_b7a8hb4w/
├── .clang-format
├── .github/
│ └── FUNDING.yml
├── .gitignore
├── .vscode/
│ ├── cmake-kits.json
│ ├── launch.json
│ ├── run-windows.bat
│ ├── settings.json
│ └── tasks.json
├── CMakeLists.txt
├── LICENSE
├── README.md
├── assets/
│ └── test.txt
├── doc/
│ └── examples/
│ ├── debugger.c
│ └── keyboard.c
├── download-tools.sh
├── src/
│ ├── gdbstub.h
│ └── main.c
└── tools/
├── dosbox-x.conf
└── toolchain-djgpp.cmake
SYMBOL INDEX (34 symbols across 4 files)
FILE: doc/examples/debugger.c
function foo (line 11) | int foo(int a, int b) {
function main (line 19) | int main(void) {
FILE: doc/examples/keyboard.c
type keyboad_state (line 21) | typedef struct keyboard_state {
function keyboard_handler (line 29) | void keyboard_handler() {
function setup_keyboard (line 50) | void setup_keyboard() {
function reset_keyboard (line 63) | void reset_keyboard() {
function main (line 68) | int main(void) {
FILE: src/gdbstub.h
function _gdb_start (line 24) | void _gdb_start() {}
function _gdb_checkpoint (line 25) | bool _gdb_checkpoint() { return false; }
function _gdb_start (line 27) | void _gdb_start() {}
function _gdb_checkpoint (line 28) | bool _gdb_checkpoint() { return false; }
type gdb_register (line 65) | enum gdb_register { EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, EIP, EFLAGS,...
type gdb_context (line 70) | typedef struct gdb_context {
function serial_port_init (line 84) | static void serial_port_init() {
function serial_port_putc (line 95) | static void serial_port_putc(char c) { _bios_serialcom(_COM_SEND, 0, c); }
function serial_port_getc (line 97) | static int serial_port_getc() {
function set_mem_error (line 101) | static void set_mem_error(void) { ctx.mem_error = 1; }
function hex_to_byte (line 103) | static int hex_to_byte(char ch) {
function hex_to_int (line 113) | static int hex_to_int(char **ptr, int *intValue) {
function mem_get_byte (line 131) | static int mem_get_byte(char *addr) { return *addr; }
function mem_set_byte (line 133) | static void mem_set_byte(char *addr, int val) { *addr = val; }
function exception_save_registers (line 168) | static void exception_save_registers(void) {
function exception_sigsegv_handler (line 212) | static void exception_sigsegv_handler(int exception_number) {
function exception_handler (line 218) | static void exception_handler(int exception_number) {
function exception_to_signal (line 224) | static int exception_to_signal(int exception_number) {
function exception_init (line 279) | static void exception_init() {
function exception_dispose (line 320) | static void exception_dispose() {
function _gdb_start (line 329) | void _gdb_start(void) {
function gdb_write_packet (line 391) | static void gdb_write_packet(unsigned char *buffer) {
function gdb_loop (line 416) | void gdb_loop(int exception_number) {
function gdb_tick_handler (line 617) | void gdb_tick_handler(void) {
function _gdb_checkpoint (line 624) | bool _gdb_checkpoint() {
FILE: src/main.c
function set_video_mode (line 10) | void set_video_mode(int mode) {
function main (line 16) | int main(void) {
Condensed preview — 19 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (150K chars).
[
{
"path": ".clang-format",
"chars": 1991,
"preview": "# Generated from CLion C/C++ Code Style settings\nBasedOnStyle: LLVM\nAccessModifierOffset: -4\nAlignAfterOpenBracket: Alig"
},
{
"path": ".github/FUNDING.yml",
"chars": 20,
"preview": "github: [badlogic]\n\n"
},
{
"path": ".gitignore",
"chars": 75,
"preview": "build\ntools/djgpp\ntools/dosbox-x\ntools/gdb\n.cache\ntools/capture\nserial.txt\n"
},
{
"path": ".vscode/cmake-kits.json",
"chars": 114,
"preview": "[\n {\n \"name\": \"djgpp\",\n \"toolchainFile\": \"${workspaceFolder}/tools/toolchain-djgpp.cmake\"\n }\n]"
},
{
"path": ".vscode/launch.json",
"chars": 1173,
"preview": "{\n \"version\": \"0.2.0\",\n \"configurations\": [\n {\n \"type\": \"gdb\",\n \"request\": \"attach\",\n"
},
{
"path": ".vscode/run-windows.bat",
"chars": 175,
"preview": "cmake --build build\r\nIF %ERRORLEVEL% NEQ 0 (Exit /b 1)\r\ndos\\tools\\dosbox-x\\dosbox-x -conf dos\\tools\\dosbox-x.conf -fastl"
},
{
"path": ".vscode/settings.json",
"chars": 132,
"preview": "{\r\n\t\"C_Cpp.intelliSenseEngine\": \"disabled\",\r\n\t\"cmake.configureOnOpen\": true,\r\n\t\"editor.formatOnSave\": true,\r\n\t\"editor.ta"
},
{
"path": ".vscode/tasks.json",
"chars": 1210,
"preview": "{\n \"version\": \"2.0.0\",\n \"tasks\": [\n {\n \"type\": \"shell\",\n \"label\": \"task-dosbox-debug\""
},
{
"path": "CMakeLists.txt",
"chars": 548,
"preview": "cmake_minimum_required(VERSION 3.7)\nproject(dos-app)\n\nset(CMAKE_GENERATOR Ninja)\nset(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)"
},
{
"path": "LICENSE",
"chars": 1302,
"preview": "BSD 2-Clause License\n\nCopyright (c) 2022, Mario Zechner\n\nRedistribution and use in source and binary forms, with or with"
},
{
"path": "README.md",
"chars": 13242,
"preview": "# DOS demo/game development template\n\n# Attention: for an even better experience, use my new [VSCode DOS development ext"
},
{
"path": "assets/test.txt",
"chars": 10,
"preview": "Hello DOS!"
},
{
"path": "doc/examples/debugger.c",
"chars": 653,
"preview": "#include \"pc.h\"\n#include <stdio.h>\n#include <stdlib.h>\n\n// To add the code of the debugger to your program, define\n// GD"
},
{
"path": "doc/examples/keyboard.c",
"chars": 2268,
"preview": "#include \"pc.h\"\n#include \"sys/segments.h\"\n#include \"unistd.h\"\n#include <dpmi.h>\n#include <stdio.h>\n#include <stdint.h>\n\n"
},
{
"path": "download-tools.sh",
"chars": 3769,
"preview": "#!/bin/bash\nset -e\n\nrm -rf tools/gdb\nrm -rf tools/djgpp\nrm -rf tools/dosbox-x\n\nbase_url=\"https://marioslab.io/dump/dos\"\n"
},
{
"path": "src/gdbstub.h",
"chars": 17607,
"preview": "#pragma once\r\n\r\n#include <stdbool.h>\r\n\r\n#ifdef NDEBUG\r\n#define gdb_start()\r\n#define gdb_checkpoint()\r\n#else\r\n#ifdef DJGP"
},
{
"path": "src/main.c",
"chars": 1262,
"preview": "#include <bios.h>\n#include <dpmi.h>\n#include <sys/nearptr.h>\n#include <stdlib.h>\n#include <stdio.h>\n\n#define GDB_IMPLEME"
},
{
"path": "tools/dosbox-x.conf",
"chars": 96556,
"preview": "# This is the configuration file for DOSBox-X 2022.09.0. (Please use the latest version of DOSBox-X)\n# Lines starting wi"
},
{
"path": "tools/toolchain-djgpp.cmake",
"chars": 1409,
"preview": "#\n# CMake toolchain file for DJGPP. Usage:\n#\n# 1. Download and extract DGJPP\n# 2. Place this file into the root folder o"
}
]
About this extraction
This page contains the full source code of the badlogic/dos-dev-template GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 19 files (140.2 KB), approximately 36.7k tokens, and a symbol index with 34 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.