- if ((c=endline()) == 0) { return; }
- /*
- * If the first character is a digit then assume
- * a local symbol is being specified. The symbol
- * must end with $: to be valid.
- * pass 0:
- * Construct a tsym structure at the first
- * occurance of the symbol. Flag the symbol
- * as multiply defined if not the first occurance.
- * pass 1:
- * Load area, address, and fuzz values
- * into structure tsym.
- * pass 2:
- * Check for assembler phase error and
- * multiply defined error.
- */
- if (ctype[c] & DIGIT) {
- if (flevel)
- return;
- n = 0;
- while ((d = digit(c, 10)) >= 0) {
- n = 10*n + d;
- c = get();
- }
- if (c != '$' || get() != ':')
- qerr();
- tp = symp->s_tsym;
- if (pass == 0) {
- while (tp) {
- if (n == tp->t_num) {
- tp->t_flg |= S_MDF;
- break;
- }
- tp = tp->t_lnk;
- }
- if (tp == NULL) {
- tp=(struct tsym *) new (sizeof(struct tsym));
- tp->t_lnk = symp->s_tsym;
- tp->t_num = n;
- tp->t_flg = 0;
- tp->t_area = dot.s_area;
- tp->t_addr = dot.s_addr;
- symp->s_tsym = tp;
- }
- } else {
- while (tp) {
- if (n == tp->t_num) {
- break;
- }
- tp = tp->t_lnk;
- }
- if (tp) {
- if (pass == 1) {
- fuzz = tp->t_addr - dot.s_addr;
- tp->t_area = dot.s_area;
- tp->t_addr = dot.s_addr;
- } else {
- phase(tp->t_area, tp->t_addr);
- if (tp->t_flg & S_MDF)
- err('m');
- }
- } else {
- err('u');
- }
- }
- lmode = ALIST;
- goto loop;
- }
- /*
- * If the first character is a letter then assume a label,
- * symbol, assembler directive, or assembler mnemonic is
- * being processed.
- */
- if ((ctype[c] & LETTER) == 0) {
- if (flevel) {
- return;
- } else {
- qerr();
- }
- }
- getid(id, c);
- c = getnb();
- /*
- * If the next character is a : then a label is being processed.
- * A double :: defines a global label. If this is new label
- * then create a symbol structure.
- * pass 0:
- * Flag multiply defined labels.
- * pass 1:
- * Load area, address, and fuzz values
- * into structure symp.
- * pass 2:
- * Check for assembler phase error and
- * multiply defined error.
- */
- if (c == ':') {
- if (flevel)
- return;
- if ((c = get()) != ':') {
- unget(c);
- c = 0;
- }
- symp = lookup(id);
- if (symp == &dot)
- err('.');
- if (pass == 0)
- if ((symp->s_type != S_NEW) &&
- ((symp->s_flag & S_ASG) == 0))
- symp->s_flag |= S_MDF;
- if (pass != 2) {
- fuzz = symp->s_addr - dot.s_addr;
- symp->s_type = S_USER;
- symp->s_area = dot.s_area;
- symp->s_addr = dot.s_addr;
- } else {
- if (symp->s_flag & S_MDF)
- err('m');
- phase(symp->s_area, symp->s_addr);
- }
- if (c) {
- symp->s_flag |= S_GBL;
- }
- lmode = ALIST;
- goto loop;
- }
- /*
- * If the next character is a = then an equate is being processed.
- * A double == defines a global equate. If this is new variable
- * then create a symbol structure.
- */
- if (c == '=') {
- if (flevel)
- return;
- if ((c = get()) != '=') {
- unget(c);
- c = 0;
- }
- clrexpr(&e1);
- expr(&e1, 0);
- sp = lookup(id);
- if (sp == &dot) {
- outall();
- if (e1.e_flag || e1.e_base.e_ap != dot.s_area)
- err('.');
- } else
- if (sp->s_type != S_NEW && (sp->s_flag & S_ASG) == 0) {
- err('m');
- }
- sp->s_type = S_USER;
- sp->s_area = e1.e_base.e_ap;
- sp->s_addr = laddr = e1.e_addr;
- sp->s_flag |= S_ASG;
- if (c) {
- sp->s_flag |= S_GBL;
- }
- lmode = ELIST;
- goto loop;
- }
- unget(c);
- lmode = flevel ? SLIST : CLIST;
- if ((mp = mlookup(id)) == NULL) {
- if (!flevel)
- err('o');
- return;
- }
- /*
- * If we have gotten this far then we have found an
- * assembler directive or an assembler mnemonic.
- *
- * Check for .if, .else, .endif, and .page directives
- * which are not controlled by the conditional flags
- */
- switch (mp->m_type) {
-
- case S_IF:
- n = absexpr();
- if (tlevel < MAXIF) {
- ++tlevel;
- ifcnd[tlevel] = n;
- iflvl[tlevel] = flevel;
- if (n == 0) {
- ++flevel;
- }
- } else {
- err('i');
- }
- lmode = ELIST;
- laddr = n;
- return;
-
- case S_ELSE:
- if (ifcnd[tlevel]) {
- if (++flevel > (iflvl[tlevel]+1)) {
- err('i');
- }
- } else {
- if (--flevel < iflvl[tlevel]) {
- err('i');
- }
- }
- lmode = SLIST;
- return;
-
- case S_ENDIF:
- if (tlevel) {
- flevel = iflvl[tlevel--];
- } else {
- err('i');
- }
- lmode = SLIST;
- return;
-
- case S_PAGE:
- lop = NLPP;
- lmode = NLIST;
- return;
-
- default:
- break;
- }
- if (flevel)
- return;
- /*
- * If we are not in a false state for .if/.else then
- * process the assembler directives here.
- */
- switch (mp->m_type) {
-
- case S_EVEN:
- outall();
- laddr = dot.s_addr = (dot.s_addr + 1) & ~1;
- lmode = ALIST;
- break;
-
- case S_ODD:
- outall();
- laddr = dot.s_addr |= 1;
- lmode = ALIST;
- break;
-
- case S_BYTE:
- case S_WORD:
- do {
- clrexpr(&e1);
- expr(&e1, 0);
- if (mp->m_type == S_BYTE) {
- outrb(&e1, R_NORM);
- } else {
- outrw(&e1, R_NORM);
- }
- } while ((c = getnb()) == ',');
- unget(c);
- break;
-
- case S_ASCII:
- case S_ASCIZ:
- if ((d = getnb()) == '\0')
- qerr();
- while ((c = getmap(d)) >= 0)
- outab(c);
- if (mp->m_type == S_ASCIZ)
- outab(0);
- break;
-
- case S_ASCIS:
- if ((d = getnb()) == '\0')
- qerr();
- c = getmap(d);
- while (c >= 0) {
- if ((n = getmap(d)) >= 0) {
- outab(c);
- } else {
- outab(c | 0x80);
- }
- c = n;
- }
- break;
-
- case S_BLK:
- clrexpr(&e1);
- expr(&e1, 0);
- outchk(HUGE,HUGE);
- dot.s_addr += e1.e_addr*mp->m_valu;
- lmode = BLIST;
- break;
-
- case S_TITLE:
- p = tb;
- if ((c = getnb()) != 0) {
- do {
- if (p < &tb[NTITL-1])
- *p++ = c;
- } while ((c = get()) != 0);
- }
- *p = 0;
- unget(c);
- lmode = SLIST;
- break;
-
- case S_SBTL:
- p = stb;
- if ((c = getnb()) != 0) {
- do {
- if (p < &stb[NSBTL-1])
- *p++ = c;
- } while ((c = get()) != 0);
- }
- *p = 0;
- unget(c);
- lmode = SLIST;
- break;
-
- case S_MODUL:
- getst(id, getnb()); // a module can start with a digit
- if (pass == 0) {
- if (module[0]) {
- err('m');
- } else {
- strncpy(module, id, NCPS);
- }
- }
- lmode = SLIST;
- break;
-
- case S_OPTSDCC:
- p = optsdcc;
- if ((c = getnb()) != 0) {
- do {
- if (p < &optsdcc[NINPUT-1])
- *p++ = c;
- } while ((c = get()) != 0);
- }
- *p = 0;
- unget(c);
- lmode = SLIST;
+ if ((c=endline()) == 0) { return; }
+ /*
+ * If the first character is a digit then assume
+ * a local symbol is being specified. The symbol
+ * must end with $: to be valid.
+ * pass 0:
+ * Construct a tsym structure at the first
+ * occurance of the symbol. Flag the symbol
+ * as multiply defined if not the first occurance.
+ * pass 1:
+ * Load area, address, and fuzz values
+ * into structure tsym.
+ * pass 2:
+ * Check for assembler phase error and
+ * multiply defined error.
+ */
+ if (ctype[c] & DIGIT) {
+ if (flevel)
+ return;
+ n = 0;
+ while ((d = digit(c, 10)) >= 0) {
+ n = 10*n + d;
+ c = get();
+ }
+ if (c != '$' || get() != ':')
+ qerr();
+ tp = symp->s_tsym;
+ if (pass == 0) {
+ while (tp) {
+ if (n == tp->t_num) {
+ tp->t_flg |= S_MDF;
+ break;
+ }
+ tp = tp->t_lnk;
+ }
+ if (tp == NULL) {
+ tp=(struct tsym *) new (sizeof(struct tsym));
+ tp->t_lnk = symp->s_tsym;
+ tp->t_num = n;
+ tp->t_flg = 0;
+ tp->t_area = dot.s_area;
+ tp->t_addr = dot.s_addr;
+ symp->s_tsym = tp;
+ }
+ } else {
+ while (tp) {
+ if (n == tp->t_num) {
+ break;
+ }
+ tp = tp->t_lnk;
+ }
+ if (tp) {
+ if (pass == 1) {
+ fuzz = tp->t_addr - dot.s_addr;
+ tp->t_area = dot.s_area;
+ tp->t_addr = dot.s_addr;
+ } else {
+ phase(tp->t_area, tp->t_addr);
+ if (tp->t_flg & S_MDF)
+ err('m');
+ }
+ } else {
+ err('u');
+ }
+ }
+ lmode = ALIST;
+ goto loop;
+ }
+ /*
+ * If the first character is a letter then assume a label,
+ * symbol, assembler directive, or assembler mnemonic is
+ * being processed.
+ */
+ if ((ctype[c] & LETTER) == 0) {
+ if (flevel) {
+ return;
+ } else {
+ qerr();
+ }
+ }
+ getid(id, c);
+ c = getnb();
+ /*
+ * If the next character is a : then a label is being processed.
+ * A double :: defines a global label. If this is new label
+ * then create a symbol structure.
+ * pass 0:
+ * Flag multiply defined labels.
+ * pass 1:
+ * Load area, address, and fuzz values
+ * into structure symp.
+ * pass 2:
+ * Check for assembler phase error and
+ * multiply defined error.
+ */
+ if (c == ':') {
+ if (flevel)
+ return;
+ if ((c = get()) != ':') {
+ unget(c);
+ c = 0;
+ }
+ symp = lookup(id);
+ if (symp == &dot)
+ err('.');
+ if (pass == 0)
+ if ((symp->s_type != S_NEW) &&
+ ((symp->s_flag & S_ASG) == 0))
+ symp->s_flag |= S_MDF;
+ if (pass != 2) {
+ fuzz = symp->s_addr - dot.s_addr;
+ symp->s_type = S_USER;
+ symp->s_area = dot.s_area;
+ symp->s_addr = dot.s_addr;
+ } else {
+ if (symp->s_flag & S_MDF)
+ err('m');
+ phase(symp->s_area, symp->s_addr);
+ }
+ if (c) {
+ symp->s_flag |= S_GBL;
+ }
+ lmode = ALIST;
+ goto loop;
+ }
+ /*
+ * If the next character is a = then an equate is being processed.
+ * A double == defines a global equate. If this is new variable
+ * then create a symbol structure.
+ */
+ if (c == '=') {
+ if (flevel)
+ return;
+ if ((c = get()) != '=') {
+ unget(c);
+ c = 0;
+ }
+ clrexpr(&e1);
+ expr(&e1, 0);
+ sp = lookup(id);
+ if (sp == &dot) {
+ outall();
+ if (e1.e_flag || e1.e_base.e_ap != dot.s_area)
+ err('.');
+ } else
+ if (sp->s_type != S_NEW && (sp->s_flag & S_ASG) == 0) {
+ err('m');
+ }
+ sp->s_type = S_USER;
+ sp->s_area = e1.e_base.e_ap;
+ sp->s_addr = laddr = e1.e_addr;
+ sp->s_flag |= S_ASG;
+ if (c) {
+ sp->s_flag |= S_GBL;
+ }
+ lmode = ELIST;
+ goto loop;
+ }
+ unget(c);
+ lmode = flevel ? SLIST : CLIST;
+ if ((mp = mlookup(id)) == NULL) {
+ if (!flevel)
+ err('o');
+ return;
+ }
+ /*
+ * If we have gotten this far then we have found an
+ * assembler directive or an assembler mnemonic.
+ *
+ * Check for .if, .else, .endif, and .page directives
+ * which are not controlled by the conditional flags
+ */
+ switch (mp->m_type) {
+
+ case S_IF:
+ n = absexpr();
+ if (tlevel < MAXIF) {
+ ++tlevel;
+ ifcnd[tlevel] = n;
+ iflvl[tlevel] = flevel;
+ if (n == 0) {
+ ++flevel;
+ }
+ } else {
+ err('i');
+ }
+ lmode = ELIST;
+ laddr = n;
+ return;
+
+ case S_ELSE:
+ if (ifcnd[tlevel]) {
+ if (++flevel > (iflvl[tlevel]+1)) {
+ err('i');
+ }
+ } else {
+ if (--flevel < iflvl[tlevel]) {
+ err('i');
+ }
+ }
+ lmode = SLIST;
+ return;
+
+ case S_ENDIF:
+ if (tlevel) {
+ flevel = iflvl[tlevel--];
+ } else {
+ err('i');
+ }
+ lmode = SLIST;
+ return;
+
+ case S_PAGE:
+ lop = NLPP;
+ lmode = NLIST;
+ return;
+
+ default:
+ break;
+ }
+ if (flevel)
+ return;
+ /*
+ * If we are not in a false state for .if/.else then
+ * process the assembler directives here.
+ */
+ switch (mp->m_type) {
+
+ case S_EVEN:
+ outall();
+ laddr = dot.s_addr = (dot.s_addr + 1) & ~1;
+ lmode = ALIST;
+ break;
+
+ case S_ODD:
+ outall();
+ laddr = dot.s_addr |= 1;
+ lmode = ALIST;
+ break;
+
+ case S_BYTE:
+ case S_WORD:
+ do {
+ clrexpr(&e1);
+ expr(&e1, 0);
+ if (mp->m_type == S_BYTE) {
+ outrb(&e1, R_NORM);
+ } else {
+ outrw(&e1, R_NORM);
+ }
+ } while ((c = getnb()) == ',');
+ unget(c);
+ break;
+
+ case S_ASCII:
+ case S_ASCIZ:
+ if ((d = getnb()) == '\0')
+ qerr();
+ while ((c = getmap(d)) >= 0)
+ outab(c);
+ if (mp->m_type == S_ASCIZ)
+ outab(0);
+ break;
+
+ case S_ASCIS:
+ if ((d = getnb()) == '\0')
+ qerr();
+ c = getmap(d);
+ while (c >= 0) {
+ if ((n = getmap(d)) >= 0) {
+ outab(c);
+ } else {
+ outab(c | 0x80);
+ }
+ c = n;
+ }
+ break;
+
+ case S_BLK:
+ clrexpr(&e1);
+ expr(&e1, 0);
+ outchk(HUGE,HUGE);
+ dot.s_addr += e1.e_addr*mp->m_valu;
+ lmode = BLIST;
+ break;
+
+ case S_TITLE:
+ p = tb;
+ if ((c = getnb()) != 0) {
+ do {
+ if (p < &tb[NTITL-1])
+ *p++ = c;
+ } while ((c = get()) != 0);
+ }
+ *p = 0;
+ unget(c);
+ lmode = SLIST;
+ break;
+
+ case S_SBTL:
+ p = stb;
+ if ((c = getnb()) != 0) {
+ do {
+ if (p < &stb[NSBTL-1])
+ *p++ = c;
+ } while ((c = get()) != 0);
+ }
+ *p = 0;
+ unget(c);
+ lmode = SLIST;
+ break;
+
+ case S_MODUL:
+ getst(id, getnb()); // a module can start with a digit
+ if (pass == 0) {
+ if (module[0]) {
+ err('m');
+ } else {
+ strncpy(module, id, NCPS);
+ }
+ }
+ lmode = SLIST;
+ break;
+
+ case S_OPTSDCC:
+ p = optsdcc;
+ if ((c = getnb()) != 0) {
+ do {
+ if (p < &optsdcc[NINPUT-1])
+ *p++ = c;
+ } while ((c = get()) != 0);
+ }
+ *p = 0;
+ unget(c);
+ lmode = SLIST;