Some OMF, initial DiskCopy 4.2

This commit is contained in:
Denis Molony 2020-07-12 12:46:18 +10:00
parent 5191615953
commit f78dce5d05
8 changed files with 540 additions and 12 deletions

View File

@ -2,14 +2,18 @@ package com.bytezone.diskbrowser.applefile;
import com.bytezone.diskbrowser.utilities.HexFormatter; import com.bytezone.diskbrowser.utilities.HexFormatter;
// -----------------------------------------------------------------------------------//
public class FileSystemTranslator extends AbstractFile public class FileSystemTranslator extends AbstractFile
// -----------------------------------------------------------------------------------//
{ {
private final String text1; private final String text1;
private final String text2; private final String text2;
private final String text3; private final String text3;
private final String text4; private final String text4;
// ---------------------------------------------------------------------------------//
public FileSystemTranslator (String name, byte[] buffer) public FileSystemTranslator (String name, byte[] buffer)
// ---------------------------------------------------------------------------------//
{ {
super (name, buffer); super (name, buffer);
@ -20,10 +24,15 @@ public class FileSystemTranslator extends AbstractFile
text3 = HexFormatter.getPascalString (buffer, 0xFC + len1 + 1); text3 = HexFormatter.getPascalString (buffer, 0xFC + len1 + 1);
int len2 = buffer[0xFC + len1 + 1] & 0xFF; int len2 = buffer[0xFC + len1 + 1] & 0xFF;
text4 = HexFormatter.getPascalString (buffer, 0xFC + len1 + len2 + 4); text4 = HexFormatter.getPascalString (buffer, 0xFC + len1 + len2 + 4);
SegmentHeader segmentHeader = new SegmentHeader (buffer, 0);
System.out.println (segmentHeader);
} }
// ---------------------------------------------------------------------------------//
@Override @Override
public String getText () public String getText ()
// ---------------------------------------------------------------------------------//
{ {
StringBuilder text = new StringBuilder ("Name : " + name + "\n\n"); StringBuilder text = new StringBuilder ("Name : " + name + "\n\n");

View File

@ -0,0 +1,50 @@
package com.bytezone.diskbrowser.applefile;
import java.util.ArrayList;
import java.util.List;
import com.bytezone.diskbrowser.utilities.Utility;
// -----------------------------------------------------------------------------------//
public class ObjectModule extends AbstractFile
// -----------------------------------------------------------------------------------//
{
List<SegmentHeader> segmentHeaders = new ArrayList<> ();
// ---------------------------------------------------------------------------------//
public ObjectModule (String name, byte[] buffer, int auxType)
// ---------------------------------------------------------------------------------//
{
super (name, buffer);
int ptr = 0;
while (ptr < buffer.length - 4)
{
int byteCount = Utility.getLong (buffer, ptr);
if (byteCount == 0)
break;
segmentHeaders.add (new SegmentHeader (buffer, ptr));
ptr += byteCount;
}
}
// ---------------------------------------------------------------------------------//
@Override
public String getText ()
// ---------------------------------------------------------------------------------//
{
StringBuilder text = new StringBuilder ("Name : " + name + "\n\n");
text.append ("Object Module\n\n");
for (SegmentHeader segmentHeader : segmentHeaders)
{
text.append (segmentHeader);
text.append ("\n");
}
return text.toString ();
}
}

View File

@ -0,0 +1,356 @@
package com.bytezone.diskbrowser.applefile;
import com.bytezone.diskbrowser.utilities.HexFormatter;
import com.bytezone.diskbrowser.utilities.Utility;
// -----------------------------------------------------------------------------------//
public class SegmentHeader
// -----------------------------------------------------------------------------------//
{
int bytecnt;
int resspc;
int length;
int kind1;
String kindWhereText;
boolean kindReload;
boolean kindAbsoluteBank;
boolean kindSpecialMemory;
boolean kindPosIndependent;
boolean kindPrivate;
boolean kindStatic;
int lablen;
int numlen;
int version;
int banksize;
int kind2;
int unused;
int org;
int align;
int numsex;
int lcbank;
int segnum;
int entry;
int dispname;
int dispdata;
String loadname;
String segname;
// ---------------------------------------------------------------------------------//
public SegmentHeader (byte[] buffer, int offset)
// ---------------------------------------------------------------------------------//
{
bytecnt = Utility.getLong (buffer, offset);
resspc = Utility.getLong (buffer, offset + 4);
length = Utility.getLong (buffer, offset + 8);
kind1 = buffer[offset + 12] & 0xFF;
lablen = buffer[offset + 13] & 0xFF;
numlen = buffer[offset + 14] & 0xFF;
version = buffer[offset + 15] & 0xFF;
banksize = Utility.getLong (buffer, offset + 16);
kind2 = Utility.getWord (buffer, offset + 20);
unused = Utility.getWord (buffer, offset + 22);
org = Utility.getLong (buffer, offset + 24);
align = Utility.getLong (buffer, offset + 28);
numsex = buffer[offset + 32] & 0xFF;
lcbank = buffer[offset + 33] & 0xFF;
segnum = Utility.getWord (buffer, offset + 34);
entry = Utility.getLong (buffer, offset + 36);
dispname = Utility.getWord (buffer, offset + 40);
dispdata = Utility.getWord (buffer, offset + 42);
decodeKind ();
if (buffer[offset + dispname] == 0)
loadname = "";
else
loadname = new String (buffer, offset + dispname, 10);
if (lablen == 0)
segname = HexFormatter.getPascalString (buffer, offset + dispname + 10);
else
segname = "not finished";
System.out.println (this);
int ptr = offset + dispdata;
while (true)
{
int recType = buffer[ptr] & 0xFF;
// System.out.printf ("%04X = %02X%n", ptr, recType);
if (recType > 0 && recType <= 0xDF)
{
System.out.printf ("Const: %02X%n", recType);
System.out.println (HexFormatter.format (buffer, ptr, recType + 1, ptr));
ptr += recType + 1;
continue;
}
System.out.printf ("%02X ", recType);
switch (recType)
{
case 0x00: // END
System.out.println ("END");
break;
case 0xE0: // ALIGN
System.out.printf ("ALIGN:%n");
break;
case 0xE1: // ORG
System.out.printf ("ORG:%n");
break;
case 0xE2: // RELOC
int bytesRelocated = buffer[ptr + 1] & 0xFF;
int bitShift = buffer[ptr + 2] & 0xFF;
int segmentOffset = Utility.getLong (buffer, ptr + 3);
int value = Utility.getLong (buffer, ptr + 7);
System.out.printf ("RELOC: %02X %02X %08X %08X%n", bytesRelocated, bitShift,
segmentOffset, value);
ptr += 11;
continue;
case 0xE3: // INTERSEG
int count1 = buffer[ptr + 1] & 0xFF;
int count2 = buffer[ptr + 2] & 0xFF;
int operandOffset = Utility.getLong (buffer, ptr + 3);
int fileNo = Utility.getWord (buffer, ptr + 7);
int segNo = Utility.getWord (buffer, ptr + 9);
int subroutineOffset = Utility.getLong (buffer, ptr + 11);
System.out.printf ("INTERSEG: %02X %02X %08X %04X %04X %08X%n", count1, count2,
operandOffset, fileNo, segNo, subroutineOffset);
ptr += 15;
break;
case 0xE4: // USING
System.out.printf ("USING:%n");
break;
case 0xE5: // STRONG
System.out.printf ("STRONG:%n");
break;
case 0xE6: // GLOBAL
System.out.printf ("GLOBAL:%n");
break;
case 0xE7: // GEQU
System.out.printf ("GEQU:%n");
break;
case 0xE8: // MEM
System.out.printf ("MEM:%n");
break;
case 0xEB: // EXPR
System.out.printf ("EXPR:%n");
break;
case 0xEC: // ZEXPR
System.out.printf ("ZEXPR:%n");
break;
case 0xED: // BEXPR
System.out.printf ("BEXPR:%n");
break;
case 0xEE: // RELEXPR
System.out.printf ("RELEXPR:%n");
break;
case 0xEF: // LOCAL
System.out.printf ("LOCAL:%n");
break;
case 0xF0: // EQU
String label = HexFormatter.getPascalString (buffer, ptr + 1);
System.out.printf ("EQU: %s%n", label);
break;
case 0xF1: // DS
System.out.printf ("DS:%n");
break;
case 0xF2: // LCONST
int constLength = Utility.getLong (buffer, ptr + 1);
System.out.printf ("Const: %04X%n", constLength);
ptr += constLength + 5;
continue;
case 0xF3: // LEXPR
System.out.printf ("LEXPR:%n");
break;
case 0xF4: // ENTRY
System.out.printf ("ENTRY:%n");
break;
case 0xF5: // cRELOC
int cBytesRelocated = buffer[ptr + 1] & 0xFF;
int cBitShift = buffer[ptr + 2] & 0xFF;
int cSegmentOffset = Utility.getWord (buffer, ptr + 3);
int cValue = Utility.getWord (buffer, ptr + 5);
System.out.printf ("cRELOC: %02X %02X %08X %08X%n", cBytesRelocated, cBitShift,
cSegmentOffset, cValue);
ptr += 7;
continue;
case 0xF6: // cINTERSEG
int cCount1 = buffer[ptr + 1] & 0xFF;
int cCount2 = buffer[ptr + 2] & 0xFF;
int cOperandOffset = Utility.getWord (buffer, ptr + 3);
int cSegNo = buffer[ptr + 5] & 0xFF;
int cSubroutineOffset = Utility.getWord (buffer, ptr + 6);
System.out.printf ("cINTERSEG: %02X %02X %04X %02X %04X%n", cCount1, cCount2,
cOperandOffset, cSegNo, cSubroutineOffset);
ptr += 8;
continue;
case 0xF7: // SUPER
int superLength = Utility.getLong (buffer, ptr + 1);
int recordType = buffer[ptr + 5] & 0xFF;
System.out.printf ("Super type %02X%n", recordType);
ptr += superLength + 5;
continue;
default:
System.out.printf ("Unknown record type: %02X%n", recType);
break;
}
System.out.println ();
break;
}
}
// ---------------------------------------------------------------------------------//
private void decodeKind ()
// ---------------------------------------------------------------------------------//
{
int segType;
int segAttr;
if (version < 2) // 8 bits
{
segType = kind1 & 0x1F;
segAttr = kind1 & 0xE0;
}
else // 16 bits
{
segType = kind2 & 0x001F;
segAttr = kind2 >>> 8;
}
kindReload = (segAttr & 0x04) != 0;
kindAbsoluteBank = (segAttr & 0x08) != 0;
kindSpecialMemory = (segAttr & 0x10) == 0;
kindPosIndependent = (segAttr & 0x20) != 0;
kindPrivate = (segAttr & 0x40) != 0;
kindStatic = (segAttr & 0x80) == 0;
switch (segType)
{
case 0:
kindWhereText = "Code Segment";
break;
case 1:
kindWhereText = "Data Segment";
break;
case 2:
kindWhereText = "Jump Table Segment";
break;
case 4:
kindWhereText = "Pathname Segment";
break;
case 8:
kindWhereText = "Library Dictionary Segment";
break;
case 0x10:
kindWhereText = "Initialization Segment";
break;
case 0x11:
kindWhereText = "Absolute Bank Segment";
break;
case 0x12:
kindWhereText = "Direct Page / Stack Segment";
break;
}
}
// ---------------------------------------------------------------------------------//
@Override
public String toString ()
// ---------------------------------------------------------------------------------//
{
StringBuilder text = new StringBuilder ();
text.append (String.format ("Byte count ......... %08X%n", bytecnt));
text.append (String.format ("Reserved space ..... %08X%n", resspc));
text.append (String.format ("Length ............. %08X%n", length));
text.append (String.format ("Kind v1 ............ %02X%n", kind1));
if (version < 2)
{
text.append (String.format (" Type ............. %s%n", kindWhereText));
text.append (
String.format (" Position ind ..... %s%n", kindPosIndependent ? "Yes" : "No"));
text.append (
String.format (" Private .......... %s%n", kindPrivate ? "Yes" : "No"));
text.append (
String.format (" Static/Dynamic ... %s%n", kindStatic ? "Static" : "Dynamic"));
}
text.append (String.format ("Label length ....... %02X%n", lablen));
text.append (String.format ("Number length ...... %02X%n", numlen));
text.append (String.format ("Version ............ %02X%n", version));
text.append (String.format ("Bank size .......... %08X%n", banksize));
text.append (String.format ("Kind v2 ............ %04X%n", kind2));
if (version >= 2)
{
text.append (String.format (" Type ............. %s%n", kindWhereText));
text.append (
String.format (" Reload ........... %s%n", kindReload ? "Yes" : "No"));
text.append (
String.format (" Absolute Bank .... %s%n", kindAbsoluteBank ? "Yes" : "No"));
text.append (
String.format (" Special Memory ... %s%n", kindSpecialMemory ? "Yes" : "No"));
text.append (
String.format (" Position ind ..... %s%n", kindPosIndependent ? "Yes" : "No"));
text.append (
String.format (" Private .......... %s%n", kindPrivate ? "Yes" : "No"));
text.append (
String.format (" Static/Dynamic ... %s%n", kindStatic ? "Static" : "Dynamic"));
}
text.append (String.format ("Unused ............. %04X%n", unused));
text.append (String.format ("Org ................ %08X%n", org));
text.append (String.format ("Align .............. %08X%n", align));
text.append (String.format ("Number sex ......... %02X%n", numsex));
text.append (String.format ("LC Bank ............ %02X%n", lcbank));
text.append (String.format ("Segment number ..... %04X%n", segnum));
text.append (String.format ("Entry .............. %08X%n", entry));
text.append (String.format ("Disp name .......... %04X%n", dispname));
text.append (String.format ("Disp data .......... %04X%n", dispdata));
text.append (String.format ("Load name .......... %s%n", loadname));
text.append (String.format ("Segment name ....... %s%n", segname));
return text.toString ();
}
}

View File

@ -140,6 +140,18 @@ public class AppleDisk implements Disk
this.trackSize = sectors * sectorSize; this.trackSize = sectors * sectorSize;
} }
} }
else if ("img".equals (suffix))
{
PrefixDiskCopy prefixDiskCopy = new PrefixDiskCopy (buffer);
blocks = prefixDiskCopy.getBlocks ();
this.sectorSize = 512;
this.trackSize = 8 * sectorSize;
skip = 0x54;
tracks = blocks / 8; // change parameter!
sectors = 8; // change parameter!
}
else if (suffix.equalsIgnoreCase ("HDV") else if (suffix.equalsIgnoreCase ("HDV")
|| (suffix.equalsIgnoreCase ("po") && tracks > 50)) // ULTIMATE APPLE1 CFFA 3.5.po || (suffix.equalsIgnoreCase ("po") && tracks > 50)) // ULTIMATE APPLE1 CFFA 3.5.po
{ {
@ -278,7 +290,7 @@ public class AppleDisk implements Disk
private byte[] getPrefix (File path) private byte[] getPrefix (File path)
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
{ {
byte[] buffer = new byte[64]; byte[] buffer = new byte[0x54];
try (BufferedInputStream file = new BufferedInputStream (new FileInputStream (path))) try (BufferedInputStream file = new BufferedInputStream (new FileInputStream (path)))
{ {
file.read (buffer); file.read (buffer);

View File

@ -184,12 +184,12 @@ public class DiskFactory
if (prodosDisk != null) if (prodosDisk != null)
return prodosDisk; return prodosDisk;
disk2 = check2mgDisk (file); disk = check2mgDisk (file);
if (disk2 != null) if (disk != null)
{ {
if (compressed) if (compressed)
disk2.setOriginalPath (originalPath); disk.setOriginalPath (originalPath);
return disk2; return disk;
} }
AppleDisk appleDisk = new AppleDisk (file, (int) file.length () / 4096, 8); AppleDisk appleDisk = new AppleDisk (file, (int) file.length () / 4096, 8);
@ -200,18 +200,25 @@ public class DiskFactory
{ {
if (debug) if (debug)
System.out.println (" ** 2mg **"); System.out.println (" ** 2mg **");
disk2 = check2mgDisk (file); disk = check2mgDisk (file);
if (disk2 != null) if (disk != null)
{ {
if (compressed) if (compressed)
disk2.setOriginalPath (originalPath); disk.setOriginalPath (originalPath);
return disk2; return disk;
} }
AppleDisk appleDisk = new AppleDisk (file, (int) file.length () / 4096, 8); AppleDisk appleDisk = new AppleDisk (file, (int) file.length () / 4096, 8);
return new DataDisk (appleDisk); return new DataDisk (appleDisk);
} }
if (suffix.equals ("img"))
{
disk = checkDiskCopyDisk (file);
if (disk != null)
return disk;
}
// Toolkit.do = 143488 // Toolkit.do = 143488
if (((suffix.equals ("po") || suffix.equals ("dsk") || suffix.equals ("do")) if (((suffix.equals ("po") || suffix.equals ("dsk") || suffix.equals ("do"))
&& file.length () > 143360)) && file.length () > 143360))
@ -699,7 +706,6 @@ public class DiskFactory
catch (Exception e) catch (Exception e)
{ {
e.printStackTrace (); e.printStackTrace ();
// System.out.println (e);
} }
if (debug) if (debug)
System.out.println ("Not a 2mg disk"); System.out.println ("Not a 2mg disk");
@ -707,6 +713,33 @@ public class DiskFactory
return null; return null;
} }
// ---------------------------------------------------------------------------------//
private static FormattedDisk checkDiskCopyDisk (File file)
// ---------------------------------------------------------------------------------//
{
if (debug)
System.out.println ("Checking DiskCopy disk");
try
{
AppleDisk disk = new AppleDisk (file, 0, 0);
if (disk.getTotalBlocks () > 0)
{
if (ProdosDisk.isCorrectFormat (disk))
return new ProdosDisk (disk);
}
}
catch (Exception e)
{
e.printStackTrace ();
}
if (debug)
System.out.println ("Not a DiskCopy disk");
return null;
}
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
private static FormattedDisk checkPascalDisk (AppleDisk disk) private static FormattedDisk checkPascalDisk (AppleDisk disk)
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//

View File

@ -0,0 +1,54 @@
package com.bytezone.diskbrowser.disk;
import com.bytezone.diskbrowser.utilities.HexFormatter;
import com.bytezone.diskbrowser.utilities.Utility;
// -----------------------------------------------------------------------------------//
public class PrefixDiskCopy
// -----------------------------------------------------------------------------------//
{
private String name;
private int dataSize;
private int tagSize;
private int encoding;
private int format;
private int id;
// ---------------------------------------------------------------------------------//
public PrefixDiskCopy (byte[] buffer)
// ---------------------------------------------------------------------------------//
{
int nameLength = buffer[0] * 0xFF;
if (nameLength < 1 || nameLength > 0x3F)
name = HexFormatter.getPascalString (buffer, 0);
dataSize = Utility.getLongBigEndian (buffer, 0x40);
tagSize = Utility.getLongBigEndian (buffer, 0x44);
encoding = buffer[0x50] & 0xFF;
format = buffer[0x51] & 0xFF;
id = Utility.getWordBigEndian (buffer, 0x52);
}
// ---------------------------------------------------------------------------------//
int getBlocks ()
// ---------------------------------------------------------------------------------//
{
return dataSize / 512;
}
// ---------------------------------------------------------------------------------//
@Override
public String toString ()
// ---------------------------------------------------------------------------------//
{
StringBuilder text = new StringBuilder ();
text.append (String.format ("Name : %s%n", name));
text.append (String.format ("Data size : %08X (%<,d)%n", dataSize));
text.append (String.format ("Tag size : %08X (%<,d)%n", tagSize));
text.append (String.format ("Encoding : %02X%n", encoding));
text.append (String.format ("Format : %02X%n", format));
text.append (String.format ("ID : %04X%n", id));
return text.toString ();
}
}

View File

@ -23,6 +23,7 @@ import com.bytezone.diskbrowser.applefile.IconFile;
import com.bytezone.diskbrowser.applefile.IntegerBasicProgram; import com.bytezone.diskbrowser.applefile.IntegerBasicProgram;
import com.bytezone.diskbrowser.applefile.LodeRunner; import com.bytezone.diskbrowser.applefile.LodeRunner;
import com.bytezone.diskbrowser.applefile.MerlinSource; import com.bytezone.diskbrowser.applefile.MerlinSource;
import com.bytezone.diskbrowser.applefile.ObjectModule;
import com.bytezone.diskbrowser.applefile.OriginalHiResImage; import com.bytezone.diskbrowser.applefile.OriginalHiResImage;
import com.bytezone.diskbrowser.applefile.PascalArea; import com.bytezone.diskbrowser.applefile.PascalArea;
import com.bytezone.diskbrowser.applefile.QuickDrawFont; import com.bytezone.diskbrowser.applefile.QuickDrawFont;
@ -433,7 +434,7 @@ class FileEntry extends CatalogEntry implements ProdosConstants
break; break;
case FILE_TYPE_IIGS_APPLICATION: case FILE_TYPE_IIGS_APPLICATION:
file = new AssemblerProgram (name, buffer, auxType); file = new ObjectModule (name, exactBuffer, auxType);
break; break;
case FILE_TYPE_IIGS_DEVICE_DRIVER: case FILE_TYPE_IIGS_DEVICE_DRIVER:

View File

@ -18,7 +18,7 @@ public class Utility
// -----------------------------------------------------------------------------------// // -----------------------------------------------------------------------------------//
{ {
public static final List<String> suffixes = public static final List<String> suffixes =
Arrays.asList ("po", "dsk", "do", "hdv", "2mg", "v2d", "d13", "sdk", "woz"); Arrays.asList ("po", "dsk", "do", "hdv", "2mg", "v2d", "d13", "sdk", "woz", "img");
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
public static boolean test (Graphics2D g) public static boolean test (Graphics2D g)
@ -92,6 +92,19 @@ public class Utility
return val; return val;
} }
// ---------------------------------------------------------------------------------//
public static int getWordBigEndian (byte[] buffer, int ptr)
// ---------------------------------------------------------------------------------//
{
int val = 0;
for (int i = 0; i < 2; i++)
{
val <<= 8;
val += buffer[ptr + i] & 0xFF;
}
return val;
}
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//
public static int unsignedShort (byte[] buffer, int ptr) public static int unsignedShort (byte[] buffer, int ptr)
// ---------------------------------------------------------------------------------// // ---------------------------------------------------------------------------------//