CONVENIENT IMPLEMENTATION BY IBM
Other uses of the similar mechanism, e.g. Diablo on Xerox Alto or DEC RK-05, have the processor's device controller generate the clock pulses along with the data bit pulses, thus snagging any data written by the CPU requires capturing async incoming pulses and separating data from clock.
Fortunately, since the IBM 1800 and IBM 1130 were the first uses of this mechanism before it was widely licenses to other vendors, they did things a bit differently. Sometimes the newer ways were an improvement, but I am glad for one of the original design choices.
In later versions of the drive, the CPU sent the target cylinder number to the drive which moved as many cylinders as needed in a single operation, while the 1130 implementation of the drive only moves 1 or 2 cylinders per operation. This puts more burden on the device driver software or user application but otherwise has no impact on me.
In later versions, the data to be written was delivered in a single line called Write Data and Clock, which was the raw stream that would be amplified and turned into flux reversals by the write head. If I intercepted such a line I would need to shadow the clock to know which pulses are clock, to be stripped, and which are a 1 data bit and which interval with no pulse is a 0 data bit.
In the original 1800/1130 version, the drive produces a 720 KHz clock whose normal and inverted state are output as 700KCphaseA and 700KCphase B. The CPU device interface logic uses this to time the emission of data bits in phase B, leaving the drive to generate the clock pulses during phase A. The only bits I see on the Write Data line are data bits that are a 1. If there is no bit during a phase B, I infer a data bit value of 0.
HOW TO FIND START OF STREAM OF 321 WORDS AT FIRST BIT
The sector begins after the sector mark ends with a stream of zero bit cells for 250 us. Since every data bit value is 0, there will be no pulses coming out of the Write Data line during this time, although I will see the 700KCphaseA and 700KCphaseB signals alternating.
The next word is a sync word, a word with value x8000 whose pattern on disk including check bits is b00000000000000011110 thus when I see the first 1 bit coming out of Write Data I know I am near the end of the sync word.
I will check to be sure that the next four bits following the one I just detected are 1, 1, 1 and 0 because that proves I am seeing a sync word being written. If not, I will force the Write Error state to turn on which will stop the CPU from writing and block any further operations to the disk.
Once I consumed that stream of 1, 1, 1, 1, 0 the very next bit cell will be for bit 15 of the first of 321 words in the sector. It is possible that the CPU may write fewer than 321 words, thus I am always prepared to safely cease the capture of written data. I then use the 700KCphaseB as the indicator of each bit cell, counting out 20 per word and then 321 groups of 20 to complete a sector.
CAPTURING UP TO 321 WORDS AND WRITING THEM TO THE FPGA RAM
Each occurrence of phase B opens a window where I look for any 1 value coming from Write Data. I latch that in as a data bit value 1, but if the phase ends without such an incoming value, I have detected a data bit value of 0. At the phase A time following, I shift the bit into a shift register to assemble a word.
The bits on the disk surface start with the low order bit of the data word, bit 15, and continue leftward to bit 0, after which there are four check bits. I have to inject the bits into the bit 0 position and shift right on each cycle to end up with a 16 bit value in the proper orientation for the 1130.
I begin the write request to put that newly captured word into RAM at the address associated with the cylinder, head, sector and word count. I bump the word count and move on to error checking the final four bits.
During the capture of the data I increment a two bit binary counter whenever I have captured a data bit value of 1. As each of the four check bits is captured, it also increments the bit counter. A proper check value causes the counter to end up with the value b00 indicating that our written word has a number of 1 bits that is evenly divisible by four, the error detection algorithm.
If the bit counter is not b00 then I force the Write Error state. This again stops the write from the CPU and blocks the software from further disk access.
When the WriteGate control signal is switched off, we are done writing words. My logic should go back to the idle state where it waits for the next write from the CPU.
ROTATIONAL MODELING ONLY USEFUL IN LIMITED SCOPE
For generating the bit stream during reading, I have to model the actions during the disk rotation very faithfully, deciding where each clock pulse and data plus is placed. I have to generate 250 us of zero data bits, the sync word, then spit out all with words along with clock pulses and the correct four check bits.
When writing, I don't have the same control over timing and won't be able to predict where the clock pulse is or where the sync word begins with its first 0 data bit. Fortunately I don't have to. I only need to know in sequence that
- we have Write Gate on and are seeing 700KCphaseA and 700KCphaseB
- a bit on Write Data while in 700KCphaseB means we are inside the sync word
- proper verification that the bits I see next are the right check bits 1,1,1,0
- every 700KCphaseB is a new bit cell of the 20 that make up a word
- every 20 bit cells I begin a new word
- when Write Gate is dropped or I finished capturing 321 words we are at the end
- bad check bits or a sector mark with Write Gate active is an error I inject back
Thus my rotational modeling isn't needed at all except as a simple indication that we moved beyond the fall of the sector mark, easily gleaned from the modeling circuit's output.