OSDN Git Service

read buffer and programming buffer are separated
[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 "reader_master.h"
6 #include "usb_device.h"
7 #include "reader_kazzo.h"
8
9 static usb_dev_handle *device_open(void)
10 {
11         usb_dev_handle *handle = NULL;
12         const unsigned char rawVid[2] = {USB_CFG_VENDOR_ID};
13         const unsigned char rawPid[2] = {USB_CFG_DEVICE_ID};
14         char vendor[] = {USB_CFG_VENDOR_NAME, 0};
15         char product[] = {USB_CFG_DEVICE_NAME, 0};
16         int vid, pid;
17
18         /* compute VID/PID from usbconfig.h so that there is a central source of information */
19         vid = (rawVid[1] << 8) | rawVid[0];
20         pid = (rawPid[1] << 8) | rawPid[0];
21
22         if(usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) == 0){
23                 return handle;
24         }
25         fprintf(stderr, "Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid, pid);
26         return NULL;
27 }
28 static usb_dev_handle *handle = NULL;
29 static int kazzo_open_close(enum reader_control oc)
30 {
31         switch(oc){
32         case READER_OPEN:
33                 handle = device_open();
34                 return handle == NULL ? NG : OK;
35         case READER_CLOSE:
36                 usb_close(handle);
37                 handle = NULL;
38                 return OK;
39         }
40         return NG;
41 }
42 enum{
43         TIMEOUT = 4000
44 };
45 //-------- read sequence --------
46 static void device_read(usb_dev_handle *handle, enum request r, long address, long length, uint8_t *data)
47 {
48         int cnt = usb_control_msg(
49                 handle, 
50                 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, 
51                 r, address, 
52                 0, data, length, TIMEOUT
53         );
54         if(cnt != length){
55                 usb_strerror();
56                 exit(1);
57         }
58 }
59 static void read_main(const enum request r, long address, long length, uint8_t *data)
60 {
61         const int packet = READ_PACKET_SIZE;
62         while(length >= packet){
63                 device_read(handle, r, address, packet, data);
64                 data += packet;
65                 address += packet;
66                 length -= packet;
67         }
68         if(length != 0){
69                 device_read(handle, r, address, length, data);
70         }
71 }
72 static void kazzo_cpu_read(long address, long length, uint8_t *data)
73 {
74         read_main(REQUEST_CPU_READ, address, length, data);
75 //      read_main(REQUEST_CPU_READ_6502, address, length, data);
76 }
77 static void kazzo_ppu_read(long address, long length, uint8_t *data)
78 {
79         read_main(REQUEST_PPU_READ, address, length, data);
80 }
81 //-------- write sequence --------
82 static void device_write(usb_dev_handle *handle, enum request w, long address, long length, const uint8_t *data)
83 {
84         //Removing const attribute is not good method....
85         int cnt = usb_control_msg(
86                 handle, 
87                 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
88                 w, address, 
89                 0, (uint8_t *) data, length, TIMEOUT
90         );
91         if(cnt != length){
92                 usb_strerror();
93                 exit(1);
94         }
95 }
96
97 static void kazzo_init(void)
98 {
99         device_write(handle, REQUEST_PHI2_INIT, 0, 0, NULL);
100 }
101
102 static void kazzo_cpu_write_6502(long address, long length, const uint8_t *data)
103 {
104         device_write(handle, REQUEST_CPU_WRITE_6502, address, length, data);
105 }
106 /*static void kazzo_cpu_write_flash(long address, long data)
107 {
108         uint8_t d = (uint8_t) (data & 0xff);
109         device_write(handle, REQUEST_CPU_WRITE_FLASH, address, 1, &d);
110 }*/
111 static void kazzo_ppu_write(long address, long length, const uint8_t *data)
112 {
113         device_write(handle, REQUEST_PPU_WRITE, address, length, data);
114 }
115
116 static inline void pack_short_le(long l, uint8_t *t)
117 {
118         t[0] = l & 0xff;
119         t[1] = (l >> 8) & 0xff;
120 }
121 static void flash_config(enum request r, long c000x, long c2aaa, long c5555, long unit)
122 {
123         const int size = 2 * 4;
124         uint8_t t[size];
125         assert(unit >= 1 && unit < 0x400);
126         pack_short_le(c000x, t);
127         pack_short_le(c2aaa, t + 2);
128         pack_short_le(c5555, t + 4);
129         pack_short_le(unit, t + 6);
130         device_write(handle, r, 0, size, t);
131 }
132 static void kazzo_cpu_flash_config(long c000x, long c2aaa, long c5555, long unit)
133 {
134         flash_config(REQUEST_CPU_FLASH_CONFIG_SET, c000x, c2aaa, c5555, unit);
135 }
136 static void kazzo_ppu_flash_config(long c000x, long c2aaa, long c5555, long unit)
137 {
138         flash_config(REQUEST_PPU_FLASH_CONFIG_SET, c000x, c2aaa, c5555, unit);
139 }
140
141 static inline void flash_execute(enum request p, enum request s, long address, const uint8_t *data, int size, bool dowait)
142 {
143         uint8_t status;
144         device_write(handle, p, address, size, data);
145         if(dowait == true){
146                 do{
147                         wait(1);
148                         device_read(handle, s, 0, 1, &status);
149                 }while(status != 0);
150         }
151 }
152 static void kazzo_cpu_flash_erase(long address, bool dowait)
153 {
154         flash_execute(REQUEST_CPU_FLASH_ERASE, REQUEST_CPU_FLASH_STATUS, address, NULL, 0, dowait);
155 }
156 static void kazzo_ppu_flash_erase(long address, bool dowait)
157 {
158         flash_execute(REQUEST_PPU_FLASH_ERASE, REQUEST_PPU_FLASH_STATUS, address, NULL, 0, dowait);
159 }
160
161 static long flash_program(enum request p, enum request s, long address, long length, const uint8_t *data, bool dowait)
162 {
163         if(dowait == false){
164                 flash_execute(p, s, address, data, FLASH_PACKET_SIZE, dowait);
165                 return FLASH_PACKET_SIZE;
166         }
167         long count = 0;
168         while(length >= FLASH_PACKET_SIZE){
169                 flash_execute(p, s, address, data, FLASH_PACKET_SIZE, dowait);
170                 address += FLASH_PACKET_SIZE;
171                 data += FLASH_PACKET_SIZE;
172                 count += FLASH_PACKET_SIZE;
173                 length -= FLASH_PACKET_SIZE;
174         }
175         return count;
176 }
177 static long kazzo_cpu_flash_program(long address, long length, const uint8_t *data, bool dowait)
178 {
179         enum request p = REQUEST_CPU_FLASH_PROGRAM;
180         enum request s = REQUEST_CPU_FLASH_STATUS;
181         return flash_program(p, s, address, length, data, dowait);
182 }
183 static long kazzo_ppu_flash_program(long address, long length, const uint8_t *data, bool dowait)
184 {
185         return flash_program(REQUEST_PPU_FLASH_PROGRAM, REQUEST_PPU_FLASH_STATUS, address, length, data, dowait);
186 }
187
188 static void kazzo_flash_status(uint8_t s[2])
189 {
190         read_main(REQUEST_BOTH_FLASH_STATUS, 0, 2, s);
191 }
192 static void kazzo_cpu_flash_device_get(uint8_t s[2])
193 {
194         read_main(REQUEST_CPU_FLASH_DEVICE, 0, 2, s);
195 }
196 static void kazzo_ppu_flash_device_get(uint8_t s[2])
197 {
198         read_main(REQUEST_PPU_FLASH_DEVICE, 0, 2, s);
199 }
200 static uint8_t kazzo_vram_connection(void)
201 {
202         uint8_t s;
203         read_main(REQUEST_VRAM_CONNECTION, 0, 1, &s);
204         return s;
205 }
206 const struct reader_driver DRIVER_KAZZO = {
207         .name = "kazzo",
208         .open_or_close = kazzo_open_close,
209         .init = kazzo_init,
210         .cpu_read = kazzo_cpu_read, .ppu_read = kazzo_ppu_read,
211         .cpu_write_6502 = kazzo_cpu_write_6502,
212         .flash_support = true,
213         .ppu_write = kazzo_ppu_write,
214         .cpu_flash_config = kazzo_cpu_flash_config,
215         .cpu_flash_erase = kazzo_cpu_flash_erase,
216         .cpu_flash_program = kazzo_cpu_flash_program,
217         .cpu_flash_device_get = kazzo_cpu_flash_device_get,
218         .ppu_flash_config = kazzo_ppu_flash_config,
219         .ppu_flash_erase = kazzo_ppu_flash_erase,
220         .ppu_flash_program = kazzo_ppu_flash_program,
221         .ppu_flash_device_get = kazzo_ppu_flash_device_get,
222         .flash_status = kazzo_flash_status,
223         .vram_connection = kazzo_vram_connection
224 };