mirror of
https://github.com/st3fan/ewm.git
synced 2024-12-28 15:29:45 +00:00
parent
f3781e2d69
commit
8800bf2b9f
46
src/cpu.c
46
src/cpu.c
@ -40,22 +40,20 @@
|
||||
// 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;
|
||||
cpu->page1[cpu->state.sp--] = b;
|
||||
}
|
||||
|
||||
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);
|
||||
cpu->page1[cpu->state.sp--] = w >> 8;
|
||||
cpu->page1[cpu->state.sp--] = w;
|
||||
}
|
||||
|
||||
uint8_t _cpu_pull_byte(struct cpu_t *cpu) {
|
||||
cpu->state.sp += 1;
|
||||
return mem_get_byte(cpu, 0x0100 + cpu->state.sp);
|
||||
return cpu->page1[++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);
|
||||
return (uint16_t) cpu->page1[++cpu->state.sp] | ((uint16_t) cpu->page1[++cpu->state.sp] << 8);
|
||||
}
|
||||
|
||||
uint8_t _cpu_stack_free(struct cpu_t *cpu) {
|
||||
@ -212,6 +210,17 @@ void cpu_destroy(struct cpu_t *cpu) {
|
||||
}
|
||||
}
|
||||
|
||||
static struct mem_t *cpu_mem_for_page(struct cpu_t *cpu, uint8_t page) {
|
||||
struct mem_t *mem = cpu->mem;
|
||||
while (mem != NULL) {
|
||||
if (mem->enabled && ((page * 0x100) >= mem->start) && ((page * 0x0100 + 0xff) <= mem->end)) {
|
||||
return mem;
|
||||
}
|
||||
mem = mem->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct mem_t *cpu_add_mem(struct cpu_t *cpu, struct mem_t *mem) {
|
||||
if (cpu->mem == NULL) {
|
||||
cpu->mem = mem;
|
||||
@ -345,6 +354,27 @@ struct mem_t *cpu_add_iom(struct cpu_t *cpu, uint16_t start, uint16_t end, void
|
||||
return cpu_add_mem(cpu, mem);
|
||||
}
|
||||
|
||||
// Call this when the memory layout changes for page 0 and 1. For
|
||||
// example when those pages are bankswitched. I don't think anything
|
||||
// does that right now. The Apple Language Card works in different
|
||||
// memory regions.
|
||||
|
||||
void cpu_optimize_memory(struct cpu_t *cpu) {
|
||||
struct mem_t *page0 = cpu_mem_for_page(cpu, 0);
|
||||
if (page0 == NULL || (page0->flags != (MEM_FLAGS_READ | MEM_FLAGS_WRITE))) {
|
||||
printf("[CPU] Cannot find rw memory region that handles Page 0\n");
|
||||
exit(1);
|
||||
}
|
||||
cpu->page0 = page0->obj + (0x0000 - page0->start);
|
||||
|
||||
struct mem_t *page1 = cpu_mem_for_page(cpu, 1);
|
||||
if (page1 == NULL || (page1->flags != (MEM_FLAGS_READ | MEM_FLAGS_WRITE))) {
|
||||
printf("[CPU] Cannot find rw memory region that handles Page 1\n");
|
||||
exit(1);
|
||||
}
|
||||
cpu->page1 = page1->obj + (0x0100 - page1->start);
|
||||
}
|
||||
|
||||
void cpu_strict(struct cpu_t *cpu, bool strict) {
|
||||
cpu->strict = strict;
|
||||
}
|
||||
@ -378,6 +408,8 @@ void cpu_reset(struct cpu_t *cpu) {
|
||||
cpu->state.z = 0;
|
||||
cpu->state.c = 0;
|
||||
cpu->state.sp = 0xff;
|
||||
|
||||
cpu_optimize_memory(cpu);
|
||||
}
|
||||
|
||||
int cpu_irq(struct cpu_t *cpu) {
|
||||
|
@ -54,6 +54,9 @@ struct cpu_t {
|
||||
struct mem_t *mem;
|
||||
struct cpu_instruction_t *instructions;
|
||||
uint64_t counter;
|
||||
|
||||
uint8_t *page0;
|
||||
uint8_t *page1;
|
||||
};
|
||||
|
||||
typedef void (*cpu_instruction_handler_t)(struct cpu_t *cpu);
|
||||
@ -102,6 +105,8 @@ struct mem_t *cpu_add_rom_data(struct cpu_t *cpu, uint16_t start, uint16_t end,
|
||||
struct mem_t *cpu_add_rom_file(struct cpu_t *cpu, uint16_t start, char *path);
|
||||
struct mem_t *cpu_add_iom(struct cpu_t *cpu, uint16_t start, uint16_t end, void *obj, mem_read_handler_t read_handler, mem_write_handler_t write_handler);
|
||||
|
||||
void cpu_optimize_memory(struct cpu_t *cpu);
|
||||
|
||||
void cpu_strict(struct cpu_t *cpu, bool strict);
|
||||
int cpu_trace(struct cpu_t *cpu, char *path);
|
||||
|
||||
|
30
src/mem.c
30
src/mem.c
@ -74,54 +74,53 @@ uint8_t mem_get_byte_abs(struct cpu_t *cpu, uint16_t addr) {
|
||||
}
|
||||
|
||||
uint8_t mem_get_byte_absx(struct cpu_t *cpu, uint16_t addr) {
|
||||
return mem_get_byte(cpu, addr + cpu->state.x); /* TODO: Carry? */
|
||||
return mem_get_byte(cpu, addr + cpu->state.x);
|
||||
}
|
||||
|
||||
uint8_t mem_get_byte_absy(struct cpu_t *cpu, uint16_t addr) {
|
||||
return mem_get_byte(cpu, addr + cpu->state.y); /* TODO: Carry? */
|
||||
return mem_get_byte(cpu, addr + cpu->state.y);
|
||||
}
|
||||
|
||||
uint8_t mem_get_byte_zpg(struct cpu_t *cpu, uint8_t addr) {
|
||||
return mem_get_byte(cpu, addr);
|
||||
return cpu->page0[addr];
|
||||
}
|
||||
|
||||
uint8_t mem_get_byte_zpgx(struct cpu_t *cpu, uint8_t addr) {
|
||||
return mem_get_byte(cpu, ((uint16_t) addr + cpu->state.x) & 0x00ff);
|
||||
return cpu->page0[((uint16_t) addr + cpu->state.x) & 0x00ff];
|
||||
}
|
||||
|
||||
uint8_t mem_get_byte_zpgy(struct cpu_t *cpu, uint8_t addr) {
|
||||
return mem_get_byte(cpu, ((uint16_t) addr + cpu->state.y) & 0x00ff);
|
||||
return cpu->page0[((uint16_t) addr + cpu->state.y) & 0x00ff];
|
||||
}
|
||||
|
||||
uint8_t mem_get_byte_indx(struct cpu_t *cpu, uint8_t addr) {
|
||||
return mem_get_byte(cpu, mem_get_word(cpu, (uint8_t)(addr + cpu->state.x)));
|
||||
return mem_get_byte(cpu, (((uint16_t) cpu->page0[((uint16_t)addr+1+cpu->state.x)&0x00ff] << 8) | (uint16_t) cpu->page0[((uint16_t) addr+cpu->state.x) & 0x00ff]));
|
||||
}
|
||||
|
||||
uint8_t mem_get_byte_indy(struct cpu_t *cpu, uint8_t addr) {
|
||||
return mem_get_byte(cpu, mem_get_word(cpu, addr) + cpu->state.y);
|
||||
return mem_get_byte(cpu, (((uint16_t) cpu->page0[addr+1] << 8) | (uint16_t) cpu->page0[addr]) + cpu->state.y);
|
||||
}
|
||||
|
||||
uint8_t mem_get_byte_ind(struct cpu_t *cpu, uint8_t addr) {
|
||||
return mem_get_byte(cpu, mem_get_word(cpu, addr));
|
||||
return mem_get_byte(cpu, ((uint16_t) cpu->page0[addr+1] << 8) | (uint16_t) cpu->page0[addr]);
|
||||
}
|
||||
|
||||
uint16_t mem_get_word(struct cpu_t *cpu, uint16_t addr) {
|
||||
// TODO Did I do this right?
|
||||
return ((uint16_t) mem_get_byte(cpu, addr+1) << 8) | (uint16_t) mem_get_byte(cpu, addr);
|
||||
}
|
||||
|
||||
// Setters
|
||||
|
||||
void mem_set_byte_zpg(struct cpu_t *cpu, uint8_t addr, uint8_t v) {
|
||||
mem_set_byte(cpu, addr, v);
|
||||
cpu->page0[addr] = v;
|
||||
}
|
||||
|
||||
void mem_set_byte_zpgx(struct cpu_t *cpu, uint8_t addr, uint8_t v) {
|
||||
mem_set_byte(cpu, ((uint16_t) addr + cpu->state.x) & 0x00ff, v);
|
||||
cpu->page0[((uint16_t) addr + cpu->state.x) & 0x00ff] = v;
|
||||
}
|
||||
|
||||
void mem_set_byte_zpgy(struct cpu_t *cpu, uint8_t addr, uint8_t v) {
|
||||
mem_set_byte(cpu, ((uint16_t) addr + cpu->state.y) & 0x00ff, v);
|
||||
cpu->page0[((uint16_t) addr + cpu->state.y) & 0x00ff] = v;
|
||||
}
|
||||
|
||||
void mem_set_byte_abs(struct cpu_t *cpu, uint16_t addr, uint8_t v) {
|
||||
@ -137,16 +136,15 @@ void mem_set_byte_absy(struct cpu_t *cpu, uint16_t addr, uint8_t v) {
|
||||
}
|
||||
|
||||
void mem_set_byte_indx(struct cpu_t *cpu, uint8_t addr, uint8_t v) {
|
||||
//uint8_t a = ;
|
||||
mem_set_byte(cpu, mem_get_word(cpu, (uint8_t)(addr + cpu->state.x)), v);
|
||||
mem_set_byte(cpu, (((uint16_t) cpu->page0[((uint16_t)addr+1+cpu->state.x)&0x00ff] << 8) | (uint16_t) cpu->page0[((uint16_t) addr+cpu->state.x) & 0x00ff]), v);
|
||||
}
|
||||
|
||||
void mem_set_byte_indy(struct cpu_t *cpu, uint8_t addr, uint8_t v) {
|
||||
mem_set_byte(cpu, mem_get_word(cpu, addr)+cpu->state.y, v);
|
||||
mem_set_byte(cpu, (((uint16_t) cpu->page0[addr+1] << 8) | (uint16_t) cpu->page0[addr]) + cpu->state.y, v);
|
||||
}
|
||||
|
||||
void mem_set_byte_ind(struct cpu_t *cpu, uint8_t addr, uint8_t v) {
|
||||
mem_set_byte(cpu, mem_get_word(cpu, addr), v);
|
||||
mem_set_byte(cpu, (((uint16_t) cpu->page0[addr+1] << 8) | (uint16_t) cpu->page0[addr]), v);
|
||||
}
|
||||
|
||||
void mem_set_word(struct cpu_t *cpu, uint16_t addr, uint16_t v) {
|
||||
|
Loading…
Reference in New Issue
Block a user