MS-DOS 6.22 DOSKEY Macro Processing Explained
This article explores how MS-DOS 6.22 processes command macros stored
in DOSKEY memory, covering its memory architecture, interrupt
interception, lookup routines, and parameter substitution mechanisms.
When a user defines and runs a macro, DOSKEY operates at the system
level to capture keyboard input, scan internal memory buffers, parse
variable tokens, and redirect expanded commands back to the
COMMAND.COM command interpreter.
Memory Allocation and Storage Architecture
When loaded into conventional or upper memory, DOSKEY installs itself
as a Terminate-and-Stay-Resident (TSR) program. By default, it allocates
a dedicated 512-byte internal buffer—configurable via the
/BUFSIZE switch—which holds both command history and active
macros.
Macros are stored in a contiguous, byte-oriented table within DOSKEY’s resident data segment. Each macro entry consists of:
- The macro name in plain text, terminated by a null byte
(
0x00) or an equals sign (=). - The expansion string containing the commands and metadata symbols.
- A final null terminator denoting the end of that specific macro record.
Because memory is shared with the command history, defining new macros shrinks the available capacity for previous command recall.
Input Interception via Interrupt 21h
To detect when a macro is invoked, DOSKEY hooks MS-DOS Interrupt 21h
(the DOS system API). It specifically monitors Function 0Ah (Buffered
Keyboard Input), which is the standard system call
COMMAND.COM uses to retrieve a line of text from standard
input (CON).
- Interception: When the user types a command and
presses Enter, DOSKEY’s custom INT 21h handler intercepts the call
before
COMMAND.COMreceives the raw string. - Parsing the Primary Token: DOSKEY reads the user's input buffer, strips leading whitespace, and isolates the first word (the potential command or macro name).
- Table Scanning: The TSR performs a linear, case-insensitive search through its macro memory block, comparing the initial token against stored macro labels. If no match is found, DOSKEY simply updates its command history buffer and passes the unmodified input back to the original INT 21h handler.
Token Expansion and Parameter Parsing
When DOSKEY finds a matching label, it replaces the typed command
with the expanded string stored in memory. During this substitution
phase, it parses specific dollar-sign ($)
meta-characters:
- Positional Arguments (
$1through$9): DOSKEY scans the remainder of the user’s typed line, separates parameters delimited by spaces or tabs, and substitutes them into corresponding$1–$9tokens within the macro string. - Global Arguments (
$*): Any text typed after the macro name is captured in its entirety and substituted wherever$*appears. - Redirection and Piping (
$G,$L,$B): Because standard symbols like>,<, and|would be interpreted immediately during macro creation, DOSKEY preserves them internally as meta-characters and converts them back to ASCII redirection symbols ($Gto>,$Lto<,$Bto|) during expansion.
Multi-Command Processing
($T)
DOSKEY macros support command chaining through the $T
delimiter. Because MS-DOS is single-tasking and COMMAND.COM
expects a single command per input line:
- When
$Tis encountered, DOSKEY splits the macro expansion into discrete commands. - The first command segment is written into the buffer provided by
COMMAND.COM's INT 21h Function 0Ah request. - DOSKEY retains the remaining command segments in an internal execution queue.
- On subsequent INT 21h Function 0Ah calls from
COMMAND.COM, DOSKEY checks its execution queue before reading the keyboard. If queued commands remain, it automatically populates the input buffer with the next command segment without prompting the user.
Final Execution Hand-off
Once the macro text is fully expanded and formatted, DOSKEY writes
the completed string directly into the calling program's memory buffer
(provided by COMMAND.COM via the registers passed to INT
21h). DOSKEY sets the buffer's character count byte, restores CPU
registers, and executes an IRET (Interrupt Return)
instruction. COMMAND.COM processes the resulting string as
if it had been typed manually at the command prompt.