From 94fad97aedcd8bd85c53a505db28390e3f82577b Mon Sep 17 00:00:00 2001 From: Vegard Nossum Date: Thu, 11 Jun 2009 07:32:12 +0200 Subject: [PATCH] Switch line terminators from CRLF to LF Argh, that obnoxious platform again... ;-) Signed-off-by: Vegard Nossum --- src/asm/alloca.c | 994 ++++++++--------- src/asm/fstack.c | 820 +++++++------- src/asm/gameboy/localasm.h | 308 +++--- src/asm/gameboy/locallex.c | 176 +-- src/asm/gameboy/yaccprt2.y | 82 +- src/asm/gameboy/yaccprt4.y | 994 ++++++++--------- src/asm/globlex.c | 1024 ++++++++--------- src/asm/include/asm.h | 64 +- src/asm/include/fstack.h | 84 +- src/asm/include/gbasmy.h | 306 ++--- src/asm/include/lexer.h | 134 +-- src/asm/include/main.h | 68 +- src/asm/include/mylink.h | 244 ++-- src/asm/include/mymath.h | 36 +- src/asm/include/output.h | 72 +- src/asm/include/rpn.h | 100 +- src/asm/include/symbol.h | 134 +-- src/asm/include/types.h | 34 +- src/asm/lexer.c | 1624 +++++++++++++-------------- src/asm/main.c | 810 +++++++------- src/asm/math.c | 304 ++--- src/asm/output.c | 2052 +++++++++++++++++----------------- src/asm/rpn.c | 712 ++++++------ src/asm/symbol.c | 2144 ++++++++++++++++++------------------ src/asm/yaccprt3.y | 1062 +++++++++--------- src/asmotor.h | 48 +- src/lib/include/library.h | 24 +- src/lib/include/libwrap.h | 38 +- src/lib/include/types.h | 30 +- src/lib/library.c | 614 +++++------ src/lib/main.c | 284 ++--- src/link/assign.c | 1138 +++++++++---------- src/link/include/assign.h | 42 +- src/link/include/library.h | 10 +- src/link/include/main.h | 40 +- src/link/include/mapfile.h | 20 +- src/link/include/mylink.h | 236 ++-- src/link/include/object.h | 12 +- src/link/include/output.h | 14 +- src/link/include/patch.h | 16 +- src/link/include/symbol.h | 20 +- src/link/include/types.h | 30 +- src/link/library.c | 252 ++--- src/link/main.c | 458 ++++---- src/link/mapfile.c | 214 ++-- src/link/object.c | 1090 +++++++++--------- src/link/output.c | 442 ++++---- src/link/patch.c | 598 +++++----- src/link/symbol.c | 248 ++--- src/rgbfix/main.c | 862 +++++++-------- 50 files changed, 10581 insertions(+), 10581 deletions(-) diff --git a/src/asm/alloca.c b/src/asm/alloca.c index effa817e..8a0c3203 100644 --- a/src/asm/alloca.c +++ b/src/asm/alloca.c @@ -1,497 +1,497 @@ -/* alloca.c -- allocate automatically reclaimed memory - (Mostly) portable public-domain implementation -- D A Gwyn - - This implementation of the PWB library alloca function, - which is used to allocate space off the run-time stack so - that it is automatically reclaimed upon procedure exit, - was inspired by discussions with J. Q. Johnson of Cornell. - J.Otto Tennant contributed the Cray support. - - There are some preprocessor constants that can - be defined when compiling for your specific system, for - improved efficiency; however, the defaults should be okay. - - The general concept of this implementation is to keep - track of all alloca-allocated blocks, and reclaim any - that are found to be deeper in the stack than the current - invocation. This heuristic does not reclaim storage as - soon as it becomes invalid, but it will do so eventually. - - As a special case, alloca(0) reclaims storage without - allocating any. It is a good idea to use alloca(0) in - your main control loop, etc. to force garbage collection. */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#ifdef emacs -#include "blockinput.h" -#endif - -/* If compiling with GCC 2, this file's not needed. */ -#if !defined (__GNUC__) || __GNUC__ < 2 - -/* If someone has defined alloca as a macro, - there must be some other way alloca is supposed to work. */ -#ifndef alloca - -#ifdef emacs -#ifdef static -/* actually, only want this if static is defined as "" - -- this is for usg, in which emacs must undefine static - in order to make unexec workable - */ -#ifndef STACK_DIRECTION -you -lose --- must know STACK_DIRECTION at compile-time -#endif /* STACK_DIRECTION undefined */ -#endif /* static */ -#endif /* emacs */ - -/* If your stack is a linked list of frames, you have to - provide an "address metric" ADDRESS_FUNCTION macro. */ - -#if defined (CRAY) && defined (CRAY_STACKSEG_END) -long i00afunc (); -#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg)) -#else -#define ADDRESS_FUNCTION(arg) &(arg) -#endif - -#if __STDC__ -typedef void *pointer; -#else -typedef char *pointer; -#endif - -#define NULL 0 - -/* Different portions of Emacs need to call different versions of - malloc. The Emacs executable needs alloca to call xmalloc, because - ordinary malloc isn't protected from input signals. On the other - hand, the utilities in lib-src need alloca to call malloc; some of - them are very simple, and don't have an xmalloc routine. - - Non-Emacs programs expect this to call use xmalloc. - - Callers below should use malloc. */ - -/* Carsten Sorensen 09/09/97 - * Commented out the following, I want malloc! -#ifndef emacs -#define malloc xmalloc -#endif -extern pointer malloc (); - And added the following line: - */ -#include - -/* Define STACK_DIRECTION if you know the direction of stack - growth for your system; otherwise it will be automatically - deduced at run-time. - - STACK_DIRECTION > 0 => grows toward higher addresses - STACK_DIRECTION < 0 => grows toward lower addresses - STACK_DIRECTION = 0 => direction of growth unknown */ - -#ifndef STACK_DIRECTION -#define STACK_DIRECTION 0 /* Direction unknown. */ -#endif - -#if STACK_DIRECTION != 0 - -#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */ - -#else /* STACK_DIRECTION == 0; need run-time code. */ - -static int stack_dir; /* 1 or -1 once known. */ -#define STACK_DIR stack_dir - -static void -find_stack_direction () -{ - static char *addr = NULL; /* Address of first `dummy', once known. */ - auto char dummy; /* To get stack address. */ - - if (addr == NULL) - { /* Initial entry. */ - addr = ADDRESS_FUNCTION (dummy); - - find_stack_direction (); /* Recurse once. */ - } - else - { - /* Second entry. */ - if (ADDRESS_FUNCTION (dummy) > addr) - stack_dir = 1; /* Stack grew upward. */ - else - stack_dir = -1; /* Stack grew downward. */ - } -} - -#endif /* STACK_DIRECTION == 0 */ - -/* An "alloca header" is used to: - (a) chain together all alloca'ed blocks; - (b) keep track of stack depth. - - It is very important that sizeof(header) agree with malloc - alignment chunk size. The following default should work okay. */ - -#ifndef ALIGN_SIZE -#define ALIGN_SIZE sizeof(double) -#endif - -typedef union hdr -{ - char align[ALIGN_SIZE]; /* To force sizeof(header). */ - struct - { - union hdr *next; /* For chaining headers. */ - char *deep; /* For stack depth measure. */ - } h; -} header; - -static header *last_alloca_header = NULL; /* -> last alloca header. */ - -/* Return a pointer to at least SIZE bytes of storage, - which will be automatically reclaimed upon exit from - the procedure that called alloca. Originally, this space - was supposed to be taken from the current stack frame of the - caller, but that method cannot be made to work for some - implementations of C, for example under Gould's UTX/32. */ - -pointer -alloca (size) - unsigned size; -{ - auto char probe; /* Probes stack depth: */ - register char *depth = ADDRESS_FUNCTION (probe); - -#if STACK_DIRECTION == 0 - if (STACK_DIR == 0) /* Unknown growth direction. */ - find_stack_direction (); -#endif - - /* Reclaim garbage, defined as all alloca'd storage that - was allocated from deeper in the stack than currently. */ - - { - register header *hp; /* Traverses linked list. */ - -#ifdef emacs - BLOCK_INPUT; -#endif - - for (hp = last_alloca_header; hp != NULL;) - if ((STACK_DIR > 0 && hp->h.deep > depth) - || (STACK_DIR < 0 && hp->h.deep < depth)) - { - register header *np = hp->h.next; - - free ((pointer) hp); /* Collect garbage. */ - - hp = np; /* -> next header. */ - } - else - break; /* Rest are not deeper. */ - - last_alloca_header = hp; /* -> last valid storage. */ - -#ifdef emacs - UNBLOCK_INPUT; -#endif - } - - if (size == 0) - return NULL; /* No allocation required. */ - - /* Allocate combined header + user data storage. */ - - { - register pointer new = malloc (sizeof (header) + size); - /* Address of header. */ - - ((header *) new)->h.next = last_alloca_header; - ((header *) new)->h.deep = depth; - - last_alloca_header = (header *) new; - - /* User storage begins just after header. */ - - return (pointer) ((char *) new + sizeof (header)); - } -} - -#if defined (CRAY) && defined (CRAY_STACKSEG_END) - -#ifdef DEBUG_I00AFUNC -#include -#endif - -#ifndef CRAY_STACK -#define CRAY_STACK -#ifndef CRAY2 -/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */ -struct stack_control_header - { - long shgrow:32; /* Number of times stack has grown. */ - long shaseg:32; /* Size of increments to stack. */ - long shhwm:32; /* High water mark of stack. */ - long shsize:32; /* Current size of stack (all segments). */ - }; - -/* The stack segment linkage control information occurs at - the high-address end of a stack segment. (The stack - grows from low addresses to high addresses.) The initial - part of the stack segment linkage control information is - 0200 (octal) words. This provides for register storage - for the routine which overflows the stack. */ - -struct stack_segment_linkage - { - long ss[0200]; /* 0200 overflow words. */ - long sssize:32; /* Number of words in this segment. */ - long ssbase:32; /* Offset to stack base. */ - long:32; - long sspseg:32; /* Offset to linkage control of previous - segment of stack. */ - long:32; - long sstcpt:32; /* Pointer to task common address block. */ - long sscsnm; /* Private control structure number for - microtasking. */ - long ssusr1; /* Reserved for user. */ - long ssusr2; /* Reserved for user. */ - long sstpid; /* Process ID for pid based multi-tasking. */ - long ssgvup; /* Pointer to multitasking thread giveup. */ - long sscray[7]; /* Reserved for Cray Research. */ - long ssa0; - long ssa1; - long ssa2; - long ssa3; - long ssa4; - long ssa5; - long ssa6; - long ssa7; - long sss0; - long sss1; - long sss2; - long sss3; - long sss4; - long sss5; - long sss6; - long sss7; - }; - -#else /* CRAY2 */ -/* The following structure defines the vector of words - returned by the STKSTAT library routine. */ -struct stk_stat - { - long now; /* Current total stack size. */ - long maxc; /* Amount of contiguous space which would - be required to satisfy the maximum - stack demand to date. */ - long high_water; /* Stack high-water mark. */ - long overflows; /* Number of stack overflow ($STKOFEN) calls. */ - long hits; /* Number of internal buffer hits. */ - long extends; /* Number of block extensions. */ - long stko_mallocs; /* Block allocations by $STKOFEN. */ - long underflows; /* Number of stack underflow calls ($STKRETN). */ - long stko_free; /* Number of deallocations by $STKRETN. */ - long stkm_free; /* Number of deallocations by $STKMRET. */ - long segments; /* Current number of stack segments. */ - long maxs; /* Maximum number of stack segments so far. */ - long pad_size; /* Stack pad size. */ - long current_address; /* Current stack segment address. */ - long current_size; /* Current stack segment size. This - number is actually corrupted by STKSTAT to - include the fifteen word trailer area. */ - long initial_address; /* Address of initial segment. */ - long initial_size; /* Size of initial segment. */ - }; - -/* The following structure describes the data structure which trails - any stack segment. I think that the description in 'asdef' is - out of date. I only describe the parts that I am sure about. */ - -struct stk_trailer - { - long this_address; /* Address of this block. */ - long this_size; /* Size of this block (does not include - this trailer). */ - long unknown2; - long unknown3; - long link; /* Address of trailer block of previous - segment. */ - long unknown5; - long unknown6; - long unknown7; - long unknown8; - long unknown9; - long unknown10; - long unknown11; - long unknown12; - long unknown13; - long unknown14; - }; - -#endif /* CRAY2 */ -#endif /* not CRAY_STACK */ - -#ifdef CRAY2 -/* Determine a "stack measure" for an arbitrary ADDRESS. - I doubt that "lint" will like this much. */ - -static long -i00afunc (long *address) -{ - struct stk_stat status; - struct stk_trailer *trailer; - long *block, size; - long result = 0; - - /* We want to iterate through all of the segments. The first - step is to get the stack status structure. We could do this - more quickly and more directly, perhaps, by referencing the - $LM00 common block, but I know that this works. */ - - STKSTAT (&status); - - /* Set up the iteration. */ - - trailer = (struct stk_trailer *) (status.current_address - + status.current_size - - 15); - - /* There must be at least one stack segment. Therefore it is - a fatal error if "trailer" is null. */ - - if (trailer == 0) - abort (); - - /* Discard segments that do not contain our argument address. */ - - while (trailer != 0) - { - block = (long *) trailer->this_address; - size = trailer->this_size; - if (block == 0 || size == 0) - abort (); - trailer = (struct stk_trailer *) trailer->link; - if ((block <= address) && (address < (block + size))) - break; - } - - /* Set the result to the offset in this segment and add the sizes - of all predecessor segments. */ - - result = address - block; - - if (trailer == 0) - { - return result; - } - - do - { - if (trailer->this_size <= 0) - abort (); - result += trailer->this_size; - trailer = (struct stk_trailer *) trailer->link; - } - while (trailer != 0); - - /* We are done. Note that if you present a bogus address (one - not in any segment), you will get a different number back, formed - from subtracting the address of the first block. This is probably - not what you want. */ - - return (result); -} - -#else /* not CRAY2 */ -/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP. - Determine the number of the cell within the stack, - given the address of the cell. The purpose of this - routine is to linearize, in some sense, stack addresses - for alloca. */ - -static long -i00afunc (long address) -{ - long stkl = 0; - - long size, pseg, this_segment, stack; - long result = 0; - - struct stack_segment_linkage *ssptr; - - /* Register B67 contains the address of the end of the - current stack segment. If you (as a subprogram) store - your registers on the stack and find that you are past - the contents of B67, you have overflowed the segment. - - B67 also points to the stack segment linkage control - area, which is what we are really interested in. */ - - stkl = CRAY_STACKSEG_END (); - ssptr = (struct stack_segment_linkage *) stkl; - - /* If one subtracts 'size' from the end of the segment, - one has the address of the first word of the segment. - - If this is not the first segment, 'pseg' will be - nonzero. */ - - pseg = ssptr->sspseg; - size = ssptr->sssize; - - this_segment = stkl - size; - - /* It is possible that calling this routine itself caused - a stack overflow. Discard stack segments which do not - contain the target address. */ - - while (!(this_segment <= address && address <= stkl)) - { -#ifdef DEBUG_I00AFUNC - fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl); -#endif - if (pseg == 0) - break; - stkl = stkl - pseg; - ssptr = (struct stack_segment_linkage *) stkl; - size = ssptr->sssize; - pseg = ssptr->sspseg; - this_segment = stkl - size; - } - - result = address - this_segment; - - /* If you subtract pseg from the current end of the stack, - you get the address of the previous stack segment's end. - This seems a little convoluted to me, but I'll bet you save - a cycle somewhere. */ - - while (pseg != 0) - { -#ifdef DEBUG_I00AFUNC - fprintf (stderr, "%011o %011o\n", pseg, size); -#endif - stkl = stkl - pseg; - ssptr = (struct stack_segment_linkage *) stkl; - size = ssptr->sssize; - pseg = ssptr->sspseg; - result += size; - } - return (result); -} - -#endif /* not CRAY2 */ -#endif /* CRAY */ - -#endif /* no alloca */ -#endif /* not GCC version 2 */ +/* alloca.c -- allocate automatically reclaimed memory + (Mostly) portable public-domain implementation -- D A Gwyn + + This implementation of the PWB library alloca function, + which is used to allocate space off the run-time stack so + that it is automatically reclaimed upon procedure exit, + was inspired by discussions with J. Q. Johnson of Cornell. + J.Otto Tennant contributed the Cray support. + + There are some preprocessor constants that can + be defined when compiling for your specific system, for + improved efficiency; however, the defaults should be okay. + + The general concept of this implementation is to keep + track of all alloca-allocated blocks, and reclaim any + that are found to be deeper in the stack than the current + invocation. This heuristic does not reclaim storage as + soon as it becomes invalid, but it will do so eventually. + + As a special case, alloca(0) reclaims storage without + allocating any. It is a good idea to use alloca(0) in + your main control loop, etc. to force garbage collection. */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef emacs +#include "blockinput.h" +#endif + +/* If compiling with GCC 2, this file's not needed. */ +#if !defined (__GNUC__) || __GNUC__ < 2 + +/* If someone has defined alloca as a macro, + there must be some other way alloca is supposed to work. */ +#ifndef alloca + +#ifdef emacs +#ifdef static +/* actually, only want this if static is defined as "" + -- this is for usg, in which emacs must undefine static + in order to make unexec workable + */ +#ifndef STACK_DIRECTION +you +lose +-- must know STACK_DIRECTION at compile-time +#endif /* STACK_DIRECTION undefined */ +#endif /* static */ +#endif /* emacs */ + +/* If your stack is a linked list of frames, you have to + provide an "address metric" ADDRESS_FUNCTION macro. */ + +#if defined (CRAY) && defined (CRAY_STACKSEG_END) +long i00afunc (); +#define ADDRESS_FUNCTION(arg) (char *) i00afunc (&(arg)) +#else +#define ADDRESS_FUNCTION(arg) &(arg) +#endif + +#if __STDC__ +typedef void *pointer; +#else +typedef char *pointer; +#endif + +#define NULL 0 + +/* Different portions of Emacs need to call different versions of + malloc. The Emacs executable needs alloca to call xmalloc, because + ordinary malloc isn't protected from input signals. On the other + hand, the utilities in lib-src need alloca to call malloc; some of + them are very simple, and don't have an xmalloc routine. + + Non-Emacs programs expect this to call use xmalloc. + + Callers below should use malloc. */ + +/* Carsten Sorensen 09/09/97 + * Commented out the following, I want malloc! +#ifndef emacs +#define malloc xmalloc +#endif +extern pointer malloc (); + And added the following line: + */ +#include + +/* Define STACK_DIRECTION if you know the direction of stack + growth for your system; otherwise it will be automatically + deduced at run-time. + + STACK_DIRECTION > 0 => grows toward higher addresses + STACK_DIRECTION < 0 => grows toward lower addresses + STACK_DIRECTION = 0 => direction of growth unknown */ + +#ifndef STACK_DIRECTION +#define STACK_DIRECTION 0 /* Direction unknown. */ +#endif + +#if STACK_DIRECTION != 0 + +#define STACK_DIR STACK_DIRECTION /* Known at compile-time. */ + +#else /* STACK_DIRECTION == 0; need run-time code. */ + +static int stack_dir; /* 1 or -1 once known. */ +#define STACK_DIR stack_dir + +static void +find_stack_direction () +{ + static char *addr = NULL; /* Address of first `dummy', once known. */ + auto char dummy; /* To get stack address. */ + + if (addr == NULL) + { /* Initial entry. */ + addr = ADDRESS_FUNCTION (dummy); + + find_stack_direction (); /* Recurse once. */ + } + else + { + /* Second entry. */ + if (ADDRESS_FUNCTION (dummy) > addr) + stack_dir = 1; /* Stack grew upward. */ + else + stack_dir = -1; /* Stack grew downward. */ + } +} + +#endif /* STACK_DIRECTION == 0 */ + +/* An "alloca header" is used to: + (a) chain together all alloca'ed blocks; + (b) keep track of stack depth. + + It is very important that sizeof(header) agree with malloc + alignment chunk size. The following default should work okay. */ + +#ifndef ALIGN_SIZE +#define ALIGN_SIZE sizeof(double) +#endif + +typedef union hdr +{ + char align[ALIGN_SIZE]; /* To force sizeof(header). */ + struct + { + union hdr *next; /* For chaining headers. */ + char *deep; /* For stack depth measure. */ + } h; +} header; + +static header *last_alloca_header = NULL; /* -> last alloca header. */ + +/* Return a pointer to at least SIZE bytes of storage, + which will be automatically reclaimed upon exit from + the procedure that called alloca. Originally, this space + was supposed to be taken from the current stack frame of the + caller, but that method cannot be made to work for some + implementations of C, for example under Gould's UTX/32. */ + +pointer +alloca (size) + unsigned size; +{ + auto char probe; /* Probes stack depth: */ + register char *depth = ADDRESS_FUNCTION (probe); + +#if STACK_DIRECTION == 0 + if (STACK_DIR == 0) /* Unknown growth direction. */ + find_stack_direction (); +#endif + + /* Reclaim garbage, defined as all alloca'd storage that + was allocated from deeper in the stack than currently. */ + + { + register header *hp; /* Traverses linked list. */ + +#ifdef emacs + BLOCK_INPUT; +#endif + + for (hp = last_alloca_header; hp != NULL;) + if ((STACK_DIR > 0 && hp->h.deep > depth) + || (STACK_DIR < 0 && hp->h.deep < depth)) + { + register header *np = hp->h.next; + + free ((pointer) hp); /* Collect garbage. */ + + hp = np; /* -> next header. */ + } + else + break; /* Rest are not deeper. */ + + last_alloca_header = hp; /* -> last valid storage. */ + +#ifdef emacs + UNBLOCK_INPUT; +#endif + } + + if (size == 0) + return NULL; /* No allocation required. */ + + /* Allocate combined header + user data storage. */ + + { + register pointer new = malloc (sizeof (header) + size); + /* Address of header. */ + + ((header *) new)->h.next = last_alloca_header; + ((header *) new)->h.deep = depth; + + last_alloca_header = (header *) new; + + /* User storage begins just after header. */ + + return (pointer) ((char *) new + sizeof (header)); + } +} + +#if defined (CRAY) && defined (CRAY_STACKSEG_END) + +#ifdef DEBUG_I00AFUNC +#include +#endif + +#ifndef CRAY_STACK +#define CRAY_STACK +#ifndef CRAY2 +/* Stack structures for CRAY-1, CRAY X-MP, and CRAY Y-MP */ +struct stack_control_header + { + long shgrow:32; /* Number of times stack has grown. */ + long shaseg:32; /* Size of increments to stack. */ + long shhwm:32; /* High water mark of stack. */ + long shsize:32; /* Current size of stack (all segments). */ + }; + +/* The stack segment linkage control information occurs at + the high-address end of a stack segment. (The stack + grows from low addresses to high addresses.) The initial + part of the stack segment linkage control information is + 0200 (octal) words. This provides for register storage + for the routine which overflows the stack. */ + +struct stack_segment_linkage + { + long ss[0200]; /* 0200 overflow words. */ + long sssize:32; /* Number of words in this segment. */ + long ssbase:32; /* Offset to stack base. */ + long:32; + long sspseg:32; /* Offset to linkage control of previous + segment of stack. */ + long:32; + long sstcpt:32; /* Pointer to task common address block. */ + long sscsnm; /* Private control structure number for + microtasking. */ + long ssusr1; /* Reserved for user. */ + long ssusr2; /* Reserved for user. */ + long sstpid; /* Process ID for pid based multi-tasking. */ + long ssgvup; /* Pointer to multitasking thread giveup. */ + long sscray[7]; /* Reserved for Cray Research. */ + long ssa0; + long ssa1; + long ssa2; + long ssa3; + long ssa4; + long ssa5; + long ssa6; + long ssa7; + long sss0; + long sss1; + long sss2; + long sss3; + long sss4; + long sss5; + long sss6; + long sss7; + }; + +#else /* CRAY2 */ +/* The following structure defines the vector of words + returned by the STKSTAT library routine. */ +struct stk_stat + { + long now; /* Current total stack size. */ + long maxc; /* Amount of contiguous space which would + be required to satisfy the maximum + stack demand to date. */ + long high_water; /* Stack high-water mark. */ + long overflows; /* Number of stack overflow ($STKOFEN) calls. */ + long hits; /* Number of internal buffer hits. */ + long extends; /* Number of block extensions. */ + long stko_mallocs; /* Block allocations by $STKOFEN. */ + long underflows; /* Number of stack underflow calls ($STKRETN). */ + long stko_free; /* Number of deallocations by $STKRETN. */ + long stkm_free; /* Number of deallocations by $STKMRET. */ + long segments; /* Current number of stack segments. */ + long maxs; /* Maximum number of stack segments so far. */ + long pad_size; /* Stack pad size. */ + long current_address; /* Current stack segment address. */ + long current_size; /* Current stack segment size. This + number is actually corrupted by STKSTAT to + include the fifteen word trailer area. */ + long initial_address; /* Address of initial segment. */ + long initial_size; /* Size of initial segment. */ + }; + +/* The following structure describes the data structure which trails + any stack segment. I think that the description in 'asdef' is + out of date. I only describe the parts that I am sure about. */ + +struct stk_trailer + { + long this_address; /* Address of this block. */ + long this_size; /* Size of this block (does not include + this trailer). */ + long unknown2; + long unknown3; + long link; /* Address of trailer block of previous + segment. */ + long unknown5; + long unknown6; + long unknown7; + long unknown8; + long unknown9; + long unknown10; + long unknown11; + long unknown12; + long unknown13; + long unknown14; + }; + +#endif /* CRAY2 */ +#endif /* not CRAY_STACK */ + +#ifdef CRAY2 +/* Determine a "stack measure" for an arbitrary ADDRESS. + I doubt that "lint" will like this much. */ + +static long +i00afunc (long *address) +{ + struct stk_stat status; + struct stk_trailer *trailer; + long *block, size; + long result = 0; + + /* We want to iterate through all of the segments. The first + step is to get the stack status structure. We could do this + more quickly and more directly, perhaps, by referencing the + $LM00 common block, but I know that this works. */ + + STKSTAT (&status); + + /* Set up the iteration. */ + + trailer = (struct stk_trailer *) (status.current_address + + status.current_size + - 15); + + /* There must be at least one stack segment. Therefore it is + a fatal error if "trailer" is null. */ + + if (trailer == 0) + abort (); + + /* Discard segments that do not contain our argument address. */ + + while (trailer != 0) + { + block = (long *) trailer->this_address; + size = trailer->this_size; + if (block == 0 || size == 0) + abort (); + trailer = (struct stk_trailer *) trailer->link; + if ((block <= address) && (address < (block + size))) + break; + } + + /* Set the result to the offset in this segment and add the sizes + of all predecessor segments. */ + + result = address - block; + + if (trailer == 0) + { + return result; + } + + do + { + if (trailer->this_size <= 0) + abort (); + result += trailer->this_size; + trailer = (struct stk_trailer *) trailer->link; + } + while (trailer != 0); + + /* We are done. Note that if you present a bogus address (one + not in any segment), you will get a different number back, formed + from subtracting the address of the first block. This is probably + not what you want. */ + + return (result); +} + +#else /* not CRAY2 */ +/* Stack address function for a CRAY-1, CRAY X-MP, or CRAY Y-MP. + Determine the number of the cell within the stack, + given the address of the cell. The purpose of this + routine is to linearize, in some sense, stack addresses + for alloca. */ + +static long +i00afunc (long address) +{ + long stkl = 0; + + long size, pseg, this_segment, stack; + long result = 0; + + struct stack_segment_linkage *ssptr; + + /* Register B67 contains the address of the end of the + current stack segment. If you (as a subprogram) store + your registers on the stack and find that you are past + the contents of B67, you have overflowed the segment. + + B67 also points to the stack segment linkage control + area, which is what we are really interested in. */ + + stkl = CRAY_STACKSEG_END (); + ssptr = (struct stack_segment_linkage *) stkl; + + /* If one subtracts 'size' from the end of the segment, + one has the address of the first word of the segment. + + If this is not the first segment, 'pseg' will be + nonzero. */ + + pseg = ssptr->sspseg; + size = ssptr->sssize; + + this_segment = stkl - size; + + /* It is possible that calling this routine itself caused + a stack overflow. Discard stack segments which do not + contain the target address. */ + + while (!(this_segment <= address && address <= stkl)) + { +#ifdef DEBUG_I00AFUNC + fprintf (stderr, "%011o %011o %011o\n", this_segment, address, stkl); +#endif + if (pseg == 0) + break; + stkl = stkl - pseg; + ssptr = (struct stack_segment_linkage *) stkl; + size = ssptr->sssize; + pseg = ssptr->sspseg; + this_segment = stkl - size; + } + + result = address - this_segment; + + /* If you subtract pseg from the current end of the stack, + you get the address of the previous stack segment's end. + This seems a little convoluted to me, but I'll bet you save + a cycle somewhere. */ + + while (pseg != 0) + { +#ifdef DEBUG_I00AFUNC + fprintf (stderr, "%011o %011o\n", pseg, size); +#endif + stkl = stkl - pseg; + ssptr = (struct stack_segment_linkage *) stkl; + size = ssptr->sssize; + pseg = ssptr->sspseg; + result += size; + } + return (result); +} + +#endif /* not CRAY2 */ +#endif /* CRAY */ + +#endif /* no alloca */ +#endif /* not GCC version 2 */ diff --git a/src/asm/fstack.c b/src/asm/fstack.c index bf7d7d67..77a800fb 100644 --- a/src/asm/fstack.c +++ b/src/asm/fstack.c @@ -1,411 +1,411 @@ -/* - * RGBAsm - FSTACK.C (FileStack routines) - * - * INCLUDES - * - */ - -#include -#include -#include -#include "symbol.h" -#include "fstack.h" -#include "types.h" -#include "main.h" -#include "lexer.h" - -/* - * RGBAsm - FSTACK.C (FileStack routines) - * - * VARIABLES - * - */ - -struct sContext *pFileStack; -struct sSymbol *pCurrentMacro; -YY_BUFFER_STATE CurrentFlexHandle; -FILE *pCurrentFile; -ULONG nCurrentStatus; -char tzCurrentFileName[_MAX_PATH + 1]; -char IncludePaths[MAXINCPATHS][_MAX_PATH + 1]; -SLONG NextIncPath = 0; -ULONG nMacroCount; - -char *pCurrentREPTBlock; -ULONG nCurrentREPTBlockSize; -ULONG nCurrentREPTBlockCount; - -ULONG ulMacroReturnValue; - -/* - * defines for nCurrentStatus - */ -#define STAT_isInclude 0 -#define STAT_isMacro 1 -#define STAT_isMacroArg 2 -#define STAT_isREPTBlock 3 - -ULONG filesize (char *s) -{ - FILE *f; - ULONG size = 0; - - if( (f=fopen(s,"rt"))!=NULL ) - { - fseek (f, 0, SEEK_END); - size = ftell (f); - fclose (f); - } - return (size); -} - -/* - * RGBAsm - FSTACK.C (FileStack routines) - * - * Context push and pop - * - */ - -void pushcontext (void) -{ - struct sContext **ppFileStack; - - ppFileStack = &pFileStack; - while (*ppFileStack) - ppFileStack = &((*ppFileStack)->pNext); - - if( (*ppFileStack=(struct sContext *)malloc(sizeof (struct sContext)))!=NULL ) - { - (*ppFileStack)->FlexHandle = CurrentFlexHandle; - (*ppFileStack)->pNext = NULL; - strcpy ( (char *)(*ppFileStack)->tzFileName, (char *)tzCurrentFileName); - (*ppFileStack)->nLine = nLineNo; - switch ((*ppFileStack)->nStatus = nCurrentStatus) - { - case STAT_isMacroArg: - case STAT_isMacro: - sym_SaveCurrentMacroArgs ((*ppFileStack)->tzMacroArgs); - (*ppFileStack)->pMacro = pCurrentMacro; - break; - case STAT_isInclude: - (*ppFileStack)->pFile = pCurrentFile; - break; - case STAT_isREPTBlock: - sym_SaveCurrentMacroArgs ((*ppFileStack)->tzMacroArgs); - (*ppFileStack)->pREPTBlock = pCurrentREPTBlock; - (*ppFileStack)->nREPTBlockSize = nCurrentREPTBlockSize; - (*ppFileStack)->nREPTBlockCount = nCurrentREPTBlockCount; - break; - } - nLineNo = 0; - } - else - fatalerror ("No memory for context"); -} - -int popcontext (void) -{ - struct sContext *pLastFile, - **ppLastFile; - - if (nCurrentStatus == STAT_isREPTBlock) - { - if (--nCurrentREPTBlockCount) - { - yy_delete_buffer (CurrentFlexHandle); - CurrentFlexHandle = yy_scan_bytes (pCurrentREPTBlock, nCurrentREPTBlockSize); - yy_switch_to_buffer (CurrentFlexHandle); - sym_UseCurrentMacroArgs (); - sym_SetMacroArgID (nMacroCount++); - sym_UseNewMacroArgs (); - return (0); - } - } - - if( (pLastFile=pFileStack)!=NULL ) - { - ppLastFile = &pFileStack; - while (pLastFile->pNext) - { - ppLastFile = &(pLastFile->pNext); - pLastFile = *ppLastFile; - } - - yy_delete_buffer (CurrentFlexHandle); - nLineNo = pLastFile->nLine; - if (nCurrentStatus == STAT_isInclude) - fclose (pCurrentFile); - if (nCurrentStatus == STAT_isMacro) - { - sym_FreeCurrentMacroArgs (); - nLineNo += 1; - } - if (nCurrentStatus == STAT_isREPTBlock) - nLineNo += 1; - - CurrentFlexHandle = pLastFile->FlexHandle; - strcpy ((char *)tzCurrentFileName, (char *)pLastFile->tzFileName); - switch (nCurrentStatus = pLastFile->nStatus) - { - case STAT_isMacroArg: - case STAT_isMacro: - sym_RestoreCurrentMacroArgs (pLastFile->tzMacroArgs); - pCurrentMacro = pLastFile->pMacro; - break; - case STAT_isInclude: - pCurrentFile = pLastFile->pFile; - break; - case STAT_isREPTBlock: - sym_RestoreCurrentMacroArgs (pLastFile->tzMacroArgs); - pCurrentREPTBlock = pLastFile->pREPTBlock; - nCurrentREPTBlockSize = pLastFile->nREPTBlockSize; - nCurrentREPTBlockCount = pLastFile->nREPTBlockCount; - break; - } - - free (*ppLastFile); - *ppLastFile = NULL; - yy_switch_to_buffer (CurrentFlexHandle); - return (0); - } - else - return (1); -} - -int yywrap (void) -{ - return (popcontext ()); -} - -/* - * RGBAsm - FSTACK.C (FileStack routines) - * - * Dump the context stack to stdout - * - */ - -void fstk_Dump (void) -{ - struct sContext *pLastFile; - - pLastFile = pFileStack; - - while (pLastFile) - { - printf ("%s(%ld) -> ", pLastFile->tzFileName, pLastFile->nLine); - pLastFile = pLastFile->pNext; - } - - printf ("%s(%ld)", tzCurrentFileName, nLineNo); -} - -/* - * RGBAsm - FSTACK.C (FileStack routines) - * - * Extra includepath stuff - * - */ - -void fstk_AddIncludePath (char *s) -{ - strcpy (IncludePaths[NextIncPath++], s); -} - -void fstk_FindFile (char *s) -{ - char t[_MAX_PATH + 1]; - SLONG i = -1; - - strcpy (t, s); - - while (i < NextIncPath) - { - FILE *f; - - if( (f=fopen(t,"rb"))!=NULL ) - { - fclose (f); - strcpy (s, t); - return; - } - i += 1; - if (i < NextIncPath) - { - strcpy (t, IncludePaths[i]); - strcat (t, s); - } - } -} - -/* - * RGBAsm - FSTACK.C (FileStack routines) - * - * Set up an include file for parsing - * - */ - -ULONG fstk_RunInclude (char *s) -{ - FILE *f; - char tzFileName[_MAX_PATH + 1]; - - //printf( "INCLUDE: %s\n", s ); - - strcpy (tzFileName, s); - fstk_FindFile (tzFileName); - //printf( "INCLUDING: %s\n", tzFileName ); - - if( (f=fopen(tzFileName,"rt"))!=NULL ) - { - pushcontext (); - nLineNo = 1; - nCurrentStatus = STAT_isInclude; - strcpy (tzCurrentFileName, tzFileName); - pCurrentFile = f; - CurrentFlexHandle = yy_create_buffer (pCurrentFile); - yy_switch_to_buffer (CurrentFlexHandle); - - // Dirty hack to give the INCLUDE directive a linefeed - - yyunput( '\n' ); - nLineNo-=1; - - return (1); - } - else - return (0); -} - -/* - * RGBAsm - FSTACK.C (FileStack routines) - * - * Set up a macro for parsing - * - */ - -ULONG fstk_RunMacro (char *s) -{ - struct sSymbol *sym; - - if( (sym=sym_FindMacro(s))!=NULL ) - { - pushcontext (); - sym_SetMacroArgID (nMacroCount++); - nLineNo = -1; - sym_UseNewMacroArgs (); - nCurrentStatus = STAT_isMacro; - strcpy (tzCurrentFileName, s); - pCurrentMacro = sym; - CurrentFlexHandle = yy_scan_bytes (pCurrentMacro->pMacro, pCurrentMacro->ulMacroSize); - yy_switch_to_buffer (CurrentFlexHandle); - return (1); - } - else - return (0); -} - -/* - * RGBAsm - FSTACK.C (FileStack routines) - * - * Set up a macroargument for parsing - * - */ - -void fstk_RunMacroArg (SLONG s) -{ - char *sym; - - if (s == '@') - s = -1; - else - s -= '0'; - - if( (sym=sym_FindMacroArg(s))!=NULL ) - { - pushcontext (); - nCurrentStatus = STAT_isMacroArg; - sprintf (tzCurrentFileName, "%c", (UBYTE)s); - CurrentFlexHandle = yy_scan_bytes (sym, strlen (sym)); - yy_switch_to_buffer (CurrentFlexHandle); - } - else - fatalerror ("No such macroargument"); -} - -/* - * RGBAsm - FSTACK.C (FileStack routines) - * - * Set up a stringequate for parsing - * - */ - -void fstk_RunString (char *s) -{ - struct sSymbol *pSym; - - if( (pSym=sym_FindSymbol(s))!=NULL ) - { - pushcontext (); - nCurrentStatus = STAT_isMacroArg; - strcpy (tzCurrentFileName, s); - CurrentFlexHandle = yy_scan_bytes (pSym->pMacro, strlen (pSym->pMacro)); - yy_switch_to_buffer (CurrentFlexHandle); - } - else - yyerror ("No such string symbol"); -} - -/* - * RGBAsm - FSTACK.C (FileStack routines) - * - * Set up a repeat block for parsing - * - */ - -void fstk_RunRept (ULONG count) -{ - if (count) - { - pushcontext (); - sym_UseCurrentMacroArgs (); - sym_SetMacroArgID (nMacroCount++); - sym_UseNewMacroArgs (); - nCurrentREPTBlockCount = count; - nCurrentStatus = STAT_isREPTBlock; - nCurrentREPTBlockSize = ulNewMacroSize; - pCurrentREPTBlock = tzNewMacro; - CurrentFlexHandle = yy_scan_bytes (pCurrentREPTBlock, nCurrentREPTBlockSize); - yy_switch_to_buffer (CurrentFlexHandle); - } -} - -/* - * RGBAsm - FSTACK.C (FileStack routines) - * - * Initialize the filestack routines - * - */ - -ULONG fstk_Init (char *s) -{ - char tzFileName[_MAX_PATH + 1]; - - sym_AddString ("__FILE__", s); - - strcpy (tzFileName, s); - fstk_FindFile (tzFileName); - - pFileStack = NULL; - if( (pCurrentFile=fopen(tzFileName,"rt"))!=NULL ) - { - nMacroCount = 0; - nCurrentStatus = STAT_isInclude; - strcpy (tzCurrentFileName, tzFileName); - CurrentFlexHandle = yy_create_buffer (pCurrentFile); - yy_switch_to_buffer (CurrentFlexHandle); - nLineNo = 1; - return (1); - } - else - return (0); +/* + * RGBAsm - FSTACK.C (FileStack routines) + * + * INCLUDES + * + */ + +#include +#include +#include +#include "symbol.h" +#include "fstack.h" +#include "types.h" +#include "main.h" +#include "lexer.h" + +/* + * RGBAsm - FSTACK.C (FileStack routines) + * + * VARIABLES + * + */ + +struct sContext *pFileStack; +struct sSymbol *pCurrentMacro; +YY_BUFFER_STATE CurrentFlexHandle; +FILE *pCurrentFile; +ULONG nCurrentStatus; +char tzCurrentFileName[_MAX_PATH + 1]; +char IncludePaths[MAXINCPATHS][_MAX_PATH + 1]; +SLONG NextIncPath = 0; +ULONG nMacroCount; + +char *pCurrentREPTBlock; +ULONG nCurrentREPTBlockSize; +ULONG nCurrentREPTBlockCount; + +ULONG ulMacroReturnValue; + +/* + * defines for nCurrentStatus + */ +#define STAT_isInclude 0 +#define STAT_isMacro 1 +#define STAT_isMacroArg 2 +#define STAT_isREPTBlock 3 + +ULONG filesize (char *s) +{ + FILE *f; + ULONG size = 0; + + if( (f=fopen(s,"rt"))!=NULL ) + { + fseek (f, 0, SEEK_END); + size = ftell (f); + fclose (f); + } + return (size); +} + +/* + * RGBAsm - FSTACK.C (FileStack routines) + * + * Context push and pop + * + */ + +void pushcontext (void) +{ + struct sContext **ppFileStack; + + ppFileStack = &pFileStack; + while (*ppFileStack) + ppFileStack = &((*ppFileStack)->pNext); + + if( (*ppFileStack=(struct sContext *)malloc(sizeof (struct sContext)))!=NULL ) + { + (*ppFileStack)->FlexHandle = CurrentFlexHandle; + (*ppFileStack)->pNext = NULL; + strcpy ( (char *)(*ppFileStack)->tzFileName, (char *)tzCurrentFileName); + (*ppFileStack)->nLine = nLineNo; + switch ((*ppFileStack)->nStatus = nCurrentStatus) + { + case STAT_isMacroArg: + case STAT_isMacro: + sym_SaveCurrentMacroArgs ((*ppFileStack)->tzMacroArgs); + (*ppFileStack)->pMacro = pCurrentMacro; + break; + case STAT_isInclude: + (*ppFileStack)->pFile = pCurrentFile; + break; + case STAT_isREPTBlock: + sym_SaveCurrentMacroArgs ((*ppFileStack)->tzMacroArgs); + (*ppFileStack)->pREPTBlock = pCurrentREPTBlock; + (*ppFileStack)->nREPTBlockSize = nCurrentREPTBlockSize; + (*ppFileStack)->nREPTBlockCount = nCurrentREPTBlockCount; + break; + } + nLineNo = 0; + } + else + fatalerror ("No memory for context"); +} + +int popcontext (void) +{ + struct sContext *pLastFile, + **ppLastFile; + + if (nCurrentStatus == STAT_isREPTBlock) + { + if (--nCurrentREPTBlockCount) + { + yy_delete_buffer (CurrentFlexHandle); + CurrentFlexHandle = yy_scan_bytes (pCurrentREPTBlock, nCurrentREPTBlockSize); + yy_switch_to_buffer (CurrentFlexHandle); + sym_UseCurrentMacroArgs (); + sym_SetMacroArgID (nMacroCount++); + sym_UseNewMacroArgs (); + return (0); + } + } + + if( (pLastFile=pFileStack)!=NULL ) + { + ppLastFile = &pFileStack; + while (pLastFile->pNext) + { + ppLastFile = &(pLastFile->pNext); + pLastFile = *ppLastFile; + } + + yy_delete_buffer (CurrentFlexHandle); + nLineNo = pLastFile->nLine; + if (nCurrentStatus == STAT_isInclude) + fclose (pCurrentFile); + if (nCurrentStatus == STAT_isMacro) + { + sym_FreeCurrentMacroArgs (); + nLineNo += 1; + } + if (nCurrentStatus == STAT_isREPTBlock) + nLineNo += 1; + + CurrentFlexHandle = pLastFile->FlexHandle; + strcpy ((char *)tzCurrentFileName, (char *)pLastFile->tzFileName); + switch (nCurrentStatus = pLastFile->nStatus) + { + case STAT_isMacroArg: + case STAT_isMacro: + sym_RestoreCurrentMacroArgs (pLastFile->tzMacroArgs); + pCurrentMacro = pLastFile->pMacro; + break; + case STAT_isInclude: + pCurrentFile = pLastFile->pFile; + break; + case STAT_isREPTBlock: + sym_RestoreCurrentMacroArgs (pLastFile->tzMacroArgs); + pCurrentREPTBlock = pLastFile->pREPTBlock; + nCurrentREPTBlockSize = pLastFile->nREPTBlockSize; + nCurrentREPTBlockCount = pLastFile->nREPTBlockCount; + break; + } + + free (*ppLastFile); + *ppLastFile = NULL; + yy_switch_to_buffer (CurrentFlexHandle); + return (0); + } + else + return (1); +} + +int yywrap (void) +{ + return (popcontext ()); +} + +/* + * RGBAsm - FSTACK.C (FileStack routines) + * + * Dump the context stack to stdout + * + */ + +void fstk_Dump (void) +{ + struct sContext *pLastFile; + + pLastFile = pFileStack; + + while (pLastFile) + { + printf ("%s(%ld) -> ", pLastFile->tzFileName, pLastFile->nLine); + pLastFile = pLastFile->pNext; + } + + printf ("%s(%ld)", tzCurrentFileName, nLineNo); +} + +/* + * RGBAsm - FSTACK.C (FileStack routines) + * + * Extra includepath stuff + * + */ + +void fstk_AddIncludePath (char *s) +{ + strcpy (IncludePaths[NextIncPath++], s); +} + +void fstk_FindFile (char *s) +{ + char t[_MAX_PATH + 1]; + SLONG i = -1; + + strcpy (t, s); + + while (i < NextIncPath) + { + FILE *f; + + if( (f=fopen(t,"rb"))!=NULL ) + { + fclose (f); + strcpy (s, t); + return; + } + i += 1; + if (i < NextIncPath) + { + strcpy (t, IncludePaths[i]); + strcat (t, s); + } + } +} + +/* + * RGBAsm - FSTACK.C (FileStack routines) + * + * Set up an include file for parsing + * + */ + +ULONG fstk_RunInclude (char *s) +{ + FILE *f; + char tzFileName[_MAX_PATH + 1]; + + //printf( "INCLUDE: %s\n", s ); + + strcpy (tzFileName, s); + fstk_FindFile (tzFileName); + //printf( "INCLUDING: %s\n", tzFileName ); + + if( (f=fopen(tzFileName,"rt"))!=NULL ) + { + pushcontext (); + nLineNo = 1; + nCurrentStatus = STAT_isInclude; + strcpy (tzCurrentFileName, tzFileName); + pCurrentFile = f; + CurrentFlexHandle = yy_create_buffer (pCurrentFile); + yy_switch_to_buffer (CurrentFlexHandle); + + // Dirty hack to give the INCLUDE directive a linefeed + + yyunput( '\n' ); + nLineNo-=1; + + return (1); + } + else + return (0); +} + +/* + * RGBAsm - FSTACK.C (FileStack routines) + * + * Set up a macro for parsing + * + */ + +ULONG fstk_RunMacro (char *s) +{ + struct sSymbol *sym; + + if( (sym=sym_FindMacro(s))!=NULL ) + { + pushcontext (); + sym_SetMacroArgID (nMacroCount++); + nLineNo = -1; + sym_UseNewMacroArgs (); + nCurrentStatus = STAT_isMacro; + strcpy (tzCurrentFileName, s); + pCurrentMacro = sym; + CurrentFlexHandle = yy_scan_bytes (pCurrentMacro->pMacro, pCurrentMacro->ulMacroSize); + yy_switch_to_buffer (CurrentFlexHandle); + return (1); + } + else + return (0); +} + +/* + * RGBAsm - FSTACK.C (FileStack routines) + * + * Set up a macroargument for parsing + * + */ + +void fstk_RunMacroArg (SLONG s) +{ + char *sym; + + if (s == '@') + s = -1; + else + s -= '0'; + + if( (sym=sym_FindMacroArg(s))!=NULL ) + { + pushcontext (); + nCurrentStatus = STAT_isMacroArg; + sprintf (tzCurrentFileName, "%c", (UBYTE)s); + CurrentFlexHandle = yy_scan_bytes (sym, strlen (sym)); + yy_switch_to_buffer (CurrentFlexHandle); + } + else + fatalerror ("No such macroargument"); +} + +/* + * RGBAsm - FSTACK.C (FileStack routines) + * + * Set up a stringequate for parsing + * + */ + +void fstk_RunString (char *s) +{ + struct sSymbol *pSym; + + if( (pSym=sym_FindSymbol(s))!=NULL ) + { + pushcontext (); + nCurrentStatus = STAT_isMacroArg; + strcpy (tzCurrentFileName, s); + CurrentFlexHandle = yy_scan_bytes (pSym->pMacro, strlen (pSym->pMacro)); + yy_switch_to_buffer (CurrentFlexHandle); + } + else + yyerror ("No such string symbol"); +} + +/* + * RGBAsm - FSTACK.C (FileStack routines) + * + * Set up a repeat block for parsing + * + */ + +void fstk_RunRept (ULONG count) +{ + if (count) + { + pushcontext (); + sym_UseCurrentMacroArgs (); + sym_SetMacroArgID (nMacroCount++); + sym_UseNewMacroArgs (); + nCurrentREPTBlockCount = count; + nCurrentStatus = STAT_isREPTBlock; + nCurrentREPTBlockSize = ulNewMacroSize; + pCurrentREPTBlock = tzNewMacro; + CurrentFlexHandle = yy_scan_bytes (pCurrentREPTBlock, nCurrentREPTBlockSize); + yy_switch_to_buffer (CurrentFlexHandle); + } +} + +/* + * RGBAsm - FSTACK.C (FileStack routines) + * + * Initialize the filestack routines + * + */ + +ULONG fstk_Init (char *s) +{ + char tzFileName[_MAX_PATH + 1]; + + sym_AddString ("__FILE__", s); + + strcpy (tzFileName, s); + fstk_FindFile (tzFileName); + + pFileStack = NULL; + if( (pCurrentFile=fopen(tzFileName,"rt"))!=NULL ) + { + nMacroCount = 0; + nCurrentStatus = STAT_isInclude; + strcpy (tzCurrentFileName, tzFileName); + CurrentFlexHandle = yy_create_buffer (pCurrentFile); + yy_switch_to_buffer (CurrentFlexHandle); + nLineNo = 1; + return (1); + } + else + return (0); } \ No newline at end of file diff --git a/src/asm/gameboy/localasm.h b/src/asm/gameboy/localasm.h index 768a6b64..489465cd 100644 --- a/src/asm/gameboy/localasm.h +++ b/src/asm/gameboy/localasm.h @@ -1,154 +1,154 @@ -/* GB Z80 instruction groups - - n3 = 3-bit - n = 8-bit - nn = 16-bit - -*ADC A,n : 0xCE -*ADC A,r : 0x88|r -*ADD A,n : 0xC6 -*ADD A,r : 0x80|r -*ADD HL,ss : 0x09|(ss<<4) -*ADD SP,n : 0xE8 -*AND A,n : 0xE6 -*AND A,r : 0xA0|r -*BIT n3,r : 0xCB 0x40|(n3<<3)|r -*CALL cc,nn : 0xC4|(cc<<3) -*CALL nn : 0xCD -*CCF : 0x3F -*CP A,n : 0xFE -*CP A,r : 0xB8|r -*CPL : 0x2F -*DAA : 0x27 -*DEC r : 0x05|(r<<3) -*DEC ss : 0x0B|(ss<<4) -*DI : 0xF3 -*EI : 0xFB -*EX HL,(SP) : 0xE3 -*HALT : 0x76 -*INC r : 0x04|(r<<3) -*INC ss : 0x03|(ss<<4) -*JP (HL) : 0xE9 -*JP cc,nn : 0xC2|(cc<<3) -*JP nn : 0xC3|(cc<<3) -*JR n : 0x18 -*JR cc,n : 0x20|(cc<<3) -*LD (nn),SP : 0x08 -*LD ($FF00+C),A : 0xE2 -*LD ($FF00+n),A : 0xE0 -*LD (nn),A : 0xEA -*LD (rr),A : 0x02|(rr<<4) -*LD A,($FF00+C) : 0xF2 -*LD A,($FF00+n) : 0xF0 -*LD A,(nn) : 0xFA -*LD A,(rr) : 0x0A|(rr<<4) -*LD HL,(SP+n) : 0xF8 -*LD SP,HL : 0xF9 -*LD r,n : 0x06|(r<<3) -*LD r,r' : 0x40|(r<<3)|r' // NOTE: LD (HL),(HL) not allowed -*LD ss,nn : 0x01|(ss<<4) -*NOP : 0x00 -*OR A,n : 0xF6 -*OR A,r : 0xB0|r -*POP tt : 0xC1|(tt<<4) -*PUSH tt : 0xC5|(tt<<4) -*RES n3,r : 0xCB 0x80|(n3<<3)|r -*RET : 0xC9 -*RET cc : 0xC0|(cc<<3) -*RETI : 0xD9 -*RL r : 0xCB 0x10|r -*RLA : 0x17 -*RLC r : 0xCB 0x00|r -*RLCA : 0x07 -*RR r : 0xCB 0x18|r -*RRA : 0x1F -*RRC r : 0xCB 0x08|r -*RRCA : 0x0F -*RST n : 0xC7|n -*SBC A,n : 0xDE -*SBC A,r : 0x98|r -*SCF : 0x37 -*SET n3,r : 0xCB 0xC0|(n8<<3)|r -*SLA r : 0xCB 0x20|r -*SRA r : 0xCB 0x28|r -*SRL r : 0xCB 0x38|r -*STOP : 0x10 -*SUB A,n : 0xD6 -*SUB A,r : 0x90|r -*SWAP r : 0xCB 0x30|r -*XOR A,n : 0xEE -*XOR A,r : 0xA8|r - - */ - -#define MAXSECTIONSIZE 0x4000 - -#define ASM_DEFAULT_ENDIAN ASM_LITTLE_ENDIAN - -#define APPNAME "RGBAsm" -#define EXENAME "rgbasm" - -#define NAME_DB "db" -#define NAME_DW "dw" -#define NAME_RB "rb" -#define NAME_RW "rw" - -/* "r" defs */ - -enum -{ - REG_B=0, - REG_C, - REG_D, - REG_E, - REG_H, - REG_L, - REG_HL_IND, - REG_A -}; - -/* "rr" defs */ - -enum -{ - REG_BC_IND=0, - REG_DE_IND, - REG_HL_INDINC, - REG_HL_INDDEC, -}; - -/* "ss" defs */ - -enum -{ - REG_BC=0, - REG_DE, - REG_HL, - REG_SP -}; - -/* "tt" defs */ - -/* -#define REG_BC 0 -#define REG_DE 1 -#define REG_HL 2 - */ -#define REG_AF 3 - -/* "cc" defs */ - -enum -{ - CC_NZ=0, - CC_Z, - CC_NC, - CC_C -}; - - - - - - - +/* GB Z80 instruction groups + + n3 = 3-bit + n = 8-bit + nn = 16-bit + +*ADC A,n : 0xCE +*ADC A,r : 0x88|r +*ADD A,n : 0xC6 +*ADD A,r : 0x80|r +*ADD HL,ss : 0x09|(ss<<4) +*ADD SP,n : 0xE8 +*AND A,n : 0xE6 +*AND A,r : 0xA0|r +*BIT n3,r : 0xCB 0x40|(n3<<3)|r +*CALL cc,nn : 0xC4|(cc<<3) +*CALL nn : 0xCD +*CCF : 0x3F +*CP A,n : 0xFE +*CP A,r : 0xB8|r +*CPL : 0x2F +*DAA : 0x27 +*DEC r : 0x05|(r<<3) +*DEC ss : 0x0B|(ss<<4) +*DI : 0xF3 +*EI : 0xFB +*EX HL,(SP) : 0xE3 +*HALT : 0x76 +*INC r : 0x04|(r<<3) +*INC ss : 0x03|(ss<<4) +*JP (HL) : 0xE9 +*JP cc,nn : 0xC2|(cc<<3) +*JP nn : 0xC3|(cc<<3) +*JR n : 0x18 +*JR cc,n : 0x20|(cc<<3) +*LD (nn),SP : 0x08 +*LD ($FF00+C),A : 0xE2 +*LD ($FF00+n),A : 0xE0 +*LD (nn),A : 0xEA +*LD (rr),A : 0x02|(rr<<4) +*LD A,($FF00+C) : 0xF2 +*LD A,($FF00+n) : 0xF0 +*LD A,(nn) : 0xFA +*LD A,(rr) : 0x0A|(rr<<4) +*LD HL,(SP+n) : 0xF8 +*LD SP,HL : 0xF9 +*LD r,n : 0x06|(r<<3) +*LD r,r' : 0x40|(r<<3)|r' // NOTE: LD (HL),(HL) not allowed +*LD ss,nn : 0x01|(ss<<4) +*NOP : 0x00 +*OR A,n : 0xF6 +*OR A,r : 0xB0|r +*POP tt : 0xC1|(tt<<4) +*PUSH tt : 0xC5|(tt<<4) +*RES n3,r : 0xCB 0x80|(n3<<3)|r +*RET : 0xC9 +*RET cc : 0xC0|(cc<<3) +*RETI : 0xD9 +*RL r : 0xCB 0x10|r +*RLA : 0x17 +*RLC r : 0xCB 0x00|r +*RLCA : 0x07 +*RR r : 0xCB 0x18|r +*RRA : 0x1F +*RRC r : 0xCB 0x08|r +*RRCA : 0x0F +*RST n : 0xC7|n +*SBC A,n : 0xDE +*SBC A,r : 0x98|r +*SCF : 0x37 +*SET n3,r : 0xCB 0xC0|(n8<<3)|r +*SLA r : 0xCB 0x20|r +*SRA r : 0xCB 0x28|r +*SRL r : 0xCB 0x38|r +*STOP : 0x10 +*SUB A,n : 0xD6 +*SUB A,r : 0x90|r +*SWAP r : 0xCB 0x30|r +*XOR A,n : 0xEE +*XOR A,r : 0xA8|r + + */ + +#define MAXSECTIONSIZE 0x4000 + +#define ASM_DEFAULT_ENDIAN ASM_LITTLE_ENDIAN + +#define APPNAME "RGBAsm" +#define EXENAME "rgbasm" + +#define NAME_DB "db" +#define NAME_DW "dw" +#define NAME_RB "rb" +#define NAME_RW "rw" + +/* "r" defs */ + +enum +{ + REG_B=0, + REG_C, + REG_D, + REG_E, + REG_H, + REG_L, + REG_HL_IND, + REG_A +}; + +/* "rr" defs */ + +enum +{ + REG_BC_IND=0, + REG_DE_IND, + REG_HL_INDINC, + REG_HL_INDDEC, +}; + +/* "ss" defs */ + +enum +{ + REG_BC=0, + REG_DE, + REG_HL, + REG_SP +}; + +/* "tt" defs */ + +/* +#define REG_BC 0 +#define REG_DE 1 +#define REG_HL 2 + */ +#define REG_AF 3 + +/* "cc" defs */ + +enum +{ + CC_NZ=0, + CC_Z, + CC_NC, + CC_C +}; + + + + + + + diff --git a/src/asm/gameboy/locallex.c b/src/asm/gameboy/locallex.c index 105df32f..3601d8d7 100644 --- a/src/asm/gameboy/locallex.c +++ b/src/asm/gameboy/locallex.c @@ -1,89 +1,89 @@ -#include "symbol.h" -#include "lexer.h" -#include "rpn.h" -#include "asmy.h" - -struct sLexInitString localstrings[] = -{ - "adc", T_Z80_ADC, - "add", T_Z80_ADD, - "and", T_Z80_AND, - "bit", T_Z80_BIT, - "call", T_Z80_CALL, - "ccf", T_Z80_CCF, - "cpl", T_Z80_CPL, - "cp", T_Z80_CP, - "daa", T_Z80_DAA, - "dec", T_Z80_DEC, - "di", T_Z80_DI, - "ei", T_Z80_EI, - "ex", T_Z80_EX, - "halt", T_Z80_HALT, - "inc", T_Z80_INC, - "jp", T_Z80_JP, - "jr", T_Z80_JR, - "ld", T_Z80_LD, - "ldi", T_Z80_LDI, - "ldd", T_Z80_LDD, - "ldio", T_Z80_LDIO, - "ldh", T_Z80_LDIO, - "nop", T_Z80_NOP, - "or", T_Z80_OR, - "pop", T_Z80_POP, - "push", T_Z80_PUSH, - "res", T_Z80_RES, - "reti", T_Z80_RETI, - "ret", T_Z80_RET, - "rlca", T_Z80_RLCA, - "rlc", T_Z80_RLC, - "rla", T_Z80_RLA, - "rl", T_Z80_RL, - "rrc", T_Z80_RRC, - "rrca", T_Z80_RRCA, - "rra", T_Z80_RRA, - "rr", T_Z80_RR, - "rst", T_Z80_RST, - "sbc", T_Z80_SBC, - "scf", T_Z80_SCF, - -// Handled by globallex.c -// "set" , T_POP_SET, - - "sla", T_Z80_SLA, - "sra", T_Z80_SRA, - "srl", T_Z80_SRL, - "stop", T_Z80_STOP, - "sub", T_Z80_SUB, - "swap", T_Z80_SWAP, - "xor", T_Z80_XOR, - - "nz", T_CC_NZ, - "z", T_CC_Z, - "nc", T_CC_NC, -// "c" , T_MODE_C - - "[hl]", T_MODE_HL_IND, - "[hl+]", T_MODE_HL_INDINC, - "[hl-]", T_MODE_HL_INDDEC, - "[hli]", T_MODE_HL_INDINC, - "[hld]", T_MODE_HL_INDDEC, - "hl", T_MODE_HL, - "af", T_MODE_AF, - "[bc]", T_MODE_BC_IND, - "bc", T_MODE_BC, - "[de]", T_MODE_DE_IND, - "de", T_MODE_DE, - "[sp]", T_MODE_SP_IND, - "sp", T_MODE_SP, - "a", T_MODE_A, - "b", T_MODE_B, - "[$ff00+c]", T_MODE_C_IND, - "[c]", T_MODE_C_IND, - "c", T_MODE_C, - "d", T_MODE_D, - "e", T_MODE_E, - "h", T_MODE_H, - "l", T_MODE_L, - - NULL, 0 +#include "symbol.h" +#include "lexer.h" +#include "rpn.h" +#include "asmy.h" + +struct sLexInitString localstrings[] = +{ + "adc", T_Z80_ADC, + "add", T_Z80_ADD, + "and", T_Z80_AND, + "bit", T_Z80_BIT, + "call", T_Z80_CALL, + "ccf", T_Z80_CCF, + "cpl", T_Z80_CPL, + "cp", T_Z80_CP, + "daa", T_Z80_DAA, + "dec", T_Z80_DEC, + "di", T_Z80_DI, + "ei", T_Z80_EI, + "ex", T_Z80_EX, + "halt", T_Z80_HALT, + "inc", T_Z80_INC, + "jp", T_Z80_JP, + "jr", T_Z80_JR, + "ld", T_Z80_LD, + "ldi", T_Z80_LDI, + "ldd", T_Z80_LDD, + "ldio", T_Z80_LDIO, + "ldh", T_Z80_LDIO, + "nop", T_Z80_NOP, + "or", T_Z80_OR, + "pop", T_Z80_POP, + "push", T_Z80_PUSH, + "res", T_Z80_RES, + "reti", T_Z80_RETI, + "ret", T_Z80_RET, + "rlca", T_Z80_RLCA, + "rlc", T_Z80_RLC, + "rla", T_Z80_RLA, + "rl", T_Z80_RL, + "rrc", T_Z80_RRC, + "rrca", T_Z80_RRCA, + "rra", T_Z80_RRA, + "rr", T_Z80_RR, + "rst", T_Z80_RST, + "sbc", T_Z80_SBC, + "scf", T_Z80_SCF, + +// Handled by globallex.c +// "set" , T_POP_SET, + + "sla", T_Z80_SLA, + "sra", T_Z80_SRA, + "srl", T_Z80_SRL, + "stop", T_Z80_STOP, + "sub", T_Z80_SUB, + "swap", T_Z80_SWAP, + "xor", T_Z80_XOR, + + "nz", T_CC_NZ, + "z", T_CC_Z, + "nc", T_CC_NC, +// "c" , T_MODE_C + + "[hl]", T_MODE_HL_IND, + "[hl+]", T_MODE_HL_INDINC, + "[hl-]", T_MODE_HL_INDDEC, + "[hli]", T_MODE_HL_INDINC, + "[hld]", T_MODE_HL_INDDEC, + "hl", T_MODE_HL, + "af", T_MODE_AF, + "[bc]", T_MODE_BC_IND, + "bc", T_MODE_BC, + "[de]", T_MODE_DE_IND, + "de", T_MODE_DE, + "[sp]", T_MODE_SP_IND, + "sp", T_MODE_SP, + "a", T_MODE_A, + "b", T_MODE_B, + "[$ff00+c]", T_MODE_C_IND, + "[c]", T_MODE_C_IND, + "c", T_MODE_C, + "d", T_MODE_D, + "e", T_MODE_E, + "h", T_MODE_H, + "l", T_MODE_L, + + NULL, 0 }; \ No newline at end of file diff --git a/src/asm/gameboy/yaccprt2.y b/src/asm/gameboy/yaccprt2.y index 56aa1bb6..2191e6ce 100644 --- a/src/asm/gameboy/yaccprt2.y +++ b/src/asm/gameboy/yaccprt2.y @@ -1,41 +1,41 @@ -%token T_SECT_BSS T_SECT_VRAM T_SECT_CODE T_SECT_HOME T_SECT_HRAM - -%token T_Z80_ADC T_Z80_ADD T_Z80_AND -%token T_Z80_BIT -%token T_Z80_CALL T_Z80_CCF T_Z80_CP T_Z80_CPL -%token T_Z80_DAA T_Z80_DEC T_Z80_DI -%token T_Z80_EI T_Z80_EX -%token T_Z80_HALT -%token T_Z80_INC -%token T_Z80_JP T_Z80_JR -%token T_Z80_LD -%token T_Z80_LDI -%token T_Z80_LDD -%token T_Z80_LDIO -%token T_Z80_NOP -%token T_Z80_OR -%token T_Z80_POP T_Z80_PUSH -%token T_Z80_RES T_Z80_RET T_Z80_RETI T_Z80_RST -%token T_Z80_RL T_Z80_RLA T_Z80_RLC T_Z80_RLCA -%token T_Z80_RR T_Z80_RRA T_Z80_RRC T_Z80_RRCA -%token T_Z80_SBC T_Z80_SCF T_Z80_STOP -%token T_Z80_SLA T_Z80_SRA T_Z80_SRL T_Z80_SUB T_Z80_SWAP -%token T_Z80_XOR - -%token T_MODE_A T_MODE_B T_MODE_C T_MODE_C_IND T_MODE_D T_MODE_E T_MODE_H T_MODE_L -%token T_MODE_AF -%token T_MODE_BC T_MODE_BC_IND -%token T_MODE_DE T_MODE_DE_IND -%token T_MODE_SP T_MODE_SP_IND -%token T_MODE_HL T_MODE_HL_IND T_MODE_HL_INDDEC T_MODE_HL_INDINC -%token T_CC_NZ T_CC_Z T_CC_NC - -%type reg_r -%type reg_ss -%type reg_rr -%type reg_tt -%type ccode -%type op_a_n -%type op_a_r -%type op_hl_ss -%type op_mem_ind +%token T_SECT_BSS T_SECT_VRAM T_SECT_CODE T_SECT_HOME T_SECT_HRAM + +%token T_Z80_ADC T_Z80_ADD T_Z80_AND +%token T_Z80_BIT +%token T_Z80_CALL T_Z80_CCF T_Z80_CP T_Z80_CPL +%token T_Z80_DAA T_Z80_DEC T_Z80_DI +%token T_Z80_EI T_Z80_EX +%token T_Z80_HALT +%token T_Z80_INC +%token T_Z80_JP T_Z80_JR +%token T_Z80_LD +%token T_Z80_LDI +%token T_Z80_LDD +%token T_Z80_LDIO +%token T_Z80_NOP +%token T_Z80_OR +%token T_Z80_POP T_Z80_PUSH +%token T_Z80_RES T_Z80_RET T_Z80_RETI T_Z80_RST +%token T_Z80_RL T_Z80_RLA T_Z80_RLC T_Z80_RLCA +%token T_Z80_RR T_Z80_RRA T_Z80_RRC T_Z80_RRCA +%token T_Z80_SBC T_Z80_SCF T_Z80_STOP +%token T_Z80_SLA T_Z80_SRA T_Z80_SRL T_Z80_SUB T_Z80_SWAP +%token T_Z80_XOR + +%token T_MODE_A T_MODE_B T_MODE_C T_MODE_C_IND T_MODE_D T_MODE_E T_MODE_H T_MODE_L +%token T_MODE_AF +%token T_MODE_BC T_MODE_BC_IND +%token T_MODE_DE T_MODE_DE_IND +%token T_MODE_SP T_MODE_SP_IND +%token T_MODE_HL T_MODE_HL_IND T_MODE_HL_INDDEC T_MODE_HL_INDINC +%token T_CC_NZ T_CC_Z T_CC_NC + +%type reg_r +%type reg_ss +%type reg_rr +%type reg_tt +%type ccode +%type op_a_n +%type op_a_r +%type op_hl_ss +%type op_mem_ind diff --git a/src/asm/gameboy/yaccprt4.y b/src/asm/gameboy/yaccprt4.y index 39aebbbd..981f8657 100644 --- a/src/asm/gameboy/yaccprt4.y +++ b/src/asm/gameboy/yaccprt4.y @@ -1,498 +1,498 @@ -section : T_POP_SECTION string ',' sectiontype - { out_NewSection($2,$4); } - | T_POP_SECTION string ',' sectiontype '[' const ']' - { - if( $6>=0 && $6<0x10000 ) - out_NewAbsSection($2,$4,$6,-1); - else - yyerror( "Address must be 16-bit" ); - } - | T_POP_SECTION string ',' sectiontype ',' T_OP_BANK '[' const ']' - { - if( $4==SECT_CODE ) - { - if( $8>=1 && $8<=255 ) - out_NewAbsSection($2,$4,-1,$8); - else - yyerror( "BANK value out of range" ); - } - else - yyerror( "BANK only allowed for CODE/DATA" ); - } - | T_POP_SECTION string ',' sectiontype '[' const ']' ',' T_OP_BANK '[' const ']' - { - if( $4==SECT_CODE ) - { - if( $6>=0 && $6<0x10000 ) - { - if( $11>=1 && $11<=255 ) - out_NewAbsSection($2,$4,$6,$11); - else - yyerror( "BANK value out of range" ); - } - else - yyerror( "Address must be 16-bit" ); - } - else - yyerror( "BANK only allowed for CODE/DATA" ); - } -; - -sectiontype : T_SECT_BSS { $$=SECT_BSS; } - | T_SECT_VRAM { $$=SECT_VRAM; } - | T_SECT_CODE { $$=SECT_CODE; } - | T_SECT_HOME { $$=SECT_HOME; } - | T_SECT_HRAM { $$=SECT_HRAM; } -; - - -cpu_command : z80_adc - | z80_add - | z80_and - | z80_bit - | z80_call - | z80_ccf - | z80_cp - | z80_cpl - | z80_daa - | z80_dec - | z80_di - | z80_ei - | z80_ex - | z80_halt - | z80_inc - | z80_jp - | z80_jr - | z80_ld - | z80_ldd - | z80_ldi - | z80_ldio - | z80_nop - | z80_or - | z80_pop - | z80_push - | z80_res - | z80_ret - | z80_reti - | z80_rl - | z80_rla - | z80_rlc - | z80_rlca - | z80_rr - | z80_rra - | z80_rrc - | z80_rrca - | z80_rst - | z80_sbc - | z80_scf - | z80_set - | z80_sla - | z80_sra - | z80_srl - | z80_stop - | z80_sub - | z80_swap - | z80_xor -; - -z80_adc : T_Z80_ADC op_a_n { out_AbsByte(0xCE); out_RelByte(&$2); } - | T_Z80_ADC op_a_r { out_AbsByte(0x88|$2); } -; - -z80_add : T_Z80_ADD op_a_n { out_AbsByte(0xC6); out_RelByte(&$2); } - | T_Z80_ADD op_a_r { out_AbsByte(0x80|$2); } - | T_Z80_ADD op_hl_ss { out_AbsByte(0x09|($2<<4)); } - | T_Z80_ADD T_MODE_SP comma const_8bit - { out_AbsByte(0xE8); out_RelByte(&$4); } - -; - -z80_and : T_Z80_AND op_a_n { out_AbsByte(0xE6); out_RelByte(&$2); } - | T_Z80_AND op_a_r { out_AbsByte(0xA0|$2); } -; - -z80_bit : T_Z80_BIT const_3bit comma reg_r - { out_AbsByte(0xCB); out_AbsByte(0x40|($2<<3)|$4); } -; - -z80_call : T_Z80_CALL const_16bit - { out_AbsByte(0xCD); out_RelWord(&$2); } - | T_Z80_CALL ccode comma const_16bit - { out_AbsByte(0xC4|($2<<3)); out_RelWord(&$4); } -; - -z80_ccf : T_Z80_CCF - { out_AbsByte(0x3F); } -; - -z80_cp : T_Z80_CP op_a_n { out_AbsByte(0xFE); out_RelByte(&$2); } - | T_Z80_CP op_a_r { out_AbsByte(0xB8|$2); } -; - -z80_cpl : T_Z80_CPL { out_AbsByte(0x2F); } -; - -z80_daa : T_Z80_DAA { out_AbsByte(0x27); } -; - -z80_dec : T_Z80_DEC reg_r - { out_AbsByte(0x05|($2<<3)); } - | T_Z80_DEC reg_ss - { out_AbsByte(0x0B|($2<<4)); } -; - -z80_di : T_Z80_DI - { out_AbsByte(0xF3); } -; - -z80_ei : T_Z80_EI - { out_AbsByte(0xFB); } -; - -z80_ex : T_Z80_EX T_MODE_HL comma T_MODE_SP_IND - { out_AbsByte(0xE3); } - | T_Z80_EX T_MODE_SP_IND comma T_MODE_HL - { out_AbsByte(0xE3); } -; - -z80_halt : T_Z80_HALT - { out_AbsByte(0x76); out_AbsByte(0x00); } -; - -z80_inc : T_Z80_INC reg_r - { out_AbsByte(0x04|($2<<3)); } - | T_Z80_INC reg_ss - { out_AbsByte(0x03|($2<<4)); } -; - -z80_jp : T_Z80_JP const_16bit - { out_AbsByte(0xC3); out_RelWord(&$2); } - | T_Z80_JP ccode comma const_16bit - { out_AbsByte(0xC2|($2<<3)); out_RelWord(&$4); } - | T_Z80_JP T_MODE_HL_IND - { out_AbsByte(0xE9); } -; - -z80_jr : T_Z80_JR const_PCrel - { out_AbsByte(0x18); out_PCRelByte(&$2); } - | T_Z80_JR ccode comma const_PCrel - { out_AbsByte(0x20|($2<<3)); out_PCRelByte(&$4); } -; - -z80_ldi : T_Z80_LDI T_MODE_HL_IND comma T_MODE_A - { out_AbsByte(0x02|(2<<4)); } - | T_Z80_LDI T_MODE_A comma T_MODE_HL - { out_AbsByte(0x0A|(2<<4)); } -; - -z80_ldd : T_Z80_LDD T_MODE_HL_IND comma T_MODE_A - { out_AbsByte(0x02|(3<<4)); } - | T_Z80_LDD T_MODE_A comma T_MODE_HL - { out_AbsByte(0x0A|(3<<4)); } -; - -z80_ldio : T_Z80_LDIO T_MODE_A comma op_mem_ind - { - rpn_CheckHRAM(&$4,&$4); - - if( (!rpn_isReloc(&$4)) - && ($4.nVal<0 || ($4.nVal>0xFF && $4.nVal<0xFF00) || $4.nVal>0xFFFF) ) - { - yyerror( "Source must be in the IO/HRAM area" ); - } - - out_AbsByte(0xF0); - $4.nVal&=0xFF; - out_RelByte(&$4); - } - | T_Z80_LDIO op_mem_ind comma T_MODE_A - { - rpn_CheckHRAM(&$2,&$2); - - if( (!rpn_isReloc(&$2)) - && ($2.nVal<0 || ($2.nVal>0xFF && $2.nVal<0xFF00) || $2.nVal>0xFFFF) ) - { - yyerror( "Destination must be in the IO/HRAM area" ); - } - - out_AbsByte(0xE0); - $2.nVal&=0xFF; - out_RelByte(&$2); - } -; - -z80_ld : z80_ld_mem - | z80_ld_cind - | z80_ld_rr - | z80_ld_ss - | z80_ld_hl - | z80_ld_sp - | z80_ld_r - | z80_ld_a -; - -z80_ld_hl : T_Z80_LD T_MODE_HL comma '[' T_MODE_SP const_8bit ']' - { out_AbsByte(0xF8); out_RelByte(&$6); } - | T_Z80_LD T_MODE_HL comma const_16bit - { out_AbsByte(0x01|(REG_HL<<4)); out_RelWord(&$4) } -; -z80_ld_sp : T_Z80_LD T_MODE_SP comma T_MODE_HL - { out_AbsByte(0xF9); } - | T_Z80_LD T_MODE_SP comma const_16bit - { out_AbsByte(0x01|(REG_SP<<4)); out_RelWord(&$4) } -; - -z80_ld_mem : T_Z80_LD op_mem_ind comma T_MODE_SP - { out_AbsByte(0x08); out_RelWord(&$2); } - | T_Z80_LD op_mem_ind comma T_MODE_A - { - if( (!rpn_isReloc(&$2)) && $2.nVal>=0xFF00) - { - out_AbsByte(0xE0); - out_AbsByte($2.nVal&0xFF); - } - else - { - out_AbsByte(0xEA); - out_RelWord(&$2); - } - } -; - -z80_ld_cind : T_Z80_LD T_MODE_C_IND comma T_MODE_A - { out_AbsByte(0xE2); } -; - -z80_ld_rr : T_Z80_LD reg_rr comma T_MODE_A - { out_AbsByte(0x02|($2<<4)); } -; - -z80_ld_r : T_Z80_LD reg_r comma const_8bit - { out_AbsByte(0x06|($2<<3)); out_RelByte(&$4); } - | T_Z80_LD reg_r comma reg_r - { - if( ($2==REG_HL_IND) && ($4==REG_HL_IND) ) - { - yyerror( "LD (HL),(HL) not allowed" ); - } - else - out_AbsByte(0x40|($2<<3)|$4); - } -; - -z80_ld_a : T_Z80_LD reg_r comma T_MODE_C_IND - { - if( $2==REG_A ) - out_AbsByte(0xF2); - else - { - yyerror( "Destination operand must be A" ); - } - } - | T_Z80_LD reg_r comma reg_rr - { - if( $2==REG_A ) - out_AbsByte(0x0A|($4<<4)); - else - { - yyerror( "Destination operand must be A" ); - } - } - | T_Z80_LD reg_r comma op_mem_ind - { - if( $2==REG_A ) - { - if( (!rpn_isReloc(&$4)) && $4.nVal>=0xFF00 ) - { - out_AbsByte(0xF0); - out_AbsByte($4.nVal&0xFF); - } - else - { - out_AbsByte(0xFA); - out_RelWord(&$4); - } - } - else - { - yyerror( "Destination operand must be A" ); - } - } -; - -z80_ld_ss : T_Z80_LD reg_ss comma const_16bit - { out_AbsByte(0x01|($2<<4)); out_RelWord(&$4) } -; - -z80_nop : T_Z80_NOP - { out_AbsByte(0x00); } -; - -z80_or : T_Z80_OR op_a_n - { out_AbsByte(0xF6); out_RelByte(&$2); } - | T_Z80_OR op_a_r - { out_AbsByte(0xB0|$2); } -; - -z80_pop : T_Z80_POP reg_tt - { out_AbsByte(0xC1|($2<<4)); } -; - -z80_push : T_Z80_PUSH reg_tt - { out_AbsByte(0xC5|($2<<4)); } -; - -z80_res : T_Z80_RES const_3bit comma reg_r - { out_AbsByte(0xCB); out_AbsByte(0x80|($2<<3)|$4); } -; - -z80_ret : T_Z80_RET - { out_AbsByte(0xC9); } - | T_Z80_RET ccode - { out_AbsByte(0xC0|($2<<3)); } -; - -z80_reti : T_Z80_RETI - { out_AbsByte(0xD9); } -; - -z80_rl : T_Z80_RL reg_r - { out_AbsByte(0xCB); out_AbsByte(0x10|$2); } -; - -z80_rla : T_Z80_RLA - { out_AbsByte(0x17); } -; - -z80_rlc : T_Z80_RLC reg_r - { out_AbsByte(0xCB); out_AbsByte(0x00|$2); } -; - -z80_rlca : T_Z80_RLCA - { out_AbsByte(0x07); } -; - -z80_rr : T_Z80_RR reg_r - { out_AbsByte(0xCB); out_AbsByte(0x18|$2); } -; - -z80_rra : T_Z80_RRA - { out_AbsByte(0x1F); } -; - -z80_rrc : T_Z80_RRC reg_r - { out_AbsByte(0xCB); out_AbsByte(0x08|$2); } -; - -z80_rrca : T_Z80_RRCA - { out_AbsByte(0x0F); } -; - -z80_rst : T_Z80_RST const_8bit - { - if( rpn_isReloc(&$2) ) - { - yyerror( "Address for RST must be absolute" ); - } - else if( ($2.nVal&0x38)!=$2.nVal ) - { - yyerror( "Invalid address for RST" ); - } - else - out_AbsByte(0xC7|$2.nVal); - } -; - -z80_sbc : T_Z80_SBC op_a_n { out_AbsByte(0xDE); out_RelByte(&$2); } - | T_Z80_SBC op_a_r { out_AbsByte(0x98|$2); } -; - -z80_scf : T_Z80_SCF - { out_AbsByte(0x37); } -; - -z80_set : T_POP_SET const_3bit comma reg_r - { out_AbsByte(0xCB); out_AbsByte(0xC0|($2<<3)|$4); } -; - -z80_sla : T_Z80_SLA reg_r - { out_AbsByte(0xCB); out_AbsByte(0x20|$2); } -; - -z80_sra : T_Z80_SRA reg_r - { out_AbsByte(0xCB); out_AbsByte(0x28|$2); } -; - -z80_srl : T_Z80_SRL reg_r - { out_AbsByte(0xCB); out_AbsByte(0x38|$2); } -; - -z80_stop : T_Z80_STOP - { out_AbsByte(0x10); out_AbsByte(0x00); } -; - -z80_sub : T_Z80_SUB op_a_n { out_AbsByte(0xD6); out_RelByte(&$2); } - | T_Z80_SUB op_a_r { out_AbsByte(0x90|$2); } -; - -z80_swap : T_Z80_SWAP reg_r - { out_AbsByte(0xCB); out_AbsByte(0x30|$2); } -; - -z80_xor : T_Z80_XOR op_a_n { out_AbsByte(0xEE); out_RelByte(&$2); } - | T_Z80_XOR op_a_r { out_AbsByte(0xA8|$2); } -; - -op_mem_ind : '[' const_16bit ']' { $$ = $2 } -; - -op_hl_ss : reg_ss { $$ = $1 } - | T_MODE_HL comma reg_ss { $$ = $3 } -; - -op_a_r : reg_r { $$ = $1 } - | T_MODE_A comma reg_r { $$ = $3 } -; - -op_a_n : const_8bit { $$ = $1 } - | T_MODE_A comma const_8bit { $$ = $3 } -; - -comma : ',' -; - -ccode : T_CC_NZ { $$ = CC_NZ } - | T_CC_Z { $$ = CC_Z } - | T_CC_NC { $$ = CC_NC } - | T_MODE_C { $$ = CC_C } -; - -reg_r : T_MODE_B { $$ = REG_B } - | T_MODE_C { $$ = REG_C } - | T_MODE_D { $$ = REG_D } - | T_MODE_E { $$ = REG_E } - | T_MODE_H { $$ = REG_H } - | T_MODE_L { $$ = REG_L } - | T_MODE_HL_IND { $$ = REG_HL_IND } - | T_MODE_A { $$ = REG_A } -; - -reg_tt : T_MODE_BC { $$ = REG_BC } - | T_MODE_DE { $$ = REG_DE } - | T_MODE_HL { $$ = REG_HL } - | T_MODE_AF { $$ = REG_AF } -; - -reg_ss : T_MODE_BC { $$ = REG_BC } - | T_MODE_DE { $$ = REG_DE } - | T_MODE_HL { $$ = REG_HL } - | T_MODE_SP { $$ = REG_SP } -; - -reg_rr : T_MODE_BC_IND { $$ = REG_BC_IND } - | T_MODE_DE_IND { $$ = REG_DE_IND } - | T_MODE_HL_INDINC { $$ = REG_HL_INDINC } - | T_MODE_HL_INDDEC { $$ = REG_HL_INDDEC } -; - +section : T_POP_SECTION string ',' sectiontype + { out_NewSection($2,$4); } + | T_POP_SECTION string ',' sectiontype '[' const ']' + { + if( $6>=0 && $6<0x10000 ) + out_NewAbsSection($2,$4,$6,-1); + else + yyerror( "Address must be 16-bit" ); + } + | T_POP_SECTION string ',' sectiontype ',' T_OP_BANK '[' const ']' + { + if( $4==SECT_CODE ) + { + if( $8>=1 && $8<=255 ) + out_NewAbsSection($2,$4,-1,$8); + else + yyerror( "BANK value out of range" ); + } + else + yyerror( "BANK only allowed for CODE/DATA" ); + } + | T_POP_SECTION string ',' sectiontype '[' const ']' ',' T_OP_BANK '[' const ']' + { + if( $4==SECT_CODE ) + { + if( $6>=0 && $6<0x10000 ) + { + if( $11>=1 && $11<=255 ) + out_NewAbsSection($2,$4,$6,$11); + else + yyerror( "BANK value out of range" ); + } + else + yyerror( "Address must be 16-bit" ); + } + else + yyerror( "BANK only allowed for CODE/DATA" ); + } +; + +sectiontype : T_SECT_BSS { $$=SECT_BSS; } + | T_SECT_VRAM { $$=SECT_VRAM; } + | T_SECT_CODE { $$=SECT_CODE; } + | T_SECT_HOME { $$=SECT_HOME; } + | T_SECT_HRAM { $$=SECT_HRAM; } +; + + +cpu_command : z80_adc + | z80_add + | z80_and + | z80_bit + | z80_call + | z80_ccf + | z80_cp + | z80_cpl + | z80_daa + | z80_dec + | z80_di + | z80_ei + | z80_ex + | z80_halt + | z80_inc + | z80_jp + | z80_jr + | z80_ld + | z80_ldd + | z80_ldi + | z80_ldio + | z80_nop + | z80_or + | z80_pop + | z80_push + | z80_res + | z80_ret + | z80_reti + | z80_rl + | z80_rla + | z80_rlc + | z80_rlca + | z80_rr + | z80_rra + | z80_rrc + | z80_rrca + | z80_rst + | z80_sbc + | z80_scf + | z80_set + | z80_sla + | z80_sra + | z80_srl + | z80_stop + | z80_sub + | z80_swap + | z80_xor +; + +z80_adc : T_Z80_ADC op_a_n { out_AbsByte(0xCE); out_RelByte(&$2); } + | T_Z80_ADC op_a_r { out_AbsByte(0x88|$2); } +; + +z80_add : T_Z80_ADD op_a_n { out_AbsByte(0xC6); out_RelByte(&$2); } + | T_Z80_ADD op_a_r { out_AbsByte(0x80|$2); } + | T_Z80_ADD op_hl_ss { out_AbsByte(0x09|($2<<4)); } + | T_Z80_ADD T_MODE_SP comma const_8bit + { out_AbsByte(0xE8); out_RelByte(&$4); } + +; + +z80_and : T_Z80_AND op_a_n { out_AbsByte(0xE6); out_RelByte(&$2); } + | T_Z80_AND op_a_r { out_AbsByte(0xA0|$2); } +; + +z80_bit : T_Z80_BIT const_3bit comma reg_r + { out_AbsByte(0xCB); out_AbsByte(0x40|($2<<3)|$4); } +; + +z80_call : T_Z80_CALL const_16bit + { out_AbsByte(0xCD); out_RelWord(&$2); } + | T_Z80_CALL ccode comma const_16bit + { out_AbsByte(0xC4|($2<<3)); out_RelWord(&$4); } +; + +z80_ccf : T_Z80_CCF + { out_AbsByte(0x3F); } +; + +z80_cp : T_Z80_CP op_a_n { out_AbsByte(0xFE); out_RelByte(&$2); } + | T_Z80_CP op_a_r { out_AbsByte(0xB8|$2); } +; + +z80_cpl : T_Z80_CPL { out_AbsByte(0x2F); } +; + +z80_daa : T_Z80_DAA { out_AbsByte(0x27); } +; + +z80_dec : T_Z80_DEC reg_r + { out_AbsByte(0x05|($2<<3)); } + | T_Z80_DEC reg_ss + { out_AbsByte(0x0B|($2<<4)); } +; + +z80_di : T_Z80_DI + { out_AbsByte(0xF3); } +; + +z80_ei : T_Z80_EI + { out_AbsByte(0xFB); } +; + +z80_ex : T_Z80_EX T_MODE_HL comma T_MODE_SP_IND + { out_AbsByte(0xE3); } + | T_Z80_EX T_MODE_SP_IND comma T_MODE_HL + { out_AbsByte(0xE3); } +; + +z80_halt : T_Z80_HALT + { out_AbsByte(0x76); out_AbsByte(0x00); } +; + +z80_inc : T_Z80_INC reg_r + { out_AbsByte(0x04|($2<<3)); } + | T_Z80_INC reg_ss + { out_AbsByte(0x03|($2<<4)); } +; + +z80_jp : T_Z80_JP const_16bit + { out_AbsByte(0xC3); out_RelWord(&$2); } + | T_Z80_JP ccode comma const_16bit + { out_AbsByte(0xC2|($2<<3)); out_RelWord(&$4); } + | T_Z80_JP T_MODE_HL_IND + { out_AbsByte(0xE9); } +; + +z80_jr : T_Z80_JR const_PCrel + { out_AbsByte(0x18); out_PCRelByte(&$2); } + | T_Z80_JR ccode comma const_PCrel + { out_AbsByte(0x20|($2<<3)); out_PCRelByte(&$4); } +; + +z80_ldi : T_Z80_LDI T_MODE_HL_IND comma T_MODE_A + { out_AbsByte(0x02|(2<<4)); } + | T_Z80_LDI T_MODE_A comma T_MODE_HL + { out_AbsByte(0x0A|(2<<4)); } +; + +z80_ldd : T_Z80_LDD T_MODE_HL_IND comma T_MODE_A + { out_AbsByte(0x02|(3<<4)); } + | T_Z80_LDD T_MODE_A comma T_MODE_HL + { out_AbsByte(0x0A|(3<<4)); } +; + +z80_ldio : T_Z80_LDIO T_MODE_A comma op_mem_ind + { + rpn_CheckHRAM(&$4,&$4); + + if( (!rpn_isReloc(&$4)) + && ($4.nVal<0 || ($4.nVal>0xFF && $4.nVal<0xFF00) || $4.nVal>0xFFFF) ) + { + yyerror( "Source must be in the IO/HRAM area" ); + } + + out_AbsByte(0xF0); + $4.nVal&=0xFF; + out_RelByte(&$4); + } + | T_Z80_LDIO op_mem_ind comma T_MODE_A + { + rpn_CheckHRAM(&$2,&$2); + + if( (!rpn_isReloc(&$2)) + && ($2.nVal<0 || ($2.nVal>0xFF && $2.nVal<0xFF00) || $2.nVal>0xFFFF) ) + { + yyerror( "Destination must be in the IO/HRAM area" ); + } + + out_AbsByte(0xE0); + $2.nVal&=0xFF; + out_RelByte(&$2); + } +; + +z80_ld : z80_ld_mem + | z80_ld_cind + | z80_ld_rr + | z80_ld_ss + | z80_ld_hl + | z80_ld_sp + | z80_ld_r + | z80_ld_a +; + +z80_ld_hl : T_Z80_LD T_MODE_HL comma '[' T_MODE_SP const_8bit ']' + { out_AbsByte(0xF8); out_RelByte(&$6); } + | T_Z80_LD T_MODE_HL comma const_16bit + { out_AbsByte(0x01|(REG_HL<<4)); out_RelWord(&$4) } +; +z80_ld_sp : T_Z80_LD T_MODE_SP comma T_MODE_HL + { out_AbsByte(0xF9); } + | T_Z80_LD T_MODE_SP comma const_16bit + { out_AbsByte(0x01|(REG_SP<<4)); out_RelWord(&$4) } +; + +z80_ld_mem : T_Z80_LD op_mem_ind comma T_MODE_SP + { out_AbsByte(0x08); out_RelWord(&$2); } + | T_Z80_LD op_mem_ind comma T_MODE_A + { + if( (!rpn_isReloc(&$2)) && $2.nVal>=0xFF00) + { + out_AbsByte(0xE0); + out_AbsByte($2.nVal&0xFF); + } + else + { + out_AbsByte(0xEA); + out_RelWord(&$2); + } + } +; + +z80_ld_cind : T_Z80_LD T_MODE_C_IND comma T_MODE_A + { out_AbsByte(0xE2); } +; + +z80_ld_rr : T_Z80_LD reg_rr comma T_MODE_A + { out_AbsByte(0x02|($2<<4)); } +; + +z80_ld_r : T_Z80_LD reg_r comma const_8bit + { out_AbsByte(0x06|($2<<3)); out_RelByte(&$4); } + | T_Z80_LD reg_r comma reg_r + { + if( ($2==REG_HL_IND) && ($4==REG_HL_IND) ) + { + yyerror( "LD (HL),(HL) not allowed" ); + } + else + out_AbsByte(0x40|($2<<3)|$4); + } +; + +z80_ld_a : T_Z80_LD reg_r comma T_MODE_C_IND + { + if( $2==REG_A ) + out_AbsByte(0xF2); + else + { + yyerror( "Destination operand must be A" ); + } + } + | T_Z80_LD reg_r comma reg_rr + { + if( $2==REG_A ) + out_AbsByte(0x0A|($4<<4)); + else + { + yyerror( "Destination operand must be A" ); + } + } + | T_Z80_LD reg_r comma op_mem_ind + { + if( $2==REG_A ) + { + if( (!rpn_isReloc(&$4)) && $4.nVal>=0xFF00 ) + { + out_AbsByte(0xF0); + out_AbsByte($4.nVal&0xFF); + } + else + { + out_AbsByte(0xFA); + out_RelWord(&$4); + } + } + else + { + yyerror( "Destination operand must be A" ); + } + } +; + +z80_ld_ss : T_Z80_LD reg_ss comma const_16bit + { out_AbsByte(0x01|($2<<4)); out_RelWord(&$4) } +; + +z80_nop : T_Z80_NOP + { out_AbsByte(0x00); } +; + +z80_or : T_Z80_OR op_a_n + { out_AbsByte(0xF6); out_RelByte(&$2); } + | T_Z80_OR op_a_r + { out_AbsByte(0xB0|$2); } +; + +z80_pop : T_Z80_POP reg_tt + { out_AbsByte(0xC1|($2<<4)); } +; + +z80_push : T_Z80_PUSH reg_tt + { out_AbsByte(0xC5|($2<<4)); } +; + +z80_res : T_Z80_RES const_3bit comma reg_r + { out_AbsByte(0xCB); out_AbsByte(0x80|($2<<3)|$4); } +; + +z80_ret : T_Z80_RET + { out_AbsByte(0xC9); } + | T_Z80_RET ccode + { out_AbsByte(0xC0|($2<<3)); } +; + +z80_reti : T_Z80_RETI + { out_AbsByte(0xD9); } +; + +z80_rl : T_Z80_RL reg_r + { out_AbsByte(0xCB); out_AbsByte(0x10|$2); } +; + +z80_rla : T_Z80_RLA + { out_AbsByte(0x17); } +; + +z80_rlc : T_Z80_RLC reg_r + { out_AbsByte(0xCB); out_AbsByte(0x00|$2); } +; + +z80_rlca : T_Z80_RLCA + { out_AbsByte(0x07); } +; + +z80_rr : T_Z80_RR reg_r + { out_AbsByte(0xCB); out_AbsByte(0x18|$2); } +; + +z80_rra : T_Z80_RRA + { out_AbsByte(0x1F); } +; + +z80_rrc : T_Z80_RRC reg_r + { out_AbsByte(0xCB); out_AbsByte(0x08|$2); } +; + +z80_rrca : T_Z80_RRCA + { out_AbsByte(0x0F); } +; + +z80_rst : T_Z80_RST const_8bit + { + if( rpn_isReloc(&$2) ) + { + yyerror( "Address for RST must be absolute" ); + } + else if( ($2.nVal&0x38)!=$2.nVal ) + { + yyerror( "Invalid address for RST" ); + } + else + out_AbsByte(0xC7|$2.nVal); + } +; + +z80_sbc : T_Z80_SBC op_a_n { out_AbsByte(0xDE); out_RelByte(&$2); } + | T_Z80_SBC op_a_r { out_AbsByte(0x98|$2); } +; + +z80_scf : T_Z80_SCF + { out_AbsByte(0x37); } +; + +z80_set : T_POP_SET const_3bit comma reg_r + { out_AbsByte(0xCB); out_AbsByte(0xC0|($2<<3)|$4); } +; + +z80_sla : T_Z80_SLA reg_r + { out_AbsByte(0xCB); out_AbsByte(0x20|$2); } +; + +z80_sra : T_Z80_SRA reg_r + { out_AbsByte(0xCB); out_AbsByte(0x28|$2); } +; + +z80_srl : T_Z80_SRL reg_r + { out_AbsByte(0xCB); out_AbsByte(0x38|$2); } +; + +z80_stop : T_Z80_STOP + { out_AbsByte(0x10); out_AbsByte(0x00); } +; + +z80_sub : T_Z80_SUB op_a_n { out_AbsByte(0xD6); out_RelByte(&$2); } + | T_Z80_SUB op_a_r { out_AbsByte(0x90|$2); } +; + +z80_swap : T_Z80_SWAP reg_r + { out_AbsByte(0xCB); out_AbsByte(0x30|$2); } +; + +z80_xor : T_Z80_XOR op_a_n { out_AbsByte(0xEE); out_RelByte(&$2); } + | T_Z80_XOR op_a_r { out_AbsByte(0xA8|$2); } +; + +op_mem_ind : '[' const_16bit ']' { $$ = $2 } +; + +op_hl_ss : reg_ss { $$ = $1 } + | T_MODE_HL comma reg_ss { $$ = $3 } +; + +op_a_r : reg_r { $$ = $1 } + | T_MODE_A comma reg_r { $$ = $3 } +; + +op_a_n : const_8bit { $$ = $1 } + | T_MODE_A comma const_8bit { $$ = $3 } +; + +comma : ',' +; + +ccode : T_CC_NZ { $$ = CC_NZ } + | T_CC_Z { $$ = CC_Z } + | T_CC_NC { $$ = CC_NC } + | T_MODE_C { $$ = CC_C } +; + +reg_r : T_MODE_B { $$ = REG_B } + | T_MODE_C { $$ = REG_C } + | T_MODE_D { $$ = REG_D } + | T_MODE_E { $$ = REG_E } + | T_MODE_H { $$ = REG_H } + | T_MODE_L { $$ = REG_L } + | T_MODE_HL_IND { $$ = REG_HL_IND } + | T_MODE_A { $$ = REG_A } +; + +reg_tt : T_MODE_BC { $$ = REG_BC } + | T_MODE_DE { $$ = REG_DE } + | T_MODE_HL { $$ = REG_HL } + | T_MODE_AF { $$ = REG_AF } +; + +reg_ss : T_MODE_BC { $$ = REG_BC } + | T_MODE_DE { $$ = REG_DE } + | T_MODE_HL { $$ = REG_HL } + | T_MODE_SP { $$ = REG_SP } +; + +reg_rr : T_MODE_BC_IND { $$ = REG_BC_IND } + | T_MODE_DE_IND { $$ = REG_DE_IND } + | T_MODE_HL_INDINC { $$ = REG_HL_INDINC } + | T_MODE_HL_INDDEC { $$ = REG_HL_INDDEC } +; + %% \ No newline at end of file diff --git a/src/asm/globlex.c b/src/asm/globlex.c index b41acb53..247cb4e1 100644 --- a/src/asm/globlex.c +++ b/src/asm/globlex.c @@ -1,513 +1,513 @@ -#include "asm.h" -#include "symbol.h" -#include "rpn.h" -#include "asmy.h" -#include "symbol.h" -#include "main.h" -#include "lexer.h" -#include -#include -#include -#include - -UBYTE oDontExpandStrings=0; -SLONG nGBGfxID=-1; -SLONG nBinaryID=-1; - -SLONG gbgfx2bin (char ch) -{ - SLONG i; - - for( i=0; i<=3; i+=1 ) - { - if( CurrentOptions.gbgfx[i]==ch ) - { - return( i ); - } - } - - return (0); -} - -SLONG binary2bin (char ch) -{ - SLONG i; - - for( i=0; i<=1; i+=1 ) - { - if( CurrentOptions.binary[i]==ch ) - { - return( i ); - } - - } - - return (0); -} - -SLONG char2bin (char ch) -{ - if (ch >= 'a' && ch <= 'f') - return (ch - 'a' + 10); - - if (ch >= 'A' && ch <= 'F') - return (ch - 'A' + 10); - - if (ch >= '0' && ch <= '9') - return (ch - '0'); - - return (0); -} - -typedef SLONG (*x2bin)(char ch); - -SLONG ascii2bin (char *s) -{ - SLONG radix = 10; - SLONG result = 0; - x2bin convertfunc=char2bin; - - switch (*s) - { - case '$': - radix = 16; - s += 1; - convertfunc=char2bin; - break; - case '&': - radix = 8; - s += 1; - convertfunc=char2bin; - break; - case '`': - radix = 4; - s += 1; - convertfunc=gbgfx2bin; - break; - case '%': - radix = 2; - s += 1; - convertfunc=binary2bin; - break; - } - - if (radix == 4) - { - SLONG c; - - while (*s != '\0') - { - c = convertfunc (*s++); - result = result * 2 + ((c & 1) << 8) + ((c & 2) >> 1); - } - } - else - { - while (*s != '\0') - result = result * radix + convertfunc (*s++); - } - - return (result); -} - -ULONG ParseFixedPoint (char *s, ULONG size) -{ - char dest[256]; - ULONG i = 0, - dot = 0; - - while (size && dot != 2) - { - if (s[i] == '.') - dot += 1; - - if (dot < 2) - { - dest[i] = s[i]; - size -= 1; - i += 1; - } - } - - dest[i] = 0; - - yyunputbytes (size); - - yylval.nConstValue = (SLONG) (atof (s) * 65536); - - return (1); -} - -ULONG ParseNumber (char *s, ULONG size) -{ - char dest[256]; - - strncpy (dest, s, size); - dest[size] = 0; - yylval.nConstValue = ascii2bin (dest); - - return (1); -} - -ULONG ParseSymbol (char *src, ULONG size) -{ - char dest[MAXSYMLEN + 1]; - int copied = 0, - size_backup = size; - - while (size && copied < MAXSYMLEN) - { - if (*src == '\\') - { - char *marg; - - src += 1; - size -= 1; - - if (*src == '@') - marg = sym_FindMacroArg (-1); - else if (*src >= '0' && *src <= '9') - marg = sym_FindMacroArg (*src); - else - { - fatalerror ("Malformed ID"); - return(0); - } - - src += 1; - size -= 1; - - if (marg) - { - while (*marg) - dest[copied++] = *marg++; - } - } - else - { - dest[copied++] = *src++; - size -= 1; - } - } - - if (copied > MAXSYMLEN) - fatalerror ("Symbol too long"); - - dest[copied] = 0; - - if( oDontExpandStrings==0 - && sym_isString(dest) ) - { - char *s; - - yyskipbytes( size_backup ); - yyunputstr( s=sym_GetStringValue(dest) ); - - while( *s ) - { - if( *s++=='\n' ) - { - nLineNo-=1; - } - } - return (0); - } - else - { - strcpy( yylval.tzString, dest ); - return (1); - } -} - -ULONG PutMacroArg (char *src, ULONG size) -{ - char *s; - - yyskipbytes (size); - if( (s=sym_FindMacroArg (src[1] - '0'))!=NULL ) - { - yyunputstr(s); - } - else - { - yyerror( "Macro argument not defined" ); - } - return (0); -} - -ULONG PutUniqueArg (char *src, ULONG size) -{ - src=src; - yyskipbytes (size); - yyunputstr (sym_FindMacroArg (-1)); - return (0); -} - -enum -{ - T_LEX_MACROARG = 3000, - T_LEX_MACROUNIQUE -}; - -extern struct sLexInitString localstrings[]; - -struct sLexInitString staticstrings[] = -{ - "||", T_OP_LOGICOR, - "&&", T_OP_LOGICAND, - "==", T_OP_LOGICEQU, - ">", T_OP_LOGICGT, - "<", T_OP_LOGICLT, - ">=", T_OP_LOGICGE, - "<=", T_OP_LOGICLE, - "!=", T_OP_LOGICNE, - "!", T_OP_LOGICNOT, - "|", T_OP_OR, - "^", T_OP_XOR, - "&", T_OP_AND, - "<<", T_OP_SHL, - ">>", T_OP_SHR, - "+", T_OP_ADD, - "-", T_OP_SUB, - "*", T_OP_MUL, - "/", T_OP_DIV, - "%", T_OP_MOD, - "~", T_OP_NOT, - - "def", T_OP_DEF, - - "bank", T_OP_BANK, - - "div", T_OP_FDIV, - "mul", T_OP_FMUL, - "sin", T_OP_SIN, - "cos", T_OP_COS, - "tan", T_OP_TAN, - "asin", T_OP_ASIN, - "acos", T_OP_ACOS, - "atan", T_OP_ATAN, - "atan2", T_OP_ATAN2, - - "strcmp", T_OP_STRCMP, - "strin", T_OP_STRIN, - "strsub", T_OP_STRSUB, - "strlen", T_OP_STRLEN, - "strcat", T_OP_STRCAT, - "strupr", T_OP_STRUPR, - "strlwr", T_OP_STRLWR, - - "include", T_POP_INCLUDE, - "printt", T_POP_PRINTT, - "printv", T_POP_PRINTV, - "printf", T_POP_PRINTF, - "export", T_POP_EXPORT, - "xdef", T_POP_EXPORT, - "import", T_POP_IMPORT, - "xref", T_POP_IMPORT, - "global", T_POP_GLOBAL, - "ds", T_POP_DS, - NAME_DB, T_POP_DB, - NAME_DW, T_POP_DW, -#ifdef NAME_DL - NAME_DL, T_POP_DL, -#endif - "section", T_POP_SECTION, - "purge", T_POP_PURGE, - - "rsreset", T_POP_RSRESET, - "rsset", T_POP_RSSET, - - "incbin", T_POP_INCBIN, - - "fail", T_POP_FAIL, - "warn", T_POP_WARN, - - "macro", T_POP_MACRO, - "endm", T_POP_ENDM, // Not needed but we have it here just to protect the name - "shift", T_POP_SHIFT, - - "rept", T_POP_REPT, - "endr", T_POP_ENDR, // Not needed but we have it here just to protect the name - - "if", T_POP_IF, - "else", T_POP_ELSE, - "endc", T_POP_ENDC, - - "bss", T_SECT_BSS, -#if defined(GAMEBOY) || defined(PCENGINE) - "vram", T_SECT_VRAM, -#endif - "code", T_SECT_CODE, - "data", T_SECT_CODE, -#ifdef GAMEBOY - "home", T_SECT_HOME, - "hram", T_SECT_HRAM, -#endif - - NAME_RB, T_POP_RB, - NAME_RW, T_POP_RW, -#ifdef NAME_RL - NAME_RL, T_POP_RL, -#endif - "equ", T_POP_EQU, - "equs", T_POP_EQUS, - - "set", T_POP_SET, - "=", T_POP_SET, - - "pushs", T_POP_PUSHS, - "pops", T_POP_POPS, - "pusho", T_POP_PUSHO, - "popo", T_POP_POPO, - - "opt", T_POP_OPT, - - NULL, 0 -}; - -struct sLexFloat tNumberToken = -{ - ParseNumber, - T_NUMBER -}; - -struct sLexFloat tFixedPointToken = -{ - ParseFixedPoint, - T_NUMBER -}; - -struct sLexFloat tIDToken = -{ - ParseSymbol, - T_ID -}; - -struct sLexFloat tMacroArgToken = -{ - PutMacroArg, - T_LEX_MACROARG -}; - -struct sLexFloat tMacroUniqueToken = -{ - PutUniqueArg, - T_LEX_MACROUNIQUE -}; - -void setuplex (void) -{ - ULONG id; - - lex_Init (); - lex_AddStrings (staticstrings); - lex_AddStrings (localstrings); - - // Macro arguments - - id = lex_FloatAlloc (&tMacroArgToken); - lex_FloatAddFirstRange (id, '\\', '\\'); - lex_FloatAddSecondRange (id, '0', '9'); - id = lex_FloatAlloc (&tMacroUniqueToken); - lex_FloatAddFirstRange (id, '\\', '\\'); - lex_FloatAddSecondRange (id, '@', '@'); - - // Decimal constants - - id = lex_FloatAlloc (&tNumberToken); - lex_FloatAddFirstRange (id, '0', '9'); - lex_FloatAddSecondRange (id, '0', '9'); - lex_FloatAddRange (id, '0', '9'); - - // Binary constants - - nBinaryID = id = lex_FloatAlloc (&tNumberToken); - lex_FloatAddFirstRange (id, '%', '%'); - lex_FloatAddSecondRange (id, CurrentOptions.binary[0], CurrentOptions.binary[0]); - lex_FloatAddSecondRange (id, CurrentOptions.binary[1], CurrentOptions.binary[1]); - lex_FloatAddRange (id, CurrentOptions.binary[0], CurrentOptions.binary[0]); - lex_FloatAddRange (id, CurrentOptions.binary[1], CurrentOptions.binary[1]); - - // Octal constants - - id = lex_FloatAlloc (&tNumberToken); - lex_FloatAddFirstRange (id, '&', '&'); - lex_FloatAddSecondRange (id, '0', '7'); - lex_FloatAddRange (id, '0', '7'); - - // Gameboy gfx constants - - nGBGfxID = id = lex_FloatAlloc (&tNumberToken); - lex_FloatAddFirstRange (id, '`', '`'); - lex_FloatAddSecondRange (id, CurrentOptions.gbgfx[0], CurrentOptions.gbgfx[0]); - lex_FloatAddSecondRange (id, CurrentOptions.gbgfx[1], CurrentOptions.gbgfx[1]); - lex_FloatAddSecondRange (id, CurrentOptions.gbgfx[2], CurrentOptions.gbgfx[2]); - lex_FloatAddSecondRange (id, CurrentOptions.gbgfx[3], CurrentOptions.gbgfx[3]); - lex_FloatAddRange (id, CurrentOptions.gbgfx[0], CurrentOptions.gbgfx[0]); - lex_FloatAddRange (id, CurrentOptions.gbgfx[1], CurrentOptions.gbgfx[1]); - lex_FloatAddRange (id, CurrentOptions.gbgfx[2], CurrentOptions.gbgfx[2]); - lex_FloatAddRange (id, CurrentOptions.gbgfx[3], CurrentOptions.gbgfx[3]); - - // Hex constants - - id = lex_FloatAlloc (&tNumberToken); - lex_FloatAddFirstRange (id, '$', '$'); - lex_FloatAddSecondRange (id, '0', '9'); - lex_FloatAddSecondRange (id, 'A', 'F'); - lex_FloatAddSecondRange (id, 'a', 'f'); - lex_FloatAddRange (id, '0', '9'); - lex_FloatAddRange (id, 'A', 'F'); - lex_FloatAddRange (id, 'a', 'f'); - - // ID's - - id = lex_FloatAlloc (&tIDToken); - lex_FloatAddFirstRange (id, 'a', 'z'); - lex_FloatAddFirstRange (id, 'A', 'Z'); - lex_FloatAddFirstRange (id, '_', '_'); - lex_FloatAddSecondRange (id, 'a', 'z'); - lex_FloatAddSecondRange (id, 'A', 'Z'); - lex_FloatAddSecondRange (id, '0', '9'); - lex_FloatAddSecondRange (id, '_', '_'); - lex_FloatAddSecondRange (id, '\\', '\\'); - lex_FloatAddSecondRange (id, '@', '@'); - lex_FloatAddSecondRange (id, '#', '#'); - lex_FloatAddRange (id, 'a', 'z'); - lex_FloatAddRange (id, 'A', 'Z'); - lex_FloatAddRange (id, '0', '9'); - lex_FloatAddRange (id, '_', '_'); - lex_FloatAddRange (id, '\\', '\\'); - lex_FloatAddRange (id, '@', '@'); - lex_FloatAddRange (id, '#', '#'); - - // Local ID - - id = lex_FloatAlloc (&tIDToken); - lex_FloatAddFirstRange (id, '.', '.'); - lex_FloatAddSecondRange (id, 'a', 'z'); - lex_FloatAddSecondRange (id, 'A', 'Z'); - lex_FloatAddSecondRange (id, '_', '_'); - lex_FloatAddRange (id, 'a', 'z'); - lex_FloatAddRange (id, 'A', 'Z'); - lex_FloatAddRange (id, '0', '9'); - lex_FloatAddRange (id, '_', '_'); - lex_FloatAddRange (id, '\\', '\\'); - lex_FloatAddRange (id, '@', '@'); - lex_FloatAddRange (id, '#', '#'); - - // @ ID - - id = lex_FloatAlloc (&tIDToken); - lex_FloatAddFirstRange (id, '@', '@'); - - // Fixed point constants - - id = lex_FloatAlloc (&tFixedPointToken); - lex_FloatAddFirstRange (id, '.', '.'); - lex_FloatAddFirstRange (id, '0', '9'); - lex_FloatAddSecondRange (id, '.', '.'); - lex_FloatAddSecondRange (id, '0', '9'); - lex_FloatAddRange (id, '.', '.'); - lex_FloatAddRange (id, '0', '9'); - +#include "asm.h" +#include "symbol.h" +#include "rpn.h" +#include "asmy.h" +#include "symbol.h" +#include "main.h" +#include "lexer.h" +#include +#include +#include +#include + +UBYTE oDontExpandStrings=0; +SLONG nGBGfxID=-1; +SLONG nBinaryID=-1; + +SLONG gbgfx2bin (char ch) +{ + SLONG i; + + for( i=0; i<=3; i+=1 ) + { + if( CurrentOptions.gbgfx[i]==ch ) + { + return( i ); + } + } + + return (0); +} + +SLONG binary2bin (char ch) +{ + SLONG i; + + for( i=0; i<=1; i+=1 ) + { + if( CurrentOptions.binary[i]==ch ) + { + return( i ); + } + + } + + return (0); +} + +SLONG char2bin (char ch) +{ + if (ch >= 'a' && ch <= 'f') + return (ch - 'a' + 10); + + if (ch >= 'A' && ch <= 'F') + return (ch - 'A' + 10); + + if (ch >= '0' && ch <= '9') + return (ch - '0'); + + return (0); +} + +typedef SLONG (*x2bin)(char ch); + +SLONG ascii2bin (char *s) +{ + SLONG radix = 10; + SLONG result = 0; + x2bin convertfunc=char2bin; + + switch (*s) + { + case '$': + radix = 16; + s += 1; + convertfunc=char2bin; + break; + case '&': + radix = 8; + s += 1; + convertfunc=char2bin; + break; + case '`': + radix = 4; + s += 1; + convertfunc=gbgfx2bin; + break; + case '%': + radix = 2; + s += 1; + convertfunc=binary2bin; + break; + } + + if (radix == 4) + { + SLONG c; + + while (*s != '\0') + { + c = convertfunc (*s++); + result = result * 2 + ((c & 1) << 8) + ((c & 2) >> 1); + } + } + else + { + while (*s != '\0') + result = result * radix + convertfunc (*s++); + } + + return (result); +} + +ULONG ParseFixedPoint (char *s, ULONG size) +{ + char dest[256]; + ULONG i = 0, + dot = 0; + + while (size && dot != 2) + { + if (s[i] == '.') + dot += 1; + + if (dot < 2) + { + dest[i] = s[i]; + size -= 1; + i += 1; + } + } + + dest[i] = 0; + + yyunputbytes (size); + + yylval.nConstValue = (SLONG) (atof (s) * 65536); + + return (1); +} + +ULONG ParseNumber (char *s, ULONG size) +{ + char dest[256]; + + strncpy (dest, s, size); + dest[size] = 0; + yylval.nConstValue = ascii2bin (dest); + + return (1); +} + +ULONG ParseSymbol (char *src, ULONG size) +{ + char dest[MAXSYMLEN + 1]; + int copied = 0, + size_backup = size; + + while (size && copied < MAXSYMLEN) + { + if (*src == '\\') + { + char *marg; + + src += 1; + size -= 1; + + if (*src == '@') + marg = sym_FindMacroArg (-1); + else if (*src >= '0' && *src <= '9') + marg = sym_FindMacroArg (*src); + else + { + fatalerror ("Malformed ID"); + return(0); + } + + src += 1; + size -= 1; + + if (marg) + { + while (*marg) + dest[copied++] = *marg++; + } + } + else + { + dest[copied++] = *src++; + size -= 1; + } + } + + if (copied > MAXSYMLEN) + fatalerror ("Symbol too long"); + + dest[copied] = 0; + + if( oDontExpandStrings==0 + && sym_isString(dest) ) + { + char *s; + + yyskipbytes( size_backup ); + yyunputstr( s=sym_GetStringValue(dest) ); + + while( *s ) + { + if( *s++=='\n' ) + { + nLineNo-=1; + } + } + return (0); + } + else + { + strcpy( yylval.tzString, dest ); + return (1); + } +} + +ULONG PutMacroArg (char *src, ULONG size) +{ + char *s; + + yyskipbytes (size); + if( (s=sym_FindMacroArg (src[1] - '0'))!=NULL ) + { + yyunputstr(s); + } + else + { + yyerror( "Macro argument not defined" ); + } + return (0); +} + +ULONG PutUniqueArg (char *src, ULONG size) +{ + src=src; + yyskipbytes (size); + yyunputstr (sym_FindMacroArg (-1)); + return (0); +} + +enum +{ + T_LEX_MACROARG = 3000, + T_LEX_MACROUNIQUE +}; + +extern struct sLexInitString localstrings[]; + +struct sLexInitString staticstrings[] = +{ + "||", T_OP_LOGICOR, + "&&", T_OP_LOGICAND, + "==", T_OP_LOGICEQU, + ">", T_OP_LOGICGT, + "<", T_OP_LOGICLT, + ">=", T_OP_LOGICGE, + "<=", T_OP_LOGICLE, + "!=", T_OP_LOGICNE, + "!", T_OP_LOGICNOT, + "|", T_OP_OR, + "^", T_OP_XOR, + "&", T_OP_AND, + "<<", T_OP_SHL, + ">>", T_OP_SHR, + "+", T_OP_ADD, + "-", T_OP_SUB, + "*", T_OP_MUL, + "/", T_OP_DIV, + "%", T_OP_MOD, + "~", T_OP_NOT, + + "def", T_OP_DEF, + + "bank", T_OP_BANK, + + "div", T_OP_FDIV, + "mul", T_OP_FMUL, + "sin", T_OP_SIN, + "cos", T_OP_COS, + "tan", T_OP_TAN, + "asin", T_OP_ASIN, + "acos", T_OP_ACOS, + "atan", T_OP_ATAN, + "atan2", T_OP_ATAN2, + + "strcmp", T_OP_STRCMP, + "strin", T_OP_STRIN, + "strsub", T_OP_STRSUB, + "strlen", T_OP_STRLEN, + "strcat", T_OP_STRCAT, + "strupr", T_OP_STRUPR, + "strlwr", T_OP_STRLWR, + + "include", T_POP_INCLUDE, + "printt", T_POP_PRINTT, + "printv", T_POP_PRINTV, + "printf", T_POP_PRINTF, + "export", T_POP_EXPORT, + "xdef", T_POP_EXPORT, + "import", T_POP_IMPORT, + "xref", T_POP_IMPORT, + "global", T_POP_GLOBAL, + "ds", T_POP_DS, + NAME_DB, T_POP_DB, + NAME_DW, T_POP_DW, +#ifdef NAME_DL + NAME_DL, T_POP_DL, +#endif + "section", T_POP_SECTION, + "purge", T_POP_PURGE, + + "rsreset", T_POP_RSRESET, + "rsset", T_POP_RSSET, + + "incbin", T_POP_INCBIN, + + "fail", T_POP_FAIL, + "warn", T_POP_WARN, + + "macro", T_POP_MACRO, + "endm", T_POP_ENDM, // Not needed but we have it here just to protect the name + "shift", T_POP_SHIFT, + + "rept", T_POP_REPT, + "endr", T_POP_ENDR, // Not needed but we have it here just to protect the name + + "if", T_POP_IF, + "else", T_POP_ELSE, + "endc", T_POP_ENDC, + + "bss", T_SECT_BSS, +#if defined(GAMEBOY) || defined(PCENGINE) + "vram", T_SECT_VRAM, +#endif + "code", T_SECT_CODE, + "data", T_SECT_CODE, +#ifdef GAMEBOY + "home", T_SECT_HOME, + "hram", T_SECT_HRAM, +#endif + + NAME_RB, T_POP_RB, + NAME_RW, T_POP_RW, +#ifdef NAME_RL + NAME_RL, T_POP_RL, +#endif + "equ", T_POP_EQU, + "equs", T_POP_EQUS, + + "set", T_POP_SET, + "=", T_POP_SET, + + "pushs", T_POP_PUSHS, + "pops", T_POP_POPS, + "pusho", T_POP_PUSHO, + "popo", T_POP_POPO, + + "opt", T_POP_OPT, + + NULL, 0 +}; + +struct sLexFloat tNumberToken = +{ + ParseNumber, + T_NUMBER +}; + +struct sLexFloat tFixedPointToken = +{ + ParseFixedPoint, + T_NUMBER +}; + +struct sLexFloat tIDToken = +{ + ParseSymbol, + T_ID +}; + +struct sLexFloat tMacroArgToken = +{ + PutMacroArg, + T_LEX_MACROARG +}; + +struct sLexFloat tMacroUniqueToken = +{ + PutUniqueArg, + T_LEX_MACROUNIQUE +}; + +void setuplex (void) +{ + ULONG id; + + lex_Init (); + lex_AddStrings (staticstrings); + lex_AddStrings (localstrings); + + // Macro arguments + + id = lex_FloatAlloc (&tMacroArgToken); + lex_FloatAddFirstRange (id, '\\', '\\'); + lex_FloatAddSecondRange (id, '0', '9'); + id = lex_FloatAlloc (&tMacroUniqueToken); + lex_FloatAddFirstRange (id, '\\', '\\'); + lex_FloatAddSecondRange (id, '@', '@'); + + // Decimal constants + + id = lex_FloatAlloc (&tNumberToken); + lex_FloatAddFirstRange (id, '0', '9'); + lex_FloatAddSecondRange (id, '0', '9'); + lex_FloatAddRange (id, '0', '9'); + + // Binary constants + + nBinaryID = id = lex_FloatAlloc (&tNumberToken); + lex_FloatAddFirstRange (id, '%', '%'); + lex_FloatAddSecondRange (id, CurrentOptions.binary[0], CurrentOptions.binary[0]); + lex_FloatAddSecondRange (id, CurrentOptions.binary[1], CurrentOptions.binary[1]); + lex_FloatAddRange (id, CurrentOptions.binary[0], CurrentOptions.binary[0]); + lex_FloatAddRange (id, CurrentOptions.binary[1], CurrentOptions.binary[1]); + + // Octal constants + + id = lex_FloatAlloc (&tNumberToken); + lex_FloatAddFirstRange (id, '&', '&'); + lex_FloatAddSecondRange (id, '0', '7'); + lex_FloatAddRange (id, '0', '7'); + + // Gameboy gfx constants + + nGBGfxID = id = lex_FloatAlloc (&tNumberToken); + lex_FloatAddFirstRange (id, '`', '`'); + lex_FloatAddSecondRange (id, CurrentOptions.gbgfx[0], CurrentOptions.gbgfx[0]); + lex_FloatAddSecondRange (id, CurrentOptions.gbgfx[1], CurrentOptions.gbgfx[1]); + lex_FloatAddSecondRange (id, CurrentOptions.gbgfx[2], CurrentOptions.gbgfx[2]); + lex_FloatAddSecondRange (id, CurrentOptions.gbgfx[3], CurrentOptions.gbgfx[3]); + lex_FloatAddRange (id, CurrentOptions.gbgfx[0], CurrentOptions.gbgfx[0]); + lex_FloatAddRange (id, CurrentOptions.gbgfx[1], CurrentOptions.gbgfx[1]); + lex_FloatAddRange (id, CurrentOptions.gbgfx[2], CurrentOptions.gbgfx[2]); + lex_FloatAddRange (id, CurrentOptions.gbgfx[3], CurrentOptions.gbgfx[3]); + + // Hex constants + + id = lex_FloatAlloc (&tNumberToken); + lex_FloatAddFirstRange (id, '$', '$'); + lex_FloatAddSecondRange (id, '0', '9'); + lex_FloatAddSecondRange (id, 'A', 'F'); + lex_FloatAddSecondRange (id, 'a', 'f'); + lex_FloatAddRange (id, '0', '9'); + lex_FloatAddRange (id, 'A', 'F'); + lex_FloatAddRange (id, 'a', 'f'); + + // ID's + + id = lex_FloatAlloc (&tIDToken); + lex_FloatAddFirstRange (id, 'a', 'z'); + lex_FloatAddFirstRange (id, 'A', 'Z'); + lex_FloatAddFirstRange (id, '_', '_'); + lex_FloatAddSecondRange (id, 'a', 'z'); + lex_FloatAddSecondRange (id, 'A', 'Z'); + lex_FloatAddSecondRange (id, '0', '9'); + lex_FloatAddSecondRange (id, '_', '_'); + lex_FloatAddSecondRange (id, '\\', '\\'); + lex_FloatAddSecondRange (id, '@', '@'); + lex_FloatAddSecondRange (id, '#', '#'); + lex_FloatAddRange (id, 'a', 'z'); + lex_FloatAddRange (id, 'A', 'Z'); + lex_FloatAddRange (id, '0', '9'); + lex_FloatAddRange (id, '_', '_'); + lex_FloatAddRange (id, '\\', '\\'); + lex_FloatAddRange (id, '@', '@'); + lex_FloatAddRange (id, '#', '#'); + + // Local ID + + id = lex_FloatAlloc (&tIDToken); + lex_FloatAddFirstRange (id, '.', '.'); + lex_FloatAddSecondRange (id, 'a', 'z'); + lex_FloatAddSecondRange (id, 'A', 'Z'); + lex_FloatAddSecondRange (id, '_', '_'); + lex_FloatAddRange (id, 'a', 'z'); + lex_FloatAddRange (id, 'A', 'Z'); + lex_FloatAddRange (id, '0', '9'); + lex_FloatAddRange (id, '_', '_'); + lex_FloatAddRange (id, '\\', '\\'); + lex_FloatAddRange (id, '@', '@'); + lex_FloatAddRange (id, '#', '#'); + + // @ ID + + id = lex_FloatAlloc (&tIDToken); + lex_FloatAddFirstRange (id, '@', '@'); + + // Fixed point constants + + id = lex_FloatAlloc (&tFixedPointToken); + lex_FloatAddFirstRange (id, '.', '.'); + lex_FloatAddFirstRange (id, '0', '9'); + lex_FloatAddSecondRange (id, '.', '.'); + lex_FloatAddSecondRange (id, '0', '9'); + lex_FloatAddRange (id, '.', '.'); + lex_FloatAddRange (id, '0', '9'); + } \ No newline at end of file diff --git a/src/asm/include/asm.h b/src/asm/include/asm.h index 7331f744..b9faa1fa 100644 --- a/src/asm/include/asm.h +++ b/src/asm/include/asm.h @@ -1,33 +1,33 @@ -/* asm.h - * - * Contains some assembler-wide defines and externs - * - * Copyright 1997 Carsten Sorensen - * - */ - -#ifndef ASM_H -#define ASM_H - -#include -#include -#include "types.h" -#include "symbol.h" -#include "localasm.h" -#include "asmotor.h" - -extern SLONG nLineNo; -extern ULONG nTotalLines; -extern ULONG nPC; -extern ULONG nPass; -extern ULONG nIFDepth; -extern char tzCurrentFileName[_MAX_PATH+1]; -extern struct Section *pCurrentSection; -extern struct sSymbol *tHashedSymbols[HASHSIZE]; -extern struct sSymbol *pPCSymbol; -extern UBYTE oDontExpandStrings; - -#define MAXMACROARGS 9 -#define MAXINCPATHS 16 - +/* asm.h + * + * Contains some assembler-wide defines and externs + * + * Copyright 1997 Carsten Sorensen + * + */ + +#ifndef ASM_H +#define ASM_H + +#include +#include +#include "types.h" +#include "symbol.h" +#include "localasm.h" +#include "asmotor.h" + +extern SLONG nLineNo; +extern ULONG nTotalLines; +extern ULONG nPC; +extern ULONG nPass; +extern ULONG nIFDepth; +extern char tzCurrentFileName[_MAX_PATH+1]; +extern struct Section *pCurrentSection; +extern struct sSymbol *tHashedSymbols[HASHSIZE]; +extern struct sSymbol *pPCSymbol; +extern UBYTE oDontExpandStrings; + +#define MAXMACROARGS 9 +#define MAXINCPATHS 16 + #endif // ASM_H \ No newline at end of file diff --git a/src/asm/include/fstack.h b/src/asm/include/fstack.h index cc1ecae2..fc9e8607 100644 --- a/src/asm/include/fstack.h +++ b/src/asm/include/fstack.h @@ -1,42 +1,42 @@ -/* fstack.h - * - * Contains some assembler-wide defines and externs - * - * Copyright 1997 Carsten Sorensen - * - */ - -#ifndef FSTACK_H -#define FSTACK_H - -#include "asm.h" -#include "types.h" -#include "lexer.h" - -struct sContext -{ - YY_BUFFER_STATE FlexHandle; - struct sSymbol *pMacro; - struct sContext *pNext; - char tzFileName[_MAX_PATH+1]; - char *tzMacroArgs[MAXMACROARGS+1]; - SLONG nLine; - ULONG nStatus; - FILE *pFile; - char *pREPTBlock; - ULONG nREPTBlockCount; - ULONG nREPTBlockSize; -}; - -extern ULONG fstk_RunInclude( char *s ); -extern void fstk_RunMacroArg( SLONG s ); -extern ULONG fstk_Init( char *s ); -extern void fstk_Dump( void ); -extern void fstk_AddIncludePath( char *s ); -extern ULONG fstk_RunMacro( char *s ); -extern void fstk_RunRept( ULONG count ); -extern void fstk_FindFile( char *s ); - -extern int yywrap( void ); - -#endif +/* fstack.h + * + * Contains some assembler-wide defines and externs + * + * Copyright 1997 Carsten Sorensen + * + */ + +#ifndef FSTACK_H +#define FSTACK_H + +#include "asm.h" +#include "types.h" +#include "lexer.h" + +struct sContext +{ + YY_BUFFER_STATE FlexHandle; + struct sSymbol *pMacro; + struct sContext *pNext; + char tzFileName[_MAX_PATH+1]; + char *tzMacroArgs[MAXMACROARGS+1]; + SLONG nLine; + ULONG nStatus; + FILE *pFile; + char *pREPTBlock; + ULONG nREPTBlockCount; + ULONG nREPTBlockSize; +}; + +extern ULONG fstk_RunInclude( char *s ); +extern void fstk_RunMacroArg( SLONG s ); +extern ULONG fstk_Init( char *s ); +extern void fstk_Dump( void ); +extern void fstk_AddIncludePath( char *s ); +extern ULONG fstk_RunMacro( char *s ); +extern void fstk_RunRept( ULONG count ); +extern void fstk_FindFile( char *s ); + +extern int yywrap( void ); + +#endif diff --git a/src/asm/include/gbasmy.h b/src/asm/include/gbasmy.h index efd365ac..7d1b8948 100644 --- a/src/asm/include/gbasmy.h +++ b/src/asm/include/gbasmy.h @@ -1,153 +1,153 @@ -typedef union -{ - char tzSym[MAXSYMLEN+1]; - char tzString[256]; - struct Expression sVal; - SLONG nConstValue; -} YYSTYPE; -#define T_NUMBER 258 -#define T_STRING 259 -#define T_OP_LOGICNOT 260 -#define T_OP_LOGICOR 261 -#define T_OP_LOGICAND 262 -#define T_OP_LOGICEQU 263 -#define T_OP_LOGICGT 264 -#define T_OP_LOGICLT 265 -#define T_OP_LOGICGE 266 -#define T_OP_LOGICLE 267 -#define T_OP_LOGICNE 268 -#define T_OP_ADD 269 -#define T_OP_SUB 270 -#define T_OP_OR 271 -#define T_OP_XOR 272 -#define T_OP_AND 273 -#define T_OP_SHL 274 -#define T_OP_SHR 275 -#define T_OP_MUL 276 -#define T_OP_DIV 277 -#define T_OP_MOD 278 -#define T_OP_NOT 279 -#define T_OP_DEF 280 -#define T_OP_BANK 281 -#define T_OP_SIN 282 -#define T_OP_COS 283 -#define T_OP_TAN 284 -#define T_OP_ASIN 285 -#define T_OP_ACOS 286 -#define T_OP_ATAN 287 -#define T_OP_ATAN2 288 -#define T_OP_FDIV 289 -#define T_OP_FMUL 290 -#define T_OP_STRCMP 291 -#define T_OP_STRIN 292 -#define T_OP_STRSUB 293 -#define T_OP_STRLEN 294 -#define T_OP_STRCAT 295 -#define T_OP_STRUPR 296 -#define T_OP_STRLWR 297 -#define NEG 298 -#define T_LABEL 299 -#define T_ID 300 -#define T_POP_EQU 301 -#define T_POP_SET 302 -#define T_POP_EQUS 303 -#define T_POP_INCLUDE 304 -#define T_POP_PRINTF 305 -#define T_POP_PRINTT 306 -#define T_POP_PRINTV 307 -#define T_POP_IF 308 -#define T_POP_ELSE 309 -#define T_POP_ENDC 310 -#define T_POP_IMPORT 311 -#define T_POP_EXPORT 312 -#define T_POP_GLOBAL 313 -#define T_POP_DB 314 -#define T_POP_DS 315 -#define T_POP_DW 316 -#define T_POP_SECTION 317 -#define T_POP_RB 318 -#define T_POP_RW 319 -#define T_POP_MACRO 320 -#define T_POP_ENDM 321 -#define T_POP_RSRESET 322 -#define T_POP_RSSET 323 -#define T_POP_INCBIN 324 -#define T_POP_REPT 325 -#define T_POP_SHIFT 326 -#define T_POP_ENDR 327 -#define T_POP_FAIL 328 -#define T_POP_WARN 329 -#define T_SECT_BSS 330 -#define T_SECT_VRAM 331 -#define T_SECT_CODE 332 -#define T_SECT_HOME 333 -#define T_SECT_HRAM 334 -#define T_Z80_ADC 335 -#define T_Z80_ADD 336 -#define T_Z80_AND 337 -#define T_Z80_BIT 338 -#define T_Z80_CALL 339 -#define T_Z80_CCF 340 -#define T_Z80_CP 341 -#define T_Z80_CPL 342 -#define T_Z80_DAA 343 -#define T_Z80_DEC 344 -#define T_Z80_DI 345 -#define T_Z80_EI 346 -#define T_Z80_EX 347 -#define T_Z80_HALT 348 -#define T_Z80_INC 349 -#define T_Z80_JP 350 -#define T_Z80_JR 351 -#define T_Z80_LD 352 -#define T_Z80_LDIO 353 -#define T_Z80_NOP 354 -#define T_Z80_OR 355 -#define T_Z80_POP 356 -#define T_Z80_PUSH 357 -#define T_Z80_RES 358 -#define T_Z80_RET 359 -#define T_Z80_RETI 360 -#define T_Z80_RST 361 -#define T_Z80_RL 362 -#define T_Z80_RLA 363 -#define T_Z80_RLC 364 -#define T_Z80_RLCA 365 -#define T_Z80_RR 366 -#define T_Z80_RRA 367 -#define T_Z80_RRC 368 -#define T_Z80_RRCA 369 -#define T_Z80_SBC 370 -#define T_Z80_SCF 371 -#define T_Z80_STOP 372 -#define T_Z80_SLA 373 -#define T_Z80_SRA 374 -#define T_Z80_SRL 375 -#define T_Z80_SUB 376 -#define T_Z80_SWAP 377 -#define T_Z80_XOR 378 -#define T_MODE_A 379 -#define T_MODE_B 380 -#define T_MODE_C 381 -#define T_MODE_C_IND 382 -#define T_MODE_D 383 -#define T_MODE_E 384 -#define T_MODE_H 385 -#define T_MODE_L 386 -#define T_MODE_AF 387 -#define T_MODE_BC 388 -#define T_MODE_BC_IND 389 -#define T_MODE_DE 390 -#define T_MODE_DE_IND 391 -#define T_MODE_SP 392 -#define T_MODE_SP_IND 393 -#define T_MODE_HL 394 -#define T_MODE_HL_IND 395 -#define T_MODE_HL_INDDEC 396 -#define T_MODE_HL_INDINC 397 -#define T_CC_NZ 398 -#define T_CC_Z 399 -#define T_CC_NC 400 - - -extern YYSTYPE yylval; +typedef union +{ + char tzSym[MAXSYMLEN+1]; + char tzString[256]; + struct Expression sVal; + SLONG nConstValue; +} YYSTYPE; +#define T_NUMBER 258 +#define T_STRING 259 +#define T_OP_LOGICNOT 260 +#define T_OP_LOGICOR 261 +#define T_OP_LOGICAND 262 +#define T_OP_LOGICEQU 263 +#define T_OP_LOGICGT 264 +#define T_OP_LOGICLT 265 +#define T_OP_LOGICGE 266 +#define T_OP_LOGICLE 267 +#define T_OP_LOGICNE 268 +#define T_OP_ADD 269 +#define T_OP_SUB 270 +#define T_OP_OR 271 +#define T_OP_XOR 272 +#define T_OP_AND 273 +#define T_OP_SHL 274 +#define T_OP_SHR 275 +#define T_OP_MUL 276 +#define T_OP_DIV 277 +#define T_OP_MOD 278 +#define T_OP_NOT 279 +#define T_OP_DEF 280 +#define T_OP_BANK 281 +#define T_OP_SIN 282 +#define T_OP_COS 283 +#define T_OP_TAN 284 +#define T_OP_ASIN 285 +#define T_OP_ACOS 286 +#define T_OP_ATAN 287 +#define T_OP_ATAN2 288 +#define T_OP_FDIV 289 +#define T_OP_FMUL 290 +#define T_OP_STRCMP 291 +#define T_OP_STRIN 292 +#define T_OP_STRSUB 293 +#define T_OP_STRLEN 294 +#define T_OP_STRCAT 295 +#define T_OP_STRUPR 296 +#define T_OP_STRLWR 297 +#define NEG 298 +#define T_LABEL 299 +#define T_ID 300 +#define T_POP_EQU 301 +#define T_POP_SET 302 +#define T_POP_EQUS 303 +#define T_POP_INCLUDE 304 +#define T_POP_PRINTF 305 +#define T_POP_PRINTT 306 +#define T_POP_PRINTV 307 +#define T_POP_IF 308 +#define T_POP_ELSE 309 +#define T_POP_ENDC 310 +#define T_POP_IMPORT 311 +#define T_POP_EXPORT 312 +#define T_POP_GLOBAL 313 +#define T_POP_DB 314 +#define T_POP_DS 315 +#define T_POP_DW 316 +#define T_POP_SECTION 317 +#define T_POP_RB 318 +#define T_POP_RW 319 +#define T_POP_MACRO 320 +#define T_POP_ENDM 321 +#define T_POP_RSRESET 322 +#define T_POP_RSSET 323 +#define T_POP_INCBIN 324 +#define T_POP_REPT 325 +#define T_POP_SHIFT 326 +#define T_POP_ENDR 327 +#define T_POP_FAIL 328 +#define T_POP_WARN 329 +#define T_SECT_BSS 330 +#define T_SECT_VRAM 331 +#define T_SECT_CODE 332 +#define T_SECT_HOME 333 +#define T_SECT_HRAM 334 +#define T_Z80_ADC 335 +#define T_Z80_ADD 336 +#define T_Z80_AND 337 +#define T_Z80_BIT 338 +#define T_Z80_CALL 339 +#define T_Z80_CCF 340 +#define T_Z80_CP 341 +#define T_Z80_CPL 342 +#define T_Z80_DAA 343 +#define T_Z80_DEC 344 +#define T_Z80_DI 345 +#define T_Z80_EI 346 +#define T_Z80_EX 347 +#define T_Z80_HALT 348 +#define T_Z80_INC 349 +#define T_Z80_JP 350 +#define T_Z80_JR 351 +#define T_Z80_LD 352 +#define T_Z80_LDIO 353 +#define T_Z80_NOP 354 +#define T_Z80_OR 355 +#define T_Z80_POP 356 +#define T_Z80_PUSH 357 +#define T_Z80_RES 358 +#define T_Z80_RET 359 +#define T_Z80_RETI 360 +#define T_Z80_RST 361 +#define T_Z80_RL 362 +#define T_Z80_RLA 363 +#define T_Z80_RLC 364 +#define T_Z80_RLCA 365 +#define T_Z80_RR 366 +#define T_Z80_RRA 367 +#define T_Z80_RRC 368 +#define T_Z80_RRCA 369 +#define T_Z80_SBC 370 +#define T_Z80_SCF 371 +#define T_Z80_STOP 372 +#define T_Z80_SLA 373 +#define T_Z80_SRA 374 +#define T_Z80_SRL 375 +#define T_Z80_SUB 376 +#define T_Z80_SWAP 377 +#define T_Z80_XOR 378 +#define T_MODE_A 379 +#define T_MODE_B 380 +#define T_MODE_C 381 +#define T_MODE_C_IND 382 +#define T_MODE_D 383 +#define T_MODE_E 384 +#define T_MODE_H 385 +#define T_MODE_L 386 +#define T_MODE_AF 387 +#define T_MODE_BC 388 +#define T_MODE_BC_IND 389 +#define T_MODE_DE 390 +#define T_MODE_DE_IND 391 +#define T_MODE_SP 392 +#define T_MODE_SP_IND 393 +#define T_MODE_HL 394 +#define T_MODE_HL_IND 395 +#define T_MODE_HL_INDDEC 396 +#define T_MODE_HL_INDINC 397 +#define T_CC_NZ 398 +#define T_CC_Z 399 +#define T_CC_NC 400 + + +extern YYSTYPE yylval; diff --git a/src/asm/include/lexer.h b/src/asm/include/lexer.h index f67babdb..639ade5d 100644 --- a/src/asm/include/lexer.h +++ b/src/asm/include/lexer.h @@ -1,68 +1,68 @@ -#ifndef LEXER_H -#define LEXER_H - -#include "types.h" -#include - -#define LEXHASHSIZE 512 - -struct sLexInitString -{ - char *tzName; - ULONG nToken; -}; - -struct sLexFloat -{ - ULONG (*Callback)( char *s, ULONG size ); - ULONG nToken; -}; - -struct yy_buffer_state -{ - char *pBufferStart; - char *pBuffer; - ULONG nBufferSize; - ULONG oAtLineStart; -}; - -enum eLexerState -{ - LEX_STATE_NORMAL, - LEX_STATE_MACROARGS -}; - -#define INITIAL 0 -#define macroarg 3 - -typedef struct yy_buffer_state *YY_BUFFER_STATE; - -extern void yy_set_state( enum eLexerState i ); -extern YY_BUFFER_STATE yy_create_buffer( FILE *f ); -extern YY_BUFFER_STATE yy_scan_bytes( char *mem, ULONG size ); -extern void yy_delete_buffer( YY_BUFFER_STATE ); -extern void yy_switch_to_buffer( YY_BUFFER_STATE ); -extern ULONG lex_FloatAlloc( struct sLexFloat *tok ); -extern void lex_FloatAddRange( ULONG id, UWORD start, UWORD end ); -extern void lex_FloatDeleteRange( ULONG id, UWORD start, UWORD end ); -extern void lex_FloatAddFirstRange( ULONG id, UWORD start, UWORD end ); -extern void lex_FloatDeleteFirstRange( ULONG id, UWORD start, UWORD end ); -extern void lex_FloatAddSecondRange( ULONG id, UWORD start, UWORD end ); -extern void lex_FloatDeleteSecondRange( ULONG id, UWORD start, UWORD end ); -extern void lex_Init( void ); -extern void lex_AddStrings( struct sLexInitString *lex ); -extern void lex_SetBuffer( char *buffer, ULONG len ); -extern ULONG yylex( void ); -extern void yyunput( char c ); -extern void yyunputstr( char *s ); -extern void yyskipbytes( ULONG count ); -extern void yyunputbytes( ULONG count ); - -extern YY_BUFFER_STATE pCurrentBuffer; - -#ifdef __GNUC__ -extern void strupr( char *s ); -extern void strlwr( char *s ); -#endif - +#ifndef LEXER_H +#define LEXER_H + +#include "types.h" +#include + +#define LEXHASHSIZE 512 + +struct sLexInitString +{ + char *tzName; + ULONG nToken; +}; + +struct sLexFloat +{ + ULONG (*Callback)( char *s, ULONG size ); + ULONG nToken; +}; + +struct yy_buffer_state +{ + char *pBufferStart; + char *pBuffer; + ULONG nBufferSize; + ULONG oAtLineStart; +}; + +enum eLexerState +{ + LEX_STATE_NORMAL, + LEX_STATE_MACROARGS +}; + +#define INITIAL 0 +#define macroarg 3 + +typedef struct yy_buffer_state *YY_BUFFER_STATE; + +extern void yy_set_state( enum eLexerState i ); +extern YY_BUFFER_STATE yy_create_buffer( FILE *f ); +extern YY_BUFFER_STATE yy_scan_bytes( char *mem, ULONG size ); +extern void yy_delete_buffer( YY_BUFFER_STATE ); +extern void yy_switch_to_buffer( YY_BUFFER_STATE ); +extern ULONG lex_FloatAlloc( struct sLexFloat *tok ); +extern void lex_FloatAddRange( ULONG id, UWORD start, UWORD end ); +extern void lex_FloatDeleteRange( ULONG id, UWORD start, UWORD end ); +extern void lex_FloatAddFirstRange( ULONG id, UWORD start, UWORD end ); +extern void lex_FloatDeleteFirstRange( ULONG id, UWORD start, UWORD end ); +extern void lex_FloatAddSecondRange( ULONG id, UWORD start, UWORD end ); +extern void lex_FloatDeleteSecondRange( ULONG id, UWORD start, UWORD end ); +extern void lex_Init( void ); +extern void lex_AddStrings( struct sLexInitString *lex ); +extern void lex_SetBuffer( char *buffer, ULONG len ); +extern ULONG yylex( void ); +extern void yyunput( char c ); +extern void yyunputstr( char *s ); +extern void yyskipbytes( ULONG count ); +extern void yyunputbytes( ULONG count ); + +extern YY_BUFFER_STATE pCurrentBuffer; + +#ifdef __GNUC__ +extern void strupr( char *s ); +extern void strlwr( char *s ); +#endif + #endif \ No newline at end of file diff --git a/src/asm/include/main.h b/src/asm/include/main.h index 3ccf9429..033303a7 100644 --- a/src/asm/include/main.h +++ b/src/asm/include/main.h @@ -1,35 +1,35 @@ -#ifndef MAIN_H -#define MAIN_H - -struct sOptions -{ - ULONG endian; - char gbgfx[4]; - char binary[2]; - SLONG fillchar; // -1 == random -}; - -extern char *tzNewMacro; -extern ULONG ulNewMacroSize; -extern SLONG nGBGfxID; -extern SLONG nBinaryID; - -extern struct sOptions DefaultOptions; -extern struct sOptions CurrentOptions; -extern void opt_Push( void ); -extern void opt_Pop( void ); -extern void opt_Parse( char *s ); - -void fatalerror( char *s ); -void yyerror( char *s ); - -extern char temptext[1024]; - -#define YY_FATAL_ERROR fatalerror - -#ifdef YYLMAX -#undef YYLMAX -#endif -#define YYLMAX 65536 - +#ifndef MAIN_H +#define MAIN_H + +struct sOptions +{ + ULONG endian; + char gbgfx[4]; + char binary[2]; + SLONG fillchar; // -1 == random +}; + +extern char *tzNewMacro; +extern ULONG ulNewMacroSize; +extern SLONG nGBGfxID; +extern SLONG nBinaryID; + +extern struct sOptions DefaultOptions; +extern struct sOptions CurrentOptions; +extern void opt_Push( void ); +extern void opt_Pop( void ); +extern void opt_Parse( char *s ); + +void fatalerror( char *s ); +void yyerror( char *s ); + +extern char temptext[1024]; + +#define YY_FATAL_ERROR fatalerror + +#ifdef YYLMAX +#undef YYLMAX +#endif +#define YYLMAX 65536 + #endif \ No newline at end of file diff --git a/src/asm/include/mylink.h b/src/asm/include/mylink.h index ba54eb1f..48bc74fc 100644 --- a/src/asm/include/mylink.h +++ b/src/asm/include/mylink.h @@ -1,123 +1,123 @@ -#ifndef LINK_H -#define LINK_H 1 - -/* RGB0 .obj format: - * - * Header - * Symbols - * Sections - * - * Header: - * "RGB0" - * LONG NumberOfSymbols - * LONG NumberOfSections - * - * Symbols: - * Symbol[NumberOfSymbols] - * - * Symbol: - * char Name (NULL terminated) - * char nType - * if( nType!=SYM_IMPORT ) - * { - * LONG SectionID - * LONG Offset - * } - * - * Sections: - * Section[NumberOfSections] - * - * Section: - * LONG SizeInBytes - * char Type - * if( Type!=BSS ) - * { - * char Data[SizeInBytes] - * Patches - * } - * - * Patches: - * LONG NumberOfPatches - * Patch[NumberOfPatches] - * - * Patch: - * char Filename NULL-terminated - * LONG LineNo - * LONG Offset - * char Type - * LONG RpnByteSize - * Rpn[RpnByteSize] - * - * Rpn: - * Operators: 0x00-0x7F - * Constants: 0x80 0x00000000 - * Symbols : 0x81 0x00000000 - * - */ - -enum -{ - RPN_ADD=0, - RPN_SUB, - RPN_MUL, - RPN_DIV, - RPN_MOD, - RPN_UNSUB, - - RPN_OR, - RPN_AND, - RPN_XOR, - RPN_UNNOT, - - RPN_LOGAND, - RPN_LOGOR, - RPN_LOGUNNOT, - - RPN_LOGEQ, - RPN_LOGNE, - RPN_LOGGT, - RPN_LOGLT, - RPN_LOGGE, - RPN_LOGLE, - - RPN_SHL, - RPN_SHR, - - RPN_BANK, - - RPN_HRAM, - - RPN_PCEZP, - - RPN_RANGECHECK, - - RPN_CONST=0x80, - RPN_SYM=0x81 -}; - -enum -{ - SECT_BSS=0, - SECT_VRAM, - SECT_CODE, - SECT_HOME, - SECT_HRAM -}; - -enum -{ - SYM_LOCAL=0, - SYM_IMPORT, - SYM_EXPORT -}; - -enum -{ - PATCH_BYTE=0, - PATCH_WORD_L, - PATCH_LONG_L, - PATCH_WORD_B, - PATCH_LONG_B -}; - +#ifndef LINK_H +#define LINK_H 1 + +/* RGB0 .obj format: + * + * Header + * Symbols + * Sections + * + * Header: + * "RGB0" + * LONG NumberOfSymbols + * LONG NumberOfSections + * + * Symbols: + * Symbol[NumberOfSymbols] + * + * Symbol: + * char Name (NULL terminated) + * char nType + * if( nType!=SYM_IMPORT ) + * { + * LONG SectionID + * LONG Offset + * } + * + * Sections: + * Section[NumberOfSections] + * + * Section: + * LONG SizeInBytes + * char Type + * if( Type!=BSS ) + * { + * char Data[SizeInBytes] + * Patches + * } + * + * Patches: + * LONG NumberOfPatches + * Patch[NumberOfPatches] + * + * Patch: + * char Filename NULL-terminated + * LONG LineNo + * LONG Offset + * char Type + * LONG RpnByteSize + * Rpn[RpnByteSize] + * + * Rpn: + * Operators: 0x00-0x7F + * Constants: 0x80 0x00000000 + * Symbols : 0x81 0x00000000 + * + */ + +enum +{ + RPN_ADD=0, + RPN_SUB, + RPN_MUL, + RPN_DIV, + RPN_MOD, + RPN_UNSUB, + + RPN_OR, + RPN_AND, + RPN_XOR, + RPN_UNNOT, + + RPN_LOGAND, + RPN_LOGOR, + RPN_LOGUNNOT, + + RPN_LOGEQ, + RPN_LOGNE, + RPN_LOGGT, + RPN_LOGLT, + RPN_LOGGE, + RPN_LOGLE, + + RPN_SHL, + RPN_SHR, + + RPN_BANK, + + RPN_HRAM, + + RPN_PCEZP, + + RPN_RANGECHECK, + + RPN_CONST=0x80, + RPN_SYM=0x81 +}; + +enum +{ + SECT_BSS=0, + SECT_VRAM, + SECT_CODE, + SECT_HOME, + SECT_HRAM +}; + +enum +{ + SYM_LOCAL=0, + SYM_IMPORT, + SYM_EXPORT +}; + +enum +{ + PATCH_BYTE=0, + PATCH_WORD_L, + PATCH_LONG_L, + PATCH_WORD_B, + PATCH_LONG_B +}; + #endif \ No newline at end of file diff --git a/src/asm/include/mymath.h b/src/asm/include/mymath.h index 9d2751a6..d00de0b4 100644 --- a/src/asm/include/mymath.h +++ b/src/asm/include/mymath.h @@ -1,18 +1,18 @@ -#ifndef MATH_H -#define MATH_H - -#include "types.h" - -void math_DefinePI( void ); -void math_Print( SLONG i ); -SLONG math_Sin( SLONG i ); -SLONG math_Cos( SLONG i ); -SLONG math_Tan( SLONG i ); -SLONG math_ASin( SLONG i ); -SLONG math_ACos( SLONG i ); -SLONG math_ATan( SLONG i ); -SLONG math_ATan2( SLONG i, SLONG j ); -SLONG math_Mul( SLONG i, SLONG j ); -SLONG math_Div( SLONG i, SLONG j ); - -#endif +#ifndef MATH_H +#define MATH_H + +#include "types.h" + +void math_DefinePI( void ); +void math_Print( SLONG i ); +SLONG math_Sin( SLONG i ); +SLONG math_Cos( SLONG i ); +SLONG math_Tan( SLONG i ); +SLONG math_ASin( SLONG i ); +SLONG math_ACos( SLONG i ); +SLONG math_ATan( SLONG i ); +SLONG math_ATan2( SLONG i, SLONG j ); +SLONG math_Mul( SLONG i, SLONG j ); +SLONG math_Div( SLONG i, SLONG j ); + +#endif diff --git a/src/asm/include/output.h b/src/asm/include/output.h index 66531725..cd625c0a 100644 --- a/src/asm/include/output.h +++ b/src/asm/include/output.h @@ -1,36 +1,36 @@ -#ifndef OUTPUT_H -#define OUTPUT_H 1 - -#include "rpn.h" -#include "types.h" - -struct Section -{ - char *pzName; - UBYTE nType; - ULONG nPC; - ULONG nOrg; - ULONG nBank; - struct Section *pNext; - struct Patch *pPatches; - UBYTE *tData; -}; - -void out_PrepPass2( void ); -void out_SetFileName( char *s ); -void out_NewSection (char *pzName, ULONG secttype); -void out_NewAbsSection (char *pzName, ULONG secttype, SLONG org, SLONG bank); -void out_AbsByte( int b ); -void out_RelByte( struct Expression *expr ); -void out_RelWord( struct Expression *expr ); -void out_PCRelByte( struct Expression *expr ); -void out_WriteObject( void ); -void out_Skip( int skip ); -void out_BinaryFile( char *s ); -void out_String( char *s ); -void out_AbsLong (SLONG b); -void out_RelLong (struct Expression *expr); -void out_PushSection( void ); -void out_PopSection( void ); - -#endif +#ifndef OUTPUT_H +#define OUTPUT_H 1 + +#include "rpn.h" +#include "types.h" + +struct Section +{ + char *pzName; + UBYTE nType; + ULONG nPC; + ULONG nOrg; + ULONG nBank; + struct Section *pNext; + struct Patch *pPatches; + UBYTE *tData; +}; + +void out_PrepPass2( void ); +void out_SetFileName( char *s ); +void out_NewSection (char *pzName, ULONG secttype); +void out_NewAbsSection (char *pzName, ULONG secttype, SLONG org, SLONG bank); +void out_AbsByte( int b ); +void out_RelByte( struct Expression *expr ); +void out_RelWord( struct Expression *expr ); +void out_PCRelByte( struct Expression *expr ); +void out_WriteObject( void ); +void out_Skip( int skip ); +void out_BinaryFile( char *s ); +void out_String( char *s ); +void out_AbsLong (SLONG b); +void out_RelLong (struct Expression *expr); +void out_PushSection( void ); +void out_PopSection( void ); + +#endif diff --git a/src/asm/include/rpn.h b/src/asm/include/rpn.h index 83467502..fde6b837 100644 --- a/src/asm/include/rpn.h +++ b/src/asm/include/rpn.h @@ -1,51 +1,51 @@ -#ifndef RPN_H -#define RPN_H 1 - -struct Expression -{ - SLONG nVal; - UBYTE tRPN[256]; - ULONG nRPNLength; - ULONG nRPNOut; - ULONG isReloc; - ULONG isPCRel; -}; - - -ULONG rpn_isReloc( struct Expression *expr ); -ULONG rpn_isPCRelative( struct Expression *expr ); -void rpn_Symbol( struct Expression *expr, char *tzSym ); -void rpn_Number( struct Expression *expr, ULONG i ); -void rpn_LOGNOT( struct Expression *expr, struct Expression *src1 ); -void rpn_LOGOR( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); -void rpn_LOGAND( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); -void rpn_LOGEQU( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); -void rpn_LOGGT( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); -void rpn_LOGLT( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); -void rpn_LOGGE( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); -void rpn_LOGLE( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); -void rpn_LOGNE( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); -void rpn_ADD( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); -void rpn_SUB( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); -void rpn_XOR( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); -void rpn_OR( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); -void rpn_AND( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); -void rpn_SHL( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); -void rpn_SHR( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); -void rpn_MUL( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); -void rpn_DIV( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); -void rpn_MOD( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); -void rpn_UNNEG( struct Expression *expr, struct Expression *src ); -void rpn_UNNOT( struct Expression *expr, struct Expression *src ); -UWORD rpn_PopByte( struct Expression *expr ); -void rpn_Bank( struct Expression *expr, char *tzSym ); -void rpn_Reset( struct Expression *expr ); -int rpn_RangeCheck( struct Expression *expr, struct Expression *src, SLONG low, SLONG high ); -#ifdef GAMEBOY -void rpn_CheckHRAM( struct Expression *expr,struct Expression *src1 ); -#endif -#ifdef PCENGINE -void rpn_CheckZP( struct Expression *expr,struct Expression *src ); -#endif - +#ifndef RPN_H +#define RPN_H 1 + +struct Expression +{ + SLONG nVal; + UBYTE tRPN[256]; + ULONG nRPNLength; + ULONG nRPNOut; + ULONG isReloc; + ULONG isPCRel; +}; + + +ULONG rpn_isReloc( struct Expression *expr ); +ULONG rpn_isPCRelative( struct Expression *expr ); +void rpn_Symbol( struct Expression *expr, char *tzSym ); +void rpn_Number( struct Expression *expr, ULONG i ); +void rpn_LOGNOT( struct Expression *expr, struct Expression *src1 ); +void rpn_LOGOR( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); +void rpn_LOGAND( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); +void rpn_LOGEQU( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); +void rpn_LOGGT( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); +void rpn_LOGLT( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); +void rpn_LOGGE( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); +void rpn_LOGLE( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); +void rpn_LOGNE( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); +void rpn_ADD( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); +void rpn_SUB( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); +void rpn_XOR( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); +void rpn_OR( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); +void rpn_AND( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); +void rpn_SHL( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); +void rpn_SHR( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); +void rpn_MUL( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); +void rpn_DIV( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); +void rpn_MOD( struct Expression *expr, struct Expression *src1, struct Expression *src2 ); +void rpn_UNNEG( struct Expression *expr, struct Expression *src ); +void rpn_UNNOT( struct Expression *expr, struct Expression *src ); +UWORD rpn_PopByte( struct Expression *expr ); +void rpn_Bank( struct Expression *expr, char *tzSym ); +void rpn_Reset( struct Expression *expr ); +int rpn_RangeCheck( struct Expression *expr, struct Expression *src, SLONG low, SLONG high ); +#ifdef GAMEBOY +void rpn_CheckHRAM( struct Expression *expr,struct Expression *src1 ); +#endif +#ifdef PCENGINE +void rpn_CheckZP( struct Expression *expr,struct Expression *src ); +#endif + #endif \ No newline at end of file diff --git a/src/asm/include/symbol.h b/src/asm/include/symbol.h index 8ba3a411..6a3a6c41 100644 --- a/src/asm/include/symbol.h +++ b/src/asm/include/symbol.h @@ -1,68 +1,68 @@ -#ifndef SYMBOL_H -#define SYMBOL_H 1 - -#include "types.h" - -#define HASHSIZE 73 -#define MAXSYMLEN 256 - -struct sSymbol -{ - char tzName[MAXSYMLEN+1]; - SLONG nValue; - ULONG nType; - struct sSymbol *pScope; - struct sSymbol *pNext; - struct Section *pSection; - ULONG ulMacroSize; - char *pMacro; - SLONG (*Callback)(struct sSymbol *); -}; - -#define SYMF_RELOC 0x001 /* symbol will be reloc'ed during linking, it's absolute value is unknown */ -#define SYMF_EQU 0x002 /* symbol is defined using EQU, will not be changed during linking */ -#define SYMF_SET 0x004 /* symbol is (re)defined using SET, will not be changed during linking */ -#define SYMF_EXPORT 0x008 /* symbol should be exported */ -#define SYMF_IMPORT 0x010 /* symbol is imported, it's value is unknown */ -#define SYMF_LOCAL 0x020 /* symbol is a local symbol */ -#define SYMF_DEFINED 0x040 /* symbol has been defined, not only referenced */ -#define SYMF_MACRO 0x080 /* symbol is a macro */ -#define SYMF_STRING 0x100 /* symbol is a stringsymbol */ -#define SYMF_CONST 0x200 /* symbol has a constant value, will not be changed during linking */ - -void sym_PrepPass1( void ); -void sym_PrepPass2( void ); -void sym_AddLocalReloc( char *tzSym ); -void sym_AddReloc( char *tzSym ); -void sym_Export( char *tzSym ); -void sym_PrintSymbolTable( void ); -struct sSymbol *sym_FindMacro( char *s ); -void sym_InitNewMacroArgs( void ); -void sym_AddNewMacroArg( char *s ); -void sym_SaveCurrentMacroArgs( char *save[] ); -void sym_RestoreCurrentMacroArgs( char *save[] ); -void sym_UseNewMacroArgs( void ); -void sym_FreeCurrentMacroArgs( void ); -void sym_AddEqu( char *tzSym, SLONG value ); -void sym_AddSet( char *tzSym, SLONG value ); -void sym_Init( void ); -ULONG sym_GetConstantValue( char *s ); -void sym_Import( char *tzSym ); -ULONG sym_isConstant( char *s ); -struct sSymbol *sym_FindSymbol( char *tzName ); -void sym_Global( char *tzSym ); -char *sym_FindMacroArg( SLONG i ); -char *sym_GetStringValue( char *tzSym ); -void sym_UseCurrentMacroArgs( void ); -void sym_SetMacroArgID( ULONG nMacroCount ); -ULONG sym_isString( char *tzSym ); -void sym_AddMacro( char *tzSym ); -void sym_ShiftCurrentMacroArgs( void ); -void sym_AddString( char *tzSym, char *tzValue ); -ULONG sym_GetValue( char *s ); -ULONG sym_GetDefinedValue( char *s ); -ULONG sym_isDefined( char *tzName ); -void sym_Purge( char *tzName ); -ULONG sym_isConstDefined (char *tzName); - +#ifndef SYMBOL_H +#define SYMBOL_H 1 + +#include "types.h" + +#define HASHSIZE 73 +#define MAXSYMLEN 256 + +struct sSymbol +{ + char tzName[MAXSYMLEN+1]; + SLONG nValue; + ULONG nType; + struct sSymbol *pScope; + struct sSymbol *pNext; + struct Section *pSection; + ULONG ulMacroSize; + char *pMacro; + SLONG (*Callback)(struct sSymbol *); +}; + +#define SYMF_RELOC 0x001 /* symbol will be reloc'ed during linking, it's absolute value is unknown */ +#define SYMF_EQU 0x002 /* symbol is defined using EQU, will not be changed during linking */ +#define SYMF_SET 0x004 /* symbol is (re)defined using SET, will not be changed during linking */ +#define SYMF_EXPORT 0x008 /* symbol should be exported */ +#define SYMF_IMPORT 0x010 /* symbol is imported, it's value is unknown */ +#define SYMF_LOCAL 0x020 /* symbol is a local symbol */ +#define SYMF_DEFINED 0x040 /* symbol has been defined, not only referenced */ +#define SYMF_MACRO 0x080 /* symbol is a macro */ +#define SYMF_STRING 0x100 /* symbol is a stringsymbol */ +#define SYMF_CONST 0x200 /* symbol has a constant value, will not be changed during linking */ + +void sym_PrepPass1( void ); +void sym_PrepPass2( void ); +void sym_AddLocalReloc( char *tzSym ); +void sym_AddReloc( char *tzSym ); +void sym_Export( char *tzSym ); +void sym_PrintSymbolTable( void ); +struct sSymbol *sym_FindMacro( char *s ); +void sym_InitNewMacroArgs( void ); +void sym_AddNewMacroArg( char *s ); +void sym_SaveCurrentMacroArgs( char *save[] ); +void sym_RestoreCurrentMacroArgs( char *save[] ); +void sym_UseNewMacroArgs( void ); +void sym_FreeCurrentMacroArgs( void ); +void sym_AddEqu( char *tzSym, SLONG value ); +void sym_AddSet( char *tzSym, SLONG value ); +void sym_Init( void ); +ULONG sym_GetConstantValue( char *s ); +void sym_Import( char *tzSym ); +ULONG sym_isConstant( char *s ); +struct sSymbol *sym_FindSymbol( char *tzName ); +void sym_Global( char *tzSym ); +char *sym_FindMacroArg( SLONG i ); +char *sym_GetStringValue( char *tzSym ); +void sym_UseCurrentMacroArgs( void ); +void sym_SetMacroArgID( ULONG nMacroCount ); +ULONG sym_isString( char *tzSym ); +void sym_AddMacro( char *tzSym ); +void sym_ShiftCurrentMacroArgs( void ); +void sym_AddString( char *tzSym, char *tzValue ); +ULONG sym_GetValue( char *s ); +ULONG sym_GetDefinedValue( char *s ); +ULONG sym_isDefined( char *tzName ); +void sym_Purge( char *tzName ); +ULONG sym_isConstDefined (char *tzName); + #endif \ No newline at end of file diff --git a/src/asm/include/types.h b/src/asm/include/types.h index 2a817377..77909fc4 100644 --- a/src/asm/include/types.h +++ b/src/asm/include/types.h @@ -1,18 +1,18 @@ -#ifndef TYPES_H -#define TYPES_H 1 - -#if defined(AMIGA) || defined(__GNUC__) -#define _MAX_PATH 512 -#endif - -typedef unsigned char UBYTE; -typedef signed char SBYTE; -typedef unsigned short UWORD; -typedef signed short SWORD; -typedef unsigned long ULONG; -typedef signed long SLONG; - -#define ASM_LITTLE_ENDIAN 0 -#define ASM_BIG_ENDIAN 1 - +#ifndef TYPES_H +#define TYPES_H 1 + +#if defined(AMIGA) || defined(__GNUC__) +#define _MAX_PATH 512 +#endif + +typedef unsigned char UBYTE; +typedef signed char SBYTE; +typedef unsigned short UWORD; +typedef signed short SWORD; +typedef unsigned long ULONG; +typedef signed long SLONG; + +#define ASM_LITTLE_ENDIAN 0 +#define ASM_BIG_ENDIAN 1 + #endif \ No newline at end of file diff --git a/src/asm/lexer.c b/src/asm/lexer.c index 8b109855..9d17f1c2 100644 --- a/src/asm/lexer.c +++ b/src/asm/lexer.c @@ -1,813 +1,813 @@ -#include "asm.h" -#include "lexer.h" -#include "types.h" -#include "main.h" -#include "rpn.h" -#include "asmy.h" -#include "fstack.h" -#include -#include -#include -#include - -struct sLexString -{ - char *tzName; - ULONG nToken; - ULONG nNameLength; - struct sLexString *pNext; -}; - -#define pLexBuffer (pCurrentBuffer->pBuffer) -#define nLexBufferLeng (pCurrentBuffer->nBufferSize) - -#define SAFETYMARGIN 1024 - -extern ULONG symvaluetostring (char *dest, char *s); - -struct sLexFloat tLexFloat[32]; -struct sLexString *tLexHash[LEXHASHSIZE]; -YY_BUFFER_STATE pCurrentBuffer; -ULONG yyleng; -ULONG nLexMaxLeng; - -ULONG tFloatingSecondChar[256]; -ULONG tFloatingFirstChar[256]; -ULONG tFloatingChars[256]; -ULONG nFloating; -enum eLexerState lexerstate=LEX_STATE_NORMAL; - -#define AtLineStart pCurrentBuffer->oAtLineStart - -#ifdef __GNUC__ -void strupr( char *s ) -{ - while( *s ) - { - *s=toupper(*s); - s+=1; - } -} - -void strlwr( char *s ) -{ - while( *s ) - { - *s=tolower(*s); - s+=1; - } -} - -#endif -void yyskipbytes( ULONG count ) -{ - pLexBuffer+=count; -} - -void yyunputbytes( ULONG count ) -{ - pLexBuffer-=count; -} - -void yyunput( char c ) -{ - *(--pLexBuffer)=c; -} - -void yyunputstr( char *s ) -{ - SLONG i; - - i=strlen(s)-1; - - while( i>=0 ) - yyunput( s[i--] ); -} - -void yy_switch_to_buffer( YY_BUFFER_STATE buf ) -{ - pCurrentBuffer=buf; -} - -void yy_set_state( enum eLexerState i ) -{ - lexerstate=i; -} - -void yy_delete_buffer( YY_BUFFER_STATE buf ) -{ - free( buf->pBufferStart-SAFETYMARGIN ); - free( buf ); -} - -YY_BUFFER_STATE yy_scan_bytes( char *mem, ULONG size ) -{ - YY_BUFFER_STATE pBuffer; - - if( (pBuffer=(YY_BUFFER_STATE)malloc(sizeof(struct yy_buffer_state)))!=NULL ) - { - if( (pBuffer->pBuffer=pBuffer->pBufferStart=(char *)malloc(size+1+SAFETYMARGIN))!=NULL ) - { - pBuffer->pBuffer+=SAFETYMARGIN; - pBuffer->pBufferStart+=SAFETYMARGIN; - memcpy( pBuffer->pBuffer, mem, size ); - pBuffer->nBufferSize=size; - pBuffer->oAtLineStart=1; - pBuffer->pBuffer[size]=0; - return( pBuffer ); - } - } - - fatalerror( "Out of memory!" ); - return( NULL ); -} - -YY_BUFFER_STATE yy_create_buffer( FILE *f ) -{ - YY_BUFFER_STATE pBuffer; - - if( (pBuffer=(YY_BUFFER_STATE)malloc(sizeof(struct yy_buffer_state)))!=NULL ) - { - ULONG size; - - fseek (f, 0, SEEK_END); - size = ftell (f); - fseek (f, 0, SEEK_SET); - - if( (pBuffer->pBuffer=pBuffer->pBufferStart=(char *)malloc(size+2+SAFETYMARGIN))!=NULL ) - { - char *mem; - ULONG instring = 0; - - pBuffer->pBuffer+=SAFETYMARGIN; - pBuffer->pBufferStart+=SAFETYMARGIN; - - size=fread( pBuffer->pBuffer, sizeof (UBYTE), size, f ); - - pBuffer->pBuffer[size]='\n'; - pBuffer->pBuffer[size+1]=0; - pBuffer->nBufferSize=size+1; - - mem=pBuffer->pBuffer; - - while( *mem ) - { - if( *mem=='\"' ) - instring=1-instring; - - if( instring ) - { - mem+=1; - } - else - { - if( (mem[0]==10 && mem[1]==13) - || (mem[0]==13 && mem[1]==10) ) - { - mem[0]=' '; - mem[1]='\n'; - mem+=2; - } - else if( mem[0]==10 || mem[0]==13 ) - { - mem[0]='\n'; - mem+=1; - } - else if( mem[0]=='\n' && mem[1]=='*' ) - { - mem+=1; - while( !(*mem == '\n' || *mem == '\0') ) - *mem++=' '; - } - else if( *mem==';' ) - { - while( !(*mem == '\n' || *mem == '\0') ) - *mem++=' '; - } - else - mem+=1; - } - } - - pBuffer->oAtLineStart=1; - return( pBuffer ); - } - } - - fatalerror( "Out of memory!" ); - return( NULL ); -} - -ULONG lex_FloatAlloc( struct sLexFloat *tok ) -{ - tLexFloat[nFloating]=(*tok); - - return( 1<<(nFloating++) ); -} - -void lex_FloatDeleteRange( ULONG id, UWORD start, UWORD end ) -{ - while( start<=end ) - { - tFloatingChars[start]&=~id; - start+=1; - } -} - -void lex_FloatAddRange( ULONG id, UWORD start, UWORD end ) -{ - while( start<=end ) - { - tFloatingChars[start]|=id; - start+=1; - } -} - -void lex_FloatDeleteFirstRange( ULONG id, UWORD start, UWORD end ) -{ - while( start<=end ) - { - tFloatingFirstChar[start]&=~id; - start+=1; - } -} - -void lex_FloatAddFirstRange( ULONG id, UWORD start, UWORD end ) -{ - while( start<=end ) - { - tFloatingFirstChar[start]|=id; - start+=1; - } -} - -void lex_FloatDeleteSecondRange( ULONG id, UWORD start, UWORD end ) -{ - while( start<=end ) - { - tFloatingSecondChar[start]&=~id; - start+=1; - } -} - -void lex_FloatAddSecondRange( ULONG id, UWORD start, UWORD end ) -{ - while( start<=end ) - { - tFloatingSecondChar[start]|=id; - start+=1; - } -} - -struct sLexFloat *lexgetfloat( ULONG id ) -{ - ULONG r=0, - mask=1; - - if( id==0 ) - return( NULL ); - - while( (id&mask)==0 ) - { - mask<<=1; - r+=1; - } - - return( &tLexFloat[r] ); -} - -ULONG lexcalchash( char *s ) -{ - ULONG r=0; - - while( *s ) - { - r=((r<<1)+(toupper(*s)))%LEXHASHSIZE; - s+=1; - } - - return( r ); -} - -void lex_Init( void ) -{ - ULONG i; - - for( i=0; itzName ) - { - struct sLexString **ppHash; - ULONG hash; - - ppHash = &tLexHash[hash=lexcalchash (lex->tzName)]; - while (*ppHash) - ppHash = &((*ppHash)->pNext); - -// printf( "%s has hashvalue %d\n", lex->tzName, hash ); - - if( ((*ppHash)=(struct sLexString *)malloc(sizeof(struct sLexString)))!=NULL ) - { - if( ((*ppHash)->tzName=(char *)strdup(lex->tzName))!=NULL ) - { - (*ppHash)->nNameLength = strlen (lex->tzName); - (*ppHash)->nToken = lex->nToken; - (*ppHash)->pNext = NULL; - - strupr ((*ppHash)->tzName); - - if ((*ppHash)->nNameLength > nLexMaxLeng) - nLexMaxLeng = (*ppHash)->nNameLength; - - } - else - fatalerror ("Out of memory!"); - } - else - fatalerror ("Out of memory!"); - - lex += 1; - } -} - -ULONG yylex (void) -{ - ULONG hash, - maxlen; - char *s; - struct sLexString *pLongestFixed = NULL; - ULONG nFloatMask, - nOldFloatMask, - nFloatLen; - ULONG linestart = AtLineStart; - - switch( lexerstate ) - { - case LEX_STATE_NORMAL: - AtLineStart = 0; - - scanagain: - - while (*pLexBuffer == ' ' || *pLexBuffer == '\t') - { - linestart = 0; - pLexBuffer += 1; - } - - if (*pLexBuffer == 0) - { - if (yywrap () == 0) - { - linestart = AtLineStart; - AtLineStart = 0; - goto scanagain; - } - } - - s = pLexBuffer; - nOldFloatMask = nFloatLen = 0; - nFloatMask = tFloatingFirstChar[*s++]; - while (nFloatMask && nFloatLen < nLexBufferLeng) - { - nFloatLen += 1; - nOldFloatMask = nFloatMask; - if (nFloatLen == 1) - nFloatMask &= tFloatingSecondChar[*s++]; - else - nFloatMask &= tFloatingChars[*s++]; - } - - maxlen = nLexBufferLeng; - if (nLexMaxLeng < maxlen) - maxlen = nLexMaxLeng; - - yyleng = 0; - hash = 0; - s = pLexBuffer; - while (yyleng < nLexMaxLeng) - { - yyleng += 1; - hash = ((hash << 1) + (toupper (*s))) % LEXHASHSIZE; - s+=1; - if (tLexHash[hash]) - { - struct sLexString *lex; - - lex = tLexHash[hash]; - while (lex) - { - if (lex->nNameLength == yyleng) - { - if (strnicmp (pLexBuffer, lex->tzName, yyleng) == 0) - { - pLongestFixed = lex; - } - } - lex = lex->pNext; - } - } - - } - - if (nFloatLen == 0 && pLongestFixed == NULL) - { - if (*pLexBuffer == '"') - { - ULONG index = 0; - - pLexBuffer += 1; - while ((*pLexBuffer != '"') && (*pLexBuffer != '\n')) - { - char ch, - *marg; - - if ((ch = *pLexBuffer++) == '\\') - { - switch (ch = (*pLexBuffer++)) - { - case 'n': - ch = '\n'; - break; - case 't': - ch = '\t'; - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if( (marg=sym_FindMacroArg(ch-'0'))!=NULL ) - { - while (*marg) - yylval.tzString[index++] = *marg++; - ch = 0; - } - break; - case '@': - if( (marg=sym_FindMacroArg(-1))!=NULL ) - { - while (*marg) - yylval.tzString[index++] = *marg++; - ch = 0; - } - break; - } - } - else if (ch == '{') - { - char sym[MAXSYMLEN]; - int i = 0; - - while ((*pLexBuffer != '}') && (*pLexBuffer != '"') && (*pLexBuffer != '\n')) - { - if ((ch = *pLexBuffer++) == '\\') - { - switch (ch = (*pLexBuffer++)) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if( (marg=sym_FindMacroArg(ch-'0'))!=NULL ) - { - while (*marg) - sym[i++] = *marg++; - ch = 0; - } - break; - case '@': - if( (marg=sym_FindMacroArg(-1))!=NULL ) - { - while (*marg) - sym[i++] = *marg++; - ch = 0; - } - break; - } - } - else - sym[i++] = ch; - } - - sym[i] = 0; - index += symvaluetostring (&yylval.tzString[index], sym); - if (*pLexBuffer == '}') - pLexBuffer += 1; - else - yyerror ("Missing }"); - ch = 0; - } - - if (ch) - yylval.tzString[index++] = ch; - } - - yylval.tzString[index++] = 0; - - if (*pLexBuffer == '\n') - yyerror ("Unterminated string"); - else - pLexBuffer += 1; - - return (T_STRING); - } - else if (*pLexBuffer == '{') - { - char sym[MAXSYMLEN], - ch, - *marg; - int i = 0; - - pLexBuffer += 1; - - while ((*pLexBuffer != '}') && (*pLexBuffer != '\n')) - { - if ((ch = *pLexBuffer++) == '\\') - { - switch (ch = (*pLexBuffer++)) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if( (marg=sym_FindMacroArg(ch-'0'))!=NULL ) - { - while (*marg) - sym[i++] = *marg++; - ch = 0; - } - break; - case '@': - if( (marg=sym_FindMacroArg(-1))!=NULL ) - { - while (*marg) - sym[i++] = *marg++; - ch = 0; - } - break; - } - } - else - sym[i++] = ch; - } - sym[i] = 0; - symvaluetostring (yylval.tzString, sym); - if (*pLexBuffer == '}') - pLexBuffer += 1; - else - yyerror ("Missing }"); - - return (T_STRING); - } - else - { - if (*pLexBuffer == '\n') - AtLineStart = 1; - - yyleng = 1; - return (*pLexBuffer++); - } - } - - if (nFloatLen == 0) - { - yyleng = pLongestFixed->nNameLength; - pLexBuffer += yyleng; - return (pLongestFixed->nToken); - } - - if (pLongestFixed == NULL) - { - struct sLexFloat *tok; - - tok = lexgetfloat (nOldFloatMask); - yyleng = nFloatLen; - if (tok->Callback) - { - if (tok->Callback (pLexBuffer, yyleng) == 0) - goto scanagain; - } - - if (tok->nToken == T_ID && linestart) - { - pLexBuffer += yyleng; - return (T_LABEL); - } - else - { - pLexBuffer += yyleng; - return (tok->nToken); - } - } - - if (nFloatLen > pLongestFixed->nNameLength) - { - struct sLexFloat *tok; - - tok = lexgetfloat (nOldFloatMask); - yyleng = nFloatLen; - if (tok->Callback) - { - if (tok->Callback (pLexBuffer, yyleng) == 0) - goto scanagain; - } - - if (tok->nToken == T_ID && linestart) - { - pLexBuffer += yyleng; - return (T_LABEL); - } - else - { - pLexBuffer += yyleng; - return (tok->nToken); - } - } - else - { - yyleng = pLongestFixed->nNameLength; - pLexBuffer += yyleng; - return (pLongestFixed->nToken); - } - break; - - case LEX_STATE_MACROARGS: - { - ULONG index = 0; - - while (*pLexBuffer == ' ' || *pLexBuffer == '\t') - { - linestart = 0; - pLexBuffer += 1; - } - - while( (*pLexBuffer != ',') - && (*pLexBuffer != '\n') ) - { - char ch, - *marg; - - if ((ch = *pLexBuffer++) == '\\') - { - switch (ch = (*pLexBuffer++)) - { - case 'n': - ch = '\n'; - break; - case 't': - ch = '\t'; - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if( (marg=sym_FindMacroArg(ch-'0'))!=NULL ) - { - while (*marg) - yylval.tzString[index++] = *marg++; - ch = 0; - } - break; - case '@': - if( (marg=sym_FindMacroArg(-1))!=NULL ) - { - while (*marg) - yylval.tzString[index++] = *marg++; - ch = 0; - } - break; - } - } - else if (ch == '{') - { - char sym[MAXSYMLEN]; - int i = 0; - - while ((*pLexBuffer != '}') && (*pLexBuffer != '"') && (*pLexBuffer != '\n')) - { - if ((ch = *pLexBuffer++) == '\\') - { - switch (ch = (*pLexBuffer++)) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if( (marg=sym_FindMacroArg(ch-'0'))!=NULL ) - { - while (*marg) - sym[i++] = *marg++; - ch = 0; - } - break; - case '@': - if( (marg=sym_FindMacroArg(-1))!=NULL ) - { - while (*marg) - sym[i++] = *marg++; - ch = 0; - } - break; - } - } - else - sym[i++] = ch; - } - sym[i] = 0; - index += symvaluetostring (&yylval.tzString[index], sym); - if (*pLexBuffer == '}') - pLexBuffer += 1; - else - yyerror ("Missing }"); - ch = 0; - } - - if (ch) - yylval.tzString[index++] = ch; - } - - if( index ) - { - yyleng=index; - yylval.tzString[index] = 0; - if( *pLexBuffer=='\n' ) - { - while( yylval.tzString[--index]==' ' ) - { - yylval.tzString[index]=0; - yyleng-=1; - } - } - return (T_STRING); - } - else if( *pLexBuffer=='\n' ) - { - pLexBuffer+=1; - AtLineStart = 1; - yyleng = 1; - return( '\n' ); - } - else if( *pLexBuffer==',' ) - { - pLexBuffer+=1; - yyleng = 1; - return( ',' ); - } - else - { - yyerror( "INTERNAL ERROR IN YYLEX" ); - return( 0 ); - } - } - - break; - } - - yyerror( "INTERNAL ERROR IN YYLEX" ); - return( 0 ); +#include "asm.h" +#include "lexer.h" +#include "types.h" +#include "main.h" +#include "rpn.h" +#include "asmy.h" +#include "fstack.h" +#include +#include +#include +#include + +struct sLexString +{ + char *tzName; + ULONG nToken; + ULONG nNameLength; + struct sLexString *pNext; +}; + +#define pLexBuffer (pCurrentBuffer->pBuffer) +#define nLexBufferLeng (pCurrentBuffer->nBufferSize) + +#define SAFETYMARGIN 1024 + +extern ULONG symvaluetostring (char *dest, char *s); + +struct sLexFloat tLexFloat[32]; +struct sLexString *tLexHash[LEXHASHSIZE]; +YY_BUFFER_STATE pCurrentBuffer; +ULONG yyleng; +ULONG nLexMaxLeng; + +ULONG tFloatingSecondChar[256]; +ULONG tFloatingFirstChar[256]; +ULONG tFloatingChars[256]; +ULONG nFloating; +enum eLexerState lexerstate=LEX_STATE_NORMAL; + +#define AtLineStart pCurrentBuffer->oAtLineStart + +#ifdef __GNUC__ +void strupr( char *s ) +{ + while( *s ) + { + *s=toupper(*s); + s+=1; + } +} + +void strlwr( char *s ) +{ + while( *s ) + { + *s=tolower(*s); + s+=1; + } +} + +#endif +void yyskipbytes( ULONG count ) +{ + pLexBuffer+=count; +} + +void yyunputbytes( ULONG count ) +{ + pLexBuffer-=count; +} + +void yyunput( char c ) +{ + *(--pLexBuffer)=c; +} + +void yyunputstr( char *s ) +{ + SLONG i; + + i=strlen(s)-1; + + while( i>=0 ) + yyunput( s[i--] ); +} + +void yy_switch_to_buffer( YY_BUFFER_STATE buf ) +{ + pCurrentBuffer=buf; +} + +void yy_set_state( enum eLexerState i ) +{ + lexerstate=i; +} + +void yy_delete_buffer( YY_BUFFER_STATE buf ) +{ + free( buf->pBufferStart-SAFETYMARGIN ); + free( buf ); +} + +YY_BUFFER_STATE yy_scan_bytes( char *mem, ULONG size ) +{ + YY_BUFFER_STATE pBuffer; + + if( (pBuffer=(YY_BUFFER_STATE)malloc(sizeof(struct yy_buffer_state)))!=NULL ) + { + if( (pBuffer->pBuffer=pBuffer->pBufferStart=(char *)malloc(size+1+SAFETYMARGIN))!=NULL ) + { + pBuffer->pBuffer+=SAFETYMARGIN; + pBuffer->pBufferStart+=SAFETYMARGIN; + memcpy( pBuffer->pBuffer, mem, size ); + pBuffer->nBufferSize=size; + pBuffer->oAtLineStart=1; + pBuffer->pBuffer[size]=0; + return( pBuffer ); + } + } + + fatalerror( "Out of memory!" ); + return( NULL ); +} + +YY_BUFFER_STATE yy_create_buffer( FILE *f ) +{ + YY_BUFFER_STATE pBuffer; + + if( (pBuffer=(YY_BUFFER_STATE)malloc(sizeof(struct yy_buffer_state)))!=NULL ) + { + ULONG size; + + fseek (f, 0, SEEK_END); + size = ftell (f); + fseek (f, 0, SEEK_SET); + + if( (pBuffer->pBuffer=pBuffer->pBufferStart=(char *)malloc(size+2+SAFETYMARGIN))!=NULL ) + { + char *mem; + ULONG instring = 0; + + pBuffer->pBuffer+=SAFETYMARGIN; + pBuffer->pBufferStart+=SAFETYMARGIN; + + size=fread( pBuffer->pBuffer, sizeof (UBYTE), size, f ); + + pBuffer->pBuffer[size]='\n'; + pBuffer->pBuffer[size+1]=0; + pBuffer->nBufferSize=size+1; + + mem=pBuffer->pBuffer; + + while( *mem ) + { + if( *mem=='\"' ) + instring=1-instring; + + if( instring ) + { + mem+=1; + } + else + { + if( (mem[0]==10 && mem[1]==13) + || (mem[0]==13 && mem[1]==10) ) + { + mem[0]=' '; + mem[1]='\n'; + mem+=2; + } + else if( mem[0]==10 || mem[0]==13 ) + { + mem[0]='\n'; + mem+=1; + } + else if( mem[0]=='\n' && mem[1]=='*' ) + { + mem+=1; + while( !(*mem == '\n' || *mem == '\0') ) + *mem++=' '; + } + else if( *mem==';' ) + { + while( !(*mem == '\n' || *mem == '\0') ) + *mem++=' '; + } + else + mem+=1; + } + } + + pBuffer->oAtLineStart=1; + return( pBuffer ); + } + } + + fatalerror( "Out of memory!" ); + return( NULL ); +} + +ULONG lex_FloatAlloc( struct sLexFloat *tok ) +{ + tLexFloat[nFloating]=(*tok); + + return( 1<<(nFloating++) ); +} + +void lex_FloatDeleteRange( ULONG id, UWORD start, UWORD end ) +{ + while( start<=end ) + { + tFloatingChars[start]&=~id; + start+=1; + } +} + +void lex_FloatAddRange( ULONG id, UWORD start, UWORD end ) +{ + while( start<=end ) + { + tFloatingChars[start]|=id; + start+=1; + } +} + +void lex_FloatDeleteFirstRange( ULONG id, UWORD start, UWORD end ) +{ + while( start<=end ) + { + tFloatingFirstChar[start]&=~id; + start+=1; + } +} + +void lex_FloatAddFirstRange( ULONG id, UWORD start, UWORD end ) +{ + while( start<=end ) + { + tFloatingFirstChar[start]|=id; + start+=1; + } +} + +void lex_FloatDeleteSecondRange( ULONG id, UWORD start, UWORD end ) +{ + while( start<=end ) + { + tFloatingSecondChar[start]&=~id; + start+=1; + } +} + +void lex_FloatAddSecondRange( ULONG id, UWORD start, UWORD end ) +{ + while( start<=end ) + { + tFloatingSecondChar[start]|=id; + start+=1; + } +} + +struct sLexFloat *lexgetfloat( ULONG id ) +{ + ULONG r=0, + mask=1; + + if( id==0 ) + return( NULL ); + + while( (id&mask)==0 ) + { + mask<<=1; + r+=1; + } + + return( &tLexFloat[r] ); +} + +ULONG lexcalchash( char *s ) +{ + ULONG r=0; + + while( *s ) + { + r=((r<<1)+(toupper(*s)))%LEXHASHSIZE; + s+=1; + } + + return( r ); +} + +void lex_Init( void ) +{ + ULONG i; + + for( i=0; itzName ) + { + struct sLexString **ppHash; + ULONG hash; + + ppHash = &tLexHash[hash=lexcalchash (lex->tzName)]; + while (*ppHash) + ppHash = &((*ppHash)->pNext); + +// printf( "%s has hashvalue %d\n", lex->tzName, hash ); + + if( ((*ppHash)=(struct sLexString *)malloc(sizeof(struct sLexString)))!=NULL ) + { + if( ((*ppHash)->tzName=(char *)strdup(lex->tzName))!=NULL ) + { + (*ppHash)->nNameLength = strlen (lex->tzName); + (*ppHash)->nToken = lex->nToken; + (*ppHash)->pNext = NULL; + + strupr ((*ppHash)->tzName); + + if ((*ppHash)->nNameLength > nLexMaxLeng) + nLexMaxLeng = (*ppHash)->nNameLength; + + } + else + fatalerror ("Out of memory!"); + } + else + fatalerror ("Out of memory!"); + + lex += 1; + } +} + +ULONG yylex (void) +{ + ULONG hash, + maxlen; + char *s; + struct sLexString *pLongestFixed = NULL; + ULONG nFloatMask, + nOldFloatMask, + nFloatLen; + ULONG linestart = AtLineStart; + + switch( lexerstate ) + { + case LEX_STATE_NORMAL: + AtLineStart = 0; + + scanagain: + + while (*pLexBuffer == ' ' || *pLexBuffer == '\t') + { + linestart = 0; + pLexBuffer += 1; + } + + if (*pLexBuffer == 0) + { + if (yywrap () == 0) + { + linestart = AtLineStart; + AtLineStart = 0; + goto scanagain; + } + } + + s = pLexBuffer; + nOldFloatMask = nFloatLen = 0; + nFloatMask = tFloatingFirstChar[*s++]; + while (nFloatMask && nFloatLen < nLexBufferLeng) + { + nFloatLen += 1; + nOldFloatMask = nFloatMask; + if (nFloatLen == 1) + nFloatMask &= tFloatingSecondChar[*s++]; + else + nFloatMask &= tFloatingChars[*s++]; + } + + maxlen = nLexBufferLeng; + if (nLexMaxLeng < maxlen) + maxlen = nLexMaxLeng; + + yyleng = 0; + hash = 0; + s = pLexBuffer; + while (yyleng < nLexMaxLeng) + { + yyleng += 1; + hash = ((hash << 1) + (toupper (*s))) % LEXHASHSIZE; + s+=1; + if (tLexHash[hash]) + { + struct sLexString *lex; + + lex = tLexHash[hash]; + while (lex) + { + if (lex->nNameLength == yyleng) + { + if (strnicmp (pLexBuffer, lex->tzName, yyleng) == 0) + { + pLongestFixed = lex; + } + } + lex = lex->pNext; + } + } + + } + + if (nFloatLen == 0 && pLongestFixed == NULL) + { + if (*pLexBuffer == '"') + { + ULONG index = 0; + + pLexBuffer += 1; + while ((*pLexBuffer != '"') && (*pLexBuffer != '\n')) + { + char ch, + *marg; + + if ((ch = *pLexBuffer++) == '\\') + { + switch (ch = (*pLexBuffer++)) + { + case 'n': + ch = '\n'; + break; + case 't': + ch = '\t'; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if( (marg=sym_FindMacroArg(ch-'0'))!=NULL ) + { + while (*marg) + yylval.tzString[index++] = *marg++; + ch = 0; + } + break; + case '@': + if( (marg=sym_FindMacroArg(-1))!=NULL ) + { + while (*marg) + yylval.tzString[index++] = *marg++; + ch = 0; + } + break; + } + } + else if (ch == '{') + { + char sym[MAXSYMLEN]; + int i = 0; + + while ((*pLexBuffer != '}') && (*pLexBuffer != '"') && (*pLexBuffer != '\n')) + { + if ((ch = *pLexBuffer++) == '\\') + { + switch (ch = (*pLexBuffer++)) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if( (marg=sym_FindMacroArg(ch-'0'))!=NULL ) + { + while (*marg) + sym[i++] = *marg++; + ch = 0; + } + break; + case '@': + if( (marg=sym_FindMacroArg(-1))!=NULL ) + { + while (*marg) + sym[i++] = *marg++; + ch = 0; + } + break; + } + } + else + sym[i++] = ch; + } + + sym[i] = 0; + index += symvaluetostring (&yylval.tzString[index], sym); + if (*pLexBuffer == '}') + pLexBuffer += 1; + else + yyerror ("Missing }"); + ch = 0; + } + + if (ch) + yylval.tzString[index++] = ch; + } + + yylval.tzString[index++] = 0; + + if (*pLexBuffer == '\n') + yyerror ("Unterminated string"); + else + pLexBuffer += 1; + + return (T_STRING); + } + else if (*pLexBuffer == '{') + { + char sym[MAXSYMLEN], + ch, + *marg; + int i = 0; + + pLexBuffer += 1; + + while ((*pLexBuffer != '}') && (*pLexBuffer != '\n')) + { + if ((ch = *pLexBuffer++) == '\\') + { + switch (ch = (*pLexBuffer++)) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if( (marg=sym_FindMacroArg(ch-'0'))!=NULL ) + { + while (*marg) + sym[i++] = *marg++; + ch = 0; + } + break; + case '@': + if( (marg=sym_FindMacroArg(-1))!=NULL ) + { + while (*marg) + sym[i++] = *marg++; + ch = 0; + } + break; + } + } + else + sym[i++] = ch; + } + sym[i] = 0; + symvaluetostring (yylval.tzString, sym); + if (*pLexBuffer == '}') + pLexBuffer += 1; + else + yyerror ("Missing }"); + + return (T_STRING); + } + else + { + if (*pLexBuffer == '\n') + AtLineStart = 1; + + yyleng = 1; + return (*pLexBuffer++); + } + } + + if (nFloatLen == 0) + { + yyleng = pLongestFixed->nNameLength; + pLexBuffer += yyleng; + return (pLongestFixed->nToken); + } + + if (pLongestFixed == NULL) + { + struct sLexFloat *tok; + + tok = lexgetfloat (nOldFloatMask); + yyleng = nFloatLen; + if (tok->Callback) + { + if (tok->Callback (pLexBuffer, yyleng) == 0) + goto scanagain; + } + + if (tok->nToken == T_ID && linestart) + { + pLexBuffer += yyleng; + return (T_LABEL); + } + else + { + pLexBuffer += yyleng; + return (tok->nToken); + } + } + + if (nFloatLen > pLongestFixed->nNameLength) + { + struct sLexFloat *tok; + + tok = lexgetfloat (nOldFloatMask); + yyleng = nFloatLen; + if (tok->Callback) + { + if (tok->Callback (pLexBuffer, yyleng) == 0) + goto scanagain; + } + + if (tok->nToken == T_ID && linestart) + { + pLexBuffer += yyleng; + return (T_LABEL); + } + else + { + pLexBuffer += yyleng; + return (tok->nToken); + } + } + else + { + yyleng = pLongestFixed->nNameLength; + pLexBuffer += yyleng; + return (pLongestFixed->nToken); + } + break; + + case LEX_STATE_MACROARGS: + { + ULONG index = 0; + + while (*pLexBuffer == ' ' || *pLexBuffer == '\t') + { + linestart = 0; + pLexBuffer += 1; + } + + while( (*pLexBuffer != ',') + && (*pLexBuffer != '\n') ) + { + char ch, + *marg; + + if ((ch = *pLexBuffer++) == '\\') + { + switch (ch = (*pLexBuffer++)) + { + case 'n': + ch = '\n'; + break; + case 't': + ch = '\t'; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if( (marg=sym_FindMacroArg(ch-'0'))!=NULL ) + { + while (*marg) + yylval.tzString[index++] = *marg++; + ch = 0; + } + break; + case '@': + if( (marg=sym_FindMacroArg(-1))!=NULL ) + { + while (*marg) + yylval.tzString[index++] = *marg++; + ch = 0; + } + break; + } + } + else if (ch == '{') + { + char sym[MAXSYMLEN]; + int i = 0; + + while ((*pLexBuffer != '}') && (*pLexBuffer != '"') && (*pLexBuffer != '\n')) + { + if ((ch = *pLexBuffer++) == '\\') + { + switch (ch = (*pLexBuffer++)) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + if( (marg=sym_FindMacroArg(ch-'0'))!=NULL ) + { + while (*marg) + sym[i++] = *marg++; + ch = 0; + } + break; + case '@': + if( (marg=sym_FindMacroArg(-1))!=NULL ) + { + while (*marg) + sym[i++] = *marg++; + ch = 0; + } + break; + } + } + else + sym[i++] = ch; + } + sym[i] = 0; + index += symvaluetostring (&yylval.tzString[index], sym); + if (*pLexBuffer == '}') + pLexBuffer += 1; + else + yyerror ("Missing }"); + ch = 0; + } + + if (ch) + yylval.tzString[index++] = ch; + } + + if( index ) + { + yyleng=index; + yylval.tzString[index] = 0; + if( *pLexBuffer=='\n' ) + { + while( yylval.tzString[--index]==' ' ) + { + yylval.tzString[index]=0; + yyleng-=1; + } + } + return (T_STRING); + } + else if( *pLexBuffer=='\n' ) + { + pLexBuffer+=1; + AtLineStart = 1; + yyleng = 1; + return( '\n' ); + } + else if( *pLexBuffer==',' ) + { + pLexBuffer+=1; + yyleng = 1; + return( ',' ); + } + else + { + yyerror( "INTERNAL ERROR IN YYLEX" ); + return( 0 ); + } + } + + break; + } + + yyerror( "INTERNAL ERROR IN YYLEX" ); + return( 0 ); } \ No newline at end of file diff --git a/src/asm/main.c b/src/asm/main.c index 48ed7c4c..2d6ca108 100644 --- a/src/asm/main.c +++ b/src/asm/main.c @@ -1,406 +1,406 @@ -/* - * RGBAsm - MAIN.C - * - * INCLUDES - * - */ - -#include -#include -#include -#include -#include -#include "symbol.h" -#include "fstack.h" -#include "output.h" -#include "main.h" - -int yyparse (void); -void setuplex (void); - -#ifdef AMIGA -__near long __stack = 65536L; - -#endif - -/* - * RGBAsm - MAIN.C - * - * VARIABLES - * - */ - -clock_t nStartClock, - nEndClock; -SLONG nLineNo; -ULONG nTotalLines, - nPass, - nPC, - nIFDepth, - nErrors; - -extern int yydebug; - -char temptext[1024]; - -/* - * RGBAsm - MAIN.C - * - * Option stack - * - */ - -struct sOptions DefaultOptions; -struct sOptions CurrentOptions; - -struct sOptionStackEntry -{ - struct sOptions Options; - struct sOptionStackEntry *pNext; -}; - -struct sOptionStackEntry *pOptionStack=NULL; - -void opt_SetCurrentOptions( struct sOptions *pOpt ) -{ - if( nGBGfxID!=-1 ) - { - lex_FloatDeleteRange( nGBGfxID, CurrentOptions.gbgfx[0], CurrentOptions.gbgfx[0] ); - lex_FloatDeleteRange( nGBGfxID, CurrentOptions.gbgfx[1], CurrentOptions.gbgfx[1] ); - lex_FloatDeleteRange( nGBGfxID, CurrentOptions.gbgfx[2], CurrentOptions.gbgfx[2] ); - lex_FloatDeleteRange( nGBGfxID, CurrentOptions.gbgfx[3], CurrentOptions.gbgfx[3] ); - lex_FloatDeleteSecondRange( nGBGfxID, CurrentOptions.gbgfx[0], CurrentOptions.gbgfx[0] ); - lex_FloatDeleteSecondRange( nGBGfxID, CurrentOptions.gbgfx[1], CurrentOptions.gbgfx[1] ); - lex_FloatDeleteSecondRange( nGBGfxID, CurrentOptions.gbgfx[2], CurrentOptions.gbgfx[2] ); - lex_FloatDeleteSecondRange( nGBGfxID, CurrentOptions.gbgfx[3], CurrentOptions.gbgfx[3] ); - } - - if( nBinaryID!=-1 ) - { - lex_FloatDeleteRange( nBinaryID, CurrentOptions.binary[0], CurrentOptions.binary[0] ); - lex_FloatDeleteRange( nBinaryID, CurrentOptions.binary[1], CurrentOptions.binary[1] ); - lex_FloatDeleteSecondRange( nBinaryID, CurrentOptions.binary[0], CurrentOptions.binary[0] ); - lex_FloatDeleteSecondRange( nBinaryID, CurrentOptions.binary[1], CurrentOptions.binary[1] ); - } - - CurrentOptions = *pOpt; - - if( nGBGfxID!=-1 ) - { - lex_FloatAddRange( nGBGfxID, CurrentOptions.gbgfx[0], CurrentOptions.gbgfx[0] ); - lex_FloatAddRange( nGBGfxID, CurrentOptions.gbgfx[1], CurrentOptions.gbgfx[1] ); - lex_FloatAddRange( nGBGfxID, CurrentOptions.gbgfx[2], CurrentOptions.gbgfx[2] ); - lex_FloatAddRange( nGBGfxID, CurrentOptions.gbgfx[3], CurrentOptions.gbgfx[3] ); - lex_FloatAddSecondRange( nGBGfxID, CurrentOptions.gbgfx[0], CurrentOptions.gbgfx[0] ); - lex_FloatAddSecondRange( nGBGfxID, CurrentOptions.gbgfx[1], CurrentOptions.gbgfx[1] ); - lex_FloatAddSecondRange( nGBGfxID, CurrentOptions.gbgfx[2], CurrentOptions.gbgfx[2] ); - lex_FloatAddSecondRange( nGBGfxID, CurrentOptions.gbgfx[3], CurrentOptions.gbgfx[3] ); - } - - if( nBinaryID!=-1 ) - { - lex_FloatAddRange( nBinaryID, CurrentOptions.binary[0], CurrentOptions.binary[0] ); - lex_FloatAddRange( nBinaryID, CurrentOptions.binary[1], CurrentOptions.binary[1] ); - lex_FloatAddSecondRange( nBinaryID, CurrentOptions.binary[0], CurrentOptions.binary[0] ); - lex_FloatAddSecondRange( nBinaryID, CurrentOptions.binary[1], CurrentOptions.binary[1] ); - } - -} - -void opt_Parse( char *s ) -{ - struct sOptions newopt; - - newopt=CurrentOptions; - - switch( s[0] ) - { - case 'e': - switch( s[1] ) - { - case 'b': - newopt.endian=ASM_BIG_ENDIAN; - printf( "*WARNING*\t :\n\tEndianness forced to BIG for destination CPU\n" ); - break; - case 'l': - newopt.endian=ASM_LITTLE_ENDIAN; - printf( "*WARNING*\t :\n\tEndianness forced to LITTLE for destination CPU\n" ); - break; - default: - printf ("*ERROR*\t :\n\tArgument to option -e must be 'b' or 'l'\n" ); - exit (5); - } - break; - case 'g': - if( strlen(&s[1])==4 ) - { - newopt.gbgfx[0]=s[1]; - newopt.gbgfx[1]=s[2]; - newopt.gbgfx[2]=s[3]; - newopt.gbgfx[3]=s[4]; - } - else - { - printf ("*ERROR*\t :\n\tMust specify exactly 4 characters for option 'g'\n" ); - exit( 5 ); - } - break; - case 'b': - if( strlen(&s[1])==2 ) - { - newopt.binary[0]=s[1]; - newopt.binary[1]=s[2]; - } - else - { - printf ("*ERROR*\t :\n\tMust specify exactly 2 characters for option 'b'\n" ); - exit( 5 ); - } - break; - case 'z': - if( strlen(&s[1])<=2 ) - { - if( strcmp(&s[1],"?")==0 ) - { - newopt.fillchar=-1; - } - else - { - int result; - - result=sscanf( &s[1], "%lx", &newopt.fillchar ); - if( !((result==EOF) || (result==1)) ) - { - printf ("*ERROR*\t :\n\tInvalid argument for option 'z'\n" ); - exit( 5 ); - } - } - } - else - { - printf ("*ERROR*\t :\n\tInvalid argument for option 'z'\n" ); - exit( 5 ); - } - break; - default: - fatalerror( "Unknown option" ); - break; - } - - opt_SetCurrentOptions( &newopt ); -} - -void opt_Push( void ) -{ - struct sOptionStackEntry *pOpt; - - if( (pOpt=(struct sOptionStackEntry *)malloc(sizeof(struct sOptionStackEntry)))!=NULL ) - { - pOpt->Options=CurrentOptions; - pOpt->pNext=pOptionStack; - pOptionStack=pOpt; - } - else - fatalerror( "No memory for option stack" ); -} - -void opt_Pop( void ) -{ - if( pOptionStack ) - { - struct sOptionStackEntry *pOpt; - - pOpt=pOptionStack; - opt_SetCurrentOptions( &(pOpt->Options) ); - pOptionStack=pOpt->pNext; - free( pOpt ); - } - else - fatalerror( "No entries in the option stack" ); -} - -/* - * RGBAsm - MAIN.C - * - * Error handling - * - */ - -void yyerror (char *s) -{ - printf ("*ERROR*\t"); - fstk_Dump (); - printf (" :\n\t%s\n", s); - nErrors += 1; -} - -void fatalerror (char *s) -{ - yyerror (s); - exit (5); -} - -/* - * RGBAsm - MAIN.C - * - * Help text - * - */ - -void PrintUsage (void) -{ - printf (APPNAME " v" ASM_VERSION " (part of ASMotor " ASMOTOR_VERSION ")\n\nUsage: " EXENAME " [options] asmfile\n"); - printf ("Options:\n"); - printf ("\t-h\t\tThis text\n"); - printf ("\t-i\tExtra include path\n"); - printf ("\t-o\tWrite objectoutput to \n"); - printf ("\t-e(l|b)\t\tChange endianness (CAUTION!)\n"); - printf ("\t-g\tChange the four characters used for Gameboy graphics\n" - "\t\t\tconstants (default is 0123)\n" ); - printf ("\t-b\t\tChange the two characters used for binary constants\n" - "\t\t\t(default is 01)\n" ); - printf ("\t-z\t\tSet the byte value (hex format) used for uninitialised\n" - "\t\t\tdata (default is ? for random)\n" ); - exit (0); -} - -/* - * RGBAsm - MAIN.C - * - * main - * - */ - -int main (int argc, char *argv[]) -{ - char *tzMainfile; - int argn = 1; - - argc -= 1; - - if (argc == 0) - PrintUsage (); - - /* yydebug=1; */ - - DefaultOptions.endian=ASM_DEFAULT_ENDIAN; - DefaultOptions.gbgfx[0]='0'; - DefaultOptions.gbgfx[1]='1'; - DefaultOptions.gbgfx[2]='2'; - DefaultOptions.gbgfx[3]='3'; - DefaultOptions.binary[0]='0'; - DefaultOptions.binary[1]='1'; - DefaultOptions.fillchar=-1; // fill uninitialised data with random values - opt_SetCurrentOptions( &DefaultOptions ); - - while (argv[argn][0] == '-' && argc) - { - switch (argv[argn][1]) - { - case 'h': - PrintUsage (); - break; - case 'i': - fstk_AddIncludePath (&(argv[argn][2])); - break; - case 'o': - out_SetFileName (&(argv[argn][2])); - break; - case 'e': - case 'g': - case 'b': - case 'z': - opt_Parse( &argv[argn][1] ); - break; - default: - printf ("*ERROR*\t :\n\tUnknown option '%c'\n", argv[argn][1]); - exit (5); - break; - } - argn += 1; - argc -= 1; - } - - DefaultOptions=CurrentOptions; - - /*tzMainfile=argv[argn++]; - * argc-=1; */ - tzMainfile = argv[argn]; - - setuplex (); - - printf ("Assembling %s\n", tzMainfile); - - nStartClock = clock (); - - nLineNo = 1; - nTotalLines = 0; - nIFDepth = 0; - nPC = 0; - nPass = 1; - nErrors = 0; - sym_PrepPass1 (); - if (fstk_Init (tzMainfile)) - { - printf ("Pass 1...\n"); - - yy_set_state( LEX_STATE_NORMAL ); - opt_SetCurrentOptions( &DefaultOptions ); - - if (yyparse () == 0 && nErrors == 0) - { - if (nIFDepth == 0) - { - nTotalLines = 0; - nLineNo = 1; - nIFDepth = 0; - nPC = 0; - nPass = 2; - nErrors = 0; - sym_PrepPass2 (); - out_PrepPass2 (); - fstk_Init (tzMainfile); - yy_set_state( LEX_STATE_NORMAL ); - opt_SetCurrentOptions( &DefaultOptions ); - - printf ("Pass 2...\n"); - - if (yyparse () == 0 && nErrors == 0) - { - double timespent; - - nEndClock = clock (); - timespent = ((double) (nEndClock - nStartClock)) / (double) CLOCKS_PER_SEC; - printf ("Success! %ld lines in %d.%02d seconds ", nTotalLines, (int) timespent, ((int) (timespent * 100.0)) % 100); - if (timespent == 0) - printf ("(INFINITY lines/minute)\n"); - else - printf ("(%d lines/minute)\n", (int) (60 / timespent * nTotalLines)); - out_WriteObject (); - } - else - { - printf ("Assembly aborted in pass 2 (%ld errors)!\n", nErrors); - //sym_PrintSymbolTable(); - exit (5); - } - } - else - { - printf ("*ERROR*\t:\tUnterminated IF construct (%ld levels)!\n", nIFDepth); - exit (5); - } - } - else - { - printf ("Assembly aborted in pass 1 (%ld errors)!\n", nErrors); - exit (5); - } - } - else - { - printf ("File '%s' not found\n", tzMainfile); - exit (5); - } - return (0); +/* + * RGBAsm - MAIN.C + * + * INCLUDES + * + */ + +#include +#include +#include +#include +#include +#include "symbol.h" +#include "fstack.h" +#include "output.h" +#include "main.h" + +int yyparse (void); +void setuplex (void); + +#ifdef AMIGA +__near long __stack = 65536L; + +#endif + +/* + * RGBAsm - MAIN.C + * + * VARIABLES + * + */ + +clock_t nStartClock, + nEndClock; +SLONG nLineNo; +ULONG nTotalLines, + nPass, + nPC, + nIFDepth, + nErrors; + +extern int yydebug; + +char temptext[1024]; + +/* + * RGBAsm - MAIN.C + * + * Option stack + * + */ + +struct sOptions DefaultOptions; +struct sOptions CurrentOptions; + +struct sOptionStackEntry +{ + struct sOptions Options; + struct sOptionStackEntry *pNext; +}; + +struct sOptionStackEntry *pOptionStack=NULL; + +void opt_SetCurrentOptions( struct sOptions *pOpt ) +{ + if( nGBGfxID!=-1 ) + { + lex_FloatDeleteRange( nGBGfxID, CurrentOptions.gbgfx[0], CurrentOptions.gbgfx[0] ); + lex_FloatDeleteRange( nGBGfxID, CurrentOptions.gbgfx[1], CurrentOptions.gbgfx[1] ); + lex_FloatDeleteRange( nGBGfxID, CurrentOptions.gbgfx[2], CurrentOptions.gbgfx[2] ); + lex_FloatDeleteRange( nGBGfxID, CurrentOptions.gbgfx[3], CurrentOptions.gbgfx[3] ); + lex_FloatDeleteSecondRange( nGBGfxID, CurrentOptions.gbgfx[0], CurrentOptions.gbgfx[0] ); + lex_FloatDeleteSecondRange( nGBGfxID, CurrentOptions.gbgfx[1], CurrentOptions.gbgfx[1] ); + lex_FloatDeleteSecondRange( nGBGfxID, CurrentOptions.gbgfx[2], CurrentOptions.gbgfx[2] ); + lex_FloatDeleteSecondRange( nGBGfxID, CurrentOptions.gbgfx[3], CurrentOptions.gbgfx[3] ); + } + + if( nBinaryID!=-1 ) + { + lex_FloatDeleteRange( nBinaryID, CurrentOptions.binary[0], CurrentOptions.binary[0] ); + lex_FloatDeleteRange( nBinaryID, CurrentOptions.binary[1], CurrentOptions.binary[1] ); + lex_FloatDeleteSecondRange( nBinaryID, CurrentOptions.binary[0], CurrentOptions.binary[0] ); + lex_FloatDeleteSecondRange( nBinaryID, CurrentOptions.binary[1], CurrentOptions.binary[1] ); + } + + CurrentOptions = *pOpt; + + if( nGBGfxID!=-1 ) + { + lex_FloatAddRange( nGBGfxID, CurrentOptions.gbgfx[0], CurrentOptions.gbgfx[0] ); + lex_FloatAddRange( nGBGfxID, CurrentOptions.gbgfx[1], CurrentOptions.gbgfx[1] ); + lex_FloatAddRange( nGBGfxID, CurrentOptions.gbgfx[2], CurrentOptions.gbgfx[2] ); + lex_FloatAddRange( nGBGfxID, CurrentOptions.gbgfx[3], CurrentOptions.gbgfx[3] ); + lex_FloatAddSecondRange( nGBGfxID, CurrentOptions.gbgfx[0], CurrentOptions.gbgfx[0] ); + lex_FloatAddSecondRange( nGBGfxID, CurrentOptions.gbgfx[1], CurrentOptions.gbgfx[1] ); + lex_FloatAddSecondRange( nGBGfxID, CurrentOptions.gbgfx[2], CurrentOptions.gbgfx[2] ); + lex_FloatAddSecondRange( nGBGfxID, CurrentOptions.gbgfx[3], CurrentOptions.gbgfx[3] ); + } + + if( nBinaryID!=-1 ) + { + lex_FloatAddRange( nBinaryID, CurrentOptions.binary[0], CurrentOptions.binary[0] ); + lex_FloatAddRange( nBinaryID, CurrentOptions.binary[1], CurrentOptions.binary[1] ); + lex_FloatAddSecondRange( nBinaryID, CurrentOptions.binary[0], CurrentOptions.binary[0] ); + lex_FloatAddSecondRange( nBinaryID, CurrentOptions.binary[1], CurrentOptions.binary[1] ); + } + +} + +void opt_Parse( char *s ) +{ + struct sOptions newopt; + + newopt=CurrentOptions; + + switch( s[0] ) + { + case 'e': + switch( s[1] ) + { + case 'b': + newopt.endian=ASM_BIG_ENDIAN; + printf( "*WARNING*\t :\n\tEndianness forced to BIG for destination CPU\n" ); + break; + case 'l': + newopt.endian=ASM_LITTLE_ENDIAN; + printf( "*WARNING*\t :\n\tEndianness forced to LITTLE for destination CPU\n" ); + break; + default: + printf ("*ERROR*\t :\n\tArgument to option -e must be 'b' or 'l'\n" ); + exit (5); + } + break; + case 'g': + if( strlen(&s[1])==4 ) + { + newopt.gbgfx[0]=s[1]; + newopt.gbgfx[1]=s[2]; + newopt.gbgfx[2]=s[3]; + newopt.gbgfx[3]=s[4]; + } + else + { + printf ("*ERROR*\t :\n\tMust specify exactly 4 characters for option 'g'\n" ); + exit( 5 ); + } + break; + case 'b': + if( strlen(&s[1])==2 ) + { + newopt.binary[0]=s[1]; + newopt.binary[1]=s[2]; + } + else + { + printf ("*ERROR*\t :\n\tMust specify exactly 2 characters for option 'b'\n" ); + exit( 5 ); + } + break; + case 'z': + if( strlen(&s[1])<=2 ) + { + if( strcmp(&s[1],"?")==0 ) + { + newopt.fillchar=-1; + } + else + { + int result; + + result=sscanf( &s[1], "%lx", &newopt.fillchar ); + if( !((result==EOF) || (result==1)) ) + { + printf ("*ERROR*\t :\n\tInvalid argument for option 'z'\n" ); + exit( 5 ); + } + } + } + else + { + printf ("*ERROR*\t :\n\tInvalid argument for option 'z'\n" ); + exit( 5 ); + } + break; + default: + fatalerror( "Unknown option" ); + break; + } + + opt_SetCurrentOptions( &newopt ); +} + +void opt_Push( void ) +{ + struct sOptionStackEntry *pOpt; + + if( (pOpt=(struct sOptionStackEntry *)malloc(sizeof(struct sOptionStackEntry)))!=NULL ) + { + pOpt->Options=CurrentOptions; + pOpt->pNext=pOptionStack; + pOptionStack=pOpt; + } + else + fatalerror( "No memory for option stack" ); +} + +void opt_Pop( void ) +{ + if( pOptionStack ) + { + struct sOptionStackEntry *pOpt; + + pOpt=pOptionStack; + opt_SetCurrentOptions( &(pOpt->Options) ); + pOptionStack=pOpt->pNext; + free( pOpt ); + } + else + fatalerror( "No entries in the option stack" ); +} + +/* + * RGBAsm - MAIN.C + * + * Error handling + * + */ + +void yyerror (char *s) +{ + printf ("*ERROR*\t"); + fstk_Dump (); + printf (" :\n\t%s\n", s); + nErrors += 1; +} + +void fatalerror (char *s) +{ + yyerror (s); + exit (5); +} + +/* + * RGBAsm - MAIN.C + * + * Help text + * + */ + +void PrintUsage (void) +{ + printf (APPNAME " v" ASM_VERSION " (part of ASMotor " ASMOTOR_VERSION ")\n\nUsage: " EXENAME " [options] asmfile\n"); + printf ("Options:\n"); + printf ("\t-h\t\tThis text\n"); + printf ("\t-i\tExtra include path\n"); + printf ("\t-o\tWrite objectoutput to \n"); + printf ("\t-e(l|b)\t\tChange endianness (CAUTION!)\n"); + printf ("\t-g\tChange the four characters used for Gameboy graphics\n" + "\t\t\tconstants (default is 0123)\n" ); + printf ("\t-b\t\tChange the two characters used for binary constants\n" + "\t\t\t(default is 01)\n" ); + printf ("\t-z\t\tSet the byte value (hex format) used for uninitialised\n" + "\t\t\tdata (default is ? for random)\n" ); + exit (0); +} + +/* + * RGBAsm - MAIN.C + * + * main + * + */ + +int main (int argc, char *argv[]) +{ + char *tzMainfile; + int argn = 1; + + argc -= 1; + + if (argc == 0) + PrintUsage (); + + /* yydebug=1; */ + + DefaultOptions.endian=ASM_DEFAULT_ENDIAN; + DefaultOptions.gbgfx[0]='0'; + DefaultOptions.gbgfx[1]='1'; + DefaultOptions.gbgfx[2]='2'; + DefaultOptions.gbgfx[3]='3'; + DefaultOptions.binary[0]='0'; + DefaultOptions.binary[1]='1'; + DefaultOptions.fillchar=-1; // fill uninitialised data with random values + opt_SetCurrentOptions( &DefaultOptions ); + + while (argv[argn][0] == '-' && argc) + { + switch (argv[argn][1]) + { + case 'h': + PrintUsage (); + break; + case 'i': + fstk_AddIncludePath (&(argv[argn][2])); + break; + case 'o': + out_SetFileName (&(argv[argn][2])); + break; + case 'e': + case 'g': + case 'b': + case 'z': + opt_Parse( &argv[argn][1] ); + break; + default: + printf ("*ERROR*\t :\n\tUnknown option '%c'\n", argv[argn][1]); + exit (5); + break; + } + argn += 1; + argc -= 1; + } + + DefaultOptions=CurrentOptions; + + /*tzMainfile=argv[argn++]; + * argc-=1; */ + tzMainfile = argv[argn]; + + setuplex (); + + printf ("Assembling %s\n", tzMainfile); + + nStartClock = clock (); + + nLineNo = 1; + nTotalLines = 0; + nIFDepth = 0; + nPC = 0; + nPass = 1; + nErrors = 0; + sym_PrepPass1 (); + if (fstk_Init (tzMainfile)) + { + printf ("Pass 1...\n"); + + yy_set_state( LEX_STATE_NORMAL ); + opt_SetCurrentOptions( &DefaultOptions ); + + if (yyparse () == 0 && nErrors == 0) + { + if (nIFDepth == 0) + { + nTotalLines = 0; + nLineNo = 1; + nIFDepth = 0; + nPC = 0; + nPass = 2; + nErrors = 0; + sym_PrepPass2 (); + out_PrepPass2 (); + fstk_Init (tzMainfile); + yy_set_state( LEX_STATE_NORMAL ); + opt_SetCurrentOptions( &DefaultOptions ); + + printf ("Pass 2...\n"); + + if (yyparse () == 0 && nErrors == 0) + { + double timespent; + + nEndClock = clock (); + timespent = ((double) (nEndClock - nStartClock)) / (double) CLOCKS_PER_SEC; + printf ("Success! %ld lines in %d.%02d seconds ", nTotalLines, (int) timespent, ((int) (timespent * 100.0)) % 100); + if (timespent == 0) + printf ("(INFINITY lines/minute)\n"); + else + printf ("(%d lines/minute)\n", (int) (60 / timespent * nTotalLines)); + out_WriteObject (); + } + else + { + printf ("Assembly aborted in pass 2 (%ld errors)!\n", nErrors); + //sym_PrintSymbolTable(); + exit (5); + } + } + else + { + printf ("*ERROR*\t:\tUnterminated IF construct (%ld levels)!\n", nIFDepth); + exit (5); + } + } + else + { + printf ("Assembly aborted in pass 1 (%ld errors)!\n", nErrors); + exit (5); + } + } + else + { + printf ("File '%s' not found\n", tzMainfile); + exit (5); + } + return (0); } \ No newline at end of file diff --git a/src/asm/math.c b/src/asm/math.c index d2ce2f5c..6c4dc6ed 100644 --- a/src/asm/math.c +++ b/src/asm/math.c @@ -1,153 +1,153 @@ -/* - * RGBAsm - MATH.C (Fixedpoint math routines) - * - * INCLUDES - * - */ - -#include -#include -#include "types.h" -#include "mymath.h" -#include "symbol.h" - -#define fix2double(i) ((double)(i/65536.0)) -#define double2fix(d) ((SLONG)(d*65536.0)) -#ifndef PI -#define PI (acos(-1)) -#endif - -/* - * RGBAsm - MATH.C (Fixedpoint math routines) - * - * Define the _PI symbol - * - */ - -void math_DefinePI (void) -{ - sym_AddEqu ("_PI", double2fix (PI)); -} - -/* - * RGBAsm - MATH.C (Fixedpoint math routines) - * - * Print a fixed point value - * - */ - -void math_Print (SLONG i) -{ - if (i >= 0) - printf ("%ld.%05ld", i >> 16, ((SLONG) (fix2double (i) * 100000 + 0.5)) % 100000); - else - printf ("-%ld.%05ld", (-i) >> 16, ((SLONG) (fix2double (-i) * 100000 + 0.5)) % 100000); -} - -/* - * RGBAsm - MATH.C (Fixedpoint math routines) - * - * Calculate sine - * - */ - -SLONG math_Sin (SLONG i) -{ - return (double2fix (sin (fix2double (i) * 2 * PI / 65536))); -} - -/* - * RGBAsm - MATH.C (Fixedpoint math routines) - * - * Calculate cosine - * - */ - -SLONG math_Cos (SLONG i) -{ - return (double2fix (cos (fix2double (i) * 2 * PI / 65536))); -} - -/* - * RGBAsm - MATH.C (Fixedpoint math routines) - * - * Calculate tangent - * - */ - -SLONG math_Tan (SLONG i) -{ - return (double2fix (tan (fix2double (i) * 2 * PI / 65536))); -} - -/* - * RGBAsm - MATH.C (Fixedpoint math routines) - * - * Calculate sine^-1 - * - */ - -SLONG math_ASin (SLONG i) -{ - return (double2fix (asin (fix2double (i)) / 2 / PI * 65536)); -} - -/* - * RGBAsm - MATH.C (Fixedpoint math routines) - * - * Calculate cosine^-1 - * - */ - -SLONG math_ACos (SLONG i) -{ - return (double2fix (acos (fix2double (i)) / 2 / PI * 65536)); -} - -/* - * RGBAsm - MATH.C (Fixedpoint math routines) - * - * Calculate tangent^-1 - * - */ - -SLONG math_ATan (SLONG i) -{ - return (double2fix (atan (fix2double (i)) / 2 / PI * 65536)); -} - -/* - * RGBAsm - MATH.C (Fixedpoint math routines) - * - * Calculate atan2 - * - */ - -SLONG math_ATan2 (SLONG i, SLONG j) -{ - return (double2fix (atan2 (fix2double (i), fix2double (j)) / 2 / PI * 65536)); -} - -/* - * RGBAsm - MATH.C (Fixedpoint math routines) - * - * Multiplication - * - */ - -SLONG math_Mul (SLONG i, SLONG j) -{ - return (double2fix (fix2double (i) * fix2double (j))); -} - -/* - * RGBAsm - MATH.C (Fixedpoint math routines) - * - * Division - * - */ - -SLONG math_Div (SLONG i, SLONG j) -{ - return (double2fix (fix2double (i) / fix2double (j))); +/* + * RGBAsm - MATH.C (Fixedpoint math routines) + * + * INCLUDES + * + */ + +#include +#include +#include "types.h" +#include "mymath.h" +#include "symbol.h" + +#define fix2double(i) ((double)(i/65536.0)) +#define double2fix(d) ((SLONG)(d*65536.0)) +#ifndef PI +#define PI (acos(-1)) +#endif + +/* + * RGBAsm - MATH.C (Fixedpoint math routines) + * + * Define the _PI symbol + * + */ + +void math_DefinePI (void) +{ + sym_AddEqu ("_PI", double2fix (PI)); +} + +/* + * RGBAsm - MATH.C (Fixedpoint math routines) + * + * Print a fixed point value + * + */ + +void math_Print (SLONG i) +{ + if (i >= 0) + printf ("%ld.%05ld", i >> 16, ((SLONG) (fix2double (i) * 100000 + 0.5)) % 100000); + else + printf ("-%ld.%05ld", (-i) >> 16, ((SLONG) (fix2double (-i) * 100000 + 0.5)) % 100000); +} + +/* + * RGBAsm - MATH.C (Fixedpoint math routines) + * + * Calculate sine + * + */ + +SLONG math_Sin (SLONG i) +{ + return (double2fix (sin (fix2double (i) * 2 * PI / 65536))); +} + +/* + * RGBAsm - MATH.C (Fixedpoint math routines) + * + * Calculate cosine + * + */ + +SLONG math_Cos (SLONG i) +{ + return (double2fix (cos (fix2double (i) * 2 * PI / 65536))); +} + +/* + * RGBAsm - MATH.C (Fixedpoint math routines) + * + * Calculate tangent + * + */ + +SLONG math_Tan (SLONG i) +{ + return (double2fix (tan (fix2double (i) * 2 * PI / 65536))); +} + +/* + * RGBAsm - MATH.C (Fixedpoint math routines) + * + * Calculate sine^-1 + * + */ + +SLONG math_ASin (SLONG i) +{ + return (double2fix (asin (fix2double (i)) / 2 / PI * 65536)); +} + +/* + * RGBAsm - MATH.C (Fixedpoint math routines) + * + * Calculate cosine^-1 + * + */ + +SLONG math_ACos (SLONG i) +{ + return (double2fix (acos (fix2double (i)) / 2 / PI * 65536)); +} + +/* + * RGBAsm - MATH.C (Fixedpoint math routines) + * + * Calculate tangent^-1 + * + */ + +SLONG math_ATan (SLONG i) +{ + return (double2fix (atan (fix2double (i)) / 2 / PI * 65536)); +} + +/* + * RGBAsm - MATH.C (Fixedpoint math routines) + * + * Calculate atan2 + * + */ + +SLONG math_ATan2 (SLONG i, SLONG j) +{ + return (double2fix (atan2 (fix2double (i), fix2double (j)) / 2 / PI * 65536)); +} + +/* + * RGBAsm - MATH.C (Fixedpoint math routines) + * + * Multiplication + * + */ + +SLONG math_Mul (SLONG i, SLONG j) +{ + return (double2fix (fix2double (i) * fix2double (j))); +} + +/* + * RGBAsm - MATH.C (Fixedpoint math routines) + * + * Division + * + */ + +SLONG math_Div (SLONG i, SLONG j) +{ + return (double2fix (fix2double (i) / fix2double (j))); } \ No newline at end of file diff --git a/src/asm/output.c b/src/asm/output.c index f57657dc..7787246c 100644 --- a/src/asm/output.c +++ b/src/asm/output.c @@ -1,1027 +1,1027 @@ -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * INCLUDES - * - */ - -#include -#include -#include -#include "asm.h" -#include "output.h" -#include "symbol.h" -#include "mylink.h" -#include "main.h" -#include "rpn.h" -#include "fstack.h" - -#define SECTIONCHUNK 0x4000 - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Internal structures - * - */ - -void out_SetCurrentSection (struct Section *pSect); - -struct Patch -{ - char tzFilename[_MAX_PATH + 1]; - ULONG nLine; - ULONG nOffset; - UBYTE nType; - ULONG nRPNSize; - UBYTE *pRPN; - struct Patch *pNext; -}; - -struct PatchSymbol -{ - ULONG ID; - struct sSymbol *pSymbol; - struct PatchSymbol *pNext; -}; - -struct SectionStackEntry -{ - struct Section *pSection; - struct SectionStackEntry *pNext; -}; - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * VARIABLES - * - */ - -struct Section *pSectionList=NULL, - *pCurrentSection=NULL; -struct PatchSymbol *pPatchSymbols=NULL; -char tzObjectname[_MAX_PATH]; -struct SectionStackEntry *pSectionStack=NULL; - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Section stack routines - * - */ - -void out_PushSection( void ) -{ - struct SectionStackEntry *pSect; - - if( (pSect=(struct SectionStackEntry *)malloc(sizeof(struct SectionStackEntry)))!=NULL ) - { - pSect->pSection=pCurrentSection; - pSect->pNext=pSectionStack; - pSectionStack=pSect; - } - else - fatalerror( "No memory for section stack" ); -} - -void out_PopSection( void ) -{ - if( pSectionStack ) - { - struct SectionStackEntry *pSect; - - pSect=pSectionStack; - out_SetCurrentSection(pSect->pSection); - pSectionStack=pSect->pNext; - free( pSect ); - } - else - fatalerror( "No entries in the section stack" ); -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Count the number of symbols used in this object - * - */ - -ULONG countsymbols( void ) -{ - struct PatchSymbol *pSym; - ULONG count=0; - - pSym=pPatchSymbols; - - while( pSym ) - { - count+=1; - pSym=pSym->pNext; - } - - return (count); -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Count the number of sections used in this object - * - */ - -ULONG countsections( void ) -{ - struct Section *pSect; - ULONG count=0; - - pSect=pSectionList; - - while( pSect ) - { - count+=1; - pSect=pSect->pNext; - } - - return( count ); -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Count the number of patches used in this object - * - */ - -ULONG countpatches( struct Section *pSect ) -{ - struct Patch *pPatch; - ULONG r=0; - - pPatch=pSect->pPatches; - while( pPatch ) - { - r+=1; - pPatch=pPatch->pNext; - } - - return( r ); -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Write a long to a file (little-endian) - * - */ - -void fputlong( ULONG i, FILE * f ) -{ - fputc( i, f); - fputc( i>>8, f ); - fputc( i>>16, f ); - fputc( i>>24, f ); -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Write a NULL-terminated string to a file - * - */ - -void fputstring( char *s, FILE * f ) -{ - while( *s ) - fputc( *s++, f ); - fputc( 0, f ); -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Return a sections ID - * - */ - -ULONG getsectid( struct Section *pSect ) -{ - struct Section *sec; - ULONG ID = 0; - - sec=pSectionList; - - while( sec ) - { - if( sec==pSect) - return( ID ); - ID+=1; - sec=sec->pNext; - } - - fatalerror( "INTERNAL: Unknown section" ); - return( (ULONG)-1 ); -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Write a patch to a file - * - */ - -void writepatch( struct Patch *pPatch, FILE * f ) -{ - fputstring( pPatch->tzFilename, f ); - fputlong( pPatch->nLine, f ); - fputlong( pPatch->nOffset, f ); - fputc( pPatch->nType, f ); - fputlong( pPatch->nRPNSize, f ); - fwrite( pPatch->pRPN, 1, pPatch->nRPNSize, f ); -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Write a section to a file - * - */ - -void writesection( struct Section *pSect, FILE * f ) -{ - //printf( "SECTION: %s, ID: %d\n", pSect->pzName, getsectid(pSect) ); - - fputlong (pSect->nPC, f); - fputc (pSect->nType, f); - fputlong (pSect->nOrg, f); // RGB1 addition - - fputlong (pSect->nBank, f); // RGB1 addition - - if( (pSect->nType==SECT_HOME) - || (pSect->nType==SECT_CODE) ) - { - struct Patch *pPatch; - - fwrite (pSect->tData, 1, pSect->nPC, f); - fputlong (countpatches (pSect), f); - - pPatch = pSect->pPatches; - while (pPatch) - { - writepatch (pPatch, f); - pPatch = pPatch->pNext; - } - } -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Write a symbol to a file - * - */ - -void writesymbol (struct sSymbol *pSym, FILE * f) -{ - char symname[MAXSYMLEN * 2 + 1]; - ULONG type; - ULONG offset; - SLONG sectid; - - if (pSym->nType & SYMF_IMPORT) - { - /* Symbol should be imported */ - strcpy (symname, pSym->tzName); - offset=0; - sectid=-1; - type = SYM_IMPORT; - } - else if (pSym->nType & SYMF_EXPORT) - { - /* Symbol should be exported */ - strcpy (symname, pSym->tzName); - type = SYM_EXPORT; - offset = pSym->nValue; - if (pSym->nType & SYMF_CONST) - sectid = -1; - else - sectid = getsectid (pSym->pSection); - } - else - { - /* Symbol is local to this file */ - if (pSym->nType & SYMF_LOCAL) - { - strcpy (symname, pSym->pScope->tzName); - strcat (symname, pSym->tzName); - } - else - strcpy (symname, pSym->tzName); - type = SYM_LOCAL; - offset = pSym->nValue; - sectid = getsectid (pSym->pSection); - } - - fputstring (symname, f); - fputc (type, f); - - if (type != SYM_IMPORT) - { - fputlong (sectid, f); - fputlong (offset, f); - } -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Add a symbol to the object - * - */ - -ULONG addsymbol (struct sSymbol *pSym) -{ - struct PatchSymbol *pPSym, - **ppPSym; - ULONG ID = 0; - - pPSym = pPatchSymbols; - ppPSym = &(pPatchSymbols); - - while (pPSym) - { - if (pSym == pPSym->pSymbol) - return (pPSym->ID); - ppPSym = &(pPSym->pNext); - pPSym = pPSym->pNext; - ID += 1; - } - - if( (*ppPSym=pPSym=(struct PatchSymbol *)malloc(sizeof(struct PatchSymbol)))!=NULL ) - { - pPSym->pNext = NULL; - pPSym->pSymbol = pSym; - pPSym->ID = ID; - return (ID); - } - else - fatalerror ("No memory for patchsymbol"); - - return ((ULONG) -1); -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Add all exported symbols to the object - * - */ - -void addexports (void) -{ - int i; - - for (i = 0; i < HASHSIZE; i += 1) - { - struct sSymbol *pSym; - - pSym = tHashedSymbols[i]; - while (pSym) - { - if (pSym->nType & SYMF_EXPORT) - addsymbol (pSym); - pSym = pSym->pNext; - } - } -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Allocate a new patchstructure and link it into the list - * - */ - -struct Patch *allocpatch (void) -{ - struct Patch *pPatch, - **ppPatch; - - pPatch = pCurrentSection->pPatches; - ppPatch = &(pCurrentSection->pPatches); - - while (pPatch) - { - ppPatch = &(pPatch->pNext); - pPatch = pPatch->pNext; - } - - if( (*ppPatch=pPatch=(struct Patch *)malloc(sizeof (struct Patch)))!=NULL ) - { - pPatch->pNext = NULL; - pPatch->nRPNSize = 0; - pPatch->pRPN = NULL; - } - else - fatalerror ("No memory for patch"); - - return (pPatch); -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Create a new patch (includes the rpn expr) - * - */ - -void createpatch (ULONG type, struct Expression *expr) -{ - struct Patch *pPatch; - UWORD rpndata; - UBYTE rpnexpr[2048]; - char tzSym[512]; - ULONG rpnptr = 0, - symptr; - - pPatch = allocpatch (); - pPatch->nType = type; - strcpy (pPatch->tzFilename, tzCurrentFileName); - pPatch->nLine = nLineNo; - pPatch->nOffset = nPC; - - while ((rpndata = rpn_PopByte (expr)) != 0xDEAD) - { - switch (rpndata) - { - case RPN_CONST: - rpnexpr[rpnptr++] = RPN_CONST; - rpnexpr[rpnptr++] = rpn_PopByte (expr); - rpnexpr[rpnptr++] = rpn_PopByte (expr); - rpnexpr[rpnptr++] = rpn_PopByte (expr); - rpnexpr[rpnptr++] = rpn_PopByte (expr); - break; - case RPN_SYM: - symptr = 0; - while( (tzSym[symptr++]=rpn_PopByte(expr))!=0 ); - if (sym_isConstant (tzSym)) - { - ULONG value; - - value = sym_GetConstantValue (tzSym); - rpnexpr[rpnptr++] = RPN_CONST; - rpnexpr[rpnptr++] = value & 0xFF; - rpnexpr[rpnptr++] = value >> 8; - rpnexpr[rpnptr++] = value >> 16; - rpnexpr[rpnptr++] = value >> 24; - } - else - { - symptr = addsymbol (sym_FindSymbol (tzSym)); - rpnexpr[rpnptr++] = RPN_SYM; - rpnexpr[rpnptr++] = symptr & 0xFF; - rpnexpr[rpnptr++] = symptr >> 8; - rpnexpr[rpnptr++] = symptr >> 16; - rpnexpr[rpnptr++] = symptr >> 24; - } - break; - case RPN_BANK: - symptr = 0; - while( (tzSym[symptr++]=rpn_PopByte(expr))!=0 ); - symptr = addsymbol (sym_FindSymbol (tzSym)); - rpnexpr[rpnptr++] = RPN_BANK; - rpnexpr[rpnptr++] = symptr & 0xFF; - rpnexpr[rpnptr++] = symptr >> 8; - rpnexpr[rpnptr++] = symptr >> 16; - rpnexpr[rpnptr++] = symptr >> 24; - break; - default: - rpnexpr[rpnptr++] = rpndata; - break; - } - } - if( (pPatch->pRPN=(UBYTE *)malloc(rpnptr))!=NULL ) - { - memcpy (pPatch->pRPN, rpnexpr, rpnptr); - pPatch->nRPNSize = rpnptr; - } -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * A quick check to see if we have an initialized section - * - */ - -void checksection (void) -{ - if (pCurrentSection) - return; - else - fatalerror ("Code generation before SECTION directive"); -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * A quick check to see if we have an initialized section that can contain - * this much initialized data - * - */ - -void checkcodesection (SLONG size) -{ - checksection (); - if ((pCurrentSection->nType == SECT_HOME || pCurrentSection->nType == SECT_CODE) - && (pCurrentSection->nPC + size <= MAXSECTIONSIZE)) - { - if( ((pCurrentSection->nPC%SECTIONCHUNK)>((pCurrentSection->nPC+size)%SECTIONCHUNK)) - && (pCurrentSection->nType == SECT_HOME || pCurrentSection->nType == SECT_CODE) ) - { - if( (pCurrentSection->tData= - (UBYTE *)realloc( pCurrentSection->tData, - ((pCurrentSection->nPC+size)/SECTIONCHUNK+1)*SECTIONCHUNK))!=NULL ) - { - return; - } - else - fatalerror( "Not enough memory to expand section" ); - } - return; - } - else - fatalerror ("Section can't contain initialized data or section limit exceeded"); -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Write an objectfile - * - */ - -void out_WriteObject (void) -{ - FILE *f; - - addexports (); - - if( (f=fopen(tzObjectname,"wb"))!=NULL ) - { - struct PatchSymbol *pSym; - struct Section *pSect; - - fwrite ("RGB2", 1, 4, f); - fputlong (countsymbols (), f); - fputlong (countsections (), f); - - pSym = pPatchSymbols; - while (pSym) - { - writesymbol (pSym->pSymbol, f); - pSym = pSym->pNext; - } - - pSect = pSectionList; - while (pSect) - { - writesection (pSect, f); - pSect = pSect->pNext; - } - - fclose (f); - } -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Prepare for pass #2 - * - */ - -void out_PrepPass2 (void) -{ - struct Section *pSect; - - pSect = pSectionList; - while (pSect) - { - pSect->nPC = 0; - pSect = pSect->pNext; - } - pCurrentSection = NULL; - pSectionStack = NULL; -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Set the objectfilename - * - */ - -void out_SetFileName (char *s) -{ - strcpy (tzObjectname, s); - printf ("Output filename %s\n", s); - pSectionList = NULL; - pCurrentSection = NULL; - pPatchSymbols = NULL; -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Find a section by name and type. If it doesn't exist, create it - * - */ - -struct Section *out_FindSection (char *pzName, ULONG secttype, SLONG org, SLONG bank) -{ - struct Section *pSect, - **ppSect; - - ppSect = &pSectionList; - pSect = pSectionList; - - while (pSect) - { - if (strcmp (pzName, pSect->pzName) == 0) - { - if( secttype==pSect->nType && ((ULONG)org)==pSect->nOrg && ((ULONG)bank)==pSect->nBank) - { - return (pSect); - } - else - fatalerror ("Section already exists but with a different type"); - } - ppSect = &(pSect->pNext); - pSect = pSect->pNext; - } - - if( (*ppSect=(pSect=(struct Section *)malloc(sizeof(struct Section))))!=NULL ) - { - if( (pSect->pzName=(char *)malloc(strlen(pzName)+1))!=NULL ) - { - strcpy (pSect->pzName, pzName); - pSect->nType = secttype; - pSect->nPC = 0; - pSect->nOrg = org; - pSect->nBank = bank; - pSect->pNext = NULL; - pSect->pPatches = NULL; - pPatchSymbols = NULL; - - if( (pSect->tData=(UBYTE *)malloc(SECTIONCHUNK))!=NULL ) - { - return (pSect); - } - else - fatalerror ("Not enough memory for section"); - } - else - fatalerror ("Not enough memory for sectionname"); - } - else - fatalerror ("Not enough memory for section"); - - return (NULL); -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Set the current section - * - */ - -void out_SetCurrentSection (struct Section *pSect) -{ - pCurrentSection = pSect; - nPC = pSect->nPC; - - pPCSymbol->nValue = nPC; - pPCSymbol->pSection = pCurrentSection; -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Set the current section by name and type - * - */ - -void out_NewSection (char *pzName, ULONG secttype) -{ - out_SetCurrentSection (out_FindSection (pzName, secttype, -1, -1)); -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Set the current section by name and type - * - */ - -void out_NewAbsSection (char *pzName, ULONG secttype, SLONG org, SLONG bank) -{ - out_SetCurrentSection (out_FindSection (pzName, secttype, org, bank)); -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Output an absolute byte - * - */ - -void out_AbsByte (int b) -{ - checkcodesection (1); - b &= 0xFF; - if (nPass == 2) - pCurrentSection->tData[nPC] = b; - - pCurrentSection->nPC += 1; - nPC += 1; - pPCSymbol->nValue += 1; -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Skip this many bytes - * - */ - -void out_Skip (int skip) -{ - checksection (); - if( (CurrentOptions.fillchar==-1) - || !((pCurrentSection->nType == SECT_HOME) || (pCurrentSection->nType == SECT_CODE)) ) - { - pCurrentSection->nPC += skip; - nPC += skip; - pPCSymbol->nValue += skip; - } - else - { - checkcodesection( skip ); - while( skip-- ) - out_AbsByte( CurrentOptions.fillchar ); - } -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Output a NULL terminated string (excluding the NULL-character) - * - */ - -void out_String (char *s) -{ - checkcodesection (strlen (s)); - while (*s) - out_AbsByte (*s++); -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Output a relocatable byte. Checking will be done to see if it - * is an absolute value in disguise. - * - */ - -void out_RelByte (struct Expression *expr) -{ - checkcodesection (1); - if (rpn_isReloc (expr)) - { - if (nPass == 2) - { - pCurrentSection->tData[nPC] = 0; - createpatch (PATCH_BYTE, expr); - } - pCurrentSection->nPC += 1; - nPC += 1; - pPCSymbol->nValue += 1; - } - else - out_AbsByte (expr->nVal); - - rpn_Reset (expr); -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Output an absolute word - * - */ - -void out_AbsWord (int b) -{ - checkcodesection (2); - b &= 0xFFFF; - if (nPass == 2) - { - if( CurrentOptions.endian==ASM_LITTLE_ENDIAN ) - { - pCurrentSection->tData[nPC] = b & 0xFF; - pCurrentSection->tData[nPC + 1] = b >> 8; - } - else - { - // Assume big endian - pCurrentSection->tData[nPC] = b >> 8; - pCurrentSection->tData[nPC+1] = b & 0xFF; - } - } - pCurrentSection->nPC += 2; - nPC += 2; - pPCSymbol->nValue += 2; -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Output a relocatable word. Checking will be done to see if - * is an absolute value in disguise. - * - */ - -void out_RelWord (struct Expression *expr) -{ - ULONG b; - - checkcodesection (2); - b = expr->nVal&0xFFFF; - if (rpn_isReloc (expr)) - { - if (nPass == 2) - { - if( CurrentOptions.endian==ASM_LITTLE_ENDIAN ) - { - pCurrentSection->tData[nPC] = b & 0xFF; - pCurrentSection->tData[nPC + 1] = b >> 8; - createpatch (PATCH_WORD_L,expr); - } - else - { - // Assume big endian - pCurrentSection->tData[nPC] = b >> 8; - pCurrentSection->tData[nPC+1] = b & 0xFF; - createpatch (PATCH_WORD_B,expr); - } - } - pCurrentSection->nPC += 2; - nPC += 2; - pPCSymbol->nValue += 2; - } - else - out_AbsWord (expr->nVal); - rpn_Reset (expr); -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Output an absolute longword - * - */ - -void out_AbsLong (SLONG b) -{ - checkcodesection (sizeof(SLONG)); - if (nPass == 2) - { - if( CurrentOptions.endian==ASM_LITTLE_ENDIAN ) - { - pCurrentSection->tData[nPC] = b & 0xFF; - pCurrentSection->tData[nPC + 1] = b >> 8; - pCurrentSection->tData[nPC + 2] = b >> 16; - pCurrentSection->tData[nPC + 3] = b >> 24; - } - else - { - // Assume big endian - pCurrentSection->tData[nPC] = b >> 24; - pCurrentSection->tData[nPC+1] = b >> 16; - pCurrentSection->tData[nPC+2] = b >> 8; - pCurrentSection->tData[nPC+3] = b & 0xFF; - } - } - pCurrentSection->nPC += 4; - nPC += 4; - pPCSymbol->nValue += 4; -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Output a relocatable longword. Checking will be done to see if - * is an absolute value in disguise. - * - */ - -void out_RelLong (struct Expression *expr) -{ - SLONG b; - - checkcodesection (4); - b=expr->nVal; - if (rpn_isReloc (expr)) - { - if (nPass == 2) - { - if( CurrentOptions.endian==ASM_LITTLE_ENDIAN ) - { - pCurrentSection->tData[nPC] = b & 0xFF; - pCurrentSection->tData[nPC + 1] = b >> 8; - pCurrentSection->tData[nPC + 2] = b >> 16; - pCurrentSection->tData[nPC + 3] = b >> 24; - createpatch (PATCH_LONG_L,expr); - } - else - { - // Assume big endian - pCurrentSection->tData[nPC] = b >> 24; - pCurrentSection->tData[nPC+1] = b >> 16; - pCurrentSection->tData[nPC+2] = b >> 8; - pCurrentSection->tData[nPC+3] = b & 0xFF; - createpatch (PATCH_LONG_B,expr); - } - } - pCurrentSection->nPC += 4; - nPC += 4; - pPCSymbol->nValue += 4; - } - else - out_AbsLong (expr->nVal); - rpn_Reset (expr); -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Output a PC-relative byte - * - */ - -void out_PCRelByte (struct Expression *expr) -{ - SLONG b=expr->nVal; - - checkcodesection (1); - b = (b & 0xFFFF) - (nPC + 1); - if (nPass == 2 && (b < -128 || b > 127)) - yyerror ("PC-relative value must be 8-bit"); - - out_AbsByte (b); - rpn_Reset (expr); -} - -/* - * RGBAsm - OUTPUT.C - Outputs an objectfile - * - * Output a binary file - * - */ - -void out_BinaryFile (char *s) -{ - FILE *f; - - fstk_FindFile (s); - - if( (f=fopen(s,"rb"))!=NULL ) - { - SLONG fsize; - - fseek (f, 0, SEEK_END); - fsize = ftell (f); - fseek (f, 0, SEEK_SET); - - checkcodesection (fsize); - - if (nPass == 2) - { - SLONG dest = nPC; - SLONG todo = fsize; - - while (todo--) - pCurrentSection->tData[dest++] = fgetc (f); - } - - pCurrentSection->nPC += fsize; - nPC += fsize; - pPCSymbol->nValue += fsize; - fclose (f); - } - else - fatalerror ("File not found"); +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * INCLUDES + * + */ + +#include +#include +#include +#include "asm.h" +#include "output.h" +#include "symbol.h" +#include "mylink.h" +#include "main.h" +#include "rpn.h" +#include "fstack.h" + +#define SECTIONCHUNK 0x4000 + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Internal structures + * + */ + +void out_SetCurrentSection (struct Section *pSect); + +struct Patch +{ + char tzFilename[_MAX_PATH + 1]; + ULONG nLine; + ULONG nOffset; + UBYTE nType; + ULONG nRPNSize; + UBYTE *pRPN; + struct Patch *pNext; +}; + +struct PatchSymbol +{ + ULONG ID; + struct sSymbol *pSymbol; + struct PatchSymbol *pNext; +}; + +struct SectionStackEntry +{ + struct Section *pSection; + struct SectionStackEntry *pNext; +}; + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * VARIABLES + * + */ + +struct Section *pSectionList=NULL, + *pCurrentSection=NULL; +struct PatchSymbol *pPatchSymbols=NULL; +char tzObjectname[_MAX_PATH]; +struct SectionStackEntry *pSectionStack=NULL; + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Section stack routines + * + */ + +void out_PushSection( void ) +{ + struct SectionStackEntry *pSect; + + if( (pSect=(struct SectionStackEntry *)malloc(sizeof(struct SectionStackEntry)))!=NULL ) + { + pSect->pSection=pCurrentSection; + pSect->pNext=pSectionStack; + pSectionStack=pSect; + } + else + fatalerror( "No memory for section stack" ); +} + +void out_PopSection( void ) +{ + if( pSectionStack ) + { + struct SectionStackEntry *pSect; + + pSect=pSectionStack; + out_SetCurrentSection(pSect->pSection); + pSectionStack=pSect->pNext; + free( pSect ); + } + else + fatalerror( "No entries in the section stack" ); +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Count the number of symbols used in this object + * + */ + +ULONG countsymbols( void ) +{ + struct PatchSymbol *pSym; + ULONG count=0; + + pSym=pPatchSymbols; + + while( pSym ) + { + count+=1; + pSym=pSym->pNext; + } + + return (count); +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Count the number of sections used in this object + * + */ + +ULONG countsections( void ) +{ + struct Section *pSect; + ULONG count=0; + + pSect=pSectionList; + + while( pSect ) + { + count+=1; + pSect=pSect->pNext; + } + + return( count ); +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Count the number of patches used in this object + * + */ + +ULONG countpatches( struct Section *pSect ) +{ + struct Patch *pPatch; + ULONG r=0; + + pPatch=pSect->pPatches; + while( pPatch ) + { + r+=1; + pPatch=pPatch->pNext; + } + + return( r ); +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Write a long to a file (little-endian) + * + */ + +void fputlong( ULONG i, FILE * f ) +{ + fputc( i, f); + fputc( i>>8, f ); + fputc( i>>16, f ); + fputc( i>>24, f ); +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Write a NULL-terminated string to a file + * + */ + +void fputstring( char *s, FILE * f ) +{ + while( *s ) + fputc( *s++, f ); + fputc( 0, f ); +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Return a sections ID + * + */ + +ULONG getsectid( struct Section *pSect ) +{ + struct Section *sec; + ULONG ID = 0; + + sec=pSectionList; + + while( sec ) + { + if( sec==pSect) + return( ID ); + ID+=1; + sec=sec->pNext; + } + + fatalerror( "INTERNAL: Unknown section" ); + return( (ULONG)-1 ); +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Write a patch to a file + * + */ + +void writepatch( struct Patch *pPatch, FILE * f ) +{ + fputstring( pPatch->tzFilename, f ); + fputlong( pPatch->nLine, f ); + fputlong( pPatch->nOffset, f ); + fputc( pPatch->nType, f ); + fputlong( pPatch->nRPNSize, f ); + fwrite( pPatch->pRPN, 1, pPatch->nRPNSize, f ); +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Write a section to a file + * + */ + +void writesection( struct Section *pSect, FILE * f ) +{ + //printf( "SECTION: %s, ID: %d\n", pSect->pzName, getsectid(pSect) ); + + fputlong (pSect->nPC, f); + fputc (pSect->nType, f); + fputlong (pSect->nOrg, f); // RGB1 addition + + fputlong (pSect->nBank, f); // RGB1 addition + + if( (pSect->nType==SECT_HOME) + || (pSect->nType==SECT_CODE) ) + { + struct Patch *pPatch; + + fwrite (pSect->tData, 1, pSect->nPC, f); + fputlong (countpatches (pSect), f); + + pPatch = pSect->pPatches; + while (pPatch) + { + writepatch (pPatch, f); + pPatch = pPatch->pNext; + } + } +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Write a symbol to a file + * + */ + +void writesymbol (struct sSymbol *pSym, FILE * f) +{ + char symname[MAXSYMLEN * 2 + 1]; + ULONG type; + ULONG offset; + SLONG sectid; + + if (pSym->nType & SYMF_IMPORT) + { + /* Symbol should be imported */ + strcpy (symname, pSym->tzName); + offset=0; + sectid=-1; + type = SYM_IMPORT; + } + else if (pSym->nType & SYMF_EXPORT) + { + /* Symbol should be exported */ + strcpy (symname, pSym->tzName); + type = SYM_EXPORT; + offset = pSym->nValue; + if (pSym->nType & SYMF_CONST) + sectid = -1; + else + sectid = getsectid (pSym->pSection); + } + else + { + /* Symbol is local to this file */ + if (pSym->nType & SYMF_LOCAL) + { + strcpy (symname, pSym->pScope->tzName); + strcat (symname, pSym->tzName); + } + else + strcpy (symname, pSym->tzName); + type = SYM_LOCAL; + offset = pSym->nValue; + sectid = getsectid (pSym->pSection); + } + + fputstring (symname, f); + fputc (type, f); + + if (type != SYM_IMPORT) + { + fputlong (sectid, f); + fputlong (offset, f); + } +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Add a symbol to the object + * + */ + +ULONG addsymbol (struct sSymbol *pSym) +{ + struct PatchSymbol *pPSym, + **ppPSym; + ULONG ID = 0; + + pPSym = pPatchSymbols; + ppPSym = &(pPatchSymbols); + + while (pPSym) + { + if (pSym == pPSym->pSymbol) + return (pPSym->ID); + ppPSym = &(pPSym->pNext); + pPSym = pPSym->pNext; + ID += 1; + } + + if( (*ppPSym=pPSym=(struct PatchSymbol *)malloc(sizeof(struct PatchSymbol)))!=NULL ) + { + pPSym->pNext = NULL; + pPSym->pSymbol = pSym; + pPSym->ID = ID; + return (ID); + } + else + fatalerror ("No memory for patchsymbol"); + + return ((ULONG) -1); +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Add all exported symbols to the object + * + */ + +void addexports (void) +{ + int i; + + for (i = 0; i < HASHSIZE; i += 1) + { + struct sSymbol *pSym; + + pSym = tHashedSymbols[i]; + while (pSym) + { + if (pSym->nType & SYMF_EXPORT) + addsymbol (pSym); + pSym = pSym->pNext; + } + } +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Allocate a new patchstructure and link it into the list + * + */ + +struct Patch *allocpatch (void) +{ + struct Patch *pPatch, + **ppPatch; + + pPatch = pCurrentSection->pPatches; + ppPatch = &(pCurrentSection->pPatches); + + while (pPatch) + { + ppPatch = &(pPatch->pNext); + pPatch = pPatch->pNext; + } + + if( (*ppPatch=pPatch=(struct Patch *)malloc(sizeof (struct Patch)))!=NULL ) + { + pPatch->pNext = NULL; + pPatch->nRPNSize = 0; + pPatch->pRPN = NULL; + } + else + fatalerror ("No memory for patch"); + + return (pPatch); +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Create a new patch (includes the rpn expr) + * + */ + +void createpatch (ULONG type, struct Expression *expr) +{ + struct Patch *pPatch; + UWORD rpndata; + UBYTE rpnexpr[2048]; + char tzSym[512]; + ULONG rpnptr = 0, + symptr; + + pPatch = allocpatch (); + pPatch->nType = type; + strcpy (pPatch->tzFilename, tzCurrentFileName); + pPatch->nLine = nLineNo; + pPatch->nOffset = nPC; + + while ((rpndata = rpn_PopByte (expr)) != 0xDEAD) + { + switch (rpndata) + { + case RPN_CONST: + rpnexpr[rpnptr++] = RPN_CONST; + rpnexpr[rpnptr++] = rpn_PopByte (expr); + rpnexpr[rpnptr++] = rpn_PopByte (expr); + rpnexpr[rpnptr++] = rpn_PopByte (expr); + rpnexpr[rpnptr++] = rpn_PopByte (expr); + break; + case RPN_SYM: + symptr = 0; + while( (tzSym[symptr++]=rpn_PopByte(expr))!=0 ); + if (sym_isConstant (tzSym)) + { + ULONG value; + + value = sym_GetConstantValue (tzSym); + rpnexpr[rpnptr++] = RPN_CONST; + rpnexpr[rpnptr++] = value & 0xFF; + rpnexpr[rpnptr++] = value >> 8; + rpnexpr[rpnptr++] = value >> 16; + rpnexpr[rpnptr++] = value >> 24; + } + else + { + symptr = addsymbol (sym_FindSymbol (tzSym)); + rpnexpr[rpnptr++] = RPN_SYM; + rpnexpr[rpnptr++] = symptr & 0xFF; + rpnexpr[rpnptr++] = symptr >> 8; + rpnexpr[rpnptr++] = symptr >> 16; + rpnexpr[rpnptr++] = symptr >> 24; + } + break; + case RPN_BANK: + symptr = 0; + while( (tzSym[symptr++]=rpn_PopByte(expr))!=0 ); + symptr = addsymbol (sym_FindSymbol (tzSym)); + rpnexpr[rpnptr++] = RPN_BANK; + rpnexpr[rpnptr++] = symptr & 0xFF; + rpnexpr[rpnptr++] = symptr >> 8; + rpnexpr[rpnptr++] = symptr >> 16; + rpnexpr[rpnptr++] = symptr >> 24; + break; + default: + rpnexpr[rpnptr++] = rpndata; + break; + } + } + if( (pPatch->pRPN=(UBYTE *)malloc(rpnptr))!=NULL ) + { + memcpy (pPatch->pRPN, rpnexpr, rpnptr); + pPatch->nRPNSize = rpnptr; + } +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * A quick check to see if we have an initialized section + * + */ + +void checksection (void) +{ + if (pCurrentSection) + return; + else + fatalerror ("Code generation before SECTION directive"); +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * A quick check to see if we have an initialized section that can contain + * this much initialized data + * + */ + +void checkcodesection (SLONG size) +{ + checksection (); + if ((pCurrentSection->nType == SECT_HOME || pCurrentSection->nType == SECT_CODE) + && (pCurrentSection->nPC + size <= MAXSECTIONSIZE)) + { + if( ((pCurrentSection->nPC%SECTIONCHUNK)>((pCurrentSection->nPC+size)%SECTIONCHUNK)) + && (pCurrentSection->nType == SECT_HOME || pCurrentSection->nType == SECT_CODE) ) + { + if( (pCurrentSection->tData= + (UBYTE *)realloc( pCurrentSection->tData, + ((pCurrentSection->nPC+size)/SECTIONCHUNK+1)*SECTIONCHUNK))!=NULL ) + { + return; + } + else + fatalerror( "Not enough memory to expand section" ); + } + return; + } + else + fatalerror ("Section can't contain initialized data or section limit exceeded"); +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Write an objectfile + * + */ + +void out_WriteObject (void) +{ + FILE *f; + + addexports (); + + if( (f=fopen(tzObjectname,"wb"))!=NULL ) + { + struct PatchSymbol *pSym; + struct Section *pSect; + + fwrite ("RGB2", 1, 4, f); + fputlong (countsymbols (), f); + fputlong (countsections (), f); + + pSym = pPatchSymbols; + while (pSym) + { + writesymbol (pSym->pSymbol, f); + pSym = pSym->pNext; + } + + pSect = pSectionList; + while (pSect) + { + writesection (pSect, f); + pSect = pSect->pNext; + } + + fclose (f); + } +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Prepare for pass #2 + * + */ + +void out_PrepPass2 (void) +{ + struct Section *pSect; + + pSect = pSectionList; + while (pSect) + { + pSect->nPC = 0; + pSect = pSect->pNext; + } + pCurrentSection = NULL; + pSectionStack = NULL; +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Set the objectfilename + * + */ + +void out_SetFileName (char *s) +{ + strcpy (tzObjectname, s); + printf ("Output filename %s\n", s); + pSectionList = NULL; + pCurrentSection = NULL; + pPatchSymbols = NULL; +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Find a section by name and type. If it doesn't exist, create it + * + */ + +struct Section *out_FindSection (char *pzName, ULONG secttype, SLONG org, SLONG bank) +{ + struct Section *pSect, + **ppSect; + + ppSect = &pSectionList; + pSect = pSectionList; + + while (pSect) + { + if (strcmp (pzName, pSect->pzName) == 0) + { + if( secttype==pSect->nType && ((ULONG)org)==pSect->nOrg && ((ULONG)bank)==pSect->nBank) + { + return (pSect); + } + else + fatalerror ("Section already exists but with a different type"); + } + ppSect = &(pSect->pNext); + pSect = pSect->pNext; + } + + if( (*ppSect=(pSect=(struct Section *)malloc(sizeof(struct Section))))!=NULL ) + { + if( (pSect->pzName=(char *)malloc(strlen(pzName)+1))!=NULL ) + { + strcpy (pSect->pzName, pzName); + pSect->nType = secttype; + pSect->nPC = 0; + pSect->nOrg = org; + pSect->nBank = bank; + pSect->pNext = NULL; + pSect->pPatches = NULL; + pPatchSymbols = NULL; + + if( (pSect->tData=(UBYTE *)malloc(SECTIONCHUNK))!=NULL ) + { + return (pSect); + } + else + fatalerror ("Not enough memory for section"); + } + else + fatalerror ("Not enough memory for sectionname"); + } + else + fatalerror ("Not enough memory for section"); + + return (NULL); +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Set the current section + * + */ + +void out_SetCurrentSection (struct Section *pSect) +{ + pCurrentSection = pSect; + nPC = pSect->nPC; + + pPCSymbol->nValue = nPC; + pPCSymbol->pSection = pCurrentSection; +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Set the current section by name and type + * + */ + +void out_NewSection (char *pzName, ULONG secttype) +{ + out_SetCurrentSection (out_FindSection (pzName, secttype, -1, -1)); +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Set the current section by name and type + * + */ + +void out_NewAbsSection (char *pzName, ULONG secttype, SLONG org, SLONG bank) +{ + out_SetCurrentSection (out_FindSection (pzName, secttype, org, bank)); +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Output an absolute byte + * + */ + +void out_AbsByte (int b) +{ + checkcodesection (1); + b &= 0xFF; + if (nPass == 2) + pCurrentSection->tData[nPC] = b; + + pCurrentSection->nPC += 1; + nPC += 1; + pPCSymbol->nValue += 1; +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Skip this many bytes + * + */ + +void out_Skip (int skip) +{ + checksection (); + if( (CurrentOptions.fillchar==-1) + || !((pCurrentSection->nType == SECT_HOME) || (pCurrentSection->nType == SECT_CODE)) ) + { + pCurrentSection->nPC += skip; + nPC += skip; + pPCSymbol->nValue += skip; + } + else + { + checkcodesection( skip ); + while( skip-- ) + out_AbsByte( CurrentOptions.fillchar ); + } +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Output a NULL terminated string (excluding the NULL-character) + * + */ + +void out_String (char *s) +{ + checkcodesection (strlen (s)); + while (*s) + out_AbsByte (*s++); +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Output a relocatable byte. Checking will be done to see if it + * is an absolute value in disguise. + * + */ + +void out_RelByte (struct Expression *expr) +{ + checkcodesection (1); + if (rpn_isReloc (expr)) + { + if (nPass == 2) + { + pCurrentSection->tData[nPC] = 0; + createpatch (PATCH_BYTE, expr); + } + pCurrentSection->nPC += 1; + nPC += 1; + pPCSymbol->nValue += 1; + } + else + out_AbsByte (expr->nVal); + + rpn_Reset (expr); +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Output an absolute word + * + */ + +void out_AbsWord (int b) +{ + checkcodesection (2); + b &= 0xFFFF; + if (nPass == 2) + { + if( CurrentOptions.endian==ASM_LITTLE_ENDIAN ) + { + pCurrentSection->tData[nPC] = b & 0xFF; + pCurrentSection->tData[nPC + 1] = b >> 8; + } + else + { + // Assume big endian + pCurrentSection->tData[nPC] = b >> 8; + pCurrentSection->tData[nPC+1] = b & 0xFF; + } + } + pCurrentSection->nPC += 2; + nPC += 2; + pPCSymbol->nValue += 2; +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Output a relocatable word. Checking will be done to see if + * is an absolute value in disguise. + * + */ + +void out_RelWord (struct Expression *expr) +{ + ULONG b; + + checkcodesection (2); + b = expr->nVal&0xFFFF; + if (rpn_isReloc (expr)) + { + if (nPass == 2) + { + if( CurrentOptions.endian==ASM_LITTLE_ENDIAN ) + { + pCurrentSection->tData[nPC] = b & 0xFF; + pCurrentSection->tData[nPC + 1] = b >> 8; + createpatch (PATCH_WORD_L,expr); + } + else + { + // Assume big endian + pCurrentSection->tData[nPC] = b >> 8; + pCurrentSection->tData[nPC+1] = b & 0xFF; + createpatch (PATCH_WORD_B,expr); + } + } + pCurrentSection->nPC += 2; + nPC += 2; + pPCSymbol->nValue += 2; + } + else + out_AbsWord (expr->nVal); + rpn_Reset (expr); +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Output an absolute longword + * + */ + +void out_AbsLong (SLONG b) +{ + checkcodesection (sizeof(SLONG)); + if (nPass == 2) + { + if( CurrentOptions.endian==ASM_LITTLE_ENDIAN ) + { + pCurrentSection->tData[nPC] = b & 0xFF; + pCurrentSection->tData[nPC + 1] = b >> 8; + pCurrentSection->tData[nPC + 2] = b >> 16; + pCurrentSection->tData[nPC + 3] = b >> 24; + } + else + { + // Assume big endian + pCurrentSection->tData[nPC] = b >> 24; + pCurrentSection->tData[nPC+1] = b >> 16; + pCurrentSection->tData[nPC+2] = b >> 8; + pCurrentSection->tData[nPC+3] = b & 0xFF; + } + } + pCurrentSection->nPC += 4; + nPC += 4; + pPCSymbol->nValue += 4; +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Output a relocatable longword. Checking will be done to see if + * is an absolute value in disguise. + * + */ + +void out_RelLong (struct Expression *expr) +{ + SLONG b; + + checkcodesection (4); + b=expr->nVal; + if (rpn_isReloc (expr)) + { + if (nPass == 2) + { + if( CurrentOptions.endian==ASM_LITTLE_ENDIAN ) + { + pCurrentSection->tData[nPC] = b & 0xFF; + pCurrentSection->tData[nPC + 1] = b >> 8; + pCurrentSection->tData[nPC + 2] = b >> 16; + pCurrentSection->tData[nPC + 3] = b >> 24; + createpatch (PATCH_LONG_L,expr); + } + else + { + // Assume big endian + pCurrentSection->tData[nPC] = b >> 24; + pCurrentSection->tData[nPC+1] = b >> 16; + pCurrentSection->tData[nPC+2] = b >> 8; + pCurrentSection->tData[nPC+3] = b & 0xFF; + createpatch (PATCH_LONG_B,expr); + } + } + pCurrentSection->nPC += 4; + nPC += 4; + pPCSymbol->nValue += 4; + } + else + out_AbsLong (expr->nVal); + rpn_Reset (expr); +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Output a PC-relative byte + * + */ + +void out_PCRelByte (struct Expression *expr) +{ + SLONG b=expr->nVal; + + checkcodesection (1); + b = (b & 0xFFFF) - (nPC + 1); + if (nPass == 2 && (b < -128 || b > 127)) + yyerror ("PC-relative value must be 8-bit"); + + out_AbsByte (b); + rpn_Reset (expr); +} + +/* + * RGBAsm - OUTPUT.C - Outputs an objectfile + * + * Output a binary file + * + */ + +void out_BinaryFile (char *s) +{ + FILE *f; + + fstk_FindFile (s); + + if( (f=fopen(s,"rb"))!=NULL ) + { + SLONG fsize; + + fseek (f, 0, SEEK_END); + fsize = ftell (f); + fseek (f, 0, SEEK_SET); + + checkcodesection (fsize); + + if (nPass == 2) + { + SLONG dest = nPC; + SLONG todo = fsize; + + while (todo--) + pCurrentSection->tData[dest++] = fgetc (f); + } + + pCurrentSection->nPC += fsize; + nPC += fsize; + pPCSymbol->nValue += fsize; + fclose (f); + } + else + fatalerror ("File not found"); } \ No newline at end of file diff --git a/src/asm/rpn.c b/src/asm/rpn.c index 1da5f88f..fbc7443f 100644 --- a/src/asm/rpn.c +++ b/src/asm/rpn.c @@ -1,356 +1,356 @@ -/* - * RGBAsm - RPN.C - Controls RPN expressions for objectfiles - * - * INCLUDES - * - */ - -#include "mylink.h" -#include "types.h" -#include "symbol.h" -#include "asm.h" -#include "main.h" -#include "rpn.h" - -#include -#include - -void mergetwoexpressions( struct Expression *expr, struct Expression *src1, struct Expression *src2 ) -{ - *expr = *src1; - memcpy( &(expr->tRPN[expr->nRPNLength]), src2->tRPN, src2->nRPNLength ); - - expr->nRPNLength += src2->nRPNLength; - expr->isReloc |= src2->isReloc; - expr->isPCRel |= src2->isPCRel; -} - -#define joinexpr() mergetwoexpressions(expr,src1,src2) - -/* - * RGBAsm - RPN.C - Controls RPN expressions for objectfiles - * - * VARIABLES - * - */ - -//UBYTE rpnexpr[2048]; -//ULONG rpnptr = 0; -//ULONG rpnoutptr = 0; -//ULONG reloc = 0; -//ULONG pcrel = 0; - -/* - * RGBAsm - RPN.C - Controls RPN expressions for objectfiles - * - * Add a byte to the RPN expression - * - */ - -void pushbyte (struct Expression *expr, int b) -{ - expr->tRPN[expr->nRPNLength++] = b & 0xFF; -} - -/* - * RGBAsm - RPN.C - Controls RPN expressions for objectfiles - * - * Reset the RPN module - * - */ - -void rpn_Reset (struct Expression *expr) -{ - expr->nRPNLength = expr->nRPNOut = expr->isReloc = expr->isPCRel = 0; -} - -/* - * RGBAsm - RPN.C - Controls RPN expressions for objectfiles - * - * Returns the next rpn byte in expression - * - */ - -UWORD rpn_PopByte (struct Expression *expr) -{ - if (expr->nRPNOut == expr->nRPNLength) - { - return (0xDEAD); - } - else - return (expr->tRPN[expr->nRPNOut++]); -} - -/* - * RGBAsm - RPN.C - Controls RPN expressions for objectfiles - * - * Determine if the current expression is relocatable - * - */ - -ULONG rpn_isReloc (struct Expression *expr) -{ - return (expr->isReloc); -} - -/* - * RGBAsm - RPN.C - Controls RPN expressions for objectfiles - * - * Determine if the current expression can be pc-relative - * - */ - -ULONG rpn_isPCRelative (struct Expression *expr) -{ - return (expr->isPCRel); -} - -/* - * RGBAsm - RPN.C - Controls RPN expressions for objectfiles - * - * Add symbols, constants and operators to expression - * - */ - -void rpn_Number (struct Expression *expr, ULONG i) -{ - rpn_Reset (expr); - pushbyte (expr, RPN_CONST); - pushbyte (expr, i); - pushbyte (expr, i >> 8); - pushbyte (expr, i >> 16); - pushbyte (expr, i >> 24); - expr->nVal = i; -} - -void rpn_Symbol (struct Expression *expr, char *tzSym) -{ - if (!sym_isConstant (tzSym)) - { - struct sSymbol *psym; - - rpn_Reset(expr); - - psym = sym_FindSymbol (tzSym); - - if (psym == NULL || psym->pSection == pCurrentSection || psym->pSection == NULL) - expr->isPCRel = 1; - expr->isReloc = 1; - pushbyte (expr,RPN_SYM); - while (*tzSym) - pushbyte (expr,*tzSym++); - pushbyte (expr,0); - } - else - rpn_Number (expr,sym_GetConstantValue (tzSym)); -} - -void rpn_Bank (struct Expression *expr,char *tzSym) -{ - if (!sym_isConstant (tzSym)) - { - struct sSymbol *psym; - - rpn_Reset( expr ); - - psym = sym_FindSymbol (tzSym); - if (nPass == 2 && psym == NULL) - { - sprintf (temptext, "'%s' not defined", tzSym); - yyerror (temptext); - } - expr->isReloc = 1; - pushbyte (expr,RPN_BANK); - while (*tzSym) - pushbyte (expr,*tzSym++); - pushbyte (expr,0); - } - else - yyerror ("BANK argument must be a relocatable identifier"); -} - -int rpn_RangeCheck( struct Expression *expr, struct Expression *src, SLONG low, SLONG high ) -{ - *expr=*src; - - if( rpn_isReloc(src) ) - { - pushbyte( expr, RPN_RANGECHECK ); - pushbyte( expr, low ); - pushbyte( expr, low>>8 ); - pushbyte( expr, low>>16 ); - pushbyte( expr, low>>24 ); - pushbyte( expr, high ); - pushbyte( expr, high>>8 ); - pushbyte( expr, high>>16 ); - pushbyte( expr, high>>24 ); - return( 1 ); - } - else - { - return( expr->nVal>=low && expr->nVal<=high ); - } -} - -#ifdef GAMEBOY -void rpn_CheckHRAM (struct Expression *expr, struct Expression *src) -{ - *expr = *src; - pushbyte (expr, RPN_HRAM); -} -#endif - -#ifdef PCENGINE -void rpn_CheckZP (struct Expression *expr, struct Expression *src) -{ - *expr = *src; - pushbyte (expr, RPN_PCEZP); -} -#endif - -void rpn_LOGNOT (struct Expression *expr, struct Expression *src) -{ - *expr = *src; - pushbyte (expr, RPN_LOGUNNOT); -} - -void rpn_LOGOR (struct Expression *expr, struct Expression *src1, struct Expression *src2) -{ - joinexpr(); - expr->nVal = (expr->nVal||src2->nVal); - pushbyte (expr,RPN_LOGOR); -} - -void rpn_LOGAND (struct Expression *expr, struct Expression *src1, struct Expression *src2) -{ - joinexpr(); - expr->nVal = (expr->nVal&&src2->nVal); - pushbyte (expr,RPN_LOGAND); -} - -void rpn_LOGEQU (struct Expression *expr, struct Expression *src1, struct Expression *src2) -{ - joinexpr(); - expr->nVal = (expr->nVal==src2->nVal); - pushbyte (expr,RPN_LOGEQ); -} - -void rpn_LOGGT (struct Expression *expr, struct Expression *src1, struct Expression *src2) -{ - joinexpr(); - expr->nVal = (expr->nVal>src2->nVal); - pushbyte (expr,RPN_LOGGT); -} - -void rpn_LOGLT (struct Expression *expr, struct Expression *src1, struct Expression *src2) -{ - joinexpr(); - expr->nVal = (expr->nValnVal); - pushbyte (expr,RPN_LOGLT); -} - -void rpn_LOGGE (struct Expression *expr, struct Expression *src1, struct Expression *src2) -{ - joinexpr(); - expr->nVal = (expr->nVal>=src2->nVal); - pushbyte (expr,RPN_LOGGE); -} - -void rpn_LOGLE (struct Expression *expr, struct Expression *src1, struct Expression *src2) -{ - joinexpr(); - expr->nVal = (expr->nVal<=src2->nVal); - pushbyte (expr,RPN_LOGLE); -} - -void rpn_LOGNE (struct Expression *expr, struct Expression *src1, struct Expression *src2) -{ - joinexpr(); - expr->nVal = (expr->nVal!=src2->nVal); - pushbyte (expr,RPN_LOGNE); -} - -void rpn_ADD (struct Expression *expr, struct Expression *src1, struct Expression *src2) -{ - joinexpr(); - expr->nVal = (expr->nVal+src2->nVal); - pushbyte (expr,RPN_ADD); -} - -void rpn_SUB (struct Expression *expr, struct Expression *src1, struct Expression *src2) -{ - joinexpr(); - expr->nVal = (expr->nVal-src2->nVal); - pushbyte (expr,RPN_SUB); -} - -void rpn_XOR (struct Expression *expr, struct Expression *src1, struct Expression *src2) -{ - joinexpr(); - expr->nVal = (expr->nVal^src2->nVal); - pushbyte (expr,RPN_XOR); -} - -void rpn_OR (struct Expression *expr, struct Expression *src1, struct Expression *src2) -{ - joinexpr(); - expr->nVal = (expr->nVal|src2->nVal); - pushbyte (expr,RPN_OR); -} - -void rpn_AND (struct Expression *expr, struct Expression *src1, struct Expression *src2) -{ - joinexpr(); - expr->nVal = (expr->nVal&src2->nVal); - pushbyte (expr,RPN_AND); -} - -void rpn_SHL (struct Expression *expr, struct Expression *src1, struct Expression *src2) -{ - joinexpr(); - expr->nVal = (expr->nVal<nVal); - pushbyte (expr,RPN_SHL); -} - -void rpn_SHR (struct Expression *expr, struct Expression *src1, struct Expression *src2) -{ - joinexpr(); - expr->nVal = (expr->nVal>>src2->nVal); - pushbyte (expr,RPN_SHR); -} - -void rpn_MUL (struct Expression *expr, struct Expression *src1, struct Expression *src2) -{ - joinexpr(); - expr->nVal = (expr->nVal*src2->nVal); - pushbyte (expr,RPN_MUL); -} - -void rpn_DIV (struct Expression *expr, struct Expression *src1, struct Expression *src2) -{ - joinexpr(); - expr->nVal = (expr->nVal/src2->nVal); - pushbyte (expr,RPN_DIV); -} - -void rpn_MOD (struct Expression *expr, struct Expression *src1, struct Expression *src2) -{ - joinexpr(); - expr->nVal = (expr->nVal%src2->nVal); - pushbyte (expr,RPN_MOD); -} - -void rpn_UNNEG (struct Expression *expr, struct Expression *src) -{ - *expr = *src; - expr->nVal = -expr->nVal; - pushbyte (expr,RPN_UNSUB); -} - -void rpn_UNNOT (struct Expression *expr, struct Expression *src) -{ - *expr = *src; - expr->nVal = expr->nVal^0xFFFFFFFF; - pushbyte (expr,RPN_UNNOT); -} - +/* + * RGBAsm - RPN.C - Controls RPN expressions for objectfiles + * + * INCLUDES + * + */ + +#include "mylink.h" +#include "types.h" +#include "symbol.h" +#include "asm.h" +#include "main.h" +#include "rpn.h" + +#include +#include + +void mergetwoexpressions( struct Expression *expr, struct Expression *src1, struct Expression *src2 ) +{ + *expr = *src1; + memcpy( &(expr->tRPN[expr->nRPNLength]), src2->tRPN, src2->nRPNLength ); + + expr->nRPNLength += src2->nRPNLength; + expr->isReloc |= src2->isReloc; + expr->isPCRel |= src2->isPCRel; +} + +#define joinexpr() mergetwoexpressions(expr,src1,src2) + +/* + * RGBAsm - RPN.C - Controls RPN expressions for objectfiles + * + * VARIABLES + * + */ + +//UBYTE rpnexpr[2048]; +//ULONG rpnptr = 0; +//ULONG rpnoutptr = 0; +//ULONG reloc = 0; +//ULONG pcrel = 0; + +/* + * RGBAsm - RPN.C - Controls RPN expressions for objectfiles + * + * Add a byte to the RPN expression + * + */ + +void pushbyte (struct Expression *expr, int b) +{ + expr->tRPN[expr->nRPNLength++] = b & 0xFF; +} + +/* + * RGBAsm - RPN.C - Controls RPN expressions for objectfiles + * + * Reset the RPN module + * + */ + +void rpn_Reset (struct Expression *expr) +{ + expr->nRPNLength = expr->nRPNOut = expr->isReloc = expr->isPCRel = 0; +} + +/* + * RGBAsm - RPN.C - Controls RPN expressions for objectfiles + * + * Returns the next rpn byte in expression + * + */ + +UWORD rpn_PopByte (struct Expression *expr) +{ + if (expr->nRPNOut == expr->nRPNLength) + { + return (0xDEAD); + } + else + return (expr->tRPN[expr->nRPNOut++]); +} + +/* + * RGBAsm - RPN.C - Controls RPN expressions for objectfiles + * + * Determine if the current expression is relocatable + * + */ + +ULONG rpn_isReloc (struct Expression *expr) +{ + return (expr->isReloc); +} + +/* + * RGBAsm - RPN.C - Controls RPN expressions for objectfiles + * + * Determine if the current expression can be pc-relative + * + */ + +ULONG rpn_isPCRelative (struct Expression *expr) +{ + return (expr->isPCRel); +} + +/* + * RGBAsm - RPN.C - Controls RPN expressions for objectfiles + * + * Add symbols, constants and operators to expression + * + */ + +void rpn_Number (struct Expression *expr, ULONG i) +{ + rpn_Reset (expr); + pushbyte (expr, RPN_CONST); + pushbyte (expr, i); + pushbyte (expr, i >> 8); + pushbyte (expr, i >> 16); + pushbyte (expr, i >> 24); + expr->nVal = i; +} + +void rpn_Symbol (struct Expression *expr, char *tzSym) +{ + if (!sym_isConstant (tzSym)) + { + struct sSymbol *psym; + + rpn_Reset(expr); + + psym = sym_FindSymbol (tzSym); + + if (psym == NULL || psym->pSection == pCurrentSection || psym->pSection == NULL) + expr->isPCRel = 1; + expr->isReloc = 1; + pushbyte (expr,RPN_SYM); + while (*tzSym) + pushbyte (expr,*tzSym++); + pushbyte (expr,0); + } + else + rpn_Number (expr,sym_GetConstantValue (tzSym)); +} + +void rpn_Bank (struct Expression *expr,char *tzSym) +{ + if (!sym_isConstant (tzSym)) + { + struct sSymbol *psym; + + rpn_Reset( expr ); + + psym = sym_FindSymbol (tzSym); + if (nPass == 2 && psym == NULL) + { + sprintf (temptext, "'%s' not defined", tzSym); + yyerror (temptext); + } + expr->isReloc = 1; + pushbyte (expr,RPN_BANK); + while (*tzSym) + pushbyte (expr,*tzSym++); + pushbyte (expr,0); + } + else + yyerror ("BANK argument must be a relocatable identifier"); +} + +int rpn_RangeCheck( struct Expression *expr, struct Expression *src, SLONG low, SLONG high ) +{ + *expr=*src; + + if( rpn_isReloc(src) ) + { + pushbyte( expr, RPN_RANGECHECK ); + pushbyte( expr, low ); + pushbyte( expr, low>>8 ); + pushbyte( expr, low>>16 ); + pushbyte( expr, low>>24 ); + pushbyte( expr, high ); + pushbyte( expr, high>>8 ); + pushbyte( expr, high>>16 ); + pushbyte( expr, high>>24 ); + return( 1 ); + } + else + { + return( expr->nVal>=low && expr->nVal<=high ); + } +} + +#ifdef GAMEBOY +void rpn_CheckHRAM (struct Expression *expr, struct Expression *src) +{ + *expr = *src; + pushbyte (expr, RPN_HRAM); +} +#endif + +#ifdef PCENGINE +void rpn_CheckZP (struct Expression *expr, struct Expression *src) +{ + *expr = *src; + pushbyte (expr, RPN_PCEZP); +} +#endif + +void rpn_LOGNOT (struct Expression *expr, struct Expression *src) +{ + *expr = *src; + pushbyte (expr, RPN_LOGUNNOT); +} + +void rpn_LOGOR (struct Expression *expr, struct Expression *src1, struct Expression *src2) +{ + joinexpr(); + expr->nVal = (expr->nVal||src2->nVal); + pushbyte (expr,RPN_LOGOR); +} + +void rpn_LOGAND (struct Expression *expr, struct Expression *src1, struct Expression *src2) +{ + joinexpr(); + expr->nVal = (expr->nVal&&src2->nVal); + pushbyte (expr,RPN_LOGAND); +} + +void rpn_LOGEQU (struct Expression *expr, struct Expression *src1, struct Expression *src2) +{ + joinexpr(); + expr->nVal = (expr->nVal==src2->nVal); + pushbyte (expr,RPN_LOGEQ); +} + +void rpn_LOGGT (struct Expression *expr, struct Expression *src1, struct Expression *src2) +{ + joinexpr(); + expr->nVal = (expr->nVal>src2->nVal); + pushbyte (expr,RPN_LOGGT); +} + +void rpn_LOGLT (struct Expression *expr, struct Expression *src1, struct Expression *src2) +{ + joinexpr(); + expr->nVal = (expr->nValnVal); + pushbyte (expr,RPN_LOGLT); +} + +void rpn_LOGGE (struct Expression *expr, struct Expression *src1, struct Expression *src2) +{ + joinexpr(); + expr->nVal = (expr->nVal>=src2->nVal); + pushbyte (expr,RPN_LOGGE); +} + +void rpn_LOGLE (struct Expression *expr, struct Expression *src1, struct Expression *src2) +{ + joinexpr(); + expr->nVal = (expr->nVal<=src2->nVal); + pushbyte (expr,RPN_LOGLE); +} + +void rpn_LOGNE (struct Expression *expr, struct Expression *src1, struct Expression *src2) +{ + joinexpr(); + expr->nVal = (expr->nVal!=src2->nVal); + pushbyte (expr,RPN_LOGNE); +} + +void rpn_ADD (struct Expression *expr, struct Expression *src1, struct Expression *src2) +{ + joinexpr(); + expr->nVal = (expr->nVal+src2->nVal); + pushbyte (expr,RPN_ADD); +} + +void rpn_SUB (struct Expression *expr, struct Expression *src1, struct Expression *src2) +{ + joinexpr(); + expr->nVal = (expr->nVal-src2->nVal); + pushbyte (expr,RPN_SUB); +} + +void rpn_XOR (struct Expression *expr, struct Expression *src1, struct Expression *src2) +{ + joinexpr(); + expr->nVal = (expr->nVal^src2->nVal); + pushbyte (expr,RPN_XOR); +} + +void rpn_OR (struct Expression *expr, struct Expression *src1, struct Expression *src2) +{ + joinexpr(); + expr->nVal = (expr->nVal|src2->nVal); + pushbyte (expr,RPN_OR); +} + +void rpn_AND (struct Expression *expr, struct Expression *src1, struct Expression *src2) +{ + joinexpr(); + expr->nVal = (expr->nVal&src2->nVal); + pushbyte (expr,RPN_AND); +} + +void rpn_SHL (struct Expression *expr, struct Expression *src1, struct Expression *src2) +{ + joinexpr(); + expr->nVal = (expr->nVal<nVal); + pushbyte (expr,RPN_SHL); +} + +void rpn_SHR (struct Expression *expr, struct Expression *src1, struct Expression *src2) +{ + joinexpr(); + expr->nVal = (expr->nVal>>src2->nVal); + pushbyte (expr,RPN_SHR); +} + +void rpn_MUL (struct Expression *expr, struct Expression *src1, struct Expression *src2) +{ + joinexpr(); + expr->nVal = (expr->nVal*src2->nVal); + pushbyte (expr,RPN_MUL); +} + +void rpn_DIV (struct Expression *expr, struct Expression *src1, struct Expression *src2) +{ + joinexpr(); + expr->nVal = (expr->nVal/src2->nVal); + pushbyte (expr,RPN_DIV); +} + +void rpn_MOD (struct Expression *expr, struct Expression *src1, struct Expression *src2) +{ + joinexpr(); + expr->nVal = (expr->nVal%src2->nVal); + pushbyte (expr,RPN_MOD); +} + +void rpn_UNNEG (struct Expression *expr, struct Expression *src) +{ + *expr = *src; + expr->nVal = -expr->nVal; + pushbyte (expr,RPN_UNSUB); +} + +void rpn_UNNOT (struct Expression *expr, struct Expression *src) +{ + *expr = *src; + expr->nVal = expr->nVal^0xFFFFFFFF; + pushbyte (expr,RPN_UNNOT); +} + diff --git a/src/asm/symbol.c b/src/asm/symbol.c index 133c1257..c75c3d26 100644 --- a/src/asm/symbol.c +++ b/src/asm/symbol.c @@ -1,1073 +1,1073 @@ -/* - * RGBAsm - SYMBOL.C - Symboltable and macroargs stuff - * - * INCLUDES - * - */ - -#include -#include -#include -#include "asm.h" -#include "symbol.h" -#include "main.h" -#include "mymath.h" -#include "output.h" - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * VARIABLES - * - */ - -struct sSymbol *tHashedSymbols[HASHSIZE]; -struct sSymbol *pScope = NULL; -struct sSymbol *pPCSymbol = NULL; -struct sSymbol *p_NARGSymbol = NULL; -struct sSymbol *p__LINE__Symbol = NULL; -char *currentmacroargs[MAXMACROARGS + 1]; -char *newmacroargs[MAXMACROARGS + 1]; -char SavedTIME[256]; -char SavedDATE[256]; - -SLONG Callback_NARG (struct sSymbol *sym) -{ - ULONG i = 0; - - sym = sym; - while (currentmacroargs[i] && i < MAXMACROARGS) - i += 1; - - return (i); -} - -SLONG Callback__LINE__ (struct sSymbol *sym) -{ - sym=sym; - return (nLineNo); -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Get the nValue field of a symbol - * - */ - -SLONG getvaluefield (struct sSymbol *sym) -{ - if (sym->Callback) - { - return (sym->Callback (sym)); - } - else - return (sym->nValue); -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Calculate the hash value for a string - * - */ - -ULONG calchash (char *s) -{ - ULONG hash = 0; - - while (*s != 0) - hash += (*s++); - - return (hash % HASHSIZE); -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Create a new symbol by name - * - */ - -struct sSymbol *createsymbol (char *s) -{ - struct sSymbol **ppsym; - ULONG hash; - - hash = calchash (s); - ppsym = &(tHashedSymbols[hash]); - - while ((*ppsym) != NULL) - ppsym = &((*ppsym)->pNext); - - if( ((*ppsym)=(struct sSymbol *)malloc(sizeof (struct sSymbol)))!=NULL ) - { - strcpy ((*ppsym)->tzName, s); - (*ppsym)->nValue = 0; - (*ppsym)->nType = 0; - (*ppsym)->pScope = NULL; - (*ppsym)->pNext = NULL; - (*ppsym)->pMacro = NULL; - (*ppsym)->pSection = NULL; - (*ppsym)->Callback = NULL; - return (*ppsym); - } - else - { - fatalerror ("No memory for symbol"); - return (NULL); - } -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Find a symbol by name and scope - * - */ - -struct sSymbol *findsymbol (char *s, struct sSymbol *scope) -{ - struct sSymbol **ppsym; - SLONG hash; - - hash = calchash (s); - ppsym = &(tHashedSymbols[hash]); - - while ((*ppsym) != NULL) - { - if( (strcmp (s, (*ppsym)->tzName) == 0) - && ((*ppsym)->pScope == scope) ) - { - return (*ppsym); - } - else - ppsym = &((*ppsym)->pNext); - } - return (NULL); -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Find the pointer to a symbol by name and scope - * - */ - -struct sSymbol **findpsymbol (char *s, struct sSymbol *scope) -{ - struct sSymbol **ppsym; - SLONG hash; - - hash = calchash (s); - ppsym = &(tHashedSymbols[hash]); - - while ((*ppsym) != NULL) - { - if( (strcmp (s, (*ppsym)->tzName) == 0) - && ((*ppsym)->pScope == scope) ) - { - return (ppsym); - } - else - ppsym = &((*ppsym)->pNext); - } - return (NULL); -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Find a symbol by name and scope - * - */ - -struct sSymbol *sym_FindSymbol (char *tzName) -{ - struct sSymbol *pscope; - - if (*tzName == '.') - pscope = pScope; - else - pscope = NULL; - - return (findsymbol (tzName, pscope)); -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Purge a symbol - * - */ - -void sym_Purge( char *tzName ) -{ - struct sSymbol **ppSym; - struct sSymbol *pscope; - - if (*tzName == '.') - pscope = pScope; - else - pscope = NULL; - - ppSym=findpsymbol( tzName, pscope ); - - if( ppSym ) - { - struct sSymbol *pSym; - - pSym=*ppSym; - *ppSym=pSym->pNext; - - if( pSym->pMacro ) - free( pSym->pMacro ); - - free( pSym ); - } - else - { - sprintf( temptext, "'%s' not defined", tzName ); - yyerror( temptext ); - } -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Determine if a symbol has been defined - * - */ - -ULONG sym_isConstDefined (char *tzName) -{ - struct sSymbol *psym, - *pscope; - - if (*tzName == '.') - pscope = pScope; - else - pscope = NULL; - - psym = findsymbol (tzName, pscope); - - if( psym - && (psym->nType & SYMF_DEFINED) ) - { - if( psym->nType & (SYMF_EQU|SYMF_SET|SYMF_MACRO|SYMF_STRING) ) - { - return (1); - } - else - { - sprintf( temptext, "'%s' is not allowed as argument to the DEF function", tzName ); - fatalerror( temptext ); - } - } - return (0); -} - -ULONG sym_isDefined (char *tzName) -{ - struct sSymbol *psym, - *pscope; - - if (*tzName == '.') - pscope = pScope; - else - pscope = NULL; - - psym = findsymbol (tzName, pscope); - - if (psym && (psym->nType & SYMF_DEFINED)) - return (1); - else - return (0); -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Determine if the symbol is a constant - * - */ - -ULONG sym_isConstant (char *s) -{ - struct sSymbol *psym, - *pscope; - - if (*s == '.') - pscope = pScope; - else - pscope = NULL; - - if( (psym=findsymbol(s,pscope))!=NULL ) - { - if (psym->nType & SYMF_CONST) - return (1); - } - - return (0); -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Get a string equate's value - * - */ - -char *sym_GetStringValue (char *tzSym) -{ - struct sSymbol *pSym; - - if( (pSym=sym_FindSymbol(tzSym))!=NULL ) - return (pSym->pMacro); - else - { - sprintf (temptext, "Stringsymbol '%s' not defined", tzSym); - yyerror (temptext); - } - - return (NULL); -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Return a constant symbols value - * - */ - -ULONG sym_GetConstantValue (char *s) -{ - struct sSymbol *psym, - *pscope; - - if (*s == '.') - pscope = pScope; - else - pscope = NULL; - - if( (psym=findsymbol(s,pscope))!=NULL ) - { - if (psym->nType & SYMF_CONST) - return (getvaluefield (psym)); - else - { - fatalerror ("Expression must have a constant value"); - } - } - else - { - sprintf (temptext, "'%s' not defined", s); - yyerror (temptext); - } - - return (0); -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Return a symbols value... "estimated" if not defined yet - * - */ - -ULONG sym_GetValue (char *s) -{ - struct sSymbol *psym, - *pscope; - - if (*s == '.') - pscope = pScope; - else - pscope = NULL; - - if( (psym=findsymbol(s,pscope))!=NULL ) - { - if( psym->nType & SYMF_DEFINED ) - { - if( psym->nType & (SYMF_MACRO|SYMF_STRING) ) - { - sprintf (temptext, "'%s' is a macro or string symbol", s); - yyerror (temptext); - } - return (getvaluefield (psym)); - } - else - { - if ((nPass == 1) || (psym->nType & SYMF_IMPORT)) - { - /* 0x80 seems like a good default value... */ - return (0x80); - } - else - { - sprintf (temptext, "'%s' not defined", s); - yyerror (temptext); - } - } - } - else - { - if (nPass == 1) - { - createsymbol (s); - return (0x80); - } - else - { - sprintf (temptext, "'%s' not defined", s); - yyerror (temptext); - } - } - - return (0); -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Return a defined symbols value... aborts if not defined yet - * - */ - -ULONG sym_GetDefinedValue (char *s) -{ - struct sSymbol *psym, - *pscope; - - if (*s == '.') - pscope = pScope; - else - pscope = NULL; - - if( (psym=findsymbol(s,pscope))!=NULL ) - { - if( (psym->nType & SYMF_DEFINED) ) - { - if( psym->nType & (SYMF_MACRO|SYMF_STRING) ) - { - sprintf (temptext, "'%s' is a macro or string symbol", s); - yyerror (temptext); - } - - return (getvaluefield (psym)); - } - else - { - sprintf (temptext, "'%s' not defined", s); - yyerror (temptext); - } - } - else - { - sprintf (temptext, "'%s' not defined", s); - yyerror (temptext); - } - - return (0); -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Macro argument stuff - * - */ - -void sym_ShiftCurrentMacroArgs (void) -{ - SLONG i; - - free (currentmacroargs[0]); - for (i = 0; i < MAXMACROARGS - 1; i += 1) - { - currentmacroargs[i] = currentmacroargs[i + 1]; - } - currentmacroargs[MAXMACROARGS - 1] = NULL; -} - -char *sym_FindMacroArg (SLONG i) -{ - if (i == -1) - i = MAXMACROARGS + 1; - - return (currentmacroargs[i - 1]); -} - -void sym_UseNewMacroArgs (void) -{ - SLONG i; - - for (i = 0; i <= MAXMACROARGS; i += 1) - { - currentmacroargs[i] = newmacroargs[i]; - newmacroargs[i] = NULL; - } -} - -void sym_SaveCurrentMacroArgs (char *save[]) -{ - SLONG i; - - for (i = 0; i <= MAXMACROARGS; i += 1) - save[i] = currentmacroargs[i]; -} - -void sym_RestoreCurrentMacroArgs (char *save[]) -{ - SLONG i; - - for (i = 0; i <= MAXMACROARGS; i += 1) - currentmacroargs[i] = save[i]; -} - -void sym_FreeCurrentMacroArgs (void) -{ - SLONG i; - - for (i = 0; i <= MAXMACROARGS; i += 1) - { - free (currentmacroargs[i]); - currentmacroargs[i] = NULL; - } -} - -void sym_AddNewMacroArg (char *s) -{ - SLONG i = 0; - - while (i < MAXMACROARGS && newmacroargs[i] != NULL) - i += 1; - - if (i < MAXMACROARGS) - { - if (s) - newmacroargs[i] = strdup (s); - else - newmacroargs[i] = NULL; - } - else - yyerror ("A maximum of 9 arguments allowed"); -} - -void sym_SetMacroArgID (ULONG nMacroCount) -{ - char s[256]; - - sprintf(s, "_%ld", nMacroCount); - newmacroargs[MAXMACROARGS] = strdup (s); -} - -void sym_UseCurrentMacroArgs (void) -{ - SLONG i; - - for (i = 1; i <= MAXMACROARGS; i += 1) - sym_AddNewMacroArg (sym_FindMacroArg (i)); -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Find a macro by name - * - */ - -struct sSymbol *sym_FindMacro (char *s) -{ - return (findsymbol (s, NULL)); -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Add an equated symbol - * - */ - -void sym_AddEqu (char *tzSym, SLONG value) -{ - if( (nPass==1) - || ((nPass==2)&&(sym_isDefined(tzSym)==0)) ) - { - /* only add equated symbols in pass 1 */ - struct sSymbol *nsym; - - if( (nsym=findsymbol(tzSym,NULL))!=NULL ) - { - if (nsym->nType & SYMF_DEFINED) - { - sprintf (temptext, "'%s' already defined", tzSym); - yyerror (temptext); - } - } - else - nsym = createsymbol (tzSym); - - if (nsym) - { - nsym->nValue = value; - nsym->nType |= SYMF_EQU | SYMF_DEFINED | SYMF_CONST; - nsym->pScope = NULL; - } - } -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Add a string equated symbol - * - */ - -void sym_AddString (char *tzSym, char *tzValue) -{ - struct sSymbol *nsym; - - if( (nsym=findsymbol(tzSym,NULL))!=NULL ) - { - if (nsym->nType & SYMF_DEFINED) - { - sprintf (temptext, "'%s' already defined", tzSym); - yyerror (temptext); - } - } - else - nsym = createsymbol (tzSym); - - if (nsym) - { - if( (nsym->pMacro=(char *)malloc(strlen(tzValue)+1))!=NULL ) - strcpy (nsym->pMacro, tzValue); - else - fatalerror ("No memory for stringequate"); - nsym->nType |= SYMF_STRING | SYMF_DEFINED; - nsym->ulMacroSize = strlen( tzValue ); - nsym->pScope = NULL; - } -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * check if symbol is a string equated symbol - * - */ - -ULONG sym_isString (char *tzSym) -{ - struct sSymbol *pSym; - - if( (pSym=findsymbol(tzSym,NULL))!=NULL ) - { - if (pSym->nType & SYMF_STRING) - return (1); - } - return (0); -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Alter a SET symbols value - * - */ - -void sym_AddSet (char *tzSym, SLONG value) -{ - struct sSymbol *nsym; - - if( (nsym=findsymbol(tzSym,NULL))!=NULL ) - { - } - else - nsym = createsymbol (tzSym); - - if (nsym) - { - nsym->nValue = value; - nsym->nType |= SYMF_SET | SYMF_DEFINED | SYMF_CONST; - nsym->pScope = NULL; - } -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Add a local (.name) relocatable symbol - * - */ - -void sym_AddLocalReloc (char *tzSym) -{ - if( (nPass==1) - || ((nPass==2)&&(sym_isDefined(tzSym)==0)) ) - { - /* only add local reloc symbols in pass 1 */ - struct sSymbol *nsym; - - if (pScope) - { - if( (nsym=findsymbol(tzSym,pScope))!=NULL ) - { - if (nsym->nType & SYMF_DEFINED) - { - sprintf (temptext, "'%s' already defined", tzSym); - yyerror (temptext); - } - } - else - nsym = createsymbol (tzSym); - - if (nsym) - { - nsym->nValue = nPC; - nsym->nType |= SYMF_RELOC | SYMF_LOCAL | SYMF_DEFINED; - nsym->pScope = pScope; - nsym->pSection = pCurrentSection; - } - } - else - fatalerror ("Local label in main scope"); - } -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Add a relocatable symbol - * - */ - -void sym_AddReloc (char *tzSym) -{ - if( (nPass==1) - || ((nPass==2)&&(sym_isDefined(tzSym)==0)) ) - { - /* only add reloc symbols in pass 1 */ - struct sSymbol *nsym; - - if( (nsym=findsymbol(tzSym,NULL))!=NULL ) - { - if (nsym->nType & SYMF_DEFINED) - { - sprintf (temptext, "'%s' already defined", tzSym); - yyerror (temptext); - } - } - else - nsym = createsymbol (tzSym); - - if (nsym) - { - nsym->nValue = nPC; - nsym->nType |= SYMF_RELOC | SYMF_DEFINED; - nsym->pScope = NULL; - nsym->pSection = pCurrentSection; - } - } - pScope = findsymbol (tzSym, NULL); - -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Export a symbol - * - */ - -void sym_Export (char *tzSym) -{ - if (nPass == 1) - { - /* only export symbols in pass 1 */ - struct sSymbol *nsym; - - if ((nsym = findsymbol (tzSym, 0)) == NULL) - nsym = createsymbol (tzSym); - - if (nsym) - nsym->nType |= SYMF_EXPORT; - } - else - { - struct sSymbol *nsym; - - if( (nsym=findsymbol(tzSym,0))!=NULL ) - { - if (nsym->nType & SYMF_DEFINED) - return; - } - sprintf (temptext, "'%s' not defined", tzSym); - yyerror (temptext); - } - -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Import a symbol - * - */ - -void sym_Import (char *tzSym) -{ - if (nPass == 1) - { - /* only import symbols in pass 1 */ - struct sSymbol *nsym; - - if (findsymbol (tzSym, NULL)) - { - sprintf (temptext, "'%s' already defined", tzSym); - yyerror (temptext); - } - - if( (nsym=createsymbol(tzSym))!=NULL ) - nsym->nType |= SYMF_IMPORT; - } -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Globalize a symbol (export if defined, import if not) - * - */ - -void sym_Global (char *tzSym) -{ - if (nPass == 2) - { - /* only globalize symbols in pass 2 */ - struct sSymbol *nsym; - - nsym = findsymbol (tzSym, 0); - - if ((nsym == NULL) || ((nsym->nType & SYMF_DEFINED) == 0)) - { - if (nsym == NULL) - nsym = createsymbol (tzSym); - - if (nsym) - nsym->nType |= SYMF_IMPORT; - } - else - { - if (nsym) - nsym->nType |= SYMF_EXPORT; - } - } -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Add a macro definition - * - */ - -void sym_AddMacro (char *tzSym) -{ - if( (nPass==1) - || ((nPass==2)&&(sym_isDefined(tzSym)==0)) ) - { - /* only add macros in pass 1 */ - struct sSymbol *nsym; - - if( (nsym=findsymbol(tzSym,NULL))!=NULL ) - { - if (nsym->nType & SYMF_DEFINED) - { - sprintf (temptext, "'%s' already defined", tzSym); - yyerror (temptext); - } - } - else - nsym = createsymbol (tzSym); - - if (nsym) - { - nsym->nValue = nPC; - nsym->nType |= SYMF_MACRO | SYMF_DEFINED; - nsym->pScope = NULL; - nsym->ulMacroSize = ulNewMacroSize; - nsym->pMacro = tzNewMacro; - } - } -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Prepare for pass #1 - * - */ - -void sym_PrepPass1 (void) -{ - sym_Init (); -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Prepare for pass #2 - * - */ - -void sym_PrepPass2 (void) -{ - SLONG i; - - for (i = 0; i < HASHSIZE; i += 1) - { - struct sSymbol **ppSym = &(tHashedSymbols[i]); - - while (*ppSym) - { - if ((*ppSym)->nType & (SYMF_SET | SYMF_STRING | SYMF_EQU)) - { - struct sSymbol *pTemp; - - pTemp = (*ppSym)->pNext; - free (*ppSym); - *ppSym = pTemp; - } - else - ppSym = &((*ppSym)->pNext); - } - } - pScope = NULL; - pPCSymbol->nValue = 0; - - sym_AddString ("__TIME__", SavedTIME); - sym_AddString ("__DATE__", SavedDATE); - sym_AddSet( "_RS", 0 ); -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * Initialise the symboltable - * - */ - -void sym_Init (void) -{ - SLONG i; - time_t tod; - - for (i = 0; i < MAXMACROARGS; i += 1) - { - currentmacroargs[i] = NULL; - newmacroargs[i] = NULL; - } - - for (i = 0; i < HASHSIZE; i += 1) - tHashedSymbols[i] = NULL; - - sym_AddReloc ("@"); - pPCSymbol = findsymbol ("@", NULL); - sym_AddEqu ("_NARG", 0); - p_NARGSymbol = findsymbol ("_NARG", NULL); - p_NARGSymbol->Callback = Callback_NARG; - sym_AddEqu ("__LINE__", 0); - p__LINE__Symbol = findsymbol ("__LINE__", NULL); - p__LINE__Symbol->Callback = Callback__LINE__; - - sym_AddEqu( "__ASM__", (SLONG) (atof (ASM_VERSION) * 65536)); - sym_AddSet( "_RS", 0 ); - - if( time(&tod)!=-1 ) - { - struct tm *tptr; - - tptr=localtime( &tod ); - strftime( SavedTIME, sizeof(SavedTIME), "%H:%M:%S", tptr ); - strftime( SavedDATE, sizeof(SavedDATE), "%d %B %Y", tptr ); - sym_AddString ("__TIME__", SavedTIME); - sym_AddString ("__DATE__", SavedDATE); - } - - pScope = NULL; - - math_DefinePI (); - -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * DEBUG: Print the symbol table - * - */ - -void sym_PrintSymbolTable (void) -{ - ULONG i; - - for (i = 0; i < HASHSIZE; i += 1) - { - struct sSymbol *sym = tHashedSymbols[i]; - - if (sym != NULL) - printf ("\nHashTable #%ld:\n", i); - - while (sym != NULL) - { - if (sym->nType & SYMF_LOCAL) - printf ("LOCAL : '%s%s' - %08lX\n", sym->pScope->tzName, sym->tzName, getvaluefield (sym)); - else if (sym->nType & (SYMF_MACRO | SYMF_STRING)) - { - ULONG i = 0; - - printf ("MACRO : '%s'\n\"", sym->tzName); - while (i < sym->ulMacroSize) - { - if (sym->pMacro[i] == '\n') - { - printf ("\n"); - i += 1; - } - else - printf ("%c", sym->pMacro[i++]); - } - printf ("\"\n"); - } - else if (sym->nType & SYMF_EXPORT) - printf ("EXPORT: '%s' - %08lX\n", sym->tzName, getvaluefield (sym)); - else if (sym->nType & SYMF_IMPORT) - printf ("IMPORT: '%s'\n", sym->tzName); - else if (sym->nType & SYMF_EQU) - printf ("EQU : '%s' - %08lX\n", sym->tzName, getvaluefield (sym)); - else if (sym->nType & SYMF_SET) - printf ("SET : '%s' - %08lX\n", sym->tzName, getvaluefield (sym)); - else - printf ("SYMBOL: '%s' - %08lX\n", sym->tzName, getvaluefield (sym)); - - sym = sym->pNext; - } - } -} - -/* - * RGBAsm - SYMBOL.C - Symboltable stuff - * - * DEBUG: Dump the macroargs - * - */ - -void sym_DumpMacroArgs (void) -{ - ULONG i; - - for (i = 0; i < MAXMACROARGS; i += 1) - printf ("CurrentArg%ld: %s\n", i + 1, currentmacroargs[i]); +/* + * RGBAsm - SYMBOL.C - Symboltable and macroargs stuff + * + * INCLUDES + * + */ + +#include +#include +#include +#include "asm.h" +#include "symbol.h" +#include "main.h" +#include "mymath.h" +#include "output.h" + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * VARIABLES + * + */ + +struct sSymbol *tHashedSymbols[HASHSIZE]; +struct sSymbol *pScope = NULL; +struct sSymbol *pPCSymbol = NULL; +struct sSymbol *p_NARGSymbol = NULL; +struct sSymbol *p__LINE__Symbol = NULL; +char *currentmacroargs[MAXMACROARGS + 1]; +char *newmacroargs[MAXMACROARGS + 1]; +char SavedTIME[256]; +char SavedDATE[256]; + +SLONG Callback_NARG (struct sSymbol *sym) +{ + ULONG i = 0; + + sym = sym; + while (currentmacroargs[i] && i < MAXMACROARGS) + i += 1; + + return (i); +} + +SLONG Callback__LINE__ (struct sSymbol *sym) +{ + sym=sym; + return (nLineNo); +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Get the nValue field of a symbol + * + */ + +SLONG getvaluefield (struct sSymbol *sym) +{ + if (sym->Callback) + { + return (sym->Callback (sym)); + } + else + return (sym->nValue); +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Calculate the hash value for a string + * + */ + +ULONG calchash (char *s) +{ + ULONG hash = 0; + + while (*s != 0) + hash += (*s++); + + return (hash % HASHSIZE); +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Create a new symbol by name + * + */ + +struct sSymbol *createsymbol (char *s) +{ + struct sSymbol **ppsym; + ULONG hash; + + hash = calchash (s); + ppsym = &(tHashedSymbols[hash]); + + while ((*ppsym) != NULL) + ppsym = &((*ppsym)->pNext); + + if( ((*ppsym)=(struct sSymbol *)malloc(sizeof (struct sSymbol)))!=NULL ) + { + strcpy ((*ppsym)->tzName, s); + (*ppsym)->nValue = 0; + (*ppsym)->nType = 0; + (*ppsym)->pScope = NULL; + (*ppsym)->pNext = NULL; + (*ppsym)->pMacro = NULL; + (*ppsym)->pSection = NULL; + (*ppsym)->Callback = NULL; + return (*ppsym); + } + else + { + fatalerror ("No memory for symbol"); + return (NULL); + } +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Find a symbol by name and scope + * + */ + +struct sSymbol *findsymbol (char *s, struct sSymbol *scope) +{ + struct sSymbol **ppsym; + SLONG hash; + + hash = calchash (s); + ppsym = &(tHashedSymbols[hash]); + + while ((*ppsym) != NULL) + { + if( (strcmp (s, (*ppsym)->tzName) == 0) + && ((*ppsym)->pScope == scope) ) + { + return (*ppsym); + } + else + ppsym = &((*ppsym)->pNext); + } + return (NULL); +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Find the pointer to a symbol by name and scope + * + */ + +struct sSymbol **findpsymbol (char *s, struct sSymbol *scope) +{ + struct sSymbol **ppsym; + SLONG hash; + + hash = calchash (s); + ppsym = &(tHashedSymbols[hash]); + + while ((*ppsym) != NULL) + { + if( (strcmp (s, (*ppsym)->tzName) == 0) + && ((*ppsym)->pScope == scope) ) + { + return (ppsym); + } + else + ppsym = &((*ppsym)->pNext); + } + return (NULL); +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Find a symbol by name and scope + * + */ + +struct sSymbol *sym_FindSymbol (char *tzName) +{ + struct sSymbol *pscope; + + if (*tzName == '.') + pscope = pScope; + else + pscope = NULL; + + return (findsymbol (tzName, pscope)); +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Purge a symbol + * + */ + +void sym_Purge( char *tzName ) +{ + struct sSymbol **ppSym; + struct sSymbol *pscope; + + if (*tzName == '.') + pscope = pScope; + else + pscope = NULL; + + ppSym=findpsymbol( tzName, pscope ); + + if( ppSym ) + { + struct sSymbol *pSym; + + pSym=*ppSym; + *ppSym=pSym->pNext; + + if( pSym->pMacro ) + free( pSym->pMacro ); + + free( pSym ); + } + else + { + sprintf( temptext, "'%s' not defined", tzName ); + yyerror( temptext ); + } +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Determine if a symbol has been defined + * + */ + +ULONG sym_isConstDefined (char *tzName) +{ + struct sSymbol *psym, + *pscope; + + if (*tzName == '.') + pscope = pScope; + else + pscope = NULL; + + psym = findsymbol (tzName, pscope); + + if( psym + && (psym->nType & SYMF_DEFINED) ) + { + if( psym->nType & (SYMF_EQU|SYMF_SET|SYMF_MACRO|SYMF_STRING) ) + { + return (1); + } + else + { + sprintf( temptext, "'%s' is not allowed as argument to the DEF function", tzName ); + fatalerror( temptext ); + } + } + return (0); +} + +ULONG sym_isDefined (char *tzName) +{ + struct sSymbol *psym, + *pscope; + + if (*tzName == '.') + pscope = pScope; + else + pscope = NULL; + + psym = findsymbol (tzName, pscope); + + if (psym && (psym->nType & SYMF_DEFINED)) + return (1); + else + return (0); +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Determine if the symbol is a constant + * + */ + +ULONG sym_isConstant (char *s) +{ + struct sSymbol *psym, + *pscope; + + if (*s == '.') + pscope = pScope; + else + pscope = NULL; + + if( (psym=findsymbol(s,pscope))!=NULL ) + { + if (psym->nType & SYMF_CONST) + return (1); + } + + return (0); +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Get a string equate's value + * + */ + +char *sym_GetStringValue (char *tzSym) +{ + struct sSymbol *pSym; + + if( (pSym=sym_FindSymbol(tzSym))!=NULL ) + return (pSym->pMacro); + else + { + sprintf (temptext, "Stringsymbol '%s' not defined", tzSym); + yyerror (temptext); + } + + return (NULL); +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Return a constant symbols value + * + */ + +ULONG sym_GetConstantValue (char *s) +{ + struct sSymbol *psym, + *pscope; + + if (*s == '.') + pscope = pScope; + else + pscope = NULL; + + if( (psym=findsymbol(s,pscope))!=NULL ) + { + if (psym->nType & SYMF_CONST) + return (getvaluefield (psym)); + else + { + fatalerror ("Expression must have a constant value"); + } + } + else + { + sprintf (temptext, "'%s' not defined", s); + yyerror (temptext); + } + + return (0); +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Return a symbols value... "estimated" if not defined yet + * + */ + +ULONG sym_GetValue (char *s) +{ + struct sSymbol *psym, + *pscope; + + if (*s == '.') + pscope = pScope; + else + pscope = NULL; + + if( (psym=findsymbol(s,pscope))!=NULL ) + { + if( psym->nType & SYMF_DEFINED ) + { + if( psym->nType & (SYMF_MACRO|SYMF_STRING) ) + { + sprintf (temptext, "'%s' is a macro or string symbol", s); + yyerror (temptext); + } + return (getvaluefield (psym)); + } + else + { + if ((nPass == 1) || (psym->nType & SYMF_IMPORT)) + { + /* 0x80 seems like a good default value... */ + return (0x80); + } + else + { + sprintf (temptext, "'%s' not defined", s); + yyerror (temptext); + } + } + } + else + { + if (nPass == 1) + { + createsymbol (s); + return (0x80); + } + else + { + sprintf (temptext, "'%s' not defined", s); + yyerror (temptext); + } + } + + return (0); +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Return a defined symbols value... aborts if not defined yet + * + */ + +ULONG sym_GetDefinedValue (char *s) +{ + struct sSymbol *psym, + *pscope; + + if (*s == '.') + pscope = pScope; + else + pscope = NULL; + + if( (psym=findsymbol(s,pscope))!=NULL ) + { + if( (psym->nType & SYMF_DEFINED) ) + { + if( psym->nType & (SYMF_MACRO|SYMF_STRING) ) + { + sprintf (temptext, "'%s' is a macro or string symbol", s); + yyerror (temptext); + } + + return (getvaluefield (psym)); + } + else + { + sprintf (temptext, "'%s' not defined", s); + yyerror (temptext); + } + } + else + { + sprintf (temptext, "'%s' not defined", s); + yyerror (temptext); + } + + return (0); +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Macro argument stuff + * + */ + +void sym_ShiftCurrentMacroArgs (void) +{ + SLONG i; + + free (currentmacroargs[0]); + for (i = 0; i < MAXMACROARGS - 1; i += 1) + { + currentmacroargs[i] = currentmacroargs[i + 1]; + } + currentmacroargs[MAXMACROARGS - 1] = NULL; +} + +char *sym_FindMacroArg (SLONG i) +{ + if (i == -1) + i = MAXMACROARGS + 1; + + return (currentmacroargs[i - 1]); +} + +void sym_UseNewMacroArgs (void) +{ + SLONG i; + + for (i = 0; i <= MAXMACROARGS; i += 1) + { + currentmacroargs[i] = newmacroargs[i]; + newmacroargs[i] = NULL; + } +} + +void sym_SaveCurrentMacroArgs (char *save[]) +{ + SLONG i; + + for (i = 0; i <= MAXMACROARGS; i += 1) + save[i] = currentmacroargs[i]; +} + +void sym_RestoreCurrentMacroArgs (char *save[]) +{ + SLONG i; + + for (i = 0; i <= MAXMACROARGS; i += 1) + currentmacroargs[i] = save[i]; +} + +void sym_FreeCurrentMacroArgs (void) +{ + SLONG i; + + for (i = 0; i <= MAXMACROARGS; i += 1) + { + free (currentmacroargs[i]); + currentmacroargs[i] = NULL; + } +} + +void sym_AddNewMacroArg (char *s) +{ + SLONG i = 0; + + while (i < MAXMACROARGS && newmacroargs[i] != NULL) + i += 1; + + if (i < MAXMACROARGS) + { + if (s) + newmacroargs[i] = strdup (s); + else + newmacroargs[i] = NULL; + } + else + yyerror ("A maximum of 9 arguments allowed"); +} + +void sym_SetMacroArgID (ULONG nMacroCount) +{ + char s[256]; + + sprintf(s, "_%ld", nMacroCount); + newmacroargs[MAXMACROARGS] = strdup (s); +} + +void sym_UseCurrentMacroArgs (void) +{ + SLONG i; + + for (i = 1; i <= MAXMACROARGS; i += 1) + sym_AddNewMacroArg (sym_FindMacroArg (i)); +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Find a macro by name + * + */ + +struct sSymbol *sym_FindMacro (char *s) +{ + return (findsymbol (s, NULL)); +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Add an equated symbol + * + */ + +void sym_AddEqu (char *tzSym, SLONG value) +{ + if( (nPass==1) + || ((nPass==2)&&(sym_isDefined(tzSym)==0)) ) + { + /* only add equated symbols in pass 1 */ + struct sSymbol *nsym; + + if( (nsym=findsymbol(tzSym,NULL))!=NULL ) + { + if (nsym->nType & SYMF_DEFINED) + { + sprintf (temptext, "'%s' already defined", tzSym); + yyerror (temptext); + } + } + else + nsym = createsymbol (tzSym); + + if (nsym) + { + nsym->nValue = value; + nsym->nType |= SYMF_EQU | SYMF_DEFINED | SYMF_CONST; + nsym->pScope = NULL; + } + } +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Add a string equated symbol + * + */ + +void sym_AddString (char *tzSym, char *tzValue) +{ + struct sSymbol *nsym; + + if( (nsym=findsymbol(tzSym,NULL))!=NULL ) + { + if (nsym->nType & SYMF_DEFINED) + { + sprintf (temptext, "'%s' already defined", tzSym); + yyerror (temptext); + } + } + else + nsym = createsymbol (tzSym); + + if (nsym) + { + if( (nsym->pMacro=(char *)malloc(strlen(tzValue)+1))!=NULL ) + strcpy (nsym->pMacro, tzValue); + else + fatalerror ("No memory for stringequate"); + nsym->nType |= SYMF_STRING | SYMF_DEFINED; + nsym->ulMacroSize = strlen( tzValue ); + nsym->pScope = NULL; + } +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * check if symbol is a string equated symbol + * + */ + +ULONG sym_isString (char *tzSym) +{ + struct sSymbol *pSym; + + if( (pSym=findsymbol(tzSym,NULL))!=NULL ) + { + if (pSym->nType & SYMF_STRING) + return (1); + } + return (0); +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Alter a SET symbols value + * + */ + +void sym_AddSet (char *tzSym, SLONG value) +{ + struct sSymbol *nsym; + + if( (nsym=findsymbol(tzSym,NULL))!=NULL ) + { + } + else + nsym = createsymbol (tzSym); + + if (nsym) + { + nsym->nValue = value; + nsym->nType |= SYMF_SET | SYMF_DEFINED | SYMF_CONST; + nsym->pScope = NULL; + } +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Add a local (.name) relocatable symbol + * + */ + +void sym_AddLocalReloc (char *tzSym) +{ + if( (nPass==1) + || ((nPass==2)&&(sym_isDefined(tzSym)==0)) ) + { + /* only add local reloc symbols in pass 1 */ + struct sSymbol *nsym; + + if (pScope) + { + if( (nsym=findsymbol(tzSym,pScope))!=NULL ) + { + if (nsym->nType & SYMF_DEFINED) + { + sprintf (temptext, "'%s' already defined", tzSym); + yyerror (temptext); + } + } + else + nsym = createsymbol (tzSym); + + if (nsym) + { + nsym->nValue = nPC; + nsym->nType |= SYMF_RELOC | SYMF_LOCAL | SYMF_DEFINED; + nsym->pScope = pScope; + nsym->pSection = pCurrentSection; + } + } + else + fatalerror ("Local label in main scope"); + } +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Add a relocatable symbol + * + */ + +void sym_AddReloc (char *tzSym) +{ + if( (nPass==1) + || ((nPass==2)&&(sym_isDefined(tzSym)==0)) ) + { + /* only add reloc symbols in pass 1 */ + struct sSymbol *nsym; + + if( (nsym=findsymbol(tzSym,NULL))!=NULL ) + { + if (nsym->nType & SYMF_DEFINED) + { + sprintf (temptext, "'%s' already defined", tzSym); + yyerror (temptext); + } + } + else + nsym = createsymbol (tzSym); + + if (nsym) + { + nsym->nValue = nPC; + nsym->nType |= SYMF_RELOC | SYMF_DEFINED; + nsym->pScope = NULL; + nsym->pSection = pCurrentSection; + } + } + pScope = findsymbol (tzSym, NULL); + +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Export a symbol + * + */ + +void sym_Export (char *tzSym) +{ + if (nPass == 1) + { + /* only export symbols in pass 1 */ + struct sSymbol *nsym; + + if ((nsym = findsymbol (tzSym, 0)) == NULL) + nsym = createsymbol (tzSym); + + if (nsym) + nsym->nType |= SYMF_EXPORT; + } + else + { + struct sSymbol *nsym; + + if( (nsym=findsymbol(tzSym,0))!=NULL ) + { + if (nsym->nType & SYMF_DEFINED) + return; + } + sprintf (temptext, "'%s' not defined", tzSym); + yyerror (temptext); + } + +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Import a symbol + * + */ + +void sym_Import (char *tzSym) +{ + if (nPass == 1) + { + /* only import symbols in pass 1 */ + struct sSymbol *nsym; + + if (findsymbol (tzSym, NULL)) + { + sprintf (temptext, "'%s' already defined", tzSym); + yyerror (temptext); + } + + if( (nsym=createsymbol(tzSym))!=NULL ) + nsym->nType |= SYMF_IMPORT; + } +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Globalize a symbol (export if defined, import if not) + * + */ + +void sym_Global (char *tzSym) +{ + if (nPass == 2) + { + /* only globalize symbols in pass 2 */ + struct sSymbol *nsym; + + nsym = findsymbol (tzSym, 0); + + if ((nsym == NULL) || ((nsym->nType & SYMF_DEFINED) == 0)) + { + if (nsym == NULL) + nsym = createsymbol (tzSym); + + if (nsym) + nsym->nType |= SYMF_IMPORT; + } + else + { + if (nsym) + nsym->nType |= SYMF_EXPORT; + } + } +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Add a macro definition + * + */ + +void sym_AddMacro (char *tzSym) +{ + if( (nPass==1) + || ((nPass==2)&&(sym_isDefined(tzSym)==0)) ) + { + /* only add macros in pass 1 */ + struct sSymbol *nsym; + + if( (nsym=findsymbol(tzSym,NULL))!=NULL ) + { + if (nsym->nType & SYMF_DEFINED) + { + sprintf (temptext, "'%s' already defined", tzSym); + yyerror (temptext); + } + } + else + nsym = createsymbol (tzSym); + + if (nsym) + { + nsym->nValue = nPC; + nsym->nType |= SYMF_MACRO | SYMF_DEFINED; + nsym->pScope = NULL; + nsym->ulMacroSize = ulNewMacroSize; + nsym->pMacro = tzNewMacro; + } + } +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Prepare for pass #1 + * + */ + +void sym_PrepPass1 (void) +{ + sym_Init (); +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Prepare for pass #2 + * + */ + +void sym_PrepPass2 (void) +{ + SLONG i; + + for (i = 0; i < HASHSIZE; i += 1) + { + struct sSymbol **ppSym = &(tHashedSymbols[i]); + + while (*ppSym) + { + if ((*ppSym)->nType & (SYMF_SET | SYMF_STRING | SYMF_EQU)) + { + struct sSymbol *pTemp; + + pTemp = (*ppSym)->pNext; + free (*ppSym); + *ppSym = pTemp; + } + else + ppSym = &((*ppSym)->pNext); + } + } + pScope = NULL; + pPCSymbol->nValue = 0; + + sym_AddString ("__TIME__", SavedTIME); + sym_AddString ("__DATE__", SavedDATE); + sym_AddSet( "_RS", 0 ); +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * Initialise the symboltable + * + */ + +void sym_Init (void) +{ + SLONG i; + time_t tod; + + for (i = 0; i < MAXMACROARGS; i += 1) + { + currentmacroargs[i] = NULL; + newmacroargs[i] = NULL; + } + + for (i = 0; i < HASHSIZE; i += 1) + tHashedSymbols[i] = NULL; + + sym_AddReloc ("@"); + pPCSymbol = findsymbol ("@", NULL); + sym_AddEqu ("_NARG", 0); + p_NARGSymbol = findsymbol ("_NARG", NULL); + p_NARGSymbol->Callback = Callback_NARG; + sym_AddEqu ("__LINE__", 0); + p__LINE__Symbol = findsymbol ("__LINE__", NULL); + p__LINE__Symbol->Callback = Callback__LINE__; + + sym_AddEqu( "__ASM__", (SLONG) (atof (ASM_VERSION) * 65536)); + sym_AddSet( "_RS", 0 ); + + if( time(&tod)!=-1 ) + { + struct tm *tptr; + + tptr=localtime( &tod ); + strftime( SavedTIME, sizeof(SavedTIME), "%H:%M:%S", tptr ); + strftime( SavedDATE, sizeof(SavedDATE), "%d %B %Y", tptr ); + sym_AddString ("__TIME__", SavedTIME); + sym_AddString ("__DATE__", SavedDATE); + } + + pScope = NULL; + + math_DefinePI (); + +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * DEBUG: Print the symbol table + * + */ + +void sym_PrintSymbolTable (void) +{ + ULONG i; + + for (i = 0; i < HASHSIZE; i += 1) + { + struct sSymbol *sym = tHashedSymbols[i]; + + if (sym != NULL) + printf ("\nHashTable #%ld:\n", i); + + while (sym != NULL) + { + if (sym->nType & SYMF_LOCAL) + printf ("LOCAL : '%s%s' - %08lX\n", sym->pScope->tzName, sym->tzName, getvaluefield (sym)); + else if (sym->nType & (SYMF_MACRO | SYMF_STRING)) + { + ULONG i = 0; + + printf ("MACRO : '%s'\n\"", sym->tzName); + while (i < sym->ulMacroSize) + { + if (sym->pMacro[i] == '\n') + { + printf ("\n"); + i += 1; + } + else + printf ("%c", sym->pMacro[i++]); + } + printf ("\"\n"); + } + else if (sym->nType & SYMF_EXPORT) + printf ("EXPORT: '%s' - %08lX\n", sym->tzName, getvaluefield (sym)); + else if (sym->nType & SYMF_IMPORT) + printf ("IMPORT: '%s'\n", sym->tzName); + else if (sym->nType & SYMF_EQU) + printf ("EQU : '%s' - %08lX\n", sym->tzName, getvaluefield (sym)); + else if (sym->nType & SYMF_SET) + printf ("SET : '%s' - %08lX\n", sym->tzName, getvaluefield (sym)); + else + printf ("SYMBOL: '%s' - %08lX\n", sym->tzName, getvaluefield (sym)); + + sym = sym->pNext; + } + } +} + +/* + * RGBAsm - SYMBOL.C - Symboltable stuff + * + * DEBUG: Dump the macroargs + * + */ + +void sym_DumpMacroArgs (void) +{ + ULONG i; + + for (i = 0; i < MAXMACROARGS; i += 1) + printf ("CurrentArg%ld: %s\n", i + 1, currentmacroargs[i]); } \ No newline at end of file diff --git a/src/asm/yaccprt3.y b/src/asm/yaccprt3.y index 10de4596..3707f4b5 100644 --- a/src/asm/yaccprt3.y +++ b/src/asm/yaccprt3.y @@ -1,532 +1,532 @@ -%start asmfile - -%% - -asmfile : lines lastline -; - -lastline : /* empty */ - | line - { nLineNo+=1; nTotalLines+=1; } -; - -lines : /* empty */ - | lines line '\n' - { nLineNo+=1; nTotalLines+=1; } -; - -line : /* empty */ - | label - | label cpu_command - | label macro - | label simple_pseudoop - | pseudoop -; - -label : /* empty */ - | T_LABEL { if( $1[0]=='.' ) - sym_AddLocalReloc($1); - else - sym_AddReloc($1); - } - | T_LABEL ':' { if( $1[0]=='.' ) - sym_AddLocalReloc($1); - else - sym_AddReloc($1); - } - | T_LABEL ':' ':' { sym_AddReloc($1); sym_Export($1); } -; - -macro : T_ID - { - yy_set_state( LEX_STATE_MACROARGS ); - } - macroargs - { - yy_set_state( LEX_STATE_NORMAL ); - - if( !fstk_RunMacro($1) ) - { - yyerror( "No such macro" ); - } - } -; - -macroargs : /* empty */ - | macroarg - | macroarg ',' macroargs -; - -macroarg : T_STRING - { sym_AddNewMacroArg( $1 ); } -; - -pseudoop : equ - | set - | rb - | rw - | rl - | equs - | macrodef -; - -simple_pseudoop : include - | printf - | printt - | printv - | if - | else - | endc - | import - | export - | global - | db - | dw - | dl - | ds - | section - | rsreset - | rsset - | incbin - | rept - | shift - | fail - | warn - | purge - | pops - | pushs - | popo - | pusho - | opt -; - -opt : T_POP_OPT - { - yy_set_state( LEX_STATE_MACROARGS ); - } - opt_list - { - yy_set_state( LEX_STATE_NORMAL ); - } -; - -opt_list : opt_list_entry - | opt_list_entry ',' opt_list -; - -opt_list_entry : T_STRING - { - opt_Parse($1); - } -; - -popo : T_POP_POPO - { opt_Pop(); } -; - -pusho : T_POP_PUSHO - { opt_Push(); } -; - -pops : T_POP_POPS - { out_PopSection(); } -; - -pushs : T_POP_PUSHS - { out_PushSection(); } -; - -fail : T_POP_FAIL string - { fatalerror($2); } -; - -warn : T_POP_WARN string - { yyerror($2); } -; - -shift : T_POP_SHIFT - { sym_ShiftCurrentMacroArgs(); } -; - -rept : T_POP_REPT const - { - copyrept(); - fstk_RunRept( $2 ); - } -; - -macrodef : T_LABEL ':' T_POP_MACRO - { - copymacro(); - sym_AddMacro($1); - } -; - -equs : T_LABEL T_POP_EQUS string - { sym_AddString( $1, $3 ); } -; - -rsset : T_POP_RSSET const - { sym_AddSet( "_RS", $2 ); } -; - -rsreset : T_POP_RSRESET - { sym_AddSet( "_RS", 0 ); } -; - -rl : T_LABEL T_POP_RL const - { - sym_AddEqu( $1, sym_GetConstantValue("_RS") ); - sym_AddSet( "_RS", sym_GetConstantValue("_RS")+4*$3 ); - } -; - -rw : T_LABEL T_POP_RW const - { - sym_AddEqu( $1, sym_GetConstantValue("_RS") ); - sym_AddSet( "_RS", sym_GetConstantValue("_RS")+2*$3 ); - } -; - -rb : T_LABEL T_POP_RB const - { - sym_AddEqu( $1, sym_GetConstantValue("_RS") ); - sym_AddSet( "_RS", sym_GetConstantValue("_RS")+$3 ); - } -; - -ds : T_POP_DS const - { out_Skip( $2 ); } -; - -db : T_POP_DB constlist_8bit -; - -dw : T_POP_DW constlist_16bit -; - -dl : T_POP_DL constlist_32bit -; - -purge : T_POP_PURGE - { - oDontExpandStrings=1; - } - purge_list - { - oDontExpandStrings=0; - } -; - -purge_list : purge_list_entry - | purge_list_entry ',' purge_list -; - -purge_list_entry : T_ID { sym_Purge($1); } -; - -import : T_POP_IMPORT import_list -; - -import_list : import_list_entry - | import_list_entry ',' import_list -; - -import_list_entry : T_ID { sym_Import($1); } -; - -export : T_POP_EXPORT export_list -; - -export_list : export_list_entry - | export_list_entry ',' export_list -; - -export_list_entry : T_ID { sym_Export($1); } -; - -global : T_POP_GLOBAL global_list -; - -global_list : global_list_entry - | global_list_entry ',' global_list -; - -global_list_entry : T_ID { sym_Global($1); } -; - -equ : T_LABEL T_POP_EQU const - { sym_AddEqu( $1, $3 ); } -; - -set : T_LABEL T_POP_SET const - { sym_AddSet( $1, $3 ); } -; - -include : T_POP_INCLUDE string - { - if( !fstk_RunInclude($2) ) - { - yyerror( "File not found" ); - } - } -; - -incbin : T_POP_INCBIN string - { out_BinaryFile( $2 ); } -; - -printt : T_POP_PRINTT string - { - if( nPass==1 ) - printf( "%s", $2 ); - } -; - -printv : T_POP_PRINTV const - { - if( nPass==1 ) - printf( "$%lX", $2 ); - } -; - -printf : T_POP_PRINTF const - { - if( nPass==1 ) - math_Print( $2 ); - } -; - -if : T_POP_IF const - { - nIFDepth+=1; - if( !$2 ) - { - if_skip_to_else(); /* will continue parsing just after ELSE or just at ENDC keyword */ - } - } - -else : T_POP_ELSE - { - if_skip_to_endc(); /* will continue parsing just at ENDC keyword */ - } -; - -endc : T_POP_ENDC - { - nIFDepth-=1; - } -; - -const_3bit : const - { - if( ($1<0) || ($1>7) ) - { - yyerror( "Immediate value must be 3-bit" ); - } - else - $$=$1&0x7; - } -; - -constlist_8bit : constlist_8bit_entry - | constlist_8bit_entry ',' constlist_8bit -; - -constlist_8bit_entry : { out_Skip( 1 ); } - | const_8bit { out_RelByte( &$1 ); } - | string { out_String( $1 ); } -; - -constlist_16bit : constlist_16bit_entry - | constlist_16bit_entry ',' constlist_16bit -; - -constlist_16bit_entry : { out_Skip( 2 ); } - | const_16bit { out_RelWord( &$1 ); } -; - - -constlist_32bit : constlist_32bit_entry - | constlist_32bit_entry ',' constlist_32bit -; - -constlist_32bit_entry : { out_Skip( 4 ); } - | relocconst { out_RelLong( &$1 ); } -; - - -const_PCrel : relocconst - { - $$ = $1; - if( !rpn_isPCRelative(&$1) ) - yyerror( "Expression must be PC-relative" ); - } -; - -const_8bit : relocconst - { - if( (!rpn_isReloc(&$1)) && (($1.nVal<-128) || ($1.nVal>255)) ) - { - yyerror( "Expression must be 8-bit" ); - } - $$=$1; - } -; - -const_16bit : relocconst - { - if( (!rpn_isReloc(&$1)) && (($1.nVal<-32768) || ($1.nVal>65535)) ) - { - yyerror( "Expression must be 16-bit" ); - } - $$=$1 - } -; - - -relocconst : T_ID - { rpn_Symbol(&$$,$1); $$.nVal = sym_GetValue($1); } - | T_NUMBER - { rpn_Number(&$$,$1); $$.nVal = $1; } - | string - { ULONG r; r=str2int($1); rpn_Number(&$$,r); $$.nVal=r; } - | T_OP_LOGICNOT relocconst %prec NEG - { rpn_LOGNOT(&$$,&$2); } - | relocconst T_OP_LOGICOR relocconst - { rpn_LOGOR(&$$,&$1,&$3); } - | relocconst T_OP_LOGICAND relocconst - { rpn_LOGAND(&$$,&$1,&$3); } - | relocconst T_OP_LOGICEQU relocconst - { rpn_LOGEQU(&$$,&$1,&$3); } - | relocconst T_OP_LOGICGT relocconst - { rpn_LOGGT(&$$,&$1,&$3); } - | relocconst T_OP_LOGICLT relocconst - { rpn_LOGLT(&$$,&$1,&$3); } - | relocconst T_OP_LOGICGE relocconst - { rpn_LOGGE(&$$,&$1,&$3); } - | relocconst T_OP_LOGICLE relocconst - { rpn_LOGLE(&$$,&$1,&$3); } - | relocconst T_OP_LOGICNE relocconst - { rpn_LOGNE(&$$,&$1,&$3); } - | relocconst T_OP_ADD relocconst - { rpn_ADD(&$$,&$1,&$3); } - | relocconst T_OP_SUB relocconst - { rpn_SUB(&$$,&$1,&$3); } - | relocconst T_OP_XOR relocconst - { rpn_XOR(&$$,&$1,&$3); } - | relocconst T_OP_OR relocconst - { rpn_OR(&$$,&$1,&$3); } - | relocconst T_OP_AND relocconst - { rpn_AND(&$$,&$1,&$3); } - | relocconst T_OP_SHL relocconst - { rpn_SHL(&$$,&$1,&$3); } - | relocconst T_OP_SHR relocconst - { rpn_SHR(&$$,&$1,&$3); } - | relocconst T_OP_MUL relocconst - { rpn_MUL(&$$,&$1,&$3); } - | relocconst T_OP_DIV relocconst - { rpn_DIV(&$$,&$1,&$3); } - | relocconst T_OP_MOD relocconst - { rpn_MOD(&$$,&$1,&$3); } - | T_OP_ADD relocconst %prec NEG - { $$ = $2; } - | T_OP_SUB relocconst %prec NEG - { rpn_UNNEG(&$$,&$2); } - | T_OP_NOT relocconst %prec NEG - { rpn_UNNOT(&$$,&$2); } - | T_OP_BANK '(' T_ID ')' - { rpn_Bank(&$$,$3); $$.nVal = 0; } - | T_OP_DEF '(' T_ID ')' - { rpn_Number(&$$,sym_isConstDefined($3)); } - | T_OP_FDIV '(' const ',' const ')' { rpn_Number(&$$,math_Div($3,$5)); } - | T_OP_FMUL '(' const ',' const ')' { rpn_Number(&$$,math_Mul($3,$5)); } - | T_OP_SIN '(' const ')' { rpn_Number(&$$,math_Sin($3)); } - | T_OP_COS '(' const ')' { rpn_Number(&$$,math_Cos($3)); } - | T_OP_TAN '(' const ')' { rpn_Number(&$$,math_Tan($3)); } - | T_OP_ASIN '(' const ')' { rpn_Number(&$$,math_ASin($3)); } - | T_OP_ACOS '(' const ')' { rpn_Number(&$$,math_ACos($3)); } - | T_OP_ATAN '(' const ')' { rpn_Number(&$$,math_ATan($3)); } - | T_OP_ATAN2 '(' const ',' const ')' { rpn_Number(&$$,math_ATan2($3,$5)); } - | T_OP_STRCMP '(' string ',' string ')' { rpn_Number(&$$,strcmp($3,$5)); } - | T_OP_STRIN '(' string ',' string ')' - { - char *p; - if( (p=strstr($3,$5))!=NULL ) - { - rpn_Number(&$$,p-$3+1); - } - else - { - rpn_Number(&$$,0); - } - } - | T_OP_STRLEN '(' string ')' { rpn_Number(&$$,strlen($3)); } - | '(' relocconst ')' - { $$ = $2; } -; - -const : T_ID { $$ = sym_GetConstantValue($1); } - | T_NUMBER { $$ = $1; } - | string { $$ = str2int($1); } - | T_OP_LOGICNOT const %prec NEG { $$ = !$2; } - | const T_OP_LOGICOR const { $$ = $1 || $3; } - | const T_OP_LOGICAND const { $$ = $1 && $3; } - | const T_OP_LOGICEQU const { $$ = $1 == $3; } - | const T_OP_LOGICGT const { $$ = $1 > $3; } - | const T_OP_LOGICLT const { $$ = $1 < $3; } - | const T_OP_LOGICGE const { $$ = $1 >= $3; } - | const T_OP_LOGICLE const { $$ = $1 <= $3; } - | const T_OP_LOGICNE const { $$ = $1 != $3; } - | const T_OP_ADD const { $$ = $1 + $3; } - | const T_OP_SUB const { $$ = $1 - $3; } - | T_ID T_OP_SUB T_ID { $$ = sym_GetDefinedValue($1) - sym_GetDefinedValue($3); } - | const T_OP_XOR const { $$ = $1 ^ $3; } - | const T_OP_OR const { $$ = $1 | $3; } - | const T_OP_AND const { $$ = $1 & $3; } - | const T_OP_SHL const { $$ = $1 << $3; } - | const T_OP_SHR const { $$ = $1 >> $3; } - | const T_OP_MUL const { $$ = $1 * $3; } - | const T_OP_DIV const { $$ = $1 / $3; } - | const T_OP_MOD const { $$ = $1 % $3; } - | T_OP_ADD const %prec NEG { $$ = +$2; } - | T_OP_SUB const %prec NEG { $$ = -$2; } - | T_OP_NOT const %prec NEG { $$ = 0xFFFFFFFF^$2; } - | T_OP_FDIV '(' const ',' const ')' { $$ = math_Div($3,$5); } - | T_OP_FMUL '(' const ',' const ')' { $$ = math_Mul($3,$5); } - | T_OP_SIN '(' const ')' { $$ = math_Sin($3); } - | T_OP_COS '(' const ')' { $$ = math_Cos($3); } - | T_OP_TAN '(' const ')' { $$ = math_Tan($3); } - | T_OP_ASIN '(' const ')' { $$ = math_ASin($3); } - | T_OP_ACOS '(' const ')' { $$ = math_ACos($3); } - | T_OP_ATAN '(' const ')' { $$ = math_ATan($3); } - | T_OP_ATAN2 '(' const ',' const ')' { $$ = math_ATan2($3,$5); } - | T_OP_DEF '(' T_ID ')' { $$ = sym_isConstDefined($3); } - | T_OP_STRCMP '(' string ',' string ')' { $$ = strcmp( $3, $5 ); } - | T_OP_STRIN '(' string ',' string ')' - { - char *p; - if( (p=strstr($3,$5))!=NULL ) - { - $$ = p-$3+1; - } - else - { - $$ = 0; - } - } - | T_OP_STRLEN '(' string ')' { $$ = strlen($3); } - | '(' const ')' { $$ = $2; } -; - -string : T_STRING - { strcpy($$,$1); } - | T_OP_STRSUB '(' string ',' const ',' const ')' - { strncpy($$,$3+$5-1,$7); $$[$7]=0; } - | T_OP_STRCAT '(' string ',' string ')' - { strcpy($$,$3); strcat($$,$5); } - | T_OP_STRUPR '(' string ')' - { strcpy($$,$3); strupr($$); } - | T_OP_STRLWR '(' string ')' - { strcpy($$,$3); strlwr($$); } +%start asmfile + +%% + +asmfile : lines lastline +; + +lastline : /* empty */ + | line + { nLineNo+=1; nTotalLines+=1; } +; + +lines : /* empty */ + | lines line '\n' + { nLineNo+=1; nTotalLines+=1; } +; + +line : /* empty */ + | label + | label cpu_command + | label macro + | label simple_pseudoop + | pseudoop +; + +label : /* empty */ + | T_LABEL { if( $1[0]=='.' ) + sym_AddLocalReloc($1); + else + sym_AddReloc($1); + } + | T_LABEL ':' { if( $1[0]=='.' ) + sym_AddLocalReloc($1); + else + sym_AddReloc($1); + } + | T_LABEL ':' ':' { sym_AddReloc($1); sym_Export($1); } +; + +macro : T_ID + { + yy_set_state( LEX_STATE_MACROARGS ); + } + macroargs + { + yy_set_state( LEX_STATE_NORMAL ); + + if( !fstk_RunMacro($1) ) + { + yyerror( "No such macro" ); + } + } +; + +macroargs : /* empty */ + | macroarg + | macroarg ',' macroargs +; + +macroarg : T_STRING + { sym_AddNewMacroArg( $1 ); } +; + +pseudoop : equ + | set + | rb + | rw + | rl + | equs + | macrodef +; + +simple_pseudoop : include + | printf + | printt + | printv + | if + | else + | endc + | import + | export + | global + | db + | dw + | dl + | ds + | section + | rsreset + | rsset + | incbin + | rept + | shift + | fail + | warn + | purge + | pops + | pushs + | popo + | pusho + | opt +; + +opt : T_POP_OPT + { + yy_set_state( LEX_STATE_MACROARGS ); + } + opt_list + { + yy_set_state( LEX_STATE_NORMAL ); + } +; + +opt_list : opt_list_entry + | opt_list_entry ',' opt_list +; + +opt_list_entry : T_STRING + { + opt_Parse($1); + } +; + +popo : T_POP_POPO + { opt_Pop(); } +; + +pusho : T_POP_PUSHO + { opt_Push(); } +; + +pops : T_POP_POPS + { out_PopSection(); } +; + +pushs : T_POP_PUSHS + { out_PushSection(); } +; + +fail : T_POP_FAIL string + { fatalerror($2); } +; + +warn : T_POP_WARN string + { yyerror($2); } +; + +shift : T_POP_SHIFT + { sym_ShiftCurrentMacroArgs(); } +; + +rept : T_POP_REPT const + { + copyrept(); + fstk_RunRept( $2 ); + } +; + +macrodef : T_LABEL ':' T_POP_MACRO + { + copymacro(); + sym_AddMacro($1); + } +; + +equs : T_LABEL T_POP_EQUS string + { sym_AddString( $1, $3 ); } +; + +rsset : T_POP_RSSET const + { sym_AddSet( "_RS", $2 ); } +; + +rsreset : T_POP_RSRESET + { sym_AddSet( "_RS", 0 ); } +; + +rl : T_LABEL T_POP_RL const + { + sym_AddEqu( $1, sym_GetConstantValue("_RS") ); + sym_AddSet( "_RS", sym_GetConstantValue("_RS")+4*$3 ); + } +; + +rw : T_LABEL T_POP_RW const + { + sym_AddEqu( $1, sym_GetConstantValue("_RS") ); + sym_AddSet( "_RS", sym_GetConstantValue("_RS")+2*$3 ); + } +; + +rb : T_LABEL T_POP_RB const + { + sym_AddEqu( $1, sym_GetConstantValue("_RS") ); + sym_AddSet( "_RS", sym_GetConstantValue("_RS")+$3 ); + } +; + +ds : T_POP_DS const + { out_Skip( $2 ); } +; + +db : T_POP_DB constlist_8bit +; + +dw : T_POP_DW constlist_16bit +; + +dl : T_POP_DL constlist_32bit +; + +purge : T_POP_PURGE + { + oDontExpandStrings=1; + } + purge_list + { + oDontExpandStrings=0; + } +; + +purge_list : purge_list_entry + | purge_list_entry ',' purge_list +; + +purge_list_entry : T_ID { sym_Purge($1); } +; + +import : T_POP_IMPORT import_list +; + +import_list : import_list_entry + | import_list_entry ',' import_list +; + +import_list_entry : T_ID { sym_Import($1); } +; + +export : T_POP_EXPORT export_list +; + +export_list : export_list_entry + | export_list_entry ',' export_list +; + +export_list_entry : T_ID { sym_Export($1); } +; + +global : T_POP_GLOBAL global_list +; + +global_list : global_list_entry + | global_list_entry ',' global_list +; + +global_list_entry : T_ID { sym_Global($1); } +; + +equ : T_LABEL T_POP_EQU const + { sym_AddEqu( $1, $3 ); } +; + +set : T_LABEL T_POP_SET const + { sym_AddSet( $1, $3 ); } +; + +include : T_POP_INCLUDE string + { + if( !fstk_RunInclude($2) ) + { + yyerror( "File not found" ); + } + } +; + +incbin : T_POP_INCBIN string + { out_BinaryFile( $2 ); } +; + +printt : T_POP_PRINTT string + { + if( nPass==1 ) + printf( "%s", $2 ); + } +; + +printv : T_POP_PRINTV const + { + if( nPass==1 ) + printf( "$%lX", $2 ); + } +; + +printf : T_POP_PRINTF const + { + if( nPass==1 ) + math_Print( $2 ); + } +; + +if : T_POP_IF const + { + nIFDepth+=1; + if( !$2 ) + { + if_skip_to_else(); /* will continue parsing just after ELSE or just at ENDC keyword */ + } + } + +else : T_POP_ELSE + { + if_skip_to_endc(); /* will continue parsing just at ENDC keyword */ + } +; + +endc : T_POP_ENDC + { + nIFDepth-=1; + } +; + +const_3bit : const + { + if( ($1<0) || ($1>7) ) + { + yyerror( "Immediate value must be 3-bit" ); + } + else + $$=$1&0x7; + } +; + +constlist_8bit : constlist_8bit_entry + | constlist_8bit_entry ',' constlist_8bit +; + +constlist_8bit_entry : { out_Skip( 1 ); } + | const_8bit { out_RelByte( &$1 ); } + | string { out_String( $1 ); } +; + +constlist_16bit : constlist_16bit_entry + | constlist_16bit_entry ',' constlist_16bit +; + +constlist_16bit_entry : { out_Skip( 2 ); } + | const_16bit { out_RelWord( &$1 ); } +; + + +constlist_32bit : constlist_32bit_entry + | constlist_32bit_entry ',' constlist_32bit +; + +constlist_32bit_entry : { out_Skip( 4 ); } + | relocconst { out_RelLong( &$1 ); } +; + + +const_PCrel : relocconst + { + $$ = $1; + if( !rpn_isPCRelative(&$1) ) + yyerror( "Expression must be PC-relative" ); + } +; + +const_8bit : relocconst + { + if( (!rpn_isReloc(&$1)) && (($1.nVal<-128) || ($1.nVal>255)) ) + { + yyerror( "Expression must be 8-bit" ); + } + $$=$1; + } +; + +const_16bit : relocconst + { + if( (!rpn_isReloc(&$1)) && (($1.nVal<-32768) || ($1.nVal>65535)) ) + { + yyerror( "Expression must be 16-bit" ); + } + $$=$1 + } +; + + +relocconst : T_ID + { rpn_Symbol(&$$,$1); $$.nVal = sym_GetValue($1); } + | T_NUMBER + { rpn_Number(&$$,$1); $$.nVal = $1; } + | string + { ULONG r; r=str2int($1); rpn_Number(&$$,r); $$.nVal=r; } + | T_OP_LOGICNOT relocconst %prec NEG + { rpn_LOGNOT(&$$,&$2); } + | relocconst T_OP_LOGICOR relocconst + { rpn_LOGOR(&$$,&$1,&$3); } + | relocconst T_OP_LOGICAND relocconst + { rpn_LOGAND(&$$,&$1,&$3); } + | relocconst T_OP_LOGICEQU relocconst + { rpn_LOGEQU(&$$,&$1,&$3); } + | relocconst T_OP_LOGICGT relocconst + { rpn_LOGGT(&$$,&$1,&$3); } + | relocconst T_OP_LOGICLT relocconst + { rpn_LOGLT(&$$,&$1,&$3); } + | relocconst T_OP_LOGICGE relocconst + { rpn_LOGGE(&$$,&$1,&$3); } + | relocconst T_OP_LOGICLE relocconst + { rpn_LOGLE(&$$,&$1,&$3); } + | relocconst T_OP_LOGICNE relocconst + { rpn_LOGNE(&$$,&$1,&$3); } + | relocconst T_OP_ADD relocconst + { rpn_ADD(&$$,&$1,&$3); } + | relocconst T_OP_SUB relocconst + { rpn_SUB(&$$,&$1,&$3); } + | relocconst T_OP_XOR relocconst + { rpn_XOR(&$$,&$1,&$3); } + | relocconst T_OP_OR relocconst + { rpn_OR(&$$,&$1,&$3); } + | relocconst T_OP_AND relocconst + { rpn_AND(&$$,&$1,&$3); } + | relocconst T_OP_SHL relocconst + { rpn_SHL(&$$,&$1,&$3); } + | relocconst T_OP_SHR relocconst + { rpn_SHR(&$$,&$1,&$3); } + | relocconst T_OP_MUL relocconst + { rpn_MUL(&$$,&$1,&$3); } + | relocconst T_OP_DIV relocconst + { rpn_DIV(&$$,&$1,&$3); } + | relocconst T_OP_MOD relocconst + { rpn_MOD(&$$,&$1,&$3); } + | T_OP_ADD relocconst %prec NEG + { $$ = $2; } + | T_OP_SUB relocconst %prec NEG + { rpn_UNNEG(&$$,&$2); } + | T_OP_NOT relocconst %prec NEG + { rpn_UNNOT(&$$,&$2); } + | T_OP_BANK '(' T_ID ')' + { rpn_Bank(&$$,$3); $$.nVal = 0; } + | T_OP_DEF '(' T_ID ')' + { rpn_Number(&$$,sym_isConstDefined($3)); } + | T_OP_FDIV '(' const ',' const ')' { rpn_Number(&$$,math_Div($3,$5)); } + | T_OP_FMUL '(' const ',' const ')' { rpn_Number(&$$,math_Mul($3,$5)); } + | T_OP_SIN '(' const ')' { rpn_Number(&$$,math_Sin($3)); } + | T_OP_COS '(' const ')' { rpn_Number(&$$,math_Cos($3)); } + | T_OP_TAN '(' const ')' { rpn_Number(&$$,math_Tan($3)); } + | T_OP_ASIN '(' const ')' { rpn_Number(&$$,math_ASin($3)); } + | T_OP_ACOS '(' const ')' { rpn_Number(&$$,math_ACos($3)); } + | T_OP_ATAN '(' const ')' { rpn_Number(&$$,math_ATan($3)); } + | T_OP_ATAN2 '(' const ',' const ')' { rpn_Number(&$$,math_ATan2($3,$5)); } + | T_OP_STRCMP '(' string ',' string ')' { rpn_Number(&$$,strcmp($3,$5)); } + | T_OP_STRIN '(' string ',' string ')' + { + char *p; + if( (p=strstr($3,$5))!=NULL ) + { + rpn_Number(&$$,p-$3+1); + } + else + { + rpn_Number(&$$,0); + } + } + | T_OP_STRLEN '(' string ')' { rpn_Number(&$$,strlen($3)); } + | '(' relocconst ')' + { $$ = $2; } +; + +const : T_ID { $$ = sym_GetConstantValue($1); } + | T_NUMBER { $$ = $1; } + | string { $$ = str2int($1); } + | T_OP_LOGICNOT const %prec NEG { $$ = !$2; } + | const T_OP_LOGICOR const { $$ = $1 || $3; } + | const T_OP_LOGICAND const { $$ = $1 && $3; } + | const T_OP_LOGICEQU const { $$ = $1 == $3; } + | const T_OP_LOGICGT const { $$ = $1 > $3; } + | const T_OP_LOGICLT const { $$ = $1 < $3; } + | const T_OP_LOGICGE const { $$ = $1 >= $3; } + | const T_OP_LOGICLE const { $$ = $1 <= $3; } + | const T_OP_LOGICNE const { $$ = $1 != $3; } + | const T_OP_ADD const { $$ = $1 + $3; } + | const T_OP_SUB const { $$ = $1 - $3; } + | T_ID T_OP_SUB T_ID { $$ = sym_GetDefinedValue($1) - sym_GetDefinedValue($3); } + | const T_OP_XOR const { $$ = $1 ^ $3; } + | const T_OP_OR const { $$ = $1 | $3; } + | const T_OP_AND const { $$ = $1 & $3; } + | const T_OP_SHL const { $$ = $1 << $3; } + | const T_OP_SHR const { $$ = $1 >> $3; } + | const T_OP_MUL const { $$ = $1 * $3; } + | const T_OP_DIV const { $$ = $1 / $3; } + | const T_OP_MOD const { $$ = $1 % $3; } + | T_OP_ADD const %prec NEG { $$ = +$2; } + | T_OP_SUB const %prec NEG { $$ = -$2; } + | T_OP_NOT const %prec NEG { $$ = 0xFFFFFFFF^$2; } + | T_OP_FDIV '(' const ',' const ')' { $$ = math_Div($3,$5); } + | T_OP_FMUL '(' const ',' const ')' { $$ = math_Mul($3,$5); } + | T_OP_SIN '(' const ')' { $$ = math_Sin($3); } + | T_OP_COS '(' const ')' { $$ = math_Cos($3); } + | T_OP_TAN '(' const ')' { $$ = math_Tan($3); } + | T_OP_ASIN '(' const ')' { $$ = math_ASin($3); } + | T_OP_ACOS '(' const ')' { $$ = math_ACos($3); } + | T_OP_ATAN '(' const ')' { $$ = math_ATan($3); } + | T_OP_ATAN2 '(' const ',' const ')' { $$ = math_ATan2($3,$5); } + | T_OP_DEF '(' T_ID ')' { $$ = sym_isConstDefined($3); } + | T_OP_STRCMP '(' string ',' string ')' { $$ = strcmp( $3, $5 ); } + | T_OP_STRIN '(' string ',' string ')' + { + char *p; + if( (p=strstr($3,$5))!=NULL ) + { + $$ = p-$3+1; + } + else + { + $$ = 0; + } + } + | T_OP_STRLEN '(' string ')' { $$ = strlen($3); } + | '(' const ')' { $$ = $2; } +; + +string : T_STRING + { strcpy($$,$1); } + | T_OP_STRSUB '(' string ',' const ',' const ')' + { strncpy($$,$3+$5-1,$7); $$[$7]=0; } + | T_OP_STRCAT '(' string ',' string ')' + { strcpy($$,$3); strcat($$,$5); } + | T_OP_STRUPR '(' string ')' + { strcpy($$,$3); strupr($$); } + | T_OP_STRLWR '(' string ')' + { strcpy($$,$3); strlwr($$); } ; \ No newline at end of file diff --git a/src/asmotor.h b/src/asmotor.h index 05e349e1..c2fb7807 100644 --- a/src/asmotor.h +++ b/src/asmotor.h @@ -1,25 +1,25 @@ -/* asmotor.h - * - * Contains defines for every program in the ASMotor package - * - * Copyright 1997 Carsten Sorensen - * - */ - -#ifndef ASMOTOR_H -#define ASMOTOR_H - -#define ASMOTOR - -#define ASMOTOR_VERSION "1.10" - -#define ASM_VERSION "1.08c" -#define LINK_VERSION "1.06c" -#define RGBFIX_VERSION "1.02" -#define LIB_VERSION "1.00" - -#ifdef __GNUC__ -#define strnicmp strncasecmp -#endif - +/* asmotor.h + * + * Contains defines for every program in the ASMotor package + * + * Copyright 1997 Carsten Sorensen + * + */ + +#ifndef ASMOTOR_H +#define ASMOTOR_H + +#define ASMOTOR + +#define ASMOTOR_VERSION "1.10" + +#define ASM_VERSION "1.08c" +#define LINK_VERSION "1.06c" +#define RGBFIX_VERSION "1.02" +#define LIB_VERSION "1.00" + +#ifdef __GNUC__ +#define strnicmp strncasecmp +#endif + #endif // ASMOTOR_H \ No newline at end of file diff --git a/src/lib/include/library.h b/src/lib/include/library.h index 1e4d7fea..0e119c97 100644 --- a/src/lib/include/library.h +++ b/src/lib/include/library.h @@ -1,13 +1,13 @@ -#ifndef LIBRARY_H -#define LIBRARY_H - -#include "libwrap.h" - -extern sLibrary *lib_Read( char *filename ); -extern BBOOL lib_Write( sLibrary *lib, char *filename ); -extern sLibrary *lib_AddReplace( sLibrary *lib, char *filename ); -extern void lib_Free( sLibrary *lib ); -extern sLibrary *lib_DeleteModule( sLibrary *lib, char *filename ); -extern sLibrary *lib_Find( sLibrary *lib, char *filename ); - +#ifndef LIBRARY_H +#define LIBRARY_H + +#include "libwrap.h" + +extern sLibrary *lib_Read( char *filename ); +extern BBOOL lib_Write( sLibrary *lib, char *filename ); +extern sLibrary *lib_AddReplace( sLibrary *lib, char *filename ); +extern void lib_Free( sLibrary *lib ); +extern sLibrary *lib_DeleteModule( sLibrary *lib, char *filename ); +extern sLibrary *lib_Find( sLibrary *lib, char *filename ); + #endif \ No newline at end of file diff --git a/src/lib/include/libwrap.h b/src/lib/include/libwrap.h index 307e3e26..e1e867d3 100644 --- a/src/lib/include/libwrap.h +++ b/src/lib/include/libwrap.h @@ -1,20 +1,20 @@ -#ifndef LIBWRAP_H -#define LIBWRAP_H - -#include "types.h" - -#define MAXNAMELENGTH 256 - -struct LibraryWrapper -{ - char tName[MAXNAMELENGTH]; - UWORD uwTime; - UWORD uwDate; - SLONG nByteLength; - UBYTE *pData; - struct LibraryWrapper *pNext; -}; - -typedef struct LibraryWrapper sLibrary; - +#ifndef LIBWRAP_H +#define LIBWRAP_H + +#include "types.h" + +#define MAXNAMELENGTH 256 + +struct LibraryWrapper +{ + char tName[MAXNAMELENGTH]; + UWORD uwTime; + UWORD uwDate; + SLONG nByteLength; + UBYTE *pData; + struct LibraryWrapper *pNext; +}; + +typedef struct LibraryWrapper sLibrary; + #endif \ No newline at end of file diff --git a/src/lib/include/types.h b/src/lib/include/types.h index 7bc4679f..7c6aa1fb 100644 --- a/src/lib/include/types.h +++ b/src/lib/include/types.h @@ -1,16 +1,16 @@ -#ifndef TYPES_H -#define TYPES_H 1 - -#if defined(AMIGA) || defined(__GNUC__) -#define _MAX_PATH 512 -#endif - -typedef unsigned char UBYTE; -typedef signed char SBYTE; -typedef unsigned short UWORD; -typedef signed short SWORD; -typedef unsigned long ULONG; -typedef signed long SLONG; -typedef signed char BBOOL; - +#ifndef TYPES_H +#define TYPES_H 1 + +#if defined(AMIGA) || defined(__GNUC__) +#define _MAX_PATH 512 +#endif + +typedef unsigned char UBYTE; +typedef signed char SBYTE; +typedef unsigned short UWORD; +typedef signed short SWORD; +typedef unsigned long ULONG; +typedef signed long SLONG; +typedef signed char BBOOL; + #endif \ No newline at end of file diff --git a/src/lib/library.c b/src/lib/library.c index ee39ef54..40ba757a 100644 --- a/src/lib/library.c +++ b/src/lib/library.c @@ -1,308 +1,308 @@ -#include -#include -#include -#include "types.h" -#include "libwrap.h" - -extern void fatalerror( char *s ); - -SLONG file_Length( FILE *f ) -{ - ULONG r, - p; - - p=ftell( f ); - fseek( f, 0, SEEK_END ); - r=ftell( f ); - fseek( f, p, SEEK_SET ); - - return( r ); -} - -SLONG file_ReadASCIIz( char *b, FILE *f ) -{ - SLONG r=0; - - while( (*b++ = fgetc(f))!=0 ) - r+=1; - - return( r+1 ); -} - -void file_WriteASCIIz( char *b, FILE *f ) -{ - while( *b ) - fputc(*b++,f); - - fputc( 0, f ); -} - -UWORD file_ReadWord( FILE *f ) -{ - UWORD r; - - r =fgetc( f ); - r|=fgetc( f )<<8; - - return( r ); -} - -void file_WriteWord( UWORD w, FILE *f ) -{ - fputc( w, f ); - fputc( w>>8, f ); -} - -ULONG file_ReadLong( FILE *f ) -{ - ULONG r; - - r =fgetc( f ); - r|=fgetc( f )<<8; - r|=fgetc( f )<<16; - r|=fgetc( f )<<24; - - return( r ); -} - -void file_WriteLong( UWORD w, FILE *f ) -{ - fputc( w, f ); - fputc( w>>8, f ); - fputc( w>>16, f ); - fputc( w>>24, f ); -} - -sLibrary *lib_ReadLib0( FILE *f, SLONG size ) -{ - if( size ) - { - sLibrary *l=NULL, - *first=NULL; - - while( size>0 ) - { - if( l==NULL ) - { - if( (l=(sLibrary *)malloc(sizeof(sLibrary)))==NULL ) - fatalerror( "Out of memory" ); - - first=l; - } - else - { - if( (l->pNext=(sLibrary *)malloc(sizeof(sLibrary)))==NULL ) - fatalerror( "Out of memory" ); - l=l->pNext; - } - - size-=file_ReadASCIIz( l->tName, f ); - l->uwTime=file_ReadWord( f ); size-=2; - l->uwDate=file_ReadWord( f ); size-=2; - l->nByteLength=file_ReadLong( f ); size-=4; - if( l->pData=(UBYTE *)malloc(l->nByteLength) ) - { - fread( l->pData, sizeof(UBYTE), l->nByteLength, f ); - size-=l->nByteLength; - } - else - fatalerror( "Out of memory" ); - - l->pNext=NULL; - } - return( first ); - } - - return( NULL ); -} - -sLibrary *lib_Read( char *filename ) -{ - FILE *f; - - if( f=fopen(filename,"rb") ) - { - SLONG size; - char ID[5]; - - size=file_Length( f ); - if( size==0 ) - { - fclose( f ); - return( NULL ); - } - - fread( ID, sizeof(char), 4, f ); - ID[4]=0; - size-=4; - - if( strcmp(ID,"XLB0")==0 ) - { - sLibrary *r; - - r=lib_ReadLib0( f, size ); - fclose( f ); - printf( "Library '%s' opened\n", filename ); - return( r ); - } - else - { - fclose( f ); - fatalerror( "Not a valid xLib library" ); - return( NULL ); - } - } - else - { - printf( "Library '%s' not found, it will be created if necessary\n", filename ); - return( NULL ); - } -} - -BBOOL lib_Write( sLibrary *lib, char *filename ) -{ - FILE *f; - - if( f=fopen(filename,"wb") ) - { - fwrite( "XLB0", sizeof(char), 4, f ); - while( lib ) - { - file_WriteASCIIz( lib->tName, f ); - file_WriteWord( lib->uwTime, f ); - file_WriteWord( lib->uwDate, f ); - file_WriteLong( lib->nByteLength, f ); - fwrite( lib->pData, sizeof(UBYTE), lib->nByteLength,f ); - lib=lib->pNext; - } - - fclose( f ); - printf( "Library '%s' closed\n", filename ); - return( 1 ); - } - - return( 0 ); -} - -void TruncateFileName( char *dest, char *src ) -{ - SLONG l; - - l=strlen( src )-1; - while( (l>=0) && (src[l]!='\\') && (src[l]!='/') ) - l-=1; - - strcpy( dest, &src[l+1] ); -} - -sLibrary *lib_Find( sLibrary *lib, char *filename ) -{ - char truncname[MAXNAMELENGTH]; - - TruncateFileName( truncname, filename ); - - while( lib ) - { - if( strcmp(lib->tName,truncname)==0 ) - break; - - lib=lib->pNext; - } - - return( lib ); -} - -sLibrary *lib_AddReplace( sLibrary *lib, char *filename ) -{ - FILE *f; - - if( f=fopen(filename,"rb") ) - { - sLibrary *module; - char truncname[MAXNAMELENGTH]; - - TruncateFileName( truncname, filename ); - - if( (module=lib_Find(lib,filename))==NULL ) - { - if( module=(sLibrary *)malloc(sizeof(sLibrary)) ) - { - module->pNext=lib; - lib=module; - } - else - fatalerror( "Out of memory" ); - } - else - { - /* Module already exists */ - free( module->pData ); - } - - module->nByteLength=file_Length( f ); - strcpy( module->tName, truncname ); - if( module->pData=(UBYTE *)malloc(module->nByteLength) ) - { - fread( module->pData, sizeof(UBYTE), module->nByteLength, f ); - } - - printf( "Added module '%s'\n", truncname ); - - fclose( f ); - } - - return( lib ); -} - -sLibrary *lib_DeleteModule( sLibrary *lib, char *filename ) -{ - char truncname[MAXNAMELENGTH]; - sLibrary **pp, - **first; - BBOOL found=0; - - pp=&lib; - first=pp; - - TruncateFileName( truncname, filename ); - while( (*pp) && (!found) ) - { - if( strcmp((*pp)->tName,truncname)==0 ) - { - sLibrary *t; - - t=*pp; - - if( t->pData ) - free( t->pData ); - - *pp = t->pNext; - - free( t ); - found=1; - } - pp=&((*pp)->pNext); - } - - if( !found ) - fatalerror( "Module not found" ); - else - printf( "Module '%s' deleted from library\n", truncname ); - - return( *first ); -} - -void lib_Free( sLibrary *lib ) -{ - while( lib ) - { - sLibrary *l; - - if( lib->pData ) - free( lib->pData ); - - l=lib; - lib=lib->pNext; - free( l ); - } +#include +#include +#include +#include "types.h" +#include "libwrap.h" + +extern void fatalerror( char *s ); + +SLONG file_Length( FILE *f ) +{ + ULONG r, + p; + + p=ftell( f ); + fseek( f, 0, SEEK_END ); + r=ftell( f ); + fseek( f, p, SEEK_SET ); + + return( r ); +} + +SLONG file_ReadASCIIz( char *b, FILE *f ) +{ + SLONG r=0; + + while( (*b++ = fgetc(f))!=0 ) + r+=1; + + return( r+1 ); +} + +void file_WriteASCIIz( char *b, FILE *f ) +{ + while( *b ) + fputc(*b++,f); + + fputc( 0, f ); +} + +UWORD file_ReadWord( FILE *f ) +{ + UWORD r; + + r =fgetc( f ); + r|=fgetc( f )<<8; + + return( r ); +} + +void file_WriteWord( UWORD w, FILE *f ) +{ + fputc( w, f ); + fputc( w>>8, f ); +} + +ULONG file_ReadLong( FILE *f ) +{ + ULONG r; + + r =fgetc( f ); + r|=fgetc( f )<<8; + r|=fgetc( f )<<16; + r|=fgetc( f )<<24; + + return( r ); +} + +void file_WriteLong( UWORD w, FILE *f ) +{ + fputc( w, f ); + fputc( w>>8, f ); + fputc( w>>16, f ); + fputc( w>>24, f ); +} + +sLibrary *lib_ReadLib0( FILE *f, SLONG size ) +{ + if( size ) + { + sLibrary *l=NULL, + *first=NULL; + + while( size>0 ) + { + if( l==NULL ) + { + if( (l=(sLibrary *)malloc(sizeof(sLibrary)))==NULL ) + fatalerror( "Out of memory" ); + + first=l; + } + else + { + if( (l->pNext=(sLibrary *)malloc(sizeof(sLibrary)))==NULL ) + fatalerror( "Out of memory" ); + l=l->pNext; + } + + size-=file_ReadASCIIz( l->tName, f ); + l->uwTime=file_ReadWord( f ); size-=2; + l->uwDate=file_ReadWord( f ); size-=2; + l->nByteLength=file_ReadLong( f ); size-=4; + if( l->pData=(UBYTE *)malloc(l->nByteLength) ) + { + fread( l->pData, sizeof(UBYTE), l->nByteLength, f ); + size-=l->nByteLength; + } + else + fatalerror( "Out of memory" ); + + l->pNext=NULL; + } + return( first ); + } + + return( NULL ); +} + +sLibrary *lib_Read( char *filename ) +{ + FILE *f; + + if( f=fopen(filename,"rb") ) + { + SLONG size; + char ID[5]; + + size=file_Length( f ); + if( size==0 ) + { + fclose( f ); + return( NULL ); + } + + fread( ID, sizeof(char), 4, f ); + ID[4]=0; + size-=4; + + if( strcmp(ID,"XLB0")==0 ) + { + sLibrary *r; + + r=lib_ReadLib0( f, size ); + fclose( f ); + printf( "Library '%s' opened\n", filename ); + return( r ); + } + else + { + fclose( f ); + fatalerror( "Not a valid xLib library" ); + return( NULL ); + } + } + else + { + printf( "Library '%s' not found, it will be created if necessary\n", filename ); + return( NULL ); + } +} + +BBOOL lib_Write( sLibrary *lib, char *filename ) +{ + FILE *f; + + if( f=fopen(filename,"wb") ) + { + fwrite( "XLB0", sizeof(char), 4, f ); + while( lib ) + { + file_WriteASCIIz( lib->tName, f ); + file_WriteWord( lib->uwTime, f ); + file_WriteWord( lib->uwDate, f ); + file_WriteLong( lib->nByteLength, f ); + fwrite( lib->pData, sizeof(UBYTE), lib->nByteLength,f ); + lib=lib->pNext; + } + + fclose( f ); + printf( "Library '%s' closed\n", filename ); + return( 1 ); + } + + return( 0 ); +} + +void TruncateFileName( char *dest, char *src ) +{ + SLONG l; + + l=strlen( src )-1; + while( (l>=0) && (src[l]!='\\') && (src[l]!='/') ) + l-=1; + + strcpy( dest, &src[l+1] ); +} + +sLibrary *lib_Find( sLibrary *lib, char *filename ) +{ + char truncname[MAXNAMELENGTH]; + + TruncateFileName( truncname, filename ); + + while( lib ) + { + if( strcmp(lib->tName,truncname)==0 ) + break; + + lib=lib->pNext; + } + + return( lib ); +} + +sLibrary *lib_AddReplace( sLibrary *lib, char *filename ) +{ + FILE *f; + + if( f=fopen(filename,"rb") ) + { + sLibrary *module; + char truncname[MAXNAMELENGTH]; + + TruncateFileName( truncname, filename ); + + if( (module=lib_Find(lib,filename))==NULL ) + { + if( module=(sLibrary *)malloc(sizeof(sLibrary)) ) + { + module->pNext=lib; + lib=module; + } + else + fatalerror( "Out of memory" ); + } + else + { + /* Module already exists */ + free( module->pData ); + } + + module->nByteLength=file_Length( f ); + strcpy( module->tName, truncname ); + if( module->pData=(UBYTE *)malloc(module->nByteLength) ) + { + fread( module->pData, sizeof(UBYTE), module->nByteLength, f ); + } + + printf( "Added module '%s'\n", truncname ); + + fclose( f ); + } + + return( lib ); +} + +sLibrary *lib_DeleteModule( sLibrary *lib, char *filename ) +{ + char truncname[MAXNAMELENGTH]; + sLibrary **pp, + **first; + BBOOL found=0; + + pp=&lib; + first=pp; + + TruncateFileName( truncname, filename ); + while( (*pp) && (!found) ) + { + if( strcmp((*pp)->tName,truncname)==0 ) + { + sLibrary *t; + + t=*pp; + + if( t->pData ) + free( t->pData ); + + *pp = t->pNext; + + free( t ); + found=1; + } + pp=&((*pp)->pNext); + } + + if( !found ) + fatalerror( "Module not found" ); + else + printf( "Module '%s' deleted from library\n", truncname ); + + return( *first ); +} + +void lib_Free( sLibrary *lib ) +{ + while( lib ) + { + sLibrary *l; + + if( lib->pData ) + free( lib->pData ); + + l=lib; + lib=lib->pNext; + free( l ); + } } \ No newline at end of file diff --git a/src/lib/main.c b/src/lib/main.c index f26b86cd..4b0d97cd 100644 --- a/src/lib/main.c +++ b/src/lib/main.c @@ -1,143 +1,143 @@ -#include -#include -#include -#include - -#include "asmotor.h" -#include "types.h" -#include "library.h" - -// Quick and dirty...but it works -#ifdef __GNUC__ -#define strcmpi strcasecmp -#endif - -/* - * Print out an errormessage - * - */ - -void fatalerror( char *s ) -{ - printf( "*ERROR* : %s\n", s ); - exit( 5 ); -} - -/* - * Print the usagescreen - * - */ - -void PrintUsage( void ) -{ - printf( "xLib v" LIB_VERSION " (part of ASMotor " ASMOTOR_VERSION ")\n\n" - "Usage: xlib library command [module1 module2 ... modulen]\n" - "Commands:\n\ta\tAdd/replace modules to library\n" - "\td\tDelete modules from library\n" - "\tl\tList library contents\n" - "\tx\tExtract modules from library\n" ); - exit( 0 ); -} - -/* - * The main routine - * - */ - -int main( int argc, char *argv[] ) -{ - SLONG argn=0; - char *libname; - - argc-=1; - argn+=1; - - if( argc>=2 ) - { - UBYTE command; - sLibrary *lib; - - lib=lib_Read( libname=argv[argn++] ); - argc-=1; - - if( strlen(argv[argn])==1 ) - { - command=argv[argn++][0]; - argc-=1; - - switch( tolower(command) ) - { - case 'a': - while( argc ) - { - lib=lib_AddReplace( lib, argv[argn++] ); - argc-=1; - } - lib_Write( lib, libname ); - lib_Free( lib ); - break; - case 'd': - while( argc ) - { - lib=lib_DeleteModule( lib, argv[argn++] ); - argc-=1; - } - lib_Write( lib, libname ); - lib_Free( lib ); - break; - case 'l': - { - sLibrary *l; - - l=lib; - - while( l ) - { - printf( "%10d %s\n", l->nByteLength, l->tName ); - l=l->pNext; - } - } - break; - case 'x': - while( argc ) - { - sLibrary *l; - - l=lib_Find( lib, argv[argn] ); - if( l ) - { - FILE *f; - - if( f=fopen(argv[argn],"wb") ) - { - fwrite( l->pData, sizeof(UBYTE), l->nByteLength, f ); - fclose( f ); - printf( "Extracted module '%s'\n", argv[argn] ); - } - else - fatalerror( "Unable to write module" ); - } - else - fatalerror( "Module not found" ); - - argn+=1; - argc-=1; - } - lib_Free( lib ); - break; - default: - fatalerror( "Invalid command" ); - break; - } - - } - else - { - fatalerror( "Invalid command" ); - } - } - else - PrintUsage(); - - return( 0 ); +#include +#include +#include +#include + +#include "asmotor.h" +#include "types.h" +#include "library.h" + +// Quick and dirty...but it works +#ifdef __GNUC__ +#define strcmpi strcasecmp +#endif + +/* + * Print out an errormessage + * + */ + +void fatalerror( char *s ) +{ + printf( "*ERROR* : %s\n", s ); + exit( 5 ); +} + +/* + * Print the usagescreen + * + */ + +void PrintUsage( void ) +{ + printf( "xLib v" LIB_VERSION " (part of ASMotor " ASMOTOR_VERSION ")\n\n" + "Usage: xlib library command [module1 module2 ... modulen]\n" + "Commands:\n\ta\tAdd/replace modules to library\n" + "\td\tDelete modules from library\n" + "\tl\tList library contents\n" + "\tx\tExtract modules from library\n" ); + exit( 0 ); +} + +/* + * The main routine + * + */ + +int main( int argc, char *argv[] ) +{ + SLONG argn=0; + char *libname; + + argc-=1; + argn+=1; + + if( argc>=2 ) + { + UBYTE command; + sLibrary *lib; + + lib=lib_Read( libname=argv[argn++] ); + argc-=1; + + if( strlen(argv[argn])==1 ) + { + command=argv[argn++][0]; + argc-=1; + + switch( tolower(command) ) + { + case 'a': + while( argc ) + { + lib=lib_AddReplace( lib, argv[argn++] ); + argc-=1; + } + lib_Write( lib, libname ); + lib_Free( lib ); + break; + case 'd': + while( argc ) + { + lib=lib_DeleteModule( lib, argv[argn++] ); + argc-=1; + } + lib_Write( lib, libname ); + lib_Free( lib ); + break; + case 'l': + { + sLibrary *l; + + l=lib; + + while( l ) + { + printf( "%10d %s\n", l->nByteLength, l->tName ); + l=l->pNext; + } + } + break; + case 'x': + while( argc ) + { + sLibrary *l; + + l=lib_Find( lib, argv[argn] ); + if( l ) + { + FILE *f; + + if( f=fopen(argv[argn],"wb") ) + { + fwrite( l->pData, sizeof(UBYTE), l->nByteLength, f ); + fclose( f ); + printf( "Extracted module '%s'\n", argv[argn] ); + } + else + fatalerror( "Unable to write module" ); + } + else + fatalerror( "Module not found" ); + + argn+=1; + argc-=1; + } + lib_Free( lib ); + break; + default: + fatalerror( "Invalid command" ); + break; + } + + } + else + { + fatalerror( "Invalid command" ); + } + } + else + PrintUsage(); + + return( 0 ); } \ No newline at end of file diff --git a/src/link/assign.c b/src/link/assign.c index 1324d6a2..68f8a03e 100644 --- a/src/link/assign.c +++ b/src/link/assign.c @@ -1,570 +1,570 @@ -#include -#include -#include "mylink.h" -#include "main.h" -#include "symbol.h" -#include "assign.h" - -struct sFreeArea -{ - SLONG nOrg; - SLONG nSize; - struct sFreeArea *pPrev, *pNext; -}; - -struct sFreeArea *BankFree[MAXBANKS]; -SLONG MaxAvail[MAXBANKS]; -SLONG MaxBankUsed; - -#define DOMAXBANK(x) {if( (x)>MaxBankUsed ) MaxBankUsed=(x);} - -SLONG area_Avail( SLONG bank ) -{ - SLONG r; - struct sFreeArea *pArea; - - r=0; - pArea=BankFree[bank]; - - while( pArea ) - { - r+=pArea->nSize; - pArea=pArea->pNext; - } - - return( r ); -} - -SLONG area_AllocAbs( struct sFreeArea **ppArea, SLONG org, SLONG size ) -{ - struct sFreeArea *pArea; - - pArea=*ppArea; - while( pArea ) - { - if( org>=pArea->nOrg && (org+size-1)<=(pArea->nOrg+pArea->nSize-1) ) - { - if( org==pArea->nOrg ) - { - pArea->nOrg+=size; - pArea->nSize-=size; - return( org ); - } - else - { - if( (org+size-1)==(pArea->nOrg+pArea->nSize-1) ) - { - pArea->nSize-=size; - return( org ); - } - else - { - struct sFreeArea *pNewArea; - - if( (pNewArea=(struct sFreeArea *)malloc(sizeof(struct sFreeArea)))!=NULL ) - { - *pNewArea=*pArea; - pNewArea->pPrev=pArea; - pArea->pNext=pNewArea; - pArea->nSize=org-pArea->nOrg; - pNewArea->nOrg=org+size; - pNewArea->nSize-=size+pArea->nSize; - - return( org ); - } - else - fatalerror( "Out of memory!" ); - } - } - } - ppArea=&(pArea->pNext); - pArea=*ppArea; - } - - return( -1 ); -} - -SLONG area_AllocAbsCODEAnyBank( SLONG org, SLONG size ) -{ - SLONG i; - - for( i=1; i<=255; i+=1 ) - { - if( area_AllocAbs( &BankFree[i], org, size )==org ) - return( i ); - } - - return( -1 ); -} - -SLONG area_Alloc( struct sFreeArea **ppArea, SLONG size ) -{ - struct sFreeArea *pArea; - - pArea=*ppArea; - while( pArea ) - { - if( size<=pArea->nSize ) - { - SLONG r; - - r=pArea->nOrg; - pArea->nOrg+=size; - pArea->nSize-=size; - - return( r ); - } - ppArea=&(pArea->pNext); - pArea=*ppArea; - } - - return( -1 ); -} - -SLONG area_AllocCODEAnyBank( SLONG size ) -{ - SLONG i, org; - - for( i=1; i<=255; i+=1 ) - { - if( (org=area_Alloc(&BankFree[i],size))!=-1 ) - return( (i<<16)|org ); - } - - return( -1 ); -} - -struct sSection *FindLargestCode( void ) -{ - struct sSection *pSection, *r=NULL; - SLONG nLargest=0; - - pSection=pSections; - while( pSection ) - { - if( pSection->oAssigned==0 && pSection->Type==SECT_CODE ) - { - if( pSection->nByteSize > nLargest ) - { - nLargest=pSection->nByteSize; - r=pSection; - } - } - pSection=pSection->pNext; - } - return( r ); -} - - -void AssignCodeSections( void ) -{ - struct sSection *pSection; - - while( pSection=FindLargestCode() ) - { - SLONG org; - - if( (org=area_AllocCODEAnyBank( pSection->nByteSize ))!=-1 ) - { - pSection->nOrg=org&0xFFFF; - pSection->nBank=org>>16; - pSection->oAssigned=1; - DOMAXBANK(pSection->nBank); - } - else - fatalerror( "Unable to place CODE section anywhere" ); - } -} - -void GBROM_AssignSections( void ) -{ - SLONG i; - struct sSection *pSection; - - MaxBankUsed=0; - - /* - * Initialize the memory areas - * - */ - - for( i=0; inOrg=0x0000; - if( options&OPT_SMALL ) - { - BankFree[i]->nSize=0x8000; - MaxAvail[i]=0x8000; - } - else - { - BankFree[i]->nSize=0x4000; - MaxAvail[i]=0x4000; - } - } - else if( i>=1 && i<=255 ) - { - BankFree[i]->nOrg=0x4000; - /* - * Now, this shouldn't really be necessary... but for good - * measure we'll do it anyway - * - */ - if( options&OPT_SMALL ) - { - BankFree[i]->nSize=0; - MaxAvail[i]=0; - } - else - { - BankFree[i]->nSize=0x4000; - MaxAvail[i]=0x4000; - } - } - else if( i==BANK_BSS ) - { - BankFree[i]->nOrg =0xC000; - BankFree[i]->nSize=0x2000; - MaxAvail[i]=0x2000; - } - else if( i==BANK_VRAM ) - { - BankFree[i]->nOrg =0x8000; - BankFree[i]->nSize=0x2000; - MaxAvail[i]=0x2000; - } - else if( i==BANK_HRAM ) - { - BankFree[i]->nOrg =0xFF80; - BankFree[i]->nSize=0x007F; - MaxAvail[i]=0x007F; - } - BankFree[i]->pPrev=NULL; - BankFree[i]->pNext=NULL; - } - else - fatalerror( "Out of memory!" ); - } - - /* - * First, let's assign all the fixed sections... - * And all because of that Jens Restemeier character ;) - * - */ - - pSection=pSections; - while( pSection ) - { - if( (pSection->nOrg!=-1 || pSection->nBank!=-1) && pSection->oAssigned==0 ) - { - /* User wants to have a say... */ - - switch( pSection->Type ) - { - case SECT_BSS: - if( area_AllocAbs(&BankFree[BANK_BSS],pSection->nOrg,pSection->nByteSize)!=pSection->nOrg ) - { - sprintf( temptext, "Unable to load fixed BSS section at $%X", pSection->nOrg ); - fatalerror( temptext ); - } - pSection->oAssigned=1; - pSection->nBank=BANK_BSS; - break; - case SECT_HRAM: - if( area_AllocAbs(&BankFree[BANK_HRAM],pSection->nOrg,pSection->nByteSize)!=pSection->nOrg ) - { - sprintf( temptext, "Unable to load fixed HRAM section at $%X", pSection->nOrg ); - fatalerror( temptext ); - } - pSection->oAssigned=1; - pSection->nBank=BANK_HRAM; - break; - case SECT_VRAM: - if( area_AllocAbs(&BankFree[BANK_VRAM],pSection->nOrg,pSection->nByteSize)!=pSection->nOrg ) - { - sprintf( temptext, "Unable to load fixed VRAM section at $%X", pSection->nOrg ); - fatalerror( temptext ); - } - pSection->oAssigned=1; - pSection->nBank=BANK_VRAM; - break; - case SECT_HOME: - if( area_AllocAbs(&BankFree[BANK_HOME],pSection->nOrg,pSection->nByteSize)!=pSection->nOrg ) - { - sprintf( temptext, "Unable to load fixed HOME section at $%X", pSection->nOrg ); - fatalerror( temptext ); - } - pSection->oAssigned=1; - pSection->nBank=BANK_HOME; - break; - case SECT_CODE: - if( pSection->nBank==-1 ) - { - /* - * User doesn't care which bank, so he must want to - * decide which position within that bank. - * We'll do that at a later stage when the really - * hardcoded things are allocated - * - */ - } - else - { - /* - * User wants to decide which bank we use - * Does he care about the position as well? - * - */ - - if( pSection->nOrg==-1 ) - { - /* - * Nope, any position will do - * Again, we'll do that later - * - */ - } - else - { - /* - * How hardcore can you possibly get? Why does - * he even USE this package? Yeah let's just - * direct address everything, shall we? - * Oh well, the customer is always right - * - */ - - if( pSection->nBank>=1 && pSection->nBank<=255 ) - { - if( area_AllocAbs(&BankFree[pSection->nBank],pSection->nOrg,pSection->nByteSize)!=pSection->nOrg ) - { - sprintf( temptext, "Unable to load fixed CODE/DATA section at $%X in bank $%02X", pSection->nOrg, pSection->nBank ); - fatalerror( temptext ); - } - DOMAXBANK(pSection->nBank); - pSection->oAssigned=1; - } - else - { - sprintf( temptext, "Unable to load fixed CODE/DATA section at $%X in bank $%02X", pSection->nOrg, pSection->nBank ); - fatalerror( temptext ); - } - } - - } - break; - } - } - pSection=pSection->pNext; - } - - /* - * Next, let's assign all the bankfixed ONLY CODE sections... - * - */ - - pSection=pSections; - while( pSection ) - { - if( pSection->oAssigned==0 - && pSection->Type==SECT_CODE - && pSection->nOrg==-1 - && pSection->nBank!=-1 ) - { - /* User wants to have a say... and he's pissed */ - if( pSection->nBank>=1 && pSection->nBank<=255 ) - { - if( (pSection->nOrg=area_Alloc(&BankFree[pSection->nBank],pSection->nByteSize))==-1 ) - { - sprintf( temptext, "Unable to load fixed CODE/DATA section into bank $%02X", pSection->nBank ); - fatalerror( temptext ); - } - pSection->oAssigned=1; - DOMAXBANK(pSection->nBank); - } - else - { - sprintf( temptext, "Unable to load fixed CODE/DATA section into bank $%02X", pSection->nBank ); - fatalerror( temptext ); - } - } - pSection=pSection->pNext; - } - - /* - * Now, let's assign all the floating bank but fixed CODE sections... - * - */ - - pSection=pSections; - while( pSection ) - { - if( pSection->oAssigned==0 - && pSection->Type==SECT_CODE - && pSection->nOrg!=-1 - && pSection->nBank==-1 ) - { - /* User wants to have a say... and he's back with a vengeance */ - if( (pSection->nBank=area_AllocAbsCODEAnyBank(pSection->nOrg,pSection->nByteSize))==-1 ) - { - sprintf( temptext, "Unable to load fixed CODE/DATA section at $%X into any bank", pSection->nOrg ); - fatalerror( temptext ); - } - pSection->oAssigned=1; - DOMAXBANK(pSection->nBank); - } - pSection=pSection->pNext; - } - - /* - * OK, all that nasty stuff is done so let's assign all the other - * sections - * - */ - - pSection=pSections; - while( pSection ) - { - if( pSection->oAssigned==0 ) - { - switch( pSection->Type ) - { - case SECT_BSS: - if( (pSection->nOrg=area_Alloc(&BankFree[BANK_BSS],pSection->nByteSize))==-1 ) - { - fatalerror( "BSS section too large\n" ); - } - pSection->nBank=BANK_BSS; - pSection->oAssigned=1; - break; - case SECT_HRAM: - if( (pSection->nOrg=area_Alloc(&BankFree[BANK_HRAM],pSection->nByteSize))==-1 ) - { - fatalerror( "HRAM section too large" ); - } - pSection->nBank=BANK_HRAM; - pSection->oAssigned=1; - break; - case SECT_VRAM: - if( (pSection->nOrg=area_Alloc(&BankFree[BANK_VRAM],pSection->nByteSize))==-1 ) - { - fatalerror( "VRAM section too large" ); - } - pSection->nBank=BANK_VRAM; - pSection->oAssigned=1; - break; - case SECT_HOME: - if( (pSection->nOrg=area_Alloc(&BankFree[BANK_HOME],pSection->nByteSize))==-1 ) - { - fatalerror( "HOME section too large" ); - } - pSection->nBank=BANK_HOME; - pSection->oAssigned=1; - break; - case SECT_CODE: - break; - default: - fatalerror( "(INTERNAL) Unknown section type!" ); - break; - } - } - pSection=pSection->pNext; - } - - AssignCodeSections(); -} - -void PSION2_AssignSections( void ) -{ - struct sSection *pSection; - - if( BankFree[0]=(struct sFreeArea *)malloc(sizeof(struct sFreeArea)) ) - { - BankFree[0]->nOrg=0x0000; - BankFree[0]->nSize=0x10000; - MaxAvail[0]=0x10000; - BankFree[0]->pPrev=NULL; - BankFree[0]->pNext=NULL; - - pSection=pSections; - while( pSection ) - { - if( pSection->oAssigned==0 && pSection->Type==SECT_CODE ) - { - pSection->oAssigned=1; - pSection->nBank=0; - pSection->nOrg=BankFree[0]->nOrg; - BankFree[0]->nOrg+=pSection->nByteSize; - BankFree[0]->nSize-=pSection->nByteSize; - } - pSection=pSection->pNext; - } - - pSection=pSections; - while( pSection ) - { - if( pSection->oAssigned==0 && pSection->Type==SECT_BSS ) - { - pSection->oAssigned=1; - pSection->nBank=0; - pSection->nOrg=BankFree[0]->nOrg; - BankFree[0]->nOrg+=pSection->nByteSize; - BankFree[0]->nSize-=pSection->nByteSize; - } - pSection=pSection->pNext; - } - } - else - fatalerror( "Out of memory!" ); -} - -void AssignSections( void ) -{ - switch( outputtype ) - { - case OUTPUT_GBROM: - GBROM_AssignSections(); - break; - case OUTPUT_PSION2: - PSION2_AssignSections(); - break; - } -} - -void CreateSymbolTable( void ) -{ - struct sSection *pSect; - - sym_Init(); - - pSect=pSections; - - while( pSect ) - { - SLONG i; - - i=pSect->nNumberOfSymbols; - - while( i-- ) - { - if( (pSect->tSymbols[i]->Type==SYM_EXPORT) && - ( (pSect->tSymbols[i]->pSection==pSect) || - (pSect->tSymbols[i]->pSection==NULL)) ) - { - if( pSect->tSymbols[i]->pSection==NULL ) - sym_CreateSymbol( pSect->tSymbols[i]->pzName, - pSect->tSymbols[i]->nOffset, - -1 ); - else - sym_CreateSymbol( pSect->tSymbols[i]->pzName, - pSect->nOrg+pSect->tSymbols[i]->nOffset, - pSect->nBank ); - } - } - pSect=pSect->pNext; - } +#include +#include +#include "mylink.h" +#include "main.h" +#include "symbol.h" +#include "assign.h" + +struct sFreeArea +{ + SLONG nOrg; + SLONG nSize; + struct sFreeArea *pPrev, *pNext; +}; + +struct sFreeArea *BankFree[MAXBANKS]; +SLONG MaxAvail[MAXBANKS]; +SLONG MaxBankUsed; + +#define DOMAXBANK(x) {if( (x)>MaxBankUsed ) MaxBankUsed=(x);} + +SLONG area_Avail( SLONG bank ) +{ + SLONG r; + struct sFreeArea *pArea; + + r=0; + pArea=BankFree[bank]; + + while( pArea ) + { + r+=pArea->nSize; + pArea=pArea->pNext; + } + + return( r ); +} + +SLONG area_AllocAbs( struct sFreeArea **ppArea, SLONG org, SLONG size ) +{ + struct sFreeArea *pArea; + + pArea=*ppArea; + while( pArea ) + { + if( org>=pArea->nOrg && (org+size-1)<=(pArea->nOrg+pArea->nSize-1) ) + { + if( org==pArea->nOrg ) + { + pArea->nOrg+=size; + pArea->nSize-=size; + return( org ); + } + else + { + if( (org+size-1)==(pArea->nOrg+pArea->nSize-1) ) + { + pArea->nSize-=size; + return( org ); + } + else + { + struct sFreeArea *pNewArea; + + if( (pNewArea=(struct sFreeArea *)malloc(sizeof(struct sFreeArea)))!=NULL ) + { + *pNewArea=*pArea; + pNewArea->pPrev=pArea; + pArea->pNext=pNewArea; + pArea->nSize=org-pArea->nOrg; + pNewArea->nOrg=org+size; + pNewArea->nSize-=size+pArea->nSize; + + return( org ); + } + else + fatalerror( "Out of memory!" ); + } + } + } + ppArea=&(pArea->pNext); + pArea=*ppArea; + } + + return( -1 ); +} + +SLONG area_AllocAbsCODEAnyBank( SLONG org, SLONG size ) +{ + SLONG i; + + for( i=1; i<=255; i+=1 ) + { + if( area_AllocAbs( &BankFree[i], org, size )==org ) + return( i ); + } + + return( -1 ); +} + +SLONG area_Alloc( struct sFreeArea **ppArea, SLONG size ) +{ + struct sFreeArea *pArea; + + pArea=*ppArea; + while( pArea ) + { + if( size<=pArea->nSize ) + { + SLONG r; + + r=pArea->nOrg; + pArea->nOrg+=size; + pArea->nSize-=size; + + return( r ); + } + ppArea=&(pArea->pNext); + pArea=*ppArea; + } + + return( -1 ); +} + +SLONG area_AllocCODEAnyBank( SLONG size ) +{ + SLONG i, org; + + for( i=1; i<=255; i+=1 ) + { + if( (org=area_Alloc(&BankFree[i],size))!=-1 ) + return( (i<<16)|org ); + } + + return( -1 ); +} + +struct sSection *FindLargestCode( void ) +{ + struct sSection *pSection, *r=NULL; + SLONG nLargest=0; + + pSection=pSections; + while( pSection ) + { + if( pSection->oAssigned==0 && pSection->Type==SECT_CODE ) + { + if( pSection->nByteSize > nLargest ) + { + nLargest=pSection->nByteSize; + r=pSection; + } + } + pSection=pSection->pNext; + } + return( r ); +} + + +void AssignCodeSections( void ) +{ + struct sSection *pSection; + + while( pSection=FindLargestCode() ) + { + SLONG org; + + if( (org=area_AllocCODEAnyBank( pSection->nByteSize ))!=-1 ) + { + pSection->nOrg=org&0xFFFF; + pSection->nBank=org>>16; + pSection->oAssigned=1; + DOMAXBANK(pSection->nBank); + } + else + fatalerror( "Unable to place CODE section anywhere" ); + } +} + +void GBROM_AssignSections( void ) +{ + SLONG i; + struct sSection *pSection; + + MaxBankUsed=0; + + /* + * Initialize the memory areas + * + */ + + for( i=0; inOrg=0x0000; + if( options&OPT_SMALL ) + { + BankFree[i]->nSize=0x8000; + MaxAvail[i]=0x8000; + } + else + { + BankFree[i]->nSize=0x4000; + MaxAvail[i]=0x4000; + } + } + else if( i>=1 && i<=255 ) + { + BankFree[i]->nOrg=0x4000; + /* + * Now, this shouldn't really be necessary... but for good + * measure we'll do it anyway + * + */ + if( options&OPT_SMALL ) + { + BankFree[i]->nSize=0; + MaxAvail[i]=0; + } + else + { + BankFree[i]->nSize=0x4000; + MaxAvail[i]=0x4000; + } + } + else if( i==BANK_BSS ) + { + BankFree[i]->nOrg =0xC000; + BankFree[i]->nSize=0x2000; + MaxAvail[i]=0x2000; + } + else if( i==BANK_VRAM ) + { + BankFree[i]->nOrg =0x8000; + BankFree[i]->nSize=0x2000; + MaxAvail[i]=0x2000; + } + else if( i==BANK_HRAM ) + { + BankFree[i]->nOrg =0xFF80; + BankFree[i]->nSize=0x007F; + MaxAvail[i]=0x007F; + } + BankFree[i]->pPrev=NULL; + BankFree[i]->pNext=NULL; + } + else + fatalerror( "Out of memory!" ); + } + + /* + * First, let's assign all the fixed sections... + * And all because of that Jens Restemeier character ;) + * + */ + + pSection=pSections; + while( pSection ) + { + if( (pSection->nOrg!=-1 || pSection->nBank!=-1) && pSection->oAssigned==0 ) + { + /* User wants to have a say... */ + + switch( pSection->Type ) + { + case SECT_BSS: + if( area_AllocAbs(&BankFree[BANK_BSS],pSection->nOrg,pSection->nByteSize)!=pSection->nOrg ) + { + sprintf( temptext, "Unable to load fixed BSS section at $%X", pSection->nOrg ); + fatalerror( temptext ); + } + pSection->oAssigned=1; + pSection->nBank=BANK_BSS; + break; + case SECT_HRAM: + if( area_AllocAbs(&BankFree[BANK_HRAM],pSection->nOrg,pSection->nByteSize)!=pSection->nOrg ) + { + sprintf( temptext, "Unable to load fixed HRAM section at $%X", pSection->nOrg ); + fatalerror( temptext ); + } + pSection->oAssigned=1; + pSection->nBank=BANK_HRAM; + break; + case SECT_VRAM: + if( area_AllocAbs(&BankFree[BANK_VRAM],pSection->nOrg,pSection->nByteSize)!=pSection->nOrg ) + { + sprintf( temptext, "Unable to load fixed VRAM section at $%X", pSection->nOrg ); + fatalerror( temptext ); + } + pSection->oAssigned=1; + pSection->nBank=BANK_VRAM; + break; + case SECT_HOME: + if( area_AllocAbs(&BankFree[BANK_HOME],pSection->nOrg,pSection->nByteSize)!=pSection->nOrg ) + { + sprintf( temptext, "Unable to load fixed HOME section at $%X", pSection->nOrg ); + fatalerror( temptext ); + } + pSection->oAssigned=1; + pSection->nBank=BANK_HOME; + break; + case SECT_CODE: + if( pSection->nBank==-1 ) + { + /* + * User doesn't care which bank, so he must want to + * decide which position within that bank. + * We'll do that at a later stage when the really + * hardcoded things are allocated + * + */ + } + else + { + /* + * User wants to decide which bank we use + * Does he care about the position as well? + * + */ + + if( pSection->nOrg==-1 ) + { + /* + * Nope, any position will do + * Again, we'll do that later + * + */ + } + else + { + /* + * How hardcore can you possibly get? Why does + * he even USE this package? Yeah let's just + * direct address everything, shall we? + * Oh well, the customer is always right + * + */ + + if( pSection->nBank>=1 && pSection->nBank<=255 ) + { + if( area_AllocAbs(&BankFree[pSection->nBank],pSection->nOrg,pSection->nByteSize)!=pSection->nOrg ) + { + sprintf( temptext, "Unable to load fixed CODE/DATA section at $%X in bank $%02X", pSection->nOrg, pSection->nBank ); + fatalerror( temptext ); + } + DOMAXBANK(pSection->nBank); + pSection->oAssigned=1; + } + else + { + sprintf( temptext, "Unable to load fixed CODE/DATA section at $%X in bank $%02X", pSection->nOrg, pSection->nBank ); + fatalerror( temptext ); + } + } + + } + break; + } + } + pSection=pSection->pNext; + } + + /* + * Next, let's assign all the bankfixed ONLY CODE sections... + * + */ + + pSection=pSections; + while( pSection ) + { + if( pSection->oAssigned==0 + && pSection->Type==SECT_CODE + && pSection->nOrg==-1 + && pSection->nBank!=-1 ) + { + /* User wants to have a say... and he's pissed */ + if( pSection->nBank>=1 && pSection->nBank<=255 ) + { + if( (pSection->nOrg=area_Alloc(&BankFree[pSection->nBank],pSection->nByteSize))==-1 ) + { + sprintf( temptext, "Unable to load fixed CODE/DATA section into bank $%02X", pSection->nBank ); + fatalerror( temptext ); + } + pSection->oAssigned=1; + DOMAXBANK(pSection->nBank); + } + else + { + sprintf( temptext, "Unable to load fixed CODE/DATA section into bank $%02X", pSection->nBank ); + fatalerror( temptext ); + } + } + pSection=pSection->pNext; + } + + /* + * Now, let's assign all the floating bank but fixed CODE sections... + * + */ + + pSection=pSections; + while( pSection ) + { + if( pSection->oAssigned==0 + && pSection->Type==SECT_CODE + && pSection->nOrg!=-1 + && pSection->nBank==-1 ) + { + /* User wants to have a say... and he's back with a vengeance */ + if( (pSection->nBank=area_AllocAbsCODEAnyBank(pSection->nOrg,pSection->nByteSize))==-1 ) + { + sprintf( temptext, "Unable to load fixed CODE/DATA section at $%X into any bank", pSection->nOrg ); + fatalerror( temptext ); + } + pSection->oAssigned=1; + DOMAXBANK(pSection->nBank); + } + pSection=pSection->pNext; + } + + /* + * OK, all that nasty stuff is done so let's assign all the other + * sections + * + */ + + pSection=pSections; + while( pSection ) + { + if( pSection->oAssigned==0 ) + { + switch( pSection->Type ) + { + case SECT_BSS: + if( (pSection->nOrg=area_Alloc(&BankFree[BANK_BSS],pSection->nByteSize))==-1 ) + { + fatalerror( "BSS section too large\n" ); + } + pSection->nBank=BANK_BSS; + pSection->oAssigned=1; + break; + case SECT_HRAM: + if( (pSection->nOrg=area_Alloc(&BankFree[BANK_HRAM],pSection->nByteSize))==-1 ) + { + fatalerror( "HRAM section too large" ); + } + pSection->nBank=BANK_HRAM; + pSection->oAssigned=1; + break; + case SECT_VRAM: + if( (pSection->nOrg=area_Alloc(&BankFree[BANK_VRAM],pSection->nByteSize))==-1 ) + { + fatalerror( "VRAM section too large" ); + } + pSection->nBank=BANK_VRAM; + pSection->oAssigned=1; + break; + case SECT_HOME: + if( (pSection->nOrg=area_Alloc(&BankFree[BANK_HOME],pSection->nByteSize))==-1 ) + { + fatalerror( "HOME section too large" ); + } + pSection->nBank=BANK_HOME; + pSection->oAssigned=1; + break; + case SECT_CODE: + break; + default: + fatalerror( "(INTERNAL) Unknown section type!" ); + break; + } + } + pSection=pSection->pNext; + } + + AssignCodeSections(); +} + +void PSION2_AssignSections( void ) +{ + struct sSection *pSection; + + if( BankFree[0]=(struct sFreeArea *)malloc(sizeof(struct sFreeArea)) ) + { + BankFree[0]->nOrg=0x0000; + BankFree[0]->nSize=0x10000; + MaxAvail[0]=0x10000; + BankFree[0]->pPrev=NULL; + BankFree[0]->pNext=NULL; + + pSection=pSections; + while( pSection ) + { + if( pSection->oAssigned==0 && pSection->Type==SECT_CODE ) + { + pSection->oAssigned=1; + pSection->nBank=0; + pSection->nOrg=BankFree[0]->nOrg; + BankFree[0]->nOrg+=pSection->nByteSize; + BankFree[0]->nSize-=pSection->nByteSize; + } + pSection=pSection->pNext; + } + + pSection=pSections; + while( pSection ) + { + if( pSection->oAssigned==0 && pSection->Type==SECT_BSS ) + { + pSection->oAssigned=1; + pSection->nBank=0; + pSection->nOrg=BankFree[0]->nOrg; + BankFree[0]->nOrg+=pSection->nByteSize; + BankFree[0]->nSize-=pSection->nByteSize; + } + pSection=pSection->pNext; + } + } + else + fatalerror( "Out of memory!" ); +} + +void AssignSections( void ) +{ + switch( outputtype ) + { + case OUTPUT_GBROM: + GBROM_AssignSections(); + break; + case OUTPUT_PSION2: + PSION2_AssignSections(); + break; + } +} + +void CreateSymbolTable( void ) +{ + struct sSection *pSect; + + sym_Init(); + + pSect=pSections; + + while( pSect ) + { + SLONG i; + + i=pSect->nNumberOfSymbols; + + while( i-- ) + { + if( (pSect->tSymbols[i]->Type==SYM_EXPORT) && + ( (pSect->tSymbols[i]->pSection==pSect) || + (pSect->tSymbols[i]->pSection==NULL)) ) + { + if( pSect->tSymbols[i]->pSection==NULL ) + sym_CreateSymbol( pSect->tSymbols[i]->pzName, + pSect->tSymbols[i]->nOffset, + -1 ); + else + sym_CreateSymbol( pSect->tSymbols[i]->pzName, + pSect->nOrg+pSect->tSymbols[i]->nOffset, + pSect->nBank ); + } + } + pSect=pSect->pNext; + } } \ No newline at end of file diff --git a/src/link/include/assign.h b/src/link/include/assign.h index 698694b7..3eabc548 100644 --- a/src/link/include/assign.h +++ b/src/link/include/assign.h @@ -1,22 +1,22 @@ -#ifndef ASSIGN_H -#define ASSIGN_H - -#include "types.h" - -enum eBankDefine -{ - BANK_HOME=0, - BANK_BSS=256, - BANK_VRAM, - BANK_HRAM -}; - -#define MAXBANKS 259 - -extern SLONG area_Avail( SLONG bank ); -extern void AssignSections( void ); -extern void CreateSymbolTable( void ); -extern SLONG MaxBankUsed; -extern SLONG MaxAvail[MAXBANKS]; - +#ifndef ASSIGN_H +#define ASSIGN_H + +#include "types.h" + +enum eBankDefine +{ + BANK_HOME=0, + BANK_BSS=256, + BANK_VRAM, + BANK_HRAM +}; + +#define MAXBANKS 259 + +extern SLONG area_Avail( SLONG bank ); +extern void AssignSections( void ); +extern void CreateSymbolTable( void ); +extern SLONG MaxBankUsed; +extern SLONG MaxAvail[MAXBANKS]; + #endif \ No newline at end of file diff --git a/src/link/include/library.h b/src/link/include/library.h index 2bcc4952..1eeda6d9 100644 --- a/src/link/include/library.h +++ b/src/link/include/library.h @@ -1,6 +1,6 @@ -#ifndef LIBRARY_H -#define LIBRARY_H - -extern void AddNeededModules( void ); - +#ifndef LIBRARY_H +#define LIBRARY_H + +extern void AddNeededModules( void ); + #endif \ No newline at end of file diff --git a/src/link/include/main.h b/src/link/include/main.h index af26bd12..d9cedbbb 100644 --- a/src/link/include/main.h +++ b/src/link/include/main.h @@ -1,21 +1,21 @@ -#ifndef MAIN_H -#define MAIN_H - -#include "types.h" - -extern void PrintUsage( void ); -extern void fatalerror( char *s ); -extern char temptext[1024]; -extern SLONG fillchar; -extern char smartlinkstartsymbol[256]; - -enum eOutputType -{ - OUTPUT_GBROM, - OUTPUT_PSION2 -}; - -extern enum eOutputType outputtype; - - +#ifndef MAIN_H +#define MAIN_H + +#include "types.h" + +extern void PrintUsage( void ); +extern void fatalerror( char *s ); +extern char temptext[1024]; +extern SLONG fillchar; +extern char smartlinkstartsymbol[256]; + +enum eOutputType +{ + OUTPUT_GBROM, + OUTPUT_PSION2 +}; + +extern enum eOutputType outputtype; + + #endif \ No newline at end of file diff --git a/src/link/include/mapfile.h b/src/link/include/mapfile.h index 17105331..63b40731 100644 --- a/src/link/include/mapfile.h +++ b/src/link/include/mapfile.h @@ -1,11 +1,11 @@ -#ifndef MAPFILE_H -#define MAPFILE_H - -extern void SetMapfileName( char *name ); -extern void SetSymfileName( char *name ); -extern void CloseMapfile( void ); -extern void MapfileWriteSection( struct sSection *pSect ); -extern void MapfileInitBank( SLONG bank ); -extern void MapfileCloseBank( SLONG slack ); - +#ifndef MAPFILE_H +#define MAPFILE_H + +extern void SetMapfileName( char *name ); +extern void SetSymfileName( char *name ); +extern void CloseMapfile( void ); +extern void MapfileWriteSection( struct sSection *pSect ); +extern void MapfileInitBank( SLONG bank ); +extern void MapfileCloseBank( SLONG slack ); + #endif \ No newline at end of file diff --git a/src/link/include/mylink.h b/src/link/include/mylink.h index 0bd208f5..0a7603b2 100644 --- a/src/link/include/mylink.h +++ b/src/link/include/mylink.h @@ -1,119 +1,119 @@ -#ifndef LINK_H -#define LINK_H 1 - -#if defined(AMIGA) || defined(__GNUC__) -#define _MAX_PATH 512 -#endif - -#include "types.h" - -extern SLONG options; -#define OPT_SMALL 0x01 -#define OPT_SMART_C_LINK 0x02 - -enum eRpnData -{ - RPN_ADD=0, - RPN_SUB, - RPN_MUL, - RPN_DIV, - RPN_MOD, - RPN_UNSUB, - - RPN_OR, - RPN_AND, - RPN_XOR, - RPN_UNNOT, - - RPN_LOGAND, - RPN_LOGOR, - RPN_LOGUNNOT, - - RPN_LOGEQ, - RPN_LOGNE, - RPN_LOGGT, - RPN_LOGLT, - RPN_LOGGE, - RPN_LOGLE, - - RPN_SHL, - RPN_SHR, - - RPN_BANK, - - RPN_HRAM, - - RPN_PCEZP, - - RPN_RANGECHECK, - - RPN_CONST=0x80, - RPN_SYM=0x81 -}; - -enum eSectionType -{ - SECT_BSS, - SECT_VRAM, - SECT_CODE, - SECT_HOME, - SECT_HRAM -}; - -struct sSection -{ - SLONG nBank; - SLONG nOrg; - BBOOL oAssigned; - - SLONG nByteSize; - enum eSectionType Type; - UBYTE *pData; - SLONG nNumberOfSymbols; - struct sSymbol **tSymbols; - struct sPatch *pPatches; - struct sSection *pNext; -}; - -enum eSymbolType -{ - SYM_LOCAL, - SYM_IMPORT, - SYM_EXPORT -}; - -struct sSymbol -{ - char *pzName; - enum eSymbolType Type; - /* the following 3 items only valid when Type!=SYM_IMPORT */ - SLONG nSectionID; /* internal to object.c */ - struct sSection *pSection; - SLONG nOffset; -}; - -enum ePatchType -{ - PATCH_BYTE=0, - PATCH_WORD_L, - PATCH_LONG_L, - PATCH_WORD_B, - PATCH_LONG_B -}; - -struct sPatch -{ - char *pzFilename; - SLONG nLineNo; - SLONG nOffset; - enum ePatchType Type; - SLONG nRPNSize; - UBYTE *pRPN; - struct sPatch *pNext; - BBOOL oRelocPatch; -}; - -extern struct sSection *pSections; -extern struct sSection *pLibSections; - +#ifndef LINK_H +#define LINK_H 1 + +#if defined(AMIGA) || defined(__GNUC__) +#define _MAX_PATH 512 +#endif + +#include "types.h" + +extern SLONG options; +#define OPT_SMALL 0x01 +#define OPT_SMART_C_LINK 0x02 + +enum eRpnData +{ + RPN_ADD=0, + RPN_SUB, + RPN_MUL, + RPN_DIV, + RPN_MOD, + RPN_UNSUB, + + RPN_OR, + RPN_AND, + RPN_XOR, + RPN_UNNOT, + + RPN_LOGAND, + RPN_LOGOR, + RPN_LOGUNNOT, + + RPN_LOGEQ, + RPN_LOGNE, + RPN_LOGGT, + RPN_LOGLT, + RPN_LOGGE, + RPN_LOGLE, + + RPN_SHL, + RPN_SHR, + + RPN_BANK, + + RPN_HRAM, + + RPN_PCEZP, + + RPN_RANGECHECK, + + RPN_CONST=0x80, + RPN_SYM=0x81 +}; + +enum eSectionType +{ + SECT_BSS, + SECT_VRAM, + SECT_CODE, + SECT_HOME, + SECT_HRAM +}; + +struct sSection +{ + SLONG nBank; + SLONG nOrg; + BBOOL oAssigned; + + SLONG nByteSize; + enum eSectionType Type; + UBYTE *pData; + SLONG nNumberOfSymbols; + struct sSymbol **tSymbols; + struct sPatch *pPatches; + struct sSection *pNext; +}; + +enum eSymbolType +{ + SYM_LOCAL, + SYM_IMPORT, + SYM_EXPORT +}; + +struct sSymbol +{ + char *pzName; + enum eSymbolType Type; + /* the following 3 items only valid when Type!=SYM_IMPORT */ + SLONG nSectionID; /* internal to object.c */ + struct sSection *pSection; + SLONG nOffset; +}; + +enum ePatchType +{ + PATCH_BYTE=0, + PATCH_WORD_L, + PATCH_LONG_L, + PATCH_WORD_B, + PATCH_LONG_B +}; + +struct sPatch +{ + char *pzFilename; + SLONG nLineNo; + SLONG nOffset; + enum ePatchType Type; + SLONG nRPNSize; + UBYTE *pRPN; + struct sPatch *pNext; + BBOOL oRelocPatch; +}; + +extern struct sSection *pSections; +extern struct sSection *pLibSections; + #endif \ No newline at end of file diff --git a/src/link/include/object.h b/src/link/include/object.h index 33ebb709..2537747e 100644 --- a/src/link/include/object.h +++ b/src/link/include/object.h @@ -1,7 +1,7 @@ -#ifndef OBJECT_H -#define OBJECT_H - -extern void obj_Readfile( char *tzObjectfile ); -extern void lib_Readfile( char *tzLibfile ); - +#ifndef OBJECT_H +#define OBJECT_H + +extern void obj_Readfile( char *tzObjectfile ); +extern void lib_Readfile( char *tzLibfile ); + #endif \ No newline at end of file diff --git a/src/link/include/output.h b/src/link/include/output.h index 14e79d3b..ac49c27e 100644 --- a/src/link/include/output.h +++ b/src/link/include/output.h @@ -1,7 +1,7 @@ -#ifndef OUTPUT_H -#define OUTPUT_H - -void out_Setname( char *tzOutputfile ); -void Output( void ); - -#endif +#ifndef OUTPUT_H +#define OUTPUT_H + +void out_Setname( char *tzOutputfile ); +void Output( void ); + +#endif diff --git a/src/link/include/patch.h b/src/link/include/patch.h index 091a0621..33ba88a8 100644 --- a/src/link/include/patch.h +++ b/src/link/include/patch.h @@ -1,9 +1,9 @@ -#ifndef PATCH_H -#define PATCH_H - -#include "types.h" - -void Patch( void ); -extern SLONG nPC; - +#ifndef PATCH_H +#define PATCH_H + +#include "types.h" + +void Patch( void ); +extern SLONG nPC; + #endif \ No newline at end of file diff --git a/src/link/include/symbol.h b/src/link/include/symbol.h index f3d28fdd..c994ad42 100644 --- a/src/link/include/symbol.h +++ b/src/link/include/symbol.h @@ -1,11 +1,11 @@ -#ifndef SYMBOL_H -#define SYMBOL_H - -#include "types.h" - -void sym_Init( void ); -void sym_CreateSymbol( char *tzName, SLONG nValue, SBYTE nBank ); -SLONG sym_GetValue( char *tzName ); -SLONG sym_GetBank( char *tzName ); - +#ifndef SYMBOL_H +#define SYMBOL_H + +#include "types.h" + +void sym_Init( void ); +void sym_CreateSymbol( char *tzName, SLONG nValue, SBYTE nBank ); +SLONG sym_GetValue( char *tzName ); +SLONG sym_GetBank( char *tzName ); + #endif \ No newline at end of file diff --git a/src/link/include/types.h b/src/link/include/types.h index 7bc4679f..7c6aa1fb 100644 --- a/src/link/include/types.h +++ b/src/link/include/types.h @@ -1,16 +1,16 @@ -#ifndef TYPES_H -#define TYPES_H 1 - -#if defined(AMIGA) || defined(__GNUC__) -#define _MAX_PATH 512 -#endif - -typedef unsigned char UBYTE; -typedef signed char SBYTE; -typedef unsigned short UWORD; -typedef signed short SWORD; -typedef unsigned long ULONG; -typedef signed long SLONG; -typedef signed char BBOOL; - +#ifndef TYPES_H +#define TYPES_H 1 + +#if defined(AMIGA) || defined(__GNUC__) +#define _MAX_PATH 512 +#endif + +typedef unsigned char UBYTE; +typedef signed char SBYTE; +typedef unsigned short UWORD; +typedef signed short SWORD; +typedef unsigned long ULONG; +typedef signed long SLONG; +typedef signed char BBOOL; + #endif \ No newline at end of file diff --git a/src/link/library.c b/src/link/library.c index f09b0dfc..14aae24b 100644 --- a/src/link/library.c +++ b/src/link/library.c @@ -1,127 +1,127 @@ -#include -#include -#include -#include "types.h" -#include "mylink.h" -#include "main.h" - -static BBOOL symboldefined( char *name ) -{ - struct sSection *pSect; - - pSect=pSections; - - while( pSect ) - { - ULONG i; - - for( i=0; inNumberOfSymbols; i+=1 ) - { - if( (pSect->tSymbols[i]->Type==SYM_EXPORT) - || ( (pSect->tSymbols[i]->Type==SYM_LOCAL) - && (pSect==pSect->tSymbols[i]->pSection) ) ) - { - if( strcmp(pSect->tSymbols[i]->pzName,name)==0 ) - return( 1 ); - } - - } - pSect=pSect->pNext; - } - return( 0 ); -} - -static BBOOL addmodulecontaining( char *name ) -{ - struct sSection **ppLSect; - - ppLSect=&pLibSections; - - while( *ppLSect ) - { - ULONG i; - - for( i=0; i<(*ppLSect)->nNumberOfSymbols; i+=1 ) - { - if( ((*ppLSect)->tSymbols[i]->Type==SYM_EXPORT) - || ( ((*ppLSect)->tSymbols[i]->Type==SYM_LOCAL) - && ((*ppLSect)==(*ppLSect)->tSymbols[i]->pSection) ) ) - { - if( strcmp((*ppLSect)->tSymbols[i]->pzName,name)==0 ) - { - struct sSection **ppSect; - ppSect=&pSections; - while( *ppSect ) - ppSect=&((*ppSect)->pNext); - - *ppSect = *ppLSect; - *ppLSect = (*ppLSect)->pNext; - (*ppSect)->pNext = NULL; - return( 1 ); - } - } - - } - ppLSect=&((*ppLSect)->pNext); - } - return( 0 ); -} - -void AddNeededModules( void ) -{ - struct sSection *pSect; - - if( (options&OPT_SMART_C_LINK)==0 ) - { - struct sSection **ppLSect; - - ppLSect=&pLibSections; - - while( *ppLSect ) - { - struct sSection **ppSect; - ppSect=&pSections; - while( *ppSect ) - ppSect=&((*ppSect)->pNext); - - *ppSect = *ppLSect; - *ppLSect = (*ppLSect)->pNext; - (*ppSect)->pNext = NULL; - - /*ppLSect=&((*ppLSect)->pNext);*/ - } - return; - } - - if( options&OPT_SMART_C_LINK ) - { - if( !addmodulecontaining( smartlinkstartsymbol ) ) - { - sprintf( temptext, "Can't find start symbol '%s'", smartlinkstartsymbol ); - fatalerror( temptext ); - } - else - printf( "Smart linking with symbol '%s'\n", smartlinkstartsymbol ); - } - - pSect=pSections; - - while( pSect ) - { - ULONG i; - - for( i=0; inNumberOfSymbols; i+=1 ) - { - if( (pSect->tSymbols[i]->Type==SYM_IMPORT) - || (pSect->tSymbols[i]->Type==SYM_LOCAL) ) - { - if( !symboldefined(pSect->tSymbols[i]->pzName) ) - { - addmodulecontaining( pSect->tSymbols[i]->pzName ); - } - } - - } - pSect=pSect->pNext; - } +#include +#include +#include +#include "types.h" +#include "mylink.h" +#include "main.h" + +static BBOOL symboldefined( char *name ) +{ + struct sSection *pSect; + + pSect=pSections; + + while( pSect ) + { + ULONG i; + + for( i=0; inNumberOfSymbols; i+=1 ) + { + if( (pSect->tSymbols[i]->Type==SYM_EXPORT) + || ( (pSect->tSymbols[i]->Type==SYM_LOCAL) + && (pSect==pSect->tSymbols[i]->pSection) ) ) + { + if( strcmp(pSect->tSymbols[i]->pzName,name)==0 ) + return( 1 ); + } + + } + pSect=pSect->pNext; + } + return( 0 ); +} + +static BBOOL addmodulecontaining( char *name ) +{ + struct sSection **ppLSect; + + ppLSect=&pLibSections; + + while( *ppLSect ) + { + ULONG i; + + for( i=0; i<(*ppLSect)->nNumberOfSymbols; i+=1 ) + { + if( ((*ppLSect)->tSymbols[i]->Type==SYM_EXPORT) + || ( ((*ppLSect)->tSymbols[i]->Type==SYM_LOCAL) + && ((*ppLSect)==(*ppLSect)->tSymbols[i]->pSection) ) ) + { + if( strcmp((*ppLSect)->tSymbols[i]->pzName,name)==0 ) + { + struct sSection **ppSect; + ppSect=&pSections; + while( *ppSect ) + ppSect=&((*ppSect)->pNext); + + *ppSect = *ppLSect; + *ppLSect = (*ppLSect)->pNext; + (*ppSect)->pNext = NULL; + return( 1 ); + } + } + + } + ppLSect=&((*ppLSect)->pNext); + } + return( 0 ); +} + +void AddNeededModules( void ) +{ + struct sSection *pSect; + + if( (options&OPT_SMART_C_LINK)==0 ) + { + struct sSection **ppLSect; + + ppLSect=&pLibSections; + + while( *ppLSect ) + { + struct sSection **ppSect; + ppSect=&pSections; + while( *ppSect ) + ppSect=&((*ppSect)->pNext); + + *ppSect = *ppLSect; + *ppLSect = (*ppLSect)->pNext; + (*ppSect)->pNext = NULL; + + /*ppLSect=&((*ppLSect)->pNext);*/ + } + return; + } + + if( options&OPT_SMART_C_LINK ) + { + if( !addmodulecontaining( smartlinkstartsymbol ) ) + { + sprintf( temptext, "Can't find start symbol '%s'", smartlinkstartsymbol ); + fatalerror( temptext ); + } + else + printf( "Smart linking with symbol '%s'\n", smartlinkstartsymbol ); + } + + pSect=pSections; + + while( pSect ) + { + ULONG i; + + for( i=0; inNumberOfSymbols; i+=1 ) + { + if( (pSect->tSymbols[i]->Type==SYM_IMPORT) + || (pSect->tSymbols[i]->Type==SYM_LOCAL) ) + { + if( !symboldefined(pSect->tSymbols[i]->pzName) ) + { + addmodulecontaining( pSect->tSymbols[i]->pzName ); + } + } + + } + pSect=pSect->pNext; + } } \ No newline at end of file diff --git a/src/link/main.c b/src/link/main.c index ad2358ec..27115052 100644 --- a/src/link/main.c +++ b/src/link/main.c @@ -1,230 +1,230 @@ -#include -#include -#include - -#include "object.h" -#include "output.h" -#include "assign.h" -#include "patch.h" -#include "asmotor.h" -#include "mylink.h" -#include "mapfile.h" -#include "main.h" -#include "library.h" - -// Quick and dirty...but it works -#ifdef __GNUC__ -#define strcmpi strcasecmp -#endif - -enum eBlockType -{ - BLOCK_COMMENT, - BLOCK_OBJECTS, - BLOCK_LIBRARIES, - BLOCK_OUTPUT -}; - -SLONG options=0; -SLONG fillchar=-1; -enum eOutputType outputtype=OUTPUT_GBROM; -char temptext[1024]; -char smartlinkstartsymbol[256]; - -/* - * Print out an errormessage - * - */ - -void fatalerror( char *s ) -{ - printf( "*ERROR* : %s\n", s ); - exit( 5 ); -} - -/* - * Print the usagescreen - * - */ - -void PrintUsage( void ) -{ - printf( "xLink v" LINK_VERSION " (part of ASMotor " ASMOTOR_VERSION ")\n\n" - "Usage: xlink [options] linkfile\n" - "Options:\n\t-h\t\tThis text\n" - "\t-m\tWrite a mapfile\n" - "\t-n\tWrite a NO$GMB compatible symfile\n" - "\t-z\t\tSet the byte value (hex format) used for uninitialised\n" - "\t\t\tdata (default is ? for random)\n" - "\t-s\tPerform smart linking starting with \n" - "\t-t\t\tOutput target\n" - "\t\t-tg\tGameboy ROM image(default)\n" - "\t\t-ts\tGameboy small mode (32kB)\n" - "\t\t-tp\tPsion2 reloc module\n" ); - exit( 0 ); -} - -/* - * Parse the linkfile and load all the objectfiles - * - */ - -void ProcessLinkfile( char *tzLinkfile ) -{ - FILE *pLinkfile; - enum eBlockType CurrentBlock=BLOCK_COMMENT; - - if( pLinkfile=fopen(tzLinkfile,"rt") ) - { - while( !feof(pLinkfile) ) - { - char tzLine[256]; - - fscanf( pLinkfile, "%s\n", tzLine ); - if( tzLine[0]!='#' ) - { - if( tzLine[0]=='[' && tzLine[strlen(tzLine)-1]==']' ) - { - if( strcmpi("[objects]",tzLine)==0 ) - CurrentBlock=BLOCK_OBJECTS; - else if( strcmpi("[output]",tzLine)==0 ) - CurrentBlock=BLOCK_OUTPUT; - else if( strcmpi("[libraries]",tzLine)==0 ) - CurrentBlock=BLOCK_LIBRARIES; - else if( strcmpi("[comment]",tzLine)==0 ) - CurrentBlock=BLOCK_COMMENT; - else - { - fclose( pLinkfile ); - sprintf( temptext, "Unknown block '%s'\n", tzLine ); - fatalerror( temptext ); - } - } - else - { - switch( CurrentBlock ) - { - case BLOCK_COMMENT: - break; - case BLOCK_OBJECTS: - obj_Readfile( tzLine ); - break; - case BLOCK_LIBRARIES: - lib_Readfile( tzLine ); - break; - case BLOCK_OUTPUT: - out_Setname( tzLine ); - break; - } - } - } - } - fclose( pLinkfile ); - } - else - { - sprintf( temptext, "Unable to find linkfile '%s'\n", tzLinkfile ); - fatalerror( temptext ); - } - -} - -/* - * The main routine - * - */ - -int main( int argc, char *argv[] ) -{ - SLONG argn=0; - - argc-=1; - argn+=1; - - if( argc==0 ) - PrintUsage(); - - while( *argv[argn]=='-' ) - { - char opt; - argc-=1; - switch( opt=argv[argn++][1] ) - { - case '?': - case 'h': - PrintUsage(); - break; - case 'm': - SetMapfileName( argv[argn-1]+2 ); - break; - case 'n': - SetSymfileName( argv[argn-1]+2 ); - break; - case 't': - switch( opt=argv[argn-1][2] ) - { - case 'g': - outputtype=OUTPUT_GBROM; - break; - case 's': - outputtype=OUTPUT_GBROM; - options|=OPT_SMALL; - break; - case 'p': - outputtype=OUTPUT_PSION2; - break; - default: - sprintf( temptext, "Unknown option 't%c'\n", opt ); - fatalerror( temptext ); - break; - } - break; - case 'z': - if( strlen(argv[argn-1]+2)<=2 ) - { - if( strcmp(argv[argn-1]+2,"?")==0 ) - { - fillchar=-1; - } - else - { - int result; - - result=sscanf( argv[argn-1]+2, "%x", &fillchar ); - if( !((result==EOF) || (result==1)) ) - { - fatalerror("Invalid argument for option 'z'\n" ); - } - } - } - else - { - fatalerror("Invalid argument for option 'z'\n" ); - } - break; - case 's': - options|=OPT_SMART_C_LINK; - strcpy( smartlinkstartsymbol, argv[argn-1]+2 ); - break; - default: - sprintf( temptext, "Unknown option '%c'\n", opt ); - fatalerror( temptext ); - break; - } - } - - if( argc==1 ) - { - ProcessLinkfile( argv[argn++] ); - AddNeededModules(); - AssignSections(); - CreateSymbolTable(); - Patch(); - Output(); - CloseMapfile(); - } - else - PrintUsage(); - - return( 0 ); +#include +#include +#include + +#include "object.h" +#include "output.h" +#include "assign.h" +#include "patch.h" +#include "asmotor.h" +#include "mylink.h" +#include "mapfile.h" +#include "main.h" +#include "library.h" + +// Quick and dirty...but it works +#ifdef __GNUC__ +#define strcmpi strcasecmp +#endif + +enum eBlockType +{ + BLOCK_COMMENT, + BLOCK_OBJECTS, + BLOCK_LIBRARIES, + BLOCK_OUTPUT +}; + +SLONG options=0; +SLONG fillchar=-1; +enum eOutputType outputtype=OUTPUT_GBROM; +char temptext[1024]; +char smartlinkstartsymbol[256]; + +/* + * Print out an errormessage + * + */ + +void fatalerror( char *s ) +{ + printf( "*ERROR* : %s\n", s ); + exit( 5 ); +} + +/* + * Print the usagescreen + * + */ + +void PrintUsage( void ) +{ + printf( "xLink v" LINK_VERSION " (part of ASMotor " ASMOTOR_VERSION ")\n\n" + "Usage: xlink [options] linkfile\n" + "Options:\n\t-h\t\tThis text\n" + "\t-m\tWrite a mapfile\n" + "\t-n\tWrite a NO$GMB compatible symfile\n" + "\t-z\t\tSet the byte value (hex format) used for uninitialised\n" + "\t\t\tdata (default is ? for random)\n" + "\t-s\tPerform smart linking starting with \n" + "\t-t\t\tOutput target\n" + "\t\t-tg\tGameboy ROM image(default)\n" + "\t\t-ts\tGameboy small mode (32kB)\n" + "\t\t-tp\tPsion2 reloc module\n" ); + exit( 0 ); +} + +/* + * Parse the linkfile and load all the objectfiles + * + */ + +void ProcessLinkfile( char *tzLinkfile ) +{ + FILE *pLinkfile; + enum eBlockType CurrentBlock=BLOCK_COMMENT; + + if( pLinkfile=fopen(tzLinkfile,"rt") ) + { + while( !feof(pLinkfile) ) + { + char tzLine[256]; + + fscanf( pLinkfile, "%s\n", tzLine ); + if( tzLine[0]!='#' ) + { + if( tzLine[0]=='[' && tzLine[strlen(tzLine)-1]==']' ) + { + if( strcmpi("[objects]",tzLine)==0 ) + CurrentBlock=BLOCK_OBJECTS; + else if( strcmpi("[output]",tzLine)==0 ) + CurrentBlock=BLOCK_OUTPUT; + else if( strcmpi("[libraries]",tzLine)==0 ) + CurrentBlock=BLOCK_LIBRARIES; + else if( strcmpi("[comment]",tzLine)==0 ) + CurrentBlock=BLOCK_COMMENT; + else + { + fclose( pLinkfile ); + sprintf( temptext, "Unknown block '%s'\n", tzLine ); + fatalerror( temptext ); + } + } + else + { + switch( CurrentBlock ) + { + case BLOCK_COMMENT: + break; + case BLOCK_OBJECTS: + obj_Readfile( tzLine ); + break; + case BLOCK_LIBRARIES: + lib_Readfile( tzLine ); + break; + case BLOCK_OUTPUT: + out_Setname( tzLine ); + break; + } + } + } + } + fclose( pLinkfile ); + } + else + { + sprintf( temptext, "Unable to find linkfile '%s'\n", tzLinkfile ); + fatalerror( temptext ); + } + +} + +/* + * The main routine + * + */ + +int main( int argc, char *argv[] ) +{ + SLONG argn=0; + + argc-=1; + argn+=1; + + if( argc==0 ) + PrintUsage(); + + while( *argv[argn]=='-' ) + { + char opt; + argc-=1; + switch( opt=argv[argn++][1] ) + { + case '?': + case 'h': + PrintUsage(); + break; + case 'm': + SetMapfileName( argv[argn-1]+2 ); + break; + case 'n': + SetSymfileName( argv[argn-1]+2 ); + break; + case 't': + switch( opt=argv[argn-1][2] ) + { + case 'g': + outputtype=OUTPUT_GBROM; + break; + case 's': + outputtype=OUTPUT_GBROM; + options|=OPT_SMALL; + break; + case 'p': + outputtype=OUTPUT_PSION2; + break; + default: + sprintf( temptext, "Unknown option 't%c'\n", opt ); + fatalerror( temptext ); + break; + } + break; + case 'z': + if( strlen(argv[argn-1]+2)<=2 ) + { + if( strcmp(argv[argn-1]+2,"?")==0 ) + { + fillchar=-1; + } + else + { + int result; + + result=sscanf( argv[argn-1]+2, "%x", &fillchar ); + if( !((result==EOF) || (result==1)) ) + { + fatalerror("Invalid argument for option 'z'\n" ); + } + } + } + else + { + fatalerror("Invalid argument for option 'z'\n" ); + } + break; + case 's': + options|=OPT_SMART_C_LINK; + strcpy( smartlinkstartsymbol, argv[argn-1]+2 ); + break; + default: + sprintf( temptext, "Unknown option '%c'\n", opt ); + fatalerror( temptext ); + break; + } + } + + if( argc==1 ) + { + ProcessLinkfile( argv[argn++] ); + AddNeededModules(); + AssignSections(); + CreateSymbolTable(); + Patch(); + Output(); + CloseMapfile(); + } + else + PrintUsage(); + + return( 0 ); } \ No newline at end of file diff --git a/src/link/mapfile.c b/src/link/mapfile.c index a0c23246..2019f271 100644 --- a/src/link/mapfile.c +++ b/src/link/mapfile.c @@ -1,108 +1,108 @@ -#include -#include -#include - -#include "asmotor.h" -#include "main.h" -#include "mylink.h" -#include "assign.h" - -FILE *mf=NULL; -FILE *sf=NULL; -SLONG currentbank=0; -SLONG sfbank; - -void SetMapfileName( char *name ) -{ - if( mf=fopen(name,"wt") ) - return; - else - fatalerror( "Unable to open mapfile for writing" ); -} - -void SetSymfileName( char *name ) -{ - if( sf=fopen(name,"wt") ) - { - fprintf( sf, ";File generated by xLink v" LINK_VERSION "\n\n" ); - return; - } - else - fatalerror( "Unable to open symfile for writing" ); -} - -void CloseMapfile( void ) -{ - if( mf ) - { - fclose( mf ); - mf=NULL; - } - if( sf ) - { - fclose( sf ); - sf=NULL; - } -} - -void MapfileInitBank( SLONG bank ) -{ - if( mf ) - { - currentbank=bank; - if( bank==0 ) - fprintf( mf, "Bank #0 (HOME):\n" ); - else if( bank<=255 ) - fprintf( mf, "Bank #%d:\n", bank ); - else if( bank==BANK_BSS ) - fprintf( mf, "BSS:\n" ); - else if( bank==BANK_HRAM ) - fprintf( mf, "HRAM:\n" ); - else if( bank==BANK_VRAM ) - fprintf( mf, "VRAM:\n" ); - } - - if( sf ) - { - sfbank=(bank>=1&&bank<=255)?bank:0; - } -} - -void MapfileWriteSection( struct sSection *pSect ) -{ - if( mf || sf ) - { - SLONG i; - - fprintf( mf, " SECTION: $%04X-$%04X ($%04X bytes)\n", pSect->nOrg, pSect->nOrg+pSect->nByteSize-1, pSect->nByteSize ); - - for( i=0; inNumberOfSymbols; i+=1 ) - { - struct sSymbol *pSym; - pSym=pSect->tSymbols[i]; - if( (pSym->pSection==pSect) && (pSym->Type!=SYM_IMPORT) ) - { - if( mf ) - { - fprintf( mf, " $%04X = %s\n", pSym->nOffset+pSect->nOrg, pSym->pzName ); - } - if( sf ) - { - fprintf( sf, "%02X:%04X %s\n", sfbank, pSym->nOffset+pSect->nOrg, pSym->pzName ); - } - - } - } - } -} - -void MapfileCloseBank( SLONG slack ) -{ - if( mf ) - { - if( slack==MaxAvail[currentbank] ) - fprintf( mf, " EMPTY\n\n" ); - else - fprintf( mf, " SLACK: $%04X bytes\n\n", slack ); - } +#include +#include +#include + +#include "asmotor.h" +#include "main.h" +#include "mylink.h" +#include "assign.h" + +FILE *mf=NULL; +FILE *sf=NULL; +SLONG currentbank=0; +SLONG sfbank; + +void SetMapfileName( char *name ) +{ + if( mf=fopen(name,"wt") ) + return; + else + fatalerror( "Unable to open mapfile for writing" ); +} + +void SetSymfileName( char *name ) +{ + if( sf=fopen(name,"wt") ) + { + fprintf( sf, ";File generated by xLink v" LINK_VERSION "\n\n" ); + return; + } + else + fatalerror( "Unable to open symfile for writing" ); +} + +void CloseMapfile( void ) +{ + if( mf ) + { + fclose( mf ); + mf=NULL; + } + if( sf ) + { + fclose( sf ); + sf=NULL; + } +} + +void MapfileInitBank( SLONG bank ) +{ + if( mf ) + { + currentbank=bank; + if( bank==0 ) + fprintf( mf, "Bank #0 (HOME):\n" ); + else if( bank<=255 ) + fprintf( mf, "Bank #%d:\n", bank ); + else if( bank==BANK_BSS ) + fprintf( mf, "BSS:\n" ); + else if( bank==BANK_HRAM ) + fprintf( mf, "HRAM:\n" ); + else if( bank==BANK_VRAM ) + fprintf( mf, "VRAM:\n" ); + } + + if( sf ) + { + sfbank=(bank>=1&&bank<=255)?bank:0; + } +} + +void MapfileWriteSection( struct sSection *pSect ) +{ + if( mf || sf ) + { + SLONG i; + + fprintf( mf, " SECTION: $%04X-$%04X ($%04X bytes)\n", pSect->nOrg, pSect->nOrg+pSect->nByteSize-1, pSect->nByteSize ); + + for( i=0; inNumberOfSymbols; i+=1 ) + { + struct sSymbol *pSym; + pSym=pSect->tSymbols[i]; + if( (pSym->pSection==pSect) && (pSym->Type!=SYM_IMPORT) ) + { + if( mf ) + { + fprintf( mf, " $%04X = %s\n", pSym->nOffset+pSect->nOrg, pSym->pzName ); + } + if( sf ) + { + fprintf( sf, "%02X:%04X %s\n", sfbank, pSym->nOffset+pSect->nOrg, pSym->pzName ); + } + + } + } + } +} + +void MapfileCloseBank( SLONG slack ) +{ + if( mf ) + { + if( slack==MaxAvail[currentbank] ) + fprintf( mf, " EMPTY\n\n" ); + else + fprintf( mf, " SLACK: $%04X bytes\n\n", slack ); + } } \ No newline at end of file diff --git a/src/link/object.c b/src/link/object.c index 902814d0..7a30728b 100644 --- a/src/link/object.c +++ b/src/link/object.c @@ -1,546 +1,546 @@ -/* - * Here we have the routines that read an objectfile - * - */ - -#include -#include -#include - -#include "mylink.h" -#include "main.h" - -struct sSymbol **tSymbols; -struct sSection *pSections=NULL; -struct sSection *pLibSections=NULL; -UBYTE dummymem; -BBOOL oReadLib=0; - - -/* - * The usual byte order stuff - * - */ - -SLONG readlong( FILE *f ) -{ - SLONG r; - - r =fgetc(f); - r|=fgetc(f)<<8; - r|=fgetc(f)<<16; - r|=fgetc(f)<<24; - - return( r ); -} - -UWORD readword( FILE *f ) -{ - UWORD r; - - r =fgetc(f); - r|=fgetc(f)<<8; - - return( r ); -} - -/* - * Read a NULL terminated string from a file - * - */ - -SLONG readasciiz( char *s, FILE *f ) -{ - SLONG r=0; - - while( ((*s++)=fgetc(f))!=0 ) - r+=1; - - return( r+1 ); -} - - -/* - * Allocate a new section and link it into the list - * - */ - -struct sSection *AllocSection( void ) -{ - struct sSection **ppSections; - - if( oReadLib==1 ) - ppSections=&pLibSections; - else - ppSections=&pSections; - - while( *ppSections ) - ppSections=&((*ppSections)->pNext); - - if( (*ppSections)=(struct sSection *)malloc(sizeof(struct sSection)) ) - { - (*ppSections)->tSymbols=tSymbols; - (*ppSections)->pNext=NULL; - (*ppSections)->pPatches=NULL; - (*ppSections)->oAssigned=0; - return( *ppSections ); - } - else - { - fatalerror( "Out of memory!" ); - return( NULL ); - } -} - -/* - * Read a symbol from a file - * - */ - -struct sSymbol *obj_ReadSymbol( FILE *f ) -{ - char s[256]; - struct sSymbol *pSym; - - if( pSym=(struct sSymbol *)malloc(sizeof(struct sSymbol)) ) - { - readasciiz( s, f ); - if( pSym->pzName=(char *)malloc(strlen(s)+1) ) - { - strcpy( pSym->pzName, s ); - if( (pSym->Type=(enum eSymbolType)fgetc(f))!=SYM_IMPORT ) - { - pSym->nSectionID=readlong(f); - pSym->nOffset=readlong(f); - } - return( pSym ); - } - else - fatalerror( "Out of memory!" ); - } - else - fatalerror( "Out of memory!" ); - - return( NULL ); -} - -/* - * RGB0 object reader routines - * - */ - -struct sSection *obj_ReadRGB0Section( FILE *f ) -{ - struct sSection *pSection; - - pSection=AllocSection(); - - pSection->nByteSize=readlong( f ); - pSection->Type=(enum eSectionType)fgetc( f ); - pSection->nOrg=-1; - pSection->nBank=-1; - - /* does the user want the -s mode? */ - - if( (options&OPT_SMALL) && (pSection->Type==SECT_CODE) ) - { - pSection->Type=SECT_HOME; - } - - if( (pSection->Type==SECT_CODE) || (pSection->Type==SECT_HOME) ) - { - /* - * These sectiontypes contain data... - * - */ - if( pSection->nByteSize ) - { - if( pSection->pData=(UBYTE *)malloc(pSection->nByteSize) ) - { - SLONG nNumberOfPatches; - struct sPatch **ppPatch, *pPatch; - char s[256]; - - fread( pSection->pData, sizeof(UBYTE), pSection->nByteSize, f ); - nNumberOfPatches=readlong(f); - ppPatch=&pSection->pPatches; - - /* - * And patches... - * - */ - while( nNumberOfPatches-- ) - { - if( pPatch=(struct sPatch *)malloc(sizeof(struct sPatch)) ) - { - *ppPatch=pPatch; - readasciiz( s, f ); - if( pPatch->pzFilename=(char *)malloc(strlen(s)+1) ) - { - strcpy( pPatch->pzFilename, s ); - pPatch->nLineNo=readlong( f ); - pPatch->nOffset=readlong( f ); - pPatch->Type=(enum ePatchType)fgetc( f ); - if( (pPatch->nRPNSize=readlong(f))>0 ) - { - if( pPatch->pRPN=(UBYTE *)malloc(pPatch->nRPNSize) ) - fread( pPatch->pRPN, sizeof(UBYTE), pPatch->nRPNSize, f ); - else - fatalerror( "Out of memory!" ); - } - else - pPatch->pRPN=NULL; - pPatch->pNext=NULL; - ppPatch=&(pPatch->pNext); - } - else - fatalerror( "Out of memory!" ); - } - else - fatalerror( "Out of memory!" ); - } - } - else - fatalerror( "Out of memory!" ); - } - else - { - readlong(f); // Skip number of patches - pSection->pData=&dummymem; - } - } - - return( pSection ); -} - -void obj_ReadRGB0( FILE *pObjfile ) -{ - struct sSection *pFirstSection; - SLONG nNumberOfSymbols, nNumberOfSections, i; - - nNumberOfSymbols=readlong( pObjfile ); - nNumberOfSections=readlong( pObjfile ); - - /* First comes the symbols */ - - if( nNumberOfSymbols ) - { - if( tSymbols=(struct sSymbol **)malloc(nNumberOfSymbols*sizeof(struct sSymbol *)) ) - { - for( i=0; inNumberOfSymbols=nNumberOfSymbols; - if( pFirstSection==NULL ) - pFirstSection=pNewSection; - } - - /* - * Fill in the pSection entry in the symbolstructure. - * This REALLY needs some cleaning up... but, hey, it works - * - */ - - for( i=0; iType!=SYM_IMPORT && tSymbols[i]->nSectionID!=-1 ) - { - SLONG j=0; - while( j != tSymbols[i]->nSectionID ) - { - j+=1; - pConvSect=pConvSect->pNext; - } - tSymbols[i]->pSection=pConvSect; - } - else - tSymbols[i]->pSection=NULL; - } -} - -/* - * RGB1 object reader routines - * - */ - -struct sSection *obj_ReadRGB1Section( FILE *f ) -{ - struct sSection *pSection; - - pSection=AllocSection(); - - pSection->nByteSize=readlong( f ); - pSection->Type=(enum eSectionType)fgetc( f ); - /* - * And because of THIS new feature I'll have to rewrite loads and - * loads of stuff... oh well it needed to be done anyway - * - */ - pSection->nOrg=readlong( f ); - pSection->nBank=readlong( f ); - - /* does the user want the -s mode? */ - - if( (options&OPT_SMALL) && (pSection->Type==SECT_CODE) ) - { - pSection->Type=SECT_HOME; - } - - if( (pSection->Type==SECT_CODE) || (pSection->Type==SECT_HOME) ) - { - /* - * These sectiontypes contain data... - * - */ - if( pSection->nByteSize ) - { - if( pSection->pData=(UBYTE *)malloc(pSection->nByteSize) ) - { - SLONG nNumberOfPatches; - struct sPatch **ppPatch, *pPatch; - char s[256]; - - fread( pSection->pData, sizeof(UBYTE), pSection->nByteSize, f ); - nNumberOfPatches=readlong(f); - ppPatch=&pSection->pPatches; - - /* - * And patches... - * - */ - while( nNumberOfPatches-- ) - { - if( pPatch=(struct sPatch *)malloc(sizeof(struct sPatch)) ) - { - *ppPatch=pPatch; - readasciiz( s, f ); - if( pPatch->pzFilename=(char *)malloc(strlen(s)+1) ) - { - strcpy( pPatch->pzFilename, s ); - pPatch->nLineNo=readlong( f ); - pPatch->nOffset=readlong( f ); - pPatch->Type=(enum ePatchType)fgetc( f ); - if( (pPatch->nRPNSize=readlong(f))>0 ) - { - if( pPatch->pRPN=(UBYTE *)malloc(pPatch->nRPNSize) ) - fread( pPatch->pRPN, sizeof(UBYTE), pPatch->nRPNSize, f ); - else - fatalerror( "Out of memory!" ); - } - else - pPatch->pRPN=NULL; - pPatch->pNext=NULL; - ppPatch=&(pPatch->pNext); - } - else - fatalerror( "Out of memory!" ); - } - else - fatalerror( "Out of memory!" ); - } - } - else - fatalerror( "Out of memory!" ); - } - else - { - readlong(f); // Skip number of patches - pSection->pData=&dummymem; - } - } - - return( pSection ); -} - -void obj_ReadRGB1( FILE *pObjfile ) -{ - struct sSection *pFirstSection; - SLONG nNumberOfSymbols, nNumberOfSections, i; - - nNumberOfSymbols=readlong( pObjfile ); - nNumberOfSections=readlong( pObjfile ); - - /* First comes the symbols */ - - if( nNumberOfSymbols ) - { - if( tSymbols=(struct sSymbol **)malloc(nNumberOfSymbols*sizeof(struct sSymbol *)) ) - { - for( i=0; inNumberOfSymbols=nNumberOfSymbols; - if( pFirstSection==NULL ) - pFirstSection=pNewSection; - } - - /* - * Fill in the pSection entry in the symbolstructure. - * This REALLY needs some cleaning up... but, hey, it works - * - */ - - for( i=0; iType!=SYM_IMPORT && tSymbols[i]->nSectionID!=-1 ) - { - SLONG j=0; - while( j != tSymbols[i]->nSectionID ) - { - j+=1; - pConvSect=pConvSect->pNext; - } - tSymbols[i]->pSection=pConvSect; - } - else - tSymbols[i]->pSection=NULL; - } -} - -/* - * The main objectfileloadroutine (phew) - * - */ - -void obj_ReadOpenFile( FILE *pObjfile, char *tzObjectfile ) -{ - char tzHeader[8]; - - fread( tzHeader, sizeof(char), 4, pObjfile ); - tzHeader[4]=0; - if( strncmp(tzHeader,"RGB", 3)==0 ) - { - switch( tzHeader[3] ) - { - case '0': - obj_ReadRGB0( pObjfile ); - break; - case '1': - case '2': // V2 is really the same but the are new patch types - obj_ReadRGB1( pObjfile ); - break; - default: - sprintf( temptext, "'%s' is an unsupported version\n", tzObjectfile ); - fatalerror( temptext ); - break; - } - } - else - { - sprintf( temptext, "'%s' is not a valid object\n", tzObjectfile ); - fatalerror( temptext ); - } -} - -void obj_Readfile( char *tzObjectfile ) -{ - FILE *pObjfile; - - if( options&OPT_SMART_C_LINK ) - oReadLib=1; - else - oReadLib=0; - - if( pObjfile=fopen(tzObjectfile,"rb") ) - { - obj_ReadOpenFile( pObjfile, tzObjectfile ); - fclose( pObjfile ); - } - else - { - sprintf( temptext, "Unable to open '%s'\n", tzObjectfile ); - fatalerror( temptext ); - } - - oReadLib=0; -} - -SLONG file_Length( FILE *f ) -{ - ULONG r, - p; - - p=ftell( f ); - fseek( f, 0, SEEK_END ); - r=ftell( f ); - fseek( f, p, SEEK_SET ); - - return( r ); -} - -void lib_ReadXLB0( FILE *f ) -{ - SLONG size; - - size=file_Length( f )-4; - while( size ) - { - char name[256]; - - size-=readasciiz( name, f ); - readword( f ); size-=2; - readword( f ); size-=2; - size-=readlong( f ); size-=4; - obj_ReadOpenFile( f, name ); - } -} - -void lib_Readfile( char *tzLibfile ) -{ - FILE *pObjfile; - - oReadLib=1; - - if( pObjfile=fopen(tzLibfile,"rb") ) - { - char tzHeader[5]; - - fread( tzHeader, sizeof(char), 4, pObjfile ); - tzHeader[4]=0; - if( strcmp(tzHeader,"XLB0")==0 ) - lib_ReadXLB0( pObjfile ); - else - { - sprintf( temptext, "'%s' is an invalid library\n", tzLibfile ); - fatalerror( temptext ); - } - fclose( pObjfile ); - } - else - { - sprintf( temptext, "Unable to open '%s'\n", tzLibfile ); - fatalerror( temptext ); - } +/* + * Here we have the routines that read an objectfile + * + */ + +#include +#include +#include + +#include "mylink.h" +#include "main.h" + +struct sSymbol **tSymbols; +struct sSection *pSections=NULL; +struct sSection *pLibSections=NULL; +UBYTE dummymem; +BBOOL oReadLib=0; + + +/* + * The usual byte order stuff + * + */ + +SLONG readlong( FILE *f ) +{ + SLONG r; + + r =fgetc(f); + r|=fgetc(f)<<8; + r|=fgetc(f)<<16; + r|=fgetc(f)<<24; + + return( r ); +} + +UWORD readword( FILE *f ) +{ + UWORD r; + + r =fgetc(f); + r|=fgetc(f)<<8; + + return( r ); +} + +/* + * Read a NULL terminated string from a file + * + */ + +SLONG readasciiz( char *s, FILE *f ) +{ + SLONG r=0; + + while( ((*s++)=fgetc(f))!=0 ) + r+=1; + + return( r+1 ); +} + + +/* + * Allocate a new section and link it into the list + * + */ + +struct sSection *AllocSection( void ) +{ + struct sSection **ppSections; + + if( oReadLib==1 ) + ppSections=&pLibSections; + else + ppSections=&pSections; + + while( *ppSections ) + ppSections=&((*ppSections)->pNext); + + if( (*ppSections)=(struct sSection *)malloc(sizeof(struct sSection)) ) + { + (*ppSections)->tSymbols=tSymbols; + (*ppSections)->pNext=NULL; + (*ppSections)->pPatches=NULL; + (*ppSections)->oAssigned=0; + return( *ppSections ); + } + else + { + fatalerror( "Out of memory!" ); + return( NULL ); + } +} + +/* + * Read a symbol from a file + * + */ + +struct sSymbol *obj_ReadSymbol( FILE *f ) +{ + char s[256]; + struct sSymbol *pSym; + + if( pSym=(struct sSymbol *)malloc(sizeof(struct sSymbol)) ) + { + readasciiz( s, f ); + if( pSym->pzName=(char *)malloc(strlen(s)+1) ) + { + strcpy( pSym->pzName, s ); + if( (pSym->Type=(enum eSymbolType)fgetc(f))!=SYM_IMPORT ) + { + pSym->nSectionID=readlong(f); + pSym->nOffset=readlong(f); + } + return( pSym ); + } + else + fatalerror( "Out of memory!" ); + } + else + fatalerror( "Out of memory!" ); + + return( NULL ); +} + +/* + * RGB0 object reader routines + * + */ + +struct sSection *obj_ReadRGB0Section( FILE *f ) +{ + struct sSection *pSection; + + pSection=AllocSection(); + + pSection->nByteSize=readlong( f ); + pSection->Type=(enum eSectionType)fgetc( f ); + pSection->nOrg=-1; + pSection->nBank=-1; + + /* does the user want the -s mode? */ + + if( (options&OPT_SMALL) && (pSection->Type==SECT_CODE) ) + { + pSection->Type=SECT_HOME; + } + + if( (pSection->Type==SECT_CODE) || (pSection->Type==SECT_HOME) ) + { + /* + * These sectiontypes contain data... + * + */ + if( pSection->nByteSize ) + { + if( pSection->pData=(UBYTE *)malloc(pSection->nByteSize) ) + { + SLONG nNumberOfPatches; + struct sPatch **ppPatch, *pPatch; + char s[256]; + + fread( pSection->pData, sizeof(UBYTE), pSection->nByteSize, f ); + nNumberOfPatches=readlong(f); + ppPatch=&pSection->pPatches; + + /* + * And patches... + * + */ + while( nNumberOfPatches-- ) + { + if( pPatch=(struct sPatch *)malloc(sizeof(struct sPatch)) ) + { + *ppPatch=pPatch; + readasciiz( s, f ); + if( pPatch->pzFilename=(char *)malloc(strlen(s)+1) ) + { + strcpy( pPatch->pzFilename, s ); + pPatch->nLineNo=readlong( f ); + pPatch->nOffset=readlong( f ); + pPatch->Type=(enum ePatchType)fgetc( f ); + if( (pPatch->nRPNSize=readlong(f))>0 ) + { + if( pPatch->pRPN=(UBYTE *)malloc(pPatch->nRPNSize) ) + fread( pPatch->pRPN, sizeof(UBYTE), pPatch->nRPNSize, f ); + else + fatalerror( "Out of memory!" ); + } + else + pPatch->pRPN=NULL; + pPatch->pNext=NULL; + ppPatch=&(pPatch->pNext); + } + else + fatalerror( "Out of memory!" ); + } + else + fatalerror( "Out of memory!" ); + } + } + else + fatalerror( "Out of memory!" ); + } + else + { + readlong(f); // Skip number of patches + pSection->pData=&dummymem; + } + } + + return( pSection ); +} + +void obj_ReadRGB0( FILE *pObjfile ) +{ + struct sSection *pFirstSection; + SLONG nNumberOfSymbols, nNumberOfSections, i; + + nNumberOfSymbols=readlong( pObjfile ); + nNumberOfSections=readlong( pObjfile ); + + /* First comes the symbols */ + + if( nNumberOfSymbols ) + { + if( tSymbols=(struct sSymbol **)malloc(nNumberOfSymbols*sizeof(struct sSymbol *)) ) + { + for( i=0; inNumberOfSymbols=nNumberOfSymbols; + if( pFirstSection==NULL ) + pFirstSection=pNewSection; + } + + /* + * Fill in the pSection entry in the symbolstructure. + * This REALLY needs some cleaning up... but, hey, it works + * + */ + + for( i=0; iType!=SYM_IMPORT && tSymbols[i]->nSectionID!=-1 ) + { + SLONG j=0; + while( j != tSymbols[i]->nSectionID ) + { + j+=1; + pConvSect=pConvSect->pNext; + } + tSymbols[i]->pSection=pConvSect; + } + else + tSymbols[i]->pSection=NULL; + } +} + +/* + * RGB1 object reader routines + * + */ + +struct sSection *obj_ReadRGB1Section( FILE *f ) +{ + struct sSection *pSection; + + pSection=AllocSection(); + + pSection->nByteSize=readlong( f ); + pSection->Type=(enum eSectionType)fgetc( f ); + /* + * And because of THIS new feature I'll have to rewrite loads and + * loads of stuff... oh well it needed to be done anyway + * + */ + pSection->nOrg=readlong( f ); + pSection->nBank=readlong( f ); + + /* does the user want the -s mode? */ + + if( (options&OPT_SMALL) && (pSection->Type==SECT_CODE) ) + { + pSection->Type=SECT_HOME; + } + + if( (pSection->Type==SECT_CODE) || (pSection->Type==SECT_HOME) ) + { + /* + * These sectiontypes contain data... + * + */ + if( pSection->nByteSize ) + { + if( pSection->pData=(UBYTE *)malloc(pSection->nByteSize) ) + { + SLONG nNumberOfPatches; + struct sPatch **ppPatch, *pPatch; + char s[256]; + + fread( pSection->pData, sizeof(UBYTE), pSection->nByteSize, f ); + nNumberOfPatches=readlong(f); + ppPatch=&pSection->pPatches; + + /* + * And patches... + * + */ + while( nNumberOfPatches-- ) + { + if( pPatch=(struct sPatch *)malloc(sizeof(struct sPatch)) ) + { + *ppPatch=pPatch; + readasciiz( s, f ); + if( pPatch->pzFilename=(char *)malloc(strlen(s)+1) ) + { + strcpy( pPatch->pzFilename, s ); + pPatch->nLineNo=readlong( f ); + pPatch->nOffset=readlong( f ); + pPatch->Type=(enum ePatchType)fgetc( f ); + if( (pPatch->nRPNSize=readlong(f))>0 ) + { + if( pPatch->pRPN=(UBYTE *)malloc(pPatch->nRPNSize) ) + fread( pPatch->pRPN, sizeof(UBYTE), pPatch->nRPNSize, f ); + else + fatalerror( "Out of memory!" ); + } + else + pPatch->pRPN=NULL; + pPatch->pNext=NULL; + ppPatch=&(pPatch->pNext); + } + else + fatalerror( "Out of memory!" ); + } + else + fatalerror( "Out of memory!" ); + } + } + else + fatalerror( "Out of memory!" ); + } + else + { + readlong(f); // Skip number of patches + pSection->pData=&dummymem; + } + } + + return( pSection ); +} + +void obj_ReadRGB1( FILE *pObjfile ) +{ + struct sSection *pFirstSection; + SLONG nNumberOfSymbols, nNumberOfSections, i; + + nNumberOfSymbols=readlong( pObjfile ); + nNumberOfSections=readlong( pObjfile ); + + /* First comes the symbols */ + + if( nNumberOfSymbols ) + { + if( tSymbols=(struct sSymbol **)malloc(nNumberOfSymbols*sizeof(struct sSymbol *)) ) + { + for( i=0; inNumberOfSymbols=nNumberOfSymbols; + if( pFirstSection==NULL ) + pFirstSection=pNewSection; + } + + /* + * Fill in the pSection entry in the symbolstructure. + * This REALLY needs some cleaning up... but, hey, it works + * + */ + + for( i=0; iType!=SYM_IMPORT && tSymbols[i]->nSectionID!=-1 ) + { + SLONG j=0; + while( j != tSymbols[i]->nSectionID ) + { + j+=1; + pConvSect=pConvSect->pNext; + } + tSymbols[i]->pSection=pConvSect; + } + else + tSymbols[i]->pSection=NULL; + } +} + +/* + * The main objectfileloadroutine (phew) + * + */ + +void obj_ReadOpenFile( FILE *pObjfile, char *tzObjectfile ) +{ + char tzHeader[8]; + + fread( tzHeader, sizeof(char), 4, pObjfile ); + tzHeader[4]=0; + if( strncmp(tzHeader,"RGB", 3)==0 ) + { + switch( tzHeader[3] ) + { + case '0': + obj_ReadRGB0( pObjfile ); + break; + case '1': + case '2': // V2 is really the same but the are new patch types + obj_ReadRGB1( pObjfile ); + break; + default: + sprintf( temptext, "'%s' is an unsupported version\n", tzObjectfile ); + fatalerror( temptext ); + break; + } + } + else + { + sprintf( temptext, "'%s' is not a valid object\n", tzObjectfile ); + fatalerror( temptext ); + } +} + +void obj_Readfile( char *tzObjectfile ) +{ + FILE *pObjfile; + + if( options&OPT_SMART_C_LINK ) + oReadLib=1; + else + oReadLib=0; + + if( pObjfile=fopen(tzObjectfile,"rb") ) + { + obj_ReadOpenFile( pObjfile, tzObjectfile ); + fclose( pObjfile ); + } + else + { + sprintf( temptext, "Unable to open '%s'\n", tzObjectfile ); + fatalerror( temptext ); + } + + oReadLib=0; +} + +SLONG file_Length( FILE *f ) +{ + ULONG r, + p; + + p=ftell( f ); + fseek( f, 0, SEEK_END ); + r=ftell( f ); + fseek( f, p, SEEK_SET ); + + return( r ); +} + +void lib_ReadXLB0( FILE *f ) +{ + SLONG size; + + size=file_Length( f )-4; + while( size ) + { + char name[256]; + + size-=readasciiz( name, f ); + readword( f ); size-=2; + readword( f ); size-=2; + size-=readlong( f ); size-=4; + obj_ReadOpenFile( f, name ); + } +} + +void lib_Readfile( char *tzLibfile ) +{ + FILE *pObjfile; + + oReadLib=1; + + if( pObjfile=fopen(tzLibfile,"rb") ) + { + char tzHeader[5]; + + fread( tzHeader, sizeof(char), 4, pObjfile ); + tzHeader[4]=0; + if( strcmp(tzHeader,"XLB0")==0 ) + lib_ReadXLB0( pObjfile ); + else + { + sprintf( temptext, "'%s' is an invalid library\n", tzLibfile ); + fatalerror( temptext ); + } + fclose( pObjfile ); + } + else + { + sprintf( temptext, "Unable to open '%s'\n", tzLibfile ); + fatalerror( temptext ); + } } \ No newline at end of file diff --git a/src/link/output.c b/src/link/output.c index e5747efe..fe857c0d 100644 --- a/src/link/output.c +++ b/src/link/output.c @@ -1,222 +1,222 @@ -#include -#include -#include - -#include "mylink.h" -#include "mapfile.h" -#include "main.h" -#include "assign.h" - -char tzOutname[_MAX_PATH]; -BBOOL oOutput=0; - -void writehome( FILE *f ) -{ - struct sSection *pSect; - UBYTE *mem; - - if( mem=(UBYTE *)malloc(MaxAvail[BANK_HOME]) ) - { - if( fillchar!=-1 ) - { - memset( mem, fillchar, MaxAvail[BANK_HOME] ); - } - MapfileInitBank( 0 ); - - pSect=pSections; - while( pSect ) - { - if( pSect->Type==SECT_HOME ) - { - memcpy( mem+pSect->nOrg, pSect->pData, pSect->nByteSize ); - MapfileWriteSection( pSect ); - } - pSect=pSect->pNext; - } - - MapfileCloseBank( area_Avail(0) ); - - fwrite( mem, 1, MaxAvail[BANK_HOME], f ); - free( mem ); - } -} - -void writebank( FILE *f, SLONG bank ) -{ - struct sSection *pSect; - UBYTE *mem; - - if( mem=(UBYTE *)malloc(MaxAvail[bank]) ) - { - if( fillchar!=-1 ) - { - memset( mem, fillchar, MaxAvail[bank] ); - } - - MapfileInitBank( bank ); - - pSect=pSections; - while( pSect ) - { - if( pSect->Type==SECT_CODE && pSect->nBank==bank ) - { - memcpy( mem+pSect->nOrg-0x4000, pSect->pData, pSect->nByteSize ); - MapfileWriteSection( pSect ); - } - pSect=pSect->pNext; - } - - MapfileCloseBank( area_Avail(bank) ); - - fwrite( mem, 1, MaxAvail[bank], f ); - free( mem ); - } -} - -void out_Setname( char *tzOutputfile ) -{ - strcpy( tzOutname, tzOutputfile ); - oOutput=1; -} - -void GBROM_Output( void ) -{ - SLONG i; - FILE *f; - - if( f=fopen(tzOutname,"wb") ) - { - writehome( f ); - for( i=1; i<=MaxBankUsed; i+=1 ) - writebank( f, i ); - - fclose( f ); - } - - for( i=256; inBank==i ) - { - MapfileWriteSection( pSect ); - } - pSect=pSect->pNext; - } - MapfileCloseBank( area_Avail(i) ); - } -} - -void PSION2_Output( void ) -{ - FILE *f; - - if( f=fopen(tzOutname,"wb") ) - { - struct sSection *pSect; - UBYTE *mem; - ULONG size=MaxAvail[0]-area_Avail(0); - ULONG relocpatches; - - fputc( size>>24, f ); - fputc( size>>16, f ); - fputc( size>>8, f ); - fputc( size, f ); - - if( mem=(UBYTE *)malloc(MaxAvail[0]-area_Avail(0)) ) - { - MapfileInitBank( 0 ); - - pSect=pSections; - while( pSect ) - { - if( pSect->Type==SECT_CODE ) - { - memcpy( mem+pSect->nOrg, pSect->pData, pSect->nByteSize ); - MapfileWriteSection( pSect ); - } - else - { - memset( mem+pSect->nOrg, 0, pSect->nByteSize ); - } - pSect=pSect->pNext; - } - - MapfileCloseBank( area_Avail(0) ); - - fwrite( mem, 1, MaxAvail[0]-area_Avail(0), f ); - free( mem ); - } - - relocpatches=0; - pSect=pSections; - while( pSect ) - { - struct sPatch *pPatch; - - pPatch=pSect->pPatches; - - while( pPatch ) - { - if( pPatch->oRelocPatch ) - { - relocpatches+=1; - } - pPatch=pPatch->pNext; - } - pSect=pSect->pNext; - } - - fputc( relocpatches>>24, f ); - fputc( relocpatches>>16, f ); - fputc( relocpatches>>8, f ); - fputc( relocpatches, f ); - - pSect=pSections; - while( pSect ) - { - struct sPatch *pPatch; - - pPatch=pSect->pPatches; - - while( pPatch ) - { - if( pPatch->oRelocPatch ) - { - ULONG address; - - address=pPatch->nOffset+pSect->nOrg; - fputc( address>>24, f ); - fputc( address>>16, f ); - fputc( address>>8, f ); - fputc( address, f ); - } - pPatch=pPatch->pNext; - } - pSect=pSect->pNext; - } - - - - fclose( f ); - } -} - -void Output( void ) -{ - if( oOutput ) - { - switch( outputtype ) - { - case OUTPUT_GBROM: - GBROM_Output(); - break; - case OUTPUT_PSION2: - PSION2_Output(); - break; - } - } +#include +#include +#include + +#include "mylink.h" +#include "mapfile.h" +#include "main.h" +#include "assign.h" + +char tzOutname[_MAX_PATH]; +BBOOL oOutput=0; + +void writehome( FILE *f ) +{ + struct sSection *pSect; + UBYTE *mem; + + if( mem=(UBYTE *)malloc(MaxAvail[BANK_HOME]) ) + { + if( fillchar!=-1 ) + { + memset( mem, fillchar, MaxAvail[BANK_HOME] ); + } + MapfileInitBank( 0 ); + + pSect=pSections; + while( pSect ) + { + if( pSect->Type==SECT_HOME ) + { + memcpy( mem+pSect->nOrg, pSect->pData, pSect->nByteSize ); + MapfileWriteSection( pSect ); + } + pSect=pSect->pNext; + } + + MapfileCloseBank( area_Avail(0) ); + + fwrite( mem, 1, MaxAvail[BANK_HOME], f ); + free( mem ); + } +} + +void writebank( FILE *f, SLONG bank ) +{ + struct sSection *pSect; + UBYTE *mem; + + if( mem=(UBYTE *)malloc(MaxAvail[bank]) ) + { + if( fillchar!=-1 ) + { + memset( mem, fillchar, MaxAvail[bank] ); + } + + MapfileInitBank( bank ); + + pSect=pSections; + while( pSect ) + { + if( pSect->Type==SECT_CODE && pSect->nBank==bank ) + { + memcpy( mem+pSect->nOrg-0x4000, pSect->pData, pSect->nByteSize ); + MapfileWriteSection( pSect ); + } + pSect=pSect->pNext; + } + + MapfileCloseBank( area_Avail(bank) ); + + fwrite( mem, 1, MaxAvail[bank], f ); + free( mem ); + } +} + +void out_Setname( char *tzOutputfile ) +{ + strcpy( tzOutname, tzOutputfile ); + oOutput=1; +} + +void GBROM_Output( void ) +{ + SLONG i; + FILE *f; + + if( f=fopen(tzOutname,"wb") ) + { + writehome( f ); + for( i=1; i<=MaxBankUsed; i+=1 ) + writebank( f, i ); + + fclose( f ); + } + + for( i=256; inBank==i ) + { + MapfileWriteSection( pSect ); + } + pSect=pSect->pNext; + } + MapfileCloseBank( area_Avail(i) ); + } +} + +void PSION2_Output( void ) +{ + FILE *f; + + if( f=fopen(tzOutname,"wb") ) + { + struct sSection *pSect; + UBYTE *mem; + ULONG size=MaxAvail[0]-area_Avail(0); + ULONG relocpatches; + + fputc( size>>24, f ); + fputc( size>>16, f ); + fputc( size>>8, f ); + fputc( size, f ); + + if( mem=(UBYTE *)malloc(MaxAvail[0]-area_Avail(0)) ) + { + MapfileInitBank( 0 ); + + pSect=pSections; + while( pSect ) + { + if( pSect->Type==SECT_CODE ) + { + memcpy( mem+pSect->nOrg, pSect->pData, pSect->nByteSize ); + MapfileWriteSection( pSect ); + } + else + { + memset( mem+pSect->nOrg, 0, pSect->nByteSize ); + } + pSect=pSect->pNext; + } + + MapfileCloseBank( area_Avail(0) ); + + fwrite( mem, 1, MaxAvail[0]-area_Avail(0), f ); + free( mem ); + } + + relocpatches=0; + pSect=pSections; + while( pSect ) + { + struct sPatch *pPatch; + + pPatch=pSect->pPatches; + + while( pPatch ) + { + if( pPatch->oRelocPatch ) + { + relocpatches+=1; + } + pPatch=pPatch->pNext; + } + pSect=pSect->pNext; + } + + fputc( relocpatches>>24, f ); + fputc( relocpatches>>16, f ); + fputc( relocpatches>>8, f ); + fputc( relocpatches, f ); + + pSect=pSections; + while( pSect ) + { + struct sPatch *pPatch; + + pPatch=pSect->pPatches; + + while( pPatch ) + { + if( pPatch->oRelocPatch ) + { + ULONG address; + + address=pPatch->nOffset+pSect->nOrg; + fputc( address>>24, f ); + fputc( address>>16, f ); + fputc( address>>8, f ); + fputc( address, f ); + } + pPatch=pPatch->pNext; + } + pSect=pSect->pNext; + } + + + + fclose( f ); + } +} + +void Output( void ) +{ + if( oOutput ) + { + switch( outputtype ) + { + case OUTPUT_GBROM: + GBROM_Output(); + break; + case OUTPUT_PSION2: + PSION2_Output(); + break; + } + } } \ No newline at end of file diff --git a/src/link/patch.c b/src/link/patch.c index f6ccfe77..58b5b941 100644 --- a/src/link/patch.c +++ b/src/link/patch.c @@ -1,300 +1,300 @@ -#include -#include - -#include "mylink.h" -#include "symbol.h" -#include "main.h" - -struct sSection *pCurrentSection; -SLONG rpnstack[256]; -SLONG rpnp; -SLONG nPC; - -void rpnpush( SLONG i ) -{ - rpnstack[rpnp++]=i; -} - -SLONG rpnpop( void ) -{ - return( rpnstack[--rpnp] ); -} - -SLONG getsymvalue( SLONG symid ) -{ - switch( pCurrentSection->tSymbols[symid]->Type ) - { - case SYM_IMPORT: - return( sym_GetValue(pCurrentSection->tSymbols[symid]->pzName) ); - break; - case SYM_EXPORT: - case SYM_LOCAL: - { - if( strcmp(pCurrentSection->tSymbols[symid]->pzName,"@")==0 ) - { - return( nPC ); - } - else - return( pCurrentSection->tSymbols[symid]->nOffset+pCurrentSection->tSymbols[symid]->pSection->nOrg ); - } - default: - break; - } - fatalerror( "*INTERNAL* UNKNOWN SYMBOL TYPE" ); - return( 0 ); -} - -SLONG getsymbank( SLONG symid ) -{ - switch( pCurrentSection->tSymbols[symid]->Type ) - { - case SYM_IMPORT: - return( sym_GetBank(pCurrentSection->tSymbols[symid]->pzName) ); - break; - case SYM_EXPORT: - case SYM_LOCAL: - return( pCurrentSection->tSymbols[symid]->pSection->nBank ); - //return( pCurrentSection->nBank ); - default: - break; - } - fatalerror( "*INTERNAL* UNKNOWN SYMBOL TYPE" ); - return( 0 ); -} - -SLONG calcrpn( struct sPatch *pPatch ) -{ - SLONG t, size; - UBYTE *rpn; - - rpnp=0; - - size=pPatch->nRPNSize; - rpn=pPatch->pRPN; - pPatch->oRelocPatch=0; - - while( size>0 ) - { - size-=1; - switch( *rpn++ ) - { - case RPN_ADD: - rpnpush( rpnpop()+rpnpop() ); - break; - case RPN_SUB: - t=rpnpop(); - rpnpush( rpnpop()-t ); - break; - case RPN_MUL: - rpnpush( rpnpop()*rpnpop() ); - break; - case RPN_DIV: - t=rpnpop(); - rpnpush( rpnpop()/t ); - break; - case RPN_MOD: - t=rpnpop(); - rpnpush( rpnpop()%t ); - break; - case RPN_UNSUB: - rpnpush( -rpnpop() ); - break; - case RPN_OR: - rpnpush( rpnpop()|rpnpop() ); - break; - case RPN_AND: - rpnpush( rpnpop()&rpnpop() ); - break; - case RPN_XOR: - rpnpush( rpnpop()^rpnpop() ); - break; - case RPN_UNNOT: - rpnpush( rpnpop()^0xFFFFFFFF ); - break; - case RPN_LOGAND: - rpnpush( rpnpop()&&rpnpop() ); - break; - case RPN_LOGOR: - rpnpush( rpnpop()||rpnpop() ); - break; - case RPN_LOGUNNOT: - rpnpush( !rpnpop() ); - break; - case RPN_LOGEQ: - rpnpush( rpnpop()==rpnpop() ); - break; - case RPN_LOGNE: - rpnpush( rpnpop()!=rpnpop() ); - break; - case RPN_LOGGT: - t=rpnpop(); - rpnpush( rpnpop()>t ); - break; - case RPN_LOGLT: - t=rpnpop(); - rpnpush( rpnpop()=t ); - break; - case RPN_LOGLE: - t=rpnpop(); - rpnpush( rpnpop()<=t ); - break; - case RPN_SHL: - t=rpnpop(); - rpnpush( rpnpop()<>t ); - break; - case RPN_HRAM: - t=rpnpop(); - rpnpush(t&0xFF); - if( t<0 || (t>0xFF && t<0xFF00) || t>0xFFFF ) - { - sprintf( temptext, "%s(%d) : Value must be in the HRAM area", pPatch->pzFilename, pPatch->nLineNo ); - fatalerror( temptext ); - } - break; - case RPN_PCEZP: - t=rpnpop(); - rpnpush(t&0xFF); - if( t<0x2000 || t>0x20FF ) - { - sprintf( temptext, "%s(%d) : Value must be in the ZP area", pPatch->pzFilename, pPatch->nLineNo ); - fatalerror( temptext ); - } - break; - case RPN_CONST: - /* constant */ - t=(*rpn++); - t|=(*rpn++)<<8; - t|=(*rpn++)<<16; - t|=(*rpn++)<<24; - rpnpush( t ); - size-=4; - break; - case RPN_SYM: - /* symbol */ - t=(*rpn++); - t|=(*rpn++)<<8; - t|=(*rpn++)<<16; - t|=(*rpn++)<<24; - rpnpush( getsymvalue(t) ); - pPatch->oRelocPatch|=(getsymbank(t)!=-1); - size-=4; - break; - case RPN_BANK: - /* symbol */ - t=(*rpn++); - t|=(*rpn++)<<8; - t|=(*rpn++)<<16; - t|=(*rpn++)<<24; - rpnpush( getsymbank(t) ); - size-=4; - break; - case RPN_RANGECHECK: - { - SLONG low, - high; - - low =(*rpn++); - low|=(*rpn++)<<8; - low|=(*rpn++)<<16; - low|=(*rpn++)<<24; - high =(*rpn++); - high|=(*rpn++)<<8; - high|=(*rpn++)<<16; - high|=(*rpn++)<<24; - t=rpnpop(); - if( thigh ) - { - sprintf( temptext, "%s(%d) : Value must be in the range [%d;%d]", pPatch->pzFilename, pPatch->nLineNo, low, high ); - fatalerror( temptext ); - } - rpnpush(t); - size-=8; - break; - } - } - } - return( rpnpop() ); -} - -void Patch( void ) -{ - struct sSection *pSect; - - pSect=pSections; - while( pSect ) - { - struct sPatch *pPatch; - - pCurrentSection=pSect; - pPatch=pSect->pPatches; - while( pPatch ) - { - SLONG t; - - nPC=pSect->nOrg+pPatch->nOffset; - t=calcrpn( pPatch ); - switch( pPatch->Type ) - { - case PATCH_BYTE: - if( t>=-128 && t<=255 ) - { - t&=0xFF; - pSect->pData[pPatch->nOffset]=(UBYTE)t; - } - else - { - sprintf( temptext, "%s(%d) : Value must be 8-bit\n", pPatch->pzFilename, pPatch->nLineNo ); - fatalerror( temptext ); - } - break; - case PATCH_WORD_L: - case PATCH_WORD_B: - if( t>=-32768 && t<=65535 ) - { - t&=0xFFFF; - if( pPatch->Type==PATCH_WORD_L ) - { - pSect->pData[pPatch->nOffset]=t&0xFF; - pSect->pData[pPatch->nOffset+1]=(t>>8)&0xFF; - } - else - { - // Assume big endian - pSect->pData[pPatch->nOffset]=(t>>8)&0xFF; - pSect->pData[pPatch->nOffset+1]=t&0xFF; - } - } - else - { - sprintf( temptext, "%s(%d) : Value must be 16-bit\n", pPatch->pzFilename, pPatch->nLineNo ); - fatalerror( temptext ); - } - break; - case PATCH_LONG_L: - pSect->pData[pPatch->nOffset+0]=t&0xFF; - pSect->pData[pPatch->nOffset+1]=(t>>8)&0xFF; - pSect->pData[pPatch->nOffset+2]=(t>>16)&0xFF; - pSect->pData[pPatch->nOffset+3]=(t>>24)&0xFF; - break; - case PATCH_LONG_B: - pSect->pData[pPatch->nOffset+0]=(t>>24)&0xFF; - pSect->pData[pPatch->nOffset+1]=(t>>16)&0xFF; - pSect->pData[pPatch->nOffset+2]=(t>>8)&0xFF; - pSect->pData[pPatch->nOffset+3]=t&0xFF; - break; - } - - pPatch=pPatch->pNext; - } - - pSect=pSect->pNext; - } +#include +#include + +#include "mylink.h" +#include "symbol.h" +#include "main.h" + +struct sSection *pCurrentSection; +SLONG rpnstack[256]; +SLONG rpnp; +SLONG nPC; + +void rpnpush( SLONG i ) +{ + rpnstack[rpnp++]=i; +} + +SLONG rpnpop( void ) +{ + return( rpnstack[--rpnp] ); +} + +SLONG getsymvalue( SLONG symid ) +{ + switch( pCurrentSection->tSymbols[symid]->Type ) + { + case SYM_IMPORT: + return( sym_GetValue(pCurrentSection->tSymbols[symid]->pzName) ); + break; + case SYM_EXPORT: + case SYM_LOCAL: + { + if( strcmp(pCurrentSection->tSymbols[symid]->pzName,"@")==0 ) + { + return( nPC ); + } + else + return( pCurrentSection->tSymbols[symid]->nOffset+pCurrentSection->tSymbols[symid]->pSection->nOrg ); + } + default: + break; + } + fatalerror( "*INTERNAL* UNKNOWN SYMBOL TYPE" ); + return( 0 ); +} + +SLONG getsymbank( SLONG symid ) +{ + switch( pCurrentSection->tSymbols[symid]->Type ) + { + case SYM_IMPORT: + return( sym_GetBank(pCurrentSection->tSymbols[symid]->pzName) ); + break; + case SYM_EXPORT: + case SYM_LOCAL: + return( pCurrentSection->tSymbols[symid]->pSection->nBank ); + //return( pCurrentSection->nBank ); + default: + break; + } + fatalerror( "*INTERNAL* UNKNOWN SYMBOL TYPE" ); + return( 0 ); +} + +SLONG calcrpn( struct sPatch *pPatch ) +{ + SLONG t, size; + UBYTE *rpn; + + rpnp=0; + + size=pPatch->nRPNSize; + rpn=pPatch->pRPN; + pPatch->oRelocPatch=0; + + while( size>0 ) + { + size-=1; + switch( *rpn++ ) + { + case RPN_ADD: + rpnpush( rpnpop()+rpnpop() ); + break; + case RPN_SUB: + t=rpnpop(); + rpnpush( rpnpop()-t ); + break; + case RPN_MUL: + rpnpush( rpnpop()*rpnpop() ); + break; + case RPN_DIV: + t=rpnpop(); + rpnpush( rpnpop()/t ); + break; + case RPN_MOD: + t=rpnpop(); + rpnpush( rpnpop()%t ); + break; + case RPN_UNSUB: + rpnpush( -rpnpop() ); + break; + case RPN_OR: + rpnpush( rpnpop()|rpnpop() ); + break; + case RPN_AND: + rpnpush( rpnpop()&rpnpop() ); + break; + case RPN_XOR: + rpnpush( rpnpop()^rpnpop() ); + break; + case RPN_UNNOT: + rpnpush( rpnpop()^0xFFFFFFFF ); + break; + case RPN_LOGAND: + rpnpush( rpnpop()&&rpnpop() ); + break; + case RPN_LOGOR: + rpnpush( rpnpop()||rpnpop() ); + break; + case RPN_LOGUNNOT: + rpnpush( !rpnpop() ); + break; + case RPN_LOGEQ: + rpnpush( rpnpop()==rpnpop() ); + break; + case RPN_LOGNE: + rpnpush( rpnpop()!=rpnpop() ); + break; + case RPN_LOGGT: + t=rpnpop(); + rpnpush( rpnpop()>t ); + break; + case RPN_LOGLT: + t=rpnpop(); + rpnpush( rpnpop()=t ); + break; + case RPN_LOGLE: + t=rpnpop(); + rpnpush( rpnpop()<=t ); + break; + case RPN_SHL: + t=rpnpop(); + rpnpush( rpnpop()<>t ); + break; + case RPN_HRAM: + t=rpnpop(); + rpnpush(t&0xFF); + if( t<0 || (t>0xFF && t<0xFF00) || t>0xFFFF ) + { + sprintf( temptext, "%s(%d) : Value must be in the HRAM area", pPatch->pzFilename, pPatch->nLineNo ); + fatalerror( temptext ); + } + break; + case RPN_PCEZP: + t=rpnpop(); + rpnpush(t&0xFF); + if( t<0x2000 || t>0x20FF ) + { + sprintf( temptext, "%s(%d) : Value must be in the ZP area", pPatch->pzFilename, pPatch->nLineNo ); + fatalerror( temptext ); + } + break; + case RPN_CONST: + /* constant */ + t=(*rpn++); + t|=(*rpn++)<<8; + t|=(*rpn++)<<16; + t|=(*rpn++)<<24; + rpnpush( t ); + size-=4; + break; + case RPN_SYM: + /* symbol */ + t=(*rpn++); + t|=(*rpn++)<<8; + t|=(*rpn++)<<16; + t|=(*rpn++)<<24; + rpnpush( getsymvalue(t) ); + pPatch->oRelocPatch|=(getsymbank(t)!=-1); + size-=4; + break; + case RPN_BANK: + /* symbol */ + t=(*rpn++); + t|=(*rpn++)<<8; + t|=(*rpn++)<<16; + t|=(*rpn++)<<24; + rpnpush( getsymbank(t) ); + size-=4; + break; + case RPN_RANGECHECK: + { + SLONG low, + high; + + low =(*rpn++); + low|=(*rpn++)<<8; + low|=(*rpn++)<<16; + low|=(*rpn++)<<24; + high =(*rpn++); + high|=(*rpn++)<<8; + high|=(*rpn++)<<16; + high|=(*rpn++)<<24; + t=rpnpop(); + if( thigh ) + { + sprintf( temptext, "%s(%d) : Value must be in the range [%d;%d]", pPatch->pzFilename, pPatch->nLineNo, low, high ); + fatalerror( temptext ); + } + rpnpush(t); + size-=8; + break; + } + } + } + return( rpnpop() ); +} + +void Patch( void ) +{ + struct sSection *pSect; + + pSect=pSections; + while( pSect ) + { + struct sPatch *pPatch; + + pCurrentSection=pSect; + pPatch=pSect->pPatches; + while( pPatch ) + { + SLONG t; + + nPC=pSect->nOrg+pPatch->nOffset; + t=calcrpn( pPatch ); + switch( pPatch->Type ) + { + case PATCH_BYTE: + if( t>=-128 && t<=255 ) + { + t&=0xFF; + pSect->pData[pPatch->nOffset]=(UBYTE)t; + } + else + { + sprintf( temptext, "%s(%d) : Value must be 8-bit\n", pPatch->pzFilename, pPatch->nLineNo ); + fatalerror( temptext ); + } + break; + case PATCH_WORD_L: + case PATCH_WORD_B: + if( t>=-32768 && t<=65535 ) + { + t&=0xFFFF; + if( pPatch->Type==PATCH_WORD_L ) + { + pSect->pData[pPatch->nOffset]=t&0xFF; + pSect->pData[pPatch->nOffset+1]=(t>>8)&0xFF; + } + else + { + // Assume big endian + pSect->pData[pPatch->nOffset]=(t>>8)&0xFF; + pSect->pData[pPatch->nOffset+1]=t&0xFF; + } + } + else + { + sprintf( temptext, "%s(%d) : Value must be 16-bit\n", pPatch->pzFilename, pPatch->nLineNo ); + fatalerror( temptext ); + } + break; + case PATCH_LONG_L: + pSect->pData[pPatch->nOffset+0]=t&0xFF; + pSect->pData[pPatch->nOffset+1]=(t>>8)&0xFF; + pSect->pData[pPatch->nOffset+2]=(t>>16)&0xFF; + pSect->pData[pPatch->nOffset+3]=(t>>24)&0xFF; + break; + case PATCH_LONG_B: + pSect->pData[pPatch->nOffset+0]=(t>>24)&0xFF; + pSect->pData[pPatch->nOffset+1]=(t>>16)&0xFF; + pSect->pData[pPatch->nOffset+2]=(t>>8)&0xFF; + pSect->pData[pPatch->nOffset+3]=t&0xFF; + break; + } + + pPatch=pPatch->pNext; + } + + pSect=pSect->pNext; + } } \ No newline at end of file diff --git a/src/link/symbol.c b/src/link/symbol.c index bd4a3778..1a9802e9 100644 --- a/src/link/symbol.c +++ b/src/link/symbol.c @@ -1,125 +1,125 @@ -#include -#include -#include -#include "main.h" -#include "patch.h" -#include "types.h" - -#define HASHSIZE 73 - -struct ISymbol -{ - char *pzName; - SLONG nValue; - SLONG nBank; // -1=const - struct ISymbol *pNext; -}; - -struct ISymbol *tHash[HASHSIZE]; - -SLONG calchash( char *s ) -{ - SLONG r=0; - while( *s ) - r+=*s++; - - return( r%HASHSIZE ); -} - -void sym_Init( void ) -{ - SLONG i; - for( i=0; ipzName) ) - { - ppSym=&((*ppSym)->pNext); - } - else - { - return( (*ppSym)->nValue ); - } - } - - sprintf( temptext, "Unknown symbol '%s'", tzName ); - fatalerror( temptext ); - return( 0 ); - } -} - -SLONG sym_GetBank( char *tzName ) -{ - struct ISymbol **ppSym; - - ppSym=&(tHash[calchash(tzName)]); - while( *ppSym ) - { - if( strcmp(tzName,(*ppSym)->pzName) ) - { - ppSym=&((*ppSym)->pNext); - } - else - { - return( (*ppSym)->nBank ); - } - } - - sprintf( temptext, "Unknown symbol '%s'" ); - fatalerror( temptext ); - return( 0 ); -} - -void sym_CreateSymbol( char *tzName, SLONG nValue, SBYTE nBank ) -{ - if( strcmp(tzName,"@")==0 ) - { - } - else - { - struct ISymbol **ppSym; - - ppSym=&(tHash[calchash(tzName)]); - - while( *ppSym ) - { - if( strcmp(tzName,(*ppSym)->pzName) ) - { - ppSym=&((*ppSym)->pNext); - } - else - { - if( nBank==-1 ) - return; - - sprintf( temptext, "Symbol '%s' defined more than once\n", tzName ); - fatalerror( temptext ); - } - } - - if( *ppSym=(struct ISymbol *)malloc(sizeof(struct ISymbol)) ) - { - if( (*ppSym)->pzName=(char *)malloc(strlen(tzName)+1) ) - { - strcpy( (*ppSym)->pzName, tzName ); - (*ppSym)->nValue=nValue; - (*ppSym)->nBank=nBank; - (*ppSym)->pNext=NULL; - } - } - } +#include +#include +#include +#include "main.h" +#include "patch.h" +#include "types.h" + +#define HASHSIZE 73 + +struct ISymbol +{ + char *pzName; + SLONG nValue; + SLONG nBank; // -1=const + struct ISymbol *pNext; +}; + +struct ISymbol *tHash[HASHSIZE]; + +SLONG calchash( char *s ) +{ + SLONG r=0; + while( *s ) + r+=*s++; + + return( r%HASHSIZE ); +} + +void sym_Init( void ) +{ + SLONG i; + for( i=0; ipzName) ) + { + ppSym=&((*ppSym)->pNext); + } + else + { + return( (*ppSym)->nValue ); + } + } + + sprintf( temptext, "Unknown symbol '%s'", tzName ); + fatalerror( temptext ); + return( 0 ); + } +} + +SLONG sym_GetBank( char *tzName ) +{ + struct ISymbol **ppSym; + + ppSym=&(tHash[calchash(tzName)]); + while( *ppSym ) + { + if( strcmp(tzName,(*ppSym)->pzName) ) + { + ppSym=&((*ppSym)->pNext); + } + else + { + return( (*ppSym)->nBank ); + } + } + + sprintf( temptext, "Unknown symbol '%s'" ); + fatalerror( temptext ); + return( 0 ); +} + +void sym_CreateSymbol( char *tzName, SLONG nValue, SBYTE nBank ) +{ + if( strcmp(tzName,"@")==0 ) + { + } + else + { + struct ISymbol **ppSym; + + ppSym=&(tHash[calchash(tzName)]); + + while( *ppSym ) + { + if( strcmp(tzName,(*ppSym)->pzName) ) + { + ppSym=&((*ppSym)->pNext); + } + else + { + if( nBank==-1 ) + return; + + sprintf( temptext, "Symbol '%s' defined more than once\n", tzName ); + fatalerror( temptext ); + } + } + + if( *ppSym=(struct ISymbol *)malloc(sizeof(struct ISymbol)) ) + { + if( (*ppSym)->pzName=(char *)malloc(strlen(tzName)+1) ) + { + strcpy( (*ppSym)->pzName, tzName ); + (*ppSym)->nValue=nValue; + (*ppSym)->nBank=nBank; + (*ppSym)->pNext=NULL; + } + } + } } \ No newline at end of file diff --git a/src/rgbfix/main.c b/src/rgbfix/main.c index 0e27076d..2e66790f 100644 --- a/src/rgbfix/main.c +++ b/src/rgbfix/main.c @@ -1,432 +1,432 @@ -/* - * RGBFix : Perform various tasks on a Gameboy image-file - * - */ - -#include -#include -#include -#include "asmotor.h" - - - -/* - * Option defines - * - */ - -#define OPTF_DEBUG 0x01L -#define OPTF_PAD 0x02L -#define OPTF_VALIDATE 0x04L -#define OPTF_TITLE 0x08L -#define OPTF_TRUNCATE 0x10L - -unsigned long ulOptions; - - - - -/* - * Misc. variables - * - */ - -unsigned char NintendoChar[48]= -{ - 0xCE,0xED,0x66,0x66,0xCC,0x0D,0x00,0x0B,0x03,0x73,0x00,0x83,0x00,0x0C,0x00,0x0D, - 0x00,0x08,0x11,0x1F,0x88,0x89,0x00,0x0E,0xDC,0xCC,0x6E,0xE6,0xDD,0xDD,0xD9,0x99, - 0xBB,0xBB,0x67,0x63,0x6E,0x0E,0xEC,0xCC,0xDD,0xDC,0x99,0x9F,0xBB,0xB9,0x33,0x3E -}; - - - - -/* - * Misc. routines - * - */ - -void PrintUsage( void ) -{ - printf( "RGBFix v" RGBFIX_VERSION " (part of ASMotor " ASMOTOR_VERSION ")\n\n" ); - printf( "Usage: rgbfix [options] image[.gb]\n" ); - printf( "Options:\n" ); - printf( "\t-h\t\tThis text\n" ); - printf( "\t-d\t\tDebug: Don't change image\n" ); - printf( "\t-p\t\tPad image to valid size\n\t\t\tPads to 32/64/128/256/512kB as appropriate\n" ); - printf( "\t-r\t\ttRuncate image to valid size\n\t\t\tTruncates to 32/64/128/256/512kB as appropriate\n" ); - printf( "\t-t\tChange cartridge title field (16 characters)\n" ); - printf( "\t-v\t\tValidate header\n\t\t\tCorrects - Nintendo Character Area (0x0104)\n\t\t\t\t - ROM type (0x0147)\n\t\t\t\t - ROM size (0x0148)\n\t\t\t\t - Checksums (0x014D-0x014F)\n" ); - exit( 0 ); -} - -void FatalError( char *s ) -{ - printf( "\n***ERROR: %s\n\n", s ); - PrintUsage(); -} - -long int FileSize( FILE *f ) -{ - long prevpos; - long r; - - fflush( f ); - prevpos=ftell( f ); - fseek( f, 0, SEEK_END ); - r=ftell( f ); - fseek( f, prevpos, SEEK_SET ); - return( r ); -} - -int FileExists( char *s ) -{ - FILE *f; - - if( (f=fopen(s,"rb"))!=NULL ) - { - fclose( f ); - return( 1 ); - } - else - return( 0 ); -} - -/* - * Das main - * - */ - -int main( int argc, char *argv[] ) -{ - int argn=1; - char filename[512]; - char cartname[32]; - FILE *f; - - ulOptions=0; - - if( (--argc)==0 ) - PrintUsage(); - - while( *argv[argn]=='-' ) - { - argc-=1; - switch( argv[argn++][1] ) - { - case '?': - case 'h': - PrintUsage(); - break; - case 'd': - ulOptions|=OPTF_DEBUG; - break; - case 'p': - ulOptions|=OPTF_PAD; - break; - case 'r': - ulOptions|=OPTF_TRUNCATE; - break; - case 'v': - ulOptions|=OPTF_VALIDATE; - break; - case 't': - strncpy( cartname, argv[argn-1]+2, 16 ); - ulOptions|=OPTF_TITLE; - break; - } - } - - strcpy( filename, argv[argn++] ); - - if( !FileExists(filename) ) - strcat( filename, ".gb" ); - - if( (f=fopen(filename,"rb+"))!=NULL ) - { - /* - * -d (Debug) option code - * - */ - - if( ulOptions&OPTF_DEBUG ) - { - printf( "-d (Debug) option enabled...\n" ); - } - - /* - * -p (Pad) option code - * - */ - - if( ulOptions&OPTF_PAD ) - { - long size, padto; - long bytesadded=0; - - size=FileSize( f ); - padto=0x8000L; - while( size>padto ) - padto*=2; - - printf( "Padding to %ldkB:\n", padto/1024 ); - -/* - if( padto<=0x80000L ) - { - */ - if( size!=padto ) - { - fflush( stdout ); - - fseek( f, 0, SEEK_END ); - while( size(0x8000L<0x8000L ) - { - /* carttype byte must != 0x00 */ - if( carttype==0x00 ) - { - if( (ulOptions&OPTF_DEBUG)==0 ) - { - fseek( f, -1, SEEK_CUR ); - fputc( 0x01, f ); - fflush( f ); - } - printf( "\tCartridge type byte changed to 0x01\n" ); - } - else - printf( "\tCartridge type byte is OK\n" ); - } - else - { - /* carttype byte can be anything? */ - printf( "\tCartridge type byte is OK\n" ); - } - - /* Checksum */ - - fflush( f ); - fseek( f, 0, SEEK_SET ); - - for( i=0; i<(0x8000L<>8, f ); - fputc( calcchecksum&0xFF, f ); - } - fflush( f ); - printf( "\tChecksum changed from 0x%04lX to 0x%04lX\n", (long)cartchecksum, (long)calcchecksum ); - } - else - printf( "\tChecksum is OK\n" ); - - - if( cartcompchecksum!=calccompchecksum ) - { - fflush( f ); - fseek( f, 0x014DL, SEEK_SET ); - if( (ulOptions&OPTF_DEBUG)==0 ) - fputc( calccompchecksum, f ); - fflush( f ); - printf( "\tCompChecksum changed from 0x%02lX to 0x%02lX\n", (long)cartcompchecksum, (long)calccompchecksum ); - } - else - printf( "\tCompChecksum is OK\n" ); - - } - fclose( f ); - } - else - { - FatalError( "Unable to open file" ); - } - - return( 0 ); +/* + * RGBFix : Perform various tasks on a Gameboy image-file + * + */ + +#include +#include +#include +#include "asmotor.h" + + + +/* + * Option defines + * + */ + +#define OPTF_DEBUG 0x01L +#define OPTF_PAD 0x02L +#define OPTF_VALIDATE 0x04L +#define OPTF_TITLE 0x08L +#define OPTF_TRUNCATE 0x10L + +unsigned long ulOptions; + + + + +/* + * Misc. variables + * + */ + +unsigned char NintendoChar[48]= +{ + 0xCE,0xED,0x66,0x66,0xCC,0x0D,0x00,0x0B,0x03,0x73,0x00,0x83,0x00,0x0C,0x00,0x0D, + 0x00,0x08,0x11,0x1F,0x88,0x89,0x00,0x0E,0xDC,0xCC,0x6E,0xE6,0xDD,0xDD,0xD9,0x99, + 0xBB,0xBB,0x67,0x63,0x6E,0x0E,0xEC,0xCC,0xDD,0xDC,0x99,0x9F,0xBB,0xB9,0x33,0x3E +}; + + + + +/* + * Misc. routines + * + */ + +void PrintUsage( void ) +{ + printf( "RGBFix v" RGBFIX_VERSION " (part of ASMotor " ASMOTOR_VERSION ")\n\n" ); + printf( "Usage: rgbfix [options] image[.gb]\n" ); + printf( "Options:\n" ); + printf( "\t-h\t\tThis text\n" ); + printf( "\t-d\t\tDebug: Don't change image\n" ); + printf( "\t-p\t\tPad image to valid size\n\t\t\tPads to 32/64/128/256/512kB as appropriate\n" ); + printf( "\t-r\t\ttRuncate image to valid size\n\t\t\tTruncates to 32/64/128/256/512kB as appropriate\n" ); + printf( "\t-t\tChange cartridge title field (16 characters)\n" ); + printf( "\t-v\t\tValidate header\n\t\t\tCorrects - Nintendo Character Area (0x0104)\n\t\t\t\t - ROM type (0x0147)\n\t\t\t\t - ROM size (0x0148)\n\t\t\t\t - Checksums (0x014D-0x014F)\n" ); + exit( 0 ); +} + +void FatalError( char *s ) +{ + printf( "\n***ERROR: %s\n\n", s ); + PrintUsage(); +} + +long int FileSize( FILE *f ) +{ + long prevpos; + long r; + + fflush( f ); + prevpos=ftell( f ); + fseek( f, 0, SEEK_END ); + r=ftell( f ); + fseek( f, prevpos, SEEK_SET ); + return( r ); +} + +int FileExists( char *s ) +{ + FILE *f; + + if( (f=fopen(s,"rb"))!=NULL ) + { + fclose( f ); + return( 1 ); + } + else + return( 0 ); +} + +/* + * Das main + * + */ + +int main( int argc, char *argv[] ) +{ + int argn=1; + char filename[512]; + char cartname[32]; + FILE *f; + + ulOptions=0; + + if( (--argc)==0 ) + PrintUsage(); + + while( *argv[argn]=='-' ) + { + argc-=1; + switch( argv[argn++][1] ) + { + case '?': + case 'h': + PrintUsage(); + break; + case 'd': + ulOptions|=OPTF_DEBUG; + break; + case 'p': + ulOptions|=OPTF_PAD; + break; + case 'r': + ulOptions|=OPTF_TRUNCATE; + break; + case 'v': + ulOptions|=OPTF_VALIDATE; + break; + case 't': + strncpy( cartname, argv[argn-1]+2, 16 ); + ulOptions|=OPTF_TITLE; + break; + } + } + + strcpy( filename, argv[argn++] ); + + if( !FileExists(filename) ) + strcat( filename, ".gb" ); + + if( (f=fopen(filename,"rb+"))!=NULL ) + { + /* + * -d (Debug) option code + * + */ + + if( ulOptions&OPTF_DEBUG ) + { + printf( "-d (Debug) option enabled...\n" ); + } + + /* + * -p (Pad) option code + * + */ + + if( ulOptions&OPTF_PAD ) + { + long size, padto; + long bytesadded=0; + + size=FileSize( f ); + padto=0x8000L; + while( size>padto ) + padto*=2; + + printf( "Padding to %ldkB:\n", padto/1024 ); + +/* + if( padto<=0x80000L ) + { + */ + if( size!=padto ) + { + fflush( stdout ); + + fseek( f, 0, SEEK_END ); + while( size(0x8000L<0x8000L ) + { + /* carttype byte must != 0x00 */ + if( carttype==0x00 ) + { + if( (ulOptions&OPTF_DEBUG)==0 ) + { + fseek( f, -1, SEEK_CUR ); + fputc( 0x01, f ); + fflush( f ); + } + printf( "\tCartridge type byte changed to 0x01\n" ); + } + else + printf( "\tCartridge type byte is OK\n" ); + } + else + { + /* carttype byte can be anything? */ + printf( "\tCartridge type byte is OK\n" ); + } + + /* Checksum */ + + fflush( f ); + fseek( f, 0, SEEK_SET ); + + for( i=0; i<(0x8000L<>8, f ); + fputc( calcchecksum&0xFF, f ); + } + fflush( f ); + printf( "\tChecksum changed from 0x%04lX to 0x%04lX\n", (long)cartchecksum, (long)calcchecksum ); + } + else + printf( "\tChecksum is OK\n" ); + + + if( cartcompchecksum!=calccompchecksum ) + { + fflush( f ); + fseek( f, 0x014DL, SEEK_SET ); + if( (ulOptions&OPTF_DEBUG)==0 ) + fputc( calccompchecksum, f ); + fflush( f ); + printf( "\tCompChecksum changed from 0x%02lX to 0x%02lX\n", (long)cartcompchecksum, (long)calccompchecksum ); + } + else + printf( "\tCompChecksum is OK\n" ); + + } + fclose( f ); + } + else + { + FatalError( "Unable to open file" ); + } + + return( 0 ); } \ No newline at end of file