summaryrefslogtreecommitdiff
path: root/emu
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-12-28 16:10:40 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2020-12-28 16:10:40 +0100
commitdd4174bb32973d1212235dc8e262c23013b88912 (patch)
treeff72586c34bd89ea8ba50457d0901188738f2e4d /emu
parentc0e01bce21b06bf9e62d9f2bf436ad93914512e8 (diff)
download6502-dd4174bb32973d1212235dc8e262c23013b88912.tar.gz
6502-dd4174bb32973d1212235dc8e262c23013b88912.tar.bz2
introduced cycles
Diffstat (limited to 'emu')
-rw-r--r--emu/6502.c52
-rw-r--r--emu/6502.h4
-rw-r--r--emu/emul.c6
-rw-r--r--emu/memory.c2
-rw-r--r--emu/tests/test_cpu_6502.c72
5 files changed, 87 insertions, 49 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];
}
diff --git a/emu/6502.h b/emu/6502.h
index 9dc8614..c462fcc 100644
--- a/emu/6502.h
+++ b/emu/6502.h
@@ -20,6 +20,7 @@ typedef struct
int debug_flags;
int steps;
+ int cycles;
int error_state;
} cpu_6502_t;
@@ -92,7 +93,8 @@ void cpu_6502_push_word( cpu_6502_t *cpu, uint16_t data );
uint8_t cpu_6502_pop_byte( cpu_6502_t *cpu );
uint16_t cpu_6502_pop_word( cpu_6502_t *cpu );
-void cpu_6502_run( cpu_6502_t *cpu, int steps );
+void cpu_6502_run_steps( cpu_6502_t *cpu, int steps );
+void cpu_6502_run_cycles( cpu_6502_t *cpu, int cycles );
void cpu_6502_step( cpu_6502_t *cpu );
void cpu_6502_get_opcode_mnemonic( cpu_6502_t *cpu, char *buf, int buflen, uint16_t addr );
diff --git a/emu/emul.c b/emu/emul.c
index 53d5ed2..3ee60c0 100644
--- a/emu/emul.c
+++ b/emu/emul.c
@@ -118,7 +118,7 @@ void emul_run( emul_t *emul, int nof_steps )
emul->paused = true;
break;
case SDLK_s:
- cpu_6502_run( emul->cpu, 1 );
+ cpu_6502_run_steps( emul->cpu, 1 );
break;
case SDLK_EQUALS:
case SDLK_KP_EQUALS:
@@ -147,7 +147,7 @@ void emul_run( emul_t *emul, int nof_steps )
}
if( !emul->paused ) {
- cpu_6502_run( emul->cpu, emul->speed / DISPLAY_FPS );
+ cpu_6502_run_cycles( emul->cpu, emul->speed / DISPLAY_FPS );
}
SDL_RenderCopy( emul->renderer, emul->background_texture, NULL, NULL );
@@ -171,7 +171,7 @@ void emul_run( emul_t *emul, int nof_steps )
}
}
} else {
- cpu_6502_run( emul->cpu, nof_steps );
+ cpu_6502_run_steps( emul->cpu, nof_steps );
}
#else
cpu_6502_run( emul->cpu, nof_steps );
diff --git a/emu/memory.c b/emu/memory.c
index 3ab0694..4ddd8c3 100644
--- a/emu/memory.c
+++ b/emu/memory.c
@@ -45,7 +45,7 @@ void memory_load( memory_t *memory, const char *filename )
}
fread( &memory->cell[0], memory->size, 1, f );
fclose( f );
- fprintf( stderr, "INFO: Loaded firware from '%s' of size %d starting on address %04X\n",
+ fprintf( stderr, "INFO: Loaded firmware from '%s' of size %d starting on address %04X\n",
filename, memory->size, memory->addr );
} else {
fprintf( stderr, "ERROR: Cannot load firmware into RAM at address %04X\n", memory->addr );
diff --git a/emu/tests/test_cpu_6502.c b/emu/tests/test_cpu_6502.c
index 86d1115..37394ab 100644
--- a/emu/tests/test_cpu_6502.c
+++ b/emu/tests/test_cpu_6502.c
@@ -100,7 +100,7 @@ START_TEST( test_cpu_6502_nop )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -129,7 +129,7 @@ START_TEST( test_cpu_6502_txs )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -158,7 +158,7 @@ START_TEST( test_cpu_6502_lda_flags_positive )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -185,7 +185,7 @@ START_TEST( test_cpu_6502_lda_flags_negative )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -214,7 +214,7 @@ START_TEST( test_cpu_6502_lda_flags_zero )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -245,7 +245,7 @@ START_TEST( test_cpu_6502_ldy_flags_positive )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -272,7 +272,7 @@ START_TEST( test_cpu_6502_ldy_flags_negative )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -301,7 +301,7 @@ START_TEST( test_cpu_6502_ldy_flags_zero )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -332,7 +332,7 @@ START_TEST( test_cpu_6502_ldx_flags_positive )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -359,7 +359,7 @@ START_TEST( test_cpu_6502_ldx_flags_negative )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -388,7 +388,7 @@ START_TEST( test_cpu_6502_ldx_flags_zero )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -419,7 +419,7 @@ START_TEST( test_cpu_6502_stx_addr_zero )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -448,7 +448,7 @@ START_TEST( test_cpu_6502_stx_addr_abs )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -479,7 +479,7 @@ START_TEST( test_cpu_6502_inc_flags_positive )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -510,7 +510,7 @@ START_TEST( test_cpu_6502_inc_flags_negative )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -541,7 +541,7 @@ START_TEST( test_cpu_6502_inc_flags_zero )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -574,7 +574,7 @@ START_TEST( test_cpu_6502_inx_flags_positive )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -603,7 +603,7 @@ START_TEST( test_cpu_6502_inx_flags_negative )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -632,7 +632,7 @@ START_TEST( test_cpu_6502_inx_flags_zero )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -663,7 +663,7 @@ START_TEST( test_cpu_6502_dex_flags_positive )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -692,7 +692,7 @@ START_TEST( test_cpu_6502_dex_flags_negative )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -721,7 +721,7 @@ START_TEST( test_cpu_6502_dex_flags_zero )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -752,7 +752,7 @@ START_TEST( test_cpu_6502_dey_flags_positive )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -781,7 +781,7 @@ START_TEST( test_cpu_6502_dey_flags_negative )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -810,7 +810,7 @@ START_TEST( test_cpu_6502_dey_flags_zero )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -842,7 +842,7 @@ START_TEST( test_cpu_6502_rol_flags_accumulator_carry )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -874,7 +874,7 @@ START_TEST( test_cpu_6502_cpx_flags_equals )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -904,7 +904,7 @@ START_TEST( test_cpu_6502_cpx_flags_less )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -934,7 +934,7 @@ START_TEST( test_cpu_6502_cpx_flags_greater )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -966,7 +966,7 @@ START_TEST( test_cpu_6502_bcc_carry_clear )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -993,7 +993,7 @@ START_TEST( test_cpu_6502_bcc_carry_set )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -1022,7 +1022,7 @@ START_TEST( test_cpu_6502_bne_zero_clear )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -1049,7 +1049,7 @@ START_TEST( test_cpu_6502_bne_zero_set )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -1076,7 +1076,7 @@ START_TEST( test_cpu_6502_jmp_abs )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -1105,7 +1105,7 @@ START_TEST( test_cpu_6502_jsr_abs )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST
@@ -1138,7 +1138,7 @@ START_TEST( test_cpu_6502_rts )
COPY_CPU_TEST
- cpu_6502_run( &cpu, 1 );
+ cpu_6502_run_steps( &cpu, 1 );
PRINT_CPU_TEST