Monday, February 29, 2016

Virtual 1442 card reader/punch functionality working to my spec, trying to run 1442 diagnostics now


Debugging the virtual 1442 functionality

First chance to get out to test was lunchtime today, when my first test revealed a flaw causing me to only fetch the first card column in the read emitter process. Quickly changed, then glacially synthesized and made ready to load into the ztex board. I got one more shot at the read test before my afternoon client calls began, and took it. Reading is now working perfectly.

Late in the afternoon I went out to begin testing the punch functionality, when XIO Control specifies a Start Punch operation. The punch emitter process will 'loop' up to 80 times, once per column. It stops early if bit 12 of a fetched word is set on, meaning we are punching only up to this column, otherwise it goes the full size of the card. The interrupt handler software will issue an XIO Write for each interrupt on IL0, thus punching each column. I should be saving these output words in the pre-punch buffer and then writing them up to the output (stacker) files.

There are two tests to run here - partial card and full 80 column - where the goal is to see if the new punched 'holes' are added to the card previously read (from the pre-read buffer) but any prior contents are preserved. The partial card should leave all the remaining columns untouched. This involves ORing together the previous contents of the pre-punch buffer plus the output word as captured during the XIO Write. My first test of this showed that I was successfully ORing but also doing it during the copyover from pre-read to pre-punch, when I only intended to do it for XIO Write.

With some changes inserted to isolate the OR activity to card punching, but not the copy-over between the two card image buffers in the 1442, I found it all worked well now. I could punch short records or the entire card, it would overwrite existing 'holes' in the card images if they were not blank, and everything for reading, punching and feeding now looked perfect.

The final area to test was the boot function - extract the current card in the input file, translated to the special Program Load format, and write it down to core memory locations 0 to 79. I tried it, found that memory was properly loaded exactly as it should, so I went ahead and tried a deck which was a boot card, the diagnostic monitor and then the 1442 functional test diagnostic program. Why not go all out to test this virtual 1442?

My boot card stopped with a wait 30F2 which means that the DSW was not right. The stored DSW was completely blank, but it should have had on the operations complete DSW for the card reader I guess. I will need to make some change to drive this bit on when I push the "Boot" or Program Load button for the 1442.

First, however, I need to prove out that boot is working properly. I brought over the seven one-card diagnostic programs and will boot a few to be sure all is well before trying to debug the diagnostic loader deck issue. All seven worked properly. The last one will test card reading and response status from the virtual 1442, by turning on the interrupt delay switch to block interrupts. This shows me that something is not working as it should, blocking both the boot emulation and this diagnostic.

This bears some investigation - I need to investigate more closely to see what is expected but not occurring. My hand code worked but these diagnostics don't. First thing I will look at is the reset bits for the XIO Sense Device - my hand code reset both interrupt levels with bits 14 and 15 both on. However, if I have the bits reversed, so that I am resetting the wrong condition for each bit, it would fail on the diagnostic but not fail with my hand code.

I see from my research that bit 15 should be resetting the IL0 condition (read response or punch response to a column ready for read/write) and bit 14 resets the IL4 condition (operation complete). Sadly, I see that I have properly implemented this, so my first guess is wrong.

Puzzling. If I had a working 1442 I could compare its behavior to what I am producing - but I don't have that option. I could potentially get some aid from other 1130 owners in trying a few bits of hand code, but only after I have really spent time investigating this problem locally.

My best guess now is that I don't present the busy bit on in the DSW for the times that the code expects it. New research - very detailed examination of the busy status flipflop in the 1442 adapter and how it is set and reset. That confirmed I was modeling this improperly.

Several flipflops are ORed together to form the busy condition - basically when a feed, read or punch cycle is taken, it goes on at activation of the cycle and turns off at the end, about when the operation complete interrupt would be turned on. This is easy to model - I just report not busy whenever the main feed cycle process is at its idle state, otherwise the device is busy.

I was keeping the device busy up until the Sense Device with reset turned off the op complete state. This is not correct and I changed the logic to make the busy status more accurate. One final test at night but it still didn't work as expected.

Implementing physical plotter (1627 equivalent)

I cleaned up the transaction logic on the master fgpa side, sending the result of the XIO Write over and then triggering the IL5 interrupt when the slave has responded. I also changed the logic to ignore the XIO Write when the device is reported Not Ready by the slave fpga. I began building the slave fpga side of the logic to drive the plotter.

Implementing physical paper tape reader/punch (1134 and 1055 equivalents)

The transactional logic between master and slave fpgas was inserted into the ztex board side, so that it calls the slave to handle the paper tape devices. I also changed it to to handle Not Ready conditions on either device. As well as with the 1627, I began building the logic in the slave fpga that will drive the motor, latch up data and time the actions of the paper tape reader and paper tape punch devices.

Sunday, February 28, 2016

Finally moving forward on 1442 card reader and other fronts


Debugging the virtual 1442 functionality

If I had kept the logic for the two card buffers as originally expressed - 160 flipflops that I could address through multiplexors driven by indexes - I could load all 10 columns at a time from a fetch or push transaction, I could copy all 80 columns from pre-read to pre-punch in one cycle. However, because of how many LUTs this consumed on my fgpa board, I switched to a pair of memories.

Each memory can access only one column at a time, thus I had to create an 'inner loop' to read or write ten sequential locations as part of one 'outer loop' fetch or push transaction. The copy function had to loop for all eighty locations. With a memory, there were setup and hold requirements for the addresses, generated by several independent processes depending on whether it was a copy, fetch, XIO Read, etc. All this complicated the logic. Often, designers have to make tradeoffs in execution time versus hardware count versus clear expression of the function.

While I should be able to pipeline the read and write of the pre-read and pre-punch buffers, respectively, in a copy process so that there is a one cycle separation between them, that would have the two buffer processes running asynchronously to each other and make interlocking more complex.

My current design does an interlocked read from pre-read, saves the column contents, then does an interlocked write of those contents to the pre-punch buffer. Only one of the buffer processes runs at a time, well interlocked with the copy process.

Once things are running properly, I could revert to the pipelined copy process and test it, if i wished. I tested the non-pipelined version in the morning. Data is being stored in pre-read, but not showing up at the end. Test 2 in the morning watched the output of the pre-read buffer for column 11 during the copyover process.

Of the sequence of operations, push to pre-read, handle XIO Read, handle XIO Punch, fetch from pre-punch, and copyover pre-read to pre-punch, the first is validated. We are ignoring the XIO versions now by checking Start Feed operations. Test 2 looked at the value in the pre-read buffer to check near the end. Nothing there. I see it at the output of the pre-read buffer when I write it, but it is not there when I read it with the fetch process. A memory that isn't.

This smells like setup/hold issues, so I will look over my logic with that in mind. Could also be a toolchain issue, not linking properly to the generated memory component. After making some changes to improve hold times, my afternoon testing worked no better. I will be extremely unhappy if this turns out to be another Xilinx defect - I have burned so many hours on this.

 I made some redesign changes to further eliminate any changes that could be occurring and tested again. Now I get my input cards coming out to the output file, although I am still experiencing a modulo 10 corruption of the card contents. Progress, at least.

Looking over my code, I saw that the way I terminated the 'loop' process for each group of ten words left a race hazard where the column number and other indexing was changing a bit too fast for the process that read the buffer and the other process that stored the results into the outgoing transaction. I added interlocking to protect against this and retested.

Hurray! Feed mode works and the stacker 1 (output) file is an exact copy of the input file. Next up, testing the Start Read mode, which should place an exact copy of the input file card contents into memory. It did not, but I quickly found that my timing doing the buffer read was wrong.

The XIO Read instruction sets a busy signal as it starts, then that signal goes off at the end of the execution. I was not asking the pre-read buffer process to fetch the data until the XIO Read was complete - therefore it had the default value of a blank column. I adjusted the logic to request the buffer read just as soon as the XIO Read begins, so the value is ready for use while the instruction is working.

As I was testing tonight, I realized that I am doing the buffer read at the wrong point in time entirely. The basic logic of reading fires off a 'loop' process that triggers in IL0 interrupt for each of eighty card columns, waiting in between for the XIO Read to be issued. As I set up to trigger the interrupt, I should read the pre-read buffer contents and hold them in a register for use by the XIO Read instruction.

The punch logic has a similar loop of up to eighty columns with an IL0 interrupt and the XIO Write completion for each. During the XIO Write instruction I should save the value in a register and then write it to the pre-punch buffer before going back to issue the next column's interrupt.

The last functions to test, once reading is storing the card columns in core,  are:

  • Punching a card atop blank cards (input file with blanks)
  • Punching a partial card over a nonblank input file
  • Performing a boot load of the first card in a file into core 0x0000 to 0x0004F

Implementing the timeout and restart function for the high speed fpga-fpga link

The logic is in place for the master side, such that if it gets an uncoverage CRC/Hamming error on the data packet or times out waiting for a response, it goes to a reset state then starts over. Once I put the analogous change in the slave, I can test the link to see if it will deliver reliably.


I ran a full print of an object with a clean nozzle and well adjusted bed, but at the normal temp for the extruder, 210C, a layer would not adhere to the layer below. I upped the temp to 225C but still had major separation of layers. It also seems that I am underextruding, since adjacent lines often have a small gap.

At this point, I need to validate the configuration parameters. In particular, there is a parameter for vertical (Z axis) movement that might be wrong, causing each layer to be placed too much above the prior one. Also, the extruder parameter might not be pushing enough plastic to generate the volume of plastic that the software intends to be produced.

The control software in the printer includes a manual "move" function that can move each of the steppers by a specific number of millimeters. For example, if the extruder is moved 100mm then it should move a mark 100mm up on the plastic fiber exactly down to the throat of the extruder. If the Z axis is commanded to move 20mm up from the home position, it should be exactly 20mm above the bed.

The actual and software values are different - software shows 10X the actual millimeter movement. I moved the X axis 100mm by the move function and measured almost exactly 10mm of travel of the extruder left to right. Same with the Y axis (front to back bed movement) where 100mm on the screen was 10mm of physical travel. The Z axis (vertical movement of the extruder) is not on the same scale. It is off by more than 6X - 100mm on the scale would be well over 60mm of real travel/

This explains my layering problem - the Z axis steps up more than 6 times higher than it should between layers and the first step is too high for the plastic to touch the bed properly so even the first layer doesn't sit properly. Objects will be misshapen because the Z axis is stretched out of proportion.

I hadn't bothered to measure the extruder movement yet, but that is undoubtedly off as well. I will figure out how to update the parameters for the firmware to get the values correct. I also ordered better quality tools and loctite so that I can keep this printer working properly

It turns out that I can stick a line of g-code in my print software, issued at the start of a print job, which will set the Z and extruder steps to the values I want. I chose 384 for the Z step and 630 for the extruder. My first test print is just starting but  looking good. I may or may not decrease the extrude a bit, depending on whether I see artifacts that suggest over extrusion, but the difference is already night and day from what it was producing before.

The object being printed was too flattened, resulting in the nozzle scraping over the prior layer rather than adding new plastic. I adjusted the Z steps to 400 but still having problems. Sigh. Not worth investing more time today. At least my new tools have arrived and are a pleasure to use with the printer.

Saturday, February 27, 2016

testing of rewritter 1442 buffer handling logic, 1800 and 1620 news, and work on high speed link resilience


Debugging the virtual 1442 functionality

I finally had a chance to test my rewritten logic for handling buffers at lunchtime on Friday. I found that column 11 was correctly extracted from the pre-read buffer during the copyover process, validating that it was not corrupted in loading nor in the process of handling the XIO Read instructions.

What has failed is the logic to fetch the contents of the pre-punch buffer before doing the copy-over. I always get spaces regardless of what card was in the pre-read buffer. Since this is further down the chain, but my successful test above showed me that the data was still in the pre-read buffer while copy is underway, I will first chase through to see if there is any corruption before I work on the fetch transaction problem itself.

I altered the code to a couple of times and retested:

  • 1- latch what is now in the pre-punch buffer after I have written the word in copyover
  • 2 - latch in what is pulled from the pre-punch buffer when the data is fetched back to the PC
  • 3 - latch what is pulled from the pre-punch buffer by the fetch transaction

These are intended to find the first point where data is corrupted, permitting me to isolate the problem and fix it. I will also see after the first one above whether the pre-read contents made it correctly to the pre-punch buffer. By methodically isolating where problems arise, I can zoom in on just the offending logic.

Test 1 showed that my copy-over didn't seem to be writing the output of the pre-read into the pre-punch. That would cause the downstream error of seeing only spaces from the fetch. I tweaked the copy-over logic, looked it over at the same time, and prepared for a late afternoon test.

Part of my test for the afternoon, as a latched in the contents of column 11 in the pre-punch buffer right after the copyover routine had written it to match the output of the pre-read buffer, was to see that the input and output of the pre-punch buffer was the same. If not, I had a functionality issue with the buffer component.

Somehow I am now getting nothing in the read buffer by the time I try to copy it over. I checked memory and I now have nothing in memory either. WTF. This all ought to be simple stuff, easily debugged and checked off, but it has burned a couple of weeks of admittedly restricted access to the machine.

I realized that previously today I was testing with XIO Control Start Feed, but changed to XIO Control Start Read which invokes the IL0 interrupts and handles XIO Read. I looked at my rewritten buffer control logic and found conditions where the buffer read and write machines would stall. I fixed the issue but will also revert to testing simple feed through until I get the card images moving all the way through the virtual 1442. Then I can debug the read and punch actions.

Early the next morning I went out to test the new logic. Interestngly, rather than having column 11, 21 etc overloaded with the content of col 1, but the remainder of the card image okay, I now have all blank cards except for column 12, 22, 32, etc which appears to match the input file. I did verify that the buffer control logic is not stalling.

Seems I need to interlock the fetch, copy, read/write and push transactions with the buffer control, since these take several fpga cycles to process each read or write but the transactional logic advances at full fpga speed. This turned out to be more convoluted than I first thought, with the need to maintain setup and hold times for addresses but still trying to cycle the buffer FSMs at the right time.

The key is to build solid interlocked buffer processes, then add the steps to the calling FSMs to be sure it stays in sync. I updated the buffer FSMs first, then rolled in the calling sequences to the five callers (push card image to pre-read, handle XIO read from pre-read, handle XIO write into pre-punch, fetch pre-punch buffer contents, and copy from pre-read to pre-punch.)

Debugging should be a matter of fnding stalls and verifying set of data at the proper moments. First test found a stall in the pre-punch buffer process during copyover. Once I had the two buffer processes free of stalls, I redesigned the copyover to separate reading of the pre-read from writing to the pre-punch, eliminating any timing trickiness. It takes more cycles this way, but compared to electromechanical reader/punch speeds, it is invisible.

Improving resilience of the high speed link between master and slave FPGA boards

My master drives a sequence of data bytes to the slave, with an idle pause between each round. Thus the idle is a restart point to force the machines to get back into sync if an error occurs. I will put a timer on the input process for both slave and fpga, reset at the idle point and counting down independently while the input process steps through bytes.

If enough time elapses and we have not returned to the idle point, it constitutes a fault that will drive every step in the input process back to the idle point. As well, a fault will drive the output processes back to idle, so that the link machine on each side is forced to idle waiting on input and the master is ready to initiate the next round.



The 1800 system being restored by Johannes Thelan is properly executing all instructions entered in hand loops. He is still validating functionality but it looks quite solid. With the core of the system in good shape, he will turn his attention to peripherals and extentions modules, I guess.


Johannes will also be accepting this IBM 1710 (a 1620 with some process control additions), bringing it from its current home to his workshop to start the journey towards restoration. A similar but earlier restoration at the Computer History Museum found that something about the solder or rosin or other materials used in the construction of the 1620 core memory caused the connections of the fine sense and drive wires to corrode at their connection points. The memory was not salvageable at the time.

System to be restored in Finnland
What is unknown is whether this was a systemic flaw, so that all 1620 memories would similarly degrade over time due to an unfortunate choice of materials/process, or if this was due to local repairs to the one machine at CHM prior to their accessioning the system. When Johannes transports his machine, he can examine the condition of the core modules and answer this question. Cotemporaneous core memories built by IBM in systems like 1401 did not suffer this problem, so we can be hopeful that it was a one-off issue and not a plague upon all 1620 units.


The extruder was giving me problems, something I have to sort out in order to move on to good prints. I cleaned it out and assembled it, then dealt with several nuts and screws having loosened and failure of the connection to one of the microswitches for the Y axis far limit. I will resolder the limit switch wiring right away so I can make another test print.

What this really needs is loctite for the threads on some of the nuts and bolts that have loosened, particularly when they are holding compressible plastic parts yet have no lockwasher. The allen wrenches provided are cheap quality and have rounded off too much already. I need to get better tools and go over all the connections.

The fine-tuning, once all the parts are together and working, deals with getting the bed level and at the right height, the temperature of the nozzle correct and doing other tweaks to get the prints coming out with sufficient quality.  

Wednesday, February 24, 2016

Reimplemented buffer logic for 1442 card reader/punch, resolving 3d printer issue


Debugging the virtual 1442 functionality

My practice when I find that a particular section of logic or function is very troublesome is to redesign and reimplement - often getting to a more solid behavior as a result. I will do this with the logic that writes to the two buffers for the 1442 - pre-read and pre-punch. This will replace some multiplexed address and write signals, which could be causing glitches as the control signals switch.

Instead, I will put the addressing and control of the buffer memories each in its own process, which will look at the control signals and proposed addressing signals from the various processes (push content to pre-read, handle XIO read or write, fetch from pre-punch, and copy pre-read to pre-punch).

The main processes to handle the copyover, fetch from pre-punch, push to pre-read and completion of XIO Read/Write were modified to trigger these buffer processes and to tell them in what cycle they should handle the read or write to the buffer. I hope to test this tonight, but I have quite a bit of day-job work and a car that needs its battery replaced.


I disassembled the extruder on the printer and found a manufacturing defect in the bracket that bolts to the servo motor, upon which the pivot is installed that presses the filament into the knurled gear on the end of the servo shaft.  The bracket is held to the servo motor by an M3 6mm bolt. The bolt fits into a recessed hole, to keep the head of the bolt from interfering with the operation of the pivot. Due to the depth of the recess, the 6mm bolt bottoms out in the servo motor before it clamps the bracket firmly.

The bracket shifts, jams the gear on the extruder shaft and that causes it to release too little molten plastic. My solution is to substitute a 4mm long bolt, which should hold the bracket tightly in place. I also think I have to clean out and open up the nozzle so that it extrudes the proper amount. More on this in a couple of days when I have time to work on it again.

Absolute worst case is that I buy an extruder from ebay and hook it up, so I am satisfied with my bargain printer kit. It is suited to a hobbyist who can sort out spare parts, diagnose problems and understands the underlying technologies. Someone who needs tech support or very complete instructions will not do as well with this kit.

For example, the machine initially behaved bizarrely, heating both the bed and extruder when it first powered up, while shuffling all thee motors back and forth about 10mm perpetually. I created a video it including the control panel showing it mis-performing and asked for a link to replacement firmware.

A couple of days later, I got an email claiming to have watched my video and diagnosing the problem as a bad thermistor on the bed which needed replacement. Fortunately, I had earlier discovered a response from the company to a different user (on an Amazon feedback post) with a link to the firmware. I downloaded that firmware and fixed the problem, without touching the thermistor they mentioned.

I can see a chain of actions and emails from a naive user, culminating in several replacement parts being shipped from China but not fixing the problem - other than accidentally. This kit suits me but wouldn't work for many.

Tuesday, February 23, 2016

Continuing to slog painfully through the column corruption issue with the virtual 1442 driver


Debugging the virtual 1442 functionality

I remain stymied by the modulo ten corruption happening to card images as they move through the virtual 1442 system. Each debugging 'probe' takes 20 minutes of Xilinx dawdling  and a few minutes to load the bitstream, start my GUI program and power up the 1130 - lets call it 30 minutes per pass even if each change to the logic takes zero seconds to conceive and enter. Progress is slow.

3D printer experimentation

The 3D printer seems to be functional but my extruder, the part that forces out molten plastic at the intended rate and times, is not giving me enough volume of plastic. The resultant prints are stringy, with wisps of plastic floating like cobwebs instead of laying down on the bed. I will open up the extruder to see if something is not working properly. It may be software changes to parameters or a hardware issue.

Sunday, February 21, 2016

Working on 1627, 1134 and 1055 adapter functions, built 3D printer, but hitting a brick wall on 1442 buffer glitch


Debugging the virtual 1442 functionality

I have to find and fix the source of corruption of the buffer contents that occurs sometime in the feed cycle after the data is pushed from PC down to the pre-read buffer. Reading the card contents appears to get the correct data, but when it is fetched from the pre-punch buffer at the end things are wrong.

I need specialized diagnostics to figure out where things are wrong and then zero in on the source of the problem. I spent my free time at lunch devising these diagnostic signals. The other function that is not yet tested to completion is the program load (boot) process that takes the first card image, converts it to the special program load format and places the data in the first 80 words of core.

Back to basics in checking this out. First step was to read a card into core and exhaustively check all 80 columns against the card image. Do again for a second card. This combination will tell me for sure whether the data is loaded into the pre-read buffer and extracted into core properly.

As I had believed, the card image is loaded in core for all 80 columns in exact accordance with the holes in each virtual card. I then reran the test with the stacker output file open to see what is extracted into the output file. It will have read correctly, so that any changes occur during the copy-over from pre-read to pre-punch or in the extraction of the pre-punch buffer back to the PC to be saved in the output file.

This also confirmed the corrupted state of the output card images. The contents of column 1 are repeated in columns 11, 21, 31, 41, 51, 61 and 71, instead of the contents I should see in those columns, Since this occurs modulo 10, which matches the get special content transaction stride, the finger of suspicion points to the logic that does the fetching - either in the fpga where the transaction is implemented or in the Python code where it is issued and processed.

I have a test I can put into the fpga that will check the value of column 11 of the pre-punch buffer, showing me whether it contains bit 10 incorrectly copied from column 1 or if bit 10 is off as it should be. This will tell me if the pre-punch buffer is ever corrupted in the FPGA or if the issue is within the fetch operation itself.

I ran the test in the morning and found the bad data (column 1 data found in column 11) coming out of the pre-punch buffer.This problem is vexing. I included extra cycles to ensure long setup and hold around the write to the pre-punch buffer, but that seemed to make no sense.

The modulo ten behavior argues strongly for this to be related to the get special data or write special data transactions which handle ten columns each time they are called. I just can't see anything wrong yet.

I do have a plausible sequence of events to cause the problem. If the address for the pre-read or pre-punch buffer memory is seen as zero, that will cause it to output the contents of card column 1. Since these malfunctions happen in relationship to the fetch transaction, somewhere in the get special data transaction flow,

Somehow, I am letting the address of the pre-punch buffer go to zero and that is when I am latching up my outbound data word. My transaction process loads the address for memory as it starts up from incoming word 2 of the transaction, then increments it during the course of the transaction.

There are other ways for the address to get to zero, since I have a mux on the address lines which is switched by control signals when the get special, write special, copyover, XIO read and XIO write logic is active.

I tightened up what I could particularly concentrating on the address mux and the get special transaction and went back to testing. The results were even more mysterious. My first run was to read in several blank cards, copying them over to the output file and verifying that they were all blank there.

Next, I closed all the files, did an NPRO, opened a deck with card images and read several cards copying the image over to the output file. In all of these, the first column and every ten thereafter was blank!

Now I am really mystified. I might completely restructure all the logic around the buffers. I have to ponder this.

Implementing physical plotter (1627 equivalent)

I did strip out and change the logic for the 1627 (plotter) device to produce a simple transaction over to the slave FPGA. When an XIO Write occurs, one or more of the command bits is on in the word sent by the program. These are copied over the fast link to the slave, where anytime we have 1 or more bits on, it fires off the associated signal lines to the 1627 electrical adapter box - inverted logic so that any bit that is on becomes a 0 signal to the 1627 electrical adapter, the remainder stay at 1.

The slave FPGA holds these signals for a defined length of time then drops them. A response signal, D1627done, is normally 0 but is switched to 1 when the timed operation on the plotter is complete. When the slave board sees the command bits from the master reset to all zero, it drops the D1627done signal to complete the transaction. The master sees the D1627done signal turn on, triggers the response interrupt for the 1627 to the 1130 and then goes back to wait for the next XIO.

I need to add a Not Ready signal from slave to master, as well as a way of determining that the 1627 is ready or not, which will be a switch I hook up. The logic should ignore the XIO Write when the device is not ready.

Implementing physical paper tape reader/punch (1134 and 1055 equivalents)

I began the same process of moving the timing related and machinery control portions of the device adapter over to the slave FPGA, with the 1130 facing logic left in the ztex FPGA to handle XIOs, interrupts and so forth. The slave must provide the Not Ready signals from the two paper tape devices, as well as the same kind of transactional mechanism as I used for the 1627.

I will send a punch command signal and output bits to the 1055 and do an interlocked wait for a 1055 response. For the reader, there is only one command that is sent over, a request for movement command which sends back the 8 channels from the paper tape character as well as an interlocked response signal.

The movement control and timing is done in the slave, while the master will control the simple transactions and feed the buffered tape character to the XIO Read command. It also handles sense bits and interrupts. Both devices should ignore commands when not ready.

3D Printer Kit Assembled

I bought a low cost 3D printer kit (Hictop 3DP08) and assembled it in a few hours after it arrived. When I powered it up, the behavior was bizarre but that seemed to be flawed firmware (code in an Arduino that drives the unit). Although the tech support from the maker is quite limited, I found one post they put up in response to an Amazon feedback entry where they gave a link to a Dropbox with the firmware file.

With the new firmware file, the machine was much much better. I discovered a need to reroute some cables and to make tweaks to the alignment for the heated bed, but I expect with another hour or less of work it will be ready to pump out 3D parts in PLA and ABS plastic. By eight PM it was humming along on all axis smoothly. Tomorrow I will do a few prints - it does take a bit of setup time for any printing, getting the bed completely parallel and lining it with an adhering surface, then a few hours to print a reasonable complexity part - which is why I wont' start it tonight.

Thursday, February 18, 2016

Virtual 1442 stacker select working, still tweaking punch and boot


Debugging the virtual 1442 functionality

Two things left to test - punching cards and stacker select. I am expecting a very quick conclusion to the stacker select testing. What I still need to do is figure out the remaining defects in the punch logic in the fpga, then fix them.

 I also thought of some enhancements to make to the functionality. The first will close input files automatically when the last record is read. The second will provide an NPRO button. The third will act on the "last card" checkbox whenever it is changed, where the existing code only checks this at the time I open an input file. The fourth allows me to do a Program Load from 1442 with the first card interpreted in the special format for a boot card.

After an input file is open and I am reading/feeding/punching cards from it, when it goes empty the 1442 is made Not Ready, but the file is left open, waiting for the user to push the Input File button to close it. The close should be automatic when we empty the file. I will also try to include a signal that the hopper is empty.

An NPRO button will cause the 'card; that is left inside the machine in the pre-punch buffer to be discarded. I have a 'first time' variable that causes me to skip writing what is fetched from the pre-punch buffer on startup of the virtual 1442, since nothing is there until at least one card is read/punched/fed. Turning this on is the same as NPRO, but will only be allowed when the hopper is empty (input file closed), the same restriction as on a physical 1442.

I check and save the state of the Last Card while opening an input file, but should be moved to the point where I check this, when the input file was just emptied, to allow the user to select this behavior at any time up until the last card is being read/punched/fed.

My midday testing will cover:
  • Diagnostics to track down punching malfunction
  • Stacker Select function verification
  • Test late selection of Last Card
  • Test autoclose at end of hopper
  • Test display of Hopper Empty status
  • Test NPRO button functionality
  • Test booting from 1442
In reviewing my punch logic in the FPGA, I realized that my spec for how to handle punching was flawed. Reading cards always emits 80 column interrupts on IL0 and requires 80 XIO Reads to be issued, but punching a card can be terminated by a special data pattern - turning bit 12 of the word on to indicate end of the punch operation. No more IL0 interrupts are issued in this case and the op complete interrupt on Il4 is given.

I misread the spec and thought that the word with the 12 bit set was not punched - that it just served as a marker for 'stop here'. I implemented based on this which is more complicated than it needs to be. The actual spec is that the word with bit 12 set also has punch data in bits 0 to 11, which are punched in the column first and then the operation is terminated. I had to fix my logic.

I am still not seeing the fault that leads to the incorrect data values sitting in the pre-punch buffer at the end of punching a card. I did put in some testing to check on where the error is occurring.I am never seeing the second column, row 12 value.

Stacker selection seemed to work properly, although I didn't run long enough to see the card image show up in the alternate file. I did run into an implementation issue in how I test the Last Card checkbox, in that my path to the GUI feature is not accessible from the 1442 worker thread.

Finally, I found the flaw in the logic for punching and am getting my five columns punched. There is an anomaly in the output file, with the character from column 1 repeated every 11 characters across the card. Since this is the stride of my USB transaction, I suspect a flaw in the logic related to fetching the newly updated pre-punch buffer, but need to study this more to be sure.

My early evening testing found the repeating character flaw mentioned above, the progress on punching, and showed that even though I am setting the alternate stacker, somehow the card is not being written to that file. That turned out to be a simple omission in the Python program - I wasn't closing the second stacker file, only the primary one, so the in-core buffer of the card I wrote wasn't flushed out. Change made in advance of my next set of evening testing.

Before dinner, I ran another set of tests to check out the remaining functions. The stacker select function is perfect. The repetition of the first column character every 11 columns is occurring during the copy-over from pre-read to pre-punch, it appears, because I see if even when the XIO Control is only feeding cards from input file through the virtual 1442 to the output file. The data read into core is fine during reading, at least.

I tested the new Program Load (Boot) function and saw it load core with the 80 words, but a flaw in the Python program ruined the test. I will check the contents of core to see whether they look right, but I have overwritten the core area for read/punch data and the interrupt vector information, so I need to rebuild that before I can test the punch/copy issue further.

Design of Mirror 1442 Functionality

The virtual device adapter behaves like the peripheral it emulates as far as the 1130 and its programs are concerned, but uses files on a PC as the source and sink of data. A mirror device adapter, on the other hand, just 'follows along', shadows or mirrors what is taking place with an IBM device adapter built into the 1130. Real cards are being read or punched too.

The physical adapter in the 1130 controls the physical peripheral, in this case the 1442 reader/punch. It handles the XIO instructions, moves data in and out of core, and provides the sense status to the programming. The mirror adapter just observes what the physical adapter is doing, grabbing copies of the data and sense status as the physical adapter delivers it to the rest of the 1130. These copies are sent up to the PC to be captured in a file or other display.

There are use cases for a mirror 1442 adapter - to capture physical punched cards into a PC based file for use with the IBM simulator, for example. The restored 1130 at TNMoC in the UK could use the mirror adapter at times, as well as the virtual adapter when they want to use PC based files as the card images. Even though I don't have a current use for the mirror adapter, since my 1442 is not operational, at some point it will be convenient to have it.

Now that I have all the state needed to behave like a 1442, I should be able to follow along with a real unit and its adapter, snagging card images as they are read and/or punched. The changes shouldn't be too major. I will figure out how to modify my logic and Python code so that the user can select which of the two modes it should adopt - virtual or mirror. To be a virtual device, it needs to block the physical adapter, which I do with a jumper or switch. More on the design of the changes later - as soon as the virtual version is totally tested and final.

Implementing physical plotter (1627 equivalent)

The high speed link needs to be made bulletproof - automatically recover from any loss of sync. I am looking over the design to sort this out.

Wednesday, February 17, 2016

V1442 card reading is complete, now focusing on punching and stacker select


I decided to list and total all the SLT boards used in my 1130, in order to recognize when a card on ebay might be useful to acquire. There are 80 different card types used in the machine and a total of 224 actual SLT cards spread across six compartments.

I only have schematics for less than half the card types in the machine. For those where I have a schematic, I can work out discrete components to repair a bad card, if I can't find a spare. For those without a schematic, if I can figure out what components are not working, I might find replacement SLT modules on some other cards or be able to figure out what is the schematic of just the SLT module (the square metal cans that contain a mix of transistors, diodes and resistors on a ceramic base).


Debugging the virtual 1442 functionality

These are the remaining tests to sign off on the virtual 1442 function::
  • loop detects last card and it is read into core properly before 1442 goes Not Ready
  • restart of a new deck (input file) after reader exhausted previous hopper to Not Ready
  • loop runs with Last Card on and returns proper DSW on operation complete
  • feed only cycle copies deck over correctly input to output file
  • blank input file and punching produces proper output file
  • dirty input file and punching works
  • punch with short count works
My read instructions are now properly setting Not Ready both when the last card in the PC file is read and on any subsequent XIO Sense Device, until a new file is 'put into the hopper'. If Last Card is checked when a file is opened, then the LC status bit is set on the XIO Sense DSW at the completion of that card.

Restart with a new file systems to work properly, at least as far as the virtual device being ready to read and the proper card contents arriving into core. The contents of the output files seem off by one, the contents fetched seem to match the new card read and not the prior card which would be exiting the pre-punch buffer. This needs to be checked and if it is occurring, the flaw must be corrected.

I did a punch of four columns, punching the hollerith for CARL into the front of the blank card image I loaded into the input hopper. However, it looks like the FSMs didn't work properly as the fpga was not ready to accept a new punch command. This needs a new set of diagnostic LEDs to help me chase down the problem.

To summarize, reading is working solidly including the not ready condition at the end of a PC file used as card input and the proper handling of the last card condition. I seemed to have some problems to resolve:

  • I may be out of sync on the card images that appear in the output file as I read two decks, with a NR in the middle. This could be a problem due to next issue. 
  • I might need an "NPRO" equivalent to flush the card image from the pre-punch buffer out, in order to see the last card. This will take some design work.
  • Punching a short card is not working - not sure whether a full sized card would work better

After thinking about it, I realized that when I switched to testing the punching operation, I didn't fully change the software in the 1130. The punching of a card is begun by an XIO Control with the Start Punch modifier bit on, then it will receive up to 80 interrupts on IL0 to which it must respond with an XIO Write to send the holes to be punched. I left the interrupt routine with an XIO Read, not an XIO Write. Without the issuance of Write commands by the 1130, my feed cycle won't complete.

Rerunning the tests more carefully, including making all the changes to support punching, allowed me to run a full card punch and then several of the four column punches of "CARL". These all completed properly with a normal operations complete interrupt. I turned to the output files to see how I did.

I can see that when I run out of input cards, the last card that had been read is sitting in the pre-punch station and has not been fetched to put in the output file. When I open the second input file, making the virtual reader ready again, as I read the first call of the second deck, I get that final card of deck 1 into the output file. This isn't really a problem for reading decks.

On a real 1442, the input cards are placed in the hopper, but when Start is pressed on the reader it takes a feed cycle to put the first card at the pre-read station. Nothing is at the pre-punch station yet. If a punch operation is performed while the 1442 is in this state (no pre-punch card), the adapter logic forces another feed cycle first, putting the first card that was originally in the hopper into the pre-punch, the second card of the deck is now in the pre-read and the third and subsequent cards are still in the hopper.

When the hopper empties after a feed cycle (read, punch or just a feed requested), the final card that had been in the hopper is now in the pre-read station. The next to last card from the hopper is in the pre-punch station. The 1442 goes not ready.

If the operator pushes Start while the hopper is empty, the reader is ready again and another read can take place, moving the last card from pre-read to pre-punch and having ejected the N-1 card into the stacker.

If the operator then wants to remove the final card, the operator pushes the NPRO (non process runout) button to force feed cycles until nothing is in either pre-read or pre-punch stations. The last card is now in the output stacker.

If the operator did not push Start with an empty hopper, then the program reading or punching cards is paused waiting for the 1442 to go ready again. Placing the next deck of cards in the hopper before pressing start will switch the device back to ready so that another read/feed/punch can occur, but no "last card" status is reported. Things resume, with the last card of the old deck read and moved from pre-read to pre-punch, the N-1 of the old deck moving to the output stacker, and the first card of the new deck moving into the pre-read station.

I don't have an NPRO equivalent and probably don't need it. If reading a deck, I don't care if the last card makes it into the output file. If punching on blank cards, the punch operation is completed by fetching the pre-punch buffer thus that last card is captured.

I did see that the punching is not working properly - specifically I have all blanks in the output cards even though I am attempting to punch non-zero values. Although I haven't explicitly tested the Stacker Select operation of XIO Control, it is pretty simple so I will do this when I wrap up whatever I get the punching fully fixed. I figured out some diagnostic LEDs and data I can watch to figure this out.

Found the first flaw and corrected it, then went out to test. Something not right yet, as I got a card with C and a bunch of spaces, then the same group repeated several more times across the card. Also tried the stacker select, which didn't work because I miscoded the test in the Python program. Fixed and ready to test, once I figure out the punching problem tomorrow.

Testing physical plotter (1627 equivalent)

I saw a couple of instances where the slave Nexys2 FPGA board got out of sync with the master ztex board - I need some form of error recovery to get these working together again. I also will swap the polarities of the control signals to the plotter so that if the slave board is not yet talking to the master, the resulting signals to the 1627 make sense (e.g. they are all high so they mean no operation).

Tuesday, February 16, 2016

Almost finished virtual 1442 card reader/punch testing, beginning testing of the physical 1627 plotter


Debugging the virtual 1442 functionality

I began the day wrestling with two major problems. First, the DSW stored when my 'not ready' bit is set is all zeroes, not 0x0001 as it should be. DSWs with the read, punch and operation complete responses work properly. Second, the data I correct load into the pre-read buffer and correctly read into core memory is not correctly copied over to the pre-punch buffer.

I finally spotted the error in my process to copy over the buffer contents from pre-read to pre-punch stations. I initialized the index to 0 at power up, incremented it while cycling through the 80 card columns, but never reset it to 0 when I went back to the idle state waiting to copy over the next card image.

This leaves the mysterious issue of the not ready bit which does not appear in the DSW but should whenever I don't have a input file open on the PC. I suppose this could be something that effects the low bit, either spurious trimming of the signals by the untrustworthy toolchain or a hardware flaw that just arose in my interface box.

When I did a quick test, something hung up so that I couldn't do a second card read operation. Since I just changed the copy routine, that is the logical place to look. I checked the state of the diagnostic LEDs to help illuminate the condition of the system and point at what might be awry.

They showed me that the FPGA FSMs were all back to their proper idle positions, but the Not Ready but had been set for the device. Turns out the flaw was in the Python code I changed to handle hopper empty - it was treating the hopper as empty right after the first card. A quick fix and I could get back out to test.

In support of the missing DSW bit, I added some recognizable bits to the DSW and watched what was stored. The testing at lunchtime showed that my copy-over process is working correctly and the data being picked up by the Python program at the end of a fetch cycle matches the card image two back in the input deck. However, the image in the output file is distorted. I appear to have everything shifted over by one byte, so that data belonging in card column 1 shows up as column 8. Clearly a Python side problem.

The DSW stored for column (IL0) interrupts had both bits 12 and 13 lit up, which were the two I added to the DSW as a fixed output. However, the DSW stored for the operation complete (IL4) interrupt had only 12 lit. When I tried an XIO Control with the virtual device Not Ready, the DSW returned had only bit 12 lit. Something is trimming the bottom four bits from my returned DSW for both IL4 and later, but not on the column interrupts. Could also be a timing issue for the XIO Sense DSW logic. More investigation is definitely needed.

I worked on the Python program for a bit, found and changed the code which shifted the hole patterns off in the output file. My testing in the late afternoon showed that the new output file is still messed up, just differently. I suspect this is a combination of endian problems and other defects, but will have to keep working on it until I get it working properly.

I changed the length of time that I held the write gate and write data lines up during the XIO Sense Device module process, which fixed my problem with dropped Not Ready bits. Instead of dropping as soon as the 1130 gets into T6, I wait until I enter phase A of T7. This needs to be carried over to other XIO modules which write to the 1130 (XIO Sense ILSW and XIO Read).

Remaining problems or subfunctions not yet tested to satisfaction:

  • fetched words from pre-punch buffer are stored correctly in 1130 simulator binary format file
  • Stacker Select causes next card to go into the alternate stacker file
  • Start Punch will successfully punch the contents of memory into the pre-punch buffer
  • Looping to a last card in a file results in Not Ready after last read, if no Last Card selected
  • Looping to a last card in a file results in Not Ready after last read, plus last card bit in DSW at end operation, if Last Card was selected
  • Loading a new file restarts properly from Not Ready

I got the Python code to properly load the fetched words from the pre-punch buffer into the output files on the PC. I also tested that a loop will properly detect the last card of a deck, but it triggered a code defect that I have subsequently repaired.

In the early evening, I went out to test:
  • loop detects last card and it is read into core properly before 1442 goes Not Ready
  • restart of a new deck (input file) after reader exhausted previous hopper to Not Ready
  • loop runs with Last Card on and returns proper DSW on operation complete
  • feed only cycle copies deck over correctly input to output file
  • blank input file and punching produces proper output file
  • dirty input file and punching works
  • punch with short count works
The loop detects the empty status but my Not Ready is not showing up unless the file is closed - this means my Python code is not pushing the DSW update. Same with the Last Card run (3 above) likely for the same reason. I looked in memory and it didn't match up properly with what card image I should see. I need to fix the problems I see before going back to the tests.

The behavior that I can't match is when the 1442 is readied with new cards (e.g. first card is in pre-read buffer) and the first operation is Control for Start Punch, the 1442 will trigger a dummy feed cycle first. That would require a copy-over of the pre-read to the pre-punch buffer.

Instead, if the XIO Control for Start Punch is issued right after startup, the punching will take place into the pre-punch buffer as if the card were completely blank first. If the purpose of the job is to take a card with partial contents towards the right side of the card and the program wishes to punch data in earlier columns, it will be off-by-one from the presumed deck. order. This can be fixed operationally by running in a single blank card file first.

If the program is going to read cards and then punch into the first part of them in the next operation, this will work properly since the Start Read will result in the data from that card moving to the pre-punch station where a subsequent Start Punch can overwrite columns (up to 80 depending on length of the punch field). I don't understand how the device could read card 2 as well as punching in card 1, as both operations will trigger a feed cycle. More study is needed to see if this is possible and how I might mimic it.

Implementing physical plotter (1627 equivalent)

I began wiring up the connector for the 1627 adapter box this afternoon, allowing me to move on to testing the Strobe 100 plotter acting as an IBM 1627 to XIOs from the 1130. With the connector done, I hooked up the fast link and powered up the combination (SAC Interface Box, slave fpga, 1627 adapter box and Strobe 100 plotter.

When I brought up the system for my 1442 function testing, I also had the 1627 gear ready. It showed the expected values for the plotter and when I fired off a single XIO Write asking for a move to the left, I saw the plotter move to the left one step. However, there is a timer loop that seemed to be running way too long and inverted status of the movement signals.

It was a good first step in testing, but some fine tuning is needed. I will get to this when I go back to testing the 1627, but have to prioritize finishing up the virtual 1442.

Implementing physical paper tape reader/punch (1134 and 1055 equivalents)

There are status signals that I have not yet assigned or routed, which will tell me if the 1134 or 1055 is not ready. I need to work this out, make changes to both the core and slave FPGA logic, and then begin soldering up the connectors.

Monday, February 15, 2016

Virtual 1442 testing going well, beginning to wire up the 1627 plotter device

The 1130 has behaved itself for the last dozen times I have powered up to test - no sign of the misbehavior leaving it in reset or in single memory cycle mode. Fingers crossed it stays this way.


Debugging virtual 1442 card reader/card punch functionality

I spotted a flaw in some logic related to the copy-over and corrected it. In addition, I changed my diagnostic LEDs to help me further debug the copy process. With these changes made, I went out this morning to the machine and tested. Alas, no progress in seeing the previously read cards copied over and fetched successfully.

Since I was looking over the Python side code, I completed the alternate stacker support. Now, when opening an output file for cards that are punched (or just exiting into one of the two stackers), I open both the chosen filename and one with 'alt' appended to the name. When writing a line, I check to see if the user has issued an alternate stacker command via XIO Control after the last feed cycle completed.

My diagnostic lights show that bit 5 of the word for column 2 is on for the first card and then off for the next few cards, when monitoring the input to the pre-punch buffer memory. My copy routine runs through to column 80, another indication all is good, plus the main feed FSM finishes the IO. If the write signal is enabled properly, then it should have saved the proper words in the buffer.

And . . . of course, I wasn't enabling the write signal properly. Found the defect and corrected it, so after the ten minutes of glacially slow Xilinx processing I can test once again. I expanded the testing a bit, thus finding several flaws to work on:

  • Still get zero output - also not certain the data is locked into the pre-punch buffer
  • If I close a card file and open a new one, something goes wrong with the read
  • If I try an IO with the card file closed, I get a DSW of 0x0000 but should be 0x0001

The middle problem is definitely in the Python code. I see the Python code pushing the 0x0001 down to the FPGA so the last problem is going to be in the fpga logic. More diagnostics will help me figure out the first problem.

After some changes, I began to get data fetching out of the pre-punch buffer at the end of the second feed cycle (the first cycle producing a blank card). The data was partial - the first 11 columns were zeroed out but the rest of the card image matched.

On the next (third) feed cycle, I should be seeing card two's data but instead got a mix of the earlier data. I am not sure where this is getting corrupted. My diagnostic LEDs only show me a few bits, not enough to spot this, but at least on the input to the pre-punch buffer, for its copy, the data was not the zero values I see from the Python program.

The Sense of 0x0000 given with a not ready device is still occurring. I see a need to ignore any XIO issued when the device is not-ready, rather than sending it to the Python code for processing.

The problems at this point:

  • corruption of data fetched from pre-punch buffer
  • failure to see the not-ready status with an XIO Sense DSW when the input file is closed
  • XIO issued to not-ready device still triggers the feed FSM and will resume as soon as I ready a new input file, without an XIO being issued

I developed and implemented a fix to ignore the XIO commands when the device is busy. I also put in a diagnostic LED to show me the not-ready status, to be sure it is being set and reset properly. This will be tested on the next round on the machine.

I looked carefully at both sides (fpga and Python) when I push the input file image to the pre-read buffer and when I fetch the pre-punch buffer contents back to the PC. As a diagnostic aid, I will latch up the first column of each card as it is copied out of the pre-read buffer.

Midafternoon saw my next power-up of the 1130 to test the changes and examine the diagnostic output. I am seeing the LEDs light when the not ready bit is set, but it isn't being written into the DSW when I issue a XIO Sense Device. The other bits are written properly - this is very odd.

My diagnostics show me pushing each card image in turn down to the fpga, but after I write the pre-read buffer the first time, it is never updated. Some FSM is hung up and thus blocking it. LEDs will show me the state of the various FSMs.

I did test with XIO Control for a feed, as an alternative to a read. They should work the same was as far as pushing the data into the buffer, the buffers copying from read to punch, and the fetch of data coming out. The only different is that we will not trigger IL0 to ask for reads, but will give a final IL4 with an operation complete status. Works fine.

I was not happy with my hopper empty logic in the Python program, nor the last card work, so I will rewrite this tonight to make it more elegant and reliable. When I open each file as an input deck of cards, I seek to the end and record the byte offset of the end of the file. That is what I can check after the read in each feed cycle(read, punch or feed), before I push in the card contents to the pre-read buffer.

As I look at the last card in the file, I will push it into the pre-read buffer, and if the last card checkbox is on, I push the last card bit down to the DSW to be returned when this feed cycle end. What I do at the end of the feed cycle - where I process the fake XIO IR operation - is always to set the device to Not Ready since the hopper has run out, either because of reading the last card in Last Card mode or because it needs the next deck loaded.

Getting back to testing, I am still stymied by the failure to report the not ready bit in the DSW as well as the problem I am having with the copyover from pre-read to pre-punch. I am definitely getting the right contents into the pre-read buffer and into core memory when reading. Moving the data between buffers is where things are failing.

I gave up for the evening - having no clue how either of the failures can be happening. I will work on the last card and hopper empty code in Python tonight and take a fresh look tomorrow trying to find the problem in my logic.

Implementing physical plotter (1627 equivalent)

I loaded the Nexys2 board with its bitgen that drives the 1627, 1134 and 1055 device signals, in preparation for wiring up my interface box that makes the Strobe 100 plotter masquerade as an IBM 1627. I tried to test the high speed link but I had a wire break off the connector.

I rewired the high speed linkage connector tonight. I need to do the same for my six plotter signals and a ground connection. Once I get the connectors all sorted out, I can begin testing.

Implementing physical paper tape reader/punch (1134 and 1055 equivalents)

The slave Nexys2 board is now in place so that I can wire in the paper tape reader and paper tape punch for my testing. I will wait until the 1627 is verified before I test these.

Sunday, February 14, 2016

Implementation of linkages for 1627 plotter, 1134 paper tape reader and 1055 paper tape punch, plus successful virtual 1442 debugging


Testing virtual 1442 card reader/punch functionality

My final test last night had failed to complete the read cycle - which I had modified to resolve a race hazard I detected in the time when I was changing the card column number and thus the driven bits into the 1130 core would change. First task is to look over that code, find and correct the problem as well as set up diagnostics in case I didn't resolve it on the first try.

I spotted the flaw immediately when I looked at the VHDL, so back to testing as I intended to last night. I ran in single instruction mode to watch what happened. My read cycle FSM should be interlocked to require the XIO Read instruction to occur for each of the 80 card columns, but when I issued the first read, the FSM ran through all 80 columns.

Corrections made, it was back out to the machine to run the final testing for the morning. Running in SMC mode gets the columns lined up correctly in memory, but running in full speed produces these flaws:

  • The off by one error in memory contents versus card contents, again
  • Not seeing any non-zero values in the prepunch buffer when I fetch it after two cards are read, yet the second pass through the virtual card routine should have copied the pre-read buffer over to the pre-punch buffer. 
  • Python fetches the pre-punch buffer twice, apparently seeing the XIO IR twice (again). 

When I am back from time out with my valentine, I will dig into this some more. By late afternoon, I was able to look at the system again. I made some adjustments but wasn't certain that I had it fixed - definitely need to do testing. I changed the diagnostic LEDs to look at the pre-punch buffer contents rather than the pre-read buffer. This way I will know if the copy-over from pre-read to pre-punch took place correctly.

If the data copies over but is fetched as zeroes, my problem is in the transaction that fetches the buffer contents. If the buffer is not copied over, the problem is instead in my copy process. The test suggests that the data is correctly copied over but somehow not picked up correctly by the fetch transaction.

The good news is that the off-by-one error is gone - the card images are correct in core memory. Also, the double XIO IR problem has been eliminated. As a card reader, the virtual 1442 is just about ready to use. A touch more testing and I could consider it ready for prime time.

I still have to check the behavior when a card file is used up, making an empty hopper, with or without the 'last card' checkbox being selected. Without the last card checkbox, the virtual 1442 should become not ready, waiting for a new file to be opened which places new cards in the hopper. If the last card checkbox is selected, then the DSW that is returned after the last card is read will have the 'last card' bit set.

My remaining testing will focus on the rest of the feed process - fetch the result of the pre-punch buffer, then copy pre-read buffer to pre-punch buffer. When that is working, I can test that the punch function will update the pre-punch buffer properly. One final test of the stacker select operation rounds out my testing plan.

A good day of progress on the virtual 1442 device adapter and a pleasant way to close out the evening.

Implementing physical plotter (1627 equivalent)

I switched over to the Digilent Nexys2 board and began by assigning pins to the 1627, 1134 and 1055 devices. I then routed them to the appropriate bits of the 104 input and 104 output bits carried over the fast link between this slave fpga board and the central ztex board. Once this is ready, I can begin wiring the plotter into the Nexys2 and conducting some tests of my adapter logic.

Implementing physical paper tape reader/punch (1134 and 1055 equivalents)

I set up the pins and routing for the paper tape read (1134) and paper tape punch (1055) devices which I will drive from the Nexys2 board remotely. The 18 signals needed for the paper tape devices were assigned out of my 104 input and 104 output signals over the fast link.

Saturday, February 13, 2016

SAC Interface fan-out strategy change, more progress on 1442 function


As I power up and down to test my SAC Interface functions, I have had a few cases where the 1130 is misbehaving until it is power sequenced. One time it stayed in Reset continually. Another time the machine operated as if it were in SMC (single memory cycle) mode even when the main switch was set to Run or SI. I hope this isn't an SLT card getting ready to fail hard. I suppose there could be other explanations such as oxidation on the rotary mode switch contacts, but I worry.


Debugging 1442 reader/punch function

There are a few problems I observed with the test last night, including having the main feed cycle FSM skip ahead before the 80 columns were read with XIO Read instructions. That may be due to an error in the read FSM jumping ahead, since the read FSM signals the main feed one to cause it to advance. Time for diagnostic indicators to track down the failure circumstances.

I discovered the flaw that allowed the feed FSM to jump forward, and corrected it, but am dissatisfied with the read cycle FSM as is is introducing the wrong timed delays between columns of the card. I reworked it a bit until it seemed suitable. Armed with the changed code and new diagnostics, I went out at lunchtime to try this out.

I found that annoying problem where one of my output chips on the interface board needs to be moved slightly to make it work - I think it is intermittent +5V to pin 14 - which jams in bits in the middle of each word. However, my logic did manage to loop for all 80 columns and provide the opportunity for the XIO Read on each one. The contents changed and I saw the index that points at the column in the buffer advancing.

I can't consider this a complete validation of the read cycle as the data pattern couldn't be matched exactly due to the jammed bits. The read cycle completed and my main feed FSM moved on to inform the Python program of the false XIO IR that asks it to fetch the punch buffer contents. At this point, I had the timeout on the USB link. Time to debug the fetch logic and its FSM.

I found the cause for the stall of the routine that fetches the pre-punch buffer contents back up to the Python program. I incidentally found why the DSW had some random bits indicated and cleaned up the cause. I had some time in late afternoon where I could get back out for further testing.

While preparing to test, I took some time to tack solder a jumper on the +5V pin of the errant chip and bring it over to a known good power source. I don't want to be experiencing the jammed bits any more.

Having completed the jumper, the jammed bits went away! I was able to examine the contents of the memory range in core where my program reads in the card image - words x0040 to x008F - and see that while it is mostly correct, somehow the card data from card column 1 is placed in words 00040 and 00041, with column 2 at 0042 and so forth. I will put in diagnostics to determine which of two places causes the off-by-one problem:
  •  I could be storing the data in the pre-read buffer this way
  • I could be handling the XIO Read offset by one
My logic will latch up and show the value of a known bit for column 2 as it is stored in the buffer. Another place will latch up and show the value of that bit when the buffer is read during an XIO Read. Finally a third process will latch up the known bit at the time we write it to core during the XIO processing.

Something is going awry in the machine when I run at full speed, as it is jumping past a wait instruction and running amok until it hits a parity error fetching some corrupted data word. I think I know how to bypass the problem with a tight loop rather than a wait, but this may be a symptom of the erratic failures I am seeing with the 1130 at other times.

After some more study of the logic and testing, I refined the method for reading and writing the buffer memories for pre-read and pre-punch stations. I went out to test in the morning and got all the way through the read to the operation complete interrupt on IL4. The card image was stored in core at locations 0x0040 to 0x008F but still offset by one - meaning column 1 of the card is in locations 0x0040 and 0x0041 then columns 2 to 79 are stored but not column 80.

I successfully saw the message from my Python code that the punch file was not open so we didn't try to write what we fetched from the card buffer. However, one anomaly remained - I received the fake XIO IR twice, which means I have a flaw in my FSM that doesn't recognize the end of a read cycle fast enough to stop posting a second XIO IR function code. This is a case where I am off by one FPGA clock cycle in how I set up the XIO IR function code, but it should be easy to fix.

I worked on some diagnostic LEDs and other information to track down my off-by-one error with the card contents, plus looked over my fpga code for the cause of this and for the timing flaw that emits double XIO IR codes.

The double XIO IR problem should be fixed, as I could see where this could occur and design to block it, but the cause of the off-by-one on card reading was more obscure. I found an unrelated flaw and corrected it, but need to keep on varying diagnostic outputs until I see the problem.

To resolve a design flaw in the Xilinx ISE toolchain, I had to put it in Windows 7 compatibility mode. It slowed to 10% of its previous speed, requiring quite a few minutes to do each round of synthesis to bitstream generation. Painfully slow.

The results of testing showed I had successfully blocked the double XIO IR emission, and that the contents of the second card column in the pre-read buffer were correct, not the off-by-one value I am seeing in core.

All this tells me that the problem I am having involves the logic to process the XIO Read instruction, which latches the value of the data from the pre-read buffer, for use with the XIO Read logic, then bumps the card index. I must be bumping the card index too early, before the XIO Read has completed.

I spotted a possible race hazard - the XIO Read logic turns off busy as soon as the processor enters T6 state, then the busy condition turns off. The core write is not yet complete, so it is possible that changing addresses on the read buffer in the next fpga cycle (20ns) could corrupt what is going into core.

I changed the FSM to wait for 1.15ms (time for a card to move 1 column over in the physical 1442) before I increment the address. I am not sure how this would result in the off-by-one failure I am seeing, which is in the opposite direction of what could happen with an early bump of the buffer index. If this were the problem, I should be card column 2 stored in word 0x0040 and spurious data in word 0x008F, rather than seeing column 1 doubled.

I did see a spot where I might have triggered a second IL0 too early, which might be causing the program to do two reads and bumping the address in the IOCC but the fpga is still working on column 1. This kind of race hazard could produce the symptoms I am seeing. I fixed this as well.

My pre-dinner testing was impacted by the flaky 1130 behavior. The machine would only execute a single memory cycle (one phase of an instruction at a time), but it did show me that at this speed, the data is arriving in the correct memory words, not off by one. If the problem was caused by a race hazard, I wouldn't see the issue in SMC mode but it would occur at full speed Run mode.

The 1130 powered up into perpetual reset earlier today, but a power cycle fixed it. Then later tonight I hit the SMC mode issue above. I fear that I have an intermittently failing card that is going to become a hard failure soon.

I decided to try one last time tonight, hoping the 1130 will come up normally. It did, but I discovered that the off-by-one was back. Further, my logic was no longer triggering the Python program, probably because it wasn't finishing the read cycle at all. Time to finish up for the night.

Change in strategy for medium and high speed links to additional boards for connectivity

I decided to drop the idea of medium speed links to Arduino or equivalent systems and concentrate solely on the high speed error correcting links to other fpga boards which can then fan-out or communicate as they wish.

I will use the first link to accomplish connections to the plotter, paper tape and some other physical devices. Everything should be in place on both ends for the link which just mirrors over a hundred signals in each direction, which means I just have to assign pins on the remote fpga board and do some modest coding to hook this through the link to the 1627 adapter logic.

Implementing physical plotter (1627 equivalent)

I updated the logic to pass the 1627 output signals over the high speed link to my Digilent Nexys2 board, which will handle the fanout to the 1627 interface electronics. I still have to work on the Digilent side to pick up these signals and route them to chosen output pins on the board.

Implementing physical paper tape reader/punch (1134 and 1055 equivalents)

Similarly, I updated the logic to pass the eight output punch channels (for the 1055 punch) out on the link, plus the two drive signals to move the motors on the 1134 and the 1055 units. I look for the eight channels from the 1134 paper tape reader on the input side of the fast link. As above, I still have to change the Digilent side and assign pins to the signals.

One additional task is needed for the paper tape units. I have to design and build the driver and sense electronics to interface the physical boxes to the Digilent board, accommodating the 3.3V logic levels and low current limits of the board.

Thursday, February 11, 2016

Virtual 1442 now loading pre-read buffer and triggering interrupts


Debugging 1442 function

Did a few rounds of different diagnostic signals, still not seeing the defect but it can't hide forever. When I found a set of signals that showed me I did one pass through the logic to load the pre-read buffer, but the overall index never got up to 78 or 79, I suspected I was somehow ending the transaction wrong or not properly picking up the new column starting number on subsequent passes.

I spotted a race hazard, a place where a confluence of bad timing could cause me to skip some or most of the write transactions. I closed up the opening but also stuck in additional diagnostics to more firmly establish what is happening.

The next round of tests did not work any better nor did I see any indication of what went wrong. Time to break up the push on the Python side so that I can see that state of the mechanisms at the right snapshots. With that information, I noticed a spot that was resetting my index to the starting column for all 10 values in a transaction.

I am now moving on to debugging how the XIO read will populate the pre-read buffer locations as the virtual card reader issues 80 interrupts and the program responds 80 times with an XIO Read and then a reset of the interrupt level. At the end of 80 interrupts on level 0, we get an interrupt on level 4 which informs the program that our card is complete.

Moving forward nicely. The FSM completes the push of the card image, triggers the read cycle to issue 80 interrupts on IL0 which should trigger 80 XIO Reads and BOSCs from the program. I found a timing issue with when I triggered IL0 that forced a rapid loop.

The FSM also moved forward to trigger a dummy XIO Init Read, which my Python code uses to begin fetching the pre-punch buffer up from the FPGA. If this had completed by requesting all 80 columns, the FSM would then have copied the pre-read buffer into the pre-punch buffer and triggered the operation complete interrupt on IL4.

I put in some diagnostics to show me that I do seem to be correctly loading the pre-read buffer, since I displayed the first column top 8 rows on my GUI and they matched what I first sent - a good sign. However, the read emitter function is not working properly yet.

I did some minor cleanup and improved the instrumentation, then did a last round of tests tonight. The main FSM jumps ahead to send the faked XIO IR to the Python program but the 80 column card reading has not yet finished. Perhaps because of the skip ahead, the FPGA and Python get out of sync and I see timeouts. I think it is that the routine to fetch the pre-punch buffer is not working correctly and stalls.

Tuesday, February 9, 2016

Solid progress debugging virtual 1442 card reader/punch function


Testing 1442 reader/punch logic

Imagine my surprise to find that I had not instantiated a module to respond to XIO Control, which explains perfectly why my adapter logic didn't trigger on the attempt to read a card. Doh. Software reads using an XIO Control with a modifier bit to signal Start Read. I added that in along with some good diagnostics.

I found the spot to jumper off the recognition of XIOs to area code 2, which is the 1442 device. Gate A, compartment C1, card F3, pin D06 will be jumpered to ground, pin D08. This keeps the Area 2 signal false at all times. That leaves my adapter free to respond to any XIOs aimed at the virtual card reader. Later I will replace the simple jumper with a nice SPST switch and label it "Disable 1442 support".

blue jumper disables 1442 adapter inside 1130
I was thinking about how to set up the dual mode for my 1442 logic, allowing it to capture the cards read and punched on a real 1442 as a mirror device or to replace a real 1442 with a virtual device. I think I have a sound strategy, which I will apply once the current logic, purely virtual, is working right. When in mirror mode, the output punch file is the only file used and will contain any card columns read on the real 1442 (plus any columns subsequently punched in the same card image).

I found a comment somebody posted on an EDA board that the too many bits false error I have been hitting can be fixed by setting the Xilinx ISE tool to windows 7 compatibility mode. I did this and so far no more errors, which were happening almost every other time I tried to build a new bitstream. Crossing my fingers this works.

I have my new Artix 7 75T chip based board but will continue my testing with the current Spartan 6 16C based board since I believe I have to switch over to the Vivado design suite from ISE in order to build logic for the Artix. That brings a whole set of possible problems that I don't want to trigger right now. Since my current logic is less than half the size of the Spartan 6 board, I don't have to make a move right away.

New board, FPGA more than 5X capacity of old board
My first test with the XIO Control included still didn't fire. I was able to test my jumper - without the jumper, an XIO Sense Device receives a DSW of 0x2001 which has the not ready bit plus another condition. With the jumper installed, the DSW is 0x0000 which means the inboard 1442 adapter is disabled as intended.

I dug into the logic and found that my trigger to spot when an XIO is executing on behalf of the card reader took the area code from my UCW table, but I had incorrectly initialized that to 00011, area code 3, instead of area code 2, 00010. The fix was made and I got back out to test once the bitstream was generated. Still no sign of the false errors now that the Xilinx ISE toolchain is in Win7 compatibility mode!

Now my logic saw and responded to the XIO Control, correctly saw that bit 13 was on, indicating Start Read, but my logic in the Python program failed to see it properly. I mistook it for an invalid Control code. I proceeded to correct a series of Python code flaws hoping to finally get to the point where I pushed down the card image to the pre-read buffer and began triggering fpga logic again.

I confirm that my write logic is pushing 80 words of data in 8 transactions, loading the pre-read buffer. What should happen, but does not, is the last push of the data should move the 'feed cycle' FSM forward but I see it sitting in the idle state. I am now narrowing my look at the FPGA logic that handles the push of the pre-read words and the feed cycle FSM.

I thought I knew what was wrong but I still am not seeing the 1442 kick off its feed cycle after the data is pushed down to the pre-read buffer. I am going to need plenty of diagnostics as well as to pore over the logic. With only 7 LEDS (plus eight bits I could display on the GUI), it may take many cycles picking sets of signals until I find the most informative set.

After more progress, I ended the evening with the feed cycle moved to its armed state and waiting for the write process that loaded the pre-read buffer to signal completion. Somehow that next step is not take. Now I now what to zoom in and watch.

Monday, February 8, 2016

Testing underway for 1442 function, plus preparing my replica 1627 plotter for attachment


Implementing and testing virtual 1442 card reader/punch

I finished the logic but keep flirting with yet another flaw in the Xilinx ISE toolchain. I get phantom errors in bitgen that I have too many bits for FDRI, which will go away, usually, if you do a Project Clean, restart the toolchain and run the generate again. Discussed quite a bit on various internet boards, as are the several other highly annoying flaws that waste design time.

Once I have a good generate I will fire up the system for the first test of the 1442 function. This will be more challenging from a testbed standpoint because it takes more hand toggled code to drive a 1442 properly. There are interrupts on level 0 for every column to which I must quickly respond with the XIO Read, as well as on level 4 for the completion of the card. I think I am ready.

I powered up and ran a test. It didn't work properly but that is not surprising because my hand code is still funky. I found some errors in my IOCC formats, for example. It will be hard to single step through the code to check it. With a 1442, there is very tight timing required to issue the XIO Read after each int on level 0.

If I tried to run the code in single instruction mode, a real 1442 reader would throw an error as the Read wasn't done fast enough. My virtual reader won't throw an error but it inexorably advanced through the columns triggering IL0 even if the Read didn't happen, so if I ran in SI mode it would not capture any card data.

I saw no response to the XIO Control with the bits to command a Start Read. I looked through the FPGA logic and found some code I thought was cleverly handling the case when the real 1442 adapter is live, but it wasn't. Worse, I forgot to tie down the 1442 adapter so that it was trying to respond to the XIO. I ran out of time for testing today but know what I need to do tomorrow - some diagnostic indications in the fpga and Python to help track what is occurring, once I have the jumper in place to disable the 1130's 1442 circuitry.

Implementing physical plotter (1627 equivalent)

I began by testing my interface electronics for the plotter, intended to allow the Strobe model 100 to act the same as a 1627. Something was not working correctly, however the movement buttons themselves work properly. This suggested the level shifter chip, since that is the main unit that sits between the input connector and the remaining circuitry that seems to be working properly. It was time to do some diagnostics.

This turned out to be solely an issue of bad connectors, a weakness of some of my project work. I was able to remove the connectors and validated I can drive the plotter left, right, up, and down as well lift or lower the pen to the paper. The plotter will be one of the devices that has its signals driven through a high speed link to another FPGA board which

I believe I have correct logic in the fpga matching the inboard adapter that IBM would install in 1130 systems if they came with a plotter. Mine does not, but the SAC Interface box will stand in for that logic. This will be the first thing I connect once my 1442 adapter is working solidly.

Sunday, February 7, 2016

Fought space limit in FPGA and almost back to testing 1442


The new FPGA board is due to arrive Monday afternoon which is pretty good for a shipment from Germany for an item I just ordered and from a small operator, Ztex, who does not have a big warehouse and shipping department.

I began commenting out large chunks of my logic (1053 code, 1132 code, 1403 code) but the number of LUTs seems to be remaining at the same level. Something seems to be wrong. I might have another Xilinx toolchain failure that is falsely reporting the out of space problem. I will hack some more out (well, comment out everything) and see if this is a problem caused by ISE.

I commented out the two SPI links, all the CRC checking and still am above 100% on LUTs. Something is wrong, but I don't yet know which of three possibilities is the cause. It could be some code I added to the 1442 support which somehow implied a huge number of LUTs, it could be that my logic legitimately needs more than 10,000 LUTs and had been under the limit because of signal trimming when portions weren't completed yet,  or it is another of the bugs that crop up in ISE which cause bizarre behavior

If the problem is an ISE defect, this will go away since I have to upgrade to Xilinx Vivado to make use of the Artix chip. If the problem is that I legitimately need that many LUTs, then my much larger chip on the new board will give me the breathing room I need. The only case that is bad is the one where I coded something that implies a huge LUT count, but I am not noticing the error I made.

I think the only way to get to the bottom of this is to comment out the 1442 code and see what happens. If there is not a huge drop in LUT count, then I will comment out some of the latest changes to the transactional engine. Hopefully something will drive a major drop in LUT count.

When I commented out one process that sets a word from the card buffer, based on the index of the current column being processed, the size plummeted to 18% of LUTs used. I uncommented the process and did another synthesis just to confirm whether this was the problem. Indeed, the simple looking code drove me up to 109% of LUT capacity from 18% without it.

It appears that this is strictly due to the logic to mux 16 bits per column times 80 columns down to the single 16 bits needed for the column read. Since I am light on use of distributed and block RAM, I will convert the buffers into a memory in order to free up LUTs. The challenge here is that the code to load the pre-read buffer and dump the pre-punch buffer, which had been implemented to dump 10 columns in a single cycle, will now take 20-30 cycles instead of one. I may need to adjust the short packet timeout to accommodate this extra delay.

With this change, I can remove ALL the commented sections and get back to testing the 1442 function. I was able to get all the way to bit generation with no space issue but there was an issue with how I used the block ram that was only flagged during bit generation. The software inferred a 9K block RAM component for each buffer, but has a flaw that fails to initialize the contents. Xilinx flaw with 9K ramI don't need any initial contents but this stops the creation of my bit file. Most significantly, only 37% of LUTs and 3% of block RAM required so my change rebalanced the chip usage nicely.

Implementing and testing 1442 reader/punch

I converted the two 80 card column buffers from LUTs to block RAM, since I had plenty of the latter but was short on the former. The dump and load of the buffer becomes a bit more complicated as I had to watch where the various control signals are driven and have a process to step through ten sequential locations in the buffer.

Once I resolve the Xilinx ISE issue with 9K block RAM initialization, I should have a good bitstream to load into the fpga. I think the solution is to use the block RAM generator rather than having the ISE recognize my VHDL and convert it to the component.

Friday, February 5, 2016

Need to upgrade to bigger FPGA to continue developing SAC Interface Unit


Implementing and testing the virtual 1442 function

My research into the 1442 adapter highlighted that a XIO Control with Stacker Select bit set will NOT cause an operation complete interrupt. Therefore, the only handling I need when a SS is issued is for the Python program to detect that and cause the punch buffer from the fpga to be written into the alternate file (if open). This eliminates the need to force op end interrupts by a transaction from the PC; it can be handled purely locally in the fpga.

After some discussions with Peter Vaughan of TNMoC (The National Museum of Computing in Bletchley, UK), it seems there is value in also supporting a 1442 mirror mode, capturing card images of physical cards as they are read or punched on a real 1442. The logic to support this is relatively close to the logic for the virtual function.

From a design standpoint, I need to add a switch to the 1130 to enable or disable its 1442 adapter and I need some means to tell the fpga to operate as a mirror or a virtual adapter. I can send a transaction from the Python code that tells the fpga which mode it will assume.

In the Python program, I need some logic to cause the first card to feed, when a new file was opened for reading and/or punching, when the program issues a Start Punch. On a real 1442, readying the device with cards in the hopper causes one card to feed into the pre-read station, but nothing is yet in the pre-punch area. The 1442 adapter logic will force a feed cycle on the Start Punch if this is so, advancing the card from pre-read to pre-punch in order to begin punching.

Hopper empty condition turns the device Not Ready, although a last card may be in the pre-read station and the next to last may be in the pre-punch station. Pushing the Start button on the read causes it to go ready and allow one more Start Read but has also set the Last Card bit in the DSW.

As I made the refinements to the 1442 logic that I had mentioned yesterday, the unthinkable happened. I ran out of space on the fpga! Too many LUTs needed. I suspect that some of my registers and buffers could be placed into block ram, freeing up a decent number of LUTs, but from this point I am going to have to start optimizing and making choices. Drat! This could slow me down.

In lieu of all the juggling and optimization, or removal of desired functions, I just bought a replacement ztex board, with the same 100 I/O pins but a much larger and faster Artix 7 FPGA on board. I moved from the 2.01 board with a XC6LX16 chip to to the 2.13c board with the XC7A75T fpga chip. I also get a huge onboard RAM as a bonus. It should arrive in about a week, meanwhile I can comment out some portions of the design to free up LUTs for near term testing.