Skip to content
FreeDOSDeep Dive Published Updated 7 min readViews unavailable

FreeDOS INT 21h AH=37h: Querying and Changing the Switch Character

Query or set FreeDOS's switch character with INT 21h AH=37h, understand MODE integration, and avoid assuming every program honors it.

DOS command lines commonly use / to introduce switches, but that character is not always fixed. FreeDOS exposes an INT 21h switch-character service at AH=37h: subfunction AL=00h queries the current switch character, and AL=01h sets it from DL. FreeDOS’s kernel source labels this service undocumented, so code should treat the behavior as a compatibility interface that requires target testing rather than assuming every DOS clone or application implements it identically.

; Query the active switch character.
mov  ax, 3700h
int  21h
; FreeDOS returns the switch character in DL and AL=00h.

; Example: request '-' as the switch character.
mov  ax, 3701h
mov  dl, '-'
int  21h
; FreeDOS sets the switch character and returns AL=00h.

In FreeDOS’s current kernel source, AL=00h copies the kernel’s switch character to DL and clears AL; AL=01h stores the input DL and returns zero. Other subfunctions take the invalid-function path. This direct source is the basis for the register description here. If the code must run under multiple DOS implementations, probe support and preserve a fallback rather than treating FreeDOS internals as a universal contract.

What the switch character does and does not mean

The switch character is the DOS convention used to distinguish command options from ordinary arguments. A user may want a hyphen switch style for software that already uses forward slashes in filenames, or an application may expect the traditional slash. The FreeDOS MODE command documents SWITCHAR as a console setting, allowing an operator to inspect or alter the value using the system configuration command rather than a custom program.

Changing this global DOS setting does not rewrite program source code. A third-party executable may parse / itself, may hard-code -, or may use an independent option parser. A shell’s own command syntax and an application’s syntax can differ. Test each command and application that matters after the change; do not infer that all switches now accept both forms.

The setting also does not turn a switch character into a filesystem escape. A path parser and an option parser are separate. If a program treats leading punctuation as an option before examining whether an argument is a filename, pass the path in the documented way for that application or use a different invocation. Never assume that changing SWITCHAR makes every slash-containing path safe to pass as an unquoted argument.

Configure and inspect using MODE

FreeDOS MODE documentation includes MODE CON SWITCHAR=value in its console option syntax. For example, the following asks MODE to configure a hyphen:

MODE CON SWITCHAR=-

The exact spelling, accepted value, and persistence behavior should be checked with MODE /? on the installed version. Treat this as a runtime configuration change unless the FreeDOS setup documents a boot-time configuration mechanism for the target release. Query with INT 21h AX=3700h before and after applying a change; record the returned character instead of assuming MODE accepted it.

In an application, the query call is often more useful than changing global state. A well-behaved parser can read the active convention and present help that matches it. But do not use AH=37h to guess an application’s parser: the API reports a kernel setting, not a capability negotiation with every resident program.

A defensive application pattern

Before issuing the query or set function, preserve any registers your own calling convention requires. DOS register-preservation rules are function-specific, so consult the target API reference rather than assuming every register survives. If the program only needs to display an example in help text, query the current value and print it; if it must change the value, store the prior setting and restore it when the operation ends if the program’s contract requires temporary behavior.

1. Query with AX=3700h.
2. Check whether the target kernel reports the expected supported result.
3. Save DL before changing anything.
4. Set with AX=3701h and DL=the requested character.
5. Query again and verify the actual returned value.
6. Restore the prior value if the change was intended to be temporary.

That sequence is a conceptual checklist, not a substitute for an assembly language ABI. A DOS application shares global machine state with the shell, TSRs, and later child programs. A change that appears local to one utility can surprise an unrelated command launched afterward. Keep the changed interval short and restore in every normal exit path. If termination can occur through a control-break or critical error handler, include those paths in the design.

Compatibility and support diagnostics

When a command rejects an option after the switch character changes, isolate whether the cause is the global setting or the command’s parser. First query the kernel value. Then test a simple built-in command with its documented option form. Finally test the application with a harmless operation. Do not test by combining a new switch character with a destructive command.

Record the FreeDOS kernel version, MODE version, command interpreter, active SWITCHAR, and the exact application executable. If a program is a DOS extender, runs under a Windows DOS box, or uses its own option library, the kernel-level value might not describe the whole environment. The correct behavior is empirical for that supported combination.

The switch-character call is also different from changing keyboard layout or code page. Those affect character interpretation and display/input mapping; AH=37h chooses a command-switch convention. A keyboard layout that produces - in an unexpected place is not repaired by changing the option prefix, and a command parsing - does not prove that text encoding is correct.

Environment inheritance deserves attention. A shell-level change can persist after the program that made it exits because the kernel setting is shared, not attached to a process. If a utility changes the switch character and then launches another program, that child may observe a different global convention. Conversely, a program that changes it temporarily and terminates abnormally may leave later commands in a surprising state. Prefer not to change it unless the program owns the interactive session; otherwise query it and adapt help text or parsing without mutation.

If a command fails after an operator changed the prefix, avoid “fixing” the command line by adding both / and - forms speculatively. Some parsers interpret both as options, some treat punctuation as filename content, and some accept only one convention. Test a harmless help or version switch for each executable. Then validate file arguments containing punctuation and drive paths. Capture the SWITCHAR value together with VER /R, MODE output, and the application build in any reproducible support case.

The service is small enough to hide in compatibility code, but any implementation that reads or writes global DOS state must define what happens when support is missing. For a query failure, retain the documented default or report that the parser could not inspect the setting. For a set failure, stop before launching commands that depend on the new prefix. Never continue under the assumption that a failed set “probably worked.”

Acceptance checks

For a system configuration change, test in a disposable session: query the initial value, set the alternative, verify the returned character, exercise a harmless command, and restore the original. For an application, test on every supported kernel and verify the failure path when the API is unavailable or returns an unsupported-function response. Include a path containing a slash or punctuation relevant to the application’s parser.

Use AH=37h only when the application has a clear reason to inspect or temporarily change the DOS convention. Prefer the operator’s existing setting and avoid global changes in utilities that do not own the shell. The function is small, but its effects can escape the program through shared DOS state. Query, validate, minimize, and restore rather than assuming / is universal or that changing the kernel value rewrites every parser.

Related:

Sources:

Comments