summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan C <ianc@noddybox.co.uk>2008-12-05 00:37:26 +0000
committerIan C <ianc@noddybox.co.uk>2008-12-05 00:37:26 +0000
commit9ebec735c488e2f7ac29933fb51b4e6e65c7b93f (patch)
treec19015d71edcdf6dfba13d10115ebaa17a7c7fe7
parentf6a25a43ff98942dc051cfed6b28eefffeb8e40e (diff)
Initial working version of memory snapshots
-rw-r--r--CHANGES2
-rw-r--r--include/gui.h3
-rw-r--r--include/stream.h14
-rw-r--r--source/gui.c14
-rw-r--r--source/keyboard.c87
-rw-r--r--source/main.c5
-rw-r--r--source/snapshot.c10
-rw-r--r--source/stream.c86
-rw-r--r--source/z80.c106
-rw-r--r--source/zx81.c106
10 files changed, 285 insertions, 148 deletions
diff --git a/CHANGES b/CHANGES
index 8bbd5fc..332c149 100644
--- a/CHANGES
+++ b/CHANGES
@@ -46,7 +46,7 @@ Changes from V1.2 to V1.2a
Changes from V1.2a to V1.3
- * Added memory snapshots.
+ + Added memory snapshots.
* Added auto-load of named snapshot.
* Added auto initial pop-up of snapshot selection.
* Added save/load of keyboard mappings.
diff --git a/include/gui.h b/include/gui.h
index 30989e6..ea89932 100644
--- a/include/gui.h
+++ b/include/gui.h
@@ -26,6 +26,7 @@ int GUI_Menu(const char *opts[]);
void GUI_Alert(int fatal, const char *text);
void GUI_Config(void);
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);
#endif /* DS81_GUI_H */
diff --git a/include/stream.h b/include/stream.h
index f701d8b..1049706 100644
--- a/include/stream.h
+++ b/include/stream.h
@@ -22,10 +22,14 @@
#ifndef DS81_STREAM_H
#define DS81_STREAM_H
-/* Macros to aid in streaming. Should be safe as there is no intention at all
- about these snapshots being cross platform.
-*/
-#define STRPUT(fp, a) fwrite(&(a), sizeof(a), 1, fp)
-#define STRGET(fp, a) fread(&(a), sizeof(a), 1, fp)
+#include <stdio.h>
+
+void PUT_Byte(FILE *fp, unsigned char c);
+void PUT_Long(FILE *fp, long l);
+void PUT_ULong(FILE *fp, unsigned long l);
+
+unsigned char GET_Byte(FILE *fp);
+long GET_Long(FILE *fp);
+unsigned long GET_ULong(FILE *fp);
#endif /* DS81_STREAM_H */
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
*/