mirror of
https://github.com/AppleCommander/AppleCommander.git
synced 2026-01-22 17:16:11 +00:00
Improved the nibble recognition a bit. It can deduce simple protected DOS disks. (DOS file system does not, so 'dump' can be used to verify.)
This commit is contained in:
@@ -67,9 +67,9 @@ public class TrackSectorNibbleDevice implements TrackSectorDevice {
|
||||
TrackSectorDevice device = new TrackSectorNibbleDevice(trackReaderWriter,
|
||||
new Nibble62Disk525Codec(), sectorsPerTrack, DiskMarker.disk525sector16());
|
||||
int count = 0;
|
||||
for (int sector = 0; sector < sectorsPerTrack; sector++) {
|
||||
for (int track = 0; track < trackReaderWriter.getTracksOnDevice(); track++) {
|
||||
try {
|
||||
DataBuffer sectorData = device.readSector(0, sector);
|
||||
DataBuffer sectorData = device.readSector(track, sectorsPerTrack-1);
|
||||
if (sectorData.limit() == TrackSectorDevice.SECTOR_SIZE) {
|
||||
count++;
|
||||
}
|
||||
@@ -78,7 +78,7 @@ public class TrackSectorNibbleDevice implements TrackSectorDevice {
|
||||
}
|
||||
}
|
||||
if (count > 3) {
|
||||
// Just making certain we read more than sector 0
|
||||
// Just making certain we read more than track 0
|
||||
return Optional.of(device);
|
||||
}
|
||||
|
||||
@@ -87,9 +87,9 @@ public class TrackSectorNibbleDevice implements TrackSectorDevice {
|
||||
device = new TrackSectorNibbleDevice(trackReaderWriter,
|
||||
new Nibble53Disk525Codec(), sectorsPerTrack, DiskMarker.disk525sector13());
|
||||
count = 0;
|
||||
for (int sector = 0; sector < sectorsPerTrack; sector++) {
|
||||
for (int track = 0; track < trackReaderWriter.getTracksOnDevice(); track++) {
|
||||
try {
|
||||
DataBuffer sectorData = device.readSector(0, sector);
|
||||
DataBuffer sectorData = device.readSector(track, sectorsPerTrack-1);
|
||||
if (sectorData.limit() == TrackSectorDevice.SECTOR_SIZE) {
|
||||
count++;
|
||||
}
|
||||
|
||||
@@ -46,22 +46,23 @@ public class NibbleScanner {
|
||||
int successCount = 0;
|
||||
for (int track=0; track<tracksOnDevice; track++) {
|
||||
DataBuffer trackData = trackReaderWriter.readTrackData(track);
|
||||
final int trackLength = trackData.limit();
|
||||
// Generate a list of likely address prologs (that meet the expected 4&4 encodings and structure)
|
||||
Map<Integer, Set<Integer>> addressPrologs = findAddressPrologs(track, trackData);
|
||||
final int foundSectors = addressPrologs.values().stream().map(Collection::size).max(Integer::compareTo).orElseThrow();
|
||||
// Assumption: Track is "mostly" normal, so 5&3 or 6&2 along with expected 13- and 16-sector sizing:
|
||||
// (with the exception of track 0)
|
||||
// (except for track 0 since it's possibly a mix of "expected" prolog and protected prolog bytes)
|
||||
if (track != 0) {
|
||||
if (foundSectors != 13 && foundSectors != 16) {
|
||||
// Expecting 13 or 16 sector (just not track zero)
|
||||
// Expecting 13 or 16 sector (just not track zero) -- fill in a fake DiskMarker just for sanity
|
||||
diskMarkers[track] = foundSectors <= 13 ? DiskMarker.disk525sector13() : DiskMarker.disk525sector16();
|
||||
break;
|
||||
}
|
||||
if (sectorsOnTrack == 0 || sectorsOnTrack == foundSectors) {
|
||||
sectorsOnTrack = foundSectors;
|
||||
} else {
|
||||
// Expecting same sector count
|
||||
// Expecting same sector count -- fill in DiskMarker just for sanity
|
||||
successCount = 0;
|
||||
diskMarkers[track] = foundSectors == 13 ? DiskMarker.disk525sector13() : DiskMarker.disk525sector16();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -72,19 +73,19 @@ public class NibbleScanner {
|
||||
.findFirst().orElseThrow();
|
||||
// Scan from an address prolog, look for (self?) sync bytes, and then assume next 3 are data prolog
|
||||
int dataProlog = findDataProlog(addressProlog, trackData);
|
||||
// Save
|
||||
// Save (always, prevent easy NPE's in other code)
|
||||
final int addr1 = (addressProlog >> 16) & 0xff;
|
||||
final int addr2 = (addressProlog >> 8) & 0xff;
|
||||
final int addr3 = addressProlog & 0xff;
|
||||
final int data1 = (dataProlog >> 16) & 0xff;
|
||||
final int data2 = (dataProlog >> 8) & 0xff;
|
||||
final int data3 = dataProlog & 0xff;
|
||||
diskMarkers[track] = DiskMarker.build()
|
||||
.addressProlog(addr1, addr2, addr3).addressEpilog()
|
||||
.dataProlog(data1, data2, data3).dataEpilog()
|
||||
.get();
|
||||
// Only tally good ones
|
||||
if (dataProlog != 0) {
|
||||
final int addr1 = (addressProlog >> 16) & 0xff;
|
||||
final int addr2 = (addressProlog >> 8) & 0xff;
|
||||
final int addr3 = addressProlog & 0xff;
|
||||
final int data1 = (dataProlog >> 16) & 0xff;
|
||||
final int data2 = (dataProlog >> 8) & 0xff;
|
||||
final int data3 = dataProlog & 0xff;
|
||||
|
||||
diskMarkers[track] = DiskMarker.build()
|
||||
.addressProlog(addr1, addr2, addr3).addressEpilog()
|
||||
.dataProlog(data1, data2, data3).dataEpilog()
|
||||
.get();
|
||||
successCount++;
|
||||
}
|
||||
}
|
||||
@@ -106,7 +107,7 @@ public class NibbleScanner {
|
||||
Map<Integer, Set<Integer>> addressPrologs = new HashMap<>();
|
||||
final int headerLength = 14;
|
||||
final int trackLength = trackData.limit();
|
||||
for (int i = 0; i < trackLength + headerLength; i++) {
|
||||
for (int i = 5; i < trackLength + headerLength; i++) {
|
||||
int trk = decodeOddEven(trackData, i % trackLength);
|
||||
if (trk == track) {
|
||||
int sct = decodeOddEven(trackData, (i + 2) % trackLength);
|
||||
|
||||
@@ -32,8 +32,9 @@ public class NibbleUtil {
|
||||
* See page 3-12 in Beneath Apple DOS for more information.
|
||||
*/
|
||||
public static int decodeOddEven(DataBuffer rawData, int offset) {
|
||||
int b1 = rawData.getUnsignedByte(offset);
|
||||
int b2 = rawData.getUnsignedByte(offset+1);
|
||||
final int limit = rawData.limit();
|
||||
int b1 = rawData.getUnsignedByte(offset % limit);
|
||||
int b2 = rawData.getUnsignedByte((offset+1) % limit);
|
||||
return (b1 << 1 | 0x01) & b2;
|
||||
}
|
||||
|
||||
@@ -45,6 +46,8 @@ public class NibbleUtil {
|
||||
public static void encodeOddEven(DataBuffer data, int offset, int value) {
|
||||
int b1 = (value >> 1) | 0xaa;
|
||||
int b2 = value | 0xaa;
|
||||
data.putBytes(offset, b1, b2);
|
||||
final int limit = data.limit();
|
||||
data.putByte(offset % limit, b1);
|
||||
data.putByte((offset + 1) % limit, b2);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user