1
0
mirror of https://github.com/jborza/emu6502.git synced 2024-06-07 16:16:37 +00:00

INC, DEC + tests

This commit is contained in:
jborza 2019-04-15 23:34:21 +02:00
parent 5000f27a0f
commit 99eee8b5f4
2 changed files with 155 additions and 33 deletions

50
cpu.c
View File

@ -24,6 +24,7 @@ void set_NZ_flags(State6502 * state, byte value) {
else {
state->flags.z = 1;
}
printf("setting z flag to %d\n", state->flags.z);
//N flag
state->flags.n = ((1 << 7) & value) != 0;
}
@ -84,6 +85,16 @@ void STY(State6502 * state, word address) {
state->memory[address] = state->y;
}
void INC(State6502 * state, word address) {
state->memory[address] += 1;
set_NZ_flags(state, state->memory[address]);
}
void DEC(State6502 * state, word address) {
state->memory[address] -= 1;
set_NZ_flags(state, state->memory[address]);
}
word pop_word(State6502 * state) {
byte low = pop_byte(state);
byte high = pop_byte(state);
@ -101,8 +112,7 @@ word get_address_zero_page(State6502 * state) {
byte get_byte_zero_page(State6502 * state) {
//8 bit addressing, only the first 256 bytes of the memory
byte address = pop_byte(state);
return state->memory[address];
return state->memory[get_address_zero_page(state)];
}
word get_address_zero_page_x(State6502 * state) {
@ -112,8 +122,7 @@ word get_address_zero_page_x(State6502 * state) {
}
byte get_byte_zero_page_x(State6502 * state) {
byte address = pop_byte(state) + state->x;
return state->memory[address];
return state->memory[get_address_zero_page_x(state)];
}
word get_address_zero_page_y(State6502 * state) {
@ -138,16 +147,25 @@ byte get_byte_absolute(State6502 * state)
return state->memory[get_address_absolute(state)];
}
byte get_byte_absolute_x(State6502 * state) {
word get_address_absolute_x(State6502* state) {
//absolute added with the contents of x register
word address = pop_word(state) + state->x;
return state->memory[address];
return address;
}
byte get_byte_absolute_x(State6502 * state) {
return state->memory[get_address_absolute_x(state)];
}
word get_address_absolute_y(State6502* state) {
//absolute added with the contents of x register
word address = pop_word(state) + state->y;
return address;
}
byte get_byte_absolute_y(State6502 * state) {
//absolute added with the contents of y register
word address = pop_word(state) + state->y;
return state->memory[address];
return state->memory[get_address_absolute_y(state)];
}
byte get_byte_indirect_x(State6502 * state) {
@ -243,10 +261,10 @@ int emulate_6502_op(State6502 * state) {
case CPY_IMM: unimplemented_instruction(state); break;
case CPY_ZP: unimplemented_instruction(state); break;
case CPY_ABS: unimplemented_instruction(state); break;
case DEC_ZP: unimplemented_instruction(state); break;
case DEC_ZPX: unimplemented_instruction(state); break;
case DEC_ABS: unimplemented_instruction(state); break;
case DEC_ABSX: unimplemented_instruction(state); break;
case DEC_ZP: DEC(state, get_address_zero_page(state)); break;
case DEC_ZPX: DEC(state, get_address_zero_page_x(state)); break;
case DEC_ABS: DEC(state, get_address_absolute(state)); break;
case DEC_ABSX: DEC(state, get_address_absolute_x(state)); break;
case DEX: state->x -= 1; set_NZ_flags(state, state->x); break;
case DEY: state->y -= 1; set_NZ_flags(state, state->y); break;
case INX: state->x += 1; set_NZ_flags(state, state->x); break;
@ -259,10 +277,10 @@ int emulate_6502_op(State6502 * state) {
case EOR_ABSY: unimplemented_instruction(state); break;
case EOR_INDX: unimplemented_instruction(state); break;
case EOR_INDY: unimplemented_instruction(state); break;
case INC_ZP: unimplemented_instruction(state); break;
case INC_ZPX: unimplemented_instruction(state); break;
case INC_ABS: unimplemented_instruction(state); break;
case INC_ABSX: unimplemented_instruction(state); break;
case INC_ZP: INC(state, get_address_zero_page(state)); break;
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 JSR_ABS: unimplemented_instruction(state); break;

View File

@ -26,7 +26,7 @@ void print_memory(State6502* state, word offset) {
printf("\n");
}
void print_all(State6502* state) {
void print_all(State6502 * state) {
print_state(state);
print_memory(state, 0);
//print_memory(state, 0x20);
@ -35,14 +35,14 @@ void print_all(State6502* state) {
printf("\n");
}
void test_step(State6502* state) {
void test_step(State6502 * state) {
print_all(state);
disassemble_6502(state->memory, state->pc);
emulate_6502_op(state);
print_all(state);
}
void test_cleanup(State6502* state) {
void test_cleanup(State6502 * state) {
free(state->memory);
}
@ -54,21 +54,21 @@ State6502 create_blank_state() {
return state;
}
void assertA(State6502* state, byte expected) {
void assertA(State6502 * state, byte expected) {
if (state->a != expected) {
printf("Unexpected value in A, expected %02X, was %02X", expected, state->a);
exit(1);
}
}
void assertX(State6502* state, byte expected) {
void assertX(State6502 * state, byte expected) {
if (state->x != expected) {
printf("Unexpected value in X, expected %02X, was %02X", expected, state->x);
exit(1);
}
}
void assertY(State6502* state, byte expected) {
void assertY(State6502 * state, byte expected) {
if (state->y != expected) {
printf("Unexpected value in X, expected %02X, was %02X", expected, state->y);
exit(1);
@ -76,23 +76,23 @@ void assertY(State6502* state, byte expected) {
}
//assert_memory(&state, 0xFF, 0x99)
void assert_memory(State6502* state, word address, byte expected) {
void assert_memory(State6502 * state, word address, byte expected) {
if (state->memory[address] != expected) {
printf("Unexpected value in $%04X, expected %02X, was %02X", address, expected, state->memory[address]);
exit(1);
}
}
void assert_flag_n(State6502* state, byte expected) {
void assert_flag_n(State6502 * state, byte expected) {
if (state->flags.n != expected) {
printf("Unexpected value in flag N, expected %d, was %d", expected, state->flags.n);
exit(1);
}
}
void assert_flag_z(State6502* state, byte expected) {
void assert_flag_z(State6502 * state, byte expected) {
if (state->flags.z != expected) {
printf("Unexpected value in flag N, expected %d, was %d", expected, state->flags.z);
printf("Unexpected value in flag Z, expected %d, was %d", expected, state->flags.z);
exit(1);
}
}
@ -386,7 +386,7 @@ void test_ORA_ABSY() {
state.a = 0x0A;
//arrange
char program[] = { ORA_ABSY, 0x01, 0x04}; //ORA $0401,y
char program[] = { ORA_ABSY, 0x01, 0x04 }; //ORA $0401,y
memcpy(state.memory, program, sizeof(program));
state.memory[0x403] = 0xA0;
@ -811,7 +811,7 @@ void test_STX_ZP() {
state.x = 0x99;
//arrange
char program[] = { STX_ZP, 0xFF}; //STX $FF
char program[] = { STX_ZP, 0xFF }; //STX $FF
memcpy(state.memory, program, sizeof(program));
//act
@ -831,7 +831,7 @@ void test_STX_ZPY() {
state.x = 0x99;
//arrange
char program[] = { STX_ZPY, 0x02}; //STX $02,Y
char program[] = { STX_ZPY, 0x02 }; //STX $02,Y
memcpy(state.memory, program, sizeof(program));
//act
@ -1132,25 +1132,128 @@ void test_TAY() {
test_cleanup(&state);
}
//// INC, DEC
void test_INC_ZP() {
State6502 state = create_blank_state();
char program[] = { INC_ZP, 0xFF };
memcpy(state.memory, program, sizeof(program));
test_step(&state);
assert_memory(&state, 0xFF, 0x01);
assert_flag_z(&state, 0);
assert_flag_n(&state, 0);
test_cleanup(&state);
}
void test_INC_ZP_wraparound() {
State6502 state = create_blank_state();
char program[] = { INC_ZP, 0xFF };
memcpy(state.memory, program, sizeof(program));
state.memory[0xFF] = 0xFF;
test_step(&state);
assert_memory(&state, 0xFF, 0x00);
assert_flag_z(&state, 1);
assert_flag_n(&state, 0);
test_cleanup(&state);
}
void test_INC_ZPX() {
State6502 state = create_blank_state();
state.x = 0x02;
char program[] = { INC_ZPX, 0xFD };
memcpy(state.memory, program, sizeof(program));
test_step(&state);
assert_memory(&state, 0xFF, 0x01);
assert_flag_z(&state, 0);
assert_flag_n(&state, 0);
test_cleanup(&state);
}
void test_INC_ABS() {
State6502 state = create_blank_state();
char program[] = { INC_ABS, 0xFF, 0x01 };
memcpy(state.memory, program, sizeof(program));
test_step(&state);
assert_memory(&state, 0x1FF, 0x01);
assert_flag_z(&state, 0);
assert_flag_n(&state, 0);
test_cleanup(&state);
}
void test_INC_ABSX() {
State6502 state = create_blank_state();
state.x = 0x02;
char program[] = { INC_ABSX, 0xFD, 0x01 };
memcpy(state.memory, program, sizeof(program));
test_step(&state);
assert_memory(&state, 0x1FF, 0x01);
assert_flag_z(&state, 0);
assert_flag_n(&state, 0);
test_cleanup(&state);
}
void test_DEC_ZP() {
State6502 state = create_blank_state();
char program[] = { DEC_ZP, 0xFF };
memcpy(state.memory, program, sizeof(program));
state.memory[0xFF] = 0xFF;
test_step(&state);
assert_memory(&state, 0xFF, 0xFE);
assert_flag_z(&state, 0);
assert_flag_n(&state, 1);
test_cleanup(&state);
}
void test_DEC_ZP_wraparound() {
State6502 state = create_blank_state();
char program[] = { DEC_ZP, 0xFF };
memcpy(state.memory, program, sizeof(program));
test_step(&state);
assert_memory(&state, 0xFF, 0xFF);
assert_flag_z(&state, 0);
assert_flag_n(&state, 1);
test_cleanup(&state);
}
/////////////////////
typedef void fp();
fp* tests_lda[] = { test_LDA_IMM, test_LDA_ZP, test_LDA_ZPX, test_LDA_ZPX_wraparound, test_LDA_ABS, test_LDA_ABSX, test_LDA_ABSY, test_LDA_INDX, test_LDA_INDY };
fp* tests_ora[] = { test_ORA_IMM, test_ORA_ZP, test_ORA_ZPX, test_ORA_ABS, test_ORA_ABSX, test_ORA_ABSY, test_ORA_INDX, test_ORA_INDY};
fp* tests_ora[] = { test_ORA_IMM, test_ORA_ZP, test_ORA_ZPX, test_ORA_ABS, test_ORA_ABSX, test_ORA_ABSY, test_ORA_INDX, test_ORA_INDY };
fp* tests_and[] = { test_AND_IMM, test_AND_ZP, test_AND_ZPX, test_AND_ABS, test_AND_ABSX, test_AND_ABSY, test_AND_INDX, test_AND_INDY };
fp* tests_ldx[] = { test_LDX_IMM, test_LDX_ZP, test_LDX_ZPY, test_LDX_ABS, test_LDX_ABSY };
fp* tests_ldy[] = { test_LDY_IMM, test_LDY_ZP, test_LDY_ZPX, test_LDY_ABS, test_LDY_ABSX };
fp* tests_stx[] = { test_STX_ZP, test_STX_ZPY, test_STX_ABS};
fp* tests_stx[] = { test_STX_ZP, test_STX_ZPY, test_STX_ABS };
fp* tests_sty[] = { test_STY_ZP, test_STY_ZPX, test_STY_ABS };
fp* tests_inx_iny_dex_dey[] = { test_DEX, test_DEX_wraparound, test_DEY, test_DEY_wraparound, test_INX, test_INX_wraparound, test_INY, test_INY_wraparound};
fp* tests_inx_iny_dex_dey[] = { test_DEX, test_DEX_wraparound, test_DEY, test_DEY_wraparound, test_INX, test_INX_wraparound, test_INY, test_INY_wraparound };
fp* tests_txa_etc[] = { test_TXA, test_TAX, test_TYA, test_TAY };
fp* tests_inc_dec[] = { test_INC_ZP, test_INC_ZP_wraparound, test_INC_ZPX, test_INC_ABS, test_INC_ABSX, test_DEC_ZP, test_DEC_ZP_wraparound };
#define RUN(suite) run_suite(suite, sizeof(suite)/sizeof(fp*))
void run_suite(fp** suite, int size) {
void run_suite(fp * *suite, int size) {
for (int i = 0; i < size; i++)
suite[i]();
}
@ -1166,4 +1269,5 @@ void run_tests() {
RUN(tests_sty);
RUN(tests_inx_iny_dex_dey);
RUN(tests_txa_etc);
RUN(tests_inc_dec);
}