/***********************************************************************
*
* asmdef.h - Assembler header for the IBM 7090 computer.
*
* Changes:
*   05/21/03   DGP   Original.
*   08/20/03   DGP   Changed to call the SLR(1) parser.
*   12/08/04   DGP   Started adding MAP pseudo ops.
*	
***********************************************************************/

#include <stdio.h>

/*
** Definitions
*/

#define NORMAL 0
#define ABORT  12

#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif

#define VERSION "2.1.4"

#define IBSYSSYM   '$'		/* Begins an IBSYS control card */
#define COMMENTSYM '*'		/* Begins a comment */
#define INDIRECTSYM '*'		/* Indirect addressing symbol */
#define LITERALSYM '='		/* Begins a literal */

#define SYMSTART 0		/* Start of name field */
#define OPCSTART 7		/* Start of opcode field */
#define VARSTART 15		/* Start of variable field */
#define NOOPERAND 16		/* If we get this far, no variable field */
#define RIGHTMARGIN 71		/* End of variable field */

#define NARROWPRINTMARGIN 49	/* Narrow mode print margin */
#define NARROWTITLELEN 23	/* Narrow mode title length */
#define WIDETITLELEN 57		/* Wide mode title length */

#define MAXLINE 2048		/* Max length of source line, w/ ETCs  */
#define MAXSRCLINE 90		/* Max length of a single source line */

#define TTLSIZE 60		/* Max length of TTL */
#define MAXLBLLEN 8		/* Max length of LBL */
#define MAXMACNAMELEN 6		/* Max length of MACRO name */
#define MAXSYMLEN 6		/* Max length of symbol */
#define MAXFIELDSIZE 80		/* Max length of a MACRO field */

#define LINESPAGE 55		/* Max lines on a listing page */

#define MAXERRORS 3000		/* Max errors in assembly */

#define MAXDUPLINES 1000	/* Max DUP lines */
#define MAXMACROLINES 1000	/* Max MACRO lines */
#define MAXETCLINES 32		/* Max ETC lines */

#define MAXMACROS 1000		/* Max MACROs in an assembly */
#define MAXMACARGS 63		/* Max MACRO args */

#define MAXQUALS 32		/* Max QUALs in an assembly */
#define MAXBEGINS 32		/* Max BEGINs in an assembly */
#define MAXUSES   32		/* Max USEs in an assembly */
#define MAXHEADS  10		/* Max HEADs in an assembly */

#define MAXSYMBOLS 4000		/* Max symbols in an assembly */
#define MAXDEFOPS  2000		/* Max defined opcodes in an assembly */

#define FAPCOMMONSTART 077461	/* Start of COMMON in FMS (FAP) */

#define TEMPSPEC "asXXXXXX"

/*
** Object output formats
*/

#define OBJFORMAT "%c%4.4o%2.2o%1o%5.5o"
#define OBJAFORMAT "%c%1o%5.5o%1o%5.5o"
#define OBJDFORMAT "%c%4.4o%2.2o%6.6o"
#define OBJFFORMAT "%c%4.4o%8.8o"
#define OBJCHANFORMAT "%c%2.2o%4.4o%1.1o%5.5o"
#define OBJDISKFORMAT "%c%4.4o%4.4o%4.4o"
#define OBJSYMFORMAT "%c%-6.6s %5.5o"
#define OCTLFORMAT "%c%12.12llo"
#define OCT1FORMAT "%c%2.2o%10.10o"
#define OCT2FORMAT "%c%6.6o%6.6o"
#define WORDFORMAT "%c%12.12o"
#define SEQFORMAT "%4.4d\n"

/*
** Listing formats
*/

#define H1FORMAT     "ASM7090 %-8.8s  %-24.24s  %s Page %04d\n" 
#define H1WIDEFORMAT "ASM7090 %-8.8s  %-58.58s  %s Page %04d\n" 
#define H2FORMAT "%s\n\n"

#define L1FORMAT " %s  %s  %4d%c %s"
#define L2FORMAT " %s  %s\n"

#define PCBLANKS "     "
#define PCFORMAT "%05o"

#define OPBLANKS "                "
#define OPFORMAT "%c%4.4o %2.2o %1o %5.5o"
#define OPAFORMAT "%c%1o %5.5o %1o %5.5o"
#define OPDFORMAT "%c%4.4o %2.2o  %6.6o"
#define OPFFORMAT "%c%4.4o%8.8o   "
#define OPCHANFORMAT "%c%2.2o %4.4o %1o %5.5o"
#define OPDISKFORMAT " %4.4o %4.4o %4.4o "
#define ADDRFORMAT "           %5.5o"
#define BOOLFORMAT "          %6.6o"
#define CHAR1FORMAT "%2.2o"
#define OPLFORMAT "%c%12.12llo   "
#define OP1FORMAT "%c%2.2o%10.10o   "
#define OP2FORMAT "%c%6.6o%6.6o   "
#define LITFORMAT " %s  %s  %s\n"

#define SYMFORMAT " %-6.6s   %5.5o%c  "
#define BSYMFORMAT " %-6.6s  %6.6o%c  "

/*
** Modes for processing
*/

#define GENINST 0x00000001
#define DUPINST 0x00000002
#define SKPINST 0x00000010
#define CONTINU 0x00000020
#define MACDEF  0x00001000
#define MACEXP  0x00002000
#define MACCALL 0x00004000
#define CALL    0x00010000
#define RETURN  0x00020000
#define SAVE    0x00040000
#define CTLCARD 0x00100000

/*
** Data type definitions
*/

#define int8            char
#define int16           short
#define int32           int
typedef int             t_stat;                         /* status */
typedef int             t_bool;                         /* boolean */
typedef unsigned int8   uint8;
typedef unsigned int16  uint16;
typedef unsigned int32  uint32, t_addr;                 /* address */

#if defined (WIN32)                                     /* Windows */
#define t_int64 __int64
#elif defined (__ALPHA) && defined (VMS)                /* Alpha VMS */
#define t_int64 __int64
#elif defined (__ALPHA) && defined (__unix__)           /* Alpha UNIX */
#define t_int64 long
#else                                                   /* default GCC */
#define t_int64 long long
#endif                                                  /* end OS's */
typedef unsigned t_int64        t_uint64, t_value;      /* value */
typedef t_int64                 t_svalue;               /* signed value */

/*
** OpCode table definitions
*/

#define NUMOPS 448

/* Opcode types */

enum optypes
{
   TYPE_A=1,	/* O DDDDD T AAAAA */
   TYPE_B,	/* OOOO FF T AAAAA */
   TYPE_C,	/* OOOO CC T AAAAA */
   TYPE_D,	/* OOOO FF  MMMMMM */
   TYPE_E,	/* OOOO FF T OOOOO */
   TYPE_CHAN,   /* OO DDDD T AAAAA */
   TYPE_DISK,   /* OOOO DDDD AAAAA */
   TYPE_P  	/* Pseudo op */
};

/* Pseudo ops */

enum psops
{
   ABS_T=1,  BCD_T,    BCI_T,    BEGIN_T,  BES_T,    BFT_T,    BNT_T,
   BOOL_T,   BSS_T,    CALL_T,   COMMON_T, CONTRL_T, COUNT_T,  DEC_T,
   DETAIL_T, DUP_T,    END_T,    ENDM_T,   ENDQ_T,   ENT_T,    EJE_T,
   EQU_T,    ETC_T,    EVEN_T,   EXT_T,    FILE_T,   FUL_T,    GOTO_T,
   HEAD_T,   IIB_T,    IFF_T,    IFT_T,    INDEX_T,  IRP_T,    KEEP_T,
   LABEL_T,  LBL_T,    LBOOL_T,  LDIR_T,   LIST_T,   LIT_T,    LITORG_T,
   LOC_T,    LORG_T,   MACRO_T,  MAX_T,    MIN_T,    NOCRS_T,  NULL_T,
   OCT_T,    OPD_T,    OPSYN_T,  OPVFD_T,  ORG_T,    ORGCRS_T, PCC_T,
   PCG_T,    PMC_T,    PUNCH_T,  PURGE_T,  QUAL_T,   RIB_T,    RBOOL_T,
   REF_T,    REM_T,    RETURN_T, SAVE_T,   SAVEN_T,  SET_T,    SIB_T,
   SPC_T,    SST_T,    TCD_T,    TITLE_T,  TTL_T,    UNLIST_T, UNPNCH_T,
   USE_T,    VFD_T
};

/* OpCode table definition */

typedef struct
{
   char *opcode;
   unsigned opvalue;
   unsigned opmod;
   int optype;
   int model;
} OpCode;

/* User defined OpCode table definition */

typedef struct Op_DefCode
{
   struct Op_DefCode *next;
   char opcode[MAXSYMLEN+2];
   unsigned opvalue;
   unsigned opmod;
   int optype;
   int model;
} OpDefCode;

/* Macro expansion lines */

typedef struct Mac_Lines
{
   struct Mac_Lines *next;
   char label[MAXFIELDSIZE];
   char opcode[MAXFIELDSIZE];
   char operand[MAXSRCLINE];
} MacLines;

/* Macro template definition */

typedef struct
{
   char macname[MAXMACNAMELEN+2];
   int macargcount;
   int maclinecount;
   int macindirect;
   char macargs[MAXMACARGS][MAXFIELDSIZE];
   MacLines *maclines[MAXMACROLINES];
} MacDef;

/*
** Symbol table definitions
*/

/* Xref entry */

typedef struct Xref_Node
{
   struct Xref_Node *next;
   int line;
} XrefNode;

/* Symbol table entry */

typedef struct Sym_Node
{
   struct Sym_Node *next;
   XrefNode *xref_head;
   XrefNode *xref_tail;
   struct Sym_Node *vsym;
   char symbol[MAXFIELDSIZE];
   char qualifier[MAXFIELDSIZE];
   int value;
   int relocatable;
   int external;
   int noexport;
   int global;
   int sglobal;
   int locctr;
   int line;
   int bool;
   int lrbool;
   int rbool;
   int setvar;
} SymNode;

/* MONSYM SysDefs table definition */

typedef struct
{
   char *name;
   char *qual;
   int val;
} SysDefs;

/*
** IF[FT] relations
*/

enum relation
{
   EQ = 1,
   GT,
   LT
};

/*
** IF[FT] 
*/

enum conditional
{
   IFOR = 1,
   IFAND
};

/*
** Expression types for parser/scanner
*/

enum exprtypes
{
   ADDREXPR = 1,
   BOOLEXPR,
   DATAEXPR
};

#define EXPRTYPEMASK 007
#define ADDRVALUE    000
#define BOOLVALUE    010
#define DATAVALUE    020

/*
** BEGIN/USE table
*/

typedef struct
{
   char symbol[MAXSYMLEN+2];
   int  chain;
   int  value;
   int  bvalue;
} BeginTable;

/*
** Object tags
*/

#define IDT_TAG		'0'	/* 0SSSSSS0LLLLL */
#define ABSENTRY_TAG	'1'	/* 10000000AAAAA */
#define RELENTRY_TAG	'2'	/* 20000000RRRRR */
#define ABSEXTRN_TAG	'3'	/* 3SSSSSS0RRRRR */
#define RELEXTRN_TAG	'4'	/* 4SSSSSS0RRRRR */
#define ABSGLOBAL_TAG	'5'	/* 5SSSSSS0RRRRR */
#define RELGLOBAL_TAG	'6'	/* 6SSSSSS0RRRRR */
#define ABSORG_TAG	'7'	/* 70000000AAAAA */
#define RELORG_TAG	'8'	/* 80000000RRRRR */
#define ABSDATA_TAG	'9'	/* 9AAAAAAAAAAAA */
#define RELADDR_TAG 	'A'	/* AAAAAAAARRRRR */
#define RELDECR_TAG 	'B'	/* BARRRRRAAAAAA */
#define RELBOTH_TAG 	'C'	/* CARRRRRARRRRR */
#define BSS_TAG		'D'     /* D0000000PPPPP */
#define ABSXFER_TAG	'E'	/* E0000000RRRRR */
#define RELXFER_TAG	'F'	/* F0000000RRRRR */
#define EVEN_TAG	'G'	/* G0000000RRRRR */
#define FAPCOMMON_TAG	'H'	/* H0000000AAAAA */

/* Where:
 *    SSSSSS - Symbol
 *    LLLLLL - Length of module
 *    AAAAAA - Absolute field
 *    RRRRRR - Relocatable field
*/

#define CHARSPERREC	66	/* Chars per object record */
#define WORDTAGLEN	13	/* Word + Object Tag length */
#define EXTRNLEN	13	/* Tag + SYMBOL + addr */
#define GLOBALLEN	13	/* Tag + SYMBOL + addr */
#define LBLSTART        72	/* Where to put the LBL */
#define SEQUENCENUM	76	/* Where to put the sequence */

/*
** Pass 0/1 error table - pass 2 does the printing.
*/

typedef struct
{
   char *errortext;
   int errorline;
} ErrTable;

/*
** Parser definitions
*/

#include "asm7090.tok"

typedef uint8  tchar;  /* 0..255 */
typedef uint8  pstate; /* 0..255 */
typedef uint16 toktyp; /* 0..0x7F */
typedef int    tokval;

#define TOKENLEN  80 /* symbol and string length */
#define VALUEZERO 0

/*
** Token types from tokscan
*/

enum toktypes
{
   PC = 30,
   LITERAL,
   SNGLFNUM,
   DBLFNUM,
   SNGLBNUM,
   DBLBNUM,
   EOL
};

#define PCSYMBOL ASTER
 
/*
** Bit masks
*/

#ifdef WIN32
#define SIGNMASK 0400000000000I64
#else
#define SIGNMASK 0400000000000ULL
#endif

/*
** External definitions
*/

extern void definemonsyms (int);
extern void definejobsyms (void);

extern int asmpass0 (FILE *, FILE *);

extern int asmpass1 (FILE *, int);
extern int chkerror (int);

extern int asmpass2 (FILE *, FILE *, int, FILE *);

extern OpCode *oplookup (char *);
extern void freeopd (OpDefCode *);
extern void opadd (char *, unsigned, unsigned, int);
extern void opdel (char *);

extern void logerror (char *);
extern void Parse_Error (int, int, int);
extern char *tokscan (char *, char **, int *, int *, char *);
extern void freexref (XrefNode *);
extern void freesym (SymNode *);
extern SymNode *symlookup (char *, char *, int, int);
extern SymNode *entsymlookup (char *, char *, int, int);
extern SymNode *symlocate (char *, int *);
extern tokval symparse (char *, char *, int *, int, int);
extern void symdelete (SymNode *);
extern char *exprscan (char *, int *, char *, int *, int, int, int);
extern char *condexpr (char *, int *, char *);

extern tokval Parser (char *, int *, int *, int, int, int);
extern toktyp Scanner (char *, int *, tokval *, char *, char *, char *, int);

