summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan C <ianc@noddybox.co.uk>2004-01-16 02:28:10 +0000
committerIan C <ianc@noddybox.co.uk>2004-01-16 02:28:10 +0000
commitc1d084c70d3fa63eb787b57c5c6c3f511c95a357 (patch)
tree64cb119a1938dbd4d5e52a762b01c466500c6cd1
parent1a8ffd75606e69c6f766188f2ab424cc53782a52 (diff)
Added options to toggle individual breakpoints
-rw-r--r--src/gfx.h6
-rw-r--r--src/gui.c220
-rw-r--r--src/gui.h8
-rw-r--r--src/main.c12
-rw-r--r--src/memmenu.c158
-rw-r--r--src/memmenu.h4
6 files changed, 263 insertions, 145 deletions
diff --git a/src/gfx.h b/src/gfx.h
index 9b35868..6d051d8 100644
--- a/src/gfx.h
+++ b/src/gfx.h
@@ -55,12 +55,6 @@
void GFXInit(void);
-/* Size of the screen
-*/
-int GFXHeight(void);
-int GFXWidth(void);
-
-
/* Get the SDL_Surface for the screen
*/
SDL_Surface *GFXGetSurface(void);
diff --git a/src/gui.c b/src/gui.c
index c922aba..05ebc49 100644
--- a/src/gui.c
+++ b/src/gui.c
@@ -98,6 +98,133 @@ static void Box(const char *title, int x, int y, int width, int height)
}
+static int DoList(const char *title, int no, char * const list[], int *option)
+{
+ static const int max=GFX_HEIGHT/8-8;
+ SDL_Event *e;
+ int top;
+ int cur;
+ int done;
+ int f;
+
+ if (no==0)
+ return -1;
+
+ top=0;
+ cur=0;
+
+ done=FALSE;
+
+ while(!done)
+ {
+ Box(title,7,7,GFX_WIDTH-14,GFX_HEIGHT-14);
+
+ if (option)
+ {
+ Centre("Cursors to move, RETURN to accept",
+ GFX_HEIGHT-44,WHITE);
+ Centre("SPACE toggles, I inverts all",
+ GFX_HEIGHT-36,WHITE);
+ Centre("S select all, C clear all",
+ GFX_HEIGHT-28,WHITE);
+ }
+ else
+ Centre("Cursors and RETURN to select",GFX_HEIGHT-28,WHITE);
+
+ Centre("ESCAPE to cancel",GFX_HEIGHT-20,WHITE);
+
+ for(f=0;f<max;f++)
+ {
+ if (f+top<no)
+ {
+ Uint32 pen,paper;
+
+ if (f+top==cur)
+ {
+ pen=WHITE;
+ paper=RED;
+ }
+ else
+ {
+ pen=GREY;
+ paper=BLACK;
+ }
+
+ if (option)
+ GFXPrintPaper(16,20+f*8,pen,paper,"%c %-34.34s",
+ option[f+top] ? FONT_TICK:' ',list[f+top]);
+ else
+ GFXPrintPaper(16,20+f*8,pen,paper,"%-36.36s",list[f+top]);
+ }
+ }
+
+ GFXEndFrame(FALSE);
+
+ e=GFXWaitKey();
+
+ switch(e->key.keysym.sym)
+ {
+ case SDLK_RETURN:
+ done=TRUE;
+ break;
+
+ case SDLK_SPACE:
+ if (option)
+ option[cur]=!option[cur];
+ break;
+
+ case SDLK_i:
+ if (option)
+ for(f=0;f<no;f++)
+ option[f]=!option[f];
+ break;
+
+ case SDLK_s:
+ if (option)
+ for(f=0;f<no;f++)
+ option[f]=TRUE;
+ break;
+
+ case SDLK_c:
+ if (option)
+ for(f=0;f<no;f++)
+ option[f]=FALSE;
+ break;
+
+ case SDLK_ESCAPE:
+ cur=-1;
+ done=TRUE;
+ break;
+
+ case SDLK_UP:
+ if (cur>0)
+ {
+ cur--;
+
+ if (cur<top)
+ top=cur;
+ }
+ break;
+
+ case SDLK_DOWN:
+ if (cur<no-1)
+ {
+ cur++;
+
+ if (cur>top+max-2)
+ top=cur-max+2;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return cur;
+}
+
+
/* ---------------------------------------- EXPORTED INTERFACES
*/
int GUIMessage(GUIBoxType type, const char *title, const char *format,...)
@@ -265,90 +392,33 @@ const char *GUIInputString(const char *prompt, const char *orig)
int GUIListSelect(const char *title, int no, char * const list[])
{
- static const int max=GFX_HEIGHT/8-8;
- SDL_Event *e;
- int top;
- int cur;
- int done;
- int f;
-
- if (no==0)
- return -1;
-
- top=0;
- cur=0;
-
- done=FALSE;
-
- while(!done)
- {
- Box(title,7,7,GFX_WIDTH-14,GFX_HEIGHT-14);
-
- Centre("Cursors and RETURN to select",GFX_HEIGHT-40,WHITE);
- Centre("ESCAPE to cancel",GFX_HEIGHT-32,WHITE);
-
- for(f=0;f<max;f++)
- {
- if (f+top<no)
- {
- Uint32 pen,paper;
-
- if (f+top==cur)
- {
- pen=WHITE;
- paper=RED;
- }
- else
- {
- pen=GREY;
- paper=BLACK;
- }
+ return DoList(title,no,list,NULL);
+}
- GFXPrintPaper(16,20+f*8,pen,paper,"%-36.36s",list[f+top]);
- }
- }
- GFXEndFrame(FALSE);
-
- e=GFXWaitKey();
+int GUIListOption(const char *title, int no, char * const list[], int option[])
+{
+ int *o;
+ int sel;
+ int f;
- switch(e->key.keysym.sym)
- {
- case SDLK_RETURN:
- done=TRUE;
- break;
+ if (no==0)
+ return FALSE;
- case SDLK_ESCAPE:
- cur=-1;
- done=TRUE;
- break;
+ o=Malloc(no * sizeof *o);
- case SDLK_UP:
- if (cur>0)
- {
- cur--;
+ for(f=0;f<no;f++)
+ o[f]=option[f];
- if (cur<top)
- top=cur;
- }
- break;
+ sel=DoList(title,no,list,o);
- case SDLK_DOWN:
- if (cur<no-1)
- {
- cur++;
+ if (sel!=-1)
+ for(f=0;f<no;f++)
+ option[f]=o[f];
- if (cur>top+max-2)
- top=cur-max+2;
- }
- break;
-
- default:
- break;
- }
- }
+ free(o);
- return cur;
+ return sel!=-1;
}
diff --git a/src/gui.h b/src/gui.h
index e1ad43a..efbb40c 100644
--- a/src/gui.h
+++ b/src/gui.h
@@ -58,6 +58,14 @@ const char *GUIInputString(const char *prompt, const char *orig);
int GUIListSelect(const char *title, int no, char * const list[]);
+/* Allows options to be toggled in a list. Returns FALSE for cancelled (in
+ which case option will be as it was. TRUE if accepted, and option will be
+ updated.
+*/
+int GUIListOption(const char *title,
+ int no, char * const list[], int option[]);
+
+
/* Select a file from the given directory.
If load is TRUE then a new name cannot be entered.
diff --git a/src/main.c b/src/main.c
index a79464c..587e657 100644
--- a/src/main.c
+++ b/src/main.c
@@ -36,6 +36,7 @@ static const char id[]="$Id$";
#include "memmenu.h"
#include "config.h"
#include "exit.h"
+#include "util.h"
/* ---------------------------------------- MACROS
@@ -102,7 +103,7 @@ int main(int argc, char *argv[])
TODO: Proper switch handling
*/
if (argc>1 && strcmp(argv[1],"-m")==0)
- MemoryMenu(z80);
+ quit=MemoryMenu(z80);
while(!quit)
{
@@ -129,16 +130,16 @@ int main(int argc, char *argv[])
if ((brk=Break()))
{
GUIMessage(eMessageBox,"BREAKPOINT","%s",brk);
- MemoryMenu(z80);
+ quit=MemoryMenu(z80);
}
- while((e=GFXGetKey()))
+ while(!quit && (e=GFXGetKey()))
{
switch (e->key.keysym.sym)
{
case SDLK_ESCAPE:
if (e->key.state==SDL_PRESSED)
- quit=TRUE;
+ quit=GUIMessage(eYesNoBox,"QUIT","Sure?");
break;
case SDLK_F1:
@@ -214,7 +215,8 @@ int main(int argc, char *argv[])
case SDLK_F11:
if (e->key.state==SDL_PRESSED)
- MemoryMenu(z80);
+ quit=MemoryMenu(z80);
+ Debug("quit=%d\n");
break;
case SDLK_F12:
diff --git a/src/memmenu.c b/src/memmenu.c
index 41a18b3..0d5053f 100644
--- a/src/memmenu.c
+++ b/src/memmenu.c
@@ -63,6 +63,7 @@ static const char ident_h[]=ESPEC_MEMMENU_H;
typedef struct
{
int no;
+ int *active;
char **expr;
} Breakpoint;
@@ -86,7 +87,7 @@ typedef struct
/* ---------------------------------------- STATIC DATA
*/
static FILE *trace=NULL;
-static Breakpoint bpoint={0,NULL};
+static Breakpoint bpoint={0,NULL,NULL};
static const char *brk=NULL;
static int lodged=FALSE;
@@ -98,9 +99,21 @@ static int Instruction(Z80 *z80, Z80Val data);
/* ---------------------------------------- PRIVATE FUNCTIONS
*/
+static int BreaksActive(void)
+{
+ int f;
+ int ret=FALSE;
+
+ for(f=0;f<bpoint.no;f++)
+ ret|=bpoint.active[f];
+
+ return ret;
+}
+
+
static void SetCallback(Z80 *z80)
{
- if ((trace || bpoint.no) && !lodged)
+ if ((trace || BreaksActive()) && !lodged)
{
Z80LodgeCallback(z80,eZ80_Instruction,Instruction);
lodged=TRUE;
@@ -110,7 +123,7 @@ static void SetCallback(Z80 *z80)
static void ClearCallback(Z80 *z80)
{
- if (!trace && !bpoint.no && lodged)
+ if (!trace && !BreaksActive() && lodged)
{
Z80RemoveCallback(z80,eZ80_Instruction,Instruction);
lodged=FALSE;
@@ -120,7 +133,7 @@ static void ClearCallback(Z80 *z80)
static void Centre(const char *p, int y, Uint32 col)
{
- GFXPrint((320-strlen(p)*8)/2,y,col,"%s",p);
+ GFXPrint((GFX_WIDTH-strlen(p)*8)/2,y,col,"%s",p);
}
@@ -128,16 +141,17 @@ static void DisplayMenu(void)
{
static const char *menu[]=
{
- "1 - Disassemble/Hex dump ",
- "2 - Disassemble to file ",
- "3 - Start/Stop trace log ",
- "4 - Playback trace log ",
- "5 - Add a new breakpoint ",
- "6 -Clear a breakpoint ",
- "7 - Display breakpoints ",
- "8 - Clear all breakpoints",
- "R - Reset ",
- "ESC - Return ",
+ "1 - Disassemble/Hex dump ",
+ "2 - Disassemble to file ",
+ "3 - Start/Stop trace log ",
+ "4 - Playback trace log ",
+ "5 - Add a new breakpoint ",
+ "6 - Set active breakpoints",
+ "7 - Remove a breakpoint ",
+ "8 - Clear all breakpoints ",
+ "R - Reset ",
+ "X - Exit (without confirm)",
+ "ESC - Return ",
NULL
};
@@ -458,15 +472,16 @@ static int Instruction(Z80 *z80, Z80Val data)
}
for(f=0;f<bpoint.no;f++)
- {
- long l;
-
- if (Z80Expression(z80,bpoint.expr[f],&l,NULL))
+ if (bpoint.active[f])
{
- if (l)
- brk=bpoint.expr[f];
+ long l;
+
+ if (Z80Expression(z80,bpoint.expr[f],&l,NULL))
+ {
+ if (l)
+ brk=bpoint.expr[f];
+ }
}
- }
return TRUE;
}
@@ -720,63 +735,84 @@ static void DoAddBreakpoint(Z80 *z80)
}
else
{
+ int f;
+
+ for(f=0;f<50;f++)
+ {
bpoint.no++;
bpoint.expr=Realloc(bpoint.expr,bpoint.no * sizeof(*bpoint.expr));
+ bpoint.active=Realloc(bpoint.active,bpoint.no * sizeof(*bpoint.active));
bpoint.expr[bpoint.no-1]=StrCopy(expr);
+ bpoint.active[bpoint.no-1]=TRUE;
+ }
SetCallback(z80);
}
}
-static void DoRemoveBreakpoint(Z80 *z80, int delete)
+static void DoActiveBreakpoint(Z80 *z80)
{
if (bpoint.no==0)
{
- if (delete)
- GUIMessage(eMessageBox,"NOTICE","No breakpoints to delete");
- else
- GUIMessage(eMessageBox,"NOTICE","No breakpoints to display");
-
+ GUIMessage(eMessageBox,"NOTICE","No breakpoints to set");
return;
}
GFXClear(BLACK);
- if (delete)
- {
- int sel;
+ GUIListOption("SELECT ACTIVE BREAKPOINTS",
+ bpoint.no,bpoint.expr,bpoint.active);
+}
- sel=GUIListSelect("BREAKPOINT TO DELETE",bpoint.no,bpoint.expr);
- while (sel!=-1)
- {
- int f;
+static void DoRemoveBreakpoint(Z80 *z80)
+{
+ int sel;
- free(bpoint.expr[sel]);
+ if (bpoint.no==0)
+ {
+ GUIMessage(eMessageBox,"NOTICE","No breakpoints to delete");
+ return;
+ }
- for(f=sel;f<bpoint.no-1;f++)
- bpoint.expr[f]=bpoint.expr[f+1];
+ GFXClear(BLACK);
- bpoint.no--;
+ sel=GUIListSelect("BREAKPOINT TO DELETE",bpoint.no,bpoint.expr);
- if (bpoint.no==0)
- {
- free(bpoint.expr);
- bpoint.expr=NULL;
- }
- else
- bpoint.expr=Realloc(bpoint.expr,
- bpoint.no * sizeof(*bpoint.expr));
+ while (sel!=-1)
+ {
+ int f;
+
+ free(bpoint.expr[sel]);
+
+ for(f=sel;f<bpoint.no-1;f++)
+ {
+ bpoint.expr[f]=bpoint.expr[f+1];
+ bpoint.active[f]=bpoint.active[f+1];
+ }
- ClearCallback(z80);
+ bpoint.no--;
- sel=GUIListSelect("BREAKPOINT TO DELETE",bpoint.no,bpoint.expr);
+ if (bpoint.no==0)
+ {
+ free(bpoint.expr);
+ bpoint.expr=NULL;
+ bpoint.active=NULL;
}
+ else
+ {
+ bpoint.expr=Realloc(bpoint.expr,
+ bpoint.no * sizeof(*bpoint.expr));
+ bpoint.active=Realloc(bpoint.active,
+ bpoint.no * sizeof(*bpoint.active));
+ }
+
+ ClearCallback(z80);
+
+ sel=GUIListSelect("BREAKPOINT TO DELETE",bpoint.no,bpoint.expr);
}
- else
- GUIListSelect("CURRENT BREAKPOINTS",bpoint.no,bpoint.expr);
}
@@ -800,9 +836,10 @@ static void DoClearBreakpoint(Z80 *z80)
/* ---------------------------------------- EXPORTED INTERFACES
*/
-void MemoryMenu(Z80 *z80)
+int MemoryMenu(Z80 *z80)
{
SDL_Event *e;
+ int done=FALSE;
int quit=FALSE;
Z80State s;
@@ -810,10 +847,10 @@ void MemoryMenu(Z80 *z80)
GFXKeyRepeat(TRUE);
- while(!quit)
+ while(!done)
{
DisplayMenu();
- DisplayState(z80);
+ DisplayZ80State(&s,GFX_HEIGHT-70,RED);
GFXEndFrame(FALSE);
e=GFXWaitKey();
@@ -845,11 +882,11 @@ void MemoryMenu(Z80 *z80)
break;
case SDLK_6:
- DoRemoveBreakpoint(z80,TRUE);
+ DoActiveBreakpoint(z80);
break;
case SDLK_7:
- DoRemoveBreakpoint(z80,FALSE);
+ DoRemoveBreakpoint(z80);
break;
case SDLK_8:
@@ -864,16 +901,23 @@ void MemoryMenu(Z80 *z80)
}
break;
- case SDLK_ESCAPE:
+ case SDLK_x:
+ done=TRUE;
quit=TRUE;
break;
+ case SDLK_ESCAPE:
+ done=TRUE;
+ break;
+
default:
break;
}
}
GFXKeyRepeat(FALSE);
+
+ return quit;
}
@@ -882,7 +926,7 @@ void DisplayState(Z80 *z80)
Z80State s;
Z80GetState(z80,&s);
- DisplayZ80State(&s,136,RED);
+ DisplayZ80State(&s,GFX_HEIGHT/2,RED);
}
diff --git a/src/memmenu.h b/src/memmenu.h
index f04b6b8..4b818fd 100644
--- a/src/memmenu.h
+++ b/src/memmenu.h
@@ -30,9 +30,9 @@
#include "z80.h"
-/* Memory menu
+/* Memory menu. Returns TRUE if exit (from program) selected.
*/
-void MemoryMenu(Z80 *z80);
+int MemoryMenu(Z80 *z80);
/* Display the state of the SPEC at the bottom of the screen