diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/z80.h | 43 | ||||
-rw-r--r-- | include/z80_config.h | 6 | ||||
-rw-r--r-- | include/z80_private.h | 73 |
3 files changed, 97 insertions, 25 deletions
diff --git a/include/z80.h b/include/z80.h index ef24fd0..c9bd107 100644 --- a/include/z80.h +++ b/include/z80.h @@ -56,20 +56,30 @@ 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. +/* A Z80 16-bit register made up of 2 8-bit registers. */ +#ifdef Z80_LITTLE_ENDIAN +typedef struct +{ + Z80Byte lo; + Z80Byte hi; +} Z80RegPair; +#endif + +#ifdef Z80_BIG_ENDIAN +typedef struct +{ + Z80Byte hi; + Z80Byte lo; +} Z80RegPair; +#endif + typedef union { Z80Word w; - Z80Byte b[2]; + Z80RegPair b; } Z80Reg; -extern int Z80_HI_WORD; -extern int Z80_LO_WORD; - - /* The processor */ struct Z80Private; @@ -134,13 +144,23 @@ typedef int (*Z80Callback)(Z80 *cpu, Z80Val data); */ typedef enum { - eZ80_Instruction, /* data = no cycles since reset */ + eZ80_Instruction, /* data = cycles as returned by Z80Cycles */ eZ80_EDHook, /* data = byte after ED opcode (only for NOP opcodes) */ eZ80_Halt, /* data = 1 halt raised, 0 halt cleared by int */ eZ80_RETI, /* data = ignored */ eZ80_NO_CALLBACK /* leave at end */ } Z80CallbackReason; +/* Defines cycle timers +*/ +typedef enum +{ + Z80_TIMER_1, + Z80_TIMER_2, + Z80_TIMER_3, + Z80_NO_TIMERS +} Z80Timer; + /* Flags in the F register */ @@ -235,6 +255,11 @@ void Z80Exec(Z80 *cpu); Z80Val Z80Cycles(Z80 *cpu); void Z80ResetCycles(Z80 *cpu, Z80Val cycles); +/* Timers that count in cycle counts +*/ +Z80Val Z80GetTimer(Z80 *cpu, Z80Timer timer); +void Z80SetTimer(Z80 *cpu, Z80Timer timer, Z80Val cycles); + /* Set address to label mappings for the disassembler */ diff --git a/include/z80_config.h b/include/z80_config.h index 8d9ee79..4168dc3 100644 --- a/include/z80_config.h +++ b/include/z80_config.h @@ -37,6 +37,12 @@ #define ENABLE_DISASSEM +/* Pick one of these as appropriate for your real CPU +#define Z80_BIG_ENDIAN +*/ +#define Z80_LITTLE_ENDIAN + + /* 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 diff --git a/include/z80_private.h b/include/z80_private.h index 10cf97e..e3d721a 100644 --- a/include/z80_private.h +++ b/include/z80_private.h @@ -19,14 +19,14 @@ ------------------------------------------------------------------------- - $Id: z80_private.h 13 2006-10-12 16:38:57Z ianc $ + $Id$ Private macros for Z80 */ #ifndef Z80_PRIVATE_H -#define Z80_PRIVATE_H "$Id: z80_private.h 13 2006-10-12 16:38:57Z ianc $" +#define Z80_PRIVATE_H "$Id$" #include "z80_config.h" @@ -48,6 +48,8 @@ struct Z80Private { Z80Val cycle; + Z80Val timer[Z80_NO_TIMERS]; + int halt; Z80Byte shift; @@ -69,6 +71,8 @@ struct Z80Private Z80Callback callback[eZ80_NO_CALLBACK][MAX_PER_CALLBACK]; int last_cb; + + Z80Reg memptr; }; #define PRIV cpu->priv @@ -114,18 +118,21 @@ extern Z80Byte Z80_MEMORY[]; #define B3_Z80 0x08 #define B5_Z80 0x20 +#define HIDDEN_Z80 (B3_Z80|B5_Z80) #define SET(v,b) (v)|=b #define CLR(v,b) (v)&=~(b) -#define SETFLAG(f) SET(cpu->AF.b[LO],f) -#define CLRFLAG(f) CLR(cpu->AF.b[LO],f) +#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] +/* This can't be a macro as the macro is used as PEEKW(FETCH_WORD) +*/ static inline Z80Word PEEKW(Z80Word addr) { return (PEEK(addr) | (Z80Word)PEEK(addr+1)<<8); @@ -154,6 +161,9 @@ static inline Z80Word PEEKW(Z80Word addr) #else +Z80Word FPEEKW(Z80 *cpu, Z80Word addr); +void FPOKEW(Z80 *cpu, Z80Word addr, Z80Word val); + #define PEEK(addr) (PRIV->mread(cpu,addr)) #define PEEKW(addr) FPEEKW(cpu,addr) @@ -166,19 +176,37 @@ static inline Z80Word PEEKW(Z80Word addr) #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) -#define IS_H (cpu->AF.b[LO]&H_Z80) -#define IS_Z (cpu->AF.b[LO]&Z_Z80) -#define IS_S (cpu->AF.b[LO]&S_Z80) +#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) +#define IS_H (cpu->AF.b.lo&H_Z80) +#define IS_Z (cpu->AF.b.lo&Z_Z80) +#define IS_S (cpu->AF.b.lo&S_Z80) #define CARRY IS_C #define IS_IX_IY (PRIV->shift==0xdd || PRIV->shift==0xfd) -#define OFFSET(off) off=(IS_IX_IY ? (Z80Relative)FETCH_BYTE:0) -#define TSTATE(n) PRIV->cycle+=n +#define OFFSET(base,off) do \ + { \ + if (IS_IX_IY) \ + { \ + off=(Z80Relative)FETCH_BYTE; \ + PRIV->memptr.w=base+off; \ + } \ + else \ + { \ + off=0; \ + } \ + } while(0) + +#define TSTATE(n) do \ + { \ + PRIV->cycle+=n; \ + PRIV->timer[Z80_TIMER_1]+=n; \ + PRIV->timer[Z80_TIMER_2]+=n; \ + PRIV->timer[Z80_TIMER_3]+=n; \ + } while(0) #define ADD_R(v) cpu->R=((cpu->R&0x80)|((cpu->R+(v))&0x7f)) #define INC_R ADD_R(1) @@ -211,19 +239,32 @@ static inline Z80Word PEEKW(Z80Word addr) cpu->SP+=2; \ } while(0) -#define SETHIDDEN(res) cpu->AF.b[LO]=(cpu->AF.b[LO]&~(B3_Z80|B5_Z80))|\ +#define SETHIDDEN(res) cpu->AF.b.lo=(cpu->AF.b.lo&~(B3_Z80|B5_Z80))|\ ((res)&(B3_Z80|B5_Z80)) #define CALL do \ { \ PUSH(cpu->PC+2); \ cpu->PC=PEEKW(cpu->PC); \ + PRIV->memptr.w=cpu->PC; \ } while(0) #define NOCALL cpu->PC+=2 -#define JP cpu->PC=PEEKW(cpu->PC) -#define NOJP cpu->PC+=2 -#define JR cpu->PC+=(Z80Relative)PEEK(cpu->PC)+1 + +#define JP do \ + { \ + cpu->PC=PEEKW(cpu->PC); \ + PRIV->memptr.w=cpu->PC; \ + } while(0) + +#define NOJP NOCALL + +#define JR do \ + { \ + cpu->PC+=(Z80Relative)PEEK(cpu->PC)+1; \ + PRIV->memptr.w=cpu->PC; \ + } while(0) + #define NOJR cpu->PC++ #define OUT(P,V) do \ |