Mercurial > hg > Members > kono > os9 > sbc09
diff a09.c @ 33:7c5379eb406e
nitors9 version
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 14 Jul 2018 15:22:54 +0900 |
parents | 3c14d647bb51 |
children | 2032755628dc |
line wrap: on
line diff
--- a/a09.c Sat Jul 14 15:16:39 2018 +0900 +++ b/a09.c Sat Jul 14 15:22:54 2018 +0900 @@ -1,4 +1,4 @@ -/* A09, 6809 Assembler. +/* A09, 6809 Assembler2 created 1993,1994 by L.C. Benschop. copyleft (c) 1994-2014 by the sbc09 team, see AUTHORS for more details. @@ -60,6 +60,36 @@ #define LINELEN 128 static int debug=0; +static struct incl { + char *name; + struct incl *next; +} *incls = 0; + +static struct longer { + int gline; + int change; + struct longer *next; +} *lglist = 0; + +void makelonger(int gl) { + for(struct longer *p=lglist;p;p=p->next) { + if (p->gline==gl) { // already fixed + p->change = 1; + return; + } + } + struct longer *p = (struct longer *)calloc(sizeof(struct longer *),1); + p->gline=gl; + p->next = lglist; + lglist = p; +} + +int longer() { + for(struct longer *p=lglist;p;p=p->next) { + if (p->change == 0) return 1; + } + return 0; +} struct oprecord{char * name; unsigned char cat; @@ -121,8 +151,9 @@ {"FCW",13,9}, {"FDB",13,9}, {"IF",13,10}, - {"IFEQ",13,29}, - {"IFGT",13,30}, + {"IFEQ",13,30}, + {"IFGT",13,29}, + {"IFNDEF",13,33}, {"IFNE",13,28}, {"IFP1",13,21}, {"INC",10,0x0c},{"INCA",0,0x4c},{"INCB",0,0x5c}, @@ -178,11 +209,13 @@ struct symrecord{char name[MAXIDLEN+1]; char cat; unsigned short value; + struct symrecord *next; }; int symcounter=0; int os9 = 0; // os9 flag int prevloc = 0; +int prevrmb = 0; struct symrecord * prevlp = 0; /* expression categories... @@ -262,7 +295,7 @@ FILE *listfile,*objfile; char *listname,*objname,*srcname,*curname; -int lineno; +int lineno,glineno; void outsymtable() @@ -319,8 +352,9 @@ { generating = 1; if (prevloc) { + prevrmb = loccounter+1; // we were in rmb mode oldlc = loccounter = prevloc-1 ; - os9 = prevloc = 0; + prevloc = 0; } } @@ -340,7 +374,7 @@ while(1) { c=*srcptr++; if(c>='a'&&c<='z')c-=32; - if(c!='.'&&c!='$'&&(c<'0'||c>'9')&&(c<'A'||c>'Z'))break; + if(c!='_'&&c!='@'&&c!='.'&&c!='$'&&(c<'0'||c>'9')&&(c<'A'||c>'Z'))break; if(i<MAXIDLEN)namebuf[i++]=c; } namebuf[i]=0; @@ -455,8 +489,8 @@ if(isalpha(c))return scanlabel(); else if(isdigit(c))return scandecimal(); else switch(c) { - case '*' : if(prevloc) { srcptr++;exprcat|=2;return prevloc-1; } - case '.' : srcptr++;exprcat|=2;return loccounter; + case '*' : srcptr++;exprcat|=2; if(prevloc) return prevloc-1; else return loccounter; + case '.' : srcptr++;exprcat|=2; if(prevrmb) return prevrmb-1; else return loccounter; case '$' : return scanhex(); case '%' : return scanbin(); case '&' : /* compatibility */ @@ -897,15 +931,15 @@ void setlabel(struct symrecord * lp) { - if (prevlp) { + while (prevlp) { struct symrecord *l = prevlp; - prevlp = 0; + prevlp = prevlp->next; setlabel(l); } if(lp) { if(lp->cat!=13&&lp->cat!=6) { if(lp->cat!=2||lp->value!=loccounter) - error|=8; + ; // error|=8; } else { lp->cat=2; lp->value=loccounter; @@ -942,8 +976,9 @@ break; case 4: case 6: offs=(unsigned short)operand-loccounter-codeptr-2; if(offs<-128||offs>=128||opsize==3||unknown||!certain) { - if((!unknown)&&opsize==2&&(offs<-128||offs>=128) ) - error|=16; + if((!unknown)&&opsize==2&&(offs<-128||offs>=128) ) { + error|=16; makelonger(glineno); + } offs--; opsize=3; postbyte++; @@ -999,7 +1034,20 @@ scanoperands(); if(mode!=1&&mode!=2)error|=2; offs=(unsigned short)operand-loccounter-2; - if(!unknown&&(offs<-128||offs>=128))error|=16; + if(!unknown&&(offs<-128||offs>=128)) { + error|=16;makelonger(glineno); + if (co==0x20) { + if(mode!=1&&mode!=2)error|=2; + putbyte(0x16); + putword(operand-loccounter-3); + } else { + if(mode!=1&&mode!=2)error|=2; + putbyte(0x10); + putbyte(co); + putword(operand-loccounter-4); + } + return; + } if(pass==2&&unknown)error|=4; putbyte(co); putbyte(offs); @@ -1170,6 +1218,10 @@ case 0:/* RMB */ // in OS9 mode, this generates no data // loccounter will be reset after any code to the current code generation + if (prevrmb) { + oldlc = loccounter = prevrmb-1 ; + prevrmb = 0; + } setlabel(lp); operand=scanexpr(0); if(unknown)error|=4; @@ -1191,7 +1243,7 @@ if(exprcat==2)lp->cat=2; else lp->cat=0; lp->value=operand; - } else error|=8; + } // else error|=8; } break; case 7:/* FCB */ @@ -1253,24 +1305,24 @@ break; case 29: /* IFGT */ operand=scanexpr(0); - if(unknown)error|=4; - if(operand>0)suppress=2; + if(operand<=0)suppress=2; break; case 31: /* IFLT */ operand=scanexpr(0); - if(unknown)error|=4; - if(operand<0)suppress=2; + if(operand>=0)suppress=2; break; case 30: /* IFEQ */ operand=scanexpr(0); - if(unknown)error|=4; - if(operand==0)suppress=2; + if(operand!=0)suppress=2; break; case 28: /* IFNE */ case 10: /* IF */ operand=scanexpr(0); - if(unknown)error|=4; - if(!operand)suppress=2; + if(operand==0)suppress=2; + break; + case 33: /* IFNDEF */ + operand=scanexpr(0); + if(!unknown)suppress=2; break; case 12: /* ORG */ operand=scanexpr(0); @@ -1297,7 +1349,7 @@ if(exprcat==2)lp->cat=3; else lp->cat=1; lp->value=operand; - } else error|=8; + } // else error|=8; } break; case 2: /* END */ @@ -1400,7 +1452,10 @@ } else error|=0x8000; } else { - prevlp = lp; // os9 mode label can be data or code + if (lp) { + lp->next = prevlp; + prevlp = lp; // os9 mode label can be data or code + } } if(pass==2) { outbuffer(); @@ -1428,7 +1483,7 @@ skipspace(); scanname();op=findop(namebuf); if(op && op->cat==13) { - if(op->code==10||op->code==13||op->code==29||op->code==28||op->code==21||op->code==30) ifcount++; + if(op->code==10||op->code==13||op->code==29||op->code==28||op->code==21||op->code==30||op->code==31||op->code==33) ifcount++; else if(op->code==3) { if(ifcount>0)ifcount--;else if(suppress==1|suppress==2)suppress=0; } else if(op->code==1) { @@ -1477,6 +1532,17 @@ } else if(strcmp(v[i],"-l")==0) { listname=v[i+1]; i+=2; + } else if(strcmp(v[i],"-I")==0) { + struct incl *j = (struct incl *)malloc(sizeof(struct incl)); + j->name = v[i+1]; + j->next = 0; + if (!incls) incls = j; + else { + struct incl *k=incls ; + for(; k->next ; k = k->next ) ; + k->next = j; + } + i+=2; } else if(*v[i]=='-') { usage(v[0]); } else { @@ -1528,19 +1594,27 @@ } if (i>0) { char *next = strconcat(oldname,i+1,name); - if((srcfile=fopen(next,"r"))==0) { - fprintf(stderr,"Cannot open source file %s\n",next); - exit(4); + if((srcfile=fopen(next,"r"))!=0) { + curname = next; } - curname = next; - } else { + } + if (!srcfile) { + for( struct incl *d = incls; d ; d = d->next) { + char *next = strconcat(d->name,0,name); + if((srcfile=fopen(next,"r"))!=0) { + curname = next; + break; + } + } + } + } + if (!srcfile) { fprintf(stderr,"Cannot open source file %s\n",name); exit(4); - } } while(!terminate&&fgets(inpline,128,srcfile)) { expandline(); - lineno++; + lineno++; glineno++; srcptr=srcline; if(suppress)suppressline(); else processline(); } @@ -1570,12 +1644,14 @@ c=getchar(); if(c=='n'||c=='N') exit(3); } + do { pass=2; prevloc = 0; loccounter=0; errors=0; generating=0; terminate=0; + glineno=0; if(listing&&((listfile=fopen(listname,"w"))==0)) { fprintf(stderr,"Cannot open list file"); exit(4); @@ -1585,6 +1661,7 @@ exit(4); } processfile(srcname); + } while (longer()); fprintf(stderr,"%d Pass 2 errors.\n",errors); if(listing) { fprintf(listfile,"%d Pass 2 errors.\n",errors);