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"
37 #define OP_PPU_WRITE_ENABLE (0)
46 CPU_WRITE address data -> ÊÑ¿ôŸ³«+±é»»»Ò»ÈÍѲÄǽ
48 STEP_START variable start end step -> for(i=start;i<end;i+=step)
55 struct variable_manage{
59 const struct script *Continue;
64 VARIABLE_MAX = STEP_MAX
67 static const struct variable_manage VARIABLE_INIT = {
69 .start = 0, .end = 0, .step = 0,
73 static struct variable_manage variable_bank[VARIABLE_MAX];
74 static int variable_num = 0;
76 static void variable_init_single(int num)
78 memcpy(&variable_bank[num], &VARIABLE_INIT, sizeof(struct variable_manage));
81 static void variable_init_all(void)
85 for(i = 0; i < VARIABLE_MAX; i++){
86 variable_init_single(i);
90 static int variable_get(char name, long *val)
93 struct variable_manage *v;
95 for(i = 0; i < variable_num; i++){
106 static int expression_calc(const struct st_expression *e, long *val)
109 if(e->left.type == EXPRESSION_TYPE_VARIABLE){
110 if(variable_get(e->left.variable, &left) == NG){
114 left = e->left.value;
116 if(e->operator == OPERATOR_NONE){
120 if(e->right.type == EXPRESSION_TYPE_VARIABLE){
121 if(variable_get(e->right.variable, &right) == NG){
125 right = e->right.value;
131 case OPERATOR_SHIFT_LEFT:
132 *val = left >> right;
135 case OPERATOR_SHIFT_RIGHT:
136 *val = left << right;
152 static int step_new(char name, long start, long end, long step, const struct script *Continue)
154 if(variable_num >= VARIABLE_MAX){
155 return NG; //ÊÑ¿ôÄêµÁ¤¬Â¿¤¹¤®
157 struct variable_manage *v;
160 for(i = 0; i < variable_num; i++){
162 return NG; //ÊÑ¿ô̾½ÅÊ£
173 v->Continue = Continue;
178 static const struct script *step_end(const struct script *Break)
180 //¸½ºß¤Î¥ë¡¼¥×¤ÎÂоÝÊÑ¿ô¤òÆÀ¤ë
181 struct variable_manage *v;
183 v += (variable_num - 1);
189 //¥ë¡¼¥×¤¬½ª¤ï¤Ã¤¿¤Î¤Ç¤½¤ÎÊÑ¿ô¤òÇË´þ¤¹¤ë
190 variable_init_single(variable_num - 1);
195 static int syntax_check_expression(char **word, int word_num, struct st_expression *e)
201 if(value_get(word[0], &(e->left.value)) == OK){
202 e->left.type = EXPRESSION_TYPE_VALUE;
204 e->left.type = EXPRESSION_TYPE_VARIABLE;
205 e->left.variable = word[0][0];
209 e->operator = OPERATOR_NONE;
213 e->operator = operator_get(word[1]);
214 if(e->operator == OPERATOR_ERROR){
222 if(value_get(word[2], &(e->right.value)) == OK){
223 e->right.type = EXPRESSION_TYPE_VALUE;
225 e->right.type = EXPRESSION_TYPE_VARIABLE;
226 e->right.variable = word[2][0];
231 static const char SYNTAX_ERROR_PREFIX[] = "syntax error:";
234 return: error count, ¤³¤³¤Ç¤Ï 0 or 1
236 static int syntax_check_phase(char **word, int word_num, struct script *s, const int mode)
238 int i = sizeof(SCRIPT_SYNTAX) / sizeof(SCRIPT_SYNTAX[0]);
239 const struct script_syntax *syntax;
240 syntax = SCRIPT_SYNTAX;
242 if(strcmp(syntax->name, word[0]) == 0){
245 s->opcode = syntax->script_opcode;
246 if((mode & syntax->permittion) == 0){
247 printf("%s opcode %s not allowed on current mode\n", SYNTAX_ERROR_PREFIX, syntax->name);
252 switch(syntax->compare){
253 case SYNTAX_COMPARE_EQ:
254 compare = (syntax->argc == (word_num - 1));
256 case SYNTAX_COMPARE_GT:
257 compare = (syntax->argc <= (word_num - 1));
261 printf("%s parameter number not much %s\n", SYNTAX_ERROR_PREFIX, word[0]);
265 for(j = 0; j < syntax->argc; j++){
266 switch(syntax->argv_type[j]){
267 case SYNTAX_ARGVTYPE_NULL:
268 printf("%s ARGV_NULL select\n", SYNTAX_ERROR_PREFIX);
270 case SYNTAX_ARGVTYPE_VALUE:
271 if(value_get(word[j + 1], &(s->value[j])) == NG){
272 printf("%s value error %s %s\n", SYNTAX_ERROR_PREFIX, word[0], word[j+1]);
276 case SYNTAX_ARGVTYPE_HV:
277 switch(word[j + 1][0]){
280 s->value[j] = MIRROR_HORIZONAL;
284 s->value[j] = MIRROR_VERTICAL;
288 s->value[j] = MIRROR_PROGRAMABLE;
291 printf("%s unknown scroll mirroring type %s\n", SYNTAX_ERROR_PREFIX, word[j+1]);
295 case SYNTAX_ARGVTYPE_EXPRESSION:
296 s->value[j] = VALUE_EXPRESSION;
297 //Ì¿Îá̾¤Îñ¸ì¤Èñ¸ì¿ô¤ò½ü³°¤·¤ÆÅϤ¹
298 if(syntax_check_expression(&word[j+1], word_num - 2, &s->expression) == NG){
299 printf("%s expression error\n", SYNTAX_ERROR_PREFIX);
302 //²ÄÊѤ˰ú¿ô¤ò¼è¤ë¤Î¤Ç¤³¤³¤Ç½ª¤ï¤ê
304 case SYNTAX_ARGVTYPE_VARIABLE:{
305 const char v = word[j+1][0];
306 if((v >= 'a' && v <= 'z') || (v >= 'A' && v <= 'Z')){
307 s->value[j] = VALUE_VARIABLE;
310 printf("%s variable must use [A-Za-z] %s\n", SYNTAX_ERROR_PREFIX, word[j+1]);
316 //opcode found and ÆþÎÏʸ»ú¼ïÀµ¾ï
322 printf("%s unknown opcode %s\n", SYNTAX_ERROR_PREFIX, word[0]);
329 static int syntax_check(char **text, int text_num, struct script *s, int mode)
333 mode = 1<< mode; //permittion ¤Ï bitflag ¤Ê¤Î¤Ç¤³¤³¤ÇÊÑ´¹¤¹¤ë
335 for(i = 0; i < text_num; i++){
336 char *word[TEXT_MAXWORD];
337 const int n = word_load(text[i], word);
338 if(word[0][0] == '#'){
339 s->opcode = SCRIPT_OPCODE_COMMENT;
341 error += syntax_check_phase(word, n, s, mode);
349 logical_check() ÍÑ¥µ¥Ö´Ø¿ô¤È¥Ç¡¼¥¿
351 static const char LOGICAL_ERROR_PREFIX[] = "logical error:";
353 static inline void logical_print_illgalarea(const char *area, long address)
355 printf("%s illgal %s area $%06x\n", LOGICAL_ERROR_PREFIX, area, (int) address);
358 static inline void logical_print_illgallength(const char *area, long length)
360 printf("%s illgal %s length $%04x\n", LOGICAL_ERROR_PREFIX, area, (int) length);
363 static inline void logical_print_overdump(const char *area, long start, long end)
365 printf("%s %s area over dump $%06x-$%06x\n", LOGICAL_ERROR_PREFIX, area, (int)start ,(int)end);
368 static inline void logical_print_access(const char *area, const char *rw, long addr, long len)
370 printf("%s %s $%04x $%02x\n", area, rw, (int) addr, (int) len);
373 static inline void logical_print_byteerror(const char *area, long data)
375 printf("%s write data byte range over, %s $%x\n", LOGICAL_ERROR_PREFIX, area, (int) data);
378 static int dump_length_conform(const char *name, long logicallength, long configlength)
380 if(configlength != logicallength){
381 printf("%s %s dump length error\n", LOGICAL_ERROR_PREFIX, name);
382 printf("%s: 0x%06x, dump length: 0x%06x\n", name, (int) configlength, (int) logicallength);
387 static inline int is_region_cpurom(long address)
389 return (address >= 0x8000) && (address < 0x10000);
392 static inline int is_region_cpuram(long address)
394 return (address >= 0x6000) && (address < 0x8000);
397 static inline int is_region_ppurom(long address)
399 return (address >= 0) && (address < 0x2000);
402 static inline int is_data_byte(long data)
404 return (data >= 0) && (data < 0x100);
407 //¤³¤ì¤À¤± is ·Ï¤Ç <= ±é»»»Ò¤ò»ÈÍѤ·¤Æ¤¤¤ë¤Î¤ÇÃí°Õ
408 static inline int is_range(long data, long start, long end)
410 return (data >= start) && (data <= end);
412 static const char STR_REGION_CPU[] = "cpu";
413 static const char STR_REGION_PPU[] = "ppu";
414 static const char STR_ACCESS_READ[] = "read";
415 static const char STR_ACCESS_WRITE[] = "write";
420 static int command_mask(const int region, const long address, const long offset, long size, long *data)
423 case MEMORY_AREA_CPU_ROM:
425 case 0x8000: case 0xa000: case 0xc000:
428 printf("%s %s_COMMAND area offset error\n", LOGICAL_ERROR_PREFIX, STR_REGION_CPU);
432 case 0x2000: case 0x4000: case 0x8000:
435 printf("%s %s_COMMAND area mask error\n", LOGICAL_ERROR_PREFIX, STR_REGION_CPU);
439 case MEMORY_AREA_PPU:
441 case 0x0000: case 0x0400: case 0x0800: case 0x0c00:
442 case 0x1000: case 0x1400: case 0x1800: case 0x1c00:
445 printf("%s %s_COMMAND area offset error\n", LOGICAL_ERROR_PREFIX, STR_REGION_CPU);
449 case 0x0400: case 0x0800: case 0x1000: case 0x2000:
452 printf("%s %s_COMMAND area mask error\n", LOGICAL_ERROR_PREFIX, STR_REGION_CPU);
457 assert(0); //unknown memory area
460 case 0: case 0x2aaa: case 0x5555:
463 assert(0); //unknown command address
465 long mask = size - 1;
466 *data = (address & mask) | offset;
470 static int logical_check(const struct script *s, const struct st_config *c, struct romimage *r)
472 long cpu_romsize = 0, cpu_ramsize = 0, ppu_romsize = 0;
473 int imagesize = 0; //for write or program mode
474 int setting = SETTING;
478 while(s->opcode != SCRIPT_OPCODE_DUMP_END){
479 //printf("opcode exec %s\n", SCRIPT_SYNTAX[s->opcode].name);
480 if((setting == DUMP) && (s->opcode < SCRIPT_OPCODE_DUMP_START)){
481 printf("%s config script include DUMPSTART area\n", LOGICAL_ERROR_PREFIX);
485 //romimage open for write or program mode
486 if((imagesize == 0) && (setting == DUMP)){
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 if(nesfile_load(LOGICAL_ERROR_PREFIX, c->romimage, r)== NG){
515 case SCRIPT_OPCODE_COMMENT:
517 case SCRIPT_OPCODE_MAPPER:
518 r->mappernum = s->value[0];
520 case SCRIPT_OPCODE_MIRROR:
521 r->mirror = s->value[0];
523 case SCRIPT_OPCODE_CPU_ROMSIZE:
524 if(memorysize_check(s->value[0], MEMORY_AREA_CPU_ROM)){
525 printf("%s %s length error\n", LOGICAL_ERROR_PREFIX, OPSTR_CPU_ROMSIZE);
528 r->cpu_rom.size = s->value[0];
530 case SCRIPT_OPCODE_CPU_RAMSIZE:
531 //̤³ÎÄêÍ×ÁǤ¬Â¿¤¤¤Î¤Ç check ¤òÈ´¤¯
532 r->cpu_ram.size = s->value[0];
534 case SCRIPT_OPCODE_CPU_COMMAND_0000:
535 if(command_mask(MEMORY_AREA_CPU_ROM, 0, s->value[0], s->value[1], &(r->cpu_flash.command_0000)) == NG){
539 case SCRIPT_OPCODE_CPU_COMMAND_2AAA:
540 if(command_mask(MEMORY_AREA_CPU_ROM, 0x2aaa, s->value[0], s->value[1], &(r->cpu_flash.command_2aaa)) == NG){
544 case SCRIPT_OPCODE_CPU_COMMAND_5555:
545 if(command_mask(MEMORY_AREA_CPU_ROM, 0x5555, s->value[0], s->value[1], &(r->cpu_flash.command_5555)) == NG){
549 case SCRIPT_OPCODE_PPU_ROMSIZE:
550 if(memorysize_check(s->value[0], MEMORY_AREA_PPU)){
551 printf("%s %s length error\n", LOGICAL_ERROR_PREFIX, OPSTR_PPU_ROMSIZE);
554 r->ppu_rom.size = s->value[0];
556 case SCRIPT_OPCODE_PPU_COMMAND_0000:
557 if(command_mask(MEMORY_AREA_PPU, 0, s->value[0], s->value[1], &(r->ppu_flash.command_0000)) == NG){
561 case SCRIPT_OPCODE_PPU_COMMAND_2AAA:
562 if(command_mask(MEMORY_AREA_PPU, 0x2aaa, s->value[0], s->value[1], &(r->ppu_flash.command_2aaa)) == NG){
566 case SCRIPT_OPCODE_PPU_COMMAND_5555:
567 if(command_mask(MEMORY_AREA_PPU, 0x5555, s->value[0], s->value[1], &(r->ppu_flash.command_5555)) == NG){
571 case SCRIPT_OPCODE_DUMP_START:
574 case SCRIPT_OPCODE_CPU_READ:{
575 const long address = s->value[0];
576 const long length = s->value[1];
577 const long end = address + length - 1;
578 //length filter. 0 ¤Ï¤À¤á
579 if(!is_range(length, 1, 0x4000)){
580 logical_print_illgallength(STR_REGION_CPU, length);
584 else if(address < 0x8000 || address >= 0x10000){
585 logical_print_illgalarea(STR_REGION_CPU, address);
587 }else if(end >= 0x10000){
588 logical_print_overdump(STR_REGION_CPU, address, end);
591 //$7fff-$8000¤òϢ³¤Ç¤Þ¤¿¤¬¤»¤Ê¤¤
592 else if((address <= 0x7fff) && (end >= 0x8000)){
593 printf("%s address cannot over $7fff-$8000. divide CPU_READ.\n", LOGICAL_ERROR_PREFIX);
597 if(is_region_cpuram(address)){
598 cpu_ramsize += length;
599 }else if(is_region_cpurom(address)){
600 cpu_romsize += length;
605 case SCRIPT_OPCODE_CPU_WRITE:{
606 const long address = s->value[0];
608 if(expression_calc(&s->expression, &data) == NG){
609 printf("%s expression calc error\n", LOGICAL_ERROR_PREFIX);
612 if(address < 0x5000 || address >= 0x10000){
613 logical_print_illgalarea(STR_REGION_CPU, address);
615 }else if(!is_data_byte(data)){
616 logical_print_byteerror(STR_REGION_CPU, data);
622 case SCRIPT_OPCODE_CPU_RAMRW:{
623 const long address = s->value[0];
624 const long length = s->value[1];
625 const long end = address + length - 1;
626 //length filter. 0 ¤Ï¤À¤á
627 if(!is_range(length, 1, 0x2000)){
628 logical_print_illgallength(STR_REGION_CPU, length);
632 else if(address < 0x6000 || address >= 0x8000){
633 logical_print_illgalarea(STR_REGION_CPU, address);
635 }else if(end >= 0x8000){
636 logical_print_overdump(STR_REGION_CPU, address, end);
639 cpu_ramsize += length;
643 case SCRIPT_OPCODE_CPU_PROGRAM:{
644 const long address = s->value[0];
645 const long length = s->value[1];
646 const long end = address + length - 1;
648 if(!is_range(length, 0x80, 0x2000)){
649 logical_print_illgallength(STR_REGION_CPU, length);
653 else if(!is_region_cpurom(address)){
654 logical_print_illgalarea(STR_REGION_CPU, address);
656 }else if(end >= 0x10000){
657 logical_print_overdump(STR_REGION_CPU, address, end);
660 cpu_romsize += length;
664 case SCRIPT_OPCODE_PPU_RAMTEST:
665 //¥ë¡¼¥×ÆâÉô¤ËÆþ¤Ã¤Æ¤¿¤é¥¨¥é¡¼
666 if(variable_num != 0){
667 printf("%s PPU_RAMTEST must use outside loop\n", LOGICAL_ERROR_PREFIX);
671 case SCRIPT_OPCODE_PPU_READ:{
672 const long address = s->value[0];
673 const long length = s->value[1];
674 const long end = address + length - 1;
675 //length filter. 0 ¤òÍÆǧ¤¹¤ë
676 if(!is_range(length, 0, 0x2000)){
677 logical_print_illgallength(STR_REGION_PPU, length);
681 else if(!is_region_ppurom(address)){
682 logical_print_illgalarea(STR_REGION_PPU, address);
684 }else if (end >= 0x2000){
685 logical_print_overdump(STR_REGION_PPU, address, end);
689 if(is_region_ppurom(address)){
690 ppu_romsize += length;
695 case SCRIPT_OPCODE_PPU_WRITE:{
696 if(OP_PPU_WRITE_ENABLE==0){
699 const long address = s->value[0];
700 const long data = s->value[1];
702 if(!is_region_ppurom(address)){
703 logical_print_illgalarea(STR_REGION_PPU, address);
705 }else if(!is_data_byte(data)){
706 logical_print_byteerror(STR_REGION_PPU, data);
711 case SCRIPT_OPCODE_STEP_START:{
714 const int v = s->value[1];
715 if((v < 0) || (v > 0xff)){
716 printf("%s step start must 0-0xff 0x%x\n", LOGICAL_ERROR_PREFIX, v);
720 for(i = 2; i <4; i++){
721 const int v = s->value[i];
722 if((v < 1) || (v > 0x100)){
723 printf("%s end or next must 1-0x100 0x%x\n", LOGICAL_ERROR_PREFIX, v);
727 //¥ë¡¼¥×¤ÎÌá¤êÀè¤Ï¤³¤ÎÌ¿Îá¤Î¼¡¤Ê¤Î¤Ç s[1]
728 if(step_new(s->variable, s->value[1], s->value[2], s->value[3], &s[1]) == NG){
729 printf("%s step loop too much\n", LOGICAL_ERROR_PREFIX);
735 case SCRIPT_OPCODE_DUMP_END:
742 if(s->opcode == SCRIPT_OPCODE_STEP_END){
743 if(variable_num == 0){
744 printf("%s loop closed, missing STEP_START\n", LOGICAL_ERROR_PREFIX);
755 if(variable_num != 0){
756 printf("%s loop opened, missing STEP_END\n", LOGICAL_ERROR_PREFIX);
759 //dump length conform
760 error += dump_length_conform(OPSTR_CPU_ROMSIZE, cpu_romsize, r->cpu_rom.size);
761 error += dump_length_conform(OPSTR_CPU_RAMSIZE, cpu_ramsize, r->cpu_ram.size);
762 error += dump_length_conform(OPSTR_PPU_ROMSIZE, ppu_romsize, r->ppu_rom.size);
764 //command line config override
765 if(c->mirror != CONFIG_OVERRIDE_UNDEF){
766 r->mirror = c->mirror;
768 if(c->backupram != CONFIG_OVERRIDE_UNDEF){
771 if(c->mapper != CONFIG_OVERRIDE_UNDEF){
772 r->mappernum = c->mapper;
778 execute() ÍÑ¥µ¥Ö´Ø¿ô¤È¥Ç¡¼¥¿
780 static int execute_connection_check(const struct reader_driver *d)
783 const int testsize = 0x80;
786 master = malloc(testsize);
787 reload = malloc(testsize);
789 d->cpu_read(0xfee0, testsize, master);
791 while(testcount != 0){
792 d->cpu_read(0xfee0, testsize, reload);
793 if(memcmp(master, reload, testsize) != 0){
805 enum {PPU_TEST_RAM, PPU_TEST_ROM};
806 const u8 PPU_TEST_DATA[] = "PPU_TEST_DATA";
810 int ppu_ramtest(const struct reader_driver *d)
812 const int length = sizeof(PPU_TEST_DATA);
813 const long testaddr = 123;
814 //ppu ram data fill 0
817 long address = testaddr;
819 d->ppu_write(address++, 0);
824 //ppu test data write
828 long address = testaddr;
829 data = PPU_TEST_DATA;
831 d->ppu_write(address++, (long) *data);
837 u8 writedata[length];
838 d->ppu_read(testaddr, length, writedata);
839 if(memcmp(writedata, PPU_TEST_DATA, length) == 0){
845 static void readbuffer_print(const struct memory *m, long length)
850 printf("%s 0x%05x:", m->name, m->offset);
856 switch(offset & 0xf){
867 printf("%02x%c", (int) *data, safix);
874 static void checksum_print(const u8 *data, long length)
882 printf(" 0x%06x\n", sum);
885 static void read_result_print(const struct memory *m, long length)
887 readbuffer_print(m, length);
888 checksum_print(m->data, length);
892 const char EXECUTE_ERROR_PREFIX[] = "execute error:";
893 static void execute_cpu_ramrw(const struct reader_driver *d, const struct memory *ram, int mode, long address, long length)
895 if(mode == MODE_RAM_WRITE){
899 writedata = ram->data;
901 d->cpu_6502_write(a++, *writedata);
906 compare = malloc(length);
907 d->cpu_read(address, length, compare);
908 if(memcmp(ram->data, compare, length) == 0){
909 printf("RAM data write success\n");
911 printf("RAM data write failed\n");
915 d->cpu_read(address, length, ram->data);
919 static int execute(const struct script *s, const struct st_config *c, struct romimage *r)
921 const struct reader_driver *d;
923 const int gg = giveio_start();
932 printf("%s Can't Access Direct IO %d\n", EXECUTE_ERROR_PREFIX, gg);
935 if(execute_connection_check(d) == NG){
936 printf("%s maybe connection error\n", EXECUTE_ERROR_PREFIX);
939 struct memory cpu_rom, ppu_rom, cpu_ram;
940 cpu_rom = r->cpu_rom;
941 ppu_rom = r->ppu_rom;
942 cpu_ram = r->cpu_ram;
945 while(s->opcode != SCRIPT_OPCODE_DUMP_END){
948 case SCRIPT_OPCODE_CPU_READ:{
950 const long addr = s->value[0];
951 const long length = s->value[1];
953 if(is_region_cpuram(addr)){
956 d->cpu_read(addr, length, m->data);
957 read_result_print(m, length);
961 case SCRIPT_OPCODE_CPU_WRITE:{
963 expression_calc(&s->expression, &data);
964 d->cpu_6502_write(s->value[0], data);
967 case SCRIPT_OPCODE_CPU_RAMRW:{
968 const long length = s->value[1];
969 execute_cpu_ramrw(d, &cpu_ram, c->mode, s->value[0], length);
970 read_result_print(&cpu_ram, length);
971 cpu_ram.data += length;
972 cpu_ram.offset += length;
975 case SCRIPT_OPCODE_CPU_PROGRAM:{
976 struct flash_order *order;
977 order = &(r->cpu_flash);
978 order->address = s->value[0];
979 order->length = s->value[1];
980 order->data = cpu_rom.data;
981 c->cpu_flash_driver->write(order);
982 cpu_rom.data += order->length;
983 cpu_rom.offset += order->length;
986 case SCRIPT_OPCODE_PPU_RAMTEST:
987 if(ppu_ramtest(d) == PPU_TEST_RAM){
988 printf("PPU_RAMTEST: charcter RAM found\n");
993 case SCRIPT_OPCODE_PPU_READ:{
994 const long address = s->value[0];
995 const long length = s->value[1];
997 /*for mmc2,4 protect.
998 ¤³¤Î¤È¤¤Ï1byteÆɤ߹þ¤ó¤Ç¡¢¤½¤ÎÆâÍƤϥХåե¡¤Ë¤¤¤ì¤Ê¤¤*/
1000 d->ppu_read(address, 1, &dummy);
1002 d->ppu_read(address, length, ppu_rom.data);
1003 read_result_print(&ppu_rom, length);
1005 ppu_rom.data += length;
1006 ppu_rom.offset += length;
1009 case SCRIPT_OPCODE_PPU_WRITE:
1010 if(OP_PPU_WRITE_ENABLE == 1){
1011 d->ppu_write(s->value[0], s->value[1]);
1014 case SCRIPT_OPCODE_STEP_START:
1015 //¥ë¡¼¥×¤ÎÌá¤êÀè¤Ï¤³¤ÎÌ¿Îá¤Î¼¡¤Ê¤Î¤Ç &s[1]
1016 step_new(s->variable, s->value[1], s->value[2], s->value[3], &s[1]);
1018 case SCRIPT_OPCODE_DUMP_END:
1025 if(s->opcode == SCRIPT_OPCODE_STEP_END){
1031 if(gg != GIVEIO_WIN95){
1032 giveio_stop(GIVEIO_STOP);
1037 void script_load(const struct st_config *c)
1044 buf = buf_load_full(c->script, &scriptsize);
1046 printf("scriptfile open error\n");
1050 text = malloc(sizeof(char*) * TEXT_MAXLINE);
1051 const int text_num = text_load(buf, scriptsize, text);
1053 printf("script line too much\n");
1058 s = malloc(sizeof(struct script) * (text_num + 1));
1059 //logical_check, execute ¶¦¤Ë s->opcode ¤¬ DUMP_END ¤Ë¤Ê¤ë¤Þ¤Ç³¤±¤ë¡£DUMP_END ¤ÎÆþ¤ì˺¤ìÍѤËËöÈø¤Îscript¤Ëɬ¤º DUMP_END ¤ò¤¤¤ì¤ë
1064 k->opcode = SCRIPT_OPCODE_DUMP_END;
1066 const int error = syntax_check(text, text_num, s, c->mode);
1074 struct romimage r = {
1076 .size = 0, .offset = 0,
1078 .name = STR_REGION_CPU
1081 .size = 0, .offset = 0,
1083 .name = STR_REGION_PPU
1086 .size = 0, .offset = 0,
1088 .name = STR_REGION_CPU
1091 .mirror = MIRROR_PROGRAMABLE
1093 if(logical_check(s, c, &r) == 0){
1095 if(nesbuffer_malloc(&r, c->mode) == NG){
1097 if((c->mode == MODE_RAM_WRITE) && (r.cpu_ram.data != NULL)){
1098 free(r.cpu_ram.data);
1103 if(execute(s, c, &r) == OK){
1107 nesfile_create(&r, c->romimage);
1110 backupram_create(&(r.cpu_ram), c->ramimage);
1115 nesbuffer_free(&r, c->mode);
1116 if((c->mode == MODE_RAM_WRITE) && (r.cpu_ram.data != NULL)){
1117 free(r.cpu_ram.data);