mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-24 20:12:07 +00:00
Run `indent' on the whole tree
Can't indent the .y files yet, they need special treatment. Signed-off-by: Vegard Nossum <vegard.nossum@gmail.com>
This commit is contained in:
@@ -5,249 +5,216 @@
|
||||
#include "symbol.h"
|
||||
#include "assign.h"
|
||||
|
||||
struct sFreeArea
|
||||
{
|
||||
SLONG nOrg;
|
||||
SLONG nSize;
|
||||
struct sFreeArea *pPrev, *pNext;
|
||||
struct sFreeArea {
|
||||
SLONG nOrg;
|
||||
SLONG nSize;
|
||||
struct sFreeArea *pPrev, *pNext;
|
||||
};
|
||||
|
||||
struct sFreeArea *BankFree[MAXBANKS];
|
||||
SLONG MaxAvail[MAXBANKS];
|
||||
SLONG MaxBankUsed;
|
||||
struct sFreeArea *BankFree[MAXBANKS];
|
||||
SLONG MaxAvail[MAXBANKS];
|
||||
SLONG MaxBankUsed;
|
||||
|
||||
#define DOMAXBANK(x) {if( (x)>MaxBankUsed ) MaxBankUsed=(x);}
|
||||
|
||||
SLONG area_Avail( SLONG bank )
|
||||
SLONG area_Avail(SLONG bank)
|
||||
{
|
||||
SLONG r;
|
||||
struct sFreeArea *pArea;
|
||||
SLONG r;
|
||||
struct sFreeArea *pArea;
|
||||
|
||||
r=0;
|
||||
pArea=BankFree[bank];
|
||||
r = 0;
|
||||
pArea = BankFree[bank];
|
||||
|
||||
while( pArea )
|
||||
{
|
||||
r+=pArea->nSize;
|
||||
pArea=pArea->pNext;
|
||||
while (pArea) {
|
||||
r += pArea->nSize;
|
||||
pArea = pArea->pNext;
|
||||
}
|
||||
|
||||
return( r );
|
||||
return (r);
|
||||
}
|
||||
|
||||
SLONG area_AllocAbs( struct sFreeArea **ppArea, SLONG org, SLONG size )
|
||||
SLONG area_AllocAbs(struct sFreeArea ** ppArea, SLONG org, SLONG size)
|
||||
{
|
||||
struct sFreeArea *pArea;
|
||||
struct sFreeArea *pArea;
|
||||
|
||||
pArea=*ppArea;
|
||||
while( pArea )
|
||||
{
|
||||
if( org>=pArea->nOrg && (org+size-1)<=(pArea->nOrg+pArea->nSize-1) )
|
||||
{
|
||||
if( org==pArea->nOrg )
|
||||
{
|
||||
pArea->nOrg+=size;
|
||||
pArea->nSize-=size;
|
||||
return( org );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( (org+size-1)==(pArea->nOrg+pArea->nSize-1) )
|
||||
{
|
||||
pArea->nSize-=size;
|
||||
return( org );
|
||||
}
|
||||
else
|
||||
{
|
||||
struct sFreeArea *pNewArea;
|
||||
pArea = *ppArea;
|
||||
while (pArea) {
|
||||
if (org >= pArea->nOrg
|
||||
&& (org + size - 1) <= (pArea->nOrg + pArea->nSize - 1)) {
|
||||
if (org == pArea->nOrg) {
|
||||
pArea->nOrg += size;
|
||||
pArea->nSize -= size;
|
||||
return (org);
|
||||
} else {
|
||||
if ((org + size - 1) ==
|
||||
(pArea->nOrg + pArea->nSize - 1)) {
|
||||
pArea->nSize -= size;
|
||||
return (org);
|
||||
} else {
|
||||
struct sFreeArea *pNewArea;
|
||||
|
||||
if( (pNewArea=(struct sFreeArea *)malloc(sizeof(struct sFreeArea)))!=NULL )
|
||||
{
|
||||
*pNewArea=*pArea;
|
||||
pNewArea->pPrev=pArea;
|
||||
pArea->pNext=pNewArea;
|
||||
pArea->nSize=org-pArea->nOrg;
|
||||
pNewArea->nOrg=org+size;
|
||||
pNewArea->nSize-=size+pArea->nSize;
|
||||
if ((pNewArea =
|
||||
(struct sFreeArea *)
|
||||
malloc(sizeof(struct sFreeArea)))
|
||||
!= NULL) {
|
||||
*pNewArea = *pArea;
|
||||
pNewArea->pPrev = pArea;
|
||||
pArea->pNext = pNewArea;
|
||||
pArea->nSize =
|
||||
org - pArea->nOrg;
|
||||
pNewArea->nOrg = org + size;
|
||||
pNewArea->nSize -=
|
||||
size + pArea->nSize;
|
||||
|
||||
return( org );
|
||||
}
|
||||
else
|
||||
fatalerror( "Out of memory!" );
|
||||
return (org);
|
||||
} else
|
||||
fatalerror("Out of memory!");
|
||||
}
|
||||
}
|
||||
}
|
||||
ppArea=&(pArea->pNext);
|
||||
pArea=*ppArea;
|
||||
ppArea = &(pArea->pNext);
|
||||
pArea = *ppArea;
|
||||
}
|
||||
|
||||
return( -1 );
|
||||
return (-1);
|
||||
}
|
||||
|
||||
SLONG area_AllocAbsCODEAnyBank( SLONG org, SLONG size )
|
||||
SLONG area_AllocAbsCODEAnyBank(SLONG org, SLONG size)
|
||||
{
|
||||
SLONG i;
|
||||
SLONG i;
|
||||
|
||||
for( i=1; i<=255; i+=1 )
|
||||
{
|
||||
if( area_AllocAbs( &BankFree[i], org, size )==org )
|
||||
return( i );
|
||||
for (i = 1; i <= 255; i += 1) {
|
||||
if (area_AllocAbs(&BankFree[i], org, size) == org)
|
||||
return (i);
|
||||
}
|
||||
|
||||
return( -1 );
|
||||
return (-1);
|
||||
}
|
||||
|
||||
SLONG area_Alloc( struct sFreeArea **ppArea, SLONG size )
|
||||
SLONG area_Alloc(struct sFreeArea ** ppArea, SLONG size)
|
||||
{
|
||||
struct sFreeArea *pArea;
|
||||
struct sFreeArea *pArea;
|
||||
|
||||
pArea=*ppArea;
|
||||
while( pArea )
|
||||
{
|
||||
if( size<=pArea->nSize )
|
||||
{
|
||||
SLONG r;
|
||||
pArea = *ppArea;
|
||||
while (pArea) {
|
||||
if (size <= pArea->nSize) {
|
||||
SLONG r;
|
||||
|
||||
r=pArea->nOrg;
|
||||
pArea->nOrg+=size;
|
||||
pArea->nSize-=size;
|
||||
r = pArea->nOrg;
|
||||
pArea->nOrg += size;
|
||||
pArea->nSize -= size;
|
||||
|
||||
return( r );
|
||||
return (r);
|
||||
}
|
||||
ppArea=&(pArea->pNext);
|
||||
pArea=*ppArea;
|
||||
ppArea = &(pArea->pNext);
|
||||
pArea = *ppArea;
|
||||
}
|
||||
|
||||
return( -1 );
|
||||
return (-1);
|
||||
}
|
||||
|
||||
SLONG area_AllocCODEAnyBank( SLONG size )
|
||||
SLONG area_AllocCODEAnyBank(SLONG size)
|
||||
{
|
||||
SLONG i, org;
|
||||
SLONG i, org;
|
||||
|
||||
for( i=1; i<=255; i+=1 )
|
||||
{
|
||||
if( (org=area_Alloc(&BankFree[i],size))!=-1 )
|
||||
return( (i<<16)|org );
|
||||
for (i = 1; i <= 255; i += 1) {
|
||||
if ((org = area_Alloc(&BankFree[i], size)) != -1)
|
||||
return ((i << 16) | org);
|
||||
}
|
||||
|
||||
return( -1 );
|
||||
return (-1);
|
||||
}
|
||||
|
||||
struct sSection *FindLargestCode( void )
|
||||
struct sSection *FindLargestCode(void)
|
||||
{
|
||||
struct sSection *pSection, *r=NULL;
|
||||
SLONG nLargest=0;
|
||||
struct sSection *pSection, *r = NULL;
|
||||
SLONG nLargest = 0;
|
||||
|
||||
pSection=pSections;
|
||||
while( pSection )
|
||||
{
|
||||
if( pSection->oAssigned==0 && pSection->Type==SECT_CODE )
|
||||
{
|
||||
if( pSection->nByteSize > nLargest )
|
||||
{
|
||||
nLargest=pSection->nByteSize;
|
||||
r=pSection;
|
||||
pSection = pSections;
|
||||
while (pSection) {
|
||||
if (pSection->oAssigned == 0 && pSection->Type == SECT_CODE) {
|
||||
if (pSection->nByteSize > nLargest) {
|
||||
nLargest = pSection->nByteSize;
|
||||
r = pSection;
|
||||
}
|
||||
}
|
||||
pSection=pSection->pNext;
|
||||
pSection = pSection->pNext;
|
||||
}
|
||||
return( r );
|
||||
return (r);
|
||||
}
|
||||
|
||||
|
||||
void AssignCodeSections( void )
|
||||
void AssignCodeSections(void)
|
||||
{
|
||||
struct sSection *pSection;
|
||||
|
||||
while( pSection=FindLargestCode() )
|
||||
{
|
||||
SLONG org;
|
||||
while (pSection = FindLargestCode()) {
|
||||
SLONG org;
|
||||
|
||||
if( (org=area_AllocCODEAnyBank( pSection->nByteSize ))!=-1 )
|
||||
{
|
||||
pSection->nOrg=org&0xFFFF;
|
||||
pSection->nBank=org>>16;
|
||||
pSection->oAssigned=1;
|
||||
if ((org = area_AllocCODEAnyBank(pSection->nByteSize)) != -1) {
|
||||
pSection->nOrg = org & 0xFFFF;
|
||||
pSection->nBank = org >> 16;
|
||||
pSection->oAssigned = 1;
|
||||
DOMAXBANK(pSection->nBank);
|
||||
}
|
||||
else
|
||||
fatalerror( "Unable to place CODE section anywhere" );
|
||||
} else
|
||||
fatalerror("Unable to place CODE section anywhere");
|
||||
}
|
||||
}
|
||||
|
||||
void GBROM_AssignSections( void )
|
||||
void GBROM_AssignSections(void)
|
||||
{
|
||||
SLONG i;
|
||||
SLONG i;
|
||||
struct sSection *pSection;
|
||||
|
||||
MaxBankUsed=0;
|
||||
MaxBankUsed = 0;
|
||||
|
||||
/*
|
||||
* Initialize the memory areas
|
||||
*
|
||||
*/
|
||||
|
||||
for( i=0; i<MAXBANKS; i+=1 )
|
||||
{
|
||||
if( BankFree[i]=(struct sFreeArea *)malloc(sizeof(struct sFreeArea)) )
|
||||
{
|
||||
if( i==0 )
|
||||
{
|
||||
BankFree[i]->nOrg=0x0000;
|
||||
if( options&OPT_SMALL )
|
||||
{
|
||||
BankFree[i]->nSize=0x8000;
|
||||
MaxAvail[i]=0x8000;
|
||||
for (i = 0; i < MAXBANKS; i += 1) {
|
||||
if (BankFree[i] =
|
||||
(struct sFreeArea *)malloc(sizeof(struct sFreeArea))) {
|
||||
if (i == 0) {
|
||||
BankFree[i]->nOrg = 0x0000;
|
||||
if (options & OPT_SMALL) {
|
||||
BankFree[i]->nSize = 0x8000;
|
||||
MaxAvail[i] = 0x8000;
|
||||
} else {
|
||||
BankFree[i]->nSize = 0x4000;
|
||||
MaxAvail[i] = 0x4000;
|
||||
}
|
||||
else
|
||||
{
|
||||
BankFree[i]->nSize=0x4000;
|
||||
MaxAvail[i]=0x4000;
|
||||
}
|
||||
}
|
||||
else if( i>=1 && i<=255 )
|
||||
{
|
||||
BankFree[i]->nOrg=0x4000;
|
||||
} else if (i >= 1 && i <= 255) {
|
||||
BankFree[i]->nOrg = 0x4000;
|
||||
/*
|
||||
* Now, this shouldn't really be necessary... but for good
|
||||
* measure we'll do it anyway
|
||||
*
|
||||
*/
|
||||
if( options&OPT_SMALL )
|
||||
{
|
||||
BankFree[i]->nSize=0;
|
||||
MaxAvail[i]=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
BankFree[i]->nSize=0x4000;
|
||||
MaxAvail[i]=0x4000;
|
||||
* Now, this shouldn't really be necessary... but for good
|
||||
* measure we'll do it anyway
|
||||
*
|
||||
*/
|
||||
if (options & OPT_SMALL) {
|
||||
BankFree[i]->nSize = 0;
|
||||
MaxAvail[i] = 0;
|
||||
} else {
|
||||
BankFree[i]->nSize = 0x4000;
|
||||
MaxAvail[i] = 0x4000;
|
||||
}
|
||||
} else if (i == BANK_BSS) {
|
||||
BankFree[i]->nOrg = 0xC000;
|
||||
BankFree[i]->nSize = 0x2000;
|
||||
MaxAvail[i] = 0x2000;
|
||||
} else if (i == BANK_VRAM) {
|
||||
BankFree[i]->nOrg = 0x8000;
|
||||
BankFree[i]->nSize = 0x2000;
|
||||
MaxAvail[i] = 0x2000;
|
||||
} else if (i == BANK_HRAM) {
|
||||
BankFree[i]->nOrg = 0xFF80;
|
||||
BankFree[i]->nSize = 0x007F;
|
||||
MaxAvail[i] = 0x007F;
|
||||
}
|
||||
else if( i==BANK_BSS )
|
||||
{
|
||||
BankFree[i]->nOrg =0xC000;
|
||||
BankFree[i]->nSize=0x2000;
|
||||
MaxAvail[i]=0x2000;
|
||||
}
|
||||
else if( i==BANK_VRAM )
|
||||
{
|
||||
BankFree[i]->nOrg =0x8000;
|
||||
BankFree[i]->nSize=0x2000;
|
||||
MaxAvail[i]=0x2000;
|
||||
}
|
||||
else if( i==BANK_HRAM )
|
||||
{
|
||||
BankFree[i]->nOrg =0xFF80;
|
||||
BankFree[i]->nSize=0x007F;
|
||||
MaxAvail[i]=0x007F;
|
||||
}
|
||||
BankFree[i]->pPrev=NULL;
|
||||
BankFree[i]->pNext=NULL;
|
||||
}
|
||||
else
|
||||
fatalerror( "Out of memory!" );
|
||||
BankFree[i]->pPrev = NULL;
|
||||
BankFree[i]->pNext = NULL;
|
||||
} else
|
||||
fatalerror("Out of memory!");
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -256,110 +223,129 @@ void GBROM_AssignSections( void )
|
||||
*
|
||||
*/
|
||||
|
||||
pSection=pSections;
|
||||
while( pSection )
|
||||
{
|
||||
if( (pSection->nOrg!=-1 || pSection->nBank!=-1) && pSection->oAssigned==0 )
|
||||
{
|
||||
pSection = pSections;
|
||||
while (pSection) {
|
||||
if ((pSection->nOrg != -1 || pSection->nBank != -1)
|
||||
&& pSection->oAssigned == 0) {
|
||||
/* User wants to have a say... */
|
||||
|
||||
switch( pSection->Type )
|
||||
{
|
||||
case SECT_BSS:
|
||||
if( area_AllocAbs(&BankFree[BANK_BSS],pSection->nOrg,pSection->nByteSize)!=pSection->nOrg )
|
||||
{
|
||||
sprintf( temptext, "Unable to load fixed BSS section at $%X", pSection->nOrg );
|
||||
fatalerror( temptext );
|
||||
}
|
||||
pSection->oAssigned=1;
|
||||
pSection->nBank=BANK_BSS;
|
||||
break;
|
||||
case SECT_HRAM:
|
||||
if( area_AllocAbs(&BankFree[BANK_HRAM],pSection->nOrg,pSection->nByteSize)!=pSection->nOrg )
|
||||
{
|
||||
sprintf( temptext, "Unable to load fixed HRAM section at $%X", pSection->nOrg );
|
||||
fatalerror( temptext );
|
||||
}
|
||||
pSection->oAssigned=1;
|
||||
pSection->nBank=BANK_HRAM;
|
||||
break;
|
||||
case SECT_VRAM:
|
||||
if( area_AllocAbs(&BankFree[BANK_VRAM],pSection->nOrg,pSection->nByteSize)!=pSection->nOrg )
|
||||
{
|
||||
sprintf( temptext, "Unable to load fixed VRAM section at $%X", pSection->nOrg );
|
||||
fatalerror( temptext );
|
||||
}
|
||||
pSection->oAssigned=1;
|
||||
pSection->nBank=BANK_VRAM;
|
||||
break;
|
||||
case SECT_HOME:
|
||||
if( area_AllocAbs(&BankFree[BANK_HOME],pSection->nOrg,pSection->nByteSize)!=pSection->nOrg )
|
||||
{
|
||||
sprintf( temptext, "Unable to load fixed HOME section at $%X", pSection->nOrg );
|
||||
fatalerror( temptext );
|
||||
}
|
||||
pSection->oAssigned=1;
|
||||
pSection->nBank=BANK_HOME;
|
||||
break;
|
||||
case SECT_CODE:
|
||||
if( pSection->nBank==-1 )
|
||||
{
|
||||
switch (pSection->Type) {
|
||||
case SECT_BSS:
|
||||
if (area_AllocAbs
|
||||
(&BankFree[BANK_BSS], pSection->nOrg,
|
||||
pSection->nByteSize) != pSection->nOrg) {
|
||||
sprintf(temptext,
|
||||
"Unable to load fixed BSS section at $%X",
|
||||
pSection->nOrg);
|
||||
fatalerror(temptext);
|
||||
}
|
||||
pSection->oAssigned = 1;
|
||||
pSection->nBank = BANK_BSS;
|
||||
break;
|
||||
case SECT_HRAM:
|
||||
if (area_AllocAbs
|
||||
(&BankFree[BANK_HRAM], pSection->nOrg,
|
||||
pSection->nByteSize) != pSection->nOrg) {
|
||||
sprintf(temptext,
|
||||
"Unable to load fixed HRAM section at $%X",
|
||||
pSection->nOrg);
|
||||
fatalerror(temptext);
|
||||
}
|
||||
pSection->oAssigned = 1;
|
||||
pSection->nBank = BANK_HRAM;
|
||||
break;
|
||||
case SECT_VRAM:
|
||||
if (area_AllocAbs
|
||||
(&BankFree[BANK_VRAM], pSection->nOrg,
|
||||
pSection->nByteSize) != pSection->nOrg) {
|
||||
sprintf(temptext,
|
||||
"Unable to load fixed VRAM section at $%X",
|
||||
pSection->nOrg);
|
||||
fatalerror(temptext);
|
||||
}
|
||||
pSection->oAssigned = 1;
|
||||
pSection->nBank = BANK_VRAM;
|
||||
break;
|
||||
case SECT_HOME:
|
||||
if (area_AllocAbs
|
||||
(&BankFree[BANK_HOME], pSection->nOrg,
|
||||
pSection->nByteSize) != pSection->nOrg) {
|
||||
sprintf(temptext,
|
||||
"Unable to load fixed HOME section at $%X",
|
||||
pSection->nOrg);
|
||||
fatalerror(temptext);
|
||||
}
|
||||
pSection->oAssigned = 1;
|
||||
pSection->nBank = BANK_HOME;
|
||||
break;
|
||||
case SECT_CODE:
|
||||
if (pSection->nBank == -1) {
|
||||
/*
|
||||
* User doesn't care which bank, so he must want to
|
||||
* decide which position within that bank.
|
||||
* We'll do that at a later stage when the really
|
||||
* hardcoded things are allocated
|
||||
*
|
||||
*/
|
||||
} else {
|
||||
/*
|
||||
* User wants to decide which bank we use
|
||||
* Does he care about the position as well?
|
||||
*
|
||||
*/
|
||||
|
||||
if (pSection->nOrg == -1) {
|
||||
/*
|
||||
* User doesn't care which bank, so he must want to
|
||||
* decide which position within that bank.
|
||||
* We'll do that at a later stage when the really
|
||||
* hardcoded things are allocated
|
||||
* Nope, any position will do
|
||||
* Again, we'll do that later
|
||||
*
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
/*
|
||||
* User wants to decide which bank we use
|
||||
* Does he care about the position as well?
|
||||
* How hardcore can you possibly get? Why does
|
||||
* he even USE this package? Yeah let's just
|
||||
* direct address everything, shall we?
|
||||
* Oh well, the customer is always right
|
||||
*
|
||||
*/
|
||||
|
||||
if( pSection->nOrg==-1 )
|
||||
{
|
||||
/*
|
||||
* Nope, any position will do
|
||||
* Again, we'll do that later
|
||||
*
|
||||
*/
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* How hardcore can you possibly get? Why does
|
||||
* he even USE this package? Yeah let's just
|
||||
* direct address everything, shall we?
|
||||
* Oh well, the customer is always right
|
||||
*
|
||||
*/
|
||||
|
||||
if( pSection->nBank>=1 && pSection->nBank<=255 )
|
||||
{
|
||||
if( area_AllocAbs(&BankFree[pSection->nBank],pSection->nOrg,pSection->nByteSize)!=pSection->nOrg )
|
||||
{
|
||||
sprintf( temptext, "Unable to load fixed CODE/DATA section at $%X in bank $%02X", pSection->nOrg, pSection->nBank );
|
||||
fatalerror( temptext );
|
||||
}
|
||||
DOMAXBANK(pSection->nBank);
|
||||
pSection->oAssigned=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( temptext, "Unable to load fixed CODE/DATA section at $%X in bank $%02X", pSection->nOrg, pSection->nBank );
|
||||
fatalerror( temptext );
|
||||
if (pSection->nBank >= 1
|
||||
&& pSection->nBank <= 255) {
|
||||
if (area_AllocAbs
|
||||
(&BankFree
|
||||
[pSection->nBank],
|
||||
pSection->nOrg,
|
||||
pSection->
|
||||
nByteSize) !=
|
||||
pSection->nOrg) {
|
||||
sprintf
|
||||
(temptext,
|
||||
"Unable to load fixed CODE/DATA section at $%X in bank $%02X",
|
||||
pSection->
|
||||
nOrg,
|
||||
pSection->
|
||||
nBank);
|
||||
fatalerror
|
||||
(temptext);
|
||||
}
|
||||
DOMAXBANK(pSection->
|
||||
nBank);
|
||||
pSection->oAssigned = 1;
|
||||
} else {
|
||||
sprintf(temptext,
|
||||
"Unable to load fixed CODE/DATA section at $%X in bank $%02X",
|
||||
pSection->nOrg,
|
||||
pSection->
|
||||
nBank);
|
||||
fatalerror(temptext);
|
||||
}
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
pSection=pSection->pNext;
|
||||
pSection = pSection->pNext;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -367,32 +353,31 @@ void GBROM_AssignSections( void )
|
||||
*
|
||||
*/
|
||||
|
||||
pSection=pSections;
|
||||
while( pSection )
|
||||
{
|
||||
if( pSection->oAssigned==0
|
||||
&& pSection->Type==SECT_CODE
|
||||
&& pSection->nOrg==-1
|
||||
&& pSection->nBank!=-1 )
|
||||
{
|
||||
pSection = pSections;
|
||||
while (pSection) {
|
||||
if (pSection->oAssigned == 0
|
||||
&& pSection->Type == SECT_CODE
|
||||
&& pSection->nOrg == -1 && pSection->nBank != -1) {
|
||||
/* User wants to have a say... and he's pissed */
|
||||
if( pSection->nBank>=1 && pSection->nBank<=255 )
|
||||
{
|
||||
if( (pSection->nOrg=area_Alloc(&BankFree[pSection->nBank],pSection->nByteSize))==-1 )
|
||||
{
|
||||
sprintf( temptext, "Unable to load fixed CODE/DATA section into bank $%02X", pSection->nBank );
|
||||
fatalerror( temptext );
|
||||
if (pSection->nBank >= 1 && pSection->nBank <= 255) {
|
||||
if ((pSection->nOrg =
|
||||
area_Alloc(&BankFree[pSection->nBank],
|
||||
pSection->nByteSize)) == -1) {
|
||||
sprintf(temptext,
|
||||
"Unable to load fixed CODE/DATA section into bank $%02X",
|
||||
pSection->nBank);
|
||||
fatalerror(temptext);
|
||||
}
|
||||
pSection->oAssigned=1;
|
||||
pSection->oAssigned = 1;
|
||||
DOMAXBANK(pSection->nBank);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( temptext, "Unable to load fixed CODE/DATA section into bank $%02X", pSection->nBank );
|
||||
fatalerror( temptext );
|
||||
} else {
|
||||
sprintf(temptext,
|
||||
"Unable to load fixed CODE/DATA section into bank $%02X",
|
||||
pSection->nBank);
|
||||
fatalerror(temptext);
|
||||
}
|
||||
}
|
||||
pSection=pSection->pNext;
|
||||
pSection = pSection->pNext;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -400,24 +385,25 @@ void GBROM_AssignSections( void )
|
||||
*
|
||||
*/
|
||||
|
||||
pSection=pSections;
|
||||
while( pSection )
|
||||
{
|
||||
if( pSection->oAssigned==0
|
||||
&& pSection->Type==SECT_CODE
|
||||
&& pSection->nOrg!=-1
|
||||
&& pSection->nBank==-1 )
|
||||
{
|
||||
pSection = pSections;
|
||||
while (pSection) {
|
||||
if (pSection->oAssigned == 0
|
||||
&& pSection->Type == SECT_CODE
|
||||
&& pSection->nOrg != -1 && pSection->nBank == -1) {
|
||||
/* User wants to have a say... and he's back with a vengeance */
|
||||
if( (pSection->nBank=area_AllocAbsCODEAnyBank(pSection->nOrg,pSection->nByteSize))==-1 )
|
||||
{
|
||||
sprintf( temptext, "Unable to load fixed CODE/DATA section at $%X into any bank", pSection->nOrg );
|
||||
fatalerror( temptext );
|
||||
if ((pSection->nBank =
|
||||
area_AllocAbsCODEAnyBank(pSection->nOrg,
|
||||
pSection->nByteSize)) ==
|
||||
-1) {
|
||||
sprintf(temptext,
|
||||
"Unable to load fixed CODE/DATA section at $%X into any bank",
|
||||
pSection->nOrg);
|
||||
fatalerror(temptext);
|
||||
}
|
||||
pSection->oAssigned=1;
|
||||
pSection->oAssigned = 1;
|
||||
DOMAXBANK(pSection->nBank);
|
||||
}
|
||||
pSection=pSection->pNext;
|
||||
pSection = pSection->pNext;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -426,145 +412,141 @@ void GBROM_AssignSections( void )
|
||||
*
|
||||
*/
|
||||
|
||||
pSection=pSections;
|
||||
while( pSection )
|
||||
{
|
||||
if( pSection->oAssigned==0 )
|
||||
{
|
||||
switch( pSection->Type )
|
||||
{
|
||||
case SECT_BSS:
|
||||
if( (pSection->nOrg=area_Alloc(&BankFree[BANK_BSS],pSection->nByteSize))==-1 )
|
||||
{
|
||||
fatalerror( "BSS section too large\n" );
|
||||
}
|
||||
pSection->nBank=BANK_BSS;
|
||||
pSection->oAssigned=1;
|
||||
break;
|
||||
case SECT_HRAM:
|
||||
if( (pSection->nOrg=area_Alloc(&BankFree[BANK_HRAM],pSection->nByteSize))==-1 )
|
||||
{
|
||||
fatalerror( "HRAM section too large" );
|
||||
}
|
||||
pSection->nBank=BANK_HRAM;
|
||||
pSection->oAssigned=1;
|
||||
break;
|
||||
case SECT_VRAM:
|
||||
if( (pSection->nOrg=area_Alloc(&BankFree[BANK_VRAM],pSection->nByteSize))==-1 )
|
||||
{
|
||||
fatalerror( "VRAM section too large" );
|
||||
}
|
||||
pSection->nBank=BANK_VRAM;
|
||||
pSection->oAssigned=1;
|
||||
break;
|
||||
case SECT_HOME:
|
||||
if( (pSection->nOrg=area_Alloc(&BankFree[BANK_HOME],pSection->nByteSize))==-1 )
|
||||
{
|
||||
fatalerror( "HOME section too large" );
|
||||
}
|
||||
pSection->nBank=BANK_HOME;
|
||||
pSection->oAssigned=1;
|
||||
break;
|
||||
case SECT_CODE:
|
||||
break;
|
||||
default:
|
||||
fatalerror( "(INTERNAL) Unknown section type!" );
|
||||
break;
|
||||
pSection = pSections;
|
||||
while (pSection) {
|
||||
if (pSection->oAssigned == 0) {
|
||||
switch (pSection->Type) {
|
||||
case SECT_BSS:
|
||||
if ((pSection->nOrg =
|
||||
area_Alloc(&BankFree[BANK_BSS],
|
||||
pSection->nByteSize)) == -1) {
|
||||
fatalerror("BSS section too large\n");
|
||||
}
|
||||
pSection->nBank = BANK_BSS;
|
||||
pSection->oAssigned = 1;
|
||||
break;
|
||||
case SECT_HRAM:
|
||||
if ((pSection->nOrg =
|
||||
area_Alloc(&BankFree[BANK_HRAM],
|
||||
pSection->nByteSize)) == -1) {
|
||||
fatalerror("HRAM section too large");
|
||||
}
|
||||
pSection->nBank = BANK_HRAM;
|
||||
pSection->oAssigned = 1;
|
||||
break;
|
||||
case SECT_VRAM:
|
||||
if ((pSection->nOrg =
|
||||
area_Alloc(&BankFree[BANK_VRAM],
|
||||
pSection->nByteSize)) == -1) {
|
||||
fatalerror("VRAM section too large");
|
||||
}
|
||||
pSection->nBank = BANK_VRAM;
|
||||
pSection->oAssigned = 1;
|
||||
break;
|
||||
case SECT_HOME:
|
||||
if ((pSection->nOrg =
|
||||
area_Alloc(&BankFree[BANK_HOME],
|
||||
pSection->nByteSize)) == -1) {
|
||||
fatalerror("HOME section too large");
|
||||
}
|
||||
pSection->nBank = BANK_HOME;
|
||||
pSection->oAssigned = 1;
|
||||
break;
|
||||
case SECT_CODE:
|
||||
break;
|
||||
default:
|
||||
fatalerror("(INTERNAL) Unknown section type!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
pSection=pSection->pNext;
|
||||
pSection = pSection->pNext;
|
||||
}
|
||||
|
||||
AssignCodeSections();
|
||||
}
|
||||
|
||||
void PSION2_AssignSections( void )
|
||||
void PSION2_AssignSections(void)
|
||||
{
|
||||
struct sSection *pSection;
|
||||
|
||||
if( BankFree[0]=(struct sFreeArea *)malloc(sizeof(struct sFreeArea)) )
|
||||
{
|
||||
BankFree[0]->nOrg=0x0000;
|
||||
BankFree[0]->nSize=0x10000;
|
||||
MaxAvail[0]=0x10000;
|
||||
BankFree[0]->pPrev=NULL;
|
||||
BankFree[0]->pNext=NULL;
|
||||
if (BankFree[0] = (struct sFreeArea *)malloc(sizeof(struct sFreeArea))) {
|
||||
BankFree[0]->nOrg = 0x0000;
|
||||
BankFree[0]->nSize = 0x10000;
|
||||
MaxAvail[0] = 0x10000;
|
||||
BankFree[0]->pPrev = NULL;
|
||||
BankFree[0]->pNext = NULL;
|
||||
|
||||
pSection=pSections;
|
||||
while( pSection )
|
||||
{
|
||||
if( pSection->oAssigned==0 && pSection->Type==SECT_CODE )
|
||||
{
|
||||
pSection->oAssigned=1;
|
||||
pSection->nBank=0;
|
||||
pSection->nOrg=BankFree[0]->nOrg;
|
||||
BankFree[0]->nOrg+=pSection->nByteSize;
|
||||
BankFree[0]->nSize-=pSection->nByteSize;
|
||||
pSection = pSections;
|
||||
while (pSection) {
|
||||
if (pSection->oAssigned == 0
|
||||
&& pSection->Type == SECT_CODE) {
|
||||
pSection->oAssigned = 1;
|
||||
pSection->nBank = 0;
|
||||
pSection->nOrg = BankFree[0]->nOrg;
|
||||
BankFree[0]->nOrg += pSection->nByteSize;
|
||||
BankFree[0]->nSize -= pSection->nByteSize;
|
||||
}
|
||||
pSection=pSection->pNext;
|
||||
pSection = pSection->pNext;
|
||||
}
|
||||
|
||||
pSection=pSections;
|
||||
while( pSection )
|
||||
{
|
||||
if( pSection->oAssigned==0 && pSection->Type==SECT_BSS )
|
||||
{
|
||||
pSection->oAssigned=1;
|
||||
pSection->nBank=0;
|
||||
pSection->nOrg=BankFree[0]->nOrg;
|
||||
BankFree[0]->nOrg+=pSection->nByteSize;
|
||||
BankFree[0]->nSize-=pSection->nByteSize;
|
||||
pSection = pSections;
|
||||
while (pSection) {
|
||||
if (pSection->oAssigned == 0
|
||||
&& pSection->Type == SECT_BSS) {
|
||||
pSection->oAssigned = 1;
|
||||
pSection->nBank = 0;
|
||||
pSection->nOrg = BankFree[0]->nOrg;
|
||||
BankFree[0]->nOrg += pSection->nByteSize;
|
||||
BankFree[0]->nSize -= pSection->nByteSize;
|
||||
}
|
||||
pSection=pSection->pNext;
|
||||
pSection = pSection->pNext;
|
||||
}
|
||||
}
|
||||
else
|
||||
fatalerror( "Out of memory!" );
|
||||
} else
|
||||
fatalerror("Out of memory!");
|
||||
}
|
||||
|
||||
void AssignSections( void )
|
||||
void AssignSections(void)
|
||||
{
|
||||
switch( outputtype )
|
||||
{
|
||||
case OUTPUT_GBROM:
|
||||
GBROM_AssignSections();
|
||||
break;
|
||||
case OUTPUT_PSION2:
|
||||
PSION2_AssignSections();
|
||||
break;
|
||||
switch (outputtype) {
|
||||
case OUTPUT_GBROM:
|
||||
GBROM_AssignSections();
|
||||
break;
|
||||
case OUTPUT_PSION2:
|
||||
PSION2_AssignSections();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CreateSymbolTable( void )
|
||||
void CreateSymbolTable(void)
|
||||
{
|
||||
struct sSection *pSect;
|
||||
|
||||
sym_Init();
|
||||
|
||||
pSect=pSections;
|
||||
pSect = pSections;
|
||||
|
||||
while( pSect )
|
||||
{
|
||||
SLONG i;
|
||||
while (pSect) {
|
||||
SLONG i;
|
||||
|
||||
i=pSect->nNumberOfSymbols;
|
||||
i = pSect->nNumberOfSymbols;
|
||||
|
||||
while( i-- )
|
||||
{
|
||||
if( (pSect->tSymbols[i]->Type==SYM_EXPORT) &&
|
||||
( (pSect->tSymbols[i]->pSection==pSect) ||
|
||||
(pSect->tSymbols[i]->pSection==NULL)) )
|
||||
{
|
||||
if( pSect->tSymbols[i]->pSection==NULL )
|
||||
sym_CreateSymbol( pSect->tSymbols[i]->pzName,
|
||||
pSect->tSymbols[i]->nOffset,
|
||||
-1 );
|
||||
while (i--) {
|
||||
if ((pSect->tSymbols[i]->Type == SYM_EXPORT) &&
|
||||
((pSect->tSymbols[i]->pSection == pSect) ||
|
||||
(pSect->tSymbols[i]->pSection == NULL))) {
|
||||
if (pSect->tSymbols[i]->pSection == NULL)
|
||||
sym_CreateSymbol(pSect->tSymbols[i]->
|
||||
pzName,
|
||||
pSect->tSymbols[i]->
|
||||
nOffset, -1);
|
||||
else
|
||||
sym_CreateSymbol( pSect->tSymbols[i]->pzName,
|
||||
pSect->nOrg+pSect->tSymbols[i]->nOffset,
|
||||
pSect->nBank );
|
||||
sym_CreateSymbol(pSect->tSymbols[i]->
|
||||
pzName,
|
||||
pSect->nOrg +
|
||||
pSect->tSymbols[i]->
|
||||
nOffset, pSect->nBank);
|
||||
}
|
||||
}
|
||||
pSect=pSect->pNext;
|
||||
pSect = pSect->pNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,20 +3,19 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
enum eBankDefine
|
||||
{
|
||||
BANK_HOME=0,
|
||||
BANK_BSS=256,
|
||||
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];
|
||||
extern SLONG area_Avail(SLONG bank);
|
||||
extern void AssignSections(void);
|
||||
extern void CreateSymbolTable(void);
|
||||
extern SLONG MaxBankUsed;
|
||||
extern SLONG MaxAvail[MAXBANKS];
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#ifndef LIBRARY_H
|
||||
#define LIBRARY_H
|
||||
|
||||
extern void AddNeededModules( void );
|
||||
extern void AddNeededModules(void);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -3,19 +3,17 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
extern void PrintUsage( void );
|
||||
extern void fatalerror( char *s );
|
||||
extern char temptext[1024];
|
||||
extern SLONG fillchar;
|
||||
extern char smartlinkstartsymbol[256];
|
||||
extern void PrintUsage(void);
|
||||
extern void fatalerror(char *s);
|
||||
extern char temptext[1024];
|
||||
extern SLONG fillchar;
|
||||
extern char smartlinkstartsymbol[256];
|
||||
|
||||
enum eOutputType
|
||||
{
|
||||
enum eOutputType {
|
||||
OUTPUT_GBROM,
|
||||
OUTPUT_PSION2
|
||||
};
|
||||
|
||||
extern enum eOutputType outputtype;
|
||||
extern enum eOutputType outputtype;
|
||||
|
||||
|
||||
#endif
|
||||
#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 );
|
||||
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
|
||||
#endif
|
||||
|
||||
@@ -7,13 +7,12 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
extern SLONG options;
|
||||
extern SLONG options;
|
||||
#define OPT_SMALL 0x01
|
||||
#define OPT_SMART_C_LINK 0x02
|
||||
|
||||
enum eRpnData
|
||||
{
|
||||
RPN_ADD=0,
|
||||
enum eRpnData {
|
||||
RPN_ADD = 0,
|
||||
RPN_SUB,
|
||||
RPN_MUL,
|
||||
RPN_DIV,
|
||||
@@ -47,12 +46,11 @@ enum eRpnData
|
||||
|
||||
RPN_RANGECHECK,
|
||||
|
||||
RPN_CONST=0x80,
|
||||
RPN_SYM=0x81
|
||||
RPN_CONST = 0x80,
|
||||
RPN_SYM = 0x81
|
||||
};
|
||||
|
||||
enum eSectionType
|
||||
{
|
||||
enum eSectionType {
|
||||
SECT_BSS,
|
||||
SECT_VRAM,
|
||||
SECT_CODE,
|
||||
@@ -60,60 +58,55 @@ enum eSectionType
|
||||
SECT_HRAM
|
||||
};
|
||||
|
||||
struct sSection
|
||||
{
|
||||
SLONG nBank;
|
||||
SLONG nOrg;
|
||||
BBOOL oAssigned;
|
||||
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;
|
||||
SLONG nByteSize;
|
||||
enum eSectionType Type;
|
||||
UBYTE *pData;
|
||||
SLONG nNumberOfSymbols;
|
||||
struct sSymbol **tSymbols;
|
||||
struct sPatch *pPatches;
|
||||
struct sSection *pNext;
|
||||
};
|
||||
|
||||
enum eSymbolType
|
||||
{
|
||||
enum eSymbolType {
|
||||
SYM_LOCAL,
|
||||
SYM_IMPORT,
|
||||
SYM_EXPORT
|
||||
};
|
||||
|
||||
struct sSymbol
|
||||
{
|
||||
char *pzName;
|
||||
enum eSymbolType Type;
|
||||
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;
|
||||
SLONG nSectionID; /* internal to object.c */
|
||||
struct sSection *pSection;
|
||||
SLONG nOffset;
|
||||
};
|
||||
|
||||
enum ePatchType
|
||||
{
|
||||
PATCH_BYTE=0,
|
||||
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;
|
||||
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;
|
||||
extern struct sSection *pSections;
|
||||
extern struct sSection *pLibSections;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef OBJECT_H
|
||||
#define OBJECT_H
|
||||
|
||||
extern void obj_Readfile( char *tzObjectfile );
|
||||
extern void lib_Readfile( char *tzLibfile );
|
||||
extern void obj_Readfile(char *tzObjectfile);
|
||||
extern void lib_Readfile(char *tzLibfile);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef OUTPUT_H
|
||||
#define OUTPUT_H
|
||||
|
||||
void out_Setname( char *tzOutputfile );
|
||||
void Output( void );
|
||||
void out_Setname(char *tzOutputfile);
|
||||
void Output(void);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#include "types.h"
|
||||
|
||||
void Patch( void );
|
||||
extern SLONG nPC;
|
||||
void Patch(void);
|
||||
extern SLONG nPC;
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
|
||||
#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 );
|
||||
void sym_Init(void);
|
||||
void sym_CreateSymbol(char *tzName, SLONG nValue, SBYTE nBank);
|
||||
SLONG sym_GetValue(char *tzName);
|
||||
SLONG sym_GetBank(char *tzName);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -5,12 +5,12 @@
|
||||
#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;
|
||||
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
|
||||
#endif
|
||||
|
||||
@@ -5,123 +5,114 @@
|
||||
#include "mylink.h"
|
||||
#include "main.h"
|
||||
|
||||
static BBOOL symboldefined( char *name )
|
||||
static BBOOL symboldefined(char *name)
|
||||
{
|
||||
struct sSection *pSect;
|
||||
struct sSection *pSect;
|
||||
|
||||
pSect=pSections;
|
||||
pSect = pSections;
|
||||
|
||||
while( pSect )
|
||||
{
|
||||
ULONG i;
|
||||
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 );
|
||||
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;
|
||||
pSect = pSect->pNext;
|
||||
}
|
||||
return( 0 );
|
||||
return (0);
|
||||
}
|
||||
|
||||
static BBOOL addmodulecontaining( char *name )
|
||||
static BBOOL addmodulecontaining(char *name)
|
||||
{
|
||||
struct sSection **ppLSect;
|
||||
struct sSection **ppLSect;
|
||||
|
||||
ppLSect=&pLibSections;
|
||||
ppLSect = &pLibSections;
|
||||
|
||||
while( *ppLSect )
|
||||
{
|
||||
ULONG i;
|
||||
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);
|
||||
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 );
|
||||
return (1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
ppLSect=&((*ppLSect)->pNext);
|
||||
ppLSect = &((*ppLSect)->pNext);
|
||||
}
|
||||
return( 0 );
|
||||
return (0);
|
||||
}
|
||||
|
||||
void AddNeededModules( void )
|
||||
void AddNeededModules(void)
|
||||
{
|
||||
struct sSection *pSect;
|
||||
struct sSection *pSect;
|
||||
|
||||
if( (options&OPT_SMART_C_LINK)==0 )
|
||||
{
|
||||
struct sSection **ppLSect;
|
||||
if ((options & OPT_SMART_C_LINK) == 0) {
|
||||
struct sSection **ppLSect;
|
||||
|
||||
ppLSect=&pLibSections;
|
||||
ppLSect = &pLibSections;
|
||||
|
||||
while( *ppLSect )
|
||||
{
|
||||
struct sSection **ppSect;
|
||||
ppSect=&pSections;
|
||||
while( *ppSect )
|
||||
ppSect=&((*ppSect)->pNext);
|
||||
while (*ppLSect) {
|
||||
struct sSection **ppSect;
|
||||
ppSect = &pSections;
|
||||
while (*ppSect)
|
||||
ppSect = &((*ppSect)->pNext);
|
||||
|
||||
*ppSect = *ppLSect;
|
||||
*ppLSect = (*ppLSect)->pNext;
|
||||
(*ppSect)->pNext = NULL;
|
||||
|
||||
/*ppLSect=&((*ppLSect)->pNext);*/
|
||||
/*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 );
|
||||
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;
|
||||
pSect = pSections;
|
||||
|
||||
while( pSect )
|
||||
{
|
||||
ULONG i;
|
||||
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 );
|
||||
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;
|
||||
pSect = pSect->pNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
276
src/link/main.c
276
src/link/main.c
@@ -12,34 +12,33 @@
|
||||
#include "main.h"
|
||||
#include "library.h"
|
||||
|
||||
// Quick and dirty...but it works
|
||||
// Quick and dirty...but it works
|
||||
#ifdef __GNUC__
|
||||
#define strcmpi strcasecmp
|
||||
#endif
|
||||
|
||||
enum eBlockType
|
||||
{
|
||||
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];
|
||||
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 )
|
||||
void fatalerror(char *s)
|
||||
{
|
||||
printf( "*ERROR* : %s\n", s );
|
||||
exit( 5 );
|
||||
printf("*ERROR* : %s\n", s);
|
||||
exit(5);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -47,21 +46,20 @@ void fatalerror( char *s )
|
||||
*
|
||||
*/
|
||||
|
||||
void PrintUsage( void )
|
||||
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 );
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -69,62 +67,58 @@ void PrintUsage( void )
|
||||
*
|
||||
*/
|
||||
|
||||
void ProcessLinkfile( char *tzLinkfile )
|
||||
void ProcessLinkfile(char *tzLinkfile)
|
||||
{
|
||||
FILE *pLinkfile;
|
||||
enum eBlockType CurrentBlock=BLOCK_COMMENT;
|
||||
FILE *pLinkfile;
|
||||
enum eBlockType CurrentBlock = BLOCK_COMMENT;
|
||||
|
||||
if( pLinkfile=fopen(tzLinkfile,"rt") )
|
||||
{
|
||||
while( !feof(pLinkfile) )
|
||||
{
|
||||
char tzLine[256];
|
||||
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 );
|
||||
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;
|
||||
} 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 );
|
||||
fclose(pLinkfile);
|
||||
} else {
|
||||
sprintf(temptext, "Unable to find linkfile '%s'\n", tzLinkfile);
|
||||
fatalerror(temptext);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -134,97 +128,89 @@ void ProcessLinkfile( char *tzLinkfile )
|
||||
*
|
||||
*/
|
||||
|
||||
int main( int argc, char *argv[] )
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
SLONG argn=0;
|
||||
SLONG argn = 0;
|
||||
|
||||
argc-=1;
|
||||
argn+=1;
|
||||
argc -= 1;
|
||||
argn += 1;
|
||||
|
||||
if( argc==0 )
|
||||
if (argc == 0)
|
||||
PrintUsage();
|
||||
|
||||
while( *argv[argn]=='-' )
|
||||
{
|
||||
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" );
|
||||
}
|
||||
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':
|
||||
options|=OPT_SMART_C_LINK;
|
||||
strcpy( smartlinkstartsymbol, argv[argn-1]+2 );
|
||||
outputtype = OUTPUT_GBROM;
|
||||
options |= OPT_SMALL;
|
||||
break;
|
||||
case 'p':
|
||||
outputtype = OUTPUT_PSION2;
|
||||
break;
|
||||
default:
|
||||
sprintf( temptext, "Unknown option '%c'\n", opt );
|
||||
fatalerror( temptext );
|
||||
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++] );
|
||||
if (argc == 1) {
|
||||
ProcessLinkfile(argv[argn++]);
|
||||
AddNeededModules();
|
||||
AssignSections();
|
||||
CreateSymbolTable();
|
||||
Patch();
|
||||
Output();
|
||||
CloseMapfile();
|
||||
}
|
||||
else
|
||||
} else
|
||||
PrintUsage();
|
||||
|
||||
return( 0 );
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
@@ -7,88 +7,84 @@
|
||||
#include "mylink.h"
|
||||
#include "assign.h"
|
||||
|
||||
FILE *mf=NULL;
|
||||
FILE *sf=NULL;
|
||||
SLONG currentbank=0;
|
||||
SLONG sfbank;
|
||||
FILE *mf = NULL;
|
||||
FILE *sf = NULL;
|
||||
SLONG currentbank = 0;
|
||||
SLONG sfbank;
|
||||
|
||||
void SetMapfileName( char *name )
|
||||
void SetMapfileName(char *name)
|
||||
{
|
||||
if( mf=fopen(name,"wt") )
|
||||
if (mf = fopen(name, "wt"))
|
||||
return;
|
||||
else
|
||||
fatalerror( "Unable to open mapfile for writing" );
|
||||
fatalerror("Unable to open mapfile for writing");
|
||||
}
|
||||
|
||||
void SetSymfileName( char *name )
|
||||
void SetSymfileName(char *name)
|
||||
{
|
||||
if( sf=fopen(name,"wt") )
|
||||
{
|
||||
fprintf( sf, ";File generated by xLink v" LINK_VERSION "\n\n" );
|
||||
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" );
|
||||
} else
|
||||
fatalerror("Unable to open symfile for writing");
|
||||
}
|
||||
|
||||
void CloseMapfile( void )
|
||||
void CloseMapfile(void)
|
||||
{
|
||||
if( mf )
|
||||
{
|
||||
fclose( mf );
|
||||
mf=NULL;
|
||||
if (mf) {
|
||||
fclose(mf);
|
||||
mf = NULL;
|
||||
}
|
||||
if( sf )
|
||||
{
|
||||
fclose( sf );
|
||||
sf=NULL;
|
||||
if (sf) {
|
||||
fclose(sf);
|
||||
sf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void MapfileInitBank( SLONG bank )
|
||||
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 (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;
|
||||
if (sf) {
|
||||
sfbank = (bank >= 1 && bank <= 255) ? bank : 0;
|
||||
}
|
||||
}
|
||||
|
||||
void MapfileWriteSection( struct sSection *pSect )
|
||||
void MapfileWriteSection(struct sSection *pSect)
|
||||
{
|
||||
if( mf || sf )
|
||||
{
|
||||
SLONG i;
|
||||
if (mf || sf) {
|
||||
SLONG i;
|
||||
|
||||
fprintf( mf, " SECTION: $%04X-$%04X ($%04X bytes)\n", pSect->nOrg, pSect->nOrg+pSect->nByteSize-1, pSect->nByteSize );
|
||||
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 );
|
||||
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 );
|
||||
if (sf) {
|
||||
fprintf(sf, "%02X:%04X %s\n", sfbank,
|
||||
pSym->nOffset + pSect->nOrg,
|
||||
pSym->pzName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -96,13 +92,12 @@ void MapfileWriteSection( struct sSection *pSect )
|
||||
}
|
||||
}
|
||||
|
||||
void MapfileCloseBank( SLONG slack )
|
||||
void MapfileCloseBank(SLONG slack)
|
||||
{
|
||||
if( mf )
|
||||
{
|
||||
if( slack==MaxAvail[currentbank] )
|
||||
fprintf( mf, " EMPTY\n\n" );
|
||||
if (mf) {
|
||||
if (slack == MaxAvail[currentbank])
|
||||
fprintf(mf, " EMPTY\n\n");
|
||||
else
|
||||
fprintf( mf, " SLACK: $%04X bytes\n\n", slack );
|
||||
fprintf(mf, " SLACK: $%04X bytes\n\n", slack);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,38 +10,37 @@
|
||||
#include "mylink.h"
|
||||
#include "main.h"
|
||||
|
||||
struct sSymbol **tSymbols;
|
||||
struct sSection *pSections=NULL;
|
||||
struct sSection *pLibSections=NULL;
|
||||
UBYTE dummymem;
|
||||
BBOOL oReadLib=0;
|
||||
|
||||
struct sSymbol **tSymbols;
|
||||
struct sSection *pSections = NULL;
|
||||
struct sSection *pLibSections = NULL;
|
||||
UBYTE dummymem;
|
||||
BBOOL oReadLib = 0;
|
||||
|
||||
/*
|
||||
* The usual byte order stuff
|
||||
*
|
||||
*/
|
||||
|
||||
SLONG readlong( FILE *f )
|
||||
SLONG readlong(FILE * f)
|
||||
{
|
||||
SLONG r;
|
||||
SLONG r;
|
||||
|
||||
r =fgetc(f);
|
||||
r|=fgetc(f)<<8;
|
||||
r|=fgetc(f)<<16;
|
||||
r|=fgetc(f)<<24;
|
||||
r = fgetc(f);
|
||||
r |= fgetc(f) << 8;
|
||||
r |= fgetc(f) << 16;
|
||||
r |= fgetc(f) << 24;
|
||||
|
||||
return( r );
|
||||
return (r);
|
||||
}
|
||||
|
||||
UWORD readword( FILE *f )
|
||||
UWORD readword(FILE * f)
|
||||
{
|
||||
UWORD r;
|
||||
UWORD r;
|
||||
|
||||
r =fgetc(f);
|
||||
r|=fgetc(f)<<8;
|
||||
r = fgetc(f);
|
||||
r |= fgetc(f) << 8;
|
||||
|
||||
return( r );
|
||||
return (r);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -49,46 +48,42 @@ UWORD readword( FILE *f )
|
||||
*
|
||||
*/
|
||||
|
||||
SLONG readasciiz( char *s, FILE *f )
|
||||
SLONG readasciiz(char *s, FILE * f)
|
||||
{
|
||||
SLONG r=0;
|
||||
SLONG r = 0;
|
||||
|
||||
while( ((*s++)=fgetc(f))!=0 )
|
||||
r+=1;
|
||||
while (((*s++) = fgetc(f)) != 0)
|
||||
r += 1;
|
||||
|
||||
return( r+1 );
|
||||
return (r + 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Allocate a new section and link it into the list
|
||||
*
|
||||
*/
|
||||
|
||||
struct sSection *AllocSection( void )
|
||||
struct sSection *AllocSection(void)
|
||||
{
|
||||
struct sSection **ppSections;
|
||||
struct sSection **ppSections;
|
||||
|
||||
if( oReadLib==1 )
|
||||
ppSections=&pLibSections;
|
||||
if (oReadLib == 1)
|
||||
ppSections = &pLibSections;
|
||||
else
|
||||
ppSections=&pSections;
|
||||
ppSections = &pSections;
|
||||
|
||||
while( *ppSections )
|
||||
ppSections=&((*ppSections)->pNext);
|
||||
while (*ppSections)
|
||||
ppSections = &((*ppSections)->pNext);
|
||||
|
||||
if( (*ppSections)=(struct sSection *)malloc(sizeof(struct sSection)) )
|
||||
{
|
||||
(*ppSections)->tSymbols=tSymbols;
|
||||
(*ppSections)->pNext=NULL;
|
||||
(*ppSections)->pPatches=NULL;
|
||||
(*ppSections)->oAssigned=0;
|
||||
return( *ppSections );
|
||||
}
|
||||
else
|
||||
{
|
||||
fatalerror( "Out of memory!" );
|
||||
return( NULL );
|
||||
if ((*ppSections) = (struct sSection *)malloc(sizeof(struct sSection))) {
|
||||
(*ppSections)->tSymbols = tSymbols;
|
||||
(*ppSections)->pNext = NULL;
|
||||
(*ppSections)->pPatches = NULL;
|
||||
(*ppSections)->oAssigned = 0;
|
||||
return (*ppSections);
|
||||
} else {
|
||||
fatalerror("Out of memory!");
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,31 +92,27 @@ struct sSection *AllocSection( void )
|
||||
*
|
||||
*/
|
||||
|
||||
struct sSymbol *obj_ReadSymbol( FILE *f )
|
||||
struct sSymbol *obj_ReadSymbol(FILE * f)
|
||||
{
|
||||
char s[256];
|
||||
struct sSymbol *pSym;
|
||||
char s[256];
|
||||
struct sSymbol *pSym;
|
||||
|
||||
if( pSym=(struct sSymbol *)malloc(sizeof(struct sSymbol)) )
|
||||
{
|
||||
readasciiz( s, f );
|
||||
if( pSym->pzName=(char *)malloc(strlen(s)+1) )
|
||||
{
|
||||
strcpy( pSym->pzName, s );
|
||||
if( (pSym->Type=(enum eSymbolType)fgetc(f))!=SYM_IMPORT )
|
||||
{
|
||||
pSym->nSectionID=readlong(f);
|
||||
pSym->nOffset=readlong(f);
|
||||
if (pSym = (struct sSymbol *)malloc(sizeof(struct sSymbol))) {
|
||||
readasciiz(s, f);
|
||||
if (pSym->pzName = (char *)malloc(strlen(s) + 1)) {
|
||||
strcpy(pSym->pzName, s);
|
||||
if ((pSym->Type =
|
||||
(enum eSymbolType)fgetc(f)) != SYM_IMPORT) {
|
||||
pSym->nSectionID = readlong(f);
|
||||
pSym->nOffset = readlong(f);
|
||||
}
|
||||
return( pSym );
|
||||
}
|
||||
else
|
||||
fatalerror( "Out of memory!" );
|
||||
}
|
||||
else
|
||||
fatalerror( "Out of memory!" );
|
||||
return (pSym);
|
||||
} else
|
||||
fatalerror("Out of memory!");
|
||||
} else
|
||||
fatalerror("Out of memory!");
|
||||
|
||||
return( NULL );
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -129,124 +120,135 @@ struct sSymbol *obj_ReadSymbol( FILE *f )
|
||||
*
|
||||
*/
|
||||
|
||||
struct sSection *obj_ReadRGB0Section( FILE *f )
|
||||
struct sSection *obj_ReadRGB0Section(FILE * f)
|
||||
{
|
||||
struct sSection *pSection;
|
||||
struct sSection *pSection;
|
||||
|
||||
pSection=AllocSection();
|
||||
pSection = AllocSection();
|
||||
|
||||
pSection->nByteSize=readlong( f );
|
||||
pSection->Type=(enum eSectionType)fgetc( f );
|
||||
pSection->nOrg=-1;
|
||||
pSection->nBank=-1;
|
||||
pSection->nByteSize = readlong(f);
|
||||
pSection->Type = (enum eSectionType)fgetc(f);
|
||||
pSection->nOrg = -1;
|
||||
pSection->nBank = -1;
|
||||
|
||||
/* does the user want the -s mode? */
|
||||
|
||||
if( (options&OPT_SMALL) && (pSection->Type==SECT_CODE) )
|
||||
{
|
||||
pSection->Type=SECT_HOME;
|
||||
if ((options & OPT_SMALL) && (pSection->Type == SECT_CODE)) {
|
||||
pSection->Type = SECT_HOME;
|
||||
}
|
||||
|
||||
if( (pSection->Type==SECT_CODE) || (pSection->Type==SECT_HOME) )
|
||||
{
|
||||
if ((pSection->Type == SECT_CODE) || (pSection->Type == SECT_HOME)) {
|
||||
/*
|
||||
* These sectiontypes contain data...
|
||||
*
|
||||
*/
|
||||
if( pSection->nByteSize )
|
||||
{
|
||||
if( pSection->pData=(UBYTE *)malloc(pSection->nByteSize) )
|
||||
{
|
||||
SLONG nNumberOfPatches;
|
||||
struct sPatch **ppPatch, *pPatch;
|
||||
char s[256];
|
||||
if (pSection->nByteSize) {
|
||||
if (pSection->pData =
|
||||
(UBYTE *) malloc(pSection->nByteSize)) {
|
||||
SLONG nNumberOfPatches;
|
||||
struct sPatch **ppPatch, *pPatch;
|
||||
char s[256];
|
||||
|
||||
fread( pSection->pData, sizeof(UBYTE), pSection->nByteSize, f );
|
||||
nNumberOfPatches=readlong(f);
|
||||
ppPatch=&pSection->pPatches;
|
||||
fread(pSection->pData, sizeof(UBYTE),
|
||||
pSection->nByteSize, f);
|
||||
nNumberOfPatches = readlong(f);
|
||||
ppPatch = &pSection->pPatches;
|
||||
|
||||
/*
|
||||
* And patches...
|
||||
*
|
||||
*/
|
||||
while( nNumberOfPatches-- )
|
||||
{
|
||||
if( pPatch=(struct sPatch *)malloc(sizeof(struct sPatch)) )
|
||||
{
|
||||
*ppPatch=pPatch;
|
||||
readasciiz( s, f );
|
||||
if( pPatch->pzFilename=(char *)malloc(strlen(s)+1) )
|
||||
{
|
||||
strcpy( pPatch->pzFilename, s );
|
||||
pPatch->nLineNo=readlong( f );
|
||||
pPatch->nOffset=readlong( f );
|
||||
pPatch->Type=(enum ePatchType)fgetc( f );
|
||||
if( (pPatch->nRPNSize=readlong(f))>0 )
|
||||
{
|
||||
if( pPatch->pRPN=(UBYTE *)malloc(pPatch->nRPNSize) )
|
||||
fread( pPatch->pRPN, sizeof(UBYTE), pPatch->nRPNSize, f );
|
||||
while (nNumberOfPatches--) {
|
||||
if (pPatch =
|
||||
(struct sPatch *)
|
||||
malloc(sizeof(struct sPatch))) {
|
||||
*ppPatch = pPatch;
|
||||
readasciiz(s, f);
|
||||
if (pPatch->pzFilename =
|
||||
(char *)malloc(strlen(s) +
|
||||
1)) {
|
||||
strcpy(pPatch->
|
||||
pzFilename, s);
|
||||
pPatch->nLineNo =
|
||||
readlong(f);
|
||||
pPatch->nOffset =
|
||||
readlong(f);
|
||||
pPatch->Type =
|
||||
(enum ePatchType)
|
||||
fgetc(f);
|
||||
if ((pPatch->nRPNSize =
|
||||
readlong(f)) > 0) {
|
||||
if (pPatch->
|
||||
pRPN =
|
||||
(UBYTE *)
|
||||
malloc
|
||||
(pPatch->
|
||||
nRPNSize))
|
||||
fread
|
||||
(pPatch->
|
||||
pRPN,
|
||||
sizeof
|
||||
(UBYTE),
|
||||
pPatch->
|
||||
nRPNSize,
|
||||
f);
|
||||
else
|
||||
fatalerror( "Out of memory!" );
|
||||
}
|
||||
else
|
||||
pPatch->pRPN=NULL;
|
||||
pPatch->pNext=NULL;
|
||||
ppPatch=&(pPatch->pNext);
|
||||
}
|
||||
else
|
||||
fatalerror( "Out of memory!" );
|
||||
}
|
||||
else
|
||||
fatalerror( "Out of memory!" );
|
||||
fatalerror
|
||||
("Out of memory!");
|
||||
} else
|
||||
pPatch->pRPN =
|
||||
NULL;
|
||||
pPatch->pNext = NULL;
|
||||
ppPatch =
|
||||
&(pPatch->pNext);
|
||||
} else
|
||||
fatalerror
|
||||
("Out of memory!");
|
||||
} else
|
||||
fatalerror("Out of memory!");
|
||||
}
|
||||
}
|
||||
else
|
||||
fatalerror( "Out of memory!" );
|
||||
}
|
||||
else
|
||||
{
|
||||
readlong(f); // Skip number of patches
|
||||
pSection->pData=&dummymem;
|
||||
} else
|
||||
fatalerror("Out of memory!");
|
||||
} else {
|
||||
readlong(f); // Skip number of patches
|
||||
pSection->pData = &dummymem;
|
||||
}
|
||||
}
|
||||
|
||||
return( pSection );
|
||||
return (pSection);
|
||||
}
|
||||
|
||||
void obj_ReadRGB0( FILE *pObjfile )
|
||||
void obj_ReadRGB0(FILE * pObjfile)
|
||||
{
|
||||
struct sSection *pFirstSection;
|
||||
SLONG nNumberOfSymbols, nNumberOfSections, i;
|
||||
struct sSection *pFirstSection;
|
||||
SLONG nNumberOfSymbols, nNumberOfSections, i;
|
||||
|
||||
nNumberOfSymbols=readlong( pObjfile );
|
||||
nNumberOfSections=readlong( pObjfile );
|
||||
nNumberOfSymbols = readlong(pObjfile);
|
||||
nNumberOfSections = readlong(pObjfile);
|
||||
|
||||
/* First comes the symbols */
|
||||
|
||||
if( nNumberOfSymbols )
|
||||
{
|
||||
if( tSymbols=(struct sSymbol **)malloc(nNumberOfSymbols*sizeof(struct sSymbol *)) )
|
||||
{
|
||||
for( i=0; i<nNumberOfSymbols; i+=1 )
|
||||
tSymbols[i]=obj_ReadSymbol( pObjfile );
|
||||
}
|
||||
else
|
||||
fatalerror( "Out of memory!" );
|
||||
}
|
||||
else
|
||||
tSymbols=(struct sSymbol **)&dummymem;
|
||||
if (nNumberOfSymbols) {
|
||||
if (tSymbols =
|
||||
(struct sSymbol **)malloc(nNumberOfSymbols *
|
||||
sizeof(struct sSymbol *))) {
|
||||
for (i = 0; i < nNumberOfSymbols; i += 1)
|
||||
tSymbols[i] = obj_ReadSymbol(pObjfile);
|
||||
} else
|
||||
fatalerror("Out of memory!");
|
||||
} else
|
||||
tSymbols = (struct sSymbol **)&dummymem;
|
||||
|
||||
/* Next we have the sections */
|
||||
|
||||
pFirstSection=NULL;
|
||||
while( nNumberOfSections-- )
|
||||
{
|
||||
pFirstSection = NULL;
|
||||
while (nNumberOfSections--) {
|
||||
struct sSection *pNewSection;
|
||||
|
||||
pNewSection=obj_ReadRGB0Section( pObjfile );
|
||||
pNewSection->nNumberOfSymbols=nNumberOfSymbols;
|
||||
if( pFirstSection==NULL )
|
||||
pFirstSection=pNewSection;
|
||||
pNewSection = obj_ReadRGB0Section(pObjfile);
|
||||
pNewSection->nNumberOfSymbols = nNumberOfSymbols;
|
||||
if (pFirstSection == NULL)
|
||||
pFirstSection = pNewSection;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -255,22 +257,19 @@ void obj_ReadRGB0( FILE *pObjfile )
|
||||
*
|
||||
*/
|
||||
|
||||
for( i=0; i<nNumberOfSymbols; i+=1 )
|
||||
{
|
||||
struct sSection *pConvSect=pFirstSection;
|
||||
for (i = 0; i < nNumberOfSymbols; i += 1) {
|
||||
struct sSection *pConvSect = pFirstSection;
|
||||
|
||||
if( tSymbols[i]->Type!=SYM_IMPORT && tSymbols[i]->nSectionID!=-1 )
|
||||
{
|
||||
SLONG j=0;
|
||||
while( j != tSymbols[i]->nSectionID )
|
||||
{
|
||||
j+=1;
|
||||
pConvSect=pConvSect->pNext;
|
||||
if (tSymbols[i]->Type != SYM_IMPORT
|
||||
&& tSymbols[i]->nSectionID != -1) {
|
||||
SLONG j = 0;
|
||||
while (j != tSymbols[i]->nSectionID) {
|
||||
j += 1;
|
||||
pConvSect = pConvSect->pNext;
|
||||
}
|
||||
tSymbols[i]->pSection=pConvSect;
|
||||
}
|
||||
else
|
||||
tSymbols[i]->pSection=NULL;
|
||||
tSymbols[i]->pSection = pConvSect;
|
||||
} else
|
||||
tSymbols[i]->pSection = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,129 +278,140 @@ void obj_ReadRGB0( FILE *pObjfile )
|
||||
*
|
||||
*/
|
||||
|
||||
struct sSection *obj_ReadRGB1Section( FILE *f )
|
||||
struct sSection *obj_ReadRGB1Section(FILE * f)
|
||||
{
|
||||
struct sSection *pSection;
|
||||
struct sSection *pSection;
|
||||
|
||||
pSection=AllocSection();
|
||||
pSection = AllocSection();
|
||||
|
||||
pSection->nByteSize=readlong( f );
|
||||
pSection->Type=(enum eSectionType)fgetc( f );
|
||||
pSection->nByteSize = readlong(f);
|
||||
pSection->Type = (enum eSectionType)fgetc(f);
|
||||
/*
|
||||
* And because of THIS new feature I'll have to rewrite loads and
|
||||
* loads of stuff... oh well it needed to be done anyway
|
||||
*
|
||||
*/
|
||||
pSection->nOrg=readlong( f );
|
||||
pSection->nBank=readlong( f );
|
||||
pSection->nOrg = readlong(f);
|
||||
pSection->nBank = readlong(f);
|
||||
|
||||
/* does the user want the -s mode? */
|
||||
|
||||
if( (options&OPT_SMALL) && (pSection->Type==SECT_CODE) )
|
||||
{
|
||||
pSection->Type=SECT_HOME;
|
||||
if ((options & OPT_SMALL) && (pSection->Type == SECT_CODE)) {
|
||||
pSection->Type = SECT_HOME;
|
||||
}
|
||||
|
||||
if( (pSection->Type==SECT_CODE) || (pSection->Type==SECT_HOME) )
|
||||
{
|
||||
if ((pSection->Type == SECT_CODE) || (pSection->Type == SECT_HOME)) {
|
||||
/*
|
||||
* These sectiontypes contain data...
|
||||
*
|
||||
*/
|
||||
if( pSection->nByteSize )
|
||||
{
|
||||
if( pSection->pData=(UBYTE *)malloc(pSection->nByteSize) )
|
||||
{
|
||||
SLONG nNumberOfPatches;
|
||||
struct sPatch **ppPatch, *pPatch;
|
||||
char s[256];
|
||||
if (pSection->nByteSize) {
|
||||
if (pSection->pData =
|
||||
(UBYTE *) malloc(pSection->nByteSize)) {
|
||||
SLONG nNumberOfPatches;
|
||||
struct sPatch **ppPatch, *pPatch;
|
||||
char s[256];
|
||||
|
||||
fread( pSection->pData, sizeof(UBYTE), pSection->nByteSize, f );
|
||||
nNumberOfPatches=readlong(f);
|
||||
ppPatch=&pSection->pPatches;
|
||||
fread(pSection->pData, sizeof(UBYTE),
|
||||
pSection->nByteSize, f);
|
||||
nNumberOfPatches = readlong(f);
|
||||
ppPatch = &pSection->pPatches;
|
||||
|
||||
/*
|
||||
* And patches...
|
||||
*
|
||||
*/
|
||||
while( nNumberOfPatches-- )
|
||||
{
|
||||
if( pPatch=(struct sPatch *)malloc(sizeof(struct sPatch)) )
|
||||
{
|
||||
*ppPatch=pPatch;
|
||||
readasciiz( s, f );
|
||||
if( pPatch->pzFilename=(char *)malloc(strlen(s)+1) )
|
||||
{
|
||||
strcpy( pPatch->pzFilename, s );
|
||||
pPatch->nLineNo=readlong( f );
|
||||
pPatch->nOffset=readlong( f );
|
||||
pPatch->Type=(enum ePatchType)fgetc( f );
|
||||
if( (pPatch->nRPNSize=readlong(f))>0 )
|
||||
{
|
||||
if( pPatch->pRPN=(UBYTE *)malloc(pPatch->nRPNSize) )
|
||||
fread( pPatch->pRPN, sizeof(UBYTE), pPatch->nRPNSize, f );
|
||||
while (nNumberOfPatches--) {
|
||||
if (pPatch =
|
||||
(struct sPatch *)
|
||||
malloc(sizeof(struct sPatch))) {
|
||||
*ppPatch = pPatch;
|
||||
readasciiz(s, f);
|
||||
if (pPatch->pzFilename =
|
||||
(char *)malloc(strlen(s) +
|
||||
1)) {
|
||||
strcpy(pPatch->
|
||||
pzFilename, s);
|
||||
pPatch->nLineNo =
|
||||
readlong(f);
|
||||
pPatch->nOffset =
|
||||
readlong(f);
|
||||
pPatch->Type =
|
||||
(enum ePatchType)
|
||||
fgetc(f);
|
||||
if ((pPatch->nRPNSize =
|
||||
readlong(f)) > 0) {
|
||||
if (pPatch->
|
||||
pRPN =
|
||||
(UBYTE *)
|
||||
malloc
|
||||
(pPatch->
|
||||
nRPNSize))
|
||||
fread
|
||||
(pPatch->
|
||||
pRPN,
|
||||
sizeof
|
||||
(UBYTE),
|
||||
pPatch->
|
||||
nRPNSize,
|
||||
f);
|
||||
else
|
||||
fatalerror( "Out of memory!" );
|
||||
}
|
||||
else
|
||||
pPatch->pRPN=NULL;
|
||||
pPatch->pNext=NULL;
|
||||
ppPatch=&(pPatch->pNext);
|
||||
}
|
||||
else
|
||||
fatalerror( "Out of memory!" );
|
||||
}
|
||||
else
|
||||
fatalerror( "Out of memory!" );
|
||||
fatalerror
|
||||
("Out of memory!");
|
||||
} else
|
||||
pPatch->pRPN =
|
||||
NULL;
|
||||
pPatch->pNext = NULL;
|
||||
ppPatch =
|
||||
&(pPatch->pNext);
|
||||
} else
|
||||
fatalerror
|
||||
("Out of memory!");
|
||||
} else
|
||||
fatalerror("Out of memory!");
|
||||
}
|
||||
}
|
||||
else
|
||||
fatalerror( "Out of memory!" );
|
||||
}
|
||||
else
|
||||
{
|
||||
readlong(f); // Skip number of patches
|
||||
pSection->pData=&dummymem;
|
||||
} else
|
||||
fatalerror("Out of memory!");
|
||||
} else {
|
||||
readlong(f); // Skip number of patches
|
||||
pSection->pData = &dummymem;
|
||||
}
|
||||
}
|
||||
|
||||
return( pSection );
|
||||
return (pSection);
|
||||
}
|
||||
|
||||
void obj_ReadRGB1( FILE *pObjfile )
|
||||
void obj_ReadRGB1(FILE * pObjfile)
|
||||
{
|
||||
struct sSection *pFirstSection;
|
||||
SLONG nNumberOfSymbols, nNumberOfSections, i;
|
||||
struct sSection *pFirstSection;
|
||||
SLONG nNumberOfSymbols, nNumberOfSections, i;
|
||||
|
||||
nNumberOfSymbols=readlong( pObjfile );
|
||||
nNumberOfSections=readlong( pObjfile );
|
||||
nNumberOfSymbols = readlong(pObjfile);
|
||||
nNumberOfSections = readlong(pObjfile);
|
||||
|
||||
/* First comes the symbols */
|
||||
|
||||
if( nNumberOfSymbols )
|
||||
{
|
||||
if( tSymbols=(struct sSymbol **)malloc(nNumberOfSymbols*sizeof(struct sSymbol *)) )
|
||||
{
|
||||
for( i=0; i<nNumberOfSymbols; i+=1 )
|
||||
tSymbols[i]=obj_ReadSymbol( pObjfile );
|
||||
}
|
||||
else
|
||||
fatalerror( "Out of memory!" );
|
||||
}
|
||||
else
|
||||
tSymbols=(struct sSymbol **)&dummymem;
|
||||
if (nNumberOfSymbols) {
|
||||
if (tSymbols =
|
||||
(struct sSymbol **)malloc(nNumberOfSymbols *
|
||||
sizeof(struct sSymbol *))) {
|
||||
for (i = 0; i < nNumberOfSymbols; i += 1)
|
||||
tSymbols[i] = obj_ReadSymbol(pObjfile);
|
||||
} else
|
||||
fatalerror("Out of memory!");
|
||||
} else
|
||||
tSymbols = (struct sSymbol **)&dummymem;
|
||||
|
||||
/* Next we have the sections */
|
||||
|
||||
pFirstSection=NULL;
|
||||
while( nNumberOfSections-- )
|
||||
{
|
||||
struct sSection *pNewSection;
|
||||
pFirstSection = NULL;
|
||||
while (nNumberOfSections--) {
|
||||
struct sSection *pNewSection;
|
||||
|
||||
pNewSection=obj_ReadRGB1Section( pObjfile );
|
||||
pNewSection->nNumberOfSymbols=nNumberOfSymbols;
|
||||
if( pFirstSection==NULL )
|
||||
pFirstSection=pNewSection;
|
||||
pNewSection = obj_ReadRGB1Section(pObjfile);
|
||||
pNewSection->nNumberOfSymbols = nNumberOfSymbols;
|
||||
if (pFirstSection == NULL)
|
||||
pFirstSection = pNewSection;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -410,22 +420,19 @@ void obj_ReadRGB1( FILE *pObjfile )
|
||||
*
|
||||
*/
|
||||
|
||||
for( i=0; i<nNumberOfSymbols; i+=1 )
|
||||
{
|
||||
struct sSection *pConvSect=pFirstSection;
|
||||
for (i = 0; i < nNumberOfSymbols; i += 1) {
|
||||
struct sSection *pConvSect = pFirstSection;
|
||||
|
||||
if( tSymbols[i]->Type!=SYM_IMPORT && tSymbols[i]->nSectionID!=-1 )
|
||||
{
|
||||
SLONG j=0;
|
||||
while( j != tSymbols[i]->nSectionID )
|
||||
{
|
||||
j+=1;
|
||||
pConvSect=pConvSect->pNext;
|
||||
if (tSymbols[i]->Type != SYM_IMPORT
|
||||
&& tSymbols[i]->nSectionID != -1) {
|
||||
SLONG j = 0;
|
||||
while (j != tSymbols[i]->nSectionID) {
|
||||
j += 1;
|
||||
pConvSect = pConvSect->pNext;
|
||||
}
|
||||
tSymbols[i]->pSection=pConvSect;
|
||||
}
|
||||
else
|
||||
tSymbols[i]->pSection=NULL;
|
||||
tSymbols[i]->pSection = pConvSect;
|
||||
} else
|
||||
tSymbols[i]->pSection = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,113 +441,105 @@ void obj_ReadRGB1( FILE *pObjfile )
|
||||
*
|
||||
*/
|
||||
|
||||
void obj_ReadOpenFile( FILE *pObjfile, char *tzObjectfile )
|
||||
void obj_ReadOpenFile(FILE * pObjfile, char *tzObjectfile)
|
||||
{
|
||||
char tzHeader[8];
|
||||
char tzHeader[8];
|
||||
|
||||
fread( tzHeader, sizeof(char), 4, pObjfile );
|
||||
tzHeader[4]=0;
|
||||
if( strncmp(tzHeader,"RGB", 3)==0 )
|
||||
{
|
||||
switch( tzHeader[3] )
|
||||
{
|
||||
case '0':
|
||||
obj_ReadRGB0( pObjfile );
|
||||
break;
|
||||
case '1':
|
||||
case '2': // V2 is really the same but the are new patch types
|
||||
obj_ReadRGB1( pObjfile );
|
||||
break;
|
||||
default:
|
||||
sprintf( temptext, "'%s' is an unsupported version\n", tzObjectfile );
|
||||
fatalerror( temptext );
|
||||
break;
|
||||
fread(tzHeader, sizeof(char), 4, pObjfile);
|
||||
tzHeader[4] = 0;
|
||||
if (strncmp(tzHeader, "RGB", 3) == 0) {
|
||||
switch (tzHeader[3]) {
|
||||
case '0':
|
||||
obj_ReadRGB0(pObjfile);
|
||||
break;
|
||||
case '1':
|
||||
case '2': // V2 is really the same but the are new patch types
|
||||
obj_ReadRGB1(pObjfile);
|
||||
break;
|
||||
default:
|
||||
sprintf(temptext, "'%s' is an unsupported version\n",
|
||||
tzObjectfile);
|
||||
fatalerror(temptext);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
sprintf(temptext, "'%s' is not a valid object\n", tzObjectfile);
|
||||
fatalerror(temptext);
|
||||
}
|
||||
}
|
||||
|
||||
void obj_Readfile(char *tzObjectfile)
|
||||
{
|
||||
FILE *pObjfile;
|
||||
|
||||
if (options & OPT_SMART_C_LINK)
|
||||
oReadLib = 1;
|
||||
else
|
||||
{
|
||||
sprintf( temptext, "'%s' is not a valid object\n", tzObjectfile );
|
||||
fatalerror( temptext );
|
||||
oReadLib = 0;
|
||||
|
||||
if (pObjfile = fopen(tzObjectfile, "rb")) {
|
||||
obj_ReadOpenFile(pObjfile, tzObjectfile);
|
||||
fclose(pObjfile);
|
||||
} else {
|
||||
sprintf(temptext, "Unable to open '%s'\n", tzObjectfile);
|
||||
fatalerror(temptext);
|
||||
}
|
||||
|
||||
oReadLib = 0;
|
||||
}
|
||||
|
||||
SLONG file_Length(FILE * f)
|
||||
{
|
||||
ULONG r, p;
|
||||
|
||||
p = ftell(f);
|
||||
fseek(f, 0, SEEK_END);
|
||||
r = ftell(f);
|
||||
fseek(f, p, SEEK_SET);
|
||||
|
||||
return (r);
|
||||
}
|
||||
|
||||
void lib_ReadXLB0(FILE * f)
|
||||
{
|
||||
SLONG size;
|
||||
|
||||
size = file_Length(f) - 4;
|
||||
while (size) {
|
||||
char name[256];
|
||||
|
||||
size -= readasciiz(name, f);
|
||||
readword(f);
|
||||
size -= 2;
|
||||
readword(f);
|
||||
size -= 2;
|
||||
size -= readlong(f);
|
||||
size -= 4;
|
||||
obj_ReadOpenFile(f, name);
|
||||
}
|
||||
}
|
||||
|
||||
void obj_Readfile( char *tzObjectfile )
|
||||
void lib_Readfile(char *tzLibfile)
|
||||
{
|
||||
FILE *pObjfile;
|
||||
FILE *pObjfile;
|
||||
|
||||
if( options&OPT_SMART_C_LINK )
|
||||
oReadLib=1;
|
||||
else
|
||||
oReadLib=0;
|
||||
oReadLib = 1;
|
||||
|
||||
if( pObjfile=fopen(tzObjectfile,"rb") )
|
||||
{
|
||||
obj_ReadOpenFile( pObjfile, tzObjectfile );
|
||||
fclose( pObjfile );
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( temptext, "Unable to open '%s'\n", tzObjectfile );
|
||||
fatalerror( temptext );
|
||||
}
|
||||
if (pObjfile = fopen(tzLibfile, "rb")) {
|
||||
char tzHeader[5];
|
||||
|
||||
oReadLib=0;
|
||||
}
|
||||
|
||||
SLONG file_Length( FILE *f )
|
||||
{
|
||||
ULONG r,
|
||||
p;
|
||||
|
||||
p=ftell( f );
|
||||
fseek( f, 0, SEEK_END );
|
||||
r=ftell( f );
|
||||
fseek( f, p, SEEK_SET );
|
||||
|
||||
return( r );
|
||||
}
|
||||
|
||||
void lib_ReadXLB0( FILE *f )
|
||||
{
|
||||
SLONG size;
|
||||
|
||||
size=file_Length( f )-4;
|
||||
while( size )
|
||||
{
|
||||
char name[256];
|
||||
|
||||
size-=readasciiz( name, f );
|
||||
readword( f ); size-=2;
|
||||
readword( f ); size-=2;
|
||||
size-=readlong( f ); size-=4;
|
||||
obj_ReadOpenFile( f, name );
|
||||
}
|
||||
}
|
||||
|
||||
void lib_Readfile( char *tzLibfile )
|
||||
{
|
||||
FILE *pObjfile;
|
||||
|
||||
oReadLib=1;
|
||||
|
||||
if( pObjfile=fopen(tzLibfile,"rb") )
|
||||
{
|
||||
char tzHeader[5];
|
||||
|
||||
fread( tzHeader, sizeof(char), 4, pObjfile );
|
||||
tzHeader[4]=0;
|
||||
if( strcmp(tzHeader,"XLB0")==0 )
|
||||
lib_ReadXLB0( pObjfile );
|
||||
else
|
||||
{
|
||||
sprintf( temptext, "'%s' is an invalid library\n", tzLibfile );
|
||||
fatalerror( temptext );
|
||||
fread(tzHeader, sizeof(char), 4, pObjfile);
|
||||
tzHeader[4] = 0;
|
||||
if (strcmp(tzHeader, "XLB0") == 0)
|
||||
lib_ReadXLB0(pObjfile);
|
||||
else {
|
||||
sprintf(temptext, "'%s' is an invalid library\n",
|
||||
tzLibfile);
|
||||
fatalerror(temptext);
|
||||
}
|
||||
fclose( pObjfile );
|
||||
fclose(pObjfile);
|
||||
} else {
|
||||
sprintf(temptext, "Unable to open '%s'\n", tzLibfile);
|
||||
fatalerror(temptext);
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf( temptext, "Unable to open '%s'\n", tzLibfile );
|
||||
fatalerror( temptext );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,216 +7,192 @@
|
||||
#include "main.h"
|
||||
#include "assign.h"
|
||||
|
||||
char tzOutname[_MAX_PATH];
|
||||
BBOOL oOutput=0;
|
||||
char tzOutname[_MAX_PATH];
|
||||
BBOOL oOutput = 0;
|
||||
|
||||
void writehome( FILE *f )
|
||||
void writehome(FILE * f)
|
||||
{
|
||||
struct sSection *pSect;
|
||||
UBYTE *mem;
|
||||
UBYTE *mem;
|
||||
|
||||
if( mem=(UBYTE *)malloc(MaxAvail[BANK_HOME]) )
|
||||
{
|
||||
if( fillchar!=-1 )
|
||||
{
|
||||
memset( mem, fillchar, MaxAvail[BANK_HOME] );
|
||||
if (mem = (UBYTE *) malloc(MaxAvail[BANK_HOME])) {
|
||||
if (fillchar != -1) {
|
||||
memset(mem, fillchar, MaxAvail[BANK_HOME]);
|
||||
}
|
||||
MapfileInitBank( 0 );
|
||||
MapfileInitBank(0);
|
||||
|
||||
pSect=pSections;
|
||||
while( pSect )
|
||||
{
|
||||
if( pSect->Type==SECT_HOME )
|
||||
{
|
||||
memcpy( mem+pSect->nOrg, pSect->pData, pSect->nByteSize );
|
||||
MapfileWriteSection( pSect );
|
||||
pSect = pSections;
|
||||
while (pSect) {
|
||||
if (pSect->Type == SECT_HOME) {
|
||||
memcpy(mem + pSect->nOrg, pSect->pData,
|
||||
pSect->nByteSize);
|
||||
MapfileWriteSection(pSect);
|
||||
}
|
||||
pSect=pSect->pNext;
|
||||
pSect = pSect->pNext;
|
||||
}
|
||||
|
||||
MapfileCloseBank( area_Avail(0) );
|
||||
MapfileCloseBank(area_Avail(0));
|
||||
|
||||
fwrite( mem, 1, MaxAvail[BANK_HOME], f );
|
||||
free( mem );
|
||||
fwrite(mem, 1, MaxAvail[BANK_HOME], f);
|
||||
free(mem);
|
||||
}
|
||||
}
|
||||
|
||||
void writebank( FILE *f, SLONG bank )
|
||||
void writebank(FILE * f, SLONG bank)
|
||||
{
|
||||
struct sSection *pSect;
|
||||
UBYTE *mem;
|
||||
UBYTE *mem;
|
||||
|
||||
if( mem=(UBYTE *)malloc(MaxAvail[bank]) )
|
||||
{
|
||||
if( fillchar!=-1 )
|
||||
{
|
||||
memset( mem, fillchar, MaxAvail[bank] );
|
||||
if (mem = (UBYTE *) malloc(MaxAvail[bank])) {
|
||||
if (fillchar != -1) {
|
||||
memset(mem, fillchar, MaxAvail[bank]);
|
||||
}
|
||||
|
||||
MapfileInitBank( 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 = 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;
|
||||
pSect = pSect->pNext;
|
||||
}
|
||||
|
||||
MapfileCloseBank( area_Avail(bank) );
|
||||
MapfileCloseBank(area_Avail(bank));
|
||||
|
||||
fwrite( mem, 1, MaxAvail[bank], f );
|
||||
free( mem );
|
||||
fwrite(mem, 1, MaxAvail[bank], f);
|
||||
free(mem);
|
||||
}
|
||||
}
|
||||
|
||||
void out_Setname( char *tzOutputfile )
|
||||
void out_Setname(char *tzOutputfile)
|
||||
{
|
||||
strcpy( tzOutname, tzOutputfile );
|
||||
oOutput=1;
|
||||
strcpy(tzOutname, tzOutputfile);
|
||||
oOutput = 1;
|
||||
}
|
||||
|
||||
void GBROM_Output( void )
|
||||
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 );
|
||||
if (f = fopen(tzOutname, "wb")) {
|
||||
writehome(f);
|
||||
for (i = 1; i <= MaxBankUsed; i += 1)
|
||||
writebank(f, i);
|
||||
|
||||
fclose( f );
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
for( i=256; i<MAXBANKS; i+=1 )
|
||||
{
|
||||
struct sSection *pSect;
|
||||
MapfileInitBank( i );
|
||||
pSect=pSections;
|
||||
while( pSect )
|
||||
{
|
||||
if( pSect->nBank==i )
|
||||
{
|
||||
MapfileWriteSection( pSect );
|
||||
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;
|
||||
pSect = pSect->pNext;
|
||||
}
|
||||
MapfileCloseBank( area_Avail(i) );
|
||||
MapfileCloseBank(area_Avail(i));
|
||||
}
|
||||
}
|
||||
|
||||
void PSION2_Output( void )
|
||||
void PSION2_Output(void)
|
||||
{
|
||||
FILE *f;
|
||||
|
||||
if( f=fopen(tzOutname,"wb") )
|
||||
{
|
||||
if (f = fopen(tzOutname, "wb")) {
|
||||
struct sSection *pSect;
|
||||
UBYTE *mem;
|
||||
ULONG size=MaxAvail[0]-area_Avail(0);
|
||||
ULONG relocpatches;
|
||||
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 );
|
||||
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 );
|
||||
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 );
|
||||
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);
|
||||
}
|
||||
else
|
||||
{
|
||||
memset( mem+pSect->nOrg, 0, pSect->nByteSize );
|
||||
}
|
||||
pSect=pSect->pNext;
|
||||
pSect = pSect->pNext;
|
||||
}
|
||||
|
||||
MapfileCloseBank( area_Avail(0) );
|
||||
MapfileCloseBank(area_Avail(0));
|
||||
|
||||
fwrite( mem, 1, MaxAvail[0]-area_Avail(0), f );
|
||||
free( mem );
|
||||
fwrite(mem, 1, MaxAvail[0] - area_Avail(0), f);
|
||||
free(mem);
|
||||
}
|
||||
|
||||
relocpatches=0;
|
||||
pSect=pSections;
|
||||
while( pSect )
|
||||
{
|
||||
struct sPatch *pPatch;
|
||||
relocpatches = 0;
|
||||
pSect = pSections;
|
||||
while (pSect) {
|
||||
struct sPatch *pPatch;
|
||||
|
||||
pPatch=pSect->pPatches;
|
||||
pPatch = pSect->pPatches;
|
||||
|
||||
while( pPatch )
|
||||
{
|
||||
if( pPatch->oRelocPatch )
|
||||
{
|
||||
relocpatches+=1;
|
||||
while (pPatch) {
|
||||
if (pPatch->oRelocPatch) {
|
||||
relocpatches += 1;
|
||||
}
|
||||
pPatch=pPatch->pNext;
|
||||
pPatch = pPatch->pNext;
|
||||
}
|
||||
pSect=pSect->pNext;
|
||||
pSect = pSect->pNext;
|
||||
}
|
||||
|
||||
fputc( relocpatches>>24, f );
|
||||
fputc( relocpatches>>16, f );
|
||||
fputc( relocpatches>>8, f );
|
||||
fputc( relocpatches, f );
|
||||
fputc(relocpatches >> 24, f);
|
||||
fputc(relocpatches >> 16, f);
|
||||
fputc(relocpatches >> 8, f);
|
||||
fputc(relocpatches, f);
|
||||
|
||||
pSect=pSections;
|
||||
while( pSect )
|
||||
{
|
||||
struct sPatch *pPatch;
|
||||
pSect = pSections;
|
||||
while (pSect) {
|
||||
struct sPatch *pPatch;
|
||||
|
||||
pPatch=pSect->pPatches;
|
||||
pPatch = pSect->pPatches;
|
||||
|
||||
while( pPatch )
|
||||
{
|
||||
if( pPatch->oRelocPatch )
|
||||
{
|
||||
ULONG address;
|
||||
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 );
|
||||
address = pPatch->nOffset + pSect->nOrg;
|
||||
fputc(address >> 24, f);
|
||||
fputc(address >> 16, f);
|
||||
fputc(address >> 8, f);
|
||||
fputc(address, f);
|
||||
}
|
||||
pPatch=pPatch->pNext;
|
||||
pPatch = pPatch->pNext;
|
||||
}
|
||||
pSect=pSect->pNext;
|
||||
pSect = pSect->pNext;
|
||||
}
|
||||
|
||||
|
||||
|
||||
fclose( f );
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
void Output( void )
|
||||
void Output(void)
|
||||
{
|
||||
if( oOutput )
|
||||
{
|
||||
switch( outputtype )
|
||||
{
|
||||
case OUTPUT_GBROM:
|
||||
GBROM_Output();
|
||||
break;
|
||||
case OUTPUT_PSION2:
|
||||
PSION2_Output();
|
||||
break;
|
||||
if (oOutput) {
|
||||
switch (outputtype) {
|
||||
case OUTPUT_GBROM:
|
||||
GBROM_Output();
|
||||
break;
|
||||
case OUTPUT_PSION2:
|
||||
PSION2_Output();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
530
src/link/patch.c
530
src/link/patch.c
@@ -6,295 +6,303 @@
|
||||
#include "main.h"
|
||||
|
||||
struct sSection *pCurrentSection;
|
||||
SLONG rpnstack[256];
|
||||
SLONG rpnp;
|
||||
SLONG nPC;
|
||||
SLONG rpnstack[256];
|
||||
SLONG rpnp;
|
||||
SLONG nPC;
|
||||
|
||||
void rpnpush( SLONG i )
|
||||
void rpnpush(SLONG i)
|
||||
{
|
||||
rpnstack[rpnp++]=i;
|
||||
rpnstack[rpnp++] = i;
|
||||
}
|
||||
|
||||
SLONG rpnpop( void )
|
||||
SLONG rpnpop(void)
|
||||
{
|
||||
return( rpnstack[--rpnp] );
|
||||
return (rpnstack[--rpnp]);
|
||||
}
|
||||
|
||||
SLONG getsymvalue( SLONG symid )
|
||||
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++ )
|
||||
switch (pCurrentSection->tSymbols[symid]->Type) {
|
||||
case SYM_IMPORT:
|
||||
return (sym_GetValue(pCurrentSection->tSymbols[symid]->pzName));
|
||||
break;
|
||||
case SYM_EXPORT:
|
||||
case SYM_LOCAL:
|
||||
{
|
||||
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;
|
||||
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);
|
||||
}
|
||||
|
||||
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 );
|
||||
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;
|
||||
size -= 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return( rpnpop() );
|
||||
return (rpnpop());
|
||||
}
|
||||
|
||||
void Patch( void )
|
||||
void Patch(void)
|
||||
{
|
||||
struct sSection *pSect;
|
||||
|
||||
pSect=pSections;
|
||||
while( pSect )
|
||||
{
|
||||
pSect = pSections;
|
||||
while (pSect) {
|
||||
struct sPatch *pPatch;
|
||||
|
||||
pCurrentSection=pSect;
|
||||
pPatch=pSect->pPatches;
|
||||
while( 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;
|
||||
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 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;
|
||||
} 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;
|
||||
pPatch = pPatch->pNext;
|
||||
}
|
||||
|
||||
pSect=pSect->pNext;
|
||||
pSect = pSect->pNext;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,119 +7,101 @@
|
||||
|
||||
#define HASHSIZE 73
|
||||
|
||||
struct ISymbol
|
||||
{
|
||||
char *pzName;
|
||||
SLONG nValue;
|
||||
SLONG nBank; // -1=const
|
||||
struct ISymbol *pNext;
|
||||
struct ISymbol {
|
||||
char *pzName;
|
||||
SLONG nValue;
|
||||
SLONG nBank; // -1=const
|
||||
struct ISymbol *pNext;
|
||||
};
|
||||
|
||||
struct ISymbol *tHash[HASHSIZE];
|
||||
|
||||
SLONG calchash( char *s )
|
||||
SLONG calchash(char *s)
|
||||
{
|
||||
SLONG r=0;
|
||||
while( *s )
|
||||
r+=*s++;
|
||||
SLONG r = 0;
|
||||
while (*s)
|
||||
r += *s++;
|
||||
|
||||
return( r%HASHSIZE );
|
||||
return (r % HASHSIZE);
|
||||
}
|
||||
|
||||
void sym_Init( void )
|
||||
void sym_Init(void)
|
||||
{
|
||||
SLONG i;
|
||||
for( i=0; i<HASHSIZE; i+=1 )
|
||||
tHash[i]=NULL;
|
||||
SLONG i;
|
||||
for (i = 0; i < HASHSIZE; i += 1)
|
||||
tHash[i] = NULL;
|
||||
}
|
||||
|
||||
SLONG sym_GetValue( char *tzName )
|
||||
SLONG sym_GetValue(char *tzName)
|
||||
{
|
||||
if( strcmp(tzName,"@")==0 )
|
||||
{
|
||||
return( nPC );
|
||||
}
|
||||
else
|
||||
{
|
||||
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 );
|
||||
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 );
|
||||
sprintf(temptext, "Unknown symbol '%s'", tzName);
|
||||
fatalerror(temptext);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
SLONG sym_GetBank( char *tzName )
|
||||
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 );
|
||||
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 );
|
||||
sprintf(temptext, "Unknown symbol '%s'");
|
||||
fatalerror(temptext);
|
||||
return (0);
|
||||
}
|
||||
|
||||
void sym_CreateSymbol( char *tzName, SLONG nValue, SBYTE nBank )
|
||||
void sym_CreateSymbol(char *tzName, SLONG nValue, SBYTE nBank)
|
||||
{
|
||||
if( strcmp(tzName,"@")==0 )
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strcmp(tzName, "@") == 0) {
|
||||
} else {
|
||||
struct ISymbol **ppSym;
|
||||
|
||||
ppSym=&(tHash[calchash(tzName)]);
|
||||
ppSym = &(tHash[calchash(tzName)]);
|
||||
|
||||
while( *ppSym )
|
||||
{
|
||||
if( strcmp(tzName,(*ppSym)->pzName) )
|
||||
{
|
||||
ppSym=&((*ppSym)->pNext);
|
||||
}
|
||||
else
|
||||
{
|
||||
if( nBank==-1 )
|
||||
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 );
|
||||
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;
|
||||
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