OSDN Git Service

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