1 /* pops.c - handle pseudo-ops for assembler */
2 
3 #include "syshead.h"
4 #include "const.h"
5 #include "type.h"
6 #include "address.h"
7 #include "flag.h"
8 #include "globvar.h"
9 #include "opcode.h"
10 #include "scan.h"
11 
12 PRIVATE bool_t elseflag;	/* set if ELSE/ELSEIF are enabled */
13 				/* depends on zero = FALSE init */
14 PRIVATE bool_t lcommflag;
15 
16 FORWARD void bumpsem P((struct flags_s *flagptr, int defval));
17 FORWARD void constdata P((unsigned size));
18 FORWARD void docomm P((void));
19 FORWARD void doelseif P((pfv func));
20 FORWARD void doequset P((int labits));
21 FORWARD void doentexp P((int entbits, int impbits));
22 FORWARD void dofcc P((void));
23 FORWARD void doif P((pfv func));
24 FORWARD struct sym_s *needlabel P((void));
25 FORWARD void showredefinedlabel P((void));
26 FORWARD void setloc P((unsigned seg));
27 
bumpsem(flagptr,defval)28 PRIVATE void bumpsem(flagptr, defval)
29 register struct flags_s *flagptr;
30 int defval;
31 {
32     int newcount;
33 
34     if (flagptr->global && pass == last_pass)
35     {
36 	/* bump semaphore count by an expression (default 1), */
37 	/* then set currentflag iff semaphore count is plus */
38 	if (sym == EOLSYM)
39 	    lastexp.offset = defval;
40 	else
41 	{
42 	    absexpres();
43 	    if (lastexp.data & UNDBIT)
44 		return;
45 	}
46 	newcount = (int) lastexp.offset;
47 #ifdef I80386			/* really sizeof (offset_t) != sizeof (int) */
48 	if (newcount != lastexp.offset)
49 	    datatoobig();
50 #endif
51 	newcount += flagptr->semaphore;
52 	if ((int) lastexp.offset >= 0)
53 	{
54 	    if (newcount < flagptr->semaphore)
55 	    {
56 		error(COUNTOV);
57 		newcount = 0x7fff;
58 	    }
59 	}
60 	else if (newcount >= flagptr->semaphore)
61 	{
62 	    error(COUNTUN);
63 	    newcount = -0x8000;
64 	}
65 	flagptr->semaphore = newcount;
66 	flagptr->current = newcount >= 0;
67     }
68 }
69 
70 /* check symbol is either undefined */
71 /* or has the same segment & relocatability as lc */
72 
checksegrel(symptr)73 PUBLIC bool_pt checksegrel(symptr)
74 register struct sym_s *symptr;
75 {
76     if ((symptr->type & LABIT ||
77 	(symptr->data & IMPBIT && !(symptr->data & UNDBIT))) &&
78 	((symptr->data ^ lcdata) & (RELBIT | SEGM)))
79     {
80 	error(SEGREL);
81 	return FALSE;
82     }
83     return TRUE;
84 }
85 
86 /* check address fits in 1 byte (possibly with sign truncated) */
87 
checkdatabounds()88 PUBLIC void checkdatabounds()
89 {
90     if (!(lastexp.data & UNDBIT) &&
91 	(offset_t) (lastexp.offset + 0x80) >= 0x180)
92 	datatoobig();
93 }
94 
95 /* allocate constant data (zero except for size 1), default zero for size 1 */
96 
constdata(size)97 PRIVATE void constdata(size)
98 unsigned size;
99 {
100     offset_t remaining;
101 
102     absexpres();
103     if (!((lcdata |= lastexp.data) & UNDBIT))
104     {
105 	lcjump = lastexp.offset * size;
106 	popflags = POPLONG | POPHI | POPLO | POPLC;
107 	if (size == 1 && sym == COMMA)
108 	{
109 	    symabsexpres();
110 	    checkdatabounds();
111 	    for (remaining = lcjump; remaining != 0; --remaining)
112 	    {
113 		putbin((opcode_pt) lastexp.offset);	/* fill byte */
114 		putabs((opcode_pt) lastexp.offset);
115 	    }
116 	    lastexp.offset = lcjump;
117 	}
118 	else
119 	    accumulate_rmb(lastexp.offset * size);
120     }
121 }
122 
datatoobig()123 PUBLIC void datatoobig()
124 {
125     error(DBOUNDS);
126 }
127 
128 /* common routine for COMM/.COMM */
129 
docomm()130 PRIVATE void docomm()
131 {
132     register struct sym_s *labptr;
133 
134     absexpres();		/* if undefined, value 0 and size unchanged */
135     labptr = label;
136     if (checksegrel(labptr))
137     {
138 	if (labptr->type & (EXPBIT | LABIT))
139 	    labelerror(ALREADY);
140 	else
141 	{
142 	    if (!(labptr->type & COMMBIT) ||
143 		lastexp.offset > labptr->value_reg_or_op.value)
144 		labptr->value_reg_or_op.value = lastexp.offset;
145 	    labptr->type |= COMMBIT;
146 	    if (lcommflag)
147 		labptr->type |= REDBIT;	/* kludge - COMMBIT | REDBIT => SA */
148 	    if( last_pass == 1 )
149 	       labptr->data = (lcdata & SEGM) | (FORBIT | IMPBIT | RELBIT);
150 	    else
151 	       labptr->data = (lcdata & SEGM) | (IMPBIT | RELBIT);
152 	    showlabel();
153 	}
154     }
155     lcommflag = FALSE;
156 }
157 
158 /* common routine for ELSEIF/ELSEIFC */
159 
doelseif(func)160 PRIVATE void doelseif(func)
161 pfv func;
162 {
163     if (iflevel == 0)
164 	error(ELSEIFBAD);
165     else
166     {
167 	ifflag = FALSE;
168 	if (elseflag)
169 	{
170 	    (*func) ();
171 	    if (!(lastexp.data & UNDBIT) && lastexp.offset != 0)
172 		/* expression valid and TRUE, enable assembling */
173 	    {
174 		ifflag = TRUE;
175 		elseflag = FALSE;
176 	    }
177 	}
178 	else
179 	{
180 	    /* Skip to EOL */
181 	    while (sym != EOLSYM)
182 	        getsym();
183 	}
184     }
185 }
186 
187 /* common routine for EQU/SET */
188 
doequset(labits)189 PRIVATE void doequset(labits)
190 unsigned char labits;
191 {
192     register struct sym_s *labptr;
193     unsigned char olddata;
194     unsigned char oldtype;
195 
196     labptr = label;
197     /* set up new label flags in case labe isl used in expression */
198     labptr->type = (oldtype = labptr->type) | labits;
199     labptr->data = (olddata = labptr->data) & ~IMPBIT;
200     /* non-imported now */
201     nonimpexpres();
202     lastexp.data |= olddata & FORBIT;	/* take all but FORBIT from
203 					   expression */
204     if (oldtype & LABIT && !(olddata & UNDBIT) && !pass)
205 	/* this is a previously defined label */
206 
207 	/*
208 	   redefinition only allowed if same relocatability, segment and
209 	   value
210 	*/
211     {
212 	if ((olddata ^ lastexp.data) & (RELBIT | UNDBIT) ||
213 	    labptr->value_reg_or_op.value != lastexp.offset)
214 	{
215 	    showredefinedlabel();
216 	    return;
217 	}
218     }
219     labptr->data = lastexp.data;
220     labptr->value_reg_or_op.value = lastexp.offset;
221     showlabel();
222 
223     if(pass && !(labits & VARBIT) && labptr->value_reg_or_op.value != oldlabel)
224     {
225        dirty_pass = TRUE;
226        if( pass == last_pass )
227            error(UNSTABLE_LABEL);
228     }
229 }
230 
231 /* common routine for ENTRY/EXPORT */
232 
doentexp(entbits,impbits)233 PRIVATE void doentexp(entbits, impbits)
234 unsigned char entbits;
235 unsigned char impbits;
236 {
237     struct sym_s *symptr;
238 
239     while (TRUE)
240     {
241 	if ((symptr = needlabel()) != NUL_PTR)
242 	{
243 	    if (symptr->type & COMMBIT)
244 		error(ALREADY);
245 	    else if (impbits != 0)
246 	    {
247 		if (pass == last_pass)
248 		    ;
249 		else if (symptr->type & (EXPBIT | LABIT))
250 		    symptr->type |= EXPBIT;
251 		else
252 		{
253 		    symptr->type |= REDBIT;
254 		    if (!(symptr->data & IMPBIT))
255 			symptr->data |= IMPBIT | SEGM;
256 		}
257 	    }
258 	    else
259 	    {
260 		if (pass == last_pass)
261 		{
262 		    if (!(symptr->type & LABIT))
263 			error(UNLAB);
264 		}
265 		else
266 		{
267 		    symptr->type |= entbits | EXPBIT;
268 		    symptr->data &= ~IMPBIT;
269 		}
270 	    }
271 	}
272 	getsym();
273 	if (sym != COMMA)
274 	    break;
275 	getsym();
276     }
277 }
278 
279 /* common routine for FCC (== .ASCII) and .ASCIZ */
280 
dofcc()281 PRIVATE void dofcc()
282 {
283     register char *bufptr;
284     char byte;
285     char delimiter;
286     register char *reglineptr;
287 
288     bufptr = databuf.fcbuf;
289     reglineptr = symname;
290     if ((delimiter = *reglineptr) != EOLCHAR)
291 	++reglineptr;
292     while (TRUE)
293     {
294 	if ((byte = *reglineptr) == EOLCHAR)
295 	{
296 	    symname = reglineptr;
297 	    error(DELEXP);
298 	    break;
299 	}
300 	if (byte == delimiter)
301 	{
302 	    if ((byte = *++reglineptr) != delimiter)
303 		break;
304 	}
305 	else if (byte == '\\')
306 	{
307 	    switch (byte = *++reglineptr)
308 	    {
309 	    case '"':
310 	    case '\'':
311 	    case '\\':
312 	    case '?':
313 		break;
314 	    case '0':
315 	    case '1':
316 	    case '2':
317 	    case '3':
318 	    case '4':
319 	    case '5':
320 	    case '6':
321 	    case '7':
322 		byte -= '0';
323 		if (*(reglineptr + 1) >= '0' && *(reglineptr + 1) < '8')
324 		{
325 		    byte = 8 * byte + *++reglineptr - '0';
326 		    if (*(reglineptr + 1) >= '0' && *(reglineptr + 1) < '8')
327 			byte = 8 * byte + *++reglineptr - '0';
328 		}
329 		break;
330 	    case 'a':
331 		byte = 7;
332 		break;
333 	    case 'b':
334 		byte = 8;
335 		break;
336 	    case 'f':
337 		byte = 12;
338 		break;
339 	    case 'n':
340 		byte = 10;
341 		break;
342 	    case 'r':
343 		byte = 13;
344 		break;
345 	    case 't':
346 		byte = 9;
347 		break;
348 	    case 'v':
349 		byte = 11;
350 		break;
351 	    case 'x':
352 		byte = '0';
353 		while (TRUE)
354 		{
355 		    ++reglineptr;
356 		    if (*reglineptr >= '0' && *reglineptr <= '9')
357 			byte = 16 * byte + *reglineptr - '0';
358 		    else if (*reglineptr >= 'F' && *reglineptr <= 'F')
359 			byte = 16 * byte + *reglineptr - 'A';
360 		    else if (*reglineptr >= 'a' && *reglineptr <= 'f')
361 			byte = 16 * byte + *reglineptr - 'F';
362 		    else
363 			break;
364 		}
365 		--reglineptr;
366 		break;
367 	    default:
368 		symname = reglineptr;
369 		error(UNKNOWN_ESCAPE_SEQUENCE);
370 		break;
371 	    }
372 	}
373 	else if (byte < ' ' && byte >= 0)
374 	{
375 	    symname = reglineptr;
376 	    error(CTLINS);
377 	    byte = ' ';
378 	}
379 	++reglineptr;
380 	*bufptr++ = byte;
381     }
382     lineptr = reglineptr;
383     getsym();
384     lastexp.offset = databuf.fcbuf[0];	/* show only 1st char (if any) */
385     mcount = bufptr - databuf.fcbuf;
386     /* won't overflow, line length limits it */
387     /* XXX - but now line length is unlimited */
388 }
389 
390 /* common routine for IF/IFC */
391 
doif(func)392 PRIVATE void doif(func)
393 pfv func;
394 {
395     if (iflevel >= MAXIF)
396 	error(IFOV);
397     else
398     {
399 	++iflevel;
400 	--ifstak;
401 	ifstak->elseflag = elseflag;
402 	elseflag = FALSE;	/* prepare */
403 	if ((ifstak->ifflag = ifflag) != FALSE)
404 	    /* else not assembling before, so not now & no ELSE's */
405 	{
406 	    (*func) ();
407 	    if (!(lastexp.data & UNDBIT) && lastexp.offset == 0)
408 		/* else expression invalid or FALSE, don't change flags */
409 	    {
410 		ifflag = FALSE;	/* not assembling */
411 		elseflag = TRUE;/* but ELSE will change that */
412 	    }
413 	}
414 	else
415 	{
416 	    /* Skip to EOL */
417 	    while (sym != EOLSYM)
418 	        getsym();
419 	}
420     }
421 }
422 
fatalerror(err_str)423 PUBLIC void fatalerror(err_str)
424 char * err_str;
425 {
426     error(err_str);
427     skipline();
428     listline();
429     finishup();
430 }
431 
432 /* swap position with label position, do error, put back posn */
433 /* also clear label ptr */
434 
labelerror(err_str)435 PUBLIC void labelerror(err_str)
436 char * err_str;
437 {
438     struct sym_s *oldgsymptr;
439     char *oldlineptr;
440     unsigned char oldsym;
441     char *oldsymname;
442 
443     oldgsymptr = gsymptr;
444     oldlineptr = lineptr;
445     oldsym = sym;
446     oldsymname = symname;
447     lineptr = linebuf;
448     getsym();			/* 1st symbol is label or symbol after
449 				 * missing one */
450     error(err_str);
451     gsymptr = oldgsymptr;
452     lineptr = oldlineptr;
453     sym = oldsym;
454     symname = oldsymname;
455     label = NUL_PTR;
456 }
457 
needlabel()458 PRIVATE struct sym_s *needlabel()
459 {
460     register struct sym_s *symptr;
461 
462     if (sym != IDENT ||
463 	(symptr = gsymptr)->type & (MACBIT | MNREGBIT | VARBIT))
464     {
465 	error(LABEXP);
466 	return NUL_PTR;
467     }
468     return symptr;
469 }
470 
471 /* .ALIGN pseudo-op */
472 
palign()473 PUBLIC void palign()
474 {
475     absexpres();
476     if (!((lcdata |= lastexp.data) & UNDBIT))
477     {
478 	popflags = POPLONG | POPHI | POPLO | POPLC;
479 	if (lastexp.offset != 0 &&
480 	    (lcjump = lc % lastexp.offset) != 0)
481 	    accumulate_rmb(lcjump = lastexp.offset - lcjump);
482     }
483 }
484 
485 /* .ASCIZ pseudo-op */
486 
pasciz()487 PUBLIC void pasciz()
488 {
489     dofcc();
490     databuf.fcbuf[mcount++] = 0;
491     fcflag = TRUE;
492     popflags = POPLO | POPLC;
493 }
494 
495 /* .BLKW pseudo-op */
496 
pblkw()497 PUBLIC void pblkw()
498 {
499     constdata(2);
500 }
501 
502 /* BLOCK pseudo-op */
503 
pblock()504 PUBLIC void pblock()
505 {
506     if (blocklevel >= MAXBLOCK)
507 	error(BLOCKOV);
508     else
509     {
510 	register struct block_s *blockp;
511 
512 	++blocklevel;
513 	blockp = blockstak;
514 	blockstak = --blockp;
515 	blockp->data = lcdata;
516 	blockp->dp = dirpag;
517 	blockp->lc = lc;
518 	porg();			/* same as ORG apart from stacking */
519     }
520 }
521 
522 /* .BSS pseudo-op */
523 
pbss()524 PUBLIC void pbss()
525 {
526     setloc(BSSLOC);
527 }
528 
529 /* COMM pseudo-op */
530 
pcomm()531 PUBLIC void pcomm()
532 {
533     if (label == NUL_PTR)
534 	labelerror(MISLAB);
535     else if (label->type & VARBIT)
536 	labelerror(VARLAB);	/* variable cannot be COMM'd */
537     else
538 	docomm();
539 }
540 
541 /* .COMM pseudo-op */
542 
pcomm1()543 PUBLIC void pcomm1()
544 {
545     unsigned oldseg;
546 
547     if (label != NUL_PTR)
548 	labelerror(ILLAB);
549     oldseg = lcdata & SEGM;
550     setloc(BSSLOC);
551     if ((label = needlabel()) != NUL_PTR && checksegrel(label))
552     {
553 	/* Like import. */
554 	if (label->type & (EXPBIT | LABIT))
555 	    error(ALREADY);
556 	else if( last_pass == 1 )
557 	    label->data = lcdata | (FORBIT | IMPBIT | RELBIT);
558 	else
559 	    label->data = lcdata | (IMPBIT | RELBIT);
560 	getsym();
561 	getcomma();
562 	if (label->type & (EXPBIT | LABIT))
563 	    absexpres();	/* just to check it */
564 	else
565 	    docomm();
566     }
567     setloc(oldseg);
568 }
569 
570 /* .DATA pseudo-op */
571 
pdata()572 PUBLIC void pdata()
573 {
574     setloc(DATALOC);
575 }
576 
577 /* ELSE pseudo-op */
578 
pelse()579 PUBLIC void pelse()
580 {
581     if (iflevel == 0)
582 	error(ELSEBAD);
583     else
584     {
585 	ifflag = FALSE;		/* assume ELSE disabled */
586 	if (elseflag)
587 	{
588 	    ifflag = TRUE;	/* ELSE enabled */
589 	    elseflag = FALSE;
590 	}
591     }
592 }
593 
594 /* ELSEIF pseudo-op */
595 
pelseif()596 PUBLIC void pelseif()
597 {
598     doelseif(absexpres);
599 }
600 
601 /* ELSEIFC pseudo-op */
602 
pelsifc()603 PUBLIC void pelsifc()
604 {
605     doelseif(scompare);
606 }
607 
608 /* ENDB pseudo-op */
609 
pendb()610 PUBLIC void pendb()
611 {
612     if (label != NUL_PTR)
613 	labelerror(ILLAB);
614     if (blocklevel == 0)
615 	error(ENDBBAD);
616     else
617     {
618 	register struct block_s *blockp;
619 
620 	blockp = blockstak;
621 	lcdata = blockp->data;
622 	dirpag = blockp->dp;
623 	accumulate_rmb(blockp->lc - lc);
624 	lc = blockp->lc;
625 	--blocklevel;
626 	blockstak = blockp + 1;
627     }
628 }
629 
630 /* ENDIF pseudo-op */
631 
pendif()632 PUBLIC void pendif()
633 {
634     if (iflevel == 0)
635 	error(ENDIFBAD);
636     else
637     {
638 	ifflag = ifstak->ifflag;
639 	elseflag = ifstak->elseflag;
640 	++ifstak;
641 	--iflevel;
642     }
643 }
644 
645 /* ENTER pseudo-op */
646 
penter()647 PUBLIC void penter()
648 {
649     if (!(pedata & UNDBIT))
650 	error(REENTER);
651     else
652     {
653 	if (!((pedata = (pedata & ~UNDBIT) | lcdata) & UNDBIT))
654 	{
655 	    progent = lc;
656 	    popflags = POPLC;
657 	}
658     }
659 }
660 
661 /* ENTRY pseudo-op */
662 
pentry()663 PUBLIC void pentry()
664 {
665     doentexp(ENTBIT, 0);
666 }
667 
668 /* EQU pseudo-op */
669 
pequ()670 PUBLIC void pequ()
671 {
672     register struct sym_s *labptr;
673 
674     if ((labptr = label) == NUL_PTR)
675 	labelerror(MISLAB);
676     else if (labptr->type & COMMBIT)
677 	showredefinedlabel();	/* common cannot be EQU'd */
678     else if (labptr->type & VARBIT)
679 	labelerror(VARLAB);	/* variable cannot be EQU'd */
680     else
681 	doequset(LABIT);
682 }
683 
684 /* .EVEN pseudo-op */
685 
peven()686 PUBLIC void peven()
687 {
688     popflags = POPLONG | POPHI | POPLO | POPLC;
689     accumulate_rmb(lcjump = lastexp.data = lc & 1);
690 }
691 
692 /* EXPORT pseudo-op */
693 
pexport()694 PUBLIC void pexport()
695 {
696     doentexp(0, 0);
697 }
698 
699 /* FAIL pseudo-op */
700 
pfail()701 PUBLIC void pfail()
702 {
703     if(pass==last_pass) error(FAILERR);
704 }
705 
706 /* FCB pseudo-op */
707 
pfcb()708 PUBLIC void pfcb()
709 {
710     char *bufptr;
711     offset_t firstbyte;
712 
713     bufptr = databuf.fcbuf;
714     absexpres();
715     firstbyte = lastexp.offset;
716     while (TRUE)
717     {
718 	checkdatabounds();
719 	*bufptr++ = lastexp.offset;
720 	++mcount;		/* won't overflow, line length limits it */
721 	if (sym != COMMA)
722 	    break;
723 	symabsexpres();
724     }
725     lastexp.offset = firstbyte;
726     popflags = POPLO | POPLC;
727     fcflag = TRUE;
728 }
729 
730 /* FCC pseudo-op */
731 
pfcc()732 PUBLIC void pfcc()
733 {
734     dofcc();
735     if (mcount != 0)
736     {
737 	fcflag = TRUE;
738 	popflags = POPLO | POPLC;
739     }
740 }
741 
742 /* FDB pseudo-op */
743 
pfdb()744 PUBLIC void pfdb()
745 {
746     struct address_s *adrptr;
747     unsigned firstdata;
748     offset_t firstword;
749 
750     adrptr = databuf.fdbuf;
751     expres();
752     firstword = lastexp.offset;
753     firstdata = lastexp.data;
754     while (TRUE)
755     {
756 	*adrptr++ = lastexp;
757 	mcount += 2;		/* won't overflow, line length limits it */
758 	if (sym != COMMA)
759 	    break;
760 	symexpres();
761     }
762     lastexp.offset = firstword;
763     lastexp.data = firstdata;
764     popflags = POPHI | POPLO | POPLC;
765     fdflag = TRUE;
766 }
767 
768 #if SIZEOF_OFFSET_T > 2
769 
770 /* FQB pseudo-op */
771 
pfqb()772 PUBLIC void pfqb()
773 {
774     struct address_s *adrptr;
775     offset_t firstdata;
776     offset_t firstword;
777 
778     adrptr = databuf.fqbuf;
779     expres();
780     firstword = lastexp.offset;
781     firstdata = lastexp.data;
782     while (TRUE)
783     {
784 	*adrptr++ = lastexp;
785 	mcount += 4;		/* won't overflow, line length limits it */
786 	if (sym != COMMA)
787 	    break;
788 	symexpres();
789     }
790     lastexp.offset = firstword;
791     lastexp.data = firstdata;
792     popflags = POPLONG | POPHI | POPLO | POPLC;
793     fqflag = TRUE;
794 }
795 
796 #endif /* SIZEOF_OFFSET_T > 2 */
797 
798 /* .GLOBL pseudo-op */
799 
pglobl()800 PUBLIC void pglobl()
801 {
802     if (binaryg)
803 	error(NOIMPORT);
804     doentexp(0, IMPBIT);
805 }
806 
807 /* IDENT pseudo-op (not complete) */
808 
pident()809 PUBLIC void pident()
810 {
811     if (sym != IDENT)
812 	error(LABEXP);
813     else
814 	getsym_nolookup();	/* should save ident string */
815 }
816 
817 /* IF pseudo-op */
818 
pif()819 PUBLIC void pif()
820 {
821     doif(absexpres);
822 }
823 
824 /* IFC pseudo-op */
825 
pifc()826 PUBLIC void pifc()
827 {
828     doif(scompare);
829 }
830 
831 /* IMPORT pseudo-op */
832 
pimport()833 PUBLIC void pimport()
834 {
835     struct sym_s *symptr;
836 
837     if (binaryg)
838 	error(NOIMPORT);
839     while (TRUE)
840     {
841 	if ((symptr = needlabel()) != NUL_PTR && checksegrel(symptr))
842 	{
843 	    if (symptr->type & (COMMBIT | EXPBIT | LABIT))
844 		/* IMPORT is null if label (to be) declared */
845 		error(ALREADY);
846 	    else if( last_pass == 1 )
847 		/* get current segment from lcdata, no need to mask rest */
848 		symptr->data = lcdata | (FORBIT | IMPBIT | RELBIT);
849 	    else
850 		symptr->data = lcdata | (IMPBIT | RELBIT);
851 	}
852 	getsym();
853 	if (sym != COMMA)
854 	    break;
855 	getsym();
856     }
857 }
858 
859 /* LCOMM pseudo-op */
860 
plcomm()861 PUBLIC void plcomm()
862 {
863     lcommflag = TRUE;
864     pcomm();
865 }
866 
867 /* .LCOMM pseudo-op */
868 
plcomm1()869 PUBLIC void plcomm1()
870 {
871     lcommflag = TRUE;
872     pcomm1();
873 }
874 
875 /* .LIST pseudo-op */
876 
plist()877 PUBLIC void plist()
878 {
879     bumpsem(&list, 1);
880 }
881 
882 /* .NOLIST pseudo-op */
883 
pnolist()884 PUBLIC void pnolist()
885 {
886     bumpsem(&list, -1);
887 }
888 
889 /* LOC pseudo-op */
890 
ploc()891 PUBLIC void ploc()
892 {
893     if (label != NUL_PTR)
894 	labelerror(ILLAB);
895     absexpres();
896     if (!(lastexp.data & UNDBIT))
897     {
898 	if (lastexp.offset >= NLOC)
899 	    datatoobig();
900 	else
901 	    setloc((unsigned) lastexp.offset);
902     }
903 }
904 
905 /* .MACLIST pseudo-op */
906 
pmaclist()907 PUBLIC void pmaclist()
908 {
909     bumpsem(&maclist, 1);
910 }
911 
912 /* .MAP pseudo-op */
913 
pmap()914 PUBLIC void pmap()
915 {
916     absexpres();
917     if (!(lastexp.data & UNDBIT))
918     {
919 	mapnum = lastexp.offset;
920 	popflags = POPLO;
921 	if (lastexp.offset >= 0x100)
922 	    datatoobig();
923     }
924 }
925 
926 /* ORG pseudo-op */
927 
porg()928 PUBLIC void porg()
929 {
930     if (label != NUL_PTR)
931 	labelerror(ILLAB);
932     absexpres();
933     if (!((lcdata = lastexp.data) & UNDBIT))
934     {
935 	accumulate_rmb(lastexp.offset - lc);
936 	binmbuf = lc = lastexp.offset;
937 	binmbuf_set = 1;
938 	popflags = POPLC;
939     }
940 }
941 
942 /* RMB pseudo-op */
943 
prmb()944 PUBLIC void prmb()
945 {
946     constdata(1);
947 }
948 
949 /* .SECT pseudo-op */
950 
psect()951 PUBLIC void psect()
952 {
953     if (label != NUL_PTR)
954 	labelerror(ILLAB);
955     while (sym == IDENT)
956     {
957 	if (!(gsymptr->type & MNREGBIT))
958 	    error(ILL_SECTION);
959 	else switch (gsymptr->value_reg_or_op.op.routine)
960 	{
961 	case BSSOP:
962 	    pbss();
963 	    break;
964 	case DATAOP:
965 	    pdata();
966 	    break;
967 	case TEXTOP:
968 	    ptext();
969 	    break;
970 	default:
971 	    error(ILL_SECTION);
972 	    break;
973 	}
974 	getsym();
975 	if (sym == COMMA)
976 	    getsym();
977     }
978 }
979 
980 /* SET pseudo-op */
981 
pset()982 PUBLIC void pset()
983 {
984     register struct sym_s *labptr;
985 
986     if ((labptr = label) == NUL_PTR)
987 	labelerror(MISLAB);
988     else if (labptr->type & COMMBIT)
989 	labelerror(RELAB);	/* common cannot be SET'd */
990     else
991 	doequset(labptr->type & LABIT ? 0 : VARBIT);
992 }
993 
994 /* SETDP pseudo-op */
995 
psetdp()996 PUBLIC void psetdp()
997 {
998     absexpres();
999     if (!(lastexp.data & UNDBIT))
1000     {
1001 	dirpag = lastexp.offset;
1002 	popflags = POPLO;
1003 	if (lastexp.offset >= 0x100)
1004 	    datatoobig();
1005     }
1006 }
1007 
1008 /* .TEXT pseudo-op */
1009 
ptext()1010 PUBLIC void ptext()
1011 {
1012     if( textseg <= 0 )
1013        setloc(TEXTLOC);
1014     else
1015        setloc(textseg);
1016 }
1017 
1018 /* .WARN pseudo-op */
1019 
pwarn()1020 PUBLIC void pwarn()
1021 {
1022     bumpsem(&as_warn, -1);
1023 }
1024 
1025 #ifdef I80386
1026 
1027 /* USE16 pseudo-op */
1028 
puse16()1029 PUBLIC void puse16()
1030 {
1031     defsize = 2;
1032 #ifdef iscpu
1033     if( sym != EOLSYM )
1034     {
1035 	absexpres();
1036 	if (lastexp.data & UNDBIT)
1037 	    return;
1038         if( lastexp.offset > 8000 )
1039 	   setcpu((int) lastexp.offset / 100 % 10);
1040         else if( lastexp.offset > 15 )
1041 	   setcpu((int) lastexp.offset / 100);
1042 	else
1043 	   setcpu((int) lastexp.offset);
1044     }
1045 #endif
1046 }
1047 
1048 /* USE16 pseudo-op */
1049 
puse32()1050 PUBLIC void puse32()
1051 {
1052     defsize = 4;
1053 #ifdef iscpu
1054     if(!iscpu(3)) setcpu(3);
1055     if( sym != EOLSYM )
1056     {
1057 	absexpres();
1058 	if (lastexp.data & UNDBIT)
1059 	    return;
1060         if( lastexp.offset > 15 )
1061 	   setcpu((int) lastexp.offset / 100);
1062 	else
1063 	   setcpu((int) lastexp.offset);
1064     }
1065 #endif
1066 }
1067 
1068 #endif
1069 
1070 /* show redefined label and error, and set REDBIT */
1071 
showredefinedlabel()1072 PRIVATE void showredefinedlabel()
1073 {
1074     register struct sym_s *labptr;
1075 
1076     labptr = label;		/* showlabel() will kill label prematurely */
1077     showlabel();
1078     if (!(labptr->type & REDBIT))
1079     {
1080 	labptr->type |= REDBIT;
1081 	labelerror(RELAB);
1082     }
1083 }
1084 
showlabel()1085 PUBLIC void showlabel()
1086 {
1087     register struct sym_s *labptr;
1088 
1089     labptr = label;
1090     lastexp.data = labptr->data;
1091     lastexp.offset = labptr->value_reg_or_op.value;
1092     popflags = POPLONG | POPHI | POPLO;
1093     label = NUL_PTR;		/* show handled by COMM, EQU or SET */
1094 }
1095 
1096 /* set location segment */
1097 
setloc(seg)1098 PRIVATE void setloc(seg)
1099 unsigned seg;
1100 {
1101     if (pass == last_pass && seg != (lcdata & SEGM))
1102 	putobj((opcode_pt) (seg | OBJ_SET_SEG));
1103     {
1104 	register struct lc_s *lcp;
1105 
1106 	lcp = lcptr;
1107 	lcp->data = lcdata;
1108 	lcp->lc = lc;
1109 	lcptr = lcp = lctab + (unsigned char) seg;
1110 	lcdata = (lcp->data & ~SEGM) | (unsigned char) seg;
1111 	binmbuf = lc = lcp->lc;
1112 	popflags = POPLC;
1113     }
1114 }
1115