Tuesday, January 31, 2017

MACRO-11 List File Parser for embedded PDP11s




  Recently I've been working on a controller to use on assorted electronics hobby projects. I considered all the usual solutions - Raspberry PIs, Arduinos and the like. But that technology is not really where I'm at. I like solutions are are state of the art tech...for the 60s,70s and 80s.

   I decided to use some old DEC T-11 chips I had kicking around for the CPUs - my needs for compute power and memory are modest, and I can write MACRO-11 code in my sleep. The T-11 chip was a DEC product designed for use in embedded products. It implements a pretty durn complete PDP11 on one chip, and has options that enable it to work with a minimum amount of support circuitry. The T-11 doesn't include any IO capability, so I needed a chip to handle that. I had no requirement for terminal IO so I didn't need a UART. I decided to use one of my all time favorite chips for IO - the Rockwell 6522 Versatile Interface Adapter. The 6522 has 16 lines for IO, two timers, and four handshaking lines. It will handle any of my projects with ease. 

   So, after lengthy design and prototyping sessions, I have T11/6522 systems to play with. Now, since all hardware projects inevitably turn into software projects, I needed some code to make it go. I started out with my trusty old PDP-11/70 programmer's card (my old pal Dr. Bob said that these should have included some blister packed Valium on the back of them).  Assembling code by hand and entering it into my EPROM programmer's editor was beyond tedious, and modifying the code once it was written was even more of a challenge. To make it a little easier, I started coding the programs in MACRO-11 on an RSX system, and then reading the part of the listing file that contained the octal bytes generated. Here's an example. The generated bytes are in the 3rd, 4th and 5th columns. I could read them from there, translate to hex, and enter them in the editor screen for my EPROM programmer. Lots easier than hand assembling everything. 


     25 ;+
     26 ;  set 6522 port A & B lines
     27 ;-
     28 100000 z::
     29 100000 005003                                  clr             r3
     30 100002 012706 077760                    mov         #77760,sp
     31 100006 112767 000377 077667 movb #377,ddra
     32 100014 112767 000377 077660 movb #377,ddrb





This was easier, but was still pretty tedious - lots of reading, converting and typing to do. Time for more automation. I thought about reading and converting the object files from the assembly, but that looked like a lot of work. Instead, I wrote LISPAR.MAC, a utility that can read a listing file, parse out the memory columns, convert them to hex and output them as an Intel Hex record, ready for my EPROM programmer to digest.

  LISPAR is a pretty standard sort of RSX family utility - it uses GCML and CSI to get command input, FCS to do the file IO, and TPARSE to parse the input file. I've included it on the very remote chance that someone out there is working on PDP11 bare metal and doesn't already have a better cross assembler or other solution. I should point out that lispar is only useful on simple programs - it won't do anything useful if it encounters system calls or directives that don't emit anything (like .blkb for instance) or anything too hairy. It can deal with macros, but you'll need to add a .LIST MEB to the top of the program to get the binary expansions of the macros to appear in the listing.

  To make...
  >mac lispar=lispar
  >tkb
  TKB>lispar=lispar
  TKB>/
  Enter Options:
  TASK=...MLP
  //

  To use...
  >mac ,somefile=somefile
  >ins lispar
  >run lispar (or install it and invoke as MLP).
  MLP>outfile=somefile
  The output file will be in Intel Hex format.
  Input file default extension is .lst. Output file default extension is .hex
  The Intel Hex records are set to load at address 0. If you need another address, use the /adr switch.
  MLP>outfile=infile/adr:1000


Friday, March 8, 2013

Standalone floppy copy for PDT-11/150

 A goodly while back, I saved some PDT-11/150s from the dumpster. These are interesting little boxes. They contain a sort-of PDP-11/03 CPU, some memory, some terminal lines, and two RX floppy drives. Of note is their busless construction - instead of a Qbus and plug in memory and controller cards, the interface for the devices is provided by an 8085 microprocessor located on the CPU board. Also unique (as far as I know) is the size of the IO page - instead of 8KB like on all other PDP11s, this one has a 4KB IO page (I'm guessing, they did that to make 4KB more available to user programs).

  I've always thought that if DEC had marketed these for hobby and home use we could have prevented the rise of the PC and X86, but...that's not how it turned out on this timeline.

  Anyway, when I got them they didn't have any software. I managed to find an RT11 floppy that was purported to run on it. I was reluctant to use that floppy, though, since it was old even back then, and I didn't want to risk my only diskette with software on it without making a backup first.

  A look at the Users Guide for the PDT-11/150 showed that it would be pretty simple to write a program that I could "toggle in" with ODT that would copy a floppy.  I wrote DXCOPY to do just that, and it enabled me to copy the original RT disk to some working diskettes that I could then use without fear of losing the original. After I got RT-11 installed, and figured out how to work it, then I was able to use it to make copies instead. 

  On the remote chance that anyone out there besides me has any interest in working on a PDT-11/150 at this late a date, I include DXCOPY here. The values to load are included in the comment field - just load them with ODT at some address above 2000, load a source floppy in drive 0 and a destination floppy in drive 1, and give it the G command. When it finishes the hellishly loud thrashing of its heads back and forth, and the copy is complete, it will HALT. No user interface, no error checking or messages - just the bits flying from one disk to the other.


dxcopy.mac

Monday, December 31, 2012

DZREAD

    The complementary program to DZWRITE, is DZREAD. It reads an RX50 floppy on a PRO and writes it to a file.

  Here it is...

dzread.mac

  Assemble Link and run like DZWRITE. Or, if you're  tight on memory and disk space, you can link it to FCSRES and save a few bytes. DZWRITE can be linked this way as well.

$ MAC DZREAD
$ LINK DZREAD/OPTION
Option? LIBR=FCSRES:RO
Option?
$ 
Put floppy in...
$ DISMOUNT DZ2:
$ MOUNT/FOR DZ2:
$ RUN DZREAD
DZR>SOMEFILE.DSK=DZ2:
$

While writing this program, I ran into a crazy P/OS bug. Originally, I wrote it to read the floppy, block by block, and when I got a return status of IE.BLK (logical block too large) , I would know I was at the end and could close the DSK file and exit. When I did that, I got DSK files that were 801 blocks long....not right since the RX50 floppy is only 800 blocks big. A look at the 801st block in the output file revealed that it was a copy of the first block from the floppy. Evidently the DZ driver has an off by  one error in its range checking, and when the DZ controller and floppy drive gets a request for a block too large, it returns the block modulo 800. Even worse, the same thing occurs for writes - if you request the 801st block be written, it writes it to the first block...not good. DZWRITE didn't see that problem since DSK input files are only 800 blocks or less long, so it never tried to write an 801st block. 

  You can see this problem with DUMP. If you mount an RX50 foreign, and

$ DUMP/BL:800

  Which requests the 801st block, since they start at block 0, you'll see the first block dumped out. requesting block 0 and block 799 returns, correctly, the first and last blocks.

  I modded DZREAD to count blocks and stop at 800. Now the output files are the right size, and have all the right blocks in 'em.

Thursday, December 20, 2012

DZWRITE

  Recently I decided that I could reduce the storage space consumed by the assorted small PDP11 parts here by assembling some of them into systems. I had a BA23 cabinet and a pretty good selection of QBUS cards to work with. I installed an 11/73 CPU, a memory board, a DLV11J, a DHV11, an RQDX3, an RX50 and an RD53.

   The RD53 needed formatting, so I needed XXDP running on the system. I tried to use VTserver to load XXDP into memory, but, for some reason, it doesn't seem to play well with Windows 7 as the host. I spent quite a lot of time trying to debug it and discovered that it often completes IOs without bothering to get any input characters. This confuses the rest of the program (and me).

  Growing weary of Microsoft and Visual C++, I looked for another solution. It occurred to me that my old PRO-380 (formerly a VAX Console) had RX50s on it as well, that would allow me to create media for the 11/73. I dusted it off and spent a couple of days troubleshooting it. It was having all sorts of disk errors. I spend several days formatting and testing a goodly number of ST506 disks before I realized it was a bad disk controller card. I popped in a spare and all was well. After tussling with it and struggling with VTserver, I was glad to get a little closer to the original project again.

  I wrote a little program that will read an RX50 disk image file and write it to a floppy. On the long chance that there is anyone left in the world interested in using a PRO running P/OS system to support their PDP11, here it is... 

dzwrite.mac

  To use... 
$ MAC DZWRITE 
$ LINK DZWRITE
Insert floppy... 
$ DISMOUNT DZ1: 
$ MOUNT/FOR DZ1: 
$ RUN DZWRITE
DZW>DZ1:=somefile.dsk
DZW>^Z
$ DISMOUNT DZ1:

  The image I used was a copy of XXDP.DSK I found on the web that had the RQDX3 formatter on it. After DZWRITEing the image onto an RX50, I loaded it on the 11/73, and it booted fine. Unfortunately, the RQDX3 formatter sees the RD53 as an RX33, and is reluctant to format it, so it looks like I have some more hardware to sort out on that end...