mirror of
https://github.com/sethm/symon.git
synced 2025-04-14 21:37:21 +00:00
Process Status Register bits have been added.
This commit is contained in:
parent
7e36444193
commit
59e5572039
@ -1,5 +1,7 @@
|
||||
package com.loomcom.lm6502;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Main 6502 CPU Simulation.
|
||||
*/
|
||||
@ -22,12 +24,20 @@ public class Cpu implements InstructionTable {
|
||||
private int[] operands = new int[2];
|
||||
private int addr; // The address the most recent instruction
|
||||
// was fetched from
|
||||
|
||||
/* Status Flag Register bits */
|
||||
private boolean carryFlag;
|
||||
private boolean zeroFlag;
|
||||
private boolean irqDisableFlag;
|
||||
private boolean decimalModeFlag;
|
||||
private boolean breakFlag;
|
||||
private boolean overflowFlag;
|
||||
// Note: Zero Flag and Negative Flag are read directly from Accumulator.
|
||||
|
||||
/**
|
||||
* Construct a new CPU.
|
||||
*/
|
||||
public Cpu() {
|
||||
}
|
||||
public Cpu() {}
|
||||
|
||||
/**
|
||||
* Set the bus reference for this CPU.
|
||||
@ -55,6 +65,13 @@ public class Cpu implements InstructionTable {
|
||||
|
||||
// Clear instruction register.
|
||||
ir = 0;
|
||||
|
||||
// Clear status register bits.
|
||||
carryFlag = false;
|
||||
irqDisableFlag = false;
|
||||
decimalModeFlag = false;
|
||||
breakFlag = false;
|
||||
overflowFlag = false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -622,6 +639,113 @@ public class Cpu implements InstructionTable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the negative flag
|
||||
*/
|
||||
public boolean getNegativeFlag() {
|
||||
// True if the most significant bit is '1'
|
||||
return ((a>>>7)&0xff) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the carry flag
|
||||
*/
|
||||
public boolean getCarryFlag() {
|
||||
return carryFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param carryFlag the carry flag to set
|
||||
*/
|
||||
public void setCarryFlag(boolean carryFlag) {
|
||||
this.carryFlag = carryFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the zero flag
|
||||
*/
|
||||
public boolean getZeroFlag() {
|
||||
return zeroFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param zeroFlag the zero flag to set
|
||||
*/
|
||||
public void setZeroFlag(boolean zeroFlag) {
|
||||
this.zeroFlag = zeroFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the irq disable flag
|
||||
*/
|
||||
public boolean getIrqDisableFlag() {
|
||||
return irqDisableFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param irqDisableFlag the irq disable flag to set
|
||||
*/
|
||||
public void setIrqDisableFlag(boolean irqDisableFlag) {
|
||||
this.irqDisableFlag = irqDisableFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the decimal mode flag
|
||||
*/
|
||||
public boolean getDecimalModeFlag() {
|
||||
return decimalModeFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param decimalModeFlag the decimal mde flag to set
|
||||
*/
|
||||
public void setDecimalModeFlag(boolean decimalModeFlag) {
|
||||
this.decimalModeFlag = decimalModeFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the break flag
|
||||
*/
|
||||
public boolean getBreakFlag() {
|
||||
return breakFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param breakFlag the break flag to set
|
||||
*/
|
||||
public void setBreakFlag(boolean breakFlag) {
|
||||
this.breakFlag = breakFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the overflow flag
|
||||
*/
|
||||
public boolean getOverflowFlag() {
|
||||
return overflowFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param overflowFlag the overflow flag to set
|
||||
*/
|
||||
public void setOverflowFlag(boolean overflowFlag) {
|
||||
this.overflowFlag = overflowFlag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A string representing the current status register state.
|
||||
*/
|
||||
public String statusRegisterString() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append("(N:" + (getNegativeFlag() ? '1' : '0') + ", ");
|
||||
sb.append("V:" + (getOverflowFlag() ? '1' : '0') + ", ");
|
||||
sb.append("B:" + (getBreakFlag() ? '1' : '0') + ", ");
|
||||
sb.append("D:" + (getDecimalModeFlag() ? '1' : '0') + ", ");
|
||||
sb.append("I:" + (getIrqDisableFlag() ? '1' : '0') + ", ");
|
||||
sb.append("Z:" + (getZeroFlag() ? '1' : '0') + ", ");
|
||||
sb.append("C:" + (getCarryFlag() ? '1' : '0') + ")");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a string representing the CPU state.
|
||||
*/
|
||||
@ -632,7 +756,8 @@ public class Cpu implements InstructionTable {
|
||||
sb.append("A=" + String.format("$%02X", a) + "; ");
|
||||
sb.append("X=" + String.format("$%02X", x) + "; ");
|
||||
sb.append("Y=" + String.format("$%02X", y) + "; ");
|
||||
sb.append("PC=" + String.format("$%04X", pc));
|
||||
sb.append("PC=" + String.format("$%04X", pc)+ "; ");
|
||||
sb.append("P=" + statusRegisterString());
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
|
@ -13,8 +13,8 @@ public class Profiler implements InstructionTable {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// new Profiler().profileMemoryReads();
|
||||
|
||||
new Profiler().dumpOpCodes();
|
||||
// new Profiler().dumpOpCodes();
|
||||
new Profiler().profileProgram();
|
||||
}
|
||||
|
||||
public void dumpOpCodes() {
|
||||
@ -32,6 +32,83 @@ public class Profiler implements InstructionTable {
|
||||
}
|
||||
}
|
||||
|
||||
public void profileProgram() {
|
||||
Bus bus = new Bus(0, 65535);
|
||||
Cpu cpu = new Cpu();
|
||||
|
||||
bus.addCpu(cpu);
|
||||
|
||||
try {
|
||||
bus.addDevice(new Memory(0x0000, 0x10000));
|
||||
} catch (MemoryRangeException ex) {
|
||||
System.err.println("Memory Range Exception! " + ex.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
// Start at 0x0300
|
||||
bus.write(0xfffc, 0x00);
|
||||
bus.write(0xfffd, 0x03);
|
||||
|
||||
// The program to run, in an infinite loop.
|
||||
bus.write(0x0300, 0xa9); // LDA #$FF
|
||||
bus.write(0x0301, 0xff);
|
||||
bus.write(0x0302, 0xea); // NOP
|
||||
bus.write(0x0303, 0xea); // NOP
|
||||
bus.write(0x0304, 0xa0); // LDY #$1A
|
||||
bus.write(0x0305, 0x1a);
|
||||
bus.write(0x0306, 0xea); // NOP
|
||||
bus.write(0x0307, 0xea); // NOP
|
||||
bus.write(0x0308, 0xa2); // LDX #$03
|
||||
bus.write(0x0309, 0x03);
|
||||
|
||||
bus.write(0x030a, 0xa9); // LDA #$00
|
||||
bus.write(0x030b, 0x00);
|
||||
bus.write(0x030c, 0xa2); // LDX #$00
|
||||
bus.write(0x030d, 0x00);
|
||||
bus.write(0x030e, 0xa0); // LDY #$00
|
||||
bus.write(0x030f, 0x00);
|
||||
|
||||
bus.write(0x0310, 0x4c); // JMP #$0300
|
||||
bus.write(0x0311, 0x00);
|
||||
bus.write(0x0312, 0x03);
|
||||
|
||||
|
||||
long sum = 0;
|
||||
|
||||
// The number of times to run the program
|
||||
long iters = 1000;
|
||||
|
||||
// The number of steps to take when running the program
|
||||
long steps = 100000;
|
||||
|
||||
for (int i = 0; i < iters; i++) {
|
||||
long startTime = System.nanoTime();
|
||||
|
||||
// Reset the CPU (does not clear memory)
|
||||
cpu.reset();
|
||||
|
||||
for (int j = 0; j < steps; j++) {
|
||||
cpu.step();
|
||||
}
|
||||
|
||||
long endTime = System.nanoTime();
|
||||
long diff = endTime - startTime;
|
||||
|
||||
sum += diff;
|
||||
}
|
||||
|
||||
long average = sum / iters;
|
||||
long totalSteps = steps * iters;
|
||||
long avgStep = sum / totalSteps;
|
||||
|
||||
System.out.println("Total instructions executed: " +
|
||||
String.format("%,d", totalSteps));
|
||||
System.out.println("Total time taken: " +
|
||||
String.format("%,d us", sum / 1000));
|
||||
System.out.println("Average time per step: " +
|
||||
avgStep + " ns ");
|
||||
}
|
||||
|
||||
public void profileMemoryReads() {
|
||||
// Create a bus.
|
||||
Bus b = new Bus(0, 65535);
|
||||
@ -47,7 +124,8 @@ public class Profiler implements InstructionTable {
|
||||
b.addDevice(new Memory(0xc000, 0x2000)); // 8KB @ $c000-$dfff
|
||||
b.addDevice(new Memory(0xe000, 0x2000)); // 8KB @ $e000-$ffff
|
||||
} catch (MemoryRangeException ex) {
|
||||
System.out.println("Memory Range Exception! " + ex.getMessage());
|
||||
System.err.println("Memory Range Exception! " + ex.getMessage());
|
||||
return;
|
||||
}
|
||||
|
||||
// Read memory
|
||||
|
Loading…
x
Reference in New Issue
Block a user