view lwasm/lwasm.h @ 353:faa97115952e

Added SECTION/ENDSECTION
author lost@starbug
date Tue, 30 Mar 2010 21:48:49 -0600
parents 4dba8c7e242c
children 60568b123281
line wrap: on
line source

/*
lwasm.h

Copyright © 2010 William Astle

This file is part of LWTOOLS.

LWTOOLS is free software: you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation, either version 3 of the License, or (at your option) any later
version.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details.

You should have received a copy of the GNU General Public License along with
this program. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef ___lwasm_h_seen___
#define ___lwasm_h_seen___

#include <lw_expr.h>
#include <lw_stringlist.h>
#include <lw_stack.h>


// these are allowed chars BELOW 0x80 for symbols
// first is symbol start chars, second is anywhere in symbol
#define SSYMCHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_@$"
#define SYMCHARS SSYMCHARS ".?0123456789"

typedef struct asmstate_s asmstate_t;

enum
{
	lwasm_expr_linelen = 1,			// length of ref'd line
	lwasm_expr_lineaddr = 2,		// addr of ref'd line
	lwasm_expr_nextbp = 3,			// next branch point
	lwasm_expr_prevbp = 4			// previous branch point
};

enum lwasm_output_e
{
	OUTPUT_DECB = 0,	// DECB multirecord format
	OUTPUT_RAW,			// raw sequence of bytes
	OUTPUT_OBJ,			// proprietary object file format
	OUTPUT_RAWREL,		// raw bytes where ORG causes a SEEK in the file
	OUTPUT_OS9			// os9 module target
};

enum lwasm_target_e
{
	TARGET_6309 = 0,	// target 6309 CPU
	TARGET_6809			// target 6809 CPU (no 6309 ops)
};

enum lwasm_flags_e
{
	FLAG_NONE = 0,
	FLAG_LIST = 0x0001,
	FLAG_DEPEND = 0x0002
};

enum lwasm_pragmas_e
{
	PRAGMA_NONE = 0,					// no pragmas in effect
	PRAGMA_DOLLARNOTLOCAL = 0x0001,		// dollar sign does not make a symbol local
	PRAGMA_NOINDEX0TONONE = 0x0002,		// do not change implicit 0,R to ,R
	PRAGMA_UNDEFEXTERN = 0x0004,		// undefined symbols are considered to be external
	PRAGMA_CESCAPES = 0x0008,			// allow C style escapes in fcc, fcs, fcn, etc.
	PRAGMA_IMPORTUNDEFEXPORT = 0x0010	// imports symbol if undefined upon export
};

typedef struct lwasm_error_s lwasm_error_t;
struct lwasm_error_s
{
	char *mess;							// actual error message
	lwasm_error_t *next;				// ptr to next error
};

struct line_expr_s
{
	lw_expr_t expr;
	int id;
	struct line_expr_s *next;
};

typedef struct line_s line_t;
struct line_s
{
	lw_expr_t addr;						// assembly address of the line
	int len;							// the "size" this line occupies (address space wise) (-1 if unknown)
	int insn;							// number of insn in insn table
	int symset;							// set if the line symbol was consumed by the instruction
	char *sym;							// symbol, if any, on the line
	unsigned char *output;				// output bytes
	int outputl;						// size of output
	int outputbl;						// size of output buffer
	int dpval;							// direct page value
	lwasm_error_t *err;					// list of errors
	lwasm_error_t *warn;				// list of errors
	line_t *prev;						// previous line
	line_t *next;						// next line
	
	struct line_expr_s *exprs;			// expressions used during parsing
	char *lstr;							// string passed forward
	asmstate_t *as;						// assembler state data ptr
};

enum
{
	symbol_flag_set = 1,				// symbol was used with "set"
	symbol_flag_none = 0				// no flags
};

struct symtabe
{
	char *symbol;						// the name of the symbol
	int context;						// symbol context (-1 for global)
	int version;						// version of the symbol (for "set")
	int flags;							// flags for the symbol
	lw_expr_t value;					// symbol value
	struct symtabe *next;				// next symbol in the table
};

typedef struct
{
	struct symtabe *head;				// start of symbol table
} symtab_t;

typedef struct macrotab_s macrotab_t;
struct macrotab_s
{
	char *name;							// name of macro
	char **lines;						// macro lines
	int numlines;						// number lines in macro
	macrotab_t *next;					// next macro in list
};

enum
{
	section_flag_bss = 1,				// BSS section
	section_flag_none = 0				// no flags
};

typedef struct sectiontab_s sectiontab_t;
struct sectiontab_s
{
	char *name;							// section name
	int flags;							// section flags;
	lw_expr_t offset;					// offset for next instance
	sectiontab_t *next;
};

struct asmstate_s
{
	int output_format;					// output format
	int target;							// assembly target
	int debug_level;					// level of debugging requested
	int flags;							// assembly flags
	int pragmas;						// pragmas currently in effect
	int errorcount;						// number of errors encountered
	int inmacro;						// are we in a macro?
	int skipcond;						// skipping a condition?
	int skipcount;						// depth of "skipping"
	int skipmacro;						// are we skipping in a macro?	
	int endseen;						// have we seen an "end" pseudo?
	int execaddr;						// address from "end"

	line_t *line_head;					// start of lines list
	line_t *line_tail;					// tail of lines list

	line_t *cl;							// current line pointer
	
	sectiontab_t *csect;				// current section
	
	int context;						// the current "context"
	int nextcontext;					// the next available context
	
	symtab_t symtab;					// meta data for the symbol table
	macrotab_t *macros;					// macro table
	sectiontab_t *sections;				// section table

	char *list_file;					// name of file to list to
	char *output_file;					// output file name	
	lw_stringlist_t input_files;		// files to assemble
	void *input_data;					// opaque data used by the input system
	lw_stringlist_t include_list;		// include paths
	lw_stack_t file_dir;				// stack of the "current file" dir
};

#ifndef ___symbol_c_seen___

extern struct symtabe *register_symbol(asmstate_t *as, line_t *cl, char *sym, lw_expr_t value, int flags);
extern struct symtabe *lookup_symbol(asmstate_t *as, line_t *cl, char *sym, int context, int version);

#endif

#ifndef ___lwasm_c_seen___

extern void lwasm_register_error(asmstate_t *as, line_t *cl, const char *msg, ...);
extern void lwasm_register_warning(asmstate_t *as, line_t *cl, const char *msg, ...);
extern int lwasm_next_context(asmstate_t *as);
extern void lwasm_emit(line_t *cl, int byte);
extern void lwasm_emitop(line_t *cl, int opc);

extern void lwasm_save_expr(line_t *cl, int id, lw_expr_t expr);
extern lw_expr_t lwasm_fetch_expr(line_t *cl, int id);
extern lw_expr_t lwasm_parse_expr(asmstate_t *as, char **p);
extern int lwasm_emitexpr(line_t *cl, lw_expr_t expr, int s);

extern void skip_operand(char **p);

#endif

#define OPLEN(op) (((op)>0xFF)?2:1)

#endif /* ___lwasm_h_seen___ */