From a4bc64ec433e123844a5d9095cf9a2ffbf5c24b3 Mon Sep 17 00:00:00 2001 From: jborza Date: Fri, 26 Apr 2019 07:22:42 +0200 Subject: [PATCH] JSR and RTS --- cpu.c | 29 +++++++++++++++++++++++++++-- test6502.c | 31 +++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/cpu.c b/cpu.c index e50ca9d..a299e56 100644 --- a/cpu.c +++ b/cpu.c @@ -61,10 +61,21 @@ void push_byte_to_stack(State6502 * state, byte 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) { 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 void ORA(State6502 * state, byte operand) { byte result = state->a | operand; @@ -257,6 +268,20 @@ void ROR_MEM(State6502 * state, word address) { 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) { byte low = pop_byte(state); byte high = pop_byte(state); @@ -425,7 +450,7 @@ int emulate_6502_op(State6502 * state) { break; }//pull procesor status 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 SED: state->flags.d = 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 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 JSR_ABS: JSR(state, get_address_absolute(state)); break; case LDA_IMM: LDA(state, pop_byte(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; diff --git a/test6502.c b/test6502.c index 709a01f..267d34b 100644 --- a/test6502.c +++ b/test6502.c @@ -1369,6 +1369,32 @@ void test_INC_ZP_wraparound() { 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() { State6502 state = create_blank_state(); 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) { State6502 state = create_blank_state(); state.a = a; - char program[] = { BIT_ABS, 0x45, 0x03}; + char program[] = { BIT_ABS, 0x45, 0x03 }; memcpy(state.memory, program, sizeof(program)); state.memory[0x0345] = 0xF3; //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() { + // A => A N V Z test_BIT_exec(128, 128, 1, 1, 0); test_BIT_exec(5, 5, 1, 1, 0); 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_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 }; +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_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 };