ref: 94fad97aedcd8bd85c53a505db28390e3f82577b
parent: 0d9739535e313b0a2ad19c89b9c85fc7b75237a3
author: Vegard Nossum <[email protected]>
date: Thu Jun 11 03:32:12 EDT 2009
Switch line terminators from CRLF to LF Argh, that obnoxious platform again... ;-) Signed-off-by: Vegard Nossum <[email protected]>
--- 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 <[email protected]> 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 <config.h>
-#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 <stdlib.h>
-
-/* 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 <stdio.h>
-#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 <[email protected]> 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 <config.h>
+#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 <stdlib.h>
+
+/* 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 <stdio.h>
+#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 */
--- a/src/asm/fstack.c
+++ b/src/asm/fstack.c
@@ -1,411 +1,411 @@
-/*
- * RGBAsm - FSTACK.C (FileStack routines)
- *
- * INCLUDES
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#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
--- 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
+};
+
+
+
+
+
+
+
--- 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
--- 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 <nConstValue> reg_r
-%type <nConstValue> reg_ss
-%type <nConstValue> reg_rr
-%type <nConstValue> reg_tt
-%type <nConstValue> ccode
-%type <sVal> op_a_n
-%type <nConstValue> op_a_r
-%type <nConstValue> op_hl_ss
-%type <sVal> 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 <nConstValue> reg_r
+%type <nConstValue> reg_ss
+%type <nConstValue> reg_rr
+%type <nConstValue> reg_tt
+%type <nConstValue> ccode
+%type <sVal> op_a_n
+%type <nConstValue> op_a_r
+%type <nConstValue> op_hl_ss
+%type <sVal> op_mem_ind
--- 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
--- 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 <stdio.h>
-#include <stdlib.h>
-#include <math.h>
-#include <string.h>
-
-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 <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+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
--- 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 <stdlib.h>
-#include <stdio.h>
-#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 <stdlib.h>
+#include <stdio.h>
+#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
--- 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
--- 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;
--- 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 <stdio.h>
-
-#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 <stdio.h>
+
+#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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-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; i<LEXHASHSIZE; i+=1)
- {
- tLexHash[i]=NULL;
- }
-
- for( i=0; i<256; i+=1 )
- {
- tFloatingFirstChar[i]=0;
- tFloatingSecondChar[i]=0;
- tFloatingChars[i]=0;
- }
-
- nLexMaxLeng=0;
- nFloating=0;
-}
-
-void lex_AddStrings( struct sLexInitString *lex )
-{
- while( lex->tzName )
- {
- 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+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; i<LEXHASHSIZE; i+=1)
+ {
+ tLexHash[i]=NULL;
+ }
+
+ for( i=0; i<256; i+=1 )
+ {
+ tFloatingFirstChar[i]=0;
+ tFloatingSecondChar[i]=0;
+ tFloatingChars[i]=0;
+ }
+
+ nLexMaxLeng=0;
+ nFloating=0;
+}
+
+void lex_AddStrings( struct sLexInitString *lex )
+{
+ while( lex->tzName )
+ {
+ 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
--- a/src/asm/main.c
+++ b/src/asm/main.c
@@ -1,406 +1,406 @@
-/*
- * RGBAsm - MAIN.C
- *
- * INCLUDES
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <math.h>
-#include <string.h>
-#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<path>\tExtra include path\n");
- printf ("\t-o<file>\tWrite objectoutput to <file>\n");
- printf ("\t-e(l|b)\t\tChange endianness (CAUTION!)\n");
- printf ("\t-g<ASCI>\tChange the four characters used for Gameboy graphics\n"
- "\t\t\tconstants (default is 0123)\n" );
- printf ("\t-b<AS>\t\tChange the two characters used for binary constants\n"
- "\t\t\t(default is 01)\n" );
- printf ("\t-z<hx>\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 <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <math.h>
+#include <string.h>
+#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<path>\tExtra include path\n");
+ printf ("\t-o<file>\tWrite objectoutput to <file>\n");
+ printf ("\t-e(l|b)\t\tChange endianness (CAUTION!)\n");
+ printf ("\t-g<ASCI>\tChange the four characters used for Gameboy graphics\n"
+ "\t\t\tconstants (default is 0123)\n" );
+ printf ("\t-b<AS>\t\tChange the two characters used for binary constants\n"
+ "\t\t\t(default is 01)\n" );
+ printf ("\t-z<hx>\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
--- a/src/asm/math.c
+++ b/src/asm/math.c
@@ -1,153 +1,153 @@
-/*
- * RGBAsm - MATH.C (Fixedpoint math routines)
- *
- * INCLUDES
- *
- */
-
-#include <math.h>
-#include <stdio.h>
-#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 <math.h>
+#include <stdio.h>
+#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
--- a/src/asm/output.c
+++ b/src/asm/output.c
@@ -1,1027 +1,1027 @@
-/*
- * RGBAsm - OUTPUT.C - Outputs an objectfile
- *
- * INCLUDES
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#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
--- 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 <stdio.h>
-#include <string.h>
-
-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->nVal<src2->nVal);
- 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<<src2->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 <stdio.h>
+#include <string.h>
+
+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->nVal<src2->nVal);
+ 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<<src2->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);
+}
+
--- a/src/asm/symbol.c
+++ b/src/asm/symbol.c
@@ -1,1073 +1,1073 @@
-/*
- * RGBAsm - SYMBOL.C - Symboltable and macroargs stuff
- *
- * INCLUDES
- *
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <time.h>
-#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 <stdio.h>
+#include <string.h>
+#include <time.h>
+#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
--- 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
--- 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
--- 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
--- 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
--- 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
--- a/src/lib/library.c
+++ b/src/lib/library.c
@@ -1,308 +1,308 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#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
--- a/src/lib/main.c
+++ b/src/lib/main.c
@@ -1,143 +1,143 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-#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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#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
--- a/src/link/assign.c
+++ b/src/link/assign.c
@@ -1,570 +1,570 @@
-#include <stdio.h>
-#include <stdlib.h>
-#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; i<MAXBANKS; i+=1 )
- {
- if( BankFree[i]=(struct sFreeArea *)malloc(sizeof(struct sFreeArea)) )
- {
- if( i==0 )
- {
- BankFree[i]->nOrg=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 <stdio.h>
+#include <stdlib.h>
+#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; i<MAXBANKS; i+=1 )
+ {
+ if( BankFree[i]=(struct sFreeArea *)malloc(sizeof(struct sFreeArea)) )
+ {
+ if( i==0 )
+ {
+ BankFree[i]->nOrg=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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- 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
--- a/src/link/library.c
+++ b/src/link/library.c
@@ -1,127 +1,127 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#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; i<pSect->nNumberOfSymbols; 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; i<pSect->nNumberOfSymbols; 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#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; i<pSect->nNumberOfSymbols; 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; i<pSect->nNumberOfSymbols; 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
--- a/src/link/main.c
+++ b/src/link/main.c
@@ -1,230 +1,230 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#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<mapfile>\tWrite a mapfile\n"
- "\t-n<symfile>\tWrite a NO$GMB compatible symfile\n"
- "\t-z<hx>\t\tSet the byte value (hex format) used for uninitialised\n"
- "\t\t\tdata (default is ? for random)\n"
- "\t-s<symbol>\tPerform smart linking starting with <symbol>\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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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<mapfile>\tWrite a mapfile\n"
+ "\t-n<symfile>\tWrite a NO$GMB compatible symfile\n"
+ "\t-z<hx>\t\tSet the byte value (hex format) used for uninitialised\n"
+ "\t\t\tdata (default is ? for random)\n"
+ "\t-s<symbol>\tPerform smart linking starting with <symbol>\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
--- a/src/link/mapfile.c
+++ b/src/link/mapfile.c
@@ -1,108 +1,108 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#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; i<pSect->nNumberOfSymbols; 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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; i<pSect->nNumberOfSymbols; 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
--- a/src/link/object.c
+++ b/src/link/object.c
@@ -1,546 +1,546 @@
-/*
- * Here we have the routines that read an objectfile
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#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; i<nNumberOfSymbols; i+=1 )
- tSymbols[i]=obj_ReadSymbol( pObjfile );
- }
- else
- fatalerror( "Out of memory!" );
- }
- else
- tSymbols=(struct sSymbol **)&dummymem;
-
- /* Next we have the sections */
-
- pFirstSection=NULL;
- while( nNumberOfSections-- )
- {
- struct sSection *pNewSection;
-
- pNewSection=obj_ReadRGB0Section( pObjfile );
- pNewSection->nNumberOfSymbols=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; i<nNumberOfSymbols; i+=1 )
- {
- struct sSection *pConvSect=pFirstSection;
-
- if( tSymbols[i]->Type!=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; i<nNumberOfSymbols; i+=1 )
- tSymbols[i]=obj_ReadSymbol( pObjfile );
- }
- else
- fatalerror( "Out of memory!" );
- }
- else
- tSymbols=(struct sSymbol **)&dummymem;
-
- /* Next we have the sections */
-
- pFirstSection=NULL;
- while( nNumberOfSections-- )
- {
- struct sSection *pNewSection;
-
- pNewSection=obj_ReadRGB1Section( pObjfile );
- pNewSection->nNumberOfSymbols=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; i<nNumberOfSymbols; i+=1 )
- {
- struct sSection *pConvSect=pFirstSection;
-
- if( tSymbols[i]->Type!=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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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; i<nNumberOfSymbols; i+=1 )
+ tSymbols[i]=obj_ReadSymbol( pObjfile );
+ }
+ else
+ fatalerror( "Out of memory!" );
+ }
+ else
+ tSymbols=(struct sSymbol **)&dummymem;
+
+ /* Next we have the sections */
+
+ pFirstSection=NULL;
+ while( nNumberOfSections-- )
+ {
+ struct sSection *pNewSection;
+
+ pNewSection=obj_ReadRGB0Section( pObjfile );
+ pNewSection->nNumberOfSymbols=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; i<nNumberOfSymbols; i+=1 )
+ {
+ struct sSection *pConvSect=pFirstSection;
+
+ if( tSymbols[i]->Type!=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; i<nNumberOfSymbols; i+=1 )
+ tSymbols[i]=obj_ReadSymbol( pObjfile );
+ }
+ else
+ fatalerror( "Out of memory!" );
+ }
+ else
+ tSymbols=(struct sSymbol **)&dummymem;
+
+ /* Next we have the sections */
+
+ pFirstSection=NULL;
+ while( nNumberOfSections-- )
+ {
+ struct sSection *pNewSection;
+
+ pNewSection=obj_ReadRGB1Section( pObjfile );
+ pNewSection->nNumberOfSymbols=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; i<nNumberOfSymbols; i+=1 )
+ {
+ struct sSection *pConvSect=pFirstSection;
+
+ if( tSymbols[i]->Type!=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
--- a/src/link/output.c
+++ b/src/link/output.c
@@ -1,222 +1,222 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#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; i<MAXBANKS; i+=1 )
- {
- struct sSection *pSect;
- MapfileInitBank( i );
- pSect=pSections;
- while( pSect )
- {
- if( pSect->nBank==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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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; i<MAXBANKS; i+=1 )
+ {
+ struct sSection *pSect;
+ MapfileInitBank( i );
+ pSect=pSections;
+ while( pSect )
+ {
+ if( pSect->nBank==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
--- a/src/link/patch.c
+++ b/src/link/patch.c
@@ -1,300 +1,300 @@
-#include <stdio.h>
-#include <string.h>
-
-#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_LOGGE:
- 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_SHR:
- 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( t<low || t>high )
- {
- 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 <stdio.h>
+#include <string.h>
+
+#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_LOGGE:
+ 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_SHR:
+ 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( t<low || t>high )
+ {
+ 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
--- a/src/link/symbol.c
+++ b/src/link/symbol.c
@@ -1,125 +1,125 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#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; i<HASHSIZE; i+=1 )
- tHash[i]=NULL;
-}
-
-SLONG sym_GetValue( char *tzName )
-{
- if( strcmp(tzName,"@")==0 )
- {
- return( nPC );
- }
- else
- {
- struct ISymbol **ppSym;
-
- ppSym=&(tHash[calchash(tzName)]);
- while( *ppSym )
- {
- if( strcmp(tzName,(*ppSym)->pzName) )
- {
- 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#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; i<HASHSIZE; i+=1 )
+ tHash[i]=NULL;
+}
+
+SLONG sym_GetValue( char *tzName )
+{
+ if( strcmp(tzName,"@")==0 )
+ {
+ return( nPC );
+ }
+ else
+ {
+ struct ISymbol **ppSym;
+
+ ppSym=&(tHash[calchash(tzName)]);
+ while( *ppSym )
+ {
+ if( strcmp(tzName,(*ppSym)->pzName) )
+ {
+ 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
--- a/src/rgbfix/main.c
+++ b/src/rgbfix/main.c
@@ -1,432 +1,432 @@
-/*
- * RGBFix : Perform various tasks on a Gameboy image-file
- *
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#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<name>\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<padto )
- {
- size+=1;
- if( (ulOptions&OPTF_DEBUG)==0 )
- fputc( 0, f );
- bytesadded+=1;
- }
- fflush( f );
-
- printf( "\tAdded %ld bytes\n", bytesadded );
- }
- else
- printf( "\tNo padding needed\n" );
- /*
- }
- else
- FatalError( "Image size exceeds 512kB" );
- */
- }
-
- /*
- * -r (Truncate) option code
- *
- */
-
- if( ulOptions&OPTF_TRUNCATE )
- {
- long size, padto;
- char tempfile[512];
- FILE *tf;
-
- size=FileSize( f );
- padto=256*32768;
- while( size<padto )
- padto/=2;
-
- printf( "Truncating to %ldkB:\n", padto/1024 );
-
- tmpnam( tempfile );
-
- if( (ulOptions&OPTF_DEBUG)==0 )
- {
- if( (tf=fopen(tempfile,"wb"))!=NULL )
- {
- fseek( f, 0, SEEK_SET );
- while( padto-- )
- {
- fputc( fgetc(f), tf );
- }
- fclose( f );
- fclose( tf );
- remove( filename );
- rename( tempfile, filename );
- f=fopen( filename, "rb+" );
- }
- }
- }
-
- /*
- * -t (Set carttitle) option code
- *
- */
-
- if( ulOptions&OPTF_TITLE )
- {
- printf( "Setting cartridge title:\n" );
- if( (ulOptions&OPTF_DEBUG)==0 )
- {
- fflush( f );
- fseek( f, 0x0134L, SEEK_SET );
- fwrite( cartname, 16, 1, f );
- fflush( f );
- }
- printf( "\tTitle set to %s\n", cartname );
- }
-
- /*
- * -v (Validate header) option code
- *
- */
-
- if( ulOptions&OPTF_VALIDATE )
- {
- long i, byteschanged=0;
- long cartromsize, calcromsize=0, filesize;
- long carttype;
- unsigned short cartchecksum=0, calcchecksum=0;
- unsigned char cartcompchecksum=0, calccompchecksum=0;
- int ch;
-
- printf( "Validating header:\n" );
- fflush( stdout );
-
- /* Nintendo Character Area */
-
- fflush( f );
- fseek( f, 0x0104L, SEEK_SET );
-
- for( i=0; i<48; i+=1 )
- {
- int ch;
-
- ch=fgetc( f );
- if( ch==EOF )
- ch=0x00;
- if( ch!=NintendoChar[i] )
- {
- byteschanged+=1;
-
- if( (ulOptions&OPTF_DEBUG)==0 )
- {
- fseek( f, -1, SEEK_CUR );
- fputc( NintendoChar[i], f );
- fflush( f );
- }
- }
- }
-
- fflush( f );
-
- if( byteschanged )
- printf( "\tChanged %ld bytes in the Nintendo Character Area\n", byteschanged );
- else
- printf( "\tNintendo Character Area is OK\n" );
-
- /* ROM size */
-
- fflush( f );
- fseek( f, 0x0148L, SEEK_SET );
- cartromsize=fgetc( f );
- if( cartromsize==EOF )
- cartromsize=0x00;
- filesize=FileSize( f );
- while( filesize>(0x8000L<<calcromsize) )
- calcromsize+=1;
-
- if( calcromsize!=cartromsize )
- {
- if( (ulOptions&OPTF_DEBUG)==0 )
- {
- fseek( f, -1, SEEK_CUR );
- fputc( calcromsize, f );
- fflush( f );
- }
- printf( "\tChanged ROM size byte from 0x%02lX (%ldkB) to 0x%02lX (%ldkB)\n",
- cartromsize, (0x8000L<<cartromsize)/1024,
- calcromsize, (0x8000L<<calcromsize)/1024 );
- }
- else
- printf( "\tROM size byte is OK\n" );
-
- /* Cartridge type */
-
- fflush( f );
- fseek( f, 0x0147L, SEEK_SET );
- carttype=fgetc( f );
- if( carttype==EOF )
- carttype=0x00;
-
- if( FileSize(f)>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<<calcromsize); i+=1 )
- {
- ch=fgetc( f );
- if( ch==EOF )
- ch=0;
-
- if( i<0x0134L )
- calcchecksum+=ch;
- else if( i<0x014DL )
- {
- calccompchecksum+=ch;
- calcchecksum+=ch;
- }
- else if( i==0x014DL )
- cartcompchecksum=ch;
- else if( i==0x014EL )
- cartchecksum=ch<<8;
- else if( i==0x014FL )
- cartchecksum|=ch;
- else
- calcchecksum+=ch;
- }
-
- calccompchecksum=0xE7-calccompchecksum;
- calcchecksum+=calccompchecksum;
-
- if( cartchecksum!=calcchecksum )
- {
- fflush( f );
- fseek( f, 0x014EL, SEEK_SET );
- if( (ulOptions&OPTF_DEBUG)==0 )
- {
- fputc( calcchecksum>>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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#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<name>\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<padto )
+ {
+ size+=1;
+ if( (ulOptions&OPTF_DEBUG)==0 )
+ fputc( 0, f );
+ bytesadded+=1;
+ }
+ fflush( f );
+
+ printf( "\tAdded %ld bytes\n", bytesadded );
+ }
+ else
+ printf( "\tNo padding needed\n" );
+ /*
+ }
+ else
+ FatalError( "Image size exceeds 512kB" );
+ */
+ }
+
+ /*
+ * -r (Truncate) option code
+ *
+ */
+
+ if( ulOptions&OPTF_TRUNCATE )
+ {
+ long size, padto;
+ char tempfile[512];
+ FILE *tf;
+
+ size=FileSize( f );
+ padto=256*32768;
+ while( size<padto )
+ padto/=2;
+
+ printf( "Truncating to %ldkB:\n", padto/1024 );
+
+ tmpnam( tempfile );
+
+ if( (ulOptions&OPTF_DEBUG)==0 )
+ {
+ if( (tf=fopen(tempfile,"wb"))!=NULL )
+ {
+ fseek( f, 0, SEEK_SET );
+ while( padto-- )
+ {
+ fputc( fgetc(f), tf );
+ }
+ fclose( f );
+ fclose( tf );
+ remove( filename );
+ rename( tempfile, filename );
+ f=fopen( filename, "rb+" );
+ }
+ }
+ }
+
+ /*
+ * -t (Set carttitle) option code
+ *
+ */
+
+ if( ulOptions&OPTF_TITLE )
+ {
+ printf( "Setting cartridge title:\n" );
+ if( (ulOptions&OPTF_DEBUG)==0 )
+ {
+ fflush( f );
+ fseek( f, 0x0134L, SEEK_SET );
+ fwrite( cartname, 16, 1, f );
+ fflush( f );
+ }
+ printf( "\tTitle set to %s\n", cartname );
+ }
+
+ /*
+ * -v (Validate header) option code
+ *
+ */
+
+ if( ulOptions&OPTF_VALIDATE )
+ {
+ long i, byteschanged=0;
+ long cartromsize, calcromsize=0, filesize;
+ long carttype;
+ unsigned short cartchecksum=0, calcchecksum=0;
+ unsigned char cartcompchecksum=0, calccompchecksum=0;
+ int ch;
+
+ printf( "Validating header:\n" );
+ fflush( stdout );
+
+ /* Nintendo Character Area */
+
+ fflush( f );
+ fseek( f, 0x0104L, SEEK_SET );
+
+ for( i=0; i<48; i+=1 )
+ {
+ int ch;
+
+ ch=fgetc( f );
+ if( ch==EOF )
+ ch=0x00;
+ if( ch!=NintendoChar[i] )
+ {
+ byteschanged+=1;
+
+ if( (ulOptions&OPTF_DEBUG)==0 )
+ {
+ fseek( f, -1, SEEK_CUR );
+ fputc( NintendoChar[i], f );
+ fflush( f );
+ }
+ }
+ }
+
+ fflush( f );
+
+ if( byteschanged )
+ printf( "\tChanged %ld bytes in the Nintendo Character Area\n", byteschanged );
+ else
+ printf( "\tNintendo Character Area is OK\n" );
+
+ /* ROM size */
+
+ fflush( f );
+ fseek( f, 0x0148L, SEEK_SET );
+ cartromsize=fgetc( f );
+ if( cartromsize==EOF )
+ cartromsize=0x00;
+ filesize=FileSize( f );
+ while( filesize>(0x8000L<<calcromsize) )
+ calcromsize+=1;
+
+ if( calcromsize!=cartromsize )
+ {
+ if( (ulOptions&OPTF_DEBUG)==0 )
+ {
+ fseek( f, -1, SEEK_CUR );
+ fputc( calcromsize, f );
+ fflush( f );
+ }
+ printf( "\tChanged ROM size byte from 0x%02lX (%ldkB) to 0x%02lX (%ldkB)\n",
+ cartromsize, (0x8000L<<cartromsize)/1024,
+ calcromsize, (0x8000L<<calcromsize)/1024 );
+ }
+ else
+ printf( "\tROM size byte is OK\n" );
+
+ /* Cartridge type */
+
+ fflush( f );
+ fseek( f, 0x0147L, SEEK_SET );
+ carttype=fgetc( f );
+ if( carttype==EOF )
+ carttype=0x00;
+
+ if( FileSize(f)>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<<calcromsize); i+=1 )
+ {
+ ch=fgetc( f );
+ if( ch==EOF )
+ ch=0;
+
+ if( i<0x0134L )
+ calcchecksum+=ch;
+ else if( i<0x014DL )
+ {
+ calccompchecksum+=ch;
+ calcchecksum+=ch;
+ }
+ else if( i==0x014DL )
+ cartcompchecksum=ch;
+ else if( i==0x014EL )
+ cartchecksum=ch<<8;
+ else if( i==0x014FL )
+ cartchecksum|=ch;
+ else
+ calcchecksum+=ch;
+ }
+
+ calccompchecksum=0xE7-calccompchecksum;
+ calcchecksum+=calccompchecksum;
+
+ if( cartchecksum!=calcchecksum )
+ {
+ fflush( f );
+ fseek( f, 0x014EL, SEEK_SET );
+ if( (ulOptions&OPTF_DEBUG)==0 )
+ {
+ fputc( calcchecksum>>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