aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Isom <kyle@tyrfingr.is>2014-02-03 20:01:08 -0700
committerKyle Isom <kyle@tyrfingr.is>2014-02-03 20:01:08 -0700
commit5e1ee28214719d6a8bdc45c3c6f70e05e142ffb9 (patch)
treee23555274d9074573b118f22db653457871899be
parent398d2c6999acc8c37807f80a366cb80160e183f9 (diff)
downloadk6502-5e1ee28214719d6a8bdc45c3c6f70e05e142ffb9.tar.gz
k6502-5e1ee28214719d6a8bdc45c3c6f70e05e142ffb9.tar.bz2
k6502-5e1ee28214719d6a8bdc45c3c6f70e05e142ffb9.zip
documentation updateHEADmaster
-rw-r--r--src/cpu.cc167
-rw-r--r--src/cpu.h8
-rw-r--r--src/easy6502.cc360
3 files changed, 344 insertions, 191 deletions
diff --git a/src/cpu.cc b/src/cpu.cc
index b0fa63e..dbf896d 100644
--- a/src/cpu.cc
+++ b/src/cpu.cc
@@ -49,6 +49,9 @@ static const uint8_t C10_MODE_ZPX = 5;
static const uint8_t C10_MODE_ZPY = 8;
static const uint8_t C10_MODE_ABSX = 7;
+
+// debug prints a debug string to stderr, if the global flag
+// DEBUG is defined.
static void
debug(const char *s)
{
@@ -58,6 +61,8 @@ debug(const char *s)
}
+// status_flags places a formatted binary representation of the status
+// register for use in dumping registers.
static char *
status_flags(cpu_register8 p)
{
@@ -85,6 +90,8 @@ status_flags(cpu_register8 p)
}
+// overflow returns true if the add/sub of the two 8-bit integers results
+// in a an overflow.
static uint8_t
overflow(uint8_t a, uint8_t b)
{
@@ -92,6 +99,8 @@ overflow(uint8_t a, uint8_t b)
}
+// CPU creates a new processor with the designated amount of memory
+// attached.
CPU::CPU(size_t memory)
{
debug("INIT MEMORY");
@@ -101,6 +110,7 @@ CPU::CPU(size_t memory)
}
+// CPU creates a new processor with the default memory size (128k).
CPU::CPU()
{
debug("default ctor");
@@ -108,6 +118,10 @@ CPU::CPU()
}
+// reset_registers resets all registers to their power-on defaults. For
+// A, X, and Y, this is zero. For the status register, the expansion
+// (unused) bit is high. The stack points back to 0x1ff, and the program
+// count is set to zero.
void
CPU::reset_registers()
{
@@ -121,7 +135,7 @@ CPU::reset_registers()
}
-
+// dump registers prints out the registers to standard error.
void
CPU::dump_registers()
{
@@ -142,6 +156,7 @@ CPU::dump_registers()
}
+// dump_memory dumps the contents of RAM as a hex dump.
void
CPU::dump_memory()
{
@@ -149,6 +164,9 @@ CPU::dump_memory()
}
+// run begins stepping the CPU, fetching and executing instructions from
+// memory. If trace is true, after each step, the memory and registers
+// will be dumped.
void
CPU::run(bool trace)
{
@@ -160,6 +178,8 @@ CPU::run(bool trace)
}
}
+// load is used to load a program into memory. This is effectively a memcpy
+// of the source into the CPU's attached memory.
void
CPU::load(const void *src, uint16_t offset, uint16_t len)
{
@@ -167,6 +187,8 @@ CPU::load(const void *src, uint16_t offset, uint16_t len)
}
+// store copies memory from the CPU's attached memory to the destination
+// buffer.
void
CPU::store(void *dest, uint16_t offset, uint16_t len)
{
@@ -192,13 +214,20 @@ CPU::step_pc(uint8_t n)
}
+// set_entry sets the entry point for the CPU.
void
-CPU::start_pc(uint16_t loc)
+CPU::set_entry(uint16_t loc)
{
this->pc = loc;
}
+/*
+ * Instructions. These generally take either no argument or the
+ * actual op code as input (the opcode allows the emulator to
+ * determine which addressing mode to use). For instructions with
+ * only one addressing mode (i.e. INX), no parameter is required.
+ */
void
CPU::ADC(uint8_t op)
{
@@ -215,8 +244,10 @@ CPU::ADC(uint8_t op)
break;
}
+#if DEBUG
std::cerr << "[DEBUG] ADC V: " << std::setw(2) << std::hex
<< std::setfill('0') << ((unsigned int)v&0xff) << "\n";
+#endif
if ((uint8_t)(this->a + v) < (this->a))
this->p |= FLAG_CARRY;
if (overflow(this->a, v))
@@ -236,9 +267,17 @@ CPU::ADC(uint8_t op)
void
-CPU::AND(uint8_t v)
+CPU::AND(uint8_t op)
{
- debug("AND IMM");
+ uint8_t v;
+ debug("OP: AND");
+
+ switch ((op & bbb) >> 2) {
+ case C01_MODE_IMM:
+ v = this->read_immed();
+ default:
+ v = this->ram.peek(this->read_addr1((op & bbb) >> 2));
+ }
this->a &= v;
if (this->a == 0)
@@ -249,18 +288,18 @@ CPU::AND(uint8_t v)
void
-CPU::AND(uint16_t loc)
+CPU::CMP(uint8_t op)
{
- debug("AND LOC");
- uint8_t v = this->ram.peek(loc);
- this->AND(v);
-}
-
+ uint8_t v = 0;
+ debug("OP: CMP");
-void
-CPU::CMP(uint8_t v)
-{
- debug("CMP IMM");
+ switch ((op & bbb) >> 2) {
+ case C01_MODE_IMM:
+ v = this->read_immed();
+ break;
+ default:
+ v = this->ram.peek(this->read_addr1((op & bbb) >> 2));
+ }
this->p &= ~(FLAG_CARRY|FLAG_ZERO|FLAG_NEGATIVE);
if (this->a < v) {
debug("LT");
@@ -291,7 +330,7 @@ CPU::CPX(uint8_t op)
v = this->read_immed();
break;
default:
- v = this->ram.peek(this->read_addr0((op & bbb) >> 2));
+ v = this->ram.peek(this->read_addr1((op & bbb) >> 2));
}
if (this->x < v) {
@@ -353,6 +392,29 @@ CPU::DEX()
this->p |= FLAG_CARRY;
}
+
+void
+CPU::EOR(uint8_t op)
+{
+ debug("OP: EOR");
+ uint8_t v;
+
+ switch ((op & bbb) >> 2) {
+ case C10_MODE_IMM:
+ v = read_immed();
+ break;
+ default:
+ v = this->ram.peek(this->read_addr1((op & bbb) >> 2));
+ }
+
+ this->a ^= v;
+ if (this->a == 0)
+ this->p |= FLAG_ZERO;
+ if (this->a & 0x80)
+ this->p |= FLAG_NEGATIVE;
+}
+
+
void
CPU::INX()
{
@@ -438,6 +500,27 @@ CPU::LDY(uint8_t op)
void
+CPU::ORA(uint8_t op)
+{
+ uint8_t v;
+ debug("OP: ORA");
+
+ switch ((op & bbb) >> 2) {
+ case C01_MODE_IMM:
+ v = this->read_immed();
+ default:
+ v = this->ram.peek(this->read_addr1((op & bbb) >> 2));
+ }
+ this->a |= v;
+
+ if (this->a == 0)
+ this->p |= FLAG_ZERO;
+ if (this->a & 0x80)
+ this->p |= FLAG_NEGATIVE;
+}
+
+
+void
CPU::STA(uint8_t op)
{
debug("OP: STA");
@@ -665,9 +748,11 @@ CPU::JMP()
{
debug("OP: JMP");
uint16_t addr = this->read_addr1(C01_MODE_ABS);
+#if DEBUG
std::cerr << "[DEBUG] JMP ADDR: " << std::setw(4)
<< std::hex << std::setfill('0')
<< addr << std::endl;
+#endif
this->pc = addr;
}
@@ -730,6 +815,14 @@ CPU::PLA()
* Instruction processing (reading, parsing, and handling opcodes).
*/
+
+size_t
+CPU::get_steps()
+{
+ return this->steps;
+}
+
+
bool
CPU::step()
{
@@ -738,6 +831,7 @@ CPU::step()
debug("STEP");
op = this->ram.peek(this->pc);
this->step_pc();
+ this->steps++;
// Scan single-byte opcodes first
switch (op) {
@@ -747,6 +841,9 @@ CPU::step()
case 0x10: // BPL
this->BPL(this->read_immed());
return true;
+ case 0x18: // CLC
+ this->CLC();
+ return true;
case 0x20: // JSR
this->JSR();
return true;
@@ -783,6 +880,9 @@ CPU::step()
case 0xC8: // INY
this->INY();
return true;
+ case 0xCA: // DEX
+ this->DEX();
+ return true;
case 0xD0: // BNE
this->BNE(this->read_immed());
return true;
@@ -802,10 +902,13 @@ CPU::step()
this->instrc10(op);
return true;
default:
+#if DEBUG
std::cerr << "[DEBUG] ILLEGAL INSTRUCTION (cc): "
<< std::setw(2) << std::hex << std::setfill('0')
<< (unsigned int)(op&0xff) << std::endl;
this->dump_registers();
+#endif
+ break;
}
return false;
}
@@ -815,6 +918,12 @@ void
CPU::instrc01(uint8_t op)
{
switch (op >> 5) {
+ case 0x0: // ORA
+ this->ORA(op);
+ break;
+ case 0x1: // AND
+ this->AND(op);
+ break;
case 0x3: // ADC
this->ADC(op);
return;
@@ -824,11 +933,17 @@ CPU::instrc01(uint8_t op)
case 0x5: // LDA
this->LDA(op);
return;
+ case 0x6: // CMP
+ this->CMP(op);
+ return;
default:
+#if DEBUG
std::cerr << "[DEBUG] ILLEGAL INSTRUCTION (01): "
<< std::setw(2) << std::hex << std::setfill('0')
<< (unsigned int)(op&0xff) << std::endl;
std::cerr << "[DEBUG] OP = " << (unsigned int)op << "\n";
+#endif
+ break;
}
}
@@ -847,14 +962,14 @@ CPU::instrc10(uint8_t op)
this->LDX(op);
break;
case 0x06:
- if (0xCA == op)
- this->DEX();
break;
default:
+#if DEBUG
std::cerr << "[DEBUG] ILLEGAL INSTRUCTION (INVALID 10): "
<< std::setw(2) << std::hex << std::setfill('0')
<< (unsigned int)(op>>5)
<< " " << (unsigned int)op << std::endl;
+#endif
break;
}
}
@@ -878,11 +993,13 @@ CPU::instrc00(uint8_t op)
break;
default:
this->dump_registers();
+#if DEBUG
std::cerr << "[DEBUG] ILLEGAL INSTRUCTION (INVALID 00): "
<< std::setw(2) << std::hex
<< std::setfill('0')
<< (unsigned int)(op>>5)
<< " " << (unsigned int)op << std::endl;
+#endif
}
}
@@ -891,11 +1008,15 @@ uint8_t
CPU::read_immed()
{
uint8_t v;
+#if DEBUG
std::cerr << "[DEBUG] PEEK $" << std::hex << std::setfill('0')
<< std::setw(4) << this->pc;
+#endif
v = this->ram.peek(this->pc);
this->step_pc();
+#if DEBUG
std::cerr << ": " << std::setw(2) << ((unsigned int)v & 0xff) << "\n";
+#endif
return v;
}
@@ -938,13 +1059,17 @@ CPU::read_addr1(uint8_t mode)
break;
default:
debug("INVALID ADDRESSING MODE");
+#if DEBUG
std::cerr << "[DEBUG] MODE: " << std::setw(1)<< std::hex
<< mode << std::endl;
+#endif
addr = 0;
}
+#if DEBUG
std::cerr << "[DEBUG] ADDR: $" << std::setw(4) << std::setfill('0')
<< std::hex << addr << std::endl;
+#endif
return addr;
}
@@ -978,8 +1103,10 @@ CPU::read_addr2(uint8_t mode)
addr = 0;
}
+#if DEBUG
std::cerr << "[DEBUG] ADDR: $" << std::setw(4) << std::setfill('0')
<< std::hex << addr << std::endl;
+#endif
return addr;
}
@@ -1002,12 +1129,15 @@ CPU::read_addr0(uint8_t mode)
addr = 0;
}
+#if DEBUG
std::cerr << "[DEBUG] ADDR: $" << std::setw(4) << std::setfill('0')
<< std::hex << addr << std::endl;
+#endif
return addr;
}
+// The DMA read function allows the host to peer into the CPU's memory.
uint8_t
CPU::DMA(uint16_t loc)
{
@@ -1015,6 +1145,9 @@ CPU::DMA(uint16_t loc)
}
+// The DMA store function allows the host to manipulate the VM's
+// memory. This might be useful, i.e. for graphics adapters and input
+// devices.
void
CPU::DMA(uint16_t loc, uint8_t val)
{
diff --git a/src/cpu.h b/src/cpu.h
index 91e1f1f..4fabfc2 100644
--- a/src/cpu.h
+++ b/src/cpu.h
@@ -50,6 +50,7 @@ class CPU {
cpu_register8 s;
cpu_register16 pc;
RAM ram;
+ size_t steps;
// CPU control
void reset_registers(void);
@@ -78,16 +79,17 @@ class CPU {
// Instructions
void ADC(uint8_t);
void AND(uint8_t);
- void AND(uint16_t);
void CMP(uint8_t);
void CPX(uint8_t);
void CPY(uint8_t);
void DEX(void);
+ void EOR(uint8_t);
void INX(void);
void INY(void);
void LDA(uint8_t);
void LDX(uint8_t);
void LDY(uint8_t);
+ void ORA(uint8_t);
void STA(uint8_t);
void STX(uint8_t);
void STY(uint8_t);
@@ -118,7 +120,7 @@ class CPU {
void dump_memory(void);
void run(bool);
bool step(void);
- void start_pc(uint16_t);
+ void set_entry(uint16_t);
// Memory access; use this to load a memory image or
// write a memory image out.
@@ -128,6 +130,8 @@ class CPU {
uint8_t DMA(uint16_t);
void DMA(uint16_t, uint8_t);
+ size_t get_steps(void);
+
};
diff --git a/src/easy6502.cc b/src/easy6502.cc
index 50a205b..ee0f86d 100644
--- a/src/easy6502.cc
+++ b/src/easy6502.cc
@@ -25,6 +25,8 @@
* uses a starting PC of $0600.
*/
+#include <sys/time.h>
+#include <ctime>
#include <iomanip>
#include <iostream>
using namespace std;
@@ -48,261 +50,275 @@ void test11(void);
static void
dump_program(const unsigned char *program, size_t len)
{
- size_t i = 0;
- int l = 0;
- for (i = 0; i < len; ++i) {
- if (l == 0)
- std::cerr << std::setw(8) << std::hex << i << "| ";
- std::cerr << std::hex << std::setw(2) << std::setfill('0')
- << (unsigned short)(program[i] & 0xff);
- std::cerr << " ";
- l++;
- if (l == 8) {
- std::cerr << " ";
- } else if (l == 16) {
- std::cerr << std::endl;
- l = 0;
- }
- }
- std::cerr << std::endl;
+ size_t i = 0;
+ int l = 0;
+ for (i = 0; i < len; ++i) {
+ if (l == 0)
+ std::cerr << std::setw(8) << std::hex << i << "| ";
+ std::cerr << std::hex << std::setw(2) << std::setfill('0')
+ << (unsigned short)(program[i] & 0xff);
+ std::cerr << " ";
+ l++;
+ if (l == 8) {
+ std::cerr << " ";
+ } else if (l == 16) {
+ std::cerr << std::endl;
+ l = 0;
+ }
+ }
+ std::cerr << std::endl;
}
static void
run(const unsigned char *program, size_t size, bool trace)
{
- CPU cpu(0x400);
- std::cerr << "\nPROGRAM:\n";
- dump_program(program, size);
- std::cerr << std::endl;
+ CPU cpu(0x400);
+ struct timeval tv_start;
+ struct timeval tv_stop;
- cpu.load(program, 0x300, size);
- cpu.start_pc(0x300);
+ std::cerr << "\nPROGRAM:\n";
+ dump_program(program, size);
+ std::cerr << std::endl;
+
+ cpu.load(program, 0x300, size);
+ cpu.set_entry(0x300);
+
+ if (gettimeofday(&tv_start, NULL) != 0)
+ std::cerr << "failed to get time of day\n";
+ cpu.run(trace);
+ if (gettimeofday(&tv_stop, NULL) != 0)
+ std::cerr << "failed to get time of day\n";
+
+ cpu.dump_memory();
+ cpu.dump_registers();
+
+ size_t usec = (tv_stop.tv_sec * 1000000) -
+ (tv_start.tv_sec * 1000000);
+ usec += (tv_stop.tv_usec - tv_start.tv_usec);
+ std::cerr << "Run time: " << std::dec << usec << "usec\n";
- cpu.run(trace);
- cpu.dump_memory();
- cpu.dump_registers();
}
void
test1()
{
- std::cerr << "\nStarting test 1\n";
- std::cerr << "\t(First compiled program)\n";
+ std::cerr << "\nStarting test 1\n";
+ std::cerr << "\t(First compiled program)\n";
- // test1, compiled as opcodes
- unsigned char program[] = {0xA9, 0x01, 0x8D, 0x01, 0x00};
- run(program, 5, false);
+ // test1, compiled as opcodes
+ unsigned char program[] = {0xA9, 0x01, 0x8D, 0x01, 0x00};
+ run(program, 5, false);
}
void
test2()
{
- std::cerr << "\nStarting test 2\n";
- std::cerr << "\t(First full compiled easy6502 program)\n";
-
- unsigned char program[] = {
- 0xa9, 0x01, 0x8d, 0x00, 0x02, 0xa9, 0x05, 0x8d,
- 0x01, 0x02, 0xa9, 0x08, 0x8d, 0x02, 0x02, 0x00
- };
- run(program, 15, false);
+ std::cerr << "\nStarting test 2\n";
+ std::cerr << "\t(First full compiled easy6502 program)\n";
+
+ unsigned char program[] = {
+ 0xa9, 0x01, 0x8d, 0x00, 0x02, 0xa9, 0x05, 0x8d,
+ 0x01, 0x02, 0xa9, 0x08, 0x8d, 0x02, 0x02, 0x00
+ };
+ run(program, 15, false);
}
void
test3()
{
- std::cerr << "\nStarting test 3\n";
- std::cerr << "\t(Second full compiled easy6502 program)\n";
+ std::cerr << "\nStarting test 3\n";
+ std::cerr << "\t(Second full compiled easy6502 program)\n";
- unsigned char program[] = {
- 0xa9, 0xc0, 0xaa, 0xe8, 0x69, 0xc4, 0x00
- };
+ unsigned char program[] = {
+ 0xa9, 0xc0, 0xaa, 0xe8, 0x69, 0xc4, 0x00
+ };
- run(program, 7, false);
+ run(program, 7, false);
}
void
test4()
{
- std::cerr << "\nStarting test 4\n";
- std::cerr << "\t(Third full compiled easy6502 program)\n";
+ std::cerr << "\nStarting test 4\n";
+ std::cerr << "\t(Third full compiled easy6502 program)\n";
- unsigned char program[] = {
- 0xa9, 0x80, 0x85, 0x01, 0x65, 0x01
- };
+ unsigned char program[] = {
+ 0xa9, 0x80, 0x85, 0x01, 0x65, 0x01
+ };
- run(program, 6, false);
+ run(program, 6, false);
}
void
test5()
{
- std::cerr << "\nStarting test 5\n";
- std::cerr << "\t(First branching easy6502 program)\n";
-
- unsigned char program[] = {
- 0xa2, 0x08, 0xca, 0x8e, 0x00, 0x02, 0xe0, 0x03,
- 0xd0, 0xf8, 0x8e, 0x01, 0x02, 0x00
- };
- run(program, 14, false);
+ std::cerr << "\nStarting test 5\n";
+ std::cerr << "\t(First branching easy6502 program)\n";
+
+ unsigned char program[] = {
+ 0xa2, 0x08, 0xca, 0x8e, 0x00, 0x02, 0xe0, 0x03,
+ 0xd0, 0xf8, 0x8e, 0x01, 0x02, 0x00
+ };
+ run(program, 14, false);
}
void
test6()
{
- std::cerr << "\nStarting test 6\n";
- std::cerr << "\t(Indexed indirect addressing)\n";
-
- unsigned char program[] = {
- 0xa2, 0x01, 0xa9, 0x05, 0x85, 0x01, 0xa9, 0x03,
- 0x85, 0x02, 0xa0, 0x0a, 0x8c, 0x05, 0x03, 0xa1,
- 0x00
- };
- run(program, 17, false);
+ std::cerr << "\nStarting test 6\n";
+ std::cerr << "\t(Indexed indirect addressing)\n";
+
+ unsigned char program[] = {
+ 0xa2, 0x01, 0xa9, 0x05, 0x85, 0x01, 0xa9, 0x03,
+ 0x85, 0x02, 0xa0, 0x0a, 0x8c, 0x05, 0x03, 0xa1,
+ 0x00
+ };
+ run(program, 17, false);
}
void
test7()
{
- std::cerr << "\nStarting test 7\n";
- std::cerr << "\t(Indirect indexed addressing)\n";
-
- unsigned char program[] = {
- 0xa0, 0x01, 0xa9, 0x03, 0x85, 0x01, 0xa9, 0x01,
- 0x85, 0x02, 0xa2, 0x0a, 0x8e, 0x04, 0x01, 0xb1,
- 0x01, 0x00
- };
- run(program, 18, false);
+ std::cerr << "\nStarting test 7\n";
+ std::cerr << "\t(Indirect indexed addressing)\n";
+
+ unsigned char program[] = {
+ 0xa0, 0x01, 0xa9, 0x03, 0x85, 0x01, 0xa9, 0x01,
+ 0x85, 0x02, 0xa2, 0x0a, 0x8e, 0x04, 0x01, 0xb1,
+ 0x01, 0x00
+ };
+ run(program, 18, false);
}
void
test8()
{
- std::cerr << "\nStarting test 8\n";
- std::cerr << "\t(Stack manipulation 1)\n";
-
- unsigned char program[] = {
- 0xa2, 0x00, 0xa0, 0x00, 0x8a, 0x99, 0x00, 0x02,
- 0x48, 0xe8, 0xc8, 0xc0, 0x10, 0xd0, 0xf5, 0x68,
- 0x99, 0x00, 0x02, 0xc8, 0xc0, 0x20, 0xd0, 0xf7,
- 0x00
- };
- run(program, 25, false);
+ std::cerr << "\nStarting test 8\n";
+ std::cerr << "\t(Stack manipulation 1)\n";
+
+ unsigned char program[] = {
+ 0xa2, 0x00, 0xa0, 0x00, 0x8a, 0x99, 0x00, 0x02,
+ 0x48, 0xe8, 0xc8, 0xc0, 0x10, 0xd0, 0xf5, 0x68,
+ 0x99, 0x00, 0x02, 0xc8, 0xc0, 0x20, 0xd0, 0xf7,
+ 0x00
+ };
+ run(program, 25, false);
}
void
test9()
{
- std::cerr << "\nStarting test 9\n";
- std::cerr << "\t(jump)\n";
-
- unsigned char program[] = {
- 0xa9, 0x03, 0x4c, 0x08, 0x03, 0x00, 0x00, 0x00,
- 0x8d, 0x00, 0x02, 0x00
- };
- run(program, 12, false);
+ std::cerr << "\nStarting test 9\n";
+ std::cerr << "\t(jump)\n";
+
+ unsigned char program[] = {
+ 0xa9, 0x03, 0x4c, 0x08, 0x03, 0x00, 0x00, 0x00,
+ 0x8d, 0x00, 0x02, 0x00
+ };
+ run(program, 12, false);
}
void
test10()
{
- std::cerr << "\nStarting test 10\n";
- std::cerr << "\t(JSR/RTS)\n";
-
- unsigned char program[] = {
- 0x20, 0x09, 0x03, 0x20, 0x0c, 0x03, 0x20, 0x12,
- 0x03, 0xa2, 0x00, 0x60, 0xe8, 0xe0, 0x05, 0xd0,
- 0xfb, 0x60, 0x00, 0x00
- };
- run(program, 20, false);
+ std::cerr << "\nStarting test 10\n";
+ std::cerr << "\t(JSR/RTS)\n";
+
+ unsigned char program[] = {
+ 0x20, 0x09, 0x03, 0x20, 0x0c, 0x03, 0x20, 0x12,
+ 0x03, 0xa2, 0x00, 0x60, 0xe8, 0xe0, 0x05, 0xd0,
+ 0xfb, 0x60, 0x00, 0x00
+ };
+ run(program, 20, false);
}
void
test11()
{
- // This test requires more memory and a different PC to
- // avoid having to rewrite large swaths of 6502 for this test.
- std::cerr << "\nStarting test 11\n";
- std::cerr << "\t(Player-less snake)\n";
-
- unsigned char program[] = {
- 0x20, 0x06, 0x06, 0x20, 0x38, 0x06, 0x20, 0x0d,
- 0x06, 0x20, 0x2a, 0x06, 0x60, 0xa9, 0x02, 0x85,
- 0x02, 0xa9, 0x04, 0x85, 0x03, 0xa9, 0x11, 0x85,
- 0x10, 0xa9, 0x10, 0x85, 0x12, 0xa9, 0x0f, 0x85,
- 0x14, 0xa9, 0x04, 0x85, 0x11, 0x85, 0x13, 0x85,
- 0x15, 0x60, 0xa5, 0xfe, 0x85, 0x00, 0xa5, 0xfe,
- 0x29, 0x03, 0x18, 0x69, 0x02, 0x85, 0x01, 0x60,
- 0x20, 0x4d, 0x06, 0x20, 0x8d, 0x06, 0x20, 0xc3,
- 0x06, 0x20, 0x19, 0x07, 0x20, 0x20, 0x07, 0x20,
- 0x2d, 0x07, 0x4c, 0x38, 0x06, 0xa5, 0xff, 0xc9,
- 0x77, 0xf0, 0x0d, 0xc9, 0x64, 0xf0, 0x14, 0xc9,
- 0x73, 0xf0, 0x1b, 0xc9, 0x61, 0xf0, 0x22, 0x60,
- 0xa9, 0x04, 0x24, 0x02, 0xd0, 0x26, 0xa9, 0x01,
- 0x85, 0x02, 0x60, 0xa9, 0x08, 0x24, 0x02, 0xd0,
- 0x1b, 0xa9, 0x02, 0x85, 0x02, 0x60, 0xa9, 0x01,
- 0x24, 0x02, 0xd0, 0x10, 0xa9, 0x04, 0x85, 0x02,
- 0x60, 0xa9, 0x02, 0x24, 0x02, 0xd0, 0x05, 0xa9,
- 0x08, 0x85, 0x02, 0x60, 0x60, 0x20, 0x94, 0x06,
- 0x20, 0xa8, 0x06, 0x60, 0xa5, 0x00, 0xc5, 0x10,
- 0xd0, 0x0d, 0xa5, 0x01, 0xc5, 0x11, 0xd0, 0x07,
- 0xe6, 0x03, 0xe6, 0x03, 0x20, 0x2a, 0x06, 0x60,
- 0xa2, 0x02, 0xb5, 0x10, 0xc5, 0x10, 0xd0, 0x06,
- 0xb5, 0x11, 0xc5, 0x11, 0xf0, 0x09, 0xe8, 0xe8,
- 0xe4, 0x03, 0xf0, 0x06, 0x4c, 0xaa, 0x06, 0x4c,
- 0x35, 0x07, 0x60, 0xa6, 0x03, 0xca, 0x8a, 0xb5,
- 0x10, 0x95, 0x12, 0xca, 0x10, 0xf9, 0xa5, 0x02,
- 0x4a, 0xb0, 0x09, 0x4a, 0xb0, 0x19, 0x4a, 0xb0,
- 0x1f, 0x4a, 0xb0, 0x2f, 0xa5, 0x10, 0x38, 0xe9,
- 0x20, 0x85, 0x10, 0x90, 0x01, 0x60, 0xc6, 0x11,
- 0xa9, 0x01, 0xc5, 0x11, 0xf0, 0x28, 0x60, 0xe6,
- 0x10, 0xa9, 0x1f, 0x24, 0x10, 0xf0, 0x1f, 0x60,
- 0xa5, 0x10, 0x18, 0x69, 0x20, 0x85, 0x10, 0xb0,
- 0x01, 0x60, 0xe6, 0x11, 0xa9, 0x06, 0xc5, 0x11,
- 0xf0, 0x0c, 0x60, 0xc6, 0x10, 0xa5, 0x10, 0x29,
- 0x1f, 0xc9, 0x1f, 0xf0, 0x01, 0x60, 0x4c, 0x35,
- 0x07, 0xa0, 0x00, 0xa5, 0xfe, 0x91, 0x00, 0x60,
- 0xa2, 0x00, 0xa9, 0x01, 0x81, 0x10, 0xa6, 0x03,
- 0xa9, 0x00, 0x81, 0x10, 0x60, 0xa2, 0x00, 0xea,
- 0xea, 0xca, 0xd0, 0xfb, 0x60,
- };
- CPU cpu(0x800);
- std::cerr << "\nPROGRAM:\n";
- dump_program(program, 0x134);
- std::cerr << std::endl;
-
- cpu.load(program, 0x600, 0x134);
- cpu.start_pc(0x600);
-
- cpu.run(true);
- cpu.dump_memory();
- cpu.dump_registers();
+ // This test requires more memory and a different PC to
+ // avoid having to rewrite large swaths of 6502 for this test.
+ std::cerr << "\nStarting test 11\n";
+ std::cerr << "\t(Player-less snake)\n";
+
+ unsigned char program[] = {
+ 0x20, 0x06, 0x06, 0x20, 0x38, 0x06, 0x20, 0x0d,
+ 0x06, 0x20, 0x2a, 0x06, 0x60, 0xa9, 0x02, 0x85,
+ 0x02, 0xa9, 0x04, 0x85, 0x03, 0xa9, 0x11, 0x85,
+ 0x10, 0xa9, 0x10, 0x85, 0x12, 0xa9, 0x0f, 0x85,
+ 0x14, 0xa9, 0x04, 0x85, 0x11, 0x85, 0x13, 0x85,
+ 0x15, 0x60, 0xa5, 0xfe, 0x85, 0x00, 0xa5, 0xfe,
+ 0x29, 0x03, 0x18, 0x69, 0x02, 0x85, 0x01, 0x60,
+ 0x20, 0x4d, 0x06, 0x20, 0x8d, 0x06, 0x20, 0xc3,
+ 0x06, 0x20, 0x19, 0x07, 0x20, 0x20, 0x07, 0x20,
+ 0x2d, 0x07, 0x4c, 0x38, 0x06, 0xa5, 0xff, 0xc9,
+ 0x77, 0xf0, 0x0d, 0xc9, 0x64, 0xf0, 0x14, 0xc9,
+ 0x73, 0xf0, 0x1b, 0xc9, 0x61, 0xf0, 0x22, 0x60,
+ 0xa9, 0x04, 0x24, 0x02, 0xd0, 0x26, 0xa9, 0x01,
+ 0x85, 0x02, 0x60, 0xa9, 0x08, 0x24, 0x02, 0xd0,
+ 0x1b, 0xa9, 0x02, 0x85, 0x02, 0x60, 0xa9, 0x01,
+ 0x24, 0x02, 0xd0, 0x10, 0xa9, 0x04, 0x85, 0x02,
+ 0x60, 0xa9, 0x02, 0x24, 0x02, 0xd0, 0x05, 0xa9,
+ 0x08, 0x85, 0x02, 0x60, 0x60, 0x20, 0x94, 0x06,
+ 0x20, 0xa8, 0x06, 0x60, 0xa5, 0x00, 0xc5, 0x10,
+ 0xd0, 0x0d, 0xa5, 0x01, 0xc5, 0x11, 0xd0, 0x07,
+ 0xe6, 0x03, 0xe6, 0x03, 0x20, 0x2a, 0x06, 0x60,
+ 0xa2, 0x02, 0xb5, 0x10, 0xc5, 0x10, 0xd0, 0x06,
+ 0xb5, 0x11, 0xc5, 0x11, 0xf0, 0x09, 0xe8, 0xe8,
+ 0xe4, 0x03, 0xf0, 0x06, 0x4c, 0xaa, 0x06, 0x4c,
+ 0x35, 0x07, 0x60, 0xa6, 0x03, 0xca, 0x8a, 0xb5,
+ 0x10, 0x95, 0x12, 0xca, 0x10, 0xf9, 0xa5, 0x02,
+ 0x4a, 0xb0, 0x09, 0x4a, 0xb0, 0x19, 0x4a, 0xb0,
+ 0x1f, 0x4a, 0xb0, 0x2f, 0xa5, 0x10, 0x38, 0xe9,
+ 0x20, 0x85, 0x10, 0x90, 0x01, 0x60, 0xc6, 0x11,
+ 0xa9, 0x01, 0xc5, 0x11, 0xf0, 0x28, 0x60, 0xe6,
+ 0x10, 0xa9, 0x1f, 0x24, 0x10, 0xf0, 0x1f, 0x60,
+ 0xa5, 0x10, 0x18, 0x69, 0x20, 0x85, 0x10, 0xb0,
+ 0x01, 0x60, 0xe6, 0x11, 0xa9, 0x06, 0xc5, 0x11,
+ 0xf0, 0x0c, 0x60, 0xc6, 0x10, 0xa5, 0x10, 0x29,
+ 0x1f, 0xc9, 0x1f, 0xf0, 0x01, 0x60, 0x4c, 0x35,
+ 0x07, 0xa0, 0x00, 0xa5, 0xfe, 0x91, 0x00, 0x60,
+ 0xa2, 0x00, 0xa9, 0x01, 0x81, 0x10, 0xa6, 0x03,
+ 0xa9, 0x00, 0x81, 0x10, 0x60, 0xa2, 0x00, 0xea,
+ 0xea, 0xca, 0xd0, 0xfb, 0x60,
+ };
+ CPU cpu(0x800);
+ std::cerr << "\nPROGRAM:\n";
+ dump_program(program, 0x134);
+ std::cerr << std::endl;
+
+ cpu.load(program, 0x600, 0x134);
+ cpu.set_entry(0x600);
+
+ cpu.run(true);
+ cpu.dump_memory();
+ cpu.dump_registers();
}
int
main(void)
{
- test1();
- test2();
- test3();
- test4();
- test5();
- test6();
- test7();
- test8();
- test9();
- test10();
- test11();
+ test1();
+ test2();
+ test3();
+ test4();
+ test5();
+ test6();
+ test7();
+ test8();
+ test9();
+ test10();
+ //test11();
}