/** Z80: portable Z80 emulator **********************************************/
/**                                                                        **/
/**                                 Z80.h                                  **/
/**                                                                        **/
/** This file contains the main Z80 emulation function prototypes and      **/
/** definitions                                                            **/
/**                                                                        **/
/** Copyright (C) Marat Fayzullin 1994,1995,1996                           **/
/**               Marcel de Kogel 1996                                     **/
/**     You are not allowed to distribute this software commercially       **/
/**     Please, notify me, if you make any changes to this file            **/
/****************************************************************************/

/****************************************************************************/
/** Machine dependent definitions                                          **/
/****************************************************************************/
/* #define DEBUG */                   /* Compile debugging version          */
/* #define LSB_FIRST */               /* Compile for low-endian CPU         */
/* #define X86_ASM */                 /* Use inline X86 assembly            */
/* #define __64BIT__ */               /* Compile for 64 bit machines        */
/* #define __128BIT__ */              /* Compile for 128 bit machines       */

/* How to define inline functions inside header files */
#define INLINE  extern __inline__
/* Pass parameters in registers to functions declared as FASTCALL */
#define FASTCALL __attribute__ ((regparm(3)))

/* sizeof(byte)=1, sizeof(word)=2, sizeof(dword)>=4 */
typedef unsigned char byte;
typedef unsigned short word;
typedef unsigned dword;
typedef signed char offset;

/* define a Z80 word. Higher bytes are always zero */
typedef union
{
#ifdef __128BIT__
 #ifdef LSB_FIRST
   struct { byte l,h,h2,h3,h4,h5,h6,h7,
                 h8,h9,h10,h11,h12,h13,h14,h15; } B;
   struct { word l,h,h2,h3,h4,h5,h6,h7; } W;
   dword D;
 #else
   struct { byte h15,h14,h13,h12,h11,h10,h9,h8,
                 h7,h6,h5,h4,h3,h2,h,l; } B;
   struct { word h7,h6,h5,h4,h3,h2,h,l; } W;
   dword D;
 #endif
#elif __64BIT__
 #ifdef LSB_FIRST
   struct { byte l,h,h2,h3,h4,h5,h6,h7; } B;
   struct { word l,h,h2,h3; } W;
   dword D;
 #else
   struct { byte h7,h6,h5,h4,h3,h2,h,l; } B;
   struct { word h3,h2,h,l; } W;
   dword D;
 #endif
#else
 #ifdef LSB_FIRST
   struct { byte l,h,h2,h3; } B;
   struct { word l,h; } W;
   dword D;
 #else
   struct { byte h3,h2,h,l; } B;
   struct { word h,l; } W;
   dword D;
 #endif
#endif
} pair;

/****************************************************************************/
/** End of machine dependent definitions                                   **/
/****************************************************************************/

#define S_FLAG      0x80
#define Z_FLAG      0x40
#define H_FLAG      0x10
#define P_FLAG      0x04
#define V_FLAG      0x04
#define N_FLAG      0x02
#define C_FLAG      0x01

/** Trace and Trap **********************************************************/
/** Switches to turn tracing on and off in DEBUG mode                      **/
/****************************************************************************/
#ifdef DEBUG
extern int  Trace;                    /* Tracing is on if Trace==1          */
extern int  Trap;                     /* When PC==Trap, set Trace=1         */
#endif

/** TrapBadOps **************************************************************/
/** When 1, print warnings of illegal Z80 instructions                     **/
/****************************************************************************/
extern byte TrapBadOps;

/** CPURunning **************************************************************/
/** When 0, execution terminates                                           **/
/****************************************************************************/
extern byte CPURunning;

typedef struct
{
  pair AF,BC,DE,HL,IX,IY,PC,SP;
  pair AF1,BC1,DE1,HL1;
  unsigned IFF,I,R,R2;
} reg;

extern reg R;

/** Interpret Z80 code: *****************************************************/
/** RAM starts at Addr and registers have initial values from Regs. PC     **/
/** value at which emulation stopped is returned by this function          **/
/****************************************************************************/
void ResetZ80 (reg *Regs);            /* Reset all registers                */
word Z80(reg *Regs);                  /* Start Z80 emulation                */
void Patch (reg *Regs);               /* Called when ED FE occurs           */
void Z80_RegisterDump (void);         /* Prints a dump to stdout            */

#ifdef DEBUG
/** Single-step debugger ****************************************************/
/** This function should exist if DEBUG is #defined. If Trace==1 it is     **/
/** called after each command executed by the CPU and given address of     **/
/** the address space and the register file                                **/
/****************************************************************************/
void Debug(reg *R);
#endif

/** Interrupt handler *******************************************************/
/** This function is called on each attempted interrupt and should return  **/
/** an interrupt address to proceed with interrupt or IGNORE_INT to        **/
/** continue execution                                                     **/ 
/****************************************************************************/
int Interrupt(void);

/** Interrupt handler *******************************************************/
/** This function is called when EI is executed and should return an       **/
/** interrupt address to proceed with interrupt or IGNORE_INT to continue  **/
/** execution                                                              **/ 
/****************************************************************************/
int InterruptsEnabled(void);

extern int IPeriod;                   /* Number of T-states per interrupt   */
extern int ICount;                    /* T-state count                      */
#define IGNORE_INT      -1            /* Ignore interrupt                   */
#define NMI_INT         -2            /* Execute NMI                        */

/* definitions of functions to read/write memory and I/O ports */
#include "Z80IO.h"

/* some handy macros */
INLINE unsigned M_RDMEM_WORD (dword A)
{
 int i;
 i=M_RDMEM (A);
 i+=M_RDMEM ((A+1)&0xFFFF)*256;
 return i;
}

INLINE void M_WRMEM_WORD (dword A,word V)
{
 M_WRMEM (A,V&255);
 M_WRMEM ((A+1)&0xFFFF,V>>8);
}

#include "Z80Codes.h"
