/[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 70 - (hide annotations)
Sun May 24 19:53:20 2009 UTC (10 years, 8 months ago) by dbug
File size: 7404 byte(s)
Added the complete source code of the OSDK.
Projects files are available for Visual Studio 6 and .net, plus a Code::Blocks setup (everything works except PictConv that relies on FreeImage - which does not build correctly on mingw)
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     end=0x501+i;
200    
201     if (bAutoRun) head[7]=0x80; // Autorun for basic :)
202     else head[7]=0;
203    
204     head[8]=end>>8;
205     head[9]=end&0xFF;
206    
207     for(j=4,lastptr=0;j<i;j++)
208     {
209     if (buf[j]==0)
210     {
211     adr=0x501+j+1;
212     buf[lastptr]=adr&0xFF;
213     buf[lastptr+1]=adr>>8;
214     lastptr=j+1;
215     j+=4;
216     }
217     }
218    
219     //
220     // Save file
221     //
222     FILE *out=fopen(pDestFile,"wb");
223     if (out==NULL)
224     {
225     printf("Can't open file for writing\n");
226     exit(1);
227     }
228     fwrite(head,1,14,out);
229     fwrite(buf,1,i,out);
230     fclose(out);
231     }
232    
233    
234    
235    
236     #define NB_ARG 2
237    
238     void main(int argc, char **argv)
239     {
240     //
241     // Some initialization for the common library
242     //
243     SetApplicationParameters(
244     "Bas2Tap",
245     TOOL_VERSION_MAJOR,
246     TOOL_VERSION_MINOR,
247     "{ApplicationName} - Version {ApplicationVersion} - This program is a part of the OSDK\r\n"
248     "\r\n"
249     "Author:\r\n"
250     " Fabrice Frances \r\n"
251     "\r\n"
252     "Purpose:\r\n"
253     " Converting a text file containing a BASIC source code to a binary\r\n"
254     " encoded TAPE file that can be loaded using the CLOAD command.\r\n"
255     " (and the opposite operation as well).\r\n"
256     "\r\n"
257     "Parameters:\r\n"
258     " <options> <sourcefile> <destinationfile>\r\n"
259     "\r\n"
260     "Options:\r\n"
261     " -b2t[0|1] for converting to tape format with autorun (1) or not (0)\r\n"
262     " -t2b for converting from tape format text\r\n"
263     " -color[0|1] for enabling colored comments"
264     "\r\n"
265     "Exemple:\r\n"
266     " {ApplicationName} -b2t1 final.txt osdk.tap\r\n"
267     " {ApplicationName} -t2b osdk.tap program.txt\r\n"
268     );
269    
270     bool bBasicToTape=true;
271     bool bAutoRun=true;
272     bool bUseColor=false;
273    
274     ArgumentParser cArgumentParser(argc,argv);
275    
276     while (cArgumentParser.ProcessNextArgument())
277     {
278     if (cArgumentParser.IsSwitch("-t2b"))
279     {
280     // Tape to BASIC source code
281     bBasicToTape=false;
282     }
283     else
284     if (cArgumentParser.IsSwitch("-b2t"))
285     {
286     // BASIC source code to tape
287     bBasicToTape=true;
288     bAutoRun=cArgumentParser.GetBooleanValue(true);
289     }
290     else
291     if (cArgumentParser.IsSwitch("-color"))
292     {
293     // Handling of color codes
294     bUseColor=cArgumentParser.GetBooleanValue(false);
295     }
296     }
297    
298     if (cArgumentParser.GetParameterCount()!=NB_ARG)
299     {
300     ShowError(0);
301     }
302    
303    
304     std::string NameSrc(cArgumentParser.GetParameter(0));
305     std::string NameDst(cArgumentParser.GetParameter(1));
306    
307     if (bBasicToTape)
308     {
309     Bas2Tap(NameSrc.c_str(),NameDst.c_str(),bAutoRun,bUseColor);
310     }
311     else
312     {
313     // Load the source file
314     void* ptr_buffer_void;
315     size_t file_size;
316     if (!LoadFile(NameSrc.c_str(),ptr_buffer_void,file_size))
317     {
318     ShowError("Unable to load the source file");
319     }
320     unsigned char *ptr_buffer=(unsigned char*)ptr_buffer_void;
321    
322     Tap2Bas(ptr_buffer,file_size);
323     }
324    
325     exit(0);
326     }

  ViewVC Help
Powered by ViewVC 1.1.26