d_include, // 33 include
fpop, // 34 end
d_unimpl, // 35* macro
- exitmac, // 36* exitm
+ ExitMacro, // 36* exitm
d_unimpl, // 37* endm
d_list, // 38 list
d_nlist, // 39 nlist
d_equrundef, // 50 .equrundef/.regundef
d_ccundef, // 51 .ccundef
d_print, // 52 .print
- d_gpumain, // 53 .gpumain
- d_jpad, // 54 .jpad
- d_nojpad, // 55 .nojpad
- d_fail, // 56 .fail
+ d_cstruct, // 53 .cstruct
};
-//
-// .fail - User abort
-//
-int d_fail(void)
-{
- fatal("user abort");
- return 0;
-}
-
-
//
// .org - Set origin
//
}
-//
-// NOP Padding Directive
-//
-int d_jpad(void)
-{
- jpad = 1;
- return 0;
-}
-
-
-int d_nojpad(void)
-{
- jpad = 0;
- return 0;
-}
-
-
//
// Print Directive
//
long pos, size;
char buf;
+ // Check to see if we're in BSS, and, if so, throw an error
+ if (scattr & SBSS)
+ {
+ errors("Cannot include binary file \"%s\" in BSS section", string[tok[1]]);
+ return ERROR;
+ }
+
if (*tok != STRING)
{
error(syntax_error);
size = lseek(j, 0L, SEEK_END);
chcheck(size);
pos = lseek(j, 0L, SEEK_SET);
-
+
+ DEBUG
+ {
+ printf("INCBIN: File '%s' is %li bytes.\n", string[tok[1]], size);
+ }
+
for(i=0; i<size; i++)
{
buf = '\0';
//
int d_regbank0(void)
{
- regbank = BANK_0; // Set active register bank zero
+ // Set active register bank zero
+ regbank = BANK_0;
return 0;
}
int d_regbank1(void)
{
- regbank = BANK_1; // Set active register bank one
+ // Set active register bank one
+ regbank = BANK_1;
return 0;
}
// the "-d" option.
if ((j = open(fn, 0)) < 0)
{
- for(i=0; nthpath("RMACPATH", i, buf1)!=0; ++i)
+ for(i=0; nthpath("RMACPATH", i, buf1)!=0; i++)
{
j = strlen(buf1);
- if (j > 0 && buf1[j-1] != SLASHCHAR) // Append path char if necessary
+ if (j > 0 && buf1[j - 1] != SLASHCHAR) // Append path char if necessary
strcat(buf1, SLASHSTRING);
strcat(buf1, fn);
case SIZB:
if (!defined)
{
- fixup(FU_BYTE|FU_SEXT, sloc, exprbuf);
+ fixup(FU_BYTE | FU_SEXT, sloc, exprbuf);
D_byte(0);
}
else
case SIZN:
if (!defined)
{
- fixup(FU_WORD|FU_SEXT, sloc, exprbuf);
+ fixup(FU_WORD | FU_SEXT, sloc, exprbuf);
D_word(0);
}
else
if (!defined)
{
if (movei)
- fixup(FU_LONG|FU_MOVEI, sloc, exprbuf);
+ fixup(FU_LONG | FU_MOVEI, sloc, exprbuf);
else
fixup(FU_LONG, sloc, exprbuf);
case SIZB:
if (!defined)
{
- fixup(FU_BYTE|FU_SEXT, sloc, exprbuf);
+ fixup(FU_BYTE | FU_SEXT, sloc, exprbuf);
D_byte(0);
}
else
case SIZN:
if (!defined)
{
- fixup(FU_WORD|FU_SEXT, sloc, exprbuf);
+ fixup(FU_WORD | FU_SEXT, sloc, exprbuf);
D_word(0);
}
else
int d_list(void)
{
if (list_flag)
- ++listing;
+ listing++;
return 0;
}
int d_nlist(void)
{
if (list_flag)
- --listing;
+ listing--;
return 0;
}
int d_68000(void)
{
rgpu = rdsp = 0;
- in_main = 0;
// Switching from gpu/dsp sections should reset any ORG'd Address
orgactive = 0;
orgwarning = 0;
orgwarning = 0;
}
- rgpu = 1; // Set GPU assembly
- rdsp = 0; // Unset DSP assembly
- regbank = BANK_N; // Set no default register bank
- in_main = 0;
- jpad = 0;
- return 0;
-}
-
-
-//
-// GPU Main Code Directive
-//
-
-int d_gpumain(void)
-{
- if ((cursect != TEXT) && (cursect != DATA))
- {
- error(".gpumain can only be used in the TEXT or DATA segments");
- return ERROR;
- }
-
- // If previous section was dsp or 68000 then we need to reset ORG'd Addresses
- if (!rgpu)
- {
- orgactive = 0;
- orgwarning = 0;
- }
-
- rgpu = 1; // Set GPU assembly
- rdsp = 0; // Unset DSP assembly
- regbank = BANK_N; // Set no default register bank
- in_main = 1; // Enable main code execution rules
- jpad = 0;
+ rgpu = 1; // Set GPU assembly
+ rdsp = 0; // Unset DSP assembly
+ regbank = BANK_N; // Set no default register bank
return 0;
}
orgwarning = 0;
}
- rdsp = 1; // Set DSP assembly
- rgpu = 0; // Unset GPU assembly
- regbank = BANK_N; // Set no default register bank
- in_main = 0;
- jpad = 0;
+ rdsp = 1; // Set DSP assembly
+ rgpu = 0; // Unset GPU assembly
+ regbank = BANK_N; // Set no default register bank
return 0;
}
// .cargs [#offset], symbol[.size], ...
//
// Lists of registers may also be mentioned; they just take up space. Good for
-// "documentation" purposes.
+// "documentation" purposes:
//
-// .cargs a6,.arg1, .arg2, .arg3...
+// .cargs a6, .arg1, .arg2, .arg3...
//
-// The symbols are ABS and EQUATED.
+// Symbols thus created are ABS and EQUATED.
//
int d_cargs(void)
{
- VALUE eval;
+ VALUE eval = 4; // Default to 4 if no offset specified (to account for
+ // return address)
WORD rlist;
- SYM * sy;
+ SYM * symbol;
char * p;
int env;
int i;
if (*tok == '#')
{
- ++tok;
+ tok++;
if (abs_expr(&eval) != OK)
return 0;
- if (*tok == ',') // Eat comma if it's there
- ++tok;
+ // Eat the comma, if it's there
+ if (*tok == ',')
+ tok++;
}
- else
- eval = 4;
for(;;)
{
// p = (char *)tok[1];
p = string[tok[1]];
+#if 0
if (*p == '.')
- env = curenv;
+ env = curenv; // Label is local
else
- env = 0;
-
- sy = lookup(p, LABEL, env);
+ env = 0; // Label is global
+#else
+ // Set env to either local (dot prefixed) or global scope
+ env = (*p == '.' ? curenv : 0);
+#endif
+ symbol = lookup(p, LABEL, env);
- if (sy == NULL)
+ if (symbol == NULL)
{
- sy = NewSymbol(p, LABEL, env);
- sy->sattr = 0;
+ symbol = NewSymbol(p, LABEL, env);
+ symbol->sattr = 0;
}
- else if (sy->sattr & DEFINED)
+ else if (symbol->sattr & DEFINED)
return errors("multiply-defined label '%s'", p);
// Put symbol in "order of definition" list
- if (!(sy->sattr & SDECLLIST))
- sym_decl(sy);
+ if (!(symbol->sattr & SDECLLIST))
+ sym_decl(symbol);
- sy->sattr |= ABS|DEFINED|EQUATED;
- sy->svalue = eval;
+ symbol->sattr |= (ABS | DEFINED | EQUATED);
+ symbol->svalue = eval;
tok += 2;
- switch((int)*tok)
+ // What this does is eat any dot suffixes attached to a symbol. If
+ // it's a .L, it adds 4 to eval; if it's .W or .B, it adds 2. If
+ // there is no dot suffix, it assumes a size of 2.
+ switch ((int)*tok)
{
case DOTL:
eval += 2;
case DOTB:
case DOTW:
- ++tok;
+ tok++;
}
eval += 2;
}
- else
+ else if (*tok >= KW_D0 && *tok <= KW_A7)
+ {
+ if (reglist(&rlist) < 0)
+ return 0;
+
+// for(i=0; i++<16; rlist>>=1)
+ for(i=0; i<16; i++, rlist>>=1)
+ {
+ if (rlist & 1)
+ eval += 4;
+ }
+ }
+ else
+ {
+ switch ((int)*tok)
+ {
+ case KW_USP:
+ case KW_SSP:
+ case KW_PC:
+ eval += 2;
+ // FALLTHROUGH
+ case KW_SR:
+ case KW_CCR:
+ eval += 2;
+ tok++;
+ break;
+ case EOL:
+ return 0;
+ default:
+ return error(".cargs syntax");
+ }
+ }
+
+ // Eat commas in between each argument, if they exist
+ if (*tok == ',')
+ tok++;
+ }
+}
+
+
+//
+// .cstruct [#offset], symbol[.size], ...
+//
+// Lists of registers may also be mentioned; they just take up space. Good for
+// "documentation" purposes:
+//
+// .cstruct a6, .arg1, .arg2, .arg3...
+//
+// Symbols thus created are ABS and EQUATED. Note that this is for
+// compatibility with VBCC and the Remover's library. Thanks to GroovyBee for
+// the suggestion.
+//
+int d_cstruct(void)
+{
+ VALUE eval = 0; // Default, if no offset specified, is zero
+ WORD rlist;
+ SYM * symbol;
+ char * symbolName;
+ int env;
+ int i;
+
+ if (rgpu || rdsp)
+ return error("directive forbidden in gpu/dsp mode");
+
+ if (*tok == '#')
+ {
+ tok++;
+
+ if (abs_expr(&eval) != OK)
+ return 0;
+
+ // Eat the comma, if it's there
+ if (*tok == ',')
+ tok++;
+ }
+
+ for(;;)
+ {
+ if (*tok == SYMBOL)
{
- if (*tok >= KW_D0 && *tok <= KW_A7)
+ symbolName = string[tok[1]];
+
+ // Set env to either local (dot prefixed) or global scope
+ env = (symbolName[0] == '.' ? curenv : 0);
+ symbol = lookup(symbolName, LABEL, env);
+
+ // If the symbol wasn't found, then define it. Otherwise, throw an
+ // error.
+ if (symbol == NULL)
{
- if (reglist(&rlist) < 0)
- return 0;
+ symbol = NewSymbol(symbolName, LABEL, env);
+ symbol->sattr = 0;
+ }
+ else if (symbol->sattr & DEFINED)
+ return errors("multiply-defined label '%s'", symbolName);
- for(i=0; i++<16; rlist>>=1)
- if (rlist & 1)
- eval += 4;
+ // Put symbol in "order of definition" list
+ if (!(symbol->sattr & SDECLLIST))
+ sym_decl(symbol);
+
+ tok += 2;
+
+ // Adjust label start address if it's a word or a long, as a byte
+ // label might have left us on an odd address.
+ switch ((int)*tok)
+ {
+ case DOTW:
+ case DOTL:
+ eval += eval & 0x01;
}
- else
+
+ symbol->sattr |= (ABS | DEFINED | EQUATED);
+ symbol->svalue = eval;
+
+ // Check for dot suffixes and adjust space accordingly (longs and
+ // words on an odd boundary get bumped to the next word aligned
+ // address). If no suffix, then throw an error.
+ switch ((int)*tok)
{
- switch((int)*tok)
- {
- case KW_USP:
- case KW_SSP:
- case KW_PC:
- eval += 2;
- // FALLTHROUGH
- case KW_SR:
- case KW_CCR:
- eval += 2;
- ++tok;
- break;
- case EOL:
- return 0;
- default:
- return error(".cargs syntax");
- }
+ case DOTL:
+ eval += 4;
+ break;
+ case DOTW:
+ eval += 2;
+ break;
+ case DOTB:
+ eval += 1;
+ break;
+ default:
+ return error("Symbol missing dot suffix in .cstruct construct");
}
- if (*tok == ',')
- ++tok;
+ tok++;
}
+ else if (*tok >= KW_D0 && *tok <= KW_A7)
+ {
+ if (reglist(&rlist) < 0)
+ return 0;
+
+ for(i=0; i<16; i++, rlist>>=1)
+ {
+ if (rlist & 1)
+ eval += 4;
+ }
+ }
+ else
+ {
+ switch ((int)*tok)
+ {
+ case KW_USP:
+ case KW_SSP:
+ case KW_PC:
+ eval += 2;
+ // FALLTHROUGH
+ case KW_SR:
+ case KW_CCR:
+ eval += 2;
+ tok++;
+ break;
+ case EOL:
+ return 0;
+ default:
+ return error(".cstruct syntax");
+ }
+ }
+
+ // Eat commas in between each argument, if they exist
+ if (*tok == ',')
+ tok++;
}
}
//
int undmac1(char * p)
{
- SYM * sy;
+ SYM * symbol = lookup(p, MACRO, 0);
- // If the macro symbol exists, cause it to dissappear
- if ((sy = lookup(p, MACRO, 0)) != NULL)
- sy->stype = (BYTE)SY_UNDEF;
+ // If the macro symbol exists, cause it to disappear
+// if ((sy = lookup(p, MACRO, 0)) != NULL)
+ if (symbol != NULL)
+ symbol->stype = (BYTE)SY_UNDEF;
return OK;
}
symlist(undmac1);
return 0;
}
+