diff options
author | Ian C <ianc@noddybox.co.uk> | 2004-01-06 02:06:37 +0000 |
---|---|---|
committer | Ian C <ianc@noddybox.co.uk> | 2004-01-06 02:06:37 +0000 |
commit | 25bc35fbadebbf28eed3c89978e435d2df557b42 (patch) | |
tree | 74619afa6e82dd4818dd210c20396946a7c1722e /src | |
parent | 63c0f2a2f2819940efde5ff52ab13109809405f9 (diff) |
Devel checkin - added util and snap objects and non-working TAP support
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 30 | ||||
-rw-r--r-- | src/gui.c | 14 | ||||
-rw-r--r-- | src/gui.h | 27 | ||||
-rw-r--r-- | src/main.c | 54 | ||||
-rw-r--r-- | src/memmenu.c | 40 | ||||
-rw-r--r-- | src/snap.c | 200 | ||||
-rw-r--r-- | src/snap.h | 73 | ||||
-rw-r--r-- | src/spec.c | 100 | ||||
-rw-r--r-- | src/spec.h | 9 | ||||
-rw-r--r-- | src/util.c | 100 | ||||
-rw-r--r-- | src/util.h | 61 |
11 files changed, 661 insertions, 47 deletions
diff --git a/src/Makefile b/src/Makefile index 79b1d6a..68ecd6d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -18,7 +18,7 @@ # # ------------------------------------------------------------------------- # -# $Id: Makefile,v 1.4 2004-01-05 01:07:07 ianc Exp $ +# $Id: Makefile,v 1.5 2004-01-06 02:06:36 ianc Exp $ # @@ -34,18 +34,22 @@ Z80LIB = z80/z80.a SOURCE = main.c \ spec.c \ + snap.c \ config.c \ gfx.c \ gui.c \ memmenu.c \ + util.c \ exit.c OBJECTS = main.o \ spec.o \ + snap.o \ config.o \ gfx.o \ gui.o \ memmenu.o \ + util.o \ exit.o CFLAGS += -Iz80 `sdl-config --cflags` @@ -72,8 +76,9 @@ depend: main.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h main.o: /usr/include/sys/_types.h /usr/include/machine/_types.h -main.o: /usr/include/stdio.h /usr/local/include/SDL/SDL.h -main.o: /usr/local/include/SDL/SDL_main.h /usr/local/include/SDL/SDL_types.h +main.o: /usr/include/stdio.h /usr/include/string.h /usr/include/strings.h +main.o: /usr/local/include/SDL/SDL.h /usr/local/include/SDL/SDL_main.h +main.o: /usr/local/include/SDL/SDL_types.h main.o: /usr/local/include/SDL/SDL_getenv.h main.o: /usr/local/include/SDL/SDL_error.h main.o: /usr/local/include/SDL/begin_code.h @@ -111,7 +116,11 @@ spec.o: /usr/local/include/SDL/SDL_keyboard.h spec.o: /usr/local/include/SDL/SDL_keysym.h spec.o: /usr/local/include/SDL/SDL_mouse.h /usr/local/include/SDL/SDL_video.h spec.o: /usr/local/include/SDL/SDL_mutex.h /usr/local/include/SDL/SDL_quit.h -spec.o: /usr/local/include/SDL/SDL_version.h gfx.h gui.h config.h exit.h +spec.o: /usr/local/include/SDL/SDL_version.h snap.h gfx.h gui.h config.h +spec.o: exit.h +snap.o: snap.h /usr/include/stdlib.h /usr/include/sys/cdefs.h +snap.o: /usr/include/sys/_types.h /usr/include/machine/_types.h +snap.o: /usr/include/stdio.h z80/z80.h config.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h config.o: /usr/include/sys/_types.h /usr/include/machine/_types.h config.o: /usr/include/stdio.h /usr/include/string.h /usr/include/strings.h @@ -139,9 +148,10 @@ gui.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h gui.o: /usr/include/sys/_types.h /usr/include/machine/_types.h gui.o: /usr/include/stdio.h /usr/include/string.h /usr/include/strings.h gui.o: /usr/include/stdarg.h /usr/include/ctype.h /usr/include/runetype.h -gui.o: gui.h /usr/local/include/SDL/SDL.h /usr/local/include/SDL/SDL_main.h -gui.o: /usr/local/include/SDL/SDL_types.h /usr/local/include/SDL/SDL_getenv.h -gui.o: /usr/local/include/SDL/SDL_error.h /usr/local/include/SDL/begin_code.h +gui.o: gui.h gfx.h /usr/local/include/SDL/SDL.h +gui.o: /usr/local/include/SDL/SDL_main.h /usr/local/include/SDL/SDL_types.h +gui.o: /usr/local/include/SDL/SDL_getenv.h /usr/local/include/SDL/SDL_error.h +gui.o: /usr/local/include/SDL/begin_code.h gui.o: /usr/local/include/SDL/close_code.h /usr/local/include/SDL/SDL_rwops.h gui.o: /usr/local/include/SDL/SDL_timer.h /usr/local/include/SDL/SDL_audio.h gui.o: /usr/local/include/SDL/SDL_byteorder.h @@ -153,7 +163,7 @@ gui.o: /usr/local/include/SDL/SDL_keyboard.h gui.o: /usr/local/include/SDL/SDL_keysym.h /usr/local/include/SDL/SDL_mouse.h gui.o: /usr/local/include/SDL/SDL_video.h /usr/local/include/SDL/SDL_mutex.h gui.o: /usr/local/include/SDL/SDL_quit.h /usr/local/include/SDL/SDL_version.h -gui.o: gfx.h exit.h +gui.o: exit.h memmenu.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h memmenu.o: /usr/include/sys/_types.h /usr/include/machine/_types.h memmenu.o: /usr/include/stdio.h /usr/include/string.h /usr/include/strings.h @@ -180,6 +190,10 @@ memmenu.o: /usr/local/include/SDL/SDL_video.h memmenu.o: /usr/local/include/SDL/SDL_mutex.h memmenu.o: /usr/local/include/SDL/SDL_quit.h memmenu.o: /usr/local/include/SDL/SDL_version.h gfx.h gui.h +util.o: /usr/include/stdio.h /usr/include/sys/cdefs.h +util.o: /usr/include/sys/_types.h /usr/include/machine/_types.h +util.o: /usr/include/string.h /usr/include/strings.h util.h +util.o: /usr/include/stdlib.h exit.h exit.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h exit.o: /usr/include/sys/_types.h /usr/include/machine/_types.h exit.o: /usr/include/stdarg.h exit.h /usr/local/include/SDL/SDL.h @@ -207,4 +207,18 @@ const char *GUIInputString(const char *prompt, const char *orig) } +int GUIFileSelect(const char *prompt, int load, + const char *start_dir, char path[]) +{ + /* TODO */ + if (load) + strcpy(path,"/files/emu/spectrum/thrust1.tap"); + else + strcpy(path,"/files/emu/spectrum/testespec.tap"); + + strcpy(path,"/files/emu/spectrum/testespec.tap"); + return TRUE; +} + + /* END OF FILE */ @@ -27,8 +27,6 @@ #ifndef ESPEC_GUI_H #define ESPEC_GUI_H "$Id$" -#include "SDL.h" - /* ---------------------------------------- INTERFACES */ @@ -44,6 +42,31 @@ void GUIMessage(const char *title, const char *format,...); const char *GUIInputString(const char *prompt, const char *orig); +/* Select a file from the given directory. + + If load is TRUE then a new name cannot be entered. + + Returns TRUE for selected, FALSE for cancelled. + + path holds the new file entered. Note that start_dir can be a path to a + file - if chdir(start_dir) would not work, then it is tried with the + dirname(1) of start_dir. + + Also start_dir and path can be the same pointer: + + char file[FILENAME_MAX]="/home/foobar/dir/file.tap"; + + if (GUI_Fsel("Select tape",TRUE,file,file)) + .... + + Will work fine. +*/ +int GUIFileSelect(const char *prompt, + int load, + const char *start_dir, + char path[]); + + #endif @@ -25,6 +25,7 @@ static const char id[]="$Id$"; #include <stdlib.h> #include <stdio.h> +#include <string.h> #include "SDL.h" @@ -63,6 +64,8 @@ static Uint32 grey; */ int main(int argc, char *argv[]) { + char tape_in[FILENAME_MAX]; + char tape_out[FILENAME_MAX]; Z80 *z80; SDL_Event *e; int quit; @@ -72,6 +75,9 @@ int main(int argc, char *argv[]) trace=IConfig(CONF_TRACE); + strcpy(tape_in,SConfig(CONF_TAPEDIR)); + strcpy(tape_out,SConfig(CONF_TAPEDIR)); + z80=Z80Init(SPECWriteMem, SPECReadMem, SPECWritePort, @@ -89,6 +95,12 @@ int main(int argc, char *argv[]) quit=FALSE; + /* Check for initial memory menu usage + TODO: Proper switch handling + */ + if (argc>1 && strcmp(argv[1],"-m")==0) + MemoryMenu(z80); + while(!quit) { Z80State s1,s2; @@ -118,6 +130,48 @@ int main(int argc, char *argv[]) quit=TRUE; break; + case SDLK_F1: + if (e->key.state==SDL_PRESSED) + GUIMessage("HELP", + "ESC - Quit \n" + "F1 - Help \n" + "F8 - Select tape file for loading\n" + "F9 - Select tape file for saving \n" + "F10 - Close all open tape files \n" + "F11 - Memory Menu \n" + "F12 - Toggle onscreen trace "); + break; + + case SDLK_F8: + if (e->key.state==SDL_PRESSED) + { + if (GUIFileSelect("TAPE TO LOAD",TRUE, + tape_in,tape_in)) + { + SPECMount(SPEC_TAPE_IN,tape_in); + } + } + break; + + case SDLK_F9: + if (e->key.state==SDL_PRESSED) + { + if (GUIFileSelect("TAPE TO SAVE",FALSE, + tape_out,tape_out)) + { + SPECMount(SPEC_TAPE_OUT,tape_out); + } + } + break; + + case SDLK_F10: + if (e->key.state==SDL_PRESSED) + { + SPECUnmount(SPEC_TAPE_IN); + SPECUnmount(SPEC_TAPE_OUT); + } + break; + case SDLK_F11: if (e->key.state==SDL_PRESSED) MemoryMenu(z80); diff --git a/src/memmenu.c b/src/memmenu.c index 807e49f..50b9acb 100644 --- a/src/memmenu.c +++ b/src/memmenu.c @@ -280,15 +280,15 @@ static void DoDisassem(Z80 *z80, const Z80State *s) case SDLK_F1: GUIMessage ("DISASSEMBLY HELP","%s", - "ESC - Exit\n" - "H - Switch between disassembly/hex\n" - "Enter - Enter address to display\n" - "Cursor Up - Prev op\n" - "Cursor Down - Next op\n" - "Page Up - Move back a page\n" - "Page Down - Move forward a page\n" - "Cursor Left - Move PC by -1024\n" - "Cursor Right - Move PC by 1024"); + "ESC - Exit \n" + "H - Disassembly/hex \n" + "Enter - Enter address \n" + "Up - Prev byte \n" + "Down - Next op \n" + "Page Up - Back 1 page \n" + "Page Down - Forward 1 page \n" + "Left - Forward 1024 bytes\n" + "Right - Back 1024 bytes "); break; case SDLK_ESCAPE: @@ -437,7 +437,7 @@ static void PlaybackTrace(Z80 *z80) if (!fp) { - GUIMessage("ERROR","Couldn't open tracefile: " TRACE); + GUIMessage("ERROR","Couldn't open trace file"); return; } @@ -447,7 +447,7 @@ static void PlaybackTrace(Z80 *z80) if (max_pos==0) { - GUIMessage("ERROR","Empty tracefile: " TRACE); + GUIMessage("ERROR","Empty trace file"); fclose(fp); return; } @@ -508,15 +508,15 @@ static void PlaybackTrace(Z80 *z80) case SDLK_F1: GUIMessage ("PLAYBACK HELP","%s", - "ESC - Exit\n" - "Enter - Step number to display\n" - "P - Search for PC\n" - "Cursor Up - Prev step\n" - "Cursor Down - Next step\n" - "Page Up - Back 50 steps\n" - "Page Down - Forward 50 steps\n" - "Cursor Left - Back 1000 steps\n" - "Cursor Right - Forward 1000 steps\n \n" + "ESC - Exit \n" + "Enter - Step number \n" + "P - Search for PC \n" + "Up - Prev step \n" + "Down - Next step \n" + "Page Up - Back 50 steps \n" + "Page Down - Forward 50 steps \n" + "Left - Back 1000 steps \n" + "Right - Forward 1000 steps \n \n" "NOTE: Disassembly is as memory is NOW"); break; diff --git a/src/snap.c b/src/snap.c new file mode 100644 index 0000000..c67c0bf --- /dev/null +++ b/src/snap.c @@ -0,0 +1,200 @@ +/* + + espec - Sinclair Spectrum emulator + + Copyright (C) 2003 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 + + ------------------------------------------------------------------------- + + Utilities for handling snapshots + +*/ +static const char ident[]="$Id$"; + +#include "snap.h" + +static const char ident_h[]=ESPEC_SNAP_H; + + +/* ---------------------------------------- MACROS +*/ +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#define ROMLEN 0x4000 + + +/* ---------------------------------------- PRIVATE FUNCTIONS +*/ +static Z80Word GetLSBWord(FILE *fp) +{ + if (fp) + { + int c1,c2; + + c1=getc(fp); + c2=getc(fp); + + if (c1==EOF || c2==EOF) + return 0; + + return c1+(c2<<8); + } + else + return 0; +} + + +static void PutLSBWord(FILE *fp, Z80Word w) +{ + if (fp) + { + putc(w&0xff,fp); + putc(w>>8,fp); + } +} + + +static Z80Byte GetByte(FILE *fp) +{ + int c; + + if (!fp || (c=getc(fp))==EOF) + return 0; + + return c; +} + + +static void PutByte(FILE *fp, Z80Byte b) +{ + putc(b,fp); +} + + + +/* ---------------------------------------- INTERFACES +*/ +int TAPLoad(FILE *fp, Z80Byte id, Z80Word *addr, Z80Word *len, Z80Byte *mem) +{ + Z80Word blen; + Z80Byte type,b,csum,tape_csum; + + if (!fp) + return FALSE; + + /* Get length (wrapping file if at eof) + */ + blen=GetLSBWord(fp); + + if (feof(fp)) + { + rewind(fp); + blen=GetLSBWord(fp); + } + + type=GetByte(fp); + csum=id; + + /* Have we found the requested block? + */ + if (id==type) + { + /* Knock of block type + */ + blen--; + + while(blen && *len) + { + b=GetByte(fp); + csum^=b; + + if (*addr>=ROMLEN) + mem[*addr]=b; + + (*addr)++; + (*len)--; + blen--; + } + + /* Get the checksum + */ + if (blen) + { + tape_csum=GetByte(fp); + blen--; + } + else + tape_csum=b; + + /* In case we've been request less bytes than the block size + */ + while(blen--) + fgetc(fp); + + /* Check the checksum + */ + return csum==tape_csum; + } + else + { + /* If it's the wrong type, skip it + */ + while(blen--) + fgetc(fp); + + return FALSE; + } +} + + +int TAPSave(FILE *fp, Z80Byte id, Z80Word *addr, Z80Word *len, Z80Byte *mem) +{ + Z80Byte csum; + + if (!fp) + return FALSE; + + /* Write out the length and ID byte + */ + PutLSBWord(fp,(*len)+2); + PutByte(fp,id); + + /* Write out data and calc checksum + */ + csum=id; + + while(*len) + { + PutByte(fp,mem[*addr]); + csum^=mem[*addr]; + (*addr)++; + (*len)--; + } + + PutByte(fp,csum); + + return TRUE; +} + + +/* END OF FILE */ diff --git a/src/snap.h b/src/snap.h new file mode 100644 index 0000000..04d771a --- /dev/null +++ b/src/snap.h @@ -0,0 +1,73 @@ +/* + + espec - Sinclair Spectrum emulator + + Copyright (C) 2003 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 + + ------------------------------------------------------------------------- + + Utilities for handling snapshots + +*/ + +#ifndef ESPEC_SNAP_H +#define ESPEC_SNAP_H "$Id$" + +#include <stdlib.h> +#include <stdio.h> + +#include "z80.h" + +/* ---------------------------------------- INTERFACES +*/ + +/* Loads a block from a TAP file. Returns FALSE for failure. + Won't write below location 0x4000 in mem. +*/ +int TAPLoad(FILE *fp, Z80Byte id, Z80Word *addr, + Z80Word *len, Z80Byte *mem); + + +/* Saves a block to a TAP file. Returns FALSE for failure + (which it never does as long as fp is not NULL). +*/ +int TAPSave(FILE *fp, Z80Byte id, Z80Word *addr, + Z80Word *len, Z80Byte *mem); + + +/* Copies a string. The result must be freed. +*/ +char *StrCopy(const char *source); + + +/* Returns the filename portion of path. Note returned pointer is pointing + inside of path. +*/ +const char *Basename(const char *path); + + +/* Returns the directory portion of path. Note returned pointer is internal + static storage. If there are no directory seperators in path, "." is + returned. +*/ +const char *Dirname(const char *path); + + +#endif + + +/* END OF FILE */ @@ -29,6 +29,7 @@ static const char ident[]="$Id$"; #include <stdio.h> #include <string.h> #include "spec.h" +#include "snap.h" #include "gfx.h" #include "gui.h" #include "config.h" @@ -44,6 +45,9 @@ static const char ident_h[]=ESPEC_SPECH; #define FALSE 0 #endif +#define HIBYTE(w) ((w)>>8) +#define LOBYTE(w) ((w)&0xff) + /* ---------------------------------------- STATICS */ @@ -51,6 +55,9 @@ 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; + #define LOAD_PATCH 0xf0 #define SAVE_PATCH 0xf1 @@ -317,18 +324,6 @@ static void RomPatch(void) -static void LoadTape(Z80State *state) -{ - state->AF|=Z80_F_Carry; -} - - -static void SaveTape(Z80State *state) -{ - state->AF|=Z80_F_Carry; -} - - static int EDCallback(Z80 *z80, Z80Val data) { Z80State state; @@ -338,13 +333,39 @@ static int EDCallback(Z80 *z80, Z80Val data) switch((Z80Byte)data) { case SAVE_PATCH: - puts("Called tape save"); - SaveTape(&state); + if (!tape_out) + { + state.AF|=Z80_F_Carry; + } + else + { + if (TAPSave(tape_out,HIBYTE(state.AF),&state.IX,&state.DE,mem)) + { + state.AF&=~Z80_F_Carry; + } + else + { + state.AF|=Z80_F_Carry; + } + } break; case LOAD_PATCH: - puts("Called tape load"); - LoadTape(&state); + if (!tape_in) + { + state.AF|=Z80_F_Carry; + } + else + { + if (TAPLoad(tape_in,HIBYTE(state.AF),&state.IX,&state.DE,mem)) + { + state.AF&=~Z80_F_Carry; + } + else + { + state.AF|=Z80_F_Carry; + } + } break; default: @@ -533,7 +554,6 @@ Z80Byte SPECReadPort(Z80 *z80, Z80Word port) default: /* ULA */ if (!(lo&1)) { - border=(border+1)%16; /* TODO: Remove debug code */ /* Key matrix */ b=0xff; @@ -580,6 +600,8 @@ Z80Byte SPECReadForDisassem(Z80 *z80, Z80Word addr) } +/* TODO: Implement this as a binary search +*/ const char *SPECGetLabel(Z80 *z80, Z80Word addr) { static const struct @@ -788,4 +810,48 @@ const char *SPECInfo(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 */ @@ -31,6 +31,10 @@ #include "z80.h" #include "SDL.h" +/* Types for Mount and Unmount +*/ +typedef enum {SPEC_TAPE_IN,SPEC_TAPE_OUT} SPECMountType; + /* Initialise the SPEC */ @@ -54,6 +58,11 @@ const char *SPECGetLabel(Z80 *z80, Z80Word addr); const char *SPECInfo(Z80 *z80); +/* Interfaces for snapshot and device control +*/ +void SPECMount(SPECMountType type, const char *path); +void SPECUnmount(SPECMountType type); + #endif diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..c3396eb --- /dev/null +++ b/src/util.c @@ -0,0 +1,100 @@ +/* + + espec - Sinclair Spectrum emulator + + Copyright (C) 2003 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 + + ------------------------------------------------------------------------- + + Usual library wrappers and utils + +*/ +static const char ident[]="$Id$"; + +#include <stdio.h> +#include <string.h> + +#include "util.h" +#include "exit.h" + +static const char ident_h[]=ESPEC_UTIL_H; + + +/* ---------------------------------------- MACROS +*/ +#define DIRSEP '/' + +/* ---------------------------------------- INTERFACES +*/ +void *Malloc(size_t size) +{ + void *p=malloc(size); + + if (!p) + Exit("malloc failed for %lu bytes\n",(unsigned long)size); + + return p; +} + + +char *StrCopy(const char *source) +{ + return strcpy(Malloc(strlen(source)+1),source); +} + + +const char *Basename(const char *path) +{ + const char *p=path+strlen(path); + + while(p>path && *p!=DIRSEP) + p--; + + if (p>path) + p++; + + return p; +} + + +const char *Dirname(const char *path) +{ + static char dir[FILENAME_MAX]; + char *p; + + strcpy(dir,path); + + p=dir+strlen(dir); + + while(p>dir && *p!=DIRSEP) + p--; + + if (p>path) + { + p++; + *p=0; + } + else + { + strcpy(dir,"."); + } + + return dir; +} + + +/* END OF FILE */ diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..f391170 --- /dev/null +++ b/src/util.h @@ -0,0 +1,61 @@ +/* + + espec - Sinclair Spectrum emulator + + Copyright (C) 2003 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 + + ------------------------------------------------------------------------- + + Usual library wrappers and utils + +*/ + +#ifndef ESPEC_UTIL_H +#define ESPEC_UTIL_H "$Id$" + +#include <stdlib.h> + +/* ---------------------------------------- INTERFACES +*/ + +/* Returns result from malloc(size), calling Exit() if it fails. +*/ +void *Malloc(size_t size); + + +/* Copies a string. The result must be freed. +*/ +char *StrCopy(const char *source); + + +/* Returns the filename portion of path. Note returned pointer is pointing + inside of path. +*/ +const char *Basename(const char *path); + + +/* Returns the directory portion of path. Note returned pointer is internal + static storage. If there are no directory seperators in path, "." is + returned. +*/ +const char *Dirname(const char *path); + + +#endif + + +/* END OF FILE */ |