From e7ed5560234ccb8f5b3d2c00e06ad617b652c7b9 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Sun, 13 Nov 2016 15:29:49 -0500 Subject: [PATCH] Fixes #2 - Keep the stack pointer as a byte instead of word --- cpu.c | 49 +++++++++++++++++++++++++++++++++++++++---------- cpu.h | 15 +++++++++++++-- ins.c | 16 ++++++---------- 3 files changed, 58 insertions(+), 22 deletions(-) diff --git a/cpu.c b/cpu.c index 0e71064..bded4c8 100644 --- a/cpu.c +++ b/cpu.c @@ -39,14 +39,47 @@ typedef void (*cpu_instruction_handler_t)(struct cpu_t *cpu); typedef void (*cpu_instruction_handler_byte_t)(struct cpu_t *cpu, uint8_t oper); typedef void (*cpu_instruction_handler_word_t)(struct cpu_t *cpu, uint16_t oper); -static uint8_t _mem_get_byte(struct cpu_t *cpu, uint16_t addr) { +// The following get and set memory directly. There are no checks, so +// make sure you are doing the right thing. Mainly used for managing +// the stack, reading instructions, reading vectors and tracing code. + +uint8_t _mem_get_byte(struct cpu_t *cpu, uint16_t addr) { return cpu->memory[addr]; } -static uint16_t _mem_get_word(struct cpu_t *cpu, uint16_t addr) { +uint16_t _mem_get_word(struct cpu_t *cpu, uint16_t addr) { return *((uint16_t*) &cpu->memory[addr]); } +void _mem_set_byte(struct cpu_t *cpu, uint16_t addr, uint8_t v) { + cpu->memory[addr] = v; +} + +void _mem_set_word(struct cpu_t *cpu, uint16_t addr, uint8_t v) { + *((uint16_t*) &cpu->memory[addr]) = v; +} + +// Stack management. + +void _cpu_push_byte(struct cpu_t *cpu, uint8_t b) { + _mem_set_byte(cpu, 0x0100 + cpu->state.sp, b); + cpu->state.sp -= 1; +} + +void _cpu_push_word(struct cpu_t *cpu, uint16_t w) { + _cpu_push_byte(cpu, (uint8_t) (w >> 8)); + _cpu_push_byte(cpu, (uint8_t) w); +} + +uint8_t _cpu_pull_byte(struct cpu_t *cpu) { + cpu->state.sp += 1; + return _mem_get_byte(cpu, 0x0100 + cpu->state.sp); +} + +uint16_t _cpu_pull_word(struct cpu_t *cpu) { + return (uint16_t) _cpu_pull_byte(cpu) | ((uint16_t) _cpu_pull_byte(cpu) << 8); +} + #if 1 static void cpu_format_instruction(struct cpu_t *cpu, char *buffer) { *buffer = 0x00; @@ -146,7 +179,7 @@ static void cpu_format_instruction(struct cpu_t *cpu, char *buffer) { static void cpu_format_state(struct cpu_t *cpu, char *buffer) { sprintf(buffer, "A=%.2X X=%.2X Y=%.2X S=%.2X SP=%.4X %c%c%c%c%c%c%c%c", - cpu->state.a, cpu->state.x, cpu->state.y, cpu->state.s, cpu->state.sp, + cpu->state.a, cpu->state.x, cpu->state.y, cpu->state.s, 0x0100 + cpu->state.sp, cpu->state.n ? 'N' : '-', cpu->state.v ? 'V' : '-', @@ -160,9 +193,9 @@ static void cpu_format_state(struct cpu_t *cpu, char *buffer) { static void cpu_format_stack(struct cpu_t *cpu, char *buffer) { *buffer = 0x00; - for (uint16_t sp = cpu->state.sp; sp != 0x01ff; sp++) { + for (uint16_t sp = cpu->state.sp; sp != 0xff; sp++) { char tmp[8]; - sprintf(tmp, " %.2X", _mem_get_byte(cpu, sp)); + sprintf(tmp, " %.2X", _mem_get_byte(cpu, 0x0100 + sp)); buffer = strcat(buffer, tmp); } } @@ -316,11 +349,7 @@ void cpu_reset(struct cpu_t *cpu) { cpu->state.i = 1; cpu->state.z = 0; cpu->state.c = 0; - cpu->state.sp = 0x01ff; -} - -void cpu_brk(struct cpu_t *cpu) { - + cpu->state.sp = 0xff; } void cpu_irq(struct cpu_t *cpu) { diff --git a/cpu.h b/cpu.h index 67682fa..5a77ca2 100644 --- a/cpu.h +++ b/cpu.h @@ -35,8 +35,7 @@ struct iom_t { }; struct cpu_state_t { - uint8_t a, x, y, s; - uint16_t sp; + uint8_t a, x, y, s, sp; uint16_t pc; uint8_t n, v, b, d, i, z, c; }; @@ -48,6 +47,18 @@ struct cpu_t { struct iom_t *iom; }; +// Private. How do we keep them private? +uint8_t _mem_get_byte(struct cpu_t *cpu, uint16_t addr); +uint16_t _mem_get_word(struct cpu_t *cpu, uint16_t addr); +void _mem_set_byte(struct cpu_t *cpu, uint16_t addr, uint8_t v); +void _mem_set_word(struct cpu_t *cpu, uint16_t addr, uint8_t v); + +// Private. How do we keep them private? +void _cpu_push_byte(struct cpu_t *cpu, uint8_t b); +void _cpu_push_word(struct cpu_t *cpu, uint16_t w); +uint8_t _cpu_pull_byte(struct cpu_t *cpu); +uint16_t _cpu_pull_word(struct cpu_t *cpu); + typedef uint8_t (*iom_read_handler_t)(struct cpu_t *cpu, void *obj, uint16_t addr); typedef void (*iom_write_handler_t)(struct cpu_t *cpu, void *obj, uint16_t addr, uint8_t b); diff --git a/ins.c b/ins.c index ea617ac..f1ca748 100644 --- a/ins.c +++ b/ins.c @@ -436,8 +436,7 @@ static void jmp_ind(struct cpu_t *cpu, uint16_t oper) { /* JSR */ static void jsr_abs(struct cpu_t *cpu, uint16_t oper) { - cpu->state.sp -= 2; - mem_set_word(cpu, cpu->state.sp, cpu->state.pc-1); + _cpu_push_word(cpu, cpu->state.pc - 1); cpu->state.pc = oper; } @@ -613,13 +612,11 @@ static void ora_indy(struct cpu_t *cpu, uint8_t oper) { /* P** */ static void pha(struct cpu_t *cpu) { - cpu->state.sp--; - mem_set_byte(cpu, cpu->state.sp, cpu->state.a); + _cpu_push_byte(cpu, cpu->state.a); } static void pla(struct cpu_t *cpu) { - cpu->state.a = mem_get_byte(cpu, cpu->state.sp); - cpu->state.sp++; + cpu->state.a = _cpu_pull_byte(cpu); update_zn(cpu, cpu->state.a); } @@ -686,8 +683,7 @@ static void ror_absx(struct cpu_t *cpu, uint16_t oper) { /* RTS */ static void rts(struct cpu_t *cpu) { - cpu->state.pc = mem_get_word(cpu, cpu->state.sp)+1; - cpu->state.sp += 2; + cpu->state.pc = _cpu_pull_word(cpu) + 1; } /* SBC */ @@ -799,7 +795,7 @@ static void tay(struct cpu_t *cpu) { } static void tsx(struct cpu_t *cpu) { - cpu->state.x = cpu->state.sp & 0x00ff; + cpu->state.x = cpu->state.sp; update_zn(cpu, cpu->state.x); } @@ -809,7 +805,7 @@ static void txa(struct cpu_t *cpu) { } static void txs(struct cpu_t *cpu) { - cpu->state.sp = 0x0100 + cpu->state.x; + cpu->state.sp = cpu->state.x; } static void tya(struct cpu_t *cpu) {