mirror of
https://github.com/sethm/symon.git
synced 2025-08-09 11:25:13 +00:00
- Major overhaul of the Simulator control class (where 'main' lives).
- Removed the CommandParser class entirely, as the weird dependency between Simulator and CommandParser never made me comfortable. - Added a Command inner class to Simulator that handles some of the command line tokenizing.
This commit is contained in:
@@ -1,92 +0,0 @@
|
|||||||
package com.loomcom.symon;
|
|
||||||
|
|
||||||
import java.io.*;
|
|
||||||
import com.loomcom.symon.devices.*;
|
|
||||||
import com.loomcom.symon.exceptions.*;
|
|
||||||
|
|
||||||
|
|
||||||
public class CommandParser {
|
|
||||||
|
|
||||||
private BufferedReader in;
|
|
||||||
private BufferedWriter out;
|
|
||||||
private Simulator simulator;
|
|
||||||
|
|
||||||
public CommandParser(InputStream i, OutputStream o, Simulator s) {
|
|
||||||
this.in = new BufferedReader(new InputStreamReader(i));
|
|
||||||
this.out = new BufferedWriter(new OutputStreamWriter(o));
|
|
||||||
this.simulator = s;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run() throws MemoryAccessException {
|
|
||||||
try {
|
|
||||||
String command = null;
|
|
||||||
greeting();
|
|
||||||
prompt();
|
|
||||||
while (!shouldQuit(command = readLine())) {
|
|
||||||
dispatch(command);
|
|
||||||
prompt();
|
|
||||||
}
|
|
||||||
writeLine("\n\nGoodbye!");
|
|
||||||
} catch (IOException ex) {
|
|
||||||
System.err.println("Error: " + ex.toString());
|
|
||||||
System.exit(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSimulator(Simulator sim) {
|
|
||||||
this.simulator = sim;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Simulator getSimulator() {
|
|
||||||
return this.simulator;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dispatch the command.
|
|
||||||
*/
|
|
||||||
public void dispatch(String command)
|
|
||||||
throws MemoryAccessException, IOException {
|
|
||||||
// TODO: Real implementation. This first one is just
|
|
||||||
// for testing.
|
|
||||||
if ("test".equals(command)) {
|
|
||||||
simulator.runTest();
|
|
||||||
} else if ("ex".equals(command)) {
|
|
||||||
writeLine(simulator.getState());
|
|
||||||
} else {
|
|
||||||
writeLine("Huh?");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*******************************************************************
|
|
||||||
* Private
|
|
||||||
*******************************************************************/
|
|
||||||
|
|
||||||
private void greeting() throws IOException {
|
|
||||||
writeLine("Welcome to the j6502 Simulator!");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void prompt() throws IOException {
|
|
||||||
out.write("j6502> ");
|
|
||||||
out.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String readLine() throws IOException {
|
|
||||||
String line = in.readLine();
|
|
||||||
if (line == null) { return null; }
|
|
||||||
return line.trim();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeLine(String line) throws IOException {
|
|
||||||
out.write(line);
|
|
||||||
out.newLine();
|
|
||||||
out.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if the line is a quit.
|
|
||||||
*/
|
|
||||||
private boolean shouldQuit(String line) {
|
|
||||||
return (line == null || "q".equals(line.toLowerCase()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@@ -1,5 +1,15 @@
|
|||||||
package com.loomcom.symon;
|
package com.loomcom.symon;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.BufferedWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import com.loomcom.symon.devices.*;
|
import com.loomcom.symon.devices.*;
|
||||||
import com.loomcom.symon.exceptions.*;
|
import com.loomcom.symon.exceptions.*;
|
||||||
|
|
||||||
@@ -8,11 +18,6 @@ import com.loomcom.symon.exceptions.*;
|
|||||||
*/
|
*/
|
||||||
public class Simulator {
|
public class Simulator {
|
||||||
|
|
||||||
/**
|
|
||||||
* Command-line parser used by this simulator.
|
|
||||||
*/
|
|
||||||
private CommandParser parser;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The CPU itself.
|
* The CPU itself.
|
||||||
*/
|
*/
|
||||||
@@ -23,35 +28,197 @@ public class Simulator {
|
|||||||
* correct IO devices.
|
* correct IO devices.
|
||||||
*/
|
*/
|
||||||
private Bus bus;
|
private Bus bus;
|
||||||
|
|
||||||
|
private BufferedReader in;
|
||||||
|
private BufferedWriter out;
|
||||||
|
|
||||||
|
/* If true, trace execution of the CPU */
|
||||||
|
private boolean trace = false;
|
||||||
|
|
||||||
public Simulator() throws MemoryRangeException {
|
public Simulator() throws MemoryRangeException {
|
||||||
cpu = new Cpu();
|
cpu = new Cpu();
|
||||||
bus = new Bus(0x0000, 0xffff);
|
bus = new Bus(0x0000, 0xffff);
|
||||||
bus.addCpu(cpu);
|
bus.addCpu(cpu);
|
||||||
bus.addDevice(new Memory(0x0000, 0x10000));
|
bus.addDevice(new Memory(0x0000, 0x10000));
|
||||||
parser = new CommandParser(System.in, System.out, this);
|
this.in = new BufferedReader(new InputStreamReader(System.in));
|
||||||
}
|
this.out = new BufferedWriter(new OutputStreamWriter(System.out));
|
||||||
|
|
||||||
public String getState() throws MemoryAccessException {
|
|
||||||
return cpu.toString();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void run() throws MemoryAccessException {
|
public void run() throws MemoryAccessException {
|
||||||
parser.run();
|
try {
|
||||||
}
|
greeting();
|
||||||
|
prompt();
|
||||||
public void load(int address, int[] program)
|
String command = null;
|
||||||
throws MemoryAccessException {
|
while (!shouldQuit(command = readLine())) {
|
||||||
int i = 0;
|
try {
|
||||||
for (int d : program) {
|
dispatch(command);
|
||||||
bus.write(address + i++, d);
|
} catch (CommandFormatException ex) {
|
||||||
|
writeLine(ex.getMessage());
|
||||||
|
}
|
||||||
|
prompt();
|
||||||
|
}
|
||||||
|
writeLine("\n\nGoodbye!");
|
||||||
|
} catch (IOException ex) {
|
||||||
|
System.err.println("Error: " + ex.toString());
|
||||||
|
System.exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A test method.
|
* Dispatch the command.
|
||||||
*/
|
*/
|
||||||
public void runTest() throws MemoryAccessException {
|
public void dispatch(String commandLine)
|
||||||
|
throws MemoryAccessException, IOException, CommandFormatException {
|
||||||
|
Command c = new Command(commandLine);
|
||||||
|
String cmd = c.getCommand();
|
||||||
|
if (cmd != null) {
|
||||||
|
if ("test".equals(cmd)) {
|
||||||
|
doTest();
|
||||||
|
} else if (cmd.startsWith("s")) {
|
||||||
|
doGetState();
|
||||||
|
} else if (cmd.startsWith("r")) {
|
||||||
|
doReset();
|
||||||
|
} else if (cmd.startsWith("e")) {
|
||||||
|
doExamine(c);
|
||||||
|
} else if (cmd.startsWith("d")) {
|
||||||
|
doDeposit(c);
|
||||||
|
} else if (cmd.startsWith("g")) {
|
||||||
|
doGo(c);
|
||||||
|
} else if (cmd.startsWith("h")) {
|
||||||
|
doHelp(c);
|
||||||
|
} else if (cmd.startsWith("t")) {
|
||||||
|
doToggleTrace();
|
||||||
|
} else if (cmd.startsWith("f")) {
|
||||||
|
doFill(c);
|
||||||
|
} else {
|
||||||
|
writeLine("? Type h for help");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doHelp(Command c) throws IOException {
|
||||||
|
writeLine("Symon 6502 Simulator");
|
||||||
|
writeLine("");
|
||||||
|
writeLine("All addresses must be in hexadecimal. Commands may be short or");
|
||||||
|
writeLine("long (e.g. 'e' or 'ex' or 'examine'). Note that 'go' clears the");
|
||||||
|
writeLine("Break processor status flag");
|
||||||
|
writeLine("");
|
||||||
|
writeLine("g [address [steps]] Start running at address.");
|
||||||
|
writeLine("e [start [end]] Examine memory.");
|
||||||
|
writeLine("d [address] [data] Deposit data into address.");
|
||||||
|
writeLine("f [start] [end] [data] Fill memory with data.");
|
||||||
|
writeLine("r Reset simulator.");
|
||||||
|
writeLine("s Show CPU state.");
|
||||||
|
writeLine("t Toggle trace.");
|
||||||
|
writeLine("q (or Control-D) Quit.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doGetState() throws IOException, MemoryAccessException {
|
||||||
|
writeLine(cpu.toString());
|
||||||
|
writeLine("Trace is " + (trace ? "on" : "off"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doExamine(Command c) throws IOException, MemoryAccessException, CommandFormatException {
|
||||||
|
try {
|
||||||
|
if (c.numArgs() == 2) {
|
||||||
|
int startAddress = stringToWord(c.getArgs()[0]);
|
||||||
|
int endAddress = stringToWord(c.getArgs()[1]);
|
||||||
|
while (startAddress < endAddress) {
|
||||||
|
StringBuffer line = new StringBuffer();
|
||||||
|
int numBytes = 0;
|
||||||
|
line.append(String.format("%04x ", startAddress));
|
||||||
|
while (numBytes++ < 8 && startAddress <= endAddress) {
|
||||||
|
line.append(String.format("%02x ", bus.read(startAddress++)));
|
||||||
|
}
|
||||||
|
writeLine(line.toString());
|
||||||
|
}
|
||||||
|
} else if (c.numArgs() == 1) {
|
||||||
|
int address = stringToWord(c.getArgs()[0]);
|
||||||
|
writeLine(String.format("%04x %02x", address, bus.read(address)));
|
||||||
|
} else {
|
||||||
|
throw new CommandFormatException("e [start [end]]");
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
throw new CommandFormatException("Address not understood");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doDeposit(Command c) throws MemoryAccessException, CommandFormatException {
|
||||||
|
if (c.numArgs() != 2) {
|
||||||
|
throw new CommandFormatException("d [address] [data]");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
int address = stringToWord(c.getArg(0));
|
||||||
|
int data = stringToByte(c.getArg(1));
|
||||||
|
bus.write(address, data);
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
throw new CommandFormatException("Address not understood");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doFill(Command c) throws MemoryAccessException, CommandFormatException {
|
||||||
|
if (c.numArgs() != 3) {
|
||||||
|
throw new CommandFormatException("f [start] [end] [data]");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
int start = stringToWord(c.getArg(0));
|
||||||
|
int end = stringToWord(c.getArg(1));
|
||||||
|
int data = stringToByte(c.getArg(2));
|
||||||
|
while (start < end) {
|
||||||
|
bus.write(start, data);
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
throw new CommandFormatException("Address not understood");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doGo(Command c) throws IOException, MemoryAccessException, CommandFormatException {
|
||||||
|
if (c.numArgs() != 1 && c.numArgs() != 2) {
|
||||||
|
throw new CommandFormatException("g [address [steps]]");
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
int start = stringToWord(c.getArg(0));
|
||||||
|
int steps = -1;
|
||||||
|
if (c.numArgs() == 2) {
|
||||||
|
steps = stringToWord(c.getArg(1));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make a gross assumption: Restarting the CPU clears
|
||||||
|
// the break flag and the IRQ disable flag.
|
||||||
|
cpu.clearBreakFlag();
|
||||||
|
cpu.clearIrqDisableFlag();
|
||||||
|
|
||||||
|
cpu.setProgramCounter(start);
|
||||||
|
while (!cpu.getBreakFlag() && (steps == -1 || steps-- > 0)) {
|
||||||
|
cpu.step();
|
||||||
|
if (trace) {
|
||||||
|
writeLine(cpu.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!trace) {
|
||||||
|
writeLine(cpu.toString());
|
||||||
|
}
|
||||||
|
} catch (NumberFormatException ex) {
|
||||||
|
throw new CommandFormatException("Address not understood");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doToggleTrace() throws IOException {
|
||||||
|
this.trace = !trace;
|
||||||
|
writeLine("Trace is now " + (trace ? "on" : "off"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void doReset() throws MemoryAccessException {
|
||||||
|
cpu.reset();
|
||||||
|
this.trace = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run a very simple test program that doesn't do
|
||||||
|
* much other than exercise the accumulator a bit.
|
||||||
|
*/
|
||||||
|
public void doTest() throws MemoryAccessException {
|
||||||
int[] zpData = {
|
int[] zpData = {
|
||||||
0x39, // $0000
|
0x39, // $0000
|
||||||
0x21, // $0001
|
0x21, // $0001
|
||||||
@@ -100,5 +267,99 @@ public class Simulator {
|
|||||||
System.err.println("Error: " + ex.toString());
|
System.err.println("Error: " + ex.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
* Private
|
||||||
|
*******************************************************************/
|
||||||
|
|
||||||
|
public void load(int address, int[] data)
|
||||||
|
throws MemoryAccessException {
|
||||||
|
int i = 0;
|
||||||
|
for (int d : data) {
|
||||||
|
bus.write(address + i++, d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int stringToWord(String addrString) {
|
||||||
|
return Integer.parseInt(addrString, 16) & 0xffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int stringToByte(String dataString) {
|
||||||
|
return Integer.parseInt(dataString, 16) & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void greeting() throws IOException {
|
||||||
|
writeLine("Welcome to the Symon Simulator!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prompt() throws IOException {
|
||||||
|
out.write("symon> ");
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readLine() throws IOException {
|
||||||
|
String line = in.readLine();
|
||||||
|
if (line == null) { return null; }
|
||||||
|
return line.trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeLine(String line) throws IOException {
|
||||||
|
out.write(line);
|
||||||
|
out.newLine();
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if the line is a quit.
|
||||||
|
*/
|
||||||
|
private boolean shouldQuit(String line) {
|
||||||
|
return (line == null || "q".equals(line.toLowerCase()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Command line tokenizer class. Given a command line, tokenize
|
||||||
|
* it and give easy access to the command and its arguments.
|
||||||
|
*/
|
||||||
|
public static final class Command {
|
||||||
|
private String command;
|
||||||
|
private String[] args;
|
||||||
|
|
||||||
|
public Command(String commandLine) {
|
||||||
|
StringTokenizer st = new StringTokenizer(commandLine);
|
||||||
|
int numTokens = st.countTokens();
|
||||||
|
int idx = 0;
|
||||||
|
args = new String[numTokens > 1 ? numTokens - 1 : 0];
|
||||||
|
while (st.hasMoreTokens()) {
|
||||||
|
if (command == null) {
|
||||||
|
command = st.nextToken();
|
||||||
|
} else {
|
||||||
|
args[idx++] = st.nextToken();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCommand() {
|
||||||
|
return command;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getArgs() {
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getArg(int argNum) {
|
||||||
|
if (argNum > args.length - 1) {
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return args[argNum];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int numArgs() {
|
||||||
|
return args.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasArgs() {
|
||||||
|
return args.length > 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -14,8 +14,8 @@ public class Memory extends Device {
|
|||||||
super(address, size, "RW Memory");
|
super(address, size, "RW Memory");
|
||||||
this.readOnly = readOnly;
|
this.readOnly = readOnly;
|
||||||
this.mem = new int[size];
|
this.mem = new int[size];
|
||||||
// Initialize all locations to 0xff
|
// Initialize all locations to 0x00 (BRK)
|
||||||
Arrays.fill(this.mem, 0xff);
|
Arrays.fill(this.mem, 0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Memory(int address, int size)
|
public Memory(int address, int size)
|
||||||
|
@@ -0,0 +1,10 @@
|
|||||||
|
package com.loomcom.symon.exceptions;
|
||||||
|
|
||||||
|
public class CommandFormatException extends Exception {
|
||||||
|
public CommandFormatException(String msg) {
|
||||||
|
super(msg);
|
||||||
|
}
|
||||||
|
public CommandFormatException() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
64
src/test/java/com/loomcom/symon/CommandTest.java
Normal file
64
src/test/java/com/loomcom/symon/CommandTest.java
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package com.loomcom.symon;
|
||||||
|
|
||||||
|
import org.junit.*;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class CommandTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCommandShouldParseCorrectNumberOfArguments() {
|
||||||
|
Simulator.Command c;
|
||||||
|
|
||||||
|
c = new Simulator.Command("foo");
|
||||||
|
assertEquals("foo", c.getCommand());
|
||||||
|
assertEquals(0, c.numArgs());
|
||||||
|
|
||||||
|
c = new Simulator.Command("foo bar");
|
||||||
|
assertEquals("foo", c.getCommand());
|
||||||
|
assertEquals(1, c.numArgs());
|
||||||
|
assertEquals("bar", c.getArgs()[0]);
|
||||||
|
|
||||||
|
c = new Simulator.Command("foo bar baz quux 0 100");
|
||||||
|
assertEquals("foo", c.getCommand());
|
||||||
|
assertEquals(5, c.numArgs());
|
||||||
|
assertEquals("bar", c.getArgs()[0]);
|
||||||
|
assertEquals("baz", c.getArgs()[1]);
|
||||||
|
assertEquals("quux", c.getArgs()[2]);
|
||||||
|
assertEquals("0", c.getArgs()[3]);
|
||||||
|
assertEquals("100", c.getArgs()[4]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCommandShouldIgnoreWhitespaceBetweenTokens() {
|
||||||
|
Simulator.Command c;
|
||||||
|
|
||||||
|
c = new Simulator.Command("foo bar baz");
|
||||||
|
assertEquals("foo", c.getCommand());
|
||||||
|
assertEquals(2, c.numArgs());
|
||||||
|
assertEquals("bar", c.getArgs()[0]);
|
||||||
|
assertEquals("baz", c.getArgs()[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCommandShouldIgnoreWhitespaceBeforeCommand() {
|
||||||
|
Simulator.Command c;
|
||||||
|
|
||||||
|
c = new Simulator.Command(" foo bar baz");
|
||||||
|
assertEquals("foo", c.getCommand());
|
||||||
|
assertEquals(2, c.numArgs());
|
||||||
|
assertEquals("bar", c.getArgs()[0]);
|
||||||
|
assertEquals("baz", c.getArgs()[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCommandShouldIgnoreWhitespaceAfterCommand() {
|
||||||
|
Simulator.Command c;
|
||||||
|
|
||||||
|
c = new Simulator.Command("foo bar baz ");
|
||||||
|
assertEquals("foo", c.getCommand());
|
||||||
|
assertEquals(2, c.numArgs());
|
||||||
|
assertEquals("bar", c.getArgs()[0]);
|
||||||
|
assertEquals("baz", c.getArgs()[1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -170,7 +170,7 @@ public class CpuAbsoluteXModeTest extends TestCase {
|
|||||||
0xa9, 0xff, // LDA #$ff
|
0xa9, 0xff, // LDA #$ff
|
||||||
0x3d, 0x05, 0x1a, // AND $1a05,X
|
0x3d, 0x05, 0x1a, // AND $1a05,X
|
||||||
0xa9, 0x01, // LDA #$01
|
0xa9, 0x01, // LDA #$01
|
||||||
0x3d, 0xd2, 0x1a); // AND $1ad2,X
|
0x3d, 0xd2, 0x19); // AND $19d2,X
|
||||||
cpu.step();
|
cpu.step();
|
||||||
assertEquals(0x00, cpu.getAccumulator());
|
assertEquals(0x00, cpu.getAccumulator());
|
||||||
assertTrue(cpu.getZeroFlag());
|
assertTrue(cpu.getZeroFlag());
|
||||||
|
@@ -115,7 +115,7 @@ public class CpuAbsoluteYModeTest extends TestCase {
|
|||||||
0xa9, 0xff, // LDA #$ff
|
0xa9, 0xff, // LDA #$ff
|
||||||
0x39, 0x05, 0x1a, // AND $1a05,Y
|
0x39, 0x05, 0x1a, // AND $1a05,Y
|
||||||
0xa9, 0x01, // LDA #$01
|
0xa9, 0x01, // LDA #$01
|
||||||
0x39, 0xd2, 0x1a); // AND $1ad2,Y
|
0x39, 0xd2, 0x19); // AND $19d2,Y
|
||||||
cpu.step();
|
cpu.step();
|
||||||
assertEquals(0x00, cpu.getAccumulator());
|
assertEquals(0x00, cpu.getAccumulator());
|
||||||
assertTrue(cpu.getZeroFlag());
|
assertTrue(cpu.getZeroFlag());
|
||||||
|
@@ -74,7 +74,7 @@ public class CpuImpliedModeTest extends TestCase {
|
|||||||
cpu.setOverflowFlag();
|
cpu.setOverflowFlag();
|
||||||
assertEquals(0x20|Cpu.P_CARRY|Cpu.P_OVERFLOW,
|
assertEquals(0x20|Cpu.P_CARRY|Cpu.P_OVERFLOW,
|
||||||
cpu.getProcessorStatus());
|
cpu.getProcessorStatus());
|
||||||
assertEquals(0xff, cpu.stackPeek());
|
assertEquals(0x00, cpu.stackPeek());
|
||||||
assertFalse(cpu.getBreakFlag());
|
assertFalse(cpu.getBreakFlag());
|
||||||
assertEquals(0x0200, cpu.getProgramCounter());
|
assertEquals(0x0200, cpu.getProgramCounter());
|
||||||
assertEquals(0xff, cpu.getStackPointer());
|
assertEquals(0xff, cpu.getStackPointer());
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
package com.loomcom.symon;
|
package com.loomcom.symon;
|
||||||
|
|
||||||
import com.loomcom.symon.devices.Memory;
|
import com.loomcom.symon.devices.Memory;
|
||||||
import com.loomcom.symon.exceptions.MemoryAccessException;
|
|
||||||
|
|
||||||
import org.junit.*;
|
import org.junit.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
@@ -115,7 +115,7 @@ public class CpuIndirectXModeTest extends TestCase {
|
|||||||
0xa9, 0xff, // LDA #$ff
|
0xa9, 0xff, // LDA #$ff
|
||||||
0x3d, 0x05, 0x1a, // AND $1a05,X
|
0x3d, 0x05, 0x1a, // AND $1a05,X
|
||||||
0xa9, 0x01, // LDA #$01
|
0xa9, 0x01, // LDA #$01
|
||||||
0x3d, 0xd2, 0x1a); // AND $1ad2,X
|
0x3d, 0xd2, 0x19); // AND $19d2,X
|
||||||
cpu.step();
|
cpu.step();
|
||||||
assertEquals(0x00, cpu.getAccumulator());
|
assertEquals(0x00, cpu.getAccumulator());
|
||||||
assertTrue(cpu.getZeroFlag());
|
assertTrue(cpu.getZeroFlag());
|
||||||
|
@@ -70,7 +70,7 @@ public class CpuTest extends TestCase {
|
|||||||
|
|
||||||
public void testStackPush() throws MemoryAccessException {
|
public void testStackPush() throws MemoryAccessException {
|
||||||
assertEquals(0xff, cpu.getStackPointer());
|
assertEquals(0xff, cpu.getStackPointer());
|
||||||
assertEquals(0xff, bus.read(0x1ff));
|
assertEquals(0x00, bus.read(0x1ff));
|
||||||
|
|
||||||
cpu.stackPush(0x06);
|
cpu.stackPush(0x06);
|
||||||
assertEquals(0xfe, cpu.getStackPointer());
|
assertEquals(0xfe, cpu.getStackPointer());
|
||||||
@@ -179,7 +179,7 @@ public class CpuTest extends TestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testStackPeekDoesNotAlterStackPointer() throws MemoryAccessException {
|
public void testStackPeekDoesNotAlterStackPointer() throws MemoryAccessException {
|
||||||
assertEquals(0xff, cpu.stackPeek());
|
assertEquals(0x00, cpu.stackPeek());
|
||||||
assertEquals(0xff, cpu.getStackPointer());
|
assertEquals(0xff, cpu.getStackPointer());
|
||||||
|
|
||||||
cpu.stackPush(0x01);
|
cpu.stackPush(0x01);
|
||||||
|
Reference in New Issue
Block a user