forked from Apple-2-Tools/jace
Added profiler and 6502 timings switch -- it's not correct and needs a full junit test suite to prove out.
This commit is contained in:
parent
af1bdb6b35
commit
dd6b2b8566
@ -24,6 +24,8 @@ import jace.core.Computer;
|
||||
import jace.core.RAM;
|
||||
import jace.core.RAMEvent.TYPE;
|
||||
import jace.state.Stateful;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
@ -37,6 +39,7 @@ import java.util.logging.Logger;
|
||||
*/
|
||||
@Stateful
|
||||
public class MOS65C02 extends CPU {
|
||||
|
||||
private static final Logger LOG = Logger.getLogger(MOS65C02.class.getName());
|
||||
|
||||
public boolean readAddressTriggersEvent = true;
|
||||
@ -83,30 +86,32 @@ public class MOS65C02 extends CPU {
|
||||
public void reconfigure() {
|
||||
}
|
||||
|
||||
public static final boolean USE_6502_TIMINGS = true;
|
||||
|
||||
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),
|
||||
ADC_AB(0x006D, COMMAND.ADC, MODE.ABSOLUTE, 4),
|
||||
ADC_IND_ZP(0x0072, COMMAND.ADC, MODE.INDIRECT_ZP, 5, true),
|
||||
ADC_IND_ZP_X(0x0061, COMMAND.ADC, MODE.INDIRECT_ZP_X, 6),
|
||||
ADC_AB_X(0x007D, COMMAND.ADC, MODE.ABSOLUTE_X, 4),
|
||||
ADC_AB_Y(0x0079, COMMAND.ADC, MODE.ABSOLUTE_Y, 4),
|
||||
ADC_IND_ZP(0x0072, COMMAND.ADC, MODE.INDIRECT_ZP, 5, true),
|
||||
ADC_IND_ZP_X(0x0061, COMMAND.ADC, MODE.INDIRECT_ZP_X, 6),
|
||||
ADC_IND_ZP_Y(0x0071, COMMAND.ADC, MODE.INDIRECT_ZP_Y, 5),
|
||||
AND_IMM(0x0029, COMMAND.AND, MODE.IMMEDIATE, 2),
|
||||
AND_ZP(0x0025, COMMAND.AND, MODE.ZEROPAGE, 3),
|
||||
AND_ZP_X(0x0035, COMMAND.AND, MODE.ZEROPAGE_X, 4),
|
||||
AND_AB(0x002D, COMMAND.AND, MODE.ABSOLUTE, 4),
|
||||
AND_IND_ZP(0x0032, COMMAND.AND, MODE.INDIRECT_ZP, 5, true),
|
||||
AND_IND_ZP_X(0x0021, COMMAND.AND, MODE.INDIRECT_ZP_X, 6),
|
||||
AND_AB_X(0x003D, COMMAND.AND, MODE.ABSOLUTE_X, 4),
|
||||
AND_AB_Y(0x0039, COMMAND.AND, MODE.ABSOLUTE_Y, 4),
|
||||
AND_IND_ZP(0x0032, COMMAND.AND, MODE.INDIRECT_ZP, 5, true),
|
||||
AND_IND_ZP_X(0x0021, COMMAND.AND, MODE.INDIRECT_ZP_X, 6),
|
||||
AND_IND_ZP_Y(0x0031, COMMAND.AND, MODE.INDIRECT_ZP_Y, 5),
|
||||
ASL(0x000A, COMMAND.ASL_A, MODE.IMPLIED, 2),
|
||||
ASL_ZP(0x0006, COMMAND.ASL, MODE.ZEROPAGE, 5),
|
||||
ASL_ZP_X(0x0016, COMMAND.ASL, MODE.ZEROPAGE_X, 6),
|
||||
ASL_AB(0x000E, COMMAND.ASL, MODE.ABSOLUTE, 6),
|
||||
ASL_AB_X(0x001E, COMMAND.ASL, MODE.ABSOLUTE_X, 7),
|
||||
ASL_AB_X(0x001E, COMMAND.ASL, MODE.ABSOLUTE_X, USE_6502_TIMINGS ? 7 : 6),
|
||||
BCC_REL(0x0090, COMMAND.BCC, MODE.RELATIVE, 2),
|
||||
BCS_REL(0x00B0, COMMAND.BCS, MODE.RELATIVE, 2),
|
||||
BBR0(0x00f, COMMAND.BBR0, MODE.ZP_REL, 5, true),
|
||||
@ -125,16 +130,16 @@ public class MOS65C02 extends CPU {
|
||||
BBS5(0x0df, COMMAND.BBS5, MODE.ZP_REL, 5, true),
|
||||
BBS6(0x0ef, COMMAND.BBS6, MODE.ZP_REL, 5, true),
|
||||
BBS7(0x0ff, COMMAND.BBS7, MODE.ZP_REL, 5, true),
|
||||
BEQ_REL0(0x00F0, COMMAND.BEQ, MODE.RELATIVE, 2),
|
||||
BEQ_REL(0x00F0, COMMAND.BEQ, MODE.RELATIVE, 2),
|
||||
BIT_IMM(0x0089, COMMAND.BIT, MODE.IMMEDIATE, 3, true),
|
||||
BIT_ZP(0x0024, COMMAND.BIT, MODE.ZEROPAGE, 3),
|
||||
BIT_ZP_X(0x0034, COMMAND.BIT, MODE.ZEROPAGE_X, 3, true),
|
||||
BIT_ZP_X(0x0034, COMMAND.BIT, MODE.ZEROPAGE_X, 4, true),
|
||||
BIT_AB(0x002C, COMMAND.BIT, MODE.ABSOLUTE, 4),
|
||||
BIT_AB_X(0x003C, COMMAND.BIT, MODE.ABSOLUTE_X, 4, true),
|
||||
BMI_REL(0x0030, COMMAND.BMI, MODE.RELATIVE, 2),
|
||||
BNE_REL(0x00D0, COMMAND.BNE, MODE.RELATIVE, 2),
|
||||
BPL_REL(0x0010, COMMAND.BPL, MODE.RELATIVE, 2),
|
||||
BRA_REL(0x0080, COMMAND.BRA, MODE.RELATIVE, 2, true),
|
||||
BPL_REL(0x0010, COMMAND.BPL, MODE.RELATIVE, 2), //?
|
||||
BRA_REL(0x0080, COMMAND.BRA, MODE.RELATIVE, 2),
|
||||
// BRK(0x0000, COMMAND.BRK, MODE.IMPLIED, 7),
|
||||
// Do this so that BRK is treated as a two-byte instruction
|
||||
BRK(0x0000, COMMAND.BRK, MODE.IMMEDIATE, 7),
|
||||
@ -160,10 +165,10 @@ public class MOS65C02 extends CPU {
|
||||
CPY_ZP(0x00C4, COMMAND.CPY, MODE.ZEROPAGE, 3),
|
||||
CPY_AB(0x00CC, COMMAND.CPY, MODE.ABSOLUTE, 4),
|
||||
DEC(0x003A, COMMAND.DEA, MODE.IMPLIED, 2, true),
|
||||
DEC_ZP(0x00C6, COMMAND.DEC, MODE.ZEROPAGE, 5),
|
||||
DEC_ZP(0x00C6, COMMAND.DEC, MODE.ZEROPAGE, 5), // ??
|
||||
DEC_ZP_X(0x00D6, COMMAND.DEC, MODE.ZEROPAGE_X, 6),
|
||||
DEC_AB(0x00CE, COMMAND.DEC, MODE.ABSOLUTE, 6),
|
||||
DEC_AB_X(0x00DE, COMMAND.DEC, MODE.ABSOLUTE_X, 7),
|
||||
DEC_AB_X(0x00DE, COMMAND.DEC, MODE.ABSOLUTE_X_NODELAY, 7),
|
||||
DEX(0x00CA, COMMAND.DEX, MODE.IMPLIED, 2),
|
||||
DEY(0x0088, COMMAND.DEY, MODE.IMPLIED, 2),
|
||||
EOR_IMM(0x0049, COMMAND.EOR, MODE.IMMEDIATE, 2),
|
||||
@ -179,11 +184,11 @@ public class MOS65C02 extends CPU {
|
||||
INC_ZP(0x00E6, COMMAND.INC, MODE.ZEROPAGE, 5),
|
||||
INC_ZP_X(0x00F6, COMMAND.INC, MODE.ZEROPAGE_X, 6),
|
||||
INC_AB(0x00EE, COMMAND.INC, MODE.ABSOLUTE, 6),
|
||||
INC_AB_X(0x00FE, COMMAND.INC, MODE.ABSOLUTE_X, 7),
|
||||
INC_AB_X(0x00FE, COMMAND.INC, MODE.ABSOLUTE_X_NODELAY, 7),
|
||||
INX(0x00E8, COMMAND.INX, MODE.IMPLIED, 2),
|
||||
INY(0x00C8, COMMAND.INY, MODE.IMPLIED, 2),
|
||||
JMP_AB(0x004C, COMMAND.JMP, MODE.ABSOLUTE, 3, false, false),
|
||||
JMP_IND(0x006C, COMMAND.JMP, MODE.INDIRECT, 5),
|
||||
JMP_AB(0x004C, COMMAND.JMP, MODE.ABSOLUTE, 3, false, false), // ??
|
||||
JMP_IND(0x006C, COMMAND.JMP, MODE.INDIRECT, 6),
|
||||
JMP_IND_X(0x007C, COMMAND.JMP, MODE.INDIRECT_X, 6, true),
|
||||
JSR_AB(0x0020, COMMAND.JSR, MODE.ABSOLUTE, 6, false, false),
|
||||
LDA_IMM(0x00A9, COMMAND.LDA, MODE.IMMEDIATE, 2),
|
||||
@ -191,7 +196,7 @@ public class MOS65C02 extends CPU {
|
||||
LDA_ZP_X(0x00B5, COMMAND.LDA, MODE.ZEROPAGE_X, 4),
|
||||
LDA_AB(0x00AD, COMMAND.LDA, MODE.ABSOLUTE, 4),
|
||||
LDA_IND_ZP_X(0x00A1, COMMAND.LDA, MODE.INDIRECT_ZP_X, 6),
|
||||
LDA_AB_X(0x00BD, COMMAND.LDA, MODE.ABSOLUTE_X, 4),
|
||||
LDA_AB_X(0x00BD, COMMAND.LDA, MODE.ABSOLUTE_X, 4, true), //?
|
||||
LDA_AB_Y(0x00B9, COMMAND.LDA, MODE.ABSOLUTE_Y, 4),
|
||||
LDA_IND_ZP_Y(0x00B1, COMMAND.LDA, MODE.INDIRECT_ZP_Y, 5),
|
||||
LDA_IND_ZP(0x00B2, COMMAND.LDA, MODE.INDIRECT_ZP, 5, true),
|
||||
@ -209,7 +214,7 @@ public class MOS65C02 extends CPU {
|
||||
LSR_ZP(0x0046, COMMAND.LSR, MODE.ZEROPAGE, 5),
|
||||
LSR_ZP_X(0x0056, COMMAND.LSR, MODE.ZEROPAGE_X, 6),
|
||||
LSR_AB(0x004E, COMMAND.LSR, MODE.ABSOLUTE, 6),
|
||||
LSR_AB_X(0x005E, COMMAND.LSR, MODE.ABSOLUTE_X, 7),
|
||||
LSR_AB_X(0x005E, COMMAND.LSR, MODE.ABSOLUTE_X, USE_6502_TIMINGS ? 7 : 6),
|
||||
NOP(0x00EA, COMMAND.NOP, MODE.IMPLIED, 2),
|
||||
SPECIAL(0x00FC, COMMAND.NOP_SPECIAL, MODE.ABSOLUTE, 4),
|
||||
ORA_IMM(0x0009, COMMAND.ORA, MODE.IMMEDIATE, 2),
|
||||
@ -241,22 +246,22 @@ public class MOS65C02 extends CPU {
|
||||
ROL_ZP(0x0026, COMMAND.ROL, MODE.ZEROPAGE, 5),
|
||||
ROL_ZP_X(0x0036, COMMAND.ROL, MODE.ZEROPAGE_X, 6),
|
||||
ROL_AB(0x002E, COMMAND.ROL, MODE.ABSOLUTE, 6),
|
||||
ROL_AB_X(0x003E, COMMAND.ROL, MODE.ABSOLUTE_X, 7),
|
||||
ROL_AB_X(0x003E, COMMAND.ROL, USE_6502_TIMINGS ? MODE.ABSOLUTE_X_NODELAY : MODE.ABSOLUTE_X, USE_6502_TIMINGS ? 7 : 6),
|
||||
ROR(0x006A, COMMAND.ROR_A, MODE.IMPLIED, 2),
|
||||
ROR_ZP(0x0066, COMMAND.ROR, MODE.ZEROPAGE, 5),
|
||||
ROR_ZP_X(0x0076, COMMAND.ROR, MODE.ZEROPAGE_X, 6),
|
||||
ROR_AB(0x006E, COMMAND.ROR, MODE.ABSOLUTE, 6),
|
||||
ROR_AB_X(0x007E, COMMAND.ROR, MODE.ABSOLUTE_X, 7),
|
||||
ROR_AB_X(0x007E, COMMAND.ROR, USE_6502_TIMINGS ? MODE.ABSOLUTE_X_NODELAY : MODE.ABSOLUTE_X, USE_6502_TIMINGS ? 7 : 6),
|
||||
RTI(0x0040, COMMAND.RTI, MODE.IMPLIED, 6),
|
||||
RTS(0x0060, COMMAND.RTS, MODE.IMPLIED, 6),
|
||||
SBC_IMM(0x00E9, COMMAND.SBC, MODE.IMMEDIATE, 2),
|
||||
SBC_ZP(0x00E5, COMMAND.SBC, MODE.ZEROPAGE, 3),
|
||||
SBC_ZP_X(0x00F5, COMMAND.SBC, MODE.ZEROPAGE_X, 4),
|
||||
SBC_AB(0x00ED, COMMAND.SBC, MODE.ABSOLUTE, 4),
|
||||
SBC_IND_ZP(0x00F2, COMMAND.SBC, MODE.INDIRECT_ZP, 5, true),
|
||||
SBC_IND_ZP_X(0x00E1, COMMAND.SBC, MODE.INDIRECT_ZP_X, 6),
|
||||
SBC_AB_X(0x00FD, COMMAND.SBC, MODE.ABSOLUTE_X, 4),
|
||||
SBC_AB_Y(0x00F9, COMMAND.SBC, MODE.ABSOLUTE_Y, 4),
|
||||
SBC_IND_ZP(0x00F2, COMMAND.SBC, MODE.INDIRECT_ZP, 5, true),
|
||||
SBC_IND_ZP_X(0x00E1, COMMAND.SBC, MODE.INDIRECT_ZP_X, 6),
|
||||
SBC_IND_ZP_Y(0x00F1, COMMAND.SBC, MODE.INDIRECT_ZP_Y, 5),
|
||||
SEC(0x0038, COMMAND.SEC, MODE.IMPLIED, 2),
|
||||
SED(0x00F8, COMMAND.SED, MODE.IMPLIED, 2),
|
||||
@ -270,13 +275,13 @@ public class MOS65C02 extends CPU {
|
||||
SMB6(0x0e7, COMMAND.SMB6, MODE.ZEROPAGE, 5, true),
|
||||
SMB7(0x0f7, COMMAND.SMB7, MODE.ZEROPAGE, 5, true),
|
||||
STA_ZP(0x0085, COMMAND.STA, MODE.ZEROPAGE, 3),
|
||||
STA_ZP_X(0x0095, COMMAND.STA, MODE.ZEROPAGE_X, 4),
|
||||
STA_ZP_X(0x0095, COMMAND.STA, MODE.ZEROPAGE_X, 4), // ??
|
||||
STA_AB(0x008D, COMMAND.STA, MODE.ABSOLUTE, 4),
|
||||
STA_AB_X(0x009D, COMMAND.STA, MODE.ABSOLUTE_X, 5),
|
||||
STA_AB_Y(0x0099, COMMAND.STA, MODE.ABSOLUTE_Y, 5),
|
||||
STA_AB_X(0x009D, COMMAND.STA, MODE.ABSOLUTE_X_NODELAY, 5),
|
||||
STA_AB_Y(0x0099, COMMAND.STA, MODE.ABSOLUTE_Y_NODELAY, 5),
|
||||
STA_IND_ZP(0x0092, COMMAND.STA, MODE.INDIRECT_ZP, 5, true),
|
||||
STA_IND_ZP_X(0x0081, COMMAND.STA, MODE.INDIRECT_ZP_X, 6),
|
||||
STA_IND_ZP_Y(0x0091, COMMAND.STA, MODE.INDIRECT_ZP_Y, 6),
|
||||
STA_IND_ZP_Y(0x0091, COMMAND.STA, MODE.INDIRECT_ZP_Y_NODELAY, 6),
|
||||
STP(0x00DB, COMMAND.STP, MODE.IMPLIED, 3, true),
|
||||
STX_ZP(0x0086, COMMAND.STX, MODE.ZEROPAGE, 3),
|
||||
STX_ZP_Y(0x0096, COMMAND.STX, MODE.ZEROPAGE_Y, 4),
|
||||
@ -288,7 +293,7 @@ public class MOS65C02 extends CPU {
|
||||
STZ_ZP_X(0x0074, COMMAND.STZ, MODE.ZEROPAGE_X, 4, true),
|
||||
STZ_AB(0x009C, COMMAND.STZ, MODE.ABSOLUTE, 4, true),
|
||||
STZ_AB_X(0x009E, COMMAND.STZ, MODE.ABSOLUTE_X, 5, true),
|
||||
TAX(0x00AA, COMMAND.TAX, MODE.IMPLIED, 2),
|
||||
TAX(0x00AA, COMMAND.TAX, MODE.IMPLIED, 2), // ??
|
||||
TAY(0x00A8, COMMAND.TAY, MODE.IMPLIED, 2),
|
||||
TRB_ZP(0x0014, COMMAND.TRB, MODE.ZEROPAGE, 5, true),
|
||||
TRB_AB(0x001C, COMMAND.TRB, MODE.ABSOLUTE, 6, true),
|
||||
@ -401,6 +406,12 @@ public class MOS65C02 extends CPU {
|
||||
}
|
||||
return address2;
|
||||
}),
|
||||
INDIRECT_ZP_Y_NODELAY(2, "$(~1),Y", (cpu) -> {
|
||||
int address = 0x00FF & cpu.getMemory().read(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false);
|
||||
address = cpu.getMemory().readWord(address, TYPE.READ_DATA, true, false);
|
||||
int address2 = address + cpu.Y;
|
||||
return address2;
|
||||
}),
|
||||
ABSOLUTE(3, "$~2~1", (cpu) -> cpu.getMemory().readWord(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false)),
|
||||
ABSOLUTE_X(3, "$~2~1,X", (cpu) -> {
|
||||
int address2 = cpu.getMemory().readWord(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false);
|
||||
@ -410,6 +421,11 @@ public class MOS65C02 extends CPU {
|
||||
}
|
||||
return address;
|
||||
}),
|
||||
ABSOLUTE_X_NODELAY(3, "$~2~1,X", (cpu) -> {
|
||||
int address2 = cpu.getMemory().readWord(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false);
|
||||
int address = 0x0FFFF & (address2 + cpu.X);
|
||||
return address;
|
||||
}),
|
||||
ABSOLUTE_Y(3, "$~2~1,Y", (cpu) -> {
|
||||
int address2 = cpu.getMemory().readWord(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false);
|
||||
int address = 0x0FFFF & (address2 + cpu.Y);
|
||||
@ -418,6 +434,11 @@ public class MOS65C02 extends CPU {
|
||||
}
|
||||
return address;
|
||||
}),
|
||||
ABSOLUTE_Y_NODELAY(3, "$~2~1,Y", (cpu) -> {
|
||||
int address2 = cpu.getMemory().readWord(cpu.getProgramCounter() + 1, TYPE.READ_OPERAND, cpu.readAddressTriggersEvent, false);
|
||||
int address = 0x0FFFF & (address2 + cpu.Y);
|
||||
return address;
|
||||
}),
|
||||
ZP_REL(2, "$~1,$R", new AddressCalculator() {
|
||||
@Override
|
||||
public int calculateAddress(MOS65C02 cpu) {
|
||||
@ -466,6 +487,7 @@ public class MOS65C02 extends CPU {
|
||||
private MODE(int size, String fmt, AddressCalculator calc) {
|
||||
this(size, fmt, calc, true);
|
||||
}
|
||||
|
||||
private MODE(int size, String fmt, AddressCalculator calc, boolean fetch) {
|
||||
this.fetchValue = fetch;
|
||||
this.size = size;
|
||||
@ -590,6 +612,7 @@ public class MOS65C02 extends CPU {
|
||||
int w;
|
||||
cpu.V = ((cpu.A ^ value) & 0x080) == 0;
|
||||
if (cpu.D) {
|
||||
cpu.addWaitCycles(1);
|
||||
// Decimal Mode
|
||||
w = (cpu.A & 0x0f) + (value & 0x0f) + cpu.C;
|
||||
if (w >= 10) {
|
||||
@ -707,7 +730,7 @@ public class MOS65C02 extends CPU {
|
||||
}),
|
||||
BRA((address, value, addressMode, cpu) -> {
|
||||
cpu.setProgramCounter(address);
|
||||
cpu.addWaitCycles(cpu.pageBoundaryPenalty ? 1 : 0);
|
||||
cpu.addWaitCycles(cpu.pageBoundaryPenalty ? 2 : 1);
|
||||
}),
|
||||
BRK((address, value, addressMode, cpu) -> {
|
||||
cpu.BRK();
|
||||
@ -910,6 +933,7 @@ public class MOS65C02 extends CPU {
|
||||
cpu.V = ((cpu.A ^ value) & 0x080) != 0;
|
||||
int w;
|
||||
if (cpu.D) {
|
||||
cpu.addWaitCycles(1);
|
||||
int temp = 0x0f + (cpu.A & 0x0f) - (value & 0x0f) + cpu.C;
|
||||
if (temp < 0x10) {
|
||||
w = 0;
|
||||
@ -1044,6 +1068,54 @@ public class MOS65C02 extends CPU {
|
||||
}
|
||||
}
|
||||
|
||||
Map<OPCODE, Map<Integer, Integer>> histogram = null;
|
||||
int ellapsedSeconds = 0;
|
||||
long startTime = System.currentTimeMillis();
|
||||
long nextInterval = System.currentTimeMillis() + 1000;
|
||||
|
||||
private void addToHistogram(OPCODE o) {
|
||||
if (histogram == null) {
|
||||
return;
|
||||
}
|
||||
long now = System.currentTimeMillis();
|
||||
if (now >= nextInterval) {
|
||||
ellapsedSeconds = (int) ((now - startTime) / 1000);
|
||||
nextInterval = ellapsedSeconds * 1000 + startTime;
|
||||
}
|
||||
Map<Integer, Integer> countPerTimestamp = histogram.get(o);
|
||||
if (countPerTimestamp == null) {
|
||||
countPerTimestamp = new HashMap<>();
|
||||
histogram.put(o, countPerTimestamp);
|
||||
}
|
||||
Integer count = countPerTimestamp.get(ellapsedSeconds);
|
||||
if (count == null) {
|
||||
count = 0;
|
||||
}
|
||||
countPerTimestamp.put(ellapsedSeconds, count+1);
|
||||
}
|
||||
|
||||
private void dumpHistogram(Map<OPCODE, Map<Integer, Integer>> histogram) {
|
||||
System.out.println("\nOpcode");
|
||||
for (int i = 0; i <= ellapsedSeconds; i++) {
|
||||
System.out.print("\t");
|
||||
System.out.print(i);
|
||||
}
|
||||
System.out.println();
|
||||
for (OPCODE o : histogram.keySet()) {
|
||||
System.out.print(o.name());
|
||||
Map<Integer, Integer> countPerTimestamp = histogram.get(o);
|
||||
for (int i = 0; i <= ellapsedSeconds; i++) {
|
||||
Integer count = countPerTimestamp.get(i);
|
||||
if (count == null) {
|
||||
count = 0;
|
||||
}
|
||||
System.out.print("\t");
|
||||
System.out.print(count);
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void executeOpcode() {
|
||||
if (interruptSignalled) {
|
||||
@ -1065,6 +1137,7 @@ public class MOS65C02 extends CPU {
|
||||
// This makes it possible to trap the memory read of an opcode, when PC == Address, you know it is executing that opcode.
|
||||
int op = 0x00ff & getMemory().read(pc, TYPE.EXECUTE, true, false);
|
||||
OPCODE opcode = opcodes[op];
|
||||
addToHistogram(opcode);
|
||||
if (traceEntry != null && warnAboutExtendedOpcodes && opcode != null && opcode.isExtendedOpcode) {
|
||||
LOG.log(Level.WARNING, ">>EXTENDED OPCODE DETECTED {0}<<", Integer.toHexString(opcode.code));
|
||||
LOG.log(Level.WARNING, traceEntry);
|
||||
@ -1072,7 +1145,7 @@ public class MOS65C02 extends CPU {
|
||||
log(">>EXTENDED OPCODE DETECTED " + Integer.toHexString(opcode.code) + "<<");
|
||||
log(traceEntry);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (opcode == null) {
|
||||
// handle bad opcode as a NOP
|
||||
int wait = 0;
|
||||
@ -1095,14 +1168,16 @@ public class MOS65C02 extends CPU {
|
||||
wait = 3;
|
||||
} else {
|
||||
wait = 4;
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
case 0x0c:
|
||||
bytes = 3;
|
||||
if ((op & 0x0f0) == 0x050) {
|
||||
wait = 8;
|
||||
} else {
|
||||
wait = 4;
|
||||
} break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
}
|
||||
incrementProgramCounter(bytes);
|
||||
@ -1180,8 +1255,8 @@ public class MOS65C02 extends CPU {
|
||||
|
||||
@Override
|
||||
public void JSR(int address) {
|
||||
pushPC();
|
||||
setProgramCounter(address);
|
||||
pushPC();
|
||||
setProgramCounter(address);
|
||||
}
|
||||
|
||||
public void BRK() {
|
||||
@ -1226,6 +1301,14 @@ public class MOS65C02 extends CPU {
|
||||
// Cold/Warm boot procedure
|
||||
@Override
|
||||
public void reset() {
|
||||
if (histogram != null) {
|
||||
Map<OPCODE, Map<Integer, Integer>> oldHistogram = histogram;
|
||||
histogram = null;
|
||||
dumpHistogram(oldHistogram);
|
||||
}
|
||||
startTime = System.currentTimeMillis();
|
||||
ellapsedSeconds = 0;
|
||||
histogram = new HashMap<>();
|
||||
pushWord(getProgramCounter());
|
||||
push(getStatus());
|
||||
// STACK = 0x0ff;
|
||||
@ -1328,11 +1411,12 @@ public class MOS65C02 extends CPU {
|
||||
}
|
||||
|
||||
/**
|
||||
* Special commands -- these are usually treated as NOP but can be reused for emulator controls
|
||||
* !byte $fc, $65, $00 ; Turn off tracing
|
||||
* !byte $fc, $65, $01 ; Turn on tracing
|
||||
* Special commands -- these are usually treated as NOP but can be reused
|
||||
* for emulator controls !byte $fc, $65, $00 ; Turn off tracing !byte $fc,
|
||||
* $65, $01 ; Turn on tracing
|
||||
*
|
||||
* @param param1
|
||||
* @param param2
|
||||
* @param param2
|
||||
*/
|
||||
public void performExtendedCommand(byte param1, byte param2) {
|
||||
LOG.log(Level.INFO, "Extended command {0},{1}", new Object[]{Integer.toHexString(param1), Integer.toHexString(param2)});
|
||||
|
Loading…
x
Reference in New Issue
Block a user