diff --git a/src/com/bytezone/diskbrowser/applefile/ApplesoftBasicProgram.java b/src/com/bytezone/diskbrowser/applefile/ApplesoftBasicProgram.java index 02b901b..15df2f8 100644 --- a/src/com/bytezone/diskbrowser/applefile/ApplesoftBasicProgram.java +++ b/src/com/bytezone/diskbrowser/applefile/ApplesoftBasicProgram.java @@ -1,10 +1,10 @@ package com.bytezone.diskbrowser.applefile; import java.util.ArrayList; -import java.util.HashSet; import java.util.List; -import java.util.Set; +import java.util.Map; import java.util.Stack; +import java.util.TreeMap; import com.bytezone.diskbrowser.utilities.HexFormatter; import com.bytezone.diskbrowser.utilities.Utility; @@ -29,8 +29,8 @@ public class ApplesoftBasicProgram extends BasicProgram private final List sourceLines = new ArrayList<> (); private final int endPtr; - private final Set gotoLines = new HashSet<> (); - private final Set gosubLines = new HashSet<> (); + private final Map> gotoLines = new TreeMap<> (); + private final Map> gosubLines = new TreeMap<> (); // ---------------------------------------------------------------------------------// public ApplesoftBasicProgram (String name, byte[] buffer) @@ -70,6 +70,7 @@ public class ApplesoftBasicProgram extends BasicProgram { int indentSize = 2; boolean insertBlankLine = false; + boolean showGosubs = true; StringBuilder fullText = new StringBuilder (); Stack loopVariables = new Stack<> (); @@ -254,9 +255,25 @@ public class ApplesoftBasicProgram extends BasicProgram programLoadAddress + ptr)); } + if (basicPreferences.showXref) + { + if (fullText.charAt (fullText.length () - 2) != '\n') + fullText.append ("\n"); + fullText.append ("Subroutine:\n"); + for (Integer line : gosubLines.keySet ()) + { + fullText.append (String.format (" %5s %s%n", line, gosubLines.get (line))); + } + fullText.append ("\nGoTo:\n"); + for (Integer line : gotoLines.keySet ()) + { + fullText.append (String.format (" %5s %s%n", line, gotoLines.get (line))); + } + } + if (fullText.length () > 0) while (fullText.charAt (fullText.length () - 1) == '\n') - fullText.deleteCharAt (fullText.length () - 1); // remove last newline + fullText.deleteCharAt (fullText.length () - 1); // remove trailing newlines return fullText.toString (); } @@ -363,8 +380,8 @@ public class ApplesoftBasicProgram extends BasicProgram private String getBase (SourceLine line) // ---------------------------------------------------------------------------------// { - boolean isTarget = - gotoLines.contains (line.lineNumber) || gosubLines.contains (line.lineNumber); + boolean isTarget = gotoLines.containsKey (line.lineNumber) + || gosubLines.containsKey (line.lineNumber); if (!basicPreferences.showTargets) { @@ -381,9 +398,9 @@ public class ApplesoftBasicProgram extends BasicProgram c1 = "<<"; if (subline.is (TOKEN_GOTO)) c1 = " <"; - if (gotoLines.contains (line.lineNumber)) + if (gotoLines.containsKey (line.lineNumber)) c2 = "> "; - if (gosubLines.contains (line.lineNumber)) + if (gosubLines.containsKey (line.lineNumber)) c2 = ">>"; if (c1.equals (" ") && !c2.equals (" ")) c1 = "--"; @@ -570,7 +587,6 @@ public class ApplesoftBasicProgram extends BasicProgram SourceLine (int ptr) { linePtr = ptr; - // lineNumber = Utility.intValue (buffer[ptr + 2], buffer[ptr + 3]); lineNumber = Utility.unsignedShort (buffer, ptr + 2); int startPtr = ptr += 4; @@ -689,7 +705,19 @@ public class ApplesoftBasicProgram extends BasicProgram String target = new String (buffer, startPtr + 1, length - 2); try { - gotoLines.add (Integer.parseInt (target)); + int targetLine = Integer.parseInt (target); + // gotoLines.add (Integer.parseInt (target)); + if (gotoLines.containsKey (targetLine)) + { + List lines = gotoLines.get (targetLine); + lines.add (parent.lineNumber); + } + else + { + List lines = new ArrayList<> (); + lines.add (parent.lineNumber); + gotoLines.put (targetLine, lines); + } } catch (NumberFormatException e) { @@ -699,16 +727,28 @@ public class ApplesoftBasicProgram extends BasicProgram break; case TOKEN_GOSUB: - String target2 = new String (buffer, startPtr + 1, length - 2); + target = new String (buffer, startPtr + 1, length - 2); try { - gosubLines.add (Integer.parseInt (target2)); + int targetLine = Integer.parseInt (target); + // gosubLines.add (Integer.parseInt (target)); + if (gosubLines.containsKey (targetLine)) + { + List lines = gosubLines.get (targetLine); + lines.add (parent.lineNumber); + } + else + { + List lines = new ArrayList<> (); + lines.add (parent.lineNumber); + gosubLines.put (targetLine, lines); + } } catch (NumberFormatException e) { System.out.println (HexFormatter.format (buffer, startPtr + 1, length - 2)); System.out.println ( - "Error parsing : GOSUB " + target2 + " in " + parent.lineNumber); + "Error parsing : GOSUB " + target + " in " + parent.lineNumber); } break; } @@ -721,7 +761,18 @@ public class ApplesoftBasicProgram extends BasicProgram try { targetLine = Integer.parseInt (target); - gotoLines.add (targetLine); + // gotoLines.add (targetLine); + if (gotoLines.containsKey (targetLine)) + { + List lines = gotoLines.get (targetLine); + lines.add (parent.lineNumber); + } + else + { + List lines = new ArrayList<> (); + lines.add (parent.lineNumber); + gotoLines.put (targetLine, lines); + } } catch (NumberFormatException e) { diff --git a/src/com/bytezone/diskbrowser/gui/BasicPreferences.java b/src/com/bytezone/diskbrowser/gui/BasicPreferences.java index 770cd04..8f2a1c1 100644 --- a/src/com/bytezone/diskbrowser/gui/BasicPreferences.java +++ b/src/com/bytezone/diskbrowser/gui/BasicPreferences.java @@ -14,6 +14,7 @@ public class BasicPreferences public boolean blankAfterReturn = false; public boolean deleteExtraRemSpace = false; public boolean deleteExtraDataSpace = false; + public boolean showXref = false; public int wrapPrintAt = 0; public int wrapRemAt = 60; public int wrapDataAt = 60; @@ -33,6 +34,7 @@ public class BasicPreferences text.append (String.format ("Show header .............. %s%n", showHeader)); text.append (String.format ("Show caret ............... %s%n", showCaret)); text.append (String.format ("Show THEN ................ %s%n", showThen)); + text.append (String.format ("Show Xref ................ %s%n", showXref)); text.append (String.format ("Blank after RETURN ....... %s%n", blankAfterReturn)); text.append (String.format ("Delete extra REM space ... %s%n", deleteExtraRemSpace)); text.append (String.format ("Delete extra DATA space .. %s%n", deleteExtraDataSpace)); diff --git a/src/com/bytezone/diskbrowser/gui/MenuHandler.java b/src/com/bytezone/diskbrowser/gui/MenuHandler.java index 7c08176..760160d 100755 --- a/src/com/bytezone/diskbrowser/gui/MenuHandler.java +++ b/src/com/bytezone/diskbrowser/gui/MenuHandler.java @@ -49,6 +49,7 @@ class MenuHandler implements DiskSelectionListener, FileSelectionListener, QuitL private static final String PREFS_SHOW_HEADER = "showHeader"; private static final String PREFS_SHOW_CARET = "showCaret"; private static final String PREFS_SHOW_THEN = "showThen"; + private static final String PREFS_SHOW_XREF = "showXref"; private static final String PREFS_BLANK_AFTER_RETURN = "blankAfterReturn"; private static final String PREFS_DELETE_EXTRA_REM_SPACE = "deleteExtraRemSpace"; private static final String PREFS_DELETE_EXTRA_DATA_SPACE = "deleteExtraDataSpace"; @@ -136,6 +137,7 @@ class MenuHandler implements DiskSelectionListener, FileSelectionListener, QuitL final JMenuItem showHeaderItem = new JCheckBoxMenuItem ("Show header"); final JMenuItem showCaretItem = new JCheckBoxMenuItem ("Show caret"); final JMenuItem showThenItem = new JCheckBoxMenuItem ("Show THEN after IF"); + final JMenuItem showXrefItem = new JCheckBoxMenuItem ("Show Xref"); final JMenuItem blankAfterReturn = new JCheckBoxMenuItem ("Blank line after RETURN"); final JMenuItem deleteExtraRemSpace = new JCheckBoxMenuItem ("Delete extra REM space"); final JMenuItem deleteExtraDataSpace = @@ -234,6 +236,7 @@ class MenuHandler implements DiskSelectionListener, FileSelectionListener, QuitL applesoftMenu.add (onlyShowTargetLinesItem); applesoftMenu.add (showCaretItem); applesoftMenu.add (showThenItem); + applesoftMenu.add (showXrefItem); applesoftMenu.add (blankAfterReturn); applesoftMenu.add (deleteExtraRemSpace); applesoftMenu.add (deleteExtraDataSpace); @@ -294,6 +297,7 @@ class MenuHandler implements DiskSelectionListener, FileSelectionListener, QuitL showHeaderItem.addActionListener (basicPreferencesAction); showCaretItem.addActionListener (basicPreferencesAction); showThenItem.addActionListener (basicPreferencesAction); + showXrefItem.addActionListener (basicPreferencesAction); blankAfterReturn.addActionListener (basicPreferencesAction); deleteExtraRemSpace.addActionListener (basicPreferencesAction); deleteExtraDataSpace.addActionListener (basicPreferencesAction); @@ -340,6 +344,7 @@ class MenuHandler implements DiskSelectionListener, FileSelectionListener, QuitL basicPreferences.alignAssign = alignAssignItem.isSelected (); basicPreferences.showCaret = showCaretItem.isSelected (); basicPreferences.showThen = showThenItem.isSelected (); + basicPreferences.showXref = showXrefItem.isSelected (); basicPreferences.blankAfterReturn = blankAfterReturn.isSelected (); basicPreferences.deleteExtraRemSpace = deleteExtraRemSpace.isSelected (); basicPreferences.deleteExtraDataSpace = deleteExtraDataSpace.isSelected (); @@ -496,6 +501,7 @@ class MenuHandler implements DiskSelectionListener, FileSelectionListener, QuitL prefs.putBoolean (PREFS_ALIGN_ASSIGN, alignAssignItem.isSelected ()); prefs.putBoolean (PREFS_SHOW_CARET, showCaretItem.isSelected ()); prefs.putBoolean (PREFS_SHOW_THEN, showThenItem.isSelected ()); + prefs.putBoolean (PREFS_SHOW_XREF, showXrefItem.isSelected ()); prefs.putBoolean (PREFS_SHOW_HEADER, showHeaderItem.isSelected ()); prefs.putBoolean (PREFS_SHOW_TARGETS, showBasicTargetsItem.isSelected ()); prefs.putBoolean (PREFS_ONLY_SHOW_TARGETS, onlyShowTargetLinesItem.isSelected ()); @@ -545,6 +551,7 @@ class MenuHandler implements DiskSelectionListener, FileSelectionListener, QuitL alignAssignItem.setSelected (prefs.getBoolean (PREFS_ALIGN_ASSIGN, true)); showCaretItem.setSelected (prefs.getBoolean (PREFS_SHOW_CARET, false)); showThenItem.setSelected (prefs.getBoolean (PREFS_SHOW_THEN, true)); + showXrefItem.setSelected (prefs.getBoolean (PREFS_SHOW_XREF, false)); showHeaderItem.setSelected (prefs.getBoolean (PREFS_SHOW_HEADER, true)); showBasicTargetsItem.setSelected (prefs.getBoolean (PREFS_SHOW_TARGETS, false)); onlyShowTargetLinesItem