2 famicom ROM cartridge utility - unagi
5 Copyright (C) 2008 sato_tiff
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.
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.
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
22 * ÊÑ¿ô´ÉÍý¤Î¥°¥í¡¼¥Ð¥ëÃͤò¡¢logical_test(), excute() ¥í¡¼¥«¥ë¤Ë¤·¤¿¤¤
30 #include "reader_master.h"
36 #define OP_PPU_WRITE_ENABLE (0)
45 CPU_WRITE address data -> ÊÑ¿ôŸ³«+±é»»»Ò»ÈÍѲÄǽ
47 STEP_START variable start end step -> for(i=start;i<end;i+=step)
54 struct variable_manage{
58 const struct script *Continue;
63 VARIABLE_MAX = STEP_MAX
66 static const struct variable_manage VARIABLE_INIT = {
68 .start = 0, .end = 0, .step = 0,
72 static struct variable_manage variable_bank[VARIABLE_MAX];
73 static int variable_num = 0;
75 static void variable_init_single(int num)
77 memcpy(&variable_bank[num], &VARIABLE_INIT, sizeof(struct variable_manage));
80 static void variable_init_all(void)
84 for(i = 0; i < VARIABLE_MAX; i++){
85 variable_init_single(i);
89 static int variable_get(char name, long *val)
92 struct variable_manage *v;
94 for(i = 0; i < variable_num; i++){
105 static int expression_calc(const struct st_expression *e, long *val)
108 if(e->left.type == EXPRESSION_TYPE_VARIABLE){
109 if(variable_get(e->left.variable, &left) == NG){
113 left = e->left.value;
115 if(e->operator == OPERATOR_NONE){
119 if(e->right.type == EXPRESSION_TYPE_VARIABLE){
120 if(variable_get(e->right.variable, &right) == NG){
124 right = e->right.value;
130 case OPERATOR_SHIFT_LEFT:
131 *val = left >> right;
134 case OPERATOR_SHIFT_RIGHT:
135 *val = left << right;
151 static int step_new(char name, long start, long end, long step, const struct script *Continue)
153 if(variable_num >= VARIABLE_MAX){
154 return NG; //ÊÑ¿ôÄêµÁ¤¬Â¿¤¹¤®
156 struct variable_manage *v;
159 for(i = 0; i < variable_num; i++){
161 return NG; //ÊÑ¿ô̾½ÅÊ£
172 v->Continue = Continue;
177 static const struct script *step_end(const struct script *Break)
179 //¸½ºß¤Î¥ë¡¼¥×¤ÎÂоÝÊÑ¿ô¤òÆÀ¤ë
180 struct variable_manage *v;
182 v += (variable_num - 1);
188 //¥ë¡¼¥×¤¬½ª¤ï¤Ã¤¿¤Î¤Ç¤½¤ÎÊÑ¿ô¤òÇË´þ¤¹¤ë
189 variable_init_single(variable_num - 1);
194 static int syntax_check_expression(char **word, int word_num, struct st_expression *e)
200 if(value_get(word[0], &(e->left.value)) == OK){
201 e->left.type = EXPRESSION_TYPE_VALUE;
203 e->left.type = EXPRESSION_TYPE_VARIABLE;
204 e->left.variable = word[0][0];
208 e->operator = OPERATOR_NONE;
212 e->operator = operator_get(word[1]);
213 if(e->operator == OPERATOR_ERROR){
221 if(value_get(word[2], &(e->right.value)) == OK){
222 e->right.type = EXPRESSION_TYPE_VALUE;
224 e->right.type = EXPRESSION_TYPE_VARIABLE;
225 e->right.variable = word[2][0];
230 static const char SYNTAX_ERROR_PREFIX[] = "syntax error:";
233 return: error count, ¤³¤³¤Ç¤Ï 0 or 1
235 static int syntax_check_phase(char **word, int word_num, struct script *s, const int mode)
237 int i = sizeof(SCRIPT_SYNTAX) / sizeof(SCRIPT_SYNTAX[0]);
238 const struct script_syntax *syntax;
239 syntax = SCRIPT_SYNTAX;
241 if(strcmp(syntax->name, word[0]) == 0){
244 s->opcode = syntax->script_opcode;
245 if((mode & syntax->permittion) == 0){
246 printf("%s opcode %s not allowed on current mode\n", SYNTAX_ERROR_PREFIX, syntax->name);
251 switch(syntax->compare){
252 case SYNTAX_COMPARE_EQ:
253 compare = (syntax->argc == (word_num - 1));
255 case SYNTAX_COMPARE_GT:
256 compare = (syntax->argc <= (word_num - 1));
260 printf("%s parameter number not much %s\n", SYNTAX_ERROR_PREFIX, word[0]);
264 for(j = 0; j < syntax->argc; j++){
265 switch(syntax->argv_type[j]){
266 case SYNTAX_ARGVTYPE_NULL:
267 printf("%s ARGV_NULL select\n", SYNTAX_ERROR_PREFIX);
269 case SYNTAX_ARGVTYPE_VALUE:
270 if(value_get(word[j + 1], &(s->value[j])) == NG){
271 printf("%s value error %s %s\n", SYNTAX_ERROR_PREFIX, word[0], word[j+1]);
275 case SYNTAX_ARGVTYPE_HV:
276 switch(word[j + 1][0]){
279 s->value[j] = MIRROR_HORIZONAL;
283 s->value[j] = MIRROR_VERTICAL;
287 s->value[j] = MIRROR_PROGRAMABLE;
290 printf("%s unknown scroll mirroring type %s\n", SYNTAX_ERROR_PREFIX, word[j+1]);
294 case SYNTAX_ARGVTYPE_EXPRESSION:
295 s->value[j] = VALUE_EXPRESSION;
296 //Ì¿Îá̾¤Îñ¸ì¤Èñ¸ì¿ô¤ò½ü³°¤·¤ÆÅϤ¹
297 if(syntax_check_expression(&word[j+1], word_num - 2, &s->expression) == NG){
298 printf("%s expression error\n", SYNTAX_ERROR_PREFIX);
301 //²ÄÊѤ˰ú¿ô¤ò¼è¤ë¤Î¤Ç¤³¤³¤Ç½ª¤ï¤ê
303 case SYNTAX_ARGVTYPE_VARIABLE:{
304 const char v = word[j+1][0];
305 if((v >= 'a' && v <= 'z') || (v >= 'A' && v <= 'Z')){
306 s->value[j] = VALUE_VARIABLE;
309 printf("%s variable must use [A-Za-z] %s\n", SYNTAX_ERROR_PREFIX, word[j+1]);
315 //opcode found and ÆþÎÏʸ»ú¼ïÀµ¾ï
321 printf("%s unknown opcode %s\n", SYNTAX_ERROR_PREFIX, word[0]);
328 static int syntax_check(char **text, int text_num, struct script *s, int mode)
332 mode = 1<< mode; //permittion ¤Ï bitflag ¤Ê¤Î¤Ç¤³¤³¤ÇÊÑ´¹¤¹¤ë
334 for(i = 0; i < text_num; i++){
335 char *word[TEXT_MAXWORD];
336 const int n = word_load(text[i], word);
337 if(word[0][0] == '#'){
338 s->opcode = SCRIPT_OPCODE_COMMENT;
340 error += syntax_check_phase(word, n, s, mode);
348 logical_check() ÍÑ¥µ¥Ö´Ø¿ô¤È¥Ç¡¼¥¿
350 static const char LOGICAL_ERROR_PREFIX[] = "logical error:";
352 static inline void logical_print_illgalarea(const char *area, long address)
354 printf("%s illgal %s area $%06x\n", LOGICAL_ERROR_PREFIX, area, (int) address);
357 static inline void logical_print_illgallength(const char *area, long length)
359 printf("%s illgal %s length $%04x\n", LOGICAL_ERROR_PREFIX, area, (int) length);
362 static inline void logical_print_overdump(const char *area, long start, long end)
364 printf("%s %s area over dump $%06x-$%06x\n", LOGICAL_ERROR_PREFIX, area, (int)start ,(int)end);
367 static inline void logical_print_access(const char *area, const char *rw, long addr, long len)
369 printf("%s %s $%04x $%02x\n", area, rw, (int) addr, (int) len);
372 static inline void logical_print_byteerror(const char *area, long data)
374 printf("%s write data byte range over, %s $%x\n", LOGICAL_ERROR_PREFIX, area, (int) data);
377 static int dump_length_conform(const char *name, long logicallength, long configlength)
379 if(configlength != logicallength){
380 printf("%s %s dump length error\n", LOGICAL_ERROR_PREFIX, name);
381 printf("%s: 0x%06x, dump length: 0x%06x\n", name, (int) configlength, (int) logicallength);
386 static inline int is_region_cpurom(long address)
388 return (address >= 0x8000) && (address < 0x10000);
391 static inline int is_region_cpuram(long address)
393 return (address >= 0x6000) && (address < 0x8000);
396 static inline int is_region_ppurom(long address)
398 return (address >= 0) && (address < 0x2000);
401 static inline int is_data_byte(long data)
403 return (data >= 0) && (data < 0x100);
406 //¤³¤ì¤À¤± is ·Ï¤Ç <= ±é»»»Ò¤ò»ÈÍѤ·¤Æ¤¤¤ë¤Î¤ÇÃí°Õ
407 static inline int is_range(long data, long start, long end)
409 return (data >= start) && (data <= end);
411 static const char STR_REGION_CPU[] = "cpu";
412 static const char STR_REGION_PPU[] = "ppu";
413 static const char STR_ACCESS_READ[] = "read";
414 static const char STR_ACCESS_WRITE[] = "write";
419 static int command_mask(const int region, const long address, const long offset, long size, long *data)
422 case MEMORY_AREA_CPU_ROM:
424 case 0x8000: case 0xa000: case 0xc000:
427 printf("%s %s_COMMAND area offset error\n", LOGICAL_ERROR_PREFIX, STR_REGION_CPU);
431 case 0x2000: case 0x4000: case 0x8000:
434 printf("%s %s_COMMAND area mask error\n", LOGICAL_ERROR_PREFIX, STR_REGION_CPU);
438 case MEMORY_AREA_PPU:
440 case 0x0000: case 0x0400: case 0x0800: case 0x0c00:
441 case 0x1000: case 0x1400: case 0x1800: case 0x1c00:
444 printf("%s %s_COMMAND area offset error\n", LOGICAL_ERROR_PREFIX, STR_REGION_CPU);
448 case 0x0400: case 0x0800: case 0x1000: case 0x2000:
451 printf("%s %s_COMMAND area mask error\n", LOGICAL_ERROR_PREFIX, STR_REGION_CPU);
456 assert(0); //unknown memory area
459 case 0: case 0x2aaa: case 0x5555:
462 assert(0); //unknown command address
464 long mask = size - 1;
465 *data = (address & mask) | offset;
469 static int logical_check(const struct script *s, const struct st_config *c, struct romimage *r)
471 long cpu_romsize = 0, cpu_ramsize = 0, ppu_romsize = 0;
472 int imagesize = 0; //for write or program mode
473 int setting = SETTING;
477 while(s->opcode != SCRIPT_OPCODE_DUMP_END){
478 //printf("opcode exec %s\n", SCRIPT_SYNTAX[s->opcode].name);
479 if((setting == DUMP) && (s->opcode < SCRIPT_OPCODE_DUMP_START)){
480 printf("%s config script include DUMPSTART area\n", LOGICAL_ERROR_PREFIX);
484 //romimage open for write or program mode
485 if((imagesize == 0) && (setting == DUMP)){
488 assert(r->cpu_ram.attribute != MEMORY_ATTR_READ);
489 r->cpu_ram.data = buf_load_full(c->ramimage, &imagesize);
490 if(r->cpu_ram.data == NULL){
491 printf("%s RAM image open error\n", LOGICAL_ERROR_PREFIX);
494 }else if(r->cpu_ram.size != imagesize){
495 printf("%s RAM image size is not same\n", LOGICAL_ERROR_PREFIX);
496 free(r->cpu_ram.data);
497 r->cpu_ram.data = NULL;
502 case MODE_ROM_PROGRAM:
503 assert(r->cpu_rom.attribute != MEMORY_ATTR_READ);
504 assert(r->ppu_rom.attribute != MEMORY_ATTR_READ);
505 if(nesfile_load(LOGICAL_ERROR_PREFIX, c->romimage, r)== NG){
517 case SCRIPT_OPCODE_COMMENT:
519 case SCRIPT_OPCODE_MAPPER:
520 r->mappernum = s->value[0];
522 case SCRIPT_OPCODE_MIRROR:
523 r->mirror = s->value[0];
525 case SCRIPT_OPCODE_CPU_ROMSIZE:
526 if(memorysize_check(s->value[0], MEMORY_AREA_CPU_ROM)){
527 printf("%s %s length error\n", LOGICAL_ERROR_PREFIX, OPSTR_CPU_ROMSIZE);
530 r->cpu_rom.size = s->value[0];
532 case SCRIPT_OPCODE_CPU_RAMSIZE:
533 //̤³ÎÄêÍ×ÁǤ¬Â¿¤¤¤Î¤Ç check ¤òÈ´¤¯
534 r->cpu_ram.size = s->value[0];
536 case SCRIPT_OPCODE_CPU_COMMAND_0000:
537 if(command_mask(MEMORY_AREA_CPU_ROM, 0, s->value[0], s->value[1], &(r->cpu_flash.command_0000)) == NG){
541 case SCRIPT_OPCODE_CPU_COMMAND_2AAA:
542 if(command_mask(MEMORY_AREA_CPU_ROM, 0x2aaa, s->value[0], s->value[1], &(r->cpu_flash.command_2aaa)) == NG){
546 case SCRIPT_OPCODE_CPU_COMMAND_5555:
547 if(command_mask(MEMORY_AREA_CPU_ROM, 0x5555, s->value[0], s->value[1], &(r->cpu_flash.command_5555)) == NG){
551 case SCRIPT_OPCODE_PPU_ROMSIZE:
552 if(memorysize_check(s->value[0], MEMORY_AREA_PPU)){
553 printf("%s %s length error\n", LOGICAL_ERROR_PREFIX, OPSTR_PPU_ROMSIZE);
556 r->ppu_rom.size = s->value[0];
558 case SCRIPT_OPCODE_PPU_COMMAND_0000:
559 if(command_mask(MEMORY_AREA_PPU, 0, s->value[0], s->value[1], &(r->ppu_flash.command_0000)) == NG){
563 case SCRIPT_OPCODE_PPU_COMMAND_2AAA:
564 if(command_mask(MEMORY_AREA_PPU, 0x2aaa, s->value[0], s->value[1], &(r->ppu_flash.command_2aaa)) == NG){
568 case SCRIPT_OPCODE_PPU_COMMAND_5555:
569 if(command_mask(MEMORY_AREA_PPU, 0x5555, s->value[0], s->value[1], &(r->ppu_flash.command_5555)) == NG){
573 case SCRIPT_OPCODE_DUMP_START:
576 case SCRIPT_OPCODE_CPU_READ:{
577 const long address = s->value[0];
578 const long length = s->value[1];
579 const long end = address + length - 1;
581 assert(r->cpu_rom.attribute != MEMORY_ATTR_WRITE);
582 //length filter. 0 ¤Ï¤À¤á
583 if(!is_range(length, 1, 0x4000)){
584 logical_print_illgallength(STR_REGION_CPU, length);
588 else if(!is_region_cpurom(address)){
589 logical_print_illgalarea(STR_REGION_CPU, address);
591 }else if(end >= 0x10000){
592 logical_print_overdump(STR_REGION_CPU, address, end);
595 cpu_romsize += length;
599 case SCRIPT_OPCODE_CPU_WRITE:{
600 const long address = s->value[0];
602 if(expression_calc(&s->expression, &data) == NG){
603 printf("%s expression calc error\n", LOGICAL_ERROR_PREFIX);
606 if(address < 0x5000 || address >= 0x10000){
607 logical_print_illgalarea(STR_REGION_CPU, address);
609 }else if(!is_data_byte(data)){
610 logical_print_byteerror(STR_REGION_CPU, data);
616 case SCRIPT_OPCODE_CPU_RAMRW:{
617 const long address = s->value[0];
618 const long length = s->value[1];
619 const long end = address + length - 1;
622 assert(r->cpu_ram.attribute != MEMORY_ATTR_WRITE);
625 assert(r->cpu_ram.attribute = MEMORY_ATTR_READ);
628 //length filter. 0 ¤Ï¤À¤á
629 if(!is_range(length, 1, 0x2000)){
630 logical_print_illgallength(STR_REGION_CPU, length);
634 else if(address < 0x6000 || address >= 0x8000){
635 logical_print_illgalarea(STR_REGION_CPU, address);
637 }else if(end >= 0x8000){
638 logical_print_overdump(STR_REGION_CPU, address, end);
641 cpu_ramsize += length;
645 case SCRIPT_OPCODE_CPU_PROGRAM:{
646 const long address = s->value[0];
647 const long length = s->value[1];
648 const long end = address + length - 1;
650 assert(r->cpu_rom.attribute != MEMORY_ATTR_READ);
651 assert(r->ppu_rom.attribute = MEMORY_ATTR_READ);
653 if(!is_range(length, 0x80, 0x2000)){
654 logical_print_illgallength(STR_REGION_CPU, length);
658 else if(!is_region_cpurom(address)){
659 logical_print_illgalarea(STR_REGION_CPU, address);
661 }else if(end >= 0x10000){
662 logical_print_overdump(STR_REGION_CPU, address, end);
665 cpu_romsize += length;
669 case SCRIPT_OPCODE_PPU_RAMTEST:
670 //¥ë¡¼¥×ÆâÉô¤ËÆþ¤Ã¤Æ¤¿¤é¥¨¥é¡¼
671 if(variable_num != 0){
672 printf("%s PPU_RAMTEST must use outside loop\n", LOGICAL_ERROR_PREFIX);
676 case SCRIPT_OPCODE_PPU_READ:{
677 const long address = s->value[0];
678 const long length = s->value[1];
679 const long end = address + length - 1;
680 assert(r->ppu_rom.attribute != MEMORY_ATTR_WRITE);
681 //length filter. 0 ¤òÍÆǧ¤¹¤ë
682 if(!is_range(length, 0, 0x2000)){
683 logical_print_illgallength(STR_REGION_PPU, length);
687 else if(!is_region_ppurom(address)){
688 logical_print_illgalarea(STR_REGION_PPU, address);
690 }else if (end >= 0x2000){
691 logical_print_overdump(STR_REGION_PPU, address, end);
695 if(is_region_ppurom(address)){
696 ppu_romsize += length;
701 case SCRIPT_OPCODE_PPU_WRITE:{
702 if(OP_PPU_WRITE_ENABLE==0){
705 const long address = s->value[0];
706 const long data = s->value[1];
708 if(!is_region_ppurom(address)){
709 logical_print_illgalarea(STR_REGION_PPU, address);
711 }else if(!is_data_byte(data)){
712 logical_print_byteerror(STR_REGION_PPU, data);
717 case SCRIPT_OPCODE_STEP_START:{
720 const int v = s->value[1];
721 if((v < 0) || (v > 0xff)){
722 printf("%s step start must 0-0xff 0x%x\n", LOGICAL_ERROR_PREFIX, v);
726 for(i = 2; i <4; i++){
727 const int v = s->value[i];
728 if((v < 1) || (v > 0x100)){
729 printf("%s end or next must 1-0x100 0x%x\n", LOGICAL_ERROR_PREFIX, v);
733 //¥ë¡¼¥×¤ÎÌá¤êÀè¤Ï¤³¤ÎÌ¿Îá¤Î¼¡¤Ê¤Î¤Ç s[1]
734 if(step_new(s->variable, s->value[1], s->value[2], s->value[3], &s[1]) == NG){
735 printf("%s step loop too much\n", LOGICAL_ERROR_PREFIX);
741 case SCRIPT_OPCODE_DUMP_END:
748 if(s->opcode == SCRIPT_OPCODE_STEP_END){
749 if(variable_num == 0){
750 printf("%s loop closed, missing STEP_START\n", LOGICAL_ERROR_PREFIX);
761 if(variable_num != 0){
762 printf("%s loop opened, missing STEP_END\n", LOGICAL_ERROR_PREFIX);
765 //dump length conform
766 error += dump_length_conform(OPSTR_CPU_ROMSIZE, cpu_romsize, r->cpu_rom.size);
767 error += dump_length_conform(OPSTR_CPU_RAMSIZE, cpu_ramsize, r->cpu_ram.size);
768 error += dump_length_conform(OPSTR_PPU_ROMSIZE, ppu_romsize, r->ppu_rom.size);
770 //command line config override
771 if(c->mirror != CONFIG_OVERRIDE_UNDEF){
772 r->mirror = c->mirror;
774 if(c->backupram != CONFIG_OVERRIDE_UNDEF){
777 if(c->mapper != CONFIG_OVERRIDE_UNDEF){
778 //program mode ¤Ç mapper Êѹ¹¤òËɤ°
779 assert(c->mode == MODE_ROM_DUMP);
780 r->mappernum = c->mapper;
786 execute() ÍÑ¥µ¥Ö´Ø¿ô¤È¥Ç¡¼¥¿
788 static int execute_connection_check(const struct reader_driver *d)
791 const int testsize = 0x80;
794 master = malloc(testsize);
795 reload = malloc(testsize);
797 d->cpu_read(0xfee0, testsize, master);
799 while(testcount != 0){
800 d->cpu_read(0xfee0, testsize, reload);
801 if(memcmp(master, reload, testsize) != 0){
813 enum {PPU_TEST_RAM, PPU_TEST_ROM};
814 const u8 PPU_TEST_DATA[] = "PPU_TEST_DATA";
818 int ppu_ramtest(const struct reader_driver *d)
820 const int length = sizeof(PPU_TEST_DATA);
821 const long testaddr = 123;
822 //ppu ram data fill 0
825 long address = testaddr;
827 d->ppu_write(address++, 0);
832 //ppu test data write
836 long address = testaddr;
837 data = PPU_TEST_DATA;
839 d->ppu_write(address++, (long) *data);
845 u8 writedata[length];
846 d->ppu_read(testaddr, length, writedata);
847 if(memcmp(writedata, PPU_TEST_DATA, length) == 0){
853 static void readbuffer_print(const struct memory *m, long length)
858 printf("%s 0x%05x:", m->name, m->offset);
864 switch(offset & 0xf){
875 printf("%02x%c", (int) *data, safix);
882 static void checksum_print(const u8 *data, long length)
890 printf(" 0x%06x\n", sum);
893 static void read_result_print(const struct memory *m, long length)
895 readbuffer_print(m, length);
896 checksum_print(m->data, length);
900 const char EXECUTE_ERROR_PREFIX[] = "execute error:";
901 static void execute_cpu_ramrw(const struct reader_driver *d, const struct memory *ram, int mode, long address, long length)
903 if(mode == MODE_RAM_WRITE){
907 writedata = ram->data;
909 d->cpu_6502_write(a++, *writedata);
914 compare = malloc(length);
915 d->cpu_read(address, length, compare);
916 if(memcmp(ram->data, compare, length) == 0){
917 printf("RAM data write success\n");
919 printf("RAM data write failed\n");
923 d->cpu_read(address, length, ram->data);
927 static int execute(const struct script *s, const struct st_config *c, struct romimage *r)
929 const struct reader_driver *const d = c->reader;
930 switch(d->open_or_close(READER_OPEN)){
935 printf("%s driver open error\n", EXECUTE_ERROR_PREFIX);
940 if(execute_connection_check(d) == NG){
941 printf("%s maybe connection error\n", EXECUTE_ERROR_PREFIX);
942 d->open_or_close(READER_CLOSE);
945 struct memory cpu_rom, ppu_rom, cpu_ram;
946 cpu_rom = r->cpu_rom;
947 ppu_rom = r->ppu_rom;
948 cpu_ram = r->cpu_ram;
951 while(s->opcode != SCRIPT_OPCODE_DUMP_END){
954 case SCRIPT_OPCODE_CPU_READ:{
956 const long addr = s->value[0];
957 const long length = s->value[1];
959 d->cpu_read(addr, length, m->data);
960 read_result_print(m, length);
964 case SCRIPT_OPCODE_CPU_WRITE:{
966 expression_calc(&s->expression, &data);
967 d->cpu_6502_write(s->value[0], data);
970 case SCRIPT_OPCODE_CPU_RAMRW:{
971 const long length = s->value[1];
972 execute_cpu_ramrw(d, &cpu_ram, c->mode, s->value[0], length);
973 read_result_print(&cpu_ram, length);
974 cpu_ram.data += length;
975 cpu_ram.offset += length;
978 case SCRIPT_OPCODE_CPU_PROGRAM:{
979 struct flash_order *order;
980 order = &(r->cpu_flash);
981 order->address = s->value[0];
982 order->length = s->value[1];
983 order->data = cpu_rom.data;
984 c->cpu_flash_driver->write(order);
985 cpu_rom.data += order->length;
986 cpu_rom.offset += order->length;
989 case SCRIPT_OPCODE_PPU_RAMTEST:
990 if(ppu_ramtest(d) == PPU_TEST_RAM){
991 printf("PPU_RAMTEST: charcter RAM found\n");
996 case SCRIPT_OPCODE_PPU_READ:{
997 const long address = s->value[0];
998 const long length = s->value[1];
1000 /*for mmc2,4 protect.
1001 ¤³¤Î¤È¤¤Ï1byteÆɤ߹þ¤ó¤Ç¡¢¤½¤ÎÆâÍƤϥХåե¡¤Ë¤¤¤ì¤Ê¤¤*/
1003 d->ppu_read(address, 1, &dummy);
1005 d->ppu_read(address, length, ppu_rom.data);
1006 read_result_print(&ppu_rom, length);
1008 ppu_rom.data += length;
1009 ppu_rom.offset += length;
1012 case SCRIPT_OPCODE_PPU_WRITE:
1013 if(OP_PPU_WRITE_ENABLE == 1){
1014 d->ppu_write(s->value[0], s->value[1]);
1017 case SCRIPT_OPCODE_STEP_START:
1018 //¥ë¡¼¥×¤ÎÌá¤êÀè¤Ï¤³¤ÎÌ¿Îá¤Î¼¡¤Ê¤Î¤Ç &s[1]
1019 step_new(s->variable, s->value[1], s->value[2], s->value[3], &s[1]);
1021 case SCRIPT_OPCODE_DUMP_END:
1028 if(s->opcode == SCRIPT_OPCODE_STEP_END){
1034 d->open_or_close(READER_CLOSE);
1038 void script_load(const struct st_config *c)
1045 buf = buf_load_full(c->script, &scriptsize);
1047 printf("scriptfile open error\n");
1051 text = malloc(sizeof(char*) * TEXT_MAXLINE);
1052 const int text_num = text_load(buf, scriptsize, text);
1054 printf("script line too much\n");
1059 s = malloc(sizeof(struct script) * (text_num + 1));
1060 //logical_check, execute ¶¦¤Ë s->opcode ¤¬ DUMP_END ¤Ë¤Ê¤ë¤Þ¤Ç³¤±¤ë¡£DUMP_END ¤ÎÆþ¤ì˺¤ìÍѤËËöÈø¤Îscript¤Ëɬ¤º DUMP_END ¤ò¤¤¤ì¤ë
1065 k->opcode = SCRIPT_OPCODE_DUMP_END;
1067 const int error = syntax_check(text, text_num, s, c->mode);
1075 struct romimage r = {
1077 .size = 0, .offset = 0,
1079 .attribute = MEMORY_ATTR_NOTUSE,
1080 .name = STR_REGION_CPU
1083 .size = 0, .offset = 0,
1085 .attribute = MEMORY_ATTR_NOTUSE,
1086 .name = STR_REGION_PPU
1089 .size = 0, .offset = 0,
1091 .attribute = MEMORY_ATTR_NOTUSE,
1092 .name = STR_REGION_CPU
1095 .mirror = MIRROR_PROGRAMABLE
1097 //attribute ¤Ï¤½¤Î struct data ¤ËÂФ·¤Æ¤Î RW ¤Ê¤Î¤ÇÍ×Ãí°Õ
1100 r.cpu_rom.attribute = MEMORY_ATTR_WRITE;
1101 r.ppu_rom.attribute = MEMORY_ATTR_WRITE;
1104 r.cpu_ram.attribute = MEMORY_ATTR_WRITE;
1106 case MODE_RAM_WRITE:
1107 r.cpu_ram.attribute = MEMORY_ATTR_READ;
1109 case MODE_ROM_PROGRAM:
1110 r.cpu_rom.attribute = MEMORY_ATTR_READ;
1111 r.ppu_rom.attribute = MEMORY_ATTR_READ;
1117 if(logical_check(s, c, &r) == 0){
1119 if(nesbuffer_malloc(&r, c->mode) == NG){
1121 if((c->mode == MODE_RAM_WRITE) && (r.cpu_ram.data != NULL)){
1122 free(r.cpu_ram.data);
1127 if(execute(s, c, &r) == OK){
1131 nesfile_create(&r, c->romimage);
1134 backupram_create(&(r.cpu_ram), c->ramimage);
1139 nesbuffer_free(&r, c->mode);
1140 if((c->mode == MODE_RAM_WRITE) && (r.cpu_ram.data != NULL)){
1141 free(r.cpu_ram.data);