mirror of
https://github.com/sicklittlemonkey/AppleIIGo.git
synced 2024-09-27 08:54:51 +00:00
Version 1.0.7 - changes by Nick
- fixed disk emulation bug (sense write protect entered write mode) - now honour diskWritable parameter (but writing is not implemented) - support meta tag for volume number in disk filename eg: Vol2_Meta_DV2.dsk - added isPaddleEnabled parameter - exposed setPaddleEnabled(boolean value), setPaddleInverted(boolean value) - paddle values are now 255 at startup (ie. correct if disabled/not present) - minor AppleSpeaker fix (SourceDataLine.class) thanks to William Halliburton
This commit is contained in:
parent
912d6c3dbc
commit
af1cec23d3
@ -459,8 +459,8 @@ public class AppleDisplay implements Runnable {
|
|||||||
boolean isDoubleTextMode = ((graphicsMode & EmAppleII.GR_80CHAR) == EmAppleII.GR_80CHAR);
|
boolean isDoubleTextMode = ((graphicsMode & EmAppleII.GR_80CHAR) == EmAppleII.GR_80CHAR);
|
||||||
boolean isDoubleGraphicsMode = ((graphicsMode & (EmAppleII.GR_80CHAR | EmAppleII.GR_DHIRES)) == (EmAppleII.GR_80CHAR | EmAppleII.GR_DHIRES));
|
boolean isDoubleGraphicsMode = ((graphicsMode & (EmAppleII.GR_80CHAR | EmAppleII.GR_DHIRES)) == (EmAppleII.GR_80CHAR | EmAppleII.GR_DHIRES));
|
||||||
|
|
||||||
int baseAddressText = isPage2 ? apple.MEM_MAIN_RAM2 : apple.MEM_MAIN_TEXT;
|
int baseAddressText = isPage2 ? EmAppleII.MEM_MAIN_RAM2 : EmAppleII.MEM_MAIN_TEXT;
|
||||||
int baseAddressHires = isPage2 ? apple.MEM_MAIN_RAM3 : apple.MEM_MAIN_HIRES;
|
int baseAddressHires = isPage2 ? EmAppleII.MEM_MAIN_RAM3 : EmAppleII.MEM_MAIN_HIRES;
|
||||||
|
|
||||||
// Set char map
|
// Set char map
|
||||||
if (isCharsetUpdateRequested) {
|
if (isCharsetUpdateRequested) {
|
||||||
@ -769,7 +769,7 @@ public class AppleDisplay implements Runnable {
|
|||||||
}
|
}
|
||||||
private void renderText(int baseAddress, boolean isMixedMode) {
|
private void renderText(int baseAddress, boolean isMixedMode) {
|
||||||
int screenCharY, screenCharYStart = isMixedMode ? 20 : 0;
|
int screenCharY, screenCharYStart = isMixedMode ? 20 : 0;
|
||||||
int displayOffset, sourceOffset;
|
int displayOffset;
|
||||||
int address, addressEnd, addressStart;
|
int address, addressEnd, addressStart;
|
||||||
|
|
||||||
displayOffset = screenCharYStart * DISPLAY_CHAR_SIZE_Y * DISPLAY_SIZE_X;
|
displayOffset = screenCharYStart * DISPLAY_CHAR_SIZE_Y * DISPLAY_SIZE_X;
|
||||||
@ -820,7 +820,7 @@ public class AppleDisplay implements Runnable {
|
|||||||
}
|
}
|
||||||
private void renderDoubleText(int baseAddress, boolean isMixedMode) {
|
private void renderDoubleText(int baseAddress, boolean isMixedMode) {
|
||||||
int screenCharY, screenCharYStart = isMixedMode ? 20 : 0;
|
int screenCharY, screenCharYStart = isMixedMode ? 20 : 0;
|
||||||
int displayOffset, sourceOffset;
|
int displayOffset;
|
||||||
int address, addressEnd, addressStart;
|
int address, addressEnd, addressStart;
|
||||||
|
|
||||||
displayOffset = screenCharYStart * DISPLAY_CHAR_SIZE_Y * DISPLAY_SIZE_X;
|
displayOffset = screenCharYStart * DISPLAY_CHAR_SIZE_Y * DISPLAY_SIZE_X;
|
||||||
@ -873,7 +873,7 @@ public class AppleDisplay implements Runnable {
|
|||||||
}
|
}
|
||||||
private void renderLores(int baseAddress, boolean isMixedMode) {
|
private void renderLores(int baseAddress, boolean isMixedMode) {
|
||||||
int screenCharY, screenCharYEnd = isMixedMode ? 20 : 24;
|
int screenCharY, screenCharYEnd = isMixedMode ? 20 : 24;
|
||||||
int displayOffset, sourceOffset;
|
int displayOffset;
|
||||||
int address, addressEnd, addressStart;
|
int address, addressEnd, addressStart;
|
||||||
|
|
||||||
displayOffset = 0;
|
displayOffset = 0;
|
||||||
@ -904,7 +904,7 @@ public class AppleDisplay implements Runnable {
|
|||||||
*/
|
*/
|
||||||
private void renderDoubleLores(int baseAddress, boolean isMixedMode) {
|
private void renderDoubleLores(int baseAddress, boolean isMixedMode) {
|
||||||
int screenCharY, screenCharYEnd = isMixedMode ? 20 : 24;
|
int screenCharY, screenCharYEnd = isMixedMode ? 20 : 24;
|
||||||
int displayOffset, sourceOffset;
|
int displayOffset;
|
||||||
int address, addressEnd, addressStart;
|
int address, addressEnd, addressStart;
|
||||||
|
|
||||||
displayOffset = 0;
|
displayOffset = 0;
|
||||||
@ -998,7 +998,7 @@ public class AppleDisplay implements Runnable {
|
|||||||
}
|
}
|
||||||
private void renderHires(int baseAddress, boolean isMixedMode) {
|
private void renderHires(int baseAddress, boolean isMixedMode) {
|
||||||
int screenCharY, screenCharYEnd = isMixedMode ? 20 : 24;
|
int screenCharY, screenCharYEnd = isMixedMode ? 20 : 24;
|
||||||
int displayOffset, sourceOffset;
|
int displayOffset;
|
||||||
int address, addressEnd, addressStart;
|
int address, addressEnd, addressStart;
|
||||||
|
|
||||||
displayOffset = 0;
|
displayOffset = 0;
|
||||||
@ -1089,7 +1089,7 @@ public class AppleDisplay implements Runnable {
|
|||||||
}
|
}
|
||||||
private void renderDoubleHires(int baseAddress, boolean isMixedMode) {
|
private void renderDoubleHires(int baseAddress, boolean isMixedMode) {
|
||||||
int screenCharY, screenCharYEnd = isMixedMode ? 20 : 24;
|
int screenCharY, screenCharYEnd = isMixedMode ? 20 : 24;
|
||||||
int displayOffset, sourceOffset;
|
int displayOffset;
|
||||||
int address, addressEnd, addressStart;
|
int address, addressEnd, addressStart;
|
||||||
|
|
||||||
displayOffset = 0;
|
displayOffset = 0;
|
||||||
|
@ -2,25 +2,32 @@
|
|||||||
/**
|
/**
|
||||||
* AppleIIGo
|
* AppleIIGo
|
||||||
* The Java Apple II Emulator
|
* The Java Apple II Emulator
|
||||||
* (C) 2006 by Marc S. Ressl (ressl@lonetree.com)
|
* Copyright 2009 by Nick Westgate (Nick.Westgate@gmail.com)
|
||||||
* (C) 2009 by Nick Westgate (Nick.Westgate@gmail.com)
|
* Copyright 2006 by Marc S. Ressl (ressl@lonetree.com)
|
||||||
* Released under the GPL
|
* Released under the GNU General Public License version 2
|
||||||
|
* See http://www.gnu.org/licenses/
|
||||||
*
|
*
|
||||||
* Change list:
|
* Change list:
|
||||||
*
|
*
|
||||||
* Version 1.0.6 - changes by Nick:
|
* Version 1.0.7 - changes by Nick:
|
||||||
|
* - fixed disk emulation bug (sense write protect entered write mode)
|
||||||
|
* - now honour diskWritable parameter (but writing is not implemented)
|
||||||
|
* - support meta tag for volume number in disk filename eg: Vol2_Meta_DV2.dsk
|
||||||
|
* - added isPaddleEnabled parameter
|
||||||
|
* - exposed setPaddleEnabled(boolean value), setPaddleInverted(boolean value)
|
||||||
|
* - paddle values are now 255 at startup (ie. correct if disabled/not present)
|
||||||
|
* - minor AppleSpeaker fix (SourceDataLine.class) thanks to William Halliburton
|
||||||
*
|
*
|
||||||
|
* Version 1.0.6 - changes by Nick:
|
||||||
* - exposed F3/F4 disk swapping method: cycleDisk(int driveNumber)
|
* - exposed F3/F4 disk swapping method: cycleDisk(int driveNumber)
|
||||||
* - exposed reset() method
|
* - exposed reset() method
|
||||||
* - exposed setSpeed(int value) method
|
* - exposed setSpeed(int value) method
|
||||||
*
|
*
|
||||||
* Version 1.0.5 - changes by Nick:
|
* Version 1.0.5 - changes by Nick:
|
||||||
*
|
|
||||||
* - added support for .NIB (nibble) disk images (also inside ZIP archives)
|
* - added support for .NIB (nibble) disk images (also inside ZIP archives)
|
||||||
* - added disk speedup hacks for DOS (expect ~2x faster reads)
|
* - added disk speedup hacks for DOS (expect ~2x faster reads)
|
||||||
*
|
*
|
||||||
* Version 1.0.4 - changes by Nick:
|
* Version 1.0.4 - changes by Nick:
|
||||||
*
|
|
||||||
* - added support for .PO (ProDOS order) disk images (also inside ZIP archives)
|
* - added support for .PO (ProDOS order) disk images (also inside ZIP archives)
|
||||||
* - added Command key for Closed-Apple on Mac OS X
|
* - added Command key for Closed-Apple on Mac OS X
|
||||||
* - added Home and End keys for Open-Apple and Closed-Apple on full keyboards
|
* - added Home and End keys for Open-Apple and Closed-Apple on full keyboards
|
||||||
@ -66,8 +73,11 @@ import java.util.zip.ZipInputStream;
|
|||||||
public class AppleIIGo extends Applet implements KeyListener, ComponentListener,
|
public class AppleIIGo extends Applet implements KeyListener, ComponentListener,
|
||||||
MouseListener, MouseMotionListener {
|
MouseListener, MouseMotionListener {
|
||||||
|
|
||||||
final String version = "1.0.6";
|
private static final long serialVersionUID = -3302282815441501352L;
|
||||||
|
|
||||||
|
final String version = "1.0.7";
|
||||||
final String versionString = "AppleIIGo Version " + version;
|
final String versionString = "AppleIIGo Version " + version;
|
||||||
|
final String metaStart = "_meta_";
|
||||||
|
|
||||||
// Class instances
|
// Class instances
|
||||||
private EmAppleII apple;
|
private EmAppleII apple;
|
||||||
@ -82,6 +92,7 @@ public class AppleIIGo extends Applet implements KeyListener, ComponentListener,
|
|||||||
private boolean keyboardUppercaseOnly;
|
private boolean keyboardUppercaseOnly;
|
||||||
|
|
||||||
// Paddle variables
|
// Paddle variables
|
||||||
|
private boolean isPaddleEnabled;
|
||||||
private boolean isPaddleInverted;
|
private boolean isPaddleInverted;
|
||||||
|
|
||||||
// Disk variables - TODO: refactor into a class
|
// Disk variables - TODO: refactor into a class
|
||||||
@ -132,6 +143,10 @@ public class AppleIIGo extends Applet implements KeyListener, ComponentListener,
|
|||||||
// Keyboard
|
// Keyboard
|
||||||
keyboardUppercaseOnly = getAppletParameter("keyboardUppercaseOnly", "true").equals("true");
|
keyboardUppercaseOnly = getAppletParameter("keyboardUppercaseOnly", "true").equals("true");
|
||||||
|
|
||||||
|
// Paddles
|
||||||
|
isPaddleEnabled = getAppletParameter("paddleEnabled", "true").equals("true");
|
||||||
|
isPaddleInverted = getAppletParameter("paddleInverted", "false").equals("true");
|
||||||
|
|
||||||
// Display
|
// Display
|
||||||
display = new AppleDisplay(this, apple);
|
display = new AppleDisplay(this, apple);
|
||||||
display.setScale(new Float(getAppletParameter("displayScale", "1")).floatValue());
|
display.setScale(new Float(getAppletParameter("displayScale", "1")).floatValue());
|
||||||
@ -362,7 +377,64 @@ public class AppleIIGo extends Applet implements KeyListener, ComponentListener,
|
|||||||
StringBuffer diskname = new StringBuffer();
|
StringBuffer diskname = new StringBuffer();
|
||||||
DataInputStream is = openInputStream(resource, diskname);
|
DataInputStream is = openInputStream(resource, diskname);
|
||||||
|
|
||||||
success = disk.readDisk(drive, is, diskname.toString(), false);
|
int diskVolumeNumber = DiskII.DEFAULT_VOLUME;
|
||||||
|
|
||||||
|
// handle disk meta tag for disk volume (etc?)
|
||||||
|
// could break this out into a method, but then multiple tags ...?
|
||||||
|
String lowerDiskname = diskname.toString().toLowerCase();
|
||||||
|
int metaIndex = lowerDiskname.indexOf(metaStart);
|
||||||
|
if (metaIndex != -1)
|
||||||
|
{
|
||||||
|
metaIndex += metaStart.length();
|
||||||
|
int command = 0;
|
||||||
|
int operand = 0;
|
||||||
|
boolean execute = false;
|
||||||
|
while (metaIndex < lowerDiskname.length())
|
||||||
|
{
|
||||||
|
char c = lowerDiskname.charAt(metaIndex++);
|
||||||
|
switch (c)
|
||||||
|
{
|
||||||
|
case '0': case '1':case '2':case '3':case '4':
|
||||||
|
case '5': case '6':case '7':case '8':case '9':
|
||||||
|
{
|
||||||
|
operand = 10 * operand + (c - '0');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case '.': // end meta
|
||||||
|
metaIndex = lowerDiskname.length();
|
||||||
|
execute = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '_': // end word
|
||||||
|
execute = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
if (c >= 'a' && c <= 'z')
|
||||||
|
{
|
||||||
|
command = (command << 16) + c;
|
||||||
|
execute = (command & 0xFFFF0000) != 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (execute)
|
||||||
|
{
|
||||||
|
switch (command)
|
||||||
|
{
|
||||||
|
case ('d' << 16) + 'v':
|
||||||
|
diskVolumeNumber = operand;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
command = 0;
|
||||||
|
operand = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
success = disk.readDisk(drive, is, diskname.toString(), !diskWritable, diskVolumeNumber);
|
||||||
is.close();
|
is.close();
|
||||||
showStatus("Drive " + (drive + 1) + ": " + resource);
|
showStatus("Drive " + (drive + 1) + ": " + resource);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -377,7 +449,7 @@ public class AppleIIGo extends Applet implements KeyListener, ComponentListener,
|
|||||||
*/
|
*/
|
||||||
public void unmountDisk(int drive) {
|
public void unmountDisk(int drive) {
|
||||||
debug("unmountDisk(drive: " + drive + ")");
|
debug("unmountDisk(drive: " + drive + ")");
|
||||||
if ((drive < 0) || (drive > 2))
|
if ((drive < 0) || (drive > 1))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!diskWritable)
|
if (!diskWritable)
|
||||||
@ -399,6 +471,29 @@ public class AppleIIGo extends Applet implements KeyListener, ComponentListener,
|
|||||||
display.setColorMode(value);
|
display.setColorMode(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set paddle enabled/disabled
|
||||||
|
*/
|
||||||
|
public void setPaddleEnabled(boolean value) {
|
||||||
|
debug("setPaddleEnabled(value: " + value + ")");
|
||||||
|
isPaddleEnabled = value;
|
||||||
|
if (!value)
|
||||||
|
{
|
||||||
|
apple.paddle.setPaddlePos(0, Paddle.PADDLE_HIGH);
|
||||||
|
apple.paddle.setPaddlePos(1, Paddle.PADDLE_HIGH);
|
||||||
|
apple.paddle.setButton(0, false);
|
||||||
|
apple.paddle.setButton(1, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set paddle inverted/normal
|
||||||
|
*/
|
||||||
|
public void setPaddleInverted(boolean value) {
|
||||||
|
debug("setPaddleInverted(value: " + value + ")");
|
||||||
|
isPaddleInverted = value;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get disk activity
|
* Get disk activity
|
||||||
*/
|
*/
|
||||||
@ -406,8 +501,6 @@ public class AppleIIGo extends Applet implements KeyListener, ComponentListener,
|
|||||||
return (!isCpuPaused && disk.isMotorOn());
|
return (!isCpuPaused && disk.isMotorOn());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* KeyListener event handling
|
* KeyListener event handling
|
||||||
*/
|
*/
|
||||||
@ -575,11 +668,7 @@ public class AppleIIGo extends Applet implements KeyListener, ComponentListener,
|
|||||||
// else fall through
|
// else fall through
|
||||||
case KeyEvent.VK_KP_LEFT:
|
case KeyEvent.VK_KP_LEFT:
|
||||||
case KeyEvent.VK_KP_RIGHT:
|
case KeyEvent.VK_KP_RIGHT:
|
||||||
if (isPaddleInverted) {
|
handleKeypadCentreX();
|
||||||
apple.paddle.setPaddlePos(1, 127);
|
|
||||||
} else {
|
|
||||||
apple.paddle.setPaddlePos(0, 127);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case KeyEvent.VK_UP:
|
case KeyEvent.VK_UP:
|
||||||
case KeyEvent.VK_DOWN:
|
case KeyEvent.VK_DOWN:
|
||||||
@ -588,11 +677,7 @@ public class AppleIIGo extends Applet implements KeyListener, ComponentListener,
|
|||||||
// else fall through
|
// else fall through
|
||||||
case KeyEvent.VK_KP_UP:
|
case KeyEvent.VK_KP_UP:
|
||||||
case KeyEvent.VK_KP_DOWN:
|
case KeyEvent.VK_KP_DOWN:
|
||||||
if (isPaddleInverted) {
|
handleKeypadCentreY();
|
||||||
apple.paddle.setPaddlePos(0, 127);
|
|
||||||
} else {
|
|
||||||
apple.paddle.setPaddlePos(1, 127);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case KeyEvent.VK_HOME:
|
case KeyEvent.VK_HOME:
|
||||||
if (!e.isControlDown())
|
if (!e.isControlDown())
|
||||||
@ -604,37 +689,71 @@ public class AppleIIGo extends Applet implements KeyListener, ComponentListener,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void handleKeypadCentreX() {
|
||||||
|
if (isPaddleEnabled)
|
||||||
|
{
|
||||||
|
if (isPaddleInverted) {
|
||||||
|
apple.paddle.setPaddlePos(1, 127);
|
||||||
|
} else {
|
||||||
|
apple.paddle.setPaddlePos(0, 127);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleKeypadCentreY() {
|
||||||
|
if (isPaddleEnabled)
|
||||||
|
{
|
||||||
|
if (isPaddleInverted) {
|
||||||
|
apple.paddle.setPaddlePos(0, 127);
|
||||||
|
} else {
|
||||||
|
apple.paddle.setPaddlePos(1, 127);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void handleKeypadLeft() {
|
private void handleKeypadLeft() {
|
||||||
|
if (isPaddleEnabled)
|
||||||
|
{
|
||||||
if (isPaddleInverted) {
|
if (isPaddleInverted) {
|
||||||
apple.paddle.setPaddlePos(1, 255);
|
apple.paddle.setPaddlePos(1, 255);
|
||||||
} else {
|
} else {
|
||||||
apple.paddle.setPaddlePos(0, 0);
|
apple.paddle.setPaddlePos(0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void handleKeypadRight() {
|
private void handleKeypadRight() {
|
||||||
|
if (isPaddleEnabled)
|
||||||
|
{
|
||||||
if (isPaddleInverted) {
|
if (isPaddleInverted) {
|
||||||
apple.paddle.setPaddlePos(1, 0);
|
apple.paddle.setPaddlePos(1, 0);
|
||||||
} else {
|
} else {
|
||||||
apple.paddle.setPaddlePos(0, 255);
|
apple.paddle.setPaddlePos(0, 255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void handleKeypadUp() {
|
private void handleKeypadUp() {
|
||||||
|
if (isPaddleEnabled)
|
||||||
|
{
|
||||||
if (isPaddleInverted) {
|
if (isPaddleInverted) {
|
||||||
apple.paddle.setPaddlePos(0, 255);
|
apple.paddle.setPaddlePos(0, 255);
|
||||||
} else {
|
} else {
|
||||||
apple.paddle.setPaddlePos(1, 0);
|
apple.paddle.setPaddlePos(1, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void handleKeypadDown() {
|
private void handleKeypadDown() {
|
||||||
|
if (isPaddleEnabled)
|
||||||
|
{
|
||||||
if (isPaddleInverted) {
|
if (isPaddleInverted) {
|
||||||
apple.paddle.setPaddlePos(0, 0);
|
apple.paddle.setPaddlePos(0, 0);
|
||||||
} else {
|
} else {
|
||||||
apple.paddle.setPaddlePos(1, 255);
|
apple.paddle.setPaddlePos(1, 255);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ComponentListener event handling
|
* ComponentListener event handling
|
||||||
@ -677,21 +796,25 @@ public class AppleIIGo extends Applet implements KeyListener, ComponentListener,
|
|||||||
|
|
||||||
public void mousePressed(MouseEvent e) {
|
public void mousePressed(MouseEvent e) {
|
||||||
int modifiers = e.getModifiers();
|
int modifiers = e.getModifiers();
|
||||||
|
if (isPaddleEnabled)
|
||||||
|
{
|
||||||
if ((modifiers & InputEvent.BUTTON1_MASK) != 0)
|
if ((modifiers & InputEvent.BUTTON1_MASK) != 0)
|
||||||
apple.paddle.setButton(0, true);
|
apple.paddle.setButton(0, true);
|
||||||
if ((modifiers & InputEvent.BUTTON3_MASK) != 0)
|
if ((modifiers & InputEvent.BUTTON3_MASK) != 0)
|
||||||
apple.paddle.setButton(1, true);
|
apple.paddle.setButton(1, true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void mouseReleased(MouseEvent e) {
|
public void mouseReleased(MouseEvent e) {
|
||||||
int modifiers = e.getModifiers();
|
int modifiers = e.getModifiers();
|
||||||
|
if (isPaddleEnabled)
|
||||||
|
{
|
||||||
if ((modifiers & InputEvent.BUTTON1_MASK) != 0)
|
if ((modifiers & InputEvent.BUTTON1_MASK) != 0)
|
||||||
apple.paddle.setButton(0, false);
|
apple.paddle.setButton(0, false);
|
||||||
if ((modifiers & InputEvent.BUTTON3_MASK) != 0)
|
if ((modifiers & InputEvent.BUTTON3_MASK) != 0)
|
||||||
apple.paddle.setButton(1, false);
|
apple.paddle.setButton(1, false);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void mouseDragged(MouseEvent e) {
|
public void mouseDragged(MouseEvent e) {
|
||||||
mouseMoved(e);
|
mouseMoved(e);
|
||||||
@ -699,6 +822,8 @@ public class AppleIIGo extends Applet implements KeyListener, ComponentListener,
|
|||||||
|
|
||||||
public void mouseMoved(MouseEvent e) {
|
public void mouseMoved(MouseEvent e) {
|
||||||
float scale = display.getScale();
|
float scale = display.getScale();
|
||||||
|
if (isPaddleEnabled)
|
||||||
|
{
|
||||||
if (isPaddleInverted) {
|
if (isPaddleInverted) {
|
||||||
apple.paddle.setPaddlePos(0, (int) (255 - e.getY() * 256 / (192 * scale)));
|
apple.paddle.setPaddlePos(0, (int) (255 - e.getY() * 256 / (192 * scale)));
|
||||||
apple.paddle.setPaddlePos(1, (int) (255 - e.getX() * 256 / (280 * scale)));
|
apple.paddle.setPaddlePos(1, (int) (255 - e.getX() * 256 / (280 * scale)));
|
||||||
@ -707,6 +832,7 @@ public class AppleIIGo extends Applet implements KeyListener, ComponentListener,
|
|||||||
apple.paddle.setPaddlePos(1, (int) (e.getY() * 256 / (192 * scale)));
|
apple.paddle.setPaddlePos(1, (int) (e.getY() * 256 / (192 * scale)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applet paint function
|
* Applet paint function
|
||||||
|
@ -13,7 +13,7 @@ public class AppleSpeaker implements Runnable {
|
|||||||
private EmAppleII apple;
|
private EmAppleII apple;
|
||||||
|
|
||||||
// Refresh
|
// Refresh
|
||||||
private int refreshRate;
|
// private int refreshRate;
|
||||||
private long refreshInterval;
|
private long refreshInterval;
|
||||||
|
|
||||||
// Sound stuff
|
// Sound stuff
|
||||||
@ -58,7 +58,7 @@ public class AppleSpeaker implements Runnable {
|
|||||||
if (value <= 0.0f)
|
if (value <= 0.0f)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
this.refreshRate = value;
|
// this.refreshRate = value;
|
||||||
refreshInterval = (int) (1000.0 / value);
|
refreshInterval = (int) (1000.0 / value);
|
||||||
|
|
||||||
speakerClocksPerSample = (int) (apple.getCpuSpeed() * 1000.0f / SPEAKER_SAMPLERATE);
|
speakerClocksPerSample = (int) (apple.getCpuSpeed() * 1000.0f / SPEAKER_SAMPLERATE);
|
||||||
@ -67,9 +67,9 @@ public class AppleSpeaker implements Runnable {
|
|||||||
/**
|
/**
|
||||||
* Get refresh rate
|
* Get refresh rate
|
||||||
*/
|
*/
|
||||||
private int getRefreshRate() {
|
// private int getRefreshRate() {
|
||||||
return refreshRate;
|
// return refreshRate;
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set speaker volume
|
* Set speaker volume
|
||||||
@ -120,7 +120,7 @@ public class AppleSpeaker implements Runnable {
|
|||||||
SPEAKER_BIGENDIAN);
|
SPEAKER_BIGENDIAN);
|
||||||
|
|
||||||
DataLine.Info info = new DataLine.Info(
|
DataLine.Info info = new DataLine.Info(
|
||||||
DataLine.class,
|
SourceDataLine.class,
|
||||||
audioFormat);
|
audioFormat);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -37,6 +37,7 @@ public class DiskII extends Peripheral {
|
|||||||
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 = 0x1A00; // 0x1A00 (6656) for .NIB (was 6250)
|
private static final int RAW_TRACK_BYTES = 0x1A00; // 0x1A00 (6656) for .NIB (was 6250)
|
||||||
|
public static final int DEFAULT_VOLUME = 254;
|
||||||
|
|
||||||
// Disk II direct access variables
|
// Disk II direct access variables
|
||||||
private int drive = 0;
|
private int drive = 0;
|
||||||
@ -108,8 +109,8 @@ public class DiskII extends Peripheral {
|
|||||||
super();
|
super();
|
||||||
this.apple = apple;
|
this.apple = apple;
|
||||||
|
|
||||||
readDisk(0, null, "", false);
|
readDisk(0, null, "", false, DEFAULT_VOLUME);
|
||||||
readDisk(1, null, "", false);
|
readDisk(1, null, "", false, DEFAULT_VOLUME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -137,6 +138,7 @@ public class DiskII extends Peripheral {
|
|||||||
if (currPhysTrack < ((2 * DOS_NUM_TRACKS) - 1))
|
if (currPhysTrack < ((2 * DOS_NUM_TRACKS) - 1))
|
||||||
currPhysTrack++;
|
currPhysTrack++;
|
||||||
}
|
}
|
||||||
|
//System.out.println("half track=" + currPhysTrack);
|
||||||
realTrack = diskData[drive][currPhysTrack >> 1];
|
realTrack = diskData[drive][currPhysTrack >> 1];
|
||||||
break;
|
break;
|
||||||
case 0x3:
|
case 0x3:
|
||||||
@ -149,6 +151,7 @@ public class DiskII extends Peripheral {
|
|||||||
if (currPhysTrack < ((2 * DOS_NUM_TRACKS) - 1))
|
if (currPhysTrack < ((2 * DOS_NUM_TRACKS) - 1))
|
||||||
currPhysTrack++;
|
currPhysTrack++;
|
||||||
}
|
}
|
||||||
|
//System.out.println("half track=" + currPhysTrack);
|
||||||
realTrack = diskData[drive][currPhysTrack >> 1];
|
realTrack = diskData[drive][currPhysTrack >> 1];
|
||||||
break;
|
break;
|
||||||
case 0x5:
|
case 0x5:
|
||||||
@ -161,6 +164,7 @@ public class DiskII extends Peripheral {
|
|||||||
if (currPhysTrack < ((2 * DOS_NUM_TRACKS) - 1))
|
if (currPhysTrack < ((2 * DOS_NUM_TRACKS) - 1))
|
||||||
currPhysTrack++;
|
currPhysTrack++;
|
||||||
}
|
}
|
||||||
|
//System.out.println("half track=" + currPhysTrack);
|
||||||
realTrack = diskData[drive][currPhysTrack >> 1];
|
realTrack = diskData[drive][currPhysTrack >> 1];
|
||||||
break;
|
break;
|
||||||
case 0x7:
|
case 0x7:
|
||||||
@ -173,6 +177,7 @@ public class DiskII extends Peripheral {
|
|||||||
if (currPhysTrack < ((2 * DOS_NUM_TRACKS) - 1))
|
if (currPhysTrack < ((2 * DOS_NUM_TRACKS) - 1))
|
||||||
currPhysTrack++;
|
currPhysTrack++;
|
||||||
}
|
}
|
||||||
|
//System.out.println("half track=" + currPhysTrack);
|
||||||
realTrack = diskData[drive][currPhysTrack >> 1];
|
realTrack = diskData[drive][currPhysTrack >> 1];
|
||||||
break;
|
break;
|
||||||
case 0x8:
|
case 0x8:
|
||||||
@ -272,12 +277,12 @@ public class DiskII extends Peripheral {
|
|||||||
* @param is InputStream
|
* @param is InputStream
|
||||||
* @param drive Disk II drive
|
* @param drive Disk II drive
|
||||||
*/
|
*/
|
||||||
public boolean readDisk(int drive, DataInputStream is, String name, boolean isWriteProtected) {
|
public boolean readDisk(int drive, DataInputStream is, String name, boolean isWriteProtected, int volumeNumber) {
|
||||||
byte[] track = new byte[DOS_TRACK_BYTES];
|
byte[] track = new byte[DOS_TRACK_BYTES];
|
||||||
|
|
||||||
String lowerDiskname = name.toLowerCase();
|
String lowerName = name.toLowerCase();
|
||||||
boolean proDos = lowerDiskname.indexOf(".po") != -1;
|
boolean proDos = lowerName.indexOf(".po") != -1;
|
||||||
boolean nib = lowerDiskname.indexOf(".nib") != -1;
|
boolean nib = lowerName.indexOf(".nib") != -1;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (int trackNum = 0; trackNum < DOS_NUM_TRACKS; trackNum++) {
|
for (int trackNum = 0; trackNum < DOS_NUM_TRACKS; trackNum++) {
|
||||||
@ -291,7 +296,7 @@ public class DiskII extends Peripheral {
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
is.readFully(track, 0, DOS_TRACK_BYTES);
|
is.readFully(track, 0, DOS_TRACK_BYTES);
|
||||||
trackToNibbles(track, diskData[drive][trackNum], 254, trackNum, !proDos);
|
trackToNibbles(track, diskData[drive][trackNum], volumeNumber, trackNum, !proDos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -343,8 +348,8 @@ public class DiskII extends Peripheral {
|
|||||||
latchData = (realTrack[currNibble] & 0xff);
|
latchData = (realTrack[currNibble] & 0xff);
|
||||||
|
|
||||||
// simple hack to help DOS find address prologues ($B94F)
|
// simple hack to help DOS find address prologues ($B94F)
|
||||||
if (apple.memoryRead(apple.PC + 3) == 0xD5 && // #$D5
|
if (/* fastDisk && */ latchData != 0xD5 && // TODO: fastDisk property to enable/disable
|
||||||
latchData != 0xD5 &&
|
apple.memoryRead(apple.PC + 3) == 0xD5 && // #$D5
|
||||||
apple.memoryRead(apple.PC + 2) == 0xC9 && // CMP
|
apple.memoryRead(apple.PC + 2) == 0xC9 && // CMP
|
||||||
apple.memoryRead(apple.PC + 1) == 0xFB && // PC - 3
|
apple.memoryRead(apple.PC + 1) == 0xFB && // PC - 3
|
||||||
apple.memoryRead(apple.PC + 0) == 0x10) // BPL
|
apple.memoryRead(apple.PC + 0) == 0x10) // BPL
|
||||||
@ -359,7 +364,7 @@ public class DiskII extends Peripheral {
|
|||||||
}
|
}
|
||||||
while (latchData != 0xD5 && --count > 0);
|
while (latchData != 0xD5 && --count > 0);
|
||||||
}
|
}
|
||||||
// simple hack to fool DOS drive spin detect routine ($BD34)
|
// simple hack to fool DOS 3.3 RWTS drive spin detect routine ($BD34)
|
||||||
else if (apple.memoryRead(apple.PC - 3) == 0xDD && // CMP $C08C,X
|
else if (apple.memoryRead(apple.PC - 3) == 0xDD && // CMP $C08C,X
|
||||||
apple.memoryRead(apple.PC + 1) == 0x03 && // PC + 3
|
apple.memoryRead(apple.PC + 1) == 0x03 && // PC + 3
|
||||||
apple.memoryRead(apple.PC + 0) == 0xD0) // BNE
|
apple.memoryRead(apple.PC + 0) == 0xD0) // BNE
|
||||||
@ -394,9 +399,7 @@ public class DiskII extends Peripheral {
|
|||||||
* @param address Address
|
* @param address Address
|
||||||
*/
|
*/
|
||||||
private void ioLatchD(int value) {
|
private void ioLatchD(int value) {
|
||||||
// Prepare write
|
// Prepare for write protect sense
|
||||||
writeMode = true;
|
|
||||||
latchData = value;
|
|
||||||
latchAddress = 0xd;
|
latchAddress = 0xd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,11 +183,11 @@ public class Em6502 {
|
|||||||
private final void setFC(boolean c) {result = (c ? 0x100 : 0x00);}
|
private final void setFC(boolean c) {result = (c ? 0x100 : 0x00);}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Macro for page crossing cycle regulation
|
* Macro for page crossing cycle regulation - TODO: Why not used!? CPU probably not cycle accurate.
|
||||||
*/
|
*/
|
||||||
private final void checkCrossPage(int addr, int offset) {
|
// private final void checkCrossPage(int addr, int offset) {
|
||||||
if ((((addr + offset) ^ addr) & 0xff00) != 0) clock++;
|
// if ((((addr + offset) ^ addr) & 0xff00) != 0) clock++;
|
||||||
}
|
// }
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Macros for effective address calculation
|
* Macros for effective address calculation
|
||||||
@ -1539,6 +1539,9 @@ public class Em6502 {
|
|||||||
default: // unknown instructions
|
default: // unknown instructions
|
||||||
clock += 2;
|
clock += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if (PC == 0xB30)
|
||||||
|
// throw (new RuntimeException()); // TODO: for breakpoint hack - disable
|
||||||
}
|
}
|
||||||
|
|
||||||
public final int executeInstructions(int num) {
|
public final int executeInstructions(int num) {
|
||||||
|
@ -74,8 +74,9 @@ public class EmAppleII extends Em6502 implements Runnable {
|
|||||||
public static final int GR_DHIRES = (1 << 7);
|
public static final int GR_DHIRES = (1 << 7);
|
||||||
|
|
||||||
// Sound
|
// Sound
|
||||||
public static final int SPEAKER_FLIPS_SIZE = 4096;
|
public static final int SPEAKER_FLIPS_BITS = 12;
|
||||||
public static final int SPEAKER_FLIPS_MASK = 4095;
|
public static final int SPEAKER_FLIPS_SIZE = 1 << SPEAKER_FLIPS_BITS;
|
||||||
|
public static final int SPEAKER_FLIPS_MASK = SPEAKER_FLIPS_SIZE - 1;
|
||||||
|
|
||||||
public int speakerFlips[] = new int[SPEAKER_FLIPS_SIZE];
|
public int speakerFlips[] = new int[SPEAKER_FLIPS_SIZE];
|
||||||
public int speakerFlipsPointer = 0;
|
public int speakerFlipsPointer = 0;
|
||||||
@ -1126,6 +1127,7 @@ public class EmAppleII extends Em6502 implements Runnable {
|
|||||||
|
|
||||||
checkInterrupts();
|
checkInterrupts();
|
||||||
|
|
||||||
|
// try {
|
||||||
if (isStepMode) {
|
if (isStepMode) {
|
||||||
if (isNextStep) {
|
if (isNextStep) {
|
||||||
isNextStep = false;
|
isNextStep = false;
|
||||||
@ -1136,6 +1138,11 @@ public class EmAppleII extends Em6502 implements Runnable {
|
|||||||
while (clocksNeeded > 0)
|
while (clocksNeeded > 0)
|
||||||
clocksNeeded -= executeInstructions(1 + (clocksNeeded >> 3));
|
clocksNeeded -= executeInstructions(1 + (clocksNeeded >> 3));
|
||||||
}
|
}
|
||||||
|
// }
|
||||||
|
// catch (RuntimeException e)
|
||||||
|
// {
|
||||||
|
// setStepMode(true); // TODO: for breakpoint hack - disable
|
||||||
|
// }
|
||||||
|
|
||||||
// TODO: need something like the following for fast disk access
|
// TODO: need something like the following for fast disk access
|
||||||
//if (slots[6] instanceof DiskII && !((DiskII)slots[6]).isMotorOn())
|
//if (slots[6] instanceof DiskII && !((DiskII)slots[6]).isMotorOn())
|
||||||
|
@ -22,7 +22,7 @@ public class Paddle {
|
|||||||
private int[] buttonRegister = new int[4];
|
private int[] buttonRegister = new int[4];
|
||||||
|
|
||||||
// Paddle variables
|
// Paddle variables
|
||||||
private int paddleMode;
|
// private int paddleMode; // TODO: Was this for analog/digital mode? (Nick)
|
||||||
|
|
||||||
private int[] paddleClockEvent = new int[4];
|
private int[] paddleClockEvent = new int[4];
|
||||||
private int[] paddleClockInc = new int[4];
|
private int[] paddleClockInc = new int[4];
|
||||||
@ -35,10 +35,10 @@ public class Paddle {
|
|||||||
public Paddle(EmAppleII apple) {
|
public Paddle(EmAppleII apple) {
|
||||||
this.apple = apple;
|
this.apple = apple;
|
||||||
|
|
||||||
setPaddlePos(0, PADDLE_CENTER);
|
setPaddlePos(0, PADDLE_HIGH);
|
||||||
setPaddlePos(1, PADDLE_CENTER);
|
setPaddlePos(1, PADDLE_HIGH);
|
||||||
setPaddlePos(2, PADDLE_CENTER);
|
setPaddlePos(2, PADDLE_HIGH);
|
||||||
setPaddlePos(3, PADDLE_CENTER);
|
setPaddlePos(3, PADDLE_HIGH);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user