Wednesday, April 13, 2022

VAXstation 1 and PDP11 QBUS systems software install via ethernet programs (finally)


  Note - new versions of some of these programs are coming out this month. Watch for them as a new blog entry


   OK, after all of the previous confusing blog posts explaining how they work, here's some of the programs that actually do something.

   When this project started out all I wanted to do was load a disk image onto a VAXstation I without any physical hardware gyrations (floppies, tape drives, disks loaded on one system and moved to the VAXstation I, etc - you know, the usual).  As time went by I realized the same principles would also work for loading disks on QBUS PDP11's, and I actually have more occasion to do that than I do fooling with VAXstation I's - as a result, I wrote  PDP11  versions of the programs as well as VAXstation I programs, and have used them a heckuva lot more.

  So, for this project, there are  server programs and client programs.

 Server programs  run on a normal host system. There's nothing exotic or hardware dependent about the server programs - they are normal tasks/images that use supported techniques to send and receive packets on the ethernet and save/restore/check them to a disk file. Server programs' names all start with LOCAL (for VMS based server programs) or LCL (for RSX based server programs). The second part of the server programs name is determined by what function is being performed by the corresponding client. So, the VMS server program that serves blocks to a client program, that is writing the blocks to the target disk is named LOCALWRITE. The VMS server program that accepts blocks transmitted from the client, to save into a local disk image file, is called LOCALREAD. The VMS server program that compares a local disk image file to the contents of a disk on the target system is LOCALCHECK. In like wise, the RSX versions of these server programs would be called LCLWRT,LCLREAD and LCLCHK (but they haven't been written yet - they're on the way).

  Client programs are...different. They are not normal tasks/images. They run on the bare metal of the target system with no OS (heck, if you had an OS on the target systems, we wouldn't be doing all of this in the first place, nicht wahr?). They are assembled and linked special, and then get loaded onto the target systems via DECnet MOP, booting, as a system image. They are named similarly to the server programs - they start with REMOTE or REM (VMS or RSX), and the second part of the name refers to the function they are performing on the target - REMOTEWRITE is getting blocks off the ethernet from LOCALWRITE, and writing them to the MSCP disk on the target system. REMOTEREAD is reading disk blocks from the MSCP disk on the target and sending them to LOCALREAD to be stored in a disk image file. And like that for the check function, and for the RSX images.

  Clear so far? And here I want to point out that the server programs are not OS specific - that is, LOCALWRITE.EXE, running on a VMS host system, will work just fine with REMWRT.TSK running on a PDP11 system. Same goes for LOCALREAD.EXE and REMREAD.TSK, and LOCALCHECK.EXE and REMCHK.EXE. And the same symmetry will hold when LCLREAD, LCLWRT and LCLCHK server programs are written on RSX - they will support VAXstation I clients as well as PDP11 clients. But, like I say, currently, the only server programs are for VMS. Why am I writing this before the RSX server programs are done? Because I ain't writing them right away since I want to work on some other projects for a while....I'll eventually get back around to it. And probably some MicroVAX II client programs as well - that would be more widely useful than the VAXstation I ones. Lots more MIcroVAX IIs out there than I's. Anyway...here's the programs thus far...


  Update - this version of remoteread.mar and localread.mar has bugs and is being withdrawn. A new version is available in a later post on this blog. remotewritewrite.mar and localwrite.mar are withdrawn here, since new versions are available - they're in the later  blog post as well.

  Additional update - remwrt.mac has also been updated, and is available in a later blog post. The version listed here is withdrawn.


localread.mar

localwrite.mar

localcheck.mar

remoteread.mar

remotewrite.mar

remotecheck.mar

remread.mac

remwrt.mac

remchk.mac


  OK, so how do you use 'em? Here's an example. Suppose you have a MIcroPDP11 with an 11/73, an RQDX3, RD54 and DEQNA in it (a DELQA would probably work too - their software interface is not that different). You'd like to load software onto the disk. The first step would be to use SIMH or some other simulator to install RSX onto an RD54 disk image. If it's not already there, copy that image file to the system you'll be using as the server. Then, you'd edit remwrt.mac, the PDP11 client task for writing to the client disk, to indicate what file on the server system that image is in. The name is located at label filnam.

filnam: .ascii  /dua1:[mvax1]zombie.dsk/

  Save your change and assemble remwrt.mac

  >mac remwrt=remwrt

  Task build it...

>TKB
TKB>remwrt/-hd=remwrt
//
CORSIZ=32
STACK=0
PAR=GEN:0:160000
UNITS=0
/
>
  Ya gotta task build it funny, since it's not going to use an OS - its task is just a bunch of code that gets loaded. into memory like a system image.

  Alright, now you've got a system image that will request the disk image you want loaded. Next step, is to create or modify a DECnet node definition for the client node, on the system where the remwrt.tsk you just built is located. For this step you'll need to know the ethernet address of the target system. If you don't know it, read it off the card, or just try to boot it and read it from the failed load error messages on system consoles.  

For this example, let's say it's 08-00-01--02-03-04, and use the name zombie, as examples.

>
NCP>set node zombie addr 10.111 (address doesn't matter - make it unique for your site)
NCP>set node zombie service circuit QNA-0 hardware address 08-00-01-02-03-04
NCP>set node zombie  load file du1:[test]remwrt.tsk
NCP^Z
>

  Or you can use LANACP instead of DECnet to do this...if that's what you want...you know what to do instead.

  If you already have the node defined, you don't need to do all of this jazz every time, natch - just change it to match your current situation - usually just the filename changes.    

  OK, all set, client-wise. Now go to your VMS system and run LOCALWRITE.EXE. It will sit there waiting for a request from a client system. Go to the client system and tell it to boot from the ethernet, however it wants that done. On my test 11/73, I CTRL-C out of the autoboot and tell it to B XH0:

  When you do that, the system where REMWRT.TSK is, and where you set up  DECnet to load it, hears the MOP boot request, and  loads it into the client system. When it runs on the client system, It will then set up the RQDX and the ethernet card, while printing a truly eye watering amount of diagnostic messages, left over from development and that I'm too lazy to remove, then starts up and broadcasts a request for a server to feed it zombie.dsk. LOCALWRITE.EXE on the VMS system hears that request and starts sending blocks, which the client receives and writes.  You get a progress message on both systems every 1024 blocks or so. After a couple hours, it will print a done message, and now you have a runnable PDP11 - assuming you've done everything right. A couple hours is significantly faster than using something like VTserver or PDP11GUI to do the transfer on an asynch RS232 port.

  Here's what it looks like, up through the first 1024 blocks...

Commands are Help, Boot, List, Setup, Map and Test.
Type a command then press the RETURN key: B XH0

Trying XH0
Starting system from XH0
remwrt
deqna card vector
01FC
new deqna card vector
006C
old psw
FFE8
new psw
FFE8
init RQDX3 via RIP write
read and display RSA
0B40
current step value
0800
current step bit was set in rsa - write next value to rsa
step
8000
r3 shifted
1000
read and display RSA
1080
current step value
1000
current step bit was set in rsa - write next value to rsa
step
9900
r3 shifted
2000
read and display RSA
2000
current step value
2000
current step bit was set in rsa - write next value to rsa
step
0000
r3 shifted
4000
read and display RSA
4134
current step value
4000
current step bit was set in rsa - write next value to rsa
step
0001
r3 shifted
8000

RQDX3 Init complete
dskini returned
disk online touch IP
4000
0001
0000

disk characteristics
media type id
2564
4036
unit size
0004
BFA0
volume serial number
00BC
614E

RQDX3 Online complete

dskonl returned
Ethernet Address is...
08  00  2B  06  92  6D

starting DEQNA csr
1032
starting DEQNA csr decoded
CSR Set
SR  XL  RL  OK
CSR Clear
RE  NI  BD  IE  XI  IL  EL  SE  RR  CA  R2  RI
reset DEQNA csr decoded
CSR Set
XL  RL  OK
CSR Clear
RE  SR  NI  BD  IE  XI  IL  EL  SE  RR  CA  R2
Post reset DEQNA csr
1030
enter setup tmit
DEQNA setup interrupt
setup tmit fired
seek
send initack
got init packet
block delivered
0000
0000
block delivered
0000
0400
(note- the block delivered count is in hex, so 0000 0400 = 1024 decimal)

  Correspondingly, here's the message that occurs on the server system running LOCALWRITE.EXE. The double write of Newblk: 0 is a bug I haven't bothered to run down yet. Note that these counts are in decimal...so 1024 = 1024.

$ run localwrite
dua1:[mvax1]zombie.dsk
Newblk: 0
Newblk: 0
Newblk: 1024


  To write a disk image onto a disk in a VAXstation I, it's very similar. Edit REMOTEWRITE.MAR and change the file name at label filnam to match the name of the image file to use.

filnam: .ascii  /dua1:[mvax1]undead.dsk/

  Save the edited file. Assemble it.

$ mac remotewrite

  Link it, sort of funny, so it's a system image.

 $ link/notrace/nodeb/system=0/header remotewrite

  Make a system, image with SIMH.

  Use NCP and make an entry, just like for the above example.


$ mcr ncp
NCP>set node undead addr 10.112 (address doesn't matter - make it unique for your site)
NCP>set node zombie service circuit QNA-0 hardware address 08-00-01-02-03-04
NCP>set node zombie  load file dua1:[test]vaxzombie.dsk
NCP^Z
$

  OK, all set, client-wise. Now go to your VMS system and run LOCALWRITE.EXE. It will sit there waiting for a request from a client system. Go to the client system and tell it to boot from the ethernet, however it wants that done. Things proceed from there just like for the PDP11 case.

  Alright, writing disk images works pretty good. But after a while I wanted to save the work I'd been doing on  these systems. It occurred to me that relatively minor changes to the code could produce client and server programs that worked the opposite direction - read blocks from the local disk and send them across the network to a server program, to save in an image file.

  To do that, it's almost exactly the same as above. Edit remread.mac or remoteread.mar, and change the filename at label filnam: to whatever you want to call the resulting image file. Assemble and link. Make NCP changes to get it loaded when the client wants to boot. Run LOCALREAD on a server system. Boot it up and off it goes. When it's done, you'll have an image file of the contents of the disk on the client.


  OK, there's the basics - read and write. But, I'm pretty paranoid - how could I be sure that the entire disks were getting read and written OK? I wrote a set of server and client programs that will compare the contents of a client's disk to a disk image file. LOCALCHECK.MAR, REMOTECHECK.MAR and REMCHK.MAC.

  Ya set 'em up just like the above - edit the filename at filnam, of the image file to check the disk against. Assemble & link, set up network boot. Run the server program and boot the client system via ethernet. The programs will start comparing block checksums. You'll get progress messages, and eventually a successful exit...or lots of messages about disk differences. Either way, good to know.

  And that's our story thus far.