6 #include "memory_manage.h"
11 #include "reader_master.h"
12 #include "reader_kazzo.h"
13 #include "reader_dummy.h"
14 #include "script_dump.h"
15 #include "flash_device.h"
16 #include "script_program.h"
21 #define PRINTF wprintf
22 #define STRTOUL wcstoul
26 #define STRTOUL strtoul
29 static void text_append_va(void *obj, const wgChar *format, va_list list)
32 vwprintf(format, list);
34 vprintf(format, list);
38 static void text_append(void *obj, const wgChar *format, ...)
41 va_start(list, format);
42 text_append_va(obj, format, list);
46 static void log_set(struct textcontrol *log)
49 log->append = text_append;
50 log->append_va = text_append_va;
53 static void except(const wgChar *str)
59 static bool program_rom_set(const wgChar *device, wgChar trans, struct memory *m, struct flash_device *f)
62 if(flash_device_get(device, f) == false){
63 PRINTF(wgT("unknown flash memory device %s\n"), device);
68 m->transtype = TRANSTYPE_FULL;
71 m->transtype = TRANSTYPE_TOP;
74 m->transtype = TRANSTYPE_BOTTOM;
78 m->transtype = TRANSTYPE_EMPTY;
84 static void program(int c, wgChar **v, const struct reader_driver *r)
86 struct program_config config;
87 config.cpu.memory.data = NULL;
88 config.ppu.memory.data = NULL;
91 config.control = &r->control;
92 config.cpu.access = &r->cpu;
93 config.ppu.access = &r->ppu;
94 config.compare = false;
96 case wgT('F'): case wgT('X'):
97 config.compare = true;
102 case 5: {//mode script target cpu_flash_device
103 wgChar trans = wgT('f');
104 if(v[1][1] != wgT('\0')){
107 if(program_rom_set(v[4], trans, &config.cpu.memory, &config.cpu.flash) == false){
110 if(program_rom_set(wgT("dummy"), wgT('e'), &config.ppu.memory, &config.ppu.flash) == false){
115 case 6: { //mode script target cpu_flash_device ppu_flash_device
116 wgChar trans = wgT('f');
117 if(v[1][1] != wgT('\0')){
120 if(program_rom_set(v[4], trans, &config.cpu.memory, &config.cpu.flash) == false){
124 if(v[1][1] != wgT('\0') && v[1][2] != wgT('\0')){
127 if(program_rom_set(v[5], trans, &config.ppu.memory, &config.ppu.flash) == false){
132 PUTS(wgT("mode script target cpu_flash_device ppu_flash_device"));
135 log_set(&config.log);
136 cui_gauge_new(&config.cpu.gauge, wgT("Program Flash"), 2, -2);
137 cui_gauge_new(&config.ppu.gauge, wgT("Charcter Flash"), 1, -1);
138 config.except = except;
139 script_program_execute(&config);
140 cui_gauge_destory(&config.cpu.gauge);
141 cui_gauge_destory(&config.ppu.gauge);
144 static void dump(int c, wgChar **v, const struct reader_driver *r)
146 struct dump_config config;
148 PUTS(wgT("argument error"));
151 config.cpu.increase = INCREASE_AUTO;
152 config.ppu.increase = 1;
153 config.progress = true;
155 case wgT('d'): case wgT('z'):
156 config.mode = MODE_ROM_DUMP;
159 config.mode = MODE_ROM_DUMP;
160 config.progress = false;
162 case wgT('r'): case wgT('R'):
163 config.mode = MODE_RAM_READ;
165 case wgT('w'): case wgT('W'):
166 config.mode = MODE_RAM_WRITE;
171 config.cpu.increase = 1;
174 config.cpu.increase = 2;
177 config.cpu.increase = 4;
180 if(v[1][1] != wgT('\0')){
183 config.ppu.increase = 2;
186 config.ppu.increase = 4;
190 config.script = v[2];
191 config.target = v[3];
192 config.control = &r->control;
193 config.cpu.access = &r->cpu;
194 config.ppu.access = &r->ppu;
195 if(config.mode == MODE_ROM_DUMP){
196 cui_gauge_new(&config.cpu.gauge, wgT("Program ROM"), 2, -2);
198 cui_gauge_new(&config.cpu.gauge, wgT("Work RAM"), 2, -2);
200 cui_gauge_new(&config.ppu.gauge, wgT("Charcter ROM"), 1, -1);
201 config.except = except;
202 config.mappernum = -1;
203 config.battery = false;
205 const wgChar *t = v[4];
206 if(*t == 'b' || *t == 'B'){
207 config.battery = true;
212 config.mappernum = _wtoi(t);
214 config.mappernum = atoi(t);
218 log_set(&config.log);
219 if(config.mode == MODE_ROM_DUMP){
220 script_dump_execute(&config);
222 script_workram_execute(&config);
224 cui_gauge_destory(&config.cpu.gauge);
225 cui_gauge_destory(&config.ppu.gauge);
228 static void vram_scan(int c, wgChar **v, const struct reader_driver *r)
230 const struct reader_handle *h;
231 struct textcontrol log;
233 PUTS(wgT("anago F [address] [data]..."));
237 h = r->control.open(except, &log);
240 PRINTF(wgT("%02x\n"), r->control.vram_connection(h));
242 const long address = STRTOUL(v[2], NULL, 0x10);
244 for(i = 3; i < c; i++){
245 const uint8_t d = STRTOUL(v[i], NULL, 0x10);
246 r->cpu.memory_write(h, address, 1, &d);
247 PRINTF(wgT("$%04x = 0x%02x->0x%02x\n"), address, (int) d, r->control.vram_connection(h));
253 static void crc32_dump(const wgChar *name, const wgChar *str, struct memory *m)
255 long banksize = STRTOUL(str, NULL, 0x10);
256 if(banksize < 0x400 || (banksize & 0xff) != 0){
257 PUTS(wgT("banksize requires over 0x400"));
260 if(banksize > m->size){
264 PRINTF(wgT("%s 0x%x byte\n"), name, m->size);
265 for(i = 0, j = 0; i < m->size; i += banksize, j++){
266 PRINTF(wgT("%02x:%08x\n"), j, crc32_get(m->data + i, banksize));
270 static void crc32_display(int c, wgChar **v)
273 PUTS(wgT("anago b [filename] [program ROM banksize]"));
277 struct textcontrol log;
279 if(nesfile_load(&log, v[2], &r) == false){
282 crc32_dump(wgT("Program ROM"), v[3], &r.cpu_rom);
283 if(c == 5 && r.ppu_rom.size != 0){
284 crc32_dump(wgT("Charcter ROM"), v[4], &r.ppu_rom);
286 nesbuffer_free(&r, 0);
289 static void usage(const wgChar *v)
291 PUTS(wgT("famicom bus simluator 'anago'"));
292 PRINTF(wgT("%s [mode] [script] [target] ....\n"), v);
293 PUTS(wgT("d - ROM dump with kazzo"));
294 PUTS(wgT("fF- flash program with kazzo"));
295 PUTS(wgT("r - workram read with kazzo"));
296 PUTS(wgT("w - workram write with kazzo"));
297 PUTS(wgT("v - VRAM A10 scan with kazzo"));
298 PUTS(wgT("b - display each CRC32s by required size"));
300 PUTS(wgT("z - ROM dump for test"));
301 PUTS(wgT("xX- flash program for test"));
302 PUTS(wgT("R - workram read for test"));
303 PUTS(wgT("W - workram write for test"));
308 int main(int c, char **vv)
310 int anago_cui(int c, wgChar **v)
315 const struct reader_driver *r = &DRIVER_KAZZO;
319 v = Malloc(sizeof(wchar_t *) * c);
320 for(i = 0; i < c; i++){
321 size_t len = strlen(vv[i]) + 1;
322 v[i] = Malloc(sizeof(wchar_t) * len);
323 mbstowcs(v[i], vv[i], len);
327 case wgT('x'): case wgT('X'):
328 r = &DRIVER_DUMMY; //though down
329 case wgT('f'): case wgT('F'):
332 case wgT('z'): case wgT('R'): case wgT('W'):
333 r = &DRIVER_DUMMY; //though down
334 case wgT('d'): case wgT('D'):
335 case wgT('r'): case wgT('w'):
348 PUTS(wgT("mode are d, D, f, g"));
352 for(i = 0; i < c; i++){
359 size_t len = strlen(vv[0]) + 1;
360 wchar_t *t = Malloc(sizeof(wchar_t) * len);
361 mbstowcs(t, vv[0], len);