diff --git a/cli/emulator.c b/cli/emulator.c index 8a0d58e..095e5e8 100644 --- a/cli/emulator.c +++ b/cli/emulator.c @@ -30,7 +30,8 @@ int emulator_main(int argc, char *argv[]) // test the cpu, rom, and dmg independently and use the cpu // for other non-GB stuff dmg_new(&dmg, &cpu, &rom, &lcd); - cpu_bind_mem_model(&cpu, &dmg, dmg_read, dmg_write); + cpu.dmg = &dmg; + // cpu_bind_mem_model(&cpu, &dmg, dmg_read, dmg_write); cpu.pc = 0x100; diff --git a/cli/imgui_example.cpp b/cli/imgui_example.cpp index 64a5e77..55d6fe4 100644 --- a/cli/imgui_example.cpp +++ b/cli/imgui_example.cpp @@ -156,7 +156,8 @@ int main(int argc, char *argv[]) // test the cpu, rom, and dmg independently and use the cpu // for other non-GB stuff dmg_new(&dmg, &cpu, &rom, &lcd); - cpu_bind_mem_model(&cpu, &dmg, dmg_read, dmg_write); + cpu.dmg = &dmg; + // cpu_bind_mem_model(&cpu, &dmg, dmg_read, dmg_write); cpu.pc = 0x100; diff --git a/src/cpu.c b/src/cpu.c index 4e07831..d8b912d 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -2,20 +2,10 @@ #include #include "cpu.h" +#include "dmg.h" #include "types.h" #include "instructions.h" -void cpu_bind_mem_model( - struct cpu *cpu, - void *mem_model, - u8 (*mem_read)(void *, u16), - void (*mem_write)(void *, u16, u8) -) { - cpu->mem_model = mem_model; - cpu->mem_read = mem_read; - cpu->mem_write = mem_write; -} - int flag_isset(struct cpu *cpu, int flag) { return (cpu->f & flag) != 0; @@ -66,7 +56,7 @@ void cpu_panic(struct cpu *cpu) static inline u8 read8(struct cpu *cpu, u16 address) { - return cpu->mem_read(cpu->mem_model, address); + return dmg_read(cpu->dmg, address); } static inline u16 read16(struct cpu *cpu, u16 address) @@ -78,12 +68,12 @@ static inline u16 read16(struct cpu *cpu, u16 address) static inline void write8(struct cpu *cpu, u16 address, u8 data) { - cpu->mem_write(cpu->mem_model, address, data); + dmg_write(cpu->dmg, address, data); } static inline void write16(struct cpu *cpu, u16 address, u16 data) { - cpu->mem_write(cpu->mem_model, address, data); + dmg_write(cpu->dmg, address, data); } static void inc_with_carry(struct cpu *regs, u8 *reg) @@ -493,15 +483,15 @@ static u16 check_interrupts(struct cpu *cpu) return 0; } - u16 enabled = cpu->mem_read(cpu->mem_model, 0xffff); - u16 requested = cpu->mem_read(cpu->mem_model, 0xff0f); + u16 enabled = dmg_read(cpu->dmg, 0xffff); + u16 requested = dmg_read(cpu->dmg, 0xff0f); for (k = 0; k < NUM_INTERRUPTS; k++) { int check = 1 << k; if ((enabled & check) && (requested & check)) { // clear request flag for this interrupt and disable all further // interrupts until service routine executes EI or RETI - cpu->mem_write(cpu->mem_model, 0xff0f, requested & ~check); + dmg_write(cpu->dmg, 0xff0f, requested & ~check); cpu->interrupt_enable = 0; return handlers[k]; } @@ -522,7 +512,7 @@ void cpu_step(struct cpu *cpu) return; } - u8 opc = cpu->mem_read(cpu->mem_model, cpu->pc); + u8 opc = dmg_read(cpu->dmg, cpu->pc); #ifdef GB6_DEBUG printf("0x%04x %s\n", cpu->pc, instructions[opc].format); #endif diff --git a/src/cpu.h b/src/cpu.h index 9f0b659..466e99f 100644 --- a/src/cpu.h +++ b/src/cpu.h @@ -3,6 +3,8 @@ #include "types.h" +struct dmg; + struct cpu { u8 a; @@ -18,17 +20,18 @@ struct cpu u32 cycle_count; u8 interrupt_enable; - u8 (*mem_read)(void *, u16); - void (*mem_write)(void *, u16, u8); - void *mem_model; + struct dmg *dmg; + // u8 (*mem_read)(void *, u16); + // void (*mem_write)(void *, u16, u8); + // void *mem_model; }; -void cpu_bind_mem_model( - struct cpu *cpu, - void *mem_model, - u8 (*mem_read)(void *, u16), - void (*mem_write)(void *, u16, u8) -); +// void cpu_bind_mem_model( +// struct cpu *cpu, +// void *mem_model, +// u8 (*mem_read)(void *, u16), +// void (*mem_write)(void *, u16, u8) +// ); void cpu_step(struct cpu *cpu); int flag_isset(struct cpu *cpu, int flag); diff --git a/src/dmg.c b/src/dmg.c index 833d6cf..8dfffe0 100644 --- a/src/dmg.c +++ b/src/dmg.c @@ -262,22 +262,22 @@ void dmg_step(void *_dmg) dmg_request_interrupt(dmg, INT_LCDSTAT); } - int lcdc = lcd_read(dmg->lcd, REG_LCDC); - if (lcdc & LCDC_ENABLE_BG) { - render_background(dmg, lcdc); - } + // int lcdc = lcd_read(dmg->lcd, REG_LCDC); + // if (lcdc & LCDC_ENABLE_BG) { + // render_background(dmg, lcdc); + // } - if (lcdc & LCDC_ENABLE_WINDOW) { - // printf("window\n"); - } + // if (lcdc & LCDC_ENABLE_WINDOW) { + // // printf("window\n"); + // } - lcd_apply_scroll(dmg->lcd); + // lcd_apply_scroll(dmg->lcd); - if (lcdc & LCDC_ENABLE_OBJ) { - render_objs(dmg); - } + // if (lcdc & LCDC_ENABLE_OBJ) { + // render_objs(dmg); + // } - lcd_draw(dmg->lcd); + // lcd_draw(dmg->lcd); } } else { int scan = lcd_read(dmg->lcd, REG_LY); diff --git a/src/mbc.c b/src/mbc.c index f556152..33f434b 100644 --- a/src/mbc.c +++ b/src/mbc.c @@ -6,16 +6,6 @@ #include "dmg.h" #include "rom.h" -static int mbc_noop_read(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 *out_data) -{ - return 0; -} - -static int mbc_noop_write(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 data) -{ - return 0; -} - static int mbc1_read(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 *out_data) { if (addr >= 0x4000 && addr <= 0x7fff) { @@ -60,35 +50,29 @@ static int mbc1_write(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 data) return 0; } -struct mbc mbc_noop = { - mbc_noop_read, - mbc_noop_write, -}; - -struct mbc mbc1 = { - mbc1_read, - mbc1_write, -}; - struct mbc *mbc_new(int type) { - switch (type) { - case 0: - return &mbc_noop; - case 1: - case 2: - case 3: - return &mbc1; + static struct mbc mbc; + if (type > 3) { + return NULL; } - return NULL; + mbc.type = type; + + return &mbc; } int mbc_read(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 *out_data) { - return mbc->read_fn(mbc, dmg, addr, out_data); + if (mbc->type == 0) { + return 0; + } + return mbc1_read(mbc, dmg, addr, out_data); } int mbc_write(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 data) { - return mbc->write_fn(mbc, dmg, addr, data); + if (mbc->type == 0) { + return 0; + } + return mbc1_write(mbc, dmg, addr, data); } diff --git a/src/mbc.h b/src/mbc.h index d1d429b..fb9c62a 100644 --- a/src/mbc.h +++ b/src/mbc.h @@ -6,8 +6,6 @@ struct dmg; struct mbc { - int (*read_fn)(struct mbc *, struct dmg *, u16, u8 *); - int (*write_fn)(struct mbc *, struct dmg *, u16, u8); int type; int rom_bank; int ram_bank; @@ -16,7 +14,10 @@ struct mbc { }; struct mbc *mbc_new(int type); + +// set *out_data and return 1 if handled, return 0 for base dmg behavior int mbc_read(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 *out_data); +// return 1 if handled, return 0 for base dmg behavior int mbc_write(struct mbc *mbc, struct dmg *dmg, u16 addr, u8 data); #endif \ No newline at end of file diff --git a/system6/emulator.c b/system6/emulator.c index b2bea9a..3bd404f 100644 --- a/system6/emulator.c +++ b/system6/emulator.c @@ -59,18 +59,18 @@ Rect offscreenRect = { 0, 0, 144, 160 }; BitMap offscreenBmp; -int lastTicks; +int execTime; void Render(void) { - long k = 0, dst, bit; - for (dst = 0; dst < 20 * 144; dst++) { - for (bit = 7; bit >= 0; bit--) { - offscreen[dst] |= lcd.pixels[k++]; - offscreen[dst] <<= 1; - } - dst++; - } + // long k = 0, dst, bit; + // for (dst = 0; dst < 20 * 144; dst++) { + // for (bit = 7; bit >= 0; bit--) { + // offscreen[dst] |= lcd.pixels[k++]; + // offscreen[dst] <<= 1; + // } + // dst++; + // } /* offscreen[dst] = lcd.pixels[k++] << 7; @@ -83,16 +83,25 @@ void Render(void) offscreen[dst] |= lcd.pixels[k++]; */ SetPort(g_wp); - CopyBits(&offscreenBmp, &g_wp->portBits, &offscreenRect, &offscreenRect, srcCopy, NULL); + // CopyBits(&offscreenBmp, &g_wp->portBits, &offscreenRect, &offscreenRect, srcCopy, NULL); - //EraseRect(&g_wp->portRect); - // MoveTo(10, 160); - // char debug[128]; - // sprintf(debug, "PC: %04x", cpu.pc); - // C2PStr(debug); - // DrawString(debug); + EraseRect(&g_wp->portRect); + MoveTo(10, 180); + char debug[128]; + double ms = execTime / 600.0; + sprintf(debug, "10000 insn %d ticks, %f ms per instruction", execTime, ms); + C2PStr(debug); + DrawString(debug); } +// 417 ticks +// 10000 instructions + +// 0.0417 tick per instruction +// 1/60 second per tick +// 0.000695 second per instruction +// 0.695 ms per instruction + void StartEmulation(void) { g_wp = NewWindow(0, &windowBounds, WINDOW_TITLE, true, @@ -188,7 +197,7 @@ void ShowAboutBox(void) // DrawDialog(dp); // while(!GetNextEvent(mDownMask, &e)); // while(WaitMouseUp()); - + DisposeDialog(dp); } @@ -264,25 +273,26 @@ int main(int argc, char *argv[]) int executed; int paused = 0; int pause_next = 0; - + InitEverything(); lcd_new(&lcd); dmg_new(&dmg, &cpu, &rom, &lcd); - cpu_bind_mem_model(&cpu, &dmg, dmg_read, dmg_write); + cpu.dmg = &dmg; + // cpu_bind_mem_model(&cpu, &dmg, dmg_read, dmg_write); cpu.pc = 0x100; - - int start = TickCount(); + while(g_running) { if (emulationOn) { + int k; + int start = TickCount(); + for (k = 0; k < 10000; k++) { dmg_step(&dmg); - int now = TickCount(); - if (now > lastTicks + 100) { - lastTicks = now; - Render(); - } - if (Button()) g_running = false; + } + execTime = TickCount() - start; + emulationOn = false; + Render(); } else { if(WaitNextEvent(everyEvent, &evt, 0, 0) != nullEvent) { if (IsDialogEvent(&evt)) {