Disk emulator and other work, week ending April 27, 2014


Thinking through the activity on the SPI link between the Arduino and the 1130 fpga, I had to restructure my logic in the fpga. The key is the way that these links work, with each SPI transfer simultaneously sending a byte in each direction. The data sent by one side has to be chosen without having seen what will arrive from the other end, unlike the normal transactional pattern where a message goes in one direction, the other side makes decisions and sends its response message back.

It is possible but wasteful to operate SPI in the normal transactional mode, that is ignoring data flowing in one direction and ignoring the opposite data flow on the next transfer. This, however, requires more transfers than a good plan which is making full use of the directional simultanous transfer that occurs. A good way of thinking of this is that each transfer is really a swap or interchange, which takes a byte from each side and hands it to the other.

My state machine for the protocol over SPI takes a step at the point that a transfer completes, e.g. we have received the byte from the other side. At this point we can figure out what to have transferred to the remote side but it will be sent at the next step. We set it up one step early in the state machine so the outbound byte is ready when the SPI swap occurs.

I moved the logic around to set up the outbound data for the following step inside each step, thinking through what I needed to determine the right outbound information. As I revamped the code, I did save a few transfer cycles when I realized places where I had enough information to send data a step earlier than I had assumed.

Simulating away and also testing with the live hardware, I am debugging this section by section and function by function. For example, I set up the set of 1130 signals that the adapter watches when an XIO Control command is executed, watching it successfully
    - track the state, fetch the seek count and direction,
    - spin waiting for the 15 ms that a physical drive would take to complete the short seek,
    - in parallel, look at each of the current sectors to see if any are 'dirty'
    - for each dirty sector, trigger a writeback transaction to the Arduino
    - after all writebacks are done, trigger the seek request to the Arduino to go to the new cylinder
    - wait for another 22+ ms that the adapter logic will wait
       (to ensure that the disk head oscillations are damped enough to remain over the disk track)
    - meanwhile, the Arduino will send down eight sectors with cache load transactions to put in the buffers
     - set up the request for an IO interrupt to report operation complete.

I saw the SPI protocol transactions triggered but didn't simulate their full action - that will come later. Moving forward, I verified that XIO Start Write will kick off a write transaction, get the correct sector and buffer address, fetch the word count and properly wait for the sector to spin in front of the virtual head and wait the proper time between words before requesting cycle steals to transfer the memory contents into the sector buffer.

It was getting very tedious to count off microseconds and control all those signals, particularly during LOOOONG delays such as waiting for disk rotations. The solution was to automate - I put in processes in the test driver module to generate the T and X clocks, to respond to cycle steal requests with a granting of the signal at the proper times, and that allowed me to concentrate only on key data values to set up at those times.

I did have a great aha moment when something really clicked in - even though I knew that assignments to signals inside a clocked process all take effect at the clock tick, I continue to write the code as if it were sequential imperative statements - software when it is not. A process based on the rising edge of a clock, with the following statements:
    NUM <= NUM + 5;
    LOG <= NUM * 2;
    IF LOG = 16 THEN
    .  .  .  .  .
Will take the current value of the signal NUM at the time of the execution, and it will be bumped up by five at the time of the clock tick. It will then take the same current value of NUM, double it and that would become the new value of LOG at the clock tick. Finally, the comparison will take place on the current value of LOG, not on the changed value from the process.

A programmer would assume that if the initial value of NUM was 3 at the time just before the clock tick, it would be bumped to 8, that value of 8 would be doubled and 16 assigned to LOG. The If condition would seem to be true.

If it were 3 before the clock tick, what really happens is that after the tick, NUM is 8, LOG is 6 and the condition was considered false. The result of each statement is independently determined but is held as a intended value, only made active at the clock tick. All of the values are simultaneously changed, not in a sequence like the VHDL statements imply.

There is a sequence inside the process, which is why this can be confusing, with documentation referring to statements inside VHDL processes as sequential. If there had been two different assignments to NUM, the first assigning the value 1 and the second assigning the value 0, only the last assignment, 0, will be emitted at the clock tick. The nonsequential aspect has to do with signals on the right hand side of assignments or within conditional statements. Those are all evaluated with their initial values, with any changes (left hand side of assignments) occuring afterwards.


This pair of kits, the SBC6120 computer and its front panel FP6120, create a PDP/8 system with a fairly realistic panel of blinking lights and switches, able to run most PDP/8 software. The SBC6120 was completed last week, but a few parts were not yet on hand to wrap up the front panel. As of Monday afternoon, I had the LEDs, mounting hardware and ICs needed, leaving only one component, a rotary switch, before this is ready for testing and signoff.

I am extremely happy that I took the conservative move of testing one of the LEDs before soldering them all onto the board. The LEDs used in the design have their positive lead longer than the negative one, reflected in the assembly instructions and board markings. However, LEDs are sometimes reversed in polarity. Since I selected these alternative LEDs, not the parts specified in the official list, I decided to give one a test.

That was a fortunate decision, because these LEDs have their negative leads longer, the reverse of what would be expected. Had I soldered all of them in, I would have had 52 connections to remove in order to get the LEDs properly installed. I also used the testing to verify the apparent brightness and current draw for the LEDs with the resistor values employed in the kit; no deviations were found for those specifications.

Tacking some wires to temporary switches, I had the board ready to test. I assembled the SBC and FP together, added a IDE CF adapter and brought up the stack. All looked good, with the firmware correctly detecting the type and size of a CF card and several SD cards in a SD to CF adapter that was in turn placed into the CF to IDE adapter.

However, the chosen card I wanted to use, a Toshiba 256MB CF card I had on hand, produces a hang on the IDE detection, followed by a timeout and failure to detect the card. I can access it fine in PC with a CF to USB adapter, but no luck in my chosen setup. A Monster 32GB UDMA CF card is not detected at all, another sign that it is a compatibility issue or some card mode that is not right.

I don't have a spare SD card to put in the 'russian dolls' series of adapters, but not getting good results with the two CF cards that are spare (256MB and 32GB). I found only a few posts mentioning SBC6120 firmware hanging on startup at the IDE interface step, but these resolved to use of 2MHz 82C55 chip or bad solder joints. Neither of those situations pertain here.

The problem was discovered - a break in a trace, apparently caused as I clipped off a component lead whose pad sits very close to the trace - for one of the two address lines to the 82C55A chip, used to select among the three 8 bit ports and the control word. Essential to read and write through the chip to the IDE interface. Soldered a small bridge wire around the gap and verified continuity. Tested the system and all is good with the PDP 8 system now.

My final parts arrived and were added to the assembly, which is now complete. It awaits installation inside a nice box but is otherwise done from a hardware perspective. I ordered a nice 10 pin IDC to DB9 cable, but it was wired in a nonstandard way (actually one of two common wirings) so that the pin assignments of the DB9 and header were not the same. RX and TX are on pins 2 and 3 of a DB9 and are on the same pins of the header, but the wiring in this cable did not connect pins 2 and 2 or 3 and 3 together. I opened and corrected the cable wiring.

Operating computer after completion of the project
With everything working, I built some OS/8 disk images and can now operate my PDP-8 system in all its glory. Others have saved and made available disk images with most of the famous classic programs and languages, which I have installed on my system. For example, the original Adventure (Colossal Caves) game, chess, star trek, yahtze, on and on and on. Many of the famous 'computer art' programs that print an image using characters on a printer - Snoopy is a well known one.


A friend gave me a nice board that holds up to two double wide SLT cards, offering plugboard connections from all the pins. This will be an easy way to test out the replacement SLT card as it is developed, plus I can use it to study my small stock of SLT cards to be sure I know the exact behavior and characteristics needed.

SLT test fixture

No comments:

Post a Comment