Mercurial > hg > Members > kono > os9 > sbc09
comparison 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 |
comparison
equal
deleted
inserted
replaced
32:b494a9bab5f1 | 33:7c5379eb406e |
---|---|
1 /* A09, 6809 Assembler. | 1 /* A09, 6809 Assembler2 |
2 | 2 |
3 created 1993,1994 by L.C. Benschop. | 3 created 1993,1994 by L.C. Benschop. |
4 copyleft (c) 1994-2014 by the sbc09 team, see AUTHORS for more details. | 4 copyleft (c) 1994-2014 by the sbc09 team, see AUTHORS for more details. |
5 license: GNU General Public License version 2, see LICENSE for more details. | 5 license: GNU General Public License version 2, see LICENSE for more details. |
6 THERE IS NO WARRANTY ON THIS PROGRAM. | 6 THERE IS NO WARRANTY ON THIS PROGRAM. |
58 #define MAXLISTBYTES 8 | 58 #define MAXLISTBYTES 8 |
59 #define FNLEN 30 | 59 #define FNLEN 30 |
60 #define LINELEN 128 | 60 #define LINELEN 128 |
61 | 61 |
62 static int debug=0; | 62 static int debug=0; |
63 static struct incl { | |
64 char *name; | |
65 struct incl *next; | |
66 } *incls = 0; | |
67 | |
68 static struct longer { | |
69 int gline; | |
70 int change; | |
71 struct longer *next; | |
72 } *lglist = 0; | |
73 | |
74 void makelonger(int gl) { | |
75 for(struct longer *p=lglist;p;p=p->next) { | |
76 if (p->gline==gl) { // already fixed | |
77 p->change = 1; | |
78 return; | |
79 } | |
80 } | |
81 struct longer *p = (struct longer *)calloc(sizeof(struct longer *),1); | |
82 p->gline=gl; | |
83 p->next = lglist; | |
84 lglist = p; | |
85 } | |
86 | |
87 int longer() { | |
88 for(struct longer *p=lglist;p;p=p->next) { | |
89 if (p->change == 0) return 1; | |
90 } | |
91 return 0; | |
92 } | |
63 | 93 |
64 struct oprecord{char * name; | 94 struct oprecord{char * name; |
65 unsigned char cat; | 95 unsigned char cat; |
66 unsigned short code;}; | 96 unsigned short code;}; |
67 | 97 |
119 {"FCB",13,7},{"FCC",13,8}, | 149 {"FCB",13,7},{"FCC",13,8}, |
120 {"FCS",13,23}, | 150 {"FCS",13,23}, |
121 {"FCW",13,9}, | 151 {"FCW",13,9}, |
122 {"FDB",13,9}, | 152 {"FDB",13,9}, |
123 {"IF",13,10}, | 153 {"IF",13,10}, |
124 {"IFEQ",13,29}, | 154 {"IFEQ",13,30}, |
125 {"IFGT",13,30}, | 155 {"IFGT",13,29}, |
156 {"IFNDEF",13,33}, | |
126 {"IFNE",13,28}, | 157 {"IFNE",13,28}, |
127 {"IFP1",13,21}, | 158 {"IFP1",13,21}, |
128 {"INC",10,0x0c},{"INCA",0,0x4c},{"INCB",0,0x5c}, | 159 {"INC",10,0x0c},{"INCA",0,0x4c},{"INCB",0,0x5c}, |
129 {"INCLUDE",13,16}, | 160 {"INCLUDE",13,16}, |
130 {"INS",1,0x3261},{"INU",1,0x3341},{"INX",1,0x3001}, | 161 {"INS",1,0x3261},{"INU",1,0x3341},{"INX",1,0x3001}, |
176 }; | 207 }; |
177 | 208 |
178 struct symrecord{char name[MAXIDLEN+1]; | 209 struct symrecord{char name[MAXIDLEN+1]; |
179 char cat; | 210 char cat; |
180 unsigned short value; | 211 unsigned short value; |
212 struct symrecord *next; | |
181 }; | 213 }; |
182 | 214 |
183 int symcounter=0; | 215 int symcounter=0; |
184 int os9 = 0; // os9 flag | 216 int os9 = 0; // os9 flag |
185 int prevloc = 0; | 217 int prevloc = 0; |
218 int prevrmb = 0; | |
186 struct symrecord * prevlp = 0; | 219 struct symrecord * prevlp = 0; |
187 | 220 |
188 /* expression categories... | 221 /* expression categories... |
189 ECORD all zeros is ordinary constant. | 222 ECORD all zeros is ordinary constant. |
190 ECADR bit 1 indicates address within module. | 223 ECADR bit 1 indicates address within module. |
260 return symtable+i; | 293 return symtable+i; |
261 } | 294 } |
262 | 295 |
263 FILE *listfile,*objfile; | 296 FILE *listfile,*objfile; |
264 char *listname,*objname,*srcname,*curname; | 297 char *listname,*objname,*srcname,*curname; |
265 int lineno; | 298 int lineno,glineno; |
266 | 299 |
267 void | 300 void |
268 outsymtable() | 301 outsymtable() |
269 { | 302 { |
270 int i,j=0; | 303 int i,j=0; |
317 | 350 |
318 void generate() | 351 void generate() |
319 { | 352 { |
320 generating = 1; | 353 generating = 1; |
321 if (prevloc) { | 354 if (prevloc) { |
355 prevrmb = loccounter+1; // we were in rmb mode | |
322 oldlc = loccounter = prevloc-1 ; | 356 oldlc = loccounter = prevloc-1 ; |
323 os9 = prevloc = 0; | 357 prevloc = 0; |
324 } | 358 } |
325 } | 359 } |
326 | 360 |
327 | 361 |
328 char namebuf[MAXIDLEN+1]; | 362 char namebuf[MAXIDLEN+1]; |
338 int i=0; | 372 int i=0; |
339 char c; | 373 char c; |
340 while(1) { | 374 while(1) { |
341 c=*srcptr++; | 375 c=*srcptr++; |
342 if(c>='a'&&c<='z')c-=32; | 376 if(c>='a'&&c<='z')c-=32; |
343 if(c!='.'&&c!='$'&&(c<'0'||c>'9')&&(c<'A'||c>'Z'))break; | 377 if(c!='_'&&c!='@'&&c!='.'&&c!='$'&&(c<'0'||c>'9')&&(c<'A'||c>'Z'))break; |
344 if(i<MAXIDLEN)namebuf[i++]=c; | 378 if(i<MAXIDLEN)namebuf[i++]=c; |
345 } | 379 } |
346 namebuf[i]=0; | 380 namebuf[i]=0; |
347 srcptr--; | 381 srcptr--; |
348 } | 382 } |
453 skipspace(); | 487 skipspace(); |
454 c=*srcptr; | 488 c=*srcptr; |
455 if(isalpha(c))return scanlabel(); | 489 if(isalpha(c))return scanlabel(); |
456 else if(isdigit(c))return scandecimal(); | 490 else if(isdigit(c))return scandecimal(); |
457 else switch(c) { | 491 else switch(c) { |
458 case '*' : if(prevloc) { srcptr++;exprcat|=2;return prevloc-1; } | 492 case '*' : srcptr++;exprcat|=2; if(prevloc) return prevloc-1; else return loccounter; |
459 case '.' : srcptr++;exprcat|=2;return loccounter; | 493 case '.' : srcptr++;exprcat|=2; if(prevrmb) return prevrmb-1; else return loccounter; |
460 case '$' : return scanhex(); | 494 case '$' : return scanhex(); |
461 case '%' : return scanbin(); | 495 case '%' : return scanbin(); |
462 case '&' : /* compatibility */ | 496 case '&' : /* compatibility */ |
463 case '@' : return scanoct(); | 497 case '@' : return scanoct(); |
464 case '\'' : return scanchar(); | 498 case '\'' : return scanchar(); |
895 } | 929 } |
896 | 930 |
897 void | 931 void |
898 setlabel(struct symrecord * lp) | 932 setlabel(struct symrecord * lp) |
899 { | 933 { |
900 if (prevlp) { | 934 while (prevlp) { |
901 struct symrecord *l = prevlp; | 935 struct symrecord *l = prevlp; |
902 prevlp = 0; | 936 prevlp = prevlp->next; |
903 setlabel(l); | 937 setlabel(l); |
904 } | 938 } |
905 if(lp) { | 939 if(lp) { |
906 if(lp->cat!=13&&lp->cat!=6) { | 940 if(lp->cat!=13&&lp->cat!=6) { |
907 if(lp->cat!=2||lp->value!=loccounter) | 941 if(lp->cat!=2||lp->value!=loccounter) |
908 error|=8; | 942 ; // error|=8; |
909 } else { | 943 } else { |
910 lp->cat=2; | 944 lp->cat=2; |
911 lp->value=loccounter; | 945 lp->value=loccounter; |
912 } | 946 } |
913 } | 947 } |
940 case 3: putword(operand); | 974 case 3: putword(operand); |
941 } | 975 } |
942 break; | 976 break; |
943 case 4: case 6: offs=(unsigned short)operand-loccounter-codeptr-2; | 977 case 4: case 6: offs=(unsigned short)operand-loccounter-codeptr-2; |
944 if(offs<-128||offs>=128||opsize==3||unknown||!certain) { | 978 if(offs<-128||offs>=128||opsize==3||unknown||!certain) { |
945 if((!unknown)&&opsize==2&&(offs<-128||offs>=128) ) | 979 if((!unknown)&&opsize==2&&(offs<-128||offs>=128) ) { |
946 error|=16; | 980 error|=16; makelonger(glineno); |
981 } | |
947 offs--; | 982 offs--; |
948 opsize=3; | 983 opsize=3; |
949 postbyte++; | 984 postbyte++; |
950 } | 985 } |
951 putbyte(postbyte); | 986 putbyte(postbyte); |
997 { | 1032 { |
998 int offs; | 1033 int offs; |
999 scanoperands(); | 1034 scanoperands(); |
1000 if(mode!=1&&mode!=2)error|=2; | 1035 if(mode!=1&&mode!=2)error|=2; |
1001 offs=(unsigned short)operand-loccounter-2; | 1036 offs=(unsigned short)operand-loccounter-2; |
1002 if(!unknown&&(offs<-128||offs>=128))error|=16; | 1037 if(!unknown&&(offs<-128||offs>=128)) { |
1038 error|=16;makelonger(glineno); | |
1039 if (co==0x20) { | |
1040 if(mode!=1&&mode!=2)error|=2; | |
1041 putbyte(0x16); | |
1042 putword(operand-loccounter-3); | |
1043 } else { | |
1044 if(mode!=1&&mode!=2)error|=2; | |
1045 putbyte(0x10); | |
1046 putbyte(co); | |
1047 putword(operand-loccounter-4); | |
1048 } | |
1049 return; | |
1050 } | |
1003 if(pass==2&&unknown)error|=4; | 1051 if(pass==2&&unknown)error|=4; |
1004 putbyte(co); | 1052 putbyte(co); |
1005 putbyte(offs); | 1053 putbyte(offs); |
1006 } | 1054 } |
1007 | 1055 |
1168 | 1216 |
1169 switch(co) { | 1217 switch(co) { |
1170 case 0:/* RMB */ | 1218 case 0:/* RMB */ |
1171 // in OS9 mode, this generates no data | 1219 // in OS9 mode, this generates no data |
1172 // loccounter will be reset after any code to the current code generation | 1220 // loccounter will be reset after any code to the current code generation |
1221 if (prevrmb) { | |
1222 oldlc = loccounter = prevrmb-1 ; | |
1223 prevrmb = 0; | |
1224 } | |
1173 setlabel(lp); | 1225 setlabel(lp); |
1174 operand=scanexpr(0); | 1226 operand=scanexpr(0); |
1175 if(unknown)error|=4; | 1227 if(unknown)error|=4; |
1176 loccounter+=operand; | 1228 loccounter+=operand; |
1177 if(generating&&pass==2) { | 1229 if(generating&&pass==2) { |
1189 if(lp->cat==13||lp->cat==6|| | 1241 if(lp->cat==13||lp->cat==6|| |
1190 (lp->value==(unsigned short)operand&&pass==2)) { | 1242 (lp->value==(unsigned short)operand&&pass==2)) { |
1191 if(exprcat==2)lp->cat=2; | 1243 if(exprcat==2)lp->cat=2; |
1192 else lp->cat=0; | 1244 else lp->cat=0; |
1193 lp->value=operand; | 1245 lp->value=operand; |
1194 } else error|=8; | 1246 } // else error|=8; |
1195 } | 1247 } |
1196 break; | 1248 break; |
1197 case 7:/* FCB */ | 1249 case 7:/* FCB */ |
1198 generate(); | 1250 generate(); |
1199 setlabel(lp); | 1251 setlabel(lp); |
1251 case 21: /* IFP1 */ | 1303 case 21: /* IFP1 */ |
1252 if(pass==2)suppress=2; | 1304 if(pass==2)suppress=2; |
1253 break; | 1305 break; |
1254 case 29: /* IFGT */ | 1306 case 29: /* IFGT */ |
1255 operand=scanexpr(0); | 1307 operand=scanexpr(0); |
1256 if(unknown)error|=4; | 1308 if(operand<=0)suppress=2; |
1257 if(operand>0)suppress=2; | |
1258 break; | 1309 break; |
1259 case 31: /* IFLT */ | 1310 case 31: /* IFLT */ |
1260 operand=scanexpr(0); | 1311 operand=scanexpr(0); |
1261 if(unknown)error|=4; | 1312 if(operand>=0)suppress=2; |
1262 if(operand<0)suppress=2; | |
1263 break; | 1313 break; |
1264 case 30: /* IFEQ */ | 1314 case 30: /* IFEQ */ |
1265 operand=scanexpr(0); | 1315 operand=scanexpr(0); |
1266 if(unknown)error|=4; | 1316 if(operand!=0)suppress=2; |
1267 if(operand==0)suppress=2; | |
1268 break; | 1317 break; |
1269 case 28: /* IFNE */ | 1318 case 28: /* IFNE */ |
1270 case 10: /* IF */ | 1319 case 10: /* IF */ |
1271 operand=scanexpr(0); | 1320 operand=scanexpr(0); |
1272 if(unknown)error|=4; | 1321 if(operand==0)suppress=2; |
1273 if(!operand)suppress=2; | 1322 break; |
1323 case 33: /* IFNDEF */ | |
1324 operand=scanexpr(0); | |
1325 if(!unknown)suppress=2; | |
1274 break; | 1326 break; |
1275 case 12: /* ORG */ | 1327 case 12: /* ORG */ |
1276 operand=scanexpr(0); | 1328 operand=scanexpr(0); |
1277 if(unknown)error|=4; | 1329 if(unknown)error|=4; |
1278 if(generating&&pass==2&&!outmode&&!os9) { | 1330 if(generating&&pass==2&&!outmode&&!os9) { |
1295 else { | 1347 else { |
1296 if(lp->cat&1||lp->cat==6) { | 1348 if(lp->cat&1||lp->cat==6) { |
1297 if(exprcat==2)lp->cat=3; | 1349 if(exprcat==2)lp->cat=3; |
1298 else lp->cat=1; | 1350 else lp->cat=1; |
1299 lp->value=operand; | 1351 lp->value=operand; |
1300 } else error|=8; | 1352 } // else error|=8; |
1301 } | 1353 } |
1302 break; | 1354 break; |
1303 case 2: /* END */ | 1355 case 2: /* END */ |
1304 terminate=1; | 1356 terminate=1; |
1305 break; | 1357 break; |
1398 if (debug) fprintf(stderr,"DEBUG: processline: mode=%d, opsize=%d, error=%d, postbyte=%02X c=%c\n",mode,opsize,error,postbyte,c); | 1450 if (debug) fprintf(stderr,"DEBUG: processline: mode=%d, opsize=%d, error=%d, postbyte=%02X c=%c\n",mode,opsize,error,postbyte,c); |
1399 if(c!=' '&&*(srcptr-1)!=' '&&c!=0&&c!=';')error|=2; | 1451 if(c!=' '&&*(srcptr-1)!=' '&&c!=0&&c!=';')error|=2; |
1400 } | 1452 } |
1401 else error|=0x8000; | 1453 else error|=0x8000; |
1402 } else { | 1454 } else { |
1403 prevlp = lp; // os9 mode label can be data or code | 1455 if (lp) { |
1456 lp->next = prevlp; | |
1457 prevlp = lp; // os9 mode label can be data or code | |
1458 } | |
1404 } | 1459 } |
1405 if(pass==2) { | 1460 if(pass==2) { |
1406 outbuffer(); | 1461 outbuffer(); |
1407 if(listing)outlist(); | 1462 if(listing)outlist(); |
1408 } | 1463 } |
1426 if(*srcptr==':')srcptr++; | 1481 if(*srcptr==':')srcptr++; |
1427 } | 1482 } |
1428 skipspace(); | 1483 skipspace(); |
1429 scanname();op=findop(namebuf); | 1484 scanname();op=findop(namebuf); |
1430 if(op && op->cat==13) { | 1485 if(op && op->cat==13) { |
1431 if(op->code==10||op->code==13||op->code==29||op->code==28||op->code==21||op->code==30) ifcount++; | 1486 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++; |
1432 else if(op->code==3) { | 1487 else if(op->code==3) { |
1433 if(ifcount>0)ifcount--;else if(suppress==1|suppress==2)suppress=0; | 1488 if(ifcount>0)ifcount--;else if(suppress==1|suppress==2)suppress=0; |
1434 } else if(op->code==1) { | 1489 } else if(op->code==1) { |
1435 if(ifcount==0 && suppress==2)suppress=0; | 1490 if(ifcount==0 && suppress==2)suppress=0; |
1436 } | 1491 } |
1475 outmode=1; | 1530 outmode=1; |
1476 i+=2; | 1531 i+=2; |
1477 } else if(strcmp(v[i],"-l")==0) { | 1532 } else if(strcmp(v[i],"-l")==0) { |
1478 listname=v[i+1]; | 1533 listname=v[i+1]; |
1479 i+=2; | 1534 i+=2; |
1535 } else if(strcmp(v[i],"-I")==0) { | |
1536 struct incl *j = (struct incl *)malloc(sizeof(struct incl)); | |
1537 j->name = v[i+1]; | |
1538 j->next = 0; | |
1539 if (!incls) incls = j; | |
1540 else { | |
1541 struct incl *k=incls ; | |
1542 for(; k->next ; k = k->next ) ; | |
1543 k->next = j; | |
1544 } | |
1545 i+=2; | |
1480 } else if(*v[i]=='-') { | 1546 } else if(*v[i]=='-') { |
1481 usage(v[0]); | 1547 usage(v[0]); |
1482 } else { | 1548 } else { |
1483 if (srcname) usage(v[0]); | 1549 if (srcname) usage(v[0]); |
1484 srcname=v[i]; | 1550 srcname=v[i]; |
1526 i = strlen(oldname); | 1592 i = strlen(oldname); |
1527 while(i>0 && oldname[i]!='/') i--; | 1593 while(i>0 && oldname[i]!='/') i--; |
1528 } | 1594 } |
1529 if (i>0) { | 1595 if (i>0) { |
1530 char *next = strconcat(oldname,i+1,name); | 1596 char *next = strconcat(oldname,i+1,name); |
1531 if((srcfile=fopen(next,"r"))==0) { | 1597 if((srcfile=fopen(next,"r"))!=0) { |
1532 fprintf(stderr,"Cannot open source file %s\n",next); | 1598 curname = next; |
1533 exit(4); | |
1534 } | 1599 } |
1535 curname = next; | 1600 } |
1536 } else { | 1601 if (!srcfile) { |
1602 for( struct incl *d = incls; d ; d = d->next) { | |
1603 char *next = strconcat(d->name,0,name); | |
1604 if((srcfile=fopen(next,"r"))!=0) { | |
1605 curname = next; | |
1606 break; | |
1607 } | |
1608 } | |
1609 } | |
1610 } | |
1611 if (!srcfile) { | |
1537 fprintf(stderr,"Cannot open source file %s\n",name); | 1612 fprintf(stderr,"Cannot open source file %s\n",name); |
1538 exit(4); | 1613 exit(4); |
1539 } | |
1540 } | 1614 } |
1541 while(!terminate&&fgets(inpline,128,srcfile)) { | 1615 while(!terminate&&fgets(inpline,128,srcfile)) { |
1542 expandline(); | 1616 expandline(); |
1543 lineno++; | 1617 lineno++; glineno++; |
1544 srcptr=srcline; | 1618 srcptr=srcline; |
1545 if(suppress)suppressline(); else processline(); | 1619 if(suppress)suppressline(); else processline(); |
1546 } | 1620 } |
1547 setlabel(0); // process prevlp | 1621 setlabel(0); // process prevlp |
1548 fclose(srcfile); | 1622 fclose(srcfile); |
1568 if(errors) { | 1642 if(errors) { |
1569 fprintf(stderr,"%d Pass 1 Errors, Continue?",errors); | 1643 fprintf(stderr,"%d Pass 1 Errors, Continue?",errors); |
1570 c=getchar(); | 1644 c=getchar(); |
1571 if(c=='n'||c=='N') exit(3); | 1645 if(c=='n'||c=='N') exit(3); |
1572 } | 1646 } |
1647 do { | |
1573 pass=2; | 1648 pass=2; |
1574 prevloc = 0; | 1649 prevloc = 0; |
1575 loccounter=0; | 1650 loccounter=0; |
1576 errors=0; | 1651 errors=0; |
1577 generating=0; | 1652 generating=0; |
1578 terminate=0; | 1653 terminate=0; |
1654 glineno=0; | |
1579 if(listing&&((listfile=fopen(listname,"w"))==0)) { | 1655 if(listing&&((listfile=fopen(listname,"w"))==0)) { |
1580 fprintf(stderr,"Cannot open list file"); | 1656 fprintf(stderr,"Cannot open list file"); |
1581 exit(4); | 1657 exit(4); |
1582 } | 1658 } |
1583 if((objfile=fopen(objname,outmode?"w":"wb"))==0) { | 1659 if((objfile=fopen(objname,outmode?"w":"wb"))==0) { |
1584 fprintf(stderr,"Cannot write object file\n"); | 1660 fprintf(stderr,"Cannot write object file\n"); |
1585 exit(4); | 1661 exit(4); |
1586 } | 1662 } |
1587 processfile(srcname); | 1663 processfile(srcname); |
1664 } while (longer()); | |
1588 fprintf(stderr,"%d Pass 2 errors.\n",errors); | 1665 fprintf(stderr,"%d Pass 2 errors.\n",errors); |
1589 if(listing) { | 1666 if(listing) { |
1590 fprintf(listfile,"%d Pass 2 errors.\n",errors); | 1667 fprintf(listfile,"%d Pass 2 errors.\n",errors); |
1591 outsymtable(); | 1668 outsymtable(); |
1592 fclose(listfile); | 1669 fclose(listfile); |