summaryrefslogtreecommitdiff
path: root/src/memmenu.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/memmenu.c')
-rw-r--r--src/memmenu.c329
1 files changed, 329 insertions, 0 deletions
diff --git a/src/memmenu.c b/src/memmenu.c
new file mode 100644
index 0000000..2badf65
--- /dev/null
+++ b/src/memmenu.c
@@ -0,0 +1,329 @@
+/*
+
+ 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
+
+ -------------------------------------------------------------------------
+
+ Provides a common error exit point
+
+*/
+static const char ident[]="$Id$";
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "memmenu.h"
+#include "spec.h"
+#include "gfx.h"
+#include "gui.h"
+
+#include <SDL.h>
+
+static const char ident_h[]=ESPEC_MEMMENU_H;
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define WHITE GFXRGB(255,255,255)
+#define BLACK GFXRGB(0,0,0)
+#define RED GFXRGB(255,100,100)
+#define GREEN GFXRGB(100,255,100)
+#define BLUE GFXRGB(100,100,255)
+
+#define MENU
+
+
+/* ---------------------------------------- PRIVATE FUNCTIONS
+*/
+static void Centre(const char *p, int y, Uint32 col)
+{
+ GFXPrint((320-strlen(p)*8)/2,y,col,"%s",p);
+}
+
+
+static void DisplayMenu(void)
+{
+ static const char *menu[]=
+ {
+ "1. Disassemble/Hex dump",
+ "2. Return ",
+ NULL
+ };
+
+ int f;
+
+ GFXClear(BLACK);
+
+ Centre("MEMORY MENU",0,WHITE);
+ Centre("Select an option",8,WHITE);
+
+ f=0;
+
+ while(menu[f])
+ {
+ Centre(menu[f],20+f*10,WHITE);
+ f++;
+ }
+}
+
+
+static const char *FlagString(Z80Byte flag)
+{
+ static char s[]="76543210";
+ static char c[]="SZ5H3PNC";
+ int f;
+
+ for(f=0;f<8;f++)
+ if (flag&(1<<(7-f)))
+ s[f]=c[f];
+ else
+ s[f]='-';
+
+ return s;
+}
+
+
+static int EnterAddress(Z80Word *w)
+{
+ unsigned long ul;
+ const char *p;
+
+ p=GUIInputString("Address?","");
+
+ if (*p)
+ {
+ ul=strtoul(p,NULL,0);
+
+ if (ul>0xffff)
+ {
+ GUIMessage("ERROR","Bad address");
+ }
+ else
+ {
+ *w=(Z80Word)ul;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+static void DoDisassem(Z80 *z80, const Z80State *s)
+{
+ static int hexmode=FALSE;
+ Z80Word pc=s->PC;
+ int quit=FALSE;
+
+ while(!quit)
+ {
+ SDL_Event *e;
+ Z80Word curr;
+ Z80Word next;
+ int f;
+
+ GFXClear(BLACK);
+
+ Centre("Press F1 for help",0,RED);
+
+ curr=pc;
+
+ for(f=0;f<21;f++)
+ {
+ char s[80];
+ char *p;
+ int y;
+
+ y=16+f*8;
+
+ GFXPrint(0,y,GREEN,"%4.4x",curr);
+
+ if (hexmode)
+ {
+ int n;
+
+ for(n=0;n<8;n++)
+ {
+ GFXPrint(40+n*24,y,WHITE,"%2.2x",
+ (int)SPECReadForDisassem(z80,curr));
+
+ curr++;
+ }
+ }
+ else
+ {
+ strcpy(s,Z80Disassemble(z80,&curr));
+
+ p=strtok(s,";");
+ GFXPrint(40,y,WHITE,"%s",p);
+ }
+
+ if (f==0)
+ next=curr;
+ }
+
+ GFXEndFrame(FALSE);
+
+ e=GFXWaitKey();
+
+ switch(e->key.keysym.sym)
+ {
+ 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");
+ break;
+
+ case SDLK_ESCAPE:
+ quit=TRUE;
+ break;
+
+ case SDLK_h:
+ hexmode=!hexmode;
+ break;
+
+ case SDLK_RETURN:
+ case SDLK_KP_ENTER:
+ EnterAddress(&pc);
+ break;
+
+ case SDLK_UP:
+ if (hexmode)
+ pc-=8;
+ else
+ pc--;
+ break;
+
+ case SDLK_DOWN:
+ pc=next;
+ break;
+
+ case SDLK_PAGEUP:
+ if (hexmode)
+ pc-=21*8;
+ else
+ pc-=21;
+ break;
+
+ case SDLK_PAGEDOWN:
+ pc=curr;
+ break;
+
+ case SDLK_LEFT:
+ pc-=1024;
+ break;
+
+ case SDLK_RIGHT:
+ pc+=1024;
+ break;
+
+ default:
+ break;
+ }
+ }
+}
+
+
+/* ---------------------------------------- EXPORTED INTERFACES
+*/
+void MemoryMenu(Z80 *z80)
+{
+ SDL_Event *e;
+ int quit=FALSE;
+ Z80State s;
+
+ Z80GetState(z80,&s);
+
+ GFXKeyRepeat(TRUE);
+
+ while(!quit)
+ {
+ DisplayMenu();
+ DisplayState(z80);
+ GFXEndFrame(FALSE);
+
+ e=GFXWaitKey();
+
+ switch(e->key.keysym.sym)
+ {
+ case SDLK_1:
+ DoDisassem(z80,&s);
+ break;
+
+ case SDLK_ESCAPE:
+ case SDLK_2:
+ quit=TRUE;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ GFXKeyRepeat(FALSE);
+}
+
+
+void DisplayState(Z80 *z80)
+{
+ Z80State s;
+ int y;
+
+ Z80GetState(z80,&s);
+
+ y=136;
+
+ GFXPrintPaper(0,y,RED,BLACK,"PC=%4.4x A=%2.2x F=%s",
+ s.PC,s.AF>>8,FlagString(s.AF&0xff));
+ y+=8;
+
+ GFXPrintPaper(0,y,RED,BLACK,"BC=%4.4x DE=%4.4x HL=%4.4x",s.BC,s.DE,s.HL);
+ y+=8;
+
+ GFXPrintPaper(0,y,RED,BLACK,"IX=%4.4x IY=%4.4x SP=%4.4x",s.IX,s.IY,s.SP);
+ y+=8;
+
+ GFXPrintPaper(0,y,RED,BLACK,"I=%2.2x IM=%2.2x R=%2.2x",s.I,s.IM,s.R);
+ y+=8;
+
+ GFXPrintPaper(0,y,RED,BLACK,"IFF1=%2.2x IFF2=%2.2x",s.IFF1,s.IFF2);
+ y+=8;
+
+ y+=8;
+ GFXPrintPaper(0,y,RED,BLACK,"%s\n",SPECInfo(z80));
+ y+=8;
+}
+
+
+
+
+/* END OF FILE */