Generalize differences of RDOS 2.1/3.2 vs RDOS 3.3

This commit is contained in:
Bradley Bell 2023-10-21 16:23:37 -07:00
parent 836917b283
commit aa9dcd2695
1 changed files with 55 additions and 43 deletions

View File

@ -67,15 +67,38 @@ public class RdosFormatDisk extends FormattedDisk {
*/ */
public static final int ENTRY_LENGTH = 0x20; public static final int ENTRY_LENGTH = 0x20;
/** /**
* Specifies the number of blocks on the disk. * Specifies the number of tracks on the disk.
* RDOS apparantly only worked on 5.25" disks. * RDOS apparantly only worked on 5.25" disks.
*/ */
public static final int BLOCKS_ON_DISK = 455; public static final int TRACKS_ON_DISK = 35;
/**
* Number of sectors used by catalog.
* FIXME: some sources say 10, others say 11. RDOS 3.3 may support 16.
*/
public static final int CATALOG_SECTORS = 10;
/** /**
* The known filetypes for a RDOS disk. * The known filetypes for a RDOS disk.
*/ */
public static final String[] filetypes = { "B", "A", "T" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ public static final String[] filetypes = { "B", "A", "T" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
/**
* 13 sectors for RDOS 2.1/3.2, native sectoring (16) for RDOS 3.3
*/
private int SectorsPerTrack() {
if (getImageOrder() instanceof ProdosOrder) {
return getImageOrder().getSectorsPerTrack();
} else {
return 13;
}
}
/**
* 455 blocks for RDOS 2.1/3.2, 560 for RDOS 3.3
*/
private int BlocksOnDisk() {
return TRACKS_ON_DISK * SectorsPerTrack();
}
/** /**
* Use this inner interface for managing the disk usage data. * Use this inner interface for managing the disk usage data.
* This off-loads format-specific implementation to the implementing class. * This off-loads format-specific implementation to the implementing class.
@ -94,13 +117,13 @@ public class RdosFormatDisk extends FormattedDisk {
private int location = -1; private int location = -1;
private BitSet bitmap = null; private BitSet bitmap = null;
public boolean hasNext() { public boolean hasNext() {
return location == -1 || location < BLOCKS_ON_DISK - 1; return location == -1 || location < BlocksOnDisk() - 1;
} }
public void next() { public void next() {
if (bitmap == null) { if (bitmap == null) {
bitmap = new BitSet(BLOCKS_ON_DISK); bitmap = new BitSet(BlocksOnDisk());
// mark all blocks as unused // mark all blocks as unused
for (int b=0; b<BLOCKS_ON_DISK; b++) { for (int b=0; b<BlocksOnDisk(); b++) {
bitmap.set(b); bitmap.set(b);
} }
// for each file, mark the blocks used // for each file, mark the blocks used
@ -151,8 +174,12 @@ public class RdosFormatDisk extends FormattedDisk {
* itself is a 13 sector format. * itself is a 13 sector format.
*/ */
public byte[] readRdosBlock(int block) { public byte[] readRdosBlock(int block) {
int track = block / 13; int s = SectorsPerTrack();
int sector = sectorSkew[block % 13]; int track = block / s;
int sector = block % s;
if (s == 13) {
sector = sectorSkew[sector];
}
return readSector(track, sector); return readSector(track, sector);
} }
@ -166,39 +193,28 @@ public class RdosFormatDisk extends FormattedDisk {
* itself is a 13 sector format. * itself is a 13 sector format.
*/ */
public void writeRdosBlock(int block, byte[] data) { public void writeRdosBlock(int block, byte[] data) {
int track = block / 13; int s = SectorsPerTrack();
int sector = sectorSkew[block % 13]; int track = block / s;
int sector = block % s;
if (s == 13) {
sector = sectorSkew[sector];
}
writeSector(track, sector, data); writeSector(track, sector, data);
} }
/**
* Read the block from the disk image.
*/
public byte[] readBlock(int block) {
int track = block / 16;
int sector = block % 16;
return getImageOrder().readSector(track, sector);
}
/**
* Write the block to the disk image.
*/
public void writeBlock(int block, byte[] data) {
int track = block / 16;
int sector = block % 16;
getImageOrder().writeSector(track, sector, data);
}
/** /**
* RDOS really does not have a disk name. Fake one. * RDOS really does not have a disk name. Fake one.
*/ */
public String getDiskName() { public String getDiskName() {
if (getImageOrder() instanceof ProdosOrder) { if (SectorsPerTrack() == 13) {
/* Use the comment/tag added in the 13->16 sector conversion */
byte[] block = readRdosBlock(4);
return AppleUtil.getString(block, 0xe0, 0x20);
} else {
/* Use the name of the OS (catalog entry zero) */
byte[] block = readSector(1, 0x0); byte[] block = readSector(1, 0x0);
return AppleUtil.getString(block, 0x0, 0x18); return AppleUtil.getString(block, 0x0, 0x18);
} }
byte[] block = readRdosBlock(4);
return AppleUtil.getString(block, 0xe0, 0x20);
} }
/** /**
@ -206,8 +222,8 @@ public class RdosFormatDisk extends FormattedDisk {
*/ */
public List<FileEntry> getFiles() { public List<FileEntry> getFiles() {
List<FileEntry> files = new ArrayList<>(); List<FileEntry> files = new ArrayList<>();
for (int b=13; b<23; b++) { for (int b=0; b<CATALOG_SECTORS; b++) {
byte[] data = readRdosBlock(b); byte[] data = readRdosBlock(b + SectorsPerTrack());
for (int i=0; i<data.length; i+= ENTRY_LENGTH) { for (int i=0; i<data.length; i+= ENTRY_LENGTH) {
byte[] entry = new byte[ENTRY_LENGTH]; byte[] entry = new byte[ENTRY_LENGTH];
System.arraycopy(data, i, entry, 0, entry.length); System.arraycopy(data, i, entry, 0, entry.length);
@ -250,17 +266,18 @@ public class RdosFormatDisk extends FormattedDisk {
* Identify the operating system format of this disk. * Identify the operating system format of this disk.
*/ */
public String getFormat() { public String getFormat() {
if (getImageOrder() instanceof ProdosOrder) { if (SectorsPerTrack() == 13) {
return textBundle.get("RdosFormatDisk.Rdos21"); //$NON-NLS-1$
} else {
return textBundle.get("RdosFormatDisk.Rdos33"); //$NON-NLS-1$ return textBundle.get("RdosFormatDisk.Rdos33"); //$NON-NLS-1$
} }
return textBundle.get("RdosFormatDisk.Rdos21"); //$NON-NLS-1$
} }
/** /**
* Return the number of free blocks. * Return the number of free blocks.
*/ */
public int getFreeBlocks() { public int getFreeBlocks() {
return BLOCKS_ON_DISK - getUsedBlocks(); return BlocksOnDisk() - getUsedBlocks();
} }
/** /**
@ -301,7 +318,7 @@ public class RdosFormatDisk extends FormattedDisk {
* Get the length of the bitmap. * Get the length of the bitmap.
*/ */
public int getBitmapLength() { public int getBitmapLength() {
return BLOCKS_ON_DISK; return BlocksOnDisk();
} }
/** /**
@ -323,7 +340,7 @@ public class RdosFormatDisk extends FormattedDisk {
*/ */
public List<DiskInformation> getDiskInformation() { public List<DiskInformation> getDiskInformation() {
List<DiskInformation> list = super.getDiskInformation(); List<DiskInformation> list = super.getDiskInformation();
list.add(new DiskInformation(textBundle.get("TotalBlocks"), BLOCKS_ON_DISK)); //$NON-NLS-1$ list.add(new DiskInformation(textBundle.get("TotalBlocks"), BlocksOnDisk())); //$NON-NLS-1$
list.add(new DiskInformation(textBundle.get("FreeBlocks"), getFreeBlocks())); //$NON-NLS-1$ list.add(new DiskInformation(textBundle.get("FreeBlocks"), getFreeBlocks())); //$NON-NLS-1$
list.add(new DiskInformation(textBundle.get("UsedBlocks"), getUsedBlocks())); //$NON-NLS-1$ list.add(new DiskInformation(textBundle.get("UsedBlocks"), getUsedBlocks())); //$NON-NLS-1$
return list; return list;
@ -418,12 +435,7 @@ public class RdosFormatDisk extends FormattedDisk {
byte[] fileData = new byte[rdosEntry.getSizeInBlocks() * SECTOR_SIZE]; byte[] fileData = new byte[rdosEntry.getSizeInBlocks() * SECTOR_SIZE];
int offset = 0; int offset = 0;
for (int blockOffset = 0; blockOffset < rdosEntry.getSizeInBlocks(); blockOffset++) { for (int blockOffset = 0; blockOffset < rdosEntry.getSizeInBlocks(); blockOffset++) {
byte[] blockData; byte[] blockData = readRdosBlock(startingBlock + blockOffset);
if (getImageOrder() instanceof ProdosOrder) {
blockData = readBlock(startingBlock + blockOffset);
} else {
blockData = readRdosBlock(startingBlock + blockOffset);
}
System.arraycopy(blockData, 0, fileData, offset, blockData.length); System.arraycopy(blockData, 0, fileData, offset, blockData.length);
offset+= blockData.length; offset+= blockData.length;
} }