/[projet1]/public/pc/tools/osdk/main/bas2tap/sources/bas2tap.cpp
Defence Force logotype

Diff of /public/pc/tools/osdk/main/bas2tap/sources/bas2tap.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1118 by dbug, Sat Jan 21 22:33:21 2012 UTC revision 1119 by dbug, Sun Mar 16 15:52:34 2014 UTC
# Line 8  Line 8 
8  #include <conio.h>  #include <conio.h>
9  #include <string.h>  #include <string.h>
10    
11    //
12    // Things to do:
13    // - Handle auto-numeration and labels
14    // - Option to optimize the programs (truncate variables to two characters, remove comments)
15    //
16    
17  char *keywords[]=  char *keywords[]=
18  {  {
19          "END","EDIT","STORE","RECALL","TRON","TROFF","POP","PLOT",    "END","EDIT","STORE","RECALL","TRON","TROFF","POP","PLOT",
20          "PULL","LORES","DOKE","REPEAT","UNTIL","FOR","LLIST","LPRINT","NEXT","DATA",    "PULL","LORES","DOKE","REPEAT","UNTIL","FOR","LLIST","LPRINT","NEXT","DATA",
21          "INPUT","DIM","CLS","READ","LET","GOTO","RUN","IF","RESTORE","GOSUB","RETURN",    "INPUT","DIM","CLS","READ","LET","GOTO","RUN","IF","RESTORE","GOSUB","RETURN",
22          "REM","HIMEM","GRAB","RELEASE","TEXT","HIRES","SHOOT","EXPLODE","ZAP","PING",    "REM","HIMEM","GRAB","RELEASE","TEXT","HIRES","SHOOT","EXPLODE","ZAP","PING",
23          "SOUND","MUSIC","PLAY","CURSET","CURMOV","DRAW","CIRCLE","PATTERN","FILL",    "SOUND","MUSIC","PLAY","CURSET","CURMOV","DRAW","CIRCLE","PATTERN","FILL",
24          "CHAR","PAPER","INK","STOP","ON","WAIT","CLOAD","CSAVE","DEF","POKE","PRINT",    "CHAR","PAPER","INK","STOP","ON","WAIT","CLOAD","CSAVE","DEF","POKE","PRINT",
25          "CONT","LIST","CLEAR","GET","CALL","!","NEW","TAB(","TO","FN","SPC(","@",    "CONT","LIST","CLEAR","GET","CALL","!","NEW","TAB(","TO","FN","SPC(","@",
26          "AUTO","ELSE","THEN","NOT","STEP","+","-","*","/","^","AND","OR",">","=","<",    "AUTO","ELSE","THEN","NOT","STEP","+","-","*","/","^","AND","OR",">","=","<",
27          "SGN","INT","ABS","USR","FRE","POS","HEX$","&","SQR","RND","LN","EXP","COS",    "SGN","INT","ABS","USR","FRE","POS","HEX$","&","SQR","RND","LN","EXP","COS",
28          "SIN","TAN","ATN","PEEK","DEEK","LOG","LEN","STR$","VAL","ASC","CHR$","PI",    "SIN","TAN","ATN","PEEK","DEEK","LOG","LEN","STR$","VAL","ASC","CHR$","PI",
29          "TRUE","FALSE","KEY$","SCRN","POINT","LEFT$","RIGHT$","MID$"    "TRUE","FALSE","KEY$","SCRN","POINT","LEFT$","RIGHT$","MID$"
30  };  };
31    
32  unsigned char head[14]={ 0x16,0x16,0x16,0x24,0,0,0,0,0,0,5,1,0,0 };  unsigned char head[14]={ 0x16,0x16,0x16,0x24,0,0,0,0,0,0,5,1,0,0 };
# Line 32  unsigned char head[14]={ 0x16,0x16,0x16, Line 36  unsigned char head[14]={ 0x16,0x16,0x16,
36    
37  void Tap2Bas(unsigned char *ptr_buffer,size_t file_size)  void Tap2Bas(unsigned char *ptr_buffer,size_t file_size)
38  {  {
39          unsigned int i, car;    unsigned int i, car;
40    
41          if (ptr_buffer[0]!=0x16 || ptr_buffer[3]!=0x24)    if (ptr_buffer[0]!=0x16 || ptr_buffer[3]!=0x24)
42          {    {
43                  ShowError("Not an Oric file");      ShowError("Not an Oric file");
44          }    }
45          if (ptr_buffer[6])    if (ptr_buffer[6])
46          {    {
47                  ShowError("Not a BASIC file");      ShowError("Not a BASIC file");
48          }    }
49          i=13;    i=13;
50          while (ptr_buffer[i++]);    while (ptr_buffer[i++]);
51          while (ptr_buffer[i] || ptr_buffer[i+1])    while (ptr_buffer[i] || ptr_buffer[i+1])
52          {    {
53                  i+=2;      i+=2;
54                  printf(" %u ",ptr_buffer[i]+(ptr_buffer[i+1]<<8));      printf(" %u ",ptr_buffer[i]+(ptr_buffer[i+1]<<8));
55                  i+=2;      i+=2;
56                  while (car=ptr_buffer[i++])      while (car=ptr_buffer[i++])
57                  {      {
58                          if (car<128)        if (car<128)
59                                  putchar(car);          putchar(car);
60                          else        else
61                                  printf("%s",keywords[car-128]);          printf("%s",keywords[car-128]);
62                  }      }
63                  putchar('\n');      putchar('\n');
64          }    }
65  }  }
66    
67    
# Line 65  void Tap2Bas(unsigned char *ptr_buffer,s Line 69  void Tap2Bas(unsigned char *ptr_buffer,s
69  // tap2bas  // tap2bas
70  int search_keyword(const char *str)  int search_keyword(const char *str)
71  {  {
72          int i;    for (int i=0;i<sizeof(keywords)/sizeof(char *);i++)
73          for (i=0;i<sizeof(keywords)/sizeof(char *);i++)    {
74          {      if (strncmp(keywords[i],str,strlen(keywords[i]))==0)
75                  if (strncmp(keywords[i],str,strlen(keywords[i]))==0)      {
76                  {        return i;
77                          return i;      }
78                  }    }
79          }    return -1;
         return -1;  
80  }  }
81    
82    
83    
84  void Bas2Tap(const char *pSourceFile,const char *pDestFile,bool bAutoRun,bool bUseColor)  void Bas2Tap(const char *sourceFile,const char *destFile,bool autoRun,bool useColor)
85  {  {
86          unsigned char buf[48192];    unsigned char buf[48192];
87          unsigned int end, lastptr, adr;    unsigned int end, lastptr, adr;
88          int j,ptr,keyw,string,rem,data;    int j,ptr,keyw,string,rem,data;
89    
90          // Mike: Need to improve the parsing of this with a global function to split    // Mike: Need to improve the parsing of this with a global function to split
91          // a text file in separate lines.    // a text file in separate lines.
92          std::vector<std::string> cTextData;    std::vector<std::string> textData;
93          if (!LoadText(pSourceFile,cTextData))    if (!LoadText(sourceFile,textData))
94          {    {
95                  ShowError("Unable to load source file");      ShowError("Unable to load source file");
96          }    }
97    
98          std::string cCurrentFile=pSourceFile;    std::string currentFile=sourceFile;
99          int nCurrentLine=0;    int currentLineNumber=0;
100          int i=0;    int i=0;
101          std::vector<std::string>::const_iterator cIt=cTextData.begin();    std::vector<std::string>::const_iterator lineIt=textData.begin();
102          while (cIt!=cTextData.end())    while (lineIt!=textData.end())
103          {    {
104                  const std::string& cCurrentLine=*cIt;      const std::string& currentLine=*lineIt;
105    
106                  ++nCurrentLine;      ++currentLineNumber;
107    
108                  if (!cCurrentLine.empty())      if (!currentLine.empty())
109                  {      {
110                          const char* ligne=cCurrentLine.c_str();        const char* ligne=currentLine.c_str();
111                          if (ligne[0]=='#')        if (ligne[0]=='#')
112                          {        {
113                                  // Preprocessor directive          // Preprocessor directive
114                                  if (memicmp(ligne,"#file",5)==0)          if (memicmp(ligne,"#file",5)==0)
115                                  {          {
116                                          //"#file font.BAS""            //"#file font.BAS""
117                                          // Very approximative "get the name of the file and reset the line counter" code.            // Very approximative "get the name of the file and reset the line counter" code.
118                                          // Will clean up that when I will have some more time.            // Will clean up that when I will have some more time.
119                                          ligne+=5;            ligne+=5;
120                                          cCurrentFile=ligne;            currentFile=ligne;
121                                          nCurrentLine=0;            currentLineNumber=0;
122                                  }          }
123                                  else          else
124                                  {          {
125                                          std::string cErrorMessage=StringFormat("Unknown preprocessor directive in file %s line number line %d",cCurrentFile.c_str(),nCurrentLine);            ShowError("Unknown preprocessor directive in file %s line number line %d",currentFile.c_str(),currentLineNumber);
126                                          ShowError(cErrorMessage.c_str());          }
127                                  }        }
128                          }        else
129                          else        {
130                          {          // Standard line
131                                  // Standard line          buf[i++]=0;
132                                  buf[i++]=0;          buf[i++]=0;
133                                  buf[i++]=0;  
134            int number=get_value(ligne,-1);
135                                  int number=get_value(ligne,-1);          if (number<0)
136                                  if (number<0)          {
137                                  {            // Mike: Need to add better diagnostic here
138                                          // Mike: Need to add better diagnostic here            ShowError("Missing line number in file %s line %d",currentFile.c_str(),currentLineNumber);
139                                          std::string cErrorMessage=StringFormat("Missing line number in file %s line %d",cCurrentFile.c_str(),nCurrentLine);            break;
140                                          ShowError(cErrorMessage.c_str());          }
141                                          break;          buf[i++]=number&0xFF;
142                                  }          buf[i++]=number>>8;
143                                  buf[i++]=number&0xFF;  
144                                  buf[i++]=number>>8;          ptr=0;
145            rem=0;
146                                  ptr=0;          bool color=useColor;
147                                  rem=0;          string=0;
148                                  bool bColor=bUseColor;          data=0;
149                                  string=0;          if (ligne[ptr]==' ') ptr++;
150                                  data=0;  
151                                  if (ligne[ptr]==' ') ptr++;          while (ligne[ptr])
152            {
153                                  while (ligne[ptr])            if (rem)
154                                  {            {
155                                          if (rem)              if (color)
156                                          {              {
157                                                  if (bColor)                color=false;
158                                                  {                buf[i++]=27;      // ESCAPE
159                                                          bColor=false;                buf[i++]='B';     // GREEN labels
160                                                          buf[i++]=27;    // ESCAPE              }
161                                                          buf[i++]='B';   // GREEN labels              buf[i++]=ligne[ptr++];
162                                                  }            }
163                                                  buf[i++]=ligne[ptr++];            else
164                                          }            if (string)
165                                          else            {
166                                          if (string)              if (ligne[ptr]=='"') string=0;
167                                          {              buf[i++]=ligne[ptr++];
168                                                  if (ligne[ptr]=='"') string=0;            }
169                                                  buf[i++]=ligne[ptr++];            else
170                                          }            if (data)
171                                          else            {
172                                          if (data)              if (ligne[ptr]==':') data=0;
173                                          {              buf[i++]=ligne[ptr++];
174                                                  if (ligne[ptr]==':') data=0;            }
175                                                  buf[i++]=ligne[ptr++];            else
176                                          }            {
177                                          else              const char* pLine=(ligne+ptr);
178                                          {              keyw=search_keyword(pLine);
179                                                  const char* pLine=(ligne+ptr);              if (keyw==29 || ligne[ptr]=='\'') rem=1;
180                                                  keyw=search_keyword(pLine);              if (keyw==17) data=1;
181                                                  if (keyw==29 || ligne[ptr]=='\'') rem=1;              if (ligne[ptr]=='"') string=1;
182                                                  if (keyw==17) data=1;              if (keyw>=0)
183                                                  if (ligne[ptr]=='"') string=1;              {
184                                                  if (keyw>=0)                buf[i++]=keyw+128;
185                                                  {                ptr+=strlen(keywords[keyw]);
186                                                          buf[i++]=keyw+128;              }
187                                                          ptr+=strlen(keywords[keyw]);              else
188                                                  }              {
189                                                  else                buf[i++]=ligne[ptr++];
190                                                  {              }
191                                                          buf[i++]=ligne[ptr++];            }
192                                                  }          }
193                                          }          buf[i++]=0;
194                                  }        }
195                                  buf[i++]=0;      }
196                          }      ++lineIt;
197                  }    }
198                  ++cIt;    buf[i++]=0;
199          }    buf[i++]=0;
200          buf[i++]=0;  
201          buf[i++]=0;    //following line modified by Wilfrid AVRILLON (Waskol) 06/20/2009
202      //It should follow this rule of computation : End_Address=Start_Address+File_Size-1
203          //following line modified by Wilfrid AVRILLON (Waskol) 06/20/2009    //Let's assume a 1 byte program, it starts at address #501 and ends at address #501 (Address=Address+1-1) !
204          //It should follow this rule of computation : End_Address=Start_Address+File_Size-1    //It was a blocking issue for various utilities (tap2wav for instance)
205          //Let's assume a 1 byte program, it starts at address #501 and ends at address #501 (Address=Address+1-1) !    //end=0x501+i-1;              //end=0x501+i;
206          //It was a blocking issue for various utilities (tap2wav for instance)    end=0x501+i;
207          //end=0x501+i-1;                //end=0x501+i;  
208          end=0x501+i;    if (autoRun)  head[7]=0x80;   // Autorun for basic :)
209      else          head[7]=0;
210          if (bAutoRun)   head[7]=0x80;   // Autorun for basic :)  
211          else                    head[7]=0;    head[8]=end>>8;
212      head[9]=end&0xFF;
213          head[8]=end>>8;  
214          head[9]=end&0xFF;    for(j=4,lastptr=0;j<i;j++)
215      {
216          for(j=4,lastptr=0;j<i;j++)      if (buf[j]==0)
217          {      {
218                  if (buf[j]==0)        adr=0x501+j+1;
219                  {        buf[lastptr]=adr&0xFF;
220                          adr=0x501+j+1;        buf[lastptr+1]=adr>>8;
221                          buf[lastptr]=adr&0xFF;        lastptr=j+1;
222                          buf[lastptr+1]=adr>>8;        j+=4;
223                          lastptr=j+1;      }
224                          j+=4;    }
225                  }  
226          }    //
227                      // Save file
228          //    //
229          // Save file    FILE *out=fopen(destFile,"wb");
230          //    if (out==NULL)
231          FILE *out=fopen(pDestFile,"wb");    {
232          if (out==NULL)      printf("Can't open file for writing\n");
233          {      exit(1);
234                  printf("Can't open file for writing\n");    }
235                  exit(1);    fwrite(head,1,14,out);
236          }    fwrite(buf,1,i+1,out);
237          fwrite(head,1,14,out);    fclose(out);
         fwrite(buf,1,i,out);  
         fclose(out);  
238  }  }
239    
240    
# Line 243  void Bas2Tap(const char *pSourceFile,con Line 244  void Bas2Tap(const char *pSourceFile,con
244    
245  void main(int argc, char **argv)  void main(int argc, char **argv)
246  {  {
247          //    //
248          // Some initialization for the common library    // Some initialization for the common library
249          //    //
250          SetApplicationParameters(    SetApplicationParameters(
251                  "Bas2Tap",      "Bas2Tap",
252                  TOOL_VERSION_MAJOR,      TOOL_VERSION_MAJOR,
253                  TOOL_VERSION_MINOR,      TOOL_VERSION_MINOR,
254                  "{ApplicationName} - Version {ApplicationVersion} - This program is a part of the OSDK\r\n"      "{ApplicationName} - Version {ApplicationVersion} - This program is a part of the OSDK\r\n"
255                  "\r\n"      "\r\n"
256                  "Author:\r\n"      "Author:\r\n"
257                  "  Fabrice Frances \r\n"      "  Fabrice Frances \r\n"
258                  "\r\n"      "\r\n"
259                  "Purpose:\r\n"      "Purpose:\r\n"
260                  "  Converting a text file containing a BASIC source code to a binary\r\n"      "  Converting a text file containing a BASIC source code to a binary\r\n"
261                  "  encoded TAPE file that can be loaded using the CLOAD command.\r\n"      "  encoded TAPE file that can be loaded using the CLOAD command.\r\n"
262                  "  (and the opposite operation as well).\r\n"      "  (and the opposite operation as well).\r\n"
263                  "\r\n"      "\r\n"
264                  "Parameters:\r\n"      "Parameters:\r\n"
265                  "  <options> <sourcefile> <destinationfile>\r\n"      "  <options> <sourcefile> <destinationfile>\r\n"
266                  "\r\n"      "\r\n"
267                  "Options:\r\n"      "Options:\r\n"
268                  "  -b2t[0|1] for converting to tape format with autorun (1) or not (0)\r\n"      "  -b2t[0|1] for converting to tape format with autorun (1) or not (0)\r\n"
269                  "  -t2b for converting from tape format text\r\n"      "  -t2b for converting from tape format text\r\n"
270                  "  -color[0|1] for enabling colored comments"      "  -color[0|1] for enabling colored comments"
271                  "\r\n"      "\r\n"
272                  "Exemple:\r\n"      "Exemple:\r\n"
273                  "  {ApplicationName} -b2t1 final.txt osdk.tap\r\n"      "  {ApplicationName} -b2t1 final.txt osdk.tap\r\n"
274                  "  {ApplicationName} -t2b osdk.tap program.txt\r\n"      "  {ApplicationName} -t2b osdk.tap program.txt\r\n"
275                  );      );
276    
277          bool bBasicToTape=true;    bool basicToTape=true;
278          bool bAutoRun=true;        bool autoRun=true;    
279          bool bUseColor=false;    bool useColor=false;
280    
281          ArgumentParser cArgumentParser(argc,argv);    ArgumentParser argumentParser(argc,argv);
282    
283          while (cArgumentParser.ProcessNextArgument())    while (argumentParser.ProcessNextArgument())
284          {    {
285                  if (cArgumentParser.IsSwitch("-t2b"))      if (argumentParser.IsSwitch("-t2b"))
                 {  
                         // Tape to BASIC source code  
                         bBasicToTape=false;  
                 }  
                 else  
                 if (cArgumentParser.IsSwitch("-b2t"))  
                 {  
                         // BASIC source code to tape  
                         bBasicToTape=true;  
                         bAutoRun=cArgumentParser.GetBooleanValue(true);  
                 }  
                 else  
                 if (cArgumentParser.IsSwitch("-color"))  
                 {  
                         // Handling of color codes  
                         bUseColor=cArgumentParser.GetBooleanValue(false);  
                 }  
         }  
   
     if (cArgumentParser.GetParameterCount()!=NB_ARG)  
286      {      {
287                  ShowError(0);        // Tape to BASIC source code
288          basicToTape=false;
289      }      }
290                                          else
291        if (argumentParser.IsSwitch("-b2t"))
292          std::string NameSrc(cArgumentParser.GetParameter(0));      {
293          std::string NameDst(cArgumentParser.GetParameter(1));        // BASIC source code to tape
294          basicToTape=true;
295          autoRun=argumentParser.GetBooleanValue(true);
296        }
297        else
298        if (argumentParser.IsSwitch("-color"))
299        {
300          // Handling of color codes
301          useColor=argumentParser.GetBooleanValue(false);
302        }
303      }
304    
305          if (bBasicToTape)    if (argumentParser.GetParameterCount()!=NB_ARG)
306          {    {
307                  Bas2Tap(NameSrc.c_str(),NameDst.c_str(),bAutoRun,bUseColor);      ShowError(0);
308          }    }
309          else  
310          {  
311                  // Load the source file    std::string nameSrc(argumentParser.GetParameter(0));
312                  void* ptr_buffer_void;    std::string nameDst(argumentParser.GetParameter(1));
313                  size_t file_size;  
314                  if (!LoadFile(NameSrc.c_str(),ptr_buffer_void,file_size))    if (basicToTape)
315                  {    {
316                          ShowError("Unable to load the source file");      Bas2Tap(nameSrc.c_str(),nameDst.c_str(),autoRun,useColor);
317                  }    }
318                  unsigned char *ptr_buffer=(unsigned char*)ptr_buffer_void;    else
319      {
320        // Load the source file
321        void* ptr_buffer_void;
322        size_t file_size;
323        if (!LoadFile(nameSrc.c_str(),ptr_buffer_void,file_size))
324        {
325          ShowError("Unable to load the source file");
326        }
327        unsigned char *ptr_buffer=(unsigned char*)ptr_buffer_void;
328    
329                  Tap2Bas(ptr_buffer,file_size);      Tap2Bas(ptr_buffer,file_size);
330          }    }
331    
332          exit(0);    exit(0);
333  }  }

Legend:
Removed from v.1118  
changed lines
  Added in v.1119

  ViewVC Help
Powered by ViewVC 1.1.26