quickdev16.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*
  2. quickdev16.c - Quickdev16 support for uCON64
  3. Copyright (c) 2009 david@optixx.org
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. #ifdef HAVE_CONFIG_H
  17. #include "config.h"
  18. #endif
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <time.h>
  22. #include <string.h>
  23. #include <usb.h>
  24. #include "misc/misc.h"
  25. #include "misc/itypes.h"
  26. #ifdef USE_ZLIB
  27. #include "misc/archive.h"
  28. #endif
  29. #include "misc/getopt2.h" // st_getopt2_t
  30. #include "misc/file.h"
  31. #include "misc/opendevice.h"
  32. #include "ucon64.h"
  33. #include "ucon64_misc.h"
  34. #include "ffe.h"
  35. #include "smc.h"
  36. #include "quickdev16.h"
  37. #include "console/snes.h"
  38. #define SNES_HEADER_LEN (sizeof (st_snes_header_t))
  39. const st_getopt2_t quickdev16_usage[] =
  40. {
  41. {
  42. NULL, 0, 0, 0,
  43. NULL, "Quickdev16"/* http://www.optixx.org */,
  44. NULL
  45. },
  46. #ifdef USE_USB
  47. {
  48. "xquickdev16", 0, 0, UCON64_XSNESRAM, // send only
  49. NULL, "send ROM (in FFE format) to Quickdev16",
  50. &ucon64_wf[WF_OBJ_NES_DEFAULT_STOP_NO_SPLIT]
  51. },
  52. #endif
  53. {NULL, 0, 0, 0, NULL, NULL, NULL}
  54. };
  55. #ifdef USE_USB
  56. #define READ_BUFFER_SIZE 8192
  57. #define SEND_BUFFER_SIZE 128
  58. #define SNES_HIROM_SHIFT 16
  59. #define SNES_LOROM_SHIFT 15
  60. int
  61. quickdev16_write_rom (const char *filename)
  62. {
  63. FILE *file;
  64. int bytesread, bytessend, size;
  65. time_t starttime;
  66. usb_dev_handle *handle = NULL;
  67. const unsigned char rawVid[2] = { USB_CFG_VENDOR_ID }, rawPid[2] = { USB_CFG_DEVICE_ID};
  68. char vendor[] = { USB_CFG_VENDOR_NAME, 0 }, product[] = { USB_CFG_DEVICE_NAME, 0};
  69. int cnt, vid, pid;
  70. uint8_t *read_buffer;
  71. uint32_t addr = 0;
  72. uint16_t addr_lo = 0;
  73. uint16_t addr_hi = 0;
  74. uint16_t step = 0;
  75. uint8_t bank = 0;
  76. uint8_t bank_cnt = 0;
  77. uint16_t bank_shift;
  78. uint32_t bank_size;
  79. uint32_t hirom = 0;
  80. uint8_t byte = 0;
  81. st_rominfo_t rominfo;
  82. usb_init();
  83. vid = rawVid[1] * 256 + rawVid[0];
  84. pid = rawPid[1] * 256 + rawPid[0];
  85. if (usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) != 0) {
  86. fprintf(stderr,
  87. "Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n",
  88. product, vid, pid);
  89. exit(1);
  90. }
  91. printf("Open USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid,pid);
  92. if ((file = fopen (filename, "rb")) == NULL)
  93. {
  94. fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
  95. exit (1);
  96. }
  97. if ((read_buffer = (unsigned char *) malloc (READ_BUFFER_SIZE)) == NULL)
  98. {
  99. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], READ_BUFFER_SIZE);
  100. exit (1);
  101. }
  102. snes_init (&rominfo);
  103. printf(rominfo.misc);
  104. printf("\n");
  105. if (UCON64_ISSET (ucon64.snes_hirom))
  106. hirom = ucon64.snes_hirom ? 1 : 0;
  107. else {
  108. hirom = snes_get_snes_hirom ();
  109. }
  110. if (hirom) {
  111. bank_shift = SNES_HIROM_SHIFT;
  112. bank_size = 1 << SNES_HIROM_SHIFT;
  113. } else {
  114. bank_shift = SNES_LOROM_SHIFT;
  115. bank_size = 1 << SNES_LOROM_SHIFT;
  116. }
  117. fseek (file, 0, SEEK_END);
  118. size = ftell (file);
  119. fseek (file, SMC_HEADER_LEN, SEEK_SET);
  120. size -= SMC_HEADER_LEN;
  121. bank_cnt = size / bank_size;
  122. printf ("Send: %d Bytes (%.4f Mb) Hirom: %s, Banks: %i\n", size, (float) size / MBIT, hirom ? "Yes" : "No", bank_cnt);
  123. bytessend = 0;
  124. printf ("Press q to abort\n\n");
  125. starttime = time (NULL);
  126. cnt = usb_control_msg(handle,
  127. USB_TYPE_VENDOR | USB_RECIP_DEVICE |
  128. USB_ENDPOINT_OUT, USB_MODE_AVR, 0, 0, NULL,
  129. 0, 5000);
  130. /* wait for the loader to depack */
  131. usleep(500000);
  132. cnt = usb_control_msg(handle,
  133. USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
  134. USB_BULK_UPLOAD_INIT, bank_shift , bank_cnt, NULL, 0, 5000);
  135. while ((bytesread = fread(read_buffer, READ_BUFFER_SIZE, 1, file)) > 0) {
  136. for (step = 0; step < READ_BUFFER_SIZE; step += SEND_BUFFER_SIZE) {
  137. addr_lo = addr & 0xffff;
  138. addr_hi = (addr >> 16) & 0x00ff;
  139. if (addr == 0){
  140. cnt = usb_control_msg(handle,
  141. USB_TYPE_VENDOR | USB_RECIP_DEVICE |
  142. USB_ENDPOINT_OUT, USB_BULK_UPLOAD_ADDR, addr_hi,
  143. addr_lo, (char *) read_buffer + step,
  144. SEND_BUFFER_SIZE, 5000);
  145. } else {
  146. cnt = usb_control_msg(handle,
  147. USB_TYPE_VENDOR | USB_RECIP_DEVICE |
  148. USB_ENDPOINT_OUT, USB_BULK_UPLOAD_NEXT, addr_hi,
  149. addr_lo, (char *) read_buffer + step,
  150. SEND_BUFFER_SIZE, 5000);
  151. }
  152. if (cnt < 0) {
  153. fprintf(stderr, "USB error: %s\n", usb_strerror());
  154. usb_close(handle);
  155. exit(-1);
  156. }
  157. bytessend += SEND_BUFFER_SIZE;
  158. ucon64_gauge (starttime, bytessend, size);
  159. addr += SEND_BUFFER_SIZE;
  160. if ( addr % bank_size == 0) {
  161. bank++;
  162. }
  163. }
  164. }
  165. cnt = usb_control_msg(handle,
  166. USB_TYPE_VENDOR | USB_RECIP_DEVICE |
  167. USB_ENDPOINT_OUT, USB_BULK_UPLOAD_END, 0, 0, NULL,
  168. 0, 5000);
  169. #if 0
  170. bank = 0;
  171. fseek(fp, 0, SEEK_SET);
  172. while ((cnt = fread(read_buffer, READ_BUFFER_SIZE, 1, fp)) > 0) {
  173. printf ("bank=0x%02x crc=0x%04x\n", bank++,
  174. do_crc(read_buffer, READ_BUFFER_SIZE));
  175. }
  176. fclose(fp);
  177. #endif
  178. cnt = usb_control_msg(handle,
  179. USB_TYPE_VENDOR | USB_RECIP_DEVICE |
  180. USB_ENDPOINT_OUT, USB_MODE_SNES, 0, 0, NULL,
  181. 0, 5000);
  182. free (read_buffer);
  183. fclose (file);
  184. return 0;
  185. }
  186. #endif // USE_USB