prlink v0.9.5a -- a data transfer system between Commodore 8-bit computers and an Amiga (AmigaDOS) or a PC clone (Linux, MS-DOS) Release date: 22nd May, 1996 Copyright © 1994-1996 Marko Mäkelä and Olaf Seibert Original Linux and Commodore 64/128/Vic-20/16 version by Marko Mäkelä Ported to the PET and the Amiga series by Olaf Seibert This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *NOTE*: This version does not include any Amiga files, because Olaf Seibert was too busy to adapt the Amiga sources. An Amiga version will be released later, probably before the next common release. Ask Olaf for the Amiga version. 0. PREFACE This document describes the prlink utility, a program package that lets you to transfer data over a parallel connection between a Commodore 8-bit computer and a bigger system (Amiga or PC). The utility is based on a daemon, or a memory resident IRQ handler wedge running in the Commodore end of the cable. You always issue the link commands from the other side (Amiga or PC). This implementation saves you from needing a server process on the bigger computer, which is very important for MS-DOS users. Currently daemons are available for the Commodore PET series (3032 and 8032/4032), the Vic-20, C64, C16 and C128 computers. There are compilation options that support the Commodore REU (RAM Expansion Unit), even simultaneously with an Action Replay cartridge installed, and some internal memory expansions on the C64 and the C128. The client programs are written so that they compile on Amiga and on Linux with the GNU utilities, and on MS-DOS with Visual C++, or with older versions of Microsoft C. The programs were originally written for Linux. The Linux and MS-DOS versions use machine language optimized transfer routines. Also the Amiga version is partially manually optimized in 68000 machine language. The idea of the transfer utility package is that a daemon runs on the Commodore side in an interrupt routine, without affecting the computer's performance. It checks if the other side wants to send any command, and executes possible commands. The protocol includes commands for memory transfers and for starting a machine language routine or a BASIC program. The latter two commands deinstall the daemon for maximum compatibility. With the current protocol, it is possible to make useful applications that run on the other end, like disk and file copiers (prdisk, prrfile and prwfile), and possibly a machine language monitor. It is already possible to develop Commodore programs on the other side, and to transfer them over to be tested out. Actually, this is exactly how prlink itself has been developed. On the Commodore 128, you can use a boot sector, so that the prlink daemon will be started automatically when you start the system. We chose to use our "own" assembler, the DASM cross assembler, ported to ANSI C and extended by Olaf Seibert. The assembler supports conditional assembling, relocated origins and macros. You can retrieve it from ftp.funet.fi as /pub/cbm/programming/dasm.tar.gz. 1. GETTING STARTED In order to save you from compiling the prlink binaries yourself, we have prepared binary distributions of prlink. On Linux, it is normal to compile all software you get, but on the Amiga it is unusual to have a C compiler. Not to mention the MS-DOS environment, where it is almost impossible to get a free 8086 C compiler. On MS-DOS, I chose Microsoft Visual C++, because it creates 8086 code, which runs on all PCs. I could have used the GNU CC port, djgpp, but it only creates 80386 code. And I assume most people who would have use for prlink in DOS would use Linux if it was possible. (Linux requires at least 80386.) There are two different binary distributions, one for AmigaDOS and one for MS-DOS. Both of them include 6502 binaries for all supported machines and cables, and a native executable for all supported cables. For Linux, there is no binary distribution available, since we want to encourage people to make their own modifications to prlink. The source distribution is prlink-VERSION.tar.gz where VERSION is replaced with the prlink version number, like 0.9.4. It does not include any binaries, not even 6502 binaries. Consult the "COMPILING" section of this document how to compile prlink. The AmigaDOS binary distribution is called prlink-amiga-VERSION.lha where VERSION is the prlink version number. Similarly, you can find the MS-DOS binary distribution under the name prlnkVRS.zip, e.g. prlnk094.zip for the current version. But beware, the MS-DOS version is merely a quick hack. Although a hung transfer can now be stopped with Esc, there might be other bugs lurking around. One known bug (or MS-DOS "feature") occurs when you redirect e.g. prsave output to a file (e.g. "prsave e000 0000 > kernal.prg". A CR/LF conversion will take place, so this is not a reliable way to transfer binaries. The same applies to prcart. 1.1 Bootstrapping If you don't currently have any possibility to transfer data to your Commodore 8-bitter from other computers, don't worry. In loader.bas, there is a BASIC loader with which you can download the prserver daemon to your computer. Just type it in and save it on tape or disk before starting it. On the other side, you need the prlink binaries. The cable types (or transfer protocols) supported by the BASIC bootstrapper are the 4-bit/8-bit prlink cable, and the PC64 cable. With a PC, you can choose either cable. If you are not planning to use the PC64 emulator (currently the best Commodore 64 emulator for MS-DOS), you'd better choose the prlink cable because of its better overall performance. On the Amiga, there is one native cable, which works with all supported protocols. For the bootstrapping you can only choose the 4-bit/8-bit protocol, but you can use any protocol after you have transferred the desired daemon to the 8-bit Commodore side. Furthermore there is the transnib protocol, which works over both TransNib and prlink cables. The most efficient protocol is prlink88, which transfers 8 bits at a time in both directions. Start the bootstrapper on your Commodore. On the other side, change to the "bin" subdirectory and execute the prmain binary with the desired protocol to transfer the desired daemon to the Commodore, e.g.: linux/prmain -c prtrans4 --prload c64/prlink/prserver.prg or amiga/prmain -c prlink --prload c64/prlink88/prserver.prg or msdos\prmain -c prtrans4 --prload c64\pc64\prserver.prg Now you should see a list of addresses and byte values scroll by. If not, the connection does not work properly. Ensure that the cable is properly connected and you have typed in the appropriate lines of the BASIC listing, so that it is adapted for your hardware. Also, if you are using a PC, you may have chosen the wrong printer port. Try the -p parameter with different numbers (from 0 to 3). Also note that the Linux version requires super user (root) privileges. Remember to install the software as root, or use "chown root" and "chmod u+s" on the binaries. If everything seems to run correctly, replace the PRINT command on line 2050 with POKE. Now the prserver daemon will be really loaded to your computer. Once prserver.prg has been transferred, save it using your favourite method (an assembly language monitor is usually easiest). The addresses it occupies are printed by the basic program. Alternatively, if you have a disk drive, you can start the daemon and use the prwfile command to copy prserver.prg to disk. 1.2 Configuration All prlink client programs are actually integrated into one program called "prmain" or something similar. The prmain program chooses its function by the executable name, so you can make symbolic or hard links to prmain, if your system supports them. For instance, if you rename or copy prmain to "prload", or make "prload" a symbolic link to it, it will function as described in Section 2.1. The same function can be achieved by issuing the command "prmain --prload". For this reason, you can also define a shell alias for prload, which makes sense if you want to use prlink with different cables and printer ports. By default, the PC versions of prmain use the native prlink cable, and the Amiga version uses the prlink88 cable. You can specify the protocol with the "-c" option on the command line. If you are using some other protocol than these two, you are best off by defining aliases for the client programs. For Linux, there are sample definitions in Start.tcsh and Start.bash. As you might guess, one file is for tcsh and the other is for bash. The scripts define environment variables for the file and disk transfer commands (see Section 2.4) and aliases for all client and protocol combinations. The naming scheme is simple: function names combined with numbers indicating the protocol. The X1541 cable is 1, the 64NET cable is 2, the PC64 cable is 4, and the prlink cable is 8. Thus, "prload8" will execute the "prload" function using the prlink cable. By the way, you should edit the "port" definitions in the scripts to set the parallel port numbers correctly. In MS-DOS, you cannot define aliases, unless you are using DOSKEY or some other shell than COMMAND.COM. Copying the executable under all six names would be a waste of disk space, and it doesn't even work, thanks to the brain-dead MS C runtime library. But you can use batch files instead. For instance, your PRLOAD.BAT might be as follows: @ECHO OFF PRMAIN -c prtrans4 --prload -p 1 %1 You can define aliases in 4DOS or even in COMMAND.COM, if you use DOSKEY. For COMMAND.COM and DOSKEY, there is an example startup file in STARTDOS.BAT. Remember to make sure that the "port" setting is correct. If you will be using prlink with one type of C= servers, e.g. you only have a C64, you don't need to to define the PRLINK environment variables, which saves environment variable space, which in turn consumes low memory. In this case, you can use the -l option with prrfile, prwfile and prdisk. See Section 2.4 for more details. 1.3 Usage Start the 6502 side by giving the command SYS [start address] where [start address] is of course the first byte of the program. The server will hook itself in the IRQ handler chain and you should get a READY prompt back immediately. Now you can use the prload, prsave, etc programs from the other side. These programs give their usage if you call them with incorrect arguments (or no arguments at all). To make the 6502 side remove itself from the IRQ chain, give the command SYS [start address + 3]. Note that the default VIC-20 version loads at 16384 ($4000). This means that you need at least 16kB of expansion memory to use the program. If you want to use prlink with an unexpanded VIC, you have to recompile the binaries. But there won't really be much use for it, as the prserver daemon would eats up a big part of the unexpanded VIC's memory. Now that you have successfully started the daemon on the 6502 side, you can start using the client programs, as described in the following section. 1.4 Automatic startup (C128 only) The Commodore 128 tries to load a boot sector from device #8 in its startup routine. With a special boot sector, it is possible to start the prserver daemon on the C128 automatically. Marko has created such a boot sector. It not only starts the prserver daemon for the C128; it can also switch to C64 mode and start the prserver daemon there. Also, it can switch off the PIA memory expansion (if any) for maximum compatibility. By default, the boot sector loads the prserver daemon for C128 mode. You can change this behaviour by holding a key down while the boot sector is being started. Remember not to press the STOP or C= keys down too early, or the C128's startup routine doesn't load the boot sector. The keys and their functions are as follows: Boot sector Key pressed File to load Mode PIA support ------------ ------------- ------------ ---- ----------- (both) STOP (none) (aborts the boot) bootsect.pia (none),<-,1,2 pr1028 C128 yes bootsect.std (none),<-,1,2 pr128 C128 no (both) CTRL pr128 C128 no (note 1) bootsect.pia C= pr2564 C64 yes bootsect.std C= pr64 C64 no (both) SPACE BAR pr64 C64 no (note 1,2) (both) Q (none) C64 no (note 1,2) Note 1: bootsect.pia disables the PIA expansion in these modes. Note 2: The drive 8 will be issued the U0>M0 command in this case. (Effectively, a 1571 drive will be reset to 1541 mode.) The 40/80 key sense line will be zeroed in this case. (This can be used to disable a ROM extension. See text.) The table may seem a bit chaotic for the first sight. The column "file to load" is most important. You have to copy the prserver daemons for the modes you use. For instance, if you have a PIA expansion and a REU in your C128, and you are using the PC64 cable, you need to copy the following files: PC or Amiga filename C128 filename -------------------------- ------------- bin/c128/pc64/prserver.prg pr128 bin/c128/pc64/prpiareu.prg pr1028 bin/c64/pc64/prserver.prg pr64 bin/c64/pc64/prpiareu.prg pr2564 bin/c128/bootsect.pia (must be copied to track 1, sector 0) As you see, there are two different boot sectors to choose from. Actually you could use bin/c128/bootsect.pia for everything, but then you would have to name the files accordingly. The standard boot sector (bin/c128/bootsect.std) loads only pr128 or pr64, regarding to the selected operation mode. The bootsector with PIA expansion support (bin/c128/bootsect.pia) can switch the PIA off, and load prserver daemons without any PIA support. If you don't have any memory expansion, your choice is bootsect.std. If you have the PIA expansion, the choice is bootsect.pia. Actually, you can use this boot sector for any hardware configuration. You can rename other programs to "pr128", "pr64", "pr1028" or "pr2564". The boot sector makes a JSR to the start address of the program file. You can copy the boot sector to the disk with prdisk, which is discussed in Section 2.4.3: prdisk -w bootsect.pia You will get the error message "Could not read all of the input file." This message can be safely ignored. It is possible to change the default behavior of the bootsector. As you can see from the source code in src/bootsect.a65, a default value will be loaded if none of the special keys is being pressed during the boot. By changing the default value, you can create a boot sector that e.g. automatically switches to C64 mode and loads the appropriate prserver daemon. You can recompile the source with "make cleanchosen bootsect.prg". Remember to cut the the two first bytes of the binary file (the loading address $0b00) before writing it to the disk, or make sure that the assembler is invoked with the option -f3. If you have installed a custom KERNAL ROM (such as JiffyDOS) on the system, and you have two KERNALs (custom and standard) on the same EPROM, you can connect the KERNAL selection line to the 40/80 key. If you do this, the C64 mode KERNAL can be selected simply with the 40/80 key. But the bootsector can do the change as well. If you press space to get to maximum compatibility C64 mode, the bootsector will pull the 40/80 key sense line low, which will select the standard KERNAL. 2. PROGRAMS 2.1 prload Prload loads a Commodore-style program file to the remote computer. The program reports its usage as follows. prload: Uploads files to a memory area on a remote computer. Usage: prload [options] filename(s) Options: -a addr Override the load address from the file -b bank Specify the memory bank (in hex) -l Load the file as BASIC. -r Performs the BASIC RUN command after the transfers. -j addr Jumps to the specified hex address after the transfers. -p port Specify the printer port (0 to 3) As you see, you can load several files at once. The -a option, which changes the program's loading address, only makes sense if you are loading a single file. It is useful when loading BASIC programs that were written for different platform and thus have a different start address. For loading BASIC programs, you can use the -l option as well. A very useful feature is the -r option. It deinstalls the prlink daemon after loading the program and performs the BASIC RUN command automatically. The -j option is similar, but it only works with machine language programs that do not end in an RTS. The -p option selects the printer port on a PC. You don't need this option if the default port number is suitable for you, as determined at compilation time. The ports are numbered from 0 to 3, and they correspond to the port addresses $3bc, $378, $2bc and $278, respectively. Last, but not least, the -b option chooses the memory bank, which is 0 by default. It is only interpreted in the Commodore 128 version of the prlink daemon, and in versions compiled with support for any banked memory expansion. Bank numbers 0 to f are for internal memory. The two lowmost bits are for specifying the MMU mapped memory bank on a C128. In other words, MMU mapped memory banks on the C128 are numbered from 0 to 3. On unexpanded C128s, the banks 2 and 3 are the same than banks 0 and 1. The bits 2 and 3 of the bank number specify the PIA mapped expanded memory bank on a C128 or a C64. So, the 64kB banks of a C128 with 1 megabyte of internal memory are numbered from 0 to f. On a 512kB-expanded C128, the unique bank numbers are 0-1, 4-5, 8-9 and c-d, as there are only two MMU banks. For instance, the banks b and 9 are the same. On a 256kB-expanded C64, or on a PIA-expanded C128 in C64 mode, the bank numbers 0-3, 4-7, 8-b and c-f are the same, so there are 4 different banks. Bank numbers from 10 to ff are for REU memory banks, i.e. the banks of a 512-kilobyte-REU are numbered from 10 to 17. As you can see from the prserver.a65 source code, the PIA and REU expansions are accessed through a 16kB window at $4000. On a stock C128, the memory will be accessed through the FETCH ($2a2) and STASH ($2af) subroutines. Due to their design, there's a bug in the plain C128 version: any data read from $0-$3ff will be fetched from bank 0. The version for the PIA expansion does not have this bug. A typical prload command line looks like the following: prload -r sanxion Note that the program to be loaded may not overwrite the prserver daemon code. If this happens, the transfer will hang. This is a bug, and in a later version we should relocate the prserver daemons to memory areas that are not used by normal programs, i.e. under I/O areas etc. 2.2 prsave Prsave echoes the contents of a C= memory area to standard output or to a file. The program reports its usage as follows. Usage: prsave [options] startaddress endaddress [filename] Options: -b bank Specify the memory bank (in hex) -p port Specify the printer port (0 to 3) There is not much to say about this program. The -b and -p options are the same as with prload (section 2.1). Typical usage of this command is something like prsave 400 7e8 screenshot which saves the C64 or C128 text screen to a file "screenshot", which can be loaded back with prload. 2.3 prcart Prcart loads and starts VIC-20 cartridges. It takes its input either from the standard input, or from files that contain the 4kB or 8kB ROM images for $A000-$BFFF and $6000-$7FFF, or from Commodore-style program files with starting address $A000 or $6000. Prcart patches the cartridge autostart code so that a RESET will restart the transfer daemon instead of restarting the game. This is definitely a must for a VIC-20 owner. You need expansion memory at BLK5 and BLK3 to use this program, plus the memory required for the prserver daemon. I have a 32kB RAM cartridge. Also, note that some VIC-20 cartridges try to overwrite themselves, as a copy protection. So, you need a switch on R/-W, or you must patch such cartridges, which usually isn't too difficult. prcart: Uploads a cartridge to the VIC-20. Usage: prcart [options] [filename.a000 [filename.6000]] Options: -j addr Jumps to the specified address after the transfers. Not useful with auto-start cartridges. -a addr Specifies the restart address of the game. Default=20000. Only useful with auto-start cartridges. -p port Specify the printer port number (0 to 3). The -p option is the same than with all prlink utilities, the printer port number. The -a option specifies the game restart address. If you want to restart the game after hitting RESET, you can restart it without transferring it again by issuing a SYS command. You can use this option to change the SYS address. The -j option, which lets you to jump to the specified address, is only useful with cartridges that do not normally start automatically. The start address varies from cartridge to cartridge. A typical prcart command line looks like prcart OMEGA_RACE. 2.4 File and disk transfer commands The file and disk transfer commands implemented in prlink use standard KERNAL routines. This means very slow speed, but it also guarantees maximum compatibility with all C= mass memory equipment. For instance, the prdisk command can copy disks of any capacity up to 999000 sectors, which is 243 megabytes. Note that these transfer commands only work with disk drives or pseudo drives, like the REU ramdisk. The commands might work with sequential files stored on tapes, but not with program files. (This has not been tested.) Bad news for X1541 cable users: As you cannot use serial devices while the prlink daemon is running, you won't have much use for these commands. The file and disk programs download 6502 programs to the C= side, a kind of loadable modules which implement the actual file and disk operations. These commands can optionally use some environment variables to locate the loadable module files. They use PRLINKDIR to locate the directory, and each transfer utility uses a variable named after the utility and the server type (e.g. when using a Commodore 64, PRLINK_PRRFILE64, PRLINK_PRWFILE64, PRLINK_PRDISK64) for the filename. The server type numbers are as follows: number server type ------ ----------- 201 Commodore PET series (should be 2001, but must fit in a byte) 20 Commodore VIC 20 64 Commodore 64 16 Commodore 264 series (16, 116 or plus/4) 128 Commodore 128 If the variables are undefined, respectively "prrfile.prg", "prwfile.prg" and "prdisk.prg" are used. The directory and file name are concatenated directly so the PRLINKDIR should probably end in a slash "/" (or, on AmigaDOS in a colon ":" or on MS-DOS in a backslash "\"). Alternatively, the complete pathname can be specified with the -l command line option. Even if you compile the prlink server to a different address, you won't need to recompile your prrfile, prwfile or prdisk binaries. Prlink detects the server's starting address and patches these extension programs as appropriate. This allows you to use servers with different starting addresses with the same extension programs. Thanks to this, the prdisk, prrfile and prwfile binaries compiled for the C128 work also on the C64 and on the VIC-20. 2.4.1 prrfile Prrfile reads a file from C= disk to local disk. Its usage is as follows. Usage: prrfile [options] filename [local filename] Options: -d device Specify the device number (0-15) -l filename Specify the filename of the client program -p port Specify the printer port (0 to 3) -s sec. addr. Specify the secondary address (0-15) The filename can start with a $, in which case it is printed as a directory, unless a local name is given. The remote filename is converted to PETSCII. The default local file name has / characters converted to -. Again, the -p option is the same than in all prlink commands. The -d option lets you to specify the Commodore disk drive device number, instead of the default, which is 8. With the -s 15 option you can send a command to the disk drive. This case is special: if you send a command, no data is read. If the command is empty, data (the disk status) is read, converted to ascii, and printed (by default to stdout). Reading the disk status means that the command must be completed first - that is why this is normally not done. A side effect of closing the error channel (which happens before opening it) is that all other files on the drive, and non-error messages such as "01,files scratched,00,00" and "73,cbm dos v2.6 1541,00,00" are forgotten by the drive. Please keep this in mind. To avoid this, execute a Basic CLR instruction before reading the error channel. Prrfile can be used as simply as prrfile file_to_be_copied. If you have different C= computers on your network, you will need to set some environment variables (Section 2.4), or to use the -l option to specify the prrfile module to load. 2.4.2 prwfile Prwfile writes a file from local disk to C= disk. Its usage is very similar to prrfile. prwfile: Writes a local file to a file on a remote computer. Usage: prwfile [options] filename [remote filename] Options: -d device Specify the device number (0-15) -l filename Specify the filename of the client program -p port Specify the printer port (0 to 3) -s sec. addr. Specify the secondary address (0-15) The remote filename is converted to PETSCII. Consult to Section 2.4.1 for documentation for the command line switches. 2.4.3 prdisk Prdisk reads or writes whole C= disks to/from local files. All media sizes are supported. The only requirement is that the first track is 1 and the first sector on each track is 0. Tracks and sectors increment up to 999. Usage: prdisk [options] [filename] Options: -d device Specify the device number (0-15) -r Specify read operation (default) -w Specify write operation -l filename Specify the filename of the client program -p port Specify the printer port (0 to 3) By default, prdisk dumps a disk from device 8 to standard output. If you specify a file name, the disk will be dumped to that file. With the -w switch you can specify write operation, i.e. the specified file (or standard input) will be written to a disk in device 8 starting from track 1, sector 0. The -d, -l and -p options work just like with prrfile and prwfile. 2.5 Miscellanous utilities The prlink distribution package includes two utilities to be used with the Commodore 64, and a synchronous fastloader for the 1541 and 1571 and compatibles, which runs on the VIC-20, on the C64, on the Commodore 264 Series and on the C128. All utilities were written by Marko. 2.5.1 tod.a65 Tod.a65 measures the time spent in an interrupt in hours, minutes, seconds and tenth of seconds, as read from the Time of Day clock register. It assumes that the power frequency is 50 Hz. The times will be displayed on the screen, if they are at least two tenths of a second. Tod.a65 was developed to measure prlink performance. It also works on the Commodore 128. Start it with SYS12288 after starting the prserver daemon, and see how much time a 64 kilobyte transfer ("prsave 0 0 file") will consume with your equipment. 2.5.2 playtune.a65 I have a bunch of Commodore 64 music files that I downloaded from ftp.funet.fi:/pub/cbm/c64/audio/vibrants. These modules use a common format. They must be initialized with a call to $1000, and the music will be played by calling $1003 once per picture frame. As there are loads of these files, I didn't want to transfer them first to my C64, but I wanted to play them easily with a simple prload command. So, I created a simple player. Its disadvantage was caused by the prserver daemon: it disables itself, if you start a program with it. So, I had to make the player restart the prserver daemon. The player is very simple. By default, it will compile to $c800, and it assumes that the prserver daemon starts at $cd00. To use the player, you must have the prserver daemon started on your C64 (Section 1.3). Assumed that you have the player (playtune.prg) and Toccato (ftp.funet.fi:/pub/cbm/c64/audio/vibrants/dek/14/14toccat.dek) in the current directory. The music will start playing on your C64 after issuing the following command: prload -j c800 playtune.prg 14toccat.dek You could also do it in two parts: prload playtune.prg prload -j c800 14toccat.dek And if you want to change the tune, just type e.g. prload -j c800 14treasu.dek You don't need to load the player each time. Beware that there are some musics with different init and play addresses. If you keep hearing the same piece after loading a new tune, make sure that prload reports the new tune's start address to be $1000. 2.5.3 fastload.a65 This routine has actually nothing to do with prlink, except that it uses a similar protocol as prlink. This is a synchronous fastloader routine to be used with a 1541 or 1571 disk drive, also known as "IRQ loader". Because the transfer routines are synchronous, the loader works on both PAL-G and NTSC-M systems, also in fast processor modes. The loader uses the synchronous IEC bus protocol that is described in Section 6.5. Everything is fully asynchronous, so the transfer won't be disturbed by any amount of interrupts on the computer. The loader was modified from a disassembly listing that I got a long time ago. I assume that it was the loader of the G.I.Joe game, because it only compared the first two characters of the filenames. I practically rewrote everything, only some label names remained. I also left the two-character filename comparison there. Using the loader is very simple. Select the target system and compile the loader with DASM (e.g. "make TARGET=c64 fastload.prg"). You will need to initialize the disk drive with a single call to "init". Note that the FA system variable, which holds the current (or last used) device number, must be properly set before calling the routine. After the initializations, the drive will sit in a loop, waiting for the fastload command. If the ATN signal gets asserted, the fastloader will quit to normal operation. So, the drive does not prevent any normal bus operations; you just have to reinstall the routine if you want to use it again. If there aren't any other activities on the bus, you can load several files with the fastloader without reinstalling it. The constant LEDFLASH controls the drive LED flashing. There are four options. If LEDFLASH=0, the drive LED acts normally (e.g. it is lit constantly while a file is being loaded). If LEDFLASH=1, the drive LED will glow on and off while the drive is waiting for a request. From this glow you will recognize if the fast loader is active. If LEDFLASH=2, the drive LED will be on while reading a sector, and off otherwise. Setting LEDFLASH=3 combines these two advanced options. When the fastloader is installed, you can load program files by loading the first two filename characters to the X and Y registers and by calling the "irqload" routine. The Carry flag will be set in return, if the file could not be loaded. There is only one possible flaw in the loader. If the computer gets interrupted right after it has sent the second character of the filename but before it has completed the handshake, and if the interruption lasts so long that the drive starts sending the first program byte (or an error code), the computer will remain in the loop, waiting for the handshake that occurred a long time ago. This could be solved with a watchdog timer or something. But actually this is not much of a problem, since the drive will read the disk directory before sending the status byte, which should last longer than any interruption on the computer side. Interrupts are disabled on the drive while sending data. This is mainly for improving the performance. However, interrupts must be disabled when sending the last byte, right before returning to the main loop. This prevents the deadlock situation on the drive side. Note that the interrupts must be enabled while waiting for the file name, because the disk motor is controlled by the interrupt routine. If interrupts are disabled, the disk will not stop spinning. These deadlocks could have been avoided by using the protocol described in Section 6.5.2, but it would have made the loader bigger and slightly slower. 3. HARDWARE Prlink requires a special cable that is connected to your PC's or your Amiga's parallel port (also known as the printer port or the Centronics port). The cable's other end must be connected to your Commodore's user port, with the exception of the X1541 cable, which connects to the IEC bus (serial bus). The PC64 cable is the cable used by the Personal C64 emulator written and marketed in Germany by Wolfgang Lorenz <100112.220@compuserve.com>. It uses 4 independent data lines for both directions. If you are using or are planning to use this emulator, then you are best off using this cable. The prlink cable allows 8-bit data transfers from the PC to the C= side, and 4 bits from the C= to the PC. It uses four bidirectional lines on the PC. The software also supports the X1541 cable, a cable designed for connecting a Commodore disk drive to your PC. It is the only option for Commodore 16 users, because of the lack of a user port. The transfer is slow, 1 bit at a time. As the X1541 cable uses the serial bus for the transfers, the transfer daemon might get confused by any disk activities. This means that you cannot use prrfile, prwfile or prdisk with this cable. On the Amiga, there is only one cable that works with all protocols supported by the Amiga version. Also, if you have built the cable for the TransNib software, prlink will work with it, although slower. For compatibility reasons, the PC versions support the 64NET cable, which allows a pretty inefficient 4-bit/2-bit protocol. 3.1 Cable pinouts Note that we disclaim any warranties, so you are using these instructions at your own risk. Do not insert the plug to the user port the wrong way around, or you'll blow your printer port on the PC with the 9 volt signal as Marko did. The 64NET cable pinout won't be listed, as the 64NET documentation claims that it is copyrighted. Besides, including it would be a waste of space, as other cables allow much faster protocols. 3.1.1 The PC64 cable PC C64 Comment GND 25 ------ A GND Ground D7 9 ------> B FLAG Handshake signal ERROR 15 <------ C PB0 Data from C= to PC SEL 13 <------ D PB1 " PE 12 <------ E PB2 " ACK 10 <------ F PB3 " D0 2 ------> H PB4 Data from PC to C= D1 3 ------> J PB5 " D2 4 ------> K PB6 " D3 5 ------> L PB7 " BUSY 11 <------ M PA2 Handshake signal 3.1.2 The prlink cable PC C64 Comment GND 25 ------ A GND Ground D3 5 ------> B FLAG Handshake signal STROBE 1 <------> C PB0 Bidirectional data lines AUTO 14 <------> D PB1 " INIT 16 <------> E PB2 " SELECT 17 <------> F PB3 " D4 6 ------> H PB4 Data from PC to C= D5 7 ------> J PB5 " D6 8 ------> K PB6 " D7 9 ------> L PB7 " BUSY 11 <------ M PA2 Handshake signal 3.1.3 The pramiga cable Amiga PET Comment GND 22 ------ A GND Ground POUT 12 ------> B CA1 Handshake signal (strobe/flag) D0 2 <------> C PA0 Bidirectional data lines D1 3 <------> D PA1 " D2 4 <------> E PA2 " D3 5 <------> F PA3 " D4 6 <------> H PA4 Data from Amiga to PET D5 7 <------> J PA5 " D6 8 <------> K PA6 " D7 9 <------> L PA7 " BUSY 11 <------ M CB2 Handshake signal (ack) On the PET, Olaf chose to use CB2 even though that pin is normally connected to a speaker. He did this because it makes the cable identical to the 64 and VIC cable, and allows you to use a single-sided connector. Make sure though that it does not connect the top and bottom fingers! Also you can hear nicely when the transfer is going on. Note that the lower user port connections are named ABCDEFHJKMMN, skipping G and I. On the Amiga 1000, pin 25 is not GND so Olaf picked 22 instead which should be GND on all Amiga models. On the PC, all pins from 18 to 25 should be GND. The Amiga cable allows for two protocols: the prlink compatible 4-bit/8-bit transfer, and a full 8-bit transfer, the option prlink88. In addition, the Amiga software supports a third protocol, the one for the TransNib cable. TransNib is an older transfer system for Amiga and C64. Its cable has only 6 Centronics data bits connected: D0-3 <-> PA0-3: data i/o D6 <-- PA6: handshake in (from C= to Amiga) D7 --> PA7: handshake out (from Amiga to C=) The Amiga cable is downward compatible with the TransNib cable, so you can use it with the TransNib cable protocol, but of course it is slower. If you need to make a cable there is no reason to not make the full pramiga cable; The transnib protocol is provided for people who made a cable for TransNib V1.00 Devised by Matt Francis (m.p.francis@newcastle.ac.uk). 3.1.4 The X1541 cable PC IEC bus Comment GND 22 ------ 2 GND Ground STROBE 1 ------> 3 ATN not used AUTOFD 14 <------> 4 CLK Bidirectional data/handshake line SELECT 17 <------ 5 DATA Bidirectional data/handshake line As you may note, not all lines of the original X1541 cable are required. The loop from D0 (pin 2) to ERROR (pin 15) is missing, as well as the connection from INIT (pin 16) to RESET (pin 6). The ATN line is not required either, but it is required by other transfer programs that use this cable. Prlink will work with these additions installed, so you don't need to modify your existing X1541 cable. Prlink also supports the Disk64e cable, which is quite obsolete. The Disk64e code replaces the X1541 code if you define the preprocessor name DISK64E when compiling the module prtrans1.c. Marko accidentally built the Disk64e cable first; that is why it is supported. 3.2. Transfer trouble For some reason Olaf had weird problems with his 64 when using the prlink protocol. He might be the only one suffering from this, but if you too get hung transfers when transferring from the 64 to the Amiga, try to run the transnib protocol over the prlink cable. It is slower but generally causes less hung transfers. To get more technical: When the data lines are changed by the 64, the handshake line from the 64 sometimes starts bouncing, causing the Amiga side to get so confused that the computers get too much out of sync. Olaf doesn't know if it's a problem with his cable (perhaps it is a bit long), his 64, or his Amiga, or any of those in general. Because of this, we have included bounce detection in the following cases: - prlink and prlink88, Amiga. The bounce on the handshake line to the Amiga (BUSY) happens with both Olafs PET and 64, but more with the 64. When reading its state, we require its readout to be stable for 3 consecutive accesses. Since the CIAs in the Amiga run at 0.714 MHz, an access takes about 1.4 microseconds. - prlink and prlink88, 64. The edge-sensitive handshake line to the 64 (FLAG) is apparently rather sensitive. When a false trigger occurs this fact is latched in the interrupt bit. By reading (and thereby clearing) the Interrupt Flag Register at the latest possible moment before the next handshake could come in, phantom handshakes caused by bounce seem to be significantly reduced. If you wish to turn off the bounce detection, you can do this by changing some flags. For the 6502 side, edit the file prtrans.inc and change the definition of "debounce" to 0. For the Amiga side, change DEBOUNCE and DEBOUNCE2 to 0. Next you need to recompile and test if the transfer still works correctly. If the transfer hangs, you can stop the server on the Commodore side with STOP & Restore. The AmigaDOS or Linux client can be stopped with normal means, i.e. Ctrl-D on the Amiga, and Ctrl-C on Linux. The MS-DOS clients can be stopped by pressing Esc. 4. COMPILATION To compile the binaries for AmigaDOS or Linux, you need GNU Make, GNU C compiler (tested with 2.5.8 and 2.6.2, any version should do) and related tools. Also, you need the DASM port made by Olaf Seibert. It can be downloaded from ftp.funet.fi:/pub/cbm/programming/dasm.tar.gz. The MS-DOS executables can be compiled with Microsoft C/C++ v8.00, which is part of Microsoft Visual C++ v1.5. The software supports several different cables. The transfer routines for the different cables are in prtrans2.c, prtrans4.c, prtrans8.c and pramiga.c. You will have to edit the Makefile to specify which cable (CABLEOBJ) and default printer port to use. The latter one is not required in the Amiga version. The Amiga version also allows the -DPRLINK88 option, which uses full 8-bit transfer, and -DTRANSNIB option for compatibility with the TransNib cable. 4.1 Automatic compilation For Amiga and Linux, we have created useful MakeAll scripts in the src directory. The Linux version is MakeAll.sh. It makes all C= executables for all supported cables and memory expansions, and the Linux prmain executable for all those cables. The Amiga version of this script, MakeAll.rexx, makes all C= binaries and the Amiga executable in similar manner. Assuming that the source tree is prlink-0.9.4/src, the binary tree will be prlink-0.9.4/bin. The binary distribution tree is as follows: COPYING The GNU General Public License. README this file README.Amiga Additional information for the Amiga. Start.Amiga Startup definitions for the Amiga. Start.bash Startup definitions for Linux (requires bash). Start.tcsh Startup definitions for Linux (requires tcsh). loader.bas A BASIC listing that you can type in to transfer the prserver binaries, using the prlink or PC64 cable. startdos.bat Startup definitions for MS-DOS. bin/pet3001/ Binaries for the PET3001 series prlink/ prserver daemons for the PRLINK protocol prlink88/ prserver daemons for the PRLINK88 protocol (Amiga only) transnib/ prserver daemons for the TransNib cable (Amiga only) pc64/ prserver daemons for the PC64 cable (PC only) c64net/ prserver daemons for the 64NET cable (PC only) prserver.prg a basic daemon supporting no special memory expansions prdisk.prg prdisk loadable module prrfile.prg prrfile loadable module prwfile.prg prwfile loadable module bin/pet4001/ Binaries for the PET4001 series ... (contents as above) bin/vic20/ Binaries for the Commodore VIC-20 ... (contents as above, plus) iec/ prserver daemons for the X1541 cable bin/c64/ Binaries for the Commodore 64 ... (contents as above, plus) prlink/ prserver daemons for the PRLINK protocol prlink88/ prserver daemons for the PRLINK88 protocol (Amiga only) transnib/ prserver daemons for the TransNib cable (Amiga only) pc64/ prserver daemons for the PC64 cable (PC only) c64net/ prserver daemons for the 64NET cable (PC only) iec/ prserver daemons for the X1541 cable prpia.prg a daemon version supporting the PIA expansion prreu.prg a daemon version supporting the Commodore REU prpiareu.prg a daemon version supporting both the PIA and the REU bin/c128/ Binaries for the Commodore 128 ... (contents as above, plus) bootsect.prg a boot sector for automatically starting one of the prserver daemons on the C128 bin/c16/ Binaries for the Commodore 16, 116 and plus/4 iec/ prserver daemons for the X1541 cable prserver.prg a basic daemon bin/linux/ Linux prmain executable (in case of MakeAll.sh) prmain all clients for all cables bin/amiga/ Amiga prmain executable (in case of MakeAll.rexx) prmain all clients for all cables bin/msdos/ MS-DOS prmain executable (in the MS-DOS distribution) prmain.exe all clients for all cables 4.2 Manual compilation If you are compiling the binaries manually, i.e. you want something special that cannot be achieved with the MakeAll scripts, you must run "make" in the "src" directory yourself. On MS-DOS systems, manual compilation is the only alternative. The command is "NMAKE -F MAKEFILE.DOS". MAKEFILE.DOS is designed for Microsoft NMAKE and Microsoft C/C++ v8.00, which are included with Microsoft Visual C++ for Windows v1.5. If you are going to use some other compiler, note that you must use large memory model (multiple data segments) and that extern variables must be assumed to be far. First you have to edit src/Makefile, or SRC\MAKEFILE.DOS in MS-DOS. The definitions for the CLIENT, TARGET, RAMEXP and CABLE variables must be checked. You have the following options that affect the Commodore side: definition options ---------- ------- TARGET target system, i.e. vic20, c64, c128 etc. RAMEXP none no memory expansion installed piaexp the PIA expansion for the C64 and the C128 (ftp.funet.fi:/pub/cbm/documents/{256kB,1028}) reuexp Commodore RAM Expansion Unit pet96 PET 8096/8296 expansion (not yet implemented) CABLE prlink the default 8-bit/4-bit cable pc64 the 4-bit/4-bit cable used by the PC64 emulator c64net the 4-bit/2-bit cable used by 64NET prlink88 fully 8-bit transfers with the Amiga cable transnib TransNib compatible alternative for Amiga The client (Amiga or PC) options are as follows: definition options ---------- ------- CLIENT client system, i.e. AmigaDOS or Linux. Not used in MAKEFILE.DOS (MS-DOS version). The following variables are undefined by default. When defined, they have following effects: definition effect ---------- ------ DEBUG Generate code for the GNU debugger gdb. (Makefile only) NO_ASM Disable inline assembler. FIXED Generate separate executables for all clients. The FIXED option is probably most useless, unless you are going to run the prlink clients on a very small system. By default, all functions and transfer protocols will be integrated into one executable. When you use the FIXED option, there will be compiled separate executables for all functions, i.e. prload, prsave and so on. Only one transfer protocol will be supported. It is specified by the CABLE setting. You don't necessarily actually need to modify the Makefile. The variables can also be specified on the command line, i.e.: make DEBUG=1 FIXED=1 CABLE=prlink CLIENT=Linux clean clients or nmake -f makefile.dos DEBUG=1 FIXED=1 CABLE=prlink clean clients The following explicitly defined build targets are available: target meaning ------ ------- all build "clients" and "prprgs" clients build all clients, i.e. prload, prsave and so on prprgs build all Commodore side utilities for the selected config prmain build the client executable (in case FIXED is not specified) prmain.exe ditto, in case of MS-DOS distribution clean remove object files reallyclean remove object and executable files Also, you may need to change the following definitions in prserver.asm, if using the PIA and/or REU expansions: pia the PIA base address, e.g. $dff0 reu the REU base address, e.g. $df00 actionreuplay If you are using Action Replay and the REU simultaneously, set this to 1. You can connect them in parallel manner to the cartridge port if you add a switch to the REU that disables the -I/O2 signal when R/-W is high. Effectively, you can do this with the following components: /o-------+ -I/O2 ----o/ | (from C64) o->|----+--- -I/O2 (to REU) | R/-W --------->|----+ 1N4148 | diodes < > 4k7 < resistor > | --+-- If you also modify Action Replay so that its -I/O2 gets disabled when R/-W is low, you won't need the actionreuplay option. But this modification cannot be implemented with diodes and resistors. Instead, you would need an IC (quad NAND or something), which may be difficult to fit in the Action Replay case. When the switch is in its upper position, the REU will operate as previously, i.e. it won't work with the Action Replay cartridge. When it is in the lower position, the Action Replay cartridge will work, but you will most probably have problems with any software that uses the REU (except prlink). Thus, whenever you want to use anything that supports the REU, you must disable the Action Replay cartridge and then move the switch to the upper position. 5. PERFORMANCE OVERVIEW For maximum performance, you should use the native prlink cable. But as you can see from these results, the PC64 cable is not much slower. Client: 486DX2/66 with 128kB cache OS: Linux, no processes running on the background MS-DOS (with and without EMM386) Server: Commodore 128D with 1 MB internal memory and 1 MB REU Data block: 64 kilobytes PC64 cable: prsave prload server ------ ------ ------ 3.7s 4.0s c128 (pia) 4.8s 5.3s c128 (stock) 3.7s 3.9s c128 in c64 mode (pia) 4.1s 4.0s c128 in c64 mode (stock) 7.1s 7.5s c64 (pia) 7.8s 7.6s c64 (stock) prlink cable (bounce code installed): prsave prload server ------ ------ ------ 4.7s 2.6s c128 (pia) 5.8s 3.9s c128 (stock) 4.7s 2.6s c128 in c64 mode (pia) 5.1s 2.3s c128 in c64 mode (stock) 8.0s 5.1s c64 (pia) 8.8s 5.1s c64 (stock) prlink cable (no bounce code): prsave prload server ------ ------ ------ 4.2s 2.5s c128 (pia) 5.5s 3.8s c128 (stock) 4.2s 2.5s c128 in c64 mode (pia) 4.8s 2.5s c128 in c64 mode (stock) 7.5s 4.8s c64 (pia) 8.2s 4.9s c64 (stock) These timings were measured on the C128D, using a program that measures the time spent in interrupts by reading the TOD clock. The program's source code is in src/tod.a65. Processor time spent on the PC is a bit more, because of the initializations, and because the transfer won't start until a timer interrupt occurs on the Commodore end. The prlink cable with the 4-bit/8-bit protocol is a bit slower with prsave than the PC64 cable. This is due to the handshaking performed with exclusive-or instead of constant values. But if you're using Amiga, you can enable full 8-bit transfer to get rid of this problem. As you can see from the figures, the stock C128 is faster in C64 mode, because the memory banking is simpler. Surprisingly (or maybe not), the transfer rate did not change under MS-DOS, even though Linux is a multitasking operating system. 6. PROTOCOLS The prlink package uses a wide variety of transfer protocols, one for each supported cable type. The protocols are the most important part of the software, so they must be thoroughly described. Because the software is strictly non-blocking, i.e. you do not have to run a program on either end that would just sit in a loop, busy-waiting for transfer events, and because the client software may run in an pre-emptive multitasking environment, the transfer protocols must be fully synchronous. On the server (Commodore) side, all protocols are implemented in the file prtrans.inc. The transfer routines for PC clients are implemented in the files prtrans[1248].c, one file for each protocol. The routines for the Amiga are currently in one single file, pramiga.c. For clarity, all signal names in the following description are from the Commodore 64 user port. See Section 3.1 (Cable pinouts) for a reference of the actual pinouts and corresponding PC or Amiga names. Note that -FLAG is an edge-sensitive input on the C64 that only detects a high-to-low transition. The line must be held low long enough for the transition to be detected. All other lines are "normal", level-sensitive, and on the server (Commodore) side, a low voltage level is used to present a '0' bit, while a high voltage level presents a '1' bit. 6.1 The PC64 cable (PC only) The PC64 cable allows for 4-bit transfers in both directions. It has eight data lines, four for both directions, and two handshake signals, one for the sending and one for the receiving end. It is quite simple and should work even with the cheapest parallel ports. 6.1.1 Sending a byte to the server PC: put the data bits 0..3 on PB4..PB7 and drop -FLAG C64: wait for the falling edge of -FLAG C64: read the data bits, drop PA2 PC: wait for low level on PA2 PC: raise -FLAG PC: put the data bits 4..7 on PB4..PB7 and drop -FLAG C64: wait for the falling edge of -FLAG C64: read the data bits, raise PA2 PC: wait for high level on PA2 PC: raise -FLAG 6.1.2 Receiving a byte from the server PC: drop -FLAG C64: wait for the falling edge of -FLAG C64: put the data bits 0..3 on PB0..PB3 and drop PA2 PC: wait for low level on PA2 PC: raise -FLAG, read the data bits PC: drop -FLAG C64: wait for the falling edge of -FLAG C64: put the data bits 4..7 on PB0..PB3 and raise PA2 PC: wait for high level on PA2 PC: raise -FLAG, read the data bits 6.1.3 Changing the data direction The data direction can be changed without any special measures. 6.2 The prlink cable, 4-bit/8-bit protocol The prlink cable utilizes four lines on the client side that should be bidirectional on all PC printer ports. On the Amiga printer ports, they definitely are bidirectional. These lines are the only data lines from the server to the client. For transfers from the client to the server, the protocol utilizes also four output lines, which allows 8-bit transfers. 6.2.1 Sending a byte to the server PC: put the data bits 0..7 on PB0..PB7 and drop -FLAG C64: wait for the falling edge of -FLAG C64: read the data bits, change the state of PA2 PC: wait for PA2 to change its state PC: raise -FLAG 6.2.2 Receiving a byte from the server PC: drop -FLAG C64: wait for the falling edge of -FLAG C64: put the data bits 0..3 on PB0..PB3 and toggle PA2 PC: wait for PA2 to change its state PC: raise -FLAG, read the data bits PC: drop -FLAG C64: wait for the falling edge of -FLAG C64: put the data bits 4..7 on PB0..PB3 and toggle PA2 PC: wait for PA2 to change its state PC: raise -FLAG, read the data bits 6.2.3 Changing the data direction As the protocol uses bidirectional data lines, the data direction of these lines must be reconfigured when changing the data direction. This is managed on the server side. The client side can always call input and output routines without any special measures. When the data flow direction changes on the server, the server first waits for the falling edge of -FLAG, then reprograms the lines' data direction and finally transfers the byte in normal manner. 6.3 The prlink cable, true 8-bit protocol (Amiga only) This is the fastest protocol that the prlink package supports. It uses two handshake signals and eight data lines. 6.3.1 Sending a byte to the server Ami: put the data bits 0..7 on PB0..PB7 and drop -FLAG C64: wait for the falling edge of -FLAG C64: read the data bits, change the state of PA2 Ami: wait for PA2 to change its state Ami: raise -FLAG 6.3.2 Receiving a byte from the server Ami: drop -FLAG C64: wait for the falling edge of -FLAG C64: put the data bits 0..7 on PB0..PB7 and toggle PA2 Ami: wait for PA2 to change its state Ami: raise -FLAG, read the data bits 6.3.3 Changing the data direction As the protocol uses bidirectional data lines, the data direction of these lines must be reconfigured when changing the data direction. This is managed on the server side. The client side can always call input and output routines without any special measures. When the data flow direction changes on the server, the server first waits for the falling edge of -FLAG, then reprograms the lines' data direction and finally transfers the byte in normal manner. 6.4 The TransNib cable (Amiga only) The TransNib cable uses four bidirectional data lines, PB0..PB3, and two handshaking lines, PB6 and PB7. The protocol is quite inefficient, and it is not fully asynchronous, but it is included for backward compatibility anyway. 6.4.1 Sending a byte to the server Ami: put the data bits 4..7 on PB0..PB3 and drop PB7 C64: wait for low level on PB7 C64: read the data bits and drop PB6 Ami: wait for low level on PB6 Ami: raise PB7 C64: wait for high level on PB7 C64: raise PB6 Ami: wait for high level on PB6 Ami: put the data bits 0..3 on PB0..PB3 and drop PB7 C64: wait for low level on PB7 C64: read the data bits and drop PB6 Ami: wait for low level on PB6 Ami: raise PB7 C64: wait for high level on PB7 C64: raise PB6 Ami: wait for high level on PB6 6.4.2 Receiving a byte from the server C64: put the data bits 4..7 on PB0..PB3 and drop PB6 Ami: wait for low level on PB6 Ami: read the data bits and drop PB7 C64: wait for low level on PB7 C64: raise PB6 Ami: wait for high level on PB6 Ami: raise PB7 C64: put the data bits 0..3 on PB0..PB3 and drop PB6 Ami: wait for low level on PB6 Ami: read the data bits and drop PB7 C64: wait for low level on PB7 C64: raise PB6 Ami: wait for high level on PB6 Ami: raise PB7 6.4.3 Changing the data direction As the protocol uses bidirectional data lines, the data direction of these lines must be reconfigured when changing the data direction. This is managed on the server side. The client side can always call input and output routines without any special measures. When the data flow direction changes on the server, the server first waits for the falling edge of -FLAG, then reprograms the lines' data direction and finally transfers the byte in normal manner. 6.5 The IEC bus cable The IEC bus has three wires that could be used for data transfers: CLK, DATA and ATN. Unfortunately, the ATN line is a bus propagation line, so it cannot be used if there are other devices connected to the bus. For this reason, prlink's IEC bus protocol has been realized with only two bidirectional lines: CLK and DATA. You might wonder how this is possible, asynchronous transfers with only two lines. There are the two required handshake lines, but where is the data line? You can combine the handshake and data lines. If you want to send a '0' bit, you will pull the DATA line low, and if you want to send a '1', you will pull CLK low. The receiving end will then acknowledge by pulling the other line low, and the sender replies to this by raising his line. Finally, the recipient will raise his handshake line, and the bus is ready for the next bit being transferred. This protocol has one problem (aside the speed, or better the lack of it): Changing the data flow's direction. In order to make it fully asynchronous, special tricks must be applied. Marko's IRQ loader, a fastloader that works with all sorts of interrupts enabled (Section 2.5.3), uses a quick and dirty method, to keep the code short. This cannot be done in prlink, because the client is often much faster than the server, but it can be much slower as well, as it may run in a heavily loaded pre-emptive multitasking environment. So, prlink's IEC protocol must change the data direction fully asynchronously. 6.5.1 Transferring a bit Since the protocol is symmetrical, and since this protocol transfers single bits, the description can be simplified. In the following description, "snd" denotes the sender and "rcv" the receiver. This cycle is repeated 8 times for a byte to be transmitted. The LSB (bit 0) will be transferred first. snd: drop DATA if sending a '0' bit; drop CLK if sending a '1' bit rcv: wait for low level on DATA or CLK rcv: read the data rcv: drop the line that was high snd: wait for low level on DATA and CLK snd: raise DATA and CLK * Note: The line held low by rcv will remain low. rcv: wait for high level on DATA or CLK rcv: raise DATA and CLK snd: wait for high level on DATA and CLK 6.5.2 Changing the data direction Switching from sending to receiving does not require any modifications to the bit transfer protocol, because the sending end will finish only after the receiving end's acknowledgement. But the other end must switch from receiving to sending, and this is a problem. Let's assume that there isn't be any special handling for changing the data direction. If the end that switches from receiving to sending is much faster than the other end, it may do the switching too fast. Let's see what happens. The last bit before the switch is being transferred. Everything goes fine until the receiver raises DATA and CLK. After that, the receiver does not wait for anything, and it could start sending data, dropping the DATA or CLK line. If this happens fast enough, or if the former sender gets interrupted, the former sender will never see a high voltage level on DATA and CLK. So, it will sit there, waiting for the former receiver's acknowledgement, which already was on the bus. 6.5.2.1 The quick and dirty solution The easy and wrong way to fix this problem is to wait long enough before sending the first data byte after the direction change, or by sending the last byte before the direction change without interruption. This was done in the IRQ loader (Section 2.5.3), and it works, because the disk drive and the computer run at almost the same speed. 6.5.2.2 The correct solution The correct way to solve the problem is using special handshaking, like below. The name "rs" refers to the end that used to receive and will send after the direction change, and the name "sr" refers to the former sender that will start receiving the data. rs: drop CLK and DATA rs: raise CLK and DATA rs: repeat the previous 2 steps until there is low level on CLK rs: drop CLK rs: wait for low level on DATA rs: raise CLK rs: wait for high level on DATA sr: wait for low level on CLK and DATA sr: drop CLK sr: raise CLK sr: repeat the previous 2 steps until CLK==low and DATA==high sr: drop DATA sr: wait for high level on CLK sr: raise DATA This handshaking relies on wired-and open-collector logic and on the fact that CLK and DATA can be set simultaneously, because they are located in the same peripheral register. It also requires that the receiver and the sender must not run at the exactly same speed. Because the CLK and DATA lines are switched low simultaneously by the "rs" end, the "sr" end can distinquish it from a sent data bit. Even if the "sr" end would be interrupted for long time after it has risen CLK but before it has read the state of CLK and DATA, the handshaking will work properly. This handshaking is implemented on the client and on the server in the functions send_switch and receive_switch. As you see, the handshaking is rather complicated. We wanted to keep the initiative by the sender, so that the bus remains in idle state (CLK and DATA high), when nothing is being transferred. With some extra logic, this would allow the usage of the serial bus while the prserver daemon is running, when there are no requests from the PC side. Below is a simpler protocol where the new receiver will have the handshaking initiative. rs: wait for low level on CLK rs: drop CLK and DATA rs: raise CLK and DATA rs: repeat the previous 2 steps until there is high level on DATA sr: drop CLK sr: wait for low level on DATA sr: raise CLK sr: wait for high level on CLK or DATA (or both) 6.6 The 64NET cable (PC only) This proprietary cable is included for historical reasons. I developed my first transfer routine for this cable, and as I saw how inefficient it was, I decided to build a better cable. The 64NET cable has four data lines from client (PC) to server (Commodore), PB4..PB7, and two data lines from server to client, PB0 and PB1. It has two handshaking lines, PB2 and PB3. Like the PC64 cable, it should work with any parallel port. As you see, the lines chosen are very badly on the server side, so this cable only allows a very inefficient protocol. 6.6.1 Sending a byte to the server PC: put the data bits 4..7 on PB4..PB7 and raise PB3 C64: wait for high level on PB3 C64: read the data bits, drop PB2 PC: wait for low level on PB2 PC: put the data bits 0..3 on PB4..PB7 and drop PB3 C64: wait for low level on PB3 C64: read the data bits, raise PB2 PC: wait for high level on PB2 6.6.2 Receiving a byte from the server PC: raise PB4..PB7, drop PB3 C64: wait for high level on PB4..PB7 and low level on PB3 C64: drop PB2 PC: wait for low level on PB2 PC: drop PB3..PB7 C64: wait for low level on PB3..PB7 C64: put the data bits 0 and 1 on PB0 and PB1 and raise PB2 PC: wait for high level on PB2 PC: read the data bits and raise PB3 C64: wait for high level on PB3 C64: put the data bits 2 and 3 on PB0 and PB1 and drop PB2 PC: wait for low level on PB2 PC: read the data bits and drop PB3 C64: wait for low level on PB3 C64: put the data bits 4 and 5 on PB0 and PB1 and raise PB2 PC: wait for high level on PB2 PC: read the data bits and raise PB3 C64: wait for high level on PB3 C64: put the data bits 6 and 7 on PB0 and PB1 and drop PB2 PC: wait for low level on PB2 PC: read the data bits and drop PB3 C64: wait for low level on PB3 C64: raise PB2 PC: wait for high level on PB2 6.6.3 Changing the data direction The data direction can be changed without any special measures. 7. CREDITS Prlink was originally programmed for Linux and C64/C128/VIC-20 by Marko Mäkelä. Olaf Seibert joined the project and ported prlink to Amiga and the PET series. Since the original release, prlink has been ported to MS-DOS and to the Commodore 16, and the program structure has been greatly improved. I would like to express my thanks to all transfer program writers who gave me the inspiration to create prlink, whose main goal is to be compatible with virtually any platform. I want to especially thank Levente Hársfalvi for Commodore 16 programming information, and for his ComLink program, which showed me that you can also misuse the IEC bus for data transfers. 8. CONTACTING THE AUTHORS If you have any questions, suggestions, or anything, feel free to e-mail us, Marko Mäkelä or Olaf Seibert . Olaf is the Amiga and PET expert, other questions should be directed to Marko. In case you prefer snail-mail, here is the address: Marko Mäkelä Sillitie 10 A 01480 Vantaa Finland (This file is formatted using the ISO 8859-1 (Latin 1) characters. In case your terminal displays some other character set, you will see the ä characters (a-Umlaut, "a" with two dots on top of it) incorrectly.)