OSDN Git Service

supported Linux environment
[unagi/old-svn-converted.git] / client / trunk / reader_kazzo.c
index 0b6dd30..c64894a 100644 (file)
@@ -1,8 +1,10 @@
 #include <assert.h>
+#include <string.h>
 #include <stdlib.h>
 #include <usb.h>
 #include <kazzo_request.h>
 #include <kazzo_task.h>
+#include "memory_manage.h"
 #include "reader_master.h"
 #include "usb_device.h"
 #include "reader_kazzo.h"
@@ -44,65 +46,87 @@ enum{
        TIMEOUT = 4000
 };
 //-------- read sequence --------
-static void device_read(usb_dev_handle *handle, enum request r, long address, long length, uint8_t *data)
+static void device_read(usb_dev_handle *handle, enum request r, enum index index, long address, long length, uint8_t *data)
 {
        int cnt = usb_control_msg(
                handle, 
                USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, 
                r, address, 
-               0, data, length, TIMEOUT
+               index, (char *) data, length, TIMEOUT
        );
        if(cnt != length){
-               usb_strerror();
+               puts(__FUNCTION__);
+               puts(usb_strerror());
                exit(1);
        }
 }
-static void read_main(const enum request r, long address, long length, uint8_t *data)
+static void read_main(const enum request r, enum index index, long address, long length, uint8_t *data)
 {
        const int packet = READ_PACKET_SIZE;
        while(length >= packet){
-               device_read(handle, r, address, packet, data);
+               device_read(handle, r, index, address, packet, data);
                data += packet;
                address += packet;
                length -= packet;
        }
        if(length != 0){
-               device_read(handle, r, address, length, data);
+               device_read(handle, r, index, address, length, data);
        }
 }
 static void kazzo_cpu_read(long address, long length, uint8_t *data)
 {
-       read_main(REQUEST_CPU_READ, address, length, data);
+       read_main(REQUEST_CPU_READ, INDEX_IMPLIED, address, length, data);
 //     read_main(REQUEST_CPU_READ_6502, address, length, data);
 }
 static void kazzo_ppu_read(long address, long length, uint8_t *data)
 {
-       read_main(REQUEST_PPU_READ, address, length, data);
+       read_main(REQUEST_PPU_READ, INDEX_IMPLIED, address, length, data);
 }
 //-------- write sequence --------
-static void device_write(usb_dev_handle *handle, enum request w, long address, long length, const uint8_t *data)
+/*
+When host send data that contains 0xff many times, v-usb losts some 
+bits. To prevent losting bits, mask data xor 0xa5;
+*/
+static void device_write(usb_dev_handle *handle, enum request w, enum index index, long address, long length, const uint8_t *data)
 {
-       //Removing const attribute is not good method....
+       uint8_t *d = Malloc(length);
+       int i;
+       memcpy(d, data, length);
+       for(i = 0; i < length; i++){
+               d[i] ^= 0xa5;
+       }
        int cnt = usb_control_msg(
                handle, 
                USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
                w, address, 
-               0, (uint8_t *) data, length, TIMEOUT
+               index, (char *) d, length, TIMEOUT
        );
        if(cnt != length){
-               usb_strerror();
+               puts(__FUNCTION__);
+               puts(usb_strerror());
                exit(1);
        }
+       Free(d);
 }
 
 static void kazzo_init(void)
 {
-       device_write(handle, REQUEST_PHI2_INIT, 0, 0, NULL);
+       device_write(handle, REQUEST_PHI2_INIT, INDEX_IMPLIED, 0, 0, NULL);
 }
 
+static void write_memory(enum request r, long address, long length, const uint8_t *data)
+{
+       while(length != 0){
+               long l = length >= FLASH_PACKET_SIZE ? FLASH_PACKET_SIZE : length;
+               device_write(handle, r, INDEX_IMPLIED, address, l, data);
+               address += l;
+               data += l;
+               length -= l;
+       }
+}
 static void kazzo_cpu_write_6502(long address, long length, const uint8_t *data)
 {
-       device_write(handle, REQUEST_CPU_WRITE_6502, address, length, data);
+       write_memory(REQUEST_CPU_WRITE_6502, address, length, data);
 }
 /*static void kazzo_cpu_write_flash(long address, long data)
 {
@@ -111,7 +135,7 @@ static void kazzo_cpu_write_6502(long address, long length, const uint8_t *data)
 }*/
 static void kazzo_ppu_write(long address, long length, const uint8_t *data)
 {
-       device_write(handle, REQUEST_PPU_WRITE, address, length, data);
+       write_memory(REQUEST_PPU_WRITE, address, length, data);
 }
 
 static inline void pack_short_le(long l, uint8_t *t)
@@ -119,89 +143,138 @@ static inline void pack_short_le(long l, uint8_t *t)
        t[0] = l & 0xff;
        t[1] = (l >> 8) & 0xff;
 }
-static void flash_config(enum request r, long c000x, long c2aaa, long c5555, long unit)
+static void flash_config(enum request r, enum index index, long c000x, long c2aaa, long c5555, long unit, bool retry)
 {
-       const int size = 2 * 4;
-       uint8_t t[size];
+       const int size = 2 * 4 + 1;
+       uint8_t buf[size];
+       uint8_t *t = buf;
        assert(unit >= 1 && unit < 0x400);
        pack_short_le(c000x, t);
-       pack_short_le(c2aaa, t + 2);
-       pack_short_le(c5555, t + 4);
-       pack_short_le(unit, t + 6);
-       device_write(handle, r, 0, size, t);
+       t += sizeof(uint16_t);
+       pack_short_le(c2aaa, t);
+       t += sizeof(uint16_t);
+       pack_short_le(c5555, t);
+       t += sizeof(uint16_t);
+       pack_short_le(unit, t);
+       t += sizeof(uint16_t);
+       *t = retry == true ? 1 : 0;
+       device_write(handle, r, index, 0, size, buf);
 }
-static void kazzo_cpu_flash_config(long c000x, long c2aaa, long c5555, long unit)
+static void kazzo_cpu_flash_config(long c000x, long c2aaa, long c5555, long unit, bool retry)
 {
-       flash_config(REQUEST_CPU_FLASH_CONFIG_SET, c000x, c2aaa, c5555, unit);
+       flash_config(REQUEST_FLASH_CONFIG_SET, INDEX_CPU, c000x, c2aaa, c5555, unit, retry);
 }
-static void kazzo_ppu_flash_config(long c000x, long c2aaa, long c5555, long unit)
+static void kazzo_ppu_flash_config(long c000x, long c2aaa, long c5555, long unit, bool retry)
 {
-       flash_config(REQUEST_PPU_FLASH_CONFIG_SET, c000x, c2aaa, c5555, unit);
+       flash_config(REQUEST_FLASH_CONFIG_SET, INDEX_PPU, c000x, c2aaa, c5555, unit, retry);
 }
 
-static inline void flash_execute(enum request p, enum request s, long address, const uint8_t *data, int size, bool dowait)
+static inline void flash_execute(enum request p, enum request s, enum index index, long address, const uint8_t *data, int size, bool dowait, bool skip)
 {
        uint8_t status;
-       device_write(handle, p, address, size, data);
+       int filled = 1;
+       if(skip == true){
+               uint8_t *filldata = Malloc(size);
+               memset(filldata, 0xff, size);
+               filled = memcmp(filldata, data, size);
+               if(0){ //nesasm fill 0 to unused area. When this routine is enabled, programming will speed up and compare mode will not work.
+                       memset(filldata, 0, size);
+                       filled &= memcmp(filldata, data, size);
+               }
+               Free(filldata);
+       }
+       if(filled != 0){
+               device_write(handle, p, index, address, size, data);
+       }
        if(dowait == true){
                do{
-                       wait(1);
-                       device_read(handle, s, 0, 1, &status);
+                       wait(10);
+                       device_read(handle, s, index, 0, 1, &status);
                }while(status != KAZZO_TASK_FLASH_IDLE);
        }
 }
 static void kazzo_cpu_flash_erase(long address, bool dowait)
 {
-       flash_execute(REQUEST_CPU_FLASH_ERASE, REQUEST_CPU_FLASH_STATUS, address, NULL, 0, dowait);
+       flash_execute(REQUEST_FLASH_ERASE, REQUEST_FLASH_STATUS, INDEX_CPU, address, NULL, 0, dowait, false);
 }
 static void kazzo_ppu_flash_erase(long address, bool dowait)
 {
-       flash_execute(REQUEST_PPU_FLASH_ERASE, REQUEST_PPU_FLASH_STATUS, address, NULL, 0, dowait);
+       flash_execute(REQUEST_FLASH_ERASE, REQUEST_FLASH_STATUS, INDEX_PPU, address, NULL, 0, dowait, false);
 }
 
-static long flash_program(enum request p, enum request s, long address, long length, const uint8_t *data, bool dowait)
+static void dump(const uint8_t *w, const uint8_t *r, long length)
+{
+       while(length != 0){
+               if(memcmp(r, w, 0x10) != 0){
+                       int i;
+                       printf("* ");
+                       for(i = 0; i < 0x10; i+=4){
+                               printf("%02x %02x %02x %02x-", w[i], w[i+1], w[i+2], w[i+3]);
+                       }
+                       puts("");
+                       printf("  ");
+                       for(i = 0; i < 0x10; i+=4){
+                               printf("%02x %02x %02x %02x-", r[i], r[i+1], r[i+2], r[i+3]);
+                       }
+                       puts("");
+               }
+               w += 0x10;
+               r += 0x10;
+               length -= 0x10;
+       }
+}
+static long flash_program(enum index index, long address, long length, const uint8_t *data, bool dowait, bool skip)
 {
+       enum request p = REQUEST_FLASH_PROGRAM;
+       enum request s = REQUEST_FLASH_STATUS;
        if(dowait == false){
-               flash_execute(p, s, address, data, FLASH_PACKET_SIZE, dowait);
+               flash_execute(p, s, index, address, data, FLASH_PACKET_SIZE, dowait, skip);
                return FLASH_PACKET_SIZE;
        }
        long count = 0;
+       uint8_t *d = Malloc(FLASH_PACKET_SIZE);
        while(length >= FLASH_PACKET_SIZE){
-               flash_execute(p, s, address, data, FLASH_PACKET_SIZE, dowait);
+               flash_execute(p, s, index, address, data, FLASH_PACKET_SIZE, dowait, skip);
+               if(0){
+                       //device_read(handle, REQUEST_FLASH_BUFFER_GET, index, 0, FLASH_PACKET_SIZE, d);
+                       if(memcmp(d, data, FLASH_PACKET_SIZE) != 0){
+                               puts("packet send error");
+                               dump(data, d, FLASH_PACKET_SIZE);
+                       }
+               }
                address += FLASH_PACKET_SIZE;
                data += FLASH_PACKET_SIZE;
                count += FLASH_PACKET_SIZE;
                length -= FLASH_PACKET_SIZE;
        }
+       Free(d);
        return count;
 }
-static long kazzo_cpu_flash_program(long address, long length, const uint8_t *data, bool dowait)
+static long kazzo_cpu_flash_program(long address, long length, const uint8_t *data, bool dowait, bool skip)
 {
-       enum request p = REQUEST_CPU_FLASH_PROGRAM;
-       enum request s = REQUEST_CPU_FLASH_STATUS;
-       return flash_program(p, s, address, length, data, dowait);
+       return flash_program(INDEX_CPU, address, length, data, dowait, skip);
 }
-static long kazzo_ppu_flash_program(long address, long length, const uint8_t *data, bool dowait)
+static long kazzo_ppu_flash_program(long address, long length, const uint8_t *data, bool dowait, bool skip)
 {
-       return flash_program(REQUEST_PPU_FLASH_PROGRAM, REQUEST_PPU_FLASH_STATUS, address, length, data, dowait);
+       return flash_program(INDEX_PPU, address, length, data, dowait, skip);
 }
 
 static void kazzo_flash_status(uint8_t s[2])
 {
-       read_main(REQUEST_BOTH_FLASH_STATUS, 0, 2, s);
+       read_main(REQUEST_FLASH_STATUS, INDEX_BOTH, 0, 2, s);
 }
 static void kazzo_cpu_flash_device_get(uint8_t s[2])
 {
-       read_main(REQUEST_CPU_FLASH_DEVICE, 0, 2, s);
+       read_main(REQUEST_FLASH_DEVICE, INDEX_CPU, 0, 2, s);
 }
 static void kazzo_ppu_flash_device_get(uint8_t s[2])
 {
-       read_main(REQUEST_PPU_FLASH_DEVICE, 0, 2, s);
+       read_main(REQUEST_FLASH_DEVICE, INDEX_PPU, 0, 2, s);
 }
 static uint8_t kazzo_vram_connection(void)
 {
        uint8_t s;
-       read_main(REQUEST_VRAM_CONNECTION, 0, 1, &s);
+       read_main(REQUEST_VRAM_CONNECTION, INDEX_IMPLIED, 0, 1, &s);
        return s;
 }
 const struct reader_driver DRIVER_KAZZO = {