9 #include "memory_manage.h"
10 #include "reader_master.h"
11 #include "squirrel_wrap.h"
12 #include "script_common.h"
13 #include "script_dump.h"
20 void (*const write)(long address, long length, const uint8_t *data);
21 void (*const read)(long address, long length, u8 *data);
23 uint8_t (*const vram_connection)(void);
26 static SQInteger write(HSQUIRRELVM v, struct memory_driver *t)
29 SQRESULT r = qr_argument_get(v, 2, &address, &data);
33 uint8_t d8 = (uint8_t) data;
34 t->write(address, 1, &d8);
37 static SQInteger cpu_write(HSQUIRRELVM v)
39 struct dump_driver *d;
40 SQRESULT r = qr_userpointer_get(v, (SQUserPointer *) &d);
44 return write(v, &d->cpu);
47 static void buffer_show(struct memory *t, long length)
50 const uint8_t *buf = t->data + t->offset;
51 printf("%s 0x%06x:", t->name, t->offset);
52 for(i = 0; i < 0x10; i++){
54 sprintf(dump, "%02x", buf[i]);
75 printf(":0x%06x\n", sum);
79 static void progress_show(struct dump_driver *d)
81 if(d->progress == true){
82 progress_draw(d->cpu.memory.offset, d->cpu.memory.size, d->ppu.memory.offset, d->ppu.memory.size);
85 static SQInteger read(HSQUIRRELVM v, struct memory_driver *t, bool progress)
88 SQRESULT r = qr_argument_get(v, 2, &address, &length);
92 t->read(address, length == 0 ? 1: length, t->memory.data + t->memory.offset);
93 if((length != 0) && (progress == false)){
94 buffer_show(&t->memory, length);
96 t->memory.offset += length;
99 static SQInteger cpu_read(HSQUIRRELVM v)
101 struct dump_driver *d;
102 SQRESULT r = qr_userpointer_get(v, (SQUserPointer *) &d);
106 r = read(v, &d->cpu, d->progress);
111 static SQInteger ppu_read(HSQUIRRELVM v)
113 struct dump_driver *d;
114 SQRESULT r = qr_userpointer_get(v, (SQUserPointer *) &d);
118 r = read(v, &d->ppu, d->progress);
123 static SQInteger ppu_ramfind(HSQUIRRELVM v)
125 struct dump_driver *d;
130 static const uint8_t test_val[testsize] = {0xaa, 0x55, 0, 0xff, 0x46, 0x49, 0x07, 0x21};
131 static const uint8_t test_str[testsize] = "pputest";
132 uint8_t test_result[testsize];
134 SQRESULT r = qr_userpointer_get(v, (SQUserPointer *) &d);
138 d->ppu.write(testaddress, testsize, test_val);
139 d->ppu.read(testaddress, testsize, test_result);
140 if(memcmp(test_val, test_result, testsize) != 0){
141 sq_pushbool(v, SQFalse);
144 d->ppu.write(testaddress, testsize, test_str);
145 d->ppu.read(testaddress, testsize, test_result);
146 if(memcmp(test_str, test_result, testsize) != 0){
147 sq_pushbool(v, SQFalse);
150 d->ppu.memory.offset = 0;
151 d->ppu.memory.size = 0;
152 sq_pushbool(v, SQTrue);
156 //test »þ/1ÅÙÌܤΠcall ¤Ç»ÈÍÑ
157 static SQInteger memory_new(HSQUIRRELVM v)
159 struct dump_driver *d;
160 SQRESULT r = qr_userpointer_get(v, (SQUserPointer *) &d);
164 r = qr_argument_get(v, 2, &d->cpu.memory.size, &d->ppu.memory.size);
168 d->cpu.memory.offset = 0;
169 d->cpu.memory.data = Malloc(d->cpu.memory.size);
170 d->ppu.memory.offset = 0;
171 d->ppu.memory.data = Malloc(d->ppu.memory.size);
175 //dump »þ/2ÅÙÌܤΠcall ¤Ç nesfile_save ¤È¤·¤Æ»ÈÍÑ
176 static SQInteger nesfile_save(HSQUIRRELVM v)
178 struct dump_driver *d;
179 SQRESULT r = qr_userpointer_get(v, (SQUserPointer *) &d);
183 struct romimage image;
185 r = qr_argument_get(v, 2, &image.mappernum, &mirrorfind);
189 image.cpu_rom = d->cpu.memory;
190 image.cpu_ram.data = NULL;
191 image.ppu_rom = d->ppu.memory;
192 image.mirror = MIRROR_PROGRAMABLE;
194 if(d->vram_connection() == 0x05){
195 image.mirror = MIRROR_VERTICAL;
197 image.mirror = MIRROR_HORIZONAL;
201 nesfile_create(&image, d->target);
202 nesbuffer_free(&image, 0); //0 is MODE_xxx_xxxx
204 d->cpu.memory.data = NULL;
205 d->ppu.memory.data = NULL;
209 //dump »þ/1ÅÙÌܤΠcall ¤Ç nesfile_save ¤È¤·¤Æ»ÈÍÑ
210 static SQInteger length_check(HSQUIRRELVM v)
212 struct dump_driver *d;
213 SQRESULT r = qr_userpointer_get(v, (SQUserPointer *) &d);
217 bool cpu = true, ppu = true;
219 if(d->cpu.memory.size != d->cpu.read_count){
223 printf("cpu_romsize is not connected 0x%06x/0x%06x\n", (int) d->cpu.read_count, (int) d->cpu.memory.size);
225 if(d->ppu.memory.size != d->ppu.read_count){
229 printf("ppu_romsize is not connected 0x%06x/0x%06x\n", (int) d->ppu.read_count, (int) d->ppu.memory.size);
231 if(cpu == false || ppu == false){
232 r = sq_throwerror(v, "script logical error");
237 static SQInteger read_count(HSQUIRRELVM v, struct memory_driver *t, const struct range *range_address, const struct range *range_length)
239 long address, length;
240 SQRESULT r = qr_argument_get(v, 2, &address, &length);
244 r = range_check(v, "length", length, range_length);
248 if((address < range_address->start) || ((address + length) > range_address->end)){
249 printf("address range must be 0x%06x to 0x%06x", (int) range_address->start, (int) range_address->end);
250 return sq_throwerror(v, "script logical error");;
252 t->read_count += length;
255 static SQInteger cpu_read_count(HSQUIRRELVM v)
257 static const struct range range_address = {0x8000, 0x10000};
258 //length == 0 ¤Ï Âоݥ¢¥É¥ì¥¹¤ò¸Æ¤ó¤Ç¡¢¥Ð¥Ã¥Õ¥¡¤Ë¤¤¤ì¤Ê¤¤¡£mmc2, mmc4 ¤Ç»ÈÍѤ¹¤ë¡£
259 static const struct range range_length = {0x0000, 0x4000};
260 struct dump_driver *d;
261 SQRESULT r = qr_userpointer_get(v, (SQUserPointer *) &d);
265 return read_count(v, &d->cpu, &range_address, &range_length);
268 static SQInteger ppu_read_count(HSQUIRRELVM v)
270 static const struct range range_address = {0x0000, 0x2000};
271 static const struct range range_length = {0x0001, 0x2000};
272 struct dump_driver *d;
273 SQRESULT r = qr_userpointer_get(v, (SQUserPointer *) &d);
277 return read_count(v, &d->ppu, &range_address, &range_length);
280 static bool script_execute(HSQUIRRELVM v, struct config_dump *c, struct dump_driver *d)
283 if(SQ_FAILED(sqstd_dofile(v, _SC("dumpcore.nut"), SQFalse, SQTrue))){
284 printf("dump core script error\n");
286 }else if(SQ_FAILED(sqstd_dofile(v, _SC(c->script), SQFalse, SQTrue))){
287 printf("%s open error\n", c->script);
290 SQRESULT r = qr_call(
291 v, "dump", (SQUserPointer) d, true,
292 3, c->mappernum, c->increase.cpu, c->increase.ppu
296 Free(d->cpu.memory.data);
297 Free(d->ppu.memory.data);
298 d->cpu.memory.data = NULL;
299 d->ppu.memory.data = NULL;
304 void script_dump_execute(struct config_dump *c)
306 struct dump_driver d = {
310 .size = 0, .offset = 0,
311 .attribute = MEMORY_ATTR_WRITE,
312 .transtype = TRANSTYPE_FULL,
316 .write = c->reader->cpu_write_6502,
317 .read = c->reader->cpu_read
322 .size = 0, .offset = 0,
323 .attribute = MEMORY_ATTR_WRITE,
324 .transtype = TRANSTYPE_FULL,
328 .write = c->reader->ppu_write,
329 .read = c->reader->ppu_read
331 .vram_connection = c->reader->vram_connection,
333 .progress = c->progress
336 HSQUIRRELVM v = qr_open();
337 qr_function_register_global(v, "ppu_ramfind", script_nop);
338 qr_function_register_global(v, "cpu_write", cpu_write_check);
339 qr_function_register_global(v, "memory_new", memory_new);
340 qr_function_register_global(v, "nesfile_save", length_check);
341 qr_function_register_global(v, "cpu_read", cpu_read_count);
342 qr_function_register_global(v, "ppu_read", ppu_read_count);
343 if(script_execute(v, c, &d) == false){
349 if(c->progress == true){
353 HSQUIRRELVM v = qr_open();
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 script_execute(v, c, &d);