mccl.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. mccl.c - Mad Catz Camera Link (Game Boy Camera) support for uCON64
  3. Copyright (c) 2002 NoisyB
  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. /*
  17. This cable is made by Mad Catz, Inc. and has a Game Boy link connector on one
  18. end and a parallel port connector on the other. It is designed to interface
  19. with the Game Boy Camera cart and comes with included software for this. It
  20. works by simulating the Game Boy Printer with a PIC chip inside the parallel
  21. connector shell. It doesn't do a particularly good job at that so it pretty
  22. much only works with the Game Boy Camera.
  23. Mad Catz Camera Link Communications Protocol
  24. Printer IO Ports:
  25. Base+0: Data Port
  26. Base+1: Status Port
  27. Base+2: Control
  28. Reset Procedure:
  29. 1. Output 0x24 to control (tristate data and set control to 0100)
  30. 2. Wait for bit 5 of status port to become 1
  31. 3. Read lower 4 bits of data port
  32. 4. If read data != 4, then go to step 1.
  33. 5. (Useless read of control port?)
  34. 6. Output 0x22 to control (tristate data and set control to 0010)
  35. 7. Wait for bit 5 of status port to become 0
  36. 8. Output 0x26 to control (tristate data and set control to 0110)
  37. Data Read Procedure:
  38. 1. Output 0x26 to control (tristate data and set control to 0110)
  39. 2. Wait for bit 5 of status port to become 1
  40. 3. Read lower 4 bits of data port, store to lower 4 bits of received byte
  41. 4. (Useless read of control port?)
  42. 5. Output 0x22 to control (tristate data and set control to 0010)
  43. 6. Wait for bit 5 of status port to become 0
  44. 7. Output 0x26 to control (tristate data and set control to 0110)
  45. 8. Wait for bit 5 of status port to become 1
  46. 9. Read lower 4 bits of data port, store to upper 4 bits of received byte
  47. 10. (Useless read of control port?)
  48. 11. Output 0x22 to control (tristate data and set control to 0010)
  49. 12. Wait for bit 5 of status port to become 0
  50. 13. Go to step 1
  51. */
  52. #ifdef HAVE_CONFIG_H
  53. #include "config.h"
  54. #endif
  55. #include <string.h>
  56. #include "misc/archive.h"
  57. #include "misc/file.h"
  58. #include "misc/parallel.h"
  59. #include "ucon64.h"
  60. #include "ucon64_misc.h"
  61. #include "backup/mccl.h"
  62. #ifdef USE_PARALLEL
  63. static st_ucon64_obj_t mccl_obj[] =
  64. {
  65. {UCON64_GB, WF_DEFAULT | WF_STOP | WF_NO_ROM}
  66. };
  67. #endif
  68. const st_getopt2_t mccl_usage[] =
  69. {
  70. {
  71. NULL, 0, 0, 0,
  72. NULL, "Mad Catz Camera Link (Game Boy Camera)"/*"XXXX Mad Catz Inc. http://www.madcatz.com"*/,
  73. NULL
  74. },
  75. #ifdef USE_PARALLEL
  76. {
  77. "xmccl", 0, 0, UCON64_XMCCL,
  78. NULL, "receives from Mad Catz Camera Link; " OPTION_LONG_S "port=PORT",
  79. &mccl_obj[0]
  80. },
  81. #endif
  82. {NULL, 0, 0, 0, NULL, NULL, NULL}
  83. };
  84. #ifdef USE_PARALLEL
  85. #define DATA ((unsigned short) (parport + PARPORT_DATA))
  86. #define STATUS ((unsigned short) (parport + PARPORT_STATUS))
  87. #define CONTROL ((unsigned short) (parport + PARPORT_CONTROL))
  88. int
  89. mccl_read (const char *filename, unsigned int parport)
  90. {
  91. unsigned char buffer[0x1760], inbyte;
  92. char dest_name[FILENAME_MAX];
  93. int count = 0;
  94. time_t starttime;
  95. parport_print_info ();
  96. puts ("Resetting device");
  97. do
  98. {
  99. outportb (CONTROL, 0x24);
  100. while ((inportb (STATUS) & 0x20) == 0)
  101. ;
  102. }
  103. while ((inportw (DATA) & 0xf) != 4);
  104. outportb (CONTROL, 0x22);
  105. while ((inportb (STATUS) & 0x20) != 0)
  106. ;
  107. outportb (CONTROL, 0x26);
  108. printf ("Receive: %d Bytes (%.4f Mb)\n\n", 0x1760, (float) 0x1760 / MBIT);
  109. starttime = time (NULL);
  110. do
  111. {
  112. outportb (CONTROL, 0x26);
  113. while ((inportb (STATUS) & 0x20) == 0)
  114. ;
  115. inbyte = (unsigned char) (inportw (DATA) & 0xf);
  116. outportb (CONTROL, 0x22);
  117. while ((inportb (STATUS) & 0x20) != 0)
  118. ;
  119. outportb (CONTROL, 0x26);
  120. while ((inportb (STATUS) & 0x20) == 0)
  121. ;
  122. inbyte |= (unsigned char) ((inportw (DATA) & 0xf) << 4);
  123. outportb (CONTROL, 0x22);
  124. while ((inportb (STATUS) & 0x20) != 0)
  125. ;
  126. buffer[count++] = inbyte;
  127. if ((count & 0x1f) == 0)
  128. ucon64_gauge (starttime, count, 0x1760);
  129. }
  130. while (count < 0x1760);
  131. strcpy (dest_name, filename);
  132. ucon64_file_handler (dest_name, NULL, 0);
  133. ucon64_fwrite (buffer, 0, count, dest_name, "wb");
  134. printf (ucon64_msg[WROTE], dest_name);
  135. return 0;
  136. }
  137. #endif // USE_PARALLEL