PDP-11‎ > ‎


Linux TU58 Emulation Source Code

I happen to be a fan of DEC PDP-11 systems. In the 1980's they made a block oriented tape device called a TU58 which used self contained "DECtape II" tape cartridges. This unit could be connected to a PDP-11 or VAX via an RS-232 serial line. Both can boot diagnostics packages from this medium. I created and released an MSDOS based TU58 emulation package. Later I discovered that really I had just reinvented the wheel again as Dan Ts'o of Rockefeller University had already published a BSD Unix TU58 emulator. Source code for this emulator can be found at dbit.com and sunsite. Note that this code contains a copyright notice which permits use so long as it is NOT sold to others.

Recently I tried to get this code to work under Linux. It was harder than I expected, and I have not been completely successful. If anyone is interested in looking at the unresolved issues, please contact me. I have ended up with an executable that runs on my Linux 150 MHz box and will boot and run RT11 on a PDP-11/23 at 19200 baud. It also works with an MSDOS based test program, rsp.exe, I originally wrote to test my MSDOS based emulation program. However it does not work reliably with E11 which concerns and puzzles me. I've spent about a week on this project and become frustrated. I do not pretend to be a Linux/gcc guru and could use some help. I thought I would put my efforts in the public domain, hoping someone will see what I am missing. I trust I am not breaking any copyright laws by adding modifications to the original work.

In summary, the major change is in the serial port initialization. I created a new main module, lmain.c. Under gcc I can't find struct sgttyb, gtty(), nor stty() which were all called from the original init_device() routine in main.c. My new program, ltu58, can be built with gcc using the new 'makefile'. This makefile also includes commands to build btu58 from the original main.c using the gcc BSD compatibility switches. I had hoped this would work, but as near as I can tell the BSD compatibility does not include the required serial port routines (corrections or additions regarding this comment would be appreciated). I left the original code which attempts to handle permissions if one is not the root user, but I don't think ltu58 works unless its run by root.

I made changes in the debug.c file as I couldn't figure out how to get the major and minnor mode of the serial device from the file name under Linux. There is likely a method I don't know, but I just create debug files (if DEBUG is defined) based on the device name. I also made modifications to tu58.c, primarily adding debug statements. However fread() and fwrite() exist in libc, and I renamed these functions by prepending 'tu58' to the names in tu58.c and file.c to avoid conflicts. The only major problem I found was a call in file.c from fposition() to fupdate(). This is done each time the RT11 directory block, 6, is accessed and reopens the emulated tape file. This appears to close the file the program is using and index the global variable fpt out of range. Commenting out this RT11 specific code allowed the program to run successfully with an 11/23 system. There is a comment in the source code regarding this call and in the readme.txt which mentions 'rtpip', a program I know nothing about, any help would be appreciated here also!

When I got ltu58 to work with my test program, rsp.exe, I thought I was home free. However I find E11 by John Wilson a very useful test platform, and I can't get ltu58 to run reliably with the MSDOS Demo version of E11 V3.0. I'd like this to work as its a great validation test as well as a good method of creating bootable DECtape II XXDP images. I have followed recent newsgroup discussions regarding E11 and TU58 tape drives which suggest using the /TXMAX:1 switch in the com port assign statement, but this doesn't seem to be the problem. Both my Linux and MSDOS based code sees E11 sending 0xff,0xff where I would expect a break. This does not seem to be a major problem, but ltu58 displays a message about an unknow octal flag 0377 when this occurs. However ltu58 seems to get lost after the 1st or second command packet from an RT11 dir command sent by E11. The programs end up in some sort of deadlock where each is waiting for data. I am suspicious of tu58.c where there is a call from evalflag() to clearbuf() which in turn calls clearcbuf() when the flag TUF_INITF is recieved, but not at all sure this is wrong. Logically flushing the input buffer at this point seems ok, however in my tests E11 seems to have already sent the next command packet when the TUF_INITF flag is seen. Oddly I can sometimes get ltu58 and E11 to work together by adjusting the baud rate. It seems to work at some baud rates and not at others. The E11 throttle setting can also make a difference!

If this puzzle interests you, please pick up the pieces and see what you can do. I have created a Linux Lha archive that includes this descriptive file, the modified emulator source code, a Linux version of ltu58, and my MSDOS test program, rsp.exe, as indicated below:

Listing of archive : LTU58.LZH

  Name          Original    Packed  Ratio   Date     Time   Attr Type  CRC
--------------  --------  -------- ------ -------- -------- ---- ----- ----
  checksum.c         524       279  53.2% 00-03-01 10:19:14 a--w -lh5- 445C
  debug.c           1549       767  49.5% 01-09-04 09:49:26 a--w -lh5- 3562
  debug.h            591       230  38.9% 02-02-22 18:13:52 a--w -lh5- 497D
  file.c            4830      1902  39.4% 02-02-27 15:01:56 a--w -lh5- 07FC
  io.c              2239       889  39.7% 00-03-01 10:13:52 a--w -lh5- 5EAD
  lmain.c           5827      2524  43.3% 02-02-21 17:14:22 a--w -lh5- F95E
  ltu58            44730     16818  37.6% 02-02-27 15:08:52 a--w -lh5- FEC1
  main.c            2871      1266  44.1% 00-03-01 10:16:04 a--w -lh5- A1B1
  makefile          1315       534  40.6% 02-03-01 10:37:44 a--w -lh5- 28D1
  readme.txt        2276      1204  52.9% 01-09-01 14:34:36 a--w -lh5- F282
  rtdir.h           1000       320  32.0% 00-03-01 10:15:30 a--w -lh5- 642C
  tu58.1            1166       595  51.0% 00-03-01 09:53:14 a--w -lh5- 79E5
  tu58.c            6687      2616  39.1% 02-02-27 15:08:36 a--w -lh5- CB90
  tu58.h            2777      1204  43.4% 01-09-03 10:48:22 a--w -lh5- 3CEF
  RSP.EXE          86073     41398  48.1% 01-05-13 11:55:48 a--w -lh5- B04C
  CONSOLE.INI         34        34 100.0% 00-02-24 21:40:40 ---w -lh0- B8DE
  LTU58.HTM         9616      4375  45.7% 02-03-01 12:06:12 a--w -lh5- 7AC9
--------------  --------  -------- ------ -------- --------
    17 files      172497     76241  44.2% 02-03-01 11:52:08

The following files are identical to the original distribution, but the time stamps have inadverantly been changed:
readme.txt, tu58.1 - these are documentation files
main.c, checksum.c, io.c, debug.h, rtdir.h, tu58.h
The original distribution also included empty.c which is not required for the Linux build.

Build ltu58 under linux via "make ltu58".
Run it on ttyS1 at 9600 baud via "./ltu58 -s9600 /dev/ttyS1 image_file"
where image_file is your DECtape II image file.
I also added an optional -t arguement. If used the image_file is ignored, and at startup the program sends "hi will", then waits for serial input and echos it back to the sender until a 'q' is recieved. Nothing is echoed on the screen, but its a good test to validate the serial line connection/initialization.

RSP.exe and console.ini are the only MSDOS files included. Source code for my rsp.exe is available if anyone is interested, but its not real exciting. It initializes the COM port based on the console.ini file contents, a sample for COM1 at 9600 baud on irq 4 is included. The irq line may be omitted, in which case the PC defaults are used. The program is interactive and will test most RSP (radial serial protocol) commands. The first letter of each interactive operation triggers the operation. Several prompt for more data, ie start block and number of bytes. The default mode is to dump any input on the serial line in hex to the screen. For example, issue a read command by pressing 'R' and it will prompt for the start block and # of bytes desired. Then send RSP packet commands to the host and dump the data it returns to the screen. Copy, 'C' is an exception in that it writes the data packets to a file rather than dumping to the screen. One can copy all or a portion of an emulated TU58 tape this way, and it seems to work fine with ltu58 at 19200 baud! Conversely Write, 'W', will copy blocks from a source file back to the emulated TU58 tape.