This commit is contained in:
umjammer 2017-11-21 09:36:54 +09:00
parent a2139c12ea
commit 4d3949def5
13 changed files with 4281 additions and 4280 deletions

View File

@ -21,15 +21,15 @@ http://vavivavi.blogspot.com/
* DONE * DONE
improve pad control improve pad control
disk selection mode disk selection mode
virtual keyboard virtual keyboard
.nib reader .nib reader
* INSTALL * INSTALL
1. unpack bdjappleii-x.xx.rar 1. unpack bdjappleii-x.xx.rar
2. copy AVCHD directory into 2. copy AVCHD directory into
(SD Card) /PRIVATE directory (SD Card) /PRIVATE directory
@ -38,7 +38,7 @@ http://vavivavi.blogspot.com/
3. copy APPLE2E.ROM into .../AVCHD directory 3. copy APPLE2E.ROM into .../AVCHD directory
4. copy your .dsk image into .../AVCHD directory 4. copy your .dsk or .nib image into .../AVCHD directory
5. modify .../AVCHD/appleii.properties 5. modify .../AVCHD/appleii.properties
@ -70,7 +70,7 @@ http://vavivavi.blogspot.com/
BLUE Button Goto DISK DRIVE 1 MODE BLUE Button Goto DISK DRIVE 1 MODE
GREEN Button Restart GREEN Button Restart
3. DISK DRIVE 1 MODE 3. DISK DRIVE 1 MODE
CIRCLE Select disk image CIRCLE Select disk image
SQUARE Release disk image SQUARE Release disk image
@ -79,7 +79,7 @@ http://vavivavi.blogspot.com/
BLUE Button Goto DISK DRIVE 2 MODE BLUE Button Goto DISK DRIVE 2 MODE
GREEN Button Restart GREEN Button Restart
4. DISK DRIVE 2 MODE 4. DISK DRIVE 2 MODE
CIRCLE Select disk image CIRCLE Select disk image
SQUARE Release disk image SQUARE Release disk image
@ -91,7 +91,7 @@ http://vavivavi.blogspot.com/
* ROMz * ROMz
http://apple2.org.za/gswv/a2zine/System/ http://apple2.org.za/gswv/a2zine/System/
ftp://ftp.apple.asimov.net/pub/apple_II/ ftp://ftp.apple.asimov.net/pub/apple_II/
* GAMEz * GAMEz
@ -101,7 +101,7 @@ http://vavivavi.blogspot.com/
0.12 09-Oct-2008 0.12 09-Oct-2008
improve pad control (i fogot keyReleased() method calling at base ;-P) improve pad control (i forgot keyReleased() method calling at base ;-P)
0.11 28-Sep-2008 0.11 28-Sep-2008
@ -110,8 +110,8 @@ http://vavivavi.blogspot.com/
0.10 26-Sep-2008 0.10 26-Sep-2008
virtual keyboard virtual keyboard
add disk selection mode add disk selection mode
.nib reader .nib reader
0.00 15-Sep-2008 0.00 15-Sep-2008

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="Windows-31J"?> <?xml version="1.0" encoding="UTf-8"?>
<!-- ////////////////////////////////////////////////////////////////////// --> <!-- ////////////////////////////////////////////////////////////////////// -->
<!-- Copyright (c) 2008 by umjammer, All rights reserved. --> <!-- Copyright (c) 2008 by umjammer, All rights reserved. -->
@ -7,13 +7,14 @@
<!-- --> <!-- -->
<!-- BD-J Apple II --> <!-- BD-J Apple II -->
<!-- --> <!-- -->
<!-- @author umjammer --> <!-- @author umjammer -->
<!-- @version 0.00 080912 nsano initial version --> <!-- @version 0.00 080912 umjammer initial version -->
<!-- --> <!-- -->
<!-- ////////////////////////////////////////////////////////////////////// --> <!-- ////////////////////////////////////////////////////////////////////// -->
<project name="bdj Apple II" default="run" basedir="."> <project name="bdj Apple II" default="run" basedir=".">
<property environment="env"/>
<property file="local.properties" /> <property file="local.properties" />
<property name="dir.build" value="build"/> <property name="dir.build" value="build"/>
@ -57,7 +58,7 @@
destdir="${dir.build}" destdir="${dir.build}"
source="1.3" source="1.3"
target="1.3" target="1.3"
deprecation="true"> deprecation="true">
<!-- <!--
<bootclasspath> <bootclasspath>
<pathelement location="${dir.bdj}/lib/basis.jar" /> <pathelement location="${dir.bdj}/lib/basis.jar" />
@ -123,7 +124,7 @@
<include name="**/*.properties" /> <include name="**/*.properties" />
</fileset> </fileset>
</copy> </copy>
<java jar="${dir.bdj}/common/xletview.jar" fork="yes"> <java jar="${dir.bdj}/common/xletview.jar" fork="yes">
<!-- <!--
<jvmarg value="-Xprof"/> <jvmarg value="-Xprof"/>

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
* Copyright (c) 2008 by umjammer, All rights reserved. * Copyright (c) 2008 by umjammer, All rights reserved.
* *
* Programmed by umjammer * Programmed by umjammer
* *
* Released under the GPL * Released under the GPL
*/ */
@ -48,7 +48,7 @@ import org.havi.ui.HSceneFactory;
/** /**
* AppleIIApp. * AppleIIApp.
* *
* @author umjammer * @author umjammer
* @version 0.00 080912 umjammer initial version <br> * @version 0.00 080912 umjammer initial version <br>
*/ */
@ -120,7 +120,7 @@ e.printStackTrace(System.err);
private GameVC gameVC; private GameVC gameVC;
/** /**
* <pre> * <pre>
* 1 * 1
* 2 * 2
* 3 * 3
@ -136,12 +136,12 @@ e.printStackTrace(System.err);
* G restart * G restart
* Y reset * Y reset
* O pad button right * O pad button right
* # pad button left * # pad button left
* U pad up * U pad up
* L pad left * L pad left
* R pad right * R pad right
* D pad down * D pad down
* </pre> * </pre>
*/ */
class NormalVC { class NormalVC {
@ -336,20 +336,20 @@ try {
} catch (Throwable t) { // for xletview bug } catch (Throwable t) { // for xletview bug
t.printStackTrace(System.err); t.printStackTrace(System.err);
files = new File[] { files = new File[] {
new File(file, "Lode Runner.dsk"), new File(file, "Lode Runner.dsk"),
new File(file, "Mystery House.dsk"), new File(file, "Mystery House.dsk"),
new File(file, "Tetris II.dsk"), new File(file, "Tetris II.dsk"),
new File(file, "tzone1a.nib"), new File(file, "tzone1a.nib"),
new File(file, "tzone1b.nib"), new File(file, "tzone1b.nib"),
new File(file, "tzone2c.nib"), new File(file, "tzone2c.nib"),
new File(file, "tzone2d.nib"), new File(file, "tzone2d.nib"),
new File(file, "tzone3e.nib"), new File(file, "tzone3e.nib"),
new File(file, "tzone3f.nib"), new File(file, "tzone3f.nib"),
new File(file, "tzone4g.nib"), new File(file, "tzone4g.nib"),
new File(file, "tzone4h.nib"), new File(file, "tzone4h.nib"),
new File(file, "tzone5i.nib"), new File(file, "tzone5i.nib"),
new File(file, "tzone5j.nib"), new File(file, "tzone5j.nib"),
new File(file, "tzone6k.nib"), new File(file, "tzone6k.nib"),
new File(file, "tzone6l.nib"), new File(file, "tzone6l.nib"),
}; };
} }
@ -485,10 +485,10 @@ stat.clear();
break; break;
} }
} }
void mousePressed(MouseEvent e) { void mousePressed(MouseEvent e) {
int modifiers = e.getModifiers(); int modifiers = e.getModifiers();
if ((modifiers & InputEvent.BUTTON3_MASK) != 0) { if ((modifiers & InputEvent.BUTTON3_MASK) != 0) {
game.setButton(0, true); game.setButton(0, true);
} }
@ -499,7 +499,7 @@ stat.clear();
void mouseReleased(MouseEvent e) { void mouseReleased(MouseEvent e) {
int modifiers = e.getModifiers(); int modifiers = e.getModifiers();
if ((modifiers & InputEvent.BUTTON3_MASK) != 0) { if ((modifiers & InputEvent.BUTTON3_MASK) != 0) {
game.setButton(0, false); game.setButton(0, false);
} }
@ -668,7 +668,7 @@ try {
this.diskVCs[0] = new DiskVC(0); this.diskVCs[0] = new DiskVC(0);
this.diskVCs[1] = new DiskVC(1); this.diskVCs[1] = new DiskVC(1);
this.gameVC = new GameVC(); this.gameVC = new GameVC();
mode = MODE_NORMAL; mode = MODE_NORMAL;
System.err.println("mode: -> MODE_NORMAL"); System.err.println("mode: -> MODE_NORMAL");
@ -680,7 +680,7 @@ System.err.println("mode: -> MODE_NORMAL");
} }
/** /**
* <pre> * <pre>
* B mode change * B mode change
* G restart * G restart
* O key select * O key select
@ -688,12 +688,12 @@ System.err.println("mode: -> MODE_NORMAL");
* L key left * L key left
* R key right * R key right
* D key down * D key down
* </pre> * </pre>
*/ */
class KeyBoard { class KeyBoard {
Image image; Image image;
int[][] bounds = { int[][] bounds = {
{ 6, 14, 22, 14 }, { 6, 14, 22, 14 },
{ 31, 14, 22, 14 }, { 31, 14, 22, 14 },
{ 56, 14, 22, 14 }, { 56, 14, 22, 14 },
{ 82, 14, 22, 14 }, { 82, 14, 22, 14 },
@ -780,7 +780,7 @@ System.err.println("mode: -> MODE_NORMAL");
}; };
/** l, r, u, d */ /** l, r, u, d */
int[][] navigation = { int[][] navigation = {
{ 13, 1, 67, 14 }, { 13, 1, 67, 14 },
{ 0, 2, 68, 15 }, { 0, 2, 68, 15 },
{ 1, 3, 69, 16 }, { 1, 3, 69, 16 },
{ 2, 4, 70, 17 }, { 2, 4, 70, 17 },
@ -886,7 +886,7 @@ System.err.println("mode: -> MODE_NORMAL");
final int KEY_SHIFT = -2; final int KEY_SHIFT = -2;
int keyIndex; int keyIndex;
/** normal, shift */ /** normal, shift */
int[][] keyDatum = { int[][] keyData = {
{ 0x1b, 0x1b }, // esc { 0x1b, 0x1b }, // esc
{ -1, -1 }, // f1 { -1, -1 }, // f1
{ -1, -1 }, { -1, -1 },
@ -1007,10 +1007,10 @@ stat.clear();
} }
} }
private void keyPressed() { private void keyPressed() {
int keyCode = keyDatum[keyIndex][shiftIndex]; int keyCode = keyData[keyIndex][shiftIndex];
switch (keyCode) { switch (keyCode) {
case KEY_SHIFT: case KEY_SHIFT:
shiftIndex = 1 - shiftIndex; shiftIndex = 1 - shiftIndex;
System.err.println("VK: SHIFT: " + (shiftIndex == 1 ? "ON" : "OFF")); System.err.println("VK: SHIFT: " + (shiftIndex == 1 ? "ON" : "OFF"));
break; break;
default: default:
@ -1071,7 +1071,7 @@ if (stat.size() > 0) {
/** */ /** */
class GameVC { class GameVC {
int displayScaledSizeX; int displayScaledSizeX;
int displayScaledSizeY; int displayScaledSizeY;
MemoryImageSource mis; MemoryImageSource mis;
Image displayImage; Image displayImage;
Image displayImagePaused; Image displayImagePaused;
@ -1089,7 +1089,7 @@ if (stat.size() > 0) {
} }
/** */ /** */
void paint(Graphics g) { void paint(Graphics g) {
mis.newPixels(); mis.newPixels();
g.drawImage(displayImage, g.drawImage(displayImage,
@ -1099,17 +1099,17 @@ if (stat.size() > 0) {
if (game.isStatMode()) { if (game.isStatMode()) {
g.setColor(Color.black); g.setColor(Color.black);
g.fillRect(displayScaledSizeX, 0, 512, 600); g.fillRect(displayScaledSizeX, 0, 512, 600);
drawStatInfo(g); drawStatInfo(g);
} }
if (game.isPaused()) { if (game.isPaused()) {
g.drawImage(displayImagePaused, g.drawImage(displayImagePaused,
0, 0, displayScaledSizeX, displayScaledSizeY, 0, 0, displayScaledSizeX, displayScaledSizeY,
0, 0, AppleDisplay.DISPLAY_SIZE_X, AppleDisplay.DISPLAY_SIZE_Y, 0, 0, AppleDisplay.DISPLAY_SIZE_X, AppleDisplay.DISPLAY_SIZE_Y,
MyView.this); MyView.this);
} }
if (game.isGlare()) { if (game.isGlare()) {
g.drawImage(displayImageGlare, g.drawImage(displayImageGlare,
0, 0, displayScaledSizeX, displayScaledSizeY, 0, 0, displayScaledSizeX, displayScaledSizeY,

View File

@ -1,6 +1,6 @@
/* /*
* AppleIIGo * AppleIIGo
* The Java Apple II Emulator * The Java Apple II Emulator
* (C) 2006 by Marc S. Ressl(ressl@lonetree.com) * (C) 2006 by Marc S. Ressl(ressl@lonetree.com)
* Released under the GPL * Released under the GPL
*/ */
@ -13,35 +13,35 @@ package vavi.apps.appleii;
* Connects EmAppleII, AppleCanvas * Connects EmAppleII, AppleCanvas
*/ */
public class AppleIIGo { public class AppleIIGo {
// Class instances // Class instances
private EmAppleII apple; private EmAppleII apple;
private AppleDisplay display; private AppleDisplay display;
// private AppleSpeaker speaker; // private AppleSpeaker speaker;
private DiskII disk; private DiskII disk;
// Machine variables // Machine variables
private boolean isCpuPaused; private boolean isCpuPaused;
private boolean isCpuDebugEnabled; private boolean isCpuDebugEnabled;
/** */ /** */
public boolean isCpuDebugEnabled() { public boolean isCpuDebugEnabled() {
return isCpuDebugEnabled; return isCpuDebugEnabled;
} }
// Keyboard variables // Keyboard variables
private boolean keyboardUppercaseOnly; private boolean keyboardUppercaseOnly;
// Paddle variables // Paddle variables
private boolean isPaddleInverted; private boolean isPaddleInverted;
// Disk variables // Disk variables
private String diskDriveResource[] = new String[2]; private String diskDriveResource[] = new String[2];
public String getDiskDriveResource(int drive) { public String getDiskDriveResource(int drive) {
return diskDriveResource[drive]; return diskDriveResource[drive];
} }
private boolean diskWritable; private boolean diskWritable;
/** */ /** */
public interface View { public interface View {
@ -153,7 +153,7 @@ public class AppleIIGo {
isGlare = value; isGlare = value;
display.requestRefresh(); display.requestRefresh();
} }
/** /**
* Get glare * Get glare
*/ */
@ -194,92 +194,92 @@ public class AppleIIGo {
} }
/** /**
* On applet initialization * On applet initialization
*/ */
public void init() { public void init() {
System.err.println("init()"); System.err.println("init()");
// Activate listeners // Activate listeners
// Initialize Apple II emulator // Initialize Apple II emulator
apple = new EmAppleII(view); apple = new EmAppleII(view);
loadRom(getParameter("cpuRom", "")); loadRom(getParameter("cpuRom", ""));
apple.setCpuSpeed(new Integer(getParameter("cpuSpeed", "1000")).intValue()); apple.setCpuSpeed(new Integer(getParameter("cpuSpeed", "1000")).intValue());
isCpuPaused = getParameter("cpuPaused", "false").equals("true"); isCpuPaused = getParameter("cpuPaused", "false").equals("true");
isCpuDebugEnabled = getParameter("cpuDebugEnabled", "false").equals("true"); isCpuDebugEnabled = getParameter("cpuDebugEnabled", "false").equals("true");
apple.setStepMode(getParameter("cpuStepMode", "false").equals("true")); apple.setStepMode(getParameter("cpuStepMode", "false").equals("true"));
// Keyboard
keyboardUppercaseOnly = getParameter("keyboardUppercaseOnly", "true").equals("true");
// Display // Keyboard
display = new AppleDisplay(apple); keyboardUppercaseOnly = getParameter("keyboardUppercaseOnly", "true").equals("true");
display.setScale(new Float(getParameter("displayScale", "1")).floatValue());
display.setRefreshRate(new Integer(getParameter("displayRefreshRate", "10")).intValue());
display.setColorMode(new Integer(getParameter("displayColorMode", "0")).intValue());
setStatMode(getParameter("displayStatMode", "false").equals("true"));
setGlare(getParameter("displayGlare", "false").equals("true"));
// Speaker // Display
// speaker = new AppleSpeaker(apple); display = new AppleDisplay(apple);
// speaker.setVolume(new Integer(getAppletParameter("speakerVolume", "3")).intValue()); display.setScale(new Float(getParameter("displayScale", "1")).floatValue());
display.setRefreshRate(new Integer(getParameter("displayRefreshRate", "10")).intValue());
// Peripherals display.setColorMode(new Integer(getParameter("displayColorMode", "0")).intValue());
disk = new DiskII(); setStatMode(getParameter("displayStatMode", "false").equals("true"));
apple.setPeripheral(disk, 6); setGlare(getParameter("displayGlare", "false").equals("true"));
// Initialize disk drives // Speaker
diskWritable = getParameter("diskWritable", "false").equals("true"); // speaker = new AppleSpeaker(apple);
mountDisk(0, getParameter("diskDrive1", "")); // speaker.setVolume(new Integer(getAppletParameter("speakerVolume", "3")).intValue());
mountDisk(1, getParameter("diskDrive2", ""));
}
public void start() { // Peripherals
// Start CPU disk = new DiskII();
if (!isCpuPaused) { apple.setPeripheral(disk, 6);
resume();
} // Initialize disk drives
} diskWritable = getParameter("diskWritable", "false").equals("true");
mountDisk(0, getParameter("diskDrive1", ""));
mountDisk(1, getParameter("diskDrive2", ""));
}
public void start() {
// Start CPU
if (!isCpuPaused) {
resume();
}
}
/** /**
* On applet destruction * On applet destruction
*/ */
public void destroy() { public void destroy() {
System.err.println("destroy()"); System.err.println("destroy()");
unmountDisk(0); unmountDisk(0);
unmountDisk(1); unmountDisk(1);
} }
/** /**
* Pause emulator * Pause emulator
*/ */
public void pause() { public void pause() {
System.err.println("pause()"); System.err.println("pause()");
isCpuPaused = true; isCpuPaused = true;
apple.setPaused(isCpuPaused); apple.setPaused(isCpuPaused);
display.setPaused(isCpuPaused); display.setPaused(isCpuPaused);
// speaker.setPaused(isCpuPaused); // speaker.setPaused(isCpuPaused);
} }
/** /**
* Resume emulator * Resume emulator
*/ */
public void resume() { public void resume() {
System.err.println("resume()"); System.err.println("resume()");
isCpuPaused = false; isCpuPaused = false;
// speaker.setPaused(isCpuPaused); // speaker.setPaused(isCpuPaused);
display.setPaused(isCpuPaused); display.setPaused(isCpuPaused);
apple.setPaused(isCpuPaused); apple.setPaused(isCpuPaused);
} }
/** /**
* Restarts emulator * Restarts emulator
*/ */
public void restart() { public void restart() {
System.err.println("restart()"); System.err.println("restart()");
apple.restart(); apple.restart();
} }
/** /**
* Resets emulator * Resets emulator
*/ */
@ -288,82 +288,82 @@ System.err.println("reset()");
apple.reset(); apple.reset();
} }
/** /**
* Load ROM * Load ROM
*/ */
public void loadRom(String resource) { public void loadRom(String resource) {
System.err.println("loadRom(resource: " + resource + ")"); System.err.println("loadRom(resource: " + resource + ")");
apple.loadRom(dao, resource); apple.loadRom(dao, resource);
} }
/** /**
* Mount a disk * Mount a disk
*/ */
public boolean mountDisk(int drive, String resource) { public boolean mountDisk(int drive, String resource) {
System.err.println("mountDisk(drive: " + drive + ", resource: " + resource + ")"); System.err.println("mountDisk(drive: " + drive + ", resource: " + resource + ")");
if ((drive < 0) || (drive > 2)) { if ((drive < 0) || (drive > 2)) {
return false; return false;
} }
try {
unmountDisk(drive);
diskDriveResource[drive] = resource; try {
unmountDisk(drive);
diskDriveResource[drive] = resource;
System.err.println("mount: dirve: " + drive + ", " + resource); System.err.println("mount: dirve: " + drive + ", " + resource);
disk.readDisk(dao, drive, resource, 254, false); disk.readDisk(dao, drive, resource, 254, false);
return true; return true;
} catch (Throwable e) { } catch (Throwable e) {
if (e instanceof IllegalStateException) { if (e instanceof IllegalStateException) {
System.err.println("mount: drive: " + drive + ": no disk"); System.err.println("mount: drive: " + drive + ": no disk");
} else { } else {
e.printStackTrace(System.err); e.printStackTrace(System.err);
} }
return false; return false;
} }
} }
/** /**
* Unmount a disk * Unmount a disk
*/ */
public void unmountDisk(int drive) { public void unmountDisk(int drive) {
System.err.println("unmount: drive: " + drive); System.err.println("unmount: drive: " + drive);
if ((drive < 0) || (drive > 2)) { if ((drive < 0) || (drive > 2)) {
return; return;
} }
if (!diskWritable) { if (!diskWritable) {
System.err.println("unmount: drive: " + drive + ", not writable"); System.err.println("unmount: drive: " + drive + ", not writable");
return; return;
} }
try { try {
disk.writeDisk(drive, diskDriveResource[drive]); disk.writeDisk(drive, diskDriveResource[drive]);
} catch (Throwable e) { } catch (Throwable e) {
if (e instanceof NullPointerException) { if (e instanceof NullPointerException) {
System.err.println("unmount: drive: " + drive + ": no disk"); System.err.println("unmount: drive: " + drive + ": no disk");
} else { } else {
e.printStackTrace(System.err); e.printStackTrace(System.err);
} }
} }
} }
/** /**
* Set color mode * Set color mode
*/ */
public void setColorMode(int value) { public void setColorMode(int value) {
System.err.println("setColorMode(value: " + value + ")"); System.err.println("setColorMode(value: " + value + ")");
display.setColorMode(value); display.setColorMode(value);
} }
/** /**
* Get disk activity * Get disk activity
*/ */
public boolean getDiskActivity() { public boolean getDiskActivity() {
return (!isCpuPaused && disk.isMotorOn()); return (!isCpuPaused && disk.isMotorOn());
} }
} }
/* */ /* */

View File

@ -5,276 +5,276 @@
* Released under the GPL * Released under the GPL
* Based on work by Doug Kwan * Based on work by Doug Kwan
*/ */
package vavi.apps.appleii; package vavi.apps.appleii;
public class DiskII extends Peripheral { public class DiskII extends Peripheral {
// ROM (with boot wait cycle optimization) // ROM (with boot wait cycle optimization)
private static final int[] rom = { private static final int[] rom = {
0xa2, 0x20, 0xa0, 0x00, 0xa2, 0x03, 0x86, 0x3c, 0x8a, 0x0a, 0x24, 0x3c, 0xf0, 0x10, 0x05, 0x3c, 0xa2, 0x20, 0xa0, 0x00, 0xa2, 0x03, 0x86, 0x3c, 0x8a, 0x0a, 0x24, 0x3c, 0xf0, 0x10, 0x05, 0x3c,
0x49, 0xff, 0x29, 0x7e, 0xb0, 0x08, 0x4a, 0xd0, 0xfb, 0x98, 0x9d, 0x56, 0x03, 0xc8, 0xe8, 0x10, 0x49, 0xff, 0x29, 0x7e, 0xb0, 0x08, 0x4a, 0xd0, 0xfb, 0x98, 0x9d, 0x56, 0x03, 0xc8, 0xe8, 0x10,
0xe5, 0x20, 0x58, 0xff, 0xba, 0xbd, 0x00, 0x01, 0x0a, 0x0a, 0x0a, 0x0a, 0x85, 0x2b, 0xaa, 0xbd, 0xe5, 0x20, 0x58, 0xff, 0xba, 0xbd, 0x00, 0x01, 0x0a, 0x0a, 0x0a, 0x0a, 0x85, 0x2b, 0xaa, 0xbd,
0x8e, 0xc0, 0xbd, 0x8c, 0xc0, 0xbd, 0x8a, 0xc0, 0xbd, 0x89, 0xc0, 0xa0, 0x50, 0xbd, 0x80, 0xc0, 0x8e, 0xc0, 0xbd, 0x8c, 0xc0, 0xbd, 0x8a, 0xc0, 0xbd, 0x89, 0xc0, 0xa0, 0x50, 0xbd, 0x80, 0xc0,
0x98, 0x29, 0x03, 0x0a, 0x05, 0x2b, 0xaa, 0xbd, 0x81, 0xc0, 0xa9, 0x56, 0xa9, 0x00, 0xea, 0x88, 0x98, 0x29, 0x03, 0x0a, 0x05, 0x2b, 0xaa, 0xbd, 0x81, 0xc0, 0xa9, 0x56, 0xa9, 0x00, 0xea, 0x88,
0x10, 0xeb, 0x85, 0x26, 0x85, 0x3d, 0x85, 0x41, 0xa9, 0x08, 0x85, 0x27, 0x18, 0x08, 0xbd, 0x8c, 0x10, 0xeb, 0x85, 0x26, 0x85, 0x3d, 0x85, 0x41, 0xa9, 0x08, 0x85, 0x27, 0x18, 0x08, 0xbd, 0x8c,
0xc0, 0x10, 0xfb, 0x49, 0xd5, 0xd0, 0xf7, 0xbd, 0x8c, 0xc0, 0x10, 0xfb, 0xc9, 0xaa, 0xd0, 0xf3, 0xc0, 0x10, 0xfb, 0x49, 0xd5, 0xd0, 0xf7, 0xbd, 0x8c, 0xc0, 0x10, 0xfb, 0xc9, 0xaa, 0xd0, 0xf3,
0xea, 0xbd, 0x8c, 0xc0, 0x10, 0xfb, 0xc9, 0x96, 0xf0, 0x09, 0x28, 0x90, 0xdf, 0x49, 0xad, 0xf0, 0xea, 0xbd, 0x8c, 0xc0, 0x10, 0xfb, 0xc9, 0x96, 0xf0, 0x09, 0x28, 0x90, 0xdf, 0x49, 0xad, 0xf0,
0x25, 0xd0, 0xd9, 0xa0, 0x03, 0x85, 0x40, 0xbd, 0x8c, 0xc0, 0x10, 0xfb, 0x2a, 0x85, 0x3c, 0xbd, 0x25, 0xd0, 0xd9, 0xa0, 0x03, 0x85, 0x40, 0xbd, 0x8c, 0xc0, 0x10, 0xfb, 0x2a, 0x85, 0x3c, 0xbd,
0x8c, 0xc0, 0x10, 0xfb, 0x25, 0x3c, 0x88, 0xd0, 0xec, 0x28, 0xc5, 0x3d, 0xd0, 0xbe, 0xa5, 0x40, 0x8c, 0xc0, 0x10, 0xfb, 0x25, 0x3c, 0x88, 0xd0, 0xec, 0x28, 0xc5, 0x3d, 0xd0, 0xbe, 0xa5, 0x40,
0xc5, 0x41, 0xd0, 0xb8, 0xb0, 0xb7, 0xa0, 0x56, 0x84, 0x3c, 0xbc, 0x8c, 0xc0, 0x10, 0xfb, 0x59, 0xc5, 0x41, 0xd0, 0xb8, 0xb0, 0xb7, 0xa0, 0x56, 0x84, 0x3c, 0xbc, 0x8c, 0xc0, 0x10, 0xfb, 0x59,
0xd6, 0x02, 0xa4, 0x3c, 0x88, 0x99, 0x00, 0x03, 0xd0, 0xee, 0x84, 0x3c, 0xbc, 0x8c, 0xc0, 0x10, 0xd6, 0x02, 0xa4, 0x3c, 0x88, 0x99, 0x00, 0x03, 0xd0, 0xee, 0x84, 0x3c, 0xbc, 0x8c, 0xc0, 0x10,
0xfb, 0x59, 0xd6, 0x02, 0xa4, 0x3c, 0x91, 0x26, 0xc8, 0xd0, 0xef, 0xbc, 0x8c, 0xc0, 0x10, 0xfb, 0xfb, 0x59, 0xd6, 0x02, 0xa4, 0x3c, 0x91, 0x26, 0xc8, 0xd0, 0xef, 0xbc, 0x8c, 0xc0, 0x10, 0xfb,
0x59, 0xd6, 0x02, 0xd0, 0x87, 0xa0, 0x00, 0xa2, 0x56, 0xca, 0x30, 0xfb, 0xb1, 0x26, 0x5e, 0x00, 0x59, 0xd6, 0x02, 0xd0, 0x87, 0xa0, 0x00, 0xa2, 0x56, 0xca, 0x30, 0xfb, 0xb1, 0x26, 0x5e, 0x00,
0x03, 0x2a, 0x5e, 0x00, 0x03, 0x2a, 0x91, 0x26, 0xc8, 0xd0, 0xee, 0xe6, 0x27, 0xe6, 0x3d, 0xa5, 0x03, 0x2a, 0x5e, 0x00, 0x03, 0x2a, 0x91, 0x26, 0xc8, 0xd0, 0xee, 0xe6, 0x27, 0xe6, 0x3d, 0xa5,
0x3d, 0xcd, 0x00, 0x08, 0xa6, 0x2b, 0x90, 0xdb, 0x4c, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3d, 0xcd, 0x00, 0x08, 0xa6, 0x2b, 0x90, 0xdb, 0x4c, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
}; };
// Constants // Constants
private static final int NUM_DRIVES = 2; private static final int NUM_DRIVES = 2;
private static final int DOS_NUM_SECTORS = 16; private static final int DOS_NUM_SECTORS = 16;
private static final int DOS_NUM_TRACKS = 35; private static final int DOS_NUM_TRACKS = 35;
private static final int DOS_TRACK_BYTES = 256 * DOS_NUM_SECTORS; private static final int DOS_TRACK_BYTES = 256 * DOS_NUM_SECTORS;
private static final int RAW_TRACK_BYTES = 6656; // TODO 6250 ??? private static final int RAW_TRACK_BYTES = 6656; // TODO 6250 ???
// Disk II direct access variables
private int drive = 0;
private boolean isMotorOn = false;
private byte[][][] disk = new byte[NUM_DRIVES][DOS_NUM_TRACKS][]; // Disk II direct access variables
private boolean[] isWriteProtected = new boolean[NUM_DRIVES]; private int drive = 0;
private boolean isMotorOn = false;
private int currPhysTrack; private byte[][][] disk = new byte[NUM_DRIVES][DOS_NUM_TRACKS][];
private int currNibble; private boolean[] isWriteProtected = new boolean[NUM_DRIVES];
// Caches private int currPhysTrack;
private int[] driveCurrPhysTrack = new int[NUM_DRIVES]; private int currNibble;
private byte[] realTrack;
/*
* Disk II emulation:
*
* C0xD, C0xE -> Read write protect
* C0xE, C0xC -> Read data from disk
* Write data to disk -> C0xF, C0xC
* Write data to disk -> C0xD, C0xC
*
* We use 'fast mode', i.e. no 65(C)02 clock reference
* We use simplified track handling (only adjacent phases)
*/
// Internal registers // Caches
private int latchAddress; private int[] driveCurrPhysTrack = new int[NUM_DRIVES];
private int latchData; private byte[] realTrack;
private boolean writeMode;
/*
// GCR encoding and decoding tables * Disk II emulation:
private static final int[] gcrEncodingTable = { *
0x96, 0x97, 0x9a, 0x9b, 0x9d, 0x9e, 0x9f, 0xa6, * C0xD, C0xE -> Read write protect
0xa7, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb2, 0xb3, * C0xE, C0xC -> Read data from disk
0xb4, 0xb5, 0xb6, 0xb7, 0xb9, 0xba, 0xbb, 0xbc, * Write data to disk -> C0xF, C0xC
0xbd, 0xbe, 0xbf, 0xcb, 0xcd, 0xce, 0xcf, 0xd3, * Write data to disk -> C0xD, C0xC
0xd6, 0xd7, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, *
0xdf, 0xe5, 0xe6, 0xe7, 0xe9, 0xea, 0xeb, 0xec, * We use 'fast mode', i.e. no 65(C)02 clock reference
0xed, 0xee, 0xef, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, * We use simplified track handling (only adjacent phases)
0xf7, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, */
};
// private int[] gcrDecodingTable = new int[256]; // Internal registers
private int[] gcrSwapBit = {0, 2, 1, 3}; private int latchAddress;
private int[] gcrBuffer = new int[256]; private int latchData;
private int[] gcrBuffer2 = new int[86]; private boolean writeMode;
// Physical sector to DOS 3.3 logical sector table // GCR encoding and decoding tables
private static final int[] gcrLogicalSector = { private static final int[] gcrEncodingTable = {
0x0, 0x7, 0xe, 0x6, 0xd, 0x5, 0xc, 0x4, 0x96, 0x97, 0x9a, 0x9b, 0x9d, 0x9e, 0x9f, 0xa6,
0xb, 0x3, 0xa, 0x2, 0x9, 0x1, 0x8, 0xf 0xa7, 0xab, 0xac, 0xad, 0xae, 0xaf, 0xb2, 0xb3,
}; 0xb4, 0xb5, 0xb6, 0xb7, 0xb9, 0xba, 0xbb, 0xbc,
0xbd, 0xbe, 0xbf, 0xcb, 0xcd, 0xce, 0xcf, 0xd3,
// Temporary variables for conversion 0xd6, 0xd7, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde,
private byte[] gcrNibbles = new byte[RAW_TRACK_BYTES]; 0xdf, 0xe5, 0xe6, 0xe7, 0xe9, 0xea, 0xeb, 0xec,
private int gcrNibblesPos; 0xed, 0xee, 0xef, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6,
0xf7, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
/** };
* Constructor // private int[] gcrDecodingTable = new int[256];
*/ private int[] gcrSwapBit = {0, 2, 1, 3};
public DiskII() { private int[] gcrBuffer = new int[256];
readDisk(null, 0, null, 254, false); private int[] gcrBuffer2 = new int[86];
readDisk(null, 1, null, 254, false);
} // Physical sector to DOS 3.3 logical sector table
private static final int[] gcrLogicalSector = {
0x0, 0x7, 0xe, 0x6, 0xd, 0x5, 0xc, 0x4,
0xb, 0x3, 0xa, 0x2, 0x9, 0x1, 0x8, 0xf
};
// Temporary variables for conversion
private byte[] gcrNibbles = new byte[RAW_TRACK_BYTES];
private int gcrNibblesPos;
/**
* Constructor
*/
public DiskII() {
readDisk(null, 0, null, 254, false);
readDisk(null, 1, null, 254, false);
}
/** /**
* I/O read * I/O read
* *
* @param address Address * @param address Address
*/ */
public int ioRead(int address) { public int ioRead(int address) {
int phase; int phase;
switch (address & 0xf) {
case 0x0:
case 0x2:
case 0x4:
case 0x6:
// Q0, Q1, Q2, Q3 off
break;
case 0x1:
// Q0 on
phase = currPhysTrack & 3;
if (phase == 1) {
if (currPhysTrack > 0) {
currPhysTrack--;
}
} else if (phase == 3) {
if (currPhysTrack < ((2 * DOS_NUM_TRACKS) - 1)) {
currPhysTrack++;
}
}
realTrack = disk[drive][currPhysTrack >> 1];
break;
case 0x3:
// Q1 on
phase = currPhysTrack & 3;
if (phase == 2) {
if (currPhysTrack > 0) {
currPhysTrack--;
}
} else if (phase == 0) {
if (currPhysTrack < ((2 * DOS_NUM_TRACKS) - 1)) {
currPhysTrack++;
}
}
realTrack = disk[drive][currPhysTrack >> 1];
break;
case 0x5:
// Q2 on
phase = currPhysTrack & 3;
if (phase == 3) {
if (currPhysTrack > 0) {
currPhysTrack--;
}
} else if (phase == 1) {
if (currPhysTrack < ((2 * DOS_NUM_TRACKS) - 1)) {
currPhysTrack++;
}
}
realTrack = disk[drive][currPhysTrack >> 1];
break;
case 0x7:
// Q3 on
phase = currPhysTrack & 3;
if (phase == 0) {
if (currPhysTrack > 0) {
currPhysTrack--;
}
} else if (phase == 2) {
if (currPhysTrack < ((2 * DOS_NUM_TRACKS) - 1)) {
currPhysTrack++;
}
}
realTrack = disk[drive][currPhysTrack >> 1];
break;
case 0x8:
// Motor off
isMotorOn = false;
break;
case 0x9:
// Motor on
isMotorOn = true;
break;
case 0xa:
// Drive 1
driveCurrPhysTrack[drive] = currPhysTrack;
drive = 0;
currPhysTrack = driveCurrPhysTrack[drive];
realTrack = disk[drive][currPhysTrack >> 1]; switch (address & 0xf) {
break; case 0x0:
case 0xb: case 0x2:
// Drive 2 case 0x4:
driveCurrPhysTrack[drive] = currPhysTrack; case 0x6:
drive = 1; // Q0, Q1, Q2, Q3 off
currPhysTrack = driveCurrPhysTrack[drive]; break;
case 0x1:
// Q0 on
phase = currPhysTrack & 3;
if (phase == 1) {
if (currPhysTrack > 0) {
currPhysTrack--;
}
} else if (phase == 3) {
if (currPhysTrack < ((2 * DOS_NUM_TRACKS) - 1)) {
currPhysTrack++;
}
}
realTrack = disk[drive][currPhysTrack >> 1];
break;
case 0x3:
// Q1 on
phase = currPhysTrack & 3;
if (phase == 2) {
if (currPhysTrack > 0) {
currPhysTrack--;
}
} else if (phase == 0) {
if (currPhysTrack < ((2 * DOS_NUM_TRACKS) - 1)) {
currPhysTrack++;
}
}
realTrack = disk[drive][currPhysTrack >> 1];
break;
case 0x5:
// Q2 on
phase = currPhysTrack & 3;
if (phase == 3) {
if (currPhysTrack > 0) {
currPhysTrack--;
}
} else if (phase == 1) {
if (currPhysTrack < ((2 * DOS_NUM_TRACKS) - 1)) {
currPhysTrack++;
}
}
realTrack = disk[drive][currPhysTrack >> 1];
break;
case 0x7:
// Q3 on
phase = currPhysTrack & 3;
if (phase == 0) {
if (currPhysTrack > 0) {
currPhysTrack--;
}
} else if (phase == 2) {
if (currPhysTrack < ((2 * DOS_NUM_TRACKS) - 1)) {
currPhysTrack++;
}
}
realTrack = disk[drive][currPhysTrack >> 1];
break;
case 0x8:
// Motor off
isMotorOn = false;
break;
case 0x9:
// Motor on
isMotorOn = true;
break;
case 0xa:
// Drive 1
driveCurrPhysTrack[drive] = currPhysTrack;
drive = 0;
currPhysTrack = driveCurrPhysTrack[drive];
realTrack = disk[drive][currPhysTrack >> 1]; realTrack = disk[drive][currPhysTrack >> 1];
break; break;
case 0xc: case 0xb:
return ioLatchC(); // Drive 2
case 0xd: driveCurrPhysTrack[drive] = currPhysTrack;
ioLatchD(0xff); drive = 1;
break; currPhysTrack = driveCurrPhysTrack[drive];
case 0xe:
return ioLatchE(); realTrack = disk[drive][currPhysTrack >> 1];
case 0xf: break;
ioLatchF(0xff); case 0xc:
break; return ioLatchC();
} case 0xd:
ioLatchD(0xff);
return rand.nextInt(256); break;
case 0xe:
return ioLatchE();
case 0xf:
ioLatchF(0xff);
break;
}
return rand.nextInt(256);
} }
/** /**
* I/O write * I/O write
* *
* @param address Address * @param address Address
*/ */
public void ioWrite(int address, int value) { public void ioWrite(int address, int value) {
switch (address & 0xf) { switch (address & 0xf) {
case 0x0: case 0x0:
case 0x1: case 0x1:
case 0x2: case 0x2:
case 0x3: case 0x3:
case 0x4: case 0x4:
case 0x5: case 0x5:
case 0x6: case 0x6:
case 0x7: case 0x7:
case 0x8: case 0x8:
case 0x9: case 0x9:
case 0xa: case 0xa:
case 0xb: case 0xb:
ioRead(address); ioRead(address);
break; break;
case 0xc: case 0xc:
ioLatchC(); ioLatchC();
break; break;
case 0xd: case 0xd:
ioLatchD(value); ioLatchD(value);
break; break;
case 0xe: case 0xe:
ioLatchE(); ioLatchE();
break; break;
case 0xf: case 0xf:
ioLatchF(value); ioLatchF(value);
break; break;
} }
} }
/** /**
* Memory read * Memory read
* *
* @param address Address * @param address Address
*/ */
public int memoryRead(int address) { public int memoryRead(int address) {
return rom[address & 0xff]; return rom[address & 0xff];
} }
/** /**
* Reset peripheral * Reset peripheral
*/ */
public void reset() { public void reset() {
ioRead(0x8); ioRead(0x8);
} }
/** /**
* Loads a disk * Loads a disk
* *
* @param resource filename * @param resource filename
* @param drive Disk II drive * @param drive Disk II drive
* @throws IllegalStateException * @throws IllegalStateException
*/ */
public void readDisk(AppleIIGo.Dao dao, int drive, String resource, int volume, boolean isWriteProtected) { public void readDisk(AppleIIGo.Dao dao, int drive, String resource, int volume, boolean isWriteProtected) {
byte[] track = new byte[RAW_TRACK_BYTES]; byte[] track = new byte[RAW_TRACK_BYTES];
boolean isNib = false; boolean isNib = false;
if (resource != null) { if (resource != null) {
dao.openInputStream(resource); dao.openInputStream(resource);
if (resource.toLowerCase().endsWith(".nib")) { if (resource.toLowerCase().endsWith(".nib")) {
@ -284,236 +284,236 @@ System.err.println("DRIVE[" + drive + "]: NIB");
System.err.println("DRIVE[" + drive + "]: DSK"); System.err.println("DRIVE[" + drive + "]: DSK");
} }
} }
for (int trackNum = 0; trackNum < DOS_NUM_TRACKS; trackNum++) { for (int trackNum = 0; trackNum < DOS_NUM_TRACKS; trackNum++) {
disk[drive][trackNum] = new byte[RAW_TRACK_BYTES]; disk[drive][trackNum] = new byte[RAW_TRACK_BYTES];
if (resource != null) { if (resource != null) {
if (isNib) { if (isNib) {
dao.read(disk[drive][trackNum], 0, RAW_TRACK_BYTES); dao.read(disk[drive][trackNum], 0, RAW_TRACK_BYTES);
} else { } else {
dao.read(track, 0, DOS_TRACK_BYTES); dao.read(track, 0, DOS_TRACK_BYTES);
trackToNibbles(track, disk[drive][trackNum], volume, trackNum); trackToNibbles(track, disk[drive][trackNum], volume, trackNum);
} }
} }
} }
if (resource != null) { if (resource != null) {
dao.closeInputStream(); dao.closeInputStream();
} }
this.realTrack = disk[drive][currPhysTrack >> 1]; this.realTrack = disk[drive][currPhysTrack >> 1];
this.isWriteProtected[drive] = isWriteProtected; this.isWriteProtected[drive] = isWriteProtected;
} }
/** /**
* Writes a disk * Writes a disk
* *
* @param resource filename * @param resource filename
* @param drive Disk II drive * @param drive Disk II drive
*/ */
public void writeDisk(int drive, String resource) { public void writeDisk(int drive, String resource) {
} }
/** /**
* Motor on indicator * Motor on indicator
*/ */
public boolean isMotorOn() { public boolean isMotorOn() {
return isMotorOn; return isMotorOn;
} }
/** /**
* I/O read Latch C * I/O read Latch C
* *
* @param address Address * @param address Address
*/ */
private int ioLatchC() { private int ioLatchC() {
if (writeMode) { if (writeMode) {
// Write data: C0xD, C0xC // Write data: C0xD, C0xC
realTrack[currNibble] = (byte) latchData; realTrack[currNibble] = (byte) latchData;
} else { } else {
// Read data: C0xE, C0xC // Read data: C0xE, C0xC
latchData = (realTrack[currNibble] & 0xff); latchData = (realTrack[currNibble] & 0xff);
} }
currNibble++; currNibble++;
if (currNibble >= RAW_TRACK_BYTES) { if (currNibble >= RAW_TRACK_BYTES) {
currNibble = 0; currNibble = 0;
} }
latchAddress = 0xc; latchAddress = 0xc;
return latchData; return latchData;
} }
/** /**
* I/O write Latch D * I/O write Latch D
* *
* @param address Address * @param address Address
*/ */
private void ioLatchD(int value) { private void ioLatchD(int value) {
// Prepare write // Prepare write
writeMode = true; writeMode = true;
latchData = value; latchData = value;
latchAddress = 0xd; latchAddress = 0xd;
} }
/** /**
* I/O read Latch E * I/O read Latch E
* *
* @param address Address * @param address Address
*/ */
private int ioLatchE() { private int ioLatchE() {
// Read write-protect: C0xD, C0xE // Read write-protect: C0xD, C0xE
if (latchAddress == 0xd) { if (latchAddress == 0xd) {
latchAddress = 0xe; latchAddress = 0xe;
return isWriteProtected[drive] ? 0x80 : 0x00; return isWriteProtected[drive] ? 0x80 : 0x00;
} }
writeMode = false; writeMode = false;
latchAddress = 0xe; latchAddress = 0xe;
return 0x3c; return 0x3c;
} }
/** /**
* I/O write Latch F * I/O write Latch F
* *
* @param address Address * @param address Address
*/ */
private void ioLatchF(int value) { private void ioLatchF(int value) {
// Prepare write // Prepare write
writeMode = true; writeMode = true;
latchData = value; latchData = value;
latchAddress = 0xf; latchAddress = 0xf;
} }
/* /*
* TRACK CONVERSION ROUTINES * TRACK CONVERSION ROUTINES
*/ */
/** /**
* Writes a nibble * Writes a nibble
* *
* @param value Value * @param value Value
*/ */
private final void gcrWriteNibble(int value) { private final void gcrWriteNibble(int value) {
gcrNibbles[gcrNibblesPos] = (byte) value; gcrNibbles[gcrNibblesPos] = (byte) value;
gcrNibblesPos++; gcrNibblesPos++;
} }
/** /**
* Writes sync bits * Writes sync bits
* *
* @param length Number of bits * @param length Number of bits
*/ */
private final void writeSync(int length) { private final void writeSync(int length) {
while(length > 0) { while(length > 0) {
length--; length--;
gcrWriteNibble(0xff); gcrWriteNibble(0xff);
} }
} }
/** /**
* Write an FM encoded value, used in writing address fields * Write an FM encoded value, used in writing address fields
* *
* @param value Value * @param value Value
*/ */
private final void encode44(int value) { private final void encode44(int value) {
gcrWriteNibble((value >> 1) | 0xaa); gcrWriteNibble((value >> 1) | 0xaa);
gcrWriteNibble(value | 0xaa); gcrWriteNibble(value | 0xaa);
} }
/** /**
* Encode in 6:2 * Encode in 6:2
* *
* @param track Sectorized track data * @param track Sectorized track data
* @param offset Offset in this data * @param offset Offset in this data
*/ */
private void encode62(byte[] track, int offset) { private void encode62(byte[] track, int offset) {
// 86 * 3 = 258, so the first two byte are encoded twice // 86 * 3 = 258, so the first two byte are encoded twice
gcrBuffer2[0] = gcrSwapBit[track[offset + 1] & 0x03]; gcrBuffer2[0] = gcrSwapBit[track[offset + 1] & 0x03];
gcrBuffer2[1] = gcrSwapBit[track[offset] & 0x03]; gcrBuffer2[1] = gcrSwapBit[track[offset] & 0x03];
// Save higher 6 bits in gcrBuffer and lower 2 bits in gcrBuffer2 // Save higher 6 bits in gcrBuffer and lower 2 bits in gcrBuffer2
for(int i = 255, j = 2; i >= 0; i--, j = j == 85 ? 0: j + 1) { for(int i = 255, j = 2; i >= 0; i--, j = j == 85 ? 0: j + 1) {
gcrBuffer2[j] = ((gcrBuffer2[j] << 2) | gcrSwapBit[track[offset + i] & 0x03]); gcrBuffer2[j] = ((gcrBuffer2[j] << 2) | gcrSwapBit[track[offset + i] & 0x03]);
gcrBuffer[i] = (track[offset + i] & 0xff) >> 2; gcrBuffer[i] = (track[offset + i] & 0xff) >> 2;
} }
// Clear off higher 2 bits of GCR_buffer2 set in the last call // Clear off higher 2 bits of GCR_buffer2 set in the last call
for(int i = 0; i < 86; i++) { for(int i = 0; i < 86; i++) {
gcrBuffer2[i] &= 0x3f; gcrBuffer2[i] &= 0x3f;
} }
} }
/** /**
* Write address field * Write address field
* *
* @param track Sectorized track data * @param track Sectorized track data
* @param offset Offset in this data * @param offset Offset in this data
*/ */
private final void writeAddressField(int volumeNum, int trackNum, int sectorNum) { private final void writeAddressField(int volumeNum, int trackNum, int sectorNum) {
// Write address mark // Write address mark
gcrWriteNibble(0xd5); gcrWriteNibble(0xd5);
gcrWriteNibble(0xaa); gcrWriteNibble(0xaa);
gcrWriteNibble(0x96); gcrWriteNibble(0x96);
// Write volume, trackNum, sector & checksum
encode44(volumeNum);
encode44(trackNum);
encode44(sectorNum);
encode44(volumeNum ^ trackNum ^ sectorNum);
// Write epilogue
gcrWriteNibble(0xde);
gcrWriteNibble(0xaa);
gcrWriteNibble(0xeb);
}
/**
* Write data field
*/
private void writeDataField() {
int last = 0;
int checksum;
// Write prologue // Write volume, trackNum, sector & checksum
gcrWriteNibble(0xd5); encode44(volumeNum);
gcrWriteNibble(0xaa); encode44(trackNum);
gcrWriteNibble(0xad); encode44(sectorNum);
encode44(volumeNum ^ trackNum ^ sectorNum);
// Write GCR encoded data // Write epilogue
for (int i = 0x55; i >= 0; i--) { gcrWriteNibble(0xde);
checksum = last ^ gcrBuffer2[i]; gcrWriteNibble(0xaa);
gcrWriteNibble(gcrEncodingTable[checksum]); gcrWriteNibble(0xeb);
last = gcrBuffer2[i]; }
}
for (int i = 0; i < 256; i++) {
checksum = last ^ gcrBuffer[i];
gcrWriteNibble(gcrEncodingTable[checksum]);
last = gcrBuffer[i];
}
// Write checksum /**
gcrWriteNibble(gcrEncodingTable[last]); * Write data field
*/
private void writeDataField() {
int last = 0;
int checksum;
// Write epilogue // Write prologue
gcrWriteNibble(0xde); gcrWriteNibble(0xd5);
gcrWriteNibble(0xaa); gcrWriteNibble(0xaa);
gcrWriteNibble(0xeb); gcrWriteNibble(0xad);
}
/** // Write GCR encoded data
* Converts a track to nibbles for (int i = 0x55; i >= 0; i--) {
*/ checksum = last ^ gcrBuffer2[i];
private void trackToNibbles(byte[] track, byte[] nibbles, int volumeNum, int trackNum) { gcrWriteNibble(gcrEncodingTable[checksum]);
this.gcrNibbles = nibbles; last = gcrBuffer2[i];
gcrNibblesPos = 0; }
for (int i = 0; i < 256; i++) {
checksum = last ^ gcrBuffer[i];
gcrWriteNibble(gcrEncodingTable[checksum]);
last = gcrBuffer[i];
}
for (int sectorNum = 0; sectorNum < DOS_NUM_SECTORS; sectorNum++) { // Write checksum
encode62(track, gcrLogicalSector[sectorNum] << 8); gcrWriteNibble(gcrEncodingTable[last]);
writeSync(12);
writeAddressField(volumeNum, trackNum, sectorNum); // Write epilogue
writeSync(8); gcrWriteNibble(0xde);
writeDataField(); gcrWriteNibble(0xaa);
} gcrWriteNibble(0xeb);
writeSync(RAW_TRACK_BYTES - gcrNibblesPos); }
}
/**
* Converts a track to nibbles
*/
private void trackToNibbles(byte[] track, byte[] nibbles, int volumeNum, int trackNum) {
this.gcrNibbles = nibbles;
gcrNibblesPos = 0;
for (int sectorNum = 0; sectorNum < DOS_NUM_SECTORS; sectorNum++) {
encode62(track, gcrLogicalSector[sectorNum] << 8);
writeSync(12);
writeAddressField(volumeNum, trackNum, sectorNum);
writeSync(8);
writeDataField();
}
writeSync(RAW_TRACK_BYTES - gcrNibblesPos);
}
} }

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -9,94 +9,94 @@ package vavi.apps.appleii;
public class Paddle { public class Paddle {
// Public variables // Public variables
public static final int PADDLE_LOW = 0; public static final int PADDLE_LOW = 0;
public static final int PADDLE_CENTER = 127; public static final int PADDLE_CENTER = 127;
public static final int PADDLE_HIGH = 255; public static final int PADDLE_HIGH = 255;
public static final int PADDLEMODE_DIRECT = 0; public static final int PADDLEMODE_DIRECT = 0;
public static final int PADDLEMODE_FILTERED = 1; public static final int PADDLEMODE_FILTERED = 1;
// Instances of other classes
private EmAppleII apple;
// Button variables // Instances of other classes
private int[] buttonRegister = new int[4]; private EmAppleII apple;
// Paddle variables // Button variables
// private int paddleMode; private int[] buttonRegister = new int[4];
private int[] paddleClockEvent = new int[4]; // Paddle variables
private int[] paddleClockInc = new int[4]; // private int paddleMode;
/** private int[] paddleClockEvent = new int[4];
* Paddle class constructor private int[] paddleClockInc = new int[4];
*
* @param apple The EmAppleII instance
*/
public Paddle(EmAppleII apple) {
this.apple = apple;
setPaddlePos(0, PADDLE_CENTER); /**
setPaddlePos(1, PADDLE_CENTER); * Paddle class constructor
setPaddlePos(2, PADDLE_CENTER); *
setPaddlePos(3, PADDLE_CENTER); * @param apple The EmAppleII instance
} */
public Paddle(EmAppleII apple) {
/** this.apple = apple;
* Set button state
*
* @param button Paddle button
* @param state State
*/
public void setButton(int button, boolean pressed) {
buttonRegister[button] = (pressed ? 0x80 : 0x00);
}
/**
* Button register
*
* @param button Paddle button
*/
public int getButtonRegister(int button) {
return buttonRegister[button];
}
/** setPaddlePos(0, PADDLE_CENTER);
* Set paddle position setPaddlePos(1, PADDLE_CENTER);
* setPaddlePos(2, PADDLE_CENTER);
* @param address Address setPaddlePos(3, PADDLE_CENTER);
* @param value Value }
*/
public void setPaddlePos(int paddle, int value) { /**
/* * Set button state
* Magic formula, see ROM $FB1E-$FB2E, *
* We calculate the numbers of cycles after which * @param button Paddle button
* the RC circuit of a triggered paddle will discharge. * @param state State
*/ */
paddleClockInc[paddle] = value * 11 + 8; public void setButton(int button, boolean pressed) {
} buttonRegister[button] = (pressed ? 0x80 : 0x00);
}
/**
* Trigger paddle register /**
* * Button register
* @param address Address *
* @param value Value * @param button Paddle button
*/ */
public void triggerRegister() { public int getButtonRegister(int button) {
paddleClockEvent[0] = apple.clock + paddleClockInc[0]; return buttonRegister[button];
paddleClockEvent[1] = apple.clock + paddleClockInc[1]; }
paddleClockEvent[2] = apple.clock + paddleClockInc[2];
paddleClockEvent[3] = apple.clock + paddleClockInc[3]; /**
} * Set paddle position
*
/** * @param address Address
* Get paddle register * @param value Value
* */
* @param address Address public void setPaddlePos(int paddle, int value) {
* @param value Value /*
*/ * Magic formula, see ROM $FB1E-$FB2E,
public int getPaddleRegister(int paddle) { * We calculate the numbers of cycles after which
return ((((paddleClockEvent[paddle] - apple.clock) & 0x7fffffff) < 0x40000000) ? 0x80 : 0x00); * the RC circuit of a triggered paddle will discharge.
} */
paddleClockInc[paddle] = value * 11 + 8;
}
/**
* Trigger paddle register
*
* @param address Address
* @param value Value
*/
public void triggerRegister() {
paddleClockEvent[0] = apple.clock + paddleClockInc[0];
paddleClockEvent[1] = apple.clock + paddleClockInc[1];
paddleClockEvent[2] = apple.clock + paddleClockInc[2];
paddleClockEvent[3] = apple.clock + paddleClockInc[3];
}
/**
* Get paddle register
*
* @param address Address
* @param value Value
*/
public int getPaddleRegister(int paddle) {
return ((((paddleClockEvent[paddle] - apple.clock) & 0x7fffffff) < 0x40000000) ? 0x80 : 0x00);
}
} }

View File

@ -12,25 +12,25 @@ import java.util.Random;
public class Peripheral { public class Peripheral {
protected Random rand = new Random(); protected Random rand = new Random();
public Peripheral() { public Peripheral() {
}
public int ioRead(int address) {
return rand.nextInt(256);
} }
public int ioRead(int address) {
return rand.nextInt(256);
}
public void ioWrite(int address, int value) { public void ioWrite(int address, int value) {
} }
public int memoryRead(int address) { public int memoryRead(int address) {
return 0; return 0;
} }
public void memoryWrite(int address, int value) { public void memoryWrite(int address, int value) {
} }
public void reset() { public void reset() {
} }
} }

View File

@ -1,5 +1,5 @@
/* /*
* $LastChangedDate: 2005-11-21 02:11:20 +0900 (ě? 21 11 2005) $ * $LastChangedDate: 2005-11-21 02:11:20 +0900 (ě? 21 11 2005) $
* *
* Copyright 1990-2006 Sun Microsystems, Inc. All rights reserved. * Copyright 1990-2006 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
@ -17,7 +17,7 @@ import java.awt.event.KeyEvent;
/** /**
* This is a popup layer that handles a sub-popup within the text tfContext * This is a popup layer that handles a sub-popup within the text tfContext
* *
* @author Amir Uval * @author Amir Uval
*/ */
@ -72,7 +72,7 @@ class VirtualKeyboard {
/** /**
* Virtual Keyboard constructor. * Virtual Keyboard constructor.
* *
* @param keys array of available keys for the keyboard * @param keys array of available keys for the keyboard
* @param vkl the virtual keyboard listener * @param vkl the virtual keyboard listener
* @param displayTextArea flag to indicate whether to display the text area * @param displayTextArea flag to indicate whether to display the text area
@ -192,7 +192,7 @@ System.err.println("Please split your keyboard array to multiple arrays.");
/** /**
* Checks if the virtual keyboard is enabled. * Checks if the virtual keyboard is enabled.
* *
* @return <code>true</code> if the virtual keyboard is enabled, * @return <code>true</code> if the virtual keyboard is enabled,
* <code>false</code> otherwise. * <code>false</code> otherwise.
*/ */
@ -202,7 +202,7 @@ System.err.println("Please split your keyboard array to multiple arrays.");
/** /**
* Checks if the virtual keyboard is enabled. * Checks if the virtual keyboard is enabled.
* *
* @return <code>true</code> if the virtual keyboard is enabled, * @return <code>true</code> if the virtual keyboard is enabled,
* <code>false</code> otherwise. * <code>false</code> otherwise.
*/ */
@ -212,7 +212,7 @@ System.err.println("Please split your keyboard array to multiple arrays.");
/** /**
* Checks if the virtual keyboard is opened automatically. * Checks if the virtual keyboard is opened automatically.
* *
* @return <code>true</code> if the virtual keyboard is opened * @return <code>true</code> if the virtual keyboard is opened
* automatically, <code>false</code> otherwise. * automatically, <code>false</code> otherwise.
*/ */
@ -222,7 +222,7 @@ System.err.println("Please split your keyboard array to multiple arrays.");
/** /**
* traverse the virtual keyboard according to key pressed. * traverse the virtual keyboard according to key pressed.
* *
* @param type type of keypress * @param type type of keypress
* @param keyCode key code of key pressed * @param keyCode key code of key pressed
*/ */
@ -394,7 +394,7 @@ System.err.println("VirtualK: keyCode=" + keyCode);
/** /**
* paint the virtual keyboard on the screen * paint the virtual keyboard on the screen
* *
* @param g The graphics context to paint to * @param g The graphics context to paint to
*/ */
protected void paint(Graphics g) { protected void paint(Graphics g) {
@ -426,7 +426,7 @@ System.err.println("VirtualK: keyCode=" + keyCode);
/** /**
* Draw the text field of the virtual keyboard. * Draw the text field of the virtual keyboard.
* *
* @param g The graphics context to paint to * @param g The graphics context to paint to
*/ */
void drawTextField(Graphics g) { void drawTextField(Graphics g) {
@ -456,7 +456,7 @@ System.err.println("VirtualK: keyCode=" + keyCode);
/** /**
* draw keyboard keys * draw keyboard keys
* *
* @param g The graphics context to paint to * @param g The graphics context to paint to
*/ */
void drawKeys(Graphics g) { void drawKeys(Graphics g) {
@ -491,7 +491,7 @@ System.err.println("VirtualK: keyCode=" + keyCode);
/** /**
* draw keyboard meta keys * draw keyboard meta keys
* *
* @param g The graphics context to paint to * @param g The graphics context to paint to
*/ */
void drawMetaKeys(Graphics g) { void drawMetaKeys(Graphics g) {
@ -529,7 +529,7 @@ System.err.println("VirtualK: keyCode=" + keyCode);
/** /**
* draw a border * draw a border
* *
* @param g The graphics context to paint to * @param g The graphics context to paint to
* @param x1 x-coordinate of the button's location * @param x1 x-coordinate of the button's location
* @param y1 y-coordinate of the button's location * @param y1 y-coordinate of the button's location
@ -549,7 +549,7 @@ System.err.println("VirtualK: keyCode=" + keyCode);
/** /**
* draw a sunken border * draw a sunken border
* *
* @param g The graphics context to paint to * @param g The graphics context to paint to
* @param x1 x-coordinate of the button's location * @param x1 x-coordinate of the button's location
* @param y1 y-coordinate of the button's location * @param y1 y-coordinate of the button's location
@ -575,7 +575,7 @@ System.err.println("VirtualK: keyCode=" + keyCode);
/** /**
* draw a button * draw a button
* *
* @param g The graphics context to paint to * @param g The graphics context to paint to
* @param x x-coordinate of the button's location * @param x x-coordinate of the button's location
* @param y y-coordinate of the button's location * @param y y-coordinate of the button's location
@ -599,7 +599,7 @@ System.err.println("VirtualK: keyCode=" + keyCode);
/** /**
* draw a beveled button * draw a beveled button
* *
* @param g The graphics context to paint to * @param g The graphics context to paint to
* @param x x-coordinate of the button's location * @param x x-coordinate of the button's location
* @param y y-coordinate of the button's location * @param y y-coordinate of the button's location
@ -627,12 +627,12 @@ System.err.println("VirtualK: keyCode=" + keyCode);
/** /**
* Helper function to determine the itemIndex at the x,y position * Helper function to determine the itemIndex at the x,y position
* *
* @param x,y pointer coordinates in menuLayer's space (0,0 means left-top * @param x,y pointer coordinates in menuLayer's space (0,0 means left-top
* corner) both value can be negative as menuLayer handles the * corner) both value can be negative as menuLayer handles the
* pointer event outside its bounds * pointer event outside its bounds
* @return menuItem's index since 0, or PRESS_OUT_OF_BOUNDS, PRESS_ON_TITLE * @return menuItem's index since 0, or PRESS_OUT_OF_BOUNDS, PRESS_ON_TITLE
* *
*/ */
private boolean isKeyAtPointerPosition(int x, int y) { private boolean isKeyAtPointerPosition(int x, int y) {
int tmpX, tmpY, tmp; int tmpX, tmpY, tmp;
@ -696,7 +696,7 @@ System.err.println("VirtualK: keyCode=" + keyCode);
* and the x,y location in the layer at which the event occurred. Important * and the x,y location in the layer at which the event occurred. Important
* : the x,y location of the pen tap will already be translated into the * : the x,y location of the pen tap will already be translated into the
* coordinate space of the layer. * coordinate space of the layer.
* *
* @param type the type of pen event * @param type the type of pen event
* @param x the x coordinate of the event * @param x the x coordinate of the event
* @param y the y coordinate of the event * @param y the y coordinate of the event
@ -774,7 +774,7 @@ class VirtualKeyboardException extends Exception {
* The error message string <code>s</code> can later be retrieved by the * The error message string <code>s</code> can later be retrieved by the
* <code>{@link java.lang.Throwable#getMessage}</code> method of class * <code>{@link java.lang.Throwable#getMessage}</code> method of class
* <code>java.lang.Throwable</code>. * <code>java.lang.Throwable</code>.
* *
* @param s the detail message. * @param s the detail message.
*/ */
public VirtualKeyboardException(String s) { public VirtualKeyboardException(String s) {

View File

@ -1,5 +1,5 @@
/* /*
* $LastChangedDate: 2005-09-18 20:31:12 +0900 (, 18 9 2005) $ * $LastChangedDate: 2005-09-18 20:31:12 +0900 (, 18 9 2005) $
* *
* Copyright 1990-2006 Sun Microsystems, Inc. All rights reserved. * Copyright 1990-2006 Sun Microsystems, Inc. All rights reserved.
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
@ -15,39 +15,39 @@ import java.awt.Graphics;
* @author Amir Uval * @author Amir Uval
*/ */
interface VirtualKeyboardListener { interface VirtualKeyboardListener {
/** /**
* key input callback * key input callback
*/ */
public void virtualKeyEntered(int type, char c); public void virtualKeyEntered(int type, char c);
/** /**
* meta key event callback * meta key event callback
*/ */
public void virtualMetaKeyEntered(int metaKey); public void virtualMetaKeyEntered(int metaKey);
/** /**
* a callback used to draw the text entered by the virtual keyboard - on the * a callback used to draw the text entered by the virtual keyboard - on the
* keyboard text area. * keyboard text area.
* In KeyboardLayer, it is implemented by passing the call to * In KeyboardLayer, it is implemented by passing the call to
* TextField's paint(..) * TextField's paint(..)
*/ */
public void paintTextOnly(Graphics g, int width, int height); public void paintTextOnly(Graphics g, int width, int height);
public void paintCandidateBar(Graphics g, int width, int height); public void paintCandidateBar(Graphics g, int width, int height);
/** /**
* should return the width of the owner Displayable * should return the width of the owner Displayable
*/ */
public int getAvailableWidth(); public int getAvailableWidth();
/** /**
* should return the height of the owner Displayable * should return the height of the owner Displayable
*/ */
public int getAvailableHeight(); public int getAvailableHeight();
/** /**
* should trigger a requestRepaint() call to schedule a * should trigger a requestRepaint() call to schedule a
* paint() of the VirtualKeyboard * paint() of the VirtualKeyboard
*/ */
public void repaintVK(); public void repaintVK();

View File

@ -18,7 +18,7 @@ import junit.framework.TestCase;
/** /**
* VirtualKeyboardTest. * VirtualKeyboardTest.
* *
* @author <a href="mailto:vavivavi@yahoo.co.jp">Naohide Sano</a> (nsano) * @author <a href="mailto:vavivavi@yahoo.co.jp">Naohide Sano</a> (nsano)
* @version 0.00 080924 nsano initial version <br> * @version 0.00 080924 nsano initial version <br>
@ -104,7 +104,7 @@ public class VirtualKeyboardTest extends TestCase {
keys[1][48] = '&'; keys[1][48] = '&';
keys[1][49] = '*'; keys[1][49] = '*';
keys[1][50] = '/'; keys[1][50] = '/';
// Roman, upper case // Roman, upper case
keys[2] = new char[51]; // numerals keys[2] = new char[51]; // numerals
keys[2][0] = 'Q'; keys[2][0] = 'Q';