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"
22 void (*const write)(long address, long length, const uint8_t *data);
23 void (*const read)(long address, long length, u8 *data);
24 struct gauge *const gauge;
26 uint8_t (*const vram_connection)(void);
28 struct textcontrol *const log;
30 static SQInteger write_memory(HSQUIRRELVM v, struct memory_driver *t)
33 SQRESULT r = qr_argument_get(v, 2, &address, &data);
37 uint8_t d8 = (uint8_t) data;
38 t->write(address, 1, &d8);
41 static SQInteger cpu_write(HSQUIRRELVM v)
43 struct dump_driver *d;
44 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
48 return write_memory(v, &d->cpu);
51 //¤³¤³¤Î printf ¤Ï debug ÍѤ˻Ĥ·¤Æ¤ª¤¯
52 static void buffer_show(struct memory *t, long length)
55 const uint8_t *buf = t->data + t->offset;
56 printf("%s 0x%06x:", t->name, t->offset);
57 for(i = 0; i < 0x10; i++){
59 sprintf(dump, "%02x", buf[i]);
80 printf(":0x%06x\n", sum);
84 static void progress_show(struct memory_driver *d, const char *area)
87 d->gauge->value_set(d->gauge->bar, d->memory.offset);
88 snprintf(str, 80, "%s 0x%06x/0x%06x", area, d->memory.offset, d->memory.size);
89 d->gauge->label_set(d->gauge->label, str);
91 static SQInteger read_memory(HSQUIRRELVM v, struct memory_driver *t, bool progress)
94 SQRESULT r = qr_argument_get(v, 2, &address, &length);
98 t->read(address, length == 0 ? 1: length, t->memory.data + t->memory.offset);
99 if((length != 0) && (progress == false)){
100 buffer_show(&t->memory, length);
102 t->memory.offset += length;
105 static SQInteger cpu_read(HSQUIRRELVM v)
107 struct dump_driver *d;
108 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
112 r = read_memory(v, &d->cpu, d->progress);
113 progress_show(&d->cpu, "CPU");
117 static SQInteger ppu_read(HSQUIRRELVM v)
119 struct dump_driver *d;
120 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
124 r = read_memory(v, &d->ppu, d->progress);
125 progress_show(&d->ppu, "PPU");
129 static SQInteger ppu_ramfind(HSQUIRRELVM v)
131 struct dump_driver *d;
136 static const uint8_t test_val[testsize] = {0xaa, 0x55, 0, 0xff, 0x46, 0x49, 0x07, 0x21};
137 static const uint8_t test_str[testsize] = "pputest";
138 uint8_t test_result[testsize];
140 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
144 d->ppu.write(testaddress, testsize, test_val);
145 d->ppu.read(testaddress, testsize, test_result);
146 if(memcmp(test_val, test_result, testsize) != 0){
147 sq_pushbool(v, SQFalse);
150 d->ppu.write(testaddress, testsize, test_str);
151 d->ppu.read(testaddress, testsize, test_result);
152 if(memcmp(test_str, test_result, testsize) != 0){
153 sq_pushbool(v, SQFalse);
156 d->ppu.memory.offset = 0;
157 d->ppu.memory.size = 0;
158 sq_pushbool(v, SQTrue);
162 static void memory_new_init(struct memory_driver *d, const char *area)
164 d->memory.offset = 0;
165 d->memory.data = Malloc(d->memory.size);
166 d->gauge->value_set(d->gauge->bar, 0);
167 d->gauge->range_set(d->gauge->bar, d->memory.size);
168 d->gauge->label_set(d->gauge->label, area);
171 //test »þ/1ÅÙÌܤΠcall ¤Ç»ÈÍÑ
172 static SQInteger memory_new(HSQUIRRELVM v)
174 struct dump_driver *d;
175 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
179 r = qr_argument_get(v, 2, &d->cpu.memory.size, &d->ppu.memory.size);
183 /* d->cpu.memory.offset = 0;
184 d->cpu.memory.data = Malloc(d->cpu.memory.size);
185 d->cpu.gauge->value_set(0);
186 d->cpu.gauge->range_set(d->cpu.gauge->object, d->cpu.memory.size);
187 d->ppu.memory.offset = 0;
188 d->ppu.memory.data = Malloc(d->ppu.memory.size);
189 d->cpu.gauge->value_set(0);
190 d->ppu.gauge->range_set(d->ppu.gauge->object, d->ppu.memory.size);*/
191 memory_new_init(&d->cpu, "CPU");
192 memory_new_init(&d->ppu, "PPU");
196 //dump »þ/2ÅÙÌܤΠcall ¤Ç nesfile_save ¤È¤·¤Æ»ÈÍÑ
197 static SQInteger nesfile_save(HSQUIRRELVM v)
199 struct dump_driver *d;
200 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
204 struct romimage image;
206 r = qr_argument_get(v, 2, &image.mappernum, &mirrorfind);
210 image.cpu_rom = d->cpu.memory;
211 image.cpu_ram.data = NULL;
212 image.ppu_rom = d->ppu.memory;
213 image.mirror = MIRROR_PROGRAMABLE;
215 if(d->vram_connection() == 0x05){
216 image.mirror = MIRROR_VERTICAL;
218 image.mirror = MIRROR_HORIZONAL;
222 nesfile_create(d->log, &image, d->target);
223 nesbuffer_free(&image, 0); //0 is MODE_xxx_xxxx
225 d->cpu.memory.data = NULL;
226 d->ppu.memory.data = NULL;
230 //dump »þ/1ÅÙÌܤΠcall ¤Ç nesfile_save ¤È¤·¤Æ»ÈÍÑ
231 static SQInteger length_check(HSQUIRRELVM v)
233 struct dump_driver *d;
234 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
238 bool cpu = true, ppu = true;
240 if(d->cpu.memory.size != d->cpu.read_count){
245 snprintf(str, 80, "cpu_romsize is not connected 0x%06x/0x%06x\n", (int) d->cpu.read_count, (int) d->cpu.memory.size);
246 d->log->append(d->log->object, str);
248 if(d->ppu.memory.size != d->ppu.read_count){
252 snprintf(str, 80, "ppu_romsize is not connected 0x%06x/0x%06x\n", (int) d->ppu.read_count, (int) d->ppu.memory.size);
253 d->log->append(d->log->object, str);
255 if(cpu == false || ppu == false){
256 r = sq_throwerror(v, "script logical error");
261 static SQInteger read_count(HSQUIRRELVM v, struct textcontrol *l, struct memory_driver *t, const struct range *range_address, const struct range *range_length)
263 long address, length;
264 SQRESULT r = qr_argument_get(v, 2, &address, &length);
268 r = range_check(v, "length", length, range_length);
272 if((address < range_address->start) || ((address + length) > range_address->end)){
274 snprintf(str, 80, "address range must be 0x%06x to 0x%06x", (int) range_address->start, (int) range_address->end);
275 l->append(l->object, str);
276 return sq_throwerror(v, "script logical error");;
278 t->read_count += length;
281 static SQInteger cpu_read_count(HSQUIRRELVM v)
283 static const struct range range_address = {0x8000, 0x10000};
284 //length == 0 ¤Ï Âоݥ¢¥É¥ì¥¹¤ò¸Æ¤ó¤Ç¡¢¥Ð¥Ã¥Õ¥¡¤Ë¤¤¤ì¤Ê¤¤¡£mmc2, mmc4 ¤Ç»ÈÍѤ¹¤ë¡£
285 static const struct range range_length = {0x0000, 0x4000};
286 struct dump_driver *d;
287 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
291 return read_count(v, d->log, &d->cpu, &range_address, &range_length);
294 static SQInteger ppu_read_count(HSQUIRRELVM v)
296 static const struct range range_address = {0x0000, 0x2000};
297 static const struct range range_length = {0x0001, 0x2000};
298 struct dump_driver *d;
299 SQRESULT r = qr_userpointer_get(v, (SQUserPointer) &d);
303 return read_count(v, d->log, &d->ppu, &range_address, &range_length);
306 static bool script_execute(HSQUIRRELVM v, struct config_dump *c, struct dump_driver *d)
309 if(SQ_FAILED(sqstd_dofile(v, _SC("dumpcore.nut"), SQFalse, SQTrue))){
310 d->log->append(d->log->object, "dump core script error\n");
312 }else if(SQ_FAILED(sqstd_dofile(v, _SC(c->script), SQFalse, SQTrue))){
314 snprintf(str, 80, "%s open error\n", c->script);
315 d->log->append(d->log->object, str);
318 SQRESULT r = qr_call(
319 v, "dump", (SQUserPointer) d, true,
320 3, c->mappernum, c->increase.cpu, c->increase.ppu
324 Free(d->cpu.memory.data);
325 Free(d->ppu.memory.data);
326 d->cpu.memory.data = NULL;
327 d->ppu.memory.data = NULL;
332 void script_dump_execute(struct config_dump *c)
334 struct dump_driver d = {
338 .size = 0, .offset = 0,
339 .attribute = MEMORY_ATTR_WRITE,
340 .transtype = TRANSTYPE_FULL,
344 .write = c->reader->cpu_write_6502,
345 .read = c->reader->cpu_read,
346 .gauge = &c->gauge_cpu
351 .size = 0, .offset = 0,
352 .attribute = MEMORY_ATTR_WRITE,
353 .transtype = TRANSTYPE_FULL,
357 .write = c->reader->ppu_write,
358 .read = c->reader->ppu_read,
359 .gauge = &c->gauge_ppu
361 .vram_connection = c->reader->vram_connection,
363 .progress = c->progress,
367 HSQUIRRELVM v = qr_open(&c->log);
368 qr_function_register_global(v, "ppu_ramfind", script_nop);
369 qr_function_register_global(v, "cpu_write", cpu_write_check);
370 qr_function_register_global(v, "memory_new", memory_new);
371 qr_function_register_global(v, "nesfile_save", length_check);
372 qr_function_register_global(v, "cpu_read", cpu_read_count);
373 qr_function_register_global(v, "ppu_read", ppu_read_count);
374 qr_function_register_global(v, "require", script_require);
375 if(script_execute(v, c, &d) == false){
381 if(c->progress == true){
385 HSQUIRRELVM v = qr_open(&c->log);
386 qr_function_register_global(v, "memory_new", script_nop);
387 qr_function_register_global(v, "nesfile_save", nesfile_save);
388 qr_function_register_global(v, "cpu_write", cpu_write);
389 qr_function_register_global(v, "cpu_read", cpu_read);
390 qr_function_register_global(v, "ppu_read", ppu_read);
391 qr_function_register_global(v, "ppu_ramfind", ppu_ramfind);
392 qr_function_register_global(v, "require", script_require);
393 script_execute(v, c, &d);