return to main page

IPL - Initial Program Load

and the "A" switch wiring and usage

Table of Contents
     - First explanation
     - The "A" Switch
     - Ken Sherriff's explanation - Thu, Jul 14, 2016 12:54 pm
     - Stan's comments about card and tape IPL Thu, Jul 14, 2016 8:30 pm
     - Ken's Question - Thu, Jul 14, 2016 9:55 pm
     - Van Snyder's info - Fri, Jul 15, 2016 9:19 pm


First explanation
Most "serious" computers have some easy way to get started without much manual effort, such as toggling a start up loader into memory using front panel switches.

Much of the following was inspired by e-mail between Matthias Goerner (asking the questions), and Van Snyder (with the answers) and LaFarr Stuart keeping track ;-))

The key paragraph from Van Snyder seemed to be

"Seven-character set-word-mark, five-character branch with blank d- modifier, and seven-character clear-storage-and-branch do not need a word mark to *finish* fetching the instruction and enter the EX phase, but every instruction executed has to have a word mark under the op code. Of the three that don't need a word mark to move from I to EX, only set-word-mark is not a branch. Any branch, whether its I phase was terminated by sensing a word mark, or indeed if the I-address register was set from the console, has to land on a character with a word mark."

1401 characteristics which support the "LOAD" operation. (as per my understanding of Van Snyder)

  • Depressing the "LOAD" button does the following:
    1. - reads a card (in BDC mode) into 001 through 080,
      - setting a word mark into memory location 001
      - clearing any word marks 002 through 080.
    2. - starts executing code starting at memory location 001
  • Instructions that do not need a word mark in the following memory location to execute properly are:
    1. The SET WORD MARK and CLEAR-STORAGE-AND-BRANCH instructions with two addresses do not need a word mark
      permitting the first instruction, SW 008nnn, to work
    2. UNCONDITIONAL BRANCH (e.g. B with address and d-modifier=BLANK) the machine will stop the fetching after the I-4 cycle and doesn't need a word mark on the next opcode.
      I-8 is the phase that gobbles characters until it sees a word mark.

The original and primary way to get a 1401 started (assuming 1401 power is on) is to:

  1. Set the 1401 operator's panel switches
    - rotary switch in "RUN"
    - assure that any required sense switches "A"-"G" are set correctly
    - depress "START RESET" switch
  2. On the 1402 Card Reader Punch
    - assure that the "READER ON" switch is ON
    - Depress "NON-PRO RUNOUT" for a few seconds to assure reader path empty
    - (reader gate must be closed)
    - insert deck into reader, "9 edge in, face down", assure reader gate closed
    - Briefly depress "CHECK RESET" button on 1402
    - Briefly depress "LOAD" button on 1402
In a typical program, the first card of a loader is:
,008015,022029,036040,047054,061068,072/061039              ,00100110400003
followed in one case by setting memory locations 087-089 (index register 1) to zero
000                                    L003089,040040,040040,04004010400004     
followed many cards later by a branch to memory location 338 in the loaded program
                                       /338080                         0066     


"begin rambling side trip" - from Van Snyder

Oddly, the newest edition of the "Brownie Book" (A24-1403-5) doesn't include the sentence that says clear-storage-and-branch doesn't need a word mark. I don't know why it was removed. I tried it on the HzG machine, serial number 25000-something, and it branched without fetching an eighth character.

At least some 8-character instructions, that the processor knows are 8- character instructions (e.g. BCE, BWZ) work with only seven characters. The processor simply looks in the A register for its d-modifier, thereby using the last character of the B-address. I conjecture this works for other 8-character instructions, e.g. M and L with % as the first character of the A address.

Instructions work if they have too many characters, too. Of course, if the behavior of the instructions changes as the number of characters increases, you get the behavior defined for the maximum meaningful number of characters.

For example, BCE and BWZ work fine with ten characters.

In these cases, the d-modifier is taken from the LAST character, not the eighth one. I conjecture, but I haven't verified, that this also works for five-character instructions, such as select-stacker-and-branch (K), carriage-control-and-branch (F), and maybe control-unit (U). These might get check stops if they have six characters, because the processor might try to form a B-address, but the B-address register is cleared to blanks in I-5, so the fifth character is blank in I-6. But seven or more ought to work.

The default start address for beginning an Autocoder assembly (i.e., if you don't have an ORG paeudo-op) is 333, not 338. Many programs start at their first address, but that's not required.

BTW, pressing the "tape load" key does the following:

- Read a record from tape unit 1 starting in location 1, with word marks
- Branch to location 1

There is a line on the SIO that does the same thing, but there's no switch on the console to do it. I assume there was a key on equipment one could plug into the SIO. This makes a PC-to-SIO interface attractive: You don't need to load a "read the SIO" routine to boot from the SIO.


The "A" Switch with LaFarr Stuart, Van Snyder and the implemention by Ron Mak !! :-))
Ron Mak says (about the latest version of ROPE (Ron's Own Programming Environment :-)) Runtime card input tips
  1. If sense switch A (the "last card switch") is on when your program executes an R instruction, you can do a "branch on last card" instruction like this:

        B    DONE,A

    where the branch to "DONE" is taken only if the card reader is empty (i.e., the last card has already been read). Note the "A" d-character.
  2. If sense switch A is off, then the above branch is never taken, and the machine will immediately halt on an R instruction if the card reader is empty.
  3. The sense switches are in the CONSOLE window (press the "Show console ..." button in the EXEC window). The sense switches are settable only after your program has started executing, so put in a breakpoint and press the "Start program" button.
From Ed
Lots of facts - but how to put them together into what/why you are doing this - it boils down to:
  1. assume your application has a large number of input cards to read before doing some other processing, such as printing summaries.
  2. you want to know when the whole input boxes of cards has been read by the card reader - then do the other processing.
an easy way is to
  1. you write your application to terminate input processing (and go to some other phase, such as writing the output summaries) when the card reader input hopper goes empty
  2. but if you have many input cards ( say more than 2,000 ) you
LaFarr said
For most programs after the last data cards were put in the card reader you did have to go to the console to turn on the "A" sense switch (which was only effective when the reader was empty).

Van said

You can leave sense switch A on. It's wired up in series with the last- card switch in the card reader. The only reason to turn it off is so you can read an entire deck -- including the last two cards, for which the reader stops so you have to push "start" on the reader to read them -- then look at the output, then put some more cards in the hopper, then keep going.

LaFarr said

I agree with you, when you are running relatively small runs, you want the last card to go the summary portion of the program. But, when you literally have many thousand of data cards (at the phone company we had a card for every long-distance call made from or billed to a Las Vegas number) it is almost guaranteed that the card reader will run empty a few times before the job is done. Then it is important to have the "A" Switch off, until you really want to let the run end. IBM knew what they were doing when they designed the A switch function.

Van said (Mar 23, 2010)

LaFarr asserts it is important to leave Sense Switch A off when running a large batch so the program doesn't inadvertently go to its summary processing just because you haven't gotten around to loading the next tray.

It isn't actually necessary to turn off Sense Switch A to avoid this because the card reader stops just before reading the last card. You have to push the Start key on the 1402 to make it read the last card, after which the last card indicator (actually the "no more cards" indicator), which is wired in series with Sense Switch A, comes on. I'm sure this was intentional in the design, precisely for the reason LaFarr gives.

So you can just run with Sense Switch A on all the time. Just don't push Start on the 1402 when the hopper goes empty if you need to load more cards for the same job.

Van

LaFarr said (Mar 25, 2010)

I am sure Van is right.

But at the phone company we had many different girls running the machines, and it was to easy to just push the Start button whenever any machine stopped.

We had a girl run a few thousand cards through a malfunctioning 519 (mark sensing) that was lacing (punching every row in a column) cards. She had to hold the Start button down because it was stopping on every card. --But she kept it going!

Ken Sherriff's explanation - Thu, Jul 14, 2016 12:54 pm
Guy, you asked yesterday how the boot card sequence works. I looked at it last year, so I can explain how it works.

The brief picture is the first three cards clear out storage. Each of the following cards is half program code and half loader code. The loader code copies the program code into memory, adds the word marks, and loads the next card. (If you've ever wondered how word marks can get punched onto cards, this is the answer.)

In a bit more detail, the load button loads the first card and executes the first instruction. The first card sets up the necessary word marks and loads the second card. The second card clears memory from 100 to 15999 and then copies some code out of the read buffer. This code clears the read buffer (which is why it needed to get copied out of there). It then erases itself and loads the third card. The third card sets up the read buffer to read the code: it clears the left half of the buffer and puts word marks in the right half, and loads the first card with real code. Each following card has the code that we actually want to load in the left half (1-39), and loader code in the right half (40-71). The loader code copies the left half into the desired place in memory, adds the necessary word marks, and loads the next card. At the end of all this, the program is loaded into memory.

In great detail, when you push the load button,

the first card gets loaded into 001-080 
and the first instruction is executed. The first card is:
,008015,022026,030037,044,049,053053N000000N00001026                   0001

The first step is to get word marks set up so you can execute 
additional instructions. The , instruction sets two word marks. 
It is important that the word mark instruction can set two word marks, 
or else it would be hard to get ahead of things. 
The bold part sets word marks at 8, 15, 22, 26, 30, 37, 44, 49, 53 (twice?):
,008015,022026,030037,044,049,053053N000000N00001026                   0001
Then a couple nops (for no good reason):
,008015,022026,030037,044,049,053053N000000N00001026                   0001
Then the 1 instruction loads the next instruction and starts execution at 26:
,008015,022026,030037,044,049,053053N000000N00001026                   0001

Now, card 2 is loaded and starts at instruction 26:
L068116,105106,110117B101/I9I#071029C029056B026/B001/0991,001/001117I0?0002

/ is clear storage downwards until address ending in 00, 
and I9I is address 15999, so this clears 15900-15999, 
including clearing the wordmarks.

The next instruction subtracts 100 from the address used previously.
L068116,105106,110117B101/I9I#071029C029056B026/B001/0991,001/001117I0?0002
# is modify address, modifying the address at 29 
(which was the 15999 value of the previous instruction). 
The value to modify by is at 71, which holds I0?, 
which is 15900 or equivalently -100). 

L068116,105106,110117B101/I9I#071029C029056B026/B001/0991,001/001117I0?0002
C is compare, comparing the value at 029 (the address) 
with the value at 056 which is 099.

Next is a branch if unequal back to 26.
L068116,105106,110117B101/I9I#071029C029056B026/B001/0991,001/001117I0?0002

Note that the word marks had to be set up correctly 
to handle different instruction lengths, 
since there are 4 character instructions, 
5 character instructions, 7 character instructions, etc.

At this point, memory has been cleared from 100 to 15999.

Branch back to 001, to execute the first part of the card.
L068116,105106,110117B101/I9I#071029C029056B026/B001/0991,001/001117I0?0002

Load characters from 68 downwards to 116 downwards, until hitting a word mark.
L068116,105106,110117B101/I9I#071029C029056B026/B001/0991,001/001117I0?0002
This copies characters 53-68 to 101-116.

Set word marks at 105, 106, 110 and 117:
L068116,105106,110117B101/I9I#071029C029056B026/B001/0991,001/001117I0?0002

Now branch to the copied code at 101:
L068116,105106,110117B101/I9I#071029C029056B026/B001/0991,001/001117I0?0002

Clear from 99 down to 0, i.e. 
clear out the card buffer memory that was being used earlier:
/0991,001/001117

Read a card:
/0991,001/001117

Set a word mark at 1:
/0991,001/001117

Clear from 117 down to 100 and branch to 1. I.e. 
clear out the copied code that was just running:
/0991,001/001117

From card 3, set word marks at 8, 15, 22, 29, 36, 40, 47, 54 61, 68, and 72:
,008015,022029,036040,047054,061068,072/061039              ,00100110400003

Clear from 39 to 0 and branch to 61
,008015,022029,036040,047054,061068,072/061039              ,00100110400003

Set a word mark at 1 (twice?)
,008015,022029,036040,047054,061068,072/061039              ,00100110400003

Load a card and branch to 40
,008015,022029,036040,047054,061068,072/061039              ,00100110400003

At this point, the cards with "real" code start. 
Columns 1 to 39 are the code and 
columns 40-71 have the loader code for the particular code.
M357430B494M4302352.09X6MH425          L029361,340344,351352,35335810400004
This card copies the code (L) from 29 down to 361 down. 
In other words, the code gets copied into memory 333-361.

M357430B494M4302352.09X6MH425          L029361,340344,351352,35335810400004
The loaded code gets six word marks at the appropriate places.

M357430B494M4302352.09X6MH425          L029361,340344,351352,35335810400004
The next card is loaded (1) and branch to 40 for the next card's loading routine.

Note that you can only put a maximum of 6 word marks into the code per card. 
So the amount of code loaded per card varies depending on 
how many word marks are required. 
Best case is you can get 39 characters on a card. 
Worst case is you can get 6 characters (all with word marks) on a card.

Finally the last card clears the card buffer (000-080) 
and branches to the start of the loaded code (3330:
                                       /333080                         0015


A lot of work, just to load code into memory!

Ken

Stan's comments about card and tape IPL - Thu, Jul 14, 2016 at 8:30 PM
Guy,

The only function in the 1401 to help load a program into memory are the two load buttons.

    The load button on the 1402 card reader, when pressed, will:
    1. Clear memory locations 001 - 080
    2, Set a wordmark at 001
    3. Read in a card into 001-080
    4. Branch to 001

    The tape load button on the 1401 console, when pressed, will:
    1. Clear memory locations 001 - 080
    2, Set a wordmark at 001
    3. Read in a tape record from logical drive ONE into 001-080
    4. Branch to 001

    Luca Severini modified ROPE to run Van Snyder's Autocoder twice;
        The first pass builds  a card image file
        The second pass builds a tape image file.

    What Ken defined is the SIMH format from Van Snyder's Autocoder.

    There are many boot and load formats out there.
    Ron Williams like to write programs that can run with a single card.
As to Ken's comments about the double setting of a word make at 053 and the two noop instructions is that the word mark structure has been set and has to be used.

Stan Paddock

Ken's Question -Thu, Jul 14, 2016 9:55 pm
One other subtlety is that there needs to be a word mark following every instruction, so you'd expect the first instruction after boot to fail, since there is no word mark after it. The trick is that the set word mark instruction (and a couple others) will run without a terminating word mark, allowing things to get bootstrapped.
(I have to wonder if they planned this or if it was a hack to make things work.) See http://ibm-1401.info/VansOverview.html#instructions Ken

Robert Garner posed this question to two of the original 1401 design team, Jud McCarthy < jhmccarthy@aol.com > and George R Ahearn < george.ahearn@comcast.net >
Jud replied:
Robert: I believe this was planned. --- Jud

Don Crandall: Please comment. ---- Jud

Van Snyder's info - Fri, Jul 15, 2016 9:19 pm
> Van —> fyi, a discussion about your Autocoder boot loader?… ;-)

The discussion is about one of the IBM Autocoder boot loaders, which my Autocoder can produce (I think the default is IBM's 16k Autocoder boot loader).

I like my two-card loader, which runs entirely in the read area. You can select this one with the -bV command-line option. This would be fun for some students to reverse engineer.

,008015,022026,030040/019,001L020100 ,047054,061068,072072)0810811022
,008047/047046 /000H025B022100 4/061046,054061,068072,0010401040

I think there's a mistake in the description of the tape load sequence.
AFAIK, it doesn't clear core. It isn't limited to 1-80. It reads an entire record from tape unit 1, in load mode, starting at location 1, even if it's longer than 80 characters. I don't know whether a GMWM within the area the first record would occupy stops the read, as it would if L%U1001R were executed. That might be an interesting experiment for Stan. Create a tape that has a program of several hundred characters as its first record. Maybe use an Autocoder or Fortran tape. Set an address stop at 00001. Patch in a GMWM somewhere in the area the first record would occupy if it all gets loaded, or maybe scan it into all of core. Press the "tape load" key. Dump core to see if the whole record got loaded.

BTW, ROPE doesn't need to run Autocoder twice to generate both a deck and a tape. It can do both by setting the appropriate command-line options ("-o deck-file-name" for a deck, "-t tape-file-name" for a tape).

I don't know whether allowing 7-character SW, 5-character B with a blank D modifier, and 7-character CS, to work without a following word mark, was planned all along, or was an after-the-fact hack. I think that getting a check stop from an address wrap was an after-the-fact hack. Here's a really simple clear-core routine that crashes with a check stop from an address wrap, but would run forever without it:

,008015,019020/I9IL

Here's another test for Stan: What are the A- and B-address register contents after 7-character clear-storage-and-branch? The Brownie Book says they're BI and x00-1.> Van —> fyi, a discussion about your Autocoder boot loader?… ;-)

The discussion is about one of the IBM Autocoder boot loaders, which my Autocoder can produce (I think the default is IBM's 16k Autocoder boot loader).

I like my two-card loader, which runs entirely in the read area. You can select this one with the -bV command-line option. This would be fun for some students to reverse engineer.

,008015,022026,030040/019,001L020100 ,047054,061068,072072)0810811022
,008047/047046 /000H025B022100 4/061046,054061,068072,0010401040

I think there's a mistake in the description of the tape load sequence.

AFAIK, it doesn't clear core. It isn't limited to 1-80. It reads an entire record from tape unit 1, in load mode, starting at location 1, even if it's longer than 80 characters. I don't know whether a GMWM within the area the first record would occupy stops the read, as it would if L%U1001R were executed. That might be an interesting experiment for Stan. Create a tape that has a program of several hundred characters as its first record. Maybe use an Autocoder or Fortran tape. Set an address stop at 00001. Patch in a GMWM somewhere in the area the first record would occupy if it all gets loaded, or maybe scan it into all of core. Press the "tape load" key. Dump core to see if the whole record got loaded.

BTW, ROPE doesn't need to run Autocoder twice to generate both a deck and a tape. It can do both by setting the appropriate command-line options ("-o deck-file-name" for a deck, "-t tape-file-name" for a tape).

I don't know whether allowing 7-character SW, 5-character B with a blank D modifier, and 7-character CS, to work without a following word mark, was planned all along, or was an after-the-fact hack. I think that getting a check stop from an address wrap was an after-the-fact hack. Here's a really simple clear-core routine that crashes with a check stop from an address wrap, but would run forever without it:

,008015,019020/I9IL

Here's another test for Stan: What are the A- and B-address register contents after 7-character clear-storage-and-branch? The Brownie Book says they're BI and x00-1.


return to main page