mirror of
https://github.com/dmolony/DiskBrowser.git
synced 2024-11-29 11:49:29 +00:00
character ROM display
This commit is contained in:
parent
db9f0edb52
commit
e0890a2a81
109
src/com/bytezone/diskbrowser/applefile/CharacterRom.java
Normal file
109
src/com/bytezone/diskbrowser/applefile/CharacterRom.java
Normal file
@ -0,0 +1,109 @@
|
||||
package com.bytezone.diskbrowser.applefile;
|
||||
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBuffer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class CharacterRom extends AbstractFile
|
||||
{
|
||||
String description;
|
||||
List<Character> characters = new ArrayList<> ();
|
||||
|
||||
public CharacterRom (String name, byte[] buffer)
|
||||
{
|
||||
super (name, buffer);
|
||||
|
||||
description = new String (buffer, 16, 16);
|
||||
|
||||
int gapX = 4;
|
||||
int gapY = 4;
|
||||
int sizeX = 7;
|
||||
int sizeY = 8;
|
||||
int marginX = 2;
|
||||
int marginY = 2;
|
||||
|
||||
image = new BufferedImage (8 * (sizeX + gapX), 12 * (sizeY + gapY),
|
||||
BufferedImage.TYPE_BYTE_GRAY);
|
||||
Graphics2D g2d = image.createGraphics ();
|
||||
g2d.setComposite (AlphaComposite.getInstance (AlphaComposite.SRC_OVER, (float) 1.0));
|
||||
|
||||
int x = marginX;
|
||||
int y = marginY;
|
||||
int count = 0;
|
||||
int ptr = 256;
|
||||
|
||||
while (ptr < buffer.length)
|
||||
{
|
||||
Character character = new Character (buffer, ptr);
|
||||
characters.add (character);
|
||||
ptr += 8;
|
||||
|
||||
g2d.drawImage (character.image, x, y, null);
|
||||
x += sizeX + gapX;
|
||||
if (++count % 8 == 0)
|
||||
{
|
||||
x = marginX;
|
||||
y += sizeY + gapY;
|
||||
}
|
||||
}
|
||||
g2d.dispose ();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText ()
|
||||
{
|
||||
StringBuilder text = new StringBuilder (description + "\n\n");
|
||||
for (int i = 256; i < buffer.length; i += 8)
|
||||
{
|
||||
for (int line = 0; line < 8; line++)
|
||||
{
|
||||
int value = buffer[i + line] & 0xFF;
|
||||
for (int bit = 0; bit < 8; bit++)
|
||||
{
|
||||
text.append ((value & 0x80) != 0 ? "X" : ".");
|
||||
value <<= 1;
|
||||
}
|
||||
text.append ("\n");
|
||||
}
|
||||
text.append ("\n");
|
||||
}
|
||||
return text.toString ();
|
||||
}
|
||||
|
||||
public static boolean isRom (byte[] buffer)
|
||||
{
|
||||
if (buffer.length < 4)
|
||||
return false;
|
||||
|
||||
// no idea what these mean
|
||||
// BD 41 53 10 A0 07 08
|
||||
return buffer[0] == (byte) 0xBD && buffer[1] == (byte) 0x41
|
||||
&& buffer[2] == (byte) 0x53 && buffer[3] == (byte) 0x10;
|
||||
}
|
||||
|
||||
class Character
|
||||
{
|
||||
private final BufferedImage image;
|
||||
|
||||
public Character (byte[] buffer, int ptr)
|
||||
{
|
||||
// draw the image
|
||||
image = new BufferedImage (7, 8, BufferedImage.TYPE_BYTE_GRAY);
|
||||
DataBuffer dataBuffer = image.getRaster ().getDataBuffer ();
|
||||
int element = 0;
|
||||
|
||||
for (int line = 0; line < 8; line++)
|
||||
{
|
||||
int value = buffer[ptr++] & 0xFF;
|
||||
for (int bit = 0; bit < 7; bit++)
|
||||
{
|
||||
dataBuffer.setElem (element++, (value & 0x80) != 0 ? 255 : 0);
|
||||
value <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package com.bytezone.diskbrowser.applefile;
|
||||
|
||||
// Found on Pascal disks
|
||||
public class Charset extends AbstractFile
|
||||
{
|
||||
public Charset (String name, byte[] buffer)
|
||||
|
@ -25,6 +25,8 @@ class MC3470
|
||||
private final byte[] dataBuffer = new byte[MAX_DATA];
|
||||
private int dataPtr;
|
||||
|
||||
private final byte[] rawBytes = new byte[8000];
|
||||
|
||||
// D5 AA 96 16 sector address prologue
|
||||
// D5 AA B5 13 sector address prologue
|
||||
// D5 AA AD data prologue
|
||||
@ -135,6 +137,54 @@ class MC3470
|
||||
return diskSectors;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// getNibbleTrack
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
public NibbleTrack getNibbleTrack (byte[] buffer, int offset, int length, int bitsUsed)
|
||||
{
|
||||
int rawPtr = 0;
|
||||
|
||||
byte value = 0; // value to be stored
|
||||
final int max = offset + length;
|
||||
int totalBits = 0;
|
||||
int zeroBits = 0;
|
||||
|
||||
while (offset < max)
|
||||
{
|
||||
byte b = buffer[offset++];
|
||||
for (int mask = 0x80; mask != 0; mask >>>= 1)
|
||||
{
|
||||
value <<= 1;
|
||||
if ((b & mask) != 0)
|
||||
{
|
||||
value |= 0x01;
|
||||
zeroBits = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
++zeroBits;
|
||||
if (zeroBits > 2)
|
||||
System.out.println (zeroBits + " consecutive zeroes");
|
||||
}
|
||||
|
||||
if ((value & 0x80) != 0) // value is not valid until the hi-bit is set
|
||||
{
|
||||
rawBytes[rawPtr++] = value;
|
||||
value = 0;
|
||||
}
|
||||
if (++totalBits == bitsUsed) // only use this many bits
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (value != 0)
|
||||
rawBytes[rawPtr++] = value;
|
||||
|
||||
NibbleTrack track = new NibbleTrack (rawBytes, rawPtr, bitsUsed);
|
||||
return track;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// checkState
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
14
src/com/bytezone/diskbrowser/nib/NibbleTrack.java
Normal file
14
src/com/bytezone/diskbrowser/nib/NibbleTrack.java
Normal file
@ -0,0 +1,14 @@
|
||||
package com.bytezone.diskbrowser.nib;
|
||||
|
||||
public class NibbleTrack
|
||||
{
|
||||
byte[] buffer;
|
||||
int bitsUsed;
|
||||
|
||||
public NibbleTrack (byte[] buffer, int length, int bitsUsed)
|
||||
{
|
||||
this.bitsUsed = bitsUsed;
|
||||
this.buffer = new byte[length];
|
||||
System.arraycopy (buffer, 0, this.buffer, 0, length);
|
||||
}
|
||||
}
|
@ -4,8 +4,10 @@ import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.bytezone.diskbrowser.utilities.HexFormatter;
|
||||
import com.bytezone.diskbrowser.utilities.Utility;
|
||||
|
||||
public class WozFile
|
||||
@ -24,18 +26,20 @@ public class WozFile
|
||||
byte[] diskBuffer;
|
||||
|
||||
private final MC3470 mc3470 = new MC3470 ();
|
||||
private final List<NibbleTrack> nibbleTracks = new ArrayList<> (40);
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// constructor
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
public WozFile (File file) throws Exception
|
||||
public WozFile (File file) throws DiskNibbleException
|
||||
{
|
||||
this.file = file;
|
||||
byte[] buffer = readFile ();
|
||||
boolean valid = false;
|
||||
|
||||
if (!matches (WOZ_FILE_HEADER, buffer))
|
||||
throw new Exception ("Header error");
|
||||
throw new DiskNibbleException ("Header error");
|
||||
|
||||
int checksum1 = readInt (buffer, 8, 4);
|
||||
int checksum2 = Utility.crc32 (buffer, 12, buffer.length - 12);
|
||||
@ -43,7 +47,7 @@ public class WozFile
|
||||
{
|
||||
System.out.printf ("Stored checksum : %08X%n", checksum1);
|
||||
System.out.printf ("Calculated checksum : %08X%n", checksum2);
|
||||
throw new Exception ("Checksum error");
|
||||
throw new DiskNibbleException ("Checksum error");
|
||||
}
|
||||
|
||||
int ptr = 12;
|
||||
@ -110,6 +114,7 @@ public class WozFile
|
||||
|
||||
try
|
||||
{
|
||||
// nibbleTracks.add (mc3470.getNibbleTrack (buffer, ptr, bytesUsed, bitCount));
|
||||
List<RawDiskSector> diskSectors =
|
||||
mc3470.readTrack (buffer, ptr, bytesUsed, bitCount);
|
||||
|
||||
@ -150,6 +155,28 @@ public class WozFile
|
||||
ptr += chunkSize;
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid)
|
||||
readNibbleTracks (buffer);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
// readNibbleTracks
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
||||
private void readNibbleTracks (byte[] buffer)
|
||||
{
|
||||
for (int track = 0; track < 35; track++)
|
||||
{
|
||||
int ptr = track * 6656 + 256;
|
||||
|
||||
int bytesUsed = readInt (buffer, ptr + DATA_SIZE, 2);
|
||||
int bitCount = readInt (buffer, ptr + DATA_SIZE + 2, 2);
|
||||
|
||||
NibbleTrack nibbleTrack = mc3470.getNibbleTrack (buffer, ptr, bytesUsed, bitCount);
|
||||
nibbleTracks.add (nibbleTrack);
|
||||
}
|
||||
System.out.println (HexFormatter.format (nibbleTracks.get (0).buffer));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------//
|
||||
|
@ -264,6 +264,9 @@ class FileEntry extends CatalogEntry implements ProdosConstants
|
||||
file = new OriginalHiResImage (name, exactBuffer, auxType);
|
||||
else if (endOfFile == 38400 && name.startsWith ("LVL."))
|
||||
file = new LodeRunner (name, exactBuffer);
|
||||
else if (auxType == 0x1000 && endOfFile == 0x400
|
||||
&& CharacterRom.isRom (exactBuffer))
|
||||
file = new CharacterRom (name, exactBuffer);
|
||||
else
|
||||
{
|
||||
file = new AssemblerProgram (name, exactBuffer, auxType);
|
||||
|
Loading…
Reference in New Issue
Block a user