Thursday, January 18, 2018

More work on 1401 system read-print issue at Computer History Museum


The focus on Wednesday was on the timing of various cam based switches that form the logic inside the 1402 card reader/punch. We looked in particular at everything involved in clutching the mechanism to turn the rollers and other gear that moves a card forward one station.

Several cam based switches, called circuit breakers (CBs) by IBM, are involved in this process, particularly RC5, RC6, RC7 and RL10. RC numbered CBs are those that run continuously with the main motor, even when the mechanism is not moving a card through the machine. RL numbered CBs will operate only with the mechanism that performs the card feed.

These CBs in turn control several relays, such as the clutch check relay 10, and lead to the activation of the reader stop relay 4. The wiring diagram is somewhere between obscure and impenetrable, as I have mentioned before, but we gradually mastered the portions involved in this problem we are debugging.

The 1402 originally operated by feeding cards in one rotation of the mechanism, always taking 360 degrees of rotation or about 18ms at the rated speed of the reader mechanism. This meant that when a processor request came in to read another card, one could wait between 0 and 18ms before it commenced, depending on where the spinning mechanisms were in their 360 degree rotation.

To increase effective speed, IBM created an early feed feature, dividing each rotation into three equal 120 degree segments. Now, when a CPU request arrives, the wait to honor it varies from 0 to 6ms, only until the next 120 degree segment comes around.

Now, most of the CBs have three lobes, to provide the same logic for each of the three 120 degree segments. The first one we adjusted, RC6, is the primary CB that determines when a CPU request will activate the clutch. One of its three lobes is designed to close the switch (make) at 272 degrees and open (break) at 342 degrees, with a tight tolerance that requires it occur between -2 and 0 degrees of the target value.

The CBs are adjusted two ways. First, the cam itself can be rotated around the axle that turns it, to changes its timing earlier or later in a rotation. Second, the contacts can be raised or lowered from the center of rotation, causing the duration of the activated switch to lengthen or shorten. Adjustment requires that both be controlled to get the make and break timings correct.

Advancing or retarding the cam around its axle is done by loosening two setscrews that hold it to the axle. These require Bristol wrenches, similar to Allen wrenches but having four lobes rather than the hexagonal shape of Allen. We loosened the setscrews but the cam would not move relative to its peers at RC5 and RC7.

We hooked an ohmmeter across the contacts to do the timing, hand rotating the overall mechanism with the timing wheel which is marked with 360 degree lines. First, however, the cam had to revolve on the axle to move its start and stop timing.

It appears that the cam was partly adhered to its peers by corrosion, so that some mechanical force was needed to free it up. The access to the cams is quite restricted, otherwise we could have simply used pliers of some sort to turn it. Finally, I could apply sharp impacts sufficient to break the corrosion but not the mechanisms.

The second adjustment, duration of the switch, is controlled by a screw, a setscrew and a jam hexnut. The jam nut holds the setscrew in its position, while the setscrews is a stop for how high the switch contacts can move. Finally, the screw itself locked the contacts down or allowed them to slide up and down.

I finally got the height of the contacts correct for exactly 70 degrees of make time, then rotated the cam to cause the make to happen right at 270 degrees. It ended precisely on time at 340 degrees, so we were done with this adjustment. The ohmmeter showed the make and break as we slowly rotated the timing wheel.

However, when we turned on the dynamic timer with the reader operating under power, it showed that circuit energizing at 275 degrees but ending on time at 340,. Looking at the schematic and then scoping the circuit, we found that CB RL10 is misadjusted. It is in series with RC6 and since it doesn't make until 275, that delays the activation.

The RL CBs are mounted in a much more inconvenient location in the machine, requiring the removal of part of the top cover near the card hopper before we could reach and adjust them. We didn't have enough time left in the day to do this before the public demonstration started, thus we left it to the next session.

The reason that RC6 and RL10 are in series is that permission to fire the clutch depends on two things. The position of the motor assembly must be in the right 70 degree portion of its 120 degree segment, but also the feed mechanism must not already be in motion from a prior clutching.

Thus, RL10 sits activated when the feed mechanism is idle, allowing RC6 to determine when to start a card read. However, once the feed mechanism is moving, RL10 blocks clutching until the feed is advanced enough. That is, reading a card takes the entire 360 degree rotation to move it forward and past the 12 rows of holes, even though we can start this process at any one of the three 120 degree segments.

Therefore, RL10 imposes the 360 degree cycle restriction after which RC6 determines the next 120 degree segment to permit clutch activation. In addition to this complexity, CBs RC5 and RC7 control the timing of the clutch checking that ensures a clutched feed mechanism actually moved.

When RC6 lets the CPU request activate the clutch, it first energizes clutch check relay 10 then with a slight time delay activates the clutch itself.  RC7 is a set of lobes which control when the error check takes place. This CB makes and breaks opposite to RC6, activating during the span when RC6 is open. These two cannot overlap activation and there is a required gap between the two sufficient to let the clutch engage and begin moving the feed mechanism.

RC5 is another trilobe cam, with the same timing as RC6, but used to activate other relays that ultimately lead to the checking that triggers our reader stop condition. We need to get the timing of RC5, RC7 and RL10 corrected before we can be sure that our reader is working according to its design. 

Tuesday, January 16, 2018

Using HP 2621A terminal with Altair 8800 replica


I recently bought and built an Altair 8800 replica - uses an Arduino and front panel interface - which I access over bluetooth to a modern PC running a terminal emulator. The modern hardware distracts from the sense of using the Altair, so I decided to connect it to one of my ET style HP terminals.
Arduino based Altair replica
The 2621A is called an ET type because the shape of the monitor head on its pedestal looks a bit like the alien from the ET movie. It runs over RS232, usually hooked to my HP 1000 minicomputer system. However, it could be driven by any system, using ASCII input and output.

HP 2621A "ET" terminal
A few minor difficulties sat between me and immediately connecting the terminal:

  • Lack of a serial port on the Altair
  • 12V levels on a real RS232 interface
  • Terminal uses a Centronics 50 connector
  • No cable to make the connection. 

The Altair replica does not have a real RS232 port, although it emulates the serial ports of the 88SIO, 882SIO and 88ACR cards from a real Altair. However, it has two micro USB ports on the Arduino and a bluetooth module inside. There is a simple configuration program built into the replica to assign these real ports to the virtual Altair serial ports.

On a recommendation from other builders of the Altair replica, I ordered a device from Hobbytronics that will plug into the Arduino native USB port and produce TTL voltage level RS232 signals. This gives me the protocol but not the voltages.
Convert native USB in CDC mode to TTL RS232
I then procured a MAX2232 chip based level converter which interfaces a TTL level RS232 device such as the Hobbytronics box with a 12V level RS232 device. This gives me the voltages but not the cable or connector.
Convert TTL RS232 to true 12V RS232
Next, I have a male Centronics 50 connector on order, which I will wire up between the level shifter board and the terminal. That resolves the last issue and provides everything I need to begin using the 2621A terminal with the Altair 8800 replica.

Centronics 50 male connector plugged into HP 2621A terminal
The bluetooth connection in the replica will let me transfer files to act as cassette tapes, paper tape or xmodem mechanisms to get external files into the Altair replica. It has simulated floppy and Pertec hard drives inside the replica, hosted on an SD card, thus I can do much of what I want without the need to access virtual paper tape or other files from outside the replica. 


My home office needed a makeover now that I am retired and we want to use the space for storage. One element of the refresh is to replace the carpeting that is old, ripped and stained. The room is 14' 10" x 8' 3", a simple rectangle shape.

My wife and I selected a carpet that comes in both 12' and 15' wide rolls, since that way the room could be covered with no seams at all, just a 8+ foot length of 15' carpet. We bought from Home Depot and had the tech out to officially measure the room. Next step was to get a quote. Based on the carpet we chose, priced by the square foot, we guessed that the total cost would be in the 400-500 range.

In spite of the use of square feet in all the advertising and quoting, carpet is actually sold by the yard and you pay for the entire width of the roll times the length needed to cover the room. Knowing that, I expected that I would pay for 15 square yards - a 15' wide roll is 5 yards wide and the nearest size in yards to cover the 8+ foot room is 3 years- thus 5x3 yards of material.

We received a call with our quote which was for over $600. This was for 20 square yards of carpet. That told me that they had simply chosen the 12' wide roll, cutting it for the 15' length of the room. 20 square yards when all it would take is 15 square yards if the wider roll was used.

Fortunately we knew what was happening and could ask them to recalculate using the 15' roll. As expected, the cost came out right where we expected give that it now required 9 feet to be cut from the 15' roll. The deal was concluded and we expect the 15' segment, a 'special order' not in stock, to arrive at the installers in about two weeks after which they can come and install it.

We saved 1/3 of the cost of this job because we knew how they worked and the best way to lay the carpet. Even though when we first ordered the carpet we specified the 15' wide roll, and when the tech came for measurements we asked him to note that 15' rolls should be used, the quote desk approached this in a simple minded way that ballooned the price unnecessarily. 

Saturday, January 13, 2018

Retrieved more images from the Xerox PARC archives


Today we set up our production line to process the 25 disk cartridges I retrieved from Xerox PARC earlier in the week. First we open each cartridge to inspect and clean the disk surfaces. Next, we read the entire contents of the cartridge into my FPGA based disk tool from a Diablo disk drive.

Next, the data from the disk tool is uploaded to a PC and formatted into Simh format. Finally, we check that each image boots up or can be opened. If there are passwords protecting the cartridge, we use a program to unlock them.

By the end of the session, we had 13 successful extractions of a cartridge and found two cartridges irreparably damaged when we opened them. One was missing the protective cap on the cartridge, exposing the edge of the platter where it had become bent at some point in the past.

There were three cartridges that had minor crash damage, which we will attempt to read as the last three cartridges once we deal with the other six cartridges on hand.

We picked up enough oxide to need to remove and clean the heads on our drives before we take on the last nine packs during the next session. We have found that we can clean the heads in about 90 minutes, thinks in part to the ultrasonic cleaner that loosens the impacted oxide on heads. Then, we can complete an alignment in less than an hour.

Wednesday, January 10, 2018

Diagnosing 1401 read-print issue, getting Fortran compiler running on 1401


In preparation for our session on Friday, I drove all the previously archived cartridges over to PARC and exchanged them for 25 new ones. These were the top picks from a prioritized list of the 75 remaining cartridges from their database of disks. The expectation is that we can complete a batch of 25 in a week or so, then exchange those for the next group.


Both Ken and I brought in modern scopes to help shoot the problem, but we are still not certain we know the precise failure mode, due to the complexity of the 1402 card reader logic. That logic is implemented with relays, cams and microswitches, but as IBM added new feature after new feature to the unit, they took the easy way out with schematics. 

Rather than redrawing circuits to keep it clear, IBM added many, many off-page connectors for these changes such that tracing out the real circuit is extraordinarily difficult. Thus, we have a hazy idea of how the machine is actually functioning, with more than forty cams, about fifty relays, perhaps 80 diodes, and each relay has four to six independent sets of contacts. 

By the end of the day, we had narrowed our focus down to a pair of cam switches, RC6 and RC7. These are running continuously as long as the motor of the 1402 is spinning, while other relays named RL# operate only when the clutched part of the mechanism is rotating - during the feeding of cards. 

RC6 is the main timing point determining when the request from the 1401 will activate the clutch magnet. This happens at three equidistant spans around one 360 degree rotation of the motor wheel. As RC6 allows the processor request, first the pick coil of relay 10 (Clutch Control) is activated and then after a short time delay through an RC network, it activates the clutch magnet.

The clutch engages and begins moving the feed mechanism through its rotation, moving a card from one station to another. The stations are feed hopper, read check, read and stacker. Cam RC7 is set to complete a circuit during the intervals in between the three that enable clutching. Cam RC7 sets up the error check, where relay 10 is on if the processor requested to clutch but off otherwise

The Reader Stop condition occurs because the error check time determines that the clutched mechanism did not rotate, the feed relay 6 is not activated, but relay 10 is on. Essentially it tests to see if relays 6 and 10 agree, but only during the time that RC7 allows the check. 

RC6 and RC7 have only a 5 degree separation between their active times. For example, RC6 should switch off at 102 degrees and RC7 turns on at 107 degrees. When we checked the timing of RC7, it was turning on early, at 105 degrees. Another test seemed to show that RC6 is working late, turning off at 105 degrees. 

This overlap of RC6 and RC7 sets up a race condition where it is possible to falsely detect a failure to engage the clutch when in fact the reader is working properly. We will adjust the two cams to increase the gap between their operation, in our next Wednesday session. There may be other cams involved in this failure as well. 


Marc Verdiell and Mike Albaugh have been working for a while to produce a working tape of the 1401 Fortran II compiler. It is a 63 pass compiler (!) that will work even in a small memory system. Having overcome the final barriers they were able to compile and run a few sample programs today. 

Next up for the team is to accomplish this with an enhanced Fortran II compiler, a Fortran IV compiler, a Cobol compiler and hopefully RPG if we can locate that software. We also have a card oriented FARGO program to get running. Fargo was a predecessor to RPG, both of them are meant to make it easy to replace plugboard based accounting systems. 

Tuesday, January 9, 2018

Working on 1401 read-print issue, assisting a new IBM 1130 restoration effort


I was contacted by an official of a museum in Slovenia who has an IBM 1130 in the collection which they are planning to restore. I expect to share documentation and answer questions as this work proceeds.

They have a small machine, 4K or 8K, with the Garnet Rose color scheme offered by IBM during the S/360 and 1130 era. The other common color was Classic Blue, but rarely you could see a color such as the Sunshine Yellow that my personal 1130 sports.


The 'German' 1401 system at Computer History Museum has a problem when rapidly reading cards and printing their contents on the 1403 printer. After some number of cards, the 1402 reader will enter a Reader Stop check condition.

We have a tight hand program which is very reliable in causing the check condition - read, print, read, print, read, print, read, halt - which will fail on the last read command virtually every time. This has been helpful in scoping signals to find the cause.

After working half a day on Monday, we narrowed the problem to one part of the Reader Stop circuit - not the card jam detection or other portions, but the part that ensure that the reader responds correctly to a read command.

To verify its operation, the reader compares the state of two relays, clutch check and read cycle. If they don't agree, it would mean that the CPU requested a read but the 1402 didn't move, or that the 1402 has moved a card but the CPU did not request it.

There is a resistor-capacitor network on the line to the reader clutch magnet, which delays when the clutch activates. The same activation signal goes directly to the Clutch Check relay. This means that Clutch Check is active while the mechanism begins its 360 spin of the cycle wheel.

Once the wheel has moved a bit from the idle position, it activates the Read Cycle relay. Then, later in the rotation, microswitches on cams cause the circuitry to compare the two relays condition. If they don't agree, a Reader Stop relay is engaged and the 1402 enters the check condition.

Disconnecting parts of the Reader Stop relay pick coil circuit, we isolated the stop condition to the circuitry looking for disagreements between the Clutch Check and Read Cycle relays.

To verify this, we removed the Clutch Check relay from its socket, which not only stops it from activating but also removes contacts necessary to detect the error condition. The reader ran without any stops in this condition.

We will need to do more testing to discover which case is being detected - which is engaged and which relay is inactive - but that will wait for our Wednesday work session. There is something about the delayed request for reading from the processor that triggers our error, but we don't yet know the details.

Why is the read request delayed? It is because of the relative timing of the printer and card reader, such that the last read command in our test program is occurring while the printer is copying its line of data from core memory. Since reading cards requires access to the core memory in real time matching card movement, the reading must be delayed while the printer logic is touching memory.

The printer in our installation has a speedup feature called a print buffer. Thus, when a print request is issued, the logic first copies all 132 characters of the print line from core memory and stores them in a special dedicated but small core memory. It requires about 2ms to copy the 132 characters over, after which the core memory is free for the long additional time it takes to fire printer hammers and space the paper.

In our test program, the 2ms transfer of printer data is underway when the last read command is issued, thus the CPU will block the read request from the card reader until printer transfer is complete. Thus the start of the read request to the 1402 is delayed a bit compared to the preceding read commands. 

Wednesday, January 3, 2018

Cataloging the archived Xerox PARC cartridges, overcoming password protection, work on 1401


Developing record of all directory entries

I mounted and booted every cartridge image we had archived so far, issuing the ? command to list the directory of each. I did this under the Contralto simulator and took screen snapshots with that program. Each was a PNG format image file of one screen of the output.

These are all stored allowing a fairly quick scan through all the images to locate any program or file of interest (by name). A future effort might extract the file names themselves and create a quick machine searchable document.

Switching off password protection

Ken Shirriff did some investigation and determined a way to switch off password protection. It involves finding a given file, Sys.Boot, then looking at a password control field 768 bytes inside. That field contains a control flag, some SALT values and the hashed password.

Using a brute force attack, Ken recovered passwords that will unlock the six cartridges we have encountered so far that are protected. I decided to build a Python program to to this.

In order to accomplish the function, I would need to find the directory on disk, traverse its entries and locate the one for Sys.Boot. Then, with the file located, I would need to move 768 bytes into the file to capture the password control field.

The program can then store a null flag into the field and rewrite that sector to the disk image, thus switching off password protection. Alternatively the program could try a brute force attack to retrieve the password itself. 

There are complications in chasing the directory sectors, as individual directory entries can span sectors. Too, the location of the directory and of Sys.Boot varies across different disk images I have examined. I am searching for a guaranteed method that will work for all such images.

Fortunately, Ken told me of a much easier method. The first sector on the disk (track 0, head 0, sector 0) is always the first page of the Sys.Boot file. It has the first 512 bytes of that file and its label field points to the next sector of the file.

Jump to the next sector and indexing into that sector by 256 bytes will give you the password flag. It is FF FF for a protected disk. Set the flag to 00 00 and the task is done. I stripped down my Python program, gave it a Windows file open dialog box, and tested it with several protected cartridges.


We spent more diagnostic time looking at the issue of false Reader Stop conditions when repeatedly reading cards and printing lines. This will fail sporadically on a job that reads and lists cards, but fails much more 'reliably' with tight code such as Read-Move-Print-Branch loops.

We discovered that the problem is a timing issue that occurs when the printer logic is transferring its data from the core memory locations 201-232 to the special internal memory buffer in the hardware. When you issue a Print command, it appears to finish rapidly, while the logic and physical printer hardware continues to print the line.

There is a 2 ms window where the logic fetches the 132 characters from main core memory and places them in the special buffer. During this 2ms, hardware will block the card reader logic from firing the reader clutch, since the card reader will also be accessing main core memory as it reads in each card.

With the sequence Read-Print-Read-Print-Read-Print-Read-Halt we usually fail on the last read. That read is delayed slightly by the printer transfer, then fires the clutch. The 1402 itself detects some problem, most likely that it thinks the Clutch didn't activate when commanded or that the clutch activated without a command from the processor.

It then raises the Stop condition which switches off the Reader Feed flipflop in the 1401, producing a characteristic very narrow clutch pulse. A number of conditions can cause the Reader Stop, although its main causes in a properly working machine are card jams or a card failing to feed from the hopper.

The system will also check its own operation by using a relay (10 - clutch check). These tests should be made only during a certain part of a feed cycle. At the enabled time, measured as a span of degrees of rotation of the reader mechanism, the clutch check relay must agree with the state of the clutch command coming from the 1401 processor.

We are looking for a case where the processor asked for a feed cycle but the reader isn't actually moving the cards forward, or the alternate case where the reader begins to move cards but the processor did not request it.

We will need to test the conditions triggering a Reader Stop to know which is the case causing our spurious stops. Is it a spurious jam, a movement thought to be uncommanded, or a failure to move after a command?

A card jam is detected if the microswitches that indicate a card is present at the hopper (card lever 1) or between check and read stations (card lever 2) don't close and open at the appropriate rotational positions in a feed cycle. Cards must clear stations and a new card show up at defined degree ranges. If this doesn't match, we probably have a jam inside. 

Sunday, December 31, 2017

Repaired Roomba wheel but have to deal with a dead battery pack


I used a file to cut down the four posts on the gearbox to allow the wheel to rotate with less friction. After reassembly both wheels seemed to have similar resistance to manual movement. I turned on the Roomba and it worked a bit but the battery was too dead to continue.

Gearbox posts filed down, before cleaning and reassembly
After a long charge I ran it again, but it died pretty quickly which tells me the battery pack is clapped out. The original pack delivers 14.4V using NiMH technology and the Roomba charger is notorious for killing batteries if left hooked up too long - since the charge circuit is quite naive. 

I was going to open it up and replace the cells inside, perhaps with Lithium Ion cellas, but it is secured with triangular security screws. A set of screwdrivers are on the way from Amazon so I will continue this towards the end of the week. Once I get inside I can decide how to make a workable substitute.
Battery pack with security screwheads