either a string or an expression.
+<sect1><tt>.BANK</tt><label id=".BANK"><p>
+
+ The <tt/.BANK/ function is used to support systems with banked memory. The
+ argument is an expression with exactly one segment reference - usually a
+ label. The function result is the value of the <tt/bank/ attribute assigned
+ to the run memory area of the segment. Please see the linker documentation
+ for more information about memory areas and their attributes.
+
+ The value of <tt/.BANK/ can be used to switch memory so that a memory bank
+ containing specific data is available.
+
+ The <tt/bank/ attribute is a 32 bit integer and so is the result of the
+ <tt/.BANK/ function. You will have to use <tt><ref id=".LOBYTE"
+ name=".LOBYTE"></tt> or similar functions to address just part of it.
+
+ Please note that <tt/.BANK/ will always get evaluated in the link stage, so
+ an expression containing <tt/.BANK/ can never be used where a constant known
+ result is expected (for example with <tt/.RES/).
+
+ Example:
+
+ <tscreen><verb>
+ .segment "BANK1"
+ .proc banked_func_1
+ ...
+ .endproc
+
+ .segment "BANK2"
+ .proc banked_func_2
+ ...
+ .endproc
+
+ .proc bank_table
+ .addr banked_func_1
+ .byte <.BANK (banked_func_1)
+
+ .addr banked_func_2
+ .byte <.BANK (banked_func_2)
+ .endproc
+ </verb></tscreen>
+
+
+
<sect1><tt>.BANKBYTE</tt><label id=".BANKBYTE"><p>
The function returns the bank byte (that is, bits 16-23) of its argument.
is a symbol that is already defined somewhere in the source file up to the
current position. Otherwise the function yields false. As an example, the
<tt><ref id=".IFDEF" name=".IFDEF"></tt> statement may be replaced by
-
+
<tscreen><verb>
.if .defined(a)
</verb></tscreen>
__STACK_FILEOFFS__ The binary offset in the output file. This
is not defined for relocatable output file
formats (o65).
-</verb></tscreen>
+</verb></tscreen>
A memory section may also have a type. Valid types are
value given on the command line with the <tt><ref id="option-S" name="-S"></tt>
option).
+To support systems with banked memory, a special attribute named <tt/bank/ is
+available. The attribute value is an arbitrary 32 bit integer. The assembler
+has a builtin function named <tt/.BANK/ which may be used with an argument
+that has a segment reference (for example a symbol). The result of this
+function is the value of the bank attribute for the run memory area of the
+segment.
+
<sect1>Other SEGMENT attributes<p>
/* Write the segment data */
ObjWriteVar (GetStringId (Seg->Def->Name)); /* Name of the segment */
+ ObjWriteVar (Seg->Flags); /* Segment flags */
ObjWriteVar (Seg->PC); /* Size */
ObjWriteVar (Seg->Align); /* Segment alignment */
ObjWrite8 (Seg->Def->AddrSize); /* Address size of the segment */
#include "bitops.h"
#include "check.h"
#include "print.h"
+#include "segdefs.h"
#include "xmalloc.h"
#include "xsprintf.h"
* must be placed into a memory area that has the bank
* attribute.
*/
- if (S->Seg->BankRef && M->BankExpr == 0) {
+ if ((S->Seg->Flags & SEG_FLAG_BANKREF) != 0 && M->BankExpr == 0) {
CfgError (GetSourcePos (S->LI),
"Segment `%s' is refered to by .BANK, but the "
"memory area `%s' it is placed into has no BANK "
static void FreeExprNode (ExprNode* E)
/* Free a node */
-{
+{
/* Free the memory */
xfree (E);
}
/* Read an expression from the given file */
{
ExprNode* Expr;
- Section* S;
/* Read the node tag and handle NULL nodes */
unsigned char Op = Read8 (F);
break;
case EXPR_SECTION:
- /* Read the section number */
- Expr->V.SecNum = ReadVar (F);
- break;
-
case EXPR_BANK:
/* Read the section number */
Expr->V.SecNum = ReadVar (F);
- /* Mark the section so we know it must be placed into a memory
- * area with the "bank" attribute.
- */
- S = GetExprSection (Expr);
- S->Seg->BankRef = 1;
break;
default:
#include "fragdefs.h"
#include "hashfunc.h"
#include "print.h"
+#include "segdefs.h"
#include "symdefs.h"
#include "xmalloc.h"
/* Initialize the fields */
S->Name = Name;
S->Next = 0;
+ S->Flags = SEG_FLAG_NONE;
S->Sections = EmptyCollection;
S->MemArea = 0;
S->PC = 0;
S->AddrSize = AddrSize;
S->ReadOnly = 0;
S->Dumped = 0;
- S->BankRef = 0;
/* Insert the segment into the segment list and assign the segment id */
S->Id = CollCount (&SegmentList);
/* Read a section from a file */
{
unsigned Name;
+ unsigned Flags;
unsigned Size;
unsigned long Alignment;
unsigned char Type;
Section* Sec;
/* Read the segment data */
- (void) Read32 (F); /* File size of data */
+ (void) Read32 (F); /* File size of data */
Name = MakeGlobalStringId (O, ReadVar (F)); /* Segment name */
- Size = ReadVar (F); /* Size of data */
- Alignment = ReadVar (F); /* Alignment */
- Type = Read8 (F); /* Segment type */
- FragCount = ReadVar (F); /* Number of fragments */
+ Flags = ReadVar (F); /* Segment flags */
+ Size = ReadVar (F); /* Size of data */
+ Alignment = ReadVar (F); /* Alignment */
+ Type = Read8 (F); /* Segment type */
+ FragCount = ReadVar (F); /* Number of fragments */
/* Print some data */
/* Get the segment for this section */
S = GetSegment (Name, Type, GetObjFileName (O));
+
+ /* The only possible flag is currently SEG_FLAG_BANKREF, and it must be
+ * applied to the segment, not the section.
+ */
+ S->Flags |= Flags;
/* Allocate the section we will return later */
Sec = NewSection (S, Alignment, Type);
unsigned Name; /* Name index of the segment */
unsigned Id; /* Segment id for debug info */
Segment* Next; /* Hash list */
+ unsigned Flags; /* Segment flags */
Collection Sections; /* Sections in this segment */
struct MemoryArea* MemArea; /* Run memory area once placed */
unsigned long PC; /* PC were this segment is located */
unsigned char AddrSize; /* Address size of segment */
unsigned char ReadOnly; /* True for readonly segments (config) */
unsigned char Dumped; /* Did we dump this segment? */
- unsigned char BankRef; /* We need the bank of this segment */
};
unsigned long NextSeg = ftell (F) + DataSize;
const char* Name = GetString (&StrPool, ReadVar (F));
unsigned Len = strlen (Name);
+ unsigned Flags = ReadVar (F);
unsigned long Size = ReadVar (F);
unsigned long Align = ReadVar (F);
unsigned char AddrSize = Read8 (F);
/* Print the data */
printf (" Name:%*s\"%s\"\n", (int)(24-Len), "", Name);
+ printf (" Flags:%25u\n", Flags);
printf (" Size:%26lu\n", Size);
printf (" Alignment:%21lu\n", Align);
printf (" Address size:%14s0x%02X (%s)\n", "", AddrSize,