1
0
mirror of https://github.com/jborza/emu6502.git synced 2024-11-28 23:49:24 +00:00

JSR and RTS

This commit is contained in:
jborza 2019-04-26 07:22:42 +02:00
parent b53eef7d91
commit a4bc64ec43
2 changed files with 56 additions and 4 deletions

29
cpu.c
View File

@ -61,10 +61,21 @@ void push_byte_to_stack(State6502 * state, byte value) {
state->memory[STACK_HOME + state->sp--] = value; state->memory[STACK_HOME + state->sp--] = value;
} }
void push_word_to_stack(State6502* state, word value) {
push_byte_to_stack(state, (value >> 8) & 0xFF);
push_byte_to_stack(state, value & 0xFF);
}
byte pop_byte_from_stack(State6502 * state) { byte pop_byte_from_stack(State6502 * state) {
return state->memory[STACK_HOME + ++(state->sp)]; return state->memory[STACK_HOME + ++(state->sp)];
} }
word pop_word_from_stack(State6502* state) {
byte low = pop_byte_from_stack(state);
byte high = pop_byte_from_stack(state);
return low + (high >> 8);
}
//bitwise or with accumulator //bitwise or with accumulator
void ORA(State6502 * state, byte operand) { void ORA(State6502 * state, byte operand) {
byte result = state->a | operand; byte result = state->a | operand;
@ -257,6 +268,20 @@ void ROR_MEM(State6502 * state, word address) {
state->memory[address] = ror(state, operand); state->memory[address] = ror(state, operand);
} }
void JSR(State6502 * state, word address) {
byte target = state->memory[address];
//JSR pushes the address-1 of the next operation on to the stack before transferring program control to the following address.
word address_to_push = state->pc - 1;
push_byte_to_stack(state, (address_to_push >> 8 & 0xFF));
push_byte_to_stack(state, address_to_push & 0xFF);
state->pc = target;
}
void RTS_(State6502* state) {
word address = pop_word_from_stack(state);
state->pc = address + 1;
}
word pop_word(State6502 * state) { word pop_word(State6502 * state) {
byte low = pop_byte(state); byte low = pop_byte(state);
byte high = pop_byte(state); byte high = pop_byte(state);
@ -425,7 +450,7 @@ int emulate_6502_op(State6502 * state) {
break; break;
}//pull procesor status }//pull procesor status
case RTI: unimplemented_instruction(state); break; case RTI: unimplemented_instruction(state); break;
case RTS: unimplemented_instruction(state); break; case RTS: RTS_(state); break;
case SEC: state->flags.c = 1; break; case SEC: state->flags.c = 1; break;
case SED: state->flags.d = 1; break; case SED: state->flags.d = 1; break;
case SEI: state->flags.i = 1; break; case SEI: state->flags.i = 1; break;
@ -471,7 +496,7 @@ int emulate_6502_op(State6502 * state) {
case INC_ABSX: INC(state, get_address_absolute_x(state)); break; case INC_ABSX: INC(state, get_address_absolute_x(state)); break;
case JMP_ABS: JMP(state, get_address_absolute(state)); break; case JMP_ABS: JMP(state, get_address_absolute(state)); break;
case JMP_IND: JMP(state, get_address_indirect_jmp(state)); break; case JMP_IND: JMP(state, get_address_indirect_jmp(state)); break;
case JSR_ABS: unimplemented_instruction(state); break; case JSR_ABS: JSR(state, get_address_absolute(state)); break;
case LDA_IMM: LDA(state, pop_byte(state)); break; case LDA_IMM: LDA(state, pop_byte(state)); break;
case LDA_ZP: LDA(state, get_byte_zero_page(state)); break; case LDA_ZP: LDA(state, get_byte_zero_page(state)); break;
case LDA_ZPX: LDA(state, get_byte_zero_page_x(state)); break; case LDA_ZPX: LDA(state, get_byte_zero_page_x(state)); break;

View File

@ -1369,6 +1369,32 @@ void test_INC_ZP_wraparound() {
test_cleanup(&state); test_cleanup(&state);
} }
void test_INC_ZP_(byte operand, byte expected, byte expected_zero, byte expected_n) {
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);
}
#define _ ,
#define __ ,
void test_INC_ZP_multiple() {
// A => A Z N
test_INC_ZP_(0x00 __ 0x01 _ 0 _ 0);
test_INC_ZP_(0x7F __ 0x80 _ 0 _ 1);
test_INC_ZP_(0xFF __ 0x00 _ 1 _ 0);
test_INC_ZP_(0xFE __ 0xFF _ 0 _ 1);
}
void test_INC_ZPX() { void test_INC_ZPX() {
State6502 state = create_blank_state(); State6502 state = create_blank_state();
state.x = 0x02; state.x = 0x02;
@ -2055,7 +2081,7 @@ void test_ADC_IMM_multiple() {
void test_BIT_exec(byte a, byte expected_a, byte expected_n, byte expected_v, byte expected_z) { void test_BIT_exec(byte a, byte expected_a, byte expected_n, byte expected_v, byte expected_z) {
State6502 state = create_blank_state(); State6502 state = create_blank_state();
state.a = a; state.a = a;
char program[] = { BIT_ABS, 0x45, 0x03}; char program[] = { BIT_ABS, 0x45, 0x03 };
memcpy(state.memory, program, sizeof(program)); memcpy(state.memory, program, sizeof(program));
state.memory[0x0345] = 0xF3; state.memory[0x0345] = 0xF3;
//act //act
@ -2068,6 +2094,7 @@ void test_BIT_exec(byte a, byte expected_a, byte expected_n, byte expected_v, by
} }
void test_BIT_multiple() { void test_BIT_multiple() {
// A => A N V Z
test_BIT_exec(128, 128, 1, 1, 0); test_BIT_exec(128, 128, 1, 1, 0);
test_BIT_exec(5, 5, 1, 1, 0); test_BIT_exec(5, 5, 1, 1, 0);
test_BIT_exec(4, 4, 1, 1, 1); // 128 & 4 = 0 -> Z = 1 test_BIT_exec(4, 4, 1, 1, 1); // 128 & 4 = 0 -> Z = 1
@ -2086,7 +2113,7 @@ 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_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_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 }; fp* tests_inc_dec[] = { test_INC_ZP, test_INC_ZP_multiple, test_INC_ZP_wraparound, test_INC_ZPX, test_INC_ABS, test_INC_ABSX, test_DEC_ZP, test_DEC_ZP_wraparound };
fp* tests_flags[] = { test_CLC, test_SEC, test_CLD, test_SED, test_SEI, test_CLI, test_CLV }; fp* tests_flags[] = { test_CLC, test_SEC, test_CLD, test_SED, test_SEI, test_CLI, test_CLV };
fp* tests_eor[] = { test_EOR_IMM, test_EOR_ZP, test_EOR_ZPX, test_EOR_ABS, test_EOR_ABSX, test_EOR_ABSY, test_EOR_INDX, test_EOR_INDY }; fp* tests_eor[] = { test_EOR_IMM, test_EOR_ZP, test_EOR_ZPX, test_EOR_ABS, test_EOR_ABSX, test_EOR_ABSY, test_EOR_INDX, test_EOR_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_sta[] = { test_STA_ZP, test_STA_ZPX, test_STA_ABS, test_STA_ABSX, test_STA_ABSY, test_STA_INDX, test_STA_INDY };