Added/completed/debugged o65 support for Lunix
git-svn-id: svn://svn.cc65.org/cc65/trunk@1126 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
@@ -185,6 +185,10 @@ static void SetSys (const char* Sys)
|
|||||||
DefineNumericMacro ("__GEOS__", 1);
|
DefineNumericMacro ("__GEOS__", 1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TGT_LUNIX:
|
||||||
|
DefineNumericMacro ("__LUNIX__", 1);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
AbEnd ("Unknown target system type");
|
AbEnd ("Unknown target system type");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000 Ullrich von Bassewitz */
|
/* (C) 2000-2001 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Wacholderweg 14 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70597 Stuttgart */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@musoftware.de */
|
||||||
@@ -60,10 +60,11 @@ const char* TargetNames [TGT_COUNT] = {
|
|||||||
"plus4",
|
"plus4",
|
||||||
"cbm510",
|
"cbm510",
|
||||||
"cbm610",
|
"cbm610",
|
||||||
"pet",
|
"pet",
|
||||||
"bbc",
|
"bbc",
|
||||||
"apple2",
|
"apple2",
|
||||||
"geos",
|
"geos",
|
||||||
|
"lunix"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -101,4 +102,4 @@ target_t FindTarget (const char* Name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 2000 Ullrich von Bassewitz */
|
/* (C) 2000-2001 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Wacholderweg 14 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70597 Stuttgart */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@musoftware.de */
|
||||||
@@ -59,6 +59,7 @@ typedef enum {
|
|||||||
TGT_BBC,
|
TGT_BBC,
|
||||||
TGT_APPLE2,
|
TGT_APPLE2,
|
||||||
TGT_GEOS,
|
TGT_GEOS,
|
||||||
|
TGT_LUNIX,
|
||||||
TGT_COUNT /* Number of target systems */
|
TGT_COUNT /* Number of target systems */
|
||||||
} target_t;
|
} target_t;
|
||||||
|
|
||||||
|
|||||||
@@ -112,6 +112,7 @@ void TgtTranslateInit (void)
|
|||||||
case TGT_BBC: break;
|
case TGT_BBC: break;
|
||||||
case TGT_APPLE2: break;
|
case TGT_APPLE2: break;
|
||||||
case TGT_GEOS: break;
|
case TGT_GEOS: break;
|
||||||
|
case TGT_LUNIX: Tab = CTPET; break;
|
||||||
default:
|
default:
|
||||||
AbEnd ("Internal error: Target system unknown (%d)", Target);
|
AbEnd ("Internal error: Target system unknown (%d)", Target);
|
||||||
}
|
}
|
||||||
@@ -154,7 +155,7 @@ char* TgtTranslateStr (char* S)
|
|||||||
void TgtTranslateBuf (void* Buf, unsigned Len)
|
void TgtTranslateBuf (void* Buf, unsigned Len)
|
||||||
/* Translate a buffer of the given length from the source character set into
|
/* Translate a buffer of the given length from the source character set into
|
||||||
* the target system character set.
|
* the target system character set.
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
/* Translate */
|
/* Translate */
|
||||||
if (Tab) {
|
if (Tab) {
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
MEMORY {
|
MEMORY {
|
||||||
COMBINED: start = $0000, size = $FFFF, file = %O;
|
COMBINED: start = $0000, size = $FFFF, file = %O;
|
||||||
ZEROPAGE: start = $0000, size = $0100, file = %O;
|
|
||||||
}
|
}
|
||||||
SEGMENTS {
|
SEGMENTS {
|
||||||
|
ZEROPAGE: load = COMBINED, type = zp;
|
||||||
CODE: load = COMBINED, type = wprot;
|
CODE: load = COMBINED, type = wprot;
|
||||||
RODATA: load = COMBINED, type = wprot;
|
RODATA: load = COMBINED, type = wprot;
|
||||||
DATA: load = COMBINED, type = rw, define = yes;
|
DATA: load = COMBINED, type = rw, define = yes;
|
||||||
BSS: load = COMBINED, type = bss, define = yes;
|
BSS: load = COMBINED, type = bss, define = yes;
|
||||||
ZEROPAGE: load = ZEROPAGE, type = zp;
|
|
||||||
}
|
}
|
||||||
FEATURES {
|
FEATURES {
|
||||||
CONDES: segment = RODATA,
|
CONDES: segment = RODATA,
|
||||||
@@ -23,7 +22,7 @@ FILES {
|
|||||||
%O: format = o65;
|
%O: format = o65;
|
||||||
}
|
}
|
||||||
FORMATS {
|
FORMATS {
|
||||||
o65: os = lunix, type = small, extsym = "LUNIXKERNAL", extsym = "LIB6502";
|
o65: os = lunix, type = small, import = LUNIXKERNAL, import = LIB6502;
|
||||||
}
|
}
|
||||||
SYMBOLS {
|
SYMBOLS {
|
||||||
__STACKSIZE__ = $800; # 2K stack
|
__STACKSIZE__ = $800; # 2K stack
|
||||||
|
|||||||
@@ -866,7 +866,7 @@ static void ParseO65 (void)
|
|||||||
switch (CfgTok) {
|
switch (CfgTok) {
|
||||||
|
|
||||||
case CFGTOK_SMALL:
|
case CFGTOK_SMALL:
|
||||||
/* Default, nothing to do */
|
O65SetSmallModel (O65FmtDesc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CFGTOK_LARGE:
|
case CFGTOK_LARGE:
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1999 Ullrich von Bassewitz */
|
/* (C) 1999-2001 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Wacholderweg 14 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70597 Stuttgart */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@musoftware.de */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -35,9 +35,11 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "../common/hashstr.h"
|
/* common */
|
||||||
#include "../common/xmalloc.h"
|
#include "hashstr.h"
|
||||||
|
#include "xmalloc.h"
|
||||||
|
|
||||||
|
/* ld65 */
|
||||||
#include "error.h"
|
#include "error.h"
|
||||||
#include "extsyms.h"
|
#include "extsyms.h"
|
||||||
|
|
||||||
@@ -50,17 +52,17 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Structure holding an external symbol */
|
/* Structure holding an external symbol */
|
||||||
struct ExtSym_ {
|
struct ExtSym {
|
||||||
ExtSym* List; /* Next entry in list of all symbols */
|
ExtSym* List; /* Next entry in list of all symbols */
|
||||||
ExtSym* Next; /* Next entry in hash list */
|
ExtSym* Next; /* Next entry in hash list */
|
||||||
unsigned Flags; /* Generic flags */
|
unsigned Flags; /* Generic flags */
|
||||||
unsigned Num; /* Number of external symbol */
|
unsigned Num; /* Number of external symbol */
|
||||||
char Name [1]; /* Name - dynamically allocated */
|
char Name [1]; /* Name - dynamically allocated */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* External symbol table structure */
|
/* External symbol table structure */
|
||||||
#define HASHTAB_SIZE 53
|
#define HASHTAB_SIZE 53
|
||||||
struct ExtSymTab_ {
|
struct ExtSymTab {
|
||||||
ExtSym* Root; /* List of symbols */
|
ExtSym* Root; /* List of symbols */
|
||||||
ExtSym* Last; /* Pointer to last symbol */
|
ExtSym* Last; /* Pointer to last symbol */
|
||||||
unsigned Count; /* Number of symbols */
|
unsigned Count; /* Number of symbols */
|
||||||
@@ -109,7 +111,7 @@ ExtSym* NewExtSym (ExtSymTab* Tab, const char* Name)
|
|||||||
Tab->Last->List = E;
|
Tab->Last->List = E;
|
||||||
}
|
}
|
||||||
Tab->Last = E;
|
Tab->Last = E;
|
||||||
Tab->Count++;
|
++Tab->Count;
|
||||||
|
|
||||||
/* Insert the symbol into the hash table */
|
/* Insert the symbol into the hash table */
|
||||||
E->Next = Tab->HashTab [Hash];
|
E->Next = Tab->HashTab [Hash];
|
||||||
@@ -120,7 +122,7 @@ ExtSym* NewExtSym (ExtSymTab* Tab, const char* Name)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void FreeExtSym (ExtSym* E)
|
static void FreeExtSym (ExtSym* E)
|
||||||
/* Free an external symbol structure. Will not unlink the entry, so internal
|
/* Free an external symbol structure. Will not unlink the entry, so internal
|
||||||
* use only.
|
* use only.
|
||||||
@@ -230,7 +232,7 @@ const char* ExtSymName (const ExtSym* E)
|
|||||||
const ExtSym* ExtSymNext (const ExtSym* E)
|
const ExtSym* ExtSymNext (const ExtSym* E)
|
||||||
/* Return the next symbol in the list */
|
/* Return the next symbol in the list */
|
||||||
{
|
{
|
||||||
return E->Next;
|
return E->List;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -6,10 +6,10 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1999 Ullrich von Bassewitz */
|
/* (C) 1999-2001 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Wacholderweg 14 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70597 Stuttgart */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@musoftware.de */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* This software is provided 'as-is', without any expressed or implied */
|
/* This software is provided 'as-is', without any expressed or implied */
|
||||||
@@ -45,10 +45,10 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Forward decl for structure holding an external symbol */
|
/* Forward decl for structure holding an external symbol */
|
||||||
typedef struct ExtSym_ ExtSym;
|
typedef struct ExtSym ExtSym;
|
||||||
|
|
||||||
/* External symbol table structure */
|
/* External symbol table structure */
|
||||||
typedef struct ExtSymTab_ ExtSymTab;
|
typedef struct ExtSymTab ExtSymTab;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -97,3 +97,4 @@ const ExtSym* ExtSymNext (const ExtSym* E);
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ INCS = apple2.inc \
|
|||||||
cbm510.inc \
|
cbm510.inc \
|
||||||
cbm610.inc \
|
cbm610.inc \
|
||||||
geos.inc \
|
geos.inc \
|
||||||
|
lunix.inc \
|
||||||
none.inc \
|
none.inc \
|
||||||
pet.inc \
|
pet.inc \
|
||||||
plus4.inc
|
plus4.inc
|
||||||
@@ -125,6 +126,9 @@ cbm610.inc: cfg/cbm610.cfg
|
|||||||
geos.inc: cfg/geos.cfg
|
geos.inc: cfg/geos.cfg
|
||||||
@$(CVT) $< $@ CfgGeos
|
@$(CVT) $< $@ CfgGeos
|
||||||
|
|
||||||
|
lunix.inc: cfg/lunix.cfg
|
||||||
|
@$(CVT) $< $@ CfgLunix
|
||||||
|
|
||||||
none.inc: cfg/none.cfg
|
none.inc: cfg/none.cfg
|
||||||
@$(CVT) $< $@ CfgNone
|
@$(CVT) $< $@ CfgNone
|
||||||
|
|
||||||
|
|||||||
230
src/ld65/o65.c
230
src/ld65/o65.c
@@ -62,8 +62,19 @@
|
|||||||
|
|
||||||
|
|
||||||
/* Header mode bits */
|
/* Header mode bits */
|
||||||
|
#define MF_CPU_65816 0x8000 /* Executable is for 65816 */
|
||||||
|
#define MF_CPU_6502 0x0000 /* Executable is for the 6502 */
|
||||||
|
#define MF_CPU_MASK 0x8000 /* Mask to extract CPU type */
|
||||||
|
|
||||||
#define MF_SIZE_32BIT 0x2000 /* All size words are 32bit */
|
#define MF_SIZE_32BIT 0x2000 /* All size words are 32bit */
|
||||||
#define MF_CPU_816 0x8000 /* Executable is for 65816 */
|
#define MF_SIZE_16BIT 0x0000 /* All size words are 16bit */
|
||||||
|
#define MF_SIZE_MASK 0x2000 /* Mask to extract size */
|
||||||
|
|
||||||
|
#define MF_ALIGN_1 0x0000 /* Bytewise alignment */
|
||||||
|
#define MF_ALIGN_2 0x0001 /* Align words */
|
||||||
|
#define MF_ALIGN_4 0x0002 /* Align longwords */
|
||||||
|
#define MF_ALIGN_256 0x0003 /* Align pages (256 bytes) */
|
||||||
|
#define MF_ALIGN_MASK 0x0003 /* Mask to extract alignment */
|
||||||
|
|
||||||
/* The four o65 segment types. Note: These values are identical to the values
|
/* The four o65 segment types. Note: These values are identical to the values
|
||||||
* needed for the segmentID in the o65 spec.
|
* needed for the segmentID in the o65 spec.
|
||||||
@@ -81,6 +92,7 @@
|
|||||||
#define O65RELOC_LOW 0x20
|
#define O65RELOC_LOW 0x20
|
||||||
#define O65RELOC_SEGADR 0xc0
|
#define O65RELOC_SEGADR 0xc0
|
||||||
#define O65RELOC_SEG 0xa0
|
#define O65RELOC_SEG 0xa0
|
||||||
|
#define O65RELOC_MASK 0xc0
|
||||||
|
|
||||||
/* O65 executable file header */
|
/* O65 executable file header */
|
||||||
typedef struct O65Header O65Header;
|
typedef struct O65Header O65Header;
|
||||||
@@ -122,7 +134,7 @@ struct O65Desc {
|
|||||||
O65Option* Options; /* List of file options */
|
O65Option* Options; /* List of file options */
|
||||||
ExtSymTab* Exports; /* Table with exported symbols */
|
ExtSymTab* Exports; /* Table with exported symbols */
|
||||||
ExtSymTab* Imports; /* Table with imported symbols */
|
ExtSymTab* Imports; /* Table with imported symbols */
|
||||||
unsigned Undef; /* Count of undefined symbols */
|
unsigned Undef; /* Count of undefined symbols */
|
||||||
FILE* F; /* The file we're writing to */
|
FILE* F; /* The file we're writing to */
|
||||||
char* Filename; /* Name of the output file */
|
char* Filename; /* Name of the output file */
|
||||||
O65RelocTab* TextReloc; /* Relocation table for text segment */
|
O65RelocTab* TextReloc; /* Relocation table for text segment */
|
||||||
@@ -156,7 +168,7 @@ struct ExprDesc {
|
|||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Helper functions */
|
/* Helper functions */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
@@ -165,9 +177,9 @@ static void WriteSize (const O65Desc* D, unsigned long Val)
|
|||||||
/* Write a "size" word to the file */
|
/* Write a "size" word to the file */
|
||||||
{
|
{
|
||||||
if (D->Header.Mode & MF_SIZE_32BIT) {
|
if (D->Header.Mode & MF_SIZE_32BIT) {
|
||||||
Write32 (D->F, Val);
|
Write32 (D->F, Val);
|
||||||
} else {
|
} else {
|
||||||
Write16 (D->F, (unsigned) Val);
|
Write16 (D->F, (unsigned) Val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,20 +195,64 @@ static unsigned O65SegType (const SegDesc* S)
|
|||||||
* to check SF_ZP first.
|
* to check SF_ZP first.
|
||||||
*/
|
*/
|
||||||
if (S->Flags & SF_RO) {
|
if (S->Flags & SF_RO) {
|
||||||
return O65SEG_TEXT;
|
return O65SEG_TEXT;
|
||||||
} else if (S->Flags & SF_ZP) {
|
} else if (S->Flags & SF_ZP) {
|
||||||
return O65SEG_ZP;
|
return O65SEG_ZP;
|
||||||
} else if (S->Flags & SF_BSS) {
|
} else if (S->Flags & SF_BSS) {
|
||||||
return O65SEG_BSS;
|
return O65SEG_BSS;
|
||||||
} else {
|
} else {
|
||||||
return O65SEG_DATA;
|
return O65SEG_DATA;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const SegDesc* FindSeg (SegDesc** const List, unsigned Count, const Segment* S)
|
||||||
|
/* Search for a segment in the given list of segment descriptors and return
|
||||||
|
* the descriptor for a segment if we found it, and NULL if not.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
unsigned I;
|
||||||
|
|
||||||
|
for (I = 0; I < Count; ++I) {
|
||||||
|
if (List[I]->Seg == S) {
|
||||||
|
/* Found */
|
||||||
|
return List[I];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Not found */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static const SegDesc* O65FindSeg (const O65Desc* D, const Segment* S)
|
||||||
|
/* Search for a segment in the segment lists and return it's segment descriptor */
|
||||||
|
{
|
||||||
|
const SegDesc* SD;
|
||||||
|
|
||||||
|
if ((SD = FindSeg (D->TextSeg, D->TextCount, S)) != 0) {
|
||||||
|
return SD;
|
||||||
|
}
|
||||||
|
if ((SD = FindSeg (D->DataSeg, D->DataCount, S)) != 0) {
|
||||||
|
return SD;
|
||||||
|
}
|
||||||
|
if ((SD = FindSeg (D->BssSeg, D->BssCount, S)) != 0) {
|
||||||
|
return SD;
|
||||||
|
}
|
||||||
|
if ((SD = FindSeg (D->ZPSeg, D->ZPCount, S)) != 0) {
|
||||||
|
return SD;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Not found */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Expression handling */
|
/* Expression handling */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
|
||||||
@@ -251,7 +307,7 @@ static void O65ParseExpr (ExprNode* Expr, ExprDesc* D, int Sign)
|
|||||||
/* We cannot handle more than one segment reference in o65 */
|
/* We cannot handle more than one segment reference in o65 */
|
||||||
D->TooComplex = 1;
|
D->TooComplex = 1;
|
||||||
} else {
|
} else {
|
||||||
/* Remember the segment reference */
|
/* Remember the segment reference */
|
||||||
D->SegRef = GetExprSection (Expr);
|
D->SegRef = GetExprSection (Expr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -456,8 +512,8 @@ static unsigned O65WriteExpr (ExprNode* E, int Signed, unsigned Size,
|
|||||||
Offs += D->SegSize; /* Calulate full offset */
|
Offs += D->SegSize; /* Calulate full offset */
|
||||||
Diff = ((long) Offs) - D->LastOffs;
|
Diff = ((long) Offs) - D->LastOffs;
|
||||||
while (Diff > 0xFE) {
|
while (Diff > 0xFE) {
|
||||||
O65RelocPutByte (D->CurReloc, 0xFF);
|
O65RelocPutByte (D->CurReloc, 0xFF);
|
||||||
Diff -= 0xFE;
|
Diff -= 0xFE;
|
||||||
}
|
}
|
||||||
O65RelocPutByte (D->CurReloc, (unsigned char) Diff);
|
O65RelocPutByte (D->CurReloc, (unsigned char) Diff);
|
||||||
|
|
||||||
@@ -467,9 +523,9 @@ static unsigned O65WriteExpr (ExprNode* E, int Signed, unsigned Size,
|
|||||||
/* Determine the expression to relocate */
|
/* Determine the expression to relocate */
|
||||||
Expr = E;
|
Expr = E;
|
||||||
if (E->Op == EXPR_BYTE0 || E->Op == EXPR_BYTE1 ||
|
if (E->Op == EXPR_BYTE0 || E->Op == EXPR_BYTE1 ||
|
||||||
E->Op == EXPR_BYTE2 || E->Op == EXPR_BYTE3 ||
|
E->Op == EXPR_BYTE2 || E->Op == EXPR_BYTE3 ||
|
||||||
E->Op == EXPR_WORD0 || E->Op == EXPR_WORD1) {
|
E->Op == EXPR_WORD0 || E->Op == EXPR_WORD1) {
|
||||||
/* Use the real expression */
|
/* Use the real expression */
|
||||||
Expr = E->Left;
|
Expr = E->Left;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,12 +541,12 @@ static unsigned O65WriteExpr (ExprNode* E, int Signed, unsigned Size,
|
|||||||
|
|
||||||
/* We cannot handle both, an imported symbol and a segment ref */
|
/* We cannot handle both, an imported symbol and a segment ref */
|
||||||
if (ED.SegRef != 0 && ED.ExtRef != 0) {
|
if (ED.SegRef != 0 && ED.ExtRef != 0) {
|
||||||
ED.TooComplex = 1;
|
ED.TooComplex = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Bail out if we cannot handle the expression */
|
/* Bail out if we cannot handle the expression */
|
||||||
if (ED.TooComplex) {
|
if (ED.TooComplex) {
|
||||||
return SEG_EXPR_TOO_COMPLEX;
|
return SEG_EXPR_TOO_COMPLEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Safety: Check that we are really referencing a symbol or a segment */
|
/* Safety: Check that we are really referencing a symbol or a segment */
|
||||||
@@ -499,12 +555,12 @@ static unsigned O65WriteExpr (ExprNode* E, int Signed, unsigned Size,
|
|||||||
/* Write out the offset that goes into the segment. */
|
/* Write out the offset that goes into the segment. */
|
||||||
BinVal = ED.Val;
|
BinVal = ED.Val;
|
||||||
switch (E->Op) {
|
switch (E->Op) {
|
||||||
case EXPR_BYTE0: BinVal &= 0xFF; break;
|
case EXPR_BYTE0: BinVal &= 0xFF; break;
|
||||||
case EXPR_BYTE1: BinVal = (BinVal >> 8) & 0xFF; break;
|
case EXPR_BYTE1: BinVal = (BinVal >> 8) & 0xFF; break;
|
||||||
case EXPR_BYTE2: BinVal = (BinVal >> 16) & 0xFF; break;
|
case EXPR_BYTE2: BinVal = (BinVal >> 16) & 0xFF; break;
|
||||||
case EXPR_BYTE3: BinVal = (BinVal >> 24) & 0xFF; break;
|
case EXPR_BYTE3: BinVal = (BinVal >> 24) & 0xFF; break;
|
||||||
case EXPR_WORD0: BinVal &= 0xFFFF; break;
|
case EXPR_WORD0: BinVal &= 0xFFFF; break;
|
||||||
case EXPR_WORD1: BinVal = (BinVal >> 16) & 0xFFFF; break;
|
case EXPR_WORD1: BinVal = (BinVal >> 16) & 0xFFFF; break;
|
||||||
}
|
}
|
||||||
WriteVal (D->F, BinVal, Size);
|
WriteVal (D->F, BinVal, Size);
|
||||||
|
|
||||||
@@ -512,46 +568,66 @@ static unsigned O65WriteExpr (ExprNode* E, int Signed, unsigned Size,
|
|||||||
* information gathered about the expression.
|
* information gathered about the expression.
|
||||||
*/
|
*/
|
||||||
if (E->Op == EXPR_BYTE0) {
|
if (E->Op == EXPR_BYTE0) {
|
||||||
RelocType = O65RELOC_LOW;
|
RelocType = O65RELOC_LOW;
|
||||||
} else if (E->Op == EXPR_BYTE1) {
|
} else if (E->Op == EXPR_BYTE1) {
|
||||||
RelocType = O65RELOC_HIGH;
|
RelocType = O65RELOC_HIGH;
|
||||||
|
} else if (E->Op == EXPR_BYTE2) {
|
||||||
|
RelocType = O65RELOC_SEG;
|
||||||
} else {
|
} else {
|
||||||
switch (Size) {
|
switch (Size) {
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
RelocType = O65RELOC_LOW;
|
RelocType = O65RELOC_LOW;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 2:
|
case 2:
|
||||||
RelocType = O65RELOC_WORD;
|
RelocType = O65RELOC_WORD;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3:
|
case 3:
|
||||||
RelocType = O65RELOC_SEGADR;
|
RelocType = O65RELOC_SEGADR;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
/* 4 byte expression not supported by o65 */
|
/* 4 byte expression not supported by o65 */
|
||||||
return SEG_EXPR_TOO_COMPLEX;
|
return SEG_EXPR_TOO_COMPLEX;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
Internal ("O65WriteExpr: Invalid expression size: %u", Size);
|
Internal ("O65WriteExpr: Invalid expression size: %u", Size);
|
||||||
RelocType = 0; /* Avoid gcc warnings */
|
RelocType = 0; /* Avoid gcc warnings */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Determine which segment we're referencing */
|
/* Determine which segment we're referencing */
|
||||||
if (ED.ExtRef) {
|
if (ED.ExtRef) {
|
||||||
/* Imported symbol */
|
/* Imported symbol */
|
||||||
RelocType |= O65SEG_UNDEF;
|
RelocType |= O65SEG_UNDEF;
|
||||||
O65RelocPutByte (D->CurReloc, RelocType);
|
O65RelocPutByte (D->CurReloc, RelocType);
|
||||||
/* Put the number of the imported symbol into the table */
|
/* Put the number of the imported symbol into the table */
|
||||||
O65RelocPutWord (D->CurReloc, ExtSymNum (ED.ExtRef));
|
O65RelocPutWord (D->CurReloc, ExtSymNum (ED.ExtRef));
|
||||||
} else {
|
} else {
|
||||||
/* Segment reference */
|
/* Segment reference. Search for the segment and map it to it's
|
||||||
|
* o65 segmentID
|
||||||
|
*/
|
||||||
|
const SegDesc* Seg = O65FindSeg (D, ED.SegRef->Seg);
|
||||||
|
if (Seg == 0) {
|
||||||
|
/* For some reason, we didn't find this segment in the list of
|
||||||
|
* segments written to the o65 file.
|
||||||
|
*/
|
||||||
|
return SEG_EXPR_INVALID;
|
||||||
|
}
|
||||||
|
RelocType |= O65SegType (Seg);
|
||||||
|
O65RelocPutByte (D->CurReloc, RelocType);
|
||||||
|
|
||||||
|
/* Output additional data if needed */
|
||||||
|
switch (RelocType & O65RELOC_MASK) {
|
||||||
|
case O65RELOC_HIGH:
|
||||||
|
O65RelocPutByte (D->CurReloc, ED.Val & 0xFF);
|
||||||
|
break;
|
||||||
|
case O65RELOC_SEG:
|
||||||
|
O65RelocPutWord (D->CurReloc, ED.Val & 0xFFFF);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Success */
|
/* Success */
|
||||||
@@ -580,26 +656,26 @@ static void O65WriteSeg (O65Desc* D, SegDesc** Seg, unsigned Count, int DoWrite)
|
|||||||
Print (stdout, 1, " Writing `%s'\n", S->Name);
|
Print (stdout, 1, " Writing `%s'\n", S->Name);
|
||||||
|
|
||||||
/* Write this segment */
|
/* Write this segment */
|
||||||
if (DoWrite) {
|
if (DoWrite) {
|
||||||
RelocLineInfo (S->Seg);
|
RelocLineInfo (S->Seg);
|
||||||
SegWrite (D->F, S->Seg, O65WriteExpr, D);
|
SegWrite (D->F, S->Seg, O65WriteExpr, D);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mark the segment as dumped */
|
/* Mark the segment as dumped */
|
||||||
S->Seg->Dumped = 1;
|
S->Seg->Dumped = 1;
|
||||||
|
|
||||||
/* Calculate the total size */
|
/* Calculate the total size */
|
||||||
D->SegSize += S->Seg->Size;
|
D->SegSize += S->Seg->Size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Terminate the relocation table for the this segment */
|
/* Terminate the relocation table for this segment */
|
||||||
if (D->CurReloc) {
|
if (D->CurReloc) {
|
||||||
O65RelocPutByte (D->CurReloc, 0);
|
O65RelocPutByte (D->CurReloc, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check the size of the segment for overflow */
|
/* Check the size of the segment for overflow */
|
||||||
if ((D->Header.Mode & MF_SIZE_32BIT) == 0 && D->SegSize > 0xFFFF) {
|
if ((D->Header.Mode & MF_SIZE_MASK) == MF_SIZE_16BIT && D->SegSize > 0xFFFF) {
|
||||||
Error ("Segment overflow in file `%s'", D->Filename);
|
Error ("Segment overflow in file `%s'", D->Filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -711,7 +787,9 @@ static void O65WriteDataReloc (O65Desc* D)
|
|||||||
static void O65WriteExports (O65Desc* D)
|
static void O65WriteExports (O65Desc* D)
|
||||||
/* Write the list of exports */
|
/* Write the list of exports */
|
||||||
{
|
{
|
||||||
/* For now... */
|
/* Since ld65 creates exectutables, not object files, we do not have
|
||||||
|
* exports. This may change if we support writing shared libraries...
|
||||||
|
*/
|
||||||
WriteSize (D, 0);
|
WriteSize (D, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -796,10 +874,26 @@ void FreeO65Desc (O65Desc* D)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void O65Set816 (O65Desc* D)
|
void O65Set6502 (O65Desc* D)
|
||||||
|
/* Enable 6502 mode */
|
||||||
|
{
|
||||||
|
D->Header.Mode = (D->Header.Mode & ~MF_CPU_MASK) | MF_CPU_6502;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void O65Set65816 (O65Desc* D)
|
||||||
/* Enable 816 mode */
|
/* Enable 816 mode */
|
||||||
{
|
{
|
||||||
D->Header.Mode |= MF_CPU_816;
|
D->Header.Mode = (D->Header.Mode & ~MF_CPU_MASK) | MF_CPU_65816;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void O65SetSmallModel (O65Desc* D)
|
||||||
|
/* Enable a small memory model executable */
|
||||||
|
{
|
||||||
|
D->Header.Mode = (D->Header.Mode & ~MF_SIZE_MASK) | MF_SIZE_16BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -807,7 +901,7 @@ void O65Set816 (O65Desc* D)
|
|||||||
void O65SetLargeModel (O65Desc* D)
|
void O65SetLargeModel (O65Desc* D)
|
||||||
/* Enable a large memory model executable */
|
/* Enable a large memory model executable */
|
||||||
{
|
{
|
||||||
D->Header.Mode |= MF_SIZE_32BIT;
|
D->Header.Mode = (D->Header.Mode & ~MF_SIZE_MASK) | MF_SIZE_32BIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -816,14 +910,14 @@ void O65SetAlignment (O65Desc* D, unsigned Align)
|
|||||||
/* Set the executable alignment */
|
/* Set the executable alignment */
|
||||||
{
|
{
|
||||||
/* Remove all alignment bits from the mode word */
|
/* Remove all alignment bits from the mode word */
|
||||||
D->Header.Mode &= ~0x0003;
|
D->Header.Mode &= ~MF_ALIGN_MASK;
|
||||||
|
|
||||||
/* Set the alignment bits */
|
/* Set the alignment bits */
|
||||||
switch (Align) {
|
switch (Align) {
|
||||||
case 1: break;
|
case 1: D->Header.Mode |= MF_ALIGN_1; break;
|
||||||
case 2: D->Header.Mode |= 0x01; break;
|
case 2: D->Header.Mode |= MF_ALIGN_2; break;
|
||||||
case 4: D->Header.Mode |= 0x02; break;
|
case 4: D->Header.Mode |= MF_ALIGN_4; break;
|
||||||
case 256: D->Header.Mode |= 0x03; break;
|
case 256: D->Header.Mode |= MF_ALIGN_256; break;
|
||||||
default: Error ("Invalid alignment for O65 format: %u", Align);
|
default: Error ("Invalid alignment for O65 format: %u", Align);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -917,7 +1011,7 @@ static void O65SetupSegments (O65Desc* D, Memory* M)
|
|||||||
D->BssCount = 0;
|
D->BssCount = 0;
|
||||||
D->ZPCount = 0;
|
D->ZPCount = 0;
|
||||||
|
|
||||||
/* Walk through the memory list and count the segment types */
|
/* Walk through the segment list and count the segment types */
|
||||||
N = M->SegList;
|
N = M->SegList;
|
||||||
while (N) {
|
while (N) {
|
||||||
|
|
||||||
|
|||||||
@@ -79,9 +79,15 @@ O65Desc* NewO65Desc (void);
|
|||||||
void FreeO65Desc (O65Desc* D);
|
void FreeO65Desc (O65Desc* D);
|
||||||
/* Delete the descriptor struct with cleanup */
|
/* Delete the descriptor struct with cleanup */
|
||||||
|
|
||||||
void O65Set816 (O65Desc* D);
|
void O65Set6502 (O65Desc* D);
|
||||||
|
/* Enable 6502 mode */
|
||||||
|
|
||||||
|
void O65Set65816 (O65Desc* D);
|
||||||
/* Enable 816 mode */
|
/* Enable 816 mode */
|
||||||
|
|
||||||
|
void O65SetSmallModel (O65Desc* D);
|
||||||
|
/* Enable a small memory model executable */
|
||||||
|
|
||||||
void O65SetLargeModel (O65Desc* D);
|
void O65SetLargeModel (O65Desc* D);
|
||||||
/* Enable a large memory model executable */
|
/* Enable a large memory model executable */
|
||||||
|
|
||||||
|
|||||||
@@ -530,8 +530,14 @@ void SegWrite (FILE* Tgt, Segment* S, SegWriteFunc F, void* Data)
|
|||||||
|
|
||||||
case SEG_EXPR_TOO_COMPLEX:
|
case SEG_EXPR_TOO_COMPLEX:
|
||||||
Error ("Expression too complex in module `%s', line %lu",
|
Error ("Expression too complex in module `%s', line %lu",
|
||||||
GetSourceFileName (Frag->Obj, Frag->Pos.Name),
|
GetSourceFileName (Frag->Obj, Frag->Pos.Name),
|
||||||
Frag->Pos.Line);
|
Frag->Pos.Line);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SEG_EXPR_INVALID:
|
||||||
|
Error ("Invalid expression in module `%s', line %lu",
|
||||||
|
GetSourceFileName (Frag->Obj, Frag->Pos.Name),
|
||||||
|
Frag->Pos.Line);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -89,9 +89,10 @@ struct Section {
|
|||||||
/* Prototype for a function that is used to write expressions to the target
|
/* Prototype for a function that is used to write expressions to the target
|
||||||
* file (used in SegWrite). It returns one of the following values:
|
* file (used in SegWrite). It returns one of the following values:
|
||||||
*/
|
*/
|
||||||
#define SEG_EXPR_OK 0 /* Ok */
|
#define SEG_EXPR_OK 0U /* Ok */
|
||||||
#define SEG_EXPR_RANGE_ERROR 1 /* Range error */
|
#define SEG_EXPR_RANGE_ERROR 1U /* Range error */
|
||||||
#define SEG_EXPR_TOO_COMPLEX 2 /* Expression too complex */
|
#define SEG_EXPR_TOO_COMPLEX 2U /* Expression too complex */
|
||||||
|
#define SEG_EXPR_INVALID 3U /* Expression is invalid (e.g. unmapped segment) */
|
||||||
|
|
||||||
typedef unsigned (*SegWriteFunc) (ExprNode* E, /* The expression to write */
|
typedef unsigned (*SegWriteFunc) (ExprNode* E, /* The expression to write */
|
||||||
int Signed, /* Signed expression? */
|
int Signed, /* Signed expression? */
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* */
|
/* */
|
||||||
/* (C) 1998-2000 Ullrich von Bassewitz */
|
/* (C) 1998-2001 Ullrich von Bassewitz */
|
||||||
/* Wacholderweg 14 */
|
/* Wacholderweg 14 */
|
||||||
/* D-70597 Stuttgart */
|
/* D-70597 Stuttgart */
|
||||||
/* EMail: uz@musoftware.de */
|
/* EMail: uz@musoftware.de */
|
||||||
@@ -56,6 +56,7 @@ static const char CfgEmpty[] = "";
|
|||||||
#include "cbm510.inc"
|
#include "cbm510.inc"
|
||||||
#include "cbm610.inc"
|
#include "cbm610.inc"
|
||||||
#include "geos.inc"
|
#include "geos.inc"
|
||||||
|
#include "lunix.inc"
|
||||||
#include "none.inc"
|
#include "none.inc"
|
||||||
#include "pet.inc"
|
#include "pet.inc"
|
||||||
#include "plus4.inc"
|
#include "plus4.inc"
|
||||||
@@ -82,6 +83,7 @@ const TargetDesc Targets [TGT_COUNT] = {
|
|||||||
{ BINFMT_BINARY, CfgBBC },
|
{ BINFMT_BINARY, CfgBBC },
|
||||||
{ BINFMT_BINARY, CfgApple2 },
|
{ BINFMT_BINARY, CfgApple2 },
|
||||||
{ BINFMT_BINARY, CfgGeos },
|
{ BINFMT_BINARY, CfgGeos },
|
||||||
|
{ BINFMT_O65, CfgLunix },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user