summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--default.cfg1
-rw-r--r--genesis.c1
-rw-r--r--io.c10
-rw-r--r--sms.c11
-rw-r--r--vdp.c16
-rw-r--r--vdp.h3
6 files changed, 40 insertions, 2 deletions
diff --git a/default.cfg b/default.cfg
index 8074b57..99dd9d6 100644
--- a/default.cfg
+++ b/default.cfg
@@ -33,6 +33,7 @@ bindings {
- ui.prev_speed
f11 ui.toggle_fullscreen
tab ui.soft_reset
+ z ui.sms_pause
rctrl ui.toggle_keyboard_captured
}
pads {
diff --git a/genesis.c b/genesis.c
index ef1fa3a..ebc01bd 100644
--- a/genesis.c
+++ b/genesis.c
@@ -1035,6 +1035,7 @@ genesis_context *alloc_init_genesis(rom_info *rom, void *main_rom, void *lock_on
gen->header.request_exit = request_exit;
gen->header.inc_debug_mode = inc_debug_mode;
gen->header.inc_debug_pal = inc_debug_pal;
+ gen->header.type = SYSTEM_GENESIS;
set_region(gen, rom, force_region);
gen->vdp = malloc(sizeof(vdp_context));
diff --git a/io.c b/io.c
index b6ecabe..64b5424 100644
--- a/io.c
+++ b/io.c
@@ -18,6 +18,7 @@
#include "io.h"
#include "blastem.h"
#include "genesis.h"
+#include "sms.h"
#include "render.h"
#include "util.h"
@@ -74,6 +75,7 @@ typedef enum {
UI_TOGGLE_KEYBOARD_CAPTURE,
UI_TOGGLE_FULLSCREEN,
UI_SOFT_RESET,
+ UI_SMS_PAUSE,
UI_SCREENSHOT,
UI_EXIT
} ui_action;
@@ -493,6 +495,12 @@ void handle_binding_up(keybinding * binding)
case UI_SOFT_RESET:
current_system->soft_reset(current_system);
break;
+ case UI_SMS_PAUSE:
+ if (current_system->type == SYSTEM_SMS) {
+ sms_context *sms = (sms_context *)current_system;
+ vdp_pbc_pause(sms->vdp);
+ }
+ break;
case UI_SCREENSHOT: {
char *screenshot_base = tern_find_path(config, "ui\0screenshot_path\0", TVAL_PTR).ptrval;
if (!screenshot_base) {
@@ -690,6 +698,8 @@ int parse_binding_target(char * target, tern_node * padbuttons, tern_node *mouse
*ui_out = UI_TOGGLE_FULLSCREEN;
} else if (!strcmp(target + 3, "soft_reset")) {
*ui_out = UI_SOFT_RESET;
+ } else if (!strcmp(target + 3, "sms_pause")) {
+ *ui_out = UI_SMS_PAUSE;
} else if (!strcmp(target + 3, "screenshot")) {
*ui_out = UI_SCREENSHOT;
} else if(!strcmp(target + 3, "exit")) {
diff --git a/sms.c b/sms.c
index 2c8c3e6..1ba6902 100644
--- a/sms.c
+++ b/sms.c
@@ -193,7 +193,7 @@ static void run_sms(system_header *system)
{
render_disable_ym();
sms_context *sms = (sms_context *)system;
- uint32_t target_cycle = sms->z80->current_cycle + 3420*262;
+ uint32_t target_cycle = sms->z80->current_cycle + 3420*16;
//TODO: PAL support
render_set_video_standard(VID_NTSC);
while (!sms->should_return)
@@ -202,6 +202,12 @@ static void run_sms(system_header *system)
system->enter_debugger = 0;
zdebugger(sms->z80, sms->z80->pc);
}
+ if (sms->z80->nmi_start == CYCLE_NEVER) {
+ uint32_t nmi = vdp_next_nmi(sms->vdp);
+ if (nmi != CYCLE_NEVER) {
+ z80_assert_nmi(sms->z80, nmi);
+ }
+ }
z80_run(sms->z80, target_cycle);
if (sms->z80->reset) {
z80_clear_reset(sms->z80, sms->z80->current_cycle + 128*15);
@@ -209,7 +215,7 @@ static void run_sms(system_header *system)
target_cycle = sms->z80->current_cycle;
vdp_run_context(sms->vdp, target_cycle);
psg_run(sms->psg, target_cycle);
- target_cycle += 3420*262;
+ target_cycle += 3420*16;
if (target_cycle > 0x10000000) {
uint32_t adjust = sms->z80->current_cycle - 3420*262*2;
io_adjust_cycles(sms->io.ports, sms->z80->current_cycle, adjust);
@@ -355,6 +361,7 @@ sms_context *alloc_configure_sms(system_media *media, uint32_t opts, uint8_t for
sms->header.soft_reset = soft_reset;
sms->header.inc_debug_mode = inc_debug_mode;
sms->header.inc_debug_pal = inc_debug_pal;
+ sms->header.type = SYSTEM_SMS;
return sms;
} \ No newline at end of file
diff --git a/vdp.c b/vdp.c
index f222b83..830ff41 100644
--- a/vdp.c
+++ b/vdp.c
@@ -1685,6 +1685,9 @@ static void vdp_advance_line(vdp_context *context)
if (context->state == PREPARING) {
context->state = ACTIVE;
}
+ if (context->vcounter == 0x1FF) {
+ context->flags2 &= ~FLAG2_PAUSE;
+ }
if (context->state != ACTIVE) {
context->hint_counter = context->regs[REG_HINT];
@@ -3383,6 +3386,19 @@ uint32_t vdp_next_vint_z80(vdp_context * context)
return context->cycles + cycles_to_vint;
}
+uint32_t vdp_next_nmi(vdp_context *context)
+{
+ if (!(context->flags2 & FLAG2_PAUSE)) {
+ return 0xFFFFFFFF;
+ }
+ return context->cycles + vdp_cycles_to_line(context, 0x1FF);
+}
+
+void vdp_pbc_pause(vdp_context *context)
+{
+ context->flags2 |= FLAG2_PAUSE;
+}
+
void vdp_int_ack(vdp_context * context)
{
//CPU interrupt acknowledge is only used in Mode 5
diff --git a/vdp.h b/vdp.h
index 18f0142..0a1bbb5 100644
--- a/vdp.h
+++ b/vdp.h
@@ -59,6 +59,7 @@
#define FLAG2_REGION_PAL 0x10
#define FLAG2_EVEN_FIELD 0x20
#define FLAG2_BYTE_PENDING 0x40
+#define FLAG2_PAUSE 0x80
#define DISPLAY_ENABLE 0x40
@@ -238,6 +239,7 @@ void vdp_adjust_cycles(vdp_context * context, uint32_t deduction);
uint32_t vdp_next_hint(vdp_context * context);
uint32_t vdp_next_vint(vdp_context * context);
uint32_t vdp_next_vint_z80(vdp_context * context);
+uint32_t vdp_next_nmi(vdp_context *context);
void vdp_int_ack(vdp_context * context);
void vdp_print_sprite_table(vdp_context * context);
void vdp_print_reg_explain(vdp_context * context);
@@ -245,5 +247,6 @@ void latch_mode(vdp_context * context);
uint32_t vdp_cycles_to_frame_end(vdp_context * context);
void write_cram(vdp_context * context, uint16_t address, uint16_t value);
void vdp_check_update_sat_byte(vdp_context *context, uint32_t address, uint8_t value);
+void vdp_pbc_pause(vdp_context *context);
#endif //VDP_H_