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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1119 - (show 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
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 // 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[]=
18 {
19 "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 };
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 unsigned int i, car;
40
41 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 }
66
67
68
69 // tap2bas
70 int search_keyword(const char *str)
71 {
72 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 }
81
82
83
84 void Bas2Tap(const char *sourceFile,const char *destFile,bool autoRun,bool useColor)
85 {
86 unsigned char buf[48192];
87 unsigned int end, lastptr, adr;
88 int j,ptr,keyw,string,rem,data;
89
90 // 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
98 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
106 ++currentLineNumber;
107
108 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
134 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
144 ptr=0;
145 rem=0;
146 bool color=useColor;
147 string=0;
148 data=0;
149 if (ligne[ptr]==' ') ptr++;
150
151 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
201 //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
208 if (autoRun) head[7]=0x80; // Autorun for basic :)
209 else head[7]=0;
210
211 head[8]=end>>8;
212 head[9]=end&0xFF;
213
214 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 }
239
240
241
242
243 #define NB_ARG 2
244
245 void main(int argc, char **argv)
246 {
247 //
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
277 bool basicToTape=true;
278 bool autoRun=true;
279 bool useColor=false;
280
281 ArgumentParser argumentParser(argc,argv);
282
283 while (argumentParser.ProcessNextArgument())
284 {
285 if (argumentParser.IsSwitch("-t2b"))
286 {
287 // Tape to BASIC source code
288 basicToTape=false;
289 }
290 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
305 if (argumentParser.GetParameterCount()!=NB_ARG)
306 {
307 ShowError(0);
308 }
309
310
311 std::string nameSrc(argumentParser.GetParameter(0));
312 std::string nameDst(argumentParser.GetParameter(1));
313
314 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 }

  ViewVC Help
Powered by ViewVC 1.1.26