add org ucon64 to prepare patch

This commit is contained in:
optixx 2009-09-16 08:41:12 +02:00
parent dc67d91c4f
commit 99cee555c1
252 changed files with 91849 additions and 0 deletions

View File

@ -0,0 +1,11 @@
.:_______________________/\ucon64.sf.net
__/ _____/ __ /_/ / /__ \ /____ ___/\
_/_/ / / /__/ \ / / \ / / / /\_\/
\ \_____/______/______/__/___/_____/__/ / .
\/_____\______\______\__\___\_____\__\/ .
. :
: uCON64 2.0.0 |
| |
|Back To Wipe Away All Bullshit/Proprietary|
|Console Tools w/o Sources, Style And Love!|
`-------[UNIX/Windows/DOS/BeOS/Amiga/Mac]--'

View File

@ -0,0 +1 @@
2.0.0

View File

@ -0,0 +1,783 @@
<html><head>
<link rel="icon" href="images/icon.png" type="image/png">
<title>uCON64 - Changes</title></head><body bgcolor="#ffffff"><tt><br>
The original uCON for SNES and Genesis was written by Chicken &amp; chp in
1993-1995<br>
<br>
<p>
<a name="190">1.9.0</a><br>
- completely re-written<br>
- this is the first real version with support for the most consoles<br>
<p>
<a name="191">1.9.1</a><br>
- bug fixes<br>
- fixed the -xv64 routine for receive and emulation on N64<br>
- cosmetical changes<br>
- removed the stupid curses GUI<br>
- optimized noisette.h for speed<br>
- added more OPTIONS and CONSOLE SYSTEMS<br>
<p>
<a name="192">1.9.2</a><br>
- started to add missing Sega System16(A/B)/System 18/dual 68000 support<br>
- -xv64 shows now the filename on the Doctor instead of "UCON64" (sorry)<br>
- removed -xmp3 option for SongBoy (latest information says that it will
be a USB device with copyprotected MPE standard instead of MP3.. HAHAHAHA!!!)<br>
- TODO: -xmp3 send MP3 file(s) to SongBoy (MP3 player for Game Boy)<br>
- removed options which were added by mistake (like parallel transfer for Z64)<br>
- added -ispad (looks for repeating bytes at the end of a probably padded ROM)<br>
- added -rn (some people might find it useful)<br>
- added -mg, -bin and 'show ROM' support for PC-Engine<br>
- added -usms for Jos Kwanten's ultraSMS an Sega Master System/Game Gear
emulator for the Nintendo64<br>
- fixed aps (GRRNNNNN!!!)<br>
- added an universal frontend (in Java) for all platforms and all programs that
need a filename<br>
- added CD32, CD-i and Real 3DO support<br>
- added -bin and -ffe option for Sega Master System/Game Gear<br>
- added database for NES roms (that enlarged the ucon64 executable by 190kb
grnnn...) "You gotta do what you gotta do." (Futurama)<br>
- added -db and -dbv database commands... now everyone can check if the
uCON64 version he uses has new database entries for a console system<br>
<p>
<a name="193">1.9.3</a><br>
- added -mka create APS patch support<br>
- added -na change APS description<br>
- added -hd, -nhd switches for SMS/Game Gear<br>
- added auto-detection and some information for Jaguar ROMs<br>
- added -ssc convert to Super Smart Card (Game Boy)<br>
- fixed/added -chk fix checksum (Game Boy)<br>
- added -gg Game Genie support for SNES<br>
- cleaned up the usage output<br>
- added -chk fix checksum for Super NES/Super Famicom<br>
- removed most CDROM based consoles from usage since uCON64 could support
them only by showing some informations about the CDROM itself (option -cdrom)<br>
- added -gd3 convert to Professor SF(2) Game Doctor SF3/6/7 (autojoin)<br>
- added -gdf fix Professor SF(2) Game Doctor SF3/6/7 savegame problems<br>
<p>
<a name="194">1.9.4</a><br>
- included all databases for every console system that has ROMs without a
header with text<br>
- added 324 entries to SMS database<br>
- added -sam convert SAM/M.A.M.E. sound to WAV; --rom=SAMFILE<br>
- added -b2i convert BIN/RAW(2352)/Mode2(2336) to ISO; --rom=BIN_IMAGE<br>
- added -ppf apply PPF patch (&#60;=2.0); --rom=ISO_IMAGE --file=PATCHFILE<br>
- added -nppf change PPF description; --rom=PATCHFILE --file=DESCRIPTION<br>
- added -mkppf create PPF patch; --rom=ISO_IMAGE --file=CHANGED_IMAGE<br>
- added -ip extract ip0000.bin (GD-ROM header/256 bytes); --rom=/dev/&#60;cdrom&#62;<br>
- added -fds convert Famicom Disk System file (diskimage) from FAM to FDS<br>
- changed the FAQ a bit<br>
- overworked the whole tool to make it easier to develop<br>
- searched a new site for it (<a href="http://ucon64.sourceforge.net" target="_blank">http://ucon64.sourceforge.net</a>)<br>
<p>
<a name="195">1.9.5</a><br>
- after the update release of 1.9.4 I had a closer look at my sources
and realized that my style heavily changed since 1.9.3 the result is
that I had to make more changes in the source starting from ucon64.c<br>
- Gilligan wrote a nice routine to read out NeoGeo Pocket roms (added)<br>
- reorganized the whole source<br>
- added Game Boy Advance support<br>
- added (GBA) -n change ROM name; --file=NEWNAME<br>
- added (GBA) -logo restore ROM logo character data 0x04-0x9F<br>
- added (GBA) -chk fix ROM checksum<br>
- added (GB/Game Gear/NES) -gg apply Game Genie code (permanent)<br>
- added (GB/Game Gear/NES/GEN/SNES) -gge encode Game Genie code<br>
- added (GB/Game Gear/NES/GEN/SNES) -ggd decode Game Genie code<br>
- added (LYNX) -lyx convert to LYX/RAW (strip 64 Bytes LNX header)<br>
- added (LYNX) -lnx convert to LNX (uses default values for the header)<br>
- added (LYNX) -n change ROM name (LNX only); --file=NEWNAME<br>
- added (LYNX) -nrot set no rotation (LNX only)<br>
- added (LYNX) -rotl set rotation left (LNX only)<br>
- added (LYNX) -rotr set rotation right (LNX only)<br>
- added (LYNX) -b0 change Bank0 kBytes size (LNX only); --file={0,64,128,256,512}<br>
- added (LYNX) -b1 change Bank1 kBytes size (LNX only); --file={0,64,128,256,512}<br>
- added -idppf change PPF FILE_ID.DIZ (2.0); --rom=PATCHFILE --file=FILE_ID.DIZ<br>
- added -strip strip Bytes from end of ROM; --file=VALUE<br>
- added -e emulate/run ROM (check INSTALL and $HOME/.ucon64rc for more)<br>
- added (GBA) -sram patch ROM for SRAM saving<br>
- added (GBA) -crp slow down Flash Advance Linker access for ROM (crash patch)<br>
- added (GBA) -strip strip Bytes from end of ROM (use -ispad before); --file=VALUE<br>
- added (GBA) -xfal send/receive to/from Flash Advance Linker; --file=PORT<br>
<p>
<a name="196">1.9.6</a><br>
- this release brings you full support for the Super Wild Card<br>
- added (SNES) -xswc send/receive to/from Super Wild Card*/(all)SWC; --file=PORT
(by dbjh)<br>
- added (SNES) -xswcs send/receive SRAM to/from Super Wild Card*/(all)SWC;
--file=PORT (by dbjh)<br>
- added (GB) -sgb convert from GB Xchanger/GB/GBC to Super Backup Card/GX/GBX
(by NoisyB)<br>
- added (GB) -gbx convert from Super Backup Card/GX/GBX to GB Xchanger/GB/GBC
(by NoisyB)<br>
- made a few small bug fixes and code cleanups (by NoisyB; thanks to dbjh)<br>
- DOS port of uCON64 available (by dbjh)<br>
- BeOS port of uCON64 available (by dbjh)<br>
- added wildcard support to -find find string in ROM (by NoisyB)<br>
- added (SNES) some new NTSC/PAL and SlowROM fix codes (by NoisyB)<br>
- added (SNES) -swcs convert emulator *.srm to Super Wild Card*/(all)SWC (by
NoisyB)<br>
<p>
<a name="197">1.9.7</a><br>
- added (NES) -fdsl list Famicom Disk System/FDS (diskimage) contents (by
NoisyB)<br>
- updated (GBA) -xfal send/receive ROM to/from Flash Advance Linker; --file=PORT
(by dbjh)<br>
- added (GBA) -xfalc&#60;n&#62; specify chip size in Mbits of ROM in Flash
Advance Linker when receiving (by dbjh)<br>
- added (GBA) -xfalm use SPP mode, default is EPP (by dbjh)<br>
- added (Neo Geo) -bios convert NeoCD Bios to work with NeoCD emulator (by
NoisyB; thanks to Caz)<br>
- changed the whole internal ROM database code (by NoisyB)<br>
- added -dbs search ROM database (all entries) by CRC32; --rom=0xCRC32 (by
NoisyB)<br>
- added (Virtual Boy) show info (by NoisyB)<br>
- added (WonderSwan) show info (by NoisyB)<br>
- added (ColecoVision) show info (by NoisyB)<br>
- added (Vectrex) show info (by NoisyB)<br>
- added ROMs to database for Virtual Boy, WonderSwan, ColecoVision and Vectrex
(by NoisyB)<br>
- added (Intellivision) show info (by NoisyB)<br>
- made the internal ROM Database optional; compiled without DB uCON64 will be
only ~250kB in size! (by NoisyB)<br>
- updated (all) fixed -cs (file compare) (by dbjh)<br>
- updated (SNES) fixed dumping of `special' SNES cartridges (for the meaning of
special, see src/backup/swc.c) (by dbjh; thanks to Caz)<br>
- updated (SNES) fixed -k (crack) (by dbjh)<br>
- updated (SNES) fixed -f (NTSC/PAL fix) (by dbjh)<br>
- uCON64 will recognize *ANY* kind of ROM or Console System via DB now...<br>
give it a Atari2600 ROM and it will just recognize it :) (by NoisyB)<br>
- updated the internal DB; it can recognize 12387 different ROMs (by NoisyB)<br>
- updated (SNES) fixed -s (split ROM) (by dbjh)<br>
- updated (Genesis) fixed -s (by NoisyB)<br>
- updated (all) fixed -swc &amp; -ins (and others) for files with a size a
multiple of 32kB (by dbjh)<br>
- updated (SNES) fixed -swc when ROM file has a name that already has the
extension .swc fixed the same problem for -smc and -fig (by dbjh)<br>
- added -lsv like -ls but more verbose; --rom=DIRECTORY (by NoisyB)<br>
- updated (SNES) fixed checksum output (by NoisyB)<br>
- updated (SNES) fixed -j (join multi files) (by dbjh)<br>
- updated (SNES) fixed checksum output for Broadcast Satellaview ROMs (by dbjh;
thanks to Cowering)<br>
- added (SNES) -figs convert emulator *.srm (SRAM) to *Pro Fighter*/(all)FIG (by
dbjh; thanks to Caz)<br>
- added (SNES) -ufos convert emulator *.srm (SRAM) to Super UFO (by dbjh; thanks
to Caz)<br>
- added (SNES) -int, -int2 &amp; -nint force ROM is (not) in interleaved format
(2) (by dbjh)<br>
- added (SNES) -dint convert ROM to non-interleaved format (by dbjh)<br>
- added 2830 new ROMs to internal ROM database (by NoisyB)<br>
- added (Genesis) -xsmd send/receive ROM to/from Super Magic Drive/SMD;
--file=PORT (by NoisyB)<br>
- added (Genesis) -xsmds send/receive SRAM to/from Super Magic Drive/SMD;
--file=PORT (by NoisyB)<br>
- added support for CD based consoles again; uCON64 now uses cdrdao as burn
engine (by NoisyB)<br>
- added Dreamcast, PSX (one), PS2, Real3DO, CD-i, CD32 and Saturn support (by
NoisyB)<br>
- added (Genesis) -smds convert emulator (*.srm) SRAM to Super Magic Drive/SMD
(by NoisyB)<br>
- added -r2i convert RAW to ISO9660; --rom=RAW_IMAGE (by NoisyB)<br>
<p>
<a name="198-1">1.9.8-1</a><br>
- added more verbose WonderSwan ROM info (by NoisyB; thanks to dox)<br>
- updated (GBA) used Jeff Frohwein's Flash Advance Linker code V1.72 (by dbjh)<br>
- added (GBA) -xfals send/receive SRAM to/from Flash Advance Linker; --file=PORT
(by dbjh)<br>
- added (GBA) -xfalb&#60;n&#62; send/receive SRAM to/from Flash Advance Linker
bank n; --file=PORT (by dbjh)<br>
- removed (GBA) -xfalm (use SPP mode), because it is not needed anymore (by
dbjh)<br>
- updated (SNES) fixed checksum function for Far East of Eden Zero (J) (by dbjh)<br>
- added (GBA) -multi{1,2,3} make multirom for Flash Advance Linker (by dbjh)<br>
- updated/added (SNES) Game Doctor ROM file support (-gd3 &amp; -s) (by John
Weidman)<br>
- updated (all) fixed DOS specific bug in IPS code (by dbjh)<br>
- updated (SNES) fixed DOS specific problem for -swc, -fig and -smc (by dbjh)<br>
- updated (all) fixed DOS specific bug in -ins code (by dbjh)<br>
- introducing config file updates without overwrites of old values for more
comfort (by NoisyB)<br>
- added (WS/WSC) -chk fix ROM checksum (for WonderSwan(Color)) (by NoisyB;
thanks to dox)<br>
- updated (SNES) changed -swcs, -figs and -ufos to always create a file of 32.5
kB. This solves some problems where SRAM files created with an emulator would
not work on a copier (by dbjh; thanks to Caz for investigating the problem and
providing a solution)<br>
- added -mkcue generate CUE file; --rom=CD_IMAGE --file=TRACK_MODE (by NoisyB)<br>
- ported the whole project to FreeBSD (by NoisyB)<br>
<!-- beta2 -->
- updated (GBA) changed -xfalb&#60;n&#62; to -xfalb &#60;n&#62; (space between
option and argument) (by dbjh). Did the same thing for -xfalc&#60;n&#62;<br>
- updated (GB) changed -xgbxb&#60;n&#62; to -xgbxb &#60;n&#62; (space between
option and argument) (by dbjh)<br>
- switched internal workflow to getopt() and made numerous cosmetical
changes/clean ups (by NoisyB)<br>
- added -hdn=BYTES force ROM has backup unit/emulator header with BYTES size (by
NoisyB)<br>
detects the correct TRACK_MODE of IMAGES w/o *.cue file<br>
- added --rrom rename all ROMs in DIR to their internal names; --rom=DIR (by
NoisyB)<br>
- added --rr83 like --rrom but with 8.3 filenames; --rom=DIR (by NoisyB)<br>
- added --stpn=N strip N Bytes from ROM beginning (by NoisyB)<br>
- added --insn=N insert N Bytes (0x00) before ROM (by NoisyB)<br>
- added --xmccl send/receive BYTES to/from Mad Catz Camera Link (experimental)
(by NoisyB)<br>
- speed --rrom, --rr83 and --ls have been sped up significantly<br>
- updated (N64) added 512 Mb ROM support for transfers to Doctor V64 Junior
(by NoisyB; thanks to TenOfTen (tenoften@jahej.com))<br>
- updated (SNES) fixed -fig to give the same output as a Super Pro Fighter (by
dbjh; thanks to JohnDie for the information)<br>
- updated (all) parallel port is only accessed for copier I/O (by dbjh)<br>
- added (SNES) -bs &amp; -nbs force ROM is a Broadcast Satellaview dump/regular
cartridge dump (by dbjh)<br>
- added (NES) -unif convert to UNIF format/UNF {iNES, UNIF}->UNIF (by dbjh)<br>
- updated (NES) -ines convert to iNES format {iNES, UNIF, Pasofami}->iNES (by
dbjh)<br>
- added (NES) -dint convert ROM to non-interleaved format (by dbjh)<br>
- added (NES) -pasofami convert to Pasofami format iNES->Pasofami (by dbjh)<br>
- updated (NES) ROM information for iNES, UNIF, FFE and Pasofami (by dbjh)<br>
- updated (NES) fixed -j so that it converts properly from Pasofami to iNES (by
dbjh)<br>
- updated (NES) fixed -s so that it converts properly from iNES to Pasofami (by
dbjh)<br>
- updated (NES) fixed -ineshd (extract iNES header to .hdr file) (by dbjh)<br>
- added (NES) -ctrl set controller type for ROM (UNIF only) (by dbjh)<br>
- added (NES) -ntsc set TV compatibility to NTSC (UNIF only) (by dbjh)<br>
- added (NES) -pal set TV compatibility to PAL (UNIF only) (by dbjh)<br>
- added (NES) -bat set battery backup (by dbjh)<br>
- added (NES) -nbat set no battery backup (by dbjh)<br>
- added (NES) -vram set VRAM override (UNIF only) (by dbjh)<br>
- added (NES) -nvram set no VRAM override (UNIF only) (by dbjh)<br>
- added (NES) -mirr set mirroring type (by dbjh)<br>
- added (NES) -n change internal ROM name (UNIF only) (by dbjh)<br>
- added (NES) -mapr=NAME specify board name or mapper number for conversion
options (by dbjh)<br>
- added (NES) -dumpinfo use dumper info when converting to UNIF (by dbjh)<br>
<!-- beta3 -->
- updated (NES) UNIF code works also on big endian machines (by dbjh)<br>
- updated (GBA) changed meaning of -xfalc. In order to dump N megabits of a
cartridge specifying -xfalc=N &#60;filename&#62; is enough (by dbjh)<br>
- updated (NES) fixed some minor format conversion problems (by dbjh)<br>
- updated (LYNX) fixed some problems with endianess (by dbjh)<br>
- added (LYNX) --lynxit send/receive ROM to/from Lynxit interface (by NoisyB)<br>
- updated (SNES) fixed checksum function for Momotaro Dentetsu Happy (J) (by
dbjh)<br>
- updated (SNES) fixed SNES info for Dai Kaiju Monogatari 2 (J) (by dbjh)<br>
- updated (SNES) improved SNES chip type info (by dbjh)<br>
- added gzip support (by dbjh)<br>
- updated (Genesis) fixed several bugs (header is correct after -j/-s, correct
behaviour if switch -nbak is active, -smd/-mgd if already in SMD/MGD format,
-lsv) (by dbjh)<br>
- added --padn=N pad ROM to N Bytes (put Bytes with value 0x00 after end) (by
dbjh)<br>
<!-- beta4 -->
- updated (NES) FDS images are recognized without -fdsl (by dbjh)<br>
- added (GBA) -xfalmulti send multiple ROMs to Flash Advance Linker (by dbjh)<br>
- updated (GBA) changed -multi so that it takes a size argument (by dbjh)<br>
- removed (GBA) -multi{1,2,3}, -multi can be used instead (by dbjh)<br>
- some code clean ups (by NoisyB)<br>
- added read-only zip support (by dbjh) Note that only the first file inside the
zip archive will be looked at. Use -ls{v} to see info about all files in the
zip archive<br>
- added (SNES) NSRT header support (by dbjh)<br>
- updated (SNES) fixed an SWC problem for HiROM games without SRAM (by dbjh)<br>
- updated (SNES) -k also cracks Killer Instinct (by dbjh)<br>
- updated (SNES) -smc writes a correct SMC header (by dbjh)<br>
- added (SNES) -ctrl{2} specify type of controller in port 1/2 for emu when
converting (by dbjh)<br>
- updated (Genesis) replaced Charles MacDonald's SMD code with our own (by dbjh)<br>
- added experimental (PSX/N64) --xdex send/receive BLOCK N to/from DexDrive (by
NoisyB)<br>
- added 664 new ROMs to the internal database (by NoisyB)<br>
- updated (SNES) replaced Cowering's BS detection code with John Weidman's (by
dbjh)<br>
<!-- beta5 -->
- updated (all) fixed two bugs in IPS creation code (by dbjh)<br>
- updated (all) -mki generates RLE compressed IPS files (by dbjh)<br>
- updated (SNES) fixed split file detection for SWC and FIG dumps (by dbjh)<br>
- updated (Genesis) fixed -s for RAW images (by dbjh)<br>
- updated (SNES) added crack for Donkey Kong Country, Diddy's Kong Quest &amp;
Mega Man X (by dbjh; many thanks to CL of NSRT)<br>
- updated (SNES) fixed bug in Game Genie code (by dbjh)<br>
- updated (all) fixed subtle bug in function that is used for -k, -f, -l &amp;
-crp (by dbjh)<br>
- updated (SNES) added crack for BS The Legend of Zelda Remix &amp; Demon's
Crest (by dbjh, based on info of John Weidman)<br>
<!-- beta6 -->
- updated (SNES) added crack for at least the following games: Breath of Fire II,
Kirby's Dream Course (many thanks to John Weidman), Lufia II - Rise of the
Sinistrals and Earthbound (thanks to CL) (by dbjh)<br>
- updated (SNES) crack for Mega Man X should work (better) (by dbjh)<br>
- updated (SNES) added NTSC/PAL fix for at least the following games:
Final Fight Guy, Gokujyou Parodius, Kirby No Kira Kizzu, Robotrek and
Seiken Densetsu 3 (by dbjh)<br>
- updated (SNES) added crack for Uniracers/Unirally and NTSC/PAL fix for
Seiken Densetsu 2 and Secret of Mana (by dbjh; thanks to John Weidman)<br>
- updated (all) fixed problem with reading environment variables under DOS and
Windows (by dbjh)<br>
- updated (all) environment variables take precedence over configuration file
variables (by dbjh)<br>
- updated (SNES) fixed some problems with joining GD3 files (by dbjh)<br>
- added (SNES) -xgd3 send ROM to Game Doctor SF3(SF6/SF7); --file=PORT
(by John Weidman and dbjh)<br>
- added (SNES) -dbuh display backup unit header and see if it matches with what
uCON64 found while analyzing the ROM data (by dbjh, based on an idea by
JohnDie)<br>
- removed (SNES) -gdf (fix Game Doctor savegame problems), because -gd3 already
provides this functionality (by dbjh)<br>
- updated (SNES) fixed some -xgd3 problems, uppercase filenames sent to unit,
buffer data correct for all files, transfer file size fixed (by John)<br>
- updated (SNES) checksums and deinterleaves for HiROM 24 Mbit Game Doctor
format should work (by John)<br>
- added (SNES) -xswc2 send ROM to Super Wild Card and enable Real Time Save
mode (by dbjh)<br>
- updated (SNES) added NTSC/PAL fix for Live-a-Live (by dbjh)<br>
- updated (all) added full wildcard support ("ucon64 -fig *.swc"). Don't forget
to read the FAQ (by dbjh)<br>
- added (all) -q be quiet (don't show ROM info) (by dbjh)<br>
- updated (all) uCON64 handles multiple options on the same command line (by
dbjh)<br>
- added (SNES) --ssize=SIZE specify split part size in Mbit (not for Game
Doctor SF3) (by dbjh)<br>
<!-- beta 7 -->
- updated (SNES) added NTSC/PAL fix for Terranigma (by dbjh; thanks to John)<br>
- added (all) full support for all existing DAT files (GoodXXXX, RomCenter)
they'll be used to identify (test) or rename your ROMs or any other purpose
you might need a ROM manager for (by NoisyB)<br>
- updated (SNES) fixed BS ROM detection affecting BS Zootte Mahjong! IVT (by
John)<br>
- added (all) --lsd to list all ROMs using RomCenter or GoodXXXX DAT files (by
NoisyB)<br>
- updated (all) improved support for zip files that contain more than one file
(by dbjh)<br>
- updated (SNES) added NTSC/PAL fix and crack for Mario no Super Picross (by
dbjh; thanks to John)<br>
- renamed (N64) --sram to --lsram (by NoisyB)<br>
- replaced --file with option arguments for the following options: --strip,
--find, -c, --cs, --dbs, -b, -i, --mki, -a, --mka, --na, --ppf, --mkppf,
--nppf, --idppf, --crp, -n, --bot, --lsram, --usms, --n2, --n2gb, --b0, --b1,
--sam, --bios and --dumpinfo (by NoisyB)<br>
- updated (PSX) PPF code works correctly and generates correct patches on
big-endian machines (by dbjh)<br>
- added (patch) --patch option to specify the patch file for APS, IPS, BSL and
PPF (by NoisyB)<br>
- updated (SNES) added NTSC/PAL fix for Dual Orb 2 (thanks to John), Dr. Mario,
Dragon - The Bruce Lee Story (U) and Wolfenstein 3D (U) (by dbjh)<br>
- updated (N64) APS code works correctly and generates correct patches on
big-endian machines (by dbjh)<br>
- added (all) -o specify output directory. Note that now uCON64 by default
writes its output files to the current directory (by NoisyB and dbjh)<br>
- added (all) --poke=OFF:V change byte at file offset OFF to value V (by dbjh)<br>
<!--
- tested (Genesis) -xsmd and -xsmds with my "new" Super Magic Drive and they
worked as we expected (by NoisyB; thanks to dbjh)<br>
Of course we test things... Should be put in a file like testsdone.html ;-) (dbjh)
-->
- updated (SNES) fixed problem where it was necessary to run uCON64 twice on a
ROM with the option -chk, before the checksum was really fixed (by dbjh)<br>
- added (all) --rename (by NoisyB and dbjh)<br>
- added (all) --scan like: GoodXXXX scan ... (by NoisyB)<br>
- added (SNES) uCON64 is able to use an "addendum file" for the options -k
(snescopy.txt), -f (snesntsc.txt or snespal.txt) and -l (snesslow.txt). You
can add new search patterns to those files if the latest binary doesn't
support them yet. See the FAQ for a more elaborate explanation (by dbjh)<br>
- added Visual C++ build support (including libdiscmage) (by dbjh)<br>
- updated (GBA) fixed a bug that would crash FAL code on compressed files (by
dbjh)<br>
- (re)added (GBA) -xfalm (try to enable EPP mode). Note that the meaning is
reversed. Enabling EPP mode only when this switch is specified makes it
possible to use the Windows versions of uCON64 under Windows XP (NT/2000)
(by dbjh)<br>
- added support for the I/O port driver inpout32.dll to the Windows ports. See
the FAQ for more information (by dbjh)<br>
- uCON64 can also be compiled with g++; configure with "CC=g++ ./configure"
(by dbjh)<br>
- updated (SNES) uCON64 uses one maker/publisher list for all SNES games (by
dbjh; thanks to FluBBa for the help)<br>
- updated (GB &amp; GBA) fixed maker info (by dbjh; thanks to FluBBa for the
info)<br>
- updated (SNES, GB &amp; GBA) fixed huge mistake in the way the Nintendo
publisher list was used (resulting in incorrect maker info) (by dbjh)<br>
- updated (SNES) fixed problem with splitting HiROM Game Doctor files smaller
than or equal to 8 Mbit (by dbjh)<br>
- replaced internal handling/conversion of DiscJuggler and Nero images with
included libdiscmage. The recognition of ISO, BIN, CDI and NRG images works
in 80% of the cases. Every other function like ripping/converting is still
flakey and therefore disabled in this beta release (by NoisyB)<br>
<!-- beta 8 -->
- updated (all) fixed problems with -rename &amp; -rrom for files without a
suffix (by dbjh)<br>
- updated (all) links (including symbolic links) are handled correctly for
-rename &amp; -rrom (by dbjh)<br>
- added support for I/O port driver io.dll to the Windows ports. See the FAQ
for more information (by dbjh)<br>
- added (SNES) -xfig send/receive ROM to/from Pro Fighter; --file=PORT (by
JohnDie and dbjh)<br>
- added (SNES) -xfigs send/receive SRAM to/from Pro Fighter; --file=PORT (by
JohnDie and dbjh)<br>
- added (all) --mkdat=DATFILE create DAT file based on a directory/list of ROMs
(by dbjh)<br>
- updated (N64) fixed -usms (by dbjh)<br>
- updated (all) fixed problem with -rename when output directory is on another
file system (M$ speak: drive) (by dbjh)<br>
- added MinGW build support (including libdiscmage) (by dbjh)<br>
- changed name of two property variables: now configdir is named
ucon64_configdir and datdir is named ucon64_datdir (by dbjh)<br>
- updated (SNES) changed checksum calculation function so that it is stricter
(by dbjh; thanks to Nach)<br>
- updated (SNES) added more verbose BS info (by dbjh, based on info of Derrick
Sobodash)<br>
- updated (GB) fixed -n2gb, -gbx &amp; -sgb (by dbjh)<br>
- updated (SNES) replaced -ehi with -erom (force ROM is "Extended") in order to
support the two Extended LoROM dumps in the known universe (by dbjh)<br>
- updated (SNES) added initial support for Sufami Turbo ROMs (by dbjh; thanks
to Nach for some info)<br>
- added support for GameCube images to libdiscmage (by NoisyB; thanks to
gc-nfo.com)<br>
- updated (SNES) improved detection of interleaved ROMs (by dbjh)<br>
- updated (SNES) -smc, -swc, -fig, -mgd &amp; -gd3 (if it's a LoROM dump)
automatically deinterleave the ROM data if the ROM is detected as interleaved
(by dbjh)<br>
- updated (SNES) -gd3 can convert Tales of Phantasia and Dai Kaiju Monogatari 2
(by dbjh)<br>
- updated (SNES) interleaved extended HiROM dumps are handled correctly (by
dbjh)<br>
- updated (SNES) uCON64 follows the "uCONRST standard" for calculating the
"search CRC32" of BS dumps (by dbjh)<br>
- updated (all) both the search CRC32 and the "data CRC32" are displayed if
they differ (by dbjh)<br>
- updated (SNES) applied anomie's GD patch which solved a problem with one-part
split files (by dbjh)<br>
- updated (SNES) replaced John Weidman's BS detection code with Nach's (by
dbjh)<br>
- updated (SNES) uCON64 now recognises a complete GoodSNES 0.999.5 set (by
JohnDie and dbjh)<br>
- added (SNES) -dmirr strip mirrored block from end of ROM (by dbjh)<br>
- added (SNES) support for native Super UFO file format (by John and dbjh) Use
-ufo to convert a file to Super UFO format, use -s to split the resulting
file (required for HiROM games)<br>
- updated (SMS) -mgd is recognised again, -smd won't crash uCON64 anymore and
-smds calls the SMS function when -sms is specified (by dbjh)<br>
- updated (SMS) -sms in no longer required for SMD files, they are
automatically detected (by dbjh)<br>
- updated (SNES) fixed -b (apply Baseline patch) (by dbjh)<br>
- updated (all) added support for non-standard parallel port addresses (by
dbjh)<br>
- updated (SNES) added crack for Tetris Attack (by dbjh; thanks to CL)<br>
<p>
<a name="198-2">1.9.8-2</a><br>
- updated (SNES) -gd3 produces a more logical format for Daikaijuu Monogatari 2
(by dbjh; thanks to Nach for the idea)<br>
- updated (SMS) -smd interleaves SMS files (by dbjh; thanks to nori-p for
testing and feedback)<br>
- updated (GBA) fixed stupid bug introduced in 1.9.8beta8 that caused
-xfalmulti to hang (-multi and -xfal still worked) (by dbjh)<br>
- updated (SNES) hopefully fixed last problem with splitting GD3 files (by
dbjh)<br>
- updated (SNES) added crack for Dixie Kong's Double Trouble (by dbjh, based on
IPS patch by Black Hole of Infernal Affairs)<br>
- files of 0 bytes won't be detected as WonderSwan files anymore (by dbjh)<br>
- removed (NES) support for bad FDS DAT files (by dbjh) If you really want to
use FDS DAT files created by tools that erroneously include the header in the
CRC32 calculation, use the switch -nhd. Someone with a complete FDS
collection should create a new DAT file<br>
- updated (SNES) fixed crashing on first split file of Tales of Phantasia and
Daikaijuu Monogatari 2 (by dbjh)<br>
- added (SNES) -xgd6 send ROM to Game Doctor SF6/SF7. This probably solves the
problems people are having with -xgd3 (by John)<br>
- added (SNES) -xgd6s send/receive SRAM to/from Game Doctor SF6/SF7 (by John)<br>
- added (SNES) -xgd3s send SRAM to Game Doctor SF3/SF6/SF7 (by John)<br>
- added (Genesis) -multi can create a multi-game file for use on the MD-PRO
flash card. The downside: creating a multirom for the FAL doesn't work
without -gba anymore (by dbjh; thanks to Enemy and acem77 for testing)<br>
- added (Genesis) -f can fix region protections, addendum files are genpal.txt
and mdntsc.txt (by dbjh)<br>
- added (SNES) -id force -gd3 to produce a unique file name. This switch
doesn't show in the help, because it "fails" for 130 dumps of the GoodSNES
"0.999.6--" set. 128 IDs are each shared by 2 games, 2 IDs are shared by 3
games (by dbjh)<br>
- updated (all) the patch generation options (-mka, -mki, -mkppf) use the
modified ROM name for the patch to create. They used to use the name of the
original ROM (by dbjh)<br>
- updated (N64) fixed major bug in APS creation code (by dbjh)<br>
- updated (SNES) added NTSC/PAL fix for Magical Pop'n (J) and Metal Warriors
(U) (by dbjh)<br>
- added (Genesis) recognition of <i>real</i> MGD files (by dbjh; thanks to
acem77 for the feedback)<br>
- updated (Genesis) -mgd now produces proper MGD files (by dbjh)<br>
- added (Genesis) -bin convert to binary format. This option produces files in
the format that uCON64 1.9.8-1 produces with the option -mgd (by dbjh)<br>
- added (Genesis) -xmd &amp; -xmds send/receive ROM/SRAM to/from MD-PRO flash
card programmer (by dbjh and NoisyB with many thanks to timofonic and of
course ToToTEK Multi Media for providing us with the necessary information.
Special thanks go to Leo of ToToTEK for being very helpful and willing to
answer our questions)<br>
- added (Genesis) -ssize=SIZE specify split part size in Mbit (by dbjh)<br>
- updated (SNES, SMS, PC-Engine &amp; Genesis) -mgd produces correct file names
(by dbjh; thanks to acem77 for testing and feedback)<br>
- updated (Genesis) -mgd automatically pads files to the right size (by dbjh)<br>
- added (PC-Engine) -swap invert/swap bits of all bytes of a file. This
effectively converts PC-Engine games between Japan and U.S.A. "mode" (by
dbjh; thanks to acem77 for the information)<br>
- added (SMS) backup unit header length detection (by dbjh; thanks to acem77
for pointing this out) This made a problem with the current SMS DAT file
surface: some CRC32 values are the result of including a backup unit header
in the calculation. Someone with a complete GoodSMS collection should create
a new DAT file<br>
- updated (PC-Engine) auto-detection of bit-swapped files (by dbjh; thanks to
Cowering for the info)<br>
- updated (PC-Engine) -mgd automatically bit-swaps the file if it is detected
as being in Japan "mode" (by dbjh)<br>
- updated (PC-Engine) -smg automatically bit-swaps the file if it is detected
as being in U.S.A. "mode" (by dbjh) I don't know if this correct. Please give
feedback<br>
- added (GB) -logo restore ROM logo character data (offset: 0x104-0x134)
(by NoisyB)<br>
<p>
<a name="198-3">1.9.8-3</a><br>
- added (SNES) -xswc-super option to force 32 Mbit dump (by John Weidman)<br>
- updated (SNES) enabled -hi &amp; -nhi for -xswc-super, -xswc (dumping) and
-xfig (dumping) (by dbjh)<br>
You should explicitly specify the parallel port address when you use -hi or
-nhi in combination with one of the mentioned dump options<br>
- updated (Genesis) fixed problem with -multi that caused problems with some
games when run on the MD-PRO (by dbjh)<br>
- updated (SNES, Genesis, PC-Engine, SMS, Game Gear &amp; GB) -mgd now produces
correct file names. This time for real! :-) (by dbjh; thanks to acem77 for
testing and feedback)<br>
- added (SNES) -xswcr send/receive RTS data to/from Super Wild Card*/(all)SWC
(by dbjh)<br>
- updated (PC-Engine) reversed how -mgd &amp; -smg work. -mgd bit-swaps a file
if it is detected as not being bit-swapped ("Japan mode"/"unencrypted"). -smg
bit-swaps a file if it is detected as being bit-swapped
("U.S.A. mode"/"encypted") (by dbjh; thanks to kyuusaku for the feedback)<br>
Note that if you want to play a game with an MGD2 on a PC-Engine that you
have to manually bit-swap the file with -swap (or specify -int while
converting).<br>
- updated (SMS) improved detection of SMS and Game Gear files. In most cases
specifying -sms is no longer necessary (by dbjh)<br>
- added (SMS) -chk fix checksum (by dbjh)<br>
- updated (PC-Engine) it's Magic Super Griffin, not Super Magic Griffin. Thus
the option -smg has been renamed to -msg (by dbjh; thanks to kyuusaku for the
info)<br>
- added (PC-Engine) -xmsg send/receive to/from Magic Super Griffin (by dbjh;
thanks to kyuusaku for testing)<br>
- added (PC-Engine) -f fix region protection (by dbjh; thanks to kyuusaku for
testing)<br>
- updated (NES) -ffe writes correct headers for the NES games that actually run
on the Super Magic Card (by dbjh; thanks to kyuusaku for the info and
testing)<br>
- added (NES) -xsmc send to Super Magic Card (by dbjh; thanks to kyuusaku for
testing)<br>
- added (NES) -xsmcr send/receive RTS data to/from Super Magic Card (by dbjh)<br>
- added (all) -pattern=FILE change ROM based on patterns specified in FILE (by
dbjh)<br>
- added (N64) -swap2 word-swap ROM (1234 &#60;-&#62; 3412) (by dbjh)<br>
- added (SNES) -xgd3r &amp; -xgd6r send/receive RTS data to/from Game Doctor
SF3/6/7 (by John Weidman) -xgd3r can currently only be used for sending<br>
- added (SNES) -gd3s convert emulator *.srm (SRAM) to GD BRAM format (by dbjh)<br>
- updated (SNES) added crack for Front Mission - Gun Hazard (by dbjh; many
thanks to John) This crack is only necessay when the game is modified, for
example by -f.<br>
- updated (SNES) added NTSC/PAL fix for Pop'n Twinbee (by dbjh)<br>
- updated (SNES, Genesis, PC-Engine &amp; NES) (dumping) functions for FFE
copiers and Pro Fighter should work correctly with very fast PCs (by JohnDie)<br>
- updated (N64) added work-around for old bug in DJGPP and Solaris. Now -swap,
-swap2, -v64 and -z64 work correctly for large files (larger than 8 or 12 MB
respectively) when using the DOS or Solaris port of uCON64 (by dbjh)<br>
- updated (Genesis) replaced -pal with -region=CODE. Now it should be possible
to create multi-game files for the MD-PRO that work on all three console
types (by dbjh; many thanks to SamIAm for the info that brought me up the
idea)<br>
<p>
<a name="198-4">1.9.8-4</a><br>
- updated (all) fixed 2 bugs in code of -pattern (by dbjh)<br>
- added (SNES) -xfigc and -xswcc option to transfer SRAM to/from cartridge in
*Pro Fighter* and Super Wild Card copiers (by JohnDie)<br>
- added support for Linux/PPC (by dbjh; thanks to Tobias Pflug and Misty De Meo)<br>
- updated (SNES, Genesis, PC-Engine &amp; NES) fixed subtle bug in code of FFE
dumping routines (by dbjh; thanks to Neill Corlett for pointing this out)<br>
- updated (SNES) implemented SRAM size display for Super FX ROMs (by JohnDie)<br>
- updated (SMS) fixed bug that caused -chk not to work for uninterleaved files
with a header (by dbjh)<br>
- added support for Mac OS X (including libdiscmage) (by dbjh; many thanks to
Steve Paige for his help)<br>
- added (SNES) -xswc-dm=MODE specify SWC dump mode (by dbjh)<br>
- removed (SNES) -xswc-super, use -xswc -xswc-dm=1 instead (by dbjh)<br>
- updated (all) uCON64 won't accept a parallel port address without using --port
anymore (by dbjh)<br>
This used to be possible:<br>
ucon64 &#60;transfer option&#62; &#60;rom&#62; &#60;parallel port address&#62;<br>
Now you should use a command like this:<br>
ucon64 &#60;transfer option&#62; &#60;rom&#62; --port=&#60;parallel port address&#62;<br>
Or of course, if uCON64 automatically detects the right port or if you have
specified the correct port in the configuration file, a command like this:<br>
ucon64 &#60;transfer option&#62; &#60;rom&#62;<br>
This change removes the requirement of specifying the parallel port address
when using additional command line options (switches) like -xfalm or -xswc-dm.
It also prevents uCON64 from accessing I/O ports not associated to the
parallel port if you specify additional transfer switches while &#60;rom&#62;
has a name that starts with a number<br>
- updated (SNES, Genesis, PC-Engine, SMS, Game Gear &amp; GB) -mgd produces
correct index files (MULTI-GD) (by dbjh)<br>
- updated (SNES &amp; Genesis) -s produces an index file if the ROM dump is in
MGD format (by dbjh)<br>
- added support for ppdev (GNU/Linux-only) (by dbjh)<br>
This solves two problems:<br>
1.) It's no longer necessary for uCON64 to be setuid root in order to
communicate with a backup unit. Just make sure /dev/parport&#60;n&#62; has the
right permissions or get yourself added to the correct group<br>
2.) Non-standard parallel port addresses do not have to be specified. uCON64
still uses the first parallel port by default. It's possible to override that
by setting parport_dev in the configuration file or by setting an environment
variable<br>
Use the configure option --enable-ppdev to enable the code<br>
- added (all) -md5 calculate MD5 checksum of ROM (by NoisyB)<br>
- added (all) -sha1 calculate SHA-1 checksum of ROM (by NoisyB)<br>
- added (GBA) support for the Flash 2 Advance (Ultra); options are -xf2a
(transfer ROM data), -xf2ac=N (dump N Mbits), -xf2as (transfer 256 kB of SRAM
data) and -xf2ab=BANK (transfer 64 kB of SRAM data to "bank" BANK) (by NoisyB
and dbjh, based on source code of Ulrich Hecht and David Voswinkel; many
thanks to David Voswinkel for testing the parallel port code)<br>
- added (GBA) -xfa2multi=SIZE send multiple ROMs to the F2A. You should not
specify a loader file on the command line as a file argument. Specify one in
the configuration file or set an environment variable (by dbjh)<br>
- added (SNES) -dnsrt restore name, region and checksum from NSRT header and
remove it (by dbjh)<br>
- updated (SNES) fixed shameful bug that caused -chk and -n not to work
correctly for interleaved ROM dumps (by dbjh)<br>
- updated (SNES) added/updated code to dump special-chip cartridges. Now it's
possible to dump Super FX (2), S-DD1, SA-1 and SPC7110 cartridges, but see the
comment in swc.c! (by JohnDie)<br>
- updated (SNES) made -xswc-dm active for -xswcc so that SRAM data can be
transferred to and from Super FX 2 cartridges (by dbjh)<br>
- updated (SNES) renamed -xswc-dm to -xswc-io, because it can also be used for
sending an SRAM file (by dbjh)<br>
- updated (GBA) made -xfalmulti use gbaloader to be consistent with -xf2amulti.
So, don't specify a loader as file argument anymore (by dbjh)<br>
<p>
<a name="200">2.0.0</a><br> <!-- 1.9.8-5 -->
- updated (GBA) fixed F2A USB send code (by dbjh; many thanks to David Gauchard
for feedback, testing and sending a patch to fix the problem)<br>
- updated (N64) cleaned up Doctor V64 Junior transfer source code (by dbjh;
thanks to TenOfTen and GameCopierUser0666 for testing)<br>
- updated (SNES) added new SWC "I/O mode" 0x100, dump BIOS (by dbjh)<br>
- updated (GB) improved ROM info (by dbjh)<br>
- updated (GB) fixed problem with dumping "Rocket Games" cartridges with the
Game Boy Xchanger (by dbjh; thanks to Anna Kubisty for reporting the problem
and testing, and thanks to Cowering for his help and providing us with the
necessary information)<br>
- updated (GB) cleaned up Game Boy Xchanger transfer source code (by dbjh; many
thanks to Anna Kubisty for testing)<br>
- added (DC) --scr scramble 1ST_READ.BIN for selfboot CDs (by NoisyB)<br>
- added (DC) --unscr unscramble 1ST_READ.BIN for non-selfboot CDs (by NoisyB)<br>
- added (DC) --mkip generate IP.BIN file with default values (by NoisyB)<br>
- added (DC) --parse=TEMPLATE parse TEMPLATE file into a IP.BIN (by NoisyB)<br>
- updated (SNES) corrected output of -dbuh (by dbjh)<br>
- added (GB) --xgbxm try to enable EPP mode (by dbjh)<br>
- added (SMS/Game Gear) --xgg &amp; --xggs send/receive ROM/SRAM to/from
SMS-PRO/GG-PRO flash card programmer (by dbjh; thanks to timofonic and Leo of
ToToTEK Multi Media for providing us with the necessary information, many
thanks to Walter van Niftrik for testing)<br>
- added (PCE) --xpce send/receive ROM to/from PCE-PRO flash card programmer (by
dbjh; thanks to timofonic and Leo of ToToTEK Multi Media for providing us with
the necessary information)<br>
- added (PCE) --multi create a multi-game file for use on a PCE-PRO flash card
(by dbjh)<br>
- added (SMS/Game Gear) --multi create a multi-game file for use on an SMS-PRO
or GG-PRO flash card (by dbjh; thanks to Walter van Niftrik for his patch and
for testing)<br>
- added (SMS/Game Gear) --xggb=BANK send/receive SRAM to/from SMS-PRO/GG-PRO
BANK (by dbjh; thanks to Walter van Niftrik for the suggestion and testing)<br>
- added (Genesis) --xmdb=BANK send/receive SRAM to/from MD-PRO BANK (by dbjh)<br>
- added support for I/O port driver DlPortIO to the Windows ports. See the FAQ
for more information (by dbjh)<br>
- the Windows versions of uCON64 won't crash anymore without a (working) I/O
port driver under Windows NT/2000/XP. They display a helpful error message
instead (by dbjh)<br>
- updated (GBA) improved recognition of GBA files and fixed start address
information (by dbjh)<br>
- updated (GBA) added support for Linux 2.5 (and later) to F2A USB code (by
dbjh; thanks to colle for sending a patch and testing)<br>
- added support for OpenBSD (by dbjh; thanks to timofonic for testing)<br>
- added (N64) --xcd64, --xcd64b, --xcd64s, --xcd64f, --xcd64e, --xcd64m &amp;
--xcd64p transfer ROM/boot emu/SRAM/flash RAM/EEPROM/memory pack data to/from
CD64 (by dbjh; thanks to Ryan Underwood for libcd64 and testing)<br>
- added (Genesis) support for Mike Pavone's Genesis/Sega CD transfer cable (by
dbjh; thanks to Mike Pavone for the information and thanks to timofonic for
his PR work ;-)<br>
- updated (SNES) -gd3 does not produce 28 Mbit HiROM files anymore, it
automatically pads them to 32 Mbit (by dbjh)<br>
- added (Genesis) support for Cyan's Megadrive ROM copier (by Cyan Helkaraxe and
dbjh; thanks to timofonic for his PR work)<br>
- moved and split some files in the codebase and changed the workflow. Adding a
new option/function now requires only two changes in the code (by NoisyB)<br>
- added --dual show ROM as dualdump (by NoisyB)<br>
- added --code show ROM as code (by NoisyB)<br>
- added --print show ROM in printable characters (by NoisyB)<br>
- added --findi find STRING in ROM and ignore case of alpha bytes (by NoisyB)<br>
- added --findr find STRING in ROM but look also for shifted/relative
similarities (by NoisyB)<br>
- added (NeoGeo Pocket) --xpl send/receive ROM to/from Pocket Linker, --xpli
show information about inserted cartridge &amp; --xplm try to enable EPP mode
(by Walter van Niftrik)<br>
- added (SNES) --multi create a multi-game file for use on a Super Flash flash
card (by JohnDie)<br>
- added (SNES) --xsf send/receive ROM to/from Super Flash card, --xsfs to
send/receive SRAM to/from Super Flash card (by JohnDie)<br>
- updated (Genesis) added support for 32 Mbit Intel MD-PRO flash card (by dbjh;
thanks to Marc Haisenko for sending a patch and testing)<br>
- updated (Genesis) fixed -n and -n2 (-n did what -n2 should do and vice versa)
(by dbjh)<br>
- added (Genesis) support for splitting and joining binary (Magicom) files (by
dbjh; thanks to T. Reid for the information)<br>
- updated (NES) fixed -dumpinfo so that the year field is read correctly from
the dumper info file if it has more than 2 digits (by dbjh)<br>
- updated (SNES) --swcs, --figs, --ufos &amp; --gd3s now also work for backup
unit SRAM files, i.e., files with a header (by dbjh)<br>
- updated (SNES) fixed a bug that caused several headerless dumps to be detected
as SWC RTS or SWC SRAM files (by dbjh; many thanks to Dweezledap for reporting
this bug and for testing)<br>
- updated (N64) added support for 6105 boot codes to check sum routine (by dbjh)<br>
- updated (SNES) fixed some other issues with auto-detection (by dbjh; many
thanks to Dweezledap for reporting these problems and for testing)<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</tt></body></html>

View File

@ -0,0 +1,590 @@
<html><head>
<link rel="icon" href="images/icon.png" type="image/png">
<title>uCON64 - Developers</title></head><body bgcolor="#ffffff"><tt><br>
Q1: <a href="#1">Who develops uCON64?</a><br>
<br>
Q2: <a href="#2">How can I take part?</a><br>
<br>
Q3: <a href="#3">How do I get the source of uCON64, using CVS as an anonymous user?</a><br>
<br>
Q4: <a href="#4">How do I connect to the CVS repository as developer with read/write access?</a><br>
<br>
Q5: <a href="#5">How do I create a patch from the CVS repository?</a><br>
<br>
Q6: <a href="#6">How is the source of uCON64 organized?</a><br>
<br>
Q7: <a href="#7">What coding style is preferred?</a><br>
<br>
<br>
<p><!-- <p> instead of <br> to make lynx display a blank line between questions -->
<a name="1"><b>Q1</b>: Who develops uCON64?</a><br>
<b>A</b>: Written/modified by:<br>
1999 - 2004 NoisyB (Dirk) <a href="mailto:noisyb AT gmx.net">&#60;noisyb AT gmx.net&#62;</a><br>
2001 - 2004 dbjh<br>
<br>
Additional developers:<br>
2002 - 2004 John Weidman <a href="mailto:jweidman AT sonic.net">&#60;jweidman AT sonic.net&#62;</a><br>
Contributed several SNES-related features like Game Doctor &amp; Super UFO
support, the second version of the BS (Broadcast Satellaview) detection code,
SNES cracks &amp; NTSC/PAL fixes.<br>
<br>
2002 - 2004 Jan-Erik Karlsson<br>
Maintainer of the Amiga ports.<br>
<br>
2003 - 2004 JohnDie<br><!-- It's a nick name, no space between John and Die -->
Also contributed several SNES-related features like Pro Fighter support and
Super Wild Card transfer code improvements.<br>
<br>
<br>
uCON64 uses code (or at least ideas) from:<br>
<br>
<table>
<tr>
<td><tt>Chicken&nbsp;&amp;&nbsp;chp</tt></td>
<td><a href="mailto:ronaldm AT netcom.com"><tt>ronaldm AT netcom.com</tt></a><tt> (chp)</tt></td>
<td><tt>original uCON</tt></td>
</tr>
<tr>
<td><tt>Silo&nbsp;/&nbsp;BlackBag</tt></td>
<td></td>
<td><tt>APS patcher</tt></td>
</tr>
<tr>
<td><tt>madman</tt></td>
<td></td>
<td><tt>IPS patcher</tt></td>
</tr>
<tr>
<td><tt>The&nbsp;White&nbsp;Knight&nbsp;/ ATX</tt></td><!-- yes, breaking space -->
<td></td>
<td><tt>BSL patcher</tt></td>
</tr>
<tr>
<td><tt>Icarus&nbsp;/&nbsp;Paradox</tt></td>
<td></td>
<td><tt>PPF patcher</tt></td>
</tr>
<tr>
<td><tt>WyrmCorp</tt></td>
<td><a href="http://wyrmcorp.com" target="_blank"><tt>http://wyrmcorp.com</tt></a></td>
<td><tt>Game Genie "codec"</tt></td>
</tr>
<tr>
<td><tt>Marat&nbsp;Fayzullin</tt></td>
<td><a href="mailto:fms AT cs.umd.edu"><tt>fms AT cs.umd.edu</tt></a><br>
<a href="http://www.komkon.org/fms/" target="_blank">
<tt>http://www.komkon.org/fms/</tt></a></td>
<td><tt>some Famicom Disk System routines and NESLIST</tt></td>
</tr>
<tr>
<td><tt>Andreas&nbsp;Sterbenz</tt></td>
<td><a href="mailto:stan AT sbox.tu-graz.ac.at"><tt>stan AT sbox.tu-graz.ac.at</tt></a></td>
<td><tt>N64 checksum algorithm</tt></td>
</tr>
<tr>
<td><tt>Kami</tt></td>
<td><a href="mailto:m-kami AT da2.so-net.ne.jp"><tt>m-kami AT da2.so-net.ne.jp</tt></a><br>
<a href="http://www.playoffline.com" target="_blank">
<tt>http://www.playoffline.com</tt></a></td>
<td><tt>NES emulator for Game Boy</tt></td>
</tr>
<tr>
<td><tt>Gilligan&nbsp;/&nbsp;DC-S</tt></td>
<td></td>
<td><tt>show info for Neogeo Pocket</tt></td>
</tr>
<tr>
<td><tt>LaC</tt></td>
<td></td>
<td><tt>N64 makesram</tt></td>
</tr>
<tr>
<td><tt>Jeff&nbsp;Frohwein</tt></td>
<td><a href="mailto:info AT devrs.com"><tt>info AT devrs.com</tt></a><br>
<a href="http://www.devrs.com" target="_blank">
<tt>http://www.devrs.com</tt></a></td>
<td><tt>Flash Advance Linker transfer code</tt></td>
</tr>
<tr>
<td><tt>Omar&nbsp;Kilani</tt></td>
<td><a href="mailto:gbautil AT aurore.net"><tt>gbautil AT aurore.net</tt></a></td>
<td><tt>Game Boy Advance SRAM patching and "crash patching" code</tt></td>
</tr>
<tr>
<td><tt>Richard Davies</tt></td>
<td><a href="mailto:richard AT debaser.force9.co.uk"><tt>richard AT debaser.force9.co.uk</tt></a><br>
<a href="http://www.debaser.force9.co.uk" target="_blank">
<tt>http://www.debaser.force9.co.uk</tt></a></td>
<td><tt>PSX memory card code</tt></td>
</tr>
<tr>
<td><tt>Caz</tt></td>
<td><a href="mailto:turok2 AT currantbun.com"><tt>turok2 AT currantbun.com</tt></a><br>
<a href="http://www.infernal.currantbun.com" target="_blank">
<tt>http://www.infernal.currantbun.com</tt></a></td>
<td><tt>I/O port driver for BeOS, SWC help and Super UFO SRAM header format</tt></td>
</tr>
<tr>
<td><tt>Cowering</tt></td>
<td><a href="mailto:hotemu AT hotmail.com"><tt>hotemu AT hotmail.com</tt></a></td>
<td><tt>old BS ROM detection, BS checksum, some PC-Engine info &amp; code and more</tt></td>
</tr>
<tr>
<td><tt>Jerremy&nbsp;Koot</tt></td>
<td><a href="mailto:jkoot AT snes9x.com"><tt>jkoot AT snes9x.com</tt></a><br>
<a href="http://www.snes9x.com" target="_blank">
<tt>http://www.snes9x.com</tt></a></td>
<td><tt>old interleave detection and old deinterleave code (SNES)</tt></td>
</tr>
<tr>
<td><tt>Gary&nbsp;Henderson</tt></td>
<td><a href="mailto:gary AT snes9x.com"><tt>gary AT snes9x.com</tt></a><br>
<a href="http://www.snes9x.com" target="_blank">
<tt>http://www.snes9x.com</tt></a></td>
<td><tt>old interleave detection and old deinterleave code (SNES)</tt></td>
</tr>
<tr>
<td><tt>Evan&nbsp;Teran</tt></td>
<td><a href="mailto:emt3734 AT ritvax.isc.rit.edu"><tt>emt3734 AT ritvax.isc.rit.edu</tt></a></td>
<td><tt>lib_unif (NES)</tt></td>
</tr>
<tr>
<td><tt>NSRT&nbsp;authors</tt></td>
<td><a href="mailto:joecool22us AT yahoo.com"><tt>joecool22us AT yahoo.com</tt></a><br>
<a href="http://nsrt.edgeemu.com" target="_blank"><tt>http://nsrt.edgeemu.com</tt></a></td>
<td><tt>checksum algorithm for Momotaro Dentetsu Happy, their SNES add-on
chip information page, SNES cracks (thanks to CL), third version of
BS detection code (thanks to Nach) and general help and ideas</tt></td>
</tr>
<tr>
<td><tt>Gilles&nbsp;Vollant</tt></td>
<td><a href="mailto:info AT winimage.com"><tt>info AT winimage.com</tt></a></td>
<td><tt>unzip.c & unzip.h</tt></td>
</tr>
<tr>
<td><tt>Tiptonium</tt></td>
<td><tt><a href="http://www.tiptonium.com" target="_blank">http://www.tiptonium.com</a></td>
<td><tt>donated a Super Magic Drive (SMD)</tt></td>
</tr>
<tr>
<td><tt>FluBBa</tt></td>
<td></td><!-- private -->
<td><tt>maker (publisher) info for SNES, GB, CGB & GBA</tt></td>
</tr>
<tr>
<td><tt>gc-nfo.com</tt></td>
<td></td><!-- private -->
<td><tt>GameCube image specs</tt></td>
</tr>
<tr>
<td><tt>ToToTEK Multi Media</tt></td>
<td><a href="mailto:rayman AT tototek.com"><tt>rayman AT tototek.com</tt></a><br>
<a href="http://www.tototek.com" target="_blank">
<tt>http://www.tototek.com</tt></a></td>
<td><tt>MD-PRO, SMS-PRO/GG-PRO &amp; PCE-PRO transfer code (Delphi) and help
with that code</tt></td>
</tr>
<tr>
<td><tt>timofonic</tt></td>
<td></td><!-- private? -->
<td><tt>uCON64 PR work ;-)</tt></td>
</tr>
<tr>
<td><tt>Felipe&nbsp;XnaK</tt></td>
<td><a href="mailto:felipe AT ComPorts.com"><tt>felipe AT ComPorts.com</tt></a><br>
<a href="http://www.classicgaming.com/launchtool" target="_blank">
<tt>http://www.classicgaming.com/launchtool</tt></a></td>
<td><tt>some info from his Genesis ROM format document</tt></td>
</tr>
<tr>
<td><tt>Ulrich&nbsp;Hecht</tt></td>
<td><a href="mailto:uli AT emulinks.de"><tt>uli AT emulinks.de</tt></a><br>
<a href="http://www.emulinks.de/software.html" target="_blank">
<tt>http://www.emulinks.de/software.html</tt></a></td>
<td><tt>F2A (USB) code</tt></td>
</tr>
<tr>
<td><tt>David&nbsp;Voswinkel</tt></td>
<td><a href="mailto:d.voswinkel AT netcologne.de"><tt>d.voswinkel AT netcologne.de</tt></a></td>
<td><tt>F2A parallel port code</tt></td>
</tr>
<tr>
<td><tt>Ryan&nbsp;Underwood</tt></td>
<td></td><!-- private? -->
<td><tt>libcd64</tt></td>
</tr>
<tr>
<td><tt>Mike&nbsp;Pavone</tt></td>
<td><a href="mailto:mask_of_destiny AT hotmail.com"><tt>mask_of_destiny AT hotmail.com</tt></a><br>
<a href="http://www.retrodev.com" target="_blank">
<tt>http://www.retrodev.com</tt></a></td>
<td><tt>Genesis/Sega CD transfer code</tt></td>
</tr>
<tr>
<td><tt>Cyan&nbsp;Helkaraxe</tt></td>
<td><a href="mailto:cyan AT emulationzone.org"><tt>cyan AT emulationzone.org</tt></a><br>
<a href="http://www.emulationzone.org/projects/cyan/docs" target="_blank">
<tt>http://www.emulationzone.org/projects/cyan/docs</tt></a></td>
<td><tt>Cyan's Megadrive ROM copier transfer code</tt></td>
</tr>
</table><br>
and others...<br>
<br>
<p>
<a name="2"><b>Q2</b>: How can I take part?</a><br>
<b>A</b>: Install <a href="http://www.cvshome.org" target="_blank">CVS</a> and
checkout the latest version from
<a href="http://ucon64.sourceforge.net" target="_blank">http://ucon64.sourceforge.net</a>.
Then make your changes, email <a href="mailto:noisyb AT gmx.net">noisyb AT gmx.net</a>
and you will be named in this file and in the sources of course. Just the
typical way of open source development.<br>
<br>
<p>
<a name="3"><b>Q3</b>: How do I get the source of uCON64, using CVS as an
anonymous user?</a><br>
<b>A</b>: For read-only access you must have CVS installed. First you have to
login. To login, type:<br>
&nbsp;&nbsp; cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/ucon64 login<br>
Then CVS will ask you for a password. Since you are logged in as anonymous
you do not have a password, so just press the enter key at the password
prompt. To download the uCON64 source, type:<br>
&nbsp;&nbsp; cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/ucon64 checkout -PR ucon64<br>
The uCON64 source will then be downloaded to the directory ./ucon64.<br>
It can be very busy at SourceForge which may result in a message like:<br>
&nbsp;&nbsp; cvs [login aborted]: recv() from server cvs.sourceforge.net: EOF<br>
or<br>
&nbsp;&nbsp; cvs [checkout aborted]: recv() from server cvs.sourceforge.net: EOF<br>
If you get that message simply try again.<br>
You can speed up the download by using the option -z with a compression level
parameter. For example:<br>
&nbsp;&nbsp; cvs -z 9 -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/ucon64 checkout -PR ucon64<br>
If you want to get up to date with the newest source code later, enter the
directory ucon64 and type:<br>
&nbsp;&nbsp; cvs update -PRd<br>
<br>
<p>
<a name="4"><b>Q4</b>: How do I connect to the CVS repository as developer with
read/write access?</a><br>
<b>A</b>: For read/write access you must have CVS and SSH installed and set the
environment variable CVS_RSH=ssh. To download the source code, type:<br>
&nbsp;&nbsp; cvs -z 9 -d:ext:&#60;name&#62;@cvs.sourceforge.net:/cvsroot/ucon64 checkout -PR ucon64<br>
&#60;enter password at prompt&#62;<br>
If you never logged on to cvs.sourceforge.net before you may get a message
(from ssh) like:<br>
&nbsp;&nbsp; The authenticity of host 'cvs.sourceforge.net (66.35.250.207)' can't be established.<br>
&nbsp;&nbsp; DSA key fingerprint is 02:ab:7c:aa:49:ed:0b:a8:50:13:10:c2:3e:92:0f:42.<br>
&nbsp;&nbsp; Are you sure you want to continue connecting (yes/no)?<br>
Type yes (the whole word). Ssh will respond with a message like:<br>
&nbsp;&nbsp; Warning: Permanently added 'cvs.sourceforge.net' (DSA) to the list of known hosts.<br>
Now all files will be downloaded. Afterwards you can simply cd into the top
level directory and continue by just typing:<br>
&nbsp;&nbsp; cvs update -PRd<br>
&nbsp;&nbsp; cvs commit -R<br>
&nbsp;&nbsp; cvs add &#60;file&#62;<br>
&nbsp;&nbsp; cvs remove -f &#60;file&#62;<br>
You don't need to specify
-d:ext:&#60;name&#62;@cvs.sourceforge.net:/cvsroot/ucon64 anymore, because
that information is stored in the CVS directories then.<br>
If you use the update command in combination with (-)d, never forget to also
use the option -P or you will get a lot of crap.<br>
<br>
<p>
<a name="5"><b>Q5</b>: How do I create a patch from the CVS repository?</a><br>
<b>A</b>: As developer:<br>
cvs -d:ext:&#60;name&#62;@cvs.sourceforge.net:/cvsroot/ucon64 diff -u &#62;mychanges.patch<br>
&#60;enter password at prompt&#62;<br>
As anonymous:<br>
&nbsp;&nbsp; cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/ucon64 login<br>
&#60;just press enter at password prompt&#62;<br>
&nbsp;&nbsp; cvs -d:pserver:anonymous@cvs.sourceforge.net:/cvsroot/ucon64 diff -u &#62;mychanges.patch<br>
<br>
<p>
<a name="6"><b>Q6</b>: How is the source of uCON64 organized?</a><br>
<b>A</b>: The heart of uCON64 is ucon64.h/st_ucon64_t. This <i>struct</i> is
designed to hold all workflow relevant informations and it has pointers
to different structs which will be != NULL depending on which type or
format uCON64 did detect for the current ROM. libdiscmage (if compiled)
is involved in this process as well.<br><br>
uCON64 starts with the name of a ROM and possibly some arguments. Then it
checks if a configuration file exists and creates one if that is not the
case. For example the value of
ucon64.parport, the variable that contains the I/O address of the parallel
port, will initially be set to the value that is found in the configuration
file.<br>
After these initial functions every ROM will be processed.<br><br>
Processing a ROM.<br>
The command line will be scanned for switches. Switches are command line
arguments that will not result in an action by themselves, but they
influence the other type of command line arguments, options. <br>
uCON64 sets some other values in ucon64.h/st_ucon64_t, based on the
switches. This code can be found in ucon64_opts.c/ucon64_switches().
This is also the place where ucon64.c/ucon64.quiet is set. This variable
determines whether or not uCON64 displays ROM information.<br>
Then uCON64 starts scanning the command line for options. This code can be
found in ucon64_opts.c/ucon64_options(). From this code almost all
operations of uCON64 are executed. Under Unix this is also the point where
root privileges are given up with a call to misc.c/drop_privileges().<br>
First uCON64 tries to find out what console system the ROM belongs to using
for example the init function for SNES (console/snes.c/snes_init() or
console/nes.c/nes_init() for NES). Each init function tries to determine if the
ROM file belongs to its console type. If that is the case it returns 0,
otherwise -1.<br>
Some ROM file types contain information such as the internal name, country
and creator of the game that can be used to fill ucon64.c/main()/rom. SNES
ROM files are an example of this type of file. For other ROM file types this
information is not present inside the ROM file. NES ROMs are an example of
that type. In that case uCON64 uses the DAT files in the data file
directory. That makes it possible to display the full name of the game.
ucon64.c/ucon64_rom_handling() calls the function
ucon64_dat.c/ucon64_dat_search() that uses the CRC32 of the ROM file data to
find the required information in the DAT files. If the information could be
found ucon64_dat.c/ucon64_dat_search() fills ucon64.c/ucon64.dat with it.
ucon64.c/ucon64_rom_handling() copies the name to ucon64.rominfo->name.<br>
After that if ucon64.c/ucon64.quiet has a value smaller than 1 uCON64 will
call ucon64.c/ucon64_nfo() which displays the values and strings of ucon64.
For some options it doesn't make sense to display ROM info. If one of those
options has been specified on the command line
(ucon64.c/ucon64.flags & WF_NFO) will be zero.<br>
After all this the option will be executed (ucon64_opts.c/ucon64_options()).<br>
<br>
<p>
<a name="7"><b>Q7</b>: What coding style is preferred?</a><br>
<b>A</b>:<br>
<br>
<b>Keywords</b><br>
Always put a space after a keyword. That includes the keyword <i>sizeof</i>.<br>
<br>
<b>Indentation</b><br>
Two spaces instead of a real tab. The curly braces of functions should not
be indented.<br>
If an <i>if</i> statement has an <i>else</i> part, that part should be
aligned with the <i>if</i> part. For a <i>do-while</i> compound statement,
<i>do</i> and <i>while</i> should also be aligned.<br>
If <i>else</i> is immediately followed by an <i>if</i> statement, the
<i>if</i> keyword together with the condition statement should be put on the
same line as the <i>else</i> keyword. Example: <br>
<pre>
if (...)
{
...
}
else if (...)
{
...
}
else
{
...
}
</pre>
Note that this doesn't apply to the case where <i>else</i> is followed by a
curly brace.<br>
<br>
<b>New lines</b><br>
The statement(s) for <i>if</i>, <i>while</i> and <i>for</i> should always
start on a new line. That also applies to one-line statements.<br>
<br>
<b>Compound statements</b><br>
The curly braces should be indented and the code of the compound statement
should be indented again. The only exception is the <i>switch</i> statement.
The labels inside a <i>switch</i> statement should be aligned with the curly
braces. Example:<br>
<pre>
int
function (int value)
{
if (value &#60; 0)
{
printf ("Invalid argument: %d\n", value);
exit (1);
}
switch (value)
{
case 0:
case 1:
case 2: // falling through
puts ("lesser than or equal to 2\n");
case 3:
case 4:
puts ("lesser than or equal to 4\n");
break;
default:
puts ("greater than 4\n");
break;
}
return 0;
}
</pre>
A <i>do-while</i> compound statement should have this layout:<br>
<pre>
do
{
...
}
while (...);
</pre>
<br>
<b>Functions</b><br>
Function calls should contain one space after the name of the function.
Every parameter of the function should be separated from a previous one with
a space after the comma.<br>
For a function implementation the return type should be specified on its own
line. This doesn't apply to function prototypes. If a function needn't be
known at global scope it should be declared or defined as <i>static</i>.
Function implementations should be separated from each other by two new
lines.<br>
<br>
<b>Variables</b><br>
Variables of the same type should be defined in one group. Example:<br>
<pre>
int x, y = 0, z;
char str1[] = "xyz", *str2;
</pre>
Variables that need to be known at file scope but not at global scope should
be defined as <i>static</i>. Variables that do need to be known at global
scope should be defined in a source file, not in a header file. The header
file should contain an <i>extern</i> statement for the variable.<br>
<br>
<b>Types (<i>struct</i>s)</b><br>
A <i>struct</i> tag of a <i>struct</i> should have the prefix "st_". A new
type based on a <i>struct</i> should have the same prefix and the suffix
"_t". Example:<br>
<pre>
typedef struct st_unif_chunk
{
unsigned long id;
unsigned long length;
void *data;
} st_unif_chunk_t;
</pre>
<br>
<b>Line length</b><br>
The length of lines shouldn't be much longer than 90 characters. This
doesn't necessarily include the length of comment. Longer lines should be
broken into several shorter ones. Example:<br>
<pre>
static const int unif_prg_ids[] = {PRG0_ID, PRG1_ID, PRG2_ID, PRG3_ID,
PRG4_ID, PRG5_ID, PRG6_ID, PRG7_ID,
PRG8_ID, PRG9_ID, PRGA_ID, PRGB_ID,
PRGC_ID, PRGD_ID, PRGE_ID, PRGF_ID};
</pre>
<br>
<b>Comment</b><br>
Single or two-line comments should use //. Comments that need more lines
should use the pair /* and */. A two-line comment should signify that it is
one two-line comment instead of two one-line comments by putting one extra
space after the //. Single or two-line comments should start at column 49 if
that's possible. Example:<br>
<pre>
char buf[SIZE_INFO], number[80]; // 4 should be enough, but don't
// be too sensitive to errors
</pre>
Long comments should use the same indentation as the code that follows it:<br>
<pre>
if (deinterleave)
/*
This is a bit of a hack, i.e., putting the following code in this
...
*/
{
unsigned char *data;
int size, n = 0, prg = 0, chr = 0;
...
</pre>
<br>
<b>Preprocessor directives</b><br>
Preprocessor directives should not be indented. This does not only apply to
#include, but to all preprocessor directives.<br>
For #if and #ifdef blocks that are complex or enclose many lines of code the
corresponding #else, #elif or #endif should contain a comment that signifies
to which #if or #ifdef it belongs. <a name="multiplatform">Example:</a><br>
<pre>
#ifdef __unix__ // wait 32 milliseconds
usleep (32000);
...
#elif defined __MSDOS__ // __unix__
delay (32);
...
#elif defined __BEOS__ // __MSDOS__
snooze (32000);
...
#endif // __BEOS__
</pre>
Standard system header files should be included by specifying the name of
the header file between angle brackets. Non-standard header files should be
included with the name between double quotes. Example:<br>
<pre>
#include &#60;stdio.h&#62;
#ifdef __unix__
#include &#60;unistd.h&#62;
#endif
#include "ucon64.h"
</pre>
<br>
<b>Header files</b><br>
Header files should be protected against being included multiple times by
putting the entire file inside an #ifndef block. Define the constant for
which the #ifndef checks inside the #ifndef block. For example, for the file
swc.h:<br>
<pre>
#ifndef SWC_H
#define SWC_H
...
#endif // SWC_H
</pre>
Header files should only contain information about their corresponding
source file that may be needed by other source files. They should not
include information about variables or function definitions that are used
only inside the source file.<br>
<br>
<b>Portability</b><br>
Platform-specific function calls, variable types and #includes of header
files should be put inside #ifdef or #if blocks. For an example see the
<a href="#multiplatform">first code example</a> in the section Preprocessor
directives.<br>
<br>
<p>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br></tt></body></html>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,210 @@
<html><head>
<link rel="icon" href="images/icon.png" type="image/png">
<title>uCON64 - Hardware</title></head><body bgcolor="#ffffff"><tt>
The following backup units are currently supported by <img src="images/logo.png" height="50"><br>
<br>
If your backup unit is NOT supported yet, you might find what you need at <a href="http://mfm.subport.org" target="_blank">http://mfm.subport.org</a><br>
For more information about backup units check <a href="http://www.robwebb.clara.co.uk/backup/" target="_blank">http://www.robwebb.clara.co.uk/backup/</a><br>
<tt><br>
<br>
<center>
<table width="640">
<tr>
<td><tt>
<img src="images/swc.png"><br>
Super Wild Card 1.6XC/Super Wild Card 2.8CC/Super Wild Card DX(2)/SWC<br>
19XX Front Far East/FFE <a href="http://www.front.com.tw">http://www.front.com.tw</a><br>
(uCON64 options: --xswc, --xswc2, --xswcs, --xswcr, --xswcc, -xswc-io)<br>
<br>
<br>
<br>
<img src="images/fig.png"><br>
Super Pro Fighter (Q/Q+)/Pro Fighter X (Turbo 2)/Double Pro Fighter (X Turbo)<br>
19XX China Coach Limited/CCL <a href="http://www.ccltw.com.tw">http://www.ccltw.com.tw</a><br>
(uCON64 options: --xfig, --xfigs, --xfigc)<br>
<br>
<br>
<br>
<img src="images/sf3.png"><br>
Game Doctor SF3(SF6/SF7)/Professor SF(SF II)<br>
19XX Bung Enterprises Ltd <a href="http://www.bung.com.hk">http://www.bung.com.hk</a><br>
(uCON64 options: --xgd3, --xgd6, --xgd3s, --xgd6s, --xgd3r, --xgd6r)<br>
<br>
<br>
<br>
<img src="images/smd.png"><br>
Super Com Pro (HK)/Super Magic Drive/SMD<br>
19XX Front Far East/FFE <a href="http://www.front.com.tw">http://www.front.com.tw</a><br>
(uCON64 options: --xsmd, --xsmds)<br>
<br>
<br>
<br>
<img src="images/smc.png"><br>
Super Magic Card<br>
19XX Front Far East/FFE <a href="http://www.front.com.tw">http://www.front.com.tw</a><br>
(uCON64 options: --xsmc, --xsmcr)<br>
<br>
<br>
<br>
<img src="images/msg.png"><br>
Magic Super Griffin/MSG<br>
19XX Front Far East/FFE <a href="http://www.front.com.tw">http://www.front.com.tw</a><br>
(uCON64 option: --xmsg)<br>
<br>
<br>
<br>
<img src="images/v64.png"><br>
Doctor V64<br>
19XX Bung Enterprises Ltd <a href="http://www.bung.com.hk">http://www.bung.com.hk</a><br>
(uCON64 option: --xv64)<br>
<br>
<br>
<br>
<img src="images/v64jr.png"><br>
Doctor V64 Junior<br>
19XX Bung Enterprises Ltd <a href="http://www.bung.com.hk">http://www.bung.com.hk</a><br>
(uCON64 option: --xdjr)<br>
<br>
<br>
<br>
<img src="images/dexdrive.png"><br>
DexDrive (PSX and Nintendo 64 SRAMs)<br>
19XX InterAct <a href="http://www.dexdrive.de">http://www.dexdrive.de</a><br>
(uCON64 option: --xdex)<br>
<br>
<br>
<br>
</td>
<td><tt>
<img src="images/gbx.png"><br>
Game Boy Xchanger<br>
19XX Bung Enterprises Ltd <a href="http://www.bung.com.hk">http://www.bung.com.hk</a><br>
(uCON64 options: --xgbx, --xgbxs, --xgbxb, --xgbxm)<br>
<br>
<br>
<br>
<img src="images/cameralink.png"><br>
Mad Catz Camera Link (Game Boy Camera)<br>
XXXX Mad Catz Inc. <a href="http://www.madcatz.com">http://www.madcatz.com</a><br>
(uCON64 option: --xmccl)<br>
<br>
<br>
<br>
<img src="images/fal.png"><br>
Flash Advance Linker<br>
2001 Visoly <a href="http://www.visoly.com">http://www.visoly.com</a><br>
(uCON64 options: --xfal, --xfalmulti, --xfalc, --xfals, --xfalb, --xfalm)<br>
<br>
<br>
<br>
<img src="images/f2a.png"><br>
Flash 2 Advance (Ultra)<br>
2003 Flash2Advance <a href="http://www.flash2advance.com">http://www.flash2advance.com</a><br>
(uCON64 options: --xf2a, --xf2amulti, --xf2ac, --xf2as, --xf2ab)<br>
<br>
<br>
<br>
Lynxit (Lynx cartridge backup board)<br>
1997 K. Wilkins (custom selfmade)<br>
(uCON64 option: --xlit)<br>
<br>
<br>
<br>
<img src="images/cd_rw.png" height="50"><br>
(uCON64 options: --mksheet, --cdirip, and --nrgrip)<br>
<br>
<br>
<br>
<img src="images/mdpro.png"><br>
MD-PRO flash card programmer<br>
200X ToToTEK <a href="http://www.tototek.com">http://www.tototek.com</a><br>
(uCON64 options: --xmd, --xmds)<br>
<br>
<br>
<br>
<img src="images/pcepro.png"><br>
PCE-PRO flash card programmer<br>
200X ToToTEK <a href="http://www.tototek.com">http://www.tototek.com</a><br>
(uCON64 option: --xpce)<br>
<br>
<br>
<br>
<img src="images/smspro.png"><br>
SMS-PRO flash card programmer<br>
200X ToToTEK <a href="http://www.tototek.com">http://www.tototek.com</a><br>
(uCON64 options: --xgg, --xggs)<br><!-- yes, the same as for the GG-PRO -->
<br>
<br>
<br>
<img src="images/ggpro.png"><br>
GG-PRO flash card programmer<br>
200X ToToTEK <a href="http://www.tototek.com">http://www.tototek.com</a><br>
(uCON64 options: --xgg, --xggs)<br>
<br>
<br>
<br>
<!--img src="images/"><br-->
Cyan's Megadrive Copier<br>
1999-2004 Cyan Helkaraxe<br>
(uCON64 options: --xcmc, --xcmct, --xcmcm)<br>
<br>
<br>
<br>
<!--img src="images/"><br-->
Mike Pavone's Genesis/Sega CD transfer cable<br>
200X Mike Pavone<br>
(uCON64 options: --xmcd)<br>
<br>
<br>
<br>
</td>
</tr>
</table>
</center>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
</tt></body></html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.6 KiB

View File

@ -0,0 +1,5 @@
<html><head>
<link rel="icon" href="images/icon.png" type="image/png">
<title>uCON64 - Install</title></head><body bgcolor="#ffffff"><tt>
What you expect here can be found in <a href="faq.html">faq.html</a>
</tt></body></html>

View File

@ -0,0 +1,372 @@
--- parallel.c 2004-09-02 19:09:23.000000000 +0200
+++ parallel.c.libieee1284 2004-09-04 03:07:38.000000000 +0200
@@ -25,6 +25,11 @@
#include "config.h"
#endif
+#define USE_LIBIEEE1284
+#if defined USE_LIBIEEE1284 && defined USE_PPDEV
+#undef USE_PPDEV
+#endif
+
#ifdef USE_PARALLEL
#include <stdio.h>
@@ -40,7 +45,9 @@
#include <sys/time.h>
#include <linux/ppdev.h>
#include <linux/parport.h>
-#elif defined __linux__ && defined __GLIBC__ // USE_PPDEV
+#elif defined USE_LIBIEEE1284 // USE_PPDEV
+#include <ieee1284.h>
+#elif defined __linux__ && defined __GLIBC__ // USE_LIBIEEE1284
#ifdef HAVE_SYS_IO_H // necessary for some Linux/PPC configs
#include <sys/io.h> // ioperm() (glibc), in{b, w}(), out{b, w}()
#else
@@ -78,8 +85,12 @@
#include "getopt2.h"
#include "ucon64.h"
+#if defined USE_LIBIEEE1284 && defined USE_PPDEV
+#undef USE_PPDEV
+#endif
+
-#if defined USE_PPDEV || defined __BEOS__ || defined __FreeBSD__ || defined AMIGA
+#if defined USE_PPDEV || defined __BEOS__ || defined __FreeBSD__ || defined AMIGA || defined USE_LIBIEEE1284
static void close_io_port (void);
#endif
#if defined __i386__ || defined __x86_64__ // GCC && x86
@@ -92,8 +103,12 @@
#if defined USE_PPDEV || defined __BEOS__ || defined __FreeBSD__
static int parport_io_fd;
-#ifdef USE_PPDEV
+#endif
+#if defined USE_PPDEV || defined USE_LIBIEEE1284
static enum { FORWARD = 0, REVERSE } parport_io_direction;
+#ifdef USE_LIBIEEE1284
+struct parport *libieee1284_port;
+#else
static int parport_io_mode;
#endif
#endif
@@ -113,7 +128,7 @@
#endif
-#if defined _WIN32 || defined __CYGWIN__
+#if (defined _WIN32 || defined __CYGWIN__) && !defined USE_LIBIEEE1284
#define NODRIVER_MSG "ERROR: No (working) I/O port driver. Please see the FAQ, question 4\n"
@@ -172,7 +187,7 @@
static void (*output_word) (unsigned short, unsigned short) = outpw_func;
#endif
-#endif // _WIN32 || __CYGWIN__
+#endif // (_WIN32 || __CYGWIN__) && !USE_LIBIEEE1284
#if defined __i386__ || defined __x86_64__ // GCC && x86
@@ -275,6 +290,43 @@
exit (1);
}
return byte;
+#elif defined USE_LIBIEEE1284
+ int ppreg = port - ucon64.parport;
+ unsigned char byte;
+
+ switch (ppreg)
+ {
+ case 0: // data
+ if (parport_io_direction == FORWARD) // dir is forward?
+ {
+ parport_io_direction = REVERSE; // change it to reverse
+ ieee1284_data_dir (libieee1284_port, parport_io_direction);
+ }
+ byte = (unsigned char) ieee1284_read_data (libieee1284_port);
+ break;
+ case 1: // status
+ byte = (unsigned char) (ieee1284_read_status (libieee1284_port) ^ S1284_INVERTED);
+ break;
+ case 2: // control
+ byte = (unsigned char) (ieee1284_read_control (libieee1284_port) ^ C1284_INVERTED);
+ break;
+ case 3: // EPP/ECP address
+ ieee1284_epp_read_addr (libieee1284_port, F1284_NONBLOCK, (char *) &byte, 1);
+ break;
+ case 4: // EPP/ECP data
+ ieee1284_epp_read_data (libieee1284_port, F1284_NONBLOCK, (char *) &byte, 1);
+ break;
+ case 0x402: // ECP register
+ printf ("WARNING: Ignored read from ECP register, returning 0\n");
+ byte = 0;
+ break;
+ default:
+ fprintf (stderr,
+ "ERROR: inportb() tried to read from an unsupported port (0x%x)\n",
+ port);
+ exit (1);
+ }
+ return byte;
#elif defined __BEOS__
st_ioport_t temp;
@@ -358,6 +410,26 @@
exit (1);
}
return buf[0] | buf[1] << 8; // words are read in little endian format
+#elif defined USE_LIBIEEE1284
+ int ppreg = port - ucon64.parport;
+ unsigned char buf[2];
+
+ switch (ppreg)
+ {
+ case 3: // EPP/ECP address
+ ieee1284_epp_read_addr (libieee1284_port, F1284_NONBLOCK | F1284_FASTEPP, (char *) buf, 2);
+ break;
+ case 4: // EPP/ECP data
+ ieee1284_epp_read_data (libieee1284_port, F1284_NONBLOCK | F1284_FASTEPP, (char *) buf, 2);
+ break;
+ // the data, status, control and ECP registers should only be accessed in "8-bit mode"
+ default:
+ fprintf (stderr,
+ "ERROR: inportw() tried to read from an unsupported port (0x%x)\n",
+ port);
+ exit (1);
+ }
+ return buf[0] | buf[1] << 8; // words are read in little endian format
#elif defined __BEOS__
st_ioport_t temp;
@@ -434,6 +506,37 @@
port);
exit (1);
}
+#elif defined USE_LIBIEEE1284
+ int ppreg = port - ucon64.parport;
+
+ switch (ppreg)
+ {
+ case 0: // data
+ if (parport_io_direction == REVERSE) // dir is reverse?
+ {
+ parport_io_direction = FORWARD; // change it to forward
+ ieee1284_data_dir (libieee1284_port, parport_io_direction);
+ }
+ ieee1284_write_data (libieee1284_port, byte);
+ break;
+ case 2: // control
+ ieee1284_write_control (libieee1284_port, (unsigned char) (byte ^ C1284_INVERTED));
+ break;
+ case 3: // EPP/ECP address
+ ieee1284_epp_write_addr (libieee1284_port, F1284_NONBLOCK, (char *) &byte, 1);
+ break;
+ case 4: // EPP/ECP data
+ ieee1284_epp_write_data (libieee1284_port, F1284_NONBLOCK, (char *) &byte, 1);
+ break;
+ case 0x402: // ECP register
+ printf ("WARNING: Ignored write to ECP register\n");
+ break;
+ default:
+ fprintf (stderr,
+ "ERROR: outportb() tried to write to an unsupported port (0x%x)\n",
+ port);
+ exit (1);
+ }
#elif defined __BEOS__
st_ioport_t temp;
@@ -499,6 +602,28 @@
port);
exit (1);
}
+#elif defined USE_LIBIEEE1284
+ int ppreg = port - ucon64.parport;
+ unsigned char buf[2];
+
+ // words are written in little endian format
+ buf[0] = (unsigned char) word;
+ buf[1] = word >> 8;
+ switch (ppreg)
+ {
+ case 3: // EPP/ECP address
+ ieee1284_epp_write_addr (libieee1284_port, F1284_NONBLOCK | F1284_FASTEPP, (char *) buf, 2);
+ break;
+ case 4: // EPP/ECP data
+ ieee1284_epp_write_data (libieee1284_port, F1284_NONBLOCK | F1284_FASTEPP, (char *) buf, 2);
+ break;
+ // the data, control and ECP registers should only be accessed in "8-bit mode"
+ default:
+ fprintf (stderr,
+ "ERROR: outportw() tried to write to an unsupported port (0x%x)\n",
+ port);
+ exit (1);
+ }
#elif defined __BEOS__
st_ioport_t temp;
@@ -529,7 +654,7 @@
}
-#if (defined __i386__ || defined __x86_64__ || defined _WIN32) && !defined USE_PPDEV
+#if (defined __i386__ || defined __x86_64__ || defined _WIN32) && !defined USE_PPDEV && !defined USE_LIBIEEE1284
#define DETECT_MAX_CNT 1000
static int
parport_probe (unsigned int port)
@@ -557,6 +682,7 @@
#endif
+#ifndef USE_LIBIEEE1284
#ifdef _WIN32
static LONG
new_exception_filter (LPEXCEPTION_POINTERS exception_pointers)
@@ -584,6 +710,7 @@
return EXCEPTION_CONTINUE_SEARCH;
}
#endif
+#endif
int
@@ -637,6 +764,48 @@
parport_io_direction = FORWARD; // set forward direction as default
ioctl (parport_io_fd, PPDATADIR, &parport_io_direction);
+#elif defined USE_LIBIEEE1284
+ struct parport_list list;
+ int capabilities, ucon64_parport;
+
+ if (port == PARPORT_UNKNOWN)
+ port = 0;
+
+ if (ieee1284_find_ports (&list, 0) != E1284_OK)
+ {
+ fputs ("ERROR: Could not get port list\n", stderr);
+ exit (1);
+ }
+
+ if (port < list.portc)
+ libieee1284_port = list.portv[port];
+ else
+ {
+ fprintf (stderr, "ERROR: libieee1284 port %d not available\n", port);
+ exit (1);
+ }
+
+ if (ieee1284_open (libieee1284_port, F1284_EXCL, &capabilities) != E1284_OK)
+ {
+ fprintf (stderr, "ERROR: Could not open libieee1284 port %d\n", port);
+ exit (1);
+ }
+ // TODO: Handle ECP mode correctly
+ if (ucon64.parport_mode == UCON64_EPP || ucon64.parport_mode == UCON64_ECP)
+ if ((capabilities & (CAP1284_EPP | CAP1284_ECP)) == 0)
+ printf ("WARNING: EPP or ECP mode was requested, but not available\n");
+
+ ieee1284_free_ports (&list);
+
+ if (ieee1284_claim (libieee1284_port) != E1284_OK)
+ {
+ fprintf (stderr, "ERROR: Could not claim libieee1284 port %d\n", port);
+ ieee1284_close (libieee1284_port);
+ exit (1);
+ }
+
+ parport_io_direction = FORWARD;
+ ieee1284_data_dir (libieee1284_port, parport_io_direction);
#elif defined __BEOS__
parport_io_fd = open ("/dev/misc/ioport", O_RDWR | O_NONBLOCK);
if (parport_io_fd == -1)
@@ -710,16 +879,18 @@
}
#endif
-#if defined USE_PPDEV || defined __BEOS__ || defined __FreeBSD__
+#if defined USE_PPDEV || defined __BEOS__ || defined __FreeBSD__ || defined USE_LIBIEEE1284
if (register_func (close_io_port) == -1)
{
+#ifndef USE_LIBIEEE1284
close (parport_io_fd);
+#endif
fprintf (stderr, "ERROR: Could not register function with register_func()\n");
exit(1);
}
#endif
-#if defined __linux__ && (defined __i386__ || defined __x86_64__) && !defined USE_PPDEV
+#if defined __linux__ && (defined __i386__ || defined __x86_64__) && !defined USE_PPDEV && !defined USE_LIBIEEE1284
/*
Some code needs us to switch to the real uid and gid. However, other code
needs access to I/O ports other than the standard printer port registers.
@@ -751,7 +922,7 @@
}
#endif
-#if (defined __i386__ || defined __x86_64__ || defined _WIN32) && !defined USE_PPDEV
+#if (defined __i386__ || defined __x86_64__ || defined _WIN32) && !defined USE_PPDEV && !defined USE_LIBIEEE1284
#if defined _WIN32 || defined __CYGWIN__
/*
@@ -914,9 +1085,9 @@
exit (1);
}
}
-#endif // (__i386__ || __x86_64__ || _WIN32) && !USE_PPDEV
+#endif // (__i386__ || __x86_64__ || _WIN32) && !USE_PPDEV && !USE_LIBIEEE1284
-#ifdef USE_PPDEV
+#if defined USE_PPDEV || defined USE_LIBIEEE1284
// the following two calls need a valid value for ucon64.parport
ucon64_parport = ucon64.parport;
ucon64.parport = port;
@@ -924,7 +1095,7 @@
outportb ((unsigned short) (port + PARPORT_CONTROL),
(unsigned char) (inportb ((unsigned short) (port + PARPORT_CONTROL)) & 0x0f));
// bit 4 = 0 -> IRQ disable for ACK, bit 5-7 unused
-#ifdef USE_PPDEV
+#if defined USE_PPDEV || defined USE_LIBIEEE1284
ucon64.parport = ucon64_parport;
#endif
@@ -932,7 +1103,7 @@
}
-#if defined USE_PPDEV || defined __BEOS__ || defined __FreeBSD__ || defined AMIGA
+#if defined USE_PPDEV || defined __BEOS__ || defined __FreeBSD__ || defined AMIGA || defined USE_LIBIEEE1284
void
close_io_port (void)
{
@@ -947,6 +1118,9 @@
// it ppdev will do it for us...
ioctl (parport_io_fd, PPNEGOT, &parport_io_mode);
ioctl (parport_io_fd, PPRELEASE);
+#elif defined USE_LIBIEEE1284
+ ieee1284_release (libieee1284_port);
+ ieee1284_close (libieee1284_port);
#else // __BEOS__ || __FreeBSD__
close (parport_io_fd);
#endif
@@ -958,7 +1132,7 @@
parport_close (int parport)
{
(void) parport;
-#if defined USE_PPDEV || defined __BEOS__ || defined __FreeBSD__ || defined AMIGA
+#if defined USE_PPDEV || defined __BEOS__ || defined __FreeBSD__ || defined AMIGA || defined USE_LIBIEEE1284
if (unregister_func (close_io_port) == 0) // call func only if it can be removed!
close_io_port (); // (or else it will be called twice)
#elif defined _WIN32 || defined __CYGWIN__
@@ -976,6 +1150,9 @@
{
#ifdef USE_PPDEV
printf ("Using parallel port device: %s\n", ucon64.parport_dev);
+#elif defined USE_LIBIEEE1284
+ printf ("Using parallel port device: %s, base address 0x%lx\n",
+ libieee1284_port->filename, libieee1284_port->base_addr); // ->name
#elif defined AMIGA
printf ("Using parallel port device: %s, port %d\n", ucon64.parport_dev, ucon64.parport);
#else

View File

@ -0,0 +1,343 @@
<html><head>
<link rel="icon" href="images/icon.png" type="image/png">
<title>uCON64 - License</title></head><body bgcolor="#ffffff"><tt>
GNU GENERAL PUBLIC LICENSE<br>
Version 2, June 1991<br>
<br>
Copyright (C) 1989, 1991 Free Software Foundation, Inc.<br>
675 Mass Ave, Cambridge, MA 02139, USA<br>
Everyone is permitted to copy and distribute verbatim copies<br>
of this license document, but changing it is not allowed.<br>
<br>
Preamble<br>
<br>
The licenses for most software are designed to take away your<br>
freedom to share and change it. By contrast, the GNU General Public<br>
License is intended to guarantee your freedom to share and change free<br>
software--to make sure the software is free for all its users. This<br>
General Public License applies to most of the Free Software<br>
Foundation's software and to any other program whose authors commit to<br>
using it. (Some other Free Software Foundation software is covered by<br>
the GNU Library General Public License instead.) You can apply it to<br>
your programs, too.<br>
<br>
When we speak of free software, we are referring to freedom, not<br>
price. Our General Public Licenses are designed to make sure that you<br>
have the freedom to distribute copies of free software (and charge for<br>
this service if you wish), that you receive source code or can get it<br>
if you want it, that you can change the software or use pieces of it<br>
in new free programs; and that you know you can do these things.<br>
<br>
To protect your rights, we need to make restrictions that forbid<br>
anyone to deny you these rights or to ask you to surrender the rights.<br>
These restrictions translate to certain responsibilities for you if you<br>
distribute copies of the software, or if you modify it.<br>
<br>
For example, if you distribute copies of such a program, whether<br>
gratis or for a fee, you must give the recipients all the rights that<br>
you have. You must make sure that they, too, receive or can get the<br>
source code. And you must show them these terms so they know their<br>
rights.<br>
<br>
We protect your rights with two steps: (1) copyright the software, and<br>
(2) offer you this license which gives you legal permission to copy,<br>
distribute and/or modify the software.<br>
<br>
Also, for each author's protection and ours, we want to make certain<br>
that everyone understands that there is no warranty for this free<br>
software. If the software is modified by someone else and passed on, we<br>
want its recipients to know that what they have is not the original, so<br>
that any problems introduced by others will not reflect on the original<br>
authors' reputations.<br>
<br>
Finally, any free program is threatened constantly by software<br>
patents. We wish to avoid the danger that redistributors of a free<br>
program will individually obtain patent licenses, in effect making the<br>
program proprietary. To prevent this, we have made it clear that any<br>
patent must be licensed for everyone's free use or not licensed at all.<br>
<br>
The precise terms and conditions for copying, distribution and<br>
modification follow.<br>
<br>
GNU GENERAL PUBLIC LICENSE<br>
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION<br>
<br>
0. This License applies to any program or other work which contains<br>
a notice placed by the copyright holder saying it may be distributed<br>
under the terms of this General Public License. The "Program", below,<br>
refers to any such program or work, and a "work based on the Program"<br>
means either the Program or any derivative work under copyright law:<br>
that is to say, a work containing the Program or a portion of it,<br>
either verbatim or with modifications and/or translated into another<br>
language. (Hereinafter, translation is included without limitation in<br>
the term "modification".) Each licensee is addressed as "you".<br>
<br>
Activities other than copying, distribution and modification are not<br>
covered by this License; they are outside its scope. The act of<br>
running the Program is not restricted, and the output from the Program<br>
is covered only if its contents constitute a work based on the<br>
Program (independent of having been made by running the Program).<br>
Whether that is true depends on what the Program does.<br>
<br>
1. You may copy and distribute verbatim copies of the Program's<br>
source code as you receive it, in any medium, provided that you<br>
conspicuously and appropriately publish on each copy an appropriate<br>
copyright notice and disclaimer of warranty; keep intact all the<br>
notices that refer to this License and to the absence of any warranty;<br>
and give any other recipients of the Program a copy of this License<br>
along with the Program.<br>
<br>
You may charge a fee for the physical act of transferring a copy, and<br>
you may at your option offer warranty protection in exchange for a fee.<br>
<br>
2. You may modify your copy or copies of the Program or any portion<br>
of it, thus forming a work based on the Program, and copy and<br>
distribute such modifications or work under the terms of Section 1<br>
above, provided that you also meet all of these conditions:<br>
<br>
a) You must cause the modified files to carry prominent notices<br>
stating that you changed the files and the date of any change.<br>
<br>
b) You must cause any work that you distribute or publish, that in<br>
whole or in part contains or is derived from the Program or any<br>
part thereof, to be licensed as a whole at no charge to all third<br>
parties under the terms of this License.<br>
<br>
c) If the modified program normally reads commands interactively<br>
when run, you must cause it, when started running for such<br>
interactive use in the most ordinary way, to print or display an<br>
announcement including an appropriate copyright notice and a<br>
notice that there is no warranty (or else, saying that you provide<br>
a warranty) and that users may redistribute the program under<br>
these conditions, and telling the user how to view a copy of this<br>
License. (Exception: if the Program itself is interactive but<br>
does not normally print such an announcement, your work based on<br>
the Program is not required to print an announcement.)<br>
<br>
These requirements apply to the modified work as a whole. If<br>
identifiable sections of that work are not derived from the Program,<br>
and can be reasonably considered independent and separate works in<br>
themselves, then this License, and its terms, do not apply to those<br>
sections when you distribute them as separate works. But when you<br>
distribute the same sections as part of a whole which is a work based<br>
on the Program, the distribution of the whole must be on the terms of<br>
this License, whose permissions for other licensees extend to the<br>
entire whole, and thus to each and every part regardless of who wrote it.<br>
<br>
Thus, it is not the intent of this section to claim rights or contest<br>
your rights to work written entirely by you; rather, the intent is to<br>
exercise the right to control the distribution of derivative or<br>
collective works based on the Program.<br>
<br>
In addition, mere aggregation of another work not based on the Program<br>
with the Program (or with a work based on the Program) on a volume of<br>
a storage or distribution medium does not bring the other work under<br>
the scope of this License.<br>
<br>
3. You may copy and distribute the Program (or a work based on it,<br>
under Section 2) in object code or executable form under the terms of<br>
Sections 1 and 2 above provided that you also do one of the following:<br>
<br>
a) Accompany it with the complete corresponding machine-readable<br>
source code, which must be distributed under the terms of Sections<br>
1 and 2 above on a medium customarily used for software interchange; or,<br>
<br>
b) Accompany it with a written offer, valid for at least three<br>
years, to give any third party, for a charge no more than your<br>
cost of physically performing source distribution, a complete<br>
machine-readable copy of the corresponding source code, to be<br>
distributed under the terms of Sections 1 and 2 above on a medium<br>
customarily used for software interchange; or,<br>
<br>
c) Accompany it with the information you received as to the offer<br>
to distribute corresponding source code. (This alternative is<br>
allowed only for noncommercial distribution and only if you<br>
received the program in object code or executable form with such<br>
an offer, in accord with Subsection b above.)<br>
<br>
The source code for a work means the preferred form of the work for<br>
making modifications to it. For an executable work, complete source<br>
code means all the source code for all modules it contains, plus any<br>
associated interface definition files, plus the scripts used to<br>
control compilation and installation of the executable. However, as a<br>
special exception, the source code distributed need not include<br>
anything that is normally distributed (in either source or binary<br>
form) with the major components (compiler, kernel, and so on) of the<br>
operating system on which the executable runs, unless that component<br>
itself accompanies the executable.<br>
<br>
If distribution of executable or object code is made by offering<br>
access to copy from a designated place, then offering equivalent<br>
access to copy the source code from the same place counts as<br>
distribution of the source code, even though third parties are not<br>
compelled to copy the source along with the object code.<br>
<br>
4. You may not copy, modify, sublicense, or distribute the Program<br>
except as expressly provided under this License. Any attempt<br>
otherwise to copy, modify, sublicense or distribute the Program is<br>
void, and will automatically terminate your rights under this License.<br>
However, parties who have received copies, or rights, from you under<br>
this License will not have their licenses terminated so long as such<br>
parties remain in full compliance.<br>
<br>
5. You are not required to accept this License, since you have not<br>
signed it. However, nothing else grants you permission to modify or<br>
distribute the Program or its derivative works. These actions are<br>
prohibited by law if you do not accept this License. Therefore, by<br>
modifying or distributing the Program (or any work based on the<br>
Program), you indicate your acceptance of this License to do so, and<br>
all its terms and conditions for copying, distributing or modifying<br>
the Program or works based on it.<br>
<br>
6. Each time you redistribute the Program (or any work based on the<br>
Program), the recipient automatically receives a license from the<br>
original licensor to copy, distribute or modify the Program subject to<br>
these terms and conditions. You may not impose any further<br>
restrictions on the recipients' exercise of the rights granted herein.<br>
You are not responsible for enforcing compliance by third parties to<br>
this License.<br>
<br>
7. If, as a consequence of a court judgment or allegation of patent<br>
infringement or for any other reason (not limited to patent issues),<br>
conditions are imposed on you (whether by court order, agreement or<br>
otherwise) that contradict the conditions of this License, they do not<br>
excuse you from the conditions of this License. If you cannot<br>
distribute so as to satisfy simultaneously your obligations under this<br>
License and any other pertinent obligations, then as a consequence you<br>
may not distribute the Program at all. For example, if a patent<br>
license would not permit royalty-free redistribution of the Program by<br>
all those who receive copies directly or indirectly through you, then<br>
the only way you could satisfy both it and this License would be to<br>
refrain entirely from distribution of the Program.<br>
<br>
If any portion of this section is held invalid or unenforceable under<br>
any particular circumstance, the balance of the section is intended to<br>
apply and the section as a whole is intended to apply in other<br>
circumstances.<br>
<br>
It is not the purpose of this section to induce you to infringe any<br>
patents or other property right claims or to contest validity of any<br>
such claims; this section has the sole purpose of protecting the<br>
integrity of the free software distribution system, which is<br>
implemented by public license practices. Many people have made<br>
generous contributions to the wide range of software distributed<br>
through that system in reliance on consistent application of that<br>
system; it is up to the author/donor to decide if he or she is willing<br>
to distribute software through any other system and a licensee cannot<br>
impose that choice.<br>
<br>
This section is intended to make thoroughly clear what is believed to<br>
be a consequence of the rest of this License.<br>
<br>
8. If the distribution and/or use of the Program is restricted in<br>
certain countries either by patents or by copyrighted interfaces, the<br>
original copyright holder who places the Program under this License<br>
may add an explicit geographical distribution limitation excluding<br>
those countries, so that distribution is permitted only in or among<br>
countries not thus excluded. In such case, this License incorporates<br>
the limitation as if written in the body of this License.<br>
<br>
9. The Free Software Foundation may publish revised and/or new versions<br>
of the General Public License from time to time. Such new versions will<br>
be similar in spirit to the present version, but may differ in detail to<br>
address new problems or concerns.<br>
<br>
Each version is given a distinguishing version number. If the Program<br>
specifies a version number of this License which applies to it and "any<br>
later version", you have the option of following the terms and conditions<br>
either of that version or of any later version published by the Free<br>
Software Foundation. If the Program does not specify a version number of<br>
this License, you may choose any version ever published by the Free Software<br>
Foundation.<br>
<br>
10. If you wish to incorporate parts of the Program into other free<br>
programs whose distribution conditions are different, write to the author<br>
to ask for permission. For software which is copyrighted by the Free<br>
Software Foundation, write to the Free Software Foundation; we sometimes<br>
make exceptions for this. Our decision will be guided by the two goals<br>
of preserving the free status of all derivatives of our free software and<br>
of promoting the sharing and reuse of software generally.<br>
<br>
NO WARRANTY<br>
<br>
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY<br>
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN<br>
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES<br>
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED<br>
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF<br>
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS<br>
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE<br>
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,<br>
REPAIR OR CORRECTION.<br>
<br>
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING<br>
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR<br>
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,<br>
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING<br>
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED<br>
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY<br>
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER<br>
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE<br>
POSSIBILITY OF SUCH DAMAGES.<br>
<br>
END OF TERMS AND CONDITIONS<br>
<br>
Appendix: How to Apply These Terms to Your New Programs<br>
<br>
If you develop a new program, and you want it to be of the greatest<br>
possible use to the public, the best way to achieve this is to make it<br>
free software which everyone can redistribute and change under these terms.<br>
<br>
To do so, attach the following notices to the program. It is safest<br>
to attach them to the start of each source file to most effectively<br>
convey the exclusion of warranty; and each file should have at least<br>
the "copyright" line and a pointer to where the full notice is found.<br>
<br>
<one line to give the program's name and a brief idea of what it does.><br>
Copyright (C) 19yy <name of author><br>
<br>
This program is free software; you can redistribute it and/or modify<br>
it under the terms of the GNU General Public License as published by<br>
the Free Software Foundation; either version 2 of the License, or<br>
(at your option) any later version.<br>
<br>
This program is distributed in the hope that it will be useful,<br>
but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br>
GNU General Public License for more details.<br>
<br>
You should have received a copy of the GNU General Public License<br>
along with this program; if not, write to the Free Software<br>
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.<br>
<br>
Also add information on how to contact you by electronic and paper mail.<br>
<br>
If the program is interactive, make it output a short notice like this<br>
when it starts in an interactive mode:<br>
<br>
Gnomovision version 69, Copyright (C) 19yy name of author<br>
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.<br>
This is free software, and you are welcome to redistribute it<br>
under certain conditions; type `show c' for details.<br>
<br>
The hypothetical commands `show w' and `show c' should show the appropriate<br>
parts of the General Public License. Of course, the commands you use may<br>
be called something other than `show w' and `show c'; they could even be<br>
mouse-clicks or menu items--whatever suits your program.<br>
<br>
You should also get your employer (if you work as a programmer) or your<br>
school, if any, to sign a "copyright disclaimer" for the program, if<br>
necessary. Here is a sample; alter the names:<br>
<br>
Yoyodyne, Inc., hereby disclaims all copyright interest in the program<br>
`Gnomovision' (which makes passes at compilers) written by James Hacker.<br>
<br>
<signature of Ty Coon>, 1 April 1989<br>
Ty Coon, President of Vice<br>
<br>
This General Public License does not permit incorporating your program into<br>
proprietary programs. If your program is a subroutine library, you may<br>
consider it more useful to permit linking proprietary applications with the<br>
library. If this is what you want to do, use the GNU Library General<br>
Public License instead of this License.<br>
</tt></body></html>

View File

@ -0,0 +1,594 @@
<html><head>
<link rel="icon" href="images/icon.png" type="image/png">
<title>uCON64 - ReadMe</title></head><body bgcolor="#ffffff"><tt><pre>
uCON64 - THE tool for all your video game console concerns.
Its main features are:
- It is Open Source Software
- (Therefore) support for MANY platforms like: Unix, Win32, MSDOS, etc...
- Support for 14+ different cartridge and disc-based video game console systems
- Support for ALL common patch file formats like: IPS *), APS, BSL, PPF and
Game Genie
*) with RLE compression<!--
- Support of DAT file formats like: RomCenter Data, GoodXXXX
RomCenter Data
MAME Listinfo
RomCenter 2 Data
Title List
RAINE Gameinfo
Callus Gamelist
Retrocade Romlist
Sparcade RAT File
Mimic GCS
Nebula Driver
-->
- Support for 10+ different backup units to backup/restore ROM(s), disc(s) and
SRAM(s) like: Flash Advance Linker, Flash 2 Advance, Doctor V64 (Junior),
Super Wild Card, Game Doctor, Dexdrive, Super Magic Drive, Game Boy Xchanger,
Mad Catz Camera Link, Lynxit, MD-PRO, SMS-PRO, PCE-PRO, GG-PRO, Super Flash
and your CD-writer.
- Finally 150+(!) different options/features for every kind of ROM
handling/management known to man :-)
<!-- 120 options, 62 switches last time I counted them -->
Including:
*VERY* verbose ROM information for ALL systems, detection of bad dumps using
internal checksums or DAT files, CRC32 calculation, ROM comparison,
modification (strip, pad, etc...), SRAM conversion (emulator &#60;-&#62; backup
unit), DiscJuggler and Nero image conversions, complete gzip and zip support
for all file-related funtions, etc...
- Always up-to-date with support for new shit, trends, formats, and headers
like UNIF (NES), NSRT (SNES), new DAT file formats, etc...
For console specific options check the following usage:
uCON64 2.0.0 Unix (Linux) 1999-2005
Uses code from various people. See 'developers.html' for more!
This may be freely redistributed under the terms of the GNU Public License
Usage: ucon64 [OPTION]... [ROM|IMAGE|SRAM|FILE|DIR|ARCHIVE]...
Options
-o=DIRECTORY specify output directory
--nbak prevents backup files (*.BAK)
--ncol disable ANSI colors in output
--port=PORT specify USB or parallel PORT={USB0, USB1, 3bc, 378, 278, ...}
--hdn=N force ROM has backup unit/emulator header with size of N Bytes
--hd same as --hdn=512
most backup units use a header with a size of 512 Bytes
--nhd force ROM has no backup unit/emulator header
--ns force ROM is not split
-e emulate/run ROM (check .ucon64rc for all Emulator settings)
--crc show CRC32 value of ROM
--sha1 show SHA1 value of ROM
--md5 show MD5 value of ROM
--ls generate ROM list for all recognized ROMs
--lsv like --ls but more verbose
--hex[=ST] show ROM as hexdump; use "ucon64 --hex ...|less"
ST is the optional start value in bytes
--dual[=ST] show ROM as dualdump; use "ucon64 --dual ...|less"
--code[=ST] show ROM as code; use "ucon64 --code ...|less"
--print[=ST] show ROM in printable characters; use "ucon64 --print ...|less"
--find=STRING find STRING in ROM (wildcard: '?')
--findi=STR like --find but ignores the case of alpha bytes
--findr=STR like --find but looks also for shifted/relative similarities
(wildcard: disabled)
-c=FILE compare FILE with ROM for differences
--cs=FILE compare FILE with ROM for similarities
--help display this help and exit
--version output version information and exit
-q be quiet (don't show ROM info)
-v be more verbose (show backup unit headers also)
Padding
--ispad check if ROM is padded
--pad pad ROM to next Mb
-p same as --pad
--padn=N pad ROM to N Bytes (put Bytes with value 0x00 after end)
--strip=N strip N Bytes from end of ROM
--stpn=N strip N Bytes from start of ROM
--stp same as --stpn=512
most backup units use a header with a size of 512 Bytes
--insn=N insert N Bytes (0x00) before ROM
--ins same as --insn=512
most backup units use a header with a size of 512 Bytes
DATabase (support for DAT files)
--db DATabase statistics
--dbv like --db but more verbose
--dbs=CRC32 search ROM with CRC32 in DATabase
--scan generate ROM list for all ROMs using DATabase
like: GoodXXXX scan ...
--lsd same as --scan
--mkdat=DATFILE create DAT file; use -o to specify an output directory
--rrom rename ROMs to their internal names
--rename rename ROMs to their DATabase names
use -o to specify an output directory
--rr83 force to rename to 8.3 filenames
--force63 force to rename all filenames into Joliet CD format
like: GoodXXXX rename inplace force63 ...
TIP: using --nes would process only NES ROMs
--rl rename ROMs to lowercase
--ru rename ROMs to uppercase
Patching
--poke=OFF:V change byte at file offset OFF to value V (both in hexadecimal)
--pattern=FILE change ROM based on patterns specified in FILE
--patch=PATCH specify the PATCH for the following options
use this option or uCON64 expects the last commandline
argument to be the name of the PATCH file
-b apply Baseline/BSL PATCH to ROM
-i apply IPS PATCH to ROM (IPS&#60;=v1.2)
--mki=ORG_ROM create IPS patch; ROM should be the modified ROM
-a apply APS PATCH to ROM (APS&#60;=v1.2)
--mka=ORG_ROM create APS patch; ROM should be the modified ROM
--na=DESC change APS single line DESCRIPTION
--ppf apply PPF PATCH to IMAGE (PPF&#60;=v2.0); ROM should be an IMAGE
--mkppf=ORG_IMG create PPF patch; ROM should be the modified IMAGE
--nppf=DESC change PPF single line DESCRIPTION
--idppf=FILE_ID.DIZ change FILE_ID.DIZ of PPF PATCH (PPF v2.0)
--gge=CODE encode and display Game Genie code
example: --gge=CODE --sms or --gge=CODE --gb
CODE='AAAA:VV' or CODE='AAAA:VV:CC'
--gge=CODE --gen
CODE='AAAAAA:VVVV'
--gge=CODE --nes
CODE='AAAA:VV' or CODE='AAAA:VV:CC'
--gge=CODE --snes
CODE='AAAAAA:VV'
--ggd=GG_CODE decode Game Genie code
example: --ggd=GG_CODE --sms or --ggd=GG_CODE --gb
GG_CODE='XXX-XXX' or GG_CODE='XXX-XXX-XXX'
--ggd=GG_CODE --gen
GG_CODE='XXXX-XXXX'
--ggd=GG_CODE --nes
GG_CODE='XXXXXX' or GG_CODE='XXXXXXXX'
--ggd=GG_CODE --snes
GG_CODE='XXXX-XXXX'
--gg=GG_CODE apply Game Genie code (permanently)
example: like above but a ROM is required
supported are:
Game Boy/(Super GB)/GB Pocket/Color GB/(GB Advance),
Sega Master System(II/III)/Game Gear (Handheld),
Genesis/Sega Mega Drive/Sega CD/32X/Nomad,
Nintendo Entertainment System/NES/Famicom/Game Axe (Redant),
Super Nintendo Entertainment System/SNES/Super Famicom
All disc-based consoles
--disc force recognition; NEEDED
--rip=N rip/dump track N from IMAGE
--bin2iso=N convert track N to ISO (if possible) by resizing
sectors to 2048 Bytes
--isofix=N fix corrupted track N (if possible)
if PVD points to a bad DR offset it will add padding data
so actual DR gets located in right absolute address
--mkcue generate CUE sheet for IMAGE or existing TOC sheet
--mktoc generate TOC sheet for IMAGE or existing CUE sheet
Dreamcast
--dc force recognition
--scr scramble 1ST_READ.BIN for selfboot CDs
--unscr unscramble 1ST_READ.BIN for non-selfboot CDs
--mkip generate IP.BIN file with default values
--parse=TEMPLATE parse TEMPLATE file into a IP.BIN;
creates an empty template when TEMPLATE does not exist
Playstation (One)/Playstation 2 (CD only)
--psx force recognition
DexDrive
--xdex=N send/receive Block N to/from DexDrive; --port=PORT
receives automatically when SRAM does not exist
Game Boy Advance
--gba force recognition
-n=NEW_NAME change internal ROM name to NEW_NAME
--logo restore ROM logo character data (offset: 0x04-0x9F)
--chk fix ROM header checksum
--sram patch ROM for SRAM saving
--crp=WAIT_TIME slow down ROM access ("crash patch");
WAIT_TIME=0 default in most crash patches
WAIT_TIME=4 faster than 0, slower than 8
WAIT_TIME=8 faster than 4, slower than 28
WAIT_TIME=12 slowest cartridge access speed
WAIT_TIME=16 faster than 28, but slower than 20
WAIT_TIME=20 default in most original cartridges
WAIT_TIME=24 fastest cartridge access speed
WAIT_TIME=28 faster than 8 but slower than 16
--multi=SIZE make multi-game file for use with FAL/F2A flash card, truncated
to SIZE Mbit; file with loader must be specified first, then
all the ROMs, multi-game file to create last
Flash 2 Advance (Ultra)
--xf2a send/receive ROM to/from Flash 2 Advance (Ultra); --port=PORT
receives automatically (32 Mbits) when ROM does not exist
--xf2amulti=SIZE send multiple ROMs to Flash 2 Advance (Ultra); specify a
loader in the configuration file; --port=PORT
--xf2ac=N receive N Mbits of ROM from Flash 2 Advance (Ultra);
--port=PORT
--xf2as send/receive SRAM to/from Flash 2 Advance (Ultra); --port=PORT
receives automatically when SRAM does not exist
--xf2ab=BANK send/receive SRAM to/from Flash 2 Advance (Ultra) BANK
BANK should be a number &#62;= 1; --port=PORT
receives automatically when SRAM does not exist
Flash Advance Linker
--xfal send/receive ROM to/from Flash Advance Linker; --port=PORT
receives automatically (32 Mbits) when ROM does not exist
--xfalmulti=SIZE send multiple ROMs to Flash Advance Linker (makes temporary
multi-game file truncated to SIZE Mbit); specify a loader in
the configuration file; --port=PORT
--xfalc=N receive N Mbits of ROM from Flash Advance Linker; --port=PORT
N can be 8, 16, 32, 64, 128 or 256
--xfals send/receive SRAM to/from Flash Advance Linker; --port=PORT
receives automatically when SRAM does not exist
--xfalb=BANK send/receive SRAM to/from Flash Advance Linker BANK
BANK can be 1, 2, 3 or 4; --port=PORT
receives automatically when SRAM does not exist
--xfalm try to enable EPP mode, default is SPP mode
Nintendo 64
--n64 force recognition
--int force ROM is in interleaved format (2143, V64)
--nint force ROM is not in interleaved format (1234, Z64)
-n=NEW_NAME change internal ROM name to NEW_NAME
--v64 convert to Doctor V64 (and compatibles/interleaved)
--z64 convert to Mr. Backup Z64 (not interleaved)
--dint convert ROM to (non-)interleaved format (1234 &#60;-&#62; 2143)
--swap same as --dint, byte-swap ROM
--swap2 word-swap ROM (1234 &#60;-&#62; 3412)
--bot=BOOTCODE replace/extract BOOTCODE (4032 Bytes) in/from ROM;
extracts automatically if BOOTCODE does not exist
--lsram=SRAM LaC's SRAM upload tool; ROM should be LaC's ROM image
the SRAM must have a size of 512 Bytes
this option generates a ROM which can be used to transfer
SRAMs to your cartridge's SRAM (EEPROM)
--usms=SMSROM Jos Kwanten's UltraSMS (Sega Master System/Game Gear emulator);
ROM should be Jos Kwanten's UltraSMS ROM image
works only for SMS ROMs which are &#60;= 4 Mb in size
--chk fix ROM checksum
supports only 6102 and 6105 boot codes
Doctor V64
--xv64 send/receive ROM to/from Doctor V64; --port=PORT
receives automatically when ROM does not exist
Doctor V64 Junior
--xdjr send ROM to Doctor V64 Junior; --port=PORT
CD64
--xcd64 send/receive ROM to/from CD64; --port=PORT
receives automatically (64 Mbits) when ROM does not exist
--xcd64c=N receive N Mbits of ROM from CD64; --port=PORT
--xcd64b send boot emu to CD64; --port=PORT
--xcd64s send/receive SRAM to/from CD64; --port=PORT
receives automatically when SRAM file does not exist
--xcd64f send/receive flash RAM to/from CD64; --port=PORT
receives automatically when flash RAM file does not exist
--xcd64e send/receive EEPROM data to/from CD64; --port=PORT
receives automatically when EEPROM file does not exist
--xcd64m=INDEX send/receive memory pack data to/from CD64; --port=PORT
INDEX is ignored for CD64 BIOS protocol
receives automatically when memory pack file does not exist
--xcd64p=PROT use protocol PROT when communicating with CD64; --port=PORT
PROT=0 CD64 BIOS
PROT=1 Ghemor
PROT=2 UltraLink
DexDrive
--xdex=N send/receive Block N to/from DexDrive; --port=PORT
receives automatically when SRAM does not exist
Super Nintendo Entertainment System/SNES/Super Famicom
--snes force recognition
--hi force ROM is HiROM
--nhi force ROM is not HiROM
--erom force ROM is "Extended" (combine with -hi for Extended HiROM)
--int force ROM is in interleaved format (GD3/UFO)
--int2 force ROM is in interleaved format 2 (SFX)
--nint force ROM is not in interleaved format
--bs force ROM is a Broadcast Satellaview dump
--nbs force ROM is a regular cartridge dump
-n=NEW_NAME change internal ROM name to NEW_NAME
--fig convert to *Pro Fighter*/FIG
--figs convert emulator *.srm (SRAM) to *Pro Fighter*/FIG
--gd3 convert to Game Doctor SF3(SF6/SF7)/Professor SF(SF II)
--gd3s convert emulator *.srm (SRAM) to GD SF3(SF6/SF7)/Professor SF*
--mgd convert to Multi Game*/MGD2/MGH/RAW
--smc convert to Super Magicom/SMC
--swc convert to Super Wild Card*/SWC
--swcs convert emulator *.srm (SRAM) to Super Wild Card*/SWC
--ufo convert to Super UFO
--ufos convert emulator *.srm (SRAM) to Super UFO
--stp convert SRAM from backup unit for use with an emulator
--stp just strips the first 512 bytes
--dbuh display (relevant part of) backup unit header
--dint deinterleave ROM (regardless whether the ROM is interleaved)
--ctrl=TYPE specify type of controller in port 1 for emu when converting
TYPE=0 gamepad
TYPE=1 mouse
TYPE=2 mouse / gamepad
TYPE=6 multitap
--ctrl2=TYPE specify type of controller in port 2 for emu when converting
TYPE=0 gamepad
TYPE=1 mouse
TYPE=2 mouse / gamepad
TYPE=3 super scope
TYPE=4 super scope / gamepad
TYPE=5 Konami's justifier
TYPE=6 multitap
TYPE=7 mouse / super scope / gamepad
--col=0xCOLOR convert 0xRRGGBB (HTML) &#60;-&#62; 0xXXXX (SNES)
-j join split ROM
-s split ROM; default part size is 8 Mb
--ssize=SIZE specify split part size in Mbit (not for Game Doctor SF3)
-k remove protection (crack)
-f remove NTSC/PAL protection
-l remove SlowROM checks
--chk fix ROM checksum
--multi=SIZE make multi-game file for use with Super Flash flash card,
truncated to SIZE Mbit; file with loader must be specified
first, then all the ROMs, multi-game file to create last
--dmirr "de-mirror" ROM (strip mirrored block from end of ROM)
--dnsrt "de-NSRT" ROM (restore name and checksum from NSRT header)
Super Com Pro/Super Magicom/SMC/Super Wild Card (1.6XC/2.7CC/2.8CC/DX/DX2)/SWC
--xswc send/receive ROM to/from Super Wild Card*/SWC; --port=PORT
receives automatically when ROM does not exist
--xswc2 same as --xswc, but enables Real Time Save mode (SWC only)
--xswc-io=MODE specify SWC I/O mode; use with -xswc or -xswcc
MODE=0x001 force 32 Mbit dump
MODE=0x002 use alternative method for determining ROM size
MODE=0x004 Super FX
MODE=0x008 S-DD1
MODE=0x010 SA-1
MODE=0x020 SPC7110
MODE=0x040 DX2 trick (might work with other SWC models)
MODE=0x080 Mega Man X 2
MODE=0x100 dump BIOS
It is possible to combine flags. MODE=0x44 makes it possible
to dump for example Yoshi's Island
--xswcs send/receive SRAM to/from Super Wild Card*/SWC; --port=PORT
receives automatically when SRAM does not exist
--xswcc send/receive SRAM to/from cartridge in Super Wild Card*/SWC;
--port=PORT
receives automatically when SRAM does not exist
--xswcr send/receive RTS data to/from Super Wild Card*/SWC; --port=PORT
receives automatically when RTS file does not exist
Game Doctor SF3(SF6/SF7)/Professor SF(SF II)
--xgd3 send ROM to Game Doctor SF3/SF6/SF7; --port=PORT
this option uses the Game Doctor SF3 protocol
--xgd6 send ROM to Game Doctor SF6/SF7; --port=PORT
this option uses the Game Doctor SF6 protocol
--xgd3s send SRAM to Game Doctor SF3/SF6/SF7; --port=PORT
--xgd6s send/receive SRAM to/from Game Doctor SF6/SF7; --port=PORT
receives automatically when SRAM does not exist
--xgd6r send/receive saver (RTS) data to/from Game Doctor SF6/SF7;
--port=PORT
receives automatically when saver file does not exist
Super Pro Fighter (Q/Q+)/Pro Fighter X (Turbo 2)/Double Pro Fighter (X Turbo)
--xfig send/receive ROM to/from *Pro Fighter*/FIG; --port=PORT
receives automatically when ROM does not exist
--xfigs send/receive SRAM to/from *Pro Fighter*/FIG; --port=PORT
receives automatically when SRAM does not exist
--xfigc send/receive SRAM to/from cartridge in *Pro Fighter*/FIG;
--port=PORT
receives automatically when SRAM does not exist
Super Flash flash card programmer
--xsf send/receive ROM to/from Super Flash flash card programmer
--port=PORT
receives automatically (64 Mbits) when ROM does not exist
--xsfs send/receive SRAM to/from Super Flash flash card programmer
--port=PORT
receives automatically when SRAM does not exist
Neo Geo/Neo Geo CD(Z)/MVS
--ng force recognition
--bios=BIOS convert NeoCD BIOS to work with NeoCD emulator
--sam=SAMFILE convert SAM/M.A.M.E. sound to WAV
Genesis/Sega Mega Drive/Sega CD/32X/Nomad
--gen force recognition
--int force ROM is in interleaved format (SMD)
--int2 force ROM is in interleaved format 2 (MGD)
--nint force ROM is not in interleaved format (BIN/RAW)
-n=NEW_NAME change foreign ROM name to NEW_NAME
--n2=NEW_NAME change Japanese ROM name to NEW_NAME
--smd convert to Super Magic Drive/SMD
--smds convert emulator (*.srm) SRAM to Super Magic Drive/SMD
--bin convert to Magicom/BIN/RAW
--mgd convert to Multi Game*/MGD2/MGH
--stp convert SRAM from backup unit for use with an emulator
--stp just strips the first 512 bytes
-j join split ROM
-s split ROM; default part size is 8 Mb (4 Mb for SMD)
--ssize=SIZE specify split part size in Mbit
-f remove NTSC/PAL protection
--chk fix ROM checksum
--1991 fix old third party ROMs to work with consoles build after
October 1991 by inserting "(C) SEGA" and "(C)SEGA"
--multi=SIZE make multi-game file for use with MD-PRO flash card, truncated
to SIZE Mbit; file with loader must be specified first, then
all the ROMs, multi-game file to create last
--region=CODE enable region function; use with -multi
CODE=0 force NTSC/Japan for all games
CODE=1 force NTSC/U.S.A. for all games
CODE=2 force PAL for all games
CODE=x use whatever setting games expect
Super Com Pro/Super Magic Drive/SMD
--xsmd send/receive ROM to/from Super Magic Drive/SMD; --port=PORT
receives automatically when ROM does not exist
--xsmds send/receive SRAM to/from Super Magic Drive/SMD; --port=PORT
receives automatically when SRAM does not exist
MD-PRO flash card programmer
--xmd send/receive ROM to/from MD-PRO flash card programmer
--port=PORT
receives automatically (32/64 Mbits) when ROM does not exist
--xmds send/receive SRAM to/from MD-PRO flash card programmer
--port=PORT
receives automatically when SRAM does not exist
--xmdb=BANK send/receive SRAM to/from MD-PRO BANK
BANK can be a number from 1 to 4; --port=PORT
receives automatically when SRAM does not exist
Mike Pavone's Genesis/Sega CD transfer cable
--xmcd receive ROM from Genesis/Sega CD; --port=PORT
Cyan's Megadrive ROM copier
--xcmc receive ROM from Cyan's Megadrive ROM copier; --port=PORT
--xcmct=TEST run test TEST
TEST=1 burn-in reliability test (specify speed)
TEST=2 testbench mode (experts only)
--xcmcm=SPEED specify transfer speed
SPEED=1 slow (debug)
SPEED=2 medium
SPEED=3 fast (default)
SPEED=4 full speed (risky)
Game Boy/(Super GB)/GB Pocket/Color GB/(GB Advance)
--gb force recognition
-n=NEW_NAME change internal ROM name to NEW_NAME
--logo restore ROM logo character data (offset: 0x104-0x134)
--mgd convert to Multi Game*/MGD2/RAW
--ssc convert to Super Smart Card/SSC
--sgb convert from GB Xchanger/GB/GBC to Super Backup Card/GX/GBX
--gbx convert from Super Backup Card/GX/GBX to GB Xchanger/GB/GBC
--n2gb=NESROM KAMI's FC EMUlator (NES emulator);
ROM should be KAMI's FC Emulator ROM image
NESROM should contain 16 kB of PRG data and 8 kB of CHR data
--chk fix ROM checksum
Game Boy Xchanger/GBDoctor
--xgbx send/receive ROM to/from GB Xchanger; --port=PORT
receives automatically when ROM does not exist
--xgbxs send/receive SRAM to/from GB Xchanger; --port=PORT
receives automatically when SRAM does not exist
--xgbxb=BANK send/receive 64 kbits SRAM to/from GB Xchanger BANK
BANK can be a number from 0 to 15; --port=PORT
receives automatically when ROM does not exist
--xgbxm try to enable EPP mode, default is SPP mode
Mad Catz Camera Link (Game Boy Camera)
--xmccl receives from Mad Catz Camera Link; --port=PORT
Handy (prototype)/Lynx/Lynx II
--lynx force recognition
--lyx convert to LYX/RAW (strip 64 Bytes LNX header)
--lnx convert to LNX (uses default values for the header);
adjust the LNX header with the following options
-n=NEW_NAME change internal ROM name to NEW_NAME (LNX only)
--nrot set no rotation (LNX only)
--rotl set rotation left (LNX only)
--rotr set rotation right (LNX only)
--b0=N change Bank0 kBytes size to N={0,64,128,256,512} (LNX only)
--b1=N change Bank1 kBytes size to N={0,64,128,256,512} (LNX only)
Lynxit (Lynx cartridge backup board)
--xlit receive ROM from Lynxit interface; --port=PORT
PC-Engine (CD Unit/Core Grafx(II)/Shuttle/GT/LT/Super CDROM/DUO(-R(X)))
Super Grafx/Turbo (Grafx(16)/CD/DUO/Express)
--pce force recognition
--int force ROM is in interleaved (bit-swapped) format
--nint force ROM is not in interleaved (bit-swapped) format
--msg convert to Magic Super Griffin/MSG
--mgd convert to Multi Game Doctor*/MGD2/RAW
--swap swap bits of all bytes in file (TurboGrafx-16 &#60;-&#62; PC-Engine)
-f fix region protection
--multi=SIZE make multi-game file for use with PCE-PRO flash card, truncated
to SIZE Mbit; file with loader must be specified first, then
all the ROMs, multi-game file to create last
Magic Super Griffin/MSG
--xmsg send/receive ROM to/from Magic Super Griffin/MSG; --port=PORT
receives automatically when ROM does not exist
PCE-PRO flash card programmer
--xpce send/receive ROM to/from PCE-PRO flash card programmer
--port=PORT
receives automatically (32 Mbits) when ROM does not exist
Nintendo Entertainment System/NES/Famicom/Game Axe (Redant)
--nes force recognition
-n=NEW_NAME change internal ROM name to NEW_NAME (UNIF only)
--unif convert to UNIF format/UNF (uses default values)
--ines convert to iNES format/NES (uses default values)
--ineshd extract iNES header from ROM (16 Bytes)
-j join Pasofami/PRM/700/PRG/CHR/split ROM (Pasofami -&#62; iNES)
--pasofami convert to Pasofami/PRM/700/PRG/CHR
-s convert/split to Pasofami/PRM/700/PRG/CHR (iNES -&#62; Pasofami)
--ffe convert to FFE format (Super Magic Card)
--mapr=MAPR specify board name or mapper number for conversion options
MAPR must be a board name for UNIF or a number for Pasofami
and iNES
--dint deinterleave ROM (regardless whether the ROM is interleaved)
--ctrl=TYPE specify controller type (UNIF only)
TYPE=0 regular joypad
TYPE=1 zapper
TYPE=2 R.O.B.
TYPE=3 Arkanoid controller
TYPE=4 powerpad
TYPE=5 four-score adapter
--ntsc specify TV standard is NTSC (UNIF only)
--pal specify TV standard is PAL (UNIF only)
--bat specify battery is present
--nbat specify battery is not present
--vram specify VRAM override (UNIF only)
--nvram specify no VRAM override (UNIF only)
--mirr=MTYPE specify mirroring type
MTYPE=0 horizontal mirroring
MTYPE=1 vertical mirroring
MTYPE=2 mirror all pages from $2000 (UNIF only)
MTYPE=3 mirror all pages from $2400 (UNIF only)
MTYPE=4 four screens of VRAM
MTYPE=5 mirroring controlled by mapper hardware (UNIF only)
--cmnt=TEXT specify that TEXT should be used as comment (UNIF only)
--dumpinfo=FILE use dumper info from FILE when converting to UNIF
--fds convert Famicom Disk System file (diskimage) from FAM to FDS
--fdsl list Famicom Disk System/FDS (diskimage) contents
Super Magic Card
--xsmc send ROM (in FFE format) to Super Magic Card; --port=PORT
--xsmcr send/receive RTS data to/from Super Magic Card; --port=PORT
receives automatically when RTS file does not exist
Sega Master System(II/III)/Game Gear (Handheld)
--sms force recognition
--int force ROM is in interleaved format (SMD)
--nint force ROM is not in interleaved format (RAW)
--mgd convert to Multi Game*/MGD2/MGH/RAW (gives SMS name)
--mgdgg same as --mgd, but gives GG name
--smd convert to Super Magic Drive/SMD
--smds convert emulator (*.srm) SRAM to Super Magic Drive/SMD
--chk fix ROM checksum (SMS only)
--multi=SIZE make multi-game file for use with SMS-PRO/GG-PRO flash card,
truncated to SIZE Mbit; file with loader must be specified
first, then all the ROMs, multi-game file to create last
SMS-PRO/GG-PRO flash card programmer
--xgg send/receive ROM to/from SMS-PRO/GG-PRO flash card programmer
--port=PORT
receives automatically (32 Mbits) when ROM does not exist
--xggs send/receive SRAM to/from SMS-PRO/GG-PRO flash card programmer
--port=PORT
receives automatically when SRAM does not exist
--xggb=BANK send/receive SRAM to/from SMS-PRO/GG-PRO BANK
BANK can be a number from 1 to 4; --port=PORT
receives automatically when SRAM does not exist
WonderSwan/WonderSwan Color/SwanCrystal
--swan force recognition
--chk fix ROM checksum
Panther(32bit prototype)/Jaguar64/Jaguar64 CD
--jag force recognition
Neo Geo Pocket/Neo Geo Pocket Color
--ngp force recognition
Pocket Linker
--xpl send/receive ROM to/from Pocket Linker; --port=PORT
receives automatically when ROM does not exist
--xpli show information about inserted cartridge; --port=PORT
--xplm try to enable EPP mode, default is SPP mode
Atari VCS 2600(aka Stella)/Atari 5200 SuperSystem/Atari CX7800/Atari 2600 Jr
--ata force recognition
DATabase: 32626 known ROMs (DAT files: /mnt/hd2-1/home/daniel/.ucon64/dat)
NOTE: You only need to specify PORT if uCON64 doesn't detect the (right)
parallel port. If that is the case give a hardware address. For example:
ucon64 --xswc "rom.swc" --port=0x378
In order to connect a copier to a PC's parallel port you need a standard
bidirectional parallel cable
TIP: ucon64 --help --snes (would show only SNES related help)
ucon64 --help|less (to see everything in less)
Give the force recognition switch a try if something went wrong
Please report any problems/ideas/fixes to noisyb@gmx.net or
ucon64-announce@lists.sf.net or visit http://ucon64.sf.net
</pre></tt></body></html>

View File

@ -0,0 +1,173 @@
..................
...............: STANDARD CODES ::...............
: :\
: [a] Alternate [p] Pirate :\
: [b] Bad Dump [t] Trained :\
: [f] Fixed [T-] OldTranslation :\
: [T+] NewerTranslation :\
: [h] Hack (-) Unknown Year :\
: [o] Overdump [!] Verified Good Dump :\
: (M#) Multilanguage (# of Languages) :\
: (###) Checksum (??k) ROM Size :\
: ZZZ_ Unclassified (Unl) Unlicensed :\
:...............................................:\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
.................
................: SPECIAL CODES ::...............
: :\
: .-----Gameboy-----. .----Super Nintendo----. :\
: [ [C] Color ] [ (BS) BS ROMs ] :\
: [ [S] Super ] [ (ST) Sufami Turbo ] :\
: [ [BF] Bung Fix ] [ (NP) Nintendo Power ] :\
: `-----------------' `----------------------' :\
: .--------Atari---------. :\
: .-----Genesis-----. [ (PAL) Euro Version ] :\
: [ (1) Japan ] `----------------------' :\
: [ (4) USA ] .---------GBA----------. :\
: [ (5) NTSC Only ] [ [hI??] Intro hacks ] :\
: [ (8) PAL Only ] `----------------------' :\
: [ (B) non USA ] .--------Coleco--------. :\
: [ [c] Checksum ] [ (Adam) ADAM Version ] :\
: [ [x] Bad Checksum] `----------------------' :\
: [ [R-] Countries ] :\
: `-----------------' :\
: .--------NES/FC--------. :\
: .--NeoGeo Pocket--. [ (PC10) PlayChoice 10 ] :\
: [ [M] Mono Only ] [ (VS) Versus ] :\
: `-----------------' [ [hFFE] FFE Copier fmt] :\
: `----------------------' :\
:...............................................:\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
.................
................: COUNTRY CODES ::...............
: :\
: (1) Japan & Korea (4) USA & BrazilNTSC :\
: (A) Australia (J) Japan :\
: (B) non USA (Genesis) (K) Korea :\
: (C) China (NL) Netherlands :\
: (E) Europe (PD) Public Domain :\
: (F) France (S) Spain :\
: (F) World (Genesis) :\
: (FC) French Canadian (SW) Sweden :\
: (FN) Finland (U) USA :\
: (G) Germany (UK) England :\
: (GR) Greece (Unk) Unknown Country :\
: (HK) Hong Kong (I) Italy :\
: (H) Holland (Unl) Unlicensed :\
:...............................................:\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
.......................
.............: STANDARD CODE NOTES ::............
: :\
: [a] This is simply an alternate version of a :\
: ROM. Many games have been re-released to :\
: fix bugs or even to eliminate Game Genie :\
: codes (Yes, Nintendo hates that device). :\
: ------------------- :\
: [b] A bad dump often occurs with an older :\
: game or a faulty dumper (bad connection). :\
: Another common source of [b] ROMs is a :\
: corrupted upload to a release FTP. :\
: ------------------- :\
: [f] A fixed game has been altered in some way :\
: so that it will run better on a copier :\
: or emulator. :\
: ------------------- :\
: [h] Something in this ROM is not quite as it :\
: should be. Often a hacked ROM simply has :\
: a changed header or has been enabled to :\
: run in different regions. Other times it :\
: could be a release group intro, or just :\
: some kind of cheating or funny hack. :\
: ------------------- :\
: [o] An overdumped ROM image has more data :\
: than is actually in the cart. The extra :\
: information means nothing and is removed :\
: from the true image. :\
: ------------------- :\
: [t] A trainer is special code which executes :\
: before the game is begun. It allows you :\
: to access cheats from a menu. :\
: ------------------- :\
: [!] Verified good dump. Thank God for these! :\
:...............................................:\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
......................
.............: SPECIAL CODE NOTES ::.............
: :\
: **** SNES **** :\
: (BS) These Japanese ROMs were distributed :\
: through a satellite system in Japan :\
: known as the Broadcast Satellaview. :\
: They were transmitted along with a TV :\
: show which was connected to the game in :\
: some way. These games were only playable :\
: during the show, and thus stop after an :\
: hour, and many were timed so that only :\
: certain time periods were playable. :\
: ------------------- :\
: (ST) The Sufami Turbo device allowed two :\
: GameBoy sized carts to be plugged into :\
: the SNES. Certain carts combined into :\
: new games much like the Sonic & Knuckles :\
: lock-on technology by Sega. :\
: ------------------- :\
: (NP) Nintendo Power has been known to release :\
: games only available to its subscribers. :\
: Most of these ROMs are Japanese, as this :\
: practice occured mainly in Japan. :\
: ------------------- :\
: :\
: **** Genesis **** :\
: (1) Carts with this code will run on both :\
: Japanese and Korean machines. :\
: ------------------- :\
: (4) While this code is technically the same :\
: as a (U) code, it is a newer header :\
: format and represents that the cart will :\
: run on USA and Brazil NTSC machines. :\
: ------------------- :\
: (B) This country code indicates that the :\
: cart will run on any non US machine. :\
: ------------------- :\
: [c] This code represents a cart with known :\
: faulty checksum routines. :\
: ------------------- :\
: :\
: **** GameBoy **** :\
: [BF] Bung released a programmable cartridge :\
: compatable with the GameBoy which could :\
: hold any data you wished to play. :\
: However, many games do not function on :\
: Bung v1.0 carts and have to be 'fixed.' :\
: ------------------- :\
: :\
: **** Nintendo **** :\
: PC10 The PlayChoice 10 was an arcade unit :\
: which played exact copies of NES games :\
: in an arcade cabinet. The machines had a :\
: choice of 10 games to choose from and :\
: ran for about 3 minutes on 25 cents. :\
: ------------------- :\
: :\
: VS The Versus system ran on similar hard- :\
: ware to the PC10 machines, but simply :\
: allowed you to play against each other. :\
:...............................................:\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
...........
...................: Credits ::..................
: :\
: Document written by Psych0phobiA / q^-o|o-^p :\
: :\
: All codes developed by Cowering for the :\
: Goodxxxx series ROM file renaming utilities. :\
: :\
: Visit #rareroms on NewNet in IRC! :\
:...............................................:\
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

View File

@ -0,0 +1,380 @@
.PHONY: all clean distclean install uninstall
@DEFINE_DLOPEN_MAKE@
@DEFINE_ZLIB_MAKE@
@DEFINE_DISCMAGE_MAKE@
@DEFINE_USB_MAKE@
@DEFINE_LIBCD64_MAKE@
CC=@CC@
CFLAGS=-I. -Wall -W -O3 @DEFS@
LDFLAGS=-s
TARGETS=
ifdef USE_DISCMAGE
LIBNAME_DM=discmage
endif
# The test for Cygwin should be done before the test for DJGPP, because the
# environment variable DJGPP can be set under Bash for people who have
# installed both GCC (and friends) ports.
GCC_WIN=0
# test cygwin before DJGPP; OSTYPE is not exported on Cygwin
ifeq ($(TERM),cygwin)
GCC_WIN=1
endif
# test msys before DJGPP; MSYS, MinGW's POSIX build environment
ifeq ($(OSTYPE),msys)
GCC_WIN=1
endif
ifeq ($(GCC_WIN),1)
ifdef USE_DISCMAGE
FULLLIBNAME_DM=$(LIBNAME_DM).dll
ifndef DLOPEN
LDFLAGS+=libdiscmage/$(LIBNAME_DM).a
endif
endif
else
ifdef DJGPP
ifdef USE_DISCMAGE
FULLLIBNAME_DM=$(LIBNAME_DM).dxe
ifndef DLOPEN
LDFLAGS+=libdiscmage/$(LIBNAME_DM).a
endif
endif
else # Unix, BeOS or Mac OS X (Darwin)
ifeq ($(findstring openbsd,$(OSTYPE)),openbsd) # for example "openbsd3.4"
# i386_iopl() is located in libi386.a
LDFLAGS+=@LIBI386_MAKE@
endif
ifdef USE_DISCMAGE
ifeq ($(findstring darwin,$(OSTYPE)),darwin) # for example "darwin7.0"
FULLLIBNAME_DM=$(LIBNAME_DM).dylib
else
FULLLIBNAME_DM=$(LIBNAME_DM).so
endif
endif
ifdef DLOPEN
ifneq ($(OSTYPE),beos)
ifeq ($(findstring freebsd,$(OSTYPE)),) # false if OSTYPE contains "freebsd"
ifeq ($(findstring openbsd,$(OSTYPE)),) # false if OSTYPE contains "openbsd"
LDFLAGS+=-ldl
endif
endif
endif
else # DLOPEN
ifdef USE_DISCMAGE # GNU specific: "simply expanded variable"
FULLLIBNAME_DM:=$(addprefix lib,$(FULLLIBNAME_DM))
LDFLAGS+=-Llibdiscmage -l$(LIBNAME_DM)
endif
endif
endif # DJGPP
endif # GCC_WIN
TARGETS+=libdiscmage/$(FULLLIBNAME_DM)
ifdef USE_LIBCD64
LDFLAGS+=backup/libcd64/libcd64.a
TARGETS+=backup/libcd64/libcd64.a
endif
OBJECTS=ucon64.o ucon64_dat.o ucon64_misc.o ucon64_opts.o \
misc/chksum.o misc/file.o misc/getopt.o misc/getopt2.o \
misc/misc.o misc/parallel.o misc/property.o misc/string.o \
patch/aps.o patch/bsl.o patch/gg.o patch/ips.o patch/pal4u.o \
patch/ppf.o patch/xps.o \
console/dc.o console/gb.o console/gba.o console/genesis.o \
console/jaguar.o console/lynx.o console/n64.o console/neogeo.o \
console/nes.o console/ngp.o console/pce.o console/psx.o console/sms.o \
console/snes.o console/swan.o \
backup/cd64.o backup/cmc.o backup/dex.o backup/doctor64.o \
backup/doctor64jr.o backup/f2a.o backup/fal.o backup/ffe.o \
backup/fig.o backup/gbx.o backup/gd.o backup/interceptor.o \
backup/lynxit.o backup/mccl.o backup/mcd.o backup/md-pro.o \
backup/mgd.o backup/msg.o backup/pce-pro.o backup/pl.o \
backup/psxpblib.o backup/sflash.o backup/smc.o backup/smd.o \
backup/smsgg-pro.o backup/ssc.o backup/swc.o backup/tototek.o \
backup/ufo.o backup/yoko.o backup/z64.o
ifdef USE_ZLIB
LDFLAGS+=-lz
OBJECTS+=misc/archive.o misc/map.o misc/unzip.o
endif
ifdef USE_USB
LDFLAGS+=-lusb
OBJECTS+=misc/usb.o
endif
ifdef DLOPEN
OBJECTS+=misc/dlopen.o
ifndef USE_ZLIB
ifeq ($(GCC_WIN),1)
else
ifdef DJGPP # DJGPP code in dlopen needs map code
OBJECTS+=misc/map.o
endif # DJGPP
endif # GCC_WIN
endif # USE_ZLIB
else
ifeq ($(GCC_WIN),1) # Cygwin/MinGW code in ucon64_misc needs dlopen code
OBJECTS+=misc/dlopen.o
endif # GCC_WIN
endif # DLOPEN
TARGET=ucon64
ifeq ($(GCC_WIN),1)
TARGET:=$(addsuffix .exe,$(TARGET)) # adding .exe avoids "problems" with Cygwin/MinGW
else
ifdef DJGPP # OSTYPE is not defined by default under DOS
TARGET:=$(addsuffix .exe,$(TARGET))
endif # DJGPP
endif # GCC_WIN
TARGETS+=$(TARGET)
all: $(TARGETS)
CLEAN_CMD=rm -f $(TARGET) $(OBJECTS) *.core *.stackdump *~ */*~ */*/*~; \
cd libdiscmage && $(MAKE) clean; \
cd ../backup/libcd64 && $(MAKE) clean
clean:
ifeq ($(GCC_WIN),1)
$(CLEAN_CMD)
else
ifdef DJGPP
del *.o
del patch\*.o
del console\*.o
del backup\*.o
del misc\*.o
del $(TARGET)
cd libdiscmage
$(MAKE) clean
cd ../backup/libcd64
$(MAKE) clean
cd ../..
else # Unix, BeOS or Mac OS X (Darwin)
$(CLEAN_CMD)
endif # DJGPP
endif # GCC_WIN
DISTCLEAN_CMD=rm -f Makefile config.log config.status config.cache config.h; \
cd libdiscmage && $(MAKE) distclean; \
cd ../backup/libcd64 && $(MAKE) clean
# libcd64 Makefile has no distclean target
distclean: clean
ifeq ($(GCC_WIN),1)
$(DISTCLEAN_CMD)
else
ifdef DJGPP
del Makefile
del config.log
del config.status
del config.cache
del config.h
cd libdiscmage
$(MAKE) distclean
cd ../backup/libcd64
$(MAKE) clean
cd ../..
else
$(DISTCLEAN_CMD)
endif # DJGPP
endif # GCC_WIN
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
backup/cd64.o: backup/cd64.c
$(CC) $(CFLAGS) -Ibackup/libcd64 -c $< -o $@
ifdef USE_DISCMAGE
libdiscmage/$(FULLLIBNAME_DM):
ifeq ($(GCC_WIN),1)
cd libdiscmage && $(MAKE)
else
ifdef DJGPP
cd libdiscmage
$(MAKE)
cd ..
else
cd libdiscmage && $(MAKE)
endif # DJGPP
endif # GCC_WIN
endif # USE_DISCMAGE
ifdef USE_LIBCD64
backup/libcd64/libcd64.a:
ifeq ($(GCC_WIN),1)
cd backup/libcd64 && $(MAKE)
else
ifdef DJGPP
cd backup/libcd64
$(MAKE)
cd ../..
else
cd backup/libcd64 && $(MAKE)
endif # DJGPP
endif # GCC_WIN
endif # USE_DISCMAGE
$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
install:
ifeq ($(TERM),cygwin) # test cygwin before DJGPP
else
ifeq ($(OSTYPE),msys) # test msys before DJGPP
else
ifdef DJGPP
else
ifeq ($(OSTYPE),beos)
./install_beos.sh
else
./install.sh
endif # beos
endif # DJGPP
endif # msys
endif # cygwin
ifndef DLOPEN
cd libdiscmage && $(MAKE) install
endif
uninstall:
ifeq ($(TERM),cygwin) # test cygwin before DJGPP
else
ifeq ($(OSTYPE),msys) # test msys before DJGPP
else
ifdef DJGPP
else
ifeq ($(OSTYPE),beos)
rm -f $(HOME)/config/bin/$(TARGET)
else
rm -f /usr/local/bin/$(TARGET)
endif # beos
endif # DJGPP
endif # msys
endif # cygwin
ifndef DLOPEN
cd libdiscmage && $(MAKE) uninstall
endif
# Dependencies
# Most source files include these
UCON64_STD_H=ucon64.h ucon64_misc.h misc/misc.h config.h ucon64_defines.h
misc/archive.o: misc/archive.h misc/map.h config.h
misc/chksum.o: misc/chksum.h config.h
misc/dlopen.o: misc/dlopen.h misc/dxedll_pub.h config.h
misc/getopt.o: misc/getopt.h
misc/map.o: misc/map.h config.h
misc/misc.o: misc/misc.h misc/archive.h config.h
misc/parallel.o: misc/parallel.h config.h
misc/usb.o: misc/usb.h config.h
misc/unzip.o: misc/unzip.h config.h
ucon64.o: misc/dlopen.h misc/getopt.h ucon64_dat.h ucon64_opts.h \
console/dc.h console/gb.h console/gba.h console/genesis.h \
console/jaguar.h console/lynx.h console/n64.h console/neogeo.h \
console/nes.h console/ngp.h console/pce.h console/psx.h console/sms.h \
console/snes.h console/swan.h \
backup/cd64.h backup/dex.h backup/doctor64.h backup/doctor64jr.h \
backup/f2a.h backup/fal.h backup/ffe.h backup/fig.h backup/gbx.h \
backup/gd.h backup/interceptor.h backup/lynxit.h backup/mccl.h \
backup/mcd.h backup/md-pro.h backup/mgd.h backup/msg.h \
backup/pce-pro.h backup/pl.h backup/smc.h backup/smd.h \
backup/smsgg-pro.h backup/ssc.h backup/swc.h backup/tototek.h \
backup/ufo.h backup/yoko.h backup/z64.h \
patch/aps.h patch/bsl.h patch/gg.h patch/ips.h patch/pal4u.h \
patch/ppf.h patch/xps.h $(UCON64_STD_H)
ucon64_dat.o: ucon64_dat.h $(UCON64_STD_H)
ucon64_misc.o: misc/dlopen.h $(UCON64_STD_H)
ucon64_opts.o: misc/dlopen.h misc/getopt.h ucon64_dat.h ucon64_opts.h \
console/dc.h console/gb.h console/gba.h console/genesis.h \
console/jaguar.h console/lynx.h console/n64.h console/neogeo.h \
console/nes.h console/ngp.h console/pce.h console/psx.h \
console/sms.h console/snes.h console/swan.h \
backup/cd64.h backup/dex.h backup/doctor64.h \
backup/doctor64jr.h backup/f2a.h backup/fal.h backup/ffe.h \
backup/fig.h backup/gbx.h backup/gd.h backup/interceptor.h \
backup/lynxit.h backup/mccl.h backup/mcd.h backup/md-pro.h \
backup/mgd.h backup/msg.h backup/pce-pro.h backup/pl.h \
backup/smc.h backup/smd.h backup/smsgg-pro.h backup/ssc.h \
backup/swc.h backup/tototek.h backup/ufo.h backup/yoko.h \
backup/z64.h \
patch/aps.h patch/bsl.h patch/gg.h patch/ips.h patch/pal4u.h \
patch/ppf.h patch/xps.h $(UCON64_STD_H)
console/dc.o: console/dc.h $(UCON64_STD_H)
console/gb.o: console/gb.h backup/mgd.h $(UCON64_STD_H)
console/gba.o: console/gba.h $(UCON64_STD_H)
console/genesis.o: console/genesis.h backup/smd.h backup/mgd.h $(UCON64_STD_H)
console/jaguar.o: console/jaguar.h $(UCON64_STD_H)
console/lynx.o: console/lynx.h $(UCON64_STD_H)
console/n64.o: console/n64.h $(UCON64_STD_H)
console/neogeo.o: console/neogeo.h $(UCON64_STD_H)
console/nes.o: console/nes.h $(UCON64_STD_H)
console/ngp.o: console/ngp.h $(UCON64_STD_H)
console/pce.o: console/pce.h backup/mgd.h $(UCON64_STD_H)
console/psx.o: console/psx.h $(UCON64_STD_H)
console/sms.o: console/sms.h backup/smd.h backup/mgd.h $(UCON64_STD_H)
console/snes.o: console/snes.h backup/mgd.h $(UCON64_STD_H)
console/swan.o: console/swan.h $(UCON64_STD_H)
backup/cd64.o: backup/cd64.h $(UCON64_STD_H)
backup/cmc.o: backup/cmc.h $(UCON64_STD_H)
backup/dex.o: backup/dex.h backup/psxpblib.h $(UCON64_STD_H)
backup/doctor64.o: backup/doctor64.h $(UCON64_STD_H)
backup/doctor64jr.o: backup/doctor64jr.h $(UCON64_STD_H)
backup/f2a.o: backup/f2a.h $(UCON64_STD_H)
backup/fal.o: backup/fal.h backup/cartlib.c $(UCON64_STD_H)
backup/ffe.o: backup/ffe.h $(UCON64_STD_H)
backup/fig.o: backup/fig.h console/snes.h $(UCON64_STD_H)
backup/gd.o: backup/gd.h console/snes.h $(UCON64_STD_H)
backup/gbx.o: backup/gbx.h $(UCON64_STD_H)
backup/lynxit.o: backup/lynxit.h $(UCON64_STD_H)
backup/mccl.o: backup/mccl.h $(UCON64_STD_H)
backup/mcd.o: backup/mcd.h $(UCON64_STD_H)
backup/md-pro.o: backup/md-pro.h backup/tototek.h $(UCON64_STD_H)
backup/mgd.o: backup/mgd.h $(UCON64_STD_H)
backup/msg.o: backup/msg.h backup/ffe.h $(UCON64_STD_H)
backup/pce-pro.o: backup/pce-pro.h backup/tototek.h $(UCON64_STD_H)
backup/pl.o: backup/pl.h $(UCON64_STD_H)
backup/psxpblib.o: backup/psxpblib.h $(UCON64_STD_H)
backup/sflash.o: backup/sflash.h backup/tototek.h $(UCON64_STD_H)
backup/smc.o: backup/smc.h backup/ffe.h $(UCON64_STD_H)
backup/smd.o: backup/smd.h backup/ffe.h $(UCON64_STD_H)
backup/smsgg-pro.o: backup/smsgg-pro.h backup/tototek.h $(UCON64_STD_H)
backup/swc.o: backup/swc.h backup/ffe.h console/snes.h $(UCON64_STD_H)
backup/tototek.o: backup/tototek.h $(UCON64_STD_H)
backup/ufo.o: backup/ufo.h $(UCON64_STD_H)
backup/yoko.o: backup/yoko.h $(UCON64_STD_H)
backup/z64.o: backup/z64.h $(UCON64_STD_H)
patch/aps.o: patch/aps.h $(UCON64_STD_H)
patch/bsl.o: patch/bsl.h $(UCON64_STD_H)
patch/gg.o: patch/gg.h $(UCON64_STD_H)
patch/ips.o: patch/ips.h $(UCON64_STD_H)
patch/pal4u.o: patch/pal4u.h $(UCON64_STD_H)
patch/ppf.o: patch/ppf.h $(UCON64_STD_H)
patch/xps.o: patch/xps.h $(UCON64_STD_H)

View File

@ -0,0 +1,380 @@
.PHONY: all clean distclean install uninstall
DLOPEN=1
#USE_ZLIB=1
USE_DISCMAGE=1
#USE_USB=1
USE_LIBCD64=1
CC=gcc
CFLAGS=-I. -Wall -W -O3 -DHAVE_CONFIG_H
LDFLAGS=-s
TARGETS=
ifdef USE_DISCMAGE
LIBNAME_DM=discmage
endif
# The test for Cygwin should be done before the test for DJGPP, because the
# environment variable DJGPP can be set under Bash for people who have
# installed both GCC (and friends) ports.
GCC_WIN=0
# test cygwin before DJGPP; OSTYPE is not exported on Cygwin
ifeq ($(TERM),cygwin)
GCC_WIN=1
endif
# test msys before DJGPP; MSYS, MinGW's POSIX build environment
ifeq ($(OSTYPE),msys)
GCC_WIN=1
endif
ifeq ($(GCC_WIN),1)
ifdef USE_DISCMAGE
FULLLIBNAME_DM=$(LIBNAME_DM).dll
ifndef DLOPEN
LDFLAGS+=libdiscmage/$(LIBNAME_DM).a
endif
endif
else
ifdef DJGPP
ifdef USE_DISCMAGE
FULLLIBNAME_DM=$(LIBNAME_DM).dxe
ifndef DLOPEN
LDFLAGS+=libdiscmage/$(LIBNAME_DM).a
endif
endif
else # Unix, BeOS or Mac OS X (Darwin)
ifeq ($(findstring openbsd,$(OSTYPE)),openbsd) # for example "openbsd3.4"
# i386_iopl() is located in libi386.a
LDFLAGS+=
endif
ifdef USE_DISCMAGE
ifeq ($(findstring darwin,$(OSTYPE)),darwin) # for example "darwin7.0"
FULLLIBNAME_DM=$(LIBNAME_DM).dylib
else
FULLLIBNAME_DM=$(LIBNAME_DM).so
endif
endif
ifdef DLOPEN
ifneq ($(OSTYPE),beos)
ifeq ($(findstring freebsd,$(OSTYPE)),) # false if OSTYPE contains "freebsd"
ifeq ($(findstring openbsd,$(OSTYPE)),) # false if OSTYPE contains "openbsd"
LDFLAGS+=-ldl
endif
endif
endif
else # DLOPEN
ifdef USE_DISCMAGE # GNU specific: "simply expanded variable"
FULLLIBNAME_DM:=$(addprefix lib,$(FULLLIBNAME_DM))
LDFLAGS+=-Llibdiscmage -l$(LIBNAME_DM)
endif
endif
endif # DJGPP
endif # GCC_WIN
TARGETS+=libdiscmage/$(FULLLIBNAME_DM)
ifdef USE_LIBCD64
LDFLAGS+=backup/libcd64/libcd64.a
TARGETS+=backup/libcd64/libcd64.a
endif
OBJECTS=ucon64.o ucon64_dat.o ucon64_misc.o ucon64_opts.o \
misc/chksum.o misc/file.o misc/getopt.o misc/getopt2.o \
misc/misc.o misc/parallel.o misc/property.o misc/string.o \
patch/aps.o patch/bsl.o patch/gg.o patch/ips.o patch/pal4u.o \
patch/ppf.o patch/xps.o \
console/dc.o console/gb.o console/gba.o console/genesis.o \
console/jaguar.o console/lynx.o console/n64.o console/neogeo.o \
console/nes.o console/ngp.o console/pce.o console/psx.o console/sms.o \
console/snes.o console/swan.o \
backup/cd64.o backup/cmc.o backup/dex.o backup/doctor64.o \
backup/doctor64jr.o backup/f2a.o backup/fal.o backup/ffe.o \
backup/fig.o backup/gbx.o backup/gd.o backup/interceptor.o \
backup/lynxit.o backup/mccl.o backup/mcd.o backup/md-pro.o \
backup/mgd.o backup/msg.o backup/pce-pro.o backup/pl.o \
backup/psxpblib.o backup/sflash.o backup/smc.o backup/smd.o \
backup/smsgg-pro.o backup/ssc.o backup/swc.o backup/tototek.o \
backup/ufo.o backup/yoko.o backup/z64.o
ifdef USE_ZLIB
LDFLAGS+=-lz
OBJECTS+=misc/archive.o misc/map.o misc/unzip.o
endif
ifdef USE_USB
LDFLAGS+=-lusb
OBJECTS+=misc/usb.o
endif
ifdef DLOPEN
OBJECTS+=misc/dlopen.o
ifndef USE_ZLIB
ifeq ($(GCC_WIN),1)
else
ifdef DJGPP # DJGPP code in dlopen needs map code
OBJECTS+=misc/map.o
endif # DJGPP
endif # GCC_WIN
endif # USE_ZLIB
else
ifeq ($(GCC_WIN),1) # Cygwin/MinGW code in ucon64_misc needs dlopen code
OBJECTS+=misc/dlopen.o
endif # GCC_WIN
endif # DLOPEN
TARGET=ucon64
ifeq ($(GCC_WIN),1)
TARGET:=$(addsuffix .exe,$(TARGET)) # adding .exe avoids "problems" with Cygwin/MinGW
else
ifdef DJGPP # OSTYPE is not defined by default under DOS
TARGET:=$(addsuffix .exe,$(TARGET))
endif # DJGPP
endif # GCC_WIN
TARGETS+=$(TARGET)
all: $(TARGETS)
CLEAN_CMD=rm -f $(TARGET) $(OBJECTS) *.core *.stackdump *~ */*~ */*/*~; \
cd libdiscmage && $(MAKE) clean; \
cd ../backup/libcd64 && $(MAKE) clean
clean:
ifeq ($(GCC_WIN),1)
$(CLEAN_CMD)
else
ifdef DJGPP
del *.o
del patch\*.o
del console\*.o
del backup\*.o
del misc\*.o
del $(TARGET)
cd libdiscmage
$(MAKE) clean
cd ../backup/libcd64
$(MAKE) clean
cd ../..
else # Unix, BeOS or Mac OS X (Darwin)
$(CLEAN_CMD)
endif # DJGPP
endif # GCC_WIN
DISTCLEAN_CMD=rm -f Makefile config.log config.status config.cache config.h; \
cd libdiscmage && $(MAKE) distclean; \
cd ../backup/libcd64 && $(MAKE) clean
# libcd64 Makefile has no distclean target
distclean: clean
ifeq ($(GCC_WIN),1)
$(DISTCLEAN_CMD)
else
ifdef DJGPP
del Makefile
del config.log
del config.status
del config.cache
del config.h
cd libdiscmage
$(MAKE) distclean
cd ../backup/libcd64
$(MAKE) clean
cd ../..
else
$(DISTCLEAN_CMD)
endif # DJGPP
endif # GCC_WIN
.c.o:
$(CC) $(CFLAGS) -c $< -o $@
backup/cd64.o: backup/cd64.c
$(CC) $(CFLAGS) -Ibackup/libcd64 -c $< -o $@
ifdef USE_DISCMAGE
libdiscmage/$(FULLLIBNAME_DM):
ifeq ($(GCC_WIN),1)
cd libdiscmage && $(MAKE)
else
ifdef DJGPP
cd libdiscmage
$(MAKE)
cd ..
else
cd libdiscmage && $(MAKE)
endif # DJGPP
endif # GCC_WIN
endif # USE_DISCMAGE
ifdef USE_LIBCD64
backup/libcd64/libcd64.a:
ifeq ($(GCC_WIN),1)
cd backup/libcd64 && $(MAKE)
else
ifdef DJGPP
cd backup/libcd64
$(MAKE)
cd ../..
else
cd backup/libcd64 && $(MAKE)
endif # DJGPP
endif # GCC_WIN
endif # USE_DISCMAGE
$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) $(LDFLAGS) -o $@
install:
ifeq ($(TERM),cygwin) # test cygwin before DJGPP
else
ifeq ($(OSTYPE),msys) # test msys before DJGPP
else
ifdef DJGPP
else
ifeq ($(OSTYPE),beos)
./install_beos.sh
else
./install.sh
endif # beos
endif # DJGPP
endif # msys
endif # cygwin
ifndef DLOPEN
cd libdiscmage && $(MAKE) install
endif
uninstall:
ifeq ($(TERM),cygwin) # test cygwin before DJGPP
else
ifeq ($(OSTYPE),msys) # test msys before DJGPP
else
ifdef DJGPP
else
ifeq ($(OSTYPE),beos)
rm -f $(HOME)/config/bin/$(TARGET)
else
rm -f /usr/local/bin/$(TARGET)
endif # beos
endif # DJGPP
endif # msys
endif # cygwin
ifndef DLOPEN
cd libdiscmage && $(MAKE) uninstall
endif
# Dependencies
# Most source files include these
UCON64_STD_H=ucon64.h ucon64_misc.h misc/misc.h config.h ucon64_defines.h
misc/archive.o: misc/archive.h misc/map.h config.h
misc/chksum.o: misc/chksum.h config.h
misc/dlopen.o: misc/dlopen.h misc/dxedll_pub.h config.h
misc/getopt.o: misc/getopt.h
misc/map.o: misc/map.h config.h
misc/misc.o: misc/misc.h misc/archive.h config.h
misc/parallel.o: misc/parallel.h config.h
misc/usb.o: misc/usb.h config.h
misc/unzip.o: misc/unzip.h config.h
ucon64.o: misc/dlopen.h misc/getopt.h ucon64_dat.h ucon64_opts.h \
console/dc.h console/gb.h console/gba.h console/genesis.h \
console/jaguar.h console/lynx.h console/n64.h console/neogeo.h \
console/nes.h console/ngp.h console/pce.h console/psx.h console/sms.h \
console/snes.h console/swan.h \
backup/cd64.h backup/dex.h backup/doctor64.h backup/doctor64jr.h \
backup/f2a.h backup/fal.h backup/ffe.h backup/fig.h backup/gbx.h \
backup/gd.h backup/interceptor.h backup/lynxit.h backup/mccl.h \
backup/mcd.h backup/md-pro.h backup/mgd.h backup/msg.h \
backup/pce-pro.h backup/pl.h backup/smc.h backup/smd.h \
backup/smsgg-pro.h backup/ssc.h backup/swc.h backup/tototek.h \
backup/ufo.h backup/yoko.h backup/z64.h \
patch/aps.h patch/bsl.h patch/gg.h patch/ips.h patch/pal4u.h \
patch/ppf.h patch/xps.h $(UCON64_STD_H)
ucon64_dat.o: ucon64_dat.h $(UCON64_STD_H)
ucon64_misc.o: misc/dlopen.h $(UCON64_STD_H)
ucon64_opts.o: misc/dlopen.h misc/getopt.h ucon64_dat.h ucon64_opts.h \
console/dc.h console/gb.h console/gba.h console/genesis.h \
console/jaguar.h console/lynx.h console/n64.h console/neogeo.h \
console/nes.h console/ngp.h console/pce.h console/psx.h \
console/sms.h console/snes.h console/swan.h \
backup/cd64.h backup/dex.h backup/doctor64.h \
backup/doctor64jr.h backup/f2a.h backup/fal.h backup/ffe.h \
backup/fig.h backup/gbx.h backup/gd.h backup/interceptor.h \
backup/lynxit.h backup/mccl.h backup/mcd.h backup/md-pro.h \
backup/mgd.h backup/msg.h backup/pce-pro.h backup/pl.h \
backup/smc.h backup/smd.h backup/smsgg-pro.h backup/ssc.h \
backup/swc.h backup/tototek.h backup/ufo.h backup/yoko.h \
backup/z64.h \
patch/aps.h patch/bsl.h patch/gg.h patch/ips.h patch/pal4u.h \
patch/ppf.h patch/xps.h $(UCON64_STD_H)
console/dc.o: console/dc.h $(UCON64_STD_H)
console/gb.o: console/gb.h backup/mgd.h $(UCON64_STD_H)
console/gba.o: console/gba.h $(UCON64_STD_H)
console/genesis.o: console/genesis.h backup/smd.h backup/mgd.h $(UCON64_STD_H)
console/jaguar.o: console/jaguar.h $(UCON64_STD_H)
console/lynx.o: console/lynx.h $(UCON64_STD_H)
console/n64.o: console/n64.h $(UCON64_STD_H)
console/neogeo.o: console/neogeo.h $(UCON64_STD_H)
console/nes.o: console/nes.h $(UCON64_STD_H)
console/ngp.o: console/ngp.h $(UCON64_STD_H)
console/pce.o: console/pce.h backup/mgd.h $(UCON64_STD_H)
console/psx.o: console/psx.h $(UCON64_STD_H)
console/sms.o: console/sms.h backup/smd.h backup/mgd.h $(UCON64_STD_H)
console/snes.o: console/snes.h backup/mgd.h $(UCON64_STD_H)
console/swan.o: console/swan.h $(UCON64_STD_H)
backup/cd64.o: backup/cd64.h $(UCON64_STD_H)
backup/cmc.o: backup/cmc.h $(UCON64_STD_H)
backup/dex.o: backup/dex.h backup/psxpblib.h $(UCON64_STD_H)
backup/doctor64.o: backup/doctor64.h $(UCON64_STD_H)
backup/doctor64jr.o: backup/doctor64jr.h $(UCON64_STD_H)
backup/f2a.o: backup/f2a.h $(UCON64_STD_H)
backup/fal.o: backup/fal.h backup/cartlib.c $(UCON64_STD_H)
backup/ffe.o: backup/ffe.h $(UCON64_STD_H)
backup/fig.o: backup/fig.h console/snes.h $(UCON64_STD_H)
backup/gd.o: backup/gd.h console/snes.h $(UCON64_STD_H)
backup/gbx.o: backup/gbx.h $(UCON64_STD_H)
backup/lynxit.o: backup/lynxit.h $(UCON64_STD_H)
backup/mccl.o: backup/mccl.h $(UCON64_STD_H)
backup/mcd.o: backup/mcd.h $(UCON64_STD_H)
backup/md-pro.o: backup/md-pro.h backup/tototek.h $(UCON64_STD_H)
backup/mgd.o: backup/mgd.h $(UCON64_STD_H)
backup/msg.o: backup/msg.h backup/ffe.h $(UCON64_STD_H)
backup/pce-pro.o: backup/pce-pro.h backup/tototek.h $(UCON64_STD_H)
backup/pl.o: backup/pl.h $(UCON64_STD_H)
backup/psxpblib.o: backup/psxpblib.h $(UCON64_STD_H)
backup/sflash.o: backup/sflash.h backup/tototek.h $(UCON64_STD_H)
backup/smc.o: backup/smc.h backup/ffe.h $(UCON64_STD_H)
backup/smd.o: backup/smd.h backup/ffe.h $(UCON64_STD_H)
backup/smsgg-pro.o: backup/smsgg-pro.h backup/tototek.h $(UCON64_STD_H)
backup/swc.o: backup/swc.h backup/ffe.h console/snes.h $(UCON64_STD_H)
backup/tototek.o: backup/tototek.h $(UCON64_STD_H)
backup/ufo.o: backup/ufo.h $(UCON64_STD_H)
backup/yoko.o: backup/yoko.h $(UCON64_STD_H)
backup/z64.o: backup/z64.h $(UCON64_STD_H)
patch/aps.o: patch/aps.h $(UCON64_STD_H)
patch/bsl.o: patch/bsl.h $(UCON64_STD_H)
patch/gg.o: patch/gg.h $(UCON64_STD_H)
patch/ips.o: patch/ips.h $(UCON64_STD_H)
patch/pal4u.o: patch/pal4u.h $(UCON64_STD_H)
patch/ppf.o: patch/ppf.h $(UCON64_STD_H)
patch/xps.o: patch/xps.h $(UCON64_STD_H)

View File

@ -0,0 +1,223 @@
DLOPEN=1
#USE_ZLIB=1
USE_DISCMAGE=1
#USE_USB=1
USE_LIBCD64=1
CC=cl.exe
CFLAGS=/nologo /I. /W3 /O2 /DHAVE_CONFIG_H
LDFLAGS=/NOLOGO setargv.obj
TARGETS=
!ifdef USE_DISCMAGE
LIBNAME_DM=discmage
!endif
!ifdef USE_DISCMAGE
FULLLIBNAME_DM=$(LIBNAME_DM).dll
!ifndef DLOPEN
LDFLAGS=$(LDFLAGS) libdiscmage/$(LIBNAME_DM).lib
!endif
!endif
TARGETS=$(TARGETS) libdiscmage/$(FULLLIBNAME_DM)
!ifdef USE_LIBCD64
LDFLAGS=$(LDFLAGS) backup/libcd64/cd64.lib
TARGETS=$(TARGETS) backup/libcd64/cd64.lib
!endif
OBJECTS=ucon64.obj ucon64_dat.obj ucon64_misc.obj ucon64_opts.obj \
misc/chksum.obj misc/file.obj misc/getopt.obj misc/getopt2.obj \
misc/misc.obj misc/parallel.obj misc/property.obj misc/string.obj \
misc/dlopen.obj \
patch/aps.obj patch/bsl.obj patch/gg.obj patch/ips.obj \
patch/pal4u.obj patch/ppf.obj patch/xps.obj \
console/dc.obj console/gb.obj console/gba.obj console/genesis.obj \
console/jaguar.obj console/lynx.obj console/n64.obj \
console/neogeo.obj console/nes.obj console/ngp.obj console/pce.obj \
console/psx.obj console/sms.obj console/snes.obj console/swan.obj \
backup/cd64.obj backup/cmc.obj backup/dex.obj backup/doctor64.obj \
backup/doctor64jr.obj backup/f2a.obj backup/fal.obj backup/ffe.obj \
backup/fig.obj backup/gbx.obj backup/gd.obj backup/interceptor.obj \
backup/lynxit.obj backup/mccl.obj backup/mcd.obj backup/md-pro.obj \
backup/mgd.obj backup/msg.obj backup/pce-pro.obj backup/pl.obj \
backup/psxpblib.obj backup/sflash.obj backup/smc.obj backup/smd.obj \
backup/smsgg-pro.obj backup/ssc.obj backup/swc.obj backup/tototek.obj \
backup/ufo.obj backup/yoko.obj backup/z64.obj
!ifdef USE_ZLIB
LDFLAGS=$(LDFLAGS) zlib.lib
OBJECTS=$(OBJECTS) misc/map.obj misc/archive.obj misc/unzip.obj
!endif
!ifdef USE_USB
LDFLAGS=$(LDFLAGS) usb.lib
OBJECTS=$(OBJECTS) misc/usb.obj
!endif
TARGET=ucon64.exe
TARGETS=$(TARGETS) $(TARGET)
all: $(TARGETS)
clean:
del *.obj
del patch\*.obj
del console\*.obj
del backup\*.obj
del misc\*.obj
del $(TARGET)
cd libdiscmage
$(MAKE) /NOLOGO /f Makefile.vc6 clean
cd ..\backup\libcd64
$(MAKE) /NOLOGO /f Makefile.vc6 clean
cd ..\..
distclean: clean
del config.h
cd libdiscmage
$(MAKE) /NOLOGO /f Makefile.vc6 distclean
cd ..\backup\libcd64
# libcd64 Makefile has no distclean target
$(MAKE) /NOLOGO /f Makefile.vc6 clean
cd ..\..
.c.obj:
$(CC) $(CFLAGS) /c $< /Fo$@
backup/cd64.obj:
$(CC) $(CFLAGS) /Ibackup/libcd64 /c $*.c /Fo$@
!ifdef USE_DISCMAGE
libdiscmage/$(FULLLIBNAME_DM):
cd libdiscmage
$(MAKE) /NOLOGO /f Makefile.vc6
cd ..
!endif
!ifdef USE_LIBCD64
backup/libcd64/cd64.lib:
cd backup/libcd64
$(MAKE) /NOLOGO /f Makefile.vc6
cd ../..
!endif
$(TARGET): $(OBJECTS)
link.exe $(OBJECTS) $(LDFLAGS) /OUT:$@
install:
cd libdiscmage
$(MAKE) /NOLOGO /f Makefile.vc6 install
cd ..
uninstall:
cd libdiscmage
$(MAKE) /NOLOGO /f Makefile.vc6 uninstall
cd ..
# Dependencies
# Most source files include these
UCON64_STD_H=ucon64.h ucon64_misc.h misc/misc.h config.h ucon64_defines.h
misc/archive.obj: misc/archive.h misc/map.h config.h
misc/chk.obj: misc/chksum.h config.h
misc/dlopen.obj: misc/dlopen.h misc/dxedll_pub.h config.h
misc/getopt.obj: misc/getopt.h
misc/map.obj: misc/map.h config.h
misc/misc.obj: misc/misc.h misc/archive.h config.h
misc/parallel.obj: misc/parallel.h config.h
misc/usb.obj: misc/usb.h config.h
misc/unzip.obj: misc/unzip.h config.h
ucon64.obj: misc/dlopen.h misc/getopt.h ucon64_dat.h ucon64_opts.h \
console/dc.h console/gb.h console/gba.h console/genesis.h \
console/jaguar.h console/lynx.h console/n64.h console/neogeo.h \
console/nes.h console/ngp.h console/pce.h console/psx.h \
console/sms.h console/snes.h console/swan.h \
backup/cd64.h backup/dex.h backup/doctor64.h backup/doctor64jr.h \
backup/f2a.h backup/fal.h backup/ffe.h backup/fig.h backup/gbx.h \
backup/gd.h backup/interceptor.h backup/lynxit.h backup/mccl.h \
backup/mcd.h backup/md-pro.h backup/mgd.h backup/msg.h \
backup/pce-pro.h backup/pl.h backup/smc.h backup/smd.h \
backup/smsgg-pro.h backup/ssc.h backup/swc.h backup/tototek.h \
backup/ufo.h backup/yoko.h backup/z64.h \
patch/aps.h patch/bsl.h patch/gg.h patch/ips.h patch/pal4u.h \
patch/ppf.h patch/xps.h $(UCON64_STD_H)
ucon64_dat.obj: ucon64_dat.h $(UCON64_STD_H)
ucon64_misc.obj: misc/dlopen.h $(UCON64_STD_H)
ucon64_opts.obj: misc/dlopen.h misc/getopt.h ucon64_dat.h ucon64_opts.h \
console/dc.h console/gb.h console/gba.h console/genesis.h \
console/jaguar.h console/lynx.h console/n64.h \
console/neogeo.h console/nes.h console/ngp.h console/pce.h \
console/psx.h console/sms.h console/snes.h console/swan.h \
backup/cd64.h backup/dex.h backup/doctor64.h \
backup/doctor64jr.h backup/f2a.h backup/fal.h backup/ffe.h \
backup/fig.h backup/gbx.h backup/gd.h backup/interceptor.h \
backup/lynxit.h backup/mccl.h backup/mcd.h backup/md-pro.h \
backup/mgd.h backup/msg.h backup/pce-pro.h backup/pl.h \
backup/smc.h backup/smd.h backup/smsgg-pro.h backup/ssc.h \
backup/swc.h backup/tototek.h backup/ufo.h backup/yoko.h \
backup/z64.h \
patch/aps.h patch/bsl.h patch/gg.h patch/ips.h patch/pal4u.h \
patch/ppf.h patch/xps.h $(UCON64_STD_H)
console/dc.obj: console/dc.h $(UCON64_STD_H)
console/gb.obj: console/gb.h backup/mgd.h $(UCON64_STD_H)
console/gba.obj: console/gba.h $(UCON64_STD_H)
console/genesis.obj: console/genesis.h backup/smd.h backup/mgd.h $(UCON64_STD_H)
console/jaguar.obj: console/jaguar.h $(UCON64_STD_H)
console/lynx.obj: console/lynx.h $(UCON64_STD_H)
console/n64.obj: console/n64.h $(UCON64_STD_H)
console/neogeo.obj: console/neogeo.h $(UCON64_STD_H)
console/nes.obj: console/nes.h $(UCON64_STD_H)
console/ngp.obj: console/ngp.h $(UCON64_STD_H)
console/pce.obj: console/pce.h backup/mgd.h $(UCON64_STD_H)
console/psx.obj: console/psx.h $(UCON64_STD_H)
console/sms.obj: console/sms.h backup/smd.h backup/mgd.h $(UCON64_STD_H)
console/snes.obj: console/snes.h backup/mgd.h $(UCON64_STD_H)
console/swan.obj: console/swan.h $(UCON64_STD_H)
backup/cd64.obj: backup/cd64.h $(UCON64_STD_H)
backup/cmc.obj: backup/cmc.h $(UCON64_STD_H)
backup/dex.obj: backup/dex.h backup/psxpblib.h $(UCON64_STD_H)
backup/doctor64.obj: backup/doctor64.h $(UCON64_STD_H)
backup/doctor64jr.obj: backup/doctor64jr.h $(UCON64_STD_H)
backup/f2a.obj: backup/f2a.h $(UCON64_STD_H)
backup/fal.obj: backup/fal.h backup/cartlib.c $(UCON64_STD_H)
backup/ffe.obj: backup/ffe.h $(UCON64_STD_H)
backup/fig.obj: backup/fig.h console/snes.h $(UCON64_STD_H)
backup/gd.obj: backup/gd.h console/snes.h $(UCON64_STD_H)
backup/gbx.obj: backup/gbx.h $(UCON64_STD_H)
backup/lynxit.obj: backup/lynxit.h $(UCON64_STD_H)
backup/mcd.obj: backup/mcd.h $(UCON64_STD_H)
backup/mccl.obj: backup/mccl.h $(UCON64_STD_H)
backup/md-pro.obj: backup/md-pro.h backup/tototek.h $(UCON64_STD_H)
backup/mgd.obj: backup/mgd.h $(UCON64_STD_H)
backup/msg.obj: backup/msg.h backup/ffe.h $(UCON64_STD_H)
backup/pce-pro.obj: backup/pce-pro.h backup/tototek.h $(UCON64_STD_H)
backup/pl.obj: backup/pl.h $(UCON64_STD_H)
backup/psxpblib.obj: backup/psxpblib.h $(UCON64_STD_H)
backup/sflash.obj: backup/sflash.h backup/tototek.h $(UCON64_STD_H)
backup/smc.obj: backup/smc.h backup/ffe.h $(UCON64_STD_H)
backup/smd.obj: backup/smd.h backup/ffe.h $(UCON64_STD_H)
backup/smsgg-pro.obj: backup/smsgg-pro.h backup/tototek.h $(UCON64_STD_H)
backup/swc.obj: backup/swc.h backup/ffe.h console/snes.h $(UCON64_STD_H)
backup/tototek.obj: backup/tototek.h $(UCON64_STD_H)
backup/ufo.obj: backup/ufo.h $(UCON64_STD_H)
backup/yoko.obj: backup/yoko.h $(UCON64_STD_H)
backup/z64.obj: backup/z64.h $(UCON64_STD_H)
patch/aps.obj: patch/aps.h $(UCON64_STD_H)
patch/bsl.obj: patch/bsl.h $(UCON64_STD_H)
patch/gg.obj: patch/gg.h $(UCON64_STD_H)
patch/ips.obj: patch/ips.h $(UCON64_STD_H)
patch/pal4u.obj: patch/pal4u.h $(UCON64_STD_H)
patch/ppf.obj: patch/ppf.h $(UCON64_STD_H)
patch/xps.obj: patch/xps.h $(UCON64_STD_H)

View File

@ -0,0 +1,118 @@
Legend for Code1:
0 = seems to work without modification
1 = needs crack (uCON64 option -k)
2 = needs NTSC/PAL fix (uCON64 option -f)
3 = needs backup unit header fix
4 = seems to work, but doesn't work correctly
5 = music doesn't work
6 = copy protection screen
7 = wrong television standard (NTSC/PAL) screen
8 = corrupted/distorted graphics
9 = doesn't work
Legend for Code2:
N1 = 3f 21 29/89 10 f0 3f 21 29/89 10 80
N2 = ad 3f 21 29 10 d0 ad 3f 21 29 10 ea ea
P3 = ad 3f 21 89 10 d0 ad 3f 21 89 10 80 - Terranigma
N4 = ad 3f 21 89 10 d0 ad 3f 21 89 10 80/(ea ea) - Live A Live
N5 = 3f 21 29/89 10 00 f0 3f 21 29/89 10 00 80 - Clock Tower
N6 = 3f 21 29/89 10 00 d0 3f 21 29/89 10 00 ea ea - Mario no Super Picross
P7 = ad 3f 21 29 10 00 d0 ad 3f 21 29 10 00 80
P8 = ad 3f 21 89 10 00 d0 a9 10 00 89 10 00 d0 - Eric Cantona Football ?
N9 = 3f 21 89 10 c2 XX f0 3f 21 89 10 c2 XX 80 - Front Mission - Gun Hazard
N10 = 3f 21 89 10 c2 XX d0 3f 21 89 10 c2 XX ea ea - Robotrek
N11 = 3f 21 29/89 10 c9 10 f0 3f 21 29/89 10 c9 10 80
N12 = ad 3f 21 29 10 c9 00 f0 ad 3f 21 29 10 c9 00 80/(ea ea) <= original uCON used 80
N13 = ad 3f 21 29 10 c9 00 d0 ad 3f 21 29 10 c9 00 80
N14 = ad 3f 21 29 10 c9 10 d0 ad 3f 21 29 10 c9 10 ea ea
P15 = ad 3f 21 29 10 cf bd ff XX f0 ad 3f 21 29 10 cf bd ff XX 80 - Pop'n Twinbee E
N16 = 3f 21 29 10 cf XX YY 80 f0 3f 21 29 10 cf XX YY 80 80 - Gokujyou Parodius/Tokimeki Memorial
N17 = ad 3f 21 8d XX YY 29 10 8d ad 3f 21 8d XX YY 29 00 8d - Dragon Ball Z - Super Butoden 2 ?
N18 = 3f 21 00 29/89 10 f0 3f 21 00 29/89 10 80 - Kirby's Dream Course U
P19 = af 3f 21 00 29 10 d0 af 3f 21 00 29 10 80
N20 = af 3f 21 00 29/89 10 d0 af 3f 21 00 29/89 10 ea ea - Kirby no Kirakira Kids/Final Fight Guy
P21 = af 3f 21 00 29 10 00 d0 af 3f 21 00 29 10 00 ea ea
N22 = af 3f 21 00 29/89 10 00 f0 af 3f 21 00 29/89 10 00 80
P23 = af 3f 21 00 29 XX c9 XX f0 af 3f 21 00 29 XX c9 XX 80 - Secret of Mana E
N24 = af 3f 21 00 29 XX c9 XX f0 af 3f 21 00 29 XX c9 XX 80 - Seiken Densetsu 3
N25 = af 3f 21 00 29 10 80 2d 00 1b af 3f 21 00 29 00 80 2d 00 1b - Seiken Densetsu 2/Secret of Mana U
N26 = 3f 21 00 89 10 c2 XX f0 3f 21 00 89 10 c2 XX 80 - Dragon - The Bruce Lee Story U
N27 = af 3f 21 00 XX YY 29 10 00 d0 af 3f 21 00 XX YY 29 10 00 ea ea - Fatal Fury Special ?
N28 = 3f 21 c2 XX 29 10 00 f0 3f 21 c2 XX 29 10 00 80 - Metal Warriors
N29 = 3f 21 c2 XX 29 10 00 d0 3f 21 c2 XX 29 10 00 ea ea - Dual Orb II
N30 = af 3f 21 ea 89 10 00 d0 a9 00 00 ea 89 10 00 d0 - Super Famista 3 ?
P31 = a2 18 01 bd 27 20 89 10 00 f0 01 a2 18 01 bd 27 20 89 10 00 ea ea - Donkey Kong Country E
N32 = a2 18 01 bd 27 20 89 10 00 d0 01 a2 18 01 bd 27 20 89 10 00 ea ea - Donkey Kong Country U
N33 = 29 10 00 a2 00 00 c9 10 00 d0 29 10 00 a2 00 00 c9 10 00 80 - Wolfenstein 3D U
Comment:
Code1 is valid for an SWC 2.8cc 32 Mbit PAL. For example Terranigma has a Code1
of 0, but a Code2 of P3, because it runs without modification on a PAL SNES but
needs an NTSC/PAL fix for an NTSC SNES.
The prefix N indicates an NTSC protection code, the prefix P indicates a PAL
protection code. Cracking or fixing an NTSC protection code makes a game run
on a PAL SNES and vice versa.
Code1 Code2 Game
2 N5 Clock Tower (J) <= 0x29
1 + 2 N1 Demon's Crest (U) <= (0xad) 0x29
1 + 2 + 4 N6 Donkey Kong Country 2 - Diddy's Kong Quest (U) (V1.1) <= can't get past the first level; 0x29
1 P31 Donkey Kong Country (E) (V1.0)
1 P31 Donkey Kong Country (E) (V1.1)
1 + 2 N32 Donkey Kong Country (U) (V1.0)
1 + 2 N32 Donkey Kong Country (U) (V1.1)
2 N26 Dragon - The Bruce Lee Story (U)
2 N4 Dr. Mario (J) (NP) <= 0xea 0xea
2 N29 Dual Orb II (J)
1 + 2 N18 Earthbound (U) <= 0x29
2 + 3 N1 Final Fight 3 (U) <= emulation mode select byte: 0x1c; (0xad) 0x29
2 N20 Final Fight Guy (U) <= 0x89
2 + 3 N1 Final Fight Tough (J) <= emulation mode select byte: 0x1c; (0xad) 0x29
1 + 2 N9 Front Mission - Gun Hazard (J) <= modification protection; code 0 for NTSC SNES; 0x20
2 N16 Gokujou Parodius (J) <= 0xad 0xff
2 N1 Illusion of Gaia (U) <= (0xad) 0x89
2 + 9 N16 Jikkyou Oshaberi Parodius (J) <= 0xad 0xff
2 N1 Joe & Mac 2 - Lost in the Tropics (U) (35468) <= (0xad) 0x29
2 N1 Joe & Mac 2 - Lost in the Tropics (U) (54227) <= (0xad) 0x29
2 + 9 N5 Kaite Tukutte Asoberu Dezaemon (J) <= 0x89
2 N20 Kirby no Kirakira Kids (J) (NP) <= 0x29
1 + 2 N18 Kirby's Dream Course (U) <= 0x29
2 N4 Live A Live (J) <= 0xea 0xea
2 N28 Magical Pop'n (J)
1 + 2 N6 Mario no Super Picross (J) <= 0x89
2 N1 Mega Man's Soccer (U) <= (0xad) 0x89
2 N1 Mega Man VII (U) <= (0xad) 0x29
2 + 9 N1 Mega Man X 2 (U) <= the intro can be viewed; (0xad) 0x89
1 + 2 N1 Mega Man X (U) (V1.0) <= (0xad) 0x89
1 + 2 N1 Mega Man X (U) (V1.1) <= (0xad) 0x89
2 N28 Metal Warriors (U)
2 + 3 N1 + N2 Mickey to Donald Magical Adventure 3 (J) <= emulation mode select byte: 0x1c; (0xad) 0x29
2 N2 Ninja Gaiden Trilogy (U)
0 P15 Pop'n Twinbee (E) <= 0x80
0 P15 Pop'n Twinbee - Rainbow Bell Adventures (E) <= 0x00
2 N10 Robotrek (U) <= 0x20
2 N18 Romancing Sa-Ga 2 (J) <= 0x89
2 N18 Romancing Sa-Ga 3 (J) (V1.0) <= 0x89
2 N18 Romancing Sa-Ga 3 (J) (V1.1) <= 0x89
2 N25 Secret of Mana (U)
0 P23 Secret of Mana (E) (V1.0) <= 0x10 0x10
0 P23 Secret of Mana (E) (V1.1) <= 0x10 0x10
2 N25 Seiken Densetsu 2 (J)
2 N24 Seiken Densetsu 3 (J) <= 0x10 0x00
2 N1 Street Fighter II Turbo (U) <= (0xad) 0x29
1 + 2 N1 Super Mario All-Stars (U) <= (0xad) 0x89
1 + 2 N1 Super Mario All-Stars & World (U) <= (0xad) 0x89
1 + 2 N1 Super Mario Collection (J) (V1.1) <= (0xad) 0x89
1 + 2 N1 Super Metroid (JU) <= (0xad) 0x89
0 P3 Terranigma (E)
1 P3 Tetris Attack (E)
1 + 2 N1 Tetris Attack (U) <= (0xad) 0x89
2 + 8 + 9 N16 Tokimeki Memorial - Densetsu no Ki no Shita de (J) (V1.1) <= the game halts after a while; 0xad 0xff
2 N33 Wolfenstein 3D (U)
2 N1 Yoshi's Safari (U) <= I don't have a Super Scope...; (0xad) 0x29
2 N2 Ys V - Expert (J)
EOF

View File

@ -0,0 +1,419 @@
A Super Wild Card compatibility list
Version: 1.27
Author: dbjh "of uCON64" with great help from CL "of NSRT" and The Dumper
Date: 30 November 2003
Hardware: Super Wild Card 2.8cc 32 Mbit PAL
Software: uCON64 1.9.8-3
Legend:
0 = seems to work without modification
1 = needs crack (uCON64 option -k)
2 = needs NTSC/PAL fix (uCON64 option -f)
3 = needs backup unit header fix
4 = seems to work, but doesn't work correctly
5 = music doesn't work
6 = copy protection screen
7 = wrong television standard (NTSC/PAL) screen
8 = corrupted/distorted graphics
9 = doesn't work
Comment:
I use the word seems, because I have tested most games only for a few minutes
or so. Even for games that I played from the beginning till the end I can't be
sure if they run as they do from a cartridge.
Of course I tried to crack or fix the games that displayed a copy protection
screen. The games that have that code can't be cracked with uCON64.
Non-playing music seems to be a BS-specific problem.
For some games I put an extra comment after the character sequence "<=". In
some comments I mention the so-called emulation mode select byte. This is the
byte at offset 2 in the header. You can check the value of the emulation mode
select byte by passing the command line option -dbuh to uCON64. You can change
it with a hex(adecimal) editor or by using the uCON64 option -poke (new in
version 1.9.8beta8). For example, to change the emulation mode select byte for
Mickey to Donald Magical Adventure 3 (J).swc you would type:
ucon64 -poke=2:1c "Mickey to Donald Magical Adventure 3 (J).swc"
I have sent all games to the Super Wild Card via a parallel cable. Note that
for LoROM games that don't use SRAM uCON64 adjusts the emulation mode select
byte before sending the game. This causes that some games don't have code 3,
because uCON64 already makes the required modification. For example, if Addams
Family Values is loaded from diskette the emulation mode select byte should
have the value 0x2c instead of the value 0x0c (before the file is split).
For games marked with an asterisk uCON64 1.9.8-3 is required (or an updated
version of snescopy.txt and/or snesntsc.txt/snespal.txt).
Code Game
0 - 7th Saga, The (U)
0 - AAAHH!!! Real Monsters (U)
8 + 9 - Ace wo Nerae! (J) <= it does work with Super Mario Kart (E) plugged in
0 - ActRaiser 2 (E)
4 - ActRaiser 2 (U) <= level(s?) (Industen) can't be entered
0 - ActRaiser (U)
0 - Addams Family, The (E)
0 - Addams Family, The - Pugsley's Scavenger Hunt (Beta)
0 - Addams Family, The - Pugsley's Scavenger Hunt (E)
0 - Addams Family Values (E)
0 - Adventures of Batman & Robin, The (E)
0 - Aladdin (E)
0 - Alcahest (J)
0 - Alfred Chicken (E) (4285)
0 - Alfred Chicken (E) (6937)
0 - Alfred Chicken (U)
0 - Alien 3 (E)
0 - Alien vs. Predator (U)
0 - Another World (E)
0 - Arabian Nights - Sabaku no Seirei Ou (J)
0 - Arcade's Greatest Hits (E)
0 - Axelay (E)
0 - Bahamut Lagoon (J)
0 - Bastard!! Ankoku no Hakai-shin (J)
0 - Batman Returns (E)
0 - Batman Returns (J)
3 - Batman - Revenge of the Joker (U) <= emulation mode select byte: 0x0c
0 - Battletoads & Double Dragon - The Ultimate Team (U)
0 - Battletoads in Battlemaniacs (U) (26454)
0 - Beauty and the Beast (E)
0 - Bishoujo Senshi Sailor Moon (J)
0 - Brawl Brothers (U)
1 - Breath of Fire II (E)
0 - Breath of Fire (U)
9 - BS Bandai Satellaview-X BIOS
0 - BS Chrono Trigger - Character Library (J)
0 - BS Chrono Trigger - Jet Bike Special (J)
0 - BS Chrono Trigger - Music Library (J)
8 - BS Dan Dan Belt Conveyor Ukulele no Maki (J) (NG-Dump Known)
0 - BS Dr. Mario (J)
0 - BS Dynami Tracer (J)
0 - BS F-Zero Grand Prix 2 (J)
0 - BS Koi ha Balance - Battle of Lovers (J)
5 - BS Mario Collection 3 (J)
8 - BS Pokekame Magajin (J)
9 - BS Radical Dreamers (J) [f1] <= with the translation patch it does work
9 - BS Radical Dreamers (J) <= idem
0 - BS Super Earth Defense Force (J)
0 - BS Super Famicom Wars (J) [h1]
0 - BS Super Famicom Wars (J)
5 - BS Super Mario USA 4 (J)
8 - BS Treasure Conflix (J)
0 - BS Wai Wai Check 3-7th (J)
0 - BS Wario no Mori (J)
0 - BS Yoshi no Panepon (J)
0 - BS Zelda no Densetsu - Kamigami no Triforce (J)
9 - BS Zelda no Densetsu Kodai no Sekiban Dai 1 Hanashi (J)
9 - BS Zelda no Densetsu Kodai no Sekiban Dai 3 Hanashi (J)
1 - BS Zelda no Densetsu Remix (J)
0 - BS Zootto Mahjong! Event Version (J)
0 - Bubsy II (U)
0 - Bubsy in Claws Encounters of the Furred Kind (E)
0 - Castlevania - Vampire's Kiss (E)
0 - Choh Makai-Mura (J)
0 - Choplifter III (U) (30545)
0 - Chou Jikuu Yousai Macross - Scrambled Valkyrie (J)
0 - Chrono Trigger - Kurono Toriga (J)
0 - Chrono Trigger (U)
0 - Chuck Rock (U)
0 - Clay Fighter 2 - Judgment Clay (E)
0 - Clay Fighter (E)
7 - Clay Fighter (U)
2 - Clock Tower (J)
0 - Contra III - The Alien Wars (U)
0 - Cybernator (U)
0 - Daffy Duck - The Marvin Missions (U)
7 - Dai-3-Ji Super Robot Taisen (J)
9 - Daikaijuu Monogatari 2 (J) <= works on an SWC DX2 64 Mbit PAL
0 - Darius Twin (E)
0 - Darius Twin (U)
1 + 2 - Demon's Crest (U)
0 - Der Langrisser (J) (V1.1)
0 - Desert Strike - Return to the Gulf (U)
9 - Dirt Trax FX (E)
0 - Donald Duck Mahou no Boushi (J)
1 - Donkey Kong Country 2 - Diddy's Kong Quest (E)
1+2+4 - Donkey Kong Country 2 - Diddy's Kong Quest (U) (V1.1) <= can't get past the first level
1 - Donkey Kong Country 3 - Dixie Kong's Double Trouble (E)
0 - Donkey Kong Country - Competition Cartridge (U)
1 - Donkey Kong Country (E) (V1.0)
1 - Donkey Kong Country (E) (V1.1)
1 + 2 - Donkey Kong Country (U) (V1.0)
1 + 2 - Donkey Kong Country (U) (V1.1)
9 - Doom (U)
0 - Doraemon - Nobita to Yosei no Kuni (J)
0 - Dragon Quest I & II (J)
0 - Dragon Quest III (J)
0 - Dragon Quest VI (J)
0 - Dragon Quest V (J)
0 - Dragon's Lair (Beta)
0 - Dragon's Lair (E)
0 - Dragon - The Bruce Lee Story (E) [a1]
2 - Dragon - The Bruce Lee Story (U)
2 - Dr. Mario (J) (NP)
2 - Dual Orb II (J)
1 + 2 - Earthbound (U)
0 - Earthworm Jim 2 (U)
0 - Earthworm Jim (U)
0 - Eek! The Cat (E)
0 - E.V.O. Search For Eden (U)
0 - F-1 Grand Prix (J)
8 + 9 - F1 ROC II - Race of Champions (U) <= course is not visible
0 - Final Fantasy III (U) (V1.0)
0 - Final Fantasy III (U) (V1.1)
0 - Final Fantasy II (U) (V1.0)
0 - Final Fantasy IV (J)
0 - Final Fantasy - Mystic Quest (U) (V1.0)
0 - Final Fantasy VI (J)
0 - Final Fantasy V (J)
0 - Final Fight 2 (E)
2 + 3 - Final Fight 3 (U) <= emulation mode select byte: 0x1c
2 - Final Fight Guy (U)
2 + 3 - Final Fight Tough (J) <= emulation mode select byte: 0x1c
0 - Final Fight (U)
0 - Flashback (E) (M2)
0 - Frogger (U)
1*+2* - Front Mission - Gun Hazard (J) <= modification protection; code 0 for NTSC SNES
0 - Front Mission (J) (V1.0)
0 - F-Zero (E)
0 - Ganbare Goemon - Yuki hime Kyuushuutsu emaki (J) (V1.2)
0 - Ganpuru - Gunman's Proof (J)
2 - Gokujou Parodius (J)
0 - Goof Troop (E)
0 - Gradius III (U)
0 - Harvest Moon (U)
9 - Hayazashi Nidan Morita Shogi 2 (J) <= halts on "TRANSMIT WAIT"
0 - Hebereke's Popoitto (E)
9 - Hoshi no Kirby 3 (J)
2 - Illusion of Gaia (U)
0 - Illusion of Time (E)
0 - International Superstar Soccer Deluxe (E)
0 - International Superstar Soccer (E)
0 - Itchy & Scratchy Game, The (E) <= was 8 + 9!?
2 + 9 Jikkyou Oshaberi Parodius (J)
2 - Joe & Mac 2 - Lost in the Tropics (U) (35468)
2 - Joe & Mac 2 - Lost in the Tropics (U) (54227)
0 - Joe & Mac - Caveman Ninja (E)
0 - Joe & Mac (U)
0 - J.R.R. Tolkien's The Lord of the Rings - Volume 1 (U)
0 - Juutei Senki (J)
2 + 9 - Kaite Tukutte Asoberu Dezaemon (J)
0 - Kiki KaiKai - Nazo no Kuro Manto (J)
1 - Killer Instinct (E)
2 - Kirby no Kirakira Kids (J) (NP)
1 - Kirby's Dream Course (E)
1 + 2 - Kirby's Dream Course (U)
9 - Kirby's Dream Land 3 (U)
9 - Kirby's Fun Pak (E)
0 - Kirby's Ghost Trap (E)
0 - Krusty's Super Fun House (U) (V1.1)
0 - Legend of The Mystical Ninja, The (E)
0 - Legend of Zelda, The - A Link to the Past (E)
0 - Legend of Zelda, The - A Link to the Past (U)
0 - Lemmings (E)
2 - Live A Live (J)
0 - Lost Vikings II, The (E)
0 - Lost Vikings, The (U)
1 - Lufia II - Rise of the Sinistrals (H)
1 - Lufia II - Rise of the Sinistrals (U)
0 - Lufia & The Fortress of Doom (U)
0 - Magical Drop (J)
2 - Magical Pop'n (J)
0 - Magical Quest Starring Mickey Mouse, The (Beta)
0 - Magical Quest Starring Mickey Mouse, The (E)
0 - Magical Quest Starring Mickey Mouse, The (U)
1 + 2 - Mario no Super Picross (J)
0 - Mario Paint (E) <= I don't have a SNES mouse...
0 - Mario & Wario (J) <= idem
9 - Masou Kishin - Super Robot Taisen Gaiden - The Lord of Elemental (J)
2 - Mega Man's Soccer (U)
2 - Mega Man VII (U)
9 - Mega Man X 2 (E) <= the intro can be viewed
2 + 9 - Mega Man X 2 (U) <= idem
8 + 9 - Mega Man X 3 (U) <= game can be started, but sprites are not visible
1 - Mega Man X (E)
1 + 2 - Mega Man X (U) (V1.0)
1 + 2 - Mega Man X (U) (V1.1)
8 + 9 - Metal Combat - Falcon's Revenge (U) <= sprites are not visible
2 - Metal Warriors (U)
2 + 3 - Mickey to Donald Magical Adventure 3 (J) <= emulation mode select byte: 0x1c
0 - Micro Machines 2 - Turbo Tournament (E)
0 - Micro Machines (U)
9 - Momotarou Dentetsu Happy (J) <= halts on "SPC7110 check program v3.0"
0 - Mortal Kombat 3 (E)
0 - Mortal Kombat (Beta)
0 - Mortal Kombat (E)
0 - Mortal Kombat II (E) (V1.0)
0 - Mortal Kombat II (U) (V1.1)
0 - NBA Jam (Beta)
0 - NBA Jam (E) (V1.0)
2 - Ninja Gaiden Trilogy (U)
0 - Ogre Battle - The March of the Black Queen (U)
0 - Out of This World (U)
0 - Parodius Da! Shinwa kara Owarai he (J)
0 - Parodius - Non-Sense Fantasy (E)
0 - Phalanx - The Enforce Fighter A-144 (E)
9 - Pilotwings (E) <= black screen as soon as the real flying begins
9 - Pilotwings (U) <= with the DSP patch it does work with Super Mario Kart (E)
0 - Pitfall - The Mayan Adventure (Beta)
0 - Pitfall - The Mayan Adventure (E)
0 - Pocky & Rocky 2 (U) (54250)
0 - Pocky & Rocky (E)
0 - Pop'n Twinbee (E)
0 - Pop'n Twinbee - Rainbow Bell Adventures (E)
0 - Primal Rage (E)
0 - Primal Rage (U) (With Sound Test)
0 - Prince of Persia 2 - The Shadow & The Flame (E)
0 - Prince of Persia (E)
0 - Prince of Persia (J)
0 - Push-Over (E)
0 - Puzzle Bobble (E)
0 - Ranma Nibun no Ichi - Akanekodan no Hihou (J)
0 - Ranma Nibun no Ichi - Hard Battle (U)
2 - Robotrek (U)
0 - Rockman & Forte (J)
0 - Rock N' Roll Racing (E)
0 - Romance of the Three Kingdoms IV - Wall of Fire (U)
2 - Romancing Sa-Ga 2 (J)
2 - Romancing Sa-Ga 3 (J) (V1.0)
2 - Romancing Sa-Ga 3 (J) (V1.1)
0 - Romancing Sa-Ga (J) (V1.0)
0 - RPG Tsukuru 2 (J)
0 - R-Type III - The Third Lightning (E) (21451)
0 - Rudra no Hihou (J)
0 - Sanrio World Smash Ball! (J)
0 - Secret of Evermore (U)
0 - Secret of Mana (E) (V1.0)
0 - Secret of Mana (E) (V1.1)
2 - Secret of Mana (U)
2 - Seiken Densetsu 2 (J)
0 - Seiken Densetsu 3 (J) (Sample)
2 - Seiken Densetsu 3 (J)
0 - Shadowrun (E)
0 - Shin Megami Tensei (J) (V1.0)
0 - Sim Ant (U) (37113)
0 - Sim City (E)
0 - Sim City (U)
0 - Simpsons, The - Bart's Nightmare (U)
0 - Smash Tennis (E)
0 - Smurfs, The (E)
0 - Soldiers of Fortune (U)
0 - Sonic the Hedgehog (Unl) [p1][h1]
0 - Soul Blazer (U)
0 - Spider-Man and the X-Men in Arcade's Revenge (E)
9 - Star Fox 2 (Beta)
9 - Star Fox 2 (Beta TD)
9 - Star Fox Super Weekend Competition (U)
9 - Star Fox (U) (V1.0)
9 - Star Fox (U) (V1.2)
9 - Star Ocean (J)
9 - StarWing (E) (V1.0)
9 - StarWing (E) (V1.1)
9 - Street Fighter Alpha 2 (E) [b1]
9 - Street Fighter Alpha 2 (E)
9 - Street Fighter Alpha 2 (U)
0 - Street Fighter II Champ. Edition (Hack)
0 - Street Fighter II - The World Warrior (E)
0 - Street Fighter II - The World Warrior (U)
0 - Street Fighter II Turbo (E) (V1.1)
2 - Street Fighter II Turbo (U)
9 - Street Fighter Zero 2 (J)
0 - Street Racer (Beta)
0 - Street Racer (E)
0 - Strike Gunner (E)
9 - Stunt Race FX (E)
0 - Sunset Riders (E)
0 - Super Adventure Island II (U)
0 - Super Adventure Island (U)
0 - Super Aleste (E)
0 - Super Aleste (J)
0 - Super Aleste (J) [t1]
0 - Super Battletank - War in the Gulf (U) (V1.0)
0 - Super Bomberman 2 (E)
0 - Super Bomberman 3 (E)
0 - Super Bomberman 4 (J)
0 - Super Bomberman 5 (J)
0 - Super Bomberman (E)
0 - Super Castlevania IV (E)
0 - Super Earth Defense Force (E)
0 - Super Famicom Wars (J) (NP)
0 - Super Ghouls 'N Ghosts (E)
1 - Super Mario All-Stars (E)
1 + 2 - Super Mario All-Stars (U)
1 - Super Mario All-Stars & World (E)
1 + 2 - Super Mario All-Stars & World (U)
1 + 2 - Super Mario Collection (J) (V1.1)
9 - Super Mario Kart (E) <= it does work with Super Mario Kart (E) plugged in
9 - Super Mario Kart (U) <= idem
9 - Super Mario RPG (J) (V1.0)
9 - Super Mario RPG (J) (V1.1) (NG-Dump Known)
9 - Super Mario RPG - Legend of the Seven Stars (U)
9 - Super Mario World 2 - Yoshi's Island (E) (V1.0)
0 - Super Mario World (E) (V1.1)
0 - Super Mario World (U)
1 - Super Metroid (E)
1 + 2 - Super Metroid (JU)
0 - Super NES Super Scope 6 (U) <= I don't have a Super Scope...
0 - Super Off Road (U)
0 - Super Power League 3 (J)
9 - Super Power League 4 (J) <= halts on "SPC7110 check program v3.0"
0 - Super Probotector - The Alien Rebels (E)
0 - Super Punch-Out!! (U)
0 - Super Puyo Puyo (J) (V1.2)
0 - Super R-Type (E)
0 - Super R-Type (U)
0 - Super Smash T.V. (E)
0 - Super Smash T.V. (U)
0 - Super Star Wars (E)
0 - Super Star Wars - Return of the Jedi (E)
0 - Super Star Wars - The Empire Strikes Back (Beta)
0 - Super Star Wars - The Empire Strikes Back (E)
0 - Super Star Wars - The Empire Strikes Back (U) (V1.1)
0 - Super Star Wars (U) (31438)
0 - Super Street Fighter II - The New Challengers (E)
0 - Super Tennis (E) (V1.0)
0 - Super Turrican (E)
0 - Syndicate (E)
0 - T2 - The Arcade Game (U)
0 - Tactics Ogre - Let Us Cling Together (J) (V1.2)
9 - Tales of Phantasia (J) <= works on an SWC DX2 64 Mbit PAL
0 - Teenage Mutant Hero Turtles IV - Turtles in Time (E)
0 - Teenage Mutant Hero Turtles - Tournament Fighters (E)
0 - Teenage Mutant Ninja Turtles IV - Turtles in Time (A)
0 - Teenage Mutant Ninja Turtles IV - Turtles in Time (Beta)
0 - Teenage Mutant Ninja Turtles - Turtles in Time (J)
0 - Tenchi Muyou! Game Hen (J)
9 - Tengai Makyou Zero (J)
9 - Tengai Makyou Zero - Shounen Jump no Sho (J)
0 - Terranigma (E)
0 - Terranigma (S)
0 - Test Drive II - The Duel (U) (20429)
1 - Tetris Attack (E)
1 + 2 - Tetris Attack (U)
0 - Theme Park (E)
0 - Thoroughbred Breeder III (J)
0 - Tiny Toon Adventures - Buster Busts Loose! (E)
2+8+9 - Tokimeki Memorial - Densetsu no Ki no Shita de (J) (V1.1) <= the game halts after a while
0 - Tom & Jerry (U)
0 - Top Racer (J)
0 - Treasure Hunter G (J)
0 - Ultimate Mortal Kombat 3 (U)
0 - Ultima VII - The Black Gate (Beta)
0 - Ultima VII - The Black Gate (U)
1 - Uniracers (U)
1 - Unirally (E)
0 - U.N. Squadron (E)
9 - Vortex (E)
0 - Wario's Woods (U)
0 - Wolfenstein 3D (E)
2 - Wolfenstein 3D (U)
0 - Wolverine - Adamantium Rage (U)
0 - Worms (E)
0 - WWF Super Wrestlemania (E)
9 - X-Band Modem BIOS (U)
0 - X-Men - Mutant Apocalypse (E)
2 - Yoshi's Safari (U) <= I don't have a Super Scope...
2 - Ys V - Expert (J)
2 - Yuu Yuu Hakusho - Tokubetsuhen (J)
0 - Zelda no Densetsu - Kamigami no Triforce (J) (V1.0)
0 - Zombies (E)
EOF

View File

@ -0,0 +1,62 @@
/*
backup.h - single header file for all backup unit functions
Copyright (c) 2003 NoisyB <noisyb@gmx.net>
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.
*/
#ifndef BACKUP_H
#define BACKUP_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef USE_PARALLEL
#include "cd64.h"
#include "cmc.h"
#include "dex.h"
#include "doctor64.h"
#include "doctor64jr.h"
#include "fal.h"
//#include "ffe.h"
#include "fig.h"
#include "gbx.h"
#include "gd.h"
#include "interceptor.h"
#include "lynxit.h"
#include "mccl.h"
#include "mcd.h"
#include "md-pro.h"
#include "mgd.h"
#include "msg.h"
#include "pce-pro.h"
#include "pl.h"
//#include "psxpblib.h"
#include "sflash.h"
#include "smc.h"
#include "smd.h"
#include "smsgg-pro.h"
#include "ssc.h"
#include "swc.h"
#include "ufo.h"
#include "yoko.h"
#include "z64.h"
#endif // USE_PARALLEL
#if defined USE_PARALLEL || defined USE_USB
#include "f2a.h"
#endif
#endif // BACKUP_H

View File

@ -0,0 +1,768 @@
/*
cartlib.c - Flash Linker Advance support for uCON64
Copyright (c) 2001 Jeff Frohwein
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
#ifdef USE_PARALLEL
// *** GBA flash cart support routines in GCC ***
// This library allows programming FA/Visoly (both Turbo
// and non-Turbo) and official Nintendo flash carts. They
// can be used with the Flash Linker or can be called
// from GBA code to allow in-system flash cart programming.
// NOTE: ALL OF THESE ROUTINES MUST BE LOCATED IN GBA RAM
// IF THIS LIBRARY IS USED FOR IN-SYSTEM PROGRAMMING.
//
// by Jeff Frohwein, Started 2001-Aug-29
//
// v1.0 - 2001-Sept-25 - Original release
// v1.1 - 2001-Nov-13 - Slightly modified SetVisolyBackupRWMode by removing >>1.
//
// Routines -
//
// void SetFAFlashRWMode (void)
//
// Used to enable modifications of FA/Visoly cart flash chip(s)
// and also used for CartTypeDetect routine. YOU MUST CALL THIS
// ROUTINE BEFORE USING ANY OF THE OTHER FA/VISOLY ROUTINES.
//
// u8 CartTypeDetect (void)
// Return a value indicating type of cart installed:
// 0x00 = Hudson Cart, 0x2e = Standard ROM
// 0xe2 = N Flash Cart, 0xff = Unknown
// 0x17 = FA 64M, 0x96 = Turbo FA 64M
// 0x18 = FA 128M, 0x97 = Turbo FA 128M
//
// u32 EraseNintendoFlashBlocks (u32 StartAddr, u32 BlockCount)
//
// Erase official Nintendo flash cart blocks.
// Ex: EraseNintendoFlashBlocks (0x8000000, 1); // erase block 1
// EraseNintendoFlashBlocks (0x8010000, 2); // erase blocks 2 & 3
//
// u32 EraseNonTurboFABlocks (u32 StartAddr, u32 BlockCount)
//
// Erase older (non-Turbo) Visoly flash cart blocks.
// Ex: EraseNonTurboFABlocks (0x8000000, 1); // erase block 1
// EraseNonTurboFABlocks (0x8020000, 2); // erase blocks 2 & 3
//
// u32 EraseTurboFABlocks (u32 StartAddr, u32 BlockCount)
//
// Erase newer (Turbo) Visoly flash cart blocks.
// Ex: EraseTurboFABlocks (0x8000000, 1); // erase block 1
// EraseTurboFABlocks (0x8040000, 2); // erase blocks 2 & 3
//
// u32 WriteNintendoFlashCart (u32 SrcAddr, u32 FlashAddr, u32 Length)
//
// Write 2 x Length bytes to official Nintendo flash cart.
// Ex: WriteNintendoFlashCart (SrcAddr, 0x8000000, 2) // write 4 bytes
//
// u32 WriteNonTurboFACart (u32 SrcAddr, u32 FlashAddr, u32 Length)
//
// Write 32 x Length bytes to older (non-Turbo) Visoly flash cart.
// Ex: WriteNonTurboFACart (SrcAddr, 0x8000000, 2) // write 64 bytes
//
// u32 WriteTurboFACart (u32 SrcAddr, u32 FlashAddr, u32 Length)
//
// Write 64 x Length bytes to newer (Turbo) Visoly flash cart.
// Ex: WriteTurboFACart (SrcAddr, 0x8000000, 2) // write 128 bytes
//
// To reduce the library size and remove support for any
// of the following types, comment out one or more of
// the following lines using //
#define NONTURBO_FA_SUPPORT 1 // Visoly Non-Turbo flash carts
#define TURBO_FA_SUPPORT 1 // Visoly Turbo flash carts
#define NOA_FLASH_CART_SUPPORT 1 // Official Nintendo flash carts
//#define SET_CL_SECTION 1 // Enable setting code section for cartlib
//
//
//
#ifdef TURBO_FA_SUPPORT
#define COMMON_FA_SUPPORT 1
#endif
#ifdef NONTURBO_FA_SUPPORT
#define COMMON_FA_SUPPORT 1
#endif
#ifdef FLINKER
// FLinker programming defines
#define _MEM_INC 1
#define FP_TIMEOUT1 0x4000
#define FP_TIMEOUT2 0x8000
#define FP_TIMEOUT3 0x80000
#define _CART_START 0
#define FLINKER_SET l40226c ()
#define READ_NTURBO_SR(a,b) WriteFlash (a, INTEL28F_READSR); \
outpb (SPPCtrlPort, 0); \
b = (PPReadWord() & 0xff)
#define READ_NTURBO_S(a) outpb (SPPCtrlPort, 0); \
a = (PPReadWord() & 0xff)
#define READ_TURBO_SR(a) WriteFlash (0, INTEL28F_READSR); \
PPWriteWord (INTEL28F_READSR); \
outpb (SPPCtrlPort, 0); \
a = PPReadWord() & 0xff; \
a += (PPReadWord() & 0xff) << 8
#define READ_TURBO_S(a) outpb (SPPCtrlPort, 0); \
a = PPReadWord() & 0xff; \
a += (PPReadWord() & 0xff) << 8
#define READ_TURBO_S2(a,b,c) outpb (SPPCtrlPort, 0); \
b = PPReadWord () & 0x80; \
c = PPReadWord () & 0x80
#define WRITE_FLASH_NEXT(a,b) PPWriteWord (b)
#define SET_CART_ADDR(a) SetCartAddr (a); \
l4021d0 (3)
#define CTRL_PORT_0 outpb (SPPCtrlPort, 0)
#define CTRL_PORT_1 outpb (SPPCtrlPort, 1)
void
WriteRepeat (int addr, int data, int count)
{
int i;
for (i = 0; i < count; i++)
WriteFlash (addr, data);
}
#else
// GBA in-system programming defines
#define _MEM_INC 2
#define FP_TIMEOUT1 0x4000 // Probably could be MUCH smaller
#define FP_TIMEOUT2 0x8000 // Probably could be MUCH smaller
#define FP_TIMEOUT3 0x80000 // Probably could be MUCH smaller
#define INTEL28F_BLOCKERASE 0x20
#define INTEL28F_CLEARSR 0x50
#define INTEL28F_CONFIRM 0xD0
#define INTEL28F_QUIRY 0x98
#define INTEL28F_READARRAY 0xff
#define INTEL28F_READSR 0x70
#define INTEL28F_RIC 0x90
#define INTEL28F_WRTOBUF 0xe8
#define SHARP28F_BLOCKERASE 0x20
#define SHARP28F_CONFIRM 0xD0
#define SHARP28F_WORDWRITE 0x10
#define SHARP28F_READARRAY 0xff
// typedef volatile unsigned char vu8;
// typedef volatile unsigned short int vu16;
// typedef volatile unsigned int vu32;
// typedef volatile unsigned long long int vu64;
// typedef unsigned char u8;
// typedef unsigned short int u16;
// typedef unsigned int u32;
// typedef unsigned long long int u64;
#define _CART_START 0x8000000
#define _BACKUP_START 0xe000000
#define FLINKER_SET {}
#define READ_NTURBO_SR(a,b) *(vu16 *)a = INTEL28F_READSR; \
b = *(vu16 *)a
#define READ_NTURBO_S(a) a = *(vu16 *)_CART_START
#define READ_TURBO_SR(a) *(vu16 *)_CART_START = INTEL28F_READSR; \
*(vu16 *)(_CART_START+2) = INTEL28F_READSR; \
a = *(vu16 *)_CART_START & 0xff; \
a += (*(vu16 *)(_CART_START+2) & 0xff) << 8
#define READ_TURBO_S(a) a = *(vu16 *)_CART_START & 0xff; \
a += (*(vu16 *)(_CART_START+2) & 0xff) << 8
#define READ_TURBO_S2(a,b,c) b = *(vu16 *)a & 0x80; \
c = *(vu16 *)(a+2) & 0x80
#define WRITE_FLASH_NEXT(a,b) WriteFlash (a, b)
#define SET_CART_ADDR(a) {}
#define CTRL_PORT_0 {}
#define CTRL_PORT_1 {}
#define CL_SECTION __attribute__ ((section (".iwram")))
#ifdef SET_CL_SECTION
// Prototypes to allow placing routines in any section
void
WriteFlash (u32 addr, u16 data)
CL_SECTION;
u16 ReadFlash (u32 addr) CL_SECTION;
void WriteRepeat (u32 addr, u16 data, u16 count) CL_SECTION;
void VisolyModePreamble (void) CL_SECTION;
void SetVisolyFlashRWMode (void) CL_SECTION;
void SetVisolyBackupRWMode (int i) CL_SECTION;
u8 CartTypeDetect (void) CL_SECTION;
u32 EraseNintendoFlashBlocks (u32 StartAddr, u32 BlockCount) CL_SECTION;
u32 EraseNonTurboFABlocks (u32 StartAddr, u32 BlockCount) CL_SECTION;
u32 EraseTurboFABlocks (u32 StartAddr, u32 BlockCount) CL_SECTION;
u32 WriteNintendoFlashCart (u32 SrcAddr, u32 FlashAddr,
u32 Length) CL_SECTION;
u32 WriteNonTurboFACart (u32 SrcAddr, u32 FlashAddr,
u32 Length) CL_SECTION;
u32 WriteTurboFACart (u32 SrcAddr, u32 FlashAddr, u32 Length) CL_SECTION;
#endif
void WriteFlash (u32 addr, u16 data)
{
*(vu16 *) addr = data;
}
u16
ReadFlash (u32 addr)
{
return (*(vu16 *) addr);
}
void
WriteRepeat (u32 addr, u16 data, u16 count)
{
u16 i;
for (i = 0; i < count; i++)
*(vu16 *) (_CART_START + (addr << 1)) = data;
}
#endif
#ifdef COMMON_FA_SUPPORT
void
VisolyModePreamble (void) // 402438
{
FLINKER_SET;
WriteRepeat (0x987654, 0x5354, 1);
WriteRepeat (0x12345, 0x1234, 500);
WriteRepeat (0x7654, 0x5354, 1);
WriteRepeat (0x12345, 0x5354, 1);
WriteRepeat (0x12345, 0x5678, 500);
WriteRepeat (0x987654, 0x5354, 1);
WriteRepeat (0x12345, 0x5354, 1);
WriteRepeat (0x765400, 0x5678, 1);
WriteRepeat (0x13450, 0x1234, 1);
WriteRepeat (0x12345, 0xabcd, 500);
WriteRepeat (0x987654, 0x5354, 1);
}
void
SetVisolyFlashRWMode (void)
{
VisolyModePreamble ();
WriteRepeat (0xf12345, 0x9413, 1);
}
void
SetVisolyBackupRWMode (int i) // 402550
{
VisolyModePreamble ();
WriteRepeat (0xa12345, i, 1);
}
#endif
// Cart Type Detect
// Return a value indicating type of cart installed:
// 0xdc = Hudson Cart, 0x2e = Standard ROM Cart
// 0xe2 = N Flash Cart, 0xff = Unknown
// 0x17 = FA 64M, 0x96 = Turbo FA 64M
// 0x18 = FA 128M, 0x97 = Turbo FA 128M
u8
CartTypeDetect (void)
{
u8 type = 0xff;
u16 Manuf, Device;
WriteFlash (_CART_START, INTEL28F_RIC); // Read Identifier codes from flash.
// Works for intel 28F640J3A & Sharp LH28F320BJE.
Manuf = ReadFlash (_CART_START);
Device = ReadFlash (_CART_START + _MEM_INC);
switch (Manuf)
{
case 0: // Hudson Cart
type = 0xdc;
break;
case 0x2e: // Standard ROM
type = (u8) Manuf;
break;
case 0x89: // Intel chips
switch (Device)
{
case 0x16: // i28F320J3A
case 0x17: // i28F640J3A
case 0x18: // i28F128J3A
type = (u8) Device;
break;
default:
// Check to see if this is a Visoly "Turbo" cart
Device = ReadFlash (_CART_START + _MEM_INC + _MEM_INC);
switch (Device)
{
case 0x16: // 2 x i28F320J3A
case 0x17: // 2 x i28F640J3A
case 0x18: // 2 x i28F128J3A
type = Device + 0x80;
break;
}
}
break;
case 0xb0: // Sharp chips
switch (Device)
{
case 0xe2:
type = (u8) Device;
break;
}
break;
}
WriteFlash (_CART_START, INTEL28F_READARRAY); // Set flash to normal read mode
return type;
}
#ifdef NOA_FLASH_CART_SUPPORT
// Erase official Nintendo flash cart blocks
// Function returns true if erase was successful.
// Each block represents 64k bytes.
u32
EraseNintendoFlashBlocks (u32 StartAddr, u32 BlockCount)
{
int i = 0;
int j, k;
time_t starttime = time (NULL);
for (k = 0; k < (int) BlockCount; k++)
{
i = StartAddr + (k * 32768 * _MEM_INC);
do
{
READ_NTURBO_SR (i, j);
}
while ((j & 0x80) == 0);
WriteFlash (i, SHARP28F_BLOCKERASE); // Erase a 64k byte block
WriteFlash (i, SHARP28F_CONFIRM); // Comfirm block erase
ucon64_gauge (starttime, (k + 1) * 64 * 1024, BlockCount * 64 * 1024);
}
do
{
READ_NTURBO_SR (i, j);
}
while ((j & 0x80) == 0);
WriteFlash (i, SHARP28F_READARRAY); // Set normal read mode
return 1;
}
#endif
#ifdef NONTURBO_FA_SUPPORT
// Erase older (non-Turbo) FA/Visoly flash cart blocks
// (Single flash chip)
// Function returns true if erase was successful.
// Each block represents 128k bytes.
u32
EraseNonTurboFABlocks (u32 StartAddr, u32 BlockCount)
{
u16 k;
u16 Ready = 1;
u32 i = 0;
u32 Timeout;
time_t starttime = time (NULL);
for (k = 0; k < BlockCount; k++)
{
i = StartAddr + (k * 65536 * _MEM_INC);
Ready = 0;
Timeout = FP_TIMEOUT2;
while ((Ready == 0) && (Timeout != 0))
{
READ_NTURBO_SR (_CART_START, Ready);
Ready &= 0x80;
Timeout--;
}
if (Ready)
{
WriteFlash (i, INTEL28F_BLOCKERASE); // Erase a 128k byte block
Ready = 0;
Timeout = FP_TIMEOUT3;
while ((!Ready) && (Timeout != 0))
{
READ_NTURBO_S (Ready);
Ready = (Ready == 0x80);
Timeout--;
}
if (Ready)
{
WriteFlash (i, INTEL28F_CONFIRM); // Comfirm block erase
Ready = 0;
Timeout = FP_TIMEOUT3;
while ((!Ready) && (Timeout != 0))
{
READ_NTURBO_S (Ready);
Ready = (Ready == 0x80);
Timeout--;
}
if (Ready)
{
READ_NTURBO_SR (_CART_START, Ready);
Ready = (Ready == 0x80);
if (!Ready)
break;
}
else
break;
}
else
break;
}
else
break;
ucon64_gauge (starttime, (k + 1) * 128 * 1024,
BlockCount * 128 * 1024);
}
if (!Ready)
{
WriteFlash (i, INTEL28F_CLEARSR); // Clear flash status register
}
WriteFlash (i, INTEL28F_READARRAY); // Set flash to normal read mode
WriteFlash (i, INTEL28F_READARRAY); // Set flash to normal read mode
return Ready != 0;
}
#endif
#ifdef TURBO_FA_SUPPORT
// Erase newer (Turbo) FA/Visoly flash cart blocks
// (Dual chip / Interleave)
// Function returns true if erase was successful.
// Each block represents 256k bytes.
u32
EraseTurboFABlocks (u32 StartAddr, u32 BlockCount)
{
u16 j, k;
u16 done1, done2;
u16 Ready = 1;
u32 i = 0;
u32 Timeout;
time_t starttime = time (NULL);
for (k = 0; k < BlockCount; k++)
{
i = StartAddr + (k * 131072 * _MEM_INC);
Ready = 0;
Timeout = FP_TIMEOUT2;
while ((!Ready) && (Timeout != 0))
{
READ_TURBO_SR (j);
Ready = (j == 0x8080);
Timeout--;
}
if (Ready)
{
done1 = 0;
done2 = 0;
Ready = 0;
Timeout = FP_TIMEOUT3;
while ((!Ready) && (Timeout != 0))
{
if (done1 == 0)
WriteFlash (i, INTEL28F_BLOCKERASE); // Erase a 128k byte block in flash #1
if (done2 == 0)
WriteFlash (i + _MEM_INC, INTEL28F_BLOCKERASE); // Erase a 128k byte block in flash #2
READ_TURBO_S2 (_CART_START, done1, done2);
Ready = ((done1 + done2) == 0x100);
Timeout--;
}
if (Ready)
{
WriteFlash (i, INTEL28F_CONFIRM); // Comfirm block erase in flash #1
WriteFlash (i + _MEM_INC, INTEL28F_CONFIRM); // Comfirm block erase in flash #2
Ready = 0;
Timeout = FP_TIMEOUT3;
j = 0;
while (((j & 0x8080) != 0x8080) && (Timeout != 0))
{
READ_TURBO_S (j);
Ready = (j == 0x8080);
Timeout--;
}
if (!Ready)
break;
}
else
break;
}
else
break;
ucon64_gauge (starttime, (k + 1) * 256 * 1024,
BlockCount * 256 * 1024);
}
if (!Ready)
{
WriteFlash (i, INTEL28F_CLEARSR);
WriteFlash (i + _MEM_INC, INTEL28F_CLEARSR);
}
WriteFlash (_CART_START, INTEL28F_READARRAY);
WriteFlash (_CART_START + _MEM_INC, INTEL28F_READARRAY);
WriteFlash (_CART_START, INTEL28F_READARRAY);
WriteFlash (_CART_START + _MEM_INC, INTEL28F_READARRAY);
return Ready != 0;
}
#endif
#ifdef NOA_FLASH_CART_SUPPORT
// Write 2 x Length bytes to official Nintendo flash cart.
// Function returns true if write was successful.
u32
WriteNintendoFlashCart (u32 SrcAddr, u32 FlashAddr, u32 Length)
{
int j;
int LoopCount = 0;
u16 *SrcAddr2 = (u16 *)
#ifdef __LP64__
(u64)
#endif
SrcAddr;
while (LoopCount < (int) Length)
{
do
{
READ_NTURBO_SR (FlashAddr, j);
}
while ((j & 0x80) == 0);
WriteFlash (FlashAddr, SHARP28F_WORDWRITE);
WriteFlash (FlashAddr, *SrcAddr2);
SrcAddr2 += 2;
FlashAddr += _MEM_INC;
LoopCount++;
}
do
{
READ_NTURBO_SR (FlashAddr, j);
}
while ((j & 0x80) == 0);
WriteFlash (_CART_START, SHARP28F_READARRAY);
// CTRL_PORT_0;
return 1;
}
#endif
#ifdef NONTURBO_FA_SUPPORT
// Write 32 x Length bytes to older (non-Turbo) FA/Visoly flash cart.
// Function returns true if write was successful.
u32
WriteNonTurboFACart (u32 SrcAddr, u32 FlashAddr, u32 Length)
{
int Ready = 0;
int Timeout = 0;
int LoopCount = 0;
u16 *SrcAddr2 = (u16 *)
#ifdef __LP64__
(u64)
#endif
SrcAddr;
while (LoopCount < (int) Length)
{
Ready = 0;
Timeout = FP_TIMEOUT1;
while ((Ready == 0) && (Timeout != 0))
{
WriteFlash (FlashAddr, INTEL28F_WRTOBUF);
READ_NTURBO_S (Ready);
Ready &= 0x80;
Timeout--;
}
if (Ready)
{
int i;
WriteFlash (FlashAddr, 15); // Write 15+1 16bit words
SET_CART_ADDR (FlashAddr);
for (i = 0; i < 16; i++)
{
WRITE_FLASH_NEXT (FlashAddr, *SrcAddr2);
SrcAddr2 += 2;
FlashAddr += _MEM_INC;
}
WRITE_FLASH_NEXT (FlashAddr, INTEL28F_CONFIRM);
Ready = 0;
Timeout = FP_TIMEOUT1;
while ((Ready == 0) && (Timeout != 0))
{
READ_NTURBO_SR (_CART_START, i);
Ready = i & 0x80;
Timeout--;
}
if (Ready)
{
if (i & 0x7f)
{
// One or more status register error bits are set
CTRL_PORT_1;
WriteFlash (0, INTEL28F_CLEARSR);
Ready = 0;
break;
}
}
else
{
CTRL_PORT_1;
WriteFlash (0, INTEL28F_CLEARSR);
break;
}
}
else
{
break;
}
LoopCount++;
}
WriteFlash (_CART_START, INTEL28F_READARRAY); // Set flash to normal read mode
WriteFlash (_CART_START, INTEL28F_READARRAY); // Set flash to normal read mode
return Ready != 0;
}
#endif
#ifdef TURBO_FA_SUPPORT
// Write 64 x Length bytes to newer (Turbo) FA/Visoly flash cart.
// Function returns true if write was successful.
u32
WriteTurboFACart (u32 SrcAddr, u32 FlashAddr, u32 Length)
{
int i, k;
int done1, done2;
int Timeout;
int Ready = 0;
int LoopCount = 0;
u16 *SrcAddr2 = (u16 *)
#ifdef __LP64__
(u64)
#endif
SrcAddr;
while (LoopCount < (int) Length)
{
done1 = 0;
done2 = 0;
Ready = 0;
Timeout = 0x4000;
while ((!Ready) && (Timeout != 0))
{
if (done1 == 0)
WriteFlash (FlashAddr, INTEL28F_WRTOBUF);
if (done2 == 0)
WriteFlash (FlashAddr + _MEM_INC, INTEL28F_WRTOBUF);
SET_CART_ADDR (FlashAddr);
READ_TURBO_S2 (FlashAddr, done1, done2);
Ready = ((done1 + done2) == 0x100);
Timeout--;
}
if (Ready)
{
WriteFlash (FlashAddr, 15); // Write 15+1 16bit words
WRITE_FLASH_NEXT (FlashAddr + _MEM_INC, 15); // Write 15+1 16bit words
SET_CART_ADDR (FlashAddr);
for (i = 0; i < 32; i++)
{
WRITE_FLASH_NEXT (FlashAddr, *SrcAddr2);
SrcAddr2 += 2;
FlashAddr += _MEM_INC;
}
WRITE_FLASH_NEXT (FlashAddr, INTEL28F_CONFIRM);
WRITE_FLASH_NEXT (FlashAddr + _MEM_INC, INTEL28F_CONFIRM);
Ready = 0;
Timeout = 0x4000;
k = 0;
while (((k & 0x8080) != 0x8080) && (Timeout != 0))
{
READ_TURBO_S (k);
Ready = (k == 0x8080);
Timeout--;
}
if (!Ready)
break;
}
else
break;
LoopCount++;
}
WriteFlash (_CART_START, INTEL28F_READARRAY);
CTRL_PORT_0;
WriteFlash (_CART_START + _MEM_INC, INTEL28F_READARRAY);
CTRL_PORT_0;
if (!Ready)
{
WriteFlash (_CART_START, INTEL28F_CLEARSR);
WriteFlash (_CART_START + _MEM_INC, INTEL28F_CLEARSR);
}
return Ready != 0;
}
#endif
#endif // USE_PARALLEL

View File

@ -0,0 +1,504 @@
/*
cd64.c - CD64 support for uCON64
Copyright (c) 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 <stdarg.h>
#include <ultra64/host/cd64lib.h>
#include "misc/misc.h"
#include "misc/parallel.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "ucon64.h"
#include "ucon64_dat.h"
#include "ucon64_misc.h"
#include "cd64.h"
const st_getopt2_t cd64_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "CD64"/*"19XX UFO http://www.cd64.com"*/,
NULL
},
#if defined USE_PARALLEL && defined USE_LIBCD64
{
"xcd64", 0, 0, UCON64_XCD64,
NULL, "send/receive ROM to/from CD64; " OPTION_LONG_S "port=PORT\n"
"receives automatically (64 Mbits) when ROM does not exist",
&ucon64_wf[WF_OBJ_N64_DEFAULT_STOP_NO_ROM]
},
{
"xcd64c", 1, 0, UCON64_XCD64C,
"N", "receive N Mbits of ROM from CD64; " OPTION_LONG_S "port=PORT",
&ucon64_wf[WF_OBJ_N64_STOP_NO_ROM]
},
{
"xcd64b", 0, 0, UCON64_XCD64B,
NULL, "send boot emu to CD64; " OPTION_LONG_S "port=PORT",
&ucon64_wf[WF_OBJ_N64_DEFAULT_STOP]
},
{
"xcd64s", 0, 0, UCON64_XCD64S,
NULL, "send/receive SRAM to/from CD64; " OPTION_LONG_S "port=PORT\n"
"receives automatically when SRAM file does not exist",
&ucon64_wf[WF_OBJ_N64_STOP_NO_ROM]
},
{
"xcd64f", 0, 0, UCON64_XCD64F,
NULL, "send/receive flash RAM to/from CD64; " OPTION_LONG_S "port=PORT\n"
"receives automatically when flash RAM file does not exist",
&ucon64_wf[WF_OBJ_N64_STOP_NO_ROM]
},
{
"xcd64e", 0, 0, UCON64_XCD64E,
NULL, "send/receive EEPROM data to/from CD64; " OPTION_LONG_S "port=PORT\n"
"receives automatically when EEPROM file does not exist",
&ucon64_wf[WF_OBJ_N64_STOP_NO_ROM]
},
{
"xcd64m", 1, 0, UCON64_XCD64M,
"INDEX", "send/receive memory pack data to/from CD64; " OPTION_LONG_S "port=PORT\n"
"INDEX is ignored for CD64 BIOS protocol\n"
"receives automatically when memory pack file does not exist",
&ucon64_wf[WF_OBJ_N64_STOP_NO_ROM]
},
{
"xcd64p", 1, 0, UCON64_XCD64P,
"PROT", "use protocol PROT when communicating with CD64; " OPTION_LONG_S "port=PORT\n"
"PROT=0 CD64 BIOS\n"
"PROT=1 Ghemor\n"
"PROT=2 UltraLink",
&ucon64_wf[WF_OBJ_N64_SWITCH]
},
#endif // USE_PARALLEL && USE_LIBCD64
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
#if defined USE_PARALLEL && defined USE_LIBCD64
static time_t cd64_starttime;
static void
cd64_progress (uint32_t current, uint32_t total)
{
ucon64_gauge (cd64_starttime, current, total);
}
static int
cd64_notice_helper (FILE *file, const char *prefix, const char *format,
va_list argptr)
{
int n_chars;
fputs (prefix, file);
n_chars = vfprintf (file, format, argptr);
fputc ('\n', file);
fflush (file);
return n_chars;
}
static int
cd64_notice (const char *format, ...)
{
va_list argptr;
int n_chars;
va_start (argptr, format);
n_chars = cd64_notice_helper (stdout, "NOTE (libcd64): ", format, argptr);
va_end (argptr);
return n_chars;
}
static int
cd64_notice2 (const char *format, ...)
{
va_list argptr;
int n_chars;
va_start (argptr, format);
n_chars = cd64_notice_helper (stderr, "ERROR (libcd64): ", format, argptr);
va_end (argptr);
return n_chars;
}
static int
fread_wrapper (void *io_id, void *buffer, uint32_t size)
{
return fread (buffer, 1, size, (FILE *) io_id);
}
static int
fwrite_wrapper (void *io_id, void *buffer, uint32_t size)
{
return fwrite (buffer, 1, size, (FILE *) io_id);
}
static int32_t
ftell_wrapper (void *io_id)
{
return (int32_t) ftell ((FILE *) io_id);
}
static int
fseek_wrapper (void *io_id, int32_t offset, int whence)
{
return fseek ((FILE *) io_id, offset, whence);
}
static struct cd64_t *
cd64_init (void)
{
struct cd64_t *cd64;
#ifdef USE_PPDEV
uint16_t port = strtol (&ucon64.parport_dev[strlen (ucon64.parport_dev) - 1], NULL, 10);
method_t method = PPDEV;
#else
uint16_t port = ucon64.parport;
method_t method = RAWIO;
#endif
int is_parallel = 1;
if ((cd64 = (struct cd64_t *) calloc (1, sizeof (struct cd64_t))) == NULL)
{
fprintf (stderr, ucon64_msg[BUFFER_ERROR], sizeof (struct cd64_t));
exit (1);
}
#ifndef USE_PPDEV
if (ucon64.parport == UCON64_UNKNOWN)
{
fputs ("ERROR: No port or invalid port specified\n"
"TIP: Specify one with --port or in the configuration file\n", stderr);
exit (1);
}
if (port >= 0x300 && port <= 0x330)
is_parallel = 0;
#endif
cd64->notice_callback = cd64_notice;
cd64->notice_callback2 = cd64_notice2;
if (!cd64_create (cd64, method, port, (protocol_t) ucon64.io_mode, is_parallel))
{
fputs ("ERROR: Could not initialise libcd64\n", stderr);
exit (1);
}
cd64->read_callback = fread_wrapper; // actually f*2(), if zlib
cd64->write_callback = fwrite_wrapper; // support is enabled
cd64->tell_callback = ftell_wrapper;
cd64->seek_callback = fseek_wrapper;
cd64->progress_callback = cd64_progress;
strcpy (cd64->io_driver_dir, ucon64.configdir);
// parport_print_info() displays a reasonable message (even if we're using a
// comms link)
parport_print_info ();
if (!cd64->devopen (cd64))
{
fputs ("ERROR: Could not open I/O device for CD64\n", stderr);
exit (1);
}
#if defined __unix__ && !defined __MSDOS__
drop_privileges ();
#endif
return cd64;
}
int
cd64_read_rom (const char *filename, int size)
{
FILE *file;
struct cd64_t *cd64 = cd64_init ();
if ((file = fopen (filename, "w+b")) == NULL) // cd64_download_cart() also
{ // reads from file
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
cd64_starttime = time (NULL);
cd64_download_cart (cd64, file, size * MBIT, NULL);
cd64->devclose (cd64);
fclose (file);
free (cd64);
return 0;
}
int
cd64_write_rom (const char *filename)
{
FILE *file;
struct cd64_t *cd64 = cd64_init ();
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
cd64_starttime = time (NULL);
cd64_upload_dram (cd64, file, ucon64.file_size, NULL, 1);
cd64->devclose (cd64);
fclose (file);
free (cd64);
return 0;
}
int
cd64_write_bootemu (const char *filename)
{
FILE *file;
struct cd64_t *cd64 = cd64_init ();
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
cd64_starttime = time (NULL);
cd64_upload_bootemu (cd64, file, ucon64.file_size, NULL);
cd64->devclose (cd64);
fclose (file);
free (cd64);
return 0;
}
int
cd64_read_sram (const char *filename)
{
FILE *file;
struct cd64_t *cd64 = cd64_init ();
if ((file = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
cd64_starttime = time (NULL);
cd64_download_sram (cd64, file);
cd64->devclose (cd64);
fclose (file);
free (cd64);
return 0;
}
int
cd64_write_sram (const char *filename)
{
FILE *file;
struct cd64_t *cd64 = cd64_init ();
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
cd64_starttime = time (NULL);
cd64_upload_sram (cd64, file);
cd64->devclose (cd64);
fclose (file);
free (cd64);
return 0;
}
int
cd64_read_flashram (const char *filename)
{
FILE *file;
struct cd64_t *cd64 = cd64_init ();
if ((file = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
cd64_starttime = time (NULL);
cd64_download_flashram (cd64, file);
cd64->devclose (cd64);
fclose (file);
free (cd64);
return 0;
}
int
cd64_write_flashram (const char *filename)
{
FILE *file;
struct cd64_t *cd64 = cd64_init ();
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
cd64_starttime = time (NULL);
cd64_upload_flashram (cd64, file);
cd64->devclose (cd64);
fclose (file);
free (cd64);
return 0;
}
int
cd64_read_eeprom (const char *filename)
{
FILE *file;
struct cd64_t *cd64 = cd64_init ();
if ((file = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
cd64_starttime = time (NULL);
cd64_download_eeprom (cd64, file);
cd64->devclose (cd64);
fclose (file);
free (cd64);
return 0;
}
int
cd64_write_eeprom (const char *filename)
{
FILE *file;
struct cd64_t *cd64 = cd64_init ();
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
cd64_starttime = time (NULL);
cd64_upload_eeprom (cd64, file);
cd64->devclose (cd64);
fclose (file);
free (cd64);
return 0;
}
int
cd64_read_mempack (const char *filename, int index)
{
FILE *file;
struct cd64_t *cd64 = cd64_init ();
if ((file = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
if (ucon64.io_mode == CD64BIOS)
index = -1;
cd64_starttime = time (NULL);
cd64_download_mempak (cd64, file, (int8_t) index);
cd64->devclose (cd64);
fclose (file);
free (cd64);
return 0;
}
int
cd64_write_mempack (const char *filename, int index)
{
FILE *file;
struct cd64_t *cd64 = cd64_init ();
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
if (ucon64.io_mode == CD64BIOS)
index = -1;
cd64_starttime = time (NULL);
cd64_upload_mempak (cd64, file, (int8_t) index);
cd64->devclose (cd64);
fclose (file);
free (cd64);
return 0;
}
#endif // USE_PARALLEL && USE_LIBCD64

View File

@ -0,0 +1,41 @@
/*
cd64.h - CD64 support for uCON64
Copyright (c) 2001 NoisyB <noisyb@gmx.net>
Copyright (c) 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.
*/
#ifndef CD64_H
#define CD64_H
extern const st_getopt2_t cd64_usage[];
#if defined USE_PARALLEL && defined USE_LIBCD64
extern int cd64_read_rom(const char *filename, int size);
extern int cd64_write_rom(const char *filename);
extern int cd64_write_bootemu (const char *filename);
extern int cd64_read_sram(const char *filename);
extern int cd64_write_sram(const char *filename);
extern int cd64_read_flashram(const char *filename);
extern int cd64_write_flashram(const char *filename);
extern int cd64_read_eeprom(const char *filename);
extern int cd64_write_eeprom(const char *filename);
extern int cd64_read_mempack(const char *filename, int index);
extern int cd64_write_mempack(const char *filename, int index);
#endif // USE_PARALLEL && USE_LIBCD64
#endif // CD64_H

View File

@ -0,0 +1,985 @@
/*
cmc.c - Cyan's Megadrive ROM copier support for uCON64
Copyright (c) 1999 - 2004 Cyan Helkaraxe
Special thanks to dbjh for helping with the uCON64 integration
of this software, and providing the wrapping code.
CMC version: 2.5
For hardware version 1.x
Copies Sega Megadrive/Genesis cartridges into .BIN format ROM files.
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.
*/
/*
Additional information:
This software is distributed in accordance with the GNU General
Public License. The author of the hardware design/documentation and
software, Cyan Helkaraxe, retains the copyright over the 'cmc' code
('software'), the hardware design and construction documentation itself.
Cyan grants you the rights of the GNU General Public License over
the software, as stated above. The copyright does not affect your
rights in relation to the 'cmc' code under the GNU General Public
License in any way.
Cyan Helkaraxe does NOT grant you any rights relating to the hardware
design/documentation, over and above the right to build the device for
personal, not-for-profit use. Likewise, the same applies to the ROM
copier construction documentation, available at
http://www.emulationzone.org/projects/cyan/docs/ for not-for-profit
personal use.
Obviously, feel free to make changes to this software, but if you do so,
*please* clearly mark the fact it is modified, to avoid confusion.
A define is provided below this commented area, which should be edited
as described. This is to inform users which version of the code they are
using at runtime, and if they encounter a problem, it makes it far easier
for me to help debug it. I have no evil nefarious intentions. =P
Obviously, your changes must adhere to the GNU GPL, and please keep the
copyright, Cyan's name, e-mail and web site address in the comments
somewhere.
If you wish to do anything with the hardware design or the documentation
that goes beyond personal use, get in touch with Cyan first;
cyan@emulationzone.org
Disclaimer / Warranty:
This is to emphasise, not replace, any warranty information provided in
the GNU GPL or uCON64.
There is no warranty whatsoever, for either the software or accompanying
hardware/design/documentation. This software is provided free of charge,
AS-IS, in the hope that it may be useful.
Use it at your own risk. The author does not make any guarantee that you
will be able to use this software or accompanying
hardware/design/documentation, or that it will perform smoothly. There is
a possibility that damage or loss (including but not limited to financial
loss, hardware or software damage, data corruption, privacy violation,
or personal injury, suffering, legal action, imprisonment or death) may
arise through the use of this software or the accompanying
hardware/design/documentation, in addition to many other possible outcomes.
You take sole responsibility for any outcomes; by using this software or
accompanying hardware/design/ documentation, you agree that the author will
not be held responsible for anything that may occur. If your jurisdiction
does not allow the author to be isolated from responsibility, then you
must *not* use this software or accompanying hardware/design/documentation.
The author does not condone software piracy. You may not use this software
to engage in piracy. The author is not responsible for anything you choose
to use this software for, although the author strongly recommends that you
use the software for the purpose for which it was intended to be used --
primarily as an educational tool, and secondarily to make backup copies of
your expensive/rare game cartridges, or a similarly harmless and legal
purpose.
Note that although the author isn't aware of any patent violations caused
by this software/hardware/design/documentation, it is possible that
there may be patents covering parts of this device. It is your
responsibility to check this before building or using the hardware or
software, and Cyan may not be held responsible in the event of an
infringement.
That being said, if you do encounter any problems with the hardware or
software, then feel free to get in touch with the author; use the subject
line 'ROM Copier Technical Support'. No promises or guarantees are made,
however.
Also note that the author is not affiliated with anyone involved with uCON64;
therefore, only correspondence relating to this particular file (the 'cmc'
code) or the accompanying hardware design should be directed to Cyan.
If you have more general uCON64 questions, Cyan is *not* the person to ask.
Likewise, the terms "the author" and "software" in this file (cmc.c, and
additionally cmc.h), along with similar terms, apply only to Cyan, and the
CMC software you see in this file. The disclaimer above, for example, relates
exclusively to the CMC code.
All trademarks, indicated or otherwise, are the property of their
respective owners.
*/
/*
NOTE!
Please edit the following line, and remove the word "original" from it
if you have made any modifications to this file. This reduces user
confusion.
*/
#define INTRO_TEXT "Cyan's Megadrive Copier (c) 1999-2004 Cyan Helkaraxe\n" \
"Software version 2.5 original, designed for hardware version 1.x\n\n"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include "misc/bswap.h"
#include "misc/misc.h"
#include "misc/parallel.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "ucon64.h"
#include "ucon64_misc.h"
#include "cmc.h"
#ifdef USE_PARALLEL
#define RSLO 0x40 // reset line 1 d7
#define RSHI 0x01 // reset line 2 d0
#define CNLO 0x10 // counter line 1 d4
#define CNHI 0x04 // counter line 2 d2
#define INLO 0x40 // input 1 ack (int disabled)
#define INHI 0x10 // input 2 selectin
#define MBYTE (1024 * 1024)
#define DEFAULT_SPEED 3
#ifdef _MSC_VER
// Visual C++ doesn't allow inline in C source code
#define inline __inline
#endif
/************************
* Internal functions *
************************/
static inline void
cyan_write_copier (unsigned char data, unsigned int parport)
// write a value to the data register of the parallel port
{
outportb ((unsigned short) (parport + PARPORT_DATA), data);
}
static inline unsigned char
cyan_read_copier (unsigned int parport)
// read a value from the status register of the parallel port
{
return inportb ((unsigned short) (parport + PARPORT_STATUS));
}
static inline unsigned char
cyan_verify_copier (unsigned int parport)
// read a value back from the data register for verification
{
return inportb ((unsigned short) (parport + PARPORT_DATA));
}
/**** non-hardware, non-accessing ****/
static unsigned long
cyan_calculate_rom_size (unsigned char *buffer, int test_mode)
/*
Calculate the ROM size, by looking at the ROM size entry in the ROM 'header',
and the overall structure.
This function always returns a value rounded to a power of two between 128
kbytes and 4 Mbytes. It also inspects the ROM for 0's or ffh's. If test_mode
is 1 it causes an error on that condition, frees the buffer and exits.
*/
{
unsigned long i = 0x80000000, reported_size;
// look at reported size
reported_size = (buffer[0x1a4] << 24) +
(buffer[0x1a5] << 16) +
(buffer[0x1a6] << 8) +
buffer[0x1a7] + 1;
// cap
// there is a minimum valid size for ROMs, according to some sources
if (reported_size < MBIT)
reported_size = MBIT;
if (reported_size > 4 * MBYTE)
reported_size = 4 * MBYTE;
// round
if (reported_size & (reported_size - 1))
{
while (!(reported_size & 0x80000000))
{
i >>= 1;
reported_size = (reported_size << 1) | 1;
}
reported_size = i << 1;
}
// calculate real size
for (i = 2 * MBYTE; i >= 65536; i >>= 1)
if (memcmp (buffer, buffer + i, i))
{
i >>= 1;
break;
}
i <<= 2;
if (reported_size < i)
reported_size = i; // pick the safest (largest) of the two
if (i == MBIT)
{
for (i = 0; i < MBIT; i++)
if ((buffer[i] != 0xff) && (buffer[i] != 0x00))
break;
if (i == MBIT)
{
FILE *output;
if (test_mode)
{
output = stderr;
fputs ("\nERROR: ", stderr);
}
else
{
output = stdout;
fputs ("\nWARNING: ", stdout);
}
// "WARNING: "
fputs ( "The ROM file appears to consist of nothing but 0x00 / 0xff values.\n"
" This usually indicates a serious problem. Perhaps your parallel port\n"
" isn't configured correctly, or there is some problem with the ROM\n"
" copier. Is it getting power? Is a cartridge inserted? Is it properly\n"
" attached to the PC?\n",
output);
if (test_mode)
{
free (buffer);
exit (1);
}
}
}
return reported_size;
}
static int
cyan_checksum_rom (unsigned char *buffer)
// return 0 on success, -1 on failure
{
unsigned char *buffer2 = buffer;
unsigned short reported_sum, running_sum = 0;
reported_sum = (buffer2[0x18e] << 8) + buffer2[0x18f];
buffer2 += ((buffer2[0x1a4] << 24) +
(buffer2[0x1a5] << 16) +
(buffer2[0x1a6] << 8) +
(buffer2[0x1a7] & 0xfe)) + 2;
if (buffer2 > buffer + 4 * MBYTE)
buffer2 = buffer + 4 * MBYTE;
buffer += 0x200;
if (buffer2 < buffer + 2)
return -1;
while (buffer2 != buffer)
{
running_sum += *--buffer2;
running_sum += (*--buffer2) << 8;
}
return (running_sum & 0xffff) != reported_sum ? -1 : 0;
}
static inline unsigned long
cyan_get_address (unsigned long b)
// return the true address (word -- 0 - 2 M) based on word input
{
return ((b & 0x000800) >> 11) | // bit 0
((b & 0x002000) >> 12) | // bit 1
((b & 0x004000) >> 12) | // bit 2
((b & 0x000020) >> 2) | // bit 3
((b & 0x100000) >> 16) | // bit 4
((b & 0x020000) >> 12) | // bit 5
((b & 0x000400) >> 4) | // bit 6
((b & 0x000001) << 7) | // bit 7
((b & 0x000002) << 7) | // bit 8
((b & 0x000010) << 5) | // bit 9
((b & 0x000040) << 4) | // bit 10
((b & 0x040000) >> 7) | // bit 11
((b & 0x080000) >> 7) | // bit 12
((b & 0x000080) << 6) | // bit 13
((b & 0x008000) >> 1) | // bit 14
((b & 0x010000) >> 1) | // bit 15
((b & 0x001000) << 4) | // bit 16
((b & 0x000004) << 15) | // bit 17
((b & 0x000008) << 15) | // bit 18
((b & 0x000200) << 10) | // bit 19
((b & 0x000100) << 12); // bit 20
}
/**** non-hardware, indirectly accessing ****/
static inline void
cyan_delay (int speed, unsigned int parport)
// Delays a certain amount of time depending on speed selected. 0=long delay,
// used for reset and hi counter.
{
int i, scritch = 0;
switch (speed)
{
case 0:
for (i = 0; i < 128; i++)
scritch += cyan_read_copier (parport);
case 1: // falling through
for (i = 0; i < 64; i++)
scritch += cyan_read_copier (parport);
case 2: // falling through
for (i = 0; i < 12; i++)
scritch += cyan_read_copier (parport);
case 3: // falling through
scritch += cyan_read_copier (parport);
scritch += cyan_read_copier (parport);
}
}
static void
cyan_reset (unsigned int parport)
// resets the copier
{
cyan_delay (0, parport);
// zero all data outputs first, before going into SPP mode
cyan_write_copier (0, parport);
// reset the port to SPP, float all control lines high
cyan_write_copier (0, parport + PARPORT_CONTROL);
cyan_delay (0, parport);
cyan_write_copier (RSLO | RSHI, parport); // both reset lines hi
cyan_delay (0, parport);
cyan_write_copier (0, parport); // both reset lines lo
cyan_delay (0, parport);
}
static inline unsigned short
cyan_get_word (int speed, unsigned int parport)
// gets a byte pair from the ROM and return two bytes in big endian byte order
{
unsigned short value = 0;
unsigned char tempz;
cyan_write_copier (0, parport);
cyan_delay (speed, parport);
tempz = cyan_read_copier (parport);
value |= tempz & INLO; // bit 6
value |= (tempz & INHI) << 8; // bit 12
cyan_write_copier (CNLO, parport);
cyan_delay (speed, parport);
tempz = cyan_read_copier (parport);
value |= (tempz & INLO) >> 5; // bit 1
value |= (tempz & INHI) << 9; // bit 13
cyan_write_copier (0, parport);
cyan_delay (speed, parport);
tempz = cyan_read_copier (parport);
value |= (tempz & INLO) << 3; // bit 9
value |= (tempz & INHI) << 10; // bit 14
cyan_write_copier (CNLO, parport);
cyan_delay (speed, parport);
tempz = cyan_read_copier (parport);
value |= (tempz & INLO) >> 1; // bit 5
value |= (tempz & INHI) << 11; // bit 15
cyan_write_copier (0, parport);
cyan_delay (speed, parport);
tempz = cyan_read_copier (parport);
value |= (tempz & INLO) >> 4; // bit 2
value |= (tempz & INHI) << 4; // bit 8
cyan_write_copier (CNLO, parport);
cyan_delay (speed, parport);
tempz = cyan_read_copier (parport);
value |= (tempz & INLO) << 4; // bit 10
value |= (tempz & INHI) >> 4; // bit 0
cyan_write_copier (0, parport);
cyan_delay (speed, parport);
tempz = cyan_read_copier (parport);
value |= (tempz & INLO) >> 2; // bit 4
value |= (tempz & INHI) << 3; // bit 7
cyan_write_copier (CNLO, parport);
cyan_delay (speed, parport);
tempz = cyan_read_copier (parport);
value |= (tempz & INLO) >> 3; // bit 3
value |= (tempz & INHI) << 7; // bit 11
return me2be_16 (value);
}
static inline int
check_exit (void)
// check for user abort
{
int temp;
if (ucon64.frontend)
return 0;
if (!kbhit ())
return 0;
temp = getch ();
if (temp == 'q' || (temp == 27))
return 1;
return 0;
}
static unsigned char *
cyan_read_rom (int speed, unsigned int parport, unsigned char *buffer)
/*
Read the ROM and return a pointer to a 4 MB area of memory containing all ROM
data. Designed to be used from inside cyan_copy_rom(), although it can be
called elsewhere if a raw (but decoded) dump is required.
*/
{
unsigned long q;
time_t t;
// allocate the dump area
if (!buffer)
if ((buffer = (unsigned char *) malloc (4 * MBYTE)) == NULL)
{
fprintf (stderr, ucon64_msg[ROM_BUFFER_ERROR], 4 * MBYTE);
exit (1);
}
cyan_reset (parport); // reset the copier
t = time (NULL);
// copy routine
for (q = 0; q < 2 * MBYTE; ) // loop through all words
{
// get a (16-bit) word from the ROM
((unsigned short *) buffer)[cyan_get_address (q)] = cyan_get_word (speed, parport);
// periodically update progress bar, without hammering ucon64_gauge()
if (!(q & (0xfff >> (5 - speed))))
{
if (check_exit ())
{
free (buffer);
puts ("\n"
"Copy aborted.\n"
"Don't forget to turn the ROM copier off and never insert or remove a cartridge\n"
"with the power on");
break;
}
ucon64_gauge (t, q * 2, 4 * MBYTE);
}
if (!(++q & 0x3ff)) // advance loop counter and carry to hi counter (11 bits)
{
cyan_delay (0, parport);
cyan_write_copier (CNHI, parport);
cyan_delay (0, parport);
cyan_write_copier (0, parport);
cyan_delay (0, parport);
}
}
// make sure it's left in a state where it's safe to remove the cart
cyan_reset (parport);
if (q != 2 * MBYTE)
return NULL;
ucon64_gauge (t, q * 2, 4 * MBYTE); // make the progress bar reach 100%
return buffer;
}
static void
cyan_test_parport (unsigned int parport)
// Test the parallel port to see if it appears to be functioning correctly, and
// terminate if there's an error.
{
unsigned short temp;
cyan_reset (parport);
fputs ("Basic parallel port test: ", stdout);
fflush (stdout);
cyan_write_copier (170, parport);
cyan_delay (0, parport);
temp = cyan_verify_copier (parport) & 170;
cyan_reset (parport);
// even in unidirectional mode, the parallel port is bidirectional; at
// least, for a few short moments before the driver IC smokes
if ((cyan_verify_copier (parport) & 170) != 0 || temp != 170)
{
puts ("FAILED");
fputs ("ERROR: Parallel port error\n"
" Check that your parallel port is configured properly, in the BIOS, OS,\n"
" and uCON64, and check for short circuits on the parallel port connector.\n"
" Also ensure that the ROM copier is getting power, and a cartridge is\n"
" inserted\n",
stderr);
exit (1);
}
else
puts ("Passed");
// discharge caps to see if we've got power
cyan_reset (parport);
cyan_reset (parport);
cyan_write_copier (CNLO + CNHI, parport);
cyan_delay (0, parport);
for (temp = 0; temp < 1000; temp++)
{
cyan_write_copier (0, parport);
cyan_delay (3, parport);
cyan_write_copier (CNLO + CNHI, parport);
cyan_delay (3, parport);
}
cyan_reset (parport);
cyan_reset (parport);
fputs ("Parallel port output test: ", stdout);
fflush (stdout);
cyan_write_copier (255, parport);
cyan_delay (0, parport);
temp = (cyan_verify_copier (parport) != 255);
cyan_write_copier (0, parport);
cyan_delay (0, parport);
temp |= (cyan_verify_copier (parport) != 0);
cyan_write_copier (CNLO, parport);
cyan_delay (0, parport);
temp |= (cyan_verify_copier (parport) != CNLO);
cyan_write_copier (CNHI, parport);
cyan_delay (0, parport);
temp |= (cyan_verify_copier (parport) != CNHI);
cyan_write_copier (RSLO, parport);
cyan_delay (0, parport);
temp |= (cyan_verify_copier (parport) != RSLO);
cyan_write_copier (RSHI, parport);
cyan_delay (0, parport);
temp |= (cyan_verify_copier (parport) != RSHI);
cyan_reset (parport);
// if it's still okay after that, then try reading the first set of inputs
// with lines high and low
if (!temp)
{
fputs ("Passed\n"
"Input crosstalk test: ",
stdout);
fflush (stdout);
temp = cyan_read_copier (parport) & (INLO | INHI);
cyan_write_copier (255 - CNLO, parport);
cyan_delay (0, parport);
temp = (temp != (cyan_read_copier (parport) & (INLO | INHI)));
cyan_reset (parport);
}
if (temp)
{
puts ("FAILED");
fputs ("ERROR: Parallel port error\n"
"Possible causes: ROM copier not getting power (check or replace battery)\n"
" Short circuit or bad connection (on parallel port or board)\n"
" Cartridge not inserted properly (or not inserted at all)\n"
" Parallel port not configured correctly\n"
" Orange, grey or green wire(s) soldered to the wrong locations\n"
" Chips inserted backwards\n"
"NOTE: Don't forget the ROM copier needs to be turned on before starting!\n",
stderr);
exit (1);
}
else
puts ("Passed");
}
static int
cyan_test_copier (int test, int speed, unsigned int parport)
{
unsigned char *buffer1, *buffer2 = NULL;
int count = 1;
fputs (INTRO_TEXT, stdout);
parport_print_info ();
switch (test)
{
// reliability test -- note: this test may be required to run for 8 hours or more
case 1:
printf ("Reliability test mode selected, speed %d\n", speed);
cyan_test_parport (parport);
puts ("\n"
"Entering non-stop reliability test mode (press escape or q to exit, and turn\n"
"ROM copier off immediately afterwards)\n"
"\n"
"Copy process will continue indefinitely until an error is encountered, at\n"
"which point the program will terminate.\n"
"A large number of passes suggests that the copier is working reliably at the\n"
"selected speed\n");
printf (" P %2d",
count);
fflush (stdout);
if (ucon64.frontend)
fputc ('\n', stdout);
buffer1 = cyan_read_rom (speed, parport, NULL);
if (!buffer1) // user abort
exit (0);
// detect if ROM is all 0x00 or 0xff and print an error if so
cyan_calculate_rom_size (buffer1, 1);
while (1)
{
clear_line (); // remove last gauge
printf (" Pass %2d OK\n", count);
count++;
// verify checksum of first pass
if (count == 2) // check only in first iteration
if (cyan_checksum_rom (buffer1)) // verify checksum
puts ("\n"
"WARNING: Checksum of ROM does not appear to be correct.\n"
" This may be normal for this ROM, or it may indicate a bad copy\n");
printf (" P %2d",
count);
fflush (stdout);
if (ucon64.frontend)
fputc ('\n', stdout);
buffer2 = cyan_read_rom (speed, parport, buffer2);
if (!buffer2)
{
free (buffer1);
exit (0);
}
if (memcmp (buffer1, buffer2, 4 * MBYTE))
{
// error
printf ("\n"
"\n"
"Error detected on pass number %d\n"
"\n",
count);
if (count == 2)
puts ("A failure this early suggests a critical fault, such as a misconfigured or\n"
"incompatible parallel port, extremely poor wiring, or power supply problems --\n"
"you may wish to replace the battery or try another power supply, and use\n"
"shorter cables.\n"
"Try lowering the speed and running this test again, as a too high speed can\n"
"often cause these symptoms.\n"
"Alternatively, it may have been a one-time glitch; re-run the test to be sure.\n"
"When (if?) you find a lower speed which works reliably, use that speed for\n"
"copying ROMs\n");
else
puts ("The first couple of passes were successful. This indicates that you have a\n"
"minor intermittent problem; most likely power supply problems, bad wiring, or\n"
"some kind of one-time glitch.\n"
"You may wish to replace the battery or try another power supply, and use\n"
"shorter cables.\n"
"Make sure no electrical appliances turn on or off during the copy.\n"
"Re-run the test to be sure; it's recommended that you use a lower speed\n");
free (buffer1);
free (buffer2);
exit (1);
}
}
free (buffer1);
free (buffer2);
break;
// manual test
case 2:
cyan_reset (parport);
cyan_write_copier (CNHI, parport);
cyan_delay (0, parport);
cyan_write_copier (0, parport);
cyan_delay (0, parport);
if (speed != DEFAULT_SPEED)
puts ("Ignoring specified speed; test bench mode does not require a speed setting");
// print screen
puts ("Entering manual test bench mode\n"
"\n"
"Probe the board and verify that the counters are being clocked, and are\n"
"counting correctly. The upper counter should be one count ahead of the lower\n"
"counter, with both clocked at the same rate.\n"
"Inject logic levels into the multiplexers to verify that the data bits are\n"
"being read correctly:\n"
"*=high .=low, layout: L H L H L H L H (L=low multiplexer, H=high multiplexer)\n"
"NOTE: The signals in question are the chip native signals; D0 below corresponds\n"
"to D0 on the multiplexer, NOT D0 on the cartridge port. Likewise with the\n"
"address lines. The input lines are in counter order, left to right.\n"
"Press escape or q to exit; be sure to turn the ROM copier off immediately after\n"
"exiting, to reset the device.\n"
"\n"
"If the above didn't make any sense to you, press escape or q and turn the ROM\n"
"copier off immediately!\n"
"This test is designed for advanced users only\n");
while (1)
{
const char *status[2] = {"* ", ". "};
fputc ('\r', stdout);
cyan_write_copier (0, parport);
cyan_delay (1, parport);
count = cyan_read_copier (parport);
fputs (status[((count ^ INLO) >> 6) & 1], stdout);
fputs (status[((count ^ INHI) >> 4) & 1], stdout);
cyan_write_copier (CNLO | CNHI, parport);
cyan_delay (1, parport);
count = cyan_read_copier (parport);
fputs (status[((count ^ INLO) >> 6) & 1], stdout);
fputs (status[((count ^ INHI) >> 4) & 1], stdout);
cyan_write_copier (0, parport);
cyan_delay (1, parport);
count = cyan_read_copier (parport);
fputs (status[((count ^ INLO) >> 6) & 1], stdout);
fputs (status[((count ^ INHI) >> 4) & 1], stdout);
cyan_write_copier (CNLO | CNHI, parport);
cyan_delay (1, parport);
count = cyan_read_copier (parport);
fputs (status[((count ^ INLO) >> 6) & 1], stdout);
fputs (status[((count ^ INHI) >> 4) & 1], stdout);
cyan_write_copier (0, parport);
cyan_delay (1, parport);
count = cyan_read_copier (parport);
fputs (status[((count ^ INLO) >> 6) & 1], stdout);
fputs (status[((count ^ INHI) >> 4) & 1], stdout);
cyan_write_copier (CNLO | CNHI, parport);
cyan_delay (1, parport);
count = cyan_read_copier (parport);
fputs (status[((count ^ INLO) >> 6) & 1], stdout);
fputs (status[((count ^ INHI) >> 4) & 1], stdout);
cyan_write_copier (0, parport);
cyan_delay (1, parport);
count = cyan_read_copier (parport);
fputs (status[((count ^ INLO) >> 6) & 1], stdout);
fputs (status[((count ^ INHI) >> 4) & 1], stdout);
cyan_write_copier (CNLO | CNHI, parport);
cyan_delay (1, parport);
count = cyan_read_copier (parport);
fputs (status[((count ^ INLO) >> 6) & 1], stdout);
fputs (status[((count ^ INHI) >> 4) & 1], stdout);
cyan_write_copier (0, parport);
cyan_delay (1, parport);
fflush (stdout);
if (check_exit ())
{
cyan_reset (parport);
puts ("\nUser aborted test");
exit (0);
}
}
break;
default: // cmc_test() should only pass a correct speed value
fputs ("INTERNAL ERROR: Invalid test number passed to cyan_test_copier()\n", stderr);
exit (1);
}
return 0;
}
static int
cyan_copy_rom (const char *filename, int speed, unsigned int parport)
/*
Copy a ROM file -- this assumes the filename is valid and the file does not
already exist, since it will blindly try to write (overwrite) the filename you
give it.
If the open failed due to an invalid filename or path, it prints an error.
Speed setting should be between 1-4, 3 is default, and this is verified.
*/
{
unsigned long romsize;
unsigned char *buffer;
FILE *f;
fputs (INTRO_TEXT, stdout);
parport_print_info ();
if (!strlen (filename))
{
fputs ("ERROR: Filename not specified\n"
" You must specify a filename on the commandline, as follows:\n"
" ucon64 " OPTION_LONG_S "xcmc dump.bin\n", stderr);
exit (1);
}
printf ("Speed %d selected\n", speed);
cyan_test_parport (parport);
printf ("Destination file: %s\n", filename);
if ((f = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
fclose (f);
puts ("NOTE: Dumping copier's full address space (file will be automatically trimmed\n"
" after dumping)\n"
"Press escape or q to abort\n");
buffer = cyan_read_rom (speed, parport, NULL);
if (!buffer)
{
remove (filename);
exit(0);
}
fputc ('\n', stdout);
romsize = cyan_calculate_rom_size (buffer, 0);
fputs ("Writing ROM to disk... ", stdout);
fflush (stdout);
if ((f = fopen (filename, "wb")) == NULL)
{
puts ("FAILED");
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
free (buffer);
exit (1);
}
if (fwrite (buffer, 1, romsize, f) != romsize)
{
puts ("FAILED");
fprintf (stderr, ucon64_msg[WRITE_ERROR], filename);
free (buffer);
fclose (f);
exit (1);
}
fclose (f);
printf ("%d kBytes OK\n"
"Verifying checksum... ", (int) (romsize / 1024));
fflush (stdout);
if (cyan_checksum_rom (buffer))
{
puts ("FAILED\n"
"WARNING: Checksum of ROM does not appear to be correct.\n"
" This may be normal for this ROM, or it may indicate a bad copy.\n"
" Please verify the ROM, and consider running a copier test");
}
else
puts ("OK");
puts ("Copy complete!\n"
"Don't forget to turn the ROM copier off, and never insert or remove a\n"
"cartridge with the power on");
free (buffer);
return 0;
}
#endif // USE_PARALLEL
/*******************
* uCON64 wrapping *
*******************/
const st_getopt2_t cmc_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "Cyan's Megadrive ROM copier"/*"1999-2004 Cyan Helkaraxe"*/,
NULL
},
#ifdef USE_PARALLEL
{
"xcmc", 0, 0, UCON64_XCMC,
NULL, "receive ROM from Cyan's Megadrive ROM copier; " OPTION_LONG_S "port=PORT",
&ucon64_wf[WF_OBJ_GEN_STOP_NO_ROM]
},
{
"xcmct", 1, 0, UCON64_XCMCT,
"TEST", "run test TEST\n"
"TEST=1 burn-in reliability test (specify speed)\n"
"TEST=2 testbench mode (experts only)",
&ucon64_wf[WF_OBJ_GEN_STOP_NO_ROM]
},
{
"xcmcm", 1, 0, UCON64_XCMCM,
"SPEED", "specify transfer speed\n"
"SPEED=1 slow (debug)\n"
"SPEED=2 medium\n"
"SPEED=3 fast (default)\n" // verify with value of DEFAULT_SPEED
"SPEED=4 full speed (risky)",
&ucon64_wf[WF_OBJ_GEN_SWITCH]
},
#endif // USE_PARALLEL
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
#ifdef USE_PARALLEL
int
cmc_read_rom (const char *filename, unsigned int parport, int speed)
{
#if (defined __unix__ || defined __BEOS__) && !defined __MSDOS__
init_conio ();
#endif
if (speed < 1 || speed > 4)
speed = DEFAULT_SPEED;
cyan_copy_rom (filename, speed, parport);
#if (defined __unix__ || defined __BEOS__) && !defined __MSDOS__
deinit_conio ();
#endif
return 0;
}
int
cmc_test (int test, unsigned int parport, int speed)
{
#if (defined __unix__ || defined __BEOS__) && !defined __MSDOS__
init_conio ();
#endif
if (test < 1 || test > 2)
{
fputs ("ERROR: Choose a test between 1 and 2 (inclusive)\n", stderr);
exit (1);
}
if (speed < 1 || speed > 4)
speed = DEFAULT_SPEED;
cyan_test_copier (test, speed, parport);
#if (defined __unix__ || defined __BEOS__) && !defined __MSDOS__
deinit_conio ();
#endif
return 0;
}
#endif // USE_PARALLEL

View File

@ -0,0 +1,32 @@
/*
cmc.h - Cyan's Megadrive ROM copier support for uCON64
Copyright (c) 1999-2004 Cyan Helkaraxe
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.
*/
// See cmc.c for important information
#ifndef CMC_H
#define CMC_H
extern const st_getopt2_t cmc_usage[];
#ifdef USE_PARALLEL
extern int cmc_read_rom (const char *filename, unsigned int parport, int speed);
extern int cmc_test (int test, unsigned int parport, int speed);
#endif
#endif

View File

@ -0,0 +1,139 @@
/*
dex.c - DexDrive support for uCON64
Copyright (c) 2002 NoisyB <noisyb@gmx.net>
Copyright (c) 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 "misc/misc.h"
#include "misc/file.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "ucon64.h"
#include "ucon64_misc.h"
#include "dex.h"
#include "psxpblib.h"
#include "misc/parallel.h"
const st_getopt2_t dex_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "DexDrive"/*"19XX InterAct http://www.dexdrive.de"*/,
NULL
},
{
"xdex", 1, 0, UCON64_XDEX,
"N", "send/receive Block N to/from DexDrive; " OPTION_LONG_S "port=PORT\n"
"receives automatically when SRAM does not exist",
&ucon64_wf[WF_OBJ_ALL_DEFAULT_STOP_NO_ROM]
},
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
#ifdef USE_PARALLEL
#define CONPORT 1
#define TAP 1
#define DELAY 4
#define FRAME_SIZE 128
#define BLOCK_SIZE (64*FRAME_SIZE)
static int print_data;
static unsigned char *
read_block (int block_num)
{
return psx_memcard_read_block (print_data, CONPORT, TAP, DELAY, block_num);
}
static int
write_block (int block_num, unsigned char *data)
{
return psx_memcard_write_block (print_data, CONPORT, TAP, DELAY, block_num,
data);
}
#if 0
char *
read_frame (int frame, char *data)
{
return psx_memcard_read_frame (print_data, CONPORT, TAP, DELAY, frame);
}
int
write_frame (int frame, char *data)
{
return psx_memcard_write_frame (print_data, CONPORT, TAP, DELAY, frame,
data);
}
#endif
int
dex_read_block (const char *filename, int block_num, unsigned int parport)
{
unsigned char *data;
print_data = parport;
parport_print_info ();
if ((data = read_block (block_num)) == NULL)
{
fprintf (stderr, ucon64_msg[PARPORT_ERROR]);
exit (1);
}
ucon64_fwrite (data, 0, BLOCK_SIZE, filename, "wb");
return 0;
}
int
dex_write_block (const char *filename, int block_num, unsigned int parport)
{
unsigned char data[BLOCK_SIZE];
print_data = parport;
parport_print_info ();
ucon64_fread (data, 0, BLOCK_SIZE, filename);
if (write_block (block_num, data) == -1)
{
fprintf (stderr, ucon64_msg[PARPORT_ERROR]);
exit (1);
}
return 0;
}
#endif // USE_PARALLEL

View File

@ -0,0 +1,34 @@
/*
dex.h - DexDrive support for uCON64
Copyright (c) 2002 NoisyB <noisyb@gmx.net>
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.
*/
#ifndef DEX_H
#define DEX_H
extern const st_getopt2_t dex_usage[];
#define DEX_HEADER_START 0
#define DEX_HEADER_LEN 0
#ifdef USE_PARALLEL
extern int dex_read_block (const char *filename, int block_num, unsigned int parport);
extern int dex_write_block (const char *filename, int block_num, unsigned int parport);
#endif // USE_PARALLEL
#endif

View File

@ -0,0 +1,399 @@
/*
doctor64.c - Bung Doctor V64 support for uCON64
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
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 <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "misc/misc.h"
#include "misc/file.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "ucon64.h"
#include "ucon64_misc.h"
#include "doctor64.h"
#include "misc/parallel.h"
const st_getopt2_t doctor64_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "Doctor V64"/*"19XX Bung Enterprises Ltd http://www.bung.com.hk"*/,
NULL
},
#ifdef USE_PARALLEL
{
"xv64", 0, 0, UCON64_XV64,
NULL, "send/receive ROM to/from Doctor V64; " OPTION_LONG_S "port=PORT\n"
"receives automatically when ROM does not exist",
&ucon64_wf[WF_OBJ_N64_DEFAULT_STOP_NO_ROM]
},
#endif
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
#ifdef USE_PARALLEL
#define SYNC_MAX_CNT 8192
#define SYNC_MAX_TRY 32
#define SEND_MAX_WAIT 0x300000
#define REC_HIGH_NIBBLE 0x80
#define REC_LOW_NIBBLE 0x00
#define REC_MAX_WAIT SEND_MAX_WAIT
static int
parport_write (char src[], int len, unsigned int parport)
{
int maxwait, i;
for (i = 0; i < len; i++)
{
maxwait = SEND_MAX_WAIT;
if ((inportb ((unsigned short) (parport + 2)) & 1) == 0) // check ~strobe
{
while (((inportb ((unsigned short) (parport + 2)) & 2) != 0) && maxwait--)
; // wait for
if (maxwait <= 0)
return 1; // auto feed == 0
outportb ((unsigned short) parport, src[i]); // write data
outportb ((unsigned short) (parport + 2), 5); // ~strobe = 1
}
else
{
while (((inportb ((unsigned short) (parport + 2)) & 2) == 0) && maxwait--)
; // wait for
if (maxwait <= 0)
return 1; // auto feed == 1
outportb ((unsigned short) parport, src[i]); // write data
outportb ((unsigned short) (parport + 2), 4); // ~strobe = 0
}
}
return 0;
}
static int
parport_read (char dest[], int len, unsigned int parport)
{
int i, maxwait;
unsigned char c;
for (i = 0; i < len; i++)
{
outportb ((unsigned short) parport, REC_HIGH_NIBBLE);
maxwait = REC_MAX_WAIT;
while (((inportb ((unsigned short) (parport + 1)) & 0x80) == 0) && maxwait--)
; // wait for ~busy=1
if (maxwait <= 0)
return len - i;
c = (inportb ((unsigned short) (parport + 1)) >> 3) & 0x0f; // ~ack, pe, slct, ~error
outportb ((unsigned short) parport, REC_LOW_NIBBLE);
maxwait = REC_MAX_WAIT;
while (((inportb ((unsigned short) (parport + 1)) & 0x80) != 0) && maxwait--)
; // wait for ~busy=0
if (maxwait <= 0)
return len - i;
c |= (inportb ((unsigned short) (parport + 1)) << 1) & 0xf0; // ~ack, pe, slct, ~error
dest[i] = c;
}
outportb ((unsigned short) parport, REC_HIGH_NIBBLE);
return 0;
}
int
syncHeader (unsigned int baseport)
{
int i = 0;
outportb ((unsigned short) baseport, 0); // data = 00000000
outportb ((unsigned short) (baseport + 2), 4); // ~strobe=0
while (i < SYNC_MAX_CNT)
{
if ((inportb ((unsigned short) (baseport + 2)) & 8) == 0) // wait for select=0
{
outportb ((unsigned short) (baseport), 0xaa); // data = 10101010
outportb ((unsigned short) (baseport + 2), 0); // ~strobe=0, ~init=0
while (i < SYNC_MAX_CNT)
{
if ((inportb ((unsigned short) (baseport + 2)) & 8) != 0) // wait for select=1
{
outportb ((unsigned short) (baseport + 2), 4); // ~strobe=0
while (i < SYNC_MAX_CNT)
{
if ((inportb ((unsigned short) (baseport + 2)) & 8) == 0) // w for select=0
{
outportb ((unsigned short) baseport, 0x55); // data = 01010101
outportb ((unsigned short) (baseport + 2), 0); // ~strobe=0, ~init=0
while (i < SYNC_MAX_CNT)
{
if ((inportb ((unsigned short) (baseport + 2)) & 8) != 0) // w select=1
{
outportb ((unsigned short) (baseport + 2), 4); // ~strobe=0
while (i < SYNC_MAX_CNT)
{
if ((inportb ((unsigned short) (baseport + 2)) & 8) == 0) // select=0
return 0;
i++;
}
}
i++;
}
}
i++;
}
}
i++;
}
i++;
}
i++;
}
outportb ((unsigned short) (baseport + 2), 4);
return 1;
}
int
initCommunication (unsigned int port)
{
int i;
for (i = 0; i < SYNC_MAX_TRY; i++)
{
if (syncHeader (port) == 0)
break;
}
if (i >= SYNC_MAX_TRY)
return -1;
return 0;
}
int
checkSync (unsigned int baseport)
{
int i, j;
for (i = 0; i < SYNC_MAX_CNT; i++)
{
if (((inportb ((unsigned short) (baseport + 2)) & 3) == 3)
|| ((inportb ((unsigned short) (baseport + 2)) & 3) == 0))
{
outportb ((unsigned short) baseport, 0); // ~strobe, auto feed
for (j = 0; j < SYNC_MAX_CNT; j++)
{
if ((inportb ((unsigned short) (baseport + 1)) & 0x80) == 0) // wait for ~busy=0
{
return 0;
}
}
return 1;
}
}
return 1;
}
int
sendFilename (unsigned int baseport, char name[])
{
int i;
char *c, mname[12];
memset (mname, ' ', 11);
c = (strrchr (name, FILE_SEPARATOR));
if (c == NULL)
{
c = name;
}
else
{
c++;
}
for (i = 0; i < 8 && *c != '.' && *c != '\0'; i++, c++)
mname[i] = toupper (*c);
c = strrchr (c, '.');
if (c != NULL)
{
c++;
for (i = 8; i < 11 && *c != '\0'; i++, c++)
mname[i] = toupper (*c);
}
return parport_write (mname, 11, baseport);
}
int
sendUploadHeader (unsigned int baseport, char name[], int len)
{
char mname[12], lenbuffer[4];
static char protocolId[] = "GD6R\1";
if (parport_write (protocolId, strlen (protocolId), baseport) != 0)
return 1;
lenbuffer[0] = (char) len;
lenbuffer[1] = (char) (len >> 8);
lenbuffer[2] = (char) (len >> 16);
lenbuffer[3] = (char) (len >> 24);
if (parport_write (lenbuffer, 4, baseport) != 0)
return 1;
memset (mname, ' ', 11);
if (sendFilename (baseport, name) != 0)
return 1;
return 0;
}
int
sendDownloadHeader (unsigned int baseport, int *len)
{
char mname[12];
static char protocolId[] = "GD6W";
unsigned char recbuffer[15];
if (parport_write (protocolId, strlen (protocolId), baseport) != 0)
return 1;
memset (mname, ' ', 11);
if (parport_write (mname, 11, baseport) != 0)
return 1;
if (checkSync (baseport) != 0)
return 1;
if (parport_read ((char *) recbuffer, 1, baseport) != 0)
return 1;
if (recbuffer[0] != 1)
return -1;
if (parport_read ((char *) recbuffer, 15, baseport) != 0)
return 1;
*len = (int) recbuffer[0] |
((int) recbuffer[1] << 8) |
((int) recbuffer[2] << 16) |
((int) recbuffer[3] << 24);
return 0;
}
int
doctor64_read (const char *filename, unsigned int parport)
{
char buf[MAXBUFSIZE];
FILE *fh;
int size, inittime, bytesreceived = 0;
parport_print_info ();
if (initCommunication (parport) == -1)
{
fprintf (stderr, ucon64_msg[PARPORT_ERROR]);
exit (1);
}
inittime = time (0);
if (sendDownloadHeader (parport, &size) != 0)
{
fprintf (stderr, ucon64_msg[PARPORT_ERROR]);
exit (1);
}
if (!(fh = fopen (filename, "wb")))
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
printf ("Receive: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
for (;;)
{
if (parport_read (buf, sizeof buf, parport) != 0)
{
fclose (fh);
return 0;
}
bytesreceived += sizeof buf;
fwrite (buf, 1, sizeof buf, fh);
ucon64_gauge (inittime, bytesreceived, size);
}
sync ();
fclose (fh);
return 0;
}
int
doctor64_write (const char *filename, int start, int len, unsigned int parport)
{
char buf[MAXBUFSIZE];
FILE *fh;
unsigned int size, inittime, pos, bytessend = 0;
parport_print_info ();
size = len - start;
if (initCommunication (parport) == -1)
{
fprintf (stderr, ucon64_msg[PARPORT_ERROR]);
exit (1);
}
inittime = time (0);
strcpy (buf, filename);
if (sendUploadHeader (parport, buf, size) != 0)
{
fprintf (stderr, ucon64_msg[PARPORT_ERROR]);
exit (1);
}
if (!(fh = fopen (filename, "rb")))
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
printf ("Send: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
for (;;)
{
if (!(pos = fread (buf, 1, sizeof buf, fh)))
break;
if (parport_write (buf, pos, parport) != 0)
break;
bytessend += sizeof buf;
ucon64_gauge (inittime, bytessend, size);
}
fclose (fh);
return 0;
}
#endif // USE_PARALLEL

View File

@ -0,0 +1,31 @@
/*
doctor64.h - Bung Doctor V64 support for uCON64
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
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.
*/
#ifndef DOCTOR64_H
#define DOCTOR64_H
extern const st_getopt2_t doctor64_usage[];
#ifdef USE_PARALLEL
extern int doctor64_read (const char *filename, unsigned int parport);
extern int doctor64_write (const char *filename, int start, int len, unsigned int parport);
#endif
#endif

View File

@ -0,0 +1,587 @@
/*
doctor64jr.c - Bung Doctor V64 Junior support for uCON64
Copyright (c) 1999 - 2002 NoisyB <noisyb@gmx.net>
Copyright (c) 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.
*/
/*
drjr transfer protocol
DB25 pin name
p2~p9 pd[7:0] XXXXXXXXXXX ai XXXXX data XXXX
p1 nwrite ~~~~~~~~~|_____________________|~~
p14 ndstb ~~~~~~~~~~~~~~~~~~~~~~~~~|_|~~~~~~
p17 nastb ~~~~~~~~~~~~~|_|~~~~~~~~~~~~~~~~~~
ai[]=0 r/w a[7..0]
ai[]=1 r/w a[15..8]
ai[]=2 r/w a[23..16]
ai[]=3 w a[28..24]
ai[]=3 r (rst,wdf,wcf,a[28..24])
ai[]=4 r/w data
ai[]=5 w mode
ai[]=6 w en_1
ai[]=7 w en_0
*remark
a[8..1] support page count up
ai[3]d7:0=N64 power off, 1=N64 power on
d6:0=no dram data written, 1=dram data written
d5:0=no data write in b4000000~b7ffffff, 1=some data written in b4000000~b7ffffff
mode d0:0=dram read only and clear wdf, 1=dram write enable
d1:0=disable cartridge read and clear wcf flag,
1=enable cartridge read(write b4000000~b7ffffff will switch off dram and cartridge will present at b0000000~b3ffffff)
en_0=05 and en_1=0a is enable port control
mode:q0 0 1 0 1
mode:q1 0 0 1 1
b7ff ffff
b400 0000 dram read only dram r/w cartridge read cartridge read(* write this area will switch off dram)
b3ff ffff
b000 0000 dram read only dram r/w dram read only dram r/w
eg:enable port control
DB25 pin name
p2~p9 pd[7:0] XXXXXXXXXXX 07 XX 05 XXXX 06 XX 0a XXXXXXXXXXXX
p1 nwrite ~~~~~~~~~|_____________________________|~~~~~~~
p14 ndstb ~~~~~~~~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~~
p17 nastb ~~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~~~~~~~~
en_0=05 en_1=0a
eg:write adr $b0123456, data $a55a,$1234..
DB25 pin name
p2~p9 pd[7:0] XXXXXXXXXXX 00 XX 56 XXXX 01 XX 34 XXXX 02 XX 12 XXXX 03 XX b0 XXXXXX 04 XX 5a XX a5 XX 34 XX 12 XXXXXXXXXXX
p1 nwrite ~~~~~~~~~|_______________________________________________________________________________________|~~~~~~~~~~
p14 ndstb ~~~~~~~~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~~~|_|~~~|_|~~~|_|~~~|_|~~~~~~~~~~~
p17 nastb ~~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~~~|_|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
set adr word low set adr word high wdata a55a wdata 1234 (after write adr=b012345a)
eg:read adr $b0123400~$b01235ff, 512 data
DB25 pin name
p2~p9 pd[7:0] XXXXXXXXXXX 00 XX 00 XXXX 01 XX 34 XXXX 02 XX 12 XXXX 03 XX b0 XXXXXX 04 XX data0 XX data1 X ... X data510 XX data511 XXXXX
p1 nwrite ~~~~~~~~~|________________________________________________________________~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
p14 ndstb ~~~~~~~~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~~~~|_|~~~~~~|_|~~~ ~~~ ~~~~|_|~~~~~~~~|_|~~~~~~~~
p17 nastb ~~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~~~|_|~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
set adr word low set adr word high (after 512 read adr=b0123400)
eg:dram write protect, disable N64 access to cartridge and disable port control
DB25 pin name
p2~p9 pd[7:0] XXXXXXXXXXX 05 XX 00 XXXX 07 XX 00 XXXX 06 XX 00 XXXXXXXXXXXX
p1 nwrite ~~~~~~~~~|________________________________________|~~~~~~~~~~
p14 ndstb ~~~~~~~~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~~
p17 nastb ~~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~|_|~~~~~~~~~~~~~~~~~~
mode=00 en_0=00 en_1=00
simple backup rountine for N64
void writePI(unsigned long addr, unsigned long value)
{
do {} while (*(volatile unsigned long *) (0xa4600010) & 3); // check parallel interface not busy
addr &=0xbffffffc;
*(unsigned long *)(addr)=value;
}
unsigned long readPI(unsigned long addr)
{
do {} while (*(volatile unsigned long *) (0xa4600010) & 3); // check parallel interface not busy
addr &=0xbffffffc;
return *(unsigned long *)(addr);
}
// MAIN -- START OF USER CODE
void mainproc(void *arg) {
u32 base_adr;
for (base_adr=0;base_adr<0x1000000;base_adr++){ // backup 128Mbits
writePI(0xb0000000+base_adr,readPI(0xb4000000 + base_adr)); // write data
}
}
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "misc/misc.h"
#include "misc/itypes.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "misc/parallel.h"
#include "misc/file.h"
#include "ucon64.h"
#include "ucon64_misc.h"
#include "doctor64jr.h"
const st_getopt2_t doctor64jr_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "Doctor V64 Junior"/*"19XX Bung Enterprises Ltd http://www.bung.com.hk"*/,
NULL
},
#ifdef USE_PARALLEL
{
"xdjr", 0, 0, UCON64_XDJR,
NULL, "send ROM to Doctor V64 Junior; " OPTION_LONG_S "port=PORT",
&ucon64_wf[WF_OBJ_N64_DEFAULT_STOP_NO_ROM]
},
#if 0
{
"xdjrs", 0, 0, UCON64_XDJRS,
NULL, "send/receive SRAM to/from Doctor V64 Junior; " OPTION_LONG_S "port=PORT\n"
"receives automatically when SRAM does not exist",
&ucon64_wf[WF_OBJ_N64_DEFAULT_STOP_NO_ROM]
},
#endif
#endif // USE_PARALLEL
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
#ifdef USE_PARALLEL
#define BUFFERSIZE 32768
//#define set_ai_write outportb (port_a, 5); // ninit=1, nwrite=0
#define set_data_write outportb (port_a, 1); // ninit=0, nwrite=0
#define set_data_read outportb (port_a, 0); // ninit=0, nwrite=1
//#define set_normal outportb (port_a, 4); // ninit=1, nwrite=1
static unsigned short int port_8, port_9, port_a, port_b, port_c,
*buffer;
static int wv_mode;
static void
set_ai (unsigned char ai)
{
outportb (port_a, 5); // ninit=1, nwrite=0
outportb (port_b, ai);
}
static void
set_ai_data (unsigned char ai, unsigned char data)
{
set_ai (ai);
set_data_write // ninit=0, nwrite=0
outportb (port_c, data);
}
static void
init_port (int enable_write)
{
#ifndef USE_PPDEV
outportb (port_9, 1); // clear EPP time flag
#endif
set_ai_data (6, 0x0a);
set_ai_data (7, 0x05); // 6==0x0a, 7==0x05 is pc_control mode
// set_ai (5);
// set_data_read
// enable_write = inportb (port_c);
set_ai_data (5, (unsigned char) enable_write); // d0=0 is write protect mode
}
static void
end_port (int enable_write)
{
set_ai_data (5, (unsigned char) enable_write); // d0=0 is write protect mode
set_ai_data (7, 0); // release pc mode
set_ai_data (6, 0); // 6==0x0a, 7==0x05 is pc_control mode
outportb (port_a, 4); // ninit=1, nwrite=1
}
static int
check_card (void)
{
set_ai_data (3, 0x12);
set_ai_data (2, 0x34);
set_ai_data (1, 0x56);
set_ai_data (0, 0x78);
set_ai (3);
set_data_read // ninit=0, nwrite=1
if ((inportb (port_c) & 0x1f) != 0x12)
return 1;
set_ai (2);
set_data_read
if (inportb (port_c) != 0x34)
return 1;
set_ai (1);
set_data_read
if (inportb (port_c) != 0x56)
return 1;
set_ai (0);
set_data_read
if (inportb (port_c) != 0x78)
return 1;
return 0;
}
static int
write_32k (unsigned short int hi_word, unsigned short int lo_word)
{
unsigned char unpass, pass1;
unsigned short int i, j, fix;
set_ai_data (3, (unsigned char) (0x10 | (hi_word >> 8)));
set_ai_data (2, (unsigned char) hi_word);
for (i = 0; i < 0x40; i++)
{
unpass = 3;
while (unpass)
{
set_ai_data (1, (unsigned char) ((i << 1) | lo_word));
set_ai_data (0, 0);
set_ai (4); // set address index=4
set_data_write // ninit=0, nwrite=0
fix = i << 8;
for (j = 0; j < 256; j++)
outportw (port_c, buffer[j + fix]);
set_data_read // ninit=0, nwrite=1
if (wv_mode)
{
for (j = 0; j < 256; j++)
if (inportw (port_c) != buffer[j + fix])
break;
}
else
{
pass1 = 1;
for (j = 0; j < 4; j++)
if (inportw (port_c) != buffer[j + fix])
{
pass1 = 0;
break;
}
if (pass1)
{
set_ai_data (1, (unsigned char) ((i << 1) | lo_word | 1));
set_ai_data (0, 0xf8);
set_ai (4);
set_data_read // ninit=0, nwrite=1
for (j = 252; j < 256; j++)
if (inportw (port_c) != buffer[j + fix])
break;
}
}
set_ai (0);
set_data_read // ninit=0, nwrite=1
if (inportb (port_c) != 0)
{
unpass--;
outportb (port_a, 0x0b); // set all pin=0 for debug
set_ai_data (3, (unsigned char) (0x10 | (hi_word >> 8)));
set_ai_data (2, (unsigned char) hi_word);
if (unpass == 0)
return 1;
}
else
unpass = 0;
}
}
/*
outportb (ai, 0);
printf ("\na[7..0]=%02x\n", inportb (data));
outportb (ai, 1);
printf ("a[15..8]=%02x\n", inportb (data));
*/
return 0;
}
#if 0 // not used
static int
verify_32k (unsigned short int hi_word, unsigned short int lo_word)
{
char unpass;
unsigned short int i, j, fix;
set_ai_data (3, (unsigned char) (0x10 | (hi_word >> 8)));
set_ai_data (2, (unsigned char) hi_word);
for (i = 0; i < 0x40; i++)
{
unpass = 3;
while (unpass)
{
set_ai_data (1, (unsigned char) ((i << 1) | lo_word));
set_ai_data (0, 0);
set_ai (4);
set_data_read // ninit=0, nwrite=1
fix = i << 8;
for (j = 0; j < 256; j++)
{
if (inportw (port_c) != buffer[j + fix])
{
outportb (port_a, 0x0b); // all pin=0 for debug
set_ai_data (3, (unsigned char) (0x10 | (hi_word >> 8)));
set_ai_data (2, (unsigned char) hi_word);
unpass--;
if (unpass == 0)
return 1;
else
break;
}
}
if (j == 256)
break;
}
}
/*
outportb (ai,0);
printf ("\na[7..0]=%02x\n", inportb (data));
outportb (ai, 1);
printf ("a[15..8]=%02x\n", inportb (data));
*/
return 0;
}
static void
gen_pat_32k (unsigned short int offset)
{
int i;
for (i = 0; i < 0x4000; i++)
buffer[i] = i + offset;
}
static unsigned short int
test_dram (void)
{
int n_pages = 0, page;
gen_pat_32k (0x0000);
write_32k (0, 0);
gen_pat_32k (0x8000);
write_32k (0x100, 0);
gen_pat_32k (0x0000);
if (verify_32k (0, 0) == 0) // find lower 128 Mbits
n_pages = 0x100;
gen_pat_32k (0x8000);
if (verify_32k (0x100, 0) == 0) // find upper 128 Mbits
n_pages = 0x200;
printf ("Testing DRAM...\n");
for (page = 0; page < n_pages; page++)
{
gen_pat_32k ((unsigned short int) (page * 2));
if (write_32k (page, 0))
return 0;
else
{
fputc ('w', stdout);
fflush (stdout);
}
gen_pat_32k ((unsigned short int) (page * 2 + 1));
if (write_32k (page, 0x80))
return 0;
else
{
fputc ('w', stdout);
fflush (stdout);
}
}
fputc ('\n', stdout);
for (page = 0; page < n_pages; page++)
{
gen_pat_32k ((unsigned short int) (page * 2));
if (verify_32k (page, 0))
return 0;
else
{
fputc ('v', stdout);
fflush (stdout);
}
gen_pat_32k ((unsigned short int) (page * 2 + 1));
if (verify_32k (page, 0x80))
return 0;
else
{
fputc ('v', stdout);
fflush (stdout);
}
}
return n_pages;
}
#endif
static unsigned long int
get_address (void)
{
unsigned long int address;
set_ai_data (6, 0x0a); // enable pc mode
set_ai_data (7, 0x05); // enable pc mode
set_ai (3);
set_data_read // ninit=0, nwrite=1
address = inportb (port_c) << 24;
set_ai (2);
set_data_read
address |= inportb (port_c) << 16;
set_ai (1);
set_data_read
address |= inportb (port_c) << 8;
set_ai (0);
set_data_read
address |= inportb (port_c);
return address;
}
int
doctor64jr_read (const char *filename, unsigned int parport)
{
(void) filename;
(void) parport;
return fprintf (stderr, "ERROR: The function for dumping a cartridge is not yet implemented for the\n"
" Doctor V64 Junior\n");
}
int
doctor64jr_write (const char *filename, unsigned int parport)
{
unsigned int enable_write = 0, init_time, size, bytesread, bytessend = 0,
n_pages;
unsigned short int page;
FILE *file;
parport_print_info ();
port_8 = parport;
port_9 = parport + 1;
port_a = parport + 2;
port_b = parport + 3;
port_c = parport + 4;
init_port (enable_write);
if (check_card () != 0)
{
fprintf (stderr, "ERROR: No Doctor V64 Junior card present\n");
end_port (enable_write);
exit (1);
}
wv_mode = 0;
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
if ((buffer = (unsigned short int *) malloc (BUFFERSIZE)) == NULL)
{
fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
exit (1);
}
size = fsizeof (filename);
printf ("Send: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
#if 0
if (dram_test)
{
dram_size = test_dram ();
if (dram_size)
printf ("\nDRAM size=%dMbits\n", (dram_size / 2));
else
fprintf (stderr, "\nERROR: DRAM test failed\n");
return 0;
}
#endif
n_pages = (size + (64 * 1024 - 1)) / (64 * 1024); // "+ (64 * 1024 - 1)" to round up
init_time = time (0);
for (page = 0; page < n_pages; page++)
{
bytesread = fread ((unsigned char *) buffer, 1, BUFFERSIZE, file);
if (write_32k (page, 0))
{
fprintf (stderr, "ERROR: Transfer failed at address 0x%8lx", get_address ());
break;
}
bytesread += fread ((unsigned char *) buffer, 1, BUFFERSIZE, file);
if (write_32k (page, 0x80))
{
fprintf (stderr, "ERROR: Transfer failed at address 0x%8lx", get_address ());
break;
}
bytessend += bytesread;
ucon64_gauge (init_time, bytessend, size);
}
fputc ('\n', stdout);
if (enable_write) // 1 or 3
printf ("DRAM write protect disabled\n");
if (enable_write & 2) // 3
printf ("Run cartridge enabled\n");
// set_ai_data(5, enable_write); // d0=0 is write protect mode
end_port (enable_write);
return 0;
}
#endif // USE_PARALLEL

View File

@ -0,0 +1,31 @@
/*
doctor64jr.h - Bung Doctor V64 Junior support for uCON64
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
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.
*/
#ifndef DOCTOR64JR_H
#define DOCTOR64JR_H
extern const st_getopt2_t doctor64jr_usage[];
#ifdef USE_PARALLEL
extern int doctor64jr_read (const char *filename, unsigned int parport);
extern int doctor64jr_write (const char *filename, unsigned int parport);
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,34 @@
/*
f2a.h - Flash 2 Advance support for uCON64
Copyright (c) 2003 Ulrich Hecht <uli@emulinks.de>
Copyright (c) 2004 NoisyB <noisyb@gmx.net>
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.
*/
#ifndef F2A_H
#define F2A_H
extern const st_getopt2_t f2a_usage[];
#if defined USE_PARALLEL || defined USE_USB
extern int f2a_read_rom (const char *filename, int size);
extern int f2a_write_rom (const char *filename, int size);
extern int f2a_read_sram (const char *filename, int bank);
extern int f2a_write_sram (const char *filename, int bank);
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
/*
fal.h - Flash Linker Advance support for uCON64
Copyright (c) 2001 Jeff Frohwein
Copyright (c) 2001 NoisyB <noisyb@gmx.net>
Copyright (c) 2001 - 2002 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.
*/
#ifndef FAL_H
#define FAL_H
extern const st_getopt2_t fal_usage[];
#ifdef USE_PARALLEL
extern int fal_read_rom (const char *filename, unsigned int parport, int size);
extern int fal_write_rom (const char *filename, unsigned int parport);
extern int fal_read_sram (const char *filename, unsigned int parport, int bank);
extern int fal_write_sram (const char *filename, unsigned int parport, int bank);
#endif
#endif

View File

@ -0,0 +1,316 @@
/*
ffe.c - General Front Far East copier routines for uCON64
Copyright (c) 2002 - 2004 dbjh
Copyright (c) 2003 JohnDie
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 <time.h>
#include <string.h>
#include "misc/misc.h" // kbhit(), getch()
#include "misc/itypes.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "ucon64.h"
#include "ucon64_misc.h"
#include "ffe.h"
#include "misc/parallel.h"
#ifdef USE_PARALLEL
#define N_TRY_MAX 65536 // # times to test if copier ready
static void ffe_sendb (unsigned char byte);
static unsigned char ffe_wait_while_busy (void);
static int ffe_port;
void
ffe_init_io (unsigned int port)
/*
- sets global `ffe_port'. Then the send/receive functions don't need to pass `port' all
the way to ffe_sendb()/ffe_receiveb().
- calls init_conio(). Necessary for kbhit() and DOS-like behaviour of getch().
*/
{
ffe_port = port;
#if 0 // we want to support non-standard parallel port addresses
if (ffe_port != 0x3bc && ffe_port != 0x378 && ffe_port != 0x278)
{
fprintf (stderr, "ERROR: PORT must be 0x3bc, 0x378 or 0x278\n");
exit (1);
}
#endif
#if (defined __unix__ || defined __BEOS__) && !defined __MSDOS__
init_conio ();
#endif
parport_print_info ();
}
void
ffe_deinit_io (void)
{
#if (defined __unix__ || defined __BEOS__) && !defined __MSDOS__
deinit_conio ();
#endif
}
void
ffe_send_block (unsigned short address, unsigned char *buffer, int len)
{
int n;
unsigned char checksum = 0x81;
ffe_send_command (0, address, (unsigned short) len);
for (n = 0; n < len; n++)
{
ffe_sendb (buffer[n]);
checksum ^= buffer[n];
}
ffe_sendb (checksum);
}
void
ffe_send_block2 (unsigned short address, unsigned char *buffer, int len)
{
int n;
unsigned char checksum = 0x81;
ffe_send_command (2, address, (unsigned short) len);
for (n = 0; n < len; n++)
{
ffe_sendb (buffer[n]);
checksum ^= buffer[n];
}
ffe_sendb (checksum);
}
void
ffe_send_command0 (unsigned short address, unsigned char byte)
// command 0 for 1 byte
{
ffe_send_command (0, address, 1);
ffe_sendb (byte);
ffe_sendb ((unsigned char) (0x81 ^ byte));
}
unsigned char
ffe_send_command1 (unsigned short address)
// command 1 for 1 byte
{
unsigned char byte;
ffe_send_command (1, address, 1);
byte = ffe_receiveb ();
if ((0x81 ^ byte) != ffe_receiveb ())
puts ("received data is corrupt");
return byte;
}
void
ffe_send_command (unsigned char command_code, unsigned short a, unsigned short l)
{
ffe_sendb (0xd5);
ffe_sendb (0xaa);
ffe_sendb (0x96);
ffe_sendb (command_code);
ffe_sendb ((unsigned char) a); // low byte
ffe_sendb ((unsigned char) (a >> 8)); // high byte
ffe_sendb ((unsigned char) l); // low byte
ffe_sendb ((unsigned char) (l >> 8)); // high byte
ffe_sendb ((unsigned char) (0x81 ^ command_code ^ a ^ (a >> 8) ^ l ^ (l >> 8))); // check sum
}
void
ffe_sendb (unsigned char byte)
{
ffe_wait_for_ready ();
outportb ((unsigned short) (ffe_port + PARPORT_DATA), byte);
outportb ((unsigned short) (ffe_port + PARPORT_CONTROL),
(unsigned char) (inportb ((unsigned short) // invert strobe
(ffe_port + PARPORT_CONTROL)) ^ PARPORT_STROBE));
ffe_wait_for_ready (); // necessary if followed by ffe_receiveb()
}
void
ffe_receive_block (unsigned short address, unsigned char *buffer, int len)
{
volatile int n;
int n_try = 0;
unsigned char checksum1, checksum2;
do
{
checksum1 = 0x81;
ffe_send_command (1, address, (unsigned short) len);
for (n = 0; n < len; n++)
{
buffer[n] = ffe_receiveb ();
checksum1 ^= buffer[n];
}
checksum2 = ffe_receiveb ();
for (n = 0; n < 65536; n++) // a delay is necessary here
;
n_try++;
}
while ((checksum1 != checksum2) && (n_try < N_TRY_MAX));
if (checksum1 != checksum2)
puts ("\nreceived data is corrupt");
}
void
ffe_receive_block2 (unsigned short address, unsigned char *buffer, int len)
{
volatile int n;
int n_try = 0;
unsigned char checksum1, checksum2;
do
{
checksum1 = 0x81;
ffe_send_command (3, address, (unsigned short) len);
for (n = 0; n < len; n++)
{
buffer[n] = ffe_receiveb ();
checksum1 ^= buffer[n];
}
checksum2 = ffe_receiveb ();
for (n = 0; n < 65536; n++) // a delay is necessary here
;
n_try++;
}
while ((checksum1 != checksum2) && (n_try < N_TRY_MAX));
if (checksum1 != checksum2)
puts ("\nreceived data is corrupt");
}
unsigned char
ffe_receiveb (void)
{
unsigned char byte;
byte = (unsigned char) ((ffe_wait_while_busy () & PARPORT_INPUT_MASK) >> 3); // receive low nibble
outportb ((unsigned short) (ffe_port + PARPORT_CONTROL),
(unsigned char) (inportb ((unsigned short) // invert strobe
(ffe_port + PARPORT_CONTROL)) ^ PARPORT_STROBE));
byte |= (unsigned char) ((ffe_wait_while_busy () & PARPORT_INPUT_MASK) << 1); // receive high nibble
outportb ((unsigned short) (ffe_port + PARPORT_CONTROL),
(unsigned char) (inportb ((unsigned short) // invert strobe
(ffe_port + PARPORT_CONTROL)) ^ PARPORT_STROBE));
return byte;
}
unsigned char
ffe_wait_while_busy (void)
{
unsigned char input;
int n_try = 0;
do
{
input = inportb ((unsigned short) (ffe_port + PARPORT_STATUS));
n_try++;
}
while (input & PARPORT_IBUSY && n_try < N_TRY_MAX);
#if 0
/*
VGS doesn't check for this, and it seems to happen quite regularly, so it
is currently commented out
*/
if (n_try >= N_TRY_MAX)
{
fputs ("ERROR: The copier is not ready\n" // yes, "ready" :-)
" Turn it off for a few seconds then turn it on and try again\n",
stderr);
exit (1);
}
#endif
// read port again to let data settle down and to delay a little bit - JohnDie
return inportb ((unsigned short) (ffe_port + PARPORT_STATUS));
}
void
ffe_wait_for_ready (void)
{
unsigned char input;
int n_try = 0;
do
{
input = inportb ((unsigned short) (ffe_port + PARPORT_STATUS));
n_try++;
}
while (!(input & PARPORT_IBUSY) && n_try < N_TRY_MAX);
#if 0
if (n_try >= N_TRY_MAX)
{
fputs ("ERROR: The copier is not ready\n"
" Turn it off for a few seconds then turn it on and try again\n",
stderr);
exit (1);
}
#endif
}
void
ffe_checkabort (int status)
{
if (((!ucon64.frontend) ? kbhit () : 0) && getch () == 'q')
{
// ffe_send_command (5, 0, 0); // VGS: when sending/receiving a SNES ROM
puts ("\nProgram aborted");
exit (status);
}
}
#endif // USE_PARALLEL

View File

@ -0,0 +1,80 @@
/*
ffe.h - General Front Far East copier routines for uCON64
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.
*/
#ifndef FFE_H
#define FFE_H
/*
0 - Low byte of 8 kB page count
SMD: 16 kB page count
1 - High byte of 8 kB page count
SMD: File ID code 0 (3, not: high byte of 16 kB page count)
Magic Griffin: Emulation mode select, first byte?
2 - Emulation mode select (SWC/SMC/Magic Griffin, second byte?)
Bit 7 6 5 4 3 2 1 0
x : 1 = Run in mode 0 (JMP $8000) (higher precedence than bit 1)
x : 0 = Last file of the ROM dump (multi-file)
: 1 = Multi-file (there is another file to follow)
x : SWC & SMC:
0 = SRAM mapping mode 1 (LoROM)
1 = mode 2 (HiROM)
x : SWC & SMC:
0 = DRAM mapping mode 20 (LoROM)
1 = mode 21 (HiROM)
x x : SWC & SMC (SRAM size):
00 = 256 kb, 01 = 64 kb, 10 = 16 kb, 11 = no SRAM
x : SWC & SMC:
0 = Run in mode 3
1 = Run in mode 2 (JMP RESET)
x : 0 = Disable, 1 = Enable external cartridge memory
image at bank 20-5F,A0-DF in system mode 2/3)
3-7 - 0, reserved
8 - File ID code 1 (0xaa)
9 - File ID code 2 (0xbb)
10 - File type; check this byte only if ID 1 & 2 match
1 : Super Magic Card saver data
2 : Magic Griffin program (PC-Engine)
3 : Magic Griffin SRAM data
4 : SNES program
5 : SWC & SMC password, SRAM data
6 : Mega Drive program
7 : SMD SRAM data
8 : SWC & SMC saver data
11-511 - 0, reserved
*/
#ifdef USE_PARALLEL
extern void ffe_init_io (unsigned int port);
extern void ffe_deinit_io (void);
extern void ffe_send_block (unsigned short address, unsigned char *buffer, int len);
extern void ffe_send_block2 (unsigned short address, unsigned char *buffer, int len);
extern void ffe_send_command0 (unsigned short address, unsigned char byte);
extern unsigned char ffe_send_command1 (unsigned short address);
extern void ffe_send_command (unsigned char command_code, unsigned short a, unsigned short l);
extern void ffe_receive_block (unsigned short address, unsigned char *buffer, int len);
extern void ffe_receive_block2 (unsigned short address, unsigned char *buffer, int len);
extern unsigned char ffe_receiveb (void);
extern void ffe_wait_for_ready (void);
extern void ffe_checkabort (int status);
#endif // USE_PARALLEL
#endif // FFE_H

View File

@ -0,0 +1,739 @@
/*
fig.c - Super PRO Fighter support for uCON64
Copyright (c) 1999 - 2002 NoisyB <noisyb@gmx.net>
Copyright (c) 2001 - 2004 dbjh
Copyright (c) 2003 - 2004 JohnDie
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 <time.h>
#include <string.h>
#include "misc/misc.h"
#include "misc/itypes.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "misc/parallel.h"
#include "misc/file.h"
#include "ucon64.h"
#include "ucon64_misc.h"
#include "ffe.h"
#include "fig.h"
#include "console/snes.h" // for snes_get_snes_hirom()
const st_getopt2_t fig_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "Super Pro Fighter (Q/Q+)/Pro Fighter X (Turbo 2)/Double Pro Fighter (X Turbo)"
/*"1993/1994/19XX China Coach Limited/CCL http://www.ccltw.com.tw"*/,
NULL
},
#ifdef USE_PARALLEL
{
"xfig", 0, 0, UCON64_XFIG,
NULL, "send/receive ROM to/from *Pro Fighter*/FIG; " OPTION_LONG_S "port=PORT\n"
"receives automatically when ROM does not exist",
&ucon64_wf[WF_OBJ_SNES_DEFAULT_STOP_NO_SPLIT_NO_ROM]
},
{
"xfigs", 0, 0, UCON64_XFIGS,
NULL, "send/receive SRAM to/from *Pro Fighter*/FIG; " OPTION_LONG_S "port=PORT\n"
"receives automatically when SRAM does not exist",
&ucon64_wf[WF_OBJ_SNES_STOP_NO_ROM]
},
{
"xfigc", 0, 0, UCON64_XFIGC, NULL,
"send/receive SRAM to/from cartridge in *Pro Fighter*/FIG;\n" OPTION_LONG_S "port=PORT\n"
"receives automatically when SRAM does not exist",
// "Press q to abort; ^C might cause invalid state of backup unit"
&ucon64_wf[WF_OBJ_SNES_STOP_NO_ROM]
},
#endif
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
#ifdef USE_PARALLEL
#define BUFFERSIZE 8192 // don't change, only 8192 works!
static int receive_rom_info (unsigned char *buffer);
static int get_rom_size (unsigned char *info_block);
static int check1 (unsigned char *info_block, int index);
static int check2 (unsigned char *info_block, int index, unsigned char value);
static int check3 (unsigned char *info_block, int index1, int index2, int size);
static void handle_swc_header (unsigned char *header);
static int hirom;
#if BUFFERSIZE < 512
#error receive_rom_info() and fig_read_sram() expect BUFFERSIZE to be at least \
512 bytes.
#endif
int
receive_rom_info (unsigned char *buffer)
/*
- returns size of ROM in Mb (128 kB) units
- sets global `hirom'
*/
{
int n, size;
volatile int m;
unsigned char byte;
ffe_send_command0 (0xe00c, 0);
if (UCON64_ISSET (ucon64.snes_hirom))
hirom = ucon64.snes_hirom ? 1 : 0;
else
{
ffe_send_command (5, 3, 0);
byte = ffe_send_command1 (0xbfd5);
if ((byte & 1 && byte != 0x23) || byte == 0x3a) // & 1 => 0x21, 0x31, 0x35
hirom = 1;
}
for (n = 0; n < (int) FIG_HEADER_LEN; n++)
{
for (m = 0; m < 65536; m++) // a delay is necessary here
;
ffe_send_command (5, (unsigned short) (0x200 + n), 0);
buffer[n] = ffe_send_command1 (0xa0a0);
}
size = get_rom_size (buffer);
if (hirom)
size <<= 1;
return size;
}
int
get_rom_size (unsigned char *info_block)
// returns size of ROM in Mb units
{
if (check1 (info_block, 0))
return 0;
if (check2 (info_block, 0x10, 0x84))
return 0;
if (check3 (info_block, 0, 0x20, 0x20))
return 2;
if (check3 (info_block, 0, 0x40, 0x20))
return 4;
if (check3 (info_block, 0x40, 0x60, 0x20))
return 6;
if (check3 (info_block, 0, 0x80, 0x10))
return 8;
if (check1 (info_block, 0x80))
return 8;
if (check3 (info_block, 0x80, 0x90, 0x10))
return 8;
if (check2 (info_block, 0x80, 0xa0))
return 8;
if (check3 (info_block, 0x80, 0xa0, 0x20))
return 0xa;
if (check1 (info_block, 0xc0))
return 0xc;
if (check2 (info_block, 0xc0, 0xb0))
return 0xc;
if (check3 (info_block, 0x80, 0xc0, 0x20))
return 0xc;
if (check3 (info_block, 0x100, 0, 0x10))
return 0x10;
if (check2 (info_block, 0x100, 0xc0))
return 0x10;
if (check3 (info_block, 0x100, 0x120, 0x10))
return 0x12;
if (check3 (info_block, 0x100, 0x140, 0x10))
return 0x14;
if (check2 (info_block, 0x140, 0xd0))
return 0x14;
if (check3 (info_block, 0x100, 0x180, 0x10))
return 0x18;
if (check2 (info_block, 0x180, 0xe0))
return 0x18;
if (check3 (info_block, 0x180, 0x1c0, 0x10))
return 0x1c;
if (check3 (info_block, 0x1f0, 0x1f0, 0x10))
return 0x20;
return 0;
}
int
check1 (unsigned char *info_block, int index)
{
int n;
for (n = 0; n < 16; n++)
if (info_block[n + index] != info_block[index])
return 0;
return 1;
}
int
check2 (unsigned char *info_block, int index, unsigned char value)
{
int n;
for (n = 0; n < 4; n++)
if (info_block[n + index] != value)
return 0;
return 1;
}
int
check3 (unsigned char *info_block, int index1, int index2, int size)
{
int n;
for (n = 0; n < size; n++)
if (info_block[n + index1] != info_block[n + index2])
return 0;
return 1;
}
void
handle_swc_header (unsigned char *header)
{
if ((header[2] & 0x10) == 0x10)
{ // HiROM
header[3] |= 0x80;
if ((header[2] & 0x0c) == 0x0c) // 0 Kbit SRAM
{
header[4] = 0x77;
header[5] = 0x83;
}
else if (((header[2] & 0x0c) == 0x08) || // 16 *or* 64 Kbit SRAM
((header[2] & 0x0c) == 0x04))
{
header[4] = 0xdd;
header[5] = 0x82;
}
else // 256 Kbit SRAM
{
header[4] = 0xdd;
header[5] = 0x02;
}
}
else
{ // LoROM
header[3] &= 0x7f;
if ((header[2] & 0x0c) == 0x0c) // 0 Kbit SRAM
{
header[4] = 0x77;
header[5] = 0x83;
}
else if (((header[2] & 0x0c) == 0x08) || // 16 *or* 64 Kbit SRAM
((header[2] & 0x0c) == 0x04))
{
header[4] = 0x00;
header[5] = 0x80;
}
else // 256 Kbit SRAM
{
header[4] = 0x00;
header[5] = 0x00;
}
}
}
int
fig_read_rom (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char *buffer;
int n, size, blocksleft, bytesreceived = 0;
unsigned short address1, address2;
time_t starttime;
st_rominfo_t rominfo;
ffe_init_io (parport);
if ((file = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
{
fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
exit (1);
}
size = receive_rom_info (buffer);
if (size == 0)
{
fprintf (stderr, "ERROR: There is no cartridge present in the Pro Fighter\n");
fclose (file);
remove (filename);
exit (1);
}
blocksleft = size * 16; // 1 Mb (128 kB) unit == 16 8 kB units
printf ("Receive: %d Bytes (%.4f Mb)\n", size * MBIT, (float) size);
size *= MBIT; // size in bytes for ucon64_gauge() below
ffe_send_command (5, 0, 0);
ffe_send_command0 (0xe00c, 0);
ffe_send_command0 (0xe003, 0);
// byte = ffe_send_command1 (0xbfd8);
memset (buffer, 0, FIG_HEADER_LEN);
fwrite (buffer, 1, FIG_HEADER_LEN, file); // write temporary empty header
if (hirom)
blocksleft >>= 1;
printf ("Press q to abort\n\n"); // print here, NOT before first FIG I/O,
// because if we get here q works ;-)
address1 = 0x300; // address1 = 0x100, address2 = 0 should
address2 = 0x200; // also work
starttime = time (NULL);
while (blocksleft > 0)
{
if (hirom)
for (n = 0; n < 4; n++)
{
ffe_send_command (5, address1, 0);
ffe_receive_block (0x2000, buffer, BUFFERSIZE);
address1++;
fwrite (buffer, 1, BUFFERSIZE, file);
bytesreceived += BUFFERSIZE;
ucon64_gauge (starttime, bytesreceived, size);
ffe_checkabort (2);
}
for (n = 0; n < 4; n++)
{
ffe_send_command (5, address2, 0);
ffe_receive_block (0xa000, buffer, BUFFERSIZE);
blocksleft--;
address2++;
fwrite (buffer, 1, BUFFERSIZE, file);
bytesreceived += BUFFERSIZE;
ucon64_gauge (starttime, bytesreceived, size);
ffe_checkabort (2);
}
}
ffe_send_command (5, 0, 0);
// Create a correct header. We can't obtain the header from the Pro Fighter
// unless a (the same) cartridge was just dumped to diskette...
ucon64.rom = filename;
ucon64.file_size = size + FIG_HEADER_LEN;
// override everything we know for sure
ucon64.console = UCON64_SNES;
ucon64.buheader_len = FIG_HEADER_LEN;
ucon64.split = 0;
ucon64.snes_hirom = hirom ? SNES_HIROM : 0;
ucon64.interleaved = 0;
memset (&rominfo, 0, sizeof (st_rominfo_t));
fflush (file);
snes_init (&rominfo);
memset (buffer, 0, FIG_HEADER_LEN);
snes_set_fig_header (&rominfo, (st_fig_header_t *) buffer);
fseek (file, 0, SEEK_SET);
fwrite (buffer, 1, FIG_HEADER_LEN, file); // write correct header
free (buffer);
fclose (file);
ffe_deinit_io ();
return 0;
}
int
fig_write_rom (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char *buffer;
int bytesread = 0, bytessend, totalblocks, blocksdone = 0, blocksleft, fsize,
n, emu_mode_select;
unsigned short address1, address2;
time_t starttime;
ffe_init_io (parport);
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
{
fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
exit (1);
}
fsize = fsizeof (filename);
printf ("Send: %d Bytes (%.4f Mb)\n", fsize, (float) fsize / MBIT);
ffe_send_command0 (0xc008, 0);
fread (buffer, 1, FIG_HEADER_LEN, file);
if (snes_get_file_type () == SWC)
handle_swc_header (buffer);
emu_mode_select = buffer[2]; // this byte is needed later
ffe_send_command (5, 0, 0);
ffe_send_block (0x400, buffer, FIG_HEADER_LEN); // send header
bytessend = FIG_HEADER_LEN;
hirom = snes_get_snes_hirom ();
if (hirom)
ffe_send_command0 (0xe00f, 0); // seems to enable HiROM mode,
// value doesn't seem to matter
printf ("Press q to abort\n\n"); // print here, NOT before first FIG I/O,
// because if we get here q works ;-)
totalblocks = (fsize - FIG_HEADER_LEN + BUFFERSIZE - 1) / BUFFERSIZE; // round up
blocksleft = totalblocks;
address1 = 0x300;
address2 = 0x200;
starttime = time (NULL);
while (blocksleft > 0)
{
if (hirom)
for (n = 0; n < 4; n++)
{
bytesread = fread (buffer, 1, BUFFERSIZE, file);
ffe_send_command0 ((unsigned short) 0xc010, (unsigned char) (blocksdone >> 9));
ffe_send_command (5, address1, 0);
ffe_send_block (0x0000, buffer, bytesread);
address1++;
blocksleft--;
blocksdone++;
bytessend += bytesread;
ucon64_gauge (starttime, bytessend, fsize);
ffe_checkabort (2);
}
for (n = 0; n < 4; n++)
{
bytesread = fread (buffer, 1, BUFFERSIZE, file);
ffe_send_command0 ((unsigned short) 0xc010, (unsigned char) (blocksdone >> 9));
ffe_send_command (5, address2, 0);
ffe_send_block (0x8000, buffer, bytesread);
address2++;
blocksleft--;
blocksdone++;
bytessend += bytesread;
ucon64_gauge (starttime, bytessend, fsize);
ffe_checkabort (2);
}
}
if (blocksdone > 0x200) // ROM dump > 512 8 kB blocks (=32 Mb (=4 MB))
ffe_send_command0 (0xc010, 2);
ffe_send_command (5, 0, 0);
ffe_send_command (6, (unsigned short) (1 | (emu_mode_select << 8)), 0);
ffe_wait_for_ready ();
outportb ((unsigned short) (parport + PARPORT_DATA), 0);
outportb ((unsigned short) (parport + PARPORT_CONTROL),
(unsigned char) (inportb ((unsigned short) // invert strobe
(parport + PARPORT_CONTROL)) ^ PARPORT_STROBE));
free (buffer);
fclose (file);
ffe_deinit_io ();
return 0;
}
int
fig_read_sram (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char *buffer;
int blocksleft, bytesreceived = 0;
unsigned short address;
time_t starttime;
ffe_init_io (parport);
if ((file = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
{
fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
exit (1);
}
printf ("Receive: %d Bytes\n", 32 * 1024);
memset (buffer, 0, FIG_HEADER_LEN);
#if 0 // Not needed for FIG, as size is always 4 blocks
buffer[0] = 4; // 32 kB == 4*8 kB, "size_high" is already 0
#endif
fwrite (buffer, 1, FIG_HEADER_LEN, file);
ffe_send_command (5, 0, 0);
ffe_send_command0 (0xe00d, 0);
ffe_send_command0 (0xc008, 0);
printf ("Press q to abort\n\n"); // print here, NOT before first FIG I/O,
// because if we get here q works ;-)
blocksleft = 4; // SRAM is 4*8 kB
address = 0x100;
starttime = time (NULL);
while (blocksleft > 0)
{
ffe_send_command (5, address, 0);
ffe_receive_block (0x2000, buffer, BUFFERSIZE);
blocksleft--;
address++;
fwrite (buffer, 1, BUFFERSIZE, file);
bytesreceived += BUFFERSIZE;
ucon64_gauge (starttime, bytesreceived, 32 * 1024);
ffe_checkabort (2);
}
free (buffer);
fclose (file);
ffe_deinit_io ();
return 0;
}
int
fig_write_sram (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char *buffer;
int bytesread, bytessend = 0, size;
unsigned short address;
time_t starttime;
ffe_init_io (parport);
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
{
fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
exit (1);
}
size = fsizeof (filename) - FIG_HEADER_LEN; // FIG SRAM is 4*8 kB, emu SRAM often not
printf ("Send: %d Bytes\n", size);
fseek (file, FIG_HEADER_LEN, SEEK_SET); // skip the header
ffe_send_command (5, 0, 0);
ffe_send_command0 (0xe00d, 0);
ffe_send_command0 (0xc008, 0);
printf ("Press q to abort\n\n"); // print here, NOT before first FIG I/O,
// because if we get here q works ;-)
address = 0x100;
starttime = time (NULL);
while ((bytesread = fread (buffer, 1, BUFFERSIZE, file)))
{
ffe_send_command (5, address, 0);
ffe_send_block (0x2000, buffer, bytesread);
address++;
bytessend += bytesread;
ucon64_gauge (starttime, bytessend, size);
ffe_checkabort (2);
}
free (buffer);
fclose (file);
ffe_deinit_io ();
return 0;
}
int
fig_read_cart_sram (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char *buffer, byte;
int bytesreceived = 0, size;
unsigned short address;
time_t starttime;
ffe_init_io (parport);
if ((file = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
{
fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
exit (1);
}
size = receive_rom_info (buffer);
if (size == 0)
{
fprintf (stderr, "ERROR: There is no cartridge present in the Pro Fighter\n");
fclose (file);
remove (filename);
exit (1);
}
ffe_send_command (5, 3, 0); // detect cartridge SRAM size because
ffe_send_command0 (0xe00c, 0); // we don't want to read too few data
byte = ffe_send_command1 (0xbfd8);
size = MAX ((byte ? 1 << (byte + 10) : 0), 32 * 1024);
printf ("Receive: %d Bytes\n", size);
memset (buffer, 0, FIG_HEADER_LEN);
#if 0 // Not needed for FIG, as size is always 4 blocks
buffer[0] = 4; // 32 kB == 4*8 kB, "size_high" is already 0
#endif
fwrite (buffer, 1, FIG_HEADER_LEN, file);
ffe_send_command (5, 0, 0);
ffe_send_command0 (0xe00c, 0);
// ffe_send_command0 (0xc008, 0);
printf ("Press q to abort\n\n"); // print here, NOT before first FIG I/O,
// because if we get here q works ;-)
address = hirom ? 0x2c3 : 0x1c0;
starttime = time (NULL);
while (bytesreceived < size)
{
ffe_send_command (5, address, 0);
ffe_receive_block ((unsigned short) (hirom ? 0x6000 : 0x2000), buffer, BUFFERSIZE);
fwrite (buffer, 1, BUFFERSIZE, file);
address += hirom ? 4 : 1;
bytesreceived += BUFFERSIZE;
ucon64_gauge (starttime, bytesreceived, size);
ffe_checkabort (2);
}
free (buffer);
fclose (file);
ffe_deinit_io ();
return 0;
}
int
fig_write_cart_sram (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char *buffer, byte;
int bytesread, bytessend = 0, size;
unsigned short address;
time_t starttime;
ffe_init_io (parport);
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
{
fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
exit (1);
}
size = receive_rom_info (buffer);
if (size == 0)
{
fprintf (stderr, "ERROR: There is no cartridge present in the Pro Fighter\n");
fclose (file);
remove (filename);
exit (1);
}
ffe_send_command (5, 3, 0); // detect cartridge SRAM size because we don't
ffe_send_command0 (0xe00c, 0); // want to write more data than necessary
byte = ffe_send_command1 (0xbfd8);
size = fsizeof (filename) - FIG_HEADER_LEN; // FIG SRAM is 4*8 kB, emu SRAM often not
size = MIN ((byte ? 1 << (byte + 10) : 0), size);
printf ("Send: %d Bytes\n", size);
fseek (file, FIG_HEADER_LEN, SEEK_SET); // skip the header
ffe_send_command (5, 0, 0);
ffe_send_command0 (0xe00c, 0);
// ffe_send_command0 (0xc008, 0);
printf ("Press q to abort\n\n"); // print here, NOT before first FIG I/O,
// because if we get here q works ;-)
address = hirom ? 0x2c3 : 0x1c0;
starttime = time (NULL);
while ((bytessend < size) && (bytesread = fread (buffer, 1, MIN (size, BUFFERSIZE), file)))
{
ffe_send_command (5, address, 0);
ffe_send_block ((unsigned short) (hirom ? 0x6000 : 0x2000), buffer, bytesread);
address += hirom ? 4 : 1;
bytessend += bytesread;
ucon64_gauge (starttime, bytessend, size);
ffe_checkabort (2);
}
free (buffer);
fclose (file);
ffe_deinit_io ();
return 0;
}
#endif // USE_PARALLEL

View File

@ -0,0 +1,100 @@
/*
fig.h - Super PRO Fighter support for uCON64
Copyright (c) 1999 - 2002 NoisyB <noisyb@gmx.net>
Copyright (c) 2001 - 2003 dbjh
Copyright (c) 2003 JohnDie
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.
*/
#ifndef FIG_H
#define FIG_H
extern const st_getopt2_t fig_usage[];
#ifdef USE_PARALLEL
#endif // USE_PARALLEL
/*
Super Pro Fighter (FIG) Header Format
Last edited: 19.06.2002
Offset | Content
-------------+------------------------------------
$0000 | Lo-Byte of 8K-Block#
-------------+------------------------------------
$0001 | Hi-Byte of 8K-Block#
-------------+------------------------------------
$0002 | $00 = Last File
| $40 = More Files Present
-------------+------------------------------------
$0003 | $00 = LoROM
| $80 = HiROM
-------------+------------------------------------
$0004-$0005 | $77 $83 = No SRAM (LoROM)
| $00 $80 = 16 KBit (LoROM)
| $00 $80 = 64 KBit (LoROM)
| $00 $00 = 256 KBit (LoROM)
| $47 $83 = No SRAM (LoROM) (DSP)
| $11 $02 = 256 KBit (LoROM) (SFX)
| $77 $83 = No SRAM (HiROM)
| $DD $82 = 16 KBit (HiROM)
| $DD $82 = 64 KBit (HiROM)
| $DD $02 = 256 KBit (HiROM)
| $F7 $83 = No SRAM (HiROM) (DSP)
| $FD $82 = 16 KBit (HiROM) (DSP)
-------------+------------------------------------
$0006-$01FF | Reserved (=$00)
NOTE 1: The Super Pro Fighter does not distinguish between 16 KBit SRAM
and 64 KBit SRAM.
NOTE 2: When splitting files, the SPF writes all relevant header fields
to all files. So each file has the same header with exception of
the last one, because it has $0002 set to $00 to indicate that it
is the last file.
*/
typedef struct st_fig_header
{
/*
Don't create fields that are larger than one byte! For example size_low and size_high
could be combined in one unsigned short int. However, this gives problems with little
endian vs. big endian machines (e.g. writing the header to disk).
*/
unsigned char size_low;
unsigned char size_high;
unsigned char multi;
unsigned char hirom;
unsigned char emulation1;
unsigned char emulation2;
unsigned char pad[506];
} st_fig_header_t;
#define FIG_HEADER_START 0
#define FIG_HEADER_LEN (sizeof (st_fig_header_t))
#ifdef USE_PARALLEL
extern int fig_read_rom (const char *filename, unsigned int parport);
extern int fig_write_rom (const char *filename, unsigned int parport);
extern int fig_read_sram (const char *filename, unsigned int parport);
extern int fig_write_sram (const char *filename, unsigned int parport);
extern int fig_read_cart_sram (const char *filename, unsigned int parport);
extern int fig_write_cart_sram (const char *filename, unsigned int parport);
#endif
#endif // FIG_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,34 @@
/*
gbx.h - Game Boy Xchanger support for uCON64
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
Copyright (c) 2001 - 2002 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.
*/
#ifndef GBX_H
#define GBX_H
extern const st_getopt2_t gbx_usage[];
#ifdef USE_PARALLEL
extern int gbx_read_rom (const char *filename, unsigned int parport);
extern int gbx_write_rom (const char *filename, unsigned int parport);
extern int gbx_read_sram (const char *filename, unsigned int parport, int bank);
extern int gbx_write_sram (const char *filename, unsigned int parport, int bank);
#endif
#endif // GBX_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,49 @@
/*
gd.h - Game Doctor support for uCON64
Copyright (c) 2002 John Weidman
Copyright (c) 2002 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.
*/
#ifndef GD_H
#define GD_H
extern const st_getopt2_t gd_usage[];
#define GD_HEADER_START 0
#define GD_HEADER_LEN 512
#define GD3_MAX_UNITS 16 // Maximum that the hardware supports
// Each logical memory unit is 8 Mbit in size (internally it's 2*4 Mbit)
#ifdef USE_PARALLEL
extern int gd3_read_rom (const char *filename, unsigned int parport);
extern int gd3_write_rom (const char *filename, unsigned int parport,
st_rominfo_t *rominfo);
extern int gd6_read_rom (const char *filename, unsigned int parport);
extern int gd6_write_rom (const char *filename, unsigned int parport,
st_rominfo_t *rominfo);
extern int gd3_read_sram (const char *filename, unsigned int parport);
extern int gd3_write_sram (const char *filename, unsigned int parport);
extern int gd6_read_sram (const char *filename, unsigned int parport);
extern int gd6_write_sram (const char *filename, unsigned int parport);
extern int gd3_read_saver (const char *filename, unsigned int parport);
extern int gd3_write_saver (const char *filename, unsigned int parport);
extern int gd6_read_saver (const char *filename, unsigned int parport);
extern int gd6_write_saver (const char *filename, unsigned int parport);
#endif // USE_PARALLEL
#endif // GD_H

View File

@ -0,0 +1,46 @@
/*
interceptor.c - Mega Disk/Super Disk Interceptor support for uCON64
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
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 <time.h>
#include <string.h>
#include "misc/misc.h"
#include "misc/itypes.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "ucon64.h"
#include "interceptor.h"
const st_getopt2_t interceptor_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "Mega Disk/Super Disk (Interceptor),"/*"19XX Taiwan Sang Ting Co. Ltd."*/,
NULL
},
{NULL, 0, 0, 0, NULL, NULL, NULL}
};

View File

@ -0,0 +1,31 @@
/*
interceptor.h - Mega Disk/Super Disk Interceptor support for uCON64
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
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.
*/
#ifndef INTERCEPTOR_H
#define INTERCEPTOR_H
extern const st_getopt2_t interceptor_usage[];
typedef struct st_interceptor_header
{
char pad[512];
} st_interceptor_header_t;
#endif

View File

@ -0,0 +1,169 @@
CC=gcc
ifdef DEBUG
# I think we only use gnu99 instead of c99 due to va_args extensions.
CFLAGS=-I. -Wall -W -pg -g -pedantic -ansi -DDEBUG
else
CFLAGS=-I. -Wall -W -O6 -funroll-loops -fexpensive-optimizations
endif
ifndef DJGPP
# uname is not available by default under DOS
OSTYPE=$(shell uname -s)
else
OSTYPE=DJGPP
endif
GCC_WIN=0
ifeq ($(findstring MINGW,$(OSTYPE)),MINGW)
GCC_WIN=1
endif
ifeq ($(findstring CYGWIN,$(OSTYPE)),CYGWIN)
GCC_WIN=1
endif
ifdef DJGPP
LDFLAGS=
else
ifeq ($(findstring BeOS,$(OSTYPE)),BeOS)
LDFLAGS=-nostart
else # Unix or Win GCC
LDFLAGS=-shared
endif
endif
ifeq ($(findstring DJGPP,$(OSTYPE)),)
ifneq ($(GCC_WIN),1)
CFLAGS+=-fPIC
else
# Cygwin and MinGW need an import library for a DLL
LDFLAGS+=-Wl,--out-implib,libcd64dll.a
endif
endif
# The next check is not really specific to FreeBSD or OpenBSD -- the version of
# gcc I use is just old.
ifeq ($(findstring FreeBSD,$(OSTYPE)),)
ifeq ($(findstring OpenBSD,$(OSTYPE)),)
CFLAGS+=-std=gnu99
endif
endif
DEFAULT_BUILD=1
# If the user passed anything, we are not a default build.
ifdef LIBIEEE1284
DEFAULT_BUILD=0
else
ifdef PPDEV
DEFAULT_BUILD=0
else
ifdef PORTDEV
DEFAULT_BUILD=0
else
ifdef RAWIO
DEFAULT_BUILD=0
endif
endif
endif
endif
ifeq ($(DEFAULT_BUILD),1)
# Put default build options for each OS here
ifeq ($(findstring DJGPP,$(OSTYPE)),DJGPP)
RAWIO=1
endif
ifeq ($(findstring MINGW,$(OSTYPE)),MINGW)
RAWIO=1
endif
ifeq ($(findstring CYGWIN,$(OSTYPE)),CYGWIN)
RAWIO=1
endif
ifeq ($(findstring BeOS,$(OSTYPE)),BeOS)
RAWIO=1
endif
ifeq ($(findstring OpenBSD,$(OSTYPE)),OpenBSD)
# i386_iopl() is located in libi386.a (note the .a)
LIBS+=-L/usr/lib -li386
RAWIO=1
endif
ifeq ($(findstring FreeBSD,$(OSTYPE)),FreeBSD)
RAWIO=1
endif
ifeq ($(findstring Linux,$(OSTYPE)),Linux)
ifeq ($(shell if test -r /usr/include/ieee1284.h; then echo 1; else echo 0; fi),1)
LIBIEEE1284=1
endif
ifeq ($(shell if test -r /usr/include/linux/ppdev.h; then echo 1; else echo 0; fi),1)
PPDEV=1
endif
PORTDEV=1
RAWIO=1
endif
endif # DEFAULT_BUILD = 1
# Now for backend-specific defs
ifdef LIBIEEE1284
CFLAGS+=-DCD64_USE_LIBIEEE1284
LIBS+=-lieee1284
endif
ifdef PPDEV
CFLAGS+=-DCD64_USE_PPDEV
endif
ifdef PORTDEV
CFLAGS+=-DCD64_USE_PORTDEV
endif
ifdef RAWIO
CFLAGS+=-DCD64_USE_RAWIO
endif
default: all
ifeq ($(findstring DJGPP,$(OSTYPE)),DJGPP)
all: libcd64.a
else
ifeq ($(GCC_WIN),1)
all: libcd64.a cd64.dll
else
all: libcd64.a libcd64.so
endif # GCC_WIN
endif # DJGPP
# libcd64 stuff
cd64io.o: cd64io.c
$(CC) $(CFLAGS) $^ -c -o $@
cd64lib.o: cd64lib.c
$(CC) $(CFLAGS) $^ -c -o $@
libcd64.a: cd64lib.o cd64io.o
ld -r $^ $(LIBS) -o $*.o
# rm -f $@
ar crs $@ $*.o
LDFLAGS+=$(LIBS)
ifeq ($(GCC_WIN),1)
cd64.dll: cd64lib.o cd64io.o
else
libcd64.so: cd64lib.o cd64io.o
endif
# rm -f $@
$(CC) $^ $(LDFLAGS) -o $@
clean:
rm -f *.o *.so *.dll *.a a.out

View File

@ -0,0 +1,62 @@
CC=cl.exe
!ifdef DEBUG
CFLAGS=/nologo /I. /Zi /Oi /GZ /W3 /DDEBUG
!else
CFLAGS=/nologo /I. /W3 /O2
!endif
DEFAULT_BUILD=1
# If the user passed anything, we are not a default build.
!ifdef LIBIEEE1284
DEFAULT_BUILD=0
!else
!ifdef RAWIO
DEFAULT_BUILD=0
!endif
!endif
!if $(DEFAULT_BUILD)==1
# Put default build options here
RAWIO=1
!endif # DEFAULT_BUILD = 1
# Now for backend-specific defs
!ifdef LIBIEEE1284
CFLAGS=$(CFLAGS) /DCD64_USE_LIBIEEE1284
LIBS=$(LIBS) ieee1284.lib
!endif
!ifdef RAWIO
CFLAGS=$(CFLAGS) /DCD64_USE_RAWIO
!endif
default: all
all: cd64.lib cd64.dll
# libcd64 stuff
cd64io.obj: cd64io.c
$(CC) $(CFLAGS) $** /c /Fo$@
cd64lib.obj: cd64lib.c
$(CC) $(CFLAGS) $** /c /Fo$@
cd64.lib: cd64lib.obj cd64io.obj
lib.exe /NOLOGO $** $(LIBS) /OUT:$@
cd64.dll: cd64lib.obj cd64io.obj
link.exe /NOLOGO /DLL $** $(LIBS) /DEF:cd64.def /IMPLIB:cd64dll.lib /OUT:$@
clean:
del *.obj
del *.exp
del *.lib
del *.dll
del *.pdb

View File

@ -0,0 +1,28 @@
EXPORTS
cd64_create
cd64_send_byte
cd64_send_dword
cd64_grab_byte
cd64_grab_dword
cd64_trade_bytes
cd64_bios_grab
cd64_bios_send
cd64_ghemor_grab
cd64_ghemor_send
cd64_upload_dram
cd64_upload_ram
cd64_upload_bootemu
cd64_upload_sram
cd64_upload_flashram
cd64_upload_eeprom
cd64_upload_mempak
cd64_download_cart
cd64_download_dram
;cd64_download_ram
cd64_download_sram
cd64_download_flashram
cd64_download_eeprom
cd64_download_mempak
cd64_run_dram
cd64_run_cart
cd64_download_header

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,114 @@
#ifndef __CD64IO_H__
#define __CD64IO_H__
#ifdef CD64_USE_LIBIEEE1284
#include <ieee1284.h>
int cd64_open_ieee1284(struct cd64_t *cd64);
int cd64_close_ieee1284(struct cd64_t *cd64);
int cd64_xfer_ieee1284(struct cd64_t *cd64, uint8_t *wr, uint8_t *rd, int delayms);
#endif
#ifdef CD64_USE_PPDEV
#ifndef __linux__
#error ppdev can only be used on Linux
#endif
#include <sys/ioctl.h>
#include <linux/parport.h>
#include <linux/ppdev.h>
int cd64_open_ppdev(struct cd64_t *cd64);
int cd64_close_ppdev(struct cd64_t *cd64);
int cd64_xfer_ppdev(struct cd64_t *cd64, uint8_t *wr, uint8_t *rd, int delayms);
#endif
#ifdef CD64_USE_PORTDEV
#ifndef __linux__
#error portdev can only be used on Linux
#endif
int cd64_open_portdev(struct cd64_t *cd64);
int cd64_close_portdev(struct cd64_t *cd64);
int cd64_xfer_portdev(struct cd64_t *cd64, uint8_t *wr, uint8_t *rd, int delayms);
#endif
#ifdef CD64_USE_RAWIO
/* #define REALLY_SLOW_IO */
#if defined __linux__ && (defined __i386__ || defined __x86_64__)
#include <sys/io.h>
#endif
#ifdef __OpenBSD__
#include <sys/types.h>
#include <machine/sysarch.h>
#include <i386/pio.h>
/* pio.h defines several I/O functions & macros, including the macros inb() and
* outb(). This shows that using a bit of inline assembly is not such a bad idea
* at all. */
#undef inb
#define inb(port) __inb(port)
#undef outb
#define outb(data, port) __outb(port, data)
#endif
#ifdef __FreeBSD__
#include <fcntl.h>
#include <machine/cpufunc.h>
/* Almost the same story as under OpenBSD. cpufunc.h defines the macros inb()
* and outb(). We redefine them. Be sure _POSIX_SOURCE is not defined before
* including <machine/cpufunc.h>. */
#undef inb
#define inb(port) inbv(port)
#undef outb
#define outb(data, port) outbv(port, data)
#endif
#ifdef __BEOS__
#include <fcntl.h>
#endif
#ifdef _MSC_VER
#include <conio.h> /* inp() & outp() */
#include <io.h> /* access() */
#define F_OK 0
#endif
#ifdef __MSDOS__
#include <pc.h> /* inportb() & outportb() */
#endif
#if defined _WIN32 || defined __CYGWIN__
#include <windows.h> /* defines _WIN32 (checks for */
#include <string.h> /* __CYGWIN__ must come first) */
#ifdef __CYGWIN__
#include <exceptions.h>
#include <dlfcn.h>
#include <sys/cygwin.h>
#endif
#endif /* _WIN32 || __CYGWIN__ */
int cd64_open_rawio(struct cd64_t *cd64);
int cd64_close_rawio(struct cd64_t *cd64);
int cd64_xfer_rawio(struct cd64_t *cd64, uint8_t *wr, uint8_t *rd, int delayms);
#endif
#if defined _WIN32 && !defined __CYGWIN__
/* milliseconds */
#include <windows.h>
#define USLEEP(x) Sleep(x)
#elif defined __MSDOS__
/* milliseconds */
#include <dos.h>
#define USLEEP(x) delay(x)
#elif defined __BEOS__
/* microseconds */
#include <OS.h>
#define USLEEP(x) snooze(x)
#else /* Unix & Cygwin */
/* microseconds */
#include <unistd.h>
#define USLEEP(x) usleep(x)
#endif
#if __STDC_VERSION__ >= 19990L && !defined DEBUG
/* If DEBUG is defined the keyword inline is not recognised (syntax error). */
#define INLINE inline
#elif defined _MSC_VER
/* Visual C++ doesn't allow inline in C source code */
#define INLINE __inline
#else
#define INLINE
#endif
#endif

View File

@ -0,0 +1,990 @@
/*
*
* cd64lib.c
*
* Library routines for CD64 handling
*
* (c) 2004 Ryan Underwood
* Portions (c) 2004 Daniel Horchner (Win32, read/write/seek callbacks)
*
* May be distributed under the terms of the GNU Lesser/Library General
* Public License, or any later version of the same, as published by the Free
* Software Foundation.
*/
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <stdarg.h>
#include <sys/types.h>
#include <sys/stat.h>
#if defined __unix__ || defined __BEOS__
#include <unistd.h>
#endif
#if (defined _WIN32 && !defined __CYGWIN__) || defined __MSDOS__
#include <sys/timeb.h>
#else
#include <sys/time.h>
#endif
#include <ultra64/host/cd64lib.h>
#include <ultra64/rom.h>
#include <ultra64/cartmem.h>
#include "cd64io.h"
static uint8_t *cd64_tmp_buf;
static uint32_t cd64_tmp_buf_offset;
static int cd64_notice_helper(FILE *file, const char *format, va_list argptr) {
int n_chars;
fputs("libcd64: ", file);
n_chars = vfprintf(file, format, argptr);
fputc('\n', file);
fflush(file);
return n_chars;
}
int cd64_notice(const char *format, ...) {
va_list argptr;
int n_chars;
va_start(argptr, format);
n_chars = cd64_notice_helper(stdout, format, argptr);
va_end(argptr);
return n_chars;
}
int cd64_notice2(const char *format, ...) {
va_list argptr;
int n_chars;
va_start(argptr, format);
n_chars = cd64_notice_helper(stderr, format, argptr);
va_end(argptr);
return n_chars;
}
int cd64_read(void *io_id, void *buffer, uint32_t size) {
return fread(buffer, 1, size, (FILE *) io_id);
}
int cd64_write(void *io_id, void *buffer, uint32_t size) {
return fwrite(buffer, 1, size, (FILE *) io_id);
}
int32_t cd64_tell(void *io_id) {
return (int32_t) ftell((FILE *) io_id);
}
int cd64_seek(void *io_id, int32_t offset, int whence) {
return fseek((FILE *) io_id, offset, whence);
}
int cd64_create(struct cd64_t *cd64, method_t method,
uint16_t port, protocol_t protocol, int ppa) {
cd64->using_ppa = (ppa)? 1 : 0;
cd64->protocol = protocol;
cd64->port = port;
if (!cd64->notice_callback) cd64->notice_callback = cd64_notice;
if (!cd64->notice_callback2) cd64->notice_callback2 = cd64_notice2;
cd64->read_callback = cd64_read;
cd64->write_callback = cd64_write;
cd64->tell_callback = cd64_tell;
cd64->seek_callback = cd64_seek;
#ifdef CD64_USE_LIBIEEE1284
if (method == LIBIEEE1284) {
cd64->devopen = cd64_open_ieee1284;
cd64->xfer = cd64_xfer_ieee1284;
cd64->devclose = cd64_close_ieee1284;
return 1;
}
else
#endif
#ifdef CD64_USE_PPDEV
if (method == PPDEV) {
cd64->devopen = cd64_open_ppdev;
cd64->xfer = cd64_xfer_ppdev;
cd64->devclose = cd64_close_ppdev;
return 1;
}
else
#endif
#ifdef CD64_USE_PORTDEV
if (method == PORTDEV) {
cd64->devopen = cd64_open_portdev;
cd64->xfer = cd64_xfer_portdev;
cd64->devclose = cd64_close_portdev;
return 1;
}
else
#endif
#ifdef CD64_USE_RAWIO
if (method == RAWIO) {
cd64->devopen = cd64_open_rawio;
cd64->xfer = cd64_xfer_rawio;
cd64->devclose = cd64_close_rawio;
return 1;
}
else
#endif
{
switch (method) {
case LIBIEEE1284:
cd64->notice_callback2("libieee1284 not supported.");
break;
case PPDEV:
cd64->notice_callback2("ppdev not supported.");
break;
case PORTDEV:
cd64->notice_callback2("portdev not supported.");
break;
case RAWIO:
cd64->notice_callback2("rawio not supported.");
break;
default:
cd64->notice_callback2("unknown hw access method.");
break;
}
return 0;
}
}
/* CD64 BIOS routines */
static int cd64_bios_sync(struct cd64_t *cd64) {
unsigned char ret1 = 0, ret2 = 0;
cd64->notice_callback("Waiting for CD64 comms to come online...");
while (!(ret1 == 'R' && ret2 == 'W')) {
if (cd64->abort) return 0;
/* approximation here */
cd64_send_byte(cd64, 'W');
cd64_send_byte(cd64, 'B');
cd64_trade_bytes(cd64, 'B', &ret1);
cd64_trade_bytes(cd64, 'B', &ret2);
}
return 1;
}
int cd64_bios_grab(struct cd64_t *cd64, void *io_id, uint32_t addr,
uint32_t length, int *elapsed) {
unsigned int i;
unsigned short pc_csum = 0, n64_csum = 0;
#if (defined _WIN32 && !defined __CYGWIN__) || defined __MSDOS__
struct timeb tb;
#else
struct timeval tv;
#endif
unsigned long int sec = 0, usec = 0;
uint8_t send, recv;
uint8_t cmd = 0xff;
uint8_t tmp;
if (!length || length&0x00000003 || addr&0x00000003) return 0;
if (addr <= 0xa03fffff && addr+length <= 0xa03fffff) {
cmd = BIOS_DUMP_N64;
}
else if (addr >= 0xa8000000 && addr <= 0xbfffffff
&& addr+length <= 0xbfffffff) {
cmd = BIOS_DUMP_PI;
}
if (cmd == 0xff) {
cd64->notice_callback2("Invalid memory range %lxh-%lxh for operation.",
(long unsigned int) addr, (long unsigned int) addr+length);
return 0;
}
/* Try to get in sync with the CD64
* We use a delay here to give the PPA a chance to power up. */
send = 0xff;
cd64->xfer(cd64, &send, NULL, 1000);
cd64_bios_sync(cd64);
if (elapsed != NULL) {
#if (defined _WIN32 && !defined __CYGWIN__) || defined __MSDOS__
ftime(&tb);
sec = tb.time;
usec = tb.millitm*1000;
#else
gettimeofday(&tv, 0);
sec = tv.tv_sec;
usec = tv.tv_usec;
#endif
}
cd64_send_byte(cd64, cmd);
cd64_send_dword(cd64, addr);
cd64_send_dword(cd64, length);
/* dummy exchange, needed for some reason */
cd64_grab_byte(cd64, &recv);
for (i = 1; i <= length; i++) {
if (cd64->abort) return 0;
if (!cd64_grab_byte(cd64, &tmp)) return 0;
if (!cd64->write_callback(io_id, &tmp, 1)) {
cd64->notice_callback2("Error writing to output.");
return 0;
}
pc_csum += tmp;
if ((i % CD64_BUFFER_SIZE == 0) && cd64->progress_callback) {
cd64->progress_callback(i, length);
}
}
if (cd64->progress_callback) {
cd64->progress_callback(i, length);
}
if (elapsed != NULL) {
#if (defined _WIN32 && !defined __CYGWIN__) || defined __MSDOS__
ftime(&tb);
*elapsed = ((tb.time - sec)*1000000) + ((tb.millitm*1000) - usec);
#else
gettimeofday(&tv, 0);
*elapsed = ((tv.tv_sec - sec)*1000000) + (tv.tv_usec - usec);
#endif
}
pc_csum &= 0xfff;
cd64_trade_bytes(cd64, 0, &recv);
n64_csum = recv << 8;
cd64_trade_bytes(cd64, 0, &recv);
n64_csum += recv;
n64_csum &= 0xfff;
/* debug("\nVerifying checksum: pcsum = %d, n64sum = %d\n", pc_csum, n64_csum); */
if (pc_csum^n64_csum) return -1;
else return 1;
}
int cd64_bios_send(struct cd64_t *cd64, void *io_id, uint32_t addr,
uint32_t length, int *elapsed, int cmd) {
unsigned int i;
uint16_t pc_csum = 0;
#if (defined _WIN32 && !defined __CYGWIN__) || defined __MSDOS__
struct timeb tb;
#else
struct timeval tv;
#endif
unsigned long int sec = 0, usec = 0;
uint8_t send;
uint8_t buf[4];
int valid = 1;
uint8_t send_bogus_csum = 0;
uint8_t tmp;
int32_t pos;
if (!io_id || !length || length&0x00000003 || addr&0x00000003) return 0;
if (cmd != BIOS_TRANSFER_PI && cmd != BIOS_EXECUTE_PI && cmd != BIOS_TRANSFER_N64
&& !(cd64->protocol == GHEMOR && cmd == GHEMOR_TRANSFER_PROGRAM)) return 0;
if (cmd == BIOS_TRANSFER_PI || cmd == BIOS_EXECUTE_PI) {
if (addr < 0xa8000000 || addr > 0xbfffffff ||
addr+length > 0xbfffffff) valid = 0;
}
else if (cmd == BIOS_TRANSFER_N64) {
if (addr < 0xa0000000 || addr > 0xa03fffff
|| addr+length > 0xa03fffff) valid = 0;
if (addr != BIOS_TEMP_RAM || length > 0x80000) {
/* FIXME: is 0x80000 (512Kbit) really all the CD64
* BIOS will copy from a mempak? See if it copies
* 1Mbit from a 4x linear card. */
/* We are sending somewhere in RAM besides the CD64's
* scratch area. We will send a bogus checksum so the
* CD64 doesn't try to run it or copy it to a mempak.
*/
send_bogus_csum = 1;
}
}
if (!valid) {
cd64->notice_callback2("Invalid address %lxh for operation.",
(long unsigned int) addr);
return 0;
}
if (cd64->protocol == GHEMOR && addr != 0xb4000000 &&
(cmd == BIOS_TRANSFER_PI || cmd == BIOS_EXECUTE_PI)) {
/* They might try to send to Ghemor in BIOS mode, but
* oh well. Warn them if we know it's Ghemor. */
cd64->notice_callback("Ignoring address %lxh != 0xb4000000 for Ghemor.",
(long unsigned int) addr);
}
if (cmd == GHEMOR_TRANSFER_PROGRAM) {
cd64->notice_callback("Ghemor ignores this command currently...");
}
/* Try to get in sync with the CD64
* We use a delay here to give the PPA a chance to power up. */
send = 0xff;
cd64->xfer(cd64, &send, NULL, 1000);
cd64_bios_sync(cd64);
if (elapsed != NULL) {
#if (defined _WIN32 && !defined __CYGWIN__) || defined __MSDOS__
ftime(&tb);
sec = tb.time;
usec = tb.millitm*1000;
#else
gettimeofday(&tv, 0);
sec = tv.tv_sec;
usec = tv.tv_usec;
#endif
}
cd64_send_byte(cd64, (uint8_t) cmd);
cd64_send_dword(cd64, addr); /* Ghemor ignores this */
cd64_send_dword(cd64, length);
pos = cd64->tell_callback(io_id);
i = 0;
while (i < length) {
if (cd64->abort) return 0;
cd64->read_callback(io_id, &tmp, 1);
pc_csum += tmp;
pc_csum &= 0xfff;
if (!cd64_send_byte(cd64, tmp)) {
if (cd64->protocol == CD64BIOS) {
/* Probably the BIOS was stupid and dropped a
* send as it likes to. Try to recover from
* a convenient point. */
while (i % 4 != 0) i--;
cd64->seek_callback(io_id, pos+i, SEEK_SET);
cd64->read_callback(io_id, &tmp, 1);
cd64->notice_callback("Trying to recover dropped send, waiting for CD64...");
cd64_bios_sync(cd64);
cd64_send_byte(cd64, (uint8_t) cmd);
cd64_send_dword(cd64, addr+i);
cd64_send_dword(cd64, length-i);
if (!cd64_send_byte(cd64, tmp)) {
/* Oh well, at least we tried. */
return -1;
}
/* Unfortunately we can only calculate a checksum
* from _this_ point onward. */
pc_csum = tmp;
/* Now continue as if nothing ever happened. */
}
else {
cd64->notice_callback2("Send dropped, unable to recover.");
return 0;
}
}
if ((i % CD64_BUFFER_SIZE == 0) && cd64->progress_callback) {
cd64->progress_callback(i, length);
}
i++;
}
if (cd64->progress_callback) {
cd64->progress_callback(i, length);
}
if (elapsed != NULL) {
#if (defined _WIN32 && !defined __CYGWIN__) || defined __MSDOS__
ftime(&tb);
*elapsed = ((tb.time - sec)*1000000) + ((tb.millitm*1000) - usec);
#else
gettimeofday(&tv, 0);
*elapsed = ((tv.tv_sec - sec)*1000000) + (tv.tv_usec - usec);
#endif
}
/* debug("checksum: 0x%x\n",pc_csum) */
cd64_send_byte(cd64, (unsigned char)((pc_csum & 0xff00) >> 8));
/* debug("Sent checksum high byte: 0x%x\n",(unsigned char)pc_csum>>8); */
cd64_send_byte(cd64, (uint8_t) ((pc_csum & 0xff) + send_bogus_csum));
/* debug("Sent checksum low byte: 0x%x\n",pc_csum); */
cd64_grab_byte(cd64, &buf[2]);
cd64_trade_bytes(cd64, 0, &buf[0]);
cd64_trade_bytes(cd64, 0, &buf[1]);
/* debug("Got: (dummy) 0x%x, 0x%x (%c), 0x%x (%c)",buf[2], buf[0], buf[0], buf[1],buf[1]); */
if (buf[0]=='O' && buf[1]=='K') return 1;
else if (send_bogus_csum) {
cd64->notice_callback("No way to verify integrity of data in N64 RAM.");
return 1;
}
return -1;
}
int cd64_ghemor_grab(struct cd64_t *cd64, void *io_id, uint8_t slow, int *elapsed) {
int ret;
uint8_t tmp;
int sec = 0, usec = 0;
#if (defined _WIN32 && !defined __CYGWIN__) || defined __MSDOS__
struct timeb tb;
#else
struct timeval tv;
#endif
uint32_t len;
uint16_t mycsum = 0;
uint16_t cd64csum;
unsigned int i;
if (slow) {
cd64->notice_callback2("Ghemor slow receive feature not supported.");
return 0;
}
if (elapsed != NULL) {
#if (defined _WIN32 && !defined __CYGWIN__) || defined __MSDOS__
ftime(&tb);
sec = tb.time;
usec = tb.millitm*1000;
#else
gettimeofday(&tv, 0);
sec = tv.tv_sec;
usec = tv.tv_usec;
#endif
}
cd64_send_byte(cd64, slow);
i = 0;
while (cd64_grab_byte(cd64, &tmp) && tmp != 1) {
i++;
if (i > 25) {
cd64->notice_callback2("Ghemor was not ready.");
return 0;
}
}
cd64_grab_dword(cd64, &len);
cd64->notice_callback("Downloading %lu megabits via Ghemor.",
(long unsigned int) len/BYTES_IN_MBIT);
for (i = 0; i < len; i++) {
if (!cd64_grab_byte(cd64, &tmp)) return 0;
if (!cd64->write_callback(io_id, &tmp, 1)) {
cd64->notice_callback2("Error writing to output.");
return 0;
}
mycsum += tmp;
mycsum &= 0xfff;
if ((i % CD64_BUFFER_SIZE == 0) && cd64->progress_callback) {
cd64->progress_callback(i, len);
}
}
if (cd64->progress_callback) {
cd64->progress_callback(i, len);
}
cd64_grab_byte(cd64, &tmp);
cd64csum = tmp << 8;
cd64_grab_byte(cd64, &tmp);
cd64csum |= tmp;
if (mycsum^cd64csum) ret = -1;
else ret = 1;
if (elapsed != NULL) {
#if (defined _WIN32 && !defined __CYGWIN__) || defined __MSDOS__
ftime(&tb);
*elapsed = ((tb.time - sec)*1000000) + ((tb.millitm*1000) - usec);
#else
gettimeofday(&tv, 0);
*elapsed = ((tv.tv_sec - sec)*1000000) + (tv.tv_usec - usec);
#endif
}
return ret;
}
int cd64_ghemor_send(struct cd64_t *cd64, void *io_id, uint32_t length,
int *elapsed) {
int sec = 0, usec = 0;
uint16_t mycsum = 0;
unsigned int i;
#if (defined _WIN32 && !defined __CYGWIN__) || defined __MSDOS__
struct timeb tb;
#else
struct timeval tv;
#endif
uint8_t tmp;
if (elapsed != NULL) {
#if (defined _WIN32 && !defined __CYGWIN__) || defined __MSDOS__
ftime(&tb);
sec = tb.time;
usec = tb.millitm*1000;
#else
gettimeofday(&tv, 0);
sec = tv.tv_sec;
usec = tv.tv_usec;
#endif
}
cd64_send_byte(cd64, 0); /* No slow mode for sends */
i = 0;
while (cd64_grab_byte(cd64, &tmp) && tmp != 1) {
i++;
if (i > 25) {
cd64->notice_callback2("Ghemor was not ready.");
return 0;
}
}
cd64_send_dword(cd64, length);
for (i = 0; i < length; i++) {
if (!cd64->read_callback(io_id, &tmp, 1)) {
cd64->notice_callback2("Error reading from input.");
return 0;
}
if (!cd64_send_byte(cd64, tmp)) return 0;
mycsum += tmp;
mycsum &= 0xfff;
if ((i % CD64_BUFFER_SIZE == 0) && cd64->progress_callback) {
cd64->progress_callback(i, length);
}
}
if (cd64->progress_callback) {
cd64->progress_callback(i, length);
}
cd64_send_byte(cd64, (uint8_t)((mycsum << 8) & 0xff));
cd64_send_byte(cd64, (uint8_t)(mycsum & 0xff));
if (elapsed != NULL) {
#if (defined _WIN32 && !defined __CYGWIN__) || defined __MSDOS__
ftime(&tb);
*elapsed = ((tb.time - sec)*1000000) + ((tb.millitm*1000) - usec);
#else
gettimeofday(&tv, 0);
*elapsed = ((tv.tv_sec - sec)*1000000) + (tv.tv_usec - usec);
#endif
}
return 1;
}
/* Generic API functions */
int cd64_upload_dram(struct cd64_t *cd64, FILE *source, uint32_t length,
int *elapsed, int exec) {
if (cd64->protocol == CD64BIOS || cd64->protocol == GHEMOR) {
int cmd;
if (exec == 1) cmd = BIOS_EXECUTE_PI;
else cmd = BIOS_TRANSFER_PI;
if (cd64->protocol == CD64BIOS && length == 0) {
cd64->notice_callback2("CD64 BIOS needs a file length.");
return 0;
}
if (cd64->protocol == CD64BIOS) {
cd64->notice_callback("Choose CD64 Tools->Pro Comms Link.");
}
return cd64_bios_send(cd64, source, 0xb4000000, length, elapsed, cmd);
}
cd64->notice_callback2("Operation not supported by protocol.");
return 0;
}
int cd64_upload_bootemu(struct cd64_t *cd64, FILE *infile, uint32_t length, int *elapsed) {
if (cd64->protocol == CD64BIOS) {
if (cd64->protocol == CD64BIOS && length == 0) {
cd64->notice_callback2("CD64 BIOS needs a file length.\n");
return 0;
}
cd64->notice_callback("Choose CD64 Tools->Pro Comms Link.");
return cd64_bios_send(cd64, infile, BIOS_TEMP_RAM, length, elapsed,
BIOS_TRANSFER_N64);
}
else if (cd64->protocol == GHEMOR) {
cd64_bios_sync(cd64);
cd64_send_byte(cd64, GHEMOR_EXECUTE_BOOTEMU);
return cd64_ghemor_send(cd64, infile, length, elapsed);
}
cd64->notice_callback2("Operation not supported by protocol.");
return 0;
}
int cd64_upload_ram(struct cd64_t *cd64, FILE *infile, uint32_t length,
int *elapsed, uint32_t address) {
if (cd64->protocol == CD64BIOS) {
cd64->notice_callback("Choose CD64 Tools->Pro Comms Link.");
return cd64_bios_send(cd64, infile, address, length,
elapsed, BIOS_TRANSFER_N64);
}
cd64->notice_callback2("Operation not supported by protocol.");
return 0;
}
int cd64_upload_mempak(struct cd64_t *cd64, FILE *infile, int8_t which) {
int32_t len;
int32_t pos = cd64->tell_callback(infile);
cd64->seek_callback(infile, 0, SEEK_END);
len = cd64->tell_callback(infile);
cd64->seek_callback(infile, pos, SEEK_SET);
if (len != CONTROLLER_MEMPAK_LENGTH) {
cd64->notice_callback("Mempack file must be %d bytes, not %d.",
CONTROLLER_MEMPAK_LENGTH, len);
}
if (cd64->protocol == CD64BIOS) {
if (which != -1) {
cd64->notice_callback2("CD64 BIOS doesn't let mempak index be chosen.");
return 0;
}
cd64->notice_callback("Choose Memory Manager->Up/Download Pak.");
return cd64_bios_send(cd64, infile, BIOS_TEMP_RAM, CONTROLLER_MEMPAK_LENGTH,
NULL, BIOS_TRANSFER_N64);
}
else if (cd64->protocol == GHEMOR) {
cd64_bios_sync(cd64);
cd64_send_byte(cd64, GHEMOR_RESTORE_MEMPAK);
cd64_send_byte(cd64, which);
return cd64_ghemor_send(cd64, infile, CONTROLLER_MEMPAK_LENGTH, NULL);
}
cd64->notice_callback2("Operation not supported by protocol.");
return 0;
}
int cd64_upload_sram(struct cd64_t *cd64, FILE *infile) {
if (cd64->protocol == CD64BIOS) {
cd64->notice_callback("Choose CD64 Tools->Pro Comms Link.");
return cd64_bios_send(cd64, infile, 0xa8000000, CART_SRAM_LENGTH,
NULL, BIOS_TRANSFER_PI);
}
else if (cd64->protocol == GHEMOR) {
cd64_bios_sync(cd64);
cd64_send_byte(cd64, GHEMOR_RESTORE_SRAM);
return cd64_ghemor_send(cd64, infile, CART_SRAM_LENGTH, NULL);
}
cd64->notice_callback2("Operation not supported by protocol.");
return 0;
}
int cd64_upload_flashram(struct cd64_t *cd64, FILE *infile) {
/* Urm, we need to figure out if this really works. Probably, CTR
* needs to release a new Ghemor version. Maybe it works with
* CD64 BIOS but probably not. */
if (cd64->protocol == CD64BIOS) {
cd64->notice_callback("Choose CD64 Tools->Pro Comms Link.");
return cd64_bios_send(cd64, infile, 0xa8000000, CART_FLASHRAM_LENGTH,
NULL, BIOS_TRANSFER_PI);
}
else if (cd64->protocol == GHEMOR) {
cd64_bios_sync(cd64);
cd64_send_byte(cd64, GHEMOR_RESTORE_FLASHRAM);
return cd64_ghemor_send(cd64, infile, CART_FLASHRAM_LENGTH, NULL);
}
cd64->notice_callback2("Operation not supported by protocol.");
return 0;
}
int cd64_upload_eeprom(struct cd64_t *cd64, FILE *infile) {
/* Check the size of the EEPROM data first */
int32_t origpos = cd64->tell_callback(infile);
int32_t length;
if (cd64->protocol == CD64BIOS) {
cd64->notice_callback2("CD64 BIOS can only transfer EEPROM through BRAM Manager.");
return 0;
}
cd64->seek_callback(infile, 0, SEEK_END);
length = cd64->tell_callback(infile);
cd64->seek_callback(infile, origpos, SEEK_SET);
if (length != CART_EEPROM_LENGTH && length != CART_2XEEPROM_LENGTH) {
cd64->notice_callback2("Wrong length of EEPROM data: %d bytes", (int) length);
return 0;
}
else if (cd64->protocol == GHEMOR) {
cd64_bios_sync(cd64);
cd64_send_byte(cd64, GHEMOR_RESTORE_EEPROM);
return cd64_ghemor_send(cd64, infile, length, NULL);
}
cd64->notice_callback2("Operation not supported by protocol.");
return 0;
}
static int cd64_write_mem(void *dummy, void *buffer, uint32_t size) {
(void) dummy;
memcpy (cd64_tmp_buf + cd64_tmp_buf_offset, buffer, size);
cd64_tmp_buf_offset += size;
return size;
}
int cd64_download_header(struct cd64_t *cd64, n64header_t *head, uint32_t location) {
if (cd64->protocol == CD64BIOS) {
int size = sizeof(n64header_t);
int ret;
int (*org_write_cb)(void *, void *, uint32_t) = cd64->write_callback;
while (size % 4 != 0) size++;
if (!head) return 0;
cd64_tmp_buf = (uint8_t *) head;
cd64_tmp_buf_offset = 0;
cd64->write_callback = cd64_write_mem;
ret = cd64_bios_grab(cd64, (void *) -1, location, size, NULL); /* -1 is just a random (non-zero) value */
cd64->write_callback = org_write_cb; /* restore original callback */
return 1;
}
cd64->notice_callback2("Operation not supported by protocol.");
return 0;
}
int cd64_download_cart(struct cd64_t *cd64, FILE *outfile, uint32_t length,
int *elapsed) {
if (cd64->protocol == CD64BIOS) {
int ret;
unsigned int i;
int32_t curpos = 0;
int32_t origpos = cd64->tell_callback(outfile);
if (length == 0) {
cd64->notice_callback2("CD64 BIOS needs a file length.");
return 0;
}
cd64->notice_callback("Choose CD64 Tools->Pro Comms Link.");
ret = cd64_bios_grab(cd64, outfile, 0xb2000000, length, elapsed);
/* Scan through the file at 8MBit intervals to
* see if we overdumped. If we did, truncate the
* file. */
i = 0;
cd64->seek_callback(outfile, origpos, SEEK_SET);
cd64->notice_callback("Checking for overdump...");
while (i < length) {
int j = 0;
int overdump = 1;
uint8_t buf[4];
curpos = cd64->tell_callback(outfile);
while(i+j < length) {
cd64->read_callback(outfile, &buf, 4);
/* To elaborate on what we are checking here:
* When the CD64 accesses an address which is not
* decoded, in each 32-bit word is the lower 16 bits
* of the address of that 32-bit word, repeated twice.
* The pattern therefore looks like:
* 00 00 00 00 00 04 00 04 00 08 00 08 00 0c 00 0c
* and continues on like that. This pattern is what
* we are looking for here. It is possible, but
* extremely unlikely, that this pattern appears in a
* actual game and begins on a 8Mbit boundary too. */
if (
((uint8_t*)buf)[0] != ((j >> 8) & 0xff)
|| ((uint8_t*)buf)[1] != (j & 0xff)
|| ((uint8_t*)buf)[2] != ((j >> 8) & 0xff)
|| ((uint8_t*)buf)[3] != (j & 0xff)
) {
overdump = 0;
break;
}
else {
j+=4;
}
}
if (overdump) {
break;
}
i += 0x100000;
cd64->seek_callback(outfile, curpos+0x100000, SEEK_SET);
}
if (i < length) {
cd64->notice_callback("File apparently overdumped.");
#if (!defined _WIN32 || defined __CYGWIN__)
/* Don't call ftruncate() if the user installed a callback, because
* outfile may not be a real FILE *. */
if (cd64->read_callback == cd64_read) {
cd64->notice_callback("Truncating to %dMbits.", i/BYTES_IN_MBIT);
ftruncate(fileno(outfile), curpos+i);
}
#endif
}
return ret;
}
else if (cd64->protocol == GHEMOR) {
cd64_bios_sync(cd64);
cd64_send_byte(cd64, GHEMOR_DUMP_CART);
return cd64_ghemor_grab(cd64, outfile, 0, elapsed);
}
cd64->notice_callback2("Operation not supported by protocol.");
return 0;
}
int cd64_download_dram(struct cd64_t *cd64, FILE *outfile, uint32_t start,
uint32_t end, int *elapsed) {
if (cd64->protocol == CD64BIOS) {
cd64->notice_callback("Choose CD64 Tools->Pro Comms Link.");
return cd64_bios_grab(cd64, outfile, 0xb4000000, end-start, elapsed);
}
cd64->notice_callback2("Operation not supported by protocol.");
return 0;
}
int cd64_download_sram(struct cd64_t *cd64, FILE *outfile) {
if (cd64->protocol == CD64BIOS) {
cd64->notice_callback("Choose CD64 Tools->Pro Comms Link.");
return cd64_bios_grab(cd64, outfile, CART_SRAM_ADDR, CART_SRAM_LENGTH, NULL);
}
else if (cd64->protocol == GHEMOR) {
cd64_bios_sync(cd64);
cd64_send_byte(cd64, GHEMOR_DUMP_SRAM);
return cd64_ghemor_grab(cd64, outfile, 0, NULL);
}
cd64->notice_callback2("Operation not supported by protocol.");
return 0;
}
int cd64_download_flashram(struct cd64_t *cd64, FILE *outfile) {
/* We might be able to support CD64 BIOS here. Needs testing. */
if (cd64->protocol == GHEMOR) {
cd64_bios_sync(cd64);
cd64_send_byte(cd64, GHEMOR_DUMP_FLASH);
return cd64_ghemor_grab(cd64, outfile, 0, NULL);
}
cd64->notice_callback2("Operation not supported by protocol.");
return 0;
}
int cd64_download_eeprom(struct cd64_t *cd64, FILE *outfile) {
if (cd64->protocol == GHEMOR) {
cd64_bios_sync(cd64);
cd64_send_byte(cd64, GHEMOR_DUMP_EEPROM);
return cd64_ghemor_grab(cd64, outfile, 0, NULL);
}
cd64->notice_callback2("Operation not supported by protocol.");
return 0;
}
int cd64_download_mempak(struct cd64_t *cd64, FILE *outfile, int8_t which) {
if (cd64->protocol == CD64BIOS) {
if (which != -1) {
cd64->notice_callback2("CD64 BIOS doesn't let mempak index be chosen.");
return 0;
}
cd64->notice_callback("Choose Memory Manager->Up/Download Pak.");
return cd64_bios_grab(cd64, outfile, BIOS_TEMP_RAM, CONTROLLER_MEMPAK_LENGTH, NULL);
}
else if (cd64->protocol == GHEMOR) {
cd64_bios_sync(cd64);
cd64_send_byte(cd64, GHEMOR_DUMP_MEMPAK);
cd64_send_byte(cd64, which);
return cd64_ghemor_grab(cd64, outfile, 0, NULL);
}
cd64->notice_callback2("Operation not supported by protocol.");
return 0;
}
static int cd64_read_mem(void *dummy, void *buffer, uint32_t size) {
(void) dummy;
memcpy (buffer, cd64_tmp_buf + cd64_tmp_buf_offset, size);
cd64_tmp_buf_offset += size;
return size;
}
static int32_t cd64_tell_mem(void *dummy) {
(void) dummy;
return cd64_tmp_buf_offset;
}
static int cd64_seek_mem(void *dummy, int32_t offset, int whence) {
(void) dummy;
(void) whence; /* only called with SEEK_SET */
cd64_tmp_buf_offset = offset;
return 0;
}
int cd64_run_dram(struct cd64_t *cd64) {
if (cd64->protocol == GHEMOR) {
cd64_bios_sync(cd64);
cd64_send_byte(cd64, GHEMOR_RESET_DRAM);
return 1;
}
else if (cd64->protocol == CD64BIOS) {
/* Heh. Write some dummy bytes to the cart area. We
* can't just send a zero length because the CD64
* BIOS gives "File length error". */
uint8_t dummy[4] = { 0, 0, 0, 0 };
int ret;
int (*org_read_cb)(void *, void *, uint32_t) = cd64->read_callback;
int32_t (*org_tell_cb)(void *) = cd64->tell_callback;
int (*org_seek_cb)(void *, int32_t, int) = cd64->seek_callback;
cd64->notice_callback("Choose CD64 Tools->Pro Comms Link.");
cd64_tmp_buf = dummy;
cd64_tmp_buf_offset = 0;
cd64->read_callback = cd64_read_mem;
cd64->tell_callback = cd64_tell_mem;
cd64->seek_callback = cd64_seek_mem;
ret = cd64_bios_send(cd64, (void *) -1, 0xb2000000, 4, NULL, BIOS_EXECUTE_PI); /* -1 is just a random (non-zero) value */
cd64->read_callback = org_read_cb; /* restore original callbacks */
cd64->tell_callback = org_tell_cb;
cd64->seek_callback = org_seek_cb;
return ret;
}
cd64->notice_callback2("Operation not supported by protocol.");
return 0;
}
int cd64_run_cart(struct cd64_t *cd64) {
if (cd64->protocol == GHEMOR) {
cd64_bios_sync(cd64);
cd64_send_byte(cd64, GHEMOR_RESET_CART);
return 1;
}
cd64->notice_callback2("Operation not supported by protocol.");
return 0;
}

View File

@ -0,0 +1,13 @@
#ifndef __CARTMEM_H__
#define __CARTMEM_H__
#define CART_EEPROM_LENGTH 0x200 /* 512 bytes */
#define CART_2XEEPROM_LENGTH 0x800 /* 2048 bytes */
#define CART_SRAM_LENGTH 0x8000 /* 32KB */
#define CART_FLASHRAM_LENGTH 0x20000 /* 128KB */
#define CONTROLLER_MEMPAK_LENGTH 0x8000 /* 32KB */
#define CART_SRAM_ADDR 0xa8000000
#define CART_FLASHRAM_ADDR CART_SRAM_ADDR
#endif

View File

@ -0,0 +1,8 @@
#ifndef __ULTRA64__HOST__CARTINFO_H__
#define __ULTRA64__HOST__CARTINFO_H__
#include <ultra64/rom.h>
void ultra64_header_info(n64header_t *carthead);
#endif

View File

@ -0,0 +1,189 @@
#ifndef __CD64LIB_H__
#define __CD64LIB_H__
#ifdef __cplusplus
extern "C" {
#endif
#define CD64_BUFFER_SIZE 32768
/* This is the only public header file for cd64lib. */
#if __STDC_VERSION >= 19990L
#include <stdint.h>
#else
#if !(defined __MSDOS__ || defined _MSC_VER)
#include <inttypes.h>
#else
#ifndef OWN_INTTYPES
#define OWN_INTTYPES /* signal that these are defined */
typedef unsigned char uint8_t;
typedef unsigned short int uint16_t;
typedef unsigned int uint32_t;
#ifndef _MSC_VER /* _WIN32 */
typedef unsigned long long int uint64_t;
#else
typedef unsigned __int64 uint64_t;
#endif
typedef signed char int8_t;
typedef signed short int int16_t;
typedef signed int int32_t;
#ifndef _MSC_VER /* _WIN32 */
typedef signed long long int int64_t;
#else
typedef signed __int64 int64_t;
#endif
#endif /* OWN_INTTYPES */
#endif /* __MSDOS__ || _MSC_VER */
#endif /* STDC_VERSION */
#include <stdio.h> /* FILE, FILENAME_MAX */
#include <ultra64/rom.h>
typedef enum {
CD64BIOS = 0,
GHEMOR = 1,
ULTRALINK = 2
} protocol_t;
typedef enum {
LIBIEEE1284 = 1,
PPDEV = 2,
PORTDEV = 3,
RAWIO = 4
} method_t;
/* When using this structure, be sure to calloc it or otherwise set it to
* zero before setting values or calling library functions. */
struct cd64_t {
int using_ppa;
protocol_t protocol;
struct parport *ppdev; /* libieee1284 */
int ppdevfd; /* ppdev */
int portdevfd; /* /dev/port */
/* If using inb/outb or /dev/port, this is the I/O address
* Otherwise it is the parport* number */
int port;
/* Directory with io.dll or dlportio.dll. Used by the Windows ports. */
char io_driver_dir[FILENAME_MAX];
/* A flag that can be set/read to determine whether
* the current operation should be canceled. */
int abort;
int (*devopen)(struct cd64_t *cd64);
int (*xfer)(struct cd64_t *cd64, uint8_t *write, uint8_t *read, int delayms);
int (*devclose)(struct cd64_t *cd64);
/* Progress callback is responsible for printing header info if the
* user wants it */
void (*progress_callback)(uint32_t curbyte, uint32_t totalbytes);
int (*notice_callback)(const char *format, ...);
int (*notice_callback2)(const char *format, ...);
/* Callbacks for read, write and seek operations. By default they point to
* callbacks in the library which just call fread(), fwrite(), ftell() and
* fseek(). You can change them so that the library doesn't read from or
* write to a FILE * (io_id). For example, a client can install its own
* callback to make it possible to read from .zip files. */
int (*read_callback)(void *io_id, void *buffer, uint32_t size);
int (*write_callback)(void *io_id, void *buffer, uint32_t size);
int32_t (*tell_callback)(void *io_id);
int (*seek_callback)(void *io_id, int32_t offset, int whence);
};
/* This function must be called and return successful before any of the
* other functions may be used. */
int cd64_create(struct cd64_t *cd64, method_t method,
uint16_t port, protocol_t protocol, int ppa);
/* The following five functions are wrappers above the I/O abstraction.
* Use them to write code that works regardless of the underlying
* transport. */
int cd64_send_byte(struct cd64_t *cd64, uint8_t what);
int cd64_send_dword(struct cd64_t *cd64, uint32_t what);
int cd64_grab_byte(struct cd64_t *cd64, uint8_t *val);
int cd64_grab_dword(struct cd64_t *cd64, uint32_t *val);
int cd64_trade_bytes(struct cd64_t *cd64, uint8_t give, uint8_t *recv);
/* Generic protocol handlers */
int cd64_bios_grab(struct cd64_t *cd64, void *io_id, uint32_t addr, uint32_t length,
int *elapsed);
int cd64_bios_send(struct cd64_t *cd64, void *io_id, uint32_t addr,
uint32_t length, int *elapsed, int cmd);
int cd64_ghemor_grab(struct cd64_t *cd64, void *io_id, uint8_t slow, int *elapsed);
int cd64_ghemor_send(struct cd64_t *cd64, void *io_id, uint32_t length,
int *elapsed);
/* Functions for sending files to CD64 */
int cd64_upload_dram(struct cd64_t *cd64, FILE *infile, uint32_t length,
int *elapsed, int exec);
int cd64_upload_ram(struct cd64_t *cd64, FILE *infile, uint32_t length,
int *elapsed, uint32_t address);
int cd64_upload_bootemu(struct cd64_t *cd64, FILE *infile, uint32_t length, int *elapsed);
int cd64_upload_sram(struct cd64_t *cd64, FILE *infile);
int cd64_upload_flashram(struct cd64_t *cd64, FILE *infile);
int cd64_upload_eeprom(struct cd64_t *cd64, FILE *infile);
int cd64_upload_mempak(struct cd64_t *cd64, FILE *infile, int8_t which);
/* Functions for receiving files from CD64 */
int cd64_download_cart(struct cd64_t *cd64, FILE *outfile, uint32_t length,
int *elapsed);
int cd64_download_dram(struct cd64_t *cd64, FILE *outfile, uint32_t start,
uint32_t end, int *elapsed);
int cd64_download_ram(struct cd64_t *cd64, FILE *outfile, uint32_t length,
int *elapsed, uint32_t address);
int cd64_download_sram(struct cd64_t *cd64, FILE *outfile);
int cd64_download_flashram(struct cd64_t *cd64, FILE *outfile);
int cd64_download_eeprom(struct cd64_t *cd64, FILE *outfile);
int cd64_download_mempak(struct cd64_t *cd64, FILE *outfile, int8_t which);
/* Remote control functions */
int cd64_run_dram(struct cd64_t *cd64);
int cd64_run_cart(struct cd64_t *cd64);
/* This function simply gets the header from the cart and can be displayed
* using ultra64_header_info() */
int cd64_download_header(struct cd64_t *cd64, n64header_t *head, uint32_t location);
#ifdef __cplusplus
}
#endif
#define BIOS_TEMP_RAM 0xa0300000
#define BIOS_DUMP_N64 'D'
#define BIOS_TRANSFER_N64 'B'
#define BIOS_DUMP_PI 'G'
#define BIOS_TRANSFER_PI 'T'
#define BIOS_EXECUTE_PI 'X'
#define GHEMOR_RESTORE_MEMPAK 1
#define GHEMOR_RESTORE_EEPROM 2
#define GHEMOR_RESTORE_SRAM 3
#define GHEMOR_RESTORE_FLASHRAM 4
#define GHEMOR_EXECUTE_BOOTEMU 5
#define GHEMOR_TRANSFER_PROGRAM 6
#define GHEMOR_DUMP_CART 7
#define GHEMOR_DUMP_MEMPAK 8
#define GHEMOR_DUMP_EEPROM 9
#define GHEMOR_DUMP_SRAM 10
#define GHEMOR_DUMP_FLASH 11
#define GHEMOR_RESET_DRAM 12
#define GHEMOR_RESET_CART 13
#endif

View File

@ -0,0 +1,60 @@
#ifndef __ROM_H__
#define __ROM_H__
/* Based on Daedalus header */
#define N64HEADER_SIZE 0x40
#define BYTES_IN_MBIT 0x20000
#define SwapEndian(x) \
((x >> 24)&0x000000FF) \
| ((x >> 8 )&0x0000FF00) \
| ((x << 8 )&0x00FF0000) \
| ((x << 24)&0xFF000000)
typedef enum {
UNKNOWN = 0,
EEP4K = 1,
EEP16K = 2,
SRAM = 3,
FLASHRAM = 4
} savetype_t;
typedef struct { /* From Daedalus */
unsigned char x1; /* initial PI_BSB_DOM1_LAT_REG value */
unsigned char x2; /* initial PI_BSB_DOM1_PGS_REG value */
unsigned char x3; /* initial PI_BSB_DOM1_PWD_REG value */
unsigned char x4; /* initial PI_BSB_DOM1_RLS_REG value */
unsigned long int ClockRate;
unsigned long int BootAddress;
unsigned long int Release;
unsigned long int CRC1;
unsigned long int CRC2;
unsigned long int Unknown0;
unsigned long int Unknown1;
char Name[20];
unsigned long int Unknown2;
unsigned short int Unknown3;
unsigned char Unknown4;
unsigned char Manufacturer;
unsigned short int CartID;
char CountryID;
unsigned char Unknown5;
} n64header_t;
typedef enum {
OS_TV_NTSC = 0,
OS_TV_PAL,
OS_TV_MPAL
} tv_type_t;
typedef struct
{
char nCountryID;
char szName[15];
unsigned long int nTvType;
} CountryIDInfo_t;
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,31 @@
/*
lynxit.h - lynxit support for uCON64
Copyright (c) 1997 - ???? K. Wilkins
Copyright (c) 2002 NoisyB <noisyb@gmx.net>
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.
*/
#ifndef LYNXIT_H
#define LYNXIT_H
extern const st_getopt2_t lynxit_usage[];
#ifdef USE_PARALLEL
extern int lynxit_read_rom (const char *filename, unsigned int parport);
#endif
#endif

View File

@ -0,0 +1,158 @@
/*
mccl.c - Mad Catz Camera Link (Game Boy Camera) support for uCON64
Copyright (c) 2002 NoisyB <noisyb@gmx.net>
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 <stdio.h>
#include <string.h>
#include <time.h>
#include "misc/misc.h"
#include "misc/file.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "ucon64.h"
#include "ucon64_misc.h"
#include "mccl.h"
#include "misc/parallel.h"
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",
&ucon64_wf[WF_OBJ_GB_DEFAULT_STOP_NO_ROM]
},
#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];
char dest_name[FILENAME_MAX];
int inbyte, 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 = inportw (DATA) & 0xf;
outportb (CONTROL, 0x22);
while ((inportb (STATUS) & 0x20) != 0)
;
outportb (CONTROL, 0x26);
while ((inportb (STATUS) & 0x20) == 0)
;
inbyte |= (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

View File

@ -0,0 +1,30 @@
/*
mccl.h - Mad Catz Camera Link (Game Boy Camera) support for uCON64
Copyright (c) 2002 NoisyB <noisyb@gmx.net>
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.
*/
#ifndef MCCL_H
#define MCCL_H
extern const st_getopt2_t mccl_usage[];
#ifdef USE_PARALLEL
extern int mccl_read (const char *filename, unsigned int parport);
#endif
#endif // MCCL_H

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -0,0 +1,144 @@
/*
mcd.c - Mike Pavone's Genesis/Sega CD transfer cable support for uCON64
Copyright (c) 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 <time.h>
#include "misc/misc.h"
#include "misc/parallel.h"
#include "misc/itypes.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "ucon64.h"
#include "ucon64_misc.h"
#include "mcd.h"
const st_getopt2_t mcd_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "Mike Pavone's Genesis/Sega CD transfer cable",
NULL
},
#ifdef USE_PARALLEL
{
"xmcd", 0, 0, UCON64_XMCD,
NULL, "receive ROM from Genesis/Sega CD; " OPTION_LONG_S "port=PORT",
&ucon64_wf[WF_OBJ_GEN_DEFAULT_STOP_NO_SPLIT_NO_ROM]
},
#endif
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
#ifdef USE_PARALLEL
#define BUFFERSIZE 8192
static void
checkabort (int status)
{
if (((!ucon64.frontend) ? kbhit () : 0) && getch () == 'q')
{
puts ("\nProgram aborted");
exit (status);
}
}
static void
read_block (unsigned char *buffer, int size, unsigned short parport)
{
int i;
for (i = 0; i < size; i++)
{
while (inportb ((unsigned short) (parport + PARPORT_STATUS)) & 0x08)
;
outportb ((unsigned short) (parport + PARPORT_CONTROL), 0xa2);
while (!(inportb ((unsigned short) (parport + PARPORT_STATUS)) & 0x08))
;
buffer[i] = inportb ((unsigned short) (parport + PARPORT_DATA)) & 0x0f;
outportb ((unsigned short) (parport + PARPORT_CONTROL), 0xa0);
while (inportb ((unsigned short) (parport + PARPORT_STATUS)) & 0x08)
;
outportb ((unsigned short) (parport + PARPORT_CONTROL), 0xa2);
while (!(inportb ((unsigned short) (parport + PARPORT_STATUS)) & 0x08))
;
buffer[i] |=
(inportb ((unsigned short) (parport + PARPORT_DATA)) & 0x0f) << 4;
outportb ((unsigned short) (parport + PARPORT_CONTROL), 0xa0);
}
}
int
mcd_read_rom (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char buffer[BUFFERSIZE];
int n_bytes = 0, size;
time_t starttime;
#if (defined __unix__ || defined __BEOS__) && !defined __MSDOS__
init_conio ();
#endif
parport_print_info ();
if ((file = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
read_block (buffer, 1, (unsigned short) parport);
size = (buffer[0] + 1) * 64 * 1024;
printf ("Receive: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
puts ("Press q to abort\n");
starttime = time (NULL);
while (n_bytes < size)
{
read_block (buffer, BUFFERSIZE, (unsigned short) parport);
fwrite (buffer, 1, BUFFERSIZE, file);
n_bytes += BUFFERSIZE;
ucon64_gauge (starttime, n_bytes, size);
checkabort (2);
}
fclose (file);
#if (defined __unix__ || defined __BEOS__) && !defined __MSDOS__
deinit_conio ();
#endif
return 0;
}
#endif // USE_PARALLEL

View File

@ -0,0 +1,30 @@
/*
mcd.h - Mike Pavone's Genesis/Sega CD transfer cable support for uCON64
Copyright (c) 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.
*/
#ifndef MCD_H
#define MCD_H
extern const st_getopt2_t mcd_usage[];
#ifdef USE_PARALLEL
extern int mcd_read_rom (const char *filename, unsigned int parport);
#endif
#endif

View File

@ -0,0 +1,395 @@
/*
md-pro.c - MD-PRO flash card programmer support for uCON64
Copyright (c) 2003 - 2004 dbjh
Copyright (c) 2003 NoisyB <noisyb@gmx.net>
Based on Delphi source code by ToToTEK Multi Media. Information in that source
code has been used with permission. However, ToToTEK Multi Media explicitly
stated that the information in that source code may be freely distributed.
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 <time.h>
#include "misc/parallel.h"
#include "misc/itypes.h"
#include "misc/misc.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "misc/file.h"
#include "ucon64.h"
#include "ucon64_misc.h"
#include "tototek.h"
#include "md-pro.h"
const st_getopt2_t mdpro_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "MD-PRO flash card programmer"/*"2003 ToToTEK Multi Media http://www.tototek.com"*/,
NULL
},
#ifdef USE_PARALLEL
{
"xmd", 0, 0, UCON64_XMD,
NULL, "send/receive ROM to/from MD-PRO flash card programmer\n" OPTION_LONG_S "port=PORT\n"
"receives automatically (32/64 Mbits) when ROM does not exist",
&ucon64_wf[WF_OBJ_GEN_DEFAULT_STOP_NO_SPLIT_NO_ROM]
},
{
"xmds", 0, 0, UCON64_XMDS,
NULL, "send/receive SRAM to/from MD-PRO flash card programmer\n" OPTION_LONG_S "port=PORT\n"
"receives automatically when SRAM does not exist",
&ucon64_wf[WF_OBJ_GEN_STOP_NO_ROM]
},
{
"xmdb", 1, 0, UCON64_XMDB,
"BANK", "send/receive SRAM to/from MD-PRO BANK\n"
"BANK can be a number from 1 to 4; " OPTION_LONG_S "port=PORT\n"
"receives automatically when SRAM does not exist",
&ucon64_wf[WF_OBJ_GEN_STOP_NO_ROM]
},
#endif
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
#ifdef USE_PARALLEL
static void eep_reset (void);
static void write_rom_by_byte (int *addr, unsigned char *buf);
static void write_rom_by_page (int *addr, unsigned char *buf);
static void write_ram_by_byte (int *addr, unsigned char *buf);
static void write_ram_by_page (int *addr, unsigned char *buf);
static unsigned short int md_id;
void
eep_reset (void)
{
ttt_rom_enable ();
ttt_write_mem (0x400000, 0xff); // reset EEP chip 2
ttt_write_mem (0, 0xff); // reset EEP chip 1
ttt_write_mem (0x600000, 0xff); // reset EEP chip 2
ttt_write_mem (0x200000, 0xff); // reset EEP chip 1
ttt_rom_disable ();
}
void
write_rom_by_byte (int *addr, unsigned char *buf)
{
int x;
for (x = 0; x < 0x4000; x++)
{
if (md_id == 0xb0d0)
ttt_write_byte_sharp (*addr, buf[*addr & 0x3fff]);
else if (md_id == 0x8916 || md_id == 0x8917)
ttt_write_byte_intel (*addr, buf[*addr & 0x3fff]);
(*addr)++;
}
}
void
write_rom_by_page (int *addr, unsigned char *buf)
{
int x;
for (x = 0; x < 0x200; x++)
{
ttt_write_page_rom (*addr, buf);
(*addr) += 0x20;
}
}
void
write_ram_by_byte (int *addr, unsigned char *buf)
{
int x, i = *addr & 0x3fff;
for (x = 0; x < 0x4000; x++, i = (i + 1) & 0x3fff)
{
ttt_write_byte_ram (*addr, buf[i]);
(*addr)++;
// Send the same byte again => SRAM files needn't store redundant data
ttt_write_byte_ram (*addr, buf[i]);
(*addr)++;
}
}
void
write_ram_by_page (int *addr, unsigned char *buf)
{
int x;
for (x = 0; x < 0x80; x++)
{
ttt_write_page_ram2 (*addr, buf);
(*addr) += 0x80;
}
}
int
md_read_rom (const char *filename, unsigned int parport, int size)
{
FILE *file;
unsigned char buffer[0x100];
int blocksleft, address = 0, id;
time_t starttime;
void (*read_block) (int, unsigned char *) = ttt_read_rom_w; // ttt_read_rom_b
if ((file = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
ttt_init_io (parport);
eep_reset ();
id = ttt_get_id ();
if ((id == 0xb0d0 || id == 0x8916) && size > 32 * MBIT)
size = 32 * MBIT; // Sharp or Intel 32 Mbit flash card
#if 0
// size is set to 64 * MBIT "by default" (in ucon64_opts.c)
else if (id == 0x8917 && size > 64 * MBIT)
size = 64 * MBIT; // Intel 64 Mbit flash card
#endif
printf ("Receive: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
blocksleft = size >> 8;
eep_reset ();
ttt_rom_enable ();
if (read_block == ttt_read_rom_w)
ttt_set_ai_data (6, 0x94); // rst=1, wei=0(dis.), rdi=0(dis.), inc mode, rom_CS
starttime = time (NULL);
while (blocksleft-- > 0)
{
read_block (address, buffer); // 0x100 bytes read
if (read_block == ttt_read_rom_b)
ucon64_bswap16_n (buffer, 0x100);
fwrite (buffer, 1, 0x100, file);
address += 0x100;
if ((address & 0x3fff) == 0)
ucon64_gauge (starttime, address, size);
}
// original code doesn't call ttt_rom_disable() when byte-size function is
// used (ttt_read_rom_b() calls it)
if (read_block == ttt_read_rom_w)
ttt_rom_disable ();
fclose (file);
ttt_deinit_io ();
return 0;
}
int
md_write_rom (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char buffer[0x4000];
int size, address = 0, bytesread, bytessend = 0;
time_t starttime;
void (*write_block) (int *, unsigned char *) = write_rom_by_page; // write_rom_by_byte
(void) write_rom_by_byte;
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
ttt_init_io (parport);
size = fsizeof (filename);
printf ("Send: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
eep_reset ();
md_id = ttt_get_id ();
if ((md_id != 0xb0d0) && (md_id != 0x8916) && (md_id != 0x8917)) // Sharp 32M, Intel 64J3
{
fputs ("ERROR: MD-PRO flash card (programmer) not detected\n", stderr);
fclose (file);
ttt_deinit_io ();
exit (1);
}
starttime = time (NULL);
eep_reset ();
while ((bytesread = fread (buffer, 1, 0x4000, file)))
{
ucon64_bswap16_n (buffer, 0x4000);
if ((((address & 0xffff) == 0) && (md_id == 0xb0d0)) ||
(((address & 0x1ffff) == 0) && (md_id == 0x8916 || md_id == 0x8917)))
ttt_erase_block (address);
write_block (&address, buffer);
bytessend += bytesread;
ucon64_gauge (starttime, bytessend, size);
}
fclose (file);
ttt_deinit_io ();
return 0;
}
int
md_read_sram (const char *filename, unsigned int parport, int start_bank)
/*
The MD-PRO has 256 kB of SRAM. However, the SRAM dumps of all games that have
been tested had each byte doubled. In order to make it possible to easily
obtain the SRAM data for use in an emulator, or to send an emulator SRAM file
to the MD-PRO, we remove the redundant data when receiving/dumping and double
the data when sending.
It could be that this approach causes trouble for some games. However, when
looking at ToToTEK's own code in ttt_write_page_ram2() this seems unlikely
(data is doubled in that function). Note that write_sram_by_byte() is a
function written by us, and so does the doubling of data, but it doesn't mean
it should work for all games.
*/
{
FILE *file;
unsigned char buffer[0x100];
int blocksleft, address, bytesreceived = 0, size, i;
time_t starttime;
void (*read_block) (int, unsigned char *) = ttt_read_ram_b; // ttt_read_ram_w
// This function does not seem to work if ttt_read_ram_w() is used, but see
// note below
if (start_bank == -1)
{
address = 0;
size = 128 * 1024;
}
else
{
if (start_bank < 1 || start_bank > 4)
{
fputs ("ERROR: Bank must be a value 1 - 4\n", stderr);
exit (1);
}
address = (start_bank - 1) * 32 * 1024;
size = 32 * 1024;
}
if ((file = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
ttt_init_io (parport);
printf ("Receive: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
if (read_block == ttt_read_ram_w)
{
// address *= 2;
ttt_ram_enable ();
#if 0
// According to JohnDie, disabling this statement should make it possible
// to use ttt_read_ram_w().
ttt_set_ai_data (6, 0x98); // rst=1, wei=0(dis.), rdi=0(dis.), inc mode, rom_CS
#endif
}
// else
// ttt_set_ai_data (6, 0x94); // rst=1, wei=0(dis.), rdi=0(dis.), inc mode, rom_CS
blocksleft = size >> 7;
starttime = time (NULL);
while (blocksleft-- > 0)
{
read_block (address, buffer); // 0x100 bytes read
for (i = 0; i < 0x80; i++)
buffer[i] = buffer[2 * i]; // data is doubled => no problems with endianess
fwrite (buffer, 1, 0x80, file);
address += 0x100;
bytesreceived += 0x80;
if ((address & 0x3fff) == 0)
ucon64_gauge (starttime, bytesreceived, size);
}
if (read_block == ttt_read_ram_w)
ttt_ram_disable ();
fclose (file);
ttt_deinit_io ();
return 0;
}
int
md_write_sram (const char *filename, unsigned int parport, int start_bank)
{
FILE *file;
unsigned char buffer[0x4000];
int size, bytesread, bytessend = 0, address;
time_t starttime;
void (*write_block) (int *, unsigned char *) = write_ram_by_byte; // write_ram_by_page
(void) write_ram_by_page;
size = fsizeof (filename);
if (start_bank == -1)
address = 0;
else
{
if (start_bank < 1 || start_bank > 4)
{
fputs ("ERROR: Bank must be a value 1 - 4\n", stderr);
exit (1);
}
address = (start_bank - 1) * 32 * 1024;
}
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
ttt_init_io (parport);
printf ("Send: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
starttime = time (NULL);
while ((bytesread = fread (buffer, 1, 0x4000, file)))
{
write_block (&address, buffer);
bytessend += bytesread;
ucon64_gauge (starttime, bytessend, size);
}
fclose (file);
ttt_deinit_io ();
return 0;
}
#endif // USE_PARALLEL

View File

@ -0,0 +1,37 @@
/*
md-pro.h - MD-PRO flash card programmer support for uCON64
Copyright (c) 2003 dbjh
Based on Delphi source code by ToToTEK Multi Media. Information in that source
code has been used with permission. However, ToToTEK Multi Media explicitly
stated that the information in that source code may be freely distributed.
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.
*/
#ifndef MD_PRO_H
#define MD_PRO_H
extern const st_getopt2_t mdpro_usage[];
#ifdef USE_PARALLEL
extern int md_read_rom (const char *filename, unsigned int parport, int size);
extern int md_write_rom (const char *filename, unsigned int parport);
extern int md_read_sram (const char *filename, unsigned int parport, int start_bank);
extern int md_write_sram (const char *filename, unsigned int parport, int start_bank);
#endif
#endif

View File

@ -0,0 +1,466 @@
/*
mgd.c - Multi Game Doctor/Hunter support for uCON64
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
Copyright (c) 2001 - 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 <ctype.h>
#include "misc/misc.h"
#include "misc/file.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "ucon64.h"
#include "ucon64_misc.h"
#include "misc/string.h"
#include "mgd.h"
const st_getopt2_t mgd_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "Multi Game Doctor (2)/Multi Game Hunter/MGH"
/*"19XX Bung Enterprises Ltd http://www.bung.com.hk\n" "?Makko Toys Co., Ltd.?"*/,
NULL
},
#if 0
{
"xmgd", 0, 0, UCON64_XMGD,
NULL, "(TODO) send/receive ROM to/from Multi Game* /MGD2/MGH; " OPTION_LONG_S "port=PORT\n"
"receives automatically when " OPTION_LONG_S "rom does not exist",
NULL
},
#endif
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
// the following four functions are used by non-transfer code in genesis.c
void
mgd_interleave (unsigned char **buffer, int size)
{
int n;
unsigned char *src = *buffer;
if (!(*buffer = (unsigned char *) malloc (size)))
{
fprintf (stderr, ucon64_msg[BUFFER_ERROR], size);
exit (1);
}
for (n = 0; n < size / 2; n++)
{
(*buffer)[n] = src[n * 2 + 1];
(*buffer)[size / 2 + n] = src[n * 2];
}
free (src);
}
void
mgd_deinterleave (unsigned char **buffer, int data_size, int buffer_size)
{
int n = 0, offset;
unsigned char *src = *buffer;
if (!(*buffer = (unsigned char *) malloc (buffer_size)))
{
fprintf (stderr, ucon64_msg[BUFFER_ERROR], buffer_size);
exit (1);
}
for (offset = 0; offset < data_size / 2; offset++)
{
(*buffer)[n++] = src[data_size / 2 + offset];
(*buffer)[n++] = src[offset];
}
free (src);
}
int
fread_mgd (void *buffer, size_t size, size_t number, FILE *fh)
/*
This function is used to handle a Genesis MGD file as if it wasn't
interleaved, without the overhead of reading the entire file into memory.
This is important for genesis_init(). When the file turns out to be a Genesis
dump in MGD format it is much more efficient for compressed files to read the
entire file into memory and then deinterleave it (as load_rom() does).
In order to speed this function up a bit ucon64.file_size is used. That means
it can't be used for an arbitrary file.
*/
{
int n = 0, bpos = 0, fpos, fpos_org, block_size, bytesread = 0,
len = number * size, fsize = ucon64.file_size /* fsizeof (filename) */;
unsigned char tmp1[MAXBUFSIZE], tmp2[MAXBUFSIZE];
fpos = fpos_org = ftell (fh);
if (fpos >= fsize)
return 0;
if (len == 0)
return 0;
else if (len == 1)
{
if (fpos_org & 1)
{
fseek (fh, fpos / 2, SEEK_SET);
*((unsigned char *) buffer) = fgetc (fh);
}
else
{
fseek (fh, fpos / 2 + fsize / 2, SEEK_SET);
*((unsigned char *) buffer) = fgetc (fh);
}
fseek (fh, fpos_org + 1, SEEK_SET);
return 1;
}
while (len > 0 && !feof (fh))
{
block_size = len > MAXBUFSIZE ? MAXBUFSIZE : len;
fseek (fh, fpos / 2, SEEK_SET);
bytesread += fread (tmp1, 1, block_size / 2, fh); // read odd bytes
fseek (fh, (fpos + 1) / 2 + fsize / 2, SEEK_SET);
bytesread += fread (tmp2, 1, block_size / 2, fh); // read even bytes
if (fpos_org & 1)
for (n = 0; n < block_size / 2; n++)
{
((unsigned char *) buffer)[bpos + n * 2] = tmp1[n];
((unsigned char *) buffer)[bpos + n * 2 + 1] = tmp2[n];
}
else
for (n = 0; n < block_size / 2; n++)
{
((unsigned char *) buffer)[bpos + n * 2] = tmp2[n];
((unsigned char *) buffer)[bpos + n * 2 + 1] = tmp1[n];
}
fpos += block_size;
bpos += block_size;
len -= block_size;
}
fseek (fh, fpos_org + bytesread, SEEK_SET);
return bytesread / size;
}
int
q_fread_mgd (void *buffer, size_t start, size_t len, const char *filename)
{
int result;
FILE *fh;
if ((fh = fopen (filename, "rb")) == NULL)
return -1;
fseek (fh, start, SEEK_SET);
result = (int) fread_mgd (buffer, 1, len, fh);
fclose (fh);
return result;
}
static void
remove_mgd_id (char *name, const char *id)
{
char *p = name;
while ((p = strstr (p, id)))
{
*p = 'X';
*(p + 1) = 'X';
p += 2;
}
}
void
mgd_make_name (const char *filename, int console, int size, char *name)
// these characters are also valid in MGD file names: !@#$%^&_
{
char *prefix = 0, *p, *size_str = 0, *suffix = 0;
const char *fname;
int n;
switch (console)
{
default: // falling through
case UCON64_SNES:
prefix = "SF";
suffix = ".048";
if (size <= 1 * MBIT)
size_str = "1";
else if (size <= 2 * MBIT)
size_str = "2";
else if (size <= 4 * MBIT)
size_str = "4";
else if (size <= 8 * MBIT)
{
size_str = "8";
suffix = ".058";
}
else
{
suffix = ".078";
if (size <= 10 * MBIT)
size_str = "10";
else if (size <= 12 * MBIT)
size_str = "12";
else if (size <= 16 * MBIT)
size_str = "16";
else if (size <= 20 * MBIT)
size_str = "20";
else if (size <= 24 * MBIT)
size_str = "24";
else // MGD supports SNES games with sizes up to 32 Mbit
size_str = "32";
}
break;
case UCON64_GEN:
prefix = "MD";
suffix = ".000";
if (size <= 1 * MBIT)
size_str = "1";
else if (size <= 2 * MBIT)
size_str = "2";
else if (size <= 4 * MBIT)
size_str = "4";
else
{
if (size <= 8 * MBIT)
{
size_str = "8";
suffix = ".008";
}
else if (size <= 16 * MBIT)
{
size_str = "16";
suffix = ".018";
}
else
{
suffix = ".038";
if (size <= 20 * MBIT)
size_str = "20";
else if (size <= 24 * MBIT)
size_str = "24";
else // MGD supports Genesis games with sizes up to 32 Mbit
size_str = "32";
}
}
break;
case UCON64_PCE:
prefix = "PC";
suffix = ".040";
if (size <= 1 * MBIT)
size_str = "1";
else if (size <= 2 * MBIT)
size_str = "2";
else if (size <= 3 * MBIT)
{
size_str = "3";
suffix = ".030";
}
else if (size <= 4 * MBIT)
{
size_str = "4";
suffix = ".048";
}
else
{
suffix = ".058";
if (size <= 6 * MBIT)
size_str = "6";
else // MGD supports PC-Engine games with sizes up to 8 Mbit
size_str = "8";
}
break;
case UCON64_SMS:
prefix = "GG";
suffix = ".060";
if (size < 1 * MBIT)
size_str = "0";
else if (size == 1 * MBIT)
size_str = "1";
else if (size <= 2 * MBIT)
size_str = "2";
else
{
suffix = ".078";
if (size <= 3 * MBIT)
size_str = "3";
else if (size <= 4 * MBIT)
size_str = "4";
else if (size <= 6 * MBIT)
size_str = "6";
else // MGD supports Sega Master System games with sizes up to 8 Mbit
size_str = "8";
}
break;
case UCON64_GAMEGEAR:
prefix = "GG";
suffix = ".040";
if (size < 1 * MBIT)
size_str = "0";
else if (size == 1 * MBIT)
size_str = "1";
else if (size <= 2 * MBIT)
size_str = "2";
else
{
suffix = ".048";
if (size <= 3 * MBIT)
size_str = "3";
else if (size <= 4 * MBIT)
size_str = "4";
else
{
suffix = ".078";
if (size <= 6 * MBIT)
size_str = "6";
else // MGD supports Game Gear games with sizes up to 8 Mbit
size_str = "8";
}
}
break;
case UCON64_GB:
prefix = "GB";
/*
What is the maximum game size the MGD2 supports for GB (color) games?
At least one 64 Mbit game exists, Densha De Go! 2 (J) [C][!].
*/
suffix = ".040";
if (size < 1 * MBIT)
size_str = "0";
else if (size == 1 * MBIT)
size_str = "1";
else if (size <= 2 * MBIT)
size_str = "2";
else if (size <= 3 * MBIT)
{
size_str = "3";
suffix = ".030";
}
else if (size <= 4 * MBIT)
{
size_str = "4";
suffix = ".048";
}
else
{
suffix = ".058";
if (size <= 6 * MBIT)
size_str = "6";
else
size_str = "8";
}
break;
}
fname = basename2 (filename);
// Do NOT mess with prefix (strupr()/strlwr()). See below (remove_mgd_id()).
sprintf (name, "%s%s%s", prefix, size_str, fname);
if (size >= 10 * MBIT)
{
if (!strnicmp (name, fname, 4))
strcpy (name, fname);
}
else
{
if (!strnicmp (name, fname, 3))
strcpy (name, fname);
}
if ((p = strchr (name, '.')))
*p = 0;
n = strlen (name);
if (size >= 10 * MBIT)
{
if (n < 7)
strcat (name, "XXX"); // in case fname is 1 character long
n = 7;
}
else
{
if (n < 6)
strcat (name, "XX");
n = 6;
}
name[n] = '0'; // last character must be a number
name[n + 1] = 0;
for (n = 3; n < 8; n++) // we can skip the prefix
if (name[n] == ' ')
name[n] = 'X';
/*
the transfer program "pclink" contains a bug in that it looks at the
entire file name for an ID string (it should look only at the first 2
characters).
*/
strupr (name);
remove_mgd_id (name + 3, "SF");
remove_mgd_id (name + 3, "MD");
remove_mgd_id (name + 3, "PC");
remove_mgd_id (name + 3, "GG");
remove_mgd_id (name + 3, "GB");
set_suffix (name, suffix);
}
void
mgd_write_index_file (void *ptr, int n_names)
{
char buf[100 * 10], *p, name[16], dest_name[FILENAME_MAX];
// one line in the index file takes 10 bytes at max (name (8) + "\r\n" (2)),
// so buf is large enough for 44 files of 1/4 Mbit (max for 1 diskette)
if (n_names == 1)
{
strcpy (name, (char *) ptr);
if ((p = strrchr (name, '.')))
*p = 0;
sprintf (buf, "%s\r\n", name); // DOS text file format
}
else if (n_names > 1)
{
int n = 0, offset = 0;
for (; n < n_names; n++)
{
strcpy (name, ((char **) ptr)[n]);
if ((p = strrchr (name, '.')))
*p = 0;
sprintf (buf + offset, "%s\r\n", name);
offset += strlen (name) + 2; // + 2 for "\r\n"
}
}
else // n_names <= 0
return;
strcpy (dest_name, "MULTI-GD");
ucon64_file_handler (dest_name, NULL, OF_FORCE_BASENAME);
ucon64_fwrite (buf, 0, strlen (buf), dest_name, "wb");
printf (ucon64_msg[WROTE], dest_name);
}

View File

@ -0,0 +1,185 @@
/*
mgd.h - Multi Game Doctor/Hunter support for uCON64
Copyright (c) 1999 - 2001 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.
*/
#ifndef MGD_H
#define MGD_H
extern const st_getopt2_t mgd_usage[];
/*
The MGD2 only accepts certain filenames, and these filenames
must be specified in an index file, "MULTI-GD", otherwise the
MGD2 will not recognize the file. In the case of multiple games
being stored in a single disk, simply enter its corresponding
MULTI-GD index into the "MULTI-GD" file.
Thanks to acem77 for the (verified) list below.
Super Famicom:
game size # of files names MULTI-GD
================================================================
1M 1 SF1XXX#.048 SF1XXX#
2M 1 SF2XXX#.048 SF2XXX#
4M 1 SF4XXX#.048 SF4XXX#
4M 2 SF4XXXxA.078 SF4XXXxA
SF4XXXxB.078 SF4XXXxB
8M 1 SF8XXX#.058 SF8XXX#
2 SF8XXXxA.078 SF8XXXxA
SF8XXXxB.078 SF8XXXxB
10M 1 SF10XXX#.078 SF10XXX#
2 SF10XXX#.078 SF10XXX#
SF10XXX#.078 SF10XXX#
12M 1 SF12XXX#.078 SF12XXX#
2 SF12XXX#A.078 SF12XXX#B
SF12XXX#B.078 SF12XXX#A
16M 1 SF16XXX#.078 SF16XXX#
16M 2 SF16XXX#A.078 SF16XXX#A
SF16XXX#B.078 SF16XXX#B
20M 1 SF20XXX#.078 SF20XXX#
3 SF20XXX#A.078 SF20XXX#A
SF20XXX#B.078 SF20XXX#B
SF20XXX#C.078 SF20XXX#C
24M 1 SF24XXX#.078 SF24XXX#
24M 3 SF24XXX#A.078 SF24XXX#A
SF24XXX#B.078 SF24XXX#B
SF24XXX#C.078 SF24XXX#C
32M 1 SF32XXX#.078 SF32XXX#
32M 4 SF32XXX#A.078 SF32XXX#A
SF32XXX#B.078 SF32XXX#B
SF32XXX#C.078 SF32XXX#C
SF32XXX#D.078 SF32XXX#D
Mega Drive:
game size # of files names MULTI-GD
================================================================
1M 1 MD1XXX#.000 MD1XXX#
2M 1 MD2XXX#.000 MD2XXX#
4M 1 MD4XXX#.000 MD4XXX#
8M 1 MD8XXX#.008 MD8XXX#
16M 2 MD16XXX#A.018 MD16XXX#A
MD16XXX#B.018 MD16XXX#B
20M 3 MD20XXX#A.038 MD20XXX#A
MD20XXX#B.038 MD20XXX#B
MD20XXX#C.038 MD20XXX#C
24M 3 MD24XXX#A.038 MD24XXX#A
MD24XXX#B.038 MD24XXX#B
MD24XXX#C.038 MD24XXX#C
32M 4 MD32XXX#A.038 MD32XXX#A
MD32XXX#B.038 MD32XXX#B
MD32XXX#C.038 MD32XXX#C
MD32XXX#D.038 MD32XXX#D
PC-Engine:
game size # of files names MULTI-GD
================================================================
1M 1 PC1XXX#.040 PC1XXX#
2M 1 PC2XXX#.040 PC2XXX#
3M 1 PC3XXX#.030 PC2XXX#
4M 1 PC4XXX#.048 PC4XXX#
6M 1 PC6XXX#.058 PC6XXX#
8M 1 PC8XXX#.058 PC8XXX#
Sega Master System:
game size # of files names MULTI-GD
================================================================
less than 1M 1 GG0XXX#.060 GG0XXX#
1M 1 GG1XXX#.060 GG1XXX#
2M 1 GG2XXX#.060/70 GG2XXX#
3M 1 GG3XXX#.078 GG2XXX#
4M 1 GG4XXX#.078/68 GG4XXX#
6M 1 GG6XXX#.078 GG6XXX#
8M 1 GG8XXX#.078 GG8XXX#
Game Gear:
game size # of files names MULTI-GD
================================================================
less than 1M 1 GG0XXX#.040 GG0XXX#
1M 1 GG1XXX#.040 GG1XXX#
2M 1 GG2XXX#.050/40 GG2XXX#
3M 1 GG3XXX#.048 GG2XXX#
4M 1 GG4XXX#.058/48 GG4XXX#
6M 1 GG6XXX#.078 GG6XXX#
8M 1 GG8XXX#.078 GG8XXX#
Game Boy:
game size # of files names MULTI-GD
================================================================
less than 1M 1 GB0XXX#.040 GB0XXX#
1M 1 GB1XXX#.040 GB1XXX#
2M 1 GB2XXX#.040/60 GB2XXX#
3M 1 GB3XXX#.030 GB2XXX#
4M 1 GB4XXX#.048 GB4XXX#
6M 1 GB6XXX#.058 GB6XXX#
8M 1 GB8XXX#.058 GB8XXX#
Contrary to popular belief the Game Doctor SF3/SF6/SF7 *does*
use a 512 byte header like the SWC, but it also accepts
headerless files.
A header is necessary when things like SRAM size must be made
known to the Game Doctor. The Game Doctor also uses specially
designed filenames to distinguish between multi files.
Usually, the filename is in the format of: SFXXYYYZ.078
Where SF means Super Famicom, XX refers to the size of the
image in Mbit. If the size is only one character (i.e. 2, 4 or
8 Mbit) then no leading "0" is inserted.
YYY refers to a catalogue number in Hong Kong shops
identifying the game title. (0 is Super Mario World, 1 is F-
Zero, etc). I was told that the Game Doctor copier produces a
random number when backing up games.
Z indicates a multi file. Like XX, if it isn't used it's
ignored.
A would indicate the first file, B the second, etc. I am told
078 is not needed, but is placed on the end of the filename by
systems in Asia.
e.g. The first 8 Mbit file of Donkey Kong Country (assuming it
is cat. no. 475) would look like: SF32475A.078
*/
#ifdef USE_PARALLEL
#endif // USE_PARALLEL
// the following four functions are used by non-transfer code in genesis.c
extern void mgd_interleave (unsigned char **buffer, int size);
extern void mgd_deinterleave (unsigned char **buffer, int data_size,
int buffer_size);
extern int fread_mgd (void *buffer, size_t size, size_t number, FILE *fh);
extern int q_fread_mgd (void *buffer, size_t start, size_t len,
const char *filename);
extern void mgd_make_name (const char *filename, int console, int size,
char *name);
extern void mgd_write_index_file (void *ptr, int n_names);
#define MGD_HEADER_START 0
#define MGD_HEADER_LEN 512
#endif // MGD_H

View File

@ -0,0 +1,250 @@
/*
msg.c - Magic Super Griffin support for uCON64
Copyright (c) 2003 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 <time.h>
#include <string.h>
#include "misc/itypes.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "misc/file.h"
#include "misc/misc.h"
#include "ucon64.h"
#include "ucon64_misc.h"
#include "ffe.h"
#include "msg.h"
const st_getopt2_t msg_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "Magic Super Griffin/MSG"/*"1993/1994/1995/19XX Front Far East/FFE http://www.front.com.tw"*/,
NULL
},
#ifdef USE_PARALLEL
{
"xmsg", 0, 0, UCON64_XMSG,
NULL, "send/receive ROM to/from Magic Super Griffin/MSG; " OPTION_LONG_S "port=PORT\n"
"receives automatically when ROM does not exist",
&ucon64_wf[WF_OBJ_PCE_DEFAULT_STOP_NO_SPLIT_NO_ROM]
},
#endif
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
#ifdef USE_PARALLEL
#define BUFFERSIZE 8192 // don't change, only 8192 works!
static void set_header (unsigned char *buffer);
static int check (unsigned char *info_block, int index1, int index2, int size);
#if BUFFERSIZE < 512
#error receive_rom_info() expects BUFFERSIZE to be at least 512 bytes.
#endif
void
set_header (unsigned char *buffer)
{
int n, m = 0;
unsigned char sizes[] = "\x10\x20\x30\x30\x40\x40\x60\x80";
for (n = 0; n < 128; n++)
{
ffe_send_command (5, (unsigned short) n, 0);
buffer[n] = ffe_send_command1 (0xa0a0);
wait2 (1);
if (buffer[n] != 0xff)
m = 1;
}
if (m == 0)
{ // no cartridge in Magic Super Griffin
buffer[0] = 0;
return;
}
m = 0;
if (!check (buffer, 0, 0x40, 0x20))
m |= 2;
if (check (buffer, 0, 0x20, 0x20))
{
if (!check (buffer, 0, 0x10, 0x10))
m |= 1;
}
else
{
m |= 4;
if (!check (buffer, 0x40, 0x60, 0x20))
m |= 1;
}
memset (buffer, 0, MSG_HEADER_LEN);
buffer[0] = sizes[m];
if (buffer[0] == 0x30)
buffer[1] = 1;
buffer[8] = 0xaa;
buffer[9] = 0xbb;
buffer[10] = 2;
}
int
check (unsigned char *info_block, int index1, int index2, int size)
{
int n;
for (n = 0; n < size; n++)
if (info_block[n + index1] != info_block[n + index2])
return 0;
return 1;
}
int
msg_read_rom (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char *buffer;
int size, blocksleft, blocksdone = 0, bytesreceived = 0, emu_mode_select;
time_t starttime;
ffe_init_io (parport);
if ((file = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
{
fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
exit (1);
}
set_header (buffer);
if (buffer[0] == 0)
{
fprintf (stderr, "ERROR: There is no cartridge present in the Magic Super Griffin\n");
fclose (file);
remove (filename);
exit (1);
}
blocksleft = buffer[0];
size = buffer[0] * 8192;
printf ("Receive: %d Bytes (%.4f Mb)\n", size, (float) size / MBIT);
fwrite (buffer, 1, MSG_HEADER_LEN, file); // write header
emu_mode_select = buffer[1];
ffe_send_command (5, 0, 0);
ffe_send_command0 (0xbff0, 0);
printf ("Press q to abort\n\n");
starttime = time (NULL);
while (blocksleft > 0)
{
ffe_send_command (5, (unsigned short) blocksdone, 0);
if (emu_mode_select && blocksdone >= 32)
ffe_send_command (5, (unsigned short) (blocksdone + 32), 0);
ffe_receive_block (0xa000, buffer, BUFFERSIZE);
// vgs aborts if the checksum doesn't match the data, we let the user decide
blocksleft--;
blocksdone++;
fwrite (buffer, 1, BUFFERSIZE, file);
bytesreceived += BUFFERSIZE;
ucon64_gauge (starttime, bytesreceived, size);
ffe_checkabort (2);
}
free (buffer);
fclose (file);
ffe_deinit_io ();
return 0;
}
int
msg_write_rom (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char *buffer;
int bytesread, bytessend = 0, blocksdone = 0, emu_mode_select, size;
time_t starttime;
ffe_init_io (parport);
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
{
fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
exit (1);
}
size = fsizeof (filename) - MSG_HEADER_LEN;
printf ("Send: %d Bytes (%.4f Mb)\n", size, (float) size / MBIT);
fread (buffer, 1, MSG_HEADER_LEN, file);
emu_mode_select = buffer[1]; // this byte is needed later
ffe_send_command0 (0xe008, 0);
printf ("Press q to abort\n\n");
starttime = time (NULL);
while ((bytesread = fread (buffer, 1, BUFFERSIZE, file)))
{
ffe_send_command (5, (unsigned short) blocksdone, 0);
ffe_send_block (0x8000, buffer, bytesread);
blocksdone++;
bytessend += bytesread;
ucon64_gauge (starttime, bytessend, size);
ffe_checkabort (2);
}
if (emu_mode_select & 1)
ffe_send_command (4, 0xff00, 0);
else
ffe_send_command (4, 0xff03, 0);
free (buffer);
fclose (file);
ffe_deinit_io ();
return 0;
}
#endif // USE_PARALLEL

View File

@ -0,0 +1,46 @@
/*
msg.h - Magic Super Griffin support for uCON64
Copyright (c) 2003 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.
*/
#ifndef MSG_H
#define MSG_H
extern const st_getopt2_t msg_usage[];
// For the header format, see ffe.h
typedef struct st_msg_header
{
unsigned char size;
unsigned char emulation;
unsigned char pad[6];
unsigned char id1;
unsigned char id2;
unsigned char type;
unsigned char pad2[501];
} st_msg_header_t;
#define MSG_HEADER_START 0
#define MSG_HEADER_LEN (sizeof (st_msg_header_t))
#ifdef USE_PARALLEL
extern int msg_read_rom (const char *filename, unsigned int parport);
extern int msg_write_rom (const char *filename, unsigned int parport);
#endif
#endif // MSG_H

View File

@ -0,0 +1,204 @@
/*
pce-pro.c - PCE-PRO flash card programmer support for uCON64
Copyright (c) 2004 dbjh
Based on Delphi source code by ToToTEK Multi Media. Information in that source
code has been used with permission. However, ToToTEK Multi Media explicitly
stated that the information in that source code may be freely distributed.
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 <time.h>
#include "misc/parallel.h"
#include "misc/itypes.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "misc/file.h"
#include "misc/misc.h"
#include "ucon64.h"
#include "ucon64_misc.h"
#include "tototek.h"
#include "pce-pro.h"
const st_getopt2_t pcepro_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "PCE-PRO flash card programmer"/*"2004 ToToTEK Multi Media http://www.tototek.com"*/,
NULL
},
#ifdef USE_PARALLEL
{
"xpce", 0, 0, UCON64_XPCE,
NULL, "send/receive ROM to/from PCE-PRO flash card programmer\n" OPTION_LONG_S "port=PORT\n"
"receives automatically (32 Mbits) when ROM does not exist",
&ucon64_wf[WF_OBJ_PCE_DEFAULT_STOP_NO_SPLIT_NO_ROM]
},
#endif
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
#ifdef USE_PARALLEL
static void eep_reset (void);
static void write_rom_by_byte (int *addr, unsigned char *buf);
static void write_rom_by_page (int *addr, unsigned char *buf);
void
eep_reset (void)
{
ttt_rom_enable ();
ttt_write_mem (0x000000, 0xff); // reset EEP
ttt_write_mem (0x200000, 0xff); // reset EEP
ttt_rom_disable ();
}
void
write_rom_by_byte (int *addr, unsigned char *buf)
{
int x;
for (x = 0; x < 0x4000; x++)
{
ttt_write_byte_sharp (*addr, buf[*addr & 0x3fff]);
(*addr)++;
}
}
void
write_rom_by_page (int *addr, unsigned char *buf)
{
int x;
for (x = 0; x < 0x200; x++)
{
ttt_write_page_rom (*addr, buf);
(*addr) += 0x20;
}
}
int
pce_read_rom (const char *filename, unsigned int parport, int size)
{
FILE *file;
unsigned char buffer[0x100];
int blocksleft, address = 0;
time_t starttime;
void (*read_block) (int, unsigned char *) = ttt_read_rom_w; // ttt_read_rom_b
if ((file = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
ttt_init_io (parport);
printf ("Receive: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
blocksleft = size >> 8;
eep_reset ();
ttt_rom_enable ();
if (read_block == ttt_read_rom_w)
ttt_set_ai_data (6, 0x94); // rst=1, wei=0(dis.), rdi=0(dis.), inc mode, rom_CS
starttime = time (NULL);
while (blocksleft-- > 0)
{
read_block (address, buffer); // 0x100 bytes read
fwrite (buffer, 1, 0x100, file);
address += 0x100;
if ((address & 0x3fff) == 0)
ucon64_gauge (starttime, address, size);
}
// original code doesn't call ttt_rom_disable() when byte-size function is
// used (ttt_read_rom_b() calls it)
if (read_block == ttt_read_rom_w)
ttt_rom_disable ();
fclose (file);
ttt_deinit_io ();
return 0;
}
int
pce_write_rom (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char buffer[0x4000];
int size, fsize, address = 0, bytesread, bytessend = 0;
time_t starttime;
void (*write_block) (int *, unsigned char *) = write_rom_by_page; // write_rom_by_byte
(void) write_rom_by_byte;
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
ttt_init_io (parport);
size = fsize = fsizeof (filename);
if (fsize == 4 * MBIT)
size += 2 * MBIT;
printf ("Send: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
eep_reset ();
if (ttt_get_id () != 0xb0d0)
{
fputs ("ERROR: PCE-PRO flash card (programmer) not detected\n", stderr);
fclose (file);
ttt_deinit_io ();
exit (1);
}
starttime = time (NULL);
eep_reset ();
while ((bytesread = fread (buffer, 1, 0x4000, file)))
{
if ((address & 0xffff) == 0)
ttt_erase_block (address);
write_block (&address, buffer);
if ((fsize == 3 * MBIT) && (address == 2 * MBIT))
address += 2 * MBIT;
if ((fsize == 4 * MBIT) && (address == 4 * MBIT))
fseek (file, 2 * MBIT, SEEK_SET);
bytessend += bytesread;
ucon64_gauge (starttime, bytessend, size);
}
fclose (file);
ttt_deinit_io ();
return 0;
}
#endif // USE_PARALLEL

View File

@ -0,0 +1,35 @@
/*
pce-pro.h - PCE-PRO flash card programmer support for uCON64
Copyright (c) 2004 dbjh
Based on Delphi source code by ToToTEK Multi Media. Information in that source
code has been used with permission. However, ToToTEK Multi Media explicitly
stated that the information in that source code may be freely distributed.
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.
*/
#ifndef PCE_PRO_H
#define PCE_PRO_H
extern const st_getopt2_t pcepro_usage[];
#ifdef USE_PARALLEL
extern int pce_read_rom (const char *filename, unsigned int parport, int size);
extern int pce_write_rom (const char *filename, unsigned int parport);
#endif
#endif

View File

@ -0,0 +1,782 @@
/*
pl.c - Pocket Linker support for uCON64
Copyright (c) 2004 Walter van Niftrik <w.f.b.w.v.niftrik@stud.tue.nl>
Partly based on PokeLink - Copyright (c) Dark Fader / BlackThunder
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 <time.h>
#include "misc/itypes.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "misc/misc.h"
#include "misc/parallel.h"
#include "misc/file.h"
#include "ucon64.h"
#include "ucon64_misc.h"
#include "pl.h"
const st_getopt2_t pl_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "Pocket Linker"/*"19XX Bung Enterprises Ltd"*/,
NULL
},
#ifdef USE_PARALLEL
{
"xpl", 0, 0, UCON64_XPL,
NULL, "send/receive ROM to/from Pocket Linker; " OPTION_LONG_S "port=PORT\n"
"receives automatically when ROM does not exist",
&ucon64_wf[WF_OBJ_NGP_DEFAULT_STOP_NO_ROM]
},
{
"xpli", 0, 0, UCON64_XPLI,
NULL, "show information about inserted cartridge; " OPTION_LONG_S "port=PORT",
&ucon64_wf[WF_OBJ_NGP_STOP_NO_ROM]
},
{
"xplm", 0, 0, UCON64_XPLM,
NULL, "try to enable EPP mode, default is SPP mode",
&ucon64_wf[WF_OBJ_NGP_SWITCH]
},
#endif // USE_PARALLEL
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
#ifdef USE_PARALLEL
// flash unlock addresses with chip select
#define fx0002aa(A) (((A) & 0x200000) | 0x0002aa)
#define fx000555(A) (((A) & 0x200000) | 0x000555)
#define fx000aaa(A) (((A) & 0x200000) | 0x000aaa)
#define fx002aaa(A) (((A) & 0x200000) | 0x002aaa)
#define fx005555(A) (((A) & 0x200000) | 0x005555)
#define set_data_read outportb (port_a, 0);
#define set_data_write outportb (port_a, 1);
#define reset_port outportb (port_a, 4);
#define clear_timeout outportb (port_9, 1);
#define CMD_READ 0xf0
#define CMD_INFO 0x90
#define CMD_ERASE 0x80
#define TYPE_BW 0x00
#define TYPE_COLOR 0x01
#define TYPE_MULTI 0x02
static short int port_8, port_9, port_a, port_b, port_c;
static parport_mode_t port_mode;
static int current_ai;
static unsigned char ai_value[4];
static void
epp_write_data (unsigned char data)
{
outportb (port_c, data);
}
static void
spp_write_data (unsigned char data)
{
outportb (port_8, data);
outportb (port_a, 3);
outportb (port_a, 1);
}
static void
write_data (unsigned char data)
{
ai_value[current_ai] = data;
if (port_mode == UCON64_SPP)
spp_write_data (data);
else
epp_write_data (data);
}
static unsigned char
epp_read_data (void)
{
return inportb (port_c);
}
static unsigned char
spp_read_data (void)
{
unsigned char byte;
outportb (port_a, 2);
byte = (inportb (port_9) >> 3) & 0x0f;
outportb (port_a, 6);
byte |= (inportb (port_9) << 1) & 0xf0;
outportb (port_a, 0);
return byte;
}
static unsigned char
read_data (void)
{
if (port_mode == UCON64_SPP)
return spp_read_data ();
else
return epp_read_data ();
}
static void
epp_set_ai (unsigned char ai)
{
current_ai = ai;
outportb (port_b, ai);
}
static void
spp_set_ai (unsigned char ai)
{
current_ai = ai;
outportb (port_8, ai);
outportb (port_a, 9);
outportb (port_a, 1);
}
static void
set_ai (unsigned char ai)
{
if (port_mode == UCON64_SPP)
spp_set_ai (ai);
else
epp_set_ai (ai);
}
static void
epp_set_ai_data (unsigned char ai, unsigned char data)
{
epp_set_ai (ai);
epp_write_data (data);
}
static void
spp_set_ai_data (unsigned char ai, unsigned char data)
{
spp_set_ai (ai);
spp_write_data (data);
}
static void
set_ai_data (unsigned char ai, unsigned char data)
{
if (port_mode == UCON64_SPP)
spp_set_ai_data (ai, data);
else
epp_set_ai_data (ai, data);
}
static void
init_port (void)
{
#ifndef USE_PPDEV
clear_timeout
#endif
set_data_write
set_ai_data (2, 0);
}
static void
end_port (void)
{
set_data_write
set_ai_data (2, 0);
reset_port
}
static int
detect_linker (void)
{
init_port ();
set_data_write
set_ai_data (1, 0x12);
set_ai_data (0, 0x34);
set_ai (1);
set_data_read
if (read_data () != 0x12)
return 0;
set_data_write
set_ai (0);
set_data_read
if (read_data () != 0x34)
return 0;
end_port ();
return 1;
}
static void
select_address (unsigned int addr, int inc)
{
unsigned char data = (((addr >> 14) & 0x3c) | ((addr >> 13) & 0x80) |
(inc ? 0x01 : 0x00)); // a[20..16], auto-increment
if (data != ai_value[2])
set_ai_data (2, data);
set_ai_data (1, (unsigned char) ((addr >> 8) & 0xff)); // a[15..8]
set_ai_data (0, (unsigned char) (addr & 0xff)); // a[7..0]
}
static void
write_address_data (unsigned int addr, unsigned char data)
{
select_address (addr, 0);
set_ai_data (3, data);
}
static void
send_command (unsigned char cmd)
{
set_data_write
write_address_data (0x5555, 0xaa);
write_address_data (0x2aaa, 0x55);
write_address_data (0x5555, cmd);
}
static void
reset_read (void)
{
send_command (CMD_READ);
}
static unsigned char
read_ai3_data (void)
{
set_ai (3);
set_data_read
return read_data ();
}
static int
detect_chip (void)
{
int ai;
unsigned char info[4];
reset_read ();
reset_read ();
reset_read ();
send_command (CMD_INFO);
for (ai = 0; ai < 4; ai++)
{
set_data_write
select_address (ai, 0);
info[ai] = read_ai3_data ();
}
reset_read ();
if (((info[0] & 0x90) == 0x90) && (info[2] == 0x01) && (info[3] & 0x80))
return 1;
else
return 0;
}
static void
select_chip (unsigned int addr)
{
set_data_write
set_ai_data (2, 2);
set_ai_data (3, (unsigned char) ((addr & 0x200000) ? 1 : 2));
set_ai_data (2, 0);
}
static unsigned int
cart_size (void)
{
select_chip (0x000000);
if (!detect_chip ())
return 0; // no cartridge found
select_chip (0x200000);
if (!detect_chip ())
return 0x200000; // 16 megabit
return 0x400000; // 32 megabit
}
static void
read_blocks (unsigned int addr, unsigned char *buf, int blocks)
{
int block, i, offset = 0;
select_chip (addr);
for (block = 0; block < blocks; block++)
{
set_data_write
select_address (addr | (block << 8), 1);
set_ai (3);
set_data_read
for (i = 0; i < 0x100; i++)
buf[offset++] = read_data ();
}
}
static int
is_erased (unsigned char *buf, unsigned int len)
{
unsigned int i;
for (i = 0; i < len; i++)
if (buf[i] != 0xff)
return 0;
return 1;
}
static int
is_header (unsigned char *buf)
{
char msg[0x1d];
strncpy (msg, (char *) buf, 0x1c);
msg[0x1c] = '\0';
if (strstr (msg, "COPYRIGHT") || strstr (msg, "SNK") ||
strstr (msg, "LICENSED") || strstr (msg, "CORPORATION"))
return 1; // header found
return 0; // other data found
}
static int
same_header (unsigned char *header, unsigned char *buf)
{
return (!memcmp (header, buf, 0x100));
}
static unsigned int
game_info (unsigned int cart_size, char name[13], int *type)
{
unsigned char header[0x100];
unsigned char buf[0x8000];
select_chip (0x000000);
read_blocks (0x000000, header, 1);
if (!is_header (header))
return 0; // no game found
if (name)
{
strncpy (name, (char *) (header + 0x24), 12);
name[12] = '\0';
}
if (type)
{
if (strstr (name, "Multi"))
*type = TYPE_MULTI;
else if (header[0x23] == 0x10)
*type = TYPE_COLOR;
else
*type = TYPE_BW;
}
read_blocks (0x080000, buf, 128);
if ((same_header (buf, header)) || is_erased (buf, 0x8000))
return 0x080000; // 4 megabit
read_blocks (0x100000, buf, 128);
if ((same_header (buf, header)) || is_erased (buf, 0x8000))
return 0x100000; // 8 megabit
if (cart_size == 0x400000)
{
read_blocks (0x200000, buf, 128);
if (is_erased (buf, 0x8000))
return 0x200000; // 16 megabit
return 0x400000; // 32 megabit
}
return 0x200000; // 16 megabit
}
static void
deinit_io (void)
{
end_port ();
}
static void
init_io (unsigned int port)
{
#ifndef USE_PPDEV
outportb ((unsigned short) (port_8 + 0x402), 0); // Set EPP mode for ECP chipsets
#endif
port_8 = port;
port_9 = port + 1;
port_a = port + 2;
port_b = port + 3;
port_c = port + 4;
parport_print_info ();
if (ucon64.parport_mode == UCON64_EPP && port_8 != 0x3bc)
port_mode = UCON64_EPP; // if port == 0x3bc => no EPP available
else
port_mode = UCON64_SPP;
if (!detect_linker ())
{
port_mode = UCON64_SPP;
if (!detect_linker ())
{
fputs ("ERROR: Pocket Linker not found or not turned on\n", stderr);
deinit_io ();
exit (1);
}
}
// If we get here, a Pocket Linker was detected
if (port_mode == UCON64_EPP)
puts ("Pocket Linker found. EPP found");
else
puts ("Pocket Linker found. EPP not found or not enabled - SPP used");
}
static void
set_address (unsigned int addr, int inc)
{
set_ai_data (0, (unsigned char) (addr & 0xff)); // a[7..0]
set_ai_data (1, (unsigned char) ((addr >> 8) & 0xff)); // a[15..8]
set_ai_data (2, 0x02); // latch chip select
set_ai_data (3, (unsigned char) ~(1 << (addr >> 21))); // a[23..21]
set_ai_data (2, (unsigned char) ((((addr >> 16) & 0x0f) << 2) | // a[20..16], auto-increment
(((addr >> 20) & 0x01) << 7) |
(inc ? 0x01 : 0x00)));
set_ai (3);
}
static int
program (unsigned int addr, unsigned char data, int retries)
{
int to = 10000;
set_data_write
set_address (fx005555 (addr), 0); // program byte
write_data (0xaa);
set_address (fx002aaa (addr), 0);
write_data (0x55);
set_address (fx005555 (addr), 0);
write_data (0xa0);
set_address (addr, 0);
write_data (data);
set_data_read
while (to--)
{
unsigned char s = read_data ();
if ((s & 128) == 0)
return 0; // ok
if (s & 32)
{
int s = read_data ();
if ((s & 128) == 0)
return 0; // ok
if (data == read_data ())
return 0; // ok
}
}
set_data_write
set_address (addr, 0);
set_data_read
if (data == read_data ())
return 0; // ok
if (retries == 0)
return 1; // error
return program (addr, data, retries - 1);
}
static int
write_block (unsigned int addr, unsigned char *buf)
{
int count;
select_address (addr, 1);
for (count = 0; count < 0x100; count++)
{
if (buf[count] == 0xff)
continue; // nothing to write
if (program (addr + count, buf[count], 3))
{
select_address (addr + count, 0);
set_data_read
fprintf (stderr, "\nERROR: Programming failed at 0x%06x (w:0x%02x, "
"r:0x%02x)\n", addr + count, buf[count], read_data ());
return 1;
}
}
return 0;
}
#if 0
static int
wait_erased (void)
{
int i = 0;
unsigned char cur_byte, prev_byte;
prev_byte = read_ai3_data () & 0x40;
while (++i < 0x7ffffff)
{
cur_byte = read_data () & 0x40;
if (cur_byte == prev_byte)
return 0; // ok
prev_byte = cur_byte;
}
return 1; // erase error
}
static int
erase_chip (void)
{
reset_read ();
send_command (CMD_ERASE);
write_address_data (0x5555, 0xaa);
write_address_data (0x2aaa, 0x55);
write_address_data (0x5555, 0x10);
return wait_erased ();
}
static int
erase_cart (unsigned int size)
{
unsigned int addr;
unsigned char buf[0x8000];
for (addr = 0x000000; addr < size; addr += 0x200000)
{
select_chip (addr);
if (erase_chip ())
{
fprintf (stderr, "ERROR: Erase chip %d failed\n", addr >> 21);
return 1;
}
read_blocks (0x000000, buf, 128);
if (!is_erased (buf, 0x8000))
{
fprintf (stderr, "ERROR: Erase chip %d verify failed\n", addr >> 21);
return 1;
}
}
}
#endif
static int
erase (void)
{
unsigned int addr;
for (addr = 0; addr < 0x400000; addr += 0x200000)
{
set_data_write
set_address (fx005555 (addr), 0);
write_data (0xaa);
set_address (fx002aaa (addr), 0);
write_data (0x55);
set_address (fx005555 (addr), 0);
write_data (0x80);
set_address (fx005555 (addr), 0);
write_data (0xaa);
set_address (fx002aaa (addr), 0);
write_data (0x55);
set_address (fx005555 (addr), 0);
write_data (0x10);
set_data_read
while (~read_data () & 0x80) // wait for completion
;
}
return 0;
}
int
pl_read_rom (const char *filename, unsigned int parport)
{
FILE *file;
unsigned int blocksleft, c_size, size, address = 0;
unsigned char buffer[0x8000];
time_t starttime;
if ((file = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
init_io (parport);
c_size = cart_size ();
if (c_size == 0x00) // Check for cartridge
{
fputs ("ERROR: No cartridge detected\n", stderr);
deinit_io ();
exit (1);
}
size = game_info (c_size, NULL, NULL);
if (size == 0x00)
{
fputs ("ERROR: No game detected\n", stderr);
deinit_io ();
exit (1);
}
reset_read ();
printf ("Receive: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
blocksleft = size >> 15;
starttime = time (NULL);
while (blocksleft-- > 0)
{
read_blocks (address, buffer, 128);
fwrite (buffer, 1, 0x8000, file);
address += 0x8000;
ucon64_gauge (starttime, address, size);
}
fclose (file);
deinit_io ();
return 0;
}
int
pl_write_rom (const char *filename, unsigned int parport)
{
FILE *file;
unsigned int size, bytesread, bytessent = 0, address = 0;
unsigned char buffer[0x100];
time_t starttime;
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
init_io (parport);
size = fsizeof (filename);
erase ();
reset_read ();
printf ("Send: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
starttime = time (NULL);
while ((bytesread = fread (buffer, 1, 0x100, file)))
{
if (write_block (address, buffer))
break; // write failed
bytessent += bytesread;
address += 0x100;
ucon64_gauge (starttime, bytessent, size);
}
fclose (file);
deinit_io ();
return 0;
}
int
pl_info (unsigned int parport)
{
unsigned int c_size, g_size;
int g_type;
char g_name[13];
init_io (parport);
c_size = cart_size ();
if (c_size == 0)
{
printf ("No cartridge found\n");
deinit_io ();
return 0;
}
g_size = game_info (c_size, g_name, &g_type);
if (g_size == 0)
printf ("No game found\n");
else
{
printf ("Game name: \"%s\"\n", g_name);
printf ("Game type: %s\n", (g_type == TYPE_COLOR) ? "Color" : "B&W");
printf ("Game size: %d Bytes (%.4f Mb)\n", g_size, (float) g_size / MBIT);
}
deinit_io ();
return 0;
}
#endif // USE_PARALLEL

View File

@ -0,0 +1,33 @@
/*
pl.h - Pocket Linker support for uCON64
Copyright (c) 2004 Walter van Niftrik <w.f.b.w.v.niftrik@stud.tue.nl>
Partly based on PokeLink - Copyright (c) Dark Fader / BlackThunder
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.
*/
#ifndef PL_H
#define PL_H
extern const st_getopt2_t pl_usage[];
#ifdef USE_PARALLEL
extern int pl_info (unsigned int parport);
extern int pl_read_rom (const char *filename, unsigned int parport);
extern int pl_write_rom (const char *filename, unsigned int parport);
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,208 @@
/*
*
* PSX Peripheral Bus Library v1.4 17/01/00 Richard Davies
* <http://www.debaser.force9.co.uk/>
* <mailto:richard@debaser.force9.co.uk>
*
* Revision History:
* v1.4 - 17/01/00 Win32 / Win32 DLL support and bug fixes
* v1.3 - 21/12/99 Linux support and bug fixes
* v1.1 - 26/09/99 Minor Controller detection improvements.
* v1.0 - 17/07/99 Initial release (based on PSXTest v1.1 by me).
*
* see psxpblib.txt for details.
*
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef USE_PARALLEL
// outportb() and inportb() are only present in uCON64 if USE_PARALLEL is defined
#define psx_outportb(P, B) outportb((unsigned short) (P), (unsigned char) (B))
#define psx_inportb(P) inportb((unsigned short) (P))
#ifdef __MSDOS__
#include <stdlib.h>
#include <pc.h>
#endif
#define LPT1_BASE 0x378
#define LPT2_BASE 0x278
#define LPT3_BASE 0x3bc
#define LPT_D0 0x01 /* pin 2 */
#define LPT_D1 0x02 /* pin 3 */
#define LPT_D2 0x04 /* pin 4 */
#define LPT_D3 0x08 /* pin 5 */
#define LPT_D4 0x10 /* pin 6 */
#define LPT_D5 0x20 /* pin 7 */
#define LPT_D6 0x40 /* pin 8 */
#define LPT_D7 0x80 /* pin 9 */
#define LPT_AUT 0x08 /* pin 14 */
#define LPT_SEL 0x10 /* pin 13 */
#define LPT_PAP 0x20 /* pin 12 */
#define LPT_ACK 0x40 /* pin 10 */
#define LPT_ERR 0x02 /* pin 15 */
#define LPT_INI 0x04 /* pin 16 */
#define LPT_STR 0x08 /* pin 1 */
#define PSX_MAX_CONPORTS 8
#define PSX_MAX_TAPS 4
#define PSX_MAX_DELAY 10
#define PSX_MAX_DATA 30 /* maximum possible length of controller packet in bytes */
/* JAP code EUR code Name */
#define PSX_MOUSE 1 /* SCPH-1030 SCPH-???? Mouse */
#define PSX_NEGCON 2 /* SLPH-0001 SLEH-0003 Namco neGcon
SLPH-0007 Nasca Pachinco Handle (untested); Twist = Twist, TW = B
SLPH-0015 ? Volume Controller (untested); Rotation = Twist, A = Start, B = A
Puchi Carat paddle controller (not working!); Rotation = Twist, A = Start, B = A
SLPH-???? SLEH-0005 MadKatz Steering Wheel (twitchy) */
#define PSX_KONAMIGUN 3 /* SLPH-???? SLPH-???? Konami Lightgun (untested) */
#define PSX_DIGITAL 4 /* SCPH-1010 SCPH 1080 E Controller
SCPH-1110 SCPH-???? Analog Joystick - Digital Mode
SCPH-???? SCPH-1180 E Analog Controller - Digital Mode
SCPH-1150 SCPH-1200 E Dual Shock Analog Controller - Digital Mode
SLPH-???? SLEH-0011 Ascii Resident Evil Pad
SLPH-???? SLEH-0004 Namco Arcade Stick (untested)
Twin Stick
Blaze Pro-Shock Arcade Stick */
#define PSX_ANALOG_GREEN 5 /* SCPH-1110 SCPH-???? Analog Joystick - Analog Mode (untested)
SCPH-???? SCPH-1180 E Analog Controller - Analog Green Mode */
#define PSX_GUNCON 6 /* SLPH-???? SLEH-0007 Namco G-con45 */
#define PSX_ANALOG_RED 7 /* SCPH-1150 SCPH-1200 E Dual Shock Analog Controller - Analog Red Mode */
/* SCPH-???? SCPH-1180 E Analog Controller - Analog Red Mode */
#define PSX_JOGCON 14 /* SLPH-???? SLEH-0020 Namco Jogcon */
/*#define PSX_MULTITAP 17 SCPH-1070 SCPH-1070 E Multi tap */
#define PSX_MCB_STATE_OK 0x05
#define PSX_MCB_STATE_DELETED 0x0a
#define PSX_MCB_STATE_RESERVED 0x0f
#define PSX_MCB_LTYPE_NONE 0x00
#define PSX_MCB_LTYPE_FIRST 0x01
#define PSX_MCB_LTYPE_MIDDLE 0x02
#define PSX_MCB_LTYPE_LAST 0x03
#define PSX_MCB_LTYPE_RESERVED 0x0f
#define PSX_MCB_ICON_VALID 0x01
typedef struct
{
unsigned char type;
unsigned char length;
unsigned char data[PSX_MAX_DATA];
} PSX_CON_BUF;
typedef struct
{
unsigned char read;
char filename[9];
char code[11];
char territory; /* E, A or I */
int bytes;
unsigned char state; /* PSX_MCB_STAT_* or unknown */
unsigned char linktype; /* PSX_MCB_LTYPE_* or unknowm */
unsigned char next; /* 0 to 14 */
} PSX_MCB_INFO_DIR;
typedef struct
{
unsigned char read;
char name[92];
unsigned char blocks;
unsigned char icon_valid;
unsigned char icon_frames;
} PSX_MCB_INFO_DAT;
typedef struct
{
unsigned char scanned;
unsigned char read;
char name[92];
char filename[9];
char code[11];
char territory;
unsigned char state;
unsigned char blocks;
int bytes;
unsigned char linktype;
unsigned char next;
unsigned char icon_valid;
unsigned char icon_frames;
} PSX_MCB_INFO;
/* sets clock for conport connected to parallel port base */
void psx_clk (int base, int conport, int on);
/* sets att for conport connected to parallel port base */
void psx_att (int base, int conport, int on);
/* sets command for conport connected to parallel port base */
void psx_cmd (int base, int conport, int on);
/* tests data for conport connected to parallel port base, returns 1 if high */
int psx_dat (int base, int conport);
/* tests ack for conport connected to parallel port base, returns 1 if high */
int psx_ack (int base, int conport);
/* wait for delay * (outportb() execution time) */
void psx_delay (int base, int delay);
/* send byte as a command to conport connected to parallel port base
* assumes clock high and the attention of conport */
unsigned char psx_sendbyte (int base, int conport, int delay,
unsigned char byte, int wait);
/* get io permissions under linux*/
int psx_obtain_io_permission (int base);
/* sets clock high and gets the attention of conport, use before psx_sendbyte() */
void psx_sendinit (int base, int conport, int delay);
/* use after psx_sendbyte() */
void psx_sendclose (int base, int conport, int delay);
/* send string as a series of commands to conport connected to parallel port base */
void psx_sendstring (int base, int conport, int delay, int string[]);
/* tests for the presence of a controller on conport:tap connected to base
* returns the type if present, otherwise -1 */
int psx_controller_detect (int base, int conport, int tap, int delay);
/* reads a controller on conport:tap connected to base returns the data
* if present, otherwise -1 */
PSX_CON_BUF *psx_controller_read (int base, int conport, int tap, int delay);
/* sends force feedback/shock init command sequence to conport:tap on port base
* (also initialises crash protection for some controllers) */
void psx_controller_vinit (int base, int conport, int tap, int delay);
/* sends the dual shock command sequence to conport:tap on port base */
void psx_controller_vshock (int base, int conport, int tap, int delay,
int shock, int rumble);
/* Reads a single frame (128 bytes) from Memory Card on conport base:tap */
unsigned char *psx_memcard_read_frame (int base, int conport, int tap, int delay,
int frame);
/* Writes a single frame (128 bytes) to Memory Card on conport base:tap */
int psx_memcard_write_frame (int base, int conport, int tap, int delay,
int frame, unsigned char *data_f);
/* Reads a single block (64 frames) from Memory Card on conport base:tap */
unsigned char *psx_memcard_read_block (int base, int conport, int tap, int delay,
int block);
/* Writes a single block (64 frames) to Memory Card on conport base:tap */
int psx_memcard_write_block (int base, int conport, int tap, int delay,
int block, unsigned char *data_b);
/* Reads the info associated with block from the directory */
PSX_MCB_INFO_DIR *psx_mcb_read_dir (int base, int conport, int tap, int delay,
int block);
/* Prints the info associated with block from it's data */
PSX_MCB_INFO_DAT *psx_mcb_read_dat (int base, int conport, int tap, int delay,
int block);
/* Merges the info associated with block from the directory and it's data */
PSX_MCB_INFO *psx_mcb_info_merge (PSX_MCB_INFO_DIR mcb_info_dir,
PSX_MCB_INFO_DAT mcb_info_dat,
PSX_MCB_INFO * mcb_info);
/* Reads the info associated with block from the directory and it's data */
PSX_MCB_INFO *psx_mcb_read_info (int base, int conport, int tap, int delay,
int block);
#endif // USE_PARALLEL

View File

@ -0,0 +1,371 @@
/*
sflash.h - Super Flash flash card programmer support for uCON64
Copyright (c) 2004 JohnDie
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 <time.h>
#include "misc/parallel.h"
#include "misc/itypes.h"
#include "misc/misc.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "misc/file.h"
#include "ucon64.h"
#include "ucon64_misc.h"
#include "tototek.h"
#include "sflash.h"
const st_getopt2_t sflash_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "Super Flash flash card programmer"/*"2004 ToToTEK Multi Media http://www.tototek.com"*/,
NULL
},
#ifdef USE_PARALLEL
{
"xsf", 0, 0, UCON64_XSF,
NULL, "send/receive ROM to/from Super Flash flash card programmer\n" OPTION_LONG_S "port=PORT\n"
"receives automatically (64 Mbits) when ROM does not exist",
&ucon64_wf[WF_OBJ_SNES_DEFAULT_STOP_NO_SPLIT_NO_ROM]
},
{
"xsfs", 0, 0, UCON64_XSFS,
NULL, "send/receive SRAM to/from Super Flash flash card programmer\n" OPTION_LONG_S "port=PORT\n"
"receives automatically when SRAM does not exist",
&ucon64_wf[WF_OBJ_SNES_STOP_NO_ROM]
},
#endif
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
#ifdef USE_PARALLEL
static void eep_reset (void);
static void write_rom_by_byte (int *addr, unsigned char *buf);
static void write_rom_by_page (int *addr, unsigned char *buf);
static void write_ram_by_byte (int *addr, unsigned char *buf);
static void write_ram_by_page (int *addr, unsigned char *buf);
void
eep_reset (void)
{
ttt_rom_enable ();
ttt_write_mem (0x400000, 0xff); // reset EEP chip 2
ttt_write_mem (0, 0xff); // reset EEP chip 1
ttt_write_mem (0x600000, 0xff); // reset EEP chip 2
ttt_write_mem (0x200000, 0xff); // reset EEP chip 1
ttt_rom_disable ();
}
void
write_rom_by_byte (int *addr, unsigned char *buf)
{
int x;
for (x = 0; x < 0x4000; x++)
{
ttt_write_byte_intel (*addr, buf[*addr & 0x3fff]);
(*addr)++;
}
}
void
write_rom_by_page (int *addr, unsigned char *buf)
{
int x;
for (x = 0; x < 0x200; x++)
{
ttt_write_page_rom (*addr, buf);
(*addr) += 0x20;
}
}
void
write_ram_by_byte (int *addr, unsigned char *buf)
{
int x, i = *addr & 0x3fff;
for (x = 0; x < 0x4000; x++, i = (i + 1) & 0x3fff)
{
ttt_write_byte_ram (*addr, buf[i]);
(*addr)++;
}
}
void
write_ram_by_page (int *addr, unsigned char *buf)
{
int x;
for (x = 0; x < 0x40; x++)
{
ttt_write_page_ram (*addr, buf);
(*addr) += 0x100;
}
}
int
sf_read_rom (const char *filename, unsigned int parport, int size)
{
FILE *file;
unsigned char buffer[0x100];
int blocksleft, address = 0;
time_t starttime;
void (*read_block) (int, unsigned char *) = ttt_read_rom_w; // ttt_read_rom_b
if ((file = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
ttt_init_io (parport);
printf ("Receive: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
blocksleft = size >> 8;
eep_reset ();
ttt_rom_enable ();
if (read_block == ttt_read_rom_w)
ttt_set_ai_data (6, 0x94); // rst=1, wei=0(dis.), rdi=0(dis.), inc mode, rom_CS
starttime = time (NULL);
while (blocksleft-- > 0)
{
read_block (address, buffer); // 0x100 bytes read
if (read_block == ttt_read_rom_b)
ucon64_bswap16_n (buffer, 0x100);
fwrite (buffer, 1, 0x100, file);
address += 0x100;
if ((address & 0x3fff) == 0)
ucon64_gauge (starttime, address, size);
}
// ttt_read_rom_b() calls ttt_rom_disable()
if (read_block == ttt_read_rom_w)
ttt_rom_disable ();
fclose (file);
ttt_deinit_io ();
return 0;
}
int
sf_write_rom (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char buffer[0x4000], game_table[0x80];
int game_no, romsize, size, address = 0, bytesread, bytessend = 0;
time_t starttime;
void (*write_block) (int *, unsigned char *) = write_rom_by_page; // write_rom_by_byte
(void) write_rom_by_byte;
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
ttt_init_io (parport);
size = fsizeof (filename);
printf ("Send: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
eep_reset ();
if (ttt_get_id () != 0x8917) // Intel 64J3
{
fputs ("ERROR: Super Flash flash card (programmer) not detected\n", stderr);
fclose (file);
ttt_deinit_io ();
exit (1);
}
starttime = time (NULL);
// Erase last block now, because we have to write to it anyway later. Erasing
// it later could erase part of a game.
ttt_erase_block (0x7e0000);
fseek (file, 0x4000, SEEK_SET);
bytesread = fread (game_table, 1, 0x80, file);
if (bytesread != 0x80)
{
fputs ("ERROR: Could not read game table from file\n", stderr);
fclose (file);
ttt_deinit_io ();
return 0;
}
fseek (file, 0x8000, SEEK_SET);
for (game_no = 0; game_no < 4; game_no++)
{
if (game_table[game_no * 0x20] == 0)
continue;
romsize = game_table[game_no * 0x20 + 0x1f] * 0x8000;
switch (game_table[game_no * 0x20 + 0x1d] & 0x60)
{
case 0x00:
address = 0x000000;
break;
case 0x40:
address = 0x200000;
break;
case 0x20:
address = 0x400000;
break;
case 0x60:
address = 0x600000;
break;
// no default case because we handled all possible cases
}
eep_reset ();
while (romsize && (bytesread = fread (buffer, 1, 0x4000, file)))
{
if ((address & 0x1ffff) == 0)
ttt_erase_block (address);
if (address < 0x7f8000) // We mustn't write to the loader space
write_block (&address, buffer);
bytessend += bytesread;
ucon64_gauge (starttime, bytessend, size);
romsize -= 0x4000;
}
}
fseek (file, 0, SEEK_SET);
romsize = 0x8000;
address = 0x7f8000;
while (romsize && (bytesread = fread (buffer, 1, 0x4000, file)))
{
write_block (&address, buffer);
bytessend += bytesread;
ucon64_gauge (starttime, bytessend, size);
romsize -= 0x4000;
}
fclose (file);
ttt_deinit_io ();
return 0;
}
int
sf_read_sram (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char buffer[0x100];
int blocksleft, address, bytesreceived = 0, size;
time_t starttime;
void (*read_block) (int, unsigned char *) = ttt_read_ram_w; // ttt_read_ram_w
address = 0xfe0000; // SRAM is stored at 0xfe0000
size = 0x020000; // SRAM size is 1024 kbit
if ((file = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
ttt_init_io (parport);
printf ("Receive: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
// ttt_ram_enable (); // The next ttt_set_ai_data also enables ram access
ttt_set_ai_data (6, 0x98); // Enable cartridge access, auto address increment
blocksleft = size >> 8;
starttime = time (NULL);
while (blocksleft-- > 0)
{
read_block (address, buffer); // 0x100 bytes read
fwrite (buffer, 1, 0x100, file);
address += 0x100;
bytesreceived += 0x100;
if ((address & 0x3fff) == 0)
ucon64_gauge (starttime, bytesreceived, size);
}
ttt_ram_disable ();
fclose (file);
ttt_deinit_io ();
return 0;
}
int
sf_write_sram (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char buffer[0x4000];
int size, bytesread, bytessend = 0, address;
time_t starttime;
void (*write_block) (int *, unsigned char *) = write_ram_by_byte; // write_ram_by_page
(void) write_ram_by_page;
size = fsizeof (filename);
address = 0xfe0000;
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
ttt_init_io (parport);
printf ("Send: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
ttt_ram_enable ();
starttime = time (NULL);
while ((bytesread = fread (buffer, 1, 0x4000, file)))
{
write_block (&address, buffer); // 0x4000 bytes write
bytessend += bytesread;
if ((address & 0x3fff) == 0)
ucon64_gauge (starttime, bytessend, size);
}
fclose (file);
ttt_deinit_io ();
return 0;
}
#endif // USE_PARALLEL

View File

@ -0,0 +1,33 @@
/*
sflash.h - Super Flash flash card programmer support for uCON64
Copyright (c) 2004 JohnDie
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.
*/
#ifndef SFLASH_H
#define SFLASH_H
extern const st_getopt2_t sflash_usage[];
#ifdef USE_PARALLEL
extern int sf_read_rom (const char *filename, unsigned int parport, int size);
extern int sf_write_rom (const char *filename, unsigned int parport);
extern int sf_read_sram (const char *filename, unsigned int parport);
extern int sf_write_sram (const char *filename, unsigned int parport);
#endif
#endif

View File

@ -0,0 +1,407 @@
/*
smc.c - Super Magic Card support for uCON64
Copyright (c) 2003 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 <time.h>
#include <string.h>
#include "misc/misc.h"
#include "misc/itypes.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "misc/file.h"
#include "ucon64.h"
#include "ucon64_misc.h"
#include "ffe.h"
#include "smc.h"
const st_getopt2_t smc_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "Super Magic Card"/*"1993/1994/1995/19XX Front Far East/FFE http://www.front.com.tw"*/,
NULL
},
#ifdef USE_PARALLEL
{
"xsmc", 0, 0, UCON64_XSMC, // send only
NULL, "send ROM (in FFE format) to Super Magic Card; " OPTION_LONG_S "port=PORT",
&ucon64_wf[WF_OBJ_NES_DEFAULT_STOP_NO_SPLIT]
},
{
"xsmcr", 0, 0, UCON64_XSMCR,
NULL, "send/receive RTS data to/from Super Magic Card; " OPTION_LONG_S "port=PORT\n"
"receives automatically when RTS file does not exist",
&ucon64_wf[WF_OBJ_NES_STOP_NO_ROM]
},
#endif
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
#ifdef USE_PARALLEL
#define BUFFERSIZE 8192
static int get_blocks1 (unsigned char *header);
static int get_blocks2 (unsigned char *header);
static int get_blocks3 (unsigned char *header);
int
get_blocks1 (unsigned char *header)
{
if (header[7] == 0xaa)
return header[3];
if (header[0] & 0x30)
return header[0] & 0x20 ? 32 : 16; // 0x10 => 16; 0x20/0x30 => 32
else
switch (header[1] >> 5)
{
case 0:
case 4:
return 16;
case 1:
case 2:
case 3:
return 32;
default: // 5/6/7
return 4;
}
}
int
get_blocks2 (unsigned char *header)
{
if (header[0] & 0x30)
return header[0] & 0x10 ? 32 : 16; // 0x10/0x30 => 32; 0x20 => 16
else
return 0;
}
int
get_blocks3 (unsigned char *header)
{
if (header[7] == 0xaa)
return header[4];
if (header[0] & 0x30)
return 0;
else
switch (header[1] >> 5)
{
default: // 0/1/2/3
return 0;
case 4:
case 5:
return 4;
case 6:
return 2;
case 7:
return 1;
}
}
int
smc_write_rom (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char *buffer;
int bytesread, bytessend, size, offset, n_blocks1, n_blocks2, n_blocks3, n;
time_t starttime;
ffe_init_io (parport);
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
{
fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
exit (1);
}
ffe_send_command0 (0x4500, 2);
ffe_send_command0 (0x42fd, 0x20);
ffe_send_command0 (0x43fc, 0);
fread (buffer, 1, SMC_HEADER_LEN, file);
n_blocks1 = get_blocks1 (buffer);
n_blocks2 = get_blocks2 (buffer);
n_blocks3 = get_blocks3 (buffer);
size = (n_blocks1 + n_blocks2 + n_blocks3) * 8 * 1024 + 8 +
(buffer[0] & SMC_TRAINER ? 512 : 0);
printf ("Send: %d Bytes (%.4f Mb)\n", size, (float) size / MBIT);
ffe_send_block (0x5020, buffer, 8); // send "file control block"
bytessend = 8;
if (buffer[1] >> 5 > 4)
offset = 12;
else
offset = 0;
if (buffer[0] & SMC_TRAINER) // send trainer if present
{
fread (buffer, 1, 512, file);
ffe_send_block (0x600, buffer, 512);
bytessend += 512;
}
printf ("Press q to abort\n\n");
starttime = time (NULL);
for (n = 0; n < n_blocks1; n++)
{
ffe_send_command0 (0x4507, (unsigned char) (n + offset));
if ((bytesread = fread (buffer, 1, BUFFERSIZE, file)) == 0)
break;
ffe_send_block (0x6000, buffer, bytesread);
bytessend += bytesread;
ucon64_gauge (starttime, bytessend, size);
ffe_checkabort (2);
}
for (n = 0; n < n_blocks2; n++)
{
ffe_send_command0 (0x4507, (unsigned char) (n + 32));
if ((bytesread = fread (buffer, 1, BUFFERSIZE, file)) == 0)
break;
ffe_send_block (0x6000, buffer, bytesread);
bytessend += bytesread;
ucon64_gauge (starttime, bytessend, size);
ffe_checkabort (2);
}
ffe_send_command0 (0x2001, 0);
for (n = 0; n < n_blocks3; n++)
{
if (n == 0)
{
ffe_send_command0 (0x4500, 0x22);
ffe_send_command0 (0x42ff, 0x30);
if ((bytesread = fread (buffer, 1, BUFFERSIZE, file)) == 0)
break;
ffe_send_block (0x6000, buffer, bytesread);
}
else
{
int m;
ffe_send_command0 (0x4500, 7);
for (m = 0; m < 8; m++)
ffe_send_command0 ((unsigned short) (0x4510 + m), (unsigned char) (n * 8 + m));
if ((bytesread = fread (buffer, 1, BUFFERSIZE, file)) == 0)
break;
ffe_send_block2 (0, buffer, bytesread);
}
bytessend += bytesread;
ucon64_gauge (starttime, bytessend, size);
ffe_checkabort (2);
}
for (n = 0x4504; n < 0x4508; n++)
ffe_send_command0 ((unsigned short) n, 0);
for (n = 0x4510; n < 0x451c; n++)
ffe_send_command0 ((unsigned short) n, 0);
ffe_send_command (5, 1, 0);
free (buffer);
fclose (file);
ffe_deinit_io ();
return 0;
}
int
smc_read_rts (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char *buffer;
int bytesreceived = 0, size, n;
time_t starttime;
ffe_init_io (parport);
if ((file = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
{
fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
exit (1);
}
size = 0x68 + 4 * 1024 + 5 * 8 * 1024;
printf ("Receive: %d Bytes\n", size);
memset (buffer, 0, SMC_HEADER_LEN);
buffer[8] = 0xaa;
buffer[9] = 0xbb;
buffer[10] = 1;
printf ("Press q to abort\n\n");
starttime = time (NULL);
ffe_send_command (5, 3, 0);
ffe_receive_block (0x5840, buffer + 0x100, 0x68);
fwrite (buffer, 1, SMC_HEADER_LEN, file);
bytesreceived += 0x68;
ffe_send_command0 (0x4500, 0x32);
ffe_send_command0 (0x42ff, 0x30);
ffe_receive_block (0x6000, buffer, BUFFERSIZE / 2); // 0x1000
fwrite (buffer, 1, BUFFERSIZE / 2, file);
bytesreceived += BUFFERSIZE / 2;
ucon64_gauge (starttime, bytesreceived, size);
ffe_checkabort (2);
for (n = 2; n <= 0x22; n += 0x20)
{
ffe_send_command0 (0x4500, (unsigned char) n);
ffe_receive_block (0x6000, buffer, BUFFERSIZE); // 0x2000
fwrite (buffer, 1, BUFFERSIZE, file);
bytesreceived += BUFFERSIZE;
ucon64_gauge (starttime, bytesreceived, size);
ffe_checkabort (2);
}
for (n = 1; n <= 3; n++)
{
ffe_send_command0 (0x43fc, (unsigned char) n);
if (n == 1)
ffe_send_command0 (0x2001, 0);
ffe_receive_block2 (0, buffer, BUFFERSIZE); // 0x2000
fwrite (buffer, 1, BUFFERSIZE, file);
bytesreceived += BUFFERSIZE;
ucon64_gauge (starttime, bytesreceived, size);
ffe_checkabort (2);
}
ffe_send_command0 (0x43fc, 0);
ffe_send_command0 (0x2001, 0x6b);
free (buffer);
fclose (file);
ffe_deinit_io ();
return 0;
}
int
smc_write_rts (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char *buffer;
int bytessend = 0, size, n;
time_t starttime;
ffe_init_io (parport);
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
{
fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
exit (1);
}
size = 0x68 + 4 * 1024 + 5 * 8 * 1024;
printf ("Send: %d Bytes\n", size);
fread (buffer, 1, SMC_HEADER_LEN, file);
printf ("Press q to abort\n\n");
starttime = time (NULL);
ffe_send_command (5, 3, 0);
ffe_send_block (0x5840, buffer + 0x100, 0x68);
bytessend += 0x68;
ffe_send_command0 (0x4500, 0x32);
ffe_send_command0 (0x42ff, 0x30);
fread (buffer, 1, BUFFERSIZE / 2, file);
ffe_send_block (0x6000, buffer, BUFFERSIZE / 2); // 0x1000
bytessend += BUFFERSIZE / 2;
ucon64_gauge (starttime, bytessend, size);
ffe_checkabort (2);
for (n = 2; n <= 0x22; n += 0x20)
{
ffe_send_command0 (0x4500, (unsigned char) n);
fread (buffer, 1, BUFFERSIZE, file);
ffe_send_block (0x6000, buffer, BUFFERSIZE); // 0x2000
bytessend += BUFFERSIZE;
ucon64_gauge (starttime, bytessend, size);
ffe_checkabort (2);
}
for (n = 1; n <= 3; n++)
{
ffe_send_command0 (0x43fc, (unsigned char) n);
if (n == 1)
ffe_send_command0 (0x2001, 0);
fread (buffer, 1, BUFFERSIZE, file);
ffe_send_block2 (0, buffer, BUFFERSIZE); // 0x2000
bytessend += BUFFERSIZE;
ucon64_gauge (starttime, bytessend, size);
ffe_checkabort (2);
}
ffe_send_command0 (0x43fc, 0);
ffe_send_command0 (0x2001, 0x6b);
free (buffer);
fclose (file);
ffe_deinit_io ();
return 0;
}
#endif // USE_PARALLEL

View File

@ -0,0 +1,47 @@
/*
smc.h - Super Magic Card support for uCON64
Copyright (c) 2003 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.
*/
#ifndef SMC_H
#define SMC_H
extern const st_getopt2_t smc_usage[];
typedef struct st_smc_header
{
unsigned char emulation1;
unsigned char emulation2;
unsigned char pad[6];
unsigned char id1;
unsigned char id2;
unsigned char type;
unsigned char pad2[501];
} st_smc_header_t;
#define SMC_HEADER_START 0
#define SMC_HEADER_LEN (sizeof (st_smc_header_t))
#define SMC_TRAINER 0x40
#ifdef USE_PARALLEL
extern int smc_write_rom (const char *filename, unsigned int parport);
extern int smc_read_rts (const char *filename, unsigned int parport);
extern int smc_write_rts (const char *filename, unsigned int parport);
#endif
#endif // SMC_H

View File

@ -0,0 +1,343 @@
/*
smd.c - Super Magic Drive support for uCON64
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
Copyright (c) 2001 - 2003 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 <time.h>
#include "misc/misc.h"
#include "misc/itypes.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "misc/file.h"
#include "ucon64.h"
#include "ucon64_misc.h"
#include "ffe.h"
#include "smd.h"
const st_getopt2_t smd_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "Super Com Pro/Super Magic Drive/SMD"/*"19XX Front Far East/FFE http://www.front.com.tw"*/,
NULL
},
#ifdef USE_PARALLEL
{
"xsmd", 0, 0, UCON64_XSMD,
NULL, "send/receive ROM to/from Super Magic Drive/SMD; " OPTION_LONG_S "port=PORT\n"
"receives automatically when ROM does not exist",
&ucon64_wf[WF_OBJ_GEN_DEFAULT_STOP_NO_SPLIT_NO_ROM]
},
{
"xsmds", 0, 0, UCON64_XSMDS,
NULL, "send/receive SRAM to/from Super Magic Drive/SMD; " OPTION_LONG_S "port=PORT\n"
"receives automatically when SRAM does not exist",
&ucon64_wf[WF_OBJ_GEN_STOP_NO_ROM]
},
#endif // USE_PARALLEL
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
// the following two functions are used by non-transfer code in genesis.c and sms.c
void
smd_interleave (unsigned char *buffer, int size)
// Convert binary data to the SMD interleaved format
{
int count, offset;
unsigned char block[16384];
for (count = 0; count < size / 16384; count++)
{
memcpy (block, &buffer[count * 16384], 16384);
for (offset = 0; offset < 8192; offset++)
{
buffer[(count * 16384) + 8192 + offset] = block[offset << 1];
buffer[(count * 16384) + offset] = block[(offset << 1) + 1];
}
}
}
void
smd_deinterleave (unsigned char *buffer, int size)
{
int count, offset;
unsigned char block[16384];
for (count = 0; count < size / 16384; count++)
{
memcpy (block, &buffer[count * 16384], 16384);
for (offset = 0; offset < 8192; offset++)
{
buffer[(count * 16384) + (offset << 1)] = block[offset + 8192];
buffer[(count * 16384) + (offset << 1) + 1] = block[offset];
}
}
}
#ifdef USE_PARALLEL
#define BUFFERSIZE 16384
int
smd_read_rom (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char *buffer, byte;
int size, blocksdone = 0, blocksleft, bytesreceived = 0;
time_t starttime;
ffe_init_io (parport);
if ((file = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
{
fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
exit (1);
}
ffe_send_command (1, 0xdff1, 1);
byte = ffe_receiveb ();
if ((0x81 ^ byte) != ffe_receiveb ())
printf ("received data is corrupt\n");
blocksleft = 8 * byte;
if (blocksleft == 0)
{
fprintf (stderr, "ERROR: There is no cartridge present in the Super Magic Drive\n");
fclose (file);
remove (filename);
exit (1);
}
memset (buffer, 0, SMD_HEADER_LEN);
buffer[0] = blocksleft;
buffer[1] = 3;
buffer[8] = 0xaa;
buffer[9] = 0xbb;
buffer[10] = 6;
fwrite (buffer, 1, SMD_HEADER_LEN, file); // write header
size = blocksleft * 16384; // size in bytes for ucon64_gauge() below
printf ("Receive: %d Bytes (%.4f Mb)\n", size, (float) size / MBIT);
wait2 (32);
ffe_send_command0 (0x2001, 0);
printf ("Press q to abort\n\n");
starttime = time (NULL);
while (blocksleft > 0)
{
ffe_send_command (5, (unsigned short) blocksdone, 0);
ffe_receive_block (0x4000, buffer, BUFFERSIZE);
blocksdone++;
blocksleft--;
fwrite (buffer, 1, BUFFERSIZE, file);
bytesreceived += BUFFERSIZE;
ucon64_gauge (starttime, bytesreceived, size);
ffe_checkabort (2);
}
free (buffer);
fclose (file);
ffe_deinit_io ();
return 0;
}
int
smd_write_rom (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char *buffer;
int bytesread, bytessend, blocksdone = 0, fsize;
time_t starttime;
ffe_init_io (parport);
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
{
fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
exit (1);
}
fsize = fsizeof (filename);
printf ("Send: %d Bytes (%.4f Mb)\n", fsize, (float) fsize / MBIT);
fread (buffer, 1, SMD_HEADER_LEN, file);
ffe_send_block (0xdc00, buffer, SMD_HEADER_LEN); // send header
bytessend = SMD_HEADER_LEN;
ffe_send_command0 (0x2001, 0);
printf ("Press q to abort\n\n");
starttime = time (NULL);
while ((bytesread = fread (buffer, 1, BUFFERSIZE, file)))
{
ffe_send_command (5, (unsigned short) blocksdone, 0);
ffe_send_block (0x8000, buffer, bytesread);
blocksdone++;
bytessend += bytesread;
ucon64_gauge (starttime, bytessend, fsize);
ffe_checkabort (2);
}
// ROM dump > 128 16 KB blocks? (=16 Mb (=2 MB))
ffe_send_command0 (0x2001, (unsigned char) (blocksdone > 0x80 ? 7 : 3));
free (buffer);
fclose (file);
ffe_deinit_io ();
return 0;
}
int
smd_read_sram (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char *buffer;
int blocksleft, bytesreceived = 0;
unsigned short address;
time_t starttime;
ffe_init_io (parport);
if ((file = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
{
fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
exit (1);
}
printf ("Receive: %d Bytes\n", 32 * 1024);
memset (buffer, 0, SMD_HEADER_LEN);
buffer[8] = 0xaa;
buffer[9] = 0xbb;
buffer[10] = 7;
fwrite (buffer, 1, SMD_HEADER_LEN, file);
ffe_send_command0 (0x2001, 4);
printf ("Press q to abort\n\n");
blocksleft = 2; // SRAM is 2*16 KB
address = 0x4000;
starttime = time (NULL);
while (blocksleft > 0)
{
ffe_receive_block (address, buffer, BUFFERSIZE);
blocksleft--;
address += 0x4000;
fwrite (buffer, 1, BUFFERSIZE, file);
bytesreceived += BUFFERSIZE;
ucon64_gauge (starttime, bytesreceived, 32 * 1024);
ffe_checkabort (2);
}
free (buffer);
fclose (file);
ffe_deinit_io ();
return 0;
}
int
smd_write_sram (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char *buffer;
int bytesread, bytessend = 0, size;
unsigned short address;
time_t starttime;
ffe_init_io (parport);
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
if ((buffer = (unsigned char *) malloc (BUFFERSIZE)) == NULL)
{
fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFFERSIZE);
exit (1);
}
size = fsizeof (filename) - SMD_HEADER_LEN;
printf ("Send: %d Bytes\n", size);
fseek (file, SMD_HEADER_LEN, SEEK_SET); // skip the header
ffe_send_command0 (0x2001, 4);
printf ("Press q to abort\n\n");
address = 0x4000;
starttime = time (NULL);
while ((bytesread = fread (buffer, 1, BUFFERSIZE, file)))
{
ffe_send_block (address, buffer, bytesread);
address += 0x4000;
bytessend += bytesread;
ucon64_gauge (starttime, bytessend, size);
ffe_checkabort (2);
}
free (buffer);
fclose (file);
ffe_deinit_io ();
return 0;
}
#endif // USE_PARALLEL

View File

@ -0,0 +1,53 @@
/*
smd.h - Super Magic Drive support for uCON64
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
Copyright (c) 2002 - 2003 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.
*/
#ifndef SMD_H
#define SMD_H
extern const st_getopt2_t smd_usage[];
// For the header format, see ffe.h
typedef struct st_smd_header
{
unsigned char size;
unsigned char id0;
unsigned char split;
char pad[5];
unsigned char id1;
unsigned char id2;
unsigned char type;
char pad2[501];
} st_smd_header_t;
#ifdef USE_PARALLEL
extern int smd_read_rom (const char *filename, unsigned int parport);
extern int smd_write_rom (const char *filename, unsigned int parport);
extern int smd_read_sram (const char *filename, unsigned int parport);
extern int smd_write_sram (const char *filename, unsigned int parport);
#endif
// the following two functions are used by non-transfer code in genesis.c and sms.c
extern void smd_interleave (unsigned char *buffer, int size);
extern void smd_deinterleave (unsigned char *buffer, int size);
#define SMD_HEADER_LEN (sizeof (st_smd_header_t))
#endif // SMD_H

View File

@ -0,0 +1,348 @@
/*
smsgg-pro.c - SMS-PRO/GG-PRO flash card programmer support for uCON64
Copyright (c) 2004 dbjh
Based on Delphi source code by ToToTEK Multi Media. Information in that source
code has been used with permission. However, ToToTEK Multi Media explicitly
stated that the information in that source code may be freely distributed.
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 <time.h>
#include "misc/parallel.h"
#include "misc/itypes.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "misc/file.h"
#include "misc/misc.h"
#include "ucon64.h"
#include "ucon64_misc.h"
#include "tototek.h"
#include "smsgg-pro.h"
const st_getopt2_t smsggpro_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "SMS-PRO/GG-PRO flash card programmer"/*"2004 ToToTEK Multi Media http://www.tototek.com"*/,
NULL
},
#ifdef USE_PARALLEL
{
"xgg", 0, 0, UCON64_XGG,
NULL, "send/receive ROM to/from SMS-PRO/GG-PRO flash card programmer\n" OPTION_LONG_S "port=PORT\n"
"receives automatically (32 Mbits) when ROM does not exist",
&ucon64_wf[WF_OBJ_SMS_DEFAULT_STOP_NO_SPLIT_NO_ROM]
},
{
"xggs", 0, 0, UCON64_XGGS,
NULL, "send/receive SRAM to/from SMS-PRO/GG-PRO flash card programmer\n" OPTION_LONG_S "port=PORT\n"
"receives automatically when SRAM does not exist",
&ucon64_wf[WF_OBJ_SMS_STOP_NO_ROM]
},
{
"xggb", 1, 0, UCON64_XGGB,
"BANK", "send/receive SRAM to/from SMS-PRO/GG-PRO BANK\n"
"BANK can be a number from 1 to 4; " OPTION_LONG_S "port=PORT\n"
"receives automatically when SRAM does not exist",
&ucon64_wf[WF_OBJ_SMS_STOP_NO_ROM]
},
#endif // USE_PARALLEL
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
#ifdef USE_PARALLEL
static void eep_reset (void);
static void write_rom_by_byte (int *addr, unsigned char *buf);
static void write_rom_by_page (int *addr, unsigned char *buf);
static void write_ram_by_byte (int *addr, unsigned char *buf);
static void write_ram_by_page (int *addr, unsigned char *buf);
void
eep_reset (void)
{
ttt_rom_enable ();
ttt_write_mem (0x000000, 0xff); // reset EEP
ttt_write_mem (0x200000, 0xff); // reset EEP
ttt_rom_disable ();
}
void
write_rom_by_byte (int *addr, unsigned char *buf)
{
int x;
for (x = 0; x < 0x4000; x++)
{
ttt_write_byte_sharp (*addr, buf[*addr & 0x3fff]);
(*addr)++;
}
}
void
write_rom_by_page (int *addr, unsigned char *buf)
{
int x;
for (x = 0; x < 0x200; x++)
{
ttt_write_page_rom (*addr, buf);
(*addr) += 0x20;
}
}
void
write_ram_by_byte (int *addr, unsigned char *buf)
{
int x;
for (x = 0; x < 0x4000; x++)
{
ttt_write_byte_ram (*addr, buf[*addr & 0x3fff]);
(*addr)++;
}
}
void
write_ram_by_page (int *addr, unsigned char *buf)
{
int x;
for (x = 0; x < 0x40; x++)
{
ttt_write_page_ram (*addr, buf);
(*addr) += 0x100;
}
}
int
smsgg_read_rom (const char *filename, unsigned int parport, int size)
{
FILE *file;
unsigned char buffer[0x100];
int blocksleft, address = 0;
time_t starttime;
void (*read_block) (int, unsigned char *) = ttt_read_rom_w; // ttt_read_rom_b
if ((file = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
ttt_init_io (parport);
printf ("Receive: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
blocksleft = size >> 8;
eep_reset ();
ttt_rom_enable ();
if (read_block == ttt_read_rom_w)
ttt_set_ai_data (6, 0x94); // rst=1, wei=0(dis.), rdi=0(dis.), inc mode, rom_CS
starttime = time (NULL);
while (blocksleft-- > 0)
{
read_block (address, buffer); // 0x100 bytes read
fwrite (buffer, 1, 0x100, file);
address += 0x100;
if ((address & 0x3fff) == 0)
ucon64_gauge (starttime, address, size);
}
// original code doesn't call ttt_rom_disable() when byte-size function is
// used (ttt_read_rom_b() calls it)
if (read_block == ttt_read_rom_w)
ttt_rom_disable ();
fclose (file);
ttt_deinit_io ();
return 0;
}
int
smsgg_write_rom (const char *filename, unsigned int parport)
{
FILE *file;
unsigned char buffer[0x4000];
int size, address = 0, bytesread, bytessend = 0;
time_t starttime;
void (*write_block) (int *, unsigned char *) = write_rom_by_page; // write_rom_by_byte
(void) write_rom_by_byte;
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
ttt_init_io (parport);
size = fsizeof (filename);
printf ("Send: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
eep_reset ();
if (ttt_get_id () != 0xb0d0)
{
fputs ("ERROR: SMS-PRO/GG-PRO flash card (programmer) not detected\n", stderr);
fclose (file);
ttt_deinit_io ();
exit (1);
}
starttime = time (NULL);
eep_reset ();
while ((bytesread = fread (buffer, 1, 0x4000, file)))
{
if ((address & 0xffff) == 0)
ttt_erase_block (address);
write_block (&address, buffer);
bytessend += bytesread;
ucon64_gauge (starttime, bytessend, size);
}
fclose (file);
ttt_deinit_io ();
return 0;
}
int
smsgg_read_sram (const char *filename, unsigned int parport, int start_bank)
{
FILE *file;
unsigned char buffer[0x100];
int blocksleft, address, size, bytesreceived = 0;
time_t starttime;
void (*read_block) (int, unsigned char *) = ttt_read_ram_b; // ttt_read_ram_w
if (start_bank == -1)
{
address = 0;
size = 128 * 1024;
}
else
{
if (start_bank < 1 || start_bank > 4)
{
fputs ("ERROR: Bank must be a value 1 - 4\n", stderr);
exit (1);
}
address = (start_bank - 1) * 32 * 1024;
size = 32 * 1024;
}
if ((file = fopen (filename, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], filename);
exit (1);
}
ttt_init_io (parport);
printf ("Receive: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
if (read_block == ttt_read_ram_w)
{
ttt_ram_enable ();
ttt_set_ai_data (6, 0x98); // rst=1, wei=0(dis.), rdi=0(dis.), inc mode, rom_CS
}
// else
// ttt_set_ai_data (6, 0x94); // rst=1, wei=0(dis.), rdi=0(dis.), inc mode, rom_CS
blocksleft = size >> 8;
starttime = time (NULL);
while (blocksleft-- > 0)
{
read_block (address, buffer); // 0x100 bytes read
fwrite (buffer, 1, 0x100, file);
address += 0x100;
bytesreceived += 0x100;
if ((address & 0x3fff) == 0)
ucon64_gauge (starttime, bytesreceived, size);
}
if (read_block == ttt_read_ram_w)
ttt_ram_disable ();
fclose (file);
ttt_deinit_io ();
return 0;
}
int
smsgg_write_sram (const char *filename, unsigned int parport, int start_bank)
{
FILE *file;
unsigned char buffer[0x4000];
int size, bytesread, bytessend = 0, address;
time_t starttime;
void (*write_block) (int *, unsigned char *) = write_ram_by_byte; // write_ram_by_page
(void) write_ram_by_page;
size = fsizeof (filename);
if (start_bank == -1)
address = 0;
else
{
if (start_bank < 1 || start_bank > 4)
{
fputs ("ERROR: Bank must be a value 1 - 4\n", stderr);
exit (1);
}
address = (start_bank - 1) * 32 * 1024;
}
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
ttt_init_io (parport);
printf ("Send: %d Bytes (%.4f Mb)\n\n", size, (float) size / MBIT);
starttime = time (NULL);
while ((bytesread = fread (buffer, 1, 0x4000, file)))
{
write_block (&address, buffer);
bytessend += bytesread;
ucon64_gauge (starttime, bytessend, size);
}
fclose (file);
ttt_deinit_io ();
return 0;
}
#endif // USE_PARALLEL

Some files were not shown because too many files have changed in this diff Show More