gd.c 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144
  1. /*
  2. gd.c - Game Doctor support for uCON64
  3. Copyright (c) 2002 - 2003 John Weidman
  4. Copyright (c) 2002 - 2004 dbjh
  5. This program is free software; you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation; either version 2 of the License, or
  8. (at your option) any later version.
  9. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. #ifdef HAVE_CONFIG_H
  18. #include "config.h"
  19. #endif
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <ctype.h>
  24. #include <time.h>
  25. #include "misc/string.h"
  26. #include "misc/misc.h"
  27. #include "misc/file.h"
  28. #ifdef USE_ZLIB
  29. #include "misc/archive.h"
  30. #endif
  31. #include "misc/getopt2.h" // st_getopt2_t
  32. #include "ucon64.h"
  33. #include "ucon64_misc.h"
  34. #include "gd.h"
  35. #include "console/snes.h" // for snes_make_gd_names() &
  36. #include "misc/parallel.h" // snes_get_snes_hirom()
  37. const st_getopt2_t gd_usage[] =
  38. {
  39. {
  40. NULL, 0, 0, 0,
  41. NULL, "Game Doctor SF3(SF6/SF7)/Professor SF(SF II)"/*"19XX Bung Enterprises Ltd http://www.bung.com.hk"*/,
  42. NULL
  43. },
  44. #ifdef USE_PARALLEL
  45. {
  46. "xgd3", 0, 0, UCON64_XGD3, // supports split files
  47. NULL, "send ROM to Game Doctor SF3/SF6/SF7; " OPTION_LONG_S "port=PORT\n"
  48. "this option uses the Game Doctor SF3 protocol",
  49. &ucon64_wf[WF_OBJ_SNES_DEFAULT_STOP_NO_ROM]
  50. },
  51. {
  52. "xgd6", 0, 0, UCON64_XGD6,
  53. #if 1 // dumping is not yet supported
  54. NULL, "send ROM to Game Doctor SF6/SF7; " OPTION_LONG_S "port=PORT\n" // supports split files
  55. #else
  56. NULL, "send/receive ROM to/from Game Doctor SF6/SF7; " OPTION_LONG_S "port=PORT\n"
  57. "receives automatically when ROM does not exist\n"
  58. #endif
  59. "this option uses the Game Doctor SF6 protocol",
  60. &ucon64_wf[WF_OBJ_SNES_DEFAULT_STOP_NO_ROM]
  61. },
  62. {
  63. "xgd3s", 0, 0, UCON64_XGD3S,
  64. NULL, "send SRAM to Game Doctor SF3/SF6/SF7; " OPTION_LONG_S "port=PORT",
  65. &ucon64_wf[WF_OBJ_SNES_STOP_NO_ROM]
  66. },
  67. // --xgd3r should remain hidden until receiving works
  68. {
  69. "xgd3r", 0, 0, UCON64_XGD3R,
  70. NULL, NULL,
  71. &ucon64_wf[WF_OBJ_SNES_STOP_NO_ROM]
  72. },
  73. {
  74. "xgd6s", 0, 0, UCON64_XGD6S,
  75. NULL, "send/receive SRAM to/from Game Doctor SF6/SF7; " OPTION_LONG_S "port=PORT\n"
  76. "receives automatically when SRAM does not exist",
  77. &ucon64_wf[WF_OBJ_SNES_STOP_NO_ROM]
  78. },
  79. {
  80. "xgd6r", 0, 0, UCON64_XGD6R,
  81. NULL, "send/receive saver (RTS) data to/from Game Doctor SF6/SF7;\n" OPTION_LONG_S "port=PORT\n"
  82. "receives automatically when saver file does not exist",
  83. &ucon64_wf[WF_OBJ_SNES_STOP_NO_ROM]
  84. },
  85. #endif // USE_PARALLEL
  86. {NULL, 0, 0, 0, NULL, NULL, NULL}
  87. };
  88. #ifdef USE_PARALLEL
  89. #define BUFFERSIZE 8192
  90. #define GD_OK 0
  91. #define GD_ERROR 1
  92. #define GD3_PROLOG_STRING "DSF3"
  93. #define GD6_READ_PROLOG_STRING "GD6R" // GD reading, PC writing
  94. #define GD6_WRITE_PROLOG_STRING "GD6W" // GD writing, PC reading
  95. #define GD6_TIMEOUT_ATTEMPTS 0x4000
  96. #define GD6_RX_SYNC_TIMEOUT_ATTEMPTS 0x2000
  97. #define GD6_SYNC_RETRIES 16
  98. #ifdef _MSC_VER
  99. // Visual C++ doesn't allow inline in C source code
  100. #define inline __inline
  101. #endif
  102. static void init_io (unsigned int port);
  103. static void deinit_io (void);
  104. static void io_error (void);
  105. static void gd_checkabort (int status);
  106. static void remove_destfile (void);
  107. static int gd3_send_prolog_byte (unsigned char data);
  108. static int gd3_send_prolog_bytes (unsigned char *data, int len);
  109. static void gd3_send_byte (unsigned char data);
  110. static int gd3_send_bytes (unsigned char *data, int len);
  111. static int gd6_sync_hardware (void);
  112. static int gd6_sync_receive_start (void);
  113. static inline int gd6_send_byte_helper (unsigned char data, unsigned int timeout);
  114. static int gd6_send_prolog_byte (unsigned char data);
  115. static int gd6_send_prolog_bytes (unsigned char *data, int len);
  116. static int gd6_send_bytes (unsigned char *data, int len);
  117. static int gd6_receive_bytes (unsigned char *buffer, int len);
  118. static int gd_send_unit_prolog (int header, unsigned size);
  119. static int gd_write_rom (const char *filename, unsigned int parport,
  120. st_rominfo_t *rominfo, const char *prolog_str);
  121. static int gd_write_sram (const char *filename, unsigned int parport,
  122. const char *prolog_str);
  123. static int gd_write_saver (const char *filename, unsigned int parport,
  124. const char *prolog_str);
  125. typedef struct st_gd3_memory_unit
  126. {
  127. char name[12]; // Exact size is 11 chars but I'll
  128. // unsigned char *data; // add one extra for string terminator
  129. unsigned int size; // Usually either 0x100000 or 0x80000
  130. } st_gd3_memory_unit_t;
  131. static int (*gd_send_prolog_byte) (unsigned char data);
  132. static int (*gd_send_prolog_bytes) (unsigned char *data, int len);
  133. static int (*gd_send_bytes) (unsigned char *data, int len);
  134. static st_gd3_memory_unit_t gd3_dram_unit[GD3_MAX_UNITS];
  135. static int gd_port, gd_bytessend, gd_fsize, gd_name_i = 0;
  136. static time_t gd_starttime;
  137. static char **gd_names;
  138. static unsigned char gd6_send_toggle;
  139. static const char *gd_destfname = NULL;
  140. static FILE *gd_destfile;
  141. void
  142. init_io (unsigned int port)
  143. /*
  144. - sets global `gd_port'. Then the send/receive functions don't need to pass
  145. `port' to all the I/O functions.
  146. - calls init_conio(). Necessary for kbhit() and DOS-like behaviour of getch().
  147. */
  148. {
  149. gd_port = port;
  150. #if 0 // we want to support non-standard parallel port addresses
  151. if (gd_port != 0x3bc && gd_port != 0x378 && gd_port != 0x278)
  152. {
  153. fputs ("ERROR: PORT must be 0x3bc, 0x378 or 0x278\n", stderr);
  154. exit (1);
  155. }
  156. #endif
  157. #if (defined __unix__ || defined __BEOS__) && !defined __MSDOS__
  158. init_conio ();
  159. #endif
  160. parport_print_info ();
  161. }
  162. void
  163. deinit_io (void)
  164. {
  165. // Put possible transfer cleanup stuff here
  166. #if (defined __unix__ || defined __BEOS__) && !defined __MSDOS__
  167. deinit_conio ();
  168. #endif
  169. }
  170. void
  171. io_error (void)
  172. // This function could be changed to take a string argument that describes the
  173. // error. Or take an integer code that we can interpret here.
  174. {
  175. fflush (stdout);
  176. fputs ("ERROR: Communication with Game Doctor failed\n", stderr);
  177. fflush (stderr);
  178. // calling fflush() seems to be necessary under Msys in order to make the
  179. // error message be displayed before the "Removing: <filename>" message
  180. exit (1);
  181. }
  182. void
  183. gd_checkabort (int status)
  184. {
  185. if (((!ucon64.frontend) ? kbhit () : 0) && getch () == 'q')
  186. {
  187. puts ("\nProgram aborted");
  188. exit (status);
  189. }
  190. }
  191. static void
  192. remove_destfile (void)
  193. {
  194. if (gd_destfname)
  195. {
  196. printf ("Removing: %s\n", gd_destfname);
  197. fclose (gd_destfile);
  198. remove (gd_destfname);
  199. gd_destfname = NULL;
  200. }
  201. }
  202. int
  203. gd3_send_prolog_byte (unsigned char data)
  204. /*
  205. Prolog specific data output routine
  206. We could probably get away with using the general routine but the
  207. transfer program I (JW) traced to analyze the protocol did this for
  208. the bytes used to set up the transfer so here it is.
  209. */
  210. {
  211. // Wait until SF3 is not busy
  212. do
  213. {
  214. if ((inportb ((unsigned short) (gd_port + PARPORT_STATUS)) & 0x08) == 0)
  215. return GD_ERROR;
  216. }
  217. while ((inportb ((unsigned short) (gd_port + PARPORT_STATUS)) & 0x80) == 0);
  218. outportb ((unsigned short) gd_port, data); // set data
  219. outportb ((unsigned short) (gd_port + PARPORT_CONTROL), 5); // Clock data out to SF3
  220. outportb ((unsigned short) (gd_port + PARPORT_CONTROL), 4);
  221. return GD_OK;
  222. }
  223. int
  224. gd3_send_prolog_bytes (unsigned char *data, int len)
  225. {
  226. int i;
  227. for (i = 0; i < len; i++)
  228. if (gd3_send_prolog_byte (data[i]) == GD_ERROR)
  229. return GD_ERROR;
  230. return GD_OK;
  231. }
  232. int
  233. gd_send_unit_prolog (int header, unsigned size)
  234. {
  235. if (gd_send_prolog_byte (0x00) == GD_ERROR)
  236. return GD_ERROR;
  237. if (gd_send_prolog_byte ((unsigned char) ((header != 0) ? 0x02 : 0x00)) == GD_ERROR)
  238. return GD_ERROR;
  239. if (gd_send_prolog_byte ((unsigned char) (size >> 16)) == GD_ERROR) // 0x10 = 8 Mbit
  240. return GD_ERROR;
  241. if (gd_send_prolog_byte (0x00) == GD_ERROR)
  242. return GD_ERROR;
  243. return GD_OK;
  244. }
  245. void
  246. gd3_send_byte (unsigned char data)
  247. /*
  248. General data output routine
  249. Use this routine for sending ROM data bytes to the Game Doctor SF3 (SF6/SF7
  250. too).
  251. */
  252. {
  253. // Wait until SF3 is not busy
  254. while ((inportb ((unsigned short) (gd_port + PARPORT_STATUS)) & 0x80) == 0)
  255. ;
  256. outportb ((unsigned short) gd_port, data); // set data
  257. outportb ((unsigned short) (gd_port + PARPORT_CONTROL), 5); // Clock data out to SF3
  258. outportb ((unsigned short) (gd_port + PARPORT_CONTROL), 4);
  259. }
  260. int
  261. gd3_send_bytes (unsigned char *data, int len)
  262. {
  263. int i;
  264. for (i = 0; i < len; i++)
  265. {
  266. gd3_send_byte (data[i]);
  267. gd_bytessend++;
  268. if ((gd_bytessend - GD_HEADER_LEN) % 8192 == 0)
  269. {
  270. ucon64_gauge (gd_starttime, gd_bytessend, gd_fsize);
  271. gd_checkabort (2); // 2 to return something other than 1
  272. }
  273. }
  274. return GD_OK;
  275. }
  276. int
  277. gd6_sync_hardware (void)
  278. // Sets the SF7 up for an SF6/SF7 protocol transfer
  279. {
  280. int timeout, retries;
  281. volatile int delay;
  282. for (retries = GD6_SYNC_RETRIES; retries > 0; retries--)
  283. {
  284. timeout = GD6_TIMEOUT_ATTEMPTS;
  285. outportb ((unsigned short) (gd_port + PARPORT_CONTROL), 4);
  286. outportb ((unsigned short) gd_port, 0);
  287. outportb ((unsigned short) (gd_port + PARPORT_CONTROL), 4);
  288. for (delay = 0x1000; delay > 0; delay--) // A delay may not be necessary here
  289. ;
  290. outportb ((unsigned short) gd_port, 0xaa);
  291. outportb ((unsigned short) (gd_port + PARPORT_CONTROL), 0);
  292. while ((inportb ((unsigned short) (gd_port + PARPORT_CONTROL)) & 0x08) == 0)
  293. if (--timeout == 0)
  294. break;
  295. if (timeout == 0)
  296. continue;
  297. outportb ((unsigned short) (gd_port + PARPORT_CONTROL), 4);
  298. while ((inportb ((unsigned short) (gd_port + PARPORT_CONTROL)) & 0x08) != 0)
  299. if (--timeout == 0)
  300. break;
  301. if (timeout == 0)
  302. continue;
  303. outportb ((unsigned short) gd_port, 0x55);
  304. outportb ((unsigned short) (gd_port + PARPORT_CONTROL), 0);
  305. while ((inportb ((unsigned short) (gd_port + PARPORT_CONTROL)) & 0x08) == 0)
  306. if (--timeout == 0)
  307. break;
  308. if (timeout == 0)
  309. continue;
  310. outportb ((unsigned short) (gd_port + PARPORT_CONTROL), 4);
  311. while ((inportb ((unsigned short) (gd_port + PARPORT_CONTROL)) & 0x08) != 0)
  312. if (--timeout == 0)
  313. break;
  314. if (timeout == 0)
  315. continue;
  316. return GD_OK;
  317. }
  318. return GD_ERROR;
  319. }
  320. int
  321. gd6_sync_receive_start (void)
  322. // Sync with the start of the received data
  323. {
  324. int timeout = GD6_RX_SYNC_TIMEOUT_ATTEMPTS;
  325. while (1)
  326. {
  327. if (((inportb ((unsigned short) (gd_port + PARPORT_CONTROL)) & 0x03) == 0x03) ||
  328. ((inportb ((unsigned short) (gd_port + PARPORT_CONTROL)) & 0x03) == 0))
  329. break;
  330. if (--timeout == 0)
  331. return GD_ERROR;
  332. }
  333. outportb ((unsigned short) gd_port, 0);
  334. timeout = GD6_RX_SYNC_TIMEOUT_ATTEMPTS;
  335. while ((inportb ((unsigned short) (gd_port + PARPORT_STATUS)) & 0x80) != 0)
  336. if (--timeout == 0)
  337. return GD_ERROR;
  338. return GD_OK;
  339. }
  340. inline int
  341. gd6_send_byte_helper (unsigned char data, unsigned int timeout)
  342. {
  343. while ((inportb ((unsigned short) (gd_port + PARPORT_CONTROL)) & 0x02) != gd6_send_toggle)
  344. if (--timeout == 0)
  345. return GD_ERROR;
  346. gd6_send_toggle = ~gd6_send_toggle & 0x02;
  347. outportb ((unsigned short) gd_port, data);
  348. outportb ((unsigned short) (gd_port + PARPORT_CONTROL), (unsigned char) (4 | (gd6_send_toggle >> 1)));
  349. return GD_OK;
  350. }
  351. int
  352. gd6_send_prolog_byte (unsigned char data)
  353. {
  354. unsigned int timeout = 0x100000;
  355. gd6_send_toggle = (inportb ((unsigned short) (gd_port + PARPORT_CONTROL)) & 0x01) << 1;
  356. return gd6_send_byte_helper (data, timeout);
  357. }
  358. int
  359. gd6_send_prolog_bytes (unsigned char *data, int len)
  360. {
  361. int i;
  362. unsigned int timeout = 0x1e00000;
  363. gd6_send_toggle = (inportb ((unsigned short) (gd_port + PARPORT_CONTROL)) & 0x01) << 1;
  364. for (i = 0; i < len; i++)
  365. if (gd6_send_byte_helper (data[i], timeout) != GD_OK)
  366. return GD_ERROR;
  367. return GD_OK;
  368. }
  369. int
  370. gd6_send_bytes (unsigned char *data, int len)
  371. {
  372. int i;
  373. unsigned int timeout = 0x1e0000;
  374. gd6_send_toggle = (inportb ((unsigned short) (gd_port + PARPORT_CONTROL)) & 0x01) << 1;
  375. for (i = 0; i < len; i++)
  376. {
  377. if (gd6_send_byte_helper (data[i], timeout) != GD_OK)
  378. return GD_ERROR;
  379. gd_bytessend++;
  380. if ((gd_bytessend - GD_HEADER_LEN) % 8192 == 0)
  381. {
  382. ucon64_gauge (gd_starttime, gd_bytessend, gd_fsize);
  383. gd_checkabort (2); // 2 to return something other than 1
  384. }
  385. }
  386. return GD_OK;
  387. }
  388. int
  389. gd6_receive_bytes (unsigned char *buffer, int len)
  390. {
  391. int i;
  392. unsigned char nibble1, nibble2;
  393. unsigned int timeout = 0x1e0000;
  394. outportb ((unsigned short) gd_port, 0x80); // Signal the SF6/SF7 to send the next nibble
  395. for (i = 0; i < len; i++)
  396. {
  397. while ((inportb ((unsigned short) (gd_port + PARPORT_STATUS)) & 0x80) == 0)
  398. if (--timeout == 0)
  399. return GD_ERROR;
  400. nibble1 = (inportb ((unsigned short) (gd_port + PARPORT_STATUS)) >> 3) & 0x0f;
  401. outportb ((unsigned short) gd_port, 0x00); // Signal the SF6/SF7 to send the next nibble
  402. while ((inportb ((unsigned short) (gd_port + PARPORT_STATUS)) & 0x80) != 0)
  403. if (--timeout == 0)
  404. return GD_ERROR;
  405. nibble2 = (inportb ((unsigned short) (gd_port + PARPORT_STATUS)) << 1) & 0xf0;
  406. buffer[i] = nibble2 | nibble1;
  407. outportb ((unsigned short) gd_port, 0x80);
  408. }
  409. return GD_OK;
  410. }
  411. int
  412. gd_add_filename (const char *filename)
  413. {
  414. char buf[FILENAME_MAX], *p;
  415. if (gd_name_i < GD3_MAX_UNITS)
  416. {
  417. strcpy (buf, filename);
  418. p = strrchr (buf, '.');
  419. if (p)
  420. *p = 0;
  421. strncpy (gd_names[gd_name_i], basename2 (buf), 11);
  422. gd_names[gd_name_i][11] = 0;
  423. gd_name_i++;
  424. }
  425. return 0;
  426. }
  427. int
  428. gd3_read_rom (const char *filename, unsigned int parport)
  429. {
  430. (void) filename; // warning remover
  431. (void) parport; // warning remover
  432. return fputs ("ERROR: The function for dumping a cartridge is not yet implemented for the SF3\n", stderr);
  433. }
  434. int
  435. gd6_read_rom (const char *filename, unsigned int parport)
  436. {
  437. #if 0
  438. FILE *file;
  439. unsigned char *buffer;
  440. init_io (parport);
  441. if ((file = fopen (filename, "wb")) == NULL)
  442. {
  443. fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
  444. exit (1);
  445. }
  446. if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
  447. {
  448. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
  449. exit (1);
  450. }
  451. free (buffer);
  452. fclose (file);
  453. deinit_io ();
  454. return 0;
  455. #else
  456. (void) filename; // warning remover
  457. (void) parport; // warning remover
  458. return fputs ("ERROR: The function for dumping a cartridge is not yet implemented for the SF6\n", stderr);
  459. #endif
  460. }
  461. int
  462. gd3_write_rom (const char *filename, unsigned int parport, st_rominfo_t *rominfo)
  463. {
  464. gd_send_prolog_byte = gd3_send_prolog_byte; // for gd_send_unit_prolog()
  465. gd_send_prolog_bytes = gd3_send_prolog_bytes;
  466. gd_send_bytes = gd3_send_bytes;
  467. return gd_write_rom (filename, parport, rominfo, GD3_PROLOG_STRING);
  468. }
  469. int
  470. gd6_write_rom (const char *filename, unsigned int parport, st_rominfo_t *rominfo)
  471. {
  472. gd_send_prolog_byte = gd6_send_prolog_byte; // for gd_send_unit_prolog()
  473. gd_send_prolog_bytes = gd6_send_prolog_bytes;
  474. gd_send_bytes = gd6_send_bytes;
  475. return gd_write_rom (filename, parport, rominfo, GD6_READ_PROLOG_STRING);
  476. }
  477. /*
  478. Note: On most Game Doctor's the way you enter link mode to be able to upload
  479. the ROM to the unit is to hold down the R key on the controller while
  480. resetting the SNES. You will see the Game Doctor menu has a message that
  481. says "LINKING..."
  482. */
  483. int
  484. gd_write_rom (const char *filename, unsigned int parport, st_rominfo_t *rominfo,
  485. const char *prolog_str)
  486. {
  487. FILE *file = NULL;
  488. unsigned char *buffer;
  489. char *names[GD3_MAX_UNITS], names_mem[GD3_MAX_UNITS][12],
  490. *filenames[GD3_MAX_UNITS], dir[FILENAME_MAX];
  491. int num_units, i, send_header, x, split = 1, hirom = snes_get_snes_hirom();
  492. init_io (parport);
  493. // We don't want to malloc() ridiculously small chunks (of 12 bytes)
  494. for (i = 0; i < GD3_MAX_UNITS; i++)
  495. names[i] = names_mem[i];
  496. gd_names = (char **) names;
  497. ucon64_testsplit_callback = gd_add_filename;
  498. num_units = ucon64.split = ucon64_testsplit (filename); // this will call gd_add_filename()
  499. ucon64_testsplit_callback = NULL;
  500. if (!ucon64.split)
  501. {
  502. split = 0;
  503. num_units = snes_make_gd_names (filename, rominfo, (char **) names);
  504. }
  505. dirname2 (filename, dir);
  506. gd_fsize = 0;
  507. for (i = 0; i < num_units; i++)
  508. {
  509. // No suffix is necessary but the name entry must be upper case and MUST
  510. // be 11 characters long, padded at the end with spaces if necessary.
  511. memset (gd3_dram_unit[i].name, ' ', 11); // "pad" with spaces
  512. gd3_dram_unit[i].name[11] = 0; // terminate string so we can print it (debug)
  513. // Use memcpy() instead of strcpy() so that the string terminator in
  514. // names[i] won't be copied.
  515. memcpy (gd3_dram_unit[i].name, strupr (names[i]), strlen (names[i]));
  516. x = strlen (dir) + strlen (names[i]) + 6; // file sep., suffix, ASCII-z => 6
  517. if ((filenames[i] = (char *) malloc (x)) == NULL)
  518. {
  519. fprintf (stderr, ucon64_msg[BUFFER_ERROR], x);
  520. exit (1);
  521. }
  522. sprintf (filenames[i], "%s" FILE_SEPARATOR_S "%s.078", dir, names[i]); // should match with what code of -s does
  523. if (split)
  524. {
  525. x = fsizeof (filenames[i]);
  526. gd_fsize += x;
  527. gd3_dram_unit[i].size = x;
  528. if (i == 0) // Correct for header of first file
  529. gd3_dram_unit[i].size -= GD_HEADER_LEN;
  530. }
  531. else
  532. {
  533. if (!gd_fsize) // Don't call fsizeof() more
  534. gd_fsize = fsizeof (filename); // often than necessary
  535. if (hirom)
  536. gd3_dram_unit[i].size = (gd_fsize - GD_HEADER_LEN) / num_units;
  537. else
  538. {
  539. if ((i + 1) * 8 * MBIT <= gd_fsize - GD_HEADER_LEN)
  540. gd3_dram_unit[i].size = 8 * MBIT;
  541. else
  542. gd3_dram_unit[i].size = gd_fsize - GD_HEADER_LEN - i * 8 * MBIT;
  543. }
  544. }
  545. }
  546. if ((buffer = (unsigned char *) malloc (8 * MBIT)) == NULL)
  547. { // a DRAM unit can hold 8 Mbit at maximum
  548. fprintf (stderr, ucon64_msg[ROM_BUFFER_ERROR], 8 * MBIT);
  549. exit (1);
  550. }
  551. printf ("Send: %d Bytes (%.4f Mb)\n", gd_fsize, (float) gd_fsize / MBIT);
  552. // Put this just before the real transfer begins or else the ETA won't be
  553. // correct.
  554. gd_starttime = time (NULL);
  555. // Send the ROM to the hardware
  556. if (memcmp (prolog_str, GD6_READ_PROLOG_STRING, 4) == 0)
  557. if (gd6_sync_hardware () == GD_ERROR)
  558. io_error ();
  559. memcpy (buffer, prolog_str, 4);
  560. buffer[4] = num_units;
  561. if (gd_send_prolog_bytes (buffer, 5) == GD_ERROR)
  562. io_error ();
  563. puts ("Press q to abort\n");
  564. for (i = 0; i < num_units; i++)
  565. {
  566. #ifdef DEBUG
  567. printf ("\nfilename (%d): \"%s\", ", split, (split ? (char *) filenames[i] : filename));
  568. printf ("name: \"%s\", size: %d\n", gd3_dram_unit[i].name, gd3_dram_unit[i].size);
  569. #endif
  570. if (split)
  571. {
  572. if ((file = fopen (filenames[i], "rb")) == NULL)
  573. {
  574. fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filenames[i]);
  575. exit (1);
  576. }
  577. }
  578. else
  579. if (file == NULL) // don't open the file more than once
  580. if ((file = fopen (filename, "rb")) == NULL)
  581. {
  582. fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
  583. exit (1);
  584. }
  585. send_header = i == 0 ? 1 : 0;
  586. if (gd_send_unit_prolog (send_header, gd3_dram_unit[i].size) == GD_ERROR)
  587. io_error ();
  588. if (gd_send_prolog_bytes ((unsigned char *) gd3_dram_unit[i].name, 11) == GD_ERROR)
  589. io_error ();
  590. if (send_header)
  591. {
  592. // Send the Game Doctor 512 byte header
  593. fread (buffer, 1, GD_HEADER_LEN, file);
  594. if (gd_send_prolog_bytes (buffer, GD_HEADER_LEN) == GD_ERROR)
  595. io_error ();
  596. gd_bytessend += GD_HEADER_LEN;
  597. }
  598. if (split == 0) // Not pre-split -- have to split it ourselves
  599. {
  600. if (hirom)
  601. fseek (file, i * gd3_dram_unit[0].size + GD_HEADER_LEN, SEEK_SET);
  602. else
  603. fseek (file, i * 8 * MBIT + GD_HEADER_LEN, SEEK_SET);
  604. }
  605. fread (buffer, 1, gd3_dram_unit[i].size, file);
  606. if (gd_send_bytes (buffer, gd3_dram_unit[i].size) == GD_ERROR)
  607. io_error ();
  608. if (split || i == num_units - 1)
  609. fclose (file);
  610. }
  611. for (i = 0; i < num_units; i++)
  612. free (filenames[i]);
  613. free (buffer);
  614. deinit_io ();
  615. return 0;
  616. }
  617. int
  618. gd3_read_sram (const char *filename, unsigned int parport)
  619. {
  620. (void) filename; // warning remover
  621. (void) parport; // warning remover
  622. return fputs ("ERROR: The function for dumping SRAM is not yet implemented for the SF3\n", stderr);
  623. }
  624. int
  625. gd6_read_sram (const char *filename, unsigned int parport)
  626. {
  627. FILE *file;
  628. unsigned char *buffer, gdfilename[12];
  629. int len, bytesreceived = 0, transfer_size;
  630. time_t starttime;
  631. init_io (parport);
  632. if ((file = fopen (filename, "wb")) == NULL)
  633. {
  634. fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
  635. exit (1);
  636. }
  637. if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
  638. {
  639. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
  640. exit (1);
  641. }
  642. // Be nice to the user and automatically remove the file on an error (or abortion)
  643. gd_destfname = filename;
  644. gd_destfile = file;
  645. register_func (remove_destfile);
  646. if (gd6_sync_hardware () == GD_ERROR)
  647. io_error ();
  648. if (gd6_send_prolog_bytes ((unsigned char *) GD6_WRITE_PROLOG_STRING, 4) == GD_ERROR)
  649. io_error ();
  650. /*
  651. The BRAM (SRAM) filename doesn't have to exactly match any game loaded in
  652. the SF7. It needs to match any valid Game Doctor file name AND have an
  653. extension of .B## (where # is a digit from 0-9)
  654. */
  655. strcpy ((char *) gdfilename, "SF16497 B00"); // TODO: We might need to make a GD file name from the real one
  656. if (gd6_send_prolog_bytes (gdfilename, 11) == GD_ERROR)
  657. io_error ();
  658. if (gd6_sync_receive_start () == GD_ERROR)
  659. io_error ();
  660. if (gd6_receive_bytes (buffer, 16) == GD_ERROR)
  661. io_error ();
  662. transfer_size = buffer[1] | (buffer[2] << 8) | (buffer[3] << 16) | (buffer[4] << 24);
  663. if (transfer_size != 0x8000)
  664. {
  665. fprintf (stderr, "ERROR: SRAM transfer size from Game Doctor != 0x8000 bytes\n");
  666. exit (1);
  667. }
  668. printf ("Receive: %d Bytes\n", transfer_size);
  669. puts ("Press q to abort\n");
  670. starttime = time (NULL);
  671. while (bytesreceived < transfer_size)
  672. {
  673. if (transfer_size - bytesreceived >= BUFFERSIZE)
  674. len = BUFFERSIZE;
  675. else
  676. len = transfer_size - bytesreceived;
  677. if (gd6_receive_bytes (buffer, len) == GD_ERROR)
  678. io_error ();
  679. fwrite (buffer, 1, len, file);
  680. bytesreceived += len;
  681. ucon64_gauge (starttime, bytesreceived, 32 * 1024);
  682. gd_checkabort (2);
  683. }
  684. unregister_func (remove_destfile);
  685. free (buffer);
  686. fclose (file);
  687. deinit_io ();
  688. return 0;
  689. }
  690. int
  691. gd3_write_sram (const char *filename, unsigned int parport)
  692. {
  693. gd_send_prolog_bytes = gd3_send_prolog_bytes;
  694. gd_send_bytes = gd3_send_bytes;
  695. return gd_write_sram (filename, parport, GD3_PROLOG_STRING);
  696. }
  697. int
  698. gd6_write_sram (const char *filename, unsigned int parport)
  699. {
  700. gd_send_prolog_bytes = gd6_send_prolog_bytes;
  701. gd_send_bytes = gd6_send_bytes;
  702. return gd_write_sram (filename, parport, GD6_READ_PROLOG_STRING);
  703. }
  704. int
  705. gd_write_sram (const char *filename, unsigned int parport, const char *prolog_str)
  706. {
  707. FILE *file;
  708. unsigned char *buffer, gdfilename[12];
  709. int bytesread, bytessend = 0, size, header_size;
  710. time_t starttime;
  711. init_io (parport);
  712. if ((file = fopen (filename, "rb")) == NULL)
  713. {
  714. fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
  715. exit (1);
  716. }
  717. if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
  718. {
  719. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
  720. exit (1);
  721. }
  722. size = fsizeof (filename); // GD SRAM is 4*8 KB, emu SRAM often not
  723. if (size == 0x8000)
  724. header_size = 0;
  725. else if (size == 0x8200)
  726. {
  727. header_size = 0x200;
  728. size = 0x8000;
  729. }
  730. else
  731. {
  732. fputs ("ERROR: GD SRAM file size must be 32768 or 33280 bytes\n", stderr);
  733. exit (1);
  734. }
  735. printf ("Send: %d Bytes\n", size);
  736. fseek (file, header_size, SEEK_SET); // skip the header
  737. if (memcmp (prolog_str, GD6_READ_PROLOG_STRING, 4) == 0)
  738. if (gd6_sync_hardware () == GD_ERROR)
  739. io_error ();
  740. memcpy (buffer, prolog_str, 4);
  741. buffer[4] = 1;
  742. if (gd_send_prolog_bytes (buffer, 5) == GD_ERROR)
  743. io_error ();
  744. buffer[0] = 0x00;
  745. buffer[1] = 0x80;
  746. buffer[2] = 0x00;
  747. buffer[3] = 0x00;
  748. if (gd_send_prolog_bytes (buffer, 4) == GD_ERROR)
  749. io_error ();
  750. /*
  751. The BRAM (SRAM) filename doesn't have to exactly match any game loaded in
  752. the SF7. It needs to match any valid Game Doctor file name AND have an
  753. extension of .B## (where # is a digit from 0-9)
  754. */
  755. strcpy ((char *) gdfilename, "SF8123 B00"); // TODO: We might need to make a GD file name from the real one
  756. if (gd_send_prolog_bytes (gdfilename, 11) == GD_ERROR)
  757. io_error ();
  758. puts ("Press q to abort\n"); // print here, NOT before first GD I/O,
  759. // because if we get here q works ;-)
  760. starttime = time (NULL);
  761. while ((bytesread = fread (buffer, 1, BUFFERSIZE, file)))
  762. {
  763. if (gd_send_bytes (buffer, bytesread) == GD_ERROR)
  764. io_error ();
  765. bytessend += bytesread;
  766. ucon64_gauge (starttime, bytessend, size);
  767. gd_checkabort (2);
  768. }
  769. free (buffer);
  770. fclose (file);
  771. deinit_io ();
  772. return 0;
  773. }
  774. int
  775. gd3_read_saver (const char *filename, unsigned int parport)
  776. {
  777. (void) filename; // warning remover
  778. (void) parport; // warning remover
  779. return fputs ("ERROR: The function for dumping saver data is not yet implemented for the SF3\n", stderr);
  780. }
  781. int
  782. gd6_read_saver (const char *filename, unsigned int parport)
  783. {
  784. FILE *file;
  785. unsigned char *buffer, gdfilename[12];
  786. int len, bytesreceived = 0, transfer_size;
  787. time_t starttime;
  788. init_io (parport);
  789. if ((file = fopen (filename, "wb")) == NULL)
  790. {
  791. fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
  792. exit (1);
  793. }
  794. if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
  795. {
  796. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
  797. exit (1);
  798. }
  799. // Be nice to the user and automatically remove the file on an error (or abortion)
  800. gd_destfname = filename;
  801. gd_destfile = file;
  802. register_func (remove_destfile);
  803. if (gd6_sync_hardware () == GD_ERROR)
  804. io_error ();
  805. if (gd6_send_prolog_bytes ((unsigned char *) GD6_WRITE_PROLOG_STRING, 4) == GD_ERROR)
  806. io_error ();
  807. /*
  808. TODO: Graceful handling of an abort because of a name error?
  809. Currently we fail with a generic error.
  810. TODO: We could make a GD file name from the real one but a valid dummy name
  811. seems to work OK here. The user must have the proper game selected in
  812. the SF7 menu even if the real name is used.
  813. */
  814. strcpy ((char *) gdfilename, "SF16497 S00");
  815. if (gd6_send_prolog_bytes (gdfilename, 11) == GD_ERROR)
  816. io_error ();
  817. if (gd6_sync_receive_start () == GD_ERROR)
  818. io_error ();
  819. if (gd6_receive_bytes (buffer, 16) == GD_ERROR)
  820. io_error ();
  821. transfer_size = buffer[1] | (buffer[2] << 8) | (buffer[3] << 16) | (buffer[4] << 24);
  822. if (transfer_size != 0x38000)
  823. {
  824. fputs ("ERROR: Saver transfer size from Game Doctor != 0x38000 bytes\n", stderr);
  825. exit (1);
  826. }
  827. printf ("Receive: %d Bytes\n", transfer_size);
  828. puts ("Press q to abort\n");
  829. starttime = time (NULL);
  830. while (bytesreceived < transfer_size)
  831. {
  832. if (transfer_size - bytesreceived >= BUFFERSIZE)
  833. len = BUFFERSIZE;
  834. else
  835. len = transfer_size - bytesreceived;
  836. if (gd6_receive_bytes (buffer, len) == GD_ERROR)
  837. io_error ();
  838. fwrite (buffer, 1, len, file);
  839. bytesreceived += len;
  840. ucon64_gauge (starttime, bytesreceived, 32 * 1024);
  841. gd_checkabort (2);
  842. }
  843. unregister_func (remove_destfile);
  844. free (buffer);
  845. fclose (file);
  846. deinit_io ();
  847. return 0;
  848. }
  849. int
  850. gd3_write_saver (const char *filename, unsigned int parport)
  851. {
  852. gd_send_prolog_bytes = gd3_send_prolog_bytes;
  853. gd_send_bytes = gd3_send_bytes;
  854. return gd_write_saver (filename, parport, GD3_PROLOG_STRING);
  855. }
  856. int
  857. gd6_write_saver (const char *filename, unsigned int parport)
  858. {
  859. gd_send_prolog_bytes = gd6_send_prolog_bytes;
  860. gd_send_bytes = gd6_send_bytes;
  861. return gd_write_saver (filename, parport, GD6_READ_PROLOG_STRING);
  862. }
  863. int
  864. gd_write_saver (const char *filename, unsigned int parport, const char *prolog_str)
  865. {
  866. FILE *file;
  867. unsigned char *buffer, gdfilename[12];
  868. const char *p;
  869. int bytesread, bytessend = 0, size, fn_length;
  870. time_t starttime;
  871. init_io (parport);
  872. /*
  873. Check that filename is a valid Game Doctor saver filename.
  874. It should start with SF, followed by the game ID, followed by the extension.
  875. The extension is of the form .S## (where # is a digit from 0-9).
  876. E.g., SF16123.S00
  877. The saver base filename must match the base name of the game (loaded in the
  878. Game Doctor) that you are loading the saver data for.
  879. */
  880. // Strip the path out of filename for use in the GD
  881. p = basename2 (filename);
  882. fn_length = strlen (p);
  883. if (fn_length < 6 || fn_length > 11 // 7 ("base") + 1 (period) + 3 (extension)
  884. || toupper (p[0]) != 'S' || toupper (p[1]) != 'F'
  885. || p[fn_length - 4] != '.' || toupper (p[fn_length - 3]) != 'S')
  886. {
  887. fprintf (stderr, "ERROR: Filename (%s) is not a saver filename (SF*.S##)\n", p);
  888. exit (1);
  889. }
  890. if ((file = fopen (filename, "rb")) == NULL)
  891. {
  892. fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
  893. exit (1);
  894. }
  895. if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
  896. {
  897. fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
  898. exit (1);
  899. }
  900. size = fsizeof (filename);
  901. if (size != 0x38000) // GD saver size is always 0x38000 bytes -- no header
  902. {
  903. fputs ("ERROR: GD saver file size must be 229376 bytes\n", stderr);
  904. exit (1);
  905. }
  906. // Make a GD file name from the real one
  907. memset (gdfilename, ' ', 11); // "pad" with spaces
  908. gdfilename[11] = 0; // terminate string
  909. memcpy (gdfilename, p, fn_length - 4); // copy name except extension
  910. memcpy (&gdfilename[8], "S00", 3); // copy extension S00
  911. strupr ((char *) gdfilename);
  912. printf ("Send: %d Bytes\n", size);
  913. fseek (file, 0, SEEK_SET);
  914. if (memcmp (prolog_str, GD6_READ_PROLOG_STRING, 4) == 0)
  915. if (gd6_sync_hardware () == GD_ERROR)
  916. io_error ();
  917. memcpy (buffer, prolog_str, 4);
  918. buffer[4] = 1;
  919. if (gd_send_prolog_bytes (buffer, 5) == GD_ERROR)
  920. io_error ();
  921. // Transfer 0x38000 bytes
  922. buffer[0] = 0x00;
  923. buffer[1] = 0x80;
  924. buffer[2] = 0x03;
  925. buffer[3] = 0x00;
  926. if (gd_send_prolog_bytes (buffer, 4) == GD_ERROR)
  927. io_error ();
  928. if (gd_send_prolog_bytes (gdfilename, 11) == GD_ERROR)
  929. io_error ();
  930. puts ("Press q to abort\n"); // print here, NOT before first GD I/O,
  931. // because if we get here q works ;-)
  932. starttime = time (NULL);
  933. while ((bytesread = fread (buffer, 1, BUFFERSIZE, file)))
  934. {
  935. if (gd_send_bytes (buffer, bytesread) == GD_ERROR)
  936. io_error ();
  937. bytessend += bytesread;
  938. ucon64_gauge (starttime, bytessend, size);
  939. gd_checkabort (2);
  940. }
  941. free (buffer);
  942. fclose (file);
  943. deinit_io ();
  944. return 0;
  945. }
  946. #endif // USE_PARALLEL