home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 13 / AACD13.ISO / AACD / Programming / Atmel / Asm / src / asm.c < prev    next >
C/C++ Source or Header  |  2000-08-22  |  32KB  |  1,832 lines

  1. /************************************************************************/
  2. /* Atmel assembler V1.01                                                */
  3. /* (C)2000 LJS                                                          */
  4. /* This should compile on anything!                                     */
  5. /*                                                                      */
  6. /* 1)Removed NULL at end of constant strings                            */
  7. /* 2)Shift Left/Right (< >) is now as for C ( << >> )                   */
  8. /* 3)Removed temporary file, now done to a buffer.                      */
  9. /* 4)No upper limit on number of labels (except for avail RAM).         */
  10. /* 5)'def' added to allow small text replacements.                      */
  11. /* 6)Maths precedence is now /*+-&|<>                                   */
  12. /* 7)New line at end of file no longer needed.                          */
  13. /* 8)Handling of undefined labels containing X,Y and Z                  */
  14. /* 9)Corrected error on an undefined beginning with H !                 */
  15. /*10)Constant strings used to have spaces removed ! "Hell o" == "Hello" */
  16. /*11)Text strings with commas processed wrong.                          */
  17. /*12)Buffer cleans up correctly.                                        */
  18. /************************************************************************/
  19.  
  20. #include<stdio.h>
  21. #include<string.h>
  22. #include<stdlib.h>
  23.  
  24. typedef unsigned long ULONG;
  25. typedef unsigned char BYTE;
  26.  
  27. #include "buff.h"
  28. #include "errors.h"
  29.  
  30. /* #define DUMP_BUFFER "tmp1.tmp" */
  31.  
  32. #define CODEFILE "Atmel.txt"
  33. #define MAXOPCODES 256
  34. #define OPLENGTH   8
  35. #define MAX_SR_LINE 16      /*16 bytes max on one S Record line*/
  36.  
  37. char *Errors[]={"OK",
  38.                                 "Bad constant",
  39.                                 "File error",
  40.                                 "Unrecognised opcode",
  41.                                 "Operand error",
  42.                                 "Out of range",
  43.                                 "Bad code generated",
  44.                                 "Use registers >15",
  45.                                 "Use registers 24, 26, 28 and 30",
  46.                                 "Redeclared label",
  47.                                 "Relative address must be even",
  48.                                 "Code must be at an even address",
  49.                                 "Can't open file for inclusion",
  50.                                 "Out of memory",
  51.                 "Missing quote's",
  52.                 "Division by zero",
  53.                 "Missing brackets",
  54.                 "Formula to complex",
  55.                 "Constant not defined",
  56.                 "Source line too long"
  57.                              };
  58.  
  59. #define D_ORG     0
  60. #define D_END     1
  61. #define D_EQU     2
  62. #define D_INCL    3
  63. #define D_NEWFILE 4
  64. #define D_ENDNEW  5
  65. #define D_CONSTB  6
  66. #define D_CONSTW  7
  67. #define D_DEFINE  8
  68.  
  69. char *Directives[]={"ORG",
  70.                                         "END",
  71.                                         "EQU",
  72.                                         "INCLUDE",
  73.                                         "FILE",
  74.                                         "ENDFILE",
  75.                                         "DB",
  76.                                         "DW",
  77.                     "DEF",
  78.                                         NULL
  79.                                      };
  80.  
  81. #include "struct.h"
  82.  
  83. struct ACode *Codes[MAXOPCODES];
  84. extern struct ACode InternCodes[];
  85.  
  86. int Error=0;
  87. long LineNumber=0;
  88. struct DStack *Files=NULL;
  89. struct Labels *LabelStack = NULL;
  90. BYTE SRBuffer[MAX_SR_LINE];
  91. BYTE SROffset;
  92. BYTE InternalTable = 0;
  93.  
  94. int SRIn=0;
  95.  
  96. #include "proto.h"
  97. #include "str_p.h"      /* String function prototypes */
  98.  
  99. char *FGets(char *Str, int Size, FILE *In);
  100. void ConvertLine( char *Line, char *First, char *Second, char *Third );
  101.  
  102. int main(int argc, char *argv[])
  103. {
  104.   MEMBUFF *Tempfile;
  105.     int Count;
  106.     char *Outfile, *Listfile=NULL;
  107.  
  108.     printf(" Atmel cross assembler (C)2000 LJS By Lee Atkins.\n");
  109.   printf(" Version date "__DATE__"\n");
  110.     if(argc<2)
  111.     {
  112.         printf(" Asm <source file> <output file> <list file>\n");
  113.         return 1;
  114.     }
  115.  
  116.     if (argc>2)
  117.     {
  118.         Outfile=argv[2];
  119.     }
  120.     else
  121.     {
  122.         Outfile="a.out";
  123.     }
  124.  
  125.     if (argc==4)
  126.     {
  127.         Listfile=argv[3];
  128.     }
  129.  
  130.     for(Count=0; Count<MAXOPCODES; Count++)
  131.     {
  132.         Codes[Count]=NULL;
  133.     }
  134.  
  135.   printf(" Loading machine file..\r");
  136.     if(ParseCodes(CODEFILE))
  137.     {
  138.     if(InternalTable)
  139.     {
  140.       printf(" Using internal code table.\n");
  141.     }
  142.     else
  143.     {
  144.       printf(" Using machine file "CODEFILE"\n");
  145.     }
  146.  
  147.         PushFiles(argv[1],NULL);
  148.     Tempfile=OpenBuffer();
  149.       if(Tempfile!=NULL)
  150.       {
  151.       printf(" Preprocessing.........\r");
  152.           if(PreProcess(argv[1],Tempfile))
  153.           {
  154.  
  155.         printf(" Assembling :%s\n Output on  :%s\n",argv[1],Outfile);
  156.               if(Listfile)
  157.               {
  158.                   printf(" List on    :%s\n",Listfile);
  159.               }
  160.               Assemble(Tempfile,Outfile,Listfile,argv[1]);
  161.           }
  162.  
  163.         if(Error)
  164.         {
  165.             printf(" File  : %s\n",Files->Data);
  166.             printf(" Error %d Line %ld %s.\n",Error,LineNumber,Errors[Error]);
  167.         }
  168.         else
  169.         {
  170.         printf(" Bytes used : %d\n",SRIn);
  171.             printf(" Assembled with no errors.\n");
  172.         }
  173.  
  174. #ifdef DUMP_BUFFER
  175.       BuffDump(DUMP_BUFFER,Tempfile);
  176. #endif
  177.  
  178.       KillBuffer(Tempfile);
  179.     }
  180.     else
  181.     {
  182.       printf(" Out of memory!\n");
  183.     }
  184.   }
  185.     else
  186.     {
  187.       printf(" Error parsing machine file!\n");
  188.     }
  189.  
  190.   if(InternalTable != 1)
  191.   {
  192.     FreeCodes();
  193.   }
  194.     FreeLabelStack();
  195.     while(PopFiles());
  196.  
  197.     return 1;
  198. }
  199.  
  200. int ParseCodes(char *FileName)
  201. {
  202.  FILE *Infile;
  203.  int Count=0, Part=0, OneOfFour=0;
  204.  char InText, InStr[36],Finished=0;
  205.  
  206.     /*Gets code from code file FileName*/
  207.  
  208.  Infile=fopen(FileName,"r");
  209.  if(Infile==NULL)
  210.  {
  211.    InternalTable = 1;
  212.    while(InternCodes[Part].Opcode != NULL)
  213.    {
  214.      Codes[Part]=&InternCodes[Part];
  215.      Part++;
  216.    }
  217.    return 1;
  218.  }
  219.  else
  220.  {
  221.    do
  222.    {
  223.        do
  224.        {
  225.            do
  226.            {
  227.                InText=fgetc(Infile);
  228.            }while( (InText<33) && (InText!=EOF) );
  229.            if(InText==EOF)
  230.            {
  231.                fclose(Infile);
  232.                return 1;
  233.            }
  234.            if(InText=='*')
  235.            {
  236.          do
  237.          {
  238.            InText=fgetc(Infile);
  239.          }while( (InText!='*') && (InText!=EOF) );
  240.          if(InText==EOF)
  241.          {
  242.            fclose(Infile);
  243.            return 0;
  244.          }
  245.            }
  246.        }while(InText=='*');
  247.  
  248.        Count=0;
  249.        do
  250.        {
  251.            InStr[Count++]=InText;
  252.            if(Count==36)
  253.            {
  254.                Count--;
  255.          fclose(Infile);
  256.          return 0;
  257.            }
  258.            InText=fgetc(Infile);
  259.        if(InText=='*')
  260.        {
  261.          fclose(Infile);
  262.          return 0;
  263.        }
  264.        }while(InText>32);
  265.        InStr[Count]=0;        /*terminate*/
  266.  
  267.        switch(OneOfFour)
  268.        {
  269.            case 0:
  270.                         Codes[Part]=(struct ACode*)malloc(sizeof(struct ACode));
  271.                         if(Codes[Part]==NULL)
  272.                         {
  273.                             Finished=2;
  274.                         }
  275.             else
  276.             {
  277.               Codes[Part]->Operand=NULL;
  278.               Codes[Part]->Code=NULL;
  279.               Codes[Part]->Flag=NULL;
  280.                           Codes[Part]->Opcode=(char*)malloc(strlen(InStr)+1);
  281.                           if(Codes[Part]->Opcode==NULL)
  282.                           {
  283.                               Finished=2;
  284.                           }
  285.               else
  286.               {
  287.                             strcpy(Codes[Part]->Opcode,InStr);
  288.                             OneOfFour++;
  289.               }
  290.             }
  291.                         break;
  292.  
  293.            case 1:
  294.                      Codes[Part]->Operand=(char*)malloc(strlen(InStr)+1);
  295.                      if(Codes[Part]->Operand==NULL)
  296.                      {
  297.                          Finished=2;
  298.                      }
  299.            else
  300.            {
  301.                        strcpy(Codes[Part]->Operand,InStr);
  302.                        OneOfFour++;
  303.            }
  304.                      break;
  305.  
  306.            case 2:
  307.                      Codes[Part]->Code=(char*)malloc(strlen(InStr)+1);
  308.                      if(Codes[Part]->Code==NULL)
  309.                      {
  310.                          Finished=2;
  311.                      }
  312.            else
  313.            {
  314.                        strcpy(Codes[Part]->Code,InStr);
  315.                        OneOfFour++;
  316.            }
  317.                      break;
  318.            case 3:
  319.                      Codes[Part]->Flag=(char*)malloc(strlen(InStr)+1);
  320.                      if(Codes[Part]->Flag==NULL)
  321.                      {
  322.              Finished=2;
  323.                      }
  324.            else
  325.            {
  326.                        strcpy(Codes[Part]->Flag,InStr);
  327.                        OneOfFour=0;
  328.                        Part++;
  329.                        if(Part==MAXOPCODES)
  330.                        {
  331.                            Finished=2;
  332.                        }
  333.            }
  334.                      break;
  335.        } /*end switch*/
  336.    }while(!Finished);
  337.    fclose(Infile);
  338.    if(Finished==1)
  339.    {
  340.      return 1;
  341.    }
  342.    else
  343.    {
  344.      return 0;
  345.    }
  346.  }
  347. }
  348.  
  349. int FreeCodes(void)
  350. {
  351.  /*Frees Codes array*/
  352.  int Count;
  353.  
  354.  for(Count=0; Count<MAXOPCODES; Count++)
  355.  {
  356.      if(Codes[Count]!=NULL)
  357.      {
  358.          if(Codes[Count]->Opcode!=NULL)
  359.          {
  360.              free(Codes[Count]->Opcode);
  361.              Codes[Count]->Opcode=NULL;
  362.          }
  363.          if(Codes[Count]->Operand!=NULL)
  364.          {
  365.              free(Codes[Count]->Operand);
  366.              Codes[Count]->Operand=NULL;
  367.          }
  368.          if(Codes[Count]->Code!=NULL)
  369.          {
  370.              free(Codes[Count]->Code);
  371.              Codes[Count]->Code=NULL;
  372.          }
  373.          if(Codes[Count]->Flag!=NULL)
  374.          {
  375.              free(Codes[Count]->Flag);
  376.              Codes[Count]->Flag=NULL;
  377.          }
  378.          free(Codes[Count]);
  379.          Codes[Count]=NULL;
  380.      }
  381.  }
  382.  return 1;
  383. }
  384.  
  385. char *FGets(char *Str, int Size, FILE *In)
  386. {
  387.   char *p=Str, Some = 0;
  388.   int k;
  389.  
  390.   do
  391.   {
  392.     k=fgetc(In);
  393.     if (k == -1)
  394.     {
  395.       if(Some) return (Str);
  396.       return (NULL);
  397.     }
  398.     Some = 1;
  399.     *p++=k;
  400.   }while( (--Size) && (k!='\n') );
  401.   *p++=0;
  402.   if(Size == 0)
  403.   {
  404.     Error = LONGLINE;
  405.   }
  406.   return(Str);
  407. }
  408.  
  409. int PreProcess(char *Filename, MEMBUFF *Tempfile)
  410. {
  411.     FILE *Infile;
  412.   char Line[128], First[128], Second[128], Third[128];
  413.   char TempStr[128], Flag;
  414.     int PC=0, Tmp, FileCount, WordPC=0, NewSz, Address;
  415.   struct Labels *Result;
  416.  
  417.     LineNumber=0;
  418.  
  419.     Infile=fopen(Filename,"r");
  420.     if(Infile==NULL)
  421.     {
  422.         printf("Can't open %s\n",Filename);
  423.         return 0;
  424.     }
  425.  
  426.     FileCount=0;
  427.   do
  428.   {
  429.     /* Had to write my own fgets() cos some implementations are slightly */
  430.     /* different */
  431.       while( (FGets(Line,128,Infile)) && (Error==0))
  432.       {
  433.       LineNumber++;
  434.           StripComments(Line);
  435.           StripCrudd(Line);
  436.           StrUpr(Line);
  437.       /* Make us multi format compatible ! */
  438.       ConvertLine(Line, First, Second, Third);
  439.           RemoveSpace(First);
  440.           RemoveSpace(Second);
  441.           RemoveChar(Second,'.');
  442.           RemoveSpaceTSF(Third);
  443.  
  444.           if(*First)
  445.           { /*Add label in stack*/
  446.         if(strcmp(Second,Directives[D_EQU])==0)
  447.               {
  448.           Replace(Third);
  449.                   Address=StrToInt(Third);
  450.                   Flag='E';
  451.         }
  452.               else if(strcmp(Second,Directives[D_DEFINE])==0)
  453.         {
  454.           Replace(Third);
  455.                   Flag='M';
  456.         }
  457.         else
  458.               {
  459.                   Address=WordPC;
  460.                   Flag='A';
  461.               }
  462.         if(Error==0)
  463.         {
  464.                 if(IsInStack(First))
  465.             {
  466.                 Error=REPEATLABEL;
  467.                   fclose(Infile);
  468.                     return 0;
  469.                 }
  470.                 if(Flag=='E')
  471.           {
  472.                   Second[0]=0;
  473.                   Third[0]=0;
  474.                 }
  475.  
  476.           if(Flag == 'M')
  477.           {
  478.             Result = AddLabel(First, Address, Flag, Third);
  479.             Second[0]=0;
  480.                   Third[0]=0;
  481.           }
  482.           else
  483.           {
  484.             Result = AddLabel(First, Address, Flag, NULL);
  485.           }
  486.           if( Result == NULL)
  487.                 {
  488.             Error=MEM;
  489.                   fclose(Infile);
  490.                     return 0;
  491.                 }
  492.           First[0]=0;
  493.         }
  494.         else
  495.         {
  496.           Error=0;
  497.         }
  498.           }
  499.  
  500.           if(*Second)
  501.           {
  502.         ProcessOperand(Third);
  503.         Error=0;
  504.  
  505.               if( (Tmp=FindCode(Second)) !=MAXOPCODES )
  506.               {
  507.                   NewSz=CodeLength(Tmp);
  508.           PC+=NewSz;
  509.           WordPC+=NewSz>>1;
  510.               }
  511.               else
  512.               {
  513.                   /*could be a directive*/
  514.                   Tmp=FindDirective(Second);
  515.                   if(Directives[Tmp]!=NULL)
  516.                   {
  517.                       /*It is!*/
  518.                       switch(Tmp)
  519.                       {
  520.               case D_EQU:
  521.                    break;
  522.               case D_DEFINE:
  523.                    break;
  524.                           case D_CONSTB:
  525.                                    NewSz=ConstantLength(Third,1);
  526.                    PC+=NewSz;
  527.                    WordPC+=NewSz>>1;
  528.                                    break;
  529.                           case D_CONSTW:
  530.                                    NewSz=ConstantLength(Third,2);
  531.                    PC+=NewSz;
  532.                    WordPC+=NewSz>>1;
  533.                                     break;
  534.                           case D_ORG:
  535.                                    PC=StrToInt(Third);
  536.                    WordPC=PC;
  537.                                    break;
  538.                           case D_NEWFILE:
  539.                                    PushFiles(Third,NULL);
  540.                                    LineNumber=0;
  541.                                     break;
  542.                           case D_ENDNEW:
  543.                                    PopFiles();
  544.                                    break;
  545.                           case D_INCL:
  546.                                    RemoveChar(Third,'"');
  547.                                     sprintf(TempStr," FILE \"%s\" \n",Third);
  548.                    BuffPutS(TempStr,Tempfile);
  549.                                     PushFiles(Third,Infile);  /*Save current file stuff*/
  550.                                     Infile=fopen(Third,"rb");
  551.                                    if(Infile==NULL)
  552.                                     {
  553.                                        Error=NOFILE;
  554.                                        Infile=PopFiles();
  555.                                        fclose(Infile);
  556.                                        return 0;
  557.                                    }
  558.                                    First[0]=0;
  559.                                    Second[0]=0;
  560.                                    Third[0]=0;
  561.                                    FileCount++;
  562.                                    LineNumber=0;
  563.                                    break;
  564.                           case D_END:
  565.                                    First[0]=0;
  566.                                     Second[0]=0;
  567.                                    Third[0]=0;
  568.                                    break;
  569.               default:
  570.                    Error=NOTOP;
  571.                    break;
  572.                       }/*end switch*/
  573.                   }
  574.           else
  575.           {
  576.             Error=NOTOP;
  577.           }
  578.               }
  579.           }
  580.           sprintf(TempStr,"%s %s %s\n",First,Second,Third);
  581.       BuffPutS(TempStr,Tempfile);
  582.       }
  583.  
  584.       fclose(Infile);
  585.       if( (FileCount) && (Error==0) )
  586.       {
  587.           BuffPutS(" ENDFILE",Tempfile);
  588.           Infile=PopFiles();
  589.       }
  590.   }while( (FileCount--) && (Error==0) );
  591.     if(Error==0) return 1;
  592.     return 0;
  593. }
  594.  
  595. int FreeLabelStack(void)
  596. {
  597.   struct Labels *Tmp;
  598.  
  599.   while(LabelStack)
  600.   {
  601.     Tmp = LabelStack->Last;
  602.     if(LabelStack->Macro) free(LabelStack->Macro);
  603.     if(LabelStack->Label) free(LabelStack->Label);
  604.     free(LabelStack);
  605.     LabelStack = Tmp;
  606.   }
  607.   return 1;
  608. }
  609.  
  610. struct Labels *AddLabel(char *Name, int Address, char Flag, char *Macro)
  611. {
  612.   struct Labels *Tmp;
  613.  
  614.   Tmp = (struct Labels*)malloc(sizeof(struct Labels));
  615.   if(Tmp != NULL)
  616.   {
  617.     Tmp->Last  = LabelStack;
  618.     Tmp->Macro = NULL;
  619.     Tmp->Label = (char*)malloc(strlen(Name)+1);
  620.     if(Tmp->Label != NULL)
  621.     {
  622.       strcpy(Tmp->Label, Name);
  623.       Tmp->Address = Address;
  624.       Tmp->Flag = Flag;
  625.       if(Macro)
  626.       {
  627.         Tmp->Macro = (char*)malloc(strlen(Macro)+1);
  628.         if(Tmp->Macro != NULL)
  629.         {
  630.           strcpy(Tmp->Macro, Macro);
  631.           LabelStack = Tmp;
  632.           return Tmp;
  633.         }
  634.       }
  635.       else
  636.       {
  637.         LabelStack = Tmp;
  638.         return Tmp;
  639.       }
  640.       free(Tmp->Label);
  641.     }
  642.     free(Tmp);
  643.   }
  644.   return NULL;
  645. }
  646.  
  647. int StripComments(char *Txt)
  648. {
  649.     int Len=0;
  650.  
  651.     while((*Txt!=';') && (Len<127) && (*Txt))
  652.     {
  653.         Txt++;
  654.         Len++;
  655.     if(*Txt=='"')
  656.     {
  657.       Txt++;
  658.       Len++;
  659.       while( (*Txt!='"') && (Len<127) && (*Txt) )
  660.       {
  661.         Txt++;
  662.         Len++;
  663.       }
  664.       if( (Len==127) || (*Txt!='"') )
  665.       {
  666.         Error=MISSINGQUOTE;
  667.         return 0;
  668.       }
  669.     }
  670.     }
  671.     *Txt=0;
  672.     return 1;
  673. }
  674.  
  675. int CodeLength(int Code)
  676. {
  677.     int Result;
  678.  
  679.     if(Codes[Code]==NULL)
  680.     {
  681.         return 0;
  682.     }
  683.     Result=strlen(Codes[Code]->Code);
  684.     if(strchr(Codes[Code]->Code,'!'))
  685.     {
  686.         Result-=CountChar(Codes[Code]->Code,'!');
  687.     }
  688.     Result/=OPLENGTH;
  689.  
  690.     return Result;
  691. }
  692.  
  693.  
  694. int IsInStack(char *Str)
  695. {
  696.     struct Labels *Tmp;
  697.  
  698.   Tmp = LabelStack;
  699.   while(Tmp)
  700.   {
  701.         if(strcmp(Str,Tmp->Label)==0)
  702.         {
  703.             return 1;
  704.         }
  705.     Tmp = Tmp->Last;
  706.     }
  707.     return 0;
  708. }
  709.  
  710.  
  711. int FindCode(char *Str)
  712. {
  713.     int Count;
  714.  
  715.     for (Count=0; Count<MAXOPCODES; Count++)
  716.     {
  717.         if(Codes[Count]!=NULL)
  718.         {
  719.             if(strcmp(Str,Codes[Count]->Opcode)==0)
  720.             {
  721.                 return Count;
  722.             }
  723.         }
  724.     }
  725.     return Count;
  726. }
  727.  
  728. int FindDirective(char *Str)
  729. {
  730.     int Count=0;
  731.  
  732.     while(Directives[Count])
  733.     {
  734.         if(strcmp(Str,Directives[Count])==0)
  735.         {
  736.             return Count;
  737.         }
  738.         Count++;
  739.     }
  740.     return Count;
  741. }
  742.  
  743. int ProcessOperand(char *Str)
  744. {
  745.     char *Ptr,Left[128],Right[128],Comma;
  746.  
  747.   if(strlen(Str) == 0)
  748.   {
  749.     return 1;
  750.   }
  751.  
  752.   Left[0]=0;
  753.   Right[0]=0;
  754.     Ptr=Str;
  755.     Comma=0;
  756.     while( (*Str!=',') && (*Str) )
  757.     {
  758.         Str++;
  759.     }
  760.     if(*Str==',')
  761.     {
  762.         *Str=0;
  763.         Str++;
  764.         Comma=1;
  765.     }
  766.     else
  767.     {
  768.         Str=Ptr;
  769.     }
  770.  
  771.     strcpy(Left,Ptr);
  772.     strcpy(Right,Str);
  773.     Replace(Left);
  774.     strcpy(Ptr,Left);
  775.     if(Comma)
  776.     {
  777.    Replace(Right);
  778.      strcat(Ptr,",");
  779.      strcat(Ptr,Right);
  780.     }
  781.     return 0;
  782. }
  783.  
  784. int Replace(char *Str)
  785. {
  786.   int Ret, Result = 0;
  787.   char Work[128],Returned[128], *Sep="+-*/&|<>)",*Tmp;
  788.   char *Orig, *Op=" ", *StrIn, BitOfMath=0;
  789.  
  790.   Work[0]=0;
  791.   Orig=Str;
  792.   StrIn=Str;
  793.   while(*Str)
  794.   {
  795.     if(*Str=='(')
  796.     {
  797.       *Op=*Str;
  798.       strcat(Work,Op);
  799.       Orig++;
  800.     }
  801.     else
  802.     {
  803.       Tmp=Sep;
  804.       while( (*Tmp) && (*Tmp!=*Str))
  805.       {
  806.         Tmp++;
  807.       }
  808.       if(*Tmp)
  809.       {
  810.         /*Found a maths operator*/
  811.         BitOfMath=1;
  812.         *Str=0;
  813.         Result += ReplaceLabels(Orig,Returned);
  814.         strcat(Work,Returned);
  815.         *Op=*Tmp;
  816.         strcat(Work,Op);
  817.         Orig=Str+1;
  818.       }
  819.     }
  820.     Str++;
  821.   }
  822.   Result += ReplaceLabels(Orig,Returned);
  823.   strcat(Work,Returned);
  824.   if(BitOfMath)
  825.   {
  826.     Ret=Math(Work);
  827.     if(!Error)
  828.     {
  829.       sprintf(StrIn,"$%X",Ret);
  830.     }
  831.     else
  832.     {
  833.       strcpy(StrIn,Work);
  834.     }
  835.   }
  836.   else
  837.   {
  838.     strcpy(StrIn,Work);
  839.   }
  840.  
  841.   return (Result);
  842. }
  843.  
  844. /*****************************************
  845. * ReplaceLabels()
  846. * Searches for a label in the label stack.
  847. * Copies the labels value into Res.
  848. *****************************************/
  849. int ReplaceLabels(char *Str, char *Res)
  850. {
  851.     struct Labels *Tmp;
  852.  
  853.   Tmp = LabelStack;
  854.     while(Tmp)
  855.     {
  856.         if(Tmp->Label!=NULL)
  857.         {
  858.             if(strcmp(Str, Tmp->Label)==0)
  859.             {
  860.         if(Tmp->Macro)
  861.         {
  862.           strcpy(Res,Tmp->Macro);
  863.         }
  864.         else
  865.         {
  866.                 sprintf(Res,"$%04X",Tmp->Address);
  867.         }
  868.                 return 1;
  869.             }
  870.         }
  871.     Tmp = Tmp->Last;
  872.     }
  873.   strcpy(Res,Str);
  874.     return 0;
  875. }
  876.  
  877. int StrToInt(char *Str)
  878. {
  879.     /*Converts an asciiz number string into an int*/
  880.     /*Detects input type as being in hex,dec or bin*/
  881.     /*$aa, 0aaH is hex, %1001, 1001b is binary*/
  882.  
  883.     int Result;
  884.  
  885.     StrUpr(Str);
  886.     if(strchr(Str,'H')!=NULL)
  887.     {
  888.         Result=HexToInt(Str);
  889.     }
  890.     else if(strchr(Str,'$')!=NULL)
  891.     {
  892.         Result=HexToInt(Str);
  893.     }
  894.     else if(strchr(Str,'%')!=NULL)
  895.     {
  896.         Result=BinToInt(Str);
  897.     }
  898.     else if(strchr(Str,'B')!=NULL)
  899.     {
  900.         Result=BinToInt(Str);
  901.     }
  902.     else
  903.     {
  904.         if(!Validate(Str,"-+0123456789"))
  905.         {
  906.             Error=CONSTANT;
  907.             return 0;
  908.         }
  909.         Result=atoi(Str);
  910.     }
  911.     return Result;
  912. }
  913.  
  914. int HexToInt(char *Str)
  915. {
  916. /* converts a hex string into an int*/
  917.     int Result=0,Weight=1,C=1;
  918.     char *Tmp;
  919.  
  920.     Tmp=Str;
  921.     if(strchr(Str,'$')!=NULL)
  922.     {
  923.         Tmp=strchr(Str,'$');
  924.         Tmp++;
  925.     }
  926.     else
  927.     {
  928.         while(*Str)
  929.         {
  930.             Str++;
  931.         }
  932.         while(*Str!='H')
  933.         {
  934.             Str--;
  935.         }
  936.         *Str=0;
  937.     }
  938.     Str=Tmp+strlen(Tmp);
  939.  
  940.     if( (!Validate(Tmp,"0123456789ABCDEF")) || (*Tmp == 0) )
  941.     {
  942.         Error=CONSTANT;
  943.         return 0;
  944.     }
  945.     while(Str!=Tmp)
  946.     {
  947.         Str--;
  948.         Result+=(*Str<'A' ? (*Str-'0'):(10+(*Str-'A')) ) * Weight;
  949.         Weight<<=4;
  950.         C++;
  951.     }
  952.     return Result;
  953. }
  954.  
  955. int BinToInt(char *Str)
  956. {
  957.  /*Converts a binary string into an int*/
  958.     int Result=0,Weight=1;
  959.     char *Tmp;
  960.  
  961.     Tmp=Str;
  962.     if(strchr(Str,'%')!=NULL)
  963.     {
  964.         Tmp=strchr(Str,'%');
  965.         Tmp++;
  966.     }
  967.     else
  968.     {
  969.         while(*Str)
  970.         {
  971.             Str++;
  972.         }
  973.         while(*Str!='B')
  974.         {
  975.             Str--;
  976.         }
  977.         *Str=0;
  978.     }
  979.     Str=Tmp+strlen(Tmp);
  980.     if( (!Validate(Tmp,"01")) || (*Tmp == 0) )
  981.     {
  982.         Error=CONSTANT;
  983.         return 0;
  984.     }
  985.     while(Str!=Tmp)
  986.     {
  987.         Str--;
  988.         Result+=(*Str-'0') * Weight;
  989.         Weight<<=1;
  990.     }
  991.     return Result;
  992. }
  993.  
  994. int Assemble(MEMBUFF *Tempfile, char *Out, char *List, char *Name)
  995. {
  996.     FILE *Outfile=NULL, *SRecord=NULL;
  997.     int Count,Found,Replaced,Tmp,PC=0,OldPC=0,PrintPC=0, SRPC=0,CodePC=0;
  998.     char Line[128], First[128], Second[128], Repeat[128], *Ptr;
  999.     char OrigFirst[128], OrigSecond[128], Third[128];
  1000.     char Code[33], Map[8],*Indirect,*Post,*Pre, *Temp, Flag;
  1001.     ULONG CodeData;
  1002.   int Address;
  1003.  
  1004.     LineNumber=0;
  1005.  
  1006.     BuffRewind(Tempfile);
  1007.  
  1008.     if(List)
  1009.     {
  1010.         Outfile=fopen(List,"wb");
  1011.         if(Outfile==NULL)
  1012.         {
  1013.             Error=FILE_ERROR;
  1014.             return 0;
  1015.         }
  1016.     }
  1017.  
  1018.     SRecord=fopen(Out,"w");
  1019.     if(SRecord==NULL)
  1020.     {
  1021.         if(Outfile) fclose(Outfile);
  1022.         Error=FILE_ERROR;
  1023.         return 0;
  1024.     }
  1025.  
  1026.     StartSRecord(SRecord,Name);
  1027.  
  1028.     do
  1029.     {
  1030.         do
  1031.         {
  1032.       Line[0] = 0;
  1033.             BuffGetS(Line,128,Tempfile);
  1034.             LineNumber++;
  1035.             StripCrudd(Line);
  1036.             /* StrUpr(Line); */
  1037.             Ptr=StrCpyChar(First,Line,' ');
  1038.             Ptr=StrCpyChar(Second,Ptr,' ');
  1039.             StrCpyChar(Third,Ptr,0);
  1040.             RemoveSpace(First);
  1041.             RemoveSpace(Second);
  1042.       RemoveSpaceTSF(Third);
  1043.         }while((*Second==0) && (!BuffEOF(Tempfile)));
  1044.  
  1045.         if(*Second == 0)
  1046.         {
  1047.             FinishSRecord(SRecord,SRPC-1);
  1048.             if(Outfile)
  1049.       {
  1050.         DumpLabels(Outfile);
  1051.         fclose(Outfile);
  1052.       }
  1053.             fclose(SRecord);
  1054.             return 1;
  1055.         }
  1056.  
  1057.     strcpy(OrigFirst,Second);     /*Save for output to list file*/
  1058.         strcpy(OrigSecond,Third);
  1059.  
  1060.     if(!strchr(Third,'"'))   /*Test for a text string*/
  1061.     {
  1062.       ProcessOperand(Third);
  1063.       /*Look for code*/
  1064.       Indirect=strchr(Third,'X');
  1065.           if(Indirect==NULL)
  1066.           {
  1067.               Indirect=strchr(Third,'Y');
  1068.           }
  1069.           if(Indirect==NULL)
  1070.           {
  1071.               Indirect=strchr(Third,'Z');
  1072.           }
  1073.     }
  1074.     else
  1075.     {
  1076.       Indirect=NULL;
  1077.     }
  1078.  
  1079.         if(Indirect!=NULL)
  1080.         {
  1081.       Error=0;    /*These will produce an error in the maths bits*/
  1082.             Post=strchr(Third,'+');
  1083.             Pre=strchr(Third,'-');
  1084.             if(Post)
  1085.             {
  1086.                 if(Post<Indirect)
  1087.                 {
  1088.                     Pre=Post;
  1089.                     Post=NULL;
  1090.                 }
  1091.                 else if(Post>Indirect)
  1092.                 {
  1093.                     Pre=NULL;
  1094.                 }
  1095.             }
  1096.             else if(Pre)
  1097.             {
  1098.                 if(Pre>Indirect)
  1099.                 {
  1100.                     Post=Pre;
  1101.                     Pre=NULL;
  1102.                 }
  1103.                 else if(Pre<Indirect)
  1104.                 {
  1105.                     Post=NULL;
  1106.                 }
  1107.             }
  1108.       else
  1109.       {
  1110.         Indirect = NULL;    /* Was a false alarm */
  1111.       }
  1112.         }
  1113.  
  1114.         do
  1115.         {
  1116.             Count=0;
  1117.             Found=0;
  1118.             Replaced=0;
  1119.             while((Count<MAXOPCODES) && (Codes[Count]) && (!Found))
  1120.             {
  1121.                 if(strcmp(Codes[Count]->Opcode,Second)==0)
  1122.                 {
  1123.                     if(Indirect)
  1124.                     {
  1125.                         Temp=strchr(Codes[Count]->Operand,*Indirect);
  1126.                         if(Temp!=NULL)
  1127.                         {
  1128.                             if(Pre)
  1129.                             {
  1130.                                 if(*(Temp-1)==*Pre)
  1131.                                 {
  1132.                                     Found=1;
  1133.                                 }
  1134.                             }
  1135.                             else if(Post)
  1136.                             {
  1137.                                 if(*(Temp+1)==*Post)
  1138.                                 {
  1139.                                     Found=1;
  1140.                                 }
  1141.                             }
  1142.                             else if(strchr(Third,*Temp))
  1143.                             {
  1144.                                 Found=1;
  1145.                             }
  1146.                         }
  1147.                     }
  1148.                     else
  1149.                     {
  1150.                         Found=1;
  1151.                     }
  1152.                 }
  1153.                 if(!Found)
  1154.                 {
  1155.                     Count++;
  1156.                 }
  1157.             }
  1158.             if(Found)
  1159.             {
  1160.                 if(*Codes[Count]->Flag=='A')
  1161.                 {
  1162.                     strcpy(Second,Codes[Count]->Flag+1);
  1163.                     strcpy(Repeat,Third);
  1164.                     strcat(Third,",");
  1165.                     strcat(Third,Repeat);
  1166.                     Replaced=1;
  1167.                 }
  1168.             }
  1169.         }while(Replaced);
  1170.  
  1171.         if(!Found)
  1172.         {
  1173.             if(!AsmDirective(Second))
  1174.             {
  1175.                 Error=NOTOP;
  1176.                 fclose(Outfile);
  1177.                 fclose(SRecord);
  1178.                 return 0;
  1179.             }
  1180.             else
  1181.             {
  1182.                 Tmp=FindDirective(Second);
  1183.                 if(Directives[Tmp]!=NULL)
  1184.                 {
  1185.                     /*It is!*/
  1186.                     switch(Tmp)
  1187.                     {
  1188.                         case D_CONSTB:
  1189.                                  if(Outfile)
  1190.                                  {
  1191.                                      fprintf(Outfile,"%ld\t",LineNumber);
  1192.                                      fprintf(Outfile,"%04X  ",PrintPC);
  1193.                                  }
  1194.                                  PutConstants(Outfile,SRecord,Third,&SRPC,1);
  1195.                                  if(Outfile)
  1196.                                  {
  1197.                                      fprintf(Outfile,"\t%s %s\n",OrigFirst,OrigSecond);
  1198.                                  }
  1199.                  PC=SRPC;
  1200.                                  PrintPC=SRPC>>1;
  1201.                  CodePC=PrintPC;
  1202.                                  break;
  1203.                         case D_CONSTW:
  1204.                                  if(Outfile)
  1205.                                  {
  1206.                                      fprintf(Outfile,"%ld\t",LineNumber);
  1207.                                      fprintf(Outfile,"%04X  ",PrintPC);
  1208.                                  }
  1209.                                  PutConstants(Outfile,SRecord,Third,&SRPC,2);
  1210.                                  if(Outfile)
  1211.                                  {
  1212.                                      fprintf(Outfile,"\t%s %s\n",OrigFirst,OrigSecond);
  1213.                                  }
  1214.                  PC=SRPC;
  1215.                                  PrintPC=SRPC>>1;
  1216.                  CodePC=PrintPC;
  1217.                                  break;
  1218.  
  1219.                         case D_ORG:
  1220.                                  FlushSRBuffer(SRecord,SRPC-1);
  1221.                                  PC=StrToInt(Third);
  1222.                                  PrintPC=PC;
  1223.                  CodePC=PC;
  1224.                                  SRPC=PC<<1;
  1225.                                  break;
  1226.                         case D_NEWFILE:
  1227.                                  PushFiles(Third,NULL);
  1228.                                  LineNumber=0;
  1229.                                  break;
  1230.                         case D_ENDNEW:
  1231.                                  PopFiles();
  1232.                  LineNumber++;
  1233.                                  break;
  1234.             case D_EQU:
  1235.                   Replace(Third);
  1236.                           Address=StrToInt(Third);
  1237.                           Flag='E';
  1238.                   if(IsInStack(First))
  1239.                         {
  1240.                             Error=REPEATLABEL;
  1241.                   }
  1242.                   if(AddLabel(First, Address, Flag, NULL)==NULL)
  1243.                         {
  1244.                     Error=MEM;
  1245.                   }
  1246.                   break;
  1247.                     }
  1248.                 }
  1249.             }
  1250.         }
  1251.         else
  1252.         {
  1253.             strcpy(Code,Codes[Count]->Code);
  1254.             strcpy(Map,Codes[Count]->Operand);
  1255.             OldPC=PC;
  1256.             PC+=CodeLength(Count);  /*Next address*/
  1257.       CodePC+=(PC-OldPC)>>1;
  1258.             CodeData=CreateCode(Code,Map,Third,Codes[Count]->Flag,CodePC);
  1259.             if(Outfile)
  1260.             {
  1261.                 fprintf(Outfile,"%ld\t",LineNumber);
  1262.                 fprintf(Outfile,"%04X  %04lX ",PrintPC,CodeData);
  1263.         PrintPC+=(PC-OldPC)>>1;
  1264.                 fprintf(Outfile,"\t%s %s\n",OrigFirst,OrigSecond);
  1265.             }
  1266.             if( (PC-OldPC)==4)
  1267.             {
  1268.                 PutSRBuffer(SRecord,CodeData>>16,SRPC);
  1269.                 PutSRBuffer(SRecord,(CodeData>>24)&255,SRPC+1);
  1270.         PutSRBuffer(SRecord,CodeData&255,SRPC+2);
  1271.               PutSRBuffer(SRecord,CodeData>>8,SRPC+3);
  1272.             }
  1273.       else
  1274.       {
  1275.         PutSRBuffer(SRecord,CodeData&255,SRPC);
  1276.               PutSRBuffer(SRecord,CodeData>>8,SRPC+1);
  1277.       }
  1278.       if(SRPC&1)
  1279.             {
  1280.                 Error=ALLIGNMENT;
  1281.             }
  1282.             SRPC+=(PC-OldPC);
  1283.         }
  1284.  
  1285.     }while( Error==0 );
  1286.     FinishSRecord(SRecord,SRPC);
  1287.     if(Outfile)
  1288.     {
  1289.         DumpLabels(Outfile);
  1290.         fclose(Outfile);
  1291.     }
  1292.     fclose(SRecord);
  1293.     return 1;
  1294. }
  1295.  
  1296. ULONG CreateCode(char *Code, char *Map, char *Operand, char *Flag,int PC)
  1297. {
  1298.     char Part[128], *Temp, MapPart[128], *MapTemp;
  1299.     int Count, Work, Steps, Step,Len;
  1300.     ULONG Result;
  1301.  
  1302.     if(strcmp(Map,"-")==0)
  1303.     {
  1304.         Result=BinToULong(Code);
  1305.         return Result;
  1306.     }
  1307.  
  1308.     memset(MapPart,0,128);
  1309.  
  1310.     Temp=Code;
  1311.     if(strchr(Map,',')!=NULL)
  1312.     {
  1313.         Steps=2;
  1314.     }
  1315.     else
  1316.     {
  1317.         Steps=1;
  1318.     }
  1319.  
  1320.     for(Step=0; Step<Steps; Step++)
  1321.     {
  1322.         Code=Temp;
  1323.         if (Validate(Code,"01"))
  1324.         {
  1325.             break;
  1326.         }
  1327.  
  1328.         Len=strlen(Code);
  1329.         Count=0;
  1330.         MapTemp=Map;
  1331.         while((*Operand) && (*Operand!=','))
  1332.         {
  1333.             Part[Count]=*Operand;
  1334.             MapPart[Count]=*Map;
  1335.             Count++;
  1336.             Operand++;
  1337.             Map++;
  1338.         }
  1339.         Part[Count]=0;
  1340.         MapPart[Count]=0;
  1341.         Map=MapTemp;
  1342.  
  1343.         if(*Map=='R')
  1344.         {
  1345.             if(Part[0]=='R')
  1346.             {
  1347.                 Work=StrToInt(&Part[1]);
  1348.                 if(*Flag=='S')
  1349.                 {
  1350.                     if(Work<16)
  1351.                     {
  1352.                         Error=REG16;
  1353.                         return 0;
  1354.                     }
  1355.                     Work-=16;
  1356.                 }
  1357.                 if(*Flag=='U')
  1358.                 {
  1359.                     if( (Work<24) || (Work&1) )
  1360.                     {
  1361.                         Error=UPPERREGS;
  1362.                         return 0;
  1363.                     }
  1364.                     Work=(Work>>1)&3;
  1365.                 }
  1366.                 Map++;
  1367.             }
  1368.             else
  1369.             {
  1370.                 Error=WRONGOP;
  1371.                 return 0;
  1372.             }
  1373.         }
  1374.         else if(*Map=='k')
  1375.         {
  1376.             if( (strchr(Operand,',')!=NULL) && (Steps==1) )
  1377.             {
  1378.                 Error=WRONGOP;
  1379.                 return 0;
  1380.             }
  1381.             Work=StrToInt(Part);
  1382.             if(*Flag=='R')
  1383.             {
  1384.                 Work=(Work-PC);
  1385.  
  1386.                 if((Work>63) || (Work<-64))
  1387.                 {
  1388.                     Error=RANGE;
  1389.                     return 0;
  1390.                 }
  1391.                 Work&=127;
  1392.             }
  1393.             else if(*Flag=='L')
  1394.             {
  1395.                 Work=(Work-PC);
  1396.                 Work&=4095;
  1397.             }
  1398.       else if(*Flag=='N')
  1399.             {
  1400.                 Work&=0xFFFF;
  1401.             }
  1402.         }
  1403.         else if(*Map=='K')
  1404.         {
  1405.             Work=StrToInt(Part);
  1406.         }
  1407.         else if(MapPart[2]=='q')
  1408.         {
  1409.             Work=StrToInt(&Part[2]);
  1410.             Map+=2;
  1411.         }
  1412.         else
  1413.         {
  1414.          if(!Validate(MapPart,"XYZ,+-"))
  1415.          {
  1416.              Work=StrToInt(Part);
  1417.          }
  1418.          else
  1419.          {
  1420.              Work=0;
  1421.          }
  1422.         }
  1423.  
  1424.         Code+=(Len-1);
  1425.         while(Len)
  1426.         {
  1427.             if( (*Code=='!') && (*(Code+1)!='K') )
  1428.             {
  1429.                 Code++;
  1430.                 if(*Code=='1')
  1431.                 {
  1432.                     *Code='0';
  1433.                 }
  1434.                 else
  1435.                 {
  1436.                     *Code='1';
  1437.                 }
  1438.                 Code--;
  1439.                 *Code=' ';
  1440.                 RemoveSpace(Code);
  1441.             }
  1442.             if(*Code==*Map)
  1443.             {
  1444.                 if(Work&1)
  1445.                 {
  1446.                     *Code='1';
  1447.                 }
  1448.                 else
  1449.                 {
  1450.                     *Code='0';
  1451.                 }
  1452.                 Work>>=1;
  1453.             }
  1454.  
  1455.             if(*Code=='X')     /*Don't care bit*/
  1456.             {
  1457.                 *Code='0';
  1458.             }
  1459.  
  1460.             Code--;
  1461.             Len--;
  1462.         }
  1463.         if(Work>0)          /*-ve numbers are ok!*/
  1464.         {
  1465.             Error=RANGE;
  1466.             return 0;
  1467.         }
  1468.         Operand++;
  1469.         while( (*Map) && (*Map!=',') )
  1470.         {
  1471.             Map++;
  1472.         }
  1473.         Map++;
  1474.     }
  1475.     Code=Temp;
  1476.     Result=BinToULong(Code);
  1477.     return Result;
  1478. }
  1479.  
  1480. ULONG BinToULong(char *Str)
  1481. {
  1482. /*Converts binary to ulong!*/
  1483.     int Len;
  1484.     ULONG Weight=1,Result=0;
  1485.  
  1486.     StripDontCare(Str);
  1487.     Len=strlen(Str);
  1488.     Str+=Len-1;
  1489.     while(Len)
  1490.     {
  1491.         if(Weight==0)
  1492.         {
  1493.             Error=RANGE;
  1494.             return 0;
  1495.         }
  1496.         if(*Str=='1')
  1497.         {
  1498.             Result|=Weight;
  1499.         }
  1500.         else if(*Str!='0')
  1501.         {
  1502.             Error=BADCODE;
  1503.             return 0;
  1504.         }
  1505.         Weight<<=1;
  1506.         Str--;
  1507.         Len--;
  1508.     }
  1509.     return Result;
  1510. }
  1511.  
  1512. int AsmDirective(char *Str)
  1513. {
  1514.     int Count=0;
  1515.  
  1516.     while(Directives[Count]!=NULL)
  1517.     {
  1518.         if(strcmp(Str,Directives[Count])==0)
  1519.         {
  1520.             return 1;
  1521.         }
  1522.         Count++;
  1523.     }
  1524.     return 0;
  1525. }
  1526.  
  1527. int PushFiles(char *Str, FILE *H)
  1528. {
  1529.     struct DStack *Temp;
  1530.  
  1531.     if(Files==NULL)
  1532.     {
  1533.         Files=(struct DStack*)malloc(sizeof(struct DStack));
  1534.         if(Files==NULL)
  1535.         {
  1536.             Error=MEM;
  1537.             return 0;
  1538.         }
  1539.         Files->Last=NULL;
  1540.         Files->Data=(char*)malloc(strlen(Str)+1);
  1541.         if(Files->Data==NULL)
  1542.         {
  1543.             Error=MEM;
  1544.             return 0;
  1545.         }
  1546.         Files->Line=LineNumber;
  1547.         Files->Handle=H;
  1548.         strcpy(Files->Data,Str);
  1549.     }
  1550.     else
  1551.     {
  1552.         Temp=Files;
  1553.         Files=(struct DStack*)malloc(sizeof(struct DStack));
  1554.         if(Files==NULL)
  1555.         {
  1556.             Error=MEM;
  1557.             Files=Temp;
  1558.             return 0;
  1559.         }
  1560.         Files->Last=Temp;
  1561.         Files->Data=(char*)malloc(strlen(Str)+1);
  1562.         if(Files->Data==NULL)
  1563.         {
  1564.             Error=MEM;
  1565.             return 0;
  1566.         }
  1567.         strcpy(Files->Data,Str);
  1568.         Files->Line=LineNumber;
  1569.         Files->Handle=H;
  1570.     }
  1571.     return 1;
  1572. }
  1573.  
  1574. FILE *PopFiles(void)
  1575. {
  1576.     struct DStack *Temp;
  1577.     FILE *TempFile;
  1578.  
  1579.     if(Files)
  1580.     {
  1581.         if(Files->Data!=NULL)
  1582.         {
  1583.             free(Files->Data);
  1584.             Files->Data=NULL;
  1585.         }
  1586.         LineNumber=Files->Line;
  1587.         TempFile=Files->Handle;
  1588.         Temp=Files->Last;
  1589.         free(Files);
  1590.         Files=Temp;
  1591.         return TempFile;
  1592.     }
  1593.     return NULL;
  1594. }
  1595.  
  1596. int StartSRecord(FILE *File, char *Name)
  1597. {
  1598.     int Checksum, Temp;
  1599.     char *Orig;
  1600.  
  1601.     Orig=Name;
  1602.     fprintf(File,"S0");
  1603.     Temp=0;
  1604.     while( (*Name) && (*Name!='.') )
  1605.     {
  1606.         Temp++;
  1607.         Name++;
  1608.     }
  1609.     Name=Orig;
  1610.     Temp+=3;      /*+address +checksum*/
  1611.     Checksum=Temp;
  1612.     fprintf(File,"%02X",Temp);
  1613.     fprintf(File,"0000");
  1614.     while( (*Name) && (*Name!='.') )
  1615.     {
  1616.         fprintf(File,"%02X",*Name);
  1617.         Checksum+=*Name;
  1618.         Name++;
  1619.     }
  1620.     Checksum=~Checksum;
  1621.     fprintf(File,"%02X\n",(Checksum&255));
  1622.     SROffset=0;
  1623.     return 1;
  1624. }
  1625.  
  1626. int PutSRBuffer(FILE *File, BYTE Data, int PC)
  1627. {
  1628.   SRIn++;
  1629.  
  1630.     SRBuffer[SROffset]=Data;
  1631.     SROffset++;
  1632.     if(SROffset==MAX_SR_LINE)
  1633.     {
  1634.         FlushSRBuffer(File,PC);
  1635.     }
  1636.     return 1;
  1637. }
  1638.  
  1639. int FlushSRBuffer(FILE *Outfile,int PC)
  1640. {
  1641.     int C,Count;
  1642.     int Checksum;
  1643.  
  1644.     Count=SROffset;
  1645.     if(Count==0)
  1646.     {
  1647.         return 1;
  1648.     }
  1649.     fprintf(Outfile,"S1");
  1650.     fprintf(Outfile,"%02X",Count+3);  /*+3 for checksum and address*/
  1651.     Checksum=Count+3;
  1652.     fprintf(Outfile,"%04X",PC-Count+1);
  1653.     Checksum+=((PC-Count+1)>>8);
  1654.     Checksum+=((PC-Count+1)&255);
  1655.     for(C=0; C<Count; C++)
  1656.     {
  1657.         fprintf(Outfile,"%02X",SRBuffer[C]);
  1658.         Checksum+=SRBuffer[C];
  1659.     }
  1660.     Checksum=~Checksum;
  1661.     fprintf(Outfile,"%02X\n",(Checksum&255));
  1662.     SROffset=0;
  1663.     return 1;
  1664. }
  1665.  
  1666. int FinishSRecord(FILE *F,int PC)
  1667. {
  1668.      FlushSRBuffer(F,PC);
  1669.      fprintf(F,"S9030000FC\n");
  1670.      return 1;
  1671. }
  1672.  
  1673. int ConstantLength(char *S, BYTE Size)
  1674. {
  1675.     char Work[128];
  1676.     int Os,Result=0;
  1677.  
  1678.     do
  1679.     {
  1680.     Os=0;
  1681.         while((*S) && (*S!=','))
  1682.         {
  1683.             Work[Os]=*S;
  1684.             Os++;
  1685.             if(Os==128)
  1686.             {
  1687.                 Os--;
  1688.             }
  1689.             S++;
  1690.         }
  1691.         Work[Os]=0;
  1692.         if(*S==',')
  1693.         {
  1694.             S++;
  1695.         }
  1696.         Os=0;
  1697.         if(Work[Os]=='"')
  1698.         {
  1699.             Os++;
  1700.             while((Work[Os]!='"') && (Work[Os]))
  1701.             {
  1702.                 Result+=Size;  /*Do we want word long chars? !!!!*/
  1703.                 Os++;
  1704.             }
  1705.             /* Result+=Size; */   /*For the NULL, Dont put a null*/
  1706.         }
  1707.         else
  1708.         {
  1709.             Result+=Size;
  1710.         }
  1711.     }while(*S);
  1712.  
  1713.     return Result;
  1714. }
  1715.  
  1716. int PutConstants(FILE *List,FILE *Out,char *S,int *PC, BYTE Size)
  1717. {
  1718.     char Work[128];
  1719.     unsigned int Temp;
  1720.     int Os, Width=0;
  1721.  
  1722.     do
  1723.   {
  1724.       if(*S==',')
  1725.       {
  1726.            S++;
  1727.       }
  1728.  
  1729.         if( (*S=='"') && (Size==1) )
  1730.         {
  1731.       S++;
  1732.             while( (*S!='"') && (*S) )
  1733.             {
  1734.                 PutSRBuffer(Out,(BYTE)*S,*PC);
  1735.                 if(List)
  1736.                 {
  1737.                     fprintf(List,"%02X",*S);
  1738.           Width++;
  1739.           if(Width==2)
  1740.           {
  1741.             Width=0;
  1742.             fprintf(List,"\n              ");
  1743.           }
  1744.                 }
  1745.                 *PC=*PC+1;
  1746.                 S++;
  1747.             }
  1748.       if(*S)
  1749.       {
  1750.         S++;
  1751.       }
  1752.       /*  Dont stuff in a null !!! */
  1753.         }
  1754.         else if(*S)
  1755.         {
  1756.       Os=0;
  1757.           while((*S) && (*S!=','))
  1758.           {
  1759.               Work[Os]=*S;
  1760.               Os++;
  1761.               if(Os==127)
  1762.               {
  1763.                   Os--;
  1764.               }
  1765.               S++;
  1766.           }
  1767.       if(*S)
  1768.       {
  1769.         S++;
  1770.       }
  1771.       Work[Os]=0;
  1772.             Temp=StrToInt(Work);
  1773.             if(List)
  1774.             {
  1775.                 fprintf(List,"%02X",Temp&255);
  1776.         Width++;
  1777.         if(Width==2)
  1778.         {
  1779.           Width=0;
  1780.           fprintf(List,"\n              ");
  1781.         }
  1782.             }
  1783.             PutSRBuffer(Out,Temp&255,*PC);
  1784.             *PC=*PC+1;
  1785.             if(Size==2)
  1786.             {
  1787.                 if(List)
  1788.                 {
  1789.                     fprintf(List,"%02X",Temp>>8);
  1790.           Width++;
  1791.           if(Width==2)
  1792.           {
  1793.             Width=0;
  1794.             fprintf(List,"\n              ");
  1795.           }
  1796.                 }
  1797.                 PutSRBuffer(Out,Temp>>8,*PC);
  1798.                 *PC=*PC+1;
  1799.             }
  1800.         }
  1801.     }while(*S);
  1802.     return 1;
  1803. }
  1804.  
  1805. void DumpLabels(FILE *List)
  1806. {
  1807.     struct Labels *Tmp;
  1808.   fprintf(List,"\n\n");
  1809.  
  1810.   Tmp = LabelStack;
  1811.     while(Tmp)
  1812.     {
  1813.         if(Tmp->Label!=NULL)
  1814.         {
  1815.       if(Tmp->Flag=='E')
  1816.       {
  1817.               fprintf(List,"%s\t\t$%04X\tE\n",Tmp->Label,Tmp->Address);
  1818.       }
  1819.       else if(Tmp->Flag == 'M')
  1820.       {
  1821.         fprintf(List,"%s\t\t%s\tM\n",Tmp->Label,Tmp->Macro);
  1822.       }
  1823.       else
  1824.       {
  1825.         fprintf(List,"%s\t\t$%04X\tL\n",Tmp->Label,Tmp->Address);
  1826.       }
  1827.         }
  1828.     Tmp = Tmp->Last;
  1829.     }
  1830. }
  1831.  
  1832.