From 7ca8160d13e81a0e50fae645fcf46be3f03febc6 Mon Sep 17 00:00:00 2001 From: Denis Molony Date: Sun, 25 Jul 2021 18:30:22 +1000 Subject: [PATCH] initial CP/M basic --- .../diskbrowser/cpm/CPMCatalogSector.java | 13 +++++++--- src/com/bytezone/diskbrowser/cpm/CPMDisk.java | 15 ++++++----- .../diskbrowser/cpm/DirectoryEntry.java | 4 +++ .../diskbrowser/disk/AbstractSector.java | 26 +++++++++---------- .../diskbrowser/gui/DiskLayoutImage.java | 7 ++--- .../bytezone/diskbrowser/gui/DiskPanel.java | 7 ++--- .../bytezone/diskbrowser/gui/ScrollRuler.java | 24 ++++++++--------- 7 files changed, 54 insertions(+), 42 deletions(-) diff --git a/src/com/bytezone/diskbrowser/cpm/CPMCatalogSector.java b/src/com/bytezone/diskbrowser/cpm/CPMCatalogSector.java index 223008a..0d96282 100644 --- a/src/com/bytezone/diskbrowser/cpm/CPMCatalogSector.java +++ b/src/com/bytezone/diskbrowser/cpm/CPMCatalogSector.java @@ -29,20 +29,25 @@ class CPMCatalogSector extends AbstractSector if (buffer[i] == (byte) 0xE5 && buffer[i + 1] == (byte) 0xE5) break; + int userNumber = buffer[i] & 0xFF; + if (userNumber > 31 && userNumber != (byte) 0xE5) + break; + boolean readOnly = (buffer[i + 9] & 0x80) != 0; boolean systemFile = (buffer[i + 10] & 0x80) != 0; + boolean unknown = (buffer[i + 11] & 0x80) != 0; String type; String extra; - if (readOnly || systemFile) + if (readOnly || systemFile || unknown) { byte[] typeBuffer = new byte[3]; typeBuffer[0] = (byte) (buffer[i + 9] & 0x7F); typeBuffer[1] = (byte) (buffer[i + 10] & 0x7F); - typeBuffer[2] = buffer[i + 11]; + typeBuffer[2] = (byte) (buffer[i + 11] & 0x7F); type = new String (typeBuffer).trim (); - extra = String.format (" (%s%s)", readOnly ? "read only" : "", - systemFile ? "system file" : ""); + extra = String.format (" (%s%s%s)", readOnly ? "read only" : "", + systemFile ? "system file" : "", unknown ? "unknown" : ""); } else { diff --git a/src/com/bytezone/diskbrowser/cpm/CPMDisk.java b/src/com/bytezone/diskbrowser/cpm/CPMDisk.java index 16afbeb..3ec7d94 100644 --- a/src/com/bytezone/diskbrowser/cpm/CPMDisk.java +++ b/src/com/bytezone/diskbrowser/cpm/CPMDisk.java @@ -188,19 +188,18 @@ public class CPMDisk extends AbstractFormattedDisk public AppleFileSource getCatalog () // ---------------------------------------------------------------------------------// { - String newLine = String.format ("%n"); String line = "---- --------- --- - - -- -- -- -- ----------------------------" - + "-------------------" + newLine; + + "-------------------\n"; StringBuilder text = new StringBuilder (); text.append (String.format ("File : %s%n%n", getDisplayPath ())); - text.append ("User Name Typ R S Ex S2 S1 RC Blocks" + newLine); + text.append ("User Name Typ R S Ex S2 S1 RC Blocks\n"); text.append (line); for (AppleFileSource entry : fileEntries) { text.append (((DirectoryEntry) entry).line ()); - text.append (newLine); + text.append ("\n"); } text.append (line); if (version != 0) @@ -235,7 +234,8 @@ public class CPMDisk extends AbstractFormattedDisk { if (buffer[ptr] == (byte) EMPTY_BYTE_VALUE) { - if (buffer[ptr + 1] == (byte) EMPTY_BYTE_VALUE) // finished this block + if (buffer[ptr + 1] == (byte) EMPTY_BYTE_VALUE // + || buffer[ptr + 1] == 0) // finished this block break; continue; // deleted file? } @@ -246,7 +246,7 @@ public class CPMDisk extends AbstractFormattedDisk for (int j = 1; j < 12; j++) { - int ch = buffer[ptr + j] & 0xFF; + int ch = buffer[ptr + j] & 0x7F; // remove flag if (ch < 32 || ch > 126) // invalid ascii return false; } @@ -260,6 +260,9 @@ public class CPMDisk extends AbstractFormattedDisk } } + if (debug) + System.out.println ("CP/M disk"); + return true; } diff --git a/src/com/bytezone/diskbrowser/cpm/DirectoryEntry.java b/src/com/bytezone/diskbrowser/cpm/DirectoryEntry.java index e67ab94..48e851a 100644 --- a/src/com/bytezone/diskbrowser/cpm/DirectoryEntry.java +++ b/src/com/bytezone/diskbrowser/cpm/DirectoryEntry.java @@ -4,6 +4,7 @@ import java.util.ArrayList; import java.util.List; import com.bytezone.diskbrowser.applefile.AppleFileSource; +import com.bytezone.diskbrowser.applefile.CPMBasicFile; import com.bytezone.diskbrowser.applefile.CPMTextFile; import com.bytezone.diskbrowser.applefile.DefaultAppleFile; import com.bytezone.diskbrowser.disk.AppleDiskAddress; @@ -58,6 +59,7 @@ class DirectoryEntry implements AppleFileSource name = ""; else name = new String (buffer, offset + 1, 8).trim (); + extent = buffer[offset + 12] & 0xFF; s2 = buffer[offset + 13] & 0xFF; s1 = buffer[offset + 14] & 0xFF; @@ -226,6 +228,8 @@ class DirectoryEntry implements AppleFileSource else if ("ASM".equals (type) || "DOC".equals (type) || "TXT".equals (type) || count > 2) appleFile = new CPMTextFile (name, exactBuffer); + else if ("BAS".equals (type)) + appleFile = new CPMBasicFile (name, exactBuffer); else appleFile = new DefaultAppleFile (name, exactBuffer, "CPM File : " + type); diff --git a/src/com/bytezone/diskbrowser/disk/AbstractSector.java b/src/com/bytezone/diskbrowser/disk/AbstractSector.java index b697d36..cd93266 100755 --- a/src/com/bytezone/diskbrowser/disk/AbstractSector.java +++ b/src/com/bytezone/diskbrowser/disk/AbstractSector.java @@ -8,14 +8,12 @@ import javax.swing.JPanel; import com.bytezone.diskbrowser.applefile.AssemblerProgram; import com.bytezone.diskbrowser.gui.DataSource; import com.bytezone.diskbrowser.utilities.HexFormatter; +import com.bytezone.diskbrowser.utilities.Utility; // -----------------------------------------------------------------------------------// public abstract class AbstractSector implements DataSource // -----------------------------------------------------------------------------------// { - private static String newLine = String.format ("%n"); - private static String newLine2 = newLine + newLine; - final public byte[] buffer; protected Disk disk; protected DiskAddress diskAddress; @@ -90,10 +88,11 @@ public abstract class AbstractSector implements DataSource { StringBuilder text = new StringBuilder (); - text.append (title + newLine2); - text.append ("Offset Value Description" + newLine); + text.append (title + "\n\n"); + text.append ("Offset Value Description\n"); text.append ("======= =========== " - + "===============================================================" + newLine); + + "===============================================================\n"); + return text; } @@ -143,14 +142,13 @@ public abstract class AbstractSector implements DataSource String desc) // ---------------------------------------------------------------------------------// { - if (size == 1) - desc += " (" + (b[offset] & 0xFF) + ")"; - else if (size == 2) - desc += - String.format (" (%,d)", ((b[offset + 1] & 0xFF) * 256 + (b[offset] & 0xFF))); - else if (size == 3) - desc += String.format (" (%,d)", ((b[offset + 2] & 0xFF) * 65536) - + ((b[offset + 1] & 0xFF) * 256) + (b[offset] & 0xFF)); + desc += switch (size) + { + case 1 -> " (" + (b[offset] & 0xFF) + ")"; + case 2 -> String.format (" (%,d)", Utility.getShort (b, offset)); + case 3 -> String.format (" (%,d)", Utility.readTriple (b, offset)); + default -> ""; + }; addText (text, b, offset, size, desc); } diff --git a/src/com/bytezone/diskbrowser/gui/DiskLayoutImage.java b/src/com/bytezone/diskbrowser/gui/DiskLayoutImage.java index 529c036..eb5b3f7 100644 --- a/src/com/bytezone/diskbrowser/gui/DiskLayoutImage.java +++ b/src/com/bytezone/diskbrowser/gui/DiskLayoutImage.java @@ -97,9 +97,10 @@ class DiskLayoutImage extends DiskPanel implements Scrollable, RedoListener selectionHandler.setSelection (sectors); if (sectors != null && sectors.size () > 0) { - DiskAddress da = sectors.size () == 1 ? sectors.get (0) : sectors.get (1); - if (da != null) - scrollRectToVisible (layoutDetails.getLocation (da)); +// DiskAddress da = sectors.size () == 1 ? sectors.get (0) : sectors.get (1); +// if (da != null) +// scrollRectToVisible (layoutDetails.getLocation (da)); + scrollRectToVisible (layoutDetails.getLocation (sectors.get (0))); } repaint (); } diff --git a/src/com/bytezone/diskbrowser/gui/DiskPanel.java b/src/com/bytezone/diskbrowser/gui/DiskPanel.java index c7a80af..85cb53d 100644 --- a/src/com/bytezone/diskbrowser/gui/DiskPanel.java +++ b/src/com/bytezone/diskbrowser/gui/DiskPanel.java @@ -13,6 +13,7 @@ public class DiskPanel extends JPanel { FormattedDisk formattedDisk; LayoutDetails layoutDetails; + int blockWidth = 30; // default int blockHeight = 15; // default int centerOffset; @@ -20,11 +21,11 @@ public class DiskPanel extends JPanel Color backgroundColor = new Color (0xE0, 0xE0, 0xE0); // ---------------------------------------------------------------------------------// - public void setDisk (FormattedDisk disk, LayoutDetails details) + public void setDisk (FormattedDisk formattedDisk, LayoutDetails layoutDetails) // ---------------------------------------------------------------------------------// { - formattedDisk = disk; - layoutDetails = details; + this.formattedDisk = formattedDisk; + this.layoutDetails = layoutDetails; blockWidth = layoutDetails.block.width; blockHeight = layoutDetails.block.height; diff --git a/src/com/bytezone/diskbrowser/gui/ScrollRuler.java b/src/com/bytezone/diskbrowser/gui/ScrollRuler.java index a2e0db1..95f73c3 100644 --- a/src/com/bytezone/diskbrowser/gui/ScrollRuler.java +++ b/src/com/bytezone/diskbrowser/gui/ScrollRuler.java @@ -29,14 +29,14 @@ class ScrollRuler extends JComponent private boolean isHex = true; private boolean isTrackMode = true; private LayoutDetails layoutDetails; - private final JComponent image; + private final DiskLayoutImage diskLayoutImage; // ---------------------------------------------------------------------------------// - ScrollRuler (JComponent image, int orientation) + ScrollRuler (DiskLayoutImage diskLayoutImage, int orientation) // ---------------------------------------------------------------------------------// { this.orientation = orientation; - this.image = image; + this.diskLayoutImage = diskLayoutImage; // set defaults until setLayout is called if (orientation == HORIZONTAL) @@ -46,20 +46,20 @@ class ScrollRuler extends JComponent } // ---------------------------------------------------------------------------------// - public void setLayout (LayoutDetails layout) + public void setLayout (LayoutDetails layoutDetails) // ---------------------------------------------------------------------------------// { - this.layoutDetails = layout; + this.layoutDetails = layoutDetails; // Must match the preferred size of DiskLayoutImage if (orientation == HORIZONTAL) - setPreferredSize ( - new Dimension (layout.block.width * layout.grid.width + 1, HEIGHT)); + setPreferredSize (new Dimension ( + layoutDetails.block.width * layoutDetails.grid.width + 1, HEIGHT)); else - setPreferredSize ( - new Dimension (WIDTH, layout.block.height * layout.grid.height + 1)); + setPreferredSize (new Dimension (WIDTH, + layoutDetails.block.height * layoutDetails.grid.height + 1)); - setTrackMode (layout.grid.width == 16 || layout.grid.width == 13); + setTrackMode (layoutDetails.grid.width == 16 || layoutDetails.grid.width == 13); } // ---------------------------------------------------------------------------------// @@ -105,7 +105,7 @@ class ScrollRuler extends JComponent { int start = (clipRect.x / width); int end = start + clipRect.width / width; - end = Math.min (end, image.getWidth () / width - 1); + end = Math.min (end, diskLayoutImage.getWidth () / width - 1); String format; int offset; @@ -131,7 +131,7 @@ class ScrollRuler extends JComponent { int start = (clipRect.y / height); int end = start + clipRect.height / height; - end = Math.min (end, image.getHeight () / height - 1); + end = Math.min (end, diskLayoutImage.getHeight () / height - 1); String format = isHex ? "%04X" : "%04d";