Remove old ucon64
This commit is contained in:
parent
cf41986ccc
commit
123ca226ab
5846
avr/usbload/loader.c
5846
avr/usbload/loader.c
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,7 @@
|
||||
/*
|
||||
* File: qd16boot01.smc Time: Fri, 30 Oct 2009 16:49:11
|
||||
*/
|
||||
File: qd16boot01.smc
|
||||
Time: Tue, 09 Feb 2016 12:36:39
|
||||
*/
|
||||
#ifndef __FIFO_H__
|
||||
#define __FIFO_H__
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user