
/*
 * asm.h
 *
 * Definitions for Apple 2 assembler
 * (C) Copyright 1995 Archie L. Cobbs
 *
 */

/*
 * DEFINITIONS
 */

/* Helpful macro */

	#define	RoundUp(x,n)		((x) % (n) ? (x) + (n) - (x) % (n) : (x))

/* Compile-time options */

	#define	DEFAULT_OUTFILE		"a.out"		/* Default output file */
	#define	DEFAULT_HIBIT		0x00		/* Either 0x00 or 0x80 */
	#define	DEFAULT_EXPAND		TRUE		/* Default expand option */
	#define	DEFAULT_65C02		TRUE		/* Default -65c02 option */

	#define	INITIAL_SEGMENT		CodeSegment	/* Initial segment */

	#define MAX_STRING			1024		/* Max string constant length */
	#define	MAX_LISTING_LINE	(131-24)	/* Max line width, for listing */
	#define	MAX_SYMBOL_CHARS	65536		/* Max total symbol name chars */

	#define	MAX_EXPORT_SYMS		8192		/* Max exported symbols */
	#define	MAX_IMPORT_SYMS		8192		/* Max imported symbols */
	#define	MAX_RELOCATIONS		16384		/* Max relocation entries */

	#define	MAX_IF_NESTING		256			/* Max .if .endif nesting */

/* Apple 2 style floating point values -- 5 bytes */

	#define	FLOAT_SIZE_6502		5

/* Text strings */

	OpaqueDecl(TValue);
	OpaqueDefn(TValue)
	{
		char    *chars;
		short   len;
	};

/* Symbols */

	OpaqueDecl(Symbol);
	OpaqueDecl(SymOff);
	OpaqueDecl(SegRel);

	enum SymType
	{
		sSegRel,			/* Segment + offset */
		sSymOff,			/* External symbol + offset */
	};

	OpaqueDefn(SegRel)
	{
		short		segment;	/* Segment */
		int			offset;		/* Offset into segment */
	};

	OpaqueDefn(SymOff)
	{
		unsigned	id;			/* Name of unknown symbol */
		int			offset;		/* Offset */
	};

	OpaqueDefn(Symbol)
	{
		enum SymType	type;
		union
		{
			struct SegRel	segrel;
			struct SymOff	symoff;
		} u;
		unsigned		valid:1;	/* Indicates value is valid */
		unsigned		id:24;		/* Name ID */
		short			line;		/* Line where defined */
		unsigned		file;		/* File where defined */
		Symbol			next;		/* Next in hash chain (see "hash.c") */
	};

/* IValue types */

	OpaqueDecl(IValue);

	enum IvalTyp
	{
		iUnknown,			/* Unknown value (pass 1 only) */
		iSegRel,			/* Segment + offset */
		iSymOff,			/* External symbol + offset */
	};

	OpaqueDefn(IValue)
	{
		short	type;
		union
		{
			struct SegRel	segrel;
			struct SymOff	symoff;
		} u;
	};

/* Lists of things */

	OpaqueDecl(List);
	OpaqueDefn(List)
	{
		union
		{
			struct IValue	ivalue;
			double			fvalue;
			unsigned		id;
		} u;
		List		next;
	};

/* 6502 Address modes (numbering must agree with "ops.c") */

	#define	NUM_ADDRESS_MODES	14

	enum
	{
		mImplied = 1,
		mRelative,
		mImmediate,
		mZeroPage,
		mZeroPageX,
		mZeroPageY,
		mAbsolute,
		mAbsoluteX,
		mAbsoluteY,
		mZPIndirectX,
		mZPIndirectY,
		mIndirect,
		mIndirectX,		/* These were added, so they're out of order */
		mZPIndirect
	};

/*
 * VARIABLES
 */

/* Command line args */

	extern	int				g65c02;
	extern	int				gDebug;
	extern	int				gVerbose;

/* State variables */

	extern	int				gPass;
	extern	int				gHiBit;
	extern	int				gExpand;
	extern	int				gAssembleOn;

	extern	FILE			*gInFile;
	extern	FILE			*gOutFile;

/* Listing stuff */

	extern	FILE			*gInFileList;
	extern	FILE			*gListFile;

	extern	char			gLineBuf[];
	extern	int				gListBytes;
	extern	struct SegRel	gSegrel;

/* Names databases */

	extern	Names			gNames;
	extern	Names			gObjNames;

/* Segment output buffers */

	extern	Byte			*gSegBuffer[];
	extern	unsigned		gAddress[];
	extern	unsigned		gMaxAddress[];
	extern	int				gSegment;

/*
 * FUNCTIONS
 */

/* Symbols */

	extern	Symbol			DefineSym(unsigned id);
	extern	Symbol			GetSym(unsigned id);
	extern	void			SymDump(FILE *fp);
	extern	void			ShowSym(FILE *fp, Symbol sym);

/* Opcodes */

	extern	void			OpcodeInit(void);
	extern	Byte			GetOp(unsigned ins, int mode);
	extern	int				CheckOp(unsigned ins, int mode);

/* Pseudo-opcodes */

	extern	void			PsAscii(TValue tval, int zt, int dci);
	extern	void			PsData(List ilist, int numBytes, int bigEndian);

/* Emitting */

	extern	void			Emit(Byte byte);
	extern	void			EmitIns(unsigned ins, IValue ivalue, int m, int z);
	extern	void			EmitImm(unsigned ins, IValue ivalue, int hibyte);
	extern	void			EmitIvalue(IValue ivalue, int bigendian, int bytes);

/* Object file stuff */

	extern	void			WriteObj(FILE *fp);

/* Relocation */

	extern	void			RelocSeg(SegRel segrel, int bigendian, int bytes);
	extern	void			RelocSym(SymOff symoff, int bigendian, int bytes);
	extern	unsigned		RelocDumpEntries(FILE *fp, int seg);

/* Importing symbols */

	extern	void			Import(unsigned id);
	extern	void			ZpImport(unsigned id);
	extern	int				IsZpImport(unsigned id);

/* Exporting symbols */

	extern	void			Export(Symbol sym);
	extern	unsigned		ExportDump(FILE *fp);

/* Floating point conversion */

	extern	void			EncodeFloat(double f, Byte *value);

/* Output listing */

	extern	void			ListLine(FILE *fp);

/* Lexing and parsing */

	extern	void			yylexinit(char *filename);
	extern	int				yylex(void);
	extern	int				yyparse(void);
	extern	void			yyrestart(FILE *fp);



