From c1d4cc4739583f906b639daf3bd9384dd791530e Mon Sep 17 00:00:00 2001 From: Ian C Date: Wed, 30 Aug 2006 22:24:41 +0000 Subject: Development checkin --- Makefile | 10 +- callbacks.c | 74 ++++++ callbacks.h | 40 +++ gemma.c | 837 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ gemma.glade | 420 +++++++++++++++++------------- gemma.h | 56 ++++ gtkutil.c | 21 +- gtkutil.h | 4 + main.c | 28 +- z80.c | 6 + z80.h | 5 + 11 files changed, 1309 insertions(+), 192 deletions(-) create mode 100644 gemma.c create mode 100644 gemma.h diff --git a/Makefile b/Makefile index d309ea7..09d32ab 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ # # ------------------------------------------------------------------------- # -# $Id: Makefile,v 1.12 2006-08-28 22:40:44 ianc Exp $ +# $Id: Makefile,v 1.13 2006-08-30 22:24:41 ianc Exp $ # # @@ -70,7 +70,8 @@ SOURCE = z80.c \ support.c \ callbacks.c \ interface.c \ - gtkutil.c + gtkutil.c \ + gemma.c BASE_O = z80.o \ z80_decode.o \ @@ -83,7 +84,8 @@ GEMMA_O = main.o \ support.o \ callbacks.o \ interface.o \ - gtkutil.o + gtkutil.o \ + gemma.o all: $(TARGETS) @@ -91,7 +93,7 @@ emma: $(BASE_O) $(EMMA_O) cc -o emma $(BASE_O) $(EMMA_O) $(LIBS) gemma: $(BASE_O) $(GEMMA_O) - cc -o gemma $(GBASE_O) $(GEMMA_O) `pkg-config --libs gtk+-2.0` + cc -o gemma $(BASE_O) $(GEMMA_O) `pkg-config --libs gtk+-2.0` tests: emucpm.hex zexdoc.hex zexall.hex diff --git a/callbacks.c b/callbacks.c index 019fde9..a0a7a1a 100644 --- a/callbacks.c +++ b/callbacks.c @@ -3,8 +3,82 @@ #endif #include +#include #include "callbacks.h" #include "interface.h" #include "support.h" +#include "gtkutil.h" +#include "gemma.h" + + +void CloseApplication(GtkObject *object, gpointer user_data) +{ + gtk_main_quit(); +} + + +void OnRun(GtkButton *button, gpointer user_data) +{ + GEMMA_Run(); +} + + +void OnStep(GtkButton *button, gpointer user_data) +{ + GEMMA_Step(); +} + + +void OnStepOver(GtkButton *button, gpointer user_data) +{ + GEMMA_StepOver(); +} + + +void OnStop(GtkButton *button, gpointer user_data) +{ + GEMMA_Stop(); +} + + +void OnLoadHEX(GtkButton *button, gpointer user_data) +{ + static char path[PATH_MAX]={0}; + + if (DialogFSelect("Select INTEL HEX File to load",path)) + { + GEMMA_LoadHEX(path); + } +} + + +void OnLoadLabels(GtkButton *button, gpointer user_data) +{ + static char path[PATH_MAX]={0}; + + if (DialogFSelect("Select Label File to load",path)) + { + GEMMA_LoadLabels(path); + } +} + + +void OnRunUntil(GtkButton *button, gpointer user_data) +{ + DialogOK("Not yet implemented"); +} + + +void OnQuit(GtkButton *button, gpointer user_data) +{ + gtk_main_quit(); +} + + +void OnMemoryViewChoice(GtkComboBox *combobox, gpointer user_data) +{ + GEMMA_UpdateDisplay(UPDATE_MEM_VIEW); +} + diff --git a/callbacks.h b/callbacks.h index 6fefc7c..f3a05f5 100644 --- a/callbacks.h +++ b/callbacks.h @@ -1,2 +1,42 @@ #include + +void +CloseApplication (GtkObject *object, + gpointer user_data); + +void +OnRun (GtkButton *button, + gpointer user_data); + +void +OnStep (GtkButton *button, + gpointer user_data); + +void +OnStepOver (GtkButton *button, + gpointer user_data); + +void +OnStop (GtkButton *button, + gpointer user_data); + +void +OnLoadHEX (GtkButton *button, + gpointer user_data); + +void +OnLoadLabels (GtkButton *button, + gpointer user_data); + +void +OnRunUntil (GtkButton *button, + gpointer user_data); + +void +OnQuit (GtkButton *button, + gpointer user_data); + +void +OnMemoryViewChoice (GtkComboBox *combobox, + gpointer user_data); diff --git a/gemma.c b/gemma.c new file mode 100644 index 0000000..015362b --- /dev/null +++ b/gemma.c @@ -0,0 +1,837 @@ +/* + + GEMMA - Z80 testbed + + Copyright (C) 2006 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 + + ------------------------------------------------------------------------- + +*/ +static const char id[]="$Id$"; + +#include +#include +#include +#include +#include + +#include "gemma.h" +#include "expr.h" +#include "gtkutil.h" +#include "support.h" + +#define HI(w) (((w)&0xff00)>>8) +#define LO(w) ((w)&0xff) +#define MK(h,l) (((Z80Word)(h))<<8|(l)) + +/* ---------------------------------------- GLOBALS +*/ +static Z80 *z80; +static Z80Byte mem[0x10000]; +static int memctl[256]; + +static sig_atomic_t stop=FALSE; + +static Z80Label *label=NULL; + +static GtkWidget *run_button; +static GtkWidget *step_button; +static GtkWidget *step_over_button; +static GtkWidget *stop_button; +static GtkWidget *run_until_button; + +static GtkWidget *top_window; +static GtkWidget *regview; +static GtkWidget *memview; +static GtkWidget *viewreg; +static GtkWidget *logview; +static GtkWidget *assemview; + +#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); \ + gtk_widget_set_sensitive(run_until_button,!t); \ + gtk_widget_set_sensitive(stop_button,t); + + +/* ---------------------------------------- PROTOS +*/ +static void Log(const char *format, ...); +static Z80Word Address(const char *p); +static void *Malloc(size_t len); +static void *Realloc(void *p, size_t len); + + +/* ---------------------------------------- DYNAMIC STRINGS +*/ + +typedef struct +{ + size_t len; + char *text; +} *DString; + + +#define BLOCKSIZE 512 + + +DString DSInit(void) +{ + DString ds; + + ds=Malloc(sizeof *ds); + + ds->len=0; + ds->text=Malloc(BLOCKSIZE); + ds->text[0]=0; + + return ds; +} + + +void DSFree(DString ds) +{ + if (ds) + { + free(ds->text); + free(ds); + } +} + + +DString DSAddChar(DString to, char c) +{ + if (((to->len+2)%BLOCKSIZE)==0) + { + to->text=Realloc(to->text,(((to->len+2)/BLOCKSIZE)+1)*BLOCKSIZE); + } + + to->text[to->len++]=c; + to->text[to->len]=0; + + return to; +} + + +DString DSAdd(DString to, const char *from) +{ + to->len+=strlen(from); + to->text=Realloc(to->text,(((to->len+1)/BLOCKSIZE)+1)*BLOCKSIZE); + + strcat(to->text,from); + + return to; +} + + +/* ---------------------------------------- PRIVATE FUNCTIONS +*/ +static void Log(const char *format, ...) +{ + static char buff[4096]; + va_list va; + + va_start(va,format); + vsprintf(buff,format,va); + va_end(va); + + AppendText(logview,buff); +} + + +static int StrEq(const char *a, const char *b) +{ + while(*a && *b && tolower(*a)==tolower(*b)) + { + a++; + b++; + } + + if (*a || *b) + return FALSE; + else + return TRUE; +} + + +static int Expand(void *client, const char *p, long *res) +{ + Z80State s; + int ok=TRUE; + + Z80GetState(z80,&s); + + if (StrEq(p,"AF")) + *res=s.AF; + else if (StrEq(p,"BC")) + *res=s.BC; + else if (StrEq(p,"DE")) + *res=s.DE; + else if (StrEq(p,"HL")) + *res=s.HL; + else if (StrEq(p,"IX")) + *res=s.IX; + else if (StrEq(p,"IY")) + *res=s.IY; + else if (StrEq(p,"SP")) + *res=s.SP; + else if (StrEq(p,"PC")) + *res=s.PC; + else if (StrEq(p,"A")) + *res=HI(s.AF); + else if (StrEq(p,"F")) + *res=LO(s.AF); + else if (StrEq(p,"B")) + *res=HI(s.BC); + else if (StrEq(p,"C")) + *res=LO(s.BC); + else if (StrEq(p,"D")) + *res=HI(s.DE); + else if (StrEq(p,"E")) + *res=LO(s.DE); + else if (StrEq(p,"H")) + *res=HI(s.HL); + else if (StrEq(p,"L")) + *res=LO(s.HL); + else if (StrEq(p,"AF_")) + *res=s.AF_; + else if (StrEq(p,"BC_")) + *res=s.BC_; + else if (StrEq(p,"DE_")) + *res=s.DE_; + else if (StrEq(p,"HL_")) + *res=s.HL_; + else if (StrEq(p,"A_")) + *res=HI(s.AF_); + else if (StrEq(p,"F_")) + *res=LO(s.AF_); + else if (StrEq(p,"B_")) + *res=HI(s.BC_); + else if (StrEq(p,"C_")) + *res=LO(s.BC_); + else if (StrEq(p,"D_")) + *res=HI(s.DE_); + else if (StrEq(p,"E_")) + *res=LO(s.DE_); + else if (StrEq(p,"H_")) + *res=HI(s.HL_); + else if (StrEq(p,"L_")) + *res=LO(s.HL_); + else if (StrEq(p,"IM")) + *res=s.IM; + else if (StrEq(p,"R")) + *res=s.R; + else if (StrEq(p,"IFF1")) + *res=s.IFF1; + else if (StrEq(p,"IFF2")) + *res=s.IFF2; + else if (p[0]=='@') + { + Z80Word n; + + n=Address(p+1); + *res=mem[n]; + } + else if (p[0]=='#') + { + Z80Word n; + + n=Address(p+1); + *res=MK(mem[n+1],mem[n]); + } + else /* Check for labels */ + { + int f; + + ok=FALSE; + + for(f=0;label && label[f].label;f++) + { + if (StrEq(p,label[f].label)) + { + *res=label[f].address; + ok=TRUE; + break; + } + } + } + + return ok; +} + + +static Z80Word Address(const char *p) +{ + long e=0; + + if (!ExprEval(p,&e,Expand,z80)) + Log("%s\n",ExprError()); + + return (Z80Word)e; +} + + +static void *Malloc(size_t len) +{ + void *n; + + n=malloc(len); + + if (!n) + { + fprintf(stderr,"malloc failed\n"); + exit(EXIT_FAILURE); + } + + return n; +} + +static void *Realloc(void *p, size_t len) +{ + void *n; + + n=realloc(p,len); + + if (!n) + { + fprintf(stderr,"realloc failed\n"); + exit(EXIT_FAILURE); + } + + return n; +} + +static char *StrCopy(const char *p) +{ + return strcpy(Malloc(strlen(p)+1),p); +} + +static const int ToHex(char c) +{ + c=toupper(c); + + if (c>='0' && c<='9') + return c-'0'; + + if (c>='A' && c<='F') + return c-'A'+10; + + return 0; +} + +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); + + for(f=0;f<8;f++) + { + int b=1<<(7-f); + + if ((last&b)!=(flag&b)) + { + DSAdd(s,""); + } + + if (flag&b) + { + DSAdd(s,c[f]); + } + else + { + DSAdd(s,"-"); + } + + if ((last&b)!=(flag&b)) + { + DSAdd(s,""); + } + } +} + + +static void DisplayState(DString s, const char *label, + int width, Z80Val val, Z80Val last) +{ + static char buff[128]; + + sprintf(buff,"%s: %s%*.*lX", + label, + (last==val) ? + "" : + "", + width,width, + val); + + DSAdd(s,buff); +} + + +/* ---------------------------------------- MEMORY +*/ +static Z80Byte ReadPort(Z80 *z80, Z80Word addr) +{ + Z80Byte b=0xff; + Z80Word ptr; + Z80State s; + char expr[1024]; + char *p; + + Z80GetState(z80,&s); + + switch(addr&0xff) + { + case 0x80: + ptr=MK(mem[1],mem[0]); + + p=expr; + + while(mem[ptr]) + *p++=mem[ptr++]; + + *p=0; + + b=(Z80Byte)Address(expr); + + /* Log("%s -> %u\n",expr,b); */ + + break; + + case 0x81: + ptr=s.DE; + + p=expr; + + while(mem[ptr]) + *p++=mem[ptr++]; + + *p=0; + + b=(Z80Byte)Address(expr); + + break; + + default: + Log("Read from port 0x%4.4x\n",(int)addr); + break; + } + + return b; +} + + +static void WritePort(Z80 *z80, Z80Word addr, Z80Byte val) +{ + Z80State s; + DString ds; + + ds=DSInit(); + Z80GetState(z80,&s); + + switch(addr&0xff) + { + case 0x80: + DSAddChar(ds,val); + break; + + case 0x81: + DSAdd(ds,"Stop requested via OUT(0x81)\n"); + stop=TRUE; + break; + + case 0x82: + while(mem[s.DE]!='$') + { + if (isspace(mem[s.DE]) || isprint(mem[s.DE])) + { + DSAddChar(ds,mem[s.DE]); + } + + s.DE++; + } + break; + + case 0x83: + while(mem[s.DE]) + { + DSAddChar(ds,mem[s.DE]); + s.DE++; + } + break; + + default: + Log("Wrote 0x%2.2x to port 0x%4.4x\n",(int)val,(int)addr); + return; + } + + Log(ds->text); + DSFree(ds); +} + + +static int Halt(Z80 *z80, Z80Val v) +{ + + Log("**** Processor halted\n"); + DialogOK("Processor halted\n"); + stop=TRUE; + return FALSE; +} + + +/* ---------------------------------------- EXPORTED FUNCTIONS +*/ +void GEMMA_UpdateDisplay(GEMMA_View view) +{ + if (view&UPDATE_ASSEM_VIEW) + { + Z80State reg; + DString ds; + int f; + + ds=DSInit(); + Z80GetState(z80,®); + DSAdd(ds,""); + + for(f=0;f<20;f++) + { + if (f==0) + { + DSAdd(ds,""); + } + + DSAdd(ds,Z80Disassemble(z80,®.PC)); + + if (f==0) + { + DSAdd(ds,""); + } + + DSAddChar(ds,'\n'); + } + + DSAdd(ds,""); + gtk_label_set_markup(GTK_LABEL(assemview),ds->text); + + DSFree(ds); + } + + if (view&UPDATE_REG_VIEW) + { + static int reg_once=FALSE; + static Z80State last_reg; + Z80State reg; + DString ds; + + ds=DSInit(); + Z80GetState(z80,®); + + if (!reg_once) + { + last_reg=reg; + } + + DSAdd(ds,""); + + 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"); + + DisplayState(ds,"SP",4,reg.SP,last_reg.SP); + DSAdd(ds," "); + 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,"AF'",4,reg.AF_,last_reg.AF_); + DSAdd(ds," "); + 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"); + + 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); + DSAdd(ds,"\n"); + + DSAdd(ds,""); + + gtk_label_set_markup(GTK_LABEL(regview),ds->text); + + DSFree(ds); + + last_reg=reg; + } +} + + +void GEMMA_LoadHEX(const char *path) +{ + FILE *fp; + char buff[1024]; + int done=FALSE; + + if (!(fp=fopen(path,"r"))) + { + Log("Failed to open %s\n",path); + return; + } + + while(!done) + { + if (!fgets(buff,sizeof buff,fp)) + { + Log("Missing EOF record\n"); + done=TRUE; + } + + if (!done && buff[0]!=':') + { + Log("Invalid Intel HEX file\n"); + done=TRUE; + } + + if (!done && buff[8]=='1') + { + Log("\n"); + done=TRUE; + } + + if (!done) + { + Z80Word addr; + int len; + int f; + + len=ToHex(buff[1])<<4|ToHex(buff[2]); + + addr=ToHex(buff[3])<<12|ToHex(buff[4])<<8| + ToHex(buff[5])<<4|ToHex(buff[6]); + + Log("Segment of 0x%2.2x bytes at address 0x%4.4x\n",len,addr); + + for(f=0;f + 900 + 600 True GEMMA GTK_WINDOW_TOPLEVEL GTK_WIN_POS_NONE False - 770 - 640 - True + 800 + 600 + False True True False False - GDK_WINDOW_TYPE_HINT_DIALOG + GDK_WINDOW_TYPE_HINT_NORMAL GDK_GRAVITY_NORTH_WEST True False - + True False 0 - - 3 + True - False + True 0 - + True - True - 0 + <b>Assembler View</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + True + True + + + + + + True + <b>Regsiter View</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 + + + 0 + True + True + + + + + 0 + True + True + + + + + + 1 + True + True + 0 + + + + True + False + 0 - + True - True - 0 - - - - True - True - GTK_POLICY_ALWAYS - GTK_POLICY_ALWAYS - GTK_SHADOW_IN - GTK_CORNER_TOP_LEFT - - - - True - True - False - False - False - False - True - False - False - - - - - True - False - - - - - - True - True - GTK_POLICY_ALWAYS - GTK_POLICY_ALWAYS - GTK_SHADOW_IN - GTK_CORNER_TOP_LEFT - - - - True - True - False - False - False - False - True - False - False - - - - - True - True - - + SP +HL +IX +IY +BC +DE + False + True + - True - False + 0 + False + False - + True - True - GTK_POLICY_ALWAYS - GTK_POLICY_ALWAYS - GTK_SHADOW_IN - GTK_CORNER_TOP_LEFT - - - - 1 - True - True - False - False - True - GTK_JUSTIFY_LEFT - GTK_WRAP_CHAR - False - 0 - 0 - 0 - 0 - 0 - 0 - - - + <b>Memory View</b> + False + True + GTK_JUSTIFY_LEFT + False + False + 0 + 0 + 0 + 0 + PANGO_ELLIPSIZE_NONE + -1 + False + 0 - True - True + 0 + False + True @@ -154,93 +158,163 @@ - + True - GTK_BUTTONBOX_START - 10 + True + GTK_POLICY_ALWAYS + GTK_POLICY_ALWAYS + GTK_SHADOW_IN + GTK_CORNER_TOP_LEFT - + True - True True - Run - True - GTK_RELIEF_NORMAL - True + False + False + True + GTK_JUSTIFY_LEFT + GTK_WRAP_CHAR + False + 0 + 0 + 0 + 0 + 0 + 0 + + + + 0 + True + True + + + + + 0 + True + True + + - - - True - True - True - Step - True - GTK_RELIEF_NORMAL - True - - + + + 4 + True + GTK_BUTTONBOX_SPREAD + 0 - - - True - True - True - Step Over - True - GTK_RELIEF_NORMAL - True - - + + + True + True + True + Run + True + GTK_RELIEF_NORMAL + True + + + - - - True - True - True - Stop - True - GTK_RELIEF_NORMAL - True - - + + + True + True + True + Step + True + GTK_RELIEF_NORMAL + True + + + - - - True - True - True - Load HEX - True - GTK_RELIEF_NORMAL - True - - + + + True + True + True + Step Over + True + GTK_RELIEF_NORMAL + True + + + - - - True - True - True - Quit - True - GTK_RELIEF_NORMAL - True - - + + + True + False + True + True + Stop + True + GTK_RELIEF_NORMAL + True + + + + + + + True + True + True + Load HEX + True + GTK_RELIEF_NORMAL + True + + + + + + + True + True + True + Load Labels + True + GTK_RELIEF_NORMAL + True + + + + + + + True + True + True + Run Until + True + GTK_RELIEF_NORMAL + True + + + + + + + True + True + True + Quit + True + GTK_RELIEF_NORMAL + True + - - 7 - False - True - 0 - True + False True diff --git a/gemma.h b/gemma.h new file mode 100644 index 0000000..c7ccc1d --- /dev/null +++ b/gemma.h @@ -0,0 +1,56 @@ +/* + + GEMMA - Z80 testbed + + Copyright (C) 2006 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 + + ------------------------------------------------------------------------- + + $Id$ + +*/ + +#ifndef GEMMA_H +#define GEMMA_H "$Id$" + +#include +#include "z80.h" + +typedef enum +{ + UPDATE_ASSEM_VIEW=0x01, + UPDATE_REG_VIEW=0x02, + UPDATE_MEM_VIEW=0x04, + UPDATE_ALL_VIEWS=UPDATE_ASSEM_VIEW|UPDATE_REG_VIEW|UPDATE_MEM_VIEW +} GEMMA_View; + +void GEMMA_Init(GtkWidget *top); +void GEMMA_LoadHEX(const char *path); +void GEMMA_LoadLabels(const char *path); +void GEMMA_UpdateDisplay(GEMMA_View view); +void GEMMA_Step(void); +void GEMMA_StepOver(void); +void GEMMA_Run(void); +void GEMMA_RunUntil(const char *expr); +void GEMMA_Stop(void); +void GEMMA_Interrupt(int nmi); + +#endif + +/* END OF FILE */ + + diff --git a/gtkutil.c b/gtkutil.c index da08e1b..b5ec30c 100644 --- a/gtkutil.c +++ b/gtkutil.c @@ -49,7 +49,7 @@ static int selected=FALSE; static char saved_path[PATH_MAX+1]; -/* ---------------------------------------- CALLBACKS +/* ---------------------------------------- PRIVATE FUNCTIONS */ static void Callback(GtkWidget *w, gpointer data) { @@ -85,7 +85,7 @@ static void FselCallback(GtkWidget *w, gpointer data) } -/* ---------------------------------------- DialogParent() +/* ---------------------------------------- EXPORTED FUNCTIONS */ void DialogParent(GtkWidget *w) { @@ -93,8 +93,6 @@ void DialogParent(GtkWidget *w) } -/* ---------------------------------------- DialogOK() -*/ void DialogOK(const char *format, ...) { va_list va; @@ -133,8 +131,6 @@ void DialogOK(const char *format, ...) } -/* ---------------------------------------- DialogYesNo() -*/ int DialogYesNo(const char *format, ...) { va_list va; @@ -194,8 +190,6 @@ int DialogYesNo(const char *format, ...) } -/* ---------------------------------------- DialogFSelect() -*/ int DialogFSelect(const char *title, char path[]) { dialog=gtk_file_selection_new(title); @@ -236,4 +230,15 @@ int DialogFSelect(const char *title, char path[]) } +void AppendText(GtkWidget *w, const char *text) +{ + GtkTextBuffer *buff; + GtkTextIter end; + + buff=gtk_text_view_get_buffer(GTK_TEXT_VIEW(w)); + gtk_text_buffer_get_end_iter(buff,&end); + gtk_text_buffer_insert(buff,&end,text,-1); +} + + /* END OF FILE */ diff --git a/gtkutil.h b/gtkutil.h index 0385a5e..46717d2 100644 --- a/gtkutil.h +++ b/gtkutil.h @@ -55,6 +55,10 @@ int DialogYesNo(const char *format, ...); */ int DialogFSelect(const char *title, char path[]); +/* Append text to a text view +*/ +void AppendText(GtkWidget *w, const char *text); + #endif diff --git a/main.c b/main.c index f4f66a4..f39e133 100644 --- a/main.c +++ b/main.c @@ -33,17 +33,31 @@ static const char ident[]="$Id$"; #include "interface.h" #include "support.h" +#include "gtkutil.h" +#include "gemma.h" + int main (int argc, char *argv[]) { - GtkWidget *top_window; + GtkWidget *top_window; + + gtk_set_locale (); + gtk_init (&argc, &argv); + + top_window = create_top_window (); + gtk_widget_show (top_window); - gtk_set_locale (); - gtk_init (&argc, &argv); + DialogParent(top_window); + GEMMA_Init(top_window); + GEMMA_UpdateDisplay(UPDATE_ALL_VIEWS); - top_window = create_top_window (); - gtk_widget_show (top_window); + AppendText(lookup_widget(top_window,"log_view"), + "GEMMA, Copyright (C) 2006 Ian Cowburn\n" + "GEMMA comes with ABSOLUTELY NO WARRANTY\n" + "This is free software, and you are welcome\n" + "to redistribute it under certain conditions;\n" + "See the GNU General Public License for details.\n"); - gtk_main (); - return 0; + gtk_main (); + return 0; } diff --git a/z80.c b/z80.c index cd2371a..a974c40 100644 --- a/z80.c +++ b/z80.c @@ -179,6 +179,12 @@ void Z80Reset(Z80 *cpu) } +void Z80SetPC(Z80 *cpu,Z80Word PC) +{ + cpu->PC=PC; +} + + void Z80ResetCycles(Z80 *cpu, Z80Val cycles) { cpu->cycle=cycles; diff --git a/z80.h b/z80.h index 3b3220e..5ac28b7 100644 --- a/z80.h +++ b/z80.h @@ -174,6 +174,11 @@ Z80 *Z80Init(Z80Memory memory, void Z80Reset(Z80 *cpu); +/* Sets the PC +*/ +void Z80SetPC(Z80 *cpu, Z80Word PC); + + /* Sets the cycle count to the specified count */ void Z80ResetCycles(Z80 *cpu, Z80Val cycles); -- cgit v1.2.3