Hello, Guest the thread was called387 times and contains 6 replays

last post from GoDot at the

Fragen zum Floppy-Befehl "B-A"

  • Ein Hallo an alle Floppy-Spezies!


    Ich glaube ich stehe auf dem Schlauch, evtl. ist das verhalten Normal aber ich würde das so nicht erwarten.


    Hier mal ein Demo-Programm mit dem man das Verhalten reproduzieren kann:

    Code
    1. 0 ga=9
    2. 10 open 1,ga,15
    3. 20 rem open 2,ga,2,"#"
    4. 30 print#1,"b-a";0;1;1
    5. 50 rem close 2
    6. 60 close 1
    7. 100 @"$"
    8. 110 @"i"
    9. 120 @"$"

    Am C64 mit einer CMD-HD/81-Partition mit JiffyDOS und einer neuen Disk in #9 bekomme ich zuerst 3159 blocks free, nach dem @Init 3160 blocks free.


    Unter VICE konnte ich das in bestimmten Situationen auch reproduzieren. Ich hab in VICE auf "dev 9:" umgeschaltet, da liegt ab $0a00 die BAM im "Cache" der 1581. Dort waren die Werte richtig. Das Problem war aber die Adresse $35, die wohl, wenn $00, vorgibt "BAM nicht aktualisieren".


    Ich hab auch das 1581-ROM-Listing studiert und das 1541-ERRATA.


    Aus dem ROM-Listing der 1581:

    Code
    1. Abschluss eines Befehls ($c194)
    2. Einsprung von $87EB, $87F1, $8900, $89BD, $89CF, $8A5A, $8B8B, $8BAB, $8BE0,
    3. $8BF4, $8C0C, $8ED9, $96AD, $984A, $9980, $9999, $A20A, $AAFD,
    4. $B283, $B432, $B8CF, $B8D2, $B9D0:
    5. 804C: A9 00 LDA #$00 Flag: 'BAM auf Diskette schreiben' loeschen
    6. 804E: 85 35 STA $35

    Die Adresse $35 steht für "BAM aktualisieren". Nach Abschluss eines Befehls wird der Wert gelöscht.

    Im ursprünglichen Problem war das ein "U2"-Befehl:

    Code
    1. u2 ($cd97)
    2. 8BD7: 20 9F 8A JSR $8A9F Parameter holen
    3. 8BDA: 20 2F 8C JSR $8C2F Kanal oeffnen, Parameter auswerten
    4. Einsprung von $8BD4:
    5. 8BDD: 20 C1 93 JSR $93C1 Puffer schreiben
    6. 8BE0: 4C 4C 80 JMP $804C

    Wie man sieht springt das Programm hier am Ende nach $804C.


    Die Routine "BAM aktualisieren" prüft dann den Wert in $35:

    Code
    1. Wenn die BAM geaendert wurde, dann
    2. BAM auf Fehler pruefen und wenn Ok., abspeichern ($eef4)
    3. Einsprung von $872C, $997D, $9996, $99C2, $9C7C, $A41D, $B280, $B633, $DBEE:
    4. B515: A5 35 LDA $35 wurde BAM geaendert ?
    5. B517: F0 28 BEQ $B541 nein, ==>

    Im Ursprünglichen Problem wurden mehrere Blöcke per "B-A" als belegt markiert, am Ende zeigt ein Verzeichnis auch die richtige Zahl an freier Blocks an. Aber ein @I liest die BAM von Disk ein und hier waren keine Blocks belegt.


    Das Beispiel oben simuliert den Vorgang für einen echten C64. Unter VICE hab ich das getestet:

    Mit dem REMs in 35/36 erhalte ich 3159/3160 blocks free.

    Lösche ich die REM-Befehl erhalte ich 3159/3159.


    Für mich erschließt sich der "B-A"-Befehl aktuell nicht wirklich. Es sieht so aus als bräuchte es immer einen "Puffer"-Kanal. Dazu lese ich aber nichts im Handbuch.


    Sorry wenn ich da auf dem Schlauch stehe, aber selbst folgende Befehlskombi simuliert das Problem:

    Code
    1. @"b-a 0 1 1"
    2. @$
    3. @i
    4. @$

    Bei @V hätte ich das ja noch verstanden. Aber hier wird offensichtlich die BAM nicht auf die DISK zurückgeschrieben und bei @I die geänderte BAM im Cache der 1581 bei $0a00 durch die Version von Disk ersetzt.


    Kann mir da jemand auf die Sprünge helfen? Warum braucht es einen "#"-Kanal im ersten Beispiel damit der Block als "belegt" markiert wird? Ist das irgendwo dokumentiert?

  • Kann mir da jemand auf die Sprünge helfen? Warum braucht es einen "#"-Kanal im ersten Beispiel damit der Block als "belegt" markiert wird? Ist das irgendwo dokumentiert?

    Das ist genausowenig "offiziell" dokumentiert wie die drölfzig anderen Bugs in den CBM-Laufwerks-DOSen, aber es ist bekanntes Verhalten: Wenn man ohne einen offenen "#"-Kanal "B-A" (oder "B-F") benutzt, geht es schief. Es gab dazu mal ein erklärendes Posting in comp.sys.cbm, ich suche mal und editier den Link dann hier rein.


    EDIT: Ich hab die Erwähnung des Posts im Archiv der GO64-MailList gefunden, aber leider ohne expliziten News-Link. Soweit ich mich an die Erklärung erinnere, war die Begründung des Verhaltens ungefähr so: B-A belegt erst die komplette Spur "auf Vorrat" und speichert diese BAM "zur Sicherheit" auf Disk. Allerdings wird die korrekte Belegung dieser einen Spur im RAM gehalten. Beim Schließen des #-Puffers wird die BAM der Disk dann mit den Daten der kleinen RAM-Kopie aktualisiert und somit korrigiert.

  • aber es ist bekanntes Verhalten: Wenn man ohne einen offenen "#"-Kanal "B-A" (oder "B-F") benutzt, geht es schief.

    Danke dafür. :thumbsup:

    Hatte ich mir schon gedacht. Ich komme eher aus der GEOS-Schiene, da ist das weniger ein Thema. Aber in dem Fall ist das eine große Hilfe, denn dann ist mein Application-Fix nicht verkehrt.


    Wobei es im aktuellen Beispiel wohl einen offenen "#"-Kanal gab... evtl. geht es da auch um die Reihenfolge der Befehle... aktuell geht es jedenfalls... :)

  • aktuell geht es jedenfalls...

    Vorsicht, bei Tests immer mal die Disk aus dem Laufwerk nehmen und neu einlegen, damit die BAM auch wirklich garantiert von Disk gelesen wird! Die BAM-Kopie im Laufwerks-RAM ist bei diesem Bug halt falsch und wenn man sich darauf verlässt, kann das böse enden.

  • Vorsicht, bei Tests immer mal die Disk aus dem Laufwerk nehmen und neu einlegen, damit die BAM auch wirklich garantiert von Disk gelesen wird!

    Ähm... wie mach ich das bei einer CMD-HD ??? ;)

    Nein, kein Thema, mit meinen Tests/Demos geht das ja, @I scheint da auszureichen, ich kann das also reproduzieren. Aber selbst VICE unterscheidet sich da wohl vom echten 64er.

  • Das ist genausowenig "offiziell" dokumentiert wie die drölfzig anderen Bugs in den CBM-Laufwerks-DOSen, aber es ist bekanntes Verhalten:

    Noch ein Nachtrag dazu: Auch wenn man einen '#'-Kanal offen hat, funktioniert "B-A" nicht fehlerfrei. Ist der gewünschte Block nämlich bereits belegt, wird ebenfalls die komplette Spur allokiert. In MacBootMake habe ich das so gelöst, dass die aktuelle Belegungsinformation des Bootsektors "von Hand" aus der BAM gelesen wird (wofür der Laufwerkstyp bekannt sein muss) und "B-A" also nur benutzt wird wenn sowohl nötig als auch möglich. Natürlich hätte man das Allokieren dann auch gleich per Hand machen können, aber zumindest für den Schreibvorgang ins FS wollte ich dann doch lieber die offizielle API nehmen. ;)

  • Auch wenn man einen '#'-Kanal offen hat, funktioniert "B-A" nicht fehlerfrei.

    Ich hab in GoDot den Tipp von darkvision verwendet und nach jeder Blockallozierung den "#"-Kanal zu- und gleich wieder aufgemacht. Funktioniert prächtig! Es werden nur die gewünschten Blöcke alloziert.


    Arndt