use DualDos for Unidos

This commit is contained in:
Denis Molony 2019-11-13 08:18:42 +10:00
parent a32160cc33
commit 8b9b9db2eb
6 changed files with 124 additions and 68 deletions

View File

@ -134,7 +134,7 @@ public abstract class AbstractFormattedDisk implements FormattedDisk
case 1600:
if (disk.getSectorsPerTrack () == 32)
gridLayout = new Dimension (32, 50);
gridLayout = new Dimension (disk.getSectorsPerTrack (), disk.getTotalTracks ());
else
gridLayout = new Dimension (16, 100);
break;

View File

@ -31,7 +31,7 @@ public class AppleDisk implements Disk
private final byte[] diskBuffer; // contains the disk contents in memory
private final int tracks; // usually 35 for floppy disks
private int sectors; // 8 or 16
private int sectors; // 8 or 16 (or 32 for unidos)
private int blocks; // 280 or 560 for floppy disks, higher for HD
private final int trackSize; // 4096
@ -84,9 +84,15 @@ public class AppleDisk implements Disk
private WozFile wozFile;
private final boolean debug = true;
private final boolean debug = false;
public AppleDisk (File file, int tracks, int sectors) throws FileFormatException
{
this (file, tracks, sectors, 0);
}
public AppleDisk (File file, int tracks, int sectors, int skip)
throws FileFormatException
{
assert (file.exists ()) : "No such path :" + file.getAbsolutePath ();
assert (!file.isDirectory ()) : "File is directory :" + file.getAbsolutePath ();
@ -100,7 +106,7 @@ public class AppleDisk implements Disk
byte[] buffer = getPrefix (file); // HDV could be a 2mg
String prefix = new String (buffer, 0, 4);
int skip = 0;
// int skip = 0;
if (suffix.equalsIgnoreCase ("2mg") || "2IMG".equals (prefix))
{
@ -158,7 +164,7 @@ public class AppleDisk implements Disk
}
else if (suffix.equalsIgnoreCase ("HDV"))
{
// this.blocks = (int) file.length () / 4096 * 8; // reduce blocks to a multiple of 8
//this.blocks = (int) file.length () / 4096 * 8; // reduce blocks to a multiple of 8
this.blocks = tracks * sectors;
this.sectorSize = 512;
this.trackSize = sectors * sectorSize;

View File

@ -201,14 +201,17 @@ public class DiskFactory
return disk;
}
if (file.length () == 819200)
if (file.length () == 819200) // 800K 3.5"
{
if (debug)
System.out.println ("UniDos ?");
// 2 x 400k disk images
AppleDisk appleDisk = new AppleDisk (file, 50, 32);
disk = checkUnidos (appleDisk);
return disk == null ? new DataDisk (appleDisk) : disk;
AppleDisk appleDisk1 = new AppleDisk (file, 50, 32);
AppleDisk appleDisk2 = new AppleDisk (file, 50, 32, 409600);
disk = checkUnidos (appleDisk1);
disk2 = checkUnidos (appleDisk2);
if (disk != null && disk2 != null)
return new DualDosDisk (disk, disk2);
}
if (debug)
@ -399,7 +402,7 @@ public class DiskFactory
if (disk2 != null)
disk = new DualDosDisk (disk, disk2);
}
else if (checksum == 3028642627L //
else if (checksum == 3028642627L //
|| checksum == 2070151659L) // Enchanter
{
if (debug)

View File

@ -13,6 +13,7 @@ import com.bytezone.diskbrowser.applefile.AppleFileSource;
import com.bytezone.diskbrowser.gui.DataSource;
// Apple Assembly Lines disks are dual-dos
// Should be renamed MultiVolumeDisk (and allow >2 volumes)
public class DualDosDisk implements FormattedDisk
{

View File

@ -235,7 +235,6 @@ public class DosDisk extends AbstractFormattedDisk
{
disk.setInterleave (0);
int catalogBlocks = checkFormat (disk);
System.out.printf ("Catalog blocks: %d%n", catalogBlocks);
if (catalogBlocks > 3)
return true;
@ -436,10 +435,10 @@ public class DosDisk extends AbstractFormattedDisk
*
There were actually three versions of DOS 3.3 that Apple released without
bumping the version number:
The first version that was released had FPBASIC and INTBASIC files that were 50
sectors in size.
The second version of DOS 3.3, often referred to as DOS 3.3e, appeared at the
time the Apple IIe was released. In this version, the FPBASIC and INTBASIC files
were 42 sectors in size. The changes introduced at that time included code to turn
@ -447,12 +446,12 @@ public class DosDisk extends AbstractFormattedDisk
command. This fix reportedly introduced an even worse bug, but as the command was
not heavily used it did not make much of an impact on most programmers. The APPEND
fix was applied by utilizing some formerly unused space in the DOS 3.3 code.
The third version of DOS 3.3 appeared just before the first release of ProDOS.
The only mention of this in the press was in the DOSTalk column of Softalk magazine.
This final version of DOS 3.3 included a different fix for the APPEND bug, using
another bit of unused space in DOS 3.3.
With regard to the FPBASIC and INTBASIC files: There were three differences between
the 50 sector and the 42 sector versions of the INTBASIC file. Firstly, the
$F800-$FFFF section was removed. This area was the code for the Monitor, and with

View File

@ -34,7 +34,7 @@ class DosVTOCSector extends AbstractSector
maxTracks = buffer[52] & 0xFF;
maxSectors = buffer[53] & 0xFF;
sectorSize = HexFormatter.intValue (buffer[54], buffer[55]);
flagSectors ();
flagSectors2 ();
}
@Override
@ -91,7 +91,7 @@ class DosVTOCSector extends AbstractSector
else if (i == 124)
extra = "(VTOC and Catalog)";
addText (text, buffer, i, 4, String.format ("Track %02X %s %s",
(i - firstSector) / 4, getBitmap (buffer[i], buffer[i + 1]), extra));
(i - firstSector) / 4, getBitmap (buffer, i), extra));
}
text.deleteCharAt (text.length () - 1);
@ -133,12 +133,10 @@ class DosVTOCSector extends AbstractSector
String extra = "";
if (i == firstSector && bootSectorEmpty)
extra = "(unusable)";
// else if (i <= 64 && !bootSectorEmpty)
// extra = "(reserved for DOS)";
// else if (i == 124)
// extra = "(VTOC and Catalog)";
addText (text, buffer, i, 4, String.format ("Track %02X %s %s",
(i - firstSector) / 4, getBitmap (buffer[i], buffer[i + 1]), extra));
String bits = getBitmap (buffer, i);
int track = (i - firstSector) / 4;
addText (text, buffer, i, 4,
String.format ("Track %02X %s %s", track, bits, extra));
}
text.deleteCharAt (text.length () - 1);
@ -146,63 +144,112 @@ class DosVTOCSector extends AbstractSector
return text.toString ();
}
private String getBitmap (byte left, byte right)
// private String getBitmap (byte left, byte right)
// {
// StringBuilder text = new StringBuilder ();
//
// int base = maxSectors == 13 ? 3 : 0;
// right >>= base;
//
// for (int i = base; i < 8; i++)
// {
// if ((right & 0x01) == 1)
// text.append (".");
// else
// text.append ("X");
// right >>= 1;
// }
//
// for (int i = 0; i < 8; i++)
// {
// if ((left & 0x01) == 1)
// text.append (".");
// else
// text.append ("X");
// left >>= 1;
// }
//
// return text.toString ();
// }
private String getBitmap (byte[] buffer, int offset)
{
int base = maxSectors == 13 ? 3 : 0;
right >>= base;
StringBuilder text = new StringBuilder ();
for (int i = base; i < 8; i++)
{
if ((right & 0x01) == 1)
text.append (".");
else
text.append ("X");
right >>= 1;
}
for (int i = 0; i < 8; i++)
{
if ((left & 0x01) == 1)
text.append (".");
else
text.append ("X");
left >>= 1;
}
return text.toString ();
int value = HexFormatter.getLongBigEndian (buffer, offset);
String bits = "0000000000000000000000000000000" + Integer.toBinaryString (value);
bits = bits.substring (bits.length () - 32);
bits = bits.substring (0, maxSectors);
bits = bits.replace ('0', 'X');
bits = bits.replace ('1', '.');
text.append (bits);
return text.reverse ().toString ();
}
public void flagSectors ()
private void flagSectors2 ()
{
int block = 0;
int base = maxSectors == 13 ? 3 : 0;
int firstSector = 0x38;
int max = maxTracks * 4 + firstSector;
for (int i = firstSector; i < max; i += 4)
{
block = check (buffer[i + 1], block, base);
block = check (buffer[i], block, 0);
int track = (i - firstSector) / 4;
String bits = getBitmap (buffer, i);
// System.out.printf ("%08X %s%n", track, bits);
int blockNo = track * maxSectors;
char[] chars = bits.toCharArray ();
for (int sector = 0; sector < maxSectors; sector++)
{
// System.out.printf ("%3d %s%n", blockNo, chars[sector]);
if (chars[sector] == '.')
{
parentDisk.setSectorFree (blockNo, true);
++freeSectors;
}
else
{
parentDisk.setSectorFree (blockNo, false);
++usedSectors;
}
++blockNo;
}
}
}
private int check (byte b, int block, int base)
{
b >>= base;
for (int i = base; i < 8; i++)
{
if ((b & 0x01) == 1)
{
parentDisk.setSectorFree (block, true);
++freeSectors;
}
else
{
parentDisk.setSectorFree (block, false);
++usedSectors;
}
block++;
b >>= 1;
}
return block;
}
// private void flagSectors ()
// {
// int block = 0;
// int base = maxSectors == 13 ? 3 : 0;
// int firstSector = 0x38;
// int max = maxTracks * 4 + firstSector;
// for (int i = firstSector; i < max; i += 4)
// {
// block = check (buffer[i + 1], block, base);
// block = check (buffer[i], block, 0);
// }
// }
// private int check (byte b, int block, int base)
// {
// b >>= base;
// for (int i = base; i < 8; i++)
// {
// if ((b & 0x01) == 1)
// {
// parentDisk.setSectorFree (block, true);
// ++freeSectors;
// }
// else
// {
// parentDisk.setSectorFree (block, false);
// ++usedSectors;
// }
// block++;
// b >>= 1;
// }
// return block;
// }
// duplicate of DosCatalogSector.getName()
private String getName (byte[] buffer, int offset)