mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-24 20:12:07 +00:00
Switch line terminators from CRLF to LF
Argh, that obnoxious platform again... ;-) Signed-off-by: Vegard Nossum <vegard.nossum@gmail.com>
This commit is contained in:
1138
src/link/assign.c
1138
src/link/assign.c
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
458
src/link/main.c
458
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 );
|
||||
}
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
1090
src/link/object.c
1090
src/link/object.c
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
598
src/link/patch.c
598
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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user