Wang Disk Basic Cheat Sheet

Wang Disk BASIC is a complicated arrangement of three basic access modes mixed in with some unusual syntax and age-appropriate limitations. This quirkiness is part of the charm of a BASIC dialect, and Wang has plenty if it.

If you never used Wang BASIC, or it has been a long time, it would be way too frustrating to expect you to guess how to do some simple operations or to figure it out by reading a large manual.

The purpose of this page is to describe a few key Wang Disk BASIC concepts and the most important commands. If you really want to understand Wang Disk BASIC, then you'll just have to read the manual.

Here are the topics explained on this page.

Before going any further, here is the super-condensed cheat sheet:

Disk BASIC Concepts

Wang Disk BASIC offers three access modes to the contents of a disk. The BASIC exposes a lot of details of the disk system, and the burden is on the programmer/program to manage things more so than any modern OS, and even as compared to Microsoft Disk BASIC circa 1976.

All disks, from the smallest floppy to the largest hard disk uses a 256 byte sector as the atomic unit of transfer. Disks start with sector 0 and increase up to the limit of the number of sectors on the disk. A disk can have at most 32768 sectors (65536 in BASIC-2), or about 8 MB (16 MB). Although programs can build whatever file access mechanisms they want via reading and writing arbitrary sectors, all the intrinsically supported file mechanisms assume a file is allocated in a contiguous range of sector addresses. That is, a file begins at sector N, the next sector is at N+1, the next at sector N+2, etc., up to N+k-1, where k is the number of sectors in the file.

Perhaps the Wang file allocated policy should be viewed more like a random access tape. Once a file occupies a section of the disk, it can only be expanded by moving the file to a larger open range of sectors on the disk, or by overwriting whatever is on the sectors immediately following the file. The programmer must spend a lot more time managing the details of the file policy on the disk.

The three access modes are

DC mode reserves a fixed number of sectors at the start of the disk to contain a catalog of files on the disk. The catalog is flat, i.e., there are no nested directories -- just a list of filenames and locations.

In DC mode, the first 16 bytes of the first sector of a disk contains a small amount of data describing a few key parameters of that disk's structure for use by the DC commands. If a disk won't be operated on by the DC commands, then this information doesn't have to be present and all sectors of the disk can be used by the program.

The first parameter sets aside sectors 0 through N-1 of the disk to contain a list of the files on the disk.

The second parameter allows a programmer to tell the DC commands to use only the first N sectors of the disk, leaving any remaining sectors for self-managed file operation.

Wang disk controllers supported up to four disk drives, arranged as two pairs. To keep things simple, the rest of this document assumes two disk drives attached to a given controller.

The first of each pair was called the fixed disk, and the second was the removable disk, referenced as F and R respectively. Although this naming was appropriate for the first disk drives produced by Wang, it didn't have any bearing on reality for other models of disk controllers and disk drives (e.g., a dual floppy system). Perhaps it is best to think of disk F as "drive 0" and disk R as "drive 1".

Typographic Conventions

In all of the syntax examples below, the following typographic conventions have been followed to make it clear what is literal syntax and what is a dummy field representing the type of thing that needs to be entered.

{THIS|THAT}

represents that either THIS or THAT needs to be typed, but not both.

[OPTIONAL]

represents that the parameter OPTIONAL can be there but doesn't have to be.

italics

represents something that should be replaced with a number or string.

Most commands allow an optional controller I/O address to be specified, in hex. This parameter is shown as "[/dev]" below. If the address isn't specified, it was whatever the most recent "SELECT DISK" command specified. If that command hasn't been performed, then it defaults to /310.

Initialize a Disk

SCRATCH DISK {F|R} [/dev,] [LS=m,] END=n

After a new disk has been created or reformatted, all the sectors will be set to 00 bytes. This command initializes sector zero of the disk with a small record of how the disk is structured for use by the DC (catalog) commands. If a disk will not be operated upon by a DC command, then the SCRATCH DISK command doesn't need to be performed on a disk.

Either the fixed (F) or removable (R) disk drive connected to the controller must be specified.

Optionally, a disk controller address can be specified, in hex.

Optionally, the LS parameter specifies how many sectors should be set aside to hold the catalog of filenames. Each sector set aside contains the name and parameters for 16 files. However, the first sector contains room for only 15 names since the first slot is reserved to hold the disk structure bytes.

Examples:

SCRATCH DISK F END=300

Initialize the disk in the first drive, using the first 300 sectors to hold the file catalog and all the cataloged files. The default number (24) of sectors are set aside for holding the file catalog, and the rest, 300-24, are for holding files.

SCRATCH DISK F LS=4, END=300

Initialize the disk in the first drive, using the first 300 sectors to hold the file catalog and all the cataloged files. Four 4 sectors are set aside for holding the file catalog, and the rest, 300-4, are for holding files. These four catalog sectors can hold up to 16*4-1, or 63, files. In practice, it is like that fewer files can be held, as there is a hash that maps which sector a given filename will be stored.

SCRATCH DISK F/320, LS=4, END=300

This is like the last one, except it is the first drive of the disk controller at address /320.

SCRATCH DISK R LS=64, END=15000

This initializes the second drive of the pair of the controller at the default address (/310 by default, unless the SELECT DISK command has changed it). 64 sectors are set aside for the catalog, and 15000 sectors total are assigned for the catalog plus the files themselves.

List Contents of Disk

LIST DC {F|R} [/dev]

This command is used to print the contents of the disk catalog. An example catalog might be

INDEX SECTORS = 00004
END CAT. AREA = 00300
CURRENT END   = 00068

NAME     TYPE  START   END   USED
PRIMES     P   00004  00006  00003
TEST       P   00007  00009  00003
FOOTBALL   P   00010  00039  00030
MSTRMIND  SP   00040  00068  00029

In this example, there are four programs. The first part of the output lists the information established by the SCRATCH DISK command, namely that the first four sectors have been reserved for holding the disk catalog, and that anything after sector 300 is reserved for use by the programs. The first three entries have type "P" meaning they are executable programs, and the fourth entry, MSTRMIND, has type "SP" indicating that the program has been SCRATCH'd (erased), and thus can't be executed. Although this disk doesn't have any data files, they are indicated with a "D" in the TYPE column.

The START column indicates which sector the file begins on; END indicates which sector is the last of the file, and USED is how many of the sectors are in use by that file. It is possible to pre-allocate space for a file on the disk and not use all of it, in which case USED is less than (END-START+1).

Examples:

LIST DC F

List the files in the first drive of the controller at the default disk address (/310 normally).

LIST DC R

List the files in the second drive of the controller at the default disk address (/310 normally).

LIST DC F /320

List the files in the first drive of the controller at address /320.

Load a Program from Disk

LOAD DC {F|R} [/dev,] "filename"

This command is used to read a program of a specified name from the disk.

Examples:

LOAD DC F "PRIMES"

LOAD DC F /320, "FOOTBALL"

LOAD DC R "TEST"

Save a Program to Disk

SAVE DC {F|R} [/dev,] "filename"

This command is used to save a program to the disk with the specified name. You can't save a program using a name that is already on the disk.

Examples:

SAVE DC F "PRIMES"

SAVE DC F/320, "PRIMES"

SAVE DC R "PRIMES"

Erase a Program from the Disk

SCRATCH {F|R} [/dev,] "filename"

This command actually doesn't erase the program or release the area for further use. Instead, it simply marks the file for later removal. In the meantime, the program can't be loaded. When a "LIST DC" command is performed, scratched files show up with an "S" as part of the TYPE field.

SCRATCH'd programs get removed via a MOVE operation.

Examples:

SCRATCH F "FOOTBALL"

SCRATCH F/320, "PRIMES"

SCRATCH R/330, "BACKUP"

Housekeeping

MOVE {FR|RF}

COPY {FR|RF} (first sector,last sector)

In both of these commands, the drive letter is the source drive and the second letter is the destination drive.

MOVE operates on cataloged disks and copies all non-scratched programs from one drive to the other drive, skipping any that are marked as being SCRATCH'd. A common operation is to MOVE from the F drive to a scratch disk in the R drive, and then to immediately MOVE or COPY it back to the F drive.

COPY just does a blind sector by sector cloning from one drive to the other drive. As such, it works for both cataloged and non-cataloged disks. The command requires specifying the range of sectors to copy. For the common case of cloning a disk, first sector will invariably be 0. The second sector is determined by the size of the disk. Use the disk inspector to find how many sectors the disk has, then use one less for the second sector.

For instance to clone an 8" disk (which has 1024 sectors) in the first drive to another disk in the second drive, issue the command

COPY FR(0,1023)

Examples:

MOVE FR

MOVE RF

COPY FR(0,1023)

COPY RF(0,1023)

Disk Addressing

When Wang BASIC was created in the early 70s, disk drive capacity was low. Floppy disks had about 1000 sectors, and hard disks had about 10,000 (2.5MB) or 20,000 (5MB). Wang was smart and had a high level protocol between the CPU and the disk drive, which meant they could make a wide range of disk drives that could plug and play with the same CPU without requiring custom drivers and whatnot. This was important because Wang BASIC was burned into custom ROMs and were not easily field upgradable.

A given disk controller could support up to four disk drives, and system could support up to three disk controllers. Because the first generation of disk drives had one non-removable disk platter (the fixed disk) and one removable platter, DCF (fixed) and DCR (removable) were used to distinguish between a pair of drives. These names, however, quickly became anachronistic. The 0x40 bit of the device address was used to distinguish between the primary and secondary pair of drives connected to a given controller.

Device address First drive Second drive Third drive Fourth drive
0x10 DCF/310 DCR/310 DCF/350 DCR/350
0x20 DCF/320 DCR/320 DCF/360 DCR/360
0x30 DCF/330 DCR/330 DCF/370 DCR/370

Note the device address is specified as /xyz. The actual device address of a disk controller is limited to be hex 10, 20, or 30; this is the "yz" part above (modulo the 0x40 bit, which distinguishes between drive pairs). What is the "x" part? Conceptually it is a device type (eg, "3" means disk device, "2" means printer, etc). But in practice, Wang BASIC wasn't too picky. That is, although "DCF/310" was the canonical way of addressing the first drive of the first controller, DCF/... and DCR/... ignored the first digit. "DCF/010", "DCF/110", "DCF/210", ..., "DCF/F10" all mean the same thing. However, there is also no advantage to using something else, and everybody simply used /3xy.

Although using a high level disk protocol was smart, Wang was dumb in that the sector addresses used by that protocol were limited to 15 bits, which meant a given disk could support a maximum of 32768 sectors, or 8 MB. Very quickly that became a problem. Rather than switching to a 24 bit sector address in their protocol (which they did do, eventually), Wang's engineers made another hack that, at least in the short term, solved two problems.

Another designator, "DCT", was added. With this parameter, the specified address supplied all the information not only to address a given drive uniquely, but to address multiple platters on a given drive. Whereas the device type digit (the "3" in /310) didn't mean anything when using DCF/310 and DCR/310, for DCT/xyz, that first digit is meaningful with DCT.

DCT/3xy means access the "fixed" disk at device address xy, and DCT/Bxy means access the "removable" disk at device address xy. That is DCT/3xy is identical to DCF/3xy, and DCT/Bxy is synonymous with DCR/3xy. That means any drive could be selected by changing only the device address, and not having to also twiddle the "F" vs "R" parameter.

But even more importantly, the form DCT/Dxy was used to address the controller at device address x0, platter "y". For example, "DCT/D13" means address the controller at address 10, platter 3. That meant drives of up to 16 platters could be supported, allowing one drive to have up to 128 MB.

Here is a revised table showing both the DCF/DCR addressing style and, on the next line, the DCT-equivalent.

Device address First drive Second drive Third drive Fourth drive
0x10 DCF/310 DCR/310 DCF/350 DCR/350
DCT/310 DCT/B10 DCT/350 DCT/B50
0x20 DCF/320 DCR/320 DCF/360 DCR/360
DCT/320 DCT/B20 DCT/360 DCT/B60
0x30 DCF/330 DCR/330 DCF/370 DCR/370
DCT/330 DCT/B30 DCT/370 DCT/B70

The 2200 Disk Memory Reference Manual, Chapter 6, especially section 6.7, describes the use of the DCT parameter in detail.