From 53569267c59204f56e4c0fddb669536d28706e5c Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Tue, 29 Dec 2020 11:08:58 +0100 Subject: - testing of correct cycles - fixed some SDL includes --- LINKS | 1 + emu/6502.c | 5 ++- emu/7seg.c | 3 +- emu/7seg.h | 9 ----- emu/bus.h | 1 + emu/device.h | 1 + emu/tests/test_cpu_6502.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++- 7 files changed, 106 insertions(+), 12 deletions(-) diff --git a/LINKS b/LINKS index 36213cc..7f1a915 100644 --- a/LINKS +++ b/LINKS @@ -92,6 +92,7 @@ https://hgj.hu/live-migrating-a-virtual-machine-with-libvirt-without-a-shared-st https://hackaday.io/project/174128/logs https://sbc.rictor.org/ http://retro.hansotten.nl/ +http://danceswithferrets.org/geekblog/?page_id=915 delay/timers: https://gist.github.com/superjamie/fd80fabadf39199c97de400213f614e9 diff --git a/emu/6502.c b/emu/6502.c index 53af7a0..98af83a 100644 --- a/emu/6502.c +++ b/emu/6502.c @@ -182,7 +182,7 @@ static const int cycles[NOF_OPCODES] = { /* 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, + /* E */ 2, 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 }; @@ -427,6 +427,7 @@ void cpu_6502_step( cpu_6502_t *cpu ) cpu->PC++; if( !cpu_6502_is_zero( cpu ) ) { cpu->PC += (int8_t)operand8; + cpu->cycles++; } break; @@ -435,6 +436,7 @@ void cpu_6502_step( cpu_6502_t *cpu ) cpu->PC++; if( !cpu_6502_is_carry( cpu ) ) { cpu->PC += (int8_t)operand8; + cpu->cycles++; } break; @@ -443,6 +445,7 @@ void cpu_6502_step( cpu_6502_t *cpu ) cpu->PC++; if( cpu_6502_is_carry( cpu ) ) { cpu->PC += (int8_t)operand8; + cpu->cycles++; } break; diff --git a/emu/7seg.c b/emu/7seg.c index f4bc25e..787b280 100644 --- a/emu/7seg.c +++ b/emu/7seg.c @@ -4,7 +4,8 @@ #include #ifdef WITH_GUI - +#include +#include #endif static device_vtable_t const seg7_vtable = { diff --git a/emu/7seg.h b/emu/7seg.h index 4da0e1f..0256f83 100644 --- a/emu/7seg.h +++ b/emu/7seg.h @@ -3,18 +3,9 @@ #include "device.h" -#ifdef WITH_GUI -#include -#endif - #include #include -#ifdef WITH_GUI -#include -#include -#endif - // VIA connected on PORTA to 3 wires leading to the 3 coupled 74HC595 // shift register which enable the ROM address lines to read the LED // segment data (cells 0-15 contain the encoded 7 segments of 16 hexdigits) diff --git a/emu/bus.h b/emu/bus.h index baa2fe2..c1866cb 100644 --- a/emu/bus.h +++ b/emu/bus.h @@ -21,6 +21,7 @@ typedef struct bus_t { void bus_init( bus_t *bus ); void bus_register( bus_t *bus, device_t *device, uint16_t from, uint16_t to ); + uint8_t bus_read( void *obj, uint16_t addr ); void bus_write( void *obj, uint16_t addr, uint8_t data ); void bus_deinit( void *obj ); diff --git a/emu/device.h b/emu/device.h index 1cf36e7..81a1dd4 100644 --- a/emu/device.h +++ b/emu/device.h @@ -28,6 +28,7 @@ typedef struct device_t { void device_init( device_t *device, const char *name ); void device_copy( device_t *to, device_t *from ); + uint8_t device_read( void *obj, uint16_t addr ); void device_write( void *obj, uint16_t addr, uint8_t data ); #ifdef WITH_GUI diff --git a/emu/tests/test_cpu_6502.c b/emu/tests/test_cpu_6502.c index 37394ab..94b68b4 100644 --- a/emu/tests/test_cpu_6502.c +++ b/emu/tests/test_cpu_6502.c @@ -112,6 +112,7 @@ START_TEST( test_cpu_6502_nop ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -141,6 +142,7 @@ START_TEST( test_cpu_6502_txs ) ck_assert_int_eq( cpu.X, 0xff ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -172,6 +174,7 @@ START_TEST( test_cpu_6502_lda_flags_positive ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -199,6 +202,7 @@ START_TEST( test_cpu_6502_lda_flags_negative ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -228,6 +232,7 @@ START_TEST( test_cpu_6502_lda_flags_zero ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -259,6 +264,7 @@ START_TEST( test_cpu_6502_ldy_flags_positive ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, 0x01 ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -286,6 +292,7 @@ START_TEST( test_cpu_6502_ldy_flags_negative ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, 0xff ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -315,6 +322,7 @@ START_TEST( test_cpu_6502_ldy_flags_zero ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, 0x00 ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -346,6 +354,7 @@ START_TEST( test_cpu_6502_ldx_flags_positive ) ck_assert_int_eq( cpu.X, 0x01 ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -373,6 +382,7 @@ START_TEST( test_cpu_6502_ldx_flags_negative ) ck_assert_int_eq( cpu.X, 0xff ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -402,6 +412,7 @@ START_TEST( test_cpu_6502_ldx_flags_zero ) ck_assert_int_eq( cpu.X, 0x00 ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -413,7 +424,7 @@ START_TEST( test_cpu_6502_stx_addr_zero ) { INIT_CPU_TEST - CODE_SET2( 0x86, 0x03 ); // STX #$03 + CODE_SET2( 0x86, 0x03 ); // STX $03 cpu.X = 0xea; @@ -433,6 +444,7 @@ START_TEST( test_cpu_6502_stx_addr_zero ) ck_assert_mem_eq( &ram.cell[0x0], &before_ram.cell[0x0], 3 ); ck_assert_int_eq( ram.cell[0x03], 0xea ); ck_assert_mem_eq( &ram.cell[0x04], &before_ram.cell[0x04], 0x1FF - 0x03 ); + ck_assert_int_eq( cpu.cycles, 3 ); DEINIT_CPU_TEST } @@ -462,6 +474,7 @@ START_TEST( test_cpu_6502_stx_addr_abs ) ck_assert_mem_eq( &ram.cell[0x0], &before_ram.cell[0x0], 0x102 ); ck_assert_int_eq( ram.cell[0x0103], 0xea ); // modified value in memory ck_assert_mem_eq( &ram.cell[0x104], &before_ram.cell[0x104], 0x1FF - 0x103 ); + ck_assert_int_eq( cpu.cycles, 4 ); DEINIT_CPU_TEST } @@ -495,6 +508,7 @@ START_TEST( test_cpu_6502_inc_flags_positive ) ck_assert_mem_eq( &ram.cell[0x0], &before_ram.cell[0x0], 0x21 ); ck_assert_int_eq( ram.cell[0x22], 0x52 ); // modified value in memory ck_assert_mem_eq( &ram.cell[0x23], &before_ram.cell[0x23], 0x1FF - 0x23 ); + ck_assert_int_eq( cpu.cycles, 5 ); DEINIT_CPU_TEST } @@ -526,6 +540,7 @@ START_TEST( test_cpu_6502_inc_flags_negative ) ck_assert_mem_eq( &ram.cell[0x0], &before_ram.cell[0x0], 0x21 ); ck_assert_int_eq( ram.cell[0x22], 0xf2 ); // modified value in memory ck_assert_mem_eq( &ram.cell[0x23], &before_ram.cell[0x23], 0x1FF - 0x23 ); + ck_assert_int_eq( cpu.cycles, 5 ); DEINIT_CPU_TEST } @@ -557,6 +572,7 @@ START_TEST( test_cpu_6502_inc_flags_zero ) ck_assert_mem_eq( &ram.cell[0x0], &before_ram.cell[0x0], 0x21 ); ck_assert_int_eq( ram.cell[0x22], 0x00 ); // modified value in memory ck_assert_mem_eq( &ram.cell[0x23], &before_ram.cell[0x23], 0x1FF - 0x23 ); + ck_assert_int_eq( cpu.cycles, 5 ); DEINIT_CPU_TEST } @@ -588,6 +604,7 @@ START_TEST( test_cpu_6502_inx_flags_positive ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, 0x35 ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -617,6 +634,7 @@ START_TEST( test_cpu_6502_inx_flags_negative ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, 0xf7 ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -646,6 +664,7 @@ START_TEST( test_cpu_6502_inx_flags_zero ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, 0x00 ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -677,6 +696,7 @@ START_TEST( test_cpu_6502_dex_flags_positive ) ck_assert_int_eq( cpu.X, 0x55 ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -706,6 +726,7 @@ START_TEST( test_cpu_6502_dex_flags_negative ) ck_assert_int_eq( cpu.X, 0x92 ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -735,6 +756,7 @@ START_TEST( test_cpu_6502_dex_flags_zero ) ck_assert_int_eq( cpu.X, 0x00 ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -766,6 +788,7 @@ START_TEST( test_cpu_6502_dey_flags_positive ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, 0x55 ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -795,6 +818,7 @@ START_TEST( test_cpu_6502_dey_flags_negative ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, 0x92 ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -824,6 +848,7 @@ START_TEST( test_cpu_6502_dey_flags_zero ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, 0x00 ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -857,6 +882,7 @@ START_TEST( test_cpu_6502_rol_flags_accumulator_carry ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -889,6 +915,7 @@ START_TEST( test_cpu_6502_cpx_flags_equals ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -919,6 +946,7 @@ START_TEST( test_cpu_6502_cpx_flags_less ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -949,6 +977,7 @@ START_TEST( test_cpu_6502_cpx_flags_greater ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -978,6 +1007,7 @@ START_TEST( test_cpu_6502_bcc_carry_clear ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 3 ); DEINIT_CPU_TEST } @@ -1005,6 +1035,65 @@ START_TEST( test_cpu_6502_bcc_carry_set ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); + + DEINIT_CPU_TEST +} +END_TEST + +// BCS + +START_TEST( test_cpu_6502_bcs_carry_set ) +{ + INIT_CPU_TEST + + CODE_SET2( 0xb0, 0x12 ); // BCS $12 + + cpu.PS |= PS_C; + + COPY_CPU_TEST + + cpu_6502_run_steps( &cpu, 1 ); + + PRINT_CPU_TEST + + ck_assert_int_eq( cpu.error_state, ERROR_STATE_OK ); + ck_assert_int_eq( cpu.PC, before_cpu.PC + 2 + 0x12 ); // carry is set, jump taken + ck_assert_int_eq( cpu.SP, before_cpu.SP ); + ck_assert_int_eq( cpu.PS, before_cpu.PS ); + ck_assert_int_eq( cpu.A, before_cpu.A ); + ck_assert_int_eq( cpu.X, before_cpu.X ); + ck_assert_int_eq( cpu.Y, before_cpu.Y ); + ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 3 ); + + DEINIT_CPU_TEST +} +END_TEST + +START_TEST( test_cpu_6502_bcs_carry_clear ) +{ + INIT_CPU_TEST + + CODE_SET2( 0xb0, 0x12 ); // BCS $12 + + cpu.PS &= ~PS_C; + + COPY_CPU_TEST + + cpu_6502_run_steps( &cpu, 1 ); + + PRINT_CPU_TEST + + ck_assert_int_eq( cpu.error_state, ERROR_STATE_OK ); + ck_assert_int_eq( cpu.PC, before_cpu.PC+2 ); // carry is clear, execute next opcode, don't jump + ck_assert_int_eq( cpu.SP, before_cpu.SP ); + ck_assert_int_eq( cpu.PS, before_cpu.PS ); + ck_assert_int_eq( cpu.A, before_cpu.A ); + ck_assert_int_eq( cpu.X, before_cpu.X ); + ck_assert_int_eq( cpu.Y, before_cpu.Y ); + ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -1034,6 +1123,7 @@ START_TEST( test_cpu_6502_bne_zero_clear ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 3 ); DEINIT_CPU_TEST } @@ -1061,6 +1151,7 @@ START_TEST( test_cpu_6502_bne_zero_set ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 2 ); DEINIT_CPU_TEST } @@ -1088,6 +1179,7 @@ START_TEST( test_cpu_6502_jmp_abs ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 3 ); DEINIT_CPU_TEST } @@ -1119,6 +1211,7 @@ START_TEST( test_cpu_6502_jsr_abs ) ck_assert_mem_eq( &ram.cell[0x0], &before_ram.cell[0x0], 0x1fd ); ck_assert_int_eq( ram.cell[0x01fe], 0x02 ); // next PC after return on stack ck_assert_int_eq( ram.cell[0x01ff], 0xf8 ); + ck_assert_int_eq( cpu.cycles, 6 ); DEINIT_CPU_TEST } @@ -1150,6 +1243,7 @@ START_TEST( test_cpu_6502_rts ) ck_assert_int_eq( cpu.X, before_cpu.X ); ck_assert_int_eq( cpu.Y, before_cpu.Y ); ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size ); + ck_assert_int_eq( cpu.cycles, 6 ); DEINIT_CPU_TEST } @@ -1202,6 +1296,8 @@ static Suite *make_cpu_6502_testsuite( void ) create_cpu_6502_testcase( suite, "CPX (flags, greater)", test_cpu_6502_cpx_flags_greater ); create_cpu_6502_testcase( suite, "BCC (branch taken, carry clear)", test_cpu_6502_bcc_carry_clear ); create_cpu_6502_testcase( suite, "BCC (branch not taken, carry set)", test_cpu_6502_bcc_carry_set ); + create_cpu_6502_testcase( suite, "BCS (branch taken, carry set)", test_cpu_6502_bcs_carry_set ); + create_cpu_6502_testcase( suite, "BCS (branch not taken, carry clear)", test_cpu_6502_bcs_carry_clear ); create_cpu_6502_testcase( suite, "BNE (branch not taken, zero clear)", test_cpu_6502_bne_zero_clear ); create_cpu_6502_testcase( suite, "BNE (branch taken, zero set)", test_cpu_6502_bne_zero_set ); create_cpu_6502_testcase( suite, "JMP (absolute)", test_cpu_6502_jmp_abs ); -- cgit v1.2.3-54-g00ecf