Fix a few encoder issues; but while 720kB disks work fine in a real machine,

1440kB disks don't.
This commit is contained in:
David Given
2020-02-14 22:47:15 +01:00
parent a63a90bbd0
commit a4002d2617
3 changed files with 67 additions and 13 deletions

View File

@@ -6,6 +6,7 @@
#include "crc.h"
#include "sectorset.h"
#include "writer.h"
#include "fmt/format.h"
#include <ctype.h>
/* IAM record separator:
@@ -69,7 +70,7 @@ void IbmEncoder::writeRawBits(uint32_t data, int width)
{
unsigned pos = _cursor - i - 1;
if (pos < _bits.size())
_bits[pos] = data & 1;
_lastBit = _bits[pos] = data & 1;
data >>= 1;
}
}
@@ -126,7 +127,6 @@ std::unique_ptr<Fluxmap> IbmEncoder::encode(
if (_parameters.emitIam)
{
writeBytes(_parameters.useFm ? 6 : 12, 0x00);
_lastBit = false;
if (!_parameters.useFm)
{
for (int i=0; i<3; i++)
@@ -136,16 +136,17 @@ std::unique_ptr<Fluxmap> IbmEncoder::encode(
writeBytes(_parameters.gap1, gapFill);
}
int sectorIndex = 0;
while (sectorIndex < _parameters.sectorSkew.size())
bool first = true;
for (char sectorChar : _parameters.sectorSkew)
{
if (sectorIndex != 0)
int sectorId = charToInt(sectorChar);
if (!first)
writeBytes(_parameters.gap3, gapFill);
first = false;
int sectorId = charToInt(_parameters.sectorSkew.at(sectorIndex));
const auto& sectorData = allSectors.get(physicalTrack, physicalSide, sectorId);
if (!sectorData)
break;
Error() << fmt::format("format tried to find sector {} which wasn't in the input file", sectorId);
/* Writing the sector and data records are fantastically annoying.
* The CRC is calculated from the *very start* of the record, and
@@ -160,7 +161,6 @@ std::unique_ptr<Fluxmap> IbmEncoder::encode(
ByteWriter bw(header);
writeBytes(_parameters.useFm ? 6 : 12, 0x00);
_lastBit = false;
if (!_parameters.useFm)
{
for (int i=0; i<3; i++)
@@ -195,7 +195,6 @@ std::unique_ptr<Fluxmap> IbmEncoder::encode(
ByteWriter bw(data);
writeBytes(_parameters.useFm ? 6 : 12, 0x00);
_lastBit = false;
if (!_parameters.useFm)
{
for (int i=0; i<3; i++)
@@ -221,8 +220,6 @@ std::unique_ptr<Fluxmap> IbmEncoder::encode(
writeBytes(data.slice(conventionalHeaderStart));
}
sectorIndex++;
}
if (_cursor >= _bits.size())

View File

@@ -79,6 +79,7 @@ static ActionFlag preset1440(
{ "--ibm-preset-1440" },
"Preset parameters to a 3.5\" 1440kB disk.",
[] {
setWriterDefaultInput(":c=80:h=2:s=18:b=512");
trackLengthMs.setDefaultValue(200);
sectorSize.setDefaultValue(512);
emitIam.setDefaultValue(true);
@@ -88,13 +89,30 @@ static ActionFlag preset1440(
gap0.setDefaultValue(80);
gap1.setDefaultValue(50);
gap2.setDefaultValue(22);
gap3.setDefaultValue(54);
gap3.setDefaultValue(108);
sectorSkew.setDefaultValue("0123456789abcdefgh");
});
static ActionFlag preset720(
{ "--ibm-preset-720" },
"Preset parameters to a 3.5\" 720kB disk.",
[] {
setWriterDefaultInput(":c=80:h=2:s=9:b=512");
trackLengthMs.setDefaultValue(200);
sectorSize.setDefaultValue(512);
emitIam.setDefaultValue(true);
clockRateKhz.setDefaultValue(250);
idamByte.setDefaultValue(0x5554);
damByte.setDefaultValue(0x5545);
gap0.setDefaultValue(80);
gap1.setDefaultValue(50);
gap2.setDefaultValue(22);
gap3.setDefaultValue(80);
sectorSkew.setDefaultValue("012345678");
});
int mainWriteIbm(int argc, const char* argv[])
{
setWriterDefaultInput(":c=80:h=2:s=18:b=512");
setWriterDefaultDest(":d=0:t=0-79:s=0-1");
flags.parseFlags(argc, argv);

View File

@@ -38,6 +38,15 @@ static void testDecode(void)
) == Bytes{ 0x80 });
}
static std::vector<bool> wrappedEncodeMfm(const Bytes& bytes)
{
std::vector<bool> bits(16);
unsigned cursor = 0;
bool lastBit = false;
encodeMfm(bits, cursor, bytes, lastBit);
return bits;
}
static std::vector<bool> wrappedEncodeFm(const Bytes& bytes)
{
std::vector<bool> bits(16);
@@ -46,6 +55,35 @@ static std::vector<bool> wrappedEncodeFm(const Bytes& bytes)
return bits;
}
static void testEncodeMfm(void)
{
assert(wrappedEncodeMfm(Bytes{ 0xa1 })
== (std::vector<bool>{
false, true,
false, false,
false, true,
false, false,
true, false,
true, false,
true, false,
false, true
})
);
assert(wrappedEncodeMfm(Bytes{ 0xc2 })
== (std::vector<bool>{
false, true,
false, true,
false, false,
true, false,
true, false,
true, false,
false, true,
false, false
})
);
}
static void testEncodeFm(void)
{
assert(wrappedEncodeFm(Bytes{ 0x00 })
@@ -78,6 +116,7 @@ static void testEncodeFm(void)
int main(int argc, const char* argv[])
{
testDecode();
testEncodeMfm();
testEncodeFm();
return 0;
}