7 #include "reader_master.h"
8 #include "squirrel_wrap.h"
9 #include "flash_device.h"
11 #include "script_flash.h"
14 struct anago_flash_order{
16 long address, length, program_count, program_offset;
17 long c000x, c2aaa, c5555;
18 struct memory *const memory;
19 struct flash_device *const device;
20 void (*const config)(long c000x, long c2aaa, long c5555, long unit);
21 void (*const device_get)(uint8_t s[2]);
22 void (*const write)(long address, long length, const uint8_t *data);
23 void (*const read)(long address, long length, u8 *data);
24 void (*const erase)(long address, bool dowait);
25 long (*const program)(long address, long length, const u8 *data, bool dowait);
26 }order_cpu, order_ppu;
27 void (*const flash_status)(uint8_t s[2]);
30 static SQInteger command_set(HSQUIRRELVM v, struct anago_flash_order *t)
32 long command, address ,mask;
33 SQRESULT r = qr_argument_get(v, 3, &command, &address, &mask);
37 long d = command & (mask - 1);
43 case 0x02aa: case 0x2aaa:
46 case 0x0555: case 0x5555:
50 return sq_throwerror(v, "unknown command address");
52 t->command_change = true;
55 static SQInteger cpu_command(HSQUIRRELVM v)
57 struct anago_driver *d;
58 SQRESULT r = qr_userpointer_get(v, (SQUserPointer *) &d);
62 return command_set(v, &d->order_cpu);
64 static SQInteger ppu_command(HSQUIRRELVM v)
66 struct anago_driver *d;
67 SQRESULT r = qr_userpointer_get(v, (SQUserPointer *) &d);
71 return command_set(v, &d->order_ppu);
73 static SQInteger write(HSQUIRRELVM v, struct anago_flash_order *t)
76 SQRESULT r = qr_argument_get(v, 2, &address, &data);
80 uint8_t d8 = (uint8_t) data;
81 t->write(address, 1, &d8);
84 static SQInteger cpu_write(HSQUIRRELVM v)
86 struct anago_driver *d;
87 SQRESULT r = qr_userpointer_get(v, (SQUserPointer *) &d);
91 return write(v, &d->order_cpu);
93 static SQInteger erase_set(HSQUIRRELVM v, struct anago_flash_order *t, const char *region)
95 t->config(t->c000x, t->c2aaa, t->c5555, t->device->pagesize);
96 t->command_change = false;
97 if(t->device->erase_require == true){
98 t->erase(t->c2aaa, false);
99 printf("erasing %s memory...\n", region);
102 return 0; //sq_suspendvm(v);
104 static SQInteger cpu_erase(HSQUIRRELVM v)
106 struct anago_driver *d;
107 SQRESULT r = qr_userpointer_get(v, (SQUserPointer *) &d);
111 return erase_set(v, &d->order_cpu, "program");
113 static SQInteger ppu_erase(HSQUIRRELVM v)
115 struct anago_driver *d;
116 SQRESULT r = qr_userpointer_get(v, (SQUserPointer *) &d);
120 return erase_set(v, &d->order_ppu, "charcter");
122 static SQInteger program_regist(HSQUIRRELVM v, const char *name, struct anago_flash_order *t)
124 SQRESULT r = qr_argument_get(v, 2, &t->address, &t->length);
128 if(t->command_change == true){
129 t->config(t->c000x, t->c2aaa, t->c5555, t->device->pagesize);
130 t->command_change = false;
133 /* printf("programming %s ROM area 0x%06x...\n", name, t->memory->offset);
135 return sq_suspendvm(v);
137 static void program_execute(struct anago_flash_order *t)
139 /* printf("writing %06x\n", t->memory->offset);
141 const long w = t->program(t->address, t->length, t->memory->data + t->memory->offset, false);
144 t->memory->offset += w;
145 t->memory->offset &= t->memory->size - 1;
146 t->program_offset += w;
148 static SQInteger cpu_program_memory(HSQUIRRELVM v)
150 struct anago_driver *d;
151 SQRESULT r = qr_userpointer_get(v, (SQUserPointer *) &d);
155 return program_regist(v, "program", &d->order_cpu);
157 static SQInteger ppu_program_memory(HSQUIRRELVM v)
159 struct anago_driver *d;
160 SQRESULT r = qr_userpointer_get(v, (SQUserPointer *) &d);
164 return program_regist(v, "charcter", &d->order_ppu);
167 static long erase_timer_get(struct anago_flash_order *t)
170 (t->memory->transtype != TRANSTYPE_EMPTY) &&
171 (t->device->erase_require == true)
173 return t->device->erase_wait;
178 static SQInteger erase_wait(HSQUIRRELVM v)
180 struct anago_driver *d;
181 SQRESULT r = qr_userpointer_get(v, (SQUserPointer *) &d);
186 long timer_wait = erase_timer_get(&d->order_cpu);
187 long timer_ppu = erase_timer_get(&d->order_ppu);
188 if(timer_wait < timer_ppu){
189 timer_wait = timer_ppu;
197 }while((s[0] != 0) && (s[1] != 0));
202 static SQInteger program_main(HSQUIRRELVM v)
204 if(sq_gettop(v) != (1 + 3)){ //roottable, userpointer, co_cpu, co_ppu
205 return sq_throwerror(v, "argument number error");
207 struct anago_driver *d;
208 SQRESULT r = qr_userpointer_get(v, (SQUserPointer *) &d);
212 HSQUIRRELVM co_cpu, co_ppu;
213 if(SQ_FAILED(sq_getthread(v, 3, &co_cpu))){
214 return sq_throwerror(v, "thread error");
216 if(SQ_FAILED(sq_getthread(v, 4, &co_ppu))){
217 return sq_throwerror(v, "thread error");
219 SQInteger state_cpu = sq_getvmstate(co_cpu);
220 SQInteger state_ppu = sq_getvmstate(co_ppu);
223 while((state_cpu != SQ_VMSTATE_IDLE) || (state_ppu != SQ_VMSTATE_IDLE)){
225 bool console_update = false;
228 if(state_cpu != SQ_VMSTATE_IDLE && s[0] == 0){
229 if(d->order_cpu.length == 0){
230 sq_wakeupvm(co_cpu, SQFalse, SQFalse, SQTrue/*, SQTrue*/);
231 state_cpu = sq_getvmstate(co_cpu);
233 program_execute(&d->order_cpu);
234 console_update = true;
237 if(state_ppu != SQ_VMSTATE_IDLE && s[1] == 0){
238 if(d->order_ppu.length == 0){
239 sq_wakeupvm(co_ppu, SQFalse, SQFalse, SQTrue/*, SQTrue*/);
240 state_ppu = sq_getvmstate(co_ppu);
242 program_execute(&d->order_ppu);
243 console_update = true;
246 if(console_update == true){
247 progress_draw(d->order_cpu.program_offset, d->order_cpu.program_count, d->order_ppu.program_offset, d->order_ppu.program_count);
253 static SQInteger script_nop(HSQUIRRELVM v)
258 static SQInteger program_count(HSQUIRRELVM v, struct anago_flash_order *t)
260 SQRESULT r = qr_argument_get(v, 2, &t->address, &t->length);
264 t->program_count += t->length;
267 static SQInteger cpu_program_count(HSQUIRRELVM v)
269 struct anago_driver *d;
270 SQRESULT r = qr_userpointer_get(v, (SQUserPointer *) &d);
274 return program_count(v, &d->order_cpu);
277 static SQInteger ppu_program_count(HSQUIRRELVM v)
279 struct anago_driver *d;
280 SQRESULT r = qr_userpointer_get(v, (SQUserPointer *) &d);
284 return program_count(v, &d->order_ppu);
287 static bool script_testrun(struct config_flash *c, struct anago_driver *d)
289 static const char *functionname[] = {
290 "cpu_write", "cpu_erase", "cpu_command",
291 "ppu_write", "ppu_erase", "ppu_command",
292 "erase_wait", "program_main"
294 HSQUIRRELVM v = qr_open();
296 for(i = 0; i < sizeof(functionname)/sizeof(char *); i++){
297 qr_function_register_global(v, functionname[i], script_nop);
299 qr_function_register_global(v, "cpu_program", cpu_program_count);
300 qr_function_register_global(v, "ppu_program", ppu_program_count);
303 if(SQ_FAILED(sqstd_dofile(v, _SC("flashcore.nut"), SQFalse, SQTrue))){
304 printf("flash core script error\n");
306 }else if(SQ_FAILED(sqstd_dofile(v, _SC(c->script), SQFalse, SQTrue))){
307 printf("%s open error\n", c->script);
311 v, "program", (SQUserPointer) d, true,
313 d->order_cpu.memory->transtype, d->order_cpu.memory->size,
314 d->order_ppu.memory->transtype, d->order_ppu.memory->size
321 void script_flash_execute(struct config_flash *c)
323 struct anago_driver d = {
325 .command_change = true,
328 .device = &c->flash_cpu,
329 .memory = &c->rom.cpu_rom,
330 .config = c->reader->cpu_flash_config,
331 .device_get = c->reader->cpu_flash_device_get,
332 .write = c->reader->cpu_write_6502,
333 .read = c->reader->cpu_read,
334 .erase = c->reader->cpu_flash_erase,
335 .program = c->reader->cpu_flash_program
338 .command_change = true,
341 .device = &c->flash_ppu,
342 .memory = &c->rom.ppu_rom,
343 .config = c->reader->ppu_flash_config,
344 .device_get = c->reader->ppu_flash_device_get,
345 .write = c->reader->ppu_write,
346 .read = c->reader->ppu_read,
347 .erase = c->reader->ppu_flash_erase,
348 .program = c->reader->ppu_flash_program,
350 .flash_status = c->reader->flash_status
352 if(script_testrun(c, &d) == false){
356 HSQUIRRELVM v = qr_open();
357 qr_function_register_global(v, "cpu_write", cpu_write);
358 qr_function_register_global(v, "cpu_erase", cpu_erase);
359 qr_function_register_global(v, "cpu_program", cpu_program_memory);
360 qr_function_register_global(v, "cpu_command", cpu_command);
361 qr_function_register_global(v, "ppu_erase", ppu_erase);
362 qr_function_register_global(v, "ppu_program", ppu_program_memory);
363 qr_function_register_global(v, "ppu_command", ppu_command);
364 qr_function_register_global(v, "program_main", program_main);
365 qr_function_register_global(v, "erase_wait", erase_wait);
367 if(SQ_FAILED(sqstd_dofile(v, _SC("flashcore.nut"), SQFalse, SQTrue))){
368 printf("flash core script error\n");
369 }else if(SQ_FAILED(sqstd_dofile(v, _SC(c->script), SQFalse, SQTrue))){
370 printf("%s open error\n", c->script);
373 v, "program", (SQUserPointer) &d, true,
375 d.order_cpu.memory->transtype, d.order_cpu.memory->size,
376 d.order_ppu.memory->transtype, d.order_ppu.memory->size