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_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) {

15
cpu.h
View File

@ -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);

16
ins.c
View File

@ -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) {