11 #include "memory_manage.h"
12 #include "reader_master.h"
13 #include "squirrel_wrap.h"
14 #include "script_common.h"
15 #include "script_dump.h"
17 static SQInteger write_memory(HSQUIRRELVM v, const struct reader_handle *h, struct dump_memory_driver *t)
20 SQRESULT r = qr_argument_get(v, 2, &address, &data);
24 uint8_t d8 = (uint8_t) data;
25 t->access->memory_write(h, address, 1, &d8);
28 static SQInteger cpu_write(HSQUIRRELVM v)
30 struct dump_config *d;
31 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
35 return write_memory(v, &d->handle, &d->cpu);
38 //¤³¤³¤Î printf ¤Ï debug ÍѤ˻Ĥ·¤Æ¤ª¤¯
39 static void buffer_show(struct memory *t, long length)
42 const uint8_t *buf = t->data + t->offset;
43 printf("%s 0x%06x:", t->name, t->offset);
44 for(i = 0; i < 0x10; i++){
46 sprintf(dump, "%02x", buf[i]);
67 printf(":0x%06x\n", sum);
71 static SQInteger read_memory(HSQUIRRELVM v, const struct reader_handle *h, struct dump_memory_driver *t, bool progress)
74 SQRESULT r = qr_argument_get(v, 2, &address, &length);
78 t->access->memory_read(h, &t->gauge, address, length == 0 ? 1: length, t->memory.data + t->memory.offset);
79 if((length != 0) && (progress == false)){
80 buffer_show(&t->memory, length);
82 t->memory.offset += length;
88 static SQInteger cpu_read(HSQUIRRELVM v)
90 struct dump_config *d;
91 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
95 r = read_memory(v, &d->handle, &d->cpu, d->progress);
99 static SQInteger ppu_read(HSQUIRRELVM v)
101 struct dump_config *d;
102 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
106 r = read_memory(v, &d->handle, &d->ppu, d->progress);
110 static SQInteger ppu_ramfind(HSQUIRRELVM v)
112 struct dump_config *d;
117 static const uint8_t test_val[testsize] = {0xaa, 0x55, 0, 0xff, 0x46, 0x49, 0x07, 0x21};
118 static const uint8_t test_str[testsize] = "pputest";
119 uint8_t test_result[testsize];
120 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
121 struct dump_memory_driver *p = &d->ppu;
126 p->access->memory_write(&d->handle, testaddress, testsize, test_val);
127 p->access->memory_read(&d->handle, &GAUGE_DUMMY, testaddress, testsize, test_result);
128 if(memcmp(test_val, test_result, testsize) != 0){
129 sq_pushbool(v, SQFalse);
132 p->access->memory_write(&d->handle, testaddress, testsize, test_str);
133 p->access->memory_read(&d->handle, &GAUGE_DUMMY, testaddress, testsize, test_result);
134 if(memcmp(test_str, test_result, testsize) != 0){
135 sq_pushbool(v, SQFalse);
138 p->memory.offset = 0;
140 sq_pushbool(v, SQTrue);
144 static void memory_new_init(struct dump_memory_driver *d)
146 d->memory.offset = 0;
147 d->memory.data = Malloc(d->memory.size);
148 d->gauge.value_set(d->gauge.bar, d->gauge.label, 0);
149 d->gauge.range_set(d->gauge.bar, d->memory.size);
150 // d->gauge.label_set(d->gauge.label, d->memory.name);
153 //test »þ/1ÅÙÌܤΠcall ¤Ç»ÈÍÑ
154 static SQInteger memory_new(HSQUIRRELVM v)
156 struct dump_config *d;
157 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
161 r = qr_argument_get(v, 2, &d->cpu.memory.size, &d->ppu.memory.size);
165 /* d->cpu.memory.offset = 0;
166 d->cpu.memory.data = Malloc(d->cpu.memory.size);
167 d->cpu.gauge->value_set(0);
168 d->cpu.gauge->range_set(d->cpu.gauge->object, d->cpu.memory.size);
169 d->ppu.memory.offset = 0;
170 d->ppu.memory.data = Malloc(d->ppu.memory.size);
171 d->cpu.gauge->value_set(0);
172 d->ppu.gauge->range_set(d->ppu.gauge->object, d->ppu.memory.size);*/
173 memory_new_init(&d->cpu);
174 memory_new_init(&d->ppu);
178 //dump »þ/2ÅÙÌܤΠcall ¤Ç nesfile_save ¤È¤·¤Æ»ÈÍÑ
179 static SQInteger nesfile_save(HSQUIRRELVM v)
181 struct dump_config *d;
182 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
186 struct romimage image;
188 r = qr_argument_get(v, 2, &image.mappernum, &mirrorfind);
192 image.cpu_rom = d->cpu.memory;
193 image.cpu_ram.data = NULL;
194 image.ppu_rom = d->ppu.memory;
195 image.mirror = MIRROR_PROGRAMABLE;
197 if(d->control->vram_connection(&d->handle) == 0x05){
198 image.mirror = MIRROR_VERTICAL;
200 image.mirror = MIRROR_HORIZONAL;
204 nesfile_create(&d->log, &image, d->target);
205 nesbuffer_free(&image, 0); //0 is MODE_xxx_xxxx
207 d->cpu.memory.data = NULL;
208 d->ppu.memory.data = NULL;
212 //dump »þ/1ÅÙÌܤΠcall ¤Ç nesfile_save ¤È¤·¤Æ»ÈÍÑ
213 static SQInteger length_check(HSQUIRRELVM v)
215 struct dump_config *d;
216 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
220 bool cpu = true, ppu = true;
222 if(d->cpu.memory.size != d->cpu.read_count){
227 snprintf(str, 80, "cpu_romsize is not connected 0x%06x/0x%06x\n", (int) d->cpu.read_count, (int) d->cpu.memory.size);
228 d->log.append(d->log.object, str);
230 if(d->ppu.memory.size != d->ppu.read_count){
234 snprintf(str, 80, "ppu_romsize is not connected 0x%06x/0x%06x\n", (int) d->ppu.read_count, (int) d->ppu.memory.size);
235 d->log.append(d->log.object, str);
237 if(cpu == false || ppu == false){
238 r = sq_throwerror(v, "script logical error");
243 static SQInteger read_count(HSQUIRRELVM v, struct textcontrol *l, struct dump_memory_driver *t, const struct range *range_address, const struct range *range_length)
245 long address, length;
246 SQRESULT r = qr_argument_get(v, 2, &address, &length);
250 r = range_check(v, "length", length, range_length);
254 if((address < range_address->start) || ((address + length) > range_address->end)){
256 snprintf(str, 80, "address range must be 0x%06x to 0x%06x", (int) range_address->start, (int) range_address->end);
257 l->append(l->object, str);
258 return sq_throwerror(v, "script logical error");;
260 t->read_count += length;
263 static SQInteger cpu_read_count(HSQUIRRELVM v)
265 static const struct range range_address = {0x8000, 0x10000};
266 //length == 0 ¤Ï Âоݥ¢¥É¥ì¥¹¤ò¸Æ¤ó¤Ç¡¢¥Ð¥Ã¥Õ¥¡¤Ë¤¤¤ì¤Ê¤¤¡£mmc2, mmc4 ¤Ç»ÈÍѤ¹¤ë¡£
267 static const struct range range_length = {0x0000, 0x4000};
268 struct dump_config *d;
269 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
273 return read_count(v, &d->log, &d->cpu, &range_address, &range_length);
276 static SQInteger ppu_read_count(HSQUIRRELVM v)
278 static const struct range range_address = {0x0000, 0x2000};
279 static const struct range range_length = {0x0001, 0x2000};
280 struct dump_config *d;
281 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
285 return read_count(v, &d->log, &d->ppu, &range_address, &range_length);
288 static bool script_execute(HSQUIRRELVM v, struct dump_config *d)
291 if(SQ_FAILED(sqstd_dofile(v, _SC("dumpcore.nut"), SQFalse, SQTrue))){
292 d->log.append(d->log.object, "dump core script error\n");
294 }else if(SQ_FAILED(sqstd_dofile(v, _SC(d->script), SQFalse, SQTrue))){
296 snprintf(str, 80, "%s open error\n", d->script);
297 d->log.append(d->log.object, str);
300 SQRESULT r = qr_call(
301 v, "dump", (SQUserPointer) d, true,
302 3, d->mappernum, d->cpu.increase, d->ppu.increase
306 Free(d->cpu.memory.data);
307 Free(d->ppu.memory.data);
308 d->cpu.memory.data = NULL;
309 d->ppu.memory.data = NULL;
314 void script_dump_execute(struct dump_config *d)
316 struct dump_memory_driver *dd = &d->cpu;
317 dd->memory.name = "Program";
319 dd->memory.offset = 0;
320 dd->memory.attribute = MEMORY_ATTR_WRITE;
321 dd->memory.transtype = TRANSTYPE_FULL;
322 dd->memory.data = NULL;
326 dd->memory.name = "Charcter";
328 dd->memory.offset = 0;
329 dd->memory.attribute = MEMORY_ATTR_WRITE;
330 dd->memory.transtype = TRANSTYPE_FULL;
331 dd->memory.data = NULL;
335 HSQUIRRELVM v = qr_open(&d->log);
336 qr_function_register_global(v, "ppu_ramfind", script_nop);
337 qr_function_register_global(v, "cpu_write", cpu_write_check);
338 qr_function_register_global(v, "memory_new", memory_new);
339 qr_function_register_global(v, "nesfile_save", length_check);
340 qr_function_register_global(v, "cpu_read", cpu_read_count);
341 qr_function_register_global(v, "ppu_read", ppu_read_count);
342 qr_function_register_global(v, "require", script_require);
343 if(script_execute(v, d) == false){
349 if(d->progress == true){
353 HSQUIRRELVM v = qr_open(&d->log);
354 qr_function_register_global(v, "memory_new", script_nop);
355 qr_function_register_global(v, "nesfile_save", nesfile_save);
356 qr_function_register_global(v, "cpu_write", cpu_write);
357 qr_function_register_global(v, "cpu_read", cpu_read);
358 qr_function_register_global(v, "ppu_read", ppu_read);
359 qr_function_register_global(v, "ppu_ramfind", ppu_ramfind);
360 qr_function_register_global(v, "require", script_require);
361 script_execute(v, d);