2 famicom ROM cartridge dump program - unagi
6 * Ê̤ÎÆɤ߽Ф·¥Ï¡¼¥É¤ËÂбþ¤·¤¿¤È¤¤Ï cpu_read ¤Ê¤É¤ò´Ø¿ô¥Ý¥¤¥ó¥¿¤Ë¤Þ¤È¤á¤¿ struct ¤òÍÑ°Õ¤·¤Æ¼Â¹Ô¤¹¤ë
7 * ÊÑ¿ô´ÉÍý¤Î¥°¥í¡¼¥Ð¥ëÃͤò¡¢logical_test(), excute() ¥í¡¼¥«¥ë¤Ë¤·¤¿¤¤
8 * RAM ¥¢¥¯¥»¥¹¤¬¤Ç¤¼¡Âè¡¢RAM Æɤ߽Ф·¥¹¥¯¥ê¥×¥È¤âÀ߷פ¹¤ë
15 #include "driver_master.h"
21 #define OP_PPU_WRITE_ENABLE (0)
30 CPU_WRITE address data -> ÊÑ¿ôŸ³«+±é»»»Ò»ÈÍѲÄǽ
32 STEP_START variable start end step -> for(i=start;i<end;i+=step)
44 SYNTAX_ARGVTYPE_VALUE,
46 SYNTAX_ARGVTYPE_EXPRESSION,
47 SYNTAX_ARGVTYPE_VARIABLE
56 SCRIPT_OPCODE_CPU_ROMSIZE,
57 SCRIPT_OPCODE_CPU_RAMSIZE,
58 SCRIPT_OPCODE_PPU_ROMSIZE,
59 SCRIPT_OPCODE_DUMP_START,
60 SCRIPT_OPCODE_CPU_READ,
61 SCRIPT_OPCODE_CPU_WRITE,
62 SCRIPT_OPCODE_CPU_RAMRW,
63 SCRIPT_OPCODE_PPU_RAMTEST,
64 SCRIPT_OPCODE_PPU_READ,
65 SCRIPT_OPCODE_PPU_WRITE,
66 SCRIPT_OPCODE_STEP_START,
67 SCRIPT_OPCODE_STEP_END,
68 SCRIPT_OPCODE_DUMP_END,
69 SCRIPT_OPCODE_COMMENT,
72 static const char OPSTR_CPU_ROMSIZE[] = "CPU_ROMSIZE";
73 static const char OPSTR_CPU_RAMSIZE[] = "CPU_RAMSIZE";
74 static const char OPSTR_PPU_ROMSIZE[] = "PPU_ROMSIZE";
75 static const char OPSTR_CPU_RAMRW[] = "CPU_RAMRW";
76 static const struct script_syntax SCRIPT_SYNTAX[] = {
77 {"MAPPER", SCRIPT_OPCODE_MAPPER, 1, SYNTAX_COMPARE_EQ, {SYNTAX_ARGVTYPE_VALUE, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL}},
78 {"MIRROR", SCRIPT_OPCODE_MIRROR, 1, SYNTAX_COMPARE_EQ, {SYNTAX_ARGVTYPE_HV, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL}},
79 {OPSTR_CPU_ROMSIZE, SCRIPT_OPCODE_CPU_ROMSIZE, 1, SYNTAX_COMPARE_EQ, {SYNTAX_ARGVTYPE_VALUE, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL}},
80 {OPSTR_CPU_RAMSIZE, SCRIPT_OPCODE_CPU_RAMSIZE, 1, SYNTAX_COMPARE_EQ, {SYNTAX_ARGVTYPE_VALUE, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL}},
81 {OPSTR_PPU_ROMSIZE, SCRIPT_OPCODE_PPU_ROMSIZE, 1, SYNTAX_COMPARE_EQ, {SYNTAX_ARGVTYPE_VALUE, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL}},
82 {"DUMP_START", SCRIPT_OPCODE_DUMP_START, 0, SYNTAX_COMPARE_EQ, {SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL}},
83 {"CPU_READ", SCRIPT_OPCODE_CPU_READ, 2, SYNTAX_COMPARE_EQ, {SYNTAX_ARGVTYPE_VALUE, SYNTAX_ARGVTYPE_VALUE, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL}},
84 {"CPU_WRITE", SCRIPT_OPCODE_CPU_WRITE, 2, SYNTAX_COMPARE_GT, {SYNTAX_ARGVTYPE_VALUE, SYNTAX_ARGVTYPE_EXPRESSION, SYNTAX_ARGVTYPE_EXPRESSION, SYNTAX_ARGVTYPE_EXPRESSION}},
85 {OPSTR_CPU_RAMRW, SCRIPT_OPCODE_CPU_RAMRW, 2, SYNTAX_COMPARE_EQ, {SYNTAX_ARGVTYPE_VALUE, SYNTAX_ARGVTYPE_VALUE, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL}},
86 {"PPU_RAMTEST", SCRIPT_OPCODE_PPU_RAMTEST, 0, SYNTAX_COMPARE_EQ, {SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL}},
87 {"PPU_READ", SCRIPT_OPCODE_PPU_READ, 2, SYNTAX_COMPARE_EQ, {SYNTAX_ARGVTYPE_VALUE, SYNTAX_ARGVTYPE_VALUE, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL}},
88 #if OP_PPU_WRITE_ENABLE==1
89 {"PPU_WRITE", SCRIPT_OPCODE_PPU_WRITE, 2, SYNTAX_COMPARE_EQ, {SYNTAX_ARGVTYPE_VALUE, SYNTAX_ARGVTYPE_VALUE, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL}},
91 {"STEP_START", SCRIPT_OPCODE_STEP_START, 4, SYNTAX_COMPARE_EQ, {SYNTAX_ARGVTYPE_VARIABLE, SYNTAX_ARGVTYPE_VALUE, SYNTAX_ARGVTYPE_VALUE, SYNTAX_ARGVTYPE_VALUE}},
92 {"STEP_END", SCRIPT_OPCODE_STEP_END, 0, SYNTAX_COMPARE_EQ, {SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL}},
93 {"DUMP_END", SCRIPT_OPCODE_DUMP_END, 0, SYNTAX_COMPARE_EQ, {SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL, SYNTAX_ARGVTYPE_NULL}}
97 struct variable_manage{
101 const struct script *Continue;
106 VARIABLE_MAX = STEP_MAX
109 static const struct variable_manage VARIABLE_INIT = {
113 static struct variable_manage variable_bank[VARIABLE_MAX];
114 static int variable_num = 0;
116 static void variable_init_single(int num)
118 memcpy(&variable_bank[num], &VARIABLE_INIT, sizeof(struct variable_manage));
121 static void variable_init_all(void)
125 for(i = 0; i < VARIABLE_MAX; i++){
126 variable_init_single(i);
130 static int variable_get(char name, long *val)
133 struct variable_manage *v;
135 for(i = 0; i < variable_num; i++){
146 static int expression_calc(const struct st_expression *e, long *val)
149 if(e->left.type == EXPRESSION_TYPE_VARIABLE){
150 if(variable_get(e->left.variable, &left) == NG){
154 left = e->left.value;
156 if(e->operator == OPERATOR_NONE){
160 if(e->right.type == EXPRESSION_TYPE_VARIABLE){
161 if(variable_get(e->right.variable, &right) == NG){
165 right = e->right.value;
171 case OPERATOR_SHIFT_LEFT:
172 *val = left >> right;
175 case OPERATOR_SHIFT_RIGHT:
176 *val = left << right;
192 static int step_new(char name, long start, long end, long step, const struct script *Continue)
194 if(variable_num >= VARIABLE_MAX){
195 return NG; //ÊÑ¿ôÄêµÁ¤¬Â¿¤¹¤®
197 struct variable_manage *v;
200 for(i = 0; i < variable_num; i++){
202 return NG; //ÊÑ¿ô̾½ÅÊ£
213 v->Continue = Continue;
218 static const struct script *step_end(const struct script *Break)
220 //¸½ºß¤Î¥ë¡¼¥×¤ÎÂоÝÊÑ¿ô¤òÆÀ¤ë
221 struct variable_manage *v;
223 v += (variable_num - 1);
229 //¥ë¡¼¥×¤¬½ª¤ï¤Ã¤¿¤Î¤Ç¤½¤ÎÊÑ¿ô¤òÇË´þ¤¹¤ë
230 variable_init_single(variable_num - 1);
235 static int syntax_check_expression(char **word, int word_num, struct st_expression *e)
241 if(value_get(word[0], &(e->left.value)) == OK){
242 e->left.type = EXPRESSION_TYPE_VALUE;
244 e->left.type = EXPRESSION_TYPE_VARIABLE;
245 e->left.variable = word[0][0];
249 e->operator = OPERATOR_NONE;
253 e->operator = operator_get(word[1]);
254 if(e->operator == OPERATOR_ERROR){
262 if(value_get(word[2], &(e->right.value)) == OK){
263 e->right.type = EXPRESSION_TYPE_VALUE;
265 e->right.type = EXPRESSION_TYPE_VARIABLE;
266 e->right.variable = word[2][0];
271 static const char SYNTAX_ERROR_PREFIX[] = "syntax error:";
273 static int syntax_check_phase(char **word, int word_num, struct script *s)
275 int i = sizeof(SCRIPT_SYNTAX) / sizeof(SCRIPT_SYNTAX[0]);
276 const struct script_syntax *syntax;
277 syntax = SCRIPT_SYNTAX;
279 if(strcmp(syntax->name, word[0]) == 0){
282 s->opcode = syntax->script_opcode;
285 switch(syntax->compare){
286 case SYNTAX_COMPARE_EQ:
287 compare = (syntax->argc == (word_num - 1));
289 case SYNTAX_COMPARE_GT:
290 compare = (syntax->argc <= (word_num - 1));
294 printf("%s parameter number not much %s\n", SYNTAX_ERROR_PREFIX, word[0]);
298 for(j = 0; j < syntax->argc; j++){
299 switch(syntax->argv_type[j]){
300 case SYNTAX_ARGVTYPE_NULL:
301 printf("%s ARGV_NULL select\n", SYNTAX_ERROR_PREFIX);
303 case SYNTAX_ARGVTYPE_VALUE:
304 if(value_get(word[j + 1], &(s->value[j])) == NG){
305 printf("%s value error %s %s\n", SYNTAX_ERROR_PREFIX, word[0], word[j+1]);
309 case SYNTAX_ARGVTYPE_HV:
310 switch(word[j + 1][0]){
313 s->value[j] = MIRROR_HORIZONAL;
317 s->value[j] = MIRROR_VERTICAL;
321 s->value[j] = MIRROR_PROGRAMABLE;
324 printf("%s unknown scroll mirroring type %s\n", SYNTAX_ERROR_PREFIX, word[j+1]);
328 case SYNTAX_ARGVTYPE_EXPRESSION:
329 s->value[j] = VALUE_EXPRESSION;
330 //Ì¿Îá̾¤Îñ¸ì¤Èñ¸ì¿ô¤ò½ü³°¤·¤ÆÅϤ¹
331 if(syntax_check_expression(&word[j+1], word_num - 2, &s->expression) == NG){
332 printf("%s expression error\n", SYNTAX_ERROR_PREFIX);
335 //²ÄÊѤ˰ú¿ô¤ò¼è¤ë¤Î¤Ç¤³¤³¤Ç½ª¤ï¤ê
337 case SYNTAX_ARGVTYPE_VARIABLE:{
338 const char v = word[j+1][0];
339 if((v >= 'a' && v <= 'z') || (v >= 'A' && v <= 'Z')){
340 s->value[j] = VALUE_VARIABLE;
343 printf("%s variable must use [A-Za-z] %s\n", SYNTAX_ERROR_PREFIX, word[j+1]);
354 printf("%s unknown opcode %s\n", SYNTAX_ERROR_PREFIX, word[0]);
358 static int syntax_check(char **text, int text_num, struct script *s)
363 for(i = 0; i < text_num; i++){
364 char *word[TEXT_MAXWORD];
365 const int n = word_load(text[i], word);
366 if(word[0][0] == '#'){
367 s->opcode = SCRIPT_OPCODE_COMMENT;
369 error += syntax_check_phase(word, n, s);
377 logical_check() ÍÑ¥µ¥Ö´Ø¿ô¤È¥Ç¡¼¥¿
379 static const char LOGICAL_ERROR_PREFIX[] = "logical error:";
381 static inline void logical_print_illgalarea(const char *area, long address)
383 printf("%s illgal %s area $%06x\n", LOGICAL_ERROR_PREFIX, area, (int) address);
386 static inline void logical_print_illgallength(const char *area, long length)
388 printf("%s illgal %s length $%04x\n", LOGICAL_ERROR_PREFIX, area, (int) length);
391 static inline void logical_print_overdump(const char *area, long start, long end)
393 printf("%s %s area over dump $%06x-$%06x\n", LOGICAL_ERROR_PREFIX, area, (int)start ,(int)end);
396 static inline void logical_print_access(const char *area, const char *rw, long addr, long len)
398 printf("%s %s $%04x $%02x\n", area, rw, (int) addr, (int) len);
401 static inline void logical_print_byteerror(const char *area, long data)
403 printf("%s write data byte range over, %s $%x\n", LOGICAL_ERROR_PREFIX, area, (int) data);
406 static int dump_length_conform(const char *name, long logicallength, long configlength)
408 if(configlength != logicallength){
409 printf("%s %s dump length error\n", LOGICAL_ERROR_PREFIX, name);
410 printf("%s: 0x%06x, dump length: 0x%06x\n", name, (int) configlength, (int) logicallength);
415 static inline int is_region_cpurom(long address)
417 return (address >= 0x8000) && (address < 0x10000);
420 static inline int is_region_cpuram(long address)
422 return (address >= 0x6000) && (address < 0x8000);
425 static inline int is_region_ppurom(long address)
427 return (address >= 0) && (address < 0x2000);
430 static inline int is_data_byte(long data)
432 return (data >= 0) && (data < 0x100);
435 //¤³¤ì¤À¤± is ·Ï¤Ç <= ±é»»»Ò¤ò»ÈÍѤ·¤Æ¤¤¤ë¤Î¤ÇÃí°Õ
436 static inline int is_range(long data, long start, long end)
438 return (data >= start) && (data <= end);
440 static const char STR_REGION_CPU[] = "cpu";
441 static const char STR_REGION_PPU[] = "ppu";
442 static const char STR_ACCESS_READ[] = "read";
443 static const char STR_ACCESS_WRITE[] = "write";
448 static int logical_check(const struct script *s, const struct st_config *c, struct romimage *r)
450 long cpu_romsize = 0, cpu_ramsize = 0, ppu_romsize = 0;
451 int setting = SETTING, error = 0;
454 while(s->opcode != SCRIPT_OPCODE_DUMP_END){
455 //printf("opcode exec %s\n", SCRIPT_SYNTAX[s->opcode].name);
456 if((setting == DUMP) && (s->opcode < SCRIPT_OPCODE_DUMP_START)){
457 printf("%s config script include DUMPSTART area\n", LOGICAL_ERROR_PREFIX);
461 case SCRIPT_OPCODE_COMMENT:
463 case SCRIPT_OPCODE_MAPPER:
464 r->mappernum = s->value[0];
466 case SCRIPT_OPCODE_MIRROR:
467 r->mirror = s->value[0];
469 case SCRIPT_OPCODE_CPU_ROMSIZE:
470 r->cpu_rom.size = s->value[0];
472 case SCRIPT_OPCODE_CPU_RAMSIZE:
473 r->cpu_ram_read.size = s->value[0];
474 r->cpu_ram_write.size = s->value[0];
476 case SCRIPT_OPCODE_PPU_ROMSIZE:
477 r->ppu_rom.size = s->value[0];
479 case SCRIPT_OPCODE_DUMP_START:
482 case SCRIPT_OPCODE_CPU_READ:{
483 const long address = s->value[0];
484 const long length = s->value[1];
485 const long end = address + length - 1;
486 //length filter. 0 ¤Ï¤À¤á
487 if(!is_range(length, 1, 0x4000)){
488 logical_print_illgallength(STR_REGION_CPU, length);
492 else if(address < 0x6000 || address >= 0x10000){
493 logical_print_illgalarea(STR_REGION_CPU, address);
495 }else if(end >= 0x10000){
496 logical_print_overdump(STR_REGION_CPU, address, end);
499 //$7fff-$8000¤òϢ³¤Ç¤Þ¤¿¤¬¤»¤Ê¤¤
500 else if((address <= 0x7fff) && (end >= 0x8000)){
501 printf("%s address cannot over $7fff-$8000. divide CPU_READ.\n", LOGICAL_ERROR_PREFIX);
505 if(is_region_cpuram(address)){
506 cpu_ramsize += length;
507 }else if(is_region_cpurom(address)){
508 cpu_romsize += length;
513 case SCRIPT_OPCODE_CPU_WRITE:{
514 const long address = s->value[0];
516 if(expression_calc(&s->expression, &data) == NG){
517 printf("%s expression calc error\n", LOGICAL_ERROR_PREFIX);
520 if(address < 0x5000 || address >= 0x10000){
521 logical_print_illgalarea(STR_REGION_CPU, address);
523 }else if(!is_data_byte(data)){
524 logical_print_byteerror(STR_REGION_CPU, data);
530 case SCRIPT_OPCODE_CPU_RAMRW:{
531 if(c->mode == MODE_ROM_DUMP){
532 printf("%s cannot use %s on ROMDUMP mode\n", LOGICAL_ERROR_PREFIX, OPSTR_CPU_RAMRW);
535 const long address = s->value[0];
536 const long length = s->value[1];
537 const long end = address + length - 1;
538 //length filter. 0 ¤Ï¤À¤á
539 if(!is_range(length, 1, 0x2000)){
540 logical_print_illgallength(STR_REGION_CPU, length);
544 else if(address < 0x6000 || address >= 0x8000){
545 logical_print_illgalarea(STR_REGION_CPU, address);
547 }else if(end >= 0x8000){
548 logical_print_overdump(STR_REGION_CPU, address, end);
551 cpu_ramsize += length;
552 if(c->mode == MODE_RAM_WRITE){
553 r->cpu_ram_write.data = buf_load_full(c->ramimage_write, &(r->cpu_ram_write.size));
554 if(r->cpu_ram_write.data == NULL){
555 printf("%s RAM image open error\n.", LOGICAL_ERROR_PREFIX);
557 }else if(r->cpu_ram_read.size != r->cpu_ram_write.size){
558 printf("%s RAM image size is not same.\n", LOGICAL_ERROR_PREFIX);
559 free(r->cpu_ram_write.data);
560 r->cpu_ram_write.data = NULL;
567 case SCRIPT_OPCODE_PPU_RAMTEST:
568 //logical check ¤Ç¤Ï¤Ê¤Ë¤â¤·¤Ê¤¤
570 case SCRIPT_OPCODE_PPU_READ:{
571 const long address = s->value[0];
572 const long length = s->value[1];
573 const long end = address + length - 1;
574 //length filter. 0 ¤òÍÆǧ¤¹¤ë
575 if(!is_range(length, 0, 0x2000)){
576 logical_print_illgallength(STR_REGION_PPU, length);
580 else if(!is_region_ppurom(address)){
581 logical_print_illgalarea(STR_REGION_PPU, address);
583 }else if (end >= 0x2000){
584 logical_print_overdump(STR_REGION_PPU, address, end);
588 if(is_region_ppurom(address)){
589 ppu_romsize += length;
594 case SCRIPT_OPCODE_PPU_WRITE:{
595 if(OP_PPU_WRITE_ENABLE==0){
598 const long address = s->value[0];
599 const long data = s->value[1];
601 if(!is_region_ppurom(address)){
602 logical_print_illgalarea(STR_REGION_PPU, address);
604 }else if(!is_data_byte(data)){
605 logical_print_byteerror(STR_REGION_PPU, data);
610 case SCRIPT_OPCODE_STEP_START:{
613 const int v = s->value[1];
614 if((v < 0) || (v > 0xff)){
615 printf("%s step start must 0-0xff 0x%x\n", LOGICAL_ERROR_PREFIX, v);
619 for(i = 2; i <4; i++){
620 const int v = s->value[i];
621 if((v < 1) || (v > 0x100)){
622 printf("%s end or next must 1-0x100 0x%x\n", LOGICAL_ERROR_PREFIX, v);
626 //¥ë¡¼¥×¤ÎÌá¤êÀè¤Ï¤³¤ÎÌ¿Îá¤Î¼¡¤Ê¤Î¤Ç s[1]
627 if(step_new(s->variable, s->value[1], s->value[2], s->value[3], &s[1]) == NG){
628 printf("%s step loop too much\n", LOGICAL_ERROR_PREFIX);
634 case SCRIPT_OPCODE_DUMP_END:
641 if(s->opcode == SCRIPT_OPCODE_STEP_END){
642 if(variable_num == 0){
643 printf("%s loop closed, missing STEP_START\n", LOGICAL_ERROR_PREFIX);
654 if(variable_num != 0){
655 printf("%s loop opened, missing STEP_END\n", LOGICAL_ERROR_PREFIX);
658 //dump length conform
659 error += dump_length_conform(OPSTR_CPU_ROMSIZE, cpu_romsize, r->cpu_rom.size);
660 error += dump_length_conform(OPSTR_CPU_RAMSIZE, cpu_ramsize, r->cpu_ram_read.size);
661 error += dump_length_conform(OPSTR_PPU_ROMSIZE, ppu_romsize, r->ppu_rom.size);
663 //command line config override
664 if(c->mirror != CONFIG_OVERRIDE_UNDEF){
665 r->mirror = c->mirror;
667 if(c->backupram != CONFIG_OVERRIDE_UNDEF){
670 if(c->mapper != CONFIG_OVERRIDE_UNDEF){
671 r->mappernum = c->mapper;
677 execute() ÍÑ¥µ¥Ö´Ø¿ô¤È¥Ç¡¼¥¿
679 static int execute_connection_check(const struct driver *d)
682 const int testsize = 0x80;
685 master = malloc(testsize);
686 reload = malloc(testsize);
688 d->cpu_read(0xfee0, testsize, master);
690 while(testcount != 0){
691 d->cpu_read(0xfee0, testsize, reload);
692 if(memcmp(master, reload, testsize) != 0){
704 enum {PPU_TEST_RAM, PPU_TEST_ROM};
705 const u8 PPU_TEST_DATA[] = "PPU_TEST_DATA";
709 int ppu_ramtest(const struct driver *d)
711 const int length = sizeof(PPU_TEST_DATA);
712 const long testaddr = 123;
713 //ppu ram data fill 0
716 long address = testaddr;
718 d->ppu_write(address++, 0);
723 //ppu test data write
727 long address = testaddr;
728 data = PPU_TEST_DATA;
730 d->ppu_write(address++, (long) *data);
736 u8 writedata[length];
737 d->ppu_read(testaddr, length, writedata);
738 if(memcmp(writedata, PPU_TEST_DATA, length) == 0){
744 static void readbuffer_print(const struct memory *m, long length)
749 printf("%s 0x%05x:", m->name, m->offset);
755 switch(offset & 0xf){
766 printf("%02x%c", (int) *data, safix);
773 static void checksum_print(const u8 *data, long length)
781 printf(" 0x%06x\n", sum);
785 static void read_result_print(const struct memory *m, long length)
787 readbuffer_print(m, length);
788 checksum_print(m->data, length);
791 const char EXECUTE_ERROR_PREFIX[] = "execute error:";
792 static void execute_cpu_ramrw(const struct driver *d, const struct memory *w, struct memory *r, int mode, long address, long length)
794 if(mode == MODE_RAM_WRITE){
800 d->cpu_write(a++, *writedata);
805 d->cpu_read(address, length, r->data);
806 if(mode == MODE_RAM_READ){
809 if(memcmp(r->data, w->data, length) == 0){
810 printf("RAM data write success.\n");
812 printf("RAM data write failed.\n");
816 static int execute(const struct script *s, const struct st_config *c, struct romimage *r)
818 const struct driver *d;
819 d = driver_get(c->driver);
821 printf("%s driver not found.\n", EXECUTE_ERROR_PREFIX);
824 const int gg = giveio_start();
833 printf("%s Can't Access Direct IO %d\n", EXECUTE_ERROR_PREFIX, gg);
836 if(execute_connection_check(d) == NG){
837 printf("%s maybe connection error.\n", EXECUTE_ERROR_PREFIX);
840 struct memory cpu_rom, ppu_rom, cpu_ram_read, cpu_ram_write;
841 cpu_rom = r->cpu_rom;
842 ppu_rom = r->ppu_rom;
843 cpu_ram_read = r->cpu_ram_read;
844 cpu_ram_write = r->cpu_ram_write;
847 while(s->opcode != SCRIPT_OPCODE_DUMP_END){
850 case SCRIPT_OPCODE_CPU_READ:{
852 const long addr = s->value[0];
853 const long length = s->value[1];
855 if(is_region_cpuram(addr)){
858 d->cpu_read(addr, length, m->data);
859 read_result_print(m, length);
863 case SCRIPT_OPCODE_CPU_WRITE:{
865 expression_calc(&s->expression, &data);
866 d->cpu_write(s->value[0], data);
869 case SCRIPT_OPCODE_CPU_RAMRW:{
870 const long length = s->value[1];
871 execute_cpu_ramrw(d, &cpu_ram_write, &cpu_ram_read, c->mode, s->value[0], length);
872 read_result_print(&cpu_ram_read, length);
873 cpu_ram_read.data += length;
874 cpu_ram_read.offset += length;
875 if(c->mode == MODE_RAM_WRITE){
876 cpu_ram_write.data += length;
877 cpu_ram_write.offset += length;
881 case SCRIPT_OPCODE_PPU_RAMTEST:
882 if(ppu_ramtest(d) == PPU_TEST_RAM){
883 printf("PPU_RAMTEST: charcter RAM found\n");
888 case SCRIPT_OPCODE_PPU_READ:{
889 const long address = s->value[0];
890 const long length = s->value[1];
892 /*for mmc2,4 protect.
893 ¤³¤Î¤È¤¤Ï1byteÆɤ߹þ¤ó¤Ç¡¢¤½¤ÎÆâÍƤϥХåե¡¤Ë¤¤¤ì¤Ê¤¤*/
895 d->ppu_read(address, 1, &dummy);
897 d->ppu_read(address, length, ppu_rom.data);
898 read_result_print(&ppu_rom, length);
900 ppu_rom.data += length;
901 ppu_rom.offset += length;
904 case SCRIPT_OPCODE_PPU_WRITE:
905 if(OP_PPU_WRITE_ENABLE == 1){
906 d->ppu_write(s->value[0], s->value[1]);
909 case SCRIPT_OPCODE_STEP_START:
910 //¥ë¡¼¥×¤ÎÌá¤êÀè¤Ï¤³¤ÎÌ¿Îá¤Î¼¡¤Ê¤Î¤Ç &s[1]
911 step_new(s->variable, s->value[1], s->value[2], s->value[3], &s[1]);
913 case SCRIPT_OPCODE_DUMP_END:
920 if(s->opcode == SCRIPT_OPCODE_STEP_END){
926 if(gg != GIVEIO_WIN95){
927 giveio_stop(GIVEIO_STOP);
932 void script_load(const struct st_config *c)
939 buf = buf_load_full(c->script, &scriptsize);
941 printf("scriptfile open error\n");
944 char *text[TEXT_MAXLINE];
945 const int text_num = text_load(buf, scriptsize, text);
947 printf("script line too much\n");
951 s = malloc(sizeof(struct script) * (text_num + 1));
952 //logical_check, execute ¶¦¤Ë s->opcode ¤¬ DUMP_END ¤Ë¤Ê¤ë¤Þ¤Ç³¤±¤ë¡£DUMP_END ¤ÎÆþ¤ì˺¤ìÍѤËËöÈø¤Îscript¤Ëɬ¤º DUMP_END ¤ò¤¤¤ì¤ë
957 k->opcode = SCRIPT_OPCODE_DUMP_END;
959 const int error = syntax_check(text, text_num, s);
966 struct romimage r = {
989 mirror: MIRROR_PROGRAMABLE
991 if(logical_check(s, c, &r) == 0){
993 if(nesbuffer_malloc(&r) == NG){
995 if(r.cpu_ram_write.data != NULL){
996 free(r.cpu_ram_write.data);
1001 if(execute(s, c, &r) == OK){
1005 nesfile_create(&r, c->romimage);
1008 backupram_create(&(r.cpu_ram_read), c->ramimage_read);
1014 if(r.cpu_ram_write.data != NULL){
1015 free(r.cpu_ram_write.data);