

/*************************************************************************

                      Copyright (c) 1984 by Nick de Smith

        This software is supplied for interest and non-profit making
        purposes  only.   Under  no  circumstance  shall it be lent,
        copied or otherwise used for profit.  All  rights  regarding
        the  use  and  ownership of this software shall at all times
        remain with the author, who does not guarantee the  accuracy
        or  reliabilty  of this software and who will not accept any
        liability for its use.

        This software may not be copied or distributed  without  the
        inclusion of the above copyright notice.

        January 31st 1984

*************************************************************************/


/*************************************************************************
*									 *
*									 *
*	Program :	CAM						 *
*									 *
*	Module	:	CAM.H						 *
*									 *
*	Author	:	Nick de Smith		November/December 1982	 *
*									 *
*	Description :							 *
*			Main header file for CAM (object module		 *
*			disassembler).					 *
*									 *
*************************************************************************/

#define	r50toa	r50tla			/* Use lower case radix		*/

#define	MAX_C_STACK	5		/* Depth of CREL eval stack	*/
#define	MAX_STACK	5		/* Max number of 'un-got' items	*/

#define	global				/* Routine is called globally	*/
#define	local		static		/*   ''    '' only local	*/


/*************************************************************************
*
*
*		s y m b o l     t a b l e     e n t r i e s
*		-------------------------------------------
*
*
*************************************************************************/

#define	MAX_SEG		128		/* Maximum number of .psects	*/

typedef struct	psect_entry {		/* .psect table entry		*/

	int	p_flags;		/* Flags			*/
	int	p_name[2];		/* .psect name			*/
	unsigned p_mlength;		/* Maximum length		*/
	int	p_dot;			/* Relative PC for this psect	*/
	struct	symbol *p_symb;		/* This .psect's symbols	*/
	int	p_count;		/* Count of occurences		*/

} PSECT, *PSECT_PTR;

#ifdef	MAIN

PSECT	segtbl[MAX_SEG];		/* Table of .psects		*/

#else

extern	PSECT	segtbl[];		/* Table of .psects		*/

#endif

typedef	struct	symbol {		/* Symbol table atom		*/

	int	s_flags;		/* Flags (should be a byte)	*/
	int	s_name[2];		/* Symbol name			*/
	unsigned s_offset;		/* Offset from start of segment	*/
	struct	symbol *s_next;		/* Next symbol this .psect	*/

} SYMBOL, *SYMBOL_PTR;

#define	S_VALID		00001		/* Valid symbol in here		*/
#define	S_WEAK		00002		/* Weak definition		*/
#define	S_STRONG	00004		/* Strong definition		*/
#define	S_DREF		00010		/* Referenced as data		*/
#define	S_CREF		00020		/* Referenced as code		*/
#define	S_LOCAL		00040		/* psect local reference	*/
#define	S_EXT		00100		/* Referenced from another psect*/
#define	S_GLOBAL	00200		/* Its a global symbol		*/
#define	S_GREF		00400		/* ..but its a reference	*/
#define	S_GABS		01000		/* Absolute global definition	*/
#define	S_USED		02000		/* This symbol has been output	*/
#define	S_STB		04000		/* This one's from an STB	*/


/*************************************************************************
*
*
*		o b j e c t     r e c o r d     t y p e s
*		-----------------------------------------
*
*
*************************************************************************/

#define	T_GSD		01		/* Global symbol directory	*/
#define	T_EGSD		02		/* End of GSD			*/
#define	T_TEXT		03		/* Text information		*/
#define	T_RELD		04		/* Relocation directory		*/
#define	T_ISD		05		/* Internal symbol directory	*/
#define	T_EOM		06		/* End of module		*/


/*************************************************************************
*
*
*	    g l o b a l     s y m b o l     d i r e c t o r y
*	    -------------------------------------------------
*
*
*************************************************************************/

#define	T_MODN		000		/* Module name			*/
#define	T_CSECT		001		/* Control section name		*/
#define	T_ISN		002		/* Internal symbol name		*/
#define	T_TADDR		003		/* Transfer address		*/
#define	T_GSN		004		/* Global symbol name		*/
#define	T_PSECT		005		/* Program section name		*/
#define	T_IDENT		006		/* Program version id		*/
#define	T_MARR		007		/* Mapped array declaration	*/
#define	T_COMP		010		/* Completion routine address	*/

/*************************************************************************
*
*
*		g s n      f l a g      b i t s
*		-------------------------------
*
*
*************************************************************************/

#define	G_WEAK		001		/* Weak reference		*/
#define	G_LDEF		004		/* Library definition		*/
#define	G_DEF		010		/* Definition/Reference		*/
#define	G_REL		040		/* Relocatable/Absolute		*/

/*************************************************************************
*
*
*		p s e c t     f l a g     b i t s
*		---------------------------------
*
*
*************************************************************************/

#define	P_HIGH		0001		/* HIGH/LOW speed memory	*/
#define	P_LIB		0002		/* LIB/NOLIB			*/
#define	P_OVR		0004		/* OVR/CON			*/
#define	P_RO		0020		/* RO/RW			*/
#define	P_REL		0040		/* REL/ABS			*/
#define	P_GBL		0100		/* GBL/LCL			*/
#define	P_D		0200		/* D/I				*/

#define	P_USED		00400		/* Psect has been defined	*/
#define	P_STB		01000		/* Psect is really from an STB	*/

#define	P_ALL		(P_HIGH | P_LIB | P_OVR | P_RO | P_REL | P_GBL | P_D)


/*************************************************************************
*
*
*		r e l o c a t i o n      d i r e c t o r y
*		------------------------------------------
*
*
*************************************************************************/

#define	T_IREL		001		/* Internal relocation		*/
#define	T_GREL		002		/* Global relocation		*/
#define	T_IDREL		003		/* Internal displaced relocation*/
#define	T_GDREL		004		/* Global displaced relocation	*/
#define	T_GAREL		005		/* Global additive relocation	*/
#define	T_GADREL	006		/* Global additive disp. rel.	*/
#define	T_LDEF		007		/* Location counter definition	*/
#define	T_LMOD		010		/* Location counter modification*/
#define	T_LIMIT		011		/* .LIMIT directive		*/
#define	T_PREL		012		/* PSECT relocation		*/
#define	T_PDREL		014		/* PSECT displaced relocation	*/
#define	T_PAREL		015		/* PSECT additive relocation	*/
#define	T_PADREL	016		/* PSECT additive disp. rel.	*/
#define	T_CREL		017		/* Complex relocation (gosh!)	*/
#define	T_RLREL		020		/* Resident library relocation	*/

 
/*************************************************************************
*
*
*		c o m p l e x     r e l o c a t i o n
*		-------------------------------------
*
*
*************************************************************************/

#define	C_NOP		000		/* NOP				*/
#define	C_PLUS		001		/* Binop plus			*/
#define	C_MINUS		002		/* Binop minus			*/
#define	C_MUL		003		/* Binop multiply		*/
#define	C_DIV		004		/* Binop divide			*/
#define	C_AND		005		/* Binop bitwise AND		*/
#define	C_OR		006		/* Binop bitwise OR		*/
#define	C_UMINUS	010		/* Unary op minus		*/
#define	C_UCOMP		011		/* Unary op complement		*/
#define	C_STORE		012		/* Store result			*/
#define	C_DSTORE	013		/* Store result (displaced)	*/
#define	C_FGLOB		016		/* Fetch global			*/
#define	C_FREL		017		/* Fetch relocatable value	*/
#define	C_FCONST	020		/* Fetch constant		*/
#define	C_FRB		021		/* Fetch reslib/task base	*/

#define	MAX_C_LEN	128		/* Maximum length of one arg	*/

typedef struct c_elem {			/* CREL atom			*/

	int	c_prio;			/* Priority of this element	*/
	char	c_text[MAX_C_LEN];	/* Stacked text			*/

} C_ELEM;



/*************************************************************************
*
*
*		o u t p u t     f o r m a t     f l a g s
*		-----------------------------------------
*
*
*************************************************************************/

#define	F_LNUM		00001		/* Line number			*/
#define	F_PC		00002		/* 'PC'				*/
#define	F_IR		00004		/* Instruction register		*/
#define	F_D1		00010		/* Data field one		*/
#define	F_D2		00020		/* Data file two		*/
#define	F_LABEL		00040		/* Label field			*/
#define	F_INST		00100		/* Instruction			*/
#define	F_ARGS		00200		/* Arguments			*/
#define	F_COM		00400		/* Comments (ascii text)	*/
#define	F_PBL		01000		/* Output preceding blank line	*/
#define	F_TBL		02000		/* Output a trailing blank line	*/

#define	F_CODE		(F_PC | F_IR | F_D1 | F_D2)
#define	F_TEXT		(F_LABEL | F_INST | F_ARGS)

#define	F_DIRECT	F_INST		/* Where to put directives	*/

#define	F_ALL		(F_LNUM | F_CODE | F_TEXT | F_COM)


/*************************************************************************
*
*
*		   o u t p u t / d a t a     i t e m
*		   ---------------------------------
*
*		    a t t r i b u t e     f l a g s
*		    -------------------------------
*
*
*************************************************************************/

#define	MAX_ARGLEN	128		/* Maximum length of one arg	*/

typedef struct data {			/* Data item atom		*/

	int	d_flags;		/* Item flags (use A_???)	*/
	int	d_value;		/* 'value' of data item		*/
	char	d_text[MAX_ARGLEN];	/* Argument/relocation text	*/

} DATA, *DATA_PTR;

/*		In DATA_PTR->d_flags					*/

#define	A_OK		0000		/* Nothing special		*/
#define	A_R		0001		/* Relocatable	nnnnnn'		*/
#define	A_G		0002		/* Global	nnnnnnG		*/
#define	A_C		0004		/* Complex	nnnnnnC		*/
#define	A_B		0010		/* Byte				*/
#define	A_BSPEC		0020		/* Byte special (EMT or TRAP)	*/
#define	A_RELA		0040		/* Relocation available		*/
#define	A_VALID		0100		/* This block in use		*/
#define	A_LIMIT		0200		/* This is really a .LIMIT	*/

#define	A_DATA		(256*1)		/* Plain old data		*/
#define	A_EOM		(256*2)		/* End of module		*/
#define	A_LDEF		(256*3)		/* LDEF pending			*/
#define	A_LMOD		(256*4)		/* LMOD pending			*/

#define	A_TYPE		(A_DATA | A_EOM | A_LDEF | A_LMOD)


/*************************************************************************
*
*
*		i n p u t     b u f f e r     f o r m a t
*		-----------------------------------------
*
*
*************************************************************************/

#define	MAX_RECLEN	512		/* Absolute max buffer length	*/

typedef struct buffer {

	int	b_flags;		/* Buffer flags			*/
	int	b_next;			/* Pointer to next byte		*/
	int	b_left;			/* Number of bytes left		*/
	int	b_length;		/* Length of record		*/
	char	b_text[MAX_RECLEN];	/* Actual data			*/

} BUFFER, *BUFFER_PTR;

/*		In BUFFER_PTR->b_flags					*/

#define	R_EOM		1		/* End of module record		*/
#define	R_LDEF		2		/* LDEF pending			*/
#define	R_LMOD		3		/* LMOD pending			*/
#define	R_JUNK		4		/* Junk in buffer		*/
#define	R_TEXT		5		/* Text record			*/
#define	R_RELD		6		/* Relocation directory		*/

#define	R_RELA		(1*256)		/* Relocation available		*/


#ifdef	MAIN

char	*version = "NMdeS CAM x2.3, Mar '83";	/* Program version/id	*/

int	debug	= FALSE;		/* In debug mode		*/
int	octal	= TRUE;			/* Output the octal		*/
int	lines	= TRUE;			/*   ''   line numbers		*/
int	ascii	= TRUE;			/*   ''   comments		*/
int	code	= TRUE;			/*   ''   code			*/
int	ref_g	= TRUE;			/*   ''   referenced globals	*/
int	abs_g	= TRUE;			/*   ''   absolute globals	*/
int	psect_f	= FALSE;		/*   ''   output the psect table*/
int	q_flag	= FALSE;		/* Output psect defns.		*/
int	numbers	= FALSE;		/* Resolve constants in STB	*/
int	sort_g	= FALSE;		/* Sort absolute globals	*/
int	i_flag	= FALSE;		/* Ignore load address mis-match*/
int	b_flag	= FALSE;		/* Its all data (.word etc)	*/

char	*file;				/* Input filename		*/
char	option[27];			/* Input options (a..z and null)*/

FILE	*ip;				/* Input file header		*/

int	pass;				/* Current CAM pass		*/
int	abs_f = FALSE;			/* TRUE if abs globals found	*/
int	flt_f = FALSE;			/* TRUE if floating ACs used	*/

int		seg_max = -1;		/* Highest segment		*/
int		seg_cur;		/* Current segment number	*/
PSECT_PTR	seg_ptr;		/* Current segment pointer	*/
SYMBOL_PTR	ref_st;			/* Start of global ref table	*/
SYMBOL_PTR	ref_end;		/* End of global ref table	*/
SYMBOL_PTR	abs_st;			/* Start of global abs def table*/
SYMBOL_PTR	abs_end;		/* End of global abs def table	*/

int		rec_num;		/* Input record number		*/

BUFFER		buff_1;			/* Input buffer #1		*/
BUFFER		buff_2;			/* Input buffer #2		*/

BUFFER_PTR	b_current;		/* Current working buffer	*/
BUFFER_PTR	b_other;		/* Alternate working buffer	*/

int	eom;				/* End of module flag		*/
int	egsd;				/* T_EGSD detected flag		*/

int	modnam[2];			/* Module name (rad 50)		*/
int	ident_f = FALSE;		/* .ident seen flag		*/
int	_ident[2];			/* .ident text (rad 50)		*/
SYMBOL	t_addr;				/* Transfer address		*/

char *regnam[] = {			/* Guess what these are?	*/
	"r0", "r1", "r2", "r3", "r4", "r5", "sp", "pc" };

char *fltnam[] = {			/* Floating accumulators	*/
	"ac0", "ac1", "ac2", "ac3", "ac4", "ac5" };

char *comp_text[] = {			/* Complex relocation elements	*/
	"", "+", "-", "*", "/", "&", "!", "", "-", "^c" };

int   comp_prio[] = {
	 0,  1 ,  1 ,  1 ,  1 ,  1 ,  1 , 0 ,  5 ,   5  };

C_ELEM	c_stack[MAX_C_STACK];		/* CREL evaluation stack	*/
int	c_sp;				/* Index of c_stack[]		*/

#define	MAX_FIELDS	3		/* IR plus two data items	*/

DATA	instr[MAX_FIELDS];		/* Current instruction		*/

DATA	stack[MAX_STACK];		/* 'un-got' data items		*/
int	stack_p;			/* Index of stack[]		*/

DATA		dot = {			/* Current line 'pc'		*/
			A_VALID, NULL
		};

DATA_PTR	IR = &instr[0];		/* 'instruction' register	*/
DATA_PTR	D1 = &instr[1];		/* Data item 1 for IR		*/
DATA_PTR	D2 = &instr[2];		/* Data item 2 for IR		*/

char	wbuf[MAX_ARGLEN];		/* Working buffer [see arg_?()]	*/
char	*w_ptr;				/* Pointer into wbuf		*/
char	buff[7];			/* Radix buffer. cccccc<null>	*/
char	lbuff[9];			/* Label buffer. cccccc::<null>	*/
char	asc_buf[7];			/* Ascii of data		*/
char	*asc_ptr;			/* Pointer into asc_buf		*/

int	lnum;				/* Output line number		*/
int	blank_line = TRUE;		/* Last line was a blank flag	*/

char	*t_label;			/* Label field text		*/
char	*t_inst;			/* Instruction field text	*/
char	*t_args;			/* Argument field text		*/
char	*t_comments;			/* Comment field address	*/

int	r_command;			/* Pending relocation command	*/
int	r_disp;				/* Displacement of the above	*/
int	r_byte;				/* Byte relocation flag		*/

#endif


#ifdef	MODULE

extern	char	*version;		/* Program version/id		*/

extern	int	debug;			/* In debug mode		*/
extern	int	octal;			/* Output the octal		*/
extern	int	lines;			/*   ''   line numbers		*/
extern	int	ascii;			/*   ''   comments		*/
extern	int	code;			/*   ''   code			*/
extern	int	ref_g;			/*   ''   referenced globals	*/
extern	int	abs_g;			/*   ''   absolute globals	*/
extern	int	psect_f;		/*   ''   output the psect table*/
extern	int	q_flag;			/* Output psect defns.		*/
extern	int	numbers;		/* Resolve constants in STB	*/
extern	int	sort_g;			/* Sort absolute globals	*/
extern	int	i_flag;			/* Ignore load address mis-match*/
extern	int	b_flag;			/* Its all data (.word etc)	*/

extern	char	*file;			/* Input filename		*/
extern	char	option[];		/* Input options		*/

extern	FILE	*ip;			/* Input file header		*/

extern	int	pass;			/* Current CAM pass		*/
extern	int	abs_f;			/* TRUE if abs globals found	*/
extern	int	flt_f;			/* TRUE if floating ACs used	*/

extern	int		seg_max;	/* Highest segment		*/
extern	int		seg_cur;	/* Current segment number	*/
extern	PSECT_PTR	seg_ptr;	/* Current segment pointer	*/
extern	SYMBOL_PTR	ref_st;		/* Start of global ref table	*/
extern	SYMBOL_PTR	ref_end;	/* End of global ref table	*/
extern	SYMBOL_PTR	abs_st;		/* Start of global abs def table*/
extern	SYMBOL_PTR	abs_end;	/* End of global abs def table	*/

extern	int	rec_num;		/* Input record number		*/

extern	BUFFER		buff_1;		/* Input buffer #1		*/
extern	BUFFER		buff_2;		/* Input buffer #2		*/

extern	BUFFER_PTR	b_current;	/* Current working buffer	*/
extern	BUFFER_PTR	b_other;	/* Alternate working buffer	*/

extern	int	eom;			/* End of module flag		*/
extern	int	egsd;			/* T_EGSD detected flag		*/

extern	int	modnam[];		/* Module name (rad 50)		*/
extern	int	ident_f;		/* .ident seen flag		*/
extern	int	_ident[];		/* .ident text (rad 50)		*/
extern	SYMBOL	t_addr;			/* Transfer address		*/

extern	char	*regnam[];		/* Names of the registers	*/
extern	char	*fltnam[];		/* Floating accumulators	*/
extern	char	*comp_text[];		/* Complex relocation elements	*/
extern	int	 comp_prio[];

extern	DATA	instr[];		/* Current instruction		*/

extern	DATA	stack[];		/* 'un-got' data items		*/
extern	int	stack_p;		/* Index of stack[]		*/

extern	C_ELEM	c_stack[];		/* CREL evaluation stack	*/
extern	int	c_sp;			/* Index of c_stack[]		*/

extern	DATA	dot;			/* Current line 'pc'		*/

extern	DATA_PTR  IR;			/* 'instruction' register	*/
extern	DATA_PTR  D1;			/* Data item 1 for IR		*/
extern	DATA_PTR  D2;			/* Data item 2 for IR		*/

extern	char	wbuf[];			/* Working buffer (see 'arg_?')	*/
extern	char	*w_ptr;			/* Pointer into wbuf		*/
extern	char	buff[];			/* Radix buffer			*/
extern	char	lbuff[];		/* Label buffer. cccccc::<null>	*/
extern	char	asc_buf[];		/* Ascii of data		*/
extern	char	*asc_ptr;		/* Pointer into asc_buf		*/

extern	int	lnum;			/* Output line number		*/
extern	int	blank_line;		/* Last line was a blank flag	*/

extern	char	*t_label;		/* Label field text		*/
extern	char	*t_inst;		/* Instruction field text	*/
extern	char	*t_args;		/* Argument field text		*/
extern	char	*t_comments;		/* Comment field address	*/

extern	int	r_command;		/* Pending relocation command	*/
extern	int	r_disp;			/* Displacement of the above	*/
extern	int	r_byte;			/* Byte relocation flag		*/

#endif


