initial CP/M basic

This commit is contained in:
Denis Molony 2021-07-25 18:30:22 +10:00
parent 26316a82a9
commit 7ca8160d13
7 changed files with 54 additions and 42 deletions

View File

@ -29,20 +29,25 @@ class CPMCatalogSector extends AbstractSector
if (buffer[i] == (byte) 0xE5 && buffer[i + 1] == (byte) 0xE5) if (buffer[i] == (byte) 0xE5 && buffer[i + 1] == (byte) 0xE5)
break; break;
int userNumber = buffer[i] & 0xFF;
if (userNumber > 31 && userNumber != (byte) 0xE5)
break;
boolean readOnly = (buffer[i + 9] & 0x80) != 0; boolean readOnly = (buffer[i + 9] & 0x80) != 0;
boolean systemFile = (buffer[i + 10] & 0x80) != 0; boolean systemFile = (buffer[i + 10] & 0x80) != 0;
boolean unknown = (buffer[i + 11] & 0x80) != 0;
String type; String type;
String extra; String extra;
if (readOnly || systemFile) if (readOnly || systemFile || unknown)
{ {
byte[] typeBuffer = new byte[3]; byte[] typeBuffer = new byte[3];
typeBuffer[0] = (byte) (buffer[i + 9] & 0x7F); typeBuffer[0] = (byte) (buffer[i + 9] & 0x7F);
typeBuffer[1] = (byte) (buffer[i + 10] & 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 (); type = new String (typeBuffer).trim ();
extra = String.format (" (%s%s)", readOnly ? "read only" : "", extra = String.format (" (%s%s%s)", readOnly ? "read only" : "",
systemFile ? "system file" : ""); systemFile ? "system file" : "", unknown ? "unknown" : "");
} }
else else
{ {

View File

@ -188,19 +188,18 @@ public class CPMDisk extends AbstractFormattedDisk
public AppleFileSource getCatalog () public AppleFileSource getCatalog ()
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
{ {
String newLine = String.format ("%n");
String line = String line =
"---- --------- --- - - -- -- -- -- ----------------------------" "---- --------- --- - - -- -- -- -- ----------------------------"
+ "-------------------" + newLine; + "-------------------\n";
StringBuilder text = new StringBuilder (); StringBuilder text = new StringBuilder ();
text.append (String.format ("File : %s%n%n", getDisplayPath ())); 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); text.append (line);
for (AppleFileSource entry : fileEntries) for (AppleFileSource entry : fileEntries)
{ {
text.append (((DirectoryEntry) entry).line ()); text.append (((DirectoryEntry) entry).line ());
text.append (newLine); text.append ("\n");
} }
text.append (line); text.append (line);
if (version != 0) if (version != 0)
@ -235,7 +234,8 @@ public class CPMDisk extends AbstractFormattedDisk
{ {
if (buffer[ptr] == (byte) EMPTY_BYTE_VALUE) 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; break;
continue; // deleted file? continue; // deleted file?
} }
@ -246,7 +246,7 @@ public class CPMDisk extends AbstractFormattedDisk
for (int j = 1; j < 12; j++) 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 if (ch < 32 || ch > 126) // invalid ascii
return false; return false;
} }
@ -260,6 +260,9 @@ public class CPMDisk extends AbstractFormattedDisk
} }
} }
if (debug)
System.out.println ("CP/M disk");
return true; return true;
} }

View File

@ -4,6 +4,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.bytezone.diskbrowser.applefile.AppleFileSource; import com.bytezone.diskbrowser.applefile.AppleFileSource;
import com.bytezone.diskbrowser.applefile.CPMBasicFile;
import com.bytezone.diskbrowser.applefile.CPMTextFile; import com.bytezone.diskbrowser.applefile.CPMTextFile;
import com.bytezone.diskbrowser.applefile.DefaultAppleFile; import com.bytezone.diskbrowser.applefile.DefaultAppleFile;
import com.bytezone.diskbrowser.disk.AppleDiskAddress; import com.bytezone.diskbrowser.disk.AppleDiskAddress;
@ -58,6 +59,7 @@ class DirectoryEntry implements AppleFileSource
name = ""; name = "";
else else
name = new String (buffer, offset + 1, 8).trim (); name = new String (buffer, offset + 1, 8).trim ();
extent = buffer[offset + 12] & 0xFF; extent = buffer[offset + 12] & 0xFF;
s2 = buffer[offset + 13] & 0xFF; s2 = buffer[offset + 13] & 0xFF;
s1 = buffer[offset + 14] & 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) else if ("ASM".equals (type) || "DOC".equals (type) || "TXT".equals (type)
|| count > 2) || count > 2)
appleFile = new CPMTextFile (name, exactBuffer); appleFile = new CPMTextFile (name, exactBuffer);
else if ("BAS".equals (type))
appleFile = new CPMBasicFile (name, exactBuffer);
else else
appleFile = new DefaultAppleFile (name, exactBuffer, "CPM File : " + type); appleFile = new DefaultAppleFile (name, exactBuffer, "CPM File : " + type);

View File

@ -8,14 +8,12 @@ import javax.swing.JPanel;
import com.bytezone.diskbrowser.applefile.AssemblerProgram; import com.bytezone.diskbrowser.applefile.AssemblerProgram;
import com.bytezone.diskbrowser.gui.DataSource; import com.bytezone.diskbrowser.gui.DataSource;
import com.bytezone.diskbrowser.utilities.HexFormatter; import com.bytezone.diskbrowser.utilities.HexFormatter;
import com.bytezone.diskbrowser.utilities.Utility;
// -----------------------------------------------------------------------------------// // -----------------------------------------------------------------------------------//
public abstract class AbstractSector implements DataSource public abstract class AbstractSector implements DataSource
// -----------------------------------------------------------------------------------// // -----------------------------------------------------------------------------------//
{ {
private static String newLine = String.format ("%n");
private static String newLine2 = newLine + newLine;
final public byte[] buffer; final public byte[] buffer;
protected Disk disk; protected Disk disk;
protected DiskAddress diskAddress; protected DiskAddress diskAddress;
@ -90,10 +88,11 @@ public abstract class AbstractSector implements DataSource
{ {
StringBuilder text = new StringBuilder (); StringBuilder text = new StringBuilder ();
text.append (title + newLine2); text.append (title + "\n\n");
text.append ("Offset Value Description" + newLine); text.append ("Offset Value Description\n");
text.append ("======= =========== " text.append ("======= =========== "
+ "===============================================================" + newLine); + "===============================================================\n");
return text; return text;
} }
@ -143,14 +142,13 @@ public abstract class AbstractSector implements DataSource
String desc) String desc)
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
{ {
if (size == 1) desc += switch (size)
desc += " (" + (b[offset] & 0xFF) + ")"; {
else if (size == 2) case 1 -> " (" + (b[offset] & 0xFF) + ")";
desc += case 2 -> String.format (" (%,d)", Utility.getShort (b, offset));
String.format (" (%,d)", ((b[offset + 1] & 0xFF) * 256 + (b[offset] & 0xFF))); case 3 -> String.format (" (%,d)", Utility.readTriple (b, offset));
else if (size == 3) default -> "";
desc += String.format (" (%,d)", ((b[offset + 2] & 0xFF) * 65536) };
+ ((b[offset + 1] & 0xFF) * 256) + (b[offset] & 0xFF));
addText (text, b, offset, size, desc); addText (text, b, offset, size, desc);
} }

View File

@ -97,9 +97,10 @@ class DiskLayoutImage extends DiskPanel implements Scrollable, RedoListener
selectionHandler.setSelection (sectors); selectionHandler.setSelection (sectors);
if (sectors != null && sectors.size () > 0) if (sectors != null && sectors.size () > 0)
{ {
DiskAddress da = sectors.size () == 1 ? sectors.get (0) : sectors.get (1); // DiskAddress da = sectors.size () == 1 ? sectors.get (0) : sectors.get (1);
if (da != null) // if (da != null)
scrollRectToVisible (layoutDetails.getLocation (da)); // scrollRectToVisible (layoutDetails.getLocation (da));
scrollRectToVisible (layoutDetails.getLocation (sectors.get (0)));
} }
repaint (); repaint ();
} }

View File

@ -13,6 +13,7 @@ public class DiskPanel extends JPanel
{ {
FormattedDisk formattedDisk; FormattedDisk formattedDisk;
LayoutDetails layoutDetails; LayoutDetails layoutDetails;
int blockWidth = 30; // default int blockWidth = 30; // default
int blockHeight = 15; // default int blockHeight = 15; // default
int centerOffset; int centerOffset;
@ -20,11 +21,11 @@ public class DiskPanel extends JPanel
Color backgroundColor = new Color (0xE0, 0xE0, 0xE0); Color backgroundColor = new Color (0xE0, 0xE0, 0xE0);
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
public void setDisk (FormattedDisk disk, LayoutDetails details) public void setDisk (FormattedDisk formattedDisk, LayoutDetails layoutDetails)
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
{ {
formattedDisk = disk; this.formattedDisk = formattedDisk;
layoutDetails = details; this.layoutDetails = layoutDetails;
blockWidth = layoutDetails.block.width; blockWidth = layoutDetails.block.width;
blockHeight = layoutDetails.block.height; blockHeight = layoutDetails.block.height;

View File

@ -29,14 +29,14 @@ class ScrollRuler extends JComponent
private boolean isHex = true; private boolean isHex = true;
private boolean isTrackMode = true; private boolean isTrackMode = true;
private LayoutDetails layoutDetails; 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.orientation = orientation;
this.image = image; this.diskLayoutImage = diskLayoutImage;
// set defaults until setLayout is called // set defaults until setLayout is called
if (orientation == HORIZONTAL) 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 // Must match the preferred size of DiskLayoutImage
if (orientation == HORIZONTAL) if (orientation == HORIZONTAL)
setPreferredSize ( setPreferredSize (new Dimension (
new Dimension (layout.block.width * layout.grid.width + 1, HEIGHT)); layoutDetails.block.width * layoutDetails.grid.width + 1, HEIGHT));
else else
setPreferredSize ( setPreferredSize (new Dimension (WIDTH,
new Dimension (WIDTH, layout.block.height * layout.grid.height + 1)); 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 start = (clipRect.x / width);
int end = start + clipRect.width / 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; String format;
int offset; int offset;
@ -131,7 +131,7 @@ class ScrollRuler extends JComponent
{ {
int start = (clipRect.y / height); int start = (clipRect.y / height);
int end = start + clipRect.height / 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"; String format = isHex ? "%04X" : "%04d";