AppleWin/source/Z80/z80cpu.h

183 lines
6.9 KiB
C

#pragma once
/* #define DEBUG */ /* Compile debugging version */
/* #define X86_ASM */ /* Compile optimised GCC/x86 version */
#define LSB_FIRST /* Compile for low-endian CPU */
/* #define __64BIT__ */ /* Compile for 64 bit machines */
/* #define __128BIT__ */ /* Compile for 128 bit machines */
#ifndef EMU_TYPES
#define EMU_TYPES
/****************************************************************************/
/* 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. Upper 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
} regpair;
#endif /* EMU_TYPES */
/****************************************************************************/
/*** End of machine dependent definitions ***/
/****************************************************************************/
#ifndef INLINE
#define INLINE static inline
#endif
/****************************************************************************/
/* The Z80 registers. HALT is set to 1 when the CPU is halted, the refresh */
/* register is calculated as follows: refresh=(Regs.R&127)|(Regs.R2&128) */
/****************************************************************************/
typedef struct
{
regpair AF,BC,DE,HL,IX,IY,PC,SP;
regpair AF2,BC2,DE2,HL2;
unsigned IFF1,IFF2,HALT,IM,I,R,R2;
} Z80_Regs;
/****************************************************************************/
/* Set Z80_Trace to 1 when PC==Z80_Trap. When trace is on, Z80_Debug() is */
/* called after every instruction */
/****************************************************************************/
#ifdef DEBUG
extern int Z80_Trace;
extern int Z80_Trap;
void Z80_Debug(Z80_Regs *R);
#endif
extern int Z80_Running; /* When 0, emulation terminates */
extern int Z80_IPeriod; /* Number of T-states per interrupt */
extern int Z80_ICount; /* T-state count */
extern int Z80_IRQ; /* Current IRQ status. Checked after EI occurs */
#define Z80_IGNORE_INT -1 /* Ignore interrupt */
#define Z80_NMI_INT -2 /* Execute NMI */
DWORD InternalZ80Execute (ULONG totalcycles, ULONG uExecutedCycles);
unsigned Z80_GetPC (void); /* Get program counter */
void InitTables (void);
void Z80_GetRegs (Z80_Regs *Regs); /* Get registers */
void Z80_SetRegs (Z80_Regs *Regs); /* Set registers */
void Z80_Reset (void); /* Reset registers to the initial values */
//int Z80_Execute (void); /* Execute IPeriod T-States */
word Z80 (void); /* Execute until Z80_Running==0 */
void Z80_RegisterDump (void); /* Prints a dump to stdout */
void Z80_SetWaitStates (int n); /* Set number of memory wait states. */
/* This only affects opcode fetching, so */
/* wait state adjustment is still */
/* necessary in Z80_RDMEM, Z80_RDOP_ARG, */
/* Z80_RDSTACK and Z80_WRSTACK */
void Z80_Patch (Z80_Regs *Regs); /* Called when ED FE occurs. Can be used */
/* to emulate disk access etc. */
int Z80_Interrupt(void); /* This is called after IPeriod T-States */
/* have been executed. It should return */
/* Z80_IGNORE_INT, Z80_NMI_INT or a byte */
/* identifying the device (most often */
/* 0xFF) */
void Z80_Reti (void); /* Called when RETI occurs */
void Z80_Retn (void); /* Called when RETN occurs */
/****************************************************************************/
/* Definitions of functions to read/write memory and I/O ports */
/* You can replace these with your own, inlined if necessary */
/****************************************************************************/
#include "Z80IO.h"
// ---------------------------------------------------------
#define M_RDMEM(A) Z80_RDMEM(A)
#define M_WRMEM(A,V) Z80_WRMEM(A,V)
#define M_RDOP(A) Z80_RDOP(A)
#define M_RDOP_ARG(A) Z80_RDOP_ARG(A)
#define M_RDSTACK(A) Z80_RDSTACK(A)
#define M_WRSTACK(A,V) Z80_WRSTACK(A,V)
#define DoIn(lo,hi) Z80_In((lo)+(((unsigned)(hi))<<8))
#define DoOut(lo,hi,v) Z80_Out((lo)+(((unsigned)(hi))<<8),v)
static void Interrupt(int j);
static void ei(void);
#define S_FLAG 0x80
#define Z_FLAG 0x40
#define H_FLAG 0x10
#define V_FLAG 0x04
#define N_FLAG 0x02
#define C_FLAG 0x01
#define M_SKIP_CALL R.PC.W.l+=2
#define M_SKIP_JP R.PC.W.l+=2
#define M_SKIP_JR R.PC.W.l+=1
#define M_SKIP_RET
static Z80_Regs R;
#ifdef DEBUG
int Z80_Trace=0;
int Z80_Trap=-1;
#endif
#ifdef TRACE
static unsigned pc_trace[256];
static unsigned pc_count=0;
#endif
static byte PTable[512];
static byte ZSTable[512];
static byte ZSPTable[512];
#include "Z80DAA.h"
typedef void (*opcode_fn) (void);
#define M_C (R.AF.B.l&C_FLAG)
#define M_NC (!M_C)
#define M_Z (R.AF.B.l&Z_FLAG)
#define M_NZ (!M_Z)
#define M_M (R.AF.B.l&S_FLAG)
#define M_P (!M_M)
#define M_PE (R.AF.B.l&V_FLAG)
#define M_PO (!M_PE)