Files
Digital-Research-Source-Code/CPM OPERATING SYSTEMS/CPM 68K/1.0X SOURCES/v102/as68/main.lis
Sepp J Morris 31738079c4 Upload
Digital Research
2020-11-06 18:50:37 +01:00

1120 lines
37 KiB
Plaintext

1File: MAIN.C Page 1
1 /*
2 Copyright 1981
3 Alcyon Corporation
4 8716 Production Ave.
5 San Diego, Ca. 92121
6 */
7
8 char *sccs "@(#)as68 - Nov 12, 1982";
9
10 /*
11 * a two pass relocatable assembler for the Motorola 68000 microprocessor
12
13 * Bill Allen
14 * Modified by Vicki Hutchison
15
16 * after any of this assembler is recompiled, it must be initialized
17 * before it will execute properly. To initialize, become super user
18 * and execute the command:
19
20 * as68 -i as68init
21
22 * where as68 is the newly compiled version of the assembler. With-
23 * out this initialization, the assembler will not run (probably bus
24 * error).
25 */
26
27 /*
28 * Revisions :
29 *
30 * Added fix to make location relative equates
31 * correct even if branch optimization occurs. vlh 15-sep-82
32 * Recognizes commands in uppercase. vlh 17-sep-82
33 * Added recognization of upper case directives
34 * which do not have the preceding '.'. vlh 17-sep-82
35 * Added recognizing of ignored directives
36 * IDNT, ORG and MASK2. vlh 17-sep-82
37 * Added new directives XDEF, XREF. vlh 17-sep-82
38 * Added COMLINE and SECTION. vlh 20-sep-82
39 * Added new directive REG. vlh 21-sep-82
40 * Added new directives DCB and OFFSET. vlh 22-sep-82
41 * Recognizes branch extensions and takes
42 * the appropriate action. vlh 22-sep-82
43 * Added assembler directives ifeq, ifne,
44 * ifle, iflt, ifge, ifgt. vlh 23-sep-82
45 * Added character '$' to set of legitimate
46 * characters in a symbol. vlh 23-sep-82
47 * Added new ignored directive OPT. vlh 23-sep-82
48 * Recognizes non-opcodes starting in column 1
49 * as labels. vlh 23-sep-82
50 * Added conditional assembler directives
51 * ifc, ifnc. vlh 27-sep-82
52 * Major reworking of expression handler vlh 1-oct-82
53 * More revisions to expression stacks vlh 4-oct-82
54 * Added the recognition and handling of vlh 26-oct-82
55 * the 'illegal' instruction.
56 * Added handling of the jmp suffixes vlh 26-oct-82
57 * Fixed problem with -p flag and external vlh 27-oct-82
58 * variable listings.
59 * Added checking for legitimate command vlh 28-oct-82
1File: MAIN.C Page 2
60 * suffixes.
61 * Added comma as a legitimate register vlh 28-oct-82
62 * divisor for the REG directive.
63 * Fixed second pass error/instr len problem vlh 28-oct-82
64 * Added checking for invalid bit ranges. vlh 1-nov-82
65 * Added proper 2nd pass handling of the vlh 2-nov-82
66 * '*' symbol (avoid turning jsr to bra).
67 * Fixed first pass guess if operand is vlh 4-nov-82
68 * (rx,rx) instead of d(rx,rx).
69 * Check for appropriate range of 16-bit vlh 5-nov-82
70 * immediate date.
71 * Operand type check for shift/bit manip. vlh 5-nov-82
72 * Turn and/or/eor #xxx,sr/ccr into the vlh 5-nov-82
73 * corresponding immediate instruction.
74 * Generate an error when an illegal pc vlh 10-nov-82
75 * relative ea is specified.
76 */
77
78 /****************************************************************************/
79 /* */
80 /* D R I H a c k s */
81 /* ----------------- */
82 /* */
83 /* The following changes were made to facilitate running as68 under */
84 /* VMS and CP/M: */
85 /* */
86 /* o Added "-f" flag to redirect temp files to another directory */
87 /* or CP/M floppy drive. */
88 /* */
89 /* o Added "-s" flag to redirect symbol table file. */
90 /* */
91 /* o Added separate source file with initialization of all */
92 /* external variables to be compatible with Whitesmith's C. */
93 /* */
94 /* o Added "VMS", "UNIX", and "CPM" conditional compilation */
95 /* switches for these operating systems. */
96 /* */
97 /* o Added various listing enhancements so the printed file is */
98 /* usable on non-UNIX environments. */
99 /* */
100 /* o Changed I/O calls to be useable with filter library on V7 */
101 /* */
102 /****************************************************************************/
103
104
105
106 # include "as68.h"
107 char tfilname[80]; /* Temp filename area */
108 char initfnam[80]; /* Initialization filename area */
109 #ifdef UNIX
110 char tfilbase[] {"a6AXXXXXX"};
111 #else
112 char tfilbase[] {"a6xxxxA"}; /* Temp file base name */
113 #endif
114 char initbase[] {"as68symb.dat"}; /* Init file base name */
115 #ifdef VMS /* On VMS, use */
116 char *tdname = ""; /* Temps in same directory */
117 char *idname = "bin:"; /* Init in the "bin:" directory*/
118 #endif /********************************/
1File: MAIN.C Page 3
119 #ifdef UNIX /* */
120 char *tdname = "/tmp/"; /* UNIX Temp directory */
121 char *idname = "/lib/"; /* UNIX Init Directory */
122 #endif /********************************/
123 #ifdef CPM /* On CP/M, defaults for all. */
124 char *tdname = ""; /* No temp prefix */
125 char *idname = ""; /* No init prefix */
126 #endif /********************************/
127
128 char ldfn[40]; /*name of the relocatable object file*/
129
130 int brkln1 077777; /*pass 1 break line number for debugging*/
131 int opcval; /*opcode*/
132 int chmvq;
133
134 int hopd(), hend(), send(), horg(), sorg(), hequ(), hreg();
135 int hds(), sds();
136 int sdcb();
137 int hdsect(), hpsect(), sdsect(), spsect();
138 int hsection(), ssection(), hoffset();
139 int hent(), hext();
140 int igrst();
141 int hbss(), sbss();
142 int heven(), seven();
143 int hdc(), sdc(), hdcb();
144 int hmask2(), hcomline(), hidnt();
145 int hifeq(), hifne(), hiflt(), hifle(), hifgt(), hifge(), hendc();
146 int hifnc(), hifc(), hopt();
147 int hpage(),spage();
148 int (*p1direct[])() {
149 hopd, /*0*/
150 hend, /*1*/
151 hdsect, /*2*/
152 hpsect, /*3*/
153 hequ, /*4*/
154 hequ, /*5 .set same as .equ*/
155 0, /*6*/
156 0, /*7*/
157 hdc, /*8*/
158 hent, /*9*/
159 hext, /*10*/
160 hbss, /*11*/
161 hds, /*12*/
162 heven, /*13*/
163 horg, /*14*/
164 hmask2, /*15*/
165 hreg, /*16*/
166 hdcb, /*17*/
167 hcomline, /*18*/
168 hidnt, /*19*/
169 hoffset, /*20*/
170 hsection, /*21*/
171 hifeq, /*22*/
172 hifne, /*23*/
173 hiflt, /*24*/
174 hifle, /*25*/
175 hifgt, /*26*/
176 hifge, /*27*/
177 hendc, /*28*/
1File: MAIN.C Page 4
178 hifc, /*29*/
179 hifnc, /*30*/
180 hopt, /*31*/
181 hpage, /*32*/
182 0};
183
184 int (*p2direct[])() {
185 0, /*0*/
186 send, /*1*/
187 sdsect, /*2*/
188 spsect, /*3*/
189 0, /*4*/
190 0, /*5*/
191 0, /*6*/
192 0, /*7*/
193 sdc, /*8*/
194 0, /*9*/
195 0, /*10*/
196 sbss, /*11*/
197 sds, /*12*/
198 seven, /*13*/
199 sorg, /*14*/
200 0, /*15*/
201 0, /*16*/
202 sdcb, /*17*/
203 sds, /*18 comline same as .ds.b*/
204 0, /*19*/
205 0, /*20*/
206 ssection, /*21*/
207 0, /*22*/
208 0, /*23*/
209 0, /*24*/
210 0, /*25*/
211 0, /*26*/
212 0, /*27*/
213 0, /*28*/
214 0, /*29*/
215 0, /*30*/
216 0, /*31*/
217 spage, /*32*/
218 0};
219
220 char *ermsg[] {
221 "label redefined", /*1*/
222 "invalid label", /*2*/
223 "invalid opcode", /*3*/
224 "no label for operand", /*4*/
225 "opcode redefined", /*5*/
226 "illegal expr", /*6*/
227 "undefined symbol in equate", /*7*/
228 0, /*8*/
229 "invalid first operand", /*9*/
230 "invalid second operand", /*10*/
231 "absolute value required", /*11*/
232 "no code or data allowed in offset", /*12*/
233 "undefined symbol", /*13*/
234 "illegal index register", /*14*/
235 "illegal constant", /*15*/
236 "illegal extension", /*16*/ /*[vlh]*/
1File: MAIN.C Page 5
237 "constant required", /*17*/
238 "illegal format", /*18*/
239 "illegal string", /*19*/
240 "illegal addressing mode", /*20*/
241 0, /*21*/
242 "illegal relative address", /*22*/
243 "invalid bit range", /*23*/
244 "illegal text delimiter", /*24*/
245 "unexpected endc", /*25*/
246 "endc expected", /*26*/
247 "relocation error", /*27*/
248 "symbol required", /*28*/
249 "bad use of symbol", /*29*/
250 "invalid data list", /*30*/
251 0, /*31*/
252 "missing )", /*32*/
253 "register required", /*33*/
254 "illegal size", /*34*/
255 "illegal 8-bit displacement", /*35*/
256 "illegal external", /*36*/
257 "illegal shift count", /*37*/
258 "invalid instruction length", /*38*/
259 "code or data not allowed in bss", /*39*/
260 "backward assignment to *", /*40*/
261 "illegal 16-bit displacement", /*41*/
262 "illegal 16-bit immediate", /*42*/
263 "illegal 8-bit immediate", /*43*/
264 0
265 };
266
267 int endit();
268 int rubout();
269 int symcon;
270 char endstr[] "end";
271 char equstr[] "equ";
272 char evnstr[] "even";
273 char orgstr[] "~.yxzorg";
274
275 int poslab;
276 char tlab1[NAMELEN];
277 int explmode; /*explicit mode length given*/
278
279 main(argc,argv)
280 char **argv;
281 {
282 register i, ttmp;
283
284 register xargc; /* Temp copy of argc */
285 xargc = argc;
286
287 initflg = 0;
288 prtchidx = prtchars;
289 #ifdef UNIX /* Only available with UNIX */
290 signal(2,rubout);
291 #endif
292 pitix = itbuf;
293 pexti = extbl;
294 ttmp = (STESIZE*SZMT) + 2;
295 bmte = sbrk(ttmp);
1File: MAIN.C Page 6
296 if(((long)bmte) == -1L)
297 {
298 rpterr("Symbol Table Overflow\n");
299 abort();
300 }
301 if((long)bmte&1)
302 bmte++; /*make it even*/
303 emte = bmte + ttmp - 2; /*end of main table*/
304 if(argc<=1) usage();
305 i = 1;
306 shortadr = -1; /*short addresses ok*/
307 while(argv[i][0] == '-') { /*may be print or initialize*/
308 switch(argv[i++][1]) {
309
310 case 'i': /*initialize the assembler*/
311 case 'I':
312 initflg++;
313 break;
314
315 case 'p': /*produce a listing*/
316 case 'P':
317 prtflg++;
318 break;
319
320 case 'u': /*make undefined symbols external*/
321 case 'U':
322 undflg++;
323 break;
324
325 case 'N': /*no branch optimization*/
326 case 'n':
327 didorg++;
328 break;
329
330 case 'L': /*long addresses only*/
331 case 'l':
332 shortadr = 0;
333 break;
334
335 case 'f': /* Change temp files */
336 case 'F':
337 tdname = argv[i++];
338 break;
339
340 case 's': /* Change symbol table name */
341 case 'S':
342 idname = argv[i++];
343 break;
344
345 default:
346 usage();
347 }
348 }
349 strcat (tfilname,tdname); /* Build temp filenames */
350 strcat (tfilname,tfilbase); /* */
351 /**************************/
352 #ifdef UNIX /* For UNIX, Need to make */
353 mktemp (tfilname); /* Unique file name */
354 #endif /**************************/
1File: MAIN.C Page 7
355 tfilptr = &tfilname[strlen(tfilname)-1]; /* -> changed char */
356 #ifdef UNIX
357 tfilptr -= 6; /* Back off PID */
358 #endif
359
360 strcat (initfnam,idname); /* Build Symbol table filename */
361 strcat (initfnam,initbase);
362
363 if(i>=argc) usage();
364 ifn=open(argv[i],0,0); /*open source file*/
365 sfname = argv[i]; /* remember source filename */
366 setldfn(argv[i]); /*create relocatable object file name*/
367 lfn=openfi(ldfn,1); /*open loader file*/
368 itfn = gettempf(); /*get a temp file for it*/
369 itfnc = LASTCHTFN; /*remember last char for unlink*/
370 trbfn = gettempf(); /*temp for text relocation bits*/
371 trbfnc = LASTCHTFN;
372 dafn = gettempf(); /*temp for data binary*/
373 dafnc = LASTCHTFN;
374 drbfn = gettempf(); /*temp for data relocation bits*/
375 drbfnc = LASTCHTFN;
376 if(initflg) { /*initializing te main table*/
377 lmte=bmte; /*beginning main table*/
378 cszmt = SZMT; /*current size of main table*/
379 for(i=0; i<=SZIRT-2; i=+2) {
380 sirt[i] = &sirt[i]; /*initialize the initial ref tables*/
381 sirt[i+1] = 0;
382 oirt[i] = &oirt[i];
383 oirt[i+1] = 0;
384 }
385
386 /*make entries in main table for directives*/
387 mdemt("opd",0); /*opcode definition*/
388 mdemt(endstr,1); /*end statement*/
389 mdemt("data",2); /*dsect directive(code DATA based)*/
390 mdemt("text",3); /*psect directive(code TEXT based)*/
391 mdemt(equstr,4); /*equate*/
392 mdemt("set",5); /*.set - same as .equ*/
393 mdemt("dc",8); /*define byte*/
394 mdemt("globl",9); /*define global (public) symbols*/
395 mdemt("xdef",9); /*[vl]define global (public symbols*/
396 mdemt("xref",9); /*[vl]define global (public) symbols*/
397 mdemt("comm",10); /*define external symbols*/
398 mdemt("bss",11); /*block storage based*/
399 mdemt("ds",12); /*block storage based*/
400 mdemt(evnstr,13); /*round pc*/
401 mdemt(orgstr,14); /*internal org for *=n*/
402 mdemt("org",14); /*[vlh]*/
403 mdemt("mask2",15); /*[vl] assemble for mask2, ignore*/
404 mdemt("reg",16); /*[vlh] register equate*/
405 mdemt("dcb",17); /*[vlh] define block*/
406 mdemt("comline",18); /*[vlh] command line*/
407 mdemt("idnt",19); /*[vlh] relocateable id record, ignore*/
408 mdemt("offset",20); /*[vlh] define offsets*/
409 mdemt("section",21); /*[vlh] define sections*/
410 mdemt("ifeq",22); /*[vlh] ca if expr = 0*/
411 mdemt("ifne",23); /*[vlh] ca if expr != 0*/
412 mdemt("iflt",24); /*[vlh] ca if expr < 0*/
413 mdemt("ifle",25); /*[vlh] ca if expr <= 0*/
1File: MAIN.C Page 8
414 mdemt("ifgt",26); /*[vlh] ca if expr > 0*/
415 mdemt("ifge",27); /*[vlh] ca if expr >= 0*/
416 mdemt("endc",28); /*[vlh] end ca*/
417 mdemt("ifc",29); /*[vlh] ca if string compare*/
418 mdemt("ifnc",30); /*[vlh] ca if not string compare*/
419 mdemt("opt",31); /*[vlh] ignored, assemb options*/
420 mdemt("ttl",31); /* Ignore title op also */
421 mdemt("page",32);
422
423 }
424 else { /*not initializing*/
425 getsymtab(); /*read initialized main table*/
426 }
427
428 rlflg = TEXT; /*code initially TEXT based*/
429 inoffset = 0; /*[vlh]not in offset mode*/
430 loctr = 0; /*no generated code*/
431 ca = 0; /*[vlh]depth of conditional assembly*/
432 extindx = 0; /*no external symbols yet*/
433 p2flg = 0; /*pass 1*/
434 ca_true = 1; /*[vlh]true unless in side false case*/
435 absln = 1;
436 sbuflen = -1; /*no source yet*/
437 fchr = gchr(); /*get first char*/
438 if(!initflg) { /*not initializing*/
439 pack(orgstr,lmte);
440 orgptr = lemt(oirt,TRUE);
441 pack(endstr,lmte);
442 endptr = lemt(oirt,TRUE);
443 pack(equstr,lmte);
444 equptr = lemt(oirt,TRUE);
445 pack("add",lmte);
446 addptr = lemt(oirt,TRUE);
447 pack("addi",lmte);
448 addiptr = lemt(oirt,TRUE);
449 pack("addq",lmte);
450 addqptr = lemt(oirt,TRUE);
451 pack("sub",lmte);
452 subptr = lemt(oirt,TRUE);
453 pack("subi",lmte);
454 subiptr = lemt(oirt,TRUE);
455 pack("subq",lmte);
456 subqptr = lemt(oirt,TRUE);
457 pack("cmp",lmte);
458 cmpptr = lemt(oirt,TRUE);
459 pack("adda",lmte);
460 addaptr = lemt(oirt,TRUE);
461 pack("cmpa",lmte);
462 cmpaptr = lemt(oirt,TRUE);
463 pack("suba",lmte);
464 subaptr = lemt(oirt,TRUE);
465 pack("cmpm",lmte);
466 cmpmptr = lemt(oirt,TRUE);
467 pack("and",lmte);
468 andptr = lemt(oirt,TRUE);
469 pack("andi",lmte);
470 andiptr = lemt(oirt,TRUE);
471 pack("or",lmte);
472 orptr = lemt(oirt,TRUE);
1File: MAIN.C Page 9
473 pack("ori",lmte);
474 oriptr = lemt(oirt,TRUE);
475 pack("cmpi",lmte);
476 cmpiptr = lemt(oirt,TRUE);
477 pack("eor",lmte);
478 eorptr = lemt(oirt,TRUE);
479 pack("eori",lmte);
480 eoriptr = lemt(oirt,TRUE);
481 pack("move",lmte);
482 moveptr = lemt(oirt,TRUE);
483 pack("moveq",lmte);
484 moveqptr = lemt(oirt,TRUE);
485 pack("exg",lmte);
486 exgptr = lemt(oirt,TRUE);
487 pack("jsr",lmte);
488 jsrptr = lemt(oirt,TRUE);
489 pack("bsr",lmte);
490 bsrptr = lemt(oirt,TRUE);
491 pack("nop",lmte);
492 nopptr = lemt(oirt,TRUE);
493 pack(evnstr,lmte);
494 evenptr = lemt(oirt,TRUE);
495 }
496 mloop();
497 }
498
499 usage()
500 {
501 rpterr("Usage: as68 [-p] [-u] [-l] [-n] [-f d:] [-s d:] sourcefile\n");
502 endit();
503 }
504
505
506 /*main loop*/
507 mloop()
508 {
509 register i;
510
511 while(fchr!=EOF) {
512 if(absln>=brkln1) /*break for debugging the assembler*/
513 i=0;
514 fcflg = 0; /*first time thru expr pass one*/
515 cisit(); /*create it for one statement*/
516 }
517 opcpt = endptr;
518 hend();
519 }
520
521 #define NOCODE ((i>=0&&i<6)||i==9||i==11||i==16||(i>=LOW_CA&&i<=HI_CA))
522
523 /*create intermediate text (it) for one statement*/
524 /* call with first character of statement in fchr*/
525 cisit()
526 {
527
528 register int *p1,*p2;
529 register int (*dirop)();
530 register int i, col1; /*[vlh] col1 labels in col 1...*/
531 char str[NAMELEN], *l;
1File: MAIN.C Page 10
532
533 ciss1:
534 immed[0] = immed[1] = indir[0] = indir[1] = numcon[0] = 0;
535 numcon[1] = numsym[0] = numsym[1] = numreg[0] = numreg[1]=0;
536 plevel = numops = opdix = explmode = 0;
537 cistop:
538 col1 = 1;
539 if(fchr==EOLC) {
540 fchr = gchr();
541 goto cistop;
542 }
543 if(fchr==' ') {
544 col1 = 0;
545 igblk();
546 if(fchr==EOLC) /*blank line*/
547 goto cistop;
548 peekc = fchr;
549 if (fchr != EOF) fchr = ' '; /* [vlh] catch eof... */
550 }
551 if(fchr==EOF) return;
552
553 if(fchr=='*') { /*ignore comments*/
554 fchr = gchr();
555 if(fchr=='=') { /*relocation counter assignment*/
556 fchr = gchr(); /*pass the =*/
557 horg(); /*output constants if not bss*/
558 }
559 igrst();
560 fcflg = 0; /*clear expr first time flag for next stmt*/
561 goto ciss1;
562 }
563
564 /* get the opcode and label*/
565
566 mode = 'w'; /*word mode*/
567 igblk(); /*ignore blanks*/
568 poslab = 1;
569 gterm(TRUE);
570 poslab = 0;
571 if(fchr==':' || fchr=='=') { /*there is a label*/
572 label:
573 col1 = 0;
574 if(itype!=ITSY) { /*not a symbol*/
575 uerr(2);
576 lbt[0] = 0; /*no label*/
577 }
578 else {
579 p2 = &lmte->name[0];
580 for(p1= &lbt[0]; p1 < &lbt[NAMELEN]; ) {
581 *p1++ = *p2++;
582 }
583 if(fchr==':') fchr=gchr(); /*ignore the colons*/
584 }
585 labl1:
586 ligblk();
587 if(fchr == EOF) return;
588 if(fchr == '*') {
589 igrst(); /*comment*/
590 goto labl1;
1File: MAIN.C Page 11
591 }
592 gterm(TRUE);
593 if(fchr==':' || fchr=='=') { /*another label*/
594 if(lbt[0]) {
595 savelab(); /*save current label*/
596 dlabl(); /*define the last one*/
597 pack(tlab1,lmte); /*restor the old lable*/
598 }
599 goto label;
600 }
601 }
602 else {
603 lbt[0] = 0; /*no label*/
604 }
605 igblk();
606 if(fchr == '=')
607 goto label;
608 if(itype==ITSP) {
609 if(ival.wd2 == '=') {
610 hequ();
611 return;
612 }
613 }
614 if(itype!=ITSY) { /*not valid opcode*/
615 goto cisi3;
616 }
617 if (col1) { /* [vlh] could be a label save as is... */
618 l = &str;
619 strcpy(l,lmte->name,NAMELEN);
620 }
621 if((opcpt=lemt(oirt,TRUE))==lmte) { /*not in opcode table*/
622 if (col1) { /* [vlh] it's a label... */
623 strcpy(lmte->name,l,NAMELEN);
624 goto label;
625 }
626 cisi3:
627 if (ca_true) /* [vlh] report error if not in CA false */
628 xerr(3);
629 igrst();
630 return;
631 }
632 getmode(); /*look for .b .w or .l mode flag*/
633 if(opcpt->flags&OPDR) { /* its a directive*/
634 i = opcpt->vl1;
635 if (!ca_true && (i < LOW_CA || i > HI_CA)) { igrst(); return; }
636 if (inoffset) /* [vlh] */
637 if (!(NOCODE)) { /* can't generate code in offset */
638 xerr(12);
639 return;
640 }
641 dirop = p1direct[i]; /*call routine to handle directive*/
642 (*dirop)();
643 return;
644 }
645 else if (!ca_true) { /* [vlh] */
646 igrst();
647 return;
648 }
649 else if (inoffset) { /* [vlh] */
1File: MAIN.C Page 12
650 xerr(12);
651 return;
652 }
653
654 opcval = (opcpt->vl1); /*opcode*/
655 format = (opcpt->flags&OPFF); /*format of this instr*/
656 if (explmode)
657 if (!modeok()) { xerr(16); return; }
658 dlabl(); /*define label*/
659 opitb(); /*beginning of statement*/
660 if(format)
661 opito(); /*may have operands*/
662 else
663 igrst(); /*only comments*/
664 format = (opcpt->flags&OPFF); /* may have changed*/
665
666
667 /*end of statement*/
668
669 i = calcilen();
670 stbuf[1].itrl = i; /*assumed instruction length*/
671
672 stbuf[0].itrl = itwc; /*number of it entries*/
673 wostb(); /*write out statement buffer*/
674 loctr =+ i;
675 }
676
677 getmode()
678 {
679 if (fchr=='.') {
680 fchr = gchr();
681 switch (fchr) {
682 case 'b':
683 case 'B':
684 case 's':
685 case 'S':
686 modelen = 1;
687 mode = BYTE;
688 break;
689 case 'w':
690 case 'W':
691 modelen = 2;
692 mode = WORD;
693 break;
694 case 'l':
695 case 'L':
696 modelen = 4;
697 mode = LONG;
698 break;
699 default:
700 peekc = fchr;
701 fchr = '.';
702 goto getm1;
703 }
704 explmode++;
705 fchr = gchr();
706 igblk();
707 return;
708 }
1File: MAIN.C Page 13
709 getm1:
710 if(opcpt == exgptr) { /*length is long*/
711 modelen = 4;
712 mode = LONG;
713 }
714 else {
715 mode = WORD; /*default is word*/
716 modelen = 2;
717 }
718 }
719
720 /* check to be sure specified mode is legal */
721 modeok() /* [vlh] */
722 {
723 switch(format) {
724 case 0 :
725 case 14 :
726 case 18 :
727 return(FALSE);
728 case 13 :
729 case 15 :
730 case 20 :
731 case 21 :
732 return(modelen==1?FALSE:TRUE);
733 case 4 :
734 case 25 :
735 return(modelen==1?TRUE:FALSE);
736 case 7 :
737 case 9 :
738 return(modelen==2?FALSE:TRUE);
739 case 5 :
740 case 11 :
741 case 28 :
742 return(modelen==2?TRUE:FALSE);
743 case 6 :
744 return(modelen==4?FALSE:TRUE);
745 case 12 :
746 case 30 :
747 case 22 :
748 case 29 :
749 return(modelen==4?TRUE:FALSE);
750 default :
751 return(TRUE);
752 }
753 }
754
755 /* calculate the instruction length in bytes*/
756 calcilen()
757 {
758
759 register i,j;
760 register long l;
761 register char *p;
762
763 i = 2; /*all instrs at least 2 bytes*/
764
765 switch(format) {
766
767 case 20:
1File: MAIN.C Page 14
768 i =+ 2; /*for reg mask*/
769 case 1: /*two ea's -- one of which may be a reg*/
770 case 15:
771 case 30:
772 case 26:
773 case 5:
774 case 3:
775 case 21:
776 i =+ lenea(1);
777 case 16:
778 case 24:
779 case 25:
780 case 29:
781 i =+ lenea(0);
782 break;
783
784 case 9: /* [vlh] explicit jmp length... */
785 if (!explmode)
786 i =+ lenea(0);
787 else
788 return(mode==LONG?6:4); /*[vlh] explicit jmp.? */
789 break;
790
791 case 7:
792 i =+ (immed[0]) ? 2+lenea(1) : lenea(1);
793 break;
794
795 case 14:
796 case 11:
797 case 19:
798 i =+ 2; /*always 4 bytes*/
799 break;
800
801 case 6: /*relative branches*/
802 if(itwc == ITOP1+1) {
803 if(stbuf[ITOP1].itty == ITCN)
804 l = stbuf[ITOP1].itop;
805 else if(stbuf[ITOP1].itty == ITSY) {
806 p = stbuf[ITOP1].itop.ptrw2;
807 if(p->flags&SYDF)
808 l = p->vl1; /*symbol value*/
809 else
810 goto loffst;
811 }
812 else {
813 goto loffst;
814 }
815 l =- (loctr+2);
816 if(l<=127 && l>=-128) /*8 bit offset*/
817 break;
818 }
819 loffst:
820 if (!explmode || modelen > 1) /*[vlh] recognize br extensions*/
821 i =+ 2; /*long offset for branches*/
822 break;
823
824 case 2:
825 i =+ (mode==LONG?4:2) + lenea(1);
826 break;
1File: MAIN.C Page 15
827
828 case 23:
829 if(immed[0])
830 i =+ (mode==LONG?4:2);
831 case 17:
832 case 22:
833 i =+ lenea(1);
834 break;
835
836 case 8:
837 if(numops==1) /*memory shift instruction*/
838 i =+ shiftea(0);
839 break;
840 }
841
842 return(i);
843 }
844
845 /* calc the length of an effective address*/
846 lenea(lidx)
847 {
848 register i;
849
850 if(immed[lidx])
851 return(mode==LONG?4:2);
852 return(shiftea(lidx));
853 }
854
855 shiftea(lidx)
856 {
857 if(indir[lidx])
858 return((numcon[lidx] || numsym[lidx]) ? 2 : 0);
859 if(numsym[lidx] || numcon[lidx])
860 return((!shortadr || numcon[lidx]==2) ? 4 : 2);
861 return(0);
862 }
863
864 /*
865 *define a label if there is one to define
866 * call with:
867 * label name in lbt if it exists
868 * else lbt[0] == 0
869 */
870 dlabl()
871 {
872 register i;
873
874 if(lbt[0]) { /*got a label*/
875 pack(lbt,lmte); /*put label in main table*/
876 lblpt=lemt(sirt,FALSE); /*look up label*/
877 if(lblpt != lmte) { /*symbol entered previously*/
878 if(lbt[0] == '~') { /*local symbol -- may be duplicate*/
879 lblpt = lmte;
880 mmte();
881 }
882 else {
883 if(lblpt->flags&SYXR) {
884 uerr(29);
885 lblpt = 0;
1File: MAIN.C Page 16
886 return;
887 }
888 if((lblpt->flags)&SYDF) {
889 uerr(1);
890 lblpt = 0;
891 return;
892 }
893 }
894 }
895 else {
896 mmte(); /*make label entry in main table*/
897 }
898 lblpt->flags =| SYDF; /*label is now defined*/
899 lblpt->flags =| (rlflg==DATA)?SYRA:(rlflg==BSS)?SYBS:SYRO;
900 lblpt->vl1 = loctr; /*label value*/
901 }
902 else
903 lblpt = 0;
904 }
905
906 /*
907 * output it for operands
908 * gets intput from gterm
909 * puts output in stbuf using itwc as an index
910 * itwc should point at the next entry to be made in stbuf
911 */
912 opito()
913 {
914 register lopcomma;
915
916 lopcomma = symcon = chmvq = 0;
917 numops++; /*count first operand*/
918 while(1) {
919 starmul = symcon; /*star is multiply op if flag is set*/
920 if(fchr=='\'' || fchr=='"')
921 lopcomma = 0;
922 gterm(FALSE); /*get a term*/
923 if(itwc==ITOP1 && format==CLRFOR && opcval==CLRVAL)
924 chgclr();
925 opitoo(); /*output it for one operand*/
926 if(itype==ITSP && ival.wd2==',') {
927 if (plevel==1 && !numcon[opdix]) /* [vlh] */
928 numcon[opdix] = 1;
929 if(lopcomma)
930 uerr(30);
931 lopcomma++;
932 igblk(); /*ignore blanks for 68000 C compiler*/
933 }
934 else
935 lopcomma=0;
936 if(ival==EOLC && itype==ITSP) /*end of operands*/
937 break;
938 if(fchr==EOLC) {
939 fchr=gchr();
940 break;
941 }
942 }
943 if(chmvq) /*changed move to moveq*/
944 if(numops!=2 || immed[1] || indir[1] || numcon[1] || numsym[1] ||
1File: MAIN.C Page 17
945 numreg[1]>=AREGLO) {
946 stbuf[2].itop.ptrw2 = moveptr; /*change it back*/
947 opcpt = moveptr;
948 }
949
950 if (stbuf[2].itop.ptrw2==cmpptr) /* [vlh] cmp -> cmpm ?? */
951 if (numreg[0] && numreg[1] && indir[0] && indir[1]) {
952 stbuf[2].itop.ptrw2 = cmpmptr;
953 opcpt = cmpmptr;
954 }
955
956 if(lopcomma)
957 uerr(30);
958 }
959
960 /* change clr.l An to suba.l An,An*/
961 chgclr()
962 {
963 register char *p;
964
965 if(itype==ITSY) { /*first op is symbol*/
966 p = lemt(sirt,FALSE);
967 if(p==lmte)
968 return;
969 if(!(p->flags&SYER) || p->vl1<AREGLO) /*not A reg*/
970 return;
971 opcpt = subaptr; /*make it a suba instr*/
972 opitb();
973 opitoo(); /*output first operand -- An*/
974 itype = ITSP;
975 ival = ',';
976 opitoo(); /*output a comma*/
977 itype = ITSY; /*now the A reg again*/
978 }
979 }
980
981 /*output it for one operand*/
982 opitoo()
983 {
984 register i;
985 register char *sp;
986
987 symcon = 0;
988 if(itype==ITSP) { /*special symbol*/
989 if(ival.wd2==',' && !plevel) { /* another operand */
990 numops++;
991 if(!opdix)
992 opdix++;
993 }
994 if(ival.wd2==' ') { /*end of operands*/
995 while(fchr!=EOLC) /*ignore rest of statement*/
996 fchr=gchr();
997 return;
998 }
999 if(ival.wd2==EOLC)
1000 return;
1001 }
1002 else /*symbol or constant*/
1003 symcon = 1;
1File: MAIN.C Page 18
1004
1005 if(itwc >= STMAX) { /*it overflow*/
1006 rpterr("i.t. overflow\n");
1007 abort();
1008 }
1009 pitw->itty = itype; /*type of it entry*/
1010
1011 /*put symbol in it buffer*/
1012 if(itype==ITSY) {
1013 sp=lemt(sirt,FALSE); /*look up it main table*/
1014 pitw->itop.ptrw2 = sp; /*ptr to symbol entry*/
1015 if(sp==lmte) /*first occurrance*/
1016 mmte();
1017 itwc++; /*count entries in it buffer*/
1018 pitw++;
1019 if(!(sp->flags&SYER)) /*is it a register?*/
1020 numsym[opdix]++;
1021 else /*yes, a register*/
1022 numreg[opdix] = sp->vl1;
1023 return;
1024 }
1025 else if(itype == ITCN ) {
1026 if(ival.wd1 && ival.wd1 != -1)
1027 numcon[opdix] = 2;
1028 else if(!numcon[opdix])
1029 numcon[opdix] = 1;
1030 if(numops == 1)
1031 tryquick();
1032 }
1033
1034 /* special characters and constants*/
1035 pitw->itop = ival;
1036 pitw->itrl = reloc;
1037 itwc++;
1038 pitw++;
1039 }
1040
1041 /* change add into addq and sub into subq if possible*/
1042 tryquick()
1043 {
1044 register char *p;
1045 register long l;
1046
1047 if(fchr!=',' || !immed[0])
1048 return;
1049 l = ival;
1050 if(itwc != ITOP1+1) {
1051 if(itwc!=ITOP1+2 || stbuf[ITOP1+1].itty!=ITSP ||
1052 stbuf[ITOP1+1].itop.wd2 != '-')
1053 return;
1054 l = -l;
1055 }
1056 p = stbuf[2].itop.ptrw2;
1057 if(p==moveptr) {
1058 if(explmode && modelen != 4) /*dont change .w or .b*/
1059 return;
1060 if(l>=-128 && l<=127) {
1061 stbuf[2].itop.ptrw2 = moveqptr;
1062 opcpt = moveqptr;
1File: MAIN.C Page 19
1063 chmvq++;
1064 }
1065 return;
1066 }
1067 if(l<=0 || l>8) {
1068 return;
1069 }
1070 if(p==addptr || p==addiptr) {
1071 stbuf[2].itop.ptrw2 = opcpt = addqptr;
1072 }
1073 else if(p==subptr || p==subiptr) {
1074 stbuf[2].itop.ptrw2 = opcpt = subqptr;
1075 }
1076 }
1077
1078 strcpy(str1, str2, len)
1079 register char *str1, *str2;
1080 register int len;
1081 {
1082 while (len--)
1083 *str1++ = *str2++;
1084 }
1085
1086 /* index - find the index of a character in a string*/
1087 /* This is identical to Software Tools index.*/
1088 index(str,chr) /* returns index of c in str or -1*/
1089 char *str; /* pointer to string to search*/
1090 char chr; /* character to search for*/
1091 {
1092 register char *s;
1093 register int i;
1094
1095 for( s = str, i = 0; *s != '\0'; i++ )
1096 if( *s++ == chr )
1097 return(i);
1098 return(-1);
1099 }
1100