mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8863bda0d0 | ||
|
|
df83b558bf | ||
|
|
7c2b5f116d | ||
|
|
30fe75f9bf | ||
|
|
401e7a9edb | ||
|
|
fd4ddc56f2 | ||
|
|
83d907bf71 | ||
|
|
327bc76c6e | ||
|
|
fdd39fb2d8 | ||
|
|
bfcfa8eb19 | ||
|
|
7095c03e28 | ||
|
|
45e796f15f | ||
|
|
3d1dcd6874 | ||
|
|
0033d0759f | ||
|
|
53f7dfe6c9 | ||
|
|
75446de29b | ||
|
|
1d119d6921 | ||
|
|
7462bd995f | ||
|
|
0dd99efad3 | ||
|
|
1234e81463 | ||
|
|
ea13d66e6b | ||
|
|
a7cb7eb995 | ||
|
|
29f5feb34d |
@@ -29,6 +29,7 @@ IncludeBlocks: Preserve
|
||||
IndentCaseLabels: 'true'
|
||||
IndentWidth: '4'
|
||||
IndentWrappedFunctionNames: 'false'
|
||||
IndentPPDirectives: BeforeHash
|
||||
KeepEmptyLinesAtTheStartOfBlocks: 'true'
|
||||
NamespaceIndentation: All
|
||||
PointerAlignment: Left
|
||||
|
||||
2
.github/workflows/ccpp.yml
vendored
2
.github/workflows/ccpp.yml
vendored
@@ -70,7 +70,7 @@ jobs:
|
||||
mingw-w64-i686-sqlite3
|
||||
mingw-w64-i686-wxWidgets
|
||||
mingw-w64-i686-zlib
|
||||
mingw-w64-i686-imagemagick
|
||||
mingw-w64-i686-png2ico
|
||||
vim
|
||||
zip
|
||||
- name: update-protobuf
|
||||
|
||||
6
.github/workflows/release.yml
vendored
6
.github/workflows/release.yml
vendored
@@ -34,7 +34,7 @@ jobs:
|
||||
mingw-w64-i686-sqlite3
|
||||
mingw-w64-i686-wxWidgets
|
||||
mingw-w64-i686-zlib
|
||||
mingw-w64-i686-imagemagick
|
||||
mingw-w64-i686-png2ico
|
||||
vim
|
||||
zip
|
||||
- uses: actions/checkout@v3
|
||||
@@ -94,10 +94,12 @@ jobs:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: brew
|
||||
run: brew install sqlite pkg-config libusb protobuf wxwidgets fmt make coreutils dylibbundler libjpeg
|
||||
|
||||
- name: make
|
||||
run: gmake
|
||||
run: gmake -j`nproc`
|
||||
|
||||
- name: tag
|
||||
uses: EndBug/latest-tag@latest
|
||||
|
||||
@@ -19,4 +19,13 @@ message Apple2EncoderProto
|
||||
|
||||
optional uint32 side_one_track_offset = 3
|
||||
[ default = 0, (help) = "offset to apply to track numbers on side 1" ];
|
||||
|
||||
optional uint32 post_index_gap_bytes = 4
|
||||
[ default = 32, (help) = "the number of resync bytes to write after the index mark" ];
|
||||
|
||||
optional uint32 post_address_gap_bytes = 5
|
||||
[ default = 6, (help) = "the number of resync bytes to write after the address gap" ];
|
||||
|
||||
optional uint32 post_data_gap_bytes = 6
|
||||
[ default = 8, (help) = "the number of resync bytes to write after each sector" ];
|
||||
}
|
||||
|
||||
@@ -79,18 +79,14 @@ private:
|
||||
auto write_bit = [&](bool val)
|
||||
{
|
||||
if (cursor <= bits.size())
|
||||
{
|
||||
bits[cursor] = val;
|
||||
}
|
||||
cursor++;
|
||||
};
|
||||
|
||||
auto write_bits = [&](uint32_t bits, int width)
|
||||
{
|
||||
for (int i = width; i--;)
|
||||
{
|
||||
write_bit(bits & (1u << i));
|
||||
}
|
||||
};
|
||||
|
||||
auto write_gcr44 = [&](uint8_t value)
|
||||
@@ -104,15 +100,13 @@ private:
|
||||
};
|
||||
|
||||
// The special "FF40" sequence is used to synchronize the receiving
|
||||
// shift register. It's written as "1111 1111 00"; FF indicates the
|
||||
// 8 consecutive 1-bits, while "40" indicates the total number of
|
||||
// shift register. It's written as "0 1111 1111 0"; FF indicates the
|
||||
// 8 consecutive 1-bits, while "40" indicaes the total number of
|
||||
// microseconds.
|
||||
auto write_ff40 = [&](int n = 1)
|
||||
{
|
||||
for (; n--;)
|
||||
{
|
||||
write_bits(0xff << 2, 10);
|
||||
}
|
||||
write_bits(0xff << 1, 10);
|
||||
};
|
||||
|
||||
// There is data to encode to disk.
|
||||
@@ -127,7 +121,9 @@ private:
|
||||
//
|
||||
// In standard formatting, the first logical sector apparently gets
|
||||
// extra padding.
|
||||
write_ff40(sector.logicalSector == 0 ? 32 : 8);
|
||||
write_ff40(sector.logicalSector == 0
|
||||
? _config.post_index_gap_bytes()
|
||||
: _config.post_data_gap_bytes());
|
||||
|
||||
int track = sector.logicalTrack;
|
||||
if (sector.logicalSide == 1)
|
||||
@@ -144,7 +140,7 @@ private:
|
||||
|
||||
// Write data syncing leader: FF40 + APPLE2_DATA_RECORD + sector
|
||||
// data + sum + DE AA EB (+ mystery bits cut off of the scan?)
|
||||
write_ff40(8);
|
||||
write_ff40(_config.post_address_gap_bytes());
|
||||
write_bits(APPLE2_DATA_RECORD, 24);
|
||||
|
||||
// Convert the sector data to GCR, append the checksum, and write it
|
||||
|
||||
194
build.lua
194
build.lua
@@ -1,194 +0,0 @@
|
||||
vars.cflags = { "$(CFLAGS)" }
|
||||
vars.cxxflags = { "$(CXXFLAGS)" }
|
||||
vars.ldflags = { "-pthread" }
|
||||
|
||||
include "build/protobuf.lua"
|
||||
include "build/dependency.lua"
|
||||
include "build/tests.lua"
|
||||
|
||||
dependency {
|
||||
name = "fmt_dep",
|
||||
pkg_config = "fmt",
|
||||
}
|
||||
|
||||
dependency {
|
||||
name = "stb_dep",
|
||||
pkg_config = "stb",
|
||||
fallback = "dep/stb+stb"
|
||||
}
|
||||
|
||||
dependency {
|
||||
name = "protobuf_dep",
|
||||
pkg_config = "protobuf"
|
||||
}
|
||||
|
||||
dependency {
|
||||
name = "zlib_dep",
|
||||
pkg_config = "zlib"
|
||||
}
|
||||
|
||||
proto_cc_library {
|
||||
name = "config_lib",
|
||||
srcs = {
|
||||
"./lib/common.proto",
|
||||
"./lib/config.proto",
|
||||
"./lib/decoders/decoders.proto",
|
||||
"./lib/drive.proto",
|
||||
"./lib/encoders/encoders.proto",
|
||||
"./lib/fl2.proto",
|
||||
"./lib/fluxsink/fluxsink.proto",
|
||||
"./lib/fluxsource/fluxsource.proto",
|
||||
"./lib/imagereader/imagereader.proto",
|
||||
"./lib/imagewriter/imagewriter.proto",
|
||||
"./lib/mapper.proto",
|
||||
"./lib/usb/usb.proto",
|
||||
"./arch/aeslanier/aeslanier.proto",
|
||||
"./arch/agat/agat.proto",
|
||||
"./arch/amiga/amiga.proto",
|
||||
"./arch/apple2/apple2.proto",
|
||||
"./arch/brother/brother.proto",
|
||||
"./arch/c64/c64.proto",
|
||||
"./arch/f85/f85.proto",
|
||||
"./arch/fb100/fb100.proto",
|
||||
"./arch/ibm/ibm.proto",
|
||||
"./arch/macintosh/macintosh.proto",
|
||||
"./arch/micropolis/micropolis.proto",
|
||||
"./arch/mx/mx.proto",
|
||||
"./arch/northstar/northstar.proto",
|
||||
"./arch/rolandd20/rolandd20.proto",
|
||||
"./arch/tids990/tids990.proto",
|
||||
"./arch/victor9k/victor9k.proto",
|
||||
"./arch/zilogmcz/zilogmcz.proto",
|
||||
}
|
||||
}
|
||||
|
||||
clibrary {
|
||||
name = "protocol_lib",
|
||||
hdrs = { "./protocol.h" }
|
||||
}
|
||||
|
||||
clibrary {
|
||||
name = "libfluxengine",
|
||||
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",
|
||||
"./arch/apple2/decoder.cc",
|
||||
"./arch/apple2/encoder.cc",
|
||||
"./arch/brother/decoder.cc",
|
||||
"./arch/brother/encoder.cc",
|
||||
"./arch/c64/c64.cc",
|
||||
"./arch/c64/decoder.cc",
|
||||
"./arch/c64/encoder.cc",
|
||||
"./arch/f85/decoder.cc",
|
||||
"./arch/fb100/decoder.cc",
|
||||
"./arch/ibm/decoder.cc",
|
||||
"./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/rolandd20/rolandd20.cc",
|
||||
"./arch/tids990/decoder.cc",
|
||||
"./arch/tids990/encoder.cc",
|
||||
"./arch/victor9k/decoder.cc",
|
||||
"./arch/victor9k/encoder.cc",
|
||||
"./arch/zilogmcz/decoder.cc",
|
||||
"./lib/bitmap.cc",
|
||||
"./lib/bytes.cc",
|
||||
"./lib/crc.cc",
|
||||
"./lib/csvreader.cc",
|
||||
"./lib/decoders/decoders.cc",
|
||||
"./lib/decoders/fluxdecoder.cc",
|
||||
"./lib/decoders/fluxmapreader.cc",
|
||||
"./lib/decoders/fmmfm.cc",
|
||||
"./lib/encoders/encoders.cc",
|
||||
"./lib/flags.cc",
|
||||
"./lib/fluxmap.cc",
|
||||
"./lib/fluxsink/aufluxsink.cc",
|
||||
"./lib/fluxsink/fl2fluxsink.cc",
|
||||
"./lib/fluxsink/fluxsink.cc",
|
||||
"./lib/fluxsink/hardwarefluxsink.cc",
|
||||
"./lib/fluxsink/scpfluxsink.cc",
|
||||
"./lib/fluxsink/vcdfluxsink.cc",
|
||||
"./lib/fluxsource/cwffluxsource.cc",
|
||||
"./lib/fluxsource/erasefluxsource.cc",
|
||||
"./lib/fluxsource/fl2fluxsource.cc",
|
||||
"./lib/fluxsource/fluxsource.cc",
|
||||
"./lib/fluxsource/hardwarefluxsource.cc",
|
||||
"./lib/fluxsource/kryoflux.cc",
|
||||
"./lib/fluxsource/kryofluxfluxsource.cc",
|
||||
"./lib/fluxsource/scpfluxsource.cc",
|
||||
"./lib/fluxsource/testpatternfluxsource.cc",
|
||||
"./lib/globals.cc",
|
||||
"./lib/hexdump.cc",
|
||||
"./lib/image.cc",
|
||||
"./lib/imagereader/d64imagereader.cc",
|
||||
"./lib/imagereader/d88imagereader.cc",
|
||||
"./lib/imagereader/dimimagereader.cc",
|
||||
"./lib/imagereader/diskcopyimagereader.cc",
|
||||
"./lib/imagereader/fdiimagereader.cc",
|
||||
"./lib/imagereader/imagereader.cc",
|
||||
"./lib/imagereader/imdimagereader.cc",
|
||||
"./lib/imagereader/imgimagereader.cc",
|
||||
"./lib/imagereader/jv3imagereader.cc",
|
||||
"./lib/imagereader/nfdimagereader.cc",
|
||||
"./lib/imagereader/nsiimagereader.cc",
|
||||
"./lib/imagereader/td0imagereader.cc",
|
||||
"./lib/imagewriter/d64imagewriter.cc",
|
||||
"./lib/imagewriter/d88imagewriter.cc",
|
||||
"./lib/imagewriter/diskcopyimagewriter.cc",
|
||||
"./lib/imagewriter/imagewriter.cc",
|
||||
"./lib/imagewriter/imgimagewriter.cc",
|
||||
"./lib/imagewriter/ldbsimagewriter.cc",
|
||||
"./lib/imagewriter/nsiimagewriter.cc",
|
||||
"./lib/imagewriter/rawimagewriter.cc",
|
||||
"./lib/imginputoutpututils.cc",
|
||||
"./lib/ldbs.cc",
|
||||
"./lib/logger.cc",
|
||||
"./lib/mapper.cc",
|
||||
"./lib/proto.cc",
|
||||
"./lib/readerwriter.cc",
|
||||
"./lib/sector.cc",
|
||||
"./lib/usb/fluxengineusb.cc",
|
||||
"./lib/usb/greaseweazle.cc",
|
||||
"./lib/usb/greaseweazleusb.cc",
|
||||
"./lib/usb/serial.cc",
|
||||
"./lib/usb/usb.cc",
|
||||
"./lib/usb/usbfinder.cc",
|
||||
"./lib/utils.cc",
|
||||
"protocol.h",
|
||||
},
|
||||
deps = {
|
||||
"+config_lib",
|
||||
"+protocol_lib",
|
||||
"+fmt_dep",
|
||||
"+protobuf_dep",
|
||||
"+zlib_dep",
|
||||
"dep/libusbp+libusbp",
|
||||
},
|
||||
dep_cflags = { "-Ilib", "-Iarch", "-I." },
|
||||
vars = {
|
||||
["+cflags"] = { "-Ilib", "-Iarch", "-I." }
|
||||
}
|
||||
}
|
||||
|
||||
installable {
|
||||
name = "all",
|
||||
map = {
|
||||
["fluxengine"] = "src+fluxengine",
|
||||
["fluxengine-gui"] = "src/gui+fluxengine",
|
||||
["brother120tool"] = "tools+brother120tool",
|
||||
["brother240tool"] = "tools+brother240tool",
|
||||
["upgrade-flux-file"] = "tools+upgrade-flux-file",
|
||||
}
|
||||
}
|
||||
|
||||
include "tests/build.lua"
|
||||
|
||||
4
build.py
4
build.py
@@ -41,7 +41,9 @@ cxxlibrary(
|
||||
"./lib/fluxsink/scpfluxsink.cc",
|
||||
"./lib/fluxsink/vcdfluxsink.cc",
|
||||
"./lib/fluxsource/a2rfluxsource.cc",
|
||||
"./lib/fluxsource/catweasel.cc",
|
||||
"./lib/fluxsource/cwffluxsource.cc",
|
||||
"./lib/fluxsource/dmkfluxsource.cc",
|
||||
"./lib/fluxsource/erasefluxsource.cc",
|
||||
"./lib/fluxsource/fl2fluxsource.cc",
|
||||
"./lib/fluxsource/fluxsource.cc",
|
||||
@@ -185,6 +187,7 @@ cxxlibrary(
|
||||
"lib/flux.h": "./lib/flux.h",
|
||||
"lib/fluxmap.h": "./lib/fluxmap.h",
|
||||
"lib/fluxsink/fluxsink.h": "./lib/fluxsink/fluxsink.h",
|
||||
"lib/fluxsource/catweasel.h": "lib/fluxsource/catweasel.h",
|
||||
"lib/fluxsource/fluxsource.h": "lib/fluxsource/fluxsource.h",
|
||||
"lib/fluxsource/flx.h": "lib/fluxsource/flx.h",
|
||||
"lib/fluxsource/kryoflux.h": "lib/fluxsource/kryoflux.h",
|
||||
@@ -224,6 +227,7 @@ if not glob("../fluxengine-testdata/data"):
|
||||
print("fluxengine-testdata not found; skipping corpus tests")
|
||||
else:
|
||||
corpus = [
|
||||
("acorndfs", "", "--200"),
|
||||
("agat", "", ""),
|
||||
("amiga", "", ""),
|
||||
("apple2", "", "--140 40track_drive"),
|
||||
|
||||
15
build/ab.py
15
build/ab.py
@@ -417,8 +417,6 @@ def export(self, name=None, items: TargetsMap = {}, deps: Targets = []):
|
||||
for dest, src in items.items():
|
||||
destf = filenameof(dest)
|
||||
dir = dirname(destf)
|
||||
if dir:
|
||||
cs += ["mkdir -p " + dir]
|
||||
|
||||
srcs = filenamesof(src)
|
||||
if len(srcs) != 1:
|
||||
@@ -426,13 +424,16 @@ def export(self, name=None, items: TargetsMap = {}, deps: Targets = []):
|
||||
"a dependency of an export must have exactly one output file"
|
||||
)
|
||||
|
||||
cs += ["cp %s %s" % (srcs[0], destf)]
|
||||
emitter_rule(self.name + "+" + destf, srcs, [destf])
|
||||
emitter_label(f"CP {destf}")
|
||||
if dir:
|
||||
emitter_exec(["mkdir -p " + dir])
|
||||
|
||||
emitter_exec(["cp %s %s" % (srcs[0], destf)])
|
||||
self.outs += [destf]
|
||||
|
||||
emitter_rule(self.name, items.values(), self.outs, deps)
|
||||
emitter_label(f"EXPORT {self.name}")
|
||||
|
||||
emitter_exec(cs)
|
||||
emitter_rule(self.name, self.outs, [], deps)
|
||||
emit("\t@")
|
||||
|
||||
if self.outs:
|
||||
emit("clean::")
|
||||
|
||||
251
build/build.lua
251
build/build.lua
@@ -1,251 +0,0 @@
|
||||
local OBJDIR = "$(OBJDIR)"
|
||||
|
||||
local function objdir(e)
|
||||
return concatpath(OBJDIR, e.cwd, e.name)
|
||||
end
|
||||
|
||||
definerule("normalrule",
|
||||
{
|
||||
ins = { type="targets" },
|
||||
deps = { type="targets", default={} },
|
||||
outs = { type="targets", default={} },
|
||||
outleaves = { type="strings" },
|
||||
label = { type="string", optional=true },
|
||||
objdir = { type="string", optional=true },
|
||||
commands = { type="strings" },
|
||||
},
|
||||
function (e)
|
||||
local dir = e.objdir or objdir(e)
|
||||
local realouts = {}
|
||||
for _, v in pairs(e.outleaves) do
|
||||
realouts[#realouts+1] = concatpath(dir, v)
|
||||
end
|
||||
|
||||
local vars = inherit(e.vars, {
|
||||
dir = dir
|
||||
})
|
||||
|
||||
local result = simplerule {
|
||||
name = e.name,
|
||||
ins = e.ins,
|
||||
deps = e.deps,
|
||||
outs = concat(realouts, filenamesof(e.outs)),
|
||||
label = e.label,
|
||||
commands = e.commands,
|
||||
vars = vars,
|
||||
}
|
||||
result.dir = dir
|
||||
return result
|
||||
end
|
||||
)
|
||||
|
||||
local function is_clike(f)
|
||||
return f:find("%.c$") or f:find("%.cc$") or f:find("%.cpp$")
|
||||
end
|
||||
|
||||
definerule("cfile",
|
||||
{
|
||||
srcs = { type="targets" },
|
||||
deps = { type="targets", default={} }
|
||||
},
|
||||
function (e)
|
||||
local cflags = e.vars.cflags
|
||||
local cxxflags = e.vars.cxxflags
|
||||
for _, target in ipairs(targetsof(e.deps)) do
|
||||
if target.is.clibrary then
|
||||
cflags = concat(cflags, target.dep_cflags)
|
||||
cxxflags = concat(cxxflags, target.dep_cxxflags)
|
||||
end
|
||||
end
|
||||
|
||||
local src = filter(filenamesof(e.srcs), is_clike)
|
||||
local cmd
|
||||
local cxx = false
|
||||
if src[1]:find("%.c$") then
|
||||
cmd = "$(CC) -c -o %{outs[1]} %{ins[1]} %{hdrpaths} %{cflags}"
|
||||
else
|
||||
cmd = "$(CXX) -c -o %{outs[1]} %{ins[1]} %{hdrpaths} %{cflags} %{cxxflags}"
|
||||
cxx = true
|
||||
end
|
||||
|
||||
local outleaf = basename(e.name)..".o"
|
||||
local rule = normalrule {
|
||||
name = e.name,
|
||||
cwd = e.cwd,
|
||||
ins = e.srcs,
|
||||
deps = e.deps,
|
||||
outleaves = {outleaf},
|
||||
label = e.label,
|
||||
commands = cmd,
|
||||
vars = {
|
||||
hdrpaths = {},
|
||||
cflags = cflags,
|
||||
cxxflags = cxxflags,
|
||||
}
|
||||
}
|
||||
|
||||
rule.is.cxxfile = cxx
|
||||
return rule
|
||||
end
|
||||
)
|
||||
|
||||
local function do_cfiles(e)
|
||||
local outs = {}
|
||||
local srcs = filenamesof(e.srcs)
|
||||
for _, f in ipairs(sorted(filter(srcs, is_clike))) do
|
||||
local ofile
|
||||
if f:find(OBJDIR, 1, true) == 1 then
|
||||
ofile = e.name.."/"..f:sub(#OBJDIR+1)..".o"
|
||||
else
|
||||
ofile = e.name.."/"..f..".o"
|
||||
end
|
||||
outs[#outs+1] = cfile {
|
||||
name = ofile,
|
||||
srcs = { f },
|
||||
deps = e.deps
|
||||
}
|
||||
end
|
||||
return outs
|
||||
end
|
||||
|
||||
definerule("clibrary",
|
||||
{
|
||||
srcs = { type="targets", default={} },
|
||||
deps = { type="targets", default={} },
|
||||
hdrs = { type="targets", default={} },
|
||||
dep_cflags = { type="strings", default={} },
|
||||
dep_cxxflags = { type="strings", default={} },
|
||||
dep_ldflags = { type="strings", default={} },
|
||||
dep_libs = { type="strings", default={} },
|
||||
},
|
||||
function (e)
|
||||
local ins = do_cfiles(e)
|
||||
local cxx = false
|
||||
for _, f in ipairs(ins) do
|
||||
if f.is.cxxfile then
|
||||
cxx = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
local mkdirs = {}
|
||||
local copies = {}
|
||||
local outs = {}
|
||||
local function copy_file(src, dest)
|
||||
mkdirs[#mkdirs+1] = "mkdir -p %{dir}/"..dirname(dest)
|
||||
copies[#copies+1] = "cp "..src.." %{dir}/"..dest
|
||||
outs[#outs+1] = objdir(e).."/"..dest
|
||||
end
|
||||
|
||||
local deps = {}
|
||||
for k, v in pairs(e.hdrs) do
|
||||
deps[#deps+1] = v
|
||||
if type(k) == "number" then
|
||||
v = filenamesof(v)
|
||||
for _, v in ipairs(v) do
|
||||
if not startswith(e.cwd, v) then
|
||||
error(string.format("filename '%s' is not local to '%s' --- "..
|
||||
"you'll have to specify the output filename manually", v, e.cwd))
|
||||
end
|
||||
copy_file(v, v:gsub("^"..e.cwd, ""))
|
||||
end
|
||||
else
|
||||
v = filenamesof(v)
|
||||
if #v ~= 1 then
|
||||
error("each mapped hdrs item can only cope with a single file")
|
||||
end
|
||||
copy_file(v[1], k)
|
||||
end
|
||||
end
|
||||
|
||||
ins = sorted(filenamesof(ins))
|
||||
local has_ar = (#ins ~= 0)
|
||||
local lib = normalrule {
|
||||
name = e.name,
|
||||
cwd = e.cwd,
|
||||
ins = sorted(filenamesof(ins)),
|
||||
deps = deps,
|
||||
outs = outs,
|
||||
outleaves = { e.name..".a" },
|
||||
label = e.label,
|
||||
commands = {
|
||||
sorted(mkdirs),
|
||||
sorted(copies),
|
||||
has_ar and "rm -f %{outs[1]} && $(AR) cqs %{outs[1]} %{ins}" or {},
|
||||
}
|
||||
}
|
||||
|
||||
lib.dep_cflags = concat(e.dep_cflags, "-I"..lib.dir)
|
||||
lib.dep_cxxflags = e.dep_cxxflags
|
||||
lib.dep_ldflags = e.dep_ldflags
|
||||
lib.dep_libs = concat(e.dep_libs, has_ar and matching(filenamesof(lib), "%.a$") or {})
|
||||
lib.dep_cxx = cxx
|
||||
|
||||
for _, d in pairs(targetsof(e.deps)) do
|
||||
lib.dep_cflags = concat(lib.dep_cflags, d.dep_cflags)
|
||||
lib.dep_cxxflags = concat(lib.dep_cxxflags, d.dep_cxxflags)
|
||||
lib.dep_ldflags = concat(lib.dep_ldflags, d.dep_ldflags)
|
||||
lib.dep_libs = concat(lib.dep_libs, d.dep_libs)
|
||||
lib.dep_cxx = lib.dep_cxx or d.dep_cxx
|
||||
end
|
||||
|
||||
return lib
|
||||
end
|
||||
)
|
||||
|
||||
definerule("cprogram",
|
||||
{
|
||||
srcs = { type="targets", default={} },
|
||||
deps = { type="targets", default={} },
|
||||
},
|
||||
function (e)
|
||||
local deps = e.deps
|
||||
local ins = {}
|
||||
local cxx = false
|
||||
|
||||
if (#e.srcs > 0) then
|
||||
local objs = do_cfiles(e)
|
||||
for _, obj in pairs(objs) do
|
||||
if obj.is.cxxfile then
|
||||
cxx = true
|
||||
end
|
||||
ins[#ins+1] = obj
|
||||
end
|
||||
end
|
||||
|
||||
local libs = {}
|
||||
local cflags = {}
|
||||
local cxxflags = {}
|
||||
local ldflags = {}
|
||||
for _, lib in pairs(e.deps) do
|
||||
cflags = concat(cflags, lib.dep_cflags)
|
||||
cxxflags = concat(cxxflags, lib.dep_cxxflags)
|
||||
ldflags = concat(ldflags, lib.dep_ldflags)
|
||||
libs = concat(libs, lib.dep_libs)
|
||||
cxx = cxx or lib.dep_cxx
|
||||
end
|
||||
|
||||
local command
|
||||
if cxx then
|
||||
command = "$(CXX) $(LDFLAGS) %{ldflags} -o %{outs[1]} %{ins} %{libs} %{libs}"
|
||||
else
|
||||
command = "$(CC) $(LDFLAGS) %{ldflags} -o %{outs[1]} %{ins} %{libs} %{libs}"
|
||||
end
|
||||
|
||||
return normalrule {
|
||||
name = e.name,
|
||||
cwd = e.cwd,
|
||||
deps = deps,
|
||||
ins = ins,
|
||||
outleaves = { e.name },
|
||||
commands = { command },
|
||||
vars = {
|
||||
cflags = cflags,
|
||||
cxxflags = cxxflags,
|
||||
ldflags = ldflags,
|
||||
libs = libs,
|
||||
}
|
||||
}
|
||||
end
|
||||
)
|
||||
|
||||
@@ -6,7 +6,7 @@ import subprocess
|
||||
emit(
|
||||
"""
|
||||
PKG_CONFIG ?= pkg-config
|
||||
PACKAGES := $(shell $(PKG_CONFIG) --list-all | cut -d' ' -f1)
|
||||
PACKAGES := $(shell $(PKG_CONFIG) --list-all | cut -d' ' -f1 | sort)
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
definerule("test",
|
||||
{
|
||||
srcs = { type="targets", default={} },
|
||||
},
|
||||
function (e)
|
||||
if vars.TESTS == "yes" then
|
||||
normalrule {
|
||||
name = e.name,
|
||||
ins = e.srcs,
|
||||
outleaves = { "log.txt" },
|
||||
commands = {
|
||||
"%{ins} > %{outs}",
|
||||
}
|
||||
}
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
@@ -234,7 +234,7 @@ namespace libusbp
|
||||
}
|
||||
|
||||
/*! Wrapper for libusbp_error_get_message(). */
|
||||
virtual const char * what() const noexcept
|
||||
virtual const char * what() const noexcept override
|
||||
{
|
||||
return libusbp_error_get_message(pointer);
|
||||
}
|
||||
|
||||
13
doc/using.md
13
doc/using.md
@@ -58,7 +58,14 @@ If _more_ than one device is plugged in, you need to specify which one to use
|
||||
with the `--usb.serial` parameter, which takes the device serial number as a
|
||||
parameter. You can find out the serial numbers by running the command without
|
||||
the `--usb.serial` parameter, and if more than one device is attached they will
|
||||
be listed. The serial number is also shown whenever a connection is made.
|
||||
be listed. The serial number is also shown whenever a connection is made. You
|
||||
can list all the detectable devices with:
|
||||
|
||||
```
|
||||
$ fluxengine test devices
|
||||
```
|
||||
|
||||
This will show you their serial numbers.
|
||||
|
||||
You _can_ work with more than one FluxEngine at the same time, using different
|
||||
invocations of the client; but be careful of USB bandwidth. If the devices are
|
||||
@@ -221,6 +228,10 @@ FluxEngine supports a number of ways to get or put flux. When using the `-s` or
|
||||
|
||||
Read from a Catweasel flux file. **Read only.**
|
||||
|
||||
- `dmk:<directory>`
|
||||
|
||||
Read from a Catweasel CMK directory. **Read only.**
|
||||
|
||||
- `<filename.a2r>`
|
||||
|
||||
Write to a AppleSauce flux file. **Write only.**
|
||||
|
||||
@@ -38,7 +38,7 @@ normalrule(
|
||||
ins=["./icon.png"],
|
||||
outs=["fluxengine.ico"],
|
||||
commands=[
|
||||
"convert {ins[0]} -resize 64x46 -define icon:auto-resize=64,48,32,16 {outs[0]}"
|
||||
"png2ico {outs[0]} {ins[0]}"
|
||||
],
|
||||
label="MAKEICON",
|
||||
)
|
||||
|
||||
28
lib/bytes.cc
28
lib/bytes.cc
@@ -71,6 +71,15 @@ Bytes::Bytes(
|
||||
{
|
||||
}
|
||||
|
||||
Bytes::Bytes(std::istream& istream, size_t len):
|
||||
_data(createVector(0)),
|
||||
_low(0),
|
||||
_high(0)
|
||||
{
|
||||
ByteWriter bw(*this);
|
||||
bw.append(istream, len);
|
||||
}
|
||||
|
||||
Bytes* Bytes::operator=(const Bytes& other)
|
||||
{
|
||||
_data = other._data;
|
||||
@@ -352,13 +361,24 @@ uint64_t ByteReader::read_be64()
|
||||
return ((uint64_t)read_be32() << 32) | read_be32();
|
||||
}
|
||||
|
||||
ByteWriter& ByteWriter::operator+=(std::istream& stream)
|
||||
ByteWriter& ByteWriter::append(std::istream& stream, size_t length)
|
||||
{
|
||||
Bytes buffer(4096);
|
||||
|
||||
while (stream.read((char*)buffer.begin(), buffer.size()))
|
||||
this->append(buffer);
|
||||
this->append(buffer.slice(0, stream.gcount()));
|
||||
while (length != 0)
|
||||
{
|
||||
size_t chunk = std::min((size_t)buffer.size(), length);
|
||||
if (!stream.read((char*)buffer.begin(), chunk))
|
||||
{
|
||||
this->append(buffer.slice(0, stream.gcount()));
|
||||
break;
|
||||
}
|
||||
else
|
||||
this->append(buffer);
|
||||
|
||||
length -= chunk;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
11
lib/bytes.h
11
lib/bytes.h
@@ -19,6 +19,7 @@ public:
|
||||
Bytes(std::shared_ptr<std::vector<uint8_t>> data,
|
||||
unsigned start,
|
||||
unsigned end);
|
||||
Bytes(std::istream& istream, size_t len = SIZE_MAX);
|
||||
|
||||
Bytes* operator=(const Bytes& other);
|
||||
|
||||
@@ -323,7 +324,10 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
ByteWriter& operator+=(std::istream& stream);
|
||||
ByteWriter& operator+=(std::istream& stream)
|
||||
{
|
||||
return this->append(stream);
|
||||
}
|
||||
|
||||
ByteWriter& append(const char* data)
|
||||
{
|
||||
@@ -340,10 +344,7 @@ public:
|
||||
return *this += data;
|
||||
}
|
||||
|
||||
ByteWriter& append(std::istream& stream)
|
||||
{
|
||||
return *this += stream;
|
||||
}
|
||||
ByteWriter& append(std::istream& stream, size_t length = SIZE_MAX);
|
||||
|
||||
ByteWriter& pad(unsigned count, uint8_t byte = 0);
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ enum FluxSourceSinkType {
|
||||
FLUXTYPE_SCP = 9;
|
||||
FLUXTYPE_TEST_PATTERN = 10;
|
||||
FLUXTYPE_VCD = 11;
|
||||
FLUXTYPE_DMK = 12;
|
||||
}
|
||||
|
||||
enum ImageReaderWriterType {
|
||||
|
||||
@@ -78,6 +78,14 @@ static const std::vector<FluxConstructor> fluxConstructors = {
|
||||
proto->set_type(FLUXTYPE_CWF);
|
||||
proto->mutable_cwf()->set_filename(s);
|
||||
}},
|
||||
{.name = "CatWeazle DMK directory",
|
||||
.pattern = std::regex("^dmk:(.*)$"),
|
||||
.source =
|
||||
[](auto& s, auto* proto)
|
||||
{
|
||||
proto->set_type(FLUXTYPE_DMK);
|
||||
proto->mutable_dmk()->set_directory(s);
|
||||
}},
|
||||
{.pattern = std::regex("^erase:$"),
|
||||
.source =
|
||||
[](auto& s, auto* proto)
|
||||
|
||||
39
lib/flags.h
39
lib/flags.h
@@ -87,15 +87,17 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
bool hasArgument() const
|
||||
bool hasArgument() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const std::string defaultValueAsString() const
|
||||
|
||||
const std::string defaultValueAsString() const override
|
||||
{
|
||||
return "";
|
||||
}
|
||||
void set(const std::string& value)
|
||||
|
||||
void set(const std::string& value) override
|
||||
{
|
||||
_callback();
|
||||
}
|
||||
@@ -119,15 +121,17 @@ public:
|
||||
return _value;
|
||||
}
|
||||
|
||||
bool hasArgument() const
|
||||
bool hasArgument() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const std::string defaultValueAsString() const
|
||||
|
||||
const std::string defaultValueAsString() const override
|
||||
{
|
||||
return "false";
|
||||
}
|
||||
void set(const std::string& value)
|
||||
|
||||
void set(const std::string& value) override
|
||||
{
|
||||
_value = true;
|
||||
}
|
||||
@@ -176,7 +180,7 @@ public:
|
||||
_value = _defaultValue = value;
|
||||
}
|
||||
|
||||
bool hasArgument() const
|
||||
bool hasArgument() const override
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -203,11 +207,12 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
const std::string defaultValueAsString() const
|
||||
const std::string defaultValueAsString() const override
|
||||
{
|
||||
return _defaultValue;
|
||||
}
|
||||
void set(const std::string& value)
|
||||
|
||||
void set(const std::string& value) override
|
||||
{
|
||||
_value = value;
|
||||
_callback(_value);
|
||||
@@ -230,11 +235,12 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
const std::string defaultValueAsString() const
|
||||
const std::string defaultValueAsString() const override
|
||||
{
|
||||
return std::to_string(_defaultValue);
|
||||
}
|
||||
void set(const std::string& value)
|
||||
|
||||
void set(const std::string& value) override
|
||||
{
|
||||
_value = std::stoi(value);
|
||||
_callback(_value);
|
||||
@@ -257,7 +263,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
const std::string defaultValueAsString() const;
|
||||
const std::string defaultValueAsString() const override;
|
||||
};
|
||||
|
||||
class DoubleFlag : public ValueFlag<double>
|
||||
@@ -275,11 +281,12 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
const std::string defaultValueAsString() const
|
||||
const std::string defaultValueAsString() const override
|
||||
{
|
||||
return std::to_string(_defaultValue);
|
||||
}
|
||||
void set(const std::string& value)
|
||||
|
||||
void set(const std::string& value) override
|
||||
{
|
||||
_value = std::stod(value);
|
||||
_callback(_value);
|
||||
@@ -302,11 +309,11 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
const std::string defaultValueAsString() const
|
||||
const std::string defaultValueAsString() const override
|
||||
{
|
||||
return _defaultValue ? "true" : "false";
|
||||
}
|
||||
void set(const std::string& value);
|
||||
void set(const std::string& value) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
36
lib/fluxsource/catweasel.cc
Normal file
36
lib/fluxsource/catweasel.cc
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "lib/globals.h"
|
||||
#include "lib/fluxmap.h"
|
||||
#include "lib/bytes.h"
|
||||
#include "lib/fluxsource/catweasel.h"
|
||||
|
||||
std::unique_ptr<Fluxmap> decodeCatweaselData(
|
||||
const Bytes& bytes, nanoseconds_t clock)
|
||||
{
|
||||
std::unique_ptr<Fluxmap> fluxmap(new Fluxmap);
|
||||
uint32_t pending = 0;
|
||||
bool oldindex = true;
|
||||
const uint8_t* ptr = bytes.begin();
|
||||
while (ptr != bytes.end())
|
||||
{
|
||||
uint32_t b = *ptr++;
|
||||
bool index = !!(b & 0x80);
|
||||
b &= 0x7f;
|
||||
if (b == 0x7f)
|
||||
{
|
||||
pending += 0x7f;
|
||||
continue;
|
||||
}
|
||||
b += pending;
|
||||
pending = 0;
|
||||
|
||||
double interval_ns = b * clock;
|
||||
fluxmap->appendInterval(interval_ns / NS_PER_TICK);
|
||||
fluxmap->appendPulse();
|
||||
|
||||
if (index && !oldindex)
|
||||
fluxmap->appendIndex();
|
||||
oldindex = index;
|
||||
}
|
||||
|
||||
return fluxmap;
|
||||
}
|
||||
10
lib/fluxsource/catweasel.h
Normal file
10
lib/fluxsource/catweasel.h
Normal file
@@ -0,0 +1,10 @@
|
||||
#ifndef CATWEASEL_H
|
||||
#define CATWEASEL_H
|
||||
|
||||
class Fluxmap;
|
||||
class Bytes;
|
||||
|
||||
extern std::unique_ptr<Fluxmap> decodeCatweaselData(
|
||||
const Bytes& bytes, nanoseconds_t clock);
|
||||
|
||||
#endif
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "lib/fluxmap.h"
|
||||
#include "lib/fluxsource/fluxsource.pb.h"
|
||||
#include "lib/fluxsource/fluxsource.h"
|
||||
#include "lib/fluxsource/catweasel.h"
|
||||
#include "lib/proto.h"
|
||||
#include <fstream>
|
||||
|
||||
@@ -50,10 +51,10 @@ public:
|
||||
switch (_header.clock_rate)
|
||||
{
|
||||
case 1:
|
||||
_clockRate = 14161000.0;
|
||||
_clockPeriod = 1e9 / 14161000.0;
|
||||
break;
|
||||
case 2:
|
||||
_clockRate = 28322000.0;
|
||||
_clockPeriod = 1e9 / 28322000.0;
|
||||
break;
|
||||
default:
|
||||
error("unsupported clock rate");
|
||||
@@ -65,7 +66,7 @@ public:
|
||||
_header.tracks * _header.step,
|
||||
_header.sides);
|
||||
std::cout << fmt::format(
|
||||
"CWF sample clock rate: {} MHz\n", _clockRate / 1e6);
|
||||
"CWF sample clock rate: {} MHz\n", 1e3 / _clockPeriod);
|
||||
|
||||
int tracks = _header.tracks * _header.sides;
|
||||
for (int i = 0; i < tracks; i++)
|
||||
@@ -87,47 +88,22 @@ public:
|
||||
}
|
||||
|
||||
public:
|
||||
std::unique_ptr<const Fluxmap> readSingleFlux(int track, int side)
|
||||
std::unique_ptr<const Fluxmap> readSingleFlux(int track, int side) override
|
||||
{
|
||||
const auto& p = _trackOffsets.find(std::make_pair(track, side));
|
||||
if (p == _trackOffsets.end())
|
||||
return std::make_unique<const Fluxmap>();
|
||||
|
||||
off_t pos = p->second.first;
|
||||
;
|
||||
size_t length = p->second.second;
|
||||
_if.seekg(pos);
|
||||
|
||||
std::unique_ptr<Fluxmap> fluxmap(new Fluxmap);
|
||||
uint32_t pending = 0;
|
||||
bool oldindex = true;
|
||||
for (size_t cursor = 0; cursor < length; cursor++)
|
||||
{
|
||||
uint32_t b = _if.get();
|
||||
bool index = !!(b & 0x80);
|
||||
b &= 0x7f;
|
||||
if (b == 0x7f)
|
||||
{
|
||||
pending += 0x7f;
|
||||
continue;
|
||||
}
|
||||
b += pending;
|
||||
pending = 0;
|
||||
|
||||
double interval_us = b * (1e6 / _clockRate);
|
||||
fluxmap->appendInterval(interval_us / US_PER_TICK);
|
||||
fluxmap->appendPulse();
|
||||
|
||||
if (index && !oldindex)
|
||||
fluxmap->appendIndex();
|
||||
oldindex = index;
|
||||
}
|
||||
Bytes fluxdata(_if, length);
|
||||
check_for_error();
|
||||
|
||||
return fluxmap;
|
||||
return decodeCatweaselData(fluxdata, _clockPeriod);
|
||||
}
|
||||
|
||||
void recalibrate() {}
|
||||
void recalibrate() override {}
|
||||
|
||||
private:
|
||||
void check_for_error()
|
||||
@@ -140,7 +116,7 @@ private:
|
||||
const CwfFluxSourceProto& _config;
|
||||
std::ifstream _if;
|
||||
CwfHeader _header;
|
||||
nanoseconds_t _clockRate;
|
||||
nanoseconds_t _clockPeriod;
|
||||
std::map<std::pair<int, int>, std::pair<off_t, size_t>> _trackOffsets;
|
||||
};
|
||||
|
||||
|
||||
77
lib/fluxsource/dmkfluxsource.cc
Normal file
77
lib/fluxsource/dmkfluxsource.cc
Normal file
@@ -0,0 +1,77 @@
|
||||
#include "lib/globals.h"
|
||||
#include "lib/fluxmap.h"
|
||||
#include "lib/fluxsource/fluxsource.pb.h"
|
||||
#include "lib/fluxsource/fluxsource.h"
|
||||
#include "lib/fluxsource/catweasel.h"
|
||||
#include "lib/proto.h"
|
||||
#include "lib/logger.h"
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
|
||||
class DmkFluxSourceIterator : public FluxSourceIterator
|
||||
{
|
||||
public:
|
||||
DmkFluxSourceIterator(const std::string& path, int track, int side):
|
||||
_path(path),
|
||||
_track(track),
|
||||
_side(side)
|
||||
{
|
||||
}
|
||||
|
||||
bool hasNext() const override
|
||||
{
|
||||
std::string p = getPath();
|
||||
return std::filesystem::exists(getPath());
|
||||
}
|
||||
|
||||
std::unique_ptr<const Fluxmap> next() override
|
||||
{
|
||||
std::string path = getPath();
|
||||
log("DMK: reading {}", path);
|
||||
std::ifstream ifstream(getPath(), std::ios::binary);
|
||||
if (!ifstream)
|
||||
return std::make_unique<Fluxmap>();
|
||||
_count++;
|
||||
|
||||
Bytes bytes(ifstream);
|
||||
return decodeCatweaselData(bytes, 1e9 / 7080500.0);
|
||||
}
|
||||
|
||||
private:
|
||||
const std::string getPath() const
|
||||
{
|
||||
return fmt::format(
|
||||
"{}/C_S{:01}T{:02}.{:03}", _path, _side, _track, _count);
|
||||
}
|
||||
|
||||
private:
|
||||
const std::string _path;
|
||||
const int _track;
|
||||
const int _side;
|
||||
int _count = 0;
|
||||
};
|
||||
|
||||
class DmkFluxSource : public FluxSource
|
||||
{
|
||||
public:
|
||||
DmkFluxSource(const DmkFluxSourceProto& config): _path(config.directory())
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
std::unique_ptr<FluxSourceIterator> readFlux(int track, int side) override
|
||||
{
|
||||
return std::make_unique<DmkFluxSourceIterator>(_path, track, side);
|
||||
}
|
||||
|
||||
void recalibrate() override {}
|
||||
|
||||
private:
|
||||
const std::string _path;
|
||||
};
|
||||
|
||||
std::unique_ptr<FluxSource> FluxSource::createDmkFluxSource(
|
||||
const DmkFluxSourceProto& config)
|
||||
{
|
||||
return std::unique_ptr<FluxSource>(new DmkFluxSource(config));
|
||||
}
|
||||
@@ -31,6 +31,9 @@ std::unique_ptr<FluxSource> FluxSource::create(const FluxSourceProto& config)
|
||||
case FLUXTYPE_CWF:
|
||||
return createCwfFluxSource(config.cwf());
|
||||
|
||||
case FLUXTYPE_DMK:
|
||||
return createDmkFluxSource(config.dmk());
|
||||
|
||||
case FLUXTYPE_FLUX:
|
||||
return createFl2FluxSource(config.fl2());
|
||||
|
||||
|
||||
@@ -37,6 +37,8 @@ private:
|
||||
const A2rFluxSourceProto& config);
|
||||
static std::unique_ptr<FluxSource> createCwfFluxSource(
|
||||
const CwfFluxSourceProto& config);
|
||||
static std::unique_ptr<FluxSource> createDmkFluxSource(
|
||||
const DmkFluxSourceProto& config);
|
||||
static std::unique_ptr<FluxSource> createEraseFluxSource(
|
||||
const EraseFluxSourceProto& config);
|
||||
static std::unique_ptr<FluxSource> createFl2FluxSource(
|
||||
@@ -109,7 +111,7 @@ class EmptyFluxSourceIterator : public FluxSourceIterator
|
||||
class TrivialFluxSource : public FluxSource
|
||||
{
|
||||
public:
|
||||
std::unique_ptr<FluxSourceIterator> readFlux(int track, int side);
|
||||
std::unique_ptr<FluxSourceIterator> readFlux(int track, int side) override;
|
||||
virtual std::unique_ptr<const Fluxmap> readSingleFlux(
|
||||
int track, int side) = 0;
|
||||
};
|
||||
|
||||
@@ -30,6 +30,11 @@ message CwfFluxSourceProto {
|
||||
(help) = ".cwf file to read flux from"];
|
||||
}
|
||||
|
||||
message DmkFluxSourceProto {
|
||||
optional string directory = 1 [
|
||||
(help) = "path to DMK directory"];
|
||||
}
|
||||
|
||||
message Fl2FluxSourceProto {
|
||||
optional string filename = 1 [default = "flux.fl2",
|
||||
(help) = ".fl2 file to read flux from"];
|
||||
@@ -39,13 +44,14 @@ message FlxFluxSourceProto {
|
||||
optional string directory = 1 [(help) = "path to FLX stream directory"];
|
||||
}
|
||||
|
||||
// NEXT: 12
|
||||
// NEXT: 13
|
||||
message FluxSourceProto {
|
||||
optional FluxSourceSinkType type = 9
|
||||
[default = FLUXTYPE_NOT_SET, (help) = "flux source type"];
|
||||
|
||||
optional A2rFluxSourceProto a2r = 11;
|
||||
optional CwfFluxSourceProto cwf = 7;
|
||||
optional DmkFluxSourceProto dmk = 12;
|
||||
optional EraseFluxSourceProto erase = 4;
|
||||
optional Fl2FluxSourceProto fl2 = 8;
|
||||
optional FlxFluxSourceProto flx = 10;
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
return readStream(_path, track, side);
|
||||
}
|
||||
|
||||
void recalibrate() {}
|
||||
void recalibrate() override {}
|
||||
|
||||
private:
|
||||
const std::string _path;
|
||||
|
||||
@@ -47,7 +47,7 @@ public:
|
||||
return std::make_unique<EmptyFluxSourceIterator>();
|
||||
}
|
||||
|
||||
void recalibrate() {}
|
||||
void recalibrate() override {}
|
||||
|
||||
private:
|
||||
const DiskFlux& _flux;
|
||||
|
||||
@@ -27,7 +27,7 @@ public:
|
||||
return fluxmap;
|
||||
}
|
||||
|
||||
void recalibrate() {}
|
||||
void recalibrate() override {}
|
||||
|
||||
private:
|
||||
const TestPatternFluxSourceProto& _config;
|
||||
|
||||
@@ -14,7 +14,7 @@ class D64ImageReader : public ImageReader
|
||||
public:
|
||||
D64ImageReader(const ImageReaderProto& config): ImageReader(config) {}
|
||||
|
||||
std::unique_ptr<Image> readImage()
|
||||
std::unique_ptr<Image> readImage() override
|
||||
{
|
||||
std::ifstream inputFile(
|
||||
_config.filename(), std::ios::in | std::ios::binary);
|
||||
|
||||
@@ -18,7 +18,7 @@ class D88ImageReader : public ImageReader
|
||||
public:
|
||||
D88ImageReader(const ImageReaderProto& config): ImageReader(config) {}
|
||||
|
||||
std::unique_ptr<Image> readImage()
|
||||
std::unique_ptr<Image> readImage() override
|
||||
{
|
||||
std::ifstream inputFile(
|
||||
_config.filename(), std::ios::in | std::ios::binary);
|
||||
|
||||
@@ -18,7 +18,7 @@ class DimImageReader : public ImageReader
|
||||
public:
|
||||
DimImageReader(const ImageReaderProto& config): ImageReader(config) {}
|
||||
|
||||
std::unique_ptr<Image> readImage()
|
||||
std::unique_ptr<Image> readImage() override
|
||||
{
|
||||
std::ifstream inputFile(
|
||||
_config.filename(), std::ios::in | std::ios::binary);
|
||||
|
||||
@@ -14,7 +14,7 @@ class DiskCopyImageReader : public ImageReader
|
||||
public:
|
||||
DiskCopyImageReader(const ImageReaderProto& config): ImageReader(config) {}
|
||||
|
||||
std::unique_ptr<Image> readImage()
|
||||
std::unique_ptr<Image> readImage() override
|
||||
{
|
||||
std::ifstream inputFile(
|
||||
_config.filename(), std::ios::in | std::ios::binary);
|
||||
|
||||
@@ -18,7 +18,7 @@ class FdiImageReader : public ImageReader
|
||||
public:
|
||||
FdiImageReader(const ImageReaderProto& config): ImageReader(config) {}
|
||||
|
||||
std::unique_ptr<Image> readImage()
|
||||
std::unique_ptr<Image> readImage() override
|
||||
{
|
||||
std::ifstream inputFile(
|
||||
_config.filename(), std::ios::in | std::ios::binary);
|
||||
|
||||
@@ -137,7 +137,7 @@ public:
|
||||
* <End of file>
|
||||
*/
|
||||
// clang-format on
|
||||
std::unique_ptr<Image> readImage()
|
||||
std::unique_ptr<Image> readImage() override
|
||||
{
|
||||
// Read File
|
||||
std::ifstream inputFile(
|
||||
|
||||
@@ -17,7 +17,7 @@ class ImgImageReader : public ImageReader
|
||||
public:
|
||||
ImgImageReader(const ImageReaderProto& config): ImageReader(config) {}
|
||||
|
||||
std::unique_ptr<Image> readImage()
|
||||
std::unique_ptr<Image> readImage() override
|
||||
{
|
||||
std::ifstream inputFile(
|
||||
_config.filename(), std::ios::in | std::ios::binary);
|
||||
|
||||
@@ -89,7 +89,7 @@ class Jv3ImageReader : public ImageReader
|
||||
public:
|
||||
Jv3ImageReader(const ImageReaderProto& config): ImageReader(config) {}
|
||||
|
||||
std::unique_ptr<Image> readImage()
|
||||
std::unique_ptr<Image> readImage() override
|
||||
{
|
||||
std::ifstream inputFile(
|
||||
_config.filename(), std::ios::in | std::ios::binary);
|
||||
|
||||
@@ -18,7 +18,7 @@ class NFDImageReader : public ImageReader
|
||||
public:
|
||||
NFDImageReader(const ImageReaderProto& config): ImageReader(config) {}
|
||||
|
||||
std::unique_ptr<Image> readImage()
|
||||
std::unique_ptr<Image> readImage() override
|
||||
{
|
||||
std::ifstream inputFile(
|
||||
_config.filename(), std::ios::in | std::ios::binary);
|
||||
|
||||
@@ -16,7 +16,7 @@ class NsiImageReader : public ImageReader
|
||||
public:
|
||||
NsiImageReader(const ImageReaderProto& config): ImageReader(config) {}
|
||||
|
||||
std::unique_ptr<Image> readImage()
|
||||
std::unique_ptr<Image> readImage() override
|
||||
{
|
||||
std::ifstream inputFile(
|
||||
_config.filename(), std::ios::in | std::ios::binary);
|
||||
|
||||
@@ -47,7 +47,7 @@ class Td0ImageReader : public ImageReader
|
||||
public:
|
||||
Td0ImageReader(const ImageReaderProto& config): ImageReader(config) {}
|
||||
|
||||
std::unique_ptr<Image> readImage()
|
||||
std::unique_ptr<Image> readImage() override
|
||||
{
|
||||
std::ifstream inputFile(
|
||||
_config.filename(), std::ios::in | std::ios::binary);
|
||||
|
||||
@@ -26,7 +26,7 @@ class D64ImageWriter : public ImageWriter
|
||||
public:
|
||||
D64ImageWriter(const ImageWriterProto& config): ImageWriter(config) {}
|
||||
|
||||
void writeImage(const Image& image)
|
||||
void writeImage(const Image& image) override
|
||||
{
|
||||
log("D64: writing triangular image");
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ class D88ImageWriter : public ImageWriter
|
||||
public:
|
||||
D88ImageWriter(const ImageWriterProto& config): ImageWriter(config) {}
|
||||
|
||||
void writeImage(const Image& image)
|
||||
void writeImage(const Image& image) override
|
||||
{
|
||||
const Geometry geometry = image.getGeometry();
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ class DiskCopyImageWriter : public ImageWriter
|
||||
public:
|
||||
DiskCopyImageWriter(const ImageWriterProto& config): ImageWriter(config) {}
|
||||
|
||||
void writeImage(const Image& image)
|
||||
void writeImage(const Image& image) override
|
||||
{
|
||||
const Geometry& geometry = image.getGeometry();
|
||||
|
||||
|
||||
@@ -155,7 +155,7 @@ class ImdImageWriter : public ImageWriter
|
||||
public:
|
||||
ImdImageWriter(const ImageWriterProto& config): ImageWriter(config) {}
|
||||
|
||||
void writeImage(const Image& image)
|
||||
void writeImage(const Image& image) override
|
||||
{
|
||||
const Geometry& geometry = image.getGeometry();
|
||||
unsigned numHeads;
|
||||
|
||||
@@ -17,7 +17,7 @@ class ImgImageWriter : public ImageWriter
|
||||
public:
|
||||
ImgImageWriter(const ImageWriterProto& config): ImageWriter(config) {}
|
||||
|
||||
void writeImage(const Image& image)
|
||||
void writeImage(const Image& image) override
|
||||
{
|
||||
const Geometry geometry = image.getGeometry();
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ class LDBSImageWriter : public ImageWriter
|
||||
public:
|
||||
LDBSImageWriter(const ImageWriterProto& config): ImageWriter(config) {}
|
||||
|
||||
void writeImage(const Image& image)
|
||||
void writeImage(const Image& image) override
|
||||
{
|
||||
LDBS ldbs;
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ class NsiImageWriter : public ImageWriter
|
||||
public:
|
||||
NsiImageWriter(const ImageWriterProto& config): ImageWriter(config) {}
|
||||
|
||||
void writeImage(const Image& image)
|
||||
void writeImage(const Image& image) override
|
||||
{
|
||||
const Geometry& geometry = image.getGeometry();
|
||||
bool mixedDensity = false;
|
||||
|
||||
@@ -16,7 +16,7 @@ class RawImageWriter : public ImageWriter
|
||||
public:
|
||||
RawImageWriter(const ImageWriterProto& config): ImageWriter(config) {}
|
||||
|
||||
void writeImage(const Image& image)
|
||||
void writeImage(const Image& image) override
|
||||
{
|
||||
const Geometry& geometry = image.getGeometry();
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@ private:
|
||||
}
|
||||
|
||||
public:
|
||||
int getVersion()
|
||||
int getVersion() override
|
||||
{
|
||||
struct any_frame f = {
|
||||
.f = {.type = F_FRAME_GET_VERSION_CMD, .size = sizeof(f)}
|
||||
@@ -133,7 +133,7 @@ public:
|
||||
return r->version;
|
||||
}
|
||||
|
||||
void seek(int track)
|
||||
void seek(int track) override
|
||||
{
|
||||
struct seek_frame f = {
|
||||
.f = {.type = F_FRAME_SEEK_CMD, .size = sizeof(f)},
|
||||
@@ -143,7 +143,7 @@ public:
|
||||
await_reply<struct any_frame>(F_FRAME_SEEK_REPLY);
|
||||
}
|
||||
|
||||
void recalibrate()
|
||||
void recalibrate() override
|
||||
{
|
||||
struct any_frame f = {
|
||||
.f = {.type = F_FRAME_RECALIBRATE_CMD, .size = sizeof(f)},
|
||||
@@ -152,7 +152,7 @@ public:
|
||||
await_reply<struct any_frame>(F_FRAME_RECALIBRATE_REPLY);
|
||||
}
|
||||
|
||||
nanoseconds_t getRotationalPeriod(int hardSectorCount)
|
||||
nanoseconds_t getRotationalPeriod(int hardSectorCount) override
|
||||
{
|
||||
struct measurespeed_frame f = {
|
||||
.f = {.type = F_FRAME_MEASURE_SPEED_CMD, .size = sizeof(f)},
|
||||
@@ -164,7 +164,7 @@ public:
|
||||
return r->period_ms * 1000000;
|
||||
}
|
||||
|
||||
void testBulkWrite()
|
||||
void testBulkWrite() override
|
||||
{
|
||||
struct any_frame f = {
|
||||
.f = {.type = F_FRAME_BULK_WRITE_TEST_CMD, .size = sizeof(f)}
|
||||
@@ -204,7 +204,7 @@ public:
|
||||
await_reply<struct any_frame>(F_FRAME_BULK_WRITE_TEST_REPLY);
|
||||
}
|
||||
|
||||
void testBulkRead()
|
||||
void testBulkRead() override
|
||||
{
|
||||
struct any_frame f = {
|
||||
.f = {.type = F_FRAME_BULK_READ_TEST_CMD, .size = sizeof(f)}
|
||||
@@ -242,7 +242,7 @@ public:
|
||||
Bytes read(int side,
|
||||
bool synced,
|
||||
nanoseconds_t readTime,
|
||||
nanoseconds_t hardSectorThreshold)
|
||||
nanoseconds_t hardSectorThreshold) override
|
||||
{
|
||||
struct read_frame f = {
|
||||
.f = {.type = F_FRAME_READ_CMD, .size = sizeof(f)},
|
||||
@@ -265,7 +265,9 @@ public:
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void write(int side, const Bytes& bytes, nanoseconds_t hardSectorThreshold)
|
||||
void write(int side,
|
||||
const Bytes& bytes,
|
||||
nanoseconds_t hardSectorThreshold) override
|
||||
{
|
||||
unsigned safelen = bytes.size() & ~(FRAME_SIZE - 1);
|
||||
Bytes safeBytes = bytes.slice(0, safelen);
|
||||
@@ -287,7 +289,7 @@ public:
|
||||
await_reply<struct any_frame>(F_FRAME_WRITE_REPLY);
|
||||
}
|
||||
|
||||
void erase(int side, nanoseconds_t hardSectorThreshold)
|
||||
void erase(int side, nanoseconds_t hardSectorThreshold) override
|
||||
{
|
||||
struct erase_frame f = {
|
||||
.f = {.type = F_FRAME_ERASE_CMD, .size = sizeof(f)},
|
||||
@@ -300,7 +302,7 @@ public:
|
||||
await_reply<struct any_frame>(F_FRAME_ERASE_REPLY);
|
||||
}
|
||||
|
||||
void setDrive(int drive, bool high_density, int index_mode)
|
||||
void setDrive(int drive, bool high_density, int index_mode) override
|
||||
{
|
||||
struct set_drive_frame f = {
|
||||
.f = {.type = F_FRAME_SET_DRIVE_CMD, .size = sizeof(f)},
|
||||
@@ -312,7 +314,7 @@ public:
|
||||
await_reply<struct any_frame>(F_FRAME_SET_DRIVE_REPLY);
|
||||
}
|
||||
|
||||
void measureVoltages(struct voltages_frame* voltages)
|
||||
void measureVoltages(struct voltages_frame* voltages) override
|
||||
{
|
||||
struct any_frame f = {
|
||||
{.type = F_FRAME_MEASURE_VOLTAGES_CMD, .size = sizeof(f)},
|
||||
|
||||
@@ -109,7 +109,7 @@ public:
|
||||
do_command({CMD_SET_BUS_TYPE, 3, (uint8_t)config.bus_type()});
|
||||
}
|
||||
|
||||
int getVersion()
|
||||
int getVersion() override
|
||||
{
|
||||
do_command({CMD_GET_INFO, 3, GETINFO_FIRMWARE});
|
||||
|
||||
@@ -124,17 +124,17 @@ public:
|
||||
return br.read_be16();
|
||||
}
|
||||
|
||||
void recalibrate()
|
||||
void recalibrate() override
|
||||
{
|
||||
seek(0);
|
||||
}
|
||||
|
||||
void seek(int track)
|
||||
void seek(int track) override
|
||||
{
|
||||
do_command({CMD_SEEK, 3, (uint8_t)track});
|
||||
}
|
||||
|
||||
nanoseconds_t getRotationalPeriod(int hardSectorCount)
|
||||
nanoseconds_t getRotationalPeriod(int hardSectorCount) override
|
||||
{
|
||||
if (hardSectorCount != 0)
|
||||
error("hard sectors are currently unsupported on the Greaseweazle");
|
||||
@@ -214,7 +214,7 @@ public:
|
||||
return _revolutions;
|
||||
}
|
||||
|
||||
void testBulkWrite()
|
||||
void testBulkWrite() override
|
||||
{
|
||||
std::cout << "Writing data: " << std::flush;
|
||||
const int LEN = 10 * 1024 * 1024;
|
||||
@@ -264,7 +264,7 @@ public:
|
||||
int((LEN / 1024.0) / elapsed_time));
|
||||
}
|
||||
|
||||
void testBulkRead()
|
||||
void testBulkRead() override
|
||||
{
|
||||
std::cout << "Reading data: " << std::flush;
|
||||
const int LEN = 10 * 1024 * 1024;
|
||||
@@ -309,7 +309,7 @@ public:
|
||||
Bytes read(int side,
|
||||
bool synced,
|
||||
nanoseconds_t readTime,
|
||||
nanoseconds_t hardSectorThreshold)
|
||||
nanoseconds_t hardSectorThreshold) override
|
||||
{
|
||||
if (hardSectorThreshold != 0)
|
||||
error("hard sectors are currently unsupported on the Greaseweazle");
|
||||
@@ -362,7 +362,9 @@ public:
|
||||
return fldata;
|
||||
}
|
||||
|
||||
void write(int side, const Bytes& fldata, nanoseconds_t hardSectorThreshold)
|
||||
void write(int side,
|
||||
const Bytes& fldata,
|
||||
nanoseconds_t hardSectorThreshold) override
|
||||
{
|
||||
if (hardSectorThreshold != 0)
|
||||
error("hard sectors are currently unsupported on the Greaseweazle");
|
||||
@@ -385,7 +387,7 @@ public:
|
||||
do_command({CMD_GET_FLUX_STATUS, 2});
|
||||
}
|
||||
|
||||
void erase(int side, nanoseconds_t hardSectorThreshold)
|
||||
void erase(int side, nanoseconds_t hardSectorThreshold) override
|
||||
{
|
||||
if (hardSectorThreshold != 0)
|
||||
error("hard sectors are currently unsupported on the Greaseweazle");
|
||||
@@ -403,14 +405,14 @@ public:
|
||||
do_command({CMD_GET_FLUX_STATUS, 2});
|
||||
}
|
||||
|
||||
void setDrive(int drive, bool high_density, int index_mode)
|
||||
void setDrive(int drive, bool high_density, int index_mode) override
|
||||
{
|
||||
do_command({CMD_SELECT, 3, (uint8_t)drive});
|
||||
do_command({CMD_MOTOR, 4, (uint8_t)drive, 1});
|
||||
do_command({CMD_SET_PIN, 4, 2, (uint8_t)(high_density ? 1 : 0)});
|
||||
}
|
||||
|
||||
void measureVoltages(struct voltages_frame* voltages)
|
||||
void measureVoltages(struct voltages_frame* voltages) override
|
||||
{
|
||||
error("unsupported operation on the Greaseweazle");
|
||||
}
|
||||
|
||||
@@ -113,12 +113,12 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t capabilities() const
|
||||
uint32_t capabilities() const override
|
||||
{
|
||||
return OP_GETFSDATA | OP_LIST | OP_GETFILE | OP_GETDIRENT;
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> getMetadata()
|
||||
std::map<std::string, std::string> getMetadata() override
|
||||
{
|
||||
AcornDfsDirectory dir(this);
|
||||
|
||||
@@ -130,12 +130,12 @@ public:
|
||||
return attributes;
|
||||
}
|
||||
|
||||
FilesystemStatus check()
|
||||
FilesystemStatus check() override
|
||||
{
|
||||
return FS_OK;
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<Dirent>> list(const Path& path)
|
||||
std::vector<std::shared_ptr<Dirent>> list(const Path& path) override
|
||||
{
|
||||
if (!path.empty())
|
||||
throw FileNotFoundException();
|
||||
@@ -148,7 +148,7 @@ public:
|
||||
return result;
|
||||
}
|
||||
|
||||
Bytes getFile(const Path& path)
|
||||
Bytes getFile(const Path& path) override
|
||||
{
|
||||
AcornDfsDirectory dir(this);
|
||||
auto dirent = dir.findFile(path);
|
||||
@@ -166,7 +166,7 @@ public:
|
||||
return data;
|
||||
}
|
||||
|
||||
std::shared_ptr<Dirent> getDirent(const Path& path)
|
||||
std::shared_ptr<Dirent> getDirent(const Path& path) override
|
||||
{
|
||||
AcornDfsDirectory dir(this);
|
||||
return dir.findFile(path);
|
||||
|
||||
@@ -141,7 +141,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t capabilities() const
|
||||
uint32_t capabilities() const override
|
||||
{
|
||||
return OP_GETFSDATA | OP_LIST | OP_GETFILE | OP_GETDIRENT;
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t capabilities() const
|
||||
uint32_t capabilities() const override
|
||||
{
|
||||
return OP_GETFSDATA | OP_LIST | OP_GETFILE | OP_GETDIRENT;
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
uint32_t capabilities() const
|
||||
uint32_t capabilities() const override
|
||||
{
|
||||
return OP_GETFSDATA | OP_LIST | OP_GETFILE | OP_GETDIRENT;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ cxxprogram(
|
||||
"./fe-rpm.cc",
|
||||
"./fe-seek.cc",
|
||||
"./fe-testbandwidth.cc",
|
||||
"./fe-testdevices.cc",
|
||||
"./fe-testvoltages.cc",
|
||||
"./fe-write.cc",
|
||||
"./fileutils.cc",
|
||||
|
||||
@@ -17,6 +17,7 @@ static StringFlag sourceFlux({"-s", "--source"},
|
||||
|
||||
int mainRpm(int argc, const char* argv[])
|
||||
{
|
||||
globalConfig().set("flux_source.type", "FLUXTYPE_DRIVE");
|
||||
flags.parseFlagsWithConfigFiles(argc, argv, {});
|
||||
|
||||
if (globalConfig()->flux_source().type() != FLUXTYPE_DRIVE)
|
||||
|
||||
41
src/fe-testdevices.cc
Normal file
41
src/fe-testdevices.cc
Normal file
@@ -0,0 +1,41 @@
|
||||
#include "lib/globals.h"
|
||||
#include "lib/flags.h"
|
||||
#include "lib/usb/usbfinder.h"
|
||||
#include <fmt/format.h>
|
||||
|
||||
static FlagGroup flags;
|
||||
|
||||
int mainTestDevices(int argc, const char* argv[])
|
||||
{
|
||||
flags.parseFlagsWithConfigFiles(argc, argv, {});
|
||||
|
||||
auto candidates = findUsbDevices();
|
||||
switch (candidates.size())
|
||||
{
|
||||
case 0:
|
||||
fmt::print("Detected no devices.\n");
|
||||
break;
|
||||
|
||||
case 1:
|
||||
fmt::print("Detected one device:\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
fmt::print("Detected {} devices:\n", candidates.size());
|
||||
}
|
||||
|
||||
if (!candidates.empty())
|
||||
{
|
||||
fmt::print(
|
||||
"{:15} {:30} {}\n", "Type", "Serial number", "Port (if any)");
|
||||
for (auto& candidate : candidates)
|
||||
{
|
||||
fmt::print("{:15} {:30} {}\n",
|
||||
getDeviceName(candidate->type),
|
||||
candidate->serial,
|
||||
candidate->serialPort);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -23,6 +23,7 @@ extern command_cb mainRm;
|
||||
extern command_cb mainRpm;
|
||||
extern command_cb mainSeek;
|
||||
extern command_cb mainTestBandwidth;
|
||||
extern command_cb mainTestDevices;
|
||||
extern command_cb mainTestVoltages;
|
||||
extern command_cb mainWrite;
|
||||
|
||||
@@ -69,6 +70,7 @@ static std::vector<Command> analysables =
|
||||
static std::vector<Command> testables =
|
||||
{
|
||||
{ "bandwidth", mainTestBandwidth, "Measures your USB bandwidth.", },
|
||||
{ "devices", mainTestDevices, "Displays all detected devices.", },
|
||||
{ "voltages", mainTestVoltages, "Measures the FDD bus voltages.", },
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
@@ -47,12 +47,16 @@ layout {
|
||||
encoder {
|
||||
ibm {
|
||||
trackdata {
|
||||
target_rotational_period_ms: 167
|
||||
target_clock_period_us: 3.333
|
||||
target_rotational_period_ms: 166
|
||||
target_clock_period_us: 3.33
|
||||
emit_iam: false
|
||||
gap0: 80
|
||||
gap2: 22
|
||||
gap3: 34
|
||||
use_fm: true
|
||||
gap0: 0x10
|
||||
gap2: 0x09
|
||||
gap3: 0x10
|
||||
idam_byte: 0xf57e
|
||||
dam_byte: 0xf56f
|
||||
gap_fill_byte: 0xffff
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,12 @@ emit(
|
||||
"""
|
||||
WX_CONFIG ?= wx-config
|
||||
ifneq ($(strip $(shell command -v $(WX_CONFIG) >/dev/null 2>&1; echo $$?)),0)
|
||||
$(error Required binary 'wx-config' not found.)
|
||||
endif
|
||||
|
||||
WX_CFLAGS = $(error Required binary 'wx-config' not found.)
|
||||
WX_LDFLAGS = $(error Required binary 'wx-config' not found.)
|
||||
else
|
||||
WX_CFLAGS := $(shell $(WX_CONFIG) --cxxflags core base adv aui richtext)
|
||||
WX_LDFLAGS := $(shell $(WX_CONFIG) --libs core base adv aui richtext)
|
||||
endif
|
||||
"""
|
||||
)
|
||||
|
||||
@@ -99,7 +100,7 @@ if config.osx:
|
||||
"dylibbundler -of -x {outs[0]}/Contents/MacOS/fluxengine-gui -b -d {outs[0]}/Contents/libs -cd > /dev/null",
|
||||
"cp $$(brew --prefix wxwidgets)/README.md $@/Contents/libs/wxWidgets.md",
|
||||
"cp $$(brew --prefix protobuf)/LICENSE $@/Contents/libs/protobuf.txt",
|
||||
"cp $$(brew --prefix fmt)/LICENSE.rst $@/Contents/libs/fmt.rst",
|
||||
"cp $$(brew --prefix fmt)/LICENSE* $@/Contents/libs/fmt.rst",
|
||||
"cp $$(brew --prefix libpng)/LICENSE $@/Contents/libs/libpng.txt",
|
||||
"cp $$(brew --prefix libjpeg)/README $@/Contents/libs/libjpeg.txt",
|
||||
"cp $$(brew --prefix abseil)/LICENSE $@/Contents/libs/abseil.txt",
|
||||
|
||||
@@ -33,7 +33,7 @@ static inline R runOnUiThread(std::function<R()> callback)
|
||||
class FluxEngineApp : public wxApp, public wxThreadHelper
|
||||
{
|
||||
public:
|
||||
virtual bool OnInit();
|
||||
virtual bool OnInit() override;
|
||||
void RunOnWorkerThread(std::function<void()> callback);
|
||||
|
||||
private:
|
||||
@@ -44,7 +44,7 @@ public:
|
||||
bool IsWorkerThreadRunning();
|
||||
|
||||
protected:
|
||||
virtual wxThread::ExitCode Entry();
|
||||
virtual wxThread::ExitCode Entry() override;
|
||||
|
||||
private:
|
||||
static wxWindow* CreateMainWindow();
|
||||
|
||||
@@ -26,7 +26,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
wxEvent* Clone() const
|
||||
wxEvent* Clone() const override
|
||||
{
|
||||
return new ExecEvent(*this);
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
wxEvent* Clone() const
|
||||
wxEvent* Clone() const override
|
||||
{
|
||||
return new EditorSaveEvent(*this);
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ public:
|
||||
wxTextCtrl* GetTextControl() const;
|
||||
|
||||
private:
|
||||
void OnClose(wxCloseEvent& event);
|
||||
void OnClose(wxCloseEvent& event) override;
|
||||
|
||||
private:
|
||||
bool _autodestroy;
|
||||
|
||||
@@ -24,7 +24,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
wxEvent* Clone() const
|
||||
wxEvent* Clone() const override
|
||||
{
|
||||
return new TrackSelectionEvent(*this);
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<const Sector> get(
|
||||
unsigned track, unsigned side, unsigned sectorId)
|
||||
unsigned track, unsigned side, unsigned sectorId) override
|
||||
{
|
||||
auto s = _image.get(track, side, sectorId);
|
||||
if (!s)
|
||||
@@ -27,7 +27,7 @@ namespace
|
||||
}
|
||||
|
||||
std::shared_ptr<Sector> put(
|
||||
unsigned track, unsigned side, unsigned sectorId)
|
||||
unsigned track, unsigned side, unsigned sectorId) override
|
||||
{
|
||||
return _image.put(track, side, sectorId);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user