home *** CD-ROM | disk | FTP | other *** search
/ Micro R&D 1 / MicroRD-CD-ROM-Vol1-1994.iso / hardware / drivr / ibmk.lha / ibmk / a51.c next >
C/C++ Source or Header  |  1991-04-12  |  23KB  |  1,550 lines

  1. #include "a51.h"
  2. void convert();
  3. void hexs();
  4.  
  5. void cleanexit(t)
  6. char t[80];
  7. {
  8.     int x;
  9.     LINK tl;
  10.         tl=tag_list;
  11.         x=0;
  12.         hexsflag=0;
  13.         while (tl!=(LINK) NULL)
  14.         {
  15.             if (x==0) fprintf(f_lst,"\n");
  16.             else fprintf(f_lst,"\t");
  17.             hexs(tl->value);
  18.             fprintf(f_lst,"%s\t%s",tl->tag,hexstr);
  19.             tl=tl->next;
  20.         }
  21.         fprintf(f_lst,"\n\n");
  22.         fclose(f_lst);
  23.     printf("****%d\t%s\n",line,buffer);
  24.     printf("ERROR:%s\n",t);
  25.     exit();
  26. }
  27.  
  28. void warn(t)
  29. char t[80];
  30. {
  31.     printf("++++%d\t%s\n",line,buffer);
  32.     printf("WARNING:%s\n",t);
  33.     return;
  34. }
  35.  
  36. void strnullcpy(t,u,n)
  37. char t[80];
  38. char u[80];
  39. int n;
  40. {
  41.     strncpy(t,u,n);
  42.     t[n]='\0';
  43.     return;
  44. }
  45.  
  46. void hack(n)
  47. int n;
  48. {
  49.     int x;
  50.     for (x=0;x<=80;x++)
  51.         s[x]=s[x+n];
  52.     pos-=n;
  53.     return;
  54. }
  55.  
  56. char hexc(n)
  57. int n;
  58. {
  59.     if ((n+=48)>57) n+=7;
  60.     return((char) n);
  61. }
  62.  
  63. void hexs(l)
  64. long l;
  65. {
  66.     long m;
  67.     char t[7];
  68.     m=l;
  69.     t[0]=hexc(m/1048576);
  70.     m%=1048576;
  71.     t[1]=hexc(m/65536);
  72.     m%=65536;
  73.     t[2]=hexc(m/4096);
  74.     m%=4096;
  75.     t[3]=hexc(m/256);
  76.     m%=256;
  77.     t[4]=hexc(m/16);
  78.     m%=16;
  79.     t[5]=hexc(m);
  80.     t[6]='\0';
  81.     if (l>65535) {strcpy(hexstr,t);return;}
  82.     if ((l>255)||(hexsflag==1)) {strcpy(hexstr,&t[2]);return;}
  83.     strcpy(hexstr,&t[4]);
  84.     return;
  85. }
  86.  
  87. void showcode()
  88. {
  89.     int x,y;
  90.     int flag;
  91.     char filename[80];
  92.     char longstr[80];
  93.     strcpy(filename,basename);
  94.     f_hex=fopen(strcat(filename,".hex"),"w");
  95.     if (f_hex==(FILE *) NULL)
  96.         {
  97.         printf("Could not open file.hex for write.");
  98.         return;
  99.         }
  100.     for (x=0;x<32767-16;x+=16)
  101.     {
  102.         flag=0;
  103.         for (y=0;y<=15;y++)
  104.             if (mem[x+y]!=0) flag=1;
  105.         if (flag==1)
  106.         {
  107.             hexsflag=1;
  108.             hexs(x);
  109.             hexsflag=0;
  110.             strcpy(longstr,hexstr);
  111.             strcat(longstr,":    ");
  112.             for (y=0;y<=15;y++)
  113.             {
  114.                 hexs(mem[x+y]);
  115.                 strcat(longstr,hexstr);
  116.                 strcat(longstr," ");
  117.                 if (y==7) strcat(longstr," ");
  118.             }
  119.             fprintf(f_hex,"%s\n",longstr);
  120.         }
  121.     }
  122.     fclose(f_hex);
  123.     return;
  124. }    
  125.  
  126. void codeit(t)
  127. char t[80];
  128. {
  129.     char sht[3];
  130.     char tdup[80];
  131.     char buf[80];
  132.     char tdup2[80];
  133.     int ad,x,y;
  134.     strcpy(tdup,t);    
  135.     if (pass==1) return;
  136.     hexsflag=1;
  137.     hexs(addr);
  138.     hexsflag=0;
  139.     sht[2]='\0';
  140.     strcpy(buf,buffer);
  141.     if (strlen(buffer)>50) strnullcpy(buf,buffer,50);
  142.     strcpy(tdup2,tdup);
  143.     if (strlen(tdup)>6) strnullcpy(tdup2,tdup,6);
  144.     fprintf(f_lst,"%5d %4s  %6s   %s\n",line,hexstr,tdup2,buf);
  145.     
  146.     if (tdup[0]!=' ')
  147.     {
  148.         ad=addr;
  149.         for (x=0;x<strlen(tdup);x+=2)
  150.         {
  151.             y=tdup[x]-48;
  152.             if (y>9) y-=7;
  153.             value=y*16;
  154.             y=tdup[x+1]-48;
  155.             if (y>9) y-=7;
  156.             value+=y;    
  157.             mem[ad++]=value;
  158.         }
  159.     }
  160.     return;
  161. }
  162.  
  163. int tag_defined(t)
  164. char t[80];
  165. {
  166.     LINK    list;
  167.     list=tag_list;
  168.     while (list!=(LINK) NULL)
  169.     {
  170.         if (strcmp(t,list->tag)==0)
  171.             return(1);
  172.         list=list->next;
  173.     }
  174.     return(0);
  175.     
  176. void add_tag(val) 
  177. int val;
  178. {
  179.     LINK    list;
  180.     list=tag_list;
  181.     if (list!=(LINK) NULL)
  182.         while (list->next!=(LINK) NULL)
  183.             list=list->next;
  184.     if (list==(LINK) NULL)
  185.     {
  186.         tag_list=(LINK) malloc(sizeof(ELEM));
  187.         strcpy(tag_list->tag,name);
  188.         tag_list->value=val;
  189.         tag_list->next=(LINK) NULL;
  190.     }
  191.     else
  192.     {
  193.         list->next=(LINK) malloc(sizeof(ELEM));
  194.         strcpy(list->next->tag,name);
  195.         list->next->value=val;
  196.         list->next->next=(LINK) NULL;
  197.     }
  198.     return;
  199.  
  200. int validtag(t)
  201. char t[80];
  202. {
  203.     int x;
  204.     for (x=0;x<strlen(t);x++)
  205.     {
  206.         if ((
  207.         ((s[x]>='A')&&(s[x]<='Z'))||
  208.         ((s[x]>='0')&&(s[x]<='9'))||
  209.         (s[x]=='_')
  210.         )==0)
  211.             return(0);
  212.     }
  213.     return(1);
  214. }
  215.         
  216. void gettag(x)
  217. int x;
  218. {
  219.     strnullcpy(name,s,x);
  220.     if (validtag(name)==0)
  221.         cleanexit("Tag contains extranneous characters.");
  222.     if (pass==1)
  223.     {
  224.         if (tag_defined(name)) cleanexit("Tag already defined.");
  225.         add_tag(addr);
  226.     }
  227.     hack(x+1);
  228.     return;
  229. }
  230.  
  231. int testbase(b,c)
  232. int b;
  233. char c;
  234. {
  235.     int n;
  236.     n=((int) c)-48;
  237.  if (n<0) return(-1);
  238.     if ((n>9)&&(n<17)) return(-1);
  239.     if (n>9) n-=7;
  240.     if (n>(b-1)) return(-1);
  241.     return(n);
  242. }
  243.  
  244. void convert(base)
  245. int base;
  246. {
  247.     int x;
  248.     value=0;
  249.     while ((x=testbase(base,s[0]))>=0)
  250.     {
  251.         hack(1);
  252.         value*=base;
  253.         value+=x;
  254.     }
  255.     return;
  256. }
  257.  
  258. int lookup()
  259. {
  260.     LINK    list;
  261.     list=tag_list;
  262.     while (list!=(LINK) NULL)
  263.     {
  264.         if (strcmp(list->tag,name)==0) return(list->value);
  265.         list=list->next;
  266.     }
  267.     cleanexit("Lookup on identifier failed.");
  268. }
  269.  
  270. int regist(t)
  271. char t[80];
  272. {
  273.     if (strcmp(t,"AB")==0) return(18);
  274.     if (strcmp(t,"A")==0) return(1);
  275.     if (strcmp(t,"DPTR")==0) return(4);
  276.     if (t[0]=='R')
  277.         if (((t[1]>='0')&&(t[1]<='7'))&&(t[2]=='\0'))
  278.             return( ((int) t[1]) -38);
  279.     if (strcmp(t,"C")==0) return(3);
  280.     if (strcmp(t,"@DPTR")==0) return(5);
  281.     if (strcmp(t,"@R0")==0) return(8);
  282.     if (strcmp(t,"@R1")==0) return(9);
  283.     return(0);
  284. }
  285.  
  286. int getexp()
  287. {
  288.     int flag,x;
  289.     value=0;
  290.     flag=0;
  291.     if (s[0]=='#')
  292.     {
  293.         hack(1);
  294.         flag=1;
  295.     }
  296.     if (strncmp(s,"H'",2)==0)
  297.     {
  298.         hack(2);
  299.         convert(16,s);
  300.         return(7-flag);
  301.     }
  302.     if (strncmp(s,"B'",2)==0)
  303.     {
  304.         hack(2);
  305.         convert(2,s);
  306.         return(7-flag);
  307.     }
  308.     x=0;
  309.     if (testbase(10,s[0])>=0)
  310.     {
  311.         while(testbase(16,s[x])>=0) x++;
  312.         if (s[x]=='H') {convert(16,s);hack(1);return(7-flag);}
  313.         if (s[x-1]=='B') {convert(2,s);hack(1); return(7-flag);}
  314.         convert(10,s); return(7-flag);
  315.     }
  316.     if (s[0]=='\'')
  317.     {
  318.         hack(1);
  319.         if (s[1]!='\'') cleanexit("Need another single quote.");
  320.         value=(int) s[0];
  321.         hack(2);
  322.         if (flag==0)
  323.         {
  324.             warn("Character constants not advisable here.");
  325.             return(7);
  326.         }
  327.         return(6);
  328.     }
  329.     x=0;
  330.     while (
  331.     (s[0]!=',')&&
  332.     (s[0]!='\0')&&
  333.     (s[0]!='+')&&
  334.     (s[0]!='*')&&
  335.     (s[0]!='-')&&
  336.     (s[0]!=';')&&
  337.     (s[0]!=' ')
  338.     )
  339.     {
  340.         name[x++]=s[0];
  341.         hack(1);
  342.     }
  343.     name[x]='\0';
  344.     while (s[0]==' ') hack(1);
  345.     x=regist(name);
  346.     if (x>0) return(x);
  347.     if (tag_defined(name)==0)
  348.     {
  349.         if (pass==1) {value=0;return(7-flag);}
  350.         cleanexit("Need to define this expression.");
  351.     }
  352.     value=lookup();
  353.     return(7-flag);
  354. }
  355.         
  356. int getbyte()
  357. {
  358.     int v,x,firstx;
  359.     char c;
  360.     x=getexp();    
  361.     v=value;
  362.     firstx=x;
  363.     while ((s[0]=='+')||(s[0]=='-')||(s[0]=='*'))
  364.     {
  365.         c=s[0];
  366.         hack(1);
  367.         x=getexp();
  368.         if (x!=firstx) cleanexit("Expression types must match.");
  369.         switch(c) {
  370.             case '+':
  371.                 v+=value;
  372.                 break;
  373.             case '-':
  374.                 v-=value;
  375.                 break;
  376.             case '*':
  377.                 v*=value;
  378.                 break;
  379.             default:
  380.                 break;
  381.             }
  382.     }
  383.     realvalue=v;
  384.     value=v;
  385.     if (value<-65536) cleanexit("Value out of range.");
  386.     if (value<-128) value+=65536;
  387.     if (value<0) value+=256;
  388.     if (value>65535) cleanexit("Value out of range.");
  389.     return(x);
  390. }
  391.  
  392. void equate()
  393. {
  394.     char left[80];
  395.     int x;
  396.     hack(5);
  397.     x=0;
  398.     while ((s[x]!=',')&&(s[x]!='\0')) x++;
  399.     if (s[x]!=',') cleanexit("Equate needs a comma.");
  400.     strnullcpy(left,s,x);
  401.     if (regist(left)>0) cleanexit("Cannot use registers in equate.");
  402.     hack(x+1);
  403.     codeit("  ->");
  404.     if (pass==2)
  405.     {
  406.         x=getbyte();
  407.         return;
  408.     }
  409.     if (tag_defined(left)==1)
  410.         cleanexit("Identifier already defined.");
  411.     if (getbyte()!=7) cleanexit("Value must be a byte/word.");
  412.     strcpy(name,left);
  413.     add_tag(value);
  414.     return;
  415. }
  416.  
  417. void origin()
  418. {
  419.     hack(5);
  420.     if (getbyte()!=7) cleanexit("Must be byte/word.");
  421.     if (pass==2) codeit("  ->");
  422.     addr=value;
  423.     return;
  424. }
  425.  
  426. void defbyte()
  427. {
  428.     hack(4);
  429.     if (getbyte()!=7) cleanexit("Must be byte.");
  430.     if (value>255) cleanexit("Byte value out of range.");
  431.     if (pass==2)
  432.     {
  433.         hexs(value);
  434.         codeit(hexstr);
  435.     }
  436.     addr+=1;
  437.     return;
  438. }
  439.  
  440. void defword()
  441. {
  442.     hack(4);
  443.     if (getbyte()!=7) cleanexit("Must be word.");
  444.     if (pass==2)
  445.     {
  446.         hexsflag=1;
  447.         hexs(value);
  448.         hexsflag=0;
  449.         codeit(hexstr);
  450.     }
  451.     addr+=2;
  452.     return;
  453. }
  454.  
  455. void defmsg()
  456. {
  457.     char t[80];
  458.     int x;
  459.     hack(4);
  460.     if (s[0]!='\'')
  461.         cleanexit("Must start with single quote.");
  462.     hack(1);
  463.     t[0]='\0';
  464.     for (x=0;x<=pos;x++)
  465.     {
  466.         if (s[x]=='\'')
  467.         {
  468.             if (pass==2) codeit(t);
  469.             addr+=x;
  470.             hack(x+1);
  471.             return;
  472.         }
  473.         if (pass==2)
  474.         {
  475.             hexs(s[x]);
  476.             strcat(t,hexstr);
  477.         }
  478.     }
  479.     cleanexit("Must end with single quote.");
  480. }
  481.  
  482. void reserve()
  483. {
  484.     hack(4);
  485.     if (getbyte()!=7) cleanexit("Must be byte/word.");
  486.     if (pass==2) codeit("  ->");
  487.     addr+=value;
  488.     return;
  489. }
  490.  
  491. void endassm()
  492. {
  493.     hack(4);
  494.     return;
  495. }
  496.  
  497. void getdirec()
  498. {
  499.     if (strncmp(s,".EQU",4)==0) {equate();return;}
  500.     if (strncmp(s,".ORG",4)==0) {origin();return;}
  501.     if (strncmp(s,".DB",3)==0) {defbyte();return;}
  502.     if (strncmp(s,".DW",3)==0) {defword();return;}
  503.     if (strncmp(s,".DM",3)==0) {defmsg();return;}
  504.     if (strncmp(s,".RS",3)==0) {reserve();return;}
  505.     if (strncmp(s,".END",3)==0) {endassm();return;}
  506.     cleanexit("Compiler directive not understood.");
  507. }
  508.  
  509. void get2()
  510. {
  511.     mi=1;
  512.     lop=getbyte();
  513.     lval=value;
  514.     if ((lop==6)||(lop==7)) mi++;
  515.     if (lval>255) cleanexit("Left operator value > 255.");
  516.     if (s[0]!=',')
  517.         cleanexit("This statement needs two operands.");
  518.     hack(1);
  519.     rop=getbyte();
  520.     rval=value;
  521.     if ((rop==6)||(rop==7)) mi++;
  522.     if (rval>255) cleanexit("Right operator value > 255.");
  523.     return;
  524. }
  525.  
  526. void get1()
  527. {
  528.     mi=1;
  529.     lop=getbyte();
  530.     lval=value;
  531.     if ((lop==6)||(lop==7)) mi++;
  532.     if (lval>255) cleanexit("Operator value > 255.");
  533.     return;
  534. }
  535.  
  536. void addr11()
  537. {
  538.     lop=getbyte();
  539.     if (lop!=7) cleanexit("Operand must be an address.");
  540.     if (pass==1) {value=0;return;}
  541.     if ((value&63488)!=(addr&63488))
  542.         cleanexit("11 bit address out of range.");
  543.     value&=2047;
  544.     return;
  545. }
  546.  
  547. void addr16()
  548. {
  549.     lop=getbyte();
  550.     if (lop!=7) cleanexit("Operand must be an address.");
  551.     return;
  552. }
  553.  
  554. void data16()
  555. {
  556.     lop=getbyte();
  557.     if (lop!=6) cleanexit("Operand must be data.");
  558.     return;
  559. }
  560.  
  561. int getrel()
  562. {
  563.     int x,r;
  564.     x=getbyte();
  565.     if (x!=7) cleanexit("Operand must be an address.");
  566.     if (pass==1) {return(0);} 
  567.     r=realvalue-(addr+mi);
  568.     if (r<-128) cleanexit("Relative offset < -128.");
  569.     if (r>127) cleanexit("Relative offset > 127.");
  570.     if (r<0) r+=256;
  571.     return(r);
  572. }
  573.  
  574.  
  575. void ljmp()
  576. {
  577.     hack(5);
  578.     addr16();
  579.     hexs(02*65536+value);
  580.     codeit(hexstr);
  581.     addr+=3;
  582. }
  583.  
  584. void form0(n)
  585. int n;
  586. {
  587.     mi=2;
  588.     hexs(n*256+getrel());
  589.     codeit(hexstr);
  590.     addr+=mi;
  591. }
  592.  
  593. void sjmp()
  594. {
  595.     hack(5);
  596.     form0(128);
  597. }
  598.  
  599. jc()
  600. {
  601.     hack(3);
  602.     form0(64);
  603. }
  604.  
  605. jnc()
  606. {
  607.     hack(4);
  608.     form0(80);
  609. }
  610.  
  611. void form1(n)
  612. int n;
  613. {
  614.     get1();
  615.     mi++;
  616.     if (lop!=7) cleanexit("Left operand must be bit address.");
  617.     if (s[0]!=',') cleanexit("This command needs two operands.");
  618.     hack(1);
  619.     hexs(n*65536+lval*256+getrel());
  620.     codeit(hexstr);
  621.     addr+=mi;
  622. }
  623.  
  624. void jb()
  625. {
  626.     hack(3);
  627.     form1(32);
  628. }
  629.  
  630. void jnb()
  631. {
  632.     hack(4);
  633.     form1(48);
  634. }
  635.  
  636. void jbc()
  637. {
  638.     hack(4);
  639.     form1(16);
  640. }
  641.     
  642. void form2(n)
  643. int n;
  644. {
  645.     int x,y;
  646.     addr11();
  647.     x=(value/256)<<5;
  648.     x+=n;
  649.     y=(value%256);
  650.     hexs(x*256+y);
  651.     codeit(hexstr);
  652.     addr+=2;
  653. }
  654.  
  655. void ajmp()
  656. {
  657.     hack(5);
  658.     form2(1);
  659.     }
  660.  
  661. void acall()
  662. {
  663.     hack(6);
  664.     form2(17);
  665. }
  666.  
  667. void lcall()
  668. {
  669.     hack(6);
  670.     addr16();
  671.     hexs(18*65536+value);
  672.     codeit(hexstr);
  673.     addr+=3;
  674. }
  675.  
  676. void jz()
  677. {
  678.     hack(3);
  679.     form0(96);
  680. }
  681.  
  682. void jnz()
  683. {
  684.     hack(4);
  685.     form0(112);
  686. }
  687.  
  688. void djnz()
  689. {
  690.     hack(5);
  691.     get1();
  692.     if (s[0]!=',') cleanexit("This statement needs two operands.");
  693.     hack(1);
  694.     mi++;
  695.     if (lop==7)
  696.     {
  697.         hexs(213*65536+lval*256+getrel());
  698.         codeit(hexstr);
  699.         addr+=mi;
  700.         return;
  701.     }
  702.     if ((lop>=10)&&(lop<=17))
  703.     {
  704.         hexs((216-10+lop)*256+getrel());
  705.         codeit(hexstr);
  706.         addr+=mi;
  707.         return;
  708.     }
  709.     cleanexit("Left operand must be a direct addr or Rn.");
  710. }
  711.  
  712. void cjne()
  713. {
  714.     hack(5);
  715.     get2();
  716.     if (s[0]!=',') cleanexit("This statement needs 3 operands.");
  717.     hack(1);
  718.     mi++;
  719.     if (lop==1)
  720.     {
  721.         if (rop==6)
  722.         {
  723.             hexs(180*65536+rval*256+getrel());
  724.             codeit(hexstr);
  725.             addr+=mi;
  726.             return;
  727.         }
  728.         if (rop==7)
  729.         {
  730.             hexs(181*65536+rval*256+getrel());
  731.             codeit(hexstr);
  732.             addr+=mi;
  733.             return;
  734.         }
  735.         cleanexit("Middle operand must be # or $.");
  736.     }
  737.     if ((lop>=8)&&(lop<=17))
  738.     {
  739.         if (rop!=6) cleanexit("Middle operand must be #.");
  740.         hexs((182-8+lop)*65536+rval*256+getrel());
  741.         codeit(hexstr);
  742.         addr+=mi;
  743.         return;
  744.     }
  745.     cleanexit("Left operand must be A,@Ri, or Rn.");
  746. }
  747.  
  748. void movdptr()
  749. {
  750.     hack(8);
  751.     if (s[0]!=',') cleanexit("Comma needed.");
  752.     hack(1);
  753.     data16();
  754.     hexs(144*65536+value);
  755.     codeit(hexstr);
  756.     addr+=3;
  757.     return;
  758. }
  759.  
  760. void form4(n)
  761. int n;
  762. {
  763.     get2();
  764.     if (lop!=1) cleanexit("Left operand must be A.");
  765.     if ((rop>=6)&&(rop<=17))
  766.     {
  767.         hexs(n-6+rop);
  768.         if ((rop==6)||(rop==7))
  769.         {
  770.             hexs((n-6+rop)*256+rval);
  771.         }
  772.         codeit(hexstr);
  773.         addr+=mi;
  774.         return;
  775.     }
  776.     cleanexit("Right operand must be #,$,@Ri, or Rn.");
  777. }
  778.  
  779. void addc()
  780. {
  781.     hack(5);
  782.     form4(52);
  783. }
  784.  
  785. void add()
  786. {
  787.     hack(4);
  788.     form4(36);
  789. }
  790.  
  791. void subb()
  792. {
  793.     hack(5);
  794.     form4(148);
  795. }
  796.  
  797. void inc()
  798. {
  799.     hack(4);
  800.     get1();
  801.     if (lop==1) lop=6;
  802.     if ((lop>=6)&&(lop<=17))
  803.     {
  804.         hexs(4-6+lop);
  805.         if (lop==7)
  806.             hexs((4-6+lop)*256+lval);
  807.         codeit(hexstr);
  808.         addr+=mi;
  809.         return;
  810.     }
  811.     if (lop==4)
  812.     {
  813.         hexs(163);
  814.         codeit(hexstr);
  815.         addr+=mi;
  816.         return;
  817.     }
  818.     cleanexit("Operand must be A,$,@Ri, Rn, or DPTR.");
  819. }
  820.  
  821. void dec()
  822. {
  823.     hack(4);
  824.     get1();
  825.     if (lop==1) lop=6;
  826.     if ((lop>=6)&&(lop<=17))
  827.     {
  828.         hexs(20-6+lop);
  829.         if (lop==7)
  830.             hexs((20-6+lop)*256+lval);
  831.         codeit(hexstr);
  832.         addr+=mi;
  833.         return;
  834.     }
  835.     cleanexit("Operand must be A,$,@Ri, or Rn.");
  836. }
  837.  
  838. void mul()
  839. {
  840.     hack(4);
  841.     get1();
  842.     if (lop!=18) cleanexit("Operand must be AB.");
  843.     hexs(164);
  844.     codeit(hexstr);
  845.     addr++;
  846. }
  847.  
  848. void div()
  849. {
  850.     hack(4);
  851.     get1();
  852.     if (lop!=18) cleanexit("Operand must be AB.");
  853.     hexs(132);
  854.     codeit(hexstr);
  855.     addr++;
  856. }
  857.  
  858. void da()
  859. {
  860.     hack(3);
  861.     get1();
  862.     if (lop!=1) cleanexit("Operand must be A.");
  863.     hexs(212);
  864.     codeit(hexstr);
  865.     addr++;
  866. }
  867.  
  868. void form5(n,m,o,p)
  869. int n;
  870. int m;
  871. int o;
  872. int p;
  873. {
  874.     get2();
  875.     if (lop==1)
  876.     {
  877.         if ((rop>=6)&&(rop<=17))
  878.         {
  879.             hexs(n-8+rop);
  880.             if ((rop==6)||(rop==7))
  881.                 hexs((m-6+rop)*256+rval);
  882.             codeit(hexstr);
  883.             addr+=mi;
  884.             return;
  885.         }
  886.         cleanexit("Right OP must be #,$,@Ri, or Rn.");
  887.     }
  888.     if (lop==7)
  889.     {
  890.         if (rop==1)
  891.         {
  892.             hexs(o*256+lval);
  893.             codeit(hexstr);
  894.             addr+=mi;
  895.             return;
  896.         }
  897.         if (rop==6)
  898.         {
  899.             hexs((o+1)*65536+lval*256+rval);
  900.             codeit(hexstr);
  901.             addr+=mi;
  902.             return;
  903.         }
  904.         cleanexit("Right operand must be A or #.");
  905.     }
  906.     if (lop==3)
  907.     {
  908.         if (rop==7)
  909.         {
  910.             hexs(p*256+rval);
  911.             codeit(hexstr);
  912.             addr+=mi;
  913.             return;
  914.         }
  915.         cleanexit("Right operand must be bit address.");
  916.     }
  917.     cleanexit("Left operand must be A, C, or $.");
  918. }
  919.  
  920. void orl()
  921. {
  922.     hack(4);
  923.     form5(70,68,66,114);
  924. }
  925.  
  926. void anl()
  927. {
  928.     hack(4);
  929.     form5(86,84,82,130);
  930. }
  931.  
  932. void xrl()
  933. {
  934.     hack(4);
  935.     get2();
  936.     if (lop==1)
  937.     {
  938.         if ((rop>=6)&&(rop<=17))
  939.         {
  940.             hexs(100-6+rop);
  941.             if ((rop==6)||(rop==7))
  942.                 hexs((100-6+rop)*256+rval);
  943.             codeit(hexstr);
  944.             addr+=mi;
  945.             return;
  946.         }
  947.         cleanexit("Right OP must be #,$,@Ri, or Rn.");
  948.     }
  949.     if (lop==7)
  950.     {
  951.         if (rop==1)
  952.         {
  953.             hexs(98*256+lval);
  954.             codeit(hexstr);
  955.             addr+=mi;
  956.             return;
  957.         }
  958.         if (rop==6)
  959.         {
  960.             hexs(99*65536+lval*256+rval);
  961.             codeit(hexstr);
  962.             addr+=mi;
  963.             return;
  964.         }
  965.         cleanexit("Right operand must be A or #.");
  966.     }
  967.     cleanexit("Left operand must be A or $.");
  968. }
  969.  
  970. void form6(n,m,o)
  971. int m,n,o;
  972. {
  973.     get1();
  974.     if (lop==1)
  975.     {
  976.         hexs(n);
  977.         codeit(hexstr);
  978.         addr++;
  979.         return;
  980.     }
  981.     if (lop==3)
  982.     {
  983.         hexs(m);
  984.         codeit(hexstr);
  985.         addr++;
  986.         return;
  987.     }
  988.     if (lop==7)
  989.     {
  990.         hexs(o*256+lval);
  991.         codeit(hexstr);
  992.         addr+=2;
  993.         return;
  994.     }
  995.     cleanexit("Operand must be A, C, or $.");
  996. }
  997.  
  998. void clr()
  999. {
  1000.     hack(4);
  1001.     form6(228,195,194);
  1002. }
  1003.  
  1004. void cpl()
  1005. {
  1006.     hack(4);
  1007.     form6(244,179,178);
  1008. }
  1009.  
  1010. void setb()
  1011. {
  1012.     hack(5);
  1013.     get1();
  1014.     if (lop==3)
  1015.     {
  1016.         hexs(211);
  1017.         codeit(hexstr);
  1018.         addr++;
  1019.         return;
  1020.     }
  1021.     if (lop==7)
  1022.     {
  1023.         hexs(210*256+lval);
  1024.         codeit(hexstr);
  1025.         addr+=2;
  1026.         return;
  1027.     }
  1028.     cleanexit("Operand must be C or $.");
  1029. }
  1030.  
  1031. void form7(n)
  1032. int n;
  1033. {
  1034.     get1();
  1035.     if (lop!=1) cleanexit("Operand must be A.");
  1036.     hexs(n);
  1037.     codeit(hexstr);
  1038.     addr++;
  1039. }
  1040.  
  1041. void rl()
  1042. {
  1043.     hack(3);
  1044.     form7(35);
  1045. }
  1046.  
  1047. void rlc()
  1048. {
  1049.     hack(4);
  1050.     form7(51);
  1051. }
  1052.  
  1053. void rr()
  1054. {
  1055.     hack(3);
  1056.     form7(3);
  1057. }
  1058.  
  1059. void rrc()
  1060. {
  1061.     hack(4);
  1062.     form7(19);
  1063. }
  1064.  
  1065. void swap()
  1066. {
  1067.     hack(5);
  1068.     form7(196);
  1069. }
  1070.  
  1071. void mov()
  1072. {
  1073.     hack(4);
  1074.     get2();
  1075.     if (lop==1)
  1076.     {
  1077.         if ((rop>=7)&&(rop<=17))
  1078.         {
  1079.             hexs(229-7+rop);
  1080.             if (rop==7)
  1081.                 hexs(229*256+rval);
  1082.             codeit(hexstr);
  1083.             addr+=mi;
  1084.             return;
  1085.         }
  1086.         if (rop==6)
  1087.         {
  1088.             hexs(116*256+rval);
  1089.             codeit(hexstr);
  1090.             addr+=mi;
  1091.             return;
  1092.         }
  1093.         cleanexit("Right operand must be #,$,@Ri, or Rn.");
  1094.     }
  1095.     if ((lop>=8)&&(lop<=17))
  1096.     {
  1097.         if (rop==1)
  1098.         {
  1099.             hexs(245-8+lop);
  1100.             if (lop==7)
  1101.                 hexs((245-8+lop)*256+rval);
  1102.             codeit(hexstr);
  1103.             addr+=mi;
  1104.             return;
  1105.         }
  1106.         if (rop==7)
  1107.         {
  1108.             hexs((166-8+lop)*256+rval);
  1109.             codeit(hexstr);
  1110.             addr+=mi;
  1111.             return;
  1112.         }
  1113.         if (rop==6)
  1114.         {
  1115.             hexs((118-8+lop)*256+rval);
  1116.             codeit(hexstr);
  1117.             addr+=mi;
  1118.             return;
  1119.         }
  1120.         cleanexit("Right operand must be A,#, or $.");
  1121.     }
  1122.     if (lop==7)
  1123.     {
  1124.         if ((rop>=7)&&(rop<=17))
  1125.         {
  1126.             hexs((133-7+rop)*256+lval);
  1127.             if (rop==7)
  1128.                 hexs(133*65536+lval*256+rval);
  1129.             codeit(hexstr);
  1130.             addr+=mi;
  1131.             return;
  1132.         }
  1133.         if (rop==6)
  1134.         {
  1135.             hexs(117*65536+lval*256+rval);
  1136.             codeit(hexstr);
  1137.             addr+=mi;
  1138.             return;
  1139.         }
  1140.         if (rop==3)
  1141.         {
  1142.             hexs(146*256+lval);
  1143.             codeit(hexstr);
  1144.             addr+=mi;
  1145.             return;
  1146.         }
  1147.         if (rop==1)
  1148.         {
  1149.             hexs(245*256+lval);
  1150.             codeit(hexstr);
  1151.             addr+=mi;
  1152.             return;
  1153.         }
  1154.         cleanexit("Right operand must be #,$, @Ri, or Rn.");
  1155.     }
  1156.     if (lop==3)
  1157.     {
  1158.         if (rop!=7) cleanexit("Right operand must be bit addr.");
  1159.         hexs(162*256+rval);
  1160.         codeit(hexstr);
  1161.         addr+=mi;
  1162.         return;
  1163.     }
  1164.     cleanexit("Left operand must be A,$, or C.");
  1165. }
  1166.  
  1167. void movx()
  1168. {
  1169.     hack(5);
  1170.     get2();
  1171.     if (lop==1)
  1172.     {
  1173.         if (rop==5)
  1174.         {
  1175.             hexs(224);
  1176.             codeit(hexstr);
  1177.             addr++;
  1178.             return;
  1179.         }
  1180.         if (rop==8)
  1181.         {
  1182.             hexs(226);
  1183.             codeit(hexstr);
  1184.             addr++;
  1185.             return;
  1186.         }
  1187.         if (rop==9)
  1188.         {
  1189.             hexs(227);
  1190.             codeit(hexstr);
  1191.             addr++;
  1192.             return;
  1193.         }
  1194.         cleanexit("Right operand must be @Ri, or @DPTR.");
  1195.     }
  1196.     if (lop==5)
  1197.     {
  1198.         if (rop!=1) cleanexit("Right OP must be A.");
  1199.         hexs(240);
  1200.         codeit(hexstr);
  1201.         addr++;
  1202.         return;
  1203.     }
  1204.     if (lop==8)
  1205.     {
  1206.         if (rop!=1) cleanexit("Right OP must be A.");
  1207.         hexs(242);
  1208.         codeit(hexstr);
  1209.         addr++;
  1210.         return;
  1211.     }
  1212.     if (lop==9)
  1213.     {
  1214.         if (rop!=1) cleanexit("Right OP must be A.");
  1215.         hexs(243);
  1216.         codeit(hexstr);
  1217.         addr++;
  1218.         return;
  1219.     }
  1220.     cleanexit("Left operand must be A,@Ri, or @DPTR.");
  1221. }
  1222.  
  1223. void pop()
  1224. {
  1225.     hack(4);
  1226.     get1();
  1227.     if (lop!=7) cleanexit("Operand must be direct byte.");
  1228.     hexs(208*256+lval);
  1229.     codeit(hexstr);
  1230.     addr+=mi;
  1231. }
  1232.  
  1233. void push()
  1234. {
  1235.     hack(5);
  1236.     get1();
  1237.     if (lop!=7) cleanexit("Operand must be direct byte.");
  1238.     hexs(192*256+lval);
  1239.     codeit(hexstr);
  1240.     addr+=mi;
  1241. }
  1242.  
  1243. void form8(n)
  1244. int n;
  1245. {
  1246.     hexs(n);
  1247.     codeit(hexstr);
  1248.     addr++;
  1249.     return;
  1250. }
  1251.  
  1252. void ret()
  1253. {
  1254.     hack(3);
  1255.     form8(34);
  1256. }
  1257.  
  1258. void reti()
  1259. {
  1260.     hack(4);
  1261.     form8(50);
  1262. }
  1263.  
  1264. void nop()
  1265. {
  1266.     hack(3);
  1267.     form8(0);
  1268. }
  1269.  
  1270. void xch()
  1271. {
  1272.     hack(4);
  1273.     get2();
  1274.     if (lop!=1) cleanexit("Left operand must be A.");
  1275.     if ((rop>=7)&&(rop<=17))
  1276.     {
  1277.         hexs(197-7+rop);
  1278.         if (rop==7) hexs((197-7+rop)*256+rval);
  1279.         codeit(hexstr);
  1280.         addr+=mi;
  1281.         return;
  1282.     }
  1283.     cleanexit("Right operand must be $,@Ri, or Rn.");
  1284. }
  1285.  
  1286. void xchd()
  1287. {
  1288.     hack(5);
  1289.     get2();
  1290.     if (lop!=1) cleanexit("Left operand must be A.");
  1291.     if ((rop>=8)&&(rop<=17))
  1292.     {
  1293.         hexs(214-8+rop);
  1294.         codeit(hexstr);
  1295.         addr++;
  1296.         return;
  1297.     }
  1298.     cleanexit("Right operand must be @Ri.");
  1299. }
  1300.  
  1301. void movcadptr()
  1302. {
  1303.     hack(14);
  1304.     hexs(147);
  1305.     codeit(hexstr);
  1306.     addr++;
  1307. }
  1308.  
  1309. void movcapc()
  1310. {
  1311.     hack(12);
  1312.     hexs(131);
  1313.     codeit(hexstr);
  1314.     addr++;
  1315. }
  1316.  
  1317. void jmpadptr()
  1318. {
  1319.     hack(11);
  1320.     hexs(115);
  1321.     codeit(hexstr);
  1322.     addr++;
  1323. }
  1324.  
  1325. void opcode()
  1326. {
  1327.     if (strncmp(s,"ADDC ",5)==0) {addc();return;}
  1328.     if (strncmp(s,"ADD ",4)==0) {add();return;}
  1329.     if (strncmp(s,"SUBB ",5)==0) {subb();return;}
  1330.     if (strncmp(s,"INC ",4)==0) {inc();return;}
  1331.     if (strncmp(s,"DEC ",4)==0) {dec();return;}
  1332.     if (strncmp(s,"MUL ",4)==0) {mul();return;}
  1333.     if (strncmp(s,"DIV ",4)==0) {div();return;}
  1334.     if (strncmp(s,"DA ",3)==0) {da();return;}
  1335.     if (strncmp(s,"ANL ",4)==0) {anl();return;}
  1336.     if (strncmp(s,"ORL ",4)==0) {orl();return;}
  1337.     if (strncmp(s,"XRL ",4)==0) {xrl();return;}
  1338.     if (strncmp(s,"CPL ",4)==0) {cpl();return;}
  1339.     if (strncmp(s,"RLC ",4)==0) {rlc();return;}
  1340.     if (strncmp(s,"RR ",3)==0) {rr();return;}
  1341.     if (strncmp(s,"RRC ",4)==0) {rrc();return;}
  1342.     if (strncmp(s,"RL ",3)==0) {rl();return;}
  1343.     if (strncmp(s,"SWAP ",5)==0) {swap();return;}
  1344.     if (strncmp(s,"MOVX ",5)==0) {movx();return;}
  1345.     if (strncmp(s,"MOV DPTR",8)==0) {movdptr();return;}
  1346.     if (strncmp(s,"MOVC A,@A+DPTR",14)==0) {movcadptr();return;}
  1347.     if (strncmp(s,"MOVC A,@A+PC",12)==0) {movcapc();return;}
  1348.     if (strncmp(s,"JMP @A+DPTR",11)==0) {jmpadptr();return;}
  1349.     if (strncmp(s,"MOV ",4)==0) {mov();return;}
  1350.     if (strncmp(s,"PUSH ",5)==0) {push();return;}
  1351.     if (strncmp(s,"POP ",4)==0) {pop();return;}
  1352.     if (strncmp(s,"XCHD ",5)==0) {xchd();return;}
  1353.     if (strncmp(s,"XCH ",4)==0) {xch();return;}
  1354.     if (strncmp(s,"CLR ",4)==0) {clr();return;}
  1355.     if (strncmp(s,"SETB ",5)==0) {setb();return;}
  1356.     if (strncmp(s,"JC ",3)==0) {jc();return;}
  1357.     if (strncmp(s,"JNC ",4)==0) {jnc();return;}
  1358.     if (strncmp(s,"JNB ",4)==0) {jnb();return;}
  1359.     if (strncmp(s,"JBC ",4)==0) {jbc();return;}
  1360.     if (strncmp(s,"JB ",3)==0) {jb();return;}
  1361.     if (strncmp(s,"ACALL ",6)==0) {acall();return;}
  1362.     if (strncmp(s,"LCALL ",6)==0) {lcall();return;}
  1363.     if (strncmp(s,"RETI",4)==0) {reti();return;}
  1364.     if (strncmp(s,"RET",3)==0) {ret();return;}
  1365.     if (strncmp(s,"SJMP ",5)==0) {sjmp();return;}
  1366.     if (strncmp(s,"LJMP ",5)==0) {ljmp();return;}
  1367.     if (strncmp(s,"AJMP ",5)==0) {ajmp();return;}
  1368.     if (strncmp(s,"JZ ",3)==0) {jz();return;}
  1369.     if (strncmp(s,"JNZ ",4)==0) {jnz();return;}
  1370.     if (strncmp(s,"CJNE ",5)==0) {cjne();return;}
  1371.     if (strncmp(s,"DJNZ ",5)==0) {djnz();return;}
  1372.     if (strncmp(s,"NOP",3)==0) {nop();return;}
  1373.     if ((s[0]>32)&&(s[0]<127)) 
  1374.         warn("Syntax Error.");
  1375.     return;
  1376. }
  1377.  
  1378. void assemble()
  1379. {
  1380.     int x,y;
  1381.     while (s[0]==' ') hack(1);
  1382.     if (s[0]==';') {codeit("  **"); return;}
  1383.     y=(-1); x=0;
  1384.     do
  1385.     {
  1386.         if (s[x]==';')        
  1387.             y=x;
  1388.         x++;
  1389.     } while ((x<=pos)&&(y<0));
  1390.     if (y>=0)
  1391.     {
  1392.         s[y]='\0';
  1393.         pos=y;
  1394.     }
  1395.  
  1396.     while (s[0]==':')
  1397.     {
  1398.     warn (": at beginning of line.");
  1399.     hack(1);
  1400.     }
  1401.     
  1402.     for (x=0;x<=pos;x++)
  1403.         if (s[x]==':')
  1404.         {
  1405.             if (pass==1) gettag(x);
  1406.             else hack(x+1);
  1407.             while (s[0]==' ') hack(1);
  1408.             if (s[0]=='\0') codeit(" --]");
  1409.         }
  1410.     while (s[0]==' ') hack(1);    
  1411.     if (s[0]=='.') {getdirec();return;}
  1412.     opcode();
  1413.     return;
  1414. }
  1415.  
  1416. int getline()
  1417. {
  1418.     int x;
  1419.     x=0;
  1420.     while ((c=fgetc(f))<32)
  1421.     {
  1422.         if (c=='\n')
  1423.              {strcpy(buffer,"    ");line++;codeit("     ");}
  1424.         if (c==EOF) return(-1);
  1425.     }
  1426.     buffer[x++]=c;
  1427.     while ((c=fgetc(f))!='\n')
  1428.         buffer[x++]=c;
  1429.     buffer[x]='\0';
  1430.     return(x);
  1431. }
  1432.  
  1433. void main(argc,argv)
  1434. int argc;
  1435. char *argv[];
  1436. {
  1437.     int n,x,y,last,white;
  1438.     char filename[80];
  1439.     LINK tl;
  1440.     tag_list=(LINK) NULL;
  1441.     printf("8051 assembler by Eric Rudolph, 1991. Version 1.\n");
  1442.     strcpy(basename,argv[1]);
  1443.     strcpy(filename,basename);
  1444.     f=fopen("a51.equ","r");
  1445.     if (f==(FILE *) NULL)
  1446.         printf("Could not find asm.equ file.\n");
  1447.     else
  1448.         do
  1449.         {
  1450.             fscanf(f,"%s",name);
  1451.             fscanf(f,"%d",&value);
  1452.             if (value>0) add_tag(value);
  1453.         } while (value>0);
  1454.     for (x=0;x<32767;x++)
  1455.         mem[x]=0;
  1456.     
  1457.     f=fopen(filename,"r");
  1458.     hexsflag=0;
  1459.     if (f!=(FILE *) NULL)
  1460.     {
  1461.         printf("PASS1\n");
  1462.         addr=0;pass=1;line=0;
  1463.         do
  1464.         {
  1465.             n=getline();
  1466.             if (n>0)
  1467.             {
  1468.                 line++;
  1469.                 y=0;
  1470.                 last=1;
  1471.                 for (x=0;x<=n;x++)
  1472.                 {
  1473.                     white=0;
  1474. if ((buffer[x]==' ')||(buffer[x]=='\t'))
  1475.     white=1;
  1476. if ((white==1)&&(last==0))
  1477.     s[y++]=' ';
  1478. if (white==0)
  1479. {
  1480.     s[y]=buffer[x];
  1481.     if ((buffer[x]>='a')&&(buffer[x]<='z')) s[y]-=32;
  1482.     y++;
  1483. }
  1484.                     last=white;
  1485.                 }
  1486.                 pos=strlen(s);
  1487.                 if (s[pos-1]==' ') {s[pos-1]='\0';pos--;}
  1488.                 assemble();
  1489.             }
  1490.         } while (n>=1);
  1491.         fclose(f);
  1492.         printf("PASS2\n");
  1493.         f=fopen(filename,"r");
  1494.         strcat(filename,".lst");
  1495.         f_lst=fopen(filename,"w");
  1496.         if (f_lst==(FILE *) NULL) cleanexit("Can't open .lst for write.");
  1497.         addr=0;pass=2;line=0;
  1498.         do
  1499.         {
  1500.             n=getline();
  1501.             if (n>0)
  1502.                 {
  1503.                 line++;
  1504.                 y=0;
  1505.                 last=1;
  1506.                 for (x=0;x<=n;x++)
  1507.                 {
  1508.                     white=0;
  1509. if ((buffer[x]==' ')||(buffer[x]=='\t'))
  1510.     white=1;
  1511. if ((white==1)&&(last==0))
  1512.     s[y++]=' ';
  1513. if (white==0)
  1514. {
  1515.     s[y]=buffer[x];
  1516.     if ((buffer[x]>='a')&&(buffer[x]<='z')) s[y]-=32;
  1517.     y++;
  1518. }
  1519.                     last=white;
  1520.                 }
  1521.                 pos=strlen(s);
  1522.                 if (s[pos-1]==' ') {s[pos-1]='\0';pos--;}
  1523.                 assemble();
  1524.             }
  1525.         } while (n>=1);
  1526.         fprintf(f_lst,"=============================\n");
  1527.         tl=tag_list;
  1528.         x=0;
  1529.         hexsflag=0;
  1530.         while (tl!=(LINK) NULL)
  1531.         {
  1532.             if (x==0) fprintf(f_lst,"\n");
  1533.             else fprintf(f_lst,"\t");
  1534.             hexs(tl->value);
  1535.             fprintf(f_lst,"%s\t%s",tl->tag,hexstr);
  1536.             tl=tl->next;
  1537.         }
  1538.         fprintf(f_lst,"\n\n");
  1539.         fclose(f_lst);
  1540.         showcode();
  1541.         printf("END OF ASSEMBLY.\n");
  1542.     }
  1543.     else 
  1544.         printf("No such file.\n");
  1545.     
  1546. }
  1547.  
  1548.