mirror of
https://github.com/AppleCommander/AppleCommander.git
synced 2025-01-04 16:30:13 +00:00
Added ability to save and write. Added hasChanged, writeBytes,
writeSector along with other helper methods.
This commit is contained in:
parent
e16fce45c4
commit
669007afdc
@ -20,10 +20,14 @@
|
|||||||
package com.webcodepro.applecommander.storage;
|
package com.webcodepro.applecommander.storage;
|
||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
import java.util.zip.GZIPInputStream;
|
import java.util.zip.GZIPInputStream;
|
||||||
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract representation of an Apple2 disk (floppy, 800k, hard disk).
|
* Abstract representation of an Apple2 disk (floppy, 800k, hard disk).
|
||||||
@ -60,6 +64,7 @@ public class Disk {
|
|||||||
private static FilenameFilter[] filenameFilters;
|
private static FilenameFilter[] filenameFilters;
|
||||||
private byte[] diskImage;
|
private byte[] diskImage;
|
||||||
private String filename;
|
private String filename;
|
||||||
|
private boolean changed = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the supported file filters supported by the Disk interface.
|
* Get the supported file filters supported by the Disk interface.
|
||||||
@ -80,7 +85,7 @@ public class Disk {
|
|||||||
filenameFilters = new FilenameFilter[] {
|
filenameFilters = new FilenameFilter[] {
|
||||||
new FilenameFilter("All Emulator Images",
|
new FilenameFilter("All Emulator Images",
|
||||||
"*.do; *.dsk; *.po; *.2mg; *.2img; *.hdv; *.do.gz; *.dsk.gz; *.po.gz; *.2mg.gz; *.2img.gz"),
|
"*.do; *.dsk; *.po; *.2mg; *.2img; *.hdv; *.do.gz; *.dsk.gz; *.po.gz; *.2mg.gz; *.2img.gz"),
|
||||||
new FilenameFilter("140K DOS 3.3 Ordered Images (*.do, *.dsk)",
|
new FilenameFilter("140K DOS Ordered Images (*.do, *.dsk)",
|
||||||
"*.do; *.dsk; *.do.gz; *.dsk.gz"),
|
"*.do; *.dsk; *.do.gz; *.dsk.gz"),
|
||||||
new FilenameFilter("140K ProDOS Ordered Images (*.po)",
|
new FilenameFilter("140K ProDOS Ordered Images (*.po)",
|
||||||
"*.po; *.po.gz"),
|
"*.po; *.po.gz"),
|
||||||
@ -128,6 +133,23 @@ public class Disk {
|
|||||||
this.diskImage = diskImageByteArray.toByteArray();
|
this.diskImage = diskImageByteArray.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save a Disk image to its file.
|
||||||
|
*/
|
||||||
|
public void save() throws IOException {
|
||||||
|
File file = new File(getFilename());
|
||||||
|
if (!file.exists()) {
|
||||||
|
file.createNewFile();
|
||||||
|
}
|
||||||
|
OutputStream output = new FileOutputStream(file);
|
||||||
|
if (isCompressed()) {
|
||||||
|
output = new GZIPOutputStream(output);
|
||||||
|
}
|
||||||
|
output.write(getDiskImage());
|
||||||
|
output.close();
|
||||||
|
changed = false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine type of disk, and return the appropriate
|
* Determine type of disk, and return the appropriate
|
||||||
* FormattedDisk object. Returns null if none are
|
* FormattedDisk object. Returns null if none are
|
||||||
@ -159,10 +181,20 @@ public class Disk {
|
|||||||
*/
|
*/
|
||||||
public byte[] readBytes(int start, int length) {
|
public byte[] readBytes(int start, int length) {
|
||||||
byte[] buffer = new byte[length];
|
byte[] buffer = new byte[length];
|
||||||
System.arraycopy(diskImage, start + (is2ImgOrder() ? 0x40 : 0), buffer, 0, length);
|
System.arraycopy(diskImage, start + (is2ImgOrder() ? 0x40 : 0),
|
||||||
|
buffer, 0, length);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write data to the disk image.
|
||||||
|
*/
|
||||||
|
public void writeBytes(int start, byte[] bytes) {
|
||||||
|
changed = true;
|
||||||
|
System.arraycopy(bytes, 0, diskImage,
|
||||||
|
start + (is2ImgOrder() ? 0x40 : 0), bytes.length);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the filename.
|
* Returns the filename.
|
||||||
* @return String
|
* @return String
|
||||||
@ -249,21 +281,41 @@ public class Disk {
|
|||||||
/**
|
/**
|
||||||
* Retrieve the specified sector.
|
* Retrieve the specified sector.
|
||||||
*/
|
*/
|
||||||
public byte[] readSector(int track, int sector) {
|
public byte[] readSector(int track, int sector) throws IllegalArgumentException {
|
||||||
|
return readBytes(getOffset(track, sector), SECTOR_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the specified sector.
|
||||||
|
*/
|
||||||
|
public void writeSector(int track, int sector, byte[] bytes)
|
||||||
|
throws IllegalArgumentException {
|
||||||
|
writeBytes(getOffset(track, sector), bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the track and sector offset into the disk image.
|
||||||
|
* This takes into account what type of format is being dealt
|
||||||
|
* with.
|
||||||
|
*/
|
||||||
|
protected int getOffset(int track, int sector) throws IllegalArgumentException {
|
||||||
if ((track * 16 + sector) * SECTOR_SIZE > getPhysicalSize()) {
|
if ((track * 16 + sector) * SECTOR_SIZE > getPhysicalSize()) {
|
||||||
return null;
|
throw new IllegalArgumentException(
|
||||||
|
"The track (" + track + ") and sector (" + sector
|
||||||
|
+ ") do not match the disk image size.");
|
||||||
} else if (isProdosOrder()) {
|
} else if (isProdosOrder()) {
|
||||||
// what block a sector belongs to:
|
// what block a sector belongs to:
|
||||||
int[] blockInterleave = { 0, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 7 };
|
int[] blockInterleave = { 0, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0, 7 };
|
||||||
// where in that block a sector resides:
|
// where in that block a sector resides:
|
||||||
int[] blockOffsets = { 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1 };
|
int[] blockOffsets = { 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1 };
|
||||||
return readBytes(
|
return ((track * 8) + blockInterleave[sector]) * BLOCK_SIZE
|
||||||
((track * 8) + blockInterleave[sector]) * BLOCK_SIZE
|
+ blockOffsets[sector] * SECTOR_SIZE;
|
||||||
+ blockOffsets[sector] * SECTOR_SIZE, SECTOR_SIZE);
|
|
||||||
} else if (isDosOrder()) {
|
} else if (isDosOrder()) {
|
||||||
return readBytes((track * 16 + sector) * SECTOR_SIZE, SECTOR_SIZE);
|
return (track * 16 + sector) * SECTOR_SIZE;
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException(
|
||||||
|
"Unknown disk format.");
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -313,4 +365,12 @@ public class Disk {
|
|||||||
String id = AppleUtil.getString(block, 0xe0, 4);
|
String id = AppleUtil.getString(block, 0xe0, 4);
|
||||||
return "RDOS".equals(id);
|
return "RDOS".equals(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if the disk has changed. Triggered when data is
|
||||||
|
* written and cleared when data is saved.
|
||||||
|
*/
|
||||||
|
public boolean hasChanged() {
|
||||||
|
return changed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user