/[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 1119 - (hide annotations)
Sun Mar 16 15:52:34 2014 UTC (5 years, 7 months ago) by dbug
File size: 8465 byte(s)
Updated Bas2Tap to fix a loading bug
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 dbug 1119 //
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 dbug 70
17     char *keywords[]=
18     {
19 dbug 1119 "END","EDIT","STORE","RECALL","TRON","TROFF","POP","PLOT",
20     "PULL","LORES","DOKE","REPEAT","UNTIL","FOR","LLIST","LPRINT","NEXT","DATA",
21     "INPUT","DIM","CLS","READ","LET","GOTO","RUN","IF","RESTORE","GOSUB","RETURN",
22     "REM","HIMEM","GRAB","RELEASE","TEXT","HIRES","SHOOT","EXPLODE","ZAP","PING",
23     "SOUND","MUSIC","PLAY","CURSET","CURMOV","DRAW","CIRCLE","PATTERN","FILL",
24     "CHAR","PAPER","INK","STOP","ON","WAIT","CLOAD","CSAVE","DEF","POKE","PRINT",
25     "CONT","LIST","CLEAR","GET","CALL","!","NEW","TAB(","TO","FN","SPC(","@",
26     "AUTO","ELSE","THEN","NOT","STEP","+","-","*","/","^","AND","OR",">","=","<",
27     "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",
29     "TRUE","FALSE","KEY$","SCRN","POINT","LEFT$","RIGHT$","MID$"
30 dbug 70 };
31    
32     unsigned char head[14]={ 0x16,0x16,0x16,0x24,0,0,0,0,0,0,5,1,0,0 };
33    
34    
35    
36    
37     void Tap2Bas(unsigned char *ptr_buffer,size_t file_size)
38     {
39 dbug 1119 unsigned int i, car;
40 dbug 70
41 dbug 1119 if (ptr_buffer[0]!=0x16 || ptr_buffer[3]!=0x24)
42     {
43     ShowError("Not an Oric file");
44     }
45     if (ptr_buffer[6])
46     {
47     ShowError("Not a BASIC file");
48     }
49     i=13;
50     while (ptr_buffer[i++]);
51     while (ptr_buffer[i] || ptr_buffer[i+1])
52     {
53     i+=2;
54     printf(" %u ",ptr_buffer[i]+(ptr_buffer[i+1]<<8));
55     i+=2;
56     while (car=ptr_buffer[i++])
57     {
58     if (car<128)
59     putchar(car);
60     else
61     printf("%s",keywords[car-128]);
62     }
63     putchar('\n');
64     }
65 dbug 70 }
66    
67    
68    
69     // tap2bas
70     int search_keyword(const char *str)
71     {
72 dbug 1119 for (int i=0;i<sizeof(keywords)/sizeof(char *);i++)
73     {
74     if (strncmp(keywords[i],str,strlen(keywords[i]))==0)
75     {
76     return i;
77     }
78     }
79     return -1;
80 dbug 70 }
81    
82    
83    
84 dbug 1119 void Bas2Tap(const char *sourceFile,const char *destFile,bool autoRun,bool useColor)
85 dbug 70 {
86 dbug 1119 unsigned char buf[48192];
87     unsigned int end, lastptr, adr;
88     int j,ptr,keyw,string,rem,data;
89 dbug 70
90 dbug 1119 // Mike: Need to improve the parsing of this with a global function to split
91     // a text file in separate lines.
92     std::vector<std::string> textData;
93     if (!LoadText(sourceFile,textData))
94     {
95     ShowError("Unable to load source file");
96     }
97 dbug 70
98 dbug 1119 std::string currentFile=sourceFile;
99     int currentLineNumber=0;
100     int i=0;
101     std::vector<std::string>::const_iterator lineIt=textData.begin();
102     while (lineIt!=textData.end())
103     {
104     const std::string& currentLine=*lineIt;
105 dbug 70
106 dbug 1119 ++currentLineNumber;
107 dbug 70
108 dbug 1119 if (!currentLine.empty())
109     {
110     const char* ligne=currentLine.c_str();
111     if (ligne[0]=='#')
112     {
113     // Preprocessor directive
114     if (memicmp(ligne,"#file",5)==0)
115     {
116     //"#file font.BAS""
117     // 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.
119     ligne+=5;
120     currentFile=ligne;
121     currentLineNumber=0;
122     }
123     else
124     {
125     ShowError("Unknown preprocessor directive in file %s line number line %d",currentFile.c_str(),currentLineNumber);
126     }
127     }
128     else
129     {
130     // Standard line
131     buf[i++]=0;
132     buf[i++]=0;
133 dbug 70
134 dbug 1119 int number=get_value(ligne,-1);
135     if (number<0)
136     {
137     // Mike: Need to add better diagnostic here
138     ShowError("Missing line number in file %s line %d",currentFile.c_str(),currentLineNumber);
139     break;
140     }
141     buf[i++]=number&0xFF;
142     buf[i++]=number>>8;
143 dbug 70
144 dbug 1119 ptr=0;
145     rem=0;
146     bool color=useColor;
147     string=0;
148     data=0;
149     if (ligne[ptr]==' ') ptr++;
150 dbug 70
151 dbug 1119 while (ligne[ptr])
152     {
153     if (rem)
154     {
155     if (color)
156     {
157     color=false;
158     buf[i++]=27; // ESCAPE
159     buf[i++]='B'; // GREEN labels
160     }
161     buf[i++]=ligne[ptr++];
162     }
163     else
164     if (string)
165     {
166     if (ligne[ptr]=='"') string=0;
167     buf[i++]=ligne[ptr++];
168     }
169     else
170     if (data)
171     {
172     if (ligne[ptr]==':') data=0;
173     buf[i++]=ligne[ptr++];
174     }
175     else
176     {
177     const char* pLine=(ligne+ptr);
178     keyw=search_keyword(pLine);
179     if (keyw==29 || ligne[ptr]=='\'') rem=1;
180     if (keyw==17) data=1;
181     if (ligne[ptr]=='"') string=1;
182     if (keyw>=0)
183     {
184     buf[i++]=keyw+128;
185     ptr+=strlen(keywords[keyw]);
186     }
187     else
188     {
189     buf[i++]=ligne[ptr++];
190     }
191     }
192     }
193     buf[i++]=0;
194     }
195     }
196     ++lineIt;
197     }
198     buf[i++]=0;
199     buf[i++]=0;
200 dbug 70
201 dbug 1119 //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     //Let's assume a 1 byte program, it starts at address #501 and ends at address #501 (Address=Address+1-1) !
204     //It was a blocking issue for various utilities (tap2wav for instance)
205     //end=0x501+i-1; //end=0x501+i;
206     end=0x501+i;
207 dbug 208
208 dbug 1119 if (autoRun) head[7]=0x80; // Autorun for basic :)
209     else head[7]=0;
210 dbug 70
211 dbug 1119 head[8]=end>>8;
212     head[9]=end&0xFF;
213 dbug 70
214 dbug 1119 for(j=4,lastptr=0;j<i;j++)
215     {
216     if (buf[j]==0)
217     {
218     adr=0x501+j+1;
219     buf[lastptr]=adr&0xFF;
220     buf[lastptr+1]=adr>>8;
221     lastptr=j+1;
222     j+=4;
223     }
224     }
225    
226     //
227     // Save file
228     //
229     FILE *out=fopen(destFile,"wb");
230     if (out==NULL)
231     {
232     printf("Can't open file for writing\n");
233     exit(1);
234     }
235     fwrite(head,1,14,out);
236     fwrite(buf,1,i+1,out);
237     fclose(out);
238 dbug 70 }
239    
240    
241    
242    
243     #define NB_ARG 2
244    
245     void main(int argc, char **argv)
246     {
247 dbug 1119 //
248     // Some initialization for the common library
249     //
250     SetApplicationParameters(
251     "Bas2Tap",
252     TOOL_VERSION_MAJOR,
253     TOOL_VERSION_MINOR,
254     "{ApplicationName} - Version {ApplicationVersion} - This program is a part of the OSDK\r\n"
255     "\r\n"
256     "Author:\r\n"
257     " Fabrice Frances \r\n"
258     "\r\n"
259     "Purpose:\r\n"
260     " 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"
262     " (and the opposite operation as well).\r\n"
263     "\r\n"
264     "Parameters:\r\n"
265     " <options> <sourcefile> <destinationfile>\r\n"
266     "\r\n"
267     "Options:\r\n"
268     " -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"
270     " -color[0|1] for enabling colored comments"
271     "\r\n"
272     "Exemple:\r\n"
273     " {ApplicationName} -b2t1 final.txt osdk.tap\r\n"
274     " {ApplicationName} -t2b osdk.tap program.txt\r\n"
275     );
276 dbug 70
277 dbug 1119 bool basicToTape=true;
278     bool autoRun=true;
279     bool useColor=false;
280 dbug 70
281 dbug 1119 ArgumentParser argumentParser(argc,argv);
282 dbug 70
283 dbug 1119 while (argumentParser.ProcessNextArgument())
284     {
285     if (argumentParser.IsSwitch("-t2b"))
286 dbug 70 {
287 dbug 1119 // Tape to BASIC source code
288     basicToTape=false;
289 dbug 70 }
290 dbug 1119 else
291     if (argumentParser.IsSwitch("-b2t"))
292     {
293     // 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 dbug 70
305 dbug 1119 if (argumentParser.GetParameterCount()!=NB_ARG)
306     {
307     ShowError(0);
308     }
309 dbug 70
310    
311 dbug 1119 std::string nameSrc(argumentParser.GetParameter(0));
312     std::string nameDst(argumentParser.GetParameter(1));
313 dbug 70
314 dbug 1119 if (basicToTape)
315     {
316     Bas2Tap(nameSrc.c_str(),nameDst.c_str(),autoRun,useColor);
317     }
318     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);
330     }
331    
332     exit(0);
333 dbug 70 }

  ViewVC Help
Powered by ViewVC 1.1.26