summaryrefslogtreecommitdiff
path: root/emu
diff options
context:
space:
mode:
authorAndreas Baumann <mail@andreasbaumann.cc>2020-12-20 19:22:06 +0100
committerAndreas Baumann <mail@andreasbaumann.cc>2020-12-20 19:22:06 +0100
commit27ccbbb488ce6873a72e64b097f88066123efe9c (patch)
treec983993e8eadc9bedce594964eb7322343eab5b0 /emu
parent5ba99092da61aa6aeaa91214ca18c8cf03356913 (diff)
download6502-27ccbbb488ce6873a72e64b097f88066123efe9c.tar.gz
6502-27ccbbb488ce6873a72e64b097f88066123efe9c.tar.bz2
cleanup and more tests
Diffstat (limited to 'emu')
-rw-r--r--emu/tests/test_cpu_6502.c579
1 files changed, 482 insertions, 97 deletions
diff --git a/emu/tests/test_cpu_6502.c b/emu/tests/test_cpu_6502.c
index 396c671..86fcc60 100644
--- a/emu/tests/test_cpu_6502.c
+++ b/emu/tests/test_cpu_6502.c
@@ -48,29 +48,61 @@ void teardown( void )
bus_deinit( &bus );
}
-START_TEST( test_cpu_6502_nop )
-{
- cpu_6502_t before_cpu;
- memory_t before_ram;
-
- cpu_6502_reset( &cpu );
- memory_reset( &rom );
+#define INIT_CPU_TEST \
+ cpu_6502_reset( &cpu ); \
+ memory_reset( &rom ); \
memory_reset( &ram );
- memset( code, 0, ROM_SIZE );
- code[0] = 0xea; // NOP
- codesize = 1;
+#define COPY_CPU_TEST \
+ cpu_6502_t before_cpu; \
+ memory_t before_ram; \
+ \
+ memcpy( &before_cpu, &cpu, sizeof( cpu ) ); \
+ memory_copy( &before_ram, &ram );
+
+#define DEINIT_CPU_TEST \
+ memory_deinit( &before_ram );
+
+#define PRINT_CPU_TEST \
+ fprintf( stderr, "state before:\n" ); \
+ cpu_6502_print_debug( &before_cpu ); \
+ fprintf( stderr, "state after:\n" ); \
+ cpu_6502_print_debug( &cpu );
+
+#define CODE_SET1( op1 ) \
+ memset( code, 0, ROM_SIZE ); \
+ code[0] = op1; \
+ codesize = 1; \
+ memory_set( &rom, 0x00, code, codesize );
+
+#define CODE_SET2( op1, op2 ) \
+ memset( code, 0, ROM_SIZE ); \
+ code[0] = op1; \
+ code[1] = op2; \
+ codesize = 2; \
memory_set( &rom, 0x00, code, codesize );
+
+#define CODE_SET3( op1, op2, op3 ) \
+ memset( code, 0, ROM_SIZE ); \
+ code[0] = op1; \
+ code[1] = op2; \
+ code[2] = op3; \
+ codesize = 3; \
+ memory_set( &rom, 0x00, code, codesize );
+
+// NOP
- memcpy( &before_cpu, &cpu, sizeof( cpu ) );
- memory_copy( &before_ram, &ram );
+START_TEST( test_cpu_6502_nop )
+{
+ INIT_CPU_TEST
+
+ CODE_SET1( 0xea ); // NOP
+ COPY_CPU_TEST
+
cpu_6502_run( &cpu, 1 );
- fprintf( stderr, "state before:\n" );
- cpu_6502_print_debug( &before_cpu );
- fprintf( stderr, "state after:\n" );
- cpu_6502_print_debug( &cpu );
+ PRINT_CPU_TEST
ck_assert_int_eq( cpu.error_state, ERROR_STATE_OK );
ck_assert_int_eq( cpu.PC, before_cpu.PC+1 );
@@ -81,35 +113,25 @@ START_TEST( test_cpu_6502_nop )
ck_assert_int_eq( cpu.Y, before_cpu.Y );
ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size );
- memory_deinit( &before_ram );
+ DEINIT_CPU_TEST
}
END_TEST
+// TXS
+
START_TEST( test_cpu_6502_txs )
{
- cpu_6502_t before_cpu;
- memory_t before_ram;
-
- cpu_6502_reset( &cpu );
- memory_reset( &rom );
- memory_reset( &ram );
+ INIT_CPU_TEST
- memset( code, 0, ROM_SIZE );
- code[0] = 0x9a; // TXS
- codesize = 1;
- memory_set( &rom, 0x00, code, codesize );
+ CODE_SET1( 0x9a ); // TXS
cpu.X = 0xff;
-
- memcpy( &before_cpu, &cpu, sizeof( cpu ) );
- memory_copy( &before_ram, &ram );
+ COPY_CPU_TEST
+
cpu_6502_run( &cpu, 1 );
-
- fprintf( stderr, "state before:\n" );
- cpu_6502_print_debug( &before_cpu );
- fprintf( stderr, "state after:\n" );
- cpu_6502_print_debug( &cpu );
+
+ PRINT_CPU_TEST
ck_assert_int_eq( cpu.error_state, ERROR_STATE_OK );
ck_assert_int_eq( cpu.PC, before_cpu.PC+1 );
@@ -120,76 +142,226 @@ START_TEST( test_cpu_6502_txs )
ck_assert_int_eq( cpu.Y, before_cpu.Y );
ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size );
- memory_deinit( &before_ram );
+ DEINIT_CPU_TEST
}
END_TEST
-START_TEST( test_cpu_6502_ldx_pos )
+// LDA
+
+START_TEST( test_cpu_6502_lda_flags_positive )
{
- cpu_6502_t before_cpu;
- memory_t before_ram;
+ INIT_CPU_TEST
+
+ CODE_SET2( 0xa9, 0x01 ); // LDA #$1
- cpu_6502_reset( &cpu );
- memory_reset( &rom );
- memory_reset( &ram );
+ cpu.A = 0xff;
- memset( code, 0, ROM_SIZE );
- code[0] = 0xa2; // LDX immediate
- code[1] = 0x01; // #$1
- codesize = 2;
- memory_set( &rom, 0x00, code, codesize );
+ COPY_CPU_TEST
- cpu.X = 0xff;
+ cpu_6502_run( &cpu, 1 );
+
+ PRINT_CPU_TEST
- memcpy( &before_cpu, &cpu, sizeof( cpu ) );
- memory_copy( &before_ram, &ram );
+ ck_assert_int_eq( cpu.error_state, ERROR_STATE_OK );
+ ck_assert_int_eq( cpu.PC, before_cpu.PC+2 );
+ ck_assert_int_eq( cpu.SP, before_cpu.SP );
+ ck_assert_int_eq( cpu.PS & ~( PS_N | PS_Z ), before_cpu.PS & ~( PS_N | PS_Z ) );
+ ck_assert( !cpu_6502_is_zero( &cpu ) );
+ ck_assert( !cpu_6502_is_negative( &cpu ) );
+ ck_assert_int_eq( cpu.A, 0x01 );
+ 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 );
+
+ DEINIT_CPU_TEST
+}
+END_TEST
+
+START_TEST( test_cpu_6502_lda_flags_negative )
+{
+ INIT_CPU_TEST
+
+ CODE_SET2( 0xa9, 0xff ); // LDA #-1
+
+ COPY_CPU_TEST
cpu_6502_run( &cpu, 1 );
- fprintf( stderr, "state before:\n" );
- cpu_6502_print_debug( &before_cpu );
- fprintf( stderr, "state after:\n" );
- cpu_6502_print_debug( &cpu );
+ PRINT_CPU_TEST
ck_assert_int_eq( cpu.error_state, ERROR_STATE_OK );
ck_assert_int_eq( cpu.PC, before_cpu.PC+2 );
ck_assert_int_eq( cpu.SP, before_cpu.SP );
ck_assert_int_eq( cpu.PS & ~( PS_N | PS_Z ), before_cpu.PS & ~( PS_N | PS_Z ) );
ck_assert( !cpu_6502_is_zero( &cpu ) );
+ ck_assert( cpu_6502_is_negative( &cpu ) );
+ ck_assert_int_eq( cpu.A, 0xff );
+ 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 );
+
+ DEINIT_CPU_TEST
+}
+END_TEST
+
+START_TEST( test_cpu_6502_lda_flags_zero )
+{
+ INIT_CPU_TEST
+
+ CODE_SET2( 0xa9, 0x0 ); // LDA #$0
+
+ cpu.A = 0xff;
+
+ COPY_CPU_TEST
+
+ cpu_6502_run( &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 );
+ ck_assert_int_eq( cpu.SP, before_cpu.SP );
+ ck_assert_int_eq( cpu.PS & ~( PS_N | PS_Z ), before_cpu.PS & ~( PS_N | PS_Z ) );
+ ck_assert( cpu_6502_is_zero( &cpu ) );
+ ck_assert( !cpu_6502_is_negative( &cpu ) );
+ ck_assert_int_eq( cpu.A, 0x00 );
+ 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 );
+
+ DEINIT_CPU_TEST
+}
+END_TEST
+
+// LDY
+
+START_TEST( test_cpu_6502_ldy_flags_positive )
+{
+ INIT_CPU_TEST
+
+ CODE_SET2( 0xa0, 0x01 ); // LDY #$1
+
+ cpu.Y = 0xff;
+
+ COPY_CPU_TEST
+
+ cpu_6502_run( &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 );
+ ck_assert_int_eq( cpu.SP, before_cpu.SP );
+ ck_assert_int_eq( cpu.PS & ~( PS_N | PS_Z ), before_cpu.PS & ~( PS_N | PS_Z ) );
+ ck_assert( !cpu_6502_is_zero( &cpu ) );
+ ck_assert( !cpu_6502_is_negative( &cpu ) );
+ ck_assert_int_eq( cpu.A, before_cpu.A );
+ 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 );
+
+ DEINIT_CPU_TEST
+}
+END_TEST
+
+START_TEST( test_cpu_6502_ldy_flags_negative )
+{
+ INIT_CPU_TEST
+
+ CODE_SET2( 0xa0, 0xff ); // LDY #-1
+
+ COPY_CPU_TEST
+
+ cpu_6502_run( &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 );
+ ck_assert_int_eq( cpu.SP, before_cpu.SP );
+ ck_assert_int_eq( cpu.PS & ~( PS_N | PS_Z ), before_cpu.PS & ~( PS_N | PS_Z ) );
+ ck_assert( !cpu_6502_is_zero( &cpu ) );
+ ck_assert( cpu_6502_is_negative( &cpu ) );
+ ck_assert_int_eq( cpu.A, before_cpu.A );
+ 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 );
+
+ DEINIT_CPU_TEST
+}
+END_TEST
+
+START_TEST( test_cpu_6502_ldy_flags_zero )
+{
+ INIT_CPU_TEST
+
+ CODE_SET2( 0xa0, 0x0 ); // LDY #$0
+
+ cpu.Y = 0xff;
+
+ COPY_CPU_TEST
+
+ cpu_6502_run( &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 );
+ ck_assert_int_eq( cpu.SP, before_cpu.SP );
+ ck_assert_int_eq( cpu.PS & ~( PS_N | PS_Z ), before_cpu.PS & ~( PS_N | PS_Z ) );
+ ck_assert( cpu_6502_is_zero( &cpu ) );
+ ck_assert( !cpu_6502_is_negative( &cpu ) );
+ ck_assert_int_eq( cpu.A, before_cpu.A );
+ 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 );
+
+ DEINIT_CPU_TEST
+}
+END_TEST
+
+// LDX
+
+START_TEST( test_cpu_6502_ldx_flags_positive )
+{
+ INIT_CPU_TEST
+
+ CODE_SET2( 0xa2, 0x01 ); // LDX #$1
+
+ cpu.X = 0xff;
+
+ COPY_CPU_TEST
+
+ cpu_6502_run( &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 );
+ ck_assert_int_eq( cpu.SP, before_cpu.SP );
+ ck_assert_int_eq( cpu.PS & ~( PS_N | PS_Z ), before_cpu.PS & ~( PS_N | PS_Z ) );
+ ck_assert( !cpu_6502_is_zero( &cpu ) );
ck_assert( !cpu_6502_is_negative( &cpu ) );
ck_assert_int_eq( cpu.A, before_cpu.A );
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 );
- memory_deinit( &before_ram );
+ DEINIT_CPU_TEST
}
END_TEST
-START_TEST( test_cpu_6502_ldx_neg )
+START_TEST( test_cpu_6502_ldx_flags_negative )
{
- cpu_6502_t before_cpu;
- memory_t before_ram;
+ INIT_CPU_TEST
- cpu_6502_reset( &cpu );
- memory_reset( &rom );
- memory_reset( &ram );
+ CODE_SET2( 0xa2, 0xff ); // LDX #-1
- memset( code, 0, ROM_SIZE );
- code[0] = 0xa2; // LDX immediate
- code[1] = 0xff; // #-1
- codesize = 2;
- memory_set( &rom, 0x00, code, codesize );
-
- memcpy( &before_cpu, &cpu, sizeof( cpu ) );
- memory_copy( &before_ram, &ram );
+ COPY_CPU_TEST
cpu_6502_run( &cpu, 1 );
- fprintf( stderr, "state before:\n" );
- cpu_6502_print_debug( &before_cpu );
- fprintf( stderr, "state after:\n" );
- cpu_6502_print_debug( &cpu );
+ PRINT_CPU_TEST
ck_assert_int_eq( cpu.error_state, ERROR_STATE_OK );
ck_assert_int_eq( cpu.PC, before_cpu.PC+2 );
@@ -202,36 +374,23 @@ START_TEST( test_cpu_6502_ldx_neg )
ck_assert_int_eq( cpu.Y, before_cpu.Y );
ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size );
- memory_deinit( &before_ram );
+ DEINIT_CPU_TEST
}
END_TEST
-START_TEST( test_cpu_6502_ldx_zero )
+START_TEST( test_cpu_6502_ldx_flags_zero )
{
- cpu_6502_t before_cpu;
- memory_t before_ram;
+ INIT_CPU_TEST
- cpu_6502_reset( &cpu );
- memory_reset( &rom );
- memory_reset( &ram );
-
- memset( code, 0, ROM_SIZE );
- code[0] = 0xa2; // LDX immediate
- code[1] = 0x00; // #$0
- codesize = 2;
- memory_set( &rom, 0x00, code, codesize );
+ CODE_SET2( 0xa2, 0x0 ); // LDX #$0
cpu.X = 0xff;
- memcpy( &before_cpu, &cpu, sizeof( cpu ) );
- memory_copy( &before_ram, &ram );
-
+ COPY_CPU_TEST
+
cpu_6502_run( &cpu, 1 );
- fprintf( stderr, "state before:\n" );
- cpu_6502_print_debug( &before_cpu );
- fprintf( stderr, "state after:\n" );
- cpu_6502_print_debug( &cpu );
+ PRINT_CPU_TEST
ck_assert_int_eq( cpu.error_state, ERROR_STATE_OK );
ck_assert_int_eq( cpu.PC, before_cpu.PC+2 );
@@ -244,7 +403,220 @@ START_TEST( test_cpu_6502_ldx_zero )
ck_assert_int_eq( cpu.Y, before_cpu.Y );
ck_assert_mem_eq( ram.cell, before_ram.cell, ram.size );
- memory_deinit( &before_ram );
+ DEINIT_CPU_TEST
+}
+END_TEST
+
+// STX
+
+START_TEST( test_cpu_6502_stx_addr_zero )
+{
+ INIT_CPU_TEST
+
+ CODE_SET2( 0x86, 0x03 ); // STX #$03
+
+ cpu.X = 0xea;
+
+ COPY_CPU_TEST
+
+ cpu_6502_run( &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 );
+ 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[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 );
+
+ DEINIT_CPU_TEST
+}
+END_TEST
+
+START_TEST( test_cpu_6502_stx_addr_abs )
+{
+ INIT_CPU_TEST
+
+ CODE_SET3( 0x8e, 0x03, 0x01 ); // STX #$0103
+
+ cpu.X = 0xea;
+
+ COPY_CPU_TEST
+
+ cpu_6502_run( &cpu, 1 );
+
+ PRINT_CPU_TEST
+
+ ck_assert_int_eq( cpu.error_state, ERROR_STATE_OK );
+ ck_assert_int_eq( cpu.PC, before_cpu.PC+3 );
+ 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[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 );
+
+ DEINIT_CPU_TEST
+}
+END_TEST
+
+// INC
+
+START_TEST( test_cpu_6502_inc_flags_positive )
+{
+ INIT_CPU_TEST
+
+ CODE_SET2( 0xe6, 0x22 ); // INC $22
+
+ ram.cell[0x22] = 0x51;
+
+ COPY_CPU_TEST
+
+ cpu_6502_run( &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 );
+ ck_assert_int_eq( cpu.SP, before_cpu.SP );
+ ck_assert_int_eq( cpu.PS & ~( PS_N | PS_Z ), before_cpu.PS & ~( PS_N | PS_Z ) );
+ ck_assert( !cpu_6502_is_zero( &cpu ) );
+ ck_assert( !cpu_6502_is_negative( &cpu ) );
+ 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[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 );
+
+ DEINIT_CPU_TEST
+}
+END_TEST
+
+START_TEST( test_cpu_6502_inc_flags_negative )
+{
+ INIT_CPU_TEST
+
+ CODE_SET2( 0xe6, 0x22 ); // INC $22
+
+ ram.cell[0x22] = 0xf1;
+
+ COPY_CPU_TEST
+
+ cpu_6502_run( &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 );
+ ck_assert_int_eq( cpu.SP, before_cpu.SP );
+ ck_assert_int_eq( cpu.PS & ~( PS_N | PS_Z ), before_cpu.PS & ~( PS_N | PS_Z ) );
+ ck_assert( !cpu_6502_is_zero( &cpu ) );
+ ck_assert( cpu_6502_is_negative( &cpu ) );
+ 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[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 );
+
+ DEINIT_CPU_TEST
+}
+END_TEST
+
+START_TEST( test_cpu_6502_inc_flags_zero )
+{
+ INIT_CPU_TEST
+
+ CODE_SET2( 0xe6, 0x22 ); // INC $22
+
+ ram.cell[0x22] = 0xff;
+
+ COPY_CPU_TEST
+
+ cpu_6502_run( &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 );
+ ck_assert_int_eq( cpu.SP, before_cpu.SP );
+ ck_assert_int_eq( cpu.PS & ~( PS_N | PS_Z ), before_cpu.PS & ~( PS_N | PS_Z ) );
+ ck_assert( cpu_6502_is_zero( &cpu ) );
+ ck_assert( !cpu_6502_is_negative( &cpu ) );
+ 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[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 );
+
+ DEINIT_CPU_TEST
+}
+END_TEST
+
+// JMP
+
+START_TEST( test_cpu_6502_jmp_abs )
+{
+ INIT_CPU_TEST
+
+ CODE_SET3( 0x4c, 0x0c, 0xf8 ); // JMP $f80c
+
+ COPY_CPU_TEST
+
+ cpu_6502_run( &cpu, 1 );
+
+ PRINT_CPU_TEST
+
+ ck_assert_int_eq( cpu.error_state, ERROR_STATE_OK );
+ ck_assert_int_eq( cpu.PC, 0xf80c ); // jump destination is next operation to process
+ 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 );
+
+ DEINIT_CPU_TEST
+}
+END_TEST
+
+// JSR
+
+START_TEST( test_cpu_6502_jsr_abs )
+{
+ INIT_CPU_TEST
+
+ CODE_SET3( 0x20, 0x1f, 0xf8 ); // JSR $f81f
+
+ cpu.SP = 0xff;
+
+ COPY_CPU_TEST
+
+ cpu_6502_run( &cpu, 1 );
+
+ PRINT_CPU_TEST
+
+ ck_assert_int_eq( cpu.error_state, ERROR_STATE_OK );
+ ck_assert_int_eq( cpu.PC, 0xf81f ); // jump destination is next operation to process
+ ck_assert_int_eq( cpu.SP, before_cpu.SP-2 ); // return address/2 bytes on stack
+ 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[0x0], &before_ram.cell[0x0], 0x1FF - 2 );
+ ck_assert_int_eq( ram.cell[0x01fe], 0x02 ); // next PC after return on stack
+ ck_assert_int_eq( ram.cell[0x01ff], 0xf8 );
+
+ DEINIT_CPU_TEST
}
END_TEST
@@ -266,9 +638,22 @@ static Suite *make_cpu_6502_testsuite( void )
create_cpu_6502_testcase( suite, "NOP", test_cpu_6502_nop );
create_cpu_6502_testcase( suite, "TXS", test_cpu_6502_txs );
- create_cpu_6502_testcase( suite, "LDX (positive)", test_cpu_6502_ldx_pos );
- create_cpu_6502_testcase( suite, "LDX (negative)", test_cpu_6502_ldx_neg );
- create_cpu_6502_testcase( suite, "LDX (zero)", test_cpu_6502_ldx_zero );
+ create_cpu_6502_testcase( suite, "LDA (flags, positive)", test_cpu_6502_lda_flags_positive );
+ create_cpu_6502_testcase( suite, "LDA (flags, negative)", test_cpu_6502_lda_flags_negative );
+ create_cpu_6502_testcase( suite, "LDA (flags, zero)", test_cpu_6502_lda_flags_zero );
+ create_cpu_6502_testcase( suite, "LDX (flags, positive)", test_cpu_6502_ldx_flags_positive );
+ create_cpu_6502_testcase( suite, "LDX (flags, negative)", test_cpu_6502_ldx_flags_negative );
+ create_cpu_6502_testcase( suite, "LDX (flags, zero)", test_cpu_6502_ldx_flags_zero );
+ create_cpu_6502_testcase( suite, "LDY (flags, positive)", test_cpu_6502_ldy_flags_positive );
+ create_cpu_6502_testcase( suite, "LDY (flags, negative)", test_cpu_6502_ldy_flags_negative );
+ create_cpu_6502_testcase( suite, "LDY (flags, zero)", test_cpu_6502_ldy_flags_zero );
+ create_cpu_6502_testcase( suite, "STX (addr, zero)", test_cpu_6502_stx_addr_zero );
+ create_cpu_6502_testcase( suite, "STX (addr, absolute)", test_cpu_6502_stx_addr_abs );
+ create_cpu_6502_testcase( suite, "INC (flags, positive)", test_cpu_6502_inc_flags_positive );
+ create_cpu_6502_testcase( suite, "INC (flags, negative)", test_cpu_6502_inc_flags_negative );
+ create_cpu_6502_testcase( suite, "INC (flags, zero)", test_cpu_6502_inc_flags_zero );
+ create_cpu_6502_testcase( suite, "JMP (absolute)", test_cpu_6502_jmp_abs );
+ create_cpu_6502_testcase( suite, "JSR (absolute)", test_cpu_6502_jsr_abs );
return suite;
}