Console printer (typewriter) and keyboard moving to completion, other work progressed as well


Today I dug deeply into the logic for the keyboard interface. There is a large lookup from the 1130 character code (selectric tilt/rotate code for 1130 custom typeball) to yield the Electronic Typewriter equivalent printed character. I redesigned the movement portion of the logic, which is much more direct and clean now. Startup logic was needed to move the carriage to the left margin of the typewriter, as we won't necessarily know where it is along the platen when we begin. A complication is handled wherein the 1130 thinks the typeball is already in the proper shift case for the next character but our typeball and mapping requires us to shift the ET50 ball to print the same character - a hidden cycle.

Debugging proceeded reasonably well using the logic analyzer and Arduino as the standin for the typewriter. I discovered a number of flaws and combination conditions, corrected them, and continued testing. The 1130 adapter logic worked well, even forcing an automatic carriage return and line feed when I incorrectly raised the End of Line signal.

It is one of the interesting artifacts of the emulation that in some cases the typeball will spin both ways before printing a character. The 1130 adapter logic is 'shadowing' the state of the typeball, either upper case or lower case, so that it can issue a shift command prior to any character that is on the other side of the ball from its current rotation.

Some characters that are on one side of the 1130 typeball are placed on the other side of the ET50 typeball, thus the adapter may decide that printing a particular character requires rotating to upper case position, it moves the ball, then it sends the codes for the particular character. Our emulation routine does not see the particular character that will be typed when it is commanded to shift - all it gets is the shift command from the adapter. Thus, we have to first obey the adapter, then translate the character, and if we now need to shift the ball we take a hidden shift cycle before printing.

The adapter shifts the ball, we translate, we shift back, then we print - the ball will spin one way, then the other, then strike. Fortunately, most cases will be on the same side as the 1130 typeball, thus whatever shift was commanded by the adapter is the correct state for our printing and we needn't do another shift. It will, however, cause some timing differences for programs as the number of selectric print cycles will be slightly different on our machine due to additional shifts introduced by typeball differences.

I have a phantom race condition on startup, based on the order of assignment of logic to fpga cells, that in certain loads the typewriter starts up indicating it is over at the end of line, while other loads of the fpga will repeatedly start with the typewriter at the beginning of the line. I still haven't worked out a good solution to this - it is the interaction of various independent state machines and processes that causes the problems.

I may need to provide a more guaranteed handshake protocol between certain parts of the design, but at least three of them are fairly asynchronous - the carrier movement, the incoming emitter pulses recording positional changes, and the print cycle that spins the mechanism through a 360 degree action. Since the emitter pulses are changing the position along the print line, while the movement logic may be commanding forward or backward movements, there is some opportunity for race hazards and unstable signals being used to drive state machine changes. In addition, the print cycle is what kicks off the beginning of the physical movement (but ends well before most movements will be complete), thus this too may expose unstable signal values at key decision times. It is possible I may do a partial redesign of the basic structure of this logic, if I don't feel good about the condition after some more debugging and tweaking.

Once I have the basic typing and carriage returns working, I will shoot a short video of the typewriter in operation driven by the fpga 1130. Remaining to debug are additional functionality for realism, such as tabbing, tab set and clear, margin sets and the startup logic that places the carrier at the left margin, but once the essence of the interface is working properly, the remainder shouldn't be too difficult to finish off.


I made the decision to add in some timing changes that are in the 1130 "B" machine ALDs on bitsavers, which is a full speed more complete machine than the 1130 "C" for which I had all the ALDs. The "B" machine is missing all the ALD pages before KA101, which is why I didn't attempt to design from it, but the only areas that have caused me to debug tight timing issues and to modify the IBM logic slightly were related to timing similar to the changes I saw in the B machine to accommodate the faster memory cycle time (which I have been modeling all along). A few signals are delayed and in a couple of places they had to anticipate the state of a signal to make that condition available earlier than the real signal is generated.

I then had a bit of cleanup testing - I forgot to update the interconnection to one of the modified 'boards' which lead to the machine hanging at the end of an instruction. Once it was found and fixed, I have another issue where the CCC register (cycle control counter, used to control variable execution length instructions such as shifts but also to manage basic end of instruction detection) is being loaded with incorrect values.

Since I implemented a signal that gates the contents of the memory register (B reg) to CCC, with the name GateBtoCCCAdvanced, it is either occuring TOO early now or some other signal I had delayed in prior tweaks is now arriving too late. After some single step mode debugging on the 'console' of the 1130, I discovered the CCC was being set in T3, not the time this should occur, at it was a result of the Advanced signal I began using. It may be working well for loading the CCC with a shift count for the appropriate shift instructions, but it is also triggering a load in non-shift instructions at T3 which is BAD.

After some investigation into the logic, I found several errors in my implementation of the new card MB341 that produces the advanced signal causing the problems. It checks for the version of the shift instruction driven by a user provided count, which it then gates into the CCC. The logic checked for an op code of the form 0001x because shift right and shift left are 00010 and 00011. I was checking for 0000x instead, plus I inverted the logic at another point, causing it to assert the signal at the wrong time and in the wrong conditions. Fixed it and the advanced signals work well now.


I wired up the cables to and between the keyboard  interface cards and ran some tests of its operation. The channels I tested in my quick trial are switching reliably and definitively. They are sensitive to ambient light when the keyboard mechanism is exposed, but once covered that is not a problem. I will walk through each channel in the dark tonight to validate the full correct operation of the new design, then fire up the link to the fpga and verify that the logic is decoding these correctly.

Once this is working into the fpga, I need to debug the keyboard adapter logic in the fpga, both my translation circuitry that maps keypresses to the 029 keypunch switch outputs and the logic in the 1130 that would be wired to the 029 keyboard.

I installed the auxiliary card on the frame behind the keys and will probably install the fpga next to it, extending rearwards off the left of the frame. It will be a convenient location just in front of and below the console typewriter, close to where the LED light panel cables come down from the pedestal and other connections get made. where they will sit in the final machine implementation. I have about 13" from the REST KB key back to the faceplate of the console printer, which allows plenty of room to house the boards and cabling.


I ordered the quick disconnect hose connectors, the Propylene Glycol coolant and the twist lock power connector, once I have them in hand I will give the unit a try. If it works okay the next step is to make fittings to route the coolant through the punch head, replacing the ammonia cooling system it now has.

It provides status via an RS232 link, which I will activate to monitor the temperature and other status of the cooling system, hooking it into the fpga for use with the card punch interface logic. Power required is 12V at 8A, which is easily supplied by an old PC ATX power supply. I had a spare one, which I set up to provide only 12V, which should be easy work given its capacity to power two 12V channels of 16A each.

The parts are all in hand. Without a liquid loop, but powered on, the unit passes its internal tests and is running its pump. I couldn't leave it on for more than a few seconds because the inlet and outlet are not connected, but generally things look good. Later I will create a closed loop of hose and fire it up to test circulation and perhaps trivial heat removal if I dunk the hose in hot water.


The IBM 9348 tape drive, a 9 track tape reel based drive, arrived years ago very banged up due to inadequate packing by an ebay seller. I had deferred opening it up to catalog the damage, but began that process this weekend. To my surprise, the only internal parts that were affected at all by the twisted frame and dented in back and sides was the printed circuit card holding the SCSI connectors at the rear. It is a testament to how well this is built that the damage was almost exclusively to the outer skins - the 'tabletop' option for this drive that can alternatively be mounted in a rack.

The printed circuit card was bowed in an arc of about 45 degrees, but it appears unbroken in spite of this severe mistreatment. None of the circuit traces were broken, the multilayer board just seems to have bent, and all the installed chips and other components seem fine as well. I will remove the outer skin, straighten it as much as possible and reassemble, meanwhile I ran a quick status check by powering this up. The firmware reported successful completion of power on self test and good status. I put in a new blank tape I own, but it failed when trying to load, status E033. I did a drive test and it failed with error 60, drive lost tape tension. I did hear an odd sound as it detected the error. I will have to run some more detailed diagnostics built into the drive and look for the cause, to see if I can repair it without buying replacement parts.

After cleaning the tension arm again, the tape loaded fine a few times. I moved on to running a checkout diagnostic that would write data on the tape then read it back to verify correct operation. This test fails with error 5F. The most likely cause is dirty tape or dirty drive, corrected by cleaning the transport area. While I did some cleaning, I didn't have the TCE, similar to dry cleaning fluid, that is recommended. The manual explicitly warns against using isopropyl alcohol as it can damage rubber parts and the tape head. I may also have a bad tape that has deteriorated since manufacturing, but I should see signs of flaking when I inspect the transport further.

This tape drive sits on a differential SCSI channel and contains quite a bit of what IBM calls Licensed Internal Code in the controller and other logic circuits. IBM contracts and policies forbid reverse assembly or other actions, which greatly constrains what I can legally do with the drive. If I can make use of it by driving commands to the fully unmodified unit, or if I can totally replace all the IBM electronics with my own design, I would avoid the issue of the LIC entirely. The latter case is a huge effort and not justified for this project. I need to get a programming manual to learn more about the commands and responses defined for use of this drive, to evaluate the feasibility of using it without any modifications.

I will defer any further work on the tape until I am sure I know that I can interface to this and know how to control it, at which point I will get TCE, clean the heads and transport well and test out access from a computer to validate everything. If it passes all that, I will begin designing and testing an interface.


I began to cut the outlines for the terminator board to allow it to fit into the disk drive and its backplane connector, using my tabletop scrollsaw. It was a slow process, due to the hardness of the fiberglass in the printed circuit card, with the blade dulling rapidly and then smoking and finally snapping due to heat weakening. It took four of the thin blades to cut the basic outlines of the card. I will look at other blade types that might hold up longer when cutting the fiberglass based boards.

The shaping was a bit rough, which I cleaned up some, then mounted my DEC-style handles on the completed terminator board. A similar board was used to anchor the ribbon cables that would lead from the drive out to my controller/interface box. I have wired that cable card but just cut it to shape and installed the handles. Now that is done, I will protect it with silicon conformal spray and start into a prototype of the controller/interface.

However, my final check of the alignment of the pads, signals and orientations uncovered the fact that my layout for the bottom side of each card was wrong. I spent an hour carefully reviewing everything, redrawing the PCB designs and will produce replacement cards later this week, as these are scrap.

New terminator card produced, using the new double sided card blank that is 6 x 9 allowing me to cut the cards to the exact same size as the other DEC logic boards. The earlier cards were on 6x6 blanks, thus their handles were quite a bit recessed compared to the other cards in the cage. One unanticipated issue - my developer pan wasn't long enough to hold the board! I had an exposed board sitting with only an edge in the developer, the rest propped on the rim of the pan, while I scrambled to dump out the rinse water from my rinse pan. That quickly became both developer pan and rinse pan, using running water to rinse away developer then the long pan for rinsing the etchant later in the process.

I got a very good exposure, nice clean patterns, and am happy with how it etched. Before I drill the holes and begin cutting the outlines for the finger inserts and board edges, I will triple check the signal assignments against the other cards and the backplane. Assuming it is good this time, I can do the remaining steps to complete the terminator card. After completing the checks, I confirm this is a good board and tomorrow I will proceed through the cutting, drilling and assembly steps.

Since I picked up two more RK05 drives, which should arrive Friday and Monday respectively, I also should make two sets of drive to drive cables, each having a PCB on both ends. Four of a connector variant of the terminator board are needed, then I will take a fifth connector type board and run cabling to my own interface/controller. All of these will use 50 wire ribbon cables for the wires coming from the boards. I worked with the terminator board PCB but modified it to remove the resistor network packs and make use of a single 50 pin header to which the 50 wire ribbon cable will plug. The routing is done, images produced, waiting for me to make a PCB from them tomorrow.


I have collected documentation and have almost everything in hand that I need. The 1403 printer connector and interface logic is still an unknown, but that shouldn't be hard to come by at the CHM on Wednesday.

I now understand the logic family and electrical interface requirements to the 1401. IBM used several families of logic in this generation, one before the SLT I worked with on the 1130, but the bulk of the 1401 uses their CTDL - complementary transistor diode logic - that the rest of the world would call DTL. It is quite similar to the heart of SLT, although the logic diagrams (ALD) have a different format.

There are generally two voltage levels for logic signals - T and U - that are 6V swings around a reference voltage of either ground or -6V. These encompass the use of PNP and NPN based circuits. Knowing the levels, electrical requirements, termination scheme and protocols (minimum thresholds to be considered a valid 1 or 0 in U or T), I can create the level shifting required.

IO is relatively direct in the 1401 and the handshakes and meanings are documented. Physical issues and interaction with other devices are the main design choices I will have to confront. The IO devices connect via a unique 1401 connector that will be hard to duplicate.

I will visit the CHM tomorrow, spend some time talking to the Binghamton museum team about the approach of fpga modeling of ALD circuits. Hopefully I can advise and steer them, with someone local who has decent fpga and electronics design experience doing the bulk of the work.


I installed the outputs and 2501 control panel interface board in a plastic enclosure, along with its debouncer daughter card, wiring that box with the input box from the reader and will further connect it to the 2501 panel once that is reconditioned. Currently it is missing some glass blocks on lights, some switches, and had been spray painted a mustard yellow color.

I had a bad moment as I looked at my 2501 panel, since it had more button positions and lamps than I had designed into my interface. I looked at the pictures from my visit to Bob Rosenbloom's 2501, which matched the buttons and lamps of my panel. I was sure I had to find additional lamp driver, button debouncer and signal input lines, which meant an additional plug on my newly created interface enclosures. Some additional research, however, clarified the situation.

2501 readers came in A and B models - the B models had integrated control units to allow them to be attached to a 360 channel, while the A models had to be cabled to a processor that had an adapter (integrated controller) to manage the reader. The lamps and buttons were different between the A and B types. As a side note, the reader also had two operating speeds - 600 cards per minute and 1000 cpm - which yields four actual models. The A1 and A2, 600cpm and 1000cpm models without an internal controller, are the ones that are used with the 1130 processor as the adapter is built into the 1130 system. Models  B1 and B2, 600 and 1000cpm models with integrated controllers, attached to 360 channels. The 360 model 20 used the A1 or A2 model, as it did not feature a full channel like its larger kin.

The adapter logic in the 1130 did not support all the lamps and buttons that were driven by the integrated controller of the 2501 B models. Thus, the A models had just five lamps and three buttons. Attention, Read Check, Feed Check, Ready, and Power indicators plus Start, Stop and NPRO buttons. The B models have additional lamps such as Validity Check and End File, as well as buttons such as End File. My implementation will be true to the A1 model - at 600 cpm it matches the speed of my Documation reader mechanism and the panel will tie to the adapter logic designed for the 1130.

I need to clean up the panel I have, strip off the yellow paint, restore it to black, get the lights and buttons in place, then wire it up. The last step before mounting this into an enclosure holding the documation reader will be to fix any switch or lamp block titles that are incorrect. Fortunately, Acetone seems to quickly strip the bilious yellow coating without removing the original surface, as can be seen in this picture after ten minutes work with a soaked cloth.

I was more worried about the buttons and light blocks, as these are some kind of plastic and might have been damaged by the solvent. Again, fortune smiled on me and I was able to clean the light blocks and buttons without any damage to the original surface or coloring. The only issue remaining is that the white paint used for the lettering on those parts is still stained yellow. I may find a way to remove the stain or apply new white coloring or might just leave it as it is. I am proceeding carefully on the final cleaning but I am simultaneously stripping down and converting the lamp sockets to LED.

At this point, I have a cleaned up panel, wired into the card reader interface boxes and ready to test. The remaining work on this is 1) retitle appropriate lamp cubes to replicate the legends on a 2501 (for the Read Check, Feed Check, Power, and Attention lamps), and 2) install the panel and documation reader in a faux 2501 enclosure. My buttons are all correctly titled. I have some emulation logic to complete and test in the fpga before tying together the 1130, documation, 2501 panel and reading some cards.

April 11 - 18, planning, building and debugging on many fronts


My new connector PCB for the cables into the disk drives came out of the developer in superb shape, but distractions that evening led me to leave it in the etching tank far too long. The copper traces were eroding and many of the contact fingers that would fit in the card socket were unacceptably degraded.

Today I manufactured a new connector card, which is in pretty good condition, considering the damage already done to the card before purchase. The blank I had picked up from Fry's Electronics had the printed label affixed to the plastic bag with tape, an unusual addition compared to the other bags of like boards. I was suspicious of a tear that would have caused light leaks, exposing the board, but found no signs of such rips.

However, I wasn't suspicious enough, as this had apparently suffered some strong mechanical impact and abrading, likely scratching the label which spurred them to repair it with shipping tape. When I peeled the protective vinyl from the board in the darkroom in preparation for exposure, I could see that the photosensitive coating had been gouged off in spots on both faces, all hidden under the glued vinyl and the outer sealed plastic bag.

I found an orientation that minimized the amount of my copper trace patterns that would be impacted by the gouges, knowing I would have to solder on some wire bridges a bit later. The remainder worked out quite well and with just three short bare conductor wire segments crossing the gaps in three affected traces, I had a working board.

I chose to buy a table saw blade made to cut plastic and non-ferrous metals, then achieved beautiful clean straight cuts of the board outlines on my saw. I used the sliding table to move the boards smoothly across the blade and found it a delight. There are a few notches and insets and keyed slots on the end of the board with the contact fingers, which could either be cut with a router table or my tabletop scroll saw. Even though it burns through the blades quickly, I went with the scroll saw for two reasons. First, it was easy to see and control exactly how I cut the board. Second, and perhaps more importantly, my giant router table was piled with junk and blocked by other piles of storage that had crept into the garage over the last year.

With everything cut to proper shape, it was then time to drill the holes for the thru components. For the terminator, I had to drill for three 16-pin DIP form factor components, the resistor packs required by DEC logic levels and bus designs. For the cable connector card, it was a single 50 pin header into which I would plug the 50 wire ribbon cable connector. This format has two parallel rows of 25 pins, with some precision required in order to get all 50 pins to go through the holes when I mount the header. If I had drill and the hole to hole spacing is too erratic, it is quite difficult to get parts to go through. As a final touch, four holes at the top are drilled to mount the two DEC handles that grace the outer edge of every logic card.

All prepared, the cards came into the house and were assembled and soldered. The terminator card was easy to assemble, but as I expected, the 50 pin header fought me tooth and nail. I solved the problem by using separate header rows, painstakingly maneuvering each pin into its hole and then soldering it to the traces. The ribbon cable connector fits over the parallel header rows just fine and my signal continuity tests showed all is well with the connector card.

After a bit of testing and triple checking, I declared the two cards complete and (probably) correct, pending live operation of the link from my interface box. They are installed in the drive and covered by a prefilter for the air inlet I constructed. I took a reusable filter fabric designed for air conditioners, the aluminum outlet for vent holes along roof eaves, trimmed them to size and fit them with two sided tape and holddown screws/washers.

I can now begin building my test jig for proving out my disk interface logic. Portions of the drive can be tested independently of others. For example, tie the cylinder address pins to 1 or 0 power levels and activate the strobe signal to request that the drive do a seek. Before it will respond to anything, I have to tie the select lines to the address this drive answers, as a constant requirement for all other testing. As another example, if the read gate signal is activated, I should see clock and data bits streaming out of the drive. Restore plus strobe will move the arm back to the home position (cylinder 0). I will probably create a breadboard to do this testing before I move onto PCB design, to ensure I have the levels and other interface details working properly.

My second drive arrived today, packed extraordinarily well by the UPS store where the seller dropped it off. Only downside - damned styrofoam peanuts. In the low humidity in California, after 3 or 4 handfuls are handled, they pick up a large static electric charge and begin to fly apart as well as stick like magnets to my skin. Dump a handful in a bag, most stay on the hand and fly back to you if flicked away. This was a very large box full of these things, it would take days if I couldn't scoop more than four handfuls at a time.

I searched the web, noting all the solutions that were alleged to work perfectly to remove the static. Method one involved rubbing my hands with olive oil - which did nothing other than add an oily residue to the rest of the mess. Method two was to spray the peanuts with Windex. This in fact worked, but only for the peanuts that were directlly struck by the mist. I was able to spray the top surface, scoop down one handful deep all around the box, then repeat.

I wrestled the drive up onto my work table in the garage. I noticed that several of the plastic light covers on the front were missing, but this is not much of an issue. The seller had already mentioned that the bottom covers are missing, which is more substantive as I need this closed up to keep out contaminants that might cause disk crashes. The shape is pretty straightforward so this should be a simple sheet metal fabrication task. Like my other drive, it lacked the terminator card and the cable card.

I had asked the seller to install the shipping strap - a bracket that is reversed to hold the voice coil and arm back in the fully retracted position. This protects the arm and head from bouncing in and out, possibly being damaged during shipment. The strap is placed on the voice coil magnet, jutting out radially away from the voice coil. To install it, you loosen the bolt and rotate it 180 degrees. It then sits in front of the voicecoil carriage and blocks it from sliding out from the retracted rest position.

To my chagrin, I found that the strap was rotated only 90 degrees, thus not blocking the movement at all and potentially it could have ruined the voice coil magnet windings if they had scraped along the bracket. I don't see any damage to the arm or the voice call. Hopefully I was lucky once again with drives being shipped without the arm restrained, although I now am thinking of drive three that the same seller has coming to me on Monday.

The drive checked out, so I powered it up and it came up with no fault indications or other symptoms. The heads look clean, but the blower, air filter and remainder of the air path needs major cleaning before putting a pack into the drive.

Drive three arrived also without apparent damage - in this case because the shipping strap was in its non-shipping position, apparently the seller forgot about the task entirely. Fortunate as it could have damaged the mechanism. The arm and heads seem to have weathered the trip fine. This drive had a lot more deteriorating rubber and foam - the foam falls apart with age which is common to all the drives, but a rubber connector )from the air filter to the duct that mates with disk cartridges) had become brittle and shattered. Not sure how this happened, it is so different from the other drives.

I need to clean out and clean up the two new drives, then decide whether to clean out or replace the air filter that blocks big dust and smoke particles from getting to the disk drive. I will figure out a replacement for the rubber connector, perhaps casting one in the tech shop if I can't find a direct replacement part.


My final parts arrived for the chiller that will keep the punch head cool on the card punch mechanism and I completed building the power supply. I have to pick up some hosing, pull out the ammonia cooling gear and install the chiller inside the punch. Lastly, I will run an RS232 cable out to allow me to monitor the chiller operation and punch head temperature.

I installed a hose loop and ran the chiller for a bit, which worked properly although there was an odd sound from the pump that could either be worn bearings or just cavitation because I hadn't topped up the reservoir when the 20 feet of hose was filled with glycol mixture.


I have mounted the auxiliary board that detects the photocell outputs of the keyboard mechanism. It is cabled to the main interface card that plugs into the side of the fpga board. The fpga board will mount to the left of this auxiliary board, both will sit under the tilted formica desktop surface of the 1130 system, in front of the console typewriter and behind the keyboard mechanism.

Above the mounted boards, on the front plate of the console typewriter, are 16 toggle switches that are used to enter data and control program execution. The switch used on the 1130 is almost identical to this one, which is harvested from another bit of scrapped IBM gear, but I do not yet have the 16 I will need.

IBM switch, cylindrical shaft with plastic tip, built by Arrow-Hart and by Course-Hinds for IBM


I did some modest restructuring of the logic design for my interface between the IBM Electronic Typewriter model 50 mechanism and the 1130's adapter circuits designed to operate a 1053 Selectric. The behavior is much more solid now.

I did (re) learn a hard lesson when debugging some incomprehensible behavior, where a signal was switched on inexplicably because the signals that were supposed to determine its state were trimmed away during synthesis. My margins were to be set by pushing a button on the typewriter when the carriage was at the desired position, but during the testing there is no button installed. The tools noticed that the button signals could never be activated, thus the margins could never be set, thus it tossed away the signals themselves. With the signals missing, the comparisons and other tests were eliminated, leaving the end of line signal because it was hooked to a real output during testing. Debugging the comparisons and tests which had been tossed in the wastebasket was a futile exercise.

I have to periodically wade through a huge volume of messages that the tool chain produces during synthesis. The software produces many warnings that are not an issue, but provides no means to suppress those or mark them as 'intentional choices'. You can either stop all messages or read through thousands, but can't selectively disable them. The reports would be much, much more useful if all they flagged were problems you hadn't already investigated and accepted.

The great thing about working with fpga circuits is that they are totally soft - load a new set of code and within ten minutes you have a changed circuit. Much faster than physical hardware can be modified. This suits me well, as I am willing to tear up a design and start over if I find it losing a clearness or elegance, something I may do a dozen times or more until I feel satisfied. This is definitely true of the typewriter interface, because I am so paranoid of damaging the somewhat fragile mechanism if flaws in my logic activate mechanisms at a bad time. This week, I did one major restructuring and have now taken on a second rewrite. Very pleased with behavior, just cleaning up all the special cases and conditions I can dream up before letting it loose on the selectric mechanism.


Inputs side interface box for Punched Card Reader

Rear of salvaged control panel from IBM 2501 card reader

Scrap 2501 control panel with yellow paint over buttons and lamps

Outputs side box for Punched Card Reader interface

Acetone removed yellow paint; still have to clean up white lettering

Clean up of glass block for indicator lamp, needs touchup of white legends
On a parenthetical note, I had believed the card reader was marginally out of adjustment because it would get read check errors on certain cards, always the same types of cards, those with a slant cut on the trailing edge. However, today I was told that this is a well known misbehavior of the Documation readers - they all do this, because the see the light come through for the notch and assume the card has prematurely cleared the read station, thus it wasn't moving at the expected speed and the data read is suspect. If I ever have spare time I may investigate a way to 'mod' the readers to disable this erroneous behavior.


I created the design for a PCB to control the paper tape reader, hooking the mechanism I have to the 1130's adapter and causing it to behave like an IBM 1134 which was sold for use with the computer. I moved quickly to produce the board, as I had all the components on hand to assemble everything except a set of 10 resistors.

During the manufacture of the PCB, I apparently didn't leave the board in the developer quite long enough, as one corner of the board must have had a slight coat of the resist still in place, hard to spot in the darkroom conditions. The effect, however, is that the copper does not etch away where the resist remains, leaving one corner of the pattern with copper shorting and bridging traces.

In looking at the area affected, I realized that with a bit of scraping to eliminate the shorting, I would have a cosmetically flawed but fully functional board. With no spare board stock of the right size, I began scraping away.

The following day, after I picked up the remaining components, I assembled and soldered the board.

Paper Tape Reader interface board, almost complete
Paper tape reader in current enclosure, will remount it in 1034 style enclosure


I spent some time with a few people at the Computer History Museum checking out the 1054 and 1055 paper tape reader and punch units they wish to attach to the IBM 1401 computer they have restored. The interface for the reader and punch is very easy and quite well documented from the 1130 materials I own. The museum has a clever device built by a team member that pretends to be a virtual tape drive, hooked on the chain of real IBM 729 drives, but streaming the data through an RS232 link. With a small bit of work, the paper tape units they own can be connected to that RS232 port and accessed by programs in the 1401.

A museum in Binghamton, NY is restoring an IBM 1440 computer and faces several challenges with getting peripherals attached and working. Bob Rosenbloom had donated his IBM 1442 reader/punch to the museum and the team there is building an interface to connect it; that work seems to be well along. Robert Garner, who leads the 1401 team at the CHM, bought a 1403 printer that came on the used market and is donating it to the Binghamton team. However, this model has an integrated controller inside to connect to IBM 360 bus and tag cables, not to a 1440. The 1440 would make use of 1403 printers, the models with native 1403 connections not bus and tag, through a controller named the 1446 for which zero documentation seems to exist. I will be working with controller logic from the 1130, 360/20 and a 2821 control unit to create an interface for the printer, but key information I need concerns how a 1440 connects to peripherals. They will send me scanned documentation and I will determine how we might proceed.

Finally, the Living Computer Museum in Seattle has a 360/20 to which it needs to attach a 2501 card reader and a 1403 printer. We are not sure exactly what adapter logic may be installed in the 360/20, but at worst case it can be replicated in fpga. I am collecting some final documentation but this should be straightforward albeit substantial work. They are fairly sure that they have the logic installed to support a 2560 reader/punch device, thus if we can build an interface to map the 2501 to behave like a 2560, they should be able to get it working. The 2501 they have is a model B with a control unit built into the frame, but the 360 20 works with a model A reader, one that has no controller logic inside it. Instead, the 360/20 would have controller logic in its 2501 adapter circuits, if that adapter had been configured on the machine. It does not appear to be present, however.

I did spot someone selling a used manual on Amazon that looked promising. It arrived today: IBM Field Engineering Theory of Operation - 2501 Card Reader Model A. This describes the reader and how it is implemented with a 360 model 20! This provides more than enough information on the 2501 to interface to it. I have scanned the manual and delivered it to the archive to allow others to access this historical information.

On another front, I found an auction on ebay that appears to offer a cable set that has bus and tag connectors (360 channel connections) on one end and a high density single connector on the other, presumably to connect to an add-in card for a PC or workstation that allows it to access 360 peripherals. I don't need the add-in card, but having the right cabling is highly valuable and time saving. It is on the way here.


Since the printer is driven by RS232 signals and my controller will be an Arduino, I have some level shifting to address. Specifically, RS232 signals 1 and 0 states by swinging voltages between + and - 12V, while TTL logic swings between 0 and 5V. To handle this, I made use of a pair of MAX232 chips, which are designed to accomplish this exact task of level shifting between RS232 voltages and TTL style voltages. I designed and built a card that used these chips to provide the data, CTS and RTS signals to the Arduino, which can process several RS232 links as long as they are level shifted first.

The board had a small amount of damage done sometime before I purchased it, which lifted the photoresist in one corner. This left a gap on a ground trace, which I easily closed by soldering down a bridging conductor. Here you can see the completed card with the surface mount components installed and the conductor bridging the gap.
My level shifter card for line printer interfacing


I have signed up with a membership shop facility ( for access to their shops where I can make the sheet metal cabinet enclosures, machine needed metal parts, leverage 3D printers and other machinery to make key handles and other cosmetic touches, and move the project along toward completion. They mandate familiarization/safety courses on major equipment before you can use it, but after I attend four such classes in the next week I should be able to drop in when I have time and need to fabricate some part of the system.

After completing the sheet metal course, I went in to the shop and made the box that sits on pedestals above the console typewriter, into which I will install all the blinking lights, the rotary mode switch and the emergency pull handle. It was pretty straightforward, although I did learn one lesson about the order in which I need to make certain cuts and folds. Easily resolved and something I will avoid in the future.
Light panel enclosure, not yet soldered or drilled

How the rear will look, with pedestals in approximate position
I had to learn how to solder the plates and make the result look good - takes a bit of technique to do this well and I had zero technique at the outset. I began with the pedestal uprights, then moved on to solder the two halves of the enclosure together. Due to the limited size of the sheet metal at the local home improvement store, I had to make the roughly 28" by 5" by 4" box as two "L" shaped halves, with a 28" and a 5" leg, then connect the two halves to make the entire box. I overlapped a bit on the sides and soldered it to close any gap.

Since the metal will be finished with a bumpy surface under the paint, to match the appearance of the real 1130, I can hide imperfect joints to a small degree but anything grossly wrong will still be visible. Grinding or sanding can take down imperfections to a size that is masked by the finish.

Work done from April 19 to 28 2013, plus needed to improve my modeling of SLT SingleShot component


The adaption of the Electronic Typewriter Model 50 as the console printer requires me to implement some hidden shift cycles. These cycles handle the situations where an ET50 typeball has a character placed on the opposite side of where it is installed on the 1130 typeball. The 1130 adapter logic positions the ball in a discrete shift cycle it commands before printing a character, if the character is on the other side of the 1130 typeball (frequently these are called golf balls) from its current position.

When I receive the character to be printed and translate it to the location on the ET50 ball, I may need to shift the typeball to the opposite side from its current position. This has to be done as a hidden cycle since the adapter knows nothing of these details and believes it is doing a simple one character print.

The complication comes from the timing assumptions built into the 1130 adapter, which sets timers based on the known print cycle time of the selectric mechanism. Those timers won't account for the extra cycle I have to take for the hidden shifts. I believe I can handle this by manipulating the two status signals that are used by the 1130 adapter - CB Response and Interlock.

CB Response will flip to 0 and then back to 1 during the course of a print cycle, but those changes must be blocked during the hidden shift cycle. Interlock is turned on during long movement operations, such as carriage return or tab. I may need to use this signal to keep the adapter waiting and the typewriter appearing 'busy' to programs until the elongated character printing has finished, turning it on when I determine I have a hidden shift cycle and switching it off at the completion of the character print cycle that follows the shift cycle.

However, I have to be very careful here because some states may be changed solely by the expiration of timers, such that it could change program behavior. My debugging of the typewriter interface logic is centered on this topic.

Physically, I removed the front (keyboard) section of the typewriter in preparation for mounting it in an 1130-look-alike enclosure. I am designing the mount and enclosure for the mechanism, likely to fabricate it soon.

After the behavior of the FPGA seemed reasonable using the Arduino to emulate the feedback signals from the typewriter and the logic analyzer to watch the outcome, I gave it a brief live trial, with results that indicate the emitter output is not being received properly in the fpga - the unit typed the first character of my program and then began moving continuously to the right side of the paper. I am doing some experiments to validate the proper wiring and condition of the emitter output from the machine, then will make any necessary adjustments for the next run of the test.

I discovered and cleaned up some ground issues in the testbench, because I often use patch cables which have narrow pins that don't seat firmly in the headers and other sockets on the fpga and my circuit boards. once that was fixed, the emitter is working extremely well. I have also determined the PFB debounce requirements, about 150 microseconds would work based on what I observed, so out of caution I will bump this up to half a millisecond. The photocell emitter does not suffer from bounce, so I put in only a 2 microsecond debounce time just to clean up any transients that might hit the line. When I went to zero debouncing, the results proved that it does bounce, just less than mechanical contacts.

I floated the fpga input for the emitter and put in a 1K pulldown resistor at the typewriter, which gives me a nice clean signal both by scope and received in the fpga.  As with the ground connection, these are analog or classical electrical engineering issues and not digital logic problems. This is the phase where such problems will be encountered - initial full hardware test.

To my surprise, the emitter signal from the typewriter operates under a different protocol than the other two switches (printcycle feedback and upper case status), emitting 3.7V when the emitter is at logic 1 and 0 when it is off.

I began getting reasonable single character operation, but discovered that I misunderstood the polarity of the upper case status switch coming from the typehead. It caused my full logic to flip the typeball to print in the wrong case - a digit '1' became the character '!', the digit '3' became '#', etc. A quick fix got me back on track. I put in a crude carriage return capability during testing - one button that forces the typewriter to back up continuously while depressed.

Getting the emitter detection and shadow tracking of the position of the carriage was quite challenging. Once again, when I began driving circuits from the fpga, the fast rise times produced major transmission line issues with the sloppy wiring rig that served me well for the general logic debugging.

I decided to switch to a ribbon cable link, matching the fpga side impedance and killing reflections with a higher resistance termination where the cable connects to my driver board under the typewriter mechanism. Every other line in the ribbon cable is tied to ground, which establishes the cable at just a bit over 100 ohm impedance, matching the fpga outputs and the 75 ohm series resistance on the Digilent board. After the switchover, behavior was much more solid, but still not totally correct.

I ran my hand-coded 1130 program that will run through a buffer of characters using the 1130 console printer codes and drive the ET50 mechanism. I ran it in single instruction mode to separate issues of timing in my program from issues with the interface, adapter and physical typewriter mechanism.

I discovered that the IBM typewriter adapter logic is riddled with race hazards which depended upon the slow operating speed of the SLT logic gates and the signal paths among the modules/cards to achieve correct operation, but I hadn't modeled the single shot modules correctly enough.

IBM uses single shots (triggered pulses of some defined duration) and other pulses as timing control throughout their SLT machines, as logic is pretty much operating independently of an exact clock edge or of a common global clock. The IBM SLT instantiation of a single shot has the characteristic that after it has fired for its intended duration, it has a recovery time of at least that long afterwards when it won't fire again. This 'recharge' time allows for some spurious triggering signals that might be generated by a circuit due to timing differences between the end of the single shot pulse and the final state this will cause in other signals. During a short interval, the trigger may occur but it will have no effect.

In the typewriter adapter, a 25 millisecond timer (Single Shot 1) is fired, when it ends the adapter will trigger a second 25 ms timer (SS2). Logic considers the typewriter busy as long as either SS is active, but there is a short interval when SS1 drops to zero, the triggered output of SS2 has not yet arrived at some combinatorial logic but the newly zero value of SS1 has arrived. There is a blip where the logic thinks that both timers have ended. This can cause the SS1 to refire, if it has a zero recovery time like mine did. In SLT based machines, the SS module will not have recharged yet and ignores these false triggerings.

My solution was to update the behavior of my 'singleshot' component that is inserted whereever the ALD has an SLT SS gate. Where my gate had simply fired off a pulse until a counter of fpga clock cycles went down to zero, it now has to reload the counter and do a second pass to wait the same duration, before it will again be sensitive to triggering. This behavior is configurable via a generic when I instantiate the singleshot component, thus if I have logic that MUST trigger again almost immediately, I can support that as well as the IBM SLT conformant behavior.

I am seeing very good behavior from the typewriter, but still chasing down a few timing issues. In particular, it is still devilish to get the hidden shifts working well with the inherent timing logic built into the selectric adapter in the 1130 - it assumes every print operation will finish a print cycle within 25 and 50 ms after it begins, but with a hidden shift we need about 120 ms total for the twin operations of a shift followed by a print. I am going to study the output of the logic analyzer as I run many print tests, trying to find commonalities behind both success and failure.


I designed, made and soldered on some brackets that will be used to connect the pedestals with the light panel enclosure. The attachment method I selected and the design of the box I used to make it are unsuitable. They can't be used if I want to end up with a pedestal box that looks the same as the 1130, but at least I can use it as a mockup while I build the final version.

With the box able to stand on its pedestals, I temporarily installed the LED lights into the box. I had cut the two side plates, one of which holds rotary switch to select the 'mode' of the 1130, the other will hold the sham emergency pull button that my friend, Lawrence, is having milled. I temporarily installed the rotary switch, wired it up, and installed it into the display panel enclosure.

The mocked up box is missing the plastic that has the printed mask which labels and outlines the various sections of the display and has clear outlines of the various numerals that are lit by the LED behind them. I will have to build a separator grid that surrounds the many LEDs such that light from one does not illuminate any adjacent positions. The 1130 itself has a plastic grid that accomplishes this, although IBM used incandescent lamps not LEDs.

I used a 3D printer to build the plastic grid that separates the LEDs, hoping to install that onto the front of the boards that hold the LEDs. I verified that this could fit into the panel enclosure box but my first try ran for the entire four hour timeslot I had and was only able to get to 38% depth- too thin to cover the LEDs from base to tip, which is the minimum to give good blocking of light from adjacent LEDs without some labor intensive individual cones or barriers inserted around the bulbs. I was shooting for 1/2" and only got to about 3/16" deep.
Mockup of console light pedestal stand

Testing the arrangement and attachment options

I believe I can make design changes to the grid, plus alter a few 3D printer settings now that I see how the first cut worked out, to turn out one of these within a four hour period. I uploaded the design file to several 3D printing services for quotes, with the lowest quote per unit at $131 and the highest almost at $350. Considering that the 1130 needs two of these, and we are talking about a simple 8" by 4.5" grid of plain plastic, those prices are unacceptable and I have to continue with self-manufacture.

My second try fared only a bit better - 3.5 hours to get to 45% completion. Looking at some alternative approaches otherwise will plow ahead fighting the 3D printer to get this done in the max time I am allowed on the machine. I do have other items to create that are quite a bit less massive and should be quick to knock out on the 3D printer.

The 1130 has handles on toggle switches that are 1" wide parallelograms, narrower front to back at the top than at the base, made of white plastic. I modeled the handle, got a much more reasonable quote from the 3D print services and have ordered the two I need. I have finished the design of the baseplates through which the switch shaft projects, with the handles described above attached to the ends of these shafts.  Other plastic needs include special 'tab', 'space' and 'return' buttons for the faceplate of the console printer (typewriter), the side platen knobs and the top levers for pitch, etc.

I am working on a new design to build the final version of the box and pedestal, that will look correct from the outside and that I can manufacture with my skills with the available supplies and equipment. Once this is complete I will begin fabrication. Once built with all internal brackets soldered into place and all holes drilled or cut out, this will be powder coated with the grey textured powder I ordered.

I am beginning the creation of the artwork that will be silkscreened onto acrylic as the front face of the display pedestal that houses all the lights showing the contents of registers and various machine states. Once I have good artwork, I can work out how best to print the image on the inside surface of the acrylic that will cover the front of my display panel.

I have the full 1403 printer wiring diagrams and most of the other information needed to advise two museum projects on their interface of the printer to mainframes. I proposed an approach for the team working with the IBM 1440 system in Binghamton and listed the tasks, as well as noting the open questions that remain to be resolved. It is my expectation that I would advise and be available to whoever is doing the detailed design, fab and testing work, rather than my building anything directly. The 1403 printer that is going to NY has the cables and the appropriate connections to hook this to SMS (14xx generation logic), called 'paddle cards'.
1403 printer cable with paddle cards to connect to 1440 era logic circuits

The other project, tying the 1403 and a 2501 card reader to a 360/20 for a museum in Seattle, is less defined now, but I am continuing research in order to recommend ways to proceed. They have capable people at both of these museums, who will make decisions and implement what is needed for their projects; hopefully their task will be made easier by information and suggestions I can provide.

Since it is possible that I would need to design a general 360 multiplexor channel and interface it to the 360/20, which does not come with standard channels, I bought a bus and tag cable which has a modern connector on the other end, a high density 78 pin connection that it will be easier to accommodate if I move ahead to build the channel. With this, I may be able to 'breadboard' and test a channel to be sure I have it correct before passing it along to the museum.

I did some exploration of leveraging the MAX232 chips, which are designed to interface RS232 signal levels to TTL voltages, as I have an idea for how these can be used to interface to the CTDL levels of IBM SMS technology, e.g. for 1401 era machines. The CTDL logic is mostly based on +6/-6 and 12/0 levels, IBM terms these U and T, thus by appropriate offset of ground these chips can receive both voltage standards and I suspect I can generate acceptable signals for U and T as well. I will do some breadboard work when I get a chance.

more work accomplished


I wired up the connectors between the PT reader mechanism and the PT reader interface card, as well as the final connection that will link this to the fpga 1130. I have verified the mechanical operation of the unit, although I may have to add some tension to the rubber belt before doing any live reading.

I found some paper tape programs on ebay, which will not work for the 1130 but are well formed and will let me verify correct reading. Will put this aside for a few weeks to work on other portions of the machine.


The improved SingleShot component behaves correctly and this resolved the undesirable retriggering of SS1 due to the race hazard identified below, but the blip that previously triggered SS1 for the second time is also propagating thru the adapter logic to switch other gates. It is clear from the design that the original engineer expected this blip would not change anything, because it was short enough that it would be unable to trigger the IBM edge detecting gates which require a long hold of the trigger signal to switch the gate.

I have flagged the race hazard in the diagram below, where the drop of SS1 is routed to the trigger of SS2 but also to an OR gate that maintains an interlock as long as one of the three conditions is true - SS1 is firing, SS2 is firing or Drive Interlock is on. The issue occurs because SS1 drops, SS2 has not yet risen, thus the OR gate drops its signal in that interval until SS2 comes on. This drop is what prematurely triggers activities that are supposed to occur only after BOTH SS1 and SS2 are down.

Race condition where SS1 drop reaches OR gate (up arrow) before SS2 is firing (right arrow)

My solution was to add a delay for the signal that is entering the OR gate, giving a couple of cycles during which SS1 still appears to be on, during which time SS2 will have fired and its output will be at the OR gate. When the delayed SS1 drops the OR gate is held high by the SS2 and we get the intended results from the adapter.

The emitter remains a bit problematic - due to mechanical inertia we can seem to detect an extra count after we have dropped the escapement signal which shuts off the motor drive. More seriously, the quality of the pulse train is ragged, even with tweaks to the debouncing circuits. What I need to have is the falling edge of the emitter signal, without bounceback, to tell me once and only once that a new hole has arrived on the emitter wheel. I did some redesign of the approach in order to achieve this objective properly.

The action of the print cycle - printing a character or even firing that mechanism to release the clutch for movement only operations - seems to yield some spurious signals from the emitter which I need to either eliminate or block suitably.

Decided to remove the emitter and print feedback signals from the path through my relay driver board, just in case I am inducing noise or degrading the signal somehow. Wired up a bit of coax to the emitter and now enjoy really really solid emitter operation.

This prints well until it is time for the hidden cycle, where I am ending the cycle prematurely having not even fired the PSCC for the shift of the typeball. I also noticed that I can ask for a hidden shift cycle on movement only commands (e.g. space), but it has no meaning for these and shouldn't be activated. Time to move the diagnostic signals around and put the logic analyzer and brainpower onto this. If I can get this cleaned up, I can say the core of the selectric interface will be complete.

The impetus for movement only commands attempting hidden shifts was that I assign a tilt/rotate/velocity/case string for every firing of the print cycle mechanism, even when that cycle is used solely to release the escapement mechanism that allows the carrier (carriage) to move left or right. If the case I set up was different than the position of the typeball, it forced a hidden shift. Rather than try to sort out what command was in process in order to disable the shifting, I eliminated the attempt altogether. I did this by setting one of two alternate strings for the movement-only commands, with upper or lower case, depending upon the state of the ball at that instant. The logic would always determine that the ball was already in the proper orientation, thus it would skip over the hidden shift process.

Remaining testing areas for the interface include:
    - validating successful carriage return/line feed operation
    - run through all characters to ensure they are mapped correctly
    - test left and right margin setting and impact on returns, end of lines
    - test tab set and clear functions
    - test tab operation
    - startup routine homes the carrier and prepares typewriter for normal operation


The restoration technical staffs at the various museums where I am helping are all excellent, a joy to work with. The Binghamton museum group did some research on the 1440 we are attempting to interface with a 1403 printer. That machine's documentation and logic diagrams show it was configured to attach to a 1443 printer, a different type entirely that oscillated two linear type bars side to side across the page for printing, whereas the 1403 rotates a chain of type slugs between the hammers and paper.

Their research did document how it was programmatically viewed and controlled by software on the 1440, and it is very good news indeed. The programmer issues a command to print one character of a line, doing this repeatedly to fill a line. There are branch commands defined for various carriage control tape states, for example branch if carriage control tape channel 9 is sensed. Nothing else, thus no details of the printing mechanism or timing are exposed to the programmer. These instructions and results are fully compatible with how the 1403 printer works, thus there is an easy, straightforward mapping of semantics and behavior.

The next step of investigation will be to check for the existence of each SMS logic card and connector in the 1440 that the logic diagrams show are installed when a 1443 printer is hooked up. We can then document the signals and physical details for the connector or connectors we will use, most likely a set of SMS paddle cards but possibly a unique connector.

We have the full logic of an adapter that takes a line of type and prints it, plus the full logic to move the printer ahead and sense carriage control tape channels. We have the circuits with parts values for the cards that drive the print hammers and even the full circuits with parts values for the power supplies.

Given what we have learned, the odds of a successful mating of the 1403 to the 1440 and the ability to print by program has shot up. I would guesstimate it at 60% already, and if the cards and connectors are all there on the 1440, and the cards all work properly, and the 1403 mechanism has no broken or unrepairable parts, it would shoot up to perhaps 85 to 90%.

The items to make are power supplies and driving circuits for hammers and clutches, SMS sockets to connect the printer cable into, level shifting circuits to adjust the logic voltages and thresholds to modern fpga or microcontroller levels, level shifters for the connection into the 1440, some paddle cards or connectors and finally cables between interface and 1440. All the complex logic of driving the printer and mapping results will be handled in the microcontroller or fpga or other modern circuitry.

I need to sketch out the basic framework, circulate it to the teams in Binghamton and at the CHM, and provide any assist they need to move this forward into an active project. The group in NY have cleaned up the printer and it appears to be in very good shape. However, it is missing a few small parts, one of which is pretty essential. The print train cartridge, which holds the type slugs on a belt that rotates across the hammers and page, is missing a small gear in the set that drives the belt. If a spare can't be found, likely one will have to be fabricated after divining the proper design of the gear and teeth. The other parts are in the mechanism that  raises and lowers the cover over the 1403 - a sound reducing cover to lower the noise that is a feature of the N1 model printer. The cover can be manually raised and lowered, thus lack of the parts is not too much of a problem.


The front of the pedestal mounted display panel on the 1130 has two squarish metal plates on each side and a 20" wide by 5" high plastic plate in the center. That plate has lettering and other printing on its inside face, with transparent openings in the shape of numerals and letters for each place where an indicator light will glow. The basic background is black, with medium and light grey rectangles defining groups of lights that are the bits from one machine register, plus lettering and other legends. In the 1130, incandescent lamps glow behind the transparent openings for numerals or letters.

My machine replaces the incandescent lamps with LEDs, with a suitable filter to recreate the yellowish color of the original equipment lamps. The LEDs are separated by a grid or honeycomb, similar to how the 1130 separates the incandescent lamps, blocking spurious illumination of an opening by lamps in adjacent positions.

I am preparing the image that will be printed on a plate of acrylic 20" by 5", to sit on the front of my display panel. The image will be reversed as it will be printed on the inside face of the plate but read from the outside face. I have been working out the techniques to draw the image with Adobe Illustrator and have just worked out the final process I will need - 'punching' out a transparent hole in the shape of a text numeral or alphabetic character from a painted rectangle.

I will proceed to drawing the plate image very accurately to the measurements and pictures from the 1130 machines I visited, print it in grey scale and take it to CHM to hold up against the real machine. That will primarily be to validate the colors, intensities and other cosmetics, plus review how closely my chosen font appears to the unknown font used by IBM. Once it proves out, it can be flipped and saved for manufacturing.

The way I will print the image on the acrylic is still up in the air. I will check with various silkscreen printing businesses as that is likely the best method, but a hand-made version done in TechShop is a fallback. So far I have found services that print pictures on acrylic, not too bad in price as long as they can leave off the wall mountings and backings they normally include. 

Major rework of the 1130 logic to make fpga operation fully clock sync

After experiencing an increasing rate of misbehaviors that are caused by operating the fpga in an async manner, something that is widely flagged by experienced engineers as problematic, I decided to alter my strategy a bit, developing a method to make the async IBM elements operate synchronously to the underlying fpga clock. As I added more logic to handle peripheral devices, the utilization of the fpga increased. This led to more signals being routed longer distances inside the fpga, which increased the chances that signals to drive logic may arrive at different times.

These race hazards are avoided by good sync design, because all the timing variations are completed and signal levels stabilized long before the end of a clock cycle, so that actions to be taken are shielded from instantaneous incorrect results that come from the logic gates during the times when only partial signals are seen. The glitches still happen, but any action such as a state transition of a FSM are only determined at the clock edge, long after the glitches have gone away. The glitch is going to happen just after the clock edge of one cycle, shortly after all the signals have arrived and the glitch is gone, while we are still in the midst of the clock cycle. By the next edge, no glitch any more.

The combinatorial logic - the ordinary nonclocked functions such as AND, OR and NOT - are where the glitches occur. As long as actions are only taken on clock edges and as long as the signals feeding combinatorial logic are stable long enough before the clock edge, we get good reliable behavior. For most combinatorial logic, they receive new signals from actions taken at the last clock edge, thus their settling begins at the beginning of a clock cycle. As long as cumulative delays of gate operation and signal routing don't get close to the length of the fpga cycle, everything is stable by the end of a cycle.

Some circuits are driven by external signals, whose changes are initially unrelated to the clock cycle of the fpga. These therefore could change very close to but before the clock edge, with the resulting glitches not yet  vanished when the clock tick happens. This is a second type of async that the designer has to handle, often by passing the signal through a series of clocked registers to align the change in the signal value to the clock of the fpga. Usually, two in a row is considered sufficient to deal with short term metastability if the external signal changes extremely close to the clock edge. The chances that the unstable output of the first register will produce metastable behavior in the second register is quite low, enough so that a third or further stage is not usually warranted.

An FPGA does not actually implement AND, OR, NOT or other basic logic gates to instantiate the combinatorial logic I write. Instead, fpgas are mainly composed of look up tables (LUTs) which the 'compiler' will set up to produce the results intended by the combinatorial logic it is replacing. The input signals for the targeted logic are used as the address into the LUT, and the output of that table for each combination of input values is the output of the targeted logic. As a simple example, if I coded a four input AND gate - output <= Ain and Bin and Cin and Din - the compiler would set up the four inputs as the bits of an address for the LUT, then put zeroes in all the locations in the table except for the one location that corresponds to the address 1111 which is the case where all four inputs are true. In that one location, a logical '1' is placed. Thus, when the signals arrive, they are addressing a cell in the LUT and the value of that cell is the output we see.

Now, if the signals don't arrive at exactly the same time, we can have temporary addresses that are incorrect. Imagine that we have values for the signals Ain = 1, Bin = 1, Cin = 0 and Din = 1 initially, but these are going to change to Ain = 1, Bin = 0, Cin = 1 and Din = 1. The output of our logic circuit should be 0 initially and stay 0 after the new inputs arrive since both states don't satisfy the AND logic equation. However, imagine that the signal for Cin arrives earlier than the signal for Bin. As the new value of Cin (1) arrives but the old value of Bin is still present (1), we temporarily have an address of 1111 for the LUT. That means the output will temporarily be 1 instead of 0. Thus, at a gross level we are changing the inputs from 1101 to 1011 and expect a steady 0 from the circuit, but due to delays we see the output 0 glitch up to a 1 for a short period then fall back to 0.

Each time I make a change to the logic and rerun the 'compiler', it assigns my logic to LUTs and routes signals. From run to run, the placement and routing are often very different, and this is true for areas totally unrelated to the logic portion I was changing that required this new run. Thus, one may do a run of the 'compiler' and find the fpga behaving badly compared to what you expect to happen, then do another run that yields an fpga working as intended.

Some parts of the 1130 design are triggered asynchronously - whenever the trigger signal is 1, the gate will operate. Since these are edge triggered flip flops in most cases, they see an edge and will flip. The almost immediate revocation of the trigger signal doesn't matter, the 'mousetrap' is already 'sprung' and needs a signal on a different input in order to be reset. Dropping the trigger condition just leaves the flipflop set.

My edge triggered flip flops had been designed purely asynchronously - built as a SR flipflop with some extra logic to enforce the IBM behavior, but changing when the combinatorial signals looped around and the set of gates stabilized in its new state, either on or off. This had no relationship to the fpga clock, thus signals produced by these gates could in turn be causing glitches in circuits they fed; if those glitches happened with an aynch gate like the edge triggered ones, or very near the fpga clock edge, then erratic results could ensue.

Another class of latch is used widely in the 1130 - an async latch composed of some AND, OR and NOT gates interconnected. They have a set and a reset line, but no connection to the fpga clock nor to any particular timing in the 1130. Whenever a reset signal arrives, the latch will turn off. Whenever a set signal arrives, the latch will turn on. If those set or reset signals are brief glitches, they change the gate just as well as if it were a long term input.

 Like the edge triggered flip flops, these are 'mousetrap' gates that are sprung by a wrong signal and require explicit resets even if the input signal goes to its intended state almost instantly. The logic gates in the fpga are LUTs, remember, and the lookup is extremely fast compared to IBM SLT gates. Thus, it doesn't take many picoseconds of a false address combination to drive the output from an unintended cell, thus to produce a possibly incorrect output.

The designer using fpgas expresses code as if it were sequences of standard logic gates being combined, the 'compiler' converts this to data for LUTs and links input signals to the address bits of the LUT. The designer does not see this, however, it takes conscious extra effort to unravel this to discover the LUT, addressing connections and data stored in the LUT. It is not something that is reported or directly available. One would need to be inspecting at the level of the bitstream loading the fpga and that is not well exposed by the vendor.

I had experiences as well where seemingly correct finite state machines (FSMs) would misbehave or get stuck in mystery state. Turns out these were also cases of glitches into the LUTs that encode the FSM and of the layout of the state variables that hold the current or next state of the FSM. I will document this more in another shorter post after this one.

The solution to all of these was to make the FSM transition decisions or the activation of gates, latches and flipflops occur only at fpga clock edges. For my Digilent board, it ticks once per 20 nanoseconds. I created an updated version of my edge triggered gates and of the pulse triggered flip flops. As long as I am careful to ensure that all combinatorial inputs are going to be stable before the clock tick, meaning that most must depend in part on signals that change only immediately after the clock tick, then I can avoid the glitch behavior of the fpga.

There are some complications - signals that in the previous version of the machine had to flow through several sequential gates that were edge triggered or had flip flops would now have multiple 20ns delays induced. Signals that might have arrived a bit after an fpga clock tick would still change the state of the pulse triggered flipflops or latches. Now, if a signal changes after a clock tick, it won't effect the latch or flipflop until the next clock tick.

Timing that worked, sloppily but worked, will now fail. In many places, the 1130 designers expected a signal to remain active a bit after an 1130 clock change, due to latency in the circuitry and their gates, thus would trigger a flipflop based on conditions X, Y and Z during cycle B. If condition Y is created only in cycle A, dropping at the start of cycle B, it would work okay in the 1130 due to latency but won't work in a clock sync fpga implementation.

The signal Y drops at the clock edge when the system is moving out of cycle A and into cycle B, right at the edge, and emits the signal indicating cycle B after the tick. The logic that matches signal Y and the signal representing cycle B will find they are like ships passing in the night, Y dropping before B shows up, thus in cycle B the condition Y is false. On an 1130, condition Y is still true for a few nanoseconds into cycle B, long enough to change a pulse triggered or edge triggered async gate.

I anticipate several dozen hours spent adjusting timing to ensure that a clock sync machine works as well as the async version worked, but of course with the added benefit of eliminating the sporadic glitchy annoyances. I will report on a few of the modifications I needed to make to accommodate the sync nature of my implementation.

FSM issues due to hidden race hazards with LUTs

I encountered infrequent sporadic failures of input buttons where the machine stopped responding to button presses. After thinking this through and looking at my FSM logic, I realized that my signal that chose the next state of the debouncer logic was susceptible to glitches.

My FSM picked the next signal based on a series of triggers - if the current state is X and event Y occurs, the new state should be Z. At the end , if none of the conditions matched, it would make the new state equal to the current state. Some of the conditions could change near the clock edge, particularly the external button input.

Knowing that the 'compiler' created LUTs to represent the current and next states, with some input conditions as the lookup address, I realized that I could very rarely have a glitch that generated a unintended address. The result was some output that became the new state. If that was not one of the explicit states I had defined, then no transition would exist from this invisible state to any of the known states. It would sit forever in the hidden state, ignoring all future button pushes.

The problem was not simply the rare invalid state, but the code that took whatever state the machined and continued it unless specific transition conditions were matched. This was what kept it locked up.

My FSM might have code like
                  nextstate <= state2     when currentstate = state1 and conditionA = '1' else
                                     state3     when currentstate = state2 and conditionB = '1' else

 I decided it prudent to remove the catchall of remaining in the current state, whatever value of the FSM state variable that might be, since the variable can reach values other than the ones I listed.

My replacement code looked more like this:
             nextstate <= state2    when currentstate = state1 and conditionA = '1' else
                                state1     when currentstate = state1   else
                                state3    when currentstate = state2 and conditionB = '1' else
                               state2     when currentstate = state2 else

Note that I explicitly set the continuation of a current state after covering all the transitions that can happen out of that state. Note that my final catchall is the most reasonable state to enter if the FSM gets into a weird condition. There is no way it can continue forever in some hidden state. If it reaches a hidden state, the next cycle puts it into state1 again.

That ended the problems with the debounced inputs. I planned to make the same type of change to my other FSMs as I updated and tested circuits, to remove the potential for unreliable states and lockups.

Modifications and tweaks needed to make the fpga 1130 a good clock sync implementation

The clocks in an 1130 are not used to gate flipflops or to control the timing of signal changes, but are referenced in logic to determine actions to take. I think of them more like imprecise, informal, gentleman's agreement states rather than concrete clocks. They are in a hierarchy of three levels of clock.

At the bottom is the 280 nanosecond oscillator cycle, approximately 3.57 Mhz. The real 1130 ran at 3.64MHz for the fastest models, corresponding to a 275 ns cycle, but with a 20 ns fpga clock the closest I could come is 280, thus I am running at 98.2% of an IBM 1130's speed. Oscillator drift in a real 1130 could be larger than this differential; Consequently, I am willing to consider this a direct match.

The oscillator turns on for 7 fpga cycles, a duration of 140 ns, and turns off for another 7 fpga cycles. The 1130 uses the oscillator to drive two signals, phase A and phase B, that alternate and are of the same 140 nanosecond length. They are not exactly aligned, but we can think of them for normal system operation as if Phase A is the on state of the oscillator and Phase B is the off state. When single-cycle stepping the 1130 from the operators console, pushing down on the Program Start key causes Phase A to be true as long as the key is pressed. When the key is released or not pushed, Phase B is true. Otherwise, while the processor is running, we see Phase A and Phase B alternating at the basic 1130 clock rate of 280 nanoseconds per cycle.

The next level up in the clock hierarchy covers the basic timing for core storage, which they call a memory cycle. The faster version of core storage on an 1130 has a cycle time of 2.2 microseconds, which is eight of the basic machine cycles. This is tracked with the T-clock states, with one memory cycle involving sequentially states T0, T1, T2, T3, T4, T5, T6 and ending on T7. Each of the T-clock states spans a Phase A - Phase B pair of low level clock states.

Core storage is read by flipping all bits of the memory word off, detecting whether the bit was previously on or not by the pulse that is created or not by the act of turning off all bits. It takes about 1.1 microseconds to first stabilize the X and Y lines that intersect at the chosen memory word and flip the cores to zero orientation. Memory is a stack of these X-Y planes, one stack for each of the 16 bits in a word, plus two stacks for parity bits. Each stack has a sensing line that will detect the pulse if a core flips from on to off, or that sees no pulse if that core was already off when we began the read.

Since reading is a destructive process, yet we usually want the value in the memory word to remain, the second half of the memory cycle involves setting the appropriate bits of the word back to a one state. For another 1.1 microseconds, the X and Y lines are stabilized and then the memory flips the cores in the opposite direction, to the orientation that represents a 1. Any bits of that word that had been zero when we read the location are left as zero by driving a counter-signal that cancels out the write pulse. The counter-signal is to the planes that did not detect a pulse during the read, keeping them from flipping on, while the other planes that have no counter-signal will have the core flipping to its on state.

The memory begins addressing the X and Y location as T0 starts, with some timers controlling the pulses that flip the word off. This happens sometime around T2 of the memory cycle, but not in any precise synchronization. As the sense amplifiers detect pulses, the send a signal that flips thecorresponding bit of the 1130's B register on, the whole register having been reset to zeroes at the start of T0.

The values of the B register are the determinant of the counter-signals for the rewriting phase of memory. Any bit that is off in the B register will have a counter signal applied to its assigned core plane, while the bits that are on in the B register are allowed to flip on as core is rewritten. The rewriting of core starts at T4, using the same address as was set up at T0 for the reading. If the B register has not been modified by the processor, it still contains the data pattern that was read in the earlier part of the memory cycle, which is rewritten, completing around T6 more or less. Thus, by the end of a memory cycle, normally the content of a word is the same value as had been there prior to the cycle. However, if the processor changes the B register before T4, that new value is what is rewritten to the memory word, ignoring its previous value we read in T0-T2.

The topmost level of the clock hierarchy represents the stages of executing an instruction. Not every instruction goes through all the stages; most only use a few and many complete in just the first stage. These stages represent memory cycles, because each of the stages begins with a complete T-clock sequence from T0 to T7. Some of the stages may need to last longer than the 2.2 microsecond memory cycle, which is supported by extending or repeating the stage T7 as long as necessary.

Adding or subtracting takes a variable amount of time on the 1130, depending on the exact values of the two numbers involved. Carries from a bit position are saved in the 1130 D register, then those carry bits are themselves added (or subtracted) to the partial sum in the A register until we have no more carries. An example  is adding 32767 and 1. Those two values are 0111 1111 1111 1111 and 0000 0000 0000 0001, so that the first T cycle of adding produces a partial sum of 0111 1111 1111 1110 in A and the value 0000 0000 0000 0010 in D to track the carry that happened in the low order position.

The second T cycle will add the partial sum and carries to produce a new partial sum of 0111 1111 1111 1100 and a new carry value of 0000 0000 0000 0100 in D. The third cycle produces 0111 1111 1111 1000 and a carry of 0000 0000 0000 1000. You can see how the carries are rippling left to right a cycle at a time, so that the penultimate cycle has a partial sum of 0000 0000 0000 0000 and a carry value in D of 1000 0000 0000 0000. The final addition gives us an A register with 1000 0000 0000 0000 and a zeroed out D register indicating our addition is complete. With addition starting in T4 of a cycle, typically, there would be T5, T6 and then many T7 cycles until the D register gets to all zeroes.

Thus, the clock from one high level instruction stage to another is triggered by signal pulses not by a fixed relationship to the T clock steps. When the instruction stage is complete, we let the T clock advance from T7 to the T0 state, beginning the next memory cycle. A T0 pulse is produced that moves the instruction clock to its next stage, determined by some logical conditions and the just ended stage.

The stages of an instruction always begin with an I1 stage and can contain I2, IX, IA, E1, E2 and E3 stages depending on the particular instruction being executed. Instructions can be one or two words long, indicated by the F flag in bit 5 of the first word. If F is on and we are moving out of I1 stage, then an I2 stage is triggered. If bit 5 is off at the end of I1, I2 is skipped and we determine which of the later stages we move into.

Index registers (there are three in the 1130) are just memory locations 1, 2 and 3, thus we need a memory cycle if we have to read and use the value of an index register. This is indicated by the two T flags in bits 6 and 7 of the first instruction word. If T is nonzero, and we are moving from I1 or I2, we move into an IX cycle to read the index register.

Each of these I type stages are building up the effective address for the instruction, using the value of the second word of memory from an I2 cycle, the value in the index register from an IX cycle, the remaining bits of the first instruction word for a single word instruction, and may involve yet another memory reference if we have requested indirect addressing by setting on bit 8 of the first instruction word. Bit 8 is the indirect addressing flag and once we are moving out of the last earlier I cycle (I1, I2 or IX depending on whether the instruction has nonzero F and/or T) and we have bit 8 on, we then move to an IA cycle. That memory cycle takes the effective address we have created so far and reads the memory word at that address, the resulting contents of memory become the new and final effective address.

For each of these I stages, if the addition being done to update the effective address requires more than one T7 cycle to complete, we take those additional T7 until the D register becomes zero.

Some instructions can complete entirely in the I stages, the T0 SP that is produced at the start of a new memory cycle is the End Op type which means that the previous instruction was completed. That makes this new memory cycle become an I1 instruction stage. If on the other hand, there are more I cycles to processor for indexes, indirect addresses, etc or the instruction also requires some memory accesses for execution, the T0 SP is the Not End Op type. that advances us to another of the instruction stages rather than resetting us back to I1.

The basic clock circuitry of the 1130 produces a T clock advance pulse when beginning the next Phase A as long as the processor is not stopped or in some kind of single cycle mode. The advance plus flips the T clock registers to the next T clock state, e.g. all but T3 might be off, then with the pulse we turn off T3 and turn on T4. I wanted the phase A, phase B and T clock signals aligned to the same fpga clock cycles.

The 1130 design has an edge triggered gate that detects the rise of phase A and emits a quick pulse that will cause the pulse triggered flipflops of the T clock to advance. This is only allowed if all the right conditions exist for moving to a new T clock step. If we are adding and still have carry values in D, then the arithmetic control signal is still on. This blocks the clock advance so that we stay in T7. Similarly, shift operations might need more cycles since shifting moves the register one bit over per cycle. If the number of positions we want to shift is big enough, we needed extended T7 cycles so shift control signal is another factor that will block the advance from T7 to T0.

There are other complexities, but the core problem to consider is that if we use an edge triggered gate to see that phase A started, the output of that gate is 20ns after the start of phaseA. That delayed signal is the trigger for the T clock flipflops, which are now synchronous so they don't change state for another 20 ns. That puts the T clock signals 40 ns or about 2/7 of the way past the start/stop of Phase A and B signals.

To resolve this, I created a new signal that anticipates the oscillator switching from phase B to phase A by one fpga cycle. Because of the way that I toggle phase A and B on and off, I am generating a 20 ns pulse to make the phase change on the next cycle. This early signal is therefore 20ns early and used instead of the actual phase A or B. I mirror all the logic that decides whether to emit a T clock advance plus but based on the early pulse instead of the real phase A signal.

Now, since that early signal is already a pulse, I didn't need to use an edge triggered gate. To preserve the mapping of my logic to the 1130 ALDs, I left the code calling the edge triggered gate component but added a new parameter to that component called pass thu. With the passthru parameter, the gate doesn't delay or do clock syncing, just implements pure combinatorial logic. This provides the clock advancing pulse just ahead of the start of Phase A as the trigger to the T clock flipflops. Voila, they now switch coincident with the basic clock starting Phase A.

There were a few related signals, such as a pulse that was intended to fire at the start of Phase A which I generate at the correct time thru judicious use of early and on-time pulse signals and passthru mode.

The next set of issues to address were pulses that are produced by the 1130 when certain signals shut off, such as the end of T3, but they are gated by a signal from T3 that wont appear until the start of T4, or correspondingly some signal that is triggered by the start of a cycle but is gated by a signal from the prior cycle which is being shut off. The exact timing of the decision, either just before or just after the clock change, makes the difference between successful operation and failure.

In some cases, I had to convert logic to mix the prior clock state and some condition, firing off the result pulse at the start of the next cycle. Where IBM may have used the start of T2 cycle to accomplish something, I may need to gate T1 with the clock advance pulse that happens just before the move to the next clock state. That would give me a pulse just as we are moving from T1 into T2. If that set of logic fires off my usual edge triggered gate, whose output is delayed one fpga cycle, I get a pulse right at the beginning of T2 just as would occur on the original 1130.

A few registers get reset signals that are generated while the storage select signal is active. On the physical 1130, that signal exists from T0 thru the end of T1, but my clock sync version was beginnign it later in T0 due to the delay of extra fpga cycles and was extending it well into T2. Since that kept some registers in reset mode until after they were being set by other pulses, I had to accelerate the start of the reset signal and shorten its duration to end promptly with T1's end.

I need to look at every place where an SP pulse (sample pulse, the activation of some action) is emitted and determine what timing constraint may pertain to it. then, I have to look at how it is being generated, adjust if it was dependent on latency of signal values beyond their legitimate end on fpga, and test.

Another area to which I had to adjust timing was with the combinatorial latches used in the 1130. When a combinatorial loop was used for a latch that was set by one async signal and reset by another, I wished to convert this to clock synchronous behavior. I chose to do that by creating a 'latchgate' component that takes the then current signal value at a clock edge and sustains the emission of that signal value until the next clock edge. Thus, any signal change that flows through this component is quantized in time to only change states at clock edges.

Any glitchy behavior settles out before the next clock tick when a signal is passed through my gate. If a false set pulse arrives for a short interval, it has not yet made it through my gate to the rest of the latch circuits. When that glitch disappears and the set signal is back to its off state, when the next clock tick occurs it has erased the instantaneous false triggering. The latch will only fire if the set signal persists long enough to make it through the next clock edge.

I had assumed that the contemporaneous designs by IBM used similar approaches to how they designed the 1130, as they were built from the same new logic technology and tools, but that does not seem to be true. At least two of the 360 series, the model 20 and model 30, take a very different tack fundamentally.

Lawrence Wilkinson, who has a parallel project to this one but recreating a 360/30 machine, identifies the basic approach for that machine using almost all gates and flipflops as level sensitive devices. Pulses are not used to trigger changes of state or other actions. Flipflops are changed while a clock phase is active - with the clock divided into four phases - then held steady for the other phases. This holds the output steady while it is mixed in combinatorial logic and allowed to settle before the next stage of logic relies on the value, since it won't look at the inputs until its clock phase is on.

That 360/30 logic behavior is substantially clock synchronous, free of the 'flip now' change of gates in the 1130. The 1130 is riddled with pulses freefloating between clock ticks,that sequence events within one clock cycle and basic clock phase. Although the 1130 has two clock phases, A and B, multiple steps take place inside one phase.

My scans of the 360/20 ALDs show very few edge triggered gates and almost no single shot pulse generators. It does not use the 1130 style design approach and seems more like the 360/30 approach described by Lawrence. I haven't looked at other models yet, so it is possible that some use the same pulse and edge trigger fundamentals as the 1130, or at least use it in portions.

I could imagine that the 360/30 approach may be part of the design strategy for microcode driven machines, which is a key difference between 1130 and the 360 line. If behavior is defined (and updated) by microcode rather than fixed hardware timing circuits, it may not make sense to try to control timing of pulses and async behavior.

On the other hand, use of async actions allows more decisions and actions to take place in a clock phase, thus for a given clock speed it may be possible to increase the work done over the level sensitive, clock phase controlled approach of the 360/30. This may be used in high end machines where performance objectives were more readily achieved by applying the async approach of 1130. This is all speculation right now, but if I get some spare time I may research anything I can find on the high end models to see whether this does occur.