OSDN Git Service

client 0.6.1 release
[unagi/old-svn-converted.git] / client / tag / 0.6.1 / unagi.c
1 /*
2 famicom ROM cartridge utility - unagi
3 command line interface, config file parser
4
5 Copyright (C) 2008-2009 ±·³«È¯¶¨Æ±Áȹç
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20 */
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include "memory_manage.h"
25 #include "type.h"
26 #include "reader_master.h"
27 #include "giveio.h"
28 #include "file.h"
29 #include "script.h"
30 #include "header.h"
31 #include "textutil.h"
32 #include "config.h"
33 #include "flashmemory.h"
34
35 static int flag_get(const char *flag, struct st_config *c)
36 {
37         while(*flag != '\0'){
38                 switch(*flag){
39                 case 'S': case 's':
40                         c->backupram = CONFIG_OVERRIDE_TRUE;
41                         break;
42                 case 'H': case 'h':
43                         c->mirror = MIRROR_HORIZONAL;
44                         break;
45                 case 'V': case 'v':
46                         c->mirror = MIRROR_VERTICAL;
47                         break;
48                 case '_':
49                         break;
50                 case 'r':
51                         c->syntaxtest = 1;
52                         break;
53                 default:
54                         return NG;
55                 }
56                 flag++;
57         }
58         return OK;
59 }
60 //patch... for reader_hongkongfc.c
61 extern int hongkong_flash_patch;
62 static const char PREFIX_CONFIG_ERROR[] = "config error:";
63 static int config_file_load(struct st_config *c)
64 {
65         char *buf;
66         int size = 0;
67         c->reader = NULL;
68         buf = buf_load_full("unagi.cfg", &size);
69         if(buf == NULL){
70                 printf("%s config file open error\n", PREFIX_CONFIG_ERROR);
71                 return NG;
72         }
73         char **text;
74         text = Malloc(sizeof(char*) * TEXT_MAXLINE);
75         const int text_num = text_load(buf, size, text);
76         if(text_num == 0){
77                 printf("%s script line too much\n", PREFIX_CONFIG_ERROR);
78                 Free(buf);
79                 Free(text);
80                 return NG;
81         }
82         int i;
83         for(i=0; i<text_num; i++){
84                 char *word[TEXT_MAXWORD];
85                 word_load(text[i], word);
86                 if(word[0][0] == '#'){
87                         continue;
88                 }
89                 if(strcmp("DRIVER", word[0]) == 0){
90                         c->reader = reader_driver_get(word[1]);
91                 }else if(strcmp("HONGKONG_FLASH", word[0]) == 0){
92                         hongkong_flash_patch = 0;
93                         if(strcmp("0.5.3", word[1]) == 0){
94                                 hongkong_flash_patch = 1;
95                         }
96                 }else if((DEBUG == 1) && (strcmp("WRITE_WAIT", word[0]) == 0)){
97                         if(value_get(word[1], &(c->write_wait)) == NG){
98                                 printf("%s write_wait parameter is illigal", PREFIX_CONFIG_ERROR);
99                                 Free(buf);
100                                 Free(text);
101                                 return NG;
102                         }
103                 }else if(strcmp("TEST_DEVICE", word[0]) == 0){
104                         if(DEBUG == 1){
105                                 strncpy(c->flash_test_device, word[1], CONFIG_STR_LENGTH);
106                         }
107                 }else if(strcmp("TEST_MAPPER", word[0]) == 0){
108                         if(DEBUG == 1){
109                                 strncpy(c->flash_test_mapper, word[1], CONFIG_STR_LENGTH);
110                         }
111                 }else{
112                         printf("%s unknown config title %s", PREFIX_CONFIG_ERROR, word[1]);
113                         Free(buf);
114                         Free(text);
115                         return NG;
116                 }
117         }
118         
119         Free(text);
120         if(c->reader == NULL){
121                 printf("%s hardware not selected or not found\n", PREFIX_CONFIG_ERROR);
122                 Free(buf);
123                 return NG;
124         }
125         Free(buf);
126         return OK;
127 }
128
129 static int flash_pointer_init(const char *device, const struct flash_driver **f)
130 {
131         *f = flash_driver_get(device);
132         if(*f == NULL){
133                 printf("%s unknown flash device %s\n", PREFIX_CONFIG_ERROR, device);
134                 return NG;
135         }
136         return OK;
137 }
138
139 enum{
140         ARGC_MODE = 1,
141         ARGC_SCRIPTFILE,
142         //DUMP MODE
143         ARGC_DUMP_OUT_NESFILE,
144         ARGC_DUMP_FLAG,
145         ARGC_DUMP_MAPPER,
146         //RAM RW MODE
147         ARGC_READ_OUT_RAMFILE = ARGC_DUMP_OUT_NESFILE,
148         ARGC_WRITE_IN_RAMFILE = ARGC_DUMP_OUT_NESFILE,
149         ARGC_RW_NUM,
150         //PROGRAM MODE
151         ARGC_PROGRAM_IN_NESFILE = ARGC_DUMP_OUT_NESFILE,
152         ARGC_PROGRAM_CPU_DEVICE,
153         ARGC_PROGRAM_PPU_DEVICE,
154         //TESTMODE
155         ARGC_TEST_OPTION = ARGC_SCRIPTFILE,
156         ARGC_TEST_FILE,
157         ARGC_TEST_NUM
158 };
159
160 static int config_init(const int argc, const char **argv, struct st_config *c)
161 {
162         c->script = argv[ARGC_SCRIPTFILE];
163         c->romimage = NULL;
164         c->ramimage = NULL;
165         c->mapper = CONFIG_OVERRIDE_UNDEF;
166         c->mirror = CONFIG_OVERRIDE_UNDEF;
167         c->backupram = CONFIG_OVERRIDE_UNDEF;
168         c->mapper = CONFIG_OVERRIDE_UNDEF;
169         c->syntaxtest = 0;
170         c->cpu_flash_driver = &FLASH_DRIVER_UNDEF;
171         c->ppu_flash_driver = &FLASH_DRIVER_UNDEF;
172         c->write_wait = 0;
173         //mode ÊÌ target file ½é´ü²½
174         switch(argv[ARGC_MODE][0]){
175         case 'd':
176                 c->mode = MODE_ROM_DUMP;
177                 c->romimage = argv[ARGC_DUMP_OUT_NESFILE];
178                 break;
179         case 'r':
180                 c->mode = MODE_RAM_READ;
181                 c->ramimage = argv[ARGC_READ_OUT_RAMFILE];
182                 break;
183         case 'w':
184                 c->mode = MODE_RAM_WRITE;
185                 c->ramimage = argv[ARGC_WRITE_IN_RAMFILE];
186                 break;
187         case 'f':
188                 c->mode = MODE_ROM_PROGRAM;
189                 c->romimage = argv[ARGC_PROGRAM_IN_NESFILE];
190                 //ÍÆÎ̤¬¾¯¤Ê¤¤ ROM ¤ÎµÍ¤áÊý¤Î¥«¥¹¥¿¥Þ¥¤¥º
191                 switch(argv[ARGC_MODE][1]){
192                 case '\0':
193                         c->transtype_cpu = VALUE_TRANSTYPE_TOP;
194                         c->transtype_ppu = VALUE_TRANSTYPE_TOP;
195                         break;
196                 case 't':
197                         c->transtype_cpu = VALUE_TRANSTYPE_TOP;
198                         break;
199                 case 'b':
200                         c->transtype_cpu = VALUE_TRANSTYPE_BOTTOM;
201                         break;
202                 default:
203                         printf("%s unkown flash trans mode cpu %c\n", PREFIX_CONFIG_ERROR, argv[ARGC_MODE][1]);
204                         return NG;
205                 }
206                 if(argv[ARGC_MODE][1] == '\0'){
207                         break;
208                 }
209                 switch(argv[ARGC_MODE][2]){
210                 case '\0':
211                 case 't':
212                         c->transtype_ppu = VALUE_TRANSTYPE_TOP;
213                         break;
214                 case 'b':
215                         c->transtype_ppu = VALUE_TRANSTYPE_BOTTOM;
216                         break;
217                 default:
218                         printf("%s unkown flash trans mode ppu %c\n", PREFIX_CONFIG_ERROR, argv[ARGC_MODE][2]);
219                         return NG;
220                 }
221                 break;
222         case 't':
223                 if(DEBUG == 1){
224                         c->mode = MODE_TEST;
225                         break;
226                 }
227                 //²¼¤Ø
228         default:
229                 printf("%s unkown mode %s\n", PREFIX_CONFIG_ERROR, argv[ARGC_MODE]);
230                 return NG;
231         };
232         if(config_file_load(c) == NG){
233                 return NG;
234         }
235         /*mode ÊÌ argc check. 
236         DEBUG==0  argc: 4,5,6
237         DEBUG==1  argc: 3,4,5,6
238         */
239         switch(c->mode){
240         case MODE_ROM_DUMP:{
241                 int flag_error = OK, mapper_error = OK;
242                 switch(argc){
243                 case 3:
244                         return NG;
245                 case 5:
246                         flag_error = flag_get(argv[ARGC_DUMP_FLAG], c);
247                         break;
248                 case 6:
249                         flag_error = flag_get(argv[ARGC_DUMP_FLAG], c);
250                         mapper_error = value_get(argv[ARGC_DUMP_MAPPER], &c->mapper);
251                         break;
252                 }
253                 if(flag_error != OK){
254                         printf("%s unknown flag %s\n", PREFIX_CONFIG_ERROR, argv[ARGC_DUMP_FLAG]);
255                         return NG;
256                 }
257                 if(mapper_error != OK){
258                         printf("%s unknown mapper %s\n", PREFIX_CONFIG_ERROR, argv[ARGC_DUMP_MAPPER]);
259                         return NG;
260                 }
261                 }break;
262         case MODE_RAM_READ:
263         case MODE_RAM_WRITE:
264                 if(argc != ARGC_RW_NUM){
265                         printf("%s too many argument\n", PREFIX_CONFIG_ERROR);
266                         return NG;
267                 }
268                 break;
269         case MODE_ROM_PROGRAM:
270                 if(c->reader->flash_support == false){
271                         puts("this reader is not supported flash memory programming mode");
272                         return NG;
273                 }
274                 switch(argc){
275                 case 3:
276                 case 4:
277                         printf("%s few argument\n", PREFIX_CONFIG_ERROR);
278                         return NG;
279                 case 5:
280                         if(flash_pointer_init(argv[ARGC_PROGRAM_CPU_DEVICE], &(c->cpu_flash_driver)) == NG){
281                                 return NG;
282                         }
283                         break;
284                 case 6:
285                         if(flash_pointer_init(argv[ARGC_PROGRAM_CPU_DEVICE], &(c->cpu_flash_driver)) == NG){
286                                 return NG;
287                         }
288                         if(flash_pointer_init(argv[ARGC_PROGRAM_PPU_DEVICE], &(c->ppu_flash_driver)) == NG){
289                                 return NG;
290                         }
291                         break;
292                 }
293                 break;
294         }
295
296         return OK;
297 }
298
299 #include "version.h"
300 int main(int c, char **v)
301 {
302         struct st_config config;
303         int config_result = NG;
304         mm_init();
305         switch(c){
306         case 3: //t testmode target
307                 if(DEBUG == 0){
308                         goto usage;
309                 }
310                 //²¼¤Ø
311         case 4: //mode script target
312         case 5:
313                 //mode script target flag
314                 //mode script target cpu_flash_device
315         case 6:
316                 //mode script target flag mapper
317                 //mode script target cpu_flash_device ppu_flash_device
318                 config_result = config_init(c, (const char **) v, &config);
319                 break;
320         usage:
321         default:
322                 printf("famicom ROM cartridge utility - unagi version %s\n", STR_VERSION);
323                 printf("%s [mode] [mapper script] [target file] [flag]\n", v[0]);
324                 printf("mode - [d]ump ROM / [r]ead RAM/ [w]rite RAM/ [f]lash memory program\n");
325                 break;
326         }
327         if((config.mode != MODE_TEST) && (config_result == OK)){
328                 script_load(&config);
329         }
330         mm_end();
331         return 0;
332 }