1
0
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:
sethm 2008-12-13 00:50:14 -08:00
parent 7e36444193
commit 59e5572039
2 changed files with 209 additions and 6 deletions

View File

@ -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();
}

View File

@ -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