BASIC-DOS

A PCjs Retro-Programming Project

BASIC-DOS is on Twitter Project maintained by jeffpar

BASIC-DOS Manual

BASIC-DOS Programming

The BASIC-DOS programming language is based on the BASIC language of the IBM PC (Microsoft BASIC), and can be used to build BASIC programs directly from the BASIC-DOS command prompt. Topics include:

Programs

A BASIC program is a text file with a BAS or BAT extension, which you can create with any text editor. BASIC-DOS can also load BAS files saved by IBM PC BASIC (BASICA) or GW-BASIC, which are usually tokenized (a binary format); they’re converted back to text as they’re loaded, so LIST displays them as BASICA would. Protected BAS files (saved with the P option) can’t be loaded. Each line contains one or more commands, separated by colons, and any line may begin with a line number, which serves as a label for GOTO, GOSUB, and other statements that transfer control. Lines that aren’t the target of a transfer don’t need line numbers, and line numbers don’t need to be in order.

REM Print the powers of 2 below 1000
DEFINT A-Z
LET N = 1
10 PRINT N;
N = N * 2
IF N < 1000 THEN GOTO 10

Programs can use any BASIC-DOS command (eg, DIR or COLOR), and can run other programs (including other BAT and BAS files) by name. Keywords and names can be typed in upper or lower case. REM, or an apostrophe outside of quotes, starts a remark that continues to the end of the line.

To run a program, type its name (see Running Programs). BASIC-DOS compiles the program into 8086 machine code as it runs (see BASIC Compilation), which is why BASIC-DOS programs run much faster than Microsoft BASIC programs. As in Microsoft BASIC, a statement BASIC-DOS doesn’t support causes a syntax error when the program reaches it.

When a BAS program that you ran from the prompt ends, it remains loaded, along with its functions and variables, so you can LIST it, examine its variables at the prompt (eg, PRINT N), or RUN it again. NEW erases the program and its variables.

BAT files differ from BAS files in two ways: BAT files can ECHO their lines as they run (after ECHO ON), and BAT files don’t remain loaded after they end. See Batch Files for how BASIC-DOS batch files differ from PC DOS batch files.

Batch Files

A BAT file is a BASIC-DOS program too, so it can contain any BASIC-DOS command or BASIC statement, and it’s compiled the same way. This makes BASIC-DOS batch files more powerful than PC DOS batch files. Apart from ECHO and the @ prefix, PC DOS batch language features aren’t supported, and won’t be; use these BASIC features instead:

PC DOS BASIC-DOS
:LOOP labels, and GOTO LOOP Line numbers (eg, 10 DIR), and GOTO 10
ECHO message PRINT "message" (ECHO only accepts ON or OFF)
IF ERRORLEVEL 1 GOTO FAIL (true if ERRORLEVEL is 1 or more) IF ERRORLEVEL >= 1 THEN GOTO 100
SET N=5 and %N% (environment variables) BASIC variables (eg, N = 5 and PRINT N)
%1 through %9 (replaceable parameters) ARG$(1) through ARG$(9)
IF EXIST file, IF "%1"=="x" IF EXISTS("file") THEN ... (see EXISTS), IF ARG$(1) = "x" THEN ... (any BASIC expression can be used)
CALL OTHER (to run another batch file and then continue) OTHER (a batch file always continues after running another one)
FOR %%F IN (*.TXT) DO ... DIR$("*.TXT") and then DIR$ in a loop, until it returns an empty string
SHIFT ARG$(N), with a variable N
PAUSE PRINT "Press any key" : K$ = INPUT$(1) (see INPUT$)

ECHO and the @ prefix work as they do in PC DOS, except that every BAT file starts with ECHO OFF, and echoed lines are displayed with a @ in front instead of a prompt (see ECHO). Output redirection works for BASIC statements, too, using :> (or :>>) at the end of a line (eg, PRINT "done" :>> LOG.TXT); see Pipes and Redirection. REM (or an apostrophe) starts a remark.

For example, this batch file runs a program up to three times, stopping if the program reports an error:

@ECHO OFF
REM Run SLEEP three times, stopping if it fails
N = 1
10 SLEEP 1
IF ERRORLEVEL THEN PRINT "SLEEP failed" : END
N = N + 1
IF N <= 3 THEN GOTO 10
PRINT "SLEEP ran"; N - 1; "times"

Unlike a BAS file, a BAT file doesn’t remain loaded when it ends.

Command Arguments

There are three kinds of commands, and each kind takes its arguments differently:

  • DOS commands (built-in commands like DIR, COPY, DEL, KILL, LOAD, RUN, and SAVE; see Disk Commands and System Commands) take PC DOS-style arguments, separated by spaces, and use them as typed. A file name (or path, or filespec) can be written as is (eg, TYPE PRIMES.BAS), in quotes (TYPE "PRIMES.BAS"), or as a string variable (TYPE F$), whose value is used, and so can a redirection file name (eg, DIR > F$; see Pipes and Redirection). Expressions aren’t evaluated, so assign one to a variable first (eg, F$ = "TEMP" + N$ : KILL F$). Other arguments, such as line numbers (LIST 10-20), keywords (HELP MID$), and dates (DATE 10-24-26), are always used as typed.
  • BASIC statements and functions (eg, OPEN, CHAIN, DIR$, and EXISTS) take expressions, so a file name must be a string: a quoted name, a string variable, or any string expression (eg, OPEN "DATA" + N$ FOR INPUT AS #1). For example, the DOS command MERGE PART2 works, but the CHAIN MERGE statement needs CHAIN MERGE "PART2".
  • External commands (programs such as FORMAT and VI; see External Commands) receive their arguments as typed, so a string variable isn’t replaced by its value (eg, FORMAT D$ doesn’t format the drive in D$), and there’s currently no way to pass a variable’s value to one. BAS and BAT programs read their arguments with ARG$, which removes any quotes; other programs may not.

A DOS command treats any file name that looks like a string variable (a letter, followed by letters or digits, ending with $) as a variable, in BAS and BAT files and at the prompt, where variables remain until the next program runs. A variable that doesn’t exist is empty, as in BASIC, and an empty string variable is the same as no file name (eg, DIR E$ lists all files when E$ is empty). Only a whole argument is replaced, so B:F$ and F$(1) are file names, not variables. To use a file name that looks like a string variable, put it in quotes (eg, TYPE "TEST$").

Variables and Types

Variable names begin with a letter, followed by any letters and digits, and an optional type suffix. BASIC-DOS has three types of values:

Type Suffix Range
Integer % 32-bit, from -2147483648 to 2147483647 (MAXINT)
Double # or ! 64-bit IEEE 754 floating-point, with about 15 significant digits
String $ 0 to 255 characters

A variable without a suffix uses the default type for its first letter, which is double unless DEFINT or DEFSTR changes it (eg, DEFINT A-Z makes all unsuffixed variables integers). BAT files start with an implied DEFINT A-Z, so their default type is integer. If floating-point support is disabled, the default type is integer.

The type is part of a variable’s identity, so A%, A#, and A$ are three different variables. Likewise, after DEFINT A-Z and then DEFDBL A-Z, A refers to a new variable, separate from the A used before (which is still A%).

Numeric variables start with a value of zero, and string variables start empty. Values are converted automatically between integers and doubles as needed; a double converted to an integer is rounded (with halves rounded away from zero, so 2.5 becomes 3 and -2.5 becomes -3).

Integer arithmetic is much faster than floating-point arithmetic, so programs that don’t need fractions should begin with DEFINT A-Z.

The predefined variables ERRORLEVEL and MAXINT can’t be assigned new values.

Constants

  • Integers: 123, -5
  • Doubles: 1.5, .25, 6.02E23, 1D-10; any number with a decimal point or exponent is a double
  • Hexadecimal and octal integers: &H1F, &O17
  • Strings: "Hello"; a string at the end of a line doesn’t need a closing quote

A numeric constant can also have a type suffix: # or ! makes it a double (eg, 2!), and % keeps it an integer (eg, 7%).

Arrays

Arrays of integers, doubles, or strings can have up to 255 dimensions, and are created with DIM:

DIM SCORES%(100), NAMES$(10), GRID(9,9)

An array that’s used without DIM is created automatically, with a largest subscript of 10 in each dimension. The smallest subscript is 0, unless OPTION BASE 1 is used. ERASE deletes arrays, so that they can be dimensioned again.

Each array must fit in a single 64K memory block.

Operators

Operators are listed below from highest to lowest precedence; operators on the same line have the same precedence and are evaluated from left to right. Parentheses can be used to change the order of evaluation.

Operator Meaning
^ Exponentiation
-, + Negation, unary plus
*, / Multiplication, division
\ Integer division (eg, 7\2 is 3)
MOD Remainder of integer division (eg, 7 MOD 3 is 1)
+, - Addition (or string concatenation), subtraction
<<, >> Arithmetic shift left, right (eg, 1<<4 is 16)
=, <>, <, >, <=, >= Relational (== is the same as =)
NOT Bitwise NOT
AND Bitwise AND
OR Bitwise OR
XOR Bitwise exclusive OR
EQV Bitwise equivalence
IMP Bitwise implication

Relational operators return -1 for TRUE and 0 for FALSE, and they compare strings as well as numbers. The logical operators operate on all 32 bits of their integer operands, so NOT 0 is -1 (TRUE).

The / operator always produces a double (eg, 7/2 is 3.5), unless floating-point support is disabled. The << and >> operators are BASIC-DOS extensions.

Functions

BASIC-DOS includes many predefined functions, and DEF defines new functions, which can be single-line expressions or multi-line blocks:

DEF CUBE(X) = X^3
DEF HYP(A,B)
LET C = A*A + B*B
RETURN SQR(C)

Function names don’t need to begin with FN.

Control Flow

  • IF expression THEN statements [ELSE statements]
  • GOTO label and ON expression GOTO labels
  • GOSUB label and RETURN, and ON expression GOSUB labels
  • FOR … NEXT and WHILE … WEND
  • END (or STOP), and CHAIN to replace the program with another BAS file (or merge one into it)

Press Ctrl-C to stop a running program.

Error Handling

When a runtime error occurs (eg, “Illegal function call” or “Subscript out of range”), the program ends with an error message, unless an ON ERROR GOTO handler is active. The handler can use ERR to get the error number, and RESUME label to continue the program. Error numbers are the same as Microsoft BASIC’s, and ERROR n simulates an error.

Other errors are found when a line is compiled, just before it first runs (see BASIC Compilation): “Syntax error”, “Type mismatch” (eg, A$ = 5 or PRINT "A" + 1), “NEXT without FOR”, and “WEND without WHILE”. When compiling reaches the end of the program (eg, when the program runs past its last line, or a loop is skipped), a FOR or WHILE that was never closed is a “FOR without NEXT” or “WHILE without WEND” error, reported with the line of the FOR or WHILE, and a missing label is an “Undefined line number” error. A compile-time error ends the program, even if an ON ERROR handler is active, and its message includes the line number (eg, “NEXT without FOR in line 120”): the line’s label, if it has one, or else its position in the file.

When a command fails, it displays an error message, and as in PC DOS, the program (including a BAT file) continues with its next command. A command fails if it can’t do what was asked: for example, a program that can’t be found (“Unable to find”) or opened (“Unable to open”), a file that can’t be found, copied, or deleted, a directory that can’t be changed to, created, or removed, an invalid date or time, or a BAS or BAT file that ends with a syntax error. A failed command sets ERRORLEVEL to 1, and a successful one sets it to 0, so a program can check whether a command worked (eg, IF ERRORLEVEL THEN END). A program that runs and then returns a non-zero exit code hasn’t failed; ERRORLEVEL is its exit code. ON ERROR doesn’t apply to failed commands, and a CHAIN that can’t load its file still ends the program (although a missing file is the runtime error “File not found”, which ON ERROR can handle).

Graphics and Sound

On a color adapter, SCREEN 1 or 2 selects a graphics mode, where the graphics commands (CIRCLE, DRAW, GET, LINE, PAINT, PRESET, PSET, and PUT) can be used. PLAY plays music, and SOUND plays tones.

When a BAS program that used a graphics mode ends, BASIC-DOS restores the video mode it started with (even if the program returned to a text mode first), along with the colors the session had then (so a program’s COLOR, like COLOR 7,0,0, can’t leave the session’s border black); otherwise, text-mode changes (eg, WIDTH 40) persist, as in Microsoft BASIC.

On a machine with too little memory for all of COMMAND.COM (eg, 64K), the graphics, mouse, and sound statements are not available (see Low Memory).

Low Memory

On a machine with too little memory for all of COMMAND.COM (eg, 64K), BASIC-DOS loads only its core, and MEM displays Core functions only (see HELP CORE). The following are then unavailable, and using one of them displays “Not enough memory”:

  • The graphics commands: CIRCLE, DRAW, PAINT, PRESET, PSET, VIEW, WINDOW, and the graphics forms of GET, LINE, and PUT, and the PMAP and POINT functions
  • The MOUSE command and function
  • The sound commands: PLAY and SOUND
  • PRINTF, LPRINT, LLIST, the LPOS function, the MID$ statement, KEY n,string, and WIDTH device,width
  • The program editing commands AUTO, DELETE, and EDIT (lines can still be entered and deleted by number)
  • The file statements (OPEN, CLOSE, FIELD, GET, PUT, LSET, RSET, RESET, IOCTL, and the # forms of INPUT, LINE INPUT, PRINT, and WRITE) and file functions (CVD, CVI, CVL, EOF, INPUT$, IOCTL$, LOC, LOF, MKD$, MKI$, and MKL$)
  • The DOS statement and function
  • CHAIN, MERGE, RUN file, and RUN in a program
  • LOAD of tokenized BAS files (eg, those saved by BASICA or GW-BASIC)

Everything else, including INPUT and LINE INPUT from the keyboard and WRITE to the screen, is still available. HELP CORE lists the same keywords (HELP.TXT marks each one with a “+” after its category tag).

Differences from Microsoft BASIC

BASIC-DOS runs many IBM PC BASIC programs unchanged (eg, DONKEY.BAS, from the original PC DOS 1.00 diskette), but there are differences:

  • Programs are text files, which can be edited with a text editor, or typed at the prompt with line numbers (see Entering Programs) and saved with SAVE; there’s no RENUM command, and tokenized BAS files saved by BASICA and GW-BASIC can be loaded, but not saved
  • Line numbers are optional, and only needed on lines that are targets of GOTO, GOSUB, etc
  • Single-precision values are double-precision (DEFSNG is the same as DEFDBL), and integers are 32-bit, not 16-bit
  • Function names don’t need to begin with FN, and functions can have multiple lines
  • PRINT commas print a tab instead of advancing to the next print zone
  • Up to 4 files can be open at once, random access records are limited to 255 bytes, MKD$ and CVD use IEEE doubles (not MBF), MKS$, CVS, and the OPEN “mode”,#n,file form aren’t supported
  • INPUT doesn’t display “Redo from start”; missing items are empty (or zero), and extra items are ignored
  • KILL, LOAD, MERGE, RUN, and SAVE are DOS commands, so their file names don’t need quotes, but can’t be expressions (eg, KILL "TEMP" + N$ is a syntax error; see Command Arguments)
  • RANDOMIZE without a seed uses the BIOS tick count instead of prompting for a seed
  • Not supported yet: PCOPY, RUN line, and RUN’s R option (which keeps files open)
  • RESUME requires a label: RESUME without one (or with 0) and RESUME NEXT aren’t supported (see RESUME)
  • KEY n,string is accepted, but the function keys always return their key codes (as after KEY n,””), and WIDTH device,width is accepted, but output to a device is never broken into lines
  • PRINT USING isn’t supported (and won’t be); use PRINTF USING instead (see How to replace PRINT USING)

« System CommandsConfiguring BASIC-DOS »

Copyright (c) 2020-2026 Jeff Parsons Released under MIT License