BASIC-DOS consists of a boot sector and three files, which must be in the root directory of the startup diskette:
| File | Contents |
|---|---|
| (boot sector) | Loads the other files and starts the drivers |
| BASDEV.COM | Built-in device drivers, followed by their initialization code (devinit) |
| BASDOS.COM | The DOS kernel, followed by its initialization code (sysinit) |
| COMMAND.COM | The BASIC-DOS Command Shell (the default SHELL) |
The startup diskette may also contain CONFIG.SYS (see Configuring BASIC-DOS) and HELP.TXT (used by the HELP command).
Unlike PC DOS, there is no separate BIOS-level file (IO.SYS or IBMBIO.COM); BASIC-DOS relies on the ROM BIOS for low-level services, and its device drivers fill the role of IBMBIO.COM. The initialization code at the end of BASDEV.COM and BASDOS.COM is discarded once it’s done, and its memory is reused.
The boot sector runs in three parts:
Sysinit then:
- boot key (after the first console is open, so that a conflict with PATHCHAR= can be reported)Successive loads of the same program (eg, COMMAND.COM in several sessions) are served from a cached copy of the file, so the disk is read only once.
The key pressed at the boot prompt is saved in BOOT_KEY (52Dh), which sysinit copies to key_boot. These keys have special meanings:
| Key | Effect |
|---|---|
| Esc | Boots from the hard disk instead |
- |
Makes - the switch character, like SWITCHAR=- |
In DEBUG builds, the DOS_UTL_DPRINTF messages are printed on the DEBUG$ device, if the DEBUG.COM driver is installed. The tracing messages are generated only by MAXDEBUG builds (which aren’t built by default): each line of a BAS or BAT file as code is generated for it, each variable added or removed, each token parsed, each operator and number during code generation, every DOS function call, cluster reads, new PSPs, CLOCK$ tick calculations, and null characters (extended keys) read from CON. DEBUG builds print only unsupported DOS function calls.
| Address | Contents |
|---|---|
| 0000h | Interrupt vector table |
| 0400h | ROM BIOS data area |
| 0500h | BASIC-DOS low memory data: drive info, device list head (50Ah), DPT (522h), BOOT_KEY (52Dh), DDINT entry points (530h) |
| 0540h | First disk buffer (16-byte header and 512-byte sector; initially the FAT sector the boot code read) |
| 0750h | Second disk buffer (header and 512-byte sector) |
| 0960h | BIOS_END: device drivers (BASDEV.COM), followed by the DOS kernel (BASDOS.COM) |
| Resident tables: SCBs, BPBs, current directories, SFBs, and any extra disk buffers (BUFFERS=) | |
| Memory pool: MCB chain (programs, COMMAND.COM blocks, and free memory) |
All the disk buffers form a circular chain, ordered from most to least recently used. Each buffer holds a FAT sector or a directory sector (file data goes directly through the disk drivers), and when a sector isn’t already in a buffer, the least recently used buffer is reused, except that the most recently used buffer of the other kind (FAT or directory) is never reused, so that DOS can keep working with a directory entry while it updates the FAT (and vice versa).
The memory pool is a chain of Memory Control Blocks (see MCB), as in PC DOS. DOS_MEM_ALLOC normally allocates from the bottom of the first free block that’s big enough, but with MCBTYPE_HIGH (80h) set in AL, it allocates from the top of the last one. COMMAND.COM allocates its code, text, variable, and string blocks from the top, so that the memory it frees before running a program stays contiguous.
Unlike PC DOS, BASIC-DOS doesn’t give a program all available memory: a COM program gets its file size plus a heap (at least MINHEAP, or 1K, or more if the program requests it; see COMDATA), or at least half of the available memory if it has no COMDATA, and an EXE program gets its image size plus the minimum its header requests (EXE_PARASMIN), plus as much of the maximum (EXE_PARASMAX) as is available, up to 64K (or the minimum, if larger). This leaves memory available for other sessions, while still giving programs like LINK.EXE (which sizes its stack from the memory it’s given) enough room to run.
Each session is described by a Session Control Block (see SCB), which records the session’s console context, standard file handles, current PSP, stack, DTA, CTRL-C and exit handlers, and wait state.
Sessions are scheduled preemptively: hardware interrupt handlers (eg, the CLOCK$ driver’s timer handler) exit through DDINT_LEAVE, which can switch to another runnable session. A session that’s waiting for something (eg, keyboard input or a timer) calls DOS_UTL_WAIT with a wait ID, which makes it non-runnable until a driver calls DOS_UTL_ENDWAIT with the same ID.
Code that must not be interrupted by a session switch can use DOS_UTL_LOCK and DOS_UTL_UNLOCK; a switch requested while the session is locked is deferred until it’s unlocked.
Each session has its own console context (if it was given one by a CONSOLE= line), and keyboard input goes to the context with focus (Shift-Tab switches the focus). Sessions without a console of their own (eg, the sessions that run the commands of a pipeline) use the handles supplied in their Session Parameter Block (see SPB). A zero-length write to a pipe marks the end of its data (a reader then gets 0 bytes once the pipe is empty); the command shell does this after the first command of a pipeline, and when a session ends, DOS does the same to its output handle if it’s a character device, so every command of a pipeline sees the end of its input. Similarly, a zero-length read from a pipe means that its reader is done, and when a session ends, DOS does that to its input handle if it’s a character device; from then on, writes to the pipe fail (with a write fault) instead of waiting for room.
| Vector | Use |
|---|---|
| 00h, 04h | Divide error and overflow: the program is terminated (exit types EXTYPE_DVERR and EXTYPE_OVERR) |
| 01h, 03h | Single-step and breakpoint (used by DEBUG builds) |
| 20h | Terminate program |
| 21h | DOS functions (see DOS Functions) |
| 22h | Exit address |
| 23h | CTRL-C handler address |
| 24h | Critical error handler address (see Critical Errors) |
| 25h, 26h | Absolute disk read and write (not supported; open the volume as a file instead, as described in File Handles) |
| 27h | Terminate and stay resident (not implemented yet) |
| 28h | Idle notification (default handler only) |
| 29h | Fast console output (installed by the CON driver) |
| 2Ah-2Fh | Reserved (default handlers only) |
| 30h | CALL 5 far jump (overlaps vector 31h) |
| 32h | BASIC-DOS utility functions (see Utility Functions) |
Programs should use DOS_MSC_SETVEC (25h) to set vectors 22h, 23h, and 24h, which BASIC-DOS stores in the current session’s SCB, rather than writing the vector table directly.
Copyright (c) 2020-2026 Jeff Parsons Released under MIT License