summaryrefslogtreecommitdiff
path: root/gemma.c
diff options
context:
space:
mode:
Diffstat (limited to 'gemma.c')
-rw-r--r--gemma.c250
1 files changed, 218 insertions, 32 deletions
diff --git a/gemma.c b/gemma.c
index 015362b..fbf72fc 100644
--- a/gemma.c
+++ b/gemma.c
@@ -36,7 +36,7 @@ static const char id[]="$Id$";
#define HI(w) (((w)&0xff00)>>8)
#define LO(w) ((w)&0xff)
-#define MK(h,l) (((Z80Word)(h))<<8|(l))
+#define MK(h,l) (((Z80Word)(h)<<8)|(l))
/* ---------------------------------------- GLOBALS
*/
@@ -54,6 +54,8 @@ static GtkWidget *step_over_button;
static GtkWidget *stop_button;
static GtkWidget *run_until_button;
+static GtkWidget *breakpoint_text;
+
static GtkWidget *top_window;
static GtkWidget *regview;
static GtkWidget *memview;
@@ -61,6 +63,9 @@ static GtkWidget *viewreg;
static GtkWidget *logview;
static GtkWidget *assemview;
+static GtkWidget *memview_combo;
+static GtkWidget *memview_check;
+
#define RUNNING(t) gtk_widget_set_sensitive(run_button,!t); \
gtk_widget_set_sensitive(step_button,!t); \
gtk_widget_set_sensitive(step_over_button,!t); \
@@ -76,6 +81,29 @@ static void *Malloc(size_t len);
static void *Realloc(void *p, size_t len);
+/* ---------------------------------------- PC BUFFER
+*/
+#define PC_BUFFER 100
+static Z80Word pc_buffer[PC_BUFFER]={0};
+static int pc_head=0;
+
+static Z80Word Get_PC(int back)
+{
+ return pc_buffer[(pc_head+back+1)%PC_BUFFER];
+}
+
+static void Step(void)
+{
+ pc_buffer[pc_head]=Z80GetPC(z80);
+
+ if (pc_head)
+ pc_head--;
+ else
+ pc_head=PC_BUFFER-1;
+
+ Z80SingleStep(z80);
+}
+
/* ---------------------------------------- DYNAMIC STRINGS
*/
@@ -335,13 +363,10 @@ static const int ToHex(char c)
static void FlagString(DString s, Z80Byte flag, Z80Byte last)
{
- static char buff[32];
static char *c[]={"S","Z","5","H","3","P","N","C"};
int f;
- sprintf(buff,"%-10.10s: ","Flags");
-
- DSAdd(s,buff);
+ DSAdd(s,"Flags: ");
for(f=0;f<8;f++)
{
@@ -502,24 +527,43 @@ static int Halt(Z80 *z80, Z80Val v)
*/
void GEMMA_UpdateDisplay(GEMMA_View view)
{
+ Z80State reg;
+
+ Z80GetState(z80,&reg);
+
if (view&UPDATE_ASSEM_VIEW)
{
- Z80State reg;
+ Z80Word pc;
DString ds;
+ char buff[10];
int f;
ds=DSInit();
- Z80GetState(z80,&reg);
- DSAdd(ds,"<tt>");
+ DSAdd(ds,"<tt><small>");
+
+ for(f=10;f>=0;f--)
+ {
+ pc=Get_PC(f);
+
+ sprintf(buff,"%4.4X: ",pc);
+ DSAdd(ds,buff);
+ DSAdd(ds,Z80Disassemble(z80,&pc));
+ DSAddChar(ds,'\n');
+ }
+
+ pc=Z80GetPC(z80);
- for(f=0;f<20;f++)
+ for(f=0;f<12;f++)
{
if (f==0)
{
DSAdd(ds,"<span foreground=\"white\" background=\"black\">");
}
- DSAdd(ds,Z80Disassemble(z80,&reg.PC));
+ sprintf(buff,"%4.4X: ",pc);
+ DSAdd(ds,buff);
+
+ DSAdd(ds,Z80Disassemble(z80,&pc));
if (f==0)
{
@@ -529,7 +573,7 @@ void GEMMA_UpdateDisplay(GEMMA_View view)
DSAddChar(ds,'\n');
}
- DSAdd(ds,"</tt>");
+ DSAdd(ds,"</small></tt>");
gtk_label_set_markup(GTK_LABEL(assemview),ds->text);
DSFree(ds);
@@ -539,52 +583,64 @@ void GEMMA_UpdateDisplay(GEMMA_View view)
{
static int reg_once=FALSE;
static Z80State last_reg;
- Z80State reg;
DString ds;
ds=DSInit();
- Z80GetState(z80,&reg);
if (!reg_once)
{
last_reg=reg;
+ reg_once=TRUE;
}
DSAdd(ds,"<tt>");
- DisplayState(ds,"A",2,HI(reg.AF),HI(last_reg.AF));
+ DisplayState(ds,"A ",2,HI(reg.AF),HI(last_reg.AF));
DSAdd(ds," ");
FlagString(ds,LO(reg.AF),LO(last_reg.AF));
DSAdd(ds,"\n");
- DisplayState(ds,"BC",4,reg.BC,last_reg.BC);
+ DisplayState(ds,"BC ",4,reg.BC,last_reg.BC);
DSAdd(ds," ");
- DisplayState(ds,"DE",4,reg.DE,last_reg.DE);
+ DisplayState(ds,"DE ",4,reg.DE,last_reg.DE);
DSAdd(ds," ");
- DisplayState(ds,"HL",4,reg.HL,last_reg.HL);
+ DisplayState(ds,"HL ",4,reg.HL,last_reg.HL);
DSAdd(ds,"\n");
- DisplayState(ds,"SP",4,reg.SP,last_reg.SP);
+ DisplayState(ds,"SP ",4,reg.SP,last_reg.SP);
DSAdd(ds," ");
- DisplayState(ds,"IX",4,reg.IX,last_reg.IX);
+ DisplayState(ds,"IX ",4,reg.IX,last_reg.IX);
DSAdd(ds," ");
- DisplayState(ds,"IY",4,reg.IY,last_reg.IY);
- DSAdd(ds,"\n");
+ DisplayState(ds,"IY ",4,reg.IY,last_reg.IY);
+ DSAdd(ds,"\n\n");
- DisplayState(ds,"AF'",4,reg.AF_,last_reg.AF_);
+ DisplayState(ds,"A' ",2,HI(reg.AF_),HI(last_reg.AF_));
DSAdd(ds," ");
+ FlagString(ds,LO(reg.AF_),LO(last_reg.AF_));
+ DSAdd(ds,"\n");
+
DisplayState(ds,"BC'",4,reg.BC_,last_reg.BC_);
DSAdd(ds," ");
DisplayState(ds,"DE'",4,reg.DE_,last_reg.DE_);
DSAdd(ds," ");
DisplayState(ds,"HL'",4,reg.HL_,last_reg.HL_);
+ DSAdd(ds,"\n\n");
+
+ DisplayState(ds,"PC ",4,reg.PC,last_reg.PC);
+ DSAdd(ds," ");
+ DisplayState(ds,"CYCLE",8,reg.cycle,last_reg.cycle);
+ DSAdd(ds,"\n\n");
+
+ DisplayState(ds,"R ",2,reg.R,last_reg.R);
+ DSAdd(ds," ");
+ DisplayState(ds,"IFF1",1,reg.IFF1,last_reg.IFF1);
+ DSAdd(ds," ");
+ DisplayState(ds,"IFF2",1,reg.IFF2,last_reg.IFF2);
DSAdd(ds,"\n");
- DisplayState(ds,"PC",4,reg.PC,last_reg.PC);
- DSAdd(ds,"\n");
- DisplayState(ds,"R",4,reg.R,last_reg.R);
- DSAdd(ds,"\n");
- DisplayState(ds,"CYCLES",8,reg.cycle,last_reg.cycle);
+ DisplayState(ds,"IM ",1,reg.IM,last_reg.IM);
+ DSAdd(ds," ");
+ DisplayState(ds,"I",1,reg.I,last_reg.I);
DSAdd(ds,"\n");
DSAdd(ds,"</tt>");
@@ -595,6 +651,114 @@ void GEMMA_UpdateDisplay(GEMMA_View view)
last_reg=reg;
}
+
+ if (view&UPDATE_MEM_VIEW)
+ {
+ Z80Word addr;
+ Z80Word orig;
+ DString ds;
+ int f;
+ gboolean as_words;
+
+ ds=DSInit();
+
+ as_words=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(memview_check));
+
+ switch(gtk_combo_box_get_active(GTK_COMBO_BOX(memview_combo)))
+ {
+ case 0:
+ addr=reg.HL;
+ break;
+ case 1:
+ addr=reg.SP;
+ as_words=TRUE;
+ break;
+ case 2:
+ addr=reg.IX;
+ break;
+ case 3:
+ addr=reg.IY;
+ break;
+ case 4:
+ addr=reg.BC;
+ break;
+ case 5:
+ addr=reg.DE;
+ break;
+ default:
+ addr=reg.PC;
+ break;
+ }
+
+ DSAdd(ds,"<tt><small>");
+
+ orig=addr;
+ addr-=6*8;
+
+ for(f=0;f<13;f++)
+ {
+ DString asc;
+ char buff[10];
+ Z80Word off;
+
+ asc=DSInit();
+
+ sprintf(buff,"%4.4X: ",addr);
+ DSAdd(ds,buff);
+
+ for(off=0;off<8;off++)
+ {
+ gchar *p;
+ p=g_markup_printf_escaped
+ ("%c",isprint(mem[addr+off]) ? mem[addr+off] : '.');
+ DSAdd(asc,p);
+ g_free(p);
+ }
+
+ for(off=0;off<8;off+=(as_words ? 2:1))
+ {
+ Z80Word a;
+
+ a=addr+off;
+
+ if (a==orig)
+ {
+ DSAdd(ds,"<span foreground=\"white\" "
+ "background=\"black\">");
+ }
+
+ if (as_words)
+ {
+ sprintf(buff,"%4.4X ",MK(mem[a+1],mem[a]));
+ }
+ else
+ {
+ sprintf(buff,"%2.2X ",mem[a]);
+ }
+
+ DSAdd(ds,buff);
+
+ if (a==orig)
+ {
+ DSAdd(ds,"</span>");
+ }
+ }
+
+ DSAdd(ds," ");
+ DSAdd(ds,asc->text);
+ DSAdd(ds,"\n");
+
+ DSFree(asc);
+
+ addr+=8;
+ }
+
+ DSAdd(ds,"</small></tt>");
+
+ gtk_label_set_markup(GTK_LABEL(memview),ds->text);
+
+ DSFree(ds);
+ }
}
@@ -713,7 +877,7 @@ void GEMMA_LoadLabels(const char *path)
void GEMMA_Step(void)
{
- Z80SingleStep(z80);
+ Step();
GEMMA_UpdateDisplay(UPDATE_ALL_VIEWS);
}
@@ -733,11 +897,13 @@ void GEMMA_StepOver(void)
while(reg.PC!=next && !stop)
{
- GEMMA_Step();
+ Step();
Z80GetState(z80,&reg);
gtk_main_iteration_do(FALSE);
}
+ GEMMA_UpdateDisplay(UPDATE_ALL_VIEWS);
+
RUNNING(FALSE);
}
@@ -758,8 +924,12 @@ void GEMMA_Run(void)
}
-void GEMMA_RunUntil(const char *expr)
+void GEMMA_RunUntil(void)
{
+ char *expr;
+
+ expr=StrCopy(gtk_entry_get_text(GTK_ENTRY(breakpoint_text)));
+
stop=FALSE;
RUNNING(TRUE);
@@ -770,14 +940,14 @@ void GEMMA_RunUntil(const char *expr)
if (!ExprEval(expr,&e,Expand,z80))
{
- Log("%s\n",ExprError());
+ DialogOK("Error evaluating express:\n%s",ExprError());
stop=TRUE;
continue;
}
if (e)
{
- Log("%s TRUE\n",expr);
+ DialogOK("%s TRUE",expr);
stop=TRUE;
continue;
}
@@ -786,6 +956,8 @@ void GEMMA_RunUntil(const char *expr)
gtk_main_iteration_do(FALSE);
}
+ free(expr);
+
RUNNING(FALSE);
}
@@ -803,6 +975,7 @@ void GEMMA_Init(GtkWidget *top)
for(f=0;f<256;f++) memctl[f]=1;
z80=Z80Init(mem,memctl,WritePort,ReadPort);
+ Z80SetPC(z80,0x100);
if (!z80)
{
@@ -818,6 +991,19 @@ void GEMMA_Init(GtkWidget *top)
viewreg=lookup_widget(top_window,"memory_view_choice");
logview=lookup_widget(top_window,"log_view");
assemview=lookup_widget(top_window,"assem_view");
+
+ memview_combo=lookup_widget(top_window,"memory_view_choice");
+ memview_check=lookup_widget(top_window,"viewmode_check");
+
+ breakpoint_text=lookup_widget(top_window,"breakpoint_text");
+
+ run_button=lookup_widget(top_window,"run_button");
+ step_button=lookup_widget(top_window,"step_button");
+ step_over_button=lookup_widget(top_window,"step_over_button");
+ stop_button=lookup_widget(top_window,"stop_button");
+ run_until_button=lookup_widget(top_window,"run_until_button");
+
+ gtk_combo_box_set_active(GTK_COMBO_BOX(memview_combo),0);
}