[ih] ruggedized Honeywell 516 ARPANET IMP cabinet top lifting hooks (Was: The IMP Lights story (Was: Nit-picking an origin

Jack Haverty jack at 3kitty.org
Wed Aug 27 11:36:02 PDT 2025


Back around 2013, Bernie, Dave Walden, Ben Barker, and many others 
helped with a project to resurrect the early IMP code.  It was part of a 
legal activity involving the IMP as evidence of prior art in a patent fight.

As part of that, I did a "deep dive" into some of the IMP functions, to 
document exactly how certain IMP functions were accomplished.  I had 
never worked on the IMP code, or programmed a Honeywell minicomputer.   
I knew something about what the IMP did, but but not how it did it.

As always, the ultimate documentation is the code itself.

One of those IMP functions was the "reload from neighbor" process that 
was the first instance, that I'm aware of, of a computer downloading 
code from another computer using the network - the IMPs did that even 
while those computers were actually responsible for running the network 
itself.

The IMP code is the most complex, and innovative, piece of software I 
have ever seen.  It's also the "tightest" of coding and efficiency.  It 
uses "every trick in the books" and takes advantage of the details of 
how the hardware actually worked.  It also violates many modern 
programming principles, e.g., by using self-modifying code to store 
state information.

If anyone is interested...  Below is my "deep dive" analysis of the way 
in which the IMP actually accomplished reloads from some other IMP, 
which would occur either on command from the NOC or in response to 
failures such as crashes, checksum errors of the code itself, timeouts 
of the watchdog timer, and other such events during ARPANET operation.

The code analysis below refers to the IMP code from the early 1970s, 
which was recovered from an old listing and is now online at 
https://walden-family.com/impcode/c-listing-ps.txt   Anyone who wants to 
read the "functional trace" below will find it useful to have that file 
for reference.

==============================================================

Functional Trace – RELOAD

RELOAD is a procedure whereby a running IMP requests that one of its 
neighbors transmit back to it a copy of the bulk of its own core memory, 
and deposits it into its own memory, replacing what is there at the 
time. Some data is placed into memory (locations that will not be 
overwritten, to indicate to the “next” program that its predecessor 
asked for a reload – a “message from the dead” in effect.)

It then goes into a wait loop, ignoring all external activity. After a 
time, it drops out of the wait loop and does some simple checks to see 
if the reload process has completed (i.e., the neighbor IMP actually 
responded appropriately). If not, it attempts another reload, possibly 
from a different neighbor, and will continue to ask for reloads until 
one completes properly.

On completion, the IMP goes to its INIT routine, as if it had just 
started up, resets all I/O interfaces, and begins processing. Using the 
“message from the dead”, it reports to the NOC that a reload has just 
happened (as opposed to a power-up or power-fail restart.

The specific steps taken are:

 1.

    Entry is made at WDTM2 or WDLOD. If WDTM2 is used, the IMP will
    reload from the modem specified by the contents of the A register.
    If WDLOD is used, the IMP will select a modem line at random to
    request a reload. There are many ways to get to these entry points
    from other places in the code where the logic determined that a
    reload was appropriate. One form of entry is as a result of the
    watchdog timer firing, and the interrupt being handled at WDTM,
    which drops into WDTM2 to trigger a reload from a random neighbor.
    Regardless of how you get here, the result is a reload and restart.

 2.

    All interrupts are disabled except the clock. The host configuration
    (HOST34) is saved in location 46. At WDLUP, a call is made to the
    CLEA subroutine to clear all I/O interfaces. This is accomplished by
    changing all interrupt handlers to be handled by the watchdog timer
    handler itself (at WDT1), then issuing OCP commands to all hardware
    modem and host interfaces to unpatch the interface (the WDT2 loop).
    The software then enables interrupts and executes a wait loop for
    600 msec., by entering at WDT1.

 3.

    During that 600msec., interrupts will occur from the various I/O
    interfaces in unpredictable order. Each such interrupt suspends the
    600ms wait loop, and is handled by the same code as an interrupt to
    location WDT1, which starts its own 600ms wait loop after
    re-enabling interrupts. This processes continues, with each new
    interrupt suspending the current 600ms loop.

 4.

    Eventually interrupts stop happening, and some handler (whichever
    one got the most processor time) exits from its 600ms loop at loc
    1206. At that point (loc 1210-1212) it blocks all future interrupts
    and returns to LD8 with all I/O quiescent, all lines unpatched, and
    all interrupts disabled.

 5.

    Selction of the neighbor now occurs from LD8. If it is a random
    reload, the clock is read (loc 1043) and several bits used as a
    random number of modem interface to use.

 6.

    LD11 builds a request packet at SENDC, for transmission to the
    neighbor IMP. It contains the flags SNDCOR and LINETS which define
    it as a reload request. Similarly, OCP instructions are prepared for
    the appropriate modem output by placing the I/O instructions into
    the MIOTBP area (ModemImpOutputBufferPointer) for that specific
    modem, identifying the SENDC packet just constructed as the data to
    be sent.

 7.

    At loc 1053, a similar computation is made to create an appropriate
    instruction for the input side of the same modem interface,
    instructing it to place the next arriving data from that modem into
    locations from CORELO to COREHI. As defined in the listing, this
    covers the memory from location 60 to location 30000, comprising all
    of the IMP memory except for a few locations below location 60. One
    of these, locn 44, is used to convey the HOST34 info to the next
    resident program as described in (2).

 8.

    At loc 1057, the code jumps to the appropriate location to initiate
    output of the SENDC request packet on the selected modem line. E.G.,
    if modem 1 had been selected, the M1OUT instruction at LD1 would be
    executed to initiate output on modem 1.

 9.

    Continuing at LD12, a timeout loop is run (LD12 and LD13, using locn
    44 and 45 as a counter), allowing time for the request packet to be
    sent. When the timeout completes, the input instruction appropriate
    for the modem is executed (the X register specifies the modem being
    used). This initiates the process for data incoming on that modem
    line to be transferred directly into this IMP's memory (presumably
    the contents of the remote IMP's memory from CORELO to COREHI if it
    responds as expected). Note that this will result in the replacement
    of the instructions now being executed. Programmer and operator
    discipline guarantees that the new contents of these instructions
    will be identical., and this particular release contains several
    code fragments that reflect the existence of several different
    releases which might be present in any IMP. The code at LWAIT
    replicates the wait-loop function, but it is never called in this
    process. Most likely it represents where similar code resided in
    memory in an earlier release of the IMP software. Such techniques
    were used to permit new releases to be installed and tested, and
    then “rolled back” if needed.

10.

    Program operation continues at LD5 where a timer is set up using
    locations 44 and 45 (which will not be overwritten). After some time
    (long enough to transfer the entire memory contents, which are being
    placed directly into memory by the activity of the I/O processor
    attached to the same memory as the main CPU), the loop exits. It is
    now presumably running the new instructions just loaded from the
    remote IMP.

11.

    At LD7, a simple check is done to see if the I/O processor has
    indicated that input was performed into the entire memory (i.e., did
    it write all the way to COREHI). If not, something happened to
    corrupt the load, and control is passed back to WDLUP to repeat the
    reload process. Note that locn 47 still contains the number of the
    particular modem to use, or zero for a random reload. The next
    reload might be requested from a different IMP.

12.

    If the input did completely fill the IMP memory, it is likely to be
    a successful reload. At location 1106 it selects the SKS (Skip if
    Ready Line Set) appropriate for the modem just used, and stores that
    instruction in location 777 (which is outside of the “page 1”
    protected memory). It then transfers control to loc 777 to execute
    that instruction.

13.

    Operation continues at location 1000 or 1001, depending on the state
    of the modem's ready line. If an error is indicated, control is
    transferred to WDLUP, where a reload procedure is again initiated.
    Otherwise processing continues at location LD10.

14.

    At location LD10, the machine executes a sequence of instructions to
    restore the interrupt system parameters. It then transfers control
    to INIT – where the IMP performs its normal power-up starting
    procedures. However it is now running the software which it received
    from its neighbor IMP during the RELOAD process. This could be the
    same release, e.g., in response to a reload requested because of a
    watchdog timer interrupt. Or it could be a new release of the
    software, (re)loaded in response to a command to this IMP to request
    a reload.


To understand the entire process of reloading, the activities taken in 
the “other” IMP are also relevant. Assuming that the “other” IMP is 
running the same release 3050 of this listing, it takes the following steps:


 1.

    The packet sent by the IMP (I'll use the term LOADEE) requesting a
    reload arrives at the IMP (I'll use the term LOADER to identify this
    IMP) and is processed as a normal packet. The routine DIPE (p 93)
    processes all incoming packets, regardless of which modem they
    arrived from. At locn 10333, the Header of the just-received packet
    is examined for the SNDCOR and LINETS bits. Since the LOADEE set
    those bits in the outgoing packet (see step 6 above), the packet is
    characterized as a load request and processing continues at M2IRQC

 2.

    At M2IRQC (p 99), locn 11121 and 11122 set the SNDCOR bit in the
    SIHY flag table, in the slot for the particular modem being
    serviced. The SIHY table is one of the “page 0” variable areas used
    for communications between IMP modules. In this case, the input
    processor (M2I) here is leaving instructions for its corresponding
    output processor (I2M) on the same modem line to send an I-Heard-You
    (IHY) packet (which have high priority).

 3.

    After any current output operation completes on that modem, or after
    the timeout procedures trigger an I-Heard-You packet to be sent, the
    output handler for that modem will be triggered. In either case, the
    processing will come to I2MNUL to construct and send an IHY packet.

 4.

    At loc 12226, the SIHY entry is examined to detect the SNDCOR
    indicator bit, and processing is immediately diverted to I2MCOR to
    perform a core reload instead of sending an IHY.

 5.

    I2MCOR creates instructions for the I/O processor for that modem to
    transmit the contents of the LOADER's memory from CORELO to COREHI.
    These must of course have the same values as in the LOADEE, or the
    instructions won't go into the right places. The instructions at
    12262-12265 place the memory limit values into the locations
    specified by MOPX and MOP1, as instructions to the particular
    modem's I/O processor specifying where the packet to be sent is stored.

 6.

    Control is transferred to I2MDUN (p 111), where an appropriate
    instruction for the I/O processor is selected and stored into loc
    12476, where it is executed. This starts the I/O processor sending
    the contents of CORELO to COREHI out the particular modem interface
    to the LOADEE.

 7.

    The I2M interrupt handler completes at I2MQUT and returns control to
    whomever it interrupted via the IRET return location.

 8.

    The I/O processor will eventually complete the transmission of the
    core image and simply wait for the next output task, which will
    likely involve the handshake as the LOADEE program initializes and
    establishes contact with all of its neoghbors, including LOADER.




-------------- next part --------------
A non-text attachment was scrubbed...
Name: OpenPGP_signature.asc
Type: application/pgp-signature
Size: 665 bytes
Desc: OpenPGP digital signature
URL: <http://elists.isoc.org/pipermail/internet-history/attachments/20250827/121a0502/attachment-0001.asc>


More information about the Internet-history mailing list