mkd64 [2014-01-02, v0.1b] -- Tool zur Erstellung von D64 Images

Es gibt 77 Antworten in diesem Thema, welches 12.009 mal aufgerufen wurde. Der letzte Beitrag (17. November 2014 um 20:07) ist von Zirias.

  • the latest and greatest ... v0.4b :D

    Ich zitiere einfach mal eben mein debian changelog:

    Code
    * core: add possibility for claiming back reserved blocks from modules
      * cbmdos: option for how many blocks to reserve for directory
      * cbmdos: allow allocating more directory blocks as needed
      * cbmdos: support claiming back reserved blocks

    Windows 32bit: Bitte melde dich an, um diesen Link zu sehen.
    Windows 64bit: Bitte melde dich an, um diesen Link zu sehen.
    Linux (i386, portable): Bitte melde dich an, um diesen Link zu sehen.
    Debian/Ubuntu i386: Bitte melde dich an, um diesen Link zu sehen.
    Debian/Ubuntu amd64: Bitte melde dich an, um diesen Link zu sehen.

    Achja -- das "beta" ist noch da :) Grund ist, dass 'cbmdos' aktuell feststellen kann, ob es a) mehr Blocks fürs Directory braucht, als ursprünglich reserviert wurden oder b) bereits reservierte Blocks zurückgeben musste. Um bei wirklich komplett vollen Disks Fragmentierung möglichst zu vermeiden, schreit das geradezu nach einer "2-pass" Option (und einer Schnittstelle für Module, um Optionen für einen zweiten Durchgang zu empfehlen). Ich denke, das muss in das Interface noch rein bevor das "beta" weg kann.

    Nach wie vor gilt: Wer noch was wichtiges für das Modul-Interface weiß, bitte posten, bin für Vorschläge/Anregungen (oder gar Code? *g*) offen!

  • Das "beta" ist weg!

    Update: v1.0

    Changelog:

    Code
    * First non-beta release
      * core: add API version infrastructure,
        check API version before loading a module
      * core: add possibility for modules to suggest better options
      * core: add multi-pass image creation
      * add example module and sdk creation for building modules out-of-tree
      * fix several bugs, provide better information about errors
      * cbmdos: add option for how many blocks to reserve for directory
      * cbmdos: suggest value for reserved blocks to mkd64 if not optimal

    Jetzt ist auch ein SDK dabei, also wer Interesse hat -- bitte Module coden ;)

    Binaries:
    Windows 32bit: Bitte melde dich an, um diesen Link zu sehen.
    Windows 64bit: Bitte melde dich an, um diesen Link zu sehen.
    Linux (i386, portable): Bitte melde dich an, um diesen Link zu sehen.
    Debian/Ubuntu i386: Bitte melde dich an, um diesen Link zu sehen.
    Debian/Ubuntu amd64: Bitte melde dich an, um diesen Link zu sehen.

    SDK:
    Allgemein: Bitte melde dich an, um diesen Link zu sehen.
    Debian/Ubuntu: Bitte melde dich an, um diesen Link zu sehen.

  • So, jetzt komme ich auch mal dazu, Dekay zu antworten -- danke nochmal fürs Testen.

    Das heisst, dass mkd64 nur Track 18 und Sektor Null beschreibt.

    Ich habe das jetzt mal nachvollzogen, was die Original-Floppy macht. Offenbar wird NUR der erste Directory-Block von einer 1541 "pre-allocated", alle weiteren erst, wenn sie auch gebraucht werden (8 Files speichern: Directory ist nach wie vor nur einen Block groß). Daher werde ich an der Stelle nichts ändern ;) Leere Disketten erzeugen ist ja nicht der Sinn von mkd64, von daher denke ich diese Kleinigkeit darf abweichen.

    Allerdings ist mir bei meinen Tests etwas ganz anderes aufgefallen: Directory interleave bei der 1541 ist 3, nicht 4, wie ich es irgendwo gelesen hatte und cbmdos es momentan macht :böse -- das wird natürlich geändert, und vermutlich werde ich dem cbmdos-Modul noch einen Parameter für directory interleave spendieren. Weiß jemand, ob 3 tatsächlich auch der optimale Wert fürs directory lesen mit Originalhardware ist?

    Zum Thema Quotes:
    In der Tat, auch win7 cmd.exe baut single quotes mit in den string ;) Da hat mich wohl GNU make trickreich getäuscht *g* Mittlerweile unterstützt mkd64 option files, in denen können sowohl single als auch double quotes verwendet werden. Auch die üblichen *nix shells akzeptieren beides. Werde aber darauf achten, in Beispielen nur noch double quotes zu verwenden, das scheint auf allen Plattformen sicher. Quotes werden natürlich sowieso nur dann gebraucht, wenn der string whitespace enthält.

    Noch etwas, was aktuell in der Dokumentation fehlt: Angenommen ich will einen simplen Separator schreiben:

    Code
    [...] -f -n ---------------- -TD -w [...]


    Funktioniert NICHT, weil der Dateiname mit - beginnt und der Kommandozeilenparser das als Option interpretiert. Die Lösung ist einfach: Kein Leerzeichen nach der Option lassen:

    Code
    [...] -f -n---------------- -TD -w [...]


    funktioniert wie gewünscht ;)
    Quotes würden hier nämlich nichts bringen, da die Shell die beim direkten Aufruf ja vorher "wegfrisst".

  • Das mit dem ausslassen des Leezeichens für die Minus Zeichen fällt aus dem Rahmen und schwächt ein wenig die Usability. Wäre es vielleicht möglich einen extra Parameter für einen Trenner zu spendieren?
    Dein Tool find ich ganz toll, denn es eignet sich sehr gut, um Batch Files zu erstellen. Dafür mal ein Lob! :thnks:

  • Das mit dem ausslassen des Leezeichens für die Minus Zeichen fällt aus dem Rahmen und schwächt ein wenig die Usability. Wäre es vielleicht möglich einen extra Parameter für einen Trenner zu spendieren?

    Ich dachte an ein extra Modul, das verschiedene Standard-separators anbietet. Kommt bald ;)

    Auslassen des Leerzeichens ist bei allen Optionen vor dem Argument erlaubt, sollte ich auch noch dokumentieren ... Wenn man also nie Leerzeichen zwischen Option und Argument lässt ist es kein Sonderfall mehr. Optionen werden aber an dem - als erstem Zeichen erkannt...

    Dein Tool find ich ganz toll, denn es eignet sich sehr gut, um Batch Files zu erstellen. Dafür mal ein Lob! :thnks:

    Vielen Dank ;)

  • Noch etwas, was aktuell in der Dokumentation fehlt: Angenommen ich will einen simplen Separator schreiben:

    Code
    [...] -f -n ---------------- -TD -w [...]


    Funktioniert NICHT, weil der Dateiname mit - beginnt und der Kommandozeilenparser das als Option interpretiert.

    D.h. als Dateiname würde der nächste String genommen, welcher nicht mit einem Minus beginnt? Man könnte also "-a -b -c argument_for_a argument_for_b argument_for_c" schreiben?
    Verarbeite die Argumente doch einfach sequentiell, dann hast Du das Problem nicht. Also so, dass das nächste Argument hinter "-a" auch das Argument dafür ist.
    Sobald ein Programm eine beliebige Anzahl von Files bearbeiten kann, muss man eh eine Option für "ab hier keine Optionen mehr parsen" hinzufügen (traditionell "--"), denn theoretisch könnte ja auch ein Dateiname mal mit einem Minus beginnen und das Programm aus einem Skript heraus aufgerufen werden.

    Yes, I'm the guy responsible for the Bitte melde dich an, um diesen Link zu sehen. cross assembler. And some Bitte melde dich an, um diesen Link zu sehen..

  • D.h. als Dateiname würde der nächste String genommen, welcher nicht mit einem Minus beginnt?


    Nein, die Kommadozeile wird einmal generisch geparst, der parsende Code weiß nichts über unterstützte Optionen und deren Argumente. Er geht davon aus, dass jede Option ein Argument haben KANN. Wenn direkt an der Option noch was "klebt", ist das das Argument, ansonsten das nächste Element, FALLS es nicht mit - beginnt. Andernfalls hat die Option kein Argument.*

    Der Ansatz weicht also von getopt() / popt() stark ab, auch wenn er bei üblicher Verwendung ähnlich aussieht. Sinn der Sache ist, dass jede Option mit zugehörigem Argument auch jedem geladenen Modul präsentiert wird, so können z.B. auch Module auf den Start eines neuen Files (Option -f) reagieren, obwohl das Hauptprogramm diese Option schon selbst anbietet -- oder eben auch eigene Optionen anbieten. Außerdem ist die Abarbeitung der Optionen zustandsbehaftet, das erste "-f" wechselt in den Filemodus. Im Prinzip muss man also die Kommandozeile als eine art "minimale Skriptsprache" auffassen.

    Verarbeite die Argumente doch einfach sequentiell, dann hast Du das Problem nicht. Also so, dass das nächste Argument hinter "-a" auch das Argument dafür ist.


    s.o. :) Löst das Problem aber nicht, da bei meinem Aufbau der Parser nicht weiß, ob eine Option ein Argument hat / haben muss. Das wäre machbar, wenn alle Module entsprechende Metadaten anbieten, finde ich aber im Moment eigentlich unnötig komplex. Vielleicht mache ich es irgendwann rein für bessere Usability (dann könnte der Parser sich auch bei ungültigen Optionen beschweren, im Moment werden die einfach übergangen).

    Nie Leerzeichen zwischen Option und Argument lassen löst ja das "Problem".

    Sobald ein Programm eine beliebige Anzahl von Files bearbeiten kann, muss man eh eine Option für "ab hier keine Optionen mehr parsen" hinzufügen (traditionell "--"), denn theoretisch könnte ja auch ein Dateiname mal mit einem Minus beginnen und das Programm aus einem Skript heraus aufgerufen werden.


    Auch aus einem Script heraus kann man sicherheitshalber immer die Variante ohne Leerzeichen nehmen (-f${inputname} -n${c64name} -w ...) ;)


    * Im konrekten Fall übrigens (-n) wird die Option OHNE Argument bewirken, dass das File mit dem originalen Namen ins Directory geschrieben wird. Da auch -f keinen Namen hat kommt am ende ein leerer Name raus. Und jetzt wo ich darüber nachdenke fällt mir auf, dass ich da noch einen Bug fixen muss :D edit: done! -- Bitte melde dich an, um diesen Link zu sehen. -- peinlich :whistling:

  • Update: v1.1b

    Tja, kaum hat man mal eine API festgezurrt findet man die ganzen Unzulänglichkeiten :( Daher wieder eine Beta-Release, auf dem Weg zur 2.0 ;)

    Changelog:

    Dazu noch einige Bugfixes. Der cbmdos allocator sollte nun WIRKLICH das gleiche tun wie eine originale 1541, wenn man nicht an den Optionen spielt: dir interleave 3, file interleave 10, files werden wahlweise unterhalb oder oberhalb des directory begonnen, je nachdem wo näher ein freie block zu finden ist.


    Binaries:
    Windows 32bit: Bitte melde dich an, um diesen Link zu sehen.
    Windows 64bit: Bitte melde dich an, um diesen Link zu sehen.
    Linux (i386, portable): Bitte melde dich an, um diesen Link zu sehen.
    Debian/Ubuntu i386: Bitte melde dich an, um diesen Link zu sehen.
    Debian/Ubuntu amd64: Bitte melde dich an, um diesen Link zu sehen.

    SDK:
    Allgemein: Bitte melde dich an, um diesen Link zu sehen.
    Debian/Ubuntu: Bitte melde dich an, um diesen Link zu sehen.

  • Von 0.1b zu 1.1b in einer Woche :wink: Alle Achtung.

    Bitte melde dich an, um diesen Link zu sehen.
    Bitte melde dich an, um diesen Link zu sehen.
    Bitte melde dich an, um diesen Link zu sehen.

  • Von 0.1b zu 1.1b in einer Woche :wink: Alle Achtung.


    Hehe -- vermutlich war die 1.0 etwas überhastet, das hätte besser auch eine beta sein sollen. Aber jetzt kann ich ja leider nicht mehr zurück ;)

  • Und gleich noch ne beta hinterher ...

    Update: v1.2b

    Changelog:

    Code
    * core: minor API change: diskfile_setName takes copies.
      * New module `separators' for some standard separators and boxes in PETSCII

    An sich gibt es nur ein neues Modul. Aber da dazu eine kleine (aber erhebliche) API-Änderung nötig war, muss es eben eine neue Release sein ;) Wer das neue Modul ausprobieren will: "mkd64 -hseparators" zeigt Details.

    Binaries:
    Windows 32bit: Bitte melde dich an, um diesen Link zu sehen.
    Windows 64bit: Bitte melde dich an, um diesen Link zu sehen.
    Linux (i386, portable): Bitte melde dich an, um diesen Link zu sehen.
    Debian/Ubuntu i386: Bitte melde dich an, um diesen Link zu sehen.
    Debian/Ubuntu amd64: Bitte melde dich an, um diesen Link zu sehen.

    SDK:
    Allgemein: Bitte melde dich an, um diesen Link zu sehen.
    Debian/Ubuntu: Bitte melde dich an, um diesen Link zu sehen.

  • Testen und Bugfixes in Arbeit -- ein paar Kleinigkeiten sind in v1.2b noch kaputt, im Source aber schon gefixt. Falls es jemand ausprobieren will, einfach den Source ziehen (siehe post Bitte melde dich an, um diesen Link zu sehen.)

    Hat jemand Interesse an speziellen Modulen? Fehlt etwas in der aktuellen API?

  • Update: v1.3b

    Changelog:

    Code
    * bugfixes: - cbmdos: -A forgot to allocate very last block
                  - core: track number cmdline verification was broken
      * core: informative output to stdout on successful runs
      * core: API changes, IBlockAllocator implementations should not bother about
        allocating at a fixed block position -- new Image method for that.
      * core: const-correctness in public API
      * core: public API completely documented in doxy/javadoc format
      * cbmdos: new flag -0 achieves the same as -A (0 blocks free.), but with
        otherwise correct BAM bits, so tools like dirmaster will show correctly
        which blocks are allocated

    Diesmal wieder ein Ansatz für eine stabile API. Ich werde aber mindestens 14 Tage warten, bevor daraus eine nicht-beta Release wird -- Zeit für mich (und vielleicht auch euch?), eventuell verbleibenden Unzulänglichkeiten in der API zu finden und zu fixen!

    Windows 64bit binaries sind erstmal WEG, der GCC macht da unvorhersehbaren Mist und riesige binaries und es braucht eh keiner.


    Binaries:
    Windows 32bit: Bitte melde dich an, um diesen Link zu sehen.
    Windows 64bit: Dropped for now!
    Linux (i386, portable): Bitte melde dich an, um diesen Link zu sehen.
    Debian/Ubuntu i386: Bitte melde dich an, um diesen Link zu sehen.
    Debian/Ubuntu amd64: Bitte melde dich an, um diesen Link zu sehen.

    SDK:
    Allgemein: Bitte melde dich an, um diesen Link zu sehen.
    Debian/Ubuntu: Bitte melde dich an, um diesen Link zu sehen.

  • Erste kleine API-Änderung:
    aus IModule::delete() wurde IModule::free() :)

    Grund: C++-Kompatibilität. Ich habe keinen Weg gefunden, in C++ ein Symbol namens "delete" zu exportieren...

    Als proof-of-concept hier mal ein Screenshot mit einem kleinen Qt-Plugin, das live die Erstellung eines D64 image verfolgt.

    Falls Interesse an diesem quick&dirty Qt code besteht kann ich den gerne auch auf github stellen. Es könnte hilfreich beim debugging sein, wenn man versucht, einen eigenen IAllocator zu implementieren :)

  • API Überlegungen

    Eventuell gibt es ja Meinungen und Vorschläge, deshalb mache ich hier mal ein paar Überlegungen öffentlich, jeweils auch mit der Frage, wie sinnvoll und/oder relevant das erscheint ;)

    1. mehrere Instanzen eines Moduls
    API-Änderung: IModule braucht eine neue "property" {instanceId(), setInstanceId()}, modrepo_moduleInstance() ändert die Semantik (Instanzen werden nicht mehr automatisch erstellt falls nicht vorhanden) und braucht die Instanz-ID als Parameter, eventuell neue Methode modrepo_moduleInstance(), die alle Instanzen eines Moduls zurückliefert.
    Möglicher Nutzen: Mir fällt da ein Modul ein, das die Anbindung einer Scriptsprache erlaubt (z.B. perl) -- da würde man sicher das Modul auch mehrfach laden können wollen, mit unterschiedlichen Scripts.

    2. "Private" Optionen für Module
    API-Änderung: privateOption() in IModule
    UI-Änderung: Optionen nach -m (und vor -m oder -f) werden als private Option NUR an das zuletzt geladene Modul gegeben. Eventuell weiteres Flag (-g?) um zu globalen Optionen zurückkehren zu können
    Möglicher Nutzen: Geringeres Risiko von Konflikten zwischen Modulen, bei mehrfach ladbaren Modulen (Punkt 1) unterschiedliche Optionen pro Instanz

    3. Basisimplementierung für IModule
    API-Änderung: Noch unklar, "vernünftiges" Vererbungsmodell überlegen, eventuell einfach ein "BaseModule *base" ...
    Möglicher Nutzen: "Boilerplate" Code in Modulen verringern (z.B. "this->mod.id = &id;").

    4. Files auf mehrere Disk-Images verteilen
    Änderungen: Im Moment völlig unklar.
    Möglicher Nutzen: Ja äh ... braucht das irgendjemand außer Vernunftmensch? ;)

    5. C++ Kompatibilität
    API-Änderung: C++-Keywords ("this") in der API loswerden.
    Möglicher Nutzen: IMHO sehr gering, Module in C++ erstellen würde ein bisschen einfacher. Im Moment funktioniert es aber, mkd64-Header folgendermaßen einzubinden:

    C
    extern "C" {
    #define this self
    #include <mkd64/xxx.h>
    [...]
    #undef this
    }

    Spricht etwas prinzipiell gegen dieses Vorgehen?

    Die Liste ist mal nach meiner eigenen Einschätzung von "sinnvoll/nützlich" bis "muss eher nicht sein" sortiert...

  • (sorry noch nicht dazu gekommen mal das ding in meinem buildsystem zu probieren... nur dazu:)

    Zitat

    Spricht etwas prinzipiell gegen dieses Vorgehen?


    find ich hässlich, und ist auf lange sicht blöd. ich würde das ding so bauen das es mit g++ statt gcc kompiliert ohne das es fehler gibt.

  • find ich hässlich, und ist auf lange sicht blöd. ich würde das ding so bauen das es mit g++ statt gcc kompiliert ohne das es fehler gibt.

    Das hab ich auf gar keinen Fall vor, denn g++ ist auf weniger Systemen installiert als gcc und die erzeugten Binaries sind zu denen von anderen Compilern (oder manchmal auch nur g++ mit anderen Einstellungen) nicht binärkompatibel. Wenn das jemand versucht würde ich zumindest gern eine Warnung einbauen, die während dem Build angezeigt wird. Auf Buildfähigkeit achte ich zur Zeit für gcc und msvc.

    Wenn du allerdings meinst, dass die public header mit g++ compilieren sollten (ohne präprozessor-tricks) -- das ließe sich zur Zeit noch mit wenig Aufwand anpassen. Vorteil wären eben C++-Plugins ohne "Klimmzüge" und den Anwendungsfall hab ich ja mit diesem Qt-Versuch ;) Dazu müsste ich nur auf das ziemlich selbsterklärende "this" für den Objekt-Pointer verzichten. Ist stattdessen "self" auch offensichtlich genug? Wäre dann ein wenig wie in perl ...

    Vermutlich würde dann auch das ganze Projekt mit g++ compilieren, sehe ich nur keinen Sinn drin, das zu tun, eben wegen Binärkompatibilität.

    Danke aber für die Meinung, auch wenn ich es selbst nicht wichtig finde, da es nicht viel Aufwand ist werde ich es wohl tun.

  • Da ich leider schon wieder nicht mehr editieren kann mal wieder ein neues Posting ...

    Version mit C++-kompatiblem API liegt auf github :)

    Das macht in der Tat den code des qttrace plugins deutlich einfacher: Bitte melde dich an, um diesen Link zu sehen.

    mkd64 selbst compiliert nach wie vor nicht mit einem C++-Compiler. Beim manuellen alloziieren von Objekten wird malloc() ohne cast verwendet, C erlaubt implizite Konvertierung [Typ]* <-> void*, C++ nicht. Mit expliziten Casts an diesen Stellen wird IMHO der code hässlich. Wie gesagt, sehe eh keinen Sinn darin, mkd64 selbst mit einem C++ compiler zu bauen.

  • Zitat

    denn g++ ist auf weniger Systemen installiert als gcc


    ääääh. watt. meines wissens muss man da bewusst selber hand anlegen um gcc OHNE g++ zu kriegen. ich hab noch kein system gesehen auf dem es gcc gibt, aber g++ nicht. ist ja auch ein gängiger "trick" c programme damit zu kompilieren (weil g++ bessere warnings ausspuckt, zb)

    Zitat

    Vermutlich würde dann auch das ganze Projekt mit g++ compilieren, sehe ich nur keinen Sinn drin, das zu tun, eben wegen Binärkompatibilität.


    du sollst das ja nur so machen das es geht - das binary baut man natürlich mit gcc dann

    Zitat

    Beim manuellen alloziieren von Objekten wird malloc() ohne cast verwendet, C erlaubt implizite Konvertierung [Typ]* <-> void*, C++ nicht. Mit expliziten Casts an diesen Stellen wird IMHO der code hässlich. Wie gesagt, sehe eh keinen Sinn darin, mkd64 selbst mit einem C++ compiler zu bauen.


    geb dem gcc mal ein -W -Wall mit. ordentlicher code gibt da keine warning (und das heisst im umkehrschluss das dieses casts auch in den C code gehören)

    Zitat

    Wie gesagt, sehe eh keinen Sinn darin, mkd64 selbst mit einem C++ compiler zu bauen.


    der sinn ist wie schon gesagt der das man von g++ viel bessere warnings und fehlermeldungen bekommt als von gcc. und wenn man die warnings konsequent fixt wird der code ganz nebenbei etwas "moderner".