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)
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
{

View File

@ -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;
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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 ();
}

View File

@ -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;

View File

@ -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";