Skip to content

Commit

Permalink
conditional branching decoding
Browse files Browse the repository at this point in the history
  • Loading branch information
tnibert committed Nov 3, 2019
1 parent 4456c5f commit cf39f0d
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 9 deletions.
64 changes: 55 additions & 9 deletions decoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ InstructionDecoder::InstructionDecoder(cpustate * c, Memory * m)
/**
* Decode an opcode and execute it
* form aaabbbcc or xxy10000
* bbb and ccc match ups depends on cc
* bbb and aaa match ups depends on cc
* return number of cycles used
*/
int InstructionDecoder::decode_and_execute(uint8_t opcode)
Expand All @@ -30,20 +30,67 @@ int InstructionDecoder::decode_and_execute(uint8_t opcode)
// todo: single byte instructions

// The conditional branch instructions all have the form xxy10000.
// The flag indicated by xx is compared with y, and the branch is taken if they are equal.
if((opcode | 0b11100000) == 0b11110000)
{
uint8_t xx = opcode & 0b11000000;
bool y = (opcode & 0b00100000) >> 5;
// todo: finish this
// todo: BRK, JSR abs, RTI, RTS
bool to_jump = decode_branch(opcode);

/*switch(xx)
if(to_jump)
{
// these can use relative (all branch instructions) or absolute addressing
// need to differentiate
// the following won't cut it
// relative - signed 8 bit relative offset (e.g. -128 to +127)

}*/
// relative, todo: account for sign (is this two's comp?)
//cpu->pc += mem->readmem(cpu->pc + mem->readmem(cpu->pc+1));
// absolute:
//cpu->pc = mem->readmem(revlendianbytes(cpu->pc+2, cpu->pc+1));
}
}
else
// form aaabbbcc instruction
else
{
decode_aaabbbcc(opcode);
}

return 1; // replace this with cycles used?
}

bool InstructionDecoder::decode_branch(uint8_t opcode)
{
// The flag indicated by xx is compared with y, and the branch is taken if they are equal.
// this gives us: BPL, BMI, BVC, BVS, BCC, BCS, BNE, BEQ
uint8_t xx = (opcode & 0b11000000) >> 6;
int flag;
bool y = (opcode & 0b00100000) >> 5;
bool to_jump = false;

// determine the flag to evaluate
switch(xx)
{
case 0b00: // test negative flag
flag = FLAG_NEGATIVE;
break;
case 0b01: // test overflow flag
flag = FLAG_OVERFLOW;
break;
case 0b10: // test carry flag
flag = FLAG_CARRY;
break;
case 0b11: // test zero flag
flag = FLAG_ZERO;
break;
}

// compare the flag with y
to_jump = (getflag(cpu, flag) == y);

return to_jump;
}

void InstructionDecoder::decode_aaabbbcc(uint8_t opcode)
{
{
uint8_t cc = opcode & 0b00000011; // control code
uint8_t bbb = opcode & 0b00011100; // addressing mode
Expand Down Expand Up @@ -200,5 +247,4 @@ int InstructionDecoder::decode_and_execute(uint8_t opcode)
// case 0b11 only used for illegal opcodes
}
}
return 1; // replace this with cycles used?
}
2 changes: 2 additions & 0 deletions decoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ class InstructionDecoder
public:
InstructionDecoder(cpustate *, Memory *);
int decode_and_execute(uint8_t);
void decode_aaabbbcc(uint8_t);
bool decode_branch(uint8_t);
};


Expand Down
1 change: 1 addition & 0 deletions tests/systemtests.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ class TestDecoder : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE( TestDecoder );
CPPUNIT_TEST( test_aaabbbcc );
CPPUNIT_TEST( test_branching );
CPPUNIT_TEST_SUITE_END();

private:
Expand Down
16 changes: 16 additions & 0 deletions tests/testdecoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,19 @@ void TestDecoder::test_aaabbbcc()
CPPUNIT_ASSERT(cpu->a == 0b11111111);
}

void TestDecoder::test_branching()
{
cpu->pc = 0;
cpu->p = 0b00000010;
//mem->writemem(0, 0xf0);
mem->writemem(1, 3); // branch +3 bytes

bool test = decoder->decode_branch(0xf0); // decode BEQ
CPPUNIT_ASSERT(test);

cpu->p = 0b0;
test = decoder->decode_branch(0xf0);
CPPUNIT_ASSERT(!test);

// todo: test the jumping
}

0 comments on commit cf39f0d

Please sign in to comment.