From 9ebec735c488e2f7ac29933fb51b4e6e65c7b93f Mon Sep 17 00:00:00 2001 From: Ian C Date: Fri, 5 Dec 2008 00:37:26 +0000 Subject: Initial working version of memory snapshots --- CHANGES | 2 +- include/gui.h | 3 +- include/stream.h | 14 +++++--- 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 +++++++++++++++++++++++++++++++----------------------- 10 files changed, 285 insertions(+), 148 deletions(-) create mode 100644 source/stream.c 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 + +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; fPC, 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 + + 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