OSDN Git Service

append programmer 'anago'
authornaruko <naruko@24ea1065-a21e-4ca1-99c9-f5125deb0858>
Wed, 4 Nov 2009 13:58:10 +0000 (13:58 +0000)
committernaruko <naruko@24ea1065-a21e-4ca1-99c9-f5125deb0858>
Wed, 4 Nov 2009 13:58:10 +0000 (13:58 +0000)
git-svn-id: svn+ssh://svn.osdn.net/svnroot/unagi@300 24ea1065-a21e-4ca1-99c9-f5125deb0858

client/trunk/anago/Makefile [new file with mode: 0644]
client/trunk/anago/anago.c [new file with mode: 0644]
client/trunk/anago/flashmode.nut [new file with mode: 0644]
client/trunk/anago/reader_dummy.c [new file with mode: 0644]
client/trunk/anago/reader_dummy.h [new file with mode: 0644]
client/trunk/anago/script.c [new file with mode: 0644]
client/trunk/anago/script.h [new file with mode: 0644]
client/trunk/anago/script.lua.c [new file with mode: 0644]
client/trunk/anago/squirrel_wrap.c [new file with mode: 0644]
client/trunk/anago/squirrel_wrap.h [new file with mode: 0644]

diff --git a/client/trunk/anago/Makefile b/client/trunk/anago/Makefile
new file mode 100644 (file)
index 0000000..b68b803
--- /dev/null
@@ -0,0 +1,13 @@
+all: anago.exe
+LIBUSB = d:/dev/LibUSB-Win32
+SQUIRREL = ../SQUIRREL2
+VPATH = ..
+CFLAGS = -g -O0 -Wall -I.. -I$(LIBUSB)/include -I$(SQUIRREL)/include -DDEBUG=1 -DANAGO=1
+LDFLAG = -L. -L$(LIBUSB)/lib/gcc -L$(SQUIRREL)/lib
+CC = gcc
+OBJ = anago.o flashmemory.o header.o crc32.o file.o script.o \
+       reader_dummy.o reader_kazzo.o usb_device.o squirrel_wrap.o memory_manage.o
+clean:
+       rm -f $(OBJ)
+anago.exe: $(OBJ) 
+       g++ -o $@ $(LDFLAG) $(OBJ) -lusb -lsqstdlib -lsquirrel
diff --git a/client/trunk/anago/anago.c b/client/trunk/anago/anago.c
new file mode 100644 (file)
index 0000000..32a4549
--- /dev/null
@@ -0,0 +1,128 @@
+#include <stdio.h>
+#include <stdbool.h>
+#include "memory_manage.h"
+#include "type.h"
+#include "flashmemory.h"
+#include "header.h"
+#include "reader_master.h"
+#include "reader_kazzo.h"
+#include "reader_dummy.h"
+#include "script.h"
+
+static bool transtype_flash_set(char mode, struct memory *t)
+{
+       switch(mode){
+       case 't':
+               t->transtype = TRANSTYPE_TOP;
+               break;
+       case 'e':
+               t->transtype = TRANSTYPE_EMPTY;
+               break;
+       case 'b':
+               t->transtype = TRANSTYPE_BOTTOM;
+               break;
+       case 'f':
+               t->transtype = TRANSTYPE_FULL;
+               break;
+       default:
+               return false;
+       }
+       return true;
+}
+static bool transtype_set(const char *mode, struct romimage *t)
+{
+       switch(mode[0]){
+       case 'd': case 'f':
+               if(mode[1] == '\0'){
+                       t->cpu_rom.transtype = TRANSTYPE_FULL;
+                       t->ppu_rom.transtype = TRANSTYPE_FULL;
+                       return true;
+               }
+               if(transtype_flash_set(mode[1], &t->cpu_rom) == false){
+                       return false;
+               }
+               if(mode[2] == '\0'){
+                       t->ppu_rom.transtype = TRANSTYPE_FULL;
+                       return true;
+               }
+               if(transtype_flash_set(mode[2], &t->ppu_rom) == false){
+                       return false;
+               }
+               return true;
+       }
+       return false;
+}
+static bool config_parse(const char *romimage, const char *device_cpu, const char *device_ppu, struct config *c)
+{
+       c->target = romimage;
+       if(nesfile_load(__FUNCTION__, romimage, &c->rom) == false){
+               return false;
+       }
+       c->rom.cpu_rom.offset = 0;
+       c->rom.ppu_rom.offset = 0;
+       c->flash_cpu = flash_driver_get(device_cpu);
+       if(device_ppu != NULL){
+               c->flash_ppu = flash_driver_get(device_ppu);
+       }else{
+               c->flash_ppu = flash_driver_get("dummy");
+       }
+       if(c->flash_cpu == NULL || c->flash_ppu == NULL){
+               return false;
+       }
+       if(c->flash_cpu->id_device == FLASH_ID_DEVICE_DUMMY){
+               c->rom.cpu_rom.transtype = TRANSTYPE_EMPTY;
+       }
+       if(
+               (c->flash_ppu->id_device == FLASH_ID_DEVICE_DUMMY) ||
+               (c->rom.ppu_rom.size == 0)
+       ){
+               c->rom.ppu_rom.transtype = TRANSTYPE_EMPTY;
+       }
+       return true;
+}
+static void anago(int c, char **v)
+{
+       struct config config;
+       config.script = v[2];
+       config.flash_ppu = &FLASH_DRIVER_UNDEF;
+       config.reader = &DRIVER_KAZZO;
+       if(v[1][0] == 'd'){
+               config.reader = &DRIVER_DUMMY;
+       }       
+       if(transtype_set(v[1], &config.rom) == false){
+               puts("mode argument error");
+               return;
+       }
+       switch(c){
+       case 5: //mode script target cpu_flash_device
+               if(config_parse(v[3], v[4], NULL, &config) == false){
+                       nesbuffer_free(&config.rom, 0);
+                       return;
+               }
+               break;
+       case 6: //mode script target cpu_flash_device ppu_flash_device
+               if(config_parse(v[3], v[4], v[5], &config) == false){
+                       nesbuffer_free(&config.rom, 0);
+                       return;
+               }
+               break;
+       default:
+               puts("mode script target cpu_flash_device ppu_flash_device");
+               return;
+       }
+       if(config.reader->open_or_close(READER_OPEN) == NG){
+               puts("reader open error");
+               nesbuffer_free(&config.rom, 0);
+               return;
+       }
+       script_execute(&config);
+       nesbuffer_free(&config.rom, 0);
+       config.reader->open_or_close(READER_CLOSE);
+}
+int main(int c, char **v)
+{
+       mm_init();
+       anago(c, v);
+       mm_end();
+       return 0;
+}
diff --git a/client/trunk/anago/flashmode.nut b/client/trunk/anago/flashmode.nut
new file mode 100644 (file)
index 0000000..fe24544
--- /dev/null
@@ -0,0 +1,49 @@
+mega <- 0x20000;
+local trans_empty = 0;
+function loopsize_get(flashsize, trans, size)
+{
+       local trans_full = 3, trans_top = 1, trans_bottom = 2; //header.h enum transtype
+       local loop;
+       switch(trans){
+       case trans_full:
+               loop = flashsize.full;
+               break;
+       case trans_top:
+               loop = flashsize.top[size];
+               break;
+       case trans_bottom:
+               loop = flashsize.bottom[size];
+               break;
+       default:
+               loop = {start = 0, end = 0};
+               break;
+       }
+       return loop;
+}
+function program_init(mapper, cpu_trans, cpu_size, ppu_trans, ppu_size)
+{
+       if(board.mapper != mapper){
+               print("mapper number not connected");
+               return;
+       }
+       local cpu_loop = loopsize_get(board.cpu_flashsize, cpu_trans, cpu_size);
+       local ppu_loop = loopsize_get(board.ppu_flashsize, ppu_trans, ppu_size);
+       local co_cpu = newthread(program_cpu);
+       local co_ppu = newthread(program_ppu);
+       initalize();
+       if(cpu_trans != trans_empty){
+               cpu_erase();
+       }
+       if(ppu_trans != trans_empty){
+               ppu_erase();
+       }
+       erase_wait();
+       if(cpu_trans != 0){
+               co_cpu.call(cpu_loop);
+       }
+       if(ppu_trans != trans_empty){
+               co_ppu.call(ppu_loop);
+       }
+       program_main(co_cpu, co_ppu)
+}
+
diff --git a/client/trunk/anago/reader_dummy.c b/client/trunk/anago/reader_dummy.c
new file mode 100644 (file)
index 0000000..679075a
--- /dev/null
@@ -0,0 +1,105 @@
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include "reader_master.h"
+#include "reader_dummy.h"
+
+static void dummy_init(void)
+{
+}
+static int dummy_open_close(enum reader_control oc)
+{
+       return OK;
+}
+//---- cpu ----
+static void dummy_cpu_read(long address, long length, uint8_t *data)
+{
+       printf("%s %06x %04x\n", __FUNCTION__, (int) address, (int) length);
+       memset(data, 0x55, length);
+}
+static void dummy_cpu_write_6502(long address, long length, const uint8_t *data)
+{
+       printf("%s %04x %04x %02x\n", __FUNCTION__, (int) address, (int) length, (int) *data);
+}
+static void dummy_cpu_flash_config(long c000x, long c2aaa, long c5555, long unit)
+{
+       printf("%s %04x %04x %04x %04x\n", __FUNCTION__, (int) c000x, (int) c2aaa, (int) c5555, (int) unit);
+}
+static long dummy_cpu_flash_program(long address, long length, u8 *data, bool dowait)
+{
+       int i = 0x10;
+       printf("%s %06x\n", __FUNCTION__, (int) address);
+       while(i != 0){
+               printf("%02x ", *data);
+               data++;
+               i--;
+       }
+       printf("\n");
+       return 0x100;
+}
+
+static void dummy_cpu_flash_erase(long address, bool dowait)
+{
+       printf("%s %04x\n", __FUNCTION__, (int) address);
+}
+
+//---- ppu ----
+static void dummy_ppu_read(long address, long length, u8 *data)
+{
+       printf("%s %06x %04x\n", __FUNCTION__, (int) address, (int) length);
+       memset(data, 0x55, length);
+}
+static void dummy_ppu_write(long address, long length, const uint8_t *data)
+{
+       printf("%s %04x %04x %02x\n", __FUNCTION__, (int) address, (int) length, (int) *data);
+}
+static void dummy_ppu_flash_config(long c000x, long c2aaa, long c5555, long unit)
+{
+       printf("%s %04x %04x %04x %04x\n", __FUNCTION__, (int) c000x, (int) c2aaa, (int) c5555, (int) unit);
+}
+static long dummy_ppu_flash_program(long address, long length, u8 *data, bool dowait)
+{
+       int i = 0x10;
+       printf("%s %06x\n", __FUNCTION__, (int) address);
+       while(i != 0){
+               printf("%02x ", *data);
+               data++;
+               i--;
+       }
+       printf("\n");
+       return 0x100;
+}
+
+static void dummy_ppu_flash_erase(long address, bool dowait)
+{
+       printf("%s %04x\n", __FUNCTION__, (int) address);
+}
+
+static void dummy_flash_status(uint8_t s[2])
+{
+       s[0] = 0;
+       s[1] = 0;
+}
+static void dummy_flash_device_get(uint8_t s[2])
+{
+       s[0] = 0x01;
+       s[1] = 0xa4;
+}
+const struct reader_driver DRIVER_DUMMY = {
+       .name = "tester",
+       .open_or_close = dummy_open_close,
+       .init = dummy_init,
+       .cpu_read = dummy_cpu_read, .ppu_read = dummy_ppu_read,
+       .cpu_write_6502 = dummy_cpu_write_6502,
+       .flash_support = OK,
+       .ppu_write = dummy_ppu_write,
+       .cpu_flash_config = dummy_cpu_flash_config,
+       .cpu_flash_erase = dummy_cpu_flash_erase,
+       .cpu_flash_program = dummy_cpu_flash_program,
+       .cpu_flash_device_get = dummy_flash_device_get,
+       .ppu_flash_config = dummy_ppu_flash_config,
+       .ppu_flash_erase = dummy_ppu_flash_erase,
+       .ppu_flash_program = dummy_ppu_flash_program,
+       .ppu_flash_device_get = dummy_flash_device_get,
+       .flash_status = dummy_flash_status
+};
diff --git a/client/trunk/anago/reader_dummy.h b/client/trunk/anago/reader_dummy.h
new file mode 100644 (file)
index 0000000..0bdfb3c
--- /dev/null
@@ -0,0 +1,4 @@
+#ifndef _READER_DUMMY_H_
+#define _READER_DUMMY_H_
+const struct reader_driver DRIVER_DUMMY;
+#endif
diff --git a/client/trunk/anago/script.c b/client/trunk/anago/script.c
new file mode 100644 (file)
index 0000000..63d1b38
--- /dev/null
@@ -0,0 +1,243 @@
+#include <stdio.h>
+#include <squirrel.h>
+#include <sqstdio.h>
+#include <sqstdaux.h>
+#include "type.h"
+#include "header.h"
+#include "reader_master.h"
+#include "squirrel_wrap.h"
+#include "script.h"
+
+static struct anago_flash_order{
+       bool command_change;
+       long address, length;
+       long c000x, c2aaa, c5555, unit;
+       struct memory *memory;
+       void (*config)(long c000x, long c2aaa, long c5555, long unit);
+       void (*device_get)(uint8_t s[2]);
+       void (*flash_status)(uint8_t s[2]);
+       void (*write)(long address, long length, const uint8_t *data);
+       void (*read)(long address, long length, u8 *data);
+       void (*erase)(long address, bool dowait);
+       long (*program)(long address, long length, const u8 *data, bool dowait);
+}order_cpu, order_ppu;
+
+static SQInteger command_set(HSQUIRRELVM v, struct anago_flash_order *t)
+{
+       long command, address ,mask;
+       SQRESULT r = qr_argument_get(v, 3, &command, &address, &mask);
+       if(SQ_FAILED(r)){
+               return r;
+       }
+       long d = command & (mask - 1);
+       d |= address;
+       switch(command){
+       case 0x0000:
+               t->c000x = d;
+               break;
+       case 0x02aa: case 0x2aaa:
+               t->c2aaa = d;
+               break;
+       case 0x0555: case 0x5555:
+               t->c5555 = d;
+               break;
+       default:
+               return sq_throwerror(v, "unknown command address");
+       }
+       t->command_change = true;
+       return 0;
+}
+static SQInteger cpu_command(HSQUIRRELVM v)
+{
+       return command_set(v, &order_cpu);
+}
+static SQInteger ppu_command(HSQUIRRELVM v)
+{
+       return command_set(v, &order_ppu);
+}
+static SQInteger write(HSQUIRRELVM v, struct anago_flash_order *t)
+{
+       long address, data;
+       SQRESULT r = qr_argument_get(v, 2, &address, &data);
+       if(SQ_FAILED(r)){
+               return r;
+       }
+       uint8_t d8 = (uint8_t) data;
+       t->write(address, 1, &d8);
+       return 0;
+}
+static SQInteger cpu_write(HSQUIRRELVM v)
+{
+       return write(v, &order_cpu);
+}
+static SQInteger erase_set(HSQUIRRELVM v, struct anago_flash_order *t, const char *region)
+{
+       t->config(t->c000x, t->c2aaa, t->c5555, t->unit);
+       t->command_change = false;
+       t->erase(t->c2aaa, false);
+       printf("erasing %s memory...\n", region);
+       fflush(stdout);
+       return 0; //sq_suspendvm(v);
+}
+static SQInteger cpu_erase(HSQUIRRELVM v)
+{
+       return erase_set(v, &order_cpu, "program");
+}
+static SQInteger ppu_erase(HSQUIRRELVM v)
+{
+       return erase_set(v, &order_ppu, "charcter");
+}
+static SQInteger program_regist(HSQUIRRELVM v, const char *name, struct anago_flash_order *t)
+{
+       SQRESULT r = qr_argument_get(v, 2, &t->address, &t->length);
+       if(SQ_FAILED(r)){
+               return r;
+       }
+       if(t->command_change == true){
+               t->config(t->c000x, t->c2aaa, t->c5555, t->unit);
+               t->command_change = false;
+       }
+       
+       printf("programming %s ROM area 0x%06x...\n", name, t->memory->offset);
+       fflush(stdout);
+       return sq_suspendvm(v);
+}
+static void program_execute(struct anago_flash_order *t)
+{
+/*     printf("writing %06x\n", t->memory->offset);
+       fflush(stdout);*/
+       const long w = t->program(t->address, t->length, t->memory->data + t->memory->offset, false);
+       t->address += w;
+       t->length -= w;
+       t->memory->offset += w;
+}
+static SQInteger cpu_program(HSQUIRRELVM v)
+{
+       return program_regist(v, "program", &order_cpu);
+}
+static SQInteger ppu_program(HSQUIRRELVM v)
+{
+       return program_regist(v, "charcter", &order_ppu);
+}
+
+static SQInteger erase_wait(HSQUIRRELVM v)
+{
+       uint8_t s[2];
+       do{
+               Sleep(2);
+               order_cpu.flash_status(s);
+       }while((s[0] != 0) && (s[1] != 0));
+       return 0;
+}
+static void execute_main(HSQUIRRELVM v, struct config *c)
+{
+       if(SQ_FAILED(sqstd_dofile(v, _SC("flashmode.nut"), SQFalse, SQTrue)))
+       {
+               return;
+       }
+       if(SQ_FAILED(sqstd_dofile(v, _SC(c->script), SQFalse, SQTrue)))
+       {
+               return;
+       }
+       qr_call(
+               v, "program_init", true, 5, c->rom.mappernum, 
+               order_cpu.memory->transtype, order_cpu.memory->size, 
+               order_ppu.memory->transtype, order_ppu.memory->size
+       );
+}
+#if 0
+       HSQUIRRELVM co_cpu = sq_newthread(v, 0x400);
+       HSQUIRRELVM co_ppu = sq_newthread(v, 0x400);
+       SQInteger state_cpu, state_ppu;
+       qr_call(v, "initalize", true);
+       if(order_cpu.memory->size == 0 || c->flash_cpu->id_device == FLASH_ID_DEVICE_DUMMY){
+               state_cpu = SQ_VMSTATE_IDLE;
+       }else{
+               qr_call(co_cpu, "program_cpu", false);
+               state_cpu = sq_getvmstate(co_cpu);
+/*     config.reader->ppu_flash_device_get(s);
+       printf("ppu device %02x %02x\n", s[0], s[1]);*/
+       }
+       if(order_ppu.memory->size == 0 || c->flash_ppu->id_device == FLASH_ID_DEVICE_DUMMY){
+               state_ppu = SQ_VMSTATE_IDLE;
+       }else{
+               qr_call(co_ppu, "program_ppu", false);
+               state_ppu = sq_getvmstate(co_ppu);
+       }
+#endif
+static SQInteger program_main(HSQUIRRELVM v)
+{
+       if(sq_gettop(v) != (2 + 1)){
+               return sq_throwerror(v, "argument number error");
+       }
+       HSQUIRRELVM co_cpu, co_ppu;
+       if(SQ_FAILED(sq_getthread(v, 2, &co_cpu))){
+               return sq_throwerror(v, "thread error");
+       }
+       if(SQ_FAILED(sq_getthread(v, 3, &co_ppu))){
+               return sq_throwerror(v, "thread error");
+       }
+       SQInteger state_cpu = sq_getvmstate(co_cpu);
+       SQInteger state_ppu = sq_getvmstate(co_ppu);
+       while(state_cpu != SQ_VMSTATE_IDLE || state_ppu != SQ_VMSTATE_IDLE){
+               uint8_t s[2];
+               Sleep(2);
+               order_cpu.flash_status(s);
+               if(state_cpu != SQ_VMSTATE_IDLE && s[0] == 0){
+                       if(order_cpu.length == 0){
+                               sq_wakeupvm(co_cpu, SQFalse, SQFalse, SQTrue/*, SQTrue*/);
+                               state_cpu = sq_getvmstate(co_cpu);
+                       }else{
+                               program_execute(&order_cpu);
+                       }
+               }
+               if(state_ppu != SQ_VMSTATE_IDLE && s[1] == 0){
+                       if(order_ppu.length == 0){
+                               sq_wakeupvm(co_ppu, SQFalse, SQFalse, SQTrue/*, SQTrue*/);
+                               state_ppu = sq_getvmstate(co_ppu);
+                       }else{
+                               program_execute(&order_ppu);
+                       }
+               }
+       }
+       return 0;
+}
+void script_execute(struct config *c)
+{
+       order_cpu.command_change = true;
+       order_cpu.unit = c->flash_cpu->pagesize;
+       order_cpu.memory = &c->rom.cpu_rom;
+       order_cpu.config = c->reader->cpu_flash_config;
+       order_cpu.device_get = c->reader->cpu_flash_device_get;
+       order_cpu.write = c->reader->cpu_write_6502;
+       order_cpu.read = c->reader->cpu_read;
+       order_cpu.erase = c->reader->cpu_flash_erase;
+       order_cpu.program = c->reader->cpu_flash_program;
+       order_cpu.flash_status = c->reader->flash_status;
+       
+       order_ppu.command_change = true;
+       order_ppu.unit = c->flash_ppu->pagesize;
+       order_ppu.memory = &c->rom.ppu_rom;
+       order_ppu.config = c->reader->ppu_flash_config;
+       order_ppu.device_get = c->reader->ppu_flash_device_get;
+       order_ppu.write = c->reader->ppu_write; //warning ¤Ï̵»ë
+       order_ppu.read = c->reader->ppu_read;
+       order_ppu.erase = c->reader->ppu_flash_erase;
+       order_ppu.program = c->reader->ppu_flash_program;
+       order_ppu.flash_status = c->reader->flash_status;
+       
+       HSQUIRRELVM v = qr_open(); 
+       qr_function_register_global(v, "cpu_write", cpu_write);
+       qr_function_register_global(v, "cpu_erase", cpu_erase);
+       qr_function_register_global(v, "cpu_program", cpu_program);
+       qr_function_register_global(v, "cpu_command", cpu_command);
+       qr_function_register_global(v, "ppu_erase", ppu_erase);
+       qr_function_register_global(v, "ppu_program", ppu_program);
+       qr_function_register_global(v, "ppu_command", ppu_command);
+       qr_function_register_global(v, "program_main", program_main);
+       qr_function_register_global(v, "erase_wait", erase_wait);
+       
+       execute_main(v, c);
+
+       qr_close(v);
+}
diff --git a/client/trunk/anago/script.h b/client/trunk/anago/script.h
new file mode 100644 (file)
index 0000000..39330d4
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef _SCRIPT_H_
+#define _SCRIPT_H_
+struct config{
+       const char *script, *target;
+       const struct flash_driver *flash_cpu, *flash_ppu;
+       const struct reader_driver *reader;
+       struct romimage rom;
+};
+void script_execute(struct config *c);
+#endif
diff --git a/client/trunk/anago/script.lua.c b/client/trunk/anago/script.lua.c
new file mode 100644 (file)
index 0000000..62e7259
--- /dev/null
@@ -0,0 +1,198 @@
+#include <stdio.h>
+#include <stdbool.h>
+#include "lua.h"
+#include "lualib.h"
+#include "lauxlib.h"
+#include "type.h"
+#include "header.h"
+#include "reader_master.h"
+#include "script.h"
+
+static struct anago_flash_order{
+       int program_count, command_change;
+       long address, length;
+       long c2aaa, c5555, unit;
+       struct memory *memory;
+       void (*config)(long c2aaa, long c5555, long unit);
+       void (*write)(long address, long length, const uint8_t *data);
+       void (*read)(long address, long length, u8 *data);
+       void (*erase)(long address, bool dowait);
+       long (*program)(long address, long length, u8 *data, bool dowait);
+}order_cpu, order_ppu;
+static inline long long_get(lua_State *t, int index)
+{
+       lua_Number d = lua_tonumber(t, index);
+       return (long) d;
+}
+static void command_set(lua_State *l, struct anago_flash_order *t)
+{
+       long command = long_get(l, 1);
+       long address = long_get(l, 2);
+       long mask = long_get(l, 3);
+       long d = command & (mask - 1);
+       d |= address;
+       switch(command){
+       case 0x02aa: case 0x2aaa:
+               t->c2aaa = d;
+               break;
+       case 0x0555: case 0x5555:
+               t->c5555 = d;
+               break;
+       default:
+               puts("unknown command address");
+               return;
+       }
+       t->command_change += 1;
+}
+static int cpu_command(lua_State *l)
+{
+       command_set(l, &order_cpu);
+       return 0;
+}
+static int ppu_command(lua_State *l)
+{
+       command_set(l, &order_ppu);
+       return 0;
+}
+static int write(lua_State *l, struct anago_flash_order *t)
+{
+       long address = long_get(l, 1);
+       long data = long_get(l, 2);
+       uint8_t d8 = (uint8_t) data;
+       t->write(address, 1, &d8);
+       return 0;
+}
+static int cpu_write(lua_State *l)
+{
+       return write(l, &order_cpu);
+}
+static int program_regist(lua_State *l, const char *name, struct anago_flash_order *t)
+{
+       t->address = long_get(l, 1);
+       t->length = long_get(l, 2);
+       if(t->command_change != 0){
+               t->config(t->c2aaa, t->c5555, t->unit);
+               t->command_change = 0;
+       }
+       
+       printf("programming %s area 0x%06x...\n", name, t->memory->offset);
+       fflush(stdout);
+       return lua_yield(l, 0);
+}
+static void program_execute(struct anago_flash_order *t)
+{
+       if(t->program_count == 0){
+               t->erase(t->c2aaa, false);
+               t->program_count += 1;
+               printf("erase...\n");
+               fflush(stdout);
+               return;
+       }
+       t->program_count += 1;
+//     printf("writing %06x\n", t->memory->offset);
+//     fflush(stdout);
+       const long w = t->program(t->address, t->length, t->memory->data + t->memory->offset, false);
+       t->address += w;
+       t->length -= w;
+       t->memory->offset += w;
+}
+static int cpu_program(lua_State *l)
+{
+       return program_regist(l, "program ROM", &order_cpu);
+}
+static int ppu_program(lua_State *l)
+{
+       return program_regist(l, "charcter ROM", &order_ppu);
+}
+static int mmc1_write(lua_State *l)
+{
+       long address = long_get(l, 1);
+       uint8_t data = (uint8_t) long_get(l, 2);
+       int i = 5;
+       while(i != 0){
+               order_cpu.write(address, 1, &data);
+               data >>= 1;
+               i--;
+       }
+       return 0;
+}
+
+void script_execute(struct config *c)
+{
+       order_cpu.command_change = 0;
+       order_cpu.program_count = 0;
+       order_cpu.unit = c->flash_cpu->pagesize;
+       order_cpu.memory = &c->rom.cpu_rom;
+       order_cpu.config = c->reader->cpu_flash_config;
+       order_cpu.write = c->reader->cpu_write_6502;
+       order_cpu.read = c->reader->cpu_read;
+       order_cpu.erase = c->reader->cpu_flash_erase;
+       order_cpu.program = c->reader->cpu_flash_program;
+       
+       order_ppu.command_change = 0;
+       order_ppu.program_count = 0;
+       order_ppu.unit = c->flash_ppu->pagesize;
+       order_ppu.memory = &c->rom.ppu_rom;
+       order_ppu.config = c->reader->ppu_flash_config;
+       order_ppu.write = c->reader->ppu_write; //warning ¤Ï̵»ë
+       order_ppu.read = c->reader->ppu_read;
+       order_ppu.erase = c->reader->ppu_flash_erase;
+       order_ppu.program = c->reader->ppu_flash_program;
+       
+       lua_State *const l = lua_open();
+       luaL_openlibs(l);
+       lua_register(l, "cpu_write", cpu_write);
+       lua_register(l, "cpu_program", cpu_program);
+       lua_register(l, "cpu_command", cpu_command);
+       lua_register(l, "ppu_program", ppu_program);
+       lua_register(l, "ppu_command", ppu_command);
+       lua_register(l, "mmc1_write", mmc1_write);
+       if(luaL_loadfile(l, c->script) == LUA_ERRFILE){
+               lua_close(l);
+               return;
+       }
+       if(lua_pcall(l, 0, 0, 0) != 0){
+               puts(lua_tostring(l, -1));
+               return;
+       }
+       lua_getfield(l, LUA_GLOBALSINDEX, "initalize");
+       lua_getglobal(l, "initalize");
+       lua_call(l, 0, 0);
+       lua_State *const co_cpu = lua_newthread(l);
+       lua_State *const co_ppu = lua_newthread(l);
+       lua_getglobal(co_cpu, "program_cpu");
+       lua_getglobal(co_ppu, "program_ppu");
+       int state_cpu = LUA_YIELD, state_ppu = LUA_YIELD;
+       if(order_cpu.memory->size == 0 || c->flash_cpu->id_device == FLASH_ID_DEVICE_DUMMY){
+               state_cpu = 0;
+       }
+       if(order_ppu.memory->size == 0 || c->flash_ppu->id_device == FLASH_ID_DEVICE_DUMMY){
+               state_ppu = 0;
+       }
+       if(state_cpu != 0){
+               state_cpu = lua_resume(co_cpu, 0);
+       }
+       if(state_ppu != 0){
+               state_ppu = lua_resume(co_ppu, 0);
+       }
+       do{
+               uint8_t s[2];
+               Sleep(2);
+               c->reader->flash_status(s);
+               if(state_cpu != 0 && s[0] == 0){
+                       if(order_cpu.length == 0){
+                               state_cpu = lua_resume(co_cpu, 0);
+                       }else{
+                               program_execute(&order_cpu);
+                       }
+               }
+               if(state_ppu != 0 && s[1] == 0){
+                       if(order_ppu.length == 0){
+                               state_ppu = lua_resume(co_ppu, 0);
+                       }else{
+                               program_execute(&order_ppu);
+                       }
+               }
+       }while(state_cpu != 0 || state_ppu != 0);
+       lua_close(l);
+}
diff --git a/client/trunk/anago/squirrel_wrap.c b/client/trunk/anago/squirrel_wrap.c
new file mode 100644 (file)
index 0000000..37aff84
--- /dev/null
@@ -0,0 +1,93 @@
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <squirrel.h>
+#include <sqstdio.h>
+#include <sqstdaux.h>
+
+#ifdef SQUNICODE 
+#define scvprintf vwprintf 
+#else 
+#define scvprintf vprintf 
+#endif 
+static void printfunc(HSQUIRRELVM v, const SQChar *s, ...) 
+{
+       va_list arglist;
+       va_start(arglist, s);
+       scvprintf(s, arglist);
+       va_end(arglist);
+}
+
+HSQUIRRELVM qr_open(void)
+{
+       HSQUIRRELVM v = sq_open(0x400);
+       sqstd_seterrorhandlers(v);
+       sq_setprintfunc(v, printfunc);
+       sq_pushroottable(v);
+       return v;
+}
+
+//SQInteger 
+void qr_function_register_global(HSQUIRRELVM v, const char *name, SQFUNCTION f)
+{
+       sq_pushroottable(v);
+       sq_pushstring(v, name, -1);
+       sq_newclosure(v, f, 0);
+       sq_createslot(v, -3); 
+       sq_pop(v, 1);
+}
+
+void qr_call(HSQUIRRELVM v, const SQChar *functionname, bool settop, int argnum, ...)
+{
+       SQInteger top = sq_gettop(v);
+       sq_pushroottable(v);
+       sq_pushstring(v, _SC(functionname), -1);
+       if(SQ_SUCCEEDED(sq_get(v,-2))){
+               int i;
+               va_list ap;
+               va_start(ap, argnum);
+               sq_pushroottable(v);
+               for(i = 0; i < argnum; i++){
+                       sq_pushinteger(v, va_arg(ap, long));
+               }
+               sq_call(v, 1 + argnum, SQFalse, SQTrue); //calls the function 
+       }
+       if(settop == true){
+               sq_settop(v, top); //restores the original stack size
+       }
+}
+
+void qr_close(HSQUIRRELVM v)
+{
+       sq_pop(v, 1);
+       sq_close(v); 
+}
+
+static bool long_get(HSQUIRRELVM v, SQInteger index, long *d)
+{
+       if(sq_gettype(v, index) != OT_INTEGER){
+               return false;
+       }
+       SQInteger i;
+       if(SQ_FAILED(sq_getinteger(v, index, &i))){
+               return false;
+       }
+       *d = (long) i;
+       return true;
+}
+
+SQRESULT qr_argument_get(HSQUIRRELVM v, SQInteger num, ...)
+{
+       va_list ap;
+       if(sq_gettop(v) != (num + 1)){
+               return sq_throwerror(v, "argument number error");
+       }
+       va_start(ap, num);
+       SQInteger i;
+       for(i = 0; i < num; i++){
+               if(long_get(v, i + 2, va_arg(ap, long *)) == false){
+                       return sq_throwerror(v, "argument type error");
+               }
+       }
+       return 0;
+}
diff --git a/client/trunk/anago/squirrel_wrap.h b/client/trunk/anago/squirrel_wrap.h
new file mode 100644 (file)
index 0000000..db2ea0b
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef _SQUIRREL_WRAP_H_
+#define _SQUIRREL_WRAP_H_
+HSQUIRRELVM qr_open(void);
+void qr_function_register_global(HSQUIRRELVM v, const char *name, SQFUNCTION f);
+void qr_call(HSQUIRRELVM v, const SQChar *functionname, bool settop, int argnum, ...);
+void qr_close(HSQUIRRELVM v);
+SQRESULT qr_argument_get(HSQUIRRELVM v, SQInteger num, ...);
+#endif