Skip to content

Commit

Permalink
Add support for ST partitions
Browse files Browse the repository at this point in the history
  • Loading branch information
dwildie committed Jan 10, 2023
1 parent 197059c commit 02b60e2
Show file tree
Hide file tree
Showing 8 changed files with 149 additions and 32 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<groupId>au.wildie.m68k</groupId>
<artifactId>cromix-fs</artifactId>
<version>2.6</version>
<version>2.7</version>

<name>cromix-fs</name>

Expand Down
46 changes: 42 additions & 4 deletions src/main/java/au/wildie/m68k/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ public static void main(String[] args ) throws IOException, STDiskException, Inv
}
get(args[1]).list(System.out);
return;
} else if (args.length == 4 && args[0].equalsIgnoreCase("-l") && args[1].equalsIgnoreCase("-p")) {
// List partition files
if (!new File(args[3]).exists()) {
System.out.printf("Cannot open image file %s\n", args[3]);
return;
}
int partitionIndex = Integer.parseInt(args[2]);
get(args[3], partitionIndex).list(System.out);
return;
} else if (args.length == 2 && args[0].equalsIgnoreCase("-c")) {
// Check filesystem
if (!new File(args[1]).exists()) {
Expand All @@ -45,6 +54,18 @@ public static void main(String[] args ) throws IOException, STDiskException, Inv
((CromixFileSystem)fs).check(System.out);
}
return;
} else if (args.length == 4 && args[0].equalsIgnoreCase("-c") && args[1].equalsIgnoreCase("-p")) {
// Check filesystem
if (!new File(args[3]).exists()) {
System.out.printf("Cannot open image file %s\n", args[3]);
return;
}
int partitionIndex = Integer.parseInt(args[2]);
FileSystemOps fs = get(args[3], partitionIndex);
if (fs instanceof CromixFileSystem) {
((CromixFileSystem)fs).check(System.out);
}
return;
} else if (args.length == 2 && args[0].equalsIgnoreCase("-di")) {
// Dump inodes
if (!new File(args[1]).exists()) {
Expand All @@ -68,6 +89,19 @@ public static void main(String[] args ) throws IOException, STDiskException, Inv
}
get(args[1]).extract(args[2], System.out);
return;
} else if (args.length == 5 && args[0].equalsIgnoreCase("-x") && args[1].equalsIgnoreCase("-p")) {
// Extract files
if (!new File(args[3]).exists()) {
System.out.printf("Cannot open image file %s\n", args[3]);
return;
}
File target = new File(args[4]);
if (!target.exists()) {
target.mkdirs();
}
int partitionIndex = Integer.parseInt(args[2]);
get(args[3], partitionIndex).extract(args[4], System.out);
return;
} else if (args.length == 3 && args[0].equalsIgnoreCase("-f")) {
// Create new ftar image
if (!new File(args[2]).exists()) {
Expand Down Expand Up @@ -157,6 +191,10 @@ public static void main(String[] args ) throws IOException, STDiskException, Inv
}

private static FileSystemOps get(String filename) throws IOException, InvalidVFDImageException, STDiskException {
return get(filename, null);
}

private static FileSystemOps get(String filename, Integer partitionIndex) throws IOException, InvalidVFDImageException, STDiskException {
FileSystemOps fs;
if (filename.toLowerCase().trim().endsWith(".imd")) {
fs = FileSystems.getIMDFloppyFileSystem(filename, System.out);
Expand All @@ -165,7 +203,7 @@ private static FileSystemOps get(String filename) throws IOException, InvalidVFD
} else if (filename.toLowerCase().trim().endsWith(".hfe")) {
fs = FileSystems.getHFEFloppyFileSystem(filename, System.out);
} else {
fs = FileSystems.getSTFileSystem(filename, System.out);
fs = FileSystems.getSTFileSystem(filename, partitionIndex, System.out);
}
return fs;
}
Expand All @@ -176,16 +214,16 @@ private static void showUsage() {
String jarName = getJarName();

System.out.print("\nCheck a cromix image:\n");
System.out.printf(" java -jar %s -c file.imd\n", jarName);
System.out.printf(" java -jar %s -c [-p partitionIndex] file.imd|file.img\n", jarName);

System.out.print("\nDump cromix inodes:\n");
System.out.printf(" java -jar %s -di file.imd\n", jarName);

System.out.print("\nList files in an image:\n");
System.out.printf(" java -jar %s -l file.imd\n", jarName);
System.out.printf(" java -jar %s -l [-p partitionIndex] file.imd|file.img\n", jarName);

System.out.print("\nExtract files from an image to path:\n");
System.out.printf(" java -jar %s -x file.imd path\n", jarName);
System.out.printf(" java -jar %s -x [-p partitionIndex] file.imd|file.img path\n", jarName);

System.out.print("\nCreate a new Cromix ftar image containing files from path:\n");
System.out.printf(" java -jar %s -f file.imd path\n", jarName);
Expand Down
24 changes: 16 additions & 8 deletions src/main/java/au/wildie/m68k/cromixfs/disk/st/CromixStDisk.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,26 @@

import au.wildie.m68k.cromixfs.disk.DiskInterface;
import au.wildie.m68k.cromixfs.fs.cromix.CromixFileSystem;
import lombok.Getter;
import lombok.Setter;

import java.io.*;
import java.util.Optional;

public class CromixStDisk implements DiskInterface {
private static final int SECTOR_SIZE = 512; // Disks are always 512 byte sectors

private final byte[][][][] media;
private final STDCDiskInfo info;

public CromixStDisk(String fileName) throws STDiskException {
@Getter
private final STDCPartitionTable partitionTable;

// @Setter
@Getter
private int currentPartition = 0;

public CromixStDisk(String fileName, Integer partitionIndex) throws STDiskException {
byte[] sector = new byte[SECTOR_SIZE];

try (InputStream in = new FileInputStream(fileName)) {
Expand Down Expand Up @@ -48,8 +58,10 @@ public CromixStDisk(String fileName) throws STDiskException {
} catch (IOException e) {
throw new STDiskException(String.format("Error reading disk image file \"%s\"\n", fileName), e);
}
}

partitionTable = new STDCPartitionTable(info, media);
currentPartition = Optional.ofNullable(partitionIndex).orElse(0);
}

public void list(PrintStream out) throws IOException {
new CromixFileSystem(this).list(out);
Expand All @@ -60,7 +72,6 @@ public void extract(String path, PrintStream out) throws IOException {
new CromixFileSystem(this).extract(path, out);
}


public void check(PrintStream out) throws IOException {
new CromixFileSystem(this).check(out);
}
Expand All @@ -77,10 +88,7 @@ public void flushSuperBlock(byte[] data) {

@Override
public byte[] getBlock(int block) {
if (block == 0x0095) {
System.out.print("stop");
}
int c = getCylinderForBlock(0, block);
int c = getCylinderForBlock(this.currentPartition, block);
int h = getHeadForBlock(block);
int s = getSectorForBlock(block);
return media[c][h][s];
Expand Down Expand Up @@ -121,7 +129,7 @@ private int getCylinderForBlock(int unit, int block) {
}

private int getStartingCylinder(int unit) {
return 1; // Changes when partition table is present
return partitionTable.getStartCylinder(unit).orElse(1);
}

private int getHeadForBlock(int block) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package au.wildie.m68k.cromixfs.disk.st;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.ToString;

import java.io.PrintStream;
import java.util.Optional;

public class STDCPartitionTable {
public static final int TABLE_SIZE = 32;
private final STDCDiskInfo info;
private final Entry[] table = new Entry[TABLE_SIZE];

public STDCPartitionTable(STDCDiskInfo info, byte[][][][] media) {
this(info, media[0][0][info.getStartOfPartitionTable() / info.getBytesPerSector()]);
}

public STDCPartitionTable(STDCDiskInfo info, byte[] sector) {
this.info = info;

table[0] = new Entry(1, info.getCylinderCount() - 1);
table[TABLE_SIZE - 1] = new Entry(0, info.getCylinderCount());

for (int i = 0 ; i < TABLE_SIZE; i++) {
int startCylinder = ((0xFF & sector[i * 2]) << 8) + (0xFF & sector[i * 2 + 1]);
if (startCylinder == 0xe5e5) {
break;
}
table[i + 1] = new Entry(startCylinder, info.getCylinderCount() - startCylinder);
table[i].numberOfCylinders = startCylinder - table[i].startCylinder;
}
}

public Optional<Integer> getStartCylinder(int partitionIndex) {
return Optional.ofNullable(table[partitionIndex]).map(Entry::getStartCylinder);
}

@ToString
@Getter
@AllArgsConstructor
@NoArgsConstructor
public static final class Entry {
private int startCylinder;
private int numberOfCylinders;
}

public void logTable(PrintStream out) {
out.println("Partition # Starting Cylinder Number of cylinders Size (Kbytes)");
for (int i = 0; i < TABLE_SIZE; i++) {
if (table[i] != null) {
out.printf(" %2d %5d %5d %,10d \n",
i,
table[i].startCylinder,
table[i].numberOfCylinders,
(table[i].numberOfCylinders * info.getSurfaceCount() * info.getSectorsPerTrack() * info.getBytesPerSector()) / 1024);
}
}
}
}
4 changes: 2 additions & 2 deletions src/main/java/au/wildie/m68k/cromixfs/fs/FileSystems.java
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ protected static FileSystem getVFDFloppyFileSystem(VFDImage image, PrintStream o
throw new VFDFloppyException(String.format("Unrecognised disk, format label: \"%s\"", formatLabel));
}

public static FileSystem getSTFileSystem(String fileName, PrintStream out) throws STDiskException, IOException {
return new CromixFileSystem(new CromixStDisk(fileName));
public static FileSystem getSTFileSystem(String fileName, Integer partitionIndex, PrintStream out) throws STDiskException, IOException {
return new CromixFileSystem(new CromixStDisk(fileName, partitionIndex));
}
}
17 changes: 8 additions & 9 deletions src/main/java/au/wildie/m68k/cromixfs/fs/cromix/Inode.java
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
package au.wildie.m68k.cromixfs.fs.cromix;

import static au.wildie.m68k.cromixfs.fs.CromixTime.TIME_SIZE;
import static au.wildie.m68k.cromixfs.fs.cromix.InodeType.*;
import static au.wildie.m68k.cromixfs.fs.cromix.PointerBlock.BLOCK_POINTER_COUNT;
import static au.wildie.m68k.cromixfs.utils.BinUtils.*;
import au.wildie.m68k.cromixfs.disk.DiskInterface;
import au.wildie.m68k.cromixfs.fs.CromixTime;
import lombok.Getter;
import lombok.Setter;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import au.wildie.m68k.cromixfs.disk.DiskInterface;
import au.wildie.m68k.cromixfs.fs.CromixTime;
import lombok.Getter;
import lombok.Setter;
import static au.wildie.m68k.cromixfs.fs.CromixTime.TIME_SIZE;
import static au.wildie.m68k.cromixfs.fs.cromix.InodeType.*;
import static au.wildie.m68k.cromixfs.fs.cromix.PointerBlock.BLOCK_POINTER_COUNT;
import static au.wildie.m68k.cromixfs.utils.BinUtils.*;

@Getter
@Setter
Expand Down
10 changes: 10 additions & 0 deletions src/test/java/au/wildie/m68k/AppTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ public void testCreateSmall() throws InvalidVFDImageException, STDiskException,
App.main(new String[]{"-ms", "/tmp/5se.IMD"});
}

@Test
public void testListPartition() throws InvalidVFDImageException, STDiskException, IOException {
App.main(new String[]{"-l", "-p", "7", "/home/dwildie/mfm/20220705.D45.C1536.H16.master.img"});
}

@Test
public void testCheckPartition() throws InvalidVFDImageException, STDiskException, IOException {
App.main(new String[]{"-c", "-p", "0", "/home/dwildie/mfm/20220705.D45.C1536.H16.master.img"});
}

@Test
public void testListSmall() throws InvalidVFDImageException, STDiskException, IOException {
App.main(new String[]{"-l", "/tmp/5s.IMD"});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class CromixStDiskTest {
// private static final String LIST_FILE = "/home/dwildie/m68000/cromix/disk0_848.list";
// private static final String EXTRACT_PATH = "/home/dwildie/m68000/cromix/disk0_848.dump";

private static final String IMG_FILE = "/home/dwildie/ide/idecromix.img";
private static final String IMG_FILE = "/home/dwildie/mfm/20220705.D45.C1536.H16.master.img";
// private static final String LIST_FILE = "/home/dwildie/ide/idecromix.list";
// private static final String EXTRACT_PATH = "/home/dwildie/ide/idecromix.dump";

Expand All @@ -26,11 +26,12 @@ public void list() throws IOException, STDiskException {
throw new IllegalArgumentException(String.format("Image file %s does not exist", IMG_FILE));
}

String listFile = String.format("%s.%s", FilenameUtils.removeExtension(IMG_FILE), "list");
try (FileOutputStream out = new FileOutputStream(listFile)) {
CromixStDisk stDisk = new CromixStDisk(IMG_FILE);
stDisk.list(new PrintStream(out));
}
// String listFile = String.format("%s.%s", FilenameUtils.removeExtension(IMG_FILE), "list");
// try (FileOutputStream out = new FileOutputStream(listFile)) {
CromixStDisk stDisk = new CromixStDisk(IMG_FILE, 7);
stDisk.getPartitionTable().logTable(new PrintStream(System.out));
stDisk.list(new PrintStream(System.out));
// }
System.out.println("done");
}

Expand All @@ -50,7 +51,7 @@ public void extract() throws IOException, STDiskException {
}
extractDir.mkdirs();

CromixStDisk stDisk = new CromixStDisk(IMG_FILE);
CromixStDisk stDisk = new CromixStDisk(IMG_FILE, 0);
stDisk.extract(extractPath, System.out);
System.out.println("done");
}
Expand All @@ -63,7 +64,7 @@ public void check() throws IOException, STDiskException {
throw new IllegalArgumentException(String.format("Image file %s does not exist", IMG_FILE));
}

CromixStDisk stDisk = new CromixStDisk(IMG_FILE);
CromixStDisk stDisk = new CromixStDisk(IMG_FILE, null);
stDisk.check(System.out);

System.out.println("done");
Expand Down

0 comments on commit 02b60e2

Please sign in to comment.