/**

   Copyright Equator Technologies Incorporated, 1996.


   Name:

      linst.h

   Abstract:

      Library support for extracting/insterting instructions into instruction page(s)

   Author:

      Wim Colgate

--*/
#if !defined(_LINST_H_)
#define _LINST_H_

typedef char CHAR;
typedef char *PCHAR;
typedef unsigned char UCHAR;
typedef unsigned char *PUCHAR;

typedef short SHORT;
typedef unsigned short USHORT;

typedef long LONG;
typedef unsigned long ULONG;
typedef unsigned long *PULONG;

#if !defined(_MSC_VER)
typedef unsigned long long ULONGLONG;
typedef long long LONGLONG;
#else
typedef unsigned __int64 ULONGLONG;
#endif

/*
 * defined by the architecture
 */

#define OPERATION_BIT_SIZE 34           // full operation
#define OPERATION_BYTE_SIZE 4           // just the low portion (32 bits or longword)

#define INSTR_CAPABILITY_BITS 4         // bits per capability
#define INSTR_CAPABILITY_MASK 0xf       // mask for the above

#define INSTR_PAGE_SIZE       0x100
#define INSTR_PAGE_CODE_START 0x20
#define INSTR_RESERVED        0x4

/*
 * define maximum number of elements in the code section
 */

#define MAX_OPERATIONS ((INSTR_PAGE_SIZE - INSTR_PAGE_CODE_START) / OPERATION_BYTE_SIZE)

/*
 * define fetching the 4 capability bits, based on beginning of 
 * instruction page & Index into instruction page
 */

#define FETCH_CAPABILITY_BITS(Base, Index)                                  \
   ((Base->Capabilities[INSTR_RESERVED+(Index/2)] >> (Index & 1 ? INSTR_CAPABILITY_BITS : 0)) & INSTR_CAPABILITY_MASK);

#define SET_CAPABILITY_BITS(Base, Index, Bits)                              \
   Base->Capabilities[INSTR_RESERVED+(Index/2)] =                           \
        (UCHAR)(Base->Capabilities[INSTR_RESERVED+(Index/2)] & ((Index & 1) ? 0x0f : 0xf0)) | \
        (UCHAR)(Bits << ((Index & 1) ? INSTR_CAPABILITY_BITS : 0));

/*
 * issue unit are the two high bits of the capability
 */

#define EXTRACT_CAPABILITY_ISSUE_UNIT(Value)                               \
   (Value >> 2)

/*
 * high two bits of instruction are the two low bits of the capability
 */

#define EXTRACT_CAPABILITY_HIGH_INSTRUCTION_BITS(Value)                    \
   (Value & 3)

#define MNOP 0

/*
 * define the instruction page
 */

typedef struct _INSTRUCTION_PAGE {
   UCHAR Capabilities[INSTR_PAGE_CODE_START];
   ULONG Code[MAX_OPERATIONS];
} INSTRUCTION_PAGE, *PINSTRUCTION_PAGE;

#endif
