diff --git a/src/com/bytezone/diskbrowser/applefile/ApplesoftBasicProgram.java b/src/com/bytezone/diskbrowser/applefile/ApplesoftBasicProgram.java index 46e0b03..702e084 100644 --- a/src/com/bytezone/diskbrowser/applefile/ApplesoftBasicProgram.java +++ b/src/com/bytezone/diskbrowser/applefile/ApplesoftBasicProgram.java @@ -194,14 +194,14 @@ public class ApplesoftBasicProgram extends BasicProgram implements ApplesoftCons public String getText () // ---------------------------------------------------------------------------------// { - if (showDebugText) - return getHexText (); - StringBuilder text = new StringBuilder (); if (basicPreferences.showHeader) addHeader (text); + if (showDebugText) + return getHexText (text); + if (sourceLines.size () == 0) { text.append ("\n\nThis page intentionally left blank"); @@ -948,16 +948,56 @@ public class ApplesoftBasicProgram extends BasicProgram implements ApplesoftCons } // ---------------------------------------------------------------------------------// - private String getHexText () + private String getHexText (StringBuilder text) + // ---------------------------------------------------------------------------------// + { + int offset = Utility.unsignedShort (buffer, 0); + int programLoadAddress = offset - getLineLength (0); + + for (SourceLine sourceLine : sourceLines) + { + text.append (String.format ("%5d %s%n", sourceLine.lineNumber, + HexFormatter.formatNoHeader (buffer, sourceLine.linePtr, 4, + programLoadAddress + sourceLine.linePtr))); + for (SubLine subline : sourceLine.sublines) + { + byte b = buffer[subline.startPtr]; + String token = + Utility.isHighBitSet (b) ? ApplesoftConstants.tokens[b & 0x7F] : ""; + String hex = HexFormatter.formatNoHeader (buffer, subline.startPtr, + subline.length, programLoadAddress + subline.startPtr); + String[] chunks = hex.split ("\n"); + for (String s : chunks) + { + text.append (String.format (" %-8s %s%n", token, s)); + token = ""; + } + } + text.append ("\n"); + } + + if (endPtr < buffer.length) + { + String hex = HexFormatter.formatNoHeader (buffer, endPtr, buffer.length - endPtr, + programLoadAddress + endPtr); + String[] chunks = hex.split ("\n"); + for (String s : chunks) + text.append (String.format (" %s%n", s)); + } + + while (text.length () > 0 && text.charAt (text.length () - 1) == '\n') + text.deleteCharAt (text.length () - 1); + + return text.toString (); + } + + // ---------------------------------------------------------------------------------// + private String getHexText2 (StringBuilder text) // old version // ---------------------------------------------------------------------------------// { if (buffer.length < 2) return super.getHexDump (); - StringBuilder pgm = new StringBuilder (); - if (basicPreferences.showHeader) - addHeader (pgm); - int ptr = 0; int offset = Utility.unsignedShort (buffer, 0); int programLoadAddress = offset - getLineLength (0); @@ -967,14 +1007,14 @@ public class ApplesoftBasicProgram extends BasicProgram implements ApplesoftCons int length = getLineLength (ptr); if (length == 0) { - pgm.append ( + text.append ( HexFormatter.formatNoHeader (buffer, ptr, 2, programLoadAddress + ptr)); ptr += 2; break; } if (ptr + length < buffer.length) - pgm.append ( + text.append ( HexFormatter.formatNoHeader (buffer, ptr, length, programLoadAddress + ptr) + "\n\n"); ptr += length; @@ -983,12 +1023,12 @@ public class ApplesoftBasicProgram extends BasicProgram implements ApplesoftCons if (ptr < buffer.length) { int length = buffer.length - ptr; - pgm.append ("\n\n"); - pgm.append ( + text.append ("\n\n"); + text.append ( HexFormatter.formatNoHeader (buffer, ptr, length, programLoadAddress + ptr)); } - return pgm.toString (); + return text.toString (); } // A REM statement might conceal an assembler routine @@ -1031,6 +1071,7 @@ public class ApplesoftBasicProgram extends BasicProgram implements ApplesoftCons int offset = Utility.unsignedShort (buffer, ptr); if (offset == 0) return 0; + ptr += 4; // skip offset and line number int length = 5; diff --git a/src/com/bytezone/diskbrowser/applefile/SourceLine.java b/src/com/bytezone/diskbrowser/applefile/SourceLine.java index c26a63d..8bc6ce6 100644 --- a/src/com/bytezone/diskbrowser/applefile/SourceLine.java +++ b/src/com/bytezone/diskbrowser/applefile/SourceLine.java @@ -10,6 +10,7 @@ public class SourceLine implements ApplesoftConstants // -----------------------------------------------------------------------------------// { ApplesoftBasicProgram parent; + int addressNext; int lineNumber; int linePtr; int length; @@ -25,6 +26,7 @@ public class SourceLine implements ApplesoftConstants this.buffer = buffer; linePtr = ptr; + addressNext = Utility.unsignedShort (buffer, ptr); lineNumber = Utility.unsignedShort (buffer, ptr + 2); int startPtr = ptr += 4; // skip link to next line and lineNumber @@ -74,8 +76,9 @@ public class SourceLine implements ApplesoftConstants else { // REM appears mid-line (should follow a colon) System.out.printf ("%5d %s%n", lineNumber, "mid-line REM token"); - sublines.add (new SubLine (this, startPtr, (ptr - startPtr) - 1)); - startPtr = ptr - 1; + ptr--; // point back to this REM + sublines.add (new SubLine (this, startPtr, ptr - startPtr)); + startPtr = ptr; } break; @@ -87,15 +90,12 @@ public class SourceLine implements ApplesoftConstants length = ptr - linePtr; - // add whatever is left - will either start with a token, or be a line number + // add whatever is left after the last colon + // if no colon was found this is the entire line int bytesLeft = ptr - startPtr; sublines.add (new SubLine (this, startPtr, bytesLeft)); - // if (lineNumber == 99) - // { - // System.out.printf ("linePtr: %04X length: %02X%n", linePtr, length); + // if (lineNumber == 1022) // System.out.println (HexFormatter.format (buffer, linePtr, length)); - // System.out.println (HexFormatter.format (buffer, startPtr, bytesLeft)); - // } } } diff --git a/src/com/bytezone/diskbrowser/applefile/SubLine.java b/src/com/bytezone/diskbrowser/applefile/SubLine.java index 4119fda..3290845 100644 --- a/src/com/bytezone/diskbrowser/applefile/SubLine.java +++ b/src/com/bytezone/diskbrowser/applefile/SubLine.java @@ -50,7 +50,7 @@ public class SubLine implements ApplesoftConstants int ptr = startPtr; byte firstByte = buffer[startPtr]; - if (Utility.isHighBitSet (firstByte)) // BASIC command + if (isToken (firstByte)) { doToken (firstByte); if (is (TOKEN_REM) || is (TOKEN_DATA)) // no further processing @@ -67,6 +67,8 @@ public class SubLine implements ApplesoftConstants } else if (Utility.isLetter (firstByte)) // variable assignment recordEqualsPosition (); + else if (firstByte == Utility.ASCII_COLON || firstByte == 0) // empty subline + return; else // probably Beagle Bros 0D... System.out.printf ("Unexpected bytes at %5d: %s%n", parent.lineNumber, HexFormatter.formatNoHeader (buffer, startPtr, length).substring (5)); @@ -408,7 +410,7 @@ public class SubLine implements ApplesoftConstants while (ptr < max) { byte b = buffer[ptr++]; - if (Utility.isHighBitSet (b)) + if (isToken (b)) text.append (tokens[b & 0x7F]); else text.append ((char) b); @@ -446,7 +448,6 @@ public class SubLine implements ApplesoftConstants ptr++; String s = new String (buffer, start, ptr - start); - String[] chunks = s.split (","); try @@ -478,10 +479,7 @@ public class SubLine implements ApplesoftConstants boolean isImpliedGoto () // ---------------------------------------------------------------------------------// { - byte b = buffer[startPtr]; - if (Utility.isHighBitSet (b)) - return false; - return (Utility.isDigit (b)); + return (Utility.isDigit (buffer[startPtr])); } // Record the position of the equals sign so it can be aligned with adjacent lines. @@ -546,7 +544,7 @@ public class SubLine implements ApplesoftConstants { // ignore first byte, check the rest for tokens for (int p = startPtr + 1, max = startPtr + length; p < max; p++) - if (Utility.isHighBitSet (buffer[p])) + if (isToken (buffer[p])) return true; return false; @@ -632,6 +630,13 @@ public class SubLine implements ApplesoftConstants return toStringBuilder ().toString (); } + // ---------------------------------------------------------------------------------// + private boolean isToken (byte b) + // ---------------------------------------------------------------------------------// + { + return Utility.isHighBitSet (b); + } + // ---------------------------------------------------------------------------------// public StringBuilder toStringBuilder () // ---------------------------------------------------------------------------------// @@ -649,20 +654,17 @@ public class SubLine implements ApplesoftConstants for (int p = startPtr; p <= max; p++) { byte b = buffer[p]; - if (Utility.isHighBitSet (b)) // token + if (isToken (b)) { if (line.length () > 0 && line.charAt (line.length () - 1) != ' ') line.append (' '); int val = b & 0x7F; - // if (val < ApplesoftConstants.tokens.length) - // { if (b != TOKEN_THEN || ApplesoftBasicProgram.basicPreferences.showThen) line.append (ApplesoftConstants.tokens[val] + " "); - // } } else if (Utility.isControlCharacter (b)) line.append (ApplesoftBasicProgram.basicPreferences.showCaret - ? "^" + (char) (b + 64) : "."); + ? "^" + (char) (b + 64) : "?"); else line.append ((char) b); }