RIM10B Loader

From Computer History Wiki
Jump to: navigation, search

The RIM10B Loader was a bootstrap program for early PDP-10's. It read 6-bit bytes from the paper tape reader, converted them to 36-bit words, and deposited the words in main memory, verifying the checksums of the program blocks on the tape as it went.

What was novel about this program was that (after a great deal of work) it was reduced to only 14 instructions long, and used 2 data registers; this allowed the entire thing to be held in the 16 registers of the PDP-10. (In the PDP-10, the registers could be used as ordinary memory, including holding instructions.) That allowed the Loader to be retained in memory (details below), in a way that could not be over-written during operation of the system, allowing that copy to be used later for loading a new program.

The Loader was initially included in the "PDP-10 Reference Handbook" as a PDP-10 coding example; by the 1971 edition, there had been so many questions asked by people trying to use it as an example that this comment was added in the margin:

This loader is written for minimum size and is quite complex. Do not approach it as a simple programming example.

Retention

The 'FM ENB' switch on the KA10's front panel enabled the Fast Memory (semiconductor) versions of the registers, in the CPU, to be enabled, causing references to them (notionally locations 00 through 17 in main memory, in the PDP-10) to go to the instances in the CPU, instead of the main memory instances. When FM ENB is off, the bootstrap can be toggled into normally inaccessible memory locations 01 through 16 (locations 00 and 17 need not be initialized), to be run for loading programs from paper tape, and retained, un-modifiable, when FM ENB is turned on.

This technique only worked on the KA10; later PDP-10s did not have the FM ENB switch.

Program

00/   777762,,0			XWD	-16,0
01/   710600,,60	ST:	CONO	PTR,60
02/   541400,,4		ST1:	HRRI	A,RD+1
03/   710740,,10	RD:	CONSO	PTR,10
04/   254000,,3			 JRST	.-1
05/   710470,,7			DATAI	PTR,@TBL1-RD+1(A)
06/   256010,,7			XCT	     TBL1-RD+1(A)
07/   256010,,12		 XCT	     TBL2-RD+1(A)
10/   364400,,0		A:	SOJA	A,	; Magic occurs here ****
11/   312740,,16	TBL1:	CAME	CKSM,ADR
12/   270756,,1			 ADD	CKSM,1(ADR)
13/   331740,,16		SKIPL	CKSM,ADR
14/   254200,,1		TBL2:	 JRST	4,ST
15/   253700,,3			AOBJN	ADR,RD
16/   254000,,2		ADR:	JRST	ST1
17/			CKSM=ADR+1

There are no instructions to assemble 6-bit bytes into 36-bit words, as the paper tape reader is operated in 'binary' mode, in which the device controller assembles six 6-bit bytes from the reader into a 36-bit word.

Code analysis

When the Read-In Mode (RIM) switch is pressed on the console of a KA or KI, it sends a reset pulse down the I/O bus, sets the PC flags to zero, and executes "DATAI D,0" (where D is the device code selected by a set of 7 switches, the paper tape reader is device 104). The DATAI reads in an IOWD, which has the negative word count in the left half and starting address minus one in the right half. The CPU then repeatedly executes "BLKI D,0" until the left half of location 0 reaches zero. ("BLKI D,X" increments both halves of location X, reads in a word from device D, and stores it the address that the right half of location X now points to.)

In the code listing below, note that the actual instructions executed are given; the two 'XCT' instructions in the code above perform different actions, depending on the state the program is in, which depends on where in the paper tape it is. This allows the instructions of the input operation (CONSO and DATAI) to be shared between the three states (the other two instructions in each state differ from state to state), which reduced the size enough to fit.

00/ XWD -16,0
Transfer 16 octal (14 decimal) words, starting at location 1.

01/ST: CONO PTR,60
Start paper tape reader in binary mode

02/ST1: HRRI A,RD+1
Reset finite-state machine to looking for IOWD

State RD+1 = Looking for IOWD or JRST

03/RD: CONSO PTR,10
Read paper tape reader status, skip if "DONE" bit is set

04/ JRST .-1
Not set, keep looping until the bit does get set

05/ DATAI PTR,@TBL1-RD+1(A)
Index register A has RD+1, indexing TBL1-RD+1+RD+1 is TBL1+2, which is the SKIPL CKSM,ADR instruction, therefore the effective address is ADR. Store the IOWD in ADR.

06/ XCT TBL1-RD+1(A)
Same effective address, "SKIPL CKSM,ADR" loads the IOWD into accumulator CKSM, and skips next instruction because its negative.

07/ XCT TBL2-RD+1(A)
Not executed first time around. At the end of the tape, a JRST instruction will be read in instead of an IOWD. (JRST is opcode 254, which is positive). TBL2-RD+1+RD+1 is TBL2+2, which is ADR. The JRST instruction which was just read in is executed, and that causes the PC to jump to the beginning of the program.

10/A: SOJA A,RD+1
Set the PC to RD+1, subtract one from index register A (so it now has RD in the right half, then jump to the original address (RD+1).

04/ JRST .-1
Not set, keep looping until the bit does get set

State RD+0 = Reading in data words

03/RD: CONSO PTR,10
Read paper tape reader status, skip if "DONE" bit is set

04/ JRST .-1
Not set, keep looping until the bit does get set

05/ DATAI PTR,@TBL1-RD+1(A)
Index register A has RD+0, indexing TBL1-RD+1+RD+0 is TBL1+1, which is the ADD CKSM,1(ADR) instruction, therefore the effective address is one greater than what ADR points to. Store the data in memory.

06/ XCT TBL1-RD+1(A)
Same effective address, "ADD CKSM,1(ADR)" adds the word read in to the additive checksum in accumulator CKSM.

07/ XCT TBL2-RD+1(A)
The address is TBL2-RD+1+RD+0 which is TBL2+1. That location has "AOBJN ADR,RD". Add one to both halves of accumulator ADR. If the result is still negative, loop back to RD (location 3). If non-negative, continue on at location 10.

10/A: SOJA A,RD+0
Set the PC to RD+0, subtract one from index register A (so it now has RD-1 in the right half, then jump to the original address (RD+0).

State RD-1 = Reading in checksum

03/RD: CONSO PTR,10 Read paper tape reader status, skip if "DONE" bit is set

04/ JRST .-1
Not set, keep looping until the bit does get set

05/ DATAI PTR,@TBL1-RD+1(A)
Index register A has RD-1, indexing TBL1-RD+1+RD-1 is TBL1+0, which is the CAME CKSM,ADR instruction, therefore the effective address is ADR. Store the expected checksum in ADR.

06/ XCT TBL1-RD+1(A)
Same effective address, "CAME CKSM,ADR" compares the calculated checksum in accumulator CKSM with the expected checksum stored in memory location ADR. Skip the next instruction if they're equal.

07/ XCT TBL2-RD+1(A)
The address is TBL2-RD+1+RD-1 which is TBL2+0. That location has "JRST 4,ST" which is a HALT instruction. If the previous compare instruction failed, set the program counter to ST and halt the CPU. This allows the operator to back up the paper tape reader and try again. If the CAME succeeded, this HALT is not executed.

10/A: SOJA A,RD+1
Set the PC to RD+1, subtract one from index register A (so it now has RD-2 in the right half, then jump to the original address (RD+1). This jumps to location ST1, which resets the finite-state machine.

Dispatch table for finite-state machine

11/TBL1: CAME CKSM,ADR
In state RD-1, read expected checksum into ADR, then compare calculated checksum with expected checksum.

12/ ADD CKSM,1(ADR)
In state RD+0, store data word into memory, then add data word into running checksum.

13/ SKIPL CKSM,ADR
In state RD+1, store IOWD or JRST in ADR, then load that word into accumulator CKSM and skip if the word is negative.

14/TBL2: JRST 4,ST
If the checksum comparison fails, halt the CPU, with ST in the PC.

15/ AOBJN ADR,RD
In state RD+0, increment the IOWD and jump to RD if more to go.

16/ADR: JRST ST1
This is the last word of the RIM10B loader. When the hardware read-in process is completed, this instruction is executed to start the program.

17/CKSM=ADR+1
The additive checksum is calculated using this accumulator.

External links