Version 1.0.9 - changes by Nick
- fixed disk speed-up bug (Sherwood Forest reads with the drive motor off) - added check for 2IMG header ID - fixed processor status bugs in BRK, PLP, RTI, NMI, IRQ
This commit is contained in:
parent
add3d41448
commit
dc8f597c62
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* AppleIIGo
|
* AppleIIGo
|
||||||
* Display processing
|
* Display processing
|
||||||
* (C) 2006 by Marc S. Ressl (mressl@gmail.com)
|
* Copyright 2006 by Marc S. Ressl (mressl@gmail.com)
|
||||||
* Released under the GPL
|
* Released under the GPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -2,13 +2,18 @@
|
||||||
/**
|
/**
|
||||||
* AppleIIGo
|
* AppleIIGo
|
||||||
* The Java Apple II Emulator
|
* The Java Apple II Emulator
|
||||||
* Copyright 2011 by Nick Westgate (Nick.Westgate@gmail.com)
|
* Copyright 2014 by Nick Westgate (Nick.Westgate@gmail.com)
|
||||||
* Copyright 2006 by Marc S. Ressl (mressl@gmail.com)
|
* Copyright 2006 by Marc S. Ressl (mressl@gmail.com)
|
||||||
* Released under the GNU General Public License version 2
|
* Released under the GNU General Public License version 2
|
||||||
* See http://www.gnu.org/licenses/
|
* See http://www.gnu.org/licenses/
|
||||||
*
|
*
|
||||||
* Change list:
|
* Change list:
|
||||||
*
|
*
|
||||||
|
* Version 1.0.9 - changes by Nick:
|
||||||
|
* - fixed disk speed-up bug (Sherwood Forest reads with the drive motor off)
|
||||||
|
* - added check for 2IMG header ID
|
||||||
|
* - fixed processor status bugs in BRK, PLP, RTI, NMI, IRQ
|
||||||
|
*
|
||||||
* Version 1.0.8 - changes by Nick:
|
* Version 1.0.8 - changes by Nick:
|
||||||
* - implemented disk writing (only in memory, not persisted)
|
* - implemented disk writing (only in memory, not persisted)
|
||||||
* - added support for .2MG (2IMG) disk images, including lock flag and volume number
|
* - added support for .2MG (2IMG) disk images, including lock flag and volume number
|
||||||
|
@ -80,7 +85,7 @@ public class AppleIIGo extends Applet implements KeyListener, ComponentListener,
|
||||||
|
|
||||||
private static final long serialVersionUID = -3302282815441501352L;
|
private static final long serialVersionUID = -3302282815441501352L;
|
||||||
|
|
||||||
final String version = "1.0.8";
|
final String version = "1.0.9";
|
||||||
final String versionString = "AppleIIGo Version " + version;
|
final String versionString = "AppleIIGo Version " + version;
|
||||||
final String metaStart = "_meta_";
|
final String metaStart = "_meta_";
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* AppleIIGo
|
* AppleIIGo
|
||||||
* Speaker processing
|
* Speaker processing
|
||||||
* (C) 2006 by Marc S. Ressl(mressl@gmail.com)
|
* Copyright 2006 by Marc S. Ressl(mressl@gmail.com)
|
||||||
* Released under the GPL
|
* Released under the GPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
/**
|
/**
|
||||||
* AppleIIGo
|
* AppleIIGo
|
||||||
* Disk II Emulator
|
* Disk II Emulator
|
||||||
* (C) 2006 by Marc S. Ressl(mressl@gmail.com)
|
* Copyright 2014 by Nick Westgate (Nick.Westgate@gmail.com)
|
||||||
* (C) 2011 by Nick Westgate (Nick.Westgate@gmail.com)
|
* Copyright 2006 by Marc S. Ressl(mressl@gmail.com)
|
||||||
* Released under the GPL
|
* Released under the GPL
|
||||||
* Based on work by Doug Kwan
|
* Based on work by Doug Kwan
|
||||||
*/
|
*/
|
||||||
|
@ -38,6 +38,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)
|
||||||
|
private static final int STANDARD_2IMG_HEADER_ID = 0x32494D47;
|
||||||
private static final int STANDARD_2IMG_HEADER_SIZE = 64;
|
private static final int STANDARD_2IMG_HEADER_SIZE = 64;
|
||||||
private static final int STANDARD_PRODOS_BLOCKS = 280;
|
private static final int STANDARD_PRODOS_BLOCKS = 280;
|
||||||
|
|
||||||
|
@ -168,20 +169,8 @@ public class DiskII extends Peripheral {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((address & 1) == 0)
|
// only even addresses return the latch
|
||||||
{
|
return ((address & 1) == 0) ? latchData : rand.nextInt(256); // TODO: floating bus
|
||||||
// only even addresses return the latch
|
|
||||||
if (isMotorOn)
|
|
||||||
{
|
|
||||||
return latchData;
|
|
||||||
}
|
|
||||||
|
|
||||||
// simple hack to fool DOS SAMESLOT drive spin check (usually at $BD34)
|
|
||||||
driveSpin = !driveSpin;
|
|
||||||
return driveSpin ? 0x7E : 0x7F;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rand.nextInt(256); // TODO: floating bus
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -247,7 +236,10 @@ public class DiskII extends Peripheral {
|
||||||
* Reset peripheral
|
* Reset peripheral
|
||||||
*/
|
*/
|
||||||
public void reset() {
|
public void reset() {
|
||||||
ioRead(0x8);
|
drive = 0;
|
||||||
|
isMotorOn = false;
|
||||||
|
loadMode = false;
|
||||||
|
writeMode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -266,6 +258,10 @@ public class DiskII extends Peripheral {
|
||||||
byte[] header = new byte[STANDARD_2IMG_HEADER_SIZE];
|
byte[] header = new byte[STANDARD_2IMG_HEADER_SIZE];
|
||||||
is.readFully(header, 0, STANDARD_2IMG_HEADER_SIZE);
|
is.readFully(header, 0, STANDARD_2IMG_HEADER_SIZE);
|
||||||
|
|
||||||
|
int id = (header[0x00] << 24) | (header[0x01] << 16) | (header[0x02] << 8) | (header[0x03]);
|
||||||
|
if (id != STANDARD_2IMG_HEADER_ID)
|
||||||
|
return false;
|
||||||
|
|
||||||
int headerSize = (header[0x09] << 8) | (header[0x08]);
|
int headerSize = (header[0x09] << 8) | (header[0x08]);
|
||||||
if (headerSize != STANDARD_2IMG_HEADER_SIZE)
|
if (headerSize != STANDARD_2IMG_HEADER_SIZE)
|
||||||
return false;
|
return false;
|
||||||
|
@ -352,6 +348,17 @@ public class DiskII extends Peripheral {
|
||||||
loadMode = false;
|
loadMode = false;
|
||||||
if (!writeMode)
|
if (!writeMode)
|
||||||
{
|
{
|
||||||
|
if (!isMotorOn)
|
||||||
|
{
|
||||||
|
// simple hack to fool DOS SAMESLOT drive spin check (usually at $BD34)
|
||||||
|
driveSpin = !driveSpin;
|
||||||
|
if (driveSpin)
|
||||||
|
{
|
||||||
|
latchData = 0x7F;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Read data: C0xE, C0xC
|
// Read data: C0xE, C0xC
|
||||||
latchData = (realTrack[currNibble] & 0xff);
|
latchData = (realTrack[currNibble] & 0xff);
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AppleIIGo
|
* AppleIIGo
|
||||||
* Apple II Emulator for J2SE
|
* Apple II Emulator for J2SE
|
||||||
* (C) 2006 by Marc S. Ressl(mressl@gmail.com)
|
* Copyright 2006 by Marc S. Ressl(mressl@gmail.com)
|
||||||
* Released under the GPL
|
* Released under the GPL
|
||||||
* Adapted from code by Doug Kwan
|
* Adapted from code by Doug Kwan
|
||||||
* Adapted from code by Randy Frank randy@tessa.iaf.uiowa.edu
|
* Adapted from code by Randy Frank randy@tessa.iaf.uiowa.edu
|
||||||
* Adapted from code (C) 1989 Ben Koning [556498717 408/738-1763 ben@apple.com]
|
* Adapted from code Copyright 1989 Ben Koning [556498717 408/738-1763 ben@apple.com]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class Em6502 {
|
public class Em6502 {
|
||||||
|
@ -78,6 +80,7 @@ public class Em6502 {
|
||||||
public static final int FLAG_I = (1 << 2);
|
public static final int FLAG_I = (1 << 2);
|
||||||
public static final int FLAG_D = (1 << 3);
|
public static final int FLAG_D = (1 << 3);
|
||||||
public static final int FLAG_B = (1 << 4);
|
public static final int FLAG_B = (1 << 4);
|
||||||
|
public static final int FLAG_R = (1 << 6);
|
||||||
public static final int FLAG_V = (1 << 6);
|
public static final int FLAG_V = (1 << 6);
|
||||||
public static final int FLAG_N = (1 << 7);
|
public static final int FLAG_N = (1 << 7);
|
||||||
/*
|
/*
|
||||||
|
@ -120,6 +123,8 @@ public class Em6502 {
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
public Em6502() {
|
public Em6502() {
|
||||||
|
// createRunFile();
|
||||||
|
|
||||||
// Init BCD tables
|
// Init BCD tables
|
||||||
BCDTableAdd = new int[512];
|
BCDTableAdd = new int[512];
|
||||||
BCDTableSub = new int[512];
|
BCDTableSub = new int[512];
|
||||||
|
@ -133,6 +138,10 @@ public class Em6502 {
|
||||||
BCDTableSub[i] = ((i & 0x0f) <= 0x09) ? i : (i - 0x06);
|
BCDTableSub[i] = ((i & 0x0f) <= 0x09) ? i : (i - 0x06);
|
||||||
BCDTableSub[i] -= ((BCDTableSub[i] & 0xf0) <= 0x90) ? 0 : 0x60;
|
BCDTableSub[i] -= ((BCDTableSub[i] & 0xf0) <= 0x90) ? 0 : 0x60;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Init CPU
|
||||||
|
S = 0xFF;
|
||||||
|
P = FLAG_B | FLAG_R;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -294,9 +303,39 @@ public class Em6502 {
|
||||||
clock++;
|
clock++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// private PrintWriter runFile;
|
||||||
|
// private void createRunFile()
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// runFile = new PrintWriter("C:\\Users\\Public\\AppleIIGoRun.txt");
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// // swallow
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// private final void writeRunFile(int opcode)
|
||||||
|
// {
|
||||||
|
// if (
|
||||||
|
// (PC > 0x0500)
|
||||||
|
// &&
|
||||||
|
// (PC < 0x0600)
|
||||||
|
// )
|
||||||
|
// {
|
||||||
|
// setN(getFN());
|
||||||
|
// setZ(getFZ());
|
||||||
|
// setC(getFC());
|
||||||
|
//
|
||||||
|
// runFile.printf("%04X-%02X P=%02X A=%02X\r\n", PC, opcode, P, A);
|
||||||
|
// runFile.flush();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
/** This executes a single instruction. */
|
/** This executes a single instruction. */
|
||||||
private final void executeInstruction() {
|
private final void executeInstruction() {
|
||||||
opcode = memoryRead(PC);
|
opcode = memoryRead(PC);
|
||||||
|
// writeRunFile(opcode);
|
||||||
PC++;
|
PC++;
|
||||||
|
|
||||||
switch(opcode) {
|
switch(opcode) {
|
||||||
|
@ -535,8 +574,7 @@ public class Em6502 {
|
||||||
setN(getFN());
|
setN(getFN());
|
||||||
setZ(getFZ());
|
setZ(getFZ());
|
||||||
setC(getFC());
|
setC(getFC());
|
||||||
setB(true);
|
push(P); // break flag is always set
|
||||||
push(P);
|
|
||||||
setI(true);
|
setI(true);
|
||||||
PC = memoryRead(0xfffe);
|
PC = memoryRead(0xfffe);
|
||||||
PC |= memoryRead(0xffff) << 8;
|
PC |= memoryRead(0xffff) << 8;
|
||||||
|
@ -1043,7 +1081,7 @@ public class Em6502 {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x28: // PLP
|
case 0x28: // PLP
|
||||||
P = pop() | 0x20; // fix bug in bit5 of P
|
P = pop() | FLAG_B | FLAG_R; // fix bug in bit5 of P
|
||||||
setFC(getC());
|
setFC(getC());
|
||||||
setFNZ(getN(), getZ());
|
setFNZ(getN(), getZ());
|
||||||
clock += 4;
|
clock += 4;
|
||||||
|
@ -1144,7 +1182,7 @@ public class Em6502 {
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x40: // RTI
|
case 0x40: // RTI
|
||||||
P = pop() | 0x20; // bit 5 bug of 6502
|
P = pop() | FLAG_B | FLAG_R; // bit 5 bug of 6502
|
||||||
setFC(getC());
|
setFC(getC());
|
||||||
setFNZ(getN(), getZ());
|
setFNZ(getN(), getZ());
|
||||||
PC = pop(); // splitting is necessary
|
PC = pop(); // splitting is necessary
|
||||||
|
@ -1570,13 +1608,13 @@ public class Em6502 {
|
||||||
if ((exceptionRegister & SIG_6502_RESET) != 0) {
|
if ((exceptionRegister & SIG_6502_RESET) != 0) {
|
||||||
onReset();
|
onReset();
|
||||||
|
|
||||||
PC = memoryRead(0xfffc);
|
|
||||||
PC |= (memoryRead(0xfffd) << 8);
|
|
||||||
S = (S - 3) & 0xff;
|
|
||||||
setI(true);
|
|
||||||
setD(false); // not on NMOS 6502
|
setD(false); // not on NMOS 6502
|
||||||
setFC(getC());
|
setFC(getC());
|
||||||
setFNZ(getN(), getZ());
|
setFNZ(getN(), getZ());
|
||||||
|
S = (S - 3) & 0xff;
|
||||||
|
setI(true);
|
||||||
|
PC = memoryRead(0xfffc);
|
||||||
|
PC |= (memoryRead(0xfffd) << 8);
|
||||||
clock += 7;
|
clock += 7;
|
||||||
exceptionRegister &= ~SIG_6502_RESET;
|
exceptionRegister &= ~SIG_6502_RESET;
|
||||||
}
|
}
|
||||||
|
@ -1590,7 +1628,8 @@ public class Em6502 {
|
||||||
setN(getFN());
|
setN(getFN());
|
||||||
setZ(getFZ());
|
setZ(getFZ());
|
||||||
setC(getFC());
|
setC(getFC());
|
||||||
push(P);
|
push(P & ~FLAG_B);
|
||||||
|
setI(true);
|
||||||
PC = memoryRead(0xfffa);
|
PC = memoryRead(0xfffa);
|
||||||
PC |= memoryRead(0xfffb) << 8;
|
PC |= memoryRead(0xfffb) << 8;
|
||||||
clock += 7;
|
clock += 7;
|
||||||
|
@ -1608,8 +1647,7 @@ public class Em6502 {
|
||||||
setN(getFN());
|
setN(getFN());
|
||||||
setZ(getFZ());
|
setZ(getFZ());
|
||||||
setC(getFC());
|
setC(getFC());
|
||||||
setB(false);
|
push(P & ~FLAG_B);
|
||||||
push(P);
|
|
||||||
setI(true);
|
setI(true);
|
||||||
PC = memoryRead(0xfffe);
|
PC = memoryRead(0xfffe);
|
||||||
PC |= memoryRead(0xffff) << 8;
|
PC |= memoryRead(0xffff) << 8;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* AppleIIGo
|
* AppleIIGo
|
||||||
* Apple II Emulator for J2ME
|
* Apple II Emulator for J2ME
|
||||||
* (C) 2006 by Marc S. Ressl(mressl@gmail.com)
|
* Copyright 2006 by Marc S. Ressl(mressl@gmail.com)
|
||||||
* Released under the GPL
|
* Released under the GPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* AppleIIGo
|
* AppleIIGo
|
||||||
* Apple II Emulator for J2ME
|
* Apple II Emulator for J2ME
|
||||||
* (C) 2006 by Marc S. Ressl(mressl@gmail.com)
|
* Copyright 2006 by Marc S. Ressl(mressl@gmail.com)
|
||||||
* Released under the GPL
|
* Released under the GPL
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/**
|
/**
|
||||||
* AppleIIGo
|
* AppleIIGo
|
||||||
* Slot interface
|
* Slot interface
|
||||||
* (C) 2006 by Marc S. Ressl(mressl@gmail.com)
|
* Copyright 2006 by Marc S. Ressl(mressl@gmail.com)
|
||||||
* Released under the GPL
|
* Released under the GPL
|
||||||
* Based on work by Steven E. Hugg
|
* Based on work by Steven E. Hugg
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue