/*****************************************************************************/
/*                                                                           */
/*   VECTREX HP3000 Software Emulator              Copyright K.Wilkins 1996  */
/*                                                                           */
/*****************************************************************************/
/*                                                                           */
/*   Title      : 6809 Emulator module header file (prototype & declaration) */
/*                                                                           */
/*   File Name  : EMU6809.H                                                  */
/*                                                                           */
/*   Author     : Keith Wilkins / C.S.                                       */
/*                                                                           */
/*   Version    : 1.20                                                       */
/*                                                                           */
/*   Desciption : This file contains all of the function prototypes and      */
/*                definitions for the 6809 emulator module.                  */
/*                                                                           */
/*****************************************************************************/
/*                                                                           */
/*   Revision History:                                                       */
/*                                                                           */
/*   Version    Date    Who  Description of changes                          */
/*   -------    ----    ---  ----------------------                          */
/*                                                                           */
/*    0.01    14/03/93  K.W  Creation of empty file.                         */
/*    1.00    05/08/96  K.W  Public release of DVE V1.0                      */
/*    1.20    20/10/96  C.S  DVE V1.20                                       */
/*                                                                           */
/*****************************************************************************/

#if !defined EMU6809_H
    #define EMU6809_H

#include <standard.h>

/* Useful defines */

#define CPU_MEMORY_SIZE     65536
#define CPU_MAX_HANDLERS    20

#define CPU_UNMAPPED_FILL   0xff


//
// Define a static memory space for "straight" memory applications
//
extern T_UCHAR atSystemImage[CPU_MEMORY_SIZE];

// **********************************************
//
// 6809 CPU OPERATING MODES
//
// **********************************************
//
// ALL CHANGES MUST BE REFLECTED IN COD6809.ASM
//
// **********************************************

#define  CPU_FETCH         0x0000
#define  CPU_WAIT          0x00f7
#define  CPU_HALT          0x00f8
#define  CPU_DECODE        0x00f9
#define  CPU_CWAI          0x00fa
#define  CPU_SYNC          0x00fb
#define  CPU_EXCEPTION     0x00fc



// **********************************************
//
// DEFINE CC MASKS
//
// **********************************************

#define CC_C_FLAG   0x01        /* Carry       */
#define CC_V_FLAG   0x02        /* Overflow    */
#define CC_Z_FLAG   0x04        /* Zero        */
#define CC_N_FLAG   0x08        /* Negative    */
#define CC_I_FLAG   0x10        /* IRQ Mask    */
#define CC_H_FLAG   0x20        /* Half Carry  */
#define CC_F_FLAG   0x40        /* FIRQ Mask   */
#define CC_E_FLAG   0x80        /* Entire Flag */

#define CC_C_FLAGB  0xFE        /* Carry       */
#define CC_V_FLAGB  0xFD        /* Overflow    */
#define CC_Z_FLAGB  0xFB        /* Zero        */
#define CC_N_FLAGB  0xF7        /* Negative    */
#define CC_I_FLAGB  0xEF        /* IRQ Mask    */
#define CC_H_FLAGB  0xDF        /* Half Carry  */
#define CC_F_FLAGB  0xBF        /* FIRQ Mask   */
#define CC_E_FLAGB  0x7F        /* Entire Flag */


/* Define the structures used in CPU emulation */

// Old struct now unused

typedef struct tsCPUMEMORYHANDLER
{
    T_UCHAR  (*pfReadFunc)(T_UWORD);
    T_UCHAR  (*pfWriteFunc)(T_UWORD,T_UCHAR);
    T_ULONG  tReadCount;
    T_ULONG  tWriteCount;
} tsCPUMEMORYHANDLER;


// **********************************************
//
// CPU Register structure
//
// **********************************************
//
// ALL CHANGES MUST BE REFLECTED IN COD6809.ASM
//
//
// NEVER READ CC DIRECTLY AS IT MUST BE CONVERTED
// TO 6809 FORM (from 8086) BEFORE BEING USED
//
// **********************************************

typedef struct CPUREGISTERS
{
   T_UWORD       tX;         /* X  - index register           */
   T_UWORD       tPacking1;

   T_UWORD       tY;         /* Y  - index register           */
   T_UWORD       tPacking2;

   T_UWORD       tUSP;       /* U  - User Stack Pointer       */
   T_UWORD       tPacking3;

   T_UWORD       tHSP;       /* S  - Hardware Stack Pointer   */
   T_UWORD       tPacking4;

   T_UWORD       tPC;        /* PC - Program Counter          */
   T_UWORD       tPacking5;

   union
   {
       T_UWORD   tD;         /* D  - Register = A(MSB)+B(LSB) */

       struct
       {
           T_UCHAR   tB;     /* B  - Accumulator              */
           T_UCHAR   tA;     /* A  - Accumulator              */
       }sAB;
   }uABD;
   T_UWORD       tPacking6;

   T_UCHAR       tDP;        /* DP - Direct Page Register     */
   T_UCHAR       tPacking7;  /* Used for LWORD alignment      */
   T_UWORD       tPacking8;

   union
   {
      T_ULONG       tCC;     /* CC - Condition Code Register  */

      struct
      {
         T_ULONG bC  :1;       // 6809-C   CARRY
         T_ULONG bSP1:1;       //          SPARE1 - Always 1
         T_ULONG bPAR:1;       //          PARITY
         T_ULONG bSP2:1;       //          SPARE2 - Always 0
         T_ULONG bH  :1;       // 6809-H   AUX CARRY
         T_ULONG bSP3:1;       //          SPARE3 - Always 0
         T_ULONG bZ  :1;       // 6809-Z   ZERO FLAG
         T_ULONG bN  :1;       // 6809-N   SIGN FLAG
         T_ULONG bTRP:1;       //          TRAP FLAG
         T_ULONG bIEN:1;       //          INTERRUPT ENABLE
         T_ULONG bDIR:1;       //          DIRECTION FLAG
         T_ULONG bV  :1;       // 6809-V   OVERFLOW FLAG
         T_ULONG bIOP:2;       //          IO PRIVELIDGE FLAG
         T_ULONG bNT :1;       //          NESTED TASK FLAG
         T_ULONG bSP4:1;       //          SPARE4 - Always 0
         T_ULONG bSP5:16;      // Unused upper word
      }sCC;
   }uCC8086;

   union
   {
      T_UWORD       tCC;    /* CC - Code condition register */

      struct
      {
         T_UWORD bC  :1;
         T_UWORD bV  :1;
         T_UWORD bZ  :1;
         T_UWORD bN  :1;
         T_UWORD bI  :1;
         T_UWORD bH  :1;
         T_UWORD bF  :1;
         T_UWORD bE  :1;
      }sCC;
   }uCC;
   T_UWORD       tPacking9;

   T_INT           tNMIFlag;   /* Hardware NMI Line status */
   T_INT           tIRQFlag;   /* Hardware IRQ Line status */
   T_INT           tFIRQFlag;  /* Hardware FIRQ Line status */

}CPUREGISTERS;


/* Function prototypes */
#define         f6809FastAddressRead(addr)   (atSystemImage[addr])

T_INT           f6809Init(T_VOID);
T_VOID          f6809Reset(T_VOID);
T_VOID          f6809Tick(T_VOID);
//T_VOID        f6809MultiTick(T_VOID);
T_UWORD f6809LastInsAddr(T_VOID);
T_UWORD f6809StatusRead(T_VOID);
T_VOID  f6809StatusWrite(T_UWORD tStat);
T_VOID  f6809SetBreakpoint(T_UWORD tBreakpoint,T_UWORD tSkip);
T_VOID  f6809ClearBreakpoint(T_VOID);
T_VOID  f6809ReadBreakpoint(T_PUWORD tBreakpoint,T_PUWORD tSkip,T_PUWORD tEnable);
T_INT   f6809DeclareAddress(T_UWORD tAddrBase,T_UWORD tSize,T_UCHAR (*pfReadFunc)(T_UWORD),T_UCHAR (*pfWriteFunc)(T_UWORD,T_UCHAR));
T_VOID  f6809RegistersRead(CPUREGISTERS *pts6809Registers);
T_VOID  f6809RegistersWrite(CPUREGISTERS *pts6809Registers);
T_VOID  set_emu6809_functions(T_INT type);

extern T_UCHAR (* f6809AddressRead)(T_UWORD);
extern T_UCHAR (* f6809AddressWrite)(T_UWORD,T_UCHAR);

// ASM Functions
T_VOID     f6809Init8086CC(T_VOID);
T_UWORD    f6809IRQ(T_VOID);
T_UWORD    f6809FIRQ(T_VOID);

extern T_INT   iBPTriggered;
extern T_UWORD iInstruction;
extern T_SWORD iCount;
extern T_UWORD i6809status;
extern T_UWORD iLastAddress;
extern T_UWORD iBreakpoint;
extern T_UWORD iBreakpointEnable;
extern T_UWORD iSkipCount;

extern CPUREGISTERS  tsCPURegisters;
extern T_SWORD cycle_count[];
extern const T_UWORD (*apfExecuteInstruction[0x300])(T_VOID);
extern const T_SWORD packed_cycle_count[];

#endif
