quickdev16/tools/ucon64/src/ucon64_opts.c
2009-08-28 09:12:33 +02:00

2205 lines
62 KiB
C

/*
ucon64_opts.c - switch()'es for all uCON64 options
Copyright (c) 2002 - 2004 NoisyB <noisyb@gmx.net>
Copyright (c) 2002 - 2004 dbjh
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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <ctype.h>
#include <time.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "misc/misc.h"
#include "misc/getopt2.h"
#include "misc/file.h"
#include "misc/string.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "ucon64.h"
#include "ucon64_misc.h"
#include "ucon64_dat.h"
#include "console/console.h"
#include "patch/patch.h"
#include "backup/backup.h"
#include "misc/chksum.h"
#ifdef _MSC_VER
// Visual C++ doesn't allow inline in C source code
#define inline __inline
#endif
int
ucon64_switches (st_ucon64_t *p)
{
#ifdef USE_DISCMAGE
int x = 0;
#endif
int c = p->option;
const char *optarg = p->optarg;
/*
Handle options or switches that cause other _options_ to be ignored except
other options of the same class (so the order in which they were specified
matters).
We have to do this here (not in ucon64_options()) or else other options
might be executed before these.
*/
switch (c)
{
/*
Many tools ignore other options if --help has been specified. We do the
same (compare with GNU tools).
*/
case UCON64_HELP:
ucon64_usage (ucon64.argc, ucon64.argv);
exit (0);
/*
It's also common to exit after displaying version information.
On some configurations printf is a macro (Red Hat Linux 6.2 + GCC 3.2),
so we can't use preprocessor directives in the argument list.
*/
case UCON64_VER:
printf ("version: %s (%s)\n"
"platform: %s\n",
UCON64_VERSION_S, __DATE__,
CURRENT_OS_S);
#ifdef WORDS_BIGENDIAN
puts ("endianess: big");
#else
puts ("endianess: little");
#endif
#ifdef DEBUG
puts ("debug: yes");
#else
puts ("debug: no");
#endif
#ifdef USE_PARALLEL
#ifdef USE_PPDEV
puts ("parallel port backup unit support: yes (ppdev)");
#else
puts ("parallel port backup unit support: yes");
#endif // USE_PPDEV
#else
puts ("parallel port backup unit support: no");
#endif
#ifdef USE_USB
puts ("USB port backup unit support: yes");
#else
puts ("USB port backup unit support: no");
#endif
#ifdef USE_ANSI_COLOR
puts ("ANSI colors enabled: yes");
#else
puts ("ANSI colors enabled: no");
#endif
#ifdef USE_ZLIB
puts ("gzip and zip support: yes");
#else
puts ("gzip and zip support: no");
#endif
printf ("configuration file %s %s\n",
// display the existence only for the config file (really helps solving problems)
access (ucon64.configfile, F_OK) ? "(not present):" : "(present): ",
ucon64.configfile);
#ifdef USE_DISCMAGE
printf ("discmage DLL: ");
#ifdef DLOPEN
puts (ucon64.discmage_path);
#else
#if defined __MSDOS__
printf ("discmage.dxe");
#elif defined __CYGWIN__ || defined _WIN32
printf ("discmage.dll");
#elif defined __APPLE__ // Mac OS X actually
printf ("libdiscmage.dylib");
#elif defined __unix__ || defined __BEOS__
printf ("libdiscmage.so");
#else
printf ("unknown");
#endif
puts (", dynamically linked");
#endif // DLOPEN
printf ("discmage enabled: %s\n",
ucon64.discmage_enabled ? "yes" : "no");
if (ucon64.discmage_enabled)
{
x = dm_get_version ();
printf ("discmage version: %d.%d.%d (%s)\n",
x >> 16, x >> 8, x, dm_get_version_s ());
}
else
puts ("discmage version: not available");
#endif // USE_DISCMAGE
printf ("configuration directory: %s\n"
"DAT file directory: %s\n"
"entries in DATabase: %d\n"
"DATabase enabled: %s\n",
ucon64.configdir,
ucon64.datdir,
ucon64_dat_total_entries (),
ucon64.dat_enabled ? "yes" : "no");
exit (0);
break;
case UCON64_FRONTEND:
ucon64.frontend = 1; // used by ucon64_gauge()
break;
case UCON64_NBAK:
ucon64.backup = 0;
break;
#ifdef USE_ANSI_COLOR
case UCON64_NCOL:
ucon64.ansi_color = 0;
break;
#endif
case UCON64_RIP:
case UCON64_MKTOC:
case UCON64_MKCUE:
case UCON64_MKSHEET:
case UCON64_BIN2ISO:
case UCON64_ISOFIX:
case UCON64_XCDRW:
case UCON64_DISC:
case UCON64_CDMAGE:
ucon64.force_disc = 1;
break;
case UCON64_NS:
ucon64.split = 0;
break;
case UCON64_HD:
ucon64.buheader_len = UNKNOWN_HEADER_LEN;
break;
case UCON64_HDN:
ucon64.buheader_len = strtol (optarg, NULL, 10);
break;
case UCON64_NHD:
ucon64.buheader_len = 0;
break;
case UCON64_SWP: // deprecated
case UCON64_INT:
ucon64.interleaved = 1;
break;
case UCON64_INT2:
ucon64.interleaved = 2;
break;
case UCON64_NSWP: // deprecated
case UCON64_NINT:
ucon64.interleaved = 0;
break;
case UCON64_PORT:
#ifdef USE_USB
if (!strnicmp (optarg, "usb", 3))
{
if (strlen (optarg) >= 4)
ucon64.usbport = strtol (optarg + 3, NULL, 10) + 1; // usb0 => ucon64.usbport = 1
else // we automatically detect the
ucon64.usbport = 1; // USB port in the F2A code
/*
We don't want to make uCON64 behave different if --port=USB{n} is
specified *after* a transfer option (instead of before one), so we
have to reset ucon64.parport_needed here.
*/
ucon64.parport_needed = 0;
}
else
#endif
ucon64.parport = strtol (optarg, NULL, 16);
break;
#ifdef USE_PARALLEL
/*
We detect the presence of these options here so that we can drop
privileges ASAP.
Note that the libcd64 options are not listed here. We cannot drop
privileges before libcd64 is initialised (after cd64_t.devopen() has been
called).
*/
case UCON64_XCMC:
case UCON64_XCMCT:
case UCON64_XDEX:
case UCON64_XDJR:
case UCON64_XF2A: // could be for USB version
case UCON64_XF2AMULTI: // idem
case UCON64_XF2AC: // idem
case UCON64_XF2AS: // idem
case UCON64_XF2AB: // idem
case UCON64_XFAL:
case UCON64_XFALMULTI:
case UCON64_XFALC:
case UCON64_XFALS:
case UCON64_XFALB:
case UCON64_XFIG:
case UCON64_XFIGS:
case UCON64_XFIGC:
case UCON64_XGBX:
case UCON64_XGBXS:
case UCON64_XGBXB:
case UCON64_XGD3:
case UCON64_XGD3R:
case UCON64_XGD3S:
case UCON64_XGD6:
case UCON64_XGD6R:
case UCON64_XGD6S:
case UCON64_XGG:
case UCON64_XGGS:
case UCON64_XGGB:
case UCON64_XLIT:
case UCON64_XMCCL:
case UCON64_XMCD:
case UCON64_XMD:
case UCON64_XMDS:
case UCON64_XMDB:
case UCON64_XMSG:
case UCON64_XPCE:
case UCON64_XPL:
case UCON64_XPLI:
case UCON64_XSF:
case UCON64_XSFS:
case UCON64_XSMC:
case UCON64_XSMCR:
case UCON64_XSMD:
case UCON64_XSMDS:
case UCON64_XSNESRAM:
case UCON64_XSWC:
case UCON64_XSWC2:
case UCON64_XSWCR:
case UCON64_XSWCS:
case UCON64_XSWCC:
case UCON64_XV64:
#ifdef USE_USB
if (!ucon64.usbport) // no pport I/O if F2A option and USB F2A
#endif
ucon64.parport_needed = 1;
/*
We want to make this possible:
1.) ucon64 <transfer option> <rom>
2.) ucon64 <transfer option> <rom> --port=<parallel port address>
The above works "automatically". The following type of command used to
be possible, but has been deprecated:
3.) ucon64 <transfer option> <rom> <parallel port address>
It has been removed, because it caused problems when specifying additional
switches without specifying the parallel port address. For example:
ucon64 -xfal -xfalm <rom>
This would be interpreted as:
ucon64 -xfal -xfalm <rom as file> <rom as parallel port address>
If <rom> has a name that starts with a number an I/O port associated
with that number will be accessed which might well have unwanted
results. We cannot check for valid I/O port numbers, because the I/O
port of the parallel port can be mapped to almost any 16-bit number.
*/
#if 0
if (ucon64.parport == UCON64_UNKNOWN)
if (ucon64.argc >= 4)
if (access (ucon64.argv[ucon64.argc - 1], F_OK))
// Yes, we don't get here if ucon64.argv[ucon64.argc - 1] is [0x]278,
// [0x]378 or [0x]3bc and a file with the same name (path) exists.
ucon64.parport = strtol (ucon64.argv[ucon64.argc - 1], NULL, 16);
#endif
break;
#ifdef USE_LIBCD64
case UCON64_XCD64:
case UCON64_XCD64B:
case UCON64_XCD64C:
case UCON64_XCD64E:
case UCON64_XCD64F:
case UCON64_XCD64M:
case UCON64_XCD64S:
// We don't really need the parallel port. We just have to make sure that
// privileges aren't dropped.
ucon64.parport_needed = 2;
break;
case UCON64_XCD64P:
ucon64.io_mode = strtol (optarg, NULL, 10);
break;
#endif
case UCON64_XCMCM:
ucon64.io_mode = strtol (optarg, NULL, 10);
break;
case UCON64_XFALM:
case UCON64_XGBXM:
case UCON64_XPLM:
ucon64.parport_mode = UCON64_EPP;
break;
case UCON64_XSWC_IO:
ucon64.io_mode = strtol (optarg, NULL, 16);
if (ucon64.io_mode & SWC_IO_ALT_ROM_SIZE)
puts ("WARNING: I/O mode not yet implemented");
#if 0 // all these constants are defined by default
if (ucon64.io_mode & (SWC_IO_SPC7110 | SWC_IO_SDD1 | SWC_IO_SA1 | SWC_IO_MMX2))
puts ("WARNING: Be sure to compile swc.c with the appropriate constants defined");
#endif
if (ucon64.io_mode > SWC_IO_MAX)
{
printf ("WARNING: Invalid value for MODE (0x%x), using 0\n", ucon64.io_mode);
ucon64.io_mode = 0;
}
else
{
printf ("I/O mode: 0x%03x", ucon64.io_mode);
if (ucon64.io_mode)
{
char flagstr[100];
flagstr[0] = 0;
if (ucon64.io_mode & SWC_IO_FORCE_32MBIT)
strcat (flagstr, "force 32 Mbit dump, ");
if (ucon64.io_mode & SWC_IO_ALT_ROM_SIZE)
strcat (flagstr, "alternative ROM size method, ");
if (ucon64.io_mode & SWC_IO_SUPER_FX)
strcat (flagstr, "Super FX, ");
if (ucon64.io_mode & SWC_IO_SDD1)
strcat (flagstr, "S-DD1, ");
if (ucon64.io_mode & SWC_IO_SA1)
strcat (flagstr, "SA-1, ");
if (ucon64.io_mode & SWC_IO_SPC7110)
strcat (flagstr, "SPC7110, ");
if (ucon64.io_mode & SWC_IO_DX2_TRICK)
strcat (flagstr, "DX2 trick, ");
if (ucon64.io_mode & SWC_IO_MMX2)
strcat (flagstr, "Mega Man X 2, ");
if (ucon64.io_mode & SWC_IO_DUMP_BIOS)
strcat (flagstr, "dump BIOS, ");
if (flagstr[0])
flagstr[strlen (flagstr) - 2] = 0;
printf (" (%s)", flagstr);
}
fputc ('\n', stdout);
}
break;
#endif // USE_PARALLEL
case UCON64_PATCH: // falling through, so --patch is an alias for --file
case UCON64_FILE:
ucon64.file = optarg;
break;
case UCON64_I:
case UCON64_B:
case UCON64_A:
case UCON64_NA:
case UCON64_PPF:
case UCON64_NPPF:
case UCON64_IDPPF:
if (!ucon64.file || !ucon64.file[0])
ucon64.file = ucon64.argv[ucon64.argc - 1];
break;
#if 0
case UCON64_ROM:
if (optarg)
ucon64.rom = optarg;
break;
#endif
case UCON64_O:
{
struct stat fstate;
int dir = 0;
if (!stat (optarg, &fstate))
if (S_ISDIR (fstate.st_mode))
{
strcpy (ucon64.output_path, optarg);
if (ucon64.output_path[strlen (ucon64.output_path) - 1] != FILE_SEPARATOR)
strcat (ucon64.output_path, FILE_SEPARATOR_S);
dir = 1;
}
if (!dir)
puts ("WARNING: Argument for -o must be a directory. Using current directory instead");
}
break;
case UCON64_NHI:
ucon64.snes_hirom = 0;
break;
case UCON64_HI:
ucon64.snes_hirom = SNES_HIROM;
break;
case UCON64_EROM:
ucon64.snes_header_base = SNES_EROM;
break;
case UCON64_BS:
ucon64.bs_dump = 1;
break;
case UCON64_NBS:
ucon64.bs_dump = 0;
break;
case UCON64_CTRL:
if (UCON64_ISSET (ucon64.controller))
ucon64.controller |= 1 << strtol (optarg, NULL, 10);
else
ucon64.controller = 1 << strtol (optarg, NULL, 10);
break;
case UCON64_CTRL2:
if (UCON64_ISSET (ucon64.controller2))
ucon64.controller2 |= 1 << strtol (optarg, NULL, 10);
else
ucon64.controller2 = 1 << strtol (optarg, NULL, 10);
break;
case UCON64_NTSC:
if (!UCON64_ISSET (ucon64.tv_standard))
ucon64.tv_standard = 0;
else if (ucon64.tv_standard == 1)
ucon64.tv_standard = 2; // code for NTSC/PAL (NES UNIF)
break;
case UCON64_PAL:
if (!UCON64_ISSET (ucon64.tv_standard))
ucon64.tv_standard = 1;
else if (ucon64.tv_standard == 0)
ucon64.tv_standard = 2; // code for NTSC/PAL (NES UNIF)
break;
case UCON64_BAT:
ucon64.battery = 1;
break;
case UCON64_NBAT:
ucon64.battery = 0;
break;
case UCON64_VRAM:
ucon64.vram = 1;
break;
case UCON64_NVRAM:
ucon64.vram = 0;
break;
case UCON64_MIRR:
ucon64.mirror = strtol (optarg, NULL, 10);
break;
case UCON64_MAPR:
ucon64.mapr = optarg; // pass the _string_, it can be a
break; // board name
case UCON64_CMNT:
ucon64.comment = optarg;
break;
case UCON64_DUMPINFO:
ucon64.use_dump_info = 1;
ucon64.dump_info = optarg;
break;
case UCON64_RR83:
ucon64.fname_len = UCON64_RR83;
break;
case UCON64_FORCE63:
ucon64.fname_len = UCON64_FORCE63;
break;
case UCON64_Q:
case UCON64_QQ: //UCON64_XSMC for now -qq is equivalent to -q
ucon64.quiet = 1;
break;
case UCON64_V:
ucon64.quiet = -1;
break;
case UCON64_SSIZE:
ucon64.part_size = strtol (optarg, NULL, 10) * MBIT;
break;
case UCON64_ID:
ucon64.id = 1;
break;
case UCON64_REGION:
if (optarg[1] == 0 && toupper (optarg[0]) == 'X') // be insensitive to case
ucon64.region = 256;
else
ucon64.region = strtol (optarg, NULL, 10);
break;
default:
break;
}
return 0;
}
static inline char *
to_func (char *s, int len, int (*func) (int))
{
char *p = s;
for (; len > 0; p++, len--)
*p = func (*p);
return s;
}
static inline int
toprint (int c)
{
if (isprint (c))
return c;
// characters that also work with printf()
#ifdef USE_ANSI_COLOR
if (c == '\x1b')
return ucon64.ansi_color ? c : '.';
#endif
return strchr ("\t\n\r", c) ? c : '.';
}
int
ucon64_options (st_ucon64_t *p)
{
#ifdef USE_PARALLEL
int enableRTS = -1; // for UCON64_XSWC & UCON64_XSWC2
#endif
int value = 0, x = 0, padded;
unsigned int checksum;
char buf[MAXBUFSIZE], src_name[FILENAME_MAX], dest_name[FILENAME_MAX],
*ptr = NULL;
struct stat fstate;
int c = p->option;
const char *optarg = p->optarg;
if (ucon64.rom)
{
strcpy (src_name, ucon64.rom);
strcpy (dest_name, ucon64.rom);
}
switch (c)
{
case UCON64_CRCHD: // deprecated
value = UNKNOWN_HEADER_LEN;
case UCON64_CRC:
if (!value)
value = ucon64.rominfo ? ucon64.rominfo->buheader_len : ucon64.buheader_len;
fputs (basename2 (ucon64.rom), stdout);
if (ucon64.fname_arch[0])
printf (" (%s)\n", basename2 (ucon64.fname_arch));
else
fputc ('\n', stdout);
checksum = 0;
ucon64_chksum (NULL, NULL, &checksum, ucon64.rom, value);
printf ("Checksum (CRC32): 0x%08x\n\n", checksum);
break;
case UCON64_SHA1:
if (!value)
value = ucon64.rominfo ? ucon64.rominfo->buheader_len : ucon64.buheader_len;
fputs (basename2 (ucon64.rom), stdout);
if (ucon64.fname_arch[0])
printf (" (%s)\n", basename2 (ucon64.fname_arch));
else
fputc ('\n', stdout);
ucon64_chksum (buf, NULL, NULL, ucon64.rom, value);
printf ("Checksum (SHA1): 0x%s\n\n", buf);
break;
case UCON64_MD5:
if (!value)
value = ucon64.rominfo ? ucon64.rominfo->buheader_len : ucon64.buheader_len;
fputs (basename2 (ucon64.rom), stdout);
if (ucon64.fname_arch[0])
printf (" (%s)\n", basename2 (ucon64.fname_arch));
else
fputc ('\n', stdout);
ucon64_chksum (NULL, buf, NULL, ucon64.rom, value);
printf ("Checksum (MD5): 0x%s\n\n", buf);
break;
case UCON64_RL:
strcpy (buf, basename2 (ucon64.rom));
printf ("Renaming \"%s\" to ", buf);
strlwr (buf);
printf ("\"%s\"\n", buf);
ucon64_output_fname (buf, OF_FORCE_BASENAME | OF_FORCE_SUFFIX);
rename2 (ucon64.rom, buf);
strcpy ((char *) ucon64.rom, buf);
break;
case UCON64_RU:
strcpy (buf, basename2 (ucon64.rom));
printf ("Renaming \"%s\" to ", buf);
strupr (buf);
printf ("\"%s\"\n", buf);
ucon64_output_fname (buf, OF_FORCE_BASENAME | OF_FORCE_SUFFIX);
rename2 (ucon64.rom, buf);
strcpy ((char *) ucon64.rom, buf);
break;
case UCON64_HEX:
ucon64_dump (stdout, ucon64.rom,
optarg ? MAX (strtol2 (optarg, NULL), 0) : 0,
ucon64.file_size, DUMPER_HEX);
break;
case UCON64_DUAL:
ucon64_dump (stdout, ucon64.rom,
optarg ? MAX (strtol2 (optarg, NULL), 0) : 0,
ucon64.file_size, DUMPER_DUAL);
break;
case UCON64_CODE:
ucon64_dump (stdout, ucon64.rom,
optarg ? MAX (strtol2 (optarg, NULL), 0) : 0,
ucon64.file_size, DUMPER_CODE);
break;
case UCON64_PRINT:
ucon64_dump (stdout, ucon64.rom,
optarg ? MAX (strtol2 (optarg, NULL), 0) : 0,
ucon64.file_size, DUMPER_PRINT);
break;
case UCON64_C:
ucon64_filefile (optarg, 0, ucon64.rom, 0, FALSE);
break;
case UCON64_CS:
ucon64_filefile (optarg, 0, ucon64.rom, 0, TRUE);
break;
case UCON64_FIND:
ucon64_find (ucon64.rom, value, ucon64.file_size, optarg,
strlen (optarg), MEMCMP2_WCARD ('?'));
break;
case UCON64_FINDR:
ucon64_find (ucon64.rom, value, ucon64.file_size, optarg,
strlen (optarg), MEMCMP2_WCARD ('?') | MEMCMP2_REL);
break;
case UCON64_FINDI:
ucon64_find (ucon64.rom, value, ucon64.file_size, optarg, strlen (optarg),
MEMCMP2_WCARD ('?') | MEMCMP2_CASE);
break;
case UCON64_PADHD: // deprecated
value = UNKNOWN_HEADER_LEN;
case UCON64_P:
case UCON64_PAD:
if (!value && ucon64.rominfo)
value = ucon64.rominfo->buheader_len;
ucon64_file_handler (dest_name, src_name, 0);
fcopy (src_name, 0, ucon64.file_size, dest_name, "wb");
if (truncate2 (dest_name, ucon64.file_size + (MBIT - ((ucon64.file_size - value) % MBIT))) == -1)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], dest_name); // msg is not a typo
exit (1);
}
printf (ucon64_msg[WROTE], dest_name);
remove_temp_file ();
break;
case UCON64_PADN:
ucon64_file_handler (dest_name, src_name, 0);
fcopy (src_name, 0, ucon64.file_size, dest_name, "wb");
if (truncate2 (dest_name, strtol (optarg, NULL, 10) +
(ucon64.rominfo ? ucon64.rominfo->buheader_len : 0)) == -1)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], dest_name); // msg is not a typo
exit (1);
}
printf (ucon64_msg[WROTE], dest_name);
remove_temp_file ();
break;
case UCON64_ISPAD:
if ((padded = ucon64_testpad (ucon64.rom)) != -1)
{
if (!padded)
puts ("Padded: No\n");
else
printf ("Padded: Maybe, %d Bytes (%.4f Mb)\n\n", padded,
(float) padded / MBIT);
}
break;
case UCON64_STRIP:
ucon64_file_handler (dest_name, src_name, 0);
fcopy (src_name, 0, ucon64.file_size - strtol (optarg, NULL, 10),
dest_name, "wb");
printf (ucon64_msg[WROTE], dest_name);
remove_temp_file ();
break;
case UCON64_STP:
ucon64_file_handler (dest_name, src_name, 0);
fcopy (src_name, 512, ucon64.file_size, dest_name, "wb");
printf (ucon64_msg[WROTE], dest_name);
remove_temp_file ();
break;
case UCON64_STPN:
ucon64_file_handler (dest_name, src_name, 0);
fcopy (src_name, strtol (optarg, NULL, 10), ucon64.file_size, dest_name, "wb");
printf (ucon64_msg[WROTE], dest_name);
remove_temp_file ();
break;
case UCON64_INS:
ucon64_file_handler (dest_name, src_name, 0);
memset (buf, 0, 512);
ucon64_fwrite (buf, 0, 512, dest_name, "wb");
fcopy (src_name, 0, ucon64.file_size, dest_name, "ab");
printf (ucon64_msg[WROTE], dest_name);
remove_temp_file ();
break;
case UCON64_INSN:
ucon64_file_handler (dest_name, src_name, 0);
value = strtol (optarg, NULL, 10);
if (value <= MAXBUFSIZE)
{
memset (buf, 0, value);
ucon64_fwrite (buf, 0, value, dest_name, "wb");
}
else
{
int bytesleft = value, bytestowrite;
memset (buf, 0, MAXBUFSIZE);
while (bytesleft > 0)
{
bytestowrite = bytesleft <= MAXBUFSIZE ? bytesleft : MAXBUFSIZE;
ucon64_fwrite (buf, 0, bytestowrite, dest_name,
bytesleft == value ? "wb" : "ab"); // we have to use "wb" for
bytesleft -= bytestowrite; // the first iteration
}
}
fcopy (src_name, 0, ucon64.file_size, dest_name, "ab");
printf (ucon64_msg[WROTE], dest_name);
remove_temp_file ();
break;
case UCON64_A:
aps_apply (ucon64.rom, ucon64.file);
break;
case UCON64_B:
bsl_apply (ucon64.rom, ucon64.file);
break;
case UCON64_I:
ips_apply (ucon64.rom, ucon64.file);
break;
case UCON64_PPF:
ppf_apply (ucon64.rom, ucon64.file);
break;
case UCON64_MKA:
aps_create (optarg, ucon64.rom); // original, modified
break;
case UCON64_MKI:
ips_create (optarg, ucon64.rom); // original, modified
break;
case UCON64_MKPPF:
ppf_create (optarg, ucon64.rom); // original, modified
break;
case UCON64_NA:
aps_set_desc (ucon64.rom, optarg);
break;
case UCON64_NPPF:
ppf_set_desc (ucon64.rom, optarg);
break;
case UCON64_IDPPF:
ppf_set_fid (ucon64.rom, optarg);
break;
case UCON64_SCAN:
case UCON64_LSD:
if (ucon64.dat_enabled)
{
if (ucon64.crc32)
{
fputs (basename2 (ucon64.rom), stdout);
if (ucon64.fname_arch[0])
printf (" (%s)\n", basename2 (ucon64.fname_arch));
else
fputc ('\n', stdout);
// Use ucon64.fcrc32 for SNES & Genesis interleaved/N64 non-interleaved
printf ("Checksum (CRC32): 0x%08x\n", ucon64.fcrc32 ?
ucon64.fcrc32 : ucon64.crc32);
ucon64_dat_nfo ((st_ucon64_dat_t *) ucon64.dat, 1);
fputc ('\n', stdout);
}
}
else
printf (ucon64_msg[DAT_NOT_ENABLED]);
break;
case UCON64_LSV:
if (ucon64.rominfo)
ucon64_nfo ();
break;
case UCON64_LS:
if (ucon64.rominfo)
ptr = ucon64.rominfo->name;
if (ucon64.dat)
{
if (!ptr)
ptr = ((st_ucon64_dat_t *) ucon64.dat)->name;
else if (!ptr[0])
ptr = ((st_ucon64_dat_t *) ucon64.dat)->name;
}
if (ptr)
if (ptr[0])
{
if (stat (ucon64.rom, &fstate) != 0)
break;
strftime (buf, 13, "%b %d %Y", localtime (&fstate.st_mtime));
printf ("%-31.31s %10d %s %s", to_func (ptr, strlen (ptr), toprint),
ucon64.file_size, buf, basename2 (ucon64.rom));
if (ucon64.fname_arch[0])
printf (" (%s)\n", basename2 (ucon64.fname_arch));
else
fputc ('\n', stdout);
}
break;
case UCON64_RENAME:
ucon64_rename (UCON64_RENAME);
break;
case UCON64_RR83:
ucon64.fname_len = UCON64_RR83;
case UCON64_RROM:
ucon64_rename (UCON64_RROM);
break;
#ifdef USE_DISCMAGE
case UCON64_BIN2ISO:
case UCON64_ISOFIX:
case UCON64_RIP:
case UCON64_CDMAGE:
if (ucon64.discmage_enabled)
{
uint32_t flags = 0;
switch (c)
{
case UCON64_BIN2ISO:
flags |= DM_2048; // DM_2048 read sectors and convert to 2048 Bytes
break;
case UCON64_ISOFIX:
flags |= DM_FIX; // DM_FIX read sectors and fix (if needed/possible)
break;
case UCON64_CDMAGE:
// flags |= DM_CDMAGE;
break;
}
ucon64.image = dm_reopen (ucon64.rom, 0, (dm_image_t *) ucon64.image);
if (ucon64.image)
{
int track = strtol (optarg, NULL, 10);
if (track < 1)
track = 1;
track--; // decrement for dm_rip()
printf ("Writing track: %d\n\n", track + 1);
dm_set_gauge ((void (*)(int, int)) &libdm_gauge);
dm_rip ((dm_image_t *) ucon64.image, track, flags);
fputc ('\n', stdout);
}
}
else
printf (ucon64_msg[NO_LIB], ucon64.discmage_path);
break;
case UCON64_MKTOC:
case UCON64_MKCUE:
case UCON64_MKSHEET:
if (ucon64.discmage_enabled)
{
if (ucon64.image)
{
char buf[FILENAME_MAX];
strcpy (buf, ((dm_image_t *) ucon64.image)->fname);
if (c == UCON64_MKTOC || c == UCON64_MKSHEET)
{
set_suffix (buf, ".toc");
ucon64_file_handler (buf, NULL, 0);
if (!dm_toc_write ((dm_image_t *) ucon64.image))
printf (ucon64_msg[WROTE], basename2 (buf));
else
fputs ("ERROR: Could not generate toc sheet\n", stderr);
}
if (c == UCON64_MKCUE || c == UCON64_MKSHEET)
{
set_suffix (buf, ".cue");
ucon64_file_handler (buf, NULL, 0);
if (!dm_cue_write ((dm_image_t *) ucon64.image))
printf (ucon64_msg[WROTE], basename2 (buf));
else
fputs ("ERROR: Could not generate cue sheet\n", stderr);
}
}
}
else
printf (ucon64_msg[NO_LIB], ucon64.discmage_path);
break;
case UCON64_XCDRW:
if (ucon64.discmage_enabled)
{
// dm_set_gauge ((void *) &libdm_gauge);
if (!access (ucon64.rom, F_OK))
dm_disc_write ((dm_image_t *) ucon64.image);
else
dm_disc_read ((dm_image_t *) ucon64.image);
}
else
printf (ucon64_msg[NO_LIB], ucon64.discmage_path);
break;
#endif // USE_DISCMAGE
case UCON64_DB:
if (ucon64.quiet > -1) // -db + -v == -dbv
{
if (ucon64.dat_enabled)
{
ucon64_dat_view (ucon64.console, 0);
printf ("TIP: %s " OPTION_LONG_S "db " OPTION_LONG_S "nes"
" would show only information about known NES ROMs\n\n",
basename2 (ucon64.argv[0]));
}
else
fputs (ucon64_msg[DAT_NOT_ENABLED], stdout);
break;
}
case UCON64_DBV:
if (ucon64.dat_enabled)
{
ucon64_dat_view (ucon64.console, 1);
printf ("TIP: %s " OPTION_LONG_S "dbv " OPTION_LONG_S "nes"
" would show only information about known NES ROMs\n\n",
basename2 (ucon64.argv[0]));
}
else
fputs (ucon64_msg[DAT_NOT_ENABLED], stdout);
break;
case UCON64_DBS:
if (ucon64.dat_enabled)
{
ucon64.crc32 = 0;
sscanf (optarg, "%x", &ucon64.crc32);
if (!(ucon64.dat = (st_ucon64_dat_t *) ucon64_dat_search (ucon64.crc32, NULL)))
{
printf (ucon64_msg[DAT_NOT_FOUND], ucon64.crc32);
printf ("TIP: Be sure to install the right DAT files in %s\n", ucon64.datdir);
}
else
{
ucon64_dat_nfo ((st_ucon64_dat_t *) ucon64.dat, 1);
printf ("\n"
"TIP: %s " OPTION_LONG_S "dbs" OPTARG_S "0x%08x " OPTION_LONG_S
"nes would search only for a NES ROM\n\n",
basename2 (ucon64.argv[0]), ucon64.crc32);
}
}
else
fputs (ucon64_msg[DAT_NOT_ENABLED], stdout);
break;
case UCON64_MKDAT:
ucon64_create_dat (optarg, ucon64.rom, ucon64.rominfo ? ucon64.rominfo->buheader_len : 0);
break;
case UCON64_MULTI:
switch (ucon64.console)
{
case UCON64_GBA:
gba_multi (strtol (optarg, NULL, 10) * MBIT, NULL);
break;
case UCON64_GEN:
genesis_multi (strtol (optarg, NULL, 10) * MBIT, NULL);
break;
case UCON64_PCE:
pcengine_multi (strtol (optarg, NULL, 10) * MBIT, NULL);
break;
case UCON64_SMS: // Sega Master System *and* Game Gear
sms_multi (strtol (optarg, NULL, 10) * MBIT, NULL);
break;
case UCON64_SNES:
snes_multi (strtol (optarg, NULL, 10) * MBIT, NULL);
break;
default:
return -1;
}
break;
case UCON64_E:
ucon64_e ();
break;
case UCON64_1991:
genesis_1991 (ucon64.rominfo);
break;
case UCON64_B0:
lynx_b0 (ucon64.rominfo, optarg);
break;
case UCON64_B1:
lynx_b1 (ucon64.rominfo, optarg);
break;
case UCON64_BIN:
genesis_bin (ucon64.rominfo);
break;
case UCON64_BIOS:
neogeo_bios (optarg);
break;
case UCON64_BOT:
n64_bot (ucon64.rominfo, optarg);
break;
case UCON64_CHK:
switch (ucon64.console)
{
case UCON64_GB:
gameboy_chk (ucon64.rominfo);
break;
case UCON64_GBA:
gba_chk (ucon64.rominfo);
break;
case UCON64_GEN:
genesis_chk (ucon64.rominfo);
break;
case UCON64_N64:
n64_chk (ucon64.rominfo);
break;
case UCON64_SMS:
sms_chk (ucon64.rominfo);
break;
case UCON64_SNES:
snes_chk (ucon64.rominfo);
break;
case UCON64_SWAN:
swan_chk (ucon64.rominfo);
break;
default:
// The next msg has already been printed
// fputs (ucon64_msg[CONSOLE_ERROR], stderr);
return -1;
}
break;
case UCON64_COL:
snes_col (optarg);
break;
case UCON64_CRP:
gba_crp (ucon64.rominfo, optarg);
break;
case UCON64_DBUH:
snes_buheader_info (ucon64.rominfo);
break;
case UCON64_SWAP:
case UCON64_DINT:
switch (ucon64.console)
{
case UCON64_NES:
nes_dint ();
break;
case UCON64_PCE:
pcengine_swap (ucon64.rominfo);
break;
case UCON64_SNES:
snes_dint (ucon64.rominfo);
break;
default: // Nintendo 64
puts ("Converting file...");
ucon64_file_handler (dest_name, NULL, 0);
fcopy (src_name, 0, ucon64.file_size, dest_name, "wb");
ucon64_fbswap16 (dest_name, 0, ucon64.file_size);
printf (ucon64_msg[WROTE], dest_name);
break;
}
break;
case UCON64_SWAP2:
// --swap2 is currently used only for Nintendo 64
puts ("Converting file...");
ucon64_file_handler (dest_name, NULL, 0);
fcopy (src_name, 0, ucon64.file_size, dest_name, "wb");
ucon64_fwswap32 (dest_name, 0, ucon64.file_size);
printf (ucon64_msg[WROTE], dest_name);
break;
case UCON64_DMIRR:
snes_demirror (ucon64.rominfo);
break;
case UCON64_DNSRT:
snes_densrt (ucon64.rominfo);
break;
case UCON64_F:
switch (ucon64.console)
{
case UCON64_GEN:
genesis_f (ucon64.rominfo);
break;
case UCON64_N64:
n64_f (ucon64.rominfo);
break;
case UCON64_PCE:
pcengine_f (ucon64.rominfo);
break;
case UCON64_SNES:
snes_f (ucon64.rominfo);
break;
default:
// The next msg has already been printed
// fputs (ucon64_msg[CONSOLE_ERROR], stderr);
return -1;
}
break;
case UCON64_FDS:
nes_fds ();
break;
case UCON64_FDSL:
nes_fdsl (ucon64.rominfo, NULL);
break;
case UCON64_FFE:
nes_ffe (ucon64.rominfo);
break;
case UCON64_FIG:
snes_fig (ucon64.rominfo);
break;
case UCON64_FIGS:
snes_figs (ucon64.rominfo);
break;
case UCON64_GBX:
gameboy_gbx (ucon64.rominfo);
break;
case UCON64_GD3:
snes_gd3 (ucon64.rominfo);
break;
case UCON64_GD3S:
snes_gd3s (ucon64.rominfo);
break;
case UCON64_GG:
switch (ucon64.console)
{
case UCON64_GB:
case UCON64_GEN:
case UCON64_NES:
case UCON64_SMS:
case UCON64_SNES:
gg_apply (ucon64.rominfo, optarg);
break;
default:
fputs ("ERROR: Cannot apply Game Genie code for this ROM/console\n", stderr);
// The next msg has already been printed
// fputs (ucon64_msg[CONSOLE_ERROR], stderr);
return -1;
}
break;
case UCON64_GGD:
gg_display (ucon64.rominfo, optarg);
break;
case UCON64_GGE:
gg_display (ucon64.rominfo, optarg);
break;
case UCON64_INES:
nes_ines ();
break;
case UCON64_INESHD:
nes_ineshd (ucon64.rominfo);
break;
#if 0
case UCON64_IP:
break;
#endif
case UCON64_VMS:
break;
case UCON64_PARSE:
dc_parse (optarg);
break;
case UCON64_MKIP:
dc_mkip ();
break;
case UCON64_J:
switch (ucon64.console)
{
case UCON64_GEN:
genesis_j (ucon64.rominfo);
break;
case UCON64_NES:
nes_j (NULL);
break;
case UCON64_SNES:
snes_j (ucon64.rominfo);
break;
default:
// The next msg has already been printed
// fputs (ucon64_msg[CONSOLE_ERROR], stderr);
return -1;
}
break;
case UCON64_K:
snes_k (ucon64.rominfo);
break;
case UCON64_L:
snes_l (ucon64.rominfo);
break;
case UCON64_LNX:
lynx_lnx (ucon64.rominfo);
break;
case UCON64_LOGO:
switch (ucon64.console)
{
case UCON64_GB:
gameboy_logo (ucon64.rominfo);
break;
case UCON64_GBA:
gba_logo (ucon64.rominfo);
break;
default:
// The next msg has already been printed
// fputs (ucon64_msg[CONSOLE_ERROR], stderr);
return -1;
}
break;
case UCON64_LSRAM:
n64_sram (ucon64.rominfo, optarg);
break;
case UCON64_LYX:
lynx_lyx (ucon64.rominfo);
break;
case UCON64_MGD:
switch (ucon64.console)
{
case UCON64_GB:
gameboy_mgd (ucon64.rominfo);
break;
case UCON64_GEN:
genesis_mgd (ucon64.rominfo);
break;
case UCON64_NG:
neogeo_mgd ();
break;
case UCON64_PCE:
pcengine_mgd (ucon64.rominfo);
break;
case UCON64_SMS:
sms_mgd (ucon64.rominfo, UCON64_SMS);
break;
case UCON64_SNES:
snes_mgd (ucon64.rominfo);
break;
default:
// The next msg has already been printed
// fputs (ucon64_msg[CONSOLE_ERROR], stderr);
return -1;
}
break;
case UCON64_MGDGG:
sms_mgd (ucon64.rominfo, UCON64_GAMEGEAR);
break;
case UCON64_MSG:
pcengine_msg (ucon64.rominfo);
break;
case UCON64_N:
// if (strlen (optarg) == 0)
// break;
switch (ucon64.console)
{
case UCON64_GB:
gameboy_n (ucon64.rominfo, optarg);
break;
case UCON64_GBA:
gba_n (ucon64.rominfo, optarg);
break;
case UCON64_GEN:
genesis_n (ucon64.rominfo, optarg);
break;
case UCON64_LYNX:
lynx_n (ucon64.rominfo, optarg);
break;
case UCON64_N64:
n64_n (ucon64.rominfo, optarg);
break;
case UCON64_NES:
nes_n (optarg);
break;
case UCON64_SNES:
snes_n (ucon64.rominfo, optarg);
break;
default:
// The next msg has already been printed
// fputs (ucon64_msg[CONSOLE_ERROR], stderr);
return -1;
}
break;
case UCON64_N2:
// if (strlen (optarg) == 0)
// break;
genesis_n2 (ucon64.rominfo, optarg);
break;
case UCON64_N2GB:
gameboy_n2gb (ucon64.rominfo, optarg);
break;
case UCON64_NROT:
lynx_nrot (ucon64.rominfo);
break;
case UCON64_PASOFAMI:
nes_pasofami ();
break;
case UCON64_PATTERN:
ucon64_pattern (ucon64.rominfo, optarg);
break;
case UCON64_POKE:
ucon64_file_handler (dest_name, src_name, 0);
fcopy (src_name, 0, ucon64.file_size, dest_name, "wb");
sscanf (optarg, "%x:%x", &x, &value);
if (x >= ucon64.file_size)
{
fprintf (stderr, "ERROR: Offset 0x%x is too large\n", x);
remove (dest_name);
break;
}
fputc ('\n', stdout);
buf[0] = ucon64_fgetc (dest_name, x);
dumper (stdout, buf, 1, x, DUMPER_HEX);
ucon64_fputc (dest_name, x, value, "r+b");
buf[0] = value;
dumper (stdout, buf, 1, x, DUMPER_HEX);
fputc ('\n', stdout);
printf (ucon64_msg[WROTE], dest_name);
remove_temp_file ();
break;
case UCON64_ROTL:
lynx_rotl (ucon64.rominfo);
break;
case UCON64_ROTR:
lynx_rotr (ucon64.rominfo);
break;
case UCON64_S:
switch (ucon64.console)
{
case UCON64_GEN:
genesis_s (ucon64.rominfo);
break;
case UCON64_NES:
nes_s ();
break;
case UCON64_NG:
neogeo_s ();
break;
case UCON64_SNES:
snes_s (ucon64.rominfo);
break;
default:
// The next msg has already been printed
// fputs (ucon64_msg[CONSOLE_ERROR], stderr);
return -1;
}
break;
case UCON64_SAM:
neogeo_sam (optarg);
break;
case UCON64_SCR:
dc_scramble ();
break;
case UCON64_SGB:
gameboy_sgb (ucon64.rominfo);
break;
case UCON64_SMC:
snes_smc (ucon64.rominfo);
break;
case UCON64_SMD:
switch (ucon64.console)
{
case UCON64_GEN:
genesis_smd (ucon64.rominfo);
break;
case UCON64_SMS:
sms_smd (ucon64.rominfo);
break;
default:
return -1;
}
break;
case UCON64_SMDS:
switch (ucon64.console)
{
case UCON64_GEN:
genesis_smds ();
break;
case UCON64_SMS:
sms_smds ();
break;
default:
return -1;
}
break;
case UCON64_SRAM:
gba_sram ();
break;
case UCON64_SSC:
gameboy_ssc (ucon64.rominfo);
break;
case UCON64_SWC:
snes_swc (ucon64.rominfo);
break;
case UCON64_SWCS:
snes_swcs (ucon64.rominfo);
break;
case UCON64_UFO:
snes_ufo (ucon64.rominfo);
break;
case UCON64_UFOS:
snes_ufos (ucon64.rominfo);
break;
case UCON64_UNIF:
nes_unif ();
break;
case UCON64_UNSCR:
dc_unscramble ();
break;
case UCON64_USMS:
n64_usms (ucon64.rominfo, optarg);
break;
case UCON64_V64:
n64_v64 (ucon64.rominfo);
break;
#ifdef USE_PARALLEL
/*
It doesn't make sense to continue after executing a (send) backup option
("multizip"). Don't return, but use break instead. ucon64_execute_options()
checks if an option was used that should stop uCON64.
*/
#ifdef USE_LIBCD64
case UCON64_XCD64:
if (access (ucon64.rom, F_OK) != 0)
cd64_read_rom (ucon64.rom, 64);
else
cd64_write_rom (ucon64.rom);
fputc ('\n', stdout);
break;
case UCON64_XCD64C:
if (!access (ucon64.rom, F_OK) && ucon64.backup)
printf ("Wrote backup to: %s\n", mkbak (ucon64.rom, BAK_MOVE));
cd64_read_rom (ucon64.rom, strtol (optarg, NULL, 10));
fputc ('\n', stdout);
break;
case UCON64_XCD64B:
cd64_write_bootemu (ucon64.rom);
fputc ('\n', stdout);
break;
case UCON64_XCD64S:
if (access (ucon64.rom, F_OK) != 0)
cd64_read_sram (ucon64.rom);
else
cd64_write_sram (ucon64.rom);
fputc ('\n', stdout);
break;
case UCON64_XCD64F:
if (access (ucon64.rom, F_OK) != 0)
cd64_read_flashram (ucon64.rom);
else
cd64_write_flashram (ucon64.rom);
fputc ('\n', stdout);
break;
case UCON64_XCD64E:
if (access (ucon64.rom, F_OK) != 0)
cd64_read_eeprom (ucon64.rom);
else
cd64_write_eeprom (ucon64.rom);
fputc ('\n', stdout);
break;
case UCON64_XCD64M:
if (access (ucon64.rom, F_OK) != 0)
cd64_read_mempack (ucon64.rom, strtol (optarg, NULL, 10));
else
cd64_write_mempack (ucon64.rom, strtol (optarg, NULL, 10));
fputc ('\n', stdout);
break;
#endif
case UCON64_XCMC:
if (!access (ucon64.rom, F_OK) && ucon64.backup)
printf ("Wrote backup to: %s\n", mkbak (ucon64.rom, BAK_MOVE));
cmc_read_rom (ucon64.rom, ucon64.parport, ucon64.io_mode); // ucon64.io_mode contains speed value
fputc ('\n', stdout);
break;
case UCON64_XCMCT:
cmc_test (strtol (optarg, NULL, 10), ucon64.parport, ucon64.io_mode);
fputc ('\n', stdout);
break;
case UCON64_XDEX:
if (access (ucon64.rom, F_OK) != 0)
dex_read_block (ucon64.rom, strtol (optarg, NULL, 10), ucon64.parport);
else
dex_write_block (ucon64.rom, strtol (optarg, NULL, 10), ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XDJR:
if (access (ucon64.rom, F_OK) != 0)
doctor64jr_read (ucon64.rom, ucon64.parport);
else
{
if (!ucon64.rominfo->interleaved)
fputs ("ERROR: This ROM doesn't seem to be interleaved but the Doctor V64 Junior only\n"
" supports interleaved ROMs. Convert to a Doctor V64 compatible format\n",
stderr);
else
doctor64jr_write (ucon64.rom, ucon64.parport);
}
fputc ('\n', stdout);
break;
case UCON64_XFAL:
if (access (ucon64.rom, F_OK) != 0)
fal_read_rom (ucon64.rom, ucon64.parport, 32);
else
fal_write_rom (ucon64.rom, ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XFALMULTI:
tmpnam2 (src_name);
ucon64_temp_file = src_name;
register_func (remove_temp_file);
// gba_multi() calls ucon64_file_handler() so the directory part will be
// stripped from src_name. The directory should be used though.
if (!ucon64.output_path[0])
{
dirname2 (src_name, ucon64.output_path);
if (ucon64.output_path[strlen (ucon64.output_path) - 1] != FILE_SEPARATOR)
strcat (ucon64.output_path, FILE_SEPARATOR_S);
}
if (gba_multi (strtol (optarg, NULL, 10) * MBIT, src_name) == 0)
{ // Don't try to start a transfer if there was a problem
fputc ('\n', stdout);
ucon64.file_size = fsizeof (src_name);
fal_write_rom (src_name, ucon64.parport);
}
unregister_func (remove_temp_file);
remove_temp_file ();
fputc ('\n', stdout);
break;
case UCON64_XFALC:
if (!access (ucon64.rom, F_OK) && ucon64.backup)
printf ("Wrote backup to: %s\n", mkbak (ucon64.rom, BAK_MOVE));
fal_read_rom (ucon64.rom, ucon64.parport, strtol (optarg, NULL, 10));
fputc ('\n', stdout);
break;
case UCON64_XFALS:
if (access (ucon64.rom, F_OK) != 0)
fal_read_sram (ucon64.rom, ucon64.parport, UCON64_UNKNOWN);
else
fal_write_sram (ucon64.rom, ucon64.parport, UCON64_UNKNOWN);
fputc ('\n', stdout);
break;
case UCON64_XFALB:
if (access (ucon64.rom, F_OK) != 0)
fal_read_sram (ucon64.rom, ucon64.parport, strtol (optarg, NULL, 10));
else
fal_write_sram (ucon64.rom, ucon64.parport, strtol (optarg, NULL, 10));
fputc ('\n', stdout);
break;
case UCON64_XFIG:
if (access (ucon64.rom, F_OK) != 0) // file does not exist -> dump cartridge
fig_read_rom (ucon64.rom, ucon64.parport);
else
{
if (!ucon64.rominfo->buheader_len)
fputs ("ERROR: This ROM has no header. Convert to a FIG compatible format\n",
stderr);
else if (ucon64.rominfo->interleaved)
fputs ("ERROR: This ROM seems to be interleaved but the FIG doesn't support\n"
" interleaved ROMs. Convert to a FIG compatible format\n",
stderr);
else // file exists -> send it to the copier
fig_write_rom (ucon64.rom, ucon64.parport);
}
fputc ('\n', stdout);
break;
case UCON64_XFIGS:
if (access (ucon64.rom, F_OK) != 0) // file does not exist -> dump SRAM contents
fig_read_sram (ucon64.rom, ucon64.parport);
else // file exists -> restore SRAM
fig_write_sram (ucon64.rom, ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XFIGC:
if (access (ucon64.rom, F_OK) != 0) // file does not exist -> dump cart SRAM contents
fig_read_cart_sram (ucon64.rom, ucon64.parport);
else // file exists -> restore SRAM
fig_write_cart_sram (ucon64.rom, ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XGBX:
if (access (ucon64.rom, F_OK) != 0) // file does not exist -> dump cartridge/flash card
gbx_read_rom (ucon64.rom, ucon64.parport);
else // file exists -> send it to the programmer
gbx_write_rom (ucon64.rom, ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XGBXS:
if (access (ucon64.rom, F_OK) != 0)
gbx_read_sram (ucon64.rom, ucon64.parport, -1);
else
gbx_write_sram (ucon64.rom, ucon64.parport, -1);
fputc ('\n', stdout);
break;
case UCON64_XGBXB:
if (access (ucon64.rom, F_OK) != 0)
gbx_read_sram (ucon64.rom, ucon64.parport, strtol (optarg, NULL, 10));
else
gbx_write_sram (ucon64.rom, ucon64.parport, strtol (optarg, NULL, 10));
fputc ('\n', stdout);
break;
case UCON64_XGD3:
if (access (ucon64.rom, F_OK) != 0) // file does not exist -> dump cartridge
gd3_read_rom (ucon64.rom, ucon64.parport); // dumping is not yet supported
else
{
if (!ucon64.rominfo->buheader_len)
fputs ("ERROR: This ROM has no header. Convert to a Game Doctor compatible format\n",
stderr);
else // file exists -> send it to the copier
gd3_write_rom (ucon64.rom, ucon64.parport, ucon64.rominfo);
}
fputc ('\n', stdout);
break;
case UCON64_XGD3S:
if (access (ucon64.rom, F_OK) != 0) // file does not exist -> dump SRAM contents
gd3_read_sram (ucon64.rom, ucon64.parport); // dumping is not yet supported
else // file exists -> restore SRAM
gd3_write_sram (ucon64.rom, ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XGD3R:
if (access (ucon64.rom, F_OK) != 0)
gd3_read_saver (ucon64.rom, ucon64.parport);
else
gd3_write_saver (ucon64.rom, ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XGD6:
if (access (ucon64.rom, F_OK) != 0)
gd6_read_rom (ucon64.rom, ucon64.parport); // dumping is not yet supported
else
{
if (!ucon64.rominfo->buheader_len)
fputs ("ERROR: This ROM has no header. Convert to a Game Doctor compatible format\n",
stderr);
else
gd6_write_rom (ucon64.rom, ucon64.parport, ucon64.rominfo);
}
fputc ('\n', stdout);
break;
case UCON64_XGD6S:
if (access (ucon64.rom, F_OK) != 0)
gd6_read_sram (ucon64.rom, ucon64.parport);
else
gd6_write_sram (ucon64.rom, ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XGD6R:
if (access (ucon64.rom, F_OK) != 0)
gd6_read_saver (ucon64.rom, ucon64.parport);
else
gd6_write_saver (ucon64.rom, ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XGG:
if (access (ucon64.rom, F_OK) != 0)
smsgg_read_rom (ucon64.rom, ucon64.parport, 32 * MBIT);
else
{
if (ucon64.rominfo->buheader_len)
fputs ("ERROR: This ROM has a header. Remove it with -stp or -mgd\n",
stderr);
else if (ucon64.rominfo->interleaved)
fputs ("ERROR: This ROM seems to be interleaved, but uCON64 doesn't support\n"
" sending interleaved ROMs to the SMS-PRO/GG-PRO. Convert ROM with -mgd\n",
stderr);
else
smsgg_write_rom (ucon64.rom, ucon64.parport);
}
fputc ('\n', stdout);
break;
case UCON64_XGGS:
if (access (ucon64.rom, F_OK) != 0)
smsgg_read_sram (ucon64.rom, ucon64.parport, -1);
else
smsgg_write_sram (ucon64.rom, ucon64.parport, -1);
fputc ('\n', stdout);
break;
case UCON64_XGGB:
if (access (ucon64.rom, F_OK) != 0)
smsgg_read_sram (ucon64.rom, ucon64.parport, strtol (optarg, NULL, 10));
else
smsgg_write_sram (ucon64.rom, ucon64.parport, strtol (optarg, NULL, 10));
fputc ('\n', stdout);
break;
case UCON64_XLIT:
if (!access (ucon64.rom, F_OK) && ucon64.backup)
printf ("Wrote backup to: %s\n", mkbak (ucon64.rom, BAK_MOVE));
lynxit_read_rom (ucon64.rom, ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XMCCL:
if (!access (ucon64.rom, F_OK) && ucon64.backup)
printf ("Wrote backup to: %s\n", mkbak (ucon64.rom, BAK_MOVE));
mccl_read (ucon64.rom, ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XMCD:
if (!access (ucon64.rom, F_OK) && ucon64.backup)
printf ("Wrote backup to: %s\n", mkbak (ucon64.rom, BAK_MOVE));
mcd_read_rom (ucon64.rom, ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XMD:
if (access (ucon64.rom, F_OK) != 0) // file does not exist -> dump flash card
md_read_rom (ucon64.rom, ucon64.parport, 64 * MBIT); // reads 32 Mbit if Sharp card
else // file exists -> send it to the MD-PRO
{
if (ucon64.rominfo->buheader_len) // binary with header is possible
fputs ("ERROR: This ROM has a header. Remove it with -stp or -bin\n",
stderr);
else if (genesis_get_file_type () != BIN)
fputs ("ERROR: This ROM is not in binary/BIN/RAW format. uCON64 only supports sending\n"
" binary files to the MD-PRO. Convert ROM with -bin\n",
stderr);
else
md_write_rom (ucon64.rom, ucon64.parport);
}
fputc ('\n', stdout);
break;
case UCON64_XMDS:
if (access (ucon64.rom, F_OK) != 0) // file does not exist -> dump SRAM contents
md_read_sram (ucon64.rom, ucon64.parport, -1);
else // file exists -> restore SRAM
md_write_sram (ucon64.rom, ucon64.parport, -1);
fputc ('\n', stdout);
break;
case UCON64_XMDB:
if (access (ucon64.rom, F_OK) != 0)
md_read_sram (ucon64.rom, ucon64.parport, strtol (optarg, NULL, 10));
else
md_write_sram (ucon64.rom, ucon64.parport, strtol (optarg, NULL, 10));
fputc ('\n', stdout);
break;
case UCON64_XMSG:
if (access (ucon64.rom, F_OK) != 0)
msg_read_rom (ucon64.rom, ucon64.parport);
else
{
if (!ucon64.rominfo->buheader_len)
fputs ("ERROR: This ROM has no header. Convert to an MSG compatible format\n",
stderr);
else if (ucon64.rominfo->interleaved)
fputs ("ERROR: This ROM seems to be bit-swapped but the MSG doesn't support\n"
" bit-swapped ROMs. Convert to an MSG compatible format\n",
stderr);
else
msg_write_rom (ucon64.rom, ucon64.parport);
}
fputc ('\n', stdout);
break;
case UCON64_XPCE:
if (access (ucon64.rom, F_OK) != 0)
pce_read_rom (ucon64.rom, ucon64.parport, 32 * MBIT);
else
pce_write_rom (ucon64.rom, ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XPL:
if (access (ucon64.rom, F_OK) != 0)
pl_read_rom (ucon64.rom, ucon64.parport);
else
pl_write_rom (ucon64.rom, ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XPLI:
pl_info (ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XSF:
if (access (ucon64.rom, F_OK) != 0) // file does not exist -> dump flash card
sf_read_rom (ucon64.rom, ucon64.parport, 64 * MBIT);
else // file exists -> send it to the Super Flash
sf_write_rom (ucon64.rom, ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XSFS:
if (access (ucon64.rom, F_OK) != 0) // file does not exist -> dump SRAM contents
sf_read_sram (ucon64.rom, ucon64.parport);
else // file exists -> restore SRAM
sf_write_sram (ucon64.rom, ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XSMC: // we don't use WF_NO_ROM => no need to check for file
if (!ucon64.rominfo->buheader_len)
fputs ("ERROR: This ROM has no header. Convert to an SMC compatible format with -ffe\n",
stderr);
else
smc_write_rom (ucon64.rom, ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XSMCR:
if (access (ucon64.rom, F_OK) != 0)
smc_read_rts (ucon64.rom, ucon64.parport);
else
smc_write_rts (ucon64.rom, ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XSMD:
if (access (ucon64.rom, F_OK) != 0) // file does not exist -> dump cartridge
smd_read_rom (ucon64.rom, ucon64.parport);
else // file exists -> send it to the copier
{
if (!ucon64.rominfo->buheader_len)
fputs ("ERROR: This ROM has no header. Convert to an SMD compatible format\n",
stderr);
else if (!ucon64.rominfo->interleaved)
fputs ("ERROR: This ROM doesn't seem to be interleaved but the SMD only supports\n"
" interleaved ROMs. Convert to an SMD compatible format\n",
stderr);
else
smd_write_rom (ucon64.rom, ucon64.parport);
}
fputc ('\n', stdout);
break;
case UCON64_XSMDS:
if (access (ucon64.rom, F_OK) != 0) // file does not exist -> dump SRAM contents
smd_read_sram (ucon64.rom, ucon64.parport);
else // file exists -> restore SRAM
smd_write_sram (ucon64.rom, ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XSNESRAM:
if (!ucon64.rominfo->buheader_len)
fputs ("ERROR: This ROM has no header. Convert to an SMC compatible format with -ffe\n",
stderr);
else
quickdev16_write_rom (ucon64.rom);
fputc ('\n', stdout);
break;
case UCON64_XSWC:
enableRTS = 0; // falling through
case UCON64_XSWC2:
if (access (ucon64.rom, F_OK) != 0) // file does not exist -> dump cartridge
swc_read_rom (ucon64.rom, ucon64.parport, ucon64.io_mode);
else
{
if (!ucon64.rominfo->buheader_len)
fputs ("ERROR: This ROM has no header. Convert to an SWC compatible format\n",
stderr);
else if (ucon64.rominfo->interleaved)
fputs ("ERROR: This ROM seems to be interleaved but the SWC doesn't support\n"
" interleaved ROMs. Convert to an SWC compatible format\n",
stderr);
else
{
if (enableRTS != 0)
enableRTS = 1;
// file exists -> send it to the copier
swc_write_rom (ucon64.rom, ucon64.parport, enableRTS);
}
}
fputc ('\n', stdout);
break;
case UCON64_XSWCS:
if (access (ucon64.rom, F_OK) != 0) // file does not exist -> dump SRAM contents
swc_read_sram (ucon64.rom, ucon64.parport);
else // file exists -> restore SRAM
swc_write_sram (ucon64.rom, ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XSWCC:
if (access (ucon64.rom, F_OK) != 0) // file does not exist -> dump SRAM contents
swc_read_cart_sram (ucon64.rom, ucon64.parport, ucon64.io_mode);
else // file exists -> restore SRAM
swc_write_cart_sram (ucon64.rom, ucon64.parport, ucon64.io_mode);
fputc ('\n', stdout);
break;
case UCON64_XSWCR:
if (access (ucon64.rom, F_OK) != 0)
swc_read_rts (ucon64.rom, ucon64.parport);
else
swc_write_rts (ucon64.rom, ucon64.parport);
fputc ('\n', stdout);
break;
case UCON64_XV64:
if (access (ucon64.rom, F_OK) != 0)
doctor64_read (ucon64.rom, ucon64.parport);
else
{
if (!ucon64.rominfo->interleaved)
fputs ("ERROR: This ROM doesn't seem to be interleaved but the Doctor V64 only\n"
" supports interleaved ROMs. Convert to a Doctor V64 compatible format\n",
stderr);
else
doctor64_write (ucon64.rom, ucon64.rominfo->buheader_len,
ucon64.file_size, ucon64.parport);
}
fputc ('\n', stdout);
break;
#endif // USE_PARALLEL
#if defined USE_PARALLEL || defined USE_USB
case UCON64_XF2A:
if (access (ucon64.rom, F_OK) != 0)
f2a_read_rom (ucon64.rom, 32);
else
f2a_write_rom (ucon64.rom, UCON64_UNKNOWN);
fputc ('\n', stdout);
break;
case UCON64_XF2AMULTI:
f2a_write_rom (NULL, strtol (optarg, NULL, 10) * MBIT);
fputc ('\n', stdout);
break;
case UCON64_XF2AC:
if (!access (ucon64.rom, F_OK) && ucon64.backup)
printf ("Wrote backup to: %s\n", mkbak (ucon64.rom, BAK_MOVE));
f2a_read_rom (ucon64.rom, strtol (optarg, NULL, 10));
fputc ('\n', stdout);
break;
case UCON64_XF2AS:
if (access (ucon64.rom, F_OK) != 0)
f2a_read_sram (ucon64.rom, UCON64_UNKNOWN);
else
f2a_write_sram (ucon64.rom, UCON64_UNKNOWN);
fputc ('\n', stdout);
break;
case UCON64_XF2AB:
if (access (ucon64.rom, F_OK) != 0)
f2a_read_sram (ucon64.rom, strtol (optarg, NULL, 10));
else
f2a_write_sram (ucon64.rom, strtol (optarg, NULL, 10));
fputc ('\n', stdout);
break;
#endif // USE_PARALLEL || USE_USB
case UCON64_Z64:
n64_z64 (ucon64.rominfo);
break;
default:
break;
}
return 0;
}