From ec271a67ad2491d8a87089fbe8f81053754d0378 Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 16 Oct 2024 00:00:09 +0200 Subject: [PATCH 01/12] Move the flx stuff into external. --- build.py | 2 -- lib/external/build.py | 2 ++ lib/{fluxsource => external}/flx.cc | 2 +- lib/{fluxsource => external}/flx.h | 0 lib/fluxsource/flxfluxsource.cc | 2 +- tests/flx.cc | 2 +- 6 files changed, 5 insertions(+), 5 deletions(-) rename lib/{fluxsource => external}/flx.cc (97%) rename lib/{fluxsource => external}/flx.h (100%) diff --git a/build.py b/build.py index a27f272f7..016d81ca2 100644 --- a/build.py +++ b/build.py @@ -39,7 +39,6 @@ "./lib/fluxsource/erasefluxsource.cc", "./lib/fluxsource/fl2fluxsource.cc", "./lib/fluxsource/fluxsource.cc", - "./lib/fluxsource/flx.cc", "./lib/fluxsource/flxfluxsource.cc", "./lib/fluxsource/hardwarefluxsource.cc", "./lib/fluxsource/kryofluxfluxsource.cc", @@ -143,7 +142,6 @@ "lib/encoders/encoders.h": "./lib/encoders/encoders.h", "lib/fluxsink/fluxsink.h": "./lib/fluxsink/fluxsink.h", "lib/fluxsource/fluxsource.h": "lib/fluxsource/fluxsource.h", - "lib/fluxsource/flx.h": "lib/fluxsource/flx.h", "lib/imagereader/imagereader.h": "./lib/imagereader/imagereader.h", "lib/imagewriter/imagewriter.h": "./lib/imagewriter/imagewriter.h", "lib/readerwriter.h": "./lib/readerwriter.h", diff --git a/lib/external/build.py b/lib/external/build.py index 92425466e..b83027f79 100644 --- a/lib/external/build.py +++ b/lib/external/build.py @@ -12,6 +12,7 @@ "./kryoflux.cc", "./catweasel.cc", "./csvreader.cc", + "./flx.cc", ], hdrs={ "lib/external/a2r.h": "./a2r.h", @@ -21,6 +22,7 @@ "lib/external/kryoflux.h": "./kryoflux.h", "lib/external/ldbs.h": "./ldbs.h", "lib/external/scp.h": "./scp.h", + "lib/external/flx.h": "./flx.h", }, deps=["lib/core", ".+fl2_proto_lib", "lib/data"], ) diff --git a/lib/fluxsource/flx.cc b/lib/external/flx.cc similarity index 97% rename from lib/fluxsource/flx.cc rename to lib/external/flx.cc index c13fd41ef..767e0224e 100644 --- a/lib/fluxsource/flx.cc +++ b/lib/external/flx.cc @@ -2,7 +2,7 @@ #include "lib/data/fluxmap.h" #include "lib/external/kryoflux.h" #include "protocol.h" -#include "lib/fluxsource/flx.h" +#include "lib/external/flx.h" std::unique_ptr readFlxBytes(const Bytes& bytes) { diff --git a/lib/fluxsource/flx.h b/lib/external/flx.h similarity index 100% rename from lib/fluxsource/flx.h rename to lib/external/flx.h diff --git a/lib/fluxsource/flxfluxsource.cc b/lib/fluxsource/flxfluxsource.cc index 3c15e7bf7..1d37fc48a 100644 --- a/lib/fluxsource/flxfluxsource.cc +++ b/lib/fluxsource/flxfluxsource.cc @@ -2,7 +2,7 @@ #include "lib/data/fluxmap.h" #include "lib/fluxsource/fluxsource.pb.h" #include "lib/fluxsource/fluxsource.h" -#include "lib/fluxsource/flx.h" +#include "lib/external/flx.h" class FlxFluxSource : public TrivialFluxSource { diff --git a/tests/flx.cc b/tests/flx.cc index ad802ba01..b2e21d461 100644 --- a/tests/flx.cc +++ b/tests/flx.cc @@ -3,7 +3,7 @@ #include #include "lib/core/globals.h" #include "lib/data/fluxmap.h" -#include "lib/fluxsource/flx.h" +#include "lib/external/flx.h" static void test_convert(const Bytes& flxbytes, const Bytes& fluxmapbytes) { From c42e73f17ae22ebdbc4dbcdfd3067f3255e1b631 Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 16 Oct 2024 00:41:57 +0200 Subject: [PATCH 02/12] Modularise fluxsink and usb. --- build.py | 20 +------------------- lib/{usb => external}/applesauce.h | 0 lib/external/build.py | 11 +++++++---- lib/{usb => external}/greaseweazle.cc | 0 lib/{usb => external}/greaseweazle.h | 0 lib/fluxsink/build.py | 17 ++++++++++++++++- lib/fluxsink/hardwarefluxsink.cc | 1 - lib/usb/build.py | 15 +++++++++++++++ lib/usb/greaseweazleusb.cc | 2 +- lib/usb/usb.cc | 4 ++-- lib/usb/usbfinder.cc | 4 ++-- tests/greaseweazle.cc | 2 +- 12 files changed, 45 insertions(+), 31 deletions(-) rename lib/{usb => external}/applesauce.h (100%) rename lib/{usb => external}/greaseweazle.cc (100%) rename lib/{usb => external}/greaseweazle.h (100%) diff --git a/build.py b/build.py index 016d81ca2..21f77ec64 100644 --- a/build.py +++ b/build.py @@ -26,13 +26,6 @@ "./lib/decoders/fluxdecoder.cc", "./lib/decoders/fmmfm.cc", "./lib/encoders/encoders.cc", - "./lib/fluxsink/a2rfluxsink.cc", - "./lib/fluxsink/aufluxsink.cc", - "./lib/fluxsink/fl2fluxsink.cc", - "./lib/fluxsink/fluxsink.cc", - "./lib/fluxsink/hardwarefluxsink.cc", - "./lib/fluxsink/scpfluxsink.cc", - "./lib/fluxsink/vcdfluxsink.cc", "./lib/fluxsource/a2rfluxsource.cc", "./lib/fluxsource/cwffluxsource.cc", "./lib/fluxsource/dmkfluxsource.cc", @@ -67,13 +60,6 @@ "./lib/imagewriter/nsiimagewriter.cc", "./lib/imagewriter/rawimagewriter.cc", "./lib/readerwriter.cc", - "./lib/usb/applesauceusb.cc", - "./lib/usb/fluxengineusb.cc", - "./lib/usb/greaseweazle.cc", - "./lib/usb/greaseweazleusb.cc", - "./lib/usb/serial.cc", - "./lib/usb/usb.cc", - "./lib/usb/usbfinder.cc", "./arch/aeslanier/decoder.cc", "./arch/agat/agat.cc", "./arch/agat/decoder.cc", @@ -140,15 +126,10 @@ "lib/decoders/fluxdecoder.h": "./lib/decoders/fluxdecoder.h", "lib/decoders/rawbits.h": "./lib/decoders/rawbits.h", "lib/encoders/encoders.h": "./lib/encoders/encoders.h", - "lib/fluxsink/fluxsink.h": "./lib/fluxsink/fluxsink.h", "lib/fluxsource/fluxsource.h": "lib/fluxsource/fluxsource.h", "lib/imagereader/imagereader.h": "./lib/imagereader/imagereader.h", "lib/imagewriter/imagewriter.h": "./lib/imagewriter/imagewriter.h", "lib/readerwriter.h": "./lib/readerwriter.h", - "lib/usb/applesauce.h": "./lib/usb/applesauce.h", - "lib/usb/greaseweazle.h": "./lib/usb/greaseweazle.h", - "lib/usb/usb.h": "./lib/usb/usb.h", - "lib/usb/usbfinder.h": "./lib/usb/usbfinder.h", }, deps=[ "+fmt_lib", @@ -163,6 +144,7 @@ "lib/config", "lib/data", "lib/external", + "lib/fluxsink", "lib/fluxsource+proto_lib", ], ) diff --git a/lib/usb/applesauce.h b/lib/external/applesauce.h similarity index 100% rename from lib/usb/applesauce.h rename to lib/external/applesauce.h diff --git a/lib/external/build.py b/lib/external/build.py index b83027f79..c41eb1216 100644 --- a/lib/external/build.py +++ b/lib/external/build.py @@ -7,22 +7,25 @@ cxxlibrary( name="external", srcs=[ - "./ldbs.cc", - "./fl2.cc", - "./kryoflux.cc", "./catweasel.cc", "./csvreader.cc", + "./fl2.cc", "./flx.cc", + "./greaseweazle.cc", + "./kryoflux.cc", + "./ldbs.cc", ], hdrs={ "lib/external/a2r.h": "./a2r.h", + "lib/external/applesauce.h": "./applesauce.h", "lib/external/catweasel.h": "./catweasel.h", "lib/external/csvreader.h": "./csvreader.h", "lib/external/fl2.h": "./fl2.h", + "lib/external/flx.h": "./flx.h", + "lib/external/greaseweazle.h": "./greaseweazle.h", "lib/external/kryoflux.h": "./kryoflux.h", "lib/external/ldbs.h": "./ldbs.h", "lib/external/scp.h": "./scp.h", - "lib/external/flx.h": "./flx.h", }, deps=["lib/core", ".+fl2_proto_lib", "lib/data"], ) diff --git a/lib/usb/greaseweazle.cc b/lib/external/greaseweazle.cc similarity index 100% rename from lib/usb/greaseweazle.cc rename to lib/external/greaseweazle.cc diff --git a/lib/usb/greaseweazle.h b/lib/external/greaseweazle.h similarity index 100% rename from lib/usb/greaseweazle.h rename to lib/external/greaseweazle.h diff --git a/lib/fluxsink/build.py b/lib/fluxsink/build.py index ea917e84e..ffaed4676 100644 --- a/lib/fluxsink/build.py +++ b/lib/fluxsink/build.py @@ -1,5 +1,20 @@ from build.protobuf import proto, protocc +from build.c import cxxlibrary proto(name="proto", srcs=["./fluxsink.proto"], deps=["lib+common_proto"]) - protocc(name="proto_lib", srcs=[".+proto"], deps=["lib+common_proto_lib"]) + +cxxlibrary( + name="fluxsink", + srcs=[ + "./a2rfluxsink.cc", + "./aufluxsink.cc", + "./fl2fluxsink.cc", + "./fluxsink.cc", + "./hardwarefluxsink.cc", + "./scpfluxsink.cc", + "./vcdfluxsink.cc", + ], + hdrs={"lib/fluxsink/fluxsink.h": "./fluxsink.h"}, + deps=["lib/core", "lib/config", "lib/data", "lib/external","lib/usb"], +) diff --git a/lib/fluxsink/hardwarefluxsink.cc b/lib/fluxsink/hardwarefluxsink.cc index 7966ac9cf..71062326a 100644 --- a/lib/fluxsink/hardwarefluxsink.cc +++ b/lib/fluxsink/hardwarefluxsink.cc @@ -7,7 +7,6 @@ #include "lib/usb/usb.h" #include "lib/fluxsink/fluxsink.h" #include "lib/fluxsink/fluxsink.pb.h" -#include "lib/readerwriter.h" class HardwareFluxSink : public FluxSink { diff --git a/lib/usb/build.py b/lib/usb/build.py index abbb5171c..accb2803d 100644 --- a/lib/usb/build.py +++ b/lib/usb/build.py @@ -1,4 +1,19 @@ from build.protobuf import proto, protocc +from build.c import cxxlibrary proto(name="proto", srcs=["./usb.proto"], deps=["lib+common_proto"]) protocc(name="proto_lib", srcs=[".+proto"], deps=["lib+common_proto_lib"]) + +cxxlibrary( + name="usb", + srcs=[ + "./applesauceusb.cc", + "./fluxengineusb.cc", + "./greaseweazleusb.cc", + "./serial.cc", + "./usb.cc", + "./usbfinder.cc", + ], + hdrs={"lib/usb/usb.h": "./usb.h", "lib/usb/usbfinder.h": "./usbfinder.h"}, + deps=["lib/core", "lib/config", "lib/external", "dep/libusbp", "+protocol"], +) diff --git a/lib/usb/greaseweazleusb.cc b/lib/usb/greaseweazleusb.cc index 3b0effaef..a0849b60a 100644 --- a/lib/usb/greaseweazleusb.cc +++ b/lib/usb/greaseweazleusb.cc @@ -3,7 +3,7 @@ #include "lib/data/fluxmap.h" #include "lib/core/bytes.h" #include "lib/usb/usb.pb.h" -#include "greaseweazle.h" +#include "lib/external/greaseweazle.h" #include "serial.h" #include "usb.h" #include diff --git a/lib/usb/usb.cc b/lib/usb/usb.cc index e55a6e8dc..e35ca6045 100644 --- a/lib/usb/usb.cc +++ b/lib/usb/usb.cc @@ -10,8 +10,8 @@ #include "lib/config/proto.h" #include "usbfinder.h" #include "lib/core/logger.h" -#include "applesauce.h" -#include "greaseweazle.h" +#include "lib/external/applesauce.h" +#include "lib/external/greaseweazle.h" static USB* usb = NULL; diff --git a/lib/usb/usbfinder.cc b/lib/usb/usbfinder.cc index d9c357e83..3318d1090 100644 --- a/lib/usb/usbfinder.cc +++ b/lib/usb/usbfinder.cc @@ -3,8 +3,8 @@ #include "usb.h" #include "lib/core/bytes.h" #include "usbfinder.h" -#include "applesauce.h" -#include "greaseweazle.h" +#include "lib/external/applesauce.h" +#include "lib/external/greaseweazle.h" #include "protocol.h" #include "libusbp.hpp" diff --git a/tests/greaseweazle.cc b/tests/greaseweazle.cc index 6b3dc12cd..d85e4e3b9 100644 --- a/tests/greaseweazle.cc +++ b/tests/greaseweazle.cc @@ -3,7 +3,7 @@ #include #include "lib/core/globals.h" #include "lib/data/fluxmap.h" -#include "lib/usb/greaseweazle.h" +#include "lib/external/greaseweazle.h" #define E28(val) \ (1 | ((val) << 1) & 0xff), (1 | ((val) >> 6) & 0xff), \ From ecd80775d8722a5205875284b60b1d80dddbc7a8 Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 16 Oct 2024 01:00:48 +0200 Subject: [PATCH 03/12] Modularise fluxsource. --- build.py | 15 +-------------- lib/fluxsource/build.py | 21 +++++++++++++++++++++ lib/fluxsource/hardwarefluxsource.cc | 1 - src/build.py | 2 -- src/gui/build.py | 1 - 5 files changed, 22 insertions(+), 18 deletions(-) diff --git a/build.py b/build.py index 21f77ec64..15599b0f6 100644 --- a/build.py +++ b/build.py @@ -26,18 +26,6 @@ "./lib/decoders/fluxdecoder.cc", "./lib/decoders/fmmfm.cc", "./lib/encoders/encoders.cc", - "./lib/fluxsource/a2rfluxsource.cc", - "./lib/fluxsource/cwffluxsource.cc", - "./lib/fluxsource/dmkfluxsource.cc", - "./lib/fluxsource/erasefluxsource.cc", - "./lib/fluxsource/fl2fluxsource.cc", - "./lib/fluxsource/fluxsource.cc", - "./lib/fluxsource/flxfluxsource.cc", - "./lib/fluxsource/hardwarefluxsource.cc", - "./lib/fluxsource/kryofluxfluxsource.cc", - "./lib/fluxsource/memoryfluxsource.cc", - "./lib/fluxsource/scpfluxsource.cc", - "./lib/fluxsource/testpatternfluxsource.cc", "./lib/imagereader/d64imagereader.cc", "./lib/imagereader/d88imagereader.cc", "./lib/imagereader/dimimagereader.cc", @@ -126,7 +114,6 @@ "lib/decoders/fluxdecoder.h": "./lib/decoders/fluxdecoder.h", "lib/decoders/rawbits.h": "./lib/decoders/rawbits.h", "lib/encoders/encoders.h": "./lib/encoders/encoders.h", - "lib/fluxsource/fluxsource.h": "lib/fluxsource/fluxsource.h", "lib/imagereader/imagereader.h": "./lib/imagereader/imagereader.h", "lib/imagewriter/imagewriter.h": "./lib/imagewriter/imagewriter.h", "lib/readerwriter.h": "./lib/readerwriter.h", @@ -145,7 +132,7 @@ "lib/data", "lib/external", "lib/fluxsink", - "lib/fluxsource+proto_lib", + "lib/fluxsource", ], ) diff --git a/lib/fluxsource/build.py b/lib/fluxsource/build.py index dd873c02c..f32409d51 100644 --- a/lib/fluxsource/build.py +++ b/lib/fluxsource/build.py @@ -1,4 +1,5 @@ from build.protobuf import proto, protocc +from build.c import cxxlibrary proto(name="proto", srcs=["./fluxsource.proto"], deps=["lib+common_proto"]) @@ -7,3 +8,23 @@ srcs=[".+proto"], deps=["lib+common_proto", "lib+common_proto_lib"], ) + +cxxlibrary( + name="fluxsource", + srcs=[ + "./a2rfluxsource.cc", + "./cwffluxsource.cc", + "./dmkfluxsource.cc", + "./erasefluxsource.cc", + "./fl2fluxsource.cc", + "./fluxsource.cc", + "./flxfluxsource.cc", + "./hardwarefluxsource.cc", + "./kryofluxfluxsource.cc", + "./memoryfluxsource.cc", + "./scpfluxsource.cc", + "./testpatternfluxsource.cc", + ], + hdrs={"lib/fluxsource/fluxsource.h": "./fluxsource.h"}, + deps=["lib/core","lib/data","lib/external","lib/usb",".+proto_lib"] +) diff --git a/lib/fluxsource/hardwarefluxsource.cc b/lib/fluxsource/hardwarefluxsource.cc index 99af5b8d9..670c3c1fd 100644 --- a/lib/fluxsource/hardwarefluxsource.cc +++ b/lib/fluxsource/hardwarefluxsource.cc @@ -7,7 +7,6 @@ #include "lib/usb/usb.h" #include "lib/fluxsource/fluxsource.h" #include "lib/fluxsource/fluxsource.pb.h" -#include "lib/readerwriter.h" class HardwareFluxSource : public FluxSource { diff --git a/src/build.py b/src/build.py index 9692c6cd6..0756a3918 100644 --- a/src/build.py +++ b/src/build.py @@ -33,7 +33,6 @@ "+fmt_lib", "+lib", "+protobuf_lib", - "+protobuf_lib", "+protocol", "+z_lib", "dep/adflib", @@ -46,7 +45,6 @@ "lib/core", "lib/data", "lib/external", - "lib/fluxsource+proto_lib", "lib/vfs", "src/formats", ], diff --git a/src/gui/build.py b/src/gui/build.py index eb9257537..1ce1d54f8 100644 --- a/src/gui/build.py +++ b/src/gui/build.py @@ -68,7 +68,6 @@ "lib/data", "lib/vfs", "lib/config", - "lib/fluxsource+proto_lib", "src/formats", "src/gui/drivetypes", "+z_lib", From 3020705012347b67880de0c7cc868f4f583cdb69 Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 16 Oct 2024 01:12:35 +0200 Subject: [PATCH 04/12] Modularise imagewriter. --- build.py | 25 ++----------------------- lib/fluxsink/build.py | 2 +- lib/fluxsource/build.py | 2 +- lib/imagereader/build.py | 21 +++++++++++++++++++++ lib/imagewriter/build.py | 20 ++++++++++++++++++++ lib/imagewriter/nsiimagewriter.cc | 2 -- lib/imagewriter/rawimagewriter.cc | 3 +-- 7 files changed, 46 insertions(+), 29 deletions(-) diff --git a/build.py b/build.py index 15599b0f6..608be99d7 100644 --- a/build.py +++ b/build.py @@ -26,27 +26,6 @@ "./lib/decoders/fluxdecoder.cc", "./lib/decoders/fmmfm.cc", "./lib/encoders/encoders.cc", - "./lib/imagereader/d64imagereader.cc", - "./lib/imagereader/d88imagereader.cc", - "./lib/imagereader/dimimagereader.cc", - "./lib/imagereader/diskcopyimagereader.cc", - "./lib/imagereader/fdiimagereader.cc", - "./lib/imagereader/imagereader.cc", - "./lib/imagereader/imdimagereader.cc", - "./lib/imagereader/imgimagereader.cc", - "./lib/imagereader/jv3imagereader.cc", - "./lib/imagereader/nfdimagereader.cc", - "./lib/imagereader/nsiimagereader.cc", - "./lib/imagereader/td0imagereader.cc", - "./lib/imagewriter/d64imagewriter.cc", - "./lib/imagewriter/d88imagewriter.cc", - "./lib/imagewriter/diskcopyimagewriter.cc", - "./lib/imagewriter/imagewriter.cc", - "./lib/imagewriter/imdimagewriter.cc", - "./lib/imagewriter/imgimagewriter.cc", - "./lib/imagewriter/ldbsimagewriter.cc", - "./lib/imagewriter/nsiimagewriter.cc", - "./lib/imagewriter/rawimagewriter.cc", "./lib/readerwriter.cc", "./arch/aeslanier/decoder.cc", "./arch/agat/agat.cc", @@ -114,8 +93,6 @@ "lib/decoders/fluxdecoder.h": "./lib/decoders/fluxdecoder.h", "lib/decoders/rawbits.h": "./lib/decoders/rawbits.h", "lib/encoders/encoders.h": "./lib/encoders/encoders.h", - "lib/imagereader/imagereader.h": "./lib/imagereader/imagereader.h", - "lib/imagewriter/imagewriter.h": "./lib/imagewriter/imagewriter.h", "lib/readerwriter.h": "./lib/readerwriter.h", }, deps=[ @@ -133,6 +110,8 @@ "lib/external", "lib/fluxsink", "lib/fluxsource", + "lib/imagereader", + "lib/imagewriter", ], ) diff --git a/lib/fluxsink/build.py b/lib/fluxsink/build.py index ffaed4676..a5b8d375f 100644 --- a/lib/fluxsink/build.py +++ b/lib/fluxsink/build.py @@ -16,5 +16,5 @@ "./vcdfluxsink.cc", ], hdrs={"lib/fluxsink/fluxsink.h": "./fluxsink.h"}, - deps=["lib/core", "lib/config", "lib/data", "lib/external","lib/usb"], + deps=["lib/core", "lib/config", "lib/data", "lib/external", "lib/usb"], ) diff --git a/lib/fluxsource/build.py b/lib/fluxsource/build.py index f32409d51..fa9e660f3 100644 --- a/lib/fluxsource/build.py +++ b/lib/fluxsource/build.py @@ -26,5 +26,5 @@ "./testpatternfluxsource.cc", ], hdrs={"lib/fluxsource/fluxsource.h": "./fluxsource.h"}, - deps=["lib/core","lib/data","lib/external","lib/usb",".+proto_lib"] + deps=["lib/core", "lib/data", "lib/external", "lib/usb", ".+proto_lib"], ) diff --git a/lib/imagereader/build.py b/lib/imagereader/build.py index babddb947..ce265703c 100644 --- a/lib/imagereader/build.py +++ b/lib/imagereader/build.py @@ -1,4 +1,5 @@ from build.protobuf import proto, protocc +from build.c import cxxlibrary proto( name="proto", @@ -10,3 +11,23 @@ srcs=[".+proto"], deps=["lib+common_proto_lib"], ) + +cxxlibrary( + name="imagereader", + srcs=[ + "./d64imagereader.cc", + "./d88imagereader.cc", + "./dimimagereader.cc", + "./diskcopyimagereader.cc", + "./fdiimagereader.cc", + "./imagereader.cc", + "./imdimagereader.cc", + "./imgimagereader.cc", + "./jv3imagereader.cc", + "./nfdimagereader.cc", + "./nsiimagereader.cc", + "./td0imagereader.cc", + ], + hdrs={"lib/imagereader/imagereader.h": "./imagereader.h"}, + deps=["lib/core", "lib/config", "lib/data", ".+proto_lib"], +) diff --git a/lib/imagewriter/build.py b/lib/imagewriter/build.py index 678760254..3adf3292b 100644 --- a/lib/imagewriter/build.py +++ b/lib/imagewriter/build.py @@ -1,4 +1,5 @@ from build.protobuf import proto, protocc +from build.c import cxxlibrary proto( name="proto", @@ -10,3 +11,22 @@ srcs=[".+proto"], deps=["lib+common_proto_lib", "lib/imagereader+proto_lib"], ) + +cxxlibrary( + name="imagewriter", + srcs=[ + "./d64imagewriter.cc", + "./d88imagewriter.cc", + "./diskcopyimagewriter.cc", + "./imagewriter.cc", + "./imdimagewriter.cc", + "./imgimagewriter.cc", + "./ldbsimagewriter.cc", + "./nsiimagewriter.cc", + "./rawimagewriter.cc", + ], + hdrs={ + "lib/imagewriter/imagewriter.h": "./imagewriter.h", + }, + deps=["lib/core", "lib/data", "lib/external", ".+proto_lib"], +) diff --git a/lib/imagewriter/nsiimagewriter.cc b/lib/imagewriter/nsiimagewriter.cc index 93ddf706d..038cfbe25 100644 --- a/lib/imagewriter/nsiimagewriter.cc +++ b/lib/imagewriter/nsiimagewriter.cc @@ -2,10 +2,8 @@ #include "lib/config/flags.h" #include "lib/data/sector.h" #include "lib/imagewriter/imagewriter.h" -#include "lib/decoders/decoders.h" #include "lib/data/image.h" #include "lib/core/logger.h" -#include "arch/northstar/northstar.h" #include "lib/imagewriter/imagewriter.pb.h" #include #include diff --git a/lib/imagewriter/rawimagewriter.cc b/lib/imagewriter/rawimagewriter.cc index d32623ae9..f7a9c5a5f 100644 --- a/lib/imagewriter/rawimagewriter.cc +++ b/lib/imagewriter/rawimagewriter.cc @@ -2,10 +2,9 @@ #include "lib/config/flags.h" #include "lib/data/sector.h" #include "lib/imagewriter/imagewriter.h" -#include "lib/decoders/decoders.h" #include "lib/data/image.h" +#include "lib/data/flux.h" #include "lib/core/logger.h" -#include "arch/northstar/northstar.h" #include "lib/imagewriter/imagewriter.pb.h" #include #include From 167bb0287eb6d981060ac5c55a4b45028b5708ee Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 16 Oct 2024 01:29:35 +0200 Subject: [PATCH 05/12] Fix a stray header. --- lib/external/greaseweazle.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/external/greaseweazle.cc b/lib/external/greaseweazle.cc index 96dbca365..c7969ae45 100644 --- a/lib/external/greaseweazle.cc +++ b/lib/external/greaseweazle.cc @@ -1,5 +1,4 @@ #include "lib/core/globals.h" -#include "usb.h" #include "protocol.h" #include "lib/core/bytes.h" #include "greaseweazle.h" From 6d3969ab7961c225afd6170fb80591f15391ada4 Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 16 Oct 2024 21:00:48 +0200 Subject: [PATCH 06/12] Split the dependency so that the encoders/decoders don't depend on arch. --- arch/arch.cc | 96 ++++++++++++++++++++++++++++++++++++++++ arch/arch.h | 16 +++++++ build.py | 2 + lib/decoders/decoders.cc | 58 ------------------------ lib/encoders/encoders.cc | 45 ------------------- lib/encoders/encoders.h | 1 - lib/vfs/vfs.cc | 5 ++- src/fe-read.cc | 3 +- src/fe-write.cc | 7 ++- src/gui/context.cc | 21 ++++----- 10 files changed, 133 insertions(+), 121 deletions(-) create mode 100644 arch/arch.cc create mode 100644 arch/arch.h diff --git a/arch/arch.cc b/arch/arch.cc new file mode 100644 index 000000000..e03193f9b --- /dev/null +++ b/arch/arch.cc @@ -0,0 +1,96 @@ +#include "lib/core/globals.h" +#include "lib/encoders/encoders.h" +#include "lib/decoders/decoders.h" +#include "lib/config/config.h" +#include "arch/agat/agat.h" +#include "arch/aeslanier/aeslanier.h" +#include "arch/amiga/amiga.h" +#include "arch/apple2/apple2.h" +#include "arch/brother/brother.h" +#include "arch/c64/c64.h" +#include "arch/f85/f85.h" +#include "arch/fb100/fb100.h" +#include "arch/ibm/ibm.h" +#include "arch/macintosh/macintosh.h" +#include "arch/micropolis/micropolis.h" +#include "arch/mx/mx.h" +#include "arch/northstar/northstar.h" +#include "arch/rolandd20/rolandd20.h" +#include "arch/smaky6/smaky6.h" +#include "arch/tartu/tartu.h" +#include "arch/tids990/tids990.h" +#include "arch/victor9k/victor9k.h" +#include "arch/zilogmcz/zilogmcz.h" +#include "arch/arch.h" + +std::unique_ptr Arch::createEncoder(Config& config) +{ + if (!config.hasEncoder()) + error("no encoder configured"); + return createEncoder(config->encoder()); +} + + std::unique_ptr Arch::createEncoder(const EncoderProto& config){ + static const std::map(const EncoderProto&)>> + encoders = { + {EncoderProto::kAgat, createAgatEncoder }, + {EncoderProto::kAmiga, createAmigaEncoder }, + {EncoderProto::kApple2, createApple2Encoder }, + {EncoderProto::kBrother, createBrotherEncoder }, + {EncoderProto::kC64, createCommodore64Encoder}, + {EncoderProto::kIbm, createIbmEncoder }, + {EncoderProto::kMacintosh, createMacintoshEncoder }, + {EncoderProto::kMicropolis, createMicropolisEncoder }, + {EncoderProto::kNorthstar, createNorthstarEncoder }, + {EncoderProto::kTartu, createTartuEncoder }, + {EncoderProto::kTids990, createTids990Encoder }, + {EncoderProto::kVictor9K, createVictor9kEncoder }, + }; + + auto encoder = encoders.find(config.format_case()); + if (encoder == encoders.end()) + error("no encoder specified"); + + return (encoder->second)(config); +} + +std::unique_ptr Arch::createDecoder(Config& config) +{ + if (!config.hasDecoder()) + error("no decoder configured"); + return createDecoder(config->decoder()); +} + +std::unique_ptr Arch::createDecoder(const DecoderProto& config) +{ + static const std::map(const DecoderProto&)>> + decoders = { + {DecoderProto::kAgat, createAgatDecoder }, + {DecoderProto::kAeslanier, createAesLanierDecoder }, + {DecoderProto::kAmiga, createAmigaDecoder }, + {DecoderProto::kApple2, createApple2Decoder }, + {DecoderProto::kBrother, createBrotherDecoder }, + {DecoderProto::kC64, createCommodore64Decoder}, + {DecoderProto::kF85, createDurangoF85Decoder }, + {DecoderProto::kFb100, createFb100Decoder }, + {DecoderProto::kIbm, createIbmDecoder }, + {DecoderProto::kMacintosh, createMacintoshDecoder }, + {DecoderProto::kMicropolis, createMicropolisDecoder }, + {DecoderProto::kMx, createMxDecoder }, + {DecoderProto::kNorthstar, createNorthstarDecoder }, + {DecoderProto::kRolandd20, createRolandD20Decoder }, + {DecoderProto::kSmaky6, createSmaky6Decoder }, + {DecoderProto::kTartu, createTartuDecoder }, + {DecoderProto::kTids990, createTids990Decoder }, + {DecoderProto::kVictor9K, createVictor9kDecoder }, + {DecoderProto::kZilogmcz, createZilogMczDecoder }, + }; + + auto decoder = decoders.find(config.format_case()); + if (decoder == decoders.end()) + error("no decoder specified"); + + return (decoder->second)(config); +} diff --git a/arch/arch.h b/arch/arch.h new file mode 100644 index 000000000..00e355010 --- /dev/null +++ b/arch/arch.h @@ -0,0 +1,16 @@ +#pragma once + +class Encoder; +class Decoder; +class DecoderProto; +class EncoderProto; +class Config; + +namespace Arch +{ + std::unique_ptr createDecoder(Config& config); + std::unique_ptr createDecoder(const DecoderProto& config); + + std::unique_ptr createEncoder(Config& config); + std::unique_ptr createEncoder(const EncoderProto& config); +} diff --git a/build.py b/build.py index 608be99d7..e7d72341e 100644 --- a/build.py +++ b/build.py @@ -27,6 +27,7 @@ "./lib/decoders/fmmfm.cc", "./lib/encoders/encoders.cc", "./lib/readerwriter.cc", + "./arch/arch.cc", "./arch/aeslanier/decoder.cc", "./arch/agat/agat.cc", "./arch/agat/decoder.cc", @@ -89,6 +90,7 @@ "arch/c64/data_gcr.h": "./arch/c64/data_gcr.h", "arch/c64/c64.h": "./arch/c64/c64.h", "arch/tartu/tartu.h": "./arch/tartu/tartu.h", + "arch/arch.h": "./arch/arch.h", "lib/decoders/decoders.h": "./lib/decoders/decoders.h", "lib/decoders/fluxdecoder.h": "./lib/decoders/fluxdecoder.h", "lib/decoders/rawbits.h": "./lib/decoders/rawbits.h", diff --git a/lib/decoders/decoders.cc b/lib/decoders/decoders.cc index ca8a34bec..905f983be 100644 --- a/lib/decoders/decoders.cc +++ b/lib/decoders/decoders.cc @@ -4,25 +4,6 @@ #include "lib/config/config.h" #include "lib/decoders/decoders.h" #include "lib/encoders/encoders.h" -#include "arch/agat/agat.h" -#include "arch/aeslanier/aeslanier.h" -#include "arch/amiga/amiga.h" -#include "arch/apple2/apple2.h" -#include "arch/brother/brother.h" -#include "arch/c64/c64.h" -#include "arch/f85/f85.h" -#include "arch/fb100/fb100.h" -#include "arch/ibm/ibm.h" -#include "arch/macintosh/macintosh.h" -#include "arch/micropolis/micropolis.h" -#include "arch/mx/mx.h" -#include "arch/northstar/northstar.h" -#include "arch/rolandd20/rolandd20.h" -#include "arch/smaky6/smaky6.h" -#include "arch/tartu/tartu.h" -#include "arch/tids990/tids990.h" -#include "arch/victor9k/victor9k.h" -#include "arch/zilogmcz/zilogmcz.h" #include "lib/data/fluxmapreader.h" #include "lib/data/flux.h" #include "protocol.h" @@ -33,45 +14,6 @@ #include "lib/data/layout.h" #include -std::unique_ptr Decoder::create(Config& config) -{ - if (!config.hasDecoder()) - error("no decoder configured"); - return create(config->decoder()); -} - -std::unique_ptr Decoder::create(const DecoderProto& config) -{ - static const std::map(const DecoderProto&)>> - decoders = { - {DecoderProto::kAgat, createAgatDecoder }, - {DecoderProto::kAeslanier, createAesLanierDecoder }, - {DecoderProto::kAmiga, createAmigaDecoder }, - {DecoderProto::kApple2, createApple2Decoder }, - {DecoderProto::kBrother, createBrotherDecoder }, - {DecoderProto::kC64, createCommodore64Decoder}, - {DecoderProto::kF85, createDurangoF85Decoder }, - {DecoderProto::kFb100, createFb100Decoder }, - {DecoderProto::kIbm, createIbmDecoder }, - {DecoderProto::kMacintosh, createMacintoshDecoder }, - {DecoderProto::kMicropolis, createMicropolisDecoder }, - {DecoderProto::kMx, createMxDecoder }, - {DecoderProto::kNorthstar, createNorthstarDecoder }, - {DecoderProto::kRolandd20, createRolandD20Decoder }, - {DecoderProto::kSmaky6, createSmaky6Decoder }, - {DecoderProto::kTartu, createTartuDecoder }, - {DecoderProto::kTids990, createTids990Decoder }, - {DecoderProto::kVictor9K, createVictor9kDecoder }, - {DecoderProto::kZilogmcz, createZilogMczDecoder }, - }; - - auto decoder = decoders.find(config.format_case()); - if (decoder == decoders.end()) - error("no decoder specified"); - - return (decoder->second)(config); -} std::shared_ptr Decoder::decodeToSectors( std::shared_ptr fluxmap, diff --git a/lib/encoders/encoders.cc b/lib/encoders/encoders.cc index bcb93afab..11d776b20 100644 --- a/lib/encoders/encoders.cc +++ b/lib/encoders/encoders.cc @@ -3,57 +3,12 @@ #include "lib/data/fluxmap.h" #include "lib/decoders/decoders.h" #include "lib/encoders/encoders.h" -#include "arch/agat/agat.h" -#include "arch/amiga/amiga.h" -#include "arch/apple2/apple2.h" -#include "arch/brother/brother.h" -#include "arch/c64/c64.h" -#include "arch/ibm/ibm.h" -#include "arch/macintosh/macintosh.h" -#include "arch/micropolis/micropolis.h" -#include "arch/northstar/northstar.h" -#include "arch/tartu/tartu.h" -#include "arch/tids990/tids990.h" -#include "arch/victor9k/victor9k.h" #include "lib/encoders/encoders.pb.h" #include "lib/config/proto.h" #include "lib/data/layout.h" #include "lib/data/image.h" #include "protocol.h" -std::unique_ptr Encoder::create(Config& config) -{ - if (!config.hasEncoder()) - error("no encoder configured"); - return create(config->encoder()); -} - -std::unique_ptr Encoder::create(const EncoderProto& config) -{ - static const std::map(const EncoderProto&)>> - encoders = { - {EncoderProto::kAgat, createAgatEncoder }, - {EncoderProto::kAmiga, createAmigaEncoder }, - {EncoderProto::kApple2, createApple2Encoder }, - {EncoderProto::kBrother, createBrotherEncoder }, - {EncoderProto::kC64, createCommodore64Encoder}, - {EncoderProto::kIbm, createIbmEncoder }, - {EncoderProto::kMacintosh, createMacintoshEncoder }, - {EncoderProto::kMicropolis, createMicropolisEncoder }, - {EncoderProto::kNorthstar, createNorthstarEncoder }, - {EncoderProto::kTartu, createTartuEncoder }, - {EncoderProto::kTids990, createTids990Encoder }, - {EncoderProto::kVictor9K, createVictor9kEncoder }, - }; - - auto encoder = encoders.find(config.format_case()); - if (encoder == encoders.end()) - error("no encoder specified"); - - return (encoder->second)(config); -} - nanoseconds_t Encoder::calculatePhysicalClockPeriod( nanoseconds_t targetClockPeriod, nanoseconds_t targetRotationalPeriod) { diff --git a/lib/encoders/encoders.h b/lib/encoders/encoders.h index a23cfbfef..73095478b 100644 --- a/lib/encoders/encoders.h +++ b/lib/encoders/encoders.h @@ -16,7 +16,6 @@ class Encoder virtual ~Encoder() {} static std::unique_ptr create(Config& config); - static std::unique_ptr create(const EncoderProto& config); public: virtual std::shared_ptr getSector( diff --git a/lib/vfs/vfs.cc b/lib/vfs/vfs.cc index f150540b7..25189f6bd 100644 --- a/lib/vfs/vfs.cc +++ b/lib/vfs/vfs.cc @@ -15,6 +15,7 @@ #include "lib/encoders/encoders.h" #include "lib/config/config.pb.h" #include "lib/core/utils.h" +#include "arch/arch.h" Path::Path(const std::vector other): std::vector(other) @@ -244,12 +245,12 @@ std::unique_ptr Filesystem::createFilesystemFromConfig() if (globalConfig().hasFluxSource()) { fluxSource = FluxSource::create(globalConfig()); - decoder = Decoder::create(globalConfig()); + decoder = Arch::createDecoder(globalConfig()); } if (globalConfig()->flux_sink().type() == FLUXTYPE_DRIVE) { fluxSink = FluxSink::create(globalConfig()); - encoder = Encoder::create(globalConfig()); + encoder = Arch::createEncoder(globalConfig()); } sectorInterface = SectorInterface::createFluxSectorInterface( fluxSource, fluxSink, encoder, decoder); diff --git a/src/fe-read.cc b/src/fe-read.cc index 92ed83ebd..80df542ad 100644 --- a/src/fe-read.cc +++ b/src/fe-read.cc @@ -9,6 +9,7 @@ #include "lib/fluxsource/fluxsource.h" #include "lib/fluxsink/fluxsink.h" #include "lib/imagewriter/imagewriter.h" +#include "arch/arch.h" #include "fluxengine.h" #include #include @@ -66,7 +67,7 @@ int mainRead(int argc, const char* argv[]) error("you cannot copy flux to a hardware device"); auto fluxSource = FluxSource::create(globalConfig()); - auto decoder = Decoder::create(globalConfig()); + auto decoder = Arch::createDecoder(globalConfig()); auto writer = ImageWriter::create(globalConfig()); readDiskCommand(*fluxSource, *decoder, *writer); diff --git a/src/fe-write.cc b/src/fe-write.cc index 1ff293fc9..5b73261f2 100644 --- a/src/fe-write.cc +++ b/src/fe-write.cc @@ -9,8 +9,7 @@ #include "lib/config/proto.h" #include "lib/fluxsink/fluxsink.h" #include "lib/fluxsource/fluxsource.h" -#include "arch/brother/brother.h" -#include "arch/ibm/ibm.h" +#include "arch/arch.h" #include "lib/imagereader/imagereader.h" #include "fluxengine.h" #include @@ -71,14 +70,14 @@ int mainWrite(int argc, const char* argv[]) auto reader = ImageReader::create(globalConfig()); std::shared_ptr image = reader->readMappedImage(); - auto encoder = Encoder::create(globalConfig()); + auto encoder = Arch::createEncoder(globalConfig()); auto fluxSink = FluxSink::create(globalConfig()); std::shared_ptr decoder; std::shared_ptr verificationFluxSource; if (globalConfig().hasDecoder() && fluxSink->isHardware() && verify) { - decoder = Decoder::create(globalConfig()); + decoder = Arch::createDecoder(globalConfig()); verificationFluxSource = FluxSource::create(globalConfig().getVerificationFluxSourceProto()); } diff --git a/src/gui/context.cc b/src/gui/context.cc index 13fec69c4..1cf76298c 100644 --- a/src/gui/context.cc +++ b/src/gui/context.cc @@ -1,11 +1,12 @@ -#include -#include -#include -#include -#include -#include -#include -#include +#include "lib/core/globals.h" +#include "lib/fluxsource/fluxsource.h" +#include "lib/fluxsink/fluxsink.h" +#include "lib/imagereader/imagereader.h" +#include "lib/imagewriter/imagewriter.h" +#include "lib/decoders/decoders.h" +#include "lib/encoders/encoders.h" +#include "arch/arch.h" +#include "lib/config/config.h" #include "context.h" #include "gui.h" @@ -64,7 +65,7 @@ namespace { if (!_encoder) { - _encoder = Encoder::create(globalConfig()); + _encoder = Arch::createEncoder(globalConfig()); } return _encoder.get(); } @@ -73,7 +74,7 @@ namespace { if (!_decoder) { - _decoder = Decoder::create(globalConfig()); + _decoder = Arch::createDecoder(globalConfig()); } return _decoder.get(); } From 4bcbf2b089de100693461b37bf84cf858fb53241 Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 16 Oct 2024 21:17:43 +0200 Subject: [PATCH 07/12] Fix bad documentation which got checked in somehow. --- doc/disk-40track_drive.md | 17 ++++- doc/disk-acornadfs.md | 41 +++++++++++- doc/disk-acorndfs.md | 40 +++++++++++- doc/disk-aeslanier.md | 50 ++++++++++++++- doc/disk-agat.md | 38 ++++++++++- doc/disk-amiga.md | 43 ++++++++++++- doc/disk-ampro.md | 54 +++++++++++++++- doc/disk-apple2.md | 76 +++++++++++++++++++++- doc/disk-apple2_drive.md | 18 +++++- doc/disk-atarist.md | 63 +++++++++++++++++- doc/disk-bk.md | 32 +++++++++- doc/disk-brother.md | 130 +++++++++++++++++++++++++++++++++++++- doc/disk-commodore.md | 76 +++++++++++++++++++++- doc/disk-eco1.md | 44 ++++++++++++- doc/disk-epsonpf10.md | 21 +++++- doc/disk-f85.md | 49 +++++++++++++- doc/disk-fb100.md | 50 ++++++++++++++- doc/disk-hplif.md | 44 ++++++++++++- doc/disk-ibm.md | 124 +++++++++++++++++++++++++++++++++++- doc/disk-icl30.md | 21 +++++- doc/disk-mac.md | 75 +++++++++++++++++++++- doc/disk-micropolis.md | 89 +++++++++++++++++++++++++- doc/disk-ms2000.md | 35 +++++++++- doc/disk-mx.md | 71 ++++++++++++++++++++- doc/disk-n88basic.md | 28 +++++++- doc/disk-northstar.md | 52 ++++++++++++++- doc/disk-psos.md | 34 +++++++++- doc/disk-rolandd20.md | 50 ++++++++++++++- doc/disk-rx50.md | 25 +++++++- doc/disk-shugart_drive.md | 17 ++++- doc/disk-smaky6.md | 36 ++++++++++- doc/disk-tartu.md | 50 ++++++++++++++- doc/disk-tids990.md | 41 +++++++++++- doc/disk-tiki.md | 29 ++++++++- doc/disk-victor9k.md | 64 ++++++++++++++++++- doc/disk-zilogmcz.md | 44 ++++++++++++- 36 files changed, 1699 insertions(+), 72 deletions(-) diff --git a/doc/disk-40track_drive.md b/doc/disk-40track_drive.md index f5ce0ddbc..203628f89 100644 --- a/doc/disk-40track_drive.md +++ b/doc/disk-40track_drive.md @@ -1,2 +1,15 @@ --d -\r +40track_drive +==== +## Adjust configuration for a 40-track drive + + +This is an extension profile; adding this to the command line will configure +FluxEngine to read from 40-track, 48tpi 5.25" drives. You have to tell it because there is +no way to detect this automatically. + +For example: + +``` +fluxengine read ibm --180 40track_drive +``` + diff --git a/doc/disk-acornadfs.md b/doc/disk-acornadfs.md index f5ce0ddbc..2e63eff32 100644 --- a/doc/disk-acornadfs.md +++ b/doc/disk-acornadfs.md @@ -1,2 +1,39 @@ --d -\r +acornadfs +==== +## BBC Micro, Archimedes + + +Acorn ADFS disks are used by the 6502-based BBC Micro and ARM-based Archimedes +series of computers. They are yet another variation on MFM encoded IBM scheme +disks, although with different sector sizes and with the 0-based sector +identifiers rather than 1-based sector identifiers. The index hole is ignored +and sectors are written whereever, requiring FluxEngine to do two revolutions +to read a disk. + +There are various different kinds, which should all work out of the box. + +Be aware that Acorn logical block numbering goes all the way up side 0 and +then all the way up side 1. However, FluxEngine uses traditional disk images +with alternating sides, with the blocks from track 0 side 0 then track 0 side +1 then track 1 side 0 etc. Most Acorn emulators will use both formats, but +they might require nudging as the side order can't be reliably autodetected. + +## Options + + - Format variants: + - `160`: 160kB 3.5" or 5.25" 40-track SSDD; S format + - `320`: 320kB 3.5" or 5.25" 80-track SSDD; M format + - `640`: 640kB 3.5" or 5.25" 80-track DSDD; L format + - `800`: 800kB 3.5" 80-track DSDD; D and E formats + - `1600`: 1600kB 3.5" 80-track DSHD; F formats + +## Examples + +To read: + + - `fluxengine read acornadfs --160 -s drive:0 -o acornadfs.img` + - `fluxengine read acornadfs --320 -s drive:0 -o acornadfs.img` + - `fluxengine read acornadfs --640 -s drive:0 -o acornadfs.img` + - `fluxengine read acornadfs --800 -s drive:0 -o acornadfs.img` + - `fluxengine read acornadfs --1600 -s drive:0 -o acornadfs.img` + diff --git a/doc/disk-acorndfs.md b/doc/disk-acorndfs.md index f5ce0ddbc..a36b0ddc0 100644 --- a/doc/disk-acorndfs.md +++ b/doc/disk-acorndfs.md @@ -1,2 +1,38 @@ --d -\r +acorndfs +==== +## Acorn Atom, BBC Micro series + + +Acorn DFS disks are used by the Acorn Atom and BBC Micro series of computers. +They are pretty standard FM encoded IBM scheme disks, with 256-sectors and +0-based sector identifiers. There's nothing particularly special here. + +DFS disks are all single-sided, but allow the other side of the disk to be +used as another volume. + +They come in two varieties, 40 track and 80 track. These should both work. +Some rare disks are both at the same time. FluxEngine can read these but it +requires a bit of fiddling as they have the same tracks on twice. + +## Options + + - Format variants: + - `100`: 100kB 40-track SSSD + - `200`: 200kB 80-track SSSD + +## Examples + +To read: + + - `fluxengine read acorndfs --100 -s drive:0 -o acorndfs.img` + - `fluxengine read acorndfs --200 -s drive:0 -o acorndfs.img` + +To write: + + - `fluxengine write acorndfs --100 -d drive:0 -i acorndfs.img` + - `fluxengine write acorndfs --200 -d drive:0 -i acorndfs.img` + +## References + + - [The Acorn DFS disc format](https://beebwiki.mdfs.net/Acorn_DFS_disc_format) + diff --git a/doc/disk-aeslanier.md b/doc/disk-aeslanier.md index f5ce0ddbc..73073fc34 100644 --- a/doc/disk-aeslanier.md +++ b/doc/disk-aeslanier.md @@ -1,2 +1,48 @@ --d -\r +aeslanier +==== +## 616kB 5.25" 77-track SSDD hard sectored + + +Back in 1980 Lanier released a series of very early integrated word processor +appliances, the No Problem. These were actually [rebranded AES Data Superplus +machines](http://vintagecomputers.site90.net/aes/). They were gigantic, +weighed 40kg, and one example I've found cost ꆲ5bb4 +of nearly ㇢1a6e + +8080 machines with 32kB of RAM, they ran their own proprietary word +processing software off twin 5.25" drive units, but apparently other software +was available. + +The disk format is exceptionally weird. They used 77 track, 32 sector, single-sided +_hard_ sectored disks, where there were multiple index holes, +indicating to the hardware where the sectors start. The encoding scheme +itself is [MMFM (aka +M2FM)](http://www.retrotechnology.com/herbs_stuff/m2fm.html), an early +attempt at double-density disk encoding which rapidly got obsoleted by the +simpler MFM --- and the bytes are stored on disk _backwards_. Even aside from +the encoding, the format on disk was strange; unified sector header/data +records, so that the sector header (containing the sector and track number) +is actually inside the user data. + +FluxEngine can read these, but I only have a single, fairly poor example of a +disk image, and I've had to make a lot of guesses as to the sector format +based on what looks right. If anyone knows _anything_ about these disks, +[please get in touch](https://github.com/davidgiven/fluxengine/issues/new). + +## Options + +(no options) + +## Examples + +To read: + + - `fluxengine read aeslanier -s drive:0 -o aeslanier.img` + +## References + + * [SA800 Diskette Storage Drive - Theory Of + Operations](http://www.hartetechnologies.com/manuals/Shugart/50664-1_SA800_TheorOp_May78.pdf): + talks about MMFM a lot, but the Lanier machines didn't use this disk + format. + diff --git a/doc/disk-agat.md b/doc/disk-agat.md index f5ce0ddbc..dc2b579d6 100644 --- a/doc/disk-agat.md +++ b/doc/disk-agat.md @@ -1,2 +1,36 @@ --d -\r +agat +==== +## 840kB 5.25" 80-track DS + + +The Agat (Russian: ↊fd74 +1983. These were based around a 6502 and were nominally Apple II-compatible +although with enough differences to be problematic. + +They could use either standard Apple II 140kB disks, or a proprietary 840kb +MFM-based double-sided format. FluxEngine supports both of these; this profile +is for the proprietary format. for the Apple II format, use the `apple2` +profile. + +## Options + +(no options) + +## Examples + +To read: + + - `fluxengine read agat -s drive:0 -o agat.img` + +To write: + + - `fluxengine write agat -d drive:0 -i agat.img` + +## References + + - [Magazine article on the + Agat](https://sudonull.com/post/54185-Is-AGAT-a-bad-copy-of-Apple) + + - [Forum thread with (some) documentation on the + format](https://torlus.com/floppy/forum/viewtopic.php?t=1385) + diff --git a/doc/disk-amiga.md b/doc/disk-amiga.md index f5ce0ddbc..fe40ed94a 100644 --- a/doc/disk-amiga.md +++ b/doc/disk-amiga.md @@ -1,2 +1,41 @@ --d -\r +amiga +==== +## 880kB 3.5" DSDD + + +Amiga disks use MFM, but don't use IBM scheme. Instead, the entire track is +read and written as a unit, with each sector butting up against the previous +one. This saves a lot of space which allows the Amiga to not just store 880kB +on a DD disk, but _also_ allows an extra 16 bytes of metadata per sector. + +This metadata is mostly unused, so the default for FluxEngine is to ignore it +and just use the 512 bytes of main sector data. If you want it, specify a +528-byte sector size. The metadata will come after the user data. + +Bizarrely, the data in each sector is stored with all the odd bits first, and +then all the even bits. This is tied into the checksum algorithm, which is +distinctly subpar and not particularly good at detecting errors. + +## Options + + - Sector size: + - `without_metadata`: 512-byte sectors + - `with_metadata`: 528-byte sectors + +## Examples + +To read: + + - `fluxengine read amiga -s drive:0 -o amiga.adf` + +To write: + + - `fluxengine write amiga -d drive:0 -i amiga.adf` + +## References + + - [The Amiga Floppy Boot Process and Physical + Layout](https://wiki.amigaos.net/wiki/Amiga_Floppy_Boot_Process_and_Physical_Layout) + + - [The Amiga Disk File FAQ](http://lclevy.free.fr/adflib/adf_info.html) + diff --git a/doc/disk-ampro.md b/doc/disk-ampro.md index f5ce0ddbc..f1b51f325 100644 --- a/doc/disk-ampro.md +++ b/doc/disk-ampro.md @@ -1,2 +1,52 @@ --d -\r +ampro +==== +## CP/M + + +The Ampro Little Board was a very simple and cheap Z80-based computer from +1984, which ran CP/M. It was, in fact, a single PCB which you could mount +on the bottom of a 5.25" drive. + +[All about the Ampro Little Board](http://oldcomputers.net/ampro-little-board.html) + +It stored either 400kB on a double-sided 40-track drive or 800kB on a +double-sided 80 track drive. The disk format it used was a slightly quirky +variation of the standard MFM IBM scheme --- sector numbering starts at 17 +rather than 1 (or Acorn's 0). FluxEngine supports this. + +FluxEngine has direct filesystem support for these disks, or you can pass the +disk images into [cpmtools](http://www.moria.de/~michael/cpmtools/): + +``` +$ cpmls -f ampdsdd ampro.img +0: +-a60014.e +amprodsk.com +bitchk.doc +bitchk.mac +cpmmac.mac +dir.com +himem.doc +himem.mac +kaydiag.lbr +kayinfo.lbr +...etc... +``` + +## Options + + - Format variants: + - `400`: 400kB 40-track DSDD + - `800`: 800kB 80-track DSDD + +## Examples + +To read: + + - `fluxengine read ampro --400 -s drive:0 -o ampro.img` + - `fluxengine read ampro --800 -s drive:0 -o ampro.img` + +## References + + - [The Ampro Little Board](http://oldcomputers.net/ampro-little-board.html) + diff --git a/doc/disk-apple2.md b/doc/disk-apple2.md index f5ce0ddbc..d866a4974 100644 --- a/doc/disk-apple2.md +++ b/doc/disk-apple2.md @@ -1,2 +1,74 @@ --d -\r +apple2 +==== +## Prodos, Appledos, and CP/M + + +Apple II disks are nominally fairly sensible 40-track, single-sided, 256 +bytes-per-sector jobs. However, they come in two varieties: DOS 3.3/ProDOS and +above, and pre-DOS 3.3. They use different GCR encoding systems, dubbed +6-and-2 and 5-and-3, and are mutually incompatible (although in some rare +cases you can mix 6-and-2 and 5-and-3 sectors on the same disk). + +The difference is in the drive controller; the 6-and-2 controller is capable +of a more efficient encoding, and can fit 16 sectors on a track, storing +140kB on a disk. The 5-and-3 controller can only fit 13, with a mere 114kB. + +Both formats use GCR (in different varieties) in a nice, simple grid of +sectors, unlike the Macintosh. Like the Macintosh, there's a crazy encoding +scheme applied to the data before it goes down on disk to speed up +checksumming. + +In addition, a lot of the behaviour of the drive was handled in software. +This means that Apple II disks can do all kinds of weird things, including +having spiral tracks! Copy protection for the Apple II was even madder than +on other systems. + +FluxEngine can only read well-behaved 6-and-2 disks. It doesn't even try to +handle the weird stuff. + +Apple DOS also applies logical sector remapping on top of the physical sector +numbering on the disk, and this _varies_ depending on what the disk is for. +FluxEngine can remap the sectors from physical to logical using modifiers. If +you don't specify a remapping modifier, you get the sectors in the order they +appear on the disk. + +If you don't want an image in physical sector order, specify one of the +filesystem ordering options. These also select the appropriate file system; +FluxEngine has read-only support for all of these. + +In addition, some third-party systems use 80-track double sides drives, with +the same underlying disk format. The complication here is that the AppleDOS +filesystem only supports up to 50 tracks, so it needs tweaking to support +larger disks. It treats the second side of the disk as a completely different +volume. + +## Options + + - Format variants: + - `140`: 140kB 5.25" 35-track SS + - `640`: 640kB 5.25" 80-track DS + - Filesystem and sector skew: + - `nofs`: use physical CHS sector order and no file system + - `appledos`: use AppleDOS soft sector skew and file system + - `prodos`: use ProDOS soft sector skew and filesystem + - `cpm`: use CP/M soft sector skew and filesystem + - `side1`: for AppleDOS file system access, read the volume on side 1 of a disk + +## Examples + +To read: + + - `fluxengine read apple2 --140 -s drive:0 -o apple2.img` + - `fluxengine read apple2 --640 -s drive:0 -o apple2.img` + +To write: + + - `fluxengine write apple2 --140 -d drive:0 -i apple2.img` + - `fluxengine write apple2 --640 -d drive:0 -i apple2.img` + +## References + + - [Beneath Apple DOS](https://fabiensanglard.net/fd_proxy/prince_of_persia/Beneath%20Apple%20DOS.pdf) + + - [MAME's ap2_dsk.cpp file](https://github.com/mamedev/mame/blob/4263a71e64377db11392c458b580c5ae83556bc7/src/lib/formats/ap2_dsk.cpp) + diff --git a/doc/disk-apple2_drive.md b/doc/disk-apple2_drive.md index f5ce0ddbc..e631d138e 100644 --- a/doc/disk-apple2_drive.md +++ b/doc/disk-apple2_drive.md @@ -1,2 +1,16 @@ --d -\r +apple2_drive +==== +## Adjust configuration for a 40-track Apple II drive + + +This is an extension profile; adding this to the command line will configure +FluxEngine to adjust the pinout and track spacing to work with an Apple II +drive. This only works on Greaseweazle hardware and requires a custom +connector. + +For example: + +``` +fluxengine read apple2 --160 apple2_drive +``` + diff --git a/doc/disk-atarist.md b/doc/disk-atarist.md index f5ce0ddbc..25f3e11e6 100644 --- a/doc/disk-atarist.md +++ b/doc/disk-atarist.md @@ -1,2 +1,61 @@ --d -\r +atarist +==== +## Almost PC compatible + + +Atari ST disks are standard MFM encoded IBM scheme disks without an IAM header. +Disks are typically formatted 512 bytes per sector with between 9-10 (sometimes +11!) sectors per track and 80-82 tracks per side. + +For some reason, occasionally formatting software will put an extra IDAM record +with a sector number of 66 on a disk, which can horribly confuse things. The +Atari profiles below are configured to ignore these. + +Be aware that many PC drives (including mine) won't do the 82 track formats. + +## Options + + - Format variants: + - `360`: 360kB 3.5" 80-track 9-sector SSDD + - `370`: 370kB 3.5" 82-track 9-sector SSDD + - `400`: 400kB 3.5" 80-track 10-sector SSDD + - `410`: 410kB 3.5" 82-track 10-sector SSDD + - `720`: 720kB 3.5" 80-track 9-sector DSDD + - `740`: 740kB 3.5" 82-track 9-sector DSDD + - `800`: 800kB 3.5" 80-track 10-sector DSDD + - `820`: 820kB 3.5" 82-track 10-sector DSDD + +## Examples + +To read: + + - `fluxengine read atarist --360 -s drive:0 -o atarist.img` + - `fluxengine read atarist --370 -s drive:0 -o atarist.img` + - `fluxengine read atarist --400 -s drive:0 -o atarist.img` + - `fluxengine read atarist --410 -s drive:0 -o atarist.img` + - `fluxengine read atarist --720 -s drive:0 -o atarist.img` + - `fluxengine read atarist --740 -s drive:0 -o atarist.img` + - `fluxengine read atarist --800 -s drive:0 -o atarist.img` + - `fluxengine read atarist --820 -s drive:0 -o atarist.img` + +To write: + + - `fluxengine write atarist --360 -d drive:0 -i atarist.img` + - `fluxengine write atarist --370 -d drive:0 -i atarist.img` + - `fluxengine write atarist --400 -d drive:0 -i atarist.img` + - `fluxengine write atarist --410 -d drive:0 -i atarist.img` + - `fluxengine write atarist --720 -d drive:0 -i atarist.img` + - `fluxengine write atarist --740 -d drive:0 -i atarist.img` + - `fluxengine write atarist --800 -d drive:0 -i atarist.img` + - `fluxengine write atarist --820 -d drive:0 -i atarist.img` + +## References + + - [Atari ST Floppy Drive Hardware + Information](https://info-coach.fr/atari/hardware/FD-Hard.php) by Jean + Louis-Guerin + + - [Atari ST Floppy Drive Software + Information](https://info-coach.fr/atari/software/FD-Soft.php) by Jean + Louis-Guerin + diff --git a/doc/disk-bk.md b/doc/disk-bk.md index f5ce0ddbc..fa18d96ab 100644 --- a/doc/disk-bk.md +++ b/doc/disk-bk.md @@ -1,2 +1,30 @@ --d -\r +bk +==== +## 800kB 5.25"/3.5" 80-track 10-sector DSDD + + +The BK (an abbreviation for 1ba9 +is a Soviet era personal computer from Elektronika based on a PDP-11 +single-chip processor. It was the _only_ official, government approved home +computer in mass production at the time. + +It got a floppy interface in 1989 when the 128kB BK-0011 was released. This +used a relatively normal double-sided IBM scheme format with 80 sectors and ten +sectors per track, resulting in 800kB disks. The format is, in fact, identical +to the Atari ST 800kB format. Either 5.25" or 3.5" drives were used depending +on what was available at the time, with the same format on both. + +## Options + +(no options) + +## Examples + +To read: + + - `fluxengine read bk -s drive:0 -o bk800.img` + +To write: + + - `fluxengine write bk -d drive:0 -i bk800.img` + diff --git a/doc/disk-brother.md b/doc/disk-brother.md index f5ce0ddbc..6e12dceda 100644 --- a/doc/disk-brother.md +++ b/doc/disk-brother.md @@ -1,2 +1,128 @@ --d -\r +brother +==== +## GCR family + + +Brother word processor disks are weird, using custom tooling and chipsets. +They are completely not PC compatible in every possible way other than the +size. + +Different word processors use different disk formats --- the only ones supported +by FluxEngine are the 120kB and 240kB 3.5" formats. Use the `--120` and `--240` +options to select which one. + +Apparently about 20% of Brother word processors have alignment issues which +means that the disks can't be read by FluxEngine (because the tracks on the disk +don't line up with the position of the head in a PC drive). The word processors +themselves solved this by microstepping until they found where the real track +is, but normal PC drives aren't capable of doing this. Particularly with the +120kB disks, you might want to fiddle with the head bias (e.g. +`--drive.head_bias=3`) to get a clean read. Keep an eye on the bad sector map +that's dumped at the end of a read. My word processor likes to put logical track +0 on physical track 3, which means that logical track 77 is on physical track +80, so I need that `head_bias` value of 3; luckily my PC drive can access track +80. + +Using FluxEngine to *write* disks isn't a problem, so the +simplest solution is to use FluxEngine to create a new disk, with the tracks +aligned properly, and then use a word processor to copy the files you want +onto it. The new disk can then be read and you can extract the files. +Obviously this sucks if you don't actually have a word processor, but I can't +do anything about that. + +If you find one of these misaligned disks then *please* [get in +touch](https://github.com/davidgiven/fluxengine/issues/new); I want to +investigate. + +## Options + + - Format variants: + - `120`: 120kB 3.5" 39-track SS GCR + - `240`: 240kB 3.5" 78-track SS GCR + +## Examples + +To read: + + - `fluxengine read brother --120 -s drive:0 -o brother.img` + - `fluxengine read brother --240 -s drive:0 -o brother.img` + +To write: + + - `fluxengine write brother --120 -d drive:0 -i brother.img` + - `fluxengine write brother --240 -d drive:0 -i brother.img` + +Dealing with misaligned disks +----------------------------- + +While FluxEngine can't read misaligned disks directly, Brother word processors +_can_. If you have access to a compatible word processor, there's a fairly +simple workaround to allow you to extract the data: + + 1. Format a disk using FluxEngine (by simply writing a blank filesystem image + to a disk). This will have the correct alignment to work on a PC drive. + + 2. Use a word processor to copy the misaligned disk to the newly formatted + disk. The machine will happily adjust itself to both sets of alignments. + + 3. Use FluxEngine to read the data off the correctly aligned disk. + +I realise this is rather unsatisfactory, as the Brother hardware is becoming +rarer and they cope rather badly with damaged disks, but this is a limitation +of the hardware of normal PC drives. (It _is_ possible to deliberately misalign +a drive to make it match up with a bad disk, but this is for experts only --- I +wouldn't dare.) + +Low level format +---------------- + +The drive is a single-sided 3.5" drive spinning at not 300 rpm (I don't know +the precise speed yet but FluxEngine doesn't care). The 240kB disks have 78 +tracks and the 120kB disks have 39. + +Each track has 12 256-byte sectors. The drive ignores the index hole so they're +lined up all anyhow. As FluxEngine can only read from index to index, it +actually reads two complete revolutions and reassembles the sectors from that. + +The underlying encoding is exceptionally weird; they use two different kinds of +GCR, one kind for the sector header records and a completely different one for +the data itself. It also has a completely bizarre CRC variant which a genius on +StackOverflow reverse engineered for me. However, odd though it may be, it does +seem pretty robust. + +See the source code for the GCR tables and CRC routine. + +Sectors are about 16.2ms apart on the disk (at 300 rpm). The header and +data records are 0.694ms apart. (All measured from the beginning of the +record.) The sector order is 05a3816b4927, which gives a sector skew of 5. + +High level format +----------------- + +Once decoded, you end up with a file system image. FluxEngine supports direct +filesystem access for both kinds of disks. + +### 120kB disks + +These disks use a proprietary and very simple file system. It's FAT-like +with an obvious directory and allocation table. It's supported by FluxEngine. + +Any files whose names begin with an asterisk (`*`) will be marked as hidden. If +the file is named `*boot`, then a boot sector will be created which will load +and run the file at 0x7000 if the machine is started with CODE+Q pressed. So +far this has only been confirmed to work on a WP-1. + +### 240kB disks + +Conversely, the 240kB disks turns out to be a completely normal Microsoft FAT +file system with a media type of 0x58 --- did you know that FAT supports 256 +byte sectors? I didn't --- of the MSX-DOS variety. There's a faint +possibility that the word processor is based on MSX-DOS, but I haven't +reverse engineered it to find out. + +Standard Linux mtools will access the filesystem image and allow you to move +files in and out. However, you'll need to change the media type bytes at +offsets 0x015 and 0x100 from 0x58 to 0xf0 before mtools will touch it. The +supplied `brother240tool` will do this. Additionally, FluxEngine's own FAT +file system supports this. + diff --git a/doc/disk-commodore.md b/doc/disk-commodore.md index f5ce0ddbc..c2ad45f93 100644 --- a/doc/disk-commodore.md +++ b/doc/disk-commodore.md @@ -1,2 +1,74 @@ --d -\r +commodore +==== +## 1541, 1581, 8050 and variations + + +Commodore 8-bit computer disks come in two varieties: GCR, which are the +overwhelming majority; and MFM, only used on the 1571 and 1581. The latter were +(as far as I can tell) standard IBM PC format disks with a slightly odd sector +count. + +The GCR disks are much more interesting. They could store 170kB on a +single-sided disk (although later drives were double-sided), using a proprietary +encoding and record scheme; like [Apple Macintosh disks](macintosh.md) they +stored varying numbers of sectors per track to make the most of the physical +disk area, although unlike them they did it by changing the bitrate rather than +adjusting the motor speed. + +The drives were also intelligent and ran DOS on a CPU inside them. The +computer itself knew nothing about file systems. You could even upload +programs onto the drive and run them there, allowing all sorts of custom disk +formats, although this was mostly used to compensate for the [cripplingly +slow connection to the +computer](https://ilesj.wordpress.com/2014/05/14/1541-why-so-complicated/) of +300 bytes per second (!). (The drive itself could transfer data reasonably +quickly.) + + - a 1541 disk has 35 tracks of 17 to 21 sectors, each 256 bytes long + (sometimes 40 tracks), and uses GCR encoding. + + - a standard 1581 disk has 80 tracks and two sides, each with 10 sectors, 512 + bytes long, and uses normal IBM encoding. + + - an 8050 disk has 77 tracks and two sides, with four speed zones; the number + of sectors varies from 23 to 29, using GCR encoding. These will store + 1042kB. These drives are peculiar because they are 100tpi and therefore the + disks cannot be read in normal 96tpi drives. + + - a CMD FD2000 disk (a popular third-party Commodore disk drive) has 81 + tracks and two sides, each with 10 1024-byte sectors, for a massive 1620kB + of storage. This also uses IBM encoding. + +A CMD FD2000 disk (a popular third-party Commodore disk drive) + +## Options + + - Format variants: + - `171`: 171kB 1541, 35-track variant + - `192`: 192kB 1541, 40-track variant + - `800`: 800kB 3.5" 1581 + - `1042`: 1042kB 5.25" 8051 + - `1620`: 1620kB, CMD FD2000 + +## Examples + +To read: + + - `fluxengine read commodore --171 -s drive:0 -o commodore.d64` + - `fluxengine read commodore --192 -s drive:0 -o commodore.d64` + - `fluxengine read commodore --800 -s drive:0 -o commodore.d64` + - `fluxengine read commodore --1042 -s drive:0 -o commodore.d64` + - `fluxengine read commodore --1620 -s drive:0 -o commodore.d64` + +To write: + + - `fluxengine write commodore --171 -d drive:0 -i commodore.d64` + - `fluxengine write commodore --192 -d drive:0 -i commodore.d64` + - `fluxengine write commodore --800 -d drive:0 -i commodore.d64` + - `fluxengine write commodore --1620 -d drive:0 -i commodore.d64` + +## References + + - [Ruud's Commodore Site: 1541](http://www.baltissen.org/newhtm/1541c.htm): + documentation on the 1541 disk format. + diff --git a/doc/disk-eco1.md b/doc/disk-eco1.md index f5ce0ddbc..f31ca3a1a 100644 --- a/doc/disk-eco1.md +++ b/doc/disk-eco1.md @@ -1,2 +1,42 @@ --d -\r +eco1 +==== +## CP/M; 1210kB 77-track mixed format DSHD + + +The Eco1 is a Italian CP/M machine produced in 1982. It had 64kB of RAM, in +later models expandable up to 384kB, and _two_ Z80 processors. One of these was +used solely for managing the twin 8" drives, each storing 1.2MB, which was +quite impressive for a CP/M machine in those days. Visually it is best +described as 'very brown'. + +
+ A contemporary advert for the Eco1 +
+ +Its format is standard IBM scheme, but with an interesting wrinkle: there are +_three_ different formatting zones on the disk: + + - Track 0 side 0: 26 sectors, 128 bytes per sector (3296 bytes) + - Track 0 side 1: 26 sectors, 256 bytes per sector (6656 bytes) + - All others: 16 sectors, 512 bytes per sector (8192 bytes) + +The standard `read ibm` command will autodetect and read these disks, but due +to the format confusing the size autodetection the images need postprocessing +to be useful, so there's a custom profile for the Eco1 which produces sensible +images. + +## Options + +(no options) + +## Examples + +To read: + + - `fluxengine read eco1 -s drive:0 -o eco1.img` + +## References + + - [Apulio Retrocomputing's page on the + Eco1](https://www.apuliaretrocomputing.it/wordpress/?p=8976) + diff --git a/doc/disk-epsonpf10.md b/doc/disk-epsonpf10.md index f5ce0ddbc..4f272f097 100644 --- a/doc/disk-epsonpf10.md +++ b/doc/disk-epsonpf10.md @@ -1,2 +1,19 @@ --d -\r +epsonpf10 +==== +## CP/M; 3.5" 40-track DSDD + + +The Epson PF10 is the disk unit for the Epson Z80 series of 'laptops', running +CP/M. It uses a single-sided 40-track 3.5" format, which is unusual, but the +format itself is yet another IBM scheme variant. + +## Options + +(no options) + +## Examples + +To read: + + - `fluxengine read epsonpf10 -s drive:0 -o epsonpf10.img` + diff --git a/doc/disk-f85.md b/doc/disk-f85.md index f5ce0ddbc..3f99b3432 100644 --- a/doc/disk-f85.md +++ b/doc/disk-f85.md @@ -1,2 +1,47 @@ --d -\r +f85 +==== +## 461kB 5.25" 77-track SS + + +The Durango F85 was an early office computer based around a 5MHz 8085 processor, +sold in 1977. It had an impressive 64kB of RAM, upgradable to 128kB, and ran +its own multitasking operating system call DX-85M, as well as CP/M. It had an +interesting electric-typewriter form factor, with a little monitor sitting on +the side of it --- in operation you were facing the 14" printer. + +It was touted as being portable. Which it was, if you were strong; the story +is that they had to do an extensive search to find someone capable of lifting +it for the following photo... + +
+A Durango F85, held precariously +
+ +...and even then, they had to airbrush out the tendons in her neck from the +effort! + +It used 5.25 soft-sectored disks storing an impressive-for-those-days +480kBish on a side, using a proprietary 4-in-5 GCR encoding. They used 77 +tracks, 12 sectors and 512 bytes per sector. Later models used double-sided +disks; I don't have access to an image of one so don't know how they work +(there's a suspicious looking spare byte in the sector header which could +store the side). As always, if you have one, please [get in +touch](https://github.com/davidgiven/fluxengine/issues/new). + +## Options + +(no options) + +## Examples + +To read: + + - `fluxengine read f85 -s drive:0 -o f85.img` + +## References + +There's amazingly little information about these things. + + * [Chuck Guzis' F85 page](http://www.sydex.com/durango/durango.html) with + lots of pictures + diff --git a/doc/disk-fb100.md b/doc/disk-fb100.md index f5ce0ddbc..2ba814222 100644 --- a/doc/disk-fb100.md +++ b/doc/disk-fb100.md @@ -1,2 +1,48 @@ --d -\r +fb100 +==== +## 100kB 3.5" 40-track SSSD + + +The Brother FB-100 is a serial-attached smart floppy drive used by a several +different machines for mass storage, including the Tandy Model 100 and +clones, the Husky Hunter 2, and (bizarrely) several knitting machines. It was +usually rebadged, sometimes with a cheap paper label stuck over the Brother +logo, but the most common variant appears to be the Tandy Portable Disk Drive +or TPDD: + +
+ A Tandy Portable Disk Drive +
+ +It's a bit of an oddball: the disk encoding is FM with a very custom record +scheme: 40-track single-sided 3.5" disks storing 100kB or so each. Each track +had only _two_ sectors, each 1280 bytes, but with an additional 12 bytes of +ID data used for filesystem management. + +There was also apparently a TPDD-2 which could store twice as much data, but +I don't have access to one of those disks. + +## Options + +(no options) + +## Examples + +To read: + + - `fluxengine read fb100 -s drive:0 -o fb100.img` + +## References + + - [Tandy Portable Disk Drive operations + manual](http://www.classiccmp.org/cini/pdf/Tandy/Portable%20Disk%20Drive%20Operation%20Manual.pdf) + + - [Tandy Portable Disk Drive service + manual](https://archive.org/details/TandyPortableDiskDriveSoftwareManual26-3808s) + + - [TPDD design notes (including a dump of the + ROM)](http://bitchin100.com/wiki/index.php?title=TPDD_Design_Notes) + + - [Knitting machine FB-100 + resources](http://www.k2g2.org/wiki:brother_fb-100) + diff --git a/doc/disk-hplif.md b/doc/disk-hplif.md index f5ce0ddbc..f5cf22f61 100644 --- a/doc/disk-hplif.md +++ b/doc/disk-hplif.md @@ -1,2 +1,42 @@ --d -\r +hplif +==== +## a variety of disk formats used by HP + + +LIF, a.k.a. Logical Interchange Format, is a series of formats used by +Hewlett-Packard across their entire range of computers, from calculators to +modern servers. It also defines a simple non-hierarchical filesystem which is +bizarrely _still_ supported by HP-UX systems. + +Floppy-disk wise, they're yet more variations of the standard IBM floppy +encoding scheme. + +## Options + + - Format variants: + - `264`: 264kB 3.5" 66-track SSDD; HP9121 format + - `608`: 608kB 3.5" 76-track DSDD; HP9122 format + - `616`: 616kB 3.5" 77-track DSDD + - `770`: 770kB 3.5" 77-track DSDD + +## Examples + +To read: + + - `fluxengine read hplif --264 -s drive:0 -o hplif.img` + - `fluxengine read hplif --608 -s drive:0 -o hplif.img` + - `fluxengine read hplif --616 -s drive:0 -o hplif.img` + - `fluxengine read hplif --770 -s drive:0 -o hplif.img` + +To write: + + - `fluxengine write hplif --264 -d drive:0 -i hplif.img` + - `fluxengine write hplif --608 -d drive:0 -i hplif.img` + - `fluxengine write hplif --616 -d drive:0 -i hplif.img` + - `fluxengine write hplif --770 -d drive:0 -i hplif.img` + +## References + + * [A summary of the Hewlett Packard floppy disk + formats](http://www.bitsavers.org/pdf/hp/disc/912x/HP_Flexible_Disk_Formats.pdf) + diff --git a/doc/disk-ibm.md b/doc/disk-ibm.md index f5ce0ddbc..742be5281 100644 --- a/doc/disk-ibm.md +++ b/doc/disk-ibm.md @@ -1,2 +1,122 @@ --d -\r +ibm +==== +## Generic PC 3.5"/5.25" disks + + +IBM scheme disks are _the_ most common disk format, ever. They're used by a +huge variety of different systems, and they come in a huge variety of different +forms, but they're all fundamentally the same: either FM or MFM, either single- +or double-sided, with distinct sector header and data records and no sector +metadata. Systems which use IBM scheme disks include but are not limited to: + + - IBM PCs (naturally) + - Atari ST + - late era Apple machines + - Acorn machines + - the TRS-80 + - late era Commodore machines (the 1571 and so on) + - most CP/M machines + - NEC PC-88 series + - NEC PC-98 series + - Sharp X68000 + - Fujitsu FM Towns + - VAX & PDP-11 + - etc + +FluxEngine supports reading these. However, some variants are more peculiar +than others, and as a result there are specific decoders which set the defaults +correctly for certain formats (for example: on PC disks the sector numbers +start from 1, but on Acorn disks they start from 0). The IBM decoder described +here is the generic one, and is suited for 'conventional' PC disks. While you +can read all the variant formats with it if you use the right set of arguments, +it's easier to use the specific decoder. + +There is a generic decoder which should adjust automatically to whichever disk +format you are using, but it's unreliable and not recommended. This format +should also be used if you are writing images such as DIM which specify the +image format. FluxEngine will use these parameters. + +## Options + + - Format variants: + - `auto`: try to autodetect the format (unreliable) + - `160`: 160kB 5.25" 40-track 8-sector SSDD + - `180`: 180kB 5.25" 40-track 9-sector SSDD + - `320`: 320kB 5.25" 40-track 8-sector DSDD + - `360`: 360kB 5.25" 40-track 9-sector DSDD + - `720_96`: 720kB 5.25" 80-track 9-sector DSDD + - `720_135`: 720kB 3.5" 80-track 9-sector DSDD + - `1200`: 1200kB 5.25" 80-track 15-sector DSHD + - `1232`: 1232kB 5.25" 77-track 8-sector DSHD + - `1440`: 1440kB 3.5" 80-track 18-sector DSHD + - `1680`: 1680kB 3.5" 80-track 21-sector DSHD; DMF + +## Examples + +To read: + + - `fluxengine read ibm --auto -s drive:0 -o ibm.img` + - `fluxengine read ibm --160 -s drive:0 -o ibm.img` + - `fluxengine read ibm --180 -s drive:0 -o ibm.img` + - `fluxengine read ibm --320 -s drive:0 -o ibm.img` + - `fluxengine read ibm --360 -s drive:0 -o ibm.img` + - `fluxengine read ibm --720_96 -s drive:0 -o ibm.img` + - `fluxengine read ibm --720_135 -s drive:0 -o ibm.img` + - `fluxengine read ibm --1200 -s drive:0 -o ibm.img` + - `fluxengine read ibm --1232 -s drive:0 -o ibm.img` + - `fluxengine read ibm --1440 -s drive:0 -o ibm.img` + - `fluxengine read ibm --1680 -s drive:0 -o ibm.img` + +To write: + + - `fluxengine write ibm --160 -d drive:0 -i ibm.img` + - `fluxengine write ibm --180 -d drive:0 -i ibm.img` + - `fluxengine write ibm --320 -d drive:0 -i ibm.img` + - `fluxengine write ibm --360 -d drive:0 -i ibm.img` + - `fluxengine write ibm --720_96 -d drive:0 -i ibm.img` + - `fluxengine write ibm --720_135 -d drive:0 -i ibm.img` + - `fluxengine write ibm --1200 -d drive:0 -i ibm.img` + - `fluxengine write ibm --1232 -d drive:0 -i ibm.img` + - `fluxengine write ibm --1440 -d drive:0 -i ibm.img` + - `fluxengine write ibm --1680 -d drive:0 -i ibm.img` + +Mixed-format disks +------------------ + +Some disks, such as those belonging to early CP/M machines, or N88-Basic disks +(for PC-88 and PC-98), have more than one format on the disk at once. Typically, +the first few tracks will be low-density FM encoded and will be read by the +machine's ROM; those tracks contain new floppy drive handling code capable of +coping with MFM data, and so the rest of the disk will use that, allowing them +to store more data. + +FluxEngine can read these fine, but it tends to get a bit confused when it sees +tracks with differing numbers of sectors --- if track 0 has 32 sectors but +track 1 has 16, it will assume that sectors 16..31 are missing on track 1 and +size the image file accordingly. This can be worked around by specifying the +size of each track; see the `eco1` read profile for an example. + +N88-Basic format floppies can be written by either specifying the `n88basic` +format, or by using D88 or NFD format images which include explicit sector +layout information. + +Writing other formats can be made to work too, by creating a custom format +specifier, using the `n88basic` format as an example. +Please [get in touch](https://github.com/davidgiven/fluxengine/issues/new) if +you have specific requirements. + +360rpm 3.5" disks +----------------- + +Japanese PCs (NEC PC-98, Sharp X68000, Fujitsu FM Towns) spin their floppy +drives at 360rpm rather than the more typical 300rpm. This was done in order +to be fully backwards compatible with 5.25" disks, while using the exact +same floppy controller. Later models of the PC-9821, as well as most USB floppy +drives, feature "tri-mode" support which in addition to normal 300rpm modes, +can change their speed to read and write 360rpm DD and HD disks. + +Neither the FluxEngine or Greaseweazle hardware can currently command a +tri-mode drive to spin at 360rpm. However on both devices the FluxEngine +software is capable of both reading and writing 300rpm disks at 360rpm and vice +versa, so it shouldn't matter. + diff --git a/doc/disk-icl30.md b/doc/disk-icl30.md index f5ce0ddbc..a5333a8d4 100644 --- a/doc/disk-icl30.md +++ b/doc/disk-icl30.md @@ -1,2 +1,19 @@ --d -\r +icl30 +==== +## CP/M; 263kB 35-track DSSD + + +The ICL Model 30 is a reasonably standard CP/M machine using 35-track single +density disks and the traditional CP/M 128-byte secotrs --- 30 of them per +track! Other than that it's another IBM scheme variation. + +## Options + +(no options) + +## Examples + +To read: + + - `fluxengine read icl30 -s drive:0 -o icl30.img` + diff --git a/doc/disk-mac.md b/doc/disk-mac.md index f5ce0ddbc..655c5175a 100644 --- a/doc/disk-mac.md +++ b/doc/disk-mac.md @@ -1,2 +1,73 @@ --d -\r +mac +==== +## 400kB/800kB 3.5" GCR + + +Macintosh disks come in two varieties: the newer 1440kB ones, which are +perfectly ordinary PC disks you should use the `ibm` profile to read them, and +the older 800kB disks (and 400kB for the single sides ones). They have 80 +tracks and up to 12 sectors per track. + +They are also completely insane. + +It's not just the weird, custom GCR encoding. It's not just the utterly +bizarre additional encoding/checksum built on top of that where [every byte +is mutated according to the previous bytes in the +sector](https://www.bigmessowires.com/2011/10/02/crazy-disk-encoding-schemes/). +It's not just the odd way in which disks think they have four sides, two on one +side and two on the other, so that the track byte stores only the bottom 6 bits +of the track number. It's not just the way that Macintosh sectors are 524 bytes +long. No, it's the way the Macintosh drive changes speed depending on which +track it's looking at, so that each track contains a different amount of data. + +The reason for this is actually quite sensible: the tracks towards the centre +of the disk are obviously moving more slowly, so you can't pack the bits in +quite as closely (due to limitations in the magnetic media). You can use a +higher bitrate at the edge of the disk than in the middle. Many platforms, for +example the Commodore 64 1541 drive, changed bitrate this way. + +But Macintosh disks used a constant bitrate and changed the speed that the disk +spun instead to achieve the same effect... + +_Anyway_: FluxEngine will read them fine on conventional drives. Because it's +clever. + +Macintosh computers never really used the twelve bytes of metadata and the +standard for disk images is to omit it. If you want them, specify that you want +524-byte sectors. The metadata will follow the 512 bytes of user data. + +## Options + + - Format variants: + - `400`: 400kB 80-track SSDD + - `800`: 800kB 80-track DSDD + - `metadata`: read/write 524 byte sectors + +## Examples + +To read: + + - `fluxengine read mac --400 -s drive:0 -o mac.dsk` + - `fluxengine read mac --800 -s drive:0 -o mac.dsk` + +To write: + + - `fluxengine write mac --400 -d drive:0 -i mac.dsk` + - `fluxengine write mac --800 -d drive:0 -i mac.dsk` + +## References + + - [MAME's ap_dsk35.cpp file](https://github.com/mamedev/mame/blob/4263a71e64377db11392c458b580c5ae83556bc7/src/lib/formats/ap_dsk35.cpp), + without which I'd never have managed to do this + + - [Crazy Disk Encoding + Schemes](https://www.bigmessowires.com/2011/10/02/crazy-disk-encoding-schemes/), which made + me realise just how nuts the format is + + - [Les Disquettes et le drive Disk II](http://www.hackzapple.com/DISKII/DISKIITECH.HTM), an + epicly detailed writeup of the Apple II disk format (which is closely related) + + - [The DiskCopy 4.2 + format](https://www.discferret.com/wiki/Apple_DiskCopy_4.2), described on + the DiskFerret website. + diff --git a/doc/disk-micropolis.md b/doc/disk-micropolis.md index f5ce0ddbc..a5c2576f4 100644 --- a/doc/disk-micropolis.md +++ b/doc/disk-micropolis.md @@ -1,2 +1,87 @@ --d -\r +micropolis +==== +## 100tpi MetaFloppy disks + + +Micropolis MetaFloppy disks use MFM and hard sectors. Mod I was 48 TPI and +stored 143k per side. Mod II was 100 TPI and stored 315k per side. Each of the +16 sectors contains 266 bytes of "user data," allowing 10 bytes of metadata for +use by the operating system. Micropolis DOS (MDOS) used the metadata bytes, but +CP/M did not. + +Some later systems were Micropolis-compatible and so were also 100 TPI, like +the Vector Graphic Dual-Mode Disk Controller which was paired with a Tandon +drive. + +**Important note:** You _cannot_ read these disks with a normal PC drive, as +these drives are 96tpi. The track spacing is determined by the physical geometry +of the drive and can't be changed in software. You'll need to get hold of a +100tpi Micropolis drive. Luckily these seem to use the same connector and +pinout as a 96tpi PC 5.25" drive. In use they should be identical. + +While most operating systems use the standard Micropolis checksum, Vector +Graphic MZOS uses a unique checksum. The decoder will automatically detect +the checksum type in use; however, a specific checksum type may be forced +using the `--decoder.micropolis.checksum_type=TYPE` where TYPE is one of: + +| Checksum | Description | +|------------|-----------------------------------------| +| AUTO | Automatically detect | +| MICROPOLIS | Standard Micropolis (MDOS, CP/M, OASIS) | +| MZOS | Vector Graphic MZOS | + +Later versions of the Micropolis format supported ECC, especially in +controllers with HDD support. The ECC can detect and correct errors. However, +it is unclear what ECC algorithm was used by each vendor. ECC is disabled by +default, but available for checking and correcting using +`--decoder.micropolis.ecc_type=TYPE` and for writing from IMG files using +`--encoder.micropolis.ecc_type=TYPE`, where TYPE is one of: + +| ECC | Description | +|--------|------------------------------------------| +| NONE | No ECC processing enabled | +| VECTOR | Vector Graphic Dual-Mode Disk Controller | + +The [CP/M BIOS](https://www.seasip.info/Cpm/bios.html) defined SELDSK, SETTRK, +and SETSEC, but no function to select the head/side. Double-sided floppies +could be represented as having either twice the number of sectors, for CHS, or +twice the number of tracks, HCS; the second side's tracks in opposite order +logically followed the first side (e.g., tracks 77-153). Micropolis disks +tended to be the latter. FluxEngine always emits CHS format disks, so you may +need to apply extra options to change the format if desired. + +## Options + + - : + - `143`: 143kB 5.25" SSDD hard-sectored; Micropolis MetaFloppy Mod I + - `287`: 287kB 5.25" DSDD hard-sectored; Micropolis MetaFloppy Mod I + - `315`: 315kB 5.25" SSDD hard-sectored; Micropolis MetaFloppy Mod II + - `630`: 630kB 5.25" DSDD hard-sectored; Micropolis MetaFloppy Mod II + - `vgi`: Read/write VGI format images with 275 bytes per sector + +## Examples + +To read: + + - `fluxengine read micropolis -s drive:0 -o micropolis.img` + +To write: + + - `fluxengine write micropolis -d drive:0 -i micropolis.img` + +## References + + - [Micropolis 1040/1050 S-100 Floppy Disk Subsystems User's Manual][micropolis1040/1050]. + Section 6, pages 261-266. Documents pre-ECC sector format. Note that the + entire record, starting at the sync byte, is controlled by software + + - [Vector Graphic Dual-Mode Disk Controller Board Engineering Documentation][vectordualmode]. + Section 1.6.2. Documents ECC sector format + + - [AltairZ80 Simulator Usage Manual][altairz80]. Section 10.6. Documents ECC + sector format and VGI file format + +[micropolis1040/1050]: http://www.bitsavers.org/pdf/micropolis/metafloppy/1084-01_1040_1050_Users_Manual_Apr79.pdf +[vectordualmode]: http://bitsavers.org/pdf/vectorGraphic/hardware/7200-1200-02-1_Dual-Mode_Disk_Controller_Board_Engineering_Documentation_Feb81.pdf +[altairz80]: http://www.bitsavers.org/simh.trailing-edge.com_201206/pdf/altairz80_doc.pdf + diff --git a/doc/disk-ms2000.md b/doc/disk-ms2000.md index f5ce0ddbc..71f144e99 100644 --- a/doc/disk-ms2000.md +++ b/doc/disk-ms2000.md @@ -1,2 +1,33 @@ --d -\r +ms2000 +==== +## MS2000 Microdisk Development System + + +The RCA MicroDisk Development System MS2000 is a highly obscure (i.e. I gather +that single digit numbers of original machines exist) development system for the +RCA1802 series of CPUs, as made famous by the Cosmac ELF. It was a fairly +straightforward big bag o'RAM system with a 2kB boot ROM, 62kB of RAM, twin +floppy drives and a serial terminal --- CP/M users will find it very familiar. + +Read and writing disks is currently not supported by FluxEngine, but there is +basic support for the MicroDisk operating system's file system. This should +allow files to be read from MS2000 disk images. + +The disks are normal DD 3.5" disks, using a 70-track, single sided variation of +the venerable IBM floppy disk scheme, so allowing 315kB of storage per disk. + +If you have access to flux files for MS2000 disks, please [get in +touch](https://github.com/davidgiven/cpm65/issues/new) --- I would like to add +better support for these. + +## Options + +(no options) + +## Examples + +## References + + - [The EMMA-02 emulator](https://www.emma02.hobby-site.com/ms2000.html), which + supports the MS2000 and provides information on it. + diff --git a/doc/disk-mx.md b/doc/disk-mx.md index f5ce0ddbc..0e3102e9d 100644 --- a/doc/disk-mx.md +++ b/doc/disk-mx.md @@ -1,2 +1,69 @@ --d -\r +mx +==== +## Soviet-era PDP-11 clone + + +The DVK (in Russian, 沾7d65 +Computing Complex) was a late 1970s Soviet personal computer, a cut-down +version of the professional SM EVM (ⵁ241c +--- literally System of Mini Computers), which _itself_ was an unlicensed +clone of the PDP-11. The MX board was an early floppy drive controller board +for it. + +
+A DVK computer +
+ +The MX format is interesting in that it has to be read a track at a time. The +format contains the usual ID prologue at the beginning of the track, then +eleven data blocks and checksums, then the epilogue, then it stops. The +actual encoding is normal FM. There were four different disk variants, in all +combinations of single- and double-sided and 40- and 80-tracked; but every +track contained eleven 256-byte sectors. + +The format varies subtly depending on whether you're using the 'new' driver +or the 'old' driver. FluxEngine should read both. + +A track is: + + * 8 x 0x0000 words (FM encoded as 01010101...) + * 1 x 0x00F3 --- start of track + * 1 x 0xnnnn --- track number + * 11 of: + * 128 words (256 bytes) of data + * 16 bit checksum + * **if 'new' format:** + * 3 x 0x83nn --- `n = (track_number<<1) + side_number` + * **if 'old' format:** + * 3 x 0x8301 + +The checksum is just the unsigned integer sum of all the words in the sector. +Words are all stored little-endian. + +## Options + + - Format variants: + - `110`: 110kB 5.25" 40-track SSSD + - `220ds`: 220kB 5.25" 40-track DSSD + - `220ss`: 220kB 5.25" 80-track SSSD + - `440`: 440kB 5.25" 80-track DSSD + +## Examples + +To read: + + - `fluxengine read mx --110 -s drive:0 -o mx.img` + - `fluxengine read mx --220ds -s drive:0 -o mx.img` + - `fluxengine read mx --220ss -s drive:0 -o mx.img` + - `fluxengine read mx --440 -s drive:0 -o mx.img` + +## References + + - [The Soviet Digital Electronics + Museum](http://www.leningrad.su/museum/main.php) (source of the image + above) + + - [a random post on the HxC2001 support + forum](http://torlus.com/floppy/forum/viewtopic.php?t=1384) with lots of + information on the format + diff --git a/doc/disk-n88basic.md b/doc/disk-n88basic.md index f5ce0ddbc..749b256c7 100644 --- a/doc/disk-n88basic.md +++ b/doc/disk-n88basic.md @@ -1,2 +1,26 @@ --d -\r +n88basic +==== +## PC8800/PC98 5.25" 77-track 26-sector DSHD + + +The N88-BASIC disk format is the one used by the operating system of the same +name for the Japanese PC8800 and PC98 computers. It is another IBM scheme +variant, and is very similar to some mixed-format CP/M disk formats, where +track 0 side 0 uses 128-byte single density sectors and the rest of the disk +uses 512-byte double density sectors. (The reason for this is that the PC8800 +boot ROM could only read single density data.) + +## Options + +(no options) + +## Examples + +To read: + + - `fluxengine read n88basic -s drive:0 -o n88basic.img` + +To write: + + - `fluxengine write n88basic -d drive:0 -i n88basic.img` + diff --git a/doc/disk-northstar.md b/doc/disk-northstar.md index f5ce0ddbc..263865748 100644 --- a/doc/disk-northstar.md +++ b/doc/disk-northstar.md @@ -1,2 +1,50 @@ --d -\r +northstar +==== +## 5.25" hard sectored + + +Northstar Floppy disks use 10-sector hard sectored disks with either FM or MFM +encoding. They may be single- or double-sided. Each of the 10 sectors contains +256 (FM) or 512 (MFM) bytes of data. The disk has 35 cylinders, with tracks 0- +34 on side 0, and tracks 35-69 on side 1. Tracks on side 1 are numbered "back- +wards" in that track 35 corresponds to cylinder 34, side 1, and track 69 +corresponds to cylinder 0, side 1. + +The Northstar sector format does not include any head positioning information. +As such, reads from Northstar floppies need to by synchronized with the index +pulse, in order to properly identify the sector being read. This is handled +automatically by FluxEngine. + +Due to the nature of the track ordering on side 1, an .nsi image reader and +writer are provided for double-sided disks. The .nsi image writer supports +both single- and double-sided disks; however single-sided .nsi images are +equivalent to .img images. + +## Options + + - Format variants: + - `87`: 87.5kB 5.25" 35-track SSSD hard-sectored + - `175`: 175kB 5.25" 40-track SSDD hard-sectored + - `350`: 350kB 5.25" 40-track DSDD hard-sectored + +## Examples + +To read: + + - `fluxengine read northstar --87 -s drive:0 -o northstar.nsi` + - `fluxengine read northstar --175 -s drive:0 -o northstar.nsi` + - `fluxengine read northstar --350 -s drive:0 -o northstar.nsi` + +To write: + + - `fluxengine write northstar --87 -d drive:0 -i northstar.nsi` + - `fluxengine write northstar --175 -d drive:0 -i northstar.nsi` + - `fluxengine write northstar --350 -d drive:0 -i northstar.nsi` + +## References + + - [MICRO-DISK SYSTEM MDS-A-D DOUBLE DENSITY Manual][northstar_mds]. + Page 33 documents sector format for single- and double-density. + +[northstar_mds]: http://bitsavers.org/pdf/northstar/boards/Northstar_MDS-A-D_1978.pdf + diff --git a/doc/disk-psos.md b/doc/disk-psos.md index f5ce0ddbc..27df02243 100644 --- a/doc/disk-psos.md +++ b/doc/disk-psos.md @@ -1,2 +1,32 @@ --d -\r +psos +==== +## 800kB DSDD with PHILE + + +pSOS was an influential real-time operating system from the 1980s, used mainly +on 68000-based machines, lasting up until about 2000 when it was bought (and +cancelled) by Wind River. It had its own floppy disk format and file system, +both of which are partially supported here. + +The PHILE file system is almost completely undocumented and so many of the data +structures have had to be reverse engineered and are not well known. Please +[get in touch](https://github.com/davidgiven/fluxengine/issues/new) if you know +anything about it. + +The floppy disk format itself is an IBM scheme variation with 1024-byte sectors +and, oddly, swapped sides. + +## Options + +(no options) + +## Examples + +To read: + + - `fluxengine read psos -s drive:0 -o pme.img` + +To write: + + - `fluxengine write psos -d drive:0 -i pme.img` + diff --git a/doc/disk-rolandd20.md b/doc/disk-rolandd20.md index f5ce0ddbc..92eaa1dcb 100644 --- a/doc/disk-rolandd20.md +++ b/doc/disk-rolandd20.md @@ -1,2 +1,48 @@ --d -\r +rolandd20 +==== +## 3.5" electronic synthesiser disks + + +The Roland D20 is a classic electronic synthesiser with a built-in floppy +drive, used for saving MIDI sequences and samples. + +Weirdly, it seems to use precisely the same format as the Brother word +processors: a thoroughly non-IBM-compatible custom GCR system. + +FluxEngine supports both reading and writing D20 disks, as well as basic support +for the filesystem, allowing files to be read from and written to D20 disks. +Note that the D20 was never intended to support arbitrary files on its disks and +is very likely to crash if you put unexpected files on a disk. In addition, +while the file format itself is currently unknown, there is a header at the top +of the file containing what appears to be the name shown in the D20 file +browser, so the name by which you see it is not necessarily the filename. + +A word of warning --- just like the Brother word processors, the D20 floppy +drive isn't very well aligned. The drive itself uses quarter-stepping to +automatically adapt to whatever alignment the disk was formatted with. This +means that trying to read such a disk on a PC drive, which does _not_ have +adjustable alignment, may not work very well. In these situations it is possible +to adjust the alignment of most modern drives, but this is a somewhat risky +process and may result in permanently wrecking the drive alignment. + +Please [get in touch](https://github.com/davidgiven/fluxengine/issues/new) if +you know anything about it. + +Many thanks to trondl [on the VCF +forums](https://forum.vcfed.org/index.php?threads/roland-d-20-decoding-the-mysterious-floppy-format.1243226/) +for assistance with this! + +## Options + +(no options) + +## Examples + +To read: + + - `fluxengine read rolandd20 -s drive:0 -o rolandd20.img` + +To write: + + - `fluxengine write rolandd20 -d drive:0 -i rolandd20.img` + diff --git a/doc/disk-rx50.md b/doc/disk-rx50.md index f5ce0ddbc..d39a5ca21 100644 --- a/doc/disk-rx50.md +++ b/doc/disk-rx50.md @@ -1,2 +1,23 @@ --d -\r +rx50 +==== +## 400kB 5.25" 80-track 10-sector SSDD + + +The Digital RX50 is one of the external floppy drive units used by Digital's +range of computers, especially the DEC Rainbow microcomputer. It is a fairly +vanilla single-sided IBM scheme variation. + +## Options + +(no options) + +## Examples + +To read: + + - `fluxengine read rx50 -s drive:0 -o rx50.img` + +To write: + + - `fluxengine write rx50 -d drive:0 -i rx50.img` + diff --git a/doc/disk-shugart_drive.md b/doc/disk-shugart_drive.md index f5ce0ddbc..086e1d39e 100644 --- a/doc/disk-shugart_drive.md +++ b/doc/disk-shugart_drive.md @@ -1,2 +1,15 @@ --d -\r +shugart_drive +==== +## Adjust configuration for a Shugart drive + + +This is an extension profile; adding this to the command line will configure +FluxEngine to adjust the pinout to work with a Shugart drive. This only works +on Greaseweazle hardware. + +For example: + +``` +fluxengine read ibm --720 shugart_drive +``` + diff --git a/doc/disk-smaky6.md b/doc/disk-smaky6.md index f5ce0ddbc..03dec9f8b 100644 --- a/doc/disk-smaky6.md +++ b/doc/disk-smaky6.md @@ -1,2 +1,34 @@ --d -\r +smaky6 +==== +## 308kB 5.25" 77-track 16-sector SSDD, hard sectored + + +The Smaky 6 is a Swiss computer from 1978 produced by Epsitec. It's based +around a Z80 processor and has one or two Micropolis 5.25" drives which use +16-sector hard sectored disks. The disk format is single-sided with 77 tracks +and 256-byte sectors, resulting in 308kB disks. It uses MFM with a custom +sector record scheme. It was later superceded by a 68000-based Smaky which used +different disks. + +FluxEngine supports these, although because the Micropolis drives use a 100tpi +track pitch, you can't read Smaky 6 disks with a normal PC 96tpi drive. You +will have to find a 100tpi drive from somewhere (they're rare). + +There is experimental read-only support for the Smaky 6 filesystem, allowing +the directory to be listed and files read from disks. It's not known whether +this is completely correct, so don't trust it! + +## Options + +(no options) + +## Examples + +To read: + + - `fluxengine read smaky6 -s drive:0 -o smaky6.img` + +## References + + - [Smaky Info, 1978-2002 (in French)](https://www.smaky.ch/theme.php?id=sminfo) + diff --git a/doc/disk-tartu.md b/doc/disk-tartu.md index f5ce0ddbc..4831d4dbb 100644 --- a/doc/disk-tartu.md +++ b/doc/disk-tartu.md @@ -1,2 +1,48 @@ --d -\r +tartu +==== +## The Palivere and variations + + +The Tartu Palivere is a 1988 Z80-based computer from Estonia. It is a CP/M +machine with 64kB of RAM, running off a 2MHz ꃣ0e30 +clone; it operated off punched tape, cassette, external hard drive or floppy, and was notable as being the first ever computer with an Estonian keyboard. + +
+The Tartu computer's developer Leo Humal working with one. +
+ +From a floppy disk perspective, it is interesting because the floppy drive +interface is almost entirely handled in software --- necessary at the time as +the usual floppy disk interface chip at the time, the ⎲fba5 +of the WD1793), was hard to find. Instead, the floppy controller board was +implemented entirely using TTL logic. Despite this, the encoding is fairly high +density, using MFM and with up to 780kB on a double-sided 80 track disk. + +
+The Tartu FDC with Soviet TTL logic chips. +
+ +FluxEngine supports reading and writing Tartu disks with CP/M filesystem access. + +## Options + + - Format variants: + - `390`: 390kB 5.25" 40-track DSDD + - `780`: 780kB 5.25" 80-track DSDD + +## Examples + +To read: + + - `fluxengine read tartu --390 -s drive:0 -o tartu.img` + - `fluxengine read tartu --780 -s drive:0 -o tartu.img` + +To write: + + - `fluxengine write tartu --390 -d drive:0 -i tartu.img` + - `fluxengine write tartu --780 -d drive:0 -i tartu.img` + +## References + + - [The Estonia Museum of Electronics](https://www.elektroonikamuuseum.ee/tartu_arvuti_lugu.html) + diff --git a/doc/disk-tids990.md b/doc/disk-tids990.md index f5ce0ddbc..e25dea485 100644 --- a/doc/disk-tids990.md +++ b/doc/disk-tids990.md @@ -1,2 +1,39 @@ --d -\r +tids990 +==== +## 1126kB 8" DSSD + + +The Texas Instruments DS990 was a multiuser modular computing system from 1998, +based around the TMS-9900 processor (as used by the TI-99). It had an 8" floppy +drive module, the FD1000, which was a 77-track, 288-byte sector FM/MFM system +with 26 sectors per track. The encoding scheme was very similar to a simplified +version of the IBM scheme, but of course not compatible. A double-sided disk +would store a very satisfactory 1126kB of data; here's one at old-computers.com: + +
+ +A DS990 at old-computers.com +
+ +FluxEngine will read and write these (but only the DSDD MFM variant). + +## Options + +(no options) + +## Examples + +To read: + + - `fluxengine read tids990 -s drive:0 -o tids990.img` + +To write: + + - `fluxengine write tids990 -d drive:0 -i tids990.img` + +## References + + - [The FD1000 Depot Maintenance + Manual](http://www.bitsavers.org/pdf/ti/990/disk/2261885-9701_FD1000depotVo1_Jan81.pdf) + diff --git a/doc/disk-tiki.md b/doc/disk-tiki.md index f5ce0ddbc..bcf4cf894 100644 --- a/doc/disk-tiki.md +++ b/doc/disk-tiki.md @@ -1,2 +1,27 @@ --d -\r +tiki +==== +## CP/M + + +The Tiki 100 is a Z80-based Norwegian microcomputer from the mid 1980s intended +for eductional use. It mostly ran an unbranded CP/M clone, and uses fairly +normal CP/M disks --- IBM scheme and from 128 to 512 bytes per sector depending +on the precise format. + +## Options + + - Format variants: + - `90`: 90kB 40-track 18-sector SSSD + - `200`: 200kB 40-track 10-sector SSDD + - `400`: 400kB 40-track 10-sector DSDD + - `800`: 800kB 80-track 10-sector DSDD + +## Examples + +To read: + + - `fluxengine read tiki --90 -s drive:0 -o tiki.img` + - `fluxengine read tiki --200 -s drive:0 -o tiki.img` + - `fluxengine read tiki --400 -s drive:0 -o tiki.img` + - `fluxengine read tiki --800 -s drive:0 -o tiki.img` + diff --git a/doc/disk-victor9k.md b/doc/disk-victor9k.md index f5ce0ddbc..82e698145 100644 --- a/doc/disk-victor9k.md +++ b/doc/disk-victor9k.md @@ -1,2 +1,62 @@ --d -\r +victor9k +==== +## 1224kB 5.25" DSDD GCR + + +The Victor 9000 / Sirius One was a rather strange old 8086-based machine +which used a disk format very reminiscent of the Commodore format; not a +coincidence, as Chuck Peddle designed them both. They're 80-track, 512-byte +sector GCR disks, with a variable-speed drive and a varying number of sectors +per track --- from 19 to 12. Disks can be double-sided, meaning that they can +store 1224kB per disk, which was almost unheard of back then. Because the way +that the tracks on head 1 are offset from head 0 (this happens with all disks), +the speed zone allocation on head 1 differs from head 0... + +| Zone | Head 0 tracks | Head 1 tracks | Sectors | Original period (ms) | +|:----:|:-------------:|:-------------:|:-------:|:--------------------:| +| 0 | 0-3 | | 19 | 237.9 | +| 1 | 4-15 | 0-7 | 18 | 224.5 | +| 2 | 16-26 | 8-18 | 17 | 212.2 | +| 3 | 27-37 | 19-29 | 16 | 199.9 | +| 4 | 38-47\* | 30-39\* | 15 | 187.6 | +| 5 | 48-59 | 40-51 | 14 | 175.3 | +| 6 | 60-70 | 52-62 | 13 | 163.0 | +| 7 | 71-79 | 63-74 | 12 | 149.6 | +| 8 | | 75-79 | 11 | 144.0 | + +(The Original Period column is the original rotation rate. When used in +FluxEngine, the disk always spins at 360 rpm, which corresponds to a rotational +period of 166 ms.) + +\*The Victor 9000 Hardware Reference Manual has a bug in the documentation +and lists Zone 4 as ending with track 48 on head 0 and track 40 on head 1. +The above table matches observed data on various disks and the assembly +code in the boot loader, which ends Zone 4 with track 47 on head 0 +and track 39 on Head 1. + +FluxEngine can read and write both the single-sided and double-sided variants. + +## Options + + - Format variants: + - `612`: 612kB 80-track DSHD GCR + - `1224`: 1224kB 80-track DSHD GCR + +## Examples + +To read: + + - `fluxengine read victor9k --612 -s drive:0 -o victor9k.img` + - `fluxengine read victor9k --1224 -s drive:0 -o victor9k.img` + +To write: + + - `fluxengine write victor9k --612 -d drive:0 -i victor9k.img` + - `fluxengine write victor9k --1224 -d drive:0 -i victor9k.img` + +## References + + - [The Victor 9000 technical reference manual](http://bitsavers.org/pdf/victor/victor9000/Victor9000TechRef_Jun82.pdf) + + - [DiskFerret's Victor 9000 format guide](https://discferret.com/wiki/Victor_9000_format) + diff --git a/doc/disk-zilogmcz.md b/doc/disk-zilogmcz.md index f5ce0ddbc..7d2cb2182 100644 --- a/doc/disk-zilogmcz.md +++ b/doc/disk-zilogmcz.md @@ -1,2 +1,42 @@ --d -\r +zilogmcz +==== +## 320kB 8" 77-track SSSD hard-sectored + + +The Zilog MCZ is an extremely early Z80 development system, produced by +Zilog, which came out in 1976. It used twin 8-inch hard sectored floppy +drives; here's one at the Centre +for Computing History: + +
+ +A Zilog MCZ at the Centre For Computing History +
+ +The MCZ ran Zilog's own operating system, Z80-RIO, and used 77 track +single-sided disks, with 32 sectors (each marked by an index hole), with 132 +bytes per sector --- 128 bytes of user payload plus two two-byte metadata +words used to construct linked lists of sectors for storing files. These +stored 320kB each. + +FluxEngine has read support for these, including support for RIO's ZDOS file +system. + +## Options + +(no options) + +## Examples + +To read: + + - `fluxengine read zilogmcz -s drive:0 -o zilogmcz.img` + +## References + + * [About the Zilog MCZ](http://www.retrotechnology.com/restore/zilog.html), + containing lots of useful links + + * [The hardware user's manual](https://amaus.org/static/S100/zilog/ZDS/Zilog%20ZDS%201-25%20Hardware%20Users%20Manual.pdf) + From 4c140b1b905c1ea44f32713c032bc1ecd1a24647 Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 16 Oct 2024 21:17:59 +0200 Subject: [PATCH 08/12] Modularise arch. --- arch/build.py | 72 ++++++++++++++++++++++++++++++++++++++++++++++++ build.py | 62 ----------------------------------------- build/c.py | 8 +++--- lib/vfs/build.py | 1 + src/build.py | 1 + src/gui/build.py | 1 + tests/build.py | 3 +- 7 files changed, 81 insertions(+), 67 deletions(-) diff --git a/arch/build.py b/arch/build.py index b2ee3e80f..f6ed5a7ff 100644 --- a/arch/build.py +++ b/arch/build.py @@ -28,3 +28,75 @@ ) protocc(name="proto_lib", srcs=[".+proto"], deps=["lib+common_proto_lib"]) + +cxxlibrary( + name="arch", + srcs=[ + "./arch.cc", + "./aeslanier/decoder.cc", + "./agat/agat.cc", + "./agat/decoder.cc", + "./agat/encoder.cc", + "./amiga/amiga.cc", + "./amiga/decoder.cc", + "./amiga/encoder.cc", + "./apple2/decoder.cc", + "./apple2/encoder.cc", + "./brother/decoder.cc", + "./brother/encoder.cc", + "./c64/c64.cc", + "./c64/decoder.cc", + "./c64/encoder.cc", + "./f85/decoder.cc", + "./fb100/decoder.cc", + "./ibm/decoder.cc", + "./ibm/encoder.cc", + "./macintosh/decoder.cc", + "./macintosh/encoder.cc", + "./micropolis/decoder.cc", + "./micropolis/encoder.cc", + "./mx/decoder.cc", + "./northstar/decoder.cc", + "./northstar/encoder.cc", + "./rolandd20/decoder.cc", + "./smaky6/decoder.cc", + "./tartu/decoder.cc", + "./tartu/encoder.cc", + "./tids990/decoder.cc", + "./tids990/encoder.cc", + "./victor9k/decoder.cc", + "./victor9k/encoder.cc", + "./zilogmcz/decoder.cc", + ], + hdrs={ + "arch/ibm/ibm.h": "./ibm/ibm.h", + "arch/apple2/data_gcr.h": "./apple2/data_gcr.h", + "arch/apple2/apple2.h": "./apple2/apple2.h", + "arch/amiga/amiga.h": "./amiga/amiga.h", + "arch/smaky6/smaky6.h": "./smaky6/smaky6.h", + "arch/tids990/tids990.h": "./tids990/tids990.h", + "arch/zilogmcz/zilogmcz.h": "./zilogmcz/zilogmcz.h", + "arch/amiga/amiga.h": "./amiga/amiga.h", + "arch/f85/data_gcr.h": "./f85/data_gcr.h", + "arch/f85/f85.h": "./f85/f85.h", + "arch/mx/mx.h": "./mx/mx.h", + "arch/aeslanier/aeslanier.h": "./aeslanier/aeslanier.h", + "arch/northstar/northstar.h": "./northstar/northstar.h", + "arch/brother/data_gcr.h": "./brother/data_gcr.h", + "arch/brother/brother.h": "./brother/brother.h", + "arch/brother/header_gcr.h": "./brother/header_gcr.h", + "arch/macintosh/data_gcr.h": "./macintosh/data_gcr.h", + "arch/macintosh/macintosh.h": "./macintosh/macintosh.h", + "arch/agat/agat.h": "./agat/agat.h", + "arch/fb100/fb100.h": "./fb100/fb100.h", + "arch/victor9k/data_gcr.h": "./victor9k/data_gcr.h", + "arch/victor9k/victor9k.h": "./victor9k/victor9k.h", + "arch/rolandd20/rolandd20.h": "./rolandd20/rolandd20.h", + "arch/micropolis/micropolis.h": "./micropolis/micropolis.h", + "arch/c64/data_gcr.h": "./c64/data_gcr.h", + "arch/c64/c64.h": "./c64/c64.h", + "arch/tartu/tartu.h": "./tartu/tartu.h", + "arch/arch.h": "./arch.h", + }, + deps=["+lib"], +) diff --git a/build.py b/build.py index e7d72341e..0144c3c5b 100644 --- a/build.py +++ b/build.py @@ -27,70 +27,8 @@ "./lib/decoders/fmmfm.cc", "./lib/encoders/encoders.cc", "./lib/readerwriter.cc", - "./arch/arch.cc", - "./arch/aeslanier/decoder.cc", - "./arch/agat/agat.cc", - "./arch/agat/decoder.cc", - "./arch/agat/encoder.cc", - "./arch/amiga/amiga.cc", - "./arch/amiga/decoder.cc", - "./arch/amiga/encoder.cc", - "./arch/apple2/decoder.cc", - "./arch/apple2/encoder.cc", - "./arch/brother/decoder.cc", - "./arch/brother/encoder.cc", - "./arch/c64/c64.cc", - "./arch/c64/decoder.cc", - "./arch/c64/encoder.cc", - "./arch/f85/decoder.cc", - "./arch/fb100/decoder.cc", - "./arch/ibm/decoder.cc", - "./arch/ibm/encoder.cc", - "./arch/macintosh/decoder.cc", - "./arch/macintosh/encoder.cc", - "./arch/micropolis/decoder.cc", - "./arch/micropolis/encoder.cc", - "./arch/mx/decoder.cc", - "./arch/northstar/decoder.cc", - "./arch/northstar/encoder.cc", - "./arch/rolandd20/decoder.cc", - "./arch/smaky6/decoder.cc", - "./arch/tartu/decoder.cc", - "./arch/tartu/encoder.cc", - "./arch/tids990/decoder.cc", - "./arch/tids990/encoder.cc", - "./arch/victor9k/decoder.cc", - "./arch/victor9k/encoder.cc", - "./arch/zilogmcz/decoder.cc", ], hdrs={ - "arch/ibm/ibm.h": "./arch/ibm/ibm.h", - "arch/apple2/data_gcr.h": "./arch/apple2/data_gcr.h", - "arch/apple2/apple2.h": "./arch/apple2/apple2.h", - "arch/smaky6/smaky6.h": "./arch/smaky6/smaky6.h", - "arch/tids990/tids990.h": "./arch/tids990/tids990.h", - "arch/zilogmcz/zilogmcz.h": "./arch/zilogmcz/zilogmcz.h", - "arch/amiga/amiga.h": "./arch/amiga/amiga.h", - "arch/f85/data_gcr.h": "./arch/f85/data_gcr.h", - "arch/f85/f85.h": "./arch/f85/f85.h", - "arch/mx/mx.h": "./arch/mx/mx.h", - "arch/aeslanier/aeslanier.h": "./arch/aeslanier/aeslanier.h", - "arch/northstar/northstar.h": "./arch/northstar/northstar.h", - "arch/brother/data_gcr.h": "./arch/brother/data_gcr.h", - "arch/brother/brother.h": "./arch/brother/brother.h", - "arch/brother/header_gcr.h": "./arch/brother/header_gcr.h", - "arch/macintosh/data_gcr.h": "./arch/macintosh/data_gcr.h", - "arch/macintosh/macintosh.h": "./arch/macintosh/macintosh.h", - "arch/agat/agat.h": "./arch/agat/agat.h", - "arch/fb100/fb100.h": "./arch/fb100/fb100.h", - "arch/victor9k/data_gcr.h": "./arch/victor9k/data_gcr.h", - "arch/victor9k/victor9k.h": "./arch/victor9k/victor9k.h", - "arch/rolandd20/rolandd20.h": "./arch/rolandd20/rolandd20.h", - "arch/micropolis/micropolis.h": "./arch/micropolis/micropolis.h", - "arch/c64/data_gcr.h": "./arch/c64/data_gcr.h", - "arch/c64/c64.h": "./arch/c64/c64.h", - "arch/tartu/tartu.h": "./arch/tartu/tartu.h", - "arch/arch.h": "./arch/arch.h", "lib/decoders/decoders.h": "./lib/decoders/decoders.h", "lib/decoders/fluxdecoder.h": "./lib/decoders/fluxdecoder.h", "lib/decoders/rawbits.h": "./lib/decoders/rawbits.h", diff --git a/build/c.py b/build/c.py index 2ef152fcf..85a5cef9c 100644 --- a/build/c.py +++ b/build/c.py @@ -27,8 +27,8 @@ class Toolchain: label = "" cfile = ["$(CC) -c -o {outs[0]} {ins[0]} $(CFLAGS) {cflags}"] cxxfile = ["$(CXX) -c -o {outs[0]} {ins[0]} $(CFLAGS) {cflags}"] - clibrary = ["$(AR) cqs {outs[0]} {ins}"] - cxxlibrary = ["$(AR) cqs {outs[0]} {ins}"] + clibrary = ["rm -f {outs[0]} && $(AR) cqs {outs[0]} {ins}"] + cxxlibrary = ["rm -f {outs[0]} && $(AR) cqs {outs[0]} {ins}"] cprogram = [ "$(CC) -o {outs[0]} $(STARTGROUP) {ins} {ldflags} $(LDFLAGS) $(ENDGROUP)" ] @@ -41,8 +41,8 @@ class HostToolchain: label = "HOST " cfile = ["$(HOSTCC) -c -o {outs[0]} {ins[0]} $(HOSTCFLAGS) {cflags}"] cxxfile = ["$(HOSTCXX) -c -o {outs[0]} {ins[0]} $(HOSTCFLAGS) {cflags}"] - clibrary = ["$(HOSTAR) cqs {outs[0]} {ins}"] - cxxlibrary = ["$(HOSTAR) cqs {outs[0]} {ins}"] + clibrary = ["rm -f {outs[0]} && $(HOSTAR) cqs {outs[0]} {ins}"] + cxxlibrary = ["rm -f {outs[0]} && $(HOSTAR) cqs {outs[0]} {ins}"] cprogram = [ "$(HOSTCC) -o {outs[0]} $(HOSTSTARTGROUP) {ins} {ldflags} $(HOSTLDFLAGS) $(HOSTENDGROUP)" ] diff --git a/lib/vfs/build.py b/lib/vfs/build.py index a4d780683..4398869e6 100644 --- a/lib/vfs/build.py +++ b/lib/vfs/build.py @@ -48,6 +48,7 @@ deps=[ "+lib", "+fmt_lib", + "arch", ".+proto_lib", ], ) diff --git a/src/build.py b/src/build.py index 0756a3918..2d29420ff 100644 --- a/src/build.py +++ b/src/build.py @@ -46,6 +46,7 @@ "lib/data", "lib/external", "lib/vfs", + "arch", "src/formats", ], ) diff --git a/src/gui/build.py b/src/gui/build.py index 1ce1d54f8..1f4e3595e 100644 --- a/src/gui/build.py +++ b/src/gui/build.py @@ -68,6 +68,7 @@ "lib/data", "lib/vfs", "lib/config", + "arch", "src/formats", "src/gui/drivetypes", "+z_lib", diff --git a/tests/build.py b/tests/build.py index 423b554e2..3cf1f533c 100644 --- a/tests/build.py +++ b/tests/build.py @@ -103,7 +103,8 @@ "src/formats", ] + ([".+test_proto_lib"] if n == "options" else []) - + (["lib/vfs"] if n in {"cpmfs", "applesingle", "vfs"} else []), + + (["lib/vfs"] if n in {"cpmfs", "applesingle", "vfs"} else []) + + (["arch"] if n in {"amiga"} else []), ), ) for n in tests From 5eef01377f1e34e8febf1494f20eef08b5a3b341 Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 16 Oct 2024 21:52:53 +0200 Subject: [PATCH 09/12] Modularise decoders. --- arch/arch.cc | 3 ++- build.py | 7 +------ lib/build.py | 4 +++- lib/core/utils.cc | 1 - lib/decoders/build.py | 13 +++++++++++++ lib/decoders/decoders.cc | 2 -- 6 files changed, 19 insertions(+), 11 deletions(-) diff --git a/arch/arch.cc b/arch/arch.cc index e03193f9b..58bc75155 100644 --- a/arch/arch.cc +++ b/arch/arch.cc @@ -30,7 +30,8 @@ std::unique_ptr Arch::createEncoder(Config& config) return createEncoder(config->encoder()); } - std::unique_ptr Arch::createEncoder(const EncoderProto& config){ +std::unique_ptr Arch::createEncoder(const EncoderProto& config) +{ static const std::map(const EncoderProto&)>> encoders = { diff --git a/build.py b/build.py index 0144c3c5b..bb7c0c689 100644 --- a/build.py +++ b/build.py @@ -22,16 +22,10 @@ cxxlibrary( name="lib", srcs=[ - "./lib/decoders/decoders.cc", - "./lib/decoders/fluxdecoder.cc", - "./lib/decoders/fmmfm.cc", "./lib/encoders/encoders.cc", "./lib/readerwriter.cc", ], hdrs={ - "lib/decoders/decoders.h": "./lib/decoders/decoders.h", - "lib/decoders/fluxdecoder.h": "./lib/decoders/fluxdecoder.h", - "lib/decoders/rawbits.h": "./lib/decoders/rawbits.h", "lib/encoders/encoders.h": "./lib/encoders/encoders.h", "lib/readerwriter.h": "./lib/readerwriter.h", }, @@ -52,6 +46,7 @@ "lib/fluxsource", "lib/imagereader", "lib/imagewriter", + "lib/decoders", ], ) diff --git a/lib/build.py b/lib/build.py index f907eb490..0602bd1c7 100644 --- a/lib/build.py +++ b/lib/build.py @@ -2,7 +2,9 @@ proto(name="common_proto", srcs=["./common.proto"]) -protocc(name="common_proto_lib", srcs=[".+common_proto"], deps=["+protobuf_lib"]) +protocc( + name="common_proto_lib", srcs=[".+common_proto"], deps=["+protobuf_lib"] +) proto( name="layout_proto", diff --git a/lib/core/utils.cc b/lib/core/utils.cc index 30c302998..812700e4a 100644 --- a/lib/core/utils.cc +++ b/lib/core/utils.cc @@ -249,4 +249,3 @@ void warning(const std::string msg) { log(msg); } - diff --git a/lib/decoders/build.py b/lib/decoders/build.py index 386248caa..4b5fde664 100644 --- a/lib/decoders/build.py +++ b/lib/decoders/build.py @@ -1,12 +1,25 @@ from build.protobuf import proto, protocc +from build.c import cxxlibrary proto( name="proto", srcs=["./decoders.proto"], deps=["lib+common_proto", "arch+proto", "lib/fluxsink+proto"], ) + protocc( name="proto_lib", srcs=[".+proto"], deps=["lib+common_proto_lib", "arch+proto_lib", "lib/fluxsink+proto_lib"], ) + +cxxlibrary( + name="decoders", + srcs=["./decoders.cc", "./fluxdecoder.cc", "./fmmfm.cc"], + hdrs={ + "lib/decoders/decoders.h": "./decoders.h", + "lib/decoders/fluxdecoder.h": "./fluxdecoder.h", + "lib/decoders/rawbits.h": "./rawbits.h", + }, + deps=["lib/core", "lib/config", "lib/data", ".+proto_lib"], +) diff --git a/lib/decoders/decoders.cc b/lib/decoders/decoders.cc index 905f983be..5f9a43411 100644 --- a/lib/decoders/decoders.cc +++ b/lib/decoders/decoders.cc @@ -3,7 +3,6 @@ #include "lib/data/fluxmap.h" #include "lib/config/config.h" #include "lib/decoders/decoders.h" -#include "lib/encoders/encoders.h" #include "lib/data/fluxmapreader.h" #include "lib/data/flux.h" #include "protocol.h" @@ -14,7 +13,6 @@ #include "lib/data/layout.h" #include - std::shared_ptr Decoder::decodeToSectors( std::shared_ptr fluxmap, std::shared_ptr& trackInfo) From 1bcc8f45b5709cc37d56117657b31c3867a8d055 Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 16 Oct 2024 22:00:51 +0200 Subject: [PATCH 10/12] Modularise encoders. Change arch to not depend on +lib. --- arch/agat/encoder.cc | 2 +- arch/amiga/encoder.cc | 2 +- arch/apple2/encoder.cc | 2 +- arch/brother/encoder.cc | 2 +- arch/build.py | 2 +- arch/c64/encoder.cc | 2 +- arch/ibm/encoder.cc | 1 - arch/macintosh/encoder.cc | 2 +- arch/tids990/encoder.cc | 1 - arch/victor9k/encoder.cc | 2 +- build.py | 3 +-- lib/core/utils.cc | 15 +++++++++++++++ lib/core/utils.h | 5 +++++ lib/encoders/build.py | 9 ++++++++- lib/encoders/encoders.cc | 1 - lib/readerwriter.cc | 15 --------------- lib/readerwriter.h | 5 ----- src/fe-analysedriveresponse.cc | 1 - src/fe-format.cc | 1 - src/fe-getdiskinfo.cc | 1 - src/fe-getfile.cc | 1 - src/fe-getfileinfo.cc | 1 - src/fe-inspect.cc | 1 - src/fe-ls.cc | 1 - 24 files changed, 37 insertions(+), 41 deletions(-) diff --git a/arch/agat/encoder.cc b/arch/agat/encoder.cc index b60d591cf..4ece7bab7 100644 --- a/arch/agat/encoder.cc +++ b/arch/agat/encoder.cc @@ -1,9 +1,9 @@ #include "lib/core/globals.h" +#include "lib/core/utils.h" #include "lib/decoders/decoders.h" #include "lib/encoders/encoders.h" #include "agat.h" #include "lib/core/crc.h" -#include "lib/readerwriter.h" #include "lib/data/image.h" #include "lib/data/layout.h" #include "arch/agat/agat.pb.h" diff --git a/arch/amiga/encoder.cc b/arch/amiga/encoder.cc index bec5d82ee..6a1f5bb1e 100644 --- a/arch/amiga/encoder.cc +++ b/arch/amiga/encoder.cc @@ -1,9 +1,9 @@ #include "lib/core/globals.h" +#include "lib/core/utils.h" #include "lib/decoders/decoders.h" #include "lib/encoders/encoders.h" #include "amiga.h" #include "lib/core/crc.h" -#include "lib/readerwriter.h" #include "lib/data/image.h" #include "arch/amiga/amiga.pb.h" #include "lib/encoders/encoders.pb.h" diff --git a/arch/apple2/encoder.cc b/arch/apple2/encoder.cc index 089f528ed..243559392 100644 --- a/arch/apple2/encoder.cc +++ b/arch/apple2/encoder.cc @@ -1,9 +1,9 @@ #include "lib/core/globals.h" +#include "lib/core/utils.h" #include "arch/apple2/apple2.h" #include "lib/decoders/decoders.h" #include "lib/encoders/encoders.h" #include "lib/data/sector.h" -#include "lib/readerwriter.h" #include "lib/data/image.h" #include "fmt/format.h" #include "lib/encoders/encoders.pb.h" diff --git a/arch/brother/encoder.cc b/arch/brother/encoder.cc index 188a27f64..f41cf98aa 100644 --- a/arch/brother/encoder.cc +++ b/arch/brother/encoder.cc @@ -1,9 +1,9 @@ #include "lib/core/globals.h" +#include "lib/core/utils.h" #include "lib/decoders/decoders.h" #include "lib/encoders/encoders.h" #include "brother.h" #include "lib/core/crc.h" -#include "lib/readerwriter.h" #include "lib/data/image.h" #include "arch/brother/brother.pb.h" #include "lib/encoders/encoders.pb.h" diff --git a/arch/build.py b/arch/build.py index f6ed5a7ff..4fa9c2f9b 100644 --- a/arch/build.py +++ b/arch/build.py @@ -98,5 +98,5 @@ "arch/tartu/tartu.h": "./tartu/tartu.h", "arch/arch.h": "./arch.h", }, - deps=["+lib"], + deps=["lib/core", "lib/data", "lib/config", "lib/encoders", "lib/decoders"], ) diff --git a/arch/c64/encoder.cc b/arch/c64/encoder.cc index ae0c04698..0bf45e0bc 100644 --- a/arch/c64/encoder.cc +++ b/arch/c64/encoder.cc @@ -1,10 +1,10 @@ #include "lib/core/globals.h" +#include "lib/core/utils.h" #include "lib/decoders/decoders.h" #include "lib/encoders/encoders.h" #include "c64.h" #include "lib/core/crc.h" #include "lib/data/sector.h" -#include "lib/readerwriter.h" #include "lib/data/image.h" #include "fmt/format.h" #include "arch/c64/c64.pb.h" diff --git a/arch/ibm/encoder.cc b/arch/ibm/encoder.cc index 2ad9c6445..25c3496a1 100644 --- a/arch/ibm/encoder.cc +++ b/arch/ibm/encoder.cc @@ -4,7 +4,6 @@ #include "lib/encoders/encoders.h" #include "ibm.h" #include "lib/core/crc.h" -#include "lib/readerwriter.h" #include "lib/data/image.h" #include "arch/ibm/ibm.pb.h" #include "lib/encoders/encoders.pb.h" diff --git a/arch/macintosh/encoder.cc b/arch/macintosh/encoder.cc index 50b6e6b7e..75fd59a3a 100644 --- a/arch/macintosh/encoder.cc +++ b/arch/macintosh/encoder.cc @@ -1,9 +1,9 @@ #include "lib/core/globals.h" +#include "lib/core/utils.h" #include "lib/decoders/decoders.h" #include "lib/encoders/encoders.h" #include "macintosh.h" #include "lib/core/crc.h" -#include "lib/readerwriter.h" #include "lib/data/image.h" #include "fmt/format.h" #include "lib/encoders/encoders.pb.h" diff --git a/arch/tids990/encoder.cc b/arch/tids990/encoder.cc index f87d2b8b9..0b78b99dd 100644 --- a/arch/tids990/encoder.cc +++ b/arch/tids990/encoder.cc @@ -3,7 +3,6 @@ #include "lib/encoders/encoders.h" #include "tids990.h" #include "lib/core/crc.h" -#include "lib/readerwriter.h" #include "lib/data/image.h" #include "arch/tids990/tids990.pb.h" #include "lib/encoders/encoders.pb.h" diff --git a/arch/victor9k/encoder.cc b/arch/victor9k/encoder.cc index e5387ac3f..683494c56 100644 --- a/arch/victor9k/encoder.cc +++ b/arch/victor9k/encoder.cc @@ -1,10 +1,10 @@ #include "lib/core/globals.h" +#include "lib/core/utils.h" #include "lib/decoders/decoders.h" #include "lib/encoders/encoders.h" #include "victor9k.h" #include "lib/core/crc.h" #include "lib/data/sector.h" -#include "lib/readerwriter.h" #include "lib/data/image.h" #include "fmt/format.h" #include "arch/victor9k/victor9k.pb.h" diff --git a/build.py b/build.py index bb7c0c689..4d7fcc2c2 100644 --- a/build.py +++ b/build.py @@ -22,11 +22,9 @@ cxxlibrary( name="lib", srcs=[ - "./lib/encoders/encoders.cc", "./lib/readerwriter.cc", ], hdrs={ - "lib/encoders/encoders.h": "./lib/encoders/encoders.h", "lib/readerwriter.h": "./lib/readerwriter.h", }, deps=[ @@ -47,6 +45,7 @@ "lib/imagereader", "lib/imagewriter", "lib/decoders", + "lib/encoders", ], ) diff --git a/lib/core/utils.cc b/lib/core/utils.cc index 812700e4a..a63b1cec4 100644 --- a/lib/core/utils.cc +++ b/lib/core/utils.cc @@ -249,3 +249,18 @@ void warning(const std::string msg) { log(msg); } + +void fillBitmapTo(std::vector& bitmap, + unsigned& cursor, + unsigned terminateAt, + const std::vector& pattern) +{ + while (cursor < terminateAt) + { + for (bool b : pattern) + { + if (cursor < bitmap.size()) + bitmap[cursor++] = b; + } + } +} diff --git a/lib/core/utils.h b/lib/core/utils.h index 89e87a9a9..c5903ee4b 100644 --- a/lib/core/utils.h +++ b/lib/core/utils.h @@ -23,6 +23,11 @@ extern int countSetBits(uint32_t word); extern uint32_t unbcd(uint32_t bcd); extern int findLowestSetBit(uint64_t value); +extern void fillBitmapTo(std::vector& bitmap, + unsigned& cursor, + unsigned terminateAt, + const std::vector& pattern); + template std::map reverseMap(const std::map& map) { diff --git a/lib/encoders/build.py b/lib/encoders/build.py index 7972f9f67..fe7a8ba4f 100644 --- a/lib/encoders/build.py +++ b/lib/encoders/build.py @@ -1,5 +1,5 @@ from build.protobuf import proto, protocc - +from build.c import cxxlibrary proto( name="proto", @@ -11,3 +11,10 @@ srcs=[".+proto"], deps=["lib+common_proto_lib", "arch+proto_lib"], ) + +cxxlibrary( + name="encoders", + srcs=["./encoders.cc"], + hdrs={"lib/encoders/encoders.h": "./encoders.h"}, + deps=["lib/core", "lib/data", "lib/config", ".+proto_lib"], +) diff --git a/lib/encoders/encoders.cc b/lib/encoders/encoders.cc index 11d776b20..dd51e723f 100644 --- a/lib/encoders/encoders.cc +++ b/lib/encoders/encoders.cc @@ -1,7 +1,6 @@ #include "lib/core/globals.h" #include "lib/config/config.h" #include "lib/data/fluxmap.h" -#include "lib/decoders/decoders.h" #include "lib/encoders/encoders.h" #include "lib/encoders/encoders.pb.h" #include "lib/config/proto.h" diff --git a/lib/readerwriter.cc b/lib/readerwriter.cc index a85aaea71..fc0bf839f 100644 --- a/lib/readerwriter.cc +++ b/lib/readerwriter.cc @@ -768,18 +768,3 @@ void rawReadDiskCommand(FluxSource& fluxsource, FluxSink& fluxsink) log(EndOperationLogMessage{"Raw read complete"}); } - -void fillBitmapTo(std::vector& bitmap, - unsigned& cursor, - unsigned terminateAt, - const std::vector& pattern) -{ - while (cursor < terminateAt) - { - for (bool b : pattern) - { - if (cursor < bitmap.size()) - bitmap[cursor++] = b; - } - } -} diff --git a/lib/readerwriter.h b/lib/readerwriter.h index 8295e740f..3a2341e29 100644 --- a/lib/readerwriter.h +++ b/lib/readerwriter.h @@ -86,11 +86,6 @@ extern void writeTracksAndVerify(FluxSink& fluxSink, const Image& image, std::vector>& locations); -extern void fillBitmapTo(std::vector& bitmap, - unsigned& cursor, - unsigned terminateAt, - const std::vector& pattern); - extern void writeDiskCommand(const Image& image, Encoder& encoder, FluxSink& fluxSink, diff --git a/src/fe-analysedriveresponse.cc b/src/fe-analysedriveresponse.cc index 218af90d9..52bfc14e5 100644 --- a/src/fe-analysedriveresponse.cc +++ b/src/fe-analysedriveresponse.cc @@ -5,7 +5,6 @@ #include "lib/core/bitmap.h" #include "lib/data/fluxmap.h" #include "lib/data/fluxmapreader.h" -#include "lib/readerwriter.h" #include "protocol.h" #include "lib/config/proto.h" #include "lib/fluxsink/fluxsink.h" diff --git a/src/fe-format.cc b/src/fe-format.cc index c8440a08d..1552c035e 100644 --- a/src/fe-format.cc +++ b/src/fe-format.cc @@ -3,7 +3,6 @@ #include "lib/data/fluxmap.h" #include "lib/data/sector.h" #include "lib/config/proto.h" -#include "lib/readerwriter.h" #include "lib/imagereader/imagereader.h" #include "lib/imagewriter/imagewriter.h" #include "lib/fluxsource/fluxsource.h" diff --git a/src/fe-getdiskinfo.cc b/src/fe-getdiskinfo.cc index 28d890bb4..2dc64b9f0 100644 --- a/src/fe-getdiskinfo.cc +++ b/src/fe-getdiskinfo.cc @@ -3,7 +3,6 @@ #include "lib/data/fluxmap.h" #include "lib/data/sector.h" #include "lib/config/proto.h" -#include "lib/readerwriter.h" #include "lib/imagereader/imagereader.h" #include "lib/imagewriter/imagewriter.h" #include "lib/fluxsource/fluxsource.h" diff --git a/src/fe-getfile.cc b/src/fe-getfile.cc index bc4daf807..2a6ffd10c 100644 --- a/src/fe-getfile.cc +++ b/src/fe-getfile.cc @@ -3,7 +3,6 @@ #include "lib/data/fluxmap.h" #include "lib/data/sector.h" #include "lib/config/proto.h" -#include "lib/readerwriter.h" #include "lib/imagereader/imagereader.h" #include "lib/imagewriter/imagewriter.h" #include "lib/fluxsource/fluxsource.h" diff --git a/src/fe-getfileinfo.cc b/src/fe-getfileinfo.cc index 801f59807..9b764a012 100644 --- a/src/fe-getfileinfo.cc +++ b/src/fe-getfileinfo.cc @@ -3,7 +3,6 @@ #include "lib/data/fluxmap.h" #include "lib/data/sector.h" #include "lib/config/proto.h" -#include "lib/readerwriter.h" #include "lib/imagereader/imagereader.h" #include "lib/imagewriter/imagewriter.h" #include "lib/fluxsource/fluxsource.h" diff --git a/src/fe-inspect.cc b/src/fe-inspect.cc index d024baae2..d66cddc47 100644 --- a/src/fe-inspect.cc +++ b/src/fe-inspect.cc @@ -1,7 +1,6 @@ #include "lib/core/globals.h" #include "lib/config/config.h" #include "lib/config/flags.h" -#include "lib/readerwriter.h" #include "lib/data/fluxmap.h" #include "lib/data/fluxmapreader.h" #include "lib/decoders/fluxdecoder.h" diff --git a/src/fe-ls.cc b/src/fe-ls.cc index 0854cdb9d..25e2a23bd 100644 --- a/src/fe-ls.cc +++ b/src/fe-ls.cc @@ -3,7 +3,6 @@ #include "lib/data/fluxmap.h" #include "lib/data/sector.h" #include "lib/config/proto.h" -#include "lib/readerwriter.h" #include "lib/decoders/decoders.h" #include "lib/fluxsource/fluxsource.h" #include "lib/imagereader/imagereader.h" From 92b5accb90bd579e2857d6666c1ba735442618d3 Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 16 Oct 2024 22:37:47 +0200 Subject: [PATCH 11/12] Tidy rule count. --- build/ab.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/ab.mk b/build/ab.mk index 81057a83c..7dae06d7b 100644 --- a/build/ab.mk +++ b/build/ab.mk @@ -48,7 +48,7 @@ endif EXT ?= ifeq ($(PROGRESSINFO),) -rulecount := $(shell $(MAKE) --no-print-directory -q $(OBJ)/build.mk PROGRESSINFO=1 && $(MAKE) -n $(MAKECMDGOALS) PROGRESSINFO=XXXPROGRESSINFOXXX | grep XXXPROGRESSINFOXXX | wc -l) +rulecount := $(strip $(shell $(MAKE) --no-print-directory -q $(OBJ)/build.mk PROGRESSINFO=1 && $(MAKE) --no-print-directory -n $(MAKECMDGOALS) PROGRESSINFO=XXXPROGRESSINFOXXX | grep XXXPROGRESSINFOXXX | wc -l)) ruleindex := 1 PROGRESSINFO = "[$(ruleindex)/$(rulecount)]$(eval ruleindex := $(shell expr $(ruleindex) + 1))" endif From d096d7742f15b56f371bb4a49523eca2704c392e Mon Sep 17 00:00:00 2001 From: David Given Date: Wed, 16 Oct 2024 22:57:21 +0200 Subject: [PATCH 12/12] Adjust the number of OSX cpus. --- .github/workflows/ccpp.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 9f4b98fe9..2fc8aeaf8 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -42,7 +42,7 @@ jobs: run: | brew install sqlite pkg-config libusb protobuf wxwidgets fmt make coreutils dylibbundler libjpeg - name: make - run: gmake -C fluxengine -j $(nprocs) + run: gmake -C fluxengine -j2 - name: Upload build artifacts uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index a5a332119..374013844 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -97,7 +97,7 @@ jobs: - name: make run: | - gmake -j $(nprocs) + gmake -j2 mv FluxEngine.pkg FluxEngine-${{ runner.arch }}.pkg - name: tag