Finished pedestal and verifying card reader interface logic, week ending Feb 16, 2014


I got the LED circuit boards mounted into the masks, tweaked the positioning of the front plexiglass panel, and locked the masks down into place. I fashioned some braces to hold the LED boards in the masks, dressed the wiring and got the electronics board attached in its final location.

The lights look excellent in operation, I am quite satisfied with the pedestal at this point. As soon as I get the emergency pull switch side panel installed, the pedestal will be closed up and ready to mount atop the 1130 frame.

My ring magnets arrived and worked just fine to hold the Emergency Pull switch plate on the left side of the pedestal enclosure face. The pull handle itself must be secured to the plate, either in a fixed position or to a push-pull switch which is itself affixed to the backside of the plate. Lastly, the main electronics board in the pedestal box needs a holder to keep it from moving inside the box.

I built a bracket to hold the main electronics board, attached it, and dressed the cables. Once the Emergency Pull Switch is finished, I can close up the enclosure and consider this assembly complete. I could have left the Emergency Pull Switch handle fixed statically to the front plate, but wanted it to move and activate a circuit - I imagine a gag function that plays some sizzling, snapping electrical sounds, shuts off the machine and causes a puff of smoke to come out of the grill. To implement the gag, the pull handle has to work.

I searched through the switches at Anchor Electronics and came up with a lever switch that can be put into service as the active switching component for the emergency pull switch handle. I drilled and tapped the shaft of the pull switch handle, then put on a long bolt with a tab at the end. I had to form a bracket to hold the lever switch at right angles to the pull handle shaft, then hook it together. The shaft of the handle slides through an axle stop fixed behind hole in the front plate.

At this point, the axle stop came loose from the acrylic that held it against the front plate. I needed to create a bracket that will hold the axle stop up against the front plate. I used a couple more of my magnets attached to a plate with a hole for the shaft. With that in place, the emergency pull switch works properly.

After verifying the operation of all the switches and wiring in the enclosure, I closed up the box with the rear plate. Everything was working great, until about one hour later when I was testing the display other modes of the rotary mode switch on the pedestal. Suddenly, the lamps for bit 14 of the major registers all stopped working.

I suspected the connector is loose on the main electronics board, but it means removing almost two dozen screws to remove the rear panel. I came back to this when I had some idle time, opened it up and did see one of connectors tilted partly off its header, the pin furthest out was of course the one that controlled the bit 13 lamps. I reseated the cables and closed up the box once again, with everything back to par.

                                    Above is a quick view of the display pedestal in operation..

I also ran some videos of the machine operated in single step, single instruction and single memory cycle modes.  These are taking quite a while to upload to YouTube, so I published this entry first and updated it the next morning with these additional video links.

                                          Single Step mode demonstrated

                             Single Instruction mode while it reads a card from Documation

                                Lastly, shows Single Memory Cycle mode operating


I designed a circuit board to implement a three bit count, reset when the physical card reader goes busy and advanced at the rising edge of each of the 80 index marker pulses. Once I build the board, which will replace one of the two MCP23017 input boards, I will route the 12 card row signals to this board, present the three bit counters on most of the remaining input bits, and have a free bit to use for some signal.

I could use the final bit as a flag to alert the fpga end that one of the error conditions tracked on the second interface board has been raised or one of the input buttons was pressed. I can see that I might need this. If a card jams partway through reading, the reader will drop ready, flag a mock or error condition and may not send all eighty index markers. The flag will let me know to scan the other input board so I can abort the read.

Without the flag, I would have to wait until a timeout to detect the failure and begin checking the other board. On the other hand, I could use that spare bit to carry the ready status signal. That way I could carry all the remaining card reader status signals and input buttons using only one side of the second MCP23017 chip (eight bits). The timer would give me the bad news fast enough to respond appropriately. Further, if there is an error flag, the ready bit will drop too which gives me an alert.

The main loop is recoded to exclusively read from the first input chip during the time when card columns may be coming in, but without the counter bits or the ready signal moved to that chip. I can do some testing to see whether this delivers a noticeable improvement in reliability, before I build my new circuit board with the counters and new instantiation of the first input chip.

I began testing with the new interface loop to watch how much difference it makes. I had to regress the signal assignments back to the existing interface wiring, not the new approach I will use with the newly designed replacement interface board.

That done, my first test resulted in steady read check errors as the virtual 2501 attempted to read the card on behalf of the XIO from the 1130. I will set some appropriate diagnostic traces and dig into this tomorrow.

I can see that I am changing the value of the photocells in the middle of a emitter (column) interval, which will definitely cause the read check condition. The fault is definitely in my main 2501 loop in the interface logic. I spotted the situation causing this, updated the logic and did some other tightening up of the virtual 2501 FSM.

The 1130 adapter logic takes 3-4 fpga cycles to see the end of the read emitter and accomplish its read error checking at the end of each column. My interface logic moved to rapidly to retrieve and set up the next column's values on the photocells. I introduced five wait cycles in my interface logic FSM for the virtual 2501 to keep everything stable during this checking interval.

With the tighter serial link timing loop, I read a burst of cards in each run of a test with no dropped columns or timeouts experienced. I may not need to make the changes I had anticipated to the interface electronics with the newly designed input board. Unless I bump into dropped columns during my next few days of testing, I will put the new card design on hold and leave the interface as it is.

With the read check errors eliminated, I could move on to investigate why we are no longer updating core memory during a read. I see the proper cycle steal activity, the proper gates activated and the IO entry sample signal transferred by the processor during X3 cycle. I took a look at the relative timing of my CoreStack activity and the IO entry sample, to see whether I might be blocking or 'overwriting' the incoming card signals. My data transfer through the sense amplifiers is in X1, well before the IO bits are gated, which means I have to look elsewhere.

I then looked at what values were being set up on the photocells and found that all spaces were offered, which would leave the core memory at x'0000'. I turned to my interface logic for the source of the problem. Seems I am skipping out of the read of the physical reader, due to a timer going off before I start the read cycle. This is a reset or timer advance issue I should be able to fix quickly. Out of time for this week, but first thing up when I work on the machine Monday.


I have been running my 1130 with the Parity Run switch turned on, a setting that allows an FE to repair a system in spite of parity errors. Otherwise, the machine halts immediately requiring a reset to continue. When my machine powers up, before it fetches the first data word from 'core memory', it lights the Parity lamp.

Due to the design of the 1130, if the sense amplifier signals such as NotSenseAmpBit4 goes to 0, it immediately turns on the bit in the B (SBR) register. In this case, it would turn on BBit4. Thus, the idle state of all the sense amp lines has to be 1 unless we are ready to actively clock in a value after reading memory. This causes the B register to start up with the value x'0000'.

Since the 1130 is an odd parity machine, implementing one parity bit to protect each halfword in memory. Thus, there are 18 bits coming from core on a read, 8 per halfword and a parity bit for each halfword. If there are an even number of ones in the halfword, the parity bit must be set to 1 to bring the total to an odd number. If already odd in the halfword, then the parity bit must be 0.

I investigated this and watched carefully as I ran after loading memory where I thought I had set up the right parity memory values. What was showing up on the display panel did not correspond to what should be there.Further, I couldn't see any connection between what I entered and what was showing in the check bit registers.

My first step was to go over the CoreStack routine with a fine tooth comb, recode where appropriate to make everything tight and reliable, and look into the issue of the seemingly random parity bits. Once this is done I can trace until the parity is arriving properly from RAM, then ensure that my startup state does not have a parity check indicated.

I did a lot of recoding of the CoreStack and the subsidiary modules its calls, coreaccess and ramaccess. I modularized the logic to make debugging easier. Ramaccess does a single read or write to the physical RAM sitting on the fpga board. Coreaccess handles a request for a single 'core' address and turns it into a pair of calls to ramaccess, one for the 16 bits of the data word and one for the corresponding word that holds the two parity bits. CoreStack itself handles the latching of 1130 signals at the right times, strobing of the bits from coreaccess back into the 1130, and synchronization with the 1130 timing.

My code changes really tightened up the timing of all three modules while also making them bullet proof. I had one small error in the coreaccess state machine that blocked it from ending a cycle correctly, but once I spotted that and corrected it, I was getting solid results and able to run normally, without the Parity Run switch I had been using.


The assignment of signals to the main black plate lamps was not correct - the parity check lamp was lit continuously although the parity stop condition was only on at certain times. Instead, it appeared that the lamp was lit by another signal. I did some forensics to straighten out the connections and get everything assigned as it should be.

I found an error is now occurring that erases the op code register when the processor is executing additional memory cycles, e.g. E1 cycle of an instruction. Some of the register reset logic is the most timing sensitive in the machine, which I had previously tweaked, but this has apparently been thrown off by changes I made to the CoreStack module.

The Storage Select pulse, which I had lengthened to fit the new core memory emulation changes, determines the timing of reset pulses to turn off the op code registers, as well as others such as accumulator (A) and storage buffer (B or SAR). I used the Storage Select pulse end as a trigger to strobe in the memory contents to the B register, with the longer pulse extending the time before memory entered B and allowing all resets to complete first.

I readjusted the Storage Select back to its original timing of one cycle (T0/X0 and T4/X4 time), then worked on the memory strobing in CoreStack to ensure it was properly timed. With those changes, the op code register erase problem was not fixed. There is a one cycle blip on the signal caused by a slow change from I1 cycle to the later cycles of each instruction. With the 1130 being a partly asynchronous machine, all it takes is a hair of overlap in states to let glitches through combinatorial logic, as in this case.

The 1130 is very loose on its switching among major instruction states and this is well documented in the theory of operations manual. Some actions in the machine late in T7 and early in T0 are defined to be identical regardless of the major instruction state (e.g. I1 or E2), because of this noticeable slop across the boundary. The designers handled it by ensuring adequate delay in signals so these glitches wouldn't happen if the hardware was working properly.

I looked at the best way to address this, closest to the spirit of the 1130 machine itself and most elegant. As well, I don't want adjustments I make in one area propagating through the machine to induce further timing challenges, so the scope of an adjustment must be very local. In this case, the glitch occurs in a three input AND gate where one long-lived signal, NotCSLevels, combines with the late arriving I2Cycle signal and a trigger signal whenever we have a storage read cycle with StorageSelect on.

If I can delay the trigger signal one cycle, we should be free of the initial glitch, but I will have the tail end register reset condition extending one cycle as well. Since we have 14 fpga cycles in each 1130 cycle, that is probably in tolerance, but to handle the worst case, where this might affect other circuits, I will need to shorten the duration of the register reset in addition to delaying its start. This was done using an edge triggered single shot after the AND gate.

This fix was just what I needed. The machine now appears to be fully functional again. Unless I detect any other timing anomalies, I will be focused on finishing the card reader interface debugging and validation.

Well, I did indeed find other timing issues, due to my tight timing for memory access. Certain operations require the processor to manipulate the storage address, for example to fetch the second word of a doubleword operand, or to pick up each word of IOCCW field during execution of an XIO instruction.

The processor was just a hair late flipping on the low order bit, while I had already latched in the storage address to protect it from change. Thus, the 1130 intended to pull the data in address + 1 but I presented the contents of address instead. The next cycle, when it wanted to fetch what was in address, it had not yet dropped the low order bit so I latched and fetched address+1 instead. This fouled up the XIO processing, as you can imagine.

I adjusted the CoreStack module once again, this time delaying my latch of the storage address for two fpga cycles, to accommodate the async pulses flying around the machine. My next tests ran well, with the IO triggering correctly. I can switch back to finishing the card reader interface now.

No comments:

Post a Comment