aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyle Isom <kyle@tyrfingr.is>2014-01-29 11:09:28 -0700
committerKyle Isom <kyle@tyrfingr.is>2014-01-29 11:09:28 -0700
commit8f62b1f757d2b7eb62201facd712bb3af21d23df (patch)
tree9206864e1ee3bedef09dd82e52920e31efd2b090
parent0e08f6cfd4cc6a2fd6011cef73bfcc038f8304b7 (diff)
downloadk6502-8f62b1f757d2b7eb62201facd712bb3af21d23df.tar.gz
k6502-8f62b1f757d2b7eb62201facd712bb3af21d23df.tar.bz2
k6502-8f62b1f757d2b7eb62201facd712bb3af21d23df.zip
Add PHA/PLA.
-rw-r--r--src/cpu.cc148
-rw-r--r--src/cpu.h9
2 files changed, 111 insertions, 46 deletions
diff --git a/src/cpu.cc b/src/cpu.cc
index 0fa13c1..6d00eb2 100644
--- a/src/cpu.cc
+++ b/src/cpu.cc
@@ -279,15 +279,6 @@ CPU::CMP(uint8_t v)
void
-CPU::CMP(uint16_t loc)
-{
- debug("CMP LOC");
- uint8_t v = this->ram.peek(loc);
- this->CMP(v);
-}
-
-
-void
CPU::CPX(uint8_t op)
{
uint8_t v;
@@ -320,6 +311,38 @@ CPU::CPX(uint8_t op)
void
+CPU::CPY(uint8_t op)
+{
+ uint8_t v;
+
+ debug("OP: CPY");
+ this->p &= ~(FLAG_CARRY|FLAG_ZERO|FLAG_NEGATIVE);
+
+ switch ((op & bbb) >> 2) {
+ case C10_MODE_IMM:
+ v = this->read_immed();
+ break;
+ default:
+ v = this->ram.peek(this->read_addr0((op & bbb) >> 2));
+ }
+
+ if (this->y < v) {
+ debug("LT");
+ if ((this->y - v) & 0x80)
+ this->p |= FLAG_NEGATIVE;
+ } else if (this->y == v) {
+ debug("EQ");
+ this->p |= (FLAG_CARRY|FLAG_ZERO);
+ } else if (this->y > v) {
+ debug("GT");
+ this->p |= FLAG_CARRY;
+ if ((this->y - v) & 0x80)
+ this->p |= FLAG_NEGATIVE;
+ }
+}
+
+
+void
CPU::DEX()
{
debug("OP: DEX");
@@ -333,7 +356,7 @@ CPU::DEX()
void
CPU::INX()
{
- debug("INX");
+ debug("OP: INX");
this->x++;
if (this->x == 0)
this->p |= (FLAG_ZERO | FLAG_CARRY);
@@ -341,6 +364,16 @@ CPU::INX()
void
+CPU::INY()
+{
+ debug("OP: INY");
+ this->y++;
+ if (this->y == 0)
+ this->p |= (FLAG_ZERO | FLAG_CARRY);
+}
+
+
+void
CPU::LDA(uint8_t op)
{
debug("OP: LDA");
@@ -454,6 +487,18 @@ CPU::TAX()
}
+void
+CPU::TXA()
+{
+ debug("OP: TXA");
+ this->a = this->x;
+ if (this->x & 0x80)
+ this->p |= FLAG_NEGATIVE;
+ if (this->x == 0)
+ this->p |= FLAG_ZERO;
+}
+
+
/*
* CPU flag set/clear methods.
*/
@@ -616,6 +661,29 @@ CPU::BEQ(uint8_t n)
/*
+ * Stack instructions.
+ */
+
+
+void
+CPU::PHA()
+{
+ debug("OP: PHA");
+ this->ram.poke((0x01 << 8) + this->s, this->a);
+ this->s--;
+}
+
+
+void
+CPU::PLA()
+{
+ debug("OP: PLA");
+ this->s++;
+ this->a = this->ram.peek((0x01 << 8) + this->s);
+}
+
+
+/*
* Instruction processing (reading, parsing, and handling opcodes).
*/
@@ -639,21 +707,36 @@ CPU::step()
case 0x30: // BMI
this->BMI(this->read_immed());
return true;
+ case 0x48: // PHA
+ this->PHA();
+ return true;
case 0x50: // BVC
this->BVC(this->read_immed());
return true;
+ case 0x68: // PLA
+ this->PLA();
+ return true;
case 0x70: // BVS
this->BVS(this->read_immed());
return true;
+ case 0x8a: // TXA
+ this->TXA();
+ return true;
case 0x90: // BCC
this->BCC(this->read_immed());
return true;
case 0xB0: // BCC
this->BCS(this->read_immed());
return true;
+ case 0xC8: // INY
+ this->INY();
+ return true;
case 0xD0: // BNE
this->BNE(this->read_immed());
return true;
+ case 0xE8: // INX
+ this->INX();
+ return true;
}
switch (op & cc) {
@@ -670,6 +753,7 @@ CPU::step()
std::cerr << "[DEBUG] ILLEGAL INSTRUCTION (cc): "
<< std::setw(2) << std::hex << std::setfill('0')
<< (unsigned int)(op&0xff) << std::endl;
+ this->dump_registers();
}
return false;
}
@@ -734,43 +818,19 @@ CPU::instrc00(uint8_t op)
case 0x05:
this->LDY(op);
break;
+ case 0x06:
+ this->CPY(op);
+ break;
case 0x07:
- if (0xE8 == op)
- this->INX();
- else
- this->CPX(op);
+ this->CPX(op);
break;
default:
- switch (op) {
- case 0x10: // BPL
- this->BPL(this->read_immed());
- break;
- case 0x30: // BMI
- this->BMI(this->read_immed());
- break;
- case 0x50: // BVC
- this->BVC(this->read_immed());
- break;
- case 0x70: // BVS
- this->BVS(this->read_immed());
- break;
- case 0x90: // BCC
- this->BCC(this->read_immed());
- break;
- case 0xB0: // BCC
- this->BCS(this->read_immed());
- break;
- case 0xD0: // BNE
- this->BNE(this->read_immed());
- break;
- default:
- std::cerr << "[DEBUG] ILLEGAL INSTRUCTION (INVALID 00): "
- << std::setw(2) << std::hex
- << std::setfill('0')
- << (unsigned int)(op>>5)
- << " " << (unsigned int)op << std::endl;
- break;
- }
+ this->dump_registers();
+ std::cerr << "[DEBUG] ILLEGAL INSTRUCTION (INVALID 00): "
+ << std::setw(2) << std::hex
+ << std::setfill('0')
+ << (unsigned int)(op>>5)
+ << " " << (unsigned int)op << std::endl;
}
}
diff --git a/src/cpu.h b/src/cpu.h
index b58ba3f..4b4a12e 100644
--- a/src/cpu.h
+++ b/src/cpu.h
@@ -80,11 +80,11 @@ class CPU {
void AND(uint8_t);
void AND(uint16_t);
void CMP(uint8_t);
- void CMP(uint16_t);
void CPX(uint8_t);
- void CPX(uint16_t);
+ void CPY(uint8_t);
void DEX(void);
void INX(void);
+ void INY(void);
void LDA(uint8_t);
void LDX(uint8_t);
void LDY(uint8_t);
@@ -92,6 +92,7 @@ class CPU {
void STX(uint8_t);
void STY(uint8_t);
void TAX(void);
+ void TXA(void);
// Branching
void BPL(uint8_t);
@@ -102,6 +103,10 @@ class CPU {
void BCS(uint8_t);
void BNE(uint8_t);
void BEQ(uint8_t);
+
+ // Stack
+ void PHA(void);
+ void PLA(void);
public:
CPU();
CPU(size_t);