From c4b086a0967d8e5b9af944b2fa8b8223ce55ef11 Mon Sep 17 00:00:00 2001 From: Denis Molony Date: Fri, 5 Feb 2016 18:18:23 +1100 Subject: [PATCH] moved HexBlock to Infocom package --- .../diskbrowser/applefile/AbstractFile.java | 38 +- .../applefile/AssemblerProgram.java | 20 +- .../diskbrowser/infocom/Abbreviations.java | 110 ++-- .../bytezone/diskbrowser/infocom/Globals.java | 70 ++- .../bytezone/diskbrowser/infocom/Grammar.java | 556 +++++++++--------- .../bytezone/diskbrowser/infocom/Header.java | 218 +++---- .../infocom/InfocomAbstractFile.java | 60 ++ .../diskbrowser/infocom/ObjectManager.java | 142 ++--- .../bytezone/diskbrowser/infocom/Routine.java | 244 ++++---- 9 files changed, 742 insertions(+), 716 deletions(-) create mode 100644 src/com/bytezone/diskbrowser/infocom/InfocomAbstractFile.java diff --git a/src/com/bytezone/diskbrowser/applefile/AbstractFile.java b/src/com/bytezone/diskbrowser/applefile/AbstractFile.java index 2b33e7f..b11892e 100755 --- a/src/com/bytezone/diskbrowser/applefile/AbstractFile.java +++ b/src/com/bytezone/diskbrowser/applefile/AbstractFile.java @@ -1,8 +1,6 @@ package com.bytezone.diskbrowser.applefile; import java.awt.image.BufferedImage; -import java.util.ArrayList; -import java.util.List; import javax.swing.JComponent; import javax.swing.JPanel; @@ -16,7 +14,6 @@ public abstract class AbstractFile implements DataSource public byte[] buffer; AssemblerProgram assembler; protected BufferedImage image; - protected List hexBlocks = new ArrayList (); public AbstractFile (String name, byte[] buffer) { @@ -25,7 +22,7 @@ public abstract class AbstractFile implements DataSource } @Override - public String getText () // Override this to get a tailored text representation + public String getText () // Override this to get a tailored text representation { return "Name : " + name + "\n\nNo text description"; } @@ -35,31 +32,16 @@ public abstract class AbstractFile implements DataSource { if (buffer == null) return "No buffer"; + if (assembler == null) this.assembler = new AssemblerProgram (name, buffer, 0); + return assembler.getText (); } @Override public String getHexDump () { - if (hexBlocks.size () > 0) - { - StringBuilder text = new StringBuilder (); - - for (HexBlock hb : hexBlocks) - { - if (hb.title != null) - text.append (hb.title + "\n\n"); - text.append (HexFormatter.format (buffer, hb.ptr, hb.size) + "\n\n"); - } - - text.deleteCharAt (text.length () - 1); - text.deleteCharAt (text.length () - 1); - - return text.toString (); - } - if (buffer == null || buffer.length == 0) return "No buffer"; @@ -82,18 +64,4 @@ public abstract class AbstractFile implements DataSource JPanel panel = new JPanel (); return panel; } - - protected class HexBlock - { - public int ptr; - public int size; - public String title; - - public HexBlock (int ptr, int size, String title) - { - this.ptr = ptr; - this.size = size; - this.title = title; - } - } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/applefile/AssemblerProgram.java b/src/com/bytezone/diskbrowser/applefile/AssemblerProgram.java index 4b9c79d..ad169e8 100755 --- a/src/com/bytezone/diskbrowser/applefile/AssemblerProgram.java +++ b/src/com/bytezone/diskbrowser/applefile/AssemblerProgram.java @@ -45,28 +45,34 @@ public class AssemblerProgram extends AbstractFile @Override public String getHexDump () { - String text = super.getHexDump (); + // String text = super.getHexDump (); + String text = HexFormatter.format (buffer, 0, buffer.length, loadAddress); if (extraBuffer.length == 0) return text; - return text + "\n\n" - + HexFormatter.format (extraBuffer, 0, extraBuffer.length, buffer.length); + return text + "\n\n" + HexFormatter.format (extraBuffer, 0, extraBuffer.length, + loadAddress + buffer.length); } @Override public String getAssembler () { - String text = super.getAssembler (); + // String text = super.getAssembler (); + if (buffer == null) + return "No buffer"; + if (assembler == null) + this.assembler = new AssemblerProgram (name, buffer, loadAddress); + // return assembler.getText (); if (extraBuffer.length == 0) - return text; + return assembler.getText (); String extraName = String.format ("%s (extra)", name); AssemblerProgram assemblerProgram = - new AssemblerProgram (extraName, extraBuffer, buffer.length); + new AssemblerProgram (extraName, extraBuffer, loadAddress + buffer.length); - return text + "\n\n" + assemblerProgram.getText (); + return assembler.getText () + "\n\n" + assemblerProgram.getText (); } @Override diff --git a/src/com/bytezone/diskbrowser/infocom/Abbreviations.java b/src/com/bytezone/diskbrowser/infocom/Abbreviations.java index 3fcf555..6b92258 100755 --- a/src/com/bytezone/diskbrowser/infocom/Abbreviations.java +++ b/src/com/bytezone/diskbrowser/infocom/Abbreviations.java @@ -3,72 +3,70 @@ package com.bytezone.diskbrowser.infocom; import java.util.ArrayList; import java.util.List; -import com.bytezone.diskbrowser.applefile.AbstractFile; - -class Abbreviations extends AbstractFile +class Abbreviations extends InfocomAbstractFile { - List list; - Header header; - int dataPtr; - int dataSize; - int tablePtr; - int tableSize; + List list; + Header header; + int dataPtr; + int dataSize; + int tablePtr; + int tableSize; - public Abbreviations (Header header) - { - super ("Abbreviations", header.buffer); - this.header = header; + public Abbreviations (Header header) + { + super ("Abbreviations", header.buffer); + this.header = header; - dataPtr = header.getWord (header.abbreviationsTable) * 2; - dataSize = header.abbreviationsTable - dataPtr; - tablePtr = header.abbreviationsTable; - tableSize = header.objectTable - header.abbreviationsTable; + dataPtr = header.getWord (header.abbreviationsTable) * 2; + dataSize = header.abbreviationsTable - dataPtr; + tablePtr = header.abbreviationsTable; + tableSize = header.objectTable - header.abbreviationsTable; - // prepare hex dump - hexBlocks.add (new HexBlock (dataPtr, dataSize, "Abbreviations data:")); - hexBlocks.add (new HexBlock (tablePtr, tableSize, "Abbreviations table:")); - } + // prepare hex dump + hexBlocks.add (new HexBlock (dataPtr, dataSize, "Abbreviations data:")); + hexBlocks.add (new HexBlock (tablePtr, tableSize, "Abbreviations table:")); + } - private void populate () - { - System.out.println ("populating abbreviations"); - list = new ArrayList (); + private void populate () + { + System.out.println ("populating abbreviations"); + list = new ArrayList (); - for (int i = header.abbreviationsTable; i < header.objectTable; i += 2) - { - int j = header.getWord (i) * 2; - ZString zs = new ZString (buffer, j, header); - list.add (zs); - } - } + for (int i = header.abbreviationsTable; i < header.objectTable; i += 2) + { + int j = header.getWord (i) * 2; + ZString zs = new ZString (buffer, j, header); + list.add (zs); + } + } - public String getAbbreviation (int abbreviationNumber) - { - if (list == null) - populate (); - return list.get (abbreviationNumber).value; - } + public String getAbbreviation (int abbreviationNumber) + { + if (list == null) + populate (); + return list.get (abbreviationNumber).value; + } - @Override - public String getText () - { - if (list == null) - populate (); + @Override + public String getText () + { + if (list == null) + populate (); - StringBuilder text = new StringBuilder (); + StringBuilder text = new StringBuilder (); -// text.append (String.format ("Data address....%04X %d%n", dataPtr, dataPtr)); -// text.append (String.format ("Data size.......%04X %d%n", dataSize, dataSize)); -// text.append (String.format ("Table address...%04X %d%n", tablePtr, tablePtr)); -// text.append (String.format ("Table size......%04X %d (%d words)%n%n", tableSize, tableSize, -// (tableSize / 2))); + // text.append (String.format ("Data address....%04X %d%n", dataPtr, dataPtr)); + // text.append (String.format ("Data size.......%04X %d%n", dataSize, dataSize)); + // text.append (String.format ("Table address...%04X %d%n", tablePtr, tablePtr)); + // text.append (String.format ("Table size......%04X %d (%d words)%n%n", tableSize, tableSize, + // (tableSize / 2))); - int count = 0; - for (ZString word : list) - text.append (String.format ("%3d %s%n", count++, word.value)); - if (list.size () > 0) - text.deleteCharAt (text.length () - 1); + int count = 0; + for (ZString word : list) + text.append (String.format ("%3d %s%n", count++, word.value)); + if (list.size () > 0) + text.deleteCharAt (text.length () - 1); - return text.toString (); - } + return text.toString (); + } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/infocom/Globals.java b/src/com/bytezone/diskbrowser/infocom/Globals.java index f69d814..5eda775 100644 --- a/src/com/bytezone/diskbrowser/infocom/Globals.java +++ b/src/com/bytezone/diskbrowser/infocom/Globals.java @@ -1,44 +1,42 @@ package com.bytezone.diskbrowser.infocom; -import com.bytezone.diskbrowser.applefile.AbstractFile; - -class Globals extends AbstractFile +class Globals extends InfocomAbstractFile { - static final int TOTAL_GLOBALS = 240; - Header header; - int globalsPtr, globalsSize; - int arrayPtr, arraySize; + static final int TOTAL_GLOBALS = 240; + Header header; + int globalsPtr, globalsSize; + int arrayPtr, arraySize; - public Globals (Header header) - { - super ("Globals", header.buffer); - this.header = header; + public Globals (Header header) + { + super ("Globals", header.buffer); + this.header = header; - globalsPtr = header.globalsOffset; - globalsSize = TOTAL_GLOBALS * 2; - arrayPtr = globalsPtr + globalsSize; - arraySize = header.staticMemory - arrayPtr; + globalsPtr = header.globalsOffset; + globalsSize = TOTAL_GLOBALS * 2; + arrayPtr = globalsPtr + globalsSize; + arraySize = header.staticMemory - arrayPtr; - // add entries for AbstractFile.getHexDump () - hexBlocks.add (new HexBlock (globalsPtr, globalsSize, "Globals:")); - hexBlocks.add (new HexBlock (arrayPtr, arraySize, "Arrays:")); - } + // add entries for AbstractFile.getHexDump () + hexBlocks.add (new HexBlock (globalsPtr, globalsSize, "Globals:")); + hexBlocks.add (new HexBlock (arrayPtr, arraySize, "Arrays:")); + } - @Override - public String getText () - { - StringBuilder text = new StringBuilder (); - for (int i = 1; i <= TOTAL_GLOBALS; i++) - { - int value = header.getWord (globalsPtr + i * 2); - text.append (String.format ("G%03d %04X ", i, value)); - int address = value * 2; - if (address >= header.stringPointer && address < header.fileLength) - text.append (header.stringManager.stringAt (address) + "\n"); - else - text.append (String.format ("%,6d%n", value)); - } - text.deleteCharAt (text.length () - 1); - return text.toString (); - } + @Override + public String getText () + { + StringBuilder text = new StringBuilder (); + for (int i = 1; i <= TOTAL_GLOBALS; i++) + { + int value = header.getWord (globalsPtr + i * 2); + text.append (String.format ("G%03d %04X ", i, value)); + int address = value * 2; + if (address >= header.stringPointer && address < header.fileLength) + text.append (header.stringManager.stringAt (address) + "\n"); + else + text.append (String.format ("%,6d%n", value)); + } + text.deleteCharAt (text.length () - 1); + return text.toString (); + } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/infocom/Grammar.java b/src/com/bytezone/diskbrowser/infocom/Grammar.java index 8bcf191..a4fcc52 100644 --- a/src/com/bytezone/diskbrowser/infocom/Grammar.java +++ b/src/com/bytezone/diskbrowser/infocom/Grammar.java @@ -1,331 +1,327 @@ package com.bytezone.diskbrowser.infocom; -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; +import java.util.*; import com.bytezone.diskbrowser.HexFormatter; -import com.bytezone.diskbrowser.applefile.AbstractFile; -class Grammar extends AbstractFile +class Grammar extends InfocomAbstractFile { - private static final int SENTENCE_LENGTH = 8; - Header header; - int indexPtr, indexSize; - int tablePtr, tableSize; - int actionPtr, actionSize; - int preActionPtr, preActionSize; - int prepositionPtr, prepositionSize; - int indexEntries; - int totalPrepositions; - int padding; + private static final int SENTENCE_LENGTH = 8; + Header header; + int indexPtr, indexSize; + int tablePtr, tableSize; + int actionPtr, actionSize; + int preActionPtr, preActionSize; + int prepositionPtr, prepositionSize; + int indexEntries; + int totalPrepositions; + int padding; - List sentenceGroups = new ArrayList (); - Map> actionList = new TreeMap> (); + List sentenceGroups = new ArrayList (); + Map> actionList = new TreeMap> (); - List actionRoutines = new ArrayList (); - List preActionRoutines = new ArrayList (); + List actionRoutines = new ArrayList (); + List preActionRoutines = new ArrayList (); - public Grammar (String name, byte[] buffer, Header header) - { - super (name, buffer); - this.header = header; + public Grammar (String name, byte[] buffer, Header header) + { + super (name, buffer); + this.header = header; - indexPtr = header.staticMemory; // start of the index - tablePtr = header.getWord (indexPtr); // start of the data (end of the index) - indexSize = tablePtr - indexPtr; - indexEntries = indexSize / 2; + indexPtr = header.staticMemory; // start of the index + tablePtr = header.getWord (indexPtr); // start of the data (end of the index) + indexSize = tablePtr - indexPtr; + indexEntries = indexSize / 2; - padding = getPadding (); + padding = getPadding (); - int lastEntry = header.getWord (tablePtr - 2); // address of the last data entry - tableSize = lastEntry + getRecordLength (lastEntry) - tablePtr; // uses padding - actionPtr = tablePtr + tableSize; // start of the action routines - actionSize = getTotalActions () * 2; // uses padding + int lastEntry = header.getWord (tablePtr - 2); // address of the last data entry + tableSize = lastEntry + getRecordLength (lastEntry) - tablePtr; // uses padding + actionPtr = tablePtr + tableSize; // start of the action routines + actionSize = getTotalActions () * 2; // uses padding - preActionSize = actionSize; - preActionPtr = actionPtr + actionSize; - prepositionPtr = preActionPtr + preActionSize; + preActionSize = actionSize; + preActionPtr = actionPtr + actionSize; + prepositionPtr = preActionPtr + preActionSize; - totalPrepositions = header.getWord (prepositionPtr); - prepositionSize = totalPrepositions * 4 + 2; + totalPrepositions = header.getWord (prepositionPtr); + prepositionSize = totalPrepositions * 4 + 2; - if (false) - { - System.out.printf ("indexPtr %,8d %4X%n", indexPtr, indexPtr); - System.out.printf ("indexSize %,8d%n", indexSize); - System.out.printf ("indexEntries %,8d%n", indexEntries); - System.out.printf ("tablePtr %,8d %4X%n", tablePtr, tablePtr); - System.out.printf ("tableSize %,8d%n", tableSize); - System.out.printf ("actionPtr %,8d %4X%n", actionPtr, actionPtr); - System.out.printf ("actionSize %,8d%n", actionSize); - System.out.printf ("actionEntries %,8d%n", actionSize / 2); - System.out.printf ("preActionPtr %,8d %4X%n", preActionPtr, preActionPtr); - System.out.printf ("preActionSize %,8d%n", preActionSize); - System.out.printf ("prepPtr %,8d %4X%n", prepositionPtr, prepositionPtr); - System.out.printf ("prepSize %,8d%n", prepositionSize); - System.out.printf ("totPreps %,8d%n", totalPrepositions); - } + if (false) + { + System.out.printf ("indexPtr %,8d %4X%n", indexPtr, indexPtr); + System.out.printf ("indexSize %,8d%n", indexSize); + System.out.printf ("indexEntries %,8d%n", indexEntries); + System.out.printf ("tablePtr %,8d %4X%n", tablePtr, tablePtr); + System.out.printf ("tableSize %,8d%n", tableSize); + System.out.printf ("actionPtr %,8d %4X%n", actionPtr, actionPtr); + System.out.printf ("actionSize %,8d%n", actionSize); + System.out.printf ("actionEntries %,8d%n", actionSize / 2); + System.out.printf ("preActionPtr %,8d %4X%n", preActionPtr, preActionPtr); + System.out.printf ("preActionSize %,8d%n", preActionSize); + System.out.printf ("prepPtr %,8d %4X%n", prepositionPtr, prepositionPtr); + System.out.printf ("prepSize %,8d%n", prepositionSize); + System.out.printf ("totPreps %,8d%n", totalPrepositions); + } - // add entries for AbstractFile.getHexDump () - hexBlocks.add (new HexBlock (indexPtr, indexSize, "Index:")); - hexBlocks.add (new HexBlock (tablePtr, tableSize, "Grammar data:")); - hexBlocks.add (new HexBlock (actionPtr, actionSize, "Action routines:")); - hexBlocks.add (new HexBlock (preActionPtr, preActionSize, "Pre-action routines:")); - hexBlocks.add (new HexBlock (prepositionPtr, prepositionSize, "Preposition table:")); + // add entries for AbstractFile.getHexDump () + hexBlocks.add (new HexBlock (indexPtr, indexSize, "Index:")); + hexBlocks.add (new HexBlock (tablePtr, tableSize, "Grammar data:")); + hexBlocks.add (new HexBlock (actionPtr, actionSize, "Action routines:")); + hexBlocks.add (new HexBlock (preActionPtr, preActionSize, "Pre-action routines:")); + hexBlocks.add (new HexBlock (prepositionPtr, prepositionSize, "Preposition table:")); - // create SentenceGroup and Sentence objects and action lists - int count = 255; - for (int i = 0; i < indexEntries; i++) - { - int offset = header.getWord (indexPtr + i * 2); - SentenceGroup sg = new SentenceGroup (count--, offset); - sentenceGroups.add (sg); - for (Sentence sentence : sg) - { - // add to hashmap - if (!actionList.containsKey (sentence.actionId)) - actionList.put (sentence.actionId, new ArrayList ()); - actionList.get (sentence.actionId).add (sentence); - // add to pre-action routine list - if (sentence.preActionRoutine > 0 - && !preActionRoutines.contains (sentence.preActionRoutine)) - preActionRoutines.add (sentence.preActionRoutine); - // add to action routine list - if (sentence.actionRoutine > 0 && !actionRoutines.contains (sentence.actionRoutine)) - actionRoutines.add (sentence.actionRoutine); - } - } - Collections.sort (actionRoutines); - Collections.sort (preActionRoutines); - } + // create SentenceGroup and Sentence objects and action lists + int count = 255; + for (int i = 0; i < indexEntries; i++) + { + int offset = header.getWord (indexPtr + i * 2); + SentenceGroup sg = new SentenceGroup (count--, offset); + sentenceGroups.add (sg); + for (Sentence sentence : sg) + { + // add to hashmap + if (!actionList.containsKey (sentence.actionId)) + actionList.put (sentence.actionId, new ArrayList ()); + actionList.get (sentence.actionId).add (sentence); + // add to pre-action routine list + if (sentence.preActionRoutine > 0 + && !preActionRoutines.contains (sentence.preActionRoutine)) + preActionRoutines.add (sentence.preActionRoutine); + // add to action routine list + if (sentence.actionRoutine > 0 + && !actionRoutines.contains (sentence.actionRoutine)) + actionRoutines.add (sentence.actionRoutine); + } + } + Collections.sort (actionRoutines); + Collections.sort (preActionRoutines); + } - private int getPadding () - { - // calculate record padding size (Zork has 1 byte padding, Planetfall has 0) - int r1 = header.getWord (indexPtr); - int r2 = header.getWord (indexPtr + 2); - int sentences = header.getByte (r1); - return r2 - r1 - (sentences * SENTENCE_LENGTH) - 1; - } + private int getPadding () + { + // calculate record padding size (Zork has 1 byte padding, Planetfall has 0) + int r1 = header.getWord (indexPtr); + int r2 = header.getWord (indexPtr + 2); + int sentences = header.getByte (r1); + return r2 - r1 - (sentences * SENTENCE_LENGTH) - 1; + } - private int getRecordLength (int recordPtr) - { - return (buffer[recordPtr] & 0xFF) * SENTENCE_LENGTH + padding + 1; - } + private int getRecordLength (int recordPtr) + { + return (buffer[recordPtr] & 0xFF) * SENTENCE_LENGTH + padding + 1; + } - private int getTotalActions () - { - // loop through each record in each index entry, and find the highest action number - int ptr = tablePtr; - int highest = 0; - for (int i = 0; i < indexEntries; i++) - { - int totSentences = buffer[ptr++]; - for (int j = 0; j < totSentences; j++) - { - int val = buffer[ptr + 7] & 0xFF; - if (val > highest) - highest = val; - ptr += SENTENCE_LENGTH; - } - ptr += padding; // could be zero or one - } - return highest + 1; // zero-based, so increment it - } + private int getTotalActions () + { + // loop through each record in each index entry, and find the highest action number + int ptr = tablePtr; + int highest = 0; + for (int i = 0; i < indexEntries; i++) + { + int totSentences = buffer[ptr++]; + for (int j = 0; j < totSentences; j++) + { + int val = buffer[ptr + 7] & 0xFF; + if (val > highest) + highest = val; + ptr += SENTENCE_LENGTH; + } + ptr += padding; // could be zero or one + } + return highest + 1; // zero-based, so increment it + } - public List getActionRoutines () - { - List routines = new ArrayList (); - routines.addAll (actionRoutines); - routines.addAll (preActionRoutines); - return routines; - } + public List getActionRoutines () + { + List routines = new ArrayList (); + routines.addAll (actionRoutines); + routines.addAll (preActionRoutines); + return routines; + } - @Override - public String getText () - { - String line = - "-----------------------------------------------------" - + "-----------------------------------------------------------\n"; - StringBuilder text = - new StringBuilder (sentenceGroups.size () + " Grammar tables\n==================\n\n"); + @Override + public String getText () + { + String line = "-----------------------------------------------------" + + "-----------------------------------------------------------\n"; + StringBuilder text = new StringBuilder ( + sentenceGroups.size () + " Grammar tables\n==================\n\n"); - // add the sentences in their original SentenceGroup sequence - for (SentenceGroup sg : sentenceGroups) - text.append (sg + "\n" + line); + // add the sentences in their original SentenceGroup sequence + for (SentenceGroup sg : sentenceGroups) + text.append (sg + "\n" + line); - text.append ("\n" + actionList.size () + " Action groups\n=================\n\n"); + text.append ("\n" + actionList.size () + " Action groups\n=================\n\n"); - // add the sentences in their actionId sequence - for (List list : actionList.values ()) - { - for (Sentence sentence : list) - text.append (sentence + "\n"); - text.append (line); - } + // add the sentences in their actionId sequence + for (List list : actionList.values ()) + { + for (Sentence sentence : list) + text.append (sentence + "\n"); + text.append (line); + } - text.append ("\n" + preActionRoutines.size () - + " Pre-action routines\n======================\n\n"); + text.append ("\n" + preActionRoutines.size () + + " Pre-action routines\n======================\n\n"); - // add sentences in pre-action routine sequence - for (Integer routine : preActionRoutines) - { - for (Sentence sentence : getSentences (routine)) - text.append (sentence + "\n"); - text.append (line); - } + // add sentences in pre-action routine sequence + for (Integer routine : preActionRoutines) + { + for (Sentence sentence : getSentences (routine)) + text.append (sentence + "\n"); + text.append (line); + } - text.append ("\n" + actionRoutines.size () + " Action routines\n===================\n\n"); + text.append ("\n" + actionRoutines.size () + + " Action routines\n===================\n\n"); - // add sentences in action routine sequence - for (Integer routine : actionRoutines) - { - for (Sentence sentence : getSentences (routine)) - text.append (sentence + "\n"); - text.append (line); - } + // add sentences in action routine sequence + for (Integer routine : actionRoutines) + { + for (Sentence sentence : getSentences (routine)) + text.append (sentence + "\n"); + text.append (line); + } - text.append ("\n" + totalPrepositions + " Prepositions\n===============\n\n"); - text.append (HexFormatter.getHexString (buffer, prepositionPtr, 2) + "\n"); - for (int i = 0, ptr = prepositionPtr + 2; i < totalPrepositions; i++, ptr += 4) - { - text.append (HexFormatter.getHexString (buffer, ptr, 4) + " "); - int id = header.getByte (ptr + 3); - List preps = header.dictionary.getPrepositions (id); - String prepString = makeWordBlock (preps); - text.append (prepString + "\n"); - } + text.append ("\n" + totalPrepositions + " Prepositions\n===============\n\n"); + text.append (HexFormatter.getHexString (buffer, prepositionPtr, 2) + "\n"); + for (int i = 0, ptr = prepositionPtr + 2; i < totalPrepositions; i++, ptr += 4) + { + text.append (HexFormatter.getHexString (buffer, ptr, 4) + " "); + int id = header.getByte (ptr + 3); + List preps = header.dictionary.getPrepositions (id); + String prepString = makeWordBlock (preps); + text.append (prepString + "\n"); + } - text.deleteCharAt (text.length () - 1); - return text.toString (); - } + text.deleteCharAt (text.length () - 1); + return text.toString (); + } - private List getSentences (int routine) - { - List sentences = new ArrayList (); + private List getSentences (int routine) + { + List sentences = new ArrayList (); - for (SentenceGroup sg : sentenceGroups) - for (Sentence s : sg.sentences) - if (s.actionRoutine == routine || s.preActionRoutine == routine) - sentences.add (s); + for (SentenceGroup sg : sentenceGroups) + for (Sentence s : sg.sentences) + if (s.actionRoutine == routine || s.preActionRoutine == routine) + sentences.add (s); - return sentences; - } + return sentences; + } - private String makeWordBlock (List words) - { - StringBuilder text = new StringBuilder ("["); - if (words.size () > 0) - { - for (String word : words) - text.append (word + ", "); - text.deleteCharAt (text.length () - 1); - text.deleteCharAt (text.length () - 1); - } - else - text.append ("** not found **"); - text.append ("]"); - return text.toString (); - } + private String makeWordBlock (List words) + { + StringBuilder text = new StringBuilder ("["); + if (words.size () > 0) + { + for (String word : words) + text.append (word + ", "); + text.deleteCharAt (text.length () - 1); + text.deleteCharAt (text.length () - 1); + } + else + text.append ("** not found **"); + text.append ("]"); + return text.toString (); + } - private class SentenceGroup implements Iterable - { - int startPtr; - int id; - List sentences = new ArrayList (); - String verbString; // list of synonyms inside [] + private class SentenceGroup implements Iterable + { + int startPtr; + int id; + List sentences = new ArrayList (); + String verbString; // list of synonyms inside [] - public SentenceGroup (int id, int ptr) - { - this.startPtr = ptr; - this.id = id; + public SentenceGroup (int id, int ptr) + { + this.startPtr = ptr; + this.id = id; - int records = buffer[ptr] & 0xFF; - verbString = makeWordBlock (header.dictionary.getVerbs (id)); + int records = buffer[ptr] & 0xFF; + verbString = makeWordBlock (header.dictionary.getVerbs (id)); - for (int j = 0, offset = startPtr + 1; j < records; j++, offset += SENTENCE_LENGTH) - sentences.add (new Sentence (offset, this)); - } + for (int j = 0, offset = startPtr + 1; j < records; j++, offset += SENTENCE_LENGTH) + sentences.add (new Sentence (offset, this)); + } - @Override - public String toString () - { - StringBuilder text = new StringBuilder (); - for (Sentence sentence : sentences) - text.append (sentence + "\n"); - text.deleteCharAt (text.length () - 1); - return text.toString (); - } + @Override + public String toString () + { + StringBuilder text = new StringBuilder (); + for (Sentence sentence : sentences) + text.append (sentence + "\n"); + text.deleteCharAt (text.length () - 1); + return text.toString (); + } - @Override - public Iterator iterator () - { - return sentences.iterator (); - } - } + @Override + public Iterator iterator () + { + return sentences.iterator (); + } + } - private class Sentence - { - int startPtr; - SentenceGroup parent; - int actionId; - int actionRoutine; // mandatory - int preActionRoutine; // optional - String sentenceText; + private class Sentence + { + int startPtr; + SentenceGroup parent; + int actionId; + int actionRoutine; // mandatory + int preActionRoutine; // optional + String sentenceText; - public Sentence (int ptr, SentenceGroup parent) - { - this.startPtr = ptr; - this.parent = parent; + public Sentence (int ptr, SentenceGroup parent) + { + this.startPtr = ptr; + this.parent = parent; - // byte 0 contains the number of objects in the sentence - int totObjects = buffer[ptr++] & 0xFF; // 0-2 + // byte 0 contains the number of objects in the sentence + int totObjects = buffer[ptr++] & 0xFF; // 0-2 - // build the sentence text from bytes 1-2 - StringBuilder sentence = new StringBuilder (); - for (int k = 0; k < totObjects; k++) - { - int b = buffer[ptr++] & 0xFF; - if (b > 0) - sentence.append (" " + getPrep (b)); - sentence.append (" OBJ"); - } - sentenceText = sentence.toString (); + // build the sentence text from bytes 1-2 + StringBuilder sentence = new StringBuilder (); + for (int k = 0; k < totObjects; k++) + { + int b = buffer[ptr++] & 0xFF; + if (b > 0) + sentence.append (" " + getPrep (b)); + sentence.append (" OBJ"); + } + sentenceText = sentence.toString (); - // do something with bytes 3-6 - // ... what that is I have no idea + // do something with bytes 3-6 + // ... what that is I have no idea - // get action pointer from byte 7 - actionId = buffer[startPtr + 7] & 0xFF; - int targetOffset = actionId * 2; // index into the action and pre-action blocks - actionRoutine = header.getWord (actionPtr + targetOffset) * 2; - preActionRoutine = header.getWord (preActionPtr + targetOffset) * 2; - } + // get action pointer from byte 7 + actionId = buffer[startPtr + 7] & 0xFF; + int targetOffset = actionId * 2; // index into the action and pre-action blocks + actionRoutine = header.getWord (actionPtr + targetOffset) * 2; + preActionRoutine = header.getWord (preActionPtr + targetOffset) * 2; + } - private String getPrep (int value) - { - int offset = prepositionPtr + 2 + (totalPrepositions - (255 - value) - 1) * 4; - int address = header.getWord (offset); - return header.dictionary.wordAt (address); - } + private String getPrep (int value) + { + int offset = prepositionPtr + 2 + (totalPrepositions - (255 - value) - 1) * 4; + int address = header.getWord (offset); + return header.dictionary.wordAt (address); + } - private String getText () - { - return parent.verbString + " " + sentenceText; - } + private String getText () + { + return parent.verbString + " " + sentenceText; + } - @Override - public String toString () - { - StringBuilder text = new StringBuilder (String.format ("%3d %04X ", parent.id, startPtr)); - text.append (HexFormatter.getHexString (buffer, startPtr, SENTENCE_LENGTH)); - String r1 = preActionRoutine == 0 ? "" : String.format ("R:%05X", preActionRoutine); - text.append (String.format (" %-7s R:%05X %s", r1, actionRoutine, getText ())); - return text.toString (); - } - } + @Override + public String toString () + { + StringBuilder text = + new StringBuilder (String.format ("%3d %04X ", parent.id, startPtr)); + text.append (HexFormatter.getHexString (buffer, startPtr, SENTENCE_LENGTH)); + String r1 = preActionRoutine == 0 ? "" : String.format ("R:%05X", preActionRoutine); + text.append (String.format (" %-7s R:%05X %s", r1, actionRoutine, getText ())); + return text.toString (); + } + } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/infocom/Header.java b/src/com/bytezone/diskbrowser/infocom/Header.java index ababa29..8e42256 100755 --- a/src/com/bytezone/diskbrowser/infocom/Header.java +++ b/src/com/bytezone/diskbrowser/infocom/Header.java @@ -2,135 +2,137 @@ package com.bytezone.diskbrowser.infocom; import java.io.File; -import com.bytezone.diskbrowser.applefile.AbstractFile; - -class Header extends AbstractFile +class Header extends InfocomAbstractFile { - final String[] propertyNames = new String[32]; + final String[] propertyNames = new String[32]; - File file; - int version; - int highMemory; - int programCounter; - int dictionaryOffset; - int objectTable; - int globalsOffset; - int staticMemory; - int abbreviationsTable; - int fileLength; - int checksum; - int stringPointer; + File file; + int version; + int highMemory; + int programCounter; + int dictionaryOffset; + int objectTable; + int globalsOffset; + int staticMemory; + int abbreviationsTable; + int fileLength; + int checksum; + int stringPointer; - Abbreviations abbreviations; - Dictionary dictionary; - ObjectManager objectManager; - StringManager stringManager; - CodeManager codeManager; - Globals globals; - Grammar grammar; + Abbreviations abbreviations; + Dictionary dictionary; + ObjectManager objectManager; + StringManager stringManager; + CodeManager codeManager; + Globals globals; + Grammar grammar; - public Header (String name, byte[] buffer, File file) - { - super (name, buffer); - this.file = file; + public Header (String name, byte[] buffer, File file) + { + super (name, buffer); + this.file = file; - version = getByte (0); - highMemory = getWord (4); - programCounter = getWord (6); - dictionaryOffset = getWord (8); - objectTable = getWord (10); - globalsOffset = getWord (12); - staticMemory = getWord (14); - abbreviationsTable = getWord (24); - checksum = getWord (28); - fileLength = getWord (26) * 2; + version = getByte (0); + highMemory = getWord (4); + programCounter = getWord (6); + dictionaryOffset = getWord (8); + objectTable = getWord (10); + globalsOffset = getWord (12); + staticMemory = getWord (14); + abbreviationsTable = getWord (24); + checksum = getWord (28); + fileLength = getWord (26) * 2; - if (fileLength == 0) - fileLength = buffer.length; + if (fileLength == 0) + fileLength = buffer.length; - // do the basic managers - abbreviations = new Abbreviations (this); - dictionary = new Dictionary (this); - globals = new Globals (this); // may display ZStrings + // do the basic managers + abbreviations = new Abbreviations (this); + dictionary = new Dictionary (this); + globals = new Globals (this); // may display ZStrings - // set up an empty object to store Routines in - codeManager = new CodeManager (this); + // set up an empty object to store Routines in + codeManager = new CodeManager (this); - grammar = new Grammar ("Grammar", buffer, this); + grammar = new Grammar ("Grammar", buffer, this); - // add all the ZObjects, and analyse them to find stringPtr, DICT etc. - objectManager = new ObjectManager (this); + // add all the ZObjects, and analyse them to find stringPtr, DICT etc. + objectManager = new ObjectManager (this); - // add all the ZStrings - stringManager = new StringManager ("Strings", buffer, this); + // add all the ZStrings + stringManager = new StringManager ("Strings", buffer, this); - codeManager.addRoutine (programCounter - 1, 0); - codeManager.addActionRoutines (); // obtained from Grammar - codeManager.addCodeRoutines (); // obtained from Object properties - codeManager.addMissingRoutines (); // requires stringPtr to be set + codeManager.addRoutine (programCounter - 1, 0); + codeManager.addActionRoutines (); // obtained from Grammar + codeManager.addCodeRoutines (); // obtained from Object properties + codeManager.addMissingRoutines (); // requires stringPtr to be set - // add entries for AbstractFile.getHexDump () - hexBlocks.add (new HexBlock (0, 64, "Header data:")); - } + // add entries for AbstractFile.getHexDump () + hexBlocks.add (new HexBlock (0, 64, "Header data:")); + } - public String getAbbreviation (int index) - { - return abbreviations.getAbbreviation (index); - } + public String getAbbreviation (int index) + { + return abbreviations.getAbbreviation (index); + } - public boolean containsWordAt (int address) - { - return dictionary.containsWordAt (address); - } + public boolean containsWordAt (int address) + { + return dictionary.containsWordAt (address); + } - public String wordAt (int address) - { - return dictionary.wordAt (address); - } + public String wordAt (int address) + { + return dictionary.wordAt (address); + } - @Override - public String getText () - { - StringBuilder text = new StringBuilder (); + @Override + public String getText () + { + StringBuilder text = new StringBuilder (); - text.append (String.format ("Disk name %s%n", file.getName ())); - text.append (String.format ("Version %d%n", version)); - text.append ("\nDynamic memory:\n"); - text.append (String.format (" Abbreviation table %04X %,6d%n", abbreviationsTable, - abbreviationsTable)); - text.append (String.format (" Objects table %04X %,6d%n", objectTable, objectTable)); - text.append (String.format (" Global variables %04X %,6d%n", globalsOffset, - globalsOffset)); + text.append (String.format ("Disk name %s%n", file.getName ())); + text.append (String.format ("Version %d%n", version)); + text.append ("\nDynamic memory:\n"); + text.append (String.format (" Abbreviation table %04X %,6d%n", + abbreviationsTable, abbreviationsTable)); + text.append (String.format (" Objects table %04X %,6d%n", objectTable, + objectTable)); + text.append (String.format (" Global variables %04X %,6d%n", globalsOffset, + globalsOffset)); - text.append ("\nStatic memory:\n"); - text.append (String - .format (" Grammar table etc %04X %,6d%n", staticMemory, staticMemory)); - text.append (String.format (" Dictionary %04X %,6d%n", dictionaryOffset, - dictionaryOffset)); - text.append ("\nHigh memory:\n"); - text.append (String.format (" ZCode %04X %,6d%n", highMemory, highMemory)); - text.append (String.format (" Program counter %04X %,6d%n", programCounter, - programCounter)); - text.append (String.format ("\nFile length %05X %,6d%n", fileLength, fileLength)); - text.append (String.format ("Checksum %04X %,6d%n", checksum, checksum)); - text.append (String.format ("%nZString offset %05X %,6d%n", stringPointer, - stringPointer)); + text.append ("\nStatic memory:\n"); + text.append (String.format (" Grammar table etc %04X %,6d%n", staticMemory, + staticMemory)); + text.append (String.format (" Dictionary %04X %,6d%n", dictionaryOffset, + dictionaryOffset)); + text.append ("\nHigh memory:\n"); + text.append (String.format (" ZCode %04X %,6d%n", highMemory, + highMemory)); + text.append (String.format (" Program counter %04X %,6d%n", programCounter, + programCounter)); + text.append (String.format ("\nFile length %05X %,6d%n", fileLength, + fileLength)); + text.append (String.format ("Checksum %04X %,6d%n", checksum, + checksum)); + text.append (String.format ("%nZString offset %05X %,6d%n", stringPointer, + stringPointer)); - text.append (String.format ("Total strings %d%n", stringManager.strings - .size ())); - text.append (String.format ("Total objects %d%n", objectManager.list - .size ())); + text.append (String.format ("Total strings %d%n", + stringManager.strings.size ())); + text.append (String.format ("Total objects %d%n", + objectManager.list.size ())); - return text.toString (); - } + return text.toString (); + } - int getByte (int offset) - { - return buffer[offset] & 0xFF; - } + int getByte (int offset) + { + return buffer[offset] & 0xFF; + } - int getWord (int offset) - { - return ((buffer[offset] << 8) & 0xFF00) | ((buffer[offset + 1]) & 0xFF); - } + int getWord (int offset) + { + return ((buffer[offset] << 8) & 0xFF00) | ((buffer[offset + 1]) & 0xFF); + } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/infocom/InfocomAbstractFile.java b/src/com/bytezone/diskbrowser/infocom/InfocomAbstractFile.java new file mode 100644 index 0000000..3db1ba8 --- /dev/null +++ b/src/com/bytezone/diskbrowser/infocom/InfocomAbstractFile.java @@ -0,0 +1,60 @@ +package com.bytezone.diskbrowser.infocom; + +import java.util.ArrayList; +import java.util.List; + +import com.bytezone.diskbrowser.HexFormatter; +import com.bytezone.diskbrowser.applefile.AbstractFile; + +public class InfocomAbstractFile extends AbstractFile +{ + protected List hexBlocks = new ArrayList (); + + public InfocomAbstractFile (String name, byte[] buffer) + { + super (name, buffer); + } + + @Override + public String getHexDump () + { + if (hexBlocks.size () > 0) + { + StringBuilder text = new StringBuilder (); + + for (HexBlock hb : hexBlocks) + { + if (hb.title != null) + text.append (hb.title + "\n\n"); + text.append (HexFormatter.format (buffer, hb.ptr, hb.size) + "\n\n"); + } + + text.deleteCharAt (text.length () - 1); + text.deleteCharAt (text.length () - 1); + + return text.toString (); + } + + if (buffer == null || buffer.length == 0) + return "No buffer"; + + if (buffer.length <= 99999) + return HexFormatter.format (buffer, 0, buffer.length); + + return HexFormatter.format (buffer, 0, 99999); + } + + protected class HexBlock + { + public int ptr; + public int size; + public String title; + + public HexBlock (int ptr, int size, String title) + { + this.ptr = ptr; + this.size = size; + this.title = title; + } + } +} \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/infocom/ObjectManager.java b/src/com/bytezone/diskbrowser/infocom/ObjectManager.java index 7b5b5e2..5a78288 100755 --- a/src/com/bytezone/diskbrowser/infocom/ObjectManager.java +++ b/src/com/bytezone/diskbrowser/infocom/ObjectManager.java @@ -6,91 +6,91 @@ import java.util.List; import javax.swing.tree.DefaultMutableTreeNode; -import com.bytezone.diskbrowser.applefile.AbstractFile; import com.bytezone.diskbrowser.disk.DefaultAppleFileSource; import com.bytezone.diskbrowser.disk.FormattedDisk; -class ObjectManager extends AbstractFile implements Iterable +class ObjectManager extends InfocomAbstractFile implements Iterable { - Header header; - List list; - int defaultsPtr, defaultsSize; - int tablePtr, tableSize; - int propertyPtr, propertySize; - ObjectAnalyser analyser; + Header header; + List list; + int defaultsPtr, defaultsSize; + int tablePtr, tableSize; + int propertyPtr, propertySize; + ObjectAnalyser analyser; - public ObjectManager (Header header) - { - super ("Objects", header.buffer); - this.header = header; + public ObjectManager (Header header) + { + super ("Objects", header.buffer); + this.header = header; - defaultsPtr = header.objectTable; - defaultsSize = 62; - tablePtr = header.objectTable + 62; - propertyPtr = header.getWord (tablePtr + 7); - propertySize = header.globalsOffset - propertyPtr; - tableSize = (propertyPtr - tablePtr); - int totalObjects = tableSize / ZObject.HEADER_SIZE; - list = new ArrayList (tableSize); + defaultsPtr = header.objectTable; + defaultsSize = 62; + tablePtr = header.objectTable + 62; + propertyPtr = header.getWord (tablePtr + 7); + propertySize = header.globalsOffset - propertyPtr; + tableSize = (propertyPtr - tablePtr); + int totalObjects = tableSize / ZObject.HEADER_SIZE; + list = new ArrayList (tableSize); - for (int objectNo = 0; objectNo < totalObjects; objectNo++) - list.add (new ZObject (null, buffer, tablePtr + objectNo * ZObject.HEADER_SIZE, objectNo + 1, - header)); + for (int objectNo = 0; objectNo < totalObjects; objectNo++) + list.add (new ZObject (null, buffer, tablePtr + objectNo * ZObject.HEADER_SIZE, + objectNo + 1, header)); - // analyse objects - set stringPtr etc. - analyser = new ObjectAnalyser (header, this); + // analyse objects - set stringPtr etc. + analyser = new ObjectAnalyser (header, this); - // add entries for AbstractFile.getHexDump () - hexBlocks.add (new HexBlock (defaultsPtr, defaultsSize, "Property defaults:")); - hexBlocks.add (new HexBlock (tablePtr, tableSize, "Objects table:")); - hexBlocks.add (new HexBlock (propertyPtr, propertySize, "Properties:")); - } + // add entries for AbstractFile.getHexDump () + hexBlocks.add (new HexBlock (defaultsPtr, defaultsSize, "Property defaults:")); + hexBlocks.add (new HexBlock (tablePtr, tableSize, "Objects table:")); + hexBlocks.add (new HexBlock (propertyPtr, propertySize, "Properties:")); + } - public void addNodes (DefaultMutableTreeNode root, FormattedDisk disk) - { - root.setAllowsChildren (true); + public void addNodes (DefaultMutableTreeNode root, FormattedDisk disk) + { + root.setAllowsChildren (true); - for (ZObject zo : list) - if (zo.parent == 0) - buildObjectTree (zo, root, disk); - } + for (ZObject zo : list) + if (zo.parent == 0) + buildObjectTree (zo, root, disk); + } - private void buildObjectTree (ZObject object, DefaultMutableTreeNode parentNode, - FormattedDisk disk) - { - DefaultMutableTreeNode child = - new DefaultMutableTreeNode (new DefaultAppleFileSource (object.name, object, disk)); - parentNode.add (child); - if (object.sibling > 0) - buildObjectTree (header.objectManager.list.get (object.sibling - 1), parentNode, disk); - if (object.child > 0) - buildObjectTree (header.objectManager.list.get (object.child - 1), child, disk); - else - child.setAllowsChildren (false); - } + private void buildObjectTree (ZObject object, DefaultMutableTreeNode parentNode, + FormattedDisk disk) + { + DefaultMutableTreeNode child = new DefaultMutableTreeNode ( + new DefaultAppleFileSource (object.name, object, disk)); + parentNode.add (child); + if (object.sibling > 0) + buildObjectTree (header.objectManager.list.get (object.sibling - 1), parentNode, + disk); + if (object.child > 0) + buildObjectTree (header.objectManager.list.get (object.child - 1), child, disk); + else + child.setAllowsChildren (false); + } - public List getCodeRoutines () - { - return analyser.routines; - } + public List getCodeRoutines () + { + return analyser.routines; + } - @Override - public String getText () - { - StringBuilder text = - new StringBuilder (" # Attributes Pr Sb Ch Prop Title\n--- -----------" - + " -- -- -- ----- -----------------------------\n"); + @Override + public String getText () + { + StringBuilder text = + new StringBuilder (" # Attributes Pr Sb Ch Prop Title\n--- -----------" + + " -- -- -- ----- -----------------------------\n"); - int objectNumber = 0; - for (ZObject zo : list) - text.append (String.format ("%3d %s%n", ++objectNumber, zo)); - text.deleteCharAt (text.length () - 1); - return text.toString (); - } + int objectNumber = 0; + for (ZObject zo : list) + text.append (String.format ("%3d %s%n", ++objectNumber, zo)); + text.deleteCharAt (text.length () - 1); + return text.toString (); + } - @Override - public Iterator iterator () - { - return list.iterator (); - } + @Override + public Iterator iterator () + { + return list.iterator (); + } } \ No newline at end of file diff --git a/src/com/bytezone/diskbrowser/infocom/Routine.java b/src/com/bytezone/diskbrowser/infocom/Routine.java index 2fa53ec..850294b 100644 --- a/src/com/bytezone/diskbrowser/infocom/Routine.java +++ b/src/com/bytezone/diskbrowser/infocom/Routine.java @@ -4,150 +4,148 @@ import java.util.ArrayList; import java.util.Iterator; import java.util.List; -import com.bytezone.diskbrowser.applefile.AbstractFile; - -class Routine extends AbstractFile implements Iterable, Comparable +class Routine extends InfocomAbstractFile + implements Iterable, Comparable { - int startPtr, length, strings, locals; - Header header; + int startPtr, length, strings, locals; + Header header; - List parameters = new ArrayList (); - List instructions = new ArrayList (); - List calls = new ArrayList (); - List calledBy = new ArrayList (); - List actions = new ArrayList (); // not used yet + List parameters = new ArrayList (); + List instructions = new ArrayList (); + List calls = new ArrayList (); + List calledBy = new ArrayList (); + List actions = new ArrayList (); // not used yet - private static final String padding = " "; + private static final String padding = " "; - public Routine (int ptr, Header header, int caller) - { - super (String.format ("Routine %05X", ptr), header.buffer); - this.header = header; + public Routine (int ptr, Header header, int caller) + { + super (String.format ("Routine %05X", ptr), header.buffer); + this.header = header; - locals = buffer[ptr] & 0xFF; - if (locals > 15) - return; + locals = buffer[ptr] & 0xFF; + if (locals > 15) + return; - startPtr = ptr++; // also used to flag a valid routine - calledBy.add (caller); + startPtr = ptr++; // also used to flag a valid routine + calledBy.add (caller); - for (int i = 1; i <= locals; i++) - { - parameters.add (new Parameter (i, header.getWord (ptr))); // default values - ptr += 2; - } + for (int i = 1; i <= locals; i++) + { + parameters.add (new Parameter (i, header.getWord (ptr))); // default values + ptr += 2; + } - while (true) - { - if (buffer[ptr] == 0 || buffer[ptr] == 0x20 || buffer[ptr] == 0x40) - { - System.out.println ("Bad instruction found : " + ptr); - return; - } - Instruction instruction = new Instruction (buffer, ptr, header); - instructions.add (instruction); + while (true) + { + if (buffer[ptr] == 0 || buffer[ptr] == 0x20 || buffer[ptr] == 0x40) + { + System.out.println ("Bad instruction found : " + ptr); + return; + } + Instruction instruction = new Instruction (buffer, ptr, header); + instructions.add (instruction); - if (instruction.isCall () && instruction.opcode.callTarget > 0) // not stack-based - calls.add (instruction.opcode.callTarget); + if (instruction.isCall () && instruction.opcode.callTarget > 0) // not stack-based + calls.add (instruction.opcode.callTarget); - if (instruction.isPrint ()) - strings++; + if (instruction.isPrint ()) + strings++; - ptr += instruction.length (); + ptr += instruction.length (); - // is it a backwards jump? - if (instruction.isJump () && instruction.target () < ptr && !moreCode (ptr)) - break; + // is it a backwards jump? + if (instruction.isJump () && instruction.target () < ptr && !moreCode (ptr)) + break; - // is it an unconditional return? - if (instruction.isReturn () && !moreCode (ptr)) - break; - } - length = ptr - startPtr; + // is it an unconditional return? + if (instruction.isReturn () && !moreCode (ptr)) + break; + } + length = ptr - startPtr; - hexBlocks.add (new HexBlock (startPtr, length, null)); + hexBlocks.add (new HexBlock (startPtr, length, null)); - // check for branches outside this routine - if (true) - { - int endPtr = startPtr + length; - for (Instruction ins : instructions) - { - int target = - ins.target () > 256 ? ins.target () - : ins.opcode.jumpTarget > 256 ? ins.opcode.jumpTarget : 0; - if (target == 0) - continue; - if (ins.isBranch () && (target > endPtr || target < startPtr)) - System.out.println (ins); - if (ins.isJump () && (target > endPtr || target < startPtr)) - System.out.println (ins); - } - } - } + // check for branches outside this routine + if (true) + { + int endPtr = startPtr + length; + for (Instruction ins : instructions) + { + int target = ins.target () > 256 ? ins.target () + : ins.opcode.jumpTarget > 256 ? ins.opcode.jumpTarget : 0; + if (target == 0) + continue; + if (ins.isBranch () && (target > endPtr || target < startPtr)) + System.out.println (ins); + if (ins.isJump () && (target > endPtr || target < startPtr)) + System.out.println (ins); + } + } + } - // test whether the routine contains any instructions pointing to this address - private boolean moreCode (int ptr) - { - for (Instruction ins : instructions) - { - if (ins.isBranch () && ins.target () == ptr) - return true; - // should this be calling ins.target () ? - if (ins.isJump () && ins.opcode.jumpTarget == ptr) - return true; - } - return false; - } + // test whether the routine contains any instructions pointing to this address + private boolean moreCode (int ptr) + { + for (Instruction ins : instructions) + { + if (ins.isBranch () && ins.target () == ptr) + return true; + // should this be calling ins.target () ? + if (ins.isJump () && ins.opcode.jumpTarget == ptr) + return true; + } + return false; + } - public void addCaller (int caller) - { - calledBy.add (caller); - } + public void addCaller (int caller) + { + calledBy.add (caller); + } - @Override - public String getText () - { - StringBuilder text = new StringBuilder (); - text.append (String.format ("Called by : %3d%n", calledBy.size ())); - text.append (String.format ("Calls : %3d%n%n", calls.size ())); - text.append (String.format ("%s%05X : %d%n", padding, startPtr, locals)); - for (Parameter parameter : parameters) - text.append (padding + parameter.toString () + "\n"); - text.append ("\n"); - for (Instruction instruction : instructions) - text.append (instruction + "\n"); - return text.toString (); - } + @Override + public String getText () + { + StringBuilder text = new StringBuilder (); + text.append (String.format ("Called by : %3d%n", calledBy.size ())); + text.append (String.format ("Calls : %3d%n%n", calls.size ())); + text.append (String.format ("%s%05X : %d%n", padding, startPtr, locals)); + for (Parameter parameter : parameters) + text.append (padding + parameter.toString () + "\n"); + text.append ("\n"); + for (Instruction instruction : instructions) + text.append (instruction + "\n"); + return text.toString (); + } - class Parameter - { - int value; - int sequence; + class Parameter + { + int value; + int sequence; - public Parameter (int sequence, int value) - { - this.value = value; - this.sequence = sequence; - } + public Parameter (int sequence, int value) + { + this.value = value; + this.sequence = sequence; + } - @Override - public String toString () - { - return String.format ("%05X : L%02d : %d", (startPtr + (sequence - 1) * 2 + 1), sequence, - value); - } - } + @Override + public String toString () + { + return String.format ("%05X : L%02d : %d", (startPtr + (sequence - 1) * 2 + 1), + sequence, value); + } + } - @Override - public Iterator iterator () - { - return instructions.iterator (); - } + @Override + public Iterator iterator () + { + return instructions.iterator (); + } - @Override - public int compareTo (Routine o) - { - return startPtr - o.startPtr; - } + @Override + public int compareTo (Routine o) + { + return startPtr - o.startPtr; + } } \ No newline at end of file