Compare commits

...

126 Commits
lif ... dmk

Author SHA1 Message Date
David Given
93e0251bab Add the boilerplate for the Q1 decoder. 2023-11-02 21:41:11 +01:00
David Given
a7cb7eb995 Add missing files... 2023-11-02 01:22:09 +01:00
David Given
29f5feb34d Add support for DMK directory streams. 2023-11-02 01:17:44 +01:00
David Given
5dc60db7b6 When installing files, remember to create the directories. 2023-10-31 00:48:50 +01:00
David Given
fb9f7fe445 Merge pull request #723 from davidgiven/fixes2
Miscellaneous bugfixes.
2023-10-30 23:54:18 +01:00
David Given
a548471652 Add missing files. 2023-10-30 23:35:27 +01:00
David Given
3e47d66644 Put back the standard binaries, tests, install, install-bin makefile targets. 2023-10-30 23:30:18 +01:00
David Given
3bfa45a80c Remember to build with optimisation on. 2023-10-30 23:11:20 +01:00
David Given
2d717af4db The flux and image file pickers can now create new files. 2023-10-30 23:07:36 +01:00
David Given
533b217c8f Eliminate the broken tpi system for a simple drive/format type field. 2023-10-29 21:10:14 +01:00
David Given
ff1fb761f2 Update documentation (last time was wrong). 2023-10-29 21:06:56 +01:00
David Given
95d49add2c Don't show '$formats' for the format list. 2023-10-29 11:18:21 +01:00
David Given
8b75609b70 Update line endings. 2023-10-29 11:18:05 +01:00
David Given
b8929dd589 Fix Windows dependencies. 2023-10-28 13:33:10 +02:00
David Given
2fd29f8786 Merge pull request #720 from davidgiven/build
Rework the build system... again.
2023-10-28 13:17:56 +02:00
David Given
38408820ca Update the release workflow. 2023-10-28 12:52:25 +02:00
David Given
43e6840e78 Try and set the imagemagick time limit? 2023-10-28 00:49:19 +01:00
David Given
15908c52bd Typo fix. 2023-10-27 22:12:46 +01:00
David Given
c90b0e7dc2 Try and fix dependencies again... 2023-10-27 22:10:00 +01:00
David Given
d2ff9806bd Enable build logging. 2023-10-27 21:47:22 +01:00
David Given
1e6993c12d Add missing dependency. 2023-10-27 21:39:55 +01:00
David Given
1122344016 Try to correctly build the manifest this time. 2023-10-27 21:28:47 +01:00
David Given
0dbce00fe4 Try building a Windows manifest. 2023-10-27 21:38:44 +02:00
David Given
5af0b68e06 Add the corpus tests. 2023-10-27 20:43:46 +02:00
dg
6038a11671 Update the README. 2023-10-26 19:31:58 +00:00
dg
dcb92db519 Remove old build system. 2023-10-26 19:29:01 +00:00
dg
dcaeabacc6 --no_warn_duplicate_libraries is apparently too new for github CI... 2023-10-26 19:08:21 +00:00
dg
a2a5c7eff0 Build Windows with all CPUs. 2023-10-26 19:07:43 +00:00
dg
e1cf927bf3 Typo fix. 2023-10-26 18:35:21 +00:00
dg
8fd98d674a Additional windows fixes. 2023-10-26 18:26:10 +00:00
David Given
fd884027c0 Try using the mingw python. 2023-10-26 01:28:58 +02:00
dg
26bd467f79 Make the Windows binaries build. 2023-10-25 21:55:40 +00:00
David Given
c7f22c0dab Build the GUI on OSX. 2023-10-25 22:15:32 +02:00
David Given
92d44f6ae3 Add missing file. 2023-10-25 22:15:09 +02:00
David Given
9143f477b2 Build OSX with all CPUs. 2023-10-25 00:56:45 +02:00
David Given
1a519bf837 Attempt to make build on OSX. 2023-10-25 00:49:39 +02:00
David Given
ca6b90f8c1 Split C and C++ libraries, so that you can use C++ compiler flags. Build with
C++17.
2023-10-24 22:00:09 +02:00
David Given
44fc532d63 Build the documentation. 2023-10-24 00:49:05 +02:00
David Given
6a6cd025c0 Install Python on Windows. 2023-10-24 00:27:04 +02:00
David Given
d769f90704 Increase processor count. 2023-10-23 01:18:33 +02:00
David Given
9d8e3b21ba I think something's wrong with the apt installer. 2023-10-23 01:12:50 +02:00
David Given
dabdfec3e7 Try more setup. 2023-10-23 01:11:15 +02:00
David Given
6a00653d1e Don't use xxd to objectify files. 2023-10-23 01:03:28 +02:00
David Given
8fb786094f Something's wrong with Ubuntu's wx-config setup. 2023-10-23 00:00:29 +02:00
David Given
87e978c817 And again. 2023-10-22 23:10:52 +02:00
David Given
4a31046c9c Adjust dependencies, again... 2023-10-22 23:09:52 +02:00
David Given
db420b3495 Adjust the way packages are detected. 2023-10-22 23:07:20 +02:00
David Given
c81dc166bc Adjust dependencies. 2023-10-22 23:03:44 +02:00
David Given
07aa416975 Make the tests work. 2023-10-22 22:57:54 +02:00
David Given
627820cddc Build the utilities. 2023-10-22 21:35:27 +02:00
David Given
a24fe420c4 We can now build both the CLI and GUI binaries! 2023-10-22 21:20:47 +02:00
David Given
986be921f4 First working command-line executable. 2023-10-22 19:18:14 +02:00
David Given
f5f223f622 First steps towards reworking the build system... again. 2023-10-21 23:02:46 +02:00
David Given
bbdfa0d651 Merge pull request #717 from kristomu/const-correct
Fix const-correct/discards qualifiers error.
2023-09-27 10:08:26 +02:00
K. M
e6bb0cb463 Fix const-correct/discards qualifiers error. 2023-09-27 01:19:17 +02:00
David Given
9e61670116 Merge pull request #656 from davidgiven/psos
Improve pSOS file system handling.
2023-08-20 22:00:51 +02:00
David Given
3876c07164 Merge branch 'master' into psos 2023-08-20 21:42:13 +02:00
David Given
ed315eade9 Merge pull request #668 from davidgiven/ms2000
Add basic support for the MS2000 Microdos file system.
2023-08-19 23:54:27 +02:00
David Given
7456fd0c90 Make the MS2000 stuff work again. Write documentation. 2023-08-19 23:29:55 +02:00
David Given
44160e66ac Merge branch 'master' into ms2000 2023-08-19 22:59:31 +02:00
David Given
9bd969a57b Merge pull request #688 from davidgiven/lif
Add HP9122 support; fix HP9121 support.
2023-08-19 22:55:39 +02:00
David Given
0b585078d8 Merge pull request #704 from ejona86/micropolis-ecc
Micropolis: Add Vector ECC support
2023-08-19 21:54:22 +02:00
David Given
0d495ed934 Merge pull request #710 from davidgiven/usb
Make work on FreeBSD
2023-08-19 21:23:54 +02:00
David Given
95b703b1ea Tidy reporting of USB errors. 2023-08-19 20:46:41 +02:00
David Given
688061397b Adjust error messages. 2023-08-19 20:39:55 +02:00
Poul-Henning Kamp
1f00176455 Make the non-gui executable build on FreeBSD 2023-08-14 19:51:21 +00:00
David Given
90da6b1e72 Merge pull request #706 from ejona86/pkg-config-protobuf
Makefile: Eagerly run pkg-config for protobuf
2023-08-06 01:12:49 +02:00
Eric Anderson
4deb45dc3f Makefile: Eagerly run pkg-config for protobuf
Protobuf added a dependency on absl and now pkg-config is incredibly
slow. `pkg-config --libs protobuf` and `--cflags` each take around 1.5
seconds on my laptop. Running pkg-config only once reduces a 100%
incremental build for 'make all' from 90 seconds to 3.2 seconds.

Unfortunately we will pay the 3 seconds every time we execute make, even
for something that doesn't need protobuf.
2023-08-05 13:02:50 -07:00
David Given
eeec5d106a Update missing file. 2023-08-02 14:08:38 +02:00
David Given
4e42d1d197 Release and ccpp workflows now run in different environments. 2023-08-02 14:08:19 +02:00
David Given
495d08c447 Merge pull request #705 from davidgiven/d20
Update D20 documentation.
2023-08-02 13:46:10 +02:00
David Given
1b859015ae Update documentation. 2023-08-02 13:42:23 +02:00
David Given
3db2109e01 Merge pull request #700 from davidgiven/d20
Add support for the Roland-D20 filesystem.
2023-07-31 23:01:49 +01:00
David Given
294ac87503 Update documentation for the Roland D20 format. 2023-07-31 23:36:45 +02:00
David Given
c297adb0c7 Try to fix Mac builds. 2023-07-31 22:30:52 +02:00
David Given
446b965794 Handle Roland extents properly if the directory entries are in the wrong order.
Deal with block numbers >39 (they go in the bottom of the disk).
2023-07-31 22:20:08 +02:00
Eric Anderson
96d4df296d Micropolis: Add Vector ECC support 2023-07-29 14:03:08 -07:00
David Given
a149aac0e9 Merge pull request #702 from ejona86/micropolis-encodedecode
Micropolis: Fix encoder and decoder to support encodedecodetest
2023-07-29 17:20:58 +01:00
David Given
aacc7be9f3 Merge pull request #703 from ejona86/vgi-hcs
Micropolis: Add missing HCS order for VGI
2023-07-29 17:17:44 +01:00
Eric Anderson
7409955701 Micropolis: Add missing HCS order for VGI 2023-07-29 07:12:35 -07:00
Eric Anderson
c623d95a80 Micropolis: Fix encoder and decoder to support encodedecodetest
These changes should not impact reading/writing from real disks. This
includes a bug fix to Fluxmap where it might miss a trailing interval
when adding bits, as mentioned in #333.

With the Fluxmap bug fixed, the encoder now includes index pulses in its
output. The decoder was relaxed to allow reading precisely one track.

We don't actually add an encodedecodetest for micropolis, though,
because the SCP encoder is unhappy with so many revolutions.
2023-07-29 07:08:23 -07:00
David Given
1927cc7fe1 Fix issue where trying to rename files by clicking on the tree wasn't working. 2023-07-27 23:44:33 +02:00
David Given
4eca254daf Add support for renaming files. 2023-07-27 23:44:04 +02:00
David Given
c7d4fee3f6 Add support for deleting files. 2023-07-27 23:19:50 +02:00
David Given
a6f798ae5b Mangle and demangle filenames. Remember to write the correct extent numbers in
multiextent files.
2023-07-27 23:09:57 +02:00
David Given
c9ae836e52 Add very brittle write support. 2023-07-27 22:49:10 +02:00
David Given
e3ffa63f7f Make sure that the rotational speed is measured even if reads are done through
Browse Disk.
2023-07-27 22:14:48 +02:00
David Given
4ffc2cc1dc Add support for, hopefully, multi-extent files. 2023-07-27 00:30:44 +02:00
David Given
7f9ba14687 Correct erroneous index. 2023-07-26 22:37:56 +02:00
David Given
a24933e272 Merge from master. 2023-07-26 22:33:40 +02:00
David Given
20bdacbecf Add initial support for the Roland-D20 filesystem. 2023-07-26 22:31:20 +02:00
David Given
ab9d6cf5ed Merge pull request #699 from davidgiven/wx
UI improvements
2023-07-25 23:03:02 +01:00
David Given
1f5903a9a0 Don't use std::filesystem; it makes life harder on Windows with its wide
strings.
2023-07-25 23:35:01 +02:00
David Given
bb073b6bb3 Apparently Mingw can't automatically convert from path to string. 2023-07-25 23:23:04 +02:00
David Given
516241f8f5 Replace the image read file picker with a simple one. 2023-07-25 23:11:52 +02:00
David Given
977b6831a0 When reading Kryoflux streams, you can specify any file in the directory and it
will work (as the GUI now forces you to do this).
2023-07-25 22:48:17 +02:00
David Given
c61effb54f Add a file type box to the flux source selection page. 2023-07-25 22:27:09 +02:00
David Given
346d989944 When reading Kryoflux streams, allow the user to specify any file within the
directory and have it work (as that's what the GUI does now).
2023-07-25 22:51:34 +02:00
David Given
60a73c8d1e Add a file type box to the flux source selection page. 2023-07-25 22:27:09 +02:00
dg
e52db4a837 Typo fix. 2023-07-24 20:56:37 +00:00
dg
4e317643bc Try and install compatible versions of protobuf. 2023-07-24 20:53:51 +00:00
David Given
5f520bf375 Merge pull request #698 from davidgiven/zilogmcz
Add support for the ZDOS filesystem for the Zilog MCZ.
2023-07-24 22:16:33 +02:00
David Given
2efe521b3a Update documentation. 2023-07-24 21:48:37 +02:00
David Given
5c21103646 Get the ZDOS filesystem driver working. 2023-07-24 21:46:49 +02:00
David Given
9444696f37 Merge pull request #697 from davidgiven/ro
Allow read-only flux and image in the GUI.
2023-07-24 08:20:39 +02:00
David Given
082fe4e787 Hack in boilerplate for a ZDos filesystem. 2023-07-24 08:18:18 +02:00
David Given
5e13cf23f9 Allow read-only image reader/writers in the GUI. 2023-07-24 07:53:47 +02:00
David Given
8f98a1f557 Consolidate the image constructors in the same way that's been done for the
flux constructors.
2023-07-24 07:50:16 +02:00
David Given
5b21e8798b Allow read-only flux sources in the GUI. 2023-07-24 07:39:59 +02:00
David Given
b9ef5b7db8 Rename all the flux and image types to prefix the enums, due to them being in
the global namespace now.
2023-07-24 02:18:53 +02:00
David Given
9867f8c302 Combine enums for flux source/sink types. config.cc now knows whether they're
read-only, write-only, and read-write.
2023-07-24 00:50:54 +02:00
David Given
315889faf6 Warning fix. 2023-07-23 22:49:23 +02:00
David Given
798e8fee89 Merge pull request #692 from davidgiven/protobuf
Rename the `requires` config field to `prerequisite`
2023-07-08 00:43:15 +02:00
dg
e1c49db329 Use brew --prefix to detect the installation path when copying licenses from
packages.
2023-07-07 22:10:52 +00:00
dg
dae9537472 Warning fixes. 2023-07-07 21:51:24 +00:00
dg
1330d56cdd Fix a bunch of errors caused by changes to libfmt. 2023-07-07 21:32:21 +00:00
David Given
6ce3ce20d0 Remove stray debugging code. 2023-07-07 01:03:31 +02:00
David Given
362c5ee9b0 Rename the requires config field to prerequisite, as requires is about to
become a C++ keyword.
2023-07-07 00:34:03 +02:00
David Given
0f34ce0278 Merge pull request #690 from Deledrius/nsi-fix
Fix incorrect product name in installer.
2023-06-26 14:27:39 +02:00
Joseph Davies
0c27c7c4c8 Fix incorrect product name in installer. 2023-06-25 16:18:03 -07:00
dg
ba1f8b8ed8 Add missing file. Reformat. 2023-05-06 00:28:13 +00:00
dg
10605b3908 Add a read-only MS2000 file system, and a format (with no encoder or decoder). 2023-05-06 00:21:10 +00:00
dg
e31e547322 Add a routine to count the number of bits in a word. 2023-05-06 00:20:48 +00:00
dg
9484a1b870 Swap minutes and seconds, as this seems to be more correct. 2023-04-07 16:38:08 +00:00
dg
0a5a814a88 Typo fix. 2023-04-05 17:17:15 +00:00
dg
08ce455d1d Properly terminate pSOS filenames. Make a guess at the ctime format. 2023-04-05 17:13:49 +00:00
323 changed files with 5901 additions and 2611 deletions

View File

@@ -19,9 +19,10 @@ jobs:
repository: 'davidgiven/fluxengine-testdata'
path: 'fluxengine-testdata'
- name: apt
run: sudo apt update && sudo apt install libudev-dev libsqlite3-dev protobuf-compiler libwxgtk3.0-gtk3-dev libfmt-dev
run: |
sudo apt install libudev-dev libsqlite3-dev protobuf-compiler libwxgtk3.0-gtk3-dev libfmt-dev libprotobuf-dev wx-common
- name: make
run: CXXFLAGS="-Wp,-D_GLIBCXX_ASSERTIONS" make -j2 -C fluxengine
run: CXXFLAGS="-Wp,-D_GLIBCXX_ASSERTIONS" make -j`nproc` -C fluxengine
build-macos-current:
runs-on: macos-latest
@@ -37,13 +38,13 @@ jobs:
- name: brew
run: brew install sqlite pkg-config libusb protobuf wxwidgets fmt make coreutils dylibbundler libjpeg
- name: make
run: gmake -j2 -C fluxengine
run: gmake -j`nproc` -C fluxengine
- name: Upload build artifacts
uses: actions/upload-artifact@v2
with:
name: ${{ github.event.repository.name }}.${{ github.sha }}
path: fluxengine.FluxEngine.pkg
path: fluxengine/FluxEngine.pkg
build-windows:
runs-on: windows-latest
@@ -58,17 +59,23 @@ jobs:
install: >-
diffutils
make
mingw-w64-i686-binutils
mingw-w64-i686-fmt
mingw-w64-i686-gcc
mingw-w64-i686-libusb
mingw-w64-i686-nsis
mingw-w64-i686-pkg-config
mingw-w64-i686-protobuf
mingw-w64-i686-python
mingw-w64-i686-sqlite3
mingw-w64-i686-wxWidgets
mingw-w64-i686-zlib
mingw-w64-i686-nsis
zip
mingw-w64-i686-imagemagick
vim
zip
- name: update-protobuf
run: |
pacman -U --noconfirm https://repo.msys2.org/mingw/mingw32/mingw-w64-i686-protobuf-21.9-1-any.pkg.tar.zst
- uses: actions/checkout@v2
with:
repository: 'davidgiven/fluxengine'
@@ -78,7 +85,7 @@ jobs:
repository: 'davidgiven/fluxengine-testdata'
path: 'fluxengine-testdata'
- name: build
run: make -j2 -C fluxengine
run: MAGICK_TIME_LIMIT=100 make -j`nproc` -C fluxengine
- name: nsis
run: |

View File

@@ -1,7 +1,7 @@
name: Autorelease
concurrency:
group: environment-${{ github.head_ref }}
group: environment-release-${{ github.head_ref }}
cancel-in-progress: true
on:
@@ -23,22 +23,29 @@ jobs:
install: >-
diffutils
make
mingw-w64-i686-binutils
mingw-w64-i686-fmt
mingw-w64-i686-gcc
mingw-w64-i686-libusb
mingw-w64-i686-nsis
mingw-w64-i686-pkg-config
mingw-w64-i686-protobuf
mingw-w64-i686-python
mingw-w64-i686-sqlite3
mingw-w64-i686-wxWidgets
mingw-w64-i686-zlib
mingw-w64-i686-nsis
zip
mingw-w64-i686-imagemagick
vim
zip
- uses: actions/checkout@v3
- name: update-protobuf
run: |
pacman -U --noconfirm https://repo.msys2.org/mingw/mingw32/mingw-w64-i686-protobuf-21.9-1-any.pkg.tar.zst
- name: build
run: |
make -j2
MAGICK_TIME_LIMIT=100 make -j`nproc`
- name: nsis
run: |

View File

@@ -1,4 +1,5 @@
.obj
.git
streams
.*\.flux
.*\.img

331
Makefile
View File

@@ -1,300 +1,65 @@
#Special Windows settings.
CC = gcc
CXX = g++ -std=c++17
CFLAGS = -g -O3
LDFLAGS =
ifeq ($(OS), Windows_NT)
MINGWBIN = /mingw32/bin
CCPREFIX = $(MINGWBIN)/
LUA = $(MINGWBIN)/lua
PKG_CONFIG = $(MINGWBIN)/pkg-config
WX_CONFIG = /usr/bin/sh $(MINGWBIN)/wx-config --static=yes
PROTOC = $(MINGWBIN)/protoc
PLATFORM = WINDOWS
LDFLAGS += \
-static
CXXFLAGS += \
-std=c++17 \
-fext-numeric-literals \
-Wno-deprecated-enum-float-conversion \
-Wno-deprecated-enum-enum-conversion
#Required to get the gcc run - time libraries on the path.
export PATH := $(PATH):$(MINGWBIN)
EXT ?= .exe
endif
#Special OSX settings.
ifeq ($(shell uname),Darwin)
PLATFORM = OSX
LDFLAGS += \
-framework IOKit \
-framework Foundation
endif
#Check the Make version.
ifeq ($(findstring 4.,$(MAKE_VERSION)),)
$(error You need GNU Make 4.x for this (if you're on OSX, use gmake).)
endif
#Normal settings.
OBJDIR ?= .obj
CCPREFIX ?=
LUA ?= lua
CC ?= $(CCPREFIX)gcc
CXX ?= $(CCPREFIX)g++
AR ?= $(CCPREFIX)ar
PKG_CONFIG ?= pkg-config
WX_CONFIG ?= wx-config
PROTOC ?= protoc
CFLAGS ?= -g -O3
CXXFLAGS += -std=c++17
LDFLAGS ?=
PLATFORM ?= UNIX
TESTS ?= yes
EXT ?=
OBJ = .obj
DESTDIR ?=
PREFIX ?= /usr/local
BINDIR ?= $(PREFIX)/bin
CFLAGS += \
-Iarch \
-Ilib \
-I. \
-I$(OBJDIR)/arch \
-I$(OBJDIR)/lib \
-I$(OBJDIR) \
-Wno-deprecated-declarations \
# Special Windows settings.
LDFLAGS += \
-lz \
-lfmt
ifeq ($(OS), Windows_NT)
EXT ?= .exe
MINGWBIN = /mingw32/bin
CCPREFIX = $(MINGWBIN)/
PKG_CONFIG = $(MINGWBIN)/pkg-config
WX_CONFIG = /usr/bin/sh $(MINGWBIN)/wx-config --static=yes
PROTOC = $(MINGWBIN)/protoc
WINDRES = windres
LDFLAGS += \
-static
CXXFLAGS += \
-fext-numeric-literals \
-Wno-deprecated-enum-float-conversion \
-Wno-deprecated-enum-enum-conversion
.SUFFIXES:
.DELETE_ON_ERROR:
define nl
endef
empty :=
space := $(empty) $(empty)
use-library = $(eval $(use-library-impl))
define use-library-impl
$1: $(call $3_LIB)
$1: private LDFLAGS += $(call $3_LDFLAGS)
$2: private CFLAGS += $(call $3_CFLAGS)
endef
use-pkgconfig = $(eval $(use-pkgconfig-impl))
define use-pkgconfig-impl
ifneq ($(strip $(shell $(PKG_CONFIG) $3; echo $$?)),0)
$$(error Missing required pkg-config dependency: $3)
# Required to get the gcc run - time libraries on the path.
export PATH := $(PATH):$(MINGWBIN)
endif
$(1): private LDFLAGS += $(shell $(PKG_CONFIG) --libs $(3))
$(2): private CFLAGS += $(shell $(PKG_CONFIG) --cflags $(3))
endef
.PHONY: all binaries tests clean install install-bin
all: binaries tests docs
PROTOS = \
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/smaky6/smaky6.proto \
arch/tids990/tids990.proto \
arch/victor9k/victor9k.proto \
arch/zilogmcz/zilogmcz.proto \
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/layout.proto \
lib/usb/usb.proto \
lib/vfs/vfs.proto \
tests/testproto.proto \
PROTO_HDRS = $(patsubst %.proto, $(OBJDIR)/%.pb.h, $(PROTOS))
PROTO_SRCS = $(patsubst %.proto, $(OBJDIR)/%.pb.cc, $(PROTOS))
PROTO_OBJS = $(patsubst %.cc, %.o, $(PROTO_SRCS))
PROTO_CFLAGS = $(shell $(PKG_CONFIG) --cflags protobuf)
$(PROTO_SRCS): | $(PROTO_HDRS)
$(PROTO_OBJS): CFLAGS += $(PROTO_CFLAGS)
PROTO_LIB = $(OBJDIR)/libproto.a
$(PROTO_LIB): $(PROTO_OBJS)
PROTO_LDFLAGS = $(shell $(PKG_CONFIG) --libs protobuf) -pthread
.PRECIOUS: $(PROTO_HDRS) $(PROTO_SRCS)
include dep/agg/build.mk
include dep/libusbp/build.mk
include dep/stb/build.mk
include dep/emu/build.mk
include dep/fatfs/build.mk
include dep/adflib/build.mk
include dep/hfsutils/build.mk
include scripts/build.mk
include lib/build.mk
include arch/build.mk
include src/build.mk
include src/gui/build.mk
include tools/build.mk
include tests/build.mk
do-encodedecodetest = $(eval $(do-encodedecodetest-impl))
define do-encodedecodetest-impl
tests: $(OBJDIR)/$1$$(subst $$(space),_,$3).flux.encodedecode
$(OBJDIR)/$1$$(subst $$(space),_,$3).flux.encodedecode: scripts/encodedecodetest.sh $(FLUXENGINE_BIN) $2
@mkdir -p $(dir $$@)
@echo ENCODEDECODETEST $1 flux $(FLUXENGINE_BIN) $2 $3
@scripts/encodedecodetest.sh $1 flux $(FLUXENGINE_BIN) $2 $3 > $$@
tests: $(OBJDIR)/$1$$(subst $$(space),_,$3).scp.encodedecode
$(OBJDIR)/$1$$(subst $$(space),_,$3).scp.encodedecode: scripts/encodedecodetest.sh $(FLUXENGINE_BIN) $2
@mkdir -p $(dir $$@)
@echo ENCODEDECODETEST $1 scp $(FLUXENGINE_BIN) $2 $3
@scripts/encodedecodetest.sh $1 scp $(FLUXENGINE_BIN) $2 $3 > $$@
endef
$(call do-encodedecodetest,agat,,--drive.tpi=96)
$(call do-encodedecodetest,amiga,,--drive.tpi=135)
$(call do-encodedecodetest,apple2,,--140 --drive.tpi=96)
$(call do-encodedecodetest,atarist,,--360 --drive.tpi=135)
$(call do-encodedecodetest,atarist,,--370 --drive.tpi=135)
$(call do-encodedecodetest,atarist,,--400 --drive.tpi=135)
$(call do-encodedecodetest,atarist,,--410 --drive.tpi=135)
$(call do-encodedecodetest,atarist,,--720 --drive.tpi=135)
$(call do-encodedecodetest,atarist,,--740 --drive.tpi=135)
$(call do-encodedecodetest,atarist,,--800 --drive.tpi=135)
$(call do-encodedecodetest,atarist,,--820 --drive.tpi=135)
$(call do-encodedecodetest,bk)
$(call do-encodedecodetest,brother,,--120 --drive.tpi=135)
$(call do-encodedecodetest,brother,,--240 --drive.tpi=135)
$(call do-encodedecodetest,commodore,scripts/commodore1541_test.textpb,--171 --drive.tpi=96)
$(call do-encodedecodetest,commodore,scripts/commodore1541_test.textpb,--192 --drive.tpi=96)
$(call do-encodedecodetest,commodore,,--800 --drive.tpi=135)
$(call do-encodedecodetest,commodore,,--1620 --drive.tpi=135)
$(call do-encodedecodetest,hplif,,--264 --drive.tpi=135)
$(call do-encodedecodetest,hplif,,--608 --drive.tpi=135)
$(call do-encodedecodetest,hplif,,--616 --drive.tpi=135)
$(call do-encodedecodetest,hplif,,--770 --drive.tpi=135)
$(call do-encodedecodetest,ibm,,--1200 --drive.tpi=96)
$(call do-encodedecodetest,ibm,,--1232 --drive.tpi=96)
$(call do-encodedecodetest,ibm,,--1440 --drive.tpi=135)
$(call do-encodedecodetest,ibm,,--1680 --drive.tpi=135)
$(call do-encodedecodetest,ibm,,--180 --drive.tpi=96)
$(call do-encodedecodetest,ibm,,--160 --drive.tpi=96)
$(call do-encodedecodetest,ibm,,--320 --drive.tpi=96)
$(call do-encodedecodetest,ibm,,--360 --drive.tpi=96)
$(call do-encodedecodetest,ibm,,--720_96 --drive.tpi=96)
$(call do-encodedecodetest,ibm,,--720_135 --drive.tpi=135)
$(call do-encodedecodetest,mac,scripts/mac400_test.textpb,--400 --drive.tpi=135)
$(call do-encodedecodetest,mac,scripts/mac800_test.textpb,--800 --drive.tpi=135)
$(call do-encodedecodetest,n88basic,,--drive.tpi=96)
$(call do-encodedecodetest,rx50,,--drive.tpi=96)
$(call do-encodedecodetest,tids990,,--drive.tpi=48)
$(call do-encodedecodetest,victor9k,,--612 --drive.tpi=96)
$(call do-encodedecodetest,victor9k,,--1224 --drive.tpi=96)
do-corpustest = $(eval $(do-corpustest-impl))
define do-corpustest-impl
tests: $(OBJDIR)/corpustest/$2
$(OBJDIR)/corpustest/$2: $(FLUXENGINE_BIN) \
../fluxengine-testdata/data/$1 ../fluxengine-testdata/data/$2
@mkdir -p $(OBJDIR)/corpustest
@echo CORPUSTEST $1 $2 $3
@$(FLUXENGINE_BIN) read $3 -s ../fluxengine-testdata/data/$1 -o $$@ > $$@.log
@cmp $$@ ../fluxengine-testdata/data/$2
endef
ifneq ($(wildcard ../fluxengine-testdata/data),)
$(call do-corpustest,amiga.flux,amiga.adf,amiga --drive.tpi=135)
$(call do-corpustest,atarist360.flux,atarist360.st,atarist --360 --drive.tpi=135)
$(call do-corpustest,atarist720.flux,atarist720.st,atarist --720 --drive.tpi=135)
$(call do-corpustest,brother120.flux,brother120.img,brother --120 --drive.tpi=135)
$(call do-corpustest,cmd-fd2000.flux,cmd-fd2000.img,commodore --1620 --drive.tpi=135)
$(call do-corpustest,ibm1232.flux,ibm1232.img,ibm --1232 --drive.tpi=96)
$(call do-corpustest,ibm1440.flux,ibm1440.img,ibm --1440 --drive.tpi=135)
$(call do-corpustest,mac800.flux,mac800.dsk,mac --800 --drive.tpi=135)
$(call do-corpustest,micropolis315.flux,micropolis315.img,micropolis --315 --drive.tpi=100)
$(call do-corpustest,northstar87-synthetic.flux,northstar87-synthetic.nsi,northstar --87 --drive.tpi=48)
$(call do-corpustest,northstar175-synthetic.flux,northstar175-synthetic.nsi,northstar --175 --drive.tpi=48)
$(call do-corpustest,northstar350-synthetic.flux,northstar350-synthetic.nsi,northstar --350 --drive.tpi=48)
$(call do-corpustest,victor9k_ss.flux,victor9k_ss.img,victor9k --612 --drive.tpi=96)
$(call do-corpustest,victor9k_ds.flux,victor9k_ds.img,victor9k --1224 --drive.tpi=96)
# Special OSX settings.
ifeq ($(shell uname),Darwin)
LDFLAGS += \
-framework IOKit \
-framework Foundation
endif
$(OBJDIR)/%.a:
@mkdir -p $(dir $@)
@echo AR $@
@$(AR) rc $@ $^
.PHONY: all
all: +all README.md
%.exe:
@mkdir -p $(dir $@)
@echo LINK $@
@$(CXX) -o $@ $(filter %.o,$^) $(filter %.a,$^) $(LDFLAGS) $(filter %.a,$^) $(LDFLAGS)
.PHONY: binaries tests
binaries: all
tests: all
README.md: $(OBJ)/scripts+mkdocindex/scripts+mkdocindex$(EXT)
@echo MKDOC $@
@csplit -s -f$(OBJ)/README. README.md '/<!-- FORMATSSTART -->/' '%<!-- FORMATSEND -->%'
@(cat $(OBJ)/README.00 && $< && cat $(OBJ)/README.01) > README.md
$(OBJDIR)/%.o: %.cpp
@mkdir -p $(dir $@)
@echo CXX $<
@$(CXX) $(CFLAGS) $(CXXFLAGS) -MMD -MP -MF $(@:.o=.d) -c -o $@ $<
.PHONY: tests
$(OBJDIR)/%.o: %.cc
@mkdir -p $(dir $@)
@echo CXX $<
@$(CXX) $(CFLAGS) $(CXXFLAGS) -MMD -MP -MF $(@:.o=.d) -c -o $@ $<
.PHONY: install install-bin
install:: all install-bin
$(OBJDIR)/%.o: $(OBJDIR)/%.cc
@mkdir -p $(dir $@)
@echo CXX $<
@$(CXX) $(CFLAGS) $(CXXFLAGS) -MMD -MP -MF $(@:.o=.d) -c -o $@ $<
install-bin:
@echo "INSTALL"
$(hide) install -D -v "$(OBJ)/src+fluxengine/src+fluxengine" "$(DESTDIR)$(BINDIR)/fluxengine"
$(hide) install -D -v "$(OBJ)/src/gui+gui/gui+gui" "$(DESTDIR)$(BINDIR)/fluxengine-gui"
$(hide) install -D -v "$(OBJ)/tools+brother120tool/tools+brother120tool" "$(DESTDIR)$(BINDIR)/brother120tool"
$(hide) install -D -v "$(OBJ)/tools+brother240tool/tools+brother240tool" "$(DESTDIR)$(BINDIR)/brother240tool"
$(hide) install -D -v "$(OBJ)/tools+upgrade-flux-file/tools+upgrade-flux-file" "$(DESTDIR)$(BINDIR)/upgrade-flux-file"
$(OBJDIR)/%.o: %.c
@mkdir -p $(dir $@)
@echo CC $<
@$(CC) $(CFLAGS) $(CFLAGS) -MMD -MP -MF $(@:.o=.d) -c -o $@ $<
$(OBJDIR)/%.pb.h: %.proto
@mkdir -p $(dir $@)
@echo PROTOC $@
@$(PROTOC) -I. --cpp_out=$(OBJDIR) $<
clean:
rm -rf $(OBJDIR)
install: install-bin # install-man install-docs ...
install-bin: fluxengine$(EXT) fluxengine-gui$(EXT) brother120tool$(EXT) brother240tool$(EXT) upgrade-flux-file$(EXT)
install -d "$(DESTDIR)$(BINDIR)"
for target in $^; do \
install $$target "$(DESTDIR)$(BINDIR)/$$target"; \
done
-include $(OBJS:%.o=%.d)
include build/ab.mk

View File

@@ -128,17 +128,19 @@ choices because they can store multiple types of file system.
| [`icl30`](doc/disk-icl30.md) | ICL Model 30: CP/M; 263kB 35-track DSSD | 🦖 | | CPMFS |
| [`mac`](doc/disk-mac.md) | Macintosh: 400kB/800kB 3.5" GCR | 🦄 | 🦄 | MACHFS |
| [`micropolis`](doc/disk-micropolis.md) | Micropolis: 100tpi MetaFloppy disks | 🦄 | 🦄 | |
| [`ms2000`](doc/disk-ms2000.md) | : MS2000 Microdisk Development System | | | MICRODOS |
| [`mx`](doc/disk-mx.md) | DVK MX: Soviet-era PDP-11 clone | 🦖 | | |
| [`n88basic`](doc/disk-n88basic.md) | N88-BASIC: PC8800/PC98 5.25" 77-track 26-sector DSHD | 🦄 | 🦄 | |
| [`northstar`](doc/disk-northstar.md) | Northstar: 5.25" hard sectored | 🦄 | 🦄 | |
| [`psos`](doc/disk-psos.md) | pSOS: 800kB DSDD with PHILE | 🦄 | 🦄 | PHILE |
| [`rolandd20`](doc/disk-rolandd20.md) | Roland D20: 3.5" electronic synthesiser disks | 🦖 | | |
| [`q1`](doc/disk-q1.md) | Q1: Q1ish | 🦖 | | |
| [`rolandd20`](doc/disk-rolandd20.md) | Roland D20: 3.5" electronic synthesiser disks | 🦄 | 🦖 | ROLAND |
| [`rx50`](doc/disk-rx50.md) | Digital RX50: 400kB 5.25" 80-track 10-sector SSDD | 🦖 | 🦖 | |
| [`smaky6`](doc/disk-smaky6.md) | Smaky 6: 308kB 5.25" 77-track 16-sector SSDD, hard sectored | 🦖 | | SMAKY6 |
| [`tids990`](doc/disk-tids990.md) | Texas Instruments DS990: 1126kB 8" DSSD | 🦖 | 🦖 | |
| [`tiki`](doc/disk-tiki.md) | Tiki 100: CP/M | | | CPMFS |
| [`victor9k`](doc/disk-victor9k.md) | Victor 9000 / Sirius One: 1224kB 5.25" DSDD GCR | 🦖 | 🦖 | |
| [`zilogmcz`](doc/disk-zilogmcz.md) | Zilog MCZ: 320kB 8" 77-track SSSD hard-sectored | 🦖 | | |
| [`zilogmcz`](doc/disk-zilogmcz.md) | Zilog MCZ: 320kB 8" 77-track SSSD hard-sectored | 🦖 | | ZDOS |
{: .datatable }
<!-- FORMATSEND -->

View File

@@ -1,11 +1,11 @@
#include "globals.h"
#include "decoders/decoders.h"
#include "lib/globals.h"
#include "lib/decoders/decoders.h"
#include "aeslanier.h"
#include "crc.h"
#include "fluxmap.h"
#include "decoders/fluxmapreader.h"
#include "sector.h"
#include "bytes.h"
#include "lib/crc.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/sector.h"
#include "lib/bytes.h"
#include "fmt/format.h"
#include <string.h>

View File

@@ -1,7 +1,7 @@
#include "globals.h"
#include "decoders/decoders.h"
#include "lib/globals.h"
#include "lib/decoders/decoders.h"
#include "agat.h"
#include "bytes.h"
#include "lib/bytes.h"
#include "fmt/format.h"
uint8_t agatChecksum(const Bytes& bytes)

View File

@@ -1,11 +1,11 @@
#include "globals.h"
#include "decoders/decoders.h"
#include "lib/globals.h"
#include "lib/decoders/decoders.h"
#include "agat.h"
#include "crc.h"
#include "fluxmap.h"
#include "decoders/fluxmapreader.h"
#include "sector.h"
#include "bytes.h"
#include "lib/crc.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/sector.h"
#include "lib/bytes.h"
#include "fmt/format.h"
#include <string.h>

View File

@@ -1,7 +1,7 @@
#include "globals.h"
#include "decoders/decoders.h"
#include "lib/globals.h"
#include "lib/decoders/decoders.h"
#include "amiga.h"
#include "bytes.h"
#include "lib/bytes.h"
#include "fmt/format.h"
uint32_t amigaChecksum(const Bytes& bytes)

View File

@@ -1,7 +1,7 @@
#ifndef AMIGA_H
#define AMIGA_H
#include "encoders/encoders.h"
#include "lib/encoders/encoders.h"
#define AMIGA_SECTOR_RECORD 0xaaaa44894489LL

View File

@@ -1,11 +1,11 @@
#include "globals.h"
#include "fluxmap.h"
#include "decoders/fluxmapreader.h"
#include "lib/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "protocol.h"
#include "decoders/decoders.h"
#include "sector.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"
#include "amiga.h"
#include "bytes.h"
#include "lib/bytes.h"
#include "fmt/format.h"
#include "lib/decoders/decoders.pb.h"
#include <string.h>

View File

@@ -1,10 +1,10 @@
#include "globals.h"
#include "decoders/decoders.h"
#include "encoders/encoders.h"
#include "lib/globals.h"
#include "lib/decoders/decoders.h"
#include "lib/encoders/encoders.h"
#include "amiga.h"
#include "crc.h"
#include "readerwriter.h"
#include "image.h"
#include "lib/crc.h"
#include "lib/readerwriter.h"
#include "lib/image.h"
#include "arch/amiga/amiga.pb.h"
#include "lib/encoders/encoders.pb.h"

View File

@@ -2,8 +2,8 @@
#define APPLE2_H
#include <memory.h>
#include "decoders/decoders.h"
#include "encoders/encoders.h"
#include "lib/decoders/decoders.h"
#include "lib/encoders/encoders.h"
#define APPLE2_SECTOR_RECORD 0xd5aa96
#define APPLE2_DATA_RECORD 0xd5aaad

View File

@@ -1,13 +1,13 @@
#include "globals.h"
#include "fluxmap.h"
#include "decoders/fluxmapreader.h"
#include "lib/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "protocol.h"
#include "decoders/decoders.h"
#include "sector.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"
#include "apple2.h"
#include "arch/apple2/apple2.pb.h"
#include "lib/decoders/decoders.pb.h"
#include "bytes.h"
#include "lib/bytes.h"
#include "fmt/format.h"
#include <string.h>
#include <algorithm>

View File

@@ -1,14 +1,14 @@
#include "globals.h"
#include "lib/globals.h"
#include "arch/apple2/apple2.h"
#include "decoders/decoders.h"
#include "encoders/encoders.h"
#include "sector.h"
#include "readerwriter.h"
#include "image.h"
#include "lib/decoders/decoders.h"
#include "lib/encoders/encoders.h"
#include "lib/sector.h"
#include "lib/readerwriter.h"
#include "lib/image.h"
#include "fmt/format.h"
#include "lib/encoders/encoders.pb.h"
#include <ctype.h>
#include "bytes.h"
#include "lib/bytes.h"
static int encode_data_gcr(uint8_t data)
{

View File

@@ -1,12 +1,12 @@
#include "globals.h"
#include "fluxmap.h"
#include "decoders/fluxmapreader.h"
#include "decoders/decoders.h"
#include "encoders/encoders.h"
#include "lib/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/decoders.h"
#include "lib/encoders/encoders.h"
#include "brother.h"
#include "sector.h"
#include "bytes.h"
#include "crc.h"
#include "lib/sector.h"
#include "lib/bytes.h"
#include "lib/crc.h"
#include <ctype.h>
const FluxPattern SECTOR_RECORD_PATTERN(32, BROTHER_SECTOR_RECORD);

View File

@@ -1,10 +1,10 @@
#include "globals.h"
#include "decoders/decoders.h"
#include "encoders/encoders.h"
#include "lib/globals.h"
#include "lib/decoders/decoders.h"
#include "lib/encoders/encoders.h"
#include "brother.h"
#include "crc.h"
#include "readerwriter.h"
#include "image.h"
#include "lib/crc.h"
#include "lib/readerwriter.h"
#include "lib/image.h"
#include "arch/brother/brother.pb.h"
#include "lib/encoders/encoders.pb.h"

View File

@@ -1,43 +0,0 @@
LIBARCH_SRCS = \
arch/aeslanier/decoder.cc \
arch/agat/agat.cc \
arch/agat/decoder.cc \
arch/agat/encoder.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/decoder.cc \
arch/smaky6/decoder.cc \
arch/tids990/decoder.cc \
arch/tids990/encoder.cc \
arch/victor9k/decoder.cc \
arch/victor9k/encoder.cc \
arch/zilogmcz/decoder.cc \
LIBARCH_OBJS = $(patsubst %.cc, $(OBJDIR)/%.o, $(LIBARCH_SRCS))
OBJS += $(LIBARCH_OBJS)
$(LIBARCH_SRCS): | $(PROTO_HDRS)
$(LIBARCH_SRCS): CFLAGS += $(PROTO_CFLAGS)
LIBARCH_LIB = $(OBJDIR)/libarch.a
LIBARCH_LDFLAGS =
$(LIBARCH_LIB): $(LIBARCH_OBJS)
$(call use-pkgconfig, $(LIBARCH_LIB), $(LIBARCH_OBJS), fmt)

27
arch/build.py Normal file
View File

@@ -0,0 +1,27 @@
from build.c import cxxlibrary
from build.protobuf import proto, protocc
proto(
name="arch_proto",
srcs=[
"./aeslanier/aeslanier.proto",
"./agat/agat.proto",
"./amiga/amiga.proto",
"./apple2/apple2.proto",
"./brother/brother.proto",
"./c64/c64.proto",
"./f85/f85.proto",
"./fb100/fb100.proto",
"./ibm/ibm.proto",
"./macintosh/macintosh.proto",
"./micropolis/micropolis.proto",
"./mx/mx.proto",
"./northstar/northstar.proto",
"./q1/q1.proto",
"./rolandd20/rolandd20.proto",
"./smaky6/smaky6.proto",
"./tids990/tids990.proto",
"./victor9k/victor9k.proto",
"./zilogmcz/zilogmcz.proto",
],
)

View File

@@ -1,4 +1,4 @@
#include "globals.h"
#include "lib/globals.h"
#include "c64.h"
/*

View File

@@ -1,8 +1,8 @@
#ifndef C64_H
#define C64_H
#include "decoders/decoders.h"
#include "encoders/encoders.h"
#include "lib/decoders/decoders.h"
#include "lib/encoders/encoders.h"
#define C64_SECTOR_RECORD 0xffd49
#define C64_DATA_RECORD 0xffd57

View File

@@ -1,12 +1,12 @@
#include "globals.h"
#include "fluxmap.h"
#include "decoders/fluxmapreader.h"
#include "lib/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "protocol.h"
#include "decoders/decoders.h"
#include "sector.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"
#include "c64.h"
#include "crc.h"
#include "bytes.h"
#include "lib/crc.h"
#include "lib/bytes.h"
#include "fmt/format.h"
#include <string.h>
#include <algorithm>

View File

@@ -1,17 +1,17 @@
#include "globals.h"
#include "decoders/decoders.h"
#include "encoders/encoders.h"
#include "lib/globals.h"
#include "lib/decoders/decoders.h"
#include "lib/encoders/encoders.h"
#include "c64.h"
#include "crc.h"
#include "sector.h"
#include "readerwriter.h"
#include "image.h"
#include "lib/crc.h"
#include "lib/sector.h"
#include "lib/readerwriter.h"
#include "lib/image.h"
#include "fmt/format.h"
#include "arch/c64/c64.pb.h"
#include "lib/encoders/encoders.pb.h"
#include "lib/layout.h"
#include <ctype.h>
#include "bytes.h"
#include "lib/bytes.h"
static bool lastBit;
@@ -51,26 +51,6 @@ static void write_bits(
}
}
void bindump(std::ostream& stream, std::vector<bool>& buffer)
{
size_t pos = 0;
while ((pos < buffer.size()) and (pos < 520))
{
stream << fmt::format("{:5d} : ", pos);
for (int i = 0; i < 40; i++)
{
if ((pos + i) < buffer.size())
stream << fmt::format("{:01b}", (buffer[pos + i]));
else
stream << "-- ";
if ((((pos + i + 1) % 8) == 0) and i != 0)
stream << " ";
}
stream << std::endl;
pos += 40;
}
}
static std::vector<bool> encode_data(uint8_t input)
{
/*

View File

@@ -1,12 +1,12 @@
#include "globals.h"
#include "fluxmap.h"
#include "decoders/fluxmapreader.h"
#include "lib/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "protocol.h"
#include "decoders/decoders.h"
#include "sector.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"
#include "f85.h"
#include "crc.h"
#include "bytes.h"
#include "lib/crc.h"
#include "lib/bytes.h"
#include "fmt/format.h"
#include <string.h>
#include <algorithm>

View File

@@ -1,13 +1,13 @@
#include "globals.h"
#include "fluxmap.h"
#include "decoders/fluxmapreader.h"
#include "lib/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "protocol.h"
#include "decoders/decoders.h"
#include "sector.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"
#include "fb100.h"
#include "crc.h"
#include "bytes.h"
#include "decoders/rawbits.h"
#include "lib/crc.h"
#include "lib/bytes.h"
#include "lib/decoders/rawbits.h"
#include "fmt/format.h"
#include <string.h>
#include <algorithm>

View File

@@ -1,12 +1,12 @@
#include "globals.h"
#include "decoders/decoders.h"
#include "lib/globals.h"
#include "lib/decoders/decoders.h"
#include "ibm.h"
#include "crc.h"
#include "fluxmap.h"
#include "decoders/fluxmapreader.h"
#include "sector.h"
#include "lib/crc.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/sector.h"
#include "arch/ibm/ibm.pb.h"
#include "proto.h"
#include "lib/proto.h"
#include "lib/layout.h"
#include <string.h>

View File

@@ -1,10 +1,10 @@
#include "globals.h"
#include "decoders/decoders.h"
#include "encoders/encoders.h"
#include "lib/globals.h"
#include "lib/decoders/decoders.h"
#include "lib/encoders/encoders.h"
#include "ibm.h"
#include "crc.h"
#include "readerwriter.h"
#include "image.h"
#include "lib/crc.h"
#include "lib/readerwriter.h"
#include "lib/image.h"
#include "arch/ibm/ibm.pb.h"
#include "lib/encoders/encoders.pb.h"
#include "fmt/format.h"

View File

@@ -1,11 +1,11 @@
#include "globals.h"
#include "fluxmap.h"
#include "decoders/fluxmapreader.h"
#include "lib/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "protocol.h"
#include "decoders/decoders.h"
#include "sector.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"
#include "macintosh.h"
#include "bytes.h"
#include "lib/bytes.h"
#include "fmt/format.h"
#include <string.h>
#include <algorithm>

View File

@@ -1,10 +1,10 @@
#include "globals.h"
#include "decoders/decoders.h"
#include "encoders/encoders.h"
#include "lib/globals.h"
#include "lib/decoders/decoders.h"
#include "lib/encoders/encoders.h"
#include "macintosh.h"
#include "crc.h"
#include "readerwriter.h"
#include "image.h"
#include "lib/crc.h"
#include "lib/readerwriter.h"
#include "lib/image.h"
#include "fmt/format.h"
#include "lib/encoders/encoders.pb.h"
#include "lib/layout.h"

View File

@@ -1,10 +1,10 @@
#include "globals.h"
#include "fluxmap.h"
#include "decoders/fluxmapreader.h"
#include "decoders/decoders.h"
#include "sector.h"
#include "lib/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"
#include "micropolis.h"
#include "bytes.h"
#include "lib/bytes.h"
#include "fmt/format.h"
#include "lib/decoders/decoders.pb.h"
@@ -59,6 +59,76 @@ uint8_t mzosChecksum(const Bytes& bytes)
return checksum;
}
static uint8_t b(uint32_t field, uint8_t pos)
{
return (field >> pos) & 1;
}
static uint8_t eccNextBit(uint32_t ecc, uint8_t data_bit)
{
// This is 0x81932080 which is 0x0104C981 with reversed bits
return b(ecc, 7) ^ b(ecc, 13) ^ b(ecc, 16) ^ b(ecc, 17) ^ b(ecc, 20) ^
b(ecc, 23) ^ b(ecc, 24) ^ b(ecc, 31) ^ data_bit;
}
uint32_t vectorGraphicEcc(const Bytes& bytes)
{
uint32_t e = 0;
Bytes payloadBytes = bytes.slice(0, bytes.size() - 4);
ByteReader payload(payloadBytes);
while (!payload.eof())
{
uint8_t byte = payload.read_8();
for (int i = 0; i < 8; i++)
{
e = (e << 1) | eccNextBit(e, byte >> 7);
byte <<= 1;
}
}
Bytes trailerBytes = bytes.slice(bytes.size() - 4);
ByteReader trailer(trailerBytes);
uint32_t res = e;
while (!trailer.eof())
{
uint8_t byte = trailer.read_8();
for (int i = 0; i < 8; i++)
{
res = (res << 1) | eccNextBit(e, byte >> 7);
e <<= 1;
byte <<= 1;
}
}
return res;
}
/* Fixes bytes when possible, returning true if changed. */
static bool vectorGraphicEccFix(Bytes& bytes, uint32_t syndrome)
{
uint32_t ecc = syndrome;
int pos = (MICROPOLIS_ENCODED_SECTOR_SIZE - 5) * 8 + 7;
bool aligned = false;
while ((ecc & 0xff000000) == 0)
{
pos += 8;
ecc <<= 8;
}
for (; pos >= 0; pos--)
{
bool bit = ecc & 1;
ecc >>= 1;
if (bit)
ecc ^= 0x808264c0;
if ((ecc & 0xff07ffff) == 0)
aligned = true;
if (aligned && pos % 8 == 0)
break;
}
if (pos < 0)
return false;
bytes[pos / 8] ^= ecc >> 16;
return true;
}
class MicropolisDecoder : public Decoder
{
public:
@@ -85,9 +155,10 @@ public:
/* Discard a possible partial sector at the end of the track.
* This partial sector could be mistaken for a conflicted sector, if
* whatever data read happens to match the checksum of 0, which is
* rare, but has been observed on some disks.
* rare, but has been observed on some disks. There's 570uS of slack in
* each sector, after accounting for preamble, data, and postamble.
*/
if (now > (getFluxmapDuration() - 12.5e6))
if (now > (getFluxmapDuration() - 12.0e6))
{
seekToIndexMark();
return 0;
@@ -114,9 +185,10 @@ public:
_sector->headerStartTime = tell().ns();
/* seekToPattern() can skip past the index hole, if this happens
* too close to the end of the Fluxmap, discard the sector.
* too close to the end of the Fluxmap, discard the sector. The
* preamble was expected to be 640uS long.
*/
if (_sector->headerStartTime > (getFluxmapDuration() - 12.5e6))
if (_sector->headerStartTime > (getFluxmapDuration() - 11.3e6))
{
return 0;
}
@@ -130,6 +202,19 @@ public:
auto rawbits = readRawBits(MICROPOLIS_ENCODED_SECTOR_SIZE * 16);
auto bytes =
decodeFmMfm(rawbits).slice(0, MICROPOLIS_ENCODED_SECTOR_SIZE);
bool eccPresent = bytes[274] == 0xaa;
uint32_t ecc = 0;
if (_config.ecc_type() == MicropolisDecoderProto::VECTOR && eccPresent)
{
ecc = vectorGraphicEcc(bytes.slice(0, 274));
if (ecc != 0)
{
vectorGraphicEccFix(bytes, ecc);
ecc = vectorGraphicEcc(bytes.slice(0, 274));
}
}
ByteReader br(bytes);
int syncByte = br.read_8(); /* sync */
@@ -191,8 +276,10 @@ public:
_sector->data = bytes;
else
error("Sector output size may only be 256 or 275");
_sector->status =
(wantChecksum == gotChecksum) ? Sector::OK : Sector::BAD_CHECKSUM;
if (wantChecksum == gotChecksum && (!eccPresent || ecc == 0))
_sector->status = Sector::OK;
else
_sector->status = Sector::BAD_CHECKSUM;
}
private:

View File

@@ -1,14 +1,15 @@
#include "globals.h"
#include "lib/globals.h"
#include "micropolis.h"
#include "sector.h"
#include "decoders/decoders.h"
#include "encoders/encoders.h"
#include "image.h"
#include "lib/sector.h"
#include "lib/decoders/decoders.h"
#include "lib/encoders/encoders.h"
#include "lib/image.h"
#include "lib/encoders/encoders.pb.h"
static void write_sector(std::vector<bool>& bits,
unsigned& cursor,
const std::shared_ptr<const Sector>& sector)
const std::shared_ptr<const Sector>& sector,
MicropolisEncoderProto::EccType eccType)
{
if ((sector->data.size() != 256) &&
(sector->data.size() != MICROPOLIS_ENCODED_SECTOR_SIZE))
@@ -45,8 +46,16 @@ static void write_sector(std::vector<bool>& bits,
writer.write_8(0); /* Padding */
writer += sector->data;
writer.write_8(micropolisChecksum(sectorData.slice(1)));
for (int i = 0; i < 5; i++)
writer.write_8(0); /* 4 byte ECC and ECC not present flag */
uint8_t eccPresent = 0;
uint32_t ecc = 0;
if (eccType == MicropolisEncoderProto::VECTOR)
{
eccPresent = 0xaa;
ecc = vectorGraphicEcc(sectorData + Bytes(4));
}
writer.write_be32(ecc);
writer.write_8(eccPresent);
}
for (uint8_t b : sectorData)
fullSector->push_back(b);
@@ -86,18 +95,34 @@ public:
(_config.rotational_period_ms() * 1e3) / _config.clock_period_us();
std::vector<bool> bits(bitsPerRevolution);
std::vector<unsigned> indexes;
unsigned prev_cursor = 0;
unsigned cursor = 0;
for (const auto& sectorData : sectors)
write_sector(bits, cursor, sectorData);
{
indexes.push_back(cursor);
prev_cursor = cursor;
write_sector(bits, cursor, sectorData, _config.ecc_type());
}
indexes.push_back(prev_cursor + (cursor - prev_cursor) / 2);
indexes.push_back(cursor);
if (cursor != bits.size())
error("track data mismatched length");
std::unique_ptr<Fluxmap> fluxmap(new Fluxmap);
fluxmap->appendBits(bits,
nanoseconds_t clockPeriod =
calculatePhysicalClockPeriod(_config.clock_period_us() * 1e3,
_config.rotational_period_ms() * 1e6));
_config.rotational_period_ms() * 1e6);
auto pos = bits.begin();
for (int i = 1; i < indexes.size(); i++)
{
auto end = bits.begin() + indexes[i];
fluxmap->appendBits(std::vector<bool>(pos, end), clockPeriod);
fluxmap->appendIndex();
pos = end;
}
return fluxmap;
}

View File

@@ -17,5 +17,6 @@ extern std::unique_ptr<Encoder> createMicropolisEncoder(
const EncoderProto& config);
extern uint8_t micropolisChecksum(const Bytes& bytes);
extern uint32_t vectorGraphicEcc(const Bytes& bytes);
#endif

View File

@@ -8,17 +8,30 @@ message MicropolisDecoderProto {
MICROPOLIS = 1;
MZOS = 2;
}
enum EccType {
NONE = 0;
VECTOR = 1;
}
optional int32 sector_output_size = 1 [default = 256,
(help) = "How much of the raw sector should be saved. Must be 256 or 275"];
optional ChecksumType checksum_type = 2 [default = AUTO,
(help) = "Checksum type to use: AUTO, MICROPOLIS, MZOS"];
optional EccType ecc_type = 3 [default = NONE,
(help) = "ECC type to use: NONE, VECTOR"];
}
message MicropolisEncoderProto {
enum EccType {
NONE = 0;
VECTOR = 1;
}
optional double clock_period_us = 1
[ default = 2.0, (help) = "clock rate on the real device" ];
optional double rotational_period_ms = 2
[ default = 200.0, (help) = "rotational period on the real device" ];
optional EccType ecc_type = 3 [default = NONE,
(help) = "ECC type to use for IMG data: NONE, VECTOR"];
}

View File

@@ -1,10 +1,10 @@
#include "globals.h"
#include "decoders/decoders.h"
#include "mx/mx.h"
#include "crc.h"
#include "fluxmap.h"
#include "decoders/fluxmapreader.h"
#include "sector.h"
#include "lib/globals.h"
#include "lib/decoders/decoders.h"
#include "arch/mx/mx.h"
#include "lib/crc.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/sector.h"
#include <string.h>
const int SECTOR_SIZE = 256;

View File

@@ -1,7 +1,7 @@
#ifndef MX_H
#define MX_H
#include "decoders/decoders.h"
#include "lib/decoders/decoders.h"
extern std::unique_ptr<Decoder> createMxDecoder(const DecoderProto& config);

View File

@@ -11,13 +11,13 @@
* sure that the hardSectorId is correct.
*/
#include "globals.h"
#include "fluxmap.h"
#include "decoders/fluxmapreader.h"
#include "decoders/decoders.h"
#include "sector.h"
#include "lib/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"
#include "northstar.h"
#include "bytes.h"
#include "lib/bytes.h"
#include "lib/decoders/decoders.pb.h"
#include "fmt/format.h"

View File

@@ -1,10 +1,10 @@
#include "globals.h"
#include "lib/globals.h"
#include "northstar.h"
#include "sector.h"
#include "bytes.h"
#include "decoders/decoders.h"
#include "encoders/encoders.h"
#include "image.h"
#include "lib/sector.h"
#include "lib/bytes.h"
#include "lib/decoders/decoders.h"
#include "lib/encoders/encoders.h"
#include "lib/image.h"
#include "lib/encoders/encoders.pb.h"
#define GAP_FILL_SIZE_SD 30

38
arch/q1/decoder.cc Normal file
View File

@@ -0,0 +1,38 @@
#include "lib/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"
#include "arch/q1/q1.h"
#include "lib/bytes.h"
#include "lib/decoders/decoders.pb.h"
#include "fmt/format.h"
static const FluxPattern ADDRESS_RECORD(32, Q1_ADDRESS_RECORD);
static const FluxPattern DATA_RECORD(32, Q1_DATA_RECORD);
const FluxMatchers ANY_RECORD_PATTERN({&ADDRESS_RECORD, &DATA_RECORD});
class Q1Decoder : public Decoder
{
public:
Q1Decoder(const DecoderProto& config): Decoder(config), _config(config.q1())
{
}
/* Search for FM or MFM sector record */
nanoseconds_t advanceToNextRecord() override
{
return seekToPattern(ANY_RECORD_PATTERN);
}
void decodeSectorRecord() override {}
private:
const Q1DecoderProto& _config;
};
std::unique_ptr<Decoder> createQ1Decoder(const DecoderProto& config)
{
return std::unique_ptr<Decoder>(new Q1Decoder(config));
}

9
arch/q1/q1.h Normal file
View File

@@ -0,0 +1,9 @@
#ifndef Q1_H
#define Q1_H
#define Q1_ADDRESS_RECORD 0x55424954
#define Q1_DATA_RECORD 0x55424955
extern std::unique_ptr<Decoder> createQ1Decoder(const DecoderProto& config);
#endif

6
arch/q1/q1.proto Normal file
View File

@@ -0,0 +1,6 @@
syntax = "proto2";
import "lib/common.proto";
message Q1DecoderProto {}

View File

@@ -1,12 +1,12 @@
#include "globals.h"
#include "fluxmap.h"
#include "decoders/fluxmapreader.h"
#include "lib/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "protocol.h"
#include "decoders/decoders.h"
#include "sector.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"
#include "smaky6.h"
#include "bytes.h"
#include "crc.h"
#include "lib/bytes.h"
#include "lib/crc.h"
#include "fmt/format.h"
#include "lib/decoders/decoders.pb.h"
#include <string.h>

View File

@@ -1,11 +1,11 @@
#include "globals.h"
#include "decoders/decoders.h"
#include "encoders/encoders.h"
#include "tids990/tids990.h"
#include "crc.h"
#include "fluxmap.h"
#include "decoders/fluxmapreader.h"
#include "sector.h"
#include "lib/globals.h"
#include "lib/decoders/decoders.h"
#include "lib/encoders/encoders.h"
#include "arch/tids990/tids990.h"
#include "lib/crc.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/sector.h"
#include <string.h>
#include <fmt/format.h>

View File

@@ -1,10 +1,10 @@
#include "globals.h"
#include "decoders/decoders.h"
#include "encoders/encoders.h"
#include "lib/globals.h"
#include "lib/decoders/decoders.h"
#include "lib/encoders/encoders.h"
#include "tids990.h"
#include "crc.h"
#include "readerwriter.h"
#include "image.h"
#include "lib/crc.h"
#include "lib/readerwriter.h"
#include "lib/image.h"
#include "arch/tids990/tids990.pb.h"
#include "lib/encoders/encoders.pb.h"
#include <fmt/format.h>

View File

@@ -1,12 +1,12 @@
#include "globals.h"
#include "fluxmap.h"
#include "decoders/fluxmapreader.h"
#include "lib/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "protocol.h"
#include "decoders/decoders.h"
#include "sector.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"
#include "victor9k.h"
#include "crc.h"
#include "bytes.h"
#include "lib/crc.h"
#include "lib/bytes.h"
#include "fmt/format.h"
#include <string.h>
#include <algorithm>

View File

@@ -1,17 +1,17 @@
#include "globals.h"
#include "decoders/decoders.h"
#include "encoders/encoders.h"
#include "lib/globals.h"
#include "lib/decoders/decoders.h"
#include "lib/encoders/encoders.h"
#include "victor9k.h"
#include "crc.h"
#include "sector.h"
#include "readerwriter.h"
#include "image.h"
#include "lib/crc.h"
#include "lib/sector.h"
#include "lib/readerwriter.h"
#include "lib/image.h"
#include "fmt/format.h"
#include "arch/victor9k/victor9k.pb.h"
#include "lib/encoders/encoders.pb.h"
#include "lib/layout.h"
#include <ctype.h>
#include "bytes.h"
#include "lib/bytes.h"
static bool lastBit;

View File

@@ -1,12 +1,12 @@
#include "globals.h"
#include "fluxmap.h"
#include "decoders/fluxmapreader.h"
#include "lib/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "protocol.h"
#include "decoders/decoders.h"
#include "sector.h"
#include "lib/decoders/decoders.h"
#include "lib/sector.h"
#include "zilogmcz.h"
#include "bytes.h"
#include "crc.h"
#include "lib/bytes.h"
#include "lib/crc.h"
#include "fmt/format.h"
#include <string.h>
#include <algorithm>

315
build.py Normal file
View File

@@ -0,0 +1,315 @@
from build.ab import export
from build.c import clibrary, cxxlibrary
from build.protobuf import proto, protocc
from build.pkg import package
from build.utils import test
from glob import glob
import config
import re
package(name="protobuf_lib", package="protobuf")
package(name="z_lib", package="zlib")
package(name="fmt_lib", package="fmt")
package(name="sqlite3_lib", package="sqlite3")
clibrary(name="protocol", hdrs={"protocol.h": "./protocol.h"})
proto(name="fl2_proto", srcs=["lib/fl2.proto"])
protocc(name="fl2_proto_lib", srcs=["+fl2_proto"])
cxxlibrary(
name="lib",
srcs=[
"./lib/bitmap.cc",
"./lib/bytes.cc",
"./lib/config.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/fl2.cc",
"./lib/flags.cc",
"./lib/fluxmap.cc",
"./lib/fluxsink/a2rfluxsink.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/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",
"./lib/fluxsource/flx.cc",
"./lib/fluxsource/flxfluxsource.cc",
"./lib/fluxsource/hardwarefluxsource.cc",
"./lib/fluxsource/kryoflux.cc",
"./lib/fluxsource/kryofluxfluxsource.cc",
"./lib/fluxsource/memoryfluxsource.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/imdimagewriter.cc",
"./lib/imagewriter/imgimagewriter.cc",
"./lib/imagewriter/ldbsimagewriter.cc",
"./lib/imagewriter/nsiimagewriter.cc",
"./lib/imagewriter/rawimagewriter.cc",
"./lib/layout.cc",
"./lib/ldbs.cc",
"./lib/logger.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",
"./lib/vfs/acorndfs.cc",
"./lib/vfs/amigaffs.cc",
"./lib/vfs/appledos.cc",
"./lib/vfs/applesingle.cc",
"./lib/vfs/brother120fs.cc",
"./lib/vfs/cbmfs.cc",
"./lib/vfs/cpmfs.cc",
"./lib/vfs/fatfs.cc",
"./lib/vfs/fluxsectorinterface.cc",
"./lib/vfs/imagesectorinterface.cc",
"./lib/vfs/lif.cc",
"./lib/vfs/machfs.cc",
"./lib/vfs/microdos.cc",
"./lib/vfs/philefs.cc",
"./lib/vfs/prodos.cc",
"./lib/vfs/roland.cc",
"./lib/vfs/smaky6fs.cc",
"./lib/vfs/vfs.cc",
"./lib/vfs/zdos.cc",
"./arch/aeslanier/decoder.cc",
"./arch/agat/agat.cc",
"./arch/agat/decoder.cc",
"./arch/agat/encoder.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/q1/decoder.cc",
"./arch/rolandd20/decoder.cc",
"./arch/smaky6/decoder.cc",
"./arch/tids990/decoder.cc",
"./arch/tids990/encoder.cc",
"./arch/victor9k/decoder.cc",
"./arch/victor9k/encoder.cc",
"./arch/zilogmcz/decoder.cc",
],
hdrs={
"arch/ibm/ibm.h": "./arch/ibm/ibm.h",
"arch/apple2/data_gcr.h": "./arch/apple2/data_gcr.h",
"arch/apple2/apple2.h": "./arch/apple2/apple2.h",
"arch/smaky6/smaky6.h": "./arch/smaky6/smaky6.h",
"arch/tids990/tids990.h": "./arch/tids990/tids990.h",
"arch/zilogmcz/zilogmcz.h": "./arch/zilogmcz/zilogmcz.h",
"arch/amiga/amiga.h": "./arch/amiga/amiga.h",
"arch/f85/data_gcr.h": "./arch/f85/data_gcr.h",
"arch/f85/f85.h": "./arch/f85/f85.h",
"arch/mx/mx.h": "./arch/mx/mx.h",
"arch/aeslanier/aeslanier.h": "./arch/aeslanier/aeslanier.h",
"arch/northstar/northstar.h": "./arch/northstar/northstar.h",
"arch/brother/data_gcr.h": "./arch/brother/data_gcr.h",
"arch/brother/brother.h": "./arch/brother/brother.h",
"arch/brother/header_gcr.h": "./arch/brother/header_gcr.h",
"arch/macintosh/data_gcr.h": "./arch/macintosh/data_gcr.h",
"arch/macintosh/macintosh.h": "./arch/macintosh/macintosh.h",
"arch/agat/agat.h": "./arch/agat/agat.h",
"arch/fb100/fb100.h": "./arch/fb100/fb100.h",
"arch/victor9k/data_gcr.h": "./arch/victor9k/data_gcr.h",
"arch/victor9k/victor9k.h": "./arch/victor9k/victor9k.h",
"arch/rolandd20/rolandd20.h": "./arch/rolandd20/rolandd20.h",
"arch/micropolis/micropolis.h": "./arch/micropolis/micropolis.h",
"arch/q1/q1.h": "./arch/q1/q1.h",
"arch/c64/data_gcr.h": "./arch/c64/data_gcr.h",
"arch/c64/c64.h": "./arch/c64/c64.h",
"lib/a2r.h": "./lib/a2r.h",
"lib/bitmap.h": "./lib/bitmap.h",
"lib/bytes.h": "./lib/bytes.h",
"lib/config.h": "./lib/config.h",
"lib/crc.h": "./lib/crc.h",
"lib/csvreader.h": "./lib/csvreader.h",
"lib/decoders/decoders.h": "./lib/decoders/decoders.h",
"lib/decoders/fluxdecoder.h": "./lib/decoders/fluxdecoder.h",
"lib/decoders/fluxmapreader.h": "./lib/decoders/fluxmapreader.h",
"lib/decoders/rawbits.h": "./lib/decoders/rawbits.h",
"lib/encoders/encoders.h": "./lib/encoders/encoders.h",
"lib/scp.h": "./lib/scp.h",
"lib/fl2.h": "./lib/fl2.h",
"lib/flags.h": "./lib/flags.h",
"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",
"lib/globals.h": "./lib/globals.h",
"lib/image.h": "./lib/image.h",
"lib/imagereader/imagereader.h": "./lib/imagereader/imagereader.h",
"lib/imagewriter/imagewriter.h": "./lib/imagewriter/imagewriter.h",
"lib/layout.h": "./lib/layout.h",
"lib/ldbs.h": "./lib/ldbs.h",
"lib/logger.h": "./lib/logger.h",
"lib/proto.h": "./lib/proto.h",
"lib/readerwriter.h": "./lib/readerwriter.h",
"lib/sector.h": "./lib/sector.h",
"lib/usb/greaseweazle.h": "./lib/usb/greaseweazle.h",
"lib/usb/usb.h": "./lib/usb/usb.h",
"lib/usb/usbfinder.h": "./lib/usb/usbfinder.h",
"lib/utils.h": "./lib/utils.h",
"lib/vfs/applesingle.h": "./lib/vfs/applesingle.h",
"lib/vfs/sectorinterface.h": "./lib/vfs/sectorinterface.h",
"lib/vfs/vfs.h": "./lib/vfs/vfs.h",
},
deps=[
"+fl2_proto_lib",
"+protocol",
"lib+config_proto_lib",
"dep/adflib",
"dep/agg",
"dep/fatfs",
"dep/hfsutils",
"dep/libusbp",
"dep/stb",
],
)
corpustests = []
if not glob("../fluxengine-testdata/data"):
print("fluxengine-testdata not found; skipping corpus tests")
else:
corpus = [
("agat", "", ""),
("amiga", "", ""),
("apple2", "", "--140 40track_drive"),
("atarist", "", "--360"),
("atarist", "", "--370"),
("atarist", "", "--400"),
("atarist", "", "--410"),
("atarist", "", "--720"),
("atarist", "", "--740"),
("atarist", "", "--800"),
("atarist", "", "--820"),
("bk", "", ""),
("brother", "", "--120 40track_drive"),
("brother", "", "--240"),
(
"commodore",
"scripts/commodore1541_test.textpb",
"--171 40track_drive",
),
(
"commodore",
"scripts/commodore1541_test.textpb",
"--192 40track_drive",
),
("commodore", "", "--800"),
("commodore", "", "--1620"),
("hplif", "", "--264"),
("hplif", "", "--608"),
("hplif", "", "--616"),
("hplif", "", "--770"),
("ibm", "", "--1200"),
("ibm", "", "--1232"),
("ibm", "", "--1440"),
("ibm", "", "--1680"),
("ibm", "", "--180 40track_drive"),
("ibm", "", "--160 40track_drive"),
("ibm", "", "--320 40track_drive"),
("ibm", "", "--360 40track_drive"),
("ibm", "", "--720_96"),
("ibm", "", "--720_135"),
("mac", "scripts/mac400_test.textpb", "--400"),
("mac", "scripts/mac800_test.textpb", "--800"),
("n88basic", "", ""),
("rx50", "", ""),
("tids990", "", ""),
("victor9k", "", "--612"),
("victor9k", "", "--1224"),
]
for c in corpus:
name = re.sub(r"[^a-zA-Z0-9]", "_", "".join(c), 0)
corpustests += [
test(
name=f"corpustest_{name}_{format}",
ins=["src+fluxengine"],
deps=["scripts/encodedecodetest.sh"],
commands=[
"{deps[0]} "
+ c[0]
+ " "
+ format
+ " {ins[0]} '"
+ c[1]
+ "' '"
+ c[2]
+ "' $(dir {outs[0]}) > /dev/null"
],
label="CORPUSTEST",
)
for format in ["scp", "flux"]
]
export(
name="all",
items={
"fluxengine$(EXT)": "src+fluxengine",
"fluxengine-gui$(EXT)": "src/gui",
"brother120tool$(EXT)": "tools+brother120tool",
"brother240tool$(EXT)": "tools+brother240tool",
"upgrade-flux-file$(EXT)": "tools+upgrade-flux-file",
}
| ({"FluxEngine.pkg": "src/gui+fluxengine_pkg"} if config.osx else {}),
deps=["tests", "src/formats+docs", "scripts+mkdocindex"] + corpustests,
)

19
build/_objectify.py Normal file
View File

@@ -0,0 +1,19 @@
import sys
from functools import partial
if len(sys.argv) != 3:
sys.exit("Usage: %s <file> <symbol>" % sys.argv[0])
filename = sys.argv[1]
symbol = sys.argv[2]
print("const uint8_t " + symbol + "[] = {")
n = 0
with open(filename, "rb") as in_file:
for c in iter(partial(in_file.read, 1), b""):
print("0x%02X," % ord(c), end="")
n += 1
if n % 16 == 0:
print()
print("};")
print("const size_t " + symbol + "_len = sizeof(" + symbol + ");")

42
build/ab.mk Normal file
View File

@@ -0,0 +1,42 @@
ifeq ($(findstring 4.,$(MAKE_VERSION)),)
$(error You need GNU Make 4.x for this (if you're on OSX, use gmake).)
endif
OBJ ?= .obj
PYTHON ?= python3
CC ?= gcc
CXX ?= g++
AR ?= ar
CFLAGS ?= -g -Og
LDFLAGS ?= -g
hide = @
PKG_CONFIG ?= pkg-config
ECHO ?= echo
ifeq ($(OS), Windows_NT)
EXT ?= .exe
endif
EXT ?=
include $(OBJ)/build.mk
.PHONY: update-ab
update-ab:
@echo "Press RETURN to update ab from the repository, or CTRL+C to cancel." \
&& read a \
&& (curl -L https://github.com/davidgiven/ab/releases/download/dev/distribution.tar.xz | tar xvJf -) \
&& echo "Done."
.PHONY: clean
clean::
@echo CLEAN
$(hide) rm -rf $(OBJ) bin
export PYTHONHASHSEED = 1
build-files = $(shell find . -name 'build.py') build/*.py config.py
$(OBJ)/build.mk: Makefile $(build-files)
@echo "AB"
@mkdir -p $(OBJ)
$(hide) $(PYTHON) -X pycache_prefix=$(OBJ) build/ab.py -t +all -o $@ \
build.py || rm -f $@

486
build/ab.py Normal file
View File

@@ -0,0 +1,486 @@
from collections.abc import Iterable, Sequence
from os.path import *
from types import SimpleNamespace
import argparse
import copy
import functools
import importlib
import importlib.abc
import importlib.util
import inspect
import re
import sys
import types
import pathlib
import builtins
import os
defaultGlobals = {}
targets = {}
unmaterialisedTargets = set()
materialisingStack = []
outputFp = None
cwdStack = [""]
sys.path += ["."]
old_import = builtins.__import__
def new_import(name, *args, **kwargs):
if name not in sys.modules:
path = name.replace(".", "/") + ".py"
if isfile(path):
sys.stderr.write(f"loading {path}\n")
loader = importlib.machinery.SourceFileLoader(name, path)
spec = importlib.util.spec_from_loader(
name, loader, origin="built-in"
)
module = importlib.util.module_from_spec(spec)
sys.modules[name] = module
cwdStack.append(dirname(path))
spec.loader.exec_module(module)
cwdStack.pop()
return old_import(name, *args, **kwargs)
builtins.__import__ = new_import
class ABException(BaseException):
pass
class ParameterList(Sequence):
def __init__(self, parent=[]):
self.data = parent
def __getitem__(self, i):
return self.data[i]
def __len__(self):
return len(self.data)
def __str__(self):
return " ".join(self.data)
def __add__(self, other):
newdata = self.data.copy() + other
return ParameterList(newdata)
def __repr__(self):
return f"<PList: {self.data}>"
class Invocation:
name = None
callback = None
types = None
ins = None
outs = None
binding = None
def materialise(self, replacing=False):
if self in unmaterialisedTargets:
if not replacing and (self in materialisingStack):
print("Found dependency cycle:")
for i in materialisingStack:
print(f" {i.name}")
print(f" {self.name}")
sys.exit(1)
materialisingStack.append(self)
# Perform type conversion to the declared rule parameter types.
try:
self.args = {}
for k, v in self.binding.arguments.items():
if k != "kwargs":
t = self.types.get(k, None)
if t:
v = t(v).convert(self)
self.args[k] = v
else:
for kk, vv in v.items():
t = self.types.get(kk, None)
if t:
vv = t(vv).convert(self)
self.args[kk] = vv
# Actually call the callback.
cwdStack.append(self.cwd)
self.callback(**self.args)
cwdStack.pop()
except BaseException as e:
print(
f"Error materialising {self} ({id(self)}): {self.callback}"
)
print(f"Arguments: {self.args}")
raise e
if self.outs is None:
raise ABException(f"{self.name} didn't set self.outs")
if self in unmaterialisedTargets:
unmaterialisedTargets.remove(self)
materialisingStack.pop()
def __repr__(self):
return "<Invocation %s>" % self.name
def Rule(func):
sig = inspect.signature(func)
@functools.wraps(func)
def wrapper(*, name=None, replaces=None, **kwargs):
cwd = None
if name:
if ("+" in name) and not name.startswith("+"):
(cwd, _) = name.split("+", 1)
if not cwd:
cwd = cwdStack[-1]
if name:
i = Invocation()
if name.startswith("./"):
name = join(cwd, name)
elif "+" not in name:
name = cwd + "+" + name
i.name = name
i.localname = name.split("+")[-1]
if name in targets:
raise ABException(f"target {i.name} has already been defined")
targets[name] = i
elif replaces:
i = replaces
name = i.name
else:
raise ABException("you must supply either name or replaces")
i.cwd = cwd
i.types = func.__annotations__
i.callback = func
setattr(i, func.__name__, SimpleNamespace())
i.binding = sig.bind(name=name, self=i, **kwargs)
i.binding.apply_defaults()
unmaterialisedTargets.add(i)
if replaces:
i.materialise(replacing=True)
return i
defaultGlobals[func.__name__] = wrapper
return wrapper
class Type:
def __init__(self, value):
self.value = value
class Targets(Type):
def convert(self, invocation):
value = self.value
if type(value) is str:
value = [value]
if type(value) is list:
value = targetsof(value, cwd=invocation.cwd)
return value
class Target(Type):
def convert(self, invocation):
value = self.value
if not value:
return None
return targetof(value, cwd=invocation.cwd)
class TargetsMap(Type):
def convert(self, invocation):
value = self.value
if type(value) is dict:
return {
k: targetof(v, cwd=invocation.cwd) for k, v in value.items()
}
raise ABException(f"wanted a dict of targets, got a {type(value)}")
def flatten(*xs):
def recurse(xs):
for x in xs:
if isinstance(x, Iterable) and not isinstance(x, (str, bytes)):
yield from recurse(x)
else:
yield x
return list(recurse(xs))
def fileinvocation(s):
i = Invocation()
i.name = s
i.outs = [s]
targets[s] = i
return i
def targetof(s, cwd):
if isinstance(s, Invocation):
s.materialise()
return s
if s in targets:
t = targets[s]
t.materialise()
return t
if s.startswith(".+"):
s = cwd + s[1:]
elif s.startswith("./"):
s = normpath(join(cwd, s))
elif s.endswith("/"):
return fileinvocation(s)
elif s.startswith("$"):
return fileinvocation(s)
if "+" not in s:
if isdir(s):
s = s + "+" + basename(s)
else:
return fileinvocation(s)
(path, target) = s.split("+", 2)
loadbuildfile(join(path, "build.py"))
if not s in targets:
raise ABException(f"build file at {path} doesn't contain +{target}")
i = targets[s]
i.materialise()
return i
def targetsof(*xs, cwd):
return flatten([targetof(x, cwd) for x in flatten(xs)])
def filenamesof(*xs):
s = []
for t in flatten(xs):
if type(t) == str:
t = normpath(t)
s += [t]
else:
s += [f for f in [normpath(f) for f in filenamesof(t.outs)]]
return s
def targetnamesof(*xs):
s = []
for x in flatten(xs):
if type(x) == str:
x = normpath(x)
if x not in s:
s += [x]
else:
if x.name not in s:
s += [x.name]
return s
def filenameof(x):
xs = filenamesof(x)
if len(xs) != 1:
raise ABException("expected a single item")
return xs[0]
def stripext(path):
return splitext(path)[0]
def emit(*args):
outputFp.write(" ".join(flatten(args)))
outputFp.write("\n")
def templateexpand(s, invocation):
class Converter:
def __getitem__(self, key):
if key == "self":
return invocation
f = filenamesof(invocation.args[key])
if isinstance(f, Sequence):
f = ParameterList(f)
return f
return eval("f%r" % s, invocation.callback.__globals__, Converter())
def emitter_rule(name, ins, outs, deps=[]):
emit("")
emit(".PHONY:", name)
if outs:
emit(name, ":", filenamesof(outs), ";")
emit(filenamesof(outs), "&:", filenamesof(ins), filenamesof(deps))
else:
emit(name, "&:", filenamesof(ins), filenamesof(deps))
def emitter_endrule(name):
pass
def emitter_label(s):
emit("\t$(hide)", "$(ECHO)", s)
def emitter_exec(cs):
for c in cs:
emit("\t$(hide)", c)
def unmake(*ss):
return [
re.sub(r"\$\(([^)]*)\)", r"$\1", s) for s in flatten(filenamesof(ss))
]
@Rule
def simplerule(
self,
name,
ins: Targets = [],
outs=[],
deps: Targets = [],
commands=[],
label="RULE",
**kwargs,
):
self.ins = ins
self.outs = outs
self.deps = deps
emitter_rule(self.name, ins + deps, outs)
emitter_label(templateexpand("{label} {name}", self))
dirs = []
for out in filenamesof(outs):
dir = dirname(out)
if dir and dir not in dirs:
dirs += [dir]
cs = [("mkdir -p %s" % dir) for dir in dirs]
for c in commands:
cs += [templateexpand(c, self)]
emitter_exec(cs)
emitter_endrule(self.name)
@Rule
def normalrule(
self,
name=None,
ins: Targets = [],
deps: Targets = [],
outs=[],
label="RULE",
objdir=None,
commands=[],
**kwargs,
):
objdir = objdir or join("$(OBJ)", name)
self.normalrule.objdir = objdir
simplerule(
replaces=self,
ins=ins,
deps=deps,
outs=[join(objdir, f) for f in outs],
label=label,
commands=commands,
**kwargs,
)
@Rule
def export(self, name=None, items: TargetsMap = {}, deps: Targets = []):
cs = []
self.ins = items.values()
self.outs = []
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:
raise ABException(
"a dependency of an export must have exactly one output file"
)
cs += ["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)
if self.outs:
emit("clean::")
emit("\t$(hide) rm -f " + (" ".join(filenamesof(self.outs))))
self.outs += deps
emitter_endrule(self.name)
def loadbuildfile(filename):
filename = filename.replace("/", ".").removesuffix(".py")
builtins.__import__(filename)
def load(filename):
loadbuildfile(filename)
callerglobals = inspect.stack()[1][0].f_globals
for k, v in defaultGlobals.items():
callerglobals[k] = v
def main():
parser = argparse.ArgumentParser()
parser.add_argument("-o", "--output")
parser.add_argument("files", nargs="+")
parser.add_argument("-t", "--targets", action="append")
args = parser.parse_args()
if not args.targets:
raise ABException("no targets supplied")
global outputFp
outputFp = open(args.output, "wt")
for k in ("Rule", "Targets", "load", "filenamesof", "stripext"):
defaultGlobals[k] = globals()[k]
global __name__
sys.modules["build.ab"] = sys.modules[__name__]
__name__ = "build.ab"
for f in args.files:
loadbuildfile(f)
for t in flatten([a.split(",") for a in args.targets]):
if t not in targets:
raise ABException("target %s is not defined" % t)
targets[t].materialise()
emit("AB_LOADED = 1\n")
main()

265
build/c.py Normal file
View File

@@ -0,0 +1,265 @@
from os.path import basename, join
from build.ab import (
ABException,
Rule,
Targets,
TargetsMap,
filenameof,
flatten,
filenamesof,
normalrule,
stripext,
)
from os.path import *
from types import SimpleNamespace
def cfileimpl(self, name, srcs, deps, suffix, commands, label, kind, cflags):
outleaf = stripext(basename(filenameof(srcs[0]))) + suffix
normalrule(
replaces=self,
ins=srcs,
deps=deps,
outs=[outleaf],
label=label,
commands=commands,
cflags=cflags,
)
@Rule
def cfile(
self,
name,
srcs: Targets = [],
deps: Targets = [],
cflags=[],
suffix=".o",
commands=["$(CC) -c -o {outs[0]} {ins[0]} $(CFLAGS) {cflags}"],
label="CC",
):
cfileimpl(self, name, srcs, deps, suffix, commands, label, "cfile", cflags)
@Rule
def cxxfile(
self,
name,
srcs: Targets = [],
deps: Targets = [],
cflags=[],
suffix=".o",
commands=["$(CXX) -c -o {outs[0]} {ins[0]} $(CFLAGS) {cflags}"],
label="CXX",
):
cfileimpl(
self, name, srcs, deps, suffix, commands, label, "cxxfile", cflags
)
def findsources(name, srcs, deps, cflags, filerule):
objs = []
for s in flatten(srcs):
objs += [
filerule(
name=join(name, f.removeprefix("$(OBJ)/")),
srcs=[f],
deps=deps,
cflags=cflags,
)
for f in filenamesof(s)
if f.endswith(".c") or f.endswith(".cc") or f.endswith(".cpp")
]
if any(f.endswith(".o") for f in filenamesof(s)):
objs += [s]
return objs
def libraryimpl(
self, name, srcs, deps, hdrs, cflags, ldflags, commands, label, kind
):
if not srcs and not hdrs:
raise ABException(
"clibrary contains no sources and no exported headers"
)
libraries = [d for d in deps if hasattr(d, "clibrary")]
for library in libraries:
if library.clibrary.cflags:
cflags += library.clibrary.cflags
if library.clibrary.ldflags:
ldflags += library.clibrary.ldflags
for f in filenamesof(srcs):
if f.endswith(".h"):
deps += [f]
hdrcs = []
hdrins = list(hdrs.values())
hdrouts = []
i = 0
for dest, src in hdrs.items():
s = filenamesof(src)
if len(s) != 1:
raise ABException(
"a dependency of an export must have exactly one output file"
)
hdrcs += ["cp {ins[" + str(i) + "]} {outs[" + str(i) + "]}"]
hdrouts += [dest]
i = i + 1
if not hasattr(self, "clibrary"):
self.clibrary = SimpleNamespace()
if srcs:
hr = None
if hdrcs:
hr = normalrule(
name=f"{name}_hdrs",
ins=hdrins,
outs=hdrouts,
label="HEADERS",
commands=hdrcs,
)
hr.materialise()
actualsrcs = findsources(
name,
srcs,
deps + ([f"{name}_hdrs"] if hr else []),
cflags + ([f"-I{hr.normalrule.objdir}"] if hr else []),
kind,
)
normalrule(
replaces=self,
ins=actualsrcs,
outs=[basename(name) + ".a"],
label=label,
commands=commands if actualsrcs else [],
)
self.clibrary.ldflags = ldflags
self.clibrary.cflags = ["-I" + hr.normalrule.objdir] if hr else []
else:
r = normalrule(
replaces=self,
ins=hdrins,
outs=hdrouts,
label="HEADERS",
commands=hdrcs,
)
r.materialise()
self.clibrary.ldflags = ldflags
self.clibrary.cflags = ["-I" + r.normalrule.objdir]
@Rule
def clibrary(
self,
name,
srcs: Targets = [],
deps: Targets = [],
hdrs: TargetsMap = {},
cflags=[],
ldflags=[],
commands=["$(AR) cqs {outs[0]} {ins}"],
label="LIB",
):
return libraryimpl(
self, name, srcs, deps, hdrs, cflags, ldflags, commands, label, cfile
)
@Rule
def cxxlibrary(
self,
name,
srcs: Targets = [],
deps: Targets = [],
hdrs: TargetsMap = {},
cflags=[],
ldflags=[],
commands=["$(AR) cqs {outs[0]} {ins}"],
label="LIB",
):
return libraryimpl(
self, name, srcs, deps, hdrs, cflags, ldflags, commands, label, cxxfile
)
def programimpl(
self, name, srcs, deps, cflags, ldflags, commands, label, filerule, kind
):
libraries = [d for d in deps if hasattr(d, "clibrary")]
for library in libraries:
if library.clibrary.cflags:
cflags += library.clibrary.cflags
if library.clibrary.ldflags:
ldflags += library.clibrary.ldflags
deps += [f for f in filenamesof(srcs) if f.endswith(".h")]
ars = [f for f in filenamesof(libraries) if f.endswith(".a")]
normalrule(
replaces=self,
ins=(findsources(name, srcs, deps, cflags, filerule) + ars + ars),
outs=[basename(name) + "$(EXT)"],
deps=deps,
label=label,
commands=commands,
ldflags=ldflags,
)
@Rule
def cprogram(
self,
name,
srcs: Targets = [],
deps: Targets = [],
cflags=[],
ldflags=[],
commands=["$(CC) -o {outs[0]} {ins} {ldflags} $(LDFLAGS)"],
label="CLINK",
):
programimpl(
self,
name,
srcs,
deps,
cflags,
ldflags,
commands,
label,
cfile,
"cprogram",
)
@Rule
def cxxprogram(
self,
name,
srcs: Targets = [],
deps: Targets = [],
cflags=[],
ldflags=[],
commands=["$(CXX) -o {outs[0]} {ins} {ldflags} $(LDFLAGS)"],
label="CXXLINK",
):
programimpl(
self,
name,
srcs,
deps,
cflags,
ldflags,
commands,
label,
cxxfile,
"cxxprogram",
)

38
build/pkg.py Normal file
View File

@@ -0,0 +1,38 @@
from build.ab import Rule, emit, Target
from types import SimpleNamespace
import os
import subprocess
emit(
"""
PKG_CONFIG ?= pkg-config
PACKAGES := $(shell $(PKG_CONFIG) --list-all | cut -d' ' -f1)
"""
)
@Rule
def package(self, name, package=None, fallback: Target = None):
emit("ifeq ($(filter %s, $(PACKAGES)),)" % package)
if fallback:
emit(f"PACKAGE_CFLAGS_{package} :=", fallback.clibrary.cflags)
emit(f"PACKAGE_LDFLAGS_{package} := ", fallback.clibrary.ldflags)
emit(f"PACKAGE_DEP_{package} := ", fallback.name)
else:
emit(f"$(error Required package '{package}' not installed.)")
emit("else")
emit(
f"PACKAGE_CFLAGS_{package} := $(shell $(PKG_CONFIG) --cflags {package})"
)
emit(
f"PACKAGE_LDFLAGS_{package} := $(shell $(PKG_CONFIG) --libs {package})"
)
emit(f"PACKAGE_DEP_{package} := ")
emit("endif")
self.clibrary = SimpleNamespace()
self.clibrary.cflags = [f"$(PACKAGE_CFLAGS_{package})"]
self.clibrary.ldflags = [f"$(PACKAGE_LDFLAGS_{package})"]
self.ins = []
self.outs = [f"$(PACKAGE_DEP_{package})"]

65
build/protobuf.py Normal file
View File

@@ -0,0 +1,65 @@
from os.path import join
from build.ab import Rule, Targets, emit, normalrule, filenamesof, flatten
from build.c import cxxlibrary
import build.pkg
from types import SimpleNamespace
emit(
"""
PROTOC ?= protoc
ifeq ($(filter protobuf, $(PACKAGES)),)
$(error Required package 'protobuf' not installed.)"
endif
"""
)
@Rule
def proto(self, name, srcs: Targets = [], deps: Targets = []):
normalrule(
replaces=self,
ins=srcs,
outs=[f"{name}.descriptor"],
deps=deps,
commands=[
"$(PROTOC) --include_source_info --descriptor_set_out={outs[0]} {ins}"
],
label="PROTO",
)
self.proto.srcs = filenamesof(srcs) + flatten(
[s.proto.srcs for s in flatten(deps)]
)
@Rule
def protocc(self, name, srcs: Targets = [], deps: Targets = []):
outs = []
protos = []
for f in flatten([s.proto.srcs for s in flatten(srcs + deps)]):
if f.endswith(".proto"):
cc = f.replace(".proto", ".pb.cc")
h = f.replace(".proto", ".pb.h")
protos += [f]
srcs += [f]
outs += [cc, h]
r = normalrule(
name=f"{name}_srcs",
ins=protos,
outs=outs,
deps=deps,
commands=["$(PROTOC) --cpp_out={self.normalrule.objdir} {ins}"],
label="PROTOCC",
)
r.materialise()
headers = {
f: join(r.normalrule.objdir, f) for f in outs if f.endswith(".pb.h")
}
cxxlibrary(
replaces=self,
srcs=[f"{name}_srcs"],
hdrs=headers,
cflags=[f"-I{r.normalrule.objdir}"],
)

43
build/utils.py Normal file
View File

@@ -0,0 +1,43 @@
from build.ab import Rule, normalrule, Target, filenameof, Targets
from os.path import basename
@Rule
def objectify(self, name, src: Target, symbol):
normalrule(
replaces=self,
ins=["build/_objectify.py", src],
outs=[basename(filenameof(src)) + ".h"],
commands=["$(PYTHON) {ins[0]} {ins[1]} " + symbol + " > {outs}"],
label="OBJECTIFY",
)
@Rule
def test(
self,
name,
command: Target = None,
commands=None,
ins: Targets = [],
deps: Targets = [],
label="TEST",
):
if command:
normalrule(
replaces=self,
ins=[command],
outs=["sentinel"],
commands=["{ins[0]}", "touch {outs}"],
deps=deps,
label=label,
)
else:
normalrule(
replaces=self,
ins=ins,
outs=["sentinel"],
commands=commands + ["touch {outs}"],
deps=deps,
label=label,
)

5
config.py Normal file
View File

@@ -0,0 +1,5 @@
import platform
windows = platform.system() == "Windows"
osx = platform.system() == "Darwin"
unix = not windows

View File

@@ -1,22 +0,0 @@
ADFLIB_SRCS = \
dep/adflib/src/adf_bitm.c \
dep/adflib/src/adf_cache.c \
dep/adflib/src/adf_dir.c \
dep/adflib/src/adf_disk.c \
dep/adflib/src/adf_dump.c \
dep/adflib/src/adf_env.c \
dep/adflib/src/adf_file.c \
dep/adflib/src/adf_hd.c \
dep/adflib/src/adf_link.c \
dep/adflib/src/adf_raw.c \
dep/adflib/src/adf_salv.c \
dep/adflib/src/adf_util.c \
ADFLIB_OBJS = $(patsubst %.c, $(OBJDIR)/%.o, $(ADFLIB_SRCS))
$(ADFLIB_OBJS): CFLAGS += -Idep/adflib/src -Idep/adflib
ADFLIB_LIB = $(OBJDIR)/libadflib.a
$(ADFLIB_LIB): $(ADFLIB_OBJS)
ADFLIB_CFLAGS = -Idep/adflib/src
ADFLIB_LDFLAGS =
OBJS += $(ADFLIB_OBJS)

47
dep/adflib/build.py Normal file
View File

@@ -0,0 +1,47 @@
from build.c import clibrary
clibrary(
name="adflib",
srcs=[
"./src/adf_bitm.c",
"./src/adf_bitm.h",
"./src/adf_cache.c",
"./src/adf_cache.h",
"./src/adf_dir.c",
"./src/adf_dir.h",
"./src/adf_disk.c",
"./src/adf_disk.h",
"./src/adf_dump.c",
"./src/adf_dump.h",
"./src/adf_env.c",
"./src/adf_env.h",
"./src/adf_file.c",
"./src/adf_file.h",
"./src/adf_hd.c",
"./src/adf_hd.h",
"./src/adf_link.c",
"./src/adf_link.h",
"./src/adf_raw.c",
"./src/adf_raw.h",
"./src/adf_salv.c",
"./src/adf_salv.h",
"./src/adf_str.h",
"./src/adf_util.c",
"./src/adf_util.h",
"./src/defendian.h",
"./src/hd_blk.h",
"./src/prefix.h",
"./adf_nativ.h",
"./config.h",
"./src/adflib.h",
],
cflags=["-Idep/adflib", "-Idep/adflib/src"],
hdrs={
"adf_blk.h": "./src/adf_blk.h",
"adf_defs.h": "./src/adf_defs.h",
"adf_err.h": "./src/adf_err.h",
"adf_nativ.h": "./adf_nativ.h",
"adf_str.h": "./src/adf_str.h",
"adflib.h": "./src/adflib.h",
},
)

View File

@@ -1,38 +0,0 @@
AGG_SRCS = \
dep/agg/src/agg_arrowhead.cpp \
dep/agg/src/agg_line_aa_basics.cpp \
dep/agg/src/agg_vcgen_bspline.cpp \
dep/agg/src/agg_vpgen_segmentator.cpp \
dep/agg/src/agg_color_rgba.cpp \
dep/agg/src/agg_sqrt_tables.cpp \
dep/agg/src/agg_bspline.cpp \
dep/agg/src/agg_curves.cpp \
dep/agg/src/agg_rounded_rect.cpp \
dep/agg/src/agg_vcgen_markers_term.cpp \
dep/agg/src/agg_vcgen_dash.cpp \
dep/agg/src/agg2d.cpp \
dep/agg/src/agg_trans_affine.cpp \
dep/agg/src/agg_gsv_text.cpp \
dep/agg/src/agg_vcgen_smooth_poly1.cpp \
dep/agg/src/agg_trans_single_path.cpp \
dep/agg/src/agg_vpgen_clip_polygon.cpp \
dep/agg/src/agg_embedded_raster_fonts.cpp \
dep/agg/src/agg_trans_double_path.cpp \
dep/agg/src/agg_vcgen_stroke.cpp \
dep/agg/src/agg_arc.cpp \
dep/agg/src/agg_image_filters.cpp \
dep/agg/src/agg_trans_warp_magnifier.cpp \
dep/agg/src/agg_vpgen_clip_polyline.cpp \
dep/agg/src/agg_bezier_arc.cpp \
dep/agg/src/agg_line_profile_aa.cpp \
dep/agg/src/agg_vcgen_contour.cpp \
AGG_OBJS = $(patsubst %.cpp, $(OBJDIR)/%.o, $(AGG_SRCS))
AGG_LIB = $(OBJDIR)/libagg.a
$(AGG_LIB): $(AGG_OBJS)
AGG_LDFLAGS = $(AGG_LIB)
AGG_CFLAGS = -Idep/agg/include
OBJS += $(AGG_OBJS)
$(AGG_OBJS): CFLAGS += $(AGG_CFLAGS)

164
dep/agg/build.py Normal file
View File

@@ -0,0 +1,164 @@
from build.c import cxxlibrary
cxxlibrary(
name="agg",
srcs=[
"./src/agg_arrowhead.cpp",
"./src/agg_line_aa_basics.cpp",
"./src/agg_vcgen_bspline.cpp",
"./src/agg_vpgen_segmentator.cpp",
"./src/agg_color_rgba.cpp",
"./src/agg_sqrt_tables.cpp",
"./src/agg_bspline.cpp",
"./src/agg_curves.cpp",
"./src/agg_rounded_rect.cpp",
"./src/agg_vcgen_markers_term.cpp",
"./src/agg_vcgen_dash.cpp",
"./src/agg2d.cpp",
"./src/agg_trans_affine.cpp",
"./src/agg_gsv_text.cpp",
"./src/agg_vcgen_smooth_poly1.cpp",
"./src/agg_trans_single_path.cpp",
"./src/agg_vpgen_clip_polygon.cpp",
"./src/agg_embedded_raster_fonts.cpp",
"./src/agg_trans_double_path.cpp",
"./src/agg_vcgen_stroke.cpp",
"./src/agg_arc.cpp",
"./src/agg_image_filters.cpp",
"./src/agg_trans_warp_magnifier.cpp",
"./src/agg_vpgen_clip_polyline.cpp",
"./src/agg_bezier_arc.cpp",
"./src/agg_line_profile_aa.cpp",
"./src/agg_vcgen_contour.cpp",
],
hdrs={
"agg2d.h": "./include/agg2d.h",
"agg_alpha_mask_u8.h": "./include/agg_alpha_mask_u8.h",
"agg_arc.h": "./include/agg_arc.h",
"agg_array.h": "./include/agg_array.h",
"agg_arrowhead.h": "./include/agg_arrowhead.h",
"agg_basics.h": "./include/agg_basics.h",
"agg_bezier_arc.h": "./include/agg_bezier_arc.h",
"agg_bitset_iterator.h": "./include/agg_bitset_iterator.h",
"agg_blur.h": "./include/agg_blur.h",
"agg_bounding_rect.h": "./include/agg_bounding_rect.h",
"agg_bspline.h": "./include/agg_bspline.h",
"agg_clip_liang_barsky.h": "./include/agg_clip_liang_barsky.h",
"agg_color_gray.h": "./include/agg_color_gray.h",
"agg_color_rgba.h": "./include/agg_color_rgba.h",
"agg_config.h": "./include/agg_config.h",
"agg_conv_adaptor_vcgen.h": "./include/agg_conv_adaptor_vcgen.h",
"agg_conv_adaptor_vpgen.h": "./include/agg_conv_adaptor_vpgen.h",
"agg_conv_bspline.h": "./include/agg_conv_bspline.h",
"agg_conv_clip_polygon.h": "./include/agg_conv_clip_polygon.h",
"agg_conv_clip_polyline.h": "./include/agg_conv_clip_polyline.h",
"agg_conv_close_polygon.h": "./include/agg_conv_close_polygon.h",
"agg_conv_concat.h": "./include/agg_conv_concat.h",
"agg_conv_contour.h": "./include/agg_conv_contour.h",
"agg_conv_curve.h": "./include/agg_conv_curve.h",
"agg_conv_dash.h": "./include/agg_conv_dash.h",
"agg_conv_gpc.h": "./include/agg_conv_gpc.h",
"agg_conv_marker_adaptor.h": "./include/agg_conv_marker_adaptor.h",
"agg_conv_marker.h": "./include/agg_conv_marker.h",
"agg_conv_segmentator.h": "./include/agg_conv_segmentator.h",
"agg_conv_shorten_path.h": "./include/agg_conv_shorten_path.h",
"agg_conv_smooth_poly1.h": "./include/agg_conv_smooth_poly1.h",
"agg_conv_stroke.h": "./include/agg_conv_stroke.h",
"agg_conv_transform.h": "./include/agg_conv_transform.h",
"agg_conv_unclose_polygon.h": "./include/agg_conv_unclose_polygon.h",
"agg_curves.h": "./include/agg_curves.h",
"agg_dda_line.h": "./include/agg_dda_line.h",
"agg_ellipse_bresenham.h": "./include/agg_ellipse_bresenham.h",
"agg_ellipse.h": "./include/agg_ellipse.h",
"agg_embedded_raster_fonts.h": "./include/agg_embedded_raster_fonts.h",
"agg_font_cache_manager2.h": "./include/agg_font_cache_manager2.h",
"agg_font_cache_manager.h": "./include/agg_font_cache_manager.h",
"agg_gamma_functions.h": "./include/agg_gamma_functions.h",
"agg_gamma_lut.h": "./include/agg_gamma_lut.h",
"agg_glyph_raster_bin.h": "./include/agg_glyph_raster_bin.h",
"agg_gradient_lut.h": "./include/agg_gradient_lut.h",
"agg_gsv_text.h": "./include/agg_gsv_text.h",
"agg_image_accessors.h": "./include/agg_image_accessors.h",
"agg_image_filters.h": "./include/agg_image_filters.h",
"agg_line_aa_basics.h": "./include/agg_line_aa_basics.h",
"agg_math.h": "./include/agg_math.h",
"agg_math_stroke.h": "./include/agg_math_stroke.h",
"agg_path_length.h": "./include/agg_path_length.h",
"agg_path_storage.h": "./include/agg_path_storage.h",
"agg_path_storage_integer.h": "./include/agg_path_storage_integer.h",
"agg_pattern_filters_rgba.h": "./include/agg_pattern_filters_rgba.h",
"agg_pixfmt_amask_adaptor.h": "./include/agg_pixfmt_amask_adaptor.h",
"agg_pixfmt_base.h": "./include/agg_pixfmt_base.h",
"agg_pixfmt_gray.h": "./include/agg_pixfmt_gray.h",
"agg_pixfmt_rgba.h": "./include/agg_pixfmt_rgba.h",
"agg_pixfmt_rgb.h": "./include/agg_pixfmt_rgb.h",
"agg_pixfmt_rgb_packed.h": "./include/agg_pixfmt_rgb_packed.h",
"agg_pixfmt_transposer.h": "./include/agg_pixfmt_transposer.h",
"agg_rasterizer_cells_aa.h": "./include/agg_rasterizer_cells_aa.h",
"agg_rasterizer_compound_aa.h": "./include/agg_rasterizer_compound_aa.h",
"agg_rasterizer_outline_aa.h": "./include/agg_rasterizer_outline_aa.h",
"agg_rasterizer_outline.h": "./include/agg_rasterizer_outline.h",
"agg_rasterizer_scanline_aa.h": "./include/agg_rasterizer_scanline_aa.h",
"agg_rasterizer_scanline_aa_nogamma.h": "./include/agg_rasterizer_scanline_aa_nogamma.h",
"agg_rasterizer_sl_clip.h": "./include/agg_rasterizer_sl_clip.h",
"agg_renderer_base.h": "./include/agg_renderer_base.h",
"agg_renderer_markers.h": "./include/agg_renderer_markers.h",
"agg_renderer_mclip.h": "./include/agg_renderer_mclip.h",
"agg_renderer_outline_aa.h": "./include/agg_renderer_outline_aa.h",
"agg_renderer_outline_image.h": "./include/agg_renderer_outline_image.h",
"agg_renderer_primitives.h": "./include/agg_renderer_primitives.h",
"agg_renderer_raster_text.h": "./include/agg_renderer_raster_text.h",
"agg_renderer_scanline.h": "./include/agg_renderer_scanline.h",
"agg_rendering_buffer_dynarow.h": "./include/agg_rendering_buffer_dynarow.h",
"agg_rendering_buffer.h": "./include/agg_rendering_buffer.h",
"agg_rounded_rect.h": "./include/agg_rounded_rect.h",
"agg_scanline_bin.h": "./include/agg_scanline_bin.h",
"agg_scanline_boolean_algebra.h": "./include/agg_scanline_boolean_algebra.h",
"agg_scanline_p.h": "./include/agg_scanline_p.h",
"agg_scanline_storage_aa.h": "./include/agg_scanline_storage_aa.h",
"agg_scanline_storage_bin.h": "./include/agg_scanline_storage_bin.h",
"agg_scanline_u.h": "./include/agg_scanline_u.h",
"agg_shorten_path.h": "./include/agg_shorten_path.h",
"agg_simul_eq.h": "./include/agg_simul_eq.h",
"agg_span_allocator.h": "./include/agg_span_allocator.h",
"agg_span_converter.h": "./include/agg_span_converter.h",
"agg_span_gouraud_gray.h": "./include/agg_span_gouraud_gray.h",
"agg_span_gouraud.h": "./include/agg_span_gouraud.h",
"agg_span_gouraud_rgba.h": "./include/agg_span_gouraud_rgba.h",
"agg_span_gradient_alpha.h": "./include/agg_span_gradient_alpha.h",
"agg_span_gradient_contour.h": "./include/agg_span_gradient_contour.h",
"agg_span_gradient.h": "./include/agg_span_gradient.h",
"agg_span_gradient_image.h": "./include/agg_span_gradient_image.h",
"agg_span_image_filter_gray.h": "./include/agg_span_image_filter_gray.h",
"agg_span_image_filter.h": "./include/agg_span_image_filter.h",
"agg_span_image_filter_rgba.h": "./include/agg_span_image_filter_rgba.h",
"agg_span_image_filter_rgb.h": "./include/agg_span_image_filter_rgb.h",
"agg_span_interpolator_adaptor.h": "./include/agg_span_interpolator_adaptor.h",
"agg_span_interpolator_linear.h": "./include/agg_span_interpolator_linear.h",
"agg_span_interpolator_persp.h": "./include/agg_span_interpolator_persp.h",
"agg_span_interpolator_trans.h": "./include/agg_span_interpolator_trans.h",
"agg_span_pattern_gray.h": "./include/agg_span_pattern_gray.h",
"agg_span_pattern_rgba.h": "./include/agg_span_pattern_rgba.h",
"agg_span_pattern_rgb.h": "./include/agg_span_pattern_rgb.h",
"agg_span_solid.h": "./include/agg_span_solid.h",
"agg_span_subdiv_adaptor.h": "./include/agg_span_subdiv_adaptor.h",
"agg_trans_affine.h": "./include/agg_trans_affine.h",
"agg_trans_bilinear.h": "./include/agg_trans_bilinear.h",
"agg_trans_double_path.h": "./include/agg_trans_double_path.h",
"agg_trans_perspective.h": "./include/agg_trans_perspective.h",
"agg_trans_single_path.h": "./include/agg_trans_single_path.h",
"agg_trans_viewport.h": "./include/agg_trans_viewport.h",
"agg_trans_warp_magnifier.h": "./include/agg_trans_warp_magnifier.h",
"agg_vcgen_bspline.h": "./include/agg_vcgen_bspline.h",
"agg_vcgen_contour.h": "./include/agg_vcgen_contour.h",
"agg_vcgen_dash.h": "./include/agg_vcgen_dash.h",
"agg_vcgen_markers_term.h": "./include/agg_vcgen_markers_term.h",
"agg_vcgen_smooth_poly1.h": "./include/agg_vcgen_smooth_poly1.h",
"agg_vcgen_stroke.h": "./include/agg_vcgen_stroke.h",
"agg_vcgen_vertex_sequence.h": "./include/agg_vcgen_vertex_sequence.h",
"agg_vertex_sequence.h": "./include/agg_vertex_sequence.h",
"agg_vpgen_clip_polygon.h": "./include/agg_vpgen_clip_polygon.h",
"agg_vpgen_clip_polyline.h": "./include/agg_vpgen_clip_polyline.h",
"agg_vpgen_segmentator.h": "./include/agg_vpgen_segmentator.h",
},
)

View File

@@ -1,21 +0,0 @@
ifeq ($(OS), Windows_NT)
EMU_SRCS = \
dep/emu/fnmatch.c
EMU_OBJS = $(patsubst %.c, $(OBJDIR)/%.o, $(EMU_SRCS))
$(EMU_OBJS): CFLAGS += -Idep/emu
EMU_LIB = $(OBJDIR)/libemu.a
$(EMU_LIB): $(EMU_OBJS)
EMU_CFLAGS = -Idep/emu
EMU_LDFLAGS = $(EMU_LIB)
OBJS += $(EMU_OBJS)
else
EMU_LIB =
EMU_CFLAGS =
EMU_LDFLAGS =
endif

3
dep/emu/build.py Normal file
View File

@@ -0,0 +1,3 @@
from build.c import clibrary
clibrary(name="emu", srcs=["./fnmatch.c"], hdrs={"fnmatch.h": "./fnmatch.h"})

View File

@@ -1,13 +0,0 @@
FATFS_SRCS = \
dep/fatfs/source/ff.c \
dep/fatfs/source/ffsystem.c \
dep/fatfs/source/ffunicode.c \
FATFS_OBJS = $(patsubst %.c, $(OBJDIR)/%.o, $(FATFS_SRCS))
$(FATFS_OBJS): CFLAGS += -Idep/fatfs/source
FATFS_LIB = $(OBJDIR)/libfatfs.a
$(FATFS_LIB): $(FATFS_OBJS)
FATFS_CFLAGS = -Idep/fatfs/source
FATFS_LDFLAGS =
OBJS += $(FATFS_OBJS)

18
dep/fatfs/build.py Normal file
View File

@@ -0,0 +1,18 @@
from build.c import clibrary
clibrary(
name="fatfs",
srcs=[
"./source/ff.c",
"./source/ffsystem.c",
"./source/ffunicode.c",
"./source/ff.h",
"./source/ffconf.h",
"./source/diskio.h",
],
hdrs={
"ff.h": "./source/ff.h",
"ffconf.h": "./source/ffconf.h",
"diskio.h": "./source/diskio.h",
},
)

View File

@@ -1,22 +0,0 @@
HFSUTILS_SRCS = \
dep/hfsutils/libhfs/block.c \
dep/hfsutils/libhfs/btree.c \
dep/hfsutils/libhfs/data.c \
dep/hfsutils/libhfs/file.c \
dep/hfsutils/libhfs/hfs.c \
dep/hfsutils/libhfs/low.c \
dep/hfsutils/libhfs/medium.c \
dep/hfsutils/libhfs/memcmp.c \
dep/hfsutils/libhfs/node.c \
dep/hfsutils/libhfs/record.c \
dep/hfsutils/libhfs/version.c \
dep/hfsutils/libhfs/volume.c \
HFSUTILS_OBJS = $(patsubst %.c, $(OBJDIR)/%.o, $(HFSUTILS_SRCS))
$(HFSUTILS_OBJS): CFLAGS += -Idep/hfsutils/libhfs
HFSUTILS_LIB = $(OBJDIR)/libhfsutils.a
$(HFSUTILS_LIB): $(HFSUTILS_OBJS)
HFSUTILS_CFLAGS = -Idep/hfsutils/libhfs
HFSUTILS_LDFLAGS =
OBJS += $(HFSUTILS_OBJS)

25
dep/hfsutils/build.py Normal file
View File

@@ -0,0 +1,25 @@
from build.c import clibrary
clibrary(
name="hfsutils",
srcs=[
"./libhfs/block.c",
"./libhfs/btree.c",
"./libhfs/data.c",
"./libhfs/file.c",
"./libhfs/hfs.c",
"./libhfs/low.c",
"./libhfs/medium.c",
"./libhfs/memcmp.c",
"./libhfs/node.c",
"./libhfs/record.c",
"./libhfs/version.c",
"./libhfs/volume.c",
],
hdrs={
"apple.h": "./libhfs/apple.h",
"hfs.h": "./libhfs/hfs.h",
"libhfs.h": "./libhfs/libhfs.h",
"os.h": "./libhfs/os.h",
},
)

View File

@@ -1,61 +0,0 @@
LIBUSBP_SRCS = \
dep/libusbp/src/async_in_pipe.c \
dep/libusbp/src/error.c \
dep/libusbp/src/error_hresult.c \
dep/libusbp/src/find_device.c \
dep/libusbp/src/list.c \
dep/libusbp/src/pipe_id.c \
dep/libusbp/src/string.c \
ifeq ($(OS), Windows_NT)
LIBUSBP_LDFLAGS += -lsetupapi -lwinusb -lole32 -luuid
LIBUSBP_SRCS += \
dep/libusbp/src/windows/async_in_transfer_windows.c \
dep/libusbp/src/windows/device_instance_id_windows.c \
dep/libusbp/src/windows/device_windows.c \
dep/libusbp/src/windows/error_windows.c \
dep/libusbp/src/windows/generic_handle_windows.c \
dep/libusbp/src/windows/generic_interface_windows.c \
dep/libusbp/src/windows/interface_windows.c \
dep/libusbp/src/windows/list_windows.c \
dep/libusbp/src/windows/serial_port_windows.c \
else ifeq ($(shell uname),Darwin)
LIBUSBP_SRCS += \
dep/libusbp/src/mac/async_in_transfer_mac.c \
dep/libusbp/src/mac/device_mac.c \
dep/libusbp/src/mac/error_mac.c \
dep/libusbp/src/mac/generic_handle_mac.c \
dep/libusbp/src/mac/generic_interface_mac.c \
dep/libusbp/src/mac/iokit_mac.c \
dep/libusbp/src/mac/list_mac.c \
dep/libusbp/src/mac/serial_port_mac.c \
else
LIBUSBP_CFLAGS += $(shell pkg-config --cflags libudev)
LIBUSBP_LDFLAGS += $(shell pkg-config --libs libudev)
LIBUSBP_SRCS += \
dep/libusbp/src/linux/async_in_transfer_linux.c \
dep/libusbp/src/linux/device_linux.c \
dep/libusbp/src/linux/error_linux.c \
dep/libusbp/src/linux/generic_handle_linux.c \
dep/libusbp/src/linux/generic_interface_linux.c \
dep/libusbp/src/linux/list_linux.c \
dep/libusbp/src/linux/serial_port_linux.c \
dep/libusbp/src/linux/udev_linux.c \
dep/libusbp/src/linux/usbfd_linux.c \
endif
LIBUSBP_OBJS = $(patsubst %.c, $(OBJDIR)/%.o, $(LIBUSBP_SRCS))
$(LIBUSBP_OBJS): private CFLAGS += -Idep/libusbp/src -Idep/libusbp/include
LIBUSBP_LIB = $(OBJDIR)/libusbp.a
LIBUSBP_CFLAGS += -Idep/libusbp/include
LIBUSBP_LDFLAGS +=
$(LIBUSBP_LIB): $(LIBUSBP_OBJS)
OBJS += $(LIBUSBP_OBJS)

72
dep/libusbp/build.py Normal file
View File

@@ -0,0 +1,72 @@
from build.ab import emit
from build.c import clibrary
from build.pkg import package
from config import windows, osx, unix
srcs = [
"./src/async_in_pipe.c",
"./src/error.c",
"./src/error_hresult.c",
"./src/find_device.c",
"./src/list.c",
"./src/pipe_id.c",
"./src/string.c",
"./src/libusbp_internal.h",
"./include/libusbp_config.h",
"./include/libusbp.h",
]
deps = []
ldflags = []
if windows:
srcs += [
"./src/windows/async_in_transfer_windows.c",
"./src/windows/device_instance_id_windows.c",
"./src/windows/device_windows.c",
"./src/windows/error_windows.c",
"./src/windows/generic_handle_windows.c",
"./src/windows/generic_interface_windows.c",
"./src/windows/interface_windows.c",
"./src/windows/list_windows.c",
"./src/windows/serial_port_windows.c",
]
ldflags += ["-lsetupapi", "-lwinusb", "-lole32", "-luuid"]
elif osx:
srcs += [
"./src/mac/async_in_transfer_mac.c",
"./src/mac/device_mac.c",
"./src/mac/error_mac.c",
"./src/mac/generic_handle_mac.c",
"./src/mac/generic_interface_mac.c",
"./src/mac/iokit_mac.c",
"./src/mac/list_mac.c",
"./src/mac/serial_port_mac.c",
]
else:
package(name="udev_lib", package="libudev")
srcs += [
"./src/linux/async_in_transfer_linux.c",
"./src/linux/device_linux.c",
"./src/linux/error_linux.c",
"./src/linux/generic_handle_linux.c",
"./src/linux/generic_interface_linux.c",
"./src/linux/list_linux.c",
"./src/linux/serial_port_linux.c",
"./src/linux/udev_linux.c",
"./src/linux/usbfd_linux.c",
]
deps += [".+udev_lib"]
clibrary(
name="libusbp",
srcs=srcs,
cflags=["-Idep/libusbp/include", "-Idep/libusbp/src"],
ldflags=ldflags,
deps=deps,
hdrs={
"libusbp_internal.h": "./src/libusbp_internal.h",
"libusbp_config.h": "./include/libusbp_config.h",
"libusbp.hpp": "./include/libusbp.hpp",
"libusbp.h": "./include/libusbp.h",
},
)

103
dep/libusbp/src/dummy.c Normal file
View File

@@ -0,0 +1,103 @@
// This file contains failing place-holders to make things compile
// on otherwise unsupported platforms.
#include <libusbp_internal.h>
struct libusbp_device
{
char* syspath;
char* serial_number; // may be NULL
uint16_t product_id;
uint16_t vendor_id;
uint16_t revision;
};
static libusbp_error* fail()
{
return error_create("USB hardware is not supported on this platform");
}
libusbp_error* libusbp_device_copy(
const libusbp_device* source, libusbp_device** dest)
{
return fail();
}
libusbp_error* libusbp_generic_interface_create(const libusbp_device* device,
uint8_t interface_number,
bool composite __attribute__((unused)),
libusbp_generic_interface** gi)
{
return fail();
}
libusbp_error* libusbp_generic_handle_open(
const libusbp_generic_interface* gi, libusbp_generic_handle** handle)
{
return fail();
}
void libusbp_device_free(libusbp_device* device) {}
void libusbp_generic_handle_close(libusbp_generic_handle* handle) {}
void libusbp_generic_interface_free(libusbp_generic_interface* gi) {}
libusbp_error* libusbp_device_get_vendor_id(
const libusbp_device* device, uint16_t* vendor_id)
{
return fail();
}
libusbp_error* libusbp_device_get_product_id(
const libusbp_device* device, uint16_t* product_id)
{
return fail();
}
libusbp_error* libusbp_device_get_serial_number(
const libusbp_device* device, char** serial_number)
{
return fail();
}
libusbp_error* libusbp_write_pipe(libusbp_generic_handle* handle,
uint8_t pipe_id,
const void* data,
size_t size,
size_t* transferred)
{
return fail();
}
libusbp_error* libusbp_read_pipe(libusbp_generic_handle* handle,
uint8_t pipe_id,
void* data,
size_t size,
size_t* transferred)
{
return fail();
}
libusbp_error* libusbp_serial_port_create(const libusbp_device* device,
uint8_t interface_number,
bool composite,
libusbp_serial_port** port)
{
return fail();
}
libusbp_error* libusbp_serial_port_get_name(
const libusbp_serial_port* port, char** name)
{
return fail();
}
void libusbp_serial_port_free(libusbp_serial_port* port) {}
libusbp_error* libusbp_list_connected_devices(
libusbp_device*** device_list, size_t* device_count)
{
return fail();
}

49
dep/snowhouse/build.py Normal file
View File

@@ -0,0 +1,49 @@
from build.c import cxxlibrary
cxxlibrary(
name="snowhouse",
hdrs={
"snowhouse/snowhouse.h": "./include/snowhouse/snowhouse.h",
"snowhouse/assert.h": "./include/snowhouse/assert.h",
"snowhouse/fluent/fluent.h": "./include/snowhouse/fluent/fluent.h",
"snowhouse/fluent/constraintadapter.h": "./include/snowhouse/fluent/constraintadapter.h",
"snowhouse/fluent/constraintlist.h": "./include/snowhouse/fluent/constraintlist.h",
"snowhouse/fluent/operators/andoperator.h": "./include/snowhouse/fluent/operators/andoperator.h",
"snowhouse/fluent/operators/invalidexpressionexception.h": "./include/snowhouse/fluent/operators/invalidexpressionexception.h",
"snowhouse/fluent/operators/collections/collectionoperator.h": "./include/snowhouse/fluent/operators/collections/collectionoperator.h",
"snowhouse/fluent/operators/collections/collectionconstraintevaluator.h": "./include/snowhouse/fluent/operators/collections/collectionconstraintevaluator.h",
"snowhouse/fluent/operators/collections/atleastoperator.h": "./include/snowhouse/fluent/operators/collections/atleastoperator.h",
"snowhouse/fluent/operators/collections/noneoperator.h": "./include/snowhouse/fluent/operators/collections/noneoperator.h",
"snowhouse/fluent/operators/collections/atmostoperator.h": "./include/snowhouse/fluent/operators/collections/atmostoperator.h",
"snowhouse/fluent/operators/collections/alloperator.h": "./include/snowhouse/fluent/operators/collections/alloperator.h",
"snowhouse/fluent/operators/collections/exactlyoperator.h": "./include/snowhouse/fluent/operators/collections/exactlyoperator.h",
"snowhouse/fluent/operators/notoperator.h": "./include/snowhouse/fluent/operators/notoperator.h",
"snowhouse/fluent/operators/constraintoperator.h": "./include/snowhouse/fluent/operators/constraintoperator.h",
"snowhouse/fluent/operators/oroperator.h": "./include/snowhouse/fluent/operators/oroperator.h",
"snowhouse/fluent/expressionbuilder.h": "./include/snowhouse/fluent/expressionbuilder.h",
"snowhouse/assertionexception.h": "./include/snowhouse/assertionexception.h",
"snowhouse/exceptions.h": "./include/snowhouse/exceptions.h",
"snowhouse/stringizers.h": "./include/snowhouse/stringizers.h",
"snowhouse/macros.h": "./include/snowhouse/macros.h",
"snowhouse/constraints/equalscontainerconstraint.h": "./include/snowhouse/constraints/equalscontainerconstraint.h",
"snowhouse/constraints/islessthanorequaltoconstraint.h": "./include/snowhouse/constraints/islessthanorequaltoconstraint.h",
"snowhouse/constraints/equalsconstraint.h": "./include/snowhouse/constraints/equalsconstraint.h",
"snowhouse/constraints/isgreaterthanconstraint.h": "./include/snowhouse/constraints/isgreaterthanconstraint.h",
"snowhouse/constraints/fulfillsconstraint.h": "./include/snowhouse/constraints/fulfillsconstraint.h",
"snowhouse/constraints/endswithconstraint.h": "./include/snowhouse/constraints/endswithconstraint.h",
"snowhouse/constraints/constraints.h": "./include/snowhouse/constraints/constraints.h",
"snowhouse/constraints/haslengthconstraint.h": "./include/snowhouse/constraints/haslengthconstraint.h",
"snowhouse/constraints/startswithconstraint.h": "./include/snowhouse/constraints/startswithconstraint.h",
"snowhouse/constraints/equalswithdeltaconstraint.h": "./include/snowhouse/constraints/equalswithdeltaconstraint.h",
"snowhouse/constraints/isgreaterthanorequaltoconstraint.h": "./include/snowhouse/constraints/isgreaterthanorequaltoconstraint.h",
"snowhouse/constraints/containsconstraint.h": "./include/snowhouse/constraints/containsconstraint.h",
"snowhouse/constraints/islessthanconstraint.h": "./include/snowhouse/constraints/islessthanconstraint.h",
"snowhouse/constraints/isemptyconstraint.h": "./include/snowhouse/constraints/isemptyconstraint.h",
"snowhouse/constraints/expressions/andexpression.h": "./include/snowhouse/constraints/expressions/andexpression.h",
"snowhouse/constraints/expressions/orexpression.h": "./include/snowhouse/constraints/expressions/orexpression.h",
"snowhouse/constraints/expressions/expression_fwd.h": "./include/snowhouse/constraints/expressions/expression_fwd.h",
"snowhouse/constraints/expressions/notexpression.h": "./include/snowhouse/constraints/expressions/notexpression.h",
"snowhouse/constraints/expressions/expression.h": "./include/snowhouse/constraints/expressions/expression.h",
"snowhouse/stringize.h": "./include/snowhouse/stringize.h",
},
)

View File

@@ -1,23 +0,0 @@
ifeq ($(shell $(PKG_CONFIG) stb; echo $$?), 0)
# System libstb present.
STB_LIB =
STB_CFLAGS := $(shell $(PKG_CONFIG) --cflags stb)
STB_LDFLAGS := $(shell $(PKG_CONFIG) --libs stb)
else
STB_SRCS = \
dep/stb/stb_image_write.c
STB_OBJS = $(patsubst %.c, $(OBJDIR)/%.o, $(STB_SRCS))
$(STB_OBJS): CFLAGS += -Idep/stb/src
STB_LIB = $(OBJDIR)/libstb.a
$(STB_LIB): $(STB_OBJS)
STB_CFLAGS =
STB_LDFLAGS = $(STB_LIB)
OBJS += $(STB_OBJS)
endif

7
dep/stb/build.py Normal file
View File

@@ -0,0 +1,7 @@
from build.c import clibrary
clibrary(
name="stb",
srcs=["./stb_image_write.c"],
hdrs={"stb_image_write.h": "./stb_image_write.h"},
)

View File

@@ -204,7 +204,7 @@ install some support packages.
- For Linux with Ubuntu/Debian:
`libusb-1.0-0-dev`, `libsqlite3-dev`, `zlib1g-dev`,
`libudev-dev`, `protobuf-compiler`, `libwxgtk3.0-gtk3-dev`,
`libfmt-dev`.
`libfmt-dev`, `python3`.
- For Linux with Fedora/Red Hat:
`git`, `make`, `gcc`, `gcc-c++`, `xxd`, `protobuf-compiler`,
`protobuf-devel`, `fmt-devel`, `systemd-devel`, `wxGTK3-devel`,
@@ -214,7 +214,7 @@ install some support packages.
- For Windows with MSYS2: `make`, `mingw-w64-i686-libusb`,
`mingw-w64-i686-protobuf`, `mingw-w64-i686-sqlite3`, `mingw-w64-i686-zlib`,
`mingw-w64-i686-gcc`, `vim`, `diffutils`, `mingw-w64-i686-wxWidgets`,
`mingw-w64-i686-fmt`, `mingw-w64-i686-pkg-config`.
`mingw-w64-i686-fmt`, `mingw-w64-i686-pkg-config`, `mingw-w64-i686-python`.
These lists are not necessarily exhaustive --- please [get in
touch](https://github.com/davidgiven/fluxengine/issues/new) if I've missed
@@ -222,10 +222,16 @@ anything.
Windows and Linux (and other Unixes) build by just doing `make`. OSX builds by
doing `gmake` (we're using a feature which the elderly default make in OSX
doesn't have). You should end up with some executables in the current
directory, one of which is called `fluxengine` or `fluxengine.exe` depending on
your platform. It has minimal dependencies and you should be able to put it
anywhere. The other binaries may also be of interest.
doesn't have). Remember to add an appropriate `-j` option for a parallel build.
You should end up with some executables in the current directory, one of which
is called `fluxengine` or `fluxengine.exe` depending on your platform. It has
minimal dependencies and you should be able to put it anywhere. The other
binaries may also be of interest.
Potential issues:
- Complaints about a missing `libudev` on Windows? Make sure you're using the
mingw Python rather than the msys Python.
If it doesn't build, please [get in
touch](https://github.com/davidgiven/fluxengine/issues/new).

View File

@@ -22,13 +22,25 @@ pinout as a 96tpi PC 5.25" drive. In use they should be identical.
While most operating systems use the standard Micropolis checksum, Vector
Graphic MZOS uses a unique checksum. The decoder will automatically detect
the checksum type in use; however, a specific checksum type may be forced
using the `--decoder.micropolis.checksum_type=n` where the type is one of:
using the `--decoder.micropolis.checksum_type=TYPE` where TYPE is one of:
| Type | Description |
|------|-----------------------------------------|
| 0 | Automatically detect |
| 1 | Standard Micropolis (MDOS, CP/M, OASIS) |
| 2 | Vector Graphic MZOS |
| Checksum | Description |
|------------|-----------------------------------------|
| AUTO | Automatically detect |
| MICROPOLIS | Standard Micropolis (MDOS, CP/M, OASIS) |
| MZOS | Vector Graphic MZOS |
Later versions of the Micropolis format supported ECC, especially in
controllers with HDD support. The ECC can detect and correct errors. However,
it is unclear what ECC algorithm was used by each vendor. ECC is disabled by
default, but available for checking and correcting using
`--decoder.micropolis.ecc_type=TYPE` and for writing from IMG files using
`--encoder.micropolis.ecc_type=TYPE`, where TYPE is one of:
| ECC | Description |
|--------|------------------------------------------|
| NONE | No ECC processing enabled |
| VECTOR | Vector Graphic Dual-Mode Disk Controller |
The [CP/M BIOS](https://www.seasip.info/Cpm/bios.html) defined SELDSK, SETTRK,
and SETSEC, but no function to select the head/side. Double-sided floppies

33
doc/disk-ms2000.md Normal file
View File

@@ -0,0 +1,33 @@
ms2000
====
## MS2000 Microdisk Development System
<!-- This file is automatically generated. Do not edit. -->
The RCA MicroDisk Development System MS2000 is a highly obscure (i.e. I gather
that single digit numbers of original machines exist) development system for the
RCA1802 series of CPUs, as made famous by the Cosmac ELF. It was a fairly
straightforward big bag o'RAM system with a 2kB boot ROM, 62kB of RAM, twin
floppy drives and a serial terminal --- CP/M users will find it very familiar.
Read and writing disks is currently not supported by FluxEngine, but there is
basic support for the MicroDisk operating system's file system. This should
allow files to be read from MS2000 disk images.
The disks are normal DD 3.5" disks, using a 70-track, single sided variation of
the venerable IBM floppy disk scheme, so allowing 315kB of storage per disk.
If you have access to flux files for MS2000 disks, please [get in
touch](https://github.com/davidgiven/cpm65/issues/new) --- I would like to add
better support for these.
## Options
(no options)
## Examples
## References
- [The EMMA-02 emulator](https://www.emma02.hobby-site.com/ms2000.html), which
supports the MS2000 and provides information on it.

View File

@@ -9,13 +9,29 @@ drive, used for saving MIDI sequences and samples.
Weirdly, it seems to use precisely the same format as the Brother word
processors: a thoroughly non-IBM-compatible custom GCR system.
FluxEngine pretends to support this, but it has had almost no testing, the only
disk image I have seen for it was mostly corrupt, and very little is known
about the format, so I have no idea whether it's correct or not.
FluxEngine supports both reading and writing D20 disks, as well as basic support
for the filesystem, allowing files to be read from and written to D20 disks.
Note that the D20 was never intended to support arbitrary files on its disks and
is very likely to crash if you put unexpected files on a disk. In addition,
while the file format itself is currently unknown, there is a header at the top
of the file containing what appears to be the name shown in the D20 file
browser, so the name by which you see it is not necessarily the filename.
A word of warning --- just like the Brother word processors, the D20 floppy
drive isn't very well aligned. The drive itself uses quarter-stepping to
automatically adapt to whatever alignment the disk was formatted with. This
means that trying to read such a disk on a PC drive, which does _not_ have
adjustable alignment, may not work very well. In these situations it is possible
to adjust the alignment of most modern drives, but this is a somewhat risky
process and may result in permanently wrecking the drive alignment.
Please [get in touch](https://github.com/davidgiven/fluxengine/issues/new) if
you know anything about it.
Many thanks to trondl [on the VCF
forums](https://forum.vcfed.org/index.php?threads/roland-d-20-decoding-the-mysterious-floppy-format.1243226/)
for assistance with this!
## Options
(no options)
@@ -26,3 +42,7 @@ To read:
- `fluxengine read rolandd20 -s drive:0 -o rolandd20.img`
To write:
- `fluxengine write rolandd20 -d drive:0 -i rolandd20.img`

View File

@@ -20,11 +20,8 @@ bytes per sector --- 128 bytes of user payload plus two two-byte metadata
words used to construct linked lists of sectors for storing files. These
stored 320kB each.
FluxEngine has experimental read support for these disks, based on a single
Catweasel flux file I've been able to obtain, which only contained 70 tracks.
I haven't been able to try this for real. If anyone has any of these disks,
an 8-inch drive, a FluxEngine and the appropriate adapter, please [get in
touch](https://github.com/davidgiven/fluxengine/issues/new)...
FluxEngine has read support for these, including support for RIO's ZDOS file
system.
## Options

View File

@@ -26,6 +26,7 @@ The following file systems are supported so far.
| Macintosh HFS | Y | Y | Only AppleDouble files may be written |
| pSOS' PHILE | Y | | Probably unreliable due to lack of documentation |
| Smaky 6 | Y | | |
| Zilog MCZ RIO's ZDOS | Y | | |
{: .datatable }
Please not that Atari disks do _not_ use standard FatFS, and the library I'm

View File

@@ -221,6 +221,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.**

44
extras/build.py Normal file
View File

@@ -0,0 +1,44 @@
from build.ab import normalrule, simplerule
from build.utils import objectify
from build.c import clibrary
icons = ["fluxfile", "hardware", "icon", "imagefile"]
clibrary(
name="icons",
hdrs={
f"icons/{n}.h": objectify(
name=n + "_h", src=f"./{n}.png", symbol=f"icon_{n}_png"
)
for n in icons
},
)
normalrule(
name="fluxengine_iconset",
ins=["./icon.png"],
outs=["fluxengine.iconset"],
commands=[
"mkdir -p {outs[0]}",
"sips -z 64 64 {ins[0]} --out {outs[0]}/icon_32x32@2x.png > /dev/null",
],
label="ICONSET",
)
normalrule(
name="fluxengine_icns",
ins=[".+fluxengine_iconset"],
outs=["fluxengine.icns"],
commands=["iconutil -c icns -o {outs[0]} {ins[0]}"],
label="ICONUTIL",
)
normalrule(
name="fluxengine_ico",
ins=["./icon.png"],
outs=["fluxengine.ico"],
commands=[
"convert {ins[0]} -resize 64x46 -define icon:auto-resize=64,48,32,16 {outs[0]}"
],
label="MAKEICON",
)

View File

@@ -25,7 +25,7 @@ SetCompressor /solid lzma
GreaseWeazle hardware. It also allows manipulation of flux files and disk \
images, so it's useful without any hardware.$\r$\n\
$\r$\n\
This wizard will install WordGrinder on your computer.$\r$\n\
This wizard will install FluxEngine on your computer.$\r$\n\
$\r$\n\
$_CLICK"
@@ -130,7 +130,7 @@ SectionEnd
Section "Desktop Shortcut"
SetOutPath "$DOCUMENTS"
CreateShortCut "$DESKTOP\WordGrinder.lnk" "$INSTDIR\fluxengine-gui.exe" "" "$INSTDIR\fluxengine-gui.exe" 0
CreateShortCut "$DESKTOP\FluxEngine.lnk" "$INSTDIR\fluxengine-gui.exe" "" "$INSTDIR\fluxengine-gui.exe" 0
SectionEnd
;--------------------------------

View File

@@ -1,9 +1,9 @@
#include "globals.h"
#include "flags.h"
#include "dep/agg/include/agg2d.h"
#include "dep/stb/stb_image_write.h"
#include "utils.h"
#include "bitmap.h"
#include "lib/globals.h"
#include "lib/flags.h"
#include "agg2d.h"
#include "stb_image_write.h"
#include "lib/utils.h"
#include "lib/bitmap.h"
#include <regex>
#include <sstream>

View File

@@ -1,105 +0,0 @@
LIBFLUXENGINE_SRCS = \
lib/bitmap.cc \
lib/bytes.cc \
lib/config.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/fl2.cc \
lib/flags.cc \
lib/fluxmap.cc \
lib/fluxsink/a2rfluxsink.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/a2rfluxsource.cc \
lib/fluxsource/cwffluxsource.cc \
lib/fluxsource/erasefluxsource.cc \
lib/fluxsource/fl2fluxsource.cc \
lib/fluxsource/fluxsource.cc \
lib/fluxsource/flx.cc \
lib/fluxsource/flxfluxsource.cc \
lib/fluxsource/hardwarefluxsource.cc \
lib/fluxsource/kryoflux.cc \
lib/fluxsource/kryofluxfluxsource.cc \
lib/fluxsource/memoryfluxsource.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/imdimagewriter.cc \
lib/imagewriter/imgimagewriter.cc \
lib/imagewriter/ldbsimagewriter.cc \
lib/imagewriter/nsiimagewriter.cc \
lib/imagewriter/rawimagewriter.cc \
lib/layout.cc \
lib/ldbs.cc \
lib/logger.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 \
lib/vfs/acorndfs.cc \
lib/vfs/amigaffs.cc \
lib/vfs/appledos.cc \
lib/vfs/applesingle.cc \
lib/vfs/brother120fs.cc \
lib/vfs/cbmfs.cc \
lib/vfs/cpmfs.cc \
lib/vfs/fatfs.cc \
lib/vfs/lif.cc \
lib/vfs/machfs.cc \
lib/vfs/prodos.cc \
lib/vfs/smaky6fs.cc \
lib/vfs/philefs.cc \
lib/vfs/vfs.cc \
lib/vfs/fluxsectorinterface.cc \
lib/vfs/imagesectorinterface.cc \
LIBFLUXENGINE_OBJS = $(patsubst %.cc, $(OBJDIR)/%.o, $(LIBFLUXENGINE_SRCS))
OBJS += $(LIBFLUXENGINE_OBJS)
$(LIBFLUXENGINE_SRCS): | $(PROTO_HDRS)
LIBFLUXENGINE_LIB = $(OBJDIR)/libfluxengine.a
LIBFLUXENGINE_CFLAGS =
LIBFLUXENGINE_LDFLAGS =
$(LIBFLUXENGINE_LIB): $(LIBFLUXENGINE_OBJS)
$(LIBFLUXENGINE_OBJS): CFLAGS += $(LIBARCH_CFLAGS)
$(LIBFLUXENGINE_OBJS): CFLAGS += $(LIBUSBP_CFLAGS)
$(LIBFLUXENGINE_OBJS): CFLAGS += $(PROTO_CFLAGS)
$(LIBFLUXENGINE_OBJS): CFLAGS += $(FATFS_CFLAGS)
$(LIBFLUXENGINE_OBJS): CFLAGS += $(ADFLIB_CFLAGS)
$(LIBFLUXENGINE_OBJS): CFLAGS += $(HFSUTILS_CFLAGS)
$(call use-pkgconfig, $(LIBFLUXENGINE_LIB), $(LIBFLUXENGINE_OBJS), fmt)

25
lib/build.py Normal file
View File

@@ -0,0 +1,25 @@
from build.c import cxxlibrary
from build.protobuf import proto, protocc
proto(name="common_proto", srcs=["./common.proto"])
proto(
name="config_proto",
srcs=[
"./config.proto",
"./layout.proto",
"./drive.proto",
"./decoders/decoders.proto",
"./encoders/encoders.proto",
"./fluxsink/fluxsink.proto",
"./fluxsource/fluxsource.proto",
"./imagereader/imagereader.proto",
"./imagewriter/imagewriter.proto",
"./usb/usb.proto",
"./vfs/vfs.proto",
],
deps=[".+common_proto", "+fl2_proto"],
)
protocc(name="config_proto_lib", srcs=[".+config_proto", "arch+arch_proto"])

View File

@@ -1,5 +1,5 @@
#include "globals.h"
#include "bytes.h"
#include "lib/globals.h"
#include "lib/bytes.h"
#include <fstream>
#include <zlib.h>
@@ -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,32 @@ 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;
}
ByteWriter& ByteWriter::pad(unsigned count, uint8_t b)
{
while (count--)
this->write_8(b);
return *this;
}

View File

@@ -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,9 @@ 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);
private:
Bytes& _bytes;

View File

@@ -19,4 +19,37 @@ enum IndexMode {
INDEXMODE_360 = 2;
}
enum FluxSourceSinkType {
FLUXTYPE_NOT_SET = 0;
FLUXTYPE_A2R = 1;
FLUXTYPE_AU = 2;
FLUXTYPE_CWF = 3;
FLUXTYPE_DRIVE = 4;
FLUXTYPE_ERASE = 5;
FLUXTYPE_FLUX = 6;
FLUXTYPE_FLX = 7;
FLUXTYPE_KRYOFLUX = 8;
FLUXTYPE_SCP = 9;
FLUXTYPE_TEST_PATTERN = 10;
FLUXTYPE_VCD = 11;
FLUXTYPE_DMK = 12;
}
enum ImageReaderWriterType {
IMAGETYPE_NOT_SET = 0;
IMAGETYPE_D64 = 1;
IMAGETYPE_D88 = 2;
IMAGETYPE_DIM = 3;
IMAGETYPE_DISKCOPY = 4;
IMAGETYPE_FDI = 5;
IMAGETYPE_IMD = 6;
IMAGETYPE_IMG = 7;
IMAGETYPE_JV3 = 8;
IMAGETYPE_LDBS = 9;
IMAGETYPE_NFD = 10;
IMAGETYPE_NSI = 11;
IMAGETYPE_RAW = 12;
IMAGETYPE_TD0 = 13;
}

View File

@@ -11,10 +11,161 @@
#include "lib/decoders/decoders.h"
#include <fstream>
#include <google/protobuf/text_format.h>
#include <regex>
static Config config;
enum ConstructorMode
{
MODE_RO,
MODE_WO,
MODE_RW
};
struct ImageConstructor
{
std::string extension;
ImageReaderWriterType type;
ConstructorMode mode;
};
static const std::vector<FluxConstructor> fluxConstructors = {
{/* The .flux format must be first. */
.name = "FluxEngine (.flux)",
.pattern = std::regex("^(.*\\.flux)$"),
.source =
[](auto& s, auto* proto)
{
proto->set_type(FLUXTYPE_FLUX);
proto->mutable_fl2()->set_filename(s);
}, .sink =
[](auto& s, auto* proto)
{
proto->set_type(FLUXTYPE_FLUX);
proto->mutable_fl2()->set_filename(s);
}},
{
.name = "Supercard Pro (.scp)",
.pattern = std::regex("^(.*\\.scp)$"),
.source =
[](auto& s, auto* proto)
{
proto->set_type(FLUXTYPE_SCP);
proto->mutable_scp()->set_filename(s);
}, .sink =
[](auto& s, auto* proto)
{
proto->set_type(FLUXTYPE_SCP);
proto->mutable_scp()->set_filename(s);
}, },
{.name = "AppleSauce (.a2r)",
.pattern = std::regex("^(.*\\.a2r)$"),
.source =
[](auto& s, auto* proto)
{
proto->set_type(FLUXTYPE_A2R);
proto->mutable_a2r()->set_filename(s);
}, .sink =
[](auto& s, auto* proto)
{
proto->set_type(FLUXTYPE_A2R);
proto->mutable_a2r()->set_filename(s);
}},
{.name = "CatWeazle (.cwf)",
.pattern = std::regex("^(.*\\.cwf)$"),
.source =
[](auto& s, auto* proto)
{
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)
{
proto->set_type(FLUXTYPE_ERASE);
}},
{.name = "KryoFlux directory",
.pattern = std::regex("^kryoflux:(.*)$"),
.source =
[](auto& s, auto* proto)
{
proto->set_type(FLUXTYPE_KRYOFLUX);
proto->mutable_kryoflux()->set_directory(s);
}},
{.pattern = std::regex("^testpattern:(.*)"),
.source =
[](auto& s, auto* proto)
{
proto->set_type(FLUXTYPE_TEST_PATTERN);
}},
{.pattern = std::regex("^drive:(.*)"),
.source =
[](auto& s, auto* proto)
{
proto->set_type(FLUXTYPE_DRIVE);
globalConfig().overrides()->mutable_drive()->set_drive(
std::stoi(s));
}, .sink =
[](auto& s, auto* proto)
{
proto->set_type(FLUXTYPE_DRIVE);
globalConfig().overrides()->mutable_drive()->set_drive(
std::stoi(s));
}},
{.name = "FluxCopy directory",
.pattern = std::regex("^flx:(.*)$"),
.source =
[](auto& s, auto* proto)
{
proto->set_type(FLUXTYPE_FLX);
proto->mutable_flx()->set_directory(s);
}},
{.name = "Value Change Dump directory",
.pattern = std::regex("^vcd:(.*)$"),
.sink =
[](auto& s, auto* proto)
{
proto->set_type(FLUXTYPE_VCD);
proto->mutable_vcd()->set_directory(s);
}},
{.name = "Audio file directory",
.pattern = std::regex("^au:(.*)$"),
.sink =
[](auto& s, auto* proto)
{
proto->set_type(FLUXTYPE_AU);
proto->mutable_au()->set_directory(s);
}},
};
static const std::vector<ImageConstructor> imageConstructors = {
{".adf", IMAGETYPE_IMG, MODE_RW},
{".d64", IMAGETYPE_D64, MODE_RW},
{".d81", IMAGETYPE_IMG, MODE_RW},
{".d88", IMAGETYPE_D88, MODE_RW},
{".dim", IMAGETYPE_DIM, MODE_RO},
{".diskcopy", IMAGETYPE_DISKCOPY, MODE_RW},
{".dsk", IMAGETYPE_IMG, MODE_RW},
{".fdi", IMAGETYPE_FDI, MODE_RO},
{".imd", IMAGETYPE_IMD, MODE_RW},
{".img", IMAGETYPE_IMG, MODE_RW},
{".jv3", IMAGETYPE_JV3, MODE_RO},
{".nfd", IMAGETYPE_NFD, MODE_RO},
{".nsi", IMAGETYPE_NSI, MODE_RW},
{".st", IMAGETYPE_IMG, MODE_RW},
{".td0", IMAGETYPE_TD0, MODE_RO},
{".vgi", IMAGETYPE_IMG, MODE_RW},
{".xdf", IMAGETYPE_IMG, MODE_RW},
};
Config& globalConfig()
{
return config;
@@ -29,7 +180,6 @@ ConfigProto* Config::combined()
/* First apply any standalone options. */
std::set<std::string> options = _appliedOptions;
std::set<const OptionRequirementProto*> requirements;
for (const auto& option : _baseConfig.option())
{
if (options.find(option.name()) != options.end())
@@ -257,7 +407,7 @@ const OptionProto& Config::findOption(const std::string& optionName)
void Config::checkOptionValid(const OptionProto& option)
{
for (const auto& req : option.requires())
for (const auto& req : option.prerequisite())
{
bool matched = false;
try
@@ -334,72 +484,17 @@ void Config::clearOptions()
invalidate();
}
static void setFluxSourceImpl(std::string filename, FluxSourceProto* proto)
static void setFluxSourceImpl(
const std::string& filename, FluxSourceProto* proto)
{
static const std::vector<std::pair<std::regex,
std::function<void(const std::string&, FluxSourceProto*)>>>
formats = {
{std::regex("^(.*\\.flux)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceProto::FLUX);
proto->mutable_fl2()->set_filename(s);
}},
{std::regex("^(.*\\.scp)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceProto::SCP);
proto->mutable_scp()->set_filename(s);
}},
{std::regex("^(.*\\.a2r)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceProto::A2R);
proto->mutable_a2r()->set_filename(s);
}},
{std::regex("^(.*\\.cwf)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceProto::CWF);
proto->mutable_cwf()->set_filename(s);
}},
{std::regex("^erase:$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceProto::ERASE);
}},
{std::regex("^kryoflux:(.*)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceProto::KRYOFLUX);
proto->mutable_kryoflux()->set_directory(s);
}},
{std::regex("^testpattern:(.*)"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceProto::TEST_PATTERN);
}},
{std::regex("^drive:(.*)"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceProto::DRIVE);
globalConfig().overrides()->mutable_drive()->set_drive(
std::stoi(s));
}},
{std::regex("^flx:(.*)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSourceProto::FLX);
proto->mutable_flx()->set_directory(s);
}},
};
for (const auto& it : formats)
for (const auto& it : fluxConstructors)
{
std::smatch match;
if (std::regex_match(filename, match, it.first))
if (std::regex_match(filename, match, it.pattern))
{
it.second(match[1], proto);
if (!it.source)
throw new InapplicableValueException();
it.source(match[1], proto);
return;
}
}
@@ -412,56 +507,16 @@ void Config::setFluxSource(std::string filename)
setFluxSourceImpl(filename, overrides()->mutable_flux_source());
}
static void setFluxSinkImpl(std::string filename, FluxSinkProto* proto)
static void setFluxSinkImpl(const std::string& filename, FluxSinkProto* proto)
{
static const std::vector<std::pair<std::regex,
std::function<void(const std::string&, FluxSinkProto*)>>>
formats = {
{std::regex("^(.*\\.a2r)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSinkProto::A2R);
proto->mutable_a2r()->set_filename(s);
}},
{std::regex("^(.*\\.flux)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSinkProto::FLUX);
proto->mutable_fl2()->set_filename(s);
}},
{std::regex("^(.*\\.scp)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSinkProto::SCP);
proto->mutable_scp()->set_filename(s);
}},
{std::regex("^vcd:(.*)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSinkProto::VCD);
proto->mutable_vcd()->set_directory(s);
}},
{std::regex("^au:(.*)$"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSinkProto::AU);
proto->mutable_au()->set_directory(s);
}},
{std::regex("^drive:(.*)"),
[](auto& s, auto* proto)
{
proto->set_type(FluxSinkProto::DRIVE);
globalConfig().overrides()->mutable_drive()->set_drive(
std::stoi(s));
}},
};
for (const auto& it : formats)
for (const auto& it : fluxConstructors)
{
std::smatch match;
if (std::regex_match(filename, match, it.first))
if (std::regex_match(filename, match, it.pattern))
{
it.second(match[1], proto);
if (!it.sink)
throw new InapplicableValueException();
it.sink(match[1], proto);
return;
}
}
@@ -487,34 +542,14 @@ void Config::setVerificationFluxSource(std::string filename)
void Config::setImageReader(std::string filename)
{
static const std::map<std::string, std::function<void(ImageReaderProto*)>>
formats = {
// clang-format off
{".adf", [](auto* proto) { proto->set_type(ImageReaderProto::IMG); }},
{".d64", [](auto* proto) { proto->set_type(ImageReaderProto::D64); }},
{".d81", [](auto* proto) { proto->set_type(ImageReaderProto::IMG); }},
{".d88", [](auto* proto) { proto->set_type(ImageReaderProto::D88); }},
{".dim", [](auto* proto) { proto->set_type(ImageReaderProto::DIM); }},
{".diskcopy", [](auto* proto) { proto->set_type(ImageReaderProto::DISKCOPY); }},
{".dsk", [](auto* proto) { proto->set_type(ImageReaderProto::IMG); }},
{".fdi", [](auto* proto) { proto->set_type(ImageReaderProto::FDI); }},
{".imd", [](auto* proto) { proto->set_type(ImageReaderProto::IMD); }},
{".img", [](auto* proto) { proto->set_type(ImageReaderProto::IMG); }},
{".jv3", [](auto* proto) { proto->set_type(ImageReaderProto::JV3); }},
{".nfd", [](auto* proto) { proto->set_type(ImageReaderProto::NFD); }},
{".nsi", [](auto* proto) { proto->set_type(ImageReaderProto::NSI); }},
{".st", [](auto* proto) { proto->set_type(ImageReaderProto::IMG); }},
{".td0", [](auto* proto) { proto->set_type(ImageReaderProto::TD0); }},
{".vgi", [](auto* proto) { proto->set_type(ImageReaderProto::IMG); }},
{".xdf", [](auto* proto) { proto->set_type(ImageReaderProto::IMG); }},
// clang-format on
};
for (const auto& it : formats)
for (const auto& it : imageConstructors)
{
if (endsWith(filename, it.first))
if (endsWith(filename, it.extension))
{
it.second(overrides()->mutable_image_reader());
if (it.mode == MODE_WO)
throw new InapplicableValueException();
overrides()->mutable_image_reader()->set_type(it.type);
overrides()->mutable_image_reader()->set_filename(filename);
return;
}
@@ -525,31 +560,14 @@ void Config::setImageReader(std::string filename)
void Config::setImageWriter(std::string filename)
{
static const std::map<std::string, std::function<void(ImageWriterProto*)>>
formats = {
// clang-format off
{".adf", [](auto* proto) { proto->set_type(ImageWriterProto::IMG); }},
{".d64", [](auto* proto) { proto->set_type(ImageWriterProto::D64); }},
{".d81", [](auto* proto) { proto->set_type(ImageWriterProto::IMG); }},
{".d88", [](auto* proto) { proto->set_type(ImageWriterProto::D88); }},
{".diskcopy", [](auto* proto) { proto->set_type(ImageWriterProto::DISKCOPY); }},
{".dsk", [](auto* proto) { proto->set_type(ImageWriterProto::IMG); }},
{".img", [](auto* proto) { proto->set_type(ImageWriterProto::IMG); }},
{".imd", [](auto* proto) { proto->set_type(ImageWriterProto::IMD); }},
{".ldbs", [](auto* proto) { proto->set_type(ImageWriterProto::LDBS); }},
{".nsi", [](auto* proto) { proto->set_type(ImageWriterProto::NSI); }},
{".raw", [](auto* proto) { proto->set_type(ImageWriterProto::RAW); }},
{".st", [](auto* proto) { proto->set_type(ImageWriterProto::IMG); }},
{".vgi", [](auto* proto) { proto->set_type(ImageWriterProto::IMG); }},
{".xdf", [](auto* proto) { proto->set_type(ImageWriterProto::IMG); }},
// clang-format on
};
for (const auto& it : formats)
for (const auto& it : imageConstructors)
{
if (endsWith(filename, it.first))
if (endsWith(filename, it.extension))
{
it.second(overrides()->mutable_image_writer());
if (it.mode == MODE_RO)
throw new InapplicableValueException();
overrides()->mutable_image_writer()->set_type(it.type);
overrides()->mutable_image_writer()->set_filename(filename);
return;
}
@@ -560,7 +578,7 @@ void Config::setImageWriter(std::string filename)
bool Config::hasFluxSource()
{
return (*this)->flux_source().type() != FluxSourceProto::NOT_SET;
return (*this)->flux_source().type() != FLUXTYPE_NOT_SET;
}
std::shared_ptr<FluxSource>& Config::getFluxSource()
@@ -578,7 +596,7 @@ std::shared_ptr<FluxSource>& Config::getFluxSource()
bool Config::hasVerificationFluxSource() const
{
return _verificationFluxSourceProto.type() != FluxSourceProto::NOT_SET;
return _verificationFluxSourceProto.type() != FLUXTYPE_NOT_SET;
}
std::shared_ptr<FluxSource>& Config::getVerificationFluxSource()
@@ -596,7 +614,7 @@ std::shared_ptr<FluxSource>& Config::getVerificationFluxSource()
bool Config::hasImageReader()
{
return (*this)->image_reader().type() != ImageReaderProto::NOT_SET;
return (*this)->image_reader().type() != IMAGETYPE_NOT_SET;
}
std::shared_ptr<ImageReader>& Config::getImageReader()
@@ -614,7 +632,7 @@ std::shared_ptr<ImageReader>& Config::getImageReader()
bool Config::hasFluxSink()
{
return (*this)->flux_sink().type() != FluxSinkProto::NOT_SET;
return (*this)->flux_sink().type() != FLUXTYPE_NOT_SET;
}
std::unique_ptr<FluxSink> Config::getFluxSink()
@@ -627,7 +645,7 @@ std::unique_ptr<FluxSink> Config::getFluxSink()
bool Config::hasImageWriter()
{
return (*this)->image_writer().type() != ImageWriterProto::NOT_SET;
return (*this)->image_writer().type() != IMAGETYPE_NOT_SET;
}
std::unique_ptr<ImageWriter> Config::getImageWriter()
@@ -671,3 +689,8 @@ std::shared_ptr<Decoder>& Config::getDecoder()
}
return _decoder;
}
const std::vector<FluxConstructor>& Config::getFluxFormats()
{
return fluxConstructors;
}

View File

@@ -4,6 +4,7 @@
#include <google/protobuf/message.h>
#include "lib/config.pb.h"
#include "lib/common.pb.h"
class ConfigProto;
class OptionProto;
@@ -46,6 +47,23 @@ public:
}
};
class InapplicableValueException : public ErrorException
{
public:
InapplicableValueException():
ErrorException("selected format cannot be used here")
{
}
};
struct FluxConstructor
{
std::string name;
std::regex pattern;
std::function<void(const std::string& filename, FluxSourceProto*)> source;
std::function<void(const std::string& filename, FluxSinkProto*)> sink;
};
class Config
{
public:
@@ -146,6 +164,10 @@ public:
bool hasImageWriter();
std::unique_ptr<ImageWriter> getImageWriter();
public:
static const std::vector<FluxConstructor>& getFluxFormats();
static std::vector<std::string> getImageFormats();
private:
ConfigProto _baseConfig;
ConfigProto _overridesConfig;

View File

@@ -50,7 +50,7 @@ message ConfigProto
repeated OptionGroupProto option_group = 20;
}
message OptionRequirementProto
message OptionPrerequisiteProto
{
optional string key = 1 [ (help) = "path to config value" ];
repeated string value = 2 [ (help) = "list of required values" ];
@@ -65,7 +65,7 @@ message OptionProto
[ (help) = "message to display when option is in use" ];
optional bool set_by_default = 6
[ (help) = "this option is applied by default", default = false ];
repeated OptionRequirementProto requires = 7
repeated OptionPrerequisiteProto prerequisite = 7
[ (help) = "prerequisites for this option" ];
optional ConfigProto config = 4

View File

@@ -1,6 +1,6 @@
#include "globals.h"
#include "bytes.h"
#include "crc.h"
#include "lib/globals.h"
#include "lib/bytes.h"
#include "lib/crc.h"
template <class T>
T reflect(T bin, unsigned width = sizeof(T) * 8)

View File

@@ -1,6 +1,6 @@
#include <string>
#include <vector>
#include "csvreader.h"
#include "lib/csvreader.h"
std::vector<std::string> CsvReader::readLine()
{

View File

@@ -1,8 +1,8 @@
#include "globals.h"
#include "flags.h"
#include "fluxmap.h"
#include "decoders/decoders.h"
#include "encoders/encoders.h"
#include "lib/globals.h"
#include "lib/flags.h"
#include "lib/fluxmap.h"
#include "lib/decoders/decoders.h"
#include "lib/encoders/encoders.h"
#include "arch/agat/agat.h"
#include "arch/aeslanier/aeslanier.h"
#include "arch/amiga/amiga.h"
@@ -16,17 +16,18 @@
#include "arch/micropolis/micropolis.h"
#include "arch/mx/mx.h"
#include "arch/northstar/northstar.h"
#include "arch/q1/q1.h"
#include "arch/rolandd20/rolandd20.h"
#include "arch/smaky6/smaky6.h"
#include "arch/tids990/tids990.h"
#include "arch/victor9k/victor9k.h"
#include "arch/zilogmcz/zilogmcz.h"
#include "decoders/fluxmapreader.h"
#include "flux.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/flux.h"
#include "protocol.h"
#include "decoders/rawbits.h"
#include "sector.h"
#include "image.h"
#include "lib/decoders/rawbits.h"
#include "lib/sector.h"
#include "lib/image.h"
#include "lib/decoders/decoders.pb.h"
#include "lib/layout.h"
#include <numeric>
@@ -49,6 +50,7 @@ std::unique_ptr<Decoder> Decoder::create(const DecoderProto& config)
{DecoderProto::kMicropolis, createMicropolisDecoder },
{DecoderProto::kMx, createMxDecoder },
{DecoderProto::kNorthstar, createNorthstarDecoder },
{DecoderProto::kQ1, createQ1Decoder },
{DecoderProto::kRolandd20, createRolandD20Decoder },
{DecoderProto::kSmaky6, createSmaky6Decoder },
{DecoderProto::kTids990, createTids990Decoder },

View File

@@ -1,10 +1,10 @@
#ifndef DECODERS_H
#define DECODERS_H
#include "bytes.h"
#include "sector.h"
#include "decoders/fluxmapreader.h"
#include "decoders/fluxdecoder.h"
#include "lib/bytes.h"
#include "lib/sector.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxdecoder.h"
class Sector;
class Fluxmap;
@@ -12,7 +12,7 @@ class FluxmapReader;
class RawBits;
class DecoderProto;
#include "flux.h"
#include "lib/flux.h"
extern void setDecoderManualClockRate(double clockrate_us);

View File

@@ -13,6 +13,7 @@ import "arch/macintosh/macintosh.proto";
import "arch/micropolis/micropolis.proto";
import "arch/mx/mx.proto";
import "arch/northstar/northstar.proto";
import "arch/q1/q1.proto";
import "arch/rolandd20/rolandd20.proto";
import "arch/smaky6/smaky6.proto";
import "arch/tids990/tids990.proto";
@@ -21,7 +22,7 @@ import "arch/zilogmcz/zilogmcz.proto";
import "lib/fluxsink/fluxsink.proto";
import "lib/common.proto";
//NEXT: 32
//NEXT: 33
message DecoderProto {
optional double pulse_debounce_threshold = 1 [default = 0.30,
(help) = "ignore pulses with intervals shorter than this, in fractions of a clock"];
@@ -48,6 +49,7 @@ message DecoderProto {
MicropolisDecoderProto micropolis = 14;
MxDecoderProto mx = 15;
NorthstarDecoderProto northstar = 24;
Q1DecoderProto q1 = 32;
RolandD20DecoderProto rolandd20 = 31;
Smaky6DecoderProto smaky6 = 30;
Tids990DecoderProto tids990 = 16;
@@ -68,4 +70,3 @@ message DecoderProto {
optional bool skip_unnecessary_tracks = 29 [default = true,
(help) = "don't read tracks if we already have all necessary sectors"];
}

View File

@@ -1,7 +1,7 @@
#include "globals.h"
#include "fluxmap.h"
#include "decoders/fluxmapreader.h"
#include "decoders/fluxdecoder.h"
#include "lib/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/decoders/fluxdecoder.h"
#include "lib/decoders/decoders.pb.h"
/* This is a port of the samdisk code:

View File

@@ -1,9 +1,9 @@
#include "globals.h"
#include "fluxmap.h"
#include "decoders/fluxmapreader.h"
#include "flags.h"
#include "lib/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/flags.h"
#include "lib/proto.h"
#include "protocol.h"
#include "proto.h"
#include <numeric>
#include <math.h>
#include <strings.h>

View File

@@ -1,9 +1,9 @@
#ifndef FLUXMAPREADER_H
#define FLUXMAPREADER_H
#include "fluxmap.h"
#include "lib/fluxmap.h"
#include "lib/flags.h"
#include "protocol.h"
#include "flags.h"
class FluxMatcher;
class DecoderProto;

View File

@@ -1,5 +1,5 @@
#include "globals.h"
#include "decoders/decoders.h"
#include "lib/globals.h"
#include "lib/decoders/decoders.h"
Bytes decodeFmMfm(
std::vector<bool>::const_iterator ii, std::vector<bool>::const_iterator end)

View File

@@ -1,8 +1,9 @@
syntax = "proto2";
import "lib/common.proto";
import "lib/fl2.proto";
// Next: 17
// Next: 15
message DriveProto
{
optional int32 drive = 1
@@ -11,32 +12,30 @@ message DriveProto
[ default = INDEXMODE_DRIVE, (help) = "index pulse source" ];
optional int32 hard_sector_count = 3
[ default = 0, (help) = "number of hard sectors on disk" ];
optional double hard_sector_threshold_ns = 16
optional double hard_sector_threshold_ns = 4
[ default = 0, (help) = "index pulses longer than this interval are "
"considered sector markers; shorter indicates an true index marker" ];
optional bool high_density = 4
optional bool high_density = 5
[ default = true, (help) = "set if this is a high density disk" ];
optional bool sync_with_index = 5
optional bool sync_with_index = 6
[ default = false, (help) = "start reading at index mark" ];
optional double revolutions = 6
optional double revolutions = 7
[ default = 1.2, (help) = "number of revolutions to read" ];
optional int32 tracks = 7
optional int32 tracks = 8
[ default = 81, (help) = "Number of tracks supported by drive" ];
optional int32 heads = 8
optional int32 heads = 9
[ default = 2, (help) = "Number of heads supported by drive" ];
optional int32 head_bias = 9 [
optional int32 head_bias = 10 [
default = 0,
(help) = "Bias to apply to the head position (in tracks)"
];
optional int32 group_offset = 14 [
optional int32 group_offset = 11 [
default = 0,
(help) = "When writing groups, erase all tracks except this one in each group"
];
optional int32 head_width = 10
[ default = 1, (help) = "Width of the head (in tracks)" ];
optional float tpi = 11 [ default = 0, (help) = "TPI of drive; 0 disables all track mapping" ];
optional double rotational_period_ms = 12
optional DriveType drive_type = 12 [ default = DRIVETYPE_UNKNOWN, (help) = "Type of drive" ];
optional double rotational_period_ms = 13
[ default = 0, (help) = "Rotational period of the drive in milliseconds (0 to autodetect)"];
enum ErrorBehaviour {
@@ -45,7 +44,7 @@ message DriveProto
RECALIBRATE = 2;
}
optional ErrorBehaviour error_behaviour = 15
optional ErrorBehaviour error_behaviour = 14
[ default = JIGGLE, (help) = "what to do when an error occurs during reads" ];
}

View File

@@ -1,7 +1,7 @@
#include "globals.h"
#include "fluxmap.h"
#include "decoders/decoders.h"
#include "encoders/encoders.h"
#include "lib/globals.h"
#include "lib/fluxmap.h"
#include "lib/decoders/decoders.h"
#include "lib/encoders/encoders.h"
#include "arch/agat/agat.h"
#include "arch/amiga/amiga.h"
#include "arch/apple2/apple2.h"
@@ -98,6 +98,9 @@ Fluxmap& Fluxmap::appendBits(const std::vector<bool>& bits, nanoseconds_t clock)
appendPulse();
}
}
unsigned delta = (now - duration()) / NS_PER_TICK;
if (delta)
appendInterval(delta);
return *this;
}

Some files were not shown because too many files have changed in this diff Show More