OSDN Git Service

38ae17f2cff08d53fcd5316aae3a651208a7be7c
[unagi/old-svn-converted.git] / client / trunk / anago / script_flash.c
1 #include <stdio.h>
2 #include <squirrel.h>
3 #include <sqstdio.h>
4 #include <sqstdaux.h>
5 #include "type.h"
6 #include "header.h"
7 #include "reader_master.h"
8 #include "squirrel_wrap.h"
9 #include "flash_device.h"
10 #include "progress.h"
11 #include "script_flash.h"
12
13 struct anago_driver{
14         struct anago_flash_order{
15                 bool command_change;
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]);
28 };
29
30 static SQInteger command_set(HSQUIRRELVM v, struct anago_flash_order *t)
31 {
32         long command, address ,mask;
33         SQRESULT r = qr_argument_get(v, 3, &command, &address, &mask);
34         if(SQ_FAILED(r)){
35                 return r;
36         }
37         long d = command & (mask - 1);
38         d |= address;
39         switch(command){
40         case 0x0000:
41                 t->c000x = d;
42                 break;
43         case 0x02aa: case 0x2aaa:
44                 t->c2aaa = d;
45                 break;
46         case 0x0555: case 0x5555:
47                 t->c5555 = d;
48                 break;
49         default:
50                 return sq_throwerror(v, "unknown command address");
51         }
52         t->command_change = true;
53         return 0;
54 }
55 static SQInteger cpu_command(HSQUIRRELVM v)
56 {
57         struct anago_driver *d;
58         SQRESULT r =  qr_userpointer_get(v, (SQUserPointer *) &d);
59         if(SQ_FAILED(r)){
60                 return r;
61         }
62         return command_set(v, &d->order_cpu);
63 }
64 static SQInteger ppu_command(HSQUIRRELVM v)
65 {
66         struct anago_driver *d;
67         SQRESULT r =  qr_userpointer_get(v, (SQUserPointer *) &d);
68         if(SQ_FAILED(r)){
69                 return r;
70         }
71         return command_set(v, &d->order_ppu);
72 }
73 static SQInteger write(HSQUIRRELVM v, struct anago_flash_order *t)
74 {
75         long address, data;
76         SQRESULT r = qr_argument_get(v, 2, &address, &data);
77         if(SQ_FAILED(r)){
78                 return r;
79         }
80         uint8_t d8 = (uint8_t) data;
81         t->write(address, 1, &d8);
82         return 0;
83 }
84 static SQInteger cpu_write(HSQUIRRELVM v)
85 {
86         struct anago_driver *d;
87         SQRESULT r =  qr_userpointer_get(v, (SQUserPointer *) &d);
88         if(SQ_FAILED(r)){
89                 return r;
90         }
91         return write(v, &d->order_cpu);
92 }
93 static SQInteger erase_set(HSQUIRRELVM v, struct anago_flash_order *t, const char *region)
94 {
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);
100                 fflush(stdout);
101         }
102         return 0; //sq_suspendvm(v);
103 }
104 static SQInteger cpu_erase(HSQUIRRELVM v)
105 {
106         struct anago_driver *d;
107         SQRESULT r =  qr_userpointer_get(v, (SQUserPointer *) &d);
108         if(SQ_FAILED(r)){
109                 return r;
110         }
111         return erase_set(v, &d->order_cpu, "program");
112 }
113 static SQInteger ppu_erase(HSQUIRRELVM v)
114 {
115         struct anago_driver *d;
116         SQRESULT r =  qr_userpointer_get(v, (SQUserPointer *) &d);
117         if(SQ_FAILED(r)){
118                 return r;
119         }
120         return erase_set(v, &d->order_ppu, "charcter");
121 }
122 static SQInteger program_regist(HSQUIRRELVM v, const char *name, struct anago_flash_order *t)
123 {
124         SQRESULT r = qr_argument_get(v, 2, &t->address, &t->length);
125         if(SQ_FAILED(r)){
126                 return r;
127         }
128         if(t->command_change == true){
129                 t->config(t->c000x, t->c2aaa, t->c5555, t->device->pagesize);
130                 t->command_change = false;
131         }
132         
133 /*      printf("programming %s ROM area 0x%06x...\n", name, t->memory->offset);
134         fflush(stdout);*/
135         return sq_suspendvm(v);
136 }
137 static void program_execute(struct anago_flash_order *t)
138 {
139 /*      printf("writing %06x\n", t->memory->offset);
140         fflush(stdout);*/
141         const long w = t->program(t->address, t->length, t->memory->data + t->memory->offset, false);
142         t->address += w;
143         t->length -= w;
144         t->memory->offset += w;
145         t->memory->offset &= t->memory->size - 1;
146         t->program_offset += w;
147 }
148 static SQInteger cpu_program_memory(HSQUIRRELVM v)
149 {
150         struct anago_driver *d;
151         SQRESULT r =  qr_userpointer_get(v, (SQUserPointer *) &d);
152         if(SQ_FAILED(r)){
153                 return r;
154         }
155         return program_regist(v, "program", &d->order_cpu);
156 }
157 static SQInteger ppu_program_memory(HSQUIRRELVM v)
158 {
159         struct anago_driver *d;
160         SQRESULT r =  qr_userpointer_get(v, (SQUserPointer *) &d);
161         if(SQ_FAILED(r)){
162                 return r;
163         }
164         return program_regist(v, "charcter", &d->order_ppu);
165 }
166
167 static long erase_timer_get(struct anago_flash_order *t)
168 {
169         if(
170                 (t->memory->transtype != TRANSTYPE_EMPTY) && 
171                 (t->device->erase_require == true)
172         ){
173                 return t->device->erase_wait;
174         }else{
175                 return 0;
176         }
177 }
178 static SQInteger erase_wait(HSQUIRRELVM v)
179 {
180         struct anago_driver *d;
181         SQRESULT r =  qr_userpointer_get(v, (SQUserPointer *) &d);
182         if(SQ_FAILED(r)){
183                 return r;
184         }
185         if(0){
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;
190                 }
191                 Sleep(timer_wait);
192         }else{
193                 uint8_t s[2];
194                 do{
195                         Sleep(2);
196                         d->flash_status(s);
197                 }while((s[0] != 0) && (s[1] != 0));
198         }
199         return 0;
200 }
201
202 static SQInteger program_main(HSQUIRRELVM v)
203 {
204         if(sq_gettop(v) != (1 + 3)){ //roottable, userpointer, co_cpu, co_ppu
205                 return sq_throwerror(v, "argument number error");
206         }
207         struct anago_driver *d;
208         SQRESULT r =  qr_userpointer_get(v, (SQUserPointer *) &d);
209         if(SQ_FAILED(r)){
210                 return r;
211         }
212         HSQUIRRELVM co_cpu, co_ppu;
213         if(SQ_FAILED(sq_getthread(v, 3, &co_cpu))){
214                 return sq_throwerror(v, "thread error");
215         }
216         if(SQ_FAILED(sq_getthread(v, 4, &co_ppu))){
217                 return sq_throwerror(v, "thread error");
218         }
219         SQInteger state_cpu = sq_getvmstate(co_cpu);
220         SQInteger state_ppu = sq_getvmstate(co_ppu);
221
222         progress_init();
223         while((state_cpu != SQ_VMSTATE_IDLE) || (state_ppu != SQ_VMSTATE_IDLE)){
224                 uint8_t s[2];
225                 bool console_update = false;
226                 Sleep(2);
227                 d->flash_status(s);
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);
232                         }else{
233                                 program_execute(&d->order_cpu);
234                                 console_update = true;
235                         }
236                 }
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);
241                         }else{
242                                 program_execute(&d->order_ppu);
243                                 console_update = true;
244                         }
245                 }
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);
248                 }
249         }
250         return 0;
251 }
252
253 static SQInteger script_nop(HSQUIRRELVM v)
254 {
255         return 0;
256 }
257
258 static SQInteger program_count(HSQUIRRELVM v, struct anago_flash_order *t)
259 {
260         SQRESULT r = qr_argument_get(v, 2, &t->address, &t->length);
261         if(SQ_FAILED(r)){
262                 return r;
263         }
264         t->program_count += t->length;
265         return 0;
266 }
267 static SQInteger cpu_program_count(HSQUIRRELVM v)
268 {
269         struct anago_driver *d;
270         SQRESULT r =  qr_userpointer_get(v, (SQUserPointer *) &d);
271         if(SQ_FAILED(r)){
272                 return r;
273         }
274         return program_count(v, &d->order_cpu);
275 }
276
277 static SQInteger ppu_program_count(HSQUIRRELVM v)
278 {
279         struct anago_driver *d;
280         SQRESULT r =  qr_userpointer_get(v, (SQUserPointer *) &d);
281         if(SQ_FAILED(r)){
282                 return r;
283         }
284         return program_count(v, &d->order_ppu);
285 }
286
287 static bool script_testrun(struct config_flash *c, struct anago_driver *d)
288 {
289         static const char *functionname[] = {
290                 "cpu_write", "cpu_erase", "cpu_command",
291                 "ppu_write", "ppu_erase", "ppu_command",
292                 "erase_wait", "program_main"
293         };
294         HSQUIRRELVM v = qr_open();
295         int i;
296         for(i = 0; i < sizeof(functionname)/sizeof(char *); i++){
297                 qr_function_register_global(v, functionname[i], script_nop);
298         }
299         qr_function_register_global(v, "cpu_program", cpu_program_count);
300         qr_function_register_global(v, "ppu_program", ppu_program_count);
301
302         bool ret = true;
303         if(SQ_FAILED(sqstd_dofile(v, _SC("flashcore.nut"), SQFalse, SQTrue))){
304                 printf("flash core script error\n");
305                 ret = false;
306         }else if(SQ_FAILED(sqstd_dofile(v, _SC(c->script), SQFalse, SQTrue))){
307                 printf("%s open error\n", c->script);
308                 ret = false;
309         }else{
310                 qr_call(
311                         v, "program", (SQUserPointer) d, true, 
312                         5, c->rom.mappernum, 
313                         d->order_cpu.memory->transtype, d->order_cpu.memory->size, 
314                         d->order_ppu.memory->transtype, d->order_ppu.memory->size
315                 );
316         }
317
318         qr_close(v);
319         return ret;
320 }
321 void script_flash_execute(struct config_flash *c)
322 {
323         struct anago_driver d = {
324                 .order_cpu = {
325                         .command_change = true,
326                         .program_count = 0,
327                         .program_offset = 0,
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
336                 },
337                 .order_ppu = {
338                         .command_change = true,
339                         .program_count = 0,
340                         .program_offset = 0,
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,
349                 },
350                 .flash_status = c->reader->flash_status
351         };
352         if(script_testrun(c, &d) == false){
353                 return;
354         }
355         
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);
366         
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);
371         }else{
372                 qr_call(
373                         v, "program", (SQUserPointer) &d, true, 
374                         5, c->rom.mappernum, 
375                         d.order_cpu.memory->transtype, d.order_cpu.memory->size, 
376                         d.order_ppu.memory->transtype, d.order_ppu.memory->size
377                 );
378         }
379
380         qr_close(v);
381 }