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;
87 static SQInteger cpu_read(HSQUIRRELVM v)
89 struct dump_config *d;
90 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
94 r = read_memory(v, d->handle, &d->cpu, d->progress);
98 static SQInteger ppu_read(HSQUIRRELVM v)
100 struct dump_config *d;
101 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
105 r = read_memory(v, d->handle, &d->ppu, d->progress);
109 static SQInteger ppu_ramfind(HSQUIRRELVM v)
111 struct dump_config *d;
116 static const uint8_t test_val[testsize] = {0xaa, 0x55, 0, 0xff, 0x46, 0x49, 0x07, 0x21};
117 static const uint8_t test_str[testsize] = "pputest";
118 uint8_t test_result[testsize];
119 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
120 struct dump_memory_driver *p = &d->ppu;
125 p->access->memory_write(d->handle, testaddress, testsize, test_val);
126 p->access->memory_read(d->handle, &GAUGE_DUMMY, testaddress, testsize, test_result);
127 if(memcmp(test_val, test_result, testsize) != 0){
128 sq_pushbool(v, SQFalse);
131 p->access->memory_write(d->handle, testaddress, testsize, test_str);
132 p->access->memory_read(d->handle, &GAUGE_DUMMY, testaddress, testsize, test_result);
133 if(memcmp(test_str, test_result, testsize) != 0){
134 sq_pushbool(v, SQFalse);
137 p->memory.offset = 0;
139 sq_pushbool(v, SQTrue);
143 static void memory_new_init(struct dump_memory_driver *d)
145 d->memory.offset = 0;
146 d->memory.data = Malloc(d->memory.size);
147 d->gauge.range_set(d->gauge.bar, d->memory.size);
148 d->gauge.value_set(d->gauge.bar, d->gauge.label, 0);
151 //test »þ/1ÅÙÌܤΠcall ¤Ç»ÈÍÑ
152 static SQInteger memory_new(HSQUIRRELVM v)
154 struct dump_config *d;
155 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
159 r = qr_argument_get(v, 2, &d->cpu.memory.size, &d->ppu.memory.size);
164 memory_new_init(&d->cpu);
165 memory_new_init(&d->ppu);
169 //dump »þ/2ÅÙÌܤΠcall ¤Ç nesfile_save ¤È¤·¤Æ»ÈÍÑ
170 static SQInteger nesfile_save(HSQUIRRELVM v)
172 struct dump_config *d;
173 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
177 struct romimage image;
179 r = qr_argument_get(v, 2, &image.mappernum, &mirrorfind);
183 image.cpu_rom = d->cpu.memory;
184 image.cpu_ram.data = NULL;
185 image.ppu_rom = d->ppu.memory;
186 image.mirror = MIRROR_PROGRAMABLE;
188 if(d->control->vram_connection(d->handle) == 0x05){
189 image.mirror = MIRROR_VERTICAL;
191 image.mirror = MIRROR_HORIZONAL;
195 if(d->battery == true){
198 nesfile_create(&d->log, &image, d->target);
199 nesbuffer_free(&image, 0); //0 is MODE_xxx_xxxx
201 d->cpu.memory.data = NULL;
202 d->ppu.memory.data = NULL;
206 //dump »þ/1ÅÙÌܤΠcall ¤Ç nesfile_save ¤È¤·¤Æ»ÈÍÑ
207 static SQInteger length_check(HSQUIRRELVM v)
209 struct dump_config *d;
210 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
214 bool cpu = true, ppu = true;
216 if(d->cpu.memory.size != d->cpu.read_count){
220 d->log.append(d->log.object, "cpu_romsize is not connected 0x%06x/0x%06x\n", (int) d->cpu.read_count, (int) d->cpu.memory.size);
222 if(d->ppu.memory.size != d->ppu.read_count){
226 d->log.append(d->log.object, "ppu_romsize is not connected 0x%06x/0x%06x\n", (int) d->ppu.read_count, (int) d->ppu.memory.size);
228 if(cpu == false || ppu == false){
229 r = sq_throwerror(v, "script logical error");
234 static SQInteger read_count(HSQUIRRELVM v, const struct textcontrol *l, struct dump_memory_driver *t, const struct range *range_address, const struct range *range_length)
236 long address, length;
237 SQRESULT r = qr_argument_get(v, 2, &address, &length);
241 r = range_check(v, "length", length, range_length);
245 if((address < range_address->start) || ((address + length) > range_address->end)){
246 l->append(l->object, "address range must be 0x%06x to 0x%06x", (int) range_address->start, (int) range_address->end);
247 return sq_throwerror(v, "script logical error");;
249 t->read_count += length;
252 static SQInteger cpu_read_count(HSQUIRRELVM v)
254 static const struct range range_address = {0x8000, 0x10000};
255 //length == 0 ¤Ï Âоݥ¢¥É¥ì¥¹¤ò¸Æ¤ó¤Ç¡¢¥Ð¥Ã¥Õ¥¡¤Ë¤¤¤ì¤Ê¤¤¡£mmc2, mmc4 ¤Ç»ÈÍѤ¹¤ë¡£
256 static const struct range range_length = {0x0000, 0x4000};
257 struct dump_config *d;
258 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
262 return read_count(v, &d->log, &d->cpu, &range_address, &range_length);
265 static SQInteger ppu_read_count(HSQUIRRELVM v)
267 static const struct range range_address = {0x0000, 0x2000};
268 static const struct range range_length = {0x0001, 0x2000};
269 struct dump_config *d;
270 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
274 return read_count(v, &d->log, &d->ppu, &range_address, &range_length);
277 static SQInteger memory_size_set(HSQUIRRELVM v)
279 struct dump_config *d;
280 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
284 r = qr_argument_get(v, 2, &d->cpu.memory.size, &d->ppu.memory.size);
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))){
295 d->log.append(d->log.object, "%s open error\n", d->script);
298 SQRESULT r = qr_call(
299 v, "dump", (SQUserPointer) d, true,
300 3, d->mappernum, d->cpu.increase, d->ppu.increase
304 Free(d->cpu.memory.data);
305 Free(d->ppu.memory.data);
306 d->cpu.memory.data = NULL;
307 d->ppu.memory.data = NULL;
313 static void dump_memory_driver_init(struct dump_memory_driver *dd)
316 dd->memory.offset = 0;
317 dd->memory.attribute = MEMORY_ATTR_WRITE;
318 dd->memory.transtype = TRANSTYPE_FULL;
319 dd->memory.data = NULL;
323 void script_dump_execute(struct dump_config *d)
325 dump_memory_driver_init(&d->cpu);
326 d->cpu.memory.name = "Program";
328 dump_memory_driver_init(&d->ppu);
329 d->ppu.memory.name = "Charcter";
332 HSQUIRRELVM v = qr_open(&d->log);
333 qr_function_register_global(v, "ppu_ramfind", script_nop);
334 qr_function_register_global(v, "cpu_write", cpu_write_check);
335 qr_function_register_global(v, "memory_new", memory_size_set);
336 qr_function_register_global(v, "nesfile_save", length_check);
337 qr_function_register_global(v, "cpu_read", cpu_read_count);
338 qr_function_register_global(v, "ppu_read", ppu_read_count);
339 qr_function_register_global(v, "require", script_require);
340 if(script_execute(v, d) == false){
346 /* if(d->progress == true){
349 d->handle = d->control->open(d->except);
350 if(d->handle == NULL){
351 d->log.append(d->log.object, "reader open error\n");
354 d->control->init(d->handle);
355 if(connection_check(d->handle, &d->log, d->cpu.access, d->ppu.access) == false){
359 HSQUIRRELVM v = qr_open(&d->log);
360 qr_function_register_global(v, "memory_new", memory_new);
361 qr_function_register_global(v, "nesfile_save", nesfile_save);
362 qr_function_register_global(v, "cpu_write", cpu_write);
363 qr_function_register_global(v, "cpu_read", cpu_read);
364 qr_function_register_global(v, "ppu_read", ppu_read);
365 qr_function_register_global(v, "ppu_ramfind", ppu_ramfind);
366 qr_function_register_global(v, "require", script_require);
367 script_execute(v, d);
370 d->control->close(d->handle);