Non-functional boilerplate of Amiga write support.

This commit is contained in:
David Given
2019-12-01 09:07:43 +01:00
parent 8ee6eed4dc
commit eaa3c57425
5 changed files with 122 additions and 0 deletions

View File

@@ -1,12 +1,17 @@
#ifndef AMIGA_H
#define AMIGA_H
#include "encoders/encoders.h"
#define AMIGA_SECTOR_RECORD 0xaaaa44894489LL
#define AMIGA_TRACKS_PER_DISK 80
#define AMIGA_SECTORS_PER_TRACK 11
#define AMIGA_RECORD_SIZE 0x21f
class Sector;
class Fluxmap;
class SectorSet;
class AmigaDecoder : public AbstractDecoder
{
@@ -17,4 +22,15 @@ public:
void decodeSectorRecord();
};
class AmigaEncoder : public AbstractEncoder
{
public:
virtual ~AmigaEncoder() {}
public:
std::unique_ptr<Fluxmap> encode(int physicalTrack, int physicalSide, const SectorSet& allSectors);
};
extern FlagGroup amigaEncoderFlags;
#endif

79
arch/amiga/encoder.cc Normal file
View File

@@ -0,0 +1,79 @@
#include "globals.h"
#include "record.h"
#include "decoders/decoders.h"
#include "encoders/encoders.h"
#include "amiga.h"
#include "crc.h"
#include "sectorset.h"
#include "writer.h"
FlagGroup amigaEncoderFlags;
static DoubleFlag clockRateUs(
{ "--clock-rate" },
"Encoded data clock rate (microseconds).",
2.00);
static DoubleFlag postIndexGapMs(
{ "--post-index-gap" },
"Post-index gap before first sector header (milliseconds).",
20.0);
static int charToInt(char c)
{
if (isdigit(c))
return c - '0';
return 10 + tolower(c) - 'a';
}
static void write_bits(std::vector<bool>& bits, unsigned& cursor, uint64_t data, int width)
{
cursor += width;
for (int i=0; i<width; i++)
{
unsigned pos = cursor - i - 1;
if (pos < bits.size())
bits[pos] = data & 1;
data >>= 1;
}
}
static void write_sector(std::vector<bool> bits, unsigned& cursor, const Sector* sector)
{
write_bits(bits, cursor, AMIGA_SECTOR_RECORD, 6*8);
Bytes header(4);
ByteWriter bw(header);
bw.write_8(0xff); /* Amiga 1.0 format byte */
bw.write_8(sector->logicalTrack);
bw.write_8(sector->logicalSector);
bw.write_8(AMIGA_SECTORS_PER_TRACK - sector->logicalSector);
}
std::unique_ptr<Fluxmap> AmigaEncoder::encode(
int physicalTrack, int physicalSide, const SectorSet& allSectors)
{
if ((physicalTrack < 0) || (physicalTrack >= AMIGA_TRACKS_PER_DISK))
return std::unique_ptr<Fluxmap>();
int bitsPerRevolution = 200000.0 / clockRateUs;
std::vector<bool> bits(bitsPerRevolution);
unsigned cursor = 0;
fillBitmapTo(bits, cursor, postIndexGapMs * 1000 / clockRateUs, { true, false });
for (int sectorId=0; sectorId<AMIGA_SECTORS_PER_TRACK; sectorId++)
{
const auto& sectorData = allSectors.get(physicalTrack, 0, sectorId);
write_sector(bits, cursor, sectorData);
}
if (cursor > bits.size())
Error() << "track data overrun";
fillBitmapTo(bits, cursor, bits.size(), { true, false });
std::unique_ptr<Fluxmap> fluxmap(new Fluxmap);
fluxmap->appendBits(bits, clockRateUs*1e3);
return fluxmap;
}

View File

@@ -145,6 +145,7 @@ buildlibrary libbackend.a \
lib/imagewriter/ldbsimagewriter.cc \
arch/aeslanier/decoder.cc \
arch/amiga/decoder.cc \
arch/amiga/encoder.cc \
arch/apple2/decoder.cc \
arch/brother/decoder.cc \
arch/brother/encoder.cc \
@@ -213,6 +214,7 @@ buildlibrary libfrontend.a \
src/fe-seek.cc \
src/fe-testbulktransport.cc \
src/fe-upgradefluxfile.cc \
src/fe-writeamiga.cc \
src/fe-writebrother.cc \
src/fe-writeflux.cc \
src/fe-writetestpattern.cc \

23
src/fe-writeamiga.cc Normal file
View File

@@ -0,0 +1,23 @@
#include "globals.h"
#include "flags.h"
#include "decoders/decoders.h"
#include "amiga/amiga.h"
#include "writer.h"
#include "fmt/format.h"
#include "image.h"
#include <fstream>
static FlagGroup flags { &writerFlags, &amigaEncoderFlags };
int mainWriteAmiga(int argc, const char* argv[])
{
setWriterDefaultInput(":c=80:h=2:s=11:b=512");
setWriterDefaultDest(":d=0:t=0-79:s=0-1");
flags.parseFlags(argc, argv);
AmigaEncoder encoder;
writeDiskCommand(encoder);
return 0;
}

View File

@@ -28,6 +28,7 @@ extern command_cb mainRpm;
extern command_cb mainSeek;
extern command_cb mainTestBulkTransport;
extern command_cb mainUpgradeFluxFile;
extern command_cb mainWriteAmiga;
extern command_cb mainWriteBrother;
extern command_cb mainWriteFlux;
extern command_cb mainWriteTestPattern;
@@ -79,6 +80,7 @@ static std::vector<Command> readables =
static std::vector<Command> writeables =
{
{ "amiga", mainWriteAmiga, "Writes Amiga disks.", },
{ "brother", mainWriteBrother, "Writes 120kB and 240kB Brother word processor disks.", },
};