diff --git a/app/cli-acx/src/main/java/io/github/applecommander/acx/arggroup/CoordinateSelection.java b/app/cli-acx/src/main/java/io/github/applecommander/acx/arggroup/CoordinateSelection.java index 09b6082..552f713 100644 --- a/app/cli-acx/src/main/java/io/github/applecommander/acx/arggroup/CoordinateSelection.java +++ b/app/cli-acx/src/main/java/io/github/applecommander/acx/arggroup/CoordinateSelection.java @@ -30,6 +30,16 @@ public class CoordinateSelection { @ArgGroup(exclusive = false) private CoordinateSelection.BlockCoordinateSelection blockCoordinate; + public boolean includesBootSector() { + if (sectorCoordinate != null) { + return sectorCoordinate.isBootSector(); + } + else if (blockCoordinate != null) { + return blockCoordinate.isBootBlock(); + } + return false; + } + public byte[] read(Disk disk) { if (sectorCoordinate != null) { return sectorCoordinate.read(disk); @@ -56,6 +66,9 @@ public class CoordinateSelection { @Option(names = { "-s", "--sector" }, required = true, description = "Sector number.") private Integer sector; + public boolean isBootSector() { + return track == 0 && sector == 0; + } public byte[] read(Disk disk) { return disk.readSector(track, sector); } @@ -67,6 +80,9 @@ public class CoordinateSelection { @Option(names = { "-b", "--block" }, description = "Block number.") private Integer block; + public boolean isBootBlock() { + return block == 0; + } public byte[] read(Disk disk) { return disk.readBlock(block); } diff --git a/app/cli-acx/src/main/java/io/github/applecommander/acx/command/DumpCommand.java b/app/cli-acx/src/main/java/io/github/applecommander/acx/command/DumpCommand.java index c341761..fd877b9 100644 --- a/app/cli-acx/src/main/java/io/github/applecommander/acx/command/DumpCommand.java +++ b/app/cli-acx/src/main/java/io/github/applecommander/acx/command/DumpCommand.java @@ -21,6 +21,7 @@ package io.github.applecommander.acx.command; import java.io.PrintWriter; import java.io.StringWriter; +import java.util.Optional; import java.util.function.BiFunction; import java.util.stream.Collectors; @@ -28,35 +29,34 @@ import com.webcodepro.applecommander.util.AppleUtil; import io.github.applecommander.acx.arggroup.CoordinateSelection; import io.github.applecommander.acx.base.ReadOnlyDiskImageCommandOptions; +import io.github.applecommander.acx.converter.IntegerTypeConverter; import io.github.applecommander.disassembler.api.Disassembler; import io.github.applecommander.disassembler.api.Instruction; import io.github.applecommander.disassembler.api.mos6502.InstructionSet6502; import picocli.CommandLine.ArgGroup; import picocli.CommandLine.Command; +import picocli.CommandLine.Mixin; import picocli.CommandLine.Option; @Command(name = "dump", description = "Dump a block or sector.") public class DumpCommand extends ReadOnlyDiskImageCommandOptions { - @ArgGroup(multiplicity = "1", heading = "%nCoordinate Selection:%n") - private CoordinateSelection coordinate = new CoordinateSelection(); - @ArgGroup(heading = "%nOutput Selection:%n") private OutputSelection output = new OutputSelection(); - - @Option(names = { "-a", "--address" }, description = "Starting address.") - private int address = 0x800; + + @Mixin + private Options options = new Options(); @Override public int handleCommand() throws Exception { - byte[] data = coordinate.read(disk); - System.out.println(output.format(address, data)); + byte[] data = options.coordinate.read(disk); + System.out.println(output.format(options, data)); return 0; } public static class OutputSelection { - private BiFunction fn = this::formatHexDump; - public String format(int address, byte[] data) { - return fn.apply(address, data); + private BiFunction fn = this::formatHexDump; + public String format(Options options, byte[] data) { + return fn.apply(options, data); } @Option(names = "--hex", description = "Hex dump.") @@ -69,13 +69,16 @@ public class DumpCommand extends ReadOnlyDiskImageCommandOptions { fn = this::formatDisassembly; } - public String formatHexDump(int address, byte[] data) { - return AppleUtil.getHexDump(address, data); + public String formatHexDump(Options options, byte[] data) { + return AppleUtil.getHexDump(options.address, data); } - public String formatDisassembly(int address, byte[] data) { + public String formatDisassembly(Options options, byte[] data) { + // If the offset is given, use that. If not, use 0 except for the boot sector and then use 1. + int calculatedOffset = options.offset.orElse(options.coordinate.includesBootSector() ? 1 : 0); return Disassembler.with(data) - .startingAddress(address) + .startingAddress(options.address) + .bytesToSkip(calculatedOffset) .use(InstructionSet6502.for6502()) .decode() .stream() @@ -100,4 +103,17 @@ public class DumpCommand extends ReadOnlyDiskImageCommandOptions { return sw.toString(); } } + + public static class Options { + @ArgGroup(multiplicity = "1", heading = "%nCoordinate Selection:%n") + private CoordinateSelection coordinate = new CoordinateSelection(); + + @Option(names = { "-a", "--address" }, converter = IntegerTypeConverter.class, + description = "Starting address.") + private int address = 0x800; + + @Option(names = { "-o", "--offset" }, converter = IntegerTypeConverter.class, + description = "Number of bytes to skip into file before disassembling.") + private Optional offset = Optional.empty(); + } } diff --git a/gradle.properties b/gradle.properties index e95ccb1..98faa3c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -16,4 +16,4 @@ commonsCsvVersion=1.8 gsonVersion=2.8.6 picocliVersion=4.6.2 springBoot=2.6.1 -acdasmVersion=0.3.0 +acdasmVersion=0.4.0