/* mccl.c - Mad Catz Camera Link (Game Boy Camera) support for uCON64 Copyright (c) 2002 NoisyB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* This cable is made by Mad Catz, Inc. and has a Game Boy link connector on one end and a parallel port connector on the other. It is designed to interface with the Game Boy Camera cart and comes with included software for this. It works by simulating the Game Boy Printer with a PIC chip inside the parallel connector shell. It doesn't do a particularly good job at that so it pretty much only works with the Game Boy Camera. Mad Catz Camera Link Communications Protocol Printer IO Ports: Base+0: Data Port Base+1: Status Port Base+2: Control Reset Procedure: 1. Output 0x24 to control (tristate data and set control to 0100) 2. Wait for bit 5 of status port to become 1 3. Read lower 4 bits of data port 4. If read data != 4, then go to step 1. 5. (Useless read of control port?) 6. Output 0x22 to control (tristate data and set control to 0010) 7. Wait for bit 5 of status port to become 0 8. Output 0x26 to control (tristate data and set control to 0110) Data Read Procedure: 1. Output 0x26 to control (tristate data and set control to 0110) 2. Wait for bit 5 of status port to become 1 3. Read lower 4 bits of data port, store to lower 4 bits of received byte 4. (Useless read of control port?) 5. Output 0x22 to control (tristate data and set control to 0010) 6. Wait for bit 5 of status port to become 0 7. Output 0x26 to control (tristate data and set control to 0110) 8. Wait for bit 5 of status port to become 1 9. Read lower 4 bits of data port, store to upper 4 bits of received byte 10. (Useless read of control port?) 11. Output 0x22 to control (tristate data and set control to 0010) 12. Wait for bit 5 of status port to become 0 13. Go to step 1 */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include "misc/archive.h" #include "misc/file.h" #include "misc/parallel.h" #include "ucon64.h" #include "ucon64_misc.h" #include "backup/mccl.h" #ifdef USE_PARALLEL static st_ucon64_obj_t mccl_obj[] = { {UCON64_GB, WF_DEFAULT | WF_STOP | WF_NO_ROM} }; #endif const st_getopt2_t mccl_usage[] = { { NULL, 0, 0, 0, NULL, "Mad Catz Camera Link (Game Boy Camera)"/*"XXXX Mad Catz Inc. http://www.madcatz.com"*/, NULL }, #ifdef USE_PARALLEL { "xmccl", 0, 0, UCON64_XMCCL, NULL, "receives from Mad Catz Camera Link; " OPTION_LONG_S "port=PORT", &mccl_obj[0] }, #endif {NULL, 0, 0, 0, NULL, NULL, NULL} }; #ifdef USE_PARALLEL #define DATA ((unsigned short) (parport + PARPORT_DATA)) #define STATUS ((unsigned short) (parport + PARPORT_STATUS)) #define CONTROL ((unsigned short) (parport + PARPORT_CONTROL)) int mccl_read (const char *filename, unsigned int parport) { unsigned char buffer[0x1760], inbyte; char dest_name[FILENAME_MAX]; int count = 0; time_t starttime; parport_print_info (); puts ("Resetting device"); do { outportb (CONTROL, 0x24); while ((inportb (STATUS) & 0x20) == 0) ; } while ((inportw (DATA) & 0xf) != 4); outportb (CONTROL, 0x22); while ((inportb (STATUS) & 0x20) != 0) ; outportb (CONTROL, 0x26); printf ("Receive: %d Bytes (%.4f Mb)\n\n", 0x1760, (float) 0x1760 / MBIT); starttime = time (NULL); do { outportb (CONTROL, 0x26); while ((inportb (STATUS) & 0x20) == 0) ; inbyte = (unsigned char) (inportw (DATA) & 0xf); outportb (CONTROL, 0x22); while ((inportb (STATUS) & 0x20) != 0) ; outportb (CONTROL, 0x26); while ((inportb (STATUS) & 0x20) == 0) ; inbyte |= (unsigned char) ((inportw (DATA) & 0xf) << 4); outportb (CONTROL, 0x22); while ((inportb (STATUS) & 0x20) != 0) ; buffer[count++] = inbyte; if ((count & 0x1f) == 0) ucon64_gauge (starttime, count, 0x1760); } while (count < 0x1760); strcpy (dest_name, filename); ucon64_file_handler (dest_name, NULL, 0); ucon64_fwrite (buffer, 0, count, dest_name, "wb"); printf (ucon64_msg[WROTE], dest_name); return 0; } #endif // USE_PARALLEL