Fixes #2 - Keep the stack pointer as a byte instead of word

This commit is contained in:
Stefan Arentz
2016-11-13 15:29:49 -05:00
parent 51093f364c
commit e7ed556023
3 changed files with 58 additions and 22 deletions

49
cpu.c
View File

@@ -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_byte_t)(struct cpu_t *cpu, uint8_t oper);
typedef void (*cpu_instruction_handler_word_t)(struct cpu_t *cpu, uint16_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]; 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]); 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 #if 1
static void cpu_format_instruction(struct cpu_t *cpu, char *buffer) { static void cpu_format_instruction(struct cpu_t *cpu, char *buffer) {
*buffer = 0x00; *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) { 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", 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.n ? 'N' : '-',
cpu->state.v ? 'V' : '-', 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) { static void cpu_format_stack(struct cpu_t *cpu, char *buffer) {
*buffer = 0x00; *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]; char tmp[8];
sprintf(tmp, " %.2X", _mem_get_byte(cpu, sp)); sprintf(tmp, " %.2X", _mem_get_byte(cpu, 0x0100 + sp));
buffer = strcat(buffer, tmp); buffer = strcat(buffer, tmp);
} }
} }
@@ -316,11 +349,7 @@ void cpu_reset(struct cpu_t *cpu) {
cpu->state.i = 1; cpu->state.i = 1;
cpu->state.z = 0; cpu->state.z = 0;
cpu->state.c = 0; cpu->state.c = 0;
cpu->state.sp = 0x01ff; cpu->state.sp = 0xff;
}
void cpu_brk(struct cpu_t *cpu) {
} }
void cpu_irq(struct cpu_t *cpu) { void cpu_irq(struct cpu_t *cpu) {

15
cpu.h
View File

@@ -35,8 +35,7 @@ struct iom_t {
}; };
struct cpu_state_t { struct cpu_state_t {
uint8_t a, x, y, s; uint8_t a, x, y, s, sp;
uint16_t sp;
uint16_t pc; uint16_t pc;
uint8_t n, v, b, d, i, z, c; uint8_t n, v, b, d, i, z, c;
}; };
@@ -48,6 +47,18 @@ struct cpu_t {
struct iom_t *iom; 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 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); typedef void (*iom_write_handler_t)(struct cpu_t *cpu, void *obj, uint16_t addr, uint8_t b);

16
ins.c
View File

@@ -436,8 +436,7 @@ static void jmp_ind(struct cpu_t *cpu, uint16_t oper) {
/* JSR */ /* JSR */
static void jsr_abs(struct cpu_t *cpu, uint16_t oper) { static void jsr_abs(struct cpu_t *cpu, uint16_t oper) {
cpu->state.sp -= 2; _cpu_push_word(cpu, cpu->state.pc - 1);
mem_set_word(cpu, cpu->state.sp, cpu->state.pc-1);
cpu->state.pc = oper; cpu->state.pc = oper;
} }
@@ -613,13 +612,11 @@ static void ora_indy(struct cpu_t *cpu, uint8_t oper) {
/* P** */ /* P** */
static void pha(struct cpu_t *cpu) { static void pha(struct cpu_t *cpu) {
cpu->state.sp--; _cpu_push_byte(cpu, cpu->state.a);
mem_set_byte(cpu, cpu->state.sp, cpu->state.a);
} }
static void pla(struct cpu_t *cpu) { static void pla(struct cpu_t *cpu) {
cpu->state.a = mem_get_byte(cpu, cpu->state.sp); cpu->state.a = _cpu_pull_byte(cpu);
cpu->state.sp++;
update_zn(cpu, cpu->state.a); update_zn(cpu, cpu->state.a);
} }
@@ -686,8 +683,7 @@ static void ror_absx(struct cpu_t *cpu, uint16_t oper) {
/* RTS */ /* RTS */
static void rts(struct cpu_t *cpu) { static void rts(struct cpu_t *cpu) {
cpu->state.pc = mem_get_word(cpu, cpu->state.sp)+1; cpu->state.pc = _cpu_pull_word(cpu) + 1;
cpu->state.sp += 2;
} }
/* SBC */ /* SBC */
@@ -799,7 +795,7 @@ static void tay(struct cpu_t *cpu) {
} }
static void tsx(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); update_zn(cpu, cpu->state.x);
} }
@@ -809,7 +805,7 @@ static void txa(struct cpu_t *cpu) {
} }
static void txs(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) { static void tya(struct cpu_t *cpu) {