OSDN Git Service

cda3ed8f8abd3f4c14af498f6f8b8dfbf4dc8a1e
[unagi/old-svn-converted.git] / client / trunk / unagi.c
1 /*
2 famicom ROM cartridge utility - unagi
3 command line interface, config file pharser
4
5 Copyright (C) 2008  sato_tiff
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 "type.h"
25 #include "reader_master.h"
26 #include "giveio.h"
27 #include "file.h"
28 #include "script.h"
29 #include "header.h"
30 #include "textutil.h"
31 #include "config.h"
32 #include "flashmemory.h"
33 #include "client_test.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
61 static const char PREFIX_CONFIG_ERROR[] = "config error:";
62 static int config_file_load(struct st_config *c)
63 {
64         char *buf;
65         int size = 0;
66         c->reader = NULL;
67         buf = buf_load_full("unagi.cfg", &size);
68         if(buf == NULL){
69                 printf("%s config file open error\n", PREFIX_CONFIG_ERROR);
70                 return NG;
71         }
72         char **text;
73         text = malloc(sizeof(char*) * TEXT_MAXLINE);
74         const int text_num = text_load(buf, size, text);
75         if(text_num == 0){
76                 printf("%s script line too much\n", PREFIX_CONFIG_ERROR);
77                 free(buf);
78                 free(text);
79                 return NG;
80         }
81         int i;
82         for(i=0; i<text_num; i++){
83                 char *word[TEXT_MAXWORD];
84                 word_load(text[i], word);
85                 if(word[0][0] == '#'){
86                         continue;
87                 }
88                 if(strcmp("DRIVER", word[0]) == 0){
89                         c->reader = reader_driver_get(word[1]);
90                         break;
91                 }else{
92                         printf("%s unknown config title %s", PREFIX_CONFIG_ERROR, word[1]);
93                         free(buf);
94                         free(text);
95                         return NG;
96                 }
97         }
98         
99         free(text);
100         if(c->reader == NULL){
101                 printf("%s hardware not selected or not found\n", PREFIX_CONFIG_ERROR);
102                 free(buf);
103                 return NG;
104         }
105         free(buf);
106         return OK;
107 }
108
109 static const struct flash_driver DRIVER_UNDEF = {
110         .name = "undefined",
111         .capacity = 0,
112         .pagesize = 1,
113         .id_manufacurer = 0,
114         .id_device = 0,
115         .productid_check = NULL,
116 #if DEBUG==1
117         .erase = NULL,
118 #endif
119         .init = NULL,
120         .write = NULL
121 };
122 static int flash_pointer_init(const char *device, const struct flash_driver **f)
123 {
124         *f = flash_driver_get(device);
125         if(*f == NULL){
126                 printf("%s unknown flash device %s\n", PREFIX_CONFIG_ERROR, device);
127                 return NG;
128         }
129         return OK;
130 }
131
132 enum{
133         ARGC_MODE = 1,
134         ARGC_SCRIPTFILE,
135         //DUMP MODE
136         ARGC_DUMP_OUT_NESFILE,
137         ARGC_DUMP_FLAG,
138         ARGC_DUMP_MAPPER,
139         //RAM RW MODE
140         ARGC_READ_OUT_RAMFILE = ARGC_DUMP_OUT_NESFILE,
141         ARGC_WRITE_IN_RAMFILE = ARGC_DUMP_OUT_NESFILE,
142         ARGC_RW_NUM,
143         //PROGRAM MODE
144         ARGC_PROGRAM_IN_NESFILE = ARGC_DUMP_OUT_NESFILE,
145         ARGC_PROGRAM_CPU_DEVICE,
146         ARGC_PROGRAM_PPU_DEVICE,
147         //TESTMODE
148         ARGC_TEST_OPTION = ARGC_SCRIPTFILE,
149         ARGC_TEST_FILE,
150         ARGC_TEST_NUM
151 };
152
153 static int config_init(const int argc, const char **argv, struct st_config *c)
154 {
155         c->script = argv[ARGC_SCRIPTFILE];
156         c->romimage = NULL;
157         c->ramimage = NULL;
158         c->mapper = CONFIG_OVERRIDE_UNDEF;
159         c->mirror = CONFIG_OVERRIDE_UNDEF;
160         c->backupram = CONFIG_OVERRIDE_UNDEF;
161         c->mapper = CONFIG_OVERRIDE_UNDEF;
162         c->syntaxtest = 0;
163         c->cpu_flash_driver = &DRIVER_UNDEF;
164         c->ppu_flash_driver = &DRIVER_UNDEF;
165         //mode ÊÌ target file ½é´ü²½
166         switch(argv[ARGC_MODE][0]){
167         case 'd':
168                 c->mode = MODE_ROM_DUMP;
169                 c->romimage = argv[ARGC_DUMP_OUT_NESFILE];
170                 break;
171         case 'r':
172                 c->mode = MODE_RAM_READ;
173                 c->ramimage = argv[ARGC_READ_OUT_RAMFILE];
174                 break;
175         case 'w':
176                 c->mode = MODE_RAM_WRITE;
177                 c->ramimage = argv[ARGC_WRITE_IN_RAMFILE];
178                 break;
179         case 'f':
180                 c->mode = MODE_ROM_PROGRAM;
181                 c->romimage = argv[ARGC_PROGRAM_IN_NESFILE];
182                 break;
183         case 't':
184                 if(DEBUG == 1){
185                         c->mode = MODE_TEST;
186                         break;
187                 }
188                 //²¼¤Ø
189         default:
190                 printf("%s unkown mode %s\n", PREFIX_CONFIG_ERROR, argv[ARGC_MODE]);
191                 return NG;
192         };
193         if(config_file_load(c) == NG){
194                 return NG;
195         }
196         /*mode ÊÌ argc check. 
197         DEBUG==0  argc: 4,5,6
198         DEBUG==1  argc: 3,4,5,6
199         */
200         switch(c->mode){
201         case MODE_ROM_DUMP:{
202                 int flag_error = OK, mapper_error = OK;
203                 switch(argc){
204                 case 3:
205                         return NG;
206                 case 5:
207                         flag_error = flag_get(argv[ARGC_DUMP_FLAG], c);
208                         break;
209                 case 6:
210                         flag_error = flag_get(argv[ARGC_DUMP_FLAG], c);
211                         mapper_error = value_get(argv[ARGC_DUMP_MAPPER], &c->mapper);
212                         break;
213                 }
214                 if(flag_error != OK){
215                         printf("%s unknown flag %s\n", PREFIX_CONFIG_ERROR, argv[ARGC_DUMP_FLAG]);
216                         return NG;
217                 }
218                 if(mapper_error != OK){
219                         printf("%s unknown mapper %s\n", PREFIX_CONFIG_ERROR, argv[ARGC_DUMP_MAPPER]);
220                         return NG;
221                 }
222                 }break;
223         case MODE_RAM_READ:
224         case MODE_RAM_WRITE:
225                 if(argc != ARGC_RW_NUM){
226                         printf("%s too many argument\n", PREFIX_CONFIG_ERROR);
227                         return NG;
228                 }
229                 break;
230         case MODE_ROM_PROGRAM:
231                 switch(argc){
232                 case 3:
233                 case 4:
234                         printf("%s few argument\n", PREFIX_CONFIG_ERROR);
235                         return NG;
236                 case 5:
237                         if(flash_pointer_init(argv[ARGC_PROGRAM_CPU_DEVICE], &(c->cpu_flash_driver)) == NG){
238                                 return NG;
239                         }
240                         break;
241                 case 6:
242                         if(flash_pointer_init(argv[ARGC_PROGRAM_CPU_DEVICE], &(c->cpu_flash_driver)) == NG){
243                                 return NG;
244                         }
245                         if(flash_pointer_init(argv[ARGC_PROGRAM_PPU_DEVICE], &(c->ppu_flash_driver)) == NG){
246                                 return NG;
247                         }
248                         break;
249                 }
250                 break;
251         
252         case MODE_TEST:
253                 if(DEBUG == 0){
254                         break;
255                 }
256                 switch(argc){
257                 case 3:
258                         client_test(c->reader, argv[ARGC_TEST_OPTION], NULL);
259                         break;
260                 case 4:
261                         client_test(c->reader, argv[ARGC_TEST_OPTION], argv[ARGC_TEST_FILE]);
262                         break;
263                 default:
264                         printf("%s test argc error\n", PREFIX_CONFIG_ERROR);
265                 }
266                 break;
267         }
268
269         return OK;
270 }
271
272 #include "version.h"
273 int main(int c, char **v)
274 {
275         struct st_config config;
276         int config_result = NG;
277         switch(c){
278         case 3: //t testmode target
279                 if(DEBUG == 0){
280                         goto usage;
281                 }
282                 //²¼¤Ø
283         case 4: //mode script target
284         case 5:
285                 //mode script target flag
286                 //mode script target cpu_flash_device
287         case 6:
288                 //mode script target flag mapper
289                 //mode script target cpu_flash_device ppu_flash_device
290                 config_result = config_init(c, (const char **) v, &config);
291                 break;
292         usage:
293         default:
294                 printf("famicom ROM cartridge utility - unagi version %s\n", STR_VERSION);
295                 printf("%s [mode] [mapper script] [target file] [flag]\n", v[0]);
296                 printf("mode - [d]ump ROM / [r]ead RAM/ [w]rite RAM/ program [f]lash memory\n");
297                 break;
298         }
299         if((config.mode != MODE_TEST) && (config_result == OK)){
300                 script_load(&config);
301         }
302         return 0;
303 }