home *** CD-ROM | disk | FTP | other *** search
- #include <string.h>
- #include <stdio.h>
-
- #include "proto.h"
- #include "as.h"
- #include "structs.h"
-
- #include "mselect.h"
-
-
- #if (defined MC68HC11)
- #include "table11.h"
- #else
- #if (defined MC68HC05)
- #include "table5.h"
- #else
- #if (defined MC6809)
- #include "table9.h"
- #else
- #error undefined target processor, please define MICRO
- #endif /*6809*/
- #endif /*68HC05*/
- #endif /*68HC11*/
-
-
-
- #include "extvars.h"
-
- /*
- * pseudo --- pseudo op processing
- */
-
- #define RMB 0 /* Reserve Memory Bytes */
- #define FCB 1 /* Form Constant Bytes */
- #define FDB 2 /* Form Double Bytes (words) */
- #define FCC 3 /* Form Constant Characters */
- #define ORG 4 /* Origin */
- #define EQU 5 /* Equate */
- #define ZMB 6 /* Zero memory bytes */
- #define FILL 7 /* block fill constant bytes */
- #define OPT 8 /* assembler option */
- #define NULL_OP 9 /* null pseudo op */
- #define PAGE 10 /* new page */
- #define BSS 17 /* block storage segment (RAM) ver TER_2.09 */
- #define CODE 18 /* code segment ver TER_2.09 25 Jul 89 */
- #define DATA 19 /* data segment ver TER_2.09 25 Jul 89 */
- #define AUTO 20 /* data segment ver TER_2.09 25 Jul 89 */
- #define END 21 /* end of file directive */
-
- struct oper pseudo[] = {
- "=", PSEUDO, EQU, 0, /* ver TER_2.09 25 Jul 89 */
- "auto", PSEUDO, AUTO, 0,/* ver TER_2.09 25 Jul 89 */
- "bss", PSEUDO, BSS, 0, /* ver TER_2.09 25 Jul 89 */
- "bsz", PSEUDO, ZMB, 0,
- "code", PSEUDO, CODE, 0,/* ver TER_2.09 25 Jul 89 */
- "data", PSEUDO, DATA, 0,/* ver TER_2.09 25 Jul 89 */
- "end", PSEUDO, END, 0,
- "equ", PSEUDO, EQU, 0,
- "fcb", PSEUDO, FCB, 0,
- "fcc", PSEUDO, FCC, 0,
- "fdb", PSEUDO, FDB, 0,
- "fill", PSEUDO, FILL, 0,
- "nam", PSEUDO, NULL_OP, 0,
- "name", PSEUDO, NULL_OP, 0,
- "opt", PSEUDO, OPT, 0,
- "org", PSEUDO, ORG, 0,
- "pag", PSEUDO, PAGE, 0,
- "page", PSEUDO, PAGE, 0,
- "ram", PSEUDO, BSS, 0, /* ver TER_2.09 25 Jul 89 */
- "rmb", PSEUDO, RMB, 0,
- "spc", PSEUDO, NULL_OP, 0,
- "ttl", PSEUDO, NULL_OP, 0,
- "zmb", PSEUDO, ZMB, 0
- };
-
- /*
- * do_pseudo --- do pseudo op processing
- */
- void
- do_pseudo(int op)
- /* int op; which op */
- {
- char fccdelim;
- int fill;
- /*
- * void pouterror(), NewPage(), IfMachine();
- *//* rel TER_2.0 6/18/89 */
- /* void PC_Exchange(); *//* ver TER_2.09 25 Jul 89 */
-
- if (op != EQU && *Label)
- install(Label, Pc);
-
- P_force++;
-
- #ifdef DEBUG3
- printf("%s, line no. ", Argv[Cfn]); /* current file name */
- printf("%d: ", Line_num); /* current line number */
- printf(" Pseudo Op=%u\n", op);
- #endif
-
- switch (op) {
- case RMB: /* reserve memory bytes */
- if (eval()) {
- Pc += Result;
- f_record(); /* flush out bytes */
- } else
- error("Undefined Operand during Pass One");
- break;
- case ZMB: /* zero memory bytes */
- if (eval())
- while (Result--)
- emit(0);
- else
- error("Undefined Operand during Pass One");
- break;
- case FILL: /* fill memory with constant */
- eval();
- fill = Result;
- if (*Optr++ != ',')
- error("Bad fill");
- else {
- Optr = skip_white(Optr);
- eval();
- while (Result--)
- emit(fill);
- }
- break;
- case FCB: /* form constant byte(s) */
- do {
- Optr = skip_white(Optr);
- eval();
- if (Result > 0xFF) {
- if (!Force_byte)
- warn("Value truncated");
- Result = lobyte(Result);
- }
- emit(Result);
- } while (*Optr++ == ',');
- break;
- case FDB: /* form double byte(s) */
- do {
- Optr = skip_white(Optr);
- eval();
- eword(Result);
- } while (*Optr++ == ',');
- break;
- case FCC: /* form constant characters */
- if (*Operand == EOS)
- break;
- /* Optr++;*/
- fccdelim = *Optr++;
- if ((fccdelim != SQUOT) && (fccdelim != DQUOT))
- {error("Missing Delimiter - \' or \" expected");
- break;}
- /* putchar ( fccdelim );*/
- while (*Optr != EOS && *Optr != fccdelim)
- emit(*Optr++);
- if (*Optr == fccdelim)
- {Optr++;}
- else
- {error("Missing Delimiter");}
- break;
- case ORG: /* origin */
- if (eval()) {
- Old_pc = Pc = Result;
- f_record(); /* flush out any bytes */
- } else
- error("Undefined Operand during Pass One");
- break;
- case EQU: /* equate */
- if (*Label == EOS) {
- error("EQU requires label");
- break;
- }
- if (eval()) {
- install(Label, Result);
- Old_pc = Result; /* override normal */
- } else
- error("Undefined Operand during Pass One");
- break;
- case OPT: /* assembler option */
- P_force = 0;
- if (head(Operand, "l") || head(Operand, "list"))
- Lflag = 1;
- else if (head(Operand, "nol") || head(Operand, "nolist"))
- Lflag = 0;
- else if (head(Operand, "c") || head(Operand, "cyc")) {
- Cflag = 1;
- Ctotal = 0;
- } else if (head(Operand, "noc") || head(Operand, "nocyc"))
- Cflag = 0;
- else if (head(Operand, "contc") || head(Operand, "contcyc")) {
- Cflag = 1;
- } else if (head(Operand, "s") || head(Operand, "sym"))
- Sflag = 1;
- else if (head(Operand, "cre") || head(Operand, "x"))
- CREflag = 1;
- else if (head(Operand, "p50")) /* turn on page flag */
- Pflag50 = 1; /* ver (TER) 2.02 19 Jun 89 */
- else if (head(Operand, "crlf")) /* add <CR> <LF> to */
- CRflag = 1; /* S record ver TER_2.08 */
- else
- error("Unrecognized OPT");
- break;
- case PAGE: /* go to a new page */
- P_force = 0;
- N_page = 1;
- if (Pass == 2)
- if (Lflag)
- NewPage();
- break;
- case NULL_OP: /* ignored psuedo ops */
- P_force = 0;
- break;
- case CODE: /* CODE,DATA,BSS,AUTO ver TER_2.09 */
- PC_Exchange(0);
- break;
- case DATA:
- PC_Exchange(1);
- break;
- case BSS:
- PC_Exchange(2);
- break;
- case AUTO:
- PC_Exchange(3);
- break;
- case END:
- P_force = 0;
- end_found = YES;
- break;
- default:
- fatal("Pseudo error");
- break;
- }
- }
-
-
- /*
- * PC_Exchange --- Save current PC and recover requested one added ver
- * TER_2.09
- */
- void
- PC_Exchange(int PC_ptr_new)
- /* int PC_ptr_new; request 0=CODE,1=DATA,2=BSS */
- {
- P_force = 0; /* no PC in output cuz wrong first time (?) */
- PC_Save[PC_ptr] = Pc; /* save current PC */
- PC_ptr = PC_ptr_new; /* remember which one we're using */
- Old_pc = Pc = PC_Save[PC_ptr]; /* recover the one requested */
- f_record(); /* flush out any bytes, this is really an ORG */
- }
-
- /* pseudo module ends here */
-
-
-
- /*
- * install --- add a symbol to the table
- */
- int
- install(char *str, int val)
- {
- struct link *lp;
- struct nlist *np, *p, *backp;
- int i;
- /* char *LastChar(); *//* ver TER_2.0 */
-
- if (!alpha(*str)) {
- error("Illegal Symbol Name");
- return (NO);
- }
- if ((np = lookup(str)) != NULL) {
- if (*LastChar(str) == '@') { /* redefinable symbol ver
- * TER_2.0 */
- np->def = val; /* redefined */
- return (YES);
- }
- if (Pass == 2) {
- np->def2 = 2; /* defined for this pass=Pass ver
- * TER_2.0 */
- if (np->def == val)
- return (YES);
- else {
- error("Phasing Error");
- return (NO);
- }
- }
- error("Symbol Redefined");
- return (NO);
- }
- /* enter new symbol */
- #ifdef DEBUG
- printf("Installing %s as %d\n", str, val);
- #endif
- np = (struct nlist *) alloc(sizeof(struct nlist));
- if (np == (struct nlist *) ERR) {
- error("Symbol table full");
- return (NO);
- }
- np->name = alloc(strlen(str) + 1);
- if (np->name == (char *) ERR) {
- error("Symbol table full");
- return (NO);
- }
- strcpy(np->name, str);
- np->def = val;
- np->def2 = 1; /* defined for this pass=Pass ver TER_2.0 */
- np->Lnext = NULL;
- np->Rnext = NULL;
- lp = (struct link *) alloc(sizeof(struct link));
- np->L_list = lp;
- lp->L_num = Line_num;
- lp->next = NULL;
- p = root;
- backp = NULL;
- while (p != NULL) {
- backp = p;
- i = strcmp(str, p->name);
- if (i < 0)
- p = p->Lnext;
- else
- p = p->Rnext;
- }
- if (backp == NULL)
- root = np;
- else if (strcmp(str, backp->name) < 0)
- backp->Lnext = np;
- else
- backp->Rnext = np;
- return (YES);
- }
-
- /*
- * lookup --- find string in symbol table
- */
- struct nlist *
- lookup(char *name)
- {
- struct nlist *np;
- int i;
- char *c; /* ver TER_2.0 */
-
- c = name; /* copy symbol pointer */
- while (alphan(*c)) /* search for end of symbol */
- c++; /* next char */
- *c = EOS; /* disconnect anything after for good compare */
- /* end of mods for ver TER_2.0 */
-
- np = root; /* and now go on and look for symbol */
- while (np != NULL) {
- i = strcmp(name, np->name);
- if (i == 0) {
- Last_sym = np->def;
- return (np);
- } else if (i < 0)
- np = np->Lnext;
- else
- np = np->Rnext;
- }
- Last_sym = 0;
- /*
- * if (Pass == 2) error ("symbol Undefined on pass 2");
- */
- /* commented out ver TER_2.0 2 Jul 89 */
- /* function used in IFD */
- return (NULL);
- }
-
-
- #define NMNE (sizeof(table)/ sizeof(struct oper))
- #define NPSE (sizeof(pseudo)/ sizeof(struct oper))
- /*
- * mne_look --- mnemonic lookup
- *
- * Return pointer to an oper structure if found. Searches both the machine
- * mnemonic table and the pseudo table.
- */
- struct oper *
- mne_look(char *str)
- {
- struct oper *low, *high, *mid;
- int cond;
-
- /* Search machine mnemonics first */
- low = &table[0];
- high = &table[NMNE - 1];
- while (low <= high) {
- mid = low + (high - low) / 2;
- if ((cond = strcmp(str, mid->mnemonic)) < 0)
- high = mid - 1;
- else if (cond > 0)
- low = mid + 1;
- else
- return (mid);
- }
-
- /* Check for pseudo ops */
- low = &pseudo[0];
- high = &pseudo[NPSE - 1];
- while (low <= high) {
- mid = low + (high - low) / 2;
- if ((cond = strcmp(str, mid->mnemonic)) < 0)
- high = mid - 1;
- else if (cond > 0)
- low = mid + 1;
- else
- return (mid);
- }
-
- return (NULL);
- }
-