home *** CD-ROM | disk | FTP | other *** search
- #include <string.h>
- #include <stdio.h>
-
- #include "mselect.h" /*external selection of microprocessor symbol table*/
- #include "proto.h"
- #include "as.h"
- #include "structs.h"
- #ifdef HC11
- #include "table11.h"
- #else
- #include "table5.h"
- #endif
- #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 INCLUDE 11 /* include <file> or "file" ver TER_2.0 */
- #define END 12 /* include <file> terminator ver TER_2.0 */
- #define IFD 13 /* if define <symbol> ver TER_2.0 */
- #define IFND 14 /* if not define <symbol> ver TER_2.0 */
- #define ELSE 15 /* else (for IF statements) ver TER_2.0 */
- #define ENDIF 16 /* endif (for IF statements) ver TER_2.0 */
- #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 */
-
-
- 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 */
- "else", PSEUDO, ELSE, 0,/* ver TER_2.0 6/17/89 */
- "end", PSEUDO, END, 0, /* ver TER_2.0 6/17/89 */
- "endif", PSEUDO, ENDIF, 0, /* ver TER_2.0 6/17/89 */
- "equ", PSEUDO, EQU, 0,
- "fcb", PSEUDO, FCB, 0,
- "fcc", PSEUDO, FCC, 0,
- "fdb", PSEUDO, FDB, 0,
- "fill", PSEUDO, FILL, 0,
- "ifd", PSEUDO, IFD, 0, /* ver TER_2.0 6/17/89 */
- "ifnd", PSEUDO, IFND, 0,/* ver TER_2.0 6/17/89 */
- "include", PSEUDO, INCLUDE, 0, /* ver TER_2.0 6/17/89 */
- "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;
- int c; /* test variable ver TER_2.0 6/18/89 */
- char *savept; /* savept is pointer to string save */
- FILE *FdTemp; /* ver TER_2.0 6/17/89 */
- /*
- * 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"))
- Lflag = 1;
- else if (head(Operand, "nol"))
- Lflag = 0;
- else if (head(Operand, "c")) {
- Cflag = 1;
- Ctotal = 0;
- } else if (head(Operand, "noc"))
- Cflag = 0;
- else if (head(Operand, "contc")) {
- Cflag = 1;
- } else if (head(Operand, "s"))
- Sflag = 1;
- else if (head(Operand, "cre"))
- 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 if (head(Operand, "nnf")) /* no extra line no. */
- nfFlag = 0; /* w include files 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 INCLUDE: /* case INCLUDE added ver TER_2.0 6/17/89 */
- P_force = 0; /* no PC in printed output */
- if ((c = FNameGet(InclFName)) == 0)
- error("Improper INCLUDE statement");
- else {
- if (FdCount > MAXINCFILES)
- error("too many INCLUDE files");
- else {
- if ((FdTemp = fopen(InclFName, "r")) == 0) {
- warn(strcat("can't open INCLUDE file ", InclFName));
- } else {
- if ((savept = strsave(InclFName)) == 0)
- error("out of memory for INCLUDE file name");
- else {
- InclFiles[FdCount].fp = Fd; /* save current fp */
- if (nfFlag) {
- InclFiles[FdCount].line_num = Line_num;
- /*
- * save current line
- * count
- */
- Line_num = 0; /* reset for new file */
- }
- InclFiles[FdCount].name = Argv[Cfn];
- /*
- * save pointer to current
- * name
- */
- Argv[Cfn] = savept;
- /*
- * now replace pointer to
- * current name with pointer
- * to name of Include file
- */
- Fd = FdTemp; /* now replace current
- * file with INCLUDE fp */
- FdCount++; /* and increment "stack" */
- #ifdef DEBUG2
- printf("pseudo INCLUDE: FdCount=%d\n", FdCount);
- printf(" new input file pointer=%d\n", Fd);
- printf(" new file name=%s\n", Argv[Cfn]);
- #endif
- }
- }
- }
- }
- break;
- case END:
- P_force = 0;
- if (FdCount > 0) { /* skip END statements in files
- * received from CLI arguments */
- fclose(Fd); /* close file from this level nest */
- FdCount--; /* "pop stack" */
- Fd = InclFiles[FdCount].fp; /* restore fp from
- * nested stack */
- if (nfFlag)
- Line_num = InclFiles[FdCount].line_num;
- Argv[Cfn] = InclFiles[FdCount].name;
- /* restore file name pointer */
- #ifdef DEBUG2
- printf("pseudo END: FdCount=%d\n", FdCount);
- printf(" new input file pointer=%d\n", Fd);
- printf(" new file name=%s\n", Argv[Cfn]);
- #endif
- }
- break;
- case IFD:
- #ifdef DEBUG3
- printf("case IFD: in pseudo\n");
- #endif
- P_force = 0;
- c = eval_ifd();
- IfMachine(c);
- break;
- case IFND:
- P_force = 0;
- c = eval_ifnd();
- IfMachine(c);
- break;
- case ELSE:
- P_force = 0;
- IfMachine(IF_ELSE);
- break;
- case ENDIF:
- P_force = 0;
- IfMachine(IF_ENDIF);
- 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;
- 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);
- }
-