mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Add an extremely prototype version of the Smaky decoder.
This commit is contained in:
1
Makefile
1
Makefile
@@ -111,6 +111,7 @@ PROTOS = \
|
||||
arch/micropolis/micropolis.proto \
|
||||
arch/mx/mx.proto \
|
||||
arch/northstar/northstar.proto \
|
||||
arch/smaky/smaky.proto \
|
||||
arch/tids990/tids990.proto \
|
||||
arch/victor9k/victor9k.proto \
|
||||
arch/zilogmcz/zilogmcz.proto \
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
LIBARCH_SRCS = \
|
||||
arch/aeslanier/decoder.cc \
|
||||
arch/agat/agat.cc \
|
||||
arch/agat/decoder.cc \
|
||||
arch/amiga/amiga.cc \
|
||||
arch/amiga/decoder.cc \
|
||||
arch/amiga/encoder.cc \
|
||||
@@ -16,18 +18,17 @@ LIBARCH_SRCS = \
|
||||
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/smaky/decoder.cc \
|
||||
arch/tids990/decoder.cc \
|
||||
arch/tids990/encoder.cc \
|
||||
arch/victor9k/decoder.cc \
|
||||
arch/victor9k/encoder.cc \
|
||||
arch/zilogmcz/decoder.cc \
|
||||
arch/tids990/decoder.cc \
|
||||
arch/tids990/encoder.cc \
|
||||
arch/micropolis/decoder.cc \
|
||||
arch/micropolis/encoder.cc \
|
||||
arch/northstar/decoder.cc \
|
||||
arch/northstar/encoder.cc \
|
||||
arch/agat/agat.cc \
|
||||
arch/agat/decoder.cc \
|
||||
|
||||
LIBARCH_OBJS = $(patsubst %.cc, $(OBJDIR)/%.o, $(LIBARCH_SRCS))
|
||||
OBJS += $(LIBARCH_OBJS)
|
||||
|
||||
156
arch/smaky/decoder.cc
Normal file
156
arch/smaky/decoder.cc
Normal file
@@ -0,0 +1,156 @@
|
||||
#include "globals.h"
|
||||
#include "fluxmap.h"
|
||||
#include "decoders/fluxmapreader.h"
|
||||
#include "protocol.h"
|
||||
#include "decoders/decoders.h"
|
||||
#include "sector.h"
|
||||
#include "smaky.h"
|
||||
#include "bytes.h"
|
||||
#include "crc.h"
|
||||
#include "fmt/format.h"
|
||||
#include "lib/decoders/decoders.pb.h"
|
||||
#include <string.h>
|
||||
#include <algorithm>
|
||||
|
||||
static const FluxPattern SECTOR_PATTERN(20, 0x92aaa);
|
||||
|
||||
class SmakyDecoder : public Decoder
|
||||
{
|
||||
public:
|
||||
SmakyDecoder(const DecoderProto& config):
|
||||
Decoder(config),
|
||||
_config(config.smaky())
|
||||
{}
|
||||
|
||||
void beginTrack() override
|
||||
{
|
||||
/* Find the start-of-track index marks, which will be an interval
|
||||
* of about 6ms. */
|
||||
|
||||
seekToIndexMark();
|
||||
for (;;)
|
||||
{
|
||||
auto previous = tell();
|
||||
seekToIndexMark();
|
||||
auto now = tell();
|
||||
if (eof())
|
||||
return;
|
||||
|
||||
if ((now.ns() - previous.ns()) < 8e6)
|
||||
{
|
||||
seekToIndexMark();
|
||||
auto next = tell();
|
||||
if ((next.ns() - now.ns()) < 8e6)
|
||||
{
|
||||
/* We have seen two short gaps in a row, so the index
|
||||
* mark must be now. */
|
||||
|
||||
seek(previous);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We have seen one short gap and one long gap. This
|
||||
* means the index mark must be off the beginning of
|
||||
* the data. Seek to the start to simulate this. */
|
||||
|
||||
rewind();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Now we know where to start counting, start finding sectors. */
|
||||
|
||||
int sectorId = 0;
|
||||
_sectorStarts.clear();
|
||||
for (;;)
|
||||
{
|
||||
auto previous = tell();
|
||||
seekToIndexMark();
|
||||
auto now = tell();
|
||||
if (eof())
|
||||
{
|
||||
if (_sectorStarts.empty())
|
||||
return;
|
||||
|
||||
_sectorIndex = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if ((now.ns() - previous.ns()) < 8e6)
|
||||
{
|
||||
/* This is an index mark! */
|
||||
/* Advance to the start of the first sector and record
|
||||
* the time. */
|
||||
|
||||
seekToIndexMark();
|
||||
sectorId = 0;
|
||||
}
|
||||
|
||||
_sectorStarts.push_back(std::make_pair(sectorId, now));
|
||||
sectorId++;
|
||||
}
|
||||
}
|
||||
|
||||
nanoseconds_t advanceToNextRecord() override
|
||||
{
|
||||
if (_sectorIndex == _sectorStarts.size())
|
||||
{
|
||||
seekToIndexMark();
|
||||
return 0;
|
||||
}
|
||||
|
||||
const auto& p = _sectorStarts[_sectorIndex++];
|
||||
_sectorId = p.first;
|
||||
seek(p.second);
|
||||
|
||||
nanoseconds_t clock = seekToPattern(SECTOR_PATTERN);
|
||||
_sector->headerStartTime = tell().ns();
|
||||
|
||||
return clock;
|
||||
}
|
||||
|
||||
void decodeSectorRecord() override
|
||||
{
|
||||
readRawBits(21);
|
||||
const auto& rawbits = readRawBits(SMAKY_RECORD_SIZE*16);
|
||||
if (rawbits.size() < SMAKY_SECTOR_SIZE)
|
||||
return;
|
||||
const auto& rawbytes = toBytes(rawbits).slice(0, SMAKY_RECORD_SIZE*16);
|
||||
|
||||
/* The Smaky bytes are stored backwards! Backwards! */
|
||||
|
||||
const auto& bytes = decodeFmMfm(rawbits).slice(0, SMAKY_RECORD_SIZE).reverseBits();
|
||||
ByteReader br(bytes);
|
||||
|
||||
uint8_t track = br.read_8();
|
||||
Bytes data = br.read(SMAKY_SECTOR_SIZE);
|
||||
uint8_t wantedChecksum = br.read_8();
|
||||
uint8_t gotChecksum = sumBytes(data) & 0xff;
|
||||
|
||||
if (track != _sector->physicalTrack)
|
||||
return;
|
||||
|
||||
_sector->logicalTrack = _sector->physicalTrack;
|
||||
_sector->logicalSide = _sector->physicalSide;
|
||||
_sector->logicalSector = _sectorId;
|
||||
|
||||
_sector->data = data;
|
||||
_sector->status = (wantedChecksum == gotChecksum) ? Sector::OK : Sector::BAD_CHECKSUM;
|
||||
}
|
||||
|
||||
private:
|
||||
const SmakyDecoderProto& _config;
|
||||
nanoseconds_t _startOfTrack;
|
||||
std::vector<std::pair<int, Fluxmap::Position>> _sectorStarts;
|
||||
int _sectorId;
|
||||
int _sectorIndex;
|
||||
};
|
||||
|
||||
std::unique_ptr<Decoder> createSmakyDecoder(const DecoderProto& config)
|
||||
{
|
||||
return std::unique_ptr<Decoder>(new SmakyDecoder(config));
|
||||
}
|
||||
|
||||
|
||||
10
arch/smaky/smaky.h
Normal file
10
arch/smaky/smaky.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef SMAKY_H
|
||||
#define SMAKY_H
|
||||
|
||||
#define SMAKY_SECTOR_SIZE 256
|
||||
#define SMAKY_RECORD_SIZE (1 + SMAKY_SECTOR_SIZE + 1)
|
||||
|
||||
extern std::unique_ptr<Decoder> createSmakyDecoder(const DecoderProto& config);
|
||||
|
||||
#endif
|
||||
|
||||
6
arch/smaky/smaky.proto
Normal file
6
arch/smaky/smaky.proto
Normal file
@@ -0,0 +1,6 @@
|
||||
syntax = "proto2";
|
||||
|
||||
import "lib/common.proto";
|
||||
|
||||
message SmakyDecoderProto {}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include "arch/micropolis/micropolis.h"
|
||||
#include "arch/mx/mx.h"
|
||||
#include "arch/northstar/northstar.h"
|
||||
#include "arch/smaky/smaky.h"
|
||||
#include "arch/tids990/tids990.h"
|
||||
#include "arch/victor9k/victor9k.h"
|
||||
#include "arch/zilogmcz/zilogmcz.h"
|
||||
@@ -48,6 +49,7 @@ std::unique_ptr<Decoder> Decoder::create(const DecoderProto& config)
|
||||
{DecoderProto::kMicropolis, createMicropolisDecoder },
|
||||
{DecoderProto::kMx, createMxDecoder },
|
||||
{DecoderProto::kNorthstar, createNorthstarDecoder },
|
||||
{DecoderProto::kSmaky, createSmakyDecoder },
|
||||
{DecoderProto::kTids990, createTids990Decoder },
|
||||
{DecoderProto::kVictor9K, createVictor9kDecoder },
|
||||
{DecoderProto::kZilogmcz, createZilogMczDecoder },
|
||||
|
||||
@@ -71,6 +71,11 @@ public:
|
||||
return _fmr->tell();
|
||||
}
|
||||
|
||||
void rewind()
|
||||
{
|
||||
_fmr->rewind();
|
||||
}
|
||||
|
||||
void seek(const Fluxmap::Position& pos)
|
||||
{
|
||||
return _fmr->seek(pos);
|
||||
|
||||
@@ -13,13 +13,14 @@ import "arch/macintosh/macintosh.proto";
|
||||
import "arch/micropolis/micropolis.proto";
|
||||
import "arch/mx/mx.proto";
|
||||
import "arch/northstar/northstar.proto";
|
||||
import "arch/smaky/smaky.proto";
|
||||
import "arch/tids990/tids990.proto";
|
||||
import "arch/victor9k/victor9k.proto";
|
||||
import "arch/zilogmcz/zilogmcz.proto";
|
||||
import "lib/fluxsink/fluxsink.proto";
|
||||
import "lib/common.proto";
|
||||
|
||||
//NEXT: 30
|
||||
//NEXT: 31
|
||||
message DecoderProto {
|
||||
optional double pulse_debounce_threshold = 1 [default = 0.30,
|
||||
(help) = "ignore pulses with intervals shorter than this, in fractions of a clock"];
|
||||
@@ -46,6 +47,7 @@ message DecoderProto {
|
||||
MicropolisDecoderProto micropolis = 14;
|
||||
MxDecoderProto mx = 15;
|
||||
NorthstarDecoderProto northstar = 24;
|
||||
SmakyDecoderProto smaky = 30;
|
||||
Tids990DecoderProto tids990 = 16;
|
||||
Victor9kDecoderProto victor9k = 17;
|
||||
ZilogMczDecoderProto zilogmcz = 18;
|
||||
|
||||
@@ -63,6 +63,7 @@ FORMATS = \
|
||||
northstar87 \
|
||||
rx50 \
|
||||
shugart_drive \
|
||||
smaky \
|
||||
tids990 \
|
||||
victor9k_ds \
|
||||
victor9k_ss \
|
||||
|
||||
33
src/formats/smaky.textpb
Normal file
33
src/formats/smaky.textpb
Normal file
@@ -0,0 +1,33 @@
|
||||
comment: 'BK 800kB 5.25"/3.5" 80-track 10-sector DSDD'
|
||||
|
||||
image_reader {
|
||||
filename: "smaky.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
image_writer {
|
||||
filename: "smaky.img"
|
||||
type: IMG
|
||||
}
|
||||
|
||||
layout {
|
||||
tracks: 77
|
||||
sides: 1
|
||||
layoutdata {
|
||||
sector_size: 256
|
||||
physical {
|
||||
start_sector: 0
|
||||
count: 16
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
drive {
|
||||
hard_sector_count: 16
|
||||
sync_with_index: true
|
||||
}
|
||||
|
||||
decoder {
|
||||
smaky {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user