Saturday, May 30, 2015

Spring 999, me 0


Fighting with the far end of a spring is not the most relaxing way to spend a Saturday morning, but it was necessary.  No success as of lunch time but lots of sweat expended. The spring is made from stiff wire, which keeps the hook ends tightly circled and in place.

If there were no obstructions, the spring would be held at about a 75 degree angle to the interposer, the opening in the spring hook end slid over the interposer and then the spring swung to 0 degrees to force the end of the hook through the hole in the interposer.

However, the maximum angle for the spring end, given the constrained environment, is about 10 degrees, far too little to allow the usual method of attachment. I have just about enough room for the spring to enter the space within which is the interposer and its hole.

With strong lights and just the right orientation, I can barely make out the hole in the interposer into which the spring will fit, but am finding it almost impossible to manipulate the spring enough to matter.

I posted a request for ideas from the golfballtypewriters group which includes quite a few service people who worked on these machines. Perhaps there is a trick or an access direction that isn't apparent to me.

This is probably a task that will burn many hours until somehow it clicks into place and I begin putting it all back together.

Friday, May 29, 2015

Tab problem identified, replacing part, and carrier return issue tentatively corrected on the 1053 console printer


The only way to find what was wrong with the tab interposer operation was to get access. I had to remove the mainspring and other parts yesterday, but that had to continue to take off the entire return/escapement pulley assembly with its large plate that sat in the way of everything.

Improved access. The green oval indicates the CR and index latches, the red oval is for space, bs and tab. 
Looking closely, it was apparent that the return spring which pulls the tab interposer backwards when it is released was damaged. It was bent and not exerting the proper pull needed. I will have to find a replacement spring in my supplies (which are pretty large based on having bought quite a few "selectric parts" lots on eBay). Replacing the spring is going to be an interesting challenge, as is reassembly of the parts I removed today. It is akin to laparoscopic surgery, trying to work through a teeny hole with limited visibility and awkward tool mechanics.

Bent spring for tab interposer is visible in the center

I was able to extract the old spring and work out where the substitute will connect. It will be challenging but possible. I began looking through my 17 plastic parts bins and several large boxes of typewriter parts, but a first look didn't turn up the right spring. I need something with about 18 tight turns, good tension and perhaps 5/8" or 3/4" loose length.

I found a suitable spring and invested an hour trying to hook the far end into the interposer eyehole deep inside the mass of levers, brackets and springs. It will be relatively easy to hook the near end, but it is contingent of first attaching the far end.

I did more work on the carrier return mechanism and now have it springing back to full rest position when it is released. Tentatively, the problems are corrected, although to be sure I have two tests to perform - CRs from the Return button while under power, and CRs initiated by a program. In the same way, I will need to verify tab, space, index and backspace by program control and the Tab and Space buttons as well.

I tried for another thirty minutes as night arrived, but still haven't hooked the far end of the spring on the tab interposer.

Thursday, May 28, 2015

More time dedicated to the typewriter space, tab and carrier return functioning

Yesterday was such a full day that I didn't get to the 1130 system at all. I was able to help repair a power problem on one of the 1401 systems at the Computer History Museum, during my weekly midday visit, the rest of the day was absorbed by my day job and spent the evening helping my wife, who had a dental crisis with an infected tooth, one that had an old root canal but had cracked internally and abcessed.


I did some partial dis-assembly to work on the sticky carrier return restore, the blocked space button and the failure of the tab button to reliably trigger the space/backspace/tab cam cycle. I had to remove a brace, the motor starter capacitor, unhook the main spring, and loosen the tab/rewind pullies.

With the improved accessibility and visibility, I cleared up the escapement issue that blocked the space button from advancing the carrier. It took quite a bit more to fix up the carrier return issue. I unhooked a few parts of the intermediate lever, latch and restore parts to isolate where the binding is occurring.

My work for the day improved the restore operation substantially, but not completely yet. If it was restoring about 30% before today, it is now restoring to 80% and moving much more crisply. I still need it to get to 100% promptly.

I turned my attention to the tab mechanism. The interposer isn't snapping back far enough to trip the space/backspace/tab cam cycle, although the space and backspace interposers work reliably. Something was different about this one interposer.

One difference is that the interposer has to turn on a microswitch during its trigger, which is switched back off by the end of the cycle as the clutch operates. This would add a bit more resistance, but the design should have sufficient spring tension on the interposer to handle this.

Tuesday, May 26, 2015

More work on console printer (1053)


I worked on the typewriter mechanism most of the day. There are a few anomalies on the triggered actions for tab, space, index and carrier return.

The space button triggers a cycle of the space/backspace/tab operational cam, but it wasn't moving the escapement bar to allow the carrier to move forward one space. Something is not connected properly or is jammed.

The release of the carrier return latch lets the latch begin to restore but it doesn't pop back far enough. Same issue as yesterday.

The tab button will set the latch on the carrier but often the interposer doesn't trigger the tab/space/backspace operational cam so it doesn't complete. If i fire it via the space button, it then accomplishes the tab movement to the next tabset.

The index interposer will not restore all the way sporadically, so that the typewriter occasionally continually repeats indexing until it is interrupted. Most times it restores properly.

I didn't want to keep the 1130 system powered on just to work on the typewriter. I wired up the motor to a temporary power cord that I could plug in separately. This lets me work on the console printer independent of the main 1131 power.

Monday, May 25, 2015

Working on 1053 console printer, attempt to rescue fpga board, and checkout of a Tek 7854 scope


When I reattached the clevis ends to the operational mechanisms, the space was extremely limited. I have attached two photos where you can see the black ends, unconnected, and the limited space to reach them. I was able to get them all attached yesterday. but didn't upload the photos until today. Although I call these clevis ends, there may be a more official name as they are slightly different from the canonical clevis fasteners or pins.

Unconnected clevis joints visible in rectangle in center of picture

Actuator arms with holes where the clevis joint will attach

The flaw I still have in carrier return operation is that when the carrier reaches the left margin and the mechanism releases the clutch latch by pulling the release lever, the clutch latch should be moving back up to idle position promptly and completely; instead, it is oozing up partway.

Latch and release on left, but both rods and all circled parts are moving too little, too slow
I haven't yet found the spring that should be helping the clutch arm snap back into rest position. I have examined the parts catalog diagrams, the theory of operations pictures, the maintenance manual diagrams, and visually inspected the actual machine, all to no avail.

I checked on the escapement and tab operations, which led me to rewind the main spring to improve the quality of the escapement (spacing) and tabbing across the entire span of the carriage. I still have the inadequate unlatching of the carrier return latch to debug, plus sporadically the machine goes into repeated index operations until I fiddle with the interposer lever to get it to re-latch.

This warrants checking for a missing spring on the latch and restore functions of the index and carrier return mechanisms. Another anomaly is in erratic (or actually partial) tripping of the tab function. Sometimes, I push the tab button and it doesn't move or actuate, but if I push the space button it completes the tab operation.

All of these seem to be issues in the interposer trip and reset (or clutch trip and reset). It may be residual sludge from forty years of decaying lubricants, or something else, but that will take a bit more diagnosis.

Watching the tab interposer motion from several angles, it is clear that the backwards pressure on the interposer is not strong enough to activate the space/tab/backspace cam on the operational shaft. The spring is not as stretched as the others and is slanting in a different angle than the others. Could be attached to the wrong place. The spot where it attaches is behind the mainspring and blocked by many other levers and plates, but I will find a way to get to it.

Spring that should pull interposer back but isn't strong enough
My biggest concern remains the restoration of the carrier return latch once it is released. There is either way too much drag somewhere or a spring missing or broken. It should be popping up to its stop position instead of moving half-heartedly up to about 40% of its travel, never fully restoring. If I can get this sorted out, along with the tab issue above, the printer should be ready to cover up and put into place. It will take a bit more time.


I made up a JTAG interface cable for the ztex fpga board, since that is a third way I can load the bitstream on the board. While I might whip up a board to automate the loading at powerup using JTAG, my intention is simply to continue testing the SAC box while I wait for the replacement fpga board to arrive. I have been manually loading the fpga on each powerup anyway, after the failure of the onboard flash chip a couple of months ago, so this won't be much different.

I have an Altera USB to JTAG cord (USB Blaster) which I used to attempt the bitstream load via JTAG, but I couldn't find software to use the cord and recognize the .bit format file built by the Xilinx toolchain. The USB Blaster was found but it asserts that the JTAG chain is not working. I think I have the lines correctly assigned but it isn't worth a huge amount of debugging and testing time today.


I recently acquired a Tek 7854, which is a hybrid machine. It is a four compartment 7000 series 400Mhz analog scope, plus a digitizing processor that can capture waveforms and do quite a bit of processing and measurement on them. It is programmable through its attached keyboard. It has a few problems, which is why I got it free, but they seem to be due to a sync failure between the analog and digital driving of the CRT.

Tek 7854 (not mine but same type, different plug-ins)
Normally, when you have 'readout' on to show plug-in settings on top of an analog signal, the scope alternates painting the CRT with a trace and digitally rendering the pixels of the readout characters. Stored waveforms are displayed in the pure digital pixel mode. A master control either authorizes the analog circuits to drive the CRT plates or the digital circuits to drive them (but alternating so fast the eye doesn't notice).

The symptoms are dashes or interruptions in the traces of analog signals, plus bending/distortion of the characters from the readout function. However, when I click the 'readout' intensity to its 'off' position, the dashed interruptions go away and I have clean traces from the analog scope function. If I set up the analog scope to be silent (e.g. no trace triggered), the readout characters look fine. When I display a stored waveform including readout characters, everything looks fine.

The only problems occur when both are attempting to use the CRT - thus I believe one of the sync signals is bad or the alternation logic is malfunctioning. It shouldn't be hard to debug and fix this. The calibration circuit was put through the four plug-ins installed in the machine. The '2' amplifier of the left plug-in doesn't work, but the '1' amp does and both amps of the right plug-in are fine. Both timebases work well. The vertical mode buttons should light when activated, but the "Left" button does not. It selects properly and lets me view the left plugin but the lamp itself is out.

Keyboard for use with 7854 scope
The attached keyboard is slightly stiff from time but works well. I tried differentiating and integrated a stored waveform, plus conducted various measurements successfully. I feel quite good about the condition of the scope, which definitely replaces my lower bandwidth 7000 series scopes. The machine was $17,000 when new in 1990 (add more for the the keyboard and plug-ins). 

Sunday, May 24, 2015

Reassembled 1052 console, working on carrier return issue, while fpga board in interface box is still fubar


This morning I found the pivot screw and invested a half hour trying to get the nut and lockwasher in place to be threaded into by the pivot screw. I have some masking tape holding the lockwasher in front of the nut, with the hole opened up for the pivot screw thread.

Putting the nut/washer assembly on my smaller forceps, I tried to hold it in position to start the thread from the pivot screw, but several projections on the bracket and nearby mechanisms block me from having a direct vertical approach with the forceps. Attempts to compensate by cocking the nut in the forceps teeth didn't work.

I then hit upon the idea of using some soldering tools I had which were spring clips that could hold the nut and lockwasher at their edge, leaving the hole free. With a bit of effort, I was able to get the pivot screw to mesh and tighten. It was easy to finish up, putting back the springs and the shift magnet assembly to finish up this task.

Now, I have to check and adjust the varous mechanisms to get this to tab, space, backspace, return, index and of course type properly. First up, I had to unlock the various latches that were set while I worked on the typewriter. The original problem that caused me to remove the magnet assembly was failure of the carrier return mechanism to unlatch - which I suspected was due to a missing spring being somehow wedged inside interfering with the CR release.

One big zone of impaired visibility was between the magnet assembly and the operational clutches, but I have just eliminated that by the dis-assembly and re-installation I finished today. I now have to look in a number of nooks and crannies that are covered by many other arms, pivots, levers, gears, rods, springs etc.


Using the USB microscope, I could position the wire well enough to tack it down with solder. I had a bit too much solder, creating a bridge between leads 70 and 71 of the USB chip, but I was able to use some wire braid to wick up the excess solder. It appeared that the wire was attached to the proper pin with no shorts to adjacent pins.

I attempted to load the fpga bitstream, an operation that worked before the damage I had caused but alas it still failed with an error that the 'Done' line didn't go high. I suspect this means the lines I have connected to the USB chip are broken on their way to the Xilinx Spartan 6 chip. Since these pins are balls hidden underneath the chip (a BGA surface mount type), I won't be able to access them to tack on a wire.

The flash is not visible to the USB chip, meaning I have more damage than I thought. I am down to one route to possibly load the fpga, otherwise the board is pure junk. I have the JTAG pins accessible on the external connectors, which might allow me to load it from the bit file with an external circuit I build on another board.

I did pick up a inexpensive fpga board, based on the Altera Cyclone II, which seems to have enough IO pins to use as a slave board. It does not have a USB link on it thus it can't be a substitute for my ztex board. At less than $30, it is a good option for supporting major peripherals such as disk or tape drives, linking them to the SAC Interface Box.

Saturday, May 23, 2015

Began reassembly of 1052 console printer mechanism, plus failed attempts to tack the jumper wire on the fpga board chip lead


I began reassembling the operational selection magnet assembly, which I know has some very very difficult reassembly steps due to almost nonexistent service clearances. However, I am currently stuck on what should be a simple task.

One screw has to hold down a bracket on the side, but the straight line path that a screwdriver would take is blocked by two screwheads jutting out from another assembly. They are too close to find a very short screwdriver, perhaps 1.5" from the screw I have to turn, but close enough to make any screwdriver have to fit at an angle.

That makes rotating it to start into the hole threads a very difficult problem. It is inside where I can just about hold the screw with two finger tips, or with a forceps, but can't rotate it without putting sideways torque and skewing it so it won't enter the threads.

I spent an hour in a near infinite cycle of positioning, turning, skewing and eventually dropping the screw. Finding and picking it up begins the next cycle. This isn't the 'hard' part of the reassembly. which involves attaching five clevis hooks onto rotary arms up inside the inaccessible bowels of the mechanism. These clevis fit onto the actuator rods of the five magnets in the assembly I am installing.

To install a clevis, which can rotate around the rod on which it is fastened, you need to pry one of the two arms away from the other. One arm has a cylindrical pin that fits inside a hole in the actuator arm up inside the machine. The other arm holds the pin inside the hole; it has to be pried apart to allow the pin to slide over the actuator arm edge and find its hold in the center.

Thus, one hand to hold the arm with the pin. One hand to hold the other arm and pry it apart. One hand to stop the clevis from rotating, twisting the arms away from alignment. One hand to hold the clevis over the actuator arm and push it down to get the pin into the hole. That is four hands in a space that is deep inside a mechanism with perhaps 3/16" clearance on the sides, too small for even a small finger to enter.

I had no need to worry about connecting those clevis rods, since I had yet to get the screw into its hole which is one step earlier in the sequence. Fortunately (?), I was finally able to get the screw started and begin connecting clevis rods. The first two were rather easily snapped onto the arms.

After a break, I went back to work on the remaining three clevis connections. Within an hour I had them all attached properly. I have a few more parts to install and then a couple of adjustments that must be made. A pivot arm trips a microswitch to indicate the period during which the 'long' actions are in motion - those are tab movement and carrier return, which take a variable length of time depending up on how far the carrier must move to reach its target, either a set tab or the left margin.

The pivot screw is held by a lockwasher and nut that are inserted inside a bracket where fingers can't reach. I have to figure out a way to hold the nut and lockwasher in position so that I can place the pivot arm on the other side of a bracket and then thread the pivot screw in place. It will be tedious but not otherwise complicated.

The magnet assembly I just attached is adjusted to put the armatures just below the actuating arms they serve and to ensure that the armature end of the clevis rod is a bit forward compared to the actuating arm end. Not particularly finicky adjustments, easy to spot and then I tighten three mounting screws and one mounting nut.

With the assembly adjusted, a spring is attached from one of the mounting screws to the pivot arm. I can check the pivot arms and microswitches to be sure they are closing appropriately when the mechanism is actuated and opening when it relatches.

Microswitches for the shift mechanism then have to be remounted. I needed the bracket they are on swung out of the way while I worked on the magnet assembly. They may need adjustment too.

I closed up the shop before installing the pivot arm and screw, after the pivot screw fell somewhere I couldn't readily find. At least I had a method for holding the washer and nut in place . . . if I only had the screw at the same time.


Gave another try with all the magnifying and lighting tools I have, but I just can't see well enough to position the wire, know it is touching the right lead, and then to apply the solder to tack it down. Based on a suggestion from a blog reader, I bought a USB microscope, to try to lower the cost of the tools I will need to buy. It will arrive late tonight.

The microscope has limits on its field of view and focus distance, but otherwise should give me an accurate enough image. I may not be able to work while the microscope is in position, due to tight spacing under the unit, but if I can position the wire in place and hold it there with decent accuracy, then I can solder with the lesser magnification of my other tools (I think).

Tonight, when the microscope arrived, it was too dark and late to work on the board but I could experiment with the microscope itself. It seems to work great - should be just what I need, even with the shroud in place. Tomorrow I will put it over the board and determine how helpful it might be. There is a chance I will have to remove the plastic shroud that protects the LED light ring and camera lens. 

Friday, May 22, 2015

One small step away from fixing the FPGA board and resuming testing of the SAC Interface


I contacted the fpga board vendor to see if I can modify the order before shipment to switch to express delivery, 2-4 business days. Fingers crossed on this one, as it would get me back in testing mode much sooner.

I next set up my lighted magnifying lens and looked more closely at the board, in conjunction with the schematics and the fpga pin assignments, in order to see what possibilities might exist for repairing the damage.

I found that the signals going to the flash chip are accessible on leads around the outside of the USB module nearby on the board. I first did some verification of the connectivity and correctness of my information. With that verified, I could solder the flash chip to the 7 remaining pads. The final step was to solder on a bridge or jumper wire between pin 2 of my flash chip and the appropriate pin on the USB module.

Tacking the 30 ga wire wrap lead to the pad of the flash chip was easy. The tough part is getting the wire soldered onto the lead of the USB chip. The leads are .012" wide with just .014" gap between them. The copper wire is .01" diameter which is an appropriate width but alignment has to be pretty accurate. If I am off more than one hundredth of an inch, I will be touching an adjacent lead.

This evening I received, not a response to the emails I sent about changing the shipping, but an automated confirmation that the board has shipped the old, slow way so that I won't have it until near the end of June. Disappointing and it makes the need to fix the existing board all the more urgent if I am not to incur a long enforced holiday from the testing.

I tried quite a few ways, but the real limitation is my eyesight. None of the magnifying lenses and lights I have allow me to see a 1/100' inch copper wire on top of a green coated PCB, at least not well enough to be sure of the contact, angle and to allow me to touch solder a .01 x .01 spot. I can use various clamps and jigs to hold the board and the wire, but if I am not sure that it is in contact with the lead properly and not able to see where my soldering tip is placed, I am not going to be able to get the wire tacked down.

This may require an investment in a stereo microscope to allow me to proceed. Tomorrow I will give it another try with the best magnification gear I can set up, before I have to go buy a microscope.

Thursday, May 21, 2015

In the last inches before the completion line, defeat was snatched from the jaws of victory, with a big snag

I helped my daughter and son-in-law move to their new apartment this weekend and up thru Wednesday, which ate up all the time I would have spend with the 1130. My daughter was driving over to her new place to meet the cable modem installer when her tire blew out.

After AAA mounted her spare, we took the car to replace the tire during the time we were moving boxes into her apartment. Tuesday, my wife and I picked up the car and drove over to swap it for the one we loaned my daughter, when five minutes away from our destination we had another tire self-destruct! As you will read further down in this blog entry, it is a week of unforeseen failures.


I made a few changes to the core store/fetch logic and began testing, hoping to quash that last annoying hiccup. The logic analyzer shows the main link FSM jumping backwards for one cycle to a state it had already vacated, but there is no path in my VHDL to make that movement.

I asked the tool to use one-hot encoding to ensure against glitches, which should block such undesired movements, but this could be an instrumentation error rather than a real logic error. The analyzer I am using is an open source unit based on an old fpga board, which adds a third possible source of contaminated data.

Once I found the conditions that led to the glitching of states, I worked on the basic transactional flow until I felt it was solid. At that point, I began testing the core load and virtual 2501 driver functionality to see whether it now passed muster, free of small anomalies or glitches that could cause sporadic failures.

Everything was looking good, although I found one of my data lines going into the 1131 was not working properly. I think I located and fixed the loose connection on the driver board. Before doing more testing, I decided to replace the serial flash chip that was not working on the fpga board.

I dealt with the serial flash chip problem on the fpga board, by removing the presumably bad chip in order to solder a replacement into place. Alas, catastrophe struck.  I damaged one of the pads during removal, even though I thought I was careful enough.

I examined the board to find a way to solder in a way that would create an electrical contact for the damaged pin (pin 2), but that does not seem feasible. It is possible that my only recourses are 1) a replacement board or 2) an external JTAG oriented board with a flash chip to hold the power-up file.

I have just ordered a replacement fgpa board, which should come in three weeks; meanwhile I could continue to load the fpga after powerup manually, as I have been. However, to underscore the major setback I suffered, when I tried to load the fpga directly as I had, the firmware no longer does the load. The 'done' line is damaged somehow, probably it was part of the trace to the damaged pad.

At this time, I can't load the fpga so I can't test anything until my replacement board arrives three weeks from now. I may find a way to restore the fpga loading function, or even to repair the board pad, but at present I am blocked from any futher work on the SAC Interface.

Saturday, May 16, 2015

SAC Interface Box virtual 2501 card reader passes all tests, still chasing a minor problem


My last few cleanups look very good - initial tests all are free of any glitches or potential problem areas. I decided to run several more extensive tests just to ensure it all works right.  The issues so far haven't required use of the logic analyzer, they can be spotted and corrected simply from symptoms, behaviors, and indicator lights.

The virtual card reader, last card and hopper empty function is now working exactly as intended, plus of course reading of cards into core. It was very important that I get the interaction between PC side program and fpga just right, something I feel good about. I can set up a program loop on the 1130 to read cards and then clear the condition in an interrupt routine, to which I would submit files that were decks of many cards.

It ran through the cards at about the speed of a 2501 reader, stopping when the virtual hopper went empty, then restarting when I opened the next file, the equivalent of loading the next block of cards into the hopper. My checkbox for 'last card' allowed the final card in the file to be read and the DSW properly recorded the last card bit for that case.

Loading simulator core files into memory is working okay but not signed off yet. I added a feature that makes a verification of the contents after loading them to memory to ensure the data is correct. The core load operation is almost right - close, very close.

However, I see sporadic issues with cycle steal writes, both in delivering card columns and in loading core, which I have to clean up before I can declare the job done. I think it might be timing, but this might take the logic analyzer and perhaps an oscilloscope on the 1131 to really see what is happening.

When I get the SAC Interface Box to my satisfaction, the next work is to build out the SPI links to the slave fpga and microcontroller boards that support all the input and output signals to the physical peripherals - for example paper tape, plotter, disk drives, 9 track tape drives, and an APL terminal.

Friday, May 15, 2015

Stamping out bugs one by one


Getting rid of the last few anomalies is like trying to exterminate roaches - a protracted battle against very resilient and persistent vermin. I spent a few hours working on various tests and stress conditions. It keeps getting better but I still see hints of logic that doesn't satisfy me.

Way too tedious a level of testing, instrumenting, diagnosing and refining to describe in detail, so the blog entries will be a bit sparse until I am done.

Thursday, May 14, 2015

Very good progress on the QA of the SAC Interface Box core functions


When I pushed high volumes of data to store in core memory, sporadically it would get out of sync and the data would not be in the proper address. I finally traced it down to the behavior of the USB module interface, which could sometimes give me two words in sequential cycles and other times have a delay between the words, but mostly the delays occurred.

Since the two consecutive words were rare, I hadn't found them in any logic analyzer recordings. This meant I didn't know how it would behave, the documentation mainly consisted of a couple of sample fpga demonstrations which were designed around high speed streaming. My logic didn't handle the consecutive case properly, but now it does.

I loaded the disk initialization utility program into core and ran it to the point that it was looping trying to access the disk drive, which I kept powered down. The focus turned to the device adapter functionality.

I changed the instrumentation of the fpga to examine behavior surrounding virtual device status, XIO instruction execution and UCW status. With these done, I ran some testing and spotted a flaw in how I converted one of the FSMs during my revamp a couple of days ago. After some more cleanup, it is ready for more testing however it is also well after dark and time to quit for the night.

It shouldn't be long now until it is all working to my expectations and I can finalize the virtual card reader verification. From a development standpoint, I can finish up the data pump over high speed SPI to the slave fpga board, so that I can hook up the paper tape and plotter peripherals for their checkout. Ultimately, these will instead be handled by the medium speed SPI link to Arduinos and other controller devices, but I haven't built that link up to the point where it can be used yet. Good pr

Wednesday, May 13, 2015

Logic cleanup and micro-testing of the SAC Interface Box functionality


My reset signal was generated by the USB mechanism and process, thus it was emitted synchronously to the clock edge. By using that for async resets of my other FSMs, I wasn't meeting the setup requirements. Switching to synchronous reset flipflops ensured that the FSM came out of reset on the next clock edge after the reset signal went down.

Testing continued after I returned from my regular Wednesday midday time at Computer History Museum meeting with the other 1401 restoration team members. Many of the small issues on my 'punch list', to borrow a term from home construction, are resolved. However, there is still a weakness in the interaction when I am pumping a large core file down to store into the 1131 memory, where the FSMs sometimes get out of sync.

I am going to noodle on this a bit, set up some more precise instrumentation for the logic analyzer, but also consider restructuring the logic to merge some FSMs as a way of ensuring tighter coordination. The downside to combining FSMs is they get complex and less easy to understand, compared to modularizing the requirements into many simple FSMs.

The simple FSM is easier to debug and make solid, but then interactions among the machines becomes more complicated. A single large FSM has no difficulty keeping everything in sync but becomes so unwieldy that achieving correct operation gets much harder. A design tradeoff.

I have to be 101% convinced that the SAC Interface Box is glitch free and working perfectly, since so many peripherals and functions will be layered atop it. It may seem obsessive to spend so much time and fuss over esthetics of the logic and its behavior, but that is how I am going proceed.

Tuesday, May 12, 2015

Very little time to work on the 1130 until today

The holiday weekend (Mothers Day in the US) took up almost all my time, plus I had to attend to other obligations on Monday, thus progress was at a standstill until I could get back to things by Tuesday.


The root of the odd behaviors I see stem from a few causes, as I spotted using my small fpga based logic analyzer. Mostly, these are challenges causing all the FSMs to come out of reset in a controlled way - in some cases needing an extra startup cycle to allow the input signals to reach their proper initial states. One of the fixes I implemented was to convert most of the FSMs to implement synchronous reset, rather than asynchronous reset flipflops, then worked out the right sequencing for startup.

It took far too long to get the logic analyzer going. First, when I hauled out one larger unit I had, I couldn't find where I had stashed the pods that connect the signals into the unit. I spent quite a bit of time searching and moving things around in storage sheds.

Then, when I decided to use my Spartan 3 fpga board based logic analyzer, I found that the client program on the PC no longer worked. It was an old bit of Java code that was way too dependent on Java releases and a funky serial port library.

I had to locate and install a substitute client program to communicate with the fpga, set triggers and display the recorded signals. Finally by late today I started recording groups of signals to watch how the core processes were working. Each discovery means a change to the main fpga logic, perhaps some changed signals for the logic analyzer, then setting up for a retest.

I am back on the hunt for any remaining issues with the SAC Interface Box. I hope to be moving forward at a better pace in the coming days.

Friday, May 8, 2015

Still working on SAC Interface Box


My cleanup of the logic continued at lunch, with solid results at each stage once I fine tuned the VHDL. The problem I was shooting at the end of the lunch hour was failure to reliably store the SAR.

The low order bits of the SAR were updated by the 'increment by one' operation I specified in the VHDL, but the higher bits were dropping. I loaded 0x0100 as an address and began writing sequentially to the location, but bit 7 dropped out.

I continued in the early evening, hammering away at the logic. It is not working up to my expectations yet. I won't bore everyone with blow by blow descriptions of each test and solution, but will wait until I get a totally satisfactory completion when testing the major functions.


The disk drive maintenance manual describes manual cleaning as a process of using isopropyl alcohol to dampen but not soak lint free clothes which are wiped on the disk surface. Thus, I can use 99% isopropyl alcohol as my cleaning solution but I must get the machine adjusted so that it keeps the pads barely wet. No rush to work on the machine but I am happy that there is a clear path to putting it back into service.

Thursday, May 7, 2015

SAC Interface logic testing/improvement plus disk cartridge cleaning machine


In restructuring the logic, I focused on a few sections that were most critical to ultra reliable operation, specifically related to the USB link and transactional mechanisms supporting commands from the Python program on the PC.

With those changes made, I fired up some tests in the workshop while it rained gently outside. It is very important to go slowly and test exhaustively when working on core parts of the system, which is what I did for the time I had available today.


I picked up a 3M cleaning machine designed to clean the disk cartridges such as used on the 1130, 1800 and with DEC RK05 drives. It spins the disk slowly while advanced and retracting some lintfree cleaning pads soaked in cleaning fluid that slide over the disk platter inside the cartridge.

It uses 3M CS-50 cleaning solution, which of course does not exist today, as well as specific lint free cleaning inserts for the arm. I should be able to fabricate suitable cleaning material, something with Kimwipes or similar on the surface that touches the disk, but I need to figure out a decent substitute for the cleaning solution.

I am in no hurry to use this with any packs, so I have plenty of time to do research and figure out the best options. The internal plastic hose that connected the fluid reservoir to the cleaning arm has become so brittle that it cracked into a few pieces, but replacement plastic hosing is trivial to find.

Disk Cartridge Cleaning Machine - now to secure suitable supplies

Wednesday, May 6, 2015

Small progress today on SAC Interface box


Virtual 2501 reader debugging

I continue to be unsatisfied with the behavior during testing, even though yesterday it seemed I was wrapping up the final issues. The logic in the fpga is getting a restructuring to tighten it up now that I know how everything should be working.

Medium speed SPI link work

I worked a while on the approach I will use to connect microcontrollers on the end of an SPI link operating at 1MHz, which I call the medium speed link. It is a one byte wide link


I am looking into the possibility that I can make slight changes to the disk cartridge, without having to load an entire DMS system just to switch the reader to a 2501. It looks feasible, since the monitor control analyzer fetches the appropriate input and output code when it is given control at the end of execution of each user or other program.

This appears to use two fields in the disk based common area (DCOM), at sector 1 of the cart, to determine the reader and printer types. I think I can just change these words and cause the monitor to attempt to read from the 2501 rather than the 1442 that was configured for the system. 

Tuesday, May 5, 2015

SPI link operating at 12MHz, 2501 reader function getting more solid


Final debugging of virtual 2501 card reader function

I was still puzzled by inconsistent behavior - I have set some indicators that prove that I fire off the upddevtrigger signal because an FSM is cycled as a result and the FSM condition is detected. However, a simple process to flip on an output signal if that trigger signal is every on fails to flip on. Same global clock, but it might be a sync issue of some sort since the trigger signal is just one cycle in duration.

However, since I know that my FSM is triggering, I had to dive deeper into the logic there. I realized that I am coding VHDL that should be synthesizable correctly but it seems to me that it is not happening as I expected. I tested this by changing the expression of the logic to a different method more certain to be correctly synthesized, then retested.

This worked, ensuring that the state of the DSW, as stored in the UCW, was updated by the transaction from the PC program. Now I had to work through and replace any expressions in my fpga logic that were similar to the improperly synthesized logic I had debugged.

I found a clue, in that resetting the operation complete state of the card reader from one area of the Python code worked while another section did not. This helped me get to the bottom of the issue. The limited time for testing in the evening was over, leaving further progress for tomorrow

Debugging of high speed SPI link to slave board

I made a tweak to the startup and my SPI link is moving data between the two boards. My display logic for the indicators on the slave needs a bit of tweaking then I can work on increasing the link speed. The change was made and my scope attached to watch signal quality as I ratchet up the link speed a bit.

At 500KHz, I can see mild ringing just at the edges of the clock, but a nice clean signal otherwise. With the speed ramped up to 1MHz, the parity error checker spots bad frames, which wipes out some of the advantage of the speedup.

However, I didn't create clean twisted pairs or good impedance matching, which would sharply reduce the error rate. The initial wiring is flat cable into mismatched impedance inputs on the slave board. For testing purposes I will drop back to 500KHz, with speedup to full rate a later task.

I did jack up the rate to 4.8MHz once I had the parity checking logic in place to ignore any frames with errors. I found that certain inputs from the slave - sw7, btn0, btn1 and btn2 - would introduce solid parity errors at the high rate, while any of the other signals or combinations did not induce errors. This corresponded to signals 7, 8, 9 and 10, which is a clue I will use to see why these suffer the problems.

Interestingly, the spurious parity errors went away when I jacked the SPI link up to 12MHz, until after a while I got it to lock up pretty solidly when activating any of the switches/buttons. That meant the problem is loss of synchronization when I send a never-ending sequence of 128 bit words over the link. I think I can fix this by pausing and dropping the select, although that will lower the net data rate. 

Monday, May 4, 2015

Short but unproductive day chasing problems in the SAC Interface Box


Testing virtual 2501 card reader

I worked on the logic and found I was not getting the initial DSW set up properly. I still think this problem stems from lack of synchronization between the status process that updates 1130 machine states on the GUI and the virtual device driver  use of the USB link. This seems to get the link out of sync right at the times when the virtual 2501 is switching between Ready and Not Ready state. That is how my status process determines it should not be using the USB link.

A simple test will verify if this is factor in the problem - simply by disabling the status update process entirely, leaving the virtual device adapter as the only communicating entity. I ran the test and the problem still exists. I have to fall back and instrument the transactional sequences to make sure I am receiving them properly and that they are doing what they should.

I am facing a very strange situation - Some of the transaction codes work properly, others don't, yet they are very parallel in construction. Worse, I have a one time triggered latch to tell me if the transaction engine saw the code, but it isn't firing. Yet, other lights are showing the code. I am not sure what is happening here but at least once I find it I expect it to be the root of all the little issues remainoing.

High speed SPI link testing

I finished up the data pump code in the slave board and the temporary testing fixtures using switches, buttons and lights on that board. I connected the boards and did not see my messages echoed, so on to the next level of debugging. To ease the conditions, I further slowed the link to 100KHz which should eliminate signal quality issues and leave me focused purely on the logic of my use. .

Still nothing and my scope is not seeing any attempts to clock the slave. I have to look into the data pump logic itself in the master, instrumenting and verifying if it is working. 

Sunday, May 3, 2015

Still working out kinks in the virtual 2501 card reader functionality.


Wrap up virtual 2501 card reader support for SAC Interface Box

I cleaned up the logic in the Python programming for handling the 'hopper empty' condition. I will do some testing this morning to validate the operation of this, after which I need to wrap up my virtual 2501 card reader testing.

I open and read in a PC file in either IBM 1130 simulator 029 or binary format, buffering it in memory and maintaining a count of the number of card images. When the buffer drops to just one card image, it corresponds to a card sitting in the pre-read station of the physical 2501 reader.

As soon as the hopper empties on the real machine, the card reader drops out of Ready. This allows more cards to be placed in the hopper, the Start button pushed and the reader return to ready status to read more cards. . I handle the adding of cards by processing the next file and appending it to the buffer in my program.

If the card deck was complete when the 2501 reader goes to not ready state, then pushing the Start button without adding cards to the hopper turns it back to Ready in a special condition called "last card". The next XIO Init Read command will fetch that card image but have the last card bit turned on in the DSW. This is how the programming can tell that the last card was read.

Thus, when a finish up an XIO Init Read command in my virtual adapter, I check the count of remaining card images. If the count is now 1 but my 'last card' checkbox is off, I set the virtual reader to "Not Ready" and update the DSW to indicate this. If, on the other hand, the last card checkbox is on when we reach a single card remaining in the buffer, I leave the reader in "Ready" state. If the buffer has no cards left, then we had been in 'last card' state and I add in the last card bit to the DSW as this XIO Init Read completes.

I used a few small decks to check this out. The behavior should be that the reader is Not Ready if there is only one card left in the hopper (buffer) with last card unset, or Not ready with zero cards if we had last card set. Adding a file when the buffer has one card, last card is unset, and the reader is Not Ready should update the card image count and turn on Ready due to the additional card images.

I set up for testing and results were fairly good. I still have some vagaries in behavior to deal with. I ran out of testing time in the morning due to another obligation, but was able to resume later in the afternoon.

I am not seeing consistent updating of the DSW nor consistent resetting of the last XIO function. It wasn't immediately clear where this is malfunctioning. I have to ponder the way the transactional mechanism is working and figure ways to record the progress. This appears to be a good time to haul out the logic analyzer - the small one based on a small fpga board I own, and start tracking the progression of the various transactions to spot what is wrong.

High speed SPI link test preparation

I built most of the logic to go in the Nexys2 board which will be the fan-out slave that gives me many more input-output pins in order to hook to all my peripherals. This board has an SPI slave module and complementary logic to the data pump I built in the main fpga board. Its purpose is to send out signals from the eight slide switches and four pushbuttons, which the initial code in the main board will echo back. The slave board takes the input lines and uses them to drive the eight LEDs and four seven-segment displays. 

Saturday, May 2, 2015

Virtual 2501 card reader from PC file through SAC Interface Box is working, nearly done with testing


Debugging virtual 2501 card reader

Shortly after posting yesterday's entry, I discovered a flaw in my virtual adapter logic, in the fpga side. It was the new functionality I added to support timely Sense DSW reset and operations complete bit clearing, by moving that function down to the fpga while keeping the bulk of the device adapter logic up in the PC in the Python program.

It was necessary to have each interrogative command from the PC do a reset on the value it was retrieving, otherwise the PC side code can't tell whether a new XIO has been issued or we are still seeing the previous command. For example, a card reading program might issue a second XIO Initiate Read to get the second card, both of which have the same function code and buffer address. The only way to detect this is to reset the function code when the PC polls it, thus the PC will see zeroes until another XIO has loaded the function code again.

The flaw was in timing - since the interrogative commands Poll and Pollreset should receive the then current function and reset bits, but clear the bits before the next Poll/Pollreset comes in. I was clearing the stored so fast that what I sent to the PC was the newly cleared zeroes, not the value that was in the UCW at the time the transaction began. It took some thinking to find a way to guarantee clearing while also ensuring we transmitted the prior value. Once I worked that out, I changed the logic and had it ready for testing.

When I fired up the test, I did trigger a busy condition when I issued an XIO Init Read, but my adapter logic in the PC wasn't able to get to the point where it would fetch the function and WCA. Instead, I seemed to be stepping on results needed by the status polling routine that runs every second to update the 1130 state indicators on the GUI.

Since each interaction over the link is a strict transaction of two outbound words followed by two inbound response words, I am not sure how this is getting out of sync. The error I was seeing was a status interrogative from my Python program which was getting back the wrong value when it should have seen the 0x000C it just sent.

This required a new set of diagnostic outputs to figure out how it might be getting out of sync, but I also took a peek at the logic surrounding the card reader since this behavior was triggered by the fpga side of the virtual device.

My python program will not refresh the 1130 state while the virtual card reader is 'Ready'. Similarly, the virtual 2501 logic will stop polling if the card reader becomes not ready. Further diagnostic tracking showed that I was sending the Poll interrogative to the fpga and it was handling it, but the value returned was always '000' rather than the expected '110' after an XIO Initiate Read.

Diving down with more diagnostics, I found that I was not storing the function code in the UCW, so my instrumentation was updated to focus on this situation. I did see some suspect logic in the handling of the UCW update, where a one or two cycle hazard existed that would advance the state machine back to idle too early. I made the change as well as the diagnostic outputs then retested.

I am now correctly finding and resetting the XIO function code from the Poll interrogative, but when I retrieved the saved WCA (address of the table with card count and buffer), I got back zeroes not the address 0x1010 that I had coded in the instruction on the 1130.

A new set of instrumentation and some careful looking at the fpga to make sure I am indeed saving the WCA into the UCW as I should. Other possible errors were failure to process the pollwca interrogative or a failure to send the UCW field out as a response to the interrogative. I quickly found it was a problem saving the WCA, yet the logic seemed correct.

I looked into the module that processes the XIO Init Read instructions in lockstep to 1130 states and cycles. There, I found the cause of the problem. The XIO Init Read instruction has two execute cycles, E1 and E2, when it fetches the two words of the IOCC. In cycle E1, it latches in the function code and modifier bits. In cycle E2 it saves the address word, which is the WCA.  I was setting the busy condition as soon as I latched some of the fields in E1, but that fired off other FSMs that updated the UCW including the WCA address that I hadn't received yet!

Moving the busy signal so that it fires only as we latch the WCA in E2 ensures that other FSMs triggered by this busy condition have all the data they need to store into the UCW. There was a parallel flaw in the XIO Init Write command logic which I corrected at the same time.

Back to testing where I then realized that I wasn't saving the XIO function code, this time because I was looking at the B register value when busy was triggered, but due to my changes to the Init Read and Init Write logic, I am now in E2 when the B register no longer has the function code present. Since I already know what code I am handling, with each module having a unique busy trigger (e.g. busyinitread versus busycontrol), I could just hard code the function to store into the UCW.

Changes made, I did the next test round. This time, I had the proper data in the UCW fields. Making the virtual 2501 card reader 'Ready' with a file of card images, I then issued the XIO Init Read and saw that I was getting the WCA, the count of card columns to 'read' into core, and was starting to store the first column when I encountered a Python issue.

I worked on the PC side program for a bit to fix up the issue I was getting, after which it was time to test once again. Now I was successfully storing the number of card columns requested in the WCA into the locations at WCA+1 and downward in core. The end operation status was put into the DSW and interrupt level 4 was properly triggered.

I tried XIO Sense DSW and XIO Sense DSW with reset but the interrupt level trigger remained on. This is probably a flaw in the fpga logic that shadows the DSW but it could be problems in handling the PollReset interrogative and its effects. Once again, time for diagnostic instrumentation and some testing.

I was fairly sure I had resolved the issue and went back to testing. One issue I observed is that the simulator format set up by Brian Knittel defines what characters are valid in card images, but real decks I have read in contain some additional characters. The original behavior of the Python program would reject a file that had these characters, but I changed the code to simply replace any 'invalid' character with a space.

I prepared some files to test the behavior for when the 'hopper empties', leaving a last card in the pre-read station. I should be able to open the next file and resume reading taking the pre-read station card and then the cards from the new file. Otherwise, if I mark it with the 'last card' function, the file should read that last card and mark the DSW appropriately.

I modified my test program code in the 1130 to support these tests. I discovered that my logic to flip the reader between 'ready' and 'not ready' was not working properly. That blocked any chance to completely prove out the last card condition, although it did seem to be setting the bit.

The problem is most likely entirely in the Python program side of things. As daylight ran out, I moved inside where I did some code review and thinking about how I was dealing with the emptying of the virtual hopper.

Building SPI serial links to remote fpga and microcontroller boards

I finished up the data pump for the high speed SPI link, making it a loopback of the data word so that my remote board can test the interface easily using buttons, switches, LEDs and other indicators. Once I write the test logic for the remote board, I can load it into one of my digilent Nexys2 boards and begin debugging.

The medium speed link is different, including a sequence of words that form transactions. The high speed interface just pumps a registered output word to the remote and registers the incoming stream to an input word. This just mirrors state. The medium speed link adds error correction and other meaning transactionally, by series of 8 bit words, not in parallel. That added a bit more logic for this link. I haven't finalized the protocol thus I left this to code later.

Tonight I built the testing function for the Nexys2 board that will pass switch and button signals up to the master fpga board which sends them back to select various lights and indicators. When it was ready I loaded it onto the board. This can be wired up to the main fpga board and tested tomorrow. 

Friday, May 1, 2015

Beginning testing of virtual 2501 card reader through SAC Interface Box


I completed coding the virtual 2501 logic at both ends - python program on PC and VHDL for the fpga board. I uncovered one design challenge for the protocol to handle a virtual device, which I needed to sort out and then adjust the codes appropriately.

The issue is the sense DSW bits, which include the completion bit that should be reset by a Sense DSW with an appropriate modifier bit. However, the virtual adapter code in the PC does not participate in a Sense DSW function, so it has no way of knowing that the condition is to be reset.

The solution will require some addition bits in the UCW which will communicate when a reset has occurred in a Sense DSW, thus turning off the condition in the PC side adapter. For timing reasons, switching off the interrupt request and the bit in the UCW that drives interrupts should be handled by the fpga code.

The PC program polls for commands, which introduces long and variable delays in checking the UCW, yet the software in the 1130 has every reason to expect that once it executes an XIO Sense Device with a reset modifier bit, the interrupt request will be off. Immediately after the Sense Device, the program can return from the interrupt handler and it should NOT trigger another interrupt due to pokey handling of the reset.

Thus, I need the UCW bit that triggers interrupts handled locally in the fpga but I also need the adapter logic to see that the reset has occurred. The bit can't be solely controlled by the fpga, therefore, but also by the adapter logic running in the PC.

I had three spare UCW bits which I have now assigned to represent up to three interrupt levels that an individual device can use, thus each of the three can be reset by the associated bit in the XIO Sense Device modifier field. I defined a new transaction type, code 13, which fetches and clears the three new bits in the UCW. Thus, each virtual device adapter in the PC can grab any reset conditions, update their shadowing of the state in the DSW and act appropriately. The UCW bit for interrupts will be driven by one of these new bits, allowing for an immediately clearing of the interrupt.

I still had a window of vulnerability, when the device has set a bit such as Operation Complete in the DSW, sent that down to the UCW, which then causes my interrupt level to be set into the new UCW bits. When they are cleared by a Sense DSW w/reset, the operations complete bit remains in the DSW and may be fetched by subsequent Sense DSW commands up until the point that the PC program polls the new bits and sends down an updated DSW. On a physical adapter, the Operation Complete bit would disappear at the time of the Sense DSW w/reset, not later.

To solve this, I set the UCW DSW bit for operations complete based on the state in the fpga - flipped on when the PC side program sends a DSW with this bit set, turned off by the Sense DSW reset command. The Op Complete from the PC is only used to trigger on the Op Complete bit maintained in the fpga.

My testing began, but my polling routine was never seeing the XIO Init Write function codes in its polling loop. This called for instrumentation of lights on the SAC Interface Box to show me whether I was setting the UCW function bits and even seeing the XIO command.

After resolving a dopey mistake I had made in the test program setup, I got back to the testing. My remaining time before dusk was limited so I didn't make much progress but could do more logic development inside at night.