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.
- Disk BASIC Concepts
- Initialize a Disk
- List Contents of Disk
- Load a Program from Disk
- Save a Program to Disk
- Erase a Program from the Disk
- Housekeeping
- Disk Addressing
Before going any further, here is the super-condensed cheat sheet:
- Type LIST DC F to list the contents of the left disk drive
- Type LIST DC R to list the contents of the right disk drive
- Type LOAD DC F "filename" to read the named file from the left drive
- Type LOAD DC R "filename" to read the named file from the right drive
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
- BA -- block access mode. This mode allows an arbitrary raw 256 byte sector to be read or written.
- DA -- data access mode. This mode is used to read or write streams of data to contiguous sectors forming a file. Three bytes of each sector contain file meta information, such as whether the block marks the start of the file, is the middle of a file, or is the end of a file. Also, the remaining 253 bytes consist of a continuous stream of <TAG><DATA> pairs, where the TAG byte (such as "number" or "string") specify how to interpret the following DATA bytes.
- DC -- Catalog file access (DC). The focus of this page is on the third mode, the catalog file commands. This provide the most convenient mechanism for using disks for all but the power user. The rest of this document discusses only DC mode. Please read the Wang Disk BASIC reference manual to learn more about the other modes.
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 number of sectors set aside for the file catalog
- the number of sectors set aside for cataloged files
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.