/* -*- tab-width: 4 -*- */
/******************************************************************************      
 *
 *	Copyright 2004 The Orion Compiler Group. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer. 
 * 2. Redistributions in binary form must reproduce the above copyright notice, 
 *    this list of conditions and the following disclaimer in the documentation 
 *    and/or other materials provided with the distribution. 
 *
 * THIS SOFTWARE IS PROVIDED BY THE ORION COMPILER GROUP ``AS IS'' AND ANY 
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
 * DISCLAIMED. IN NO EVENT SHALL THE ORION COMPILER GROUP OR CONTRIBUTORS BE 
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGE.
 *
 * The views and conclusions contained in the software and documentation are 
 * those of the authors and should not be interpreted as representing official 
 * policies, either expressed or implied, of the Orion Compiler Group.
 *
 ******************************************************************************/

// For the curious, tabs are set to 1, 5, 9, etc... Do not modify and resubmit
// with spaces. It makes the code harder to merge in changes.

// This module should be included with all Z80 recompilations

#ifndef _Z80STUB_H_
#define _Z80STUB_H_

typedef union
{
	UINT32 AF;

	struct
	{
#ifdef ORION_BIG_ENDIAN
		UINT16 wFiller;
		UINT8 A;
		UINT8 F;
#else
		UINT8 F;
		UINT8 A;
		UINT16 wFiller;
#endif
	} half;
} reg_af;

#define	Z80AF	Z80.AF.AF
#define	Z80A	Z80.AF.half.A
#define	Z80F	Z80.AF.half.F

typedef union
{
	UINT32 BC;

	struct
	{
#ifdef ORION_BIG_ENDIAN
		UINT16 wFiller;
		UINT8 B;
		UINT8 C;
#else
		UINT8 C;
		UINT8 B;
		UINT16 wFiller;
#endif
	} half;
} reg_bc;

#define	Z80BC	Z80.BC.BC
#define	Z80B	Z80.BC.half.B
#define	Z80C	Z80.BC.half.C

typedef union
{
	UINT32 DE;

	struct
	{
#ifdef ORION_BIG_ENDIAN
		UINT16 wFiller;
		UINT8 D;
		UINT8 E;
#else
		UINT8 E;
		UINT8 D;
		UINT16 wFiller;
#endif
	} half;
} reg_de;

#define	Z80DE	Z80.DE.DE
#define	Z80D	Z80.DE.half.D
#define	Z80E	Z80.DE.half.E

typedef union
{
	UINT32 HL;

	struct
	{
#ifdef ORION_BIG_ENDIAN
		UINT16 wFiller;
		UINT8 H;
		UINT8 L;
#else
		UINT8 L;
		UINT8 H;
		UINT16 wFiller;
#endif
	} half;
} reg_hl;

#define	Z80HL	Z80.HL.HL
#define	Z80H	Z80.HL.half.H
#define	Z80L	Z80.HL.half.L

typedef union
{
	UINT32 SP;

	struct
	{
#ifdef ORION_BIG_ENDIAN
		UINT16 wFiller;
		UINT8 SH;
		UINT8 SL;
#else
		UINT8 SL;
		UINT8 SH;
		UINT16 wFiller;
#endif
	} half;
} reg_sp;

#define	Z80SP	Z80.SP.SP
#define Z80SH	Z80.SP.half.SH
#define Z80SL	Z80.SP.half.SL

typedef union
{
	UINT32 IX;

	struct
	{
#ifdef ORION_BIG_ENDIAN
		UINT16 wFiller;
		UINT8 XH;
		UINT8 XL;
#else
		UINT8 XL;
		UINT8 XH;
		UINT16 wFiller;
#endif
	} half;
} reg_ix;

#define	Z80IX	Z80.IX.IX
#define	Z80XH	Z80.IX.half.XH
#define	Z80XL	Z80.IX.half.XL

typedef union
{
	UINT32 IY;

	struct
	{
#ifdef ORION_BIG_ENDIAN
		UINT16 wFiller;
		UINT8 YH;
		UINT8 YL;
#else
		UINT8 YL;
		UINT8 YH;
		UINT16 wFiller;
#endif
	} half;
} reg_iy;

#define	Z80IY	Z80.IY.IY
#define	Z80YH	Z80.IY.half.YH
#define	Z80YL	Z80.IY.half.YL

typedef struct z80context
{
	UINT8 *Base;
#define Z80Base Z80.Base
	UINT8 *MapRead;
	UINT8 *MapWrite;
	struct MemoryReadByte *MemRead;
	struct MemoryWriteByte *MemWrite;
	struct PortRead *IoRead;
	struct PortWrite *IoWrite;
	UINT32 clockticks;
#define Z80clockticks Z80.clockticks
	UINT32 iff;
#define Z80iff Z80.iff
	UINT32 interruptMode;
#define Z80interruptMode Z80.interruptMode
	UINT32 halted;
#define Z80halted Z80.halted

	reg_af AF;
	reg_bc BC;
	reg_de DE;
	reg_hl HL;
	UINT32 afprime;
#define Z80afprime Z80.afprime
	UINT32 bcprime;
#define Z80bcprime Z80.bcprime
	UINT32 deprime;
#define Z80deprime Z80.deprime
	UINT32 hlprime;
#define Z80hlprime Z80.hlprime
	reg_ix IX;
	reg_iy IY;
	reg_sp SP;
	UINT32 PC;
#define Z80PC Z80.PC
	UINT32 nmiAddr;
#define Z80nmiAddr Z80.nmiAddr
	UINT32 intAddr;
#define Z80intAddr Z80.intAddr
	UINT32 rCounter;
#define Z80rCounter Z80.rCounter
  //UINT32 intAddr;
  //UINT32 nmiAddr;
	UINT8 i;
#define Z80i Z80.i
	UINT8 r;
#define Z80r Z80.r
	UINT8 intPending;
	UINT8 u8085InterruptMask;
} z80context;

typedef struct MemoryWriteByte {
  UINT32 lowAddr;
  UINT32 highAddr;
  void (*memoryCall)(UINT32, UINT8, struct MemoryWriteByte *);
  void *pUserArea;
} MemoryWriteByte;

typedef struct MemoryReadByte {
  UINT32 lowAddr;
  UINT32 highAddr;
  UINT8 (*memoryCall)(UINT32, struct MemoryReadByte *);
  void *pUserArea;
} MemoryReadByte;

typedef struct z80PortWrite {
  UINT16 lowIoAddr;
  UINT16 highIoAddr;
  void (*IOCall)(UINT16, UINT8, struct z80PortWrite *);
  void *pUserArea;
} z80PortWrite;

typedef struct z80PortRead {
  UINT16 lowIoAddr;
  UINT16 highIoAddr;
  UINT16 (*IOCall)(UINT16, struct z80PortRead *);
  void *pUserArea;
} z80PortRead;

typedef struct z80TrapRec {
  UINT16 trapAddr;
  UINT8 skipCnt;
  UINT8 origIns;
} z80TrapRec;

typedef struct mz80context {
  UINT8 *z80Base;
  MemoryReadByte *z80MemRead;
  MemoryWriteByte *z80MemWrite;
  z80PortRead *z80IoRead;
  z80PortWrite *z80IoWrite;
  UINT32 z80nmiAddr;
  UINT32 z80intAddr;
} mz80context;

//mz80context RETRO_PACKED;

// Z80 Flags

#define Z80_FLAG_C		0x01
#define Z80_FLAG_N		0x02
#define Z80_FLAG_PARITY	0x04
#define Z80_FLAG_OVERFLOW 0x04
#define Z80_FLAG_PV		0x04
#define Z80_FLAG_BIT3	0x08
#define Z80_FLAG_H		0x10
#define Z80_FLAG_BIT5	0x20
#define Z80_FLAG_Z		0x40
#define Z80_FLAG_S		0x80

#define Z80_FLAG_IFF1	0x01
#define Z80_FLAG_IFF2	0x02

// Support tables for the z80

extern const UINT8 g_u8SignZeroNegTable[0x100];
extern const UINT8 g_u8SignZeroTable[0x100];
extern const UINT8 g_u8PostIncFlags[0x100];
extern const UINT8 g_u8PostDecFlags[0x100];
extern const UINT8 g_u8PostORFlags[0x100];
extern const UINT8 g_u8PostANDFlags[0x100];
extern const UINT16 sg_u16DAATable[0x800];
extern const UINT8 sg_u8INTTiming[3];

#endif
