Thursday, August 17, 2017

Disk emulator role of Alto tool now handling read operations, working on write/update


Today I set up and validated the basic engine producing the ReadClock and ReadData signals that are emitted by the drive whenever the ReadGate is active - the disk continually rotates under the head and the bit patterns from each sector sequentially stream out through those signals.

Following that, I modified the logic to become the generator process that will build up a sector image. This begins at each sector mark and
  • counts off words of zero as preamble padding
  • emits a sync word for each of the three records
  • fetches data from memory to load the serializer for each word of the record
  • calculates a running checksum of the words for each record
  • loads the serializer with the checksum value at the end of the record
  • emits words of zero as a postamble padding
  • cycles bad to do preamble, sync, data words, checksum and postamble for the next record
Since a sector is comprised of three records - header, label and data - there is an 'inner' process to actualy emit the preamble words, sync, data words, build the checksum, send out the checksum and produce the postamble. It is called from the master generator process, given a count of words, memory starting address, and preamble count.

The key to everything is the serializer, which is loaded with words by the generate record logic at the appropriate time. It gets a request for the new word from the serializer after that process has shifted out each bit of the word to become ReadData pulses. The generate record logic just passes the appropriate new word to the serializer - zeros for padding, a sync word pattern, memory contents for data words and the checksum result - as the requests for new words arrive. 

I worked out from the serializer, making sure it was shifting out bits when the ReadClock pulse occured and had it ready for the ReadData pulse. Too, it had to issue the request to load a new word when it output the final data bit. 

With the serializer proven out, I then debugged the record generator, ensuring it fed the right values into the serializer. The scope shows a plausible stream of bits for the sectors but just to be sure, I will set up triggering for one specific sector number and carefully inspect the bit patterns to be sure they match what should be read. 

These match the patterns I should see, including proper checksums. I varied the cylinder using seeks and altered the head between upper and lower surface, further validating that the data patterns being emitted are correct. 

With the bits streaming out of the emulator properly, available for the Alto to do a read, it was time to build up the logic that supports writing or updates. When the Alto turns on the WriteGate signal, it will be producing clock and data pulses on the WriteDataClock signal line. 

FSMs must do a sync to the incoming stream to establish the clock vs data boundaries, since the input from the Alto is a combined signal that always pulses for clock bits but the span between clock bits will pulse only for a 1 value bit. This will occur when the GenerateRecord process is beginning its sync word phase, if WriteGate is on. 

Sync allows me to deserialize the incoming data bits, producing words. It will be slightly tricky to spot the edges of the incoming signal and determine the time of the start of a bit call, 600ns long. 

The required actions are:

  •  Pick off edges and match bit cell train when we are looking for a sync
  • Turn on sync state when the first '1' data bit is seen
  • Start deserializer
  • Feed deserializer with bit stream
  • switch off memory reading logic and begin UpdateRecord machine
  • As the deserializer fills, write that word into memory
  • Keep a running checksum of the data words
  • At the right time, compare the deserializer output to the calculated checksum
  • Flag errors in writing the records
  • Loop in higher level UpdateSector logic to track postambles and preambles
  • Higher level UpdateSector fires off UpdateRecord to regain sync and repeat
One possible error situation is an overrun, where my GenerateSector machine is ready for data words while the Alto has not yet issued the sync word. I may have to put in hold-off logic to force synchronization. The Alto is juggling various tasks in addition to the disk sector and disk word microcode tasks, thus the actual start of an activity has some jitter from sector to sector. 

I have a completely populated and wired board for the emulator role, consisting of the circuitry to shift levels between the FPGA's 3.3V needs and the TTL relatively high current signals between the Alto and a real Diablo drive. What is still to accomplish is to build the female socket into which the Alto's cable will plug.

As expected, aligning to an async incoming stream of WriteDataClock, determine which pulses are the clock pulses and attaining synchronization is difficult. First is entrainment, where I determine the start of the 600ns bit cell. This begins when WriteGate goes active and depends on the fact that the preamble is many words of all zero data bits.

After entrainment is achieved, the logic has to accommodate jitter, based on the real edges, to stay entrained. That means we can pick off data bits reliably. Sync occurs when the first '1' data bit arrives. The next bit cell is the start of the data words of a record. When the checksum has been read and compared, we drop sync but keep entrained unless WriteGate drops.

With the entrainment and deserializing logic built, the challenge was testing without a real async and jittery input stream. I turned to the Xilinx simulator and attempted to create a pulse pattern with plenty of jitter and edge cases, to see if my logic will properly entrain and extract data bit values as well as detect a sync state.

I am now working through the logic and the simulator results, fine tuning to yield reliable entrainment and then sync detect. It is now early evening and nearly time to shut down for the day. Since I have a session with the Alto tomorrow, the weekend is when the next burst of progress can take place. 

Wednesday, August 16, 2017

More code conversion and programming for the UofM card archiving task


I had volunteered to bring my Documation card reader and a copy of Brian Knittel's PC interface to the museum and archive almost 80 decks of cards that represent some experimental data from 1970. I captured an exact image of every card, lossless because it doesn't assume any particular encoding just captures all 960 hole positions per card.

I sent them to U of M along with the Deckview program (also from Brian) to allow them to look at all the card images. I described the file format, which is a binary file with a 16 bit word per column, thus 160 bytes per image. The column image has rows 12, 11, 0, 1, through 9 in the leftmost 12 bits and 0000 as padding.

I received an email asking why they aren't in Excel or CVS (sic) format as that is how they want them. I guess they don't have any programmers available there, so I dashed together a quick Python program to deal with the decks.

Almost every deck has a header card, which has a pattern of holes punched that forms big letters M, T and S each spanning six columns. The holes themselves that make up these characters are almost never a valid character. There is some other data to the side, including the MTS Job Number that can be tied back to the listings that wrapped the decks.

First card as captured
The remaining cards are numeric characters or spaces in Hollerith , apparently (by inspection) these are four column numbers, 20 to a card, right justified. Thus the number 639 would appear as " 638" while the number 1015 would be "1015" in its four columns.

Second and all subsequent cards seem to be 20 four-column integers

I really can't tell if these are indeed four column integers (what Fortran programs would code as an I4 format) or some other division into fields, thus dividing these into 20 fields by commas is pure guessword.

My quick program changed all non-numeric, non blank characters to asterisk, which only occur on the header card. The other cards had a comma character added after each number except for the last on a card. Viola, Comma Separated Values (CSV) that can be ready by Excel.

I hope this is the last I hear of this effort - a couple of days reading cards, each twice to ensure the data was captured correctly, plus all the dialog and now the data conversion.

Tuesday, August 15, 2017

Seek logic proven out in disk emulator version of the Alto disk tool


I altered the VHDL for the seek simulation to avoid a race hazard in the way I set the timer value for the next countdown in the FSM, then tested again. I first forced the time for the arm movement to zero allowing me to verify the settling delay of 14.4 ms will work properly.

It was essential to first change the button signal to a one-shot otherwise the Strobe line is held on, the seek state machine hangs till that drops, which elongates the seek to the time it takes the button to mechanically switch on and off. With the one shot I removed that factor.

I now have a 15 ms seek time, which is basically the settle time, regardless of the span of the movement. Once the rest worked and I had validated the calculated difference in cylinders on the logic analyzer, I added in the arm movement delay.

It now appears to produce the correct time delays for various seek distances. I did uncover one defect in my simulation. If the Alto sets the requested cylinder address to the address the drive has already attained, the ReadyToSWR line should not go off at all. It is a no-op in that case. For any non-zero distance, the line should go off after it sees the strobe leading edge.

My logic to control the ReadyToSWR signal needs refinement, therefore I devised a change, compiled it and tested again. It now appears that I have exactly the behavior I wanted. All the times are right on spec and the related signals work well.

I moved on to working up the logic that produces the signals that would be seen under the read head. That means at each SectorMark, we begin with the 29 words of zero, see the sync word, shift out the two words of the header record while accumulating a checksum, shift out the checksum and then insert ten words of zero before the next record in the sector.

Writing from the Alto will be compared against the continual read process above, to sync up against, then we will aggregate and write the header words, etc into memory and validate the checksum sent to us. The write logic need do little except look for sync words at appropriate times, fetch the words from the Alto, build the checksum and store away the words. Much simpler than the read process.

Monday, August 14, 2017

Debugging seek timing simulation


Testing resumed today, both with the oscilloscope and the logic analyzer. With what I have completed, I can check out everything related to basic operation, virtual disk spinning and seeking. This includes the signals FileReady, ReadyToSWR, AddrAck, LogAddrIntlk, Sect1, Sect2, Sect4, Sect8, and SectorMark.

It is important that they are the proper length and occur in the appropriate relationship to each other during operations such as seeking to a new cylinder. My test setup used a button on the fpga board to simulate the Strobe signal coming from the Alto, but alas it does not have a one-shot so that it repeatedly triggers the seek logic while depressed.

I added a stage in the seek logic that will not wrap up unless the Strobe line is logically 0. This does work although the button remains on long enough that I still could get additional cycles. Not with seeks that are valid, because my simulation of the time delay of movement adds many milliseconds to the seek process, long enough for my stab at the button to have switched it on and back off.

The time for a seek is not being properly set, thus I have to dig deeper into the logic that calculates the seek distance (number of cylinders to travel from current to new position), then waits 0.6 ms per cylinder moved. At the tail end of a movement there is a 14.4 ms delay while the heads settle into position.

I exposed the calculated number of cycles on a connector, hooked to the logic analyzer, and tried to capture it. Too, both the calculated distance and the calculated number of cycles are displayed on the seven segment displays as a quick aid. I found some flaws in how I was handling this and reconfigured the logic.

Somehow I get a delay of 200 ms minimum whereas I should have 30 us before an ack, 5 us for the ack, 600us for each cylinder moved and 14.4 ms for settle time at the end. That is, just over 15 ms not 200. Undoubtedly another case of VHDL that looks straightforward but doesn't work as intended.

Sunday, August 13, 2017

Disk emulator testing and further design


The disk emulator is now spinning up virtually when an image is downloaded to its RAM and the command is issued to turn on the drive. It goes ready and should be producing sector marks, rotating sectors at the proper rate and otherwise acting right. I hooked up the scope and did some initial testing.

The emulator was behaving correctly - all the signals I monitored did what they should. Sector marks arrived every 3.33 ms, with the sector number cycling between 0 and 11. The drive showed it was ready to seek, read or write.

I pulled a wire to cause the Strobe signal to go active, but with a cylinder request of 255 which is invalid. As expected the logic responded with a Logical Address Interlock condition since only values between 0 and 201 are valid for seeks.

I will set up the logic analyzer allowing me to check the timing of all the signals involved in a seek. Too, I have to see that all the lines respond as they should.


I popped open the scope and discovered that I had a wire loose. Soon fixed and my horizontal scan is back in operation. Unfortunately, still have the interference between the digital and the analog sections, causing dashes across signal traces and smearing sideways of digital characters.

Hmmm, guess there is something else to find and repair but I was close. The chip I replaced is indeed the switcher that determines whether the CRT horizontal plate amplifiers are driven by the digital or the analog side. I am seeing mixing of both - digital signals on screen at the time of the analog sweeps and analog signals interfering with digital signals.

Since my switching chip was blown out, but now works properly, I have to assume that the event that caused its failure also took out one or more other components in attached circuits. Time to study the schematics and look for candidates to investigate. 

Friday, August 11, 2017

Building disk emulator functionality to replace disk drive on Alto


Given the disk crash we had on our spare drive, which we anticipate is repairable with sufficient cleaning of the heads, and a crash that another Alto owner suffered last week, I decided to move forward with the disk emulator version. This version will attach to an Alto disk controller card and respond as if a real Diablo drive and cartridge were present.

I had worked out some of the logic simply to test the disk driver version and thought through most of the functionality in the past. I will fork off a version of the tool and begin logic development. In addition to different logic loaded into the fpga, it needs an alternate plug-in board that routes signals through output drivers and input level shifters.

The emulator board will require a female connector to which the disk controller cable will attach, but will implement terminators on board rather than requiring a specific connector for an external one.

It will drive 11 output lines and shift 15 input lines from the TTL voltages of the Alto to the 3.3V of the fpga board. By comparison the existing driver board implements 15 outputs and shifts 12 inputs.

The difference in counts, otherwise symmetric, is due to the elimination of the Erase Gate input signal for the emulator. Since we know that an Alto ties Write Gate and Erase Gate together, whenever we see the Write Gate line we know the value of and needn't sense Erase Gate.

Before I did anything, I backed up the current state of the Disk Tool project. I then found a way to copy it to a new project, the disk emulator. Only when I knew that changes to the emulator won't impact the disk tool at all, was I ready to begin writing VHDL.

I built a couple of the emulator boards assigning fpga pins as input or output, using the level shifter or driver chips and routing it to the appropriate pin of the connector that will hook to the Alto disk controller cable.

The logic is interesting working this way. Essentially I will have a continuously running process that "spins" the disk producing SectorMark, another that runs continuously to produce the clock and data bits for each sector as it passes under the virtual disk head. The outputs ReadClock and ReadData are gated by the ReadGate signal but otherwise being continually generated by the reading process.

Only when the WriteGate signal is activated will I block the reading of words from memory, decode the WriteData&Clock signal to form words and stick them away. Not sure how to handle the writing side, likely another process synced with the continually reading process. This will be the only tricky part.

The Alto will be giving me padding words, sync words and other content while the WriteGate is on, thus I have to shadow the Alto to know which are data words for the header, label and data records in the sector.

Thursday, August 10, 2017

Replaced my horizontal switching chip in Tek 7854, still not working (but different)


The new IC is installed on the PCB but placing that back into the scope is more trouble than I expected. The board is small, very roughly about 2" x 6", and is inserted through a cutout behind one of the four plug-in sockets in the lower bay of the scope.

I noted where the six coaxial cables and one other connector are inserted, but the bigger issue is the 9 slender wire rods that must slide through holes in this board. Each is a rectangular copper wire about 3" high standing off the lower common board and onto which my board must slide to make its contacts.

With the holes about 1/64" in size and spread across the board, I have to finesse nine separate wire rods into the holes simultaneously before I can slide the board down to its final mounting position. The slightest bend or miss-positioning of one is enough to block the entire board from sliding.

Fortunately I can look from the underside to see how these nine rods are touching the PCB. Thus it is just barely possible that I can use tools to hold the rods in position, with the board slightly tilted, moving forward so that earlier rods stay in holes but new ones are maneuvered to their holes.

The layout is one hole in the upper right, three along the left side from mid to mostly top, the rest down low and to the right. They are not as aligned as it sounds, except for one group of 3 and another of 2. This will take very good lighting and lots of patience.

Thursday morning I set up the lighting and lined up my tools for the first attempt. Placing the board over the pins was not difficult once I had tools that could reach the pins individually. I placed all cables back as they were originally and buttoned up the scope.

Now that it is installed and cabled up, it is time to test this scope out. The key will be ability to use both left and right timebases to sweep across the screen and to view un-distorted characters from the digital section. 

Drat! Not only did this not fix the original problem, but now I have no horizontal defection at all in analog mode from either B plug in. The digital mode characters still shake. The one ray of light is that the horizontal mode switching now works properly, choosing the left or right B plug in and alternating or chopping.

Something more pernicious is happening here. The digital mode sweeps, thus my new chip is at least connecting the digital left and right signals to the horizontal defection amplifiers. The analog left and right signals do not appear to be switched, however.

I will need to do some scoping of these signals, I guess, to figure out what is happening. Working hypothesis is that additional failed components are affecting the scope, with a less likely but small chance that my replacement chip is failing too. Something is wrong but I will put this aside for now until I am ready for the more involved digging necessary.