2 famicom ROM cartridge utility - unagi
5 Copyright (C) 2008-2009 ±·³«È¯¶¨Æ±Áȹç
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() ¥í¡¼¥«¥ë¤Ë¤·¤¿¤¤
28 #include "memory_manage.h"
31 #include "reader_master.h"
35 #include "script_syntax.h"
46 CPU_WRITE address data -> ÊÑ¿ôŸ³«+±é»»»Ò»ÈÍѲÄǽ
48 STEP_START variable start end step -> for(i=start;i<end;i+=step)
55 //step ¤ÎÊÑ¿ô¤Ï¾®Ê¸»ú¤Î a-z ¤Ç¤Ï¤¸¤Þ¤ë¤³¤È¡£2ʸ»úÌܰʹߤÏ̵»ë¤¹¤ë
56 struct variable_manage{
60 const struct script *Continue;
65 VARIABLE_MAX = STEP_MAX
68 static const struct variable_manage VARIABLE_INIT = {
70 .start = 0, .end = 0, .step = 0,
74 static struct variable_manage variable_bank[VARIABLE_MAX];
75 static int variable_num = 0;
77 static void variable_init_single(int num)
79 memcpy(&variable_bank[num], &VARIABLE_INIT, sizeof(struct variable_manage));
82 static void variable_init_all(void)
86 for(i = 0; i < VARIABLE_MAX; i++){
87 variable_init_single(i);
91 static int variable_get(char name, long *val)
94 struct variable_manage *v;
96 for(i = 0; i < variable_num; i++){
106 static int expression_value_get(const struct st_variable *v, long *data)
108 if(v->type == EXPRESSION_TYPE_VARIABLE){
109 if(variable_get(v->variable, data) == NG){
119 static int expression_calc(const struct st_expression *e, long *val)
122 if(expression_value_get(&e->left, &left) == NG){
125 if(e->operator == OPERATOR_NONE){
129 if(expression_value_get(&e->right, &right) == NG){
136 case OPERATOR_SHIFT_LEFT:
137 *val = left >> right;
140 case OPERATOR_SHIFT_RIGHT:
141 *val = left << right;
157 static int step_new(char name, long start, long end, long step, const struct script *Continue)
159 if(variable_num >= VARIABLE_MAX){
160 return NG; //ÊÑ¿ôÄêµÁ¤¬Â¿¤¹¤®
162 struct variable_manage *v;
165 for(i = 0; i < variable_num; i++){
167 return NG; //ÊÑ¿ô̾½ÅÊ£
178 v->Continue = Continue;
183 static const struct script *step_end(const struct script *Break)
185 //¸½ºß¤Î¥ë¡¼¥×¤ÎÂоÝÊÑ¿ô¤òÆÀ¤ë
186 struct variable_manage *v;
188 v += (variable_num - 1);
194 //¥ë¡¼¥×¤¬½ª¤ï¤Ã¤¿¤Î¤Ç¤½¤ÎÊÑ¿ô¤òÇË´þ¤¹¤ë
195 variable_init_single(variable_num - 1);
200 //int syntax_check(char **text, int text_num, struct script *s, int mode);
202 logical_check() ÍÑ¥µ¥Ö´Ø¿ô¤È¥Ç¡¼¥¿
204 static const char LOGICAL_ERROR_PREFIX[] = "logical error:";
206 SCRIPT_PPUSIZE_0 = 0,
207 SCRIPT_MEMORYSIZE = 10,
209 struct logical_romsize{
210 const struct script *data[SCRIPT_MEMORYSIZE], *constant;
213 static int logical_flashsize_set(int region, struct logical_romsize *l, const struct script *s)
215 //PPU Íѥǡ¼¥¿¤Î 0 ¤Ï size 0, Äê¿ô 0 ¤È¤·¤ÆͽÌ󤵤ì¤Æ¤ª¤ê¡¢0¤Î¾ì¹ç¤Ï¤³¤³¤ò¾å½ñ¤¤¹¤ë
216 if((region == MEMORY_AREA_PPU) && (s->value[0] == 0)){
217 l->data[SCRIPT_PPUSIZE_0] = s;
220 if(l->count >= SCRIPT_MEMORYSIZE){
222 opstr = OPSTR_CPU_ROMSIZE; //warning Âкö
224 case MEMORY_AREA_CPU_ROM:
225 opstr = OPSTR_CPU_ROMSIZE;
227 case MEMORY_AREA_PPU:
228 opstr = OPSTR_PPU_ROMSIZE;
233 printf("%d:%s %s override count over\n", s->line, LOGICAL_ERROR_PREFIX, opstr);
236 l->data[l->count] = s;
241 static int logical_flashsize_get(long transtype, long size, struct logical_romsize *l)
244 for(i = 0; i < l->count; i++){
245 const struct script *s;
247 if((s->value[0] == size) && (
248 (s->value[1] == transtype) ||
249 (s->value[1] == VALUE_TRANSTYPE_FULL)
253 }else if((s->value[0] == size) && (s->value[1] == VALUE_TRANSTYPE_EMPTY)){
258 printf("%s flashsize not found\n", LOGICAL_ERROR_PREFIX);
262 static long constant_get(long val, const struct script *cpu, const struct script *ppu)
265 case VALUE_CONTANT_CPU_STEP_START:
266 return cpu->value[2];
267 case VALUE_CONTANT_CPU_STEP_END:
268 return cpu->value[3];
269 case VALUE_CONTANT_PPU_STEP_START:
270 return ppu->value[2];
271 case VALUE_CONTANT_PPU_STEP_END:
272 return ppu->value[3];
278 static void logical_print_capacityerror(int line, const char *area)
280 printf("%d:%s %s area flash memory capacity error\n", line, LOGICAL_ERROR_PREFIX, area);
283 static inline void logical_print_illgalarea(int line, const char *area, long address)
285 printf("%d:%s illgal %s area $%06x\n", line, LOGICAL_ERROR_PREFIX, area, (int) address);
288 static inline void logical_print_illgallength(int line, const char *area, long length)
290 printf("%d:%s illgal %s length $%04x\n", line, LOGICAL_ERROR_PREFIX, area, (int) length);
293 static inline void logical_print_overdump(int line, const char *area, long start, long end)
295 printf("%d:%s %s area over dump $%06x-$%06x\n", line, LOGICAL_ERROR_PREFIX, area, (int)start ,(int)end);
298 static inline void logical_print_access(int line, const char *area, const char *rw, long addr, long len)
300 printf("%d:%s %s $%04x $%02x\n", line, area, rw, (int) addr, (int) len);
303 static inline void logical_print_byteerror(int line, const char *area, long data)
305 printf("%d:%s write data byte range over, %s $%x\n", line, LOGICAL_ERROR_PREFIX, area, (int) data);
308 static int dump_length_conform(const char *name, long logicallength, long configlength)
310 if(configlength != logicallength){
311 printf("%s %s dump length error\n", LOGICAL_ERROR_PREFIX, name);
312 printf("%s: 0x%06x, dump length: 0x%06x\n", name, (int) configlength, (int) logicallength);
317 static inline int is_region_cpurom(long address)
319 return (address >= 0x8000) && (address < 0x10000);
322 static inline int is_region_cpuram(long address)
324 return (address >= 0x6000) && (address < 0x8000);
327 static inline int is_region_ppurom(long address)
329 return (address >= 0) && (address < 0x2000);
332 static inline int is_data_byte(long data)
334 return (data >= 0) && (data < 0x100);
337 //¤³¤ì¤À¤± is ·Ï¤Ç <= ±é»»»Ò¤ò»ÈÍѤ·¤Æ¤¤¤ë¤Î¤ÇÃí°Õ
338 static inline int is_range(long data, long start, long end)
340 return (data >= start) && (data <= end);
342 static const char STR_REGION_CPU[] = "cpu";
343 static const char STR_REGION_PPU[] = "ppu";
344 static const char STR_ACCESS_READ[] = "read";
345 static const char STR_ACCESS_WRITE[] = "write";
348 SETTING, DUMP, END, STEP_THOUGH
350 static int command_mask(const int region, const long address, const long offset, long size, struct flash_order *f)
352 const char *str_region = STR_REGION_CPU;
353 if(region == MEMORY_AREA_PPU){
354 str_region = STR_REGION_PPU;
357 case MEMORY_AREA_CPU_ROM:
359 case 0x8000: case 0xa000: case 0xc000:
362 printf("%s %s_COMMAND area offset error\n", LOGICAL_ERROR_PREFIX, str_region);
366 case 0x2000: case 0x4000: case 0x8000:
369 printf("%s %s_COMMAND area mask error\n", LOGICAL_ERROR_PREFIX, str_region);
373 case MEMORY_AREA_PPU:
375 case 0x0000: case 0x0400: case 0x0800: case 0x0c00:
376 case 0x1000: case 0x1400: case 0x1800: case 0x1c00:
379 printf("%s %s_COMMAND area offset error\n", LOGICAL_ERROR_PREFIX, str_region);
383 case 0x0400: case 0x0800: case 0x1000: case 0x2000:
386 printf("%s %s_COMMAND area mask error\n", LOGICAL_ERROR_PREFIX, str_region);
391 assert(0); //unknown memory area
394 const long mask = size - 1;
395 const long data = (address & mask) | offset;
398 f->command_0000 = data;
400 case 0x2aaa: case 0x02aa:
401 f->command_2aaa = data;
403 case 0x5555: case 0x0555:
404 f->command_5555 = data;
407 printf("%s %s_COMMAND unknown commnand address\n", LOGICAL_ERROR_PREFIX, str_region);
414 STEP_VALIABLE = 0, STEP_START, STEP_END, STEP_NEXT,
417 static const struct script SCRIPT_PPU_ROMSIZE_0 = {
418 .opcode = SCRIPT_OPCODE_PPU_ROMSIZE,
420 .value = {0, VALUE_TRANSTYPE_EMPTY, 0, 0},
421 //.expression, .variable ̤ÄêµÁ
424 static int logical_check(const struct script *s, const struct st_config *c, struct romimage *r)
426 //(CPU|PPU)_(READ|PROGRAM|RAMRW) ¤Î length ²Ã»»ÃÍ
427 long cpu_romsize = 0, cpu_ramsize = 0, ppu_romsize = 0;
428 //DUMP_START ľ¸å¤Ë ROM or RAM image ¤ò³«¤¯¥Õ¥é¥°
429 //use program mode or ram write mode
430 int imagesize = 0; //for write or program mode
431 int status = SETTING;
432 //override (CPU|PPU)_ROMSIZE pointer. Program mode only
433 struct logical_romsize script_cpu_flashsize = {
437 struct logical_romsize script_ppu_flashsize = {
441 script_ppu_flashsize.data[0] = &SCRIPT_PPU_ROMSIZE_0;
442 //logical error count. Ìá¤êÃÍ
446 while(s->opcode != SCRIPT_OPCODE_DUMP_END){
447 if((status == DUMP) && (s->opcode < SCRIPT_OPCODE_DUMP_START)){
448 printf("%d:%s config script include DUMP_START area\n", s->line, LOGICAL_ERROR_PREFIX);
452 //romimage open for write or program mode
453 if((imagesize == 0) && (status == DUMP)){
455 case MODE_RAM_WRITE: //CPU_RAMSIZE check
456 assert(r->cpu_ram.attribute == MEMORY_ATTR_READ);
457 r->cpu_ram.data = buf_load_full(c->ramimage, &imagesize);
458 if(r->cpu_ram.data == NULL){
459 printf("%s RAM image open error\n", LOGICAL_ERROR_PREFIX);
462 }else if(r->cpu_ram.size != imagesize){
463 printf("%s RAM image size is not same\n", LOGICAL_ERROR_PREFIX);
464 Free(r->cpu_ram.data);
465 r->cpu_ram.data = NULL;
470 case MODE_ROM_PROGRAM: //MAPPER check
471 assert(c->cpu_flash_driver->program != NULL);
472 assert(r->cpu_rom.attribute == MEMORY_ATTR_READ);
473 assert(r->ppu_rom.attribute == MEMORY_ATTR_READ);
474 if(nesfile_load(LOGICAL_ERROR_PREFIX, c->romimage, r)== false){
477 //Äê¿ôÀë¸À¥¨¥é¡¼¤Ï̵¸Â¥ë¡¼¥×¤Î²ÄǽÀ¤¬¤¢¤ë¤Î¤Ç¥¹¥¯¥ê¥×¥ÈÆâÉô¥Á¥§¥Ã¥¯¤ò¤»¤º¤Ë»ß¤á¤ë
478 if(logical_flashsize_get(c->transtype_cpu, r->cpu_rom.size, &script_cpu_flashsize) == NG){
481 if(logical_flashsize_get(c->transtype_ppu, r->ppu_rom.size, &script_ppu_flashsize) == NG){
484 //flash memory capacity check
485 if(r->cpu_rom.size > c->cpu_flash_driver->capacity){
486 logical_print_capacityerror(s->line, r->cpu_rom.name);
489 if((r->ppu_rom.size != 0) && (r->ppu_rom.size > c->ppu_flash_driver->capacity)){
490 logical_print_capacityerror(s->line, r->ppu_rom.name);
502 case SCRIPT_OPCODE_COMMENT:
504 case SCRIPT_OPCODE_MAPPER:
505 r->mappernum = s->value[0];
507 case SCRIPT_OPCODE_MIRROR:
508 r->mirror = s->value[0];
510 case SCRIPT_OPCODE_CPU_ROMSIZE:{
511 const long size = s->value[0];
512 r->cpu_rom.size = size;
513 if(memorysize_check(size, MEMORY_AREA_CPU_ROM)){
514 printf("%s %s length error\n", LOGICAL_ERROR_PREFIX, OPSTR_CPU_ROMSIZE);
518 case SCRIPT_OPCODE_CPU_FLASHSIZE:
519 if(logical_flashsize_set(MEMORY_AREA_CPU_ROM, &script_cpu_flashsize, s) == NG){
522 case SCRIPT_OPCODE_CPU_RAMSIZE:
523 //memory size ¤Ï̤³ÎÄêÍ×ÁǤ¬Â¿¤¤¤Î¤Ç check ¤òÈ´¤¯
524 r->cpu_ram.size = s->value[0];
526 case SCRIPT_OPCODE_CPU_COMMAND:
527 if(command_mask(MEMORY_AREA_CPU_ROM, s->value[0], s->value[1], s->value[2], &(r->cpu_flash)) == NG){
531 case SCRIPT_OPCODE_PPU_ROMSIZE:{
532 const long size = s->value[0];
533 r->ppu_rom.size = size;
534 if(memorysize_check(size, MEMORY_AREA_PPU)){
535 printf("%s %s length error\n", LOGICAL_ERROR_PREFIX, OPSTR_PPU_ROMSIZE);
539 case SCRIPT_OPCODE_PPU_FLASHSIZE:
540 if(logical_flashsize_set(MEMORY_AREA_PPU, &script_ppu_flashsize, s) == NG){
544 case SCRIPT_OPCODE_PPU_COMMAND:
545 if(command_mask(MEMORY_AREA_PPU, s->value[0], s->value[1], s->value[2], &(r->ppu_flash)) == NG){
549 case SCRIPT_OPCODE_DUMP_START:
552 case SCRIPT_OPCODE_CPU_READ:{
553 const long address = s->value[0];
554 const long length = s->value[1];
555 const long end = address + length - 1;
557 assert(r->cpu_rom.attribute == MEMORY_ATTR_WRITE);
558 //length filter. 0 ¤Ï¤À¤á
559 if(!is_range(length, 1, 0x4000)){
560 logical_print_illgallength(s->line, STR_REGION_CPU, length);
564 else if(!is_region_cpurom(address)){
565 logical_print_illgalarea(s->line, STR_REGION_CPU, address);
567 }else if(end >= 0x10000){
568 logical_print_overdump(s->line, STR_REGION_CPU, address, end);
571 cpu_romsize += length;
575 case SCRIPT_OPCODE_CPU_WRITE:{
576 const long address = s->value[0];
578 if(expression_calc(&s->expression, &data) == NG){
579 printf("%d:%s expression calc error\n", s->line, LOGICAL_ERROR_PREFIX);
582 if(address < 0x5000 || address >= 0x10000){
583 logical_print_illgalarea(s->line, STR_REGION_CPU, address);
585 }else if(!is_data_byte(data)){
586 logical_print_byteerror(s->line, STR_REGION_CPU, data);
592 case SCRIPT_OPCODE_CPU_RAMRW:{
593 const long address = s->value[0];
594 const long length = s->value[1];
595 const long end = address + length - 1;
598 assert(r->cpu_ram.attribute == MEMORY_ATTR_WRITE);
601 assert(r->cpu_ram.attribute == MEMORY_ATTR_READ);
604 //length filter. 0 ¤Ï¤À¤á
605 if(!is_range(length, 1, 0x2000)){
606 logical_print_illgallength(s->line, STR_REGION_CPU, length);
610 else if(address < 0x5c00 || address >= 0xc000){
611 logical_print_illgalarea(s->line, STR_REGION_CPU, address);
613 }else if(0 && end >= 0x8000){
614 logical_print_overdump(s->line, STR_REGION_CPU, address, end);
617 cpu_ramsize += length;
621 case SCRIPT_OPCODE_CPU_PROGRAM:{
622 const long address = s->value[0];
623 const long length = s->value[1];
624 const long end = address + length - 1;
626 assert(r->cpu_rom.attribute == MEMORY_ATTR_READ);
627 assert(r->ppu_rom.attribute == MEMORY_ATTR_READ);
629 if(!is_range(length, 0x80, 0x4000)){
630 logical_print_illgallength(s->line, STR_REGION_CPU, length);
634 else if(!is_region_cpurom(address)){
635 logical_print_illgalarea(s->line, STR_REGION_CPU, address);
637 }else if(end >= 0x10000){
638 logical_print_overdump(s->line, STR_REGION_CPU, address, end);
641 cpu_romsize += length;
645 case SCRIPT_OPCODE_PPU_RAMFIND:
646 //¥ë¡¼¥×ÆâÉô¤ËÆþ¤Ã¤Æ¤¿¤é¥¨¥é¡¼
647 if(variable_num != 0){
648 printf("%d:%s PPU_RAMTEST must use outside loop\n", s->line, LOGICAL_ERROR_PREFIX);
652 case SCRIPT_OPCODE_PPU_SRAMTEST:
653 case SCRIPT_OPCODE_PPU_READ:{
654 const long address = s->value[0];
655 const long length = s->value[1];
656 const long end = address + length - 1;
657 assert(r->ppu_rom.attribute == MEMORY_ATTR_WRITE);
658 //length filter. 0 ¤òÍÆǧ¤¹¤ë
660 if(s->opcode == SCRIPT_OPCODE_PPU_SRAMTEST){
663 if(!is_range(length, min, 0x2000)){
664 logical_print_illgallength(s->line, STR_REGION_PPU, length);
668 else if(!is_region_ppurom(address)){
669 logical_print_illgalarea(s->line, STR_REGION_PPU, address);
671 }else if (end >= 0x2000){
672 logical_print_overdump(s->line, STR_REGION_PPU, address, end);
676 if((s->opcode == SCRIPT_OPCODE_PPU_READ) && is_region_ppurom(address)){
677 ppu_romsize += length;
682 case SCRIPT_OPCODE_PPU_WRITE:{
686 const long address = s->value[0];
688 if(expression_calc(&s->expression, &data) == NG){
689 printf("%d:%s expression calc error\n", s->line, LOGICAL_ERROR_PREFIX);
693 if(!is_region_ppurom(address)){
694 logical_print_illgalarea(s->line, STR_REGION_PPU, address);
696 }else if(!is_data_byte(data)){
697 logical_print_byteerror(s->line, STR_REGION_PPU, data);
703 case SCRIPT_OPCODE_PPU_PROGRAM:{
704 const long address = s->value[0];
705 const long length = s->value[1];
706 const long end = address + length - 1;
708 assert(r->ppu_rom.attribute == MEMORY_ATTR_READ);
709 assert(r->ppu_rom.size != 0);
712 if(!is_range(length, 0x80, 0x1000)){
713 logical_print_illgallength(s->line, STR_REGION_PPU, length);
717 else if(!is_region_ppurom(address)){
718 logical_print_illgalarea(s->line, STR_REGION_PPU, address);
720 }else if(end >= 0x2000){
721 logical_print_overdump(s->line, STR_REGION_PPU, address, end);
724 ppu_romsize += length;
728 case SCRIPT_OPCODE_STEP_START:{
729 const struct step_syntax{
733 } RANGE[STEP_NUM] = {
734 {.start = 0, .end = 0, .constant = NG, .name = "variable"},
735 {.start = 0, .end = 0xff, .constant = OK, .name = "start"},
736 {.start = 0, .end = 0x100, .constant = OK, .name = "end"},
737 {.start = 1, .end = 0x100, .constant = NG, .name = "next"}
740 for(i = STEP_START; i < STEP_NUM; i++){
741 const struct step_syntax *ss;
743 //Äê¿ôobject ¤ò¼Â¿ô¤ËÊÑ´¹¤¹¤ë¤¿¤á¡¢const ¤ò³°¤·¤Æ½ñ¤´¹¤¨¤ë
745 v = (long *) &s->value[i];
746 if((ss->constant == OK) && (is_range(*v, VALUE_CONTANT_CPU_STEP_START, VALUE_CONTANT_PPU_STEP_END))){
747 //VALUE_CONSTANT_xxx ¤ò¼ÂºÝ¤Ë»È¤ï¤ì¤ëÄê¿ô¤Ë¤·¤Æ¡¢¥¹¥¯¥ê¥×¥È¥Ç¡¼¥¿¤òÄ¥¤êÂؤ¨¤ë
748 *v = constant_get(*v, script_cpu_flashsize.constant, script_ppu_flashsize.constant);
750 if(!is_range(*v, ss->start, ss->end)){
751 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);
755 //charcter RAM ¤ÎÍÍ¤Ë step ÆâÉô¤ò¹Ô¤ï¤Ê¤¤¾ì¹ç¤Îscript¾õÂÖ¤ÎÊѹ¹
756 if(s->value[STEP_START] >= s->value[STEP_END]){
757 status = STEP_THOUGH;
759 //¥ë¡¼¥×¤ÎÌá¤êÀè¤Ï¤³¤ÎÌ¿Îá¤Î¼¡¤Ê¤Î¤Ç s[1]
760 else if(step_new(s->variable, s->value[STEP_START], s->value[STEP_END], s->value[STEP_NEXT], &s[1]) == NG){
761 printf("%d:%s step loop too much\n", s->line, LOGICAL_ERROR_PREFIX);
768 case SCRIPT_OPCODE_DUMP_END:
773 //status ÊÌ¤Ë script ¤ÎÀ©¸æ. while ¤òÈ´¤±¤ë¤Î¤Ç switch ¤ò»È¤¨¤Ê¤¤
776 }else if(status == STEP_THOUGH){
779 while(s->opcode != SCRIPT_OPCODE_DUMP_END){
781 case SCRIPT_OPCODE_STEP_START:
784 case SCRIPT_OPCODE_STEP_END:
798 //opcode ÊÌ¤Ë script ¤ÎÀ©¸æ. while ¤òÈ´¤±¤ë¤Î¤Ç switch ¤ò»È¤¨¤Ê¤¤
799 if(s->opcode == SCRIPT_OPCODE_STEP_END){
800 if(variable_num == 0){
801 printf("%d:%s loop closed, missing STEP_START\n", s->line, LOGICAL_ERROR_PREFIX);
806 }else if(s->opcode == SCRIPT_OPCODE_DUMP_END){
814 if(variable_num != 0){
815 printf("%d:%s loop opened, missing STEP_END\n", s->line, LOGICAL_ERROR_PREFIX);
818 //dump length conform
819 error += dump_length_conform(OPSTR_CPU_ROMSIZE, cpu_romsize, r->cpu_rom.size);
820 error += dump_length_conform(OPSTR_CPU_RAMSIZE, cpu_ramsize, r->cpu_ram.size);
821 error += dump_length_conform(OPSTR_PPU_ROMSIZE, ppu_romsize, r->ppu_rom.size);
823 //command line config override
824 if(c->mirror != CONFIG_OVERRIDE_UNDEF){
825 r->mirror = c->mirror;
827 if(c->backupram != CONFIG_OVERRIDE_UNDEF){
830 if(c->mapper != CONFIG_OVERRIDE_UNDEF){
831 //program mode ¤Ç mapper Êѹ¹¤òËɤ°
832 assert(c->mode == MODE_ROM_DUMP);
833 r->mappernum = c->mapper;
835 if(c->syntaxtest == 1){
837 printf("syntax ok!\n");
845 execute() ÍÑ¥µ¥Ö´Ø¿ô¤È¥Ç¡¼¥¿
847 static int execute_connection_check(const struct reader_driver *d)
850 const int testsize = 0x80;
852 uint8_t *master, *reload;
853 master = Malloc(testsize);
854 reload = Malloc(testsize);
856 d->cpu_read(0xfee0, testsize, master);
858 while(testcount != 0){
859 d->cpu_read(0xfee0, testsize, reload);
860 if(memcmp(master, reload, testsize) != 0){
872 enum {PPU_TEST_RAM, PPU_TEST_ROM};
873 const uint8_t PPU_TEST_DATA[] = "PPU_TEST_DATA";
874 static int ppu_ramfind(const struct reader_driver *d)
876 const long length = sizeof(PPU_TEST_DATA);
877 const long testaddr = 123;
878 uint8_t writedata[length];
879 //ppu ram data fill 0
880 memset(writedata, 0, length);
881 d->ppu_write(testaddr, length, writedata);
883 //ppu test data write
884 d->ppu_write(testaddr, length, PPU_TEST_DATA);
886 d->ppu_read(testaddr, length, writedata);
887 if(memcmp(writedata, PPU_TEST_DATA, length) == 0){
893 static int ramtest(const int region, const struct reader_driver *d, long address, long length, uint8_t *writedata, uint8_t *testdata, const long filldata)
895 memset(writedata, filldata, length);
897 case MEMORY_AREA_CPU_RAM:
898 d->cpu_write_6502(address, length, writedata);
900 case MEMORY_AREA_PPU:
901 d->ppu_write(address, length, writedata);
907 case MEMORY_AREA_CPU_RAM:
908 d->cpu_read(address, length, testdata);
910 case MEMORY_AREA_PPU:
911 d->ppu_read(address, length, testdata);
916 if(memcmp(writedata, testdata, length) == 0){
922 static const long SRAMTESTDATA[] = {0xff, 0xaa, 0x55, 0x00};
923 static int sramtest(const int region, const struct reader_driver *d, long address, long length)
925 uint8_t *writedata, *testdata;
928 testdata = Malloc(length);
929 writedata = Malloc(length);
930 for(i = 0; i < sizeof(SRAMTESTDATA) / sizeof(long); i++){
931 const long filldata = SRAMTESTDATA[i];
932 error += ramtest(region, d, address, length, testdata, writedata, filldata);
939 static void readbuffer_print(const struct memory *m, long length)
944 printf("%s ROM 0x%05x:", m->name, m->offset);
950 switch(offset & 0xf){
961 printf("%02x%c", (int) *data, safix);
968 static void checksum_print(const uint8_t *data, long length)
976 printf(" 0x%06x\n", sum);
979 static void read_result_print(const struct memory *m, long length)
981 readbuffer_print(m, length);
982 checksum_print(m->data, length);
986 static void execute_program_begin(const struct memory *m, const long length)
988 int tail = m->offset + (int) length - 1;
989 printf("writing %s area 0x%06x-0x%06x ... ", m->name, m->offset, tail);
993 static const char STR_OK[] = "OK";
994 static const char STR_NG[] = "NG";
996 //memcmp ¤ÎÌá¤êÃͤ¬Æþ¤ë¤Î¤Ç 0 ¤¬Àµ¾ï
997 static void execute_program_finish(int result)
1004 printf("%s\n", str);
1007 static const char EXECUTE_ERROR_PREFIX[] = "execute error:";
1008 static const char EXECUTE_PROGRAM_PREPARE[] = "%s device initialize ... ";
1009 static const char EXECUTE_PROGRAM_DONE[] = "done\n";
1010 static void execute_cpu_ramrw(const struct reader_driver *d, const struct memory *ram, int mode, long address, long length)
1012 if(mode == MODE_RAM_WRITE){
1013 d->cpu_write_6502(address, length, ram->data);
1014 /* const uint8_t *writedata;
1017 writedata = ram->data;
1019 d->cpu_write_6502(a++, *writedata, wait);
1024 compare = Malloc(length);
1025 d->cpu_read(address, length, compare);
1026 if(memcmp(ram->data, compare, length) == 0){
1027 printf("RAM data write success\n");
1029 printf("RAM data write failed\n");
1033 d->cpu_read(address, length, ram->data);
1037 static int execute(const struct script *s, const struct st_config *c, struct romimage *r)
1039 const struct reader_driver *const d = c->reader;
1040 switch(d->open_or_close(READER_OPEN)){
1045 printf("%s driver open error\n", EXECUTE_ERROR_PREFIX);
1050 if(execute_connection_check(d) == NG){
1051 printf("%s maybe connection error\n", EXECUTE_ERROR_PREFIX);
1052 d->open_or_close(READER_CLOSE);
1055 uint8_t *program_compare;
1056 program_compare = NULL;
1057 if(c->mode == MODE_ROM_PROGRAM){
1058 printf("flashmemory/SRAM program mode. To abort programming, press Ctrl+C\n");
1059 int size = r->cpu_rom.size;
1060 if(size < r->ppu_rom.size){
1061 size = r->ppu_rom.size;
1063 program_compare = Malloc(size);
1065 struct memory cpu_rom, ppu_rom, cpu_ram;
1066 cpu_rom = r->cpu_rom;
1067 ppu_rom = r->ppu_rom;
1068 cpu_ram = r->cpu_ram;
1071 int programcount_cpu = 0, programcount_ppu = 0;
1072 int flashcommand_change_cpu = 0, flashcommand_change_ppu = 0;
1073 variable_init_all();
1074 while(s->opcode != SCRIPT_OPCODE_DUMP_END){
1075 //printf("%s\n", SCRIPT_SYNTAX[s->opcode].name);
1077 case SCRIPT_OPCODE_CPU_COMMAND:
1078 command_mask(MEMORY_AREA_CPU_ROM, s->value[0], s->value[1], s->value[2], &(r->cpu_flash));
1079 flashcommand_change_cpu = 1;
1081 case SCRIPT_OPCODE_CPU_READ:{
1083 const long address = s->value[0];
1084 const long length = s->value[1];
1086 d->cpu_read(address, length, m->data);
1087 read_result_print(m, length);
1089 m->offset += length;
1091 case SCRIPT_OPCODE_CPU_WRITE:{
1094 expression_calc(&s->expression, &data);
1096 d->cpu_write_6502(s->value[0], 1, &d8);
1099 case SCRIPT_OPCODE_CPU_RAMRW:{
1100 const long address = s->value[0];
1101 const long length = s->value[1];
1102 if(c->mode == MODE_RAM_WRITE){
1103 if(sramtest(MEMORY_AREA_CPU_RAM, d, address, length) != 0){
1104 printf("SRAM test NG\n");
1109 execute_cpu_ramrw(d, &cpu_ram, c->mode, address, length);
1110 read_result_print(&cpu_ram, length);
1111 cpu_ram.data += length;
1112 cpu_ram.offset += length;
1115 case SCRIPT_OPCODE_CPU_PROGRAM:{
1116 if(c->cpu_flash_driver->id_device == FLASH_ID_DEVICE_DUMMY){
1119 if(flashcommand_change_cpu != 0){
1120 r->cpu_flash.config(
1121 r->cpu_flash.command_0000,
1122 r->cpu_flash.command_2aaa,
1123 r->cpu_flash.command_5555,
1124 r->cpu_flash.pagesize,
1127 flashcommand_change_cpu = 0;
1129 if(programcount_cpu++ == 0){
1130 printf(EXECUTE_PROGRAM_PREPARE, cpu_rom.name);
1132 //device ¤Ë¤è¤Ã¤Æ¤Ï erase
1133 c->cpu_flash_driver->init(&(r->cpu_flash), c->cpu_flash_driver->erase_wait);
1134 printf(EXECUTE_PROGRAM_DONE);
1137 const long address = s->value[0];
1138 const long length = s->value[1];
1139 execute_program_begin(&cpu_rom, length);
1140 c->cpu_flash_driver->program(
1147 d->cpu_read(address, length, program_compare);
1148 result = memcmp(program_compare, cpu_rom.data, length);
1149 execute_program_finish(result);
1154 cpu_rom.data += length;
1155 cpu_rom.offset += length;
1157 if((DEBUG==0) && (result != 0)){
1162 case SCRIPT_OPCODE_PPU_COMMAND:
1163 command_mask(MEMORY_AREA_PPU, s->value[0], s->value[1], s->value[2], &(r->ppu_flash));
1164 flashcommand_change_ppu = 1;
1166 case SCRIPT_OPCODE_PPU_RAMFIND:
1167 if(ppu_ramfind(d) == PPU_TEST_RAM){
1168 printf("PPU_RAMFIND: charcter RAM found\n");
1169 r->ppu_rom.size = 0;
1173 case SCRIPT_OPCODE_PPU_SRAMTEST:{
1174 const long address = s->value[0];
1175 const long length = s->value[1];
1176 printf("PPU_SRAMTEST: 0x%06x-0x%06x ", (int)ppu_rom.offset, (int) (ppu_rom.offset + length) - 1);
1177 if(sramtest(MEMORY_AREA_PPU, d, address, length) == 0){
1178 printf("%s\n", STR_OK);
1180 printf("%s\n", STR_NG);
1184 case SCRIPT_OPCODE_PPU_READ:{
1185 const long address = s->value[0];
1186 const long length = s->value[1];
1188 /*for mmc2,4 protect.
1189 ¤³¤Î¤È¤¤Ï1byteÆɤ߹þ¤ó¤Ç¡¢¤½¤ÎÆâÍƤϥХåե¡¤Ë¤¤¤ì¤Ê¤¤*/
1191 d->ppu_read(address, 1, &dummy);
1193 d->ppu_read(address, length, ppu_rom.data);
1194 read_result_print(&ppu_rom, length);
1196 ppu_rom.data += length;
1197 ppu_rom.offset += length;
1200 case SCRIPT_OPCODE_PPU_WRITE:
1204 expression_calc(&s->expression, &data);
1206 d->ppu_write(s->value[0], 1, &d8);
1209 case SCRIPT_OPCODE_PPU_PROGRAM:{
1210 if(c->ppu_flash_driver->id_device == FLASH_ID_DEVICE_DUMMY){
1213 if(flashcommand_change_ppu != 0){
1214 r->ppu_flash.config(
1215 r->ppu_flash.command_0000,
1216 r->ppu_flash.command_2aaa,
1217 r->ppu_flash.command_5555,
1218 r->ppu_flash.pagesize,
1221 flashcommand_change_ppu = 0;
1223 if(programcount_ppu++ == 0){
1224 printf(EXECUTE_PROGRAM_PREPARE, ppu_rom.name);
1226 c->ppu_flash_driver->init(&(r->ppu_flash), c->ppu_flash_driver->erase_wait);
1227 printf(EXECUTE_PROGRAM_DONE);
1230 const long address = s->value[0];
1231 const long length = s->value[1];
1232 execute_program_begin(&ppu_rom, length);
1233 c->ppu_flash_driver->program(
1238 d->ppu_read(address, length, program_compare);
1239 const int result = memcmp(program_compare, ppu_rom.data, length);
1240 execute_program_finish(result);
1241 ppu_rom.data += length;
1242 ppu_rom.offset += length;
1244 if((DEBUG==0) && (result != 0)){
1249 case SCRIPT_OPCODE_STEP_START:{
1250 if(s->value[STEP_START] >= s->value[STEP_END]){
1251 status = STEP_THOUGH;
1253 //¥ë¡¼¥×¤ÎÌá¤êÀè¤Ï¤³¤ÎÌ¿Îá¤Î¼¡¤Ê¤Î¤Ç &s[1]
1254 step_new(s->variable, s->value[STEP_START], s->value[STEP_END], s->value[STEP_NEXT], &s[1]);
1257 case SCRIPT_OPCODE_DUMP_END:
1263 }else if(status == STEP_THOUGH){
1267 while(s->opcode != SCRIPT_OPCODE_DUMP_END){
1269 case SCRIPT_OPCODE_STEP_START:
1272 case SCRIPT_OPCODE_STEP_END:
1287 if(s->opcode == SCRIPT_OPCODE_STEP_END){
1293 d->open_or_close(READER_CLOSE);
1294 if(program_compare != NULL){
1295 Free(program_compare);
1300 void script_load(const struct st_config *c)
1307 buf = buf_load_full(c->script, &scriptsize);
1309 printf("scriptfile open error\n");
1313 text = Malloc(sizeof(char*) * TEXT_MAXLINE);
1314 const int text_num = text_load(buf, scriptsize, text);
1316 printf("script line too much\n");
1321 s = Malloc(sizeof(struct script) * (text_num + 1));
1322 //logical_check, execute ¶¦¤Ë s->opcode ¤¬ DUMP_END ¤Ë¤Ê¤ë¤Þ¤Ç³¤±¤ë¡£DUMP_END ¤ÎÆþ¤ì˺¤ìÍѤËËöÈø¤Îscript¤Ëɬ¤º DUMP_END ¤ò¤¤¤ì¤ë
1327 k->opcode = SCRIPT_OPCODE_DUMP_END;
1329 const int error = syntax_check(text, text_num, s, c->mode);
1337 struct romimage r = {
1339 .size = 0, .offset = 0,
1341 .attribute = MEMORY_ATTR_NOTUSE,
1345 .size = 0, .offset = 0,
1347 .attribute = MEMORY_ATTR_NOTUSE,
1351 .size = 0, .offset = 0,
1353 .attribute = MEMORY_ATTR_NOTUSE,
1354 .name = STR_REGION_CPU
1356 //device ¤Ë±þ¤¸¤¿´Ø¿ô¥Ý¥¤¥ó¥¿¤ò flash_order ¤ËÅϤ¹
1358 .command_0000 = 0x8000,
1361 .pagesize = c->cpu_flash_driver->pagesize,
1362 .command_mask = c->cpu_flash_driver->command_mask,
1363 .config = c->reader->cpu_flash_config,
1364 .erase = c->reader->cpu_flash_erase,
1365 .program = c->reader->cpu_flash_program,
1366 .write = NULL //c->reader->cpu_write_6502
1372 .pagesize = c->ppu_flash_driver->pagesize,
1373 .command_mask = c->ppu_flash_driver->command_mask,
1374 .config = c->reader->ppu_flash_config,
1375 .erase = c->reader->ppu_flash_erase,
1376 .program = c->reader->ppu_flash_program,
1377 .write = NULL //c->reader->ppu_write
1380 .mirror = MIRROR_PROGRAMABLE
1382 //attribute ¤Ï¤½¤Î struct data ¤ËÂФ·¤Æ¤Î RW ¤Ê¤Î¤ÇÍ×Ãí°Õ
1385 r.cpu_rom.attribute = MEMORY_ATTR_WRITE;
1386 r.ppu_rom.attribute = MEMORY_ATTR_WRITE;
1389 r.cpu_ram.attribute = MEMORY_ATTR_WRITE;
1391 case MODE_RAM_WRITE:
1392 r.cpu_ram.attribute = MEMORY_ATTR_READ;
1394 case MODE_ROM_PROGRAM:
1395 r.cpu_rom.attribute = MEMORY_ATTR_READ;
1396 r.ppu_rom.attribute = MEMORY_ATTR_READ;
1402 if(logical_check(s, c, &r) == 0){
1404 if(nesbuffer_malloc(&r, c->mode) == false){
1406 if((c->mode == MODE_RAM_WRITE) && (r.cpu_ram.data != NULL)){
1407 Free(r.cpu_ram.data);
1412 if(execute(s, c, &r) == OK){
1416 nesfile_create(&r, c->romimage);
1419 backupram_create(&(r.cpu_ram), c->ramimage);
1424 nesbuffer_free(&r, c->mode);
1425 if((c->mode == MODE_RAM_WRITE) && (r.cpu_ram.data != NULL)){
1426 Free(r.cpu_ram.data);