mirror of
https://github.com/jborza/emu6502.git
synced 2024-11-21 23:31:19 +00:00
fixed PHP flag handling + test
This commit is contained in:
parent
8754aaef9f
commit
836a076d1c
16
cpu.c
16
cpu.c
@ -31,8 +31,17 @@ void set_NZ_flags(State6502 * state, byte value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
byte flags_as_byte(State6502 * state) {
|
byte flags_as_byte(State6502 * state) {
|
||||||
byte flags_value;
|
byte flags_value = 0;
|
||||||
memcpy(&flags_value, &state->flags, sizeof(Flags));
|
flags_value |= state->flags.c << 0;
|
||||||
|
flags_value |= state->flags.z << 1;
|
||||||
|
flags_value |= state->flags.i << 2;
|
||||||
|
flags_value |= state->flags.d << 3;
|
||||||
|
//flag B is active with PHP
|
||||||
|
flags_value |= 1 << 4;
|
||||||
|
//unused bit is active with PHP
|
||||||
|
flags_value |= 1 << 5;
|
||||||
|
flags_value |= state->flags.v << 6;
|
||||||
|
flags_value |= state->flags.n << 7;
|
||||||
return flags_value;
|
return flags_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,8 +359,7 @@ void PLP_(State6502* state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void PHP_(State6502 * state) {
|
void PHP_(State6502 * state) {
|
||||||
byte flags_value;
|
byte flags_value = flags_as_byte(state);
|
||||||
memcpy(&flags_value, &state->flags, sizeof(Flags));
|
|
||||||
push_byte_to_stack(state, flags_value);
|
push_byte_to_stack(state, flags_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
17
emu6502.c
17
emu6502.c
@ -22,12 +22,18 @@ byte* read_nestest() {
|
|||||||
int err = errno;
|
int err = errno;
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
byte buffer[NESTEST_SIZE];
|
static byte buffer[NESTEST_SIZE];
|
||||||
int read = fread(&buffer, sizeof(byte), NESTEST_SIZE, file);
|
int read = fread(&buffer, sizeof(byte), NESTEST_SIZE, file);
|
||||||
fclose(file);
|
fclose(file);
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
byte debug_flags_as_byte(State6502* state) {
|
||||||
|
byte flags_value = 0;
|
||||||
|
memcpy(&flags_value, &state->flags, sizeof(Flags));
|
||||||
|
return flags_value;
|
||||||
|
}
|
||||||
|
|
||||||
void run_nestest() {
|
void run_nestest() {
|
||||||
State6502 state;
|
State6502 state;
|
||||||
clear_state(&state);
|
clear_state(&state);
|
||||||
@ -38,16 +44,19 @@ void run_nestest() {
|
|||||||
memcpy(state.memory + NESTEST_DST, bin, NESTEST_SIZE);
|
memcpy(state.memory + NESTEST_DST, bin, NESTEST_SIZE);
|
||||||
memcpy(state.memory + 0x8000, bin, NESTEST_SIZE);
|
memcpy(state.memory + 0x8000, bin, NESTEST_SIZE);
|
||||||
state.pc = NESTEST_DST;
|
state.pc = NESTEST_DST;
|
||||||
|
//a little cheat to simulate probably a JSR and SEI at the beginning
|
||||||
|
state.sp = 0xfd;
|
||||||
|
state.flags.i = 1;
|
||||||
do{
|
do{
|
||||||
char* dasm = disassemble_6502_to_string(state.memory, state.pc);
|
char* dasm = disassemble_6502_to_string(state.memory, state.pc);
|
||||||
printf("%-50s A:%02X X:%02X Y:%02X P:%02X SP:%02X\n", dasm, state.a, state.x, state.y, flags_as_byte(&state), state.sp);
|
printf("%-50s A:%02X X:%02X Y:%02X P:%02X SP:%02X\n", dasm, state.a, state.x, state.y, debug_flags_as_byte(&state), state.sp);
|
||||||
emulate_6502_op(&state);
|
emulate_6502_op(&state);
|
||||||
} while (state.flags.b != 1);
|
} while (state.flags.b != 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
//run_nestest();
|
run_nestest();
|
||||||
run_tests();
|
//run_tests();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
16
flags.h
16
flags.h
@ -4,12 +4,12 @@
|
|||||||
|
|
||||||
typedef struct Flags {
|
typedef struct Flags {
|
||||||
//flags high to low: NV-BDIZC
|
//flags high to low: NV-BDIZC
|
||||||
uint8_t c : 1; //set if last operation caused an overflow from bit 7 of the result or an underflow from bit 0
|
uint8_t c : 1; //0 - set if last operation caused an overflow from bit 7 of the result or an underflow from bit 0
|
||||||
uint8_t z : 1; //set if the result of the last operation was zero
|
uint8_t z : 1; //1 - set if the result of the last operation was zero
|
||||||
uint8_t i : 1; //set with SEI and cleared with CLI
|
uint8_t i : 1; //2 - set with SEI and cleared with CLI
|
||||||
uint8_t d : 1; //set with SEC and cleared with CLD
|
uint8_t d : 1; //3 - set with SEC and cleared with CLD
|
||||||
uint8_t b : 1; //set when BRK executed
|
uint8_t b : 1; //4 - set when BRK executed
|
||||||
uint8_t pad : 1; //not used
|
uint8_t pad : 1; //5 - not used
|
||||||
uint8_t v : 1; //if the result has yielded an invalid two's complement result
|
uint8_t v : 1; //6 - if the result has yielded an invalid two's complement result
|
||||||
uint8_t n : 1; //set if the result of the last operation set bit 7 to one
|
uint8_t n : 1; //7 - set if the result of the last operation set bit 7 to one
|
||||||
} Flags;
|
} Flags;
|
26
test6502.c
26
test6502.c
@ -2001,7 +2001,6 @@ void test_PHP() {
|
|||||||
state.flags.d = 1;
|
state.flags.d = 1;
|
||||||
state.flags.i = 1;
|
state.flags.i = 1;
|
||||||
state.flags.v = 1;
|
state.flags.v = 1;
|
||||||
state.sp = 0xFF;
|
|
||||||
|
|
||||||
//arrange
|
//arrange
|
||||||
char program[] = { PHP };
|
char program[] = { PHP };
|
||||||
@ -2018,6 +2017,27 @@ void test_PHP() {
|
|||||||
test_cleanup(&state);
|
test_cleanup(&state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_PLP_no_flags() {
|
||||||
|
//initialize
|
||||||
|
State6502 state = create_blank_state();
|
||||||
|
//no flags are set
|
||||||
|
|
||||||
|
//arrange
|
||||||
|
char program[] = { PHP };
|
||||||
|
memcpy(state.memory, program, sizeof(program));
|
||||||
|
|
||||||
|
//act
|
||||||
|
test_step(&state);
|
||||||
|
|
||||||
|
//assert
|
||||||
|
assert_sp(&state, 0xFE);
|
||||||
|
byte expected_value = (1 << 4) | (1 << 5);
|
||||||
|
assert_memory(&state, 0x1FF, expected_value);
|
||||||
|
|
||||||
|
//cleanup
|
||||||
|
test_cleanup(&state);
|
||||||
|
}
|
||||||
|
|
||||||
void test_PLP() {
|
void test_PLP() {
|
||||||
State6502 state = create_blank_state();
|
State6502 state = create_blank_state();
|
||||||
state.sp = 0xFE;
|
state.sp = 0xFE;
|
||||||
@ -2051,7 +2071,7 @@ void test_PLP2() {
|
|||||||
//arrange
|
//arrange
|
||||||
char program[] = { PLP };
|
char program[] = { PLP };
|
||||||
memcpy(state.memory, program, sizeof(program));
|
memcpy(state.memory, program, sizeof(program));
|
||||||
state.memory[0x1FF] = 0x04; //all flags should be on
|
state.memory[0x1FF] = 0x04; //only flag i should be set
|
||||||
|
|
||||||
//act
|
//act
|
||||||
test_step(&state);
|
test_step(&state);
|
||||||
@ -2494,7 +2514,7 @@ 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_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_PLA_N, test_PLA_Z, test_PHA_PLA };
|
fp* tests_pha_pla[] = { test_PHA, test_PLA, test_PLA_N, test_PLA_Z, test_PHA_PLA };
|
||||||
fp* tests_txs_tsx[] = { test_TXS, test_TSX, test_TXS_Z };
|
fp* tests_txs_tsx[] = { test_TXS, test_TSX, test_TXS_Z };
|
||||||
fp* tests_php_plp[] = { test_PHP, test_PLP, test_PLP2 };
|
fp* tests_php_plp[] = { test_PHP, test_PLP_no_flags, test_PLP, test_PLP2 };
|
||||||
fp* tests_jmp[] = { test_JMP, test_JMP_IND, test_JMP_IND_wrap };
|
fp* tests_jmp[] = { test_JMP, test_JMP_IND, test_JMP_IND_wrap };
|
||||||
fp* tests_cmp[] = { test_CMP_ABS_equal, test_CMP_ABS_greater, test_CMP_ABS_greater_2, test_CMP_ABS_less_than, test_CPX_ABS, test_CPY_ABS };
|
fp* tests_cmp[] = { test_CMP_ABS_equal, test_CMP_ABS_greater, test_CMP_ABS_greater_2, test_CMP_ABS_less_than, test_CPX_ABS, test_CPY_ABS };
|
||||||
fp* tests_sbc[] = { test_SBC_IMM_multiple };
|
fp* tests_sbc[] = { test_SBC_IMM_multiple };
|
||||||
|
Loading…
Reference in New Issue
Block a user