diff options
| author | Ian C <ianc@noddybox.co.uk> | 2008-12-05 00:37:26 +0000 | 
|---|---|---|
| committer | Ian C <ianc@noddybox.co.uk> | 2008-12-05 00:37:26 +0000 | 
| commit | 9ebec735c488e2f7ac29933fb51b4e6e65c7b93f (patch) | |
| tree | c19015d71edcdf6dfba13d10115ebaa17a7c7fe7 | |
| parent | f6a25a43ff98942dc051cfed6b28eefffeb8e40e (diff) | |
Initial working version of memory snapshots
| -rw-r--r-- | CHANGES | 2 | ||||
| -rw-r--r-- | include/gui.h | 3 | ||||
| -rw-r--r-- | include/stream.h | 14 | ||||
| -rw-r--r-- | source/gui.c | 14 | ||||
| -rw-r--r-- | source/keyboard.c | 87 | ||||
| -rw-r--r-- | source/main.c | 5 | ||||
| -rw-r--r-- | source/snapshot.c | 10 | ||||
| -rw-r--r-- | source/stream.c | 86 | ||||
| -rw-r--r-- | source/z80.c | 106 | ||||
| -rw-r--r-- | source/zx81.c | 106 | 
10 files changed, 285 insertions, 148 deletions
| @@ -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      */ | 
