5 #include <kazzo_request.h>
6 #include <kazzo_task.h>
7 #include "memory_manage.h"
8 #include "reader_master.h"
9 #include "usb_device.h"
10 #include "reader_kazzo.h"
12 static usb_dev_handle *device_open(void)
14 usb_dev_handle *handle = NULL;
15 const unsigned char rawVid[2] = {USB_CFG_VENDOR_ID};
16 const unsigned char rawPid[2] = {USB_CFG_DEVICE_ID};
17 char vendor[] = {USB_CFG_VENDOR_NAME, 0};
18 char product[] = {USB_CFG_DEVICE_NAME, 0};
21 /* compute VID/PID from usbconfig.h so that there is a central source of information */
22 vid = (rawVid[1] << 8) | rawVid[0];
23 pid = (rawPid[1] << 8) | rawPid[0];
25 if(usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) == 0){
28 fprintf(stderr, "Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid, pid);
31 static usb_dev_handle *handle = NULL;
32 static int kazzo_open_close(enum reader_control oc)
36 handle = device_open();
37 return handle == NULL ? NG : OK;
48 //-------- read sequence --------
49 static void device_read(usb_dev_handle *handle, enum request r, enum index index, long address, long length, uint8_t *data)
51 int cnt = usb_control_msg(
53 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN,
55 index, data, length, TIMEOUT
63 static void read_main(const enum request r, enum index index, long address, long length, uint8_t *data)
65 const int packet = READ_PACKET_SIZE;
66 while(length >= packet){
67 device_read(handle, r, index, address, packet, data);
73 device_read(handle, r, index, address, length, data);
76 static void kazzo_cpu_read(long address, long length, uint8_t *data)
78 read_main(REQUEST_CPU_READ, INDEX_IMPLIED, address, length, data);
79 // read_main(REQUEST_CPU_READ_6502, address, length, data);
81 static void kazzo_ppu_read(long address, long length, uint8_t *data)
83 read_main(REQUEST_PPU_READ, INDEX_IMPLIED, address, length, data);
85 //-------- write sequence --------
87 When host send data that contains 0xff many times, v-usb losts some
88 bits. To prevent losting bits, mask data xor 0xa5;
90 static void device_write(usb_dev_handle *handle, enum request w, enum index index, long address, long length, const uint8_t *data)
92 uint8_t *d = Malloc(length);
94 memcpy(d, data, length);
95 for(i = 0; i < length; i++){
98 int cnt = usb_control_msg(
100 USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
102 index, d, length, TIMEOUT
106 puts(usb_strerror());
112 static void kazzo_init(void)
114 device_write(handle, REQUEST_PHI2_INIT, INDEX_IMPLIED, 0, 0, NULL);
117 static void write_memory(enum request r, long address, long length, const uint8_t *data)
120 long l = length >= FLASH_PACKET_SIZE ? FLASH_PACKET_SIZE : length;
121 device_write(handle, r, INDEX_IMPLIED, address, l, data);
127 static void kazzo_cpu_write_6502(long address, long length, const uint8_t *data)
129 write_memory(REQUEST_CPU_WRITE_6502, address, length, data);
131 /*static void kazzo_cpu_write_flash(long address, long data)
133 uint8_t d = (uint8_t) (data & 0xff);
134 device_write(handle, REQUEST_CPU_WRITE_FLASH, address, 1, &d);
136 static void kazzo_ppu_write(long address, long length, const uint8_t *data)
138 write_memory(REQUEST_PPU_WRITE, address, length, data);
141 static inline void pack_short_le(long l, uint8_t *t)
144 t[1] = (l >> 8) & 0xff;
146 static void flash_config(enum request r, enum index index, long c000x, long c2aaa, long c5555, long unit, bool retry)
148 const int size = 2 * 4 + 1;
149 uint8_t buf[10]; //[size];
151 assert(unit >= 1 && unit < 0x400);
152 pack_short_le(c000x, t);
154 pack_short_le(c2aaa, t);
156 pack_short_le(c5555, t);
158 pack_short_le(unit, t);
160 *t = retry == true ? 1 : 0;
161 device_write(handle, r, index, 0, size, buf);
163 static void kazzo_cpu_flash_config(long c000x, long c2aaa, long c5555, long unit, bool retry)
165 flash_config(REQUEST_FLASH_CONFIG_SET, INDEX_CPU, c000x, c2aaa, c5555, unit, retry);
167 static void kazzo_ppu_flash_config(long c000x, long c2aaa, long c5555, long unit, bool retry)
169 flash_config(REQUEST_FLASH_CONFIG_SET, INDEX_PPU, c000x, c2aaa, c5555, unit, retry);
172 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)
177 uint8_t *filldata = Malloc(size);
178 memset(filldata, 0xff, size);
179 filled = memcmp(filldata, data, size);
180 if(0){ //nesasm fill 0 to unused area. When this routine is enabled, programming will speed up and compare mode will not work.
181 memset(filldata, 0, size);
182 filled &= memcmp(filldata, data, size);
187 device_write(handle, p, index, address, size, data);
192 device_read(handle, s, index, 0, 1, &status);
193 }while(status != KAZZO_TASK_FLASH_IDLE);
196 static void kazzo_cpu_flash_erase(long address, bool dowait)
198 flash_execute(REQUEST_FLASH_ERASE, REQUEST_FLASH_STATUS, INDEX_CPU, address, NULL, 0, dowait, false);
200 static void kazzo_ppu_flash_erase(long address, bool dowait)
202 flash_execute(REQUEST_FLASH_ERASE, REQUEST_FLASH_STATUS, INDEX_PPU, address, NULL, 0, dowait, false);
205 static void dump(const uint8_t *w, const uint8_t *r, long length)
208 if(memcmp(r, w, 0x10) != 0){
211 for(i = 0; i < 0x10; i+=4){
212 printf("%02x %02x %02x %02x-", w[i], w[i+1], w[i+2], w[i+3]);
216 for(i = 0; i < 0x10; i+=4){
217 printf("%02x %02x %02x %02x-", r[i], r[i+1], r[i+2], r[i+3]);
226 static long flash_program(enum index index, long address, long length, const uint8_t *data, bool dowait, bool skip)
228 enum request p = REQUEST_FLASH_PROGRAM;
229 enum request s = REQUEST_FLASH_STATUS;
231 flash_execute(p, s, index, address, data, FLASH_PACKET_SIZE, dowait, skip);
232 return FLASH_PACKET_SIZE;
235 uint8_t *d = Malloc(FLASH_PACKET_SIZE);
236 while(length >= FLASH_PACKET_SIZE){
237 flash_execute(p, s, index, address, data, FLASH_PACKET_SIZE, dowait, skip);
239 //device_read(handle, REQUEST_FLASH_BUFFER_GET, index, 0, FLASH_PACKET_SIZE, d);
240 if(memcmp(d, data, FLASH_PACKET_SIZE) != 0){
241 puts("packet send error");
242 dump(data, d, FLASH_PACKET_SIZE);
245 address += FLASH_PACKET_SIZE;
246 data += FLASH_PACKET_SIZE;
247 count += FLASH_PACKET_SIZE;
248 length -= FLASH_PACKET_SIZE;
253 static long kazzo_cpu_flash_program(long address, long length, const uint8_t *data, bool dowait, bool skip)
255 return flash_program(INDEX_CPU, address, length, data, dowait, skip);
257 static long kazzo_ppu_flash_program(long address, long length, const uint8_t *data, bool dowait, bool skip)
259 return flash_program(INDEX_PPU, address, length, data, dowait, skip);
262 static void kazzo_flash_status(uint8_t s[2])
264 read_main(REQUEST_FLASH_STATUS, INDEX_BOTH, 0, 2, s);
266 static void kazzo_cpu_flash_device_get(uint8_t s[2])
268 read_main(REQUEST_FLASH_DEVICE, INDEX_CPU, 0, 2, s);
270 static void kazzo_ppu_flash_device_get(uint8_t s[2])
272 read_main(REQUEST_FLASH_DEVICE, INDEX_PPU, 0, 2, s);
274 static uint8_t kazzo_vram_connection(void)
277 read_main(REQUEST_VRAM_CONNECTION, INDEX_IMPLIED, 0, 1, &s);
280 const struct reader_driver DRIVER_KAZZO = {
282 .open_or_close = kazzo_open_close,
284 .cpu_read = kazzo_cpu_read, .ppu_read = kazzo_ppu_read,
285 .cpu_write_6502 = kazzo_cpu_write_6502,
286 .flash_support = true,
287 .ppu_write = kazzo_ppu_write,
288 .cpu_flash_config = kazzo_cpu_flash_config,
289 .cpu_flash_erase = kazzo_cpu_flash_erase,
290 .cpu_flash_program = kazzo_cpu_flash_program,
291 .cpu_flash_device_get = kazzo_cpu_flash_device_get,
292 .ppu_flash_config = kazzo_ppu_flash_config,
293 .ppu_flash_erase = kazzo_ppu_flash_erase,
294 .ppu_flash_program = kazzo_ppu_flash_program,
295 .ppu_flash_device_get = kazzo_ppu_flash_device_get,
296 .flash_status = kazzo_flash_status,
297 .vram_connection = kazzo_vram_connection