diff options
-rw-r--r-- | Makefile | 10 | ||||
-rw-r--r-- | emma.c | 52 | ||||
-rw-r--r-- | gemma.c | 44 | ||||
-rw-r--r-- | rundoc | 1 | ||||
-rw-r--r-- | z80.c | 28 | ||||
-rw-r--r-- | z80.h | 14 | ||||
-rw-r--r-- | z80_config.h | 59 | ||||
-rw-r--r-- | z80_decode.c | 38 | ||||
-rw-r--r-- | z80_dis.c | 18 | ||||
-rw-r--r-- | z80_private.h | 60 |
10 files changed, 249 insertions, 75 deletions
@@ -18,7 +18,7 @@ # # ------------------------------------------------------------------------- # -# $Id: Makefile,v 1.15 2006-09-06 23:35:58 ianc Exp $ +# $Id: Makefile,v 1.16 2006-09-16 00:41:11 ianc Exp $ # # @@ -30,7 +30,7 @@ # Simply comment out if not, and replace as needed. # Other CFLAGS lines *are* required. # -CFLAGS = -g -Wall -Werror -pedantic -ansi -O2 -finline-functions +CFLAGS = -g -w -Wsequence-point -O2 -finline-functions # Decide on what to build. Options are: # emma - Simple 'breadboard' computer. @@ -45,11 +45,7 @@ TARGETS += tests # CFLAGS += `pkg-config --cflags gtk+-2.0` -# Remove this to disable the disassembler (saving some memory) -# -CFLAGS += -DENABLE_DISASSEM - -# Remove the follwing to disable the use of readline in EMMA +# Remove the following to disable the use of readline in EMMA # CFLAGS += -DENABLE_READLINE LIBS += -lreadline @@ -49,7 +49,7 @@ static const char id[]="$Id$"; /* ---------------------------------------- GLOBALS */ static Z80 *z80; -static Z80Byte mem[0x10000]; +Z80Byte Z80_MEMORY[0x10000]; static sig_atomic_t stop=FALSE; static int quit=FALSE; @@ -87,20 +87,21 @@ static void SigInt(int sig) /* ---------------------------------------- MEMORY */ +#ifndef ENABLE_ARRAY_MEMORY static Z80Byte Peek(Z80 *cpu, Z80Word addr) { if (mem_trace) { - Log("Read %2.2x from %4.4x\n",mem[addr],addr); + Log("Read %2.2x from %4.4x\n",Z80_MEMORY[addr],addr); } - return mem[addr]; + return Z80_MEMORY[addr]; } static Z80Byte DisPeek(Z80 *cpu, Z80Word addr) { - return mem[addr]; + return Z80_MEMORY[addr]; } @@ -113,9 +114,10 @@ static void Poke(Z80 *cpu, Z80Word addr, Z80Byte b) Log("Wrote %2.2x to %4.4x\n",b,addr); } - mem[addr]=b; + Z80_MEMORY[addr]=b; } } +#endif /* ---------------------------------------- COMMANDS AND ASSOC UTILS @@ -310,14 +312,14 @@ static int Expand(void *client, const char *p, long *res) Z80Word n; n=Address(p+1); - *res=mem[n]; + *res=Z80_MEMORY[n]; } else if (p[0]=='#') { Z80Word n; n=Address(p+1); - *res=MK(mem[n+1],mem[n]); + *res=MK(Z80_MEMORY[n+1],Z80_MEMORY[n]); } else /* Check for labels */ { @@ -470,7 +472,7 @@ static void DoLoad(int no, const char *arg[]) while((c=getc(fp))!=EOF) { - mem[addr++]=(Z80Byte)c; + Z80_MEMORY[addr++]=(Z80Byte)c; total++; } @@ -536,7 +538,7 @@ static void DoIntel(int no, const char *arg[]) Z80Byte b; b=ToHex(buff[f*2+9])<<4|ToHex(buff[f*2+10]); - mem[addr++]=b; + Z80_MEMORY[addr++]=b; } } } @@ -604,10 +606,10 @@ static void DoDump(int no, const char *arg[]) if ((count%8)==0) Log("0x%4.4x: ",addr); - Log(" 0x%2.2x",mem[addr]); + Log(" 0x%2.2x",Z80_MEMORY[addr]); - if (isprint(mem[addr])) - asc[count%8]=mem[addr]; + if (isprint(Z80_MEMORY[addr])) + asc[count%8]=Z80_MEMORY[addr]; else asc[count%8]='.'; @@ -713,7 +715,7 @@ static void DoSetPC(int no, const char *arg[]) if (no<2) { - s.PC=MK(mem[s.SP+1],mem[s.SP]); + s.PC=MK(Z80_MEMORY[s.SP+1],Z80_MEMORY[s.SP]); s.SP+=2; DisplayState(); } @@ -983,12 +985,12 @@ static Z80Byte ReadPort(Z80 *z80, Z80Word addr) switch(addr&0xff) { case 0x80: - ptr=MK(mem[1],mem[0]); + ptr=MK(Z80_MEMORY[1],Z80_MEMORY[0]); p=expr; - while(mem[ptr]) - *p++=mem[ptr++]; + while(Z80_MEMORY[ptr]) + *p++=Z80_MEMORY[ptr++]; *p=0; @@ -1003,8 +1005,8 @@ static Z80Byte ReadPort(Z80 *z80, Z80Word addr) p=expr; - while(mem[ptr]) - *p++=mem[ptr++]; + while(Z80_MEMORY[ptr]) + *p++=Z80_MEMORY[ptr++]; *p=0; @@ -1040,10 +1042,10 @@ static void WritePort(Z80 *z80, Z80Word addr, Z80Byte val) break; case 0x82: - while(mem[s.DE]!='$') + while(Z80_MEMORY[s.DE]!='$') { - if (isspace(mem[s.DE]) || isprint(mem[s.DE])) - Log("%c",mem[s.DE]); + if (isspace(Z80_MEMORY[s.DE]) || isprint(Z80_MEMORY[s.DE])) + Log("%c",Z80_MEMORY[s.DE]); s.DE++; } @@ -1051,9 +1053,9 @@ static void WritePort(Z80 *z80, Z80Word addr, Z80Byte val) break; case 0x83: - while(mem[s.DE]) + while(Z80_MEMORY[s.DE]) { - Log("%c",mem[s.DE]); + Log("%c",Z80_MEMORY[s.DE]); s.DE++; } fflush(stdout); @@ -1109,7 +1111,11 @@ int main(int argc, char *argv[]) { const char *autoarg[2]={".","auto"}; +#ifndef ENABLE_ARRAY_MEMORY z80=Z80Init(Peek,Poke,ReadPort,WritePort,DisPeek); +#else + z80=Z80Init(ReadPort,WritePort); +#endif if (!z80) { @@ -41,7 +41,7 @@ static const char id[]="$Id$"; /* ---------------------------------------- GLOBALS */ static Z80 *z80; -static Z80Byte mem[0x10000]; +Z80Byte Z80_MEMORY[0x10000]; static sig_atomic_t stop=FALSE; @@ -271,14 +271,14 @@ static int Expand(void *client, const char *p, long *res) Z80Word n; n=Address(p+1); - *res=mem[n]; + *res=Z80_MEMORY[n]; } else if (p[0]=='#') { Z80Word n; n=Address(p+1); - *res=MK(mem[n+1],mem[n]); + *res=MK(Z80_MEMORY[n+1],Z80_MEMORY[n]); } else /* Check for labels */ { @@ -412,15 +412,17 @@ static void DisplayState(DString s, const char *label, /* ---------------------------------------- MEMORY */ +#ifndef ENABLE_ARRAY_MEMORY static Z80Byte Peek(Z80 *z80, Z80Word addr) { - return mem[addr]; + return Z80_MEMORY[addr]; } static void Poke(Z80 *z80, Z80Word addr, Z80Byte b) { - mem[addr]=b; + Z80_MEMORY[addr]=b; } +#endif static Z80Byte ReadPort(Z80 *z80, Z80Word addr) { @@ -435,12 +437,12 @@ static Z80Byte ReadPort(Z80 *z80, Z80Word addr) switch(addr&0xff) { case 0x80: - ptr=MK(mem[1],mem[0]); + ptr=MK(Z80_MEMORY[1],Z80_MEMORY[0]); p=expr; - while(mem[ptr]) - *p++=mem[ptr++]; + while(Z80_MEMORY[ptr]) + *p++=Z80_MEMORY[ptr++]; *p=0; @@ -455,8 +457,8 @@ static Z80Byte ReadPort(Z80 *z80, Z80Word addr) p=expr; - while(mem[ptr]) - *p++=mem[ptr++]; + while(Z80_MEMORY[ptr]) + *p++=Z80_MEMORY[ptr++]; *p=0; @@ -493,11 +495,11 @@ static void WritePort(Z80 *z80, Z80Word addr, Z80Byte val) break; case 0x82: - while(mem[s.DE]!='$') + while(Z80_MEMORY[s.DE]!='$') { - if (isspace(mem[s.DE]) || isprint(mem[s.DE])) + if (isspace(Z80_MEMORY[s.DE]) || isprint(Z80_MEMORY[s.DE])) { - DSAddChar(ds,mem[s.DE]); + DSAddChar(ds,Z80_MEMORY[s.DE]); } s.DE++; @@ -505,9 +507,9 @@ static void WritePort(Z80 *z80, Z80Word addr, Z80Byte val) break; case 0x83: - while(mem[s.DE]) + while(Z80_MEMORY[s.DE]) { - DSAddChar(ds,mem[s.DE]); + DSAddChar(ds,Z80_MEMORY[s.DE]); s.DE++; } break; @@ -719,7 +721,7 @@ void GEMMA_UpdateDisplay(GEMMA_View view) { gchar *p; p=g_markup_printf_escaped - ("%c",isprint(mem[addr+off]) ? mem[addr+off] : '.'); + ("%c",isprint(Z80_MEMORY[addr+off]) ? Z80_MEMORY[addr+off] : '.'); DSAdd(asc,p); g_free(p); } @@ -738,11 +740,11 @@ void GEMMA_UpdateDisplay(GEMMA_View view) if (as_words) { - sprintf(buff,"%4.4X ",MK(mem[a+1],mem[a])); + sprintf(buff,"%4.4X ",MK(Z80_MEMORY[a+1],Z80_MEMORY[a])); } else { - sprintf(buff,"%2.2X ",mem[a]); + sprintf(buff,"%2.2X ",Z80_MEMORY[a]); } DSAdd(ds,buff); @@ -821,7 +823,7 @@ void GEMMA_LoadHEX(const char *path) Z80Byte b; b=ToHex(buff[f*2+9])<<4|ToHex(buff[f*2+10]); - mem[addr++]=b; + Z80_MEMORY[addr++]=b; } } } @@ -979,7 +981,11 @@ void GEMMA_Stop(void) void GEMMA_Init(GtkWidget *top) { +#ifdef ENABLE_ARRAY_MEMORY + z80=Z80Init(ReadPort,WritePort); +#else z80=Z80Init(Peek,Poke,ReadPort,WritePort,Peek); +#endif Z80SetPC(z80,0x100); if (!z80) @@ -5,3 +5,4 @@ s r 0x100 #p 0x100 #n +quit @@ -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_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++) @@ -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/z80_config.h b/z80_config.h new file mode 100644 index 0000000..187d8e0 --- /dev/null +++ b/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/z80_decode.c b/z80_decode.c index ced7fbd..5fe52ea 100644 --- a/z80_decode.c +++ b/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]) @@ -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/z80_private.h b/z80_private.h index 4a19324..d031497 100644 --- a/z80_private.h +++ b/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 */ @@ -139,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) @@ -148,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) @@ -165,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; \ @@ -172,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 \ { \ |