mirror of
https://github.com/st3fan/ewm.git
synced 2025-08-10 11:24:56 +00:00
Fixes #2 - Keep the stack pointer as a byte instead of word
This commit is contained in:
49
cpu.c
49
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_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
15
cpu.h
@@ -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
16
ins.c
@@ -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) {
|
||||||
|
Reference in New Issue
Block a user