summaryrefslogtreecommitdiff
path: root/emu/6502.c
diff options
context:
space:
mode:
Diffstat (limited to 'emu/6502.c')
-rw-r--r--emu/6502.c52
1 files changed, 44 insertions, 8 deletions
diff --git a/emu/6502.c b/emu/6502.c
index cab72b3..53af7a0 100644
--- a/emu/6502.c
+++ b/emu/6502.c
@@ -12,6 +12,7 @@ void cpu_6502_init( cpu_6502_t *cpu, bus_t *bus, bool initialize )
cpu->bus = bus;
cpu->debug_flags = 0;
cpu->steps = 0;
+ cpu->cycles = 0;
cpu->error_state = ERROR_STATE_OK;
if( initialize ) {
@@ -85,7 +86,7 @@ void cpu_6502_write_word( cpu_6502_t *cpu, uint16_t addr, uint16_t data )
cpu->bus->base.vtable->write( cpu->bus, addr + 1, ( data && 0x00FF ) );
}
-void cpu_6502_run( cpu_6502_t *cpu, int steps )
+void cpu_6502_run_steps( cpu_6502_t *cpu, int steps )
{
if( steps != -1 ) {
for( int i = 1; i <= steps && cpu->error_state == ERROR_STATE_OK; i++ ) {
@@ -98,6 +99,20 @@ void cpu_6502_run( cpu_6502_t *cpu, int steps )
}
}
+void cpu_6502_run_cycles( cpu_6502_t *cpu, int cycles )
+{
+ if( cycles != -1 ) {
+ int start_cycles = cpu->cycles;
+ while( cpu->cycles < start_cycles + cycles && cpu->error_state == ERROR_STATE_OK ) {
+ cpu_6502_step( cpu );
+ }
+ } else {
+ while( cpu->error_state == ERROR_STATE_OK ) {
+ cpu_6502_step( cpu );
+ }
+ }
+}
+
static void handle_zero( cpu_6502_t *cpu, uint8_t x )
{
if( x == 0 ) {
@@ -151,8 +166,28 @@ bool cpu_6502_is_carry( cpu_6502_t *cpu )
return cpu->PS & PS_C;
}
+static const int cycles[NOF_OPCODES] = {
+ /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+ /* 0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 1 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 2 */ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0,
+ /* 3 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 4 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0,
+ /* 5 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 6 */ 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 7 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* 8 */ 0, 0, 0, 0, 0, 0, 3, 0, 2, 0, 0, 0, 0, 0, 4, 0,
+ /* 9 */ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0,
+ /* A */ 2, 0, 2, 0, 3, 3, 3, 0, 0, 2, 0, 0, 0, 0, 0, 0,
+ /* B */ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* C */ 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 2, 0, 0, 0, 0, 0,
+ /* D */ 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ /* E */ 3, 0, 0, 0, 0, 0, 5, 0, 0, 2, 2, 0, 0, 0, 0, 0,
+ /* F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
static const char mnemonic[NOF_OPCODES][MAX_MENMONIC_LENGTH] = {
- /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
+ /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */
/* 0 */ "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???",
/* 1 */ "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???",
/* 2 */ "JSR", "???", "???", "???", "???", "???", "???", "???", "???", "???", "ROL", "???", "???", "???", "???", "???",
@@ -169,6 +204,7 @@ static const char mnemonic[NOF_OPCODES][MAX_MENMONIC_LENGTH] = {
/* D */ "BNE", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???",
/* E */ "CPX", "???", "???", "???", "???", "???", "INC", "???", "???", "SBC", "NOP", "???", "???", "???", "???", "???",
/* F */ "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???", "???"
+};
/*
"BRK", "ORA", "" , "", "TSB", "ORA", "ASL", "RMB0", "PHP", "ORA", "ASL", "" , "TSB", "ORA", "ASL", "BBR0",
@@ -188,7 +224,6 @@ static const char mnemonic[NOF_OPCODES][MAX_MENMONIC_LENGTH] = {
"CPX", "SBC", "" , "", "CPX", "SBC", "INC", "SMB6", "INX", "SBC", "NOP", "" , "CPX", "SBC", "INC", "BBS6",
"BEQ", "SBC", "SBC", "", "" , "SBC", "INC", "SMB7", "SED", "SBC", "PLX", "" , "" , "SBC", "INC", "BBS7"
*/
-};
void cpu_6502_get_opcode_mnemonic( cpu_6502_t *cpu, char *buf, int buflen, uint16_t addr )
{
@@ -218,7 +253,7 @@ void cpu_6502_print_state( cpu_6502_t *cpu, uint16_t addr )
cpu_6502_get_opcode_mnemonic( cpu, opcode_str, MAX_OPCODE_MNEMONIC_STRING_LENGTH, addr );
- fprintf( stderr, "PC: %04X SP: 01%02X PS: %02X %c%c-%c%c%c%c%c A: %02X X: %02X Y: %02X steps: %d OP: %s\n",
+ fprintf( stderr, "PC: %04X SP: 01%02X PS: %02X %c%c-%c%c%c%c%c A: %02X X: %02X Y: %02X steps: %d cycles: %d OP: %s\n",
cpu->PC, cpu->SP, cpu->PS,
cpu_6502_is_negative( cpu ) ? 'N' : 'n',
cpu_6502_is_overflow( cpu ) ? 'V' : 'v',
@@ -228,7 +263,7 @@ void cpu_6502_print_state( cpu_6502_t *cpu, uint16_t addr )
cpu_6502_is_zero( cpu ) ? 'Z' : 'z',
cpu_6502_is_carry( cpu ) ? 'C' : 'c',
cpu->A, cpu->X, cpu->Y, cpu->steps,
- opcode_str );
+ cpu->cycles, opcode_str );
}
static void update_negative_and_sign( cpu_6502_t *cpu, uint8_t x )
@@ -372,12 +407,12 @@ void cpu_6502_step( cpu_6502_t *cpu )
case SBC_IMM:
operand8 = cpu_6502_read_byte( cpu, cpu->PC );
cpu->PC++;
- tmp = cpu->A - operand8 - ( cpu_6502_is_carry( cpu ) ? 1 : 0 );
+ tmp = cpu->A - operand8 - ( cpu_6502_is_carry( cpu ) ? 0 : 1 );
update_negative_and_sign( cpu, tmp );
if( tmp & 0xFF00 ) {
- cpu->PS |= PS_C;
- } else {
cpu->PS &= ~PS_C;
+ } else {
+ cpu->PS |= PS_C;
}
if( ( ( cpu->A ^ tmp ) & 0x80 ) && ( ( cpu->A ^ operand8 ) & 0x80 ) ) {
cpu->PS |= PS_V;
@@ -438,4 +473,5 @@ void cpu_6502_step( cpu_6502_t *cpu )
}
cpu->steps++;
+ cpu->cycles += cycles[opcode];
}