From 9ebec735c488e2f7ac29933fb51b4e6e65c7b93f Mon Sep 17 00:00:00 2001
From: Ian C <ianc@noddybox.co.uk>
Date: Fri, 5 Dec 2008 00:37:26 +0000
Subject: Initial working version of memory snapshots

---
 source/gui.c      |  14 ++++----
 source/keyboard.c |  87 ++++++++++++++++++++++++++++++--------------
 source/main.c     |   5 ---
 source/snapshot.c |  10 +++---
 source/stream.c   |  86 ++++++++++++++++++++++++++++++++++++++++++++
 source/z80.c      | 106 +++++++++++++++++++++++++++---------------------------
 source/zx81.c     | 106 +++++++++++++++++++++++++++++++-----------------------
 7 files changed, 273 insertions(+), 141 deletions(-)
 create mode 100644 source/stream.c

(limited to 'source')

diff --git a/source/gui.c b/source/gui.c
index 0400197..7d328b7 100644
--- a/source/gui.c
+++ b/source/gui.c
@@ -215,7 +215,7 @@ int GUI_Menu(const char *opts[])
     w=w*8+16;
 
     x=SCREEN_WIDTH/2-w/2;
-    y=SCREEN_HEIGHT/2-h/2;
+    y=2;
 
     while(!done)
     {
@@ -716,7 +716,7 @@ int GUI_FileSelect(char pwd[], char selected_file[], const char *filter)
 }
 
 
-int GUI_InputName(char name[], int maxlen)
+int GUI_InputName(const char *prompt, const char *ext, char name[], int maxlen)
 {
     struct
     {
@@ -778,12 +778,12 @@ int GUI_InputName(char name[], int maxlen)
     {
 	if (update)
 	{
-	    sprintf(text, "enter the snapshot name:\n"
-			  "\"%s%%l%%\""
+	    sprintf(text, "%s:\n"
+			  "\"%s%%l%%%s\""
 			  "\n\n\npress enter to accept.\n"
 			  "press period to backspace.\n"
-			  "press space/break to cancel\n",
-			  name);
+			  "press space/break to cancel.\n",
+			  prompt, name, ext);
 
 	    ZX81DisplayString(text);
 
@@ -851,6 +851,8 @@ int GUI_InputName(char name[], int maxlen)
 	swiWaitForVBlank();
     }
 
+    ZX81ResumeDisplay();
+
     return accept;
 }
 
diff --git a/source/keyboard.c b/source/keyboard.c
index 6483b1c..078bc78 100644
--- a/source/keyboard.c
+++ b/source/keyboard.c
@@ -278,6 +278,7 @@ void SK_DisplayKeyboard(void)
 {
     static sImage img;
     static int loaded;
+    int f;
 
     if (!loaded)
     {
@@ -286,6 +287,22 @@ void SK_DisplayKeyboard(void)
     }
 
     FB_Blit(&img,0,0,PAL_OFFSET);
+
+    /* Update any on-screen indicators
+    */
+    for(f=SK_1; f<SK_CONFIG; f++)
+    {
+	if (key_state[f].state)
+	{
+	    int x,y;
+
+	    x = 3 + (f % 10) * 25;
+	    y = 37 + (f / 10) * 30;
+	    
+	    FB_Box(x, y, 25, 18, key_state[f].new_state ?
+					    selection_on : selection_off);
+	}
+    }
 }
 
 
@@ -412,37 +429,55 @@ const char *SK_KeyName(SoftKey k)
 
 void SK_SaveSnapshot(FILE *fp)
 {
-    STRPUT(fp, pad_left_key);
-    STRPUT(fp, pad_right_key);
-    STRPUT(fp, pad_up_key);
-    STRPUT(fp, pad_down_key);
-    STRPUT(fp, pad_A_key);
-    STRPUT(fp, pad_B_key);
-    STRPUT(fp, pad_X_key);
-    STRPUT(fp, pad_Y_key);
-    STRPUT(fp, pad_R_key);
-    STRPUT(fp, pad_L_key);
-    STRPUT(fp, pad_start_key);
-    STRPUT(fp, pad_select_key);
-    STRPUT(fp, key_state);
+    int f;
+
+    PUT_Long(fp, pad_left_key);
+    PUT_Long(fp, pad_right_key);
+    PUT_Long(fp, pad_up_key);
+    PUT_Long(fp, pad_down_key);
+    PUT_Long(fp, pad_A_key);
+    PUT_Long(fp, pad_B_key);
+    PUT_Long(fp, pad_X_key);
+    PUT_Long(fp, pad_Y_key);
+    PUT_Long(fp, pad_R_key);
+    PUT_Long(fp, pad_L_key);
+    PUT_Long(fp, pad_start_key);
+    PUT_Long(fp, pad_select_key);
+
+    for(f = 0; f < NUM_SOFT_KEYS; f++)
+    {
+    	PUT_Long(fp, key_state[f].state);
+    	PUT_Long(fp, key_state[f].new_state);
+    	PUT_Long(fp, key_state[f].handled);
+    	PUT_Long(fp, key_state[f].is_sticky);
+    }
 }
 
 
 void SK_LoadSnapshot(FILE *fp)
 {
-    STRGET(fp, pad_left_key);
-    STRGET(fp, pad_right_key);
-    STRGET(fp, pad_up_key);
-    STRGET(fp, pad_down_key);
-    STRGET(fp, pad_A_key);
-    STRGET(fp, pad_B_key);
-    STRGET(fp, pad_X_key);
-    STRGET(fp, pad_Y_key);
-    STRGET(fp, pad_R_key);
-    STRGET(fp, pad_L_key);
-    STRGET(fp, pad_start_key);
-    STRGET(fp, pad_select_key);
-    STRGET(fp, key_state);
+    int f;
+
+    pad_left_key = GET_Long(fp);
+    pad_right_key = GET_Long(fp);
+    pad_up_key = GET_Long(fp);
+    pad_down_key = GET_Long(fp);
+    pad_A_key = GET_Long(fp);
+    pad_B_key = GET_Long(fp);
+    pad_X_key = GET_Long(fp);
+    pad_Y_key = GET_Long(fp);
+    pad_R_key = GET_Long(fp);
+    pad_L_key = GET_Long(fp);
+    pad_start_key = GET_Long(fp);
+    pad_select_key = GET_Long(fp);
+
+    for(f = 0; f < NUM_SOFT_KEYS; f++)
+    {
+    	key_state[f].state = GET_Long(fp);
+    	key_state[f].new_state = GET_Long(fp);
+    	key_state[f].handled = GET_Long(fp);
+    	key_state[f].is_sticky = GET_Long(fp);
+    }
 }
 
 
diff --git a/source/main.c b/source/main.c
index c196608..674478e 100644
--- a/source/main.c
+++ b/source/main.c
@@ -399,13 +399,8 @@ int main(int argc, char *argv[])
 
     while(1)
     {
-	static unsigned cycle;
-
 	SoftKeyEvent ev;
 
-	DS81_DEBUG_STATUS("PC = %4.4x   I = %u", z80->PC, cycle);
-	cycle++;
-
     	Z80Exec(z80);
 
 	while(SK_GetEvent(&ev))
diff --git a/source/snapshot.c b/source/snapshot.c
index f5a8b9c..14f0e30 100644
--- a/source/snapshot.c
+++ b/source/snapshot.c
@@ -96,7 +96,7 @@ void SNAP_Save(Z80 *cpu)
     	return;
     }
 
-    if(!GUI_InputName(base, 8) || !base[0])
+    if(!GUI_InputName("enter snapshot filename", ".d81", base, 8) || !base[0])
     {
     	return;
     }
@@ -121,6 +121,10 @@ void SNAP_Save(Z80 *cpu)
 	ZX81SaveSnapshot(fp);
     	fclose(fp);
     }
+    else
+    {
+	GUI_Alert(FALSE, "Failed to save snapshot");
+    }
 }
 
 void SNAP_Load(Z80 *cpu, const char *optional_name)
@@ -162,13 +166,9 @@ void SNAP_Load(Z80 *cpu, const char *optional_name)
 	}
 	else
 	{
-	    DS81_DEBUG("Loading SK snap");
 	    SK_LoadSnapshot(fp);
-	    DS81_DEBUG("Loading Z80 snap");
 	    Z80LoadSnapshot(cpu, fp);
-	    DS81_DEBUG("Loading ZX81 snap");
 	    ZX81LoadSnapshot(fp);
-	    DS81_DEBUG("Snap loaded");
 	}
 
     	fclose(fp);
diff --git a/source/stream.c b/source/stream.c
new file mode 100644
index 0000000..f471d93
--- /dev/null
+++ b/source/stream.c
@@ -0,0 +1,86 @@
+/*
+    ds81 - Nintendo DS ZX81 emulator
+
+    Copyright (C) 2006  Ian Cowburn <ianc@noddybox.co.uk>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    -------------------------------------------------------------------------
+
+    Provides the routines for streaming.
+
+*/
+#include "stream.h"
+
+/* The long functions are a tad convuluted, but I'm in a dash.
+*/
+
+void PUT_Byte(FILE *fp, unsigned char c)
+{
+    fputc(c, fp);
+}
+
+void PUT_Long(FILE *fp, long l)
+{
+    union {long l; unsigned char c[4];} u;
+
+    u.l = l;
+
+    fputc(u.c[0], fp);
+    fputc(u.c[1], fp);
+    fputc(u.c[2], fp);
+    fputc(u.c[3], fp);
+}
+
+void PUT_ULong(FILE *fp, unsigned long l)
+{
+    union {unsigned long l; unsigned char c[4];} u;
+
+    u.l = l;
+
+    fputc(u.c[0], fp);
+    fputc(u.c[1], fp);
+    fputc(u.c[2], fp);
+    fputc(u.c[3], fp);
+}
+
+unsigned char GET_Byte(FILE *fp)
+{
+    return (unsigned char)fgetc(fp);
+}
+
+long GET_Long(FILE *fp)
+{
+    union {long l; unsigned char c[4];} u;
+
+    u.c[0] = (unsigned char)fgetc(fp);
+    u.c[1] = (unsigned char)fgetc(fp);
+    u.c[2] = (unsigned char)fgetc(fp);
+    u.c[3] = (unsigned char)fgetc(fp);
+
+    return u.l;
+}
+
+unsigned long GET_ULong(FILE *fp)
+{
+    union {unsigned long l; unsigned char c[4];} u;
+
+    u.c[0] = (unsigned char)fgetc(fp);
+    u.c[1] = (unsigned char)fgetc(fp);
+    u.c[2] = (unsigned char)fgetc(fp);
+    u.c[3] = (unsigned char)fgetc(fp);
+
+    return u.l;
+}
diff --git a/source/z80.c b/source/z80.c
index d4205c5..e6cc2f9 100644
--- a/source/z80.c
+++ b/source/z80.c
@@ -333,64 +333,62 @@ const char *Z80Disassemble(Z80 *cpu, Z80Word *pc)
 
 void Z80SaveSnapshot(Z80 *cpu, FILE *fp)
 {
-    STRPUT(fp, cpu->PC);
-    STRPUT(fp, cpu->AF);
-    STRPUT(fp, cpu->BC);
-    STRPUT(fp, cpu->DE);
-    STRPUT(fp, cpu->HL);
-    STRPUT(fp, cpu->AF_);
-    STRPUT(fp, cpu->BC_);
-    STRPUT(fp, cpu->DE_);
-    STRPUT(fp, cpu->HL_);
-    STRPUT(fp, cpu->IX);
-    STRPUT(fp, cpu->IY);
-    STRPUT(fp, cpu->SP);
-    STRPUT(fp, cpu->IFF1);
-    STRPUT(fp, cpu->IFF2);
-    STRPUT(fp, cpu->IM);
-    STRPUT(fp, cpu->I);
-    STRPUT(fp, cpu->R);
-    STRPUT(fp, cpu->R);
-
-    STRPUT(fp, cpu->priv->cycle);
-    STRPUT(fp, cpu->priv->halt);
-    STRPUT(fp, cpu->priv->shift);
-    STRPUT(fp, cpu->priv->raise);
-    STRPUT(fp, cpu->priv->devbyte);
-    STRPUT(fp, cpu->priv->nmi);
-    STRPUT(fp, cpu->priv->callback);
-    STRPUT(fp, cpu->priv->last_cb);
+    PUT_ULong(fp, cpu->PC);
+    PUT_ULong(fp, cpu->AF.w);
+    PUT_ULong(fp, cpu->BC.w);
+    PUT_ULong(fp, cpu->DE.w);
+    PUT_ULong(fp, cpu->HL.w);
+    PUT_ULong(fp, cpu->AF_);
+    PUT_ULong(fp, cpu->BC_);
+    PUT_ULong(fp, cpu->DE_);
+    PUT_ULong(fp, cpu->HL_);
+    PUT_ULong(fp, cpu->IX.w);
+    PUT_ULong(fp, cpu->IY.w);
+    PUT_ULong(fp, cpu->SP);
+    PUT_Byte(fp, cpu->IFF1);
+    PUT_Byte(fp, cpu->IFF2);
+    PUT_Byte(fp, cpu->IM);
+    PUT_Byte(fp, cpu->I);
+    PUT_Byte(fp, cpu->R);
+    PUT_Byte(fp, cpu->R);
+
+    PUT_ULong(fp, cpu->priv->cycle);
+    PUT_Long(fp, cpu->priv->halt);
+    PUT_Byte(fp, cpu->priv->shift);
+    PUT_Long(fp, cpu->priv->raise);
+    PUT_Byte(fp, cpu->priv->devbyte);
+    PUT_Long(fp, cpu->priv->nmi);
+    PUT_Long(fp, cpu->priv->last_cb);
 }
 
 void Z80LoadSnapshot(Z80 *cpu, FILE *fp)
 {
-    STRGET(fp, cpu->PC);
-    STRGET(fp, cpu->AF);
-    STRGET(fp, cpu->BC);
-    STRGET(fp, cpu->DE);
-    STRGET(fp, cpu->HL);
-    STRGET(fp, cpu->AF_);
-    STRGET(fp, cpu->BC_);
-    STRGET(fp, cpu->DE_);
-    STRGET(fp, cpu->HL_);
-    STRGET(fp, cpu->IX);
-    STRGET(fp, cpu->IY);
-    STRGET(fp, cpu->SP);
-    STRGET(fp, cpu->IFF1);
-    STRGET(fp, cpu->IFF2);
-    STRGET(fp, cpu->IM);
-    STRGET(fp, cpu->I);
-    STRGET(fp, cpu->R);
-    STRGET(fp, cpu->R);
-
-    STRGET(fp, cpu->priv->cycle);
-    STRGET(fp, cpu->priv->halt);
-    STRGET(fp, cpu->priv->shift);
-    STRGET(fp, cpu->priv->raise);
-    STRGET(fp, cpu->priv->devbyte);
-    STRGET(fp, cpu->priv->nmi);
-    STRGET(fp, cpu->priv->callback);
-    STRGET(fp, cpu->priv->last_cb);
+    cpu->PC = GET_ULong(fp);
+    cpu->AF.w = GET_ULong(fp);
+    cpu->BC.w = GET_ULong(fp);
+    cpu->DE.w = GET_ULong(fp);
+    cpu->HL.w = GET_ULong(fp);
+    cpu->AF_ = GET_ULong(fp);
+    cpu->BC_ = GET_ULong(fp);
+    cpu->DE_ = GET_ULong(fp);
+    cpu->HL_ = GET_ULong(fp);
+    cpu->IX.w = GET_ULong(fp);
+    cpu->IY.w = GET_ULong(fp);
+    cpu->SP = GET_ULong(fp);
+    cpu->IFF1 = GET_Byte(fp);
+    cpu->IFF2 = GET_Byte(fp);
+    cpu->IM = GET_Byte(fp);
+    cpu->I = GET_Byte(fp);
+    cpu->R = GET_Byte(fp);
+    cpu->R = GET_Byte(fp);
+
+    cpu->priv->cycle = GET_ULong(fp);
+    cpu->priv->halt = GET_Long(fp);
+    cpu->priv->shift = GET_Byte(fp);
+    cpu->priv->raise = GET_Long(fp);
+    cpu->priv->devbyte = GET_Byte(fp);
+    cpu->priv->nmi = GET_Long(fp);
+    cpu->priv->last_cb = GET_Long(fp);
 }
 
 /* END OF FILE */
diff --git a/source/zx81.c b/source/zx81.c
index a8620c3..00d6015 100644
--- a/source/zx81.c
+++ b/source/zx81.c
@@ -226,40 +226,28 @@ static void RomPatch(void)
 
 static Z80Byte FromASCII(char c)
 {
-    switch(c)
-    {
-	case '\'':
-	case '"':
-	    return 11;
-
-	case '(':
-	    return 16;
-
-	case ')':
-	    return 17;
+    static const char *charset =
+      /* 0123456789 */
+    	" _________"
+	"_\"#$:?()><"
+	"=+-*/:,.01"
+	"23456789ab"
+	"cdefghijkl"
+	"mnopqrstuv"
+	"wxyz";
 
-    	case '-':
-	    return 22;
-
-	case '*':
-	    return 23;
+    int f;
 
-	case ',':
-	    return 26;
+    c = tolower(c);
 
-	case '.':
-	    return 27;
+    for(f = 0; charset[f]; f++)
+    {
+    	if (charset[f] == c)
+	{
+	    return f;
+	}
     }
 
-    if (c>='0' && c<='9')
-	return (c-'0')+28;
-
-    if (c>='a' && c<='z')
-    	return (c-'a')+38;
-
-    if (c>='A' && c<='Z')
-    	return (c-'A')+38;
-
     return 0;
 }
 
@@ -1028,6 +1016,10 @@ void ZX81SuspendDisplay(void)
 void ZX81ResumeDisplay(void)
 {
     ClearText();
+
+    /* Reset last_I to force hi/lo res detection
+    */
+    last_I = 0;
 }
 
 
@@ -1081,27 +1073,51 @@ void ZX81Reconfigure(void)
 
 void ZX81SaveSnapshot(FILE *fp)
 {
-    STRPUT(fp, mem);
-    STRPUT(fp, matrix);
-    STRPUT(fp, waitkey);
-    STRPUT(fp, started);
-    STRPUT(fp, RAMBOT);
-    STRPUT(fp, RAMTOP);
-    STRPUT(fp, prev_lk1);
-    STRPUT(fp, prev_lk2);
+    int f;
+
+    for(f=0; f<sizeof mem; f++)
+    {
+	PUT_Byte(fp, mem[f]);
+    }
+
+    for(f=0; f<sizeof matrix; f++)
+    {
+	PUT_Byte(fp, matrix[f]);
+    }
+
+    PUT_Long(fp, waitkey);
+    PUT_Long(fp, started);
+
+    PUT_ULong(fp, RAMBOT);
+    PUT_ULong(fp, RAMTOP);
+
+    PUT_ULong(fp, prev_lk1);
+    PUT_ULong(fp, prev_lk2);
 }
 
 
 void ZX81LoadSnapshot(FILE *fp)
 {
-    STRGET(fp, mem);
-    STRGET(fp, matrix);
-    STRGET(fp, waitkey);
-    STRGET(fp, started);
-    STRGET(fp, RAMBOT);
-    STRGET(fp, RAMTOP);
-    STRGET(fp, prev_lk1);
-    STRGET(fp, prev_lk2);
+    int f;
+
+    for(f=0; f<sizeof mem; f++)
+    {
+	mem[f] = GET_Byte(fp);
+    }
+
+    for(f=0; f<sizeof matrix; f++)
+    {
+	matrix[f] = GET_Byte(fp);
+    }
+
+    waitkey = GET_Long(fp);
+    started = GET_Long(fp);
+
+    RAMBOT = GET_ULong(fp);
+    RAMTOP = GET_ULong(fp);
+
+    prev_lk1 = GET_ULong(fp);
+    prev_lk2 = GET_ULong(fp);
 
     /* Reset last_I to force hi/lo res detection
     */
-- 
cgit v1.2.3