Diskettenlaufwerke am Beispiel der Commodore 1541 [video]

Dieser Vortrag wurde am 11. Oktober 2020 auf dem (virtuellen) Vintage Computing Festival Berlin gehalten.

Diskettenlaufwerke am Beispiel der Commodore 1541

Aus der Homecomputer- und frühen Personal-Computer-Zeit sind Disketten nicht wegzudenken. Dieser Vortrag beschäftigt sich mit Diskettentechnologie am Beispiel des 5,25-Zoll-Laufwerks “Commodore 1541”, bekannt als das Laufwerk zum Commodore C64. Nach einer historischen Einordnung (Bänder, Platten, 8-Zoll-Disketten) besprechen wir den Aufbau von Laufwerken und Disketten, sowie das Low-Level-Aufzeichnungsformat (Spuren, Sektoren, SYNC-Marker, GCR-Codierung) und dessen Implementierung in der Laufwerks-Firmware. Danach behandeln wir das Dateisystem-Format und die Datenübertragung zwischen dem Laufwerk und dem C64. Wir thematisieren außerdem Schnelllader, welche die Laufwerks-Firmware durch optimierteren Code zum Lesen und zur Datenübertragung ersetzen, sowie Kopierschutz-Systeme, die Nonstandard-Formate mit verschleierten Leseroutinen verbinden. Schließlich sprechen wir noch über Lösungen zum fehlerfreien Auslesen von antiken Disketten mit moderner Hardware.

4 thoughts on “Diskettenlaufwerke am Beispiel der Commodore 1541 [video]”

  1. Hi Michael. I’ve been an avid reader of your blog for a couple of years. Is there any likelihood of this being uploaded to YouTube to benefit from auto-translate?

  2. Sehr sehr guter Vortrag!

    Hätte ich zu meinen C64 Zeiten nie verstanden – aber schön jetzt die Erleuchtung bekommen zu haben.

    Danke dafür.

  3. Hello Michael,

    some comments on your talk:

    1. At first, I wanted to tell you that your example code for writing data (21:05) is misleading. But, thinking about it, I was wrong. I will write the reason at the end of this bullet point.

    You are right that the bvc loop is used to find out when the byte is written. However, afterwards, it is important to write the new data byte as soon as possible. As you show only that sta/bvc/clv, one might think that it is ok to do some processing, read the next byte from the data buffer, then do a bne or so to the sta and write again. However, this would not work, as the data buffer would have been wrong.
    So, after the clv, the pre-read data byte should be written directly to the output register.

    That’s what the 1541 also does in its firmware. Look, for example, at the routine at $F56E (writing to disk in job loop), especially $f5a5 to $f5cc. $f5a5-$f5af writes the 5 sync bytes for the sector data. At $F5B1, we are still writing the sync marker. $F5B3 prefetches the next data byte to be written, $F5B6 BVC $F5B6 waits for the previous byte to complete, $F5B8 does the CLV and $F5B9 STA $1C01 writes the prefetched data byte to the output port. Then $F5BC/$F5BD loops to $F5B3, so the next byte is prefetched before the firmware waits for the next byte to be complete.

    Now, $F5BF-$F5C8 does the same for the remaining 256 byte. Afterwards, directly after the BVC/CLV of the last byte at $F5CA, the PCR is set to read directly, without further delay.

    Interestingly, this approach is not used in the format routine at $FCBE and following. However, here, it allows for a LDA (),y or LDA 0100,y to read the data to output, there is no pre-read.

    Having read all of this and looked again at the schematic of the 1541 and 2031, I found out that all of my thinking is wrong here, though: The SO line is set as soon as the data byte has been taken over into the parallel-in-serial-out shift register. So, we have enough time to give the next byte into the output port before the next overflow is set.

    2. in the talk, you have your example code for formatting a disk (approx 22:16)
    Here, you have mixed the intra-sector GAP and the inter-sector gap. Your routine writes 11 (= $0B) byte intra-sector, and 9 byte inter-sector, but, the intra-sector gap has to be 9.

    I will not comment on the problem of using fixed values for the inter-sector gap. For the direct driven 1541-II, this will work if the RPM is not too much out of sync, but for the belt-driven 1541, this is much more problematic. That’s why I would still say that a good routine should measure the capacity of a track before writing.

    3. At 31:00, you write that the IEC addresses 0 to 3 are reserved. This is not completely true. In the layer you describe at this point, these IEC addresses actually are valid. In fact, you can send LISTEN, TALK, OPEN and CLOSE on these channels with the IEC routines in the C64 KERNAL.

    It is only the “normal” functions for accessing the KERNAL devices (CHKIN, CHKOUT, OPEN, CLOSE) that make a distinction here and prevent using these addresses, because they have a different meaning.

    And one remark, as it is not mentioned but I am sure you are aware of it: Device 31 is forbidden because its code is used for UNLISTEN (that is, “LISTEN on device 31” is UNLISTEN) and UNTALK (“TALK on device 31”).

    4. At 31:50, you tell that: “Schickt man nach dem LISTEN eine Sekundäradresse, dann…” This implies that the secondary address is optional. While this is true for LISTEN, this is NOT true for TALK. After the secondary address for TALK, the “sender-receiver-turnaround” is executed, which gives the TALKer access to the lines so it can initiate a transfer. This is important, otherwise, the TALK will not work.

    This is important for the spooling you describe (at 32:28): The order you show will not work. You have to set the LISTENer first; only afterwards, you can set the floppy as TALKer, and then, send the secondary address after TALK to initiate the talker-listener-turnaround.

    And, of course, you can also define two or more LISTENers before doing the TALK.

    5. At 35:57, you write that the channels 16-31 are illegal. I tend to disagree. As long as you do not use the OPEN or SAVE secondary addresses, they should be usable. It is only OPEN and CLOSE that are restricted to 0-15, and that’s most probably because Commodore had to put the OPEN somewhere in the “address space” of the secondary addresses.

    I will have a look into the video starting at 36:00 when I have time…

  4. Hallo Michael,

    sehr unterhaltsamer Vortrag.
    Interessant ist auch die Eigenschaft der Apple 3 1/2 Zoll Laufwerke (z.B. A9M0106 für den Apple IIGS) die variable die Drehzahl für den Antriebsmotor anpassen.
    Apple Drawing Number 699-0452-A
    Rotational Speed:
    The motor speed is variable to allow recording to be done at fixed density as the head moves from the outer edge of the diskette toward the center.

Leave a Comment