Work on various peripheral adapters week ending March 30, 2014


The speed with which I read and write from the SD card is just too slow to deliver the desired disk performance. I discovered a handy chip that hosts 1Mb of RAM, nonvolatile due to battery backup, accessible by the SPI serial link protocol.

It would give me access to any sector in under 1 ms, fast enough to read the sector over the serial link and I could even build only one FIFO for the sector in the fpga side logic. A sector rotates by the heads in 10 ms, thus a simple implementation with no prefetching at all would only miss a rotation if the request were within about 1 ms of the time the sector would be coming up to the head.

I can still create FIFOs for all eight sectors and load them all during any seek, to be assured of perfect timing accuracy for programs running on the 1130. I should be able to load all 8 RAM sector buffers within about 6 ms. Since the smallest possible seek (1 or 2 cylinder seek takes 15 ms for movement and 22+ ms for settling at the end, for a total of 37ms), all the prefetching and loading is invisible to the user.

I finalized the transaction definitions for the link between the 1130 fpga and the Arduino. These transactions are 3 to 649 bytes long, with the longest streams used to upload/download 321 word sectors. If nothing has to be done for either side, the transaction is dropped after three bytes, while a seek needs one additional byte to complete.

SPI is not just bidirectional, it is simultaneous bidirectional streams that form a ring if you don't inject new bytes on your end, reflecting back the data sent by the other side. The master pushes a byte into the interface and bit for bit, as the data from the master goes out to the slave, bits from the byte set up by the slave come in to the master. This means the master deposits a byte to start a transaction. The slave has set up a byte on its end waiting for the master to start. The two sides effectively swap bytes and at the end of the swap, they see what other sent.

The normal concept of a transaction is A sends 1 to B, B sends 2 back to A, A sends 3 to B, etc. Here, what actually happens is that A sends 1 to B and simultaneously B sends 2 to A. The decision for what to send as 2 has to be known prior to receiving message 1, which is different from the usual transaction sequence where you have 1 in hand before sending out 2.

One can make use of the link unidirectionally, just sending nulls back or injecting nothing, letting the bytes sent from one side come back to the sender. In that way, A could send 1 to B and gets 1 back itself, then in the next swap B sends 2 while A doesn't inject anything, thus A sees message 2 but it also goes back to B a cycle later. This adds delays to the exchange but does let the sender check the returning message to verify that no corruption took place. Variations are obviously possible as well.

The Arduino Mega board I am using has four USARTs onboard, which include the ability to each act as an SPI master, in addition to the main SPI hardware port. I intended to use those to separate the SPI traffic for the SD card shield, which has its own closed software controlling the link, from the traffic that will go to the fpga and to the ramboard.

However, the designers of all the Arduino boards have not linked the clock pins for those USARTS to any external pin! Thus, this capability is inaccessible. I will therefore have to try to code my own interface to the SPI hardware and use it when I know I am not using the link for SD card access.

I control two of the SS pins myself, thus I can select which of the three devices on the shared SCK/MOSI/MISO lines is being used at any time. This is because the SD card SS line is only activated when it is processing one of my requests to flash, otherwise it is high (deselected) allowing me to select one of the other destinations by making the associated SS line low.

My testing to date shows that my piggyback on the SPI hardware is working, coexisting with the SD card shield library code. I received my Microchip serial NVRAM components yesterday - 1Mbit ram accessible by SPI protocol and using battery backup to preserve contents. I was going to breadboard a pair of chips to verify my link between Arduino and the ramboard as well as the chip selection logic I will use to address which of the eight chips holds the sector we are accessing.

Instead, when an Arduino shield prototyping kit arrived, I decided to build the entire circuit on the shield, using IC sockets to allow me to remove the chips if I need to make changes or start over with the board. I began soldering the leads but plan to complete the breadboard and  the test after I return from my trip and holiday.

My remaining time will be dedicated to the last tests of the card reader interface, as it would be very nice to consider that done for the time being. Long term, this needs a modification applied to let the reader handle cards with a notch at the upper right side of the card, something the Documation machines can't do on their own, and it needs the physical work to hide this in a mock 2501 reader - frame, skins, coloring, placement of Documation inside, affixing the operator panel, and similar cosmetic/physical steps. That can wait for months without impacting the usability of the reader.

I plan to add a function to my Arduino code for the disk emulator which will dump a virtual cartridge from the ramboard to SD card. That would allow me to skip all the writeback to flash of the sectors which are written by the 1130, since they would remain in the cache of the ramboard and could be stored onto the SD card to update the permanent cartridge image. This gives me the flexibility to fork off a new version of the cartridge if I need to, or to have all changes made to a cartridge disappear by simply skipping the dump of ramboard back to SD card flash.


I coded a serial port handler and began integrating this into the line printer adapter logic in the fpga. I make use of an open source serial port VHDL design, just as I leverage other open source designs such as my SPI slave function.

I have my backup fpga board in place to do testing of the printer link and logic, but ran out of time this week due to the other activities that took precedence.


I received some very clear high resolution photographs of the 7342 card that we must manufacture, since one of them is missing from the 1130 being restored at this Museum in Germany. I have most of the schematic and parts specifications complete, but need a bit more time to work out the remainder.

The pictures of the card face and back are good but not quite good enough to properly record all the printed circuit lines on the boards. There are places where I can't be sure what pins are connected.

Reflections and lighting conditions make certain spots on the board appear as virtually identical colors for both traces and the board surface itself, thus one can't be sure if a trace is connected to a pin or just runs along past it. In other locations, a trace is partially obscured by a component on the top of the board, but with a different camera angle or perhaps a small amount of shifting of the part to the side, the trace should be visible.

A very few spots exist where the printed circuit trace is not going to be visible. The most significant of those is underneath the metal square can that houses the four dual diode (FDD) module. One can't see which pins are connected, where incoming traces are terminated, and the connections to two terminations underneath that could be unrelated signals bridged with a short trace or could be connected to some part of the FDD module.

I haven't found existing card schematics that have a similar circuit arrangement for the part I can't yet resolve. If I had a model, I could validate the plausibility that this card matches that, understand the circuit, and come up with a good prototype design for the replacement card. That could be simulated, then could be breadboarded and verified. This will have to wait for my return from my business trip to Brazil and subsequent two week holiday in Hawaii.


I simplified and rebuilt the logic that synchronizes real Documation card reading with the virtual card reading actions that are driven by 1130 requests. Getting the right triggers for state machines can be challenging with electromechanical devices where various conditions can occur asynchronously. For example the state of the preread station in the virtual 2501 temporarily drops from full to empty during every read cycle, but returns to full unless we have a feed check or run out of cards in the hopper.

Basing a state machine transition on whether the preread station is full must take into account when the decision is made, because of this time varying 'false negative' that is reported during a feed cycle. Similar risks exist for many of the conditions that reflect entry to a given state - these must be sampled only at specific times in order to be valid.

At this point, the card reader interface is operating as desired. It correctly models the 2501 reader with its preread station, allowing for NPRO, run-in, and the proper behavior when the hopper empties. I can either add cards and it will continue reading, or press start to enter the last card state. It provides correct status to the XIO Sense Device commands. The contents of memory are the correct card when I read from the 'last card' state - I get the card that was previously read physically but held in the 'preread station' in the adapter, a FIFO queue, then delivered with the last XIO Initiate Read command.

I experienced a feed check a couple of times, which the adapter properly delivers to the system, and was able to make a card that consistently forced a read check on the physical reader. The read check does not seem to be handled properly, as the virtual 2501 stays in the ready state when it should light the read check lamp and turn off ready. I can see that the signal arrived into the adapter logic in the fpga, thus I have a defect in my handling this condition.

The error should be reflected when the 1130 next issues a feed cycle for the virtual 2501 that would try to read what we put in the preread station as well as feeding the next card from hopper to preread.

This error is handled by doing an NPRO, then placing the last card from the stacker (the one we physically failed to read correctly) into the hopper and run it in. I need a more sophisticated test to verify that we maintain the right sequence of card images as far as the programs in the 1130 are concerned, but this seems like the right behavior.

I must also check the time when a read check is seen by the virtual 2501, this should definitely not be delivered until the N+1 feed cycle (next after the one we are in). The card with rips or other defects that cause a read check would probably go quietly into the preread station on feed cycle N, but have the problem seen by the photocells as it moved out of preread on cycle N+1. The operator's error recovery for this type of error is slightly different than for feed check, where after an NPRO two cards must be removed from the stacker and put into the hopper.

I added code to pad the FIFO queue up to the full length of 80 characters, since a read check error causes the Documation to cease emitting index pulses for the remainder of the card, thus I don't see all 80 columns. The logic I added will pad the FIFO out when we hit an error condition.

Normal mode operation is completely satisfactory, thus signed off. Pending the check of error recovery appropriateness, this adapter is complete. I am still having the issue with read check errors, that these are not being detected by the IBM reader adapter logic which gets my logic out of sync. I attempt to force a read check on the 2501 (virtual) read cycle, but whatever I am doing is not triggered an error. At least I know where to look.

With my flight to Brazil leaving tomorrow midday and my evening wrapping up, I have to put this aside until I am back, in spite of my desire to wrap this up, check it off and put it 'on the shelf'.

No comments:

Post a Comment