My improved logic for reading is now cleanly finding sector zero and the sync byte is clearly visible after the preamble of many zero bits. I looked into my synchronizer logic to figure out why it wasn't working properly. It should kick off the byte assembler which takes all the subsequent bits and packages them in bytes with a notification for the consuming circuit as each is ready. However, that isn't occuring.
|Synchronizer byte followed by cylinder head and sector value from sector zero|
The Altair disk has 24 sectors per rotation, with 256 bytes of data in a sector. After a preamble of a couple of hundred bits of zero to match the clocking of the recorded data, there is a sync byte (xFF) that defines which bit is number 0 in a byte, so that the stream of bits can be divided properly into bytes. The first bit encountered is the least significant digit of its byte.
In the Altair format, after the sync byte, there is a header which records the cylinder, head and sector of this record, It has a CRC checksum of two bytes. There is another preamble of a couple of hundred zeroes following the header, then the data portion of the sector begins with a sync byte of xFF. The data field consists 256 bytes of data, a two byte CRC and is followed by a couple of hundred zeroes.
The 1130 format disk has 4 sectors per rotation, with 321 words of 16 bits in a sector(642 bytes). After a preamble of a couple of hundred bits of zero to match the clocking of the recorded data, there is a sync word., Each word on the disk has its individual ECC bits at the end, thus a recorded word is 20 bits long. The sync word is 00000000000000011110 which is x'01' with its ECC. The first bit encountered in a word is the least significant.
In the 1130 format, after the sync word there are 321 of the twenty bit words that comprise the sector. No separate header field is used. The first of the words contains the relative sector number but that is purely a convention of the DMS2 operating system, whereas the controller treats all 321 words as the data field. There is no CRC since each word was protected by its own ECC. More zeroes follow the end of the data field, continuing until the next sector pulse.
On the Pertec drive, the sector count (sector number) from the disk drive changes to 0 at roughly 2.4 us before the sector pulse leading edge. Thus, when the index pulse and sector pulse sequence completes, the drive heads are at the beginning of sector zero. The sector counter is leading the sector pulses on the Pertec drive.
On the 1130 drive, the index and sector pulses occur 180 degrees away from the read/write head location. Thus, when the index and sector pulses occur, the heads are at the beginning of sector 3, the prior sector. The sector number reported is 0. The controller has to wait until the following sector pulse, while the sector number field is just about to switch from 0 to 1, for when it begins read or write operations for sector zero. Thus, the sector number is anticipatory, used by software to issue a read or write for the upcoming sector.
With the Altair controller on the Pertec drive, the user issues a command to read or write a specific sector, with the controller doing the match to the sector number as the trigger to read or write. This is unlike the 1130, thus the sector number is not anticipatory on the Pertec. Instead, it indicates that the sector pulse trailing edge demarcates the beginning of this particular sector number.
I had the synchronizing and byte assembly working fine by the mid-afternoon. Decoding the bytes as they were read from the headers, I did see exactly what I expected from the cylinder field and the sector portion of the sector/head byte. I forced the arm to three locations - cylinder 0, cylinder 3 and cylinder 256 and found the proper value being read for each of them.
The format of the sector/header byte is that the three most significant bits encode the head, while the remaining bytes encode the sector number. I selected the four different heads in turn and looked at the head bits. They were 111, 110, 101, and 100 however according to the Altair controller documentation these are not the right values. In fact, they should be the inverse - 000, 001, 010 and 011.
|Pattern of 111 (plus sector 00000) in left byte is inverse of expected 000|
The fpga board has four seven segment display characters. I use the last two to display the hexadecimal value of the current byte, while the first two record the hexadecimal address of that byte. A pair of buttons allow me to start at the first character and to step through one byte at a time. This should be sufficient for my initial testing.
I started to update the control logic of the board for this read testing, removing the seek testing since everything looked perfect with that functionality. Every cylinder I went to had the correct cylinder number in the header record and read cleanly.