OSDN Git Service

final adjustment for 0.6.0
[unagi/old-svn-converted.git] / client / trunk / reader_kazzo.c
1 #include <assert.h>
2 #include <stdlib.h>
3 #include <usb.h>
4 #include <kazzo_request.h>
5 #include <kazzo_task.h>
6 #include "memory_manage.h"
7 #include "reader_master.h"
8 #include "usb_device.h"
9 #include "reader_kazzo.h"
10
11 static usb_dev_handle *device_open(void)
12 {
13         usb_dev_handle *handle = NULL;
14         const unsigned char rawVid[2] = {USB_CFG_VENDOR_ID};
15         const unsigned char rawPid[2] = {USB_CFG_DEVICE_ID};
16         char vendor[] = {USB_CFG_VENDOR_NAME, 0};
17         char product[] = {USB_CFG_DEVICE_NAME, 0};
18         int vid, pid;
19
20         /* compute VID/PID from usbconfig.h so that there is a central source of information */
21         vid = (rawVid[1] << 8) | rawVid[0];
22         pid = (rawPid[1] << 8) | rawPid[0];
23
24         if(usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) == 0){
25                 return handle;
26         }
27         fprintf(stderr, "Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid, pid);
28         return NULL;
29 }
30 static usb_dev_handle *handle = NULL;
31 static int kazzo_open_close(enum reader_control oc)
32 {
33         switch(oc){
34         case READER_OPEN:
35                 handle = device_open();
36                 return handle == NULL ? NG : OK;
37         case READER_CLOSE:
38                 usb_close(handle);
39                 handle = NULL;
40                 return OK;
41         }
42         return NG;
43 }
44 enum{
45         TIMEOUT = 4000
46 };
47 //-------- read sequence --------
48 static void device_read(usb_dev_handle *handle, enum request r, enum index index, long address, long length, uint8_t *data)
49 {
50         int cnt = usb_control_msg(
51                 handle, 
52                 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, 
53                 r, address, 
54                 index, data, length, TIMEOUT
55         );
56         if(cnt != length){
57                 puts(__FUNCTION__);
58                 puts(usb_strerror());
59                 exit(1);
60         }
61 }
62 static void read_main(const enum request r, enum index index, long address, long length, uint8_t *data)
63 {
64         const int packet = READ_PACKET_SIZE;
65         while(length >= packet){
66                 device_read(handle, r, index, address, packet, data);
67                 data += packet;
68                 address += packet;
69                 length -= packet;
70         }
71         if(length != 0){
72                 device_read(handle, r, index, address, length, data);
73         }
74 }
75 static void kazzo_cpu_read(long address, long length, uint8_t *data)
76 {
77         read_main(REQUEST_CPU_READ, INDEX_IMPLIED, address, length, data);
78 //      read_main(REQUEST_CPU_READ_6502, address, length, data);
79 }
80 static void kazzo_ppu_read(long address, long length, uint8_t *data)
81 {
82         read_main(REQUEST_PPU_READ, INDEX_IMPLIED, address, length, data);
83 }
84 //-------- write sequence --------
85 /*
86 When host send data that contains 0xff many times, v-usb losts some 
87 bits. To prevent losting bits, mask data xor 0xa5;
88 */
89 static void device_write(usb_dev_handle *handle, enum request w, enum index index, long address, long length, const uint8_t *data)
90 {
91         uint8_t *d = Malloc(length);
92         int i;
93         memcpy(d, data, length);
94         for(i = 0; i < length; i++){
95                 d[i] ^= 0xa5;
96         }
97         int cnt = usb_control_msg(
98                 handle, 
99                 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
100                 w, address, 
101                 index, d, length, TIMEOUT
102         );
103         if(cnt != length){
104                 puts(__FUNCTION__);
105                 puts(usb_strerror());
106                 exit(1);
107         }
108         Free(d);
109 }
110
111 static void kazzo_init(void)
112 {
113         device_write(handle, REQUEST_PHI2_INIT, INDEX_IMPLIED, 0, 0, NULL);
114 }
115
116 static void write_memory(enum request r, long address, long length, const uint8_t *data)
117 {
118         while(length != 0){
119                 long l = length >= FLASH_PACKET_SIZE ? FLASH_PACKET_SIZE : length;
120                 device_write(handle, r, INDEX_IMPLIED, address, l, data);
121                 address += l;
122                 data += l;
123                 length -= l;
124         }
125 }
126 static void kazzo_cpu_write_6502(long address, long length, const uint8_t *data)
127 {
128         write_memory(REQUEST_CPU_WRITE_6502, address, length, data);
129 }
130 /*static void kazzo_cpu_write_flash(long address, long data)
131 {
132         uint8_t d = (uint8_t) (data & 0xff);
133         device_write(handle, REQUEST_CPU_WRITE_FLASH, address, 1, &d);
134 }*/
135 static void kazzo_ppu_write(long address, long length, const uint8_t *data)
136 {
137         write_memory(REQUEST_PPU_WRITE, address, length, data);
138 }
139
140 static inline void pack_short_le(long l, uint8_t *t)
141 {
142         t[0] = l & 0xff;
143         t[1] = (l >> 8) & 0xff;
144 }
145 static void flash_config(enum request r, enum index index, long c000x, long c2aaa, long c5555, long unit)
146 {
147         const int size = 2 * 4;
148         uint8_t t[size];
149         assert(unit >= 1 && unit < 0x400);
150         pack_short_le(c000x, t);
151         pack_short_le(c2aaa, t + 2);
152         pack_short_le(c5555, t + 4);
153         pack_short_le(unit, t + 6);
154         device_write(handle, r, index, 0, size, t);
155 }
156 static void kazzo_cpu_flash_config(long c000x, long c2aaa, long c5555, long unit)
157 {
158         flash_config(REQUEST_FLASH_CONFIG_SET, INDEX_CPU, c000x, c2aaa, c5555, unit);
159 }
160 static void kazzo_ppu_flash_config(long c000x, long c2aaa, long c5555, long unit)
161 {
162         flash_config(REQUEST_FLASH_CONFIG_SET, INDEX_PPU, c000x, c2aaa, c5555, unit);
163 }
164
165 static inline void flash_execute(enum request p, enum request s, enum index index, long address, const uint8_t *data, int size, bool dowait)
166 {
167         uint8_t status;
168         device_write(handle, p, index, address, size, data);
169         if(dowait == true){
170                 do{
171                         wait(10);
172                         device_read(handle, s, index, 0, 1, &status);
173                 }while(status != KAZZO_TASK_FLASH_IDLE);
174         }
175 }
176 static void kazzo_cpu_flash_erase(long address, bool dowait)
177 {
178         flash_execute(REQUEST_FLASH_ERASE, REQUEST_FLASH_STATUS, INDEX_CPU, address, NULL, 0, dowait);
179 }
180 static void kazzo_ppu_flash_erase(long address, bool dowait)
181 {
182         flash_execute(REQUEST_FLASH_ERASE, REQUEST_FLASH_STATUS, INDEX_PPU, address, NULL, 0, dowait);
183 }
184
185 static void dump(const uint8_t *w, const uint8_t *r, long length)
186 {
187         while(length != 0){
188                 if(memcmp(r, w, 0x10) != 0){
189                         int i;
190                         printf("* ");
191                         for(i = 0; i < 0x10; i+=4){
192                                 printf("%02x %02x %02x %02x-", w[i], w[i+1], w[i+2], w[i+3]);
193                         }
194                         puts("");
195                         printf("  ");
196                         for(i = 0; i < 0x10; i+=4){
197                                 printf("%02x %02x %02x %02x-", r[i], r[i+1], r[i+2], r[i+3]);
198                         }
199                         puts("");
200                 }
201                 w += 0x10;
202                 r += 0x10;
203                 length -= 0x10;
204         }
205 }
206 static long flash_program(enum index index, long address, long length, const uint8_t *data, bool dowait)
207 {
208         enum request p = REQUEST_FLASH_PROGRAM;
209         enum request s = REQUEST_FLASH_STATUS;
210         if(dowait == false){
211                 flash_execute(p, s, index, address, data, FLASH_PACKET_SIZE, dowait);
212                 return FLASH_PACKET_SIZE;
213         }
214         long count = 0;
215         uint8_t *d = Malloc(FLASH_PACKET_SIZE);
216         while(length >= FLASH_PACKET_SIZE){
217                 flash_execute(p, s, index, address, data, FLASH_PACKET_SIZE, dowait);
218                 if(0){
219                         //device_read(handle, REQUEST_FLASH_BUFFER_GET, index, 0, FLASH_PACKET_SIZE, d);
220                         if(memcmp(d, data, FLASH_PACKET_SIZE) != 0){
221                                 puts("packet send error");
222                                 dump(data, d, FLASH_PACKET_SIZE);
223                         }
224                 }
225                 address += FLASH_PACKET_SIZE;
226                 data += FLASH_PACKET_SIZE;
227                 count += FLASH_PACKET_SIZE;
228                 length -= FLASH_PACKET_SIZE;
229         }
230         Free(d);
231         return count;
232 }
233 static long kazzo_cpu_flash_program(long address, long length, const uint8_t *data, bool dowait)
234 {
235         return flash_program(INDEX_CPU, address, length, data, dowait);
236 }
237 static long kazzo_ppu_flash_program(long address, long length, const uint8_t *data, bool dowait)
238 {
239         return flash_program(INDEX_PPU, address, length, data, dowait);
240 }
241
242 static void kazzo_flash_status(uint8_t s[2])
243 {
244         read_main(REQUEST_FLASH_STATUS, INDEX_BOTH, 0, 2, s);
245 }
246 static void kazzo_cpu_flash_device_get(uint8_t s[2])
247 {
248         read_main(REQUEST_FLASH_DEVICE, INDEX_CPU, 0, 2, s);
249 }
250 static void kazzo_ppu_flash_device_get(uint8_t s[2])
251 {
252         read_main(REQUEST_FLASH_DEVICE, INDEX_PPU, 0, 2, s);
253 }
254 static uint8_t kazzo_vram_connection(void)
255 {
256         uint8_t s;
257         read_main(REQUEST_VRAM_CONNECTION, INDEX_IMPLIED, 0, 1, &s);
258         return s;
259 }
260 const struct reader_driver DRIVER_KAZZO = {
261         .name = "kazzo",
262         .open_or_close = kazzo_open_close,
263         .init = kazzo_init,
264         .cpu_read = kazzo_cpu_read, .ppu_read = kazzo_ppu_read,
265         .cpu_write_6502 = kazzo_cpu_write_6502,
266         .flash_support = true,
267         .ppu_write = kazzo_ppu_write,
268         .cpu_flash_config = kazzo_cpu_flash_config,
269         .cpu_flash_erase = kazzo_cpu_flash_erase,
270         .cpu_flash_program = kazzo_cpu_flash_program,
271         .cpu_flash_device_get = kazzo_cpu_flash_device_get,
272         .ppu_flash_config = kazzo_ppu_flash_config,
273         .ppu_flash_erase = kazzo_ppu_flash_erase,
274         .ppu_flash_program = kazzo_ppu_flash_program,
275         .ppu_flash_device_get = kazzo_ppu_flash_device_get,
276         .flash_status = kazzo_flash_status,
277         .vram_connection = kazzo_vram_connection
278 };