//
zpreq = 0;
- switch ((int)*tok)
+ switch (tok.u32[0])
{
case EOL:
amode = A65_IMPL;
break;
case '#':
- tok++;
+ tok.u32++;
- if (*tok == '>')
+ if (*tok.u32 == '>')
{
- tok++;
+ tok.u32++;
+
if (expr(exprbuf, &eval, &eattr, NULL) < 0)
return;
amode = A65_IMMEDH;
break;
}
- else if (*tok == '<')
+ else if (*tok.u32 == '<')
{
- tok++;
+ tok.u32++;
+
if (expr(exprbuf, &eval, &eattr, NULL) < 0)
return;
break;
case '(':
- tok++;
+ tok.u32++;
if (expr(exprbuf, &eval, &eattr, NULL) < 0)
return;
- if (*tok == ')')
+ if (*tok.u32 == ')')
{
// (foo) or (foo),y
- if (*++tok == ',')
+ if (*++tok.u32 == ',')
{
// (foo),y
- tok++;
- p = string[tok[1]];
+ tok.u32++;
+ p = string[tok.u32[1]];
- if (*tok != SYMBOL || p[1] != EOS || (*p | 0x20) != 'y') // Sleazo tolower()
+ // Sleazo tolower() ---------------------vvvvvvvvvvv
+ if (*tok.u32 != SYMBOL || p[1] != EOS || (*p | 0x20) != 'y')
goto badmode;
- tok += 2;
+ tok.u32 += 2;
amode = A65_INDY;
}
else
amode = A65_IND;
}
- else if (*tok == ',')
+ else if (*tok.u32 == ',')
{
// (foo,x)
- tok++;
- p = string[tok[1]];
+ tok.u32++;
+ p = string[tok.u32[1]];
- if (*tok != SYMBOL || p[1] != EOS || (*p | 0x20) != 'x') // Sleazo tolower()
+ // Sleazo tolower() ---------------------vvvvvvvvvvv
+ if (*tok.u32 != SYMBOL || p[1] != EOS || (*p | 0x20) != 'x')
goto badmode;
- tok += 2;
+ tok.u32 += 2;
- if (*tok++ != ')')
+ if (*tok.u32++ != ')')
goto badmode;
amode = A65_INDX;
break;
case '@':
- tok++;
+ tok.u32++;
if (expr(exprbuf, &eval, &eattr, NULL) < 0)
return;
- if (*tok == '(')
+ if (*tok.u32 == '(')
{
- tok++;
- p = string[tok[1]];
+ tok.u32++;
+ p = string[tok.u32[1]];
- if (*tok != SYMBOL || p[1] != EOS || tok[2] != ')' || tok[3] != EOL)
+ if (*tok.u32 != SYMBOL || p[1] != EOS || tok.u32[2] != ')' || tok.u32[3] != EOL)
goto badmode;
i = (*p | 0x20); // Sleazo tolower()
else
goto badmode;
- tok += 3; // Past SYMBOL <string> ')' EOL
+ tok.u32 += 3; // Past SYMBOL <string> ')' EOL
zpreq = 1; // Request zeropage optimization
}
- else if (*tok == EOL)
+ else if (*tok.u32 == EOL)
amode = A65_IND;
else
goto badmode;
// x,foo
// y,foo
//
- p = string[tok[1]];
+ p = string[tok.u32[1]];
// ggn: the following code is effectively disabled as it would make
// single letter labels not work correctly (would not identify the
// label properly). And from what I understand it's something to
zpreq = 1;
- if (*tok == EOL)
+ if (*tok.u32 == EOL)
amode = A65_ABS;
- else if (*tok == ',')
+ else if (*tok.u32 == ',')
{
- tok++;
- p = string[tok[1]];
+ tok.u32++;
+ p = string[tok.u32[1]];
- if (*tok != SYMBOL || p[1] != EOS)
+ if (*tok.u32 != SYMBOL || p[1] != EOS)
goto badmode;
- tok += 2;
+ tok.u32 += 2;
//
// Check for X or Y index register;
if (sloc > 0x10000L)
fatal("6502 code pointer > 64K");
- if (*tok != EOL)
+ if (*tok.u32 != EOL)
error(extra_stuff);
}
int bfparam1; // bfxxx / fmove instruction parameter 1
int bfparam2; // bfxxx / fmove instruction parameter 2
-int bfval1; //bfxxx / fmove value 1
-int bfval2; //bfxxx / fmove value 2
+int bfval1; // bfxxx / fmove value 1
+int bfval2; // bfxxx / fmove value 2
TOKEN bf0expr[EXPRSIZE]; // Expression
uint64_t bf0exval; // Expression's value
WORD bf0exattr; // Expression's attribute
bf0esym = NULL;
// If at EOL, then no addr modes at all
- if (*tok == EOL)
+ if (*tok.u32 == EOL)
return 0;
// Parse first addressing mode
#define AnREG a0reg
#define AnIXREG a0ixreg
#define AnIXSIZ a0ixsiz
- #define AnEXPR a0expr
+ #define AnEXPR (TOKENPTR)a0expr
#define AnEXVAL a0exval
#define AnEXATTR a0exattr
- #define AnOEXPR a0oexpr
+ #define AnOEXPR (TOKENPTR)a0oexpr
#define AnOEXVAL a0oexval
#define AnOEXATTR a0oexattr
#define AnESYM a0esym
#define AMn_IX0 am0_ix0
#define AMn_IXN am0_ixn
#define CHK_FOR_DISPn CheckForDisp0
- #define AnBEXPR a0bexpr
+ #define AnBEXPR (TOKENPTR)a0bexpr
#define AnBEXVAL a0bexval
#define AnBEXATTR a0bexattr
#define AnBZISE a0bsize
// it's a bitfield instruction--check the parameters inside the {} block
// for validity
- if (*tok == '{')
+ if (*tok.u32 == '{')
if (check030bf() == ERROR)
return ERROR;
- if ((acount == 0) || (*tok != ','))
+ if ((acount == 0) || (*tok.u32 != ','))
return 1;
// Eat the comma
- tok++;
+ tok.u32++;
// Parse second addressing mode
#define AnOK a1ok
#define AnREG a1reg
#define AnIXREG a1ixreg
#define AnIXSIZ a1ixsiz
- #define AnEXPR a1expr
+ #define AnEXPR (TOKENPTR)a1expr
#define AnEXVAL a1exval
#define AnEXATTR a1exattr
- #define AnOEXPR a1oexpr
+ #define AnOEXPR (TOKENPTR)a1oexpr
#define AnOEXVAL a1oexval
#define AnOEXATTR a1oexattr
#define AnESYM a1esym
#define AMn_IX0 am1_ix0
#define AMn_IXN am1_ixn
#define CHK_FOR_DISPn CheckForDisp1
- #define AnBEXPR a1bexpr
+ #define AnBEXPR (TOKENPTR)a1bexpr
#define AnBEXVAL a1bexval
#define AnBEXATTR a1bexattr
#define AnBZISE a1bsize
// It's a bitfield instruction--check the parameters inside the {} block
// for validity
- if (*tok == '{')
+ if (*tok.u32 == '{')
if (check030bf() == ERROR)
return ERROR;
// At this point, it is legal for 020+ to have a ':'. For example divu.l
// d0,d2:d3
- if (*tok == ':')
+ if (*tok.u32 == ':')
{
if ((activecpu & (CPU_68020 | CPU_68030 | CPU_68040)) == 0)
return error(unsupport);
// TODO: protect this from combinations like Dx:FPx etc :)
- tok++; //eat the colon
+ tok.u32++; //eat the colon
- if ((*tok >= KW_D0) && (*tok <= KW_D7))
+ if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7))
{
- a2reg = (*tok - KW_D0);
+ a2reg = (*tok.u32 - KW_D0);
mulmode = 1 << 10;
}
- else if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
+ else if ((*tok.u32 >= KW_FP0) && (*tok.u32 <= KW_FP7))
{
- a2reg = (*tok - KW_FP0);
+ a2reg = (*tok.u32 - KW_FP0);
mulmode = 1 << 10;
}
else
return error("a data or FPU register must follow a :");
- *tok++;
+ *tok.u32++;
}
else
{
for(;;)
{
- if ((*tok >= KW_D0) && (*tok <= KW_A7))
- r = *tok++ & 0x0F;
+ if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_A7))
+ r = *tok.u32++ & 0x0F;
else
break;
- if (*tok == '-')
+ if (*tok.u32 == '-')
{
- tok++;
+ tok.u32++;
- if ((*tok >= KW_D0) && (*tok <= KW_A7))
- cnt = *tok++ & 0x0F;
+ if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_A7))
+ cnt = *tok.u32++ & 0x0F;
else
return error("register list syntax");
while (cnt-- >= 0)
rmask |= msktab[r++];
- if (*tok != '/')
+ if (*tok.u32 != '/')
break;
- tok++;
+ tok.u32++;
}
*a_rmask = rmask;
for(;;)
{
- if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
- r = *tok++ & 0x07;
+ if ((*tok.u32 >= KW_FP0) && (*tok.u32 <= KW_FP7))
+ r = *tok.u32++ & 0x07;
else
break;
- if (*tok == '-')
+ if (*tok.u32 == '-')
{
- tok++;
+ tok.u32++;
- if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
- cnt = *tok++ & 0x07;
+ if ((*tok.u32 >= KW_FP0) && (*tok.u32 <= KW_FP7))
+ cnt = *tok.u32++ & 0x07;
else
return error("register list syntax");
while (cnt-- >= 0)
rmask |= msktab_minus[r++];
- if (*tok != '/')
+ if (*tok.u32 != '/')
break;
- tok++;
+ tok.u32++;
}
*a_rmask = rmask;
for(;;)
{
- if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
- r = *tok++ & 0x07;
+ if ((*tok.u32 >= KW_FP0) && (*tok.u32 <= KW_FP7))
+ r = *tok.u32++ & 0x07;
else
break;
- if (*tok == '-')
+ if (*tok.u32 == '-')
{
- tok++;
+ tok.u32++;
- if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
- cnt = *tok++ & 0x07;
+ if ((*tok.u32 >= KW_FP0) && (*tok.u32 <= KW_FP7))
+ cnt = *tok.u32++ & 0x07;
else
return error("register list syntax");
while (cnt-- >= 0)
rmask |= msktab_plus[r++];
- if (*tok != '/')
+ if (*tok.u32 != '/')
break;
- tok++;
+ tok.u32++;
}
*a_rmask = rmask;
int check030bf(void)
{
CHECK00;
- tok++;
+ tok.u32++;
- if (*tok == CONST)
+ if (*tok.u32 == CONST)
{
- tok++;
- bfval1 = (int)*(uint64_t *)tok;
+ tok.u32++;
+// bfval1 = (int)*(uint64_t *)tok.u32;
+ bfval1 = (int)*tok.u64;
// Do=0, offset=immediate - shift it to place
bfparam1 = (0 << 11);
- tok++;
- tok++;
+// tok.u32++;
+// tok.u32++;
+ tok.u64++;
}
- else if (*tok == SYMBOL)
+ else if (*tok.u32 == SYMBOL)
{
- if (expr(bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK)
+ if (expr((TOKENPTR)bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK)
return ERROR;
if (!(bf0exattr & DEFINED))
// Do=0, offset=immediate - shift it to place
bfparam1 = (0 << 11);
}
- else if ((*tok >= KW_D0) && (*tok <= KW_D7))
+ else if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7))
{
// Do=1, offset=data register - shift it to place
bfparam1 = (1 << 11);
- bfval1 = (*(int *)tok - 128);
- tok++;
+ bfval1 = (*(int *)tok.u32 - 128);
+ tok.u32++;
}
else
return ERROR;
- if (*tok==':')
- tok++; //eat the ':'
+ // Eat the ':', if any
+ if (*tok.u32 == ':')
+ tok.u32++;
- if (*tok == '}' && tok[1] == EOL)
+ if (*tok.u32 == '}' && tok.u32[1] == EOL)
{
// It is ok to have }, EOL here - it might be "fmove fpn,<ea> {dx}"
- tok++;
+ tok.u32++;
return OK;
}
- if (*tok == CONST)
+ if (*tok.u32 == CONST)
{
- tok++;
- bfval2 = (int)*(uint64_t *)tok;
+ tok.u32++;
+// bfval2 = (int)*(uint64_t *)tok.u32;
+ bfval2 = (int)*tok.u64;
// Do=0, offset=immediate - shift it to place
bfparam2 = (0 << 5);
- tok++;
- tok++;
+// tok.u32++;
+// tok.u32++;
+ tok.u64++;
}
- else if (*tok == SYMBOL)
+ else if (*tok.u32 == SYMBOL)
{
- if (expr(bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK)
+ if (expr((TOKENPTR)bf0expr, &bf0exval, &bf0exattr, &bf0esym) != OK)
return ERROR;
bfval2 = (int)bf0exval;
// Do=0, offset=immediate - shift it to place
bfparam2 = (0 << 5);
}
- else if ((*tok >= KW_D0) && (*tok <= KW_D7))
+ else if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7))
{
// Do=1, offset=data register - shift it to place
- bfval2 = ((*(int *)tok - 128));
+ bfval2 = ((*(int *)tok.u32 - 128));
bfparam2 = (1 << 5);
- tok++;
+ tok.u32++;
}
else
return ERROR;
- tok++; // Eat the '}'
+ tok.u32++; // Eat the '}'
return OK;
}
{
uint16_t esiz = *p.wp++;
printf("(%d long) ", (int)esiz);
- p.tk = printexpr(p.tk);
+ p.tk.u32 = printexpr(p.tk.u32);
}
else
{
#define DEF_KW
#include "kwtab.h"
-TOKEN exprbuf[128]; // Expression buffer
+// N.B.: It's perfectly fine to keep exprbuf as an array of TOKENS and to cast
+// to a TOKENPTR where needed. But this works too. :-P
+TOKEN _exprbuf[128]; // Expression buffer
+TOKENPTR exprbuf = (TOKENPTR)_exprbuf; // Expression buffer point
SYM * symbolPtr[1000000]; // Symbol pointers table
static long unused; // For supressing 'write' warnings
char buffer[256]; // Scratch buffer for messages
//
int d_error(char *str)
{
- if (*tok == EOL)
+ if (*tok.u32 == EOL)
return error("error directive encountered - aborting assembling");
else
{
- switch(*tok)
+ switch(*tok.u32)
{
case STRING:
- return error(string[tok[1]]);
+ return error(string[tok.u32[1]]);
break;
default:
return error("error directive encountered--aborting assembly");
//
int d_warn(char *str)
{
- if (*tok == EOL)
+ if (*tok.u32 == EOL)
return warn("WARNING WARNING WARNING");
else
{
- switch(*tok)
+ switch(*tok.u32)
{
case STRING:
- return warn(string[tok[1]]);
+ return warn(string[tok.u32[1]]);
break;
default:
return warn("WARNING WARNING WARNING");
SYM * esym; // External symbol involved in expr.
TOKEN r_expr[EXPRSIZE];
- while (*tok != EOL)
+ while (*tok.u32 != EOL)
{
- switch(*tok)
+ switch(*tok.u32)
{
case STRING:
- sprintf(prntstr, "%s", string[tok[1]]);
+ sprintf(prntstr, "%s", string[tok.u32[1]]);
printf("%s", prntstr);
if (list_fd)
unused = write(list_fd, prntstr, (LONG)strlen(prntstr));
- tok += 2;
+ tok.u32 += 2;
break;
case '/':
formatting = 1;
- if (tok[1] != SYMBOL)
+ if (tok.u32[1] != SYMBOL)
goto token_err;
-// strcpy(prntstr, (char *)tok[2]);
- strcpy(prntstr, string[tok[2]]);
+// strcpy(prntstr, (char *)tok.u32[2]);
+ strcpy(prntstr, string[tok.u32[2]]);
switch(prntstr[0])
{
return ERROR;
}
- tok += 3;
+ tok.u32 += 3;
break;
case ',':
- tok++;
+ tok.u32++;
break;
default:
- if (expr(r_expr, &eval, &eattr, &esym) != OK)
+ if (expr((TOKENPTR)r_expr, &eval, &eattr, &esym) != OK)
goto token_err;
else
{
return ERROR;
}
- if (*tok != SYMBOL)
+ if (*tok.u32 != SYMBOL)
{
error("syntax error; expected symbol");
return ERROR;
}
- ccname = lookup(string[tok[1]], LABEL, 0);
+ ccname = lookup(string[tok.u32[1]], LABEL, 0);
// Make sure symbol is a valid ccdef
if (!ccname || !(ccname->sattre & EQUATEDCC))
if (!rgpu && !rdsp)
return error(".equrundef/.regundef must be defined in .gpu/.dsp section");
- while (*tok != EOL)
+ while (*tok.u32 != EOL)
{
// Skip preceeding or seperating commas (if any)
- if (*tok == ',')
- tok++;
+ if (*tok.u32 == ',')
+ tok.u32++;
// Check we are dealing with a symbol
- if (*tok != SYMBOL)
+ if (*tok.u32 != SYMBOL)
return error("syntax error; expected symbol");
// Lookup and undef if equated register
- regname = lookup(string[tok[1]], LABEL, 0);
+ regname = lookup(string[tok.u32[1]], LABEL, 0);
if (regname && (regname->sattre & EQUATEDREG))
{
}
// Skip over symbol token and address
- tok += 2;
+ tok.u32 += 2;
}
return 0;
// Check to see if we're in BSS, and, if so, throw an error
if (scattr & SBSS)
{
- error("cannot include binary file \"%s\" in BSS section", string[tok[1]]);
+ error("cannot include binary file \"%s\" in BSS section", string[tok.u32[1]]);
return ERROR;
}
- if (*tok != STRING)
+ if (*tok.u32 != STRING)
{
error("syntax error; string missing");
return ERROR;
// Attempt to open the include file in the current directory, then (if that
// failed) try list of include files passed in the enviroment string or by
// the "-d" option.
- if ((fd = open(string[tok[1]], _OPEN_INC)) < 0)
+ if ((fd = open(string[tok.u32[1]], _OPEN_INC)) < 0)
{
for(i=0; nthpath("RMACPATH", i, buf1)!=0; i++)
{
if (fd > 0 && buf1[fd - 1] != SLASHCHAR)
strcat(buf1, SLASHSTRING);
- strcat(buf1, string[tok[1]]);
+ strcat(buf1, string[tok.u32[1]]);
if ((fd = open(buf1, _OPEN_INC)) >= 0)
goto allright;
}
- return error("cannot open: \"%s\"", string[tok[1]]);
+ return error("cannot open: \"%s\"", string[tok.u32[1]]);
}
allright:
pos = lseek(fd, 0L, SEEK_SET);
chcheck(size);
- DEBUG { printf("INCBIN: File '%s' is %li bytes.\n", string[tok[1]], size); }
+ DEBUG { printf("INCBIN: File '%s' is %li bytes.\n", string[tok.u32[1]], size); }
char * fileBuffer = (char *)malloc(size);
bytesRead = read(fd, fileBuffer, size);
if (bytesRead != size)
{
- error("was only able to read %li bytes from binary file (%s, %li bytes)", bytesRead, string[tok[1]], size);
+ error("was only able to read %li bytes from binary file (%s, %li bytes)", bytesRead, string[tok.u32[1]], size);
return ERROR;
}
for(;;)
{
- if (*tok != SYMBOL)
+ if (*tok.u32 != SYMBOL)
return error(em);
- if ((*func)(string[tok[1]]) != OK)
+ if ((*func)(string[tok.u32[1]]) != OK)
break;
- tok += 2;
+ tok.u32 += 2;
- if (*tok == EOL)
+ if (*tok.u32 == EOL)
break;
- if (*tok != ',')
+ if (*tok.u32 != ',')
return error(em);
- tok++;
+ tok.u32++;
}
return 0;
char buf[128];
char buf1[128];
- if (*tok == STRING) // Leave strings ALONE
- fn = string[*++tok];
- else if (*tok == SYMBOL) // Try to append ".s" to symbols
+ if (*tok.u32 == STRING) // Leave strings ALONE
+ fn = string[*++tok.u32];
+ else if (*tok.u32 == SYMBOL) // Try to append ".s" to symbols
{
- strcpy(buf, string[*++tok]);
+ strcpy(buf, string[*++tok.u32]);
fext(buf, ".s", 0);
fn = &buf[0];
}
// Make sure the user didn't try anything like:
// .include equates.s
- if (*++tok != EOL)
+ if (*++tok.u32 != EOL)
return error("extra stuff after filename--enclose it in quotes");
// Attempt to open the include file in the current directory, then (if that
WORD eattr;
uint64_t eval;
- for(; expr(exprbuf, &eval, &eattr, NULL)==OK; ++tok)
+ for(; expr(exprbuf, &eval, &eattr, NULL)==OK; ++tok.u32)
{
if (!(eattr & DEFINED))
return error("forward or undefined .assert");
if (!eval)
return error("assert failure");
- if (*tok != ',')
+ if (*tok.u32 != ',')
break;
}
{
uint64_t eval;
- if (*tok == EOL)
+ if (*tok.u32 == EOL)
return error("PRGFLAGS requires value");
else if (abs_expr(&eval) == OK)
{
SaveSection();
- if (*tok == EOL)
+ if (*tok.u32 == EOL)
eval = 0;
else if (abs_expr(&eval) != OK)
return 0;
}
else
{
- dep_block(eval, siz, 0, (WORD)(DEFINED | ABS), NULL);
+ dep_block(eval, siz, 0, (WORD)(DEFINED | ABS), (TOKENPTR){NULL});
}
at_eol();
//
-// dc.b, dc.w / dc, dc.l, dc.i
+// dc.b, dc.w / dc, dc.l, dc.i, dc.q, dc.d
//
int d_dc(WORD siz)
{
WORD eattr;
uint64_t eval;
- WORD tdb;
- WORD defined;
- uint64_t val64;
uint8_t * p;
if ((scattr & SBSS) != 0)
|| (rdsp && (orgaddr >= 0xF1B000) && (orgaddr <= 0xF1CFFFF))))
warn("depositing LONGs on a non-long address in local RAM");
- for(;; tok++)
+ for(;; tok.u32++)
{
// dc.b 'string' [,] ...
- if (siz == SIZB && (*tok == STRING || *tok == STRINGA8) && (tok[2] == ',' || tok[2] == EOL))
+ if (siz == SIZB && (*tok.u32 == STRING || *tok.u32 == STRINGA8) && (tok.u32[2] == ',' || tok.u32[2] == EOL))
{
- uint32_t i = strlen(string[tok[1]]);
+ uint32_t i = strlen(string[tok.u32[1]]);
if ((challoc - ch_size) < i)
chcheck(i);
- if (*tok == STRING)
+ if (*tok.u32 == STRING)
{
- for(p=string[tok[1]]; *p!=EOS; p++)
+ for(p=string[tok.u32[1]]; *p!=EOS; p++)
D_byte(*p);
}
- else if(*tok == STRINGA8)
+ else if(*tok.u32 == STRINGA8)
{
- for(p=string[tok[1]]; *p!=EOS; p++)
+ for(p=string[tok.u32[1]]; *p!=EOS; p++)
D_byte(strtoa8[*p]);
}
else
error("String format not supported... yet");
}
- tok += 2;
+ tok.u32 += 2;
goto comma;
}
int movei = 0; // MOVEI flag for dc.i
- if (*tok == DOTI)
+ if (*tok.u32 == DOTI)
{
movei = 1;
- tok++;
+ tok.u32++;
siz = SIZL;
}
- if (siz != SIZQ)
- {
// dc.x <expression>
SYM * esym = 0;
if (expr(exprbuf, &eval, &eattr, &esym) != OK)
return 0;
- }
- else
- {
- val64 = *(uint64_t *)(tok);
- tok = tok + 2;
- D_long((uint32_t)(val64 >> 32));
- D_long((uint32_t)val64);
- goto comma;
- }
-
- tdb = (WORD)(eattr & TDB);
- defined = (WORD)(eattr & DEFINED);
+ uint16_t tdb = eattr & TDB;
+ uint16_t defined = eattr & DEFINED;
if ((challoc - ch_size) < 4)
chcheck(4);
D_long(eval);
}
break;
+ case SIZQ:
+ // 64-bit size
+ if (m6502)
+ return error(in_6502mode);
+
+ // Shamus: We only handle DC.Q type stuff, will have to add fixups
+ // and stuff later (maybe... might not be needed...)
+ D_quad(eval);
+ break;
case SIZS:
if (m6502)
return error(in_6502mode);
D_single(eval);
}
+
break;
case SIZD:
if (m6502)
}
else
{
- double vv;
if (tdb)
MarkRelocatable(cursect, sloc, tdb, MDOUBLE, NULL);
- vv = *(double *)&eval;
+ double vv = *(double *)&eval;
D_double(vv);
}
+
break;
case SIZX:
if (m6502)
}
else
{
- float vv;
if (tdb)
MarkRelocatable(cursect, sloc, tdb, MEXTEND, NULL);
- vv = *(double *)&eval;
+ float vv = *(double *)&eval;
D_extend(vv);
}
+
break;
}
-
comma:
- if (*tok != ',')
+ if (*tok.u32 != ',')
break;
}
if (abs_expr(&evalc) != OK)
return 0;
- if (*tok++ != ',')
+ if (*tok.u32++ != ',')
return error("missing comma");
if (expr(exprbuf, &eval, &eattr, NULL) < 0)
for(;;)
{
// Get repeat count (defaults to 1)
- if (*tok == '#')
+ if (*tok.u32 == '#')
{
- ++tok;
+ tok.u32++;
if (abs_expr(&count) != OK)
return 0;
- if (*tok++ != ',')
+ if (*tok.u32++ != ',')
return error(comma_error);
}
else
if (expr(exprbuf, &eval, &eattr, NULL) < 0)
return 0;
- switch ((int)*tok++)
+ switch (*tok.u32++)
{ // Determine size of object to deposit
case DOTB: siz = SIZB; break;
case DOTW: siz = SIZB; break;
case DOTL: siz = SIZL; break;
default:
siz = def_siz;
- tok--;
+ tok.u32--;
break;
}
dep_block((uint32_t)count, siz, (uint32_t)eval, eattr, exprbuf);
- switch ((int)*tok)
+ switch (*tok.u32)
{
case EOL:
return 0;
case ',':
- tok++;
+ tok.u32++;
continue;
default:
return error(comma_error);
//
// Deposit 'count' values of size 'siz' in the current (non-BSS) segment
//
-int dep_block(uint32_t count, WORD siz, uint32_t eval, WORD eattr, TOKEN * exprbuf)
+int dep_block(uint32_t count, WORD siz, uint32_t eval, WORD eattr, TOKENPTR exprbuf)
{
WORD tdb;
WORD defined;
if (m6502)
return error(in_6502mode);
- if (*tok != SYMBOL)
+ if (*tok.u32 != SYMBOL)
return error("missing symbol");
- p = string[tok[1]];
- tok += 2;
+ p = string[tok.u32[1]];
+ tok.u32 += 2;
if (*p == '.') // Cannot .comm a local symbol
return error(locgl_error);
sym->sattr = GLOBAL | COMMON | BSS;
- if (*tok++ != ',')
+ if (*tok.u32++ != ',')
return error(comma_error);
if (abs_expr(&eval) != OK) // Parse size of common region
return ERROR;
}
- // If previous section was dsp or 68000 then we need to reset ORG'd Addresses
+ // If previous section was DSP or 68000 then we need to reset ORG'd Addresses
if (!rgpu)
{
-//printf("Resetting ORG...\n");
orgactive = 0;
orgwarning = 0;
}
-//else printf("NOT resetting ORG!\n");
rgpu = 1; // Set GPU assembly
rdsp = 0; // Unset DSP assembly
if (rgpu || rdsp)
return error("directive forbidden in gpu/dsp mode");
- if (*tok == '#')
+ if (*tok.u32 == '#')
{
- tok++;
+ tok.u32++;
if (abs_expr(&eval) != OK)
return 0;
// Eat the comma, if it's there
- if (*tok == ',')
- tok++;
+ if (*tok.u32 == ',')
+ tok.u32++;
}
for(;;)
{
- if (*tok == SYMBOL)
+ if (*tok.u32 == SYMBOL)
{
- p = string[tok[1]];
+ p = string[tok.u32[1]];
// Set env to either local (dot prefixed) or global scope
env = (*p == '.' ? curenv : 0);
symbol->sattr |= (ABS | DEFINED | EQUATED);
symbol->svalue = (uint32_t)eval;
- tok += 2;
+ tok.u32 += 2;
// 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)
+ switch ((int)*tok.u32)
{
case DOTL:
eval += 2;
case DOTB:
case DOTW:
- tok++;
+ tok.u32++;
}
eval += 2;
}
- else if (*tok >= KW_D0 && *tok <= KW_A7)
+ else if (*tok.u32 >= KW_D0 && *tok.u32 <= KW_A7)
{
if (reglist(&rlist) < 0)
return 0;
}
else
{
- switch ((int)*tok)
+ switch ((int)*tok.u32)
{
case KW_USP:
case KW_SSP:
case KW_SR:
case KW_CCR:
eval += 2;
- tok++;
+ tok.u32++;
break;
case EOL:
return 0;
}
// Eat commas in between each argument, if they exist
- if (*tok == ',')
- tok++;
+ if (*tok.u32 == ',')
+ tok.u32++;
}
}
if (rgpu || rdsp)
return error("directive forbidden in gpu/dsp mode");
- if (*tok == '#')
+ if (*tok.u32 == '#')
{
- tok++;
+ tok.u32++;
if (abs_expr(&eval) != OK)
return 0;
// Eat the comma, if it's there
- if (*tok == ',')
- tok++;
+ if (*tok.u32 == ',')
+ tok.u32++;
}
for(;;)
{
- if (*tok == SYMBOL)
+ if (*tok.u32 == SYMBOL)
{
- symbolName = string[tok[1]];
+ symbolName = string[tok.u32[1]];
// Set env to either local (dot prefixed) or global scope
env = (symbolName[0] == '.' ? curenv : 0);
// Put symbol in "order of definition" list
AddToSymbolDeclarationList(symbol);
- tok += 2;
+ tok.u32 += 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)
+ switch ((int)*tok.u32)
{
case DOTW:
case DOTL:
// 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.u32)
{
case DOTL:
eval += 4;
return error("Symbol missing dot suffix in .cstruct construct");
}
- tok++;
+ tok.u32++;
}
- else if (*tok >= KW_D0 && *tok <= KW_A7)
+ else if (*tok.u32 >= KW_D0 && *tok.u32 <= KW_A7)
{
if (reglist(&rlist) < 0)
return 0;
}
else
{
- switch ((int)*tok)
+ switch ((int)*tok.u32)
{
case KW_USP:
case KW_SSP:
case KW_SR:
case KW_CCR:
eval += 2;
- tok++;
+ tok.u32++;
break;
case EOL:
return 0;
}
// Eat commas in between each argument, if they exist
- if (*tok == ',')
- tok++;
+ if (*tok.u32 == ',')
+ tok.u32++;
}
}
//
int d_opt(void)
{
- while (*tok != EOL)
+ while (*tok.u32 != EOL)
{
- if (*tok == STRING)
+ if (*tok.u32 == STRING)
{
- tok++;
- char * tmpstr = string[*tok++];
+ tok.u32++;
+ char * tmpstr = string[*tok.u32++];
if (ParseOptimization(tmpstr) != OK)
return error("unknown optimization flag '%s'", tmpstr);
#define __DIRECT_H__
#include "rmac.h"
+#include "token.h"
// Exported variables
-extern TOKEN exprbuf[];
+extern TOKENPTR exprbuf;
extern SYM * symbolPtr[];
extern int (* dirtab[])();
extern int largestAlign[];
// Exported functions
void auto_even(void);
-int dep_block(uint32_t, WORD, uint32_t, WORD, TOKEN *);
+int dep_block(uint32_t, WORD, uint32_t, WORD, TOKENPTR);
int eject(void);
int abs_expr(uint64_t *);
int symlist(int(*)());
#define amN am0
#define aNexattr a0exattr
#define aNexval a0exval
-#define aNexpr a0expr
+#define aNexpr (TOKENPTR)a0expr
#define aNixreg a0ixreg
#define aNixsiz a0ixsiz
#define AnESYM a0esym
#define aNexten a0extension
-#define aNbexpr a0bexpr
+#define aNbexpr (TOKENPTR)a0bexpr
#define aNbdexval a0bexval
#define aNbdexattr a0bexattr
#include "eagen0.c"
#define amN am1
#define aNexattr a1exattr
#define aNexval a1exval
-#define aNexpr a1expr
+#define aNexpr (TOKENPTR)a1expr
#define aNixreg a1ixreg
#define aNixsiz a1ixsiz
#define AnESYM a1esym
#define aNexten a1extension
-#define aNbexpr a1bexpr
+#define aNbexpr (TOKENPTR)a1bexpr
#define aNbdexval a1bexval
#define aNbdexattr a1bexattr
#include "eagen0.c"
//
// Report error if not at EOL
+// N.B.: Since this should *never* happen, we can feel free to add whatever
+// diagnostics that will help in tracking down a problem to this function.
//
int at_eol(void)
{
- if (*tok != EOL)
- error("syntax error. expected EOL, found $%X ('%c')", *tok, *tok);
+ if (*tok.u32 != EOL)
+ {
+ error("syntax error. expected EOL, found $%X ('%c')", *tok.u32, *tok.u32);
+ printf("Token = ");
+ DumpToken(*tok.u32);
+ printf("\n");
+ DumpTokenBuffer();
+ }
return 0;
}
const char str_error[] = "missing symbol or string";
// Convert expression to postfix
-static TOKEN * evalTokenBuffer; // Deposit tokens here (this is really a
+static TOKENPTR evalTokenBuffer; // Deposit tokens here (this is really a
// pointer to exprbuf from direct.c)
// (Can also be from others, like
// riscasm.c)
if (expr1() != OK)
return ERROR;
- while (tokenClass[*tok] >= MULT)
+ while (tokenClass[*tok.u32] >= MULT)
{
- t = *tok++;
+ t = *tok.u32++;
if (expr1() != OK)
return ERROR;
- *evalTokenBuffer++ = t;
+ *evalTokenBuffer.u32++ = t;
}
return OK;
//
// Unary operators (detect unary '-')
-// ggn: If expression starts with a plus then also eat it up.
-// For some reason the parser gets confused when this happens and
-// emits a "bad expression".
+// ggn: If expression starts with a plus then also eat it up. For some reason
+// the parser gets confused when this happens and emits a "bad
+// expression".
//
int expr1(void)
{
char * p, * p2;
WORD w;
int j;
- uint64_t * evalTokenBuffer64;
- class = tokenClass[*tok];
+ class = tokenClass[*tok.u32];
- if (*tok == '-' || *tok == '+' || class == UNARY)
+ if (*tok.u32 == '-' || *tok.u32 == '+' || class == UNARY)
{
- t = *tok++;
+ t = *tok.u32++;
if (expr2() != OK)
return ERROR;
if (t == '-')
t = UNMINUS;
- // With leading + we don't have to deposit
- // anything to the buffer because there's
- // no unary '+' nor we have to do anything about it
+ // With leading + we don't have to deposit anything to the buffer
+ // because there's no unary '+' nor we have to do anything about it
if (t != '+')
- *evalTokenBuffer++ = t;
+ *evalTokenBuffer.u32++ = t;
}
else if (class == SUNARY)
{
- switch ((int)*tok++)
+ switch (*tok.u32++)
{
case CR_ABSCOUNT:
- *evalTokenBuffer++ = CONST;
- evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
- *evalTokenBuffer64++ = (LONG)sect[ABS].sloc;
- evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
+ *evalTokenBuffer.u32++ = CONST;
+ *evalTokenBuffer.u64++ = (uint64_t)sect[ABS].sloc;
break;
case CR_TIME:
- *evalTokenBuffer++ = CONST;
- evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
- *evalTokenBuffer64++ = dos_time();
- evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
+ *evalTokenBuffer.u32++ = CONST;
+ *evalTokenBuffer.u64++ = dos_time();
break;
case CR_DATE:
- *evalTokenBuffer++ = CONST;
- evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
- *evalTokenBuffer64++ = dos_date();
- evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
+ *evalTokenBuffer.u32++ = CONST;
+ *evalTokenBuffer.u64++ = dos_date();
break;
- case CR_MACDEF: // ^^macdef <macro-name>
- if (*tok++ != SYMBOL)
+ case CR_MACDEF: // ^^macdef <macro-name>
+ if (*tok.u32++ != SYMBOL)
return error(missym_error);
- p = string[*tok++];
+ p = string[*tok.u32++];
w = (lookup(p, MACRO, 0) == NULL ? 0 : 1);
- evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
- *evalTokenBuffer64++ = (TOKEN)w;
- evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
- *evalTokenBuffer++ = (TOKEN)w;
+ *evalTokenBuffer.u32++ = CONST;
+ *evalTokenBuffer.u64++ = (uint64_t)w;
break;
case CR_DEFINED:
w = DEFINED;
case CR_REFERENCED:
w = REFERENCED;
getsym:
- if (*tok++ != SYMBOL)
+ if (*tok.u32++ != SYMBOL)
return error(missym_error);
- p = string[*tok++];
+ p = string[*tok.u32++];
j = (*p == '.' ? curenv : 0);
w = ((sy = lookup(p, LABEL, j)) != NULL && (sy->sattr & w) ? 1 : 0);
- *evalTokenBuffer++ = CONST;
- uint64_t *evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
- *evalTokenBuffer64++ = (TOKEN)w;
- evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
+ *evalTokenBuffer.u32++ = CONST;
+ *evalTokenBuffer.u64++ = (uint64_t)w;
break;
case CR_STREQ:
- if (*tok != SYMBOL && *tok != STRING)
+ if (*tok.u32 != SYMBOL && *tok.u32 != STRING)
return error(str_error);
- p = string[tok[1]];
- tok +=2;
+ p = string[tok.u32[1]];
+ tok.u32 +=2;
- if (*tok++ != ',')
+ if (*tok.u32++ != ',')
return error(comma_error);
- if (*tok != SYMBOL && *tok != STRING)
+ if (*tok.u32 != SYMBOL && *tok.u32 != STRING)
return error(str_error);
- p2 = string[tok[1]];
- tok += 2;
+ p2 = string[tok.u32[1]];
+ tok.u32 += 2;
w = (WORD)(!strcmp(p, p2));
- *evalTokenBuffer++ = CONST;
- evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
- *evalTokenBuffer64++ = (TOKEN)w;
- evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
+ *evalTokenBuffer.u32++ = CONST;
+ *evalTokenBuffer.u64++ = (uint64_t)w;
break;
}
}
char * p;
SYM * sy;
int j;
- uint64_t * evalTokenBuffer64;
- uint64_t * tok64;
- switch ((int)*tok++)
+ switch (*tok.u32++)
{
case CONST:
- *evalTokenBuffer++ = CONST;
- evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
- tok64 = (uint64_t *)tok;
- *evalTokenBuffer64++ = *tok64++;
- tok = (TOKEN *)tok64;
- evalTokenBuffer = (TOKEN *)evalTokenBuffer64;
+ *evalTokenBuffer.u32++ = CONST;
+ *evalTokenBuffer.u64++ = *tok.u64++;
break;
case FCONST:
- *evalTokenBuffer++ = FCONST;
- evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
- tok64 = (uint64_t *)tok;
- *evalTokenBuffer64++ = *tok64++;
- tok = (TOKEN *)tok64;
- evalTokenBuffer = (TOKEN *)evalTokenBuffer64;
+ *evalTokenBuffer.u32++ = FCONST;
+ *evalTokenBuffer.u64++ = *tok.u64++;
break;
case SYMBOL:
- p = string[*tok++];
+ p = string[*tok.u32++];
j = (*p == '.' ? curenv : 0);
sy = lookup(p, LABEL, j);
warn("equated symbol \'%s\' cannot be used in register bank 1", sy->sname);
}
- *evalTokenBuffer++ = SYMBOL;
- *evalTokenBuffer++ = symbolNum;
+ *evalTokenBuffer.u32++ = SYMBOL;
+ *evalTokenBuffer.u32++ = symbolNum;
symbolPtr[symbolNum] = sy;
symbolNum++;
break;
case STRING:
- *evalTokenBuffer++ = CONST;
- uint64_t *evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
- *evalTokenBuffer64++ = str_value(string[*tok++]);
- evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
+ *evalTokenBuffer.u32++ = CONST;
+ *evalTokenBuffer.u64++ = str_value(string[*tok.u32++]);
break;
case '(':
if (expr0() != OK)
return ERROR;
- if (*tok++ != ')')
+ if (*tok.u32++ != ')')
return error("missing closing parenthesis ')'");
break;
if (expr0() != OK)
return ERROR;
- if (*tok++ != ']')
+ if (*tok.u32++ != ']')
return error("missing closing bracket ']'");
break;
case '$':
- *evalTokenBuffer++ = ACONST; // Attributed const
- *evalTokenBuffer++ = sloc; // Current location
- *evalTokenBuffer++ = cursect | DEFINED; // Store attribs
+ *evalTokenBuffer.u32++ = ACONST; // Attributed const
+ *evalTokenBuffer.u32++ = sloc; // Current location
+ *evalTokenBuffer.u32++ = cursect | DEFINED; // Store attribs
break;
case '*':
- *evalTokenBuffer++ = ACONST; // Attributed const
+ *evalTokenBuffer.u32++ = ACONST; // Attributed const
// pcloc == location at start of line
- *evalTokenBuffer++ = (orgactive ? orgaddr : pcloc);
+ *evalTokenBuffer.u32++ = (orgactive ? orgaddr : pcloc);
// '*' takes attributes of current section, not ABS!
- *evalTokenBuffer++ = cursect | DEFINED;
+ *evalTokenBuffer.u32++ = cursect | DEFINED;
break;
case '{':
if (expr0() != OK) // Eat up first parameter (register or immediate)
return ERROR;
- if (*tok++ != ':') // Demand a ':' there
+ if (*tok.u32++ != ':') // Demand a ':' there
return error("missing colon ':'");
if (expr0() != OK) // Eat up second parameter (register or immediate)
return ERROR;
- if (*tok++ != '}')
+ if (*tok.u32++ != '}')
return error("missing closing brace '}'");
break;
//
// Recursive-descent expression analyzer (with some simple speed hacks)
//
-int expr(TOKEN * otk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym)
+int expr(TOKENPTR otk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym)
{
// Passed in values (once derefenced, that is) can all be zero. They are
// there so that the expression analyzer can fill them in as needed. The
// Also set in various other places too (riscasm.c,
// e.g.)
-//printf("expr(): tokens 0-2: %i %i %i (%c %c %c); tc[2] = %i\n", tok[0], tok[1], tok[2], tok[0], tok[1], tok[2], tokenClass[tok[2]]);
+//printf("expr(): tokens 0-2: %i %i %i (%c %c %c); tc[2] = %i\n", tok.u32[0], tok.u32[1], tok.u32[2], tok.u32[0], tok.u32[1], tok.u32[2], tokenClass[tok.u32[2]]);
// Optimize for single constant or single symbol.
// Shamus: Subtle bug here. EOL token is 101; if you have a constant token
// followed by the value 101, it will trigger a bad evaluation here.
// This is probably a really bad assumption to be making here...!
- // (assuming tok[1] == EOL is a single token that is)
+ // (assuming tok.u32[1] == EOL is a single token that is)
// Seems that even other tokens (SUNARY type) can fuck this up too.
-// if ((tok[1] == EOL)
- if ((tok[1] == EOL && ((tok[0] != CONST || tok[0] != FCONST) && tokenClass[tok[0]] != SUNARY))
-// || (((*tok == CONST || *tok == FCONST || *tok == SYMBOL) || (*tok >= KW_R0 && *tok <= KW_R31))
-// && (tokenClass[tok[2]] < UNARY)))
- || (((tok[0] == SYMBOL) || (tok[0] >= KW_R0 && tok[0] <= KW_R31))
- && (tokenClass[tok[2]] < UNARY))
- || ((tok[0] == CONST || tok[0] == FCONST) && (tokenClass[tok[3]] < UNARY))
+#if 0
+// if ((tok.u32[1] == EOL)
+ if ((tok.u32[1] == EOL && ((tok.u32[0] != CONST || tok.u32[0] != FCONST) && tokenClass[tok.u32[0]] != SUNARY))
+// || (((*tok.u32 == CONST || *tok.u32 == FCONST || *tok.u32 == SYMBOL) || (*tok.u32 >= KW_R0 && *tok.u32 <= KW_R31))
+// && (tokenClass[tok.u32[2]] < UNARY)))
+ || (((tok.u32[0] == SYMBOL) || (tok.u32[0] >= KW_R0 && tok.u32[0] <= KW_R31))
+ && (tokenClass[tok.u32[2]] < UNARY))
+ || ((tok.u32[0] == CONST || tok.u32[0] == FCONST) && (tokenClass[tok.u32[3]] < UNARY))
+ )
+#else
+// Shamus: Seems to me that this could be greatly simplified by 1st checking if the first token is a multibyte token, *then* checking if there's an EOL after it depending on the actual length of the token (multiple vs. single). Otherwise, we have the horror show that is the following:
+ if ((tok.u32[1] == EOL
+ && (tok.u32[0] != CONST && tokenClass[tok.u32[0]] != SUNARY))
+ || (((tok.u32[0] == SYMBOL)
+ || (tok.u32[0] >= KW_R0 && tok.u32[0] <= KW_R31))
+ && (tokenClass[tok.u32[2]] < UNARY))
+ || ((tok.u32[0] == CONST) && (tokenClass[tok.u32[3]] < UNARY))
)
+// Shamus: Yes, you can parse that out and make some kind of sense of it, but damn, it takes a while to get it and understand the subtle bugs that result from not being careful about what you're checking; especially vis-a-vis niavely checking tok.u32[1] for an EOL. O_o
+#endif
{
- if (*tok >= KW_R0 && *tok <= KW_R31)
+ if (*tok.u32 >= KW_R0 && *tok.u32 <= KW_R31)
{
- *evalTokenBuffer++ = CONST;
- uint64_t *evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
- *evalTokenBuffer64++ = *a_value = (*tok - KW_R0);
- evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
+ *evalTokenBuffer.u32++ = CONST;
+ *evalTokenBuffer.u64++ = *a_value = (*tok.u32 - KW_R0);
*a_attr = ABS | DEFINED;
if (a_esym != NULL)
*a_esym = NULL;
- tok++;
+ tok.u32++;
}
- else if (*tok == CONST)
+ else if (*tok.u32 == CONST)
{
- *evalTokenBuffer++ = CONST;
- uint64_t *evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
- uint64_t *tok64 = (uint64_t *)&tok[1];
- *evalTokenBuffer64++ = *tok64++;
- evalTokenBuffer = (TOKEN *)evalTokenBuffer64;
- *a_value = tok[1];
+ *evalTokenBuffer.u32++ = *tok.u32++;
+ *evalTokenBuffer.u64++ = *a_value = *tok.u64++;
*a_attr = ABS | DEFINED;
if (a_esym != NULL)
*a_esym = NULL;
- tok += 3;
-//printf("Quick eval in expr(): CONST = %i, tokenClass[tok[2]] = %i\n", *a_value, tokenClass[*tok]);
+//printf("Quick eval in expr(): CONST = %i, tokenClass[tok.u32[2]] = %i\n", *a_value, tokenClass[*tok.u32]);
}
- else if (*tok == FCONST)
+// Not sure that removing float constant here is going to break anything and/or
+// make things significantly slower, but having this here seems to cause the
+// complexity of the check to get to this part of the parse to go through the
+// roof, and dammit, I just don't feel like fighting that fight ATM. :-P
+#if 0
+ else if (*tok.u32 == FCONST)
{
- *evalTokenBuffer++ = FCONST;
- *((double *)evalTokenBuffer) = *((double *)&tok[1]);
- evalTokenBuffer += 2;
- //*(double *)evalTokenBuffer++ = tok[2];
- *a_value = *((uint64_t *)&tok[1]);
+ *evalTokenBuffer.u32++ = *tok.u32++;
+ *evalTokenBuffer.u64++ = *a_value = *tok.u64++;
*a_attr = ABS | DEFINED | FLOAT;
if (a_esym != NULL)
*a_esym = NULL;
- tok += 3;
-//printf("Quick eval in expr(): CONST = %i, tokenClass[tok[2]] = %i\n", *a_value, tokenClass[*tok]);
+//printf("Quick eval in expr(): CONST = %i, tokenClass[tok.u32[2]] = %i\n", *a_value, tokenClass[*tok.u32]);
}
- else if (*tok == '*')
+#endif
+ else if (*tok.u32 == '*')
{
- *evalTokenBuffer++ = CONST;
- uint64_t *evalTokenBuffer64 = (uint64_t *)evalTokenBuffer;
+ *evalTokenBuffer.u32++ = CONST;
if (orgactive)
- *evalTokenBuffer64++ = *a_value = orgaddr;
+ *evalTokenBuffer.u64++ = *a_value = orgaddr;
else
- *evalTokenBuffer64++ = *a_value = pcloc;
- evalTokenBuffer = (uint32_t *)evalTokenBuffer64;
+ *evalTokenBuffer.u64++ = *a_value = pcloc;
// '*' takes attributes of current section, not ABS!
*a_attr = cursect | DEFINED;
if (a_esym != NULL)
*a_esym = NULL;
- tok++;
+ tok.u32++;
}
- else if (*tok == STRING || *tok == SYMBOL)
+ else if (*tok.u32 == STRING || *tok.u32 == SYMBOL)
{
- p = string[tok[1]];
+ p = string[tok.u32[1]];
j = (*p == '.' ? curenv : 0);
symbol = lookup(p, LABEL, j);
#if 0
warn("equated symbol '%s' cannot be used in register bank 1", symbol->sname);
}
- *evalTokenBuffer++ = SYMBOL;
+ *evalTokenBuffer.u32++ = SYMBOL;
#if 0
*evalTokenBuffer++ = (TOKEN)symbol;
#else
that's already available, like the symbol "order defined" table (which needs to
be converted from a linked list into an array).
*/
- *evalTokenBuffer++ = symbolNum;
+ *evalTokenBuffer.u32++ = symbolNum;
symbolPtr[symbolNum] = symbol;
symbolNum++;
#endif
&& a_esym != NULL)
*a_esym = symbol;
- tok += 2;
+ tok.u32 += 2;
}
else
{
// Unknown type here... Alert the user!,
error("undefined RISC register in expression");
// Prevent spurious error reporting...
- tok++;
+ tok.u32++;
return ERROR;
}
- *evalTokenBuffer++ = ENDEXPR;
+ *evalTokenBuffer.u32++ = ENDEXPR;
return OK;
}
if (expr0() != OK)
return ERROR;
- *evalTokenBuffer++ = ENDEXPR;
+ *evalTokenBuffer.u32++ = ENDEXPR;
return evexpr(otk, a_value, a_attr, a_esym);
}
// Evaluate expression.
// If the expression involves only ONE external symbol, the expression is
// UNDEFINED, but it's value includes everything but the symbol value, and
-// `a_esym' is set to the external symbol.
+// 'a_esym' is set to the external symbol.
//
-int evexpr(TOKEN * tk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym)
+int evexpr(TOKENPTR tk, uint64_t * a_value, WORD * a_attr, SYM ** a_esym)
{
WORD attr, attr2;
SYM * sy;
WORD * sattr = evattr;
SYM * esym = NULL; // No external symbol involved
WORD sym_seg = 0;
- uint64_t *tk64;
- while (*tk != ENDEXPR)
+ while (*tk.u32 != ENDEXPR)
{
- switch ((int)*tk++)
+ switch ((int)*tk.u32++)
{
case SYMBOL:
//printf("evexpr(): SYMBOL\n");
- sy = symbolPtr[*tk++];
+ sy = symbolPtr[*tk.u32++];
sy->sattr |= REFERENCED; // Set "referenced" bit
if (!(sy->sattr & DEFINED))
sym_seg = (WORD)(sy->sattr & TDB);
break;
case CONST:
- tk64 = (uint64_t *)tk;
- *++sval = *tk64++;
- tk = (TOKEN *)tk64;
+ *++sval = *tk.u64++;
//printf("evexpr(): CONST = %lX\n", *sval);
*++sattr = ABS | DEFINED; // Push simple attribs
break;
case FCONST:
-//printf("evexpr(): CONST = %i\n", *tk);
- *((double *)sval) = *((double *)tk);
- tk += 2;
+//printf("evexpr(): FCONST = %i\n", *tk.u32);
+ *((double *)sval) = *((double *)tk.u32);
+ tk.u32 += 2;
*++sattr = ABS | DEFINED | FLOAT; // Push simple attribs
break;
case ACONST:
-//printf("evexpr(): ACONST = %i\n", *tk);
- *++sval = *tk++; // Push value
- *++sattr = (WORD)*tk++; // Push attribs
+//printf("evexpr(): ACONST = %i\n", *tk.u32);
+ *++sval = *tk.u32++; // Push value
+ *++sattr = (WORD)*tk.u32++; // Push attribs
break;
// Binary "+" and "-" matrix:
}
else
{
- *sval += sval[1]; // Compute value
+ *sval += sval[1]; // Compute value
}
//printf("%i\n", *sval);
}
else
{
- *sval -= sval[1]; // Compute value
+ *sval -= sval[1]; // Compute value
}
//printf("%i\n", *sval);
}
else
{
- *sval = -(int)*sval;
- *sattr = ABS | DEFINED; // Expr becomes absolute
+ *sval = -(int)*sval;
+ *sattr = ABS | DEFINED; // Expr becomes absolute
}
break;
case '!':
}
else
{
- *sval = *sval <= sval[1];
+ *sval = *sval <= sval[1];
}
*sattr = ABS | DEFINED;
}
else if (attr == 0)
{
- *sval = *sval >= sval[1];
+ *sval = *sval >= sval[1];
}
else
-
- *sattr = ABS | DEFINED;
+ *sattr = ABS | DEFINED;
break;
case '>':
*sval = *dst > *src;
}
else
-= {
- *sval = *sval > sval[1];
+ {
+ *sval = *sval > sval[1];
}
*sattr = ABS | DEFINED;
// Extract float attributes from both terms and pack them
// into a single value
- attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) > >1);
+ attr = sattr[0] & FLOAT | ((sattr[1] & FLOAT) >> 1);
if (attr == (FLOAT | (FLOAT >> 1)))
{
}
else
{
- *sval = *sval < sval[1];
+ *sval = *sval < sval[1];
}
*sattr = ABS | DEFINED;
}
else
{
- *sval = *sval != sval[1];
+ *sval = *sval != sval[1];
}
*sattr = ABS | DEFINED;
}
else
{
- *sval = *sval == sval[1];
+ *sval = *sval == sval[1];
}
*sattr = ABS | DEFINED;
break;
- // All other binary operators must have two ABS items
- // to work with. They all produce an ABS value.
+ // All other binary operators must have two ABS items to work with.
+ // They all produce an ABS value.
default:
//printf("evexpr(): default\n");
// GH - Removed for v1.0.15 as part of the fix for indexed loads.
//if ((*sattr & (TEXT|DATA|BSS)) || (*--sattr & (TEXT|DATA|BSS)))
//error(seg_error);
- switch ((int)tk[-1])
+ switch ((int)tk.u32[-1])
{
case '*':
sval--;
}
else
{
- *sval *= sval[1];
+ *sval *= sval[1];
}
//printf("%i\n", *sval);
// Float / Float
double * dst = (double *)sval;
double * src = (double *)(sval + 1);
+
if (*src == 0)
return error("divide by zero");
+
*dst = *dst / *src;
}
else if (attr == FLOAT)
// Float / Int
double * dst = (double *)sval;
uint64_t * src = (uint64_t *)(sval + 1);
+
if (*src == 0)
return error("divide by zero");
+
*dst = *dst / *src;
}
else if (attr == FLOAT >> 1)
// Int / Float
uint64_t * dst=(uint64_t *)sval;
double * src=(double *)(sval + 1);
+
if (*src == 0)
return error("divide by zero");
+
*(double *)dst = *dst / *src;
}
else
if (sval[1] == 0)
return error("divide by zero");
//printf("--> N/N: %i / %i = ", sval[0], sval[1]);
- // Compiler is picky here: Without casting these, it discards
- // the sign if dividing a negative # by a positive one,
- // creating a bad result. :-/
- // Definitely a side effect of using uint32_ts intead of ints.
- *sval = (int32_t)sval[0] / (int32_t)sval[1];
+
+ // Compiler is picky here: Without casting these, it
+ // discards the sign if dividing a negative # by a
+ // positive one, creating a bad result. :-/
+ // Definitely a side effect of using uint32_ts intead of
+ // ints.
+ *sval = (int32_t)sval[0] / (int32_t)sval[1];
}
*sattr = ABS | DEFINED; // Expr becomes absolute
case '%':
sval--;
sattr--; // Pop attrib
+
if ((*sattr | sattr[1]) & FLOAT)
return error("floating point numbers not allowed with operator '%'.");
case SHL:
sval--;
sattr--; // Pop attrib
+
if ((*sattr | sattr[1]) & FLOAT)
return error("floating point numbers not allowed with operator '<<'.");
+
*sattr = ABS | DEFINED; // Expr becomes absolute
*sval <<= sval[1];
break;
case SHR:
sval--;
sattr--; // Pop attrib
+
if ((*sattr | sattr[1]) & FLOAT)
return error("floating point numbers not allowed with operator '>>'.");
+
*sattr = ABS | DEFINED; // Expr becomes absolute
*sval >>= sval[1];
break;
case '&':
sval--;
sattr--; // Pop attrib
+
if ((*sattr | sattr[1]) & FLOAT)
return error("floating point numbers not allowed with operator '&'.");
+
*sattr = ABS | DEFINED; // Expr becomes absolute
*sval &= sval[1];
break;
case '^':
sval--;
sattr--; // Pop attrib
+
if ((*sattr | sattr[1]) & FLOAT)
return error("floating point numbers not allowed with operator '^'.");
+
*sattr = ABS | DEFINED; // Expr becomes absolute
*sval ^= sval[1];
break;
case '|':
sval--;
sattr--; // Pop attrib
+
if ((*sattr | sattr[1]) & FLOAT)
return error("floating point numbers not allowed with operator '|'.");
+
*sattr = ABS | DEFINED; // Expr becomes absolute
*sval |= sval[1];
break;
void InitExpression(void);
int expr1(void);
int expr2(void);
-int expr(TOKEN *, uint64_t *, WORD *, SYM **);
-int evexpr(TOKEN *, uint64_t *, WORD *, SYM **);
+int expr(TOKENPTR, uint64_t *, WORD *, SYM **);
+int evexpr(TOKENPTR, uint64_t *, WORD *, SYM **);
#endif // __EXPR_H__
int ejectok;
ejectok = 1;
- if (*tok == '-')
+ if (*tok.u32 == '-')
{
ejectok = 0;
- ++tok;
+ ++tok.u32;
}
- if (*tok != STRING)
+ if (*tok.u32 != STRING)
return error("missing string");
-// strcpy(subttl, (char *)tok[1]);
- strcpy(subttl, string[tok[1]]);
+// strcpy(subttl, (char *)tok.u32[1]);
+ strcpy(subttl, string[tok.u32[1]]);
- tok += 2;
+ tok.u32 += 2;
// Always eject on pages 2+
if (ejectok && (subflag || pageno > 1))
//
int d_title(void)
{
- if (*tok != STRING)
+ if (*tok.u32 != STRING)
return error("missing string");
-// strcpy(title, (char*)tok[1]);
- strcpy(title, string[tok[1]]);
- tok += 2;
+// strcpy(title, (char*)tok.u32[1]);
+ strcpy(title, string[tok.u32[1]]);
+ tok.u32 += 2;
if (pageno > 1)
{
}
else
{
- AddFixup(FU_QUICK, sloc, a0expr);
+ AddFixup(FU_QUICK, sloc, (TOKENPTR)a0expr);
D_word(inst);
}
}
else
{
- AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
+ AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, (TOKENPTR)a1expr);
D_word(0);
}
siz = siz;
if (am0 == DREG && am1 == DREG)
- m = 0x0040; // Dn,Dn
+ m = 0x0040; // Dn,Dn
else if (am0 == AREG && am1 == AREG)
- m = 0x0048; // An,An
+ m = 0x0048; // An,An
else
{
if (am0 == AREG)
- { // Dn,An or An,Dn
- m = a1reg; // Get AREG into a1reg
+ { // Dn,An or An,Dn
+ m = a1reg; // Get AREG into a1reg
a1reg = a0reg;
a0reg = m;
}
int m_move30(WORD inst, WORD size)
{
int siz = (int)size;
- // TODO: is extra_addressing necessary/correct?
+ // TODO: is extra_addressing necessary/correct?
//inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg | extra_addressing[am0 - ABASE];
- inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg;
+ inst |= siz_12[siz] | reg_9[a1reg & 7] | a0reg;
D_word(inst);
// Arrange for future fixup
if (!(a0exattr & DEFINED))
{
- AddFixup(FU_BYTE | FU_SEXT, sloc + 1, a0expr);
+ AddFixup(FU_BYTE | FU_SEXT, sloc + 1, (TOKENPTR)a0expr);
a0exval = 0;
}
else if ((uint32_t)a0exval + 0x100 >= 0x200)
int m_movep(WORD inst, WORD siz)
{
// Tell ea0gen to lay off the 0(a0) optimisations on this one
- movep = 1;
+ movep = 1;
if (siz == SIZL)
inst |= 0x0040;
ea0gen(siz);
}
- movep = 0;
+ movep = 0;
return 0;
}
if (siz == SIZB || siz == SIZS)
{
// .B
- AddFixup(FU_BBRA | FU_PCREL | FU_SEXT, sloc, a0expr);
+ AddFixup(FU_BBRA | FU_PCREL | FU_SEXT, sloc, (TOKENPTR)a0expr);
D_word(inst);
return OK;
}
{
// .W
D_word(inst);
- AddFixup(FU_WORD | FU_PCREL | FU_LBRA | FU_ISBRA, sloc, a0expr);
+ AddFixup(FU_WORD | FU_PCREL | FU_LBRA | FU_ISBRA, sloc, (TOKENPTR)a0expr);
D_word(0);
}
}
else
{
- AddFixup(FU_QUICK, sloc, a0expr);
+ AddFixup(FU_QUICK, sloc, (TOKENPTR)a0expr);
D_word(inst);
}
if (siz == SIZL)
inst |= 0x0040;
- if (*tok == '#')
+ if (*tok.u32 == '#')
{
// Handle #<expr>, ea
- tok++;
+ tok.u32++;
if (abs_expr(&eval) != OK)
return OK;
goto immed1;
}
- if ((*tok >= KW_D0) && (*tok <= KW_A7))
+ if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_A7))
{
// <rlist>, ea
if (reglist(&rmask) < 0)
return OK;
immed1:
- if (*tok++ != ',')
+ if (*tok.u32++ != ',')
return error("missing comma");
if (amode(0) < 0)
inst |= 0x0400 | am0 | a0reg;
- if (*tok++ != ',')
+ if (*tok.u32++ != ',')
return error("missing comma");
- if (*tok == EOL)
+ if (*tok.u32 == EOL)
return error("missing register list");
- if (*tok == '#')
+ if (*tok.u32 == '#')
{
// ea, #<expr>
- tok++;
+ tok.u32++;
if (abs_expr(&eval) != OK)
return OK;
else
{
// .L
- AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
+ AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, (TOKENPTR)a0expr);
D_word(inst);
return OK;
}
//
int m_bfop(WORD inst, WORD siz)
{
- if ((bfval1 > 31) || (bfval1 < 0))
- return error("bfxxx offset: immediate value must be between 0 and 31");
+ if ((bfval1 > 31) || (bfval1 < 0))
+ return error("bfxxx offset: immediate value must be between 0 and 31");
// First instruction word - just the opcode and first EA
- // Note: both am1 is ORed because solely of bfins - maybe it's a good idea to make a dedicated function for it?
+ // Note: both am1 is ORed because solely of bfins - maybe it's a good idea
+ // to make a dedicated function for it?
if (am1 == AM_NONE)
- {
+ {
am1 = 0;
- }
- else
- {
- if (bfval2 > 31 || bfval2 < 0)
- return error("bfxxx width: immediate value must be between 0 and 31");
-
- // For Dw both immediate and register number are stuffed
- // into the same field O_o
- bfparam2 = (bfval2 << 0);
- }
-
- if (bfparam1 == 0)
- {
- bfparam1 = (bfval1 << 6);
- }
- else
- {
- bfparam1 = bfval1 << 12;
- }
+ }
+ else
+ {
+ if (bfval2 > 31 || bfval2 < 0)
+ return error("bfxxx width: immediate value must be between 0 and 31");
+
+ // For Dw both immediate and register number are stuffed
+ // into the same field O_o
+ bfparam2 = (bfval2 << 0);
+ }
+
+ if (bfparam1 == 0)
+ bfparam1 = (bfval1 << 6);
+ else
+ bfparam1 = bfval1 << 12;
D_word((inst | am0 | a0reg | am1 | a1reg));
ea0gen(siz); // Generate EA
// Second instruction word - Dest register (if exists), Do, Offset, Dw, Width
-
inst = bfparam1 | bfparam2;
if (am1 == DREG)
else
return error(undef_error);
- ea1gen(siz);
+ ea1gen(siz);
return OK;
}
// Dc
- if ((*tok < KW_D0) && (*tok > KW_D7))
+ if ((*tok.u32 < KW_D0) && (*tok.u32 > KW_D7))
return error("CAS accepts only data registers");
- inst2 = (*tok++) & 7;
+ inst2 = (*tok.u32++) & 7;
- if (*tok++ != ',')
+ if (*tok.u32++ != ',')
return error("missing comma");
// Du
- if ((*tok < KW_D0) && (*tok > KW_D7))
+ if ((*tok.u32 < KW_D0) && (*tok.u32 > KW_D7))
return error("CAS accepts only data registers");
- inst2 |= ((*tok++) & 7) << 6;
+ inst2 |= ((*tok.u32++) & 7) << 6;
- if (*tok++ != ',')
+ if (*tok.u32++ != ',')
return error("missing comma");
// ea
if (modes > 1)
return error("too many ea fields");
- if (*tok!=EOL)
+ if (*tok.u32 != EOL)
return error("extra (unexpected) text found");
// Reject invalud ea modes
}
// Dc1
- if ((*tok < KW_D0) && (*tok > KW_D7))
+ if ((*tok.u32 < KW_D0) && (*tok.u32 > KW_D7))
return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
- inst2 = (*tok++) & 7;
+ inst2 = (*tok.u32++) & 7;
- if (*tok++ != ':')
+ if (*tok.u32++ != ':')
return error("missing colon");
// Dc2
- if ((*tok < KW_D0) && (*tok > KW_D7))
+ if ((*tok.u32 < KW_D0) && (*tok.u32 > KW_D7))
return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
- inst3 = (*tok++) & 7;
+ inst3 = (*tok.u32++) & 7;
- if (*tok++ != ',')
+ if (*tok.u32++ != ',')
return error("missing comma");
// Du1
- if ((*tok < KW_D0) && (*tok > KW_D7))
+ if ((*tok.u32 < KW_D0) && (*tok.u32 > KW_D7))
return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
- inst2 |= ((*tok++) & 7) << 6;
+ inst2 |= ((*tok.u32++) & 7) << 6;
- if (*tok++ != ':')
+ if (*tok.u32++ != ':')
return error("missing colon");
// Du2
- if ((*tok < KW_D0) && (*tok > KW_D7))
+ if ((*tok.u32 < KW_D0) && (*tok.u32 > KW_D7))
return error("CAS2 accepts only data registers for Dx1:Dx2 pairs");
- inst3 |= ((*tok++) & 7) << 6;
+ inst3 |= ((*tok.u32++) & 7) << 6;
- if (*tok++ != ',')
+ if (*tok.u32++ != ',')
return error("missing comma");
// Rn1
- if (*tok++ != '(')
+ if (*tok.u32++ != '(')
return error("missing (");
- if ((*tok >= KW_D0) && (*tok <= KW_D7))
- inst2 |= (((*tok++) & 7) << 12) | (0 << 15);
- else if ((*tok >= KW_A0) && (*tok <= KW_A7))
- inst2 |= (((*tok++) & 7) << 12) | (1 << 15);
+ if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7))
+ inst2 |= (((*tok.u32++) & 7) << 12) | (0 << 15);
+ else if ((*tok.u32 >= KW_A0) && (*tok.u32 <= KW_A7))
+ inst2 |= (((*tok.u32++) & 7) << 12) | (1 << 15);
else
return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
- if (*tok++ != ')')
+ if (*tok.u32++ != ')')
return error("missing (");
- if (*tok++ != ':')
+ if (*tok.u32++ != ':')
return error("missing colon");
// Rn2
- if (*tok++ != '(')
+ if (*tok.u32++ != '(')
return error("missing (");
- if ((*tok >= KW_D0) && (*tok <= KW_D7))
- inst3 |= (((*tok++) & 7) << 12) | (0 << 15);
- else if ((*tok >= KW_A0) && (*tok <= KW_A7))
- inst3 |= (((*tok++) & 7) << 12) | (1 << 15);
+ if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7))
+ inst3 |= (((*tok.u32++) & 7) << 12) | (0 << 15);
+ else if ((*tok.u32 >= KW_A0) && (*tok.u32 <= KW_A7))
+ inst3 |= (((*tok.u32++) & 7) << 12) | (1 << 15);
else
return error("CAS accepts either data or address registers for Rn1:Rn2 pair");
- if (*tok++ != ')')
+ if (*tok.u32++ != ')')
return error("missing (");
- if (*tok != EOL)
+ if (*tok.u32 != EOL)
return error("extra (unexpected) text found");
D_word(inst);
if (siz == SIZL)
{
// .L
- D_word(inst);
- AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, a0expr);
- D_long(0);
+ D_word(inst);
+ AddFixup(FU_LONG | FU_PCREL | FU_SEXT, sloc, (TOKENPTR)a0expr);
+ D_long(0);
return OK;
}
else
{
// .W
D_word(inst);
- AddFixup(FU_WORD | FU_PCREL | FU_SEXT, sloc, a0expr);
+ AddFixup(FU_WORD | FU_PCREL | FU_SEXT, sloc, (TOKENPTR)a0expr);
D_word(0);
}
//
int m_cpdbr(WORD inst, WORD siz)
{
- CHECK00;
+ CHECK00;
- uint32_t v;
- WORD condition = inst & 0x1f; // Grab condition sneakily placed in the lower 5 bits of inst
- inst &= 0xffe0; // And then mask them out - you ain't seen me, roit?
+ uint32_t v;
+ WORD condition = inst & 0x1F; // Grab condition sneakily placed in the lower 5 bits of inst
+ inst &= 0xFFE0; // And then mask them out - you ain't seen me, roit?
- inst |= (1 << 9); // Bolt on FPU id
- inst |= a0reg;
+ inst |= (1 << 9); // Bolt on FPU id
+ inst |= a0reg;
- D_word(inst);
+ D_word(inst);
- D_word(condition);
+ D_word(condition);
- if (a1exattr & DEFINED)
- {
- if ((a1exattr & TDB) != cursect)
- return error(rel_error);
+ if (a1exattr & DEFINED)
+ {
+ if ((a1exattr & TDB) != cursect)
+ return error(rel_error);
v = (uint32_t)a1exval - sloc;
- if (v + 0x8000 > 0x10000)
- return error(range_error);
-
- D_word(v);
- }
- else
- {
- AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
- D_word(0);
- }
+ if (v + 0x8000 > 0x10000)
+ return error(range_error);
- return OK;
+ D_word(v);
+ }
+ else
+ {
+ AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, (TOKENPTR)a1expr);
+ D_word(0);
+ }
+ return OK;
}
//
int m_pack(WORD inst, WORD siz)
{
- CHECK00;
+ CHECK00;
- if (siz != SIZN)
- return error("bad size suffix");
+ if (siz != SIZN)
+ return error("bad size suffix");
- if (*tok >= KW_D0 && *tok <= KW_D7)
- {
- // Dx,Dy,#<adjustment>
- inst |= (0 << 3); // R/M
- inst |= (*tok++ & 7);
- if (*tok != ',' && tok[2] != ',')
- return error("missing comma");
- if (tok[1] < KW_D0 && tok[1] > KW_D7)
- return error(syntax_error);
- inst |= ((tok[1] & 7)<<9);
- tok = tok + 3;
- D_word(inst);
- // Fall through for adjustment (common in both valid cases)
- }
- else if (*tok == '-')
- {
- // -(Ax),-(Ay),#<adjustment>
- inst |= (1 << 3); // R/M
- tok++; // eat the minus
- if ((*tok != '(') && (tok[2]!=')') && (tok[3]!=',') && (tok[4] != '-') && (tok[5] != '(') && (tok[7] != ')') && (tok[8] != ','))
- return error(syntax_error);
- if (tok[1] < KW_A0 && tok[1] > KW_A7)
- return error(syntax_error);
- if (tok[5] < KW_A0 && tok[6] > KW_A7)
- return error(syntax_error);
- inst |= ((tok[1] & 7) << 0);
- inst |= ((tok[6] & 7) << 9);
- tok = tok + 9;
- D_word(inst);
- // Fall through for adjustment (common in both valid cases)
- }
- else
- return error("invalid syntax");
+ if (*tok.u32 >= KW_D0 && *tok.u32 <= KW_D7)
+ {
+ // Dx,Dy,#<adjustment>
+ inst |= (0 << 3); // R/M
+ inst |= (*tok.u32++ & 7);
+ if (*tok.u32 != ',' && tok.u32[2] != ',')
+ return error("missing comma");
- if ((*tok != CONST) && (*tok != SYMBOL) && (*tok != '-'))
- return error(syntax_error);
+ if (tok.u32[1] < KW_D0 && tok.u32[1] > KW_D7)
+ return error(syntax_error);
- if (expr(a0expr, &a0exval, &a0exattr, &a0esym)==ERROR)
- return ERROR;
+ inst |= ((tok.u32[1] & 7)<<9);
+ tok.u32 = tok.u32 + 3;
+ D_word(inst);
+ // Fall through for adjustment (common in both valid cases)
+ }
+ else if (*tok.u32 == '-')
+ {
+ // -(Ax),-(Ay),#<adjustment>
+ inst |= (1 << 3); // R/M
+ tok.u32++; // eat the minus
- if ((a0exattr & DEFINED) == 0)
- return error(undef_error);
+ if ((*tok.u32 != '(') && (tok.u32[2]!=')') && (tok.u32[3]!=',') && (tok.u32[4] != '-') && (tok.u32[5] != '(') && (tok.u32[7] != ')') && (tok.u32[8] != ','))
+ return error(syntax_error);
- if (a0exval + 0x8000 > 0x10000)
- return error("");
+ if (tok.u32[1] < KW_A0 && tok.u32[1] > KW_A7)
+ return error(syntax_error);
- if (*tok != EOL)
- return error(extra_stuff);
+ if (tok.u32[5] < KW_A0 && tok.u32[6] > KW_A7)
+ return error(syntax_error);
- D_word((a0exval & 0xffff));
+ inst |= ((tok.u32[1] & 7) << 0);
+ inst |= ((tok.u32[6] & 7) << 9);
+ tok.u32 = tok.u32 + 9;
+ D_word(inst);
+ // Fall through for adjustment (common in both valid cases)
+ }
+ else
+ return error("invalid syntax");
+ if ((*tok.u32 != CONST) && (*tok.u32 != SYMBOL) && (*tok.u32 != '-'))
+ return error(syntax_error);
+ if (expr((TOKENPTR)a0expr, &a0exval, &a0exattr, &a0esym) == ERROR)
+ return ERROR;
- return OK;
+ if ((a0exattr & DEFINED) == 0)
+ return error(undef_error);
+
+ if (a0exval + 0x8000 > 0x10000)
+ return error("");
+
+ if (*tok.u32 != EOL)
+ return error(extra_stuff);
+ D_word((a0exval & 0xFFFF));
+
+ return OK;
}
if (am1 == AM_NONE)
inst |= (0 << 6) | (a1reg);
- switch (a0reg)
- {
- case 0: // KW_IC40
+ switch (a0reg)
+ {
+ case 0: // KW_IC40
inst |= (2 << 6) | (a1reg);
- break;
- case 1: // KW_DC40
+ break;
+ case 1: // KW_DC40
inst |= (1 << 6) | (a1reg);
- break;
- case 2: // KW_BC40
+ break;
+ case 2: // KW_BC40
inst |= (3 << 6) | (a1reg);
- break;
- }
+ break;
+ }
D_word(inst);
return OK;
return error(unsupport);
if (siz == SIZB)
- {
inst |= 0 << 6;
- }
else if (siz == SIZL)
- {
inst |= 2 << 6;
- }
else // SIZW/SIZN
- {
inst |= 1 << 6;
- }
if (am0 == DREG)
{
//
int m_pflusha(WORD inst, WORD siz)
{
- if (activecpu == CPU_68030)
- {
- D_word(inst);
- inst = (1 << 13) | (1 << 10) | (0 << 5) | 0;
- D_word(inst);
- return OK;
-}
- else if (activecpu == CPU_68040)
- {
- inst = B16(11110101, 00011000);
- D_word(inst);
- return OK;
- }
- else
- return error(unsupport);
-
- return OK;
+ if (activecpu == CPU_68030)
+ {
+ D_word(inst);
+ inst = (1 << 13) | (1 << 10) | (0 << 5) | 0;
+ D_word(inst);
+ return OK;
+ }
+ else if (activecpu == CPU_68040)
+ {
+ inst = B16(11110101, 00011000);
+ D_word(inst);
+ return OK;
+ }
+ else
+ return error(unsupport);
+ return OK;
}
{
if (activecpu == CPU_68030)
{
- // PFLUSH FC, MASK
- // PFLUSH FC, MASK, < ea >
- WORD mask, fc;
- switch ((int)*tok)
- {
- case '#':
- tok++;
- if (*tok != CONST && *tok != SYMBOL)
- return error("function code should be an expression");
- if (expr(a0expr, &a0exval, &a0exattr, &a0esym) == ERROR)
- return ERROR;
- if ((a0exattr & DEFINED) == 0)
- return error("function code immediate should be defined");
- if (a0exval > 7 && a0exval < 0)
- return error("function code out of range (0-7)");
+ // PFLUSH FC, MASK
+ // PFLUSH FC, MASK, < ea >
+ WORD mask, fc;
+
+ switch ((int)*tok.u32)
+ {
+ case '#':
+ tok.u32++;
+
+ if (*tok.u32 != CONST && *tok.u32 != SYMBOL)
+ return error("function code should be an expression");
+
+ if (expr((TOKENPTR)a0expr, &a0exval, &a0exattr, &a0esym) == ERROR)
+ return ERROR;
+
+ if ((a0exattr & DEFINED) == 0)
+ return error("function code immediate should be defined");
+
+ if (a0exval > 7 && a0exval < 0)
+ return error("function code out of range (0-7)");
+
fc = (uint16_t)a0exval;
- break;
- case KW_D0:
- case KW_D1:
- case KW_D2:
- case KW_D3:
- case KW_D4:
- case KW_D5:
- case KW_D6:
- case KW_D7:
- fc = (1 << 4) | (*tok++ & 7);
- break;
- case KW_SFC:
- fc = 0;
- tok++;
- break;
- case KW_DFC:
- fc = 1;
- tok++;
- break;
- default:
- return error(syntax_error);
- }
-
- if (*tok++ != ',')
- return error("comma exptected");
-
- if (*tok++ != '#')
- return error("mask should be an immediate value");
- if (*tok != CONST && *tok != SYMBOL)
- return error("mask is supposed to be immediate");
- if (expr(a0expr, &a0exval, &a0exattr, &a0esym) == ERROR)
- return ERROR;
- if ((a0exattr & DEFINED) == 0)
- return error("mask immediate value should be defined");
- if (a0exval > 7 && a0exval < 0)
- return error("function code out of range (0-7)");
+ break;
+ case KW_D0:
+ case KW_D1:
+ case KW_D2:
+ case KW_D3:
+ case KW_D4:
+ case KW_D5:
+ case KW_D6:
+ case KW_D7:
+ fc = (1 << 4) | (*tok.u32++ & 7);
+ break;
+ case KW_SFC:
+ fc = 0;
+ tok.u32++;
+ break;
+ case KW_DFC:
+ fc = 1;
+ tok.u32++;
+ break;
+ default:
+ return error(syntax_error);
+ }
+
+ if (*tok.u32++ != ',')
+ return error("comma exptected");
+
+ if (*tok.u32++ != '#')
+ return error("mask should be an immediate value");
+
+ if (*tok.u32 != CONST && *tok.u32 != SYMBOL)
+ return error("mask is supposed to be immediate");
+
+ if (expr((TOKENPTR)a0expr, &a0exval, &a0exattr, &a0esym) == ERROR)
+ return ERROR;
+
+ if ((a0exattr & DEFINED) == 0)
+ return error("mask immediate value should be defined");
+
+ if (a0exval > 7 && a0exval < 0)
+ return error("function code out of range (0-7)");
+
mask = (uint16_t)a0exval << 5;
- if (*tok == EOL)
- {
- // PFLUSH FC, MASK
- D_word(inst);
- inst = (1 << 13) | fc | mask | (4 << 10);
- D_word(inst);
- return OK;
- }
- else if (*tok == ',')
- {
- // PFLUSH FC, MASK, < ea >
- tok++;
- if (amode(0) == ERROR)
- return ERROR;
- if (*tok != EOL)
- return error(extra_stuff);
- if (am0 == AIND || am0 == ABSW || am0 == ABSL || am0 == ADISP || am0 == ADISP || am0 == AINDEXED || am0 == ABASE || am0 == MEMPOST || am0 == MEMPRE)
- {
- inst |= am0 | a0reg;
- D_word(inst);
- inst = (1 << 13) | fc | mask | (6 << 10);
- D_word(inst);
- ea0gen(siz);
- return OK;
- }
- else
- return error("unsupported addressing mode");
-
- }
- else
- return error(syntax_error);
-
- return OK;
+ if (*tok.u32 == EOL)
+ {
+ // PFLUSH FC, MASK
+ D_word(inst);
+ inst = (1 << 13) | fc | mask | (4 << 10);
+ D_word(inst);
+ return OK;
+ }
+ else if (*tok.u32 == ',')
+ {
+ // PFLUSH FC, MASK, < ea >
+ tok.u32++;
+
+ if (amode(0) == ERROR)
+ return ERROR;
+
+ if (*tok.u32 != EOL)
+ return error(extra_stuff);
+ if (am0 == AIND || am0 == ABSW || am0 == ABSL || am0 == ADISP || am0 == ADISP || am0 == AINDEXED || am0 == ABASE || am0 == MEMPOST || am0 == MEMPRE)
+ {
+ inst |= am0 | a0reg;
+ D_word(inst);
+ inst = (1 << 13) | fc | mask | (6 << 10);
+ D_word(inst);
+ ea0gen(siz);
+ return OK;
+ }
+ else
+ return error("unsupported addressing mode");
+
+ }
+ else
+ return error(syntax_error);
+
+ return OK;
}
else if (activecpu == CPU_68040 || activecpu == CPU_68060)
{
- // PFLUSH(An)
- // PFLUSHN(An)
- if (*tok != '(' && tok[2] != ')')
- return error(syntax_error);
- if (tok[1] < KW_A0 && tok[1] > KW_A7)
- return error("expected (An)");
- if ((inst & 7) == 7)
- // With pflushn/pflush there's no easy way to
- // distinguish between the two in 68040 mode.
- // Ideally the opcode bitfields would have been
- // hardcoded in 68ktab but there is aliasing
- // between 68030 and 68040 opcode. So we just
- // set the 3 lower bits to 1 in pflushn inside
- // 68ktab and detect it here.
- inst = (inst & 0xff8) | 8;
- inst |= (tok[1] & 7) | (5 << 8);
- if (tok[3] != EOL)
- return error(extra_stuff);
- D_word(inst);
+ // PFLUSH(An)
+ // PFLUSHN(An)
+ if (*tok.u32 != '(' && tok.u32[2] != ')')
+ return error(syntax_error);
+
+ if (tok.u32[1] < KW_A0 && tok.u32[1] > KW_A7)
+ return error("expected (An)");
+
+ if ((inst & 7) == 7)
+ // With pflushn/pflush there's no easy way to distinguish between
+ // the two in 68040 mode. Ideally the opcode bitfields would have
+ // been hardcoded in 68ktab but there is aliasing between 68030
+ // and 68040 opcode. So we just set the 3 lower bits to 1 in
+ // pflushn inside 68ktab and detect it here.
+ inst = (inst & 0xff8) | 8;
+
+ inst |= (tok.u32[1] & 7) | (5 << 8);
+
+ if (tok.u32[3] != EOL)
+ return error(extra_stuff);
+
+ D_word(inst);
}
else
return error(unsupport);
//
int m_pload(WORD inst, WORD siz, WORD extension)
{
- // TODO: 68551 support is not added yet.
- // None of the ST series of computers had
- // a 68020 + 68551 socket and since this is
- // an Atari targetted assembler....
- CHECKNO30;
-
- inst |= am1;
-
- D_word(inst);
-
- switch (am0)
- {
- case CREG:
- if (a0reg == KW_SFC - KW_SFC)
- {
- inst = 0;
- }
- else if (a0reg == KW_DFC - KW_SFC)
- {
- inst = 1;
- }
- else
- return error("illegal control register specified");
- break;
- case DREG:
- inst = (1 << 3) | a0reg;
- break;
- case IMMED:
- if ((a0exattr & DEFINED) == 0)
- return error("constant value must be defined");
+ // TODO: 68551 support is not added yet.
+ // None of the ST series of computers had a 68020 + 68551 socket and since
+ // this is an Atari targetted assembler...
+ CHECKNO30;
+
+ inst |= am1;
+
+ D_word(inst);
+
+ switch (am0)
+ {
+ case CREG:
+ if (a0reg == KW_SFC - KW_SFC)
+ inst = 0;
+ else if (a0reg == KW_DFC - KW_SFC)
+ inst = 1;
+ else
+ return error("illegal control register specified");
+
+ break;
+ case DREG:
+ inst = (1 << 3) | a0reg;
+ break;
+ case IMMED:
+ if ((a0exattr & DEFINED) == 0)
+ return error("constant value must be defined");
+
inst = (2 << 3) | (uint16_t)a0exval;
- break;
- }
+ break;
+ }
- inst |= extension | (1 << 13);
- D_word(inst);
+ inst |= extension | (1 << 13);
+ D_word(inst);
- ea1gen(siz);
+ ea1gen(siz);
- return OK;
+ return OK;
}
int m_ploadr(WORD inst, WORD siz)
{
- return m_pload(inst, siz, 1 << 9);
+ return m_pload(inst, siz, 1 << 9);
}
int m_ploadw(WORD inst, WORD siz)
{
- return m_pload(inst, siz, 0 << 9);
+ return m_pload(inst, siz, 0 << 9);
}
//
{
int inst2,reg;
- // TODO: 68551 support is not added yet.
- // None of the ST series of computers had
- // a 68020 + 68551 socket and since this is
- // an Atari targetted assembler....
- // (same for 68EC030)
- CHECKNO30;
+ // TODO: 68551 support is not added yet.
+ // None of the ST series of computers had
+ // a 68020 + 68551 socket and since this is
+ // an Atari targetted assembler....
+ // (same for 68EC030)
+ CHECKNO30;
inst2 = inst & (1 << 8); //Copy the flush bit over to inst2 in case we're called from m_pmovefd
inst &= ~(1 << 8); //And mask it out
else
return error("pmove sez: Wut?");
- // The instruction is a quad-word (8 byte) operation
- // for the CPU root pointer and the supervisor root pointer.
- // It is a long - word operation for the translation control register
- // and the transparent translation registers(TT0 and TT1).
- // It is a word operation for the MMU status register.
+ // The instruction is a quad-word (8 byte) operation
+ // for the CPU root pointer and the supervisor root pointer.
+ // It is a long - word operation for the translation control register
+ // and the transparent translation registers(TT0 and TT1).
+ // It is a word operation for the MMU status register.
if (((reg == (KW_URP - KW_SFC)) || (reg == (KW_SRP - KW_SFC)))
&& ((siz != SIZD) && (siz != SIZN)))
if (am0 == CREG)
{
- inst |= am1 | a1reg;
+ inst |= am1 | a1reg;
D_word(inst);
}
else if (am1 == CREG)
switch (reg + KW_SFC)
{
- case KW_TC:
- inst2 |= (0 << 10) + (1 << 14); break;
- case KW_SRP:
- inst2 |= (2 << 10) + (1 << 14); break;
- case KW_CRP:
- inst2 |= (3 << 10) + (1 << 14); break;
- case KW_TT0:
+ case KW_TC:
+ inst2 |= (0 << 10) + (1 << 14); break;
+ case KW_SRP:
+ inst2 |= (2 << 10) + (1 << 14); break;
+ case KW_CRP:
+ inst2 |= (3 << 10) + (1 << 14); break;
+ case KW_TT0:
inst2 |= (2 << 10) + (0 << 13); break;
- case KW_TT1:
+ case KW_TT1:
inst2 |= (3 << 10) + (0 << 13); break;
- case KW_MMUSR:
- if (am0 == CREG)
- inst2 |= (1 << 9) + (3 << 13);
- else
- inst2 |= (0 << 9) + (3 << 13);
- break;
- default:
- return error("unsupported register");
- break;
+ case KW_MMUSR:
+ if (am0 == CREG)
+ inst2 |= (1 << 9) + (3 << 13);
+ else
+ inst2 |= (0 << 9) + (3 << 13);
+ break;
+ default:
+ return error("unsupported register");
+ break;
}
D_word(inst2);
- if (am0 == CREG)
- {
- ea1gen(siz);
- }
- else if (am1 == CREG)
- {
- ea0gen(siz);
- }
+ if (am0 == CREG)
+ ea1gen(siz);
+ else if (am1 == CREG)
+ ea0gen(siz);
return OK;
}
#define gen_ptrapcc(name,opcode) \
int m_##name(WORD inst, WORD siz) \
{ \
- CHECKNO20; \
- if (siz == SIZW) \
- { \
- D_word(inst); \
- D_word(B8(opcode)); \
- D_word(a0exval); \
- } \
- else \
- { \
- inst |= 3; \
- D_word(inst); \
- D_word(B8(opcode)); \
- D_long(a0exval); \
- } \
- return OK; \
+ CHECKNO20; \
+ if (siz == SIZW) \
+ { \
+ D_word(inst); \
+ D_word(B8(opcode)); \
+ D_word(a0exval); \
+ } \
+ else \
+ { \
+ inst |= 3; \
+ D_word(inst); \
+ D_word(B8(opcode)); \
+ D_long(a0exval); \
+ } \
+ return OK; \
}\
int m_##name##n(WORD inst, WORD siz) \
{ \
- CHECKNO20; \
- D_word(inst); \
- D_word(B8(opcode)); \
- return OK; \
+ CHECKNO20; \
+ D_word(inst); \
+ D_word(B8(opcode)); \
+ return OK; \
}
gen_ptrapcc(ptrapbs,00000000)
switch (siz)
{
- case SIZB: inst |= (6 << 10); break;
+ case SIZB: inst |= (6 << 10); break;
case SIZW: inst |= (4 << 10); break;
case SIZL: inst |= (0 << 10); break;
case SIZN:
}
else
{
- AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, a1expr);
+ AddFixup(FU_WORD | FU_PCREL | FU_ISBRA, sloc, (TOKENPTR)a1expr);
D_word(0);
}
// Source specifier
switch (siz)
{
- case SIZB: inst |= (6 << 10); break;
+ case SIZB: inst |= (6 << 10); break;
case SIZW: inst |= (4 << 10); break;
case SIZL: inst |= (0 << 10); break;
case SIZN:
case SIZS: inst |= (1 << 10); break;
case SIZD: inst |= (5 << 10); break;
case SIZX: inst |= (2 << 10); break;
- case SIZP: inst |= (3 << 10);
- // In P size we have 2 cases: {#k} where k is immediate
- // and {Dn} where Dn=Data register
+ case SIZP: inst |= (3 << 10);
+ // In P size we have 2 cases: {#k} where k is immediate
+ // and {Dn} where Dn=Data register
if (bfparam1)
- {
- // Dn
+ {
+ // Dn
inst |= 1 << 12;
- inst |= bfval1 << 4;
- }
- else
- {
- // #k
- if (bfval1>63 && bfval1<-64)
- return error("K-factor must be between -64 and 63");
- inst |= bfval1 & 127;
- }
+ inst |= bfval1 << 4;
+ }
+ else
+ {
+ // #k
+ if (bfval1 > 63 && bfval1 < -64)
+ return error("K-factor must be between -64 and 63");
+
+ inst |= bfval1 & 127;
+ }
break;
default:
// Source specifier
switch (siz)
{
- case SIZB: inst |= (6 << 10); break;
+ case SIZB: inst |= (6 << 10); break;
case SIZW: inst |= (4 << 10); break;
case SIZL: inst |= (0 << 10); break;
case SIZN:
case SIZS: inst |= (1 << 10); break;
case SIZD: inst |= (5 << 10); break;
case SIZX: inst |= (2 << 10); break;
- case SIZP: inst |= (3 << 10); break;
+ case SIZP: inst |= (3 << 10); break;
default:
return error("Something bad happened, possibly.");
break;
if (siz == SIZX || siz==SIZN)
{
- if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
+ if ((*tok.u32 >= KW_FP0) && (*tok.u32 <= KW_FP7))
{
//fmovem.x <rlist>,ea
if (fpu_reglist_left(®mask) < 0)
return OK;
- if (*tok++ != ',')
+ if (*tok.u32++ != ',')
return error("missing comma");
if (amode(0) < 0)
ea0gen(siz);
return OK;
}
- else if ((*tok >= KW_D0) && (*tok <= KW_D7))
+ else if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7))
{
// fmovem.x Dn,ea
- datareg = (*tok++ & 7) << 10;
+ datareg = (*tok.u32++ & 7) << 10;
- if (*tok++ != ',')
+ if (*tok.u32++ != ',')
return error("missing comma");
if (amode(0) < 0)
inst |= am0 | a0reg;
- if (*tok++ != ',')
+ if (*tok.u32++ != ',')
return error("missing comma");
- if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
+ if ((*tok.u32 >= KW_FP0) && (*tok.u32 <= KW_FP7))
{
//fmovem.x ea,<rlist>
if (fpu_reglist_right(®mask) < 0)
else
{
// fmovem.x ea,Dn
- datareg = (*tok++ & 7) << 10;
+ datareg = (*tok.u32++ & 7) << 10;
D_word(inst);
inst = (1 << 15) | (1 << 14) | (0 << 13) | (3 << 11) | (datareg << 4);
D_word(inst);
}
else if (siz == SIZL)
{
- if ((*tok == KW_FPCR) || (*tok == KW_FPSR) || (*tok == KW_FPIAR))
+ if ((*tok.u32 == KW_FPCR) || (*tok.u32 == KW_FPSR) || (*tok.u32 == KW_FPIAR))
{
//fmovem.l <rlist>,ea
regmask = (1 << 15) | (1 << 13);
fmovem_loop_1:
- if (*tok == KW_FPCR)
+ if (*tok.u32 == KW_FPCR)
{
regmask |= (1 << 12);
- tok++;
+ tok.u32++;
goto fmovem_loop_1;
}
- if (*tok == KW_FPSR)
+ if (*tok.u32 == KW_FPSR)
{
regmask |= (1 << 11);
- tok++;
+ tok.u32++;
goto fmovem_loop_1;
}
- if (*tok == KW_FPIAR)
+ if (*tok.u32 == KW_FPIAR)
{
regmask |= (1 << 10);
- tok++;
+ tok.u32++;
goto fmovem_loop_1;
}
- if ((*tok == '/') || (*tok == '-'))
+ if ((*tok.u32 == '/') || (*tok.u32 == '-'))
{
- tok++;
+ tok.u32++;
goto fmovem_loop_1;
}
- if (*tok++ != ',')
+ if (*tok.u32++ != ',')
return error("missing comma");
if (amode(0) < 0)
inst |= am0 | a0reg;
- if (*tok++ != ',')
+ if (*tok.u32++ != ',')
return error("missing comma");
regmask = (1 << 15) | (0 << 13);
fmovem_loop_2:
- if (*tok == KW_FPCR)
+ if (*tok.u32 == KW_FPCR)
{
regmask |= (1 << 12);
- tok++;
+ tok.u32++;
goto fmovem_loop_2;
}
- if (*tok == KW_FPSR)
+ if (*tok.u32 == KW_FPSR)
{
regmask |= (1 << 11);
- tok++;
+ tok.u32++;
goto fmovem_loop_2;
}
- if (*tok == KW_FPIAR)
+ if (*tok.u32 == KW_FPIAR)
{
regmask |= (1 << 10);
- tok++;
+ tok.u32++;
goto fmovem_loop_2;
}
- if ((*tok == '/') || (*tok == '-'))
+ if ((*tok.u32 == '/') || (*tok.u32 == '-'))
{
- tok++;
+ tok.u32++;
goto fmovem_loop_2;
}
- if (*tok!=EOL)
+ if (*tok.u32 != EOL)
return error("extra (unexpected) text found");
inst |= am0 | a0reg;
#define gen_FTRAPcc(name,opcode) \
int m_##name (WORD inst, WORD siz) \
{ \
- if (siz==SIZW) \
- { \
- D_word(inst); \
- D_word(B8(opcode)); \
- D_word(a0exval); \
- } \
- else \
- { \
- inst|=3; \
- D_word(inst); \
- D_word(B8(opcode)); \
- D_long(a0exval); \
- } \
- return OK;\
+ if (siz==SIZW) \
+ { \
+ D_word(inst); \
+ D_word(B8(opcode)); \
+ D_word(a0exval); \
+ } \
+ else \
+ { \
+ inst|=3; \
+ D_word(inst); \
+ D_word(B8(opcode)); \
+ D_long(a0exval); \
+ } \
+ return OK;\
} \
int m_##name##n (WORD inst, WORD siz) \
{ \
- D_word(inst); \
- D_word(B8(opcode)); \
- return OK;\
+ D_word(inst); \
+ D_word(B8(opcode)); \
+ return OK;\
}
gen_FTRAPcc(ftrapeq ,00000001)
// Setup entry in symbol table, make sure the macro isn't a duplicate
// entry, and that it doesn't override any processor mnemonic or assembler
// directive.
- if (*tok++ != SYMBOL)
+ if (*tok.u32++ != SYMBOL)
return error("missing symbol");
- char * name = string[*tok++];
+ char * name = string[*tok.u32++];
if (lookup(name, MACRO, 0) != NULL)
return error("duplicate macro definition");
curmac->sattr = (WORD)(macnum++);
// Parse and define formal arguments in symbol table
- if (*tok != EOL)
+ if (*tok.u32 != EOL)
{
argno = 0;
symlist(defmac2);
char * p = NULL;
int k = -1;
- if (*tok == SYMBOL)
+ if (*tok.u32 == SYMBOL)
{
// A string followed by a colon or double colon is a symbol and
// *not* a directive, see if we can find the directive after it
- if ((tok[2] == ':' || tok[2] == DCOLON))
+ if ((tok.u32[2] == ':' || tok.u32[2] == DCOLON))
{
- if (tok[3] == SYMBOL)
- p = string[tok[4]];
+ if (tok.u32[3] == SYMBOL)
+ p = string[tok.u32[4]];
}
else
{
// Otherwise, just grab the directive
- p = string[tok[1]];
+ p = string[tok.u32[1]];
}
}
//
int InvokeMacro(SYM * mac, WORD siz)
{
- DEBUG { printf("InvokeMacro: arguments="); DumpTokens(tok); }
+ DEBUG { printf("InvokeMacro: arguments="); DumpTokens(tok.u32); }
INOBJ * inobj = a_inobj(SRC_IMACRO); // Alloc and init IMACRO
IMACRO * imacro = inobj->inobj.imacro;
// Chop up the arguments, if any (tok comes from token.c, which at this
// point points at the macro argument token stream)
- if (*tok != EOL)
+ if (*tok.u32 != EOL)
{
// Parse out the arguments and set them up correctly
TOKEN * p = imacro->argument[nargs].token;
int stringNum = 0;
- while (*tok != EOL)
+ while (*tok.u32 != EOL)
{
- if (*tok == ACONST)
+ if (*tok.u32 == ACONST)
{
for(int i=0; i<3; i++)
- *p++ = *tok++;
+ *p++ = *tok.u32++;
}
- else if (*tok == CONST) // Constants are 64-bits
+ else if (*tok.u32 == CONST) // Constants are 64-bits
{
- *p++ = *tok++; // Token
+ *p++ = *tok.u32++; // Token
uint64_t *p64 = (uint64_t *)p;
- uint64_t *tok64 = (uint64_t *)tok;
+ uint64_t *tok64 = (uint64_t *)tok.u32;
*p64++ = *tok64++;
- tok = (TOKEN *)tok64;
+ tok.u32 = (TOKEN *)tok64;
p = (uint32_t *)p64;
}
- else if ((*tok == STRING) || (*tok == SYMBOL))
+ else if ((*tok.u32 == STRING) || (*tok.u32 == SYMBOL))
{
- *p++ = *tok++;
- imacro->argument[nargs].string[stringNum] = strdup(string[*tok++]);
+ *p++ = *tok.u32++;
+ imacro->argument[nargs].string[stringNum] = strdup(string[*tok.u32++]);
*p++ = stringNum++;
}
- else if (*tok == ',')
+ else if (*tok.u32 == ',')
{
// Comma delimiter was found, so set up for next argument
*p++ = EOL;
- tok++;
+ tok.u32++;
stringNum = 0;
nargs++;
p = imacro->argument[nargs].token;
}
else
{
- *p++ = *tok++;
+ *p++ = *tok.u32++;
}
}
#define MWORD 0x0000 // Marked word
#define MLONG 0x0100 // Marked long
+//This will have to be defined eventually. Might have to overhaul the mark
+//system as 8-bits doesn't seem to be enough, at least for a bitfield (which it
+//might not have to be, in which case it would be big enough...)
+//#define MQUAD 0x // Marked quad word (TODO: merge with MDOUBLE?)
#define MMOVEI 0x0200 // Mark RISC MOVEI instruction
#define MDOUBLE 0x0400 // Marked double float
#define MEXTEND 0x0800 // Marked extended float
// Dn
// An
// # expression
- if ((*tok >= KW_D0) && (*tok <= KW_D7))
+ if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7))
{
AMn = DREG;
- AnREG = *tok++ & 7;
+ AnREG = *tok.u32++ & 7;
}
- else if ((*tok >= KW_A0) && (*tok <= KW_A7))
+ else if ((*tok.u32 >= KW_A0) && (*tok.u32 <= KW_A7))
{
AMn = AREG;
- AnREG = *tok++ & 7;
+ AnREG = *tok.u32++ & 7;
}
- else if (*tok == '#')
+ else if (*tok.u32 == '#')
{
- tok++;
+ tok.u32++;
if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
return ERROR;
// ([bd,An,Xn],od)
// ([bd,PC],Xn,od)
// ([bd,PC,Xn],od)
- else if (*tok == '(')
+ else if (*tok.u32 == '(')
{
- tok++;
+ tok.u32++;
- if ((*tok >= KW_A0) && (*tok <= KW_A7))
+ if ((*tok.u32 >= KW_A0) && (*tok.u32 <= KW_A7))
{
- AnREG = *tok++ & 7;
+ AnREG = *tok.u32++ & 7;
- if (*tok == ')')
+ if (*tok.u32 == ')')
{
- tok++;
+ tok.u32++;
- if (*tok == '+')
+ if (*tok.u32 == '+')
{
- tok++;
+ tok.u32++;
AMn = APOSTINC;
}
else
AMn = AINDEXED;
goto AMn_IX0; // Handle ",Xn[.siz][*scale])"
}
- else if ((*tok >= KW_D0) && (*tok <= KW_D7))
+ else if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7))
{
//Since index register isn't used here, store register number in this field
- AnIXREG = *tok++ & 7; // (Dn)
+ AnIXREG = *tok.u32++ & 7; // (Dn)
- if (*tok == ')')
+ if (*tok.u32 == ')')
{
- tok++;
+ tok.u32++;
AnEXTEN |= EXT_FULLWORD; // Definitely using full extension format, so set bit 8
AnEXTEN |= EXT_BS; // Base register suppressed
AnEXTEN |= EXT_BDSIZE0; // Base displacement null
AnREG = 6 << 3; // stuff 110 to mode field
goto AnOK;
}
- else if (*tok == 'L')
+ else if (*tok.u32 == 'L')
{
// TODO: does DINDL gets used at all?
AMn = DINDL; // (Dn.l)
AnEXTEN = 1 << 1; // Long index size
- tok++;
+ tok.u32++;
}
- else if (*tok == 'W') // (Dn.w)
+ else if (*tok.u32 == 'W') // (Dn.w)
{
// TODO: does DINDW gets used at all?
AMn = DINDW;
AnEXTEN = 1 << 1; // Word index size
- tok++;
+ tok.u32++;
}
- else if (*tok == ',')
+ else if (*tok.u32 == ',')
{
// ([bd,An],Xn..) without bd, An
// Base displacement is suppressed
AnEXTEN |= EXT_BS; // Base register suppressed
AnEXTEN |= EXT_BDSIZE0;
AnREG = 6 << 3; // stuff 110 to mode field
- tok++;
+ tok.u32++;
goto CHECKODn;
}
else
return error("(Dn) error");
}
- if (*tok == '*')
+ if (*tok.u32 == '*')
{ // scale: *1, *2, *4, *8
- tok++;
+ tok.u32++;
- if (*tok == SYMBOL)
+ if (*tok.u32 == SYMBOL)
{
if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
return error("scale factor expression must evaluate");
goto badmode;
}
}
- else if (*tok++ != CONST || *tok > 8)
+ else if (*tok.u32++ != CONST || *tok.u32 > 8)
goto badmode;
else
{
- switch ((int)*tok++)
+ switch ((int)*tok.u32++)
{
case 1:
break;
}
}
- if (*tok == ')')
+ if (*tok.u32 == ')')
{
- tok++;
+ tok.u32++;
AnEXTEN |= EXT_FULLWORD; // Definitely using full extension format, so set bit 8
AnEXTEN |= EXT_BS; // Base register suppressed
AnEXTEN |= EXT_BDSIZE0; // Base displacement null
AMn = MEMPOST;
goto AnOK;
}
- else if (*tok==',')
+ else if (*tok.u32 == ',')
{
- tok++; // eat the comma
+ tok.u32++; // eat the comma
// It might be (Dn[.wl][*scale],od)
// Maybe this is wrong and we have to write some code here
// instead of reusing that path...
else
return error("unhandled so far");
}
- else if (*tok == KW_PC)
+ else if (*tok.u32 == KW_PC)
{ // (PC,Xn[.siz][*scale])
- tok++;
+ tok.u32++;
AMn = PCINDEXED;
// Common index handler; enter here with 'tok' pointing at the
AMn_IXN: // Handle any indexed (tok -> a comma)
- if (*tok++ != ',')
+ if (*tok.u32++ != ',')
goto badmode;
- if (*tok < KW_D0 || *tok > KW_A7)
+ if (*tok.u32 < KW_D0 || *tok.u32 > KW_A7)
goto badmode;
- AnIXREG = *tok++ & 15;
+ AnIXREG = *tok.u32++ & 15;
- switch ((int)*tok)
+ switch ((int)*tok.u32)
{ // Index reg size: <empty> | .W | .L
case DOTW:
- tok++;
+ tok.u32++;
default:
AnIXSIZ = 0;
break;
case DOTL:
AnIXSIZ = 0x0800;
- tok++;
+ tok.u32++;
break;
case DOTB: // .B not allowed here...
goto badmode;
}
- if (*tok == '*')
+ if (*tok.u32 == '*')
{ // scale: *1, *2, *4, *8
- tok++;
+ tok.u32++;
- if (*tok == SYMBOL)
+ if (*tok.u32 == SYMBOL)
{
if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
return error("scale factor expression must evaluate");
goto badmode;
}
}
- else if (*tok++ != CONST || *tok > 8)
+ else if (*tok.u32++ != CONST || *tok.u32 > 8)
goto badmode;
else
{
- switch ((int)*tok++)
+ switch ((int)*tok.u32++)
{
case 1:
break;
}
}
- if (*tok == ',')
+ if (*tok.u32 == ',')
{
// If we got here we didn't get any [] stuff
// so let's suppress base displacement before
// branching off
- tok++;
+ tok.u32++;
AnEXTEN |= EXT_BDSIZE0; // Base displacement null - suppressed
goto CHECKODn;
}
- if (*tok++ != ')') // final ")"
+ if (*tok.u32++ != ')') // final ")"
goto badmode;
goto AnOK;
}
- else if (*tok == '[')
+ else if (*tok.u32 == '[')
{ // ([...
- tok++;
+ tok.u32++;
AnEXTEN |= EXT_FULLWORD; // Definitely using full extension format, so set bit 8
// Check to see if base displacement is present
- if (*tok != CONST && *tok != SYMBOL)
+ if (*tok.u32 != CONST && *tok.u32 != SYMBOL)
{
AnEXTEN |= EXT_BDSIZE0;
}
// bd=0 so let's optimise it out
AnEXTEN|=EXT_BDSIZE0;
}
- else if (*tok==DOTL)
+ else if (*tok.u32 == DOTL)
{ // ([bd.l,...
AnEXTEN |= EXT_BDSIZEL;
- tok++;
+ tok.u32++;
}
else
{ // ([bd[.w],... or ([bd,...
// Is .W forced here?
- if (*tok == DOTW)
+ if (*tok.u32 == DOTW)
{
AnEXTEN |= EXT_BDSIZEW;
- tok++;
+ tok.u32++;
}
else
{
}
}
- if (*tok == ',')
- tok++;
+ if (*tok.u32 == ',')
+ tok.u32++;
//else
// return error("Comma expected after base displacement");
}
// Check for address register or PC, suppress base register
// otherwise
- if (*tok == KW_PC)
+ if (*tok.u32 == KW_PC)
{ // ([bd,PC,...
AnREG = (7 << 3) | 3; // PC is special case - stuff 011 to register field and 111 to the mode field
- tok++;
+ tok.u32++;
}
- else if ((*tok >= KW_A0) && (*tok <= KW_A7))
+ else if ((*tok.u32 >= KW_A0) && (*tok.u32 <= KW_A7))
{ // ([bd,An,...
- AnREG = (6 << 3) | *tok & 7;
- tok++;
+ AnREG = (6 << 3) | *tok.u32 & 7;
+ tok.u32++;
}
- else if ((*tok >= KW_D0) && (*tok <= KW_D7))
+ else if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7))
{
// ([bd,Dn,...
AnREG = (6 << 3);
- AnEXTEN |= ((*tok & 7) << 12);
+ AnEXTEN |= ((*tok.u32 & 7) << 12);
AnEXTEN |= EXT_D;
AnEXTEN |= EXT_BS; // Oh look, a data register! Which means that base register is suppressed
- tok++;
+ tok.u32++;
// Check for size
{
// ([bd,An/PC],Xn.W/L...)
- switch ((int)*tok)
+ switch ((int)*tok.u32)
{
// Index reg size: <empty> | .W | .L
case DOTW:
- tok++;
+ tok.u32++;
break;
default:
break;
case DOTL:
AnEXTEN |= EXT_L;
- tok++;
+ tok.u32++;
break;
case DOTB:
// .B not allowed here...
}
// Check for scale
- if (*tok == '*') // ([bd,An/PC],Xn*...)
+ if (*tok.u32 == '*') // ([bd,An/PC],Xn*...)
{ // scale: *1, *2, *4, *8
- tok++;
+ tok.u32++;
- if (*tok == SYMBOL)
+ if (*tok.u32 == SYMBOL)
{
if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
return error("scale factor expression must evaluate");
goto badmode;
}
}
- else if (*tok++ != CONST || *tok > 8)
+ else if (*tok.u32++ != CONST || *tok.u32 > 8)
goto badmode;
else
{
- switch ((int)*tok++)
+ switch ((int)*tok.u32++)
{
case 1:
break;
}
}
}
- if (*tok == ']') // ([bd,Dn]...
+ if (*tok.u32 == ']') // ([bd,Dn]...
{
- tok++;
+ tok.u32++;
goto IS_SUPPRESSEDn;
}
}
- else if (*tok == ']')
+ else if (*tok.u32 == ']')
{
// PC and Xn is suppressed
AnREG = 6 << 3; // stuff 110 to mode field
}
// At a crossroads here. We can accept either ([bd,An/PC],... or ([bd,An/PC,Xn*scale],...
- if (*tok == ']')
+ if (*tok.u32 == ']')
{
//([bd,An/PC],Xn,od)
// Check for Xn
- tok++;
+ tok.u32++;
- if (*tok == ')')
+ if (*tok.u32 == ')')
{
//Xn and od are non existent, get out of jail free card
- tok++;
+ tok.u32++;
AMn = MEMPRE; // ([bc,An,Xn],od) with no Xn and od
AnEXTEN |= EXT_IS | EXT_IISPREN; //Suppress Xn and od
goto AnOK;
}
- else if (*tok != ',')
+ else if (*tok.u32 != ',')
return error("comma expected after ]");
else
- tok++; // eat the comma
+ tok.u32++; // eat the comma
- if ((*tok >= KW_A0) && (*tok <= KW_A7))
+ if ((*tok.u32 >= KW_A0) && (*tok.u32 <= KW_A7))
{
- AnIXREG = ((*tok & 7) << 12);
+ AnIXREG = ((*tok.u32 & 7) << 12);
AnEXTEN |= EXT_A;
- tok++;
+ tok.u32++;
}
- else if ((*tok >= KW_D0) && (*tok <= KW_D7))
+ else if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7))
{
- AnEXTEN |= ((*tok & 7) << 12);
+ AnEXTEN |= ((*tok.u32 & 7) << 12);
AnEXTEN |= EXT_D;
- tok++;
+ tok.u32++;
}
else
{
//No index found, suppress it
AnEXTEN |= EXT_IS;
- tok--; // Rewind tok to point to the comma
+ tok.u32--; // Rewind tok to point to the comma
goto IS_SUPPRESSEDn; // https://xkcd.com/292/ - what does he know anyway?
}
// Check for size
{
// ([bd,An/PC],Xn.W/L...)
- switch ((int)*tok)
+ switch ((int)*tok.u32)
{
// Index reg size: <empty> | .W | .L
case DOTW:
- tok++;
+ tok.u32++;
break;
default:
break;
case DOTL:
AnEXTEN |= EXT_L;
- tok++;
+ tok.u32++;
break;
case DOTB:
// .B not allowed here...
}
// Check for scale
- if (*tok == '*') // ([bd,An/PC],Xn*...)
+ if (*tok.u32 == '*') // ([bd,An/PC],Xn*...)
{ // scale: *1, *2, *4, *8
- tok++;
+ tok.u32++;
- if (*tok == SYMBOL)
+ if (*tok.u32 == SYMBOL)
{
if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
return error("scale factor expression must evaluate");
goto badmode;
}
}
- else if (*tok++ != CONST || *tok > 8)
+ else if (*tok.u32++ != CONST || *tok.u32 > 8)
goto badmode;
else
{
- switch ((int)*tok++)
+ switch ((int)*tok.u32++)
{
case 1:
break;
}
// Check for od
- if (*tok == ')') // ([bd,An/PC],Xn)
+ if (*tok.u32 == ')') // ([bd,An/PC],Xn)
{
//od is non existant, get out of jail free card
AMn = MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then
AnEXTEN |= EXT_IISPOSN; // No outer displacement
- tok++;
+ tok.u32++;
goto AnOK;
}
- else if (*tok != ',')
+ else if (*tok.u32 != ',')
return error("comma expected");
else
- tok++; // eat the comma
+ tok.u32++; // eat the comma
CHECKODn:
if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
// od=0 so optimise it out
AMn = MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then
AnEXTEN |= EXT_IISPOSN; // No outer displacement
- tok++;
+ tok.u32++;
goto AnOK;
}
// ([bd,An/PC],Xn,od)
- if (*tok == DOTL)
+ if (*tok.u32 == DOTL)
{
// expr.L
AnEXTEN |= EXT_IISPOSL; // Long outer displacement
AMn = MEMPOST;
- tok++;
+ tok.u32++;
// Defined, absolute values from $FFFF8000..$00007FFF get
// optimized to absolute short
AMn = MEMPOST;
// Is .W forced here?
- if (*tok == DOTW)
+ if (*tok.u32 == DOTW)
{
- tok++;
+ tok.u32++;
}
}
// Check for final closing parenthesis
- if (*tok == ')')
+ if (*tok.u32 == ')')
{
- tok++;
+ tok.u32++;
goto AnOK;
}
else
IS_SUPPRESSEDn:
// Check for od
- if (*tok == ')') // ([bd,An/PC],Xn)
+ if (*tok.u32 == ')') // ([bd,An/PC],Xn)
{
//od is non existant, get out of jail free card
AMn = MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then
AnEXTEN |= EXT_IISNOIN; // No outer displacement
- tok++;
+ tok.u32++;
goto AnOK;
}
- else if (*tok!=',')
+ else if (*tok.u32!=',')
return error("comma expected");
else
- tok++; // eat the comma
+ tok.u32++; // eat the comma
- if ((*tok != CONST) && (*tok != SYMBOL))
+ if ((*tok.u32 != CONST) && (*tok.u32 != SYMBOL))
goto badmode;
expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM);
// od=0 so optimise it out
AMn = MEMPOST; // let's say it's ([bd,An],Xn,od) with od=0 then
AnEXTEN |= EXT_IISNOIN; // No outer displacement
- tok++;
+ tok.u32++;
goto AnOK;
}
// ([bd,An/PC],Xn,od)
- if (*tok == DOTL)
+ if (*tok.u32 == DOTL)
{
// expr.L
- tok++;
+ tok.u32++;
AMn = MEMPOST;
AnEXTEN |= EXT_IISNOIL; // Long outer displacement with IS suppressed
}
AnEXTEN |= EXT_IISNOIW; // Word outer displacement with IS suppressed
AMn = MEMPRE;
- if (*tok == DOTW)
+ if (*tok.u32 == DOTW)
{
//AnEXTEN|=EXT_IISNOIW; // Word outer displacement
AMn = MEMPOST;
- tok++;
+ tok.u32++;
}
// Defined, absolute values from $FFFF8000..$00007FFF get
// optimized to absolute short
}
// Check for final closing parenthesis
- if (*tok == ')')
+ if (*tok.u32 == ')')
{
- tok++;
+ tok.u32++;
goto AnOK;
}
else
return error("Closing parenthesis missing on addressing mode");
}
- else if (*tok == ',')
+ else if (*tok.u32 == ',')
{
- *tok++; // ([bd,An,Xn.size*scale],od)
+ *tok.u32++; // ([bd,An,Xn.size*scale],od)
//Check for Xn
- if ((*tok >= KW_A0) && (*tok <= KW_A7))
+ if ((*tok.u32 >= KW_A0) && (*tok.u32 <= KW_A7))
{
- AnEXTEN |= ((*tok & 7) << 12);
+ AnEXTEN |= ((*tok.u32 & 7) << 12);
AnEXTEN |= EXT_A;
- tok++;
+ tok.u32++;
}
- else if ((*tok >= KW_D0) && (*tok <= KW_D7))
+ else if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_D7))
{
- AnEXTEN |= ((*tok & 7) << 12);
+ AnEXTEN |= ((*tok.u32 & 7) << 12);
AnEXTEN |= EXT_D;
- tok++;
+ tok.u32++;
}
// Check for size
{
// ([bd,An/PC],Xn.W/L...)
- switch ((int)*tok)
+ switch ((int)*tok.u32)
{
// Index reg size: <empty> | .W | .L
case DOTW:
- tok++;
+ tok.u32++;
break;
default:
break;
case DOTL:
- tok++;
+ tok.u32++;
AnEXTEN |= EXT_L;
break;
case DOTB:
}
// Check for scale
- if (*tok == '*') // ([bd,An/PC],Xn*...)
+ if (*tok.u32 == '*') // ([bd,An/PC],Xn*...)
{ // scale: *1, *2, *4, *8
- tok++;
+ tok.u32++;
- if (*tok == SYMBOL)
+ if (*tok.u32 == SYMBOL)
{
if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
return error("scale factor expression must evaluate");
goto badmode;
}
}
- else if (*tok++ != CONST || *tok > 8)
+ else if (*tok.u32++ != CONST || *tok.u32 > 8)
goto badmode;
else
{
- switch ((int)*tok++)
+ switch ((int)*tok.u32++)
{
case 1:
break;
}
//Check for ]
- if (*tok != ']')
+ if (*tok.u32 != ']')
return error("Expected closing bracket ]");
- tok++; // Eat the bracket
+ tok.u32++; // Eat the bracket
//Check for od
- if (*tok == ')') // ([bd,An/PC,Xn]...
+ if (*tok.u32 == ')') // ([bd,An/PC,Xn]...
{
//od is non existant, get out of jail free card
//AnEXVAL=0; // zero outer displacement
AMn = MEMPRE; // let's say it's ([bd,An,Xn],od) with od suppressed then
AnEXTEN |= EXT_IISPREN; // No outer displacement
- tok++;
+ tok.u32++;
goto AnOK;
}
- else if (*tok++ != ',')
+ else if (*tok.u32++ != ',')
return error("comma expected after ]");
- if (*tok == SYMBOL || *tok == CONST)
+ if (*tok.u32 == SYMBOL || *tok.u32 == CONST)
{
if (expr(AnEXPR, &AnEXVAL, &AnEXATTR, &AnESYM) != OK)
goto badmode;
// od=0 so optimise it out
AMn = MEMPRE; // let's say it's ([bd,An],Xn,od) with od=0 then
AnEXTEN |= EXT_IISPRE0; // No outer displacement
- tok++;
+ tok.u32++;
goto AnOK;
}
}
// ([bd,An/PC,Xn],od)
- if (*tok == DOTL)
+ if (*tok.u32 == DOTL)
{
// expr.L
AMn = MEMPRE;
- tok++;
+ tok.u32++;
AnEXTEN |= EXT_IISPREL;
}
else
AnEXTEN |= expr_size; // Assume we have a .w value
// Is .W forced here?
- if (*tok == DOTW)
+ if (*tok.u32 == DOTW)
{
- tok++;
+ tok.u32++;
if (expr_size == EXT_IISPREL)
return error("outer displacement value does not fit in .w size");
}
// Check for final closing parenthesis
- if (*tok == ')')
+ if (*tok.u32 == ')')
{
- tok++;
+ tok.u32++;
goto AnOK;
}
else
// It could be that this is really just an expression prefixing a
// register as a displacement...
- if (*tok == ')')
+ if (*tok.u32 == ')')
{
- tok++;
+ tok.u32++;
goto CHK_FOR_DISPn;
}
// Otherwise, check for PC & etc displacements...
- if (*tok++ != ',')
+ if (*tok.u32++ != ',')
goto badmode;
- if ((*tok >= KW_A0) && (*tok <= KW_A7))
+ if ((*tok.u32 >= KW_A0) && (*tok.u32 <= KW_A7))
{
- AnREG = *tok & 7;
- tok++;
+ AnREG = *tok.u32 & 7;
+ tok.u32++;
- if (*tok == ',')
+ if (*tok.u32 == ',')
{
AMn = AINDEXED;
goto AMn_IXN;
}
- else if (*tok == ')')
+ else if (*tok.u32 == ')')
{
AMn = ADISP;
- tok++;
+ tok.u32++;
goto AnOK;
}
else
goto badmode;
}
- else if (*tok == KW_PC)
+ else if (*tok.u32 == KW_PC)
{
- if (*++tok == ',')
+ if (*++tok.u32 == ',')
{ // expr(PC,Xn...)
AMn = PCINDEXED;
goto AMn_IXN;
}
- else if (*tok == ')')
+ else if (*tok.u32 == ')')
{
AMn = PCDISP; // expr(PC)
- tok++;
+ tok.u32++;
goto AnOK;
}
else
goto badmode;
}
}
- else if (*tok == '-' && tok[1] == '(' && ((tok[2] >= KW_A0) && (tok[2] <= KW_A7)) && tok[3] == ')')
+ else if (*tok.u32 == '-' && tok.u32[1] == '(' && ((tok.u32[2] >= KW_A0) && (tok.u32[2] <= KW_A7)) && tok.u32[3] == ')')
{
AMn = APREDEC;
- AnREG = tok[2] & 7;
- tok += 4;
+ AnREG = tok.u32[2] & 7;
+ tok.u32 += 4;
}
- else if (*tok == KW_CCR)
+ else if (*tok.u32 == KW_CCR)
{
AMn = AM_CCR;
- tok++;
+ tok.u32++;
goto AnOK;
}
- else if (*tok == KW_SR)
+ else if (*tok.u32 == KW_SR)
{
AMn = AM_SR;
- tok++;
+ tok.u32++;
goto AnOK;
}
- else if (*tok == KW_USP)
+ else if (*tok.u32 == KW_USP)
{
AMn = AM_USP;
- tok++;
+ tok.u32++;
AnREG = 2; //Added this for the case of USP used in movec (see CREGlut in mach.c). Hopefully nothing gets broken!
goto AnOK;
}
- else if ((*tok >= KW_IC40) && (*tok <= KW_BC40))
+ else if ((*tok.u32 >= KW_IC40) && (*tok.u32 <= KW_BC40))
{
AMn = CACHES;
- AnREG = *tok++ - KW_IC40;
+ AnREG = *tok.u32++ - KW_IC40;
// After a cache keyword only a comma or EOL is allowed
- if ((*tok != ',') && (*tok != EOL))
+ if ((*tok.u32 != ',') && (*tok.u32 != EOL))
return ERROR;
goto AnOK;
}
- else if ((*tok >= KW_SFC) && (*tok <= KW_CRP))
+ else if ((*tok.u32 >= KW_SFC) && (*tok.u32 <= KW_CRP))
{
AMn = CREG;
- AnREG = (*tok++) - KW_SFC;
+ AnREG = (*tok.u32++) - KW_SFC;
goto AnOK;
}
- else if ((*tok >= KW_FP0) && (*tok <= KW_FP7))
+ else if ((*tok.u32 >= KW_FP0) && (*tok.u32 <= KW_FP7))
{
AMn = FREG;
- AnREG = (*tok++ & 7);
+ AnREG = (*tok.u32++ & 7);
}
- else if ((*tok >= KW_FPIAR) && (*tok <= KW_FPCR))
+ else if ((*tok.u32 >= KW_FPIAR) && (*tok.u32 <= KW_FPCR))
{
AMn = FPSCR;
- AnREG = (1 << ((*tok++) - KW_FPIAR + 10));
+ AnREG = (1 << ((*tok.u32++) - KW_FPIAR + 10));
}
// expr
// expr.w
return ERROR;
CHK_FOR_DISPn:
- if (*tok == DOTW)
+ if (*tok.u32 == DOTW)
{
// expr.W
- tok++;
+ tok.u32++;
AMn = ABSW;
if (((AnEXATTR & (TDB | DEFINED)) == DEFINED) && (AnEXVAL < 0x10000))
goto AnOK;
}
- else if (*tok != '(')
+ else if (*tok.u32 != '(')
{
// expr[.L]
AMn = ABSL;
}
// Is .L forced here?
- if (*tok == DOTL)
+ if (*tok.u32 == DOTL)
{
- tok++;
+ tok.u32++;
AMn = ABSL;
}
goto AnOK;
}
- tok++;
+ tok.u32++;
- if ((*tok >= KW_A0) && (*tok <= KW_A7))
+ if ((*tok.u32 >= KW_A0) && (*tok.u32 <= KW_A7))
{
- AnREG = *tok++ & 7;
+ AnREG = *tok.u32++ & 7;
- if (*tok == ')')
+ if (*tok.u32 == ')')
{
AMn = ADISP;
- tok++;
+ tok.u32++;
goto AnOK;
}
AMn = AINDEXED;
goto AMn_IXN;
}
- else if (*tok == KW_PC)
+ else if (*tok.u32 == KW_PC)
{
- if (*++tok == ')')
+ if (*++tok.u32 == ')')
{
AMn = PCDISP;
- tok++;
+ tok.u32++;
goto AnOK;
}
label = NULL; // No label
lab_sym = NULL; // No (exported) label
equate = NULL; // No equate
- tk = tok; // Save first token in line
+ tk = tok.u32; // Save first token in line
pcloc = (uint32_t)sloc; // Set beginning-of-line PC
loop1: // Internal line processing loop
- if (*tok == EOL) // Restart loop if end-of-line
+ if (*tok.u32 == EOL) // Restart loop if end-of-line
goto loop;
// First token MUST be a symbol (Shamus: not sure why :-/)
- if (*tok != SYMBOL)
+ if (*tok.u32 != SYMBOL)
{
- if ((*tok >= KW_D0) && (*tok <= KW_R31))
+ if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_R31))
error("cannot use reserved keyword as label name or .equ");
else
error("syntax error; expected symbol");
goto loop;
}
- j = (int)tok[2]; // Skip equates (normal statements)
+ j = (int)tok.u32[2]; // Skip equates (normal statements)
if (j == '=' || j == DEQUALS || j == SET || j == REG || j == EQUREG || j == CCDEF)
{
- equate = string[tok[1]];
+ equate = string[tok.u32[1]];
equtyp = j;
- tok += 3;
+ tok.u32 += 3;
goto normal;
}
if (j == ':' || j == DCOLON)
{
as68label:
- label = string[tok[1]]; // Get label name
- labtyp = tok[2]; // Get label type
- tok += 3; // Go to next line token
+ label = string[tok.u32[1]]; // Get label name
+ labtyp = tok.u32[2]; // Get label type
+ tok.u32 += 3; // Go to next line token
// 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] == ':'))
+ if (as68_flag && (*tok.u32 == SYMBOL && tok.u32[2] == ':'))
{
if (HandleLabel(label, labtyp) != 0)
goto loop;
}
// EOL is legal here...
- if (*tok == EOL)
+ if (*tok.u32 == EOL)
goto normal;
// First token MUST be a symbol (if we get here, tok didn't advance)
- if (*tok++ != SYMBOL)
+ if (*tok.u32++ != SYMBOL)
{
error("syntax error; expected symbol");
goto loop;
}
- opname = p = string[*tok++];
+ opname = p = string[*tok.u32++];
// Check to see if the SYMBOL is a keyword (a mnemonic or directive).
// On output, `state' will have one of the values:
// Check for ".b" ".w" ".l" after directive, macro or mnemonic.
siz = SIZN;
- switch (*tok)
+ switch (*tok.u32)
{
- case DOTW: siz = SIZW, tok++; break;
- case DOTL: siz = SIZL, tok++; break;
- case DOTB: siz = SIZB, tok++; break;
- case DOTD: siz = SIZD, tok++; break;
- case DOTP: siz = SIZP, tok++; break;
- case DOTQ: siz = SIZQ, tok++; break;
- case DOTS: siz = SIZS, tok++; break;
- case DOTX: siz = SIZX, tok++; break;
+ case DOTW: siz = SIZW, tok.u32++; break;
+ case DOTL: siz = SIZL, tok.u32++; break;
+ case DOTB: siz = SIZB, tok.u32++; break;
+ case DOTD: siz = SIZD, tok.u32++; break;
+ case DOTP: siz = SIZP, tok.u32++; break;
+ case DOTQ: siz = SIZQ, tok.u32++; break;
+ case DOTS: siz = SIZS, tok.u32++; break;
+ case DOTX: siz = SIZX, tok.u32++; break;
}
-
// Do special directives (500..999) (These must be handled in "real time")
if (state >= 500 && state < 1000)
{
goto loop;
}
- if (*tok++ != ',')
+ if (*tok.u32++ != ',')
{
error(comma_error);
goto loop;
}
// Check for register to equate to
- if ((*tok >= KW_R0) && (*tok <= KW_R31))
+ if ((*tok.u32 >= KW_R0) && (*tok.u32 <= KW_R31))
{
// sy->sattre = EQUATEDREG | RISCSYM; // Mark as equated register
sy->sattre = EQUATEDREG; // Mark as equated register
- riscreg = (*tok - KW_R0);
+ riscreg = (*tok.u32 - 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
// sy->sattre |= (riscreg << 8); // Store register number
#endif
// Check for ",<bank #>" override notation
- if ((tok[1] == ',') && (tok[2] == CONST))
+ if ((tok.u32[1] == ',') && (tok.u32[2] == CONST))
{
// Advance token pointer to the constant
- tok += 3;
+ tok.u32 += 3;
// Anything other than a 0 or a 1 will result in "No Bank"
- if (*(uint64_t *)tok == 0)
+ if (*(uint64_t *)tok.u32 == 0)
registerbank = BANK_0;
- else if (*(uint64_t *)tok == 1)
+ else if (*(uint64_t *)tok.u32 == 1)
registerbank = BANK_1;
}
// & what does this $80000080 constant mean???
// eval = 0x80000080 + (riscreg) + (registerbank << 8);
eval = riscreg;
- tok++;
+ tok.u32++;
}
// Checking for a register symbol
- else if (tok[0] == SYMBOL)
+ else if (tok.u32[0] == SYMBOL)
{
- sy2 = lookup(string[tok[1]], LABEL, j);
+ sy2 = lookup(string[tok.u32[1]], LABEL, j);
// Make sure symbol is a valid equreg
if (!sy2 || !(sy2->sattre & EQUATEDREG))
eattr = ABS | DEFINED | GLOBAL; // Copy symbols attributes
sy->sattre = sy2->sattre;
eval = (sy2->svalue & 0xFFFFF0FF);
- tok += 2;
+ tok.u32 += 2;
}
}
else
sy->sattre |= EQUATEDCC;
eattr = ABS | DEFINED | GLOBAL;
- if (tok[0] == SYMBOL)
+ if (tok.u32[0] == SYMBOL)
{
- sy2 = lookup(string[tok[1]], LABEL, j);
+ sy2 = lookup(string[tok.u32[1]], LABEL, j);
if (!sy2 || !(sy2->sattre & EQUATEDCC))
{
eattr = ABS | DEFINED | GLOBAL;
sy->sattre = sy2->sattre;
eval = sy2->svalue;
- tok += 2;
+ tok.u32 += 2;
}
}
else if (expr(exprbuf, &eval, &eattr, &esym) != OK)
goto loop;
}
//equ a equr
- else if (*tok == SYMBOL)
+ else if (*tok.u32 == SYMBOL)
{
- sy2 = lookup(string[tok[1]], LABEL, j);
+ sy2 = lookup(string[tok.u32[1]], LABEL, j);
if (sy2 && (sy2->sattre & EQUATEDREG))
{
if (amode(1) < 0) // Parse 0, 1 or 2 addr modes
goto loop;
- if (*tok != EOL)
+ if (*tok.u32 != EOL)
error(extra_stuff);
amsk0 = amsktab[am0];
TOKEN r_expr[EXPRSIZE]; // Expression token list
// Evaluate what's in the global "tok" buffer
- if (expr(r_expr, &eval, &eattr, &esym) != OK)
+ if (expr((TOKENPTR)r_expr, &eval, &eattr, &esym) != OK)
return ERROR;
if ((challoc - ch_size) < 4)
if (!(eattr & DEFINED))
{
- AddFixup((WORD)(FU_WORD | rattr), sloc, r_expr);
+ AddFixup((WORD)(FU_WORD | rattr), sloc, (TOKENPTR)r_expr);
return 0;
}
if (parm & SUB32)
attrflg |= FU_SUB32;
- if (*tok != '#')
+ if (*tok.u32 != '#')
return MalformedOpcode(0x01);
- tok++;
+ tok.u32++;
riscImmTokenSeen = 1;
- if (expr(r_expr, &eval, &eattr, &esym) != OK)
+ if (expr((TOKENPTR)r_expr, &eval, &eattr, &esym) != OK)
return MalformedOpcode(0x02);
if ((challoc - ch_size) < 4)
if (!(eattr & DEFINED))
{
- AddFixup((WORD)(FU_WORD | attrflg), sloc, r_expr);
+ AddFixup((WORD)(FU_WORD | attrflg), sloc, (TOKENPTR)r_expr);
reg1 = 0;
}
else
// Move Immediate--n,Rn--n in Second Word
case RI_MOVEI:
- if (*tok != '#')
+ if (*tok.u32 != '#')
return MalformedOpcode(0x03);
- tok++;
+ tok.u32++;
riscImmTokenSeen = 1;
// Check for equated register after # and return error if so
- if (*tok == SYMBOL)
+ if (*tok.u32 == SYMBOL)
{
- sy = lookup(string[tok[1]], LABEL, 0);
+ sy = lookup(string[tok.u32[1]], LABEL, 0);
if (sy && (sy->sattre & EQUATEDREG))
return error("equated register in 1st operand of MOVEI instruction");
}
- if (expr(r_expr, &eval, &eattr, &esym) != OK)
+ if (expr((TOKENPTR)r_expr, &eval, &eattr, &esym) != OK)
return MalformedOpcode(0x04);
if (lastOpcode == RI_JUMP || lastOpcode == RI_JR)
if (!(eattr & DEFINED))
{
- AddFixup(FU_LONG | FU_MOVEI, sloc + 2, r_expr);
+ AddFixup(FU_LONG | FU_MOVEI, sloc + 2, (TOKENPTR)r_expr);
eval = 0;
}
else
// PC,Rd or Rs,Rd
case RI_MOVE:
- if (*tok == KW_PC)
+ if (*tok.u32 == KW_PC)
{
parm = 51;
reg1 = 0;
- tok++;
+ tok.u32++;
}
else
{
indexed = 0;
parm = 41;
- if (*tok != '(')
+ if (*tok.u32 != '(')
return MalformedOpcode(0x05);
- tok++;
+ tok.u32++;
- if ((*(tok + 1) == '+') || (*(tok + 1) == '-')) {
+ if ((*(tok.u32 + 1) == '+') || (*(tok.u32 + 1) == '-')) {
// Trying to make indexed call
- if ((*tok == KW_R14 || *tok == KW_R15)) {
- indexed = (*tok - KW_R0);
+ if ((*tok.u32 == KW_R14 || *tok.u32 == KW_R15)) {
+ indexed = (*tok.u32 - KW_R0);
} else {
- return IllegalIndexedRegister(*tok);
+ return IllegalIndexedRegister(*tok.u32);
}
}
- if (*tok == SYMBOL)
+ if (*tok.u32 == SYMBOL)
{
-// sy = lookup((char *)tok[1], LABEL, 0);
- sy = lookup(string[tok[1]], LABEL, 0);
+// sy = lookup((char *)tok.u32[1], LABEL, 0);
+ sy = lookup(string[tok.u32[1]], LABEL, 0);
if (!sy)
{
if (sy->sattre & EQUATEDREG)
{
- if ((*(tok + 2) == '+') || (*(tok + 2) == '-')) {
+ if ((*(tok.u32 + 2) == '+') || (*(tok.u32 + 2) == '-')) {
if ((sy->svalue & 0x1F) == 14 || (sy->svalue & 0x1F) == 15) {
indexed = (sy->svalue & 0x1F);
- tok++;
+ tok.u32++;
} else {
return IllegalIndexedRegisterEqur(sy);
}
{
reg1 = indexed;
indexed = 0;
- tok++;
+ tok.u32++;
- if (*tok == '+')
+ if (*tok.u32 == '+')
{
parm = (WORD)(reg1 - 14 + 58);
- tok++;
+ tok.u32++;
- if (*tok >= KW_R0 && *tok <= KW_R31)
+ if (*tok.u32 >= KW_R0 && *tok.u32 <= KW_R31)
indexed = 1;
- if (*tok == SYMBOL)
+ if (*tok.u32 == SYMBOL)
{
-// sy = lookup((char *)tok[1], LABEL, 0);
- sy = lookup(string[tok[1]], LABEL, 0);
+// sy = lookup((char *)tok.u32[1], LABEL, 0);
+ sy = lookup(string[tok.u32[1]], LABEL, 0);
if (!sy)
{
}
else
{
- if (expr(r_expr, &eval, &eattr, &esym) != OK)
+ if (expr((TOKENPTR)r_expr, &eval, &eattr, &esym) != OK)
return MalformedOpcode(0x06);
if ((challoc - ch_size) < 4)
}
}
- if (*tok != ')')
+ if (*tok.u32 != ')')
return MalformedOpcode(0x07);
- tok++;
+ tok.u32++;
CHECK_COMMA;
reg2 = GetRegister(FU_REGTWO);
at_eol();
reg1 = GetRegister(FU_REGONE);
CHECK_COMMA;
- if (*tok != '(')
+ if (*tok.u32 != '(')
return MalformedOpcode(0x08);
- tok++;
+ tok.u32++;
indexed = 0;
- if ((*tok == KW_R14 || *tok == KW_R15) && (*(tok + 1) != ')'))
- indexed = (*tok - KW_R0);
+ if ((*tok.u32 == KW_R14 || *tok.u32 == KW_R15) && (*(tok.u32 + 1) != ')'))
+ indexed = (*tok.u32 - KW_R0);
- if (*tok == SYMBOL)
+ if (*tok.u32 == SYMBOL)
{
- sy = lookup(string[tok[1]], LABEL, 0);
+ sy = lookup(string[tok.u32[1]], LABEL, 0);
if (!sy)
{
if (sy->sattre & EQUATEDREG)
{
if (((sy->svalue & 0x1F) == 14 || (sy->svalue & 0x1F) == 15)
- && (*(tok + 2) != ')'))
+ && (*(tok.u32 + 2) != ')'))
{
indexed = (sy->svalue & 0x1F);
- tok++;
+ tok.u32++;
}
}
}
{
reg2 = indexed;
indexed = 0;
- tok++;
+ tok.u32++;
- if (*tok == '+')
+ if (*tok.u32 == '+')
{
parm = (WORD)(reg2 - 14 + 60);
- tok++;
+ tok.u32++;
- if (*tok >= KW_R0 && *tok <= KW_R31)
+ if (*tok.u32 >= KW_R0 && *tok.u32 <= KW_R31)
indexed = 1;
- if (*tok == SYMBOL)
+ if (*tok.u32 == SYMBOL)
{
- sy = lookup(string[tok[1]], LABEL, 0);
+ sy = lookup(string[tok.u32[1]], LABEL, 0);
if (!sy)
{
}
else
{
- if (expr(r_expr, &eval, &eattr, &esym) != OK)
+ if (expr((TOKENPTR)r_expr, &eval, &eattr, &esym) != OK)
return MalformedOpcode(0x09);
if ((challoc - ch_size) < 4)
if (!(eattr & DEFINED))
{
- AddFixup(FU_WORD | FU_REGTWO, sloc, r_expr);
+ AddFixup(FU_WORD | FU_REGTWO, sloc, (TOKENPTR)r_expr);
reg2 = 0;
}
else
}
}
- if (*tok != ')')
+ if (*tok.u32 != ')')
return MalformedOpcode(0x0A);
- tok++;
+ tok.u32++;
at_eol();
BuildRISCIntructionWord(parm, reg2, reg1);
break;
// LOADB/LOADP/LOADW (Rn),Rn
case RI_LOADN:
- if (*tok != '(')
+ if (*tok.u32 != '(')
return MalformedOpcode(0x0B);
- tok++;
+ tok.u32++;
reg1 = GetRegister(FU_REGONE);
- if (*tok != ')')
+ if (*tok.u32 != ')')
return MalformedOpcode(0x0C);
- tok++;
+ tok.u32++;
CHECK_COMMA;
reg2 = GetRegister(FU_REGTWO);
at_eol();
reg1 = GetRegister(FU_REGONE);
CHECK_COMMA;
- if (*tok != '(')
+ if (*tok.u32 != '(')
return MalformedOpcode(0x0D);
- tok++;
+ tok.u32++;
reg2 = GetRegister(FU_REGTWO);
- if (*tok != ')')
+ if (*tok.u32 != ')')
return MalformedOpcode(0x0E);
- tok++;
+ tok.u32++;
at_eol();
BuildRISCIntructionWord(parm, reg2, reg1);
break;
// the JR or JUMP should default to 0, Jump Always
commaFound = 0;
- for(t=tok; *t!=EOL; t++)
+ for(t=tok.u32; *t!=EOL; t++)
{
if (*t == ',')
{
if (commaFound)
{
- if (*tok == CONST)
+ if (*tok.u32 == CONST)
{
// CC using a constant number
- tok++;
- uint64_t *tok64 = (uint64_t *)tok;
+ tok.u32++;
+ uint64_t *tok64 = (uint64_t *)tok.u32;
val = (int)*tok64++;
- tok = (uint32_t *)tok64;
+ tok.u32 = (uint32_t *)tok64;
CHECK_COMMA;
}
- else if (*tok == SYMBOL)
+ else if (*tok.u32 == SYMBOL)
{
val = 99;
-// strcpy(scratch, (char *)tok[1]);
- strcpy(scratch, string[tok[1]]);
+// strcpy(scratch, (char *)tok.u32[1]);
+ strcpy(scratch, string[tok.u32[1]]);
strtoupper(scratch);
for(i=0; i<MAXINTERNCC; i++)
// Standard CC was not found, look for an equated one
if (val == 99)
{
-// ccsym = lookup((char *)tok[1], LABEL, 0);
- ccsym = lookup(string[tok[1]], LABEL, 0);
+// ccsym = lookup((char *)tok.u32[1], LABEL, 0);
+ ccsym = lookup(string[tok.u32[1]], LABEL, 0);
if (ccsym && (ccsym->sattre & EQUATEDCC) && !(ccsym->sattre & UNDEF_CC))
val = ccsym->svalue;
return error("unknown condition code");
}
- tok += 2;
+ tok.u32 += 2;
CHECK_COMMA;
}
- else if (*tok == '(')
+ else if (*tok.u32 == '(')
{
// Set CC to "Jump Always"
val = 0;
if (type == RI_JR)
{
// JR cc,n
- if (expr(r_expr, &eval, &eattr, &esym) != OK)
+ if (expr((TOKENPTR)r_expr, &eval, &eattr, &esym) != OK)
return MalformedOpcode(0x0F);
if ((challoc - ch_size) < 4)
if (!(eattr & DEFINED))
{
- AddFixup(FU_WORD | FU_JR, sloc, r_expr);
+ AddFixup(FU_WORD | FU_JR, sloc, (TOKENPTR)r_expr);
reg2 = 0;
}
else
else
{
// JUMP cc, (Rn)
- if (*tok != '(')
+ if (*tok.u32 != '(')
return MalformedOpcode(0x10);
- tok++;
+ tok.u32++;
reg2 = GetRegister(FU_REGTWO);
- if (*tok != ')')
+ if (*tok.u32 != ')')
return MalformedOpcode(0x11);
- tok++;
+ tok.u32++;
at_eol();
BuildRISCIntructionWord(parm, reg2, reg1);
}
#define GPUONLY 0x4000 // Opcode is for the GPU Only
#define DSPONLY 0x8000 // Opcode is for the DSP Only
-#define CHECK_COMMA if(*tok++ != ',') { error(comma_error); return(ERROR); }
+#define CHECK_COMMA if(*tok.u32++ != ',') { error(comma_error); return(ERROR); }
// Opcode Specific Data
struct opcoderecord {
#define SPACE ' ' // ASCII space
#define SLASHCHAR '/'
#define SLASHSTRING "/"
-#define TOKEN uint32_t // Assembler token
#define FNSIZ 128 // Maximum size of a filename
#define OK 0 // OK return
#define DEBUG if (debug) // Debug conditional
// Object code formats
enum
{
-ALCYON, // Alcyon/DRI C object format
+ALCYON, // Alcyon/DRI C object format
MWC, // Mark Williams object format
BSD, // BSD object format
ELF, // ELF object format
XEX, // COM/EXE/XEX/whatever a8 object format
};
+// Assembler token
+#define TOKEN uint32_t
+
+// Token pointer type is a union because we have 64-bit sized tokens now :-P
+#define TOKENPTR union _tokenptr
+TOKENPTR
+{
+ uint32_t * u32;
+ uint64_t * u64;
+};
+
// Pointer type that can point to (almost) anything
#define PTR union _ptr
PTR
{
- uint8_t * cp; // Char
+ uint8_t * cp; // Char
uint16_t * wp; // WORD
uint32_t * lp; // LONG
- uint32_t lw; // LONG
- SYM ** sy; // SYM
- TOKEN * tk; // TOKEN
+ uint32_t lw; // LONG
+ SYM ** sy; // SYM
+ TOKENPTR tk; // TOKEN
};
// Symbol spaces
#define SIZW 0x0002 // .w
#define SIZL 0x0004 // .l
#define SIZN 0x0008 // no .(size) specifier
-#define SIZD 0x0010 // .d (quad word or FPU double precision real)
+#define SIZD 0x0010 // .d (FPU double precision real)
#define SIZS 0x0020 // .s (FPU single precision real)
#define SIZX 0x0040 // .x (FPU extended precision real)
#define SIZP 0x0080 // .p (FPU pakced decimal real)
-#define SIZQ 0x0100 // .q
+#define SIZQ 0x0100 // .q (quad word)
// RISC register bank definitions (used in extended symbol attributes also)
#define BANK_N 0x0000 // No register bank specified
//
// Arrange for a fixup on a location
//
-int AddFixup(uint16_t attr, uint32_t loc, TOKEN * fexpr)
+int AddFixup(uint16_t attr, uint32_t loc, TOKENPTR fexpr)
{
uint32_t i = MIN_FIXUP_MEM;
uint16_t len = 0;
// Compute length of expression (could be faster); determine if it's the
// single-symbol case; no expression if it's just a mark. (? is this true?)
- if ((*fexpr == SYMBOL) && (fexpr[2] == ENDEXPR))
+ if ((*fexpr.u32 == SYMBOL) && (fexpr.u32[2] == ENDEXPR))
{
// Just a single symbol, possibly followed by a DWORD
i += sizeof(SYM *);
attr |= FU_EXPR;
// Count the # of tokens in the expression
- for(len=0; fexpr[len]!=ENDEXPR; len++)
+ for(len=0; fexpr.u32[len]!=ENDEXPR; len++)
{
// Add one to len for 2X tokens, two for 3X tokens
- if (fexpr[len] == SYMBOL)
+ if (fexpr.u32[len] == SYMBOL)
len++;
- else if (fexpr[len] == CONST)
+ else if (fexpr.u32[len] == CONST)
len += 2;
}
*fchptr.wp++ = len;
while (len--)
- *fchptr.lp++ = *fexpr++;
+ *fchptr.lp++ = *fexpr.u32++;
}
else
{
- *fchptr.sy++ = symbolPtr[fexpr[1]];
+ *fchptr.sy++ = symbolPtr[fexpr.u32[1]];
// SCPCD: Correct bit mask for attr (else other FU_xxx will match)
// NYAN !
{
i = *fup.wp++;
- if (evexpr(fup.tk, &eval, &eattr, &esym) != OK)
+ if (evexpr((TOKENPTR)fup.tk, &eval, &eattr, &esym) != OK)
{
fup.lp += i;
continue;
*chptr++=(uint8_t)((lw)>>8); \
*chptr++=(uint8_t)(lw); \
sloc += 4; ch_size += 4; if(orgactive) orgaddr += 4;}
+#define D_quad(qw) {*chptr++=(uint8_t)((qw)>>56); \
+ *chptr++=(uint8_t)((qw)>>48);\
+ *chptr++=(uint8_t)((qw)>>40);\
+ *chptr++=(uint8_t)((qw)>>32);\
+ *chptr++=(uint8_t)((qw)>>24);\
+ *chptr++=(uint8_t)((qw)>>16);\
+ *chptr++=(uint8_t)((qw)>>8); \
+ *chptr++=(uint8_t)(qw); \
+ sloc += 8; ch_size += 8; if(orgactive) orgaddr += 8;}
#define D_rword(w) {*chptr++=(uint8_t)(w); *chptr++=(uint8_t)((w)>>8); \
sloc+=2; ch_size+=2;if(orgactive) orgaddr += 2;}
#define D_single(w) {chcheck(4);*chptr++ = ((char *)&w)[3]; \
void SaveSection(void);
int fixtest(int, uint32_t);
int chcheck(uint32_t);
-int AddFixup(uint16_t, uint32_t, TOKEN *);
+int AddFixup(uint16_t, uint32_t, TOKENPTR);
int ResolveAllFixups(void);
#endif // __SECT_H__
char lnbuf[LNSIZ]; // Text of current line
WORD filecount; // Unique file number counter
WORD cfileno; // Current file number
-TOKEN * tok; // Ptr to current token
+TOKENPTR tok; // Ptr to current token
TOKEN * etok; // Ptr past last token in tokbuf[]
TOKEN tokeol[1] = {EOL}; // Bailout end-of-line token
-char * string[TOKBUFSIZE*2]; // Token buffer string pointer storage
+char * string[TOKBUFSIZE*2];// Token buffer string pointer storage
int optimizeOff; // Optimization override flag
// File record, used to maintain a list of every include file ever visited
dotxtab['W'] = DOTW;
dotxtab['l'] = DOTL; // .l .L
dotxtab['L'] = DOTL;
- dotxtab['i'] = DOTI; // .i .I (???)
+ dotxtab['i'] = DOTI; // .i .I (WTF is this???)
dotxtab['I'] = DOTI;
- dotxtab['D'] = DOTD; // .d .D (quad word)
+ dotxtab['D'] = DOTD; // .d .D (double)
dotxtab['d'] = DOTD;
dotxtab['S'] = DOTS; // .s .S
dotxtab['s'] = DOTS;
- dotxtab['Q'] = DOTQ; // .q .Q
+ dotxtab['Q'] = DOTQ; // .q .Q (quad word)
dotxtab['q'] = DOTQ;
dotxtab['X'] = DOTX; // .x .x
dotxtab['x'] = DOTX;
// Install INOBJ on top of input stack
inobj->in_ifent = ifent; // Record .if context on entry
inobj->in_type = (WORD)typ;
- inobj->in_otok = tok;
+ inobj->in_otok = tok.u32;
inobj->in_etok = etok;
inobj->in_link = cur_inobj;
cur_inobj = inobj;
*dst++ = *s++;
continue;
case '?': // \? <macro> set `questmark' flag
- ++s;
+ s++;
questmark = 1;
break;
case '#': // \#, number of arguments
if (numUnmatched > 0)
warn("missing %d .endif(s)", numUnmatched);
- tok = inobj->in_otok; // Restore tok and otok
+ tok.u32 = inobj->in_otok; // Restore tok and otok
etok = inobj->in_etok;
switch (inobj->in_type)
{
uint8_t * ln = NULL; // Ptr to current position in line
uint8_t * p; // Random character ptr
- TOKEN * tk; // Token-deposit ptr
+ TOKENPTR tk; // Token-deposit ptr
int state = 0; // State for keyword detector
int j = 0; // Var for keyword detector
uint8_t c; // Random char
int stuffnull; // 1:terminate SYMBOL '\0' at *nullspot
uint8_t c1;
int stringNum = 0; // Pointer to string locations in tokenized line
- uint64_t * tk64;
retry:
- if (cur_inobj == NULL) // Return EOF if input stack is empty
+ if (cur_inobj == NULL) // Return EOF if input stack is empty
return TKEOF;
// Get another line of input from the current input source: a file, a
strcpy(lnbuf, ln);
// General housekeeping
- tok = tokeol; // Set "tok" to EOL in case of error
- tk = etok; // Reset token ptr
+ tok.u32 = tokeol; // Set "tok" to EOL in case of error
+ tk.u32 = etok; // Reset token ptr
stuffnull = 0; // Don't stuff nulls
totlines++; // Bump total #lines assembled
// token stream:
ln++;
stuffnull = 0;
- *tk++ = (TOKEN)dotxtab[*ln++];
+ *tk.u32++ = (TOKEN)dotxtab[*ln++];
continue;
}
}
*ln++ = EOS; // Terminate symbol
stuffnull = 0; // And never try it again
- // Character following the `.' must have a DOT attribute, and
+ // Character following the '.' must have a DOT attribute, and
// the chararacter after THAT one must not have a start-symbol
// attribute (to prevent symbols that look like, for example,
// "zingo.barf", which might be a good idea anyway....)
// If not tokenized keyword OR token was not found
if ((j < 0) || (state < 0))
{
- *tk++ = SYMBOL;
+ *tk.u32++ = SYMBOL;
//#warning
//problem here: nullspot is a char * but TOKEN is a uint32_t. On a 64-bit
//system, this will cause all kinds of mischief.
*tk++ = (TOKEN)nullspot;
#else
string[stringNum] = nullspot;
- *tk++ = stringNum;
+ *tk.u32++ = stringNum;
stringNum++;
#endif
}
else
{
- *tk++ = (TOKEN)j;
+ *tk.u32++ = (TOKEN)j;
stuffnull = 0;
}
if (v) // Record attribute token (if any)
- *tk++ = (TOKEN)v;
+ *tk.u32++ = (TOKEN)v;
if (stuffnull) // Arrange for string termination on next pass
nullspot = ln;
// Handle identity tokens
if (c & SELF)
{
- *tk++ = *ln++;
+ *tk.u32++ = *ln++;
continue;
}
case '!': // ! or !=
if (*ln == '=')
{
- *tk++ = NE;
- ++ln;
+ *tk.u32++ = NE;
+ ln++;
}
else
- *tk++ = '!';
+ *tk.u32++ = '!';
continue;
case '\'': // 'string'
if (m6502)
{
// Hardcoded for now, maybe this will change in the future
- *tk++ = STRINGA8;
+ *tk.u32++ = STRINGA8;
goto dostring;
}
// Fall through
case '\"': // "string"
- *tk++ = STRING;
+ *tk.u32++ = STRING;
dostring:
c1 = ln[-1];
string[stringNum] = ln;
- *tk++ = stringNum;
+ *tk.u32++ = stringNum;
stringNum++;
for(p=ln; *ln!=EOS && *ln!=c1;)
case '$': // $, hex constant
if (chrtab[*ln] & HDIGIT)
{
- if (cursize == 'q' || cursize == 'Q')
- {
- // Parse 64-bit integer
- uint64_t v64 = 0;
-
- while (hextab[*ln] >= 0)
- v64 = (v64 << 4) + (int)hextab[*ln++];
-
- *(uint64_t *)tk = v64;
- tk = tk + 2;
-
- continue;
- }
v = 0;
// Parse the hex value
}
}
- *tk++ = CONST;
- tk64 = (uint64_t *)tk;
- *tk64++ = v;
- tk = (TOKEN *)tk64;
+ *tk.u32++ = CONST;
+ *tk.u64++ = v;
if (obj_format == ALCYON)
{
{
if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W'))
{
- *tk++ = DOTW;
+ *tk.u32++ = DOTW;
ln += 2;
}
else if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L'))
{
- *tk++ = DOTL;
+ *tk.u32++ = DOTL;
ln += 2;
}
}
}
}
else
- *tk++ = '$';
+ *tk.u32++ = '$';
continue;
case '<': // < or << or <> or <=
switch (*ln)
{
case '<':
- *tk++ = SHL;
- ++ln;
+ *tk.u32++ = SHL;
+ ln++;
continue;
case '>':
- *tk++ = NE;
- ++ln;
+ *tk.u32++ = NE;
+ ln++;
continue;
case '=':
- *tk++ = LE;
- ++ln;
+ *tk.u32++ = LE;
+ ln++;
continue;
default:
- *tk++ = '<';
+ *tk.u32++ = '<';
continue;
}
case ':': // : or ::
if (*ln == ':')
{
- *tk++ = DCOLON;
- ++ln;
+ *tk.u32++ = DCOLON;
+ ln++;
}
else
- *tk++ = ':';
+ *tk.u32++ = ':';
continue;
case '=': // = or ==
if (*ln == '=')
{
- *tk++ = DEQUALS;
- ++ln;
+ *tk.u32++ = DEQUALS;
+ ln++;
}
else
- *tk++ = '=';
+ *tk.u32++ = '=';
continue;
case '>': // > or >> or >=
switch (*ln)
{
case '>':
- *tk++ = SHR;
+ *tk.u32++ = SHR;
ln++;
continue;
case '=':
- *tk++ = GE;
+ *tk.u32++ = GE;
ln++;
continue;
default:
- *tk++ = '>';
+ *tk.u32++ = '>';
continue;
}
case '%': // % or binary constant
if (*ln < '0' || *ln > '1')
{
- *tk++ = '%';
+ *tk.u32++ = '%';
continue;
}
}
}
- *tk++ = CONST;
- tk64 = (uint64_t *)tk;
- *tk64++ = v;
- tk = (TOKEN *)tk64;
+ *tk.u32++ = CONST;
+ *tk.u64++ = v;
continue;
case '@': // @ or octal constant
if (*ln < '0' || *ln > '7')
{
- *tk++ = '@';
+ *tk.u32++ = '@';
continue;
}
if (*ln == '.')
{
- if ((*(ln+1) == 'b') || (*(ln+1) == 'B'))
+ if ((*(ln + 1) == 'b') || (*(ln + 1) == 'B'))
{
v &= 0x000000FF;
ln += 2;
}
- if ((*(ln+1) == 'w') || (*(ln+1) == 'W'))
+ if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W'))
{
v &= 0x0000FFFF;
ln += 2;
}
- if ((*(ln+1) == 'l') || (*(ln+1) == 'L'))
+ if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L'))
{
v &= 0xFFFFFFFF;
ln += 2;
}
}
- *tk++ = CONST;
- tk64 = (uint64_t *)tk;
- *tk64++ = v;
- tk = (TOKEN *)tk64;
+ *tk.u32++ = CONST;
+ *tk.u64++ = v;
continue;
case '^': // ^ or ^^ <operator-name>
if (*ln != '^')
{
- *tk++ = '^';
+ *tk.u32++ = '^';
continue;
}
continue;
}
- *tk++ = (TOKEN)j;
+ *tk.u32++ = (TOKEN)j;
continue;
default:
interror(2); // Bad MULTX entry in chrtab
// Handle decimal constant
if (c & DIGIT)
{
+ uint8_t * numStart = ln;
v = 0;
while ((int)chrtab[*ln] & DIGIT)
{
v &= 0x000000FF;
ln += 2;
- *tk++ = CONST;
- tk64 = (uint64_t *)tk;
- *tk64++ = v;
- tk = (uint32_t *)tk64;
- *tk++ = DOTB;
+ *tk.u32++ = CONST;
+ *tk.u64++ = v;
+ *tk.u32++ = DOTB;
}
else if ((*(ln + 1) == 'w') || (*(ln + 1) == 'W'))
{
v &= 0x0000FFFF;
ln += 2;
- *tk++ = CONST;
- tk64 = (uint64_t *)tk;
- *tk64++ = v;
- tk = (uint32_t *)tk64;
-
- *tk++ = DOTW;
+ *tk.u32++ = CONST;
+ *tk.u64++ = v;
+ *tk.u32++ = DOTW;
}
else if ((*(ln + 1) == 'l') || (*(ln + 1) == 'L'))
{
v &= 0xFFFFFFFF;
ln += 2;
- *tk++ = CONST;
- tk64 = (uint64_t *)tk;
- *tk64++ = v;
- tk = (uint32_t *)tk64;
-
- *tk++ = DOTL;
+ *tk.u32++ = CONST;
+ *tk.u64++ = v;
+ *tk.u32++ = DOTL;
}
else if ((int)chrtab[*(ln + 1)] & DIGIT)
{
- // Hey, more digits after the dot, so assume it's a
- // fractional number
+ // Hey, more digits after the dot, so we assume it's a
+ // floating point number of some kind
+#if 0
double fract = 10;
ln++;
f = (double)v;
f = f + (double)(*ln++ - '0') / fract;
fract *= 10;
}
+#else
+ // Here we parse the whole floating point number
+#include <errno.h>
+ char * numEnd;
+ errno = 0;
+ double f = strtod(numStart, &numEnd);
+ ln = (uint8_t *)numEnd;
+
+ if (errno != 0)
+ return error("floating point parse error");
+#endif
- *tk++ = FCONST;
- *((double *)tk) = f;
- tk += 2;
+ *tk.u32++ = FCONST;
+// Shamus: Well, this is all kinds of icky--not the least of which is that unlike uintNN_t types, we have no guarantees of any kind when it comes to the size of floating point numbers in C (as far as I know of). If there is, we need to use those kinds here, or else figure out at runtime what sizes we're dealing with and act accordingly. To be fair, this is OK as long as the double type is less than 64 bits wide, but again, there's no guarantee that it isn't. :-/
+ *tk.u64++ = f;
continue;
}
}
else
{
- *tk++ = CONST;
- tk64 = (uint64_t *)tk;
- *tk64++ = v;
- tk = (TOKEN *)tk64;
+ *tk.u32++ = CONST;
+ *tk.u64++ = v;
}
//printf("CONST: %i\n", v);
// Terminate line of tokens and return "success."
goteol:
- tok = etok; // Set tok to beginning of line
+ tok.u32 = etok; // Set tok to beginning of line
if (stuffnull) // Terminate last SYMBOL
*nullspot = EOS;
- *tk++ = EOL;
+ *tk.u32++ = EOL;
return OK;
}
int d_goto(WORD unused)
{
// Setup for the search
- if (*tok != SYMBOL)
+ if (*tok.u32 != SYMBOL)
return error("missing label");
- char * sym = string[tok[1]];
- tok += 2;
+ char * sym = string[tok.u32[1]];
+ tok.u32 += 2;
if (cur_inobj->in_type != SRC_IMACRO)
return error("goto not in macro");
}
+void DumpToken(TOKEN t)
+{
+ if (t == COLON)
+ printf("[COLON]");
+ else if (t == CONST)
+ printf("[CONST]");
+ else if (t == ACONST)
+ printf("[ACONST]");
+ else if (t == STRING)
+ printf("[STRING]");
+ else if (t == SYMBOL)
+ printf("[SYMBOL]");
+ else if (t == EOS)
+ printf("[EOS]");
+ else if (t == TKEOF)
+ printf("[TKEOF]");
+ else if (t == DEQUALS)
+ printf("[DEQUALS]");
+ else if (t == SET)
+ printf("[SET]");
+ else if (t == REG)
+ printf("[REG]");
+ else if (t == DCOLON)
+ printf("[DCOLON]");
+ else if (t == GE)
+ printf("[GE]");
+ else if (t == LE)
+ printf("[LE]");
+ else if (t == NE)
+ printf("[NE]");
+ else if (t == SHR)
+ printf("[SHR]");
+ else if (t == SHL)
+ printf("[SHL]");
+ else if (t == UNMINUS)
+ printf("[UNMINUS]");
+ else if (t == DOTB)
+ printf("[DOTB]");
+ else if (t == DOTW)
+ printf("[DOTW]");
+ else if (t == DOTL)
+ printf("[DOTL]");
+ else if (t == DOTQ)
+ printf("[DOTQ]");
+ else if (t == DOTS)
+ printf("[DOTS]");
+ else if (t == DOTD)
+ printf("[DOTD]");
+ else if (t == DOTI)
+ printf("[DOTI]");
+ else if (t == ENDEXPR)
+ printf("[ENDEXPR]");
+ else if (t == CR_ABSCOUNT)
+ printf("[CR_ABSCOUNT]");
+ else if (t == CR_DEFINED)
+ printf("[CR_DEFINED]");
+ else if (t == CR_REFERENCED)
+ printf("[CR_REFERENCED]");
+ else if (t == CR_STREQ)
+ printf("[CR_STREQ]");
+ else if (t == CR_MACDEF)
+ printf("[CR_MACDEF]");
+ else if (t == CR_TIME)
+ printf("[CR_TIME]");
+ else if (t == CR_DATE)
+ printf("[CR_DATE]");
+ else if (t >= 0x20 && t <= 0x2F)
+ printf("[%c]", (char)t);
+ else if (t >= 0x3A && t <= 0x3F)
+ printf("[%c]", (char)t);
+ else if (t >= 0x80 && t <= 0x87)
+ printf("[D%u]", ((uint32_t)t) - 0x80);
+ else if (t >= 0x88 && t <= 0x8F)
+ printf("[A%u]", ((uint32_t)t) - 0x88);
+ else
+ printf("[%X:%c]", (uint32_t)t, (char)t);
+}
+
+
void DumpTokenBuffer(void)
{
printf("Tokens [%X]: ", sloc);
printf("[COLON]");
else if (*t == CONST)
{
- printf("[CONST: $%lX]", ((uint64_t)t[1] << 32) | (uint64_t)t[2]);
+ TOKENPTR tp = (TOKENPTR)(t + 1);
+ printf("[CONST: $%lX]", (uint64_t)(*tp.u64));
t += 2;
}
else if (*t == ACONST)
printf("[DOTW]");
else if (*t == DOTL)
printf("[DOTL]");
+ else if (*t == DOTQ)
+ printf("[DOTQ]");
+ else if (*t == DOTS)
+ printf("[DOTS]");
+ else if (*t == DOTD)
+ printf("[DOTD]");
else if (*t == DOTI)
printf("[DOTI]");
else if (*t == ENDEXPR)
extern uint16_t curlineno;
extern char * curfname;
extern WORD cfileno;
-extern TOKEN * tok;
+extern TOKENPTR tok;
extern char lnbuf[];
extern char lntag;
extern char tolowertab[];
int fpop(void);
int d_goto(WORD);
INOBJ * a_inobj(int);
+void DumpToken(TOKEN);
void DumpTokenBuffer(void);
#endif // __TOKEN_H__
// Release Information
#define MAJOR 1 // Major version number
-#define MINOR 9 // Minor version number
-#define PATCH 1 // Patch release number
+#define MINOR 10 // Minor version number
+#define PATCH 0 // Patch release number
#endif // __VERSION_H__