Using DriveWire
Introduction
DriveWire provides many services to your CoCo. These include disk drives that can mount disk image files, serial ports that can be used to communicate over the internet, a real time clock, MIDI, and printing support.
Instances
Instances
The DriveWire server can provide any number of instances. Each instance supports one CoCo via one connection, such as a serial link or TCP/IP connection. A single server can run one or many instances at the same time. Each instance has its own set of virtual disks, ports, etc.
There are multiple interfaces which can be used to configure and control these services. The most basic tool for these tasks is the OS-9 command dw which comes on a DriveWire bootable NitrOS-9 image. Modern implementations (like the MicroPython or Swift versions) also provide web-based or native graphical dashboards for management.
Starting the DriveWire Server
Starting the server depends on your specific implementation. See the Installation Guide for platform-specific launch commands.
Disk Buffers
When you insert a disk into one of DriveWire's drives, the contents of the source image are read into a buffer. All reads and writes done from the CoCo operate on the buffer contents, not directly on the source. This is similar to how applications such as word processors work: you load a file into the word processor and make changes to an in memory copy of the document.
Similar to a word processor's "auto save" function, DriveWire will periodically write any changes made to the buffer back to the source in some situations. You can load a disk image from a wide variety of sources, and some are not writable or do not support random access operations. If DriveWire cannot do random access writes to the source, you will have to use the 'dw disk write' or the equivalent function in your server's dashboard to save any changes you make to the buffer.
This diagram displays how the various disk settings effect the operation of the buffers. These settings can be specified using a dashboard, using various 'dw disk' commands, or stored along with a source path in a configuration file.
(Image: dw_buffer.gif)
The 'dw' utility runs in OS-9, it can be found on the latest NitrOS-9 disks for DriveWire. The sub commands and options available in dw provide many informational displays and give you a way to configure every aspect of DriveWire operation right from your CoCo.
All of the sub commands and options to dw may be abbreviated to their shortest unique form. For example, the command "dw server show threads" can be given as "dw s s t".
For quick help on what sub commands are available, type "dw" by itself. For help on an individual sub command, type "dw subcommand", for instance "dw disk".
HDBDOSMode
HDBDOS for DriveWire allows access to DriveWire disks under DECB.
In DriveWire 3, DriveWire disks 0 - 3 are treated as a virtual hard drive containing 256 disk images. You can communicate with only one of these virtual hard drives at a time, switching between them using the command "DRIVE #x". Within these large files you access the 256 individual disks with the standard DRIVE command.
DriveWire defaults to identical behavior for compatibility.
DW3/Default mode:
(Image: hdbdos_dw3.gif)
Modern DriveWire Features
Modern DriveWire servers have an alternate mode that can be enabled by specifying:
<HDBDOSMode>true</HDBDOSMode>
inside any instance section or diskset definition. You can also toggle this mode on and off using the server's management interface.
HDBDOSMode uses the sector number contained in each request sent from HDBDOS, and not the drive number, to determine which .dsk file to access. The result is a one to one mapping between disks on the CoCo and disks in DriveWire. The "DRIVE #" command has no effect when DriveWire is in this mode.
HDBDOSMode:
(Image: hdbdos_dw.jpg)
Copying disks between real floppies and DriveWire disks
HDBDOS allows you to access real floppy drives using the DRIVE OFF command. This will allow access to real drives 0-3 and still provide DriveWire drives 4-255. When in HDBDOSMode, you can then copy (for instance) a real floppy in drive 0 to a DriveWire disk in drive 4 using a command like:
BACKUP 0 To 4
To write a .dsk image to a real floppy, use:
BACKUP 4 to 0
Using DW3 style files containing multiple floppy images
If you have existing 'hard disk' images, containing 256 floppies in a single file, you can still use them in current DriveWire servers. In fact, you can do some things with them that were impossible in legacy versions.
The simplest way to use these types of images is to leave HDBDOS mode turned off. Current DriveWire servers will behave exactly like DW3 did in this mode, and you can use the multi-disk images as you always have.
However, you can now copy between disk images, something that was impossible in DW3. You can also mount a single disk or set of disks out of one image and other disks from another image, or mix some single disk images with a multi disk image. The key to doing all of this is the new HDBDOS mode, combined with the sector offset setting.
When in HDBDOS mode, the server ignores the drive # sent in I/O requests and instead uses the absolute sector of the request to determine which server drive will handle it. This means that you can load a regular single disk .dsk image into any of the 256 drives, and access it from the coco simply as that same drive. To copy between two single disk image files, simply mount each in a different drive # and copy as usual.
To move files between multi-disk images is a bit more complicated, but it's quite easy once you get the hang of it. The multi-disk images contain up to 256 disk images, each containing exactly 630 sectors. We can use the sector offset setting to map any of those individual disks to any of the DriveWire server's drives, and then again we access these as the same drive # on the CoCo.
For instance, lets say you have 2 DW3 style multi disk images, multiA.dsk and multiB.dsk. You want to copy a file from disk #10 in multiA.dsk to disk #20 in multiB.dsk.
Since every disk is exactly 630 sectors, we know that disk #10 starts at sector 6300 of the file multiA.dsk. We can insert multiA.dsk into any DriveWire server drive and specify an offset of 6300 (This can be done in the GUI or using the 'dw' command in OS9, and can be changed at any time while the disk is inserted. You can also store an offset along with other disk details in disk sets). Similarly we would insert multiB.dsk and give an offset of 12600, so that it points to disk #20. Now we can copy directly between the two.
You can also mount different disk images that are inside the same multi disk image. Just insert the file into more than one drive, specifying a different offset on each one. You can use this technique to rearrange the disks inside the file to fit into any drives you'd prefer, or to create a system that uses some disks out of one image and other disks out of another (or several).
You can also use offsets to access files containing partitions, especially partitions that do not start at the beginning of an image. When doing complex configurations with offsets outside of HDBDOS mode (which enforces size limits per disk by its very nature), you may want to use the size limit setting to ensure no writes go beyond the region of the file you want to work with. Read/Writes to sectors greater than the offset + the limit specified will return errors even if the sector exists in the underlying file.
There are a few options that can be specified in the server configuration for use specifically with CoCoBoot. These should be specified in the configuration section(s) you wish them to effect.
NamedObjectDir sets a path to use for named object mount requests. CoCoBoot uses these requests to load scripts and save data. You can specify any valid local path or URL, following the same rules as any disk path or other file setting in DriveWire. Example:
<NamedObjectDir>E:\cocodisks\named</NamedObjectDir>
If you would like named objects to reload when the server notices a change in the original source object, enable NamedObjectSyncFromSource:
<NamedObjectSyncFromSource>true</NamedObjectSyncFromSource>
If you are using the default 40 column mode in CoCoBoot, the dw command help will wrap and use a lot of screen real estate. You can turn off the extra help:
<CommandShortHelp>false</CommandShortHelp>
Often you will want to create CoCoBoot scripts using your own editor on modern PC and load them into CoCoBoot via DriveWire. Normally the server will complain about images that are not some multiple of 256 bytes in size. This setting will tell the server to simply pad files out to fill the last sector with 0 (Which CoCoBoot understands).
<DiskPadPartialSectors>true</DiskPadPartialSectors>
Modern DriveWire servers provide a wide variety of options available when loading and saving disk images. You can load disk images via various protocols and from local files.
Paths are generally specified in URI form. Note that some special characters may need escaping depending on your implementation.
Many possible locations for disk images are not writable. The DriveWire server loads the disk image into a local buffer where you can make any changes you like, however these changes are not written back to the source file in these situations. You can still write the disk image to an alternate, writable location (local file, ftp, etc) using the "dw disk write" command.
For example, this command loads the extras.dsk from inside the file dw_beta_1.3.tar.gz which is on the website aaronwolfe.com into drive 3:
dw disk insert 3 tgz:http://aaronwolfe.com/coco/dw_beta_1.3.tar.gz*/dwbeta/disks/extras.dsk
And this command would save the disk image in drive 3 to the incoming directory of the MaltedMedia FTP server:
dw disk write 3 ftp://maltedmedia.com/incoming/test_please_delete.dsk
Disk images located on local filesystems will be automatically synced to disk using lazy writes (the interval at which this sync occurs is usually adjustable). Disks from remote locations may require you to use the "disk write" command if you want to save changes.
You can use the "dw disk show #" command to show what type of filesystem a current disk image is located on if you are not sure. You can also check for dirty sectors (changed sectors which have not been written to disk) using the "dw server show" or "dw disk show #" commands.
The "dw server list" and "dw server dir" commands support the same paths as the dw disk commands. You can use them together as a poor man's FTP/SFTP client. Redirecting the output of dw server list to a local file essentially downloads that file to local disk.
For example, to list the files inside the gzipped tar file on a web server, you could do something like this:
dw server dir tgz:http://aaronwolfe.com/coco/dw_beta_1.3.tar.gz*/dwbeta/disks
And to download a file from an FTP site onto your local disk, you could do this:
dw server list ftp://www.rtsi.com/OS9/OS9_6X09/GAMES/cave.lzh > /dd/games/cave.lzh
To save time, remember that all commands may be abbreviated to their shortest unique form. "dw d i 3" is equivalent to "dw disk insert 3".
Ports
DriveWire implementations typically use various TCP ports for internal and external communication.
UI Port
This port is used for communication between the server and user interface dashboards. It often defaults to 6800.
Instance ports
These ports must be unique per instance. They become active when the instance is started, usually when the server is started but it is possible to disable instances individually or to tell the server not to start them automatically.
TCPDevicePort
This port is used only when the instance's device type is set to 'tcp'. In this mode, the instance opens the TCPDevicePort and listens for an incoming drivewire protocol connection, similar to the serial mode where the instance opens a serial port and listens for drivewire protocol commands. This is useful for patched MESS where the bitbanger patch causes MESS to make a connection out to the drivewire server. A single incoming connection is supported per instance.
Related settings in config.xml:
<DeviceType>tcp</DeviceType>
<TCPDevicePort>6799</TCPDevicePort>
TCPClientPort
This port is used only when the instance's device type is set to 'tcpclient'. In this mode, the instance initiates an outgoing connection to the specified host and port (the port is not used on the DW server itself). This is useful for MESS patches that expect an incoming connection, or for using IP-serial adapters connected to a CoCo. A single outgoing connection is supported per instance.
Related settings in config.xml:
<DeviceType>tcpclient</DeviceType>
<TCPClientPort>10001</TCPClientPort>
<TCPClientHost>some.host.com</TCPClientHost>
TermPort
This instance-specific port is used in conjunction with the special 'headless' NitrOS-9 disks. When booted with these disks, the CoCo sends all I/O that normally would go to the CoCo's console out over a DriveWire virtual channel. To interact with the console, you telnet to the TermPort on the server. When specified, the instance will listen on this TCP port at all times regardless of a CoCo connection. A single incoming TCP connection is supported.
Related settings in config.xml:
<TermPort>6801</TermPort>
Note for users of FTDI USB-Serial adapters
While working on the server code, I found that my FTDI adapter performed about 20% slower than my Prolific adapter and a 16550 "real" serial port. There is a simple change that can be made in the FTDI driver's settings to bring its performance in line with the other hardware.
Simply change the "receive buffer latency timer" to 4ms (from the default 16ms). In Windows, this is done in the properties of the adapter, accessible from device manager.