diff --git a/.vscode/settings.json b/.vscode/settings.json index 44636c6..ab8b1f2 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -8,6 +8,7 @@ "profileapi.h": "c", "type_traits": "c", "xtr1common": "c", - "chrono": "c" + "chrono": "c", + "interrupts.h": "c" } } \ No newline at end of file diff --git a/include/cart.h b/include/cart.h index 88fdfea..66df39c 100644 --- a/include/cart.h +++ b/include/cart.h @@ -28,4 +28,6 @@ void cart_write(u16 address, u8 value); bool cart_need_save(); bool cart_battery_load(); -bool cart_battery_save(); \ No newline at end of file +bool cart_battery_save(); + +u8 cart_get_rom_bank(); \ No newline at end of file diff --git a/include/cpu.h b/include/cpu.h index f086e2b..7c5a043 100644 --- a/include/cpu.h +++ b/include/cpu.h @@ -47,6 +47,8 @@ IN_PROC inst_get_processor(in_type type); #define CPU_FLAG_H BIT(ctx->regs.f, 5) #define CPU_FLAG_C BIT(ctx->regs.f, 4) +cpu_context *cpu_get_context(); + u16 cpu_read_reg(reg_type rt); void cpu_set_reg(reg_type rt, u16 val); diff --git a/include/gamepad.h b/include/gamepad.h index 8460056..4692c97 100644 --- a/include/gamepad.h +++ b/include/gamepad.h @@ -17,6 +17,7 @@ void gamepad_init(); bool gamepad_button_sel(); bool gamepad_dir_sel(); void gamepad_set_sel(u8 value); +void gamepad_int_update(); gamepad_state *gamepad_get_state(); u8 gamepad_get_output(); \ No newline at end of file diff --git a/lib/audio.c b/lib/audio.c index c04d737..331f5a8 100644 --- a/lib/audio.c +++ b/lib/audio.c @@ -353,14 +353,21 @@ void audio_sample_tick() { } if(ctx.buffer_write_index == FRAMES_PER_BUFFER) { - ctx.buffer_write_index = 0; float *data[2]; data[0] = ctx.left_audio_buffer; data[1] = ctx.right_audio_buffer; - int err = Pa_WriteStream(stream, data, FRAMES_PER_BUFFER); - if(err != paNoError && err != paOutputUnderflowed) { - fprintf(stderr, "portaudio stream error\n\tError Number: %d\n\tError Message: %s\n", err, Pa_GetErrorText(err)); - } + //long available = Pa_GetStreamWriteAvailable(stream); + //if(available > 0) { + // if(available > FRAMES_PER_BUFFER) { + // available = FRAMES_PER_BUFFER; + // } + // ctx.buffer_write_index -= available; + ctx.buffer_write_index = 0; + int err = Pa_WriteStream(stream, data, FRAMES_PER_BUFFER); + if(err != paNoError && err != paOutputUnderflowed) { + fprintf(stderr, "portaudio stream error\n\tError Number: %d\n\tError Message: %s\n", err, Pa_GetErrorText(err)); + } + //} } } } diff --git a/lib/cart.c b/lib/cart.c index 45d942f..fe635d5 100644 --- a/lib/cart.c +++ b/lib/cart.c @@ -355,3 +355,7 @@ bool cart_battery_save(){ fclose(fp); } + +u8 cart_get_rom_bank() { + return ctx.rom_bank_value; +} \ No newline at end of file diff --git a/lib/cpu.c b/lib/cpu.c index 143781f..a62b2b5 100644 --- a/lib/cpu.c +++ b/lib/cpu.c @@ -120,3 +120,7 @@ void cpu_set_ie_register(u8 ie){ void cpu_request_interrupt(interrupt_type t) { ctx.int_flags |= t; } + +cpu_context *cpu_get_context() { + return &ctx; +} \ No newline at end of file diff --git a/lib/gamepad.c b/lib/gamepad.c index 8491168..f3bc5fe 100644 --- a/lib/gamepad.c +++ b/lib/gamepad.c @@ -1,16 +1,33 @@ #include #include +#include typedef struct { bool button_sel; bool dir_sel; gamepad_state controller; + gamepad_state prev; } gamepad_context; static gamepad_context ctx = {0}; void gamepad_init(); +void gamepad_int_update(){ + if(ctx.button_sel) { + if((ctx.prev.a == 1 && ctx.controller.a == 0) || (ctx.prev.b == 1 && ctx.controller.b == 0) || (ctx.prev.select == 1 && ctx.controller.select == 0) || (ctx.prev.start == 1 && ctx.controller.start == 0)) { + cpu_request_interrupt(IT_JOYPAD); + return; + } + } + if(ctx.dir_sel) { + if((ctx.prev.up == 1 && ctx.controller.up == 0) || (ctx.prev.down == 1 && ctx.controller.down == 0) || (ctx.prev.left == 1 && ctx.controller.left == 0) || (ctx.prev.right == 1 && ctx.controller.right == 0)) { + cpu_request_interrupt(IT_JOYPAD); + } + } + +} + bool gamepad_button_sel(){ return ctx.button_sel; } diff --git a/lib/ppu_sm.c b/lib/ppu_sm.c index d5de13e..239198e 100644 --- a/lib/ppu_sm.c +++ b/lib/ppu_sm.c @@ -167,6 +167,8 @@ void ppu_mode_hblank() { if(frame_time < ppu_get_context()->target_frame_time) { delay((ppu_get_context()->target_frame_time - frame_time)); + } else if(frame_time > ppu_get_context()->target_frame_time) { + //printf("Frame timing missed!\n"); } while(ppu_get_context()->paused) { diff --git a/lib/ui.c b/lib/ui.c index 14f46c5..730fd7e 100644 --- a/lib/ui.c +++ b/lib/ui.c @@ -6,10 +6,14 @@ #include #include #include +#include +#include #include #include +#define VRAM_DEBUG 0 + SDL_Window *sdlWindow; SDL_Renderer *sdlRenderer; SDL_Texture *sdlTexture; @@ -41,7 +45,7 @@ void ui_init(){ SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT); - +#if VRAM_DEBUG == 1 SDL_CreateWindowAndRenderer(16 * 8 * scale, 32 * 8 * scale, 0, &sdlDebugWindow, &sdlDebugRenderer); debugScreen = SDL_CreateRGBSurface(0, (16 * 8 * scale) + (16 * scale), (32 * 8 * scale) + (64 * scale), 32, @@ -57,9 +61,10 @@ void ui_init(){ int x, y; SDL_GetWindowPosition(sdlWindow, &x, &y); SDL_SetWindowPosition(sdlDebugWindow, x+SCREEN_WIDTH, y); +#endif } -static unsigned long tile_colors[4] = {0xFF759833, 0xFF588F51, 0xFF3B7560, 0xFF2E615A}; +static unsigned long tile_colors[4] = {0xFF9ABB1B, 0xFF8AAB19, 0xFF2F6130, 0xFF0E370F}; void display_tile(SDL_Surface *surface, u16 startLocation, u16 tileNum, int x, int y) { SDL_Rect rc; @@ -278,9 +283,23 @@ void ui_update() { break; } } - SDL_RenderPresent(sdlRenderer); + char cpu_buffer[1024]; + sprintf_s(cpu_buffer, 1024, "PC: %04X, SP: %04X, AF: %02X%02X, BC: %02X%02X, DE: %02X%02X, HL: %02X%02X, Cart_Bank: %02d", cpu_get_context()->regs.pc, cpu_get_context()->regs.sp, cpu_get_context()->regs.a, cpu_get_context()->regs.f, cpu_get_context()->regs.b, cpu_get_context()->regs.c, cpu_get_context()->regs.d, cpu_get_context()->regs.e, cpu_get_context()->regs.h, cpu_get_context()->regs.l, cart_get_rom_bank()); + message = TTF_RenderText_Solid(sans, cpu_buffer, text_color); + messageTexture = SDL_CreateTextureFromSurface(sdlRenderer, message); + messageRect.x = 0; + messageRect.y = (YRES * scale) + 10; + messageRect.w = 500; + messageRect.h = 20; + SDL_RenderCopy(sdlRenderer, messageTexture, NULL, &messageRect); + SDL_SetRenderDrawColor(sdlRenderer, 0, 255, 0, 255); + SDL_FreeSurface(message); + SDL_DestroyTexture(messageTexture); + SDL_RenderPresent(sdlRenderer); +#if VRAM_DEBUG == 1 update_debug_window(); +#endif } void ui_on_key(bool down, u32 key_code) { @@ -325,6 +344,7 @@ void ui_on_key(bool down, u32 key_code) { case SDLK_LEFT: gamepad_get_state()->left = down; break; case SDLK_RIGHT: gamepad_get_state()->right = down; break; } + gamepad_int_update(); }