178 lines
5.9 KiB
Java
178 lines
5.9 KiB
Java
package com.bytezone.diskbrowser.applefile;
|
|
|
|
import static com.bytezone.diskbrowser.utilities.Utility.ASCII_BACKSPACE;
|
|
import static com.bytezone.diskbrowser.utilities.Utility.ASCII_CR;
|
|
import static com.bytezone.diskbrowser.utilities.Utility.ASCII_LF;
|
|
import static com.bytezone.diskbrowser.utilities.Utility.getIndent;
|
|
import static com.bytezone.diskbrowser.utilities.Utility.getShort;
|
|
import static com.bytezone.diskbrowser.utilities.Utility.isHighBitSet;
|
|
|
|
import com.bytezone.diskbrowser.gui.BasicPreferences;
|
|
|
|
// -----------------------------------------------------------------------------------//
|
|
public class AppleBasicFormatter extends BasicFormatter
|
|
// -----------------------------------------------------------------------------------//
|
|
{
|
|
private final LineFormatter flatFormatter = new FlatLine ();
|
|
private final LineFormatter wrapFormatter = new WrapLine ();
|
|
|
|
// ---------------------------------------------------------------------------------//
|
|
public AppleBasicFormatter (ApplesoftBasicProgram program,
|
|
BasicPreferences basicPreferences)
|
|
// ---------------------------------------------------------------------------------//
|
|
{
|
|
super (program, basicPreferences);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------------//
|
|
@Override
|
|
public void append (StringBuilder fullText)
|
|
// ---------------------------------------------------------------------------------//
|
|
{
|
|
int loadAddress = getLoadAddress ();
|
|
int ptr = 0;
|
|
int linkField;
|
|
|
|
StringBuilder currentLine = new StringBuilder ();
|
|
LineFormatter formatter =
|
|
basicPreferences.appleLineWrap ? wrapFormatter : flatFormatter;
|
|
|
|
while ((linkField = getShort (buffer, ptr)) != 0)
|
|
{
|
|
int lineNumber = getShort (buffer, ptr + 2);
|
|
currentLine.append (String.format (" %d ", lineNumber));
|
|
ptr += 4;
|
|
|
|
ptr = formatter.formatLine (currentLine, ptr);
|
|
|
|
if (ptr != (linkField - loadAddress))
|
|
System.out.printf ("%s: ptr: %04X, nextLine: %04X%n", program.name,
|
|
ptr + loadAddress, linkField);
|
|
|
|
currentLine.append (NEWLINE);
|
|
fullText.append (currentLine);
|
|
currentLine.setLength (0);
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------------//
|
|
interface LineFormatter
|
|
// ---------------------------------------------------------------------------------//
|
|
{
|
|
abstract int formatLine (StringBuilder currentLine, int ptr);
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------------//
|
|
class FlatLine implements LineFormatter
|
|
// ---------------------------------------------------------------------------------//
|
|
{
|
|
// -------------------------------------------------------------------------------//
|
|
@Override
|
|
public int formatLine (StringBuilder currentLine, int ptr)
|
|
// -------------------------------------------------------------------------------//
|
|
{
|
|
byte b;
|
|
|
|
while ((b = buffer[ptr++]) != 0)
|
|
if (isHighBitSet (b))
|
|
{
|
|
String token = String.format (" %s ", ApplesoftConstants.tokens[b & 0x7F]);
|
|
currentLine.append (token);
|
|
}
|
|
else
|
|
switch (b)
|
|
{
|
|
case ASCII_CR:
|
|
currentLine.append (NEWLINE);
|
|
break;
|
|
|
|
case ASCII_BACKSPACE:
|
|
if (currentLine.length () > 0)
|
|
currentLine.deleteCharAt (currentLine.length () - 1);
|
|
break;
|
|
|
|
case ASCII_LF:
|
|
int indent = getIndent (currentLine);
|
|
currentLine.append ("\n");
|
|
for (int i = 0; i < indent; i++)
|
|
currentLine.append (" ");
|
|
break;
|
|
|
|
default:
|
|
currentLine.append ((char) b);
|
|
}
|
|
|
|
return ptr;
|
|
}
|
|
}
|
|
|
|
// ---------------------------------------------------------------------------------//
|
|
class WrapLine implements LineFormatter
|
|
// ---------------------------------------------------------------------------------//
|
|
{
|
|
private static final int LEFT_MARGIN = 5;
|
|
private static final int RIGHT_MARGIN = 33;
|
|
|
|
// -------------------------------------------------------------------------------//
|
|
@Override
|
|
public int formatLine (StringBuilder currentLine, int ptr)
|
|
// -------------------------------------------------------------------------------//
|
|
{
|
|
byte b;
|
|
int cursor = currentLine.length ();
|
|
|
|
while ((b = buffer[ptr++]) != 0)
|
|
if (isHighBitSet (b))
|
|
{
|
|
String token = String.format (" %s ", ApplesoftConstants.tokens[b & 0x7F]);
|
|
currentLine.append (token);
|
|
cursor = incrementCursor (currentLine, cursor, token.length ());
|
|
}
|
|
else
|
|
switch (b)
|
|
{
|
|
case ASCII_CR:
|
|
currentLine.append (NEWLINE);
|
|
cursor = 0;
|
|
break;
|
|
|
|
case ASCII_BACKSPACE:
|
|
if (cursor > 0)
|
|
{
|
|
currentLine.deleteCharAt (currentLine.length () - 1);
|
|
--cursor;
|
|
}
|
|
break;
|
|
|
|
case ASCII_LF:
|
|
currentLine.append ("\n");
|
|
for (int i = 0; i < cursor; i++)
|
|
currentLine.append (" ");
|
|
break;
|
|
|
|
default:
|
|
currentLine.append ((char) b);
|
|
cursor = incrementCursor (currentLine, cursor, 1);
|
|
}
|
|
|
|
return ptr;
|
|
}
|
|
|
|
// -------------------------------------------------------------------------------//
|
|
private int incrementCursor (StringBuilder currentLine, int cursor, int size)
|
|
// -------------------------------------------------------------------------------//
|
|
{
|
|
assert size <= 9; // longest token possible (7 plus 2 spaces)
|
|
cursor += size;
|
|
|
|
if ((cursor) >= RIGHT_MARGIN)
|
|
{
|
|
cursor = cursor >= 40 ? cursor - 40 : LEFT_MARGIN;
|
|
currentLine.append ("\n ".substring (0, cursor + 1));
|
|
}
|
|
|
|
return cursor;
|
|
}
|
|
}
|
|
}
|