X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?p=rmac;a=blobdiff_plain;f=procln.c;h=0bb52e6a733eafe35eb0c944b57048e074f45999;hp=9b5392668ce2fe6ae4cee86d5a2c6935c5cc005b;hb=0561939cf64e5d66153c2e7903e2411b802ff5c8;hpb=f3c7d186a15b89c39e360b9cc89545a0d24bd6a4 diff --git a/procln.c b/procln.c index 9b53926..0bb52e6 100644 --- a/procln.c +++ b/procln.c @@ -1,7 +1,7 @@ // // RMAC - Reboot's Macro Assembler for all Atari computers // PROCLN.C - Line Processing -// Copyright (C) 199x Landon Dyer, 2011-2017 Reboot and Friends +// Copyright (C) 199x Landon Dyer, 2011-2018 Reboot and Friends // RMAC derived from MADMAC v1.07 Written by Landon Dyer, 1986 // Source utilised with the kind permission of Landon Dyer // @@ -10,11 +10,14 @@ #include "6502.h" #include "amode.h" #include "direct.h" +#include "dsp56k_amode.h" +#include "dsp56k_mach.h" #include "error.h" #include "expr.h" #include "listing.h" #include "mach.h" #include "macro.h" +#include "op.h" #include "riscasm.h" #include "sect.h" #include "symbol.h" @@ -34,6 +37,15 @@ #define DECL_MP // Include 6502 keyword state machine tables #include "6502kw.h" +#define DEF_MO // Include OP keyword definitions +#define DECL_MO // Include OP keyword state machine tables +#include "opkw.h" + +#define DEF_DSP // Include DSP56K keywords definitions +#define DECL_DSP // Include DSP56K keyword state machine tables +#include "dsp56kkw.h" + + IFENT * ifent; // Current ifent static IFENT ifent0; // Root ifent IFENT * f_ifent; // Freelist of ifents @@ -176,18 +188,18 @@ DEBUG { printf("Assemble: Found TKEOF flag...\n"); } label = NULL; // No label lab_sym = NULL; // No (exported) label equate = NULL; // No equate - tk = tok.u32; // Save first token in line + tk = tok; // Save first token in line pcloc = (uint32_t)sloc; // Set beginning-of-line PC loop1: // Internal line processing loop - if (*tok.u32 == EOL) // Restart loop if end-of-line + if (*tok == EOL) // Restart loop if end-of-line goto loop; // First token MUST be a symbol (Shamus: not sure why :-/) - if (*tok.u32 != SYMBOL) + if (*tok != SYMBOL) { - if ((*tok.u32 >= KW_D0) && (*tok.u32 <= KW_R31)) + if ((*tok >= KW_D0) && (*tok <= KW_R31)) error("cannot use reserved keyword as label name or .equ"); else error("syntax error; expected symbol"); @@ -195,13 +207,13 @@ loop1: // Internal line processing loop goto loop; } - j = (int)tok.u32[2]; // Skip equates (normal statements) + j = (int)tok[2]; // Skip equates (normal statements) if (j == '=' || j == DEQUALS || j == SET || j == REG || j == EQUREG || j == CCDEF) { - equate = string[tok.u32[1]]; + equate = string[tok[1]]; equtyp = j; - tok.u32 += 3; + tok += 3; goto normal; } @@ -209,14 +221,14 @@ loop1: // Internal line processing loop if (j == ':' || j == DCOLON) { as68label: - label = string[tok.u32[1]]; // Get label name - labtyp = tok.u32[2]; // Get label type - tok.u32 += 3; // Go to next line token + label = string[tok[1]]; // Get label name + labtyp = tok[2]; // Get label type + tok += 3; // Go to next line token // 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.u32 == SYMBOL && tok.u32[2] == ':')) + if (as68_flag && (*tok == SYMBOL && tok[2] == ':')) { if (HandleLabel(label, labtyp) != 0) goto loop; @@ -226,17 +238,17 @@ as68label: } // EOL is legal here... - if (*tok.u32 == EOL) + if (*tok == EOL) goto normal; // First token MUST be a symbol (if we get here, tok didn't advance) - if (*tok.u32++ != SYMBOL) + if (*tok++ != SYMBOL) { error("syntax error; expected symbol"); goto loop; } - opname = p = string[*tok.u32++]; + opname = p = string[*tok++]; // Check to see if the SYMBOL is a keyword (a mnemonic or directive). // On output, `state' will have one of the values: @@ -269,16 +281,16 @@ as68label: // Check for ".b" ".w" ".l" after directive, macro or mnemonic. siz = SIZN; - switch (*tok.u32) + switch (*tok) { - 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; + 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; } // Do special directives (500..999) (These must be handled in "real time") @@ -308,7 +320,7 @@ as68label: goto loop; } - if (*tok.u32++ != ',') + if (*tok++ != ',') { error(comma_error); goto loop; @@ -398,13 +410,11 @@ normal: { if ((equtyp == EQUREG) && (sy->sattre & UNDEF_EQUR)) { -//REALLY? sy->sattre |= ~UNDEF_EQUR; sy->sattre &= ~UNDEF_EQUR; sy->svalue = 0; } else if ((equtyp == CCDEF) && (sy->sattre & UNDEF_CC)) { -//REALLY? sy->sattre |= ~UNDEF_CC; sy->sattre &= ~UNDEF_CC; sy->svalue = 0; } @@ -440,11 +450,11 @@ When checking to see if it's already been equated, issue a warning. } // Check for register to equate to - if ((*tok.u32 >= KW_R0) && (*tok.u32 <= KW_R31)) + if ((*tok >= KW_R0) && (*tok <= KW_R31)) { // sy->sattre = EQUATEDREG | RISCSYM; // Mark as equated register sy->sattre = EQUATEDREG; // Mark as equated register - riscreg = (*tok.u32 - KW_R0); + riscreg = (*tok - KW_R0); //is there any reason to do this, since we're putting this in svalue? //i'm thinking, no. Let's test that out! :-D // sy->sattre |= (riscreg << 8); // Store register number @@ -460,15 +470,15 @@ When checking to see if it's already been equated, issue a warning. #endif // Check for "," override notation - if ((tok.u32[1] == ',') && (tok.u32[2] == CONST)) + if ((tok[1] == ',') && (tok[2] == CONST)) { // Advance token pointer to the constant - tok.u32 += 3; + tok += 3; // Anything other than a 0 or a 1 will result in "No Bank" - if (*(uint64_t *)tok.u32 == 0) + if (*(uint64_t *)tok == 0) registerbank = BANK_0; - else if (*(uint64_t *)tok.u32 == 1) + else if (*(uint64_t *)tok == 1) registerbank = BANK_1; } @@ -485,15 +495,13 @@ When checking to see if it's already been equated, issue a warning. sy->sattre |= regbank; // Store register bank #endif eattr = ABS | DEFINED | GLOBAL; -// & what does this $80000080 constant mean??? -// eval = 0x80000080 + (riscreg) + (registerbank << 8); eval = riscreg; - tok.u32++; + tok++; } // Checking for a register symbol - else if (tok.u32[0] == SYMBOL) + else if (tok[0] == SYMBOL) { - sy2 = lookup(string[tok.u32[1]], LABEL, j); + sy2 = lookup(string[tok[1]], LABEL, j); // Make sure symbol is a valid equreg if (!sy2 || !(sy2->sattre & EQUATEDREG)) @@ -506,7 +514,7 @@ When checking to see if it's already been equated, issue a warning. eattr = ABS | DEFINED | GLOBAL; // Copy symbols attributes sy->sattre = sy2->sattre; eval = (sy2->svalue & 0xFFFFF0FF); - tok.u32 += 2; + tok += 2; } } else @@ -528,9 +536,9 @@ When checking to see if it's already been equated, issue a warning. sy->sattre |= EQUATEDCC; eattr = ABS | DEFINED | GLOBAL; - if (tok.u32[0] == SYMBOL) + if (tok[0] == SYMBOL) { - sy2 = lookup(string[tok.u32[1]], LABEL, j); + sy2 = lookup(string[tok[1]], LABEL, j); if (!sy2 || !(sy2->sattre & EQUATEDCC)) { @@ -542,23 +550,22 @@ When checking to see if it's already been equated, issue a warning. eattr = ABS | DEFINED | GLOBAL; sy->sattre = sy2->sattre; eval = sy2->svalue; - tok.u32 += 2; + tok += 2; } } else if (expr(exprbuf, &eval, &eattr, &esym) != OK) goto loop; } - //equ a equr - else if (*tok.u32 == SYMBOL) + // equ an equr + else if (*tok == SYMBOL) { - sy2 = lookup(string[tok.u32[1]], LABEL, j); + sy2 = lookup(string[tok[1]], LABEL, j); if (sy2 && (sy2->sattre & EQUATEDREG)) { sy->stype = sy2->stype; sy->sattr = sy2->sattr; sy->sattre = sy2->sattre; -//ICK sy->svalue = (sy2->svalue & 0xFFFFF0FF); sy->svalue = sy2->svalue; goto loop; } @@ -575,7 +582,7 @@ When checking to see if it's already been equated, issue a warning. } sy->sattr |= eattr | EQUATED; // Symbol inherits value and attributes - sy->svalue = (uint32_t)eval; + sy->svalue = eval; if (list_flag) // Put value in listing listvalue((uint32_t)eval); @@ -664,6 +671,125 @@ When checking to see if it's already been equated, issue a warning. } } + // If we are in OP mode and still in need of a mnemonic then search for one + if (robjproc && ((state < 0) || (state >= 1000))) + { + for(state=0, p=opname; state>=0;) + { + j = mobase[state] + (int)tolowertab[*p]; + + // Reject, character doesn't match + if (mocheck[j] != state) + { + state = -1; // No match + break; + } + + // Must accept or reject at EOS + if (!*++p) + { + state = moaccept[j]; // (-1 on no terminal match) + break; + } + + state = motab[j]; + } + + // Call OP code generator if we found a mnemonic + if (state >= 3100) + { + GenerateOPCode(state); + goto loop; + } + } + + // If we are in 56K mode and still in need of a mnemonic then search for one + if (dsp56001 && ((state < 0) || (state >= 1000))) + { + for(state=0, p=opname; state>=0;) + { + j = dspbase[state] + (int)tolowertab[*p]; + + // Reject, character doesn't match + if (dspcheck[j] != state) + { + state = -1; // No match + break; + } + + // Must accept or reject at EOS + if (!*++p) + { + state = dspaccept[j]; // (-1 on no terminal match) + break; + } + + state = dsptab[j]; + } + + // Call DSP code generator if we found a mnemonic + if (state >= 2000) + { + LONG parcode; + int operands; + MNTABDSP * md = &dsp56k_machtab[state - 2000]; + deposit_extra_ea = 0; // Assume no extra word needed + + if (md->mnfunc == dsp_mult) + { + // Special case for multiplication instructions: they require + // 3 operands + if ((operands = dsp_amode(3)) == ERROR) + goto loop; + } + else if ((md->mnattr & PARMOVE) && md->mn0 != M_AM_NONE) + { + if (dsp_amode(2) == ERROR) + goto loop; + } + else if ((md->mnattr & PARMOVE) && md->mn0 == M_AM_NONE) + { + // Instructions that have parallel moves but use no operands + // (probably only move). In this case, don't parse addressing + // modes--just go straight to parallel parse + dsp_am0 = dsp_am1 = M_AM_NONE; + } + else + { + // Non parallel move instructions can have up to 4 parameters + // (well, only tcc instructions really) + if ((operands = dsp_amode(4)) == ERROR) + goto loop; + + if (operands == 4) + { + dsp_tcc4(md->mninst); + goto loop; + } + } + + if (md->mnattr & PARMOVE) + { + // Check for parallel moves + if ((parcode = parmoves(dsp_a1reg)) == ERROR) + goto loop; + } + else + { + if (*tok != EOL) + error("parallel moves not allowed with this instruction"); + + parcode = 0; + } + + while ((dsp_am0 & md->mn0) == 0 || (dsp_am1 & md->mn1) == 0) + md = &dsp56k_machtab[md->mncont]; + + (*md->mnfunc)(md->mninst | (parcode << 8)); + goto loop; + } + } + // Invoke macro or complain about bad mnemonic if (state < 0) { @@ -711,7 +837,7 @@ When checking to see if it's already been equated, issue a warning. if (amode(1) < 0) // Parse 0, 1 or 2 addr modes goto loop; - if (*tok.u32 != EOL) + if (*tok != EOL) error(extra_stuff); amsk0 = amsktab[am0]; @@ -728,16 +854,13 @@ When checking to see if it's already been equated, issue a warning. // Keep a backup of chptr (used for optimisations during codegen) chptr_opcode = chptr; - for(;;) - { - if ((m->mnattr & siz) && (amsk0 & m->mn0) != 0 && (amsk1 & m->mn1) != 0) - { - (*m->mnfunc)(m->mninst, siz); - goto loop; - } - + while (!(m->mnattr & siz) || (amsk0 & m->mn0) == 0 || (amsk1 & m->mn1) == 0) m = &machtab[m->mncont]; - } + + DEBUG { printf(" 68K: mninst=$%X, siz=$%X, mnattr=$%X, amsk0=$%X, mn0=$%X, amsk1=$%X, mn1=$%X\n", m->mninst, siz, m->mnattr, amsk0, m->mn0, amsk1, m->mn1); } + + (*m->mnfunc)(m->mninst, siz); + goto loop; } @@ -754,7 +877,6 @@ int HandleLabel(char * label, int labelType) { symbol = NewSymbol(label, LABEL, environment); symbol->sattr = 0; -// symbol->sattre = RISCSYM; symbol->sattre = 0; } else if (symbol->sattr & DEFINED)