It is awkward to switch between monitoring writing and reading, as the signals to be sent to the logic analyzer are mostly different. I finally set up a slide switch that will alternate between banks of signals appropriate to each operation.
With it all generated, and the corresponding changes made to two saved logic analyzer settings for reading and writing, it was lunchtime. I fired up the testbed for a first capture of a
WriteSector right after I finished my meal.
The capture looks good up to the end of the first record of the
WriteSector. My trigger conditions are to wait for the
WriteSector FSM to enter the sector wait step, then trigger on the
gotsector output of the sector matching logic.
This assumes that
gotsector is issued at the beginning of the correct sector. I can see that
SectorMark is on when
gotsector is issued, but can't verify the correctness otherwise. I will do independent tests to check for this later.
I did discover the cause of the sporadic power-down of the disk drive I had been experiencing. The low cost power supply that delivers +15 and -15 to the drive seems to thermal out after a period of operation. In spite of the specifications that assert this can power the drive, it clearly can't or it has some internal defect. The solution is shorter test intervals with a cooldown in between.
I watched the delivery of the proper header record, all the times and the
WriteData&Clock states matched what should be happening. Since my
ReadSector logic appears to read this record properly, but finds a checksum error on the label record that follows it, I need to watch further along in the
WriteSector operation.
At first I had worried that the Alto drops the
ReadGate between records but I do not and somehow feared the drive wouldn't resync, but the schematics proved that to be a needless worry. All
ReadGate does is gate or ungate the output of the separator which is emitting clock and data pulses, it does not affect anything that would cause the drive or logic to sync up.
I did some tests using the logic analyzer trigger output to trigger the scope - looking at
SectorMark at the time that I received the
gotsector signal. They were essentially at the same time, except for a few 20 ns cycles used by my matching logic. As long as this is the correct sector number, I am beginning to write at precisely the proper place - the beginning of a sector.
Next up, I triggered the scope at the same
gotsector point, advanced to the time when the sync bit would be emitted to start the label record, and did see that transition, both on the logic analyzer and by reading from the differential amplifier inside the drive via test point 1.
The odd dip of the signal is occurring when writing, which definitely causes the data separator to be confused and return junk. I still don't have official statements about the validity of the
ReadClock and
ReadData signals when writing, only innuendo from comments in Alto design documents, ergo I can't clearly flag this as a flaw.
|
Reflected write signal showing sync word 1 bit is 2 us to right of center, but also notice dips |
I did see an anomaly - the bits being written for the label record are not correct - I see the first four bits of the data word going out as '1' but the intended content is not that. I can't double check the word showing in the logic analyzer against this because I am only emitting the low 8 bits of the word. I do see what appears to be an incorrect memory address, so I will look there.
I will also emit the sector number so that I can check it against the
gotsector signal, since I am going through the investment of a 30 minute cycle to generate the new bitstream with high data word and sector number signals.
Testing with the new signals and the modified logic analyzer formatting showed me two things right away. First, the sector number is indeed 0000 when
gotsector fires, which is what it should be. Second, the fetched word to serialize is incorrect. Not sure why, but time to zoom in one the memory access as part of the
WriteField process.
Time to look for race hazards or timing errors in my use of the memory access FSM. Another half hour of idling about until I could watch the signals I selected - bits 16 down to 1 of the memory address and the low order three bits of the fetched data word. I can easily check this against the contents of RAM which I can fetch through my USB link transactions.
It appears that it is a timing issue, which I hope I corrected by adding one extra cycle before loading the serializer with the output of the RAM access. I also switched the instrumentation to show the full output data word from memory.
It appears I am writing the contents correctly now - verified at least through the header and label records - but the checksum that is written out by
WriteSector is not valid when doing a
ReadSector. This is undoubtedly also a timing issue that just needs a bit of adjustment to get right.
As I suspected, the signals from testpoint 1 are clean, with no dips in the middle, when doing a read. Similarly, the separated data bits are clean and correct. This tells me that at least with this drive, it is not possible to 'loop back' the
ReadClock and
ReadData to check what is being written.
|
Testpoint 1 while reading - sync bit 1 to left of center and first word x7900 |
|
ReadData bits corresponding to signal above - good data separation |
I am fairly certain I found the problem. It is a classic mistake where a clocked process in VHDL is coded as if it were sequential - like programming - when in fact all changes to signals only take place at the next clock edge.
I updated the checksum by XORing the last word of the record, then later output the checksum as the next output word for the serializer. Sounds correct, but in fact the latter step will use the old value of the checksum, prior to the XOR. Thus we leave off the value of the last word from the checksum.
The change was made, as well as displaying the running checksum on the logic analyzer - after the obligatory 30 minutes of processing - and I tested again. First I run a
WriteSector and observe the checksums generated and written by the logic. If that passes, I will switch over and test a
ReadSector.
As a means of testing checksum generation, I built a little spreadsheet and used that with the label record value of the real sector 0 I am trying to write. The checksum should be x7CF3 if it includes all eight words of the record.
|
My spreadsheet to calculate checksum values for records |
This explains why the
ReadSector validated the checksum of the header record but rejected the label and data records. The contents of the two words of this header are 0000 and 0000, which produce the same checksum whether I drop the last word or not. XOR by 0000 leaves the checksum unchanged.
When the new bitstream was ready, I set up the testbed and ran my
WriteSector. The checksums were correct. When I ran the
ReadSector, it completed with no checksum errors on any of the three records. I dumped the RAM up to the PC and validated that it was a word for word copy of what I tranferred down to RAM to write to sector 0.
I will call it a day - nice success point in the testing so I leave the testing on a high. Next up is to adapt or write a program so that I can easily set up all the sectors of cylinder 0, which had been inadvertently erased, into the RAM allowing me to restore all of cylinder 0 to the contents found in the xmsmall.dsk archive that matched this cartridge.