summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan C <ianc@noddybox.co.uk>2006-09-16 22:54:59 +0000
committerIan C <ianc@noddybox.co.uk>2006-09-16 22:54:59 +0000
commitf76b8997620b8fb22f3b3c650c6fa9005b7d660b (patch)
treede3c279bff19a21affd395e086ad068853a264fe
parent7145eef7df3d346e816117b78d5cbd6e023611e1 (diff)
Added newer version of the Z80 core
-rw-r--r--src/Makefile19
-rw-r--r--src/z80.c28
-rw-r--r--src/z80.h14
-rw-r--r--src/z80_config.h59
-rw-r--r--src/z80_decode.c38
-rw-r--r--src/z80_dis.c18
-rw-r--r--src/z80_private.h72
7 files changed, 203 insertions, 45 deletions
diff --git a/src/Makefile b/src/Makefile
index 7335868..5ff98c5 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -18,7 +18,7 @@
#
# -------------------------------------------------------------------------
#
-# $Id: Makefile,v 1.10 2006-09-07 23:46:31 ianc Exp $
+# $Id: Makefile,v 1.11 2006-09-16 22:54:59 ianc Exp $
#
@@ -56,7 +56,7 @@ OBJECTS = main.o \
z80_decode.o \
z80_dis.o
-CFLAGS += `sdl-config --cflags` -DENABLE_DISASSEM
+CFLAGS += `sdl-config --cflags`
LIBS = `sdl-config --libs`
@@ -100,13 +100,14 @@ main.o: /usr/local/include/SDL11/SDL_mouse.h
main.o: /usr/local/include/SDL11/SDL_video.h
main.o: /usr/local/include/SDL11/SDL_mutex.h
main.o: /usr/local/include/SDL11/SDL_quit.h
-main.o: /usr/local/include/SDL11/SDL_version.h z80.h zx81.h gfx.h gui.h
-main.o: memmenu.h config.h exit.h
+main.o: /usr/local/include/SDL11/SDL_version.h z80.h z80_config.h zx81.h
+main.o: gfx.h gui.h memmenu.h config.h exit.h
zx81.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h
zx81.o: /usr/include/sys/_null.h /usr/include/sys/_types.h
zx81.o: /usr/include/machine/_types.h /usr/include/stdio.h
zx81.o: /usr/include/string.h /usr/include/strings.h zx81.h z80.h
-zx81.o: /usr/local/include/SDL11/SDL.h /usr/local/include/SDL11/SDL_main.h
+zx81.o: z80_config.h /usr/local/include/SDL11/SDL.h
+zx81.o: /usr/local/include/SDL11/SDL_main.h
zx81.o: /usr/local/include/SDL11/SDL_types.h
zx81.o: /usr/local/include/SDL11/SDL_getenv.h
zx81.o: /usr/local/include/SDL11/SDL_error.h
@@ -190,7 +191,7 @@ memmenu.o: /usr/include/sys/_null.h /usr/include/sys/_types.h
memmenu.o: /usr/include/machine/_types.h /usr/include/stdio.h
memmenu.o: /usr/include/string.h /usr/include/strings.h /usr/include/ctype.h
memmenu.o: /usr/include/_ctype.h /usr/include/runetype.h memmenu.h z80.h
-memmenu.o: zx81.h /usr/local/include/SDL11/SDL.h
+memmenu.o: z80_config.h zx81.h /usr/local/include/SDL11/SDL.h
memmenu.o: /usr/local/include/SDL11/SDL_main.h
memmenu.o: /usr/local/include/SDL11/SDL_types.h
memmenu.o: /usr/local/include/SDL11/SDL_getenv.h
@@ -249,13 +250,13 @@ expr.o: /usr/include/_ctype.h /usr/include/runetype.h
z80.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h
z80.o: /usr/include/sys/_null.h /usr/include/sys/_types.h
z80.o: /usr/include/machine/_types.h /usr/include/string.h
-z80.o: /usr/include/strings.h z80.h z80_private.h
+z80.o: /usr/include/strings.h z80.h z80_config.h z80_private.h
z80_decode.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h
z80_decode.o: /usr/include/sys/_null.h /usr/include/sys/_types.h
z80_decode.o: /usr/include/machine/_types.h /usr/include/limits.h
z80_decode.o: /usr/include/sys/limits.h /usr/include/machine/_limits.h
-z80_decode.o: /usr/include/sys/syslimits.h z80.h z80_private.h
-z80_dis.o: /usr/include/stdio.h /usr/include/sys/cdefs.h
+z80_decode.o: /usr/include/sys/syslimits.h z80.h z80_config.h z80_private.h
+z80_dis.o: z80_config.h /usr/include/stdio.h /usr/include/sys/cdefs.h
z80_dis.o: /usr/include/sys/_null.h /usr/include/sys/_types.h
z80_dis.o: /usr/include/machine/_types.h /usr/include/string.h
z80_dis.o: /usr/include/strings.h /usr/include/stdarg.h z80.h z80_private.h
diff --git a/src/z80.c b/src/z80.c
index 60dbca4..3a15a22 100644
--- a/src/z80.c
+++ b/src/z80.c
@@ -112,11 +112,16 @@ static void Z80_CheckInterrupt(Z80 *cpu)
/* ---------------------------------------- INTERFACES
*/
-Z80 *Z80Init(Z80ReadMemory read_memory,
- Z80WriteMemory write_memory,
- Z80ReadPort read_port,
- Z80WritePort write_port,
- Z80ReadMemory read_disassem)
+#ifdef ENABLE_ARRAY_MEMORY
+Z80 *Z80Init(Z80ReadPort read_port,
+ Z80WritePort write_port)
+#else
+Z80 *Z80Init(Z80ReadMemory read_memory,
+ Z80WriteMemory write_memory,
+ Z80ReadPort read_port,
+ Z80WritePort write_port,
+ Z80ReadMemory read_for_disassem)
+#endif
{
Z80 *cpu;
int f;
@@ -124,18 +129,22 @@ Z80 *Z80Init(Z80ReadMemory read_memory,
InitTables();
+#ifndef ENABLE_ARRAY_MEMORY
if (!read_memory || !write_memory)
return NULL;
+#endif
cpu=malloc(sizeof *cpu);
if (cpu)
{
+#ifndef ENABLE_ARRAY_MEMORY
cpu->mread=read_memory;
cpu->mwrite=write_memory;
+ cpu->disread=read_for_disassem;
+#endif
cpu->pread=read_port;
cpu->pwrite=write_port;
- cpu->disread=read_disassem;
for(f=0;f<eZ80_NO_CALLBACK;f++)
for(r=0;r<MAX_PER_CALLBACK;r++)
@@ -336,6 +345,7 @@ void Z80SetLabels(Z80Label labels[])
const char *Z80Disassemble(Z80 *cpu, Z80Word *pc)
{
#ifdef ENABLE_DISASSEM
+ Z80Byte Z80_Dis_FetchByte(Z80 *cpu, Z80Word *pc);
static char s[80];
Z80Word opc,npc;
Z80Byte op;
@@ -350,7 +360,13 @@ const char *Z80Disassemble(Z80 *cpu, Z80Word *pc)
strcat(s,Z80_Dis_Printf("%-40s ;",Z80_Dis_GetArg()));
for(f=0;f<5 && opc!=npc;f++)
+ {
+#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++)));
+#endif
+ }
if (opc!=npc)
for(f=1;f<3;f++)
diff --git a/src/z80.h b/src/z80.h
index 0b7424b..f6bc041 100644
--- a/src/z80.h
+++ b/src/z80.h
@@ -27,6 +27,11 @@
#ifndef Z80_H
#define Z80_H "$Id$"
+/* Configuration
+*/
+#include "z80_config.h"
+
+
/* ---------------------------------------- TYPES
*/
@@ -157,11 +162,16 @@ typedef struct
/* Initialises the processor.
*/
+#ifdef ENABLE_ARRAY_MEMORY
+Z80 *Z80Init(Z80ReadPort read_port,
+ Z80WritePort write_port);
+#else
Z80 *Z80Init(Z80ReadMemory read_memory,
Z80WriteMemory write_memory,
Z80ReadPort read_port,
Z80WritePort write_port,
Z80ReadMemory read_for_disassem);
+#endif
/* Resets the processor.
@@ -235,8 +245,8 @@ void Z80SetState(Z80 *cpu, const Z80State *state);
void Z80SetLabels(Z80Label labels[]);
-/* Simple disassembly of memory accessed through read_for_disassem.
- addr is updated on exit.
+/* Simple disassembly of memory accessed through read_for_disassem, or
+ Z80_MEMORY as appropriate. addr is updated on exit.
*/
const char *Z80Disassemble(Z80 *cpu, Z80Word *addr);
diff --git a/src/z80_config.h b/src/z80_config.h
new file mode 100644
index 0000000..af36944
--- /dev/null
+++ b/src/z80_config.h
@@ -0,0 +1,59 @@
+/*
+
+ z80 - Z80 emulation
+
+ Copyright (C) 2006 Ian Cowburn <ianc@noddybox.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 Z80_CONFIG_H
+#define Z80_CONFIG_H "$Id$"
+
+
+/* This file defines various compile-time configuration options
+ for the Z80 emulation
+*/
+
+
+/* Define this to enable the disassembly interface
+*/
+#define ENABLE_DISASSEM
+
+
+/* Define this to enable the array-based memory model. In this mode
+ an externally visible Z80Byte array called Z80_MEMORY must be
+ defined. The macros RAMBOT and RAMTOP define the writable area of
+ memory and must be changed accordingly.
+
+ In this mode the signature of Z80Init changes so that the memory functions
+ are not passed. ALL processor instances share the same memory.
+#define ENABLE_ARRAY_MEMORY
+*/
+
+#ifdef ENABLE_ARRAY_MEMORY
+#define RAMBOT 0x0000
+#define RAMTOP 0xffff
+#endif
+
+
+#endif
+
+/* END OF FILE */
diff --git a/src/z80_decode.c b/src/z80_decode.c
index ced7fbd..5fe52ea 100644
--- a/src/z80_decode.c
+++ b/src/z80_decode.c
@@ -118,6 +118,7 @@ void Z80_InitialiseInternals(void)
}
}
+#ifndef ENABLE_ARRAY_MEMORY
static Z80Word FPEEKW(Z80 *cpu, Z80Word addr)
{
return (PEEK(addr) | (Z80Word)PEEK(addr+1)<<8);
@@ -129,6 +130,7 @@ static void FPOKEW(Z80 *cpu, Z80Word addr, Z80Word val)
cpu->mwrite(cpu,addr,val);
cpu->mwrite(cpu,addr+1,val>>8);
}
+#endif
/* ---------------------------------------- GENERAL MACROS
@@ -274,35 +276,35 @@ do { \
#define OP_ON_MEM(OP,addr) \
do { \
- Z80Byte memop=cpu->mread(cpu,addr); \
+ Z80Byte memop=PEEK(addr); \
OP(memop); \
- cpu->mwrite(cpu,addr,memop); \
+ POKE(addr,memop); \
} while(0)
#define OP_ON_MEM_WITH_ARG(OP,addr,arg) \
do { \
- Z80Byte memop=cpu->mread(cpu,addr); \
+ Z80Byte memop=PEEK(addr); \
OP(memop,arg); \
- cpu->mwrite(cpu,addr,memop); \
+ POKE(addr,memop); \
} while(0)
#define OP_ON_MEM_WITH_COPY(OP,addr,copy) \
do { \
- Z80Byte memop=cpu->mread(cpu,addr); \
+ Z80Byte memop=PEEK(addr); \
OP(memop); \
copy=memop; \
- cpu->mwrite(cpu,addr,memop); \
+ POKE(addr,memop); \
} while(0)
#define OP_ON_MEM_WITH_ARG_AND_COPY(OP,addr,arg,copy) \
do { \
- Z80Byte memop=cpu->mread(cpu,addr); \
+ Z80Byte memop=PEEK(addr); \
OP(memop,arg); \
copy=memop; \
- cpu->mwrite(cpu,addr,memop); \
+ POKE(addr,memop); \
} while(0)
@@ -748,7 +750,7 @@ do { \
case BASE+6: /* LD DEST,(HL) */ \
TSTATE(7); \
OFFSET(off); \
- DEST2=cpu->mread(cpu,*HL+off); \
+ DEST2=PEEK(*HL+off); \
break; \
\
case BASE+7: /* LD DEST,A */ \
@@ -2063,7 +2065,7 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode)
case 0x36: /* LD (HL),n */
TSTATE(10);
OFFSET(off);
- cpu->mwrite(cpu,*HL+off,FETCH_BYTE);
+ POKE(*HL+off,FETCH_BYTE);
break;
case 0x37: /* SCF */
@@ -2084,7 +2086,7 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode)
case 0x3a: /* LD A,(nnnn) */
TSTATE(13);
- cpu->AF.b[HI]=cpu->mread(cpu,FETCH_WORD);
+ cpu->AF.b[HI]=PEEK(FETCH_WORD);
break;
case 0x3b: /* DEC SP */
@@ -2129,37 +2131,37 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode)
case 0x70: /* LD (HL),B */
TSTATE(7);
OFFSET(off);
- cpu->mwrite(cpu,*HL+off,cpu->BC.b[HI]);
+ POKE(*HL+off,cpu->BC.b[HI]);
break;
case 0x71: /* LD (HL),C */
TSTATE(7);
OFFSET(off);
- cpu->mwrite(cpu,*HL+off,cpu->BC.b[LO]);
+ POKE(*HL+off,cpu->BC.b[LO]);
break;
case 0x72: /* LD (HL),D */
TSTATE(7);
OFFSET(off);
- cpu->mwrite(cpu,*HL+off,cpu->DE.b[HI]);
+ POKE(*HL+off,cpu->DE.b[HI]);
break;
case 0x73: /* LD (HL),E */
TSTATE(7);
OFFSET(off);
- cpu->mwrite(cpu,*HL+off,cpu->DE.b[LO]);
+ POKE(*HL+off,cpu->DE.b[LO]);
break;
case 0x74: /* LD (HL),H */
TSTATE(7);
OFFSET(off);
- cpu->mwrite(cpu,*HL+off,cpu->HL.b[HI]);
+ POKE(*HL+off,cpu->HL.b[HI]);
break;
case 0x75: /* LD (HL),L */
TSTATE(7);
OFFSET(off);
- cpu->mwrite(cpu,*HL+off,cpu->HL.b[LO]);
+ POKE(*HL+off,cpu->HL.b[LO]);
break;
case 0x76: /* HALT */
@@ -2175,7 +2177,7 @@ void Z80_Decode(Z80 *cpu, Z80Byte opcode)
case 0x77: /* LD (HL),A */
TSTATE(7);
OFFSET(off);
- cpu->mwrite(cpu,*HL+off,cpu->AF.b[HI]);
+ POKE(*HL+off,cpu->AF.b[HI]);
break;
LD_BLOCK(0x78,cpu->AF.b[HI],cpu->AF.b[HI])
diff --git a/src/z80_dis.c b/src/z80_dis.c
index 9d42829..6204f0d 100644
--- a/src/z80_dis.c
+++ b/src/z80_dis.c
@@ -25,6 +25,8 @@
*/
static const char ident[]="$Id$";
+#include "z80_config.h"
+
#ifdef ENABLE_DISASSEM
#include <stdio.h>
@@ -62,7 +64,11 @@ const char *Z80_Dis_Printf(const char *format, ...)
Z80Byte Z80_Dis_FetchByte(Z80 *cpu, Z80Word *pc)
{
+#ifdef ENABLE_ARRAY_MEMORY
+ return Z80_MEMORY[(*pc)++];
+#else
return cpu->disread(cpu,(*pc)++);
+#endif
}
@@ -1454,7 +1460,11 @@ static void DIS_DJNZ (Z80 *z80, Z80Byte op, Z80Word *pc)
{
Z80Word new;
+#ifdef ENABLE_ARRAY_MEMORY
+ new=*pc+(Z80Relative)Z80_MEMORY[*pc]+1;
+#else
new=*pc+(Z80Relative)z80->disread(z80,*pc)+1;
+#endif
(*pc)++;
Z80_Dis_Set("djnz",Z80_Dis_Printf("$%.4x",new));
}
@@ -1469,7 +1479,11 @@ static void DIS_JR (Z80 *z80, Z80Byte op, Z80Word *pc)
Z80Word new;
const char *p;
+#ifdef ENABLE_ARRAY_MEMORY
+ new=*pc+(Z80Relative)Z80_MEMORY[*pc]+1;
+#else
new=*pc+(Z80Relative)z80->disread(z80,*pc)+1;
+#endif
(*pc)++;
if ((p=GetLabel(new)))
@@ -1490,7 +1504,11 @@ static void DIS_JR_CO (Z80 *z80, Z80Byte op, Z80Word *pc)
const char *p;
con=z80_dis_condition[(op-0x20)/8];
+#ifdef ENABLE_ARRAY_MEMORY
+ new=*pc+(Z80Relative)Z80_MEMORY[*pc]+1;
+#else
new=*pc+(Z80Relative)z80->disread(z80,*pc)+1;
+#endif
(*pc)++;
if ((p=GetLabel(new)))
diff --git a/src/z80_private.h b/src/z80_private.h
index 6675c12..d031497 100644
--- a/src/z80_private.h
+++ b/src/z80_private.h
@@ -29,6 +29,8 @@
#ifndef Z80_PRIVATE_H
#define Z80_PRIVATE_H "$Id$"
+#include "z80_config.h"
+
#ifndef TRUE
#define TRUE 1
#endif
@@ -85,10 +87,12 @@ struct Z80
Z80Byte devbyte;
int nmi;
+#ifndef ENABLE_ARRAY_MEMORY
Z80ReadMemory disread;
Z80ReadMemory mread;
Z80WriteMemory mwrite;
+#endif
Z80ReadPort pread;
Z80WritePort pwrite;
@@ -99,6 +103,14 @@ struct Z80
};
+/* ---------------------------------------- ARRAY MEMORY
+*/
+
+#ifdef ENABLE_ARRAY_MEMORY
+extern Z80Byte Z80_MEMORY[];
+#endif
+
+
/* ---------------------------------------- MACROS
*/
@@ -115,7 +127,8 @@ struct Z80
\
for(f=0;f<MAX_PER_CALLBACK;f++) \
if (cpu->callback[r][f]) \
- cpu->callback[r][f](cpu,d); \
+ cpu->last_cb &= \
+ cpu->callback[r][f](cpu,d); \
} while(0)
/* Flag register
@@ -138,6 +151,38 @@ struct Z80
#define SETFLAG(f) SET(cpu->AF.b[LO],f)
#define CLRFLAG(f) CLR(cpu->AF.b[LO],f)
+#ifdef ENABLE_ARRAY_MEMORY
+
+#define PEEK(addr) Z80_MEMORY[addr]
+
+static inline Z80Word PEEKW(Z80Word addr)
+{
+ return (PEEK(addr) | (Z80Word)PEEK(addr+1)<<8);
+}
+
+#define POKE(addr,val) do \
+ { \
+ Z80Word ba=addr; \
+ if (ba>=RAMBOT && ba<=RAMTOP) \
+ Z80_MEMORY[ba]=val; \
+ } while(0)
+
+#define POKEW(addr,val) do \
+ { \
+ Z80Word wa=addr; \
+ Z80Word wv=val; \
+ POKE(wa,wv); \
+ POKE(wa+1,wv>>8); \
+ } while(0)
+
+
+#define FETCH_BYTE (Z80_MEMORY[cpu->PC++])
+#define FETCH_WORD (cpu->PC+=2, \
+ Z80_MEMORY[cpu->PC-2]| \
+ ((Z80Word)Z80_MEMORY[cpu->PC-1]<<8))
+
+#else
+
#define PEEK(addr) (cpu->mread(cpu,addr))
#define PEEKW(addr) FPEEKW(cpu,addr)
@@ -147,6 +192,9 @@ struct Z80
#define FETCH_BYTE (cpu->mread(cpu,cpu->PC++))
#define FETCH_WORD (cpu->PC+=2,FPEEKW(cpu,cpu->PC-2))
+#endif
+
+
#define IS_C (cpu->AF.b[LO]&C_Z80)
#define IS_N (cpu->AF.b[LO]&N_Z80)
#define IS_P (cpu->AF.b[LO]&P_Z80)
@@ -164,6 +212,18 @@ struct Z80
#define ADD_R(v) cpu->R=((cpu->R&0x80)|((cpu->R+(v))&0x7f))
#define INC_R ADD_R(1)
+#ifdef ENABLE_ARRAY_MEMORY
+
+#define PUSH(REG) do \
+ { \
+ Z80Word pv=REG; \
+ cpu->SP-=2; \
+ POKE(cpu->SP,pv); \
+ POKE(cpu->SP+1,pv>>8); \
+ } while(0)
+
+#else
+
#define PUSH(REG) do \
{ \
Z80Word pushv=REG; \
@@ -171,6 +231,7 @@ struct Z80
cpu->mwrite(cpu,cpu->SP,pushv); \
cpu->mwrite(cpu,cpu->SP+1,pushv>>8);\
} while(0)
+#endif
#define POP(REG) do \
{ \
@@ -209,15 +270,6 @@ struct Z80
extern Z80Label *z80_labels;
-/* ---------------------------------------- FLAG TABLES
-*/
-extern Z80Byte PSZtable[512];
-extern Z80Byte SZtable[512];
-extern Z80Byte Ptable[512];
-extern Z80Byte Stable[512];
-extern Z80Byte Ztable[512];
-
-
/* ---------------------------------------- GLOBAL GENERAL OPCODES/ROUTINES
*/
void Z80_Decode(Z80 *cpu, Z80Byte opcode);