diff --git a/Source/AppleIIGo.java b/Source/AppleIIGo.java index f5ddba9..8679db9 100644 --- a/Source/AppleIIGo.java +++ b/Source/AppleIIGo.java @@ -8,6 +8,12 @@ * * Change list: * + * Version 1.0.4 - changes by Nick: + * + * - added support for .PO (ProDOS order) disk images (also inside ZIP archives) + * - added Command key for Closed-Apple on Mac OS X + * - added Home and End keys for Open-Apple and Closed-Apple on full keyboards + * * Version 1.0.3 - changes by Nick: * - fixed paddle values for scaled display window * - added "digital" joystick support via numeric keypad arrows @@ -39,6 +45,7 @@ import java.io.OutputStream; import java.net.MalformedURLException; import java.net.URL; import java.util.zip.GZIPInputStream; +import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; /** @@ -48,7 +55,7 @@ import java.util.zip.ZipInputStream; public class AppleIIGo extends Applet implements KeyListener, ComponentListener, MouseListener, MouseMotionListener { - final String version = "1.0.3"; + final String version = "1.0.4"; final String versionString = "AppleIIGo Version " + version; // Class instances @@ -216,8 +223,15 @@ public class AppleIIGo extends Applet implements KeyListener, ComponentListener, * Open input stream */ private DataInputStream openInputStream(String resource) { + return openInputStream(resource, null); + } + + private DataInputStream openInputStream(String resource, StringBuffer OutFilename) { InputStream is = null; - + + if (OutFilename != null) + OutFilename.setLength(0); + try { URL url = new URL(getCodeBase(), resource); debug("resource: " + url.toString()); @@ -230,7 +244,21 @@ public class AppleIIGo extends Applet implements KeyListener, ComponentListener, else if (resource.toLowerCase().endsWith(".zip")) { is = new ZipInputStream(is); - ((ZipInputStream)is).getNextEntry(); + ZipEntry entry = ((ZipInputStream)is).getNextEntry(); + if (OutFilename != null) + { + OutFilename.append(entry.getName()); + } + } + else + { + if (OutFilename != null) + { + int slashPos = resource.lastIndexOf('/'); + int backslashPos = resource.lastIndexOf('\\'); + int index = Math.max(slashPos, backslashPos); + OutFilename.append(resource.substring((index > 0) ? index : 0)); + } } } catch (Exception e) { debug("Exeption: " + e.getLocalizedMessage()); @@ -296,8 +324,12 @@ public class AppleIIGo extends Applet implements KeyListener, ComponentListener, diskDriveResource[drive] = resource; - DataInputStream is = openInputStream(resource); - success = disk.readDisk(drive, is, 254, false); + StringBuffer diskname = new StringBuffer(); + DataInputStream is = openInputStream(resource, diskname); + String lowerDiskname = diskname.toString().toLowerCase(); + boolean dos = lowerDiskname.indexOf(".po") == -1; + + success = disk.readDisk(drive, is, 254, dos, false); is.close(); } catch (Exception e) { debug("Exeption: " + e.getLocalizedMessage()); @@ -360,6 +392,10 @@ public class AppleIIGo extends Applet implements KeyListener, ComponentListener, public void keyPressed(KeyEvent e) { switch(e.getKeyCode()) { + + case KeyEvent.VK_META: + apple.paddle.setButton(1, true); + break; case KeyEvent.VK_ALT: if (e.getKeyLocation() == KeyEvent.KEY_LOCATION_LEFT) { @@ -427,7 +463,12 @@ public class AppleIIGo extends Applet implements KeyListener, ComponentListener, break; case KeyEvent.VK_HOME: if (e.isControlDown()) - apple.restart(); + apple.restart(); + else + apple.paddle.setButton(0, true); + break; + case KeyEvent.VK_END: + apple.paddle.setButton(1, true); break; case KeyEvent.VK_F1: showStatus("AppleIIGo Version " + version); @@ -488,6 +529,9 @@ public class AppleIIGo extends Applet implements KeyListener, ComponentListener, public void keyReleased(KeyEvent e) { switch(e.getKeyCode()) { + case KeyEvent.VK_META: + apple.paddle.setButton(1, false); + break; case KeyEvent.VK_ALT: if (e.getKeyLocation() == KeyEvent.KEY_LOCATION_LEFT) { @@ -524,6 +568,13 @@ public class AppleIIGo extends Applet implements KeyListener, ComponentListener, apple.paddle.setPaddlePos(1, 127); } break; + case KeyEvent.VK_HOME: + if (!e.isControlDown()) + { + apple.paddle.setButton(0, false); + } + case KeyEvent.VK_END: + apple.paddle.setButton(1, false); } } diff --git a/Source/DiskII.java b/Source/DiskII.java index d9037da..9150380 100644 --- a/Source/DiskII.java +++ b/Source/DiskII.java @@ -85,10 +85,15 @@ public class DiskII extends Peripheral { private int[] gcrBuffer2 = new int[86]; // Physical sector to DOS 3.3 logical sector table - private static final int[] gcrLogicalSector = { + private static final int[] gcrLogicalDos33Sector = { 0x0, 0x7, 0xE, 0x6, 0xD, 0x5, 0xC, 0x4, 0xB, 0x3, 0xA, 0x2, 0x9, 0x1, 0x8, 0xF }; + // Physical sector to DOS 3.3 logical sector table + private static final int[] gcrLogicalProdosSector = { + 0x0, 0x8, 0x1, 0x9, 0x2, 0xA, 0x3, 0xB, + 0x4, 0xC, 0x5, 0xD, 0x6, 0xE, 0x7, 0xF }; + // Temporary variables for conversion private byte[] gcrNibbles = new byte[RAW_TRACK_BYTES]; private int gcrNibblesPos; @@ -101,8 +106,8 @@ public class DiskII extends Peripheral { public DiskII() { super(); - readDisk(0, null, 254, false); - readDisk(1, null, 254, false); + readDisk(0, null, 254, true, false); + readDisk(1, null, 254, true, false); } /** @@ -265,7 +270,7 @@ public class DiskII extends Peripheral { * @param is InputStream * @param drive Disk II drive */ - public boolean readDisk(int drive, DataInputStream is, int volume, boolean isWriteProtected) { + public boolean readDisk(int drive, DataInputStream is, int volume, boolean dos, boolean isWriteProtected) { byte[] track = new byte[RAW_TRACK_BYTES]; try { @@ -274,7 +279,7 @@ public class DiskII extends Peripheral { if (is != null) { is.readFully(track, 0, DOS_TRACK_BYTES); - trackToNibbles(track, disk[drive][trackNum], volume, trackNum); + trackToNibbles(track, disk[drive][trackNum], volume, trackNum, dos); } } @@ -487,12 +492,13 @@ public class DiskII extends Peripheral { /** * Converts a track to nibbles */ - private void trackToNibbles(byte[] track, byte[] nibbles, int volumeNum, int trackNum) { + private void trackToNibbles(byte[] track, byte[] nibbles, int volumeNum, int trackNum, boolean dos) { this.gcrNibbles = nibbles; gcrNibblesPos = 0; + int logicalSector[] = (dos) ? gcrLogicalDos33Sector : gcrLogicalProdosSector; for (int sectorNum = 0; sectorNum < DOS_NUM_SECTORS; sectorNum++) { - encode62(track, gcrLogicalSector[sectorNum] << 8); + encode62(track, logicalSector[sectorNum] << 8); writeSync(12); writeAddressField(volumeNum, trackNum, sectorNum); writeSync(8);