From 6e0f085b5f9981a38b3eef83abee80f89b70fe0c Mon Sep 17 00:00:00 2001 From: Roman Donchenko Date: Tue, 12 Nov 2024 00:52:47 +0200 Subject: ap2_dsk.cpp: add read-only support for the D13 format (#12956) This is the equivalent of DSK used for 13-sector disks. While `diskiing` cannot directly boot from 13-sector disks, you can still access such disks with it (for example, using the BOOT13 and MUFFIN programs), so list the format as supported by both `diskiing13` and `diskiing`. --- src/devices/bus/a2bus/a2diskiing.cpp | 2 + src/lib/formats/all.cpp | 1 + src/lib/formats/ap2_dsk.cpp | 122 +++++++++++++++++++++++++++++++++++ src/lib/formats/ap2_dsk.h | 19 ++++++ 4 files changed, 144 insertions(+) diff --git a/src/devices/bus/a2bus/a2diskiing.cpp b/src/devices/bus/a2bus/a2diskiing.cpp index bba1144fcda..1d384bbec56 100644 --- a/src/devices/bus/a2bus/a2diskiing.cpp +++ b/src/devices/bus/a2bus/a2diskiing.cpp @@ -64,6 +64,7 @@ ROM_END void diskiing_device::floppy_formats(format_registration &fr) { + fr.add(FLOPPY_A213S_FORMAT); fr.add(FLOPPY_A216S_DOS_FORMAT); fr.add(FLOPPY_A216S_PRODOS_FORMAT); fr.add(FLOPPY_RWTS18_FORMAT); @@ -76,6 +77,7 @@ void diskiing_device::floppy_formats(format_registration &fr) void a2bus_diskiing13_device::floppy_formats(format_registration &fr) { + fr.add(FLOPPY_A213S_FORMAT); fr.add(FLOPPY_EDD_FORMAT); fr.add(FLOPPY_WOZ_FORMAT); fr.add(FLOPPY_NIB_FORMAT); diff --git a/src/lib/formats/all.cpp b/src/lib/formats/all.cpp index c068969db2e..f07a2cd2efb 100644 --- a/src/lib/formats/all.cpp +++ b/src/lib/formats/all.cpp @@ -789,6 +789,7 @@ void mame_formats_full_list(mame_formats_enumerator &en) en.add(fs::PRODOS); #endif #ifdef HAS_FORMATS_AP2_DSK + en.add(FLOPPY_A213S_FORMAT); // ap2_dsk.h en.add(FLOPPY_A216S_DOS_FORMAT); // ap2_dsk.h en.add(FLOPPY_A216S_PRODOS_FORMAT); // ap2_dsk.h en.add(FLOPPY_RWTS18_FORMAT); // ap2_dsk.h diff --git a/src/lib/formats/ap2_dsk.cpp b/src/lib/formats/ap2_dsk.cpp index 92c8b999965..b2b5a60066a 100644 --- a/src/lib/formats/ap2_dsk.cpp +++ b/src/lib/formats/ap2_dsk.cpp @@ -18,6 +18,128 @@ #include #include +static const uint8_t translate5[] = { + 0xab, 0xad, 0xae, 0xaf, 0xb5, 0xb6, 0xb7, 0xba, + 0xbb, 0xbd, 0xbe, 0xbf, 0xd6, 0xd7, 0xda, 0xdb, + 0xdd, 0xde, 0xdf, 0xea, 0xeb, 0xed, 0xee, 0xef, + 0xf5, 0xf6, 0xf7, 0xfa, 0xfb, 0xfd, 0xfe, 0xff, +}; + +a2_13sect_format::a2_13sect_format() : floppy_image_format_t() +{ +} + +int a2_13sect_format::identify(util::random_read &io, uint32_t form_factor, const std::vector &variants) const +{ + uint64_t size; + if (io.length(size)) + return 0; + + if (size != APPLE2_STD_TRACK_COUNT * 13 * 256) + return 0; + + return FIFID_SIZE; +} + +bool a2_13sect_format::load(util::random_read &io, uint32_t form_factor, const std::vector &variants, floppy_image &image) const +{ + uint64_t size; + if (io.length(size)) + return false; + + image.set_form_variant(floppy_image::FF_525, floppy_image::SSSD); + + int tracks = size / 13 / 256; + + for(int track = 0; track < tracks; track++) { + std::vector track_data; + uint8_t sector_data[256 * 13]; + + auto const [err, actual] = read_at( + io, track * sizeof sector_data, sector_data, sizeof sector_data); + if (err || actual != sizeof sector_data) + return false; + + for(int i=0; i<13; i++) { + int sector = (i * 10) % 13; + + // write inter-sector padding + for(int j=0; j<40; j++) + raw_w(track_data, 9, 0x1fe); + raw_w(track_data, 8, 0xff); + + // write sector address + raw_w(track_data, 24, 0xd5aab5); + raw_w(track_data, 16, gcr4_encode(0xfe)); + raw_w(track_data, 16, gcr4_encode(track)); + raw_w(track_data, 16, gcr4_encode(sector)); + raw_w(track_data, 16, gcr4_encode(0xfe ^ track ^ sector)); + raw_w(track_data, 24, 0xdeaaeb); + + // write intra-sector padding + for(int j=0; j<11; j++) + raw_w(track_data, 9, 0x1fe); + + // write sector data + raw_w(track_data, 24, 0xd5aaad); + + uint8_t pval = 0x00; + auto write_data_byte = [&track_data, &pval](uint8_t nval) { + raw_w(track_data, 8, translate5[nval ^ pval]); + pval = nval; + }; + + const uint8_t *sdata = sector_data + 256 * sector; + + // write 154 bytes encoding bits 2-0 + write_data_byte(sdata[255] & 7); + for (int k=2; k>-1; k--) + for (int j=0; j<51; j++) + write_data_byte( + (sdata[j*5+k] & 7) << 2 + | ((sdata[j*5+3] >> (2-k)) & 1) << 1 + | ((sdata[j*5+4] >> (2-k)) & 1)); + + // write 256 bytes encoding bits 7-3 + for (int k=0; k<5; k++) + for (int j=50; j>-1; j--) + write_data_byte(sdata[j*5+k] >> 3); + write_data_byte(sdata[255] >> 3); + + raw_w(track_data, 8, translate5[pval]); + raw_w(track_data, 24, 0xdeaaeb); + raw_w(track_data, 8, 0xff); + } + + generate_track_from_levels(track, 0, track_data, 0, image); + } + + return true; +} + + +const char *a2_13sect_format::name() const noexcept +{ + return "a2_13sect"; +} + +const char *a2_13sect_format::description() const noexcept +{ + return "Apple II 13-sector d13 image"; +} + +const char *a2_13sect_format::extensions() const noexcept +{ + return "d13"; +} + +bool a2_13sect_format::supports_save() const noexcept +{ + return false; +} + +const a2_13sect_format FLOPPY_A213S_FORMAT; + static const uint8_t translate6[0x40] = { 0x96, 0x97, 0x9a, 0x9b, 0x9d, 0x9e, 0x9f, 0xa6, diff --git a/src/lib/formats/ap2_dsk.h b/src/lib/formats/ap2_dsk.h index cbeea73f2d3..c89aa3d9533 100644 --- a/src/lib/formats/ap2_dsk.h +++ b/src/lib/formats/ap2_dsk.h @@ -29,6 +29,25 @@ #define APPLE2_SECTOR_SIZE 256 /**************************************************************************/ +class a2_13sect_format : public floppy_image_format_t +{ +public: + a2_13sect_format(); + + virtual int identify(util::random_read &io, uint32_t form_factor, const std::vector &variants) const override; + virtual bool load(util::random_read &io, uint32_t form_factor, const std::vector &variants, floppy_image &image) const override; + + virtual const char *name() const noexcept override; + virtual const char *description() const noexcept override; + virtual const char *extensions() const noexcept override; + virtual bool supports_save() const noexcept override; + +private: + static uint8_t gb(const std::vector &buf, int &pos, int &wrap); +}; + +extern const a2_13sect_format FLOPPY_A213S_FORMAT; + class a2_16sect_format : public floppy_image_format_t { public: -- cgit v1.2.3