summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan C <ianc@noddybox.co.uk>2006-09-20 00:02:42 +0000
committerIan C <ianc@noddybox.co.uk>2006-09-20 00:02:42 +0000
commit1f7e9c076768e6dc4aa0e5aef0a120a9a234c00b (patch)
treea032b026f0451870e42e2978e377896d45510f80
parent6bbeddada8aceec51f76a727448d88467ef6b037 (diff)
Changed Z80 core and fixed raising of interrupt on R register.
-rw-r--r--src/Makefile4
-rw-r--r--src/memmenu.c141
-rw-r--r--src/z80.c162
-rw-r--r--src/z80.h103
-rw-r--r--src/z80_decode.c81
-rw-r--r--src/z80_dis.c8
-rw-r--r--src/z80_private.h60
-rw-r--r--src/zx81.c71
8 files changed, 267 insertions, 363 deletions
diff --git a/src/Makefile b/src/Makefile
index 5ff98c5..5103ab6 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -18,7 +18,7 @@
#
# -------------------------------------------------------------------------
#
-# $Id: Makefile,v 1.11 2006-09-16 22:54:59 ianc Exp $
+# $Id: Makefile,v 1.12 2006-09-20 00:02:42 ianc Exp $
#
@@ -212,7 +212,7 @@ memmenu.o: /usr/local/include/SDL11/SDL_mouse.h
memmenu.o: /usr/local/include/SDL11/SDL_video.h
memmenu.o: /usr/local/include/SDL11/SDL_mutex.h
memmenu.o: /usr/local/include/SDL11/SDL_quit.h
-memmenu.o: /usr/local/include/SDL11/SDL_version.h gfx.h gui.h util.h
+memmenu.o: /usr/local/include/SDL11/SDL_version.h gfx.h gui.h expr.h util.h
util.o: /usr/include/stdio.h /usr/include/sys/cdefs.h
util.o: /usr/include/sys/_null.h /usr/include/sys/_types.h
util.o: /usr/include/machine/_types.h /usr/include/string.h
diff --git a/src/memmenu.c b/src/memmenu.c
index 02eeabd..e7909a9 100644
--- a/src/memmenu.c
+++ b/src/memmenu.c
@@ -82,7 +82,8 @@ typedef struct
typedef struct
{
- Z80State s;
+ Z80 s;
+ Z80Val c;
MemTrace hl[TRACEMEM_WIN];
MemTrace de[TRACEMEM_WIN];
MemTrace sp[TRACEMEM_WIN];
@@ -138,75 +139,75 @@ static int Address(Z80 *z80, const char *p, Z80Word *addr)
static int Expand(void *client, const char *p, long *res)
{
- Z80State s;
+ Z80 *cpu;
int ok=TRUE;
- Z80GetState(client,&s);
+ cpu=client;
if (StrEq(p,"AF"))
- *res=s.AF;
+ *res=cpu->AF.w;
else if (StrEq(p,"BC"))
- *res=s.BC;
+ *res=cpu->BC.w;
else if (StrEq(p,"DE"))
- *res=s.DE;
+ *res=cpu->DE.w;
else if (StrEq(p,"HL"))
- *res=s.HL;
+ *res=cpu->HL.w;
else if (StrEq(p,"IX"))
- *res=s.IX;
+ *res=cpu->IX.w;
else if (StrEq(p,"IY"))
- *res=s.IY;
+ *res=cpu->IY.w;
else if (StrEq(p,"SP"))
- *res=s.SP;
+ *res=cpu->SP;
else if (StrEq(p,"PC"))
- *res=s.PC;
+ *res=cpu->PC;
else if (StrEq(p,"A"))
- *res=HI(s.AF);
+ *res=HI(cpu->AF.w);
else if (StrEq(p,"F"))
- *res=LO(s.AF);
+ *res=LO(cpu->AF.w);
else if (StrEq(p,"B"))
- *res=HI(s.BC);
+ *res=HI(cpu->BC.w);
else if (StrEq(p,"C"))
- *res=LO(s.BC);
+ *res=LO(cpu->BC.w);
else if (StrEq(p,"D"))
- *res=HI(s.DE);
+ *res=HI(cpu->DE.w);
else if (StrEq(p,"E"))
- *res=LO(s.DE);
+ *res=LO(cpu->DE.w);
else if (StrEq(p,"H"))
- *res=HI(s.HL);
+ *res=HI(cpu->HL.w);
else if (StrEq(p,"L"))
- *res=LO(s.HL);
+ *res=LO(cpu->HL.w);
else if (StrEq(p,"AF_"))
- *res=s.AF_;
+ *res=cpu->AF_;
else if (StrEq(p,"BC_"))
- *res=s.BC_;
+ *res=cpu->BC_;
else if (StrEq(p,"DE_"))
- *res=s.DE_;
+ *res=cpu->DE_;
else if (StrEq(p,"HL_"))
- *res=s.HL_;
+ *res=cpu->HL_;
else if (StrEq(p,"A_"))
- *res=HI(s.AF_);
+ *res=HI(cpu->AF_);
else if (StrEq(p,"F_"))
- *res=LO(s.AF_);
+ *res=LO(cpu->AF_);
else if (StrEq(p,"B_"))
- *res=HI(s.BC_);
+ *res=HI(cpu->BC_);
else if (StrEq(p,"C_"))
- *res=LO(s.BC_);
+ *res=LO(cpu->BC_);
else if (StrEq(p,"D_"))
- *res=HI(s.DE_);
+ *res=HI(cpu->DE_);
else if (StrEq(p,"E_"))
- *res=LO(s.DE_);
+ *res=LO(cpu->DE_);
else if (StrEq(p,"H_"))
- *res=HI(s.HL_);
+ *res=HI(cpu->HL_);
else if (StrEq(p,"L_"))
- *res=LO(s.HL_);
+ *res=LO(cpu->HL_);
else if (StrEq(p,"IM"))
- *res=s.IM;
+ *res=cpu->IM;
else if (StrEq(p,"R"))
- *res=s.R;
+ *res=cpu->R;
else if (StrEq(p,"IFF1"))
- *res=s.IFF1;
+ *res=cpu->IFF1;
else if (StrEq(p,"IFF2"))
- *res=s.IFF2;
+ *res=cpu->IFF2;
else if (p[0]=='@')
{
Z80Word n;
@@ -322,19 +323,19 @@ static const char *FlagString(Z80Byte flag)
}
-int DisplayZ80State(Z80State *s, int y, Uint32 col)
+int DisplayZ80State(Z80 *s, Z80Val cycle, int y, Uint32 col)
{
GFXPrintPaper(0,y,col,BLACK,
"PC=%4.4x A=%2.2x F=%s",
- s->PC,s->AF>>8,FlagString(s->AF&0xff));
+ s->PC,s->AF.w>>8,FlagString(s->AF.w&0xff));
y+=8;
GFXPrintPaper(0,y,col,BLACK,
"BC=%4.4x DE=%4.4x HL=%4.4x",
- s->BC,s->DE,s->HL);
+ s->BC.w,s->DE.w,s->HL.w);
y+=8;
GFXPrintPaper(0,y,col,BLACK,
"IX=%4.4x IY=%4.4x SP=%4.4x",
- s->IX,s->IY,s->SP);
+ s->IX.w,s->IY.w,s->SP);
y+=8;
GFXPrintPaper(0,y,col,BLACK,
"AF'=%4.4x BC'=%4.4x DE'=%4.4x HL'=%4.4x",
@@ -346,7 +347,7 @@ int DisplayZ80State(Z80State *s, int y, Uint32 col)
y+=8;
GFXPrintPaper(0,y,col,BLACK,
"IFF1=%2.2x IFF2=%2.2x CY=%8.8lx",
- s->IFF1,s->IFF2,s->cycle);
+ s->IFF1,s->IFF2,cycle);
return y+8;
}
@@ -387,10 +388,10 @@ static void EnterLong(const char *prompt, long *l)
}
-static void DoDisassem(Z80 *z80, const Z80State *s)
+static void DoDisassem(Z80 *z80)
{
static int hexmode=FALSE;
- Z80Word pc=s->PC;
+ Z80Word pc=z80->PC;
int quit=FALSE;
while(!quit)
@@ -524,7 +525,7 @@ static void DoDisassem(Z80 *z80, const Z80State *s)
}
-static void DoDisassemFile(Z80 *z80, const Z80State *s)
+static void DoDisassemFile(Z80 *z80)
{
static char fname[FILENAME_MAX]="";
FILE *fp;
@@ -594,10 +595,11 @@ static int Instruction(Z80 *z80, Z80Val data)
{
Trace t;
- Z80GetState(z80,&t.s);
+ t.s=*z80;
+ t.c=Z80Cycles(z80);
- GetMemTrace(z80,t.hl,t.s.HL-(TRACEMEM_WIN/2+1),TRACEMEM_WIN);
- GetMemTrace(z80,t.de,t.s.DE-(TRACEMEM_WIN/2+1),TRACEMEM_WIN);
+ GetMemTrace(z80,t.hl,t.s.HL.w-(TRACEMEM_WIN/2+1),TRACEMEM_WIN);
+ GetMemTrace(z80,t.de,t.s.DE.w-(TRACEMEM_WIN/2+1),TRACEMEM_WIN);
GetMemTrace(z80,t.sp,t.s.SP-(TRACEMEM_WIN/2+1),TRACEMEM_WIN);
fwrite(&t,sizeof t,1,trace);
@@ -619,7 +621,7 @@ static int Instruction(Z80 *z80, Z80Val data)
}
-static void EnableTrace(Z80 *z80, Z80State *s)
+static void EnableTrace(Z80 *z80)
{
if (!trace)
{
@@ -723,11 +725,11 @@ static void PlaybackTrace(Z80 *z80)
if (showmem)
{
DisplayTraceMem(0,136,"MEM (SP)",t.sp,t.s.SP);
- DisplayTraceMem(100,136,"MEM (HL)",t.hl,t.s.HL);
- DisplayTraceMem(200,136,"MEM (DE)",t.de,t.s.DE);
+ DisplayTraceMem(100,136,"MEM (HL)",t.hl,t.s.HL.w);
+ DisplayTraceMem(200,136,"MEM (DE)",t.de,t.s.DE.w);
}
else
- DisplayZ80State(&t.s,136,WHITE);
+ DisplayZ80State(&t.s,t.c,136,WHITE);
for(f=0;f<10;f++)
{
@@ -971,10 +973,10 @@ static void DoMonitor(Z80 *z80)
while(!quit)
{
+ Z80Word pc;
MemTrace mt[TRACEMEM_WIN];
const char *brk;
SDL_Event *e;
- Z80State s;
int f;
step=FALSE;
@@ -984,25 +986,25 @@ static void DoMonitor(Z80 *z80)
CentrePaper("MONITOR",0,WHITE,BLACK);
CentrePaper("Press F1 for help",9,RED,BLACK);
- Z80GetState(z80,&s);
-
if (showmem)
{
- GetMemTrace(z80,mt,s.SP-(TRACEMEM_WIN/2+1),TRACEMEM_WIN);
- DisplayTraceMem(0,136,"MEM (SP)",mt,s.SP);
- GetMemTrace(z80,mt,s.HL-(TRACEMEM_WIN/2+1),TRACEMEM_WIN);
- DisplayTraceMem(100,136,"MEM (HL)",mt,s.HL);
- GetMemTrace(z80,mt,s.DE-(TRACEMEM_WIN/2+1),TRACEMEM_WIN);
- DisplayTraceMem(200,136,"MEM (DE)",mt,s.DE);
+ GetMemTrace(z80,mt,z80->SP-(TRACEMEM_WIN/2+1),TRACEMEM_WIN);
+ DisplayTraceMem(0,136,"MEM (SP)",mt,z80->SP);
+ GetMemTrace(z80,mt,z80->HL.w-(TRACEMEM_WIN/2+1),TRACEMEM_WIN);
+ DisplayTraceMem(100,136,"MEM (HL)",mt,z80->HL.w);
+ GetMemTrace(z80,mt,z80->DE.w-(TRACEMEM_WIN/2+1),TRACEMEM_WIN);
+ DisplayTraceMem(200,136,"MEM (DE)",mt,z80->DE.w);
}
else
{
int y;
- y=DisplayZ80State(&s,136,WHITE);
+ y=DisplayZ80State(z80,Z80Cycles(z80),136,WHITE);
GFXPrint(0,y,GREEN,"%s",ZX81Info(z80));
}
+ pc=z80->PC;
+
for(f=0;f<10;f++)
{
char str[80];
@@ -1017,9 +1019,9 @@ static void DoMonitor(Z80 *z80)
else
paper=BLACK;
- GFXPrintPaper(0,y,GREEN,paper,"%4.4x ",s.PC);
+ GFXPrintPaper(0,y,GREEN,paper,"%4.4x ",pc);
- strcpy(str,Z80Disassemble(z80,&s.PC));
+ strcpy(str,Z80Disassemble(z80,&pc));
p=strtok(str,";");
GFXPrintPaper(40,y,WHITE,paper,"%s",str);
}
@@ -1117,11 +1119,8 @@ int MemoryMenu(Z80 *z80)
SDL_Event *e;
int done=FALSE;
int quit=FALSE;
- Z80State s;
int y;
- Z80GetState(z80,&s);
-
GFXKeyRepeat(TRUE);
while(!done)
@@ -1134,16 +1133,16 @@ int MemoryMenu(Z80 *z80)
switch(e->key.keysym.sym)
{
case SDLK_1:
- DoDisassem(z80,&s);
+ DoDisassem(z80);
break;
case SDLK_2:
- DoDisassemFile(z80,&s);
+ DoDisassemFile(z80);
break;
case SDLK_3:
if (!trace)
- EnableTrace(z80,&s);
+ EnableTrace(z80);
else
DisableTrace(z80);
break;
@@ -1190,7 +1189,7 @@ int MemoryMenu(Z80 *z80)
GFXClear(BLACK);
Centre("CURRENT STATE",0,WHITE);
Centre("Press a key",9,RED);
- y=DisplayZ80State(&s,20,WHITE);
+ y=DisplayZ80State(z80,Z80Cycles(z80),20,WHITE);
GFXPrint(0,y,GREEN,"%s",ZX81Info(z80));
GFXEndFrame(FALSE);
GFXWaitKey();
@@ -1214,11 +1213,9 @@ int MemoryMenu(Z80 *z80)
void DisplayState(Z80 *z80)
{
- Z80State s;
int y;
- Z80GetState(z80,&s);
- y=DisplayZ80State(&s,GFX_HEIGHT/2,RED);
+ y=DisplayZ80State(z80,Z80Cycles(z80),GFX_HEIGHT/2,RED);
GFXPrintPaper(0,y,GREEN,BLACK,"%s",ZX81Info(z80));
}
diff --git a/src/z80.c b/src/z80.c
index 3a15a22..be50494 100644
--- a/src/z80.c
+++ b/src/z80.c
@@ -55,28 +55,28 @@ static void Z80_CheckInterrupt(Z80 *cpu)
{
/* Check interrupts
*/
- if (cpu->raise)
+ if (PRIV->raise)
{
- if (cpu->nmi)
+ if (PRIV->nmi)
{
- if (cpu->halt)
+ if (PRIV->halt)
{
- cpu->halt=FALSE;
+ PRIV->halt=FALSE;
CALLBACK(eZ80_Halt,0);
cpu->PC++;
}
TSTATE(2);
cpu->IFF1=0;
- cpu->nmi=FALSE;
+ PRIV->nmi=FALSE;
PUSH(cpu->PC);
cpu->PC=0x66;
}
else if (cpu->IFF1)
{
- if (cpu->halt)
+ if (PRIV->halt)
{
- cpu->halt=FALSE;
+ PRIV->halt=FALSE;
CALLBACK(eZ80_Halt,0);
cpu->PC++;
}
@@ -88,7 +88,7 @@ static void Z80_CheckInterrupt(Z80 *cpu)
default:
case 0:
INC_R;
- Z80_Decode(cpu,cpu->devbyte);
+ Z80_Decode(cpu,PRIV->devbyte);
return;
break;
@@ -99,12 +99,12 @@ static void Z80_CheckInterrupt(Z80 *cpu)
case 2:
PUSH(cpu->PC);
- cpu->PC=(Z80Word)cpu->I*256+cpu->devbyte;
+ cpu->PC=(Z80Word)cpu->I*256+PRIV->devbyte;
break;
}
}
- cpu->raise=FALSE;
+ PRIV->raise=FALSE;
}
}
@@ -138,19 +138,29 @@ Z80 *Z80Init(Z80ReadMemory read_memory,
if (cpu)
{
+ cpu->priv=malloc(sizeof *cpu->priv);
+
+ if (cpu->priv)
+ {
#ifndef ENABLE_ARRAY_MEMORY
- cpu->mread=read_memory;
- cpu->mwrite=write_memory;
- cpu->disread=read_for_disassem;
+ PRIV->mread=read_memory;
+ PRIV->mwrite=write_memory;
+ PRIV->disread=read_for_disassem;
#endif
- cpu->pread=read_port;
- cpu->pwrite=write_port;
+ PRIV->pread=read_port;
+ PRIV->pwrite=write_port;
- for(f=0;f<eZ80_NO_CALLBACK;f++)
- for(r=0;r<MAX_PER_CALLBACK;r++)
- cpu->callback[f][r]=NULL;
+ for(f=0;f<eZ80_NO_CALLBACK;f++)
+ for(r=0;r<MAX_PER_CALLBACK;r++)
+ PRIV->callback[f][r]=NULL;
- Z80Reset(cpu);
+ Z80Reset(cpu);
+ }
+ else
+ {
+ free(cpu);
+ cpu=NULL;
+ }
}
return cpu;
@@ -159,7 +169,7 @@ Z80 *Z80Init(Z80ReadMemory read_memory,
void Z80Reset(Z80 *cpu)
{
- cpu->cycle=0;
+ PRIV->cycle=0;
cpu->PC=0;
cpu->AF.w=0xffff;
@@ -180,28 +190,22 @@ void Z80Reset(Z80 *cpu)
cpu->IM=0;
cpu->I=0;
cpu->R=0;
- cpu->halt=0;
+ PRIV->halt=0;
- cpu->raise=FALSE;
- cpu->nmi=FALSE;
+ PRIV->raise=FALSE;
+ PRIV->nmi=FALSE;
}
-void Z80SetPC(Z80 *cpu,Z80Word PC)
-{
- cpu->PC=PC;
-}
-
-
-Z80Word Z80GetPC(Z80 *cpu)
+Z80Val Z80Cycles(Z80 *cpu)
{
- return cpu->PC;
+ return PRIV->cycle;
}
void Z80ResetCycles(Z80 *cpu, Z80Val cycles)
{
- cpu->cycle=cycles;
+ PRIV->cycle=cycles;
}
@@ -211,9 +215,9 @@ int Z80LodgeCallback(Z80 *cpu, Z80CallbackReason reason, Z80Callback callback)
for(f=0;f<MAX_PER_CALLBACK;f++)
{
- if (!cpu->callback[reason][f])
+ if (!PRIV->callback[reason][f])
{
- cpu->callback[reason][f]=callback;
+ PRIV->callback[reason][f]=callback;
return TRUE;
}
}
@@ -227,23 +231,27 @@ void Z80RemoveCallback(Z80 *cpu, Z80CallbackReason reason, Z80Callback callback)
int f;
for(f=0;f<MAX_PER_CALLBACK;f++)
- if (cpu->callback[reason][f]==callback)
- cpu->callback[reason][f]=NULL;
+ {
+ if (PRIV->callback[reason][f]==callback)
+ {
+ PRIV->callback[reason][f]=NULL;
+ }
+ }
}
void Z80Interrupt(Z80 *cpu, Z80Byte devbyte)
{
- cpu->raise=TRUE;
- cpu->devbyte=devbyte;
- cpu->nmi=FALSE;
+ PRIV->raise=TRUE;
+ PRIV->devbyte=devbyte;
+ PRIV->nmi=FALSE;
}
void Z80NMI(Z80 *cpu)
{
- cpu->raise=TRUE;
- cpu->nmi=TRUE;
+ PRIV->raise=TRUE;
+ PRIV->nmi=TRUE;
}
@@ -251,12 +259,12 @@ int Z80SingleStep(Z80 *cpu)
{
Z80Byte opcode;
- cpu->last_cb=TRUE;
- cpu->shift=0;
+ PRIV->last_cb=TRUE;
+ PRIV->shift=0;
Z80_CheckInterrupt(cpu);
- CALLBACK(eZ80_Instruction,cpu->cycle);
+ CALLBACK(eZ80_Instruction,PRIV->cycle);
INC_R;
@@ -264,7 +272,7 @@ int Z80SingleStep(Z80 *cpu)
Z80_Decode(cpu,opcode);
- return cpu->last_cb;
+ return PRIV->last_cb;
}
@@ -274,68 +282,6 @@ void Z80Exec(Z80 *cpu)
}
-void Z80GetState(Z80 *cpu, Z80State *state)
-{
- state->cycle= cpu->cycle;
-
- state->AF = cpu->AF.w;
- state->BC = cpu->BC.w;
- state->DE = cpu->DE.w;
- state->HL = cpu->HL.w;
-
- state->AF_ = cpu->AF_;
- state->BC_ = cpu->BC_;
- state->DE_ = cpu->DE_;
- state->HL_ = cpu->HL_;
-
- state->IX = cpu->IX.w;
- state->IY = cpu->IY.w;
-
- state->SP = cpu->SP;
- state->PC = cpu->PC;
-
- state->IFF1 = cpu->IFF1;
- state->IFF2 = cpu->IFF2;
- state->IM = cpu->IM;
- state->I = cpu->I;
- state->R = cpu->R;
-}
-
-
-void Z80SetState(Z80 *cpu, const Z80State *state)
-{
- cpu->cycle = state->cycle;
-
- cpu->AF.w = state->AF;
- cpu->BC.w = state->BC;
- cpu->DE.w = state->DE;
- cpu->HL.w = state->HL;
-
- cpu->AF_ = state->AF_;
- cpu->BC_ = state->BC_;
- cpu->DE_ = state->DE_;
- cpu->HL_ = state->HL_;
-
- cpu->IX.w = state->IX;
- cpu->IY.w = state->IY;
-
- cpu->SP = state->SP;
- cpu->PC = state->PC;
-
- cpu->IFF1 = state->IFF1;
- cpu->IFF2 = state->IFF2;
- cpu->IM = state->IM;
- cpu->I = state->I;
- cpu->R = state->R;
-}
-
-
-Z80Val Z80Cycles(Z80 *cpu)
-{
- return cpu->cycle;
-}
-
-
void Z80SetLabels(Z80Label labels[])
{
z80_labels=labels;
@@ -364,7 +310,7 @@ const char *Z80Disassemble(Z80 *cpu, Z80Word *pc)
#ifdef ENABLE_ARRAY_MEMORY
strcat(s,Z80_Dis_Printf(" %.2x",(int)Z80_MEMORY[opc++]));
#else
- strcat(s,Z80_Dis_Printf(" %.2x",(int)cpu->disread(cpu,opc++)));
+ strcat(s,Z80_Dis_Printf(" %.2x",(int)PRIV->disread(cpu,opc++)));
#endif
}
diff --git a/src/z80.h b/src/z80.h
index f6bc041..000b950 100644
--- a/src/z80.h
+++ b/src/z80.h
@@ -35,12 +35,6 @@
/* ---------------------------------------- TYPES
*/
-/* The processor
-*/
-struct Z80;
-typedef struct Z80 Z80;
-
-
/* Large unsigned type
*/
typedef unsigned long Z80Val;
@@ -61,6 +55,53 @@ typedef signed char Z80Relative;
typedef unsigned short Z80Word;
+/* A Z80 16-bit register. To access the HI/LO component use the indexes
+ Z80_HI_WORD and Z80_LO_WORD which will be initialised once Z80Init has been
+ called.
+*/
+typedef union
+{
+ Z80Word w;
+ Z80Byte b[2];
+} Z80Reg;
+
+extern int Z80_HI_WORD;
+extern int Z80_LO_WORD;
+
+
+/* The processor
+*/
+struct Z80Private;
+
+typedef struct
+{
+ Z80Word PC;
+
+ Z80Reg AF;
+ Z80Reg BC;
+ Z80Reg DE;
+ Z80Reg HL;
+
+ Z80Word AF_;
+ Z80Word BC_;
+ Z80Word DE_;
+ Z80Word HL_;
+
+ Z80Reg IX;
+ Z80Reg IY;
+
+ Z80Word SP;
+
+ Z80Byte IFF1;
+ Z80Byte IFF2;
+ Z80Byte IM;
+ Z80Byte I;
+ Z80Byte R;
+
+ struct Z80Private *priv;
+} Z80;
+
+
/* Interfaces used to handle memory
*/
typedef Z80Byte (*Z80ReadMemory)(Z80 *cpu, Z80Word address);
@@ -100,36 +141,6 @@ typedef enum
} Z80CallbackReason;
-/* Get/settable state of the Z80
-*/
-typedef struct
-{
- Z80Word PC;
- Z80Word SP;
-
- Z80Val cycle;
-
- Z80Word AF;
- Z80Word BC;
- Z80Word DE;
- Z80Word HL;
-
- Z80Word AF_; /* Alternate registers */
- Z80Word BC_;
- Z80Word DE_;
- Z80Word HL_;
-
- Z80Word IX;
- Z80Word IY;
-
- Z80Byte IFF1;
- Z80Byte IFF2;
- Z80Byte IM;
- Z80Byte I;
- Z80Byte R;
-} Z80State;
-
-
/* Flags in the F register
*/
typedef enum
@@ -179,21 +190,6 @@ Z80 *Z80Init(Z80ReadMemory read_memory,
void Z80Reset(Z80 *cpu);
-/* Sets the PC
-*/
-void Z80SetPC(Z80 *cpu, Z80Word PC);
-
-
-/* Gets the PC
-*/
-Z80Word Z80GetPC(Z80 *cpu);
-
-
-/* Sets the cycle count to the specified count
-*/
-void Z80ResetCycles(Z80 *cpu, Z80Val cycles);
-
-
/* Lodge a callback to be invoked after special events. Returns FALSE
if the callback couldn't be lodged (there is a max of 10 callbacks per
reason).
@@ -233,11 +229,10 @@ int Z80SingleStep(Z80 *cpu);
void Z80Exec(Z80 *cpu);
-/* Interrogate the state of the Z80
+/* Manipulate the cylce count of the Z80
*/
Z80Val Z80Cycles(Z80 *cpu);
-void Z80GetState(Z80 *cpu, Z80State *state);
-void Z80SetState(Z80 *cpu, const Z80State *state);
+void Z80ResetCycles(Z80 *cpu, Z80Val cycles);
/* Set address to label mappings for the disassembler
diff --git a/src/z80_decode.c b/src/z80_decode.c
index c134b7b..a8f66ca 100644
--- a/src/z80_decode.c
+++ b/src/z80_decode.c
@@ -40,8 +40,11 @@ static Z80Byte Stable[512];
static Z80Byte Ztable[512];
-static int HI;
-static int LO;
+int Z80_HI_WORD;
+int Z80_LO_WORD;
+
+#define HI Z80_HI_WORD
+#define LO Z80_LO_WORD
/* ---------------------------------------- MISC FUNCTIONS
*/
@@ -127,8 +130,8 @@ static Z80Word FPEEKW(Z80 *cpu, Z80Word addr)
static void FPOKEW(Z80 *cpu, Z80Word addr, Z80Word val)
{
- cpu->mwrite(cpu,addr,val);
- cpu->mwrite(cpu,addr+1,val>>8);
+ PRIV->mwrite(cpu,addr,val);
+ PRIV->mwrite(cpu,addr+1,val>>8);
}
#endif
@@ -1020,9 +1023,9 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode)
case 0x40: /* IN B,(C) */
TSTATE(12);
- if (cpu->pread)
+ if (PRIV->pread)
{
- cpu->BC.b[HI]=cpu->pread(cpu,cpu->BC.w);
+ cpu->BC.b[HI]=PRIV->pread(cpu,cpu->BC.w);
}
else
{
@@ -1035,7 +1038,7 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode)
case 0x41: /* OUT (C),B */
TSTATE(12);
- if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->BC.b[HI]);
+ if (PRIV->pwrite) PRIV->pwrite(cpu,cpu->BC.w,cpu->BC.b[HI]);
break;
case 0x42: /* SBC HL,BC */
@@ -1079,9 +1082,9 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode)
case 0x48: /* IN C,(C) */
TSTATE(12);
- if (cpu->pread)
+ if (PRIV->pread)
{
- cpu->BC.b[LO]=cpu->pread(cpu,cpu->BC.w);
+ cpu->BC.b[LO]=PRIV->pread(cpu,cpu->BC.w);
}
else
{
@@ -1094,7 +1097,7 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode)
case 0x49: /* OUT (C),C */
TSTATE(12);
- if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->BC.b[LO]);
+ if (PRIV->pwrite) PRIV->pwrite(cpu,cpu->BC.w,cpu->BC.b[LO]);
break;
case 0x4a: /* ADC HL,BC */
@@ -1139,9 +1142,9 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode)
case 0x50: /* IN D,(C) */
TSTATE(12);
- if (cpu->pread)
+ if (PRIV->pread)
{
- cpu->DE.b[HI]=cpu->pread(cpu,cpu->BC.w);
+ cpu->DE.b[HI]=PRIV->pread(cpu,cpu->BC.w);
}
else
{
@@ -1154,7 +1157,7 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode)
case 0x51: /* OUT (C),D */
TSTATE(12);
- if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->DE.b[HI]);
+ if (PRIV->pwrite) PRIV->pwrite(cpu,cpu->BC.w,cpu->DE.b[HI]);
break;
case 0x52: /* SBC HL,DE */
@@ -1198,9 +1201,9 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode)
case 0x58: /* IN E,(C) */
TSTATE(12);
- if (cpu->pread)
+ if (PRIV->pread)
{
- cpu->DE.b[LO]=cpu->pread(cpu,cpu->BC.w);
+ cpu->DE.b[LO]=PRIV->pread(cpu,cpu->BC.w);
}
else
{
@@ -1213,7 +1216,7 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode)
case 0x59: /* OUT (C),E */
TSTATE(12);
- if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->DE.b[LO]);
+ if (PRIV->pwrite) PRIV->pwrite(cpu,cpu->BC.w,cpu->DE.b[LO]);
break;
case 0x5a: /* ADC HL,DE */
@@ -1257,9 +1260,9 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode)
case 0x60: /* IN H,(C) */
TSTATE(12);
- if (cpu->pread)
+ if (PRIV->pread)
{
- cpu->HL.b[HI]=cpu->pread(cpu,cpu->BC.w);
+ cpu->HL.b[HI]=PRIV->pread(cpu,cpu->BC.w);
}
else
{
@@ -1272,7 +1275,7 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode)
case 0x61: /* OUT (C),H */
TSTATE(12);
- if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->HL.b[HI]);
+ if (PRIV->pwrite) PRIV->pwrite(cpu,cpu->BC.w,cpu->HL.b[HI]);
break;
case 0x62: /* SBC HL,HL */
@@ -1327,9 +1330,9 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode)
case 0x68: /* IN L,(C) */
TSTATE(12);
- if (cpu->pread)
+ if (PRIV->pread)
{
- cpu->HL.b[LO]=cpu->pread(cpu,cpu->BC.w);
+ cpu->HL.b[LO]=PRIV->pread(cpu,cpu->BC.w);
}
else
{
@@ -1342,7 +1345,7 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode)
case 0x69: /* OUT (C),L */
TSTATE(12);
- if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->HL.b[LO]);
+ if (PRIV->pwrite) PRIV->pwrite(cpu,cpu->BC.w,cpu->HL.b[LO]);
break;
case 0x6a: /* ADC HL,HL */
@@ -1400,9 +1403,9 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode)
TSTATE(12);
- if (cpu->pread)
+ if (PRIV->pread)
{
- b=cpu->pread(cpu,cpu->BC.w);
+ b=PRIV->pread(cpu,cpu->BC.w);
}
else
{
@@ -1416,7 +1419,7 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode)
case 0x71: /* OUT (C) */
TSTATE(12);
- if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,0);
+ if (PRIV->pwrite) PRIV->pwrite(cpu,cpu->BC.w,0);
break;
case 0x72: /* SBC HL,SP */
@@ -1460,9 +1463,9 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode)
case 0x78: /* IN A,(C) */
TSTATE(12);
- if (cpu->pread)
+ if (PRIV->pread)
{
- cpu->AF.b[HI]=cpu->pread(cpu,cpu->BC.w);
+ cpu->AF.b[HI]=PRIV->pread(cpu,cpu->BC.w);
}
else
{
@@ -1475,7 +1478,7 @@ static void DecodeED(Z80 *cpu, Z80Byte opcode)
case 0x79: /* OUT (C),A */
TSTATE(12);
- if (cpu->pwrite) cpu->pwrite(cpu,cpu->BC.w,cpu->AF.b[HI]);
+ if (PRIV->pwrite) PRIV->pwrite(cpu,cpu->BC.w,cpu->AF.b[HI]);
break;
case 0x7a: /* ADC HL,SP */
@@ -1697,7 +1700,7 @@ static void ShiftedDecodeCB(Z80 *cpu, Z80Byte opcode, Z80Relative offset)
/* See if we've come here from a IX/IY shift.
*/
- switch (cpu->shift)
+ switch (PRIV->shift)
{
case 0xdd:
addr=cpu->IX.w+offset;
@@ -1762,7 +1765,7 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode)
/* See if we've come here from a IX/IY shift
*/
- switch (cpu->shift)
+ switch (PRIV->shift)
{
case 0xdd:
HL=&(cpu->IX.w);
@@ -2168,10 +2171,10 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode)
TSTATE(4);
cpu->PC--;
- if (!cpu->halt)
+ if (!PRIV->halt)
CALLBACK(eZ80_Halt,1);
- cpu->halt=TRUE;
+ PRIV->halt=TRUE;
break;
case 0x77: /* LD (HL),A */
@@ -2244,7 +2247,7 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode)
/* Check for previous IX/IY shift.
*/
- if (cpu->shift!=0)
+ if (PRIV->shift!=0)
{
Z80Relative cb_offset;
@@ -2289,13 +2292,13 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode)
case 0xd3: /* OUT (n),A */
TSTATE(11);
- if (cpu->pwrite)
+ if (PRIV->pwrite)
{
Z80Word port;
port=FETCH_BYTE;
port|=(Z80Word)cpu->AF.b[HI]<<8;
- cpu->pwrite(cpu,port,cpu->AF.b[HI]);
+ PRIV->pwrite(cpu,port,cpu->AF.b[HI]);
}
else
cpu->PC++;
@@ -2336,13 +2339,13 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode)
case 0xdb: /* IN A,(n) */
TSTATE(11);
- if (cpu->pread)
+ if (PRIV->pread)
{
Z80Word port;
port=FETCH_BYTE;
port|=(Z80Word)cpu->AF.b[HI]<<8;
- cpu->AF.b[HI]=cpu->pread(cpu,port);
+ cpu->AF.b[HI]=PRIV->pread(cpu,port);
}
else
cpu->PC++;
@@ -2356,7 +2359,7 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode)
TSTATE(4);
INC_R;
- cpu->shift=opcode;
+ PRIV->shift=opcode;
Z80_Decode(cpu,FETCH_BYTE);
break;
@@ -2510,7 +2513,7 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode)
TSTATE(4);
INC_R;
- cpu->shift=opcode;
+ PRIV->shift=opcode;
Z80_Decode(cpu,FETCH_BYTE);
break;
diff --git a/src/z80_dis.c b/src/z80_dis.c
index 6204f0d..8a8ade8 100644
--- a/src/z80_dis.c
+++ b/src/z80_dis.c
@@ -67,7 +67,7 @@ Z80Byte Z80_Dis_FetchByte(Z80 *cpu, Z80Word *pc)
#ifdef ENABLE_ARRAY_MEMORY
return Z80_MEMORY[(*pc)++];
#else
- return cpu->disread(cpu,(*pc)++);
+ return cpu->priv->disread(cpu,(*pc)++);
#endif
}
@@ -1463,7 +1463,7 @@ static void DIS_DJNZ (Z80 *z80, Z80Byte op, Z80Word *pc)
#ifdef ENABLE_ARRAY_MEMORY
new=*pc+(Z80Relative)Z80_MEMORY[*pc]+1;
#else
- new=*pc+(Z80Relative)z80->disread(z80,*pc)+1;
+ new=*pc+(Z80Relative)z80->priv->disread(z80,*pc)+1;
#endif
(*pc)++;
Z80_Dis_Set("djnz",Z80_Dis_Printf("$%.4x",new));
@@ -1482,7 +1482,7 @@ static void DIS_JR (Z80 *z80, Z80Byte op, Z80Word *pc)
#ifdef ENABLE_ARRAY_MEMORY
new=*pc+(Z80Relative)Z80_MEMORY[*pc]+1;
#else
- new=*pc+(Z80Relative)z80->disread(z80,*pc)+1;
+ new=*pc+(Z80Relative)z80->priv->disread(z80,*pc)+1;
#endif
(*pc)++;
@@ -1507,7 +1507,7 @@ static void DIS_JR_CO (Z80 *z80, Z80Byte op, Z80Word *pc)
#ifdef ENABLE_ARRAY_MEMORY
new=*pc+(Z80Relative)Z80_MEMORY[*pc]+1;
#else
- new=*pc+(Z80Relative)z80->disread(z80,*pc)+1;
+ new=*pc+(Z80Relative)z80->priv->disread(z80,*pc)+1;
#endif
(*pc)++;
diff --git a/src/z80_private.h b/src/z80_private.h
index d031497..be45e56 100644
--- a/src/z80_private.h
+++ b/src/z80_private.h
@@ -45,40 +45,10 @@
/* ---------------------------------------- TYPES
*/
-typedef signed short sword;
-
-typedef union
-{
- Z80Word w;
- Z80Byte b[2];
-} Z80Reg;
-
-struct Z80
+struct Z80Private
{
Z80Val cycle;
- Z80Word PC;
-
- Z80Reg AF;
- Z80Reg BC;
- Z80Reg DE;
- Z80Reg HL;
-
- Z80Word AF_;
- Z80Word BC_;
- Z80Word DE_;
- Z80Word HL_;
-
- Z80Reg IX;
- Z80Reg IY;
-
- Z80Word SP;
-
- Z80Byte IFF1;
- Z80Byte IFF2;
- Z80Byte IM;
- Z80Byte I;
- Z80Byte R;
int halt;
Z80Byte shift;
@@ -102,6 +72,8 @@ struct Z80
int last_cb;
};
+#define PRIV cpu->priv
+
/* ---------------------------------------- ARRAY MEMORY
*/
@@ -126,9 +98,9 @@ extern Z80Byte Z80_MEMORY[];
int f; \
\
for(f=0;f<MAX_PER_CALLBACK;f++) \
- if (cpu->callback[r][f]) \
- cpu->last_cb &= \
- cpu->callback[r][f](cpu,d); \
+ if (PRIV->callback[r][f]) \
+ PRIV->last_cb &= \
+ PRIV->callback[r][f](cpu,d);\
} while(0)
/* Flag register
@@ -183,13 +155,13 @@ static inline Z80Word PEEKW(Z80Word addr)
#else
-#define PEEK(addr) (cpu->mread(cpu,addr))
+#define PEEK(addr) (PRIV->mread(cpu,addr))
#define PEEKW(addr) FPEEKW(cpu,addr)
-#define POKE(addr,val) cpu->mwrite(cpu,addr,val)
+#define POKE(addr,val) PRIV->mwrite(cpu,addr,val)
#define POKEW(addr,val) FPOKEW(cpu,addr,val)
-#define FETCH_BYTE (cpu->mread(cpu,cpu->PC++))
+#define FETCH_BYTE (PRIV->mread(cpu,cpu->PC++))
#define FETCH_WORD (cpu->PC+=2,FPEEKW(cpu,cpu->PC-2))
#endif
@@ -204,10 +176,10 @@ static inline Z80Word PEEKW(Z80Word addr)
#define CARRY IS_C
-#define IS_IX_IY (cpu->shift==0xdd || cpu->shift==0xfd)
+#define IS_IX_IY (PRIV->shift==0xdd || PRIV->shift==0xfd)
#define OFFSET(off) off=(IS_IX_IY ? (Z80Relative)FETCH_BYTE:0)
-#define TSTATE(n) cpu->cycle+=n
+#define TSTATE(n) PRIV->cycle+=n
#define ADD_R(v) cpu->R=((cpu->R&0x80)|((cpu->R+(v))&0x7f))
#define INC_R ADD_R(1)
@@ -228,8 +200,8 @@ static inline Z80Word PEEKW(Z80Word addr)
{ \
Z80Word pushv=REG; \
cpu->SP-=2; \
- cpu->mwrite(cpu,cpu->SP,pushv); \
- cpu->mwrite(cpu,cpu->SP+1,pushv>>8);\
+ PRIV->mwrite(cpu,cpu->SP,pushv); \
+ PRIV->mwrite(cpu,cpu->SP+1,pushv>>8);\
} while(0)
#endif
@@ -257,11 +229,11 @@ static inline Z80Word PEEKW(Z80Word addr)
#define OUT(P,V) do \
{ \
- if (cpu->pwrite) \
- cpu->pwrite(cpu,P,V); \
+ if (PRIV->pwrite) \
+ PRIV->pwrite(cpu,P,V); \
} while(0)
-#define IN(P) (cpu->pread?cpu->pread(cpu,P):0)
+#define IN(P) (PRIV->pread?PRIV->pread(cpu,P):0)
diff --git a/src/zx81.c b/src/zx81.c
index efaef52..35a6558 100644
--- a/src/zx81.c
+++ b/src/zx81.c
@@ -52,7 +52,7 @@ static const int ROMLEN=0x2000;
static const int ROM_SAVE=0x2fc;
static const int ROM_LOAD=0x347;
-static const Z80Val HSYNC_PERIOD=208;
+static const Z80Val NMI_PERIOD=208;
/* The ZX81 screen
*/
@@ -239,9 +239,9 @@ static const char *ConvertFilename(Z80Word addr)
}
-static void LoadTape(Z80State *state)
+static void LoadTape(Z80 *cpu)
{
- const char *p=ConvertFilename(state->DE);
+ const char *p=ConvertFilename(cpu->DE.w);
char path[FILENAME_MAX];
FILE *fp;
Z80Word addr;
@@ -278,9 +278,9 @@ static void LoadTape(Z80State *state)
}
-static void SaveTape(Z80State *state)
+static void SaveTape(Z80 *cpu)
{
- const char *p=ConvertFilename(state->DE);
+ const char *p=ConvertFilename(cpu->DE.w);
char path[FILENAME_MAX];
FILE *fp;
Z80Word start;
@@ -315,18 +315,14 @@ static void SaveTape(Z80State *state)
static int EDCallback(Z80 *z80, Z80Val data)
{
- Z80State state;
-
- Z80GetState(z80,&state);
-
switch((Z80Byte)data)
{
case 0xf0:
- SaveTape(&state);
+ SaveTape(z80);
break;
case 0xf1:
- LoadTape(&state);
+ LoadTape(z80);
break;
default:
@@ -339,7 +335,6 @@ static int EDCallback(Z80 *z80, Z80Val data)
static void ULA_Video_Shifter(Z80 *z80, Z80Byte val)
{
- Z80State state;
Z80Word base;
int x,y;
int inv;
@@ -348,8 +343,6 @@ static void ULA_Video_Shifter(Z80 *z80, Z80Byte val)
if (!scr_enable)
return;
- Z80GetState(z80,&state);
-
/* Extra check due to out dodgy ULA emulation
*/
if (ULA.y>=0 && ULA.y<SCR_H)
@@ -366,7 +359,7 @@ static void ULA_Video_Shifter(Z80 *z80, Z80Byte val)
inv=val&0x80;
val&=0x3f;
- base=((Z80Word)state.I<<8)|(val<<3)|ULA.c;
+ base=((Z80Word)z80->I<<8)|(val<<3)|ULA.c;
if (inv)
{
@@ -394,29 +387,27 @@ static void ULA_Video_Shifter(Z80 *z80, Z80Byte val)
static int CheckTimers(Z80 *z80, Z80Val val)
{
- if (val>HSYNC_PERIOD)
+ static Z80Byte last_R;
+
+ if (nmigen && val>NMI_PERIOD)
{
- Z80ResetCycles(z80,val-HSYNC_PERIOD);
+ Z80ResetCycles(z80,val-NMI_PERIOD);
- if (nmigen && hsync)
- {
- Z80NMI(z80);
- Debug("NMIGEN\n");
- }
- else if (hsync)
+ Z80NMI(z80);
+ /* Debug("NMI\n"); */
+ }
+
+ if (hsync)
+ {
+ if (last_R&0x40 && !(z80->R&0x40))
{
- Debug("HSYNC\n");
Z80Interrupt(z80,0xff);
- if (ULA.release)
- {
- /* ULA.release=FALSE; */
- ULA.c=(ULA.c+1)&7;
- ULA.y++;
- ULA.x=0;
- }
+ /* Debug("INTERRUPT\n"); */
}
}
+ last_R=z80->R;
+
return TRUE;
}
@@ -570,7 +561,7 @@ Z80Byte ZX81ReadPort(Z80 *z80, Z80Word port)
{
Z80Byte b=0;
- Debug("IN %4.4x\n",port);
+ /* Debug("IN %4.4x\n",port); */
switch(port&0xff)
{
@@ -609,13 +600,13 @@ Z80Byte ZX81ReadPort(Z80 *z80, Z80Word port)
*/
if (!vsync)
{
- Debug("VSYNC\n");
+ /* Debug("VSYNC\n"); */
GFXEndFrame(TRUE);
GFXClear(white);
ULA.x=0;
- ULA.y=-1;
+ ULA.y=0;
ULA.c=7;
ULA.release=FALSE;
@@ -634,7 +625,7 @@ Z80Byte ZX81ReadPort(Z80 *z80, Z80Word port)
*/
if (!nmigen)
{
- Debug("HSYNC OFF\n");
+ /* Debug("HSYNC OFF\n"); */
hsync=FALSE;
}
break;
@@ -649,7 +640,7 @@ Z80Byte ZX81ReadPort(Z80 *z80, Z80Word port)
void ZX81WritePort(Z80 *z80, Z80Word port, Z80Byte val)
{
- Debug("OUT %4.4x,%2.2X\n",port,val);
+ /* Debug("OUT %4.4x,%2.2X\n",port,val); */
/* Any port write releases the ULA line counter
*/
@@ -658,20 +649,20 @@ void ZX81WritePort(Z80 *z80, Z80Word port, Z80Byte val)
switch(port&0xff)
{
case 0xfd: /* NMI generator OFF */
- Debug("NMIGEN OFF\n");
+ /* Debug("NMIGEN OFF\n"); */
nmigen=FALSE;
break;
case 0xfe: /* NMI generator ON */
- Debug("NMIGEN ON/VSYNC OFF\n");
+ /* Debug("NMIGEN ON/VSYNC OFF\n"); */
nmigen=TRUE;
vsync=FALSE;
+ Z80ResetCycles(z80,0);
break;
case 0xff: /* HSYNC generator ON */
- Debug("HSYNC ON\n");
+ /* Debug("HSYNC ON\n"); */
hsync=TRUE;
- Z80ResetCycles(z80,0);
break;
}
}