Sven Petersen discovered an old EPROM marked
VC-1541-DOS/80 in the UD11 option ROM socket of a Commodore CBM 8032. It turned out to be for a user port adapter that allows PET/CBM computers to use CBM IEC serial peripherals like the 1541 disk drive. Sven did not have the hardware but he reverse engineered the requirements from the EPROM and designed his own PCB. With the EPROM and Sven's PCB, you can use IEC peripherals with the PET.
This is a disassembly of the
BASIC 4.0. The code makes many calls that are specific to the BASIC 4.0 ROMs.
80-column Screen RAM. For the wedge commands
!cmd#, the code uses
$87D0, which is a non-visible location in the 80-column RAM. These commands will not work on a 40-column machine, although all others will. To adapt the code for 40-column PETs,
$87D0could be replaced with
An 80-column Editor ROM. For the
!cmd#command only, the code changes the
VOUTvector to redirect output through its own routine. The
VOUTvector is a feature of the 80-column Editor ROMs only. It is present in the 80-column North American and German (DIN) Editor versions but is not present in any 40-column version.
An unknown 80-column Editor ROM. Again for the
!cmd#command only, the code expects
$E787to be the default address that the Editor ROM stores in
VOUT. However, in the standard Editor ROMs for North America and Germany (DIN), there is nothing at
$E787, meaning VC-1541-DOS was written for use with an unknown Editor ROM. To adapt the code to the standard 80-column editor ROMs, replace
VC-1541-DOS provides a BASIC wedge. Install it with
sys 40960 and it will show:
All commands in the VC-1541-DOS wedge are prefixed with a
!. The standard CBM BASIC commands can still access IEEE-488 devices but only the
! commands can access IEC devices. Although most
! commands share the same names as their CBM BASIC counterparts, the usage of these commands is not exactly the same.
||Quit. Uninstalls the VC-1541-DOS wedge.|
||Read the command channel on an IEC device and print it.|
||Send a CBM DOS command to the command channel on an IEC device. The command must be quoted.|
||Use the given IEC device number for the wedge command that follows it. Another wedge command must follow the number, e.g.
||Reprogram the device number of an IEC device to the given device number. This sends an
||Read the directory on an IEC device. This is equivalent to
||Read the directory on an IEC device with the given search pattern. Enter the search pattern the same as you would with
||Load a program from an IEC device starting at the address in the file. The BASIC pointers
||Load a program from an IEC device starting at the address in the file. The BASIC pointers will not be changed.|
||Load a program from an IEC device starting at the given address instead of the address in the file. Only a start address may be given and it must be four hexadecimal digits. The BASIC pointers will not be changed.|
||Verify a program on an IEC device starting at the address in the file.|
||Verify a program on an IEC device starting at the given address instead of the address in the file. Only a start address may be given and it must be four hexadecimal digits.|
||Save a BASIC program to an IEC device.|
||Save memory from
||Open a file with the given secondary address on an IEC device. The comma and the quotes are required. The filename can not be empty. Note that secondary addresses 0 (load), 1 (save), and 15 (command) are special in CBM DOS. For general purpose file access, use a secondary address between 2 and 14.|
||Redirect output to the given secondary address on an IEC device.|
||Print a CR to the given secondary address on an IEC device. If
||Print an expression to the given secondary address on an IEC device. Multiple expressions can be combined with a
||Read a byte from the given secondary address on an IEC device into a variable.|
||Read CR-delimited data from the given secondary address on an IEC device into one or more variables separated by commas. The command channel of a drive can be read with
||Close a file with the given secondary address on an IEC device.|
Command shortcuts, whitespace, and quoting works like CBM BASIC, e.g.
!load "foo" can be shortened to
!lO"foo. Variables and expressions can be used, e.g.
f$="name":!load $f or
!print#2,chr$(x+1);. Most commands work from direct mode or from within a program, but some do not work in direct mode, like their CBM BASIC counterparts. The variable
st is updated after commands but
ds$ are not supported.
VC-1541-DOS uses a default device number stored in location
$03fe). It is set to
8 when the wedge starts. If a wedge command is entered without a device number, such as
!load"filename", then the default will be used. You can
poke a new default. After
poke1022,9, the command
!load"filename" will load from device 9.
A wedge command may be prefixed with a device number to override the default. For example,
!9load"filename" will load from device 9. The prefixed device number will only be used for the command that immediately follows it.
If bit 7 of the device number is set, an automatic CR (
0x0d) to CRLF (
0x0a) translation mode is activated. The
!cmd# commands will automatically send an LF after every CR in this mode.
VC-1541-DOS can also be used without installing the wedge by entering
sys 40963 followed by a command. This statement is equivalent to
All of the VC-1541-DOS commands may be used this way, regardless of whether the wedge is installed or not. Due to the way
sys parsing works, a device number prefix (such as
!9load"filename" in the wedge) cannot be used.
!close# can be used with
sys40963 but they cannot be the very first VC-1541-DOS command executed because they do not initialize the VIA. This is not a problem when working with disk files, since
!open is always called first. However, to read the command channel of a drive into variables without first sending a command, or to send data to a printer,
!open is not called first. As a workaround, you can use
sys40960:!q first, which installs the wedge (initializing the VIA in the process) and then immediately uninstalls it.
Additional Entry Points
Only the first two entry points are intended to be used from BASIC. However, there are 15 additional entry points available for use by assembly language programs. These provide a "unified" or "universal" API to control both IEC and IEEE-488 devices. Please see the source code.
The original author is unknown. The EPROM contained the strings
(C) g mutz (84).
Sven Petersen discovered the EPROM, disassembled large parts of it, determined the hardware requirements, and designed a circuit and PCB for it. He was the first to get it working and published extensive documentation.
Martin Hoffman-Vetter is credited by Sven for noticing that the IEC routines in the ROM are nearly identical to those in the C64 KERNAL, which greatly simplified disassembly.
To make this disassembly, I ran
m740dasm on the original binary and then added symbols and comments.
No rights are claimed on the original VC-1541-DOS code or C64 KERNAL code.
All other work in this repository is made available under the 3-Clause BSD License.