diff --git a/arch/micropolis/decoder.cc b/arch/micropolis/decoder.cc index 7b817caa..116ac6b1 100644 --- a/arch/micropolis/decoder.cc +++ b/arch/micropolis/decoder.cc @@ -6,6 +6,7 @@ #include "micropolis.h" #include "bytes.h" #include "fmt/format.h" +#include "lib/decoders/decoders.pb.h" /* The sector has a preamble of MFM 0x00s and uses 0xFF as a sync pattern. */ static const FluxPattern SECTOR_SYNC_PATTERN(32, 0xaaaa5555); @@ -28,7 +29,8 @@ class MicropolisDecoder : public AbstractDecoder { public: MicropolisDecoder(const DecoderProto& config): - AbstractDecoder(config) + AbstractDecoder(config), + _config(config.micropolis()) {} RecordType advanceToNextRecord() @@ -59,13 +61,21 @@ public: return; br.read(10); /* OS data or padding */ - _sector->data = br.read(256); + auto data = br.read(256); uint8_t wantChecksum = br.read_8(); uint8_t gotChecksum = micropolisChecksum(bytes.slice(1, 2+266)); br.read(5); /* 4 byte ECC and ECC-present flag */ + if (_config.sector_output_size() == 256) + _sector->data = data; + else if (_config.sector_output_size() == MICROPOLIS_ENCODED_SECTOR_SIZE) + _sector->data = bytes; + else + Error() << "Sector output size may only be 256 or 275"; _sector->status = (wantChecksum == gotChecksum) ? Sector::OK : Sector::BAD_CHECKSUM; } +private: + const MicropolisDecoderProto& _config; }; std::unique_ptr createMicropolisDecoder(const DecoderProto& config) diff --git a/arch/micropolis/encoder.cc b/arch/micropolis/encoder.cc index 14b19911..77719222 100644 --- a/arch/micropolis/encoder.cc +++ b/arch/micropolis/encoder.cc @@ -19,7 +19,15 @@ static void write_sector(std::vector& bits, unsigned& cursor, const std::s fullSector->push_back(0); Bytes sectorData; if (sector->data.size() == MICROPOLIS_ENCODED_SECTOR_SIZE) + { + if (sector->data[0] != 0xFF) + Error() << "275 byte sector doesn't start with sync byte 0xFF. Corrupted sector"; + uint8_t wantChecksum = sector->data[1+2+266]; + uint8_t gotChecksum = micropolisChecksum(sector->data.slice(1, 2+266)); + if (wantChecksum != gotChecksum) + std::cerr << "Warning: checksum incorrect. Sector: " << sector->logicalSector << std::endl; sectorData = sector->data; + } else { ByteWriter writer(sectorData); diff --git a/arch/micropolis/micropolis.proto b/arch/micropolis/micropolis.proto index 417a9089..8d383ac2 100644 --- a/arch/micropolis/micropolis.proto +++ b/arch/micropolis/micropolis.proto @@ -1,5 +1,11 @@ syntax = "proto2"; -message MicropolisDecoderProto {} +import "lib/common.proto"; + +message MicropolisDecoderProto { + optional int32 sector_output_size = 1 [default = 256, + (help) = "How much of the raw sector should be saved. Must be 256 or 275"]; +} + message MicropolisEncoderProto {} diff --git a/mkninja.sh b/mkninja.sh index 6725b0d8..1078c501 100644 --- a/mkninja.sh +++ b/mkninja.sh @@ -422,6 +422,7 @@ FORMATS="\ mac400 \ mac800 \ micropolis \ + micropolis275 \ mx \ northstar175 \ northstar350 \ diff --git a/src/formats/micropolis275.textpb b/src/formats/micropolis275.textpb new file mode 100644 index 00000000..d0f7c191 --- /dev/null +++ b/src/formats/micropolis275.textpb @@ -0,0 +1,54 @@ +comment: 'Micropolis MetaFloppy 630kB 5.25" DSDD hard-sectored' + +flux_source { + drive { + hard_sector_count: 16 + } +} + +flux_sink { + drive { + hard_sector_count: 16 + } +} + +image_reader { + filename: "micropolis.img" + img { + tracks: 77 + sides: 2 + trackdata { + sector_size: 275 + sector_range { + start_sector: 0 + sector_count: 16 + } + } + } +} + +image_writer { + filename: "micropolis.img" + img {} +} + +encoder { + micropolis {} +} + +decoder { + micropolis { + sector_output_size: 275 + } +} + +cylinders { + start: 0 + end: 76 +} + +heads { + start: 0 + end: 1 +} +