forked from Apple-2-Tools/jace
Changed CPU static variable to pass by reference -- now possible to have multiple 65c02 instaces at a time.
This commit is contained in:
parent
e82af529e8
commit
b4b95ff88b
@ -36,8 +36,7 @@ import jace.state.Stateful;
|
||||
@Stateful
|
||||
public class MOS65C02 extends CPU {
|
||||
|
||||
static public boolean readAddressTriggersEvent = true;
|
||||
static private MOS65C02 cpu;
|
||||
public boolean readAddressTriggersEvent = true;
|
||||
static int RESET_VECTOR = 0x00FFFC;
|
||||
static int INT_VECTOR = 0x00FFFE;
|
||||
@Stateful
|
||||
@ -78,6 +77,7 @@ public class MOS65C02 extends CPU {
|
||||
}
|
||||
|
||||
public enum OPCODE {
|
||||
|
||||
ADC_IMM(0x0069, COMMAND.ADC, MODE.IMMEDIATE, 2),
|
||||
ADC_ZP(0x0065, COMMAND.ADC, MODE.ZEROPAGE, 3),
|
||||
ADC_ZP_X(0x0075, COMMAND.ADC, MODE.ZEROPAGE_X, 4),
|
||||
@ -316,13 +316,13 @@ public class MOS65C02 extends CPU {
|
||||
int address = 0;
|
||||
int value = 0;
|
||||
|
||||
private void fetch() {
|
||||
address = getMode().calculator.calculateAddress();
|
||||
value = getMode().calculator.getValue(!command.isStoreOnly());
|
||||
private void fetch(MOS65C02 cpu) {
|
||||
address = getMode().calculator.calculateAddress(cpu);
|
||||
value = getMode().calculator.getValue(!command.isStoreOnly(), cpu);
|
||||
}
|
||||
|
||||
public void execute() {
|
||||
command.getProcessor().processCommand(address, value, addressingMode);
|
||||
public void execute(MOS65C02 cpu) {
|
||||
command.getProcessor().processCommand(address, value, addressingMode, cpu);
|
||||
}
|
||||
|
||||
private OPCODE(int val, COMMAND c, MODE m, int wait) {
|
||||
@ -340,64 +340,64 @@ public class MOS65C02 extends CPU {
|
||||
|
||||
private static interface AddressCalculator {
|
||||
|
||||
abstract int calculateAddress();
|
||||
abstract int calculateAddress(MOS65C02 cpu);
|
||||
|
||||
default int getValue(boolean isRead) {
|
||||
int address = calculateAddress();
|
||||
default int getValue(boolean isRead, MOS65C02 cpu) {
|
||||
int address = calculateAddress(cpu);
|
||||
return (address > -1) ? (0x0ff & getMemory().read(address, TYPE.READ_DATA, isRead, false)) : 0;
|
||||
}
|
||||
}
|
||||
|
||||
private enum MODE {
|
||||
public enum MODE {
|
||||
|
||||
IMPLIED(1, "", () -> -1),
|
||||
IMPLIED(1, "", (cpu) -> -1),
|
||||
// RELATIVE(2, "#$~1 ($R)"),
|
||||
RELATIVE(2, "$R", () -> {
|
||||
RELATIVE(2, "$R", (cpu) -> {
|
||||
int pc = cpu.getProgramCounter();
|
||||
int address = pc + 2 + getMemory().read(pc + 1, TYPE.READ_OPERAND, readAddressTriggersEvent, false);
|
||||
int address = pc + 2 + getMemory().read(pc + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false);
|
||||
// The wait cycles are not added unless the branch actually happens!
|
||||
cpu.setPageBoundaryPenalty((address & 0x00ff00) != (pc & 0x00ff00));
|
||||
return address;
|
||||
}),
|
||||
IMMEDIATE(2, "#$~1", () -> cpu.getProgramCounter() + 1),
|
||||
ZEROPAGE(2, "$~1", () -> getMemory().read(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, readAddressTriggersEvent, false) & 0x00FF),
|
||||
ZEROPAGE_X(2, "$~1,X", () -> 0x0FF & (getMemory().read(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, readAddressTriggersEvent, false) + cpu.X)),
|
||||
ZEROPAGE_Y(2, "$~1,Y", () -> 0x0FF & (getMemory().read(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, readAddressTriggersEvent, false) + cpu.Y)),
|
||||
INDIRECT(3, "$(~2~1)", () -> {
|
||||
int address = getMemory().readWord(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, readAddressTriggersEvent, false);
|
||||
IMMEDIATE(2, "#$~1", (cpu) -> cpu.getProgramCounter() + 1),
|
||||
ZEROPAGE(2, "$~1", (cpu) -> getMemory().read(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false) & 0x00FF),
|
||||
ZEROPAGE_X(2, "$~1,X", (cpu) -> 0x0FF & (getMemory().read(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false) + cpu.X)),
|
||||
ZEROPAGE_Y(2, "$~1,Y", (cpu) -> 0x0FF & (getMemory().read(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false) + cpu.Y)),
|
||||
INDIRECT(3, "$(~2~1)", (cpu) -> {
|
||||
int address = getMemory().readWord(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false);
|
||||
return getMemory().readWord(address, TYPE.READ_DATA, true, false);
|
||||
}),
|
||||
INDIRECT_X(3, "$(~2~1,X)", () -> {
|
||||
int address = getMemory().readWord(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, readAddressTriggersEvent, false) + cpu.X;
|
||||
INDIRECT_X(3, "$(~2~1,X)", (cpu) -> {
|
||||
int address = getMemory().readWord(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false) + cpu.X;
|
||||
return getMemory().readWord(address & 0x0FFFF, TYPE.READ_DATA, true, false);
|
||||
}),
|
||||
INDIRECT_ZP(2, "$(~1)", () -> {
|
||||
int address = getMemory().read(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, readAddressTriggersEvent, false);
|
||||
INDIRECT_ZP(2, "$(~1)", (cpu) -> {
|
||||
int address = getMemory().read(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false);
|
||||
return getMemory().readWord(address & 0x0FF, TYPE.READ_DATA, true, false);
|
||||
}),
|
||||
INDIRECT_ZP_X(2, "$(~1,X)", () -> {
|
||||
int address = getMemory().read(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, readAddressTriggersEvent, false) + cpu.X;
|
||||
INDIRECT_ZP_X(2, "$(~1,X)", (cpu) -> {
|
||||
int address = getMemory().read(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false) + cpu.X;
|
||||
return getMemory().readWord(address & 0x0FF, TYPE.READ_DATA, true, false);
|
||||
}),
|
||||
INDIRECT_ZP_Y(2, "$(~1),Y", () -> {
|
||||
int address = 0x00FF & getMemory().read(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, readAddressTriggersEvent, false);
|
||||
INDIRECT_ZP_Y(2, "$(~1),Y", (cpu) -> {
|
||||
int address = 0x00FF & getMemory().read(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false);
|
||||
address = getMemory().readWord(address, TYPE.READ_DATA, true, false) + cpu.Y;
|
||||
if ((address & 0x00ff00) > 0) {
|
||||
cpu.addWaitCycles(1);
|
||||
}
|
||||
return address;
|
||||
}),
|
||||
ABSOLUTE(3, "$~2~1", () -> getMemory().readWord(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, readAddressTriggersEvent, false)),
|
||||
ABSOLUTE_X(3, "$~2~1,X", () -> {
|
||||
int address2 = getMemory().readWord(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, readAddressTriggersEvent, false);
|
||||
ABSOLUTE(3, "$~2~1", (cpu) -> getMemory().readWord(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false)),
|
||||
ABSOLUTE_X(3, "$~2~1,X", (cpu) -> {
|
||||
int address2 = getMemory().readWord(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false);
|
||||
int address = 0x0FFFF & (address2 + cpu.X);
|
||||
if ((address & 0x00FF00) != (address2 & 0x00FF00)) {
|
||||
cpu.addWaitCycles(1);
|
||||
}
|
||||
return address;
|
||||
}),
|
||||
ABSOLUTE_Y(3, "$~2~1,Y", () -> {
|
||||
int address2 = getMemory().readWord(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, readAddressTriggersEvent, false);
|
||||
ABSOLUTE_Y(3, "$~2~1,Y", (cpu) -> {
|
||||
int address2 = getMemory().readWord(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false);
|
||||
int address = 0x0FFFF & (address2 + cpu.Y);
|
||||
if ((address & 0x00FF00) != (address2 & 0x00FF00)) {
|
||||
cpu.addWaitCycles(1);
|
||||
@ -406,19 +406,19 @@ public class MOS65C02 extends CPU {
|
||||
}),
|
||||
ZP_REL(2, "$~1,$R", new AddressCalculator() {
|
||||
@Override
|
||||
public int calculateAddress() {
|
||||
public int calculateAddress(MOS65C02 cpu) {
|
||||
// Note: This is two's compliment addition and the getMemory().read() returns a signed 8-bit value
|
||||
int pc = cpu.getProgramCounter();
|
||||
int address = pc + 2 + getMemory().read(pc + 2, TYPE.READ_OPERAND, readAddressTriggersEvent, false);
|
||||
int address = pc + 2 + getMemory().read(pc + 2, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false);
|
||||
// The wait cycles are not added unless the branch actually happens!
|
||||
cpu.setPageBoundaryPenalty((address & 0x00ff00) != (pc & 0x00ff00));
|
||||
return address;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getValue(boolean isRead) {
|
||||
public int getValue(boolean isRead, MOS65C02 cpu) {
|
||||
int pc = cpu.getProgramCounter();
|
||||
int address = getMemory().read(pc + 1, TYPE.READ_OPERAND, readAddressTriggersEvent, false);
|
||||
int address = getMemory().read(pc + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false);
|
||||
return getMemory().read(address, TYPE.READ_DATA, true, false);
|
||||
}
|
||||
});
|
||||
@ -434,8 +434,8 @@ public class MOS65C02 extends CPU {
|
||||
// }
|
||||
private AddressCalculator calculator;
|
||||
|
||||
public int calcAddress() {
|
||||
return calculator.calculateAddress();
|
||||
public int calcAddress(MOS65C02 cpu) {
|
||||
return calculator.calculateAddress(cpu);
|
||||
}
|
||||
private boolean indirect;
|
||||
|
||||
@ -493,7 +493,7 @@ public class MOS65C02 extends CPU {
|
||||
|
||||
private static interface CommandProcessor {
|
||||
|
||||
public void processCommand(int address, int value, MODE addressMode);
|
||||
public void processCommand(int address, int value, MODE addressMode, MOS65C02 cpu);
|
||||
}
|
||||
|
||||
private static class BBRCommand implements CommandProcessor {
|
||||
@ -505,7 +505,7 @@ public class MOS65C02 extends CPU {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCommand(int address, int value, MODE addressMode) {
|
||||
public void processCommand(int address, int value, MODE addressMode, MOS65C02 cpu) {
|
||||
if (((value >> bit) & 1) != 0) {
|
||||
return;
|
||||
}
|
||||
@ -525,7 +525,7 @@ public class MOS65C02 extends CPU {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCommand(int address, int value, MODE addressMode) {
|
||||
public void processCommand(int address, int value, MODE addressMode, MOS65C02 cpu) {
|
||||
if (((value >> bit) & 1) == 0) {
|
||||
return;
|
||||
}
|
||||
@ -545,7 +545,7 @@ public class MOS65C02 extends CPU {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCommand(int address, int value, MODE addressMode) {
|
||||
public void processCommand(int address, int value, MODE addressMode, MOS65C02 cpu) {
|
||||
int mask = 0x0ff ^ (1 << bit);
|
||||
value &= mask;
|
||||
getMemory().write(address, (byte) value, true, false);
|
||||
@ -561,16 +561,17 @@ public class MOS65C02 extends CPU {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processCommand(int address, int value, MODE addressMode) {
|
||||
public void processCommand(int address, int value, MODE addressMode, MOS65C02 cpu) {
|
||||
int mask = 1 << bit;
|
||||
value |= mask;
|
||||
getMemory().write(address, (byte) value, true, false);
|
||||
}
|
||||
}
|
||||
|
||||
private enum COMMAND {
|
||||
ADC((int address, int value, MODE addressMode) -> {
|
||||
int w = 0;
|
||||
public enum COMMAND {
|
||||
|
||||
ADC((address, value, addressMode, cpu) -> {
|
||||
int w;
|
||||
cpu.V = ((cpu.A ^ value) & 0x080) == 0;
|
||||
if (cpu.D) {
|
||||
// Decimal Mode
|
||||
@ -609,11 +610,11 @@ public class MOS65C02 extends CPU {
|
||||
cpu.A = w & 0x0ff;
|
||||
cpu.setNZ(cpu.A);
|
||||
}),
|
||||
AND((int address, int value, MODE addressMode) -> {
|
||||
AND((address, value, addressMode, cpu) -> {
|
||||
cpu.A &= value;
|
||||
cpu.setNZ(cpu.A);
|
||||
}),
|
||||
ASL((int address, int value, MODE addressMode) -> {
|
||||
ASL((address, value, addressMode, cpu) -> {
|
||||
cpu.C = ((value & 0x080) != 0) ? 1 : 0;
|
||||
value = 0x0FE & (value << 1);
|
||||
cpu.setNZ(value);
|
||||
@ -622,7 +623,7 @@ public class MOS65C02 extends CPU {
|
||||
getMemory().write(address, (byte) value, true, false);
|
||||
getMemory().write(address, (byte) value, true, false);
|
||||
}),
|
||||
ASL_A((int address, int value, MODE addressMode) -> {
|
||||
ASL_A((address, value, addressMode, cpu) -> {
|
||||
cpu.C = cpu.A >> 7;
|
||||
cpu.A = 0x0FE & (cpu.A << 1);
|
||||
cpu.setNZ(cpu.A);
|
||||
@ -643,25 +644,25 @@ public class MOS65C02 extends CPU {
|
||||
BBS5(new BBSCommand(5)),
|
||||
BBS6(new BBSCommand(6)),
|
||||
BBS7(new BBSCommand(7)),
|
||||
BCC((int address, int value, MODE addressMode) -> {
|
||||
BCC((address, value, addressMode, cpu) -> {
|
||||
if (cpu.C == 0) {
|
||||
cpu.setProgramCounter(address);
|
||||
cpu.addWaitCycles(cpu.pageBoundaryPenalty ? 2 : 1);
|
||||
}
|
||||
}),
|
||||
BCS((int address, int value, MODE addressMode) -> {
|
||||
BCS((address, value, addressMode, cpu) -> {
|
||||
if (cpu.C != 0) {
|
||||
cpu.setProgramCounter(address);
|
||||
cpu.addWaitCycles(cpu.pageBoundaryPenalty ? 2 : 1);
|
||||
}
|
||||
}),
|
||||
BEQ((int address, int value, MODE addressMode) -> {
|
||||
BEQ((address, value, addressMode, cpu) -> {
|
||||
if (cpu.Z) {
|
||||
cpu.setProgramCounter(address);
|
||||
cpu.addWaitCycles(cpu.pageBoundaryPenalty ? 2 : 1);
|
||||
}
|
||||
}),
|
||||
BIT((int address, int value, MODE addressMode) -> {
|
||||
BIT((address, value, addressMode, cpu) -> {
|
||||
int result = (cpu.A & value);
|
||||
cpu.Z = result == 0;
|
||||
cpu.N = (value & 0x080) != 0;
|
||||
@ -670,132 +671,132 @@ public class MOS65C02 extends CPU {
|
||||
cpu.V = (value & 0x040) != 0;
|
||||
}
|
||||
}),
|
||||
BMI((int address, int value, MODE addressMode) -> {
|
||||
BMI((address, value, addressMode, cpu) -> {
|
||||
if (cpu.N) {
|
||||
cpu.setProgramCounter(address);
|
||||
cpu.addWaitCycles(cpu.pageBoundaryPenalty ? 2 : 1);
|
||||
}
|
||||
}),
|
||||
BNE((int address, int value, MODE addressMode) -> {
|
||||
BNE((address, value, addressMode, cpu) -> {
|
||||
if (!cpu.Z) {
|
||||
cpu.setProgramCounter(address);
|
||||
cpu.addWaitCycles(cpu.pageBoundaryPenalty ? 2 : 1);
|
||||
}
|
||||
}),
|
||||
BPL((int address, int value, MODE addressMode) -> {
|
||||
BPL((address, value, addressMode, cpu) -> {
|
||||
if (!cpu.N) {
|
||||
cpu.setProgramCounter(address);
|
||||
cpu.addWaitCycles(cpu.pageBoundaryPenalty ? 2 : 1);
|
||||
}
|
||||
}),
|
||||
BRA((int address, int value, MODE addressMode) -> {
|
||||
BRA((address, value, addressMode, cpu) -> {
|
||||
cpu.setProgramCounter(address);
|
||||
cpu.addWaitCycles(cpu.pageBoundaryPenalty ? 1 : 0);
|
||||
}),
|
||||
BRK((int address, int value, MODE addressMode) -> {
|
||||
BRK((address, value, addressMode, cpu) -> {
|
||||
cpu.BRK();
|
||||
}),
|
||||
BVC((int address, int value, MODE addressMode) -> {
|
||||
BVC((address, value, addressMode, cpu) -> {
|
||||
if (!cpu.V) {
|
||||
cpu.setProgramCounter(address);
|
||||
cpu.addWaitCycles(cpu.pageBoundaryPenalty ? 2 : 1);
|
||||
}
|
||||
}),
|
||||
BVS((int address, int value, MODE addressMode) -> {
|
||||
BVS((address, value, addressMode, cpu) -> {
|
||||
if (cpu.V) {
|
||||
cpu.setProgramCounter(address);
|
||||
cpu.addWaitCycles(cpu.pageBoundaryPenalty ? 2 : 1);
|
||||
}
|
||||
}),
|
||||
CLC((int address, int value, MODE addressMode) -> {
|
||||
CLC((address, value, addressMode, cpu) -> {
|
||||
cpu.C = 0;
|
||||
}),
|
||||
CLD((int address, int value, MODE addressMode) -> {
|
||||
CLD((address, value, addressMode, cpu) -> {
|
||||
cpu.D = false;
|
||||
}),
|
||||
CLI((int address, int value, MODE addressMode) -> {
|
||||
CLI((address, value, addressMode, cpu) -> {
|
||||
cpu.I = false;
|
||||
cpu.interruptSignalled = false;
|
||||
}),
|
||||
CLV((int address, int value, MODE addressMode) -> {
|
||||
CLV((address, value, addressMode, cpu) -> {
|
||||
cpu.V = false;
|
||||
}),
|
||||
CMP((int address, int value, MODE addressMode) -> {
|
||||
CMP((address, value, addressMode, cpu) -> {
|
||||
int val = cpu.A - value;
|
||||
cpu.C = (val >= 0) ? 1 : 0;
|
||||
cpu.setNZ(val);
|
||||
}),
|
||||
CPX((int address, int value, MODE addressMode) -> {
|
||||
CPX((address, value, addressMode, cpu) -> {
|
||||
int val = cpu.X - value;
|
||||
cpu.C = (val >= 0) ? 1 : 0;
|
||||
cpu.setNZ(val);
|
||||
}),
|
||||
CPY((int address, int value, MODE addressMode) -> {
|
||||
CPY((address, value, addressMode, cpu) -> {
|
||||
int val = cpu.Y - value;
|
||||
cpu.C = (val >= 0) ? 1 : 0;
|
||||
cpu.setNZ(val);
|
||||
}),
|
||||
DEC((int address, int value, MODE addressMode) -> {
|
||||
DEC((address, value, addressMode, cpu) -> {
|
||||
value = 0x0FF & (value - 1);
|
||||
getMemory().write(address, (byte) value, true, false);
|
||||
getMemory().write(address, (byte) value, true, false);
|
||||
cpu.setNZ(value);
|
||||
}),
|
||||
DEA((int address, int value, MODE addressMode) -> {
|
||||
DEA((address, value, addressMode, cpu) -> {
|
||||
cpu.A = 0x0FF & (cpu.A - 1);
|
||||
cpu.setNZ(cpu.A);
|
||||
}),
|
||||
DEX((int address, int value, MODE addressMode) -> {
|
||||
DEX((address, value, addressMode, cpu) -> {
|
||||
cpu.X = 0x0FF & (cpu.X - 1);
|
||||
cpu.setNZ(cpu.X);
|
||||
}),
|
||||
DEY((int address, int value, MODE addressMode) -> {
|
||||
DEY((address, value, addressMode, cpu) -> {
|
||||
cpu.Y = 0x0FF & (cpu.Y - 1);
|
||||
cpu.setNZ(cpu.Y);
|
||||
}),
|
||||
EOR((int address, int value, MODE addressMode) -> {
|
||||
EOR((address, value, addressMode, cpu) -> {
|
||||
cpu.A = 0x0FF & (cpu.A ^ value);
|
||||
cpu.setNZ(cpu.A);
|
||||
}),
|
||||
INC((int address, int value, MODE addressMode) -> {
|
||||
INC((address, value, addressMode, cpu) -> {
|
||||
value = 0x0ff & (value + 1);
|
||||
// emulator correct fetch-modify-store behavior
|
||||
getMemory().write(address, (byte) value, true, false);
|
||||
getMemory().write(address, (byte) value, true, false);
|
||||
cpu.setNZ(value);
|
||||
}),
|
||||
INA((int address, int value, MODE addressMode) -> {
|
||||
INA((address, value, addressMode, cpu) -> {
|
||||
cpu.A = 0x0FF & (cpu.A + 1);
|
||||
cpu.setNZ(cpu.A);
|
||||
}),
|
||||
INX((int address, int value, MODE addressMode) -> {
|
||||
INX((address, value, addressMode, cpu) -> {
|
||||
cpu.X = 0x0FF & (cpu.X + 1);
|
||||
cpu.setNZ(cpu.X);
|
||||
}),
|
||||
INY((int address, int value, MODE addressMode) -> {
|
||||
INY((address, value, addressMode, cpu) -> {
|
||||
cpu.Y = 0x0FF & (cpu.Y + 1);
|
||||
cpu.setNZ(cpu.Y);
|
||||
}),
|
||||
JMP((int address, int value, MODE addressMode) -> {
|
||||
JMP((address, value, addressMode, cpu) -> {
|
||||
cpu.setProgramCounter(address);
|
||||
}),
|
||||
JSR((int address, int value, MODE addressMode) -> {
|
||||
JSR((address, value, addressMode, cpu) -> {
|
||||
cpu.pushWord(cpu.getProgramCounter() - 1);
|
||||
cpu.setProgramCounter(address);
|
||||
}),
|
||||
LDA((int address, int value, MODE addressMode) -> {
|
||||
LDA((address, value, addressMode, cpu) -> {
|
||||
cpu.A = value;
|
||||
cpu.setNZ(cpu.A);
|
||||
}),
|
||||
LDX((int address, int value, MODE addressMode) -> {
|
||||
LDX((address, value, addressMode, cpu) -> {
|
||||
cpu.X = value;
|
||||
cpu.setNZ(cpu.X);
|
||||
}),
|
||||
LDY((int address, int value, MODE addressMode) -> {
|
||||
LDY((address, value, addressMode, cpu) -> {
|
||||
cpu.Y = value;
|
||||
cpu.setNZ(cpu.Y);
|
||||
}),
|
||||
LSR((int address, int value, MODE addressMode) -> {
|
||||
LSR((address, value, addressMode, cpu) -> {
|
||||
cpu.C = (value & 1);
|
||||
value = (value >> 1) & 0x07F;
|
||||
cpu.setNZ(value);
|
||||
@ -803,40 +804,41 @@ public class MOS65C02 extends CPU {
|
||||
getMemory().write(address, (byte) value, true, false);
|
||||
getMemory().write(address, (byte) value, true, false);
|
||||
}),
|
||||
LSR_A((int address, int value, MODE addressMode) -> {
|
||||
LSR_A((address, value, addressMode, cpu) -> {
|
||||
cpu.C = cpu.A & 1;
|
||||
cpu.A = (cpu.A >> 1) & 0x07F;
|
||||
cpu.setNZ(cpu.A);
|
||||
}),
|
||||
NOP((int address, int value, MODE addressMode) -> {}),
|
||||
ORA((int address, int value, MODE addressMode) -> {
|
||||
NOP((address, value, addressMode, cpu) -> {
|
||||
}),
|
||||
ORA((address, value, addressMode, cpu) -> {
|
||||
cpu.A |= value;
|
||||
cpu.setNZ(cpu.A);
|
||||
}),
|
||||
PHA((int address, int value, MODE addressMode) -> {
|
||||
PHA((address, value, addressMode, cpu) -> {
|
||||
cpu.push((byte) cpu.A);
|
||||
}),
|
||||
PHP((int address, int value, MODE addressMode) -> {
|
||||
PHP((address, value, addressMode, cpu) -> {
|
||||
cpu.push((byte) (cpu.getStatus()));
|
||||
}),
|
||||
PHX((int address, int value, MODE addressMode) -> {
|
||||
PHX((address, value, addressMode, cpu) -> {
|
||||
cpu.push((byte) cpu.X);
|
||||
}),
|
||||
PHY((int address, int value, MODE addressMode) -> {
|
||||
PHY((address, value, addressMode, cpu) -> {
|
||||
cpu.push((byte) cpu.Y);
|
||||
}),
|
||||
PLA((int address, int value, MODE addressMode) -> {
|
||||
PLA((address, value, addressMode, cpu) -> {
|
||||
cpu.A = 0x0FF & cpu.pop();
|
||||
cpu.setNZ(cpu.A);
|
||||
}),
|
||||
PLP((int address, int value, MODE addressMode) -> {
|
||||
PLP((address, value, addressMode, cpu) -> {
|
||||
cpu.setStatus(cpu.pop());
|
||||
}),
|
||||
PLX((int address, int value, MODE addressMode) -> {
|
||||
PLX((address, value, addressMode, cpu) -> {
|
||||
cpu.X = 0x0FF & cpu.pop();
|
||||
cpu.setNZ(cpu.X);
|
||||
}),
|
||||
PLY((int address, int value, MODE addressMode) -> {
|
||||
PLY((address, value, addressMode, cpu) -> {
|
||||
cpu.Y = 0x0FF & cpu.pop();
|
||||
cpu.setNZ(cpu.Y);
|
||||
}),
|
||||
@ -848,7 +850,7 @@ public class MOS65C02 extends CPU {
|
||||
RMB5(new RMBCommand(5)),
|
||||
RMB6(new RMBCommand(6)),
|
||||
RMB7(new RMBCommand(7)),
|
||||
ROL((int address, int value, MODE addressMode) -> {
|
||||
ROL((address, value, addressMode, cpu) -> {
|
||||
int oldC = cpu.C;
|
||||
cpu.C = value >> 7;
|
||||
value = 0x0ff & ((value << 1) | oldC);
|
||||
@ -857,13 +859,13 @@ public class MOS65C02 extends CPU {
|
||||
getMemory().write(address, (byte) value, true, false);
|
||||
getMemory().write(address, (byte) value, true, false);
|
||||
}),
|
||||
ROL_A((int address, int value, MODE addressMode) -> {
|
||||
ROL_A((address, value, addressMode, cpu) -> {
|
||||
int oldC = cpu.C;
|
||||
cpu.C = cpu.A >> 7;
|
||||
cpu.A = 0x0ff & ((cpu.A << 1) | oldC);
|
||||
cpu.setNZ(cpu.A);
|
||||
}),
|
||||
ROR((int address, int value, MODE addressMode) -> {
|
||||
ROR((address, value, addressMode, cpu) -> {
|
||||
int oldC = cpu.C << 7;
|
||||
cpu.C = value & 1;
|
||||
value = 0x0ff & ((value >> 1) | oldC);
|
||||
@ -872,21 +874,21 @@ public class MOS65C02 extends CPU {
|
||||
getMemory().write(address, (byte) value, true, false);
|
||||
getMemory().write(address, (byte) value, true, false);
|
||||
}),
|
||||
ROR_A((int address, int value, MODE addressMode) -> {
|
||||
ROR_A((address, value, addressMode, cpu) -> {
|
||||
int oldC = cpu.C << 7;
|
||||
cpu.C = cpu.A & 1;
|
||||
cpu.A = 0x0ff & ((cpu.A >> 1) | oldC);
|
||||
cpu.setNZ(cpu.A);
|
||||
}),
|
||||
RTI((int address, int value, MODE addressMode) -> {
|
||||
RTI((address, value, addressMode, cpu) -> {
|
||||
cpu.returnFromInterrupt();
|
||||
}),
|
||||
RTS((int address, int value, MODE addressMode) -> {
|
||||
RTS((address, value, addressMode, cpu) -> {
|
||||
cpu.setProgramCounter(cpu.popWord() + 1);
|
||||
}),
|
||||
SBC((int address, int value, MODE addressMode) -> {
|
||||
SBC((address, value, addressMode, cpu) -> {
|
||||
cpu.V = ((cpu.A ^ value) & 0x080) != 0;
|
||||
int w = 0;
|
||||
int w;
|
||||
if (cpu.D) {
|
||||
int temp = 0x0f + (cpu.A & 0x0f) - (value & 0x0f) + cpu.C;
|
||||
if (temp < 0x10) {
|
||||
@ -927,13 +929,13 @@ public class MOS65C02 extends CPU {
|
||||
cpu.A = w & 0x0ff;
|
||||
cpu.setNZ(cpu.A);
|
||||
}),
|
||||
SEC((int address, int value, MODE addressMode) -> {
|
||||
SEC((address, value, addressMode, cpu) -> {
|
||||
cpu.C = 1;
|
||||
}),
|
||||
SED((int address, int value, MODE addressMode) -> {
|
||||
SED((address, value, addressMode, cpu) -> {
|
||||
cpu.D = true;
|
||||
}),
|
||||
SEI((int address, int value, MODE addressMode) -> {
|
||||
SEI((address, value, addressMode, cpu) -> {
|
||||
cpu.I = true;
|
||||
}),
|
||||
SMB0(new SMBCommand(0)),
|
||||
@ -944,55 +946,55 @@ public class MOS65C02 extends CPU {
|
||||
SMB5(new SMBCommand(5)),
|
||||
SMB6(new SMBCommand(6)),
|
||||
SMB7(new SMBCommand(7)),
|
||||
STA(true, (int address, int value, MODE addressMode) -> {
|
||||
STA(true, (address, value, addressMode, cpu) -> {
|
||||
getMemory().write(address, (byte) cpu.A, true, false);
|
||||
}),
|
||||
STP((int address, int value, MODE addressMode) -> {
|
||||
STP((address, value, addressMode, cpu) -> {
|
||||
cpu.suspend();
|
||||
}),
|
||||
STX(true, (int address, int value, MODE addressMode) -> {
|
||||
STX(true, (address, value, addressMode, cpu) -> {
|
||||
getMemory().write(address, (byte) cpu.X, true, false);
|
||||
}),
|
||||
STY(true, (int address, int value, MODE addressMode) -> {
|
||||
STY(true, (address, value, addressMode, cpu) -> {
|
||||
getMemory().write(address, (byte) cpu.Y, true, false);
|
||||
}),
|
||||
STZ(true, (int address, int value, MODE addressMode) -> {
|
||||
STZ(true, (address, value, addressMode, cpu) -> {
|
||||
getMemory().write(address, (byte) 0, true, false);
|
||||
}),
|
||||
TAX((int address, int value, MODE addressMode) -> {
|
||||
TAX((address, value, addressMode, cpu) -> {
|
||||
cpu.X = cpu.A;
|
||||
cpu.setNZ(cpu.X);
|
||||
}),
|
||||
TAY((int address, int value, MODE addressMode) -> {
|
||||
TAY((address, value, addressMode, cpu) -> {
|
||||
cpu.Y = cpu.A;
|
||||
cpu.setNZ(cpu.Y);
|
||||
}),
|
||||
TRB((int address, int value, MODE addressMode) -> {
|
||||
TRB((address, value, addressMode, cpu) -> {
|
||||
cpu.C = (value & cpu.A) != 0 ? 1 : 0;
|
||||
value &= ~cpu.A;
|
||||
getMemory().write(address, (byte) value, true, false);
|
||||
}),
|
||||
TSB((int address, int value, MODE addressMode) -> {
|
||||
TSB((address, value, addressMode, cpu) -> {
|
||||
cpu.C = (value & cpu.A) != 0 ? 1 : 0;
|
||||
value |= cpu.A;
|
||||
getMemory().write(address, (byte) value, true, false);
|
||||
}),
|
||||
TSX((int address, int value, MODE addressMode) -> {
|
||||
TSX((address, value, addressMode, cpu) -> {
|
||||
cpu.X = cpu.STACK;
|
||||
cpu.setNZ(cpu.STACK);
|
||||
}),
|
||||
TXA((int address, int value, MODE addressMode) -> {
|
||||
TXA((address, value, addressMode, cpu) -> {
|
||||
cpu.A = cpu.X;
|
||||
cpu.setNZ(cpu.X);
|
||||
}),
|
||||
TXS((int address, int value, MODE addressMode) -> {
|
||||
TXS((address, value, addressMode, cpu) -> {
|
||||
cpu.STACK = cpu.X;
|
||||
}),
|
||||
TYA((int address, int value, MODE addressMode) -> {
|
||||
TYA((address, value, addressMode, cpu) -> {
|
||||
cpu.A = cpu.Y;
|
||||
cpu.setNZ(cpu.Y);
|
||||
}),
|
||||
WAI((int address, int value, MODE addressMode) -> {
|
||||
WAI((address, value, addressMode, cpu) -> {
|
||||
cpu.waitForInterrupt();
|
||||
});
|
||||
private CommandProcessor processor;
|
||||
@ -1024,13 +1026,6 @@ public class MOS65C02 extends CPU {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance of MOS65C02
|
||||
*/
|
||||
public MOS65C02() {
|
||||
cpu = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void executeOpcode() {
|
||||
if (interruptSignalled) {
|
||||
@ -1046,10 +1041,10 @@ public class MOS65C02 extends CPU {
|
||||
if (isTraceEnabled() || isLogEnabled() || (warnAboutExtendedOpcodes && opcode != null && opcode.isExtendedOpcode)) {
|
||||
String t = getState().toUpperCase() + " " + Integer.toString(pc, 16) + " : " + disassemble();
|
||||
if (warnAboutExtendedOpcodes && opcode != null && opcode.isExtendedOpcode) {
|
||||
System.out.println(">>EXTENDED OPCODE DETECTED "+Integer.toHexString(opcode.code)+"<<");
|
||||
System.out.println(">>EXTENDED OPCODE DETECTED " + Integer.toHexString(opcode.code) + "<<");
|
||||
System.out.println(t);
|
||||
if (isLogEnabled()) {
|
||||
log(">>EXTENDED OPCODE DETECTED "+Integer.toHexString(opcode.code)+"<<");
|
||||
log(">>EXTENDED OPCODE DETECTED " + Integer.toHexString(opcode.code) + "<<");
|
||||
log(t);
|
||||
}
|
||||
} else {
|
||||
@ -1098,12 +1093,12 @@ public class MOS65C02 extends CPU {
|
||||
dumpTrace();
|
||||
}
|
||||
if (breakOnBadOpcode) {
|
||||
OPCODE.BRK.execute();
|
||||
OPCODE.BRK.execute(this);
|
||||
}
|
||||
} else {
|
||||
opcode.fetch();
|
||||
opcode.fetch(this);
|
||||
incrementProgramCounter(opcode.getMode().getSize());
|
||||
opcode.execute();
|
||||
opcode.execute(this);
|
||||
addWaitCycles(opcode.getWaitCycles());
|
||||
}
|
||||
}
|
||||
@ -1206,6 +1201,7 @@ public class MOS65C02 extends CPU {
|
||||
}
|
||||
|
||||
// Cold/Warm boot procedure
|
||||
@Override
|
||||
public void reset() {
|
||||
boolean restart = Computer.pause();
|
||||
pushWord(getProgramCounter());
|
||||
@ -1227,6 +1223,7 @@ public class MOS65C02 extends CPU {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getDeviceName() {
|
||||
return "65C02 Processor";
|
||||
}
|
||||
@ -1259,7 +1256,7 @@ public class MOS65C02 extends CPU {
|
||||
out.append(byte2(X)).append(" ");
|
||||
out.append(byte2(Y)).append(" ");
|
||||
// out += "PC:"+wordString(getProgramCounter())+" ";
|
||||
out.append("01").append(byte2(STACK)). append(" ");
|
||||
out.append("01").append(byte2(STACK)).append(" ");
|
||||
out.append(getFlags());
|
||||
return out.toString();
|
||||
}
|
||||
@ -1308,6 +1305,6 @@ public class MOS65C02 extends CPU {
|
||||
|
||||
@Override
|
||||
public void pushPC() {
|
||||
cpu.pushWord(cpu.getProgramCounter() - 1);
|
||||
pushWord(getProgramCounter() - 1);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user