Page 1 of 2
Joint venture: To bring a new PS2 port of Snes9x.
Posted: Mon Mar 17, 2008 8:45 am
by bootsector_
Hi folks!
As we all know, Snes-station is kinda dead and sources are not available. What do you scene developers think about we join efforts and try to make a brand new port of snes9x for PS2?
I just love PS2 and I really love retrogaming and playing SNES on my PS2 with good emulation quality would be just heaven.
What do you guys think about it?
Best regards,
bootsector
Posted: Mon Mar 17, 2008 12:28 pm
by J.F.
Sounds like a good idea. I imagine that quite a bit of what in your other emulations can be applied to it as well. The latest code (1.5.1) can be found here:
http://snes9x.ipherswipsite.com/
or here:
http://www.geocities.co.jp/SiliconValle ... nes9x.html
Posted: Tue Mar 18, 2008 4:27 am
by Wraggster
im no devver rather a fan more than anything but would the sources from say the Dreamcast or PSP versions of Snes9x be handy as a starting base ?
Posted: Tue Mar 18, 2008 3:33 pm
by ryan_hoopes
Dude, I'd play your emulator.
Posted: Wed Mar 19, 2008 12:55 am
by jbit
ryan_hoopes wrote:Dude, I'd play your emulator.
Is this a euphemism?! :)
Posted: Wed Mar 19, 2008 7:22 am
by J.F.
Wraggster wrote:im no devver rather a fan more than anything but would the sources from say the Dreamcast or PSP versions of Snes9x be handy as a starting base ?
No. Both are based on older versions of SNES9x, and there is very little in common between the PS2, DC, and PSP. About the most that would be in common would be controller code for the PS2 and PSP, and even that wouldn't be identical, just very similar.
Posted: Fri Mar 28, 2008 8:04 am
by syproject
http://www.snes9x.com/phpbb2/viewtopic.php?t=2695
bootsector this forum may be helpful, luzarius81 sounds like he has got quite far with 1.43
Posted: Sat Mar 29, 2008 7:33 am
by J.F.
That thread (other than one "I wanna beta test!" post) is almost two years old. It won't be as helpful as you think.
Posted: Sat Mar 29, 2008 8:59 am
by syproject
ahh thxs jf i just went off the date of the last comment i wont be as quick next time hehe. still could be a starting point i think
Posted: Sat Mar 29, 2008 11:57 am
by J.F.
It does have a few comments that might be helpful, like the one about FAST_LSB_WORD_ACCESS, but that's about it. Better than nothing. :)
Posted: Sun Apr 06, 2008 12:19 am
by syproject
any news bootsector ??
Posted: Mon Apr 14, 2008 12:56 pm
by Rev1Dev
I don't know much at all about programming aside from what C++ I've been learning lately but I really would like to contribute to this in any way I can...
Well, the only things I can say at this point is I've got the PS2SDK + toolchain installed under MinGW (I'm running Windows XP, so I needed a Linux environment to work under - in case anyone knows of a better alternative to MinGW). I've been using/learning
Dev-C++ as an editor (also installed
Crimson Editor).
Aside from that, I've downloaded the source files for SNES9x [snes9x-1.51-src]. In the
docs directory was an html document titled
Porting Snes9x that seemed to have been included by it's original author(s) in aiding with porting the emulator, or at least compiling it, for use on various platforms.
Looked like a good place to start, however, I'm uncertain if it'll aide with adapting it to the Playstation 2's architecture, since it seems to be aimed at MacOSX, Linux, and Windows development.
Unfortunately, suffice it to say that my C++ skill is rudimentary at this point [Everything I know so far amounts to what I picked up from this site's tutorials:
http://www.cprogramming.com/ ... but that's it : / ]
Anyhow, I thought undertaking a project like this would be a good, challenging start; and if anything teach me more of what I need to know to gain an understanding of the language.
From what I've read of
SNES9x, it was written in a combination of C, C++,
and Assembly... but
SNES-Station was ported/written strictly in C++... Which allows me to assume that a similar approach can be taken... (Am I grasping the basic concept of this correctly?) However... While I'm certain it definitely helps, I'm unsure if it's entirely necessary to
also know both C and Assembly, since the native language of the program consists of all three, or was it developed with portability in mind [hence, adapt the code strictly through C++]?
Perhaps someone more knowledgeable would be willing to assist, as I am only (barely) a beginner, but am willing/eager to learn.
Posted: Tue Apr 15, 2008 2:04 am
by Sanehouse
What's the difference between ZSNES and SNES9X, or is your chosen port based more on personal preference than functuality?
Posted: Tue Apr 15, 2008 2:07 am
by jbit
SNES9x is very portable.
ZSNES (IIRC) is written mainly in x86 assembly... thus not very portable to the PS2...
Posted: Tue Apr 15, 2008 2:11 am
by Sanehouse
I see. So, if I were to use this ported version, I would be able to, on my very own PS2, use the SNES9X emulator as well as any SNES games that are compatible with it without modifying my PS2?
Posted: Tue Apr 15, 2008 6:54 am
by J.F.
Well, obviously you would need a way to run homebrew. The PS2 won't run just anything. You would need a mod-chip, swap discs, or if your PS2 is old enough you can use the ID Exploit. Don't bother to ask about any of those... this is a developer site, not a "how can I run stuff on my PS2/PSP" site.
Posted: Tue Apr 15, 2008 9:36 am
by Rev1Dev
Okay... I should've looked right there at the homepage: says it's C++ (snes9x source) -=slaps-forehead=-
I'm interested in this but I'm not sure it's place to discuss it.
Basically, I wanted more information on how emulators themselves work.
My idea is: are you basically using the target hardware (in this case the PS2) as a way to interpret the data in the games themselves?
For example, SNES9x itself, creates an environment for the games, that when loaded, redirect and interpret the code so that it can be emulated on whatever hardware it's being used on?
Now for some crude diagrams = ) :
- {I am the PC}
- [I am SNES9x, which is basically a simulated Super Nintendo program "inside" the PC, running off or "borrowing" it's hardware - to simulate my own - and run my games]}
- (I am Super Mario All-Stars... this is my code in the ROM image)
------------------------------------------------------------------------------
{PC [SNES + (ROM)] } = OUPUT----> to PC's DISPLAY, monitor/respond to USER INPUT, etc.
------------------------------------------------------------------------------
So in taking it's source code we're basically adapting the program itself, like this:
{PS2 [SNES + (ROM)]} = OUTPUT----> to TV screen, monitor/respond to PS2 Dual Shock Controller INPUT, so on and so forth.
--------------------------------------------------------------------------------
So you have to dig through the source code to find out which of these handles which function of the SNES (display, user input, save states, etc.)....
Point the code in the direction of whichever part of the PS2 handles each of these things [which means knowing the libraries and functions of the PS2's hardware itself], compile it all (the C++ code) into a format the PS2 understands (ELF binary).... and there you have it, SNES on PS2.
Sorry for my super long posts... please forgive me - as I know it's alot more complicated than this - but I'd like to understand it; not just know that it can do it, if that makes any sense.
Basically, can emulators (SNES9x in this case) be considered ROM "interpreters"?
When you run the game (open the file) in that simulated environment, it says "Hey, I'm in a Super Nintendo" and is executed... Kinda like a game within a game... or PS2 software that executes another type of software... bypassing the PS2 saying: "What the heck is a .smc file, anyway?" when you attempt to execute it.
Posted: Tue Apr 15, 2008 10:02 am
by J.F.
http://en.wikipedia.org/wiki/Emulator
If that isn't enough, all I can say is look at the code for existing emulators. If you can't figure it out from the code, you aren't ready to be working on an emulation yet. Start with simple emulators - too many beginners try to jump right to the hard stuff. "I just got a book on C++ for Dummies, and now I want to do a PS3 emulator!!"
Emulations are some of the more complex forms of programming. They stress the systems in ways no other program can. We used to use emulators to stress-test computers to see how well they worked for a new setup or hardware configuration.
Posted: Tue Apr 15, 2008 3:51 pm
by Rev1Dev
Thank you J.F. for helping to feed the hungry mind. = )
The information you referenced is actually extremely helpful to someone such as myself. In truth, I know at this stage, I wouldn't even know where to begin coding any of this myself - however, it's good to know the way something like this works, so that if in the (hopefully, near) future, my skill in programming is competent enough, it helps knowing how existing code is applied [per your suggestion ; ) ] and where to begin with a template for approaching this sort of project. I know you have to start out crawling before you can walk, but as a beginner it's a great personal challenge to say to yourself: "One day, I'll be able to do something like that" and set some goals. I like to learn by doing and I thought something like this couldn't be too difficult... I mean c'mon it's Super Nintendo, right? Wrong... boy, oh boy, did it turn out that I was wrong (in reading what was described in the wiki, it can be a very system intensive process).
Well, I guess it only makes sense that I'd need to retract my offer for any direct involvement with this project in particular, seeing as how I know I don't yet know enough to make a logical or useful contribution, but I'd still like to know more about it's development process if it's possible to hopefully gain some learning from it. = ) In the mean time, I'll try reviewing simpler code (perhaps as you'd suggested, a simpler emulator) to gain a better understanding of just how this works; all the while, trying to brush up on my own coding skills...
Then... from there... who knows...
Maybe we'll see "PS3 Emulator for Windows 2012 by Rev1Dev" posted on the boards. = )
Posted: Tue Apr 15, 2008 7:24 pm
by J.F.
Some advice - start simple. Jumping right into a complex emulator like the SNES is a sink-or-swim approach to kills many aspiring devs. Best to look over the code for more simple computers to get an idea of how emulators work in general, then work into more complex machines. Take a look at something like the Atari 2600, then the NES, then the Atari 400/800/XL, then the SEGA Genesis, then the SNES. That sort of thing. Each step up adds to your understanding, making harder machines easier to figure out.
Posted: Wed Apr 16, 2008 12:01 am
by ragnarok2040
I've managed to compile snes9x with the makefile you posted, bootsector_. I just bypassed the ashiftrt instruction error by removing the cast to int64 in front of hertz in the "void S9xSetSoundFrequency(int, int)" function. I'm not sure why it worked, but it did. I tried compiling the source with stlport (after creating a stub function for rename in ps2sdk's libc), but I was getting "out of scope" errors, so I just fell back to libstdc++. Right now, it's failing on linking since none of the port's interface functions have been defined. Should be a piece of cake now.
I looked at porting.html and decided to just copy and paste their list of needed functions. I defined them empty, but I included their descriptions underneath their definitions so they'll be easy to flesh out. Now I'm stuck at an undefined reference to `S9xSPCDump', which is defined in snapshot.cpp and its declaration is surrounded by START/END_EXTERN_C (snes9x's macro) in snapshot.h, so I'm not sure what the hangup is.
Code: Select all
#include "port.h"
#include "spc700.h"
#include "snes9x.h"
#include "display.h"
#include <iostream>
using namespace std;
START_EXTERN_C
bool8 S9xOpenSnapshotFile (const char *filepath, bool8 read_only, STREAM *file)
{
return false;
}
// This function opens a freeze-game file. STREAM is defined as a gzFile if ZLIB is defined else it's defined as FILE *.
// The read_only parameter is set to true when reading a freeze-game file and false when writing a freeze-game file.
// Open the file filepath and return its pointer file.
void S9xCloseSnapshotFile (STREAM file)
{
;
}
// This function closes the freeze-game file opened by S9xOpenSnapshotFile function.
void S9xExit (void)
{
;
}
// Called when some fatal error situation arises or when the "q" debugger command is used.
bool8 S9xInitUpdate (void)
{
return true;
}
// Called just before Snes9x begins to render an SNES screen. Use this function if you should prepare before drawing, otherwise let it empty.
bool8 S9xDeinitUpdate (int width, int height)
{
return true;
}
bool8 S9xContinueUpdate (int width, int height)
{
return true;
}
// Called once a complete SNES screen has been rendered into the GFX.Screen memory buffer,
// now is your chance to copy the SNES rendered screen to the host computer's screen memory.
// The problem is that you have to cope with different sized SNES rendered screens: 256*224, 256*239, 512*224, 512*239, 512*448 and 512*478.
void S9xMessage (int type, int number, const char *message)
{
cout << "Type: " << type << "Number: " << number << "Message: " << message << endl;
}
// When Snes9x wants to display an error, information or warning message, it calls this function.
// Check in messages.h for the types and individual message numbers that Snes9x currently passes as parameters.
//The idea is display the message string so the user can see it, but you choose not to display anything at all,
// or change the message based on the message number or message type.
//Eventually all debug output will also go via this function, trace information already does.
bool8 S9xOpenSoundDevice (int mode, bool8 stereo, int buffer_size)
{
return true;
}
//S9xInitSound function calls this function to actually open the host sound device. The three parameters are the just the same as you passed in S9xInitSound function.
const char *S9xGetFilename (const char *extension, enum s9x_getdirtype dirtype)
{
return NULL;
}
// When Snes9x needs to know the name of the cheat/ips file and so on, this function is called.
// Check extension and dirtype, and return the appropriate filename.
// The current ports return the ROM file path with the given extension.
const char *S9xGetFilenameInc (const char *extension, enum s9x_getdirtype dirtype)
{
return NULL;
}
//Almost the same as S9xGetFilename function, but used for saving SPC files etc.
// So you have to take care not to delete the previously saved file, by increasing the number of the filename; romname.000.spc, romname.001.spc, ...
const char *S9xGetDirectory (enum s9x_getdirtype dirtype)
{
return NULL;
}
// Called when Snes9x wants to know the directory dirtype.
//extern "C" char *osd_GetPackDir (void)
char *osd_GetPackDir (void)
{
return NULL;
}
// Called when Snes9x wants to know the directory of the SPC7110 graphics pack.
const char *S9xChooseFilename (bool8 read_only)
{
return NULL;
}
// If you port can match Snes9x's built-in LoadFreezeFile/SaveFreezeFile command (see controls.cpp), you may choose to use this function. Otherwise return NULL.
const char *S9xChooseMovieFilename (bool8 read_only)
{
return NULL;
}
//If you port can match Snes9x's built-in BeginRecordingMovie/LoadMovie command (see controls.cpp), you may choose to use this function. Otherwise return NULL.
const char *S9xBasename (const char *path)
{
return NULL;
}
//Called when Snes9x wants to know the name of the ROM image. Typically, extract the filename from path and return it.
void S9xAutoSaveSRAM (void)
{
;
}
// If Settings.AutoSaveDelay is not zero, Snes9x calls this function when the contents of the S-RAM has been changed.
// Simply call Memory.SaveSRAM function from this function.
void S9xGenerateSound (void)
{
;
}
// Use this function if you defined CHECK_SOUND in port.h.
void S9xToggleSoundChannel (int c)
{
;
}
//If you port can match Snes9x's built-in SoundChannelXXX command (see controls.cpp), you may choose to use this function.
// Otherwise return NULL. Basically, turn on/off the sound channel c (0-7), and turn on all channels if c is 8.
void S9xSetPalette (void)
{
;
}
//Called when the SNES color palette has changed. Use this function if your system should change its color palette to match the SNES's. Otherwise let it empty.
void S9xSyncSpeed (void)
{
;
}
//Called at the end of S9xMainLoop function, when emulating one frame has been done. You should adjust the frame rate in this function.
void S9xLoadSDD1Data (void)
{
;
}
END_EXTERN_C
int main()
{
cout << "Hello World!" << endl;
return 0;
}
After messing around with the code for a couple of more hours, I've got some more information. The source is kind of intermingled with a ton of functions for recording movies and audio and such, including in the controls and inside the cpu functions. I've just been commenting out object files from linking that seem to just have abundant unneeded code for the ps2. The only one that really needs to be implemented in some way is controls.cpp and snapshot.cpp for savestates.
#conffile.o
#controls.o
#logger.o
#movie.o
#netplay.o
#sound.o
#snapshot.o
#snes9x.o
Posted: Wed Apr 16, 2008 5:43 am
by Rev1Dev
The snes9x code compiles using the makefile bootsector posted, along with the few modifications to the makefile (only reported a missing separator on line 199) and replacing the code the compiler was turning as errors [including the line with (int64) as you posted, Ragnarok, which fixed the hang-up with soundux]... up until the point it references my
libjpg installation.
The error I'm getting is:
C:\msys\local\ps2\dev\ee\bin\..\lib\gcc-lib\ee\3.2.2\..\..\..\..\ee\bin\ld.exe: cannot find -ljpg
(It's hanging at -lkernel, for me, because of this)
I used the build from PS2DEV.org for libjpg... but when I kept trying to make it... it also returned a bunch of errors (mostly about "file or folder not found"). I hunted down most of the files it referenced (including the oh-so-fun to-try-finding libjpg.a), placed them in the libjpg directory... and the make completes - without warning or hang-ups.
However... I went back into where I was trying to compile snes9x - and ran into the same wall. It still returns the same error quoted above.
Anyone have any ideas why this could be happening? (If it helps, I'm installing under
C:\msys\local\ps2sdk\libjpg\libjpg)
And this is my makefile for libjpg:
SYSDEPMEM= jmemnobs.o
# library object files common to compression and decompression
COMOBJECTS= jcomapi.o jutils.o jerror.o jmemmgr.o $(SYSDEPMEM)
# compression library object files
CLIBOBJECTS= jcapimin.o jcapistd.o jctrans.o jcparam.o jdatadst.o jcinit.o \
jcmaster.o jcmarker.o jcmainct.o jcprepct.o jccoefct.o jccolor.o \
jcsample.o jchuff.o jcphuff.o jcdctmgr.o jfdctfst.o jfdctflt.o \
jfdctint.o
# decompression library object files
DLIBOBJECTS= jdapimin.o jdapistd.o jdtrans.o jdmaster.o \
jdinput.o jdmarker.o jdhuff.o jdphuff.o jdmainct.o jdcoefct.o \
jdpostct.o jddctmgr.o jidctfst.o jidctflt.o jidctint.o jidctred.o \
jdsample.o jdcolor.o jquant1.o jquant2.o jdmerge.o
# These objectfiles are included in libjpeg.a
LIBOBJECTS= $(CLIBOBJECTS) $(DLIBOBJECTS) $(COMOBJECTS)
EE_INCS = -I$(LIBJPG)/include -I.
EE_LIB = lib/libjpg.a
EE_OBJS = libjpg.o $(LIBOBJECTS)
all: $(EE_LIB)
clean:
rm -f *.elf *.o *.a
include $(PS2SDK)/samples/Makefile.pref
include $(PS2SDK)/samples/Makefile.eeglobal
I also read in another post on here that you have to add -ldebug to the makefile of jpg on this line:
EE_LIBS = -L$(LIBJPG)/lib -ljpg -ldebug
Posted: Wed Apr 16, 2008 6:05 am
by J.F.
libjpg is not part of the standard PS2 libs - but libjpeg is. Just change the makefile from -ljpg to -ljpeg.
Posted: Wed Apr 16, 2008 6:38 am
by ragnarok2040
The EE_LIBS flag in the makefile is filled with a bunch of libraries that aren't really necessary for compiling the core snes9x code. Since zip support is already ingrained into the source, and I already had zlib installed, I added it, but you could probably just get by with libm.
Code: Select all
EE_LIBS += -lz -lm
#-lgskit -ldmakit -ljpg -lpng -lz -lm -lfileXio -lhdd -lmc -lpadx -laudsrv -lpoweroff -lpatches -ldebug -lcdvdfs
I'm going to work on a little more organized makefile, based on the current one and the mingw version, and add some #ifdef checks inside the source code to comment out code on the fly. I'm at the point right now where I can see undefined symbols inside of libstdc++ like setlocale, strcoll, and strxfrm so I think I'm pretty close.
Posted: Wed Apr 16, 2008 7:43 am
by Rev1Dev
Thanks again... I know I've been a real pain being a newcomer around here, and I can't thank you all enough for your patience and support.
I managed to get past the libjpg process and for the life of me it actually installed. So of course, the next logical thing it did was hang at the libpng (it'll probably do that for everything I try to do that has a dependency I don't yet have integrated into my environment, so I kind of expected it). It also doesn't help that I'm taking the learning-as-I-go approach, but this has been a pretty good experience in learning my way around MinGW.
However, I'm at yet another snag - libpng can't continue because it can't find -lz ... I'm assuming this is zlib. I went for the zlib installation, it first hung because it couldn't find -lsyscall - and I know this was in there because it installed with the toolchain. In looking at the error I saw I had to edit out the \usr\ part in my profile for the directories to input/output correctly. That fixed that problem... crt0.o bunked out... fixed that... and now it's snagging on example.c -> example.o -=grrr=-.
I'm using the trunk repository version, so I'll see if I can find a different pre-combined package somewhere. Anyhow, I'm straying way off topic here and I don't want to become the community "thread-spammer".
Like I said, I'm very new to all this and don't yet know much at all about it, but in relevance to snes9x and just looking at all this code, you start to figure it out little by little if you look at it long enough, even for an upstart such as myself - and I have to agree with you Ragnarok, it doesn't take much to see that there is simply a lot of useless function calls in there if applied to a PS2 version (well for the PC or another platform that can take advantage of it, it's great but doesn't seem practical for the Playstation) .... Sound timing (don't think this really needs to be accessible on a user interface level once the right adjustment for accurate sound emulation is set - this is a more PC-like feature, I'm guessing for the sake of being accessible to different hardware configs), screenshots (unless you really, really wanted to), alot of the various joypad mapping functions (some of the lesser shortcut assignments and the like)... and aside from filters, if it's optimized enough I don't believe there are reasons to need code for switches in GPU settings for base-line hardware features (Mode7 On/Off, etc.).
Well back to work on trying to get this SDK working the way it needs to be (I've got to keep these posts down X D )... Good Luck and keep up the good work!
EDIT: Okay... so what library is -lz referencing?
Posted: Wed Apr 16, 2008 5:36 pm
by ragnarok2040
You're right that -lz references zlib. You shouldn't have any problems compiling it, just "make" and then "make install", as it just needs ps2sdk. There should be a libz.a file (-lz is a truncated name for GNU libraries to use with gcc) in the $PS2SDK/ps2sdk-ports/lib directory after you're done.
It sounds like your environment might not be setup correctly. I replied in the other thread on what might be your problem (crt0.o), but it could also be that your environment variables PS2DEV and PS2SDK might be setup wrong. I posted the versions I think that'll work for you in the other thread as well :D.
Update:
I've gotten it down to 109 errors about undefined symbols. A lot of them are ones that need to be implemented via the port or just commented out but I think I've ran into a bug on MinGW, where libstdc++ isn't compiled correctly because of mangled paths, I think. (tries to do c:\something/something/ar and then ar.exe isn't found when compiling the toolchain).
I've uploaded a patch that has all the changes I did plus the entire Makefile.
http://homebrew.thewaffleiron.net/ragna ... ch.tar.bz2
Code: Select all
To Apply:
cd snes9x-1.51-src
cat ../snes9x-ps2.patch | patch -p1
Posted: Thu Apr 17, 2008 7:13 am
by Rev1Dev
Here's the source I'm using (it includes your patch as well Ragnarok):
http://www.flipdrive.com/download.php?f ... 2d9e1613d6
It's locking at
on creation of
controls.o.
Posted: Thu Apr 17, 2008 6:01 pm
by ragnarok2040
Oh, I created an empty rename function in ps2sdk's implementation of libc in order to compile stlport which is why I didn't get that error, heh. Just edit ee/libc/include/stdio.h in ps2sdk's source and add:
Code: Select all
int remove(const char *);
int rename(const char *, const char *);
And edit ee/libc/src/stdio.c and add this right after the remove() function definition:
Code: Select all
#ifdef F_rename
int rename(const char *str1, const char *str2)
{
printf("Rename: doesn't work!\n");
return -1;
}
#endif
Then just make and make install ps2sdk again.
I'll probably write an implementation of it later via the suggestion in the other thread, which probably wouldn't take much time, but I wanted to focus on compiling snes9x first :D.
Posted: Thu Apr 17, 2008 6:28 pm
by Rev1Dev
Sweet! Thank you Ragnarok... That took the work out of that ; )
Well, I'm now back at another reference to crt0.o ... I just don't get this as it's an -lkernel dependency... any past revisions of the SDK that you know of that might work better in regards to this problem (tried 1420, didn't work).
Posted: Thu Apr 17, 2008 6:57 pm
by ragnarok2040
Hrmm, for some reason you don't have bleh.cpp, which is where main() is defined and a lot of those undefined functions. The main() function is the entry point for the program, without it no program will run, and it's declared inside of crt0.o which is why you get the message from there. I included it in the patch and there's a copy of it I pasted above. You can copy it into a something like "bleh.cpp" and then add bleh.o to the end of the EE_OBJS list inside the Makefile. Other than that, you're pretty much at the same point I am. I'll probably have a new patch out in a few hours. I'm at 79 errors, :D.
Code: Select all
EE_OBJS=$(CPUOBJ) $(SOUNDOBJ) apudebug.o $(FXOBJ) $(C4OBJ) \
crosshairs.o controls.o cpu.o sa1.o debug.o sdd1.o tile.o srtc.o gfx.o \
memmap.o clip.o dsp1.o ppu.o dma.o snes9x.o data.o globals.o reader.o \
conffile.o bsx.o snapshot.o \
$(SPC7110OBJ) $(OBC1OBJ) $(SETAOBJ) $(KREEDOBJ) $(SDD1OBJ) \
$(CHEATOBJ) $(PLATFORMOBJ) $(SCREENSHOTOBJ) $(MOVIEOBJ) $(LOGGEROBJ) \
bleh.o