This commit is contained in:
Denis Molony 2016-12-03 19:20:01 +11:00
parent 2a29477e96
commit f0c1c538eb
4 changed files with 67 additions and 53 deletions

View File

@ -224,7 +224,7 @@ public class AppleDisk implements Disk
tracks = 35;
trackSize = 4096;
file = disk.file;
diskBuffer = disk.buffer;
diskBuffer = disk.diskBuffer;
sectorSize = 256;
sectors = 16;

View File

@ -7,7 +7,7 @@ import java.io.IOException;
public class NibDisk
{
private final Nibblizer nibbler = new Nibblizer ();
private final Nibblizer nibbler;
final File file;
int tracks;
@ -24,6 +24,8 @@ public class NibDisk
{
this.file = file;
byte[] trackBuffer = new byte[6656];
nibbler = new Nibblizer (file);
try
{
BufferedInputStream in = new BufferedInputStream (new FileInputStream (file));

View File

@ -1,11 +1,20 @@
package com.bytezone.diskbrowser.disk;
import java.io.File;
public class Nibblizer
{
static byte[] addressPrologue = { (byte) 0xD5, (byte) 0xAA, (byte) 0x96 };
static byte[] dataPrologue = { (byte) 0xD5, (byte) 0xAA, (byte) 0xAD };
static byte[] epilogue = { (byte) 0xDE, (byte) 0xAA, (byte) 0xEB };
private static int[][] interleave =
{ { 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15 },
{ 0, 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15 } };
private static final int DOS = 0;
private static final int PRODOS = 1;
private static byte[] writeTranslateTable =
{ (byte) 0x96, (byte) 0x97, (byte) 0x9A, (byte) 0x9B, (byte) 0x9D, (byte) 0x9E,
(byte) 0x9F, (byte) 0xA6, (byte) 0xA7, (byte) 0xAB, (byte) 0xAC, (byte) 0xAD,
@ -90,8 +99,12 @@ public class Nibblizer
private final byte[] encode1 = new byte[342];
private final byte[] encode2 = new byte[343];
public Nibblizer ()
private final File file;
public Nibblizer (File file)
{
this.file = file;
if (false) // test with the Beneath Apple Prodos example
{
byte[] testBuffer = decode6and2 (encode6and2 (xor), 0);
@ -104,12 +117,50 @@ public class Nibblizer
}
}
AddressField getAddressField (byte[] buffer, int offset)
public boolean processTrack (int trackNo, byte[] buffer, byte[] diskBuffer)
{
int ptr = 0;
while (buffer[ptr] == (byte) 0xEB)
{
System.out.printf ("%s overrun 0xEB offset %d in track %02X%n", file.getName (),
ptr, trackNo);
++ptr;
}
ptr += skipBytes (buffer, ptr, (byte) 0xFF); // gap1
while (ptr < buffer.length)
{
AddressField addressField = getAddressField (buffer, ptr);
if (!addressField.isValid ())
return false;
assert addressField.track == trackNo;
ptr += addressField.size ();
ptr += skipBytes (buffer, ptr, (byte) 0xFF); // gap2
DataField dataField = getDataField (buffer, ptr);
if (!dataField.isValid ())
return false;
int offset = addressField.track * 4096 + interleave[DOS][addressField.sector] * 256;
System.arraycopy (dataField.dataBuffer, 0, diskBuffer, offset, 256);
ptr += dataField.size ();
ptr += skipBytes (buffer, ptr, (byte) 0xFF); // gap3
}
return true;
}
private AddressField getAddressField (byte[] buffer, int offset)
{
return new AddressField (buffer, offset);
}
DataField getDataField (byte[] buffer, int offset)
private DataField getDataField (byte[] buffer, int offset)
{
return new DataField (buffer, offset);
}

View File

@ -5,8 +5,6 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import com.bytezone.diskbrowser.disk.Nibblizer.AddressField;
import com.bytezone.diskbrowser.disk.Nibblizer.DataField;
import com.bytezone.diskbrowser.utilities.HexFormatter;
/*
@ -43,27 +41,28 @@ public class V2dDisk
private static final int TRACK_LENGTH = 6304;
private final Nibblizer nibbler = new Nibblizer ();
private final Nibblizer nibbler;
final File file;
final int tracks;
final byte[] buffer = new byte[4096 * 35];
final byte[] diskBuffer = new byte[4096 * 35];
public V2dDisk (File file)
{
this.file = file;
int tracks = 0;
nibbler = new Nibblizer (file);
try
{
byte[] diskBuffer = new byte[10];
byte[] header = new byte[10];
BufferedInputStream in = new BufferedInputStream (new FileInputStream (file));
in.read (diskBuffer);
in.read (header);
int diskLength = HexFormatter.getLongBigEndian (diskBuffer, 0); // 4 bytes
String id = HexFormatter.getString (diskBuffer, 4, 4); // 4 bytes
tracks = HexFormatter.getShortBigEndian (diskBuffer, 8); // 2 bytes
int diskLength = HexFormatter.getLongBigEndian (header, 0); // 4 bytes
String id = HexFormatter.getString (header, 4, 4); // 4 bytes
tracks = HexFormatter.getShortBigEndian (header, 8); // 2 bytes
assert diskLength + 8 == file.length ();
assert "D5NI".equals (id);
@ -86,7 +85,7 @@ public class V2dDisk
int halfTrackNo = trackNumber % 4;
if (halfTrackNo == 0) // only process full tracks
processTrack (fullTrackNo, trackData, buffer);
nibbler.processTrack (fullTrackNo, trackData, diskBuffer);
else
System.out.printf ("%s skipping half track %02X / %02X%n", file.getName (),
fullTrackNo, halfTrackNo);
@ -101,42 +100,4 @@ public class V2dDisk
this.tracks = tracks;
}
private boolean processTrack (int trackNo, byte[] buffer, byte[] diskBuffer)
{
int ptr = 0;
while (buffer[ptr] == (byte) 0xEB)
{
System.out.printf ("%s overrun 0xEB offset %d in track %02X%n", file.getName (),
ptr, trackNo);
++ptr;
}
ptr += nibbler.skipBytes (buffer, ptr, (byte) 0xFF); // gap1
while (ptr < buffer.length)
{
AddressField addressField = nibbler.getAddressField (buffer, ptr);
if (!addressField.isValid ())
return false;
assert addressField.track == trackNo;
ptr += addressField.size ();
ptr += nibbler.skipBytes (buffer, ptr, (byte) 0xFF); // gap2
DataField dataField = nibbler.getDataField (buffer, ptr);
if (!dataField.isValid ())
return false;
int offset = addressField.track * 4096 + interleave[DOS][addressField.sector] * 256;
System.arraycopy (dataField.dataBuffer, 0, diskBuffer, offset, 256);
ptr += dataField.size ();
ptr += nibbler.skipBytes (buffer, ptr, (byte) 0xFF); // gap3
}
return true;
}
}