Wednesday, September 9, 2020

TU58 emulator for RSX11


  So every once in a while I try to retrieve some space here in the War Room (my computer room - we call it that because, during a spirited discussion about how messy it was, I jokingly told my wife "we can't fight in here - this is the War Room") by assembling some of the parts into systems. I have an old BA11-VA  QBUS box I got in trade a long time ago.I figured it could consume a few QBUS cards and maybe even do something useful (well, OK, maybe not useful, but at least amusing). 

I had a look at the specs for it. The power supply isn't all that powerful in that box, so the choice of cards is a little limited. It could just barely power an 11/23, an MXV11A and an RQDX3 in there. And that would have been a relatively useful system. - I could control a floppy and an old RD disk with it, and the MXV would provide memory and two serial ports.


  But, I didn't have a PDP11-23 (I got plenty of 11/23+s, but no plain 11/23s). An 11/23+, MXV11A and  RQDX3  together  draw too much power for that plan. And, I was in no mood to make the cables required to use the RQDX3 without the breakout board it gets used with in BA23 system boxes. And ST506 hard drives are loud and getting rarer every day. So scratch that idea - even though it would have allowed me to use RSX on it. 

  I decided to use an 11/2 processor (KD11-HA), and an MXV11A. The MXV11A has memory and boot roms on it, and it has two serial ports. One gets used for the console. The other one can be used to connect to a TU58 drive unit, which provides (slow and annoying) mass storage to the system. This won't run RSX (well, it would run unmapped RSX, but that's not my idea of a good time), but it could run RT11 and stand alone programs.

  A few articles back, I joked about how richly hated  TK50 drives were. Another DEC tape device that was not well liked was DECtape II - the  TU58. TU58s were little tape cartridge drives, that were used like a disk. Like their previous generation's namesake, DECtape, they were block addressable like disks and you could rewrite a block in the middle of the tape. TU58s connect via RS-232, and use good ole async serial ASCII to communicate with the system. TU58s were tiny (only held 512 blocks, 256K) and slow - very slow. They usually connected at 9600 baud, and seek times were...long.

  Since they were  controlled like disks, that meant that they were managed by a disk ACP on RSX . Disk ACPs are single threaded for all the disks that they control. If you mounted a TU58 using the same ACP as, say, the system disk, you would stall all disk activity on the system disk  whenever the TU58 needed a few minutes to seek to the end of the tape looking for a block...this is bound to make the phones ring...

  TU58s showed up as load media on assorted DEC systems. They were why VAX-11/730s and HSC50s booted slowly. A TU58 was used as part of the boot process on my old 11/725, and it took quite awhile. I managed to cut the amount of time booting required in half  by careful arrangement of the needed files on the tape so that rewinds were avoided.

  Real TU58 drives, however, are scarce these days, and almost all of the rubber capstans in them have deteriorated into gooey messes. Not a problem, though - lots of folks have written TU58 emulators, that connect to the serial ports and serve blocks back and forth just like a real TU58 unit does. Here's a couple of  good projects that illustrate use of them




   On the implementation side, Will Kranz has done a lot of work on TU58 emulation in general - lots of good info on his page at


especially about the new version of the RSP protocol, MSRP.

  Don North has also done a lot of work in the area, both on emulators and on tools to manipulate TU58 images. See some of his work at


  So, there's lot's of TU58 emulators available. But, (as far as I could discover), they all run on Windows, Linux, and a few run on stand alone microcontroller gizmos. I'm sure I've mentioned it before, but let me repeat again here, that I hate Windows and Unix/Linux with the incandescent, coruscating, ravening white hot soul searing  intensity of a billion exploding supernova antimatter hypergalaxies. Now that I think about it, I don't like Alphas, Itaniums or VMS-X86-64, either, but all that's another story... anyway, I will be thrice damned before I use Windows or Linux to support a DEC hardware project. I decided to write my own emulator, using my favorite platform - RSX11M+.  I'm a lot more likely to have RSX running here when I need to emulate a TU58 than I am Windows or Linux...

  To develop and test this program, I used a Micro-11/73 I already had. By luck, this old system came with a DLV-11 already installed - this was fortunate, since that is what RSX uses to communicate with TU58s. I connected a cable from it to my HP 4951C logic analyser, and from it, back to a DHV11 TT port back on the same 11/73 system. This way, RSX would be looking to see a TU58 on the DLV, and  my emulator program would strive to look like one on the DHV port. 

  The HP 4951C is a piece of gear I recently got on Ebay for $100, and it's invaluable for this sort of thing. It lets you see what's really on the wire, instead of having to add debug print statements and guessing which side wrote what, when. It cost $3500 back when it was new - but, there's not much demand for them anymore, since ASCII communications on RS232 style connections are pretty rare these days. If you have to do any work like this, I highly recommend acquiring one. It's from the golden age of HP test equipment.

















  So, basically, a program to emulate a TU58 boils down to doing a bunch of reads and writes.  Writes are easy - Just assemble a protocol message and send it out in one piece, via a QIOW.  Reads are another story. You can't really predict what or how much you're gonna get ahead of time, so you can't just do a read and wait for some number of characters.  The easiest way to code something like this would be to do one character reads and react to them as they come in, as the protocol requires. I didn't even try that strategy - doing that many QIOWs at 9600 baud or higher would be a surefire recipe for failure.

  Years and years back, Jamie Hanrahan (RIP) posted somewhere a description of his strategy for dealing with IO for a protocol on a serial line. I spent a couple of days looking for it -  couldn't find it. It may have been part of the comments for the DECUS UUCP project he worked on - I'm still looking for it. Anyway, as well as I can remember, it did a one character, non-blocking QIO read. When that read completed, it activated an AST that determined how many characters are in the typeahead buffer, then did a QIOW that actually read them. Those two steps repeat (getting the count, and reading that many characters) until the typeahead count returns 0). When the typeahead buffer is empty, the one character QIO is reissued, thus arming it for the next burst of incoming data. I inserted the incoming characters into a circular queue, and the code running at non-AST level de-queues them out one at a time as needed.

  The above strategy drastically reduces the number of QIOs vs the single character method - in this program, it does around 3 or 4 QIOs/data packet, vs. the 134 a full data packet would require, reading a character at a time. And, it doesn't get behind and choke itself to death, which is the whole point of doing it this way.

  Anyway, getting packets and then acting on them was middlin' straightforward. There were a couple of stumbles along the way, caused by the fact that every piece of DEC gear that accesses TU58s has its own set of quirks.

  For instance, RSP protocol has a boot protocol defined - but nothing I tested with used that - they all just did a standard read to block 0 when they wanted to boot. There is an enhanced protocol called MRSP that some TU58s support, with additional handshaking. TU58 hosts are allowed to query the TU58 if they support this protocol. XXDP and RT11 never queried about it. RSX queried about it - every other command  packet. It seems like DDDRV (the RSX TU58 driver) doesn't record the fact that we replied "none for me" to the MSRP query. Also,RSX occasionally "stutters" - emits two bytes of a packet, then starts over and sends the whole packet. RT11 likes to occasionally write FF into the unit and switch fields of a command packet for no reason.

  Anyway, it got done. I've tested this using RSX-11m+, RT11 and XXDP... Each one was a little different in behavior - for example, RSX never does a partial block read or write, while RT11 and XXDP do them both during boot and during normal operations. Here's a few screen shots of it in action...

  Running the program with raw command packet trace debug







  Here's RT11 booted from ETU58









  Here's XXDP booted from ETU58










So, here it is...



  Here's how to build it...

>mac etu58=etu58
>tkb
etu58/pr:0=etu58
/
suplib=fcsfsl:sv (or libr=fcsres:ro)
//
 
  To use, hook up the intended client device to a free terminal line and...

>run etu58
ETU>tt5:=xxxx.dsk,yyyy.dsk

 Where tt5: in the example is the  terminal line the client is connected to

xxxx.dsk and yyyy.dsk are example tu58 disk images.To use only one image,

ttx:=xxxx
  For only unit 0

ttx:=,xxxx
  For only unit 1

  There's one switch, /DBG, that will print out some debug info. It accepts a bitmask that determines what info to print.


BIt 0 - 1  prints out decoded incoming command packets
BIt 1 - 2  prints out raw incoming command packets
Bit 2 - 4  prints out comms related info
Bit 4 - 8  prints out queuing related info.

If you want more than one at a time, add up the values and enter as a decimal value
So, all four would be
  You get the picture...I like using /DBG:2

ETU>tt5:=disk0,disk1/dbg:15

 I like to run this with /DBG:2  - the raw command packets don't take up a lot of screen room, and you can easily see what unit, blocks and lengths are being requested. It was amusing to run this /DBG:2 while using disk1 as a shadow unit to disk 0 on RSX, and watch the load sharing occur (said load sharing was totally ineffectual, performance wise, since the requests are single threaded and not overlapped - still fun to watch). It's also fun to set the TU58 devices cached on RSX, and notice the reduction in IOs that get issued, as requests for blocks get served out of the cache.

  Any problems, let me know...I'm planning on improving this and testing it on more platforms (VAX is next), so I'd appreciate any feedback.








2 comments:

  1. Lee,
    I just noticed that you posted on this on your TU58 emulation project. I am very interested to learn more about the QIO read technique used to minimize the number of QIOs to read an arbitary amount of characters. That would have been very useful in some laboratory data acquisition projects in the past.
    Best,
    Mark M.

    ReplyDelete
  2. I'll email the details to you tomorrow.

    ReplyDelete

Comments?