1
0
mirror of https://github.com/jborza/emu6502.git synced 2024-06-06 23:29:31 +00:00

JMP + tests, PHP_PLP tests

This commit is contained in:
jborza 2019-04-17 19:46:56 +02:00
parent 4b691d3414
commit 285bb840af
2 changed files with 166 additions and 14 deletions

20
cpu.c
View File

@ -120,6 +120,10 @@ void EOR(State6502 * state, byte operand) {
set_NV_flags(state, state->a);
}
void JMP(State6502 * state, word address) {
state->pc = address;
}
word pop_word(State6502 * state) {
byte low = pop_byte(state);
byte high = pop_byte(state);
@ -193,6 +197,18 @@ byte get_byte_absolute_y(State6502 * state) {
return state->memory[get_address_absolute_y(state)];
}
word get_address_indirect_jmp(State6502 * state) {
//AN INDIRECT JUMP MUST NEVER USE A VECTOR BEGINNING ON THE LAST BYTE OF A PAGE
word indirect_address = pop_word(state);
if ((indirect_address & 0xFF) == 0xFF) {
//avoid crossing the page boundary
return state->memory[indirect_address] | state->memory[indirect_address + 1 - 0xFF] << 8;
}
else {
return read_word(state, indirect_address);
}
}
word get_address_indirect_x(State6502 * state) {
//pre-indexed indirect with the X register
//zero-page address is added to x register
@ -320,8 +336,8 @@ int emulate_6502_op(State6502 * state) {
case INC_ZPX: INC(state, get_address_zero_page_x(state)); break;
case INC_ABS: INC(state, get_address_absolute(state)); break;
case INC_ABSX: INC(state, get_address_absolute_x(state)); break;
case JMP_ABS: unimplemented_instruction(state); break;
case JMP_IND: unimplemented_instruction(state); break;
case JMP_ABS: JMP(state, get_address_absolute(state)); break;
case JMP_IND: JMP(state, get_address_indirect_jmp(state)); break;
case JSR_ABS: unimplemented_instruction(state); break;
case LDA_IMM: LDA(state, pop_byte(state)); break;
case LDA_ZP: LDA(state, get_byte_zero_page(state)); break;

View File

@ -54,7 +54,7 @@ State6502 create_blank_state() {
return state;
}
void assert_register(State6502* state, byte expected, byte actual, char* name) {
void assert_register(State6502 * state, byte expected, byte actual, char* name) {
if (actual != expected) {
printf("Unexpected value in %s, expected %02X, was %02X", name, expected, actual);
exit(1);
@ -73,10 +73,17 @@ void assertY(State6502 * state, byte expected) {
assert_register(state, expected, state->y, "Y");
}
void assert_sp(State6502* state, byte expected) {
void assert_sp(State6502 * state, byte expected) {
assert_register(state, expected, state->sp, "SP");
}
void assert_pc(State6502 * state, word expected) {
if (state->pc != expected) {
printf("Unexpected value in SP, expected %02X, was %02X", expected, state->pc);
exit(1);
}
}
//assert_memory(&state, 0xFF, 0x99)
void assert_memory(State6502 * state, word address, byte expected) {
if (state->memory[address] != expected) {
@ -99,28 +106,35 @@ void assert_flag_z(State6502 * state, byte expected) {
}
}
void assert_flag_c(State6502* state, byte expected) {
void assert_flag_c(State6502 * state, byte expected) {
if (state->flags.c != expected) {
printf("Unexpected value in flag C, expected %d, was %d", expected, state->flags.c);
exit(1);
}
}
void assert_flag_i(State6502* state, byte expected) {
void assert_flag_i(State6502 * state, byte expected) {
if (state->flags.i != expected) {
printf("Unexpected value in flag I, expected %d, was %d", expected, state->flags.i);
exit(1);
}
}
void assert_flag_d(State6502* state, byte expected) {
void assert_flag_d(State6502 * state, byte expected) {
if (state->flags.d != expected) {
printf("Unexpected value in flag D, expected %d, was %d", expected, state->flags.d);
exit(1);
}
}
void assert_flag_v(State6502* state, byte expected) {
void assert_flag_v(State6502 * state, byte expected) {
if (state->flags.v != expected) {
printf("Unexpected value in flag D, expected %d, was %d", expected, state->flags.v);
exit(1);
}
}
void assert_flag_b(State6502* state, byte expected) {
if (state->flags.v != expected) {
printf("Unexpected value in flag D, expected %d, was %d", expected, state->flags.v);
exit(1);
@ -459,7 +473,7 @@ void test_ORA_INDY() {
state.a = 0x0A;
//arrange
char program[] = { ORA_INDY, 0x3E}; //ORA ($3E),y
char program[] = { ORA_INDY, 0x3E }; //ORA ($3E),y
memcpy(state.memory, program, sizeof(program));
state.memory[0x3E] = 0xA0; //0x04A0
state.memory[0x3F] = 0x04;
@ -793,7 +807,7 @@ void test_AND_INDY() {
state.a = 0xAA;
//arrange
char program[] = { AND_INDY, 0x3E}; //AND ($3E),y
char program[] = { AND_INDY, 0x3E }; //AND ($3E),y
memcpy(state.memory, program, sizeof(program));
state.memory[0x3E] = 0xA0; //0x04A0
state.memory[0x3F] = 0x04;
@ -1437,7 +1451,7 @@ void test_DEC_ZP_wraparound() {
void test_SEC() {
State6502 state = create_blank_state();
char program[] = { SEC };
memcpy(state.memory, program, sizeof(program));
test_step(&state);
@ -1626,7 +1640,7 @@ void test_STA_INDX() {
state.x = 0x05;
//arrange
char program[] = { STA_INDX, 0x3E}; //STA ($3E,x)
char program[] = { STA_INDX, 0x3E }; //STA ($3E,x)
memcpy(state.memory, program, sizeof(program));
state.memory[0x43] = 0x01;
state.memory[0x44] = 0x04;
@ -1672,7 +1686,7 @@ void test_PHA() {
state.sp = 0xFF;
//arrange
char program[] = { PHA };
char program[] = { PHA };
memcpy(state.memory, program, sizeof(program));
//act
@ -1712,7 +1726,7 @@ void test_PHA_PLA() {
State6502 state = create_blank_state();
//arrange
char program[] = { LDX_IMM, 0xFF, TXS, LDA_IMM, 0xAA, PHA, LDY_IMM, 0xBB, TYA, PHA, TXA, PHA };
char program[] = { LDX_IMM, 0xFF, TXS, LDA_IMM, 0xAA, PHA, LDY_IMM, 0xBB, TYA, PHA, TXA, PHA };
memcpy(state.memory, program, sizeof(program));
//act
@ -1757,6 +1771,124 @@ void test_TSX() {
test_cleanup(&state);
}
// PHP, PLP
void test_PHP() {
//initialize
State6502 state = create_blank_state();
state.flags.c = 1;
state.flags.b = 1;
state.flags.z = 1;
state.flags.n = 1;
state.flags.d = 1;
state.flags.i = 1;
state.flags.v = 1;
state.sp = 0xFF;
//arrange
char program[] = { PHP };
memcpy(state.memory, program, sizeof(program));
//act
test_step(&state);
//assert
assert_sp(&state, 0xFE);
assert_memory(&state, 0x1FF, 0xFF);
//cleanup
test_cleanup(&state);
}
void test_PLP() {
State6502 state = create_blank_state();
state.sp = 0xFE;
//arrange
char program[] = { PLP };
memcpy(state.memory, program, sizeof(program));
//act
test_step(&state);
//assert
assert_sp(&state, 0xFF);
assert_flag_c(&state, 1);
assert_flag_d(&state, 1);
assert_flag_b(&state, 1);
assert_flag_z(&state, 1);
assert_flag_v(&state, 1);
assert_flag_n(&state, 1);
assert_flag_i(&state, 1);
//cleanup
test_cleanup(&state);
}
//// JMP
void test_JMP() {
//initialize
State6502 state = create_blank_state();
//arrange
char program[] = { JMP_ABS, 0x04, 0x03 };
memcpy(state.memory, program, sizeof(program));
//act
test_step(&state);
//assert
assert_pc(&state, 0x0304);
//cleanup
test_cleanup(&state);
}
void test_JMP_IND() {
//initialize
State6502 state = create_blank_state();
//arrange
char program[] = { JMP_IND, 0xFF, 0x02 };
memcpy(state.memory, program, sizeof(program));
state.memory[0x02FF] = 0x01;
state.memory[0x0200] = 0xAA;
state.memory[0x01AA] = 0xFF; //target
//NOT state.memory[0x03FF] ! as there is no wrap
//act
test_step(&state);
//assert
assert_pc(&state, 0x1AA);
//cleanup
test_cleanup(&state);
}
void test_JMP_IND_wrap() {
//initialize
State6502 state = create_blank_state();
//arrange
char program[] = { JMP_IND, 0xFF, 0x02 };
memcpy(state.memory, program, sizeof(program));
state.memory[0x02FF] = 0x01;
state.memory[0x0200] = 0xAA;
state.memory[0x01AA] = 0xFF; //target
//NOT state.memory[0x03FF] ! as there is no wrap
//act
test_step(&state);
//assert
assert_pc(&state, 0x1AA);
//cleanup
test_cleanup(&state);
}
/////////////////////
typedef void fp();
@ -1775,6 +1907,8 @@ fp* tests_eor[] = { test_EOR_IMM, test_EOR_ZP, test_EOR_ZPX, test_EOR_ABS, test_
fp* tests_sta[] = { test_STA_ZP, test_STA_ZPX, test_STA_ABS, test_STA_ABSX, test_STA_ABSY, test_STA_INDX, test_STA_INDY };
fp* tests_pha_pla[] = { test_PHA, test_PLA, test_PHA_PLA };
fp* tests_txs_tsx[] = { test_TXS, test_TSX };
fp* tests_php_plp[] = { test_PHP, test_PLP };
fp* tests_jmp[] = { test_JMP, test_JMP_IND };
#define RUN(suite) run_suite(suite, sizeof(suite)/sizeof(fp*))
@ -1800,4 +1934,6 @@ void run_tests() {
RUN(tests_sta);
RUN(tests_pha_pla);
RUN(tests_txs_tsx);
RUN(tests_jmp);
RUN(tests_php_plp);
}