Where am I – Track sector display for the 1541

Introduction

I would like to report less about the structure of the disk format, but rather about how to get the head position relatively easily.

Information how the format of the Commodore 1541 floppy disks is constructed can be read among other things here: Visualizing Commodore 1541 Disk Contents

When formatting the floppy disks in the VC1541 from Commodore, a sector header is written before each data part. This area contains exactly the desired information that is needed for a track and sector display.

How to get the data?

Getting the raw data is not that difficult. The necessary information is exchanged between the GateArray (325572-01) and the VIA (6522).

At this point, I will simply take the VIA 6522, on slot UC2, to access the required data.

The following lines are required:

  • PIN 2-9
    • PA0 – PA7 / D0 – D7: The data lines D0 to D7 from the read/write electronics are connected here
  • PIN 13
    • PB3 / ACT: The lines that also control the red LED on the front of the floppy drive, indicating appropriate activity
  • PIN 17
    • PB7 / SYNC: SYNC signal, which corresponds to 0xFF on the data line.
  • PIN 39
    • CA2 / SOE: Signal coming from the VIA to the R/W electronics. Only then can the ByteReady signal be generated. The VIA is ready for data.
  • PIN 40
    • CA1 / BR or ByteReady: Thus the GateArray signals that a new byte is present on the data lines.

By the way, the data lines do not mean the lines that exist between processor, RAM, ROM and VIAs, but only the 8-bit wide connection between VIA and GateArray (or the discrete version in the old Longboard variants).

A trip into bits and bytes

If you now connect a logic analyzer to the lines mentioned above and load the directory, you already have everything you need.

What catches the eye directly is the contiguous block in the lower left area. In addition, a signal on HIGH can be seen underneath, which fits to it.

Directly below you can also see a signal, which is almost over the entire screen width on “HIGH”. This is the activity LED. The moment when the motor is switched on and the head starts reading data. It takes a little while (after all, the disk rotates at 300 revolutions per minute, which is 5 per second) until the number of revolutions is constant, and the SYNC signals are detected.

The contiguous block enlarged then looks like this:

What you can already see very well on this picture are the small gaps, between the data lines (the upper 8 bars).

These are the SYNC signals that are written during formatting. From this it can be recognized when the next block with data comes.

First of all you can recognize a SYNC, then a short area, again a SYNC and then a longer area.

The shorter area is the sector header and the longer one is the area where the actual user data is located.

We are only interested in the sector header here.

This is now the complete sector header of a sector. Before each sector this header is written and contains the data, which track and sector it is, the disk ID, that it is a sector header and a checksum.

So with this data the floppy drive always knows where the head is.

The ByteReady signal indicates when a valid byte is present, which the VIA can then process or holds ready for the CPU.

If this signal is used as trigger at a falling edge, the bytes can be displayed in numerical form by the Logic Analyzer. These can be seen well in the light blue stripe.

What you can see especially well is the SYNC signal, which logically consists of 0xFF, so all lines are pulled HIGH.

I have enlarged the area once more.

The sector header

If you have already read a little deeper and have information about the disk format and its structure, the first thing you would expect is a 0x08. This is the start of the sector header, or a 0x07 for the user data. followed by a checksum, sector, track and the disk ID. Then comes a blank space which contains 0x0F after formatting.

However, if you look at the ones that have just been recorded, somehow it doesn’t add up.

It is a bit hard to see, but the following bytes have been transferred:

0x52 0x57 0x55 0x29 0x72 0xD2 0xB5 0xD5 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55

Now comes the “mean” part, because these bytes have been encoded in the so-called GCR process.

So it is not enough to simply translate the bytes from hexadecimal to decimal system, because then only nonsense comes out. First these bytes must be translated.

GCR coding

All the reading and writing is based on quite sophisticated timing, the SYNC marks, and the hope that it really is always 300 rpm.

The whole thing would also work if there were not the zeros, or logically LOW. Two or three “LOW” can still be mapped quite reliably via the timing, but then the detection becomes difficult.

So a system was thought up so that no LOW occurs more than twice in succession. The GCR system, also called group code recording or group coded recording.

For this purpose 4 bits are converted into 5 bits.

Als Beispiel soll direkt der eben gelesene Sektorkopf dienen:

0x52 0x57 0x55 0x29 0x72 0xD2 0xB5 0xD5 0x55 0x55

Why only 10 bytes, or exactly 10 bytes, I will explain in a moment.

First, the hexadecimal values must be translated into binary values.

  • 0x52 = 01010010
  • 0x57 = 01010111
  • 0x55 = 01010101
  • 0x29 = 00101001
  • 0x72 = 01110010
  • 0xD2 = 11010010
  • 0xB5 = 10110101
  • 0xD5 = 11010101
  • 0x55 = 01010101
  • 0x55 = 01010101

Now the easiest way is to write all bits one after the other.

01010010010101110101010100101001011100101101001010110101110101010101010101010101

Now groups of five must be formed from these bits. Therefore also the 10 bytes and not only the actually 8 necessary bytes. We need a number divisible by 5. 5 bytes would have been enough, but we want the whole sector header.

01010 01001 01011 10101 01010 01010 01011 10010 11010 01010 11010 11101 01010 10101 01010 10101

The coding table

What is needed now is the table that contains the coding. So, so to speak, the Enigma for the disk data. And the comparison is even less lame than one would think.

GCR CodeNibbleNibble in Hex
0101000000x0
0101100010x1
1001000100x2
1001100110x3
0111001000x4
0111101010x5
1011001100x6
1011101110x7
0100110000x8
1100110010x9
1101010100xA
1101110110xB
0110111000xC
1110111010xD
1111011100xE
1010111110xF
GCR Table

Now comes a little diligence. For each group of five there is a corresponding 4-bit value. These must be searched out and noted.

  • 01010 = 0000 = 0x0
  • 01001 = 1000 = 0x8
  • 01011 = 0001 = 0x1
  • 10101 = 1111 = 0xF
  • 01010 = 0000 = 0x0
  • 01010 = 0000 = 0x0
  • 01011 = 0001 = 0x1
  • 10010 = 0010 = 0x2
  • 11010 = 1010 = 0xA
  • 01010 = 0000 = 0x0
  • 11010 = 1010 = 0xA
  • 11101 = 1101 = 0xD
  • 01010 = 0000 = 0x0
  • 10101 = 1111 = 0xF
  • 01010 = 0000 = 0x0
  • 10101 = 1111 = 0xF

Now simply recombine the bytes:

081F0012A0AD0F0F = 0x08 0x1F 0x00 0x12 0xA0 0xAD 0x0F 0x0F

The decoded data

And now a sector head is also recognizable. It starts with the byte 0x08. At the end the 0x0F fill bytes can be recognized.

If you execute an XOR operation over the 3rd, 4th, 5th and 6th byte:

00 XOR 12 XOR A0 XOR AD = 1F

Then you get the checksum, which is in the 2nd byte.

The sector is in the 3rd byte, which contains a 0x00 here. Without converting much, this was sector 0 of the floppy disk.

in the 4th byte is the track with the byte 0x12, which in decimal corresponds to an 18. So the head was on track 18 and sector 0 when the Logic Analyzer had just recorded.

The two following bytes are the ASCII values for the disk ID. 0xA0 corresponds to decimal 160 and 0xAD corresponds to 173.

Do not be surprised at these high values. The diskette I just had in here had special characters in it. Mostly one has rather numbers standing there.

Why so complicated?

The advantage of this method is that it works independently of the kernal. Many of this type of displays simply look in the RAM of the floppy drive. Because there is also the current track and sector.

Just stupidly not always in the same place. Depending on the kernal these are different addresses. Now one could intercept all this very elaborately and convert with appropriate tables. But this is error-prone and could change again with a new Kernal.

A display has to come

So basically, it’s not that hard to get this data. Reading the RAW data and decoding it to the real values was actually quite easy.

Unfortunately, this is in many books much more scientific than it is in reality.

To the data, we still had the various other signals. The ACT signal, which is always HIGH during activity. But activity is an elastic term. Perhaps one or the other has already observed that there are moments in which the LED lights up, although the engine is at a standstill. So alone not such a suitable indicator. And in the event of an error, the LED also flashes, so the signal toggles constantly.

One could still evaluate the motor signal. But even this is not always completely reliable, because the motor could also run when no data is read or written (test programs are an example).

The SYNC signal is more interesting, because it can only be triggered when a formatted diskette rotates under the magnetic head.

The ByteReady signal indicates when a valid byte is present. But, this alone is not an indicator. Because this is also triggered when the floppy is not yet at full rotation speed. And because of the way this signal is generated, you will quickly notice that even when the floppy is idle, the ByteReady signal is constantly activated.

Finally there is the SOE signal. But you can’t rely on it alone, because this is in connection with the ByteReady signal.

So a combination of these signals is needed.

A sequence of specific events is best.

Two points can be said with certainty, the ACT and the SOE signal must be on HIGH, if the head is “working” and above all usable data should come out. Then SYNC signals must be present again and again.

This is the best way to go through a kind of checklist. Now you know how the floppy acts when it reads or writes data. And you can go through this, similar to a traffic light control. Green becomes this also always only, if after RED before still YELLOW was indicated (at least with the traffic lights in Germany is this so).

Traffic lights are controlled by so-called state machines or finite state machines. The previous event controls the next event and the current status can be determined at any time.

Additionally, abort parameters are needed. So if the ACT and SOE signal was HIGH and SYNC was also recognized, read errors can still lead to an abort and no more usable data comes. In this case, of course, the FSM must recognize that there is an error and start from the beginning, or branch into an error handling routine.

What is the best way to proceed?

The simplest way to do the whole thing is with a microcontroller for poor people, also called Arduino 🙂 You “collect” half a dozen libraries from other people, write two or three lines of code and become a big developer of a track/sector display.

This is of course the easy way.

Or you do it the “hard way” in hardware. The effort is of course much higher, but so is the learning effect. And you really did it yourself.

So hardware in this case I took a small FPGA. Even if some confuse a FPGA with a microcontroller, I can only say, he can try to “program” one.

Unfortunately, many believe this and then have their problems with it. Because the “code” has similarities with a programming language in some places. But finally one describes the hardware in this way. So you can easily convert this “code” into real chips, and for example build a TTL grave. The latter is even a smaller effort than to take a FPGA.

For this I had divided the whole thing into different modules, respectively I had already written the GCR En-/Decoder for another project, where I can format and copy disks without needing the CPU. Two drives are simply coupled via an FPGA and the two gate arrays.

Then the display controller. To not have to connect all lines for the 7-segment display to the FPGA, I added a MAX7221 in between. It takes care of the charlieplexing, the brightness control and is mainly designed for the control of LEDs.

It is accessed via an SPI interface, for which I also wrote a library.

So it’s much more work than just taking an Arduino, copying other people’s code and then connecting a display. But it makes for it more fun, learns as said substantially more and has it made.

Especially since the libs are always needed for other projects.

I hate breadboards

But unfortunately there is no alternative for just plugging together. And this is what my result looked like.

But unfortunately there is no alternative for just plugging together. Constantly loose contacts and strange errors and problems. But often also without alternative.

And so my result then looked like.

At the bottom left you can see the FPGA. This is the well known Altera Cyclone II miniboard, which you can sometimes get in China for just under $5 or in Europe for just under 10 Euros.

On the board is an Altera EP2C5T144C8N chip. So the quite small version. But unbeatable in price and there is still plenty of room for improvement in terms of resources. It is clocked with a 50MHz oscillator.

Between the FPGA and the display you can see the level shifter. There I used the typical china modules with the Mosfet BSS138 on it.

Speaking of speed. At the beginning I always had a track completely read in. Since the FPGA is so fast, I save myself this meanwhile again.

Complete track read completely unnecessary

In my experiments I had found that reading in a complete track is superfluous and even slower. The FPGA is so fast that the GCR decoding, or encoding (in my other project) is so fast that it is always enough only 5 bytes. And even then the FPGA still waits several clock cycles until the next byte arrives again.

When I talk about slow here, that is of course complaining at the highest level. We are talking about a few clock cycles more. But at 50MHz, that’s really peanuts, at least when the basis is a floppy drive clocked at 1MHz and the data is even much slower (in the kHz range).

So I could reduce the shift registers enormously and save even more resources.

The whole thing goes so fast that the sector display is actually no longer readable. Because with 5 revolutions per second and partly up to 21 sectors per track, you can calculate how often the whole thing changes.

But it’s still a nice gag.

It is much more interesting to get to know the disk format better and to get deeper into the 1541. Maybe I will make a small board from my track display. I’ll have to see what small FPGAs are currently available on the market. Many signals are not needed, because I would only read here, but not control.

Would there be interest in something like this? Write me something about it in the comments.

5 1 vote
Article Rating
Subscribe
Notify of
guest
4 Comments
Newest
Oldest Most Voted
Inline Feedbacks
View all comments

4
0
Would love your thoughts, please comment.x
()
x