run rom image, more instructions

This commit is contained in:
Matthew Laux 2022-07-14 01:26:59 -05:00
parent 261bb40563
commit b1dca59463
4 changed files with 62 additions and 20 deletions

View File

@ -103,7 +103,7 @@ int main(int argc, char *argv[])
dmg_new(&dmg, &cpu, &rom, &lcd);
cpu_bind_mem_model(&cpu, &dmg, dmg_read, dmg_write);
cpu.pc = 0;//0x100;
cpu.pc = 0x100;
// Setup SDL
// (Some versions of SDL before <2.0.10 appears to have performance/stalling issues on a minority of Windows systems,
@ -177,25 +177,25 @@ int main(int argc, char *argv[])
unsigned int lastDrawTime = 0, currentTime;
while (!done)
{
// Poll and handle events (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
SDL_Event event;
while (SDL_PollEvent(&event))
{
ImGui_ImplSDL2_ProcessEvent(&event);
if (event.type == SDL_QUIT)
done = true;
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
done = true;
}
dmg_step(&dmg);
currentTime = SDL_GetTicks();
if (currentTime >= lastDrawTime + 16) {
// Poll and handle events (inputs, window resize, etc.)
// You can read the io.WantCaptureMouse, io.WantCaptureKeyboard flags to tell if dear imgui wants to use your inputs.
// - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application, or clear/overwrite your copy of the mouse data.
// - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application, or clear/overwrite your copy of the keyboard data.
// Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags.
SDL_Event event;
while (SDL_PollEvent(&event))
{
ImGui_ImplSDL2_ProcessEvent(&event);
if (event.type == SDL_QUIT)
done = true;
if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_CLOSE && event.window.windowID == SDL_GetWindowID(window))
done = true;
}
// Start the Dear ImGui frame
ImGui_ImplOpenGL3_NewFrame();
ImGui_ImplSDL2_NewFrame();

View File

@ -582,6 +582,7 @@ void cpu_step(struct cpu *cpu)
case 0xc0: // RET NZ
if (!flag_isset(cpu, FLAG_ZERO)) {
cpu->pc = pop(cpu);
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
}
break;
case 0xc9: // RET
@ -599,6 +600,7 @@ void cpu_step(struct cpu *cpu)
case 0xd2: // JP NC,a16
if (flag_isset(cpu, FLAG_CARRY)) {
cpu->pc = read16(cpu, cpu->pc);
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
}
break;
@ -695,6 +697,18 @@ void cpu_step(struct cpu *cpu)
case 0xc5: // PUSH BC
push(cpu, read_bc(cpu));
break;
case 0xc8: // RET Z
if (flag_isset(cpu, FLAG_ZERO)) {
cpu->pc = pop(cpu);
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
}
break;
case 0xca: // JP Z, u16
if (flag_isset(cpu, FLAG_ZERO)) {
cpu->pc = read16(cpu, cpu->pc);
cpu->cycle_count += instructions[opc].cycles_branch - instructions[opc].cycles;
}
break;
case 0xcb:
extended_insn(cpu, read8(cpu, cpu->pc));
cpu->pc++;
@ -703,13 +717,28 @@ void cpu_step(struct cpu *cpu)
add(cpu, read8(cpu, cpu->pc), 1);
cpu->pc++;
break;
case 0xd1: // POP DE
write_de(cpu, pop(cpu));
break;
case 0xd5: // PUSH DE
push(cpu, read_de(cpu));
break;
case 0xe0: // LD (a8),A
write8(cpu, 0xff00 + read8(cpu, cpu->pc), cpu->a);
cpu->pc++;
break;
case 0xe1: // POP HL
write_hl(cpu, pop(cpu));
break;
case 0xe2: // LD (C),A
write8(cpu, 0xff00 + cpu->c, cpu->a);
break;
case 0xe5: // PUSH HL
push(cpu, read_hl(cpu));
break;
case 0xe9: // JP HL
cpu->pc = read_hl(cpu);
break;
case 0xea: // LD (a16),A
write8(cpu, read16(cpu, cpu->pc), cpu->a);
cpu->pc += 2;
@ -718,11 +747,21 @@ void cpu_step(struct cpu *cpu)
cpu->a = read8(cpu, 0xff00 + read8(cpu, cpu->pc));
cpu->pc++;
break;
case 0xf1: // POP AF
write_af(cpu, pop(cpu));
break;
case 0xf2: // LD A,(C)
cpu->a = read8(cpu, 0xff00 + cpu->c);
break;
case 0xf3: // DI
break;
case 0xf5: // PUSH AF
push(cpu, read_af(cpu));
break;
case 0xfa: // LD A,(u16)
cpu->a = read8(cpu, read16(cpu, cpu->pc));
cpu->pc += 2;
break;
case 0xfb: // EI
break;
default:

View File

@ -18,9 +18,10 @@ void dmg_new(struct dmg *dmg, struct cpu *cpu, struct rom *rom, struct lcd *lcd)
u8 dmg_read(void *_dmg, u16 address)
{
struct dmg *dmg = (struct dmg *) _dmg;
if (address < 0x100) {
return dmg_boot_rom[address];
} else if (address < 0x4000) {
// if (address < 0x100) {
// return dmg_boot_rom[address];
// } else if (address < 0x4000) {
if (address < 0x4000) {
return dmg->rom->data[address];
} else if (address < 0x8000) {
// TODO switchable rom bank
@ -79,7 +80,8 @@ void dmg_step(void *_dmg)
cpu_step(dmg->cpu);
// each line takes 456 cycles
if (dmg->cpu->cycle_count % 456 == 0) {
if (dmg->cpu->cycle_count - dmg->last_lcd_update >= 456) {
dmg->last_lcd_update = dmg->cpu->cycle_count;
int next_scanline = lcd_step(dmg->lcd);
if (next_scanline == 144) {
// vblank has started, draw all the stuff from ram into the lcd

View File

@ -12,6 +12,7 @@ struct dmg {
u8 main_ram[0x2000];
u8 video_ram[0x2000];
u8 zero_page[0x80];
u32 last_lcd_update;
};
void dmg_new(struct dmg *dmg, struct cpu *cpu, struct rom *rom, struct lcd *lcd);