mirror of
https://github.com/gbdev/rgbds.git
synced 2025-11-21 18:52: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:
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user