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