From 8f4656b7920d37b3f1df5944dfe9307264a52f0b Mon Sep 17 00:00:00 2001 From: Ian C Date: Sat, 13 Jun 2026 17:19:51 +0100 Subject: Reorganised tape files a bit and select one if none selected when patch is hit --- src/Makefile | 2 + src/main.c | 49 +++--------------- src/spec.c | 69 +++++++------------------- src/spec.h | 11 ---- src/tape.c | 160 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/tape.h | 78 +++++++++++++++++++++++++++++ src/util.c | 10 ++++ src/util.h | 7 +++ 8 files changed, 284 insertions(+), 102 deletions(-) create mode 100644 src/tape.c create mode 100644 src/tape.h diff --git a/src/Makefile b/src/Makefile index f8a0a14..96193fe 100644 --- a/src/Makefile +++ b/src/Makefile @@ -40,6 +40,7 @@ SOURCE = main.c \ util.c \ kbbmp.c \ exit.c \ + tape.c \ expr.c \ z80.c \ z80_decode.c \ @@ -55,6 +56,7 @@ OBJECTS = main.o \ util.o \ kbbmp.o \ exit.o \ + tape.o \ expr.o \ z80.o \ z80_decode.o \ diff --git a/src/main.c b/src/main.c index a657edb..7e2844e 100644 --- a/src/main.c +++ b/src/main.c @@ -35,6 +35,7 @@ #include "config.h" #include "kbbmp.h" #include "exit.h" +#include "tape.h" #include "util.h" @@ -69,8 +70,6 @@ static void Usage(void) */ int main(int argc, char *argv[]) { - char tape_in[FILENAME_MAX]=""; - char tape_out[FILENAME_MAX]=""; Z80 *z80; SDL_Event *e; int quit; @@ -99,9 +98,6 @@ int main(int argc, char *argv[]) /* Parse switches */ inital_menu=FALSE; - tape_in[0]=0; - tape_out[0]=0; - f=1; while(fkey.state==SDL_PRESSED) - GUIMessage(eMessageBox, - "Mounted Tape Files", - "In: %-20.20s\nOut: %-20.20s", - tape_in[0] ? Basename(tape_in):"None", - tape_out[0] ? Basename(tape_out):"None"); + TAPEDisplayInfo(); break; case SDLK_F8: if (e->key.state==SDL_PRESSED) { - if (GUIFileSelect("TAPE TO LOAD",TRUE, - tape_in[0] ? - Dirname(tape_in) : - SConfig(CONF_TAPEDIR), - tape_in)) - { - SPECMount(SPEC_TAPE_IN,tape_in); - } + TAPESelectInput(); } break; case SDLK_F9: if (e->key.state==SDL_PRESSED) { - if (GUIFileSelect("TAPE TO SAVE",FALSE, - tape_out[0] ? - Dirname(tape_out) : - SConfig(CONF_TAPEDIR), - tape_out)) - { - SPECMount(SPEC_TAPE_OUT,tape_out); - } + TAPESelectOutput(); } break; case SDLK_F10: if (e->key.state==SDL_PRESSED) { - SPECUnmount(SPEC_TAPE_IN); - SPECUnmount(SPEC_TAPE_OUT); + TAPEUnmount(TAP_IN); + TAPEUnmount(TAP_OUT); } break; diff --git a/src/spec.c b/src/spec.c index 7066292..3a872dd 100644 --- a/src/spec.c +++ b/src/spec.c @@ -32,6 +32,7 @@ #include "gui.h" #include "config.h" #include "exit.h" +#include "tape.h" #include "util.h" #ifndef TRUE @@ -52,8 +53,8 @@ static const int ROMLEN=0x4000; static const int ROM_SAVE=0x4c6; static const int ROM_LOAD=0x562; -static FILE *tape_in; -static FILE *tape_out; +static int selected_in_tape = FALSE; +static int selected_out_tape = FALSE; #define LOAD_PATCH 0xf0 #define SAVE_PATCH 0xf1 @@ -350,13 +351,19 @@ static int EDCallback(Z80 *z80, Z80Val data) case SAVE_PATCH: Z80GetState(z80,&state); - if (!tape_out) + if (!TAPEFile(TAP_OUT) && !selected_out_tape) + { + TAPESelectOutput(); + selected_out_tape = TRUE; + } + + if (!TAPEFile(TAP_OUT)) { state.AF|=eZ80_Carry; } else { - if (TAPSave(tape_out, + if (TAPSave(TAPEFile(TAP_OUT), HIBYTE(state.AF), &state.IX, &state.DE, @@ -377,13 +384,19 @@ static int EDCallback(Z80 *z80, Z80Val data) case LOAD_PATCH: Z80GetState(z80,&state); - if (!tape_in) + if (!TAPEFile(TAP_IN) && !selected_in_tape) + { + TAPESelectInput(); + selected_in_tape = TRUE; + } + + if (!TAPEFile(TAP_IN)) { state.AF|=eZ80_Carry; } else { - if (TAPLoad(tape_in, + if (TAPLoad(TAPEFile(TAP_IN), HIBYTE(state.AF), &state.IX, &state.DE, @@ -858,48 +871,4 @@ void SPECReset(Z80 *z80) } -void SPECMount(SPECMountType type, const char *path) -{ - switch(type) - { - case SPEC_TAPE_IN: - if (tape_in) - fclose(tape_in); - - tape_in=fopen(path,"rb"); - break; - - case SPEC_TAPE_OUT: - if (tape_out) - fclose(tape_out); - - tape_out=fopen(path,"wb"); - break; - } -} - - -void SPECUnmount(SPECMountType type) -{ - switch(type) - { - case SPEC_TAPE_IN: - if (tape_in) - { - fclose(tape_in); - tape_in=NULL; - } - break; - - case SPEC_TAPE_OUT: - if (tape_out) - { - fclose(tape_out); - tape_out=NULL; - } - break; - } -} - - /* END OF FILE */ diff --git a/src/spec.h b/src/spec.h index d5429cd..261429c 100644 --- a/src/spec.h +++ b/src/spec.h @@ -29,11 +29,6 @@ #include "z80.h" #include "SDL.h" -/* Types for Mount and Unmount -*/ -typedef enum {SPEC_TAPE_IN,SPEC_TAPE_OUT} SPECMountType; - - /* Initialise the SPEC */ void SPECInit(Z80 *z80); @@ -64,12 +59,6 @@ void SPECShowScreen(void); */ void SPECReset(Z80 *z80); - -/* Interfaces for snapshot and device control -*/ -void SPECMount(SPECMountType type, const char *path); -void SPECUnmount(SPECMountType type); - #endif diff --git a/src/tape.c b/src/tape.c new file mode 100644 index 0000000..157d644 --- /dev/null +++ b/src/tape.c @@ -0,0 +1,160 @@ +/* + + espec - Sinclair Spectrum emulator + + Copyright (C) 2026 Ian Cowburn (ianc@noddybox.demon.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 + + ------------------------------------------------------------------------- + + Selected tape files + +*/ +#include +#include +#include +#include + +#include "tape.h" +#include "util.h" +#include "gui.h" +#include "config.h" + + +/* ---------------------------------------- MACROS +*/ +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + + +/* ---------------------------------------- GLOBALS +*/ +static char tape_in[FILENAME_MAX]=""; +static char tape_out[FILENAME_MAX]=""; +static FILE *in; +static FILE *out; + +/* ---------------------------------------- INTERFACES +*/ + +int TAPESelectInput(void) +{ + char path[FILENAME_MAX]; + + if (GUIFileSelect("TAPE TO LOAD",TRUE, + tape_in[0] ? Dirname(tape_in) : SConfig(CONF_TAPEDIR), + path)) + { + TAPEMount(TAP_IN, path); + return TRUE; + } + + return FALSE; +} + + +int TAPESelectOutput(void) +{ + char path[FILENAME_MAX]; + + if (GUIFileSelect("TAPE TO SAVE",FALSE, + tape_out[0] ? Dirname(tape_out) : SConfig(CONF_TAPEDIR), + path)) + { + TAPEMount(TAP_OUT, path); + return TRUE; + } + + return FALSE; +} + + +void TAPEMount(TAPEMountType type, const char *path) +{ + TAPEUnmount(type); + + switch(type) + { + case TAP_IN: + strncpy(tape_in, path, FILENAME_MAX); + in = fopen(tape_in, "rb"); + break; + + case TAP_OUT: + strncpy(tape_out, path, FILENAME_MAX); + out = fopen(tape_out, "wb"); + break; + } +} + + +void TAPEUnmount(TAPEMountType type) +{ + switch(type) + { + case TAP_IN: + if (in) + { + fclose(in); + in = NULL; + } + tape_in[0] = 0; + break; + + case TAP_OUT: + if (out) + { + fclose(out); + out = NULL; + } + tape_out[0] = 0; + break; + } +} + + +FILE *TAPEFile(TAPEMountType type) +{ + switch(type) + { + case TAP_IN: + return in; + + case TAP_OUT: + return out; + + default: + return NULL; + } +} + + +void TAPEDisplayInfo(void) +{ + GUIMessage(eMessageBox, + "Mounted Tape Files", + "In: %-20.20s\nOut: %-20.20s", + tape_in[0] ? Basename(tape_in):"None", + tape_out[0] ? Basename(tape_out):"None"); +} + + +/* END OF FILE */ diff --git a/src/tape.h b/src/tape.h new file mode 100644 index 0000000..05e09e9 --- /dev/null +++ b/src/tape.h @@ -0,0 +1,78 @@ +/* + + espec - Sinclair Spectrum emulator + + Copyright (C) 2026 Ian Cowburn (ianc@noddybox.demon.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 + + ------------------------------------------------------------------------- + + Seleted tape files + +*/ + +#ifndef ESPEC_TAPE_H +#define ESPEC_TAPE_H "$Id$" + +#include + +/* ---------------------------------------- TYPES +*/ + +/* Types for Mount and Unmount +*/ +typedef enum {TAP_IN, TAP_OUT} TAPEMountType; + + +/* ---------------------------------------- INTERFACES +*/ + +/* Select the tape file to use for input. Returns TRUE if a tape was + selected. +*/ +int TAPESelectInput(void); + + +/* Select the tape file to use for output. Returns TRUE if a tape was + selected. +*/ +int TAPESelectOutput(void); + + +/* Mount a file without using the selector +*/ +void TAPEMount(TAPEMountType type, const char *path); + + +/* Unmount a file without using the selector +*/ +void TAPEUnmount(TAPEMountType type); + + +/* Get the current tape +*/ +FILE *TAPEFile(TAPEMountType type); + + +/* Display tape info in a message box +*/ +void TAPEDisplayInfo(void); + + +#endif + + +/* END OF FILE */ diff --git a/src/util.c b/src/util.c index ee43a3c..c16584c 100644 --- a/src/util.c +++ b/src/util.c @@ -66,6 +66,16 @@ char *StrCopy(const char *source) } +char *SafeStrCopy(char *destination, + const char *source, + size_t destination_size) +{ + strncpy(destination, source, destination_size); + destination[destination_size - 1] = 0; + return destination; +} + + const char *Basename(const char *path) { const char *p=path+strlen(path); diff --git a/src/util.h b/src/util.h index 922f641..c82169e 100644 --- a/src/util.h +++ b/src/util.h @@ -47,6 +47,13 @@ void *Realloc(void *p, size_t size); char *StrCopy(const char *source); +/* Safely copies a string. The destination is returned. +*/ +char *SafeStrCopy(char *destination, + const char *source, + size_t destination_size); + + /* Returns the filename portion of path. Note returned pointer is pointing inside of path. */ -- cgit v1.3