From 3cf17ecef2ac48e92910ac971fec9ea5b3eeb1d3 Mon Sep 17 00:00:00 2001 From: Ian C Date: Fri, 12 Dec 2008 00:19:08 +0000 Subject: Implemented snapshots and SAVE. --- include/config.h | 1 + include/snapshot.h | 10 ++++++++-- instructions.txt | 26 ++++++++++++++++++++++---- source/config.c | 5 +++++ source/main.c | 20 ++++++++++---------- source/snapshot.c | 51 +++++++++++++++++++++++++++++++++++---------------- source/zx81.c | 46 ++++++++++++++++++++++++++++++++++++++-------- 7 files changed, 119 insertions(+), 40 deletions(-) diff --git a/include/config.h b/include/config.h index 9946356..8dc05e8 100644 --- a/include/config.h +++ b/include/config.h @@ -31,6 +31,7 @@ typedef enum DS81_STICKY_SHIFT, DS81_AVERAGE_TOUCHSCREEN, DS81_STATIC_RAM_AT_0x2000, + DS81_ALLOW_TAPE_SAVE, DS81_LOAD_DEFAULT_SNAPSHOT, DS81_NUM_CONFIG_ITEMS } DS81_ConfigItem; diff --git a/include/snapshot.h b/include/snapshot.h index 0afd20b..5b0f536 100644 --- a/include/snapshot.h +++ b/include/snapshot.h @@ -24,8 +24,14 @@ #include "z80.h" +typedef enum +{ + SNAP_TYPE_FULL, + SNAP_TYPE_KEYBOARD +} SnapshotType; + void SNAP_Enable(int enable); -void SNAP_Save(Z80 *cpu); -void SNAP_Load(Z80 *cpu, const char *optional_name); +void SNAP_Save(Z80 *cpu, SnapshotType type); +void SNAP_Load(Z80 *cpu, const char *optional_name, SnapshotType type); #endif /* DS81_SNAPSHOT_H */ diff --git a/instructions.txt b/instructions.txt index 3b78efa..2e43577 100644 --- a/instructions.txt +++ b/instructions.txt @@ -123,16 +123,25 @@ See the second to last section for more details. - LOAD MEMORY SNAPSHOT - Loads a memory snapshot. This option only works if a FAT-enabled + SAVE MEMORY SNAPSHOT + Saves a memory snapshot. This option only works if a FAT-enabled version of DS81 is being used. See the "Memory Snapshot" section for more details. - SAVE MEMORY SNAPSHOT - Saves a memory snapshot. This option only works if a FAT-enabled + LOAD MEMORY SNAPSHOT + Loads a memory snapshot. This option only works if a FAT-enabled version of DS81 is being used. See the "Memory Snapshot" section for more details. + SAVE JOYPAD/KEY STATE + Saves a snapshot that just contains the current state of the + keyboard and the joypad mappings. This just allows you to save + a complex controller mapping to share between different games. + + LOAD JOYPAD/KEY STATE + This loads the state of the keyboard and the joypad mappings + from a selected file. + CANCEL Cancels the menu. @@ -273,6 +282,15 @@ Not that I've found any that work yet :-) + ALLOW TAPE SAVE + + If enabled this means that files saved with the SAVE command will + try and create a .P file in the ZX81SNAP directory, or the root + directory. You can SAVE "*" to bring up the file selector. + + If not enabled attempts to SAVE files from BASIC will be silently + ignored. + LOAD DEFAULT MEMORY SNAP If enabled DS81 will look for a memory snapshot called AUTO.D81 in diff --git a/source/config.c b/source/config.c index 55141ba..9d02417 100644 --- a/source/config.c +++ b/source/config.c @@ -35,6 +35,7 @@ const char *conf_entry[DS81_NUM_CONFIG_ITEMS]= "sticky_shift", "average_touchscreen", "static_ram_at_0x2000", + "allow_tape_save", "load_default_snapshot" }; @@ -46,6 +47,7 @@ int DS81_Config[DS81_NUM_CONFIG_ITEMS]= TRUE, FALSE, FALSE, + FALSE, FALSE }; @@ -133,6 +135,9 @@ const char *ConfigDesc(DS81_ConfigItem item) case DS81_LOAD_DEFAULT_SNAPSHOT: return "LOAD DEFAULT SNAPSHOT"; + case DS81_ALLOW_TAPE_SAVE: + return "ALLOW TAPE SAVING"; + default: return "UNKNOWN"; } diff --git a/source/main.c b/source/main.c index 674478e..218dd40 100644 --- a/source/main.c +++ b/source/main.c @@ -59,8 +59,8 @@ static const char *main_menu[]= #ifndef DS81_DISABLE_FAT "Save Memory Snapshot", "Load Memory Snapshot", - "Save Joypad Mappings", - "Load Joypad Mappings", + "Save Joypad/Key State", + "Load Joypad/Key State", #endif "Cancel", NULL @@ -98,9 +98,9 @@ static void Splash(void) " " "Welcome to DS81, a ZX81 emulator for the Ninetendo DS. " "You can safely ignore this message. I was just bored for half an " - "hour. And no retro item is complete without a side-scroller... " - "Thanks to Slay Radio, the Genki Rockets and the High Voltage SID " - "Collection for coding fuel." + "hour. And no retro game is complete without a side-scroller... " + "Thanks to Slay Radio, Ladytron, the Genki Rockets, the High " + "Voltage SID Collection and Retro Gamer for coding fuel." }; static const char *text[]= @@ -394,7 +394,7 @@ int main(int argc, char *argv[]) if (DS81_Config[DS81_LOAD_DEFAULT_SNAPSHOT]) { - SNAP_Load(z80, "AUTO"); + SNAP_Load(z80, "AUTO", SNAP_TYPE_FULL); } while(1) @@ -438,19 +438,19 @@ int main(int argc, char *argv[]) #ifndef DS81_DISABLE_FAT case MenuSaveSnapshot: - SNAP_Save(z80); + SNAP_Save(z80, SNAP_TYPE_FULL); break; case MenuLoadSnapshot: - SNAP_Load(z80, NULL); + SNAP_Load(z80, NULL, SNAP_TYPE_FULL); break; case MenuSaveMappings: - // TODO + SNAP_Save(z80, SNAP_TYPE_KEYBOARD); break; case MenuLoadMappings: - // TODO + SNAP_Load(z80, NULL, SNAP_TYPE_KEYBOARD); break; #endif } diff --git a/source/snapshot.c b/source/snapshot.c index 14f0e30..1d5aa37 100644 --- a/source/snapshot.c +++ b/source/snapshot.c @@ -28,6 +28,7 @@ #include #include +#include "snapshot.h" #include "zx81.h" #include "gui.h" @@ -47,12 +48,13 @@ /* ---------------------------------------- STATICS */ static int enabled; -static const char *magic = "V00_DS81"; +static const char *magic = "V01_DS81"; +static const char *extension[2] = {".D81", ".K81"}; /* ---------------------------------------- PRIVATE FUNCTIONS */ -static void WriteMagic(FILE *fp) +static void WriteMagic(FILE *fp, SnapshotType t) { const char *p = magic; @@ -60,9 +62,11 @@ static void WriteMagic(FILE *fp) { fputc(*p++, fp); } + + fputc(t, fp); } -static int CheckMagic(FILE *fp) +static int CheckMagic(FILE *fp, SnapshotType t) { const char *p = magic; @@ -74,7 +78,7 @@ static int CheckMagic(FILE *fp) } } - return TRUE; + return (fgetc(fp) == t); } @@ -85,7 +89,7 @@ void SNAP_Enable(int enable) enabled = enable; } -void SNAP_Save(Z80 *cpu) +void SNAP_Save(Z80 *cpu, SnapshotType type) { char base[FILENAME_MAX] = ""; char file[FILENAME_MAX]; @@ -96,12 +100,13 @@ void SNAP_Save(Z80 *cpu) return; } - if(!GUI_InputName("enter snapshot filename", ".d81", base, 8) || !base[0]) + if(!GUI_InputName("enter snapshot filename", + extension[type], base, 8) || !base[0]) { return; } - strcat(base, ".D81"); + strcat(base, extension[type]); strcpy(file, DEFAULT_SNAPDIR); strcat(file, base); @@ -115,10 +120,16 @@ void SNAP_Save(Z80 *cpu) if (fp) { - WriteMagic(fp); + WriteMagic(fp, type); + SK_SaveSnapshot(fp); - Z80SaveSnapshot(cpu, fp); - ZX81SaveSnapshot(fp); + + if (type == SNAP_TYPE_FULL) + { + Z80SaveSnapshot(cpu, fp); + ZX81SaveSnapshot(fp); + } + fclose(fp); } else @@ -127,7 +138,7 @@ void SNAP_Save(Z80 *cpu) } } -void SNAP_Load(Z80 *cpu, const char *optional_name) +void SNAP_Load(Z80 *cpu, const char *optional_name, SnapshotType type) { static char last_dir[FILENAME_MAX] = "/"; char file[FILENAME_MAX]; @@ -142,17 +153,21 @@ void SNAP_Load(Z80 *cpu, const char *optional_name) { strcpy(file, DEFAULT_SNAPDIR); strcat(file, optional_name); + strcat(file, extension[type]); fp = fopen(file, "rb"); if (!fp) { - fp = fopen(optional_name, "rb"); + strcpy(file, optional_name); + strcat(file, extension[type]); + + fp = fopen(file, "rb"); } } else { - if (GUI_FileSelect(last_dir, file, ".D81")) + if (GUI_FileSelect(last_dir, file, extension[type])) { fp = fopen(file, "rb"); } @@ -160,15 +175,19 @@ void SNAP_Load(Z80 *cpu, const char *optional_name) if (fp) { - if (!CheckMagic(fp)) + if (!CheckMagic(fp, type)) { GUI_Alert(FALSE, "Not a valid snapshot"); } else { SK_LoadSnapshot(fp); - Z80LoadSnapshot(cpu, fp); - ZX81LoadSnapshot(fp); + + if (type == SNAP_TYPE_FULL) + { + Z80LoadSnapshot(cpu, fp); + ZX81LoadSnapshot(fp); + } } fclose(fp); diff --git a/source/zx81.c b/source/zx81.c index 00d6015..b8143cd 100644 --- a/source/zx81.c +++ b/source/zx81.c @@ -62,6 +62,7 @@ #define SLOW_TSTATES 16000 #define FAST_TSTATES 64000 +#define E_LINE 16404 #define LASTK1 16421 #define LASTK2 16422 #define MARGIN 16424 @@ -103,6 +104,7 @@ static Z80Word RAMTOP=0; /* Tape */ static int enable_filesystem; +static int allow_save; static const Z80Byte *tape_image; static int tape_len; @@ -254,12 +256,13 @@ static Z80Byte FromASCII(char c) /* Open a tape file the passed address */ -static FILE *OpenTapeFile(Z80Word addr, int *cancelled) +static FILE *OpenTapeFile(Z80Word addr, int *cancelled, const char *mode) { static const char zx_chars[] = "\"#$:?()><=+-*/;,." "0123456789" "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; FILE *fp; + char full_fn[FILENAME_MAX] = DEFAULT_SNAPDIR; char fn[FILENAME_MAX]; int f; int done; @@ -291,7 +294,7 @@ static FILE *OpenTapeFile(Z80Word addr, int *cancelled) { if (GUI_FileSelect(last_dir,fn,".P")) { - fp = fopen(fn,"rb"); + fp = fopen(fn, mode); } else { @@ -306,12 +309,11 @@ static FILE *OpenTapeFile(Z80Word addr, int *cancelled) fn[f++] = 'P'; fn[f] = 0; - if (!(fp = fopen(fn,"rb"))) - { - char full_fn[FILENAME_MAX] = DEFAULT_SNAPDIR; + strcat(full_fn,fn); - strcat(full_fn,fn); - fp = fopen(full_fn,"rb"); + if (!(fp = fopen(full_fn, mode))) + { + fp = fopen(fn, mode); } } @@ -339,6 +341,21 @@ static void LoadExternalTape(FILE *tape, Z80 *z80) } +static void SaveExternalTape(FILE *tape, Z80 *z80) +{ + int f; + int end; + + f = 0x4009; + end = WORD(E_LINE); + + while(f <= end) + { + fputc(mem[f++], tape); + } +} + + static void ClearBitmap(void) { uint16 *s; @@ -744,6 +761,17 @@ static int EDCallback(Z80 *z80, Z80Val data) switch((Z80Byte)data) { case ED_SAVE: + if (allow_save && z80->DE.w<0x8000) + { + FILE *fp; + int cancel; + + if ((fp=OpenTapeFile(z80->HL.w, &cancel, "wb"))) + { + SaveExternalTape(fp,z80); + fclose(fp); + } + } break; case ED_LOAD: @@ -757,7 +785,7 @@ static int EDCallback(Z80 *z80, Z80Val data) FILE *fp; int cancel; - if ((fp=OpenTapeFile(z80->DE.w,&cancel))) + if ((fp=OpenTapeFile(z80->DE.w, &cancel, "rb"))) { LoadExternalTape(fp,z80); fclose(fp); @@ -1068,6 +1096,8 @@ void ZX81Reconfigure(void) RAMBOT = 0x4000; memcpy(mem+ROMLEN,mem,ROMLEN); } + + allow_save = enable_filesystem && DS81_Config[DS81_ALLOW_TAPE_SAVE]; } -- cgit v1.2.3