mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2024-11-25 16:34:00 +00:00
Woz 3.5" disks, display preferences
This commit is contained in:
parent
696393799a
commit
19386e5c8e
@ -556,7 +556,7 @@ public class ApplesoftBasicProgram extends BasicProgram
|
|||||||
this.length = length;
|
this.length = length;
|
||||||
|
|
||||||
byte b = buffer[startPtr];
|
byte b = buffer[startPtr];
|
||||||
if (isToken (b))
|
if (isHighBitSet (b))
|
||||||
{
|
{
|
||||||
switch (b)
|
switch (b)
|
||||||
{
|
{
|
||||||
@ -637,7 +637,7 @@ public class ApplesoftBasicProgram extends BasicProgram
|
|||||||
private boolean isImpliedGoto ()
|
private boolean isImpliedGoto ()
|
||||||
{
|
{
|
||||||
byte b = buffer[startPtr];
|
byte b = buffer[startPtr];
|
||||||
if (isToken (b))
|
if (isHighBitSet (b))
|
||||||
return false;
|
return false;
|
||||||
return (isDigit (b));
|
return (isDigit (b));
|
||||||
}
|
}
|
||||||
@ -677,7 +677,7 @@ public class ApplesoftBasicProgram extends BasicProgram
|
|||||||
{
|
{
|
||||||
// ignore first byte, check the rest for tokens
|
// ignore first byte, check the rest for tokens
|
||||||
for (int p = startPtr + 1, max = startPtr + length; p < max; p++)
|
for (int p = startPtr + 1, max = startPtr + length; p < max; p++)
|
||||||
if (isToken (buffer[p]))
|
if (isHighBitSet (buffer[p]))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -740,7 +740,7 @@ public class ApplesoftBasicProgram extends BasicProgram
|
|||||||
for (int p = startPtr; p <= max; p++)
|
for (int p = startPtr; p <= max; p++)
|
||||||
{
|
{
|
||||||
byte b = buffer[p];
|
byte b = buffer[p];
|
||||||
if (isToken (b))
|
if (isHighBitSet (b))
|
||||||
{
|
{
|
||||||
if (line.length () > 0 && line.charAt (line.length () - 1) != ' ')
|
if (line.length () > 0 && line.charAt (line.length () - 1) != ' ')
|
||||||
line.append (' ');
|
line.append (' ');
|
||||||
|
@ -9,13 +9,14 @@ import java.util.HashMap;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import com.bytezone.common.Utility;
|
|
||||||
import com.bytezone.diskbrowser.gui.AssemblerPreferences;
|
import com.bytezone.diskbrowser.gui.AssemblerPreferences;
|
||||||
import com.bytezone.diskbrowser.gui.DiskBrowser;
|
import com.bytezone.diskbrowser.gui.DiskBrowser;
|
||||||
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
||||||
|
|
||||||
public class AssemblerProgram extends AbstractFile
|
public class AssemblerProgram extends AbstractFile
|
||||||
{
|
{
|
||||||
|
static AssemblerPreferences assemblerPreferences; // set by MenuHandler
|
||||||
|
|
||||||
private static Map<Integer, String> equates;
|
private static Map<Integer, String> equates;
|
||||||
|
|
||||||
private final int loadAddress;
|
private final int loadAddress;
|
||||||
@ -26,8 +27,6 @@ public class AssemblerProgram extends AbstractFile
|
|||||||
private List<Integer> entryPoints;
|
private List<Integer> entryPoints;
|
||||||
private List<StringLocation> stringLocations;
|
private List<StringLocation> stringLocations;
|
||||||
|
|
||||||
static AssemblerPreferences assemblerPreferences;
|
|
||||||
|
|
||||||
public static void setAssemblerPreferences (AssemblerPreferences assemblerPreferences)
|
public static void setAssemblerPreferences (AssemblerPreferences assemblerPreferences)
|
||||||
{
|
{
|
||||||
AssemblerProgram.assemblerPreferences = assemblerPreferences;
|
AssemblerProgram.assemblerPreferences = assemblerPreferences;
|
||||||
@ -81,6 +80,7 @@ public class AssemblerProgram extends AbstractFile
|
|||||||
{
|
{
|
||||||
if (buffer == null)
|
if (buffer == null)
|
||||||
return "No buffer";
|
return "No buffer";
|
||||||
|
|
||||||
if (assembler == null)
|
if (assembler == null)
|
||||||
this.assembler = new AssemblerProgram (name, buffer, loadAddress);
|
this.assembler = new AssemblerProgram (name, buffer, loadAddress);
|
||||||
|
|
||||||
@ -94,19 +94,25 @@ public class AssemblerProgram extends AbstractFile
|
|||||||
return assembler.getText () + "\n\n" + assemblerProgram.getText ();
|
return assembler.getText () + "\n\n" + assemblerProgram.getText ();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void addHeader (StringBuilder pgm)
|
||||||
public String getText ()
|
|
||||||
{
|
{
|
||||||
StringBuilder pgm = new StringBuilder ();
|
|
||||||
|
|
||||||
pgm.append (String.format ("Name : %s%n", name));
|
pgm.append (String.format ("Name : %s%n", name));
|
||||||
pgm.append (String.format ("Length : $%04X (%,d)%n", buffer.length, buffer.length));
|
pgm.append (String.format ("Length : $%04X (%,d)%n", buffer.length, buffer.length));
|
||||||
pgm.append (String.format ("Load at : $%04X (%,d)%n", loadAddress, loadAddress));
|
pgm.append (String.format ("Load at : $%04X (%,d)%n", loadAddress, loadAddress));
|
||||||
|
|
||||||
if (executeOffset > 0)
|
if (executeOffset > 0)
|
||||||
pgm.append (String.format ("Entry : $%04X%n", (loadAddress + executeOffset)));
|
pgm.append (String.format ("Entry : $%04X%n", (loadAddress + executeOffset)));
|
||||||
|
|
||||||
pgm.append ("\n");
|
pgm.append ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getText ()
|
||||||
|
{
|
||||||
|
StringBuilder pgm = new StringBuilder ();
|
||||||
|
|
||||||
|
if (assemblerPreferences.showHeader)
|
||||||
|
addHeader (pgm);
|
||||||
|
|
||||||
pgm.append (getListing ());
|
pgm.append (getListing ());
|
||||||
|
|
||||||
if (assemblerPreferences.showStrings)
|
if (assemblerPreferences.showStrings)
|
||||||
@ -250,7 +256,7 @@ public class AssemblerProgram extends AbstractFile
|
|||||||
{
|
{
|
||||||
int address = stringLocation.offset + loadAddress;
|
int address = stringLocation.offset + loadAddress;
|
||||||
text.append (String.format ("%s %04X - %04X %s %n",
|
text.append (String.format ("%s %04X - %04X %s %n",
|
||||||
entryPoints.contains (stringLocation.offset + loadAddress) ? "*" : " ", address,
|
entryPoints.contains (stringLocation.offset) ? "*" : " ", address,
|
||||||
address + stringLocation.length, stringLocation));
|
address + stringLocation.length, stringLocation));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,19 +272,8 @@ public class AssemblerProgram extends AbstractFile
|
|||||||
stringLocations = new ArrayList<> ();
|
stringLocations = new ArrayList<> ();
|
||||||
|
|
||||||
int start = 0;
|
int start = 0;
|
||||||
int max = buffer.length - 2;
|
|
||||||
for (int ptr = 0; ptr < buffer.length; ptr++)
|
for (int ptr = 0; ptr < buffer.length; ptr++)
|
||||||
{
|
{
|
||||||
if ((buffer[ptr] == (byte) 0xBD // LDA Absolute,X
|
|
||||||
|| buffer[ptr] == (byte) 0xB9 // LDA Absolute,Y
|
|
||||||
|| buffer[ptr] == (byte) 0xAD) // LDA Absolute
|
|
||||||
&& (ptr < max))
|
|
||||||
{
|
|
||||||
int address = Utility.getWord (buffer, ptr + 1);
|
|
||||||
if (address >= loadAddress && address < loadAddress + buffer.length)
|
|
||||||
entryPoints.add (address);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((buffer[ptr] & 0x80) != 0) // hi bit set
|
if ((buffer[ptr] & 0x80) != 0) // hi bit set
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -290,6 +285,15 @@ public class AssemblerProgram extends AbstractFile
|
|||||||
|
|
||||||
if (buffer.length - start > 3)
|
if (buffer.length - start > 3)
|
||||||
stringLocations.add (new StringLocation (start, buffer.length - 1));
|
stringLocations.add (new StringLocation (start, buffer.length - 1));
|
||||||
|
|
||||||
|
int max = buffer.length - 2;
|
||||||
|
for (StringLocation stringLocation : stringLocations)
|
||||||
|
for (int ptr = 0; ptr < max; ptr++)
|
||||||
|
if (stringLocation.matches (buffer, ptr))
|
||||||
|
{
|
||||||
|
entryPoints.add (stringLocation.offset);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getArrow (AssemblerStatement cmd)
|
private String getArrow (AssemblerStatement cmd)
|
||||||
@ -350,6 +354,7 @@ public class AssemblerProgram extends AbstractFile
|
|||||||
class StringLocation
|
class StringLocation
|
||||||
{
|
{
|
||||||
int offset;
|
int offset;
|
||||||
|
byte hi, lo;
|
||||||
int length;
|
int length;
|
||||||
boolean zeroTerminated;
|
boolean zeroTerminated;
|
||||||
boolean lowTerminated;
|
boolean lowTerminated;
|
||||||
@ -364,12 +369,20 @@ public class AssemblerProgram extends AbstractFile
|
|||||||
{
|
{
|
||||||
offset = first;
|
offset = first;
|
||||||
length = last - offset + 1;
|
length = last - offset + 1;
|
||||||
|
|
||||||
int end = last + 1;
|
int end = last + 1;
|
||||||
|
|
||||||
zeroTerminated = end < buffer.length && buffer[end] == 0;
|
zeroTerminated = end < buffer.length && buffer[end] == 0;
|
||||||
lowTerminated = end < buffer.length && buffer[end] >= 32 && buffer[end] < 127;
|
lowTerminated = end < buffer.length && buffer[end] >= 32 && buffer[end] < 127;
|
||||||
hasLengthByte = first > 0 && (buffer[first] & 0xFF) == length;
|
|
||||||
|
if (first > 0 && (buffer[first] & 0xFF) == length + 1)
|
||||||
|
{
|
||||||
|
hasLengthByte = true;
|
||||||
|
--offset;
|
||||||
|
++length;
|
||||||
|
}
|
||||||
|
|
||||||
|
hi = (byte) ((offset + loadAddress) >>> 8);
|
||||||
|
lo = (byte) ((offset + loadAddress) & 0x00FF);
|
||||||
|
|
||||||
for (int i = offset; i < offset + length; i++)
|
for (int i = offset; i < offset + length; i++)
|
||||||
{
|
{
|
||||||
@ -389,11 +402,21 @@ public class AssemblerProgram extends AbstractFile
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boolean matches (byte[] buffer, int ptr)
|
||||||
|
{
|
||||||
|
return lo == buffer[ptr] && hi == buffer[ptr + 1];
|
||||||
|
}
|
||||||
|
|
||||||
boolean likelyString ()
|
boolean likelyString ()
|
||||||
{
|
{
|
||||||
return spaces > 0 || letters > punctuation;
|
return spaces > 0 || letters > punctuation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String address ()
|
||||||
|
{
|
||||||
|
return String.format ("%04X %02X %02X", offset, hi, lo);
|
||||||
|
}
|
||||||
|
|
||||||
public String toStatisticsString ()
|
public String toStatisticsString ()
|
||||||
{
|
{
|
||||||
return String.format ("%2d, %2d, %2d, %2d, %2d", digits, letters, punctuation,
|
return String.format ("%2d, %2d, %2d, %2d, %2d", digits, letters, punctuation,
|
||||||
|
@ -9,11 +9,11 @@ public abstract class BasicProgram extends AbstractFile
|
|||||||
static final byte ASCII_SEMI_COLON = 0x3B;
|
static final byte ASCII_SEMI_COLON = 0x3B;
|
||||||
static final byte ASCII_CARET = 0x5E;
|
static final byte ASCII_CARET = 0x5E;
|
||||||
|
|
||||||
static BasicPreferences basicPreferences;
|
static BasicPreferences basicPreferences; // set by MenuHandler
|
||||||
|
|
||||||
public static void setBasicPreferences (BasicPreferences basicPreferences)
|
public static void setBasicPreferences (BasicPreferences basicPreferences)
|
||||||
{
|
{
|
||||||
ApplesoftBasicProgram.basicPreferences = basicPreferences;
|
BasicProgram.basicPreferences = basicPreferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BasicProgram (String name, byte[] buffer)
|
public BasicProgram (String name, byte[] buffer)
|
||||||
@ -21,14 +21,15 @@ public abstract class BasicProgram extends AbstractFile
|
|||||||
super (name, buffer);
|
super (name, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isToken (byte value)
|
boolean isHighBitSet (byte value)
|
||||||
{
|
{
|
||||||
return (value & 0x80) != 0;
|
return (value & 0x80) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isControlCharacter (byte value)
|
boolean isControlCharacter (byte value)
|
||||||
{
|
{
|
||||||
return (value & 0xFF) < 32;
|
int val = value & 0xFF;
|
||||||
|
return val > 0 && val < 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isDigit (byte value)
|
boolean isDigit (byte value)
|
||||||
|
@ -136,7 +136,7 @@ public class BasicProgramGS extends BasicProgram
|
|||||||
while (ptr < max)
|
while (ptr < max)
|
||||||
{
|
{
|
||||||
byte b1 = buffer[ptr++];
|
byte b1 = buffer[ptr++];
|
||||||
if (isToken (b1))
|
if (isHighBitSet (b1))
|
||||||
ptr = tokenOrNumber (b1, text, ptr);
|
ptr = tokenOrNumber (b1, text, ptr);
|
||||||
else
|
else
|
||||||
text.append ((b1 & 0xFF) < 32 ? '.' : (char) b1);
|
text.append ((b1 & 0xFF) < 32 ? '.' : (char) b1);
|
||||||
|
@ -10,6 +10,7 @@ public class BootSector extends AbstractSector
|
|||||||
private static final byte[] skew = { 0x00, 0x0D, 0x0B, 0x09, 0x07, 0x05, 0x03, 0x01,
|
private static final byte[] skew = { 0x00, 0x0D, 0x0B, 0x09, 0x07, 0x05, 0x03, 0x01,
|
||||||
0x0E, 0x0C, 0x0A, 0x08, 0x06, 0x04, 0x02, 0x0F };
|
0x0E, 0x0C, 0x0A, 0x08, 0x06, 0x04, 0x02, 0x0F };
|
||||||
private static final int SKEW_OFFSET = 0x4D;
|
private static final int SKEW_OFFSET = 0x4D;
|
||||||
|
private static final int SKEW_OFFSET_2 = 0x3C; // DOS 4.x
|
||||||
|
|
||||||
AssemblerProgram assembler1;
|
AssemblerProgram assembler1;
|
||||||
AssemblerProgram assembler2;
|
AssemblerProgram assembler2;
|
||||||
@ -34,7 +35,7 @@ public class BootSector extends AbstractSector
|
|||||||
|
|
||||||
if (assembler1 == null)
|
if (assembler1 == null)
|
||||||
{
|
{
|
||||||
int flag = buffer[0] & 0xFF;
|
int flag = buffer[0] & 0xFF; // how many blocks to load
|
||||||
if (flag == 1) // apple II
|
if (flag == 1) // apple II
|
||||||
{
|
{
|
||||||
if (matches (buffer, SKEW_OFFSET, skew))
|
if (matches (buffer, SKEW_OFFSET, skew))
|
||||||
@ -53,8 +54,8 @@ public class BootSector extends AbstractSector
|
|||||||
}
|
}
|
||||||
else // apple III (SOS)
|
else // apple III (SOS)
|
||||||
{
|
{
|
||||||
byte[] newBuffer = new byte[buffer.length * 2];
|
// byte[] newBuffer = new byte[buffer.length * 2];
|
||||||
System.arraycopy (buffer, 0, newBuffer, 0, buffer.length);
|
// System.arraycopy (buffer, 0, newBuffer, 0, buffer.length);
|
||||||
|
|
||||||
// byte[] buf = disk.readSector (1);
|
// byte[] buf = disk.readSector (1);
|
||||||
// System.arraycopy (buf, 0, newBuffer, buf.length, buf.length);
|
// System.arraycopy (buf, 0, newBuffer, buf.length, buf.length);
|
||||||
@ -66,6 +67,7 @@ public class BootSector extends AbstractSector
|
|||||||
}
|
}
|
||||||
|
|
||||||
text.append (assembler1.getText ());
|
text.append (assembler1.getText ());
|
||||||
|
|
||||||
if (assembler2 != null)
|
if (assembler2 != null)
|
||||||
{
|
{
|
||||||
text.append ("\n\n");
|
text.append ("\n\n");
|
||||||
|
@ -247,13 +247,30 @@ public class DiskFactory
|
|||||||
|
|
||||||
if (wozFile.getSectorsPerTrack () == 16)
|
if (wozFile.getSectorsPerTrack () == 16)
|
||||||
{
|
{
|
||||||
AppleDisk appleDisk256 = new AppleDisk (wozFile, wozFile.getTracks (), 16);
|
if (wozFile.getDiskType () == 2)
|
||||||
disk = checkDos (appleDisk256);
|
{
|
||||||
if (disk == null)
|
if (debug)
|
||||||
disk = checkProdos (new AppleDisk (wozFile, 35, 8));
|
System.out.println ("Checking woz 3.5");
|
||||||
if (disk == null)
|
AppleDisk disk800 = new AppleDisk (wozFile, 200, 8);
|
||||||
disk = new DataDisk (appleDisk256);
|
if (ProdosDisk.isCorrectFormat (disk800))
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
System.out.println (" --> PRODOS hard disk");
|
||||||
|
return new ProdosDisk (disk800);
|
||||||
|
}
|
||||||
|
disk = new DataDisk (disk800);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AppleDisk appleDisk256 = new AppleDisk (wozFile, wozFile.getTracks (), 16);
|
||||||
|
disk = checkDos (appleDisk256);
|
||||||
|
if (disk == null)
|
||||||
|
disk = checkProdos (new AppleDisk (wozFile, 35, 8));
|
||||||
|
if (disk == null)
|
||||||
|
disk = new DataDisk (appleDisk256);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return disk;
|
return disk;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -5,6 +5,7 @@ public class AssemblerPreferences
|
|||||||
public boolean showTargets = true;
|
public boolean showTargets = true;
|
||||||
public boolean showStrings = true;
|
public boolean showStrings = true;
|
||||||
public boolean offsetFromZero = false;
|
public boolean offsetFromZero = false;
|
||||||
|
public boolean showHeader = true;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString ()
|
public String toString ()
|
||||||
@ -14,6 +15,7 @@ public class AssemblerPreferences
|
|||||||
text.append (String.format ("Show targets .......... %s%n", showTargets));
|
text.append (String.format ("Show targets .......... %s%n", showTargets));
|
||||||
text.append (String.format ("Show strings .......... %s%n", showStrings));
|
text.append (String.format ("Show strings .......... %s%n", showStrings));
|
||||||
text.append (String.format ("Offset from zero ...... %s%n", offsetFromZero));
|
text.append (String.format ("Offset from zero ...... %s%n", offsetFromZero));
|
||||||
|
text.append (String.format ("Show header ........... %s%n", showHeader));
|
||||||
|
|
||||||
return text.toString ();
|
return text.toString ();
|
||||||
}
|
}
|
||||||
|
@ -35,6 +35,7 @@ public class MenuHandler
|
|||||||
|
|
||||||
private static final String PREFS_SHOW_ASSEMBLER_TARGETS = "showAssemblerTargets";
|
private static final String PREFS_SHOW_ASSEMBLER_TARGETS = "showAssemblerTargets";
|
||||||
private static final String PREFS_SHOW_ASSEMBLER_STRINGS = "showAssemblerStrings";
|
private static final String PREFS_SHOW_ASSEMBLER_STRINGS = "showAssemblerStrings";
|
||||||
|
private static final String PREFS_SHOW_ASSEMBLER_HEADER = "showAssemblerHeader";
|
||||||
|
|
||||||
// private static final String PREFS_DEBUGGING = "debugging";
|
// private static final String PREFS_DEBUGGING = "debugging";
|
||||||
private static final String PREFS_PALETTE = "palette";
|
private static final String PREFS_PALETTE = "palette";
|
||||||
@ -99,6 +100,7 @@ public class MenuHandler
|
|||||||
// Assembler menu items
|
// Assembler menu items
|
||||||
final JMenuItem showAssemblerTargetsItem = new JCheckBoxMenuItem ("Show targets");
|
final JMenuItem showAssemblerTargetsItem = new JCheckBoxMenuItem ("Show targets");
|
||||||
final JMenuItem showAssemblerStringsItem = new JCheckBoxMenuItem ("Show strings");
|
final JMenuItem showAssemblerStringsItem = new JCheckBoxMenuItem ("Show strings");
|
||||||
|
final JMenuItem showAssemblerHeaderItem = new JCheckBoxMenuItem ("Show header");
|
||||||
|
|
||||||
ButtonGroup paletteGroup = new ButtonGroup ();
|
ButtonGroup paletteGroup = new ButtonGroup ();
|
||||||
|
|
||||||
@ -174,6 +176,7 @@ public class MenuHandler
|
|||||||
|
|
||||||
assemblerMenu.add (showAssemblerTargetsItem);
|
assemblerMenu.add (showAssemblerTargetsItem);
|
||||||
assemblerMenu.add (showAssemblerStringsItem);
|
assemblerMenu.add (showAssemblerStringsItem);
|
||||||
|
assemblerMenu.add (showAssemblerHeaderItem);
|
||||||
|
|
||||||
ActionListener basicPreferencesAction = new ActionListener ()
|
ActionListener basicPreferencesAction = new ActionListener ()
|
||||||
{
|
{
|
||||||
@ -204,6 +207,7 @@ public class MenuHandler
|
|||||||
|
|
||||||
showAssemblerTargetsItem.addActionListener (assemblerPreferencesAction);
|
showAssemblerTargetsItem.addActionListener (assemblerPreferencesAction);
|
||||||
showAssemblerStringsItem.addActionListener (assemblerPreferencesAction);
|
showAssemblerStringsItem.addActionListener (assemblerPreferencesAction);
|
||||||
|
showAssemblerHeaderItem.addActionListener (assemblerPreferencesAction);
|
||||||
|
|
||||||
helpMenu.add (new JMenuItem (new EnvironmentAction ()));
|
helpMenu.add (new JMenuItem (new EnvironmentAction ()));
|
||||||
|
|
||||||
@ -255,6 +259,7 @@ public class MenuHandler
|
|||||||
{
|
{
|
||||||
assemblerPreferences.showTargets = showAssemblerTargetsItem.isSelected ();
|
assemblerPreferences.showTargets = showAssemblerTargetsItem.isSelected ();
|
||||||
assemblerPreferences.showStrings = showAssemblerStringsItem.isSelected ();
|
assemblerPreferences.showStrings = showAssemblerStringsItem.isSelected ();
|
||||||
|
assemblerPreferences.showHeader = showAssemblerHeaderItem.isSelected ();
|
||||||
AssemblerProgram.setAssemblerPreferences (assemblerPreferences);
|
AssemblerProgram.setAssemblerPreferences (assemblerPreferences);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,6 +328,7 @@ public class MenuHandler
|
|||||||
showAssemblerTargetsItem.isSelected ());
|
showAssemblerTargetsItem.isSelected ());
|
||||||
prefs.putBoolean (PREFS_SHOW_ASSEMBLER_STRINGS,
|
prefs.putBoolean (PREFS_SHOW_ASSEMBLER_STRINGS,
|
||||||
showAssemblerStringsItem.isSelected ());
|
showAssemblerStringsItem.isSelected ());
|
||||||
|
prefs.putBoolean (PREFS_SHOW_ASSEMBLER_HEADER, showAssemblerHeaderItem.isSelected ());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -334,6 +340,7 @@ public class MenuHandler
|
|||||||
showFreeSectorsItem.setSelected (prefs.getBoolean (PREFS_SHOW_FREE_SECTORS, false));
|
showFreeSectorsItem.setSelected (prefs.getBoolean (PREFS_SHOW_FREE_SECTORS, false));
|
||||||
colourQuirksItem.setSelected (prefs.getBoolean (PREFS_COLOUR_QUIRKS, false));
|
colourQuirksItem.setSelected (prefs.getBoolean (PREFS_COLOUR_QUIRKS, false));
|
||||||
monochromeItem.setSelected (prefs.getBoolean (PREFS_MONOCHROME, false));
|
monochromeItem.setSelected (prefs.getBoolean (PREFS_MONOCHROME, false));
|
||||||
|
|
||||||
// debuggingItem.setSelected (prefs.getBoolean (PREFS_DEBUGGING, false));
|
// debuggingItem.setSelected (prefs.getBoolean (PREFS_DEBUGGING, false));
|
||||||
|
|
||||||
splitRemarkItem.setSelected (prefs.getBoolean (PREFS_SPLIT_REMARKS, false));
|
splitRemarkItem.setSelected (prefs.getBoolean (PREFS_SPLIT_REMARKS, false));
|
||||||
@ -348,6 +355,8 @@ public class MenuHandler
|
|||||||
.setSelected (prefs.getBoolean (PREFS_SHOW_ASSEMBLER_TARGETS, true));
|
.setSelected (prefs.getBoolean (PREFS_SHOW_ASSEMBLER_TARGETS, true));
|
||||||
showAssemblerStringsItem
|
showAssemblerStringsItem
|
||||||
.setSelected (prefs.getBoolean (PREFS_SHOW_ASSEMBLER_STRINGS, true));
|
.setSelected (prefs.getBoolean (PREFS_SHOW_ASSEMBLER_STRINGS, true));
|
||||||
|
showAssemblerHeaderItem
|
||||||
|
.setSelected (prefs.getBoolean (PREFS_SHOW_ASSEMBLER_HEADER, true));
|
||||||
|
|
||||||
setBasicPreferences ();
|
setBasicPreferences ();
|
||||||
setAssemblerPreferences ();
|
setAssemblerPreferences ();
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
package com.bytezone.diskbrowser.nib;
|
package com.bytezone.diskbrowser.nib;
|
||||||
|
|
||||||
public interface ByteTranslator
|
// -----------------------------------------------------------------------------------//
|
||||||
|
interface ByteTranslator
|
||||||
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
abstract byte encode (byte b);
|
abstract byte encode (byte b);
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
abstract byte decode (byte b) throws DiskNibbleException;
|
abstract byte decode (byte b) throws DiskNibbleException;
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package com.bytezone.diskbrowser.nib;
|
package com.bytezone.diskbrowser.nib;
|
||||||
|
|
||||||
public class ByteTranslator5and3 implements ByteTranslator
|
// -----------------------------------------------------------------------------------//
|
||||||
|
class ByteTranslator5and3 implements ByteTranslator
|
||||||
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
// 32 valid bytes that can be stored on a disk (plus 0xAA and 0xD5)
|
// 32 valid bytes that can be stored on a disk (plus 0xAA and 0xD5)
|
||||||
private static byte[] writeTranslateTable5and3 =
|
private static byte[] writeTranslateTable5and3 =
|
||||||
@ -11,14 +13,16 @@ public class ByteTranslator5and3 implements ByteTranslator
|
|||||||
(byte) 0xEE, (byte) 0xEF, (byte) 0xF5, (byte) 0xF6, (byte) 0xF7, (byte) 0xFA,
|
(byte) 0xEE, (byte) 0xEF, (byte) 0xF5, (byte) 0xF6, (byte) 0xF7, (byte) 0xFA,
|
||||||
(byte) 0xFB, (byte) 0xFD, (byte) 0xFE, (byte) 0xFF };
|
(byte) 0xFB, (byte) 0xFD, (byte) 0xFE, (byte) 0xFF };
|
||||||
|
|
||||||
private static byte[] readTranslateTable5and3 = new byte[85]; // skip first 171 blanks
|
private static final int SKIP = 0xAB;
|
||||||
|
private static byte[] readTranslateTable5and3 = new byte[256 - SKIP];
|
||||||
|
|
||||||
private static boolean debug = false;
|
private static boolean debug = false;
|
||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
for (int i = 0; i < writeTranslateTable5and3.length; i++)
|
for (int i = 0; i < writeTranslateTable5and3.length; i++)
|
||||||
{
|
{
|
||||||
int j = (writeTranslateTable5and3[i] & 0xFF) - 0xAB; // skip first 171 blanks
|
int j = (writeTranslateTable5and3[i] & 0xFF) - SKIP; // skip first 171 blanks
|
||||||
readTranslateTable5and3[j] = (byte) (i + 1); // offset by 1 to avoid zero
|
readTranslateTable5and3[j] = (byte) (i + 1); // offset by 1 to avoid zero
|
||||||
if (debug)
|
if (debug)
|
||||||
System.out.printf ("%02X %02X %02X%n", i, writeTranslateTable5and3[i], j);
|
System.out.printf ("%02X %02X %02X%n", i, writeTranslateTable5and3[i], j);
|
||||||
@ -38,24 +42,20 @@ public class ByteTranslator5and3 implements ByteTranslator
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
// encode
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte encode (byte b)
|
public byte encode (byte b)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
System.out.println ("encode() not written");
|
System.out.println ("encode() not written");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
// decode
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte decode (byte b) throws DiskNibbleException
|
public byte decode (byte b) throws DiskNibbleException
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
int val = (b & 0xFF) - 0xAB; // 0 - 84
|
int val = (b & 0xFF) - SKIP; // 0 - 84
|
||||||
if (val < 0 || val > 84)
|
if (val < 0 || val > 84)
|
||||||
throw new DiskNibbleException ("5&3 val: " + val);
|
throw new DiskNibbleException ("5&3 val: " + val);
|
||||||
byte trans = (byte) (readTranslateTable5and3[val] - 1); // 0 - 31 (5 bits)
|
byte trans = (byte) (readTranslateTable5and3[val] - 1); // 0 - 31 (5 bits)
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
package com.bytezone.diskbrowser.nib;
|
package com.bytezone.diskbrowser.nib;
|
||||||
|
|
||||||
public class ByteTranslator6and2 implements ByteTranslator
|
// -----------------------------------------------------------------------------------//
|
||||||
|
class ByteTranslator6and2 implements ByteTranslator
|
||||||
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
// 64 valid bytes that can be stored on a disk (plus 0xAA and 0xD5)
|
// 64 valid bytes that can be stored on a disk (plus 0xAA and 0xD5)
|
||||||
private static byte[] writeTranslateTable6and2 =
|
private static byte[] writeTranslateTable6and2 =
|
||||||
@ -17,35 +19,36 @@ public class ByteTranslator6and2 implements ByteTranslator
|
|||||||
(byte) 0xF5, (byte) 0xF6, (byte) 0xF7, (byte) 0xF9, (byte) 0xFA, (byte) 0xFB,
|
(byte) 0xF5, (byte) 0xF6, (byte) 0xF7, (byte) 0xF9, (byte) 0xFA, (byte) 0xFB,
|
||||||
(byte) 0xFC, (byte) 0xFD, (byte) 0xFE, (byte) 0xFF };
|
(byte) 0xFC, (byte) 0xFD, (byte) 0xFE, (byte) 0xFF };
|
||||||
|
|
||||||
private static byte[] readTranslateTable6and2 = new byte[106]; // skip first 150 blanks
|
private static final int SKIP = 0x96;
|
||||||
|
private static byte[] readTranslateTable6and2 = new byte[256 - SKIP];
|
||||||
|
|
||||||
static
|
static
|
||||||
{
|
{
|
||||||
for (int i = 0; i < writeTranslateTable6and2.length; i++)
|
for (int i = 0; i < writeTranslateTable6and2.length; i++)
|
||||||
{
|
{
|
||||||
int j = (writeTranslateTable6and2[i] & 0xFF) - 0x96; // skip first 150 blanks
|
int j = (writeTranslateTable6and2[i] & 0xFF) - SKIP; // skip first 150 blanks
|
||||||
readTranslateTable6and2[j] = (byte) (i + 1); // offset by 1 to avoid zero
|
readTranslateTable6and2[j] = (byte) (i + 1); // offset by 1 to avoid zero
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (false)
|
||||||
|
for (int i = 0; i < readTranslateTable6and2.length; i++)
|
||||||
|
System.out.printf ("%02X %02X%n", i + SKIP, readTranslateTable6and2[i] - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
// encode
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte encode (byte b)
|
public byte encode (byte b)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
return writeTranslateTable6and2[(b & 0xFC)];
|
return writeTranslateTable6and2[(b & 0xFC)];
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
// decode
|
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte decode (byte b) throws DiskNibbleException
|
public byte decode (byte b) throws DiskNibbleException
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
int val = (b & 0xFF) - 0x96; // 0 - 105
|
int val = (b & 0xFF) - SKIP; // 0 - 105
|
||||||
if (val < 0 || val > 105)
|
if (val < 0 || val > 105)
|
||||||
throw new DiskNibbleException ("6&2 val: " + val);
|
throw new DiskNibbleException ("6&2 val: " + val);
|
||||||
byte trans = (byte) (readTranslateTable6and2[val] - 1); // 0 - 63 (6 bits)
|
byte trans = (byte) (readTranslateTable6and2[val] - 1); // 0 - 63 (6 bits)
|
||||||
|
@ -1,16 +1,22 @@
|
|||||||
package com.bytezone.diskbrowser.nib;
|
package com.bytezone.diskbrowser.nib;
|
||||||
|
|
||||||
public class DiskNibbleException extends Exception
|
// -----------------------------------------------------------------------------------//
|
||||||
|
class DiskNibbleException extends Exception
|
||||||
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
String message;
|
String message;
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
public DiskNibbleException (String message)
|
public DiskNibbleException (String message)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
this.message = message;
|
this.message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
@Override
|
@Override
|
||||||
public String toString ()
|
public String toString ()
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,15 @@
|
|||||||
package com.bytezone.diskbrowser.nib;
|
package com.bytezone.diskbrowser.nib;
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
public abstract class DiskReader
|
abstract class DiskReader
|
||||||
// ---------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
static final int BLOCK_SIZE = 256;
|
static final int BLOCK_SIZE = 256;
|
||||||
static final byte[] dataPrologue = { (byte) 0xD5, (byte) 0xAA, (byte) 0xAD };
|
static final byte[] dataPrologue = { (byte) 0xD5, (byte) 0xAA, (byte) 0xAD };
|
||||||
|
|
||||||
static DiskReader reader13;
|
static DiskReader reader13;
|
||||||
static DiskReader reader16;
|
static DiskReader reader16;
|
||||||
|
static DiskReader readerGRC;
|
||||||
|
|
||||||
final int sectorsPerTrack;
|
final int sectorsPerTrack;
|
||||||
|
|
||||||
@ -23,21 +24,26 @@ public abstract class DiskReader
|
|||||||
static DiskReader getInstance (int sectors)
|
static DiskReader getInstance (int sectors)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
if (sectors == 13)
|
switch (sectors)
|
||||||
{
|
{
|
||||||
if (reader13 == null)
|
case 13:
|
||||||
reader13 = new DiskReader13Sector ();
|
if (reader13 == null)
|
||||||
return reader13;
|
reader13 = new DiskReader13Sector ();
|
||||||
}
|
return reader13;
|
||||||
|
|
||||||
if (sectors == 16)
|
case 16:
|
||||||
{
|
if (reader16 == null)
|
||||||
if (reader16 == null)
|
reader16 = new DiskReader16Sector ();
|
||||||
reader16 = new DiskReader16Sector ();
|
return reader16;
|
||||||
return reader16;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
case 0:
|
||||||
|
if (readerGRC == null)
|
||||||
|
readerGRC = new DiskReaderGRC ();
|
||||||
|
return readerGRC;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -55,7 +61,5 @@ public abstract class DiskReader
|
|||||||
|
|
||||||
abstract byte[] encodeSector (byte[] buffer);
|
abstract byte[] encodeSector (byte[] buffer);
|
||||||
|
|
||||||
// abstract void storeBuffer (RawDiskSector diskSector, byte[] diskBuffer);
|
|
||||||
|
|
||||||
abstract int expectedDataSize ();
|
abstract int expectedDataSize ();
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.bytezone.diskbrowser.nib;
|
package com.bytezone.diskbrowser.nib;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
public class DiskReader13Sector extends DiskReader
|
class DiskReader13Sector extends DiskReader
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private static final int RAW_BUFFER_SIZE = 410;
|
private static final int RAW_BUFFER_SIZE = 410;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package com.bytezone.diskbrowser.nib;
|
package com.bytezone.diskbrowser.nib;
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
public class DiskReader16Sector extends DiskReader
|
class DiskReader16Sector extends DiskReader
|
||||||
// -----------------------------------------------------------------------------------//
|
// -----------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private static final int RAW_BUFFER_SIZE = 342;
|
private static final int RAW_BUFFER_SIZE = 342;
|
||||||
|
99
src/com/bytezone/diskbrowser/nib/DiskReaderGRC.java
Normal file
99
src/com/bytezone/diskbrowser/nib/DiskReaderGRC.java
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
package com.bytezone.diskbrowser.nib;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------------//
|
||||||
|
public class DiskReaderGRC extends DiskReader
|
||||||
|
// -----------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
private final ByteTranslator byteTranslator = new ByteTranslator6and2 ();
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
DiskReaderGRC ()
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
super (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@Override
|
||||||
|
byte[] decodeSector (byte[] buffer, int ptr) throws DiskNibbleException
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
byte[] outBuffer = new byte[BLOCK_SIZE * 2 + 12]; // 524 bytes
|
||||||
|
int outPtr = 0;
|
||||||
|
|
||||||
|
int[] checksums = new int[3];
|
||||||
|
|
||||||
|
for (int j = 0; j < 175; j++)
|
||||||
|
{
|
||||||
|
checksums[0] = (checksums[0] & 0xFF) << 1; // ROL
|
||||||
|
if ((checksums[0] > 0xFF))
|
||||||
|
++checksums[0];
|
||||||
|
|
||||||
|
byte d3 = byteTranslator.decode (buffer[ptr++]); // composite byte
|
||||||
|
byte d0 = byteTranslator.decode (buffer[ptr++]);
|
||||||
|
byte d1 = byteTranslator.decode (buffer[ptr++]);
|
||||||
|
|
||||||
|
byte b0 = (byte) ((d0 & 0x3F) | ((d3 & 0x30) << 2));
|
||||||
|
byte b1 = (byte) ((d1 & 0x3F) | ((d3 & 0x0C) << 4));
|
||||||
|
|
||||||
|
outBuffer[outPtr++] = checksum (b0, checksums, 0, 2);
|
||||||
|
outBuffer[outPtr++] = checksum (b1, checksums, 2, 1);
|
||||||
|
|
||||||
|
if (j < 174)
|
||||||
|
{
|
||||||
|
byte d2 = byteTranslator.decode (buffer[ptr++]);
|
||||||
|
byte b2 = (byte) ((d2 & 0x3F) | ((d3 & 0x03) << 6));
|
||||||
|
outBuffer[outPtr++] = checksum (b2, checksums, 1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
byte d3 = byteTranslator.decode (buffer[ptr++]); // composite byte
|
||||||
|
byte d0 = byteTranslator.decode (buffer[ptr++]);
|
||||||
|
byte d1 = byteTranslator.decode (buffer[ptr++]);
|
||||||
|
byte d2 = byteTranslator.decode (buffer[ptr++]);
|
||||||
|
|
||||||
|
byte b0 = (byte) ((d0 & 0x3F) | ((d3 & 0x30) << 2));
|
||||||
|
byte b1 = (byte) ((d1 & 0x3F) | ((d3 & 0x0C) << 4));
|
||||||
|
byte b2 = (byte) ((d2 & 0x3F) | ((d3 & 0x03) << 6));
|
||||||
|
|
||||||
|
if ((checksums[0] & 0xFF) != (b2 & 0xFF) //
|
||||||
|
|| (checksums[1] & 0xFF) != (b1 & 0xFF) //
|
||||||
|
|| (checksums[2] & 0xFF) != (b0 & 0xFF))
|
||||||
|
throw new DiskNibbleException ("Checksum failed");
|
||||||
|
|
||||||
|
return outBuffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
private byte checksum (byte b, int[] checksums, int c1, int c2)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
int val = (b ^ checksums[c1]) & 0xFF;
|
||||||
|
checksums[c2] += val;
|
||||||
|
|
||||||
|
if (checksums[c1] > 0xFF)
|
||||||
|
{
|
||||||
|
++checksums[c2];
|
||||||
|
checksums[c1] &= 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (byte) val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@Override
|
||||||
|
byte[] encodeSector (byte[] buffer)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@Override
|
||||||
|
int expectedDataSize ()
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
assert false;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ import java.io.File;
|
|||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -44,6 +45,8 @@ public class WozFile
|
|||||||
private final boolean debug1 = false;
|
private final boolean debug1 = false;
|
||||||
private final boolean showTracks = false;
|
private final boolean showTracks = false;
|
||||||
|
|
||||||
|
private final ByteTranslator6and2 byteTranslator6and2 = new ByteTranslator6and2 ();
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public WozFile (File file) throws DiskNibbleException
|
public WozFile (File file) throws DiskNibbleException
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -101,7 +104,23 @@ public class WozFile
|
|||||||
diskBuffer = new byte[tracks.size () * diskSectors * SECTOR_SIZE];
|
diskBuffer = new byte[tracks.size () * diskSectors * SECTOR_SIZE];
|
||||||
|
|
||||||
for (Track track : tracks)
|
for (Track track : tracks)
|
||||||
track.pack (diskBuffer);
|
track.packType1 (diskBuffer);
|
||||||
|
}
|
||||||
|
else if (info.diskType == 2) // 3.5"
|
||||||
|
{
|
||||||
|
List<Sector> sectors = new ArrayList<> ();
|
||||||
|
for (Track track : tracks)
|
||||||
|
sectors.addAll (track.sectors);
|
||||||
|
Collections.sort (sectors);
|
||||||
|
|
||||||
|
diskBuffer = new byte[800 * info.sides * SECTOR_SIZE * 2];
|
||||||
|
ptr = 0;
|
||||||
|
|
||||||
|
for (Sector sector : sectors)
|
||||||
|
{
|
||||||
|
sector.pack (diskBuffer, ptr);
|
||||||
|
ptr += 512;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,6 +131,13 @@ public class WozFile
|
|||||||
return diskBuffer;
|
return diskBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
public int getDiskType ()
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
return info.diskType;
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public int getTracks ()
|
public int getTracks ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -368,9 +394,6 @@ public class WozFile
|
|||||||
this.rawBuffer = rawBuffer;
|
this.rawBuffer = rawBuffer;
|
||||||
this.trackNo = trackNo;
|
this.trackNo = trackNo;
|
||||||
|
|
||||||
// if (debug1)
|
|
||||||
// System.out.println (HexFormatter.format (rawBuffer, ptr, 1024, ptr));
|
|
||||||
|
|
||||||
if (info.wozVersion == 1)
|
if (info.wozVersion == 1)
|
||||||
{
|
{
|
||||||
bytesUsed = val16 (rawBuffer, ptr + DATA_SIZE);
|
bytesUsed = val16 (rawBuffer, ptr + DATA_SIZE);
|
||||||
@ -413,18 +436,21 @@ public class WozFile
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
Sector sector = new Sector (this, offset);
|
Sector sector = new Sector (this, offset);
|
||||||
checkDuplicates (sector);
|
if (isDuplicate (sector))
|
||||||
|
break;
|
||||||
sectors.add (sector);
|
sectors.add (sector);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
private void checkDuplicates (Sector newSector)
|
private boolean isDuplicate (Sector newSector)
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
for (Sector sector : sectors)
|
for (Sector sector : sectors)
|
||||||
if (sector.isDuplicate (newSector))
|
if (sector.sectorNo == newSector.sectorNo)
|
||||||
System.out.printf ("Duplicate: %s%n", newSector);
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -483,7 +509,7 @@ public class WozFile
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
int max = (bitCount - 1) / 8 + 1;
|
int max = (bitCount - 1) / 8 + 1;
|
||||||
max += 520;
|
max += 600;
|
||||||
newBuffer = new byte[max];
|
newBuffer = new byte[max];
|
||||||
|
|
||||||
for (int i = 0; i < max; i++)
|
for (int i = 0; i < max; i++)
|
||||||
@ -509,7 +535,7 @@ public class WozFile
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
void pack (byte[] diskBuffer) throws DiskNibbleException
|
void packType1 (byte[] diskBuffer) throws DiskNibbleException
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
int ndx = diskSectors == 13 ? 0 : 1;
|
int ndx = diskSectors == 13 ? 0 : 1;
|
||||||
@ -517,8 +543,29 @@ public class WozFile
|
|||||||
|
|
||||||
for (Sector sector : sectors)
|
for (Sector sector : sectors)
|
||||||
if (sector.dataOffset > 0)
|
if (sector.dataOffset > 0)
|
||||||
sector.pack (diskReader, diskBuffer, SECTOR_SIZE
|
{
|
||||||
* (sector.trackNo * diskSectors + interleave[ndx][sector.sectorNo]));
|
byte[] decodedBuffer =
|
||||||
|
diskReader.decodeSector (newBuffer, sector.dataOffset + 3);
|
||||||
|
int ptr = SECTOR_SIZE
|
||||||
|
* (sector.trackNo * diskSectors + interleave[ndx][sector.sectorNo]);
|
||||||
|
System.arraycopy (decodedBuffer, 0, diskBuffer, ptr, decodedBuffer.length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
int packType2 (byte[] diskBuffer, int ptr) throws DiskNibbleException
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
DiskReader diskReader = DiskReader.getInstance (0);
|
||||||
|
for (Sector sector : sectors)
|
||||||
|
if (sector.dataOffset > 0)
|
||||||
|
{
|
||||||
|
byte[] decodedBuffer =
|
||||||
|
diskReader.decodeSector (newBuffer, sector.dataOffset + 4);
|
||||||
|
System.arraycopy (decodedBuffer, 12, diskBuffer, ptr, 512);
|
||||||
|
ptr += 512;
|
||||||
|
}
|
||||||
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -552,11 +599,11 @@ public class WozFile
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
public class Sector
|
public class Sector implements Comparable<Sector>
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
private final Track track;
|
private final Track track;
|
||||||
private final int trackNo, sectorNo, volume, checksum;
|
private int trackNo, sectorNo, volume, checksum;
|
||||||
private final int addressOffset;
|
private final int addressOffset;
|
||||||
private int dataOffset;
|
private int dataOffset;
|
||||||
|
|
||||||
@ -566,10 +613,37 @@ public class WozFile
|
|||||||
{
|
{
|
||||||
this.track = track;
|
this.track = track;
|
||||||
|
|
||||||
volume = decode4and4 (track.newBuffer, addressOffset + 3);
|
if (info.diskType == 1)
|
||||||
trackNo = decode4and4 (track.newBuffer, addressOffset + 5);
|
{
|
||||||
sectorNo = decode4and4 (track.newBuffer, addressOffset + 7);
|
volume = decode4and4 (track.newBuffer, addressOffset + 3);
|
||||||
checksum = decode4and4 (track.newBuffer, addressOffset + 9);
|
trackNo = decode4and4 (track.newBuffer, addressOffset + 5);
|
||||||
|
sectorNo = decode4and4 (track.newBuffer, addressOffset + 7);
|
||||||
|
checksum = decode4and4 (track.newBuffer, addressOffset + 9);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// http://apple2.guidero.us/doku.php/articles/iicplus_smartport_secrets
|
||||||
|
// SWIM Chip User's Ref pp 6
|
||||||
|
// uPD72070.pdf
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int b1 = byteTranslator6and2.decode (track.newBuffer[addressOffset + 3]);
|
||||||
|
sectorNo = byteTranslator6and2.decode (track.newBuffer[addressOffset + 4]);
|
||||||
|
int b3 = byteTranslator6and2.decode (track.newBuffer[addressOffset + 5]);
|
||||||
|
int format = byteTranslator6and2.decode (track.newBuffer[addressOffset + 6]);
|
||||||
|
checksum = byteTranslator6and2.decode (track.newBuffer[addressOffset + 7]);
|
||||||
|
|
||||||
|
trackNo = (b1 & 0x3F) | ((b3 & 0x1F) << 6);
|
||||||
|
volume = (b3 & 0x20) >>> 5; // side
|
||||||
|
|
||||||
|
int chk = b1 ^ sectorNo ^ b3 ^ format;
|
||||||
|
assert chk == checksum;
|
||||||
|
}
|
||||||
|
catch (DiskNibbleException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// int epiloguePtr = track.findNext (epilogue, addressOffset + 11);
|
// int epiloguePtr = track.findNext (epilogue, addressOffset + 11);
|
||||||
// assert epiloguePtr == addressOffset + 11;
|
// assert epiloguePtr == addressOffset + 11;
|
||||||
@ -581,18 +655,13 @@ public class WozFile
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
boolean isDuplicate (Sector sector)
|
void pack (byte[] diskBuffer, int ptr) throws DiskNibbleException
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
return this.sectorNo == sector.sectorNo;
|
DiskReader diskReader = DiskReader.getInstance (0);
|
||||||
}
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
byte[] decodedBuffer = diskReader.decodeSector (track.newBuffer, dataOffset + 4);
|
||||||
void pack (DiskReader diskReader, byte[] buffer, int ptr) throws DiskNibbleException
|
System.arraycopy (decodedBuffer, 12, diskBuffer, ptr, 512);
|
||||||
// ---------------------------------------------------------------------------------//
|
|
||||||
{
|
|
||||||
byte[] decodedBuffer = diskReader.decodeSector (track.newBuffer, dataOffset + 3);
|
|
||||||
System.arraycopy (decodedBuffer, 0, buffer, ptr, decodedBuffer.length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
@ -600,10 +669,24 @@ public class WozFile
|
|||||||
public String toString ()
|
public String toString ()
|
||||||
// ---------------------------------------------------------------------------------//
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
|
String fld = info.diskType == 1 ? "Vol" : info.diskType == 2 ? "Sde" : "???";
|
||||||
String dataOffsetText = dataOffset < 0 ? "" : String.format ("%04X", dataOffset);
|
String dataOffsetText = dataOffset < 0 ? "" : String.format ("%04X", dataOffset);
|
||||||
|
|
||||||
return String.format (
|
return String.format (
|
||||||
"Vol: %02X Trk: %02X Sct: %02X Chk: %02X Add: %04X Dat: %s", volume,
|
"%s: %02X Trk: %02X Sct: %02X Chk: %02X Add: %04X Dat: %s", fld, volume,
|
||||||
trackNo, sectorNo, checksum, addressOffset, dataOffsetText);
|
trackNo, sectorNo, checksum, addressOffset, dataOffsetText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
@Override
|
||||||
|
public int compareTo (Sector o)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
|
if (this.trackNo != o.trackNo)
|
||||||
|
return this.trackNo - o.trackNo;
|
||||||
|
if (this.volume != o.volume)
|
||||||
|
return this.volume - o.volume;
|
||||||
|
return this.sectorNo - o.sectorNo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user