/ as the option character in CP/M
One piece of folklore I see cropping up on the Net from time to time involves the directory separator in DOS. In general, it goes like this:
- Why is the DOS directory separator character "\", rather than "/" as in UNIX?
- Because in DOS 1.x, before directories were added, "/" was used as an option character. For the sake of compatibility DOS 2.x kept "/" for options and had to find another character for the directory separator.
- So why did DOS 1.x use "/" for options?
- Because the option character in CP/M was "/".
Unfortunately for this view of history, it wasn't.
- CP/M itself has no concept of 'the option character'. Unlike DOS, there is no system call to get the correct character to use (cf INT 21h/AX=3700h). The character each program uses is defined by that program. The same thing is true of UNIX; but unlike in UNIX, the authors of different programs chose different characters.
- Also unlike DOS, the system doesn't have any sort of enforcement of whether a filename is valid. In CP/M 2 there is no call to convert a filename to an FCB, so each program must do its own; the CCP passes two parsed filenames to programs, but the programs can't call its parser so any other names have to be done by them - not necessarily to the same rules.
- Since programs don't agree what characters can and can't be in a filename, they also don't agree what counts as an option character (since it makes sense for an option character to be one that can't be in filenames).
At the time DOS was written, the latest version of CP/M was version 2. The following programs were provided with the system:
CCP parses the command line to extract the name of the program to run, and one or two additional filenames. To the CCP, the following characters are not valid for use in filenames:
space = _ . : ; < >
(colon and dot obviously are used in filenames, but they are used to separate sections of the name rather than being part of the name itself).
Note that from the CCP's point of view, "/" is a valid filename character; it's quite easy to create a file containing it:
A>SAVE 0 CP/M.TXT
whereas "_" isn't:
A>SAVE 0 CP_M.TXT
creates a file called "CP"; the "_" is treated as a separator.
The CP/M 2 assembler does not use an option character at all. It reads its options from the filename it was passed:
assembles x:FILENAME.ASM, writing its output file to y:FILENAME.HEX and a listing to z:FILENAME.PRN. x is a standard drive letter; y can be a drive letter, or "Z" not to produce Hex output; and z can be a drive letter, X for the screen or Z not to produce a listing.
PIP does its own filename parsing. Its list of characters not valid for filenames is:
space = _ . : ; < > [ ]
The two extra characters [ and ] are used to mark the start and end of an option string. In PIP, the option string follows a source filename without a space.
All options but two are either single characters or single characters followed by decimal integers. The exceptions are:
- Start copying when string is encountered. Note that the ^Z actually means that character 26 has to be in the command line.
- Stop copying when string is encountered.
STAT uses the parsed filenames passed to it by the CCP. However, the second filename (if not blank) is treated as an option. The first character of it is ignored; the manuals instruct the user to use '$', so that probably counts as the option lead-in character. The options include "$R/W" and "$R/O" (ie, they rely on the CCP to treat "/" as a valid filename character).
The CP/M 2 manual says that an unambiguous filename cannot contain any of these characters:
< > . , ; : = ? * [ ] % | ( ) / \
- but as listed above, this is not adhered to by the programs themselves.
DUMP, DDT, ED, MOVCPM, LOAD, SUBMIT, SYSGEN, XSUB
These programs do not take options; they rely on the parsed filenames passed to them by the CCP.
So, of all the programs supplied with CP/M, none uses the "/" character as an option leadin. Then where did the slash come from?
A hasty search of the SIG/M library (archived on the CP/M CDROM) suggests that one early program that used "/" was DCHBYE (a program that allows a CP/M program to be remotely controlled by a modem). The original program was written by Dave Jaffe in January 1979; DCHBYE dates from 17 October 1980. The convention seems to be confined to BYE until SUPERSUB (18 February 1981) is released; and by the time we reach ZCPR (1982-1983), it's used in a lot of programs.
It may be that the convention did originate with BYE, but there's another possibility. At the time MS-DOS was written, Microsoft sold various language compilers (BASIC, FORTRAN, M80, etc.). These tools were influential; some accounts say that BDOS call 28h was added specifically to support Microsoft FORTRAN, and the .REL file format they use became the standard format for CP/M assemblers and linkers. And the option character used by these programs is... "/".