home *** CD-ROM | disk | FTP | other *** search
- /* M6800 Cross Assembler */
- /* Overlay Segment SEG2.C Version A.1 */
- /* Pass Two of X68 M6800 cross assembler */
-
- /*
- * PERMISSION IS GRANTED FOR THE PUBLIC DOMAIN
- * NON COMMERCIAL USE OF THIS SOFTWARE.
- *
- * (C) CHRIS UNDERY 25th OCTOBER 1982
- * 11 MARGARET ST NEWTOWN 2042
- * SYDNEY, AUSTRALIA
- */
-
- /*
- This pass of X68 reads the UFN.TMP searching for
- undefined hex code signified by a '?' in the I2 field of
- and instruction. If the I3 field is also undefined, a word
- reference is assumed. The program looks up the operand in the
- symbol table and fills in the blanks. If the symbol is still
- undefined, a fatal error is assumed.
-
- This module is an overlay, loaded by the swapin function
- in X68.c
-
- */
-
- #include "x68.h"
-
- main()
- {
-
- struct nlist *lookup(), *install(), *ptr;
- char asfile[15], temp[150], listfile[15];
- char hbuf[BUFSIZ];
-
- pageno = linecnt = 0;
- printf("Pass two (Version A.1)\n");
- strcpy(asfile,filename); /* get primary file name */
- strcat(asfile,".TMP"); /* add temp filetype */
- if (fopen(asfile,ibuf) == ERROR ) {
- printf("Cannot open %s\007\n",asfile);
- exit(); /* Halt progress */
- }
- if (xing) {
- if (fcreat(hexname,hbuf) == ERROR) {
- printf("Disk probably full: Cannot create hex file\n");
- exit();
- }
- }
- if (listing) {
- if (fcreat(lstname,obuf) == ERROR ) {
- printf("Disk probably full: Cannot create %s\007\n",listfile);
- exit();
- }
- }
- lineno = 0;
- header();
- while (fgets(line,ibuf)) {
- pass2(); /* Do pass 2 */
- if (line[0] != ';') makeline();
- else {
- if (listing) {
- putc(TAB,obuf); /* Pretty up the listing */
- putc(TAB,obuf);
- }
- if (printing) printf("\t\t");
- }
- if (linecnt++ == 55) header();
- if (xing) wrhex(hbuf); /* Write hex file */
- if (listing) fputs(line,obuf);
- if (printing) printf("%s",line);
- }
- putsym(); /* Write symbols to lst */
- if (listing) {
- fprintf(obuf,"\n\nEND OF ASSEMBLY ");
- fprintf(obuf,"%d FATAL ERROR(S) DETECTED\n",errors);
- putc(0x1a,obuf);
- fflush(obuf);
- fclose(obuf);
- }
- fclose(ibuf);
- if (xing) {
- fprintf(hbuf,":00000001FF\n");
- putc(0x1a,hbuf);
- fflush(hbuf);
- fclose(hbuf);
- }
- if (!debug) unlink(asfile);
- } /* PAss 2 done */
-
-
- pass2()
- {
- struct nlist *ptr, *alt, *lookup();
- unsigned current, branch, relative;
- char swopper[16], fiddled;
-
- current = branch = relative = 0;
- lineno++;
- tokenise(); /* Get tokens */
- if (temp[8] != '?') return(1); /* No wuckers */
-
- /* Version A.1 has expression evaluator in root module x68.com */
- /* the old version was in seg1 overlay and as result, seg2 could */
- /* not be very intelligent. This version can evaluate failed */
- /* operand complexes from pass 1 */
-
- fiddled = 0;
- if (operand[0] == '#') {
- strcpy(swopper,&operand[1]);
- strcpy(operand,swopper);
- fiddled = 1;
- }
- getsub(operand); /* split operand down the middle */
- if ((ptr = lookup(xp1)) != NULL) goto itil;
- if ((alt = lookup(xp2)) == NULL) {
- B1090(); /* Total failure undefined symbol */
- return(1);
- }
- itil: if ((index(alt->def,"??") >=0) || (index(ptr->def,"??") >= 0)) {
- B1090(); /* trap unresolved references */
- return(1);
- }
- if (!evaluate(operand)) { /* only now is it safe to evaluate it */
- B1090();
- return(1);
- }
-
- /* if this line has a label then install the label now in case further */
- /* references are made to it, this takes care of foward refs on an equ */
-
- getok(label,&line[18],1,16); /* extract label from line */
- tohex(labrec,dec); /* convert result to hex string */
- if (label[0] != '\0') { /* install label reference */
- if ((alt = install(label,labrec)) == NULL) {
- printf("I just creamed the symbol table boss!\n");
- exit();
- }
- }
- if (fiddled) {
- strcpy(swopper,"#");
- strcat(swopper,operand);
- strcpy(operand,swopper);
- }
- strcpy(labad,labrec);
- if (line[10] == '?' ) { /* Word reference eg JMP */
- if (index(mnem,"EQU") >= 0) {
- temp[13] = labrec[0];
- temp[14] = labrec[1];
- temp[15] = labrec[2];
- temp[16] = labrec[3];
- temp[8] = ' ';
- temp[9] = ' ';
- temp[10] = ' '; temp[11] = ' ';
- }
- else {
- temp[8] = labrec[0];
- temp[9] = labrec[1];
- temp[10] = labrec[2];
- temp[11] = labrec[3];
- }
- return(1);
- }
- smov(hex,&temp[0],4); /* Rel brnch, get current address */
- current = todec(hex,16); /* Convert to hex */
- branch = todec(labrec,16); /* ready for diff test */
- relative = branch - current + 254;
- if (relative < 128 ) B1095();
- if (relative > 383 ) B1095();
- tohex(hex,relative); /* convert back to hex */
- temp[8] = hex[2];
- temp[9] = hex[3]; /* Replace ?? with result */
- temp[13] = labad[0]; /* Now pretty up with label addr */
- temp[14] = labad[1];
- temp[15] = labad[2];
- temp[16] = labad[3];
- return(1);
- } /* While not end of file */
-
- B1090()
- {
- printf("Variable <%s> not defined at line <%u> in module %s\n",operand,lineno,title);
- printf("%s\n",line);
- if (listing) fprintf(obuf,"*** ERROR *** UNDEFINED VARIABLE: %s \n",operand);
- errors++;
- if (lineno++ == 55) header();
- return(1);
- }
-
-
- B1095()
- {
- printf("Branch out of range at line <%u> in module %s\n",lineno,title);
- printf("%s\n",line);
- if (listing) fprintf(obuf,"*** ERROR *** BRANCH DISPLACEMENT OUT OF RANGE \n");
- errors++;
- if (lineno++ == 55) header();
- return(1);
- }
-
- /* Get set of tokens from temporary pass 1 file */
-
- tokenise()
- {
- int slew_count;
-
- getok(temp,line,1,30); /* Will also get LABEL code field */
- getok(mnem,line,2,9); /* Get mnemonic field */
- getok(operand,line,3,80); /* Get operand field */
- getcomment(line);
- if (index(mnem,"TITLE") >= 0) smov(title,operand,32);
- if (index(mnem,"PAGE") >= 0) header();
- if (index(mnem,"NOLIST") >= 0) printing = 0;
- if (index(mnem,"LIST") >= 0) printing = 1;
- if (index(mnem,"SPACE") >= 0) { /* accomodate excesses of tek ass */
- if (evaluate(operand)) {
- slew_count = 0;
- while (slew_count++ < dec) {
- if (listing) fprintf(obuf,"\n");
- if (printing) printf("\n");
- if (lineno++ == 55) header();
- }
- }
- }
- }
-
- makeline() /* Build up output line */
- {
- int adjuster;
-
-
- strcpy(line,temp); /* First stuff incl label */
- adjuster = 30 - strlen(temp);
- while (adjuster--) strcat(line," ");
- strcat(line,"\t");
- strcat(line,mnem);
- strcat(line,"\t");
- strcat(line,operand);
- strcat(line,"\t");
- strcat(line,comment);
- }
-
- header() /* Produce page header */
- {
- if (listing) {
- putc(0x0c,obuf); /* Form feed */
- fprintf(obuf,"X68 Motorola 6800 Cross Assembler Version A.1");
- fprintf(obuf," Page # %5d File: %s ",++pageno,filename);
- fprintf(obuf,"Module name: %s\n\n",title);
- fprintf(obuf,"Addr Code Source Statement\n\n");
- linecnt = 0;
- }
- if (printing) {
- if (!listing) pageno++; /* dont double up page numbering */
- putc(0x0c,1);
- printf("X68 Motorola 6800 Cross Assembler Version A.1");
- printf(" Page # %5d File: %s ",pageno,filename);
- printf("Module name: %s\n\n",title);
- printf("Addr Code Source Statement\n\n");
- if (!listing) linecnt = 0;
- }
- }
-
- gethex() /* Get hex record from output line */
- { /* Returning numberof data bytes */
- int count;
- int k, i;
- char fudge[10];
-
- count = i = 0;
- hexrec[0] = '0';
- hexrec[1] = '0';
- hexrec[2] = NULL;
- smov(fudge,temp,4);
- k = todec(fudge,16); /* convert address to dec */
- k = (k - bias);
- tohex(fudge,k);
- hexrec[2] = fudge[0];
- hexrec[3] = fudge[1];
- hexrec[4] = fudge[2];
- hexrec[5] = fudge[3];
- hexrec[6] = '\0';
- i = 6;
- strcat(hexrec,"00"); /* record type */
- i += 2;
- if (!isspace(temp[5])) {
- hexrec[i++] = temp[5];
- hexrec[i++] = temp[6];
- count++;
- }
- if (!isspace(temp[8])) {
- hexrec[i++] = temp[8];
- hexrec[i++] = temp[9];
- count++;
- }
- if (!isspace(temp[10])) {
- hexrec[i++] = temp[10];
- hexrec[i++] = temp[11];
- count++;
- }
- hexrec[i] = '\0';
- hexrec[1] = (0x30 + count);
- return(count); /* one more for checksum */
- }
-
- genbin(c) /* Generate binary image of hex record */
- int c; /* Count for countfield */
- {
- int m, i, g, j, k; /* Indices */
- char tb[5];
- bcc = i = j = k = m = 0;
- g = (strlen(hexrec)-1);
- while (m < g) { /* Loop converting hexrec to binary */
- tb[0] = hexrec[m++];
- tb[1] = hexrec[m++];
- tb[2] = '\0';
- k = todec(tb,16);
- bcc += k; /* update checksum */
- }
- bcc=(~bcc)+1; /* Take twos complement */
- return(1); /* number of characters to send */
- }
-
- wrhex(h) /* Write hex record */
- char *h;
- {
- int c, e, d;
-
- d = 0;
- if (temp[0] == ';' || temp[0] == '*') return(1);
- if (index(mnem,"SPACE") >= 0) return(1); /*PA - return if directive*/
- if (index(mnem,"NOLIST") >= 0) return(1);
- if (index(mnem,"LIST") >= 0) return(1);
- if (index(mnem,"PAGE") >= 0) return(1);
- if (index(mnem,"TITLE") >= 0) return(1);
- if (index(mnem,"PURGE") >= 0) return(1);
- if (!gethex()) return(0); /* no stuff to write */
- c = genbin(e);
- fprintf(h,":");
- fprintf(h,"%s",hexrec);
- tohex(temp,bcc);
- putc(temp[2],h);
- putc(temp[3],h);
- fprintf(h,"\n");
- }
-
- /* Write symbol table to listing device */
-
- putsym()
- {
- struct nlist *tp, *lookup();
- int bucket, num;
-
- bucket = num = 0;
- if ((!listing) && (!printing)) return(1);
- if (listing) {
- putc(0x0c,obuf);
- fprintf(obuf,"Symbols:\n\n");
- }
- if (printing) {
- putc(0x0c);
- printf("Symbols:\n\n");
- }
- while (bucket < HASHSIZE) {
- for (tp = hashtab[bucket]; tp != NULL; tp = tp->next) {
- if (listing) {
- fprintf(obuf,"%s\t%s\t",tp->name,tp->def);
- if (num == 5) {
- fprintf(obuf,"\n");
- if (linecnt++ == 55) header();
- num = 0;
- }
- }
- if (printing) { /* to console or printer */
- printf("%s\t%s\t",tp->name,tp->def);
- if (num == 4) {
- printf("\n");
- if (linecnt++ == 55) header();
- num = 0;
- }
- }
- num++;
- }
- bucket++;
- }
- if (printing) putc(0x0c,1);
- }
-