changeset 961:750995b587a0

Save State menu option is now fully functional. Load state sort of works, but is mostly broken.
author Michael Pavone <pavone@retrodev.com>
date Sun, 17 Apr 2016 23:50:41 -0700
parents 0abfecaaf5c8
children f52cb02a1466
files blastem.c blastem.h gst.c io.c menu.c menu.s68
diffstat 6 files changed, 66 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/blastem.c	Sun Apr 17 20:31:22 2016 -0700
+++ b/blastem.c	Sun Apr 17 23:50:41 2016 -0700
@@ -191,7 +191,6 @@
 }
 
 int break_on_sync = 0;
-int save_state = 0;
 char *save_state_path;
 
 //#define DO_DEBUG_PRINT
@@ -294,7 +293,7 @@
 		vdp_int_ack(v_context);
 		context->int_ack = 0;
 	}
-	if (!address && (break_on_sync || save_state)) {
+	if (!address && (break_on_sync || gen->save_state)) {
 		context->sync_cycle = context->current_cycle + 1;
 	}
 	adjust_int_cycle(context, v_context);
@@ -303,16 +302,29 @@
 			break_on_sync = 0;
 			debugger(context, address);
 		}
-		if (save_state && (z_context->pc || (!z_context->reset && !z_context->busreq))) {
-			save_state = 0;
+		if (gen->save_state && (z_context->pc || (!z_context->reset && !z_context->busreq))) {
+			uint8_t slot = gen->save_state - 1;
+			gen->save_state = 0;
 			//advance Z80 core to the start of an instruction
 			while (!z_context->pc)
 			{
 				sync_z80(z_context, z_context->current_cycle + MCLKS_PER_Z80);
 			}
-			save_gst(gen, save_state_path, address);
-			printf("Saved state to %s\n", save_state_path);
-		} else if(save_state) {
+			char *save_path;
+			if (slot == QUICK_SAVE_SLOT) {
+				save_path = save_state_path;
+			} else {
+				char slotname[] = "slot_0.gst";
+				slotname[5] = '0' + slot;
+				char const *parts[] = {gen->save_dir, "/", slotname};
+				save_path = alloc_concat_m(3, parts);
+			}
+			save_gst(gen, save_path, address);
+			printf("Saved state to %s\n", save_path);
+			if (slot != QUICK_SAVE_SLOT) {
+				free(save_path);
+			}
+		} else if(gen->save_state) {
 			context->sync_cycle = context->current_cycle + 1;
 		}
 	}
--- a/blastem.h	Sun Apr 17 20:31:22 2016 -0700
+++ b/blastem.h	Sun Apr 17 23:50:41 2016 -0700
@@ -48,17 +48,18 @@
 	io_port         ports[3];
 	uint8_t         bus_busy;
 	uint8_t         should_exit;
+	uint8_t         save_state;
 	eeprom_state    eeprom;
 };
 
 extern genesis_context * genesis;
 extern int headless;
 extern int break_on_sync;
-extern int save_state;
 extern tern_node * config;
 
 #define RAM_WORDS 32 * 1024
 #define Z80_RAM_BYTES 8 * 1024
+#define QUICK_SAVE_SLOT 10
 
 extern uint16_t *cart;
 extern uint16_t *ram;
--- a/gst.c	Sun Apr 17 20:31:22 2016 -0700
+++ b/gst.c	Sun Apr 17 23:50:41 2016 -0700
@@ -95,6 +95,7 @@
 	}
 	fseek(gstfile, GST_68K_RAM, SEEK_SET);
 	for (int i = 0; i < (32*1024);) {
+		//FIXME: Need to deal with code in RAM that has potentially changed after this
 		if (fread(buffer, 1, sizeof(buffer), gstfile) != sizeof(buffer)) {
 			fputs("Failed to read 68K RAM from savestate\n", stderr);
 			return 0;
--- a/io.c	Sun Apr 17 20:31:22 2016 -0700
+++ b/io.c	Sun Apr 17 23:50:41 2016 -0700
@@ -349,7 +349,7 @@
 			break_on_sync = 1;
 			break;
 		case UI_SAVE_STATE:
-			save_state = 1;
+			genesis->save_state = QUICK_SAVE_SLOT+1;
 			break;
 		case UI_NEXT_SPEED:
 			current_speed++;
--- a/menu.c	Sun Apr 17 20:31:22 2016 -0700
+++ b/menu.c	Sun Apr 17 23:50:41 2016 -0700
@@ -7,6 +7,8 @@
 #include "menu.h"
 #include "backend.h"
 #include "util.h"
+#include "gst.h"
+#include "m68k_internal.h" //needed for get_native_address_trans, should be eliminated once handling of PC is cleaned up
 
 
 uint16_t menu_read_w(uint32_t address, void * context)
@@ -273,6 +275,32 @@
 			}
 			copy_to_guest(m68k, dst, buffer, cur-buffer);
 			break;
+		case 5:
+			//save state
+			if (gen->next_context) {
+				gen->next_context->save_state = dst + 1;
+			}
+			m68k->should_return = 1;
+			break;
+		case 6:
+			//load state
+			if (gen->next_context && gen->next_context->save_dir) {
+				char numslotname[] = "slot_0.gst";
+				char *slotname;
+				if (dst == QUICK_SAVE_SLOT) {
+					slotname = "quicksave.gst";
+				} else {
+					numslotname[5] = '0' + dst;
+					slotname = numslotname;
+				}
+				char const *parts[] = {gen->next_context->save_dir, "/", slotname};
+				char *gstpath = alloc_concat_m(3, parts);
+				uint32_t pc = load_gst(gen->next_context, gstpath);
+				free(gstpath);
+				gen->next_context->m68k->resume_pc = get_native_address_trans(gen->next_context->m68k, pc);
+			}
+			m68k->should_return = 1;
+			break;
 		}
 		default:
 			fprintf(stderr, "WARNING: write to undefined menu port %X\n", address);
--- a/menu.s68	Sun Apr 17 20:31:22 2016 -0700
+++ b/menu.s68	Sun Apr 17 23:50:41 2016 -0700
@@ -192,6 +192,7 @@
 last_mbuttons  rs.b 1
 num_menu       rs.b 1
 num_slots      rs.b 1
+port_off       rs.b 1
 
 
 int_6:
@@ -353,6 +354,8 @@
 	add.w d0, d0
 	tst.b num_menu.w
 	bne .select_menu_button
+	tst.b num_slots.w
+	bne .select_save_slot
 	lea page_index.w, a2
 	move.l (0, a2, d0.w), a2
 	tst.b (-1, a2)
@@ -368,6 +371,16 @@
 	move.l (0, a2, d0.w), a2
 	addq #6, a7
 	jmp (a2)
+.select_save_slot:
+	lea menu_port, a3
+	moveq #0, d0
+	move.b port_off.w, d0
+	add.w d0, a3
+	move.b selected.w, d0
+	move.l d0, (a3)
+	addq #6, a7
+	jmp show_pause_menu
+	
 enter_dir:
 	lea menu_port+4, a3
 	move.l a2, (a3)
@@ -977,12 +990,14 @@
 	rts
 	
 save_state:
+	move.b #(5*4), port_off.w
 	bsr show_save_slots
 .wait
 	stop #$2500
 	bra .wait
 	
 load_state:
+	move.b #(6*4), port_off.w
 	bsr show_save_slots
 .wait
 	stop #$2500