Remove old ucon64

This commit is contained in:
optixx 2016-02-09 21:36:15 +01:00
parent cf41986ccc
commit 123ca226ab
227 changed files with 1955 additions and 91598 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
/*
* File: qd16boot01.smc Time: Fri, 30 Oct 2009 16:49:11
*/
File: qd16boot01.smc
Time: Tue, 09 Feb 2016 12:36:39
*/
#ifndef __FIFO_H__
#define __FIFO_H__

View File

@ -1,173 +0,0 @@
..................
...............: 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

@ -1,381 +0,0 @@
.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@ -I/opt/local/include
LDFLAGS=-s -L/opt/local/lib
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 \
misc/opendevice.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/quickdev16.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

@ -1,380 +0,0 @@
.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

@ -1,223 +0,0 @@
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

@ -1,118 +0,0 @@
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

@ -1,419 +0,0 @@
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

@ -1,67 +0,0 @@
/*
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
#ifdef USE_USB
#include "quickdev16.h"
#endif // USE_PARALLEL
#endif // BACKUP_H

View File

@ -1,768 +0,0 @@
/*
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

@ -1,504 +0,0 @@
/*
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

@ -1,41 +0,0 @@
/*
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

@ -1,985 +0,0 @@
/*
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

@ -1,32 +0,0 @@
/*
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

@ -1,139 +0,0 @@
/*
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

@ -1,34 +0,0 @@
/*
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

@ -1,399 +0,0 @@
/*
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

@ -1,31 +0,0 @@
/*
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

@ -1,587 +0,0 @@
/*
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

@ -1,31 +0,0 @@
/*
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

@ -1,34 +0,0 @@
/*
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

@ -1,35 +0,0 @@
/*
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

@ -1,316 +0,0 @@
/*
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

@ -1,80 +0,0 @@
/*
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

@ -1,739 +0,0 @@
/*
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

@ -1,100 +0,0 @@
/*
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

@ -1,34 +0,0 @@
/*
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

@ -1,49 +0,0 @@
/*
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

@ -1,46 +0,0 @@
/*
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

@ -1,31 +0,0 @@
/*
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

@ -1,169 +0,0 @@
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

@ -1,62 +0,0 @@
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

@ -1,28 +0,0 @@
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

@ -1,114 +0,0 @@
#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

@ -1,990 +0,0 @@
/*
*
* 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

@ -1,13 +0,0 @@
#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

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

View File

@ -1,189 +0,0 @@
#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

@ -1,60 +0,0 @@
#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

@ -1,31 +0,0 @@
/*
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

@ -1,158 +0,0 @@
/*
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

@ -1,30 +0,0 @@
/*
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.

Before

Width:  |  Height:  |  Size: 4.7 KiB

View File

@ -1,144 +0,0 @@
/*
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

@ -1,30 +0,0 @@
/*
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

@ -1,395 +0,0 @@
/*
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

@ -1,37 +0,0 @@
/*
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

@ -1,466 +0,0 @@
/*
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

@ -1,185 +0,0 @@
/*
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

@ -1,250 +0,0 @@
/*
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

@ -1,46 +0,0 @@
/*
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

@ -1,204 +0,0 @@
/*
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

@ -1,35 +0,0 @@
/*
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

@ -1,782 +0,0 @@
/*
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

@ -1,33 +0,0 @@
/*
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

@ -1,208 +0,0 @@
/*
*
* 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

@ -1,228 +0,0 @@
/*
quickdev16.c - Quickdev16 support for uCON64
Copyright (c) 2009 david@optixx.org
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 <usb.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 "misc/opendevice.h"
#include "ucon64.h"
#include "ucon64_misc.h"
#include "ffe.h"
#include "smc.h"
#include "quickdev16.h"
#include "console/snes.h"
#define SNES_HEADER_LEN (sizeof (st_snes_header_t))
const st_getopt2_t quickdev16_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "Quickdev16"/* http://www.optixx.org */,
NULL
},
#ifdef USE_USB
{
"xquickdev16", 0, 0, UCON64_XSNESRAM, // send only
NULL, "send ROM (in FFE format) to Quickdev16",
&ucon64_wf[WF_OBJ_NES_DEFAULT_STOP_NO_SPLIT]
},
#endif
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
#ifdef USE_USB
#define READ_BUFFER_SIZE 8192
#define SEND_BUFFER_SIZE 128
#define SNES_HIROM_SHIFT 16
#define SNES_LOROM_SHIFT 15
int
quickdev16_write_rom (const char *filename)
{
FILE *file;
int bytesread, bytessend, size;
time_t starttime;
usb_dev_handle *handle = NULL;
const unsigned char rawVid[2] = { USB_CFG_VENDOR_ID }, rawPid[2] = { USB_CFG_DEVICE_ID};
char vendor[] = { USB_CFG_VENDOR_NAME, 0 }, product[] = { USB_CFG_DEVICE_NAME, 0};
int cnt, vid, pid;
uint8_t *read_buffer;
uint32_t addr = 0;
uint16_t addr_lo = 0;
uint16_t addr_hi = 0;
uint16_t step = 0;
uint8_t bank = 0;
uint8_t bank_cnt = 0;
uint16_t bank_shift;
uint32_t bank_size;
uint32_t hirom = 0;
uint8_t byte = 0;
st_rominfo_t rominfo;
usb_init();
vid = rawVid[1] * 256 + rawVid[0];
pid = rawPid[1] * 256 + rawPid[0];
if (usbOpenDevice(&handle, vid, vendor, pid, product, NULL, NULL, NULL) != 0) {
fprintf(stderr,
"Could not find USB device \"%s\" with vid=0x%x pid=0x%x\n",
product, vid, pid);
exit(1);
}
printf("Open USB device \"%s\" with vid=0x%x pid=0x%x\n", product, vid,pid);
if ((file = fopen (filename, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], filename);
exit (1);
}
if ((read_buffer = (unsigned char *) malloc (READ_BUFFER_SIZE)) == NULL)
{
fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], READ_BUFFER_SIZE);
exit (1);
}
snes_init (&rominfo);
printf(rominfo.misc);
printf("\n");
if (UCON64_ISSET (ucon64.snes_hirom))
hirom = ucon64.snes_hirom ? 1 : 0;
else {
hirom = snes_get_snes_hirom ();
}
if (hirom) {
bank_shift = SNES_HIROM_SHIFT;
bank_size = 1 << SNES_HIROM_SHIFT;
} else {
bank_shift = SNES_LOROM_SHIFT;
bank_size = 1 << SNES_LOROM_SHIFT;
}
fseek (file, 0, SEEK_END);
size = ftell (file);
fseek (file, SMC_HEADER_LEN, SEEK_SET);
size -= SMC_HEADER_LEN;
bank_cnt = size / bank_size;
printf ("Send: %d Bytes (%.4f Mb) Hirom: %s, Banks: %i\n", size, (float) size / MBIT, hirom ? "Yes" : "No", bank_cnt);
bytessend = 0;
printf ("Press q to abort\n\n");
starttime = time (NULL);
cnt = usb_control_msg(handle,
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
USB_ENDPOINT_OUT, USB_MODE_AVR, 0, 0, NULL,
0, 5000);
/* wait for the loader to depack */
usleep(500000);
cnt = usb_control_msg(handle,
USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT,
USB_BULK_UPLOAD_INIT, bank_shift , bank_cnt, NULL, 0, 5000);
while ((bytesread = fread(read_buffer, READ_BUFFER_SIZE, 1, file)) > 0) {
for (step = 0; step < READ_BUFFER_SIZE; step += SEND_BUFFER_SIZE) {
addr_lo = addr & 0xffff;
addr_hi = (addr >> 16) & 0x00ff;
if (addr == 0){
cnt = usb_control_msg(handle,
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
USB_ENDPOINT_OUT, USB_BULK_UPLOAD_ADDR, addr_hi,
addr_lo, (char *) read_buffer + step,
SEND_BUFFER_SIZE, 5000);
} else {
cnt = usb_control_msg(handle,
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
USB_ENDPOINT_OUT, USB_BULK_UPLOAD_NEXT, addr_hi,
addr_lo, (char *) read_buffer + step,
SEND_BUFFER_SIZE, 5000);
}
if (cnt < 0) {
fprintf(stderr, "USB error: %s\n", usb_strerror());
usb_close(handle);
exit(-1);
}
bytessend += SEND_BUFFER_SIZE;
ucon64_gauge (starttime, bytessend, size);
addr += SEND_BUFFER_SIZE;
if ( addr % bank_size == 0) {
bank++;
}
}
}
cnt = usb_control_msg(handle,
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
USB_ENDPOINT_OUT, USB_BULK_UPLOAD_END, 0, 0, NULL,
0, 5000);
#if 0
bank = 0;
fseek(fp, 0, SEEK_SET);
while ((cnt = fread(read_buffer, READ_BUFFER_SIZE, 1, fp)) > 0) {
printf ("bank=0x%02x crc=0x%04x\n", bank++,
do_crc(read_buffer, READ_BUFFER_SIZE));
}
fclose(fp);
#endif
cnt = usb_control_msg(handle,
USB_TYPE_VENDOR | USB_RECIP_DEVICE |
USB_ENDPOINT_OUT, USB_MODE_SNES, 0, 0, NULL,
0, 5000);
free (read_buffer);
fclose (file);
return 0;
}
#endif // USE_USB

View File

@ -1,81 +0,0 @@
/*
quickdev16.h - Quickdev16 support for uCON64
Copyright (c) 2009 david@optixx.org
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 SNESRAM_H
#define SNESRAM_H
#define USB_UPLOAD_INIT 0
#define USB_UPLOAD_ADDR 1
#define USB_DOWNLOAD_INIT 2
#define USB_DOWNLOAD_ADDR 3
#define USB_CRC 4
#define USB_CRC_ADDR 5
#define USB_BULK_UPLOAD_INIT 6
#define USB_BULK_UPLOAD_ADDR 7
#define USB_BULK_UPLOAD_NEXT 8
#define USB_BULK_UPLOAD_END 9
#define USB_MODE_SNES 10
#define USB_MODE_AVR 11
#define USB_AVR_RESET 12
/* -------------------------- Device Description --------------------------- */
#define USB_CFG_VENDOR_ID 0xc0, 0x16
/* USB vendor ID for the device, low byte first. If you have registered your
* own Vendor ID, define it here. Otherwise you use one of obdev's free shared
* VID/PID pairs. Be sure to read USBID-License.txt for rules!
*/
#define USB_CFG_DEVICE_ID 0xdd, 0x05
/* This is the ID of the product, low byte first. It is interpreted in the
* scope of the vendor ID. If you have registered your own VID with usb.org
* or if you have licensed a PID from somebody else, define it here. Otherwise
* you use obdev's free shared VID/PID pair. Be sure to read the rules in
* USBID-License.txt!
*/
#define USB_CFG_DEVICE_VERSION 0x00, 0x01
/* Version number of the device: Minor number first, then major number.
*/
#define USB_CFG_VENDOR_NAME 'o', 'p', 't', 'i', 'x', 'x', '.', 'o', 'r', 'g'
#define USB_CFG_VENDOR_NAME_LEN 10
/* These two values define the vendor name returned by the USB device. The name
* must be given as a list of characters under single quotes. The characters
* are interpreted as Unicode (UTF-16) entities.
* If you don't want a vendor name string, undefine these macros.
* ALWAYS define a vendor name containing your Internet domain name if you use
* obdev's free shared VID/PID pair. See the file USBID-License.txt for
* details.
*/
#define USB_CFG_DEVICE_NAME 'Q', 'U', 'I', 'C', 'K', 'D', 'E', 'V', '1', '6'
#define USB_CFG_DEVICE_NAME_LEN 10
/* Same as above for the device name. If you don't want a device name, undefine
* the macros. See the file USBID-License.txt before you assign a name if you
* use a shared VID/PID.
*/
extern const st_getopt2_t quickdev16_usage[];
#ifdef USE_USB
extern int quickdev16_write_rom (const char *filename);
#endif
#endif // SNESRAM_H

View File

@ -1,371 +0,0 @@
/*
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

@ -1,33 +0,0 @@
/*
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

@ -1,407 +0,0 @@
/*
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

@ -1,47 +0,0 @@
/*
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

@ -1,343 +0,0 @@
/*
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

@ -1,53 +0,0 @@
/*
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

@ -1,348 +0,0 @@
/*
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

View File

@ -1,37 +0,0 @@
/*
smsgg-pro.h - 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.
*/
#ifndef SMSGG_PRO_H
#define SMSGG_PRO_H
extern const st_getopt2_t smsggpro_usage[];
#ifdef USE_PARALLEL
extern int smsgg_read_rom (const char *filename, unsigned int parport, int size);
extern int smsgg_write_rom (const char *filename, unsigned int parport);
extern int smsgg_read_sram (const char *filename, unsigned int parport, int start_bank);
extern int smsgg_write_sram (const char *filename, unsigned int parport, int start_bank);
#endif
#endif

View File

@ -1,46 +0,0 @@
/*
ssc.c - support for Super Smart Card
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/itypes.h"
#include "misc/misc.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "ucon64.h"
#include "ssc.h"
const st_getopt2_t ssc_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "Super Smart Card/SSC",
NULL
},
{NULL, 0, 0, 0, NULL, NULL, NULL}
};

View File

@ -1,34 +0,0 @@
/*
ssc.h - minimal support for Super Smart Card/SSC
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 SCC_H
#define SCC_H
extern const st_getopt2_t ssc_usage[];
typedef struct st_ssc_header
{
char pad[512];
} st_ssc_header_t;
#define SSC_HEADER_LEN (sizeof (st_ssc_header_t))
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,72 +0,0 @@
/*
swc.h - Super Wild Card 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.
*/
#ifndef SWC_H
#define SWC_H
#define SWC_IO_FORCE_32MBIT 0x001
#define SWC_IO_ALT_ROM_SIZE 0x002
#define SWC_IO_SUPER_FX 0x004
#define SWC_IO_SDD1 0x008
#define SWC_IO_SA1 0x010
#define SWC_IO_SPC7110 0x020
#define SWC_IO_DX2_TRICK 0x040
#define SWC_IO_MMX2 0x080
#define SWC_IO_DUMP_BIOS 0x100
#define SWC_IO_MAX 0x1ff // highest valid dumping mode value
extern const st_getopt2_t swc_usage[];
// For the header format, see ffe.h
typedef struct st_swc_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 emulation;
unsigned char pad[5];
unsigned char id1;
unsigned char id2;
unsigned char type;
unsigned char pad2[501];
} st_swc_header_t;
#define SWC_HEADER_START 0
#define SWC_HEADER_LEN (sizeof (st_swc_header_t))
#ifdef USE_PARALLEL
extern int swc_read_rom (const char *filename, unsigned int parport, int io_mode);
extern int swc_write_rom (const char *filename, unsigned int parport, int enableRTS);
extern int swc_read_sram (const char *filename, unsigned int parport);
extern int swc_write_sram (const char *filename, unsigned int parport);
extern int swc_read_rts (const char *filename, unsigned int parport);
extern int swc_write_rts (const char *filename, unsigned int parport);
extern int swc_read_cart_sram (const char *filename, unsigned int parport, int io_mode);
extern int swc_write_cart_sram (const char *filename, unsigned int parport, int io_mode);
extern void swc_unlock (unsigned int parport);
#endif
#endif // SWC_H

View File

@ -1,428 +0,0 @@
/*
tototek.c - General ToToTEK flash card programmer routines 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 "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 "tototek.h"
#ifdef USE_PARALLEL
static void set_data_read (void);
//static void set_data_write (void);
static void set_ai (unsigned char ai);
static void init_port (void);
static void deinit_port (void);
static void end_port (void);
static void set_addr_read (int addr);
static void set_addr_write (int addr);
static unsigned char get_id_byte (unsigned char addr);
static short int port_8, port_9, port_a, port_b, port_c;
void
ttt_init_io (unsigned int port)
{
#if (defined __unix__ || defined __BEOS__) && !defined __MSDOS__
init_conio ();
#endif
port_8 = port; // original code used 0x378 for port_8
port_9 = port + 1;
port_a = port + 2;
port_b = port + 3;
port_c = port + 4;
parport_print_info ();
init_port ();
}
void
ttt_deinit_io (void)
{
#if (defined __unix__ || defined __BEOS__) && !defined __MSDOS__
deinit_conio ();
#endif
end_port ();
deinit_port ();
}
void
set_data_read (void) // original name: set_data_read
{
outportb (port_a, 0); // nastb=1,nib_sel=0,ndstb=1,nwrite=1
}
#if 0
void
set_data_write (void) // original name: set_data_write
{
outportb (port_a, 1); // nastb=1,nib_sel=0,ndstb=1,nwrite=0
}
#endif
void
set_ai (unsigned char ai) // original name: {epp_}set_ai
{
outportb (port_a, 1); // set_data_write ()
outportb (port_b, ai);
}
void
ttt_set_ai_data (unsigned char ai, unsigned char data) // original name: set_ai_data
{
set_ai (ai);
outportb (port_a, 1); // set_data_write ()
outportb (port_c, data);
}
void
init_port (void) // original name: init_port
{
#ifndef USE_PPDEV
outportb ((unsigned short) (port_8 + 0x402),
(unsigned char) ((inportb ((unsigned short) (port_8 + 0x402)) & 0x1f) | 0x80));
outportb (port_9, 1); // clear EPP time flag
#endif
ttt_set_ai_data (6, 0); // rst=0, wei=0(dis.), rdi=0(dis.)
ttt_set_ai_data (6, 0x84); // rst=1, wei=0(dis.), rdi=0(dis.)
}
void
deinit_port (void) // original name: Close_end_port
{
outportb (port_a, 1);
outportb (port_b, 0);
outportb (port_a, 4); // port normal now
}
void
end_port (void) // original name: end_port
{
ttt_set_ai_data (6, 0); // rst=0, wei=0(dis.), rdi=0(dis.)
outportb (port_a, 4); // set_normal ninit=1, nwrite=1
}
void
ttt_rom_enable (void) // original name: romCS_on
{
ttt_set_ai_data (6, 0x84);
}
void
ttt_rom_disable (void) // original name: romCS_off
{
ttt_set_ai_data (6, 0x80);
}
void
ttt_ram_enable (void) // original name: ramCS_on
{
ttt_set_ai_data (6, 0x88);
}
void
ttt_ram_disable (void) // original name: ramCS_off
{
ttt_set_ai_data (6, 0x80);
}
void
set_addr_write (int addr) // original name: set_Long_adrw
{
ttt_set_ai_data (0, (unsigned char) (addr & 0xff)); // a[7..0]
addr >>= 8;
ttt_set_ai_data (1, (unsigned char) (addr & 0xff)); // a[15..8]
addr >>= 8;
ttt_set_ai_data (2, (unsigned char) (addr & 0xff)); // a[23..16]
set_ai (3);
}
void
set_addr_read (int addr) // original name: set_Long_adr
{
set_addr_write (addr);
set_data_read (); // ninit=0, nwrite=1
}
void
ttt_write_mem (int addr, unsigned char b) // original name: WriteMEMb
{
set_addr_write (addr);
outportb (port_c, b);
}
unsigned char
get_id_byte (unsigned char addr) // original name: GETID
{
unsigned char byte;
ttt_rom_enable ();
ttt_set_ai_data (0, addr); // a[7..0] = 0
set_ai (3);
outportb (port_c, 0x90); // write_data ()
set_ai (3);
set_data_read (); // ninit=0, nwrite=1
byte = inportb (port_c); // read_data ()
ttt_rom_disable ();
return byte;
}
unsigned short int
ttt_get_id (void) // original name: getIDword
{
unsigned short int word;
// eep_reset ();
word = get_id_byte (0); // msg
word <<= 8;
word |= get_id_byte (2); // ID
return word;
}
void
ttt_read_rom_b (int addr, unsigned char *buf) // original name: read_buffb
{
int count;
ttt_rom_enable ();
for (count = 0; count < 0x100; count++)
{
set_addr_read (addr + count);
buf[count] = inportb (port_c); // read_data ()
}
ttt_rom_disable ();
}
void
ttt_read_rom_w (int addr, unsigned char *buf) // original name: read_buff
{
int count;
set_addr_read (addr);
for (count = 0; count < 0x80; count++)
#ifdef WORDS_BIGENDIAN
((unsigned short int *) buf)[count] = bswap_16 (inportw (port_c)); // read_dataw ()
#else
((unsigned short int *) buf)[count] = inportw (port_c); // read_dataw ()
#endif
}
void
ttt_read_ram_b (int addr, unsigned char *buf) // original name: read_rambuff
{
int count;
ttt_ram_enable ();
for (count = 0; count < 0x100; count++)
{
set_addr_read (addr + count);
buf[count] = inportb (port_c); // read_data ()
}
ttt_ram_disable ();
}
void
ttt_read_ram_w (int addr, unsigned char *buf) // original name: readpagerambuff
{
int count;
set_addr_read (addr);
for (count = 0; count < 0x80; count++)
((unsigned short int *) buf)[count] = inportw (port_c);
// read_dataw (); data is doubled for MD-PRO => no problems with endianess
}
// Sharp function
void
ttt_erase_block (int addr) // original name: EraseBLOCK
{
ttt_rom_enable ();
ttt_write_mem (addr, 0x50);
ttt_rom_disable ();
ttt_rom_enable ();
ttt_write_mem (addr, 0x20);
outportb (port_c, 0xd0);
ttt_rom_disable ();
ttt_rom_enable ();
set_ai (3);
set_data_read (); // set read mode
while (inportb (port_c) < 0x80)
;
ttt_rom_disable ();
}
void
ttt_write_byte_sharp (int addr, unsigned char b) // original name: writeEEPDataB
{
ttt_rom_enable ();
ttt_write_mem (addr, 0x40);
outportb (port_c, b);
ttt_rom_disable ();
}
void
ttt_write_byte_intel (int addr, unsigned char b) // original name: writeIntelEEPDataB
{ // MD-PRO function
ttt_rom_enable ();
ttt_write_mem (addr, 0x40);
outportb (port_c, b);
set_data_read ();
while (inportb (port_c) < 0x80)
;
ttt_rom_disable ();
}
void
ttt_write_page_rom (int addr, unsigned char *buf) // original name: writeEEPDataPAGE
{
int i;
// send command 0xe8
ttt_rom_enable ();
ttt_write_mem (addr, 0xe8);
// read status
set_ai (3);
set_data_read ();
while (inportb (port_c) < 0x80)
;
set_ai (3);
outportb (port_c, 0x1f);
ttt_set_ai_data (6, 0x94);
set_addr_write (addr);
for (i = 0; i <= 0x1f; i++)
outportb (port_c, buf[(addr + i) & 0x3fff]);
ttt_set_ai_data (6, 0x84);
set_ai (3);
outportb (port_c, 0xd0);
// read status
set_ai (3);
set_data_read ();
while (inportb (port_c) < 0x80)
;
ttt_rom_disable ();
}
void
ttt_write_byte_ram (int addr, unsigned char b) // original name: writeRAMDataB
{
ttt_ram_enable ();
ttt_write_mem (addr, b);
ttt_ram_disable ();
}
void
ttt_write_page_ram (int addr, unsigned char *buf) // original name: writeRAMDataPAGE
{
int i;
ttt_ram_enable ();
ttt_set_ai_data (6, 0x98);
set_addr_write (addr);
for (i = 0; i < 0x100; i++)
outportb (port_c, buf[(addr + i) & 0x3fff]);
ttt_ram_disable ();
}
void
ttt_write_page_ram2 (int addr, unsigned char *buf) // original name: writeRAMDBDataPAGE
{ // MD-PRO function
int i;
ttt_ram_enable ();
ttt_set_ai_data (6, 0x98);
set_addr_write (addr * 2);
for (i = 0; i < 0x80; i++)
{
outportb (port_c, buf[(addr + i) & 0x3fff]);
outportb (port_c, buf[(addr + i) & 0x3fff]);
}
ttt_ram_disable ();
}
#if 0
void
readstatus (void)
{ // MD-PRO function
// send command 0xe8
ttt_rom_enable ();
set_ai (3);
set_data_read ();
while (inportb (port_c) < 0x80)
;
ttt_rom_disable ();
}
#endif
#endif // USE_PARALLEL

View File

@ -1,47 +0,0 @@
/*
tototek.h - General ToToTEK flash card programmer routines 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 TOTOTEK_H
#define TOTOTEK_H
#ifdef USE_PARALLEL
extern void ttt_init_io (unsigned int port);
extern void ttt_deinit_io (void);
extern void ttt_set_ai_data (unsigned char ai, unsigned char data);
extern void ttt_rom_enable (void);
extern void ttt_rom_disable (void);
extern void ttt_ram_enable (void);
extern void ttt_ram_disable (void);
extern void ttt_write_mem (int addr, unsigned char b);
extern unsigned short int ttt_get_id (void);
extern void ttt_read_rom_b (int addr, unsigned char *buf);
extern void ttt_read_rom_w (int addr, unsigned char *buf);
extern void ttt_read_ram_b (int addr, unsigned char *buf);
extern void ttt_read_ram_w (int addr, unsigned char *buf);
extern void ttt_erase_block (int addr);
extern void ttt_write_byte_sharp (int addr, unsigned char b);
extern void ttt_write_byte_intel (int addr, unsigned char b);
extern void ttt_write_page_rom (int addr, unsigned char *buf);
extern void ttt_write_byte_ram (int addr, unsigned char b);
extern void ttt_write_page_ram (int addr, unsigned char *buf);
extern void ttt_write_page_ram2 (int addr, unsigned char *buf);
#endif // USE_PARALLEL
#endif // TOTOTEK_H

View File

@ -1,45 +0,0 @@
/*
ufo.c - Super UFO 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 "ucon64.h"
#include "ufo.h"
const st_getopt2_t ufo_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "Super UFO Pro 8"/*"UFO Enterprises"*/,
NULL
},
{NULL, 0, 0, 0, NULL, NULL, NULL}
};

View File

@ -1,144 +0,0 @@
/*
ufo.h - Super UFO 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 UFO_H
#define UFO_H
extern const st_getopt2_t ufo_usage[];
/*
Super UFO Pro 8 Header Format (researched by John Weidman)
Byte-Offset Function
----------- ---------------------------------------------------
00-01 Chunk size: 04 00 == 4 Mbit (same format as the DX2)
02 LoROM games: 0x40 == continue loading another chunk after this one.
0x00 == This is the last chunk.
HiROM games: 0x40 == more work to figure this out -- maybe interleave info
0x10 == more work to figure this out -- maybe interleave info
0x00 == This is the last chunk.
03-07 0x00
08-0F 53 55 50 45 52 55 46 4F (SUPERUFO)
10 0x01 == This file is a ROM image file
11 ROM size: 04 == 4 Mb, 0x18 == 24 Mb, 0x20 == 32 Mb, etc.
12 ROM format: 00 == HiROM, 01 == LoROM
==== Start SRAM address mapping config ===============
13 SRAM Size:
00: 0Kb
01: 16Kb
02: 64Kb
03: 256Kb
04-07: Not used
08: XXXKb (Used for sram sizes above 256Kb, like 1024Kb)
14 SRAM A15 control:
00: A15 not used for SRAM control?
Use this for HiROM games
LoROM: Use this if SRAM size = 0Kb (no SRAM)
01: A15=X selects SRAM
02: A15=0 selects SRAM
03: A15=1 selects SRAM
15 SRAM A20 and A21 control:
Bits 3:2
00: A21=x selects SRAM
01: Not used?
10: A21=0 selects SRAM
11: A21=1 selects SRAM
Bits 1:0
00: A20=x selects SRAM
01: Not used?
10: A20=0 selects SRAM
11: A20=1 selects SRAM
16 SRAM A22 and A23 control:
Bits 3:2
00: A23=x selects SRAM
01: Not used?
10: A23=0 selects SRAM
11: A23=1 selects SRAM
Bits 1:0
00: A22=x selects SRAM
01: Not used?
10: A22=0 selects SRAM
11: A22=1 selects SRAM
17 SRAM type
0x00: Linear (HiROM)
0x03: Skip (LoROM)
==== End SRAM address mapping config ================
18-1FF 00
LoROM SRAM header
=========================================================
The SRAM mapping I would try first for LoROM games is:
0Kb SRAM
0012-0017 01 00 00 00 02 00
0Kb LoROM DSP
0012-0017 01 00 01 0C 00 03
Note: LoROM DSPs with SRAM don't seem to work on the Super UFO
(For reference, no LoROM DSP carts work on the SWC DX2)
Non 0 SRAM - default map (map low halves of banks 7x to SRAM)
0012-0017 01 ss 02 0F 03 03
Non 0 SRAM - alternate map (map all of banks 7x to SRAM -- will not work for > 28 Mbit
games )
0012-0017 01 ss 01 0F 03 03
HiROM SRAM header
==========================================================
0Kb SRAM
0012-0017 00 00 00 00 02 00
Non 0 SRAM
0012-0017 00 ss 00 0C 02 00 (Hopefully this will work for everything?)
If you find an SRAM protected game that doesn't work with the above mapping try:
0012-0017 00 ss 00 03 02 00 (seen in a couple of games but should work with above
mapping too)
--
For Tales of Phantasia or Dai Kaijyu Monogatari II
0012-0017 00 ss 00 00 0E 00 (Unverified)
*/
typedef struct st_ufo_header
{
unsigned char size_low;
unsigned char size_high;
unsigned char multi;
unsigned char pad[5];
unsigned char id[8]; // "SUPERUFO"
unsigned char isrom;
unsigned char size;
unsigned char banktype;
unsigned char sram_size;
unsigned char sram_a15;
unsigned char sram_a20_a21;
unsigned char sram_a22_a23;
unsigned char sram_type;
unsigned char pad2[488];
} st_ufo_header_t;
#define UFO_HEADER_LEN (sizeof (st_ufo_header_t))
#endif // UFO_H

View File

@ -1,46 +0,0 @@
/*
yoko.c - support for Yoko backup unit (Atari 2600, etc.)
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 "yoko.h"
const st_getopt2_t yoko_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "YOKO backup unit",
NULL
},
{NULL, 0, 0, 0, NULL, NULL, NULL}
};

View File

@ -1,26 +0,0 @@
/*
yoko.h - minimal support for Yoko backup unit (Atari 2600, etc.)
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 YOKO_H
#define YOKO_H
extern const st_getopt2_t yoko_usage[];
#endif

View File

@ -1,46 +0,0 @@
/*
z64.c - Mr. Backup Z64 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 "z64.h"
const st_getopt2_t z64_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "Mr. Backup Z64",
NULL
},
{NULL, 0, 0, 0, NULL, NULL, NULL}
};

View File

@ -1,26 +0,0 @@
/*
z64.h - Z64 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 Z64_H
#define Z64_H
extern const st_getopt2_t z64_usage[];
#endif

View File

@ -1,128 +0,0 @@
/* config.h.in. Generated from configure.in by autoheader. */
/* enable debug output (default: no) */
#undef DEBUG
/* enable dynamic loading of add-on libraries (default: yes) */
#undef DLOPEN
/* Define to 1 if you have the <byteswap.h> header file. */
#undef HAVE_BYTESWAP_H
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
#undef HAVE_DIRENT_H
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
#undef HAVE_DOPRNT
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
#undef HAVE_NDIR_H
/* Define to 1 if you have the `realpath' function. */
#undef HAVE_REALPATH
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strftime' function. */
#undef HAVE_STRFTIME
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
*/
#undef HAVE_SYS_DIR_H
/* Define to 1 if you have the <sys/io.h> header file. */
#undef HAVE_SYS_IO_H
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/
#undef HAVE_SYS_NDIR_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the `vprintf' function. */
#undef HAVE_VPRINTF
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* enable usage of color (default: yes) */
#undef USE_ANSI_COLOR
/* enable libdiscmage (default: yes) */
#undef USE_DISCMAGE
/* enable libcd64 (default: no) */
#undef USE_LIBCD64
/* enable support for parallel port backup units (default: yes) */
#undef USE_PARALLEL
/* use ppdev for parallel port I/O (default: no) */
#undef USE_PPDEV
/* build with (lib)usb support (default: no) */
#undef USE_USB
/* build with gzip and zip support (default: yes) */
#undef USE_ZLIB
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
/* Define to `int' if <sys/types.h> doesn't define. */
#undef gid_t
/* Define as `__inline' if that's what the C compiler calls it, or to nothing
if it is not supported. */
#undef inline
/* Define to `int' if <sys/types.h> does not define. */
#undef pid_t
/* Define to `unsigned' if <sys/types.h> does not define. */
#undef size_t
/* Define to `int' if <sys/types.h> doesn't define. */
#undef uid_t

View File

@ -1,129 +0,0 @@
/* config.h. Generated by configure. */
/* config.h.in. Generated from configure.in by autoheader. */
/* enable debug output (default: no) */
/* #undef DEBUG */
/* enable dynamic loading of add-on libraries (default: yes) */
#define DLOPEN 1
/* Define to 1 if you have the <byteswap.h> header file. */
/* #undef HAVE_BYTESWAP_H */
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
#define HAVE_DIRENT_H 1
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
/* #undef HAVE_DOPRNT */
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
/* #undef HAVE_INTTYPES_H */
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
/* #undef HAVE_NDIR_H */
/* Define to 1 if you have the `realpath' function. */
/* #undef HAVE_REALPATH */
/* Define to 1 if you have the <stdint.h> header file. */
/* #undef HAVE_STDINT_H */
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `strftime' function. */
#define HAVE_STRFTIME 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
*/
/* #undef HAVE_SYS_DIR_H */
/* Define to 1 if you have the <sys/io.h> header file. */
/* #undef HAVE_SYS_IO_H */
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/
/* #undef HAVE_SYS_NDIR_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the `vprintf' function. */
#define HAVE_VPRINTF 1
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "noisyb@gmx.net"
/* Define to the full name of this package. */
#define PACKAGE_NAME "uCON64"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "uCON64 2.0.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "ucon64"
/* Define to the version of this package. */
#define PACKAGE_VERSION "2.0.0"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* enable usage of color (default: yes) */
#define USE_ANSI_COLOR 1
/* enable libdiscmage (default: yes) */
#define USE_DISCMAGE 1
/* enable libcd64 (default: no) */
#define USE_LIBCD64 1
/* enable support for parallel port backup units (default: yes) */
#define USE_PARALLEL 1
/* use ppdev for parallel port I/O (default: no) */
/* #undef USE_PPDEV */
/* build with (lib)usb support (default: no) */
/* #undef USE_USB */
/* build with gzip and zip support (default: yes) */
//#define USE_ZLIB 1
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `int' if <sys/types.h> doesn't define. */
/* #undef gid_t */
/* Define as `__inline' if that's what the C compiler calls it, or to nothing
if it is not supported. */
/* #undef inline */
/* Define to `int' if <sys/types.h> does not define. */
/* #undef pid_t */
/* Define to `unsigned' if <sys/types.h> does not define. */
/* #undef size_t */
/* Define to `int' if <sys/types.h> doesn't define. */
/* #undef uid_t */

View File

@ -1,129 +0,0 @@
/* config.h. Generated by configure. */
/* config.h.in. Generated from configure.in by autoheader. */
/* enable debug output (default: no) */
/* #undef DEBUG */
/* enable dynamic loading of add-on libraries (default: yes) */
#define DLOPEN 1
/* Define to 1 if you have the <byteswap.h> header file. */
/* #undef HAVE_BYTESWAP_H */
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
/* #undef HAVE_DIRENT_H */
/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
/* #undef HAVE_DOPRNT */
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
/* #undef HAVE_INTTYPES_H */
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
/* #undef HAVE_NDIR_H */
/* Define to 1 if you have the `realpath' function. */
/* #undef HAVE_REALPATH */
/* Define to 1 if you have the <stdint.h> header file. */
/* #undef HAVE_STDINT_H */
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `strftime' function. */
#define HAVE_STRFTIME 1
/* Define to 1 if you have the <strings.h> header file. */
/* #undef HAVE_STRINGS_H */
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
*/
/* #undef HAVE_SYS_DIR_H */
/* Define to 1 if you have the <sys/io.h> header file. */
/* #undef HAVE_SYS_IO_H */
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
*/
/* #undef HAVE_SYS_NDIR_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <unistd.h> header file. */
/* #undef HAVE_UNISTD_H */
/* Define to 1 if you have the `vprintf' function. */
#define HAVE_VPRINTF 1
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT "noisyb@gmx.net"
/* Define to the full name of this package. */
#define PACKAGE_NAME "uCON64"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "uCON64 2.0.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "ucon64"
/* Define to the version of this package. */
#define PACKAGE_VERSION "2.0.0"
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* enable usage of color (default: yes) */
#define USE_ANSI_COLOR 1
/* enable libdiscmage (default: yes) */
#define USE_DISCMAGE 1
/* enable libcd64 (default: no) */
#define USE_LIBCD64 1
/* enable support for parallel port backup units (default: yes) */
#define USE_PARALLEL 1
/* use ppdev for parallel port I/O (default: no) */
/* #undef USE_PPDEV */
/* build with (lib)usb support (default: no) */
/* #undef USE_USB */
/* build with gzip and zip support (default: yes) */
//#define USE_ZLIB 1
/* Define to empty if `const' does not conform to ANSI C. */
/* #undef const */
/* Define to `int' if <sys/types.h> doesn't define. */
/* #undef gid_t */
/* Define as `__inline' if that's what the C compiler calls it, or to nothing
if it is not supported. */
/* #undef inline */
/* Define to `int' if <sys/types.h> does not define. */
/* #undef pid_t */
/* Define to `unsigned' if <sys/types.h> does not define. */
/* #undef size_t */
/* Define to `int' if <sys/types.h> doesn't define. */
/* #undef uid_t */

View File

@ -1,4 +0,0 @@
export CFLAGS="-I/opt/local/include"
export LDFLAGS="-L/opt/local/lib"
./configure --with-libusb --disable-discmage
make -j 3 clean all

View File

@ -1,2 +0,0 @@
./configure --with-libusb --disable-discmage
make -j 2 clean all

File diff suppressed because it is too large Load Diff

View File

@ -1,183 +0,0 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(uCON64, 2.0.0, noisyb@gmx.net)
AC_CONFIG_HEADER(config.h libdiscmage/config.h)
dnl Checks for programs.
AC_PROG_CC(gcc egcs cc)
AC_PROG_GCC_TRADITIONAL
AC_MSG_CHECKING(whether debug output is enabled)
AC_ARG_ENABLE(debug,
AC_HELP_STRING([--enable-debug],
[enable debug output (default: no)]),
enable_debug=$enableval,
enable_debug=no)
if test $enable_debug = yes; then
AC_DEFINE(DEBUG, 1, [enable debug output (default: no)])
fi
AC_MSG_RESULT($enable_debug)
AC_MSG_CHECKING(whether support for parallel port backup units is enabled)
AC_ARG_ENABLE(parallel,
AC_HELP_STRING([--enable-parallel],
[enable support for parallel port backup units (default: yes)]),
enable_parallel=$enableval,
enable_parallel=yes)
if test $enable_parallel = yes; then
AC_DEFINE(USE_PARALLEL, 1, [enable support for parallel port backup units (default: yes)])
fi
AC_MSG_RESULT($enable_parallel)
dnl AC_MSG_CHECKING(whether support for serial port backup units is enabled)
dnl AC_ARG_ENABLE(serial,
dnl AC_HELP_STRING([--enable-serial],
dnl [enable support for serial port backup units (default: yes)]),
dnl enable_serial=$enableval,
dnl enable_serial=yes)
dnl if test $enable_serial = yes; then
dnl AC_DEFINE(USE_SERIAL, 1, [enable support for serial port backup units (default: yes)])
dnl fi
dnl AC_MSG_RESULT($enable_serial)
AC_MSG_CHECKING(whether to use ppdev)
AC_ARG_ENABLE(ppdev,
AC_HELP_STRING([--enable-ppdev],
[use ppdev for parallel port I/O (default: no)]),
enable_ppdev=$enableval,
enable_ppdev=no)
if test $enable_ppdev = yes; then
AC_TRY_COMPILE([#include <linux/ppdev.h>], , enable_ppdev=yes, enable_ppdev=no)
fi
if test $enable_ppdev = yes; then
AC_DEFINE(USE_PPDEV, 1, [use ppdev for parallel port I/O (default: no)])
fi
AC_MSG_RESULT($enable_ppdev)
AC_MSG_CHECKING(whether the use of color is enabled)
AC_ARG_ENABLE(ansi_color,
AC_HELP_STRING([--enable-ansi-color],
[enable usage of color (default: yes)]),
enable_ansi_color=$enableval,
enable_ansi_color=yes)
if test $enable_ansi_color = yes; then
AC_DEFINE(USE_ANSI_COLOR, 1, [enable usage of color (default: yes)])
fi
AC_MSG_RESULT($enable_ansi_color)
AC_MSG_CHECKING(whether add-on libraries are dynamically loaded)
AC_ARG_ENABLE(dload,
AC_HELP_STRING([--enable-dload],
[enable dynamic loading of add-on libraries (default: yes)]),
enable_dload=$enableval,
enable_dload=yes)
if test $enable_dload = yes; then
AC_DEFINE(DLOPEN, 1, [enable dynamic loading of add-on libraries (default: yes)])
DEFINE_DLOPEN_MAKE="DLOPEN=1"
fi
AC_MSG_RESULT($enable_dload)
AC_SUBST(DEFINE_DLOPEN_MAKE)
AC_MSG_CHECKING(whether libdiscmage is enabled)
AC_ARG_ENABLE(discmage,
AC_HELP_STRING([--enable-discmage],
[enable libdiscmage (default: yes)]),
enable_discmage=$enableval,
enable_discmage=yes)
if test $enable_discmage = yes; then
AC_DEFINE(USE_DISCMAGE, 1, [enable libdiscmage (default: yes)])
DEFINE_DISCMAGE_MAKE="USE_DISCMAGE=1"
fi
AC_MSG_RESULT($enable_discmage)
AC_SUBST(DEFINE_DISCMAGE_MAKE)
dnl This belongs here, not at the checks for libraries. We don't have to check
dnl if libcd64 is present as it is part of our source tree.
AC_MSG_CHECKING(whether libcd64 is enabled)
AC_ARG_ENABLE(libcd64,
AC_HELP_STRING([--enable-libcd64],
[enable libcd64 (default: no)]),
enable_libcd64=$enableval,
enable_libcd64=no)
if test $enable_libcd64 = yes; then
AC_DEFINE(USE_LIBCD64, 1, [enable libcd64 (default: no)])
DEFINE_LIBCD64_MAKE="USE_LIBCD64=1"
else
dnl libi386 is necessary under OpenBSD, but only if libcd64 isn't enabled. The
dnl reason is that libcd64 already includes libi386.
LIBI386_MAKE="-li386"
fi
AC_MSG_RESULT($enable_libcd64)
AC_SUBST(DEFINE_LIBCD64_MAKE)
AC_SUBST(LIBI386_MAKE)
dnl Checks for libraries.
AC_MSG_CHECKING(for zlib)
AC_ARG_WITH(zlib,
AC_HELP_STRING([--with-zlib],
[build with gzip and zip support (default: yes)]),
with_zlib=$withval,
with_zlib=yes)
if test $with_zlib = yes; then
AC_TRY_COMPILE([#include <zlib.h>], , with_zlib=yes, with_zlib=no)
fi
if test $with_zlib = yes; then
AC_DEFINE(USE_ZLIB, 1, [build with gzip and zip support (default: yes)])
DEFINE_ZLIB_MAKE="USE_ZLIB=1"
fi
AC_MSG_RESULT($with_zlib)
AC_SUBST(DEFINE_ZLIB_MAKE)
AC_MSG_CHECKING(for libusb)
AC_ARG_WITH(libusb,
AC_HELP_STRING([--with-libusb],
[build with (lib)usb support (default: no)]),
with_libusb=$withval,
with_libusb=no)
if test $with_libusb = yes; then
AC_TRY_COMPILE([#include <usb.h>], , with_libusb=yes, with_libusb=no)
fi
if test $with_libusb = yes; then
AC_DEFINE(USE_USB, 1, [build with (lib)usb support (default: no)])
DEFINE_USB_MAKE="USE_USB=1"
fi
AC_MSG_RESULT($with_libusb)
AC_SUBST(DEFINE_USB_MAKE)
dnl Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_CHECK_HEADERS(fcntl.h unistd.h byteswap.h inttypes.h sys/io.h)
dnl NOT zlib.h! Or else --with[out]-zlib gets overrriden in config.h.
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_TYPE_UID_T
AC_C_INLINE
AC_TYPE_PID_T
AC_TYPE_SIZE_T
dnl Checks for library functions.
AC_FUNC_MEMCMP
AC_FUNC_STRFTIME
AC_FUNC_VPRINTF
AC_CHECK_FUNCS(realpath)
AC_PROG_RANLIB
AC_PROG_INSTALL
AC_OUTPUT(Makefile libdiscmage/Makefile)
echo
echo NOTE: On non-Linux systems you might need to use gmake instead of make

View File

@ -1,65 +0,0 @@
351258: UNROM
351298: UNROM
351908
352026: TLROM (w/ LS32 for VROM enable control)
51555: Acclaim, MMC3B mapper, PRG ROM, CHR ROM
53361
54425
55741
56504
AMROM: LS161, VRAM, PRG-ROM
ANROM: LS161+LS02 mapper, PRG-ROM, CHR-RAM
AOROM: LS161 mapper, PRG-ROM, CHR-ROM
BNROM: LS161, VRAM, PRG-ROM (Different LS161 bits? Only used on Deadly Towers)
CNROM: LS161 mapper, PRG-ROM, CHR-ROM?/CHR-RAM
COB: "Glop Top" style board
CPROM: LS04, LS08, LS161, 32K ROM, 16K VRAM (bankswitched, Videomation only)
DEIROM
DEROM
DRROM: MMC3, 4K of nametable RAM (for 4-screen), PRG-ROM, CHR-ROM (only in Gauntlet)
EKROM
ELROM: MMC5, PRG-ROM, CHR-ROM
ETROM: MMC5, PRG-ROM, CHR-ROM, 2x 8k optionnal RAM (battery)
EWROM: MMC5, PRG-ROM, CHR-ROM, 32k optionnal RAM (battery)
GNROM: LS161 mapper, PRG ROM, CHR ROM
HKROM: MMC6B, PRG-ROM, CHR-ROM, Battery
MHROM: LS161 mapper, black blob chips. Mario Bros / Duck Hunt multi
NES-B4: Same as TLROM
NES-BTR: Sunsoft FME7 mapper, PRG ROM, CHR ROM, 8k optionnal RAM
NES-QJ:
NES-RROM: Same as NROM (Only used in Clu Clu land)
NROM: No mapper, PRG-ROM, CHR-ROM
PNROM: MMC2, PRG-ROM, CHR-ROM
SAROM: MMC1B, PRG ROM, CHR ROM, optional 8k of RAM (battery)
SBROM: MMC1A, PRG ROM, CHR ROM (only 32K of CHR ROM)
SCEOROM
SC1ROM: MMC1B, PRG ROM, CHR ROM
SCROM: LS161, LS02, VRAM, PRG-ROM (Similar to UNROM)
SEROM: MMC1B, PRG ROM, CHR ROM
SFROM
SGROM: MMC1B, PRG ROM, 8k CHR RAM
SHROM
SJROM
SKROM: MMC1B, PRG ROM, CHR ROM, 8k optional RAM (battery)
SL1ROM: MMC3, PRG ROM, CHR ROM, LS32 (for 128K 28 pin CHR ROMs)
SL2ROM
SL3ROM
SLROM: MMC1A, PRG ROM, CHR ROM
SLRROM
SN1-ROM AW (Overlord only)
SNROM: MMC1A, PRG ROM, CHR ROM/RAM ?, 8k optional RAM (battery)
SOROM: MMC1B2, PRG ROM, VRAM, 16K of WRAM (Battery) Only 8K battery-backed
SVROM: MMC1B2, PRG ROM, VRAM, WRAM (Battery)
SUROM: MMC1B2, PRG ROM, CHR RAM/(ROM?), 8k battery-backed RAM (DW4???)
TEROM: MMC3A, PRG ROM, CHR ROM, (32k ROMs)
TFROM: MMC3B, PRG ROM, CHR ROM (64K of CHR only)
TGROM: MMC3C, PRG ROM, VRAM (512K of PRG)
TKROM: MMC3A, PRG ROM, CHR ROM, 8k optional RAM (battery)
TL1ROM: Same as TLROM
TLROM: MMC3B, PRG ROM, CHR ROM
TLSROM: Same as TLROM
TQROM: MMC3B+74HC32, PRG ROM, CHR ROM + 8k of CHR-RAM
TSROM: MMC3A, PRG ROM, CHR ROM, 8k optionnal RAM
TVROM: MMC3B, PRG ROM, CHR ROM, 4K of Nametable RAM (4-screen)
UNROM: 74LS32+74LS161 mapper, 128k PRG, 8k CHR-RAM
UOROM

View File

@ -1,782 +0,0 @@
Name |Maker |RR|Board
--------------------------------------+--------------------+--+----------------
10 Yard Fight |Nintendo |E |NROM
110 in 1 (Canada?) |Supervision | |
1942 |Capcom |C+|NROM
1943 |Capcom |C+|UNROM
6 in 1 |Caltron |A |
720 |Mindscape |C |SGROM
8 Eyes |Taxan |C-|TLROM
A Boy and His Blob |Absolute |C |SLROM
Abadox |Milton Bradley |C |SLROM
Action 52 |Active Enterprises |A |
Addams Family |Ocean |B |SLROM
Adv of Bayou Billy |Konami |C-|SLROM
Adv of Dino Riki |Hudson |C |CNROM
Adv of Lolo |HAL |C+|SEROM
Adv of Lolo 2 |HAL |B-|TEROM
Adv of Lolo 3 |HAL |B+|SLROM
Adv of Tom Saywer |Seta |B |SLROM
Adventure Island |Hudson |D |CNROM
Adventure Island 2 |Hudson |B-|TLROM
Adventure Island 3 |Hudson |B |TLROM
After Burner |Tengen |C+|
Air Fortress |HAL |C |SJROM
Airwolf |Acclaim |C |SHROM
Al Unser Racing |Data East |C |SKROM
Aladdin Deck Enhancer |Camerica |A+|
Alfred Chicken |Mindscape |B+|UNROM
Alien 3 |LJN |B+|55741
Alien Syndrome |Tengen |C+|
All Pro Basketball |Vic Tokai |C |SLROM
Alpha Mission |SNK |C |CNROM
Amagon |American Sammy |C |UNROM
American Gladiators |Gametek |B-|SLROM
Anticipation |Nintendo |C |SEROM
Arch Rivals |Acclaim |C |AMROM
Archon |Activision |B |UNROM
Arkanoid |Taito |B+|CNROM
Arkanoid Controller |Taito |A |
Arkistas Ring |American Sammy |B |CNROM
Astyanax |Jaleco |C |TLROM
Athena |SNK |C |UNROM
Athletic World |Bandai |B-|CNROM
Attack/Killer Tomato |T*HQ |B-|SLROM
Baby Boomer |Color Dreams |B-|
Back to the Future |LJN |D |CNROM
Back to the Future 2 & 3 |LJN |C |SLROM
Bad Dudes |Data East |C |TLROM
Bad News Baseball |Tecmo |B |SLROM
Bad Street Brawler |Mattel |C |SGROM
Balloon Fight |Nintendo |C |NROM
Bandit Kings/China |Koei |B-|ETROM
Barbie |Hi Tech |B |SLROM
Bard's Tale |FCI |B-|SNROM
Base Wars |Ultra |C |TKROM
Baseball |Nintendo |E |NROM
Baseball Simulator |Culture Brain |C+|SKROM
Baseball Stars |SNK |C+|SKROM
Baseball Stars 2 |Romstar |B+|TKROM
Bases Loaded |Jaleco |E |SFROM
Bases Loaded 2 |Jaleco |D |SL3ROM
Bases Loaded 3 |Jaleco |C |TLROM
Bases Loaded 4 |Jaleco |C+|TLROM
Batman |Sunsoft |D |NES_B4
Batman Return/Joker |Sunsoft |B-|NES_BTR
Batman Returns |Konami |B+|TLROM
Battle Chess |Data East |B+|SKROM
Battle of Olympus |Broderbund |C |SGROM
Battle Tank |Absolute |B |CNROM
Battle Toads |Tradewest |D |AOROM
Battle Toads & Double Dragon |Tradewest |B+|AOROM
Battleship |Mindscape |B |CNROM
Bee 52 |Camerica |B+|
Beetlejuice |LJN |C+|AMROM
Best of the Best |Electro Brain |B+|UOROM
Bible Adventures |Wisdom Tree |B+|
Bible Adventures (blue label) |Wisdom Tree |B+|
Bible Buffet |Wisdom Tree |B+|
Big Bird Hide & Speak |Hi Tech |B |SLROM
Big Foot |Acclaim |B-|SLROM
Big Nose Freaks Out |Camerica |A |
Big Nose Freaks Out (Aladdin Cart) |Camerica |A+|
Big Nose the Caveman |Camerica |B |
Bill & Ted Adventure |LJN |C+|SLROM
Bill Elliot NASCAR |Konami |C+|TSROM
Bionic Commando |Capcom |C |SGROM
Black Bass |Hot B |B |UNROM
Blackjack |American Video |A-|
Blades of Steel |Konami |D |UNROM
Blaster Master |Sunsoft |D |SL2ROM
Blue Marlin |Hot B |B+|TLROM
Blues Brothers |Titus |B |UNROM
Bo Jackson Baseball |Data East |C+|TSROM
Bomberman |Hudson |C |NROM
Bomberman 2 |Hudson |B |SNROM
Bonks Adventure |Hudson |B+|TLROM
Boulder Dash |JVC |B+|SEROM
Break Time |FCI |B+|SFROM
Breakthru |Data East |C |(SLROM)
Bubble Bath Babes |Panesian |A+|
Bubble Bobble |Taito |D |SFROM
Bubble Bobble 2 |Taito |B |TLROM
Bucky O'Hare |Konami |B |TLROM
Bugs Bunny Birthday Blowout |Kemco |B |TSROM
Bugs Bunny Castle |Kemco |B+|SBROM
Bump & Jump |Vic Tokai |B-|CNROM
Burai Fighter |Taxan |B-|TEROM
Burger Time |Data East |B-|NROM
Cabal |Milton Bradley |C |AMROM
Caesars Palace |Virgin |B |UNROM
California Games |Milton Bradley |C |UNROM
Captain America |Data East |B |TLROM
Captain Comic |Color Dreams |B |
Captain Planet |Mindscape |B |TLROM
Captain Skyhawk |Milton Bradley |C |AMROM
Casino Kid |Sofel |C+|UNROM
Casino Kid 2 |Sofel |B+|UNROM
Castelian |Triffix |B |UNROM
Castle of Deceit |Bunch Games |B |
Castle of Dragon |Seta |B |UNROM
Castlequest |Nexoft |B |CNROM
Castlevania |Konami |E |UNROM
Castlevania 2 |Konami |D |SLROM
Castlevania 3 |Konami |C-|ELROM
Caveman Games |Data East |B-|SLROM
Challenge of the Dragon |Color Dreams |B |
Championship Bowling |Romstar |B |CNROM
Championship Pool |Mindscape |B+|UNROM
Cheetahman II |Active Enterprises |A |
Chessmaster |Hi Tech |B |SJROM
Chiller |American Game Carts Inc|B+|
Chubby Cherub |Bandai |B |NROM
Circus Caper |Toho |B |SLROM
City Connection |Jaleco |B |CNROM
Clash at Demonhead |Vic Tokai |B-|SLROM
Classic Concentration |Gametek |B-|UNROM
Cliffhanger |Imagesoft |B |TLROM
Clu Clu Land |Nintendo |B-|NES_RROM
Cobra Command |Data East |C |SLROM
Cobra Triangle |Nintendo |B-|ANROM
Codename Viper |Capcom |C |TLROM
Color A Dinosaur |Virgin |A-|UNROM
Commando |Capcom |C |UNROM
Conan |Mindscape |B |UNROM
Conflict |Vic Tokai |C+|SKROM
Conquest Crystal Palace |Asmik |C+|TLROM
Contra |Konami |E |UNROM
Contra Force |Konami |B |TLROM
Cool World |Ocean |B |SLROM
Cowboy Kid |Romstar |A-|TLROM
Crash & the Boys Street Challange |American Technos |B |TLROM
Crash Dummies |LJN |B |55741
Crystal Mines |Color Dreams |B+|
Crystalis |SNK |C |TKROM
Cyberball |Jaleco |B |TLROM
Cybernoid |Acclaim |C |CNROM
Dance Aerobics |Nintendo |C+|SBROM
Darkman |Ocean |B |SLROM
Darkwing Duck |Capcom |B+|SLROM
Dash Galaxy |Data East |C |CNROM
Day Dreamin' Davey |HAL |B+|SLROM
Days of Thunder |Mindscape |C+|TLROM
Deadly Towers |Broderbund |C+|BNROM
Death Race |American Game Carts Inc|B+|
Deathbots |American Video |B+|
Defender 2 |HAL |B |NROM
Defender of the Crown |Ultra |C+|SGROM
Defenders of Dynacron City |JVC |B |TLROM
Deja Vu |Kemco |C+|TKROM
Demon Sword |Taito |C+|SL1ROM
Desert Commander |Kemco |C-|SKROM
Destination Earthstar |Acclaim |C |CNROM
Destiny/Emporer |Capcom |B-|SNROM
Dick Tracy |Bandai |C+|UNROM
Die Hard |Activision |B+|SLROM
Dig Dug 2 |Bandai |B |NROM
Digger |Milton Bradley |B+|AMROM
Dirty Harry |Mindscape |C+|TLROM
Disney Adventure |Capcom |B |SLROM
Dizzy the Adventurer (Aladdin Cart) |Camerica |A+|
Donkey Kong |Nintendo |B-|NROM
Donkey Kong 3 |Nintendo |B-|NROM
Donkey Kong Classics |Nintendo |B-|CNROM
Donkey Kong Jr |Nintendo |B-|NROM
Donkey Kong Jr Math |Nintendo |A-|NROM
Double Dare |Gametek |B |AOROM
Double Dragon |Tradewest |E |SLROM
Double Dragon 2 |Acclaim |D |TL1ROM
Double Dragon 3 |Acclaim |C+|TLROM
Double Dribble |Konami |D |UNROM
Double Strike |American Video |B+|
Dr. Chaos |FCI |C |UNROM
Dr. Jeckyl/Mr. Hyde |Bandai |C+|SFROM (SFDOROM)
Dr. Mario |Nintendo |D |SEROM
Dracula |Imagesoft |B |TSROM
Dragon Fighter |Sofel |B |SLROM
Dragon Power |Bandai |C |GNROM
Dragon Spirit |Bandai |B |TLROM
Dragon Strike |FCI |C |TLROM
Dragon Warrior |Nintendo |E |SAROM
Dragon Warrior 2 |Enix |C+|SNROM
Dragon Warrior 3 |Enix |B+|SVROM
Dragon Warrior 4 |Enix |B |SVROM
Dragon's Lair |Imagesoft |B |UNROM
Duck Hunt |Nintendo |F |NROM
Duck Tales |Capcom |C+|UNROM
Duck Tales 2 |Capcom |B+|UNROM
Dudes with Attitude |American Video |B+|
Dungeon Magic |Taito |C |SKROM
Dusty Diamond All Star Softball |Broderbund |B-|SLROM
Dyno Warz |Bandai |C+|SLROM
Elevator Action |Taito |B-|NROM
Eliminator Boat Duel |Electro Brain |C+|SLROM
Empire Strikes Back |JVC |B |TLROM
Excitebike |Nintendo |E |NROM
Exodus |Wisdom Tree |B+|
F 117 Stealth |Microprose |B+|TLROM
F 15 City War |American Video |B |
F 15 Strike Eagle |Microprose |B+|TLROM
F1 Built to Win |Seta |B+|SKROM
Family Feud |Gametek |B+|SHROM
Fantastic Adv Dizzy (Aladdin Cart) |Camerica |A+|
Fantastic Adventures of Dizzy |Camerica |B-|
Fantasy Zone |Tengen |C |
Faria |Nexoft |B+|SKROM
Fast Break |Tradewest |C |SCROM
Faxanadu |Nintendo |C-|SGROM
Felix the Cat |Hudson |B+|TSROM
Ferrari Grand Prix |Acclaim |B |SLROM
Fester's Quest |Sunsoft |C |SLROM
Fighting Golf |SNK |C |SLROM
Final Fantasy |Nintendo |C+|SNROM
Fire & Ice |Tecmo |A-|TLROM
Fire Hawk |Camerica |B |
Firehouse Rescue |Gametek |B |CNROM
Fist of the North Star |Taxan |C+|UNROM
Flight of the Intruder |Mindscape |B |UNROM
Flintstones |Taito |C+|TLROM
Flintstones 2 |Taito |A+|
Flying Dragon |Culture Brain |C |UNROM
Flying Warriors |Culture Brain |C |SLROM
Frankenstein |Bandai |B+|SLRROM
Freedom Force |Sunsoft |D |SLROM
Friday The 13th |LJN |C-|CNROM
Fun House |Hi Tech |B+|UNROM
G I Joe |Taxan |B+|TLROM
G I Joe Atlantis Factor |Capcom |C+|TLROM
Galactic Crusader |Bunch Games |B |
Galaga |Bandai |B |NROM
Galaxy 5000 |Activision |A-|TLROM
Game Action Replay |STD |A-|
Game Genie |Galoob |D |
Gargoyle's Quest 2 |Capcom |B+|TLROM
Gauntlet (licensed) |Tengen |C |DRROM
Gauntlet (unlicensed) |Tengen |C |
Gauntlet 2 |Mindscape |C |TSROM
Gemfire |Koei |B-|EKROM
Genghis Kahn |Koei |C+|SOROM
George Forman |Acclaim |B |55741
Ghost & Goblins |Capcom |C |UNROM
Ghost Lion |Kemco |B |SKROM
Ghostbusters |Activision |B-|CNROM
Ghostbusters 2 |Activision |B |SLROM
Ghoul School |Electro Brain |B-|SLROM
Gilligans Island |Bandai |B+|UNROM
Goal |Jaleco |D |SL3ROM
Goal 2 |Jaleco |B-|TLSROM
Godzilla |Toho |C+|SLROM
Godzilla 2 |Toho |B |SLROM
Gold Metal Challenge |Capcom |B+|TKROM
Golf |Nintendo |E |NROM
Golf Grand Slam |Atlus |B+|SLROM
Golf Power |Virgin |B+|SNROM
Golgo 13 Top Secret Episode |Vic Tokai |D |SLROM
Goonies 2 |Konami |C+|351258
Gotcha |LJN |C |CNROM
Gradius |Konami |C-|CNROM
Great Waldo Search |T*HQ |B-|SLROM
Gremlins 2 |Sunsoft |B-|TLROM
Guardian Legend |Broderbund |C+|UNROM
Guerrilla War |SNK |C |SLROM
Gum Shoe |Nintendo |C+|GNROM
Gun Nac |Ascii |B |TLROM
Gunsmoke |Capcom |B-|UNROM
Gyromite |Nintendo |E |NROM
Gyruss |Ultra |C+|CNROM
Harlem Globetrotters |Gametek |B |SLROM
Hatris |Bullet Proof |A |SNROM
Heavy Barrel |Data East |C |TLROM
Heavy Shreddin' |Parker Brothers |B-|SLROM
Heroes of the Lance |FCI |C |SKROM
High Speed |Tradewest |B-|TQROM
Hillsfar |FCI |B |SNROM
Hogan's Alley |Nintendo |D |NROM
Hollywood Squares |Gametek |B+|UNROM
Home Alone |T*HQ |B-|TSROM
Home Alone 2 |T*HQ |B-|TLROM
Hook |Imagesoft |B |SLROM
Hoops |Jaleco |D |SLROM
Hot Slots |Panesian |A+|
Hudson Hawk |Imagesoft |B |SLROM
Hunt for Red October |Hi Tech |C |TLROM
Hydlide |FCI |D |NROM
I Can Remember |Gametek |B |CNROM
Ice Climber |Nintendo |C+|NROM
Ice Hockey |Nintendo |D |NROM
Ikari Warriors |SNK |C-|UNROM
Ikari Warriors 2 |SNK |C-|SGROM
Ikari Warriors 3 |SNK |B-|SLROM
Image Fight |Irem |B |TSROM
Immortal |Electronic Arts |B |TLROM
Impossible Mission 2 |American Video |A-|
Impossible Mission 2 |SEI |B+|
Indiana Jones Last Crusade |UBI Soft |B+|UNROM
Indiana Jones Last Crusade |Taito |B+|SGROM
Indiana Jones Temple of Doom |Tengen |B-|
Indiana Jones Temple of Doom |Mindscape |C |TFROM
Indy Heat |Tradewest |B |AMROM
Infiltrator |Mindscape |B |TLROM
Iron Tank |SNK |C |SLROM
Isolated Warrior |NTVIC |B |TLROM
Jack Nicklaus Golf |Konami |B-|351258
Jackal |Konami |C |UNROM
Jackie Chan Kung Fu |Hudson |B |TLROM
James Bond Jr |T*HQ |B-|TLROM
Jaws |LJN |D |CNROM
Jeopardy |Gametek |C |AOROM
Jeopardy 25th Anniversary |Gametek |C+|ANROM
Jeopardy Jr |Gametek |C |ANROM
Jeopardy Super |Gametek |B |SLROM
Jetsons |Taito |B+|TLROM
Jimmy Connors Tennis |UBI Soft |B+|UNROM
Joe & Mac |Data East |B+|TLROM
Jordan vs. Bird |Milton Bradley |C |UNROM
Joshua |Wisdom Tree |B+|
Journey to Silius |Sunsoft |C+|SLROM
Joust |HAL |B |CNROM
Jungle Book |Virgin |A-|TLROM
Jurassic Park |Ocean |B |TSROM
Karate Champ |Data East |C |CNROM
Karate Kid |LJN |C |CNROM
Karnov |Data East |C |DEIROM
Kick Master |Taito |C+|TLROM
Kickle Cubicle |Irem |B+|TLROM
Kid Icarus |Nintendo |C-|SNROM
Kid Klown |Kemco |B |TSROM
Kid Kool |Vic Tokai |C+|UNROM
Kid Niki |Data East |C |SGROM
King Neptune's Adventure |Color Dreams |B+|
King of Kings |Wisdom Tree |B+|
King of Kings (cartoon mule) |Wisdom Tree |B+|
King of the Ring |Acclaim |B+|55741
Kings Knight |Square |C+|CNROM
Kings of the Beach |Ultra |C |CNROM
Kings Quest 5 |Konami |B+|TSROM
Kirbys Adventure |Nintendo |B-|TKROM
Kiwi Kraze |Taito |B+|TLROM
Klash Ball |Sofel |B-|UNROM
Klax |Tengen |B+|
Knight Rider |Acclaim |B-|SCIROM
Krazy Kreatures |American Video |B+|
Krion Conquest |Vic Tokai |B |TLROM
Krusty's Fun House |Acclaim |C+|TLROM
Kung Fu |Nintendo |E |NROM
Kung Fu Heroes |Culture Brain |C |CNROM
L'Empereur |Koei |B |ETROM
Laser Invasion |Konami |B-|ELROM
Last Action Hero |Imagesoft |B+|TLROM
Last Ninja |Jaleco |B-|TLROM
Last Starfighter |Mindscape |C+|CNROM
Legacy/Wizard |Broderbund |C |TFROM
Legend of Kage |Taito |C-|CNROM
Legendary Wings |Capcom |B |UNROM
Legends/Diamond |Bandai |B+|TLROM
Lemmings |Sunsoft |B-|SLROM
Lethal Weapon |Ocean |B |SLROM
Life Force |Konami |C |351258
Linus Spacehead |Camerica |B |
Linus Spacehead (Aladdin Cart) |Camerica |A+|
Little League Baseball |SNK |B-|SLROM
Little Mermaid |Capcom |B |UNROM
Little Nemo |Capcom |B+|TLROM
Little Ninja Brothers |Culture Brain |C |TLROM
Little Sampson |Taito |B |TLROM
Lode Runner |Broderbund |B |NROM
Lone Ranger |Konami |B-|TLROM
Loopz |Mindscape |B+|UNROM
Low G Man |Taxan |C |TLROM
Lunar Pool |FCI |C+|NROM
M C Kids |Virgin |C+|TSROM
M.U.L.E. |Mindscape |C+|SNROM
Mach Rider |Nintendo |C-|NROM
Mad Max |Mindscape |C+|TLROM
Mafat Conspiracy |Vic Tokai |C |TLROM
Magic Darts |Romstar |B |SLRROM
Magic of Scheherazade |Culture Brain |C-|SLROM
Magician |Taxan |A-|TKROM
Magmax |FCI |C-|NROM
Major League Baseball |LJN |E |CNROM
Maniac Mansion |Jaleco |C+|SNROM
Mappyland |Taxan |C+|TFROM
Marble Madness |Milton Bradley |C+|ANROM
Mario Brothers |Nintendo |B-|NROM
Mario Is Missing |Mindscape |B |TLROM
Mario Time Machine |Mindscape |A-|TLROM
Marvel's X-Men |LJN |B-|UNROM
Master Chu & the Drunkard Hu |Color Dreams |B |
Maxi 15 |American Video |A |
Mechanized Attack |SNK |C |SCROM
Mega Man |Capcom |B-|UNROM
Mega Man 2 |Capcom |C |SGROM
Mega Man 3 |Capcom |C |TLROM
Mega Man 4 |Capcom |B-|TGROM
Mega Man 5 |Capcom |B |TLROM
Mega Man 6 |Nintendo |B+|TGROM
Menace Beach |Color Dreams |A-|
Mendel Palace |Hudson |B |TLROM
Mermaids of Atlantis |American Video |B+|
Metal Fighter |Color Dreams |B |
Metal Gear |Ultra |D |UNROM
Metal Mech |Jaleco |B-|SLROM
Metal Storm |Irem |B+|TLROM
Metroid |Nintendo |D |SNROM
Michael Andretti World GP |American Sammy |B-|TLROM
Mickey Mousecapade |Capcom |C+|CNROM
Mickey Numbers |Hi Tech |B+|TLROM
Mickey's Safari in Letterland |Hi Tech |B+|55741
Micro Machines |Camerica |A-|
Micro Machines (Aladdin Cart) |Camerica |A+|
Mig 29 |Camerica |C+|
Might & Magic |American Sammy |B+|TKROM
Mighty Bombjack |Tecmo |B |CNROM
Mighty Final Fight |Capcom |B+|TLROM
Mike Tyson's Punch Out |Nintendo |D |PNROM
Millipede |HAL |B |NROM
Milon's Secret Castle |Hudson |C |CNROM
Miracle Piano |Mindscape |A-|SJROM
Mission Cobra |Bunch Games |A-|
Mission Impossible |Ultra |C+|352026
Monopoly |Parker Brothers |B-|SLROM
Monster in my Pocket |Konami |B+|TLROM
Monster Party |Bandai |B |SLROM
Monster Truck Rally |INTV |B |CNROM
Moon Ranger |Bunch Games |C |
Motor City Patrol |Matchbox |C+|SLROM
Ms. Pacman |Namco |A |NROM
Ms. Pacman |Tengen |B+|
Muppet Adventure |Hi Tech |B |SGROM
Muscle |Bandai |B-|NROM
Mutant Virus |American Software |B+|SLROM
Mystery Quest |Taxan |C+|CNROM
NARC |Acclaim |C |AMROM
NES Open Golf |Nintendo |B-|SNROM
NFL Football |LJN |C |UNROM
Nigel Mansell |Gametek |B+|SLROM
Nightmare on Elm Street |LJN |B |AMROM
Nightshade |Ultra |C+|TLROM
Ninja Crusaders |American Sammy |B |TGROM
Ninja Gaiden |Tecmo |E |SLROM
Ninja Gaiden 2 |Tecmo |C-|TLROM
Ninja Gaiden 3 |Tecmo |C+|TLROM
Ninja Kid |Bandai |C+|CNROM
Nombunagas Ambition |Koei |C |SOROM
Nombunagas Ambition 2 |Koei |B |ETROM
North & South |Kemco |B+|TSROM
Operation Secret Storm |Color Dreams |A |
Operation Wolf |Taito |D |SLROM
ORB-3D |Hi Tech |C |SCROM
Othello |Acclaim |C |NROM
Overlord |Virgin |B-|SN1
P'radikus Conflict |Color Dreams |B |
Pac Man |Namco |A |56504
Pac Man (licensed) |Tengen |B-|NROM
Pac Man (unlicensed) |Tengen |B-|
Pac Mania |Tengen |A |
Palamedes |Hot B |B+|SEROM
Panic Resturant |Taito |B |TLROM
Paperboy |Mindscape |C |CNROM
Paperboy 2 |Mindscape |B |UOROM
Parodius (England) |Palcom | |
Pebble Beach Golf |Bandai |C+|CNROM
Peek A Boo Poker |Panesian |A+|
Perfect Fit |Gametek |B |CNROM
Pesterminator |Color Dreams |B |
Peter Pan & the Pirates |T*HQ |B-|SFROM
Phantom Fighter |FCI |C+|SGROM
Pictionary |LJN |B-|SLROM
Pinball |Nintendo |D |NROM
Pinball Quest |Jaleco |B |SLROM
Pinbot |Nintendo |B |TQROM
Pipe Dream |Bullet Proof |B |CNROM
Pirates |Ultra |B |SKROM
Platoon |Sunsoft |D |SLROM
Play Action Football |Nintendo |D |TLSROM
Pool of Radiance |FCI |B+|TKROM
Popeye |Nintendo |B-|NROM
POW |SNK |C |SLROM
Power Blade |Taito |B-|TLROM
Power Blade 2 |Taito |B-|TLROM
Power Punch 2 |American Softworks |B |TLROM
Predator |Activision |C+|SLROM
Prince of Persia |Virgin |C+|UNROM
Princess Tomato |Hudson |B+|SGROM
Pro Am |Nintendo |D |SEROM
Pro Am 2 |Tradewest |B |AOROM
Pro Sport Hockey |Jaleco |B+|TLSROM
Pro Wrestling |Nintendo |D |UNROM
Puggsly's Scavenger Hunt |Ocean |B |SLROM
Punch Out |Nintendo |C+|PNROM
Punisher |LJN |B |TLROM
Puss N Boots |Electro Brain |B-|UNROM
Puzzle |American Video |A-|
Puzznic |Taito |B+|CNROM
Pyramid |American Video |A-|
Q*Bert |Ultra |B-|CNROM
Qix |Taito |A |SNROM
Quantum Fighter |HAL |B |TLROM
Quarterback |Tradewest |D |CNROM
Quattro Adventure |Camerica |B+|
Quattro Adventure (Aladdin Cart) |Camerica |A+|
Quattro Arcade |Camerica |A-|
Quattro Sports |Camerica |B |
Quattro Sports (Aladdin Cart) |Camerica |A+|
Race America |Absolute |B+|SLROM
Racket Attack |Jaleco |C-|SLROM
Rad Gravity |Activision |B-|SLROM
Rad Racer |Nintendo |D |SGROM
Rad Racer 2 |Square |B-|TVROM
Rad Racket |American Video |A-|
Raid 2020 |Color Dreams |B |
Raid on Bungling Bay |Broderbund |B |NROM
Rainbow Island |Taito |B+|UNROM
Rally Bike |Romstar |B |UNROM
Rambo |Acclaim |E |UNROM
Rampage |Data East |C+|TFROM
Rampart |Jaleco |B |TLROM
RBI Baseball (licensed) |Tengen |C+|DEROM
RBI Baseball (unlicensed) |Tengen |C |
RBI Baseball 2 |Tengen |C+|
RBI Baseball 3 |Tengen |B-|
Remote Control |Hi Tech |C |SLROM
Ren + Stimpy Buckaroos |T*HQ |B-|TLROM
Renegade |Taito |C-|UNROM
Rescue |Kemco |C-|SLROM
Rescue Rangers |Capcom |C+|SLROM
Rescue Rangers 2 |Capcom |B+|SLROM
Ring King |Data East |C |DEROM
River City Ransom |American Technos |C |TLROM
Road Blasters |Mindscape |C+|SLROM
Road Runner |Tengen |B+|
Robin Hood |Virgin |C+|SGROM
Robo Cop |Data East |C |TL1ROM
Robo Cop 2 |Data East |B-|SLROM
Robo Cop 3 |Ocean |B |SLROM
Robo Demons |Color Dreams |B |
Robo Warrior |Jaleco |B |UNROM
Rock N Ball |NTVIC |B |TFROM
Rocket Ranger |Kemco |B-|SGROM
Rocketeer |Bandai |B-|SGROM
Rockin Kats |Atlus |B+|TLROM
Rocky & Bullwinkle |T*HQ |B-|TLROM
Roger Clemens |LJN |C |53361
Roller Games |Ultra |B-|TLROM
Rollerball |HAL |B |SFROM
Rollerblade Racer |Hi Tech |B |53361
Rolling Thunder |Tengen |C+|
Romance/3 Kingdoms |Koei |C |SOROM
Romance/3 Kingdoms 2 |Koei |B |EWROM
Roundball |Mindscape |B-|TSROM
Rush N Attack |Konami |D |UNROM
Rygar |Tecmo |C |UNROM
SCAT |Natsume |B |SLROM
Secret Scout |Color Dreams |A |
Section Z |Capcom |C |UNROM
Seicross |FCI |D |NROM
Sesame Street 1-2-3 |Hi Tech |C+|SEROM (SCROROM)
Sesame Street 123/ABC |Hi Tech |B |SLROM
Sesame Street A-B-C |Hi Tech |C+|SEROM
Sesame Street Countdown |Hi Tech |A-|SLROM
Shadow of the Ninja |Natsume |B |TLROM
Shadowgate |Kemco |C+|TKROM
Shatterhand |Jaleco |B-|TLROM
Shingen the Ruler |Hot B |C |SNROM
Shinobi |Tengen |C+|
Shockwave |American Game Carts Inc|B |
Shooting Range |Bandai |B |CNROM
Short Order/Eggsplode |Nintendo |B+|SBROM
Side Pocket |Data East |B |UNROM
Silent Assault |Color Dreams |B |
Silent Service |Ultra |C-|351258
Silk Worm |American Sammy |C |SLROM
Silver Surfer |Arcadia |B |TSROM
Simpsons Bart Meets Radioactive Man |Acclaim |B+|55741
Simpsons Bart Vs Space Mutants |Acclaim |D |SLROM
Simpsons Bart Vs World |Acclaim |B-|53361
Skate or Die |Ultra |D |351258
Skate or Die 2 |Electronic Arts |B |SLROM
Ski or Die |Ultra |B-|351908
Skull & Crossbones |Tengen |B |
Sky Kid |Sunsoft |B-|SCEOROM
Sky Shark |Taito |D |SL1ROM
Slalom |Nintendo |B-|NROM
Smash TV |Acclaim |C+|51555
Snake Rattle & Roll |Nintendo |C+|SEROM
Snakes Revenge |Ultra |C |SLROM
Snoopy Silly Sports |Kemco |B+|SLROM
Snow Brothers |Capcom |B |SLROM
Soccer |Nintendo |D |NROM
Solar Jetman |Tradewest |C |AOROM
Solitaire |American Video |A-|
Soloman's Key |Tecmo |C+|CNROM
Solstice |Imagesoft |C |ANROM
Space Shuttle |Absolute |B+|SGROM
Spelunker |Broderbund |C+|NROM
Spiderman |LJN |B-|53361
Spiritual Warfare |Wisdom Tree |B+|
Spot |Arcadia |B-|SNROM
Spy Hunter |Sunsoft |C |CNROM
Spy vs. Spy |Kemco |B-|NROM
Sqoon |Irem |B+|NROM
Stack Up |Nintendo |A-|HVC
Stadium Events |Bandai |B |
Stanley |Electro Brain |B |TLROM
Star Force |Tecmo |C+|CNROM
Star Soldier |Taxan |C-|CNROM
Star Trek 25th Anniversary |Ultra |B |TLROM
Star Trek: The Next Generation |Absolute |A-|UNROM
Star Tropics |Nintendo |C-|HKROM
Star Voyager |Acclaim |C+|CNROM
Star Wars |JVC |B |TSROM
Starship Hector |Hudson |B-|UNROM
Stealth ATF |Activision |C+|SLROM
Stinger |Konami |B-|UNROM
Street Cop |Bandai |A-|SLROM
Street Fighter 2010 |Capcom |B |TLROM
Strider |Capcom |C |SGROM
Stunt Kids |Camerica |A-|
Sunday Funday |Wisdom Tree |B+|
Super C |Konami |C |352026
Super Cars |Electro Brain |B+|UNROM
Super Dodge Ball |Imagesoft |C |SLROM
Super Glove Ball |Mattel |C |UNROM
Super Mario Brothers |Nintendo |F |NROM
Super Mario Brothers 2 |Nintendo |D |TSROM
Super Mario Brothers 3 |Nintendo |D |TSROM
Super Mario/Duck Hunt |Nintendo |F |MH
Super Mario/Duck Hunt/Track Meet |Nintendo |C |COB
Super Off Road |Tradewest |C-|AMROM
Super Pitfall |Activision |C+|UNROM
Super Spike V'Ball |Nintendo |C-|TLROM
Super Spike/World Cup |Nintendo |B-|COB
Super Sprint |Tengen |C |COB
Super Spy Hunter |Sunsoft |B+|TLROM
Super Team Games |Nintendo |C-|CNROM
Superman |Kemco |B+|SLROM
Swamp Thing |T*HQ |C+|SLROM
Sword Master |Activision |A-|TLROM
Swords & Serpents |Acclaim |B+|UNROM
T&C Surf Design |LJN |E |CNROM
Taboo |Tradewest |C+|SEROM
Tag Team Wrestling |Data East |C |NROM
Taggin Dragon |Bunch Games |B |
Talespin |Capcom |B |SLROM
Target Renegade |Taito |C+|SLROM
Tecmo Baseball |Tecmo |C |SGROM
Tecmo Basketball |Tecmo |C+|TKROM
Tecmo Bowl |Tecmo |E |SLROM
Tecmo Cup Soccer |Tecmo |B+|SLROM
Tecmo Super Bowl |Tecmo |C-|TKROM
Tecmo Wrestling |Tecmo |C |SLROM
Teenage Turtles |Ultra |E |351908
Teenage Turtles 2 |Ultra |D |TLROM
Teenage Turtles 3 |Konami |B-|TLROM
Teenage Turtles Tournament Fighters |Konami |B+|TLROM
Tennis |Nintendo |D |NROM
Terminator |Mindscape |B+|TLROM
Terminator 2 Judgement Day |LJN |B-|53361
Terra Cresta |Vic Tokai |B+|UNROM
Tetris |Tengen |A-|
Tetris |Nintendo |D |SEROM
Tetris 2 |Nintendo |B-|TSROM
Three Stooges |Activision |C+|SLROM
Thrilla Safari |LJN |B |53361
Thunder & Lightning |Romstar |B+|GNROM
Thunderbirds |Activision |C+|SLROM
Thundercade |American Sammy |C+|UNROM
Tiger Heli |Acclaim |C+|CNROM
Tiles of Fate |American Video |B+|
Time Lord |Milton Bradley |C |AMROM
Times of Lore |Toho |B-|UNROM
Tiny Toon |Konami |C+|TLROM
Tiny Toon Cartoon Workshop |Konami |B+|TSROM
Tiny Toons 2 |Konami |B+|TLROM
To The Earth |Nintendo |C+|TEROM
Toki |Taito |B+|TLROM
Tom & Jerry |Hi Tech |B+|TLROM
Tombs & Treasures |Infocom |A-|SGROM
Toobin |Tengen |B |
Top Gun |Konami |D |351298
Top Gun 2 |Konami |D |352026
Top Players Tennis |Asmik |C+|SLROM
Total Recall |Acclaim |D |UNROM
Totally Rad |Jaleco |B-|TLROM
Touchdown Fever |SNK |B+|SFROM
Toxic Crusader |Bandai |B |TLROM
Track & Field |Konami |D |CNROM
Track & Field 2 |Konami |D |SLROM
Treasure Master |American Softworks |A-|SLROM
Trick Shooting |Nintendo |C+|SCROM
Trog |Acclaim |B+|UNROM
Trojan |Capcom |C |UNROM
Trolls on Treasure Island |American Video |A-|
Twin Cobra |American Sammy |C+|TLROM
Twin Eagle |Romstar |C+|UNROM
Ultima/Exodus |FCI |C-|SNROM
Ultima/Quest Avatar |FCI |B |SNROM
Ultima/War Destiny |FCI |B+|SNROM
Ultimate Air Combat |Activision |B+|TLROM
Ultimate Basketball |American Sammy |C |TLROM
Ultimate League Soccer |American Video |A-|
Ultimate Stuntman |Camerica |C+|
Uncharted Waters |Koei |B-|ETROM
Uninvited |Kemco |B+|TKROM
Untouchables |Ocean |B-|SLROM
Urban Champion |Nintendo |D |NROM
Vegas Dream |HAL |B |SKROM
Venice Beach Volleyball |American Video |A-|
Vice Project Doom |American Sammy |C+|TLROM
Videomation |T*HQ |B+|CPROM
Vindicators |Tengen |C |
Volleyball |Nintendo |C |NROM
Wacky Races |Atlus |B+|TLROM
Wall Street Kid |Sofel |B |UNROM
Wally Bear and the No Gang |American Video |A-|
Wario Woods |Nintendo |B+|TKROM
Wayne Gretzky |T*HQ |C+|UNROM
Wayne's World |T*HQ |B |TLROM
Werewolf |Data East |C |TLROM
Wheel/Fortune |Gametek |C |AOROM
Wheel/Fortune/Family |Gametek |C |ANROM
Wheel/Fortune/Junior |Gametek |C |ANROM
Wheel/Fortune/Vanna |Gametek |B |AOROM
Where in Time is Carmen |Konami |B |TSROM
Where's Waldo |T*HQ |C+|TSROM
Who Framed Roger Rabbit |LJN |B-|ANROM
Whomp Em |Jaleco |B |TLROM
Widget |Atlus |B |TLROM
Wild Gunman |Nintendo |C |NROM
Willow |Capcom |B-|SLROM
Win Lose or Draw |Hi Tech |C |SGROM
Winter Games |Acclaim |B-|UNROM
Wizardry |Nexoft |C+|SKROM
Wizardry 2 Knight of Diamonds |Ascii |B+|TKROM
Wizards & Warriors |Acclaim |D |ANROM
Wizards & Warriors 2 - Ironsword |Acclaim |D |AOROM
Wizards & Warriors 3 |Acclaim |C-|54425
Wolverine |LJN |B-|TLROM
World Champ |Romstar |B+|TLROM
World Championship Wrestling |FCI |D |TLROM
World Class Track Meet |Nintendo |D |CNROM
World Cup Soccer |Nintendo |C-|TLROM
World Games |Milton Bradley |B-|ANROM
World Runner 3D |Acclaim |C-|UNROM
Wrath of the Black Manta |Taito |C+|SLROM
Wrecking Crew |Nintendo |C+|NROM
Wrestlemania |Acclaim |D |ANROM
Wrestlemania Challenge |LJN |C-|UNROM
Wrestlemania Steel Cage |LJN |C+|53361
Wurm |Asmik |B-|TLROM
Xenophobe |Sunsoft |B-|SFROM
Xevious |Bandai |C+|NROM
Xexyz |Hudson |C+|SLROM
Yo Noid |Capcom |C+|SLROM
Yoshi |Nintendo |C-|SFROM
Yoshi's Cookie |Nintendo |B-|TFROM
Young Indy |Jaleco |B+|TLROM
Zanac |FCI |C+|UNROM
Zelda |Nintendo |E |SNROM
Zelda 2 |Nintendo |D |SKROM
Zen |Konami |B |TLROM
Zoda's Revenge, Startropics 2 |Nintendo |B-|HKROM
Zombie Nation |Meldac |B |TLROM

View File

@ -1,38 +0,0 @@
/*
console.h - single header for all console 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 CONSOLE_H
#define CONSOLE_H
#include "dc.h"
#include "gb.h"
#include "gba.h"
#include "genesis.h"
#include "jaguar.h"
#include "lynx.h"
#include "n64.h"
#include "neogeo.h"
#include "nes.h"
#include "ngp.h"
#include "pce.h"
#include "psx.h"
#include "sms.h"
#include "snes.h"
#include "swan.h"
#endif // CONSOLE_H

View File

@ -1,646 +0,0 @@
/*
dc.c - Dreamcast support for uCON64
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.
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "misc/file.h"
#include "misc/misc.h"
#include "misc/property.h"
#include "misc/string.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "ucon64.h"
#include "ucon64_misc.h"
#include "dc.h"
const st_getopt2_t dc_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "Dreamcast" /* "1998 SEGA http://www.sega.com" */,
NULL
},
{
"dc", 0, 0, UCON64_DC,
NULL, "force recognition",
&ucon64_wf[WF_OBJ_DC_SWITCH]
},
#if 0
{
"vms", 1, 0, UCON64_VMS,
"SAV", "convert NES SAV file to a VMS file for use with NesterDC",
NULL
},
#endif
{
"scr", 0, 0, UCON64_SCR,
NULL, "scramble 1ST_READ.BIN for selfboot CDs",
&ucon64_wf[WF_OBJ_DC_DEFAULT]
},
{
"unscr", 0, 0, UCON64_UNSCR,
NULL, "unscramble 1ST_READ.BIN for non-selfboot CDs",
&ucon64_wf[WF_OBJ_DC_DEFAULT]
},
#if 0
{
"ip", 1, 0, UCON64_IP,
"FILE", "extract ip.bin FILE from IMAGE; " OPTION_LONG_S "rom=IMAGE",
NULL
},
#endif
{
"mkip", 0, 0, UCON64_MKIP,
NULL, "generate IP.BIN file with default values",
&ucon64_wf[WF_OBJ_DC_NO_ROM]
},
{
"parse", 1, 0, UCON64_PARSE,
"TEMPLATE", "parse TEMPLATE file into a IP.BIN;\n"
"creates an empty template when TEMPLATE does not exist",
&ucon64_wf[WF_OBJ_DC_NO_ROM]
},
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
static int
calc_crc (const unsigned char *buf, int size)
{
int i, c, n = 0xffff;
for (i = 0; i < size; i++)
{
n ^= (buf[i] << 8);
for (c = 0; c < 8; c++)
if (n & 0x8000)
n = (n << 1) ^ 4129;
else
n = (n << 1);
}
return n & 0xffff;
}
static void
update_crc (char *ip)
{
int n = calc_crc ((unsigned char *) (ip + 0x40), 16);
char buf[5];
sprintf (buf, "%04X", n);
if (memcmp (buf, ip + 0x20, 4))
{
printf ("Setting CRC to %s (was %.4s)\n", buf, ip + 0x20);
memcpy (ip + 0x20, buf, 4);
}
}
static unsigned int seed;
static void
dc_srand (unsigned int n)
{
seed = n & 0xffff;
}
static unsigned int
dc_rand ()
{
seed = (seed * 2109 + 9273) & 0x7fff;
return (seed + 0xc000) & 0xffff;
}
#if 0
// header for SAV -> VMS conversion
static const uint8_t nstrsave_bin[1024] = {
0x4e, 0x45, 0x53, 0x52, 0x4f, 0x4d, 0x2e, 0x4e, // 0x8 (8)
0x45, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 (16)
0x4e, 0x65, 0x73, 0x74, 0x65, 0x72, 0x44, 0x43, // 0x18 (24)
0x20, 0x53, 0x61, 0x76, 0x65, 0x52, 0x61, 0x6d, // 0x20 (32)
0x20, 0x46, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x00, // 0x28 (40)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x30 (48)
0x2a, 0x2a, 0x2a, 0x4e, 0x65, 0x73, 0x74, 0x65, // 0x38 (56)
0x72, 0x44, 0x43, 0x2a, 0x2a, 0x2a, 0x00, 0x00, // 0x40 (64)
0x01, 0x00, 0x00, 0x00, 0x01, 0x3f, 0x00, 0x00, // 0x48 (72)
0x80, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 (80)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 (88)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 (96)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 (104)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 (112)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 (120)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 (128)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 (136)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 (144)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 (152)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xa0 (160)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xa8 (168)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xb0 (176)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xb8 (184)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xc0 (192)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xc8 (200)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xd0 (208)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xd8 (216)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xe0 (224)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xe8 (232)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xf0 (240)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xf8 (248)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x100 (256)
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x108 (264)
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x110 (272)
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x118 (280)
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x120 (288)
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x128 (296)
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x130 (304)
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x138 (312)
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x140 (320)
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x148 (328)
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x150 (336)
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x158 (344)
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x160 (352)
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x168 (360)
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x170 (368)
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x178 (376)
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x180 (384)
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x188 (392)
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x190 (400)
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x198 (408)
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1a0 (416)
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1a8 (424)
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1b0 (432)
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1b8 (440)
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1c0 (448)
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1c8 (456)
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1d0 (464)
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1d8 (472)
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1e0 (480)
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1e8 (488)
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1f0 (496)
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1f8 (504)
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x200 (512)
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x208 (520)
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x210 (528)
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x218 (536)
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x220 (544)
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x228 (552)
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x230 (560)
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x238 (568)
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x240 (576)
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x248 (584)
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x250 (592)
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x258 (600)
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x260 (608)
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x268 (616)
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x270 (624)
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x278 (632)
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x280 (640)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x288 (648)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x290 (656)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x298 (664)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2a0 (672)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2a8 (680)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2b0 (688)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2b8 (696)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2c0 (704)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2c8 (712)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2d0 (720)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2d8 (728)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2e0 (736)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2e8 (744)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2f0 (752)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2f8 (760)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x300 (768)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x308 (776)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x310 (784)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x318 (792)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x320 (800)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x328 (808)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x330 (816)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x338 (824)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x340 (832)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x348 (840)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x350 (848)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x358 (856)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x360 (864)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x368 (872)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x370 (880)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x378 (888)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x380 (896)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x388 (904)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x390 (912)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x398 (920)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3a0 (928)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3a8 (936)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3b0 (944)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3b8 (952)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3c0 (960)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3c8 (968)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3d0 (976)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3d8 (984)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3e0 (992)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3e8 (1000)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3f0 (1008)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3f8 (1016)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // 0x400 (1024)
};
#endif
int
dc_init (st_rominfo_t *rominfo)
{
int result = -1;
rominfo->console_usage = dc_usage[0].help;
return result;
}
static int
check_areasym (char *ptr, int len)
{
int i, a = 0;
for (i = 0; i < len; i++)
switch (ptr[i])
{
case 'J':
a |= (1<<0);
break;
case 'U':
a |= (1<<1);
break;
case 'E':
a |= (1<<2);
break;
case ' ':
break;
default:
fprintf (stderr, "ERROR: Unknown area symbol '%c'\n", ptr[i]);
return -1;
}
for (i = 0; i < len; i++)
if ((a & (1<<i)) == 0)
ptr[i] = ' ';
else
ptr[i] = "JUE"[i];
return 0;
}
typedef struct
{
char *name;
int pos;
int len;
int (*extra_check) (char *, int);
char *def;
char *comment;
} st_templ_t;
st_templ_t templ[] =
{
{"hardware_id", 0x0, 0x10, NULL, "SEGA SEGAKATANA", "Hardware ID (always \"SEGA SEGAKATANA\")"},
{"maker_id", 0x10, 0x10, NULL, "SEGA ENTERPRISES", "Maker ID (always \"SEGA ENTERPRISES\")"},
{"device_info", 0x20, 0x10, NULL, "0000 CD-ROM1/1", "Device Information"},
{"area_symbols", 0x30, 0x8, check_areasym, "JUE", "Area Symbols"},
{"peripherals", 0x38, 0x8, NULL, "E000F10", "Peripherals"},
{"product_no", 0x40, 0xa, NULL, "T0000", "Product number (\"HDR-nnnn\" etc.)"},
{"version", 0x4a, 0x6, NULL, "V1.000", "Product version"},
{"release_date", 0x50, 0x10, NULL, "20000627", "Release date (YYYYMMDD)"},
{"boot_filename", 0x60, 0x10, NULL, "1ST_READ.BIN", "Boot filename (usually \"1ST_READ.BIN\")"},
{"sw_maker_name", 0x70, 0x10, NULL, "YOUR NAME HERE", "Name of the company that produced the disc"},
{"game_title", 0x80, 0x80, NULL, "TITLE OF THE SOFTWARE", "Name of the software"},
{NULL, 0, 0, NULL, NULL, NULL}
};
static int
parse_templ (const char *templ_file, char *ip)
{
int filled_in[MAXBUFSIZE];
static char buf[MAXBUFSIZE];
int i;
memset (filled_in, 0, sizeof (filled_in));
for (i = 0; templ[i].name; i++)
{
char *p = buf;
get_property (templ_file, templ[i].name, p, templ[i].def);
strtriml (strtrimr (p));
if (!(*p))
continue;
memset (ip + templ[i].pos, ' ', templ[i].len);
if ((int) strlen (p) > templ[i].len)
{
fprintf (stderr, "ERROR: Data for field \"%s\" is too long... stripping to %d chars\n",
templ[i].name, templ[i].len);
p[templ[i].len] = 0;
}
memcpy (ip + templ[i].pos, p, strlen (p));
if (templ[i].extra_check)
if (templ[i].extra_check (ip + templ[i].pos, templ[i].len) == -1)
return -1;
filled_in[i] = 1;
}
for (i = 0; templ[i].name; i++)
if (!filled_in[i])
{
fprintf (stderr, "ERROR: Missing value for \"%s\"\n", templ[i].name);
return -1;
}
return 0;
}
int
dc_parse (const char *templ_file)
{
char ip[0x8000], dest_name[FILENAME_MAX];
if (access (templ_file, F_OK) == -1)
{
int i = 0;
printf ("Creating empty template file: \"%s\"\n", templ_file);
for (i = 0; templ[i].name; i++)
set_property (templ_file, templ[i].name, templ[i].def, templ[i].comment);
printf (ucon64_msg[WROTE], templ_file);
}
if (parse_templ (templ_file, ip) == -1)
return -1;
update_crc (ip);
strcpy (dest_name, "ip.bin");
ucon64_file_handler (dest_name, NULL, 0);
ucon64_fwrite (ip, 0, 0x8000, dest_name, "wb");
printf (ucon64_msg[WROTE], dest_name);
return 0;
}
int
dc_mkip (void)
{
dc_parse ("default");
return 0;
}
static int
load_chunk (FILE * fh, unsigned char *ptr, int32_t sz)
{
#define MAXCHUNK (2048*1024)
static int idx[MAXCHUNK / 32];
int32_t i;
/* Convert chunk size to number of slices */
sz /= 32;
/* Initialize index table with unity,
so that each slice gets loaded exactly once */
for (i = 0; i < sz; i++)
idx[i] = i;
for (i = sz - 1; i >= 0; --i)
{
/* Select a replacement index */
int x = (dc_rand () * i) >> 16;
/* Swap */
int tmp = idx[i];
idx[i] = idx[x];
idx[x] = tmp;
/* Load resulting slice */
if (fread (ptr + 32 * idx[i], 1, 32, fh) != 32)
return -1;
}
return 0;
}
static int
load_file (FILE * fh, unsigned char *ptr, uint32_t filesz)
{
uint32_t chunksz;
dc_srand (filesz);
/* Descramble 2 meg blocks for as long as possible, then
gradually reduce the window down to 32 bytes (1 slice) */
for (chunksz = MAXCHUNK; chunksz >= 32; chunksz >>= 1)
while (filesz >= chunksz)
{
load_chunk (fh, ptr, chunksz);
filesz -= chunksz;
ptr += chunksz;
}
/* Load final incomplete slice */
if (filesz)
if (fread (ptr, 1, filesz, fh) != filesz)
return -1;
return 0;
}
static int
save_chunk (FILE * fh, unsigned char *ptr, int32_t sz)
{
static int idx[MAXCHUNK / 32];
int32_t i;
/* Convert chunk size to number of slices */
sz /= 32;
/* Initialize index table with unity,
so that each slice gets saved exactly once */
for (i = 0; i < sz; i++)
idx[i] = i;
for (i = sz - 1; i >= 0; --i)
{
/* Select a replacement index */
int x = (dc_rand () * i) >> 16;
/* Swap */
int tmp = idx[i];
idx[i] = idx[x];
idx[x] = tmp;
/* Save resulting slice */
if (fwrite (ptr + 32 * idx[i], 1, 32, fh) != 32)
return -1;
}
return 0;
}
static int
save_file (FILE * fh, unsigned char *ptr, uint32_t filesz)
{
uint32_t chunksz;
dc_srand (filesz);
/* Descramble 2 meg blocks for as long as possible, then
gradually reduce the window down to 32 bytes (1 slice) */
for (chunksz = MAXCHUNK; chunksz >= 32; chunksz >>= 1)
while (filesz >= chunksz)
{
save_chunk (fh, ptr, chunksz);
filesz -= chunksz;
ptr += chunksz;
}
/* Save final incomplete slice */
if (filesz)
if (fwrite (ptr, 1, filesz, fh) != filesz)
return -1;
return 0;
}
static int
descramble (const char *src, char *dst)
{
unsigned char *ptr = NULL;
uint32_t sz = 0;
FILE *fh;
if (!(fh = fopen (src, "rb")))
return -1;
sz = fsizeof (src);
if (!(ptr = (unsigned char *) malloc (sz)))
return -1;
load_file (fh, ptr, sz);
fclose (fh);
if (!(fh = fopen (dst, "wb")))
return -1;
if (fwrite (ptr, 1, sz, fh) != sz)
return -1;
fclose (fh);
free (ptr);
return 0;
}
static int
scramble (const char *src, char *dst)
{
unsigned char *ptr = NULL;
uint32_t sz = 0;
FILE *fh;
if (!(fh = fopen (src, "rb")))
return -1;
sz = fsizeof (src);
if (!(ptr = (unsigned char *) malloc (sz)))
return -1;
if (fread (ptr, 1, sz, fh) != sz)
return -1;
fclose (fh);
if (!(fh == fopen (dst, "wb")))
return -1;
save_file (fh, ptr, sz);
fclose (fh);
free (ptr);
return 0;
}
int
dc_scramble (void)
{
char dest_name[FILENAME_MAX];
strcpy (dest_name, ucon64.rom);
ucon64_file_handler (dest_name, NULL, 0);
if (!scramble (ucon64.rom, dest_name))
printf (ucon64_msg[WROTE], dest_name);
else
fprintf (stderr, ucon64_msg[WRITE_ERROR], dest_name);
return 0;
}
int
dc_unscramble (void)
{
char dest_name[FILENAME_MAX];
strcpy (dest_name, ucon64.rom);
ucon64_file_handler (dest_name, NULL, 0);
if (!descramble (ucon64.rom, dest_name))
printf (ucon64_msg[WROTE], dest_name);
else
fprintf (stderr, ucon64_msg[WRITE_ERROR], dest_name);
return 0;
}

View File

@ -1,29 +0,0 @@
/*
dc.h - Dreamcast support for uCON64
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 DC_H
#define DC_H
extern int dc_init (st_rominfo_t *rominfo);
extern const st_getopt2_t dc_usage[];
extern int dc_parse (const char *template_file);
extern int dc_mkip (void);
extern int dc_scramble (void);
extern int dc_unscramble (void);
#endif

View File

@ -1,703 +0,0 @@
/*
gb.c - Game Boy 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>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include "misc/file.h"
#include "misc/misc.h"
#include "misc/string.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "ucon64.h"
#include "ucon64_misc.h"
#include "console/nes.h"
#include "backup/gbx.h"
#include "backup/mgd.h"
#include "backup/ssc.h"
#include "patch/ips.h"
#include "patch/bsl.h"
#include "gb.h"
#define GAMEBOY_HEADER_START 0x100
#define GAMEBOY_HEADER_LEN (sizeof (st_gameboy_header_t))
#define GB_NAME_LEN 15
const st_getopt2_t gameboy_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "Game Boy/(Super GB)/GB Pocket/Color GB/(GB Advance)"
/*"1989/1994/1996/1998/2001 Nintendo http://www.nintendo.com"*/,
NULL
},
{
"gb", 0, 0, UCON64_GB,
NULL, "force recognition",
&ucon64_wf[WF_OBJ_GB_SWITCH]
},
{
"n", 1, 0, UCON64_N,
"NEW_NAME", "change internal ROM name to NEW_NAME",
&ucon64_wf[WF_OBJ_ALL_DEFAULT]
},
{
"logo", 0, 0, UCON64_LOGO,
NULL, "restore ROM logo character data (offset: 0x104-0x134)",
&ucon64_wf[WF_OBJ_ALL_DEFAULT]
},
{
"mgd", 0, 0, UCON64_MGD,
NULL, "convert to Multi Game*/MGD2/RAW",
&ucon64_wf[WF_OBJ_ALL_DEFAULT]
},
{
"ssc", 0, 0, UCON64_SSC,
NULL, "convert to Super Smart Card/SSC",
&ucon64_wf[WF_OBJ_GB_DEFAULT]
},
{
"sgb", 0, 0, UCON64_SGB,
NULL, "convert from GB Xchanger/GB/GBC to Super Backup Card/GX/GBX",
&ucon64_wf[WF_OBJ_GB_DEFAULT]
},
{
"gbx", 0, 0, UCON64_GBX,
NULL, "convert from Super Backup Card/GX/GBX to GB Xchanger/GB/GBC",
&ucon64_wf[WF_OBJ_GB_DEFAULT]
},
{
"n2gb", 1, 0, UCON64_N2GB,
"NESROM", "KAMI's FC EMUlator (NES emulator);\n"
"ROM should be KAMI's FC Emulator ROM image\n"
"NESROM should contain 16 kB of PRG data and 8 kB of CHR data",
&ucon64_wf[WF_OBJ_GB_DEFAULT]
},
{
"chk", 0, 0, UCON64_CHK,
NULL, "fix ROM checksum",
&ucon64_wf[WF_OBJ_ALL_DEFAULT]
},
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
/*
0148 ROM size:
0 - 256kBit = 32kB = 2 banks
1 - 512kBit = 64kB = 4 banks
2 - 1Mb = 128kB = 8 banks
3 - 2Mb = 256kB = 16 banks
4 - 4Mb = 512kB = 32 banks
0149 RAM size:
0 - None
1 - 16kBit = 2kB = 1 bank
2 - 64kBit = 8kB = 1 bank
3 - 256kBit = 32kB = 4 banks
*/
typedef struct st_gameboy_header
{
unsigned char opcode1; // 0x00 usually 0x00, NOP
unsigned char opcode2; // 0x01 usually 0xc3, JP
unsigned char start_low; // 0x02 first byte of parameter of JP
unsigned char start_high; // 0x03 second byte
unsigned char logo[GB_LOGODATA_LEN]; // 0x04
unsigned char name[GB_NAME_LEN]; // 0x34
unsigned char gb_type; // 0x43
unsigned char maker_high; // 0x44
unsigned char maker_low; // 0x45
unsigned char pad;
unsigned char rom_type; // 0x47
unsigned char rom_size; // 0x48
unsigned char sram_size; // 0x49
unsigned char country; // 0x4a
unsigned char maker; // 0x4b
unsigned char version; // 0x4c
unsigned char header_checksum; // 0x4d
unsigned char checksum_high; // 0x4e
unsigned char checksum_low; // 0x4f
} st_gameboy_header_t;
static st_gameboy_header_t gameboy_header;
const unsigned char gb_logodata[] = // Note: not a static variable
{
0xce, 0xed, 0x66, 0x66, 0xcc, 0x0d, 0x00, 0x0b,
0x03, 0x73, 0x00, 0x83, 0x00, 0x0c, 0x00, 0x0d,
0x00, 0x08, 0x11, 0x1f, 0x88, 0x89, 0x00, 0x0e,
0xdc, 0xcc, 0x6e, 0xe6, 0xdd, 0xdd, 0xd9, 0x99,
0xbb, 0xbb, 0x67, 0x63, 0x6e, 0x0e, 0xec, 0xcc,
0xdd, 0xdc, 0x99, 0x9f, 0xbb, 0xb9, 0x33, 0x3e
},
rocket_logodata[] = // idem
{
0x11, 0x23, 0xf1, 0x1e, 0x01, 0x22, 0xf0, 0x00,
0x08, 0x99, 0x78, 0x00, 0x08, 0x11, 0x9a, 0x48,
0x11, 0x23, 0xf0, 0x0e, 0x70, 0x01, 0xf8, 0x80,
0x22, 0x44, 0x44, 0x22, 0x22, 0x21, 0x00, 0x1e,
0x99, 0x10, 0x00, 0x1e, 0x19, 0x22, 0x44, 0x22,
0x22, 0x47, 0x00, 0x0e, 0x11, 0x22, 0x00, 0x00
};
typedef struct st_gameboy_chksum
{
unsigned short value;
unsigned char header;
} st_gameboy_chksum_t;
static st_gameboy_chksum_t checksum;
static st_gameboy_chksum_t gameboy_chksum (st_rominfo_t *rominfo);
int
gameboy_logo (st_rominfo_t *rominfo)
{
char dest_name[FILENAME_MAX];
strcpy (dest_name, ucon64.rom);
ucon64_file_handler (dest_name, NULL, 0);
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
ucon64_fwrite ((unsigned char *)
((gameboy_header.rom_type >= 0x97 && gameboy_header.rom_type <= 0x99) ?
rocket_logodata : gb_logodata),
rominfo->buheader_len + GAMEBOY_HEADER_START + 4, GB_LOGODATA_LEN,
dest_name, "r+b");
printf (ucon64_msg[WROTE], dest_name);
return 0;
}
int
gameboy_n2gb (st_rominfo_t *rominfo, const char *nesrom)
{
#define EMULATOR_LEN 0x10000
st_ines_header_t ines_header;
int n = 0, crc = 0;
unsigned char *buf;
char dest_name[FILENAME_MAX];
if (ucon64.file_size - rominfo->buheader_len != EMULATOR_LEN)
{
fprintf (stderr, "ERROR: %s does not appear to be KAMI's FC emulator\n", ucon64.rom);
return -1;
}
ucon64_fread (&ines_header, 0, INES_HEADER_LEN, nesrom);
if (memcmp (ines_header.signature, INES_SIG_S, 4))
{
fprintf (stderr, "ERROR: Only NES ROMs with iNES header are supported\n");
return -1;
}
if (ines_header.prg_size != 1 || ines_header.chr_size != 1)
{
fprintf (stderr,
"ERROR: Only NES ROMs with 0.1250 Mb of ROM (PRG) and 0.0625 Mb of VROM (CHR)\n"
" are supported by KAMI's FC emulator\n");
return -1;
}
if (!(buf = (unsigned char *) malloc (ucon64.file_size)))
{
fprintf (stderr, ucon64_msg[ROM_BUFFER_ERROR], ucon64.file_size);
return -1;
}
ucon64_fread (buf, 0, ucon64.file_size, ucon64.rom);
ucon64_fread (rominfo->buheader_len + buf + 0x4000, INES_HEADER_LEN,
0x4000 + 0x2000, nesrom); // read PRG & CHR data
for (n = 0; n < ucon64.file_size - rominfo->buheader_len; n++)
{
if ((n == GAMEBOY_HEADER_START + 0x4e) || (n == GAMEBOY_HEADER_START + 0x4f))
continue;
else
crc += buf[rominfo->buheader_len + n];
}
buf[rominfo->buheader_len + GAMEBOY_HEADER_START + 0x4e] = crc >> 8;
buf[rominfo->buheader_len + GAMEBOY_HEADER_START + 0x4f] = crc;
strcpy (dest_name, ucon64.rom);
ucon64_file_handler (dest_name, NULL, 0);
ucon64_fwrite (buf, 0, ucon64.file_size, dest_name, "wb");
free (buf);
printf (ucon64_msg[WROTE], dest_name);
return 0;
}
static int
gameboy_convert_data (st_rominfo_t *rominfo, unsigned char *conversion_table,
const char *suffix)
{
char dest_name[FILENAME_MAX], src_name[FILENAME_MAX];
unsigned char buf[MAXBUFSIZE];
int x, n, n_bytes;
strcpy (src_name, ucon64.rom);
strcpy (dest_name, ucon64.rom);
set_suffix (dest_name, suffix);
ucon64_file_handler (dest_name, src_name, 0);
x = rominfo->buheader_len;
while ((n_bytes = ucon64_fread (buf, x, MAXBUFSIZE, src_name)))
{
for (n = 0; n < n_bytes; n++)
buf[n] = conversion_table[(int) buf[n]];
ucon64_fwrite (buf, x, n_bytes, dest_name, x == rominfo->buheader_len ? "wb" : "ab");
x += n_bytes;
}
printf (ucon64_msg[WROTE], dest_name);
return 0;
}
int
gameboy_gbx (st_rominfo_t *rominfo)
{
unsigned char gbx2gbc[] =
{
0xB4, 0xBC, 0xA4, 0xAC, 0x94, 0x9C, 0x84, 0x8C,
0xF4, 0xFC, 0xE4, 0xEC, 0xD4, 0xDC, 0xC4, 0xCC,
0x34, 0x3C, 0x24, 0x2C, 0x14, 0x1C, 0x04, 0x0C,
0x74, 0x7C, 0x64, 0x6C, 0x54, 0x5C, 0x44, 0x4C,
0xB5, 0xBD, 0xA5, 0xAD, 0x95, 0x9D, 0x85, 0x8D,
0xF5, 0xFD, 0xE5, 0xED, 0xD5, 0xDD, 0xC5, 0xCD,
0x35, 0x3D, 0x25, 0x2D, 0x15, 0x1D, 0x05, 0x0D,
0x75, 0x7D, 0x65, 0x6D, 0x55, 0x5D, 0x45, 0x4D,
0xB6, 0xBE, 0xA6, 0xAE, 0x96, 0x9E, 0x86, 0x8E,
0xF6, 0xFE, 0xE6, 0xEE, 0xD6, 0xDE, 0xC6, 0xCE,
0x36, 0x3E, 0x26, 0x2E, 0x16, 0x1E, 0x06, 0x0E,
0x76, 0x7E, 0x66, 0x6E, 0x56, 0x5E, 0x46, 0x4E,
0xB7, 0xBF, 0xA7, 0xAF, 0x97, 0x9F, 0x87, 0x8F,
0xF7, 0xFF, 0xE7, 0xEF, 0xD7, 0xDF, 0xC7, 0xCF,
0x37, 0x3F, 0x27, 0x2F, 0x17, 0x1F, 0x07, 0x0F,
0x77, 0x7F, 0x67, 0x6F, 0x57, 0x5F, 0x47, 0x4F,
0xB0, 0xB8, 0xA0, 0xA8, 0x90, 0x98, 0x80, 0x88,
0xF0, 0xF8, 0xE0, 0xE8, 0xD0, 0xD8, 0xC0, 0xC8,
0x30, 0x38, 0x20, 0x28, 0x10, 0x18, 0x00, 0x08,
0x70, 0x78, 0x60, 0x68, 0x50, 0x58, 0x40, 0x48,
0xB1, 0xB9, 0xA1, 0xA9, 0x91, 0x99, 0x81, 0x89,
0xF1, 0xF9, 0xE1, 0xE9, 0xD1, 0xD9, 0xC1, 0xC9,
0x31, 0x39, 0x21, 0x29, 0x11, 0x19, 0x01, 0x09,
0x71, 0x79, 0x61, 0x69, 0x51, 0x59, 0x41, 0x49,
0xB2, 0xBA, 0xA2, 0xAA, 0x92, 0x9A, 0x82, 0x8A,
0xF2, 0xFA, 0xE2, 0xEA, 0xD2, 0xDA, 0xC2, 0xCA,
0x32, 0x3A, 0x22, 0x2A, 0x12, 0x1A, 0x02, 0x0A,
0x72, 0x7A, 0x62, 0x6A, 0x52, 0x5A, 0x42, 0x4A,
0xB3, 0xBB, 0xA3, 0xAB, 0x93, 0x9B, 0x83, 0x8B,
0xF3, 0xFB, 0xE3, 0xEB, 0xD3, 0xDB, 0xC3, 0xCB,
0x33, 0x3B, 0x23, 0x2B, 0x13, 0x1B, 0x03, 0x0B,
0x73, 0x7B, 0x63, 0x6B, 0x53, 0x5B, 0x43, 0x4B
};
const char *old_suffix = get_suffix (ucon64.rom), *new_suffix;
new_suffix = stricmp (old_suffix, ".GBX") ? ".GB" : ".GBC";
return gameboy_convert_data (rominfo, gbx2gbc, new_suffix);
}
int
gameboy_sgb (st_rominfo_t *rominfo)
{
unsigned char gbc2gbx[] =
{
0x96, 0xB6, 0xD6, 0xF6, 0x16, 0x36, 0x56, 0x76,
0x97, 0xB7, 0xD7, 0xF7, 0x17, 0x37, 0x57, 0x77,
0x94, 0xB4, 0xD4, 0xF4, 0x14, 0x34, 0x54, 0x74,
0x95, 0xB5, 0xD5, 0xF5, 0x15, 0x35, 0x55, 0x75,
0x92, 0xB2, 0xD2, 0xF2, 0x12, 0x32, 0x52, 0x72,
0x93, 0xB3, 0xD3, 0xF3, 0x13, 0x33, 0x53, 0x73,
0x90, 0xB0, 0xD0, 0xF0, 0x10, 0x30, 0x50, 0x70,
0x91, 0xB1, 0xD1, 0xF1, 0x11, 0x31, 0x51, 0x71,
0x9E, 0xBE, 0xDE, 0xFE, 0x1E, 0x3E, 0x5E, 0x7E,
0x9F, 0xBF, 0xDF, 0xFF, 0x1F, 0x3F, 0x5F, 0x7F,
0x9C, 0xBC, 0xDC, 0xFC, 0x1C, 0x3C, 0x5C, 0x7C,
0x9D, 0xBD, 0xDD, 0xFD, 0x1D, 0x3D, 0x5D, 0x7D,
0x9A, 0xBA, 0xDA, 0xFA, 0x1A, 0x3A, 0x5A, 0x7A,
0x9B, 0xBB, 0xDB, 0xFB, 0x1B, 0x3B, 0x5B, 0x7B,
0x98, 0xB8, 0xD8, 0xF8, 0x18, 0x38, 0x58, 0x78,
0x99, 0xB9, 0xD9, 0xF9, 0x19, 0x39, 0x59, 0x79,
0x86, 0xA6, 0xC6, 0xE6, 0x06, 0x26, 0x46, 0x66,
0x87, 0xA7, 0xC7, 0xE7, 0x07, 0x27, 0x47, 0x67,
0x84, 0xA4, 0xC4, 0xE4, 0x04, 0x24, 0x44, 0x64,
0x85, 0xA5, 0xC5, 0xE5, 0x05, 0x25, 0x45, 0x65,
0x82, 0xA2, 0xC2, 0xE2, 0x02, 0x22, 0x42, 0x62,
0x83, 0xA3, 0xC3, 0xE3, 0x03, 0x23, 0x43, 0x63,
0x80, 0xA0, 0xC0, 0xE0, 0x00, 0x20, 0x40, 0x60,
0x81, 0xA1, 0xC1, 0xE1, 0x01, 0x21, 0x41, 0x61,
0x8E, 0xAE, 0xCE, 0xEE, 0x0E, 0x2E, 0x4E, 0x6E,
0x8F, 0xAF, 0xCF, 0xEF, 0x0F, 0x2F, 0x4F, 0x6F,
0x8C, 0xAC, 0xCC, 0xEC, 0x0C, 0x2C, 0x4C, 0x6C,
0x8D, 0xAD, 0xCD, 0xED, 0x0D, 0x2D, 0x4D, 0x6D,
0x8A, 0xAA, 0xCA, 0xEA, 0x0A, 0x2A, 0x4A, 0x6A,
0x8B, 0xAB, 0xCB, 0xEB, 0x0B, 0x2B, 0x4B, 0x6B,
0x88, 0xA8, 0xC8, 0xE8, 0x08, 0x28, 0x48, 0x68,
0x89, 0xA9, 0xC9, 0xE9, 0x09, 0x29, 0x49, 0x69
};
const char *old_suffix = get_suffix (ucon64.rom), *new_suffix;
new_suffix = stricmp (old_suffix, ".GBC") ? ".GX" : ".GBX";
return gameboy_convert_data (rominfo, gbc2gbx, new_suffix);
}
int
gameboy_n (st_rominfo_t *rominfo, const char *name)
{
char buf[GB_NAME_LEN], dest_name[FILENAME_MAX];
memset (buf, 0, GB_NAME_LEN);
strncpy (buf, name, GB_NAME_LEN);
strcpy (dest_name, ucon64.rom);
ucon64_file_handler (dest_name, NULL, 0);
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
ucon64_fwrite (buf, rominfo->buheader_len + GAMEBOY_HEADER_START + 0x34,
GB_NAME_LEN, dest_name, "r+b");
printf (ucon64_msg[WROTE], dest_name);
return 0;
}
int
gameboy_chk (st_rominfo_t *rominfo)
{
char buf[4], dest_name[FILENAME_MAX];
strcpy (dest_name, ucon64.rom);
ucon64_file_handler (dest_name, NULL, 0);
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
buf[0] = checksum.header;
buf[1] = rominfo->current_internal_crc >> 8;
buf[2] = rominfo->current_internal_crc;
ucon64_fwrite (buf, rominfo->buheader_len + GAMEBOY_HEADER_START + 0x4d, 3,
dest_name, "r+b");
dumper (stdout, buf, 3, GAMEBOY_HEADER_START + rominfo->buheader_len + 0x4d, DUMPER_HEX);
printf (ucon64_msg[WROTE], dest_name);
return 0;
}
int
gameboy_mgd (st_rominfo_t *rominfo)
// TODO: convert the ROM data
{
char src_name[FILENAME_MAX], dest_name[FILENAME_MAX];
int size = ucon64.file_size - rominfo->buheader_len;
strcpy (src_name, ucon64.rom);
mgd_make_name (ucon64.rom, UCON64_GB, size, dest_name);
ucon64_file_handler (dest_name, src_name, OF_FORCE_BASENAME);
fcopy (src_name, rominfo->buheader_len, size, dest_name, "wb");
printf (ucon64_msg[WROTE], dest_name);
remove_temp_file ();
mgd_write_index_file ((char *) basename2 (dest_name), 1);
return 0;
}
int
gameboy_ssc (st_rominfo_t *rominfo)
// TODO: convert the ROM data
{
st_unknown_header_t header;
char src_name[FILENAME_MAX], dest_name[FILENAME_MAX];
const char *p = NULL;
int size = ucon64.file_size - rominfo->buheader_len;
memset (&header, 0, UNKNOWN_HEADER_LEN);
header.size_low = size / 8192;
header.size_high = size / 8192 >> 8;
header.id1 = 0xaa;
header.id2 = 0xbb;
#if 0 // TODO: find out correct value. 2 is used for Magic Super Griffin
header.type = 2;
#endif
strcpy (src_name, ucon64.rom);
p = basename2 (ucon64.rom);
// TODO: find out if this is correct (giving the file name a prefix)
if ((p[0] == 'G' || p[0] == 'g') && (p[1] == 'B' || p[1] == 'b'))
strcpy (dest_name, p);
else
sprintf (dest_name, "gb%s", p);
set_suffix (dest_name, ".gb");
ucon64_file_handler (dest_name, src_name, 0);
ucon64_fwrite (&header, 0, UNKNOWN_HEADER_LEN, dest_name, "wb");
fcopy (src_name, rominfo->buheader_len, size, dest_name, "ab");
printf (ucon64_msg[WROTE], dest_name);
remove_temp_file ();
return 0;
}
int
gameboy_init (st_rominfo_t *rominfo)
{
int result = -1, value, x;
char buf[MAXBUFSIZE];
static const char *gameboy_romtype1[0x20] =
{
"ROM only",
"ROM + MBC1",
"ROM + MBC1 + RAM",
"ROM + MBC1 + RAM + Battery",
NULL,
"ROM + MBC2",
"ROM + MBC2 + Battery",
NULL,
"ROM + RAM", // correct? - dbjh
"ROM + RAM + Battery", // correct? - dbjh
NULL,
"ROM + MMM01",
"ROM + MMM01 + SRAM",
"ROM + MMM01 + SRAM + Battery",
NULL,
"ROM + MBC3 + Battery + Timer",
"ROM + MBC3 + RAM + Battery + Timer",
"ROM + MBC3",
"ROM + MBC3 + RAM",
"ROM + MBC3 + RAM + Battery",
NULL,
NULL,
NULL,
NULL,
NULL,
"ROM + MBC5",
"ROM + MBC5 + RAM",
"ROM + MBC5 + RAM + Battery",
"ROM + MBC5 + Rumble",
"ROM + MBC5 + SRAM + Rumble",
"ROM + MBC5 + SRAM + Battery + Rumble",
"Nintendo Pocket Camera"
},
*gameboy_romtype2[3] =
{
"Rocket Games",
NULL,
"Rocket Games 2-in-1"
},
*gameboy_romtype3[3] =
{
"Bandai TAMA5",
"Hudson HuC-3",
"Hudson HuC-1"
},
*str;
rominfo->buheader_len = UCON64_ISSET (ucon64.buheader_len) ? ucon64.buheader_len : 0;
ucon64_fread (&gameboy_header, rominfo->buheader_len + GAMEBOY_HEADER_START,
GAMEBOY_HEADER_LEN, ucon64.rom);
if (gameboy_header.opcode1 == 0x00 && gameboy_header.opcode2 == 0xc3)
result = 0;
else
{
rominfo->buheader_len = UCON64_ISSET (ucon64.buheader_len) ?
ucon64.buheader_len : (int) SSC_HEADER_LEN;
ucon64_fread (&gameboy_header, rominfo->buheader_len + GAMEBOY_HEADER_START,
GAMEBOY_HEADER_LEN, ucon64.rom);
if (gameboy_header.opcode1 == 0x00 && gameboy_header.opcode2 == 0xc3)
result = 0;
else
result = -1;
}
if (ucon64.console == UCON64_GB)
result = 0;
rominfo->header_start = GAMEBOY_HEADER_START;
rominfo->header_len = GAMEBOY_HEADER_LEN;
rominfo->header = &gameboy_header;
// internal ROM name
strncpy (rominfo->name, (const char *) gameboy_header.name, GB_NAME_LEN);
rominfo->name[GB_NAME_LEN] = 0; // terminate string
// ROM maker
if (gameboy_header.maker == 0x33)
{
int ih = gameboy_header.maker_high <= '9' ?
gameboy_header.maker_high - '0' : gameboy_header.maker_high - 'A' + 10,
il = gameboy_header.maker_low <= '9' ?
gameboy_header.maker_low - '0' : gameboy_header.maker_low - 'A' + 10;
x = ih * 36 + il;
}
else
x = (gameboy_header.maker >> 4) * 36 + (gameboy_header.maker & 0x0f);
/*
I added the first if statement, because I didn't want to expand
nintendo_maker by a large amount for only one publisher and because index 0
is used when the publisher code is unknown (so it shouldn't be set to
"Rocket Games"). - dbjh
*/
if (x == 33 * 36 + 33 || x == 0) // publisher code XX/00
x = 2; // Rocket Games
else if (x < 0 || x >= NINTENDO_MAKER_LEN)
x = 0;
rominfo->maker = NULL_TO_UNKNOWN_S (nintendo_maker[x]);
// ROM country
rominfo->country = gameboy_header.country == 0 ? "Japan" : "U.S.A. & Europe";
// misc stuff
// Don't move division by 4 to shift parameter (gameboy_header.rom_size can be < 2)
sprintf (buf, "Internal size: %.4f Mb\n", (1 << gameboy_header.rom_size) / 4.0f);
strcat (rominfo->misc, buf);
if (gameboy_header.rom_type <= 0x1f)
str = NULL_TO_UNKNOWN_S (gameboy_romtype1[gameboy_header.rom_type]);
else if (gameboy_header.rom_type >= 0x97 && gameboy_header.rom_type <= 0x99)
str = gameboy_romtype2[gameboy_header.rom_type - 0x97];
else if (gameboy_header.rom_type >= 0xfd)
str = gameboy_romtype3[gameboy_header.rom_type - 0xfd];
else
str = "Unknown";
sprintf (buf, "ROM type: %s\n", str);
strcat (rominfo->misc, buf);
if (!gameboy_header.sram_size)
sprintf (buf, "Save RAM: No\n");
else
{
value = (gameboy_header.sram_size & 7) << 1; // 0/1/2/4/5
if (value)
value = 1 << (value - 1);
sprintf (buf, "Save RAM: Yes, %d kBytes\n", value);
}
strcat (rominfo->misc, buf);
sprintf (buf, "Version: 1.%d\n", gameboy_header.version);
strcat (rominfo->misc, buf);
sprintf (buf, "Game Boy type: %s\n",
(gameboy_header.gb_type == 0x80) ? "Color" :
// (OFFSET (gameboy_header, 0x46) == 0x03) ? "Super" :
"Standard (4 colors)");
strcat (rominfo->misc, buf);
value = gameboy_header.start_high << 8;
value += gameboy_header.start_low;
sprintf (buf, "Start address: 0x%04x\n", value);
strcat (rominfo->misc, buf);
strcat (rominfo->misc, "Logo data: ");
if (memcmp (gameboy_header.logo,
(gameboy_header.rom_type >= 0x97 && gameboy_header.rom_type <= 0x99) ?
rocket_logodata : gb_logodata,
GB_LOGODATA_LEN) == 0)
{
#ifdef USE_ANSI_COLOR
if (ucon64.ansi_color)
strcat (rominfo->misc, "\x1b[01;32mOk\x1b[0m");
else
#endif
strcat (rominfo->misc, "Ok");
}
else
{
#ifdef USE_ANSI_COLOR
if (ucon64.ansi_color)
strcat (rominfo->misc, "\x1b[01;31mBad\x1b[0m");
else
#endif
strcat (rominfo->misc, "Bad");
}
if (!UCON64_ISSET (ucon64.do_not_calc_crc) && result == 0)
{
rominfo->has_internal_crc = 1;
rominfo->internal_crc_len = 2;
checksum = gameboy_chksum (rominfo);
rominfo->current_internal_crc = checksum.value;
rominfo->internal_crc = (gameboy_header.checksum_high << 8) +
gameboy_header.checksum_low;
x = gameboy_header.header_checksum;
sprintf (rominfo->internal_crc2,
"Header checksum: %s, 0x%02x (calculated) %c= 0x%02x (internal)",
#ifdef USE_ANSI_COLOR
ucon64.ansi_color ?
((checksum.header == x) ?
"\x1b[01;32mOk\x1b[0m" : "\x1b[01;31mBad\x1b[0m")
:
((checksum.header == x) ? "Ok" : "Bad"),
#else
(checksum.header == x) ? "Ok" : "Bad",
#endif
checksum.header, (checksum.header == x) ? '=' : '!', x);
}
rominfo->console_usage = gameboy_usage[0].help;
rominfo->copier_usage = (!rominfo->buheader_len ? mgd_usage[0].help : ssc_usage[0].help);
return result;
}
st_gameboy_chksum_t
gameboy_chksum (st_rominfo_t *rominfo)
{
st_gameboy_chksum_t sum = { 0, 0 };
unsigned char *rom_buffer;
int size = ucon64.file_size - rominfo->buheader_len, i;
if (!(rom_buffer = (unsigned char *) malloc (size)))
{
fprintf (stderr, ucon64_msg[ROM_BUFFER_ERROR], size);
return sum;
}
ucon64_fread (rom_buffer, rominfo->buheader_len, size, ucon64.rom);
for (i = GAMEBOY_HEADER_START + 0x34; i < GAMEBOY_HEADER_START + 0x4d; i++)
sum.header += ~rom_buffer[i];
for (i = 0; i < size; i++)
sum.value += rom_buffer[i];
sum.value -= (rom_buffer[GAMEBOY_HEADER_START + 0x4d] - sum.header) +
rom_buffer[GAMEBOY_HEADER_START + 0x4e] +
rom_buffer[GAMEBOY_HEADER_START + 0x4f];
free (rom_buffer);
return sum;
}

View File

@ -1,39 +0,0 @@
/*
gb.h - Game Boy 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 GB_H
#define GB_H
#define GB_LOGODATA_LEN 48
extern const st_getopt2_t gameboy_usage[];
extern const unsigned char gb_logodata[], rocket_logodata[];
extern int gameboy_chk (st_rominfo_t *rominfo);
extern int gameboy_gbx (st_rominfo_t *rominfo);
extern int gameboy_mgd (st_rominfo_t *rominfo);
extern int gameboy_n (st_rominfo_t *rominfo, const char *name);
extern int gameboy_n2gb (st_rominfo_t *rominfo, const char *emu_rom);
extern int gameboy_sgb (st_rominfo_t *rominfo);
extern int gameboy_ssc (st_rominfo_t *rominfo);
extern int gameboy_init (st_rominfo_t *rominfo);
extern int gameboy_logo (st_rominfo_t *rominfo);
#endif

View File

@ -1,850 +0,0 @@
/*
gba.c - Game Boy Advance support for uCON64
Copyright (c) 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>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/stat.h>
#include "misc/file.h"
#include "misc/misc.h"
#include "misc/property.h"
#ifdef USE_ZLIB
#include "misc/archive.h"
#endif
#include "misc/getopt2.h" // st_getopt2_t
#include "misc/string.h"
#include "ucon64.h"
#include "ucon64_misc.h"
#include "gba.h"
#include "backup/fal.h"
#define GBA_NAME_LEN 12
#define GBA_HEADER_START 0
#define GBA_HEADER_LEN (sizeof (st_gba_header_t))
static int gba_chksum (void);
const st_getopt2_t gba_usage[] =
{
{
NULL, 0, 0, 0,
NULL, "Game Boy Advance"/*"2001 Nintendo http://www.nintendo.com"*/,
NULL
},
{
"gba", 0, 0, UCON64_GBA,
NULL, "force recognition",
&ucon64_wf[WF_OBJ_GBA_SWITCH]
},
{
"n", 1, 0, UCON64_N,
"NEW_NAME", "change internal ROM name to NEW_NAME",
&ucon64_wf[WF_OBJ_ALL_DEFAULT]
},
{
"logo", 0, 0, UCON64_LOGO,
NULL, "restore ROM logo character data (offset: 0x04-0x9F)",
&ucon64_wf[WF_OBJ_ALL_DEFAULT]
},
{
"chk", 0, 0, UCON64_CHK,
NULL, "fix ROM header checksum",
&ucon64_wf[WF_OBJ_ALL_DEFAULT]
},
{
"sram", 0, 0, UCON64_SRAM,
NULL, "patch ROM for SRAM saving",
&ucon64_wf[WF_OBJ_GBA_DEFAULT]
},
{
"crp", 1, 0, UCON64_CRP,
"WAIT_TIME", "slow down ROM access (\"crash patch\");\n"
"WAIT_TIME=0 default in most crash patches\n"
"WAIT_TIME=4 faster than 0, slower than 8\n"
"WAIT_TIME=8 faster than 4, slower than 28\n"
"WAIT_TIME=12 slowest cartridge access speed\n"
"WAIT_TIME=16 faster than 28, but slower than 20\n"
"WAIT_TIME=20 default in most original cartridges\n"
"WAIT_TIME=24 fastest cartridge access speed\n"
"WAIT_TIME=28 faster than 8 but slower than 16",
&ucon64_wf[WF_OBJ_GBA_DEFAULT]
},
// "n 0 and 28, with a stepping of 4. I.e. 0, 4, 8, 12 ...\n"
{
"multi", 1, 0, UCON64_MULTI,
"SIZE", "make multi-game file for use with FAL/F2A flash card, truncated\n"
"to SIZE Mbit; file with loader must be specified first, then\n"
"all the ROMs, multi-game file to create last",
&ucon64_wf[WF_OBJ_ALL_INIT_PROBE_STOP]
},
{NULL, 0, 0, 0, NULL, NULL, NULL}
};
/*
Offset 00h-03h - Start Address - A 32 bit ARM B command with jump destination
to the start address of the program, cannot be manipulated
with this tool, there's no reason.
Offset 04h-9fh - Nintendo logo character data - The fix Nintendo logo graphics
needed to start a ROM on the real machine as it is verified
by it.
Offset a0h-abh - Game title - The game title is an ASCII string, officially
can use only ASCII characters between the ASCII code 20h and
60h. Although it is not a strict rule for hobby programmers,
it is fun to follow such a rules in my opinion. As I know
developers can choose their own game title here describing
the product in short.
Offset ach-afh - Game code - The 4 bytes long code of the game is an ASCII
string too, officially can use only ASCII characters between
the ASCII code 20h and 60h. The first letter is always A as I
know, probably stands for GBA, so it won't change unless a
higher hardware with backwards compatibility won't be
introduced and this letter could hold some more infos about
it. The second and third letters are the shortened version of
the name of the game. And the fourth letter is the territory
code. Don't afraid, there's no territory lockout, this is for
information purposes only. So far as I know J stands for
Japan and Asia, E stands for USA and the whole American
continent and P stands for Europe, Australia and Africa
(probably came from that these are the PAL video standard
territories, but I could be wrong). Although it is not a
strict rule for hobby programmers, it is fun to follow such a
rules in my opinion. Developers get this 4 letter code right
from Nintendo and they have to use that.
Offset b0h-b1h - Maker code - The 2 bytes long code of the developer company
is an ASCII string too, officially can use only ASCII
characters between the ASCII code 20h and 60h. Although it is
not a strict rule for hobby programmers, it is fun to follow
such a rules in my opinion. Developers get this 2 letter code
right from Nintendo and they have to use that.
Offset b2h-b2h - 96h - Fixed 96h byte without any useful information.
Offset b3h-b3h - Main unit code - This hexadecimal byte is the destination
hardware code. It is always 00h at the moment as it stands
for Game Boy Advance, so it won't change in the future either
unless a higher hardware with backwards compatibility won't
be introduced and this byte could hold some more infos about
it. There's no reason to change this or write something
different than 00h into it.
Offset b4h-b4h - Device type - This hexadecimal byte is the device type code.
It is always 00h as the only other possible value stands for
a debugger cart what I assume won't be available on the
streets and I assume even if a developer works with such a
hardware, he or she doesn't have to change this byte, however
he or she easily can of course. So there's no reason to
change this or write something different than 00h into it.
Offset b5h-bbh - Reserved area - Fixed, 00h filled area without any useful
information.
Offset bch-bch - Mask ROM version number - This hexadecimal byte holds the
version number of the ROM. As I know it works somehow that
way, the first published (and released on the streets) is
always the first version and for that 00h is stored here. In
the case it is getting updated, so in the same territory the
very same game with the very same title is getting replaced
with a new version, what is happening rarely, the number here
is getting increased by one. So usually this byte holds 00h
and there isn't too much reason to write something here and
something else than 00h.
Offset bdh-bdh - Complement check - This hexadecimal byte have to be
calculated automatically, when the whole header is in its
final state, so nothing will change inside of it. (Manually
it would be hard to calculate.) Add the bytes between offset
a0h and bch together, take the number's two's complement and
add 19h to the result. Store the lowest 8 bits here. Or
calculate automatically with GBARM. The hardware is
verifying this byte just like the Nintendo logo character
data and in the case it isn't correct, the game won't start
on the real machine.
Offset beh-bfh - Reserved area - Fixed, 00h filled area without any useful
information.
*/
typedef struct st_gba_header
{
unsigned char start[4]; // 0x00
unsigned char logo[GBA_LOGODATA_LEN]; // 0x04
unsigned char name[GBA_NAME_LEN]; // 0xa0
unsigned char game_id_prefix; // 0xac
unsigned char game_id_low; // 0xad
unsigned char game_id_high; // 0xae
unsigned char game_id_country; // 0xaf
unsigned char maker_high; // 0xb0
unsigned char maker_low; // 0xb1
unsigned char pad1;
unsigned char gba_type; // 0xb3
unsigned char device_type; // 0xb4
unsigned char pad2[7];
unsigned char version; // 0xbc
unsigned char checksum; // 0xbd
unsigned char pad3[2];
} st_gba_header_t;
static st_gba_header_t gba_header;
const unsigned char gba_logodata[] = // Note: not a static variable
{
0x24, 0xff, 0xae, 0x51,
0x69, 0x9a, 0xa2, 0x21, 0x3d, 0x84, 0x82, 0x0a,
0x84, 0xe4, 0x09, 0xad, 0x11, 0x24, 0x8b, 0x98,
0xc0, 0x81, 0x7f, 0x21, 0xa3, 0x52, 0xbe, 0x19,
0x93, 0x09, 0xce, 0x20, 0x10, 0x46, 0x4a, 0x4a,
0xf8, 0x27, 0x31, 0xec, 0x58, 0xc7, 0xe8, 0x33,
0x82, 0xe3, 0xce, 0xbf, 0x85, 0xf4, 0xdf, 0x94,
0xce, 0x4b, 0x09, 0xc1, 0x94, 0x56, 0x8a, 0xc0,
0x13, 0x72, 0xa7, 0xfc, 0x9f, 0x84, 0x4d, 0x73,
0xa3, 0xca, 0x9a, 0x61, 0x58, 0x97, 0xa3, 0x27,
0xfc, 0x03, 0x98, 0x76, 0x23, 0x1d, 0xc7, 0x61,
0x03, 0x04, 0xae, 0x56, 0xbf, 0x38, 0x84, 0x00,
0x40, 0xa7, 0x0e, 0xfd, 0xff, 0x52, 0xfe, 0x03,
0x6f, 0x95, 0x30, 0xf1, 0x97, 0xfb, 0xc0, 0x85,
0x60, 0xd6, 0x80, 0x25, 0xa9, 0x63, 0xbe, 0x03,
0x01, 0x4e, 0x38, 0xe2, 0xf9, 0xa2, 0x34, 0xff,
0xbb, 0x3e, 0x03, 0x44, 0x78, 0x00, 0x90, 0xcb,
0x88, 0x11, 0x3a, 0x94, 0x65, 0xc0, 0x7c, 0x63,
0x87, 0xf0, 0x3c, 0xaf, 0xd6, 0x25, 0xe4, 0x8b,
0x38, 0x0a, 0xac, 0x72, 0x21, 0xd4, 0xf8, 0x07
};
int
gba_n (st_rominfo_t *rominfo, const char *name)
{
char buf[GBA_NAME_LEN], dest_name[FILENAME_MAX];
memset (buf, 0, GBA_NAME_LEN);
strncpy (buf, name, GBA_NAME_LEN);
strcpy (dest_name, ucon64.rom);
ucon64_file_handler (dest_name, NULL, 0);
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
ucon64_fwrite (buf, GBA_HEADER_START + rominfo->buheader_len + 0xa0, GBA_NAME_LEN,
dest_name, "r+b");
printf (ucon64_msg[WROTE], dest_name);
return 0;
}
int
gba_logo (st_rominfo_t *rominfo)
{
char dest_name[FILENAME_MAX];
strcpy (dest_name, ucon64.rom);
ucon64_file_handler (dest_name, NULL, 0);
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
ucon64_fwrite (gba_logodata, GBA_HEADER_START + rominfo->buheader_len + 0x04,
GBA_LOGODATA_LEN, dest_name, "r+b");
printf (ucon64_msg[WROTE], dest_name);
return 0;
}
int
gba_chk (st_rominfo_t *rominfo)
{
char buf, dest_name[FILENAME_MAX];
strcpy (dest_name, ucon64.rom);
ucon64_file_handler (dest_name, NULL, 0);
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
buf = rominfo->current_internal_crc;
ucon64_fputc (dest_name, GBA_HEADER_START + rominfo->buheader_len + 0xbd,
buf, "r+b");
dumper (stdout, &buf, 1, GBA_HEADER_START + rominfo->buheader_len + 0xbd, DUMPER_HEX);
printf (ucon64_msg[WROTE], dest_name);
return 0;
}
int
gba_sram (void)
// This function is based on Omar Kilani's gbautil 1.1
{
unsigned char st_orig[2][10] =
{
{ 0x0E, 0x48, 0x39, 0x68, 0x01, 0x60, 0x0E, 0x48, 0x79, 0x68 },
{ 0x13, 0x4B, 0x18, 0x60, 0x13, 0x48, 0x01, 0x60, 0x13, 0x49 }
},
st_repl[2][10] =
{
{ 0x00, 0x48, 0x00, 0x47, 0x01, 0xFF, 0xFF, 0x08, 0x79, 0x68 },
{ 0x01, 0x4C, 0x20, 0x47, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x08 }
},
fl_orig[2][24] =
{
{
0xD0, 0x20, 0x00, 0x05, 0x01, 0x88, 0x01, 0x22, 0x08, 0x1C,
0x10, 0x40, 0x02, 0x1C, 0x11, 0x04, 0x08, 0x0C, 0x00, 0x28,
0x01, 0xD0, 0x1B, 0xE0
},
{
0xD0, 0x21, 0x09, 0x05, 0x01, 0x23, 0x0C, 0x4A, 0x08, 0x88,
0x18, 0x40, 0x00, 0x28, 0x08, 0xD1, 0x10, 0x78, 0x00, 0x28,
0xF8, 0xD0, 0x08, 0x88
}
},
fl_repl[2][24] =
{
{
0xE0, 0x20, 0x00, 0x05, 0x01, 0x88, 0x01, 0x22, 0x08, 0x1C,
0x10, 0x40, 0x02, 0x1C, 0x11, 0x04, 0x08, 0x0C, 0x00, 0x28,
0x01, 0xD0, 0x1B, 0xE0
},
{
0xE0, 0x21, 0x09, 0x05, 0x01, 0x23, 0x0C, 0x4A, 0x08, 0x88,
0x18, 0x40, 0x00, 0x28, 0x08, 0xD1, 0x10, 0x78, 0x00, 0x28,
0xF8, 0xD0, 0x08, 0x88
}
},
p_repl[2][188] =
{
{
0x39, 0x68, 0x27, 0x48, 0x81, 0x42, 0x23, 0xD0, 0x89, 0x1C,
0x08, 0x88, 0x01, 0x28, 0x02, 0xD1, 0x24, 0x48, 0x78, 0x60,
0x33, 0xE0, 0x00, 0x23, 0x00, 0x22, 0x89, 0x1C, 0x10, 0xB4,
0x01, 0x24, 0x08, 0x68, 0x20, 0x40, 0x5B, 0x00, 0x03, 0x43,
0x89, 0x1C, 0x52, 0x1C, 0x06, 0x2A, 0xF7, 0xD1, 0x10, 0xBC,
0x39, 0x60, 0xDB, 0x01, 0x02, 0x20, 0x00, 0x02, 0x1B, 0x18,
0x0E, 0x20, 0x00, 0x06, 0x1B, 0x18, 0x7B, 0x60, 0x39, 0x1C,
0x08, 0x31, 0x08, 0x88, 0x09, 0x38, 0x08, 0x80, 0x16, 0xE0,
0x15, 0x49, 0x00, 0x23, 0x00, 0x22, 0x10, 0xB4, 0x01, 0x24,
0x08, 0x68, 0x20, 0x40, 0x5B, 0x00, 0x03, 0x43, 0x89, 0x1C,
0x52, 0x1C, 0x06, 0x2A, 0xF7, 0xD1, 0x10, 0xBC, 0xDB, 0x01,
0x02, 0x20, 0x00, 0x02, 0x1B, 0x18, 0x0E, 0x20, 0x00, 0x06,
0x1B, 0x18, 0x08, 0x3B, 0x3B, 0x60, 0x0B, 0x48, 0x39, 0x68,
0x01, 0x60, 0x0A, 0x48, 0x79, 0x68, 0x01, 0x60, 0x0A, 0x48,
0x39, 0x1C, 0x08, 0x31, 0x0A, 0x88, 0x80, 0x21, 0x09, 0x06,
0x0A, 0x43, 0x02, 0x60, 0x07, 0x48, 0x00, 0x47, 0x00, 0x00,
0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0E, 0x04, 0x00,
0x00, 0x0E, 0xD4, 0x00, 0x00, 0x04, 0xD8, 0x00, 0x00, 0x04,
0xDC, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xFF, 0x08
},
{
0x22, 0x4C, 0x84, 0x42, 0x20, 0xD0, 0x80, 0x1C, 0x04, 0x88,
0x01, 0x25, 0x2C, 0x40, 0x01, 0x2C, 0x02, 0xD1, 0x80, 0x1E,
0x1E, 0x49, 0x2E, 0xE0, 0x00, 0x23, 0x00, 0x24, 0x80, 0x1C,
0x40, 0xB4, 0x01, 0x26, 0x05, 0x68, 0x35, 0x40, 0x5B, 0x00,
0x2B, 0x43, 0x80, 0x1C, 0x64, 0x1C, 0x06, 0x2C, 0xF7, 0xD1,
0x40, 0xBC, 0xDB, 0x01, 0x02, 0x24, 0x24, 0x02, 0x1B, 0x19,
0x0E, 0x24, 0x24, 0x06, 0x1B, 0x19, 0x19, 0x1C, 0x09, 0x3A,
0x16, 0xE0, 0x12, 0x48, 0x00, 0x23, 0x00, 0x24, 0x40, 0xB4,
0x01, 0x26, 0x05, 0x68, 0x35, 0x40, 0x5B, 0x00, 0x2B, 0x43,
0x80, 0x1C, 0x64, 0x1C, 0x06, 0x2C, 0xF7, 0xD1, 0x40, 0xBC,
0xDB, 0x01, 0x02, 0x24, 0x24, 0x02, 0x1B, 0x19, 0x0E, 0x24,
0x24, 0x06, 0x1B, 0x19, 0x08, 0x3B, 0x18, 0x1C, 0x08, 0x4C,
0x20, 0x60, 0x08, 0x4C, 0x21, 0x60, 0x08, 0x49, 0x80, 0x20,
0x00, 0x06, 0x02, 0x43, 0x0A, 0x60, 0x06, 0x4C, 0x20, 0x47,
0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0E, 0x04, 0x00,
0x00, 0x0E, 0xD4, 0x00, 0x00, 0x04, 0xD8, 0x00, 0x00, 0x04,
0xDC, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xFF, 0x08
}
},
major, minor, micro, *buffer, *bufferptr, *ptr, value;
char dest_name[FILENAME_MAX];
int p_size[2] = { 188, 168 }, p_off, st_off;
unsigned int fsize = ucon64.file_size;
FILE *destfile;
strcpy (dest_name, ucon64.rom);
ucon64_file_handler (dest_name, NULL, 0);
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
if ((destfile = fopen (dest_name, "rb+")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], dest_name);
return -1;
}
if (!(buffer = (unsigned char *) malloc (fsize)))
{
fprintf (stderr, ucon64_msg[ROM_BUFFER_ERROR], fsize);
fclose (destfile);
exit (1);
}
if (fread (buffer, 1, fsize, destfile) != fsize)
{
fprintf (stderr, ucon64_msg[READ_ERROR], dest_name);
free (buffer);
fclose (destfile);
return -1;
}
bufferptr = buffer + 160 + 12 + 4;
ptr = (unsigned char *) memmem2 (bufferptr, fsize, "EEPROM_", 7, 0);
if (ptr == 0)
{
printf ("This ROM does not appear to use EEPROM saving\n");
free (buffer);
fclose (destfile);
return -1;
}
major = ptr[8] - '0';
minor = ptr[9] - '0';
micro = ptr[10] - '0';
if (ucon64.quiet < 0)
printf ("version: %d.%d.%d; offset: 0x%08x\n",
major, minor, micro, (int) (ptr - buffer));
if (minor > 2)
{
fputs ("ERROR: ROMs with an EEPROM minor version higher than 2 are not supported\n", stderr);
free (buffer);
fclose (destfile);
return -1;
}
ptr = (unsigned char *) memmem2 (bufferptr, fsize,
fl_orig[minor - 1], sizeof (fl_orig[minor - 1]), 0);
if (ptr == 0)
{
fputs ("ERROR: Could not find fl pattern. Perhaps this file is already patched?\n", stderr);
free (buffer);
fclose (destfile);
return -1;
}
if (ucon64.quiet < 0)
printf ("fl offset: 0x%08x\n", (int) (ptr - buffer));
fseek (destfile, ptr - buffer, SEEK_SET);
fwrite (fl_repl[minor - 1], 1, sizeof (fl_repl[minor - 1]), destfile);
ptr = buffer + fsize - 1;
value = *ptr;
do
ptr--;
while (*ptr == value && ptr - buffer > 0);
p_off = (ptr - buffer + 0xff) & ~0xff; // align at 256 byte boundary
if (ucon64.quiet < 0)
printf ("p_off: 0x%08x\n", p_off);
// if the SRAM function won't fit at the end of the ROM, abort
if ((minor == 1 && (int) (fsize - 188) < p_off) ||
(minor == 2 && (int) (fsize - 168) < p_off))
{
fputs ("ERROR: Not enough room for SRAM function at end of ROM\n", stderr);
free (buffer);
fclose (destfile);
return -1;
}
ptr = (unsigned char *) memmem2 (bufferptr, fsize,
st_orig[minor - 1], sizeof (st_orig[minor - 1]), 0);
if (ptr == 0)
{
fputs ("ERROR: Could not find st pattern\n", stderr);
free (buffer);
fclose (destfile);
return -1;
}
st_off = ptr - buffer;
if (ucon64.quiet < 0)
printf ("st offset: 0x%08x\n", st_off);
bufferptr = buffer + p_off;
switch (minor)
{
case 1:
// these are the offsets to the caller function, it handles all saving and
// is at st_off
p_repl[minor - 1][184] = (unsigned char) (st_off + 0x21);
p_repl[minor - 1][186] = (unsigned char) (st_off >> 16);
if (*(bufferptr - 1) == 0xff)
p_repl[minor - 1][185] = (unsigned char) (st_off >> 8);
else
{
st_off += 0x1f;
p_repl[minor - 1][185] = (unsigned char) (st_off >> 8);
}
// tell the calling function where the SRAM function is (p_off)
st_repl[minor - 1][5] = (unsigned char) (p_off >> 8);
st_repl[minor - 1][6] = (unsigned char) (p_off >> 16);
break;
case 2:
// offsets to the caller function
p_repl[minor - 1][164] = (unsigned char) (st_off + 0x13);
p_repl[minor - 1][165] = (unsigned char) (st_off >> 8);
p_repl[minor - 1][166] = (unsigned char) (st_off >> 16);
// tell the calling function where the SRAM function is
st_repl[minor - 1][7] = (unsigned char) (p_off >> 8);
st_repl[minor - 1][8] = (unsigned char) (p_off >> 16);
break;
}
fseek (destfile, st_off, SEEK_SET);
fwrite (st_repl[minor - 1], 1, sizeof (st_repl[minor - 1]), destfile);
fseek (destfile, p_off, SEEK_SET);
fwrite (p_repl[minor - 1], 1, p_size[minor - 1], destfile);
free (buffer);
fclose (destfile);
puts ("SRAM patch applied");
printf (ucon64_msg[WROTE], dest_name);
return 0;
}
int
gba_crp (st_rominfo_t *rominfo, const char *value)
{
FILE *srcfile, *destfile;
int bytesread, n = 0;
char buffer[32 * 1024], src_name[FILENAME_MAX], dest_name[FILENAME_MAX],
replace[2], wait_time = atoi (value);
if (wait_time % 4 != 0 || wait_time > 28 || wait_time < 0)
{
fprintf (stderr, "ERROR: You specified an incorrect WAIT_TIME value\n");
return -1;
}
puts ("Applying crash patch...");
strcpy (src_name, ucon64.rom);
strcpy (dest_name, ucon64.rom);
ucon64_file_handler (dest_name, src_name, 0);
if ((srcfile = fopen (src_name, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], src_name);
return -1;
}
if ((destfile = fopen (dest_name, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], dest_name);
return -1;
}
if (rominfo->buheader_len) // copy header (if present)
{
fread (buffer, 1, rominfo->buheader_len, srcfile);
fwrite (buffer, 1, rominfo->buheader_len, destfile);
}
replace[0] = wait_time;
replace[1] = 0x40;
while ((bytesread = fread (buffer, 1, 32 * 1024, srcfile)))
{ // '!' == ASCII 33 (\x21), '*' == 42 (\x2a)
n += change_mem (buffer, bytesread, "\x04\x02\x00\x04\x14\x40", 6, '*', '!', replace, 1, -1);
n += change_mem (buffer, bytesread, "\x02\x00\x04\x14\x40\x00", 6, '*', '!', replace, 1, -2);
n += change_mem (buffer, bytesread, "\x04\x02\x00\x04\xB4\x45", 6, '*', '!', replace, 2, -1);
n += change_mem (buffer, bytesread, "\x3E\xE0\x00\x00\xB4\x45", 6, '*', '!', replace, 2, -1);
n += change_mem (buffer, bytesread, "\x04\x02\x00\x04\x94\x44", 6, '*', '!', replace, 2, -1);
fwrite (buffer, 1, bytesread, destfile);
}
fclose (srcfile);
fclose (destfile);
printf ("Found %d pattern%s\n", n, n != 1 ? "s" : "");
printf (ucon64_msg[WROTE], dest_name);
remove_temp_file ();
return 0;
}
int
gba_init (st_rominfo_t *rominfo)
{
int result = -1, value;
char buf[MAXBUFSIZE];
rominfo->buheader_len = UCON64_ISSET (ucon64.buheader_len) ?
ucon64.buheader_len : 0;
ucon64_fread (&gba_header, GBA_HEADER_START +
rominfo->buheader_len, GBA_HEADER_LEN, ucon64.rom);
if (/*gba_header.game_id_prefix == 'A' && */ // 'B' in Mario vs. Donkey Kong
gba_header.start[3] == 0xea && gba_header.pad1 == 0x96 && gba_header.gba_type == 0)
result = 0;
else
{
#if 0 // AFAIK (dbjh) GBA ROMs never have a header
rominfo->buheader_len = UCON64_ISSET (ucon64.buheader_len) ?
ucon64.buheader_len : UNKNOWN_HEADER_LEN;
ucon64_fread (&gba_header, GBA_HEADER_START +
rominfo->buheader_len, GBA_HEADER_LEN, ucon64.rom);
if (gba_header.game_id_prefix == 'A' && gba_header.gba_type == 0)
result = 0;
else
#endif
result = -1;
}
if (ucon64.console == UCON64_GBA)
result = 0;
rominfo->header_start = GBA_HEADER_START;
rominfo->header_len = GBA_HEADER_LEN;
rominfo->header = &gba_header;
// internal ROM name
strncpy (rominfo->name, (const char *) gba_header.name, GBA_NAME_LEN);
rominfo->name[GBA_NAME_LEN] = 0;
// ROM maker
{
int ih = gba_header.maker_high <= '9' ?
gba_header.maker_high - '0' : gba_header.maker_high - 'A' + 10,
il = gba_header.maker_low <= '9' ?
gba_header.maker_low - '0' : gba_header.maker_low - 'A' + 10;
value = ih * 36 + il;
}
if (value < 0 || value >= NINTENDO_MAKER_LEN)
value = 0;
rominfo->maker = NULL_TO_UNKNOWN_S (nintendo_maker[value]);
// ROM country
rominfo->country =
(gba_header.game_id_country == 'J') ? "Japan/Asia" :
(gba_header.game_id_country == 'E') ? "U.S.A." :
(gba_header.game_id_country == 'P') ? "Europe, Australia and Africa" :
"Unknown country";
// misc stuff
sprintf (buf, "Version: %d\n", gba_header.version);
strcat (rominfo->misc, buf);
sprintf (buf, "Device type: 0x%02x\n", gba_header.device_type);
strcat (rominfo->misc, buf);
/*
start address = current address + (parameter of B instruction * 4) + 8
gba_header.start[3] is opcode of B instruction (0xea)
*/
value = 0x8000008 +
(gba_header.start[2] << 18 | gba_header.start[1] << 10 | gba_header.start[0] << 2);
sprintf (buf, "Start address: 0x%08x\n", value);
strcat (rominfo->misc, buf);
strcat (rominfo->misc, "Logo data: ");
if (memcmp (gba_header.logo, gba_logodata, GBA_LOGODATA_LEN) == 0)
{
#ifdef USE_ANSI_COLOR
if (ucon64.ansi_color)
strcat (rominfo->misc, "\x1b[01;32mOk\x1b[0m");
else
#endif
strcat (rominfo->misc, "Ok");
}
else
{
#ifdef USE_ANSI_COLOR
if (ucon64.ansi_color)
strcat (rominfo->misc, "\x1b[01;31mBad\x1b[0m");
else
#endif
strcat (rominfo->misc, "Bad");
}
// internal ROM crc
if (!UCON64_ISSET (ucon64.do_not_calc_crc) && result == 0)
{
rominfo->has_internal_crc = 1;
rominfo->internal_crc_len = 1;
rominfo->current_internal_crc = gba_chksum ();
rominfo->internal_crc = gba_header.checksum;
rominfo->internal_crc2[0] = 0;
}
rominfo->console_usage = gba_usage[0].help;
// We use fal_usage, but we could just as well use f2a_usage
rominfo->copier_usage = (!rominfo->buheader_len ? fal_usage[0].help : unknown_usage[0].help);
return result;
}
int
gba_chksum (void)
// Note that this function only calculates the checksum of the internal header
{
unsigned char sum = 0x19, *ptr = (unsigned char *) &gba_header + 0xa0;
while (ptr < (unsigned char *) &gba_header + 0xbd)
sum += *ptr++;
sum = -sum;
return sum;
}
int
gba_multi (int truncate_size, char *multi_fname)
// TODO: Check if 1024 Mbit multi-game files are supported by the FAL code
{
#define BUFSIZE (32 * 1024)
int n, n_files, file_no, bytestowrite, byteswritten, totalsize = 0, done,
truncated = 0, size_pow2_lesser = 1, size_pow2 = 1, truncate_size_ispow2 = 0;
struct stat fstate;
FILE *srcfile, *destfile;
char buffer[BUFSIZE], fname[FILENAME_MAX], *fname_ptr;
if (truncate_size == 0)
{
fprintf (stderr, "ERROR: Can't make multi-game file of 0 bytes\n");
return -1;
}
#if 0
if (truncate_size != 64 * MBIT && truncate_size != 128 * MBIT &&
truncate_size != 256 * MBIT && truncate_size != 512 * MBIT &&
truncate_size != 1024 * MBIT)
{
fprintf (stderr, "ERROR: Truncate size must be 64, 128, 256, 512 or 1024\n");
return -1;
}
#endif
if (multi_fname != NULL) // -xfalmulti
{
strcpy (fname, multi_fname);
n_files = ucon64.argc;
}
else // -multi
{
strcpy (fname, ucon64.argv[ucon64.argc - 1]);
n_files = ucon64.argc - 1;
}
ucon64_file_handler (fname, NULL, OF_FORCE_BASENAME);
if ((destfile = fopen (fname, "wb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], fname);
return -1;
}
printf ("Creating multi-game file for FAL(/F2A): %s\n", fname);
file_no = 0;
for (n = 1; n < n_files; n++)
{
if (access (ucon64.argv[n], F_OK))
continue; // "file" does not exist (option)
stat (ucon64.argv[n], &fstate);
if (!S_ISREG (fstate.st_mode))
continue;
if (file_no == 0)
{
if (multi_fname != NULL) // -xfalmulti
{
get_property_fname (ucon64.configfile, "gbaloader", fname, "loader.bin");
if (access (fname, F_OK))
{
fprintf (stderr, "ERROR: Cannot open loader binary (%s)\n", fname);
return -1;
}
fname_ptr = fname;
// NOTE: loop counter is modified, because we have to insert
// loader in the file list
n--;
}
else // -multi
fname_ptr = ucon64.argv[n];
printf ("Loader: %s\n", fname_ptr);
if (fsizeof (fname_ptr) > 64 * 1024)
printf ("WARNING: Are you sure %s is a loader binary?\n", fname_ptr);
}
else
{
fname_ptr = ucon64.argv[n];
printf ("ROM%d: %s\n", file_no, fname_ptr);
}
if ((srcfile = fopen (fname_ptr, "rb")) == NULL)
{
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], fname_ptr);
continue;
}
done = 0;
byteswritten = 0; // # of bytes written per file
while (!done)
{
bytestowrite = fread (buffer, 1, BUFSIZE, srcfile);
if (totalsize + bytestowrite > truncate_size)
{
bytestowrite = truncate_size - totalsize;
done = 1;
truncated = 1;
printf ("Output file is %d Mbit, truncating %s, skipping %d bytes\n",
truncate_size / MBIT, fname_ptr,
fsizeof (fname_ptr) - (byteswritten + bytestowrite));
// DON'T use fstate.st_size, because file could be compressed
}
totalsize += bytestowrite;
if (bytestowrite == 0)
done = 1;
fwrite (buffer, 1, bytestowrite, destfile);
byteswritten += bytestowrite;
}
fclose (srcfile);
if (truncated)
break;
file_no++;
}
fclose (destfile);
/*
Display a notification if a truncate size was specified that is not exactly
the size of one of the flash card sizes.
*/
n = truncate_size;
while (n >>= 1)
size_pow2 <<= 1;
if (truncate_size == size_pow2)
truncate_size_ispow2 = 1;
n = totalsize - 1;
while (n >>= 1)
size_pow2_lesser <<= 1;
size_pow2 = size_pow2_lesser << 1;
if (totalsize > 64 * MBIT && !truncate_size_ispow2)
printf("\n"
"NOTE: This multi-game file can only be written to a card >= %d Mbit.\n"
" Use -multi=%d to create a file truncated to %d Mbit.\n"
" Current size is %.5f Mbit\n", // 5 digits to have 1 byte resolution
size_pow2 / MBIT, size_pow2_lesser / MBIT, size_pow2_lesser / MBIT,
totalsize / (float) MBIT);
return 0;
}

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