#ifndef IN_GENERATOR_H
#define IN_GENERATOR_H

#include "machine.h"

/*-------------------- 2003.07.08 17:23 ------------------------
 * hack to fix endianness under CygWin.  Might not be an
 * actuall issue with cygwin, but rather with the configure
 * scripts that I use... :(  This is a bad, bad hack,
 * it needs to go away!
 * ----------------------------------------------------------*/
#ifdef __CYGWIN__

 #undef WORDS_BIGENDIAN
 #undef BIG_ENDIAN
 #ifndef LITTLE_ENDIAN
  #define LITTLE_ENDIAN 1
 #endif

#endif



#define VERSTRING VERSION
#define PROGNAME LisaEmulator

#define LEN_IPCLISTTABLE 4*1024

extern char gen_leafname[];

#ifdef WORDS_BIGENDIAN
#define LOCENDIAN16(y) (y)
#define LOCENDIAN32(y) (y)
#else
#define LOCENDIAN16(y) ((((y)>>8)&0x00FF)+((((y)<<8)&0xFF00)))


#define LOCENDIAN32(y) ( (((y)>>24) & 0x000000FF) + \
			 (((y)>>8)  & 0x0000FF00) + \
			 (((y)<<8)  & 0x00FF0000) + \
			 (((y)<<24) & 0xFF000000) )
#endif

#define SWAP16(y) ((((y)>>8)&0x00FF)+((((y)<<8)&0xFF00)))
#define SWAP32(y) ( (((y)>>24) & 0x000000FF) + \
		    (((y)>>8)  & 0x0000FF00) + \
		    (((y)<<8)  & 0x00FF0000) + \
		    (((y)<<24) & 0xFF000000) )

typedef enum {
	tp_src, tp_dst
} t_type;

typedef enum {
	sz_none, sz_byte, sz_word, sz_long
} t_size;

typedef enum {
	dt_Dreg, dt_Areg, dt_Aind, dt_Ainc, dt_Adec, dt_Adis, dt_Aidx,
	dt_AbsW, dt_AbsL, dt_Pdis, dt_Pidx,
	dt_ImmB, dt_ImmW, dt_ImmL, dt_ImmS,
	dt_Imm3, dt_Imm4, dt_Imm8, dt_Imm8s, dt_ImmV,
    dt_Ill
} t_datatype;

typedef enum {
	ea_Dreg, ea_Areg, ea_Aind, ea_Ainc, ea_Adec, ea_Adis, ea_Aidx,
	ea_AbsW, ea_AbsL, ea_Pdis, ea_Pidx, ea_Imm
} t_eatypes;

typedef enum {
	i_ILLG,
	i_OR, i_ORSR,
	i_AND, i_ANDSR,
	i_EOR, i_EORSR,
	i_SUB, i_SUBA, i_SUBX,
	i_ADD, i_ADDA, i_ADDX,
	i_MULU, i_MULS,
	i_CMP, i_CMPA,
	i_BTST, i_BCHG, i_BCLR, i_BSET,
	i_MOVE, i_MOVEA,
	i_MOVEPMR, i_MOVEPRM,
	i_MOVEFSR, i_MOVETSR,
	i_MOVEMRM, i_MOVEMMR,
	i_MOVETUSP, i_MOVEFUSP,
	i_NEG, i_NEGX, i_CLR, i_NOT,
	i_ABCD, i_SBCD, i_NBCD,
	i_SWAP,
	i_PEA, i_LEA,
	i_EXT, i_EXG,
	i_TST, i_TAS, i_CHK,
	i_TRAPV, i_TRAP, i_RESET, i_NOP, i_STOP,
	i_LINK, i_UNLK,
	i_RTE, i_RTS, i_RTR,
	i_JSR, i_JMP, i_Scc, i_SF, i_DBcc, i_DBRA, i_Bcc, i_BSR,
	i_DIVU, i_DIVS,
	i_ASR, i_LSR, i_ROXR, i_ROR,
	i_ASL, i_LSL, i_ROXL, i_ROL,
	i_LINE10, i_LINE15
} t_mnemonic;

typedef struct {
	uint16 mask;              /* mask of bits that are static */
	uint16 bits;              /* bit values corresponding to bits in mask */
	t_mnemonic mnemonic;      /* instruction mnemonic */
	struct {
		int priv:1;             /* instruction is privileged if set */
		int endblk:1;           /* instruction ends a block if set */
		int imm_notzero:1;      /* immediate data cannot be 0 (if applicable) */
		int used:5;             /* bitmap of XNZVC flags inspected */
		int set:5;              /* bitmap of XNZVC flags altered */
	} flags;
	t_size size;              /* size of instruction */
	t_datatype stype;         /* type of source */
	t_datatype dtype;         /* type of destination */
	unsigned int sbitpos:4;   /* bit pos of imm data or reg part of EA */
	unsigned int dbitpos:4;   /* reg part of EA */
	unsigned int immvalue;    /* if stype is ImmS this is the value */
	unsigned int cc;          /* condition code if mnemonic is Scc/Dbcc/Bcc */
	unsigned int funcnum;     /* function number for this instruction */
	unsigned int wordlen;     /* length in words of this instruction */
	unsigned int clocks;      /* number of external clock periods */
} t_iib;                    /* instruction information block */

#define IIB_FLAG_X 1<<0
#define IIB_FLAG_N 1<<1
#define IIB_FLAG_Z 1<<2
#define IIB_FLAG_V 1<<3
#define IIB_FLAG_C 1<<4

typedef struct {
	t_mnemonic mnemonic;
	const char *name;
} t_mnemonic_table;

extern t_mnemonic_table mnemonic_table[];

extern char *condition_table[];

typedef union {                   // Possible bug  BYTES_HIGHFIRST is not dealt with in autoconf???!!!
	struct {
#ifndef BYTES_HIGHFIRST
        uint16 c:1;               // this should be 1   as per MC68000 book fig 1-3 status reg.
        uint16 v:1;               // this should be 2
        uint16 z:1;               // this should be 4   // these must be uint16, and not unsigned int else the struct/union
        uint16 n:1;               // this should be 8   // will fail to line up!
        uint16 x:1;               // this should be 16
        uint16 :3;                // 32.64.128
        uint16 i0:1;              // 256,512,1024
        uint16 i1:1;
        uint16 i2:1;
        uint16 :2;                //2048,4096
        uint16 s:1;               //8192
        uint16 :1;                //16384
        uint16 t:1;               //32768
#else
        uint16 t:1;               // I believe this section is correct for sparc
        uint16 :1;
        uint16 s:1;
        uint16 :2;
        uint16 i2:1;
        uint16 i1:1;
        uint16 i0:1;
        uint16 :3;
        uint16 x:1;              // this should be 16
        uint16 n:1;              // this should be 8
        uint16 z:1;              // this should be 4
        uint16 v:1;              // this should be 2
        uint16 c:1;              // this should be 1
#endif
	} sr_struct;
	uint16 sr_int;
} t_sr;

typedef struct {
	uint32 pc;
	uint32 sp;
	t_sr sr;
	uint16 stop;
	uint32 regs[16];
	uint16 pending;
} t_regs;

#define SR_CFLAG (1<<0)
#define SR_VFLAG (1<<1)
#define SR_ZFLAG (1<<2)
#define SR_NFLAG (1<<3)
#define SR_XFLAG (1<<4)
#define SR_SFLAG (1<<13)
#define SR_TFLAG (1<<15)

#define LOG_DEBUG3(x)   /* */
#define LOG_DEBUG2(x)   /* */
#define LOG_DEBUG1(x)   /* */
// next 5lines fixed by RA for Lisa emulator
#define LOG_USER(fmt, args... )     ui_log_user(fmt,## args)
#define LOG_VERBOSE(fmt, args... )  ui_log_verbose(fmt,## args)
#define LOG_NORMAL(fmt, args... )   ui_log_normal(fmt,## args)
#define LOG_CRITICAL(fmt, args... ) ui_log_critical(fmt,## args)
#define LOG_REQUEST(fmt, args... )  ui_log_request(fmt,## args)

#endif


