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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 106 - (hide annotations)
Sat Jun 20 13:55:24 2009 UTC (10 years, 8 months ago) by waskol
File size: 7716 byte(s)


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

  ViewVC Help
Powered by ViewVC 1.1.26