mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2025-01-14 23:30:17 +00:00
added header underlines
This commit is contained in:
parent
147f7e03f2
commit
600c3a5ce2
@ -1,454 +1,488 @@
|
|||||||
package com.bytezone.diskbrowser.applefile;
|
package com.bytezone.diskbrowser.applefile;
|
||||||
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
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;
|
static AssemblerPreferences assemblerPreferences; // set by MenuHandler
|
||||||
|
|
||||||
private final int loadAddress;
|
private static Map<Integer, String> equates;
|
||||||
private int executeOffset;
|
|
||||||
|
private final int loadAddress;
|
||||||
private byte[] extraBuffer = new byte[0];
|
private int executeOffset;
|
||||||
|
|
||||||
private List<Integer> entryPoints;
|
private byte[] extraBuffer = new byte[0];
|
||||||
private List<StringLocation> stringLocations;
|
|
||||||
|
private List<Integer> entryPoints;
|
||||||
public static void setAssemblerPreferences (AssemblerPreferences assemblerPreferences)
|
private List<StringLocation> stringLocations;
|
||||||
{
|
|
||||||
AssemblerProgram.assemblerPreferences = assemblerPreferences;
|
// ---------------------------------------------------------------------------------//
|
||||||
}
|
public static void setAssemblerPreferences (AssemblerPreferences assemblerPreferences)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
public AssemblerProgram (String name, byte[] buffer, int address)
|
{
|
||||||
{
|
AssemblerProgram.assemblerPreferences = assemblerPreferences;
|
||||||
super (name, buffer);
|
}
|
||||||
this.loadAddress = address;
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
if (equates == null)
|
public AssemblerProgram (String name, byte[] buffer, int address)
|
||||||
getEquates ();
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
// AssemblerBlocks assemblerBlocks = new AssemblerBlocks (buffer, address);
|
super (name, buffer);
|
||||||
}
|
this.loadAddress = address;
|
||||||
|
|
||||||
public AssemblerProgram (String name, byte[] buffer, int address, int executeOffset)
|
if (equates == null)
|
||||||
{
|
getEquates ();
|
||||||
this (name, buffer, address);
|
|
||||||
this.executeOffset = executeOffset;
|
// AssemblerBlocks assemblerBlocks = new AssemblerBlocks (buffer, address);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExtraBuffer (byte[] fullBuffer, int offset, int length)
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
public AssemblerProgram (String name, byte[] buffer, int address, int executeOffset)
|
||||||
if (length >= 0)
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
this.extraBuffer = new byte[length];
|
this (name, buffer, address);
|
||||||
System.arraycopy (fullBuffer, offset, extraBuffer, 0, length);
|
this.executeOffset = executeOffset;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
System.out.println ("Invalid length in setExtraBuffer() : " + length);
|
// ---------------------------------------------------------------------------------//
|
||||||
}
|
public void setExtraBuffer (byte[] fullBuffer, int offset, int length)
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
@Override
|
{
|
||||||
public String getHexDump ()
|
if (length >= 0)
|
||||||
{
|
{
|
||||||
// It might be useful to add opt-O to change the offset. Sometimes it's useful
|
this.extraBuffer = new byte[length];
|
||||||
// to see the hex dump offset from zero, other times it's better to use the
|
System.arraycopy (fullBuffer, offset, extraBuffer, 0, length);
|
||||||
// load address.
|
}
|
||||||
String text = HexFormatter.format (buffer, 0, buffer.length, loadAddress);
|
else
|
||||||
|
System.out.println ("Invalid length in setExtraBuffer() : " + length);
|
||||||
if (extraBuffer.length == 0)
|
}
|
||||||
return text;
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
return text + "\n\nData outside actual buffer:\n\n" + HexFormatter
|
@Override
|
||||||
.format (extraBuffer, 0, extraBuffer.length, loadAddress + buffer.length);
|
public String getHexDump ()
|
||||||
}
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
@Override
|
// It might be useful to add opt-O to change the offset. Sometimes it's useful
|
||||||
public String getAssembler ()
|
// to see the hex dump offset from zero, other times it's better to use the
|
||||||
{
|
// load address.
|
||||||
if (buffer == null)
|
String text = HexFormatter.format (buffer, 0, buffer.length, loadAddress);
|
||||||
return "No buffer";
|
|
||||||
|
if (extraBuffer.length == 0)
|
||||||
if (assembler == null)
|
return text;
|
||||||
this.assembler = new AssemblerProgram (name, buffer, loadAddress);
|
|
||||||
|
return text + "\n\nData outside actual buffer:\n\n" + HexFormatter
|
||||||
if (extraBuffer.length == 0)
|
.format (extraBuffer, 0, extraBuffer.length, loadAddress + buffer.length);
|
||||||
return assembler.getText ();
|
}
|
||||||
|
|
||||||
String extraName = String.format ("%s (extra)", name);
|
// ---------------------------------------------------------------------------------//
|
||||||
AssemblerProgram assemblerProgram =
|
@Override
|
||||||
new AssemblerProgram (extraName, extraBuffer, loadAddress + buffer.length);
|
public String getAssembler ()
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
return assembler.getText () + "\n\n" + assemblerProgram.getText ();
|
{
|
||||||
}
|
if (buffer == null)
|
||||||
|
return "No buffer";
|
||||||
private void addHeader (StringBuilder pgm)
|
|
||||||
{
|
if (assembler == null)
|
||||||
pgm.append (String.format ("Name : %s%n", name));
|
this.assembler = new AssemblerProgram (name, buffer, loadAddress);
|
||||||
pgm.append (String.format ("Length : $%04X (%,d)%n", buffer.length, buffer.length));
|
|
||||||
pgm.append (String.format ("Load at : $%04X (%,d)%n", loadAddress, loadAddress));
|
if (extraBuffer.length == 0)
|
||||||
|
return assembler.getText ();
|
||||||
if (executeOffset > 0)
|
|
||||||
pgm.append (String.format ("Entry : $%04X%n", (loadAddress + executeOffset)));
|
String extraName = String.format ("%s (extra)", name);
|
||||||
pgm.append ("\n");
|
AssemblerProgram assemblerProgram =
|
||||||
}
|
new AssemblerProgram (extraName, extraBuffer, loadAddress + buffer.length);
|
||||||
|
|
||||||
@Override
|
return assembler.getText () + "\n\n" + assemblerProgram.getText ();
|
||||||
public String getText ()
|
}
|
||||||
{
|
|
||||||
StringBuilder pgm = new StringBuilder ();
|
// ---------------------------------------------------------------------------------//
|
||||||
|
private void addHeader (StringBuilder pgm)
|
||||||
if (assemblerPreferences.showHeader)
|
// ---------------------------------------------------------------------------------//
|
||||||
addHeader (pgm);
|
{
|
||||||
|
pgm.append (String.format ("Name : %s%n", name));
|
||||||
pgm.append (getListing ());
|
pgm.append (String.format ("Length : $%04X (%,d)%n", buffer.length, buffer.length));
|
||||||
|
pgm.append (String.format ("Load at : $%04X (%,d)%n", loadAddress, loadAddress));
|
||||||
if (assemblerPreferences.showStrings)
|
|
||||||
pgm.append (getStringsText ());
|
if (executeOffset > 0)
|
||||||
|
pgm.append (String.format ("Entry : $%04X%n", (loadAddress + executeOffset)));
|
||||||
return pgm.toString ();
|
pgm.append ("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getListing ()
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
@Override
|
||||||
StringBuilder pgm = new StringBuilder ();
|
public String getText ()
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
List<AssemblerStatement> lines = getLines ();
|
{
|
||||||
|
StringBuilder pgm = new StringBuilder ();
|
||||||
if (stringLocations == null)
|
|
||||||
getStrings ();
|
if (assemblerPreferences.showHeader)
|
||||||
|
addHeader (pgm);
|
||||||
// if the assembly doesn't start at the beginning, just dump the bytes that
|
|
||||||
// are skipped
|
pgm.append (getListing ());
|
||||||
for (int i = 0; i < executeOffset; i++)
|
|
||||||
pgm.append (String.format (" %04X: %02X%n", (loadAddress + i), buffer[i]));
|
if (assemblerPreferences.showStrings)
|
||||||
|
pgm.append (getStringsText ());
|
||||||
for (AssemblerStatement cmd : lines)
|
|
||||||
{
|
return pgm.toString ();
|
||||||
StringBuilder line = new StringBuilder ();
|
}
|
||||||
|
|
||||||
String arrowText = assemblerPreferences.showTargets ? getArrow (cmd) : "";
|
// ---------------------------------------------------------------------------------//
|
||||||
line.append (
|
private String getListing ()
|
||||||
String.format ("%3.3s %04X: %02X ", arrowText, cmd.address, cmd.value));
|
// ---------------------------------------------------------------------------------//
|
||||||
|
{
|
||||||
if (cmd.size > 1)
|
StringBuilder pgm = new StringBuilder ();
|
||||||
line.append (String.format ("%02X ", cmd.operand1));
|
|
||||||
if (cmd.size > 2)
|
List<AssemblerStatement> lines = getLines ();
|
||||||
line.append (String.format ("%02X ", cmd.operand2));
|
|
||||||
|
if (stringLocations == null)
|
||||||
while (line.length () < 23)
|
getStrings ();
|
||||||
line.append (" ");
|
|
||||||
|
// if the assembly doesn't start at the beginning, just dump the bytes that
|
||||||
line.append (cmd.mnemonic + " " + cmd.operand);
|
// are skipped
|
||||||
|
for (int i = 0; i < executeOffset; i++)
|
||||||
if (cmd.offset != 0)
|
pgm.append (String.format (" %04X: %02X%n", (loadAddress + i), buffer[i]));
|
||||||
{
|
|
||||||
int branch = cmd.address + cmd.offset + 2;
|
for (AssemblerStatement cmd : lines)
|
||||||
line.append (String.format ("$%04X", branch < 0 ? branch += 0xFFFF : branch));
|
{
|
||||||
}
|
StringBuilder line = new StringBuilder ();
|
||||||
else if (cmd.target > 0
|
|
||||||
&& (cmd.target < loadAddress - 1 || cmd.target > (loadAddress + buffer.length)))
|
String arrowText = assemblerPreferences.showTargets ? getArrow (cmd) : "";
|
||||||
{
|
line.append (
|
||||||
while (line.length () < 40)
|
String.format ("%3.3s %04X: %02X ", arrowText, cmd.address, cmd.value));
|
||||||
line.append (" ");
|
|
||||||
|
if (cmd.size > 1)
|
||||||
String text = equates.get (cmd.target);
|
line.append (String.format ("%02X ", cmd.operand1));
|
||||||
if (text != null)
|
if (cmd.size > 2)
|
||||||
line.append ("; " + text);
|
line.append (String.format ("%02X ", cmd.operand2));
|
||||||
else
|
|
||||||
for (int i = 0, max = ApplesoftConstants.tokenAddresses.length; i < max; i++)
|
while (line.length () < 23)
|
||||||
if (cmd.target == ApplesoftConstants.tokenAddresses[i])
|
line.append (" ");
|
||||||
{
|
|
||||||
line.append ("; Applesoft - " + ApplesoftConstants.tokens[i]);
|
line.append (cmd.mnemonic + " " + cmd.operand);
|
||||||
break;
|
|
||||||
}
|
if (cmd.offset != 0)
|
||||||
}
|
{
|
||||||
|
int branch = cmd.address + cmd.offset + 2;
|
||||||
pgm.append (line.toString () + "\n");
|
line.append (String.format ("$%04X", branch < 0 ? branch += 0xFFFF : branch));
|
||||||
}
|
}
|
||||||
|
else if (cmd.target > 0
|
||||||
if (pgm.length () > 0)
|
&& (cmd.target < loadAddress - 1 || cmd.target > (loadAddress + buffer.length)))
|
||||||
pgm.deleteCharAt (pgm.length () - 1);
|
{
|
||||||
|
while (line.length () < 40)
|
||||||
return pgm.toString ();
|
line.append (" ");
|
||||||
}
|
|
||||||
|
String text = equates.get (cmd.target);
|
||||||
// private int showString (AssemblerStatement cmd, StringBuilder line)
|
if (text != null)
|
||||||
// {
|
line.append ("; " + text);
|
||||||
// int key = cmd.address - loadAddress;
|
else
|
||||||
// if (strings.containsKey (key))
|
for (int i = 0, max = ApplesoftConstants.tokenAddresses.length; i < max; i++)
|
||||||
// {
|
if (cmd.target == ApplesoftConstants.tokenAddresses[i])
|
||||||
// while (line.length () < 40)
|
{
|
||||||
// line.append (" ");
|
line.append ("; Applesoft - " + ApplesoftConstants.tokens[i]);
|
||||||
// String s = strings.get (key);
|
break;
|
||||||
// line.append ("# " + s);
|
}
|
||||||
// return s.length () - cmd.size;
|
}
|
||||||
// }
|
|
||||||
// return 0;
|
pgm.append (line.toString () + "\n");
|
||||||
// }
|
}
|
||||||
|
|
||||||
private List<AssemblerStatement> getLines ()
|
if (pgm.length () > 0)
|
||||||
{
|
pgm.deleteCharAt (pgm.length () - 1);
|
||||||
List<AssemblerStatement> lines = new ArrayList<> ();
|
|
||||||
Map<Integer, AssemblerStatement> linesMap = new HashMap<> ();
|
return pgm.toString ();
|
||||||
List<Integer> targets = new ArrayList<> ();
|
}
|
||||||
|
|
||||||
int ptr = executeOffset;
|
// private int showString (AssemblerStatement cmd, StringBuilder line)
|
||||||
int address = loadAddress + executeOffset;
|
// {
|
||||||
|
// int key = cmd.address - loadAddress;
|
||||||
while (ptr < buffer.length)
|
// if (strings.containsKey (key))
|
||||||
{
|
// {
|
||||||
AssemblerStatement cmd = new AssemblerStatement (buffer[ptr]);
|
// while (line.length () < 40)
|
||||||
lines.add (cmd);
|
// line.append (" ");
|
||||||
linesMap.put (address, cmd);
|
// String s = strings.get (key);
|
||||||
cmd.address = address;
|
// line.append ("# " + s);
|
||||||
|
// return s.length () - cmd.size;
|
||||||
if (cmd.size == 2 && ptr < buffer.length - 1)
|
// }
|
||||||
cmd.addData (buffer[ptr + 1]);
|
// return 0;
|
||||||
else if (cmd.size == 3 && ptr < buffer.length - 2)
|
// }
|
||||||
cmd.addData (buffer[ptr + 1], buffer[ptr + 2]);
|
|
||||||
else
|
// ---------------------------------------------------------------------------------//
|
||||||
cmd.size = 1;
|
private List<AssemblerStatement> getLines ()
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
// JMP, JMP, JSR
|
{
|
||||||
if (cmd.target >= loadAddress && cmd.target < (loadAddress + buffer.length)
|
List<AssemblerStatement> lines = new ArrayList<> ();
|
||||||
&& (cmd.value == 0x4C || cmd.value == 0x6C || cmd.value == 0x20))
|
Map<Integer, AssemblerStatement> linesMap = new HashMap<> ();
|
||||||
targets.add (cmd.target);
|
List<Integer> targets = new ArrayList<> ();
|
||||||
|
|
||||||
// branch relative
|
int ptr = executeOffset;
|
||||||
if (cmd.offset != 0)
|
int address = loadAddress + executeOffset;
|
||||||
targets.add (cmd.address + cmd.offset + 2);
|
|
||||||
|
while (ptr < buffer.length)
|
||||||
address += cmd.size;
|
{
|
||||||
ptr += cmd.size;
|
AssemblerStatement cmd = new AssemblerStatement (buffer[ptr]);
|
||||||
}
|
lines.add (cmd);
|
||||||
|
linesMap.put (address, cmd);
|
||||||
for (Integer target : targets)
|
cmd.address = address;
|
||||||
{
|
|
||||||
AssemblerStatement cmd = linesMap.get (target);
|
if (cmd.size == 2 && ptr < buffer.length - 1)
|
||||||
if (cmd != null)
|
cmd.addData (buffer[ptr + 1]);
|
||||||
cmd.isTarget = true;
|
else if (cmd.size == 3 && ptr < buffer.length - 2)
|
||||||
}
|
cmd.addData (buffer[ptr + 1], buffer[ptr + 2]);
|
||||||
|
else
|
||||||
return lines;
|
cmd.size = 1;
|
||||||
}
|
|
||||||
|
// JMP, JMP, JSR
|
||||||
private String getStringsText ()
|
if (cmd.target >= loadAddress && cmd.target < (loadAddress + buffer.length)
|
||||||
{
|
&& (cmd.value == 0x4C || cmd.value == 0x6C || cmd.value == 0x20))
|
||||||
if (stringLocations.size () == 0)
|
targets.add (cmd.target);
|
||||||
return "";
|
|
||||||
|
// branch relative
|
||||||
StringBuilder text = new StringBuilder ("\n\nPossible strings:\n\n");
|
if (cmd.offset != 0)
|
||||||
for (StringLocation stringLocation : stringLocations)
|
targets.add (cmd.address + cmd.offset + 2);
|
||||||
{
|
|
||||||
int address = stringLocation.offset + loadAddress;
|
address += cmd.size;
|
||||||
text.append (String.format ("%s %04X - %04X %s %n",
|
ptr += cmd.size;
|
||||||
entryPoints.contains (stringLocation.offset) ? "*" : " ", address,
|
}
|
||||||
address + stringLocation.length, stringLocation));
|
|
||||||
}
|
for (Integer target : targets)
|
||||||
|
{
|
||||||
if (text.length () > 0)
|
AssemblerStatement cmd = linesMap.get (target);
|
||||||
text.deleteCharAt (text.length () - 1);
|
if (cmd != null)
|
||||||
|
cmd.isTarget = true;
|
||||||
return text.toString ();
|
}
|
||||||
}
|
|
||||||
|
return lines;
|
||||||
private void getStrings ()
|
}
|
||||||
{
|
|
||||||
entryPoints = new ArrayList<> ();
|
// ---------------------------------------------------------------------------------//
|
||||||
stringLocations = new ArrayList<> ();
|
private String getStringsText ()
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
int start = 0;
|
{
|
||||||
for (int ptr = 0; ptr < buffer.length; ptr++)
|
if (stringLocations.size () == 0)
|
||||||
{
|
return "";
|
||||||
if ((buffer[ptr] & 0x80) != 0) // hi bit set
|
|
||||||
continue;
|
StringBuilder text = new StringBuilder ("\n\nPossible strings:\n\n");
|
||||||
|
for (StringLocation stringLocation : stringLocations)
|
||||||
if (buffer[ptr] == 0x0D) // CR
|
{
|
||||||
continue;
|
int address = stringLocation.offset + loadAddress;
|
||||||
|
text.append (String.format ("%s %04X - %04X %s %n",
|
||||||
if (ptr - start > 3)
|
entryPoints.contains (stringLocation.offset) ? "*" : " ", address,
|
||||||
stringLocations.add (new StringLocation (start, ptr - 1));
|
address + stringLocation.length, stringLocation));
|
||||||
|
}
|
||||||
start = ptr + 1;
|
|
||||||
}
|
if (text.length () > 0)
|
||||||
|
text.deleteCharAt (text.length () - 1);
|
||||||
if (buffer.length - start > 3)
|
|
||||||
stringLocations.add (new StringLocation (start, buffer.length - 1));
|
return text.toString ();
|
||||||
|
}
|
||||||
int max = buffer.length - 2;
|
|
||||||
for (StringLocation stringLocation : stringLocations)
|
// ---------------------------------------------------------------------------------//
|
||||||
for (int ptr = 0; ptr < max; ptr++)
|
private void getStrings ()
|
||||||
if (stringLocation.matches (buffer, ptr))
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
entryPoints.add (stringLocation.offset);
|
entryPoints = new ArrayList<> ();
|
||||||
break;
|
stringLocations = new ArrayList<> ();
|
||||||
}
|
|
||||||
}
|
int start = 0;
|
||||||
|
for (int ptr = 0; ptr < buffer.length; ptr++)
|
||||||
private String getArrow (AssemblerStatement cmd)
|
{
|
||||||
{
|
if ((buffer[ptr] & 0x80) != 0) // hi bit set
|
||||||
String arrow = "";
|
continue;
|
||||||
|
|
||||||
if (cmd.value == 0x4C || cmd.value == 0x6C || cmd.value == 0x60 || cmd.offset != 0)
|
if (buffer[ptr] == 0x0D) // CR
|
||||||
arrow = "<--";
|
continue;
|
||||||
|
|
||||||
if (cmd.value == 0x20 && isLocal (cmd.target)) // JSR
|
if (ptr - start > 3)
|
||||||
arrow = "<--";
|
stringLocations.add (new StringLocation (start, ptr - 1));
|
||||||
|
|
||||||
if (cmd.isTarget)
|
start = ptr + 1;
|
||||||
if (arrow.isEmpty ())
|
}
|
||||||
arrow = "-->";
|
|
||||||
else
|
if (buffer.length - start > 3)
|
||||||
arrow = "<->";
|
stringLocations.add (new StringLocation (start, buffer.length - 1));
|
||||||
|
|
||||||
return arrow;
|
int max = buffer.length - 2;
|
||||||
}
|
for (StringLocation stringLocation : stringLocations)
|
||||||
|
for (int ptr = 0; ptr < max; ptr++)
|
||||||
private boolean isLocal (int target)
|
if (stringLocation.matches (buffer, ptr))
|
||||||
{
|
{
|
||||||
return target >= loadAddress
|
entryPoints.add (stringLocation.offset);
|
||||||
&& target < loadAddress + buffer.length + extraBuffer.length;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
private void getEquates ()
|
|
||||||
{
|
// ---------------------------------------------------------------------------------//
|
||||||
equates = new HashMap<Integer, String> ();
|
private String getArrow (AssemblerStatement cmd)
|
||||||
DataInputStream inputEquates =
|
// ---------------------------------------------------------------------------------//
|
||||||
new DataInputStream (DiskBrowser.class.getClassLoader ()
|
{
|
||||||
.getResourceAsStream ("com/bytezone/diskbrowser/applefile/equates.txt"));
|
String arrow = "";
|
||||||
BufferedReader in = new BufferedReader (new InputStreamReader (inputEquates));
|
|
||||||
|
if (cmd.value == 0x4C || cmd.value == 0x6C || cmd.value == 0x60 || cmd.offset != 0)
|
||||||
String line;
|
arrow = "<--";
|
||||||
try
|
|
||||||
{
|
if (cmd.value == 0x20 && isLocal (cmd.target)) // JSR
|
||||||
while ((line = in.readLine ()) != null)
|
arrow = "<--";
|
||||||
{
|
|
||||||
if (!line.isEmpty () && !line.startsWith ("*"))
|
if (cmd.isTarget)
|
||||||
{
|
if (arrow.isEmpty ())
|
||||||
int address = Integer.parseInt (line.substring (0, 4), 16);
|
arrow = "-->";
|
||||||
if (equates.containsKey (address))
|
else
|
||||||
System.out.printf ("Duplicate equate entry : %04X%n" + address);
|
arrow = "<->";
|
||||||
else
|
|
||||||
equates.put (address, line.substring (6));
|
return arrow;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
in.close ();
|
// ---------------------------------------------------------------------------------//
|
||||||
}
|
private boolean isLocal (int target)
|
||||||
catch (IOException e)
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
{
|
||||||
e.printStackTrace ();
|
return target >= loadAddress
|
||||||
}
|
&& target < loadAddress + buffer.length + extraBuffer.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
class StringLocation
|
// ---------------------------------------------------------------------------------//
|
||||||
{
|
private void getEquates ()
|
||||||
int offset;
|
// ---------------------------------------------------------------------------------//
|
||||||
byte hi, lo;
|
{
|
||||||
int length;
|
equates = new HashMap<Integer, String> ();
|
||||||
boolean zeroTerminated;
|
DataInputStream inputEquates =
|
||||||
boolean lowTerminated;
|
new DataInputStream (DiskBrowser.class.getClassLoader ()
|
||||||
boolean hasLengthByte;
|
.getResourceAsStream ("com/bytezone/diskbrowser/applefile/equates.txt"));
|
||||||
int digits;
|
BufferedReader in = new BufferedReader (new InputStreamReader (inputEquates));
|
||||||
int letters;
|
|
||||||
int punctuation;
|
String line;
|
||||||
int controlChars;
|
try
|
||||||
int spaces;
|
{
|
||||||
|
while ((line = in.readLine ()) != null)
|
||||||
public StringLocation (int first, int last)
|
{
|
||||||
{
|
if (!line.isEmpty () && !line.startsWith ("*"))
|
||||||
offset = first;
|
{
|
||||||
length = last - offset + 1;
|
int address = Integer.parseInt (line.substring (0, 4), 16);
|
||||||
int end = last + 1;
|
if (equates.containsKey (address))
|
||||||
|
System.out.printf ("Duplicate equate entry : %04X%n" + address);
|
||||||
zeroTerminated = end < buffer.length && buffer[end] == 0;
|
else
|
||||||
lowTerminated = end < buffer.length && buffer[end] >= 32 && buffer[end] < 127;
|
equates.put (address, line.substring (6));
|
||||||
|
}
|
||||||
if (first > 0 && (buffer[first] & 0xFF) == length + 1)
|
}
|
||||||
{
|
in.close ();
|
||||||
hasLengthByte = true;
|
}
|
||||||
--offset;
|
catch (IOException e)
|
||||||
++length;
|
{
|
||||||
}
|
e.printStackTrace ();
|
||||||
|
}
|
||||||
hi = (byte) ((offset + loadAddress) >>> 8);
|
}
|
||||||
lo = (byte) ((offset + loadAddress) & 0x00FF);
|
|
||||||
|
// ---------------------------------------------------------------------------------//
|
||||||
for (int i = offset; i < offset + length; i++)
|
class StringLocation
|
||||||
{
|
// ---------------------------------------------------------------------------------//
|
||||||
int val = buffer[i] & 0x7F;
|
{
|
||||||
if (val < 32 || val == 127)
|
int offset;
|
||||||
++controlChars;
|
byte hi, lo;
|
||||||
else if (val == 32)
|
int length;
|
||||||
++spaces;
|
boolean zeroTerminated;
|
||||||
else if (val >= 48 && val <= 57)
|
boolean lowTerminated;
|
||||||
++digits;
|
boolean hasLengthByte;
|
||||||
else if (val >= 65 && val <= 90)
|
int digits;
|
||||||
++letters;
|
int letters;
|
||||||
else if (val >= 97 && val <= 122)
|
int punctuation;
|
||||||
++letters;
|
int controlChars;
|
||||||
else
|
int spaces;
|
||||||
++punctuation;
|
|
||||||
}
|
public StringLocation (int first, int last)
|
||||||
}
|
{
|
||||||
|
offset = first;
|
||||||
boolean matches (byte[] buffer, int ptr)
|
length = last - offset + 1;
|
||||||
{
|
int end = last + 1;
|
||||||
return lo == buffer[ptr] && hi == buffer[ptr + 1];
|
|
||||||
}
|
zeroTerminated = end < buffer.length && buffer[end] == 0;
|
||||||
|
lowTerminated = end < buffer.length && buffer[end] >= 32 && buffer[end] < 127;
|
||||||
boolean likelyString ()
|
|
||||||
{
|
if (first > 0 && (buffer[first] & 0xFF) == length + 1)
|
||||||
return spaces > 0 || letters > punctuation;
|
{
|
||||||
}
|
hasLengthByte = true;
|
||||||
|
--offset;
|
||||||
public String address ()
|
++length;
|
||||||
{
|
}
|
||||||
return String.format ("%04X %02X %02X", offset, hi, lo);
|
|
||||||
}
|
hi = (byte) ((offset + loadAddress) >>> 8);
|
||||||
|
lo = (byte) ((offset + loadAddress) & 0x00FF);
|
||||||
public String toStatisticsString ()
|
|
||||||
{
|
for (int i = offset; i < offset + length; i++)
|
||||||
return String.format ("%2d, %2d, %2d, %2d, %2d", digits, letters, punctuation,
|
{
|
||||||
controlChars, spaces);
|
int val = buffer[i] & 0x7F;
|
||||||
}
|
if (val < 32 || val == 127)
|
||||||
|
++controlChars;
|
||||||
@Override
|
else if (val == 32)
|
||||||
public String toString ()
|
++spaces;
|
||||||
{
|
else if (val >= 48 && val <= 57)
|
||||||
StringBuilder text = new StringBuilder ();
|
++digits;
|
||||||
|
else if (val >= 65 && val <= 90)
|
||||||
if (hasLengthByte)
|
++letters;
|
||||||
text.append ("<length>");
|
else if (val >= 97 && val <= 122)
|
||||||
|
++letters;
|
||||||
for (int i = offset; i < offset + length; i++)
|
else
|
||||||
{
|
++punctuation;
|
||||||
int val = buffer[i] & 0x7F;
|
}
|
||||||
if (val == 4)
|
}
|
||||||
text.append ("<ctrl-D>");
|
|
||||||
else if (val == 10)
|
boolean matches (byte[] buffer, int ptr)
|
||||||
text.append ("<LF>");
|
{
|
||||||
else if (val == 13)
|
return lo == buffer[ptr] && hi == buffer[ptr + 1];
|
||||||
text.append ("<CR>");
|
}
|
||||||
else
|
|
||||||
text.append ((char) val);
|
boolean likelyString ()
|
||||||
}
|
{
|
||||||
if (lowTerminated)
|
return spaces > 0 || letters > punctuation;
|
||||||
text.append ((char) buffer[offset + length]);
|
}
|
||||||
|
|
||||||
return text.toString ();
|
public String address ()
|
||||||
}
|
{
|
||||||
}
|
return String.format ("%04X %02X %02X", offset, hi, lo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toStatisticsString ()
|
||||||
|
{
|
||||||
|
return String.format ("%2d, %2d, %2d, %2d, %2d", digits, letters, punctuation,
|
||||||
|
controlChars, spaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString ()
|
||||||
|
{
|
||||||
|
StringBuilder text = new StringBuilder ();
|
||||||
|
|
||||||
|
if (hasLengthByte)
|
||||||
|
text.append ("<length>");
|
||||||
|
|
||||||
|
for (int i = offset; i < offset + length; i++)
|
||||||
|
{
|
||||||
|
int val = buffer[i] & 0x7F;
|
||||||
|
if (val == 4)
|
||||||
|
text.append ("<ctrl-D>");
|
||||||
|
else if (val == 10)
|
||||||
|
text.append ("<LF>");
|
||||||
|
else if (val == 13)
|
||||||
|
text.append ("<CR>");
|
||||||
|
else
|
||||||
|
text.append ((char) val);
|
||||||
|
}
|
||||||
|
if (lowTerminated)
|
||||||
|
text.append ((char) buffer[offset + length]);
|
||||||
|
|
||||||
|
return text.toString ();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user