Remove old ucon64
This commit is contained in:
@@ -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! :\
|
||||
:...............................................:\
|
||||
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
@@ -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
|
||||
@@ -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}
|
||||
};
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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 |
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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}
|
||||
};
|
||||
@@ -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
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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}
|
||||
};
|
||||
@@ -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
|
||||
@@ -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}
|
||||
};
|
||||
@@ -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
|
||||
@@ -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}
|
||||
};
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -1,2 +0,0 @@
|
||||
./configure --with-libusb --disable-discmage
|
||||
make -j 2 clean all
|
||||
5619
tools/ucon64/src/configure
vendored
5619
tools/ucon64/src/configure
vendored
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
/*
|
||||
gba.h - Game Boy Advance support for uCON64
|
||||
|
||||
Copyright (c) 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 GBA_H
|
||||
#define GBA_H
|
||||
|
||||
#define GBA_LOGODATA_LEN 156
|
||||
|
||||
extern const st_getopt2_t gba_usage[];
|
||||
extern const unsigned char gba_logodata[];
|
||||
|
||||
extern int gba_chk (st_rominfo_t *rominfo);
|
||||
extern int gba_crp (st_rominfo_t *rominfo, const char *value);
|
||||
extern int gba_init (st_rominfo_t *rominfo);
|
||||
extern int gba_logo (st_rominfo_t *rominfo);
|
||||
extern int gba_n (st_rominfo_t *rominfo, const char *name);
|
||||
extern int gba_sram (void);
|
||||
extern int gba_multi (int truncate_size, char *fname);
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user