Monday, August 21, 2023

Installing software on Microvax and MicroPDP11 systems - update

   Recently, Hans-Ulrich Hölscher did some experimenting with the programs I wrote that allow copying a disk image from any VMS or RSX system to a MicroVAX I or PDP11, that has no software already loaded, via ethernet (see several blog posts, with VAXstation I" and "install" in their titles).

  I was surprised when he reported a several things I hadn't realized about those utilities. I had assumed that they wouldn't run on SIMH systems, or on MicroVAX IIs, due to differences in their internal architecture from the MicroVAX Is and real PDP11s I wrote and tested them on. Ulli pointed out that they actually worked on SIMH instances of MicroVAX Is, and as well on SIMH images of MicroVAX IIs, and, very likely, real instances of MicroVAX IIs.

  As well, he reported that DELQA ethenret cards work as well as DEQNAs.

  I checked it out and his reports were correct. I reckon...1 - that the architectural features I used to make this work with MIcroVAX/VAXstation 1s were also present on the MicroVAX/VAXstation II, and...2 - SIMH MicroVAX I and II emulators also include all of those features. Bravo, SIMH developers!

  OK, so he reported that they worked, and indeed produced a good disk copy, but they emitted a zillion error messages when run with an emulated system as the target. A little study showed what that problem was - I had used timing loops extensively in the downloaded code, and SIMH and real MicroVAX IIs run a whole heckuva lot faster than the real MIcroVAX I hardware does - so things were timing out and retrying a lot more than they needed to.

  Another dive into the MicroVAX architecture documents produced a solution - there is an Interval Timer included in the MIcroVAX architecture. If enabled, it will produce an interrupt every .01 seconds. This will allow me to produce a delay of fixed time, regardless of how fast the machine or simualtor it is running on.

  The clock interrupt is controlled by the ICCS (Interval Clock Consoltr/Status) register, internal register #^X18. When bit 6 is set in it, it will produce an interrupt via the vector at SCB offset ^XC0 every 1/100 of a second. When bit 6 is clear, the clock interrupts are turned off.

  So, setup the vector for the clock interrupt.

        mfpr    #^X11,r7        ;move scb addr to r7
        moval   tick,^XC0(r7)   ;point vector C0 at routine "tick".

  Here's the interrupt routine. Not much to it, nicht wahr?

tick:   incl    clock
        rei

  Then, whenver I wanted to delay for some fixed amount of time, regardless of processor speed, I enable the clock interrupt, clear the clock variable, and wait until the variable "clock" reached the number of 1/100ths of a second I needed.
 
 A macro is used to invoke it.

;+
; Wait for specified number of .01 seconds ticks
;-
        .macro  waitm   beat
        pushl   beat
        calls   #1,waitm
        .endm   waitm

  Here's the routine the macro invokes..

;+
; Wait for a specified number of "ticks"
;-
        .entry  waitm,^m<r2>
        movl    4(ap),r2        ;# of ticks needed to r2
        clrl    clock           ;start fresh
        mtpr    #64,#^X18       ;Enable timer interrupts 
1$:     cmpl    r2,clock        ;had enough?
        bgequ   1$              ;please sir, I want some more
        mtpr    #0,#^X18        ;turn off the interupts when done
        ret

  On the plus side, it was simple and easy to write. On the negative, it will totally not be of any use if I ever start using multiple streams of execution. As is, It has to be used with caution if used in an interrupt routine, since that has the potential to step on the use of it in the non-interrrupt code. For now I elect to just be mindful of that when coding. Sketchy as hell, but, in this no-OS environment, what isn't?

  As well as taking care of the timing loop issues, these new versions address a deficiency that Ulli pointed out - the disk unit targeted had to be assembled into the program. He pointed out that being able to enter what unit to target would be a lot more flexible, and less prone to writing on the wrong disk by mistake. In support of that, he figured out how to get input from the console, and provided examples to demonstrate how to specify the unit number to target at run time. Thanks again, Ulli!. I also added the ability to specify what file to load at run time as well.

  Here's new versions of remotewrite.mar,localwrite.mar, localread.mar, remoteread.mar and sendcheck.mar. Note that the packet format changed, so that the older versions of these programs won't work with the newver versions - new remotewrite won't work with old localwrite, and so forth. New versions of the PDP11 programs are coming soon.

      *** New versions loaded 1-SEP-2023 ***