OSDN Git Service

hongkong 用 PPU_READ パッチのやっつけ変数を追加
[unagi/old-svn-converted.git] / client / trunk / script_engine.c
1 /*
2 famicom ROM cartridge utility - unagi
3 script engine
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 todo: 
22 * ÊÑ¿ô´ÉÍý¤Î¥°¥í¡¼¥Ð¥ëÃͤò¡¢logical_test(), excute() ¥í¡¼¥«¥ë¤Ë¤·¤¿¤¤
23 */
24 #include <assert.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include "type.h"
29 #include "file.h"
30 #include "reader_master.h"
31 #include "textutil.h"
32 #include "config.h"
33 #include "header.h"
34 #include "script_syntax.h"
35 #include "script.h"
36
37 /*
38 MAPPER num
39 MIRROR [HV]
40 CPU_ROMSIZE num
41 CPU_RAMSIZE num
42 PPU_ROMSIZE num
43 DUMP_START
44 CPU_READ address size
45 CPU_WRITE address data -> ÊÑ¿ôŸ³«+±é»»»Ò»ÈÍѲÄǽ
46 PPU_READ address size
47 STEP_START variable start end step -> for(i=start;i<end;i+=step)
48 STEP_END
49 DUMP_END
50 */
51 //#include "syntax.h"
52
53 //ÊÑ¿ô´ÉÍý
54 //step ¤ÎÊÑ¿ô¤Ï¾®Ê¸»ú¤Î a-z ¤Ç¤Ï¤¸¤Þ¤ë¤³¤È¡£2ʸ»úÌܰʹߤÏ̵»ë¤¹¤ë
55 struct variable_manage{
56         char name;
57         long start,end,step;
58         long val;
59         const struct script *Continue;
60 };
61
62 enum{
63         STEP_MAX = 3,
64         VARIABLE_MAX = STEP_MAX
65 };
66
67 static const struct variable_manage VARIABLE_INIT = {
68         .name = '\0', 
69         .start = 0, .end = 0, .step = 0,
70         .val = 0,
71         .Continue = NULL
72 };
73 static struct variable_manage variable_bank[VARIABLE_MAX];
74 static int variable_num = 0;
75
76 static void variable_init_single(int num)
77 {
78         memcpy(&variable_bank[num], &VARIABLE_INIT, sizeof(struct variable_manage));
79 }
80
81 static void variable_init_all(void)
82 {
83         int i;
84         variable_num = 0;
85         for(i = 0; i < VARIABLE_MAX; i++){
86                 variable_init_single(i);
87         }
88 }
89
90 static int variable_get(char name, long *val)
91 {
92         int i;
93         struct variable_manage *v;
94         v = variable_bank;
95         for(i = 0; i < variable_num; i++){
96                 if(v->name == name){
97                         *val = v->val;
98                         return OK;
99                 }
100                 v++;
101         }
102         return NG;
103 }
104
105 //ÊÑ¿ôŸ³«
106 static int expression_calc(const struct st_expression *e, long *val)
107 {
108         long left, right;
109         if(e->left.type == EXPRESSION_TYPE_VARIABLE){
110                 if(variable_get(e->left.variable, &left) == NG){
111                         return NG;
112                 }
113         }else{
114                 left = e->left.value;
115         }
116         if(e->operator == OPERATOR_NONE){
117                 *val = left;
118                 return OK;
119         }
120         if(e->right.type == EXPRESSION_TYPE_VARIABLE){
121                 if(variable_get(e->right.variable, &right) == NG){
122                         return NG;
123                 }
124         }else{
125                 right = e->right.value;
126         }
127         switch(e->operator){
128         case OPERATOR_PLUS:
129                 *val = left + right;
130                 break;
131         case OPERATOR_SHIFT_LEFT:
132                 *val = left >> right;
133                 //*val &= 1;
134                 break;
135         case OPERATOR_SHIFT_RIGHT:
136                 *val = left << right;
137                 break;
138         case OPERATOR_AND:
139                 *val = left & right;
140                 break;
141         case OPERATOR_OR:
142                 *val = left | right;
143                 break;
144         case OPERATOR_XOR:
145                 *val = left ^ right;
146                 break;
147         }
148         
149         return OK;
150 }
151
152 static int step_new(char name, long start, long end, long step, const struct script *Continue)
153 {
154         if(variable_num >= VARIABLE_MAX){
155                 return NG; //ÊÑ¿ôÄêµÁ¤¬Â¿¤¹¤®
156         }
157         struct variable_manage *v;
158         int i;
159         v = variable_bank;
160         for(i = 0; i < variable_num; i++){
161                 if(v->name == name){
162                         return NG; //ÊÑ¿ô̾½ÅÊ£
163                 }
164                 v++;
165         }
166         v = variable_bank;
167         v += variable_num;
168         v->name = name;
169         v->start = start;
170         v->end = end;
171         v->step = step;
172         v->val = start;
173         v->Continue = Continue;
174         variable_num++;
175         return OK;
176 }
177
178 static const struct script *step_end(const struct script *Break)
179 {
180         //¸½ºß¤Î¥ë¡¼¥×¤ÎÂоÝÊÑ¿ô¤òÆÀ¤ë
181         struct variable_manage *v;
182         v = variable_bank;
183         v += (variable_num - 1);
184         //ÊÑ¿ô¹¹¿·
185         v->val += v->step;
186         if(v->val < v->end){
187                 return v->Continue;
188         }
189         //¥ë¡¼¥×¤¬½ª¤ï¤Ã¤¿¤Î¤Ç¤½¤ÎÊÑ¿ô¤òÇË´þ¤¹¤ë
190         variable_init_single(variable_num - 1);
191         variable_num--;
192         return Break;
193 }
194
195 //int syntax_check(char **text, int text_num, struct script *s, int mode);
196 /*
197 logical_check() ÍÑ¥µ¥Ö´Ø¿ô¤È¥Ç¡¼¥¿
198 */
199 static const char LOGICAL_ERROR_PREFIX[] = "logical error:";
200 enum{
201         SCRIPT_PPUSIZE_0 = 0,
202         SCRIPT_MEMORYSIZE = 10,
203 };
204 struct logical_romsize{
205         const struct script *data[SCRIPT_MEMORYSIZE], *constant;
206         int count;
207 };
208 static int logical_flashsize_set(int region, struct logical_romsize *l, const struct script *s)
209 {
210         //PPU Íѥǡ¼¥¿¤Î 0 ¤Ï size 0, Äê¿ô 0 ¤È¤·¤ÆͽÌ󤵤ì¤Æ¤ª¤ê¡¢0¤Î¾ì¹ç¤Ï¤³¤³¤ò¾å½ñ¤­¤¹¤ë
211         if((region == MEMORY_AREA_PPU) && (s->value[0] == 0)){
212                 l->data[SCRIPT_PPUSIZE_0] = s;
213                 return OK;
214         }
215         if(l->count >= SCRIPT_MEMORYSIZE){
216                 const char *opstr;
217                 opstr = OPSTR_CPU_ROMSIZE; //warning Âкö
218                 switch(region){
219                 case MEMORY_AREA_CPU_ROM:
220                         opstr = OPSTR_CPU_ROMSIZE;
221                         break;
222                 case MEMORY_AREA_PPU:
223                         opstr = OPSTR_PPU_ROMSIZE;
224                         break;
225                 default:
226                         assert(0);
227                 }
228                 printf("%d:%s %s override count over\n", s->line, LOGICAL_ERROR_PREFIX, opstr);
229                 return NG;
230         }
231         l->data[l->count] = s;
232         l->count += 1;
233         return OK;
234 }
235
236 static int logical_flashsize_get(long transtype, long size, struct logical_romsize *l)
237 {
238         int i;
239         for(i = 0; i < l->count; i++){
240                 const struct script *s;
241                 s = l->data[i];
242                 if((s->value[0] == size) && (
243                         (s->value[1] == transtype) || 
244                         (s->value[1] == VALUE_TRANSTYPE_FULL)
245                 )){
246                         l->constant = s;
247                         return OK;
248                 }else if((s->value[0] == size) && (s->value[1] == VALUE_TRANSTYPE_EMPTY)){
249                         l->constant = s;
250                         return OK;
251                 }
252         }
253         printf("%s flashsize not found\n", LOGICAL_ERROR_PREFIX);
254         return NG;
255 }
256
257 static long constant_get(long val, const struct script *cpu, const struct script *ppu)
258 {
259         switch(val){
260         case VALUE_CONTANT_CPU_STEP_START:
261                 return cpu->value[2];
262         case VALUE_CONTANT_CPU_STEP_END:
263                 return cpu->value[3];
264         case VALUE_CONTANT_PPU_STEP_START:
265                 return ppu->value[2];
266         case VALUE_CONTANT_PPU_STEP_END:
267                 return ppu->value[3];
268         }
269         assert(0);
270         return -1;
271 }
272
273 static void logical_print_capacityerror(int line, const char *area)
274 {
275         printf("%d:%s %s area flash memory capacity error\n", line, LOGICAL_ERROR_PREFIX, area);
276 }
277
278 static inline void logical_print_illgalarea(int line, const char *area, long address)
279 {
280         printf("%d:%s illgal %s area $%06x\n", line, LOGICAL_ERROR_PREFIX, area, (int) address);
281 }
282
283 static inline void logical_print_illgallength(int line, const char *area, long length)
284 {
285         printf("%d:%s illgal %s length $%04x\n", line, LOGICAL_ERROR_PREFIX, area, (int) length);
286 }
287
288 static inline void logical_print_overdump(int line, const char *area, long start, long end)
289 {
290         printf("%d:%s %s area over dump $%06x-$%06x\n", line, LOGICAL_ERROR_PREFIX, area, (int)start ,(int)end);
291 }
292
293 static inline void logical_print_access(int line, const char *area, const char *rw, long addr, long len)
294 {
295         printf("%d:%s %s $%04x $%02x\n", line, area, rw, (int) addr, (int) len);
296 }
297
298 static inline void logical_print_byteerror(int line, const char *area, long data)
299 {
300         printf("%d:%s write data byte range over, %s $%x\n", line, LOGICAL_ERROR_PREFIX, area, (int) data);
301 }
302
303 static int dump_length_conform(const char *name, long logicallength, long configlength)
304 {
305         if(configlength != logicallength){
306                 printf("%s %s dump length error\n", LOGICAL_ERROR_PREFIX, name);
307                 printf("%s: 0x%06x, dump length: 0x%06x\n", name, (int) configlength, (int) logicallength);
308                 return 1;
309         }
310         return 0;
311 }
312 static inline int is_region_cpurom(long address)
313 {
314         return (address >= 0x8000) && (address < 0x10000);
315 }
316
317 static inline int is_region_cpuram(long address)
318 {
319         return (address >= 0x6000) && (address < 0x8000);
320 }
321
322 static inline int is_region_ppurom(long address)
323 {
324         return (address >= 0) && (address < 0x2000);
325 }
326
327 static inline int is_data_byte(long data)
328 {
329         return (data >= 0) && (data < 0x100);
330 }
331
332 //¤³¤ì¤À¤± is ·Ï¤Ç <= ±é»»»Ò¤ò»ÈÍѤ·¤Æ¤¤¤ë¤Î¤ÇÃí°Õ
333 static inline int is_range(long data, long start, long end)
334 {
335         return (data >= start) && (data <= end);
336 }
337 static const char STR_REGION_CPU[] = "cpu";
338 static const char STR_REGION_PPU[] = "ppu";
339 static const char STR_ACCESS_READ[] = "read";
340 static const char STR_ACCESS_WRITE[] = "write";
341
342 enum{
343         SETTING, DUMP, END, STEP_THOUGH
344 };
345 static int command_mask(const int region, const long address, const long offset, long size, struct flash_order *f)
346 {
347         const char *str_region = STR_REGION_CPU;
348         if(region == MEMORY_AREA_PPU){
349                 str_region = STR_REGION_PPU;
350         }
351         switch(region){
352         case MEMORY_AREA_CPU_ROM:
353                 switch(offset){
354                 case 0x8000: case 0xa000: case 0xc000:
355                         break;
356                 default:
357                         printf("%s %s_COMMAND area offset error\n", LOGICAL_ERROR_PREFIX, str_region);
358                         return NG;
359                 }
360                 switch(size){
361                 case 0x2000: case 0x4000: case 0x8000:
362                         break;
363                 default:
364                         printf("%s %s_COMMAND area mask error\n", LOGICAL_ERROR_PREFIX, str_region);
365                         return NG;
366                 }
367                 break;
368         case MEMORY_AREA_PPU:
369                 switch(offset){
370                 case 0x0000: case 0x0400: case 0x0800: case 0x0c00:
371                 case 0x1000: case 0x1400: case 0x1800: case 0x1c00:
372                         break;
373                 default:
374                         printf("%s %s_COMMAND area offset error\n", LOGICAL_ERROR_PREFIX, str_region);
375                         return NG;
376                 }
377                 switch(size){
378                 case 0x0400: case 0x0800: case 0x1000: case 0x2000: 
379                         break;
380                 default:
381                         printf("%s %s_COMMAND area mask error\n", LOGICAL_ERROR_PREFIX, str_region);
382                         return NG;
383                 }
384                 break;
385         default:
386                 assert(0); //unknown memory area
387         }
388
389         const long mask = size - 1;
390         const long data = (address & mask) | offset;
391         switch(address){
392         case 0:
393                 f->command_0000 = data;
394                 break;
395         case 0x2aaa: case 0x02aa: 
396                 f->command_2aaa = data;
397                 break;
398         case 0x5555: case 0x0555:
399                 f->command_5555 = data;
400                 break;
401         default:
402                 printf("%s %s_COMMAND unknown commnand address\n", LOGICAL_ERROR_PREFIX, str_region);
403                 return NG;
404         }
405         return OK;
406 }
407
408 enum{
409         STEP_VALIABLE = 0, STEP_START, STEP_END, STEP_NEXT,
410         STEP_NUM
411 };
412 static const struct script SCRIPT_PPU_ROMSIZE_0 = {
413         .opcode = SCRIPT_OPCODE_PPU_ROMSIZE,
414         .line = -1,
415         .value = {0, VALUE_TRANSTYPE_EMPTY, 0, 0},
416         //.expression, .variable Ì¤ÄêµÁ
417 };
418
419 static int logical_check(const struct script *s, const struct st_config *c, struct romimage *r)
420 {
421         //(CPU|PPU)_(READ|PROGRAM|RAMRW) ¤Î length ²Ã»»ÃÍ
422         long cpu_romsize = 0, cpu_ramsize = 0, ppu_romsize = 0;
423         //DUMP_START Ä¾¸å¤Ë ROM or RAM image ¤ò³«¤¯¥Õ¥é¥°
424         //use program mode or ram write mode
425         int imagesize = 0; //for write or program mode
426         int status = SETTING;
427         //override (CPU|PPU)_ROMSIZE pointer. Program mode only
428         struct logical_romsize script_cpu_flashsize = {
429                 .constant = NULL,
430                 .count = 0
431         };
432         struct logical_romsize script_ppu_flashsize = {
433                 .constant = NULL,
434                 .count = 1
435         };
436         script_ppu_flashsize.data[0] = &SCRIPT_PPU_ROMSIZE_0;
437         //logical error count. Ìá¤êÃÍ
438         int error = 0;
439         
440         variable_init_all();
441         while(s->opcode != SCRIPT_OPCODE_DUMP_END){
442                 if((status == DUMP) && (s->opcode < SCRIPT_OPCODE_DUMP_START)){
443                         printf("%d:%s config script include DUMP_START area\n", s->line, LOGICAL_ERROR_PREFIX);
444                         error += 1;
445                 }
446
447                 //romimage open for write or program mode
448                 if((imagesize == 0) && (status == DUMP)){
449                         switch(c->mode){
450                         case MODE_RAM_WRITE: //CPU_RAMSIZE check
451                                 assert(r->cpu_ram.attribute == MEMORY_ATTR_READ);
452                                 r->cpu_ram.data = buf_load_full(c->ramimage, &imagesize);
453                                 if(r->cpu_ram.data == NULL){
454                                         printf("%s RAM image open error\n", LOGICAL_ERROR_PREFIX);
455                                         imagesize = -1;
456                                         error += 1;
457                                 }else if(r->cpu_ram.size != imagesize){
458                                         printf("%s RAM image size is not same\n", LOGICAL_ERROR_PREFIX);
459                                         free(r->cpu_ram.data);
460                                         r->cpu_ram.data = NULL;
461                                         imagesize = -1;
462                                         error += 1;
463                                 }
464                                 break;
465                         case MODE_ROM_PROGRAM: //MAPPER check
466                                 assert(c->cpu_flash_driver->write != NULL);
467                                 assert(r->cpu_rom.attribute == MEMORY_ATTR_READ);
468                                 assert(r->ppu_rom.attribute == MEMORY_ATTR_READ);
469                                 if(nesfile_load(LOGICAL_ERROR_PREFIX, c->romimage, r)== NG){
470                                         error += 1;
471                                 }
472                                 //Äê¿ôÀë¸À¥¨¥é¡¼¤Ï̵¸Â¥ë¡¼¥×¤Î²ÄǽÀ­¤¬¤¢¤ë¤Î¤Ç¥¹¥¯¥ê¥×¥ÈÆâÉô¥Á¥§¥Ã¥¯¤ò¤»¤º¤Ë»ß¤á¤ë
473                                 if(logical_flashsize_get(c->transtype_cpu, r->cpu_rom.size, &script_cpu_flashsize) == NG){
474                                         return error + 1;
475                                 }
476                                 if(logical_flashsize_get(c->transtype_ppu, r->ppu_rom.size, &script_ppu_flashsize) == NG){
477                                         return error + 1;
478                                 }
479                                 //flash memory capacity check
480                                 if(r->cpu_rom.size > c->cpu_flash_driver->capacity){
481                                         logical_print_capacityerror(s->line, r->cpu_rom.name);
482                                         error += 1;
483                                 }
484                                 if((r->ppu_rom.size != 0) && (r->ppu_rom.size > c->ppu_flash_driver->capacity)){
485                                         logical_print_capacityerror(s->line, r->ppu_rom.name);
486                                         error += 1;
487                                 }
488                                 imagesize = -1;
489                                 break;
490                         default: 
491                                 imagesize = -1;
492                                 break;
493                         }
494                 }
495         
496                 switch(s->opcode){
497                 case SCRIPT_OPCODE_COMMENT:
498                         break;
499                 case SCRIPT_OPCODE_MAPPER:
500                         r->mappernum = s->value[0];
501                         break;
502                 case SCRIPT_OPCODE_MIRROR:
503                         r->mirror = s->value[0];
504                         break;
505                 case SCRIPT_OPCODE_CPU_ROMSIZE:{
506                         const long size = s->value[0];
507                         r->cpu_rom.size = size;
508                         if(memorysize_check(size, MEMORY_AREA_CPU_ROM)){
509                                 printf("%s %s length error\n", LOGICAL_ERROR_PREFIX, OPSTR_CPU_ROMSIZE);
510                                 error += 1;
511                         }
512                         }break;
513                 case SCRIPT_OPCODE_CPU_FLASHSIZE:
514                         if(logical_flashsize_set(MEMORY_AREA_CPU_ROM, &script_cpu_flashsize, s) == NG){
515                                 error += 1;
516                         }break;
517                 case SCRIPT_OPCODE_CPU_RAMSIZE:
518                         //memory size ¤Ï̤³ÎÄêÍ×ÁǤ¬Â¿¤¤¤Î¤Ç check ¤òÈ´¤¯
519                         r->cpu_ram.size = s->value[0];
520                         break;
521                 case SCRIPT_OPCODE_CPU_COMMAND:
522                         if(command_mask(MEMORY_AREA_CPU_ROM, s->value[0], s->value[1], s->value[2], &(r->cpu_flash)) == NG){
523                                 error += 1;
524                         }
525                         break;
526                 case SCRIPT_OPCODE_PPU_ROMSIZE:{
527                         const long size = s->value[0];
528                         r->ppu_rom.size = size;
529                         if(memorysize_check(size, MEMORY_AREA_PPU)){
530                                 printf("%s %s length error\n", LOGICAL_ERROR_PREFIX, OPSTR_PPU_ROMSIZE);
531                                 error += 1;
532                         }
533                         }break;
534                 case SCRIPT_OPCODE_PPU_FLASHSIZE:
535                         if(logical_flashsize_set(MEMORY_AREA_PPU, &script_ppu_flashsize, s) == NG){
536                                 error += 1;
537                         }
538                         break;
539                 case SCRIPT_OPCODE_PPU_COMMAND:
540                         if(command_mask(MEMORY_AREA_PPU, s->value[0], s->value[1], s->value[2], &(r->ppu_flash)) == NG){
541                                 error += 1;
542                         }
543                         break;
544                 case SCRIPT_OPCODE_DUMP_START:
545                         status = DUMP;
546                         break;
547                 case SCRIPT_OPCODE_CPU_READ:{
548                         const long address = s->value[0];
549                         const long length = s->value[1];
550                         const long end = address + length - 1;
551                         
552                         assert(r->cpu_rom.attribute == MEMORY_ATTR_WRITE);
553                         //length filter. 0 ¤Ï¤À¤á
554                         if(!is_range(length, 1, 0x4000)){
555                                 logical_print_illgallength(s->line, STR_REGION_CPU, length);
556                                 error += 1;
557                         }
558                         //address filter
559                         else if(!is_region_cpurom(address)){
560                                 logical_print_illgalarea(s->line, STR_REGION_CPU, address);
561                                 error += 1;
562                         }else if(end >= 0x10000){
563                                 logical_print_overdump(s->line, STR_REGION_CPU, address, end);
564                                 error += 1;
565                         }
566                         cpu_romsize += length;
567                         status = DUMP;
568                         }
569                         break;
570                 case SCRIPT_OPCODE_CPU_WRITE:{
571                         const long address = s->value[0];
572                         long data;
573                         if(expression_calc(&s->expression, &data) == NG){
574                                 printf("%d:%s expression calc error\n", s->line, LOGICAL_ERROR_PREFIX);
575                                 error += 1;
576                         }
577                         if(address < 0x5000 || address >= 0x10000){
578                                 logical_print_illgalarea(s->line, STR_REGION_CPU, address);
579                                 error += 1;
580                         }else if(!is_data_byte(data)){
581                                 logical_print_byteerror(s->line, STR_REGION_CPU, data);
582                                 error += 1;
583                         }
584                         status = DUMP;
585                         }
586                         break;
587                 case SCRIPT_OPCODE_CPU_RAMRW:{
588                         const long address = s->value[0];
589                         const long length = s->value[1];
590                         const long end = address + length - 1;
591                         switch(c->mode){
592                         case MODE_RAM_READ:
593                                 assert(r->cpu_ram.attribute == MEMORY_ATTR_WRITE);
594                                 break;
595                         case MODE_RAM_WRITE:
596                                 assert(r->cpu_ram.attribute = MEMORY_ATTR_READ);
597                                 break;
598                         }
599                         //length filter. 0 ¤Ï¤À¤á
600                         if(!is_range(length, 1, 0x2000)){
601                                 logical_print_illgallength(s->line, STR_REGION_CPU, length);
602                                 error += 1;
603                         }
604                         //address filter
605                         else if(address < 0x6000 || address >= 0x8000){
606                                 logical_print_illgalarea(s->line, STR_REGION_CPU, address);
607                                 error += 1;
608                         }else if(end >= 0x8000){
609                                 logical_print_overdump(s->line, STR_REGION_CPU, address, end);
610                                 error += 1;
611                         }
612                         cpu_ramsize += length;
613                         status = DUMP;
614                         }
615                         break;
616                 case SCRIPT_OPCODE_CPU_PROGRAM:{
617                         const long address = s->value[0];
618                         const long length = s->value[1];
619                         const long end = address + length - 1;
620                         
621                         assert(r->cpu_rom.attribute == MEMORY_ATTR_READ);
622                         assert(r->ppu_rom.attribute == MEMORY_ATTR_READ);
623                         //length filter.
624                         if(!is_range(length, 0x80, 0x4000)){
625                                 logical_print_illgallength(s->line, STR_REGION_CPU, length);
626                                 error += 1;
627                         }
628                         //address filter
629                         else if(!is_region_cpurom(address)){
630                                 logical_print_illgalarea(s->line, STR_REGION_CPU, address);
631                                 error += 1;
632                         }else if(end >= 0x10000){
633                                 logical_print_overdump(s->line, STR_REGION_CPU, address, end);
634                                 error += 1;
635                         }
636                         cpu_romsize += length;
637                         status = DUMP;
638                         }
639                         break;
640                 case SCRIPT_OPCODE_PPU_RAMFIND:
641                         //¥ë¡¼¥×ÆâÉô¤ËÆþ¤Ã¤Æ¤¿¤é¥¨¥é¡¼
642                         if(variable_num != 0){
643                                 printf("%d:%s PPU_RAMTEST must use outside loop\n", s->line, LOGICAL_ERROR_PREFIX);
644                                 error += 1;
645                         }
646                         break;
647                 case SCRIPT_OPCODE_PPU_SRAMTEST:
648                 case SCRIPT_OPCODE_PPU_READ:{
649                         const long address = s->value[0];
650                         const long length = s->value[1];
651                         const long end = address + length - 1;
652                         assert(r->ppu_rom.attribute == MEMORY_ATTR_WRITE);
653                         //length filter. 0 ¤òÍÆǧ¤¹¤ë
654                         long min = 0;
655                         if(s->opcode == SCRIPT_OPCODE_PPU_SRAMTEST){
656                                 min = 1;
657                         }
658                         if(!is_range(length, min, 0x2000)){
659                                 logical_print_illgallength(s->line, STR_REGION_PPU, length);
660                                 error += 1;
661                         }
662                         //address filter
663                         else if(!is_region_ppurom(address)){
664                                 logical_print_illgalarea(s->line, STR_REGION_PPU, address);
665                                 error += 1;
666                         }else if (end >= 0x2000){
667                                 logical_print_overdump(s->line, STR_REGION_PPU, address, end);
668                                 error += 1;
669                         }
670                         //dump length update
671                         if((s->opcode == SCRIPT_OPCODE_PPU_READ) && is_region_ppurom(address)){
672                                 ppu_romsize += length;
673                         }
674                         status = DUMP;
675                         }
676                         break;
677                 case SCRIPT_OPCODE_PPU_WRITE:{
678                         if(DEBUG==0){
679                                 break;
680                         }
681                         const long address = s->value[0];
682                         long data;
683                         if(expression_calc(&s->expression, &data) == NG){
684                                 printf("%d:%s expression calc error\n", s->line, LOGICAL_ERROR_PREFIX);
685                                 error += 1;
686                         }
687                         status = DUMP;
688                         if(!is_region_ppurom(address)){
689                                 logical_print_illgalarea(s->line, STR_REGION_PPU, address);
690                                 error += 1;
691                         }else if(!is_data_byte(data)){
692                                 logical_print_byteerror(s->line, STR_REGION_PPU, data);
693                                 error += 1;
694                         }
695                         status = DUMP;
696                         }
697                         break;
698                 case SCRIPT_OPCODE_PPU_PROGRAM:{
699                         const long address = s->value[0];
700                         const long length = s->value[1];
701                         const long end = address + length - 1;
702                         
703                         assert(r->ppu_rom.attribute == MEMORY_ATTR_READ);
704                         assert(r->ppu_rom.size != 0);
705
706                         //length filter.
707                         if(!is_range(length, 0x80, 0x1000)){
708                                 logical_print_illgallength(s->line, STR_REGION_PPU, length);
709                                 error += 1;
710                         }
711                         //address filter
712                         else if(!is_region_ppurom(address)){
713                                 logical_print_illgalarea(s->line, STR_REGION_PPU, address);
714                                 error += 1;
715                         }else if(end >= 0x2000){
716                                 logical_print_overdump(s->line, STR_REGION_PPU, address, end);
717                                 error += 1;
718                         }
719                         ppu_romsize += length;
720                         status = DUMP;
721                         }
722                         break;
723                 case SCRIPT_OPCODE_STEP_START:{
724                         const struct step_syntax{
725                                 long start, end;
726                                 int constant;
727                                 const char *name;
728                         } RANGE[STEP_NUM] = {
729                                 {.start = 0, .end = 0, .constant = NG, .name = "variable"},
730                                 {.start = 0, .end = 0xff, .constant = OK, .name = "start"},
731                                 {.start = 0, .end = 0x100, .constant = OK, .name = "end"},
732                                 {.start = 1, .end = 0x100, .constant = NG, .name = "next"}
733                         };
734                         int i;
735                         for(i = STEP_START; i < STEP_NUM; i++){
736                                 const struct step_syntax *ss;
737                                 ss = &RANGE[i];
738                                 //Äê¿ôobject ¤ò¼Â¿ô¤ËÊÑ´¹¤¹¤ë¤¿¤á¡¢const ¤ò³°¤·¤Æ½ñ¤­´¹¤¨¤ë
739                                 long *v;
740                                 v = (long *) &s->value[i];
741                                 if((ss->constant == OK) && (is_range(*v, VALUE_CONTANT_CPU_STEP_START, VALUE_CONTANT_PPU_STEP_END))){
742                                         //VALUE_CONSTANT_xxx ¤ò¼ÂºÝ¤Ë»È¤ï¤ì¤ëÄê¿ô¤Ë¤·¤Æ¡¢¥¹¥¯¥ê¥×¥È¥Ç¡¼¥¿¤òÄ¥¤êÂؤ¨¤ë
743                                         *v = constant_get(*v, script_cpu_flashsize.constant, script_ppu_flashsize.constant);
744                                 }
745                                 if(!is_range(*v, ss->start, ss->end)){
746                                         printf("%d:%s step %s must %d-0x%x 0x%x\n", s->line, ss->name, LOGICAL_ERROR_PREFIX, (int) ss->start, (int) ss->end, (int) *v);
747                                         error += 1;
748                                 }
749                         }
750                         //charcter RAM ¤ÎÍͤˠstep ÆâÉô¤ò¹Ô¤ï¤Ê¤¤¾ì¹ç¤Îscript¾õÂÖ¤ÎÊѹ¹
751                         if(s->value[STEP_START] >= s->value[STEP_END]){
752                                 status = STEP_THOUGH;
753                         }
754                         //¥ë¡¼¥×¤ÎÌá¤êÀè¤Ï¤³¤ÎÌ¿Îá¤Î¼¡¤Ê¤Î¤Ç s[1]
755                         else if(step_new(s->variable, s->value[STEP_START], s->value[STEP_END], s->value[STEP_NEXT], &s[1]) == NG){
756                                 printf("%d:%s step loop too much\n", s->line, LOGICAL_ERROR_PREFIX);
757                                 error += 1;
758                                 return error;
759                         }else{
760                                 status = DUMP;
761                         }
762                         }break;
763                 case SCRIPT_OPCODE_DUMP_END:
764                         status = END;
765                         break;
766                 }
767                 
768                 //status Ê̤ˠscript ¤ÎÀ©¸æ. while ¤òÈ´¤±¤ë¤Î¤Ç switch ¤ò»È¤¨¤Ê¤¤
769                 if(status == END){
770                         break;
771                 }else if(status == STEP_THOUGH){
772                         int stepcount = 1;
773                         int end = 0;
774                         while(s->opcode != SCRIPT_OPCODE_DUMP_END){
775                                 switch(s->opcode){
776                                 case SCRIPT_OPCODE_STEP_START:
777                                         stepcount++;
778                                         break;
779                                 case SCRIPT_OPCODE_STEP_END:
780                                         stepcount--;
781                                         if(stepcount == 0){
782                                                 end = 1;
783                                         }
784                                         break;
785                                 }
786                                 s++;
787                                 if(end == 1){
788                                         break;
789                                 }
790                         }
791                         status = DUMP;
792                 }
793                 //opcode Ê̤ˠscript ¤ÎÀ©¸æ. while ¤òÈ´¤±¤ë¤Î¤Ç switch ¤ò»È¤¨¤Ê¤¤
794                 if(s->opcode == SCRIPT_OPCODE_STEP_END){
795                         if(variable_num == 0){
796                                 printf("%d:%s loop closed, missing STEP_START\n", s->line, LOGICAL_ERROR_PREFIX);
797                                 return error + 1;
798                         }
799                         s = step_end(&s[1]);
800                         status = DUMP;
801                 }else if(s->opcode == SCRIPT_OPCODE_DUMP_END){
802                         break;
803                 }else{
804                         s++;
805                 }
806         }
807         
808         //loop open conform
809         if(variable_num != 0){
810                 printf("%d:%s loop opened, missing STEP_END\n", s->line, LOGICAL_ERROR_PREFIX);
811                 error += 1;
812         }
813         //dump length conform
814         error += dump_length_conform(OPSTR_CPU_ROMSIZE, cpu_romsize, r->cpu_rom.size);
815         error += dump_length_conform(OPSTR_CPU_RAMSIZE, cpu_ramsize, r->cpu_ram.size);
816         error += dump_length_conform(OPSTR_PPU_ROMSIZE, ppu_romsize, r->ppu_rom.size);
817         
818         //command line config override
819         if(c->mirror != CONFIG_OVERRIDE_UNDEF){
820                 r->mirror = c->mirror;
821         }
822         if(c->backupram != CONFIG_OVERRIDE_UNDEF){
823                 r->backupram = 1;
824         }
825         if(c->mapper != CONFIG_OVERRIDE_UNDEF){
826                 //program mode ¤Ç mapper Êѹ¹¤òËɤ°
827                 assert(c->mode == MODE_ROM_DUMP);
828                 r->mappernum = c->mapper;
829         }
830         if(c->syntaxtest == 1){
831                 if(error == 0){
832                         printf("syntax ok!\n");
833                 }
834                 error += 1;
835         }
836         return error;
837 }
838
839 /*
840 execute() ÍÑ¥µ¥Ö´Ø¿ô¤È¥Ç¡¼¥¿
841 */
842 static int execute_connection_check(const struct reader_driver *d)
843 {
844         int ret = OK;
845         const int testsize = 0x80;
846         int testcount = 3;
847         u8 *master, *reload;
848         master = malloc(testsize);
849         reload = malloc(testsize);
850
851         d->cpu_read(0xfee0, testsize, master);
852         
853         while(testcount != 0){
854                 d->cpu_read(0xfee0, testsize, reload);
855                 if(memcmp(master, reload, testsize) != 0){
856                         ret = NG;
857                         break;
858                 }
859                 testcount--;
860         }
861         
862         free(master);
863         free(reload);
864         return ret;
865 }
866
867 enum {PPU_TEST_RAM, PPU_TEST_ROM};
868 const u8 PPU_TEST_DATA[] = "PPU_TEST_DATA";
869 static int ppu_ramfind(const struct reader_driver *d)
870 {
871         const int length = sizeof(PPU_TEST_DATA);
872         const long testaddr = 123;
873         //ppu ram data fill 0
874         {
875                 int i = length;
876                 long address = testaddr;
877                 while(i != 0){
878                         d->ppu_write(address++, 0);
879                         i--;
880                 }
881         }
882         
883         //ppu test data write
884         {
885                 const u8 *data;
886                 int i = length;
887                 long address = testaddr;
888                 data = PPU_TEST_DATA;
889                 while(i != 0){
890                         d->ppu_write(address++, (long) *data);
891                         data++;
892                         i--;
893                 }
894         }
895
896         u8 writedata[length];
897         d->ppu_read(testaddr, length, writedata);
898         if(memcmp(writedata, PPU_TEST_DATA, length) == 0){
899                 return PPU_TEST_RAM;
900         }
901         return PPU_TEST_ROM;
902 }
903
904 static int ramtest(const int region, const struct reader_driver *d, long address, long length, u8 *writedata, u8 *testdata, const long filldata)
905 {
906         long i = length;
907         long a = address;
908         while(i != 0){
909                 switch(region){
910                 case MEMORY_AREA_CPU_RAM:
911                         d->cpu_6502_write(a, filldata, 0);
912                         break;
913                 case MEMORY_AREA_PPU:
914                         d->ppu_write(a, filldata);
915                         break;
916                 default:
917                         assert(0);
918                 }
919                 a++;
920                 i--;
921         }
922         switch(region){
923         case MEMORY_AREA_CPU_RAM:
924                 d->cpu_read(address, length, testdata);
925                 break;
926         case MEMORY_AREA_PPU:
927                 d->ppu_read(address, length, testdata);
928                 break;
929         default:
930                 assert(0);
931         }
932         memset(writedata, filldata, length);
933         if(memcmp(writedata, testdata, length) == 0){
934                 return 0;
935         }
936         return 1;
937 }
938
939 static const long SRAMTESTDATA[] = {0xff, 0xaa, 0x55, 0x00};
940 static int sramtest(const int region, const struct reader_driver *d, long address, long length)
941 {
942         u8 *writedata, *testdata;
943         int error = 0;
944         int i;
945         testdata = malloc(length);
946         writedata = malloc(length);
947         for(i = 0; i < sizeof(SRAMTESTDATA) / sizeof(long); i++){
948                 const long filldata = SRAMTESTDATA[i];
949                 error += ramtest(region, d, address, length, testdata, writedata, filldata);
950         }
951         free(testdata);
952         free(writedata);
953         return error;
954 }
955
956 static void readbuffer_print(const struct memory *m, long length)
957 {
958         if(length >= 0x10){
959                 length = 0x10;
960         }
961         printf("%s ROM 0x%05x:", m->name, m->offset);
962         int offset = 0;
963         const u8 *data;
964         data = m->data;
965         while(length != 0){
966                 char safix;
967                 switch(offset & 0xf){
968                 default:
969                         safix = ' ';
970                         break;
971                 case 0x7:
972                         safix = '-';
973                         break;
974                 case 0xf:
975                         safix = ';';
976                         break;
977                 }
978                 printf("%02x%c", (int) *data, safix);
979                 data++;
980                 offset++;
981                 length--;
982         }
983 }
984
985 static void checksum_print(const u8 *data, long length)
986 {
987         int sum = 0;
988         while(length != 0){
989                 sum += (int) *data;
990                 data++;
991                 length--;
992         }
993         printf(" 0x%06x\n", sum);
994 }
995
996 static void read_result_print(const struct memory *m, long length)
997 {
998         readbuffer_print(m, length);
999         checksum_print(m->data, length);
1000         fflush(stdout);
1001 }
1002
1003 static void execute_program_begin(const struct memory *m, const long length)
1004 {
1005         int tail = m->offset + (int) length - 1;
1006         printf("writing %s area 0x%06x-0x%06x ... ", m->name, m->offset, tail);
1007         fflush(stdout);
1008 }
1009
1010 static const char STR_OK[] = "OK";
1011 static const char STR_NG[] = "NG";
1012
1013 //memcmp ¤ÎÌá¤êÃͤ¬Æþ¤ë¤Î¤Ç 0 ¤¬Àµ¾ï
1014 static void execute_program_finish(int result)
1015 {
1016         const char *str;
1017         str = STR_NG;
1018         if(result == 0){
1019                 str = STR_OK;
1020         }
1021         printf("%s\n", str);
1022         fflush(stdout);
1023 }
1024 static const char EXECUTE_ERROR_PREFIX[] = "execute error:";
1025 static const char EXECUTE_PROGRAM_PREPARE[] = "%s device initialize ... ";
1026 static const char EXECUTE_PROGRAM_DONE[] = "done\n";
1027 static void execute_cpu_ramrw(const struct reader_driver *d, const struct memory *ram, int mode, long address, long length, long wait)
1028 {
1029         if(mode == MODE_RAM_WRITE){
1030                 const u8 *writedata;
1031                 long a = address;
1032                 long l = length;
1033                 writedata = ram->data;
1034                 while(l != 0){
1035                         d->cpu_6502_write(a++, *writedata, wait);
1036                         writedata += 1;
1037                         l--;
1038                 }
1039                 u8 *compare;
1040                 compare = malloc(length);
1041                 d->cpu_read(address, length, compare);
1042                 if(memcmp(ram->data, compare, length) == 0){
1043                         printf("RAM data write success\n");
1044                 }else{
1045                         printf("RAM data write failed\n");
1046                 }
1047                 free(compare);
1048         }else{
1049                 d->cpu_read(address, length, ram->data);
1050         }
1051 }
1052
1053 static int execute(const struct script *s, const struct st_config *c, struct romimage *r)
1054 {
1055         const struct reader_driver *const d = c->reader;
1056         switch(d->open_or_close(READER_OPEN)){
1057         case OK:
1058                 d->init();
1059                 break;
1060         case NG:
1061                 printf("%s driver open error\n", EXECUTE_ERROR_PREFIX);
1062                 return NG;
1063         default:
1064                 assert(0);
1065         }
1066         if(execute_connection_check(d) == NG){
1067                 printf("%s maybe connection error\n", EXECUTE_ERROR_PREFIX);
1068                 d->open_or_close(READER_CLOSE);
1069                 return NG;
1070         }
1071         u8 *program_compare;
1072         program_compare = NULL;
1073         if(c->mode == MODE_ROM_PROGRAM){
1074                 printf("flashmemory/SRAM program mode. To abort programming, press Ctrl+C\n");
1075                 int size = r->cpu_rom.size;
1076                 if(size < r->ppu_rom.size){
1077                         size = r->ppu_rom.size;
1078                 }
1079                 program_compare = malloc(size);
1080         }
1081         struct memory cpu_rom, ppu_rom, cpu_ram;
1082         cpu_rom = r->cpu_rom;
1083         ppu_rom = r->ppu_rom;
1084         cpu_ram = r->cpu_ram;
1085         
1086         int status = DUMP;
1087         int programcount_cpu = 0, programcount_ppu = 0;
1088         variable_init_all();
1089         while(s->opcode != SCRIPT_OPCODE_DUMP_END){
1090                 //printf("%s\n", SCRIPT_SYNTAX[s->opcode].name);
1091                 switch(s->opcode){
1092                 case SCRIPT_OPCODE_CPU_COMMAND:
1093                         command_mask(MEMORY_AREA_CPU_ROM, s->value[0], s->value[1], s->value[2], &(r->cpu_flash));
1094                         break;
1095                 case SCRIPT_OPCODE_CPU_READ:{
1096                         struct memory *m;
1097                         const long address = s->value[0];
1098                         const long length = s->value[1];
1099                         m = &cpu_rom;
1100                         d->cpu_read(address, length, m->data);
1101                         read_result_print(m, length);
1102                         m->data += length;
1103                         m->offset += length;
1104                         }break;
1105                 case SCRIPT_OPCODE_CPU_WRITE:{
1106                         long data;
1107                         expression_calc(&s->expression, &data);
1108                         d->cpu_6502_write(s->value[0], data, c->write_wait);
1109                         }
1110                         break;
1111                 case SCRIPT_OPCODE_CPU_RAMRW:{
1112                         const long address = s->value[0];
1113                         const long length = s->value[1];
1114                         if(c->mode == MODE_RAM_WRITE){
1115                                 if(sramtest(MEMORY_AREA_CPU_RAM, d, address, length) != 0){
1116                                         printf("SRAM test NG\n");
1117                                         status = END;
1118                                         break;
1119                                 }
1120                         }
1121                         execute_cpu_ramrw(d, &cpu_ram, c->mode, address, length, c->write_wait);
1122                         read_result_print(&cpu_ram, length);
1123                         cpu_ram.data += length;
1124                         cpu_ram.offset += length;
1125                         }
1126                         break;
1127                 case SCRIPT_OPCODE_CPU_PROGRAM:{
1128                         if(c->cpu_flash_driver->id_device == FLASH_ID_DEVICE_DUMMY){
1129                                 break;
1130                         }
1131                         if(programcount_cpu++ == 0){
1132                                 printf(EXECUTE_PROGRAM_PREPARE, cpu_rom.name);
1133                                 fflush(stdout);
1134                                 //device ¤Ë¤è¤Ã¤Æ¤Ï erase
1135                                 c->cpu_flash_driver->init(&(r->cpu_flash));
1136                                 printf(EXECUTE_PROGRAM_DONE);
1137                                 fflush(stdout);
1138                         }
1139                         const long address = s->value[0];
1140                         const long length = s->value[1];
1141                         execute_program_begin(&cpu_rom, length);
1142                         c->cpu_flash_driver->write(
1143                                 &(r->cpu_flash),
1144                                 address, length,
1145                                 &cpu_rom
1146                         );
1147                         d->cpu_read(address, length, program_compare);
1148                         const int result = memcmp(program_compare, cpu_rom.data, length);
1149                         execute_program_finish(result);
1150                         cpu_rom.data += length;
1151                         cpu_rom.offset += length;
1152                         
1153                         if((DEBUG==0) && (result != 0)){
1154                                 status = END;
1155                         }
1156                         }
1157                         break;
1158                 case SCRIPT_OPCODE_PPU_COMMAND:
1159                         command_mask(MEMORY_AREA_PPU, s->value[0], s->value[1], s->value[2], &(r->ppu_flash));
1160                         break;
1161                 case SCRIPT_OPCODE_PPU_RAMFIND:
1162                         if(ppu_ramfind(d) == PPU_TEST_RAM){
1163                                 printf("PPU_RAMFIND: charcter RAM found\n");
1164                                 r->ppu_rom.size = 0;
1165                                 status = END;
1166                         }
1167                         break;
1168                 case SCRIPT_OPCODE_PPU_SRAMTEST:{
1169                         const long address = s->value[0];
1170                         const long length = s->value[1];
1171                         printf("PPU_SRAMTEST: 0x%06x-0x%06x ", (int)ppu_rom.offset, (int) (ppu_rom.offset + length) - 1);
1172                         if(sramtest(MEMORY_AREA_PPU, d, address, length) == 0){
1173                                 printf("%s\n", STR_OK);
1174                         }else{
1175                                 printf("%s\n", STR_NG);
1176                                 //status = END;
1177                         }
1178                         }break;
1179                 case SCRIPT_OPCODE_PPU_READ:{
1180                         const long address = s->value[0];
1181                         const long length = s->value[1];
1182                         if(length == 0){
1183                                 /*for mmc2,4 protect.
1184                                 ¤³¤Î¤È¤­¤Ï1byteÆɤ߹þ¤ó¤Ç¡¢¤½¤ÎÆâÍƤϥХåե¡¤Ë¤¤¤ì¤Ê¤¤*/
1185                                 u8 dummy;
1186                                 d->ppu_read(address, 1, &dummy);
1187                         }else{
1188                                 d->ppu_read(address, length, ppu_rom.data);
1189                                 read_result_print(&ppu_rom, length);
1190                         }
1191                         ppu_rom.data += length;
1192                         ppu_rom.offset += length;
1193                         }
1194                         break;
1195                 case SCRIPT_OPCODE_PPU_WRITE:
1196                         if(DEBUG == 1){
1197                                 long data;
1198                                 expression_calc(&s->expression, &data);
1199                                 d->ppu_write(s->value[0], data);
1200                         }
1201                         break;
1202                 case SCRIPT_OPCODE_PPU_PROGRAM:{
1203                         if(c->ppu_flash_driver->id_device == FLASH_ID_DEVICE_DUMMY){
1204                                 break;
1205                         }
1206                         if(programcount_ppu++ == 0){
1207                                 printf(EXECUTE_PROGRAM_PREPARE, ppu_rom.name);
1208                                 fflush(stdout);
1209                                 c->ppu_flash_driver->init(&(r->ppu_flash));
1210                                 printf(EXECUTE_PROGRAM_DONE);
1211                                 fflush(stdout);
1212                         }
1213                         const long address = s->value[0];
1214                         const long length = s->value[1];
1215                         execute_program_begin(&ppu_rom, length);
1216                         c->ppu_flash_driver->write(
1217                                 &(r->ppu_flash),
1218                                 address, length,
1219                                 &ppu_rom
1220                         );
1221                         d->ppu_read(address, length, program_compare);
1222                         const int result = memcmp(program_compare, ppu_rom.data, length);
1223                         execute_program_finish(result);
1224                         ppu_rom.data += length;
1225                         ppu_rom.offset += length;
1226                         
1227                         if((DEBUG==0) && (result != 0)){
1228                                 status = END;
1229                         }
1230                         }
1231                         break;
1232                 case SCRIPT_OPCODE_STEP_START:{
1233                         if(s->value[STEP_START] >= s->value[STEP_END]){
1234                                 status = STEP_THOUGH;
1235                         }else{
1236                                 //¥ë¡¼¥×¤ÎÌá¤êÀè¤Ï¤³¤ÎÌ¿Îá¤Î¼¡¤Ê¤Î¤Ç &s[1]
1237                                 step_new(s->variable, s->value[STEP_START], s->value[STEP_END], s->value[STEP_NEXT], &s[1]);
1238                         }
1239                         }break;
1240                 case SCRIPT_OPCODE_DUMP_END:
1241                         status = END;
1242                         break;
1243                 }
1244                 if(status == END){
1245                         break;
1246                 }else if(status == STEP_THOUGH){
1247                         //¤³¤Ô¤Ú
1248                         int stepcount = 1;
1249                         int end = 0;
1250                         while(s->opcode != SCRIPT_OPCODE_DUMP_END){
1251                                 switch(s->opcode){
1252                                 case SCRIPT_OPCODE_STEP_START:
1253                                         stepcount++;
1254                                         break;
1255                                 case SCRIPT_OPCODE_STEP_END:
1256                                         stepcount--;
1257                                         if(stepcount == 0){
1258                                                 end = 1;
1259                                         }
1260                                         break;
1261                                 }
1262                                 s++;
1263                                 if(end == 1){
1264                                         break;
1265                                 }
1266                         }
1267                         status = DUMP;
1268                 }
1269                 
1270                 if(s->opcode == SCRIPT_OPCODE_STEP_END){
1271                         s = step_end(++s);
1272                 }else{
1273                         s++;
1274                 }
1275         }
1276         d->open_or_close(READER_CLOSE);
1277         if(program_compare != NULL){
1278                 free(program_compare);
1279         }
1280         return OK;
1281 }
1282
1283 void script_load(const struct st_config *c)
1284 {
1285         struct script *s;
1286         {
1287                 int scriptsize = 0;
1288                 char *buf;
1289                 
1290                 buf = buf_load_full(c->script, &scriptsize);
1291                 if(buf == NULL){
1292                         printf("scriptfile open error\n");
1293                         return;
1294                 }
1295                 char **text;
1296                 text = malloc(sizeof(char*) * TEXT_MAXLINE);
1297                 const int text_num = text_load(buf, scriptsize, text);
1298                 if(text_num == 0){
1299                         printf("script line too much\n");
1300                         free(buf);
1301                         free(text);
1302                         return;
1303                 }
1304                 s = malloc(sizeof(struct script) * (text_num + 1));
1305                 //logical_check, execute ¶¦¤Ë s->opcode ¤¬ DUMP_END ¤Ë¤Ê¤ë¤Þ¤Ç³¤±¤ë¡£DUMP_END ¤ÎÆþ¤ì˺¤ìÍѤËËöÈø¤Îscript¤Ëɬ¤º DUMP_END ¤ò¤¤¤ì¤ë
1306                 {
1307                         struct script *k;
1308                         k = s;
1309                         k += text_num;
1310                         k->opcode = SCRIPT_OPCODE_DUMP_END;
1311                 }
1312                 const int error = syntax_check(text, text_num, s, c->mode);
1313                 free(buf);
1314                 free(text);
1315                 if(error != 0){
1316                         free(s);
1317                         return;
1318                 }
1319         }
1320         struct romimage r = {
1321                 .cpu_rom = {
1322                         .size = 0, .offset = 0,
1323                         .data = NULL,
1324                         .attribute = MEMORY_ATTR_NOTUSE,
1325                         .name = "program"
1326                 },
1327                 .ppu_rom = {
1328                         .size = 0, .offset = 0,
1329                         .data = NULL,
1330                         .attribute = MEMORY_ATTR_NOTUSE,
1331                         .name = "charcter"
1332                 },
1333                 .cpu_ram = {
1334                         .size = 0, .offset = 0,
1335                         .data = NULL,
1336                         .attribute = MEMORY_ATTR_NOTUSE,
1337                         .name = STR_REGION_CPU
1338                 },
1339                 //device ¤Ë±þ¤¸¤¿´Ø¿ô¥Ý¥¤¥ó¥¿¤ò flash_order ¤ËÅϤ¹
1340                 .cpu_flash = {
1341                         .command_0000 = 0,
1342                         .command_2aaa = 0,
1343                         .command_5555 = 0,
1344                         .pagesize = c->cpu_flash_driver->pagesize,
1345                         .erase_wait = c->cpu_flash_driver->erase_wait,
1346                         .command_mask = c->cpu_flash_driver->command_mask,
1347                         .flash_write = c->reader->cpu_flash_write,
1348                         .read = c->reader->cpu_read
1349                 },
1350                 .ppu_flash = {
1351                         .command_0000 = 0,
1352                         .command_2aaa = 0,
1353                         .command_5555 = 0,
1354                         .pagesize = c->ppu_flash_driver->pagesize,
1355                         .erase_wait = c->ppu_flash_driver->erase_wait,
1356                         .command_mask = c->ppu_flash_driver->command_mask,
1357                         .flash_write = c->reader->ppu_write,
1358                         .read = c->reader->ppu_read
1359                 },
1360                 .mappernum = 0,
1361                 .mirror = MIRROR_PROGRAMABLE
1362         };
1363         //attribute ¤Ï¤½¤Î struct data ¤ËÂФ·¤Æ¤Î RW ¤Ê¤Î¤ÇÍ×Ãí°Õ
1364         switch(c->mode){
1365         case MODE_ROM_DUMP:
1366                 r.cpu_rom.attribute = MEMORY_ATTR_WRITE;
1367                 r.ppu_rom.attribute = MEMORY_ATTR_WRITE;
1368                 break;
1369         case MODE_RAM_READ:
1370                 r.cpu_ram.attribute = MEMORY_ATTR_WRITE;
1371                 break;
1372         case MODE_RAM_WRITE:
1373                 r.cpu_ram.attribute = MEMORY_ATTR_READ;
1374                 break;
1375         case MODE_ROM_PROGRAM:
1376                 r.cpu_rom.attribute = MEMORY_ATTR_READ;
1377                 r.ppu_rom.attribute = MEMORY_ATTR_READ;
1378                 break;
1379         default:
1380                 assert(0);
1381         }
1382         
1383         if(logical_check(s, c, &r) == 0){
1384                 //dump RAM Îΰè¼èÆÀ
1385                 if(nesbuffer_malloc(&r, c->mode) == NG){
1386                         free(s);
1387                         if((c->mode == MODE_RAM_WRITE) && (r.cpu_ram.data != NULL)){
1388                                 free(r.cpu_ram.data);
1389                         }
1390                         return;
1391                 }
1392                 //script execute!!
1393                 if(execute(s, c, &r) == OK){
1394                         //À®²Ì½ÐÎÏ
1395                         switch(c->mode){
1396                         case MODE_ROM_DUMP:
1397                                 nesfile_create(&r, c->romimage);
1398                                 break;
1399                         case MODE_RAM_READ:
1400                                 backupram_create(&(r.cpu_ram), c->ramimage);
1401                                 break;
1402                         }
1403                 }
1404                 //dump RAM Îΰè²òÊü
1405                 nesbuffer_free(&r, c->mode);
1406                 if((c->mode == MODE_RAM_WRITE) && (r.cpu_ram.data != NULL)){
1407                         free(r.cpu_ram.data);
1408                 }
1409         }
1410         free(s);
1411 }