character ROM display

This commit is contained in:
Denis Molony 2018-08-18 13:24:22 +10:00
parent db9f0edb52
commit e0890a2a81
6 changed files with 207 additions and 3 deletions

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

View File

@ -1,5 +1,6 @@
package com.bytezone.diskbrowser.applefile;
// Found on Pascal disks
public class Charset extends AbstractFile
{
public Charset (String name, byte[] buffer)

View File

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

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

View File

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

View File

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