Thursday, April 30, 2015

Debugging the virtual 2501 card reader implemented on SAC Interface Box plus PC


I woke up with coffee and Python this morning, extending the PC side program to use simh and IBM 1130 simulator files as the card images to be passed to the 1130 when it boots or reads from the virtual card reader. I had the boot method set up, but have not moved over all the code from my keypunch golem program that deals with the 1130 simulator file formats and conversions.

Over lunchtime I rolled in the formatting and checking routines from the keypunch program and tested them. I then began built code to translate all of this to its hollerith code equivalent which is how it will be passed down to the 1130 on each read.

I began on the FSM for the PC program that controls the virtual reader - deciding when to update status, store a card image into memory, handle the last card situation and other complexities. Because the 2501 reader, as with the 1442 reader, has a pre-read station into which a card is first moved before it is read on the next cycle, every feed cycle is reading the prior card while feeding the current one. If the hopper runs out of cards (we reach end of the PC file), that leaves the last card sitting in the pre-read station.

There are only two ways to read that last card. A new deck is put into the hopper (e.g. we open another PC file), or we take a special operator action that tells the adapter to do a cycle but mark the DSW with the 'last card' status. This is how the operator signals the end of a card deck, with the special last card sequence, otherwise any time the hopper runs out, we can place more cards from the same large deck into the machine in order to continue reading that deck.

In order to handle this behavior, I needed a check box called "Set Last Card" and a button labeled "NPRO". The purpose of NPRO is to throw away the card in the pre-read station, if you don't want it to be read. These were added at lunchtime as I worked on the virtual card reader FSM. The rest had to wait until early evening when I could get back to the 1130 project.

When I restarted in the evening, I did a bit of rearranging of how a virtual device would function between the PC and the fpga, when I saw that a few timing vulnerabilities existed when certain state was updated from the PC. I moved that logic to the fpga where it could operate in bounded time appropriate to the 1130's speed.

I also built up most of the data pump that works over the fast SPI link to synchronize input and output signals between the two boards. This should be put under test with a second fpga board by the weekend.

The part of the virtual 2501 card reader that read and prepared PC files to be shipped to the 1130 was completed and tested to some degree. I then worked on the FSM implementation so that I could process the card reading in chunks in between GUI handling. I initially set it to handle a chunk of work every 50 milliseconds, which should support reading cards in the range of hundreds of cards per minute. The target to match a 2501 is at least 600 CPM, which is easily attainable but will need tweaking of the timing between chunks of work in order to hit the right pace. 

Wednesday, April 29, 2015

Implementing high speed SPI link from SAC Interface box to secondary fpga boards


Testing of the 1627 plotter adapter implemented in the SAC Interface Box

I set up a larger rectangle in memory and prepared some video clips of it being loaded, run and the plotter doing the drawing. At the outset, I discovered that my timing parameters for the adapter are still not good enough. While I seem to trigger reliable movement for pen movement, it was not long enough to move the pen up or down onto and off the paper. Further, I may not be giving enough time for the mechanical and electronics to complete before permitting the 1130 program to issue a subsequent command.

I made more changes but I am still not happy with inconsistent behavior from my plotter replica. It doesn't move the same amount when rerunning the same program sequence. Further, it can stall in some condition where my manual buttons don't move the drum or shift the pen off/on the paper. The solution to that is to power cycle the electronics of the plotter, which tells me they are getting wedged in some bad state.

Video of the replica plotter driven through interface box

The only solution is to make a new hardware adapter unit, replacing the box I currently have between the Strobe plotter and the fpga. This will be a small design exercise, but not a priority, because I am pretty comfortable that my SAC Interface Box is working fine. I also could attach the mbed based board designed by Richard Stofer, since this takes the six movement commands produced by my interface and will convert them into valid HPGL, sending that to an ethernet connected printer.

Building the high speed SPI link capability to a remote fpga

The remote fpga will serve as a pin extender giving me another 60 to 120 input/output signals for peripheral attachment. I will initially clock the link at 1Mhz to debug it, then shift up to its max speed of 48Mhz later in steps while validating continued reliable operation.

I designed the SPI link as a simple data pump, sending all the outgoing signals to the remove side while simultaneously receiving incoming signals from the same board. It will start with a single remote board, but I will be able to extend it to multiple remote boards fairly easily, by simply cycling through the boards sending and receiving the frames associated with each.

The frames sent between fpga boards are 128 bits long and make use of a code that can correct any single bit errors and detect any double bit one. It is a Hamming Code, carrying 120 data bits with seven parity bits for the Hamming Code plus one additional parity bit. This converts it to a Single Error Correction, Double Error Detection (SECDEC) mechanism that can be used to reliably correct single bit errors unless we suffer triple or more bit failures in one frame.

I coded up the SECDEC encoding and decoding functions, although my first cut does not attempt any error correction, it simply flags that one or more of the parity bits were in error. I then began on the SPI link and data pump logic. Once done, I need to create the complement for my Digilent Nexys2 board which will be my first remote endpoint. That unit will start out mirroring signals on LEDs and seven segment displays while sending in the state of various slide and pushbutton switches.

Building the virtual 2501 card reader

Interspersed with coding of the VHDL for the fpga functions above, I decided to work on the Python program on the PC to implement a 2501 card reader for the 1130. It will serve cards from files on the PC, using the file formats created by Brian Knittel for his 1130 simulator. 

Tuesday, April 28, 2015

1627 plotter replica working through SAC Interface box, working on paper tape reader/punch and virtual 2501 implementations


Debugged the 1627 plotter interface

I switched my diagnostic light signals around to spot what was happening with the pin used to drive Carriage Right on the plotter. I found that pin D28 of the fpga board was at ground but should have been high like all the others nearby.

Some more diagnostic changes were made and I tested again, this to looking to see what state the fpga logic 'believed' the pin should be. I am narrowing down the issue to see if it is a physical board problem, an fpga hardware issue, a synthesis tool failure, a subtle logic problem in my vhdl code, or something else.

I relocated the lead to a different pin and completed my tests of the 1627 plotter interface. However, as part of my testing of this, I did discover what was wrong with the original pin. I misread the FPGA assignment for that pin, seeing 'D1' when it was actually 'B1'. That was corrected.

All functions of the plotter were activated, but when I put the machine into a tight loop, issuing a plotter movement and redriving it as soon as I received the operations complete interrupt from my adapter, I didn't get smooth movement. It seemed to miss some steps, which implied to me that my timer of 3ms is not long enough for the plotter hardware adapter and the Strobe 100 mechanism to recover from one move and accept a next command.

I didn't have documentation for the Strobe 100 plotter but did some internet searches in order to find any speeds and feeds that might guide me. Those turned up nothing at all, so I had to experiment to see what delay would work. I increased the timer from 3ms to just over 5ms and retested. I also tried 2.6ms, but it was hard to spot a difference among them and in no case did the plotter seem to move smoothly and fast. I think I need to test over a wider range of driving signals.

I did find some timings that seemed to work okay, but I need to tune in two different timings. The first is the length of the logic pulse that triggers the plotter, which has to be long enough to ensure it triggers but not so long that it moves more than one step. The second timing is the total delay before the device goes not busy and signals an interrupt. If this is too fast, the mechanism is still moving which will interfere with smooth overall action but if it is too slow the performance of the plotter is sharply reduced.

Playing with timing pairs was a tedious business, but I did arrive at values that seemed to deliver a decent behavior and reasonable speed. Once that was set, I adjusted my driving program in the 1130 to draw a small rectangle using a sequence of commands.

The rectangle is a bit small, due to the small step size of the plotter. I will try to increase its size a bit, while I prepare to shoot a short video clip of the 1130 drawing the rectangle under program control.

Serial links to other fpga and microcontrollers

If I am going to operate the high speed SPI bus at speeds approaching the 48MHz of the fpga board and support realistic distances between the main fpga board and any secondary boards, I needed to find differential converters that could meet my needs for distance and signaling rates.

I found the LTC1518 and LTC1688 chips which can drive signals at 50Mbps over cat 5 cable for 100 feet. These take single ended signals from the fpga SPI pins and drive the twisted pair to the receiving end where they yield a single ended output for the secondary fpga board.

I should begin with an SPI link operating at a lower speed, use it to link to fpga and arduino boards. I can use the paper tape reader as the first device connected this way. OpenCores has an SPI master and slave pair that is proven to operate at 50MHz with Spartan 6 fpgas - thus perfect for my boards.

Richard Stofer reminded me of the mbed microcontrollers, another option with more power than the Arduino, which I can add to the design pool for handling devices. He developed a 1627 plotter emulation for his IBM 1130 emulator using an mbed and shared the source code with me several years ago. I still have that mbed somewhere - it takes the 1130 plotter operations and converts them to HPGL to plot on an HP printer or plotter over ethernet.

The high speed SPI link is intended to extend input/output signals beyond what can be hosted on the core fpga board. Each board I am likely to use is going to have capabilities of 50 to a bit over 100 pins. Thus, my protocol is going to be set up for worst case, that all are either outbound or inbound.

I choose a SECDEC version of a Hamming Code allow possible correction of single bit errors and detect double bits. This would place eight parity bits along with 120 data bits onto a 128bit wide SPI 'word'. It will start out simply as a detection mechanism - ensuring that I spot and ignore any frames that contain errors. Later I can add in the correction on the fly circuits.

I don't want sporadic glitches driving output actions on peripherals, so I am willing to lose a few frames to reduce the risk of glitching. Any signal change that is not extremely short will be picked up on the next frame which does not have parity errors. With the speed I intend to operate the link, I should be sending a frame in about 2.5 microseconds. Even skipping several in a row is unlikely to miss a mechanical device controlling signal which would be millisecond range or longer.

Of course, that analysis is true for a single secondary fpga board handling expansion of up to 120 signals, but even if I tripled the number of secondary boards, we are still under 8 microseconds to deliver a frame update to every board.

Data streaming in from a fast device like a disk drive would be passed by a parallel word and interlocking, so that lost frames don't lose any data. The width of the parallel word is a tradeoff between losing external signals and performance needs of the device. A disk controller might dedicate many more bits to an interlocked buffer than the board controlling paper tape, terminal or card devices.

I began developing the logic for the SPI master (and a mirrored SPI slave version). The sending side will generate parity and transmit the latest version of its outbound signals, while its receiving side will accept frames, parity check and update registered signals, A simple pump that mirrors the state of signals to the remote side, the direction depending on whether the signal is an output or input of the master fpga.

The slower SPI link is intended to communicate with slower devices, typically microcontrollers like Arduino, mbed etc. I set that up with 8 data bits used pairs of words to include parity and protocol along with the data.

The initial implementation will be slowed to just under 1MHz, sending a frame each 125 microseconds. this is still fast enough to operate paper tape and plotters during the first phase before I ratchet up the link to full speed.

Monday, April 27, 2015

Building out SAC Interface with paper tape, virtual card reader and plotter support


Device adapter code additions

I added in the logic to handle the IBM 1134 paper tape reader and IBM 1055 paper tape punch devices - although the actual devices will be different, they will operate the same way. I didn't include the logic to handle program load although as this wouldn't work on my system unless I switch some jumpers which currently set the 1442 as the program load device. I can use my virtual program load function from the PC to force in the boot stream if needed.

I improved the python code that loads core from a simulator out file, causing it to go back after loading core and fetch all the locations to compare them to the intended result. This way I can be warned if any data isn't stored properly.

My first virtual device will be a 2501 card reader allowing me to read card decks which are files stored on the PC in IBM 1130 simulator format. Program Load mode will be accomplished by the PC program using cycle steal to load the first card in PL mode into core and asking the operator to start at IAR 0000, after which normal reading occurs from the device.

Testing of 1627 plotter device adapter

Instrumentation to debug the plotter adapter was changed before I went out at lunchtime to run some tests. I found that my timer was giving me a clean 3 ms delay, which is what I targeted. I then moved the instrumentation to watch the output signals that should be driving the plotter.

My shadowing logic to mark when I was in various XIO phases didn't clear the XIO E3 status until the next instruction T0, which left it incorrectly active even when at the end of a single instruction mode. I adjusted it to work better.

I am clearly seeing the output line change so I need to move on to look inside my 1627 hardware emulation box. I did verify that the pen up and pen down commands work properly, but I don't seem to be getting any movement for the drum up, drum down, carriage left or carriage right commands. I did notice that my fpga pin is at ground level even though it should be at 3.3V, which drives the carriage to the right continually.

Until I am sure what is going on with the Carr Right pin from the fpga, which could be a shorted wire or other problem inside the interface box, it doesn't make sense to shoot problems any further. Since the day was ending, I shut down the testing for the evening and went on to other tasks.

All in all, I had progress validating the adapter. It is possible that I need to tweak the timer to accommodate the speed of the strobe plotter, although there is no point touching anything until I find out what is going on with the Carriage Right line.

Study of connectivity to physical devices

I am leaning to using SPI to link to various physical peripherals from the fpga, in order to conserve the limited remaining I/O pins. Theoretically I have 30 available if I reorganize my connectors and cabling, but I could readily get 20 or more.

For the highest speed devices, I want an SPI bus operating at full 48MHz fpga clock speed, which is just possible using the clock modules on the Spartan chip to give me the clock phases necessary for SPI operation. Using the fpga as a master on a bidirectional bus, I would need 3 wires plus 1 per slave that shares this high speed bus.

A high speed SPI link would typically talk to FPGA boards as the slaves and should give me a bus that is well north of a megabyte per second transfer rate. Since the memory of the 1131 has a peak transfer rate of 277,777 words per second if it did nothing but cycle steal transfers, That means the high speed SPI link can fully saturate the 1131.

For Arduino hosted devices, I would only be able to safely operate at about 2MHz and may shift down to 1MHz to allow the processor time to do other work, since the boards are typically 16Mhz processors which would have trouble keeping up with the incoming data at higher speeds.

The Arduino libraries only offer master mode, but examples exists of ways to force the Arduino to act as an SPI slave. As slaves, this would require 3 wires plus 1 per slave for the medium speed bus to Arduinos. Raspberry Pi is an alternative to the Arduino, if I can set up an SPI slave link.

The Arduino is limited in its performance, although I could move to a faster ATMEL processor via the Chipkit Uno32 or similar variant of the Arduino. Still, none of them could keep up with the high speed SPI bus. Having a medium speed bus at 1MHz is good enough to provide about 50KB/s of data movement, which would still drive the 1130 to almost 10% of its memory bandwidth.

If necessary, I could also host slower speed links but those would demand 3+X wires for X slaves at the lower speed. I believe it better to spray out slow speed SPI from one of the slave FPGA boards connected by the 48Mhz link, rather than implement them on the main board. The only reason to build a low speed link would be specific peripherals or very long distances where noise might impair a faster link.

I will tentatively reserve space for 7 high speed and 7 medium speed slaves, making use of the 20 signals that are easily reached on the board. Many of these are currently used with my diagnostic lights, buttons and the current plotter connections. I will need to grab four wires to test one of the links, these will use the four lines I temporarily use for pushbutton inputs. That still leaves the sixteen lines currently used for LEDs and the plotter.

The initial assignments for medium speed are:

  • Paper tape read and punch handler board
  • Documation card reader handler board
  • HP line printer handler board
  • Plotter handler board
  • Selectric based 2741 replica APL terminal
The assignments for high speed links are:
  • DEC RK05 disk drive 1 handler board
  • DEC RK05 disk drive 2 handler board
  • DEC RK05 disk drive 3 handler board
  • Pertec '2310' disk drive handler board
  • IBM 9 track tape drive handler board

Sunday, April 26, 2015

Testing device adapter for replica of 1627 plotter


Design study to add interrupt levels 0 and 1 to SAC Interface Box

The investigation for the possible modification of the 1131 to support my SAC Interface being able to sense and drive interrupt levels 0 and 1 was very tedious work. In order to repurpose signals currently on the SAC cable, I need to accomplish four things. I must interrupt the link between the driver/receiver and original circuitry, for driven signals I have to hold the original circuit inactive, I need to route the reused signal over to the new circuit and I must tie it in non-disruptively.

Some of these circuits use wire-wrap leads, which are easy to interrupt and to hold inactive. Others come from a cable that connects the signal to several different gates, which can be challenging. Some route the signal on traces on the backplane, which is hard to find and even harder to rewire.

The Block Channel Advance driven signal appears feasible to interrupt and use to request an interrupt. Both levels 0 and 1 have a reasonable place where I can add my re-purposed signal to a 'wired-or' that merges requests for that interrupt level.

The remaining signals - CPU Meter Out, CPU Parity Stop, and the candidates for the second driven signal are all messier, with no obvious route to reuse these. More work is needed, which involves the ALDs then careful examination of the backplanes and cabling.

Design study for broader scope of the SAC Interface Box

The fpga board has a full capacity of 100 input/output signals, of which 70 are used just for the 1131 signals. I am using some others for diagnostic purposes, and have just taken six more for my 1627 plotter replica. I am rapidly exhausting the signal pins but have the need for many more signals to handle all the real devices I want to attach.

The paper tape reader and punch will require another 21, the Documation card reader needs about 20, then there are devices with even higher signal requirements - multiple disk drives, a 9 track tape drive, and a 2741 terminal replica.

Some of these devices will have their own dedicated fpga or microcontroller board which can concentrate the signal requirements down, yet they all need communicate with the fpga board that is the core of the interface box.

I have two ways to proceed. One is to use sets of a few signals for each secondary board employing a high speed serial protocol like SPI. The total connectivity is still limited, especially for high speed, low latency requirements which would be bit serial over each link. A second method is to take most of the remaining signals on the main board and use them for a 16 bit parallel fast bus to a second board, which would have quite a few I/Os to the connected devices.

Testing of the 1130 using the 1627 plotter replica

I completed some hand code and tested it on the 1130 simulator, ensuring it would drive the 1627 plotter to make a certain pattern. I did some tweaking before I was satisfied with the pattern, and I had to adjust my assumptions about what bit corresponded to the various plotter movements. That successful program was then dumped to a file and transferred into core memory by my interface box, after which I tried out the plotter program on the 'real' plotter.

It didn't work, which is to be expected on the first test an a device adapter, so I began instrumented and debugging. I then found that my adapter logic was recognizing the IO conditions and triggering the response interrupt. There is also some ambiguity about whether my little hardware emulator box that sits between the strobe and the SAC interface box should be receiving inverted or normal drive signals. It was built to map the strobe plotter to the functions available on the Calcomp unit that IBM sold as the IBM 1627.

I am embarrassed to say that my interrupt routine changed the accumulator but didn't save/restore it. this didn't cause a problem on the simulator due to its high speed - it was already looping on a lockword when the interrupt occurred. On my machine the interrupt was occurring very rapidly relative to instruction execution. The machine memory cycle time is 3.6us and should have been able to execute many hundred memory cycles before the interrupt arrived.

Thus, my bad code exposed a timing issue which I need to investigate. I should be spinning in a countdown timer for almost 3 milliseconds before firing the interrupt. I had to put the scope on the lines to verify what was happening and the duration of the timer. It appears that my timer lasts only a few percent as long as it should. I will pore over the VHDL and think of ways I can narrow down the search or hopefully spot the problem directly.

Daylight was fading and so the testing came to an end for the weekend. This is reasonable progress when debugging a device adapter, even a simple one like the plotter. With the evening I can look at some of the design decisions and perhaps extend the functionality a bit.

Writing additional peripheral device adapter logic

I began implementing the paper tape adapter, allowing me to drive a 1134 tape reader and 1055 tape punch. The final implementation has to wait until I resolve the expansion approach (see topic above), but I got the devices installed in their UCWs with the proper area codes.

Saturday, April 25, 2015

SAC Interface loads IBM 1130 core from PC file


Load 1130 core from PC file

I took the new code out to the workshop to try out my Python code that uses the SAC Interface box to load core memory with the contents of a Simh memory dump file made on the IBM 1130 simulator. I have an image of the DCIP utility which initializes disk packs, which I will use to check out the functionality of this memory load.

I commenced my testing of the capability to load the real 1131 core memory with data from a simh dump file written by the IBM 1130 simulator on the PC.  It worked perfectly on the first shot. I shot some video of the process of loading the core memory from the dump file of the DCIP utility program sitting in the IBM 1130 simulator on a PC, plus I began running the utility to show that the code was good.

I didn't have my console typewriter working which kept me from a more compelling demonstration, but this is a milestone that I didn't want to ignore. The video is visible at Video of PC file loading into core of IBM 1130

Design decisions

It would be most useful if I could sense and trigger interrupt levels 0 and 1, in addition to levels 2-5 which are included on the SAC lines. I did some study of how I might rewrite my 1131 to make this happen. I would have to repurpose two outbound and two inbound signals from the SAC interface, which makes my box a bit less universally usable on other 1130 systems.

I could put in a configuration option in my box that will either use the universal signal meaning for the four chosen lines or use them for IL0 and IL1 support. Two signals are easy to pick, the Meter in and Meter out lines, since I don't care about billing or spinning a usage meter. I have two output signals that I don't need to use, Block Clock Advance and Advance IO Entry, either of which could be re-purposed to request one of the interrupt levels.

The last of the four lines will take more care in choosing, because there is no other easy input signal to commandeer. My choices at this point are CPU Parity Check and one of the X clock states. I am not using all four of the X clock state signals, which is why I could steal that line. The Parity Check signal is only used to signal an error, but it is a rare enough condition that I might be safe ignoring it so that I can borrow the line.

If I update my box to handle the first two interrupt levels, I can then have my box take on the role of the 1132, 1442 and console keyboard devices. Although I have these real devices on my system, I can easily block their action by interrupting the signals that tell the adapters when their area code is specified in an XIO instruction. If the adapter thinks the XIO is for a different device, it ignores it.

I can see how this would be quite handy, because currently I would need to generate an entirely different disk cartridge to run with the 2501 and 1403 devices I am able to emulate on the vanilla SAC interface, but my current systems are configured for the 1442 and 1132. This would let me substitute other physical readers and printers or use virtual devices on PC files.

I think I see the gate/backplane locations for the signals I need to support IL0/IL1, but I also need a way to get that to the driver/receivers for the four repurposed SAC cable lines. This may introduce some undesirable compartment to compartment or even gate to gate cabling. More study is needed.

Upcoming additions to the interface box

Next development tasks for the interface:

  • hardware adapter for my replica 1627 plotter
  • hardware adapters for paper tape reader and punch
  • virtual 2501 card reader in the PC
  • hardware adapter to emulate 2501 using Documation card reader
  • virtual 1403 printer in the PC
Implementing 1627 plotter adatper using SAC Interface Box

I decided to pull out my plotter replica since interfacing this should be fairly simple and only require the use of six of my diagnostic lines. This plotter is built using a Strobe Model 100 drum plotter plus some logic I constructed to change its behavior into that of the Calcomp unit (which IBM relabeled as the 1627).

I implemented the adapter logic that would have been installed inside the 1131 if the 1627 plotter was configured in the system, but my machine did not have this feature. The SAC Interface Box adds that adapter function into the system. This would equally work with my replica or a real 1627 or Calcomp equivalent.

I had to write some code to draw with the plotter, test it on the IBM 1130 simulator in order to load it to the real machine using the interface box. Testing everything took quite a bit of time on Saturday.

Friday, April 24, 2015

SAC Interface fully functional, code added to load simulator files into 1130 core


My adjustments to the logic paid off, giving me correct operation of XIO Sense DSW after the PC program updated the virtual device status in its UCW, and the PC was able to update the data word in the UCW for successful retrieval by an XIO Read instruction in the 1130.

I updated the instrumentation and the PC side program to work on the Sense ILSW logic validation and to check that my shadow memory register (SAR) autoincrements after each read or write. Those tests had to wait until the late afternoon, when I set up and successfully validated the XIO Sense ILSW functionality. The SAR autoincrement is not working properly, something I would look into next..

Looking at the logic, I found a situation that would cause the SAR bump to malfunction, which I corrected. I also instrumented the SAR register onto the lights to let me visually check the correct operation of the autoincrement logic. The test ran perfectly, so that I can set the initial core address and then issue a series of words to be stored in the range of addresses beginning at the value in the SAR and continuing upward sequentially.

I decided the best initial file format to open on the PC and transfer is the 1130 simulator files stored by SIMH when memory contents are dumped. That way, I can boot in diagnostics or other complex card based files and have them sitting at the idle rest position, transfer the contents to the real 1130, and set its IAR to begin executing at the same spot.

I completed program updates on the PC to open the simulator core files, process the data and issue the appropriate commands to the 1130 to cause them to be loaded in core memory. I have a bit of testing to do tonight, without the SAC Interface Box or 1130 system, but the real testing will take place tomorrow.

Thursday, April 23, 2015

Cycle Steal, Interrupt triggering and many virtual device capabilities working perfectly in SAC Interface Box


I worked on quite a few functions that weren't fully implemented, so that by the time I could work on the 1130 at lunchtime, these were presumably ready and just needed testing.

I believe I found the cause of the delayed fetch data from my testing yesterday and hope to see that confirmed today.

The PC side python code was also cleaned up and augmented. I generalized some of the code to handle virtual devices as well as the GUI triggered actions. I need to work through all of these functions as well, since the code is new or modified.

I discovered some flaws in handling my newly generalized code with functions that previously worked correctly. I set up some instrumentation through the temporary lights in order to find the cause. It was pretty easy to zero in on the flaw in my new generalized code; fixed rapidly and back on track.

Cycle steal fetch now works perfectly. I still have some timing flaw in Cycle Steal Store where I am always writing zeroes instead of the intended data value. Shouldn't take long to track this down and fix it.

I then tested by interrupt requesting logic, but found that regardless of the interrupt number I thought I was triggering, I always turned on IL4. This too should be a simple flaw to find and correct. I went in to eat lunch, work on the flaws and resume testing later today to see if I got it right.

The cause was two fold, both in the python code. Testing proved out well - I could turn on or off each of the four interrupt levels independently for any device. I realized I have a small design problem in how to properly handle the XIO Sense ILSW for virtual devices, since when this command is issued the fpga has no way of knowing which bits in the ILSW are assigned for that device when it requested an interrupt for each level. It may need to be coded in fpga logic for the virtual device,leaving all its other handling to the PC side program.

I did some instrumentation in the python program to test the functions that let me retrieve the last XIO function, modifier fields, WCA and data word for a virtual device, plus the function to set device status and to set up the data word for an XIO Read to retrieve.  This took a while but I resumed testing in the late afternoon.

Initially, I executed an XIO to the virtual device and tried to retrieve the various fields, but all that was returned were 0 values. I took the time to re-instrument the lights so that I could divide up the problem. First, make sure the proper status was being saved in my "UCW" field in the fpga, then I could track down whether it was being returned properly.

I found some spots where I could change the handling of the UCWs in the fpga, made the changes and tested again. The results were very good. Not perfect, I have a couple of issues to chase down and I still need to work out the mechanism for Sense ILSW, but most functions are working properly.


  • The function code (XIO type) is correctly stored and retrieved for all XIO types
  • The modifier field (bottom eight bits of IOCC word 2 is correctly stored and retrieved
  • The WCA is correctly saved and retrieved for XIO Init Write and XIO Init Read
  • The value in core memory is correctly transferred after an XIO Write
When I attempted to load a new value in the UCW for use with an XIO Read, it did not store the new value. I will narrow the instrumentation down to determine where the failure occurs.

When I attempted to store a new device status and interrogated it with an XIO Sense DSW command, I only saw zeroes in the B register. Again, my instrumentation will help me figure out where the failure is occuring.  In addition to setting up instrumentation, I will be looking over the relevant logic in the fpga to see if I can spot the cause or have a cleaner implementation.  Daylight is fading so my 1130 testing is over for the day.

Wednesday, April 22, 2015

Now handling cycle steal fetch requests and status inquiries from PC to the SAC Interface Box

Today was slightly better than yesterday, so a bit of time became available at the end of the day and I got in to work on the system.


I used my instrumented logic to shake out several functions, so that I can now load the memory address that will be used for cycle steal fetch and store, as well as retrieving the contents of a chosen memory location. I do have a timing bug I had to chase, because I had to fetch twice from the same location in order to receive the value of that core address. If I changed addresses, I still got the contents of the location from the last fetch request.

Status messages are also being correctly processed, sending me the status value being maintained in the box. When I tested a store into a memory address using cycle stealing, I found I was addressing memory but storing zero rather than the data pattern I sent. I suspect this is related to the timing mismatch that causes my fetch to be one request out of sync - likely I am storing before picking up the intended memory contents.

Daylight was waning by this point, but I had some good insights based on the testing. Time to go through my logic, find and fix the 'last fetch not current fetch' issue and be sure my data value is what is passed to the store logic.

I have some more code cleanup for the Python program and more logic I want to add to the fpga, some of which I will do tonight.

Tuesday, April 21, 2015

No work today, ergo no progress. Somehow there is a correlation

There was zero free time today to work on the interface. Finally in the evening I could put some work into the VHDL for the fpga logic, setting up for further diagnostics when I get back out to the garage.

Fellow historic system owner Johannes Thelan has moved his IBM 1800 system into its new home and is beginning its restoration. This system includes many peripherals including 2311 disk drives. There were no ALDs with the system, logic diagrams that are essential to diagnose and repair the machinery.

Fortunately another 1800 owner, Bob Rosenbloom, has the documents for his machine. While it is not identical, lacking mag tape support for instance, its manuals would be close enough to work from. Bob made scanned versions of the manuals available to Johannes.

Monday, April 20, 2015

Transactional logic working and returning data, on the SAC Interface Box

Heavy work day, not too much time to play with the 1130, but I did get some coding and testing accomplished.


I came up with a new design for the logic that sends back word 2 at the end of a transaction, either an echo of what was sent or the requested data, depending on the command type we received. I built it up at lunchtime along with a few other enhancements.

I fired up the systems to test and could see that I am latching up values when I command it to load the shadow SAR, but the values showing on the lights don't seem to match what I expect. Echo works well, but also getting some unique values for certain status words. I am instrumenting the logic to help dig into this further. It is progress, even if slower than I would prefer.

Sunday, April 19, 2015

PC link to SAC Interface Box operating,. now working on validating the commands and responses


Last night I redesigned the logic for the PC link, building up in layers from a solid approach. The innermost logic is a state machine that reads two words from the PC then waits until triggered to write back words or return to idle waiting for the next input. The next level up establishes the transactions, such as 'store in core' or 'trigger interrupt' or 'fetch WCA address'.

The transactions consist of a command word followed by a second word - the command may request an action or it may ask for data. These types are called imperative and interrogative respectively. Each transaction ends with an echo of the first (command) word and either an echo of word 2 for imperatives or some data returned as the second word for interrogatives.

The lowest level machine - to read two words then write a variable number of words - should be set as it is, subject to testing. The next machine, establishing transactions, is the one that also sets up the outgoing data or latches incoming values, so it needs to be more carefully written to work with the lowest machine. The transactional machine waits after it latches in the second word, having set off another state machine assigned to each command. When the other state machine has completed its function, it triggers the transaction machine when then writes back results until done.

Building up the layers involved various FSMs that will produce an output word that is transmitted back to the PC at the end of a transaction. I was most concerned with the FSM to send back status words, as that should be easiest to test. After that, I would work on the machines that load the SAR and SDR shadow registers. Finally, a test of cycle steal fetch and store would be a solid stopping point. For each test, I worked out some diagnostic signals to emit on the temporary lights.

The first test was to watch the link while the Python program sends a status request to the box and the box returns the correct status. I will be able to tell if the innermost link FSM completes or sticks in one state, same with the transactional FSM. I also watched to see what command was latched and the word sent back from the viewpoint of the fpga.

The link was not working and I wasn't sure which side of the link was at fault. After some detailed testng I found a couple of flaws in the fpga logic and successfully get through the innermost FSM, latching in the command and data words. The higher level transaction FSM recognizes the send status command, fired off that state machine, received the completion trigger and wrote both words back.

The problem I am now having is a timeout on the PC side trying to read the second word. It will take a bit of investigation to determine whether I failed to send the second word or whether the code on the PC side is in error. The general functioning of the link and transaction machines seem good.

I did have a problem with the pyusb code on the PC side, which is now fixed. At this point, I sent a Status Request interrogative to the fpga and got back the echo of those two words. I will go through some additional functionality next, first loading the SAR shadow register and then doing a cycle steal fetch and a store.  I had to change the instrumentation in order to diagnose these next steps. It was getting late so the remaining testing time was limited.

The second word returned on each transaction should be either an echo of what I sent for an imperative type ("do this") command, or a value for an interrogative type ("give me this") command. The Status Command is interrogative but I received the same value I sent for word two. The Set SAR imperative command should echo what I sent but it returned all zeroes. Further, I didn't see my diagnostic lights indicating the value I sent for word two.

I have a link operating and the basic transaction completing, but the higher level functions including determining what to write back at transaction end are not yet debugged. Basically just slow careful slogging through the logic, doing tests and reconfiguring until it is all vetted (and fixed where defective). 

Saturday, April 18, 2015

SAC Interface Box working correctly for all XIO types - ready to support devices - now debugging the PC link


I believe I found the flaw in the shadowing logic that would inform the XIO Read module when it was in the E3 phase - the point when it has to assert the data value on Channel Data In and raise the Channel Write Gate signal.

I could use some diagnostic outputs from the fpga so that I can tell what is occurring. Once the two way link is working I can send diagnostic info over that, but in the interim while I am working on the link itself . . .

There are several FPGA pins that are not currently used and accessible from the remainder of the AB and CD connectors. There are 24 potential signals to use, although four may be restricted from access mechanically due to the connector hooked to the driver/receiver boards.

While I could drive an LED on any single line to about 30ma safely, To be sure of protecting the FPGA chip, I used a high-ish limiting resistor giving me a faint illumination. I set up 16 lights initially, leaving four connector positions for future expansion of my diagnostic input/output.

I used it to check my state machine fix for determining when the 1131 is in XIO phases E2 and E3, as well as double checking the validity of the XIO type bits at the time I am sampling them. I spent a bit of time getting the lights working to my satisfaction which required smaller resistors, before moving on to the debugging of the XIO phase shadowing. One of the 16 is not working, probably due to a wire breaking off the fragile connectors, but if I disturb the wiring to fix this, I will likely break others.

Next, I discovered that none of my shadowing machines are advancing, but also I wasn't seeing DCReset or other signals I should. Something pretty basic is awry here. I am not sure what changed, but suddenly it was all working properly when I resumed testing. The great news is that an XIO Read is doing what it should - storing the data value from the peripheral device into the core location specified in the instruction's IO control word. I changed the data pattern and location just to double check, but it works nicely at both single step and full speed.

XIO Read (stores data into core storage)
I then moved on to some instrumentation using the lights to verify that XIO Write will lock in the data value from a core memory location specified in the IO control word, making it available to the peripheral device. Another test was that XIO Control picks up and saves information from the IO control word which will be used by the peripheral

As well, I checked that the XIO Initiate Write picks up and saves the memory location of the Word Count Area, a table with a word count as the first location and then data is stored or fetched from sequentially increasing addresses as the peripheral does its IO.

XIO Init Read and XIO Init Write 
The test of XIO Write was successful - it picks up both the modifier bits from the second word of the IOCC and it latched the data fetched from the core location stored in the first word of the IOCC. Similarly, the XIO Control succeeded, locking in all the bits from the IOCC word 1 and modifier section of word 2.
IO control word and write count area
The test of XIO Initiate Write was unsuccessful, failing to latch the data (or resetting it at the end of the instruction execution, which is equally useless). Looking through the logic for the XIO Init Write, I found the problem was even simpler. Since XIO Initiate Read and XIO Initiate Write both fetch the WCA and modifier bits, leaving the IO device adapter to handle read or write, the two modules are essentially copies of each other. Too much so, because my XIO Init Write didn't look for the XIO type code "101", it was still looking for "110" which is what was in the XIO Init Read code.

Corrected logic was tested and now both XIO Init Read and XIO Init Write are working perfectly. All seven XIO function types are ready to use, as well as fetch and store using cycle stealing. The box can trigger interrupts on Interrupt Levels 2, 3, 4 and 5, as needed. This completes the 1131 side of every IO adapter - the other side is concerned with signals to and from the specific device being controlled.
Cycle Steal operation
If I can get my PC link working properly, I can put the device side of an IO adapter into the PC, creating various virtual peripherals. The bulk of the functionality needed to complete the support of virtual devices will be complete when the PC link is working properly.

The other purpose of this box is to support various physical peripherals, building their IO adapters fully in the fpga or in a hybrid of the peripheral and a microcontroller such as an Arduino. I have a backlog of physical devices to implement - additional disk drives (my CHI drive and several DEC Rk05s), a tape drive, paper tape reader and punch units, a plotter, and a 2741 typeball style APL terminal.

RK05 drive, physically compatible with 2310 drive in the 1130
Video of IBM tape drive in operation - I have same model

Plotter I will mimic with a smaller drum plotter

2741 terminal for APL use, I have a very similar terminal from a Dura word processing systems

1055 paper tape punch, I have several paper tape units to mimic this

Friday, April 17, 2015

SAC Interface Box working perfectly for cycle steal and Sense Device operations - testing continues


The board maker sent a modified version of the SDK library with a longer timeout, which I will try to test whether it resolves the failures writing to the flash. It did not make a different. I have a few possible resolutions:

  • rework the board to replace the SPI flash chip
  • send the board back for a replacement
  • build a board to sit on the JTAG lines, hold the bit image and initialize the fpga at startup
If the problem with the timeout is the flash chip itself, my rework will fix the problem. However, if it is a problem with traces on the board or a failure in the USB chip, the change won't resolve the failure. 

It takes a few weeks to send the board back and forth to Germany, at least at any reasonable postage rate. It would probably be more cost effective to simply order a second board and eventually swap it into the box when it arrives. 

I am assuming I can get access to the JTAG lines from my board, but I haven't researched it fully. Since FPGAs normally load their bitimage over JTAG at startup, this is a reasonable method although it may be complicated to write each changed image to the daughter board I would build to provide the new function.

I ordered a couple of the flash chips from Digikey, because as I read the data sheets for the chip, it became clear that it has modes where it can protect portions from writing yet resetting the configuration to factory default state is not possible. My chip may be wedged in some strange state, even though it is otherwise functional. 

There are several resistors and other components nearby the flash chip, which would require good shielding before I used my heat gun to remove the flash chip. On the other hand, I can snip off the eight leads, remove the chip, then clean off the remnants of the leads using my small tip on the soldering iron. That would allow me to solder the replacement chip into place while having avoided any desoldering or heat damage to adjacent parts.

SPI Flash chip to be removed and replaced with new stock

I found and fixed the partition of my ground network inside the SAC Interface Box. Testing resumed on Friday lunchtime, when I had a chance to begin checkout of the newly built driver board. In short order I discovered a wisp of ground wire blocking one of the Channel Address In bits, corrected it, and then confirmed that all Channel Address In bits are working correctly. In addition, all the Channel Data In bits are working. Further, interrupt request, cycle steal and other lines are good.

I tested this by repeated Cycle Steal Store operations to a succession of addresses to test out each address bit, from time to time varying the bit pattern that was stored in order to validate the data lines at the same time. Once that was complete, I had the processor execute one instruction, XIO Sense DSW to my pseudo device at area code 21 (decimal), which received my status word 0x1130 in the accumulator.

It is time to work on two different sets of tests. One will test the pseudo-device for its operation with XIO Read, XIO Write and XIO Control. The other will work on establishing the PC transactional link allowing me to transfer control and data signals needed to emulate any peripheral from the PC. It will also give me the means to load and dump the contents of core storage on the 1131 to the PC.

I am working through my XIO Read logic - which did not store the value I expected into storage at the target address I intended. I am reviewing the logic for the function in preparation for some diagnostic testing. All I know at this point is that I am not emitting the Channel Data In values nor setting the Channel Write Gate. This would be symptomatic of an FSM failure, either the FSM in the XIO Read module or the shadowing routine that should be recording when I am in the various E phases of an XIO.

While mildly annoying, this is exactly the sort of debugging I should be doing, with the basic receiving/driving of signals to the 1131 now solid.

Thursday, April 16, 2015

SAC Interface wiring completed, minor snag to fix then back to testing


Got out to the garage in small bursts to continue wiring in the 1131 signal lines to the new driver card. As of lunchtime I had five of the seven chips wired, a total of 30 of the 41 lines were attached. Perhaps another hour of work to complete the remainder, sometime this afternoon or early evening, then I can power it up and test everything.

Finally, by late afternoon, all the signal wires were attached, I had checked for shorts, and the board had its power and ground lines attached to the rest of the box. Testing will involve a number of different addresses and data values, until I am certain that the lines are hooked up correctly and can be driven to both 0 and 1 states. The attachments are cleaner, easier to check and appear to be more secure.

I found one pin that appeared soldered to the trace on the new board wasn't really in contact - easily fixed. Things were looking good with the board, but I seemed to have lost part of my ground circuit inside the SAC Interface box, which blocked my testing switches from working. They pull signal lines down to zero to activate, but if the ground circuit isn't good . . .

I had to spend the rest of the evening ensuring that all the power and ground lines were correct, postponing testing until tomorrow.  My testing of the fpga board with the 'flashbench' example program got the same failures trying to write the first sector - repeated this on two different PCs. Waiting for word from the board maker.


I found two HP alignment cartridges on eBay - one listed as new but for a very high price, the other available to buy immediately at $40. I could see that these cartridges are recorded for the higher density version of the drive - double as many cylinders and a higher bit rate - but physically it is compatible.

I can adjust the alignment of my 2310 drive, simply dividing the cylinder on the HP cart in half to get the 1130's arm positioned to the same spot on the platter. I should be able to scope the signal and maximize the signal as a means of aligning my drive to the standard positioning. This aids interoperability of cartridges moved between different drives.

1130 Cartridge has 203 cylinders, with two HP tracks where each 1130 track sits
The less expensive cartridge appeared very clean so I took a chance. When I picked it up, I could see it had been properly stored, with no contamination or dirt on the platter surface.

Top platter looked clean as a whistle

Bottom of the platter equally nice

Wednesday, April 15, 2015

Wiring in newest driver board


By lunchtime I had the new drivers board mostly assembled, but hadn't yet begun wiring the signal lines to it. In the late afternoon, I set up again to begin the careful transfer of all the fpga lines first, since they are in the 'inside' near to the chips while the 1131 lines attach along the outer edges. This version of the board allowed me to connect the individual signal grounds near the signal connections.

By evening, all forty FPGA lines were installed and I had begun on the 1131 lines. Seven of the 41 output lines are installed along with their grounds, Tomorrow I can continue until the board is ready to test.

Meanwhile, I could run the 'flashbench' example to determine whether the fgpa board and its flash chip is working properly. It fails trying to write to the flash chip, which is pretty definitive for a hardware problem with that chip (or the USB interface chip). I will post these results to the board maker and see what they recommend.

Tuesday, April 14, 2015

Two steps forward, one step back - the motif of the SAC Interface box


I picked up new 74LS06 chips and built one to handle the bad circuits on the Channel Address In lines. Some quick construction and wiring got it into the SAC Interface box, ready for testing. Indeed, the three bits now worked properly.

In the process of wiring it in and testing, I broke off one wire (Channel Data In bit 15) and seem to have disrupted another of the address lines. I don't have the time tonight to chase it down and frankly, the driver circuits have become so ratty, patched upon patches and extended, that I may be permanently spiraling down with each diagnostic run or fix breaking something else.

Time to build an entirely new single board for the 41 driver signals, carefully wiring the fpga and 1131 signal lines to the new board to get me to a clean new base from which I can verify functionality. I just don't trust the shoddy mess the current instantiation has become.

I have all the parts in house to do this, but it will take several hours of careful work. Meanwhile, I am working with the Ztex board maker to guide me on the problem I am having writing the fpga bitstream to the onboard flash. He has suggested a reasonable step, using one of the example programs included with the SDK because this makes use of the flash chip.

Sunday, April 12, 2015

Homing in on last issues with cycle steal addressing and the basic bidirectional USB link from SAC Interface box to PC program


I posted a question to the maker of the Ztex fpga board before I rework the board to replace the SPI flash - since it may be a logical state that I can correct without desoldering and changing the chip. I will wait a few days to see if there is a simple fix before I order a replacement flash chip.

I spent a couple of hours exhaustively testing each Channel Address In bit for cycle steal store and determined that bits 8, 12 and 15 are always read as 0, regardless of the value I believe I am emitting. These are the three bit positions that were bad previously when I thought I had fixed things moving over to spare gates.

My next move was to electrically test these while they should be set to 1. I found them to correctly sit at 0 when they should be off, but I didn't test the other condition when they should float up to 1. As the results had hinted, these lines were frozen down at 0 regardless of the input for two of them, and the third a funny input. Grrrr. All three of these are on the same card in the 1131, thus if I find the problem is here, I can swap with the card handling bits 0 to 7 to see if it floats with the card.

I wasn't happy with the logic for the fpga side of the link, the part that writes words or reads them. I isolated this from the transactional FSM and the output FSMs, which should make debugging of the link operation easier. The first instantiation was a simple echo function, so that whatever was written to the fpga on endpoint 6 would be written back on endpoint 2.

If the Python program couldn't write words and read them back correctly, the problem was likely on the PC side not with fpga logic. I ran out of time to test them due to family obligations, but I can get to this during the coming week. 

Slogging away at SAC Interface unit


Up until mid morning of Saturday, I was completely engaged in building up fpga logic to support PC emulated peripherals, and making corresponding changes to the Python program that runs on the PC side. This extended beyond the simple functions I needed just to finish the cycle steal fetch and store operations when requested from the PC side.

These extensions will be needed to move to the next level where I appear to be a card reader, printer, punch, plotter or other peripheral so that I can do useful things bypassing physical punched cards and paper.

My first tests on the machine were to determine what was failing with the two channel address in lines. The gates were not functioning on the two chips involved, but I had a few spare gates in another location on the board. After I relocated the wires to the replacement gates and tested, I was able to set up correct addresses for cycle steal fetch and store. I still need to do a more exhaustive walk of the address range to be sure everything is good, but it is promising.

I did a few tests storing at different fixed locations and am not satisfied - so more Channel Address In testing. The data side works perfectly, giving me the right pattern each time, but addressing still needs work.

I began testing the new two-way link functionality between PC and fpga - rather than continually sending the status information as I had before, the protocol has the PC requesting a transaction with two words sent out over USB. For most transactions, the fpga will echo back the two words, which allows the PC side program to check for transmission issues.

The original status messages are now sent in response to a particular transaction, eleven words of status data followed by the two words sent to start this transaction. Some transaction types are asking for data to be returned - for example the two words asking for a cycle steal fetch will come back as the original first word (the command) but with the retrieved data as the second word.

This will take some time to wrestle with the code until it is sending and processing the transactions as I designed them.

Thursday, April 9, 2015

Some changes made to SAC Interface fpga logic while on business trip

On my way out to DC, my flight flew within about ten miles of the former home of my 1130 system, in the midst of Kansas. It was hazy enough that I couldn't see the roadways and approximate location, which might have been discernable had the air been very clear.


While flying to DC, I designed and coded the transactional FSMs as well as the messages and protocol which will be used between the PC program and the SAC Interface box. With this in place and working (and once I resolve the issue of Channel Address In that selects which word in memory I will be reading or writing) I can immediately get value from the box. First up will be a facility to load core or dump core using PC side files, in the IBM 1130 Simulator format.

I did more coding on the return flights, allowing me to begin some testing soon after arriving home. There was quite a bit of logic change to the fpga side, but it also required changes mirrored in the PC side program which is still to do.

Monday, April 6, 2015

Some work on the Channel Address In flakiness

I have a trip this week to Washington DC which will take me away from the restoration for three full days. Today I could squeeze in some work, while getting ready for the trip, but most work will have to wait until I am back at the end of the week.


I changed the fpga logic to support a bidirectional flow between the PC program and the SAC Interface box. In addition, rather than sending a stream of status, which was the initial behavior, I now have a transactional engine which waits for requests from the PC program and executes. The first transaction types are Send Status, Write Word in Core and Read Core Location.

With these, I can load software, e.g. diagnostics, into the 1131 memory and execute without needing to read it from cards or disk. Later, of course, I can create various emulated devices to respond to XIO instructions.

I went through enough variations on data bits being fetched to be assured that my Channel Data In lines are correct. I then worked on the XIO Sense Device for area code 21 which I had set up to return 0x1130 (the most appropriate first value to store in this system). It worked when single stepped but when run at full speed I only got some of the bits.

I am not sure what is occurring and need to use the scope to watch a full speed operation.

The other problem, of the erratic channel address in values, seems to be more than just the two stuck on bits. When I probe the driver card, I can see that the fpga outputs a 1 which should drive the chip output to a low voltage, but the out line remains up at 2.9V. I may have bad chip circuits, as I did in another chip.

An additional puzzling problem was when I changed the address for a store to 0x3FFF which should have been high memory, but although i was writing and reading a value I set up, I couldn't find where in memory that took place. The cycle stealing operation does not display the memory address being used, all we see is the M register which is bypassed in order to gate in the Channel Address In values we emit. More investigation is necessary here. Perhaps I have too much latency after the operation of the FSM, so that the Channel Address In value is not fully set up when it is used to issue a memory read. I will emit it earlier in my FSM just to be more confident that I am driving the proper address.

Sunday, April 5, 2015

SAC Interface cycle stealing fetch and store work perfectly other than some address bit issues


I removed any contributing signals that might affect the Channel Data or Channel Address In lines, as well as those controlling Channel Write Gate, just to be sure that I don't have a flaw in some other part of my interface logic injecting bits improperly.

Testing had to wait due to family obligations, but late in the afternoon I was able to sneak in for a brief test or two. I was still seeing the behavior but had a bit more feedback from the state machines to examine.

The machines are working correctly, but something caused me to check the correctness of the cabling of various Channel Data In and Channel Address In bits to the driver circuits. I found both registers to be a bit scrambled in their assignments, which needs rectification if my tests are to make any sense.

It took about an hour to continuity test all the bits between the 1131 entry cards and the driver card in my box. I then verified that my fpga to driver card signals were in the order I expected. There are 18 signals that are mis-connected, requiring changes to the fpga logic to reconcile them. I now have a definitive record of the connections and will update all my documentation.

With the documentation updated and the FPGA logic corrected, it was time to head out and test again. Having scrambled address bits certainly creates an Easter egg hunt through 16,384 addresses to find the one memory word I wrote to with my test. In hindsight, had I simply picked location zero, I could have at least checked that cycle steal fetch and store are working before I had to debug the errant wiring.

With the changes made, I fired up the system, set to both store and fetch into location 0x0020. I had set it up to store the pattern 0x1130, did a store cycle and then a fetch. The machine had been zeroed out using the Storage Load switch on the CE panel, but after the store and fetch were done I had retrieved 0x1130. The data was not at 0x0020, so it was time to figure out what was wrong with the address bits.

Using a voltmeter when the machine was in the midst of the X clock cycle, I found that bits 9, 10 and 15 were on - when I expected solely 10 to be on. That corresponds to location 0x0061 which I quickly checked with the console display mode. It had the 0x1130 pattern!

I then manually loaded two other patterns in the word at 0x0061 - first 0x5555 and then 0xAAAA. Both were correctly fetched when I commanded a cycle steal read operation. Once I figure out why bits 9 and 15 are on when they should be off, and correct whatever is the cause, I will have full cycle steal functionality.

Further, this makes me optimistic that the remaining XIO logic will work with minimal debugging. I used part of the logic to inject bits in when executing an XIO Sense Device for a device at area code 21, this used quite a bit of the 1131 side of the adapter functionality. I already know that I can force interrupts on the four levels, just to complete the set of all 1131 interactions I need to act as an IO adapter. 

Saturday, April 4, 2015

SAC Interface cycle stealing access to 1130 memory is functional


I had set up two buttons to trigger cycle steals - a fetch and a store - to specific addresses. I expected to see displayed on the PC whatever word I placed in location 0x0020 after the fetch and to write the value 0x1130 in location 0x0030 for the store operation. After they are working, it would be a good test to try to write to location 0xffff and see what location is actually updated - this would test the validity of all the channel address in bits.

My first test was not perfect but very satisfying. The fetch did pick up data, although the value wasn't what I expected. It was consistent from run to run. The store appeared to work also. First step is to scrutinize the logic in the fpga, then to do some diagnostic variations.

After some additional instrumentation, it is clear that my FSM for cycle stealing store is apparently correct but until I can figure out what address it is storing into I can't check it. I will try the fetch version and see what I discover.

One of the address bits, bit 4, is stuck on - but once I knew to look in location 0x0820 I found my pattern of 0x1130 nice as could be. Store via cycle steal working and definitely triggering memory cycles. I still need to resolve the bad bits on Channel Data In and Channel Address In.

Cycle steal fetch was dredging up a constant value of 0x1320 at all times, more work will be needed to figure this out. It may be a result of when I am latching the value of the B register or it could be a problem on the 1131 side. Testing continues.

I seem to be emitting the pattern on Channel Data In during fetch, not just during the store cycle, but I just don't see the path to make that happen. It is going to take more diagnostic data sent over the PC link to get to the bottom of this.

My suspicion centers on my fpga logic since that is the newest logic, everything on the 1131 seemingly has been working fine all this time. I will tighten up the logic and add more diagnostic information until I know a definitive cause. 

Friday, April 3, 2015

SAC Interface testing and logic improvement


I went out to further test the circuits for Channel Data In bits 0, 5 and 8 which didn't seem to transfer as a 1 when they should. My tests included proper resistance, voltages as measured at both ends of the cable, and voltages on the output side of the SLT card gate. Bit 5 wasn't even bad, it was burned out bulbs on my console display panel. Only real problems are bits 0 and 8.

I discovered that in spite of my beliefs to the contrary, bits 0 and 8 did NOT have proper continuity to the input pins they should. These are the pin D02 of the SLT card for the two cards that span the top and bottom halves of the input register. I see good resistance and get the +2.975 V on the pin on the backplane and my driver board. However, when the driver board pulls that wire down to zero, the voltage at the SLT card pin is still +3V, not low. Something is interrupting the action but I am not sure what at this point.

Ah, for the schematic for the SLT card. Still, I will poke around until I find what is different between D02, the input for bit 0/8 and other input puts such as D04 which represents bits 1/9. Might be a socket problem, a backplane problem, a connector on the backplane or something on the card which is particularly susceptible to failure with time.

Continuity checking definitely shows the driver output in my box is connected to the input pin where the cable enters the SLT backplane and as well to the entry pin on the SLT card. Time for another test, in case I scraped off oxide on the connectors as I reseated everything on the SLT backplane. Otherwise, time to start testing the two cards themselves. It is hard to imagine that the same error occurred on two cards simultaneously, unlikely but not impossible.

Meanwhile, I updated my FSMs for the other XIO functions and for cycle steal, now that I have reliable mirroring of the clock rings and XIO E phases. As usual, I reached a point where I was fighting with the Xilinx toolchain for quite a while since it was stubbornly refusing to notice that I had changed the signal list in a submodule and its instantiation in my main module - keeping the old definition somewhere.

I decided to set up buttons to trigger cycle steal read and write, in order to test out those functions. Cycle steal will be the first time I try out the other two SLT cards, those that receive the Channel Address In register signals.

Thursday, April 2, 2015

Channel Data input for XIO instructions and cycle mirroring logic working on SAC Interface box


I whipped up some test code and fired up the 1130 for the XIO Sense Device test on area code 21. No signs of response. Time to instrument some more diagnostic information into my fpga logic and python program.

I also thought of a more reliable way to be mirror the T and X clock state of the 1131, using a pair of FSMs I will create. This way I can time actions to any clock state and to either phase A or B within the state. A third clock will be defined to track XIO execution memory cycles, e.g. E1, E2 and E3.

The problem this solves is that all we are receiving are levels telling us when we are in states T0, T2, T4, T6, X0, X2, X4 or X6. We may wish to time activity by the missing states such as T3, T7, X7 etc.

Although the existing clock state signals are no all-inclusive, we can use these to ensure the FSM is tracking properly, using the CPU Clock Out as our primary stepping signal but kept in check by the clock state signals. CPU Clock Out moves the rings forward and also defines whether we are in phase A versus B, the front and back half of each machine cycle (clock value of 1 versus clock at 0.)

Once I see these working properly under single step mode, I can run the machine at full speed and see that these seem to be tracking properly. They will be the foundation for controlling the various types of XIO, for signalling interrupts and for handling cycle steal read or write.

On first test, my T clock mirror worked perfectly but I didn't seem to get the same good results on the X clock ring. I also found that the X6 and XIO E1 lines were touching, requiring a bit of cleanup on the receiver board.

With that fixed, it appears that I am triggering my DSW store process for the XIO, however since the value is all zeroes it is not definitive. I looked at my logic to see why I am not injecting the pattern I expected into the register. I then found another wire wisp bridge, this time to the T4 incoming state. With that fixed, my state machines where shadowing T clocks, X clocks and the E phases of the XIO instruction.

Also, my logic for Sense DSW worked properly, however the data returned was only the bottom half of the register - while I sent 1 bits, the top half of B register remained all zeroes. I began looking into continuity of the wires and other electrical issues in my link.

There is still an electrical/wiring problem with the lines for Channel Data and Channel Address in - they are not pulled up to 3V as they should. All the offending signals run to the same type of card, a 7196 SLT card, but with each card handling 8 signals the problem is common to all four cards. I see a reference in the ALD to the incoming lines showing them running to items labeled 'resistor', which should be the pullup devices yet I don't yet know there to look.

I could go through and install pullups on my side, but that is not how the machine is supposed to work. I need to figure out what is wrong and correct it. I will also pull one of the 7196 cards to see if the resistors are mounted there. It would definitely help if I could find the schematics of that card, but so far it is not in any of the material I can find online.

I opened the card compartment to take out one of the 7196 cards for a quick examination, when I got quite a surprise. There should be four of these cards, two in slots B6 and B7, the other two in slots E6 and E7. I found a gaping hole at B6 - the card responsible for the high half of the incoming data bits. This certainly explained the failure to set them to one. E6 and E7 were correct, plus I saw one more 7196 card sitting in D6.

Looking at the card map for the compartment, there should be nothing in slot D6. I tried to move the card over but couldn't insert it. Looking closely at the socket, I could see that a plastic guide piece broke off the original card and was blocking insertion. I pulled the nonessential guide piece and inserted the 7196 card.

I did a quick power up of the 1131, without any power on my SAC Interface board, and now see voltages on the channel data in lines where before there was no pullup. There must be a series circuit of some kind that requires all four cards inserted to power the lines. This of course means that I have to cut away my pull-up resistors on the driver board for all that are working properly then I can do a power-on test.

My first check is to look at the resistance of these lines now that the card is inserted - any that are less than 100 don't need a pullup on my end. I found that all of the lines to the newly discovered card could have their pullup resistor cut off my driver card.

I did a power up of the 1131 and tested voltages with no power to my SAC Interface box. All I could reach were correctly at 2.975. I then ran the XIO Sense DSW to area code 21 and found x7B70 in the B register. I was trying to emit an xFFFF. I checked the signals coming out of my box and all sixteen bits were pulled low. It should have registered as xFFFF.

I then did some continuity testing of the lines for bits 0, 5 and 8, the ones that didn't show up in the accumulator, using a VOM. My thinking was that I might have a cabling/continuity issue, it might be a termination problem, or there may be a flaw on the 7169 cards. It would require two bad circuits on one card and another bad circuit on a second, something I am not ready to accept without testing.

The continuity test was unfortunately successful - bits 0, 5 and 8 are connected from the input in of the 7169 receiver board right to the output pin of my driver board. Further, I see that my driver board is pulling the line down as it should. I will prepare to scope the lines at the 1131 backplane and make other tests to figure out what is causing this issue.

It still could be a circuit issue outside of the SLT, although I am prepared to deal with the issue however it turns out. Facts first, then plan the resolution. Focusing on the positives, I have pretty decent logic for responding to a XIO Sense Device, will only get more solid now that I have such reliable T clock, X clock and XIO phase mirroring.

I also had a very nice insight today. I had been assuming that any peripherals I attach or emulate using the SAC Interface box would have to be different from the physical devices on my system - assuming that the adapter logic in the 1131 would always be responding to XIOs for that area code.

However, I realized that all I need to do is block one signal going to the adapters - the XIO E1 signal - and they will never "see" the XIO with their area code. Instead, my SAC Interface box could respond to any area code as long as its adapter is blocked.

The big limitation to this is that not all interrupt and cycle steal levels are available via the SAC interface. Specifically, I can't trigger interrupts on IL0 or IL1 and I can only do cycle steal on level 1, not on CS0. The cycle steal level isn't really a problem as long as I prioritize CS among devices properly.

The show stopper is the limit on IL0 and IL1 triggering. The 1442 interrupts on IL0 for each column, which is how the software knows to issue an XIO Read or XIO Write for that next character. Similarly, the 1132 printer interrupts on IL0 to indicate that the next character on the rotating print wheel is ready to be read with an XIO Read and then the printer can cycle steal to fetch the hammer firing mask.

I can pretend to be the 1442 reader for a single boot card, because the hardware is blocking recognition of the interrupt and using the condition to force gate in each column to ascending words. I can just cycle steal to write all eighty characters, then push Imm Stop, Reset and Start (instead of Imm Stop, Reset and Prog Load). It won't help read a second card, since that needs IL0 for the software to work properly. Still, if I boot a card that then tries to read from a 2501, that is a device I can emulate.

As I looked at the 1130 and other gear in my two-car garage where I am restoring it, I realized that the space is about the same as the machine room where my first hands-on computer was installed - the room had an 1130 with 32K words (the full length model like mine), an 1133 Multiplexor box, a 1403 line printer, a 1442 reader/punch, and a 2310 model B with two additional disk drives to complement the single drive inside the 1131 cabinet.

It too was on a concrete floor with cables visible as they ran between the units. A different complement of peripherals, more memory, faster cycle time, and the machine from my past had the red "Garnet Rose" colored doors while mine is painted in "Sunshine Yellow", but satisfyingly, nostalgically similar. 

Wednesday, April 1, 2015

Validated last of the lines for the SAC Interface box, ready to begin testing certain FSMs

I spent some time at the Computer History Museum today, rather than working on the 1130 system, plus the usual day job workload, but I did managed to make some progress on the SAC Interface.


I modified my fpga logic to emit zeroes for both channel data and channel address lines except when the XIO E1 signal  is on. This hopefully will help me do the verification of the incoming data lines, using XIO instructions.

When I fired up the system for a test, I was no longer cramming bits onto the B register line, which is good, but without raising the Channel Write Gate line at the proper time, my Channel Data In bits won't be seen. They certainly are not visible on the console. XIO E1 is dropped by the time a normal adapter would be putting up the sense word.

I used my VOM to do some continuity testing between the 1131 backplane for various key signals such as Channel Write Gate, Block Clock Advance, Meter In and Advance IO Entry, and the pin on the SAC interface cards. This let me definitively identify the correct line for each of those signals. I also cross checked XIO E1 while I was at it.

Now that I am sure of the signals on each line and the correctness of my circuits to drive and receive them, I am ready to try out my cycle steal FSM as well as a sample Sense DSW FSM. These are coded up in my adapter logic, but I will work on a shortcut to trigger the cycle steal read and cycle steal write FSMs from two of the temporary buttons I have attached. The Sense Device FSM will be set to trigger on any area code, so that it will respond to all XIO Sense Device commands.

Tonight I will work on the changes to trigger the FSMs as described above and some other test support functions, in preparation for testing of low level behaviors such as cycle steal read or write of a memory word and device sense presentation.

I will also put in some diagnostic output information on the USB link to the PC and display it in the Python program, to help me see what is happening inside such as the state of the FSMs and their outputs. 

Breakthrough on SAC Interface


I set up the FPGA logic to emit a non-zero pattern on the Channel Data In lines of 0x5555 which should show up if I do an XIO Sense Device to a non-existent area code (peripheral address). The peripheral adapter logic for every device is watching for the XIO E1 signal. The adapter logic that as the same area code is the only one that is allowed to set up non-zero bits on the Channel Data In lines.

The Data in lines of all peripherals are wire ORed together and transferred to the B register. With a Sense Interrupt version of XIO, all device adapters that can interrupt on the selected interrupt level must raise the bit for any condition for which they requested an interrupt. Since more than one device could interrupt at the same time, they are assigned specific non conflicting bits from among the 16 possible positions and thus the wire-OR might produce an interrupt status answer in the B reg that has bits set by more than one device.

For all other XIO command types, only the device being addressed is supposed to raise any bits during the XIO E cycles (E1, E2 and sometimes E3), while the others have all bits set to zero. If I am raising every other bit (through the pattern b'0101010101010101 I set up) then that is wire-ORed for any XIO E cycle. If I picked an existing real peripheral, such as the printer, then its adapter logic would be raising bits also, but if I choose an address for which no adapter logic is configured, then only my bits will be transferred to the B reg.

This method will let me do a SMC mode stepping through an XIO instruction and watch the value of the B register as a way of testing how my Channel Data In lines are working. It would have been nice to have a similar stepping mode for cycle steal operations, allowing me to see the Channel Address In values I am sending and verify that I am reading or writing from that word in memory. However, the X clocks run at full bore through all eight states, they can't be manually stepped as we can with the T Clock cycles.

The way I can check out the cycle steal is to set up the sequencing logic and some target addresses and data patterns. Then I can verify that a certain value is indeed stored in memory at the chosen address after I trigger a cycle steal with the channel write gate involved. Without the write gate, it is simply a read of an address into the B reg, no update is done.

Cycle steal requires that the Channel Data In and Channel Address In lines only be raised at specific times during one cycle of X0 through X7 states. Further, The channel write gate line is only to be activated during certain of these states. I can't just turn all the lines on and hope it works properly. I have a finite state machine set up to process a cycle steal read or write, which I will trigger as part of my testing. Since the FSM depends on watching such signals a CS Level 1, X0, X2, X4, X6, Osc Phase A, CPU Parity Stop and the B Register, they must be correct before I can use them to control the cycle. I don't yet know for sure that CS Level 1 and the four X states are working properly and coming in on the intended pin, making that validation a mandatory pre-requisite to any cycle steal operational testing.

I already have all the signals validated that I need for handling XIO instructions - signals such as Osc Phase A, Clock Out, CPU Parity Stop, XIO E1, T0, T2, T4, T6 and the B reg - and know I can fire off the interrupt requests, so as long as I can send in device status or data values on the Channel Data In lines I could act as the adapter logic for any non-cycle-stealing peripheral. Then, when I get cycle stealing operational, I have the means to handle any device behavior.

One side of my SAC Interface box handles the duties of a device's adapter logic, handling XIOs, interrupts and cycle stealing. The other side either communicates with a PC program or drives a real peripheral of some type. I have a paper tape reader to look like a 1134, a paper tape punch that appears to be a 1055, a plotter that maps to a 1627 modle 1, and a IO Selectric that can appear to be a 2741 terminal.

In the middle between the sides is the ability to modify the behavior of the physical peripheral to make it appear to be a known 1130 device - emulating a device. For example, it may connect to a Documation card reader on one side and implement a device adapter using the area code and interrupt assignments of a 2501 card reader. In the middle we can map the behavior of the Documation to act the same way as a 2501 would.

Other real devices I can connect include three DEC RK05 disk drives and on CHI disk drive, all of which could emulate 2310 disk drives. I have an IBM 9 track tape drive from an RS6000 which can appear to be a 2420 drive. There is an HP line printer which could emulate a 1403 line printer.

Right after I woke, I took a few minutes to complete the testing of the remaining driver circuits, cutting the pullup resistors off for all that had working resistors in the 1131 side circuitry. Now the drivers are all set up to work properly, allowing me to resume testing. First up is verification that I can trigger a cycle steal by driving CS Request, giving me appropriate return signals of CS Level 1, X0, X2, X4 and X6. I should see the X7 lamp extinguish on the console when cycle steal is operational, as well as the return signals mentioned above.

Testing had to wait until I had some free time during a busy workday. I ran out and spotted a few anomalies to investigate:

  • Somehow I am triggering an interrupt on level 3 - have to check that the wire didn't come loose on the driver circuit or some other problem occur. 
  • X2 phantom detection on the PC screen, but should be seeing it. 
  • One of the final driver circuits, number 40 which is probably the CS Request, is not behaving properly. It is pulled up to 2.9V but when I give the inverter a logical 1 as input, it remains at 2.9V rather than dropping down to near zero. 
Perhaps there is a bad gate in the chip for the driver circuit 40, will swap to the spare gate and see what happens. VOM and scope probing will tell me whether the X2 line is an 1131 source problem, a receiver circuit problem or a defect in my PC side program. I can also use the VOM to check out the driver circuit for interrupt request level 3.

I discovered the cause of the three problems above. I had a broken wire on the input to the interrupt request inverter - fixed. X2 flickers came from a wire wisp bridging X2 to Parity Stop which gave the intermittents - fixed. Circuit 40 was a bad inverter, moved over to the other circuit and it was fixed.

I still wasn't seeing any cycle steal activity when I forced any of those four signals on. I even swapped the lead I believed to be the mostly useless Meter In in case I had it wrong, but still no joy. Then, I had a dim memory from the earliest days of the restoration, when I was seeing data coming in spuriously and in my debugging, I remembered setting some jumpers to block certain signals.

I pulled out the ALDs and looked at the sheet with the configuration jumpers - a list of conditions, e.g. No 2501, and the jumper setting for that condition. I saw two entries labeled No SAC, with jumpers on gate B compartment B card B6 and card B7. Referring to the logic, I discovered these would block cycle steal 1 requests and block another related signal come from my box.

I swung open the gate and saw two red jumpers glaring out at me, causing my inability to request cycle stealing. I yanked them off and powered back up - now I could cycle steal!

I used the cycle stealing and my scope to identify the association of receiver circuits to the four X clock levels - X0, X2, X4 and X6 - which was an important validation of the reliability of the signals that will step my finite state machines handling cycle steal activity. When the 1131 was in Run mode, when I pushed my button I would see the X7 light extinguish and see the X clock pulses on the scope.

When the machine was in Single Step mode sitting at T7, I expected to see the X7 light extinguish in the same way, based on my believe that cycle steal operations ran at full speed rather than being stepped. It didn't happen. I left the cycle steal request on and pushed the Start button on the console, which normally would step from T7 to T0, but instead the machine stayed at T7 and turned off the X7 light. I realized that I was wrong. It is possible to step through the eight X clock states manually.

Stepping one push at a time let me double check that I had the right sequence for the X clock signals. I am not sure if I can see the channel address and data in/out with the console, but I do have other ways to check this out.

Next up was to issue an XIO Sense Device and see what pops up in the memory location. I had set up the fpga logic to emit a non-zero pattern on data in, which had the effect of forcing those bits onto the B register at all times, not just during the XIO. I need to be much more nuanced in when I emit bits on the data and address in registers.