Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ maven.install(
"org.indunet:fastproto:4.1.0",
"net.java.dev.jna:jna:5.19.1",
"net.java.dev.jna:jna-platform:5.19.1",
"com.google.truth.extensions:truth-proto-extension:1.4.5",
],
repositories = [
"https://repo1.maven.org/maven2",
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ choices because they can store multiple types of file system.

| Profile | Format | Read? | Write? | Filesystem? |
|:--------|:-------|:-----:|:------:|:------------|
| [`abc`](doc/disk-abc.md) | Ai Electronics ABC 24: CP/M; 158kB 35-track DSDD | 🦄 | | CPMFS |
| [`acornadfs`](doc/disk-acornadfs.md) | Acorn ADFS: BBC Micro, Archimedes | 🦖 | | |
| [`acorndfs`](doc/disk-acorndfs.md) | Acorn DFS: Acorn Atom, BBC Micro series | 🦄 | | ACORNDFS |
| [`aeslanier`](doc/disk-aeslanier.md) | AES Lanier "No Problem": 616kB 5.25" 77-track SSDD hard sectored | 🦖 | | |
Expand Down
29 changes: 29 additions & 0 deletions doc/disk-abc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
Ai Electronics ABC 24
====
## CP/M; 158kB 35-track DSDD
<!-- This file is automatically generated. Do not edit. -->

Ai Electronics was a Japanese computer company that produced minicomputers during the 1960s and 1970s. In 1979 they
started production of the ABC, the Ai Business Computer, a decently specced CP/M machine with 64kB RAM, a Z80, twin
floppy drives, GBIP ports, and a maths coprocessor.

The floppy disks it uses are relatively normal 35-track IBM scheme disks, with cylinder 0 reserved as the boot track.

## Options

(no options)

## Examples

To read:

- `fluxengine read -c abc -s drive:0 -o abc.img`

To write:

- `fluxengine write -c abc -d drive:0 -i abc.img`

## References

- [DoPECC's page on the ABC 24](https://dopecc.net/computers/ai/)

75 changes: 75 additions & 0 deletions java/com/cowlark/fluxengine/arch/abc.textpb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
shortname: "Ai Electronics ABC 24"
comment: 'CP/M; 158kB 35-track DSDD'
read_support_status: UNICORN

documentation:
<<<
Ai Electronics was a Japanese computer company that produced minicomputers during the 1960s and 1970s. In 1979 they
started production of the ABC, the Ai Business Computer, a decently specced CP/M machine with 64kB RAM, a Z80, twin
floppy drives, GBIP ports, and a maths coprocessor.

The floppy disks it uses are relatively normal 35-track IBM scheme disks, with cylinder 0 reserved as the boot track.
>>>

documentation:
<<<
## References

- [DoPECC's page on the ABC 24](https://dopecc.net/computers/ai/)
>>>

image_reader {
filename: "abc.img"
type: IMAGETYPE_IMG
}

image_writer {
filename: "abc.img"
type: IMAGETYPE_IMG
}

flux_source {
type: FLUXTYPE_DRIVE
}

encoder {
ibm {
trackdata {
target_rotational_period_ms: 167
target_clock_period_us: 3.333
}
}
}

decoder {
ibm {
}
}

layout {
layoutdata {
sector_size: 512
physical {
start_sector: 1
count: 9
}
}
tracks: 35
sides: 2
format_type: FORMATTYPE_40TRACK
}

filesystem {
type: CPMFS
cpmfs {
filesystem_start {
track: 1
side: 0
sector: 1
}
block_size: 2048
dir_entries: 64
}
}


12 changes: 6 additions & 6 deletions java/com/cowlark/fluxengine/buildtools/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ java_library(
],
)

java_binary(
name = "protoencode",
main_class = "com.cowlark.fluxengine.buildtools.ProtoEncode",
runtime_deps = [":buildtools"],
)

# The doc tools live in their own library, since they depend on the format
# data, which is itself generated by the protoencode tool above.
java_library(
Expand All @@ -34,12 +40,6 @@ java_library(
],
)

java_binary(
name = "protoencode",
main_class = "com.cowlark.fluxengine.buildtools.ProtoEncode",
runtime_deps = [":buildtools"],
)

java_binary(
name = "mkdoc",
main_class = "com.cowlark.fluxengine.buildtools.MkDoc",
Expand Down
21 changes: 5 additions & 16 deletions java/com/cowlark/fluxengine/cli/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -64,26 +64,15 @@ public interface Command
.put("gui", GuiCommand::new)
.build();

/* Consume arguments until we reach a real command, instantiate it, and
* run it with the tail of the argv array. */
static boolean dispatch(
Map<String, Supplier<? extends Command>> commands,
ImmutableList<String> args)
ImmutableList<String> args) throws Exception
{
for (int index = 0; index < args.size(); index++)
Supplier<? extends Command> supplier = commands.get(args.getFirst());
if (supplier != null)
{
Supplier<? extends Command> supplier = commands.get(args.get(index));
if (supplier != null)
{
try
{
supplier.get().run(ImmutableList.copyOf(args.subList(index + 1, args.size())));
} catch (Exception e)
{
throw new RuntimeException(e);
}
return true;
}
supplier.get().run(ImmutableList.copyOf(args.subList(1, args.size())));
return true;
}

return false;
Expand Down
6 changes: 5 additions & 1 deletion java/com/cowlark/fluxengine/cli/CommandGroup.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.cowlark.fluxengine.cli;

import com.cowlark.fluxengine.core.FluxEngineException;
import com.google.common.collect.ImmutableList;
import java.util.Map;
import java.util.function.Supplier;
Expand All @@ -26,8 +27,11 @@ public String getHelp()
}

@Override
public void run(ImmutableList<String> args)
public void run(ImmutableList<String> args) throws Exception
{
if (args.getFirst().startsWith("-"))
throw new FluxEngineException("CLI verbs must come before all options, sorry!");

if (!Command.dispatch(subcommands, args))
Main.help(subcommands, "<command> <format> [<flags>...]");
}
Expand Down
4 changes: 2 additions & 2 deletions java/com/cowlark/fluxengine/cli/DevicesCommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

import static com.google.common.base.Strings.nullToEmpty;

import com.cowlark.fluxengine.config.UsbFinder;
import com.cowlark.fluxengine.config.UsbFinder.CandidateDevice;
import com.cowlark.fluxengine.usb.UsbFinder;
import com.cowlark.fluxengine.usb.UsbFinder.CandidateDevice;
import com.cowlark.fluxengine.core.flags.FlagGroup;
import com.google.common.collect.ImmutableList;
import java.util.List;
Expand Down
2 changes: 1 addition & 1 deletion java/com/cowlark/fluxengine/cli/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ private Main()
{
}

public static void main(String[] args)
public static void main(String[] args) throws Exception
{
Logger.setLogger(LogRenderer.create(System.out)::add);

Expand Down
5 changes: 3 additions & 2 deletions java/com/cowlark/fluxengine/config/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,16 @@ java_library(
"//java/com/cowlark/fluxengine/core/flags",
"//java/com/cowlark/fluxengine/data",
"//java/com/cowlark/fluxengine/fluxsink:fluxsink_java_proto",
"//java/com/cowlark/fluxengine/fluxsource",
"//java/com/cowlark/fluxengine/fluxsource:fluxsource_java_proto",
"//java/com/cowlark/fluxengine/imagereader",
"//java/com/cowlark/fluxengine/imagewriter:imagewriter_java_proto",
"//java/com/cowlark/fluxengine/usb",
"@com_google_protobuf//java/core",
"@maven//:com_fazecast_jSerialComm",
"@maven//:com_google_guava_guava",
"@maven//:com_jayway_jsonpath_json_path",
"@maven//:javax_usb_usb_api",
"@maven//:net_java_dev_jna_jna",
"@maven//:net_java_dev_jna_jna_platform",
"@maven//:org_projectlombok_lombok",
"@maven//:org_usb4java_usb4java_javax",
],
Expand Down
79 changes: 49 additions & 30 deletions java/com/cowlark/fluxengine/config/ConfigBuilder.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,21 @@
import static com.cowlark.fluxengine.config.FluxSourceSinkType.FLUXTYPE_TEST_PATTERN;
import static com.cowlark.fluxengine.config.FluxSourceSinkType.FLUXTYPE_VCD;
import static com.cowlark.fluxengine.config.ImageFormats.Mode.MODE_RO;
import static com.cowlark.fluxengine.config.ImageReaderWriterType.IMAGETYPE_D64;
import static com.cowlark.fluxengine.config.ImageReaderWriterType.IMAGETYPE_D88;
import static com.cowlark.fluxengine.config.ImageReaderWriterType.IMAGETYPE_DIM;
import static com.cowlark.fluxengine.config.ImageReaderWriterType.IMAGETYPE_DISKCOPY;
import static com.cowlark.fluxengine.config.ImageReaderWriterType.IMAGETYPE_FDI;
import static com.cowlark.fluxengine.config.ImageReaderWriterType.IMAGETYPE_IMD;
import static com.cowlark.fluxengine.config.ImageReaderWriterType.IMAGETYPE_IMG;
import static com.cowlark.fluxengine.config.ImageReaderWriterType.IMAGETYPE_JV3;
import static com.cowlark.fluxengine.config.ImageReaderWriterType.IMAGETYPE_NFD;
import static com.cowlark.fluxengine.config.ImageReaderWriterType.IMAGETYPE_NSI;
import static com.cowlark.fluxengine.config.ImageReaderWriterType.IMAGETYPE_TD0;

import com.cowlark.fluxengine.config.ImageFormats.ImageFormat;
import com.cowlark.fluxengine.core.FluxEngineException;
import com.cowlark.fluxengine.core.Logger;
import com.cowlark.fluxengine.core.flags.FlagGroup;
import com.cowlark.fluxengine.core.flags.Flags;
import com.cowlark.fluxengine.data.Formats;
import com.cowlark.fluxengine.fluxsink.FluxSinkProto;
import com.cowlark.fluxengine.fluxsource.FluxSource;
import com.cowlark.fluxengine.fluxsource.FluxSourceProto;
import com.cowlark.fluxengine.imagereader.ImageReader;
import com.cowlark.fluxengine.usb.UsbFinder;
import com.google.common.collect.ImmutableList;
import com.google.protobuf.TextFormat;
import lombok.SneakyThrows;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
Expand Down Expand Up @@ -131,51 +125,68 @@ public ConfigBuilder mergeConfig(ConfigProto other)
return this;
}

@SneakyThrows
public ConfigBuilder withFluxSource(String filename)
{
FluxSourceProto.Builder fluxSource = proto.getFluxSourceBuilder();
FluxSourceProto.Builder fluxSourceProto = proto.getFluxSourceBuilder();
if (filename.endsWith(".flux"))
{
fluxSource.setType(FLUXTYPE_FLUX);
fluxSource.getFl2Builder().setFilename(filename);
fluxSourceProto.setType(FLUXTYPE_FLUX);
fluxSourceProto.getFl2Builder().setFilename(filename);
} else if (filename.endsWith(".scp"))
{
fluxSource.setType(FLUXTYPE_SCP);
fluxSource.getScpBuilder().setFilename(filename);
fluxSourceProto.setType(FLUXTYPE_SCP);
fluxSourceProto.getScpBuilder().setFilename(filename);
} else if (filename.endsWith(".a2r"))
{
fluxSource.setType(FLUXTYPE_A2R);
fluxSource.getA2RBuilder().setFilename(filename);
fluxSourceProto.setType(FLUXTYPE_A2R);
fluxSourceProto.getA2RBuilder().setFilename(filename);
} else if (filename.endsWith(".cwf"))
{
fluxSource.setType(FLUXTYPE_CWF);
fluxSource.getCwfBuilder().setFilename(filename);
fluxSourceProto.setType(FLUXTYPE_CWF);
fluxSourceProto.getCwfBuilder().setFilename(filename);
} else if (filename.startsWith("dmk:"))
{
fluxSource.setType(FLUXTYPE_DMK);
fluxSource.getDmkBuilder().setDirectory(filename.substring(4));
fluxSourceProto.setType(FLUXTYPE_DMK);
fluxSourceProto.getDmkBuilder().setDirectory(filename.substring(4));
} else if (filename.equals("erase:"))
{
fluxSource.setType(FLUXTYPE_ERASE);
fluxSourceProto.setType(FLUXTYPE_ERASE);
} else if (filename.startsWith("kryoflux:"))
{
fluxSource.setType(FLUXTYPE_KRYOFLUX);
fluxSource.getKryofluxBuilder().setDirectory(filename.substring(9));
fluxSourceProto.setType(FLUXTYPE_KRYOFLUX);
fluxSourceProto.getKryofluxBuilder().setDirectory(filename.substring(9));
} else if (filename.startsWith("testpattern:"))
{
fluxSource.setType(FLUXTYPE_TEST_PATTERN);
fluxSourceProto.setType(FLUXTYPE_TEST_PATTERN);
} else if (filename.startsWith("drive:"))
{
fluxSource.setType(FLUXTYPE_DRIVE);
fluxSourceProto.setType(FLUXTYPE_DRIVE);
proto.getDriveBuilder().setDrive(Integer.parseInt(filename.substring(6)));
} else if (filename.startsWith("flx:"))
{
fluxSource.setType(FLUXTYPE_FLX);
fluxSource.getFlxBuilder().setDirectory(filename.substring(4));
fluxSourceProto.setType(FLUXTYPE_FLX);
fluxSourceProto.getFlxBuilder().setDirectory(filename.substring(4));
} else if (filename.startsWith("nop:"))
fluxSource.setType(FLUXTYPE_NOP);
fluxSourceProto.setType(FLUXTYPE_NOP);
else
throw new ConfigException("unrecognised flux filename '" + filename + "'");

/* If the FluxSource has any extra config to contribute, add it here. */

try (FluxSource fluxSource = FluxSource.create(
ConfigProto
.newBuilder()
.setFluxSource(fluxSourceProto)
.build(), () -> null))
{
ConfigProto extraConfig = fluxSource.getExtraConfig();
if (extraConfig != null)
proto.mergeFrom(extraConfig);
} catch (FluxEngineException e)
{
/* File not found --- ignore. */
}
return this;
}

Expand Down Expand Up @@ -245,12 +256,20 @@ public ConfigBuilder withImageWriter(String filename)
return this;
}

@SneakyThrows
public ConfigBuilder withImageReader(String filename)
{
ImageFormat format = findImageFormat(filename);
if (format == null)
throw new ConfigException("unrecognised image filename '" + filename + "'");
proto.getImageReaderBuilder().setType(format.type()).setFilename(filename);

try (ImageReader reader = ImageReader.create(proto.getImageReader()))
{
ConfigProto extraConfig = reader.getExtraConfig();
if (extraConfig != null)
proto.mergeFrom(extraConfig);
}
return this;
}

Expand Down
3 changes: 2 additions & 1 deletion java/com/cowlark/fluxengine/data/Locations.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.cowlark.fluxengine.core.FluxEngineException;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

Expand Down Expand Up @@ -38,7 +39,7 @@ public static String convertCylinderHeadsToString(List<CylinderHead> chs)
{
StringBuilder sb = new StringBuilder();
boolean first = true;
for (CylinderHead ch : chs)
for (CylinderHead ch : chs.stream().sorted().collect(ImmutableList.toImmutableList()))
{
if (!first)
sb.append(' ');
Expand Down
Loading
Loading