summary |
shortlog |
log |
commit | commitdiff |
tree
raw |
patch |
inline | side by side (from parent 1:
bcd800a)
For some reason, there was code in several places that marked fixups/symbols
as belonging to a RISC section when it was clearly not the case. As a result,
it caused serious problems by reversing words in 68K sections just because a
symbol had been seen in a MOVEI # statement in a RISC section. Probably not
the last nasty surprise in this pile of spaghetti. :-/
19 files changed:
+bugs4/
+bugs5/
+*.zip
+features/
-// printf("`%s' ;\n", (*p.sy)->sname);
printf("`%s' ;", (*p.sy)->sname);
p.sy++;
}
printf("`%s' ;", (*p.sy)->sname);
p.sy++;
}
// Check that we are in a RISC section
if (!rgpu && !rdsp)
// Check that we are in a RISC section
if (!rgpu && !rdsp)
- {
- error(".equrundef/.regundef must be defined in .gpu/.dsp section");
- return ERROR;
- }
+ return error(".equrundef/.regundef must be defined in .gpu/.dsp section");
// Check we are dealing with a symbol
if (*tok != SYMBOL)
// Check we are dealing with a symbol
if (*tok != SYMBOL)
- {
-// error(syntax_error);
- error("syntax error; expected symbol");
- return ERROR;
- }
+ return error("syntax error; expected symbol");
// Lookup and undef if equated register
// Lookup and undef if equated register
-// regname = lookup((char *)tok[1], LABEL, 0);
regname = lookup(string[tok[1]], LABEL, 0);
if (regname && (regname->sattre & EQUATEDREG))
regname = lookup(string[tok[1]], LABEL, 0);
if (regname && (regname->sattre & EQUATEDREG))
{
if ((scattr & SBSS) == 0)
{
{
if ((scattr & SBSS) == 0)
{
chcheck(val);
for(i=0; i<val; i++)
chcheck(val);
for(i=0; i<val; i++)
//
int symlist(int(* func)())
{
//
int symlist(int(* func)())
{
- char * em = "symbol list syntax";
+ const char * em = "symbol list syntax";
for(;;)
{
if (*tok != SYMBOL)
return error(em);
for(;;)
{
if (*tok != SYMBOL)
return error(em);
-#if 0
- if ((*func)(tok[1]) != OK)
-#else
if ((*func)(string[tok[1]]) != OK)
if ((*func)(string[tok[1]]) != OK)
if (*tok != ',')
return error(em);
if (*tok != ',')
return error(em);
//
int globl1(char * p)
{
//
int globl1(char * p)
{
if (*p == '.')
return error("cannot .globl local symbol");
if (*p == '.')
return error("cannot .globl local symbol");
sy = NewSymbol(p, LABEL, 0);
sy->svalue = 0;
sy->sattr = GLOBAL;
sy = NewSymbol(p, LABEL, 0);
sy->svalue = 0;
sy->sattr = GLOBAL;
+//printf("glob1: Making global symbol: attr=%04X, eattr=%08X, %s\n", sy->sattr, sy->sattre, sy->sname);
}
else
sy->sattr |= GLOBAL;
}
else
sy->sattr |= GLOBAL;
if (*tok == EOL)
eval = 0;
else if (abs_expr(&eval) != OK)
return 0;
if (*tok == EOL)
eval = 0;
else if (abs_expr(&eval) != OK)
return 0;
- savsect();
- switchsect(TEXT);
+ SaveSection();
+ SwitchSection(TEXT);
- savsect();
- switchsect(DATA);
+ SaveSection();
+ SwitchSection(DATA);
- savsect();
- switchsect(BSS);
+ SaveSection();
+ SwitchSection(BSS);
case SIZB:
if (!defined)
{
case SIZB:
if (!defined)
{
- fixup(FU_BYTE | FU_SEXT, sloc, exprbuf);
+ AddFixup(FU_BYTE | FU_SEXT, sloc, exprbuf);
case SIZN:
if (!defined)
{
case SIZN:
if (!defined)
{
- fixup(FU_WORD | FU_SEXT, sloc, exprbuf);
+ AddFixup(FU_WORD | FU_SEXT, sloc, exprbuf);
if (!defined)
{
if (movei)
if (!defined)
{
if (movei)
- fixup(FU_LONG | FU_MOVEI, sloc, exprbuf);
+ AddFixup(FU_LONG | FU_MOVEI, sloc, exprbuf);
- fixup(FU_LONG, sloc, exprbuf);
+ AddFixup(FU_LONG, sloc, exprbuf);
case SIZB:
if (!defined)
{
case SIZB:
if (!defined)
{
- fixup(FU_BYTE | FU_SEXT, sloc, exprbuf);
+ AddFixup(FU_BYTE | FU_SEXT, sloc, exprbuf);
case SIZN:
if (!defined)
{
case SIZN:
if (!defined)
{
- fixup(FU_WORD | FU_SEXT, sloc, exprbuf);
+ AddFixup(FU_WORD | FU_SEXT, sloc, exprbuf);
case SIZL:
if (!defined)
{
case SIZL:
if (!defined)
{
- fixup(FU_LONG, sloc, exprbuf);
+ AddFixup(FU_LONG, sloc, exprbuf);
// Switching from gpu/dsp sections should reset any ORG'd Address
orgactive = 0;
orgwarning = 0;
// Switching from gpu/dsp sections should reset any ORG'd Address
orgactive = 0;
orgwarning = 0;
- savsect();
- switchsect(TEXT);
+ SaveSection();
+ SwitchSection(TEXT);
// Put symbol in "order of definition" list
if (!(symbol->sattr & SDECLLIST))
// Put symbol in "order of definition" list
if (!(symbol->sattr & SDECLLIST))
+ AddToSymbolOrderList(symbol);
symbol->sattr |= (ABS | DEFINED | EQUATED);
symbol->svalue = eval;
symbol->sattr |= (ABS | DEFINED | EQUATED);
symbol->svalue = eval;
// Put symbol in "order of definition" list
if (!(symbol->sattr & SDECLLIST))
// Put symbol in "order of definition" list
if (!(symbol->sattr & SDECLLIST))
+ AddToSymbolOrderList(symbol);
- case DREG: // "Do nothing" - they're in the opword
+ // "Do nothing" - they're in the opword
+ case DREG:
case AREG:
case AIND:
case APOSTINC:
case AREG:
case AIND:
case APOSTINC:
case AM_CCR:
case AM_SR:
case AM_NONE:
case AM_CCR:
case AM_SR:
case AM_NONE:
- break; // This is a performance hit, though
- case ADISP: // expr(An)
+ // This is a performance hit, though
+ break;
+ case ADISP:
+ // expr(An)
if (tdb)
rmark(cursect, sloc, tdb, MWORD, NULL);
if (tdb)
rmark(cursect, sloc, tdb, MWORD, NULL);
- { // Arrange for fixup later on
- fixup(FU_WORD|FU_SEXT, sloc, aNexpr);
+ {
+ // Arrange for fixup later on
+ AddFixup(FU_WORD|FU_SEXT, sloc, aNexpr);
D_word(0);
}
break;
case PCDISP:
if (w)
D_word(0);
}
break;
case PCDISP:
if (w)
if ((aNexattr & TDB) == cursect)
v -= (VALUE)sloc;
else if ((aNexattr & TDB) != ABS)
if ((aNexattr & TDB) == cursect)
v -= (VALUE)sloc;
else if ((aNexattr & TDB) != ABS)
- { // Arrange for fixup later on
- fixup(FU_WORD|FU_SEXT|FU_PCREL, sloc, aNexpr);
+ {
+ // Arrange for fixup later on
+ AddFixup(FU_WORD|FU_SEXT|FU_PCREL, sloc, aNexpr);
D_word(0);
}
break;
case AINDEXED:
D_word(0);
}
break;
case AINDEXED:
- w = (WORD)((aNixreg << 12) | aNixsiz); // Compute ixreg and size+scale
+ // Compute ixreg and size+scale
+ w = (WORD)((aNixreg << 12) | aNixsiz);
+ {
+ // Deposit a byte...
- return error(abs_error); // Can't mark bytes
+ // Can't mark bytes
+ return error(abs_error);
if (v + 0x80 >= 0x180)
return error(range_error);
if (v + 0x80 >= 0x180)
return error(range_error);
- { // Fixup the byte later
- fixup(FU_BYTE|FU_SEXT, sloc+1, aNexpr);
+ {
+ // Fixup the byte later
+ AddFixup(FU_BYTE|FU_SEXT, sloc+1, aNexpr);
D_word(w);
}
break;
case PCINDEXED:
D_word(w);
}
break;
case PCINDEXED:
- w = (WORD)((aNixreg << 12) | aNixsiz); // Compute ixreg and size+scale
+ // Compute ixreg and size+scale
+ w = (WORD)((aNixreg << 12) | aNixsiz);
+ {
+ // Deposit a byte...
if ((aNexattr & TDB) == cursect)
v -= (VALUE)sloc;
else if ((aNexattr & TDB) != ABS)
if ((aNexattr & TDB) == cursect)
v -= (VALUE)sloc;
else if ((aNexattr & TDB) != ABS)
- { // Fixup the byte later
- fixup(FU_WBYTE|FU_SEXT|FU_PCREL, sloc, aNexpr);
+ {
+ // Fixup the byte later
+ AddFixup(FU_WBYTE|FU_SEXT|FU_PCREL, sloc, aNexpr);
- fixup(FU_BYTE|FU_SEXT, sloc+1, aNexpr);
+ AddFixup(FU_BYTE|FU_SEXT, sloc+1, aNexpr);
- fixup(FU_WORD|FU_SEXT, sloc, aNexpr);
+ AddFixup(FU_WORD|FU_SEXT, sloc, aNexpr);
- fixup(FU_LONG, sloc, aNexpr);
+ AddFixup(FU_LONG, sloc, aNexpr);
D_long(0);
}
break;
default:
D_long(0);
}
break;
default:
- interror(1); // IMMED size problem
+ // IMMED size problem
+ interror(1);
- fixup(FU_WORD|FU_SEXT, sloc, aNexpr);
+ AddFixup(FU_WORD|FU_SEXT, sloc, aNexpr);
- fixup(FU_LONG, sloc, aNexpr);
+ AddFixup(FU_LONG, sloc, aNexpr);
case PCMPRE:
return error("unsupported 68020 addressing mode");
default:
case PCMPRE:
return error("unsupported 68020 addressing mode");
default:
- interror(3); // Bad addressing mode in ea gen
+ // Bad addressing mode in ea gen
+ interror(3);
#undef aNexpr
#undef aNixreg
#undef aNixsiz
#undef aNexpr
#undef aNixreg
#undef aNixsiz
#define DEF_KW // Declare keyword values
#include "kwtab.h" // Incl generated keyword tables & defs
#define DEF_KW // Declare keyword values
#include "kwtab.h" // Incl generated keyword tables & defs
-static char tokenClass[128]; // Generated table of token classes
+static char tokenClass[128]; // Generated table of token classes
static VALUE evstk[EVSTACKSIZE]; // Evaluator value stack
static WORD evattr[EVSTACKSIZE]; // Evaluator attribute stack
static VALUE evstk[EVSTACKSIZE]; // Evaluator value stack
static WORD evattr[EVSTACKSIZE]; // Evaluator attribute stack
p = string[tok[1]];
j = (*p == '.' ? curenv : 0);
symbol = lookup(p, LABEL, j);
p = string[tok[1]];
j = (*p == '.' ? curenv : 0);
symbol = lookup(p, LABEL, j);
+#if 0
+printf("eval: Looking up symbol [=%08X]\n", symbol);
+if (symbol)
+ printf(" attr=%04X, attre=%08X, val=%i, name=%s\n", symbol->sattr, symbol->sattre, symbol->svalue, symbol->sname);
+#endif
if (symbol == NULL)
symbol = NewSymbol(p, LABEL, j);
if (symbol == NULL)
symbol = NewSymbol(p, LABEL, j);
#include "rmac.h"
// Tunable definitions
#include "rmac.h"
// Tunable definitions
-#define STKSIZE 64 // Size of expression stacks
-#define EVSTACKSIZE 64 // Expression evaluator stack size
+#define STKSIZE 64 // Size of expression stacks
+#define EVSTACKSIZE 64 // Expression evaluator stack size
// Token classes in order of precedence
// Token classes in order of precedence
-#define END 0 // End/beginning of input
-#define ID 1 // Symbol or constant
-#define OPAR 2 // (
-#define CPAR 3 // )
-#define SUNARY 4 // Special unary (^^defined, etc.)
-#define UNARY 5 // Unary class: ! ~ -
-#define MULT 6 // Multiplicative class: * / %
-#define ADD 7 // Additive class: + -
-#define SHIFT 8 // Shift class: << >>
-#define REL 9 // Relational class: <= >= < > <> = !=
-#define AND 10 // Bitwise and: &
-#define XOR 11 // Bitwise xor: ^
-#define OR 12 // Bitwise or: |
+#define END 0 // End/beginning of input
+#define ID 1 // Symbol or constant
+#define OPAR 2 // (
+#define CPAR 3 // )
+#define SUNARY 4 // Special unary (^^defined, etc.)
+#define UNARY 5 // Unary class: ! ~ -
+#define MULT 6 // Multiplicative class: * / %
+#define ADD 7 // Additive class: + -
+#define SHIFT 8 // Shift class: << >>
+#define REL 9 // Relational class: <= >= < > <> = !=
+#define AND 10 // Bitwise and: &
+#define XOR 11 // Bitwise xor: ^
+#define OR 12 // Bitwise or: |
// Prototypes
void InitExpression(void);
// Prototypes
void InitExpression(void);
// deposited with dcb. The fix (kludge) is an extra variable which records
// the fact that a 'ds.x' directive generated all the data, and it
// shouldn't be listed
// deposited with dcb. The fix (kludge) is an extra variable which records
// the fact that a 'ds.x' directive generated all the data, and it
// shouldn't be listed
- savsect(); // Update section variables
+ SaveSection(); // Update section variables
if (lcursect == cursect && (sect[lcursect].scattr & SBSS) == 0
&& lsloc != sloc && just_bss == 0)
if (lcursect == cursect && (sect[lcursect].scattr & SBSS) == 0
&& lsloc != sloc && just_bss == 0)
- fixup(FU_QUICK, sloc, a0expr);
+ AddFixup(FU_QUICK, sloc, a0expr);
- fixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
+ AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
// Arrange for future fixup
if (!(a0exattr & DEFINED))
{
// Arrange for future fixup
if (!(a0exattr & DEFINED))
{
- fixup(FU_BYTE | FU_SEXT, sloc + 1, a0expr);
+ AddFixup(FU_BYTE | FU_SEXT, sloc + 1, a0expr);
a0exval = 0;
}
else if (a0exval + 0x100 >= 0x200)
a0exval = 0;
}
else if (a0exval + 0x100 >= 0x200)
- fixup(FU_BBRA | FU_PCREL | FU_SEXT, sloc, a0expr);
+ AddFixup(FU_BBRA | FU_PCREL | FU_SEXT, sloc, a0expr);
D_word(inst);
return 0;
}
D_word(inst);
return 0;
}
- fixup(FU_WORD | FU_PCREL | FU_LBRA | FU_ISBRA, sloc, a0expr);
+ AddFixup(FU_WORD | FU_PCREL | FU_LBRA | FU_ISBRA, sloc, a0expr);
- fixup(FU_QUICK, sloc, a0expr);
+ AddFixup(FU_QUICK, sloc, a0expr);
{
#ifdef DEBUG_IMAGE_MARKING
printf("rmark: from=%i, loc=$%X, to=$%X, size=$%x, symbol=$%X\n", from, loc, to, size, symbol);
{
#ifdef DEBUG_IMAGE_MARKING
printf("rmark: from=%i, loc=$%X, to=$%X, size=$%x, symbol=$%X\n", from, loc, to, size, symbol);
+if (symbol)
+ printf(" symbol->stype=$%02X, sattr=$%04X, sattre=$%08X, svalue=%i, sname=%s\n", symbol->stype, symbol->sattr, symbol->sattre, symbol->svalue, symbol->sname);
if ((mcalloc - mcused) < MIN_MARK_MEM)
amark();
if ((mcalloc - mcused) < MIN_MARK_MEM)
amark();
else
rflag = 0x00000040; // Absolute fixup
else
rflag = 0x00000040; // Absolute fixup
+// This flag tells the linker to WORD swap the LONG when doing the fixup.
+//{
+//printf("bsdmarkimg: ORing $01 to rflag (MMOVEI) [symbol=%s]...\n", symbol->sname);
}
// Compute mark position in relocation information;
}
// Compute mark position in relocation information;
rflag |= 0x00000010; // Set external reloc flag bit
rflag |= (symbol->senv << 8); // Put symbol index in flags
rflag |= 0x00000010; // Set external reloc flag bit
rflag |= (symbol->senv << 8); // Put symbol index in flags
+// Looks like this is completely unnecessary (considering it does the wrong thing!)
+#if 0
if (symbol->sattre & RISCSYM)
if (symbol->sattre & RISCSYM)
+{
+printf("bsdmarkimg: ORing $01 to rflag (RISCSYM) [symbol=%s]...\n", symbol->sname);
return ERROR;
if (*tok == DOTW)
return ERROR;
if (*tok == DOTW)
tok++;
AMn = ABSW;
goto AnOK;
}
else if (*tok != '(')
tok++;
AMn = ABSW;
goto AnOK;
}
else if (*tok != '(')
- // Defined, absolute values from $FFFF8000..$00007FFF get optimized to absolute short
+ // Defined, absolute values from $FFFF8000..$00007FFF get optimized
+ // to absolute short
if ((AnEXATTR & (TDB|DEFINED)) == DEFINED && (AnEXVAL + 0x8000) < 0x10000)
AMn = ABSW;
if ((AnEXATTR & (TDB|DEFINED)) == DEFINED && (AnEXVAL + 0x8000) < 0x10000)
AMn = ABSW;
SYM * sy, * sy2; // Symbol (temp usage)
char * opname = NULL; // Name of dirctve/mnemonic/macro
int listflag; // 0: Don't call listeol()
SYM * sy, * sy2; // Symbol (temp usage)
char * opname = NULL; // Name of dirctve/mnemonic/macro
int listflag; // 0: Don't call listeol()
-// int as68mode = 0; // 1: Handle multiple labels
WORD rmask; // Register list, for REG
int registerbank; // RISC register bank
int riscreg; // RISC register
WORD rmask; // Register list, for REG
int registerbank; // RISC register bank
int riscreg; // RISC register
if (*tok == EOL) // Restart loop if end-of-line
goto loop;
if (*tok == EOL) // Restart loop if end-of-line
goto loop;
- // First token MUST be a symbol
+ // First token MUST be a symbol (Shamus: not sure why :-/)
error("syntax error; expected symbol");
goto loop;
}
error("syntax error; expected symbol");
goto loop;
}
if (j == ':' || j == DCOLON)
{
as68label:
if (j == ':' || j == DCOLON)
{
as68label:
-// label = (char *)tok[1]; // Get label name
label = string[tok[1]]; // Get label name
labtyp = tok[2]; // Get label type
tok += 3; // Go to next line token
label = string[tok[1]]; // Get label name
labtyp = tok[2]; // Get label type
tok += 3; // Go to next line token
- // Handle multiple labels; if there's another label, go process it,
- // and come back at `as68label' above.
- if (as68_flag)
+ // AS68 MODE:
+ // Looks like another label follows the previous one, so handle
+ // the previous one until there aren't any more
+ if (as68_flag && (*tok == SYMBOL && tok[2] == ':'))
-// as68mode = 0;
-
- // Looks like another label follows the previous one, so handle
- // the previous one
- if (*tok == SYMBOL && tok[2] == ':')
- {
-// as68mode = 1;
-// goto do_label;
- if (HandleLabel(label, labtyp) != 0)
- goto loop;
+ if (HandleLabel(label, labtyp) != 0)
+ goto loop;
// Next token MUST be a symbol
if (*tok++ != SYMBOL)
{
// Next token MUST be a symbol
if (*tok++ != SYMBOL)
{
error("syntax error; expected symbol");
goto loop;
}
error("syntax error; expected symbol");
goto loop;
}
-// This is the problem here: On 64-bit platforms, this cuts the native pointer
-// in half. We need to figure out how to fix this.
-//#warning "!!! Bad pointer !!!"
-#if 0
- opname = p = (char *)*tok++; // Store opcode name here
-#else
opname = p = string[*tok++];
opname = p = string[*tok++];
// Check to see if the SYMBOL is a keyword (a mnemonic or directive).
// On output, `state' will have one of the values:
// Check to see if the SYMBOL is a keyword (a mnemonic or directive).
// On output, `state' will have one of the values:
case MN_MACRO: // .macro --- macro definition
if (!disabled)
{
case MN_MACRO: // .macro --- macro definition
if (!disabled)
{
+ // Label on a macro definition is bad mojo... Warn the user
if (label != NULL)
warn(lab_ignored);
if (label != NULL)
warn(lab_ignored);
case MN_ENDM: // .endm --- same as .exitm
if (!disabled)
{
case MN_ENDM: // .endm --- same as .exitm
if (!disabled)
{
- // Label on a macro definition is bad mojo... Warn the user
if (label != NULL)
warn(lab_ignored);
if (label != NULL)
warn(lab_ignored);
case MN_REPT:
if (!disabled)
{
case MN_REPT:
if (!disabled)
{
-#if 0
- if (label != NULL)
- warn(lab_ignored);
-#else
// Handle labels on REPT directive lines...
if (label)
{
if (HandleLabel(label, labtyp) != 0)
goto loop;
}
// Handle labels on REPT directive lines...
if (label)
{
if (HandleLabel(label, labtyp) != 0)
goto loop;
}
if (equate != NULL)
{
// Pick global or local symbol enviroment
if (equate != NULL)
{
// Pick global or local symbol enviroment
-#if 0
- j = 0;
-
- if (*equate == '.')
- j = curenv;
-#else
j = (*equate == '.' ? curenv : 0);
j = (*equate == '.' ? curenv : 0);
sy = lookup(equate, LABEL, j);
if (sy == NULL)
sy = lookup(equate, LABEL, j);
if (sy == NULL)
// Put symbol in "order of definition" list
if (!(sy->sattr & SDECLLIST))
// Put symbol in "order of definition" list
if (!(sy->sattr & SDECLLIST))
+ AddToSymbolOrderList(sy);
// Parse value to equate symbol to;
// o .equr
// Parse value to equate symbol to;
// o .equr
// Check for register to equate to
if ((*tok >= KW_R0) && (*tok <= KW_R31))
{
// Check for register to equate to
if ((*tok >= KW_R0) && (*tok <= KW_R31))
{
- sy->sattre = EQUATEDREG | RISCSYM; // Mark as equated register
+// sy->sattre = EQUATEDREG | RISCSYM; // Mark as equated register
+ sy->sattre = EQUATEDREG; // Mark as equated register
riscreg = (*tok - KW_R0);
//is there any reason to do this, since we're putting this in svalue?
//i'm thinking, no. Let's test that out! :-D
riscreg = (*tok - KW_R0);
//is there any reason to do this, since we're putting this in svalue?
//i'm thinking, no. Let's test that out! :-D
// Do labels
if (label != NULL)
{
// Do labels
if (label != NULL)
{
-do_label:
-#if 0
- // Check for dot in front of label; means this is a local label if present
- j = (*label == '.' ? curenv : 0);
- sy = lookup(label, LABEL, j);
-
- if (sy == NULL)
- {
- sy = NewSymbol(label, LABEL, j);
- sy->sattr = 0;
- sy->sattre = RISCSYM;
- }
- else if (sy->sattr & DEFINED)
- {
- errors("multiply-defined label '%s'", label);
- goto loop;
- }
-
- // Put symbol in "order of definition" list
- if (!(sy->sattr & SDECLLIST))
- sym_decl(sy);
-
- if (orgactive)
- {
- sy->svalue = orgaddr;
- sy->sattr |= ABS | DEFINED | EQUATED;
- }
- else
- {
- sy->svalue = sloc;
- sy->sattr |= DEFINED | cursect;
- }
-
- lab_sym = sy;
-
- if (!j)
- curenv++;
-
- // Make label global
- if (labtyp == DCOLON)
- {
- if (j)
- {
- error(locgl_error);
- goto loop;
- }
-
- sy->sattr |= GLOBAL;
- }
-#else
// Non-zero == error occurred
if (HandleLabel(label, labtyp) != 0)
goto loop;
// Non-zero == error occurred
if (HandleLabel(label, labtyp) != 0)
goto loop;
-#endif
- // If we're in as68 mode, and there's another label, go back and handle it
-// if (as68_flag && as68mode)
-// goto as68label;
int HandleLabel(char * label, int labelType)
{
// Check for dot in front of label; means this is a local label if present
int HandleLabel(char * label, int labelType)
{
// Check for dot in front of label; means this is a local label if present
- int j = (*label == '.' ? curenv : 0);
- SYM * sy = lookup(label, LABEL, j);
+ int environment = (*label == '.' ? curenv : 0);
+ SYM * symbol = lookup(label, LABEL, environment);
- sy = NewSymbol(label, LABEL, j);
- sy->sattr = 0;
- sy->sattre = RISCSYM;
+ symbol = NewSymbol(label, LABEL, environment);
+ symbol->sattr = 0;
+// symbol->sattre = RISCSYM;
+ symbol->sattre = 0;
- else if (sy->sattr & DEFINED)
+ else if (symbol->sattr & DEFINED)
return errors("multiply-defined label '%s'", label);
// Put symbol in "order of definition" list
return errors("multiply-defined label '%s'", label);
// Put symbol in "order of definition" list
- if (!(sy->sattr & SDECLLIST))
- sym_decl(sy);
+ if (!(symbol->sattr & SDECLLIST))
+ AddToSymbolOrderList(symbol);
- sy->svalue = orgaddr;
- sy->sattr |= ABS | DEFINED | EQUATED;
+ symbol->svalue = orgaddr;
+ symbol->sattr |= ABS | DEFINED | EQUATED;
- sy->svalue = sloc;
- sy->sattr |= DEFINED | cursect;
+ symbol->svalue = sloc;
+ symbol->sattr |= DEFINED | cursect;
curenv++;
// Make label global if it has a double colon
if (labelType == DCOLON)
{
curenv++;
// Make label global if it has a double colon
if (labelType == DCOLON)
{
return error(locgl_error);
return error(locgl_error);
+ symbol->sattr |= GLOBAL;
f_ifent = rif;
return 0;
}
f_ifent = rif;
return 0;
}
// RISCA.C - GPU/DSP Assembler
// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
// RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
// RISCA.C - GPU/DSP Assembler
// Copyright (C) 199x Landon Dyer, 2011 Reboot and Friends
// RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986
-// Source Utilised with the Kind Permission of Landon Dyer
+// Source utilised with the kind permission of Landon Dyer
#include "mark.h"
#include "amode.h"
#include "mark.h"
#include "amode.h"
-#define DEF_MR // Declar keyword values
-#include "risckw.h" // Incl generated risc keywords
+#define DEF_MR // Declare keyword values
+#include "risckw.h" // Incl. generated risc keywords
#define DEF_KW // Declare keyword values
#define DEF_KW // Declare keyword values
-#include "kwtab.h" // Incl generated keyword tables & defs
+#include "kwtab.h" // Incl. generated keyword tables & defs
unsigned altbankok = 0; // Ok to use alternate register bank
unsigned altbankok = 0; // Ok to use alternate register bank
unsigned orgwarning = 0; // Has an ORG warning been issued
int lastOpcode = -1; // Last RISC opcode assembled
unsigned orgwarning = 0; // Has an ORG warning been issued
int lastOpcode = -1; // Last RISC opcode assembled
-char reg_err[] = "missing register R0...R31";
+const char reg_err[] = "missing register R0...R31";
// Jaguar Jump Condition Names
// Jaguar Jump Condition Names
-char condname[MAXINTERNCC][5] = {
+const char condname[MAXINTERNCC][5] = {
"NZ", "Z", "NC", "NCNZ", "NCZ", "C", "CNZ", "CZ", "NN", "NNNZ", "NNZ",
"N", "N_NZ", "N_Z", "T", "A", "NE", "EQ", "CC", "HS", "HI", "CS", "LO",
"PL", "MI", "F"
};
// Jaguar Jump Condition Numbers
"NZ", "Z", "NC", "NCNZ", "NCZ", "C", "CNZ", "CZ", "NN", "NNNZ", "NNZ",
"N", "N_NZ", "N_Z", "T", "A", "NE", "EQ", "CC", "HS", "HI", "CS", "LO",
"PL", "MI", "F"
};
// Jaguar Jump Condition Numbers
+const char condnumber[] = {
1, 2, 4, 5, 6, 8, 9, 10, 20, 21, 22, 24, 25, 26,
0, 0, 1, 2, 4, 4, 5, 8, 8, 20, 24, 31
};
1, 2, 4, 5, 6, 8, 9, 10, 20, 21, 22, 24, 25, 26,
0, 0, 1, 2, 4, 4, 5, 8, 8, 20, 24, 31
};
-struct opcoderecord roptbl[] = {
+const struct opcoderecord roptbl[] = {
{ MR_ADD, RI_TWO, 0 },
{ MR_ADDC, RI_TWO, 1 },
{ MR_ADDQ, RI_NUM_32, 2 },
{ MR_ADD, RI_TWO, 0 },
{ MR_ADDC, RI_TWO, 1 },
{ MR_ADDQ, RI_NUM_32, 2 },
-// Convert a String to Uppercase
+// Convert a string to uppercase
//
void strtoupper(char * s)
{
//
void strtoupper(char * s)
{
{
char buf[16];
sprintf(buf, "%02X", signal);
{
char buf[16];
sprintf(buf, "%02X", signal);
- errors("Malformed opcode [internal $%s]", buf);
- return ERROR;
+ return errors("Malformed opcode [internal $%s]", buf);
-// Build RISC Instruction Word
+// Build RISC instruction word
//
void BuildRISCIntructionWord(unsigned short opcode, int reg1, int reg2)
{
// Check for absolute address setting
if (!orgwarning && !orgactive)
{
//
void BuildRISCIntructionWord(unsigned short opcode, int reg1, int reg2)
{
// Check for absolute address setting
if (!orgwarning && !orgactive)
{
- warn("GPU/DSP code outside of absolute section");
+// warn("GPU/DSP code outside of absolute section");
+ warn("RISC code generated with no origin defined");
//
int GetRegister(WORD rattr)
{
//
int GetRegister(WORD rattr)
{
if (!(eattr & DEFINED))
{
if (!(eattr & DEFINED))
{
- fixup((WORD)(FU_WORD | rattr), sloc, r_expr);
+ AddFixup((WORD)(FU_WORD | rattr), sloc, r_expr);
return eval;
// Otherwise, it's out of range & we flag an error
return eval;
// Otherwise, it's out of range & we flag an error
- error(reg_err);
- return ERROR;
-// Do RISC Code Generation
+// Do RISC code generation
//
int GenerateRISCCode(int state)
{
//
int GenerateRISCCode(int state)
{
// specific to only one of the RISC processors and ensure it is legal in
// the current code section. If not then show error and return.
if (((parm & GPUONLY) && rdsp) || ((parm & DSPONLY) && rgpu))
// specific to only one of the RISC processors and ensure it is legal in
// the current code section. If not then show error and return.
if (((parm & GPUONLY) && rdsp) || ((parm & DSPONLY) && rgpu))
- {
- error("Opcode is not valid in this code section");
- return ERROR;
- }
+ return error("Opcode is not valid in this code section");
// Process RISC opcode
switch (type)
// Process RISC opcode
switch (type)
if (!(eattr & DEFINED))
{
if (!(eattr & DEFINED))
{
- fixup((WORD)(FU_WORD | attrflg), sloc, r_expr);
+ AddFixup((WORD)(FU_WORD | attrflg), sloc, r_expr);
reg1 = 0;
}
else
{
if ((int)eval < reg1 || (int)eval > reg2)
reg1 = 0;
}
else
{
if ((int)eval < reg1 || (int)eval > reg2)
- {
- error("constant out of range");
- return ERROR;
- }
+ return error("constant out of range");
if (parm & SUB32)
reg1 = 32 - eval;
if (parm & SUB32)
reg1 = 32 - eval;
if (!(eattr & DEFINED))
{
if (!(eattr & DEFINED))
{
- fixup(FU_LONG | FU_MOVEI, sloc + 2, r_expr);
+ AddFixup(FU_LONG | FU_MOVEI, sloc + 2, r_expr);
chcheck(4L);
if (!(eattr & DEFINED))
chcheck(4L);
if (!(eattr & DEFINED))
- {
- error("constant expected after '+'");
- return ERROR;
- }
+ return error("constant expected after '+'");
else
{
if (reg1 < 1 || reg1 > 32)
else
{
if (reg1 < 1 || reg1 > 32)
- {
- error("constant in LOAD out of range");
- return ERROR;
- }
+ return error("constant in LOAD out of range");
if (reg1 == 32)
reg1 = 0;
if (reg1 == 32)
reg1 = 0;
-// sy = lookup((char *)tok[1], LABEL, 0);
sy = lookup(string[tok[1]], LABEL, 0);
if (!sy)
sy = lookup(string[tok[1]], LABEL, 0);
if (!sy)
-// sy = lookup((char *)tok[1], LABEL, 0);
sy = lookup(string[tok[1]], LABEL, 0);
if (!sy)
sy = lookup(string[tok[1]], LABEL, 0);
if (!sy)
if (!(eattr & DEFINED))
{
if (!(eattr & DEFINED))
{
- fixup(FU_WORD | FU_REGTWO, sloc, r_expr);
+ AddFixup(FU_WORD | FU_REGTWO, sloc, r_expr);
else
{
if (reg2 < 1 || reg2 > 32)
else
{
if (reg2 < 1 || reg2 > 32)
- {
- error("constant in STORE out of range");
- return ERROR;
- }
+ return error("constant in STORE out of range");
if (reg2 == 32)
reg2 = 0;
if (reg2 == 32)
reg2 = 0;
val = ccsym->svalue;
}
else
val = ccsym->svalue;
}
else
- {
- error("unknown condition code");
- return ERROR;
- }
+ return error("unknown condition code");
}
if (val < 0 || val > 31)
}
if (val < 0 || val > 31)
- {
- error("condition constant out of range");
- return ERROR;
- }
+ return error("condition constant out of range");
// Store condition code
reg1 = val;
// Store condition code
reg1 = val;
if (!(eattr & DEFINED))
{
if (!(eattr & DEFINED))
{
- fixup(FU_WORD | FU_JR, sloc, r_expr);
+ AddFixup(FU_WORD | FU_JR, sloc, r_expr);
// Should never get here :-D
default:
// Should never get here :-D
default:
- error("Unknown risc opcode type");
- return ERROR;
+ return error("Unknown RISC opcode type");
//
void autoeven(int sect)
{
//
void autoeven(int sect)
{
// o determine name of object file:
// - "foo.o" for linkable output;
// - "foo.prg" for GEMDOS executable (-p flag).
// o determine name of object file:
// - "foo.o" for linkable output;
// - "foo.prg" for GEMDOS executable (-p flag).
for(i=TEXT; i<=BSS; i<<=1)
{
for(i=TEXT; i<=BSS; i<<=1)
{
case 32: d_qphrase(); break;
}
case 32: d_qphrase(); break;
}
#define EQUATEDCC 0x0020
#define UNDEF_CC 0x0040
#define EQUATEDCC 0x0020
#define UNDEF_CC 0x0040
-#define RISCSYM 0x00010000
+//#define RISCSYM 0x00010000
// Globals, externals etc
extern int verb_flag;
// Globals, externals etc
extern int verb_flag;
extern int sbra_flag;
extern int obj_format;
extern int legacy_flag;
extern int sbra_flag;
extern int obj_format;
extern int legacy_flag;
// Prototypes
void init_sym(void);
// Prototypes
void init_sym(void);
-void mksect(int, WORD);
-void switchsect(int);
+void MakeSection(int, WORD);
+void SwitchSection(int);
// Section descriptors
SECT sect[NSECTS]; // All sections...
// Section descriptors
SECT sect[NSECTS]; // All sections...
// Cleanup all sections
for(i=0; i<NSECTS; i++)
// Cleanup all sections
for(i=0; i<NSECTS; i++)
// Construct default sections, make TEXT the current section
// Construct default sections, make TEXT the current section
- mksect(ABS, SUSED | SABS | SBSS); // ABS
- mksect(TEXT, SUSED | TEXT ); // TEXT
- mksect(DATA, SUSED | DATA ); // DATA
- mksect(BSS, SUSED | BSS | SBSS ); // BSS
-// mksect(M6502, SUSED | TEXT ); // 6502 code section
+ MakeSection(ABS, SUSED | SABS | SBSS); // ABS
+ MakeSection(TEXT, SUSED | TEXT ); // TEXT
+ MakeSection(DATA, SUSED | DATA ); // DATA
+ MakeSection(BSS, SUSED | BSS | SBSS); // BSS
+// MakeSection(M6502, SUSED | TEXT ); // 6502 code section
- switchsect(TEXT); // Switch to TEXT for starters
+ SwitchSection(TEXT); // Switch to TEXT for starters
}
//
// Make a New (Clean) Section
//
}
//
// Make a New (Clean) Section
//
-void mksect(int sno, WORD attr)
+void MakeSection(int sno, WORD attr)
{
SECT * p = §[sno];
p->scattr = attr;
{
SECT * p = §[sno];
p->scattr = attr;
-// Switch to Another Section (Copy Section & Chunk Descriptors to Global Vars
-// for Fast Access)
+// Switch to another section (copy section & chunk descriptors to global vars
+// for fast access)
-void switchsect(int sno)
+void SwitchSection(int sno)
{
CHUNK * cp; // Chunk pointer
cursect = sno;
{
CHUNK * cp; // Chunk pointer
cursect = sno;
{
SECT * p = §[cursect];
{
SECT * p = §[cursect];
//
// Arrange for a fixup on a location
//
//
// Arrange for a fixup on a location
//
-int fixup(WORD attr, LONG loc, TOKEN * fexpr)
+int AddFixup(WORD attr, LONG loc, TOKEN * fexpr)
{
LONG i;
LONG len = 0;
CHUNK * cp;
SECT * p;
// Shamus: Expression lengths are voodoo ATM (variable "i"). Need to fix this.
{
LONG i;
LONG len = 0;
CHUNK * cp;
SECT * p;
// Shamus: Expression lengths are voodoo ATM (variable "i"). Need to fix this.
-#warning "!!! fixup() is filled with VOODOO !!!"
+#warning "!!! AddFixup() is filled with VOODOO !!!"
DEBUG printf("FIXUP@$%X: $%X\n", loc, attr);
// Compute length of expression (could be faster); determine if it's the
DEBUG printf("FIXUP@$%X: $%X\n", loc, attr);
// Compute length of expression (could be faster); determine if it's the
{
// Just a single symbol
// SCPCD : correct bit mask for attr (else other FU_xxx will match) NYAN !
{
// Just a single symbol
// SCPCD : correct bit mask for attr (else other FU_xxx will match) NYAN !
- if ((attr & 0x0F00) == FU_JR)
+ if ((attr & FUMASKRISC) == FU_JR)
{
// i = 18;
// i = FIXUP_BASE_SIZE + (sizeof(LONG) * 2);
{
// i = 18;
// i = FIXUP_BASE_SIZE + (sizeof(LONG) * 2);
}
// SCPCD : correct bit mask for attr (else other FU_xxx will match) NYAN !
}
// SCPCD : correct bit mask for attr (else other FU_xxx will match) NYAN !
- if ((attr & 0x0F00) == FU_JR)
+ if ((attr & FUMASKRISC) == FU_JR)
{
if (orgactive)
*fchptr.lp++ = orgaddr;
{
if (orgactive)
*fchptr.lp++ = orgaddr;
DEBUG printf("Resolving DATA sections...\n");
ResolveFixups(DATA);
DEBUG printf("Resolving DATA sections...\n");
ResolveFixups(DATA);
-//No, no we don't.
-#if 0
- // We need to do a final check of forward 'jump' destination addresses that
- // are external
- for(i=0; i<MAXFWDJUMPS; i++)
- {
- if (fwdjump[i])
- {
- err_setup();
- sprintf(buf, "* \'jump\' at $%08X - destination address is external to this source file and cannot have its aligment validated", fwdjump[i]);
-
- if (listing > 0)
- ship_ln(buf);
-
- if (err_flag)
- write(err_fd, buf, (LONG)strlen(buf));
- else
- printf("%s\n", buf);
- }
- }
-#endif
-
if (ch == NULL)
return 0;
if (ch == NULL)
return 0;
- CHUNK * cch = sc->sfcode; // "cache" first chunk
+ // "Cache" first chunk
+ CHUNK * cch = sc->sfcode;
- if (cch == NULL) // Can't fixup a sect with nothing in it
+ // Can't fixup a sect with nothing in it
+ if (cch == NULL)
- interror(7); // Fixup (loc) out of range
+ // Fixup (loc) out of range
+ interror(7);
// If the expression is undefined and no external symbol is
// involved, then it's an error.
// If the expression is undefined and no external symbol is
// involved, then it's an error.
- if (!(eattr & DEFINED) && esym == NULL)
+ if (!(eattr & DEFINED) && (esym == NULL))
{
error(undef_error);
continue;
}
{
error(undef_error);
continue;
}
- if (((w & 0x0F00) == FU_MOVEI) && esym)
+// It seems that this is completely unnecessary!
+#if 0
+ if (((w & FUMASKRISC) == FU_MOVEI) && esym)
+//{
+//printf("DoFixups: Setting symbol attre to RISCSYM...\n");
// the word could be unaligned in the section buffer, so we have to
// be careful.
case FU_WORD:
// the word could be unaligned in the section buffer, so we have to
// be careful.
case FU_WORD:
- if ((w & 0x0F00) == FU_JR)// || ((w & 0x0F00) == FU_MJR))
+ if ((w & FUMASKRISC) == FU_JR)// || ((w & 0x0F00) == FU_MJR))
- if ((w & 0x0F00) == FU_NUM15)
+ if ((w & FUMASKRISC) == FU_NUM15)
{
if (eval < -16 || eval > 15)
{
{
if (eval < -16 || eval > 15)
{
- if ((w & 0x0F00) == FU_NUM31)
+ if ((w & FUMASKRISC) == FU_NUM31)
{
if (eval < 0 || eval > 31)
{
{
if (eval < 0 || eval > 31)
{
- if ((w & 0x0F00) == FU_NUM32)
+ if ((w & FUMASKRISC) == FU_NUM32)
{
if (eval < 1 || eval > 32)
{
{
if (eval < 1 || eval > 32)
{
- if ((w & 0x0F00) == FU_REGONE)
+ if ((w & FUMASKRISC) == FU_REGONE)
{
if (eval < 0 || eval > 31)
{
{
if (eval < 0 || eval > 31)
{
- if ((w & 0x0F00) == FU_REGTWO)
+ if ((w & FUMASKRISC) == FU_REGTWO)
{
if (eval < 0 || eval > 31)
{
{
if (eval < 0 || eval > 31)
{
// the long could be unaligned in the section buffer, so be careful
// (again).
case FU_LONG:
// the long could be unaligned in the section buffer, so be careful
// (again).
case FU_LONG:
- if ((w & 0x0F00) == FU_MOVEI)
+ if ((w & FUMASKRISC) == FU_MOVEI)
{
#if 0
address = loc + 4;
{
#if 0
address = loc + 4;
+ // Long constant in MOVEI # is word-swapped, so fix it here
eval = ((eval >> 16) & 0x0000FFFF) | ((eval << 16) & 0xFFFF0000);
flags = (MLONG | MMOVEI);
}
eval = ((eval >> 16) & 0x0000FFFF) | ((eval << 16) & 0xFFFF0000);
flags = (MLONG | MMOVEI);
}
#define FU_PCREL 020 // Subtract PC first
#define FU_EXPR 040 // Expression (not symbol) follows
#define FU_PCREL 020 // Subtract PC first
#define FU_EXPR 040 // Expression (not symbol) follows
+#define FUMASKRISC 0x0F00 // Mask for RISC fixup cases
#define FU_MOVEI 0x0100
#define FU_JR 0x0200
#define FU_MOVEI 0x0100
#define FU_JR 0x0200
#define FU_REGONE 0x0400
#define FU_NUM15 0x0500
#define FU_NUM31 0x0600
#define FU_NUM32 0x0700
#define FU_REGTWO 0x0800
#define FU_REGONE 0x0400
#define FU_NUM15 0x0500
#define FU_NUM31 0x0600
#define FU_NUM32 0x0700
#define FU_REGTWO 0x0800
#define FU_SUB32 0x1000
#define FU_ISBRA 0x2000 // Word forward fixup is a BRA or DBRA
#define FU_LBRA 0x4000 // Long branch, for short branch detect
#define FU_SUB32 0x1000
#define FU_ISBRA 0x2000 // Word forward fixup is a BRA or DBRA
#define FU_LBRA 0x4000 // Long branch, for short branch detect
#define MCHEND 0x2000 // Indicates end of mark chunk
#define MPCREL 0x1000 // Mark is PC-relative
#define MCHEND 0x2000 // Indicates end of mark chunk
#define MPCREL 0x1000 // Mark is PC-relative
-//#define MAXFWDJUMPS 1024 // Maximum forward jumps to check
-//extern unsigned fwdjump[MAXFWDJUMPS];
-//extern unsigned fwindex;
-
// Globals, external etc
extern LONG sloc;
extern WORD scattr;
// Globals, external etc
extern LONG sloc;
extern WORD scattr;
// Prototypes
void InitSection(void);
// Prototypes
void InitSection(void);
-void switchsect(int);
-void savsect(void);
+void SwitchSection(int);
+void SaveSection(void);
int fixtest(int, LONG);
int chcheck(LONG);
int fixtest(int, LONG);
int chcheck(LONG);
-int fixup(WORD, LONG, TOKEN *);
+int AddFixup(WORD, LONG, TOKEN *);
int ResolveAllFixups(void);
#endif // __SECT_H__
int ResolveAllFixups(void);
#endif // __SECT_H__
symbol->stype = (BYTE)type;
symbol->senv = (WORD)envno;
symbol->sattr = 0;
symbol->stype = (BYTE)type;
symbol->senv = (WORD)envno;
symbol->sattr = 0;
- symbol->sattre = (rgpu || rdsp ? RISCSYM : 0);
+//we don't do this, it could be a forward reference!
+// symbol->sattr = DEFINED; // We just defined it...
+ // This is a bad assumption. Not every symbol 1st seen in a RISC section is
+ // a RISC symbol!
+// symbol->sattre = (rgpu || rdsp ? RISCSYM : 0);
+ symbol->sattre = 0;
symbol->svalue = 0;
symbol->sorder = NULL;
symbol->uid = currentUID++;
symbol->svalue = 0;
symbol->sorder = NULL;
symbol->uid = currentUID++;
//
// Put symbol on "order-of-declaration" list of symbols
//
//
// Put symbol on "order-of-declaration" list of symbols
//
-void sym_decl(SYM * symbol)
+//void sym_decl(SYM * symbol)
+void AddToSymbolOrderList(SYM * symbol)
{
if (symbol->sattr & SDECLLIST)
return; // Already on list
{
if (symbol->sattr & SDECLLIST)
return; // Already on list
SYM * lookup(char *, int, int);
void InitSymbolTable(void);
SYM * NewSymbol(char *, int, int);
SYM * lookup(char *, int, int);
void InitSymbolTable(void);
SYM * NewSymbol(char *, int, int);
+void AddToSymbolOrderList(SYM *);
int syg_fix(void);
int symtable(void);
int sy_assign(char *, char *(*)());
int syg_fix(void);
int symtable(void);
int sy_assign(char *, char *(*)());
#define MAJOR 1 // Major version number
#define MINOR 2 // Minor version number
#define MAJOR 1 // Major version number
#define MINOR 2 // Minor version number
-#define PATCH 13 // Patch release number
+#define PATCH 15 // Patch release number