Skip to content

Commit

Permalink
End of stream #4
Browse files Browse the repository at this point in the history
  • Loading branch information
Shachar committed Sep 3, 2023
1 parent 7133b19 commit e113cd9
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 5 deletions.
125 changes: 125 additions & 0 deletions c6502.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,31 @@ void c6502::handleInstruction() {
advance_pc();

switch(current_opcode) {
case 0x08: op_php( addrmode_stack() ); break;
case 0x10: op_bpl( addrmode_immediate() ); break;
case 0x20: op_jsr( addrmode_special() ); break;
case 0x26: op_rol( addrmode_zp() ); break;
case 0x28: op_plp( addrmode_stack() ); break;
case 0x2e: op_rol( addrmode_abs() ); break;
case 0x30: op_bmi( addrmode_immediate() ); break;
case 0x40: op_rti( addrmode_stack() ); break;
case 0x48: op_pha( addrmode_stack() ); break;
case 0x4c: op_jmp( addrmode_abs() ); break;
case 0x50: op_bvc( addrmode_immediate() ); break;
case 0x60: op_rts( addrmode_stack() ); break;
case 0x68: op_pla( addrmode_stack() ); break;
case 0x70: op_bvs( addrmode_immediate() ); break;
case 0x85: op_sta( addrmode_zp() ); break;
case 0x90: op_bcc( addrmode_immediate() ); break;
case 0x9a: op_txs( addrmode_implicit() ); break;
case 0xa2: op_ldx( addrmode_immediate() ); break;
case 0xa5: op_lda( addrmode_zp() ); break;
case 0xa9: op_lda( addrmode_immediate() ); break;
case 0xad: op_lda( addrmode_abs() ); break;
case 0xb0: op_bcs( addrmode_immediate() ); break;
case 0xd0: op_bne( addrmode_immediate() ); break;
case 0xea: op_nop( addrmode_implicit() ); break;
case 0xf0: op_beq( addrmode_immediate() ); break;
default: std::cerr<<"Unknown command "<<std::hex<<int(current_opcode)<<" at "<<(pc()-1)<<"\n"; abort();
}
}
Expand Down Expand Up @@ -126,6 +141,12 @@ Addr c6502::addrmode_immediate() {
}

Addr c6502::addrmode_implicit() {
read( pc() );

return pc();
}

Addr c6502::addrmode_special() {
return pc();
}

Expand All @@ -142,6 +163,74 @@ Addr c6502::addrmode_zp() {
return addr;
}

void c6502::branch_helper(Addr addr, bool jump) {
int8_t offset = read(addr);

if( jump ) {
read( pc() );

uint16_t program_counter = pc();
program_counter += offset;

regPcL = program_counter & 0xff;

if( regPcH != (program_counter>>8) ) {
read( pc() );
regPcH = program_counter >> 8;
}
}
}

void c6502::op_bcc(Addr addr) {
branch_helper(addr, ! ccGet(CC::Carry));
}

void c6502::op_bcs(Addr addr) {
branch_helper(addr, ccGet(CC::Carry));
}

void c6502::op_beq(Addr addr) {
branch_helper(addr, ccGet(CC::Zero));
}

void c6502::op_bne(Addr addr) {
branch_helper(addr, ! ccGet(CC::Zero));
}

void c6502::op_bmi(Addr addr) {
branch_helper(addr, ccGet(CC::Negative));
}

void c6502::op_bpl(Addr addr) {
branch_helper(addr, ! ccGet(CC::Negative));
}


void c6502::op_bvc(Addr addr) {
branch_helper(addr, ! ccGet(CC::oVerflow));
}

void c6502::op_bvs(Addr addr) {
branch_helper(addr, ccGet(CC::oVerflow));
}

void c6502::op_jmp(Addr addr) {
regPcL = addr & 0xff;
regPcH = addr >> 8;
}

void c6502::op_jsr(Addr addr) {
uint8_t dest_low = read( pc() );
advance_pc();

read( compose( 0x01, regSp ) );
write( compose( 0x01, regSp-- ), regPcH );
write( compose( 0x01, regSp-- ), regPcL );

regPcH = read( pc() );
regPcL = dest_low;
}

void c6502::op_lda(Addr addr) {
regA = read( addr );
}
Expand All @@ -150,12 +239,21 @@ void c6502::op_ldx(Addr addr) {
regX = read( addr );
}

void c6502::op_nop(Addr addr) {
}

void c6502::op_pha(Addr addr) {
write( addr, regA );

regSp--;
}

void c6502::op_php(Addr addr) {
write( addr, regStatus );

regSp--;
}

void c6502::op_pla(Addr addr) {
read( addr );

Expand All @@ -166,6 +264,13 @@ void c6502::op_pla(Addr addr) {
ccSet( CC::Zero, regA==0 );
}

void c6502::op_plp(Addr addr) {
read( addr );

regSp++;
regStatus = read( compose( 0x01, regSp ) ) | 0x30;
}

void c6502::op_rol(Addr addr) {
uint16_t value = read( addr );
write( addr, value );
Expand All @@ -179,6 +284,26 @@ void c6502::op_rol(Addr addr) {
write( addr, value );
}

void c6502::op_rti(Addr addr) {
read( addr );
regSp++;

regStatus = read( compose(0x01, regSp++) ) | 0x30;

regPcL = read( compose(0x01, regSp++) );
regPcH = read( compose(0x01, regSp) );
}

void c6502::op_rts(Addr addr) {
read( compose(0x01, regSp++) );

regPcL = read( compose(0x01, regSp++) );
regPcH = read( compose(0x01, regSp) );

read( pc() );
advance_pc();
}

void c6502::op_sta(Addr addr) {
write( addr, regA );
}
Expand Down
20 changes: 19 additions & 1 deletion c6502.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class c6502 {
Bus &bus_;
uint8_t regA, regX, regY;
uint8_t regSp;
uint8_t regStatus;
uint8_t regStatus = 0xff;
uint8_t regPcL, regPcH;

uint8_t current_opcode;
Expand Down Expand Up @@ -52,20 +52,38 @@ class c6502 {
void ccSet( CC cc, bool value );


void branch_helper(Addr addr, bool jump);

// Address modes
Addr addrmode_abs();
Addr addrmode_immediate();
Addr addrmode_implicit();
Addr addrmode_stack();
Addr addrmode_zp();
Addr addrmode_special();


// Operations
void op_bcc(Addr addr);
void op_bcs(Addr addr);
void op_beq(Addr addr);
void op_bmi(Addr addr);
void op_bne(Addr addr);
void op_bpl(Addr addr);
void op_bvc(Addr addr);
void op_bvs(Addr addr);
void op_jmp(Addr addr);
void op_jsr(Addr addr);
void op_lda(Addr addr);
void op_ldx(Addr addr);
void op_nop(Addr addr);
void op_pha(Addr addr);
void op_php(Addr addr);
void op_pla(Addr addr);
void op_plp(Addr addr);
void op_rol(Addr addr);
void op_rti(Addr addr);
void op_rts(Addr addr);
void op_sta(Addr addr);
void op_txs(Addr addr);
};
18 changes: 14 additions & 4 deletions verify_cpu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class TestBus : public Bus {
ReadMem<8,8,16,4> test_plan;
size_t cycles_until_start = StartGraceCycles;
bool cpuInReset = true;
size_t cycle_num = 0;


public:
Expand All @@ -34,6 +35,7 @@ class TestBus : public Bus {

if( address==0xfffc && !cpuInReset ) {
cycles_until_start = 0;
cycle_num = 1;
std::cout<<"Reset vector read detected\n";
} else {
if( --cycles_until_start == 0 ) {
Expand All @@ -44,20 +46,28 @@ class TestBus : public Bus {
}

if( cycles_until_start==0 ) {
std::cout<<std::dec<<cycle_num<<" R: "<<std::hex<<address<<" "<<int(ret)<<"\n";
cycle_num++;
bool valid = test_plan.read_line();
assert(valid);

check( test_plan[0], 1, "Write operation where read was expected", address, ret );
check( test_plan[0], 1, "Read operation where write was expected", address, ret );
check( test_plan[2], address, "Read from wrong address", address, ret );
check( test_plan[1], ret, "Read wrong value from memory", address, ret );
}

return ret;
}
virtual void write( c6502 *cpu, Addr address, uint8_t value ) override {
check( test_plan[0], 0, "Read operation where write was expected", address, value );
check( test_plan[2], address, "Write to wrong address", address, value );
check( test_plan[1], value, "Write of wrong value to memory", address, value );
std::cout<<std::dec<<cycle_num<<" W: "<<std::hex<<address<<" "<<int(value)<<"\n";
cycle_num++;

bool valid = test_plan.read_line();
if( valid ) {
check( test_plan[0], 0, "Write operation where read was expected", address, value );
check( test_plan[2], address, "Write to wrong address", address, value );
check( test_plan[1], value, "Write of wrong value to memory", address, value );
}

memory[address] = value;
}
Expand Down

0 comments on commit e113cd9

Please sign in to comment.